[
  {
    "path": ".gitignore",
    "content": "out/\ntags\ncscope.in.out\ncscope.out\ncscope.po.out\nlinkmap.txt\ninclude/config/config.h\nramdisk.sh\nramdisk2.sh\nfat32.sh\n*.srv\n*.drv\n*.app\n.*\n*.o\n*.o.*\n*.a\n*.s\n*.ko\n*.so\n*.so.dbg\n*.mod.c\n*.i\n*.lst\n*.symtypes\n*.order\n*.elf\n*.bin\n!user.bin/\n*.tar\n*.gz\n*.bz2\n*.lzma\n*.xz\n*.d\n*.lz4\n*.lzo\n*.patch\n*.gcno\nmodules.builtin\nModule.symvers\n*.dwo\n*.su\n\n#\n# Top-level generic files\n#\n/tags\n/TAGS\n/linux\n/vmlinux\n/vmlinux.32\n/vmlinux-gdb.py\n/vmlinuz\n/System.map\n/Module.markers\n\n#\n# Debian directory (make deb-pkg)\n#\n/debian/\n\n#\n# tar directory (make tar*-pkg)\n#\n/tar-install/\n\n#\n# git files that we don't want to ignore even if they are dot-files\n#\n!.gitignore\n!.mailmap\n\n#\n# Generated include files\n#\ninclude/config/\ninclude/generated\narch/*/include/generated\n\n# stgit generated dirs\npatches-*\n\n# quilt's files\npatches\nseries\n\n# cscope files\ncscope.*\nncscope.*\n\n# gnu global files\nGPATH\nGRTAGS\nGSYMS\nGTAGS\n\n# id-utils files\nID\n\n*.orig\n*~\n\\#*#\n\n#\n# Leavings from module signing\n#\nextra_certificates\nsigning_key.pem\nsigning_key.priv\nsigning_key.x509\nx509.genkey\n\n# Kconfig presets\nall.config\n\n# Kdevelop4\n*.kdev4\n*.lds\nallsymbols.S\ntmp.minos.symbols\n*.dtb\n*.py[co]\ntools/Kconfiglib/build/\n*.egg-info/\ntools/Kconfiglib/dist/\ntools/fdt_parse/parse_dtb\nasm-offset.h\n"
  },
  {
    "path": "Makefile",
    "content": "PHONY := _all\n_all:\n\nifeq ($(DEBUG),1)\n  BUILD_DEBUG = 1\nelse\n  BUILD_DEBUG = 0\nendif\n\nifeq ($(VERBOSE),1)\n  Q =\nelse\n  Q = @\nendif\n\nprojtree := $(shell pwd)\nsrctree  := .\nsrc\t := $(srctree)\n\nVPATH\t:= $(srctree)\n\nexport BUILD_DEBUG VERBOSE srctree projtree\n\nARCH\t\t?= aarch64\nCROSS_COMPILE\t?= aarch64-linux-gnu-\nPLATFORM\t?= fvp\n\nTARGET_ARCH            \t= $(ARCH)\nTARGET_CROSS_COMPILE   \t= $(CROSS_COMPILE)\nTARGET_PLATFORM \t= $(PLATFORM)\n\nexport TARGET_ARCH TARGET_CROSS_COMPILE TARGET_PLATFORM\n\n# Make variables (CC, etc...)\nTARGET_AS\t= $(TARGET_CROSS_COMPILE)as\nTARGET_LD\t= $(TARGET_CROSS_COMPILE)ld\nTARGET_CC\t= $(TARGET_CROSS_COMPILE)gcc\nTARGET_APP_CC\t= $(projtree)/out/bin/musl-gcc\nTARGET_CPP\t= $(TARGET_CC) -E\nTARGET_AR\t= $(TARGET_CROSS_COMPILE)ar\nTARGET_NM\t= $(TARGET_CROSS_COMPILE)nm\nTARGET_STRIP\t= $(TARGET_CROSS_COMPILE)strip\nTARGET_OBJCOPY\t= $(TARGET_CROSS_COMPILE)objcopy\nTARGET_OBJDUMP\t= $(TARGET_CROSS_COMPILE)objdump\nTARGET_INSTALL = $(projtree)/tools/install.sh\n\nTARGET_INCLUDE_DIR = $(projtree)/out/include\nTARGET_LIBS_DIR = $(projtree)/out/lib\nTARGET_OUT_DIR = $(projtree)/out\nUAPI_INCLUDE_DIR = $(projtree)/generic/include/\n\nHOST_LEX\t= flex\nHOST_YACC\t= bison\nHOST_AWK\t= awk\nHOST_PERL\t= perl\nHOST_PYTHON\t= python\nHOST_PYTHON2\t= python2\nHOST_PYTHON3\t= python3\nHOST_CHECK\t= sparse\nHOST_CC\t\t= gcc\nHOST_AS\t\t= as\nHOST_LD\t\t= ld\nHOST_CC\t\t= gcc\nHOST_CPP\t= gcc -E\nHOST_AR\t\t= ar\nHOST_NM\t\t= nm\nHOST_STRIP\t= strip\nHOST_OBJCOPY\t= objcopy\nHOST_OBJDUMP\t= objdump\n\nMAKE\t\t= make\nMFLAGS\t\t:= --no-print-directory\n\nexport TARGET_AS TARGET_LD TARGET_CC TARGET_APP_CC TARGET_CPP TARGET_AR TARGET_NM TARGET_STRIP TARGET_OBJCOPY TARGET_OBJDUMP MAKE TARGET_INCLUDE_DIR TARGET_LIBS_DIR TARGET_INSTALL TARGET_OUT_DIR UAPI_INCLUDE_DIR\nexport HOST_LEX HOST_YACC HOST_AWK HOST_PERL HOST_PYTHON HOST_PYTHON2 HOST_PYTHON3 HOST_CHECK HOST_CC HOST_AS HOST_LD HOST_CC HOST_APP_CC HOST_CPP HOST_AR HOST_NM HOST_STRIP HOST_OBJCOPY HOST_OBJDUMP\n\nLIB_DIRS := user.libs\nAPP_DIRS := user.sbin user.bin user.driver\n\n# get all the libs folder under LIB_DIRS\nLIB_SUB_DIRS = $(foreach dir, $(LIB_DIRS), $(shell find $(dir) -maxdepth 1 -type d))\nLIB_TARGETS = $(filter-out $(LIB_DIRS),$(LIB_SUB_DIRS))\n\n# get the all application folders under APP_DIRS\nAPP_SUB_DIRS = $(foreach dir, $(APP_DIRS), $(shell find $(dir) -maxdepth 1 -type d))\nAPP_TARGETS = $(filter-out $(APP_DIRS),$(APP_SUB_DIRS))\n\nPHONY += all\n_all: all\n\nPHONY += libc libs apps kernel\n\nall: apps kernel\n\nlibc libs apps kernel: objdirs\n\napps: libs\n\t$(Q) set -e;\t\t\t\t\t\\\n\tfor i in $(APP_TARGETS); do \t\t\t\\\n\t\tif [ -f $$i/Makefile ]; then\t\t\\\n\t\t\techo \"\\n\\033[32m ---> Compiling App $$i ... \\033[0m \\n\";\t\\\n\t\t\t$(MAKE) $(MFLAGS) -C $$i ;\t\t\\\n\t\t\t$(MAKE) $(MFLAGS) -C $$i install;\t\\\n\t\tfi\t\t\t\t\t\\\n\tdone\n\nlibs: libc\n\t$(Q) set -e;\t\t\t\t\t\\\n\tfor i in $(LIB_TARGETS); do \t\t\t\\\n\t\tif [ -f $$i/Makefile ]; then\t\t\\\n\t\t\techo \"\\n\\033[32m ---> Compiling Lib $$i ... \\033[0m \\n\";\t\\\n\t\t\t$(MAKE) $(MFLAGS) -C $$i ;\t\t\\\n\t\t\t$(MAKE) $(MFLAGS) -C $$i install;\t\\\n\t\tfi\t\t\t\t\t\\\n\tdone\n\nlibc:\n\t$(Q) echo \"\\n\\033[32m---> Build LIBC ... \\033[0m \\n\"\n\t$(Q) $(MAKE) $(MFLAGS) -C user.libc -j 16\n\t$(Q) $(MAKE) $(MFLAGS) -C user.libc install\n\nkernel:\n\t$(Q) echo \"\\n\\033[32m ---> Build Kernel ... \\033[0m \\n\"\n\t$(Q) $(MAKE) $(MFLAGS) -C kernel\n\t$(Q) $(MAKE) $(MFLAGS) -C kernel dtbs\n\t$(Q) $(MAKE) $(MFLAGS) -C kernel install\n\nclean-kernel:\n\t$(Q) echo \"\\n\\033[32m ---> Clean Kernel ... \\033[0m \\n\"\n\t$(Q) $(MAKE) $(MFLAGS) -C kernel clean\n\nobjdirs:\n\t$(Q) mkdir -p $(srctree)/out\n\t$(Q) mkdir -p $(srctree)/out/include\n\t$(Q) mkdir -p $(srctree)/out/lib\n\t$(Q) mkdir -p $(srctree)/out/ramdisk\n\t$(Q) mkdir -p $(srctree)/out/rootfs/bin\n\t$(Q) mkdir -p $(srctree)/out/rootfs/sbin\n\t$(Q) mkdir -p $(srctree)/out/rootfs/driver\n\t$(Q) mkdir -p $(srctree)/out/rootfs/etc\n\nPHONY += images ramdisk rootfs prepare clean clean-libs clean-apps\n\nclean-libs:\n\t$(Q)set -e;\t\t\t\t\t\\\n\tfor i in $(LIB_TARGETS); do \t\t\t\\\n\t\tif [ -f $$i/Makefile ]; then\t\t\\\n\t\t\techo \"\\033[32m Clean $$i \\033[0m\";\t\t\\\n\t\t\t$(MAKE) $(MFLAGS) -C $$i clean;\t\\\n\t\tfi\t\t\t\t\t\\\n\tdone\n\nclean-apps:\n\t$(Q)set -e;\t\t\t\t\t\\\n\tfor i in $(APP_TARGETS); do \t\t\t\\\n\t\tif [ -f $$i/Makefile ]; then\t\t\\\n\t\t\techo \"\\033[32m Clean $$i \\033[0m\";\t\t\\\n\t\t\t$(MAKE) $(MFLAGS) -C $$i clean;\t\\\n\t\tfi\t\t\t\t\t\\\n\tdone\n\nclean: clean-libs clean-apps\n\t$(Q) echo \"\\033[32m Clean libc \\033[0m\"\n\t$(Q) $(MAKE) $(MFLAGS) -C user.libc clean\n\t$(Q) echo \"\\033[32m Clean kernel \\033[0m\"\n\t$(Q) $(MAKE) $(MFLAGS) -C kernel clean\n\t$(Q) rm -rf out\n\t$(Q) echo \"\\033[32m Clean done ... \\033[0m\"\n\nimages: ramdisk rootfs kernel\n\nramdisk: apps kernel\n\t$(Q) echo \"\\n\\033[32m ---> Packing Ramdisk image ... \\033[0m \\n\"\n\t$(Q) mkrmd -d out/ramdisk.bin out/ramdisk\n\nrootfs: apps\n\t$(Q) echo \"\\n\\033[32m ---> Packing Rootfs image ... \\033[0m \\n\"\n\t$(Q) mkdir -p /tmp/minos-mnt\n\t$(Q) dd if=/dev/zero of=/tmp/rootfs.img bs=1M count=64\n\t$(Q) mkfs.vfat -n \"ROOTFS\" -F 32 /tmp/rootfs.img\n\t$(Q) sudo mount /tmp/rootfs.img /tmp/minos-mnt\n\t$(Q) sudo cp -r out/rootfs/* /tmp/minos-mnt\n\t$(Q) sudo umount /tmp/minos-mnt\n\t$(Q) cp -f /tmp/rootfs.img out/rootfs.img\n\t$(Q) rm -rf /tmp/rootfs.img /tmp/minos-mnt\n\nprepare: objdirs\n\t$(Q) cd user.libc; ./build.sh $(TARGET_OUT_DIR) $(TARGET_ARCH) $(TARGET_CROSS_COMPILE)\n\t$(Q) cd kernel; make $(TARGET_PLATFORM)_defconfig\n\tcp -f kernel/include/uapi/* user.libc/include/minos/\n\nbin/% sbin/% driver/% libs/%:\n\t$(Q)set -e;\t\t\t\t\t\\\n\tif [ -f user.$@/Makefile ]; then\t\t\\\n\t\t$(MAKE) $(MFLAGS) -C user.$@;\t\t\\\n\t\t$(MAKE) $(MFLAGS) -C user.$@ install;\t\\\n\telse\t\t\t\t\t\t\\\n\t\techo \"Target user.$@ not found\";\t\\\n\tfi\n\n.PHONY: $(PHONY)\n"
  },
  {
    "path": "README.md",
    "content": "# Minos2\n\n**Minos2 is a micro-kernel OS.**\n\n- [x] Multi-process\n- [x] SMP\n- [x] Multi-thread\n- [x] Virtual memory management\n- [x] Libc (based on musl-libc)\n- [x] IPC\n- [x] VFS\n- [x] Ext4 (based on lwext4)\n- [x] Virtio-blk driver\n- [x] Qemu\n- [x] ARM FVP\n- [ ] Virtualization\n\n## Build Minos2\n\nBelow command tested on Ubuntu-18.04.\n\n1. Create a working directory\n\n   ```bash\n   # mkdir ~/minos2-workspace\n   # cd ~/minos2-workspace\n   ```\n\n2. Install AARCH64 GCC cross compilation tool (Other GCC version is also work fine)\n\n   ```bash\n   # wget https://releases.linaro.org/components/toolchain/binaries/7.2-2017.11/aarch64-linux-gnu/gcc-linaro-7.2.1-2017.11-x86_64_aarch64-linux-gnu.tar.xz\n   # tar xjf gcc-linaro-7.2.1-2017.11-x86_64_aarch64-linux-gnu.tar.xz\n   # sudo mv gcc-linaro-7.2.1-2017.11-x86_64_aarch64-linux-gnu /opt\n   # echo \"export PATH=/opt/gcc-linaro-7.2.1-2017.11-x86_64_aarch64-linux-gnu/bin:$PATH\" >> ~/.bashrc\n   # source ~/.bashrc\n   ```\n\n3. Install device-tree tool\n\n   ```bash\n   # sudo apt-get install device-tree-compiler\n   ```\n\n4. Download minos2 source code\n\n   ```bash\n   # git clone https://github.com/minosproject/minos2.git\n   ```\n\n5. Compile minos2\n\n   ```bash\n   # make PLATFORM=xxx prepare   \t(platform can be fvp or qemu_arm64)\n   # make ramdisk\t\t\t\t\t(build kernel, libc, system service, application, ramdisk in out/ directory)\n   ```\n\n## Download Virtio-blk image\n\nMinos2 support Qemu and FVP now, and both use virtio-blk disk with Ext4 filesystem as rootfs, this image can be create by qemu-img tool. If you do not want to create it by self, you can download the example one here.\n\n```\nvirtio-sd.img 链接: https://pan.baidu.com/s/1hMaQT20s7n8HNEZ-BqG7XQ 提取码: 9wyh \n```\n\n## Run Minos2 on Qemu\n\n1. Install qemu-system-aarch64\n\n   ```bash\n   # apt install qemu-system-arm\n   ```\n\n2. Download and compile u-boot\n\n   ```\n   # git clone https://github.com/u-boot/u-boot.git\n   ```\n\n   Before compile the U-boot, please apply below patch to support boot minos2.\n\n   ```c\n   diff --git a/common/image-fdt.c b/common/image-fdt.c\n   index eb552ca207..987817546d 100644\n   --- a/common/image-fdt.c\n   +++ b/common/image-fdt.c\n   @@ -175,6 +175,8 @@ int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size)\n           if (fdt_high) {\n                   void *desired_addr = (void *)simple_strtoul(fdt_high, NULL, 16);\n    \n   +               desired_addr = (void *)-1;\n   +\n                   if (((ulong) desired_addr) == ~0UL) {\n                           /* All ones means use fdt in place */\n                           of_start = fdt_blob;\n   \n   ```\n\n   Build u-boot\n\n   ```bash\n   # make qemu_arm64_defconfig\n   # make -j16 CROSS_COMPILE=aarch64-linux-gnu-\n   ```\n\n3. Build Minos\n\n   ```bash\n   # make PLATFORM=qemu_arm64 prepare\n   # make ramdisk\n   ```\n\n4. Copy files to the virtio image (use the image which from the pan.baidu.com as an example)\n\n   Mount the virtio image, please refer to https://unix.stackexchange.com/questions/82314/how-to-find-the-type-of-an-img-file-and-mount-it. There are two partitions in the virtio-sd.img, one is fat16 and other is ext4, please put below file in fat16 partitions.\n\n   ```\n   out/kernel.bin out/ramdisk.bin out/qemu-arm64.dtb\n   ```\n\n   and put below file in ext4 partiotion\n\n   ```\n   # mkdir bin  (create a directory named bin first)\n   # cp out/rootfs/bin/ps.app out/rootfs/bin/shell.app to $(virtio_ext_partition)/bin\n   ```\n\n5. Run minos2 on Qemu\n\n   ```bash\n   # qemu-system-aarch64 -nographic -bios u-boot.bin qemu-system-aarch64 -nographic -bios u-boot.bin -cpu cortex-a53 -machine type=virt -smp 4 -m 2G -machine virtualization=true -drive if=none,file=sd.img,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 -device virtio-net-device,netdev=net0 -netdev user,id=net0,hostfwd=tcp:127.0.0.1:5555-:22\n       \n   After qemu boot, use below command to boot minos2\n   \n   # fatload virtio 0:1 0x40000000 kernel.bin;fatload virtio 0:1 0x44000000 ramdisk.bin;fatload virtio 0:1 0x43e00000 qemu-arm64.dtb;booti 0x40000000 - 0x43e00000\n   ```\n\nBelow is the boot log for Qemu\n\n```\nminle@minle-Z840:~/work/github/u-boot$ qemu-system-aarch64 -nographic -machine virt -bios u-boot.bin -cpu cortex-a57 -smp 4 -m 2G  -drive if=none,file=/home/minle/work/minos-next/fvp_debug/sd.img,format=raw,id=hd0 \\\n-device virtio-blk-device,drive=hd0\n\n\nU-Boot 2019.07-rc4-00358-g1f83431f00-dirty (Dec 24 2021 - 15:20:30 +0800)\n\nDRAM:  2 GiB\n(virtio_mmio@a003e00): device (2) vendor (554d4551) version (1)\nFlash: 128 MiB\n*** Warning - bad CRC, using default environment\n\nIn:    pl011@9000000\nOut:   pl011@9000000\nErr:   pl011@9000000\nNet:   No ethernet found.\nHit any key to stop autoboot:  0 \n=> fatload virtio 0:1 0x40000000 kernel.bin;fatload virtio 0:1 0x44000000 ramdisk.bin;fatload virtio 0:1 0x43e00000 qemu-arm64.dtb;booti 0x40000000 - 0x43e00000\n257656 bytes read in 4 ms (61.4 MiB/s)\n695304 bytes read in 1 ms (663.1 MiB/s)\n4143 bytes read in 1 ms (4 MiB/s)\n## Flattened Device Tree blob at 43e00000\n   Booting using the fdt blob at 0x43e00000\n   Using Device Tree in place at 0000000043e00000, end 0000000043e0402e\n\nStarting kernel ...\n\n[       0.000000@00 000] NIC Starting Minos AARCH64\n[       0.000000@00 000] NIC DTB address [0x43e00000]\n[       0.000000@00 000] NIC Minos v0.3.3 unstable\n[       0.000000@00 000] NIC memory node address_cells:2 size_cells:2\n[       0.000000@00 000] NIC DTB - 0x43e00000 ---> 0x2000\n[       0.000000@00 000] NIC MEM: 0x0000000044000000 ---> 0x00000000c0000000 [0x000000007c000000] Normal\n[       0.000000@00 000] NIC MEM: 0x0000000040000000 ---> 0x0000000043c00000 [0x0000000003c00000] Kernel\n[       0.000000@00 000] NIC MEM: 0x0000000043e02000 ---> 0x0000000044000000 [0x00000000001fe000] Kernel\n[       0.000000@00 000] NIC MEM: 0x0000000043e00000 ---> 0x0000000043e02000 [0x0000000000002000] DTB\n[       0.000000@00 000] NIC MEM: 0x0000000043c00000 ---> 0x0000000043e00000 [0x0000000000200000] RamDisk\n[       0.000000@00 000] NIC kmem [0xffffff804004d000 0xffffff8043c00000]\n[       0.000000@00 000] NIC kmem [0xffffff8043e02000 0xffffff8044000000]\n[       0.000000@00 000] NIC umem [0x44000000 0xc0000000]\n[       0.000000@00 000] NIC slab memory allocator init ...\n[       0.000000@00 000] NIC bootargs: bootwait=3 tty=vm0 rootfs=virtio-blk.drv\n[       0.000000@00 000] NIC platform : linux,qemu-arm64\n[       0.000000@00 000] NIC current EL is 1\n[       0.000000@00 000] NIC *** gicv2 init ***\n[       0.000000@00 000] NIC gicv2 information: gic_dist_addr=0000000008000000 size=0x10000 gic_cpu_addr=0000000008010000 size=0x10000 gic_hyp_addr=0000000000000000 size=0x0 gic_vcpu_addr=0000000000000000 size=0x0\n[       0.000000@00 000] NIC GICv2: 288 lines, 4 cpus (IID 0).\n[       0.000000@00 000] WRN not support unmask irq_percpu\n[       0.000000@00 000] WRN not support unmask irq_percpu\n[       0.000000@00 000] WRN not support unmask irq_percpu\n[       0.000000@00 000] WRN not support unmask irq_percpu\n[       0.000000@00 000] NIC Register kobject type [5] name [endpoint]\n[       0.000000@00 000] NIC Register kobject type [1] name [process]\n[       0.000000@00 000] NIC Register kobject type [4] name [pma]\n[       0.000000@00 000] NIC Register kobject type [2] name [thread]\n[       0.000000@00 000] NIC Register kobject type [9] name [irq]\n[       0.000000@00 000] NIC Register kobject type [12] name [poll_hub]\n[       0.000000@00 000] NIC Register kobject type [3] name [notify]\n[       0.000000@00 000] NIC Register kobject type [13] name [port]\n[       0.000000@00 000] NIC    sec_phy_timer  : 29\n[       0.000000@00 000] NIC nonsec_phy_timer  : 30\n[       0.000000@00 000] NIC       virt_timer  : 27\n[       0.000000@00 000] NIC hypervisor_timer  : 26\n[      16.687407@00 000] NIC get timer clock freq from reg 62500\n[       0.000000@00 000] NIC boot ticks is :0x3e2a8f97\n[       0.004660@00 X95] NIC waiting 2 seconds for cpu-1 up\n[       0.006231@00 X95] NIC waiting 2 seconds for cpu-2 up\n[       0.005760@01 000] NIC cpu-1 is up\n[       0.006962@02 000] NIC cpu-2 is up\n[       0.007815@00 X95] NIC waiting 2 seconds for cpu-3 up\n[       0.008542@03 000] NIC cpu-3 is up\n[       0.010513@02 000] NIC current EL is 1\n[       0.010518@01 000] NIC current EL is 1\n[       0.010652@03 000] NIC current EL is 1\n[       0.012897@00 X95] NIC Root service load successfully prepare to run...\n\n\nPanGu service start...\n\npangu: dtb     [0x4043e00000 0x4043e02000]\npangu: ramdisk [0x4043c00000 0x4043e00000]\npangu: vmap    [0x1040000000 0x3fc0000000]\npangu: heap    [0x1000000000 0x1010000000]\npangu: sys max proc 4096\npangu: uproc_info 5\npangu: ktask_stat 6\npangu: bootargs: bootwait=3 tty=vm0 rootfs=virtio-blk.drv\npangu: handle send to fuxi.srv [handle@4]\npangu: Start fuxi.srv and waitting ...\n\n\nFuXi service start...\n\nfuxi: fuxi handle 4\npangu: Get response from fuxi.srv service 4132\nfuxi: waitting request\npangu: handle send to nvwa.srv [handle@4]\npangu: Start nvwa.srv and waitting ...\n\n\nNvWa service start...\n\npangu: Get response from nvwa.srv service 4132\nnvwa: nvwa waitting elf load request\npangu: handle send to chiyou.srv [handle@4,5]\npangu: only support map anon mapping for process\nvirtio-blk: virtio-dev: legacy mode\nvirtio-blk: virtio supports unsupported option VIRTIO_BLK_F_SEG_MAX (Maximum number of segments in a request is in seg_max.)\nvirtio-blk: virtio supports unsupported option VIRTIO_BLK_F_GEOMETRY (Disk-style geometry specified in geometry.)\nvirtio-blk: virtio supports unsupported option VIRTIO_BLK_F_BLK_SIZE (Block size of disk is in blk_size.)\nvirtio-blk: virtio supports unsupported option VIRTIO_BLK_F_FLUSH (Cache flush command support.)\nvirtio-blk: virtio supports unsupported option VIRTIO_BLK_F_TOPOLOGY (Device exports information on optimal I/O alignment.)\nvirtio-blk: virtio supports unsupported option VIRTIO_BLK_F_CONFIG_WCE (Device can toggle its cache between writeback and writethrough modes.)\nvirtio-blk: virtio supports unsupported option VIRTIO_F_RING_INDIRECT_DESC (Negotiating this feature indicates that the driver can use descriptors with the VIRTQ_DESC_F_INDIRECT flag set, as described in 2.4.5.3 Indirect Descriptors.)\nvirtio-blk: virtio supports unsupported option VIRTIO_F_RING_EVENT_IDX (This feature enables the used_event and the avail_event fields as described in 2.4.7 and 2.4.8.)\nvirtio-blk: virtio-blk: device supports unknown bits 0x1000080 in bank 0\npangu: only support map anon mapping for process\nvirtio-blk: virtio-blk virtq size 8192\nvirtio-blk: vd0 capacity : 512MB\next4_mbr: l: 75   [info]  ext4_mbr_scan\next4_mbr: l: 96   mbr_part: bootstrap:\n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, \n00, 00, 00, 00, 00, 00, 00, 00, 9f, 27, \n\next4_mbr: l: 106   mbr_part: 0\next4_mbr: l: 107   \tstatus: 0x80\next4_mbr: l: 108   \ttype 0xe:\next4_mbr: l: 109   \tfirst_lba: 0x3f\next4_mbr: l: 110   \tsectors: 0x25fc0\next4_mbr: l: 106   mbr_part: 1\next4_mbr: l: 107   \tstatus: 0x0\next4_mbr: l: 108   \ttype 0x83:\next4_mbr: l: 109   \tfirst_lba: 0x26000\next4_mbr: l: 110   \tsectors: 0xda000\next4_mbr: l: 106   mbr_part: 2\next4_mbr: l: 107   \tstatus: 0x0\next4_mbr: l: 108   \ttype 0x0:\next4_mbr: l: 109   \tfirst_lba: 0x0\next4_mbr: l: 110   \tsectors: 0x0\next4_mbr: l: 106   mbr_part: 3\next4_mbr: l: 107   \tstatus: 0x0\next4_mbr: l: 108   \ttype 0x0:\next4_mbr: l: 109   \tfirst_lba: 0x0\next4_mbr: l: 110   \tsectors: 0x0\nliblwext4: ext4_mbr_scan:\nliblwext4: mbr_entry 0:\nliblwext4: \tempty/unknown\nliblwext4: mbr_entry 1:\nliblwext4: \toffeset: 0x4c00000, 76MB\nliblwext4: \tsize:    0x1b400000, 436MB\nliblwext4: mbr_entry 2:\nliblwext4: \tempty/unknown\nliblwext4: mbr_entry 3:\nliblwext4: \tempty/unknown\next4_fs: l: 219   [info]  sblock features_incompatible:\next4_fs: l: 144   filetype\next4_fs: l: 152   extents\next4_fs: l: 154   64bit\next4_fs: l: 158   flex_bg\next4_fs: l: 222   [info]  sblock features_compatible:\next4_fs: l: 177   has_journal\next4_fs: l: 179   ext_attr\next4_fs: l: 181   resize_inode\next4_fs: l: 183   dir_index\next4_fs: l: 225   [info]  sblock features_read_only:\next4_fs: l: 189   sparse_super\next4_fs: l: 191   large_file\next4_fs: l: 195   huge_file\next4_fs: l: 199   dir_nlink\next4_fs: l: 201   extra_isize\next4_fs: l: 207   metadata_csum\nliblwext4: ext4 server epfd:10 root_fd:9\npangu: loading init shell.app ...\nliblwext4: ext4 server start, waitting for request...\nchiyou: rootfs is ready, exit chiyou event loop\npangu: only support map anon mapping for process\n\n _   _   _   _   _   _\n/ \\ / \\ / \\ / \\ / \\ / \\\n(M | i | n | o | s | 2 )\n\\_/ \\_/ \\_/ \\_/ \\_/ \\_/\n\n  Welcome to Minos2 \n\n\nminos # help\ncd : \"change directory\"\npwd : \"current directory\"\nclear : \"clear the screen\"\nls : \"list directory\"\nhelp : \"get help\"\nexec : \"run a application on the filesystem\"\nexit : \"exit the shell\"\nminos # ls\npangu: only support map anon mapping for process\ndrw-    c/\ntotal   1\nminos # cd c\nminos # ls\ndrw-    ./\ndrw-    ../\n-rw-    kernel.bin \ndrw-    bin/\ndrw-    etc/\ndrw-    home/\n-rw-    ramdisk.bin \n-rw-    qemu-arm64.dtb \ntotal   8\nminos # cd bin\nminos # ls\ndrw-    ./\ndrw-    ../\n-rw-    ps.app \n-rw-    shell.app \ntotal   4\nminos # ps\n PID CMD \n   0 pangu.srv\n   1 fuxi.srv\n   2 nvwa.srv\n   3 chiyou.srv\n   4 virtio-blk.drv\n   5 /c/bin/shell.app\n   6 /c/bin/ps.app\nminos # \n```\n\n## Video tutorial\n\n**TBD**\n"
  },
  {
    "path": "generic/include/uapi/bootdata.h",
    "content": "#ifndef __LIBMINOS_BOOTDATA_H__\n#define __LIBMINOS_BOOTDATA_H__\n\n#ifdef __KERNEL__\n#include <minos/types.h>\n#define ROOTSRV_USTACK_PAGES 4\n#else\n#include <inttypes.h>\n#endif\n\n#define CMDLINE_SIZE\t512\n\n#define BOOTDATA_MAGIC  0xe4b990e6958f\n\nstruct bootdata {\n\tuint64_t magic;\n\tuint64_t dtb_start;\n\tuint64_t dtb_end;\n\tuint64_t ramdisk_start;\n\tuint64_t ramdisk_end;\n\tuint64_t heap_start;\n\tuint64_t heap_end;\n\tuint64_t vmap_start;\n\tuint64_t vmap_end;\n\tint max_proc;\n\tint task_stat_handle;\n};\n\n#endif\n"
  },
  {
    "path": "generic/include/uapi/gvm.h",
    "content": "#ifndef __LIBMINOS_GVM_H__\n#define __LIBMINOS_GVM_H__\n\n\n/*\n * each guest vm may have at least 64 spi irqs,\n * the 32 - 63 virqs is for host vdevs and the\n * 64 - 95 virqs is for guest vms. also the hypervisor\n * provide auto allocation API to allocate virqs.\n * the only case to use the allocate API is to allocate\n * the vmcs irq after all the virtual devices has been\n * created\n *\n * the memory map for a guest vm showed as below:\n * 0x00000000 -> 0x1fffffff [IOMEM for device]\n *    0x00000000 -> 0x0fffffff [Map to directly io device passthough]\n *    0x10000000 -> 0x1fffffff [virtual device]\n * 0x20000000 -> 0xffffffff [Normal memory]\n */\n\n#define GVM_VIRT_TIMER_INT\t\t27\n\n#define GIC_IRQ\t\t\t\t9\n\n#define GICV2_GICD_IOMEM_BASE\t\t0x10000000\n#define GICV2_GICD_IOMEM_SIZE\t\t0x10000\n#define GICV2_GICC_IOMEM_BASE\t\t0x10010000\n#define GICV2_GICC_IOMEM_SIZE\t\t0x2000\n#define GICV2_GICH_IOMEM_BASE\t\t0x10012000\n#define GICV2_GICH_IOMEM_SIZE\t\t0x2000\n#define GICV2_GICV_IOMEM_BASE\t\t0x10014000\n#define GICV2_GICV_IOMEM_SIZE\t\t0x2000\n\n#define GICV3_GICD_IOMEM_BASE\t\t0x10000000\n#define GICV3_GICD_IOMEM_SIZE\t\t0x10000\n#define GICV3_GICR_IOMEM_BASE\t\t0x10200000\n#define GICV3_GICR_IOMEM_SIZE\t\t0x200000\n#define GICV3_GICC_IOMEM_BASE\t\t0x10400000\n#define GICV3_GICC_IOMEM_SIZE\t\t0x2000\n#define GICV3_GICH_IOMEM_BASE\t\t0x10410000\n#define GICV3_GICH_IOMEM_SIZE\t\t0x2000\n#define GICV3_GICV_IOMEM_BASE\t\t0x10420000\n#define GICV3_GICV_IOMEM_SIZE\t\t0x2000\n#define GICV3_ITS_IOMEM_BASE\t\t0x10430000\n#define GICV3_ITS_IOMEM_SIZE\t\t0x2000\n\n#define SP805_IRQ\t\t\t32\n#define SP805_CLK_RATE\t\t\t100000\n#define SP805_IOMEM_BASE\t\t0x10440000\n#define SP805_IOMEM_SIZE\t\t0x1000\n\n#define PL031_IRQ\t\t\t33\n#define PL031_IOMEM_BASE\t\t0x10441000\n#define PL031_IOMEM_SIZE\t\t0x1000\n\n#define GVM_IRQ_BASE\t\t\t64\n#define GVM_IRQ_COUNT\t\t\t32\n#define GVM_IRQ_END\t\t\t(GVM_IRQ_BASE + GVM_IRQ_COUNT)\n\n#define VM_MAX_VIRTIO_DEVICES\t\t32\n#define VM_VIRTIO_IOMEM_BASE\t\t0x1fe00000\n#define VM_VIRTIO_IOMEM_SIZE\t\t(0x1000 * VM_MAX_VIRTIO_DEVICES)\n\n#endif\n"
  },
  {
    "path": "generic/include/uapi/hypervisor.h",
    "content": "#ifndef __LIBMINOS_HYPERVISOR_H__\n#define __LIBMINOS_HYPERVISOR_H__\n\n#ifdef __KERNEL__\n#include <minos/types.h>\n#else\n#include <inttypes.h>\n#include <sys/types.h>\n#endif\n\n#include <common/ramdisk.h>\n\n#define VM_NAME_SIZE\t32\n#define VM_TYPE_SIZE\t16\n\n#define VM_FLAGS_64BIT\t\t\t(1 << 0)\n#define VM_FLAGS_NATIVE\t\t\t(1 << 1)\n#define VM_FLAGS_DYNAMIC_AFF\t\t(1 << 2)\n#define VM_FLAGS_NO_RAMDISK\t\t(1 << 3)\n#define VM_FLAGS_NO_BOOTIMAGE\t\t(1 << 4)\n#define VM_FLAGS_HAS_EARLYPRINTK\t(1 << 5)\n#define VM_FLAGS_NATIVE_WFI\t\t(1 << 6)\n#define VM_FLAGS_NO_OF_RESOURCE\t\t(1 << 7)\n\n#define VM_FLAGS_SETUP_OF\t\t(1 << 8)\n#define VM_FLAGS_SETUP_ACPI\t\t(1 << 9)\n#define VM_FLAGS_SETUP_ATAG\t\t(1 << 10)\n#define VM_FLAGS_SETUP_OTHER\t\t(1 << 11)\n#define VM_FLAGS_SETUP_MASK\t\t(0xf00)\n\n#define VM_FLAGS_XNU_APPLE\t\t(1 << 12)\n\nstruct vmtag {\n\tuint32_t vmid;\n\tchar name[VM_NAME_SIZE];\n\tchar os_type[VM_TYPE_SIZE];\n\tint32_t nr_vcpu;\n\tuint64_t mem_base;\n\tuint64_t mem_size;\n\tuint64_t entry;\n\tuint64_t setup_data;\n\tuint64_t flags;\n\tuint32_t vcpu_affinity[8];\n\tuint64_t load_address;\n\tchar image_file[RAMDISK_FNAME_SIZE];\n\tchar dtb_file[RAMDISK_FNAME_SIZE];\n};\n\n#define IOCTL_CREATE_VM\t\t\t0xf000\n#define IOCTL_DESTROY_VM\t\t0xf001\n#define IOCTL_RESTART_VM\t\t0xf002\n#define IOCTL_POWER_DOWN_VM\t\t0xf003\n#define IOCTL_POWER_UP_VM\t\t0xf004\n#define IOCTL_VM_MMAP\t\t\t0xf005\n#define IOCTL_VM_UNMAP\t\t\t0xf006\n#define IOCTL_REGISTER_VCPU\t\t0xf007\n#define IOCTL_SEND_VIRQ\t\t\t0xf008\n#define IOCTL_CREATE_VMCS\t\t0xf00a\n#define IOCTL_CREATE_VMCS_IRQ\t\t0xf00b\n#define IOCTL_UNREGISTER_VCPU\t\t0xf00c\n#define IOCTL_VIRTIO_MMIO_INIT\t\t0xf00d\n#define IOCTL_VIRTIO_MMIO_DEINIT\t0xf00e\n#define IOCTL_REQUEST_VIRQ\t\t0xf00f\n#define IOCTL_CREATE_VM_RESOURCE\t0xf010\n\nstruct vm_ring {\n\tvolatile uint32_t ridx;\n\tvolatile uint32_t widx;\n\tuint32_t size;\n\tchar buf[0];\n};\n\n#define VM_RING_IDX(idx, size)\t\t(idx & (size - 1))\n\n#endif\n"
  },
  {
    "path": "generic/include/uapi/ramdisk.h",
    "content": "#ifndef __LIBMINOS_RAMDISK_H__\n#define __LIBMINOS_RAMDISK_H__\n\n#ifdef __KERNEL__\n#include <minos/types.h>\n#else\n#include <inttypes.h>\n#include <sys/types.h>\n#endif\n\n#define RAMDISK_MAGIC \"MINOSRAMDISK....\"\n#define RAMDISK_MAGIC_SIZE 16\n\n#define RAMDISK_FNAME_SIZE 32\n\nstruct ramdisk_inode {\n\tchar f_name[RAMDISK_FNAME_SIZE];\n\tuint64_t f_offset;\t// data offset from ramdisk_start.\n\tuint64_t f_size;\t// data size of this file\n} __attribute__((__packed__));\n\nstruct ramdisk_sb {\n\tuint32_t file_cnt;\n\tuint32_t block_size;\t// always 4096\n\tuint64_t inode_offset;\t// inode offset\n\tuint64_t data_offset;\t// file data offset.\n\tuint64_t ramdisk_size;\t// total size of the ramdisk.\n};\n\nstruct ramdisk_file {\n\tstruct ramdisk_inode *inode;\n\tunsigned long pos;\t// reserved\n};\n\n#endif\n"
  },
  {
    "path": "generic/include/uapi/time.h",
    "content": "#ifndef __LIBMINOS_TIME_H__\n#define __LIBMINOS_TIME_H__\n\nstruct timespec {\n\tlong ts_sec;\n\tlong ts_nsec;\n};\n\n#endif\n"
  },
  {
    "path": "generic/include/uapi/virtio_mmio.h",
    "content": "#ifndef __LIBMINOS_VIRTIO_MMIO_H__\n#define __LIBMIONS_VIRTIO_MMIO_H__\n\n/*\n * for detail of the below mmio register, refer\n * to the Documents/virtio-v1.0.pdf\n */\n#define VIRTIO_MMIO_MAGIC_VALUE\t\t0x000\n#define VIRTIO_MMIO_VERSION\t\t0x004\n#define VIRTIO_MMIO_DEVICE_ID\t\t0x008\n#define VIRTIO_MMIO_VENDOR_ID\t\t0x00c\n#define VIRTIO_MMIO_HOST_FEATURES\t0x010\n#define VIRTIO_MMIO_HOST_FEATURES_SEL\t0x014\n#define VIRTIO_MMIO_GUEST_FEATURES\t0x020\n#define VIRTIO_MMIO_GUEST_FEATURES_SEL\t0x024\n#define VIRTIO_MMIO_GUEST_PAGE_SIZE\t0x028\n#define VIRTIO_MMIO_QUEUE_SEL\t\t0x030\n#define VIRTIO_MMIO_QUEUE_NUM_MAX\t0x034\n#define VIRTIO_MMIO_QUEUE_NUM\t\t0x038\n#define VIRTIO_MMIO_QUEUE_ALIGN\t\t0x03c\n#define VIRTIO_MMIO_QUEUE_READY\t\t0x044\n#define VIRTIO_MMIO_QUEUE_PFN\t\t0x040\n#define VIRTIO_MMIO_QUEUE_NOTIFY\t0x050\n#define VIRTIO_MMIO_INTERRUPT_STATUS\t0x060\n#define VIRTIO_MMIO_INTERRUPT_ACK\t0x064\n#define VIRTIO_MMIO_STATUS\t\t0x070\n#define VIRTIO_MMIO_QUEUE_DESC_LOW\t0x080\n#define VIRTIO_MMIO_QUEUE_DESC_HIGH\t0x084\n#define VIRTIO_MMIO_QUEUE_AVAIL_LOW\t0x090\n#define VIRTIO_MMIO_QUEUE_AVAIL_HIGH\t0x094\n#define VIRTIO_MMIO_QUEUE_USED_LOW\t0x0a0\n#define VIRTIO_MMIO_QUEUE_USED_HIGH\t0x0a4\n#define VIRTIO_MMIO_CONFIG_GENERATION\t0x0fc\n#define VIRTIO_MMIO_CONFIG\t\t0x100\n\n/* below register from 0x300 is used for hypervisor */\n#define VIRTIO_MMIO_GVM_ADDR\t\t0x300\n#define VIRTIO_MMIO_DEV_FLAGS\t\t0x304\n#define VIRTIO_MMIO_HOST_FEATURE0\t0x308\n#define VIRTIO_MMIO_HOST_FEATURE1\t0x30c\n#define VIRTIO_MMIO_HOST_FEATURE2\t0x310\n#define VIRTIO_MMIO_HOST_FEATURE3\t0x314\n#define VIRTIO_MMIO_DRIVER_FEATURE0\t0x318\n#define VIRTIO_MMIO_DRIVER_FEATURE1\t0x31c\n#define VIRTIO_MMIO_DRIVER_FEATURE2\t0x320\n#define VIRTIO_MMIO_DRIVER_FEATURE3\t0x324\n\n#define VIRTIO_DEVICE_IOMEM_SIZE\t0x1000\n\n#define VIRTIO_MMIO_INT_VRING\t\t(1 << 0)\n#define VIRTIO_MMIO_INT_CONFIG\t\t(1 << 1)\n\n#define VIRTIO_EVENT_BUFFER_READY\t(1 << 0)\n#define VIRTIO_EVENT_QUEUE_READY\t(1 << 1)\n#define VIRTIO_EVENT_STATUS_CHANGE\t(1 << 2)\n#define VIRTIO_EVENT_MMIO\t\t(1 << 3)\n\n#define VIRTIO_FEATURE_OFFSET(index) \\\n\t(VIRTIO_MMIO_HOST_FEATURE0 + index * 4)\n\n#endif\n"
  },
  {
    "path": "kernel/.gitignore",
    "content": "os/out/\ntools/mvm/mvm\ntags\ncscope.in.out\ncscope.out\ncscope.po.out\nlinkmap.txt\ninclude/config/config.h\n.*\n*.o\n*.o.*\n*.a\n*.s\n*.ko\n*.so\n*.so.dbg\n*.mod.c\n*.i\n*.lst\n*.symtypes\n*.order\n*.elf\n*.bin\n*.tar\n*.gz\n*.bz2\n*.lzma\n*.xz\n*.lz4\n*.lzo\n*.patch\n*.gcno\nmodules.builtin\nModule.symvers\n*.dwo\n*.su\n\n#\n# Top-level generic files\n#\n/tags\n/TAGS\n/linux\n/vmlinux\n/vmlinux.32\n/vmlinux-gdb.py\n/vmlinuz\n/System.map\n/Module.markers\n\n#\n# Debian directory (make deb-pkg)\n#\n/debian/\n\n#\n# tar directory (make tar*-pkg)\n#\n/tar-install/\n\n#\n# git files that we don't want to ignore even if they are dot-files\n#\n!.gitignore\n!.mailmap\n\n#\n# Generated include files\n#\ninclude/config/\ninclude/generated\narch/*/include/generated\n\n# stgit generated dirs\npatches-*\n\n# quilt's files\npatches\nseries\n\n# cscope files\ncscope.*\nncscope.*\n\n# gnu global files\nGPATH\nGRTAGS\nGSYMS\nGTAGS\n\n# id-utils files\nID\n\n*.orig\n*~\n\\#*#\n\n#\n# Leavings from module signing\n#\nextra_certificates\nsigning_key.pem\nsigning_key.priv\nsigning_key.x509\nx509.genkey\n\n# Kconfig presets\nall.config\n\n# Kdevelop4\n*.kdev4\n*.lds\nallsymbols.S\ntmp.minos.symbols\n*.dtb\n*.py[co]\ntools/Kconfiglib/build/\n*.egg-info/\ntools/Kconfiglib/dist/\ntools/fdt_parse/parse_dtb\nasm-offset.h\n"
  },
  {
    "path": "kernel/Kconfig",
    "content": "# Kconfig - main configuration options for Minos\n#\n# Copyright (c) 2019 Min Le <lemin9538@gmail.com>\n#\n#\nmainmenu \"Minos $ARCH Configuration\"\n\nconfig SRCARCH\n\tstring\n\toption env=\"SRCARCH\"\n\nsource \"arch/$(SRCARCH)/Kconfig\"\n"
  },
  {
    "path": "kernel/LICENSE",
    "content": "\t\t    GNU GENERAL PUBLIC LICENSE\n                       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc.,\n 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicense is intended to guarantee your freedom to share and change free\nsoftware--to make sure the software is free for all its users.  This\nGeneral Public License applies to most of the Free Software\nFoundation's software and to any other program whose authors commit to\nusing it.  (Some other Free Software Foundation software is covered by\nthe GNU Lesser General Public License instead.)  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthis service if you wish), that you receive source code or can get it\nif you want it, that you can change the software or use pieces of it\nin new free programs; and that you know you can do these things.\n\n  To protect your rights, we need to make restrictions that forbid\nanyone to deny you these rights or to ask you to surrender the rights.\nThese restrictions translate to certain responsibilities for you if you\ndistribute copies of the software, or if you modify it.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must give the recipients all the rights that\nyou have.  You must make sure that they, too, receive or can get the\nsource code.  And you must show them these terms so they know their\nrights.\n\n  We protect your rights with two steps: (1) copyright the software, and\n(2) offer you this license which gives you legal permission to copy,\ndistribute and/or modify the software.\n\n  Also, for each author's protection and ours, we want to make certain\nthat everyone understands that there is no warranty for this free\nsoftware.  If the software is modified by someone else and passed on, we\nwant its recipients to know that what they have is not the original, so\nthat any problems introduced by others will not reflect on the original\nauthors' reputations.\n\n  Finally, any free program is threatened constantly by software\npatents.  We wish to avoid the danger that redistributors of a free\nprogram will individually obtain patent licenses, in effect making the\nprogram proprietary.  To prevent this, we have made it clear that any\npatent must be licensed for everyone's free use or not licensed at all.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                    GNU GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License applies to any program or other work which contains\na notice placed by the copyright holder saying it may be distributed\nunder the terms of this General Public License.  The \"Program\", below,\nrefers to any such program or work, and a \"work based on the Program\"\nmeans either the Program or any derivative work under copyright law:\nthat is to say, a work containing the Program or a portion of it,\neither verbatim or with modifications and/or translated into another\nlanguage.  (Hereinafter, translation is included without limitation in\nthe term \"modification\".)  Each licensee is addressed as \"you\".\n\nActivities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning the Program is not restricted, and the output from the Program\nis covered only if its contents constitute a work based on the\nProgram (independent of having been made by running the Program).\nWhether that is true depends on what the Program does.\n\n  1. You may copy and distribute verbatim copies of the Program's\nsource code as you receive it, in any medium, provided that you\nconspicuously and appropriately publish on each copy an appropriate\ncopyright notice and disclaimer of warranty; keep intact all the\nnotices that refer to this License and to the absence of any warranty;\nand give any other recipients of the Program a copy of this License\nalong with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and\nyou may at your option offer warranty protection in exchange for a fee.\n\n  2. You may modify your copy or copies of the Program or any portion\nof it, thus forming a work based on the Program, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) You must cause the modified files to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in\n    whole or in part contains or is derived from the Program or any\n    part thereof, to be licensed as a whole at no charge to all third\n    parties under the terms of this License.\n\n    c) If the modified program normally reads commands interactively\n    when run, you must cause it, when started running for such\n    interactive use in the most ordinary way, to print or display an\n    announcement including an appropriate copyright notice and a\n    notice that there is no warranty (or else, saying that you provide\n    a warranty) and that users may redistribute the program under\n    these conditions, and telling the user how to view a copy of this\n    License.  (Exception: if the Program itself is interactive but\n    does not normally print such an announcement, your work based on\n    the Program is not required to print an announcement.)\n\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Program,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Program, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Program.\n\nIn addition, mere aggregation of another work not based on the Program\nwith the Program (or with a work based on the Program) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may copy and distribute the Program (or a work based on it,\nunder Section 2) in object code or executable form under the terms of\nSections 1 and 2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable\n    source code, which must be distributed under the terms of Sections\n    1 and 2 above on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three\n    years, to give any third party, for a charge no more than your\n    cost of physically performing source distribution, a complete\n    machine-readable copy of the corresponding source code, to be\n    distributed under the terms of Sections 1 and 2 above on a medium\n    customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer\n    to distribute corresponding source code.  (This alternative is\n    allowed only for noncommercial distribution and only if you\n    received the program in object code or executable form with such\n    an offer, in accord with Subsection b above.)\n\nThe source code for a work means the preferred form of the work for\nmaking modifications to it.  For an executable work, complete source\ncode means all the source code for all modules it contains, plus any\nassociated interface definition files, plus the scripts used to\ncontrol compilation and installation of the executable.  However, as a\nspecial exception, the source code distributed need not include\nanything that is normally distributed (in either source or binary\nform) with the major components (compiler, kernel, and so on) of the\noperating system on which the executable runs, unless that component\nitself accompanies the executable.\n\nIf distribution of executable or object code is made by offering\naccess to copy from a designated place, then offering equivalent\naccess to copy the source code from the same place counts as\ndistribution of the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\n  4. You may not copy, modify, sublicense, or distribute the Program\nexcept as expressly provided under this License.  Any attempt\notherwise to copy, modify, sublicense or distribute the Program is\nvoid, and will automatically terminate your rights under this License.\nHowever, parties who have received copies, or rights, from you under\nthis License will not have their licenses terminated so long as such\nparties remain in full compliance.\n\n  5. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Program or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Program (or any work based on the\nProgram), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n  6. Each time you redistribute the Program (or any work based on the\nProgram), the recipient automatically receives a license from the\noriginal licensor to copy, distribute or modify the Program subject to\nthese terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties to\nthis License.\n\n  7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Program at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Program by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under\nany particular circumstance, the balance of the section is intended to\napply and the section as a whole is intended to apply in other\ncircumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system, which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\n  8. If the distribution and/or use of the Program is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Program under this License\nmay add an explicit geographical distribution limitation excluding\nthose countries, so that distribution is permitted only in or among\ncountries not thus excluded.  In such case, this License incorporates\nthe limitation as if written in the body of this License.\n\n  9. The Free Software Foundation may publish revised and/or new versions\nof the General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and \"any\nlater version\", you have the option of following the terms and conditions\neither of that version or of any later version published by the Free\nSoftware Foundation.  If the Program does not specify a version number of\nthis License, you may choose any version ever published by the Free Software\nFoundation.\n\n  10. If you wish to incorporate parts of the Program into other free\nprograms whose distribution conditions are different, write to the author\nto ask for permission.  For software which is copyrighted by the Free\nSoftware Foundation, write to the Free Software Foundation; we sometimes\nmake exceptions for this.  Our decision will be guided by the two goals\nof preserving the free status of all derivatives of our free software and\nof promoting the sharing and reuse of software generally.\n\n                            NO WARRANTY\n\n  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\nFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\nOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\nPROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\nOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\nTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\nPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\nREPAIR OR CORRECTION.\n\n  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\nREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\nOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\nTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\nYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\nPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGES.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nconvey the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License along\n    with this program; if not, write to the Free Software Foundation, Inc.,\n    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this\nwhen it starts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) year name of author\n    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, the commands you use may\nbe called something other than `show w' and `show c'; they could even be\nmouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the program, if\nnecessary.  Here is a sample; alter the names:\n\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n\n  <signature of Ty Coon>, 1 April 1989\n  Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program into\nproprietary programs.  If your program is a subroutine library, you may\nconsider it more useful to permit linking proprietary applications with the\nlibrary.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.\n"
  },
  {
    "path": "kernel/Makefile",
    "content": "# SPDX-License-Identifier: GPL-2.0\nVERSION = 0\nPATCHLEVEL = 0\nSUBLEVEL = 1\nEXTRAVERSION =\nNAME = unstable\n\nPHONY := _all\n_all:\n\nMAKEFLAGS += -rR --no-print-directory\n\nifeq (\"$(origin V)\", \"command line\")\n  MBUILD_VERBOSE = $(V)\nendif\nifndef MBUILD_VERBOSE\n  MBUILD_VERBOSE = 0\nendif\n\nifeq ($(VERBOSE),1)\n MBUILD_VERBOSE = 1\nendif\n\nifeq ($(MBUILD_VERBOSE),1)\n  quiet =\n  Q =\nelse\n  quiet=quiet_\n  Q = @\nendif\n\nifeq (\"$(origin O)\", \"command line\")\n\tO_LEVEL = $(O)\nendif\nifndef O_LEVEL\n\tO_LEVEL = 2\nendif\n\nifeq ($(BUILD_DEBUG),1)\n  O_LEVEL = 0\nendif\n\nexport quiet Q MBUILD_VERBOSE\n\nsrctree \t:= .\nobjtree\t\t:= .\nsrc\t\t:= $(srctree)\nobj\t\t:= $(objtree)\n\nVPATH\t\t:= $(srctree)\n\nexport srctree objtree VPATH\n\nversion_h := include/config/version.h\n\nclean-targets := %clean\nno-dot-config-targets := $(clean-targets) cscope gtags TAGS tags help% $(version_h)\nno-sync-config-targets := $(no-dot-config-targets)\n\nconfig-targets  := 0\nmixed-targets   := 0\ndot-config      := 1\nmay-sync-config := 1\n\nifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)\n\tifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),)\n\t\tdot-config := 0\n\tendif\nendif\n\nifneq ($(filter $(no-sync-config-targets), $(MAKECMDGOALS)),)\n\tifeq ($(filter-out $(no-sync-config-targets), $(MAKECMDGOALS)),)\n\t\tmay-sync-config := 0\n\tendif\nendif\n\n# For \"make -j clean all\", \"make -j mrproper defconfig all\", etc.\nifneq ($(filter $(clean-targets),$(MAKECMDGOALS)),)\n        ifneq ($(filter-out $(clean-targets),$(MAKECMDGOALS)),)\n                mixed-targets := 1\n        endif\nendif\n\nifeq ($(mixed-targets),1)\n# ===========================================================================\n# We're called with mixed targets (*config and build targets).\n# Handle them one by one.\n\nPHONY += $(MAKECMDGOALS) __build_one_by_one\n\n$(filter-out __build_one_by_one, $(MAKECMDGOALS)): __build_one_by_one\n\t@:\n\n__build_one_by_one:\n\t$(Q)set -e; \\\n\tfor i in $(MAKECMDGOALS); do \\\n\t\t$(MAKE) -f $(srctree)/Makefile $$i; \\\n\tdone\n\nelse\n\ninclude scripts/Minos.config.mk\n\n# Read KERNELRELEASE from include/config/kernel.release (if it exists)\nKERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)\nKERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION)\nexport VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION\n\nARCH\t\t?= aarch64\nCROSS_COMPILE \t?= aarch64-linux-gnu-\n\nSRCARCH \t:= $(ARCH)\n\noffset_h  := $(srctree)/arch/$(SRCARCH)/include/asm/asm-offset.h\noffset_s  := $(srctree)/arch/$(SRCARCH)/core/asm-offset.s\noffset_c  := $(srctree)/arch/$(SRCARCH)/core/asm-offset.c\n\nMCONFIG_CONFIG\t?= .config\nexport MCONFIG_CONFIG\n\n# Make variables (CC, etc...)\nAS\t\t= $(CROSS_COMPILE)as\nLD\t\t= $(CROSS_COMPILE)ld\nCC\t\t= $(CROSS_COMPILE)gcc\nCPP\t\t= $(CC) -E\nAR\t\t= $(CROSS_COMPILE)ar\nNM\t\t= $(CROSS_COMPILE)nm\nSTRIP\t\t= $(CROSS_COMPILE)strip\nOBJCOPY\t\t= $(CROSS_COMPILE)objcopy\nOBJDUMP\t\t= $(CROSS_COMPILE)objdump\nLEX\t\t= flex\nYACC\t\t= bison\nAWK\t\t= awk\nPERL\t\t= perl\nPYTHON\t\t= python\nPYTHON2\t\t= python2\nPYTHON3\t\t= python3\nCHECK\t\t= sparse\nDTC\t\t= dtc\n\nCHECKFLAGS     := -D__minos__ -Dminos -D__STDC__ -Dunix -D__unix__ \\\n\t\t  -Wbitwise -Wno-return-void -Wno-unknown-attribute $(CF)\n\n# Use LINUXINCLUDE when you must reference the include/ directory.\n# Needed to be compatible with the O= option\nMINOSINCLUDE    := \\\n\t\t-I$(srctree)/arch/$(SRCARCH)/include \\\n\t\t-I$(objtree)/include \\\n\t\t-I$(srctree)/../generic/include\n\nMBUILD_AFLAGS   := -D__ASSEMBLY__\nMBUILD_CFLAGS   := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \\\n\t\t   -fno-strict-aliasing -fno-common -fshort-wchar \\\n\t\t   -Werror-implicit-function-declaration -D__KERNEL__ \\\n\t\t   -Wno-format-security -O$(O_LEVEL) -DBUILD_HYPERVISOR \\\n\t\t   -std=gnu89 --static -nostdlib -fno-builtin -g $(MINOSINCLUDE)\nMBUILD_CPPFLAGS := -D__KERNEL__\nMBUILD_LDFLAGS := --no-undefined\n\nexport ARCH SRCARCH CONFIG_SHELL HOSTCC MBUILD_HOSTCFLAGS CROSS_COMPILE AS LD CC DTC\nexport CPP AR NM STRIP OBJCOPY OBJDUMP MBUILD_HOSTLDFLAGS MBUILD_HOSTLDLIBS\nexport MAKE LEX YACC AWK GENKSYMS INSTALLKERNEL PERL PYTHON PYTHON2 PYTHON3 UTS_MACHINE\n\nexport MBUILD_CPPFLAGS NOSTDINC_FLAGS MINOSINCLUDE OBJCOPYFLAGS MBUILD_LDFLAGS\nexport MBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE\nexport CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE CFLAGS_UBSAN\nexport MBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE\nexport MBUILD_AFLAGS_KERNEL MBUILD_CFLAGS_KERNEL\n\nexport RCS_FIND_IGNORE := \\( -name SCCS -o -name BitKeeper -o -name .svn -o    \\\n\t\t\t  -name CVS -o -name .pc -o -name .hg -o -name .git \\) \\\n\t\t\t  -prune -o\nexport RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn \\\n\t\t\t --exclude CVS --exclude .pc --exclude .hg --exclude .git\n\nPHONY += all\n_all: all\n\ncore-y\t\t:= core/ userspace/\ndrivers-y\t:= drivers/ platform/\nexternal-y\t:= libs/\nlibs-y\t\t:=\n\n-include .config\ndrivers-$(CONFIG_VIRT) += virt/\n\n# The arch Makefile can set ARCH_{CPP,A,C}FLAGS to override the default\n# values of the respective MBUILD_* variables\nARCH_CPPFLAGS :=\nARCH_AFLAGS :=\nARCH_CFLAGS :=\n-include arch/$(SRCARCH)/Makefile\n\nMBUILD_IMAGE \t:= minos.bin\nMBUILD_IMAGE_ELF := minos.elf\nMBUILD_IMAGE_SYMBOLS := allsymbols.o\n\nall: include/config/config.h $(version_h) $(offset_h) minos dtbs\n\nminos-dirs\t:= $(patsubst %/,%,$(filter %/, $(core-y) $(external-y) $(drivers-y) $(libs-y)))\n\nminos-alldirs\t:= $(sort $(minos-dirs) $(patsubst %/,%,$(filter %/, \\\n\t\t\t$(core-) $(external-) $(drivers-) $(libs-))))\n\nminos-clean-dirs = $(minos-dirs)\nminos-cleandirs = $(minos-alldirs) dtbs/\n\ncore-y\t\t:= $(patsubst %/, %/built-in.o, $(core-y))\nexternal-y\t:= $(patsubst %/, %/built-in.o, $(external-y))\ndrivers-y\t:= $(patsubst %/, %/built-in.o, $(drivers-y))\nlibs-y1\t\t:= $(patsubst %/, %/lib.a, $(libs-y))\nlibs-y2\t\t:= $(patsubst %/, %/built-in.o, $(filter-out %.o, $(libs-y)))\n\n# Externally visible symbols (used by link-minos.sh)\nexport MBUILD_MINOS_INIT := $(head-y)\nexport MBUILD_MINOS_MAIN := $(core-y) $(libs-y2) $(drivers-y) $(external-y)\nexport MBUILD_MINOS_LIBS := $(libs-y1)\nexport MBUILD_LDS          := $(objtree)/arch/$(SRCARCH)/lds/minos.lds\nexport LDFLAGS_minos\n# used by scripts/package/Makefile\nexport MBUILD_ALLDIRS := $(sort $(filter-out arch/%,$(minos-alldirs)) arch Documentation include samples scripts tools)\n\nminos-deps := $(MBUILD_LDS) $(MBUILD_MINOS_INIT) $(MBUILD_MINOS_MAIN) $(MBUILD_MINOS_LIBS)\n\nCLEAN_DIRS\t:=\nclean: rm-dirs \t:= $(CLEAN_DIRS)\nclean-dirs      := $(addprefix _clean_, . $(minos-cleandirs))\n\nminos_LDFLAGS := $(MBUILD_LDFLAGS)\nminos_LDFLAGS += -T$(MBUILD_LDS) -Map=$(srctree)/linkmap.txt\n\nPHONY += $(clean-dirs) clean distclean\n$(clean-dirs):\n\t$(Q) $(MAKE) $(clean)=$(patsubst _clean_%,%,$@)\n\nminos: $(minos-deps) scripts/generate_allsymbols.py\n\t$(Q) echo \"  LD      .tmp.minos.elf\"\n\t$(Q) $(LD) $(minos_LDFLAGS) -o .tmp.minos.elf $(MBUILD_MINOS_INIT) $(MBUILD_MINOS_MAIN) $(MBUILD_MINOS_LIBS)\n\t$(Q) echo \"  NM      .tmp.minos.symbols\"\n\t$(Q) $(NM) -n .tmp.minos.elf > .tmp.minos.symbols\n\t$(Q) echo \"  PYTHON  allsymbols.S\"\n\t$(Q) python3 scripts/generate_allsymbols.py .tmp.minos.symbols allsymbols.S\n\t$(Q) echo \"  CC      $(MBUILD_IMAGE_SYMBOLS)\"\n\t$(Q) $(CC) $(CCFLAG) $(MBUILD_CFLAGS) -c allsymbols.S -o $(MBUILD_IMAGE_SYMBOLS)\n\t$(Q) echo \"  LD      $(MBUILD_IMAGE_ELF)\"\n\t$(Q) $(LD) $(minos_LDFLAGS) -o $(MBUILD_IMAGE_ELF) $(MBUILD_MINOS_INIT) $(MBUILD_MINOS_MAIN) $(MBUILD_MINOS_LIBS) $(MBUILD_IMAGE_SYMBOLS)\n\t$(Q) echo \"  OBJCOPY $(MBUILD_IMAGE)\"\n\t$(Q) $(OBJCOPY) -O binary $(MBUILD_IMAGE_ELF) $(MBUILD_IMAGE)\n\t$(Q) echo \"  OBJDUMP minos.s\"\n\t$(Q) $(OBJDUMP) $(MBUILD_IMAGE_ELF) -D > minos.s\n\n# The actual objects are generated when descending,\n# make sure no implicit rule kicks in\n$(sort $(minos-deps)): $(minos-dirs) ;\n\n# here goto each directory to generate built-in.o\nPHONY += $(minos-dirs)\n$(minos-dirs):\n\t$(Q)$(MAKE) $(build)=$@\n\ndefine sed-y\n    \"/^->/{s:->#\\(.*\\):/* \\1 */:; \\\n    s:^->\\([^ ]*\\) [\\$$#]*\\([^ ]*\\) \\(.*\\):#define \\1 \\2 /* \\3 */:; \\\n    s:->::; p;}\"\nendef\n\ndefine cmd_offsets\n    (set -e; \\\n     echo \"#ifndef __ASM_OFFSETS_H__\"; \\\n     echo \"#define __ASM_OFFSETS_H__\"; \\\n     echo \"/*\"; \\\n     echo \" * DO NOT MODIFY.\"; \\\n     echo \" *\"; \\\n     echo \" * This file was generated by Kbuild\"; \\\n     echo \" *\"; \\\n     echo \" */\"; \\\n     echo \"\"; \\\n     sed -ne $(sed-y) $<; \\\n     echo \"\"; \\\n     echo \"#endif\" ) > $@\nendef\n\ndefine filechk_version.h\n\t(echo \\#define MINOS_VERSION_CODE $(shell                         \\\n\texpr $(VERSION) \\* 65536 + 0$(PATCHLEVEL) \\* 256 + 0$(SUBLEVEL)) > $@; \\\n\techo '#define MINOS_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))' >> $@; \\\n\techo '#define MINOS_VERSION_STR \"v$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) $(NAME)\"' >> $@;)\nendef\n\nPHONY += scriptconfig iscriptconfig menuconfig guiconfig dumpvarsconfig install\n\nALL_DTS = $(notdir $(wildcard dtbs/*.dts))\nALL_DTB = $(ALL_DTS:%.dts=$(TARGET_OUT_DIR)/%.dtb)\n\n$(TARGET_OUT_DIR)/kernel.bin: minos.bin\n\t$(Q) cp minos.bin $(TARGET_OUT_DIR)/kernel.bin\n\n$(TARGET_OUT_DIR)/%.dtb: dtbs/%.dtb\n\t$(Q) cp $< $@\n\ninstall: $(TARGET_OUT_DIR)/kernel.bin $(ALL_DTB)\n\nPYTHONCMD ?= python\nkpython := PYTHONPATH=$(srctree)/scripts/Kconfiglib:$$PYTHONPATH $(PYTHONCMD)\nKCONFIG ?= $(srctree)/Kconfig\n\nifneq ($(filter scriptconfig,$(MAKECMDGOALS)),)\nifndef SCRIPT\n$(error Use \"make scriptconfig SCRIPT=<path to script> [SCRIPT_ARG=<argument>]\")\nendif\nendif\n\n$(offset_s): $(offset_c)\n\t$(Q) echo \"  CC      $(offset_s)\"\n\t$(Q) gcc $(MINOSINCLUDE) -S $< -o $@\n\n$(offset_h): $(offset_s)\n\t$(Q) $(call cmd_offsets)\n\n$(version_h) : Makefile\n\t$(Q) mkdir -p include/config\n\t$(Q) $(call filechk_version.h)\n\nPHONY += include/config/config.h\ninclude/config/config.h: .config\n\t$(Q) mkdir -p include/config\n\t$(Q) $(kpython) $(srctree)/scripts/Kconfiglib/genconfig.py --header-path=include/config/config.h\n\ndtbs: FORCE\n\t$(Q) $(MAKE) $(build)=$@\n\nclean: $(clean-dirs)\n#\t$(Q) echo \"  CLEAN   all .o .*.d *.dtb built-in.o\"\n#\t$(Q) echo \"  CLEAN   allsymbols.o allsymbols.S linkmap.txt minos.s .tmp.minos.elf .tmp.minos.symbols minos.bin minos.elf\"\n\t$(Q) rm -f allsymbols.o allsymbols.S linkmap.txt minos.s .tmp.minos.elf .tmp.minos.symbols minos.bin minos.elf\n\t$(Q) rm -rf $(offset_h)\n\t$(Q) rm -rf $(offset_s)\n\t$(Q) echo \"  Clean kernel done...\"\n\ndistclean: clean\n\t$(Q) echo \"  CLEAN   .config include/config\"\n\t$(Q) rm -rf include/config .config .config.old\n\t$(Q) echo \"  CLEAN   tags cscope.in.out cscope.out cscope.po.out\"\n\t$(Q) rm -f tags cscope.in.out cscope.out cscope.po.out\n\nscriptconfig:\n\t$(Q)$(kpython) $(SCRIPT) $(Kconfig) $(if $(SCRIPT_ARG),\"$(SCRIPT_ARG)\")\n\niscriptconfig:\n\t$(Q)$(kpython) -i -c \\\n\t  \"import kconfiglib; \\\n\t   kconf = kconfiglib.Kconfig('$(Kconfig)'); \\\n\t   print('A Kconfig instance \\'kconf\\' for the architecture $(ARCH) has been created.')\"\n\nmenuconfig:\n\t$(Q)$(kpython) $(srctree)/scripts/Kconfiglib/menuconfig.py $(Kconfig)\n\nguiconfig:\n\t$(Q)$(kpython) $(srctree)/scripts/Kconfiglib/guiconfig.py $(Kconfig)\n\ndumpvarsconfig:\n\t$(Q)$(kpython) $(srctree)/scripts/Kconfiglib/examples/dumpvars.py $(Kconfig)\n\ngenconfig:\n\t$(Q)$(kpython) $(srctree)/scripts/Kconfiglib/genconfig.py $(Kconfig)\n\n%defconfig:\n\t$(Q)test -e configs/$@ || (\t\t\\\n\techo >&2;\t\t\t\\\n\techo >&2 \"  ERROR: $@ doest exist.\";\t\t\\\n\techo >&2 ;\t\t\t\t\t\t\t\\\n\t/bin/false)\n\t$(Q) echo \"  GEN      .config From configs/$@\"\n\t$(Q) mkdir -p include/config\n\t$(Q) python $(srctree)/scripts/Kconfiglib/defconfig.py $(Kconfig) configs/$@\n\nendif\n\nPHONY += FORCE\nFORCE:\n\n# Declare the contents of the PHONY variable as phony.  We keep that\n# information in a variable so we can use it in if_changed and friends.\n.PHONY: $(PHONY)\n"
  },
  {
    "path": "kernel/VERSION",
    "content": "MAJOR_VERSION=0\nMINOR_VERSION=0\nEXTRA_VERSION=1\n\nKnown issue:\n"
  },
  {
    "path": "kernel/apps/Kconfig",
    "content": "menu \"Application Config\"\n\nconfig SHELL\n\tbool \"Shell support\"\n\tdefault n\n\thelp\n\t  \"hell support using ESH from Chris Pavlina\"\n\nsource \"apps/esh/Kconfig\"\n\nendmenu\n"
  },
  {
    "path": "kernel/apps/Makefile",
    "content": "obj-$(CONFIG_SHELL)\t+= esh/\nobj-y\t\t\t+= init.o\n"
  },
  {
    "path": "kernel/apps/esh/COPYING",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc.,\n 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicense is intended to guarantee your freedom to share and change free\nsoftware--to make sure the software is free for all its users.  This\nGeneral Public License applies to most of the Free Software\nFoundation's software and to any other program whose authors commit to\nusing it.  (Some other Free Software Foundation software is covered by\nthe GNU Lesser General Public License instead.)  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthis service if you wish), that you receive source code or can get it\nif you want it, that you can change the software or use pieces of it\nin new free programs; and that you know you can do these things.\n\n  To protect your rights, we need to make restrictions that forbid\nanyone to deny you these rights or to ask you to surrender the rights.\nThese restrictions translate to certain responsibilities for you if you\ndistribute copies of the software, or if you modify it.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must give the recipients all the rights that\nyou have.  You must make sure that they, too, receive or can get the\nsource code.  And you must show them these terms so they know their\nrights.\n\n  We protect your rights with two steps: (1) copyright the software, and\n(2) offer you this license which gives you legal permission to copy,\ndistribute and/or modify the software.\n\n  Also, for each author's protection and ours, we want to make certain\nthat everyone understands that there is no warranty for this free\nsoftware.  If the software is modified by someone else and passed on, we\nwant its recipients to know that what they have is not the original, so\nthat any problems introduced by others will not reflect on the original\nauthors' reputations.\n\n  Finally, any free program is threatened constantly by software\npatents.  We wish to avoid the danger that redistributors of a free\nprogram will individually obtain patent licenses, in effect making the\nprogram proprietary.  To prevent this, we have made it clear that any\npatent must be licensed for everyone's free use or not licensed at all.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                    GNU GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License applies to any program or other work which contains\na notice placed by the copyright holder saying it may be distributed\nunder the terms of this General Public License.  The \"Program\", below,\nrefers to any such program or work, and a \"work based on the Program\"\nmeans either the Program or any derivative work under copyright law:\nthat is to say, a work containing the Program or a portion of it,\neither verbatim or with modifications and/or translated into another\nlanguage.  (Hereinafter, translation is included without limitation in\nthe term \"modification\".)  Each licensee is addressed as \"you\".\n\nActivities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning the Program is not restricted, and the output from the Program\nis covered only if its contents constitute a work based on the\nProgram (independent of having been made by running the Program).\nWhether that is true depends on what the Program does.\n\n  1. You may copy and distribute verbatim copies of the Program's\nsource code as you receive it, in any medium, provided that you\nconspicuously and appropriately publish on each copy an appropriate\ncopyright notice and disclaimer of warranty; keep intact all the\nnotices that refer to this License and to the absence of any warranty;\nand give any other recipients of the Program a copy of this License\nalong with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and\nyou may at your option offer warranty protection in exchange for a fee.\n\n  2. You may modify your copy or copies of the Program or any portion\nof it, thus forming a work based on the Program, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) You must cause the modified files to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in\n    whole or in part contains or is derived from the Program or any\n    part thereof, to be licensed as a whole at no charge to all third\n    parties under the terms of this License.\n\n    c) If the modified program normally reads commands interactively\n    when run, you must cause it, when started running for such\n    interactive use in the most ordinary way, to print or display an\n    announcement including an appropriate copyright notice and a\n    notice that there is no warranty (or else, saying that you provide\n    a warranty) and that users may redistribute the program under\n    these conditions, and telling the user how to view a copy of this\n    License.  (Exception: if the Program itself is interactive but\n    does not normally print such an announcement, your work based on\n    the Program is not required to print an announcement.)\n\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Program,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Program, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Program.\n\nIn addition, mere aggregation of another work not based on the Program\nwith the Program (or with a work based on the Program) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may copy and distribute the Program (or a work based on it,\nunder Section 2) in object code or executable form under the terms of\nSections 1 and 2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable\n    source code, which must be distributed under the terms of Sections\n    1 and 2 above on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three\n    years, to give any third party, for a charge no more than your\n    cost of physically performing source distribution, a complete\n    machine-readable copy of the corresponding source code, to be\n    distributed under the terms of Sections 1 and 2 above on a medium\n    customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer\n    to distribute corresponding source code.  (This alternative is\n    allowed only for noncommercial distribution and only if you\n    received the program in object code or executable form with such\n    an offer, in accord with Subsection b above.)\n\nThe source code for a work means the preferred form of the work for\nmaking modifications to it.  For an executable work, complete source\ncode means all the source code for all modules it contains, plus any\nassociated interface definition files, plus the scripts used to\ncontrol compilation and installation of the executable.  However, as a\nspecial exception, the source code distributed need not include\nanything that is normally distributed (in either source or binary\nform) with the major components (compiler, kernel, and so on) of the\noperating system on which the executable runs, unless that component\nitself accompanies the executable.\n\nIf distribution of executable or object code is made by offering\naccess to copy from a designated place, then offering equivalent\naccess to copy the source code from the same place counts as\ndistribution of the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\n  4. You may not copy, modify, sublicense, or distribute the Program\nexcept as expressly provided under this License.  Any attempt\notherwise to copy, modify, sublicense or distribute the Program is\nvoid, and will automatically terminate your rights under this License.\nHowever, parties who have received copies, or rights, from you under\nthis License will not have their licenses terminated so long as such\nparties remain in full compliance.\n\n  5. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Program or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Program (or any work based on the\nProgram), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n  6. Each time you redistribute the Program (or any work based on the\nProgram), the recipient automatically receives a license from the\noriginal licensor to copy, distribute or modify the Program subject to\nthese terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties to\nthis License.\n\n  7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Program at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Program by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under\nany particular circumstance, the balance of the section is intended to\napply and the section as a whole is intended to apply in other\ncircumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system, which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\n  8. If the distribution and/or use of the Program is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Program under this License\nmay add an explicit geographical distribution limitation excluding\nthose countries, so that distribution is permitted only in or among\ncountries not thus excluded.  In such case, this License incorporates\nthe limitation as if written in the body of this License.\n\n  9. The Free Software Foundation may publish revised and/or new versions\nof the General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and \"any\nlater version\", you have the option of following the terms and conditions\neither of that version or of any later version published by the Free\nSoftware Foundation.  If the Program does not specify a version number of\nthis License, you may choose any version ever published by the Free Software\nFoundation.\n\n  10. If you wish to incorporate parts of the Program into other free\nprograms whose distribution conditions are different, write to the author\nto ask for permission.  For software which is copyrighted by the Free\nSoftware Foundation, write to the Free Software Foundation; we sometimes\nmake exceptions for this.  Our decision will be guided by the two goals\nof preserving the free status of all derivatives of our free software and\nof promoting the sharing and reuse of software generally.\n\n                            NO WARRANTY\n\n  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\nFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\nOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\nPROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\nOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\nTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\nPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\nREPAIR OR CORRECTION.\n\n  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\nREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\nOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\nTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\nYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\nPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGES.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nconvey the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License along\n    with this program; if not, write to the Free Software Foundation, Inc.,\n    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this\nwhen it starts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) year name of author\n    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, the commands you use may\nbe called something other than `show w' and `show c'; they could even be\nmouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the program, if\nnecessary.  Here is a sample; alter the names:\n\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n\n  <signature of Ty Coon>, 1 April 1989\n  Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program into\nproprietary programs.  If your program is a subroutine library, you may\nconsider it more useful to permit linking proprietary applications with the\nlibrary.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.\n"
  },
  {
    "path": "kernel/apps/esh/Kconfig",
    "content": "if SHELL\n\nmenu \"Shell config\"\n\nconfig SHELL_TASK_PRIO\n\tint \"The priority of shell task\"\n\tdefault 63\n\nendmenu\n\nendif\n"
  },
  {
    "path": "kernel/apps/esh/Makefile",
    "content": "obj-$(CONFIG_SHELL)\t+= shell.o esh.o esh_hist.o esh_argparser.o\n"
  },
  {
    "path": "kernel/apps/esh/README.md",
    "content": "esh - embedded shell\n====================\n\nesh is a lightweight command shell for embedded applications in C or Rust,\nsmall enough to be used for (and intended for) debug UART consoles on\nmicrocontrollers.\n\nThis readme describes esh and how to try it out. If you think you'd like to\nuse it, see the guides in the source for informations on how to set it up and\nintegrate it into your project: [C header](esh.h),\n[Rust library](esh_rust/src/esh/lib.rs).\n\nDemo\n====\n\nThere is a simple demo in the `demo` subdirectory, which can be compiled and\nrun on a unix-like system by moving into that directory and issuing the `make`\ncommand. There are no dependencies other than libc and a compiler. Once built,\nexecute `./demo` and try it out!\n\nThe Rust demo is in `demo_rust`, and can be compiled and run on a unix-like\nsystem by moving into that directory and issuing `cargo build` and `cargo run`.\n\nFeatures\n========\n\nLine editing\n------------\n\nesh supports basic line editing, understanding the backspace key to delete\ncharacters, left and right arrow to move the insertion point, and Ctrl-C\nto ditch the entire line. Ctrl-left/right to move by a word is upcoming.\n\nArgument tokenizing\n-------------------\n\nesh automatically splits a command string into arguments, and understands\nbash-style quoting. The command handler callback receives a simple\nargc/argv array of arguments, ready to use. Environment variables are not yet\nsupported, but may be in the future.\n\nHistory (optional)\n------------------\n\nIf compiled in, esh supports history, allowing the use of the up/down arrow keys\nto browse previously entered commands and edit/re-issue them. A ring buffer is\nused to store a fixed number of characters, so more commands can be remembered\nif they're shorter.\n"
  },
  {
    "path": "kernel/apps/esh/esh.c",
    "content": "/*\n * esh - embedded shell\n * Copyright (C) 2017 Chris Pavlina\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n */\n#include \"esh.h\"\n#define ESH_INTERNAL_INCLUDE\n#include \"esh_argparser.h\"\n#include \"esh_internal.h\"\n#include <minos/string.h>\n\nenum esh_flags {\n    IN_ESCAPE = 0x01,\n    IN_BRACKET_ESCAPE = 0x02,\n    IN_NUMERIC_ESCAPE = 0x04,\n};\n\nstatic struct esh * allocate_esh(void);\nstatic void free_last_allocated(struct esh * esh);\nstatic void do_print_callback(struct esh * esh, char c);\nstatic void do_command(struct esh * esh, int argc, char ** argv);\nstatic void do_overflow_callback(struct esh * esh, char const * buffer);\nstatic bool command_is_nop(struct esh * esh);\nstatic void execute_command(struct esh * esh);\nstatic void handle_char(struct esh * esh, char c);\nstatic void handle_esc(struct esh * esh, char esc);\nstatic void handle_ctrl(struct esh * esh, char c);\nstatic void ins_del(struct esh * esh, char c);\nstatic void term_cursor_move(struct esh * esh, int n);\nstatic void cursor_move(struct esh * esh, int n);\nstatic void word_move(struct esh * esh, int dir);\n\nvoid esh_default_overflow(struct esh * esh, char const * buffer, void * arg);\n\n#ifdef ESH_STATIC_CALLBACKS\nextern void ESH_PRINT_CALLBACK(struct esh * esh, char c, void * arg);\nextern void ESH_COMMAND_CALLBACK(\n    struct esh * esh, int argc, char ** argv, void * arg);\n__attribute__((weak))\nvoid ESH_OVERFLOW_CALLBACK(struct esh * esh, char const * buffer, void * arg)\n{\n    (void) arg;\n    esh_default_overflow(esh, buffer, arg);\n}\n#else\nvoid esh_register_command(struct esh * esh, esh_cb_command callback)\n{\n    (void) esh;\n    ESH_INSTANCE->cb_command = callback;\n}\n\n\nvoid esh_register_print(struct esh * esh, esh_cb_print callback)\n{\n    (void) esh;\n    ESH_INSTANCE->print = callback;\n}\n\n\nvoid esh_register_overflow(struct esh * esh, esh_cb_overflow overflow)\n{\n    (void) esh;\n    ESH_INSTANCE->overflow = (overflow ? overflow : &esh_default_overflow);\n}\n#endif\n\n// API WARNING: This function is separately declared in lib.rs\nvoid esh_set_command_arg(struct esh * esh, void * arg)\n{\n    (void) esh;\n    ESH_INSTANCE->cb_command_arg = arg;\n}\n\n// API WARNING: This function is separately declared in lib.rs\nvoid esh_set_print_arg(struct esh * esh, void * arg)\n{\n    (void) esh;\n    ESH_INSTANCE->cb_print_arg = arg;\n}\n\n// API WARNING: This function is separately declared in lib.rs\nvoid esh_set_overflow_arg(struct esh * esh, void * arg)\n{\n    (void) esh;\n    ESH_INSTANCE->cb_overflow_arg = arg;\n}\n\nstatic void do_print_callback(struct esh * esh, char c)\n{\n    (void) esh;\n#ifdef ESH_STATIC_CALLBACKS\n    ESH_PRINT_CALLBACK(ESH_INSTANCE, c, ESH_INSTANCE->cb_print_arg);\n#else\n    ESH_INSTANCE->print(ESH_INSTANCE, c, ESH_INSTANCE->cb_print_arg);\n#endif\n}\n\n\nstatic void do_command(struct esh * esh, int argc, char ** argv)\n{\n    (void) esh;\n#ifdef ESH_STATIC_CALLBACKS\n    ESH_COMMAND_CALLBACK(ESH_INSTANCE, argc, argv, ESH_INSTANCE->cb_command_arg);\n#else\n    ESH_INSTANCE->cb_command(ESH_INSTANCE, argc, argv, ESH_INSTANCE->cb_command_arg);\n#endif\n}\n\n\nstatic void do_overflow_callback(struct esh * esh, char const * buffer)\n{\n    (void) esh;\n#ifdef ESH_STATIC_CALLBACKS\n    ESH_OVERFLOW_CALLBACK(ESH_INSTANCE, buffer, ESH_INSTANCE->cb_overflow_arg);\n#else\n    ESH_INSTANCE->overflow(ESH_INSTANCE, buffer, ESH_INSTANCE->cb_overflow_arg);\n#endif\n}\n\n\n/**\n * For the static allocator, this is global so free_last_allocated() can\n * decrement it.\n */\n#if ESH_ALLOC == STATIC\nstatic bool g_allocated = false;\nstruct esh g_esh_struct;\n#endif\n\n/**\n * Allocate a new struct esh, or return a new statically allocated one from the pool.\n * This does not perform initialization.\n */\nstatic struct esh * allocate_esh(void)\n{\n#if ESH_ALLOC == STATIC\n    if (g_allocated) {\n        return NULL;\n    } else {\n        g_allocated = true;\n        return &g_esh_struct;\n    }\n#elif ESH_ALLOC == MALLOC\n    return malloc(sizeof(struct esh));\n#else\n#   error \"ESH_ALLOC must be STATIC or MALLOC\"\n#endif\n}\n\n\n/**\n * Free the last struct esh that was allocated, in case an initialization error\n * occurs after allocation.\n */\nstatic void free_last_allocated(struct esh *esh)\n{\n#if ESH_ALLOC == STATIC\n    (void) esh;\n    g_allocated = false;\n#elif ESH_ALLOC == MALLOC\n    free(esh);\n#endif\n}\n\n\n// API WARNING: This function is separately declared in lib.rs\nstruct esh * esh_init(void)\n{\n    struct esh * esh = allocate_esh();\n\n    memset(esh, 0, sizeof(*esh));\n#ifndef ESH_STATIC_CALLBACKS\n    esh->overflow = &esh_default_overflow;\n#endif\n\n    if (esh_hist_init(ESH_INSTANCE)) {\n        free_last_allocated(ESH_INSTANCE);\n        return NULL;\n    } else {\n        return esh;\n    }\n}\n\n\n// API WARNING: This function is separately declared in lib.rs\nvoid esh_rx(struct esh * esh, char c)\n{\n    (void) esh;\n    if (ESH_INSTANCE->flags & (IN_BRACKET_ESCAPE | IN_NUMERIC_ESCAPE)) {\n        handle_esc(ESH_INSTANCE, c);\n    } else if (ESH_INSTANCE->flags & IN_ESCAPE) {\n        if (c == '[' || c == 'O') {\n            ESH_INSTANCE->flags |= IN_BRACKET_ESCAPE;\n        } else {\n            ESH_INSTANCE->flags &= ~(IN_ESCAPE | IN_BRACKET_ESCAPE);\n        }\n    } else {\n        // Verify the c is valid non-extended ASCII (and thus also valid\n        // UTF-8, for Rust), regardless of whether this platform's isprint()\n        // accepts things above 0x7f.\n        if (c >= 0x20 && (unsigned char) c < 0x7f) {\n            handle_char(ESH_INSTANCE, c);\n        } else {\n            handle_ctrl(ESH_INSTANCE, c);\n        }\n    }\n}\n\n\n/**\n * Process a normal text character. If there is room in the buffer, it is\n * inserted directly. Otherwise, the buffer is set into the overflow state.\n */\nstatic void handle_char(struct esh * esh, char c)\n{\n    (void) esh;\n    esh_hist_substitute(ESH_INSTANCE);\n\n    if (ESH_INSTANCE->cnt < ESH_BUFFER_LEN) {\n        ins_del(ESH_INSTANCE, c);\n    } else {\n        // If we let esh->cnt keep counting past the buffer limit, it could\n        // eventually wrap around. Let it sit right past the end, and make sure\n        // there is a NUL terminator in the buffer (we promise the overflow\n        // handler that).\n        ESH_INSTANCE->cnt = ESH_BUFFER_LEN + 1;\n\n        // Note that the true buffer length is actually one greater than\n        // ESH_BUFFER_LEN (which is the number of characters NOT including the\n        // terminator that it can hold).\n        ESH_INSTANCE->buffer[ESH_BUFFER_LEN] = 0;\n    }\n}\n\n\n/**\n * Process a single-character control byte.\n */\nstatic void handle_ctrl(struct esh * esh, char c)\n{\n    (void) esh;\n    switch (c) {\n        case 27: // escape\n            ESH_INSTANCE->flags |= IN_ESCAPE;\n            break;\n        case 3:  // ^C\n            esh_puts_flash(ESH_INSTANCE, FSTR(\"^C\\n\"));\n            esh_print_prompt(ESH_INSTANCE);\n            ESH_INSTANCE->cnt = ESH_INSTANCE->ins = 0;\n            break;\n        case '\\n':\n            execute_command(ESH_INSTANCE);\n            break;\n        case 8:     // backspace\n        case 127:   // delete\n            esh_hist_substitute(ESH_INSTANCE);\n            if (ESH_INSTANCE->cnt > 0 && ESH_INSTANCE->cnt <= ESH_BUFFER_LEN) {\n                ins_del(ESH_INSTANCE, 0);\n            }\n            break;\n        default:\n            // nop\n            ;\n    }\n}\n\n\n/**\n * Process the last character in an escape sequence.\n */\nstatic void handle_esc(struct esh * esh, char esc)\n{\n    (void) esh;\n    int cdelta;\n\n    if (esc >= '0' && esc <= '9') {\n        ESH_INSTANCE->flags\n            |= IN_ESCAPE | IN_BRACKET_ESCAPE | IN_NUMERIC_ESCAPE;\n        return;\n    }\n\n    if (ESH_INSTANCE->flags & IN_NUMERIC_ESCAPE) {\n        // Numeric escapes can contain numbers and semicolons; they terminate\n        // at letters and ~\n        if (esc == '~' || isalpha(esc)) {\n            ESH_INSTANCE->flags\n                &= ~(IN_BRACKET_ESCAPE | IN_NUMERIC_ESCAPE | IN_ESCAPE);\n        }\n    } else {\n        ESH_INSTANCE->flags\n            &= ~(IN_BRACKET_ESCAPE | IN_NUMERIC_ESCAPE | IN_ESCAPE);\n    }\n\n    switch (esc) {\n    case ESCCHAR_UP:\n    case ESCCHAR_DOWN:\n        if (esc == ESCCHAR_UP) {\n            ++ESH_INSTANCE->hist.idx;\n        } else if (ESH_INSTANCE->hist.idx) {\n            --ESH_INSTANCE->hist.idx;\n        }\n        if (ESH_INSTANCE->hist.idx) {\n            int offset = esh_hist_nth(ESH_INSTANCE,\n                    ESH_INSTANCE->hist.idx - 1);\n            if (offset >= 0 || esc == ESCCHAR_DOWN) {\n                esh_hist_print(ESH_INSTANCE, offset);\n            } else if (esc == ESCCHAR_UP) {\n                // Don't overscroll the top\n                --ESH_INSTANCE->hist.idx;\n            }\n        } else {\n            esh_restore(ESH_INSTANCE);\n        }\n        break;\n\n    case ESCCHAR_LEFT:\n        cdelta = -1;\n        goto cmove;\n    case ESCCHAR_RIGHT:\n        cdelta = 1;\n        goto cmove;\n    case ESCCHAR_HOME:\n        cdelta = -ESH_INSTANCE->ins;\n        goto cmove;\n    case ESCCHAR_END:\n        cdelta = ESH_INSTANCE->cnt - ESH_INSTANCE->ins;\n        goto cmove;\n    case ESCCHAR_CTRLLEFT:\n        cdelta = -1;\n        goto wmove;\n    case ESCCHAR_CTRLRIGHT:\n        cdelta = 1;\n        goto wmove;\n    }\n\n    return;\ncmove: // micro-optimization, yo!\n    cursor_move(ESH_INSTANCE, cdelta);\n    return;\nwmove:\n    word_move(ESH_INSTANCE, cdelta);\n}\n\n\n/**\n * Return whether the command in the edit buffer is a NOP and should be ignored.\n * This does not substitute the selected history item.\n */\nstatic bool command_is_nop(struct esh * esh)\n{\n    int i;\n\n    (void) esh;\n    for (i = 0; ESH_INSTANCE->buffer[i]; ++i) {\n        if (ESH_INSTANCE->buffer[i] != ' ') {\n            return false;\n        }\n    }\n    return true;\n}\n\n\n/**\n * Process the command in the buffer and give it to the command callback. If\n * the buffer has overflowed, call the overflow callback instead.\n */\nstatic void execute_command(struct esh * esh)\n{\n    (void) esh;\n\n    // If a command from the history is selected, put it in the edit buffer.\n    esh_hist_substitute(ESH_INSTANCE);\n\n    if (ESH_INSTANCE->cnt >= ESH_BUFFER_LEN) {\n        do_overflow_callback(ESH_INSTANCE, ESH_INSTANCE->buffer);\n        ESH_INSTANCE->cnt = ESH_INSTANCE->ins = 0;\n        esh_print_prompt(ESH_INSTANCE);\n        return;\n    } else {\n        ESH_INSTANCE->buffer[ESH_INSTANCE->cnt] = 0;\n    }\n\n    esh_putc(ESH_INSTANCE, '\\n');\n\n    if (!command_is_nop(ESH_INSTANCE)) {\n        esh_hist_add(ESH_INSTANCE, ESH_INSTANCE->buffer);\n\n        int argc = esh_parse_args(ESH_INSTANCE);\n\n        if (argc > ESH_ARGC_MAX) {\n            do_overflow_callback(ESH_INSTANCE, ESH_INSTANCE->buffer);\n        } else if (argc > 0) {\n            do_command(ESH_INSTANCE, argc, ESH_INSTANCE->argv);\n        }\n    }\n\n    ESH_INSTANCE->cnt = ESH_INSTANCE->ins = 0;\n    esh_print_prompt(ESH_INSTANCE);\n}\n\n\nvoid esh_print_prompt(struct esh * esh)\n{\n    (void) esh;\n    esh_puts_flash(ESH_INSTANCE, FSTR(ESH_PROMPT));\n}\n\n\n/**\n * Default overflow callback. This just prints a message.\n */\n// API WARNING: This function is separately declared in lib.rs\nvoid esh_default_overflow(struct esh * esh, char const * buffer, void * arg)\n{\n    (void) esh;\n    (void) buffer;\n    (void) arg;\n    esh_puts_flash(ESH_INSTANCE, FSTR(\"\\nesh: command buffer overflow\\n\"));\n}\n\n\nbool esh_putc(struct esh * esh, char c)\n{\n    (void) esh;\n\n    do_print_callback(ESH_INSTANCE, c);\n    return false;\n}\n\n\nbool esh_puts(struct esh * esh, char const * s)\n{\n    (void) esh;\n    char c;\n\n    while ((c = *s++)) {\n        esh_putc(ESH_INSTANCE, c);\n    }\n    return false;\n}\n\n\n#ifdef __AVR_ARCH__\nbool esh_puts_flash(struct esh * esh, char const __flash * s)\n{\n    (void) esh;\n    char c;\n\n    while ((c = *s++)) {\n        esh_putc(ESH_INSTANCE, c);\n    }\n    return false;\n}\n#endif // __AVR_ARCH__\n\n\nvoid esh_restore(struct esh * esh)\n{\n    (void) esh;\n\n    esh_puts_flash(ESH_INSTANCE, FSTR(ESC_ERASE_LINE \"\\r\")); // Clear line\n    esh_print_prompt(ESH_INSTANCE);\n    ESH_INSTANCE->buffer[ESH_INSTANCE->cnt] = 0;\n    esh_puts(ESH_INSTANCE, ESH_INSTANCE->buffer);\n    term_cursor_move(ESH_INSTANCE,\n            -(int)(ESH_INSTANCE->cnt - ESH_INSTANCE->ins));\n}\n\n\n#ifdef ESH_RUST\n// API WARNING: This function is separately declared in lib.rs\nsize_t esh_get_slice_size(void)\n{\n    return sizeof (struct char_slice);\n}\n#endif\n\n\n/**\n * Move only the terminal cursor. This does not move the insertion point.\n */\nstatic void term_cursor_move(struct esh * esh, int n)\n{\n    (void) esh;\n\n    for ( ; n > 0; --n) {\n        esh_puts_flash(ESH_INSTANCE, FSTR(ESC_CURSOR_RIGHT));\n    }\n\n    for ( ; n < 0; ++n) {\n        esh_puts_flash(ESH_INSTANCE, FSTR(ESC_CURSOR_LEFT));\n    }\n}\n\n\n/**\n * Move the esh cursor. This applies history substitution, moves the terminal\n * cursor, and moves the insertion point.\n */\nstatic void cursor_move(struct esh * esh, int n)\n{\n    (void) esh;\n\n    esh_hist_substitute(ESH_INSTANCE);\n    if ((int) ESH_INSTANCE->ins + n < 0) {\n        n = -ESH_INSTANCE->ins;\n    } else if ((int) ESH_INSTANCE->ins + n > (int) ESH_INSTANCE->cnt) {\n        n = ESH_INSTANCE->cnt - ESH_INSTANCE->ins;\n    }\n\n    term_cursor_move(ESH_INSTANCE, n);\n    ESH_INSTANCE->ins += n;\n}\n\n\n/**\n * Move the esh cursor backwards or forwards one word. This applies history\n * substitution, moves the terminal cursor, and moves the insertion point.\n *\n * @param dir - move forward if +1 or negative if -1. All other numbers produce\n *              undefined behavior.\n */\nstatic void word_move(struct esh * esh, int dir)\n{\n    (void) esh;\n\n    size_t ins = ESH_INSTANCE->ins;\n    esh_hist_substitute(ESH_INSTANCE);\n\n    if (dir == 0) {\n        return;\n    } else if (dir < 0) {\n        for (; ins > 0 && ESH_INSTANCE->buffer[ins - 1] == ' '; --ins);\n        for (; ins > 0 && ESH_INSTANCE->buffer[ins - 1] != ' '; --ins);\n    } else {\n        const size_t cnt = ESH_INSTANCE->cnt;\n        for (; ins < cnt && ESH_INSTANCE->buffer[ins] != ' '; ++ins);\n        for (; ins < cnt && ESH_INSTANCE->buffer[ins] == ' '; ++ins);\n    }\n\n    term_cursor_move(ESH_INSTANCE, ins - ESH_INSTANCE->ins);\n    ESH_INSTANCE->ins = ins;\n}\n\n\n/**\n * Either insert or delete a character at the current insertion point.\n * @param esh - esh instance\n * @param c - character to insert, or 0 to delete\n */\nstatic void ins_del(struct esh * esh, char c)\n{\n    (void) esh;\n\n    int sgn = c ? 1 : -1;\n    bool move = (ESH_INSTANCE->ins != ESH_INSTANCE->cnt);\n\n    memmove(&ESH_INSTANCE->buffer[ESH_INSTANCE->ins + sgn],\n            &ESH_INSTANCE->buffer[ESH_INSTANCE->ins],\n            ESH_INSTANCE->cnt - ESH_INSTANCE->ins);\n\n    if (c) {\n        ESH_INSTANCE->buffer[ESH_INSTANCE->ins] = c;\n    }\n\n    ESH_INSTANCE->cnt += sgn;\n    ESH_INSTANCE->ins += sgn;\n\n    if (move) {\n        esh_restore(ESH_INSTANCE);\n    } else if (!c) {\n        esh_puts_flash(ESH_INSTANCE, FSTR(\"\\b \\b\"));\n    } else {\n        esh_putc(ESH_INSTANCE, c);\n    }\n}\n"
  },
  {
    "path": "kernel/apps/esh/esh.h",
    "content": "/**\n * esh - embedded shell\n * ====================\n *\n * *****************************************************************************\n * * PLEASE read ALL of this documentation (all comment blocks starting with a *\n * * double-asterisk **). esh is simple, but a number of things need to be     *\n * * addressed by every esh user.                                              *\n * *****************************************************************************\n *\n * esh is a lightweight command shell for embedded applications in C or rust,\n * small enough to be used for (and intended for) debug UART consoles on\n * microcontrollers. Features include line editing, automatic argument\n * tokenizing (including sh-like quoting), and an optional history ring buffer.\n *\n * esh - embedded shell\n * Copyright (C) 2017 Chris Pavlina\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * -----------------------------------------------------------------------------\n *\n * 1.   Rust users\n * 2.   Configuring esh\n * 2.1.     Line endings\n * 2.2.     Static callbacks\n * 2.3.     History (optional)\n * 3.   Compiling esh\n * 4.   Code documentation\n * 4.1.     Basic interface: initialization and input\n * 4.2.     Callback types and registration functions\n * 4.3.     Advanced functions\n *\n * -----------------------------------------------------------------------------\n *\n * 1. Rust users\n * =============\n *\n * The Rust API and configuration is different, so if you want to use esh with\n * Rust, see esh_rust/src/esh/lib.rs for separate documentation. None of this\n * documentation (including the definitions for `esh_config.h`) applies.\n *\n * 2. Configuring esh\n * ==================\n *\n * esh expects a file called `esh_config.h` to be on the quoted include path. It\n * should define the following:\n *\n *     #define ESH_PROMPT       \"% \"        // Prompt string\n *     #define ESH_BUFFER_LEN   200         // Maximum length of a command\n *     #define ESH_ARGC_MAX     10          // Maximum argument count\n *     #define ESH_ALLOC        STATIC      // How to allocate struct esh (or MALLOC)\n *\n * Then, to use esh, include `esh.h`, and initialize an esh instance with:\n *\n *     struct esh * esh = esh_init();\n *\n * Unless you're using static callbacks (see below), register your callbacks\n * with:\n *\n *     esh_register_command(esh, &command_callback);\n *     esh_register_print(esh, &print_callback);\n *\n *     // Optional, see the documentation for this function:\n *     esh_register_overflow(esh, &overflow_callback);\n *\n * Now, just begin receiving characters from your serial interface and feeding\n * them in with:\n *\n *     esh_rx(esh, c);\n *\n * 2.1. Line endings\n * -----------------\n *\n * Internally, esh uses strictly `\\n` line endings. A great many IO sources use\n * different line endings; the user is responsible for translating them for esh.\n * In general, most raw-mode unix-like terminals will give `\\r` from the\n * keyboard and require `\\r\\n` as output, so your input functions should\n * translate `\\r` to `\\n`, and your output function should insert `\\r` before\n * `\\n`.\n *\n * 2.2. Static callbacks\n * ---------------------\n *\n * If you're only using one esh instance, or all your esh instances use the\n * same callbacks, callbacks can be compiled in statically, saving a bit of code\n * space, runtime, and RAM from keeping and following the pointers. Add the\n * following to your `esh_config.h`:\n *\n *     #define ESH_STATIC_CALLBACKS\n *\n * Now, simply name your callback functions `ESH_PRINT_CALLBACK`,\n * `ESH_COMMAND_CALLBACK`, and `ESH_OVERFLOW_CALLBACK` (the overflow callback\n * is still optional), and the linker will find them. The esh_register_*\n * functions are not defined when ESH_STATIC_CALLBACKS is set.\n *\n * 2.3. History (optional)\n * -----------------------\n *\n * To enable the optional history, define the following in `esh_config.h`:\n *\n *     #define ESH_HIST_ALLOC   STATIC      // STATIC, MANUAL, or MALLOC\n *     #define ESH_HIST_LEN     512         // Length. Use powers of 2 for\n *                                          //   efficiency on arithmetic-weak\n *                                          //   devices.\n *\n * If you chose `MANUAL` allocation, call `esh_set_histbuf()` once you have\n * allocated your own buffer of length ESH_HIST_LEN:\n *\n *     esh_set_histbuf(esh, &buffer[0]);\n *\n * Manual allocation was created for one specific purpose: history buffer in\n * external SRAM on AVR (the compiler and allocator don't generally know about\n * external SRAM unless you jump through hoops). However, it's there for\n * whatever you like :)\n *\n * WARNING: static allocation is only valid when using a SINGLE esh instance.\n * Using multiple esh instances with static allocation is undefined and WILL\n * make demons fly out your nose.\n *\n * 3. Compiling esh\n * ================\n *\n * esh has no build script of its own; building it is trivial and it's meant to\n * be integrated directly into your project.\n *\n *  1. Put the `esh` subdirectory on the include path.\n *  2. Make sure `esh_config.h` is on the quoted include path (`-iquote`).\n *  3. Make sure selected C standard is one of `c99`, `c11`, `gnu99`, or\n *       `gnu11`. On AVR, use only `gnu99` or `gnu11` (esh on AVR uses the\n *       Named Address Spaces GNU extension).\n *  4. Include *all* esh C source files in the build (whether or not you used\n *       the feature - e.g. esh_hist.c).\n *\n * esh should compile quietly with most warning settings, including\n * `-Wall -Wextra -pedantic`.\n */\n\n#ifndef ESH_H\n#define ESH_H\n\n#define ESH_INTERNAL_INCLUDE\n#include \"esh_incl_config.h\"\n#include \"esh_hist.h\"\n#undef ESH_INTERNAL_INCLUDE\n#include <minos/types.h>\n\nstruct esh;\n\n/**\n * -----------------------------------------------------------------------------\n *\n * 4. Code documentation\n */\n\n/**\n * -----------------------------------------------------------------------------\n * 4.1. Basic interface: initialization and input\n */\n\n/*\n * Return a pointer to an initialized esh object. Must be called before\n * any other functions.\n *\n * See ESH_ALLOC in esh_config.h - this should be STATIC or MALLOC.\n * If STATIC, only a single instance can be used. esh_init() will return a\n * pointer to it on the first call, and all subsequent calls will return\n * NULL.\n *\n * @return esh instance, or NULL in the following cases:\n *  - using malloc to allocate either the esh struct itself or the history\n *      buffer, and malloc returns NULL.\n *  - using static allocation and esh has already been initialized.\n *  - whichever allocation method was chosen for ESH_HIST_ALLOC, if any,\n *      failed.\n */\nstruct esh *esh_init(void);\n\n/**\n * Pass in a character that was received.\n */\nvoid esh_rx(struct esh * esh, char c);\n\n#ifndef ESH_STATIC_CALLBACKS\n/**\n * -----------------------------------------------------------------------------\n * 4.2. Callback types and registration functions\n *\n * These only exist if ESH_STATIC_CALLBACKS is not defined.\n */\n\n/**\n * Callback to handle commands.\n * @param argc - number of arguments, including the command name\n * @param argv - arguments\n * @param arg - arbitrary argument passed to esh_set_command_arg()\n */\ntypedef void (*esh_cb_command)(struct esh *esh,\n\t\tint argc, char **argv, void *arg);\n\n/**\n * Callback to print a character.\n * @param esh - the esh instance calling\n * @param c - the character to print\n * @param arg - arbitrary argument passed to esh_set_print_arg()\n */\ntypedef void (*esh_cb_print)(struct esh * esh, char c, void *arg);\n\n/**\n * Callback to notify about overflow.\n * @param esh - the esh instance calling\n * @param buffer - the internal buffer, NUL-terminated\n * @param arg - arbitrary argument passed to esh_set_overflow_arg()\n */\ntypedef void (*esh_cb_overflow)(struct esh *esh,\n\t\tchar const *buffer, void *rg);\n\n/**\n * Register a callback to execute a command.\n */\nvoid esh_register_command(struct esh *esh, esh_cb_command callback);\n\n/**\n * Register a callback to print a character.\n */\nvoid esh_register_print(struct esh *esh, esh_cb_print callback);\n\n/**\n * Register a callback to notify about overflow. Optional; esh has an internal\n * overflow handler. To reset to that, set the handler to NULL.\n */\nvoid esh_register_overflow(struct esh *esh, esh_cb_overflow overflow);\n#endif\n\n/**\n * -----------------------------------------------------------------------------\n * 4.3. Advanced functions\n */\n\n/**\n * Set the location of the history buffer, if ESH_HIST_ALLOC is defined and\n * set to MANUAL. If ESH_HIST_ALLOC is not defined or not set to MANUAL, this\n * is a no-op.\n */\nvoid esh_set_histbuf(struct esh *esh, char *buffer);\n\n/**\n * Set an argument to be given to the command callback. Default is NULL.\n */\nvoid esh_set_command_arg(struct esh *esh, void *arg);\n\n/**\n * Set an argument to be given to the print callback. Default is NULL.\n */\nvoid esh_set_print_arg(struct esh * esh, void *arg);\n\n/**\n * Set an argument to be given to the overflow callback. Default is NULL.\n */\nvoid esh_set_overflow_arg(struct esh *esh, void *arg);\n\n#endif // ESH_H\n"
  },
  {
    "path": "kernel/apps/esh/esh_argparser.c",
    "content": "/*\n * esh - embedded shell\n * Copyright (C) 2017 Chris Pavlina\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n */\n\n#define ESH_INTERNAL\n#include \"esh.h\"\n#define ESH_INTERNAL_INCLUDE\n#include \"esh_argparser.h\"\n#include \"esh_internal.h\"\n\n#define DEST(esh) ((esh)->buffer)\n\n\n/**\n * Consume a quoted string. The source string will be modified into the\n * destination string as follows:\n *\n * source:  \" b\"\n * dest:     b\n *\n * This is safe to use when the destination and source buffer are the same;\n * it will only ever contract the data, not expand it.\n */\nstatic void consume_quoted(struct esh *esh, size_t *src_i, size_t *dest_i)\n{\n    (void) esh;\n    char quote = ESH_INSTANCE->buffer[*src_i];\n\n    for (++*src_i; *src_i < ESH_INSTANCE->cnt; ++*src_i) {\n        char c = ESH_INSTANCE->buffer[*src_i];\n        if (c == quote) {\n            // End of quoted string\n            break;\n        } else {\n            DEST(ESH_INSTANCE)[*dest_i] = c;\n            ++*dest_i;\n        }\n    }\n}\n\n\nint esh_parse_args(struct esh *esh)\n{\n    size_t i;\n    (void) esh;\n    int argc = 0;\n    bool last_was_space = true;\n    size_t dest = 0;\n\n    for (i = 0; i < ESH_INSTANCE->cnt; ++i) {\n        if (ESH_INSTANCE->buffer[i] == ' ') {\n            last_was_space = true;\n            ESH_INSTANCE->buffer[dest] = 0;\n            ++dest;\n        } else {\n            if (last_was_space) {\n                if (argc < ESH_ARGC_MAX) {\n                    ESH_INSTANCE->argv[argc] = &ESH_INSTANCE->buffer[dest];\n                }\n                ++argc;\n            }\n            if (ESH_INSTANCE->buffer[i] == '\\'' || ESH_INSTANCE->buffer[i] == '\\\"') {\n                consume_quoted(ESH_INSTANCE, &i, &dest);\n            } else {\n                ESH_INSTANCE->buffer[dest] = ESH_INSTANCE->buffer[i];\n                ++dest;\n            }\n            last_was_space = false;\n        }\n    }\n    ESH_INSTANCE->buffer[dest] = 0;\n    ESH_INSTANCE->buffer[ESH_BUFFER_LEN] = 0;\n    return argc;\n}\n"
  },
  {
    "path": "kernel/apps/esh/esh_argparser.h",
    "content": "/*\n * esh - embedded shell\n * Copyright (C) 2017 Chris Pavlina\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n */\n\n#ifndef ESH_INTERNAL_INCLUDE\n#error \"esh_argparser.h is an internal header and should not be included by the user.\"\n#endif // ESH_INTERNAL_INCLUDE\n\n#ifndef ESH_ARGPARSER_H\n#define ESH_ARGPARSER_H\n\nstruct esh;\n\n/**\n * Map the buffer to the argv array, and return argc. If argc exceeds the\n * maximum, the full buffer will still be processed; argument pointers will\n * just not be stored beyond the maximum. The number that would have been\n * stored is returned.\n *\n * Handles whitespace and quotes. The entire buffer is processed in place,\n * with any changes leaveing the length equal or shorter.\n *\n * Following is an example buffer before and after processing (# for NUL),\n * with pointers stored in argv[] marked with ^\n *\n * before: git   config user.name \"My Name\"\n * after:  git###config#user.name#My Name#\n * argv:   ^     ^      ^         ^\n *\n * Rearranging the buffer is necessary because quotes can occur in the\n * middle of arguments. For example:\n *\n * before: why\" would you ever\"'\"'\"do this??\"\n * after:  why would you ever\"do this??#\n * argv:   ^\n *\n */\nint esh_parse_args(struct esh *esh);\n\n#endif // ESH_ARGPARSER_H\n"
  },
  {
    "path": "kernel/apps/esh/esh_config.h",
    "content": "#define ESH_PROMPT \"minos # \"\n#define ESH_BUFFER_LEN 200\n#define ESH_ARGC_MAX 10\n\n#define ESH_HIST_ALLOC STATIC\n#define ESH_HIST_LEN 4096\n\n#define ESH_ALLOC STATIC\n#define ESH_INSTANCES 1\n"
  },
  {
    "path": "kernel/apps/esh/esh_hist.c",
    "content": "/*\n * esh - embedded shell\n * Copyright (C) 2017 Chris Pavlina\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n */\n\n// History allocation types\n#define STATIC 1\n#define MANUAL 2\n#define MALLOC 3\n\n#include \"esh.h\"\n#define ESH_INTERNAL_INCLUDE\n#include \"esh_internal.h\"\n#include <minos/string.h>\n\n#ifdef ESH_HIST_ALLOC\n// Begin actual history implementation\n\n/**\n * Initialize the history buffer.\n *\n * The initial value is a NUL byte followed by a fill of 0xff. This avoids\n * the extra empty-string history entry that would be seen if the buffer\n * were filled with 0x00.\n */\nstatic void init_buffer(char * buffer)\n{\n    memset(buffer, 0xff, ESH_HIST_LEN);\n    buffer[0] = 0;\n}\n\n/**\n * True signed modulo, for wraparound signed arithmetic. This is mathematically\n * equivalent to \"0 + a   mod b\".\n */\nstatic int modulo(int n, int modulus)\n{\n    int rem = n % modulus;\n    return (rem >= 0) ? rem : rem + modulus;\n}\n\n/**\n * Given an offset in the ring buffer, call the callback once for each\n * character in the string starting there. This is meant to abstract away\n * ring buffer access.\n *\n * @param esh - esh instance\n * @param offset - offset into the ring buffer\n * @param callback - will be called once per character\n *      - callback:param esh - esh instance\n *      - callback:param c - character\n *      - callback:return - true to stop iterating, false to continue\n *\n * Regardless of the callback's return value, iteration will always stop at NUL\n * or if the loop wraps all the way around.\n */\nstatic void for_each_char(struct esh * esh, int offset,\n        bool (*callback)(struct esh * esh, char c))\n{\n    int i;\n    (void) esh;\n\n    for (i = offset; ESH_INSTANCE->hist.hist[i]; i = (i + 1) % ESH_HIST_LEN) {\n        if (i == modulo(offset - 1, ESH_HIST_LEN)) {\n            // Wrapped around and didn't encounter NUL. Stop here to prevent\n            // an infinite loop.\n            return;\n        }\n\n        if (callback(ESH_INSTANCE, ESH_INSTANCE->hist.hist[i])) {\n            return;\n        }\n    }\n}\n\n\n/**\n * Internal callback passed to for_each_char by clobber_buffer\n */\nstatic bool clobber_cb(struct esh * esh, char c)\n{\n    (void) esh;\n    ESH_INSTANCE->buffer[ESH_INSTANCE->cnt] = c;\n    ++ESH_INSTANCE->cnt;\n    ++ESH_INSTANCE->ins;\n    return false;\n}\n\n\n/**\n * Put the selected history item in the buffer. Make sure to call\n * esh_restore afterward to display the buffer.\n * @param esh - esh instance\n * @param offset - offset into the ring buffer\n */\nstatic void clobber_buffer(struct esh * esh, int offset)\n{\n    (void) esh;\n    if (offset < 0 || offset >= ESH_HIST_LEN) {\n        return;\n    }\n\n    ESH_INSTANCE->cnt = 0;\n    ESH_INSTANCE->ins = 0;\n    for_each_char(ESH_INSTANCE, offset, &clobber_cb);\n}\n\n\nbool esh_hist_init(struct esh * esh)\n{\n    (void) esh;\n#if ESH_HIST_ALLOC == STATIC\n    static char esh_hist[ESH_HIST_LEN] = {0};\n    ESH_INSTANCE->hist.hist = &esh_hist[0];\n    init_buffer(ESH_INSTANCE->hist.hist);\n    return false;\n#elif ESH_HIST_ALLOC == MALLOC\n    ESH_INSTANCE->hist.hist = malloc(ESH_HIST_LEN);\n    if (ESH_INSTANCE->hist.hist) {\n        init_buffer(ESH_INSTANCE->hist.hist);\n        return false;\n    } else {\n        return true;\n    }\n#elif ESH_HIST_ALLOC == MANUAL\n    ESH_INSTANCE->hist.hist = NULL;\n    return false;\n#endif\n}\n\n\nint esh_hist_nth(struct esh * esh, int n)\n{\n    int i;\n    (void) esh;\n    const int start = modulo(ESH_INSTANCE->hist.tail - 1, ESH_HIST_LEN);\n    const int stop = (ESH_INSTANCE->hist.tail + 1) % ESH_HIST_LEN;\n\n    for (i = start; i != stop; i = modulo(i - 1, ESH_HIST_LEN)) {\n        if (n && ESH_INSTANCE->hist.hist[i] == 0) {\n            --n;\n        } else if (ESH_INSTANCE->hist.hist[i] == 0) {\n            return (i + 1) % ESH_HIST_LEN;\n        }\n    }\n\n    return -1;\n}\n\n\nbool esh_hist_add(struct esh * esh, char const * s)\n{\n    int i;\n    (void) esh;\n    const int start = (ESH_INSTANCE->hist.tail + 1) % ESH_HIST_LEN;\n\n    for (i = start; ; i = (i + 1) % ESH_HIST_LEN)\n    {\n        if (i == modulo(ESH_INSTANCE->hist.tail - 1, ESH_HIST_LEN)) {\n            // Wrapped around\n            ESH_INSTANCE->hist.tail = 0;\n            init_buffer(ESH_INSTANCE->hist.hist);\n            return true;\n        }\n\n        ESH_INSTANCE->hist.hist[i] = *s;\n\n        if (*s) {\n            ++s;\n        } else {\n            ESH_INSTANCE->hist.tail = i;\n            return false;\n        }\n    }\n}\n\n\nvoid esh_hist_print(struct esh * esh, int offset)\n{\n    (void) esh;\n    // Clear the line\n    esh_puts_flash(ESH_INSTANCE, FSTR(ESC_ERASE_LINE \"\\r\"));\n\n    esh_print_prompt(ESH_INSTANCE);\n\n    if (offset >= 0) {\n        for_each_char(ESH_INSTANCE, offset, esh_putc);\n    }\n}\n\n\nbool esh_hist_substitute(struct esh * esh)\n{\n    (void) esh;\n    if (ESH_INSTANCE->hist.idx) {\n        int offset = esh_hist_nth(ESH_INSTANCE, ESH_INSTANCE->hist.idx - 1);\n        clobber_buffer(ESH_INSTANCE, offset);\n        esh_restore(ESH_INSTANCE);\n        ESH_INSTANCE->hist.idx = 0;\n        return true;\n    } else {\n        return false;\n    }\n}\n\n#endif // ESH_HIST_ALLOC\n\n#if defined(ESH_HIST_ALLOC) && ESH_HIST_ALLOC == MANUAL\n\nvoid esh_set_histbuf(struct esh * esh, char * buffer)\n{\n    ESH_INSTANCE->hist.hist = buffer;\n    init_buffer(ESH_INSTANCE->hist.hist);\n}\n\n#else // ESH_HIST_ALLOC == MANUAL\n\nvoid esh_set_histbuf(struct esh * esh, char * buffer)\n{\n    (void) esh;\n    (void) buffer;\n}\n\n#endif // ESH_HIST_ALLOC == MANUAL\n"
  },
  {
    "path": "kernel/apps/esh/esh_hist.h",
    "content": "/*\n * esh - embedded shell\n * Copyright (C) 2017 Chris Pavlina\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n */\n\n#ifndef ESH_HIST_H\n#define ESH_HIST_H\n\n#include <minos/types.h>\n\n/*\n * esh history support. This provides either a full history implementation or\n * a placeholder, depending on whether history was enabled in configuration.\n * This allows the main esh code to not be conditionally compiled.\n */\n\nstruct esh;\n\n#ifdef ESH_HIST_ALLOC\n// Begin actual history implementation\n\nstruct esh_hist {\n    char *hist;\n    int tail;\n    int idx;\n};\n\n/**\n * Initialize history.\n * @param esh - esh instance\n * @return true on error. Can only return error if the history buffer is to be\n * allocated on heap.\n */\nbool esh_hist_init(struct esh *esh);\n\n/**\n * Count back n strings from the current tail of the ring buffer and return the\n * index the string starts at.\n *\n * @param esh - esh instance\n * @param n - count to the nth string back, where 0 is the last string added\n * @return offset in the ring buffer where the nth string starts, or -1 if\n *  there are not n-1 strings in the buffer.\n */\nint esh_hist_nth(struct esh *esh, int n);\n\n/**\n * Add a string into the buffer. If the string doesn't fit, the buffer is\n * intentionally reset to avoid restoring a corrupted string later.\n * @param esh - esh instance\n * @param s - string to add\n * @return true iff the string didn't fit (this is destructive!)\n */\nbool esh_hist_add(struct esh *esh, char const *s);\n\n/**\n * Overwrite the prompt and print a history suggestion.\n * @param esh - esh instance\n * @param offset - offset into the ring buffer\n */\nvoid esh_hist_print(struct esh *esh, int offset);\n\n/**\n * If history is currently being browsed, substitute the selected history item\n * for the buffer and redraw the buffer for editing.\n * @param esh - esh instance\n * @return true iff the substitution was made (i.e. history was being browsed)\n */\nbool esh_hist_substitute(struct esh *esh);\n\n#else // ESH_HIST_ALLOC\n// Begin placeholder implementation\n\nstruct esh_hist {\n    size_t idx;\n};\n\n#define INL static inline __attribute__((always_inline))\n\nINL bool esh_hist_init(struct esh *esh)\n{\n    (void) esh;\n    return false;\n}\n\nINL int esh_hist_nth(struct esh *esh, int n)\n{\n    (void) esh;\n    (void) n;\n    return -1;\n}\n\nINL bool esh_hist_add(struct esh *esh, char const *s)\n{\n    (void) esh;\n    (void) s;\n    return true;\n}\n\nINL void esh_hist_for_each_char( struct esh *esh, int offset,\n        bool (*callback)(struct esh * esh, char c))\n{\n    (void) esh;\n    (void) offset;\n    (void) callback;\n}\n\nINL void esh_hist_print(struct esh *esh, int offset)\n{\n    (void) esh;\n    (void) offset;\n}\n\nINL void esh_hist_restore(struct esh *esh)\n{\n    (void) esh;\n}\n\nINL void esh_hist_clobber(struct esh *esh, int offset)\n{\n    (void) esh;\n    (void) offset;\n}\n\nINL bool esh_hist_substitute(struct esh *esh)\n{\n    (void) esh;\n    return false;\n}\n\n#undef INL\n\n#endif // ESH_HIST_ALLOC\n\n#endif // ESH_HIST_H\n"
  },
  {
    "path": "kernel/apps/esh/esh_incl_config.h",
    "content": "/*\n * esh - embedded shell\n * Copyright (C) 2017 Chris Pavlina\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n */\n\n#ifndef ESH_INCL_CONFIG_H\n#define ESH_INCL_CONFIG_H\n\n#define STATIC 1\n#define MANUAL 2\n#define MALLOC 3\n#include \"esh_config.h\"\n\n#ifdef ESH_RUST\n#define ESH_STATIC_CALLBACKS\n#endif\n\n#endif // ESH_INCL_CONFIG_H\n"
  },
  {
    "path": "kernel/apps/esh/esh_internal.h",
    "content": "/*\n * esh - embedded shell\n * Copyright (C) 2017 Chris Pavlina\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n */\n\n#ifndef ESH_INTERNAL_H\n#define ESH_INTERNAL_H\n\n#include \"esh_incl_config.h\"\n#include \"esh_hist.h\"\n#include <minos/types.h>\n\nstruct tty;\n\n/**\n * If we're building for Rust, we need to know the size of a &[u8] in order\n * to allocate space for it. This definition should be equivalent. Because the\n * internal representation of a slice has not been stabilized [1], this is not\n * guaranteed to remain constant in the future; the Rust bindings will check\n * sizeof(struct char_slice) against mem::size_of::<&[u8]>().\n *\n * [1] https://github.com/rust-lang/rust/issues/27751\n */\n\n#ifdef ESH_RUST\nstruct char_slice {\n    char *p;\n    size_t sz;\n};\n#endif\n\n/**\n * esh instance struct. This holds all of the state that needs to be saved\n * between calls to esh_rx().\n */\nstruct esh {\n    /**\n     * The config item ESH_BUFFER_LEN is only the number of characters to be\n     * stored, not characters plus termination.\n     */\n    char buffer[ESH_BUFFER_LEN + 1];\n\n    /**\n     * The Rust bindings require space allocated for an argv array of &[u8],\n     * which can share memory with C's char* array to save limited SRAM.\n     */\n#ifdef ESH_RUST\n    union {\n        char * argv[ESH_ARGC_MAX];\n        struct char_slice rust_argv[ESH_ARGC_MAX];\n    };\n#else\n    char * argv[ESH_ARGC_MAX];\n#endif\n\n    size_t cnt;             ///< Number of characters currently held in .buffer\n    size_t ins;             ///< Position of the current insertion point\n    uint8_t flags;          ///< State flags for escape sequence parser\n    struct esh_hist hist;\n#ifndef ESH_STATIC_CALLBACKS\n    esh_cb_command cb_command;\n    esh_cb_print print;\n    esh_cb_overflow overflow;\n#endif\n    void *cb_command_arg;\n    void *cb_print_arg;\n    void *cb_overflow_arg;\n\n    struct tty *tty;\n};\n\n/**\n * On AVR, a number of strings should be stored in and read from flash space.\n * Other architectures have linearized address spaces and don't require this.\n */\n#ifdef __AVR_ARCH__\n#   define FSTR(s) (__extension__({ \\\n            static const __flash char __c[] = (s); \\\n            &__c[0];}))\n#   define AVR_ONLY(x) x\n#else\n#   define FSTR(s) (s)\n#   define AVR_ONLY(x)\n#endif // __AVR_ARCH__\n\n/**\n * Print one character.\n * @return false (allows it to be an esh_hist_for_each_char callback)\n */\nbool esh_putc(struct esh *esh, char c);\n\n/**\n * @internal\n * Print a string located in RAM.\n */\nbool esh_puts(struct esh *esh, char const *s);\n\n/**\n * @internal\n * Print a string located in flash. On all but AVR this is an alias for\n * esh_puts().\n */\n#ifdef __AVR_ARCH__\nbool esh_puts_flash(struct esh *esh, char const __flash * s);\n#else\n#define esh_puts_flash esh_puts\n#endif\n\n/**\n * Print the prompt string\n */\nvoid esh_print_prompt(struct esh *esh);\n\n/**\n * Overwrite the prompt and restore the buffer.\n */\nvoid esh_restore(struct esh *esh);\n\n/**\n * Call the print callback. Wrapper to avoid ifdefs for static callback.\n */\nvoid esh_do_print_callback(struct esh *esh, char c);\n\n/**\n * Call the main callback. Wrapper to avoid ifdefs for static callback.\n */\nvoid esh_do_callback(struct esh *esh, int argc, char **argv);\n\n/**\n * Call the overflow callback. Wrapper to avoid ifdefs for the static\n * callback.\n */\nvoid esh_do_overflow_callback(struct esh *esh, char const * buffer);\n\n#ifdef ESH_RUST\n/**\n * Return what we think the size of a Rust &[u8] slice is. This is used to\n * verify that the statically allocated slice array is long enough, and also\n * to make sure a linker error is produced if ESH_RUST wasn't enabled\n * (which would mean the slice array wasn't allocated at all).\n */\nsize_t esh_get_slice_size(void);\n#endif\n\n#define ESC_CURSOR_RIGHT    \"\\33[1C\"\n#define ESC_CURSOR_LEFT     \"\\33[1D\"\n#define ESC_ERASE_LINE      \"\\33[2K\"\n\n#define ESCCHAR_UP      'A'\n#define ESCCHAR_DOWN    'B'\n#define ESCCHAR_RIGHT   'C'\n#define ESCCHAR_LEFT    'D'\n#define ESCCHAR_HOME    'H'\n#define ESCCHAR_END     'F'\n#define ESCCHAR_CTRLLEFT    'd'\n#define ESCCHAR_CTRLRIGHT   'c'\n\n#if ESH_ALLOC == STATIC\nextern struct esh g_esh_struct;\n#define ESH_INSTANCE (&g_esh_struct)\n#else\n#define ESH_INSTANCE esh\n#endif // ESH_ALLOC\n\n#endif // ESH_INTERNAL_H\n"
  },
  {
    "path": "kernel/apps/esh/shell.c",
    "content": "/*\n * Copyright (C) 2020 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/console.h>\n#include <minos/compiler.h>\n#include <minos/shell_command.h>\n#include <minos/tty.h>\n#include <minos/print.h>\n#include <minos/errno.h>\n#include <minos/string.h>\n#include <minos/bootarg.h>\n\n#include \"esh.h\"\n#include \"esh_internal.h\"\n\nstatic struct esh *pesh;\n\nstatic void __esh_putc(struct esh *esh, char c, void *arg)\n{\n\tconsole_putc(c);\n}\n\nstatic void esh_excute_command(struct esh *esh,\n\t\tint argc, char **argv, void *arg)\n{\n\tint ret;\n\n\tret = excute_shell_command(argc, argv);\n\tif (ret == -ENOENT)\n\t\tprintf(\"Command \\'%s\\' not found\\n\", argv[0]);\n}\n\nstatic void shell_detach_tty(void)\n{\n\tclose_tty(pesh->tty);\n\tprintf(\"\\nDetach tty: %s\\n\", pesh->tty->name);\n\tpesh->tty = NULL;\n}\n\nstatic int shell_cmd_tty(int argc, char **argv)\n{\n\tif (argc > 2 && strcmp(argv[1], \"attach\") == 0) {\n\t\tprintf(\"Attach tty: %s press any key to active the console\\n\",\n\t\t\t\targv[2]);\n\t\tpesh->tty = open_tty(argv[2]);\n\t\tif (!pesh->tty) {\n\t\t\tprintf(\"no such tty\\n\");\n\t\t\treturn -EINVAL;\n\t\t}\n\t} else {\n\t\tprintf(\"unsupport action now\\n\");\n\t}\n\n\treturn 0;\n}\nDEFINE_SHELL_COMMAND(tty, \"tty\", \"tty related command\",\n\t\tshell_cmd_tty, 2);\n\nint shell_task(void *data)\n{\n\tchar buf[32];\n\tchar ch;\n\tint i, copy;\n\tchar *tty = NULL;\n\n\tpesh = esh_init();\n\tesh_register_command(pesh, esh_excute_command);\n\tesh_register_print(pesh, __esh_putc);\n\n\tesh_rx(pesh, '\\n');\n\twhile (console_gets(buf, 32, 0) != 0);\n\n\tif ((long)data == 0) {\n\t\ti = bootarg_parse_string(\"tty\", &tty);\n\t\tif (!i && tty && !strncmp(tty, \"vm\", 2)) {\n\t\t\tprintf(\"\\nAttach tty: %s\\n\", tty);\n\t\t\tpesh->tty = open_tty(tty);\n\t\t}\n\t}\n\n\tfor (; ;) {\n\t\tcopy = console_gets(buf, 32, -1);\n\t\tfor (i = 0; i < copy; i++) {\n\t\t\tch = buf[i];\n\t\t\tif (ch <= 0)\n\t\t\t\tcontinue;\n\t\t\tif (pesh->tty) {\n\t\t\t\t/*\n\t\t\t\t * use Ctrl-\\ to exit the vm tty\n\t\t\t\t */\n\t\t\t\tif (ch == 28) {\n\t\t\t\t\tshell_detach_tty();\n\t\t\t\t\tesh_rx(pesh, '\\n');\n\t\t\t\t} else {\n\t\t\t\t\tpesh->tty->ops->put_char(pesh->tty, ch);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (ch == '\\r')\n\t\t\t\t\tch = '\\n';\n\t\t\t\tesh_rx(pesh, ch);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "kernel/apps/init.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/console.h>\n#include <minos/shell_command.h>\n#include <minos/bootarg.h>\n#include <minos/print.h>\n#include <minos/task.h>\n\n#ifdef CONFIG_VIRT\n#include <virt/virt.h>\n#endif\n\n#ifdef CONFIG_VIRT\nstatic long __skip_vm_boot;\n#else\nstatic long __skip_vm_boot = 1;\n#endif\n\nstatic void skip_vm_boot(void)\n{\n#ifdef CONFIG_VIRT\n#ifdef CONFIG_SHELL\n\tuint32_t wait;\n\tchar str[8];\n\tint i;\n\n\tbootarg_parse_uint(\"bootwait\", &wait);\n\tif (wait > 0) {\n\t\tprintf(\"\\nPress any key to stop vm startup: %d \", wait);\n\t\tfor (i = 0; i < wait; i++) {\n\t\t\tprintf(\"\\b\\b%d \", wait - i);\n\t\t\tif (console_gets(str, 8, 1000) > 0) {\n\t\t\t\t__skip_vm_boot = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!__skip_vm_boot) {\n\t\tprintf(\"\\b\\b \");\n\t\tprintf(\"\\n\");\n\t}\n#endif\n\tif (!__skip_vm_boot)\n\t\tstart_all_vm();\n#endif\n}\n\nstatic void start_shell_task(void)\n{\n#ifdef CONFIG_SHELL\n\textern int shell_task(void *data);\n\tcreate_task(\"shell_task\", shell_task, 0x2000, OS_PRIO_SYSTEM,\n\t\t\t-1, 0, (void *)__skip_vm_boot);\n#endif\n}\n\nint init_task(void *data)\n{\n\tskip_vm_boot();\n\tstart_shell_task();\n\n\treturn 0;\n}\n"
  },
  {
    "path": "kernel/arch/aarch64/Kconfig",
    "content": "config ARCH_AARCH64\n\tdef_bool y\n\tselect DEVICE_TREE\n\tselect 64BIT\n\thelp\n\t  AARCH64 Minos support\n\nconfig 64BIT\n\tdef_bool y\n\nsource \"arch/aarch64/core/Kconfig\"\n\nif VIRT\nsource \"arch/aarch64/virt/Kconfig\"\nendif\n\nsource \"core/Kconfig\"\n# source \"virt/Kconfig\"\nsource \"drivers/Kconfig\"\nsource \"platform/Kconfig\"\nsource \"libs/Kconfig\"\nsource \"userspace/Kconfig\"\n"
  },
  {
    "path": "kernel/arch/aarch64/Makefile",
    "content": "#\n# arch/arm64/Makefile\n#\n# This file is included by the global makefile so that you can add your own\n# architecture-specific flags and dependencies.\n#\n# This file is subject to the terms and conditions of the GNU General Public\n# License.  See the file \"COPYING\" in the main directory of this archive\n# for more details.\n#\n# Copyright (C) 1995-2001 by Russell King\n#\nifeq ($(CONFIG_ARM64_LSE_ATOMICS), y)\n  ifeq ($(lseinstr),)\n$(warning LSE atomics not supported by binutils)\n  endif\nendif\n\nifeq ($(CONFIG_ARCH_AARCH64), y)\nbrokengasinst := $(call as-instr,1:\\n.inst 0\\n.rept . - 1b\\n\\nnop\\n.endr\\n,,-DCONFIG_BROKEN_GAS_INST=1)\n\n  ifneq ($(brokengasinst),)\n$(warning Detected assembler with broken .inst; disassembly will be unreliable)\n  endif\nendif\n\nifeq ($(CONFIG_ARM_ATOMIC_LSE), y)\n\tARMV8_ARCH\t= armv8.1-a\nelse\n\tARMV8_ARCH\t= armv8-a\nendif\n\nMBUILD_LDFLAGS\t+= -X\n\nMBUILD_CFLAGS\t+= -mgeneral-regs-only $(lseinstr) $(brokengasinst)\nMBUILD_CFLAGS\t+= -fno-asynchronous-unwind-tables -march=$(ARMV8_ARCH) -ffixed-x18\nMBUILD_AFLAGS\t+= $(lseinstr) $(brokengasinst)\n\nifeq ($(CONFIG_CPU_BIG_ENDIAN), y)\nMBUILD_CFLAGS\t+= -mbig-endian\n# Prefer the baremetal ELF build target, but not all toolchains include\n# it so fall back to the standard linux version if needed.\nMBUILD_LDFLAGS\t+= -EB\nelse\nMBUILD_CFLAGS\t+= -mlittle-endian -mcmodel=large\nMBUILD_LDFLAGS\t+= -EL\nendif\n\n# Default value\nhead-y\t\t:= arch/aarch64/core/boot.o\n\ncore-y\t\t\t+= arch/aarch64/core/\ncore-y\t\t\t+= arch/aarch64/lib/\ncore-y\t\t\t+= arch/aarch64/lds/\ncore-y\t\t\t+= arch/aarch64/userspace/\ncore-$(CONFIG_VIRT)\t+= arch/aarch64/virt/\n"
  },
  {
    "path": "kernel/arch/aarch64/core/Kconfig",
    "content": "menu \"Minos aarch64 Arch Feature\"\n\nconfig NR_CPUS_CLUSTER0\n\tint \"cpu number in cluster0\"\n\tdefault 4\n\thelp\n\t  cpu count in SOC cluster0, this\n\t  will help to caculate the cpuid\n\nconfig NR_CPUS_CLUSTER1\n\tint \"cpu number in cluster1\"\n\tdefault 0\n\thelp\n\t  cpu count in SOC cluster1, this\n\t  will help to caculate the cpuid\n\nconfig EXCEPTION_STACK_SIZE\n\thex \"the stack size of the exception vector\"\n\tdefault 0x2000\n\thelp\n\t  the stack size of the exception vector\n\nconfig ARM_ATOMIC_LSE\n\tbool \"use lse atomic instruction\"\n\tdefault n\n\thelp\n\t  this require at leaset armv8.1 soc\n\nconfig ARM_ADDRESS_TAGGING\n\tbool\n\tdefault (VIRT && ARM_VHE) || (!VIRT)\n\nconfig PTOV_MASK\n\thex\n\tdefault 0xffffff8000000000 if ARM_ADDRESS_TAGGING\n\tdefault 0x0\n\nconfig VTOP_MASK\n\thex\n\tdefault 0x0000007fffffffff if ARM_ADDRESS_TAGGING\n\tdefault 0x0\n\nendmenu\n"
  },
  {
    "path": "kernel/arch/aarch64/core/Makefile",
    "content": "obj-y += aarch64_IRQ.o\nobj-y += aarch64.o\nobj-y += aarch64_sync.o\nobj-y += arch.o\nobj-y += arm_arch_timer.o\nobj-y += boot.o\nobj-y += cache.o\nobj-y += cpu.o\nobj-y += entry.o\nobj-y += mem_map.o\nobj-y += vector.o\nobj-y += cpu_feature.o\nobj-y += stage1.o\nobj-y += fpsimd.o\n"
  },
  {
    "path": "kernel/arch/aarch64/core/aarch64.S",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/aarch64_common.h>\n#include <asm/asm_marco.S>\n#include <config/config.h>\n\n\t.global arch_raw_smp_processor_id\n\t.global arch_get_fp\n\t.global arch_get_lr\n\t.global arch_get_sp\n\t.global smc_call\n\t.global hvc_call\n\t.global aarch64_task_exit\n\nfunc arch_raw_smp_processor_id\n\tmrs \tx0, MPIDR_EL1\n\tldr\tx4, =(1 << 24)\n\tand\tx5, x0, x4\n\tcbnz\tx5, __shift_mpidr\n\tubfx    x1, x0, #MPIDR_EL1_AFF0_LSB, #MPIDR_EL1_AFF_WIDTH\n\tubfx    x2, x0, #MPIDR_EL1_AFF1_LSB, #MPIDR_EL1_AFF_WIDTH\n\tb\t__out\n__shift_mpidr:\n\tubfx    x1, x0, #MPIDR_EL1_AFF1_LSB, #MPIDR_EL1_AFF_WIDTH\n\tubfx    x2, x0, #MPIDR_EL1_AFF2_LSB, #MPIDR_EL1_AFF_WIDTH\n__out:\n\tmov\tx3, #CONFIG_NR_CPUS_CLUSTER0\n\tmul\tx2, x2, x3\n\tadd\tx0, x2, x1\n\tdsb\tsy\n\tret\nendfunc arch_raw_smp_processor_id\n\nfunc arch_get_fp\n\tmov\tx0, x29\n\tret\nendfunc arch_get_fp\n\nfunc arch_get_lr\n\tmov\tx0, x30\n\tret\nendfunc arch_get_lr\n\nfunc arch_get_sp\n\tmov\tx0, sp\n\tret\nendfunc arch_get_sp\n\nfunc smc_call\n\tsmc\t#0\n\tldr\tx4, [sp]\n\tstp\tx0, x1, [x4, #0]\n\tstp\tx2, x3, [x4, #16]\n\tret\nendfunc smc_call\n\nfunc hvc_call\n\thvc\t#0\n\tldr\tx4, [sp]\n\tstp\tx0, x1, [x4, #0]\n\tstp\tx2, x3, [x4, #16]\n\tret\nendfunc hvc_call\n\nfunc aarch64_task_exit\n\tmov\tx0, x0\n\tbl\ttask_exit\n1:\n\tb\t1b\nendfunc aarch64_task_exit\n"
  },
  {
    "path": "kernel/arch/aarch64/core/aarch64_IRQ.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/irq.h>\n#include <minos/sched.h>\n\nstatic inline void irq_handler(gp_regs *regs)\n{\n\tdo_irq_handler();\n}\n\nvoid irq_from_lower_el(gp_regs *regs)\n{\n\tirq_handler(regs);\n}\n\nvoid irq_from_current_el(gp_regs *regs)\n{\n\tirq_handler(regs);\n}\n"
  },
  {
    "path": "kernel/arch/aarch64/core/aarch64_sync.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/aarch64_helper.h>\n#include <asm/trap.h>\n#include <minos/minos.h>\n#include <minos/smp.h>\n#include <asm/reg.h>\n#include <minos/sched.h>\n#include <minos/irq.h>\n#include <asm/svccc.h>\n#include <asm/trap.h>\n\nstatic char *mode_info[] = {\n\t\"Sync taken from current EL with SP0\",\n\t\"IRQ taken from current EL with SP0\",\n\t\"FIQ taken from current EL with SP0\",\n\t\"Serr taken from current EL with SP0\",\n\t\"Sync taken from current EL with SPx\",\n\t\"IRQ taken from current EL with SPx\",\n\t\"FIQ taken from current EL with SPx\",\n\t\"Serr taken from current EL with SPx\",\n\t\"Sync taken from lower EL with AARCH32\"\n\t\"IRQ taken from lower EL with AARCH32\"\n\t\"FIQ taken from lower EL with AARCH32\"\n\t\"Serr taken from lower EL with AARCH32\"\n\t\"Sync taken from lower EL with AARCH64\"\n\t\"IRQ taken from lower EL with AARCH64\"\n\t\"FIQ taken from lower EL with AARCH64\"\n\t\"Serr taken from lower EL with AARCH64\"\n};\n\nstatic const char *esr_class_str[] = {\n\t[0 ... ESR_ELx_EC_MAX]\t\t= \"UNRECOGNIZED EC\",\n\t[ESR_ELx_EC_UNKNOWN]\t\t= \"Unknown/Uncategorized\",\n\t[ESR_ELx_EC_WFx]\t\t= \"WFI/WFE\",\n\t[ESR_ELx_EC_CP15_32]\t\t= \"CP15 MCR/MRC\",\n\t[ESR_ELx_EC_CP15_64]\t\t= \"CP15 MCRR/MRRC\",\n\t[ESR_ELx_EC_CP14_MR]\t\t= \"CP14 MCR/MRC\",\n\t[ESR_ELx_EC_CP14_LS]\t\t= \"CP14 LDC/STC\",\n\t[ESR_ELx_EC_FP_ASIMD]\t\t= \"ASIMD\",\n\t[ESR_ELx_EC_CP10_ID]\t\t= \"CP10 MRC/VMRS\",\n\t[ESR_ELx_EC_CP14_64]\t\t= \"CP14 MCRR/MRRC\",\n\t[ESR_ELx_EC_ILL]\t\t= \"PSTATE.IL\",\n\t[ESR_ELx_EC_SVC32]\t\t= \"SVC (AArch32)\",\n\t[ESR_ELx_EC_HVC32]\t\t= \"HVC (AArch32)\",\n\t[ESR_ELx_EC_SMC32]\t\t= \"SMC (AArch32)\",\n\t[ESR_ELx_EC_SVC64]\t\t= \"SVC (AArch64)\",\n\t[ESR_ELx_EC_HVC64]\t\t= \"HVC (AArch64)\",\n\t[ESR_ELx_EC_SMC64]\t\t= \"SMC (AArch64)\",\n\t[ESR_ELx_EC_SYS64]\t\t= \"MSR/MRS (AArch64)\",\n\t[ESR_ELx_EC_SVE]\t\t= \"SVE\",\n\t[ESR_ELx_EC_IMP_DEF]\t\t= \"EL3 IMP DEF\",\n\t[ESR_ELx_EC_IABT_LOW]\t\t= \"IABT (lower EL)\",\n\t[ESR_ELx_EC_IABT_CUR]\t\t= \"IABT (current EL)\",\n\t[ESR_ELx_EC_PC_ALIGN]\t\t= \"PC Alignment\",\n\t[ESR_ELx_EC_DABT_LOW]\t\t= \"DABT (lower EL)\",\n\t[ESR_ELx_EC_DABT_CUR]\t\t= \"DABT (current EL)\",\n\t[ESR_ELx_EC_SP_ALIGN]\t\t= \"SP Alignment\",\n\t[ESR_ELx_EC_FP_EXC32]\t\t= \"FP (AArch32)\",\n\t[ESR_ELx_EC_FP_EXC64]\t\t= \"FP (AArch64)\",\n\t[ESR_ELx_EC_SERROR]\t\t= \"SError\",\n\t[ESR_ELx_EC_BREAKPT_LOW]\t= \"Breakpoint (lower EL)\",\n\t[ESR_ELx_EC_BREAKPT_CUR]\t= \"Breakpoint (current EL)\",\n\t[ESR_ELx_EC_SOFTSTP_LOW]\t= \"Software Step (lower EL)\",\n\t[ESR_ELx_EC_SOFTSTP_CUR]\t= \"Software Step (current EL)\",\n\t[ESR_ELx_EC_WATCHPT_LOW]\t= \"Watchpoint (lower EL)\",\n\t[ESR_ELx_EC_WATCHPT_CUR]\t= \"Watchpoint (current EL)\",\n\t[ESR_ELx_EC_BKPT32]\t\t= \"BKPT (AArch32)\",\n\t[ESR_ELx_EC_VECTOR32]\t\t= \"Vector catch (AArch32)\",\n\t[ESR_ELx_EC_BRK64]\t\t= \"BRK (AArch64)\",\n};\n\nvoid bad_mode(gp_regs *regs, int mode)\n{\n\tpr_fatal(\"bad error: %s\\n\", mode_info[mode]);\n\tarch_dump_register(regs);\n\tpanic(\"Bad error received\\n\");\n}\n\nstatic const char *get_ec_class_string(int ec)\n{\n\treturn esr_class_str[ec];\n}\n\nstatic int kernel_mem_fault(gp_regs *regs, int ec, uint32_t esr)\n{\n\t__panic(regs, \"Memory fault in kernel space\\n\");\n}\n\nstatic int unknown_trap_handler(gp_regs *regs, int ec, uint32_t esr)\n{\n\t__panic(regs, \"Unknown exception class: ESR: 0x%x -- %s\\n\",\n\t\t\tesr, get_ec_class_string(ec));\n\n\treturn 0;\n}\n\nstatic inline int da_is_write_fault(uint32_t esr)\n{\n\treturn !!(esr & ESR_ELx_WNR);\n}\n\nstatic int __handle_user_page_fault(uint64_t addr, int is_write, unsigned long status)\n{\n\tpanic(\"Unsupport User Page Fault\\n\");\n\n\treturn -EFAULT;\n}\nweak_alias(__handle_user_page_fault, handle_user_page_fault);\n\nstatic int __handle_user_ia_fault(void)\n{\n\tpanic(\"Unsupport User IA Fault\\n\");\n\n\treturn -EFAULT;\n}\nweak_alias(__handle_user_ia_fault, handle_user_ia_fault);\n\nstatic int user_da_fault(gp_regs *regs, int ec, uint32_t esr)\n{\n\tunsigned long fault_status;\n\tuint64_t far;\n\tint is_write;\n\n\tswitch (esr & ESR_ELx_FSC) {\n\tcase FSC_SEA:\n\tcase FSC_SEA_TTW0:\n\tcase FSC_SEA_TTW1:\n\tcase FSC_SEA_TTW2:\n\tcase FSC_SEA_TTW3:\n\tcase FSC_SECC:\n\tcase FSC_SECC_TTW0:\n\tcase FSC_SECC_TTW1:\n\tcase FSC_SECC_TTW2:\n\tcase FSC_SECC_TTW3:\n\t\tpanic(\"TBD\\n\");\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\n\tif (esr & ESR_ELx_FnV) {\n\t\tpr_err(\"far is not vaild external abort ?\\n\");\n\t\tpanic(\"TBD\\n\");\n\t}\n\n\t/*\n\t * currently we only handle FSC_FAULT and FSC_PERM, Access fault\n\t * will not support currently.\n\t */\n\tfault_status = esr & ESR_ELx_FSC_TYPE;\n\tif (fault_status != FSC_FAULT && fault_status != FSC_PERM) {\n                pr_err(\"Unsupported FSC: EC=%#x xFSC=%#lx ESR_EL1=%#lx\\n\",\n\t\t\t\tec, fault_status, esr);\n                panic(\"TBD\\n\");\n        }\n\n\tfar = read_sysreg(ARM64_FAR);\n\tis_write = da_is_write_fault(esr);\n\n\treturn handle_user_page_fault(far, is_write, fault_status);\n}\n\nint user_ia_fault(gp_regs *regs, int ec, uint32_t esr)\n{\n\tstruct task *task = current;\n\n\tpr_err(\"User instruction abort pid:%d tid:%d ESR:0x%x IP:0x%x\\n\",\n\t\ttask->pid, task->tid, esr, regs->pc);\n\n\treturn handle_user_ia_fault();\n}\n\nint user_svc64(gp_regs *regs, int ec, uint32_t esr)\n{\n\textern int aarch64_do_syscall(gp_regs *regs);\n\n\treturn aarch64_do_syscall(regs);\n}\n\nDEFINE_SYNC_DESC(trap_unknown, EC_TYPE_AARCH64, unknown_trap_handler, 1, 0);\nDEFINE_SYNC_DESC(trap_kernel_da, EC_TYPE_AARCH64, kernel_mem_fault, 1, 0);\nDEFINE_SYNC_DESC(trap_kernel_ia, EC_TYPE_AARCH64, kernel_mem_fault, 1, 0);\nDEFINE_SYNC_DESC(trap_user_da, EC_TYPE_AARCH64, user_da_fault, 1, 0);\nDEFINE_SYNC_DESC(trap_user_ia, EC_TYPE_AARCH64, user_ia_fault, 1, 0);\nDEFINE_SYNC_DESC(trap_user_svc64, EC_TYPE_AARCH64, user_svc64, 1, 0);\n\nstatic struct sync_desc *process_sync_descs[] = {\n\t[0 ... ESR_ELx_EC_MAX] \t= &sync_desc_trap_unknown,\n\t[ESR_ELx_EC_IABT_CUR]\t= &sync_desc_trap_kernel_ia,\n\t[ESR_ELx_EC_DABT_CUR]\t= &sync_desc_trap_kernel_da,\n\t[ESR_ELx_EC_IABT_LOW]\t= &sync_desc_trap_user_ia,\n\t[ESR_ELx_EC_DABT_LOW]\t= &sync_desc_trap_user_da,\n\t[ESR_ELx_EC_SVC64]\t= &sync_desc_trap_user_svc64,\n};\n\nstatic inline uint32_t read_esr(void)\n{\n#ifdef CONFIG_VIRT\n\treturn read_esr_el2();\n#else\n\treturn read_esr_el1();\n#endif\n}\n\nstatic void handle_sync_exception(gp_regs *regs)\n{\n\tuint32_t esr_value;\n\tuint32_t ec_type;\n\tstruct sync_desc *ec;\n\n\tesr_value = read_esr();\n\tec_type = ESR_ELx_EC(esr_value);\n\tif (ec_type >= ESR_ELx_EC_MAX)\n\t\tpanic(\"unknown sync exception type from current EL %d\\n\", ec_type);\n\n\t/*\n\t * for normal userspace process the return address shall\n\t * be adjust\n\t */\n\tec = process_sync_descs[ec_type];\n\tregs->pc += ec->ret_addr_adjust;\n\tec->handler(regs, ec_type, esr_value);\n}\n\nvoid sync_exception_from_current_el(gp_regs *regs)\n{\n\thandle_sync_exception(regs);\n}\n\nvoid sync_exception_from_lower_el(gp_regs *regs)\n{\n#ifdef CONFIG_VIRT\n\textern void handle_vcpu_sync_exception(gp_regs *regs);\n\n\t/*\n\t * check whether this task is a vcpu task or a normal\n\t * userspace task.\n\t * 1 - TGE bit means a normal task\n\t * 2 - current->flags\n\t */\n\tif ((current->flags & TASK_FLAGS_VCPU) && !(read_hcr_el2() & HCR_EL2_TGE))\n\t\thandle_vcpu_sync_exception(regs);\n\telse\n#endif\n\t\thandle_sync_exception(regs);\n}\n"
  },
  {
    "path": "kernel/arch/aarch64/core/arch.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/aarch64_common.h>\n#include <asm/aarch64_helper.h>\n#include <asm/arch.h>\n#include <minos/string.h>\n#include <minos/print.h>\n#include <minos/sched.h>\n#include <minos/calltrace.h>\n#include <minos/smp.h>\n#include <minos/of.h>\n#include <minos/platform.h>\n#include <minos/task.h>\n#include <minos/console.h>\n#include <minos/ramdisk.h>\n#include <asm/tcb.h>\n#include <minos/mm.h>\n\n#ifdef CONFIG_VIRT\n#define read_esr()\tread_esr_el2()\n#else\n#define read_esr()\tread_esr_el1()\n#endif\n\n#ifdef CONFIG_VIRT\nextern void vcpu_context_restore(struct task *task);\nextern void vcpu_context_save(struct task *task);\n#endif\n\n#ifdef CONFIG_DEVICE_TREE\nextern void of_parse_host_device_tree(void);\n#endif\n\nvoid arch_dump_register(gp_regs *regs)\n{\n\tunsigned long spsr;\n\n\tif (!regs)\n\t\treturn;\n\n\tspsr = regs->pstate;\n\tpr_fatal(\"SPSR:0x%x Mode:%d-%s F:%d I:%d A:%d D:%d NZCV:%x\\n\",\n\t\t\tspsr, (spsr & 0x7), (spsr & 0x8) ?\n\t\t\t\"aarch64\" : \"aarch32\", (spsr & (BIT(6))) >> 6,\n\t\t\t(spsr & (BIT(7))) >> 7, (spsr & (BIT(8))) >> 8,\n\t\t\t(spsr & (BIT(9))) >> 9, spsr >> 28);\n\n\tpr_fatal(\"x0:0x%p x1:0x%p x2:0x%p\\n\",\n\t\t\tregs->x0, regs->x1, regs->x2);\n\tpr_fatal(\"x3:0x%p x4:0x%p x5:0x%p\\n\",\n\t\t\tregs->x3, regs->x4, regs->x5);\n\tpr_fatal(\"x6:0x%p x7:0x%p x8:0x%p\\n\",\n\t\t\tregs->x6, regs->x7, regs->x8);\n\tpr_fatal(\"x9:0x%p x10:0x%p x11:0x%p\\n\",\n\t\t\tregs->x9, regs->x10, regs->x11);\n\tpr_fatal(\"x12:0x%p x13:0x%p x14:0x%p\\n\",\n\t\t\tregs->x12, regs->x13, regs->x14);\n\tpr_fatal(\"x15:0x%p x16:0x%p x17:0x%p\\n\",\n\t\t\tregs->x15, regs->x16, regs->x17);\n\tpr_fatal(\"x18:0x%p x19:0x%p x20:0x%p\\n\",\n\t\t\tregs->x18, regs->x19, regs->x20);\n\tpr_fatal(\"x21:0x%p x22:0x%p x23:0x%p\\n\",\n\t\t\tregs->x21, regs->x22, regs->x23);\n\tpr_fatal(\"x24:0x%p x25:0x%p x26:0x%p\\n\",\n\t\t\tregs->x24, regs->x25, regs->x26);\n\tpr_fatal(\"x27:0x%p x28:0x%p x29:0x%p\\n\",\n\t\t\tregs->x27, regs->x28, regs->x29);\n\tpr_fatal(\"lr:0x%p sp_el0:0x%p spsr:0x%p\\n\",\n\t\t\tregs->lr, regs->sp, regs->pstate);\n\tpr_fatal(\"pc:0x%p esr:0x%p\\n\", regs->pc, read_esr());\n}\n\nvoid arch_dump_stack(gp_regs *regs, unsigned long *stack)\n{\n\tstruct task *task = get_current_task();\n\tunsigned long fp, lr = 0;\n\n\tif ((task) && os_is_running()) {\n\t\tpr_fatal(\"current task: tid:%d prio:%d name:%s\\n\",\n\t\t\t\tget_task_tid(task), get_task_prio(task),\n\t\t\t\ttask->name);\n\t}\n\n\tarch_dump_register(regs);\n\n\tif (!stack) {\n\t\tif (regs) {\n\t\t\tfp = regs->x29;\n\t\t\tlr = regs->pc;\n\t\t} else {\n\t\t\tfp = arch_get_fp();\n\t\t\tlr = arch_get_lr();\n\t\t}\n\t} else {\n\t\tfp = *stack;\n\t}\n\n\tpr_fatal(\"Call Trace :\\n\");\n\tpr_fatal(\"------------ cut here ------------\\n\");\n\tdo {\n\t\tprint_symbol(lr);\n\n\t\tif ((fp < (unsigned long)task->stack_bottom) ||\n\t\t\t\t(fp >= (unsigned long)task->stack_top))\n\t\t\t\tbreak;\n\n\t\tlr = *(unsigned long *)(fp + sizeof(unsigned long));\n\t\tlr -= 4;\n\t\tfp = *(unsigned long *)fp;\n\t} while (1);\n}\n\nint arch_taken_from_guest(gp_regs *regs)\n{\n\treturn !!((regs->pstate & 0xf) != (AARCH64_SPSR_EL2h));\n}\n\nint arch_is_exit_to_user(struct task *task)\n{\n\tgp_regs *regs = (gp_regs *)task->stack_base;\n\n\treturn !!((regs->pstate & 0xf) != (AARCH64_SPSR_EL2h));\n}\n\nstatic inline uint64_t task_ttbr_value(struct task *task)\n{\n\tstruct vspace *vs = task->vs;\n\n\treturn (uint64_t)vtop(vs->pgdp) | ((uint64_t)vs->asid << 48);\n}\n\nstatic inline void user_task_sched_out(struct task *task)\n{\n\tstruct cpu_context *c = &task->cpu_context;\n\textern void fpsimd_state_save(struct task *task,\n\t\tstruct fpsimd_context *c);\n\n\tc->tpidr_el0 = read_sysreg(TPIDR_EL0);\n\tfpsimd_state_save(task, &c->fpsimd_state);\n}\n\nstatic inline void user_task_sched_in(struct task *task)\n{\n\tstruct cpu_context *c = &task->cpu_context;\n\textern void fpsimd_state_restore(struct task *task,\n\t\tstruct fpsimd_context *c);\n\n\twrite_sysreg(c->tpidr_el0, TPIDR_EL0);\n\twrite_sysreg(c->tpidrro_el0, TPIDRRO_EL0);\n\tfpsimd_state_restore(task, &c->fpsimd_state);\n\n\twrite_sysreg(c->ttbr_el0, TTBR0_EL1);\n}\n\nvoid arch_task_sched_out(struct task *task)\n{\n\tif (!(task->flags & TASK_FLAGS_KERNEL))\n\t\tuser_task_sched_out(task);\n}\n\nvoid arch_task_sched_in(struct task *task)\n{\n\tif (!(task->flags & TASK_FLAGS_KERNEL))\n\t\tuser_task_sched_in(task);\n}\n\nvoid arch_init_task(struct task *task, void *entry, void *user_sp, void *arg)\n{\n\textern void aarch64_task_exit(void);\n\tgp_regs *regs = stack_to_gp_regs(task->stack_top);\n\n\tmemset(regs, 0, sizeof(gp_regs));\n\ttask->stack_base = (void *)regs;\n\n\tregs->pc = (uint64_t)entry;\n\tregs->sp = (uint64_t)user_sp;\n\tregs->x18 = (uint64_t)task;\n\n\tif (task->flags & TASK_FLAGS_KERNEL) {\n\t\t/*\n\t\t * if the task is not a deadloop the task will exist\n\t\t * by itself like below\n\t\t * int main(int argc, char **argv)\n\t\t * {\n\t\t *\tdo_some_thing();\n\t\t *\treturn 0;\n\t\t * }\n\t\t * then the lr register should store a function to\n\t\t * handle the task's exist\n\t\t *\n\t\t * kernel task will not use fpsimd now, so kernel task\n\t\t * do not need to save/restore it\n\t\t */\n\t\tregs->lr = (uint64_t)aarch64_task_exit;\n\t\tregs->pstate = AARCH64_SPSR_EL1h;\n\t} else {\n\t\tregs->pstate = AARCH64_SPSR_EL0t;\n\t\ttask->cpu_context.tpidr_el0 = 0;\n\t\ttask->cpu_context.tpidrro_el0 = (uint64_t)task->pid << 32 | (task->tid);\n\t\ttask->cpu_context.ttbr_el0 = task_ttbr_value(task);\n\t}\n}\n\nvoid arch_set_task_user_stack(struct task *task, unsigned long stack)\n{\n       gp_regs *regs = stack_to_gp_regs(task->stack_top);\n       regs->sp = stack;\n}\n\nvoid arch_set_task_reg0(struct task *task, unsigned long data)\n{\n       gp_regs *regs = stack_to_gp_regs(task->stack_top);\n       regs->x0 = data;\n}\n\nvoid arch_set_tls(struct task *task, unsigned long tls)\n{\n       struct cpu_context *ctx = &task->cpu_context;\n       ctx->tpidr_el0 = tls;\n}\n\nvoid arch_set_task_entry_point(struct task *task, long entry)\n{\n       gp_regs *regs = stack_to_gp_regs(task->stack_top);\n       regs->pc = entry;\n}\n\npgd_t *arch_alloc_process_page_table(void)\n{\n       pgd_t *pgt;\n\n       /*\n\t* - 3 levels page table.\n\t* - 4KB page size.\n\t* - 512G virtual memory space.\n\t* - 4KB PGD  \n        */\n       pgt = get_free_pages(1, GFP_KERNEL);\n       if (!pgt)\n               return NULL;\n\n       memset(pgt, 0, PAGE_SIZE);\n       return pgt;\n}\n\nint arch_get_asid_size(void)\n{\n       // TBD, get from the register\n       return 256;\n}\n\nvoid arch_release_task(struct task *task)\n{\n\n}\n\nstatic int __init_text aarch64_init_percpu(void)\n{\n\tuint64_t reg;\n\n\treg = read_CurrentEl();\n\tpr_notice(\"current EL is %d\\n\", GET_EL(reg));\n\n\t/*\n\t * set IMO and FMO let physic irq and fiq taken to\n\t * EL2, without this irq and fiq will not send to\n\t * the cpu\n\t */\n#ifdef CONFIG_VIRT\n\treg = read_sysreg64(HCR_EL2);\n\treg |= HCR_EL2_IMO | HCR_EL2_FMO | HCR_EL2_AMO;\n\twrite_sysreg64(reg, HCR_EL2);\n\t// write_sysreg64(0x3 << 20, CPACR_EL2);\n\tdsb();\n\tisb();\n#else\n\twrite_sysreg64(0x3 << 20, CPACR_EL1);\n\tdsb();\n\tisb();\n#endif\n\n\treturn 0;\n}\narch_initcall_percpu(aarch64_init_percpu);\n\nint arch_early_init(void)\n{\n#ifdef CONFIG_DEVICE_TREE\n\t/*\n\t * set up the platform from the dtb file then get the spin\n\t * table information if the platform is using spin table to\n\t * wake up other cores\n\t */\n\tof_setup_platform();\n#endif\n\treturn 0;\n}\n\nint __arch_init(void)\n{\n#ifdef CONFIG_DEVICE_TREE\n\tof_parse_host_device_tree();\n#endif\n\treturn 0;\n}\n\nuint64_t cpuid_to_affinity(int cpuid)\n{\n\tint aff0, aff1;\n\n\tif (cpu_has_feature(ARM_FEATURE_MPIDR_SHIFT))  {\n\t\tif (cpuid < CONFIG_NR_CPUS_CLUSTER0)\n\t\t\treturn (cpuid << MPIDR_EL1_AFF1_LSB);\n\t\telse {\n\t\t\taff0 = cpuid - CONFIG_NR_CPUS_CLUSTER0;\n\t\t\taff1 = 1;\n\n\t\t\treturn (aff1 << MPIDR_EL1_AFF2_LSB) |\n\t\t\t\t(aff0 << MPIDR_EL1_AFF1_LSB);\n\t\t}\n\t} else {\n\t\tif (cpuid < CONFIG_NR_CPUS_CLUSTER0) {\n\t\t\treturn cpuid;\n\t\t} else {\n\t\t\taff0 = cpuid - CONFIG_NR_CPUS_CLUSTER0;\n\t\t\taff1 = 1;\n\n\t\t\treturn (aff1 << MPIDR_EL1_AFF1_LSB) + aff0;\n\t\t}\n\t}\n}\n\nint affinity_to_cpuid(unsigned long affinity)\n{\n\tint aff0, aff1;\n\n\tif (cpu_has_feature(ARM_FEATURE_MPIDR_SHIFT))  {\n\t\taff0 = (affinity >> MPIDR_EL1_AFF1_LSB) & 0xff;\n\t\taff1 = (affinity >> MPIDR_EL1_AFF2_LSB) & 0xff;\n\t} else {\n\t\taff0 = (affinity >> MPIDR_EL1_AFF0_LSB) & 0xff;\n\t\taff1 = (affinity >> MPIDR_EL1_AFF1_LSB) & 0xff;\n\t}\n\n\treturn (aff1 * CONFIG_NR_CPUS_CLUSTER0) + aff0;\n}\n\nvoid arch_smp_init(phy_addr_t *smp_h_addr)\n{\n#ifdef CONFIG_DEVICE_TREE\n\tof_spin_table_init(smp_h_addr);\n#endif\n}\n\nstatic void *relocate_dtb_address(unsigned long dtb)\n{\n\tunsigned long mem_end, relocated_base = dtb;\n\textern unsigned long minos_end;\n\tsize_t size;\n\n\tASSERT(!fdt_check_header((void *)dtb));\n\n\t/*\n\t * DTB image start address should bigger than minos_end, or\n\t * DTB image should included in minos.bin.\n\t */\n\tmem_end = PAGE_BALIGN(ptov(minos_end));\n\tsize = fdt_totalsize(dtb);\n\tif ((dtb < minos_end) && ((dtb + size) > minos_end))\n\t\tpanic(\"minos data overlaped by dtb image\\n\");\n\n\tif (dtb > mem_end) {\n\t\tpr_notice(\"relocate dtb from 0x%x to 0x%x\\n\", dtb, mem_end);\n\t\tmemmove((void *)mem_end, (void *)dtb, size);\n\n\t\t/*\n\t\t * call of init again to check and setup the new\n\t\t * device tree memory address.\n\t\t */\n\t\trelocated_base = mem_end;\n\t\tminos_end += PAGE_BALIGN(size);\n\t}\n\n\treturn (void *)relocated_base;\n}\n\nvoid arch_main(void *dtb)\n{\n\textern void boot_main(void);\n\tchar *name = NULL;\n\n\tpr_notice(\"Starting Minos AARCH64\\n\");\n#ifdef CONFIG_DTB_LOAD_ADDRESS\n\tdtb = (void *)ptov(CONFIG_DTB_LOAD_ADDRESS);\n#else\n\tdtb = (void *)ptov(dtb);\n#endif\n\tpr_notice(\"DTB address [0x%x]\\n\", dtb);\n\n\tdtb = relocate_dtb_address((unsigned long)dtb);\n\n\tof_init(dtb);\n\tof_get_console_name(&name);\n\tconsole_init(name);\n\n\t/*\n\t * here start the kernel\n\t */\n\tboot_main();\n}\n"
  },
  {
    "path": "kernel/arch/aarch64/core/arm_arch_timer.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/time.h>\n#include <minos/init.h>\n#include <asm/io.h>\n#include <minos/stdlib.h>\n#include <minos/softirq.h>\n#include <minos/sched.h>\n#include <minos/irq.h>\n#include <minos/of.h>\n#include <asm/reg.h>\n#include <minos/platform.h>\n#include <asm/aarch64_reg.h>\n\nenum timer_type {\n\tSEC_PHY_TIMER,\n\tNONSEC_PHY_TIMER,\n\tVIRT_TIMER,\n\tHYP_TIMER,\n\tTIMER_MAX,\n};\n\nstatic char *timer_name[TIMER_MAX] = {\n\t\"   sec_phy_timer \",\n\t\"nonsec_phy_timer \",\n\t\"      virt_timer \",\n\t\"hypervisor_timer \"\n};\n\nstruct armv8_timer_info {\n\tuint32_t irq;\n\tunsigned long flags;\n};\n\nstatic struct armv8_timer_info timer_info[TIMER_MAX];\n\nuint32_t cpu_khz = 0;\nuint64_t boot_tick = 0;\n\nextern unsigned long sched_tick_handler(unsigned long data);\n\nvoid arch_enable_timer(unsigned long expires)\n{\n\tuint64_t deadline;\n\tunsigned long ctl;\n\n\tif (expires == 0) {\n\t\twrite_sysreg32(0, ARM64_CNTSCHED_CTL);\n\t\treturn;\n\t}\n\n\tdeadline = ns_to_ticks(expires);\n\twrite_sysreg64(deadline, ARM64_CNTSCHED_CVAL);\n\n\tctl = read_sysreg(ARM64_CNTSCHED_CTL);\n\tctl |= CNT_CTL_ENABLE;\n\tctl &= ~CNT_CTL_IMASK;\n\twrite_sysreg(ctl, ARM64_CNTSCHED_CTL);\n\tisb();\n}\n\nunsigned long get_sys_ticks(void)\n{\n\tisb();\n\treturn read_sysreg64(CNTPCT_EL0);\n}\n\nunsigned long get_current_time(void)\n{\n\tisb();\n\treturn ticks_to_ns(read_sysreg64(CNTPCT_EL0) - boot_tick);\n}\n\nunsigned long get_sys_time(void)\n{\n\tisb();\n\treturn ticks_to_ns(read_sysreg64(CNTPCT_EL0));\n}\n\nstatic int __init_text timers_arch_init(void)\n{\n\tint i, ret, from_dt;\n\tstruct armv8_timer_info *info;\n\tstruct device_node *node = NULL;\n\n#ifdef CONFIG_DEVICE_TREE\n\tnode = of_find_node_by_compatible(of_root_node, arm_arch_timer_match_table);\n#endif\n\tif (!node) {\n\t\tpr_err(\"can not find arm-arch-timer\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\tfor (i = 0; i < TIMER_MAX; i++) {\n\t\tinfo = &timer_info[i];\n\t\tret = get_device_irq_index(node, &info->irq, &info->flags, i);\n\t\tif (ret) {\n\t\t\tpr_err(\"error found in arm timer config\\n\");\n\t\t\treturn -ENOENT;\n\t\t}\n\n\t\tpr_notice(\"%s : %d\\n\", timer_name[i], info->irq);\n\t}\n\n\tret = of_get_u32_array(node, \"clock-frequency\", &cpu_khz, 1);\n\tif (cpu_khz > 0) {\n\t\tcpu_khz = cpu_khz / 1000;\n\t\tfrom_dt = 1;\n\t} else {\n\t\tcpu_khz = read_sysreg32(CNTFRQ_EL0) / 1000;\n\t\tfrom_dt = 0;\n\t}\n\n\tisb();\n\tboot_tick = read_sysreg64(CNTPCT_EL0);\n\tpr_notice(\"clock freq from %s %d\\n\", from_dt ? \"DTB\" : \"REG\", cpu_khz);\n\tpr_notice(\"boot ticks is :0x%x\\n\", boot_tick);\n\n\tif (platform->time_init)\n\t\tplatform->time_init();\n\n#ifdef CONFIG_VIRT\n\textern int arch_vtimer_init(uint32_t virtual_irq, uint32_t phy_irq);\n\tarch_vtimer_init(timer_info[VIRT_TIMER].irq,\n\t\t\ttimer_info[NONSEC_PHY_TIMER].irq);\n#endif\n\n\treturn 0;\n}\n\nstatic int timer_interrupt_handler(uint32_t irq, void *data)\n{\n\textern void soft_timer_interrupt(void);\n\tunsigned long ctl;\n\n\tctl = read_sysreg(ARM64_CNTSCHED_CTL);\n\tctl |= CNT_CTL_IMASK;\t\t\t// disable the interrupt.\n\twrite_sysreg(ctl, ARM64_CNTSCHED_CTL);\n\n\tsoft_timer_interrupt();\n\n\treturn 0;\n}\n\nstatic int __init_text timers_init(void)\n{\n\tstruct armv8_timer_info *sched_timer_info = NULL;\n\n#ifdef CONFIG_VIRT\n\tstruct armv8_timer_info *info;\n\textern int virtual_timer_irq_handler(uint32_t irq, void *data);\n\n\twrite_sysreg64(0, CNTVOFF_EL2);\n\n\t/* el1/el0 can read CNTPCT_EL0 */\n\twrite_sysreg32(1 << 0, CNTHCTL_EL2);\n\n\t/* disable hyper and phy timer */\n\twrite_sysreg32(0, CNTP_CTL_EL0);\n\twrite_sysreg32(0, CNTHP_CTL_EL2);\n\tisb();\n\n\tinfo = &timer_info[VIRT_TIMER];\n\tif (info->irq) {\n\t\trequest_irq(info->irq, virtual_timer_irq_handler,\n\t\t\tinfo->flags & 0xf, \"virt timer irq\", NULL);\n\t}\n\n\tsched_timer_info = &timer_info[HYP_TIMER];\n#else\n\tsched_timer_info = &timer_info[VIRT_TIMER];\n#endif\n\n\tASSERT(sched_timer_info && sched_timer_info->irq);\n\trequest_irq(sched_timer_info->irq,\n\t\t\ttimer_interrupt_handler,\n\t\t\tsched_timer_info->flags & 0xf,\n\t\t\t\"sched_timer_int\", NULL);\n\n\treturn 0;\n}\n\nsubsys_initcall_percpu(timers_init);\nsubsys_initcall(timers_arch_init);\n"
  },
  {
    "path": "kernel/arch/aarch64/core/asm-offset.c",
    "content": "/*\n * Copyright (C) 2019 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/kbuild.h>\n#include <minos/percpu.h>\n#include <minos/task_def.h>\n\n#define __NO_STUBS\t1\n\nint main(void)\n{\n\tDEFINE(TASK_INFO_SIZE, sizeof(struct task_info));\n\tDEFINE(TASK_INFO_FLAGS_OFFSET, offsetof(struct task_info, flags));\n\tDEFINE(PCPU_SIZE, sizeof(struct pcpu));\n\tDEFINE(PCPU_ID_OFFSET, offsetof(struct pcpu, pcpu_id));\n\tDEFINE(PCPU_STACK_OFFSET, offsetof(struct pcpu, stack));\n\tDEFINE(TASK_SIZE, sizeof(struct task));\n\tDEFINE(TASK_STACK_OFFSET, offsetof(struct task, stack_base));\n\tDEFINE(PCPU_CURRENT_TASK, offsetof(struct pcpu, running_task));\n\tDEFINE(GP_REGS_SIZE, sizeof(gp_regs));\n\tDEFINE(TASK_USER_REGS_OFFSET, offsetof(struct task, user_regs));\n\n\treturn 0;\n}\n"
  },
  {
    "path": "kernel/arch/aarch64/core/boot.S",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/aarch64_common.h>\n#include <config/config.h>\n#include <asm/asm-offset.h>\n#include <asm/asm_marco.S>\n#include <asm/aarch64_reg.h>\n\n\t.section __start_up, \"ax\"\n\t.balign 4\n\n.macro clear_ttbr0\n#ifdef CONFIG_VIRT\n#ifdef CONFIG_ARM_VHE\n\tmsr     ARM64_TTBR0, xzr\n#endif\n\ttlbi\talle2\n#else\n\tmsr     ARM64_TTBR0, xzr\n\ttlbi\tvmalle1\n#endif\n.endm\n\n\t// current task is store in the x18\n.macro set_percpu_idle_task tsk, tsk_size, cpuid\n\tldr\t\\tsk, =idle_tasks\n\tldr\t\\tsk_size, =TASK_SIZE\n\tmul\t\\tsk_size, \\tsk_size, \\cpuid\n\tadd\t\\tsk, \\tsk, \\tsk_size\n\tmov\tx18, \\tsk\n.endm\n\n\t// TPIDR_ELx will store the pcpu data\n.macro set_percpu_pcpu pcpu, pcpu_size, cpuid\n\tldr\t\\pcpu, =pcpus\n\tldr\t\\pcpu_size, =PCPU_SIZE\n\tmul\t\\pcpu_size, \\pcpu_size, \\cpuid\n\tadd\t\\pcpu, \\pcpu, \\pcpu_size\n\tmsr\tARM64_TPIDR, \\pcpu\n\tasm_vtop \\pcpu\n\tstr\tx19, [\\pcpu, #PCPU_ID_OFFSET]\n.endm\n\n\t.global _start\n\t.type _start, \"function\"\n_start:\n\t/* interrupt disabled mmu/dcache/icache off */\n\tmsr\tdaifset, #2\n\tb\tdo_start\n\t.quad   0\t\t\t\t/* Image load offset from start of RAM */\n        .quad   __code_end - _start\t\t/* reserved */\n        .quad   8\t\t\t\t/* kernel flags */\n        .quad   0\t\t\t\t/* reserved */\n        .quad   0\t\t\t\t/* reserved */\n        .quad   0\t\t\t\t/* reserved */\n        .byte   0x41\t\t\t\t/* Magic number, \"ARM\\x64\" */\n        .byte   0x52\n        .byte   0x4d\n        .byte   0x64\n        .long   0x0\n\ndo_start:\n\tmov\tx27, x0\t\t\t\t// save the dtb blob to x27\n\n\t// see which level we are now, minos currently can\n\t// support running on EL1 and EL2 but can not run\n\t// on EL3.\n\tmrs\tx0, CurrentEl\n\tmov\tx1, x0, lsr #2\n\tand\tx1, x1, #3\n\n\t// can not run on EL3.\n\tcmp\tx1, #3\n\tb.eq\tminos_panic\n\n\tmov\tx26, #0\n\tcmp\tx1, #2\n\n#ifdef CONFIG_VIRT\n\tb.ne\tminos_panic\n\n\tmov\tx0, 0\n\tmsr\tHCR_EL2, x0\n\tisb\n\n#ifdef CONFIG_ARM_VHE\n\t// if VHE is enabled, check whether the soc has\n\t// implement this feature and enable it\n\tmrs\tx0, ID_AA64MMFR1_EL1\n\tubfx\tx1, x0, #8, #4\n\tcbz\tx1, minos_panic\n\n\tmrs\tx0, HCR_EL2\n\tldr\tx1, =HCR_EL2_E2H\n\torr\tx0, x0, x1\n\tmsr\tHCR_EL2, x0\n\tisb\n#endif\n#else\n\t// if current EL is not EL2 then jump to EL1\n\t// directly, othewise set 1 to x26 indicate that\n\t// need to jump to EL1\n\tb.ne\tminos_os_start\n\tmov\tx26, #1\n\n\tmov\tx0, 0\n\tmsr\tHCR_EL2, x0\n\tisb\n#endif // CONFIG_VIRT\n\n\t// init the EL2 env\n\tmrs\tx0, midr_el1\n\tmrs\tx1, mpidr_el1\n\tmsr\tvpidr_el2, x0\n\tmsr\tvmpidr_el2, x1\n\n\t/*\n\t * neither EL3 nor EL2 trap floating point or\n\t * accesses to CPACR\n\t */\n\tldr\tx0, =0x300000\n\tmsr\tCPTR_EL2, x0\n\n\tmsr\tVTTBR_EL2, xzr\n\tdsb\tsy\n\tisb\n\n\tcmp\tx26, #1\n\tb.ne\tminos_os_start\n\n\t// drop to EL1\n\tmov\tx1, #15\n\tmsr\tICC_SRE_EL1, x1\n\n\tmrs\tx1, HCR_EL2\n\tmov\tx2, #HCR_EL2_RW\n\torr\tx2, x2, x1\n\tmsr\tHCR_EL2, x2\n\tisb\n\n\tmsr\tCPTR_EL2, xzr\n\tmov\tx1, #0\n\tmsr\tSCTLR_EL2, x1\n\n\tmov\tx1, #3\n\tmsr\tCNTHCTL_EL2, x1\n\tdsb\tsy\n\tisb\n\ndrop_to_el1:\n\tadr\tx1, minos_os_start\n\tmsr\tELR_EL2, x1\n\tmov\tx1, #(AARCH64_SPSR_EL1h | AARCH64_SPSR_F | AARCH64_SPSR_I | AARCH64_SPSR_A)\n\tmsr\tSPSR_EL2, x1\n\teret\n\tdsb\tnsh\n\tisb\n\nminos_os_start:\n\tadr\tx1, _start\t\t\t// entry address must 4K align\n\tand\tx0, x1, #0xfff\n\tcbnz\tx0, minos_panic\n\n\t// minos_start to __code_start is the reserve memory\n\t// for minos\n\tldr\tx3, =0xffffffffffe00000\n\tand\tx1, x1, x3\n\tadr\tx2, minos_start\n\tstr\tx1, [x2]\n\n\tbl\tarch_raw_smp_processor_id\t// cpuid save to x19\n\tmov\tx19, x0\n\n\t/* using current EL stack register */\n\tmsr\tspsel, #1\n\tdsb\tnsh\n\tisb\n\n\tldr\tx1, =elx_vectors\n\tmsr\tARM64_VBAR, x1\n\n\t/* enable Abort now for early system abort */\n\tmsr\tdaifclr, #4\n\tdsb\tnsh\n\tisb\n\n\t/* invalid the dcache and flush the tlb */\n\tbl\tinv_dcache_all\n\tdsb\tsy\n\tisb\n\n#ifdef CONFG_VIRT\n\ttlbi\talle2\n#else\n\ttlbi\tvmalle1\n#endif\n\tdsb\tsy\n\tisb\n\n\tldr\tx1, =ARM64_SCTLR_VALUE\n\tmsr\tARM64_SCTLR, x1\n\tdsb\tnsh\n\tisb\n\n\t/* setup the el2 page table */\n\tldr\tx1, = __stage1_page_table\n\tasm_vtop x1\n\tmsr     ARM64_TTBR0, x1\n\tmsr     ARM64_TTBR1, x1\n\tdsb\tnsh\n\tisb\n\n\t/*\n\t * 0xff440c0400\n\t * MT_DEVICE_NGNRNE\t0\n\t * MT_DEVICE_NGNRE\t1\n\t * MT_DEVICE_GRE\t2\n\t * MT_NORMAL_NC\t\t3\n\t * MT_NORMAL\t\t4\n\t * 0x00 - MT_DEVICE_NGNRNE\n\t * 0x04 - MT_DEVICE_NGNRE\n\t * 0x0c - MT_DEVICE_GRE\n\t * 0x44 - MT_NORMAL_NC\n\t * 0xff - MT_NORMAL\n\t * 0xbb - MT_NORMAL_WT\n\t */\n\tldr\tx1, =0xbbff440c0400\n\tmsr\tARM64_MAIR, x1\n\n\t/* get the physical address range */\n\tmrs\tx0, ID_AA64MMFR0_EL1\n\tand\tx0, x0, #0xf\n#if defined(CONFIG_VIRT) && !defined(CONFIG_ARM_VHE)\n\tmov\tx2, x0, lsl #16\n\tldr\tx3, =0xfffffffffff8ffff\n#else\n\tmov\tx2, x0, lsl #32\n\tldr\tx3, =0xfffffff8ffffffff\n#endif\n\n\tldr\tx1, =ARM64_TCR_VALUE\t\t// load the value of TCR.\n\tand\tx1, x1, x3\t\t\t// update the IPA/PA for TCR_ELx.\n\torr\tx1, x1, x2\n\n\tmsr     ARM64_TCR, x1\t\t\t// set the TCR_ELx.\n\tdsb     sy\n\tisb\n\n\t// idle task is in Current_EL\n\tmov\tx1, #ARM64_SPSR_VALUE\n\tmsr\tARM64_SPSR, x1\n\tdsb\tnsh\n\n\tcbnz\tx19, secondary_start_up\n\n\tldr\tx0, =__minos_end\n\tasm_vtop x0\n\tadr\tx1, minos_stack_top\n\tadr\tx2, minos_bootmem_base\n\tadr\tx3, minos_stack_bottom\n\n\t// store the bootmem base\n\tadd\tx0, x0, #4095\n\tmov\tx4, #4095\n\tmvn\tx5, x4\n\tand\tx0, x0, x5\n\tstr\tx0, [x2]\n\n\t// store the minos stack bottom\n\tstr\tx0, [x3]\n\n\t// store the minos stack top\n\tmov\tx4, #CONFIG_TASK_STACK_SIZE\n\tmov\tx5, #CONFIG_NR_CPUS\n\tmul\tx5, x4, x5\n\tadd\tx0, x0, x5\n\tstr\tx0, [x1]\n\n\tsub\tx0, x0, x19, lsl #CONFIG_TASK_STACK_SHIFT\n\tasm_ptov x0\n\tmov\tsp, x0\n\n\tldr\tx0, =__bss_start\n\tasm_vtop x0\n\tmov\tx1, #0\n\tldr\tx2, =__bss_end\n\tasm_vtop x2\n\tsub\tx2, x2, x0\n\tbl\tmemset\n\n\tldr\tx0, =__percpu_start\n\tasm_vtop x0\n\tmov\tx1, #0\n\tldr\tx2, =__percpu_end\n\tasm_vtop x2\n\tsub\tx2, x2, x0\n\tbl\tmemset\n\n\t// map the boot memory when booting\n\tbl\tmap_boot_mem\n\tdsb\tishst\n\tisb\n\n\t// current task is store in the x18\n\t// x18 will store the current task pointer\n\tset_percpu_idle_task x0, x1, x19\n\n\t// TPIDR_ELx will store the pcpu data\n\tset_percpu_pcpu x0, x1, x19\n\n\tldr\tx26, =mmu_on\n\n\t// enable the mmu and disable the aligment check\n\tmrs\tx1, ARM64_SCTLR\n\torr\tx1, x1, #SCTLR_ELx_M\n\torr\tx1, x1, #SCTLR_ELx_C\n\torr\tx1, x1, #SCTLR_ELx_I\n\tbic\tx1, x1, #SCTLR_ELx_SA\n\tbic\tx1, x1, #SCTLR_ELx_A\n\tmsr\tARM64_SCTLR, x1\n\tdsb\tsy\n\tisb\n\n\tbr\tx26\n\nmmu_on:\n\tic\tialluis\n\tdsb\tsy\n\tisb\n\n\tclear_ttbr0\n\n\tdsb\tsy\n\tisb\n\tmov\tx0, x27\t\t// restore the dtb address.\n\tbl\tarch_main\t// never return.\ndead_loop:\n\tb\tdead_loop\n\nsecondary_start_up:\n\t// setup the idle task stack\n\tadr\tx0, minos_stack_top\n\tldr\tx0, [x0]\n\tsub\tx0, x0, x19, lsl #CONFIG_TASK_STACK_SHIFT\n\tasm_ptov x0\n\tmov\tsp, x0\n\n\t// current task is store in the x18\n\t// x18 will store the current task pointer\n\tset_percpu_idle_task x0, x1, x19\n\n\t// TPIDR_ELx will store the pcpu data\n\tset_percpu_pcpu x0, x1, x19\n\n\tldr\tx1, =ARM64_SCTLR_VALUE\n\tmsr\tARM64_SCTLR, x1\n\tdsb\tsy\n\tisb\n\n\tldr     x26, =mmu_on_secondary\n\n\t// enable the dcache and the icache\n\tmrs\tx1, ARM64_SCTLR\n\torr\tx1, x1, #SCTLR_ELx_C\n\torr\tx1, x1, #SCTLR_ELx_I\n\torr\tx1, x1, #SCTLR_ELx_M\n\tbic\tx1, x1, #SCTLR_ELx_SA\n\tbic\tx1, x1, #SCTLR_ELx_A\n\tmsr\tARM64_SCTLR, x1\n\tdsb\tsy\n\tisb\n\n\tbr\tx26\n\nmmu_on_secondary:\n\tic\tialluis\n\tdsb\tsy\n\tisb\n\n\tclear_ttbr0\n\n\tldr\tx1, =__smp_affinity_id\n\tadd\tx1, x1, x19, lsl #3\n\tmrs\tx2, MPIDR_EL1\n\tldr\tx4, =0x000000ff00ffffff\n\tand\tx2, x2, x4\n\tstr\tx2, [x1]\n\tdsb\tsy\n\tisb\n\n\t/* here wait for boot cpu finish tht init work */\n\t/* pass the cpuid to the boot_secondary */\n\tmov\tx0, x19\n\tbl\tboot_secondary\n\tnop\n\nminos_panic:\n\tnop\n\tb\tminos_panic\n\n\t.data\n\t.global minos_start\n\t.global minos_bootmem_base\n\t.global minos_stack_top\n\t.global minos_stack_bottom\n\t.global minos_end\n\t.balignl 16, 0xdeadbeef\n\nminos_start:\t\t.quad\t0x0\nminos_bootmem_base:\t.quad\t0x0\nminos_stack_top:\t.quad\t0x0\nminos_stack_bottom:\t.quad\t0x0\nminos_end:\t\t.quad\t0x0\n"
  },
  {
    "path": "kernel/arch/aarch64/core/cache.S",
    "content": "/*\n * Copyright (C) 2001 Deep Blue Solutions Ltd.\n * Copyright (C) 2012 ARM Ltd.\n * Copyright (C) 1996-2000 Russell King\n * Copyright (C) 2012 ARM Ltd.\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/aarch64_common.h>\n#include <asm/asm_marco.S>\n\n\t.global flush_dcache_range\n\t.global inv_dcache_range\n\t.global inv_dcache_all\n\t.global flush_dcache_all\n\t.global flush_cache_all\n\n.macro\tdcache_line_size  reg, tmp\n\tmrs\t\\tmp, ctr_el0\n\tubfx\t\\tmp, \\tmp, #16, #4\n\tmov\t\\reg, #4\n\tlsl\t\\reg, \\reg, \\tmp\n.endm\n\n.macro\ticache_line_size  reg, tmp\n\tmrs\t\\tmp, ctr_el0\n\tand\t\\tmp, \\tmp, #0xf\n\tmov\t\\reg, #4\n\tlsl\t\\reg, \\reg, \\tmp\n.endm\n\n.macro do_dcache_maintenance_by_mva op\n\t/* Exit early if size is zero */\n\tcbz\tx1, exit_loop_\\op\n\tdcache_line_size x2, x3\n\tadd\tx1, x0, x1\n\tsub\tx3, x2, #1\n\tbic\tx0, x0, x3\nloop_\\op:\n\tdc\t\\op, x0\n\tadd\tx0, x0, x2\n\tcmp\tx0, x1\n\tb.lo    loop_\\op\n\tdsb\tsy\nexit_loop_\\op:\n\tret\n.endm\n\nfunc flush_dcache_range\n\tdo_dcache_maintenance_by_mva civac\nendfunc flush_dcache_range\n\nfunc inv_dcache_range\n\tdo_dcache_maintenance_by_mva ivac\nendfunc inv_dcache_range\n\nfunc inv_dcache_all\n\t// From the ARM ARMv8-A Architecture Reference Manual\n\tdmb\tish                   // ensure all prior inner-shareable accesses have been observed\n\tmrs\tx0, CLIDR_EL1\n\tand\tw3, w0, #0x07000000   // get 2 x level of coherence\n\tlsr\tw3, w3, #23\n\tcbz\tw3, finished\n\tmov\tw10, #0               // w10 = 2 x cache level\n\tmov\tw8, #1                // w8 = constant 0b1\nloop_level:\n\tadd\tw2, w10, w10, lsr #1  // calculate 3 x cache level\n\tlsr\tw1, w0, w2            // extract 3-bit cache type for this level\n\tand\tw1, w1, #0x7\n\tcmp\tw1, #2\n\tb.lt\tnext_level            // no data or unified cache at this level\n\tmsr\tCSSELR_EL1, x10       // select this cache level\n\tisb\t\t\t      // synchronize change of csselr\n\tmrs\tx1, CCSIDR_EL1        // read ccsidr\n\tand\tw2, w1, #7            // w2 = log2(linelen)-4\n\tadd\tw2, w2, #4            // w2 = log2(linelen)\n\tubfx\tw4, w1, #3, #10       // w4 = max way number, right aligned\n\tclz\tw5, w4                // w5 = 32-log2(ways), bit position of way in dc operand\n\tlsl\tw9, w4, w5            // w9 = max way number, aligned to position in dc operand\n\tlsl\tw16, w8, w5           // w16 = amount to decrement way number per iteration\nloop_way:\n\tubfx\tw7, w1, #13, #15      // w7 = max set number, right aligned\n\tlsl\tw7, w7, w2            // w7 = max set number, aligned to position in dc operand\n\tlsl\tw17, w8, w2           // w17 = amount to decrement set number per iteration\nloop_set:\n\torr\tw11, w10, w9          // w11 = combine way number and cache number ...\n\torr\tw11, w11, w7          // ... and set number for dc operand\n\tdc\tisw, x11              // do data cache invalidate by set and way\n\tsubs\tw7, w7, w17           // decrement set number\n\tb.ge\tloop_set\n\tsubs\tx9, x9, x16           // decrement way number\n\tb.ge\tloop_way\nnext_level:\n\tadd\tw10, w10, #2          // increment 2 x cache level\n\tcmp\tw3, w10\n\tb.gt\tloop_level\n\tdsb\tsy                    // ensure completion of previous cache maintenance operation\n\tisb\nfinished:\n\tret\nendfunc inv_dcache_all\n\nfunc flush_dcache_all\n\tdmb\tsy\t\t\t\t// ensure ordering with previous memory accesses\n\tmrs\tx0, clidr_el1\t\t\t// read clidr\n\tand\tx3, x0, #0x7000000\t\t// extract loc from clidr\n\tlsr\tx3, x3, #23\t\t\t// left align loc bit field\n\tcbz\tx3, finish\t\t\t// if loc is 0, then no need to clean\n\tmov\tx10, #0\t\t\t\t// start clean at cache level 0\nloop4:\n\tadd\tx2, x10, x10, lsr #1\t\t// work out 3x current cache level\n\tlsr\tx1, x0, x2\t\t\t// extract cache type bits from clidr\n\tand\tx1, x1, #7\t\t\t// mask of the bits for current cache only\n\tcmp\tx1, #2\t\t\t\t// see what cache we have at this level\n\tb.lt\tskip\t\t\t\t// skip if no cache, or just i-cache\n\tmrs\tx9, daif\n\tmsr\tdaifset, #2\n\tmsr\tcsselr_el1, x10\t\t\t// select current cache level in csselr\n\tisb\t\t\t\t\t// isb to sych the new cssr&csidr\n\tmrs\tx1, ccsidr_el1\t\t\t// read the new ccsidr\n\tmsr\tdaif, x9\n\tand\tx2, x1, #7\t\t\t// extract the length of the cache lines\n\tadd\tx2, x2, #4\t\t\t// add 4 (line length offset)\n\tmov\tx4, #0x3ff\n\tand\tx4, x4, x1, lsr #3\t\t// find maximum number on the way size\n\tclz\tw5, w4\t\t\t\t// find bit position of way size increment\n\tmov\tx7, #0x7fff\n\tand\tx7, x7, x1, lsr #13\t\t// extract max number of the index size\nloop2:\n\tmov\tx9, x4\t\t\t\t// create working copy of max way size\nloop3:\n\tlsl\tx6, x9, x5\n\torr\tx11, x10, x6\t\t\t// factor way and cache number into x11\n\tlsl\tx6, x7, x2\n\torr\tx11, x11, x6\t\t\t// factor index number into x11\n\tdc\tcisw, x11\t\t\t// clean & invalidate by set/way\n\tsubs\tx9, x9, #1\t\t\t// decrement the way\n\tb.ge\tloop3\n\tsubs\tx7, x7, #1\t\t\t// decrement the index\n\tb.ge\tloop2\nskip:\n\tadd\tx10, x10, #2\t\t\t// increment cache number\n\tcmp\tx3, x10\n\tb.gt\tloop4\nfinish:\n\tmov\tx10, #0\t\t\t\t// swith back to cache level 0\n\tmsr\tcsselr_el1, x10\t\t\t// select current cache level in csselr\n\tdsb\tsy\n\tisb\n\tret\nendfunc flush_dcache_all\n\n/*\n *\tflush_cache_all()\n *\n *\tFlush the entire cache system.  The data cache flush is now achieved\n *\tusing atomic clean / invalidates working outwards from L1 cache. This\n *\tis done using Set/Way based cache maintainance instructions.  The\n *\tinstruction cache can still be invalidated back to the point of\n *\tunification in a single instruction.\n */\nfunc flush_cache_all\n\tmov\tx12, x30\n\tbl\tflush_dcache_all\n\tmov\tx0, #0\n\tic\tialluis\t\t\t\t// I+BTB cache invalidate\n\tret\tx12\nendfunc flush_cache_all\n"
  },
  {
    "path": "kernel/arch/aarch64/core/cpu.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <config/config.h>\n#include <minos/arch.h>\n#include <minos/of.h>\n#include <asm/psci.h>\n#include <asm/svccc.h>\n#include <asm/cache.h>\n#include <minos/mm.h>\n\nextern unsigned char __smp_affinity_id;\nextern phy_addr_t smp_holding_address[CONFIG_NR_CPUS];\n\nstatic inline unsigned long psci_fn(uint32_t id, unsigned long a1,\n\t\tunsigned long a2, unsigned long a3)\n{\n\tstruct arm_smc_res res;\n\n\tsmc_call(id, a1, a2, a3, 0, 0, 0, 0, &res);\n\n\treturn res.a0;\n}\n\nstatic inline unsigned long psci_fn_hvc(uint32_t id, unsigned long a1,\n\t\tunsigned long a2, unsigned long a3)\n{\n\tstruct arm_smc_res res;\n\n\thvc_call(id, a1, a2, a3, 0, 0, 0, 0, &res);\n\n\treturn res.a0;\n}\n\nint psci_cpu_on(unsigned long cpu, unsigned long entry)\n{\n\treturn (int)psci_fn(PSCI_0_2_FN_CPU_ON, cpu, entry, 0);\n}\n\nint psci_cpu_off(unsigned long cpu)\n{\n\treturn (int)psci_fn(PSCI_0_2_FN_CPU_OFF, cpu, 0, 0);\n}\n\nvoid psci_system_reboot(int mode, const char *cmd)\n{\n\tpsci_fn(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0);\n}\n\nvoid psci_system_shutdown(void)\n{\n\tpsci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);\n}\n\nint psci_cpu_on_hvc(unsigned long cpu, unsigned long entry)\n{\n\treturn (int)psci_fn_hvc(PSCI_0_2_FN_CPU_ON, cpu, entry, 0);\n}\n\nint psci_cpu_off_hvc(unsigned long cpu)\n{\n\treturn (int)psci_fn_hvc(PSCI_0_2_FN_CPU_OFF, cpu, 0, 0);\n}\n\nvoid psci_system_reboot_hvc(int mode, const char *cmd)\n{\n\tpsci_fn_hvc(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0);\n}\n\nvoid psci_system_shutdown_hvc(void)\n{\n\tpsci_fn_hvc(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);\n}\n\nint spin_table_cpu_on(unsigned long affinity, unsigned long entry)\n{\n\tvoid *addr;\n\tint cpu = affinity_to_cpuid(affinity);\n\n\tif (smp_holding_address[cpu] != 0) {\n\t\taddr = io_remap(smp_holding_address[cpu], sizeof(uint64_t));\n\t\t*(unsigned long *)addr = entry;\n\n\t\t/* flush the cache and send signal to other cpu */\n\t\tflush_dcache_range((unsigned long)addr, PAGE_SIZE);\n\t\tsev();\n\t\tio_unmap((virt_addr_t)addr, sizeof(unsigned long));\n\t\treturn 0;\n\t}\n\n\treturn -EINVAL;\n}\n"
  },
  {
    "path": "kernel/arch/aarch64/core/cpu_feature.c",
    "content": "/*\n * Copyright (C) 2020 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <asm/aarch64_helper.h>\n#include <asm/arch.h>\n#include <asm/cpu_feature.h>\n#include <minos/mm.h>\n\n#define CPU_FEATURE_BITS\t128\n\n#define CPU_FEATURE_VHE\t\t0\n\nstatic DEFINE_PER_CPU(unsigned long *, cpu_feature);\n\nint cpu_has_feature(int feature)\n{\n\tint ret;\n\tunsigned long *cf;\n\n\tif (feature >= CPU_FEATURE_BITS)\n\t\treturn 0;\n\n\tcf = get_cpu_data(cpu_feature);\n\tret = test_bit(feature, cf);\n\tput_cpu_data(cpu_feature);\n\n\treturn ret;\n}\n\nint cpu_has_vhe(void)\n{\n\tstatic int vhe_enable = -1;\n\n\tif (vhe_enable == -1) {\n\t\tvhe_enable = cpu_has_feature(CPU_FEATURE_VHE);\n\t}\n\n\treturn vhe_enable;\n}\n\nstatic int arch_cpu_feature_init(void)\n{\n\tunsigned long *cf;\n\tuint64_t value;\n\n\tcf = malloc(BITS_TO_LONGS(CPU_FEATURE_BITS));\n\tif (!cf)\n\t\tpanic(\"can not allocate memory for cpu feature\\n\");\n\n\tmemset(cf, 0, BITMAP_SIZE(CPU_FEATURE_BITS));\n\tget_cpu_var(cpu_feature) = cf;\n\n\tvalue = read_mpidr_el1();\n\tif (value & MPIDR_EL1_MT)\n\t\tset_bit(ARM_FEATURE_MPIDR_SHIFT, cf);\n\n\treturn 0;\n}\narch_initcall_percpu(arch_cpu_feature_init);\n"
  },
  {
    "path": "kernel/arch/aarch64/core/entry.S",
    "content": "/*\n * Copyright (C) 2004-2017 ARM Ltd. All rights reserved.\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/aarch64_common.h>\n#include <config/config.h>\n#include <asm/asm_marco.S>\n\n// .align n = align 2^n\n// balign 0x80 = align with 0x80 boundary.\n\n\t.global elx_vectors\n\n\t.section __el2_vectors, \"ax\"\n\t.align 12\n\n.macro BAD_MODE mode\n\tstp\tx29, x30, [sp, #-16]\n\tmov\tx29, #\\mode\n\tb\t__bad_mode\n.endm\n\nelx_vectors:\nc0sync:\t\t// Current EL with SP0\n\tBAD_MODE VECTOR_C0_SYNC\n\t.balign 0x80\nc0irq:\n\tBAD_MODE VECTOR_C0_IRQ\n\t.balign 0x80\nc0fiq:\n\tBAD_MODE VECTOR_C0_FIQ\n\t.balign 0x80\nc0serr:\n\tBAD_MODE VECTOR_C0_SERR\n\t.balign 0x80\t// Current EL with SPx\ncxsync:\n\tb __sync_exception_from_current_el\n\t.balign 0x80\ncxirq:\n\tb __irq_exception_from_current_el\n\t.balign 0x80\ncxfiq:\n\tBAD_MODE VECTOR_CX_FIQ\n\t.balign 0x80\ncxserr:\n\tBAD_MODE VECTOR_CX_SERR\n\t.balign 0x80\t//Lower EL using AArch64\nl64sync:\n\tb __sync_exception_from_lower_el\n\t.balign 0x80\nl64irq:\n\tb __irq_exception_from_lower_el\n\t.balign 0x80\nl64fiq:\n\tBAD_MODE VECTOR_L64_FIQ\n\t.balign 0x80\nl64serr:\n\tBAD_MODE VECTOR_L64_SERR\n\t.balign 0x80\t// Lower EL using AArch32\nl32sync:\n\tb __sync_exception_from_lower_el\n\t.balign 0x80\nl32irq:\n\tb __irq_exception_from_lower_el\n\t.balign 0x80\nl32fiq:\n\tBAD_MODE VECTOR_L32_FIQ\n\t.balign 0x80\nl32serr:\n\tBAD_MODE VECTOR_L32_SERR\n\t.balign 0x80\n"
  },
  {
    "path": "kernel/arch/aarch64/core/fpsimd.c",
    "content": "/*\n * Copyright (C) 2020 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <asm/tcb.h>\n#include <minos/task.h>\n\nvoid fpsimd_state_save(struct task *task, struct fpsimd_context *c)\n{\n#ifdef CONFIG_VIRT\n\tif (task_is_vcpu(task) && task_is_32bit(task))\n\t\tc->fpexc32_el2 = read_sysreg32(FPEXC32_EL2);\n#endif\n\n\tc->fpsr = read_sysreg32(FPSR);\n\tc->fpcr = read_sysreg32(FPCR);\n\n\tasm volatile(\"stp q0, q1, [%1, #16 * 0]\\n\\t\"\n\t\t     \"stp q2, q3, [%1, #16 * 2]\\n\\t\"\n\t\t     \"stp q4, q5, [%1, #16 * 4]\\n\\t\"\n                     \"stp q6, q7, [%1, #16 * 6]\\n\\t\"\n                     \"stp q8, q9, [%1, #16 * 8]\\n\\t\"\n                     \"stp q10, q11, [%1, #16 * 10]\\n\\t\"\n                     \"stp q12, q13, [%1, #16 * 12]\\n\\t\"\n                     \"stp q14, q15, [%1, #16 * 14]\\n\\t\"\n                     \"stp q16, q17, [%1, #16 * 16]\\n\\t\"\n                     \"stp q18, q19, [%1, #16 * 18]\\n\\t\"\n                     \"stp q20, q21, [%1, #16 * 20]\\n\\t\"\n                     \"stp q22, q23, [%1, #16 * 22]\\n\\t\"\n                     \"stp q24, q25, [%1, #16 * 24]\\n\\t\"\n                     \"stp q26, q27, [%1, #16 * 26]\\n\\t\"\n                     \"stp q28, q29, [%1, #16 * 28]\\n\\t\"\n                     \"stp q30, q31, [%1, #16 * 30]\\n\\t\"\n                     : \"=Q\" (*c->regs) : \"r\" (c->regs));\n}\n\nvoid fpsimd_state_restore(struct task *task, struct fpsimd_context *c)\n{\n#ifdef CONFIG_VIRT\n\tif (task_is_vcpu(task) && task_is_32bit(task))\n\t\twrite_sysreg(c->fpexc32_el2, FPEXC32_EL2);\n#endif\n\n\twrite_sysreg(c->fpsr, FPSR);\n\twrite_sysreg(c->fpcr, FPCR);\n\n\tasm volatile(\"ldp q0, q1, [%1, #16 * 0]\\n\\t\"\n\t\t     \"ldp q2, q3, [%1, #16 * 2]\\n\\t\"\n                     \"ldp q4, q5, [%1, #16 * 4]\\n\\t\"\n                     \"ldp q6, q7, [%1, #16 * 6]\\n\\t\"\n                     \"ldp q8, q9, [%1, #16 * 8]\\n\\t\"\n                     \"ldp q10, q11, [%1, #16 * 10]\\n\\t\"\n                     \"ldp q12, q13, [%1, #16 * 12]\\n\\t\"\n                     \"ldp q14, q15, [%1, #16 * 14]\\n\\t\"\n                     \"ldp q16, q17, [%1, #16 * 16]\\n\\t\"\n                     \"ldp q18, q19, [%1, #16 * 18]\\n\\t\"\n                     \"ldp q20, q21, [%1, #16 * 20]\\n\\t\"\n                     \"ldp q22, q23, [%1, #16 * 22]\\n\\t\"\n                     \"ldp q24, q25, [%1, #16 * 24]\\n\\t\"\n                     \"ldp q26, q27, [%1, #16 * 26]\\n\\t\"\n                     \"ldp q28, q29, [%1, #16 * 28]\\n\\t\"\n                     \"ldp q30, q31, [%1, #16 * 30]\\n\\t\"\n                     : : \"Q\" (*c->regs), \"r\" (c->regs));\n\n}\n"
  },
  {
    "path": "kernel/arch/aarch64/core/mem_map.S",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/aarch64_common.h>\n#include <config/config.h>\n#include <asm/asm_marco.S>\n#include \"stage1.h\"\n#include <asm/aarch64_reg.h>\n\n\t/*\n\t * map the code memory VA->PA, if need to using\n\t * dcache need to enable the MMU, first clear\n\t * the page table, below is the var defination\n\t * Note, this function will call memset, and memset\n\t * will use x0 - x4, so need pay attention for x0-x4\n\t * if there some value saved in these register\n\t */\npage_table\t.req\tx24\nttb0_pgd\t.req\tx20\nttb0_pud\t.req\tx21\nttb0_pmd\t.req\tx22\n\nvaddr\t\t.req\tx5\npaddr\t\t.req\tx6\nsize\t\t.req\tx7\npte_attr\t.req\tx8\n\ntmp_const\t.req\tx9\npud_tmp\t\t.req\tx10\npmd_tmp\t\t.req\tx12\ntmp\t\t.req\tx13\npte_value\t.req\tx14\npte_index\t.req\tx15\nentry_size\t.req\tx16\nentry_align\t.req\tx17\nentry_mask\t.req\tx18\npagetable_base\t.req\tx23\t\t// store the pagetable for page allocation\n\n\t.section __start_up, \"ax\"\n\t.balign 4\n\n\t.global\tmap_boot_mem\n\n.macro asm_get_boot_page reg\n\tmov\t\\reg, pagetable_base\n\tadd\tpagetable_base, pagetable_base, #4096\n.endm\n\n#define HOST_TABLE_DES\t(S1_DES_TABLE | S1_TABLE_UAP | S1_TABLE_UXN)\n\nmap_boot_mem:\n\t/* save the lr register */\n\tmov\tx26, x30\n\n\t/* get the base address of free memory */\n\tadr\tpagetable_base, minos_stack_top\n\tldr\tpagetable_base, [pagetable_base]\n\n\t/* kernel pgd is defined in lds */\n\tmov\tx1, #0\n\tmov\tx2, #4096\n\tldr\tpage_table, = __stage1_page_table\n\tasm_vtop page_table\n\tmov\tx0, page_table\n\tbl\tmemset\n\n\t// boot memory must at 0 - 4GB space, here will\n\t// alloc all the 4GB memory's PUD\n\tbl\tbuild_page_table\n\n\t// map the reserve memory as rw\n\tadr\tvaddr, minos_start\n\tldr\tvaddr, [vaddr]\n\tldr\ttmp, =__code_start\n\tasm_vtop tmp\n\tsub\tsize, tmp, vaddr\n\tcbz\tsize, __map_code_section\n\tmov\tpaddr, vaddr\n\tldr\tpte_attr, =BOOTMEM_DATA_ATTR\n\tbl\tbuild_normal_pte_table\n\n\t// map the code section rx\n__map_code_section:\n\tldr\tvaddr, =__code_start\n\tldr\ttmp, =__code_end\n\tsub\tsize, tmp, vaddr\n\tasm_vtop vaddr\n\tmov\tpaddr, vaddr\n\tldr\tpte_attr, =BOOTMEM_CODE_ATTR\n\tbl\tbuild_normal_pte_table\n\n\t// map the init data section rwx, data section will\n\t// be freed after system is bootup\n\tldr\tvaddr, =__init_start\n\tldr\ttmp, =__init_end\n\tsub\tsize, tmp, vaddr\n\tasm_vtop vaddr\n\tmov\tpaddr, vaddr\n\tldr\tpte_attr, =BOOTMEM_INIT_ATTR\n\tbl\tbuild_normal_pte_table\n\n\t// map the data section\n\tldr\tvaddr, =__data_start\n\tldr\ttmp, =__data_end\n\tsub\tsize, tmp, vaddr\n\tasm_vtop vaddr\n\tmov\tpaddr, vaddr\n\tldr\tpte_attr, =BOOTMEM_DATA_ATTR\n\tbl\tbuild_normal_pte_table\n\n\t// map the RO data section like symbol and string\n\t// RO section is the last section in the dts, so the\n\t// the range is from __rodata_start to minos_bootmem_base\n\tldr\tvaddr, =__rodata_start\n\tasm_vtop vaddr\n\tadr\ttmp, minos_bootmem_base\n\tldr\ttmp, [tmp]\n\tsub\tsize, tmp, vaddr\n\tmov\tpaddr, vaddr\n\tldr\tpte_attr, =BOOTMEM_DATA_RO_ATTR\n\tbl\tbuild_normal_pte_table\n\n\t// map the left 4K pages\n\tadr\tvaddr, minos_bootmem_base\n\tldr\tvaddr, [vaddr]\n\tmov\ttmp, vaddr\n\tldr\tentry_mask, =0x1fffff\n\tadd\ttmp, tmp, entry_mask\n\tmvn\tentry_align, entry_mask\n\tand\ttmp, tmp, entry_align\n\tmov\tpaddr, vaddr\n\tsub\tsize, tmp, vaddr\n\tldr\tpte_attr, =BOOTMEM_DATA_ATTR\n\tbl\tbuild_normal_pte_table\n\n\t// map the UART memory for early log rw-device\n\tldr\tvaddr, =CONFIG_UART_BASE\n\tmov\tpaddr, vaddr\n\tldr\tsize, =CONFIG_UART_IO_SIZE\n\tldr\tpte_attr, =BOOTMEM_IO_ATTR\n\tbl\tbuild_io_pte_table\n\n\t// update the pagetable base\n\tadr\tx0, minos_end\n\tstr\tpagetable_base, [x0]\n\n\tret\tx26\n\nbuild_normal_pmd_table:\n\tmov\tx25, x30\n\tldr\tentry_mask, =0x1fffff\n\tldr\tentry_align, =0xffe00000\n\n\tret\tx25\n\nbuild_io_pte_table:\n\tmov\tx25, x30\n\n\tldr\tentry_size, =0x1000\n\tldr\tentry_mask, =0xfff\n\tldr\tentry_align, =0xfffffffffffff000\n\n\t// alloc one page to map 2M IO pmd\n\tmov\tx0, pagetable_base\n\tadd\tpagetable_base, pagetable_base, #4096\n\tmov\tpmd_tmp, x0\n\tmov\tx1, #0\n\tmov\tx2, #4096\n\tbl\tmemset\n\n\t// if the memory region is not in a 2M range ?\n\tadd\tx1, vaddr, size\n\tadd\tx1, x1, entry_mask\n\tand\tx1, x1, entry_align\n\n\tand\tvaddr, vaddr, entry_align\n\tand\tpaddr, paddr, entry_align\n\tsub\tsize, x1, vaddr\n\n\tubfx\tx0, vaddr, #21, #11\n\tldr\tx1, =HOST_TABLE_DES\n\torr\tx1, pmd_tmp, x1\n\tstr\tx1, [ttb0_pud, x0, lsl #3]\n\n\tldr\tentry_align, =0x1fffff\n\tand\tx2, vaddr, entry_align\n\tlsr\tx2, x2, #12\n\torr\tpaddr, paddr, pte_attr\n\nloop_io_pte:\n\tstr\tpaddr, [pmd_tmp, x2, lsl #3]\n\tsub\tsize, size, entry_size\n\tadd\tpaddr, paddr, entry_size\n\tadd\tx2, x2, #1\n\tcbnz\tsize, loop_io_pte\n\tret\tx25\n\nbuild_normal_pte_table:\n\tldr\tentry_size, =0x1000\n\tldr\tentry_mask, =0xfff\n\tldr\tentry_align, =0xfffffffffffff000\n\n\t// the va and pa must page align, so the info\n\t// from lds must correct\n\tand\tvaddr, vaddr, entry_align\n\tand\tpaddr, paddr, entry_align\n\tand\tsize, size, entry_align\n\n\t// get the va offset in bootmem\n\tadr\tx0, minos_start\n\tldr\tx0, [x0]\n\tsub\tx0, vaddr, x0\n\tubfx\tpte_index, x0, #12, #20\n\tmov\tpmd_tmp, ttb0_pmd\n\tadd\tpmd_tmp, pmd_tmp, pte_index, lsl #3\n\n\tbic\tpaddr, paddr, entry_mask\n\tbic\tpaddr, paddr, #0xffff000000000000\n\torr\tpaddr, paddr, pte_attr\n\nloop_normal_pte:\n\tcbz\tsize, exit_loop\n\tstr\tpaddr, [pmd_tmp]\n\tsub\tsize, size, entry_size\n\tadd\tpmd_tmp, pmd_tmp, #8\n\tadd\tpaddr, paddr, entry_size\n\tb\tloop_normal_pte\nexit_loop:\n\tret\n\nbuild_page_table:\n\tmov\tx25, x30\n\n\t// map first 4GB for minos boot memory, here\n\t// need 4 pages\n\tmov\tx3, #4\n\tmov\tttb0_pud, pagetable_base\n\tldr\tx2, =(4096 << 2)\n\tadd\tpagetable_base, pagetable_base, x2\n\tmov\tx0, ttb0_pud\n\tmov\tx1, #0\n\tbl\tmemset\n\n\tmov\tvaddr, #0x0\n\tmov\tentry_size, #4\n\tmov\ttmp, ttb0_pud\n\tmov\tpte_index, 0\n\tldr\tx1, =HOST_TABLE_DES\nloop_pud:\n\torr\tpte_value, tmp, x1\n\tstr\tpte_value, [page_table, pte_index, lsl #3]\n\tadd\tpte_index, pte_index, #1\n\tadd\ttmp, tmp, #0x1000\n\tsub\tentry_size, entry_size, #1\n\tcbnz\tentry_size, loop_pud\n\n\t// count how many memory is mapped as 4K page\n\t// other memory will mapped as PMD block\n\tadr\tvaddr, minos_bootmem_base\n\tldr\tvaddr, [vaddr]\n\tmov\ttmp, vaddr\n\tldr\tentry_mask, =0x1fffff\n\tadd\ttmp, tmp, entry_mask\n\tmvn\tentry_align, entry_mask\n\tand\ttmp, tmp, entry_align\n\tadr\tpte_value, minos_start\n\tldr\tpte_value, [pte_value]\n\n\t// size record the 4K page size\n\t// tmp_const record the 2M block start address\n\tmov\ttmp_const, tmp\n\tsub\tsize, tmp, pte_value\n\n\tlsr\tx3, size, #21\n\tlsl\tx2, x3, #12\n\n\tmov\tttb0_pmd, pagetable_base\n\tadd\tpagetable_base, pagetable_base, x2\n\tmov\tx0, ttb0_pmd\n\tmov\tx1, #0\n\tbl\tmemset\n\n\t// minos_start address 2M align minos_start\n\t// will set at boot stage correctly\n\tadr\tvaddr, minos_start\n\tldr\tvaddr, [vaddr]\n\n\tlsr\tpte_index, vaddr, #21\n\tmov\ttmp, ttb0_pmd\n\tldr\tx1, =HOST_TABLE_DES\nloop_pmd:\n\torr\tpte_value, tmp, x1\n\tstr\tpte_value, [ttb0_pud, pte_index, lsl #3]\n\tadd\tpte_index, pte_index, #1\n\tadd\ttmp, tmp, #4096\n\tsub\tx3, x3, #1\n\tcbnz\tx3, loop_pmd\n\n\t// continue map the pmd block memory\n\tldr\tx2, =CONFIG_MINOS_RAM_SIZE\n\tsub\tsize, x2, size\n\tlsr\tsize, size, #21\n\tldr\tentry_mask, =0x200000\n\n\tmov\tpaddr, tmp_const\n\tldr\tpte_attr, =BOOTMEM_DATA_BLK_ATTR\nloop_pmd_blk:\n\torr\tpte_value, paddr, pte_attr\n\tstr\tpte_value, [ttb0_pud, pte_index, lsl #3]\n\tadd\tpte_index, pte_index, #1\n\tadd\tpaddr, paddr, entry_mask\n\tsub\tsize, size, #1\n\tcbnz\tsize, loop_pmd_blk\n\n\tret\tx25\n"
  },
  {
    "path": "kernel/arch/aarch64/core/stage1.c",
    "content": "/*\n * Copyright (C) 2020 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/mm.h>\n#include <asm/tlb.h>\n#include <asm/cache.h>\n#include \"stage1.h\"\n\n/*\n * 40bit stage1 IPA use 3 levels page table, the pagetable\n * need 2 pages\n */\n#define S1_PGTABLE_LEVELS\t\t3\n#define S1_PAGETABLE_SIZE\t\t4096\n\n#define S1_PGD_SHIFT\t\t\t39\n#define S1_PGD_SIZE\t\t\t(1UL << S1_PGD_SHIFT)\n#define S1_PGD_MASK\t\t\t(~(S1_PGD_SIZE - 1))\n\n#define S1_PUD_SHIFT\t\t\t30\n#define S1_PUD_SIZE\t\t\t(1UL << S1_PUD_SHIFT)\n#define S1_PUD_MASK\t\t\t(~(S1_PUD_SIZE - 1))\n\n#define S1_PMD_SHIFT\t\t\t21\n#define S1_PMD_SIZE\t\t\t(1UL << S1_PMD_SHIFT)\n#define S1_PMD_MASK\t\t\t(~(S1_PMD_SIZE - 1))\n\n#define S1_PTE_SHIFT\t\t\t12\n#define S1_PTE_SIZE\t\t\t(1UL << S1_PTE_SHIFT)\n#define S1_PTE_MASK\t\t\t(~(S1_PTE_SIZE - 1))\n\n#define S1_PHYSICAL_MASK\t\t0x0000fffffffff000UL\n#define S1_PHYSICAL_MAX\t\t\t(1UL << 40)\n#define S1_VIRT_MAX\t\t\t(1UL << 39)\n\n/*\n * The number of PTRS across all concatenated stage1 tables given by the\n * number of bits resolved at the initial level.\n *\n * since we use 3 level pagetable, and translation walk will from pud, the\n * PTRS in one pud is 1024\n */\n#define PTRS_PER_S1_PGD\t\t\t512\n#define PTRS_PER_S1_PUD\t\t\t512\n#define PTRS_PER_S1_PMD\t\t\t512\n#define PTRS_PER_S1_PTE\t\t\t512\n\n#define stage1_pud_value(pudp)\t\t(*(pudp))\n#define stage1_pmd_value(pmdp)\t\t(*(pmdp))\n#define stage1_pte_value(ptep)\t\t(*(ptep))\n\n#define stage1_pgd_index(addr)\t\t(((addr) >> S1_PGD_SHIFT) & (PTRS_PER_S1_PGD - 1))\n#define stage1_pud_index(addr)\t\t(((addr) >> S1_PUD_SHIFT) & (PTRS_PER_S1_PUD - 1))\n#define stage1_pmd_index(addr)\t\t(((addr) >> S1_PMD_SHIFT) & (PTRS_PER_S1_PMD - 1))\n#define stage1_pte_index(addr)\t\t(((addr) >> S1_PTE_SHIFT) & (PTRS_PER_S1_PTE - 1))\n\n#define stage1_pgd_offset(pgdp, addr)\t\t((pgd_t *)(pgdp) + stage1_pgd_index((unsigned long)addr))\n#define stage1_pud_offset(pudp, addr)\t\t((pud_t *)(pudp) + stage1_pud_index((unsigned long)addr))\n#define stage1_pmd_offset(pmdp, addr)\t\t((pmd_t *)(pmdp) + stage1_pmd_index((unsigned long)addr))\n#define stage1_pte_offset(ptep, addr)\t\t((pte_t *)(ptep) + stage1_pte_index((unsigned long)addr))\n\n#define stage1_pud_huge(pud)\t\t\t((pud) && ((pud) & 0x03) == S1_DES_BLOCK)\n#define stage1_pmd_huge(pmd)\t\t\t((pmd) && ((pmd) & 0x03) == S1_DES_BLOCK)\n\n#define stage1_pud_table_addr(pgd)\t\t(pud_t *)(unsigned long)((pgd) & S1_PHYSICAL_MASK)\n#define stage1_pmd_table_addr(pud)\t\t(pmd_t *)(unsigned long)((pud) & S1_PHYSICAL_MASK)\n#define stage1_pte_table_addr(pmd)\t\t(pte_t *)(unsigned long)((pmd) & S1_PHYSICAL_MASK)\n\n#define stage1_pgd_none(pgd)\t\t\t((pgd) == 0)\n#define stage1_pud_none(pud)\t\t\t((pud) == 0)\n#define stage1_pmd_none(pmd)\t\t\t((pmd) == 0)\n#define stage1_pte_none(pte)\t\t\t((pte) == 0)\n\n#define stage1_phy_pte(pte)\t\t\t(void *)((pte) & S1_PHYSICAL_MASK)\n#define stage1_phy_pmd(pmd)\t\t\t(void *)((pmd) & S1_PHYSICAL_MASK)\n\nstatic void inline flush_tlb_va_range(unsigned long va, size_t size)\n{\n\tflush_tlb_va_host(va, size);\n}\n\nstatic inline void flush_dcache_pte(unsigned long addr)\n{\n\tflush_dcache_range(addr, PAGE_SIZE);\n}\n\nstatic inline void flush_dcache_pmd(unsigned long addr)\n{\n\tflush_dcache_range(addr, S1_PMD_SIZE);\n}\n\nstatic void inline stage1_pgd_clear(pud_t *pgdp)\n{\n\tWRITE_ONCE(*pgdp, 0);\n\t__dsb(ishst);\n\tisb();\n}\n\nstatic void inline stage1_pud_clear(pud_t *pudp)\n{\n\tWRITE_ONCE(*pudp, 0);\n\t__dsb(ishst);\n\tisb();\n}\n\nstatic void inline stage1_pmd_clear(pmd_t *pmdp)\n{\n\tWRITE_ONCE(*pmdp, 0);\n\t__dsb(ishst);\n\tisb();\n}\n\nstatic void *stage1_get_free_page(unsigned long flags)\n{\n\treturn get_free_page(GFP_KERNEL);\n}\n\nstatic unsigned long stage1_xxx_addr_end(unsigned long start, unsigned long end, size_t map_size)\n{\n\tunsigned long boundary = (start + map_size) & ~((unsigned long)map_size - 1);\n\n\treturn ((boundary - 1) < (end - 1)) ? boundary : end;\n}\n\n#define stage1_pgd_addr_end(start, end)\t\\\n\tstage1_xxx_addr_end(start, end, S1_PGD_SIZE)\n\n#define stage1_pud_addr_end(start, end)\t\\\n\tstage1_xxx_addr_end(start, end, S1_PUD_SIZE)\n\n#define stage1_pmd_addr_end(start, end)\t\\\n\tstage1_xxx_addr_end(start, end, S1_PMD_SIZE)\n\nstatic inline void stage1_set_pte(pte_t *ptep, pte_t new_pte)\n{\n\tWRITE_ONCE(*ptep, new_pte);\n\t__dsb(ishst);\n}\n\nstatic inline void stage1_set_pmd(pmd_t *pmdp, pmd_t new_pmd)\n{\n\tWRITE_ONCE(*pmdp, new_pmd);\n\t__dsb(ishst);\n}\n\nstatic inline void stage1_set_pud(pud_t *pudp, pud_t new_pud)\n{\n\tWRITE_ONCE(*pudp, new_pud);\n\t__dsb(ishst);\n}\n\nstatic inline void stage1_set_pgd(pgd_t *pgdp, pgd_t new_pgd)\n{\n\tWRITE_ONCE(*pgdp, new_pgd);\n\t__dsb(ishst);\n}\n\nstatic inline void stage1_pgd_populate(pgd_t *pgdp, unsigned long addr, unsigned long flags)\n{\n\tuint64_t attrs = S1_DES_TABLE;\n\n\tif (flags & VM_HOST)\n\t\tattrs |= S1_TABLE_UAP | S1_TABLE_UXN;\n\tstage1_set_pgd(pgdp, vtop(addr) | attrs);\n}\n\nstatic inline void stage1_pud_populate(pud_t *pudp, unsigned long addr, unsigned long flags)\n{\n\tuint64_t attrs = S1_DES_TABLE;\n\n\tif (flags & VM_HOST)\n\t\tattrs |= S1_TABLE_UAP | S1_TABLE_UXN;\n\tstage1_set_pud(pudp, vtop(addr) | attrs);\n}\n\nstatic inline void stage1_pmd_populate(pmd_t *pmdp, unsigned long addr, unsigned long flags)\n{\n\tuint64_t attrs = S1_DES_TABLE;\n\n\tif (flags & VM_HOST)\n\t\tattrs |= S1_TABLE_UAP | S1_TABLE_UXN;\n\tstage1_set_pmd(pmdp, vtop(addr) | attrs);\n}\n\nstatic inline pmd_t stage1_pmd_attr(unsigned long phy, unsigned long flags)\n{\n\tpmd_t pmd = phy & S1_PMD_MASK;\n\n\tswitch (flags & VM_TYPE_MASK) {\n\tcase __VM_NORMAL_NC:\n\t\tpmd |= S1_BLOCK_NORMAL_NC;\n\t\tbreak;\n\tcase __VM_IO:\n\t\tpmd |= S1_BLOCK_DEVICE;\n\t\tbreak;\n\t\tbreak;\n\tcase __VM_WT:\n\t\tpmd |= S1_BLOCK_WT;\n\t\tbreak;\n\tdefault:\n\t\tpmd |= S1_BLOCK_NORMAL;\n\t\tbreak;\n\t}\n\n\tif (flags & __VM_HOST) {\n\t\tif ((flags & VM_RW_MASK) == __VM_RO)\n\t\t\tpmd |= S1_AP_RO;\n\t\telse\n\t\t\tpmd |= S1_AP_RW;\n\t} else {\n\t\tpmd |= S1_nG;\n\t\tif ((flags & VM_RW_MASK) == __VM_RO)\n\t\t\tpmd |= S1_AP_RO_URO;\n\t\telse\n\t\t\tpmd |= S1_AP_RW_URW;\n\t}\n\n\tif (!(flags & __VM_EXEC))\n\t\tpmd |= (S1_XN | S1_PXN);\n\n\tif (flags & __VM_PFNMAP)\n\t\tpmd |= S1_PFNMAP;\n\n\tif (flags & __VM_DEVMAP)\n\t\tpmd |= S1_DEVMAP;\n\n\tif (flags & (__VM_SHARED | __VM_PMA))\n\t\tpmd |= S1_SHARED;\n\n\treturn pmd;\n}\n\nstatic inline pte_t stage1_pte_attr(unsigned long phy, unsigned long flags)\n{\n\tpte_t pte = phy & S1_PTE_MASK;\n\n\tswitch (flags & VM_TYPE_MASK) {\n\tcase __VM_NORMAL_NC:\n\t\tpte |= S1_PAGE_NORMAL_NC;\n\t\tbreak;\n\tcase __VM_IO:\n\t\tpte |= S1_PAGE_DEVICE;\n\t\tbreak;\n\tcase __VM_WT:\n\t\tpte |= S1_PAGE_WT;\n\t\tbreak;\n\tdefault:\n\t\tpte |= S1_PAGE_NORMAL;\n\t\tbreak;\n\t}\n\n\tif (flags & __VM_HOST) {\n\t\tif ((flags & VM_RW_MASK) == __VM_RO)\n\t\t\tpte |= S1_AP_RO;\n\t\telse\n\t\t\tpte |= S1_AP_RW;\n\t} else {\n\t\tpte |= S1_nG;\n\t\tif ((flags & VM_RW_MASK) == __VM_RO)\n\t\t\tpte |= S1_AP_RO_URO;\n\t\telse\n\t\t\tpte |= S1_AP_RW_URW;\n\t}\n\n\tif (!(flags & __VM_EXEC))\n\t\tpte |= (S1_XN | S1_PXN);\n\n\tif (flags & __VM_PFNMAP)\n\t\tpte |= S1_PFNMAP;\n\n\tif (flags & __VM_DEVMAP)\n\t\tpte |= S1_DEVMAP;\n\n\tif (flags & (__VM_SHARED | __VM_PMA))\n\t\tpte |= S1_SHARED;\n\n\treturn pte;\n}\n\nstatic void add_release_page(struct vspace *vs, unsigned long addr)\n{\n\tstruct page *page = addr_to_page(addr);\n\n\tASSERT(page != NULL);\n\tpage->next = vs->release_pages;\n\tvs->release_pages = page;\n}\n\nstatic void stage1_unmap_pte_range(struct vspace *vs, pte_t *ptep,\n\t\tunsigned long addr, unsigned long end, int flags)\n{\n\tpte_t *pte;\n\n\tpte = stage1_pte_offset(ptep, addr);\n\n\tdo {\n\t\tif (!stage1_pte_none(*pte)) {\n\t\t\tpte_t old_pte = *pte;\n\t\t\tstage1_set_pte(pte, 0);\n\n\t\t\t/* pfnmap and shared page don not free the page */\n\t\t\tif (!(old_pte & S1_PFNMAP) && !(old_pte & S1_SHARED))\n\t\t\t\tadd_release_page(vs, ptov(stage1_phy_pte(old_pte)));\n\t\t}\n\t} while (pte++, addr += PAGE_SIZE, addr != end);\n}\n\nstatic void stage1_unmap_pmd_range(struct vspace *vs, pmd_t *pmdp,\n\t\tunsigned long addr, unsigned long end, int flags)\n{\n\tunsigned long next;\n\tpmd_t *pmd;\n\tpte_t *ptep;\n\n\tpmd = stage1_pmd_offset(pmdp, addr);\n\n\tdo {\n\t\tnext = stage1_pmd_addr_end(addr, end);\n\t\tif (!stage1_pmd_none(*pmd)) {\n\t\t\tif (stage1_pmd_huge(*pmd)) {\n\t\t\t\tpmd_t old_pmd = *pmd;\n\t\t\t\tstage1_pmd_clear(pmd);\n\t\t\t\tif (!(old_pmd & S1_PFNMAP) && !(old_pmd & S1_SHARED))\n\t\t\t\t\tadd_release_page(vs, ptov(stage1_phy_pte(old_pmd)));\n\t\t\t} else {\n\t\t\t\tptep = (pte_t *)ptov(stage1_pte_table_addr(*pmd));\n\t\t\t\tstage1_unmap_pte_range(vs, ptep, addr, next, flags);\n\t\t\t\tif (next - addr == S1_PMD_SIZE)\n\t\t\t\t\tadd_release_page(vs, (unsigned long)ptep);\n\t\t\t}\n\t\t}\n\t} while (pmd++, addr = next, addr != end);\n}\n\nstatic int stage1_unmap_pud_range(struct vspace *vs,\n\t\tunsigned long addr, unsigned long end, int flags)\n{\n\tunsigned long next;\n\tpud_t *pud;\n\tpmd_t *pmdp;\n\n\tpud = stage1_pud_offset((pud_t *)vs->pgdp, end);\n\tdo {\n\t\tnext = stage1_pud_addr_end(addr, end);\n\t\tif (!stage1_pud_none(*pud)) {\n\t\t\tpmdp = (pmd_t *)ptov(stage1_pmd_table_addr(*pud));\n\t\t\tstage1_unmap_pmd_range(vs, pmdp, addr, next, flags);\n\t\t\tif (next - addr == S1_PUD_SIZE)\n\t\t\t\tadd_release_page(vs, (unsigned long)pmdp);\n\t\t}\n\t} while (pud++, addr = next, addr != end);\n\n\tflush_tlb_asid_all(vs->asid);\n\n\tif (vs->notifier_ops && vs->notifier_ops->unmap_range)\n\t\tvs->notifier_ops->unmap_range(vs, addr, end, flags);\n\n\treturn 0;\n}\n\nstatic int stage1_map_pte_range(struct vspace *vs, pte_t *ptep, unsigned long start,\n\t\tunsigned long end, unsigned long physical, unsigned long flags)\n{\n\tunsigned long pte_attr;\n\tpte_t *pte;\n\tpte_t old_pte;\n\n\tpte = stage1_pte_offset(ptep, start);\n\tpte_attr = stage1_pte_attr(0, flags);\n\n\tdo {\n\t\told_pte = *pte;\n\t\tif (old_pte)\n\t\t\tpr_err(\"error: pte remaped 0x%x\\n\", start);\n\t\tstage1_set_pte(pte, pte_attr | physical);\n\t} while (pte++, start += PAGE_SIZE, physical += PAGE_SIZE, start != end);\n\n\treturn 0;\n}\n\nstatic inline bool stage1_pmd_huge_page(pmd_t old_pmd, unsigned long start,\n\t\tunsigned long phy, size_t size, unsigned long flags)\n{\n\tif (!(flags & __VM_HUGE_2M) || old_pmd)\n\t\treturn false;\n\n\tif (!IS_BLOCK_ALIGN(start) || !IS_BLOCK_ALIGN(phy) || !(IS_BLOCK_ALIGN(size)))\n\t\treturn false;\n\n\treturn true;\n}\n\nstatic int stage1_map_pmd_range(struct vspace *vs, pmd_t *pmdp, unsigned long start,\n\t\tunsigned long end, unsigned long physical, unsigned long flags)\n{\n\tunsigned long next;\n\tunsigned long attr;\n\tpmd_t *pmd;\n\tpmd_t old_pmd;\n\tpte_t *ptep;\n\tsize_t size;\n\tint ret;\n\n\tpmd = stage1_pmd_offset(pmdp, start);\n\tdo {\n\t\tnext = stage1_pmd_addr_end(start, end);\n\t\tsize = next - start;\n\t\told_pmd = *pmd;\n\n\t\t/*\n\t\t * virtual memory need to map as PMD huge page\n\t\t */\n\t\tif (stage1_pmd_huge_page(old_pmd, start, physical, size, flags)) {\n\t\t\tattr = stage1_pmd_attr(physical, flags);\n\t\t\tstage1_set_pmd(pmd, attr);\n\t\t} else {\n\t\t\tif (stage1_pmd_none(old_pmd)) {\n\t\t\t\tptep = (pte_t *)stage1_get_free_page(flags);\n\t\t\t\tif (!ptep)\n\t\t\t\t\treturn -ENOMEM;\n\t\t\t\tmemset(ptep, 0, PAGE_SIZE);\n\t\t\t\tstage1_pmd_populate(pmd, (unsigned long)ptep, flags);\n\t\t\t} else {\n\t\t\t\tptep = (pte_t *)ptov(stage1_pte_table_addr(old_pmd));\n\t\t\t}\n\n\t\t\tret = stage1_map_pte_range(vs, ptep, start, next, physical, flags);\n\t\t\tif (ret)\n\t\t\t\treturn ret;\n\t\t}\n\t} while (pmd++, physical += size, start = next, start != end);\n\n\treturn 0;\n}\n\nstatic int stage1_map_pud_range(struct vspace *vs, unsigned long start,\n\t\tunsigned long end, unsigned long physical, unsigned long flags)\n{\n\tunsigned long next;\n\tpud_t *pud;\n\tpmd_t *pmdp;\n\tsize_t size;\n\tint ret;\n\n\tpud = stage1_pud_offset((pud_t *)vs->pgdp, start);\n\tdo {\n\t\tnext = stage1_pud_addr_end(start, end);\n\t\tsize = next - start;\n\n\t\tif (stage1_pud_none(*pud)) {\n\t\t\tpmdp = (pmd_t *)stage1_get_free_page(flags);\n\t\t\tif (!pmdp)\n\t\t\t\treturn -ENOMEM;\n\t\t\tmemset(pmdp, 0, PAGE_SIZE);\n\t\t\tstage1_pud_populate(pud, (unsigned long)pmdp, flags);\n\t\t} else {\n\t\t\tpmdp = (pmd_t *)ptov(stage1_pmd_table_addr(*pud));\n\t\t}\n\n\t\tret = stage1_map_pmd_range(vs, pmdp, start, next, physical, flags);\n\t\tif (ret)\n\t\t\treturn ret;\n\t} while (pud++, physical += size, start = next, start != end);\n\n\treturn 0;\n}\n\nstatic int stage1_get_leaf_entry(struct vspace *vs,\n\t\tunsigned long va, pmd_t **pmdpp, pte_t **ptepp)\n{\n\tpud_t *pudp;\n\tpmd_t *pmdp;\n\tpte_t *ptep;\n\n\tpudp = stage1_pud_offset(vs->pgdp, va);\n\tif (stage1_pud_none(*pudp))\n\t\treturn -ENOMEM;\n\n\tpmdp = stage1_pmd_offset(stage1_pmd_table_addr(*pudp), va);\n\tif (stage1_pmd_none(*pmdp))\n\t\treturn -ENOMEM;\n\n\tif (stage1_pmd_huge(*pmdp)) {\n\t\t*pmdpp = pmdp;\n\t\treturn 0;\n\t}\n\n\tptep = stage1_pte_offset(stage1_pte_table_addr(*pmdp), va);\n\t*ptepp = ptep;\n\n\treturn 0;\n}\n\nint arch_host_change_map(struct vspace *vs, unsigned long vir,\n\t\tunsigned long phy, unsigned long flags)\n{\n\tint ret;\n\tpmd_t *pmdp = NULL;\n\tpte_t *ptep = NULL;\n\n\tret = stage1_get_leaf_entry(vs, vir, &pmdp, &ptep);\n\tif (ret)\n\t\treturn ret;\n\n\tif (pmdp) {\n\t\tstage1_set_pmd(pmdp, 0);\n\t\tflush_tlb_va_range(vir, S1_PMD_SIZE);\n\t\tstage1_set_pmd(pmdp, stage1_pmd_attr(phy, flags));\n\t\treturn 0;\n\t}\n\n\tstage1_set_pte(ptep, 0);\n\tflush_tlb_va_range(vir, S1_PTE_SIZE);\n\tstage1_set_pte(ptep, stage1_pte_attr(phy, flags));\n\n\treturn 0;\n}\n\nstatic inline phy_addr_t stage1_va_to_pa(struct vspace *vs, unsigned long va)\n{\n\tunsigned long pte_offset = va & ~S1_PTE_MASK;\n\tunsigned long pmd_offset = va & ~S1_PMD_MASK;\n\tunsigned long phy = 0;\n\tpud_t *pudp;\n\tpmd_t *pmdp;\n\tpte_t *ptep;\n\n\tpudp = stage1_pud_offset(vs->pgdp, va);\n\tif (stage1_pud_none(*pudp))\n\t\treturn 0;\n\n\tpmdp = stage1_pmd_offset(ptov(stage1_pmd_table_addr(*pudp)), va);\n\tif (stage1_pmd_none(*pmdp))\n\t\treturn 0;\n\n\tif (stage1_pmd_huge(*pmdp)) {\n\t\tphy = ((*pmdp) & S1_PHYSICAL_MASK) + pmd_offset;\n\t\treturn 0;\n\t}\n\n\tptep = stage1_pte_offset(ptov(stage1_pte_table_addr(*pmdp)), va);\n\tphy = *ptep & S1_PHYSICAL_MASK;\n\tif (phy == 0)\n\t\treturn 0;\n\n\treturn phy + pte_offset;\n}\n\nphy_addr_t arch_translate_va_to_pa(struct vspace *vs, unsigned long va)\n{\n\treturn stage1_va_to_pa(vs, va);\n}\n\nint arch_host_map(struct vspace *vs, unsigned long start, unsigned long end,\n\t\tunsigned long physical, unsigned long flags)\n{\n\tif (end == start)\n\t\treturn -EINVAL;\n\n\tASSERT((start < S1_VIRT_MAX) && (end <= S1_VIRT_MAX));\n\tASSERT(physical < S1_PHYSICAL_MAX);\n\tASSERT(IS_PAGE_ALIGN(start) && IS_PAGE_ALIGN(end) && IS_PAGE_ALIGN(physical));\n\n\treturn stage1_map_pud_range(vs, start, end, physical, flags);\n}\n\nint arch_host_unmap(struct vspace *vs, unsigned long start, unsigned long end, int mode)\n{\n\tASSERT((start < S1_VIRT_MAX) && (end <= S1_VIRT_MAX));\n\treturn stage1_unmap_pud_range(vs, start, end, mode);\n}\n\nunsigned long arch_kernel_pgd_base(void)\n{\n\textern unsigned char __stage1_page_table;\n\n\treturn (unsigned long)&__stage1_page_table;\n}\n"
  },
  {
    "path": "kernel/arch/aarch64/core/stage1.h",
    "content": "#ifndef __MINOS_ARM64_STAGE1_H__\n#define __MINOS_ARM64_STAGE1_H__\n\n#include <minos/const.h>\n\n/*\n * stage 1 VMSAv8-64 Table Descriptors\n */\n#define S1_DES_FAULT\t\t(0b00 << 0)\n#define S1_DES_BLOCK\t\t(0b01 << 0)\t/* level 1/2 */\n#define S1_DES_TABLE\t\t(0b11 << 0)\t/* level 0/1/2 */\n#define S1_DES_PAGE\t\t(0b11 << 0)\t/* level 3 */\n\n#define S1_TABLE_NS\t\t(UL(1) << 63)\n#define S1_TABLE_AP\t\t(0)\n#define S1_TABLE_XN\t\t(UL(1) << 60)\n\n#define S1_TABLE_UAP\t\t(UL(1) << 61)\n#define S1_TABLE_UXN\t\t(UL(1) << 60)\n\n#define S1_CONTIGUOUS\t\t(UL(1) << 52)\n#define S1_PXN\t\t\t(UL(1) << 53)\n#define S1_XN\t\t\t(UL(1) << 54)\n\n#define S1_PFNMAP\t\t(UL(1) << 55)\t// 55 - 58 is for software\n#define S1_DEVMAP\t\t(UL(1) << 56)\t// 55 - 58 is for software\n#define S1_SHARED\t\t(UL(1) << 57)\t// 55 - 58 is for software\n\n#define S1_NS\t\t\t(1 << 5)\n\n#define S1_AP_RW\t\t(0b00 << 6)\t// for EL2 ap[2] is valid\n#define S1_AP_RW_URW\t\t(0b01 << 6)\n#define S1_AP_RO\t\t(0b10 << 6)\n#define S1_AP_RO_URO\t\t(0b11 << 6)\n\n#define S1_SH_NON\t\t(0b00 << 8)\n#define S1_SH_OUTER\t\t(0b10 << 8)\n#define S1_SH_INNER\t\t(0b11 << 8)\n\n#define S1_AF\t\t\t(1 << 10)\n#define S1_nG\t\t\t(1 << 11)\n\n#define S1_ATTR_IDX(n)\t\t((n & 0xf) << 2)\n\n#define MT_DEVICE_nGnRnE\t0\n#define MT_DEVICE_nGnRE\t\t1\n#define MT_DEVICE_GRE\t\t2\n#define MT_NORMAL_NC\t\t3\n#define MT_NORMAL\t\t4\n#define MT_NORMAL_WT\t\t5\n\n#define S1_PAGE_NORMAL\t\t(S1_DES_PAGE | S1_AF | S1_NS | S1_SH_INNER | S1_ATTR_IDX(MT_NORMAL))\n#define S1_PAGE_NC\t\t(S1_DES_PAGE | S1_AF | S1_NS | S1_SH_INNER | S1_ATTR_IDX(MT_DEVICE_nGnRE))\n#define S1_PAGE_DEVICE\t\t(S1_DES_PAGE | S1_AF | S1_NS | S1_SH_INNER | S1_ATTR_IDX(MT_DEVICE_nGnRnE))\n#define S1_PAGE_NORMAL_NC\t(S1_DES_PAGE | S1_AF | S1_NS | S1_SH_INNER | S1_ATTR_IDX(MT_NORMAL_NC))\n#define S1_PAGE_WT\t\t(S1_DES_PAGE | S1_AF | S1_NS | S1_SH_INNER | S1_ATTR_IDX(MT_NORMAL_WT))\n\n#define S1_BLOCK_NORMAL\t\t(S1_DES_BLOCK | S1_AF | S1_NS | S1_SH_INNER | S1_ATTR_IDX(MT_NORMAL))\n#define S1_BLOCK_NC\t\t(S1_DES_BLOCK | S1_AF | S1_NS | S1_SH_INNER | S1_ATTR_IDX(MT_DEVICE_nGnRE))\n#define S1_BLOCK_DEVICE\t\t(S1_DES_BLOCK | S1_AF | S1_NS | S1_SH_INNER | S1_ATTR_IDX(MT_DEVICE_nGnRnE))\n#define S1_BLOCK_NORMAL_NC\t(S1_DES_BLOCK | S1_AF | S1_NS | S1_SH_INNER | S1_ATTR_IDX(MT_NORMAL_NC))\n#define S1_BLOCK_WT\t\t(S1_DES_BLOCK | S1_AF | S1_NS | S1_SH_INNER | S1_ATTR_IDX(MT_NORMAL_WT))\n\n#define BOOTMEM_CODE_ATTR\t(S1_ATTR_IDX(MT_NORMAL) | S1_DES_PAGE | S1_NS | S1_AP_RO | S1_SH_INNER | S1_AF | S1_XN)\n#define BOOTMEM_DATA_ATTR\t(S1_ATTR_IDX(MT_NORMAL) | S1_DES_PAGE | S1_NS | S1_AP_RW | S1_SH_INNER | S1_AF | S1_XN | S1_PXN)\n#define BOOTMEM_DATA_RO_ATTR\t(S1_ATTR_IDX(MT_NORMAL) | S1_DES_PAGE | S1_NS | S1_AP_RO | S1_SH_INNER | S1_AF | S1_XN | S1_PXN)\n#define BOOTMEM_INIT_ATTR\t(S1_ATTR_IDX(MT_NORMAL) | S1_DES_PAGE | S1_NS | S1_AP_RW | S1_SH_INNER | S1_AF | S1_XN)\n#define BOOTMEM_IO_ATTR\t\t(S1_ATTR_IDX(MT_DEVICE_nGnRnE) | S1_DES_PAGE | S1_NS | S1_AP_RW | S1_SH_INNER | S1_AF | S1_XN | S1_PXN)\n#define BOOTMEM_DATA_BLK_ATTR\t(S1_ATTR_IDX(MT_NORMAL) | S1_DES_BLOCK | S1_NS | S1_AP_RW | S1_SH_INNER | S1_AF | S1_XN | S1_PXN)\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/core/vector.S",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/aarch64_common.h>\n#include <config/config.h>\n#include <asm/asm-offset.h>\n#include <asm/aarch64_reg.h>\n#include <minos/task_info.h>\n\n\t.section __elx_vectors, \"ax\"\n\t.balign 8\n\n.macro vfunc name\n\t.global \\name\n\t.type \\name \"function\"\n\t.cfi_startproc\n\t\\name:\n.endm\n\n.macro vfunc_end name\n\t.cfi_endproc\n.endm\n\n// ARM64_TPIDR will store the pcpu data\n// x18 will store the current_task\n.macro PCPU_SAVE_CURRENT_TASK tmp0\n\tmrs\t\\tmp0, ARM64_TPIDR\n\tstr\tx18, [\\tmp0, #PCPU_CURRENT_TASK]\n.endm\n\n.macro PCPU_LOAD_CURRENT_TASK\n\tmrs\tx18, ARM64_TPIDR\n\tldr\tx18, [x18, #PCPU_CURRENT_TASK]\n.endm\n\n.macro LOAD_PCPU_STACK, tmp0\n\tmrs\t\\tmp0, ARM64_TPIDR\n\tldr\t\\tmp0, [\\tmp0, #PCPU_STACK_OFFSET]\n\tmov\tsp, \\tmp0\n.endm\n\n.macro __SAVE_GP_REGS\n\tstp\tx27, x28, [sp, #-16]!\n\tstp\tx25, x26, [sp, #-16]!\n\tstp\tx23, x24, [sp, #-16]!\n\tstp\tx21, x22, [sp, #-16]!\n\tstp\tx19, x20, [sp, #-16]!\n\tstp\tx17, x18, [sp, #-16]!\n\tstp     x15, x16, [sp, #-16]!\n\tstp     x13, x14, [sp, #-16]!\n\tstp     x11, x12, [sp, #-16]!\n\tstp     x9, x10, [sp, #-16]!\n\tstp     x7, x8, [sp, #-16]!\n\tstp     x5, x6, [sp, #-16]!\n\tstp     x3, x4, [sp, #-16]!\n\tstp     x1, x2, [sp, #-16]!\n\tstr\tx0, [sp, #-8]!\n\tmrs\tx0, SP_EL0\n\tstr\tx0, [sp, #-8]!\n\tmrs\tx0, ARM64_SPSR\n\tstr\tx0, [sp, #-8]!\n\tmrs\tx0, ARM64_ELR\n\tstr\tx0, [sp, #-8]!\n\tdsb\tnsh\n.endm\n\n.macro SAVE_GP_REGS\n\tstp\tx29, x30, [sp, #-16]!\n\t__SAVE_GP_REGS\n.endm\n\n.macro LOAD_GP_REGS\n\tldr\tx0, [sp], #8\t\t\t// restore task context\n\tmsr\tARM64_ELR, x0\n\tldr\tx0, [sp], #8\n\tmsr\tARM64_SPSR, x0\n\tldr\tx0, [sp], #8\n\tmsr\tSP_EL0, x0\n\tldp     x0, x1, [sp], #16\n\tldp     x2, x3, [sp], #16\n\tldp     x4, x5, [sp], #16\n\tldp     x6, x7, [sp], #16\n\tldp     x8, x9, [sp], #16\n\tldp     x10, x11, [sp], #16\n\tldp     x12, x13, [sp], #16\n\tldp     x14, x15, [sp], #16\n\tldp     x16, x17, [sp], #16\n\tldp     x18, x19, [sp], #16\n\tldp     x20, x21, [sp], #16\n\tldp     x22, x23, [sp], #16\n\tldp     x24, x25, [sp], #16\n\tldp     x26, x27, [sp], #16\n\tldp     x28, x29, [sp], #16\n\tldr\tx30, [sp], #8\n\tdsb\tnsh\n.endm\n\nvfunc __bad_mode\n\t__SAVE_GP_REGS\n\tmov\tx0, sp\n\tmov\tx1, x29\n\tb\tbad_mode\t/* will never return */\nlb:\n\tb\tlb\nvfunc_end __bad_mode\n\nvfunc exception_return\n\tLOAD_PCPU_STACK x1\t\t\t// load percpu stack, need ensure the irq is off.\n\n\tbl\texception_return_handler\t// check whether need to resched. x18 will the next task.\n\n\tldr\tx1, [x18, #TASK_STACK_OFFSET]\t// load the running task's stack\n\tmov\tsp, x1\t\t\t\t// change to the new stack address\n\n\tldr\tx1, [sp, #8]\t\t\t// load spsr\n\tand\tx1, x1, #0x0f\n\tcmp\tx1, #ARM64_SPSR_KERNEL\t\t// whether the task will return to user\n\tb.eq\t__do_exception_return\n\n\tmov\tx0, sp\n\tbl\ttask_return_to_user\n\tstr\txzr, [x18, #TASK_USER_REGS_OFFSET] // clear the user_regs for task\n\n__do_exception_return:\n\tLOAD_GP_REGS\n\teret\nvfunc_end exception_return\n\nvfunc __sync_exception_from_current_el\n\tSAVE_GP_REGS\n\n\tmov\tx0, sp\n\tstr\tx0, [x18, #TASK_STACK_OFFSET]\n\n\t// use SVC for sched() , other type will\n\t// go to the exception handler.\n\tmrs\tx1, ARM64_ESR\n\tubfx\tx2, x1, #ESR_ELx_EC_SHIFT, #ESR_ELx_EC_WIDTH\n\tcmp\tx2, #ESR_ELx_EC_SVC64\n\tb.eq\t__sync_current_out\n\n\tbl\tsync_exception_from_current_el\t\t// go to the c handler, will die.\n\n__sync_current_out:\n\tb\texception_return\nvfunc_end __sync_exception_from_current_el\n\nvfunc __sync_exception_from_lower_el\n\tSAVE_GP_REGS\n\n\tPCPU_LOAD_CURRENT_TASK\t\t\t\t// x18 will be the current task.\n\n\tbl\ttask_exit_from_user\n\n\tmov\tx0, sp\n\tstr\tx0, [x18, #TASK_USER_REGS_OFFSET]\t// save the user_regs to task\n\n\tbl\tsync_exception_from_lower_el\t\t// go to the c handler.\n\n\tmov\tx0, sp\n\tbl      task_return_to_user\n\n\tLOAD_GP_REGS\n\teret\nvfunc_end __sync_exception_from_lower_el\n\nvfunc __irq_exception_from_lower_el\n\tSAVE_GP_REGS\n\n\tPCPU_LOAD_CURRENT_TASK\t\t\t\t// x18 will store the current task\n\n\t// Set the irq flags into ti->flags.\n\tldr\tx1, [x18, #TASK_INFO_FLAGS_OFFSET]\n\torr\tx1, x1, #__TIF_HARDIRQ_MASK\n\tstr\tx1, [x18, #TASK_INFO_FLAGS_OFFSET]\n\tdsb\tsy\n\n\tmov\tx0, sp\t\t\t\t\t// x0 is the gp_regs pass to irq_c_handler\n\tstr\tx0, [x18, #TASK_STACK_OFFSET]\t\t// save the current task's stack to task\n\tstr\tx0, [x18, #TASK_USER_REGS_OFFSET]\t// save the user_regs to task\n\n\tbl\ttask_exit_from_user\n\n\tmov\tx0, sp\n\tbl\tirq_from_lower_el\t\t\t// call the c irq handler\n\n\t// clear the irq flags into ti->flags.\n\tldr\tx1, [x18, #TASK_INFO_FLAGS_OFFSET]\n\tand\tx1, x1, #(~__TIF_HARDIRQ_MASK)\n\tstr\tx1, [x18, #TASK_INFO_FLAGS_OFFSET]\n\tdsb\tsy\n\n\tb\texception_return\nvfunc_end __irq_exception_from_lower_el\n\nvfunc __irq_exception_from_current_el\n\tSAVE_GP_REGS\n\n\t// Set the irq flags into ti->flags.\n\tldr\tx1, [x18, #TASK_INFO_FLAGS_OFFSET]\n\torr\tx1, x1, #__TIF_HARDIRQ_MASK\n\tstr\tx1, [x18, #TASK_INFO_FLAGS_OFFSET]\n\tdsb\tsy\n\n\tmov\tx0, sp\n\tstr     x0, [x18, #TASK_STACK_OFFSET]\t// store the stack in case this task will scheded out.\n\tbl\tirq_from_current_el\t\t// irq is disabled all the time\n\n\t// clear the irq flags into ti->flags.\n\tldr\tx1, [x18, #TASK_INFO_FLAGS_OFFSET]\n\tand\tx1, x1, #(~__TIF_HARDIRQ_MASK)\n\tstr\tx1, [x18, #TASK_INFO_FLAGS_OFFSET]\n\tdsb\tsy\n\n\tb\texception_return\nvfunc_end __irq_exception_from\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/aarch64_common.h",
    "content": "#ifndef _MINOS_AARCH64_COMMON_H_\n#define _MINOS_AARCH64_COMMON_H_\n\n#include <minos/const.h>\n\n#define ESR_ELx_EC_UNKNOWN\t(0x00)\n#define ESR_ELx_EC_WFx\t\t(0x01)\n/* Unallocated EC: 0x02 */\n#define ESR_ELx_EC_CP15_32\t(0x03)\n#define ESR_ELx_EC_CP15_64\t(0x04)\n#define ESR_ELx_EC_CP14_MR\t(0x05)\n#define ESR_ELx_EC_CP14_LS\t(0x06)\n#define ESR_ELx_EC_FP_ASIMD\t(0x07)\n#define ESR_ELx_EC_CP10_ID\t(0x08)\n/* Unallocated EC: 0x09 - 0x0B */\n#define ESR_ELx_EC_CP14_64\t(0x0C)\n/* Unallocated EC: 0x0d */\n#define ESR_ELx_EC_ILL\t\t(0x0E)\n/* Unallocated EC: 0x0F - 0x10 */\n#define ESR_ELx_EC_SVC32\t(0x11)\n#define ESR_ELx_EC_HVC32\t(0x12)\n#define ESR_ELx_EC_SMC32\t(0x13)\n/* Unallocated EC: 0x14 */\n#define ESR_ELx_EC_SVC64\t(0x15)\n#define ESR_ELx_EC_HVC64\t(0x16)\n#define ESR_ELx_EC_SMC64\t(0x17)\n#define ESR_ELx_EC_SYS64\t(0x18)\n#define ESR_ELx_EC_SVE\t\t(0x19)\n/* Unallocated EC: 0x1A - 0x1E */\n#define ESR_ELx_EC_IMP_DEF\t(0x1f)\n#define ESR_ELx_EC_IABT_LOW\t(0x20)\n#define ESR_ELx_EC_IABT_CUR\t(0x21)\n#define ESR_ELx_EC_PC_ALIGN\t(0x22)\n/* Unallocated EC: 0x23 */\n#define ESR_ELx_EC_DABT_LOW\t(0x24)\n#define ESR_ELx_EC_DABT_CUR\t(0x25)\n#define ESR_ELx_EC_SP_ALIGN\t(0x26)\n/* Unallocated EC: 0x27 */\n#define ESR_ELx_EC_FP_EXC32\t(0x28)\n/* Unallocated EC: 0x29 - 0x2B */\n#define ESR_ELx_EC_FP_EXC64\t(0x2C)\n/* Unallocated EC: 0x2D - 0x2E */\n#define ESR_ELx_EC_SERROR\t(0x2F)\n#define ESR_ELx_EC_BREAKPT_LOW\t(0x30)\n#define ESR_ELx_EC_BREAKPT_CUR\t(0x31)\n#define ESR_ELx_EC_SOFTSTP_LOW\t(0x32)\n#define ESR_ELx_EC_SOFTSTP_CUR\t(0x33)\n#define ESR_ELx_EC_WATCHPT_LOW\t(0x34)\n#define ESR_ELx_EC_WATCHPT_CUR\t(0x35)\n/* Unallocated EC: 0x36 - 0x37 */\n#define ESR_ELx_EC_BKPT32\t(0x38)\n/* Unallocated EC: 0x39 */\n#define ESR_ELx_EC_VECTOR32\t(0x3A)\n/* Unallocted EC: 0x3B */\n#define ESR_ELx_EC_BRK64\t(0x3C)\n/* Unallocated EC: 0x3D - 0x3F */\n#define ESR_ELx_EC_MAX\t\t(0x3F)\n\n#define ESR_ELx_EC_SHIFT\t(26)\n#define ESR_ELx_EC_WIDTH\t(6)\n#define ESR_ELx_EC_MASK\t\t(ULONG(0x3F) << ESR_ELx_EC_SHIFT)\n#define ESR_ELx_EC(esr)\t\t(((esr) & ESR_ELx_EC_MASK) >> ESR_ELx_EC_SHIFT)\n\n#define ESR_ELx_IL_SHIFT\t(25)\n#define ESR_ELx_IL\t\t(ULONG(1) << ESR_ELx_IL_SHIFT)\n#define ESR_ELx_ISS_MASK\t(ESR_ELx_IL - 1)\n\n/* ISS field definitions shared by different classes */\n#define ESR_ELx_WNR_SHIFT\t(6)\n#define ESR_ELx_WNR\t\t(ULONG(1) << ESR_ELx_WNR_SHIFT)\n\n/* Asynchronous Error Type */\n#define ESR_ELx_IDS_SHIFT\t(24)\n#define ESR_ELx_IDS\t\t(ULONG(1) << ESR_ELx_IDS_SHIFT)\n#define ESR_ELx_AET_SHIFT\t(10)\n#define ESR_ELx_AET\t\t(ULONG(0x7) << ESR_ELx_AET_SHIFT)\n\n#define ESR_ELx_AET_UC\t\t(ULONG(0) << ESR_ELx_AET_SHIFT)\n#define ESR_ELx_AET_UEU\t\t(ULONG(1) << ESR_ELx_AET_SHIFT)\n#define ESR_ELx_AET_UEO\t\t(ULONG(2) << ESR_ELx_AET_SHIFT)\n#define ESR_ELx_AET_UER\t\t(ULONG(3) << ESR_ELx_AET_SHIFT)\n#define ESR_ELx_AET_CE\t\t(ULONG(6) << ESR_ELx_AET_SHIFT)\n\n/* Shared ISS field definitions for Data/Instruction aborts */\n#define ESR_ELx_SET_SHIFT\t(11)\n#define ESR_ELx_SET_MASK\t(ULONG(3) << ESR_ELx_SET_SHIFT)\n#define ESR_ELx_FnV_SHIFT\t(10)\n#define ESR_ELx_FnV\t\t(ULONG(1) << ESR_ELx_FnV_SHIFT)\n#define ESR_ELx_EA_SHIFT\t(9)\n#define ESR_ELx_EA\t\t(ULONG(1) << ESR_ELx_EA_SHIFT)\n#define ESR_ELx_S1PTW_SHIFT\t(7)\n#define ESR_ELx_S1PTW\t\t(ULONG(1) << ESR_ELx_S1PTW_SHIFT)\n\n/* Shared ISS fault status code(IFSC/DFSC) for Data/Instruction aborts */\n#define ESR_ELx_FSC\t\t(0x3F)\n#define ESR_ELx_FSC_TYPE\t(0x3C)\n#define ESR_ELx_FSC_EXTABT\t(0x10)\n#define ESR_ELx_FSC_SERROR\t(0x11)\n#define ESR_ELx_FSC_ACCESS\t(0x08)\n#define ESR_ELx_FSC_FAULT\t(0x04)\n#define ESR_ELx_FSC_PERM\t(0x0C)\n\n/* ISS field definitions for Data Aborts */\n#define ESR_ELx_ISV_SHIFT\t(24)\n#define ESR_ELx_ISV\t\t(ULONG(1) << ESR_ELx_ISV_SHIFT)\n#define ESR_ELx_SAS_SHIFT\t(22)\n#define ESR_ELx_SAS\t\t(ULONG(3) << ESR_ELx_SAS_SHIFT)\n#define ESR_ELx_SSE_SHIFT\t(21)\n#define ESR_ELx_SSE\t\t(ULONG(1) << ESR_ELx_SSE_SHIFT)\n#define ESR_ELx_SRT_SHIFT\t(16)\n#define ESR_ELx_SRT_MASK\t(ULONG(0x1F) << ESR_ELx_SRT_SHIFT)\n#define ESR_ELx_SRT(val)\t(((val) & ESR_ELx_SRT_MASK) >> ESR_ELx_SRT_SHIFT)\n#define ESR_ELx_SF_SHIFT\t(15)\n#define ESR_ELx_SF \t\t(ULONG(1) << ESR_ELx_SF_SHIFT)\n#define ESR_ELx_AR_SHIFT\t(14)\n#define ESR_ELx_AR \t\t(ULONG(1) << ESR_ELx_AR_SHIFT)\n#define ESR_ELx_CM_SHIFT\t(8)\n#define ESR_ELx_CM \t\t(ULONG(1) << ESR_ELx_CM_SHIFT)\n\n/* ISS field definitions for exceptions taken in to Hyp */\n#define ESR_ELx_CV\t\t(ULONG(1) << 24)\n#define ESR_ELx_COND_SHIFT\t(20)\n#define ESR_ELx_COND_MASK\t(ULONG(0xF) << ESR_ELx_COND_SHIFT)\n#define ESR_ELx_WFx_ISS_WFE\t(ULONG(1) << 0)\n#define ESR_ELx_xVC_IMM_MASK\t((1UL << 16) - 1)\n\n#define FSC_FAULT       ESR_ELx_FSC_FAULT\n#define FSC_ACCESS      ESR_ELx_FSC_ACCESS\n#define FSC_PERM        ESR_ELx_FSC_PERM\n#define FSC_SEA         ESR_ELx_FSC_EXTABT\n#define FSC_SEA_TTW0    (0x14)\n#define FSC_SEA_TTW1    (0x15)\n#define FSC_SEA_TTW2    (0x16)\n#define FSC_SEA_TTW3    (0x17)\n#define FSC_SECC        (0x18)\n#define FSC_SECC_TTW0   (0x1c)\n#define FSC_SECC_TTW1   (0x1d)\n#define FSC_SECC_TTW2   (0x1e)\n#define FSC_SECC_TTW3   (0x1f)\n\n#define DISR_EL1_IDS\t\t(ULONG(1) << 24)\n/*\n * DISR_EL1 and ESR_ELx share the bottom 13 bits, but the RES0 bits may mean\n * different things in the future...\n */\n#define DISR_EL1_ESR_MASK\t(ESR_ELx_AET | ESR_ELx_EA | ESR_ELx_FSC)\n\n#define HPFAR_MASK\tGENMASK(39, 4)\n\n#define EC_TYPE_AARCH64\t\t(0x1)\n#define EC_TYPE_AARCH32\t\t(0X2)\n#define EC_TYPE_BOTH\t\t(0x3)\n\n/*\n * Current EL with SP0\t\t0 - 3\n * Current EL with SPx\t\t4 - 7\n * Lower EL with aarch64\t8 - 11\n * Lower EL with aarch32\t12 - 15\n */\n#define VECTOR_C0_SYNC\t\t0\n#define VECTOR_C0_IRQ\t\t1\n#define VECTOR_C0_FIQ\t\t2\n#define VECTOR_C0_SERR\t\t3\n#define VECTOR_CX_SYNC\t\t4\n#define VECTOR_CX_IRQ\t\t5\n#define VECTOR_CX_FIQ\t\t6\n#define VECTOR_CX_SERR\t\t7\n#define VECTOR_L64_SYNC\t\t8\n#define VECTOR_L64_IRQ\t\t9\n#define VECTOR_L64_FIQ\t\t10\n#define VECTOR_L64_SERR\t\t11\n#define VECTOR_L32_SYNC\t\t12\n#define VECTOR_L32_IRQ\t\t13\n#define VECTOR_L32_FIQ\t\t14\n#define VECTOR_L32_SERR\t\t15\n#define VECTOR_MAX\t\t16\n\n#define AARCH64_SPSR_EL3h\t0b1101\t\t// el3 using sp_el3\n#define AARCH64_SPSR_EL3t\t0b1100\t\t// el3 using sp_el0\n#define AARCH64_SPSR_EL2h\t0b1001\t\t// el2 using sp_el2\n#define AARCH64_SPSR_EL2t\t0b1000\t\t// el2 using sp_el0\n#define AARCH64_SPSR_EL1h\t0b0101\t\t// el1 using sp_el1\n#define AARCH64_SPSR_EL1t\t0b0100\t\t// el1 using sp_el0\n#define AARCH64_SPSR_EL0t\t0b0000\t\t// el0 using sp_el0\n#define AARCH64_SPSR_RW\t\t(1 << 4)\n#define AARCH64_SPSR_F\t\t(1 << 6)\n#define AARCH64_SPSR_I\t\t(1 << 7)\n#define AARCH64_SPSR_A\t\t(1 << 8)\n#define AARCH64_SPSR_D\t\t(1 << 9)\n#define AARCH64_SPSR_IL\t\t(1 << 20)\n#define AARCH64_SPSR_SS\t\t(1 << 21)\n#define AARCH64_SPSR_V\t\t(1 << 28)\n#define AARCH64_SPSR_C\t\t(1 << 29)\n#define AARCH64_SPSR_Z\t\t(1 << 30)\n#define AARCH64_SPSR_N\t\t(1 << 31)\n\n#define AARCH32_USER\t\t0b0000\n#define AARCH32_FIQ\t\t0b0001\n#define AARCH32_IRQ\t\t0b0010\n#define AARCH32_SVC\t\t0b0011\n#define AARCH32_MON\t\t0b0110\n#define AARCH32_ABT\t\t0b0111\n#define AARCH32_HYP\t\t0b1010\n#define AARCH32_UND\t\t0b1011\n#define AARCH32_SYSTEM\t\t0b1111\n\n#define MODE_EL3\t\t(0x3UL)\n#define MODE_EL2\t\t(0x2UL)\n#define MODE_EL1\t\t(0x1UL)\n#define MODE_EL0\t\t(0x0UL)\n#define MODE_EL_SHIFT\t\t(0x2UL)\n#define MODE_EL_MASK\t\t(0x3UL)\n#define GET_EL(mode)\t\t(((mode) >> MODE_EL_SHIFT) & MODE_EL_MASK)\n\n#define MPIDR_EL1_AFF3_LSB\t32\n#define MPIDR_EL1_U\t\t(1 << 30)\n#define MPIDR_EL1_MT\t\t(1 << 24)\n#define MPIDR_EL1_AFF2_LSB\t16\n#define MPIDR_EL1_AFF1_LSB\t8\n#define MPIDR_EL1_AFF0_LSB\t0\n#define MPIDR_EL1_AFF_WIDTH\t8\n#define MIPIDR_AFF_SHIFT\t2\n\n#define DCZID_EL0_BS_LSB\t0\n#define DCZID_EL0_BS_WIDTH\t4\n#define DCZID_EL0_DZP_LSB\t5\n#define DCZID_EL0_DZP\t\t(1 << 5)\n\n#define SCTLR_EL1_UCI\t\t(1 << 26)\n#define SCTLR_ELx_EE\t\t(1 << 25)\n#define SCTLR_EL1_E0E\t\t(1 << 24)\n#define SCTLR_ELx_WXN\t\t(1 << 19)\n#define SCTLR_EL1_nTWE\t\t(1 << 18)\n#define SCTLR_EL1_nTWI\t\t(1 << 16)\n#define SCTLR_EL1_UCT\t\t(1 << 15)\n#define SCTLR_EL1_DZE\t\t(1 << 14)\n#define SCTLR_ELx_I\t\t(1 << 12)\n#define SCTLR_EL1_UMA\t\t(1 << 9)\n#define SCTLR_EL1_SED\t\t(1 << 8)\n#define SCTLR_EL1_ITD\t\t(1 << 7)\n#define SCTLR_EL1_THEE\t\t(1 << 6)\n#define SCTLR_EL1_CP15BEN\t(1 << 5)\n#define SCTLR_EL1_SA0\t\t(1 << 4)\n#define SCTLR_ELx_SA\t\t(1 << 3)\n#define SCTLR_ELx_C\t\t(1 << 2)\n#define SCTLR_ELx_A\t\t(1 << 1)\n#define SCTLR_ELx_M\t\t(1 << 0)\n\n#define SCTLR_ELx_C_BIT\t\t(2)\n#define SCTLR_ELx_A_BIT\t\t(1)\n#define SCTLR_ELx_M_BIT\t\t(0)\n\n#define CPACR_EL1_TTA\t\t(1 << 28)\n#define CPACR_EL1_FPEN\t\t(3 << 20)\n\n#define CPTR_ELx_TCPAC\t\t(1 << 31)\n#define CPTR_ELx_TTA\t\t(1 << 20)\n#define CPTR_ELx_TFP\t\t(1 << 10)\n\n#define SCR_EL3_TWE\t\t(1 << 13)\n#define SCR_EL3_TWI\t\t(1 << 12)\n#define SCR_EL3_ST\t\t(1 << 11)\n#define SCR_EL3_RW\t\t(1 << 10)\n#define SCR_EL3_SIF\t\t(1 << 9)\n#define SCR_EL3_HCE\t\t(1 << 8)\n#define SCR_EL3_SMD\t\t(1 << 7)\n#define SCR_EL3_EA\t\t(1 << 3)\n#define SCR_EL3_FIQ\t\t(1 << 2)\n#define SCR_EL3_IRQ\t\t(1 << 1)\n#define SCR_EL3_NS\t\t(1 << 0)\n\n#define HCR_EL2_VM\t\t(1ul << 0)\n#define HCR_EL2_SWIO\t\t(1ul << 1)\n#define HCR_EL2_PTW\t\t(1ul << 2)\n#define HCR_EL2_FMO\t\t(1ul << 3)\n#define HCR_EL2_IMO\t\t(1ul << 4)\n#define HCR_EL2_AMO\t\t(1ul << 5)\n#define HCR_EL2_VF\t\t(1ul << 6)\n#define HCR_EL2_VI\t\t(1ul << 7)\n#define HCR_EL2_VSE\t\t(1ul << 8)\n#define HCR_EL2_FB\t\t(1ul << 9)\n#define HCR_EL2_BSU_IS\t\t(1ul << 10)\n#define HCR_EL2_BSU_OS\t\t(2ul << 10)\n#define HCR_EL2_BSU_FS\t\t(3ul << 10)\n#define HCR_EL2_DC\t\t(1ul << 12)\n#define HCR_EL2_TWI\t\t(1ul << 13)\n#define HCR_EL2_TWE\t\t(1ul << 14)\n#define HCR_EL2_TID0\t\t(1ul << 15)\n#define HCR_EL2_TID1\t\t(1ul << 16)\n#define HCR_EL2_TID2\t\t(1ul << 17)\n#define HCR_EL2_TID3\t\t(1ul << 18)\n#define HCR_EL2_TSC\t\t(1ul << 19)\n#define HCR_EL2_TIDCP\t\t(1ul << 20)\n#define HCR_EL2_TACR\t\t(1ul << 21)\n#define HCR_EL2_TSW\t\t(1ul << 22)\n#define HCR_EL2_TPC\t\t(1ul << 23)\n#define HCR_EL2_TPU\t\t(1ul << 24)\n#define HCR_EL2_TTLB\t\t(1ul << 25)\n#define HCR_EL2_TVM\t\t(1ul << 26)\n#define HCR_EL2_TGE\t\t(1ul << 27)\n#define HCR_EL2_TDZ\t\t(1ul << 28)\n#define HCR_EL2_HCD\t\t(1ul << 29)\n#define HCR_EL2_TRVM\t\t(1ul << 30)\n#define HCR_EL2_RW\t\t(1ul << 31)\n#define HCR_EL2_CD\t\t(1ul << 32)\n#define HCR_EL2_ID\t\t(1ul << 33)\n#define HCR_EL2_E2H\t\t(1ul << 34)\n\n#define LOUIS_SHIFT\t\t(21)\n#define LOC_SHIFT\t\t(24)\n#define CLIDR_FIELD_WIDTH\t(3)\n\n#define DAIF_F_BIT\t\t6\n#define DAIF_I_BIT\t\t7\n#define DAIF_A_BIT\t\t8\n#define DAIF_D_BIT\t\t9\n\n#define LEVEL_SHIFT\t\t(1)\n\n/*\n * TCR flags.\n */\n#define TCR_T0SZ_OFFSET\t\t0\n#define TCR_T1SZ_OFFSET\t\t16\n#define TCR_T0SZ(x)\t\t((UL(64) - (x)) << TCR_T0SZ_OFFSET)\n#define TCR_T1SZ(x)\t\t((UL(64) - (x)) << TCR_T1SZ_OFFSET)\n#define TCR_TxSZ(x)\t\t(TCR_T0SZ(x) | TCR_T1SZ(x))\n#define TCR_TxSZ_WIDTH\t\t6\n#define TCR_T0SZ_MASK\t\t(((UL(1) << TCR_TxSZ_WIDTH) - 1) << TCR_T0SZ_OFFSET)\n\n#define TCR_IRGN0_SHIFT\t\t8\n#define TCR_IRGN0_MASK\t\t(UL(3) << TCR_IRGN0_SHIFT)\n#define TCR_IRGN0_NC\t\t(UL(0) << TCR_IRGN0_SHIFT)\n#define TCR_IRGN0_WBWA\t\t(UL(1) << TCR_IRGN0_SHIFT)\n#define TCR_IRGN0_WT\t\t(UL(2) << TCR_IRGN0_SHIFT)\n#define TCR_IRGN0_WBnWA\t\t(UL(3) << TCR_IRGN0_SHIFT)\n\n#define TCR_IRGN1_SHIFT\t\t24\n#define TCR_IRGN1_MASK\t\t(UL(3) << TCR_IRGN1_SHIFT)\n#define TCR_IRGN1_NC\t\t(UL(0) << TCR_IRGN1_SHIFT)\n#define TCR_IRGN1_WBWA\t\t(UL(1) << TCR_IRGN1_SHIFT)\n#define TCR_IRGN1_WT\t\t(UL(2) << TCR_IRGN1_SHIFT)\n#define TCR_IRGN1_WBnWA\t\t(UL(3) << TCR_IRGN1_SHIFT)\n\n#define TCR_IRGN_NC\t\t(TCR_IRGN0_NC | TCR_IRGN1_NC)\n#define TCR_IRGN_WBWA\t\t(TCR_IRGN0_WBWA | TCR_IRGN1_WBWA)\n#define TCR_IRGN_WT\t\t(TCR_IRGN0_WT | TCR_IRGN1_WT)\n#define TCR_IRGN_WBnWA\t\t(TCR_IRGN0_WBnWA | TCR_IRGN1_WBnWA)\n#define TCR_IRGN_MASK\t\t(TCR_IRGN0_MASK | TCR_IRGN1_MASK)\n\n#define TCR_ORGN0_SHIFT\t\t10\n#define TCR_ORGN0_MASK\t\t(UL(3) << TCR_ORGN0_SHIFT)\n#define TCR_ORGN0_NC\t\t(UL(0) << TCR_ORGN0_SHIFT)\n#define TCR_ORGN0_WBWA\t\t(UL(1) << TCR_ORGN0_SHIFT)\n#define TCR_ORGN0_WT\t\t(UL(2) << TCR_ORGN0_SHIFT)\n#define TCR_ORGN0_WBnWA\t\t(UL(3) << TCR_ORGN0_SHIFT)\n\n#define TCR_ORGN1_SHIFT\t\t26\n#define TCR_ORGN1_MASK\t\t(UL(3) << TCR_ORGN1_SHIFT)\n#define TCR_ORGN1_NC\t\t(UL(0) << TCR_ORGN1_SHIFT)\n#define TCR_ORGN1_WBWA\t\t(UL(1) << TCR_ORGN1_SHIFT)\n#define TCR_ORGN1_WT\t\t(UL(2) << TCR_ORGN1_SHIFT)\n#define TCR_ORGN1_WBnWA\t\t(UL(3) << TCR_ORGN1_SHIFT)\n\n#define TCR_ORGN_NC\t\t(TCR_ORGN0_NC | TCR_ORGN1_NC)\n#define TCR_ORGN_WBWA\t\t(TCR_ORGN0_WBWA | TCR_ORGN1_WBWA)\n#define TCR_ORGN_WT\t\t(TCR_ORGN0_WT | TCR_ORGN1_WT)\n#define TCR_ORGN_WBnWA\t\t(TCR_ORGN0_WBnWA | TCR_ORGN1_WBnWA)\n#define TCR_ORGN_MASK\t\t(TCR_ORGN0_MASK | TCR_ORGN1_MASK)\n\n#define TCR_SH0_SHIFT\t\t12\n#define TCR_SH0_MASK\t\t(UL(3) << TCR_SH0_SHIFT)\n#define TCR_SH0_INNER\t\t(UL(3) << TCR_SH0_SHIFT)\n\n#define TCR_SH1_SHIFT\t\t28\n#define TCR_SH1_MASK\t\t(UL(3) << TCR_SH1_SHIFT)\n#define TCR_SH1_INNER\t\t(UL(3) << TCR_SH1_SHIFT)\n#define TCR_SHARED\t\t(TCR_SH0_INNER | TCR_SH1_INNER)\n\n#define TCR_TG0_SHIFT\t\t14\n#define TCR_TG0_MASK\t\t(UL(3) << TCR_TG0_SHIFT)\n#define TCR_TG0_4K\t\t(UL(0) << TCR_TG0_SHIFT)\n#define TCR_TG0_64K\t\t(UL(1) << TCR_TG0_SHIFT)\n#define TCR_TG0_16K\t\t(UL(2) << TCR_TG0_SHIFT)\n\n#define TCR_TG1_SHIFT\t\t30\n#define TCR_TG1_MASK\t\t(UL(3) << TCR_TG1_SHIFT)\n#define TCR_TG1_16K\t\t(UL(1) << TCR_TG1_SHIFT)\n#define TCR_TG1_4K\t\t(UL(2) << TCR_TG1_SHIFT)\n#define TCR_TG1_64K\t\t(UL(3) << TCR_TG1_SHIFT)\n\n#define TCR_IPS_SHIFT\t\t32\n#define TCR_IPS_MASK\t\t(UL(7) << TCR_IPS_SHIFT)\n#define TCR_A1\t\t\t(UL(1) << 22)\n#define TCR_ASID16\t\t(UL(1) << 36)\n#define TCR_TBI0\t\t(UL(1) << 37)\n#define TCR_HA\t\t\t(UL(1) << 39)\n#define TCR_HD\t\t\t(UL(1) << 40)\n#define TCR_NFD1\t\t(UL(1) << 54)\n\n#define CNT_CTL_ISTATUS\t\t(1 << 2)\n#define CNT_CTL_IMASK\t\t(1 << 1)\n#define CNT_CTL_ENABLE\t\t(1 << 0)\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/aarch64_el1_reg.h",
    "content": "/*\n * Copyright (C) 2020 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef __MINOS_AARCH64_EL1_REG_H__\n#define __MINOS_ARRCH64_EL1_REG_H__\n\n#include <asm/aarch64_common.h>\n\n#define ARM64_SCTLR\t\tSCTLR_EL1\n#define ARM64_CPACR\t\tCAPACR_EL1\n#define ARM64_TRFCR\t\tTRFCR_EL1\n#define ARM64_TTBR0\t\tTTBR0_EL1\n#define ARM64_TTBR1\t\tTTBR1_EL1\n#define ARM64_TCR\t\tTCR_EL1\n#define ARM64_AFSR0\t\tAFSR0_EL1\n#define ARM64_AFSR1\t\tAFSR1_EL1\n#define ARM64_ESR\t\tESR_EL1\n#define ARM64_FAR\t\tFAR_EL1\n#define ARM64_MAIR\t\tMAIR_EL1\n#define ARM64_AMAIR\t\tAMAIR_EL1\n#define ARM64_VBAR\t\tVBAR_EL1\n#define ARM64_CONTEXTIDR\tCONTEXTIDR_EL1\n#define ARM64_CNTKCTL\t\tCNTHCTL_EL1\n#define ARM64_SPSR\t\tSPSR_EL1\n#define ARM64_ELR\t\tELR_EL1\n#define ARM64_TPIDR\t\tTPIDR_EL1\n#define ARM64_CNTSIRQ_TVAL\tCNTP_TVAL_EL0\n#define ARM64_CNTSIRQ_CTL\tCNTP_CTL_EL0\n#define ARM64_CNTSIRQ_CVAL\tCNTP_CVAL_EL0\n#define ARM64_CNTSCHED_TVAL\tCNTV_TVAL_EL0\n#define ARM64_CNTSCHED_CTL\tCNTV_CTL_EL0\n#define ARM64_CNTSCHED_CVAL\tCNTV_CVAL_EL0\n\n#define ARM64_SPSR_VALUE\t0x1c5\n#define ARM64_SPSR_KERNEL\tAARCH64_SPSR_EL1h\n#define ARM64_SPSR_USER\t\tAARCH64_SPSR_EL0t\n\n#define ARM64_SCTLR_VALUE\t\\\n\tSCTLR_EL1_UCI | SCTLR_EL1_UCT | SCTLR_EL1_DZE\n\n// #define ARM64_TCR_VALUE\t\t0x25B5103510\n// VA[55] == 0 : TCR_ELx.TBI0 determines whether address tags are used.\n// VA[55] == 1 : TCR_ELx.TBI1 determines whether address tags are used.\n// use 512GB VA size, 1T IPA\n#define ARM64_TCR_VALUE\t\\\n\tTCR_T0SZ(39) | TCR_T1SZ(39) | TCR_IRGN0_WBWA | TCR_IRGN1_WBWA |\t\t\\\n\tTCR_ORGN0_WBWA | TCR_ORGN1_WBWA | TCR_SH0_INNER | TCR_SH1_INNER |\t\\\n\tTCR_TG1_4K | TCR_TG0_4K | TCR_ASID16 | TCR_TBI0\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/aarch64_el2_reg.h",
    "content": "/*\n * Copyright (C) 2020 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef __MINOS_AARCH64_EL2_REG_H__\n#define __MINOS_AARCH64_EL2_REG_H__\n\n#define ARM64_SCTLR\t\tSCTLR_EL2\n#define ARM64_CPACR\t\tCPACR_EL2\n#define ARM64_TRFCR\t\tTRFCR_EL2\n#define ARM64_TTBR0\t\tTTBR0_EL2\n#define ARM64_TTBR1\t\tTTBR0_EL2\n#define ARM64_TCR\t\tTCR_EL2\n#define ARM64_AFSR0\t\tAFSR0_EL2\n#define ARM64_AFSR1\t\tAFSR1_EL2\n#define ARM64_ESR\t\tESR_EL2\n#define ARM64_FAR\t\tFAR_EL2\n#define ARM64_MAIR\t\tMAIR_EL2\n#define ARM64_AMAIR\t\tAMAIR_EL2\n#define ARM64_VBAR\t\tVBAR_EL2\n#define ARM64_CONTEXTIDR\tCONTEXTIDR_EL2\n#define ARM64_CNTKCTL\t\tCNTHCTL_EL2\n#define ARM64_SPSR\t\tSPSR_EL2\n#define ARM64_ELR\t\tELR_EL2\n#define ARM64_TPIDR\t\tTPIDR_EL2\n#define ARM64_CNTSIRQ_TVAL\tCNTP_TVAL_EL0\n#define ARM64_CNTSIRQ_CTL\tCNTP_CTL_EL0\n#define ARM64_CNTSIRQ_CVAL\tCNTP_CVAL_EL0\n#define ARM64_CNTSCHED_TVAL\tCNTHP_TVAL_EL2\n#define ARM64_CNTSCHED_CTL\tCNTHP_CTL_EL2\n#define ARM64_CNTSCHED_CVAL\tCNTHP_CVAL_EL2\n\n#define ARM64_VTCR_EL2\t\tVTCR_EL2\n#define ARM64_VTTBR_EL2\t\tVTTBR_EL2\n#define ARM64_VMPIDR_EL2\tVMPIDR_EL2\n#define ARM64_VPIDR_EL2\t\tVPIDR_EL2\n#define ARM64_HCR_EL2\t\tHCR_EL2\n#define ARM64_DACR32_EL2\tDACR32_EL2\n#define ARM64_IFSR32_EL2\tIFSR32_EL2\n#define ARM64_CNTVOFF_EL2\tCNTVOFF_EL2\n\n/* the register for guest */\n#define ARM64_SCTLR_EL1\t\tSCTLR_EL1\n#define ARM64_CPACR_EL1\t\tCPACR_EL1\n#define ARM64_ZCR_EL1\t\tZCR_EL1\n#define ARM64_TRFCR_EL1\t\tTRFCR_EL1\n#define ARM64_TTBR0_EL1\t\tTTBR0_EL1\n#define ARM64_TTBR1_EL1\t\tTTBR1_EL1\n#define ARM64_TCR_EL1\t\tTCR_EL1\n#define ARM64_AFSR0_EL1\t\tAFSR0_EL1\n#define ARM64_AFSR1_EL1\t\tAFSR1_EL1\n#define ARM64_ESR_EL1\t\tESR_EL1\n#define ARM64_FAR_EL1\t\tFAR_EL1\n#define ARM64_PMSCR_EL1\t\tPMSCR_EL1\n#define ARM64_PAR_EL1\t\tPAR_EL1\n#define ARM64_MAIR_EL1\t\tMAIR_EL1\n#define ARM64_AMAIR_EL1\t\tAMAIR_EL1\n#define ARM64_VBAR_EL1\t\tVBAR_EL1\n#define ARM64_CONTEXTIDR_EL1\tCONTEXTIDR_EL1\n#define ARM64_CNTKCTL_EL1\tCNTKCTL_EL1\n#define ARM64_SPSR_EL1\t\tSPSR_EL1\n#define ARM64_ELR_EL1\t\tELR_EL1\n#define ARM64_SP_EL1\t\tSP_EL1\n#define ARM64_ACTLR_EL1\t\tACTLR_EL1\n#define ARM64_TPIDR_EL1\t\tTPIDR_EL1\n#define ARM64_CSSELR_EL1\tCSSELR_EL1\n\n#define ARM64_SP_EL0\t\tSP_EL0\n#define ARM64_TPIDR_EL0\t\tTPIDR_EL0\n#define ARM64_TPIDRRO_EL0\tTPIDRRO_EL0\n#define ARM64_CNTV_TVAL_EL0\tCNTV_TVAL_EL0\n#define ARM64_CNTV_CTL_EL0\tCNTV_CTL_EL0\n#define ARM64_CNTV_CVAL_EL0\tCNTV_CVAL_EL0\n\n#define ARM64_SCTLR_VALUE\t0x30c51878\n#define ARM64_SPSR_VALUE\t0x1c9\n#define ARM64_SPSR_KERNEL\tAARCH64_SPSR_EL2h\n#define ARM64_SPSR_USER\t\tAARCH64_SPSR_EL0t\n\n/*\n * VA 48 bit address range 1TB and translation start at lvl1\n * IRGN0 : Normal memory, Inner Write-Back Write-Allocate Cacheable\n * ORGN0 : Normal memory, Outer Write-Back Write-Allocate Cacheable\n * SH0\t : Inner shareable\n * BIT23 :Reserved, res1.\n */\n#define ARM64_TCR_VALUE\t\\\n\tTCR_T0SZ(39) | TCR_IRGN0_WBWA | TCR_ORGN0_WBWA | TCR_SH0_INNER | TCR_TG0_4K\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/aarch64_el2_vhe_reg.h",
    "content": "/*\n * Copyright (C) 2020 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef __MINOS_AARCH64_EL2_VHE_REG_H__\n#define __MINOS_AARCH64_EL2_VHE_REG_H__\n\n#define ARM64_SCTLR\t\tSCTLR_EL1\n#define ARM64_CPTR\t\tCPACR_EL1\n#define ARM64_TRFCR\t\tTRFCR_EL1\n#define ARM64_TTBR0\t\tTTBR0_EL1\n#define ARM64_TTBR1\t\tTTBR1_EL1\n#define ARM64_TCR\t\tTCR_EL1\n#define ARM64_AFSR0\t\tAFSR0_EL1\n#define ARM64_AFSR1\t\tAFSR1_EL1\n#define ARM64_ESR\t\tESR_EL1\n#define ARM64_FAR\t\tFAR_EL1\n#define ARM64_MAIR\t\tMAIR_EL1\n#define ARM64_AMAIR\t\tAMAIR_EL1\n#define ARM64_VBAR\t\tVBAR_EL1\n#define ARM64_CONTEXTIDR\tCONTEXTIDR_EL1\n#define ARM64_CNTHCTL\t\tCNTKCTL_EL1\n#define ARM64_SPSR\t\tSPSR_EL1\n#define ARM64_ELR\t\tELR_EL1\n#define ARM64_TPIDR\t\tTPIDR_EL2\n#define ARM64_CNTSIRQ_TVAL\tCNTP_TVAL_EL02\n#define ARM64_CNTSIRQ_CTL\tCNTP_CTL_EL02\n#define ARM64_CNTSIRQ_CVAL\tCNTP_CVAL_EL02\n#define ARM64_CNTSCHED_TVAL\tCNTHP_TVAL_EL2\n#define ARM64_CNTSCHED_CTL\tCNTHP_CTL_EL2\n#define ARM64_CNTSCHED_CVAL\tCNTHP_CVAL_EL2\n\n#define ARM64_VTCR_EL2\t\tVTCR_EL2\n#define ARM64_VTTBR_EL2\t\tVTTBR_EL2\n#define ARM64_VMPIDR_EL2\tVMPIDR_EL2\n#define ARM64_VPIDR_EL2\t\tVPIDR_EL2\n#define ARM64_HCR_EL2\t\tHCR_EL2\n#define ARM64_DACR32_EL2\tDACR32_EL2\n#define ARM64_IFSR32_EL2\tIFSR32_EL2\n#define ARM64_CNTVOFF_EL2\tCNTVOFF_EL2\n\n/* the register for guest */\n#define ARM64_SCTLR_EL1\t\tSCTLR_EL12\n#define ARM64_CPACR_EL1\t\tCPACR_EL12\n#define ARM64_ZCR_EL1\t\tZCR_EL12\n#define ARM64_TRFCR_EL1\t\tTRFCR_EL12\n#define ARM64_TTBR0_EL1\t\tTTBR0_EL12\n#define ARM64_TTBR1_EL1\t\tTTBR1_EL12\n#define ARM64_TCR_EL1\t\tTCR_EL12\n#define ARM64_AFSR0_EL1\t\tAFSR0_EL12\n#define ARM64_AFSR1_EL1\t\tAFSR1_EL12\n#define ARM64_ESR_EL1\t\tESR_EL12\n#define ARM64_FAR_EL1\t\tFAR_EL12\n#define ARM64_PMSCR_EL1\t\tPMSCR_EL12\n#define ARM64_MAIR_EL1\t\tMAIR_EL12\n#define ARM64_AMAIR_EL1\t\tAMAIR_EL12\n#define ARM64_VBAR_EL1\t\tVBAR_EL12\n#define ARM64_CONTEXTIDR_EL1\tCONTEXTIDR_EL12\n#define ARM64_CNTKCTL_EL1\tCNTKCTL_EL12\n#define ARM64_SPSR_EL1\t\tSPSR_EL12\n#define ARM64_ELR_EL1\t\tELR_EL12\n\n#define ARM64_SP_EL1\t\tSP_EL1\n#define ARM64_ACTLR_EL1\t\tACTLR_EL1\n#define ARM64_TPIDR_EL1\t\tTPIDR_EL1\n#define ARM64_CSSELR_EL1\tCSSELR_EL1\n#define ARM64_PAR_EL1\t\tPAR_EL1\n\n#define ARM64_SP_EL0\t\tSP_EL0\n#define ARM64_TPIDR_EL0\t\tTPIDR_EL0\n#define ARM64_TPIDRRO_EL0\tTPIDRRO_EL0\n#define ARM64_CNTV_TVAL_EL0\tCNTV_TVAL_EL02\n#define ARM64_CNTV_CTL_EL0\tCNTV_CTL_EL02\n#define ARM64_CNTV_CVAL_EL0\tCNTV_CVAL_EL02\n\n#define ARM64_SCTLR_VALUE\t0x30c50838\n#define ARM64_SPSR_VALUE\t0x1c9\n#define ARM64_SPSR_KERNEL\tAARCH64_SPSR_EL2h\n#define ARM64_SPSR_USER\t\tAARCH64_SPSR_EL0t\n\n/* config the TCR_EL1 for kernel\n * mov\tx1, #0x0\n * orr\tx1, x1, #(0x10 << 16)\t// VA 48 bit address range and translation start at lvl0 for kernel\n * orr\tx1, x1, #(1 << 24)\t// IRGN1 : Normal memory, Inner Write-Back Write-Allocate Cacheable\n * orr\tx1, x1, #(1 << 26)\t// ORGN1 : Normal memory, Outer Write-Back Write-Allocate Cacheable\n * orr\tx1, x1, #(3 << 28)\t// Inner shareable\n * orr\tx1, x1, #(2 << 30)\t// 4KB Granule size\n * orr\tx1, x1, #(1 << 37)\t// Top bit do not used for address caculate for TTBR0_EL1 (user space).\n * orr\tx1, x1, #(0 << 38)\t// Top bit used for address caculate for TTBR1_EL1 (kernel space).\n * orr\tx1, x1, #0x10\t\t// VA 48 bit address range t0sz\n * orr\tx1, x1, #(1 << 8)\t// IRGN0 : Normal memory, Inner Write-Back Write-Allocate Cacheable\n * orr\tx1, x1, #(1 << 10)\t// ORGN0 : Normal memory, Outer Write-Back Write-Allocate Cacheable\n * orr\tx1, x1, #(3 << 12)\t// Inner shareable\n * ldr\tx2, =(5 << 32)\t\t// 256TB IPS\n * orr\tx1, x1, x2\n */\n#define ARM64_TCR_VALUE\t\t0x25B5103510\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/aarch64_helper.h",
    "content": "/*\n * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.\n *\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n#ifndef _MINOS_ARMV8_H_\n#define _MINOS_ARMV8_H_\n\n#include <minos/types.h>\n#include <asm/aarch64_common.h>\n#include <asm/gic_reg.h>\n\n#ifdef CONFIG_ERRATA_A57_813419\n#define ERRATA_A57_813419 1\n#else\n#define ERRATA_A57_813419 0\n#endif\n\n#define _DEFINE_SYSREG_READ_FUNC(_name, _reg_name)\t\t\\\nstatic inline uint64_t read_ ## _name(void)\t\t\t\\\n{\t\t\t\t\t\t\t\t\\\n\tuint64_t v;\t\t\t\t\t\t\\\n\t__asm__ volatile (\"mrs %0, \" #_reg_name : \"=r\" (v));\t\\\n\treturn v;\t\t\t\t\t\t\\\n}\n\n#define _DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name)\t\t\t\\\nstatic inline void write_ ## _name(uint64_t v)\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\t__asm__ volatile (\"msr \" #_reg_name \", %0\" : : \"r\" (v));\t\\\n}\n\n#define SYSREG_WRITE_CONST(reg_name, v)\t\t\t\t\\\n\t__asm__ volatile (\"msr \" #reg_name \", %0\" : : \"i\" (v))\n\n/* Define read function for system register */\n#define DEFINE_SYSREG_READ_FUNC(_name) \t\t\t\\\n\t_DEFINE_SYSREG_READ_FUNC(_name, _name)\n\n/* Define read & write function for system register */\n#define DEFINE_SYSREG_RW_FUNCS(_name)\t\t\t\\\n\t_DEFINE_SYSREG_READ_FUNC(_name, _name)\t\t\\\n\t_DEFINE_SYSREG_WRITE_FUNC(_name, _name)\n\n/* Define read & write function for renamed system register */\n#define DEFINE_RENAME_SYSREG_RW_FUNCS(_name, _reg_name)\t\\\n\t_DEFINE_SYSREG_READ_FUNC(_name, _reg_name)\t\\\n\t_DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name)\n\n/* Define read function for renamed system register */\n#define DEFINE_RENAME_SYSREG_READ_FUNC(_name, _reg_name)\t\\\n\t_DEFINE_SYSREG_READ_FUNC(_name, _reg_name)\n\n/* Define write function for renamed system register */\n#define DEFINE_RENAME_SYSREG_WRITE_FUNC(_name, _reg_name)\t\\\n\t_DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name)\n\n/**********************************************************************\n * Macros to create inline functions for system instructions\n *********************************************************************/\n\n/* Define function for simple system instruction */\n#define DEFINE_SYSOP_FUNC(_op)\t\t\t\t\\\nstatic inline void _op(void)\t\t\t\t\\\n{\t\t\t\t\t\t\t\\\n\t__asm__ (#_op);\t\t\t\t\t\\\n}\n\n/* Define function for system instruction with type specifier */\n#define DEFINE_SYSOP_TYPE_FUNC(_op, _type)\t\t\\\nstatic inline void _op ## _type(void)\t\t\t\\\n{\t\t\t\t\t\t\t\\\n\t__asm__ (#_op \" \" #_type);\t\t\t\\\n}\n\n/* Define function for system instruction with register parameter */\n#define DEFINE_SYSOP_TYPE_PARAM_FUNC(_op, _type)\t\\\nstatic inline void _op ## _type(uint64_t v)\t\t\\\n{\t\t\t\t\t\t\t\\\n\t __asm__ (#_op \" \" #_type \", %0\" : : \"r\" (v));\t\\\n}\n\n/*******************************************************************************\n * TLB maintenance accessor prototypes\n ******************************************************************************/\n\n#if ERRATA_A57_813419\n/*\n * Define function for TLBI instruction with type specifier that implements\n * the workaround for errata 813419 of Cortex-A57.\n */\n#define DEFINE_TLBIOP_ERRATA_A57_813419_TYPE_FUNC(_type)\\\nstatic inline void tlbi ## _type(void)\t\t\t\\\n{\t\t\t\t\t\t\t\\\n\t__asm__(\"tlbi \" #_type \"\\n\"\t\t\t\\\n\t\t\"dsb ish\\n\"\t\t\t\t\\\n\t\t\"tlbi \" #_type);\t\t\t\\\n}\n\n/*\n * Define function for TLBI instruction with register parameter that implements\n * the workaround for errata 813419 of Cortex-A57.\n */\n#define DEFINE_TLBIOP_ERRATA_A57_813419_TYPE_PARAM_FUNC(_type)\t\\\nstatic inline void tlbi ## _type(uint64_t v)\t\t\t\\\n{\t\t\t\t\t\t\t\t\\\n\t__asm__(\"tlbi \" #_type \", %0\\n\"\t\t\t\t\\\n\t\t\"dsb ish\\n\"\t\t\t\t\t\\\n\t\t\"tlbi \" #_type \", %0\" : : \"r\" (v));\t\t\\\n}\n#endif /* ERRATA_A57_813419 */\n\nDEFINE_SYSOP_TYPE_FUNC(tlbi, alle1)\nDEFINE_SYSOP_TYPE_FUNC(tlbi, alle1is)\nDEFINE_SYSOP_TYPE_FUNC(tlbi, alle2)\nDEFINE_SYSOP_TYPE_FUNC(tlbi, alle2is)\n#if ERRATA_A57_813419\nDEFINE_TLBIOP_ERRATA_A57_813419_TYPE_FUNC(alle3)\nDEFINE_TLBIOP_ERRATA_A57_813419_TYPE_FUNC(alle3is)\n#else\nDEFINE_SYSOP_TYPE_FUNC(tlbi, alle3)\nDEFINE_SYSOP_TYPE_FUNC(tlbi, alle3is)\n#endif\nDEFINE_SYSOP_TYPE_FUNC(tlbi, vmalle1)\n\nDEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vaae1is)\nDEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vaale1is)\nDEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vae2is)\nDEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vale2is)\n#if ERRATA_A57_813419\nDEFINE_TLBIOP_ERRATA_A57_813419_TYPE_PARAM_FUNC(vae3is)\nDEFINE_TLBIOP_ERRATA_A57_813419_TYPE_PARAM_FUNC(vale3is)\n#else\nDEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vae3is)\nDEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vale3is)\n#endif\n\n/*******************************************************************************\n * Cache maintenance accessor prototypes\n ******************************************************************************/\nDEFINE_SYSOP_TYPE_PARAM_FUNC(dc, isw)\nDEFINE_SYSOP_TYPE_PARAM_FUNC(dc, cisw)\nDEFINE_SYSOP_TYPE_PARAM_FUNC(dc, csw)\nDEFINE_SYSOP_TYPE_PARAM_FUNC(dc, cvac)\nDEFINE_SYSOP_TYPE_PARAM_FUNC(dc, ivac)\nDEFINE_SYSOP_TYPE_PARAM_FUNC(dc, civac)\nDEFINE_SYSOP_TYPE_PARAM_FUNC(dc, cvau)\nDEFINE_SYSOP_TYPE_PARAM_FUNC(dc, zva)\n\n/*******************************************************************************\n * Address translation accessor prototypes\n ******************************************************************************/\nDEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e1r)\nDEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e1w)\nDEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e0r)\nDEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e0w)\n\nvoid disable_mmu_el1(void);\nvoid disable_mmu_el3(void);\nvoid disable_mmu_icache_el1(void);\nvoid disable_mmu_icache_el3(void);\n\n/*******************************************************************************\n * Misc. accessor prototypes\n ******************************************************************************/\n\n#define write_daifclr(val) SYSREG_WRITE_CONST(daifclr, val)\n#define write_daifset(val) SYSREG_WRITE_CONST(daifset, val)\n\nDEFINE_SYSREG_READ_FUNC(par_el1)\nDEFINE_SYSREG_READ_FUNC(id_pfr1_el1)\nDEFINE_SYSREG_READ_FUNC(id_aa64pfr0_el1)\nDEFINE_SYSREG_READ_FUNC(id_aa64dfr0_el1)\nDEFINE_SYSREG_READ_FUNC(CurrentEl)\nDEFINE_SYSREG_RW_FUNCS(daif)\nDEFINE_SYSREG_RW_FUNCS(spsr_el1)\nDEFINE_SYSREG_RW_FUNCS(spsr_el2)\nDEFINE_SYSREG_RW_FUNCS(spsr_el3)\nDEFINE_SYSREG_RW_FUNCS(elr_el1)\nDEFINE_SYSREG_RW_FUNCS(elr_el2)\nDEFINE_SYSREG_RW_FUNCS(elr_el3)\n\nDEFINE_SYSOP_FUNC(wfi)\nDEFINE_SYSOP_FUNC(wfe)\nDEFINE_SYSOP_FUNC(sev)\nDEFINE_SYSOP_TYPE_FUNC(dsb, sy)\nDEFINE_SYSOP_TYPE_FUNC(dmb, sy)\nDEFINE_SYSOP_TYPE_FUNC(dmb, st)\nDEFINE_SYSOP_TYPE_FUNC(dmb, ld)\nDEFINE_SYSOP_TYPE_FUNC(dsb, ish)\nDEFINE_SYSOP_TYPE_FUNC(dsb, ishst)\nDEFINE_SYSOP_TYPE_FUNC(dmb, ish)\nDEFINE_SYSOP_TYPE_FUNC(dmb, ishst)\nDEFINE_SYSOP_TYPE_FUNC(dsb, nsh)\nDEFINE_SYSOP_TYPE_FUNC(dsb, nshst)\nDEFINE_SYSOP_TYPE_FUNC(dmb, nsh)\nDEFINE_SYSOP_TYPE_FUNC(dmb, nshst)\n\nuint32_t get_afflvl_shift(uint32_t);\nuint32_t mpidr_mask_lower_afflvls(uint64_t, uint32_t);\n\n\n/*******************************************************************************\n * System register accessor prototypes\n ******************************************************************************/\nDEFINE_SYSREG_READ_FUNC(midr_el1)\nDEFINE_SYSREG_READ_FUNC(mpidr_el1)\nDEFINE_SYSREG_READ_FUNC(id_aa64mmfr0_el1)\n\nDEFINE_SYSREG_RW_FUNCS(scr_el3)\nDEFINE_SYSREG_RW_FUNCS(hcr_el2)\n\nDEFINE_SYSREG_RW_FUNCS(vbar_el1)\nDEFINE_SYSREG_RW_FUNCS(vbar_el2)\nDEFINE_SYSREG_RW_FUNCS(vbar_el3)\n\nDEFINE_SYSREG_RW_FUNCS(sctlr_el1)\nDEFINE_SYSREG_RW_FUNCS(sctlr_el2)\nDEFINE_SYSREG_RW_FUNCS(sctlr_el3)\n\nDEFINE_SYSREG_RW_FUNCS(actlr_el1)\nDEFINE_SYSREG_RW_FUNCS(actlr_el2)\nDEFINE_SYSREG_RW_FUNCS(actlr_el3)\n\nDEFINE_SYSREG_RW_FUNCS(esr_el1)\nDEFINE_SYSREG_RW_FUNCS(esr_el2)\nDEFINE_SYSREG_RW_FUNCS(esr_el3)\n\nDEFINE_SYSREG_RW_FUNCS(afsr0_el1)\nDEFINE_SYSREG_RW_FUNCS(afsr0_el2)\nDEFINE_SYSREG_RW_FUNCS(afsr0_el3)\n\nDEFINE_SYSREG_RW_FUNCS(afsr1_el1)\nDEFINE_SYSREG_RW_FUNCS(afsr1_el2)\nDEFINE_SYSREG_RW_FUNCS(afsr1_el3)\n\nDEFINE_SYSREG_RW_FUNCS(far_el1)\nDEFINE_SYSREG_RW_FUNCS(far_el2)\nDEFINE_SYSREG_RW_FUNCS(far_el3)\n\nDEFINE_SYSREG_RW_FUNCS(mair_el1)\nDEFINE_SYSREG_RW_FUNCS(mair_el2)\nDEFINE_SYSREG_RW_FUNCS(mair_el3)\n\nDEFINE_SYSREG_RW_FUNCS(amair_el1)\nDEFINE_SYSREG_RW_FUNCS(amair_el2)\nDEFINE_SYSREG_RW_FUNCS(amair_el3)\n\nDEFINE_SYSREG_READ_FUNC(rvbar_el1)\nDEFINE_SYSREG_READ_FUNC(rvbar_el2)\nDEFINE_SYSREG_READ_FUNC(rvbar_el3)\n\nDEFINE_SYSREG_RW_FUNCS(rmr_el1)\nDEFINE_SYSREG_RW_FUNCS(rmr_el2)\nDEFINE_SYSREG_RW_FUNCS(rmr_el3)\n\nDEFINE_SYSREG_RW_FUNCS(tcr_el1)\nDEFINE_SYSREG_RW_FUNCS(tcr_el2)\nDEFINE_SYSREG_RW_FUNCS(tcr_el3)\n\nDEFINE_SYSREG_RW_FUNCS(ttbr0_el1)\nDEFINE_SYSREG_RW_FUNCS(ttbr0_el2)\nDEFINE_SYSREG_RW_FUNCS(ttbr0_el3)\n\nDEFINE_SYSREG_RW_FUNCS(ttbr1_el1)\n\nDEFINE_SYSREG_RW_FUNCS(vttbr_el2)\n\nDEFINE_SYSREG_RW_FUNCS(cptr_el2)\nDEFINE_SYSREG_RW_FUNCS(cptr_el3)\n\nDEFINE_SYSREG_RW_FUNCS(cpacr_el1)\nDEFINE_SYSREG_RW_FUNCS(cntfrq_el0)\nDEFINE_SYSREG_RW_FUNCS(cntps_ctl_el1)\nDEFINE_SYSREG_RW_FUNCS(cntps_tval_el1)\nDEFINE_SYSREG_RW_FUNCS(cntps_cval_el1)\nDEFINE_SYSREG_READ_FUNC(cntpct_el0)\nDEFINE_SYSREG_RW_FUNCS(cnthctl_el2)\n\nDEFINE_SYSREG_RW_FUNCS(tpidr_el3)\n\nDEFINE_SYSREG_RW_FUNCS(cntvoff_el2)\n\nDEFINE_SYSREG_RW_FUNCS(vpidr_el2)\nDEFINE_SYSREG_RW_FUNCS(vmpidr_el2)\nDEFINE_SYSREG_RW_FUNCS(cntp_ctl_el0)\n\nDEFINE_SYSREG_READ_FUNC(isr_el1)\n\nDEFINE_SYSREG_READ_FUNC(ctr_el0)\n\nDEFINE_SYSREG_RW_FUNCS(mdcr_el2)\nDEFINE_SYSREG_RW_FUNCS(hstr_el2)\nDEFINE_SYSREG_RW_FUNCS(cnthp_ctl_el2)\nDEFINE_SYSREG_RW_FUNCS(pmcr_el0)\n\nDEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el1, ICC_SRE_EL1)\nDEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el2, ICC_SRE_EL2)\nDEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el3, ICC_SRE_EL3)\nDEFINE_RENAME_SYSREG_RW_FUNCS(icc_pmr_el1, ICC_PMR_EL1)\nDEFINE_RENAME_SYSREG_READ_FUNC(icc_rpr_el1, ICC_RPR_EL1)\nDEFINE_RENAME_SYSREG_RW_FUNCS(icc_igrpen1_el3, ICC_IGRPEN1_EL3)\nDEFINE_RENAME_SYSREG_RW_FUNCS(icc_igrpen0_el1, ICC_IGRPEN0_EL1)\nDEFINE_RENAME_SYSREG_READ_FUNC(icc_hppir0_el1, ICC_HPPIR0_EL1)\nDEFINE_RENAME_SYSREG_READ_FUNC(icc_hppir1_el1, ICC_HPPIR1_EL1)\nDEFINE_RENAME_SYSREG_READ_FUNC(icc_iar0_el1, ICC_IAR0_EL1)\nDEFINE_RENAME_SYSREG_READ_FUNC(icc_iar1_el1, ICC_IAR1_EL1)\nDEFINE_RENAME_SYSREG_WRITE_FUNC(icc_eoir0_el1, ICC_EOIR0_EL1)\nDEFINE_RENAME_SYSREG_WRITE_FUNC(icc_eoir1_el1, ICC_EOIR1_EL1)\nDEFINE_RENAME_SYSREG_WRITE_FUNC(icc_dir_el1, ICC_DIR_EL1)\nDEFINE_RENAME_SYSREG_READ_FUNC(icc_sgi1r_el1, ICC_SGI1R_EL1)\n\nDEFINE_RENAME_SYSREG_READ_FUNC(ich_vtr_el2, ICH_VTR_EL2)\n\n\n#define IS_IN_EL(x) \\\n\t(GET_EL(read_CurrentEl()) == MODE_EL##x)\n\n#define IS_IN_EL1() IS_IN_EL(1)\n#define IS_IN_EL3() IS_IN_EL(3)\n#define IS_IN_EL2() IS_IN_EL(2)\n\n/*\n * Check if an EL is implemented from AA64PFR0 register fields. 'el' argument\n * must be one of 1, 2 or 3.\n */\n#define EL_IMPLEMENTED(el) \\\n\t((read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL##el##_SHIFT) \\\n\t\t& ID_AA64PFR0_ELX_MASK)\n\n/* Previously defined accesor functions with incomplete register names  */\n\n#define read_current_el()\tread_CurrentEl()\n\n#define dsb()\t\t\tdsbsy()\n#define dmb()\t\t\tdmbsy()\n\n#define read_midr()\t\tread_midr_el1()\n\n#define read_mpidr()\t\tread_mpidr_el1()\n\n#define read_scr()\t\tread_scr_el3()\n#define write_scr(_v)\t\twrite_scr_el3(_v)\n\n#define read_hcr()\t\tread_hcr_el2()\n#define write_hcr(_v)\t\twrite_hcr_el2(_v)\n\n#define read_cpacr()\t\tread_cpacr_el1()\n#define write_cpacr(_v)\t\twrite_cpacr_el1(_v)\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/aarch64_reg.h",
    "content": "/*\n * Copyright (C) 2020 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef __MINOS_AARCH64_REG_H__\n#define __MINOS_AARCH64_REG_H__\n\n#include <config/config.h>\n\n#ifdef CONFIG_VIRT\n\t#include <asm/aarch64_el2_reg.h>\n#else\n\t#include <asm/aarch64_el1_reg.h>\n#endif\t// CONFIG_VIRT\n\n#include <asm/gic_reg.h>\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/arch.h",
    "content": "#ifndef _MINOS_ARCH_AARCH64_H_\n#define _MINOS_ARCH_AARCH64_H_\n\n#include <asm/tcb.h>\n#include <asm/aarch64_helper.h>\n#include <config/config.h>\n#include <minos/task_def.h>\n#include <asm/cpu_feature.h>\n#include <asm/aarch64_reg.h>\n\n#ifdef CONFIG_VIRT\n#include <asm/virt.h>\n#endif\n\n#define NR_LOCAL_IRQS\t(32)\n#define NR_SGI_IRQS\t(16)\n#define NR_PPI_IRQS\t(16)\n\n#define SGI_IRQ_BASE\t(0)\n#define PPI_IRQ_BASE\t(16)\n\n#define SPI_OFFSET(n)\t(n - NR_LOCAL_IRQS);\n#define LOCAL_OFFSET(n) (n)\n\n#define arch_disable_local_irq()\twrite_daifset(2)\n#define arch_enable_local_irq() \twrite_daifclr(2)\n\n#define arch_save_irqflags()\t\tread_daif()\n#define arch_restore_irqflags(flags)\twrite_daif(flags)\n\n#define arch_irq_disabled()\t\t(read_daif() & (1 << DAIF_I_BIT))\n\n#define local_irq_save(flag) \\\n\tdo { \\\n\t\tflag = arch_save_irqflags(); \\\n\t\tarch_disable_local_irq(); \\\n\t} while (0)\n\n#define local_irq_restore(flag) \\\n\tdo { \\\n\t\tarch_restore_irqflags(flag); \\\n\t} while (0)\n\n#define stack_to_gp_regs(base) \\\n\t(gp_regs *)((base) - sizeof(gp_regs))\n\n#define get_reg_value(regs, index)\t\\\n\t*((unsigned long *)(regs) + index + 3)\n\n#define set_reg_value(regs, index, value)\t\\\n\t*((unsigned long *)(regs) + index + 3) = (unsigned long)value\n\n#define read_sysreg32(name) ({\t\t\t\t\t\t\\\n\tuint32_t _r;\t\t\t\t\t\t\t\\\n\tasm volatile(\"mrs  %0, \"stringify(name) : \"=r\" (_r));\t\t\\\n\t_r; })\n\n#define write_sysreg32(v, name)\t\t\t\t\t\t\\\n\tdo {\t\t\t\t\t\t\t\t\\\n\t\tuint32_t _r = v;\t\t\t\t\t\\\n\t\tasm volatile(\"msr \"stringify(name)\", %0\" : : \"r\" (_r));\t\\\n\t} while (0)\n\n#define write_sysreg64(v, name)\t\t\t\t\t\t\\\n\tdo {\t\t\t\t\t\t\t\t\\\n\t\tuint64_t _r = v;\t\t\t\t\t\\\n\t\tasm volatile(\"msr \"stringify(name)\", %0\" : : \"r\" (_r));\t\\\n\t} while (0)\n\n#define read_sysreg64(name) ({\t\t\t\t\t\t\\\n\tuint64_t _r;\t\t\t\t\t\t\t\\\n\tasm volatile(\"mrs  %0, \"stringify(name) : \"=r\" (_r));\t\t\\\n\t_r; })\n\n#define read_sysreg(name)     read_sysreg64(name)\n#define write_sysreg(v, name) write_sysreg64(v, name)\n\n#define nop() asm (\"nop\")\n\nstatic inline int affinity_to_logic_cpu(uint32_t aff3, uint32_t aff2,\n\t\tuint32_t aff1, uint32_t aff0)\n{\n\treturn (aff1 * CONFIG_NR_CPUS_CLUSTER0) + aff0;\n}\n\nstatic inline unsigned long va_to_pa(unsigned long va)\n{\n\tuint64_t pa, tmp = read_sysreg64(PAR_EL1);\n\n\tasm volatile (\"at s1e2r, %0;\" : : \"r\" (va));\n\tisb();\n\tpa = read_sysreg64(PAR_EL1) & 0x0000fffffffff000;\n\tpa = pa | (va & (~(~PAGE_MASK)));\n\twrite_sysreg64(tmp, PAR_EL1);\n\n\treturn pa;\n}\n\nstatic inline unsigned long guest_va_to_pa(unsigned long va, int read)\n{\n\tuint64_t pa, tmp = read_sysreg64(PAR_EL1);\n\n\tif (read)\n\t\tasm volatile (\"at s12e1r, %0;\" : : \"r\" (va));\n\telse\n\t\tasm volatile (\"at s12e1w, %0;\" : : \"r\" (va));\n\tisb();\n\tpa = read_sysreg64(PAR_EL1) & 0x0000fffffffff000;\n\tpa = pa | (va & PAGE_MASK);\n\twrite_sysreg64(tmp, PAR_EL1);\n\n\treturn pa;\n}\n\nstatic inline unsigned long guest_va_to_ipa(unsigned long va, int read)\n{\n\tuint64_t pa, tmp = read_sysreg64(PAR_EL1);\n\n\tif (read)\n\t\tasm volatile (\"at s1e1w, %0;\" : : \"r\" (va));\n\telse\n\t\tasm volatile (\"at s1e1r, %0;\" : : \"r\" (va));\n\tisb();\n\tpa = read_sysreg64(PAR_EL1) & 0x0000fffffffff000;\n\tpa = pa | (va & (~(~PAGE_MASK)));\n\twrite_sysreg64(tmp, PAR_EL1);\n\n\treturn pa;\n}\n\nstatic inline void cpu_relax(void)\n{\n\tasm volatile(\"yield\" ::: \"memory\");\n}\n\nstatic inline unsigned long arch_get_virtual_address_size(void)\n{\n\treturn (unsigned long)1 << 39;\n}\n\nint arch_is_exit_to_user(struct task *task);\nint arch_is_taken_from_guest(gp_regs *regs);\n\nvoid arch_switch_task_sw(struct task *cur, struct task *next);\nvoid arch_dump_stack(gp_regs *regs, unsigned long *sp);\nvoid arch_dump_register(gp_regs *regs);\nunsigned long arch_get_fp(void);\nunsigned long arch_get_sp(void);\nunsigned long arch_get_lr(void);\nvoid arch_smp_init(phy_addr_t *smp_h_addr);\nint __arch_init(void);\nint arch_early_init(void);\n\nvoid arch_init_task(struct task *task, void *entry, void *usp, void *data);\n\nvoid arch_set_user_stack(struct task *task, unsigned long stack);\n\nvoid arch_release_task(struct task *task);\n\nuint64_t cpuid_to_affinity(int cpuid);\nint affinity_to_cpuid(unsigned long affinity);\n\npgd_t *arch_alloc_process_page_table(void);\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/asm_current.h",
    "content": "#ifndef __MINOS_ASM_CURRENT_H__\n#define __MINOS_ASM_CURRENT_H__\n\n#include <config/config.h>\n#include <minos/compiler.h>\n#include <asm/barrier.h>\n\nstatic inline void *asm_get_current_task(void)\n{\n\tvoid *tsk;\n\t__asm__ volatile (\"mov %0, x18\" : \"=r\" (tsk));\n\treturn tsk;\n}\n\nstatic inline void *asm_get_current_task_info(void)\n{\n\tvoid *tsk_info;\n\t__asm__ volatile (\"mov %0, x18\" : \"=r\" (tsk_info));\n\treturn tsk_info;\n}\n\nstatic inline void asm_set_current_task(void *task)\n{\n\t__asm__ volatile (\"mov x18, %0\" : : \"r\" (task));\n}\n\n#ifdef CONFIG_VIRT\nstatic inline void arch_set_pcpu_data(void *pcpu)\n{\n\t__asm__ volatile(\"msr TPIDR_EL2, %0\" : : \"r\" (pcpu));\n}\n\nstatic inline void *arch_get_pcpu_data(void)\n{\n\tuint64_t v;\n\t__asm__ volatile(\"mrs %0, TPIDR_EL2\" : \"=r\" (v));\n\treturn (void *)v;\n}\n\nstatic inline int __smp_processor_id(void)\n{\n\tuint64_t v;\n\tint cpu;\n\n\t__asm__ volatile (\n\t\t\"mrs\t%0, TPIDR_EL2\\n\"\n\t\t\"ldrh\t%w1, [%0, #0]\\n\"\n\t\t: \"=r\" (v), \"=r\" (cpu)\n\t\t:\n\t\t: \"memory\"\n\t);\n\n\treturn cpu;\n}\n#else\nstatic inline void arch_set_pcpu_data(void *pcpu)\n{\n\t__asm__ volatile(\"msr TPIDR_EL1, %0\" : : \"r\" (pcpu));\n}\n\nstatic inline void *arch_get_pcpu_data(void)\n{\n\tuint64_t v;\n\t__asm__ volatile(\"mrs %0, TPIDR_EL1\" : \"=r\" (v));\n\treturn (void *)v;\n}\n\nstatic inline int __smp_processor_id(void)\n{\n\tuint64_t v;\n\tint cpu;\n\n\t__asm__ volatile (\n\t\t\"mrs\t%0, TPIDR_EL1\\n\"\n\t\t\"ldrh\t%w1, [%0, #0]\\n\"\n\t\t: \"=r\" (v), \"=r\" (cpu)\n\t\t:\n\t\t: \"memory\"\n\t);\n\n\treturn cpu;\n}\n#endif\n\nstatic inline void arch_sys_sched(void)\n{\n\t__asm__ volatile(\"svc #0\");\n}\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/asm_marco.S",
    "content": "#ifndef _MINOS_ASM_MARCO_H_\n#define _MINOS_ASM_MARCO_H_\n\n#include <config/config.h>\n\n// current kernel and user space all used 512G virtual\n// address range, so:\n// ttbr0_el1 : 0x0000000000000000 - 0x00000007fffffffff\n// ttbr1_el1 : 0xfffffff800000000 - 0xfffffffffffffffff\n\n#ifdef CONFIG_ARM_ADDRESS_TAGGING\n.macro asm_vtop reg\n\tand\t\\reg, \\reg, #CONFIG_VTOP_MASK\n.endm\n\n.macro asm_ptov reg\n\torr\t\\reg, \\reg, #CONFIG_PTOV_MASK\n.endm\n#else\n.macro asm_vtop reg\n.endm\n\n.macro asm_ptov reg\n.endm\n#endif\n\n.macro func _name, align=2\n\t.cfi_sections .debug_frame\n\t.section __asm_code, \"ax\"\n\t.type \\_name, %function\n\t.func \\_name\n\t.cfi_startproc\n\t.align \\align\n\t\\_name:\n.endm\n\n.macro endfunc _name\n\t.endfunc\n\t.cfi_endproc\n\t.size \\_name, . - \\_name\n.endm\n\n.macro PRINT\n\tadr\tx0, 98f\n\tbl\tputs\n\tb\t99f\n98:     .asciz \"-------1\\r\\n\"\n\t.align 2\n99:\n.endm\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/asm_types.h",
    "content": "#ifndef _MINOS_AARCH64_TYPES_H_\n#define _MINOS_AARCH64_TYPES_H_\n\n#include <config/config.h>\n\ntypedef unsigned long\t\t__u64;\ntypedef unsigned int\t\t__u32;\ntypedef unsigned short\t\t__u16;\ntypedef unsigned char\t\t__u8;\ntypedef signed long\t\t__s64;\ntypedef signed int\t\t__s32;\ntypedef signed short\t\t__s16;\ntypedef signed char\t\t__s8;\n\n#ifndef __aarch64__\n#define __aarch64__\n#endif\n\n#ifdef CONFIG_ARM_ADDRESS_TAGGING\n#define ptov(addr)\t((unsigned long)(addr) | CONFIG_PTOV_MASK)\n#define vtop(addr)\t((unsigned long)(addr) & CONFIG_VTOP_MASK)\n#define __va(addr)\t((unsigned long)(addr) & CONFIG_VTOP_MASK)\n#define is_kva(va)\t(((unsigned long)(va) & CONFIG_PTOV_MASK) == CONFIG_PTOV_MASK)\n#else\n#define ptov(addr)\t((unsigned long)addr)\n#define vtop(addr)\t((unsigned long)addr)\n#define __va(va)\t((unsigned long)(va))\n#define is_kva(va)\t((unsigned long)va >= 4096)\n#endif\n\n/*\n * 512G for user space process\n */\n#define USER_PROCESS_ADDR_LIMIT\t\t(1UL << 39)\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/atomic.h",
    "content": "#ifndef __ASM_ATOMIC_H__\n#define __ASM_ATOMIC_H__\n\n#include <asm/aarch64_common.h>\n#include <minos/types.h>\n#include <asm/barrier.h>\n\nstatic inline int atomic_read(atomic_t *t)\n{\n\tsmp_mb();\n\treturn t->value;\n}\n\nstatic inline void atomic_set(int i, atomic_t *t)\n{\n\tt->value = i;\n\tsmp_mb();\n}\n\n#ifndef CONFIG_ARM_ATOMIC_LSE\n\nstatic inline void atomic_add(int i, atomic_t *v)\n{\n\tunsigned long tmp;\n\tint ret;\n\n\tasm volatile(\n\"1:\tldxr\t%w0, %2\\n\"\n\"\tadd\t%w0, %w0, %w3\\n\"\n\"\tstxr\t%w1, %w0, %2\\n\"\n\"\tcbnz\t%w1, 1b\"\n\t: \"=&r\" (ret), \"=&r\" (tmp), \"+Q\" (v->value)\n\t: \"Ir\" (i)\n\t);\n}\n\nstatic inline int atomic_add_return(int i, atomic_t *v)\n{\n\tunsigned long tmp;\n\tint ret;\n\n\tasm volatile(\n\"1:\tldxr\t%w0, %2\\n\"\n\"\tadd\t%w0, %w0, %w3\\n\"\n\"\tstlxr\t%w1, %w0, %2\\n\"\n\"\tcbnz\t%w1, 1b\"\n\t: \"=&r\" (ret), \"=&r\" (tmp), \"+Q\" (v->value)\n\t: \"Ir\" (i)\n\t: \"memory\"\n\t);\n\n\tsmp_mb();\n\treturn ret;\n}\n\nstatic inline int atomic_add_return_old(int i, atomic_t *v)\n{\n\tunsigned long tmp;\n\tint ret;\n\n\tasm volatile(\n\"1:\tldxr\t%w0, %2\\n\"\n\"\tadd\t%w0, %w0, %w3\\n\"\n\"\tstlxr\t%w1, %w0, %2\\n\"\n\"\tcbnz\t%w1, 1b\\n\"\n\"\tsub\t%w0, %w0, %w3\"\n\t: \"=&r\" (ret), \"=&r\" (tmp), \"+Q\" (v->value)\n\t: \"Ir\" (i)\n\t: \"memory\"\n\t);\n\n\tsmp_mb();\n\treturn ret;\n}\n\nstatic inline void atomic_sub(int i, atomic_t *v)\n{\n\tunsigned long tmp;\n\tint ret;\n\n\tasm volatile(\n\"1:\tldxr\t%w0, %2\\n\"\n\"\tsub\t%w0, %w0, %w3\\n\"\n\"\tstlxr\t%w1, %w0, %2\\n\"\n\"\tcbnz\t%w1, 1b\"\n\t: \"=&r\" (ret), \"=&r\" (tmp), \"+Q\" (v->value)\n\t: \"Ir\" (i)\n\t);\n}\n\nstatic inline int atomic_sub_return(int i, atomic_t *v)\n{\n\tunsigned long tmp;\n\tint ret;\n\n\tasm volatile(\n\"1:\tldaxr\t%w0, %2\\n\"\n\"\tsub\t%w0, %w0, %w3\\n\"\n\"\tstlxr\t%w1, %w0, %2\\n\"\n\"\tcbnz\t%w1, 1b\"\n\t: \"=&r\" (ret), \"=&r\" (tmp), \"+Q\" (v->value)\n\t: \"Ir\" (i)\n\t: \"memory\"\n\t);\n\n\tsmp_mb();\n\treturn ret;\n}\n\nstatic inline int atomic_sub_return_old(int i, atomic_t *v)\n{\n\tunsigned long tmp;\n\tint ret;\n\n\tasm volatile(\n\"1:\tldaxr\t%w0, %2\\n\"\n\"\tsub\t%w0, %w0, %w3\\n\"\n\"\tstlxr\t%w1, %w0, %2\\n\"\n\"\tcbnz\t%w1, 1b\\n\"\n\"\tadd\t%w0, %w0, %w3\"\n\t: \"=&r\" (ret), \"=&r\" (tmp), \"+Q\" (v->value)\n\t: \"Ir\" (i)\n\t: \"memory\"\n\t);\n\n\treturn ret;\n}\n\nstatic inline int atomic_cmpxchg(atomic_t *t, int old, int new)\n{\n\tunsigned long tmp;\n\tint oldval;\n\n\tsmp_mb();\n\n\tasm volatile(\n\"1:\tldxr\t%w1, %2\\n\"\n\"\tcmp\t%w1, %w3\\n\"\n\"\tb.ne\t2f\\n\"\n\"\tstxr\t%w0, %w4, %2\\n\"\n\"\tcbnz\t%w0, 1b\\n\"\n\"2:\t\t\t\"\n\t: \"=&r\" (tmp), \"=&r\" (oldval), \"+Q\" (t->value)\n\t: \"Ir\" (old), \"r\" (new)\n\t: \"cc\"\n\t);\n\n\tsmp_mb();\n\treturn oldval;\n}\n\nstatic inline int atomic_inc_if_postive(atomic_t *t)\n{\n\tunsigned long tmp;\n\tint oldval;\n\tint value;\n\n\tsmp_mb();\n\n\tasm volatile(\n\"1:\tldxr\t%w1, %2\\n\"\n\"\tcmp\t%w1, #0\\n\"\n\"\tb.lt\t2f\\n\"\n\"\tadd\t%w3, %w1, #1\\n\"\n\"\tstxr\t%w0, %w3, %2\\n\"\n\"\tcbnz\t%w0, 1b\\n\"\n\"2:\t\t\t\"\n\t: \"=&r\" (tmp), \"=&r\" (oldval), \"+Q\" (t->value), \"=&r\" (value)\n\t:\n\t: \"cc\"\n\t);\n\n\tsmp_mb();\n\treturn oldval;\n}\n\nstatic inline int atomic_dec_set_negtive_if_zero(atomic_t *t)\n{\n\tunsigned long tmp;\n\tint oldval;\n\tint value;\n\n\tsmp_mb();\n\n\tasm volatile(\n\"1:\tldxr\t%w1, %2\\n\"\n\"\tcmp\t%w1, #0\\n\"\n\"\tb.le\t2f\\n\"\n\"\tsub\t%w3, %w1, #1\\n\"\n\"\tcmp\t%w3, #0\\n\"\n\"\tb.ne\t3f\\n\"\n\"\tsub\t%w3, %w3, #1\\n\"\t// set the value to -1 if new value is -1\n\"3:\t\t\"\n\"\tstxr\t%w0, %w3, %2\\n\"\n\"\tcbnz\t%w0, 1b\\n\"\n\"2:\t\t\t\"\n\t: \"=&r\" (tmp), \"=&r\" (oldval), \"+Q\" (t->value), \"=&r\" (value)\n\t:\n\t: \"cc\"\n\t);\n\n\tsmp_mb();\n\treturn oldval;\n}\n\nstatic inline int atomic_cmpsub(atomic_t *t, int old, int value)\n{\n\tunsigned long tmp;\n\tint oldval;\n\n\tsmp_mb();\n\n\tasm volatile(\n\"1:\tldxr\t%w1, %2\\n\"\n\"\tcmp\t%w1, %w3\\n\"\n\"\tsub\t%w4, %w1, %4\\n\"\n\"\tb.eq\t2f\\n\"\n\"\tstxr\t%w0, %w4, %2\\n\"\n\"\tcbnz\t%w0, 1b\\n\"\n\"2:\t\t\t\"\n\t: \"=&r\" (tmp), \"=&r\" (oldval), \"+Q\" (t->value)\n\t: \"Ir\" (old), \"r\" (value)\n\t: \"cc\"\n\t);\n\n\tsmp_mb();\n\treturn oldval;\n}\n\n#else\n\n#define ATOMIC_OP(op, asm_op)\t\t\t\t\\\nstatic inline void atomic_##op(int i, atomic_t *t)\t\\\n{\t\t\t\t\t\t\t\\\n\tregister int w0 asm (\"w0\") = i;\t\t\t\\\n\tregister atomic_t *x1 asm (\"x1\") = t;\t\t\\\n\t\t\t\t\t\t\t\\\n\tasm volatile (\t\t\t\t\t\\\n\"\t\" #asm_op \"\t%w[i], %[v]\\n\"\t\t\t\\\n\t: [i] \"+r\" (w0), [v] \"+Q\" (t->value)\t\t\\\n\t: \"r\" (x1)\t\t\t\t\t\\\n\t: \"x16\", \"x17\", \"x30\"\t\t\t\t\\\n\t);\t\t\t\t\t\t\\\n}\n\nATOMIC_OP(andnot, stclr)\nATOMIC_OP(or, stset)\nATOMIC_OP(xor, steor)\nATOMIC_OP(add, stadd)\n\n#define ATOMIC_OP_ADD_RETURN(name, mb, cl...)\t\t\t\t\\\nstatic inline int atomic_add_return##name(int i, atomic_t *v)\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\tregister int w0 asm (\"w0\") = i;\t\t\t\t\t\\\n\tregister atomic_t *x1 asm (\"x1\") = v;\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tasm volatile(\t\t\t\t\t\t\t\\\n\t\"\tldadd\" #mb \"\t%w[i], w30, %[v]\\n\"\t\t\t\\\n\t\"\tadd\t%w[i], %w[i], w30\"\t\t\t\t\\\n\t: [i] \"+r\" (w0), [v] \"+Q\" (v->value)\t\t\t\t\\\n\t: \"r\" (x1)\t\t\t\t\t\t\t\\\n\t: \"x16\", \"x17\", \"x30\", ##cl\t\t\t\t\t\\\n\t);\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\treturn w0;\t\t\t\t\t\t\t\\\n}\n\nstatic inline int atomic_add_return_old(int i, atomic_t *v)\n{\n\tregister int w0 asm (\"w0\") = i;\n\tregister atomic_t *x1 asm (\"x1\") = v;\n\n\tasm volatile(\n\"\tldaddal %w[i], w30, %[v]\\n\"\n\"\tadd\t%w[i], %w[i], w30\"\n\t: [i] \"+r\" (w0), [v] \"+Q\" (v->value)\n\t: \"r\" (x1)\n\t: \"x16\", \"x17\", \"x30\", \"memory\"\n\t);\n\n\treturn w0;\n}\n\nATOMIC_OP_ADD_RETURN(_relaxed,   )\nATOMIC_OP_ADD_RETURN(_acquire,  a, \"memory\")\nATOMIC_OP_ADD_RETURN(_release,  l, \"memory\")\nATOMIC_OP_ADD_RETURN(        , al, \"memory\")\n\nstatic inline void atomic_sub(int i, atomic_t *v)\n{\n\tregister int w0 asm (\"w0\") = i;\n\tregister atomic_t *x1 asm (\"x1\") = v;\n\n\tasm volatile(\n\t\"\tneg\t%w[i], %w[i]\\n\"\n\t\"\tstadd\t%w[i], %[v]\"\n\t: [i] \"+&r\" (w0), [v] \"+Q\" (v->value)\n\t: \"r\" (x1)\n\t: \"x16\", \"x17\", \"x30\"\n\t);\n}\n\n#define ATOMIC_OP_SUB_RETURN(name, mb, cl...)\t\t\t\t\\\nstatic inline int atomic_sub_return##name(int i, atomic_t *v)\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\tregister int w0 asm (\"w0\") = i;\t\t\t\t\t\\\n\tregister atomic_t *x1 asm (\"x1\") = v;\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tasm volatile(\t\t\t\t\t\t\t\\\n\"\tneg\t%w[i], %w[i]\\n\"\t\t\t\t\t\t\\\n\"\tldadd\" #mb \"\t%w[i], w30, %[v]\\n\"\t\t\t\t\\\n\"\tadd\t%w[i], %w[i], w30\"\t\t\t\t\t\\\n\t: [i] \"+&r\" (w0), [v] \"+Q\" (v->value)\t\t\t\t\\\n\t: \"r\" (x1)\t\t\t\t\t\t\t\\\n\t: \"x16\", \"x17\", \"x30\", ##cl);\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\treturn w0;\t\t\t\t\t\t\t\\\n}\n\nATOMIC_OP_SUB_RETURN(_relaxed,   )\nATOMIC_OP_SUB_RETURN(_acquire,  a, \"memory\")\nATOMIC_OP_SUB_RETURN(_release,  l, \"memory\")\nATOMIC_OP_SUB_RETURN(        , al, \"memory\")\n\nstatic inline int atomic_sub_return_old(int i, atomic_t *v)\n{\n\tregister int w0 asm (\"w0\") = i;\n\tregister atomic_t *x1 asm (\"x1\") = v;\n\n\tasm volatile(\n\"\tneg\t%w[i], %w[i]\\n\"\n\"\tldaddal %w[i], w30, %[v]\"\n\t: [i] \"+&r\" (w0), [v] \"+Q\" (v->value)\n\t: \"r\" (x1)\n\t: \"x16\", \"x17\", \"x30\", \"memory\");\n\n\treturn w0;\n}\n\n#define __CMPXCHG_CASE(w, sz, name, mb, cl...)\t\t\t\t\\\nstatic inline unsigned long __cmpxchg_case_##name(volatile void *ptr,\t\\\n\t\t\t\t\t\t  unsigned long old,\t\\\n\t\t\t\t\t\t  unsigned long new)\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\tregister unsigned long x0 asm (\"x0\") = (unsigned long)ptr;\t\\\n\tregister unsigned long x1 asm (\"x1\") = old;\t\t\t\\\n\tregister unsigned long x2 asm (\"x2\") = new;\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tasm volatile(\t\t\t\t\t\t\t\\\n\"\tmov\t\" #w \"30, %\" #w \"[old]\\n\"\t\t\t\t\\\n\"\tcas\" #mb #sz \"\\t\" #w \"30, %\" #w \"[new], %[v]\\n\"\t\t\t\\\n\"\tmov\t%\" #w \"[ret], \" #w \"30\"\t\t\t\t\t\\\n\t: [ret] \"+r\" (x0), [v] \"+Q\" (*(unsigned long *)ptr)\t\t\\\n\t: [old] \"r\" (x1), [new] \"r\" (x2)\t\t\t\t\\\n\t: \"x16\", \"x17\", \"x30\", ##cl);\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\treturn x0;\t\t\t\t\t\t\t\\\n}\n\n__CMPXCHG_CASE(w, b,     1,   )\n__CMPXCHG_CASE(w, h,     2,   )\n__CMPXCHG_CASE(w,  ,     4,   )\n__CMPXCHG_CASE(x,  ,     8,   )\n__CMPXCHG_CASE(w, b, acq_1,  a, \"memory\")\n__CMPXCHG_CASE(w, h, acq_2,  a, \"memory\")\n__CMPXCHG_CASE(w,  , acq_4,  a, \"memory\")\n__CMPXCHG_CASE(x,  , acq_8,  a, \"memory\")\n__CMPXCHG_CASE(w, b, rel_1,  l, \"memory\")\n__CMPXCHG_CASE(w, h, rel_2,  l, \"memory\")\n__CMPXCHG_CASE(w,  , rel_4,  l, \"memory\")\n__CMPXCHG_CASE(x,  , rel_8,  l, \"memory\")\n__CMPXCHG_CASE(w, b,  mb_1, al, \"memory\")\n__CMPXCHG_CASE(w, h,  mb_2, al, \"memory\")\n__CMPXCHG_CASE(w,  ,  mb_4, al, \"memory\")\n__CMPXCHG_CASE(x,  ,  mb_8, al, \"memory\")\n\n#endif // CONFIG_ARM_ATOMIC_LSE\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/barrier.h",
    "content": "#ifndef __MINOS_ASM_BARRIER_H__\n#define __MINOS_ASM_BARRIER_H__\n\n#define __isb()\t\tasm volatile(\"isb\" : : : \"memory\")\n#define __dmb(opt)\tasm volatile(\"dmb \" #opt : : : \"memory\")\n#define __dsb(opt)\tasm volatile(\"dsb \" #opt : : : \"memory\")\n\n#define isb()\t\t__isb();\n\n#define mb()\t\t__dsb(sy)\n#define rmb()\t\t__dsb(ld)\n#define wmb()\t\t__dsb(st)\n\n#define dma_rmb()\t__dmb(oshld)\n#define dma_wmb()\t__dmb(oshst)\n\n#define iormb()\t\tdma_rmb()\n#define iowmb()\t\tdma_wmb()\n\n#define smp_mb()\t__dmb(ish)\n#define smp_rmb()\t__dmb(ishld)\n#define smp_wmb()\t__dmb(ishst)\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/bitops.h",
    "content": "#ifndef _ASM_GENERIC_BITOPS_H_\n#define _ASM_GENERIC_BITOPS_H_\n\n#include <minos/types.h>\n\n/**\n * __ffs - find first bit in word.\n * @word: The word to search\n *\n * Undefined if no bit exists, so code should check against 0 first.\n */\nstatic inline unsigned long __ffs(unsigned long word)\n{\n\tint num = 0;\n\n#if BITS_PER_LONG == 64\n\tif ((word & 0xffffffff) == 0) {\n\t\tnum += 32;\n\t\tword >>= 32;\n\t}\n#endif\n\tif ((word & 0xffff) == 0) {\n\t\tnum += 16;\n\t\tword >>= 16;\n\t}\n\tif ((word & 0xff) == 0) {\n\t\tnum += 8;\n\t\tword >>= 8;\n\t}\n\tif ((word & 0xf) == 0) {\n\t\tnum += 4;\n\t\tword >>= 4;\n\t}\n\tif ((word & 0x3) == 0) {\n\t\tnum += 2;\n\t\tword >>= 2;\n\t}\n\tif ((word & 0x1) == 0)\n\t\tnum += 1;\n\treturn num;\n}\n\nstatic inline unsigned long __fls(unsigned long word)\n{\n\tint num = BITS_PER_LONG - 1;\n\n#if BITS_PER_LONG == 64\n\tif (!(word & (~0ul << 32))) {\n\t\tnum -= 32;\n\t\tword <<= 32;\n\t}\n#endif\n\tif (!(word & (~0ul << (BITS_PER_LONG-16)))) {\n\t\tnum -= 16;\n\t\tword <<= 16;\n\t}\n\tif (!(word & (~0ul << (BITS_PER_LONG-8)))) {\n\t\tnum -= 8;\n\t\tword <<= 8;\n\t}\n\tif (!(word & (~0ul << (BITS_PER_LONG-4)))) {\n\t\tnum -= 4;\n\t\tword <<= 4;\n\t}\n\tif (!(word & (~0ul << (BITS_PER_LONG-2)))) {\n\t\tnum -= 2;\n\t\tword <<= 2;\n\t}\n\tif (!(word & (~0ul << (BITS_PER_LONG-1))))\n\t\tnum -= 1;\n\treturn num;\n}\n\n\nstatic inline int fls(int x)\n{\n\tint r = 32;\n\n\tif (!x)\n\t\treturn 0;\n\tif (!(x & 0xffff0000u)) {\n\t\tx <<= 16;\n\t\tr -= 16;\n\t}\n\tif (!(x & 0xff000000u)) {\n\t\tx <<= 8;\n\t\tr -= 8;\n\t}\n\tif (!(x & 0xf0000000u)) {\n\t\tx <<= 4;\n\t\tr -= 4;\n\t}\n\tif (!(x & 0xc0000000u)) {\n\t\tx <<= 2;\n\t\tr -= 2;\n\t}\n\tif (!(x & 0x80000000u)) {\n\t\tx <<= 1;\n\t\tr -= 1;\n\t}\n\treturn r;\n}\n\n#if BITS_PER_LONG == 32\nstatic inline int fls64(__u64 x)\n{\n\t__u32 h = x >> 32;\n\tif (h)\n\t\treturn fls(h) + 32;\n\treturn fls(x);\n}\n#elif BITS_PER_LONG == 64\nstatic inline int fls64(__u64 x)\n{\n\tif (x == 0)\n\t\treturn 0;\n\treturn __fls(x) + 1;\n}\n#else\n#error BITS_PER_LONG not 32 or 64\n#endif\n\n#define ffz(x)  __ffs(~(x))\n\n#endif /* _ASM_GENERIC_BITOPS___FFS_H_ */\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/cache.h",
    "content": "#ifndef __MINOS_AARCH64_CACHE_H__\n#define __MINOS_AARCH64_CACHE_H__\n\nvoid flush_dcache_range(unsigned long addr, size_t size);\nvoid inv_dcache_range(unsigned long addr, size_t size);\nvoid flush_cache_all(void);\nvoid flush_dcache_all(void);\nvoid inv_dcache_all(void);\n\nstatic inline void inv_icache_local(void)\n{\n\tasm volatile(\"ic iallu\");\n\tdsbsy();\n\tisb();\n}\n\nstatic inline void inv_icache_all(void)\n{\n\tasm volatile(\"ic ialluis\");\n\tdsbsy();\n}\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/cmpxchg.h",
    "content": "/*\n * Based on arch/arm/include/asm/cmpxchg.h\n *\n * Copyright (C) 2012 ARM Ltd.\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef __ASM_CMPXCHG_H__\n#define __ASM_CMPXCHG_H__\n\n#ifndef CONFIG_ARM_ATOMIC_LSE\n#define __XCHG_CASE(w, sz, name, mb, nop_lse, acq, acq_lse, rel, cl)\t\\\nstatic inline unsigned long __xchg_case_##name(unsigned long x,\t\t\\\n\t\t\t\t\t       volatile void *ptr)\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\tunsigned long ret, tmp;\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tasm volatile (\t\t\t\t\t\t\t\\\n\t\"\tprfm\tpstl1strm, %2\\n\"\t\t\t\t\\\n\t\"1:\tld\" #acq \"xr\" #sz \"\\t%\" #w \"0, %2\\n\"\t\t\t\\\n\t\"\tst\" #rel \"xr\" #sz \"\\t%w1, %\" #w \"3, %2\\n\"\t\t\\\n\t\"\tcbnz\t%w1, 1b\\n\"\t\t\t\t\t\\\n\t\"\t\" #mb\t\t\t\t\t\t\t\\\n\t: \"=&r\" (ret), \"=&r\" (tmp), \"+Q\" (*(u8 *)ptr)\t\t\t\\\n\t: \"r\" (x)\t\t\t\t\t\t\t\\\n\t: cl);\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\treturn ret;\t\t\t\t\t\t\t\\\n}\n\n#define __CMPXCHG_CASE(w, sz, name, mb, acq, rel, cl)\t\t\t\\\nstatic inline unsigned long __cmpxchg_case_##name(volatile void *ptr,\t\\\n\t\t\t\t     unsigned long old,\t\t\t\\\n\t\t\t\t     unsigned long new)\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\tunsigned long tmp, oldval;\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tasm volatile(\t\t\t\t\t\t\t\\\n\t\"\tprfm\tpstl1strm, %[v]\\n\"\t\t\t\t\\\n\t\"1:\tld\" #acq \"xr\" #sz \"\\t%\" #w \"[oldval], %[v]\\n\"\t\t\\\n\t\"\teor\t%\" #w \"[tmp], %\" #w \"[oldval], %\" #w \"[old]\\n\"\t\\\n\t\"\tcbnz\t%\" #w \"[tmp], 2f\\n\"\t\t\t\t\\\n\t\"\tst\" #rel \"xr\" #sz \"\\t%w[tmp], %\" #w \"[new], %[v]\\n\"\t\\\n\t\"\tcbnz\t%w[tmp], 1b\\n\"\t\t\t\t\t\\\n\t\"\t\" #mb \"\\n\"\t\t\t\t\t\t\\\n\t\"\tmov\t%\" #w \"[oldval], %\" #w \"[old]\\n\"\t\t\\\n\t\"2:\"\t\t\t\t\t\t\t\t\\\n\t: [tmp] \"=&r\" (tmp), [oldval] \"=&r\" (oldval),\t\t\t\\\n\t  [v] \"+Q\" (*(unsigned long *)ptr)\t\t\t\t\\\n\t: [old] \"Lr\" (old), [new] \"r\" (new)\t\t\t\t\\\n\t: cl);\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\treturn oldval;\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\n\n__CMPXCHG_CASE(w, b,     1,        ,  ,  ,         )\n__CMPXCHG_CASE(w, h,     2,        ,  ,  ,         )\n__CMPXCHG_CASE(w,  ,     4,        ,  ,  ,         )\n__CMPXCHG_CASE( ,  ,     8,        ,  ,  ,         )\n__CMPXCHG_CASE(w, b, acq_1,        , a,  , \"memory\")\n__CMPXCHG_CASE(w, h, acq_2,        , a,  , \"memory\")\n__CMPXCHG_CASE(w,  , acq_4,        , a,  , \"memory\")\n__CMPXCHG_CASE( ,  , acq_8,        , a,  , \"memory\")\n__CMPXCHG_CASE(w, b, rel_1,        ,  , l, \"memory\")\n__CMPXCHG_CASE(w, h, rel_2,        ,  , l, \"memory\")\n__CMPXCHG_CASE(w,  , rel_4,        ,  , l, \"memory\")\n__CMPXCHG_CASE( ,  , rel_8,        ,  , l, \"memory\")\n__CMPXCHG_CASE(w, b,  mb_1, dmb ish,  , l, \"memory\")\n__CMPXCHG_CASE(w, h,  mb_2, dmb ish,  , l, \"memory\")\n__CMPXCHG_CASE(w,  ,  mb_4, dmb ish,  , l, \"memory\")\n__CMPXCHG_CASE( ,  ,  mb_8, dmb ish,  , l, \"memory\")\n\n#else\n#define __XCHG_CASE(w, sz, name, mb, nop_lse, acq, acq_lse, rel, cl)\t\\\nstatic inline unsigned long __xchg_case_##name(unsigned long x,\t\t\\\n\t\t\t\t\t       volatile void *ptr)\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\tunsigned long ret;\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tasm volatile (\t\t\t\t\t\t\t\\\n\t\"\tnop\\n\"\t\t\t\t\t\t\t\\\n\t\"\tnop\\n\"\t\t\t\t\t\t\t\\\n\t\"\tswp\" #acq_lse #rel #sz \"\\t%\" #w \"3, %\" #w \"0, %2\\n\"\t\\\n\t\"\tnop\\n\"\t\t\t\t\t\t\t\\\n\t\"\t\" #nop_lse\t\t\t\t\t\t\\\n\t: \"=&r\" (ret), \"=&r\" (tmp), \"+Q\" (*(u8 *)ptr)\t\t\t\\\n\t: \"r\" (x)\t\t\t\t\t\t\t\\\n\t: cl);\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\treturn ret;\t\t\t\t\t\t\t\\\n}\n\n#define __CMPXCHG_CASE(w, sz, name, mb, cl...)\t\t\t\t\\\nstatic inline unsigned long __cmpxchg_case_##name(volatile void *ptr,\t\\\n\t\t\t\t\t\t  unsigned long old,\t\\\n\t\t\t\t\t\t  unsigned long new)\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\tregister unsigned long x0 asm (\"x0\") = (unsigned long)ptr;\t\\\n\tregister unsigned long x1 asm (\"x1\") = old;\t\t\t\\\n\tregister unsigned long x2 asm (\"x2\") = new;\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tasm volatile (\t\t\t\t\t\t\t\\\n\t\"\tmov\t\" #w \"30, %\" #w \"[old]\\n\"\t\t\t\\\n\t\"\tcas\" #mb #sz \"\\t\" #w \"30, %\" #w \"[new], %[v]\\n\"\t\t\\\n\t\"\tmov\t%\" #w \"[ret], \" #w \"30\")\t\t\t\\\n\t: [ret] \"+r\" (x0), [v] \"+Q\" (*(unsigned long *)ptr)\t\t\\\n\t: [old] \"r\" (x1), [new] \"r\" (x2)\t\t\t\t\\\n\t: \"x30\" , ##cl;\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\treturn x0;\t\t\t\t\t\t\t\\\n}\n\n__CMPXCHG_CASE(w, b,     1,   )\n__CMPXCHG_CASE(w, h,     2,   )\n__CMPXCHG_CASE(w,  ,     4,   )\n__CMPXCHG_CASE(x,  ,     8,   )\n__CMPXCHG_CASE(w, b, acq_1,  a, \"memory\")\n__CMPXCHG_CASE(w, h, acq_2,  a, \"memory\")\n__CMPXCHG_CASE(w,  , acq_4,  a, \"memory\")\n__CMPXCHG_CASE(x,  , acq_8,  a, \"memory\")\n__CMPXCHG_CASE(w, b, rel_1,  l, \"memory\")\n__CMPXCHG_CASE(w, h, rel_2,  l, \"memory\")\n__CMPXCHG_CASE(w,  , rel_4,  l, \"memory\")\n__CMPXCHG_CASE(x,  , rel_8,  l, \"memory\")\n__CMPXCHG_CASE(w, b,  mb_1, al, \"memory\")\n__CMPXCHG_CASE(w, h,  mb_2, al, \"memory\")\n__CMPXCHG_CASE(w,  ,  mb_4, al, \"memory\")\n__CMPXCHG_CASE(x,  ,  mb_8, al, \"memory\")\n\n#endif // CONFIG_ARM_ATOMIC_LSE\n\n__XCHG_CASE(w, b,     1,        ,    ,  ,  ,  ,         )\n__XCHG_CASE(w, h,     2,        ,    ,  ,  ,  ,         )\n__XCHG_CASE(w,  ,     4,        ,    ,  ,  ,  ,         )\n__XCHG_CASE( ,  ,     8,        ,    ,  ,  ,  ,         )\n__XCHG_CASE(w, b, acq_1,        ,    , a, a,  , \"memory\")\n__XCHG_CASE(w, h, acq_2,        ,    , a, a,  , \"memory\")\n__XCHG_CASE(w,  , acq_4,        ,    , a, a,  , \"memory\")\n__XCHG_CASE( ,  , acq_8,        ,    , a, a,  , \"memory\")\n__XCHG_CASE(w, b, rel_1,        ,    ,  ,  , l, \"memory\")\n__XCHG_CASE(w, h, rel_2,        ,    ,  ,  , l, \"memory\")\n__XCHG_CASE(w,  , rel_4,        ,    ,  ,  , l, \"memory\")\n__XCHG_CASE( ,  , rel_8,        ,    ,  ,  , l, \"memory\")\n__XCHG_CASE(w, b,  mb_1, dmb ish, nop,  , a, l, \"memory\")\n__XCHG_CASE(w, h,  mb_2, dmb ish, nop,  , a, l, \"memory\")\n__XCHG_CASE(w,  ,  mb_4, dmb ish, nop,  , a, l, \"memory\")\n__XCHG_CASE( ,  ,  mb_8, dmb ish, nop,  , a, l, \"memory\")\n\n#undef __XCHG_CASE\n\n#define __XCHG_GEN(sfx)\t\t\t\t\t\t\t\\\nstatic inline unsigned long __xchg##sfx(unsigned long x,\t\t\\\n\t\t\t\t\tvolatile void *ptr,\t\t\\\n\t\t\t\t\tint size)\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\tswitch (size) {\t\t\t\t\t\t\t\\\n\tcase 1:\t\t\t\t\t\t\t\t\\\n\t\treturn __xchg_case##sfx##_1(x, ptr);\t\t\t\\\n\tcase 2:\t\t\t\t\t\t\t\t\\\n\t\treturn __xchg_case##sfx##_2(x, ptr);\t\t\t\\\n\tcase 4:\t\t\t\t\t\t\t\t\\\n\t\treturn __xchg_case##sfx##_4(x, ptr);\t\t\t\\\n\tcase 8:\t\t\t\t\t\t\t\t\\\n\t\treturn __xchg_case##sfx##_8(x, ptr);\t\t\t\\\n\tdefault:\t\t\t\t\t\t\t\\\n\t\treturn 0;\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n}\n\n__XCHG_GEN()\n__XCHG_GEN(_acq)\n__XCHG_GEN(_rel)\n__XCHG_GEN(_mb)\n\n#undef __XCHG_GEN\n\n#define __xchg_wrapper(sfx, ptr, x)\t\t\t\t\t\\\n({\t\t\t\t\t\t\t\t\t\\\n\t__typeof__(*(ptr)) __ret;\t\t\t\t\t\\\n\t__ret = (__typeof__(*(ptr)))\t\t\t\t\t\\\n\t\t__xchg##sfx((unsigned long)(x), (ptr), sizeof(*(ptr))); \\\n\t__ret;\t\t\t\t\t\t\t\t\\\n})\n\n/* xchg */\n#define xchg_relaxed(...)\t__xchg_wrapper(    , __VA_ARGS__)\n#define xchg_acquire(...)\t__xchg_wrapper(_acq, __VA_ARGS__)\n#define xchg_release(...)\t__xchg_wrapper(_rel, __VA_ARGS__)\n#define xchg(...)\t\t__xchg_wrapper( _mb, __VA_ARGS__)\n\n#define __CMPXCHG_GEN(sfx)\t\t\t\t\t\t\\\nstatic inline unsigned long __cmpxchg##sfx(volatile void *ptr,\t\t\\\n\t\t\t\t\t   unsigned long old,\t\t\\\n\t\t\t\t\t   unsigned long new,\t\t\\\n\t\t\t\t\t   int size)\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\tswitch (size) {\t\t\t\t\t\t\t\\\n\tcase 1:\t\t\t\t\t\t\t\t\\\n\t\treturn __cmpxchg_case##sfx##_1(ptr, (u8)old, new);\t\\\n\tcase 2:\t\t\t\t\t\t\t\t\\\n\t\treturn __cmpxchg_case##sfx##_2(ptr, (u16)old, new);\t\\\n\tcase 4:\t\t\t\t\t\t\t\t\\\n\t\treturn __cmpxchg_case##sfx##_4(ptr, old, new);\t\t\\\n\tcase 8:\t\t\t\t\t\t\t\t\\\n\t\treturn __cmpxchg_case##sfx##_8(ptr, old, new);\t\t\\\n\tdefault:\t\t\t\t\t\t\t\\\n\t\treturn 0;\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n}\n\n__CMPXCHG_GEN()\n__CMPXCHG_GEN(_acq)\n__CMPXCHG_GEN(_rel)\n__CMPXCHG_GEN(_mb)\n\n#undef __CMPXCHG_GEN\n\n#define __cmpxchg_wrapper(sfx, ptr, o, n)\t\t\t\t\\\n({\t\t\t\t\t\t\t\t\t\\\n\t__typeof__(*(ptr)) __ret;\t\t\t\t\t\\\n\t__ret = (__typeof__(*(ptr)))\t\t\t\t\t\\\n\t\t__cmpxchg##sfx((ptr), (unsigned long)(o),\t\t\\\n\t\t\t\t(unsigned long)(n), sizeof(*(ptr)));\t\\\n\t__ret;\t\t\t\t\t\t\t\t\\\n})\n\n/* cmpxchg */\n#define cmpxchg_relaxed(...)\t__cmpxchg_wrapper(    , __VA_ARGS__)\n#define cmpxchg_acquire(...)\t__cmpxchg_wrapper(_acq, __VA_ARGS__)\n#define cmpxchg_release(...)\t__cmpxchg_wrapper(_rel, __VA_ARGS__)\n#define cmpxchg(...)\t\t__cmpxchg_wrapper( _mb, __VA_ARGS__)\n#define cmpxchg_local\t\tcmpxchg_relaxed\n\n/* cmpxchg64 */\n#define cmpxchg64_relaxed\tcmpxchg_relaxed\n#define cmpxchg64_acquire\tcmpxchg_acquire\n#define cmpxchg64_release\tcmpxchg_release\n#define cmpxchg64\t\tcmpxchg\n#define cmpxchg64_local\t\tcmpxchg_local\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/cpu_feature.h",
    "content": "#ifndef __MINOS_CPU_FEATURE_H__\n#define __MINOS_CPU_FEATURE_H__\n\n#define ARM_FEATURE_MPIDR_SHIFT\t0\n\nint cpu_has_feature(int feature);\nint cpu_has_vhe(void);\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/div64.h",
    "content": "#ifndef _ASM_GENERIC_DIV64_H\n#define _ASM_GENERIC_DIV64_H\n/*\n * Copyright (C) 2003 Bernardo Innocenti <bernie@develer.com>\n * Based on former asm-ppc/div64.h and asm-m68knommu/div64.h\n *\n * The semantics of do_div() are:\n *\n * uint32_t do_div(uint64_t *n, uint32_t base)\n * {\n * \tuint32_t remainder = *n % base;\n * \t*n = *n / base;\n * \treturn remainder;\n * }\n *\n * NOTE: macro parameter n is evaluated multiple times,\n *       beware of side effects!\n */\n\n#include <minos/types.h>\n\n#if BITS_PER_LONG == 64\n\n# define do_div(n,base) ({\t\t\t\t\t\\\n\tuint32_t __base = (base);\t\t\t\t\\\n\tuint32_t __rem;\t\t\t\t\t\t\\\n\t__rem = ((uint64_t)(n)) % __base;\t\t\t\\\n\t(n) = ((uint64_t)(n)) / __base;\t\t\t\t\\\n\t__rem;\t\t\t\t\t\t\t\\\n })\n\n#elif BITS_PER_LONG == 32\n\nextern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor);\n\n/* The unnecessary pointer compare is there\n * to check for type safety (n must be 64bit)\n */\n# define do_div(n,base) ({\t\t\t\t\\\n\tuint32_t __base = (base);\t\t\t\\\n\tuint32_t __rem;\t\t\t\t\t\\\n\t(void)(((typeof((n)) *)0) == ((uint64_t *)0));\t\\\n\tif (likely(((n) >> 32) == 0)) {\t\t\t\\\n\t\t__rem = (uint32_t)(n) % __base;\t\t\\\n\t\t(n) = (uint32_t)(n) / __base;\t\t\\\n\t} else \t\t\t\t\t\t\\\n\t\t__rem = __div64_32(&(n), __base);\t\\\n\t__rem;\t\t\t\t\t\t\\\n })\n\n#else /* BITS_PER_LONG == ?? */\n\n# error do_div() does not yet support the C64\n\n#endif /* BITS_PER_LONG */\n\n#endif /* _ASM_GENERIC_DIV64_H */\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/gic_reg.h",
    "content": "#ifndef _MINOS_GIC_REG_H_\n#define _MINOS_GIC_REG_H_\n\n/*\n * Mapping of MSR and MRS to physical and virtual CPU interface registers\n *\n * ARM Generic Interrupt Controller Architecture Specification\n * GIC architecture version 3.0 and version 4.0\n * Table 8-5\n */\n#define ICC_AP0R0_EL1       S3_0_C12_C8_4\n#define ICC_AP0R1_EL1       S3_0_C12_C8_5\n#define ICC_AP0R2_EL1       S3_0_C12_C8_6\n#define ICC_AP0R3_EL1       S3_0_C12_C8_7\n\n#define ICC_AP1R0_EL1       S3_0_C12_C9_0\n#define ICC_AP1R1_EL1       S3_0_C12_C9_1\n#define ICC_AP1R2_EL1       S3_0_C12_C9_2\n#define ICC_AP1R3_EL1       S3_0_C12_C9_3\n\n#define ICC_ASGI1R_EL1      S3_0_C12_C11_6\n\n#define ICC_BPR0_EL1        S3_0_C12_C8_3\n#define ICC_BPR1_EL1        S3_0_C12_C12_3\n\n#define ICC_CTLR_EL1        S3_0_C12_C12_4\n#define ICC_CTLR_EL3        S3_6_C12_C12_4\n\n#define ICC_DIR_EL1         S3_0_C12_C11_1\n\n#define ICC_EOIR0_EL1       S3_0_C12_C8_1\n#define ICC_EOIR1_EL1       S3_0_C12_C12_1\n\n#define ICC_HPPIR0_EL1      S3_0_C12_C8_2\n#define ICC_HPPIR1_EL1      S3_0_C12_C12_2\n\n#define ICC_IAR0_EL1        S3_0_C12_C8_0\n#define ICC_IAR1_EL1        S3_0_C12_C12_0\n\n#define ICC_IGRPEN0_EL1     S3_0_C12_C12_6\n#define ICC_IGRPEN1_EL1     S3_0_C12_C12_7\n#define ICC_IGRPEN1_EL3     S3_6_C12_C12_7\n\n#define ICC_PMR_EL1         S3_0_C4_C6_0\n#define ICC_RPR_EL1         S3_0_C12_C11_3\n\n#define ICC_SGI0R_EL1       S3_0_C12_C11_7\n#define ICC_SGI1R_EL1       S3_0_C12_C11_5\n\n#define ICC_SRE_EL1         S3_0_C12_C12_5\n#define ICC_SRE_EL2         S3_4_C12_C9_5\n#define ICC_SRE_EL3         S3_6_C12_C12_5\n\n/*\n * Mapping of MSR and MRS to virtual interface control registers\n *\n * ARM Generic Interrupt Controller Architecture Specification\n * GIC architecture version 3.0 and version 4.0\n * Table 8-6\n */\n#define ICH_AP0R0_EL2       S3_4_C12_C8_0\n#define ICH_AP0R1_EL2       S3_4_C12_C8_1\n#define ICH_AP0R2_EL2       S3_4_C12_C8_2\n#define ICH_AP0R3_EL2       S3_4_C12_C8_3\n\n#define ICH_AP1R0_EL2       S3_4_C12_C9_0\n#define ICH_AP1R1_EL2       S3_4_C12_C9_1\n#define ICH_AP1R2_EL2       S3_4_C12_C9_2\n#define ICH_AP1R3_EL2       S3_4_C12_C9_3\n\n#define ICH_HCR_EL2         S3_4_C12_C11_0\n\n#define ICH_VTR_EL2         S3_4_C12_C11_1\n\n#define ICH_MISR_EL2        S3_4_C12_C11_2\n\n#define ICH_EISR_EL2        S3_4_C12_C11_3\n\n#define ICH_ELRSR_EL2       S3_4_C12_C11_5\n\n#define ICH_VMCR_EL2        S3_4_C12_C11_7\n\n#define ICH_LR0_EL2         S3_4_C12_C12_0\n#define ICH_LR1_EL2         S3_4_C12_C12_1\n#define ICH_LR2_EL2         S3_4_C12_C12_2\n#define ICH_LR3_EL2         S3_4_C12_C12_3\n#define ICH_LR4_EL2         S3_4_C12_C12_4\n#define ICH_LR5_EL2         S3_4_C12_C12_5\n#define ICH_LR6_EL2         S3_4_C12_C12_6\n#define ICH_LR7_EL2         S3_4_C12_C12_7\n#define ICH_LR8_EL2         S3_4_C12_C13_0\n#define ICH_LR9_EL2         S3_4_C12_C13_1\n#define ICH_LR10_EL2        S3_4_C12_C13_2\n#define ICH_LR11_EL2        S3_4_C12_C13_3\n#define ICH_LR12_EL2        S3_4_C12_C13_4\n#define ICH_LR13_EL2        S3_4_C12_C13_5\n#define ICH_LR14_EL2        S3_4_C12_C13_6\n#define ICH_LR15_EL2        S3_4_C12_C13_7\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/io.h",
    "content": "/*\n * Based on arch/arm/include/asm/io.h\n *\n * Copyright (C) 1996-2000 Russell King\n * Copyright (C) 2012 ARM Ltd.\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _MINOS_IO_H_\n#define _MINOS_IO_H_\n\n#include <minos/types.h>\n\n/*\n * Generic IO read/write.  These perform native-endian accesses.\n */\n#define __raw_writeb __raw_writeb\nstatic inline void __raw_writeb(uint8_t val, volatile void *addr)\n{\n\tasm volatile(\"strb %w0, [%1]\" : : \"r\" (val), \"r\" (addr));\n}\n\n#define __raw_writew __raw_writew\nstatic inline void __raw_writew(uint16_t val, volatile void *addr)\n{\n\tasm volatile(\"strh %w0, [%1]\" : : \"r\" (val), \"r\" (addr));\n}\n\n#define __raw_writel __raw_writel\nstatic inline void __raw_writel(uint32_t val, volatile void *addr)\n{\n\tasm volatile(\"str %w0, [%1]\" : : \"r\" (val), \"r\" (addr));\n}\n\n#define __raw_writeq __raw_writeq\nstatic inline void __raw_writeq(uint64_t val, volatile void *addr)\n{\n\tasm volatile(\"str %0, [%1]\" : : \"r\" (val), \"r\" (addr));\n}\n\n#define __raw_readb __raw_readb\nstatic inline uint8_t __raw_readb(const volatile void *addr)\n{\n\tuint8_t val;\n\tasm volatile(\"ldrb %w0, [%1]\" : \"=r\" (val) : \"r\" (addr));\n\treturn val;\n}\n\n#define __raw_readw __raw_readw\nstatic inline uint16_t __raw_readw(const volatile void *addr)\n{\n\tuint16_t val;\n\tasm volatile(\"ldarh %w0, [%1]\" : \"=r\" (val) : \"r\" (addr));\n\treturn val;\n}\n\n#define __raw_readl __raw_readl\nstatic inline uint32_t __raw_readl(const volatile void *addr)\n{\n\tuint32_t val;\n\tasm volatile(\"ldar %w0, [%1]\" : \"=r\" (val) : \"r\" (addr));\n\treturn val;\n}\n\n#define __raw_readq __raw_readq\nstatic inline uint64_t __raw_readq(const volatile void *addr)\n{\n\tuint64_t val;\n\tasm volatile(\"ldar %0, [%1]\" : \"=r\" (val) : \"r\" (addr));\n\treturn val;\n}\n\n/*\n * Relaxed I/O memory access primitives. These follow the Device memory\n * ordering rules but do not guarantee any ordering relative to Normal memory\n * accesses.\n */\n#define readb_relaxed(c)\t({ uint8_t  __v = __raw_readb(c); iormb(); __v; })\n#define readw_relaxed(c)\t({ uint16_t __v = __raw_readw(c); iormb(); __v; })\n#define readl_relaxed(c)\t({ uint32_t __v = __raw_readl(c); iormb(); __v; })\n#define readq_relaxed(c)\t({ uint64_t __v = __raw_readq(c); iormb(); __v; })\n\n#define writeb_relaxed(v,c)\t({ iowmb(); (void)__raw_writeb((v), (c)); })\n#define writew_relaxed(v,c)\t({ iowmb(); (void)__raw_writew((v), (c)); })\n#define writel_relaxed(v,c)\t({ iowmb(); (void)__raw_writel((v), (c)); })\n#define writeq_relaxed(v,c)\t({ iowmb(); (void)__raw_writeq((v), (c)); })\n                                            \n#define ioread8(addr)\t\treadb_relaxed(addr)\n#define ioread16(addr)\t\treadw_relaxed(addr)\n#define ioread32(addr)\t\treadl_relaxed(addr)\n#define ioread64(addr)\t\treadq_relaxed(addr)\n\n#define iowrite8(v, addr)\twriteb_relaxed((v), (addr))\n#define iowrite16(v, addr)\twritew_relaxed((v), (addr))\n#define iowrite32(v, addr)\twritel_relaxed((v), (addr))\n#define iowrite64(v, addr)\twriteq_relaxed((v), (addr))\n\n#define readb(addr)\t\treadb_relaxed(addr)\n#define readw(addr)\t\treadw_relaxed(addr)\n#define readl(addr)\t\treadl_relaxed(addr)\n#define readq(addr)\t\treadq_relaxed(addr)\n\n#define writeb(v, addr)\t\twriteb_relaxed((v), (addr))\n#define writew(v, addr)\t\twritew_relaxed((v), (addr))\n#define writel(v, addr)\t\twritel_relaxed((v), (addr))\n#define writeq(v, addr)\t\twriteq_relaxed((v), (addr))\n\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/power.h",
    "content": "#ifndef __MINOS_CPU_H__\n#define __MINOS_CPU_H__\n\n#include <asm/psci.h>\n\nint psci_cpu_on(unsigned long cpu, unsigned long entry);\nint psci_cpu_off(unsigned long cpu);\nvoid psci_system_reboot(int mode, const char *cmd);\nvoid psci_system_shutdown(void);\n\nint psci_cpu_on_hvc(unsigned long cpu, unsigned long entry);\nint psci_cpu_off_hvc(unsigned long cpu);\nvoid psci_system_reboot_hvc(int mode, const char *cmd);\nvoid psci_system_shutdown_hvc(void);\n\nint spin_table_cpu_on(unsigned long affinity, unsigned long entry);\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/psci.h",
    "content": "/*\n * ARM Power State and Coordination Interface (PSCI) header\n *\n * This header holds common PSCI defines and macros shared\n * by: ARM kernel, ARM64 kernel, KVM ARM/ARM64 and user space.\n *\n * Copyright (C) 2014 Linaro Ltd.\n * Author: Anup Patel <anup.patel@linaro.org>\n */\n\n#ifndef _MINOS_PSCI_H_\n#define _MINOS_PSCI_H_\n\n#define PSCI_0_2_FN_BASE\t\t\t(0x84000000)\n#define PSCI_0_2_FN(n)\t\t\t\t(PSCI_0_2_FN_BASE + (n))\n#define PSCI_0_2_64BIT\t\t\t\t(0x40000000)\n#define PSCI_0_2_FN64_BASE\t\t\t\\\n\t\t\t\t\t(PSCI_0_2_FN_BASE + PSCI_0_2_64BIT)\n#define PSCI_0_2_FN64(n)\t\t\t(PSCI_0_2_FN64_BASE + (n))\n\n#define PSCI_0_2_FN_PSCI_VERSION\t\tPSCI_0_2_FN(0)\n#define PSCI_0_2_FN_CPU_SUSPEND\t\t\tPSCI_0_2_FN(1)\n#define PSCI_0_2_FN_CPU_OFF\t\t\tPSCI_0_2_FN(2)\n#define PSCI_0_2_FN_CPU_ON\t\t\tPSCI_0_2_FN(3)\n#define PSCI_0_2_FN_AFFINITY_INFO\t\tPSCI_0_2_FN(4)\n#define PSCI_0_2_FN_MIGRATE\t\t\tPSCI_0_2_FN(5)\n#define PSCI_0_2_FN_MIGRATE_INFO_TYPE\t\tPSCI_0_2_FN(6)\n#define PSCI_0_2_FN_MIGRATE_INFO_UP_CPU\t\tPSCI_0_2_FN(7)\n#define PSCI_0_2_FN_SYSTEM_OFF\t\t\tPSCI_0_2_FN(8)\n#define PSCI_0_2_FN_SYSTEM_RESET\t\tPSCI_0_2_FN(9)\n\n#define PSCI_0_2_FN64_CPU_SUSPEND\t\tPSCI_0_2_FN64(1)\n#define PSCI_0_2_FN64_CPU_ON\t\t\tPSCI_0_2_FN64(3)\n#define PSCI_0_2_FN64_AFFINITY_INFO\t\tPSCI_0_2_FN64(4)\n#define PSCI_0_2_FN64_MIGRATE\t\t\tPSCI_0_2_FN64(5)\n#define PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU\tPSCI_0_2_FN64(7)\n\n#define PSCI_1_0_FN_PSCI_FEATURES\t\tPSCI_0_2_FN(10)\n#define PSCI_1_0_FN_SYSTEM_SUSPEND\t\tPSCI_0_2_FN(14)\n\n#define PSCI_1_0_FN64_SYSTEM_SUSPEND\t\tPSCI_0_2_FN64(14)\n\n#define ARM_SMCCC_VERSION_FUNC_ID\t\t0x80000000\n\n/* PSCI v0.2 power state encoding for CPU_SUSPEND function */\n#define PSCI_0_2_POWER_STATE_ID_MASK\t\t0xffff\n#define PSCI_0_2_POWER_STATE_ID_SHIFT\t\t0\n#define PSCI_0_2_POWER_STATE_TYPE_SHIFT\t\t16\n#define PSCI_0_2_POWER_STATE_TYPE_MASK\t\t\\\n\t\t\t\t(0x1 << PSCI_0_2_POWER_STATE_TYPE_SHIFT)\n#define PSCI_0_2_POWER_STATE_AFFL_SHIFT\t\t24\n#define PSCI_0_2_POWER_STATE_AFFL_MASK\t\t\\\n\t\t\t\t(0x3 << PSCI_0_2_POWER_STATE_AFFL_SHIFT)\n\n/* PSCI extended power state encoding for CPU_SUSPEND function */\n#define PSCI_1_0_EXT_POWER_STATE_ID_MASK\t0xfffffff\n#define PSCI_1_0_EXT_POWER_STATE_ID_SHIFT\t0\n#define PSCI_1_0_EXT_POWER_STATE_TYPE_SHIFT\t30\n#define PSCI_1_0_EXT_POWER_STATE_TYPE_MASK\t\\\n\t\t\t\t(0x1 << PSCI_1_0_EXT_POWER_STATE_TYPE_SHIFT)\n\n/* PSCI v0.2 affinity level state returned by AFFINITY_INFO */\n#define PSCI_0_2_AFFINITY_LEVEL_ON\t\t0\n#define PSCI_0_2_AFFINITY_LEVEL_OFF\t\t1\n#define PSCI_0_2_AFFINITY_LEVEL_ON_PENDING\t2\n\n/* PSCI v0.2 multicore support in Trusted OS returned by MIGRATE_INFO_TYPE */\n#define PSCI_0_2_TOS_UP_MIGRATE\t\t\t0\n#define PSCI_0_2_TOS_UP_NO_MIGRATE\t\t1\n#define PSCI_0_2_TOS_MP\t\t\t\t2\n\n/* PSCI version decoding (independent of PSCI version) */\n#define PSCI_VERSION_MAJOR_SHIFT\t\t16\n#define PSCI_VERSION_MINOR_MASK\t\t\t\\\n\t\t((1U << PSCI_VERSION_MAJOR_SHIFT) - 1)\n#define PSCI_VERSION_MAJOR_MASK\t\t\t~PSCI_VERSION_MINOR_MASK\n#define PSCI_VERSION_MAJOR(ver)\t\t\t\\\n\t\t(((ver) & PSCI_VERSION_MAJOR_MASK) >> PSCI_VERSION_MAJOR_SHIFT)\n#define PSCI_VERSION_MINOR(ver)\t\t\t\\\n\t\t((ver) & PSCI_VERSION_MINOR_MASK)\n\n/* PSCI features decoding (>=1.0) */\n#define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT\t1\n#define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_MASK\t\\\n\t\t\t(0x1 << PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT)\n\n/* PSCI return values (inclusive of all PSCI versions) */\n#define PSCI_RET_SUCCESS\t\t\t0\n#define PSCI_RET_NOT_SUPPORTED\t\t\t-1\n#define PSCI_RET_INVALID_PARAMS\t\t\t-2\n#define PSCI_RET_DENIED\t\t\t\t-3\n#define PSCI_RET_ALREADY_ON\t\t\t-4\n#define PSCI_RET_ON_PENDING\t\t\t-5\n#define PSCI_RET_INTERNAL_FAILURE\t\t-6\n#define PSCI_RET_NOT_PRESENT\t\t\t-7\n#define PSCI_RET_DISABLED\t\t\t-8\n#define PSCI_RET_INVALID_ADDRESS\t\t-9\n\n#define PSCI_VERSION(major, minor)\t\\\n\t\t(0 | (major << PSCI_VERSION_MAJOR_SHIFT) | (minor))\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/reg.h",
    "content": "#ifndef _MINOS_PROCESSER_H_\n#define _MINOS_PROCESSER_H_\n\n#include <minos/types.h>\n\n/* ESR.EC == ESR_CP{15,14,10}_32 */\n#define HSR_CP32_OP2_MASK (0x000e0000)\n#define HSR_CP32_OP2_SHIFT (17)\n#define HSR_CP32_OP1_MASK (0x0001c000)\n#define HSR_CP32_OP1_SHIFT (14)\n#define HSR_CP32_CRN_MASK (0x00003c00)\n#define HSR_CP32_CRN_SHIFT (10)\n#define HSR_CP32_CRM_MASK (0x0000001e)\n#define HSR_CP32_CRM_SHIFT (1)\n#define HSR_CP32_REGS_MASK (HSR_CP32_OP1_MASK|HSR_CP32_OP2_MASK|\\\n                            HSR_CP32_CRN_MASK|HSR_CP32_CRM_MASK)\n\n/* ESR.EC == ESR_CP{15,14}_64 */\n#define HSR_CP64_OP1_MASK (0x000f0000)\n#define HSR_CP64_OP1_SHIFT (16)\n#define HSR_CP64_CRM_MASK (0x0000001e)\n#define HSR_CP64_CRM_SHIFT (1)\n#define HSR_CP64_REGS_MASK (HSR_CP64_OP1_MASK|HSR_CP64_CRM_MASK)\n\n/* ESR.EC == ESR_SYSREG */\n#define ESR_SYSREG_OP0_MASK (0x00300000)\n#define ESR_SYSREG_OP0_SHIFT (20)\n#define ESR_SYSREG_OP1_MASK (0x0001c000)\n#define ESR_SYSREG_OP1_SHIFT (14)\n#define ESR_SYSREG_CRN_MASK (0x00003c00)\n#define ESR_SYSREG_CRN_SHIFT (10)\n#define ESR_SYSREG_CRM_MASK (0x0000001e)\n#define ESR_SYSREG_CRM_SHIFT (1)\n#define ESR_SYSREG_OP2_MASK (0x000e0000)\n#define ESR_SYSREG_OP2_SHIFT (17)\n#define ESR_SYSREG_REGS_MASK (ESR_SYSREG_OP0_MASK|ESR_SYSREG_OP1_MASK|\\\n                              ESR_SYSREG_CRN_MASK|ESR_SYSREG_CRM_MASK|\\\n                              ESR_SYSREG_OP2_MASK)\n\n/* ESR.EC == ESR_{HVC32, HVC64, SMC64, SVC32, SVC64} */\n#define ESR_XXC_IMM_MASK     (0xffff)\n\n#define __ESR_SYSREG_c0  0\n#define __ESR_SYSREG_c1  1\n#define __ESR_SYSREG_c2  2\n#define __ESR_SYSREG_c3  3\n#define __ESR_SYSREG_c4  4\n#define __ESR_SYSREG_c5  5\n#define __ESR_SYSREG_c6  6\n#define __ESR_SYSREG_c7  7\n#define __ESR_SYSREG_c8  8\n#define __ESR_SYSREG_c9  9\n#define __ESR_SYSREG_c10 10\n#define __ESR_SYSREG_c11 11\n#define __ESR_SYSREG_c12 12\n#define __ESR_SYSREG_c13 13\n#define __ESR_SYSREG_c14 14\n#define __ESR_SYSREG_c15 15\n\n#define __ESR_SYSREG_0   0\n#define __ESR_SYSREG_1   1\n#define __ESR_SYSREG_2   2\n#define __ESR_SYSREG_3   3\n#define __ESR_SYSREG_4   4\n#define __ESR_SYSREG_5   5\n#define __ESR_SYSREG_6   6\n#define __ESR_SYSREG_7   7\n\n/* These are used to decode traps with ESR.EC==ESR_EC_SYSREG */\n#define ESR_SYSREG(op0,op1,crn,crm,op2) \\\n    (((__ESR_SYSREG_##op0) << ESR_SYSREG_OP0_SHIFT) | \\\n     ((__ESR_SYSREG_##op1) << ESR_SYSREG_OP1_SHIFT) | \\\n     ((__ESR_SYSREG_##crn) << ESR_SYSREG_CRN_SHIFT) | \\\n     ((__ESR_SYSREG_##crm) << ESR_SYSREG_CRM_SHIFT) | \\\n     ((__ESR_SYSREG_##op2) << ESR_SYSREG_OP2_SHIFT))\n\n#define ESR_SYSREG_DCISW          ESR_SYSREG(1,0,c7,c6,2)\n#define ESR_SYSREG_DCCSW          ESR_SYSREG(1,0,c7,c10,2)\n#define ESR_SYSREG_DCCISW         ESR_SYSREG(1,0,c7,c14,2)\n#define ESR_SYSREG_DCZVA\t  ESR_SYSREG(1,3,c7,c4,1)\n\n#define ESR_SYSREG_MDSCR_EL1      ESR_SYSREG(2,0,c0,c2,2)\n#define ESR_SYSREG_MDRAR_EL1      ESR_SYSREG(2,0,c1,c0,0)\n#define ESR_SYSREG_OSLAR_EL1      ESR_SYSREG(2,0,c1,c0,4)\n#define ESR_SYSREG_OSLSR_EL1      ESR_SYSREG(2,0,c1,c1,4)\n#define ESR_SYSREG_OSDLR_EL1      ESR_SYSREG(2,0,c1,c3,4)\n#define ESR_SYSREG_DBGPRCR_EL1    ESR_SYSREG(2,0,c1,c4,4)\n#define ESR_SYSREG_MDCCSR_EL0     ESR_SYSREG(2,3,c0,c1,0)\n\n#define ESR_SYSREG_DBGBVRn_EL1(n) ESR_SYSREG(2,0,c0,c##n,4)\n#define ESR_SYSREG_DBGBCRn_EL1(n) ESR_SYSREG(2,0,c0,c##n,5)\n#define ESR_SYSREG_DBGWVRn_EL1(n) ESR_SYSREG(2,0,c0,c##n,6)\n#define ESR_SYSREG_DBGWCRn_EL1(n) ESR_SYSREG(2,0,c0,c##n,7)\n\n#define ESR_SYSREG_DBG_CASES(REG) case ESR_SYSREG_##REG##n_EL1(0):  \\\n                                  case ESR_SYSREG_##REG##n_EL1(1):  \\\n                                  case ESR_SYSREG_##REG##n_EL1(2):  \\\n                                  case ESR_SYSREG_##REG##n_EL1(3):  \\\n                                  case ESR_SYSREG_##REG##n_EL1(4):  \\\n                                  case ESR_SYSREG_##REG##n_EL1(5):  \\\n                                  case ESR_SYSREG_##REG##n_EL1(6):  \\\n                                  case ESR_SYSREG_##REG##n_EL1(7):  \\\n                                  case ESR_SYSREG_##REG##n_EL1(8):  \\\n                                  case ESR_SYSREG_##REG##n_EL1(9):  \\\n                                  case ESR_SYSREG_##REG##n_EL1(10): \\\n                                  case ESR_SYSREG_##REG##n_EL1(11): \\\n                                  case ESR_SYSREG_##REG##n_EL1(12): \\\n                                  case ESR_SYSREG_##REG##n_EL1(13): \\\n                                  case ESR_SYSREG_##REG##n_EL1(14): \\\n                                  case ESR_SYSREG_##REG##n_EL1(15)\n\n#define ESR_SYSREG_SCTLR_EL1      ESR_SYSREG(3,0,c1, c0,0)\n#define ESR_SYSREG_ACTLR_EL1      ESR_SYSREG(3,0,c1, c0,1)\n#define ESR_SYSREG_TTBR0_EL1      ESR_SYSREG(3,0,c2, c0,0)\n#define ESR_SYSREG_TTBR1_EL1      ESR_SYSREG(3,0,c2, c0,1)\n#define ESR_SYSREG_TCR_EL1        ESR_SYSREG(3,0,c2, c0,2)\n#define ESR_SYSREG_AFSR0_EL1      ESR_SYSREG(3,0,c5, c1,0)\n#define ESR_SYSREG_AFSR1_EL1      ESR_SYSREG(3,0,c5, c1,1)\n#define ESR_SYSREG_ESR_EL1        ESR_SYSREG(3,0,c5, c2,0)\n#define ESR_SYSREG_FAR_EL1        ESR_SYSREG(3,0,c6, c0,0)\n#define ESR_SYSREG_PMINTENSET_EL1 ESR_SYSREG(3,0,c9,c14,1)\n#define ESR_SYSREG_PMINTENCLR_EL1 ESR_SYSREG(3,0,c9,c14,2)\n#define ESR_SYSREG_MAIR_EL1       ESR_SYSREG(3,0,c10,c2,0)\n#define ESR_SYSREG_AMAIR_EL1      ESR_SYSREG(3,0,c10,c3,0)\n#define ESR_SYSREG_ICC_SGI1R_EL1  ESR_SYSREG(3,0,c12,c11,5)\n#define ESR_SYSREG_ICC_ASGI1R_EL1 ESR_SYSREG(3,1,c12,c11,6)\n#define ESR_SYSREG_ICC_SGI0R_EL1  ESR_SYSREG(3,2,c12,c11,7)\n#define ESR_SYSREG_ICC_SRE_EL1    ESR_SYSREG(3,0,c12,c12,5)\n#define ESR_SYSREG_CONTEXTIDR_EL1 ESR_SYSREG(3,0,c13,c0,1)\n\n#define ESR_SYSREG_PMCR_EL0       ESR_SYSREG(3,3,c9,c12,0)\n#define ESR_SYSREG_PMCNTENSET_EL0 ESR_SYSREG(3,3,c9,c12,1)\n#define ESR_SYSREG_PMCNTENCLR_EL0 ESR_SYSREG(3,3,c9,c12,2)\n#define ESR_SYSREG_PMOVSCLR_EL0   ESR_SYSREG(3,3,c9,c12,3)\n#define ESR_SYSREG_PMSWINC_EL0    ESR_SYSREG(3,3,c9,c12,4)\n#define ESR_SYSREG_PMSELR_EL0     ESR_SYSREG(3,3,c9,c12,5)\n#define ESR_SYSREG_PMCEID0_EL0    ESR_SYSREG(3,3,c9,c12,6)\n#define ESR_SYSREG_PMCEID1_EL0    ESR_SYSREG(3,3,c9,c12,7)\n\n#define ESR_SYSREG_PMCCNTR_EL0    ESR_SYSREG(3,3,c9,c13,0)\n#define ESR_SYSREG_PMXEVTYPER_EL0 ESR_SYSREG(3,3,c9,c13,1)\n#define ESR_SYSREG_PMXEVCNTR_EL0  ESR_SYSREG(3,3,c9,c13,2)\n\n#define ESR_SYSREG_PMUSERENR_EL0  ESR_SYSREG(3,3,c9,c14,0)\n#define ESR_SYSREG_PMOVSSET_EL0   ESR_SYSREG(3,3,c9,c14,3)\n\n#define ESR_SYSREG_CNTPCT_EL0     ESR_SYSREG(3,3,c14,c0,0)\n#define ESR_SYSREG_CNTP_TVAL_EL0  ESR_SYSREG(3,3,c14,c2,0)\n#define ESR_SYSREG_CNTP_CTL_EL0   ESR_SYSREG(3,3,c14,c2,1)\n#define ESR_SYSREG_CNTP_CVAL_EL0  ESR_SYSREG(3,3,c14,c2,2)\n\n#define ESR_SYSREG_ASOC_HID11\t  ESR_SYSREG(3,0,c15,c13,0)\n#define ESR_SYSREG_ASOC_HID5\t  ESR_SYSREG(3,0,c15,c5,0)\n#define ESR_SYSREG_ASOC_HID4      ESR_SYSREG(3,0,c15,c4,0)\n#define ESR_SYSREG_ASOC_HID8 \t  ESR_SYSREG(3,0,c15,c8,0)\n#define ESR_SYSREG_ASOC_HID7      ESR_SYSREG(3,0,c15,c7,0)\n#define ESR_SYSREG_ASOC_LSU_ERR_STS ESR_SYSREG(3,3,c15,c0,0)\n#define ESR_SYSREG_ASOC_PMC0      ESR_SYSREG(3,2,c15,c0,0)\n#define ESR_SYSREG_ASOC_PMC1      ESR_SYSREG(3,2,c15,c1,0)\n#define ESR_SYSREG_ASOC_PMCR1     ESR_SYSREG(3,1,c15,c1,0)\n#define ESR_SYSREG_ASOC_PMSR      ESR_SYSREG(3,1,c15,c13,0)\n\n/*\n * AArch32 Co-processor registers.\n *\n * Note that AArch64 requires many of these definitions in order to\n * support 32-bit guests.\n */\n#define __HSR_CPREG_c0  0\n#define __HSR_CPREG_c1  1\n#define __HSR_CPREG_c2  2\n#define __HSR_CPREG_c3  3\n#define __HSR_CPREG_c4  4\n#define __HSR_CPREG_c5  5\n#define __HSR_CPREG_c6  6\n#define __HSR_CPREG_c7  7\n#define __HSR_CPREG_c8  8\n#define __HSR_CPREG_c9  9\n#define __HSR_CPREG_c10 10\n#define __HSR_CPREG_c11 11\n#define __HSR_CPREG_c12 12\n#define __HSR_CPREG_c13 13\n#define __HSR_CPREG_c14 14\n#define __HSR_CPREG_c15 15\n\n#define __HSR_CPREG_0   0\n#define __HSR_CPREG_1   1\n#define __HSR_CPREG_2   2\n#define __HSR_CPREG_3   3\n#define __HSR_CPREG_4   4\n#define __HSR_CPREG_5   5\n#define __HSR_CPREG_6   6\n#define __HSR_CPREG_7   7\n\n#define _HSR_CPREG32(cp,op1,crn,crm,op2) \\\n    ((__HSR_CPREG_##crn) << HSR_CP32_CRN_SHIFT) | \\\n    ((__HSR_CPREG_##crm) << HSR_CP32_CRM_SHIFT) | \\\n    ((__HSR_CPREG_##op1) << HSR_CP32_OP1_SHIFT) | \\\n    ((__HSR_CPREG_##op2) << HSR_CP32_OP2_SHIFT)\n\n#define _HSR_CPREG64(cp,op1,crm) \\\n    ((__HSR_CPREG_##crm) << HSR_CP64_CRM_SHIFT) | \\\n    ((__HSR_CPREG_##op1) << HSR_CP64_OP1_SHIFT)\n\n/* Encode a register as per HSR ISS pattern */\n#define HSR_CPREG32(X) _HSR_CPREG32(X)\n#define HSR_CPREG64(X) _HSR_CPREG64(X)\n\n/*\n * Order registers by Coprocessor-> CRn-> Opcode 1-> CRm-> Opcode 2\n *\n * This matches the ordering used in the ARM as well as the groupings\n * which the CP registers are allocated in.\n *\n * This is slightly different to the form of the instruction\n * arguments, which are cp,opc1,crn,crm,opc2.\n */\n\n/* Coprocessor 10 */\n\n#define FPSID           p10,7,c0,c0,0   /* Floating-Point System ID Register */\n#define FPSCR           p10,7,c1,c0,0   /* Floating-Point Status and Control Register */\n#define MVFR0           p10,7,c7,c0,0   /* Media and VFP Feature Register 0 */\n#define FPEXC           p10,7,c8,c0,0   /* Floating-Point Exception Control Register */\n#define FPINST          p10,7,c9,c0,0   /* Floating-Point Instruction Register */\n#define FPINST2         p10,7,c10,c0,0  /* Floating-point Instruction Register 2 */\n\n/* Coprocessor 14 */\n\n/* CP14 0: Debug Register interface */\n#define DBGDIDR         p14,0,c0,c0,0   /* Debug ID Register */\n#define DBGDSCRINT      p14,0,c0,c1,0   /* Debug Status and Control Internal */\n#define DBGDSCREXT      p14,0,c0,c2,2   /* Debug Status and Control External */\n#define DBGVCR          p14,0,c0,c7,0   /* Vector Catch */\n#define DBGBVR0         p14,0,c0,c0,4   /* Breakpoint Value 0 */\n#define DBGBCR0         p14,0,c0,c0,5   /* Breakpoint Control 0 */\n#define DBGWVR0         p14,0,c0,c0,6   /* Watchpoint Value 0 */\n#define DBGWCR0         p14,0,c0,c0,7   /* Watchpoint Control 0 */\n#define DBGBVR1         p14,0,c0,c1,4   /* Breakpoint Value 1 */\n#define DBGBCR1         p14,0,c0,c1,5   /* Breakpoint Control 1 */\n#define DBGOSLAR        p14,0,c1,c0,4   /* OS Lock Access */\n#define DBGOSLSR        p14,0,c1,c1,4   /* OS Lock Status Register */\n#define DBGOSDLR        p14,0,c1,c3,4   /* OS Double Lock */\n#define DBGPRCR         p14,0,c1,c4,4   /* Debug Power Control Register */\n\n/* CP14 CR0: */\n#define TEECR           p14,6,c0,c0,0   /* ThumbEE Configuration Register */\n\n/* CP14 CR1: */\n#define DBGDRAR64       p14,0,c1        /* Debug ROM Address Register (64-bit access) */\n#define DBGDRAR         p14,0,c1,c0,0   /* Debug ROM Address Register (32-bit access) */\n#define TEEHBR          p14,6,c1,c0,0   /* ThumbEE Handler Base Register */\n#define JOSCR           p14,7,c1,c0,0   /* Jazelle OS Control Register */\n\n/* CP14 CR2: */\n#define DBGDSAR64       p14,0,c2        /* Debug Self Address Offset Register (64-bit access) */\n#define DBGDSAR         p14,0,c2,c0,0   /* Debug Self Address Offset Register (32-bit access) */\n#define JMCR            p14,7,c2,c0,0   /* Jazelle Main Configuration Register */\n\n\n/* Coprocessor 15 */\n\n/* CP15 CR0: CPUID and Cache Type Registers */\n#define MIDR            p15,0,c0,c0,0   /* Main ID Register */\n#define MPIDR           p15,0,c0,c0,5   /* Multiprocessor Affinity Register */\n#define ID_PFR0         p15,0,c0,c1,0   /* Processor Feature Register 0 */\n#define ID_PFR1         p15,0,c0,c1,1   /* Processor Feature Register 1 */\n#define ID_DFR0         p15,0,c0,c1,2   /* Debug Feature Register 0 */\n#define ID_AFR0         p15,0,c0,c1,3   /* Auxiliary Feature Register 0 */\n#define ID_MMFR0        p15,0,c0,c1,4   /* Memory Model Feature Register 0 */\n#define ID_MMFR1        p15,0,c0,c1,5   /* Memory Model Feature Register 1 */\n#define ID_MMFR2        p15,0,c0,c1,6   /* Memory Model Feature Register 2 */\n#define ID_MMFR3        p15,0,c0,c1,7   /* Memory Model Feature Register 3 */\n#define ID_ISAR0        p15,0,c0,c2,0   /* ISA Feature Register 0 */\n#define ID_ISAR1        p15,0,c0,c2,1   /* ISA Feature Register 1 */\n#define ID_ISAR2        p15,0,c0,c2,2   /* ISA Feature Register 2 */\n#define ID_ISAR3        p15,0,c0,c2,3   /* ISA Feature Register 3 */\n#define ID_ISAR4        p15,0,c0,c2,4   /* ISA Feature Register 4 */\n#define ID_ISAR5        p15,0,c0,c2,5   /* ISA Feature Register 5 */\n#define CCSIDR          p15,1,c0,c0,0   /* Cache Size ID Registers */\n#define CLIDR           p15,1,c0,c0,1   /* Cache Level ID Register */\n#define CSSELR          p15,2,c0,c0,0   /* Cache Size Selection Register */\n#define VPIDR           p15,4,c0,c0,0   /* Virtualization Processor ID Register */\n#define VMPIDR          p15,4,c0,c0,5   /* Virtualization Multiprocessor ID Register */\n\n/* CP15 CR1: System Control Registers */\n#define SCTLR           p15,0,c1,c0,0   /* System Control Register */\n#define ACTLR           p15,0,c1,c0,1   /* Auxiliary Control Register */\n#define CPACR           p15,0,c1,c0,2   /* Coprocessor Access Control Register */\n#define SCR             p15,0,c1,c1,0   /* Secure Configuration Register */\n#define NSACR           p15,0,c1,c1,2   /* Non-Secure Access Control Register */\n#define HSCTLR          p15,4,c1,c0,0   /* Hyp. System Control Register */\n#define HCR             p15,4,c1,c1,0   /* Hyp. Configuration Register */\n#define HDCR            p15,4,c1,c1,1   /* Hyp. Debug Configuration Register */\n#define HCPTR           p15,4,c1,c1,2   /* Hyp. Coprocessor Trap Register */\n#define HSTR            p15,4,c1,c1,3   /* Hyp. System Trap Register */\n\n/* CP15 CR2: Translation Table Base and Control Registers */\n#define TTBCR           p15,0,c2,c0,2   /* Translatation Table Base Control Register */\n#define TTBR0           p15,0,c2        /* Translation Table Base Reg. 0 */\n#define TTBR1           p15,1,c2        /* Translation Table Base Reg. 1 */\n#define HTTBR           p15,4,c2        /* Hyp. Translation Table Base Register */\n#define TTBR0_32        p15,0,c2,c0,0   /* 32-bit access to TTBR0 */\n#define TTBR1_32        p15,0,c2,c0,1   /* 32-bit access to TTBR1 */\n#define HTCR            p15,4,c2,c0,2   /* Hyp. Translation Control Register */\n#define VTCR            p15,4,c2,c1,2   /* Virtualization Translation Control Register */\n#define VTTBR           p15,6,c2        /* Virtualization Translation Table Base Register */\n\n/* CP15 CR3: Domain Access Control Register */\n#define DACR            p15,0,c3,c0,0   /* Domain Access Control Register */\n\n/* CP15 CR4: */\n\n/* CP15 CR5: Fault Status Registers */\n#define DFSR            p15,0,c5,c0,0   /* Data Fault Status Register */\n#define IFSR            p15,0,c5,c0,1   /* Instruction Fault Status Register */\n#define ADFSR           p15,0,c5,c1,0   /* Auxiliary Data Fault Status Register */\n#define AIFSR           p15,0,c5,c1,1   /* Auxiliary Instruction Fault Status Register */\n#define HSR             p15,4,c5,c2,0   /* Hyp. Syndrome Register */\n\n/* CP15 CR6: Fault Address Registers */\n#define DFAR            p15,0,c6,c0,0   /* Data Fault Address Register  */\n#define IFAR            p15,0,c6,c0,2   /* Instruction Fault Address Register */\n#define HDFAR           p15,4,c6,c0,0   /* Hyp. Data Fault Address Register */\n#define HIFAR           p15,4,c6,c0,2   /* Hyp. Instruction Fault Address Register */\n#define HPFAR           p15,4,c6,c0,4   /* Hyp. IPA Fault Address Register */\n\n/* CP15 CR7: Cache and address translation operations */\n#define PAR             p15,0,c7        /* Physical Address Register */\n\n#define ICIALLUIS       p15,0,c7,c1,0   /* Invalidate all instruction caches to PoU inner shareable */\n#define BPIALLIS        p15,0,c7,c1,6   /* Invalidate entire branch predictor array inner shareable */\n#define ICIALLU         p15,0,c7,c5,0   /* Invalidate all instruction caches to PoU */\n#define ICIMVAU         p15,0,c7,c5,1   /* Invalidate instruction caches by MVA to PoU */\n#define BPIALL          p15,0,c7,c5,6   /* Invalidate entire branch predictor array */\n#define BPIMVA          p15,0,c7,c5,7   /* Invalidate MVA from branch predictor array */\n#define DCIMVAC         p15,0,c7,c6,1   /* Invalidate data cache line by MVA to PoC */\n#define DCISW           p15,0,c7,c6,2   /* Invalidate data cache line by set/way */\n#define ATS1CPR         p15,0,c7,c8,0   /* Address Translation Stage 1. Non-Secure Kernel Read */\n#define ATS1CPW         p15,0,c7,c8,1   /* Address Translation Stage 1. Non-Secure Kernel Write */\n#define ATS1CUR         p15,0,c7,c8,2   /* Address Translation Stage 1. Non-Secure User Read */\n#define ATS1CUW         p15,0,c7,c8,3   /* Address Translation Stage 1. Non-Secure User Write */\n#define ATS12NSOPR      p15,0,c7,c8,4   /* Address Translation Stage 1+2 Non-Secure Kernel Read */\n#define ATS12NSOPW      p15,0,c7,c8,5   /* Address Translation Stage 1+2 Non-Secure Kernel Write */\n#define ATS12NSOUR      p15,0,c7,c8,6   /* Address Translation Stage 1+2 Non-Secure User Read */\n#define ATS12NSOUW      p15,0,c7,c8,7   /* Address Translation Stage 1+2 Non-Secure User Write */\n#define DCCMVAC         p15,0,c7,c10,1  /* Clean data or unified cache line by MVA to PoC */\n#define DCCSW           p15,0,c7,c10,2  /* Clean data cache line by set/way */\n#define DCCMVAU         p15,0,c7,c11,1  /* Clean data cache line by MVA to PoU */\n#define DCCIMVAC        p15,0,c7,c14,1  /* Data cache clean and invalidate by MVA */\n#define DCCISW          p15,0,c7,c14,2  /* Clean and invalidate data cache line by set/way */\n#define ATS1HR          p15,4,c7,c8,0   /* Address Translation Stage 1 Hyp. Read */\n#define ATS1HW          p15,4,c7,c8,1   /* Address Translation Stage 1 Hyp. Write */\n\n/* CP15 CR8: TLB maintenance operations */\n#define TLBIALLIS       p15,0,c8,c3,0   /* Invalidate entire TLB innrer shareable */\n#define TLBIMVAIS       p15,0,c8,c3,1   /* Invalidate unified TLB entry by MVA inner shareable */\n#define TLBIASIDIS      p15,0,c8,c3,2   /* Invalidate unified TLB by ASID match inner shareable */\n#define TLBIMVAAIS      p15,0,c8,c3,3   /* Invalidate unified TLB entry by MVA all ASID inner shareable */\n#define ITLBIALL        p15,0,c8,c5,0   /* Invalidate instruction TLB */\n#define ITLBIMVA        p15,0,c8,c5,1   /* Invalidate instruction TLB entry by MVA */\n#define ITLBIASID       p15,0,c8,c5,2   /* Invalidate instruction TLB by ASID match */\n#define DTLBIALL        p15,0,c8,c6,0   /* Invalidate data TLB */\n#define DTLBIMVA        p15,0,c8,c6,1   /* Invalidate data TLB entry by MVA */\n#define DTLBIASID       p15,0,c8,c6,2   /* Invalidate data TLB by ASID match */\n#define TLBIALL         p15,0,c8,c7,0   /* invalidate unified TLB */\n#define TLBIMVA         p15,0,c8,c7,1   /* invalidate unified TLB entry by MVA */\n#define TLBIASID        p15,0,c8,c7,2   /* invalid unified TLB by ASID match */\n#define TLBIMVAA        p15,0,c8,c7,3   /* invalidate unified TLB entries by MVA all ASID */\n#define TLBIALLHIS      p15,4,c8,c3,0   /* Invalidate Entire Hyp. Unified TLB inner shareable */\n#define TLBIMVAHIS      p15,4,c8,c3,1   /* Invalidate Unified Hyp. TLB by MVA inner shareable */\n#define TLBIALLNSNHIS   p15,4,c8,c3,4   /* Invalidate Entire Non-Secure Non-Hyp. Unified TLB inner shareable */\n#define TLBIALLH        p15,4,c8,c7,0   /* Invalidate Entire Hyp. Unified TLB */\n#define TLBIMVAH        p15,4,c8,c7,1   /* Invalidate Unified Hyp. TLB by MVA */\n#define TLBIALLNSNH     p15,4,c8,c7,4   /* Invalidate Entire Non-Secure Non-Hyp. Unified TLB */\n\n/* CP15 CR9: Performance monitors */\n#define PMCR            p15,0,c9,c12,0  /* Perf. Mon. Control Register */\n#define PMCNTENSET      p15,0,c9,c12,1  /* Perf. Mon. Count Enable Set register */\n#define PMCNTENCLR      p15,0,c9,c12,2  /* Perf. Mon. Count Enable Clear register */\n#define PMOVSR          p15,0,c9,c12,3  /* Perf. Mon. Overflow Flag Status Register */\n#define PMSWINC         p15,0,c9,c12,4  /* Perf. Mon. Software Increment register */\n#define PMSELR          p15,0,c9,c12,5  /* Perf. Mon. Event Counter Selection Register */\n#define PMCEID0         p15,0,c9,c12,6  /* Perf. Mon. Common Event Identification register 0 */\n#define PMCEID1         p15,0,c9,c12,7  /* Perf. Mon. Common Event Identification register 1 */\n#define PMCCNTR         p15,0,c9,c13,0  /* Perf. Mon. Cycle Count Register */\n#define PMXEVTYPER      p15,0,c9,c13,1  /* Perf. Mon. Event Type Select Register */\n#define PMXEVCNTR       p15,0,c9,c13,2  /* Perf. Mon. Event Count Register */\n#define PMUSERENR       p15,0,c9,c14,0  /* Perf. Mon. User Enable Register */\n#define PMINTENSET      p15,0,c9,c14,1  /* Perf. Mon. Interrupt Enable Set Register */\n#define PMINTENCLR      p15,0,c9,c14,2  /* Perf. Mon. Interrupt Enable Clear Register */\n#define PMOVSSET        p15,0,c9,c14,3  /* Perf. Mon. Overflow Flag Status Set register */\n\n/* CP15 CR10: */\n#define MAIR0           p15,0,c10,c2,0  /* Memory Attribute Indirection Register 0 AKA PRRR */\n#define MAIR1           p15,0,c10,c2,1  /* Memory Attribute Indirection Register 1 AKA NMRR */\n#define HMAIR0          p15,4,c10,c2,0  /* Hyp. Memory Attribute Indirection Register 0 */\n#define HMAIR1          p15,4,c10,c2,1  /* Hyp. Memory Attribute Indirection Register 1 */\n#define AMAIR0          p15,0,c10,c3,0  /* Aux. Memory Attribute Indirection Register 0 */\n#define AMAIR1          p15,0,c10,c3,1  /* Aux. Memory Attribute Indirection Register 1 */\n\n/* CP15 CR11: DMA Operations for TCM Access */\n\n/* CP15 CR12:  */\n#define ICC_SGI1R       p15,0,c12       /* Interrupt Controller SGI Group 1 */\n#define ICC_ASGI1R      p15,1,c12       /* Interrupt Controller Alias SGI Group 1 Register */\n#define ICC_SGI0R       p15,2,c12       /* Interrupt Controller SGI Group 0 */\n#define VBAR            p15,0,c12,c0,0  /* Vector Base Address Register */\n#define HVBAR           p15,4,c12,c0,0  /* Hyp. Vector Base Address Register */\n\n/* CP15 CR13:  */\n#define FCSEIDR         p15,0,c13,c0,0  /* FCSE Process ID Register */\n#define CONTEXTIDR      p15,0,c13,c0,1  /* Context ID Register */\n#define TPIDRURW        p15,0,c13,c0,2  /* Software Thread ID, User, R/W */\n#define TPIDRURO        p15,0,c13,c0,3  /* Software Thread ID, User, R/O */\n#define TPIDRPRW        p15,0,c13,c0,4  /* Software Thread ID, Priveleged */\n#define HTPIDR          p15,4,c13,c0,2  /* HYp Software Thread Id Register */\n\n/* CP15 CR14:  */\n#define CNTPCT          p15,0,c14       /* Time counter value */\n#define CNTFRQ          p15,0,c14,c0,0  /* Time counter frequency */\n#define CNTKCTL         p15,0,c14,c1,0  /* Time counter kernel control */\n#define CNTP_TVAL       p15,0,c14,c2,0  /* Physical Timer value */\n#define CNTP_CTL        p15,0,c14,c2,1  /* Physical Timer control register */\n#define CNTVCT          p15,1,c14       /* Time counter value + offset */\n#define CNTP_CVAL       p15,2,c14       /* Physical Timer comparator */\n#define CNTV_CVAL       p15,3,c14       /* Virt. Timer comparator */\n#define CNTVOFF         p15,4,c14       /* Time counter offset */\n#define CNTHCTL         p15,4,c14,c1,0  /* Time counter hyp. control */\n#define CNTHP_TVAL      p15,4,c14,c2,0  /* Hyp. Timer value */\n#define CNTHP_CTL       p15,4,c14,c2,1  /* Hyp. Timer control register */\n#define CNTV_TVAL       p15,0,c14,c3,0  /* Virt. Timer value */\n#define CNTV_CTL        p15,0,c14,c3,1  /* Virt. TImer control register */\n#define CNTHP_CVAL      p15,6,c14       /* Hyp. Timer comparator */\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/svccc.h",
    "content": "#ifndef _MINOS_ASM_SVCCC_H_\n#define _MINOS_ASM_SVCCC_H_\n\n#include <asm/arch.h>\n\n/*\n * ARM_DEN0028B_SMC_Calling_Convention.pdf\n * Table 2-1 Bit usage within the SMC and HVC Function Identifier\n * bit[31] \t: 0-yielding call 1-fast call\n * bit[30] \t: 0-smc32/hvc32 1-smc64/hvc64\n * bit[29:24]\t: service call ranges SVC_STYPE_XX\n * bit[23:16]\t: must be zero\n * bit[15:0]\t: function number with the range call type\n */\n#define SVC_CTYPE_MASK\t\t\t(0x80000000)\n#define SVC_BTYPE_MASK\t\t\t(0x40000000)\n#define SVC_STYPE_MASK\t\t\t(0x3f000000)\n#define SVC_FID_MASK\t\t\t(0x0000ffff)\n\n#define SVC_STYPE_ARCH\t\t\t(0x00)\n#define SVC_STYPE_CPU\t\t\t(0x01)\n#define SVC_STYPE_SIP\t\t\t(0x02)\n#define SVC_STYPE_OEM\t\t\t(0x03)\n#define SVC_STYPE_STDSMC\t\t(0x04)\n#define SVC_STYPE_STDHVC\t\t(0x05)\n#define SVC_STYPE_VNDHVC\t\t(0x06)\n#define SVC_STYPE_TRUST_APP_START\t(0x30)\n#define SVC_STYPE_TRUST_APP_END\t\t(0x31)\n#define SVC_STYPE_TRUST_OS_START\t(0x32)\n#define SVC_STYPE_TRUST_OS_END\t\t(0x3f)\n#define SVC_STYPE_MAX\t\t\t(64)\n\n#define SVC_RET()\t\t{\t\\\n\treturn 0;\t\t\t\\\n}\n\n#define SVC_RET1(reg, a0)\t{\t\\\n\tset_reg_value(reg, 0, a0); \t\\\n\treturn 0;\t\t\t\\\n}\n\n#define SVC_RET2(reg, a0, a1)\t{\t\\\n\tset_reg_value(reg, 0, a0);\t\\\n\tset_reg_value(reg, 1, a1);\t\\\n\treturn 0;\t\t\t\\\n}\n\n#define SVC_RET3(reg, a0, a1, a2)\t{\t\\\n\tset_reg_value(reg, 0, a0); \t\\\n\tset_reg_value(reg, 1, a1); \t\\\n\tset_reg_value(reg, 2, a2); \t\\\n\treturn 0;\t\t\t\\\n}\n\n#define SVC_RET4(reg, a0, a1, a2, a3) {\t\\\n\tset_reg_value(reg, 0, a0); \t\\\n\tset_reg_value(reg, 1, a1); \t\\\n\tset_reg_value(reg, 2, a2); \t\\\n\tset_reg_value(reg, 3, a3); \t\\\n\treturn 0;\t\t\t\\\n}\n\n#define HVC_RET0()\t\t \tSVC_RET0()\n#define HVC_RET1(reg, a0)\t\tSVC_RET1(reg, a0)\n#define HVC_RET2(reg, a0, a1)\t \tSVC_RET2(reg, a0, a1)\n#define HVC_RET3(reg, a0, a1, a2)\tSVC_RET3(reg, a0, a1, a2)\n#define HVC_RET4(reg, a0, a1, a2, a3) \tSVC_RET4(reg, a0, a1, a2, a3)\n\ntypedef int (*svc_handler_t)(gp_regs *c, uint32_t id, uint64_t *args);\n\nstruct svc_desc {\n\tchar *name;\n\tuint16_t type_start;\n\tuint16_t type_end;\n\tsvc_handler_t handler;\n};\n\n#define DEFINE_SMC_HANDLER(n, start, end, h)\t\\\n\tstatic struct svc_desc __smc_##h __used \\\n\t__section(\".__smc_handler\") = {\t\\\n\t\t.name = n,\t\\\n\t\t.type_start = start, \\\n\t\t.type_end = end, \\\n\t\t.handler = h, \\\n\t}\n\n#define DEFINE_HVC_HANDLER(n, start, end, h)\t\\\n\tstatic struct svc_desc __hvc_##h __used \\\n\t__section(\".__hvc_handler\") = {\t\\\n\t\t.name = n,\t\\\n\t\t.type_start = start, \\\n\t\t.type_end = end, \\\n\t\t.handler = h, \\\n\t}\n\nstruct arm_smc_res {\n\tunsigned long a0;\n\tunsigned long a1;\n\tunsigned long a2;\n\tunsigned long a3;\n};\n\nvoid smc_call(uint32_t id, unsigned long a1, unsigned long a2,\n\t\tunsigned long a3, unsigned long a4, unsigned long a5,\n\t\tunsigned long a6, unsigned long a7, struct arm_smc_res *res);\n\nvoid hvc_call(uint32_t id, unsigned long a1, unsigned long a2,\n\t\tunsigned long a3, unsigned long a4, unsigned long a5,\n\t\tunsigned long a6, unsigned long a7, struct arm_smc_res *res);\n\nint do_svc_handler(gp_regs *regs, uint32_t svc_id,\n\t\tuint64_t *args, int smc);\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/syscall.h",
    "content": "#ifndef __ASM_SYSCALL_H__\n#define __ASM_SYSCALL_H__\n\n#define __NR_kobject_create 0\n#define __NR_kobject_open 1\n#define __NR_kobject_close 2\n#define __NR_kobject_recv 3\n#define __NR_kobject_send 4\n#define __NR_kobject_reply 5\n#define __NR_kobject_reply_recv 6\n#define __NR_kobject_ctl 7\n#define __NR_kobject_mmap 8\n#define __NR_kobject_munmap 9\n\n#define __NR_grant 10\n\n#define __NR_futex 11\n#define __NR_yield 12\n\n#define __NR_map 13\n#define __NR_unmap 14\n#define __NR_trans 15\n\n#define __NR_clock_gettime 16\n#define __NR_clock_nanosleep 17\n\n#define __NR_exit 18\n#define __NR_exitgroup 19\n\n#define __NR_clone 20\n\n#undef __NR_syscalls\n#define __NR_syscalls 21\n\nstruct syscall_regs {\n\tunsigned long regs[8];\n};\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/tcb.h",
    "content": "#ifndef __ASM_TCB_H__\n#define __ASM_TCB_H__\n\n#include <minos/types.h>\n\nstruct aarch64_regs {\n\tuint64_t pc;\t\t// elr_el2\n\tuint64_t pstate;\t// spsr_el2\n\tuint64_t sp;\t\t// sp_el0\n\tuint64_t x0;\n\tuint64_t x1;\n\tuint64_t x2;\n\tuint64_t x3;\n\tuint64_t x4;\n\tuint64_t x5;\n\tuint64_t x6;\n\tuint64_t x7;\n\tuint64_t x8;\n\tuint64_t x9;\n\tuint64_t x10;\n\tuint64_t x11;\n\tuint64_t x12;\n\tuint64_t x13;\n\tuint64_t x14;\n\tuint64_t x15;\n\tuint64_t x16;\n\tuint64_t x17;\n\tuint64_t x18;\n\tuint64_t x19;\n\tuint64_t x20;\n\tuint64_t x21;\n\tuint64_t x22;\n\tuint64_t x23;\n\tuint64_t x24;\n\tuint64_t x25;\n\tuint64_t x26;\n\tuint64_t x27;\n\tuint64_t x28;\n\tuint64_t x29;\n\tuint64_t lr;\n}__packed;\n\n#define PT_REG_R0\t3\n\ntypedef struct aarch64_regs gp_regs;\n\nstruct fpsimd_context {\n\tuint64_t regs[64] __align(16);\n\tuint32_t fpsr;\n\tuint32_t fpcr;\n#ifdef CONFIG_VIRT\n\tuint32_t fpexc32_el2;\n\tuint32_t padding0;\n#endif\n};\n\nstruct cpu_context {\n\tuint64_t tpidr_el0;\n\tuint64_t tpidrro_el0;\n\tuint64_t ttbr_el0;\n\tstruct fpsimd_context fpsimd_state;\n};\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/time.h",
    "content": "#ifndef _MINOS_ASM_TIME_H_\n#define _MINOS_ASM_TIME_H_\n\n#include <minos/types.h>\n\nextern uint64_t boot_tick;\nextern uint32_t cpu_khz;\n\nunsigned long get_sys_time(void);\nunsigned long get_current_time(void);\nunsigned long get_sys_ticks(void);\nvoid arch_enable_timer(unsigned long e);\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/tlb.h",
    "content": "#ifndef __MINOS_ASM_TLB_H__\n#define __MINOS_ASM_TLB_H__\n\n#include <minos/mm.h>\n\nstatic inline void flush_tlb_asid_all(uint16_t asid)\n{\n\t/*\n\t * load the ttbr0_el0 value to the register\n\t */\n\tasm volatile (\n\t\t\"lsl %x0, %0, #48\\n\"\n\t\t\"dsb sy\\n\"\n\t\t\"tlbi aside1is, %x0\\n\"\n\t\t\"dsb sy\\n\"\n\t\t\"isb\\n\"\n\t\t:\n\t\t: \"Ir\" (asid)\n\t\t: \"memory\"\n\t);\n}\n\nstatic inline void flush_all_tlb_host(void)\n{\n#ifdef CONFIG_VIRT\n\tasm volatile (\n\t\t\"dsb sy;\"\n\t\t\"tlbi alle2is;\"\n\t\t\"dsb sy;\"\n\t\t\"isb;\"\n\t\t: : : \"memory\"\n\t);\n#else\n\tasm volatile (\n\t\t\"dsb sy;\"\n\t\t\"tlbi alle1is;\"\n\t\t\"dsb sy;\"\n\t\t\"isb;\"\n\t\t: : : \"memory\"\n\t);\n#endif\n}\n\nstatic inline void flush_local_tlb_host(void)\n{\n#ifdef CONFIG_VIRT\n\tasm volatile (\n\t\t\"dsb sy;\"\n\t\t\"tlbi alle2;\"\n\t\t\"dsb sy;\"\n\t\t\"isb;\"\n\t\t: : : \"memory\"\n\t);\n#else\n\tasm volatile (\n\t\t\"dsb sy;\"\n\t\t\"tlbi alle2;\"\n\t\t\"dsb sy;\"\n\t\t\"isb;\"\n\t\t: : : \"memory\"\n\t);\n#endif\n}\n\nstatic inline void flush_tlb_va_host(unsigned long va, unsigned long size)\n{\n\tunsigned long end = va + size;\n\n\tdsb();\n\n#ifdef CONFIG_VIRT\n\twhile (va < end) {\n\t\tasm volatile(\"tlbi vae2is, %0;\" : : \"r\"\n\t\t\t\t(va >> PAGE_SHIFT) : \"memory\");\n\t\tva += PAGE_SIZE;\n\t}\n#else\n\twhile (va < end) {\n\t\tasm volatile(\"tlbi vae1is, %0;\" : : \"r\"\n\t\t\t\t(va >> PAGE_SHIFT) : \"memory\");\n\t\tva += PAGE_SIZE;\n\t}\n#endif\n\n\tdsb();\n\tisb();\n}\n\nstatic inline void flush_local_tlb_va_host(unsigned long va, unsigned long size)\n{\n\tunsigned long end = va + size;\n\n\tdsb();\n\n#ifdef CONFIG_VIRT\n\twhile (va < end) {\n\t\tasm volatile(\"tlbi vae2, %0;\" : : \"r\"\n\t\t\t\t(va >> PAGE_SHIFT) : \"memory\");\n\t\tva += PAGE_SIZE;\n\t}\n#else\n\twhile (va < end) {\n\t\tasm volatile(\"tlbi vae2, %0;\" : : \"r\"\n\t\t\t\t(va >> PAGE_SHIFT) : \"memory\");\n\t\tva += PAGE_SIZE;\n\t}\n#endif\n\n\tdsb();\n\tisb();\n}\n\nstatic inline void flush_local_tlb_guest(void)\n{\n\t/* current VMID only */\n\tasm volatile (\n\t\t\"dsb sy;\"\n\t\t\"tlbi vmalls12e1;\"\n\t\t\"dsb sy;\"\n\t\t\"isb;\"\n\t\t: : : \"memory\"\n\t);\n}\n\nstatic inline void flush_all_tlb_guest(void)\n{\n\t/* current vmid only and innershareable TLBS */\n\tasm volatile(\n\t\t\"dsb sy;\"\n\t\t\"tlbi vmalls12e1is;\"\n\t\t\"dsb sy;\"\n\t\t\"isb;\"\n\t\t: : : \"memory\"\n\t);\n}\n\nstatic inline void flush_tlb_ipa_guest(unsigned long ipa, size_t size)\n{\n\tunsigned long end = ipa + size;\n\n\tdsb();\n\n\t/*\n\t * step 1 - flush stage2 tlb for va range\n\t * step 2 - flush all stage1 tlb for this VM\n\t */\n\twhile (ipa < end) {\n\t\tasm volatile(\"tlbi ipas2e1is, %0;\" : : \"r\"\n\t\t\t\t(ipa >> PAGE_SHIFT) : \"memory\");\n\t\tipa += PAGE_SIZE;\n\t}\n\n\tasm volatile(\"tlbi vmalle1;\");\n\n\tdsb();\n\tisb();\n}\n\nvoid flush_tlb_vm(struct vspace *mm);\nvoid flush_tlb_vm_ipa_range(struct vspace *mm, unsigned long ipa, size_t size);\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/trap.h",
    "content": "#ifndef _MINOS_EXCEPTION_H_\n#define _MINOS_EXCEPTION_H_\n\n#include <config/config.h>\n#include <asm/arch.h>\n\ntypedef int (*sync_handler_t)(gp_regs *reg, int ec, uint32_t esr);\n\nstruct sync_desc {\n\tuint8_t aarch;\n\tuint8_t irq_safe;\n\tuint8_t ret_addr_adjust;\n\tuint8_t resv;\n\tsync_handler_t handler;\n};\n\n#define DEFINE_SYNC_DESC(t, arch, h, is, raa)\t\t\t\\\n\tstatic struct sync_desc sync_desc_##t __used = {\t\\\n\t\t.aarch = arch, \t\t\t\t\t\\\n\t\t.handler = h,\t\t\t\t\t\\\n\t\t.irq_safe = is,\t\t\t\t\t\\\n\t\t.ret_addr_adjust = raa, \t\t\t\\\n\t}\n\nstruct esr {\n\tunsigned long iss:25;  /* Instruction Specific Syndrome */\n\tunsigned long len:1;   /* Instruction length */\n\tunsigned long ec:6;    /* Exception Class */\n};\n\n/* Common to all conditional exception classes (0x0N, except 0x00). */\nstruct esr_cond {\n\tunsigned long iss:20;  /* Instruction Specific Syndrome */\n\tunsigned long cc:4;    /* Condition Code */\n\tunsigned long ccvalid:1;/* CC Valid */\n\tunsigned long len:1;   /* Instruction length */\n\tunsigned long ec:6;    /* Exception Class */\n};\n\nstruct esr_wfi_wfe {\n\tunsigned long ti:1;    /* Trapped instruction */\n\tunsigned long sbzp:19;\n\tunsigned long cc:4;    /* Condition Code */\n\tunsigned long ccvalid:1;/* CC Valid */\n\tunsigned long len:1;   /* Instruction length */\n\tunsigned long ec:6;    /* Exception Class */\n};\n\n/* reg, reg0, reg1 are 4 bits on AArch32, the fifth bit is sbzp. */\nstruct esr_cp32 {\n\tunsigned long read:1;  /* Direction */\n\tunsigned long crm:4;   /* CRm */\n\tunsigned long reg:5;   /* Rt */\n\tunsigned long crn:4;   /* CRn */\n\tunsigned long op1:3;   /* Op1 */\n\tunsigned long op2:3;   /* Op2 */\n\tunsigned long cc:4;    /* Condition Code */\n\tunsigned long ccvalid:1;/* CC Valid */\n\tunsigned long len:1;   /* Instruction length */\n\tunsigned long ec:6;    /* Exception Class */\n};\n\nstruct esr_cp64 {\n\tunsigned long read:1;   /* Direction */\n\tunsigned long crm:4;    /* CRm */\n\tunsigned long reg1:5;   /* Rt1 */\n\tunsigned long reg2:5;   /* Rt2 */\n\tunsigned long sbzp2:1;\n\tunsigned long op1:4;    /* Op1 */\n\tunsigned long cc:4;     /* Condition Code */\n\tunsigned long ccvalid:1;/* CC Valid */\n\tunsigned long len:1;    /* Instruction length */\n\tunsigned long ec:6;     /* Exception Class */\n};\n\nstruct esr_cp {\n\tunsigned long coproc:4; /* Number of coproc accessed */\n\tunsigned long sbz0p:1;\n\tunsigned long tas:1;    /* Trapped Advanced SIMD */\n\tunsigned long res0:14;\n\tunsigned long cc:4;     /* Condition Code */\n\tunsigned long ccvalid:1;/* CC Valid */\n\tunsigned long len:1;    /* Instruction length */\n\tunsigned long ec:6;     /* Exception Class */\n};\n\n/*\n * This encoding is valid only for ARMv8 (ARM DDI 0487B.a, pages D7-2271 and\n * G6-4957). On ARMv7, encoding ISS for EC=0x13 is defined as UNK/SBZP\n * (ARM DDI 0406C.c page B3-1431). UNK/SBZP means that hardware implements\n * this field as Read-As-Zero. ARMv8 is backwards compatible with ARMv7:\n * reading CCKNOWNPASS on ARMv7 will return 0, which means that condition\n * check was passed or instruction was unconditional.\n */\nstruct esr_smc32 {\n\tunsigned long res0:19;  /* Reserved */\n\tunsigned long ccknownpass:1; /* Instruction passed conditional check */\n\tunsigned long cc:4;    /* Condition Code */\n\tunsigned long ccvalid:1;/* CC Valid */\n\tunsigned long len:1;   /* Instruction length */\n\tunsigned long ec:6;    /* Exception Class */\n};\n\nstruct esr_sysreg {\n\tunsigned long read:1;   /* Direction */\n\tunsigned long crm:4;    /* CRm */\n\tunsigned long reg:5;    /* Rt */\n\tunsigned long crn:4;    /* CRn */\n\tunsigned long op1:3;    /* Op1 */\n\tunsigned long op2:3;    /* Op2 */\n\tunsigned long op0:2;    /* Op0 */\n\tunsigned long res0:3;\n\tunsigned long len:1;    /* Instruction length */\n\tunsigned long ec:6;\n};\n\nstruct esr_iabt {\n\tunsigned long ifsc:6;  /* Instruction fault status code */\n\tunsigned long res0:1;  /* RES0 */\n\tunsigned long s1ptw:1; /* Stage 2 fault during stage 1 translation */\n\tunsigned long res1:1;  /* RES0 */\n\tunsigned long eat:1;   /* External abort type */\n\tunsigned long fnv:1;   /* FAR not Valid */\n\tunsigned long res2:14;\n\tunsigned long len:1;   /* Instruction length */\n\tunsigned long ec:6;    /* Exception Class */\n};\n\nstruct esr_dabt {\n\tunsigned long dfsc:6;  /* Data Fault Status Code */\n\tunsigned long write:1; /* Write / not Read */\n\tunsigned long s1ptw:1; /* Stage 2 fault during stage 1 translation */\n\tunsigned long cache:1; /* Cache Maintenance */\n\tunsigned long eat:1;   /* External Abort Type */\n\tunsigned long fnv:1;   /* FAR not Valid */\n#ifdef ARM_AARCH32\n\tunsigned long sbzp0:5;\n#else\n\tunsigned long sbzp0:3;\n\tunsigned long ar:1;    /* Acquire Release */\n\tunsigned long sf:1;    /* Sixty Four bit register */\n#endif\n\tunsigned long reg:5;   /* Register */\n\tunsigned long sign:1;  /* Sign extend */\n\tunsigned long size:2;  /* Access Size */\n\tunsigned long valid:1; /* Syndrome Valid */\n\tunsigned long len:1;   /* Instruction length */\n\tunsigned long ec:6;    /* Exception Class */\n};\n\n/* Contain the common bits between DABT and IABT */\nstruct esr_xabt {\n\tunsigned long fsc:6;    /* Fault status code */\n\tunsigned long pad1:1;   /* Not common */\n\tunsigned long s1ptw:1;  /* Stage 2 fault during stage 1 translation */\n\tunsigned long pad2:1;   /* Not common */\n\tunsigned long eat:1;    /* External abort type */\n\tunsigned long fnv:1;    /* FAR not Valid */\n\tunsigned long pad3:14;  /* Not common */\n\tunsigned long len:1;    /* Instruction length */\n\tunsigned long ec:6;     /* Exception Class */\n};\n\n#ifdef ARM_AARCH64\nstruct esr_brk {\n\tunsigned long comment:16;   /* Comment */\n        unsigned long res0:9;\n        unsigned long len:1;        /* Instruction length */\n        unsigned long ec:6;         /* Exception Class */\n};\n#endif\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/uaccess.h",
    "content": "#ifndef __ASM_UACCESS_H__\n#define __ASM_UACCESS_H__\n\n#include <asm/asm_types.h>\n#include <minos/compiler.h>\n\nstatic inline unsigned long user_ranges_ok(const void __user *addr, unsigned long size)\n{\n\tunsigned long ret, limit = USER_PROCESS_ADDR_LIMIT;\n\n\tasm volatile(\n\t// A + B <= C + 1 for all A,B,C, in four easy steps:\n\t// 1: X = A + B; X' = X % 2^64\n\t\"\tadds\t%0, %3, %2\\n\"\n\t// 2: Set C = 0 if X > 2^64, to guarantee X' > C in step 4\n\t\"\tcsel\t%1, xzr, %1, hi\\n\"\n\t// 3: Set X' = ~0 if X >= 2^64. For X == 2^64, this decrements X'\n\t//    to compensate for the carry flag being set in step 4. For\n\t//    X > 2^64, X' merely has to remain nonzero, which it does.\n\t\"\tcsinv\t%0, %0, xzr, cc\\n\"\n\t// 4: For X < 2^64, this gives us X' - C - 1 <= 0, where the -1\n\t//    comes from the carry in being clear. Otherwise, we are\n\t//    testing X' - C == 0, subject to the previous adjustments.\n\t\"\tsbcs\txzr, %0, %1\\n\"\n\t\"\tcset\t%0, ls\\n\"\n\t: \"=&r\" (ret), \"+r\" (limit) : \"Ir\" (size), \"0\" (addr) : \"cc\");\n\n\treturn ret;\n}\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/virt.h",
    "content": "#ifndef __MINOS_AARCH64_VIRT_H__\n#define __MINOS_AARCH64_VIRT_H__\n\n#include <asm/tcb.h>\n\nstruct vcpu;\n\nstruct arm_virt_data {\n\tint (*dczva_trap)(struct vcpu *vcpu, unsigned long va);\n\tint (*sgi1r_el1_trap)(struct vcpu *vcpu, unsigned long value);\n\tint (*phy_timer_trap)(struct vcpu *vcpu, int reg,\n\t\t\tint read, unsigned long *value);\n\tint (*smc_handler)(struct vcpu *vcpu,\n\t\t\tgp_regs *regs, uint32_t esr);\n\tint (*hvc_handler)(struct vcpu *vcpu,\n\t\t\tgp_regs *regs, uint32_t esr);\n\tint (*sysreg_emulation)(struct vcpu *vcpu, int reg,\n\t\t\tint read, unsigned long *value);\n};\n\nvoid set_current_vmid(uint32_t vmid);\nuint32_t get_current_vmid(void);\nstruct vcpu *get_vcpu_from_reg(void);\nvoid arch_set_virq_flag(void);\nvoid arch_set_vfiq_flag(void);\nvoid arch_clear_vfiq_flag(void);\nvoid arch_clear_virq_flag(void);\n\nvoid arch_vcpu_init(struct vcpu *, void *, void *);\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/include/asm/vtcb.h",
    "content": "#ifndef __ASM_VTCB_H__\n#define __ASM_VTCB_H__\n\n/*\n * 0 is reserved as an invalid value.\n * Order should be kept in sync with the save/restore code.\n */\nenum vcpu_sysreg {\n\t__INVALID_SYSREG__,\n\tMPIDR_EL1,\t/* MultiProcessor Affinity Register */\n\tCSSELR_EL1,\t/* Cache Size Selection Register */\n\tSCTLR_EL1,\t/* System Control Register */\n\tACTLR_EL1,\t/* Auxiliary Control Register */\n\tCPACR_EL1,\t/* Coprocessor Access Control */\n\tTTBR0_EL1,\t/* Translation Table Base Register 0 */\n\tTTBR1_EL1,\t/* Translation Table Base Register 1 */\n\tTCR_EL1,\t/* Translation Control Register */\n\tESR_EL1,\t/* Exception Syndrome Register */\n\tAFSR0_EL1,\t/* Auxiliary Fault Status Register 0 */\n\tAFSR1_EL1,\t/* Auxiliary Fault Status Register 1 */\n\tFAR_EL1,\t/* Fault Address Register */\n\tMAIR_EL1,\t/* Memory Attribute Indirection Register */\n\tVBAR_EL1,\t/* Vector Base Address Register */\n\tCONTEXTIDR_EL1,\t/* Context ID Register */\n\tTPIDR_EL0,\t/* Thread ID, User R/W */\n\tTPIDRRO_EL0,\t/* Thread ID, User R/O */\n\tTPIDR_EL1,\t/* Thread ID, Privileged */\n\tAMAIR_EL1,\t/* Aux Memory Attribute Indirection Register */\n\tCNTKCTL_EL1,\t/* Timer Control Register (EL1) */\n\tPAR_EL1,\t/* Physical Address Register */\n\tMDSCR_EL1,\t/* Monitor Debug System Control Register */\n\tMDCCINT_EL1,\t/* Monitor Debug Comms Channel Interrupt Enable Reg */\n\tDISR_EL1,\t/* Deferred Interrupt Status Register */\n\n\t/* Performance Monitors Registers */\n\tPMCR_EL0,\t/* Control Register */\n\tPMSELR_EL0,\t/* Event Counter Selection Register */\n\tPMEVCNTR0_EL0,\t/* Event Counter Register (0-30) */\n\tPMEVCNTR30_EL0 = PMEVCNTR0_EL0 + 30,\n\tPMCCNTR_EL0,\t/* Cycle Counter Register */\n\tPMEVTYPER0_EL0,\t/* Event Type Register (0-30) */\n\tPMEVTYPER30_EL0 = PMEVTYPER0_EL0 + 30,\n\tPMCCFILTR_EL0,\t/* Cycle Count Filter Register */\n\tPMCNTENSET_EL0,\t/* Count Enable Set Register */\n\tPMINTENSET_EL1,\t/* Interrupt Enable Set Register */\n\tPMOVSSET_EL0,\t/* Overflow Flag Status Set Register */\n\tPMSWINC_EL0,\t/* Software Increment Register */\n\tPMUSERENR_EL0,\t/* User Enable Register */\n\n\t/* 32bit specific registers. Keep them at the end of the range */\n\tDACR32_EL2,\t/* Domain Access Control Register */\n\tIFSR32_EL2,\t/* Instruction Fault Status Register */\n\tFPEXC32_EL2,\t/* Floating-Point Exception Control Register */\n\tDBGVCR32_EL2,\t/* Debug Vector Catch Register */\n\n\tNR_SYS_REGS\t/* Nothing after this line! */\n};\n\nstruct vcpu_context {\n\tuint64_t vbar_el1;\n\tuint64_t esr_el1;\n\tuint64_t sp_el1;\n\tuint64_t sp_el0;\n\tuint64_t elr_el1;\n\tuint64_t vmpidr;\n\tuint64_t vpidr;\n\tuint64_t sctlr_el1;\n\tuint64_t hcr_el2;\n\tuint64_t spsr_el1;\n\tuint64_t far_el1;\n\tuint64_t actlr_el1;\n\tuint64_t tpidr_el1;\n\tuint64_t csselr;\n\tuint64_t cpacr;\n\tuint64_t contextidr;\n\tuint64_t tpidr_el0;\n\tuint64_t tpidrro_el0;\n\tuint64_t cntkctl;\n\tuint64_t afsr0;\n\tuint64_t afsr1;\n\tuint32_t teecr;\n\tuint32_t teehbr;\n\tuint32_t dacr32_el2;\n\tuint32_t ifsr32_el2;\n\n\tuint64_t vtcr_el2;\n\tuint64_t ttbr0_el1;\n\tuint64_t ttbr1_el1;\n\tuint64_t vttbr_el2;\n\tuint64_t mair_el1;\n\tuint64_t amair_el1;\n\tuint64_t tcr_el1;\n\tuint64_t par_el1;\n};\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/lds/Makefile",
    "content": "obj-y\t+= minos.lds\n"
  },
  {
    "path": "kernel/arch/aarch64/lds/minos.lds.S",
    "content": "#include <config/config.h>\n\nENTRY(_start)\nSECTIONS\n{\n\t.vectors CONFIG_MINOS_ENTRY_ADDRESS + CONFIG_PTOV_MASK:\n\t{\n\t\t/*\n\t\t * put all asm code into this section\n\t\t */\n\t\t__minos_start = .;\n\t\t__code_start = .;\n\t\tKEEP(*(__start_up))\n\t\tKEEP(*(__elx_vectors __int_handlers __asm_code))\n\t}\n\n\t.text :\n\t{\n\t\t*(.text)\n\t}\n\n\t. = ALIGN(4096);\n\t__code_end = .;\n\n\t__init_start = .;\n\t__init_func_start = .;\n\t__init_func_0_start = .;\n\t.__init_func_0 : {\n\t\t*(.__init_func_0)\n\t}\n\t__init_func_1_start = .;\n\t.__init_func_1 : {\n\t\t*(.__init_func_1)\n\t}\n\t__init_func_2_start = .;\n\t.__init_func_2 : {\n\t\t*(.__init_func_2)\n\t}\n\t__init_func_3_start = .;\n\t.__init_func_3 : {\n\t\t*(.__init_func_3)\n\t}\n\t__init_func_4_start = .;\n\t.__init_func_4 : {\n\t\t*(.__init_func_4)\n\t}\n\t__init_func_5_start = .;\n\t.__init_func_5 : {\n\t\t*(.__init_func_5)\n\t}\n\t__init_func_6_start = .;\n\t.__init_func_6 : {\n\t\t*(.__init_func_6)\n\t}\n\t__init_func_7_start = .;\n\t.__init_func_7 : {\n\t\t*(.__init_func_7)\n\t}\n\t__init_func_8_start = .;\n\t.__init_func_8 : {\n\t\t*(.__init_func_8)\n\t}\n\t__init_func_9_start = .;\n\t.__init_func_9 : {\n\t\t*(.__init_func_9)\n\t}\n\t__init_func_end = .;\n\n\t. = ALIGN(8);\n\n\t__init_data_start = .;\n\t.__init_data_section : {\n\t\t*(.__init_data_section)\n\t}\n\t__init_data_end = .;\n\n\t. = ALIGN(8);\n\n\t__init_text_start = .;\n\t.__init_text : {\n\t\t*(__init_text)\n\t}\n\t__init_text_end = .;\n\n\t. = ALIGN(4096);\n\t__init_end = .;\n\n\t__data_start = .;\n\t.stage1_page_table : {\n\t\t. = ALIGN(4096);\n\t\t__stage1_page_table = .;\n\t\t. = . + 0x1000;\n\t}\n\n\t.data : {*(.data)}\n\n\t. = ALIGN(8);\n\n\t.smp_affinity_id : {\n\t\t__smp_affinity_id = .;\n\t\t. = . + (CONFIG_NR_CPUS * 8);\n\t\t__smp_affinity_id_end = .;\n\t}\n\n\t. = ALIGN(8);\n\n\t__percpu_start = .;\n\t__percpu_cpu_0_start = .;\n\t.percpu_0 : {\n\t\tKEEP(*(\".__percpu\"))\n\t}\n\t. = ALIGN(64);\n\t__percpu_cpu_0_end = .;\n\t__percpu_section_size = __percpu_cpu_0_end - __percpu_cpu_0_start;\n\n\t.__percpu_others : {\n\n\t}\n\t. = __percpu_cpu_0_end + __percpu_section_size * (CONFIG_NR_CPUS - 1);\n\t__percpu_end = .;\n\n\t. = ALIGN(8);\n\n\t__bss_start = .;\n\t.bss : {*(.bss)}\n\t__bss_end = .;\n\n\t. = ALIGN(8);\n\n\t__vmodule_start = .;\n\t.__vmodule : {\n\t\t*(.__vmodule)\n\t}\n\t__vmodule_end = .;\n\n\t. = ALIGN(8);\n\n\t__platform_start = .;\n\t.__platform : {\n\t\t*(.__platform)\n\t}\n\t__platform_end = .;\n\n\t. = ALIGN(8);\n\n\t__irqchip_start = .;\n\t.__irqchip : {\n\t\t*(.__irqchip)\n\t}\n\t__irqchip_end = .;\n\n\t. = ALIGN(8);\n\n\t__iommu_ops_start = .;\n\t.__iommu_ops : {\n\t\t*(.__iommu_ops)\n\t}\n\t__iommu_ops_end = .;\n\n\t. = ALIGN(8);\n\n\t__virqchip_start = .;\n\t.__virqchip : {\n\t\t*(.__virqchip)\n\t}\n\t__virqchip_end = .;\n\n\t. = ALIGN(8);\n\n\t__vdev_start = .;\n\t.__vdev : {\n\t\t*(.__vdev)\n\t}\n\t__vdev_end = .;\n\n\t__console_start = .;\n\t.__console : {\n\t\t*(.__console)\n\t}\n\t__console_end = .;\n\n\t. = ALIGN(8);\n\n\t__smc_handler_start = .;\n\t.__smc_handler : {\n\t\t*(.__smc_handler)\n\t}\n\t__smc_handler_end = .;\n\n\t. = ALIGN(8);\n\n\t__hvc_handler_start = .;\n\t.__hvc_handler : {\n\t\t*(.__hvc_handler)\n\t}\n\t__hvc_handler_end = .;\n\n\t. = ALIGN(8);\n\n\t__shell_command_start = .;\n\t.__shell_command : {\n\t\t*(.__shell_command)\n\t}\n\t__shell_command_end = .;\n\n\t__kobject_desc_start = .;\n\t.__kobject_desc : {\n               *(.__kobject_desc)\n\t}\n\t__kobject_desc_end = .;\n\n\t. = ALIGN(4096);\n\t__data_end = .;\n\n\t__rodata_start = .;\n\t__symbols_start = .;\n\t.__symbols__ : {\n\t\tKEEP(*(.__symbols__))\n\t}\n\n\t.rodata : {\n\t\tKEEP(*(.rodata))\n\t}\n\t.rodata.str1.8 : {\n\t\tKEEP(*(.rodata.str1.8))\n\t}\n\n\t__minos_end = .;\n}\n"
  },
  {
    "path": "kernel/arch/aarch64/lib/Makefile",
    "content": "# obj-y += atomic.o\nobj-y += bitops.o\nobj-y += memchr.o\nobj-y += memcmp.o\nobj-y += memcpy.o\nobj-y += memmove.o\nobj-y += memset.o\nobj-y += spinlock.o\nobj-y += strchr.o\nobj-y += strcmp.o\nobj-y += strcpy.o\nobj-y += strlen.o\nobj-y += strncmp.o\nobj-y += strnlen.o\nobj-y += strrchr.o\nobj-y += ticket_lock.o\n"
  },
  {
    "path": "kernel/arch/aarch64/lib/atomic.S",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/aarch64_common.h>\n#include <asm/asm_marco.S>\n\n\t.global __atomic_set\n\t.global __atomic_get\n\t.global atomic_add\n\t.global atomic_sub\n\t.global atomic_add_return\n\t.global atomic_add_return_old\n\t.global atomic_sub_return\n\t.global atomic_sub_return_old\n\n\t/*\n\t * ldaxr : a - acquire (equal add a dmb ins)\n\t *         x - exclusive\n\t * ldar ldarb ldarh ldxr ldxrh\n\t *\n\t * stlxr : l - release (equal add a dmb ins)\n\t *       : x - exclusive\n\t * stlr stxr stlrb stlrh stxrh etc\n\t */\n\nfunc __atomic_set\n\tstlr\tw0, [x1]\n\tret\nendfunc __atomic_set\n\nfunc __atomic_get\n\tldar\tw1, [x0]\n\tmov\tw0, w1\n\tret\nendfunc __atomic_get\n\nfunc atomic_add\n1:\n\tldaxr\tw2, [x1]\n\tadd\tw2, w2, w0\n\tstxr\tw3, w2, [x1]\n\tcbnz\tw3, 1b\n\tret\nendfunc atomic_add\n\nfunc atomic_sub\n2:\n\tldaxr\tw2, [x1]\n\tsub\tw2, w2, w0\n\tstlxr\tw3, w2, [x1]\n\tcbnz\tw3, 2b\n\tret\nendfunc atomic_sub\n\nfunc atomic_add_return\n3:\n\tldaxr\tw2, [x1]\n\tadd\tw2, w2, w0\n\tstlxr\tw3, w2, [x1]\n\tcbnz\tw3, 3b\n\tmov\tw0, w2\n\tret\nendfunc atomic_add_return\n\nfunc atomic_sub_return\n4:\n\tldaxr\tw2, [x1]\n\tsub\tw2, w2, w0\n\tstlxr\tw3, w2, [x1]\n\tcbnz\tw3, 4b\n\tmov\tw0, w2\n\tret\nendfunc atomic_sub_return\n\nfunc atomic_add_return_old\n3:\n\tldaxr\tw2, [x1]\n\tadd\tw2, w2, w0\n\tstlxr\tw3, w2, [x1]\n\tcbnz\tw3, 3b\n\tsub\tw0, w2, w0\n\tret\nendfunc atomic_add_return_old\n\nfunc atomic_sub_return_old\n4:\n\tldaxr\tw2, [x1]\n\tsub\tw2, w2, w0\n\tstlxr\tw3, w2, [x1]\n\tcbnz\tw3, 4b\n\tadd\tw0, w2, w0\n\tret\nendfunc atomic_sub_return_old\n"
  },
  {
    "path": "kernel/arch/aarch64/lib/bitops.S",
    "content": "/*\n * Based on linux/arch/arm64/lib/bitops.h which in turn is\n * Based on arch/arm/lib/bitops.h\n *\n * Copyright (C) 2013 ARM Ltd.\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n/*\n * x0: bits 4:0  bit offset\n *     bits 31:5 word offset\n * x1: address\n */\n\n#include <asm/asm_marco.S>\n\n\t.section __asm_code, \"ax\"\n\n\t.global test_bit\n\n\t.macro\tbitop, name, instr\n.global \\name\n\\name:\n.func\t\\name\n.cfi_startproc\n\tand\tw3, w0, #31\t\t// Get bit offset\n\teor\tw0, w0, w3\t\t// Clear low bits\n\tmov\tx2, #1\n\tadd\tx1, x1, x0, lsr #3\t// Get word offset\n\tlsl\tx3, x2, x3\t\t// Create mask\n1:\tldxr\tw2, [x1]\n\t\\instr\tw2, w2, w3\n\tstxr\tw0, w2, [x1]\n\tcbnz\tw0, 1b\n\tret\n.endfunc\n.cfi_endproc\n\t.endm\n\n\t.macro\ttestop, name, instr\n.global \\name\n\\name:\n.func\t\\name\n.cfi_startproc\n\tand\tw3, w0, #31\t\t// Get bit offset\n\teor\tw0, w0, w3\t\t// Clear low bits\n\tmov\tx2, #1\n\tadd\tx1, x1, x0, lsr #3\t// Get word offset\n\tlsl\tx4, x2, x3\t\t// Create mask\n1:\tldxr\tw2, [x1]\n\tlsr\tw0, w2, w3\t\t// Save old value of bit\n\t\\instr\tw2, w2, w4\t\t// toggle bit\n\tstlxr\tw5, w2, [x1]\n\tcbnz\tw5, 1b\n\tdmb\tish\n\tand\tw0, w0, #1\n3:\tret\n.endfunc\n.cfi_endproc\n\t.endm\n\n/*\n * Atomic bit operations.\n */\n\tbitop\tchange_bit, eor\n\tbitop\tclear_bit, bic\n\tbitop\tset_bit, orr\n\n\ttestop\ttest_and_change_bit, eor\n\ttestop\ttest_and_clear_bit, bic\n\ttestop\ttest_and_set_bit, orr\n\nfunc test_bit\n\tand\tw3, w0, #31\t\t// Get bit offset\n\teor\tw0, w0, w3\t\t// Clear low bits\n\tadd\tx1, x1, x0, lsr #3\t// Get word offset\n1:\tldxr\tw2, [x1]\n\tlsr\tw0, w2, w3\t\t// Save old value of bit\n\tand\tw0, w0, #1\n\tret\nendfunc test_bit\n"
  },
  {
    "path": "kernel/arch/aarch64/lib/memchr.S",
    "content": "/*\n * Based on arch/arm/lib/memchr.S\n *\n * Copyright (C) 1995-2000 Russell King\n * Copyright (C) 2013 ARM Ltd.\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/asm_marco.S>\n\n/*\n * Find a character in an area of memory.\n *\n * Parameters:\n *\tx0 - buf\n *\tx1 - c\n *\tx2 - n\n * Returns:\n *\tx0 - address of first occurrence of 'c' or 0\n */\n\t.global memchr\n\nfunc memchr\n\tand\tw1, w1, #0xff\n1:\tsubs\tx2, x2, #1\n\tb.mi\t2f\n\tldrb\tw3, [x0], #1\n\tcmp\tw3, w1\n\tb.ne\t1b\n\tsub\tx0, x0, #1\n\tret\n2:\tmov\tx0, #0\n\tret\nendfunc memchr\n"
  },
  {
    "path": "kernel/arch/aarch64/lib/memcmp.S",
    "content": "/*\n * Copyright (C) 2013 ARM Ltd.\n * Copyright (C) 2013 Linaro.\n *\n * This code is based on glibc cortex strings work originally authored by Linaro\n * and re-licensed under GPLv2 for the Linux kernel. The original code can\n * be found @\n *\n * http://bazaar.launchpad.net/~linaro-toolchain-dev/cortex-strings/trunk/\n * files/head:/src/aarch64/\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/asm_marco.S>\n\n\t.global memcmp\n\n/* Parameters and result.  */\nsrc1\t\t.req\tx0\nsrc2\t\t.req\tx1\nlimit\t\t.req\tx2\nresult\t\t.req\tx0\n\n/* Internal variables.  */\ndata1\t\t.req\tx3\ndata1w\t\t.req\tw3\ndata2\t\t.req\tx4\ndata2w\t\t.req\tw4\nhas_nul\t\t.req\tx5\ndiff\t\t.req\tx6\nendloop\t\t.req\tx7\ntmp1\t\t.req\tx8\ntmp2\t\t.req\tx9\ntmp3\t\t.req\tx10\npos\t\t.req\tx11\nlimit_wd\t.req\tx12\nmask\t\t.req\tx13\n\nfunc memcmp\n\tcbz\tlimit, .Lret0\n\teor\ttmp1, src1, src2\n\ttst\ttmp1, #7\n\tb.ne\t.Lmisaligned8\n\tands\ttmp1, src1, #7\n\tb.ne\t.Lmutual_align\n\tsub\tlimit_wd, limit, #1 /* limit != 0, so no underflow.  */\n\tlsr\tlimit_wd, limit_wd, #3 /* Convert to Dwords.  */\n\t/*\n\t* The input source addresses are at alignment boundary.\n\t* Directly compare eight bytes each time.\n\t*/\n.Lloop_aligned:\n\tldr\tdata1, [src1], #8\n\tldr\tdata2, [src2], #8\n.Lstart_realigned:\n\tsubs\tlimit_wd, limit_wd, #1\n\teor\tdiff, data1, data2\t/* Non-zero if differences found.  */\n\tcsinv\tendloop, diff, xzr, cs\t/* Last Dword or differences.  */\n\tcbz\tendloop, .Lloop_aligned\n\n\t/* Not reached the limit, must have found a diff.  */\n\ttbz\tlimit_wd, #63, .Lnot_limit\n\n\t/* Limit % 8 == 0 => the diff is in the last 8 bytes. */\n\tands\tlimit, limit, #7\n\tb.eq\t.Lnot_limit\n\t/*\n\t* The remained bytes less than 8. It is needed to extract valid data\n\t* from last eight bytes of the intended memory range.\n\t*/\n\tlsl\tlimit, limit, #3\t/* bytes-> bits.  */\n\tmov\tmask, #~0\n\tlsl\tmask, mask, limit\n\tbic\tdata1, data1, mask\n\tbic\tdata2, data2, mask\n\n\torr\tdiff, diff, mask\n\tb\t.Lnot_limit\n\n.Lmutual_align:\n\t/*\n\t* Sources are mutually aligned, but are not currently at an\n\t* alignment boundary. Round down the addresses and then mask off\n\t* the bytes that precede the start point.\n\t*/\n\tbic\tsrc1, src1, #7\n\tbic\tsrc2, src2, #7\n\tldr\tdata1, [src1], #8\n\tldr\tdata2, [src2], #8\n\t/*\n\t* We can not add limit with alignment offset(tmp1) here. Since the\n\t* addition probably make the limit overflown.\n\t*/\n\tsub\tlimit_wd, limit, #1/*limit != 0, so no underflow.*/\n\tand\ttmp3, limit_wd, #7\n\tlsr\tlimit_wd, limit_wd, #3\n\tadd\ttmp3, tmp3, tmp1\n\tadd\tlimit_wd, limit_wd, tmp3, lsr #3\n\tadd\tlimit, limit, tmp1/* Adjust the limit for the extra.  */\n\n\tlsl\ttmp1, tmp1, #3/* Bytes beyond alignment -> bits.*/\n\tneg\ttmp1, tmp1/* Bits to alignment -64.  */\n\tmov\ttmp2, #~0\n\t/*mask off the non-intended bytes before the start address.*/\n\t/* Little-endian.  Early bytes are at LSB.  */\n\tlsr\ttmp2, tmp2, tmp1\n\n\torr\tdata1, data1, tmp2\n\torr\tdata2, data2, tmp2\n\tb\t.Lstart_realigned\n\n\t/*src1 and src2 have different alignment offset.*/\n.Lmisaligned8:\n\tcmp\tlimit, #8\n\tb.lo\t.Ltiny8proc /*limit < 8: compare byte by byte*/\n\n\tand\ttmp1, src1, #7\n\tneg\ttmp1, tmp1\n\tadd\ttmp1, tmp1, #8/*valid length in the first 8 bytes of src1*/\n\tand\ttmp2, src2, #7\n\tneg\ttmp2, tmp2\n\tadd\ttmp2, tmp2, #8/*valid length in the first 8 bytes of src2*/\n\tsubs\ttmp3, tmp1, tmp2\n\tcsel\tpos, tmp1, tmp2, hi /*Choose the maximum.*/\n\n\tsub\tlimit, limit, pos\n\t/*compare the proceeding bytes in the first 8 byte segment.*/\n.Ltinycmp:\n\tldrb\tdata1w, [src1], #1\n\tldrb\tdata2w, [src2], #1\n\tsubs\tpos, pos, #1\n\tccmp\tdata1w, data2w, #0, ne  /* NZCV = 0b0000.  */\n\tb.eq\t.Ltinycmp\n\tcbnz\tpos, 1f /*diff occurred before the last byte.*/\n\tcmp\tdata1w, data2w\n\tb.eq\t.Lstart_align\n1:\n\tsub\tresult, data1, data2\n\tret\n\n.Lstart_align:\n\tlsr\tlimit_wd, limit, #3\n\tcbz\tlimit_wd, .Lremain8\n\n\tands\txzr, src1, #7\n\tb.eq\t.Lrecal_offset\n\t/*process more leading bytes to make src1 aligned...*/\n\tadd\tsrc1, src1, tmp3 /*backwards src1 to alignment boundary*/\n\tadd\tsrc2, src2, tmp3\n\tsub\tlimit, limit, tmp3\n\tlsr\tlimit_wd, limit, #3\n\tcbz\tlimit_wd, .Lremain8\n\t/*load 8 bytes from aligned SRC1..*/\n\tldr\tdata1, [src1], #8\n\tldr\tdata2, [src2], #8\n\n\tsubs\tlimit_wd, limit_wd, #1\n\teor\tdiff, data1, data2  /*Non-zero if differences found.*/\n\tcsinv\tendloop, diff, xzr, ne\n\tcbnz\tendloop, .Lunequal_proc\n\t/*How far is the current SRC2 from the alignment boundary...*/\n\tand\ttmp3, tmp3, #7\n\n.Lrecal_offset:/*src1 is aligned now..*/\n\tneg\tpos, tmp3\n.Lloopcmp_proc:\n\t/*\n\t* Divide the eight bytes into two parts. First,backwards the src2\n\t* to an alignment boundary,load eight bytes and compare from\n\t* the SRC2 alignment boundary. If all 8 bytes are equal,then start\n\t* the second part's comparison. Otherwise finish the comparison.\n\t* This special handle can garantee all the accesses are in the\n\t* thread/vcpu space in avoid to overrange access.\n\t*/\n\tldr\tdata1, [src1,pos]\n\tldr\tdata2, [src2,pos]\n\teor\tdiff, data1, data2  /* Non-zero if differences found.  */\n\tcbnz\tdiff, .Lnot_limit\n\n\t/*The second part process*/\n\tldr\tdata1, [src1], #8\n\tldr\tdata2, [src2], #8\n\teor\tdiff, data1, data2  /* Non-zero if differences found.  */\n\tsubs\tlimit_wd, limit_wd, #1\n\tcsinv\tendloop, diff, xzr, ne/*if limit_wd is 0,will finish the cmp*/\n\tcbz\tendloop, .Lloopcmp_proc\n.Lunequal_proc:\n\tcbz\tdiff, .Lremain8\n\n/* There is difference occurred in the latest comparison. */\n.Lnot_limit:\n/*\n* For little endian,reverse the low significant equal bits into MSB,then\n* following CLZ can find how many equal bits exist.\n*/\n\trev\tdiff, diff\n\trev\tdata1, data1\n\trev\tdata2, data2\n\n\t/*\n\t* The MS-non-zero bit of DIFF marks either the first bit\n\t* that is different, or the end of the significant data.\n\t* Shifting left now will bring the critical information into the\n\t* top bits.\n\t*/\n\tclz\tpos, diff\n\tlsl\tdata1, data1, pos\n\tlsl\tdata2, data2, pos\n\t/*\n\t* We need to zero-extend (char is unsigned) the value and then\n\t* perform a signed subtraction.\n\t*/\n\tlsr\tdata1, data1, #56\n\tsub\tresult, data1, data2, lsr #56\n\tret\n\n.Lremain8:\n\t/* Limit % 8 == 0 =>. all data are equal.*/\n\tands\tlimit, limit, #7\n\tb.eq\t.Lret0\n\n.Ltiny8proc:\n\tldrb\tdata1w, [src1], #1\n\tldrb\tdata2w, [src2], #1\n\tsubs\tlimit, limit, #1\n\n\tccmp\tdata1w, data2w, #0, ne  /* NZCV = 0b0000. */\n\tb.eq\t.Ltiny8proc\n\tsub\tresult, data1, data2\n\tret\n.Lret0:\n\tmov\tresult, #0\n\tret\nendfunc memcmp\n"
  },
  {
    "path": "kernel/arch/aarch64/lib/memcpy.S",
    "content": "/*\n * Copyright (C) 2013 ARM Ltd.\n * Copyright (C) 2013 Linaro.\n *\n * This code is based on glibc cortex strings work originally authored by Linaro\n * and re-licensed under GPLv2 for the Linux kernel. The original code can\n * be found @\n *\n * http://bazaar.launchpad.net/~linaro-toolchain-dev/cortex-strings/trunk/\n * files/head:/src/aarch64/\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/asm_marco.S>\n\n\t.macro ldrb1 ptr, regB, val\n\tldrb  \\ptr, [\\regB], \\val\n\t.endm\n\n\t.macro strb1 ptr, regB, val\n\tstrb \\ptr, [\\regB], \\val\n\t.endm\n\n\t.macro ldrh1 ptr, regB, val\n\tldrh  \\ptr, [\\regB], \\val\n\t.endm\n\n\t.macro strh1 ptr, regB, val\n\tstrh \\ptr, [\\regB], \\val\n\t.endm\n\n\t.macro ldr1 ptr, regB, val\n\tldr \\ptr, [\\regB], \\val\n\t.endm\n\n\t.macro str1 ptr, regB, val\n\tstr \\ptr, [\\regB], \\val\n\t.endm\n\n\t.macro ldp1 ptr, regB, regC, val\n\tldp \\ptr, \\regB, [\\regC], \\val\n\t.endm\n\n\t.macro stp1 ptr, regB, regC, val\n\tstp \\ptr, \\regB, [\\regC], \\val\n\t.endm\n\n\t.global memcpy\n\ndstin\t.req\tx0\nsrc\t.req\tx1\ncount\t.req\tx2\ntmp1\t.req\tx3\ntmp1w\t.req\tw3\ntmp2\t.req\tx4\ntmp2w\t.req\tw4\ndst\t.req\tx6\n\nA_l\t.req\tx7\nA_h\t.req\tx8\nB_l\t.req\tx9\nB_h\t.req\tx10\nC_l\t.req\tx11\nC_h\t.req\tx12\nD_l\t.req\tx13\nD_h\t.req\tx14\n\nfunc memcpy\n\tmov\tdst, dstin\n\tcmp\tcount, #16\n\t/*When memory length is less than 16, the accessed are not aligned.*/\n\tb.lo\t.Ltiny15\n\n\tneg\ttmp2, src\n\tands\ttmp2, tmp2, #15/* Bytes to reach alignment. */\n\tb.eq\t.LSrcAligned\n\tsub\tcount, count, tmp2\n\t/*\n\t* Copy the leading memory data from src to dst in an increasing\n\t* address order.By this way,the risk of overwritting the source\n\t* memory data is eliminated when the distance between src and\n\t* dst is less than 16. The memory accesses here are alignment.\n\t*/\n\ttbz\ttmp2, #0, 1f\n\tldrb1\ttmp1w, src, #1\n\tstrb1\ttmp1w, dst, #1\n1:\n\ttbz\ttmp2, #1, 2f\n\tldrh1\ttmp1w, src, #2\n\tstrh1\ttmp1w, dst, #2\n2:\n\ttbz\ttmp2, #2, 3f\n\tldr1\ttmp1w, src, #4\n\tstr1\ttmp1w, dst, #4\n3:\n\ttbz\ttmp2, #3, .LSrcAligned\n\tldr1\ttmp1, src, #8\n\tstr1\ttmp1, dst, #8\n\n.LSrcAligned:\n\tcmp\tcount, #64\n\tb.ge\t.Lcpy_over64\n\t/*\n\t* Deal with small copies quickly by dropping straight into the\n\t* exit block.\n\t*/\n.Ltail63:\n\t/*\n\t* Copy up to 48 bytes of data. At this point we only need the\n\t* bottom 6 bits of count to be accurate.\n\t*/\n\tands\ttmp1, count, #0x30\n\tb.eq\t.Ltiny15\n\tcmp\ttmp1w, #0x20\n\tb.eq\t1f\n\tb.lt\t2f\n\tldp1\tA_l, A_h, src, #16\n\tstp1\tA_l, A_h, dst, #16\n1:\n\tldp1\tA_l, A_h, src, #16\n\tstp1\tA_l, A_h, dst, #16\n2:\n\tldp1\tA_l, A_h, src, #16\n\tstp1\tA_l, A_h, dst, #16\n.Ltiny15:\n\t/*\n\t* Prefer to break one ldp/stp into several load/store to access\n\t* memory in an increasing address order,rather than to load/store 16\n\t* bytes from (src-16) to (dst-16) and to backward the src to aligned\n\t* address,which way is used in original cortex memcpy. If keeping\n\t* the original memcpy process here, memmove need to satisfy the\n\t* precondition that src address is at least 16 bytes bigger than dst\n\t* address,otherwise some source data will be overwritten when memove\n\t* call memcpy directly. To make memmove simpler and decouple the\n\t* memcpy's dependency on memmove, withdrew the original process.\n\t*/\n\ttbz\tcount, #3, 1f\n\tldr1\ttmp1, src, #8\n\tstr1\ttmp1, dst, #8\n1:\n\ttbz\tcount, #2, 2f\n\tldr1\ttmp1w, src, #4\n\tstr1\ttmp1w, dst, #4\n2:\n\ttbz\tcount, #1, 3f\n\tldrh1\ttmp1w, src, #2\n\tstrh1\ttmp1w, dst, #2\n3:\n\ttbz\tcount, #0, .Lexitfunc\n\tldrb1\ttmp1w, src, #1\n\tstrb1\ttmp1w, dst, #1\n\n\tb\t.Lexitfunc\n\n.Lcpy_over64:\n\tsubs\tcount, count, #128\n\tb.ge\t.Lcpy_body_large\n\t/*\n\t* Less than 128 bytes to copy, so handle 64 here and then jump\n\t* to the tail.\n\t*/\n\tldp1\tA_l, A_h, src, #16\n\tstp1\tA_l, A_h, dst, #16\n\tldp1\tB_l, B_h, src, #16\n\tldp1\tC_l, C_h, src, #16\n\tstp1\tB_l, B_h, dst, #16\n\tstp1\tC_l, C_h, dst, #16\n\tldp1\tD_l, D_h, src, #16\n\tstp1\tD_l, D_h, dst, #16\n\n\ttst\tcount, #0x3f\n\tb.ne\t.Ltail63\n\tb\t.Lexitfunc\n\n\t/*\n\t* Critical loop.  Start at a new cache line boundary.  Assuming\n\t* 64 bytes per line this ensures the entire loop is in one line.\n\t*/\n\t.p2align 6\n.Lcpy_body_large:\n\t/* pre-get 64 bytes data. */\n\tldp1\tA_l, A_h, src, #16\n\tldp1\tB_l, B_h, src, #16\n\tldp1\tC_l, C_h, src, #16\n\tldp1\tD_l, D_h, src, #16\n1:\n\t/*\n\t* interlace the load of next 64 bytes data block with store of the last\n\t* loaded 64 bytes data.\n\t*/\n\tstp1\tA_l, A_h, dst, #16\n\tldp1\tA_l, A_h, src, #16\n\tstp1\tB_l, B_h, dst, #16\n\tldp1\tB_l, B_h, src, #16\n\tstp1\tC_l, C_h, dst, #16\n\tldp1\tC_l, C_h, src, #16\n\tstp1\tD_l, D_h, dst, #16\n\tldp1\tD_l, D_h, src, #16\n\tsubs\tcount, count, #64\n\tb.ge\t1b\n\tstp1\tA_l, A_h, dst, #16\n\tstp1\tB_l, B_h, dst, #16\n\tstp1\tC_l, C_h, dst, #16\n\tstp1\tD_l, D_h, dst, #16\n\n\ttst\tcount, #0x3f\n\tb.ne\t.Ltail63\n.Lexitfunc:\n\tret\nendfunc memcpy\n"
  },
  {
    "path": "kernel/arch/aarch64/lib/memmove.S",
    "content": "/*\n * Copyright (C) 2013 ARM Ltd.\n * Copyright (C) 2013 Linaro.\n *\n * This code is based on glibc cortex strings work originally authored by Linaro\n * and re-licensed under GPLv2 for the Linux kernel. The original code can\n * be found @\n *\n * http://bazaar.launchpad.net/~linaro-toolchain-dev/cortex-strings/trunk/\n * files/head:/src/aarch64/\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/asm_marco.S>\n\n\t.global memmove\n\n/*\n * Move a buffer from src to test (alignment handled by the hardware).\n * If dest <= src, call memcpy, otherwise copy in reverse order.\n *\n * Parameters:\n *\tx0 - dest\n *\tx1 - src\n *\tx2 - n\n * Returns:\n *\tx0 - dest\n */\ndstin\t.req\tx0\nsrc\t.req\tx1\ncount\t.req\tx2\ntmp1\t.req\tx3\ntmp1w\t.req\tw3\ntmp2\t.req\tx4\ntmp2w\t.req\tw4\ntmp3\t.req\tx5\ntmp3w\t.req\tw5\ndst\t.req\tx6\n\nA_l\t.req\tx7\nA_h\t.req\tx8\nB_l\t.req\tx9\nB_h\t.req\tx10\nC_l\t.req\tx11\nC_h\t.req\tx12\nD_l\t.req\tx13\nD_h\t.req\tx14\n\nfunc memmove\n\tcmp\tdstin, src\n\tb.lo\tmemcpy\n\tadd\ttmp1, src, count\n\tcmp\tdstin, tmp1\n\tb.hs\tmemcpy\t\t/* No overlap.  */\n\n\tadd\tdst, dstin, count\n\tadd\tsrc, src, count\n\tcmp\tcount, #16\n\tb.lo\t.Ltail15  /*probably non-alignment accesses.*/\n\n\tands\ttmp2, src, #15     /* Bytes to reach alignment.  */\n\tb.eq\t.LSrcAligned\n\tsub\tcount, count, tmp2\n\t/*\n\t* process the aligned offset length to make the src aligned firstly.\n\t* those extra instructions' cost is acceptable. It also make the\n\t* coming accesses are based on aligned address.\n\t*/\n\ttbz\ttmp2, #0, 1f\n\tldrb\ttmp1w, [src, #-1]!\n\tstrb\ttmp1w, [dst, #-1]!\n1:\n\ttbz\ttmp2, #1, 2f\n\tldrh\ttmp1w, [src, #-2]!\n\tstrh\ttmp1w, [dst, #-2]!\n2:\n\ttbz\ttmp2, #2, 3f\n\tldr\ttmp1w, [src, #-4]!\n\tstr\ttmp1w, [dst, #-4]!\n3:\n\ttbz\ttmp2, #3, .LSrcAligned\n\tldr\ttmp1, [src, #-8]!\n\tstr\ttmp1, [dst, #-8]!\n\n.LSrcAligned:\n\tcmp\tcount, #64\n\tb.ge\t.Lcpy_over64\n\n\t/*\n\t* Deal with small copies quickly by dropping straight into the\n\t* exit block.\n\t*/\n.Ltail63:\n\t/*\n\t* Copy up to 48 bytes of data. At this point we only need the\n\t* bottom 6 bits of count to be accurate.\n\t*/\n\tands\ttmp1, count, #0x30\n\tb.eq\t.Ltail15\n\tcmp\ttmp1w, #0x20\n\tb.eq\t1f\n\tb.lt\t2f\n\tldp\tA_l, A_h, [src, #-16]!\n\tstp\tA_l, A_h, [dst, #-16]!\n1:\n\tldp\tA_l, A_h, [src, #-16]!\n\tstp\tA_l, A_h, [dst, #-16]!\n2:\n\tldp\tA_l, A_h, [src, #-16]!\n\tstp\tA_l, A_h, [dst, #-16]!\n\n.Ltail15:\n\ttbz\tcount, #3, 1f\n\tldr\ttmp1, [src, #-8]!\n\tstr\ttmp1, [dst, #-8]!\n1:\n\ttbz\tcount, #2, 2f\n\tldr\ttmp1w, [src, #-4]!\n\tstr\ttmp1w, [dst, #-4]!\n2:\n\ttbz\tcount, #1, 3f\n\tldrh\ttmp1w, [src, #-2]!\n\tstrh\ttmp1w, [dst, #-2]!\n3:\n\ttbz\tcount, #0, .Lexitfunc\n\tldrb\ttmp1w, [src, #-1]\n\tstrb\ttmp1w, [dst, #-1]\n\n.Lexitfunc:\n\tret\n\n.Lcpy_over64:\n\tsubs\tcount, count, #128\n\tb.ge\t.Lcpy_body_large\n\t/*\n\t* Less than 128 bytes to copy, so handle 64 bytes here and then jump\n\t* to the tail.\n\t*/\n\tldp\tA_l, A_h, [src, #-16]\n\tstp\tA_l, A_h, [dst, #-16]\n\tldp\tB_l, B_h, [src, #-32]\n\tldp\tC_l, C_h, [src, #-48]\n\tstp\tB_l, B_h, [dst, #-32]\n\tstp\tC_l, C_h, [dst, #-48]\n\tldp\tD_l, D_h, [src, #-64]!\n\tstp\tD_l, D_h, [dst, #-64]!\n\n\ttst\tcount, #0x3f\n\tb.ne\t.Ltail63\n\tret\n\n\t/*\n\t* Critical loop. Start at a new cache line boundary. Assuming\n\t* 64 bytes per line this ensures the entire loop is in one line.\n\t*/\n\t.p2align\t6\n.Lcpy_body_large:\n\t/* pre-load 64 bytes data. */\n\tldp\tA_l, A_h, [src, #-16]\n\tldp\tB_l, B_h, [src, #-32]\n\tldp\tC_l, C_h, [src, #-48]\n\tldp\tD_l, D_h, [src, #-64]!\n1:\n\t/*\n\t* interlace the load of next 64 bytes data block with store of the last\n\t* loaded 64 bytes data.\n\t*/\n\tstp\tA_l, A_h, [dst, #-16]\n\tldp\tA_l, A_h, [src, #-16]\n\tstp\tB_l, B_h, [dst, #-32]\n\tldp\tB_l, B_h, [src, #-32]\n\tstp\tC_l, C_h, [dst, #-48]\n\tldp\tC_l, C_h, [src, #-48]\n\tstp\tD_l, D_h, [dst, #-64]!\n\tldp\tD_l, D_h, [src, #-64]!\n\tsubs\tcount, count, #64\n\tb.ge\t1b\n\tstp\tA_l, A_h, [dst, #-16]\n\tstp\tB_l, B_h, [dst, #-32]\n\tstp\tC_l, C_h, [dst, #-48]\n\tstp\tD_l, D_h, [dst, #-64]!\n\n\ttst\tcount, #0x3f\n\tb.ne\t.Ltail63\n\tret\nendfunc memmove\n"
  },
  {
    "path": "kernel/arch/aarch64/lib/memset.S",
    "content": "/*\n * Copyright (C) 2013 ARM Ltd.\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/asm_marco.S>\n\n/*\n * Fill in the buffer with character c (alignment handled by the hardware)\n *\n * Parameters:\n *\tx0 - buf\n *\tx1 - c\n *\tx2 - n\n * Returns:\n *\tx0 - buf\n */\n\t.global memset\n\nfunc memset\n\tmov\tx4, x0\n\tand\tw1, w1, #0xff\n\torr\tw1, w1, w1, lsl #8\n\torr\tw1, w1, w1, lsl #16\n\torr\tx1, x1, x1, lsl #32\n\tsubs\tx2, x2, #8\n\tb.mi\t2f\n1:\tstr\tx1, [x4], #8\n\tsubs\tx2, x2, #8\n\tb.pl\t1b\n2:\tadds\tx2, x2, #4\n\tb.mi\t3f\n\tsub\tx2, x2, #4\n\tstr\tw1, [x4], #4\n3:\tadds\tx2, x2, #2\n\tb.mi\t4f\n\tsub\tx2, x2, #2\n\tstrh\tw1, [x4], #2\n4:\tadds\tx2, x2, #1\n\tb.mi\t5f\n\tstrb\tw1, [x4]\n5:\tret\nendfunc memset\n"
  },
  {
    "path": "kernel/arch/aarch64/lib/spinlock.S",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/asm_marco.S>\n\n\t.global arch_spin_lock\n\t.global arch_spin_unlock\n\nfunc arch_spin_lock\n\tmov\tw2, #1\n\tsevl\nl1:\twfe\nl2:\tldaxr\tw1, [x0]\n\tcbnz\tw1, l1\n\tstlxr\tw1, w2, [x0]\n\tcbnz\tw1, l1\n\tret\nendfunc arch_spin_lock\n\nfunc arch_spin_unlock\n\tstlr\twzr, [x0]\n\tret\nendfunc arch_spin_unlock\n"
  },
  {
    "path": "kernel/arch/aarch64/lib/strchr.S",
    "content": "/*\n * Based on arch/arm/lib/strchr.S\n *\n * Copyright (C) 1995-2000 Russell King\n * Copyright (C) 2013 ARM Ltd.\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/asm_marco.S>\n\n/*\n * Find the first occurrence of a character in a string.\n *\n * Parameters:\n *\tx0 - str\n *\tx1 - c\n * Returns:\n *\tx0 - address of first occurrence of 'c' or 0\n */\n\n\t.global strchr\n\nfunc strchr\n\tand\tw1, w1, #0xff\n1:\tldrb\tw2, [x0], #1\n\tcmp\tw2, w1\n\tccmp\tw2, wzr, #4, ne\n\tb.ne\t1b\n\tsub\tx0, x0, #1\n\tcmp\tw2, w1\n\tcsel\tx0, x0, xzr, eq\n\tret\nendfunc strchr\n"
  },
  {
    "path": "kernel/arch/aarch64/lib/strcmp.S",
    "content": "/*\n * Copyright (C) 2013 ARM Ltd.\n * Copyright (C) 2013 Linaro.\n *\n * This code is based on glibc cortex strings work originally authored by Linaro\n * and re-licensed under GPLv2 for the Linux kernel. The original code can\n * be found @\n *\n * http://bazaar.launchpad.net/~linaro-toolchain-dev/cortex-strings/trunk/\n * files/head:/src/aarch64/\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/asm_marco.S>\n\n\t.global strcmp\n\n#define REP8_01 0x0101010101010101\n#define REP8_7f 0x7f7f7f7f7f7f7f7f\n#define REP8_80 0x8080808080808080\n\n/* Parameters and result.  */\nsrc1\t\t.req\tx0\nsrc2\t\t.req\tx1\nresult\t\t.req\tx0\n\n/* Internal variables.  */\ndata1\t\t.req\tx2\ndata1w\t\t.req\tw2\ndata2\t\t.req\tx3\ndata2w\t\t.req\tw3\nhas_nul\t\t.req\tx4\ndiff\t\t.req\tx5\nsyndrome\t.req\tx6\ntmp1\t\t.req\tx7\ntmp2\t\t.req\tx8\ntmp3\t\t.req\tx9\nzeroones\t.req\tx10\npos\t\t.req\tx11\n\nfunc strcmp\n\teor\ttmp1, src1, src2\n\tmov\tzeroones, #REP8_01\n\ttst\ttmp1, #7\n\tb.ne\t.Lmisaligned8\n\tands\ttmp1, src1, #7\n\tb.ne\t.Lmutual_align\n\n\t/*\n\t* NUL detection works on the principle that (X - 1) & (~X) & 0x80\n\t* (=> (X - 1) & ~(X | 0x7f)) is non-zero iff a byte is zero, and\n\t* can be done in parallel across the entire word.\n\t*/\n.Lloop_aligned:\n\tldr\tdata1, [src1], #8\n\tldr\tdata2, [src2], #8\n.Lstart_realigned:\n\tsub\ttmp1, data1, zeroones\n\torr\ttmp2, data1, #REP8_7f\n\teor\tdiff, data1, data2\t/* Non-zero if differences found.  */\n\tbic\thas_nul, tmp1, tmp2\t/* Non-zero if NUL terminator.  */\n\torr\tsyndrome, diff, has_nul\n\tcbz\tsyndrome, .Lloop_aligned\n\tb\t.Lcal_cmpresult\n\n.Lmutual_align:\n\t/*\n\t* Sources are mutually aligned, but are not currently at an\n\t* alignment boundary.  Round down the addresses and then mask off\n\t* the bytes that preceed the start point.\n\t*/\n\tbic\tsrc1, src1, #7\n\tbic\tsrc2, src2, #7\n\tlsl\ttmp1, tmp1, #3\t\t/* Bytes beyond alignment -> bits.  */\n\tldr\tdata1, [src1], #8\n\tneg\ttmp1, tmp1\t\t/* Bits to alignment -64.  */\n\tldr\tdata2, [src2], #8\n\tmov\ttmp2, #~0\n\t/* Big-endian.  Early bytes are at MSB.  */\n\t/* Little-endian.  Early bytes are at LSB.  */\n\tlsr\ttmp2, tmp2, tmp1\t/* Shift (tmp1 & 63).  */\n\n\torr\tdata1, data1, tmp2\n\torr\tdata2, data2, tmp2\n\tb\t.Lstart_realigned\n\n.Lmisaligned8:\n\t/*\n\t* Get the align offset length to compare per byte first.\n\t* After this process, one string's address will be aligned.\n\t*/\n\tand\ttmp1, src1, #7\n\tneg\ttmp1, tmp1\n\tadd\ttmp1, tmp1, #8\n\tand\ttmp2, src2, #7\n\tneg\ttmp2, tmp2\n\tadd\ttmp2, tmp2, #8\n\tsubs\ttmp3, tmp1, tmp2\n\tcsel\tpos, tmp1, tmp2, hi /*Choose the maximum. */\n.Ltinycmp:\n\tldrb\tdata1w, [src1], #1\n\tldrb\tdata2w, [src2], #1\n\tsubs\tpos, pos, #1\n\tccmp\tdata1w, #1, #0, ne  /* NZCV = 0b0000.  */\n\tccmp\tdata1w, data2w, #0, cs  /* NZCV = 0b0000.  */\n\tb.eq\t.Ltinycmp\n\tcbnz\tpos, 1f /*find the null or unequal...*/\n\tcmp\tdata1w, #1\n\tccmp\tdata1w, data2w, #0, cs\n\tb.eq\t.Lstart_align /*the last bytes are equal....*/\n1:\n\tsub\tresult, data1, data2\n\tret\n\n.Lstart_align:\n\tands\txzr, src1, #7\n\tb.eq\t.Lrecal_offset\n\t/*process more leading bytes to make str1 aligned...*/\n\tadd\tsrc1, src1, tmp3\n\tadd\tsrc2, src2, tmp3\n\t/*load 8 bytes from aligned str1 and non-aligned str2..*/\n\tldr\tdata1, [src1], #8\n\tldr\tdata2, [src2], #8\n\n\tsub\ttmp1, data1, zeroones\n\torr\ttmp2, data1, #REP8_7f\n\tbic\thas_nul, tmp1, tmp2\n\teor\tdiff, data1, data2 /* Non-zero if differences found.  */\n\torr\tsyndrome, diff, has_nul\n\tcbnz\tsyndrome, .Lcal_cmpresult\n\t/*How far is the current str2 from the alignment boundary...*/\n\tand\ttmp3, tmp3, #7\n.Lrecal_offset:\n\tneg\tpos, tmp3\n.Lloopcmp_proc:\n\t/*\n\t* Divide the eight bytes into two parts. First,backwards the src2\n\t* to an alignment boundary,load eight bytes from the SRC2 alignment\n\t* boundary,then compare with the relative bytes from SRC1.\n\t* If all 8 bytes are equal,then start the second part's comparison.\n\t* Otherwise finish the comparison.\n\t* This special handle can garantee all the accesses are in the\n\t* thread/vcpu space in avoid to overrange access.\n\t*/\n\tldr\tdata1, [src1,pos]\n\tldr\tdata2, [src2,pos]\n\tsub\ttmp1, data1, zeroones\n\torr\ttmp2, data1, #REP8_7f\n\tbic\thas_nul, tmp1, tmp2\n\teor\tdiff, data1, data2  /* Non-zero if differences found.  */\n\torr\tsyndrome, diff, has_nul\n\tcbnz\tsyndrome, .Lcal_cmpresult\n\n\t/*The second part process*/\n\tldr\tdata1, [src1], #8\n\tldr\tdata2, [src2], #8\n\tsub\ttmp1, data1, zeroones\n\torr\ttmp2, data1, #REP8_7f\n\tbic\thas_nul, tmp1, tmp2\n\teor\tdiff, data1, data2  /* Non-zero if differences found.  */\n\torr\tsyndrome, diff, has_nul\n\tcbz\tsyndrome, .Lloopcmp_proc\n\n.Lcal_cmpresult:\n\t/*\n\t* reversed the byte-order as big-endian,then CLZ can find the most\n\t* significant zero bits.\n\t*/\n\trev\tsyndrome, syndrome\n\trev\tdata1, data1\n\trev\tdata2, data2\n\n\t/*\n\t* For big-endian we cannot use the trick with the syndrome value\n\t* as carry-propagation can corrupt the upper bits if the trailing\n\t* bytes in the string contain 0x01.\n\t* However, if there is no NUL byte in the dword, we can generate\n\t* the result directly.  We ca not just subtract the bytes as the\n\t* MSB might be significant.\n\t*/\n\t/*Re-compute the NUL-byte detection, using a byte-reversed value. */\n\n\tclz\tpos, syndrome\n\t/*\n\t* The MS-non-zero bit of the syndrome marks either the first bit\n\t* that is different, or the top bit of the first zero byte.\n\t* Shifting left now will bring the critical information into the\n\t* top bits.\n\t*/\n\tlsl\tdata1, data1, pos\n\tlsl\tdata2, data2, pos\n\t/*\n\t* But we need to zero-extend (char is unsigned) the value and then\n\t* perform a signed 32-bit subtraction.\n\t*/\n\tlsr\tdata1, data1, #56\n\tsub\tresult, data1, data2, lsr #56\n\tret\nendfunc strcmp\n"
  },
  {
    "path": "kernel/arch/aarch64/lib/strcpy.S",
    "content": "/*\n * Copyright (C) 2013 ARM Ltd.\n * Copyright (C) 2013 Linaro.\n * Copyright (C) 2014 The Android Open Source Project\n *\n * This code is based on glibc cortex strings work originally authored by Linaro\n * and re-licensed under GPLv2 for the Linux kernel. The original code can\n * be found @\n *\n * http://bazaar.launchpad.net/~linaro-toolchain-dev/cortex-strings/trunk/\n * files/head:/src/aarch64/\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/asm_marco.S>\n\n\t.global strcpy\n\ndst_in\t\t.req x0\nsrc\t\t.req x1\ndst\t\t.req x2\ndata_1\t\t.req x3\ndata_1_w\t.req w3\ndata2\t\t.req x4\ndata2_w\t\t.req w4\nhas_nul1\t.req x5\nhas_nul1_w\t.req w5\nhas_nul2\t.req x6\ntmp1\t\t.req x7\ntmp2\t\t.req x8\ntmp3\t\t.req x9\ntmp4\t\t.req x10\nzero_oness\t.req x11\nzero_oness_w\t.req w11\npos\t\t.req x12\n\n#define REP8_01 0x0101010101010101\n#define REP8_7f 0x7f7f7f7f7f7f7f7f\n#define REP8_80 0x8080808080808080\n\nfunc strcpy\n    mov     zero_oness, #REP8_01\n    mov     dst, dst_in\n    ands    tmp1, src, #15\n    b.ne    .Lmisaligned\n.Lloop:\n    ldp     data_1, data2, [src], #16\n    sub     tmp1, data_1, zero_oness\n    orr     tmp2, data_1, #REP8_7f\n    bic     has_nul1, tmp1, tmp2\n    cbnz    has_nul1, .Lnul_in_data_1\n    sub     tmp3, data2, zero_oness\n    orr     tmp4, data2, #REP8_7f\n    bic     has_nul2, tmp3, tmp4\n    cbnz    has_nul2, .Lnul_in_data2\n    stp     data_1, data2, [dst], #16\n    b       .Lloop\n\n.Lnul_in_data_1:\n    rev     has_nul1, has_nul1\n    clz     pos, has_nul1\n    add     tmp1, pos, #0x8\n\n    tbz     tmp1, #6, 1f\n    str     data_1, [dst]\n    ret\n1:\n    tbz     tmp1, #5, 1f\n    str     data_1_w, [dst], #4\n    lsr     data_1, data_1, #32\n1:\n    tbz     tmp1, #4, 1f\n    strh    data_1_w, [dst], #2\n    lsr     data_1, data_1, #16\n1:\n    tbz     tmp1, #3, 1f\n    strb    data_1_w, [dst]\n1:\n    ret\n\n.Lnul_in_data2:\n    str     data_1, [dst], #8\n    rev     has_nul2, has_nul2\n    clz     pos, has_nul2\n    add     tmp1, pos, #0x8\n\n    tbz     tmp1, #6, 1f\n    str     data2, [dst]\n    ret\n1:\n    tbz     tmp1, #5, 1f\n    str     data2_w, [dst], #4\n    lsr     data2, data2, #32\n1:\n    tbz     tmp1, #4, 1f\n    strh    data2_w, [dst], #2\n    lsr     data2, data2, #16\n1:\n    tbz     tmp1, #3, 1f\n    strb    data2_w, [dst]\n1:\n    ret\n\n.Lmisaligned:\n    tbz     src, #0, 1f\n    ldrb    data_1_w, [src], #1\n    strb    data_1_w, [dst], #1\n    cbnz    data_1_w, 1f\n    ret\n1:\n    tbz     src, #1, 1f\n    ldrb    data_1_w, [src], #1\n    strb    data_1_w, [dst], #1\n    cbz     data_1_w, .Ldone\n    ldrb    data2_w, [src], #1\n    strb    data2_w, [dst], #1\n    cbnz    data2_w, 1f\n.Ldone:\n    ret\n1:\n    tbz     src, #2, 1f\n    ldr     data_1_w, [src], #4\n    sub     has_nul1_w, data_1_w, zero_oness_w\n    bic     has_nul1_w, has_nul1_w, data_1_w\n    ands    has_nul1_w, has_nul1_w, #0x80808080\n    b.ne    .Lnul_in_data_1\n    str     data_1_w, [dst], #4\n1:\n    tbz     src, #3, .Lloop\n    ldr     data_1, [src], #8\n    sub     tmp1, data_1, zero_oness\n    orr     tmp2, data_1, #REP8_7f\n    bics    has_nul1, tmp1, tmp2\n    b.ne    .Lnul_in_data_1\n    str     data_1, [dst], #8\n    b       .Lloop\nendfunc strcpy\n"
  },
  {
    "path": "kernel/arch/aarch64/lib/strlen.S",
    "content": "/*\n * Copyright (C) 2013 ARM Ltd.\n * Copyright (C) 2013 Linaro.\n *\n * This code is based on glibc cortex strings work originally authored by Linaro\n * and re-licensed under GPLv2 for the Linux kernel. The original code can\n * be found @\n *\n * http://bazaar.launchpad.net/~linaro-toolchain-dev/cortex-strings/trunk/\n * files/head:/src/aarch64/\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/asm_marco.S>\n\n\t.global strlen\n\n/*\n * calculate the length of a string\n *\n * Parameters:\n *\tx0 - const string pointer\n * Returns:\n *\tx0 - the return length of specific string\n */\n\n/* Arguments and results.  */\nsrcin\t\t.req\tx0\nlen\t\t.req\tx0\n\n/* Locals and temporaries.  */\nsrc\t\t.req\tx1\ndata1\t\t.req\tx2\ndata2\t\t.req\tx3\ndata2a\t\t.req\tx4\nhas_nul1\t.req\tx5\nhas_nul2\t.req\tx6\ntmp1\t\t.req\tx7\ntmp2\t\t.req\tx8\ntmp3\t\t.req\tx9\ntmp4\t\t.req\tx10\nzeroones\t.req\tx11\npos\t\t.req\tx12\n\n#define REP8_01 0x0101010101010101\n#define REP8_7f 0x7f7f7f7f7f7f7f7f\n#define REP8_80 0x8080808080808080\n\nfunc strlen\n\tmov\tzeroones, #REP8_01\n\tbic\tsrc, srcin, #15\n\tands\ttmp1, srcin, #15\n\tb.ne\t.Lmisaligned\n\t/*\n\t* NUL detection works on the principle that (X - 1) & (~X) & 0x80\n\t* (=> (X - 1) & ~(X | 0x7f)) is non-zero iff a byte is zero, and\n\t* can be done in parallel across the entire word.\n\t*/\n\t/*\n\t* The inner loop deals with two Dwords at a time. This has a\n\t* slightly higher start-up cost, but we should win quite quickly,\n\t* especially on cores with a high number of issue slots per\n\t* cycle, as we get much better parallelism out of the operations.\n\t*/\n.Lloop:\n\tldp\tdata1, data2, [src], #16\n.Lrealigned:\n\tsub\ttmp1, data1, zeroones\n\torr\ttmp2, data1, #REP8_7f\n\tsub\ttmp3, data2, zeroones\n\torr\ttmp4, data2, #REP8_7f\n\tbic\thas_nul1, tmp1, tmp2\n\tbics\thas_nul2, tmp3, tmp4\n\tccmp\thas_nul1, #0, #0, eq\t/* NZCV = 0000  */\n\tb.eq\t.Lloop\n\n\tsub\tlen, src, srcin\n\tcbz\thas_nul1, .Lnul_in_data2\n\tsub\tlen, len, #8\n\tmov\thas_nul2, has_nul1\n.Lnul_in_data2:\n\t/*\n\t* For big-endian, carry propagation (if the final byte in the\n\t* string is 0x01) means we cannot use has_nul directly.  The\n\t* easiest way to get the correct byte is to byte-swap the data\n\t* and calculate the syndrome a second time.\n\t*/\n\tsub\tlen, len, #8\n\trev\thas_nul2, has_nul2\n\tclz\tpos, has_nul2\n\tadd\tlen, len, pos, lsr #3\t\t/* Bits to bytes.  */\n\tret\n\n.Lmisaligned:\n\tcmp\ttmp1, #8\n\tneg\ttmp1, tmp1\n\tldp\tdata1, data2, [src], #16\n\tlsl\ttmp1, tmp1, #3\t\t/* Bytes beyond alignment -> bits.  */\n\tmov\ttmp2, #~0\n\t/* Big-endian.  Early bytes are at MSB.  */\n\t/* Little-endian.  Early bytes are at LSB.  */\n\tlsr\ttmp2, tmp2, tmp1\t/* Shift (tmp1 & 63).  */\n\n\torr\tdata1, data1, tmp2\n\torr\tdata2a, data2, tmp2\n\tcsinv\tdata1, data1, xzr, le\n\tcsel\tdata2, data2, data2a, le\n\tb\t.Lrealigned\nendfunc strlen\n"
  },
  {
    "path": "kernel/arch/aarch64/lib/strncmp.S",
    "content": "/*\n * Copyright (C) 2013 ARM Ltd.\n * Copyright (C) 2013 Linaro.\n *\n * This code is based on glibc cortex strings work originally authored by Linaro\n * and re-licensed under GPLv2 for the Linux kernel. The original code can\n * be found @\n *\n * http://bazaar.launchpad.net/~linaro-toolchain-dev/cortex-strings/trunk/\n * files/head:/src/aarch64/\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/asm_marco.S>\n\n\t.global strncmp\n\n/*\n * compare two strings\n *\n * Parameters:\n *  x0 - const string 1 pointer\n *  x1 - const string 2 pointer\n *  x2 - the maximal length to be compared\n * Returns:\n *  x0 - an integer less than, equal to, or greater than zero if s1 is found,\n *     respectively, to be less than, to match, or be greater than s2.\n */\n\n#define REP8_01 0x0101010101010101\n#define REP8_7f 0x7f7f7f7f7f7f7f7f\n#define REP8_80 0x8080808080808080\n\n/* Parameters and result.  */\nsrc1\t\t.req\tx0\nsrc2\t\t.req\tx1\nlimit\t\t.req\tx2\nresult\t\t.req\tx0\n\n/* Internal variables.  */\ndata1\t\t.req\tx3\ndata1w\t\t.req\tw3\ndata2\t\t.req\tx4\ndata2w\t\t.req\tw4\nhas_nul\t\t.req\tx5\ndiff\t\t.req\tx6\nsyndrome\t.req\tx7\ntmp1\t\t.req\tx8\ntmp2\t\t.req\tx9\ntmp3\t\t.req\tx10\nzeroones\t.req\tx11\npos\t\t.req\tx12\nlimit_wd\t.req\tx13\nmask\t\t.req\tx14\nendloop\t\t.req\tx15\n\nfunc strncmp\n\tcbz\tlimit, .Lret0\n\teor\ttmp1, src1, src2\n\tmov\tzeroones, #REP8_01\n\ttst\ttmp1, #7\n\tb.ne\t.Lmisaligned8\n\tands\ttmp1, src1, #7\n\tb.ne\t.Lmutual_align\n\t/* Calculate the number of full and partial words -1.  */\n\t/*\n\t* when limit is mulitply of 8, if not sub 1,\n\t* the judgement of last dword will wrong.\n\t*/\n\tsub\tlimit_wd, limit, #1 /* limit != 0, so no underflow.  */\n\tlsr\tlimit_wd, limit_wd, #3  /* Convert to Dwords.  */\n\n\t/*\n\t* NUL detection works on the principle that (X - 1) & (~X) & 0x80\n\t* (=> (X - 1) & ~(X | 0x7f)) is non-zero iff a byte is zero, and\n\t* can be done in parallel across the entire word.\n\t*/\n.Lloop_aligned:\n\tldr\tdata1, [src1], #8\n\tldr\tdata2, [src2], #8\n.Lstart_realigned:\n\tsubs\tlimit_wd, limit_wd, #1\n\tsub\ttmp1, data1, zeroones\n\torr\ttmp2, data1, #REP8_7f\n\teor\tdiff, data1, data2  /* Non-zero if differences found.  */\n\tcsinv\tendloop, diff, xzr, pl  /* Last Dword or differences.*/\n\tbics\thas_nul, tmp1, tmp2 /* Non-zero if NUL terminator.  */\n\tccmp\tendloop, #0, #0, eq\n\tb.eq\t.Lloop_aligned\n\n\t/*Not reached the limit, must have found the end or a diff.  */\n\ttbz\tlimit_wd, #63, .Lnot_limit\n\n\t/* Limit % 8 == 0 => all bytes significant.  */\n\tands\tlimit, limit, #7\n\tb.eq\t.Lnot_limit\n\n\tlsl\tlimit, limit, #3    /* Bits -> bytes.  */\n\tmov\tmask, #~0\n\tlsl\tmask, mask, limit\n\tbic\tdata1, data1, mask\n\tbic\tdata2, data2, mask\n\n\t/* Make sure that the NUL byte is marked in the syndrome.  */\n\torr\thas_nul, has_nul, mask\n\n.Lnot_limit:\n\torr\tsyndrome, diff, has_nul\n\tb\t.Lcal_cmpresult\n\n.Lmutual_align:\n\t/*\n\t* Sources are mutually aligned, but are not currently at an\n\t* alignment boundary.  Round down the addresses and then mask off\n\t* the bytes that precede the start point.\n\t* We also need to adjust the limit calculations, but without\n\t* overflowing if the limit is near ULONG_MAX.\n\t*/\n\tbic\tsrc1, src1, #7\n\tbic\tsrc2, src2, #7\n\tldr\tdata1, [src1], #8\n\tneg\ttmp3, tmp1, lsl #3  /* 64 - bits(bytes beyond align). */\n\tldr\tdata2, [src2], #8\n\tmov\ttmp2, #~0\n\tsub\tlimit_wd, limit, #1 /* limit != 0, so no underflow.  */\n\t/* Big-endian.  Early bytes are at MSB.  */\n\t/* Little-endian.  Early bytes are at LSB.  */\n\tlsr\ttmp2, tmp2, tmp3\t/* Shift (tmp1 & 63).  */\n\n\tand\ttmp3, limit_wd, #7\n\tlsr\tlimit_wd, limit_wd, #3\n\t/* Adjust the limit. Only low 3 bits used, so overflow irrelevant.*/\n\tadd\tlimit, limit, tmp1\n\tadd\ttmp3, tmp3, tmp1\n\torr\tdata1, data1, tmp2\n\torr\tdata2, data2, tmp2\n\tadd\tlimit_wd, limit_wd, tmp3, lsr #3\n\tb\t.Lstart_realigned\n\n/*when src1 offset is not equal to src2 offset...*/\n.Lmisaligned8:\n\tcmp\tlimit, #8\n\tb.lo\t.Ltiny8proc /*limit < 8... */\n\t/*\n\t* Get the align offset length to compare per byte first.\n\t* After this process, one string's address will be aligned.*/\n\tand\ttmp1, src1, #7\n\tneg\ttmp1, tmp1\n\tadd\ttmp1, tmp1, #8\n\tand\ttmp2, src2, #7\n\tneg\ttmp2, tmp2\n\tadd\ttmp2, tmp2, #8\n\tsubs\ttmp3, tmp1, tmp2\n\tcsel\tpos, tmp1, tmp2, hi /*Choose the maximum. */\n\t/*\n\t* Here, limit is not less than 8, so directly run .Ltinycmp\n\t* without checking the limit.*/\n\tsub\tlimit, limit, pos\n.Ltinycmp:\n\tldrb\tdata1w, [src1], #1\n\tldrb\tdata2w, [src2], #1\n\tsubs\tpos, pos, #1\n\tccmp\tdata1w, #1, #0, ne  /* NZCV = 0b0000.  */\n\tccmp\tdata1w, data2w, #0, cs  /* NZCV = 0b0000.  */\n\tb.eq\t.Ltinycmp\n\tcbnz\tpos, 1f /*find the null or unequal...*/\n\tcmp\tdata1w, #1\n\tccmp\tdata1w, data2w, #0, cs\n\tb.eq\t.Lstart_align /*the last bytes are equal....*/\n1:\n\tsub\tresult, data1, data2\n\tret\n\n.Lstart_align:\n\tlsr\tlimit_wd, limit, #3\n\tcbz\tlimit_wd, .Lremain8\n\t/*process more leading bytes to make str1 aligned...*/\n\tands\txzr, src1, #7\n\tb.eq\t.Lrecal_offset\n\tadd\tsrc1, src1, tmp3\t/*tmp3 is positive in this branch.*/\n\tadd\tsrc2, src2, tmp3\n\tldr\tdata1, [src1], #8\n\tldr\tdata2, [src2], #8\n\n\tsub\tlimit, limit, tmp3\n\tlsr\tlimit_wd, limit, #3\n\tsubs\tlimit_wd, limit_wd, #1\n\n\tsub\ttmp1, data1, zeroones\n\torr\ttmp2, data1, #REP8_7f\n\teor\tdiff, data1, data2  /* Non-zero if differences found.  */\n\tcsinv\tendloop, diff, xzr, ne/*if limit_wd is 0,will finish the cmp*/\n\tbics\thas_nul, tmp1, tmp2\n\tccmp\tendloop, #0, #0, eq /*has_null is ZERO: no null byte*/\n\tb.ne\t.Lunequal_proc\n\t/*How far is the current str2 from the alignment boundary...*/\n\tand\ttmp3, tmp3, #7\n.Lrecal_offset:\n\tneg\tpos, tmp3\n.Lloopcmp_proc:\n\t/*\n\t* Divide the eight bytes into two parts. First,backwards the src2\n\t* to an alignment boundary,load eight bytes from the SRC2 alignment\n\t* boundary,then compare with the relative bytes from SRC1.\n\t* If all 8 bytes are equal,then start the second part's comparison.\n\t* Otherwise finish the comparison.\n\t* This special handle can garantee all the accesses are in the\n\t* thread/vcpu space in avoid to overrange access.\n\t*/\n\tldr\tdata1, [src1,pos]\n\tldr\tdata2, [src2,pos]\n\tsub\ttmp1, data1, zeroones\n\torr\ttmp2, data1, #REP8_7f\n\tbics\thas_nul, tmp1, tmp2 /* Non-zero if NUL terminator.  */\n\teor\tdiff, data1, data2  /* Non-zero if differences found.  */\n\tcsinv\tendloop, diff, xzr, eq\n\tcbnz\tendloop, .Lunequal_proc\n\n\t/*The second part process*/\n\tldr\tdata1, [src1], #8\n\tldr\tdata2, [src2], #8\n\tsubs\tlimit_wd, limit_wd, #1\n\tsub\ttmp1, data1, zeroones\n\torr\ttmp2, data1, #REP8_7f\n\teor\tdiff, data1, data2  /* Non-zero if differences found.  */\n\tcsinv\tendloop, diff, xzr, ne/*if limit_wd is 0,will finish the cmp*/\n\tbics\thas_nul, tmp1, tmp2\n\tccmp\tendloop, #0, #0, eq /*has_null is ZERO: no null byte*/\n\tb.eq\t.Lloopcmp_proc\n\n.Lunequal_proc:\n\torr\tsyndrome, diff, has_nul\n\tcbz\tsyndrome, .Lremain8\n.Lcal_cmpresult:\n\t/*\n\t* reversed the byte-order as big-endian,then CLZ can find the most\n\t* significant zero bits.\n\t*/\n\trev\tsyndrome, syndrome\n\trev\tdata1, data1\n\trev\tdata2, data2\n\t/*\n\t* For big-endian we cannot use the trick with the syndrome value\n\t* as carry-propagation can corrupt the upper bits if the trailing\n\t* bytes in the string contain 0x01.\n\t* However, if there is no NUL byte in the dword, we can generate\n\t* the result directly.  We can't just subtract the bytes as the\n\t* MSB might be significant.\n\t*/\n\t/*\n\t* The MS-non-zero bit of the syndrome marks either the first bit\n\t* that is different, or the top bit of the first zero byte.\n\t* Shifting left now will bring the critical information into the\n\t* top bits.\n\t*/\n\tclz\tpos, syndrome\n\tlsl\tdata1, data1, pos\n\tlsl\tdata2, data2, pos\n\t/*\n\t* But we need to zero-extend (char is unsigned) the value and then\n\t* perform a signed 32-bit subtraction.\n\t*/\n\tlsr\tdata1, data1, #56\n\tsub\tresult, data1, data2, lsr #56\n\tret\n\n.Lremain8:\n\t/* Limit % 8 == 0 => all bytes significant.  */\n\tands\tlimit, limit, #7\n\tb.eq\t.Lret0\n.Ltiny8proc:\n\tldrb\tdata1w, [src1], #1\n\tldrb\tdata2w, [src2], #1\n\tsubs\tlimit, limit, #1\n\n\tccmp\tdata1w, #1, #0, ne  /* NZCV = 0b0000.  */\n\tccmp\tdata1w, data2w, #0, cs  /* NZCV = 0b0000.  */\n\tb.eq\t.Ltiny8proc\n\tsub\tresult, data1, data2\n\tret\n\n.Lret0:\n\tmov\tresult, #0\n\tret\nendfunc strncmp\n"
  },
  {
    "path": "kernel/arch/aarch64/lib/strnlen.S",
    "content": "/*\n * Copyright (C) 2013 ARM Ltd.\n * Copyright (C) 2013 Linaro.\n *\n * This code is based on glibc cortex strings work originally authored by Linaro\n * and re-licensed under GPLv2 for the Linux kernel. The original code can\n * be found @\n *\n * http://bazaar.launchpad.net/~linaro-toolchain-dev/cortex-strings/trunk/\n * files/head:/src/aarch64/\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/asm_marco.S>\n\n\t.global strnlen\n\n/*\n * determine the length of a fixed-size string\n *\n * Parameters:\n *\tx0 - const string pointer\n *\tx1 - maximal string length\n * Returns:\n *\tx0 - the return length of specific string\n */\n\n/* Arguments and results.  */\nsrcin\t\t.req\tx0\nlen\t\t.req\tx0\nlimit\t\t.req\tx1\n\n/* Locals and temporaries.  */\nsrc\t\t.req\tx2\ndata1\t\t.req\tx3\ndata2\t\t.req\tx4\ndata2a\t\t.req\tx5\nhas_nul1\t.req\tx6\nhas_nul2\t.req\tx7\ntmp1\t\t.req\tx8\ntmp2\t\t.req\tx9\ntmp3\t\t.req\tx10\ntmp4\t\t.req\tx11\nzeroones\t.req\tx12\npos\t\t.req\tx13\nlimit_wd\t.req\tx14\n\n#define REP8_01 0x0101010101010101\n#define REP8_7f 0x7f7f7f7f7f7f7f7f\n#define REP8_80 0x8080808080808080\n\nfunc strnlen\n\tcbz\tlimit, .Lhit_limit\n\tmov\tzeroones, #REP8_01\n\tbic\tsrc, srcin, #15\n\tands\ttmp1, srcin, #15\n\tb.ne\t.Lmisaligned\n\t/* Calculate the number of full and partial words -1.  */\n\tsub\tlimit_wd, limit, #1 /* Limit != 0, so no underflow.  */\n\tlsr\tlimit_wd, limit_wd, #4  /* Convert to Qwords.  */\n\n\t/*\n\t* NUL detection works on the principle that (X - 1) & (~X) & 0x80\n\t* (=> (X - 1) & ~(X | 0x7f)) is non-zero iff a byte is zero, and\n\t* can be done in parallel across the entire word.\n\t*/\n\t/*\n\t* The inner loop deals with two Dwords at a time.  This has a\n\t* slightly higher start-up cost, but we should win quite quickly,\n\t* especially on cores with a high number of issue slots per\n\t* cycle, as we get much better parallelism out of the operations.\n\t*/\n.Lloop:\n\tldp\tdata1, data2, [src], #16\n.Lrealigned:\n\tsub\ttmp1, data1, zeroones\n\torr\ttmp2, data1, #REP8_7f\n\tsub\ttmp3, data2, zeroones\n\torr\ttmp4, data2, #REP8_7f\n\tbic\thas_nul1, tmp1, tmp2\n\tbic\thas_nul2, tmp3, tmp4\n\tsubs\tlimit_wd, limit_wd, #1\n\torr\ttmp1, has_nul1, has_nul2\n\tccmp\ttmp1, #0, #0, pl    /* NZCV = 0000  */\n\tb.eq\t.Lloop\n\n\tcbz\ttmp1, .Lhit_limit   /* No null in final Qword.  */\n\n\t/*\n\t* We know there's a null in the final Qword. The easiest thing\n\t* to do now is work out the length of the string and return\n\t* MIN (len, limit).\n\t*/\n\tsub\tlen, src, srcin\n\tcbz\thas_nul1, .Lnul_in_data2\n\tsub\tlen, len, #8\n\tmov\thas_nul2, has_nul1\n.Lnul_in_data2:\n\t/*\n\t* For big-endian, carry propagation (if the final byte in the\n\t* string is 0x01) means we cannot use has_nul directly.  The\n\t* easiest way to get the correct byte is to byte-swap the data\n\t* and calculate the syndrome a second time.\n\t*/\n\tsub\tlen, len, #8\n\trev\thas_nul2, has_nul2\n\tclz\tpos, has_nul2\n\tadd\tlen, len, pos, lsr #3       /* Bits to bytes.  */\n\tcmp\tlen, limit\n\tcsel\tlen, len, limit, ls     /* Return the lower value.  */\n\tret\n\n.Lmisaligned:\n\t/*\n\t* Deal with a partial first word.\n\t* We're doing two things in parallel here;\n\t* 1) Calculate the number of words (but avoiding overflow if\n\t* limit is near ULONG_MAX) - to do this we need to work out\n\t* limit + tmp1 - 1 as a 65-bit value before shifting it;\n\t* 2) Load and mask the initial data words - we force the bytes\n\t* before the ones we are interested in to 0xff - this ensures\n\t* early bytes will not hit any zero detection.\n\t*/\n\tldp\tdata1, data2, [src], #16\n\n\tsub\tlimit_wd, limit, #1\n\tand\ttmp3, limit_wd, #15\n\tlsr\tlimit_wd, limit_wd, #4\n\n\tadd\ttmp3, tmp3, tmp1\n\tadd\tlimit_wd, limit_wd, tmp3, lsr #4\n\n\tneg\ttmp4, tmp1\n\tlsl\ttmp4, tmp4, #3  /* Bytes beyond alignment -> bits.  */\n\n\tmov\ttmp2, #~0\n\t/* Big-endian.  Early bytes are at MSB.  */\n\t/* Little-endian.  Early bytes are at LSB.  */\n\tlsr\ttmp2, tmp2, tmp4\t/* Shift (tmp1 & 63).  */\n\n\tcmp\ttmp1, #8\n\n\torr\tdata1, data1, tmp2\n\torr\tdata2a, data2, tmp2\n\n\tcsinv\tdata1, data1, xzr, le\n\tcsel\tdata2, data2, data2a, le\n\tb\t.Lrealigned\n\n.Lhit_limit:\n\tmov\tlen, limit\n\tret\nendfunc strnlen\n"
  },
  {
    "path": "kernel/arch/aarch64/lib/strrchr.S",
    "content": "/*\n * Based on arch/arm/lib/strrchr.S\n *\n * Copyright (C) 1995-2000 Russell King\n * Copyright (C) 2013 ARM Ltd.\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/asm_marco.S>\n\n\t.global strrchr\n\n/*\n * Find the last occurrence of a character in a string.\n *\n * Parameters:\n *\tx0 - str\n *\tx1 - c\n * Returns:\n *\tx0 - address of last occurrence of 'c' or 0\n */\nfunc strrchr\n\tmov\tx3, #0\n\tand\tw1, w1, #0xff\n1:\tldrb\tw2, [x0], #1\n\tcbz\tw2, 2f\n\tcmp\tw2, w1\n\tb.ne\t1b\n\tsub\tx3, x0, #1\n\tb\t1b\n2:\tmov\tx0, x3\n\tret\nendfunc strrchr\n"
  },
  {
    "path": "kernel/arch/aarch64/lib/ticket_lock.S",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/asm_marco.S>\n\n\t.global arch_ticket_lock\n\t.global arch_ticket_unlock\n\t.global arch_ticket_trylock\n\nfunc arch_ticket_lock\n\tprfm    pstl1keep, [x0]\n\tadd\tx4, x0, #4\nloop1:\n\tldaxr\tw2, [x4]\n\tadd\tw2, w2, #1\n\tstlxr\tw3, w2, [x4]\n\tcbnz\tw3, loop1\n\tsub\tw2, w2, #1\n\n\tldaxr\tw1, [x0]\n\tcmp\tw1, w2\n\tb.eq\tout\n\n\tsevl\nloop2:\n\twfe\n\tldaxr\tw1, [x0]\n\tcmp\tw1, w2\n\tb.ne\tloop2\nout:\n\tret\nendfunc arch_ticket_lock\n\nfunc arch_ticket_trylock\n\tprfm    pstl1keep, [x0]\n\tadd\tx4, x0, #4\n\n\tmov\tw3, #0\n\tldaxr\tw1, [x0]\n\tldaxr\tw2, [x4]\n\tcmp\tw1, w2\n\tb.ne\tfail_trylock\n\n\tadd\tw2, w2, #1\n\tstlxr   w3, w2, [x4]\n\tcbnz\tw3, fail_trylock\n\tmov\tw3, #1\n\n\t/* need double check ? */\n\nfail_trylock:\n\tmov\tw0, w3\n\tret\nendfunc arch_ticket_trylock\n\nfunc arch_ticket_unlock\n\tldar\tw1, [x0]\n\tadd\tw1, w1, #1\n\tstlr\tw1, [x0]\n\tdsb\tish\n\tret\nendfunc arch_ticket_unlock\n"
  },
  {
    "path": "kernel/arch/aarch64/userspace/Makefile",
    "content": "obj-y += asm_syscall.o\n"
  },
  {
    "path": "kernel/arch/aarch64/userspace/asm_syscall.c",
    "content": "/*\n * Copyright (C) 2020 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/console.h>\n#include <minos/time.h>\n\n#include <uspace/poll.h>\n#include <uspace/syscall.h>\n#include <uspace/kobject.h>\n\nstruct aarch64_syscall_reg {\n\tunsigned long regs[8];\n} __packed;\n\ntypedef void (*syscall_handler_t)(gp_regs *regs);\n\nstatic void aarch64_syscall_unsupport(gp_regs *regs)\n{\n\tpr_err(\"Unsupported syscall:%d\\n\", regs->x8);\n\tregs->x0 = -ENOENT;\n}\n\nstatic void __sys_kobject_close(gp_regs *regs)\n{\n\tregs->x0 = sys_kobject_close((handle_t)regs->x0);\n}\n\nstatic void __sys_kobject_create(gp_regs *regs)\n{\n\tregs->x0 = sys_kobject_create((int)regs->x0, (unsigned long)regs->x1);\n}\n\nstatic void __sys_kobject_recv(gp_regs *regs)\n{\n\tsize_t data = 0, extra = 0;\n\n\tregs->x0 = sys_kobject_recv(\n\t\t\t(int)regs->x0,\n\t\t\t(void __user *)regs->x1,\n\t\t\t(size_t)regs->x2,\n\t\t\t&data,\n\t\t\t(void __user *)regs->x3,\n\t\t\t(size_t)regs->x4,\n\t\t\t&extra,\n\t\t\t(uint32_t)regs->x5);\n\tregs->x1 = data;\n\tregs->x2 = extra;\n}\n\nstatic void __sys_kobject_send(gp_regs *regs)\n{\n\tregs->x0 = sys_kobject_send(\n\t\t\t(int)regs->x0,\n\t\t\t(void __user *)regs->x1,\n\t\t\t(size_t)regs->x2,\n\t\t\t(void __user *)regs->x3,\n\t\t\t(size_t)regs->x4,\n\t\t\t(uint32_t)regs->x5);\n}\n\nstatic void __sys_kobject_reply(gp_regs *regs)\n{\n\tregs->x0 = sys_kobject_reply(\n\t\t\t(int)regs->x0,\n\t\t\t(unsigned long)regs->x1,\n\t\t\t(long)regs->x2,\n\t\t\t(handle_t)regs->x3,\n\t\t\t(right_t)regs->x4);\n}\n\nstatic void __sys_kobject_ctl(gp_regs *regs)\n{\n\tregs->x0 = sys_kobject_ctl((handle_t)regs->x0,\n\t\t\t(int)regs->x1,\n\t\t\t(unsigned long)regs->x2);\n}\n\nstatic void __sys_kobject_mmap(gp_regs *regs)\n{\n\tvoid *addr = 0;\n\tunsigned long mapsz = 0;\n\n\tregs->x0 = (unsigned long)sys_kobject_mmap((handle_t)regs->x0, &addr, &mapsz);\n\tregs->x1 = (unsigned long)addr;\n\tregs->x2 = mapsz;\n}\n\nstatic void __sys_kobject_munmap(gp_regs *regs)\n{\n\tregs->x0 = sys_kobject_munmap((handle_t)regs->x0);\n}\n\nstatic void __sys_kobject_open(gp_regs *regs)\n{\n\tregs->x0 = sys_kobject_open((handle_t)regs->x0);\n}\n\nstatic void __sys_map(gp_regs *regs)\n{\n\tregs->x0 = sys_map((handle_t)regs->x0,\n\t\t\t(handle_t)regs->x1,\n\t\t\t(unsigned long)regs->x2,\n\t\t\t(size_t)regs->x3,\n\t\t\t(right_t)regs->x4);\n}\n\nstatic void __sys_unmap(gp_regs *regs)\n{\n\tregs->x0 = sys_unmap((handle_t)regs->x0,\n\t\t\t(handle_t)regs->x1,\n\t\t\t(unsigned long)regs->x2,\n\t\t\t(size_t)regs->x3);\n}\n\nstatic void __sys_yield(gp_regs *regs)\n{\n\tsys_sched_yield();\n}\n\nstatic void __sys_futex(gp_regs *regs)\n{\n\tregs->x0 = sys_futex(\n\t\t\t(uint32_t __user *)regs->x0,\n\t\t\t(int)regs->x1,\n\t\t\t(uint32_t)regs->x2,\n\t\t\t(struct timespec __user *)regs->x3,\n\t\t\t(uint32_t __user *)regs->x4,\n\t\t\t(uint32_t)regs->x5);\n}\n\nstatic void __sys_grant(gp_regs *regs)\n{\n\tregs->x0 = sys_grant((handle_t)regs->x0,\n\t\t\t(handle_t)regs->x1,\n\t\t\t(right_t)regs->x2,\n\t\t\t(int)regs->x3);\n}\n\nstatic void __sys_mtrans(gp_regs *regs)\n{\n\tregs->x0 = sys_mtrans((unsigned long)regs->x0);\n}\n\nstatic void __sys_clock_gettime(gp_regs *regs)\n{\n\tregs->x0 = sys_clock_gettime((int)regs->x0,\n\t\t\t(struct timespec __user *)regs->x1);\n}\n\nstatic void __sys_clock_nanosleep(gp_regs *regs)\n{\n\tregs->x0 = sys_clock_nanosleep((int)regs->x0, (int)regs->x1,\n\t\t\t(int64_t)regs->x2, (long)regs->x3,\n\t\t\t(struct timespec __user *)regs->x4);\n}\n\nstatic void __sys_exit(gp_regs *regs)\n{\n\tsys_exit((int)regs->x0);\n}\n\nstatic void __sys_exitgroup(gp_regs *regs)\n{\n\tsys_exitgroup((int)regs->x0);\n}\n\nstatic void __sys_clone(gp_regs *regs)\n{\n\tregs->x0 = sys_clone((int)regs->x0,\n\t\t\t(void __user *)regs->x1,\n\t\t\t(int __user *)regs->x2,\n\t\t\t(void __user *)regs->x3,\n\t\t\t(int __user *)regs->x4);\n}\n\nstatic syscall_handler_t __syscall_table[] = {\n\t[0 ... __NR_syscalls] \t\t= aarch64_syscall_unsupport,\n\n\t[__NR_kobject_open]\t\t= __sys_kobject_open,\n\t[__NR_kobject_create]\t\t= __sys_kobject_create,\n\t[__NR_kobject_reply]\t\t= __sys_kobject_reply,\n\t[__NR_kobject_send]\t\t= __sys_kobject_send,\n\t[__NR_kobject_recv]\t\t= __sys_kobject_recv,\n\t[__NR_kobject_close]\t\t= __sys_kobject_close,\n\t[__NR_kobject_ctl]\t\t= __sys_kobject_ctl,\n\t[__NR_kobject_mmap]\t\t= __sys_kobject_mmap,\n\t[__NR_kobject_munmap]\t\t= __sys_kobject_munmap,\n\n\t[__NR_grant]\t\t\t= __sys_grant,\n\n\t[__NR_yield]\t\t\t= __sys_yield,\n\t[__NR_futex]\t\t\t= __sys_futex,\n\n\t[__NR_map]\t\t\t= __sys_map,\n\t[__NR_unmap]\t\t\t= __sys_unmap,\n\t[__NR_trans]\t\t\t= __sys_mtrans,\n\n\t[__NR_clock_gettime]\t\t= __sys_clock_gettime,\n\t[__NR_clock_nanosleep]\t\t= __sys_clock_nanosleep,\n\n\t[__NR_exit]\t\t\t= __sys_exit,\n\t[__NR_exitgroup]\t\t= __sys_exitgroup,\n\n\t[__NR_clone]\t\t\t= __sys_clone,\n};\n\nvoid aarch64_do_syscall(gp_regs *regs)\n{\n\tint nr = regs->x8;\n\n\tarch_enable_local_irq();\n\n\tif (nr >= __NR_syscalls) {\n\t\tregs->x0 = -EINVAL;\n\t\treturn;\n\t}\n\t__syscall_table[nr](regs);\n\n\tarch_disable_local_irq();\n}\n"
  },
  {
    "path": "kernel/arch/aarch64/virt/Kconfig",
    "content": "menu \"Minos aarch64 virtualaztion features\"\n\nconfig ARM_VHE\n\tbool \"enable VHE feature for minos\"\n\tdepends on VIRT\n\tdefault n\n\thelp\n\t  this require at leaset armv8.1 soc\n\nendmenu\n"
  },
  {
    "path": "kernel/arch/aarch64/virt/Makefile",
    "content": "obj-y\t+= arch_virt.o\nobj-y\t+= smc_service.o \nobj-y\t+= svc_service.o\nobj-y\t+= trap.o\nobj-y\t+= vmsa.o\nobj-y\t+= vtimer.o\nobj-y\t+= vfp.o\nobj-y\t+= stage2.o\n"
  },
  {
    "path": "kernel/arch/aarch64/virt/arch_virt.c",
    "content": "/*\n * Copyright (C) 2019 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/aarch64_common.h>\n#include <asm/aarch64_helper.h>\n#include <virt/vm.h>\n#include <virt/vmodule.h>\n#include <asm/arch.h>\n#include <minos/string.h>\n#include <minos/print.h>\n#include <minos/sched.h>\n#include <minos/calltrace.h>\n#include <minos/smp.h>\n#include <minos/of.h>\n#include <minos/platform.h>\n#include <minos/task.h>\n#include <virt/vm.h>\n#include <virt/virq.h>\n#include <virt/os.h>\n#include <asm/vtcb.h>\n#include <asm/tlb.h>\n\nstatic uint32_t mpidr_el1[NR_CPUS];\n\nvoid flush_all_tlb_mm(struct mm_struct *mm)\n{\n\tstruct vm *vm = container_of(mm, struct vm, mm);\n\tuint64_t vttbr = vtop(mm->pgdp) | ((uint64_t)vm->vmid << 48);\n\tunsigned long flags;\n\tuint64_t old_vttbr;\n\n\tlocal_irq_save(flags);\n\n\t/*\n\t * switch to the target VM's VTTBR to VTTBR_EL2, make sure\n\t * use the correct vmid.\n\t */\n\told_vttbr = read_sysreg(VTTBR_EL2);\n\twrite_sysreg(vttbr, VTTBR_EL2);\n\n\t/*\n\t * flush all the tlb with the vmid.\n\t */\n\tflush_all_tlb_guest();\n\n\t/*\n\t * restore the origin vttbr.\n\t */\n\twrite_sysreg(old_vttbr, VTTBR_EL2);\n\n\tlocal_irq_restore(flags);\n}\n\nvoid arch_set_virq_flag(void)\n{\n\tuint64_t hcr_el2;\n\n\thcr_el2 = read_sysreg(HCR_EL2);\n\thcr_el2 |= HCR_EL2_VI;\n\twrite_sysreg(hcr_el2, HCR_EL2);\n\tdsb();\n}\n\nvoid arch_set_vfiq_flag(void)\n{\n\tuint64_t hcr_el2;\n\n\thcr_el2 = read_sysreg(HCR_EL2);\n\thcr_el2 |= HCR_EL2_VF;\n\twrite_sysreg(hcr_el2, HCR_EL2);\n\tdsb();\n}\n\nvoid arch_clear_virq_flag(void)\n{\n\tuint64_t hcr_el2;\n\n\thcr_el2 = read_sysreg(HCR_EL2);\n\thcr_el2 &= ~HCR_EL2_VI;\n\thcr_el2 &= ~HCR_EL2_VF;\n\twrite_sysreg(hcr_el2, HCR_EL2);\n\tdsb();\n}\n\nvoid arch_clear_vfiq_flag(void)\n{\n\tuint64_t hcr_el2;\n\n\thcr_el2 = read_sysreg(HCR_EL2);\n\thcr_el2 &= ~HCR_EL2_VF;\n\twrite_sysreg(hcr_el2, HCR_EL2);\n\tdsb();\n}\n\nvoid arch_vcpu_init(struct vcpu *vcpu, void *entry, void *arg)\n{\n\tstruct task *task = vcpu->task;\n\tgp_regs *regs;\n\n\tregs = stack_to_gp_regs(task->stack_top);\n\tmemset(regs, 0, sizeof(gp_regs));\n\ttask->stack_base = task->stack_top - sizeof(gp_regs);\n\n\tregs->pc = (uint64_t)entry;\n\n\tif (task_is_32bit(vcpu->task))\n\t\tregs->pstate = AARCH32_SVC | \\\n\t\t\t\tAARCH64_SPSR_F | \\\n\t\t\t\tAARCH64_SPSR_I | \\\n\t\t\t\tAARCH64_SPSR_A | (1 << 4);\n\telse\n\t\tregs->pstate = AARCH64_SPSR_EL1h | \\\n\t\t\t\tAARCH64_SPSR_F | \\\n\t\t\t\tAARCH64_SPSR_I | \\\n\t\t\t\tAARCH64_SPSR_A;\n}\n\nstatic inline uint64_t generate_vtcr_el2(void)\n{\n\tuint64_t value = 0;\n\n\t/*\n\t * vtcr_el2 used to defined the memory attribute\n\t * for the EL1, this is defined by hypervisor\n\t * and may do not related to physical information\n\t */\n\tvalue |= (24 << 0);\t// t0sz = 0x10 40bits vaddr\n\tvalue |= (0x01 << 6);\t// SL0: 4kb start at level1\n\tvalue |= (0x1 << 8);\t// Normal memory, Inner WBWA\n\tvalue |= (0x1 << 10);\t// Normal memory, Outer WBWA\n\tvalue |= (0x3 << 12);\t// Inner Shareable\n\n\t// TG0 4K\n\tvalue |= (0x0 << 14);\n\n\t// PS --- pysical size 1TB\n\tvalue |= (2 << 16);\n\n\t// vmid -- 8bit\n\tvalue |= (0x0 << 19);\n\n\treturn value;\n}\n\nstatic inline uint64_t generate_vttbr_el2(uint32_t vmid, unsigned long base)\n{\n\treturn (base | ((uint64_t)vmid << 48));\n}\n\nvoid arch_vcpu_state_init(struct vcpu *vcpu, void *c)\n{\n\tstruct vcpu_context *context = (struct vcpu_context *)c;\n\tstruct vm *vm = vcpu->vm;\n\tuint64_t value;\n\n\tmemset(context, 0, sizeof(*context));\n\n\t/*\n\t * HVC : enable hyper call function\n\t * TWI : trap wfi - default enable, disable by dts\n\t * TWE : trap wfe - default disable\n\t * TIDCP : Trap implementation defined functionality\n\t * IMP : physical irq routing\n\t * FMO : physical firq routing\n\t * BSU_IS : Barrier Shareability upgrade\n\t * FB : force broadcast when do some tlb ins\n\t * PTW : protect table walk\n\t * TSC : trap smc ins\n\t * TACR : Trap Auxiliary Control Registers\n\t * AMO : Physical SError interrupt routing.\n\t * RW : low level is 64bit, when 0 is 32 bit\n\t * VM : enable virtualzation\n\t */\n\tvalue = read_sysreg64(HCR_EL2);\n\tcontext->hcr_el2 = value | HCR_EL2_VM |\n\t\t     HCR_EL2_TIDCP | HCR_EL2_IMO | HCR_EL2_FMO |\n\t\t     HCR_EL2_BSU_IS | HCR_EL2_FB | HCR_EL2_PTW |\n\t\t     HCR_EL2_TSC | HCR_EL2_TACR | HCR_EL2_AMO;\n\n\t/*\n\t * usually there will be so many wfis from the VM\n\t * in some case this will have much infulence to\n\t * the system, add this flag to disable WFI trap.\n\t */\n\tif (!(vcpu->vm->flags & VM_FLAGS_NATIVE_WFI))\n\t\tcontext->hcr_el2 |= HCR_EL2_TWI;\n\n\tif (!task_is_32bit(vcpu->task))\n\t\tcontext->hcr_el2 |= HCR_EL2_RW;\n\n\t/*\n\t * this require HVM's vcpu affinity need start with 0\n\t */\n\tif (vm_is_host_vm(vcpu->vm))\n\t\tcontext->vmpidr = cpuid_to_affinity(get_vcpu_id(vcpu));\n\telse\n\t\tcontext->vmpidr = get_vcpu_id(vcpu);\n\n\tpr_notice(\"vmpidr is 0x%x\\n\", context->vmpidr);\n\n\tcontext->cpacr = 0x3 << 20;\n\n\tif (vm_is_native(vcpu->vm))\n\t\tcontext->vpidr = mpidr_el1[vcpu_affinity(vcpu)];\n\telse\n\t\tcontext->vpidr = 0x410fc050;\t/* arm fvp */\n\n\t/*\n\t * enable dc zva trap, the apple soc use zva size 64\n\t * fixed, which may not equal to the target platform\n\t * so need trap dc zva\n\t */\n\tif (vcpu->vm->os->type == OS_TYPE_XNU)\n\t\tcontext->hcr_el2 |= HCR_EL2_TDZ;\n\n\tcontext->vtcr_el2 = generate_vtcr_el2();\n\tcontext->vttbr_el2 = generate_vttbr_el2(vm->vmid, vtop(vm->mm.pgdp));\n\tcontext->ttbr0_el1 = 0;\n\tcontext->ttbr1_el1 = 0;\n\tcontext->mair_el1 = 0;\n\tcontext->tcr_el1 = 0;\n\tcontext->par_el1 = 0;\n\tcontext->amair_el1 = 0;\n}\n\nstatic void arch_vcpu_state_save(struct vcpu *vcpu, void *c)\n{\n\tstruct vcpu_context *context = (struct vcpu_context *)c;\n\n\tcontext->vbar_el1 = read_sysreg(ARM64_VBAR_EL1);\n\tcontext->esr_el1 = read_sysreg(ARM64_ESR_EL1);\n\tcontext->elr_el1 = read_sysreg(ARM64_ELR_EL1);\n\tcontext->vmpidr = read_sysreg(ARM64_VMPIDR_EL2);\n\tcontext->vpidr = read_sysreg(ARM64_VPIDR_EL2);\n\tcontext->sctlr_el1 = read_sysreg(ARM64_SCTLR_EL1);\n\tcontext->hcr_el2 = read_sysreg(ARM64_HCR_EL2);\n\tcontext->sp_el1 = read_sysreg(ARM64_SP_EL1);\n\tcontext->sp_el0 = read_sysreg(ARM64_SP_EL0);\n\tcontext->spsr_el1 = read_sysreg(ARM64_SPSR_EL1);\n\tcontext->far_el1 = read_sysreg(ARM64_FAR_EL1);\n\tcontext->actlr_el1 = read_sysreg(ARM64_ACTLR_EL1);\n\tcontext->tpidr_el1 = read_sysreg(ARM64_TPIDR_EL1);\n\tcontext->csselr = read_sysreg(ARM64_CSSELR_EL1);\n\tcontext->cpacr = read_sysreg(ARM64_CPACR_EL1);\n\tcontext->contextidr = read_sysreg(ARM64_CONTEXTIDR_EL1);\n\tcontext->tpidr_el0 = read_sysreg(ARM64_TPIDR_EL0);\n\tcontext->tpidrro_el0 = read_sysreg(ARM64_TPIDRRO_EL0);\n\tcontext->cntkctl = read_sysreg(ARM64_CNTKCTL_EL1);\n\tcontext->afsr0 = read_sysreg(ARM64_AFSR0_EL1);\n\tcontext->afsr1 = read_sysreg(ARM64_AFSR1_EL1);\n\n\tif (task_is_32bit(vcpu->task)) {\n\t\t//context->teecr = read_sysreg32(TEECR32_EL1);\n\t\t//context->teehbr = read_sysreg32(TEEHBR32_EL1);\n\t\tcontext->dacr32_el2 = read_sysreg32(ARM64_DACR32_EL2);\n\t\tcontext->ifsr32_el2 = read_sysreg32(ARM64_IFSR32_EL2);\n\t}\n\n\tcontext->vtcr_el2 = read_sysreg(ARM64_VTCR_EL2);\n\tcontext->vttbr_el2 = read_sysreg(ARM64_VTTBR_EL2);\n\tcontext->ttbr0_el1 = read_sysreg(ARM64_TTBR0_EL1);\n\tcontext->ttbr1_el1 = read_sysreg(ARM64_TTBR1_EL1);\n\tcontext->mair_el1 = read_sysreg(ARM64_MAIR_EL1);\n\tcontext->tcr_el1 = read_sysreg(ARM64_TCR_EL1);\n\tcontext->par_el1 = read_sysreg(ARM64_PAR_EL1);\n\tcontext->amair_el1 = read_sysreg(ARM64_AMAIR_EL1);\n\n\tmb();\n}\n\nstatic void arch_vcpu_state_restore(struct vcpu *vcpu, void *c)\n{\n\tstruct vcpu_context *context = (struct vcpu_context *)c;\n\n\twrite_sysreg(context->vbar_el1, VBAR_EL1);\n\twrite_sysreg(context->esr_el1, ESR_EL1);\n\twrite_sysreg(context->elr_el1, ELR_EL1);\n\twrite_sysreg(context->vmpidr, VMPIDR_EL2);\n\twrite_sysreg(context->vpidr, VPIDR_EL2);\n\twrite_sysreg(context->sctlr_el1, SCTLR_EL1);\n\twrite_sysreg(context->hcr_el2, HCR_EL2);\n\twrite_sysreg(context->sp_el1, SP_EL1);\n\twrite_sysreg(context->sp_el0, SP_EL0);\n\twrite_sysreg(context->spsr_el1, SPSR_EL1);\n\twrite_sysreg(context->far_el1, FAR_EL1);\n\twrite_sysreg(context->actlr_el1, ACTLR_EL1);\n\twrite_sysreg(context->tpidr_el1, TPIDR_EL1);\n\twrite_sysreg(context->csselr, CSSELR_EL1);\n\twrite_sysreg(context->cpacr, CPACR_EL1);\n\twrite_sysreg(context->contextidr, CONTEXTIDR_EL1);\n\twrite_sysreg(context->tpidr_el0, TPIDR_EL0);\n\twrite_sysreg(context->tpidrro_el0, TPIDRRO_EL0);\n\twrite_sysreg(context->cntkctl, CNTKCTL_EL1);\n\twrite_sysreg(context->afsr0, AFSR0_EL1);\n\twrite_sysreg(context->afsr1, AFSR1_EL1);\n\n\tif (task_is_32bit(vcpu->task)) {\n\t\t//write_sysreg(context->teecr, TEECR32_EL1);\n\t\t//write_sysreg(context->teehbr, TEEHBR32_EL1);\n\t\twrite_sysreg(context->dacr32_el2, DACR32_EL2);\n\t\twrite_sysreg(context->ifsr32_el2, IFSR32_EL2);\n\t}\n\n\twrite_sysreg(context->vtcr_el2, ARM64_VTCR_EL2);\n\twrite_sysreg(context->vttbr_el2, ARM64_VTTBR_EL2);\n\twrite_sysreg(context->ttbr0_el1, ARM64_TTBR0_EL1);\n\twrite_sysreg(context->ttbr1_el1, ARM64_TTBR1_EL1);\n\twrite_sysreg(context->mair_el1, ARM64_MAIR_EL1);\n\twrite_sysreg(context->amair_el1, ARM64_AMAIR_EL1);\n\twrite_sysreg(context->tcr_el1, ARM64_TCR_EL1);\n\twrite_sysreg(context->par_el1, ARM64_PAR_EL1);\n\n\tmb();\n}\n\nstatic void arch_vcpu_state_dump(struct vcpu *vcpu, void *context)\n{\n\tstruct vcpu_context *c = (struct vcpu_context *)context;\n\n\tpr_notice(\"----- dump vcpu context -----\\n\");\n\tpr_notice(\" vbar_el1: 0x%16lx    esr_el1: 0x%16lx\\n\", c->vbar_el1, c->esr_el1);\n\tpr_notice(\"   sp_el1: 0x%16lx contextidr: 0x%16lx\\n\", c->sp_el1, c->contextidr);\n\tpr_notice(\"   sp_el0: 0x%16lx    elr_el1: 0x%16lx\\n\", c->sp_el0, c->elr_el1);\n\tpr_notice(\"   vmpidr: 0x%16lx  tpidr_el0: 0x%16lx\\n\", c->vmpidr, c->tpidr_el0);\n\tpr_notice(\"    vpidr: 0x%16lx  sctlr_el1: 0x%16lx\\n\", c->vpidr, c->sctlr_el1);\n\tpr_notice(\"  hcr_el2: 0x%16lx    tpidrro: 0x%16lx\\n\", c->hcr_el2, c->tpidrro_el0);\n\tpr_notice(\" spsr_el1: 0x%16lx    far_el1: 0x%16lx\\n\", c->spsr_el1, c->far_el1);\n\tpr_notice(\"actlr_el1: 0x%16lx    cntkctl: 0x%16lx\\n\", c->actlr_el1, c->cntkctl);\n\tpr_notice(\"tpidr_el1: 0x%16lx     csselr: 0x%16lx\\n\", c->tpidr_el1, c->csselr);\n\tpr_notice(\"    cpacr: 0x%16lx      afsr0: 0x%16lx\\n\", c->cpacr, c->afsr0);\n\tpr_notice(\"    afsr1: 0x%16lx   vtcr_el2: 0x%16lx\\n\", c->afsr1, c->vtcr_el2);\n\tpr_notice(\"ttbr0_el1: 0x%16lx  ttbr1_el1: 0x%16lx\\n\", c->ttbr0_el1, c->ttbr1_el1);\n\tpr_notice(\"vttbr_el2: 0x%16lx   mair_el1: 0x%16lx\\n\", c->vttbr_el2, c->mair_el1);\n\tpr_notice(\"amair_el1: 0x%16lx    tcr_el1: 0x%16lx\\n\", c->mair_el1, c->tcr_el1);\n\tpr_notice(\"  par_el1: 0x%16lx\\n\", c->par_el1);\n}\n\nstatic int aarch64_vcpu_context_init(struct vmodule *vmodule)\n{\n\tvmodule->context_size = sizeof(struct vcpu_context);\n\tvmodule->state_init = arch_vcpu_state_init;\n\tvmodule->state_save = arch_vcpu_state_save;\n\tvmodule->state_restore = arch_vcpu_state_restore;\n\tvmodule->state_dump = arch_vcpu_state_dump;\n\n\treturn 0;\n}\nMINOS_MODULE_DECLARE(arch_vcpu, \"aarch64 vcpu context\",\n\t\t(void *)aarch64_vcpu_context_init);\n\nstatic int arm_create_vm(void *item, void *context)\n{\n\tstruct vm *vm = item;\n\tstruct arm_virt_data *arch_data;\n\n\tarch_data = zalloc(sizeof(struct arm_virt_data));\n\tif (!arch_data)\n\t\tpanic(\"No more memory for arm arch data\\n\");\n\tvm->arch_data = arch_data;\n\n\treturn 0;\n}\n\nstatic int arm_virt_init(void)\n{\n\treturn register_hook(arm_create_vm, OS_HOOK_CREATE_VM);\n}\nmodule_initcall(arm_virt_init);\n"
  },
  {
    "path": "kernel/arch/aarch64/virt/smc_service.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <asm/svccc.h>\n#include <minos/sched.h>\n#include <asm/psci.h>\n#include <virt/vm.h>\n#include <virt/vm_pm.h>\n\nstatic int std_smc_handler(gp_regs *c,\n\t\tuint32_t id, unsigned long *args)\n{\n\tint ret;\n\n\tpr_debug(\"psci function id 0x%x\\n\", id);\n\n\tswitch (id) {\n\tcase PSCI_0_2_FN_PSCI_VERSION:\n\t\tSVC_RET1(c, PSCI_VERSION(1, 0));\n\t\tbreak;\n\n\tcase PSCI_0_2_FN64_CPU_ON:\n\tcase PSCI_0_2_FN_CPU_ON:\n\t\tpr_notice(\"request vcpu on\\n\");\n\t\tret = vcpu_power_on(get_current_vcpu(),\n\t\t\t\targs[0], args[1], args[2]);\n\t\tif (ret)\n\t\t\tSVC_RET1(c, PSCI_RET_INVALID_PARAMS);\n\t\tbreak;\n\n\tcase PSCI_0_2_FN_CPU_OFF:\n\t\t/* virtual vcpu only support freeze mode */\n\t\tpr_notice(\"request vcpu off\\n\");\n\t\tret = vcpu_off(get_current_vcpu());\n\t\tif (ret)\n\t\t\tSVC_RET1(c, PSCI_RET_INTERNAL_FAILURE);\n\t\tbreak;\n\tcase PSCI_0_2_FN64_CPU_SUSPEND:\n\t\t/*\n\t\t * only can be called by vcpu self\n\t\t */\n\t\tret = vcpu_suspend(get_current_vcpu(), c,\n\t\t\t\t(uint32_t)args[0], args[1]);\n\t\tif (ret)\n\t\t\tSVC_RET1(c, PSCI_RET_DENIED);\n\t\tbreak;\n\n\tcase PSCI_0_2_FN_MIGRATE_INFO_TYPE:\n\t\tSVC_RET1(c, PSCI_0_2_TOS_MP);\n\t\tbreak;\n\n\tcase PSCI_0_2_FN_AFFINITY_INFO:\n\tcase PSCI_0_2_FN64_AFFINITY_INFO:\n\t\t/* all spi irq will send to vm0 do nothing */\n\t\tSVC_RET1(c, PSCI_0_2_AFFINITY_LEVEL_OFF);\n\t\tbreak;\n\n\tcase PSCI_0_2_FN_SYSTEM_OFF:\n\t\t/* request reset by it self */\n\t\tvm_power_off(get_vmid(get_current_vcpu()), NULL,\n\t\t\t\tVM_PM_ACTION_BY_SELF);\n\t\tbreak;\n\n\tcase PSCI_0_2_FN_SYSTEM_RESET:\n\t\tvm_reset(get_vmid(get_current_vcpu()), NULL,\n\t\t\t\tVM_PM_ACTION_BY_SELF);\n\t\tbreak;\n\n\tcase PSCI_1_0_FN_SYSTEM_SUSPEND:\n\tcase PSCI_1_0_FN64_SYSTEM_SUSPEND:\n\t\t/* only can be called by vcpu0 itself */\n\t\tvm_suspend(get_vmid(get_current_vcpu()));\n\t\tbreak;\n\n\tcase PSCI_1_0_FN_PSCI_FEATURES:\n\t\tswitch (args[0]) {\n\t\tcase ARM_SMCCC_VERSION_FUNC_ID:\n\t\tcase PSCI_0_2_FN64_CPU_SUSPEND:\n\t\tcase PSCI_1_0_FN_SYSTEM_SUSPEND:\n\t\tcase PSCI_1_0_FN64_SYSTEM_SUSPEND:\n\t\t\tSVC_RET1(c, PSCI_RET_SUCCESS);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tSVC_RET1(c, PSCI_RET_NOT_SUPPORTED);\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\tSVC_RET1(c, PSCI_RET_SUCCESS);\n}\n\nDEFINE_SMC_HANDLER(\"std_smc_desc\", SVC_STYPE_STDSMC,\n\t\tSVC_STYPE_STDSMC, std_smc_handler);\n"
  },
  {
    "path": "kernel/arch/aarch64/virt/stage2.c",
    "content": "/*\n * Copyright (C) 2020 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/mm.h>\n#include <virt/vmm.h>\n#include <virt/vm.h>\n#include <asm/tlb.h>\n#include <asm/cache.h>\n#include \"stage2.h\"\n\nvoid *arch_alloc_guest_pgd(void)\n{\n\tvoid *page;\n\n\tpage = __get_free_pages(2, 2);\n\tif (page)\n\t\tmemset(page, 0, PAGE_SIZE * 2);\n\n\treturn page;\n}\n\nstatic void inline flush_tlb_va_range(unsigned long va, size_t size)\n{\n\tflush_tlb_ipa_guest(va, size);\n}\n\nstatic void inline stage2_pgd_clear(pud_t *pgdp)\n{\n\tWRITE_ONCE(*pgdp, 0);\n\t__dsb(ishst);\n\tisb();\n}\n\nstatic void inline stage2_pud_clear(pud_t *pudp)\n{\n\tWRITE_ONCE(*pudp, 0);\n\t__dsb(ishst);\n\tisb();\n}\n\nstatic void inline stage2_pmd_clear(pmd_t *pmdp)\n{\n\tWRITE_ONCE(*pmdp, 0);\n\t__dsb(ishst);\n\tisb();\n}\n\nstatic void *stage2_get_free_page(unsigned long flags)\n{\n\treturn get_free_page();\n}\n\nstatic unsigned long stage2_xxx_addr_end(unsigned long start, unsigned long end, size_t map_size)\n{\n\tunsigned long boundary = (start + map_size) & ~((unsigned long)map_size - 1);\n\n\treturn ((boundary - 1) < (end - 1)) ? boundary : end;\n}\n\n#define stage2_pgd_addr_end(start, end)\t\\\n\tstage2_xxx_addr_end(start, end, S2_PGD_SIZE)\n\n#define stage2_pud_addr_end(start, end)\t\\\n\tstage2_xxx_addr_end(start, end, S2_PUD_SIZE)\n\n#define stage2_pmd_addr_end(start, end)\t\\\n\tstage2_xxx_addr_end(start, end, S2_PMD_SIZE)\n\nstatic inline void stage2_set_pte(pte_t *ptep, pte_t new_pte)\n{\n\tWRITE_ONCE(*ptep, new_pte);\n\t__dsb(ishst);\n}\n\nstatic inline void stage2_set_pmd(pmd_t *pmdp, pmd_t new_pmd)\n{\n\tWRITE_ONCE(*pmdp, new_pmd);\n\t__dsb(ishst);\n}\n\nstatic inline void stage2_set_pud(pud_t *pudp, pud_t new_pud)\n{\n\tWRITE_ONCE(*pudp, new_pud);\n\t__dsb(ishst);\n}\n\nstatic inline void stage2_set_pgd(pgd_t *pgdp, pgd_t new_pgd)\n{\n\tWRITE_ONCE(*pgdp, new_pgd);\n\t__dsb(ishst);\n}\n\nstatic inline void stage2_pgd_populate(pgd_t *pgdp, unsigned long addr, unsigned long flags)\n{\n\tuint64_t attrs = S2_DES_TABLE;\n\n\tstage2_set_pgd(pgdp, vtop(addr) | attrs);\n}\n\nstatic inline void stage2_pud_populate(pud_t *pudp, unsigned long addr, unsigned long flags)\n{\n\tuint64_t attrs = S2_DES_TABLE;\n\n\tstage2_set_pud(pudp, vtop(addr) | attrs);\n}\n\nstatic inline void stage2_pmd_populate(pmd_t *pmdp, unsigned long addr, unsigned long flags)\n{\n\tuint64_t attrs = S2_DES_TABLE;\n\n\tstage2_set_pmd(pmdp, vtop(addr) | attrs);\n}\n\nstatic inline uint64_t stage2_block_attr(unsigned long flags)\n{\n\tuint64_t attr = 0;\n\n\tswitch (flags & VM_TYPE_MASK) {\n\tcase __VM_NORMAL_NC:\n\t\tattr |= S2_BLOCK_NORMAL_NC;\n\t\tbreak;\n\tcase __VM_IO:\n\t\tattr |= S2_BLOCK_DEVICE;\n\t\tbreak;\n\tcase __VM_WT:\n\t\tattr |= S2_BLOCK_WT;\n\t\tbreak;\n\tdefault:\n\t\tattr |= S2_BLOCK_NORMAL;\n\t\tbreak;\n\t}\n\n\tswitch (flags & VM_RW_MASK) {\n\tcase __VM_RO:\n\t\tattr |= S2_AP_RO;\n\t\tbreak;\n\tcase __VM_RW:\n\t\tattr |= S2_AP_RW;\n\t\tbreak;\n\tcase __VM_WO:\n\t\tattr |= S2_AP_WO;\n\t\tbreak;\n\tdefault:\n\t\tattr |= S2_AP_NON;\n\t\tbreak;\n\t}\n\n\tif (!(flags & __VM_EXEC))\n\t\tattr |= S2_XN;\n\n\tif (flags & __VM_PFNMAP)\n\t\tattr |= S2_PFNMAP;\n\n\tif (flags & __VM_DEVMAP)\n\t\tattr |= S2_DEVMAP;\n\n\tif (flags & __VM_SHARED)\n\t\tattr |= S2_SHARED;\n\n\treturn attr;\n}\n\nstatic inline uint64_t stage2_page_attr(unsigned long flags)\n{\n\tuint64_t pte = 0;\n\n\tswitch (flags & VM_TYPE_MASK) {\n\tcase __VM_NORMAL_NC:\n\t\tpte |= S2_PAGE_NORMAL_NC;\n\t\tbreak;\n\tcase __VM_IO:\n\t\tpte |= S2_PAGE_DEVICE;\n\t\tbreak;\n\tcase __VM_WT:\n\t\tpte |= S2_PAGE_WT;\n\t\tbreak;\n\tdefault:\n\t\tpte |= S2_PAGE_NORMAL;\n\t\tbreak;\n\t}\n\n\tswitch (flags & VM_RW_MASK) {\n\tcase __VM_RO:\n\t\tpte |= S2_AP_RO;\n\t\tbreak;\n\tcase __VM_RW:\n\t\tpte |= S2_AP_RW;\n\t\tbreak;\n\tcase __VM_WO:\n\t\tpte |= S2_AP_WO;\n\t\tbreak;\n\tdefault:\n\t\tpte |= S2_AP_NON;\n\t\tbreak;\n\t}\n\n\tif (!(flags & __VM_EXEC))\n\t\tpte |= S2_XN;\n\n\tif (flags & __VM_PFNMAP)\n\t\tpte |= S2_PFNMAP;\n\n\tif (flags & __VM_DEVMAP)\n\t\tpte |= S2_DEVMAP;\n\n\tif (flags & __VM_SHARED)\n\t\tpte |= S2_SHARED;\n\n\treturn pte;\n}\n\nstatic void stage2_unmap_pte_range(struct mm_struct *vs, pte_t *ptep,\n\t\tunsigned long addr, unsigned long end)\n{\n\tpte_t *pte;\n\n\tpte = stage2_pte_offset(ptep, addr);\n\n\tdo {\n\t\tif (!stage2_pte_none(*pte))\n\t\t\tstage2_set_pte(pte, 0);\n\t} while (pte++, addr += PAGE_SIZE, addr != end);\n}\n\nstatic inline bool is_pmd_range(unsigned long start, unsigned long end)\n{\n        if (((start & (S2_PMD_SIZE - 1)) == 0) && ((end - start) == S2_PMD_SIZE))\n                return true;\n        return false;\n}\n\nstatic inline bool is_pud_range(unsigned long start, unsigned long end)\n{\n        if (((start & (S2_PUD_SIZE - 1)) == 0) && ((end - start) == S2_PUD_SIZE))\n                return true;\n        return false;\n}\n\nstatic void stage2_unmap_pmd_range(struct mm_struct *vs, pmd_t *pmdp,\n\t\tunsigned long addr, unsigned long end)\n{\n\tunsigned long next;\n\tpmd_t *pmd;\n\tpte_t *ptep;\n\n\tpmd = stage2_pmd_offset(pmdp, addr);\n\n\tdo {\n\t\tnext = stage2_pmd_addr_end(addr, end);\n\t\tif (!stage2_pmd_none(*pmd)) {\n\t\t\tif (stage2_pmd_huge(*pmd)) {\n\t\t\t\tstage2_pmd_clear(pmd);\n\t\t\t} else {\n\t\t\t\tptep = (pte_t *)ptov(stage2_pte_table_addr(*pmd));\n\t\t\t\tstage2_unmap_pte_range(vs, ptep, addr, next);\n\t\t\t\tif (is_pmd_range(addr, next)) {\n\t\t\t\t\tstage2_pmd_clear(pmd);\n\t\t\t\t\tfree_pages(ptep);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} while (pmd++, addr = next, addr != end);\n}\n\nstatic int stage2_unmap_pud_range(struct mm_struct *vs, unsigned long addr, unsigned long end)\n{\n\tunsigned long next;\n\tpud_t *pud;\n\tpmd_t *pmdp;\n\n\tpud = stage2_pud_offset((pud_t *)vs->pgdp, end);\n\tdo {\n\t\tnext = stage2_pud_addr_end(addr, end);\n\t\tif (!stage2_pud_none(*pud)) {\n\t\t\tpmdp = (pmd_t *)ptov(stage2_pmd_table_addr(*pud));\n\t\t\tstage2_unmap_pmd_range(vs, pmdp, addr, next);\n\t\t\tif (is_pud_range(addr, next)) {\n\t\t\t\tstage2_pud_clear(pud);\n\t\t\t\tfree_pages(pmdp);\n\t\t\t}\n\t\t}\n\t} while (pud++, addr = next, addr != end);\n\n\tflush_all_tlb_mm(vs);\n\n\treturn 0;\n}\n\nstatic int stage2_map_pte_range(struct mm_struct *vs, pte_t *ptep, unsigned long start,\n\t\tunsigned long end, unsigned long physical, unsigned long flags)\n{\n\tunsigned long pte_attr;\n\tpte_t *pte;\n\tpte_t old_pte;\n\n\tpte = stage2_pte_offset(ptep, start);\n\tpte_attr = stage2_page_attr(flags);\n\n\tdo {\n\t\told_pte = *pte;\n\t\tstage2_set_pte(pte, pte_attr | physical);\n\t\tif (old_pte) {\n\t\t\tpr_warn(\"pte range 0x%lx remaped old 0x%lx new 0x%lx\\n\",\n\t\t\t\t\tstart, old_pte, pte_attr | physical);\n\t\t}\n\t} while (pte++, start += PAGE_SIZE, physical += PAGE_SIZE, start != end);\n\n\treturn 0;\n}\n\nstatic inline bool stage2_pmd_huge_page(pmd_t old_pmd, unsigned long start,\n\t\tunsigned long phy, size_t size, unsigned long flags)\n{\n\tif (!(flags & (__VM_HUGE_2M | __VM_HUGE_1G)) || old_pmd)\n\t\treturn false;\n\n\tif (!IS_BLOCK_ALIGN(start) || !IS_BLOCK_ALIGN(phy) || !(IS_BLOCK_ALIGN(size)))\n\t\treturn false;\n\n\treturn true;\n}\n\nstatic int stage2_map_pmd_range(struct mm_struct *vs, pmd_t *pmdp, unsigned long start,\n\t\tunsigned long end, unsigned long physical, unsigned long flags)\n{\n\tunsigned long next;\n\tunsigned long attr;\n\tpmd_t *pmd;\n\tpmd_t old_pmd;\n\tpte_t *ptep;\n\tsize_t size;\n\tint ret;\n\n\tpmd = stage2_pmd_offset(pmdp, start);\n\tdo {\n\t\tnext = stage2_pmd_addr_end(start, end);\n\t\tsize = next - start;\n\t\told_pmd = *pmd;\n\n\t\t/*\n\t\t * virtual memory need to map as PMD huge page\n\t\t */\n\t\tif (stage2_pmd_huge_page(old_pmd, start, physical, size, flags)) {\n\t\t\tattr = stage2_block_attr(flags);\n\t\t\tstage2_set_pmd(pmd, attr | (physical & S2_PMD_MASK));\n\t\t} else {\n\t\t\tif (old_pmd && stage2_pmd_huge(old_pmd)) {\n\t\t\t\tpr_err(\"stage2: vaddr 0x%x has mapped as huge page\\n\", start);\n\t\t\t\treturn -EINVAL;\n\t\t\t}\n\n\t\t\tif (stage2_pmd_none(old_pmd)) {\n\t\t\t\tptep = (pte_t *)stage2_get_free_page(flags);\n\t\t\t\tif (!ptep)\n\t\t\t\t\treturn -ENOMEM;\n\t\t\t\tmemset(ptep, 0, PAGE_SIZE);\n\t\t\t\tstage2_pmd_populate(pmd, (unsigned long)ptep, flags);\n\t\t\t} else {\n\t\t\t\tptep = (pte_t *)ptov(stage2_pte_table_addr(old_pmd));\n\t\t\t}\n\n\t\t\tret = stage2_map_pte_range(vs, ptep, start, next, physical, flags);\n\t\t\tif (ret)\n\t\t\t\treturn ret;\n\t\t}\n\t} while (pmd++, physical += size, start = next, start != end);\n\n\treturn 0;\n}\n\nstatic inline int stage2_pud_huge_page(pud_t old_pud, unsigned long start,\n\t\tunsigned long phy, size_t size, unsigned long flags)\n{\n\tif (!(flags & __VM_HUGE_1G) || old_pud)\n\t\treturn false;\n\n\tif (!IS_PUD_ALIGN(start) || !IS_PUD_ALIGN(phy) || !(IS_PUD_ALIGN(size)))\n\t\treturn false;\n\n\treturn true;\n}\n\nstatic int stage2_map_pud_range(struct mm_struct *vs, unsigned long start,\n\t\tunsigned long end, unsigned long physical, unsigned long flags)\n{\n\tunsigned long next, attr;\n\tpud_t *pud;\n\tpmd_t *pmdp;\n\tsize_t size;\n\tpud_t old_pud;\n\tint ret;\n\n\tpud = stage2_pud_offset((pud_t *)vs->pgdp, start);\n\tdo {\n\t\tnext = stage2_pud_addr_end(start, end);\n\t\tsize = next - start;\n\t\told_pud = *pud;\n\n\t\tif (stage2_pud_huge_page(old_pud, start, physical, size, flags)) {\n\t\t\tattr = stage2_block_attr(flags);\n\t\t\tstage2_set_pud(pud, attr | (physical & S2_PUD_MASK));\n\t\t} else {\n\t\t\tif (old_pud && stage2_pud_huge(old_pud)) {\n\t\t\t\tpr_err(\"stage2: vaddr 0x%x mapped as PUD huge page\\n\", start);\n\t\t\t\treturn -EINVAL;\n\t\t\t}\n\n\t\t\tif (stage2_pud_none(*pud)) {\n\t\t\t\tpmdp = (pmd_t *)stage2_get_free_page(flags);\n\t\t\t\tif (!pmdp)\n\t\t\t\t\treturn -ENOMEM;\n\t\t\t\tmemset(pmdp, 0, PAGE_SIZE);\n\t\t\t\tstage2_pud_populate(pud, (unsigned long)pmdp, flags);\n\t\t\t} else {\n\t\t\t\tpmdp = (pmd_t *)ptov(stage2_pmd_table_addr(*pud));\n\t\t\t}\n\n\t\t\tret = stage2_map_pmd_range(vs, pmdp, start, next, physical, flags);\n\t\t\tif (ret)\n\t\t\t\treturn ret;\n\t\t}\n\t} while (pud++, physical += size, start = next, start != end);\n\n\treturn 0;\n}\n\nstatic inline int stage2_ipa_to_pa(struct mm_struct *vs,\n\t\tunsigned long va, phy_addr_t *pa)\n{\n\tunsigned long pte_offset = va & ~S2_PTE_MASK;\n\tunsigned long pmd_offset = va & ~S2_PMD_MASK;\n\tunsigned long phy = 0;\n\tpud_t *pudp;\n\tpmd_t *pmdp;\n\tpte_t *ptep;\n\n\tpudp = stage2_pud_offset(vs->pgdp, va);\n\tif (stage2_pud_none(*pudp))\n\t\treturn -EFAULT;\n\n\tpmdp = stage2_pmd_offset(ptov(stage2_pmd_table_addr(*pudp)), va);\n\tif (stage2_pmd_none(*pmdp))\n\t\treturn -EFAULT;\n\n\tif (stage2_pmd_huge(*pmdp)) {\n\t\t*pa = ((*pmdp) & S2_PHYSICAL_MASK) + pmd_offset;\n\t\treturn 0;\n\t}\n\n\tptep = stage2_pte_offset(ptov(stage2_pte_table_addr(*pmdp)), va);\n\tphy = *ptep & S2_PHYSICAL_MASK;\n\tif (phy == 0)\n\t\treturn -EFAULT;\n\n\t*pa = phy + pte_offset;\n\n\treturn 0;\n}\n\nint arch_translate_guest_ipa(struct mm_struct *vs,\n\t\tunsigned long va, phy_addr_t *pa)\n{\n\treturn stage2_ipa_to_pa(vs, va, pa);\n}\n\nint arch_guest_map(struct mm_struct *vs, unsigned long start, unsigned long end,\n\t\tunsigned long physical, unsigned long flags)\n{\n\tif (end == start)\n\t\treturn -EINVAL;\n\n\tASSERT((start < VMM_VIRT_MAX) && (end <= VMM_VIRT_MAX));\n\tASSERT(physical < S2_PHYSICAL_MAX);\n\tASSERT(IS_PAGE_ALIGN(start) && IS_PAGE_ALIGN(end) && IS_PAGE_ALIGN(physical));\n\n\treturn stage2_map_pud_range(vs, start, end, physical, flags);\n}\n\nint arch_guest_unmap(struct mm_struct *vs, unsigned long start, unsigned long end)\n{\n\tif (end == start)\n\t\treturn -EINVAL;\n\n\tASSERT((start < VMM_VIRT_MAX) && (end <= VMM_VIRT_MAX));\n\treturn stage2_unmap_pud_range(vs, start, end);\n}\n"
  },
  {
    "path": "kernel/arch/aarch64/virt/stage2.h",
    "content": "#ifndef __MINOS_ARM64_STAGE2_H__\n#define __MINOS_ARM64_STAGE2_H__\n\n#include <minos/types.h>\n\n/*\n * Stage 2 VMSAv8-64 Table Descriptors\n */\n#define S2_DES_FAULT\t\t\t(0b00 << 0)\n#define S2_DES_BLOCK\t\t\t(0b01 << 0)\n#define S2_DES_TABLE\t\t\t(0b11 << 0)\n#define S2_DES_PAGE\t\t\t(0b11 << 0)\n\n/*\n * Stage 2 VMSAv8-64 Page / Block Descriptors\n */\n#define S2_CONTIGUOUS\t\t\t(1UL << 52)\n#define S2_XN\t\t\t\t(1UL << 54)\n#define S2_AF\t\t\t\t(1UL << 10)\n\n#define S2_PFNMAP\t\t\t(1UL << 55)\t// bit 55 - 58 is for software use\n#define S2_DEVMAP\t\t\t(1UL << 56)\t// bit 55 - 58 is for software use\n#define S2_SHARED\t\t\t(1UL << 57)\t// bit 55 - 58 is for software use\n\n#define S2_SH_NON\t\t\t(0b00 << 8)\n#define S2_SH_OUTER\t\t\t(0b10 << 8)\n#define S2_SH_INNER\t\t\t(0b11 << 8)\n\n#define S2_AP_NON\t\t\t(0b00 << 6)\n#define S2_AP_RO\t\t\t(0b01 << 6)\n#define S2_AP_WO\t\t\t(0b10 << 6)\n#define S2_AP_RW\t\t\t(0b11 << 6)\n\n#define S2_MEMATTR_DEV_nGnRnE\t\t(0b0000 << 2)\n#define S2_MEMATTR_DEV_nGnRE\t\t(0b0001 << 2)\n#define S2_MEMATTR_DEV_nGRE\t\t(0b0010 << 2)\n#define S2_MEMATTR_DEV_GRE\t\t(0b0011 << 2)\n\n#define S2_MEMATTR_NORMAL_WB\t\t(0b1111 << 2)\n#define S2_MEMATTR_NORMAL_NC\t\t(0b0101 << 2)\n#define S2_MEMATTR_NORMAL_WT\t\t(0b1010 << 2)\n\n#define S2_MT_NORMAL\t\t\t0\n#define S2_MT_DEVICE\t\t\t1\n\n#define S2_CACHE_WB\t\t\t0\n#define S2_CACHE_NC\t\t\t1\n\n#define S2_PAGE_NORMAL\t\t\t(S2_DES_PAGE | S2_AF | S2_SH_INNER | S2_MEMATTR_NORMAL_WB)\n#define S2_PAGE_NORMAL_NC\t\t(S2_DES_PAGE | S2_AF | S2_SH_INNER | S2_MEMATTR_NORMAL_NC)\n#define S2_PAGE_WT\t\t\t(S2_DES_PAGE | S2_AF | S2_SH_INNER | S2_MEMATTR_NORMAL_WT)\n// #define S2_PAGE_DEVICE\t\t(S2_DES_PAGE | S2_AF | S2_SH_OUTER | S2_MEMATTR_DEV_nGnRnE | S2_XN)\n#define S2_PAGE_DEVICE\t\t\t(S2_DES_PAGE | S2_AF | S2_SH_OUTER | S2_MEMATTR_DEV_nGnRE | S2_XN)\n\n#define S2_BLOCK_NORMAL\t\t\t(S2_DES_BLOCK | S2_AF | S2_SH_INNER | S2_MEMATTR_NORMAL_WB)\n#define S2_BLOCK_NORMAL_NC\t\t(S2_DES_BLOCK | S2_AF | S2_SH_INNER | S2_MEMATTR_NORMAL_NC)\n#define S2_BLOCK_DEVICE\t\t\t(S2_DES_BLOCK | S2_AF | S2_SH_OUTER | S2_MEMATTR_DEV_nGnRE | S2_XN)\n// #define S2_BLOCK_DEVICE\t\t(S2_DES_BLOCK | S2_AF | S2_SH_OUTER | S2_MEMATTR_DEV_nGnRnE | S2_XN)\n#define S2_BLOCK_WT\t\t\t(S2_DES_BLOCK | S2_AF | S2_SH_OUTER | S2_MEMATTR_NORMAL_WT)\n\n/*\n * 40bit stage2 IPA use 3 levels page table, the pagetable\n * need 2 pages\n */\n#define STAGE2_PGTABLE_LEVELS\t\t3\n#define S2_PAGETABLE_SIZE\t\t8192\n\n#define S2_PHYSICAL_MASK\t\t0x0000fffffffff000UL\n#define S2_PHYSICAL_MAX\t\t\t(1UL << 40)\n#define S2_VIRT_MAX\t\t\t(1UL << 40)\n#define S2_PHYSICAL_SIZE\t\t(1UL << 40)\n\n#define GUEST_PGD_PAGES\t\t\t2\n#define GUEST_PGD_PAGE_ALIGN\t\t2\n\n#define S2_PGD_SHIFT\t\t\t39\n#define S2_PGD_SIZE\t\t\t(1UL << S2_PGD_SHIFT)\n#define S2_PGD_MASK\t\t\t(~(S2_PGD_SIZE - 1))\n\n#define S2_PUD_SHIFT\t\t\t30\n#define S2_PUD_SIZE\t\t\t(1UL << S2_PUD_SHIFT)\n#define S2_PUD_MASK\t\t\t(~(S2_PUD_SIZE - 1))\n\n#define S2_PMD_SHIFT\t\t\t21\n#define S2_PMD_SIZE\t\t\t(1UL << S2_PMD_SHIFT)\n#define S2_PMD_MASK\t\t\t(~(S2_PMD_SIZE - 1))\n\n#define S2_PTE_SHIFT\t\t\t12\n#define S2_PTE_SIZE\t\t\t(1UL << S2_PTE_SHIFT)\n#define S2_PTE_MASK\t\t\t(~(S2_PTE_SIZE - 1))\n\n/*\n * The number of PTRS across all concatenated stage2 tables given by the\n * number of bits resolved at the initial level.\n *\n * since we use 3 level pagetable, and translation walk will from pud, the\n * PTRS in one pud is 1024\n */\n#define PTRS_PER_S2_PGD\t\t\t512\n#define PTRS_PER_S2_PUD\t\t\t1024\n#define PTRS_PER_S2_PMD\t\t\t512\n#define PTRS_PER_S2_PTE\t\t\t512\n\n#define stage2_pud_value(pudp)\t\t(*(pudp))\n#define stage2_pmd_value(pmdp)\t\t(*(pmdp))\n#define stage2_pte_value(ptep)\t\t(*(ptep))\n\n#define IS_PUD_ALIGN(addr)\\\n\t(!((unsigned long)(addr) & (S2_PUD_SIZE - 1)))\n\n#define stage2_pgd_index(addr)\t\t(((addr) >> S2_PGD_SHIFT) & (PTRS_PER_S2_PGD - 1))\n#define stage2_pud_index(addr)\t\t(((addr) >> S2_PUD_SHIFT) & (PTRS_PER_S2_PUD - 1))\n#define stage2_pmd_index(addr)\t\t(((addr) >> S2_PMD_SHIFT) & (PTRS_PER_S2_PMD - 1))\n#define stage2_pte_index(addr)\t\t(((addr) >> S2_PTE_SHIFT) & (PTRS_PER_S2_PTE - 1))\n\n#define stage2_pgd_offset(pgdp, addr)\t\t((pgd_t *)(pgdp) + stage2_pgd_index((unsigned long)addr))\n#define stage2_pud_offset(pudp, addr)\t\t((pud_t *)(pudp) + stage2_pud_index((unsigned long)addr))\n#define stage2_pmd_offset(pmdp, addr)\t\t((pmd_t *)(pmdp) + stage2_pmd_index((unsigned long)addr))\n#define stage2_pte_offset(ptep, addr)\t\t((pte_t *)(ptep) + stage2_pte_index((unsigned long)addr))\n\n#define stage2_pud_huge(pud)\t\t\t((pud) && ((pud) & 0x03) == S2_DES_BLOCK)\n#define stage2_pmd_huge(pmd)\t\t\t((pmd) && ((pmd) & 0x03) == S2_DES_BLOCK)\n\n#define stage2_pud_table_addr(pgd)\t\t(pud_t *)(unsigned long)((pgd) & S2_PHYSICAL_MASK)\n#define stage2_pmd_table_addr(pud)\t\t(pmd_t *)(unsigned long)((pud) & S2_PHYSICAL_MASK)\n#define stage2_pte_table_addr(pmd)\t\t(pte_t *)(unsigned long)((pmd) & S2_PHYSICAL_MASK)\n\n#define stage2_pgd_none(pgd)\t\t\t((pgd) == 0)\n#define stage2_pud_none(pud)\t\t\t((pud) == 0)\n#define stage2_pmd_none(pmd)\t\t\t((pmd) == 0)\n#define stage2_pte_none(pte)\t\t\t((pte) == 0)\n\n#define stage2_pmd_pfn(pmd)\t\t\t(pmd >> S2_PMD_SHIFT)\n#define stage2_pfn_pte(pfn, attr)\t\t(((unsigned long)(pfn) << PAGE_SHIFT) | attr)\n\n#define S2_PTE_ADDR_MASK\t\t\t(0x0000fffffffff000UL)\n#define S2_PMD_ADDR_MASK\t\t\t(0x0000ffffffe00000UL)\n\n#endif\n"
  },
  {
    "path": "kernel/arch/aarch64/virt/svc_service.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <asm/svccc.h>\n#include <minos/string.h>\n\nextern unsigned char __hvc_handler_start;\nextern unsigned char __hvc_handler_end;\nextern unsigned char __smc_handler_start;\nextern unsigned char __smc_handler_end;\n\nstatic struct svc_desc *smc_descs[SVC_STYPE_MAX];\nstatic struct svc_desc *hvc_descs[SVC_STYPE_MAX];\n\nint do_svc_handler(gp_regs *regs, uint32_t svc_id, uint64_t *args, int smc)\n{\n\tuint16_t type;\n\tstruct svc_desc **table;\n\tstruct svc_desc *desc;\n\n\tif (smc)\n\t\ttable = smc_descs;\n\telse\n\t\ttable = hvc_descs;\n\n\ttype = (svc_id & SVC_STYPE_MASK) >> 24;\n\n\tif (unlikely(type > SVC_STYPE_MAX)) {\n\t\tpr_err(\"Unsupported SVC type %d\\n\", type);\n\t\tgoto invalid;\n\t}\n\n\tdesc = table[type];\n\tif (unlikely(!desc))\n\t\tgoto invalid;\n\n\tpr_debug(\"doing SVC Call %s:0x%x\\n\", desc->name, svc_id);\n\n\treturn desc->handler(regs, svc_id, args);\n\ninvalid:\n\tSVC_RET1(regs, -EINVAL);\n}\n\nstatic void parse_svc_desc(unsigned long start, unsigned long end,\n\t\t\t   struct svc_desc **table)\n{\n\tstruct svc_desc *desc;\n\tint32_t j;\n\n\tsection_for_each_item_addr(start, end, desc) {\n\t\tBUG_ON((desc->type_start > desc->type_end) ||\n\t\t       (desc->type_end >= SVC_STYPE_MAX));\n\t\tfor (j = desc->type_start; j <= desc->type_end; j++) {\n\t\t\tif (table[j])\n\t\t\t\tpr_warn(\"overwrite SVC_DESC:%d %s\\n\", j,\n\t\t\t\t\tdesc->name);\n\t\t\ttable[j] = desc;\n\t\t}\n\t}\n}\n\nstatic int __init_text svc_service_init(void)\n{\n\tpr_notice(\"parsing SMC/HVC handler\\n\");\n\n\tparse_svc_desc((unsigned long)&__hvc_handler_start,\n\t\t       (unsigned long)&__hvc_handler_end, hvc_descs);\n\tparse_svc_desc((unsigned long)&__smc_handler_start,\n\t\t       (unsigned long)&__smc_handler_end, smc_descs);\n\n\treturn 0;\n}\narch_initcall(svc_service_init);\n"
  },
  {
    "path": "kernel/arch/aarch64/virt/trap.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/aarch64_helper.h>\n#include <virt/vm.h>\n#include <asm/trap.h>\n#include <minos/minos.h>\n#include <minos/smp.h>\n#include <asm/reg.h>\n#include <minos/sched.h>\n#include <minos/irq.h>\n#include <asm/svccc.h>\n#include <virt/vdev.h>\n\nstatic inline int taken_from_el1(uint64_t spsr)\n{\n\treturn ((spsr & 0xf) != AARCH64_SPSR_EL0t);\n}\n\nstatic inline void inject_virtual_data_abort(uint32_t esr_value)\n{\n\tuint64_t hcr_el2 = read_sysreg(HCR_EL2) | HCR_EL2_VSE;\n\n\twrite_sysreg(hcr_el2, HCR_EL2);\n\twrite_sysreg(esr_value, ESR_EL1);\n\twmb();\n}\n\nstatic int unknown_handler(gp_regs *reg, int ec, uint32_t esr_value)\n{\n\treturn 0;\n}\n\nstatic int wfi_wfe_handler(gp_regs *reg, int ec, uint32_t esr_value)\n{\n\tvcpu_idle(get_current_vcpu());\n\treturn 0;\n}\n\nstatic int mcr_mrc_cp15_handler(gp_regs *reg, int ec, uint32_t esr_value)\n{\n\tswitch (esr_value & HSR_CP32_REGS_MASK) {\n\tcase HSR_CPREG32(ACTLR):\n\t\tbreak;\n\tdefault:\n\t\tpr_notice(\"mcr_mrc_cp15_handler 0x%x\\n\", esr_value);\n\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\nstatic int mcrr_mrrc_cp15_handler(gp_regs *reg, int ec, uint32_t esr_value)\n{\n\tstruct esr_cp64 *sysreg = (struct esr_cp64 *)&esr_value;\n\tunsigned long reg_value0, reg_value1;\n\tunsigned long reg_value;\n\tstruct vcpu *vcpu = get_current_vcpu();\n\tstruct arm_virt_data *arm_data = vcpu->vm->arch_data;\n\n\tswitch (esr_value & HSR_CP64_REGS_MASK) {\n\tcase HSR_CPREG64(CNTP_CVAL):\n\t\tbreak;\n\n\t/* for aarch32 vm and using gicv3 */\n\tcase HSR_CPREG64(ICC_SGI1R):\n\tcase HSR_CPREG64(ICC_ASGI1R):\n\tcase HSR_CPREG64(ICC_SGI0R):\n\t\tif (!sysreg->read && arm_data->sgi1r_el1_trap) {\n\t\t\treg_value0 = get_reg_value(reg, sysreg->reg1);\n\t\t\treg_value1 = get_reg_value(reg, sysreg->reg2);\n\t\t\treg_value = (reg_value1 << 32) | reg_value0;\n\t\t\tarm_data->sgi1r_el1_trap(vcpu, reg_value);\n\t\t}\n\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\nstatic int mcr_mrc_cp14_handler(gp_regs *reg, int ec, uint32_t esr_value)\n{\n\treturn 0;\n}\n\nstatic int ldc_stc_cp14_handler(gp_regs *reg, int ec, uint32_t esr_value)\n{\n\treturn 0;\n}\n\nstatic int access_simd_reg_handler(gp_regs *reg, int ec, uint32_t esr_value)\n{\n\treturn 0;\n}\n\nstatic int mcr_mrc_cp10_handler(gp_regs *reg, int ec, uint32_t esr_value)\n{\n\treturn 0;\n}\n\nstatic int mrrc_cp14_handler(gp_regs *reg, int ec, uint32_t esr_value)\n{\n\treturn 0;\n}\n\nstatic int illegal_exe_state_handler(gp_regs *reg, int ec, uint32_t esr_value)\n{\n\treturn 0;\n}\n\nstatic int __arm_svc_handler(gp_regs *reg, int smc)\n{\n\tuint32_t id;\n\tunsigned long args[6];\n\n\tid = reg->x0;\n\targs[0] = reg->x1;\n\targs[1] = reg->x2;\n\targs[2] = reg->x3;\n\targs[3] = reg->x4;\n\targs[4] = reg->x5;\n\targs[5] = reg->x6;\n\n\tif (!(id & SVC_CTYPE_MASK))\n\t\tlocal_irq_enable();\n\n\treturn do_svc_handler(reg, id, args, smc);\n}\n\nstatic int access_system_reg_handler(gp_regs *reg, int ec, uint32_t esr_value)\n{\n\tstruct esr_sysreg *sysreg = (struct esr_sysreg *)&esr_value;\n\tstruct vcpu *vcpu = get_current_vcpu();\n\tstruct arm_virt_data *arm_data = vcpu->vm->arch_data;\n\tuint32_t regindex = sysreg->reg;\n\tunsigned long reg_value = 0;\n\tint ret = 0, reg_name;\n\n\treg_name = esr_value & ESR_SYSREG_REGS_MASK;\n\treg_value = sysreg->read ? 0 : get_reg_value(reg, regindex);\n\n\tswitch (reg_name) {\n\tcase ESR_SYSREG_ICC_SGI1R_EL1:\n\tcase ESR_SYSREG_ICC_ASGI1R_EL1:\n\tcase ESR_SYSREG_ICC_SGI0R_EL1:\n\t\tpr_debug(\"access system reg SGI1R_EL1\\n\");\n\t\tif (!sysreg->read && (arm_data->sgi1r_el1_trap))\n\t\t\tarm_data->sgi1r_el1_trap(vcpu, reg_value);\n\t\tbreak;\n\tcase ESR_SYSREG_CNTPCT_EL0:\n\tcase ESR_SYSREG_CNTP_TVAL_EL0:\n\tcase ESR_SYSREG_CNTP_CTL_EL0:\n\tcase ESR_SYSREG_CNTP_CVAL_EL0:\n\t\tif (arm_data->phy_timer_trap) {\n\t\t\tret = arm_data->phy_timer_trap(vcpu, reg_name,\n\t\t\t\t\tsysreg->read, &reg_value);\n\t\t}\n\t\tbreak;\n\n\tcase ESR_SYSREG_DCZVA:\n\t\tif ((arm_data->dczva_trap) && !sysreg->read)\n\t\t\tret = arm_data->dczva_trap(vcpu, reg_value);\n\t\tbreak;\n\tdefault:\n\t\tpr_debug(\"unsupport register access 0x%x %s\\n\",\n\t\t\t\treg_name, sysreg->read ? \"read\" : \"write\");\n\t\tif (arm_data->sysreg_emulation) {\n\t\t\tret = arm_data->sysreg_emulation(vcpu,\n\t\t\t\t\treg_name, sysreg->read, &reg_value);\n\t\t}\n\t\tbreak;\n\t}\n\n\tif (sysreg->read)\n\t\tset_reg_value(reg, regindex, reg_value);\n\n\treturn ret;\n}\n\nstatic int insabort_tfl_handler(gp_regs *reg, int ec, uint32_t esr_value)\n{\n\tpanic(\"%s\\n\", __func__);\n\treturn 0;\n}\n\nstatic int misaligned_pc_handler(gp_regs *reg, int ec, uint32_t esr_value)\n{\n\tpanic(\"%s\\n\", __func__);\n\treturn 0;\n}\n\nstatic inline bool dabt_isextabt(uint32_t dfsc)\n{\n\tswitch (dfsc) {\n\tcase FSC_SEA:\n\tcase FSC_SEA_TTW0:\n\tcase FSC_SEA_TTW1:\n\tcase FSC_SEA_TTW2:\n\tcase FSC_SEA_TTW3:\n\tcase FSC_SECC:\n\tcase FSC_SECC_TTW0:\n\tcase FSC_SECC_TTW1:\n\tcase FSC_SECC_TTW2:\n\tcase FSC_SECC_TTW3:\n\t\treturn true;\n\tdefault:\n\t\treturn false;\n\t}\n}\n\nstatic inline unsigned long get_faulting_ipa(unsigned long vaddr)\n{\n        uint64_t hpfar = read_sysreg(HPFAR_EL2);\n        unsigned long ipa;\n\n        ipa = (hpfar & HPFAR_MASK) << (12 - 4);\n        ipa |= vaddr & (~(~PAGE_MASK));\n\n        return ipa;\n}\n\nstatic inline bool dabt_iswrite(uint32_t esr_value)\n{\n\treturn (!!(esr_value & ESR_ELx_WNR)) ||\n\t\t\t(!!(esr_value & ESR_ELx_S1PTW));\n}\n\nstatic int dataabort_tfl_handler(gp_regs *regs, int ec, uint32_t esr_value)\n{\n\tuint32_t dfsc = esr_value & ESR_ELx_FSC_TYPE;\n\tunsigned long vaddr, ipa, value;\n\tint ret, iswrite, reg;\n\n\tif (dabt_isextabt(dfsc)) {\n\t\tpr_err(\"data abort is external abort\\n\");\n\t\tgoto out_fail;\n\t}\n\n\tif ((dfsc != FSC_FAULT) && (dfsc != FSC_PERM)) {\n\t\tpr_err(\"Unsupported data abort FSC: EC=%x xFSC=%x ESR_EL2=%x\\n\",\n\t\t\t\tec, dfsc, esr_value);\n\t\tgoto out_fail;\n\t}\n\n\tif (!(esr_value & ESR_ELx_ISV)) {\n\t\tpr_err(\"Instruction syndrome not valid\\n\");\n\t\tgoto out_fail;\n\t}\n\n\tiswrite = dabt_iswrite(esr_value);\n\treg = ESR_ELx_SRT(esr_value);\n\tvalue = iswrite ? get_reg_value(regs, reg) : 0;\n\tvaddr = read_sysreg(FAR_EL2);\n\tif ((esr_value &ESR_ELx_S1PTW) || (dfsc == FSC_FAULT))\n\t\tipa = get_faulting_ipa(vaddr);\n\telse\n\t\tipa = guest_va_to_ipa(vaddr, 1);\n\n\tret = vdev_mmio_emulation(regs, iswrite, ipa, &value);\n\tif (ret == -EACCES) {\n\t\tpr_warn(\"Fault on mmio read/write fail 0x%x vmid:%d\\n\", ipa,\n\t\t\t\tget_vmid(get_current_vcpu()));\n\t\t/*\n\t\t * if failed to handle the mmio trap inject a\n\t\t * sync error to guest vm to generate a fault\n\t\t */\n\t\tgoto out_fail;\n\t}\n\t\n\tif (!iswrite)\n\t\tset_reg_value(regs, reg, value);\n\n\treturn 0;\n\nout_fail:\n\tvcpu_fault(current_vcpu, regs);\n\t/*\n\t * the VCPU will exit when return to guest.\n\t */\n\treturn -EFAULT;\n}\n\nstatic int stack_misalign_handler(gp_regs *reg, int ec, uint32_t esr_value)\n{\n\tpanic(\"%s\\n\", __func__);\n\treturn 0;\n}\n\nstatic int floating_aarch32_handler(gp_regs *reg, int ec, uint32_t esr_value)\n{\n\tpanic(\"%s\\n\", __func__);\n\treturn 0;\n}\n\nstatic int floating_aarch64_handler(gp_regs *reg, int ec, uint32_t esr_value)\n{\n\tpanic(\"%s\\n\", __func__);\n\treturn 0;\n}\n\nstatic int serror_handler(gp_regs *reg, int ec, uint32_t esr_value)\n{\n\tpanic(\"%s\\n\", __func__);\n\treturn 0;\n}\n\nint aarch64_hypercall_handler(gp_regs *reg, int ec, uint32_t esr_value)\n{\n\tstruct vcpu *vcpu = get_current_vcpu();\n\tstruct arm_virt_data *arm_data = vcpu->vm->arch_data;\n\n\tif (arm_data->hvc_handler)\n\t\treturn arm_data->hvc_handler(vcpu, reg, read_esr_el2());\n\telse\n\t\treturn __arm_svc_handler(reg, 0);\n}\n\nint aarch64_smccall_handler(gp_regs *reg, int ec, uint32_t esr_value)\n{\n\tstruct vcpu *vcpu = get_current_vcpu();\n\tstruct arm_virt_data *arm_data = vcpu->vm->arch_data;\n\n\tif (arm_data->hvc_handler)\n\t\treturn arm_data->smc_handler(vcpu, reg, read_esr_el2());\n\telse\n\t\treturn __arm_svc_handler(reg, 1);\n}\n\n\n/* type defination is at armv8-spec 1906 */\nDEFINE_SYNC_DESC(guest_ESR_ELx_EC_WFx, EC_TYPE_BOTH, wfi_wfe_handler, 1, 4);\nDEFINE_SYNC_DESC(guest_ESR_ELx_EC_UNKNOWN, EC_TYPE_BOTH, unknown_handler, 1, 4);\nDEFINE_SYNC_DESC(guest_ESR_ELx_EC_CP15_32, EC_TYPE_BOTH, mcr_mrc_cp15_handler, 1, 4);\nDEFINE_SYNC_DESC(guest_ESR_ELx_EC_CP15_64, EC_TYPE_AARCH32, mcrr_mrrc_cp15_handler, 1, 4);\nDEFINE_SYNC_DESC(guest_ESR_ELx_EC_CP14_MR, EC_TYPE_AARCH32, mcr_mrc_cp14_handler, 1, 4);\nDEFINE_SYNC_DESC(guest_ESR_ELx_EC_CP14_LS, EC_TYPE_AARCH32, ldc_stc_cp14_handler, 1, 4);\nDEFINE_SYNC_DESC(guest_ESR_ELx_EC_FP_ASIMD, EC_TYPE_BOTH, access_simd_reg_handler, 1, 4);\nDEFINE_SYNC_DESC(guest_ESR_ELx_EC_CP10_ID, EC_TYPE_AARCH32, mcr_mrc_cp10_handler, 1, 4);\nDEFINE_SYNC_DESC(guest_ESR_ELx_EC_CP14_64, EC_TYPE_AARCH32, mrrc_cp14_handler, 1, 4);\nDEFINE_SYNC_DESC(guest_ESR_ELx_EC_ILL, EC_TYPE_BOTH, illegal_exe_state_handler, 1, 4);\nDEFINE_SYNC_DESC(guest_ESR_ELx_EC_SYS64, EC_TYPE_AARCH64, access_system_reg_handler, 1, 4);\nDEFINE_SYNC_DESC(guest_ESR_ELx_EC_IABT_LOW, EC_TYPE_BOTH, insabort_tfl_handler, 1, 4);\nDEFINE_SYNC_DESC(guest_ESR_ELx_EC_PC_ALIGN, EC_TYPE_BOTH, misaligned_pc_handler, 1, 4);\nDEFINE_SYNC_DESC(guest_ESR_ELx_EC_DABT_LOW, EC_TYPE_BOTH, dataabort_tfl_handler, 1, 4);\nDEFINE_SYNC_DESC(guest_ESR_ELx_EC_SP_ALIGN, EC_TYPE_BOTH, stack_misalign_handler, 1, 4);\nDEFINE_SYNC_DESC(guest_ESR_ELx_EC_FP_EXC32, EC_TYPE_AARCH32, floating_aarch32_handler, 1, 4);\nDEFINE_SYNC_DESC(guest_ESR_ELx_EC_FP_EXC64, EC_TYPE_AARCH64, floating_aarch64_handler, 1, 4);\nDEFINE_SYNC_DESC(guest_ESR_ELx_EC_SERROR, EC_TYPE_BOTH, serror_handler, 1, 4);\nDEFINE_SYNC_DESC(guest_ESR_ELx_EC_HVC32, EC_TYPE_AARCH32, aarch64_hypercall_handler, 1, 0);\nDEFINE_SYNC_DESC(guest_ESR_ELx_EC_HVC64, EC_TYPE_AARCH64, aarch64_hypercall_handler, 1, 0);\nDEFINE_SYNC_DESC(guest_ESR_ELx_EC_SMC32, EC_TYPE_AARCH32, aarch64_smccall_handler, 1, 4);\nDEFINE_SYNC_DESC(guest_ESR_ELx_EC_SMC64, EC_TYPE_AARCH64, aarch64_smccall_handler, 1, 4);\n\nstatic struct sync_desc *guest_sync_descs[] = {\n\t[0 ... ESR_ELx_EC_MAX]\t= &sync_desc_guest_ESR_ELx_EC_UNKNOWN,\n\t[ESR_ELx_EC_WFx]\t= &sync_desc_guest_ESR_ELx_EC_WFx,\n\t[ESR_ELx_EC_CP15_32]    = &sync_desc_guest_ESR_ELx_EC_CP15_32,\n\t[ESR_ELx_EC_CP15_64]    = &sync_desc_guest_ESR_ELx_EC_CP15_64,\n\t[ESR_ELx_EC_CP14_MR]    = &sync_desc_guest_ESR_ELx_EC_CP14_MR,\n\t[ESR_ELx_EC_CP14_LS]    = &sync_desc_guest_ESR_ELx_EC_CP14_LS,\n\t[ESR_ELx_EC_FP_ASIMD]   = &sync_desc_guest_ESR_ELx_EC_FP_ASIMD,\n\t[ESR_ELx_EC_CP10_ID]    = &sync_desc_guest_ESR_ELx_EC_CP10_ID,\n\t[ESR_ELx_EC_CP14_64]\t= &sync_desc_guest_ESR_ELx_EC_CP14_64,\n\t[ESR_ELx_EC_ILL]\t= &sync_desc_guest_ESR_ELx_EC_ILL,\n\t[ESR_ELx_EC_SYS64]\t= &sync_desc_guest_ESR_ELx_EC_SYS64,\n\t[ESR_ELx_EC_IABT_LOW]   = &sync_desc_guest_ESR_ELx_EC_IABT_LOW,\n\t[ESR_ELx_EC_PC_ALIGN]   = &sync_desc_guest_ESR_ELx_EC_PC_ALIGN,\n\t[ESR_ELx_EC_DABT_LOW]   = &sync_desc_guest_ESR_ELx_EC_DABT_LOW,\n\t[ESR_ELx_EC_SP_ALIGN]   = &sync_desc_guest_ESR_ELx_EC_SP_ALIGN,\n\t[ESR_ELx_EC_FP_EXC32]   = &sync_desc_guest_ESR_ELx_EC_FP_EXC32,\n\t[ESR_ELx_EC_FP_EXC64]   = &sync_desc_guest_ESR_ELx_EC_FP_EXC64,\n\t[ESR_ELx_EC_SERROR]\t= &sync_desc_guest_ESR_ELx_EC_SERROR,\n\t[ESR_ELx_EC_HVC32]\t= &sync_desc_guest_ESR_ELx_EC_HVC32,\n\t[ESR_ELx_EC_HVC64]\t= &sync_desc_guest_ESR_ELx_EC_HVC64,\n\t[ESR_ELx_EC_SMC32]\t= &sync_desc_guest_ESR_ELx_EC_SMC32,\n\t[ESR_ELx_EC_SMC64]\t= &sync_desc_guest_ESR_ELx_EC_SMC64,\n};\n\nvoid handle_vcpu_sync_exception(gp_regs *regs)\n{\n\tint cpuid = smp_processor_id();\n\tuint32_t esr_value;\n\tint ec_type;\n\tstruct sync_desc *ec;\n\tstruct vcpu *vcpu = get_current_vcpu();\n\n\tif ((!vcpu) || (vcpu->task->affinity != cpuid))\n\t\tpanic(\"this vcpu is not belong to the pcpu\");\n\n\tesr_value = read_esr_el2();\n\tec_type = (esr_value & ESR_ELx_EC_MASK) >> ESR_ELx_EC_SHIFT;\n\n\tif (ec_type >= ESR_ELx_EC_MAX) {\n\t\tpr_err(\"unknown sync exception type from guest %d\\n\", ec_type);\n\t\tgoto out;\n\t}\n\n\tpr_debug(\"sync from lower EL, handle 0x%x\\n\", ec_type);\n\tec = guest_sync_descs[ec_type];\n\tif (ec->irq_safe)\n\t\tlocal_irq_enable();\n\n\tregs->pc += ec->ret_addr_adjust;\n\tec->handler(regs, ec_type, esr_value);\nout:\n\tlocal_irq_disable();\n}\n"
  },
  {
    "path": "kernel/arch/aarch64/virt/vfp.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <virt/vmodule.h>\n#include <minos/task.h>\n\n#ifdef CONFIG_VIRT\n#include <virt/vm.h>\n#endif\n\nstruct vfp_context {\n\tuint64_t regs[64] __align(16);\n#ifdef CONFIG_VIRT\n\tuint32_t fpexc32_el2;\n\tuint32_t padding0;\n#endif\n\tuint32_t fpsr;\n\tuint32_t fpcr;\n\tuint32_t cptr;\n};\n\nstatic void vfp_state_init(struct vcpu *vcpu, void *c)\n{\n\tstruct vfp_context *context = (struct vfp_context *)c;\n\n\tmemset(context, 0, sizeof(struct vfp_context));\n\tcontext->cptr = 0x300000;\n}\n\nstatic void vfp_state_save(struct vcpu *vcpu, void *context)\n{\n\tstruct vfp_context *c = (struct vfp_context *)context;\n\n\tif (task_is_32bit(vcpu->task))\n\t\tc->fpexc32_el2 = read_sysreg32(FPEXC32_EL2);\n\n\t/*\n\t * need write CPTR_EL2 first to enable FPEN\n\t */\n\tc->cptr = read_sysreg(CPTR_EL2);\n\tc->fpsr = read_sysreg(FPSR);\n\tc->fpcr = read_sysreg(FPCR);\n\n\tasm volatile(\"stp q0, q1, [%1, #16 * 0]\\n\\t\"\n\t\t     \"stp q2, q3, [%1, #16 * 2]\\n\\t\"\n\t\t     \"stp q4, q5, [%1, #16 * 4]\\n\\t\"\n                     \"stp q6, q7, [%1, #16 * 6]\\n\\t\"\n                     \"stp q8, q9, [%1, #16 * 8]\\n\\t\"\n                     \"stp q10, q11, [%1, #16 * 10]\\n\\t\"\n                     \"stp q12, q13, [%1, #16 * 12]\\n\\t\"\n                     \"stp q14, q15, [%1, #16 * 14]\\n\\t\"\n                     \"stp q16, q17, [%1, #16 * 16]\\n\\t\"\n                     \"stp q18, q19, [%1, #16 * 18]\\n\\t\"\n                     \"stp q20, q21, [%1, #16 * 20]\\n\\t\"\n                     \"stp q22, q23, [%1, #16 * 22]\\n\\t\"\n                     \"stp q24, q25, [%1, #16 * 24]\\n\\t\"\n                     \"stp q26, q27, [%1, #16 * 26]\\n\\t\"\n                     \"stp q28, q29, [%1, #16 * 28]\\n\\t\"\n                     \"stp q30, q31, [%1, #16 * 30]\\n\\t\"\n                     : \"=Q\" (*c->regs) : \"r\" (c->regs));\n}\n\nstatic void vfp_state_restore(struct vcpu *vcpu, void *context)\n{\n\tstruct vfp_context *c = (struct vfp_context *)context;\n\n\twrite_sysreg(c->cptr, CPTR_EL2);\n\tif (task_is_32bit(vcpu->task))\n\t\twrite_sysreg(c->fpexc32_el2, FPEXC32_EL2);\n\n\twrite_sysreg(c->fpsr, FPSR);\n\twrite_sysreg(c->fpcr, FPCR);\n\n\tasm volatile(\"ldp q0, q1, [%1, #16 * 0]\\n\\t\"\n\t\t     \"ldp q2, q3, [%1, #16 * 2]\\n\\t\"\n                     \"ldp q4, q5, [%1, #16 * 4]\\n\\t\"\n                     \"ldp q6, q7, [%1, #16 * 6]\\n\\t\"\n                     \"ldp q8, q9, [%1, #16 * 8]\\n\\t\"\n                     \"ldp q10, q11, [%1, #16 * 10]\\n\\t\"\n                     \"ldp q12, q13, [%1, #16 * 12]\\n\\t\"\n                     \"ldp q14, q15, [%1, #16 * 14]\\n\\t\"\n                     \"ldp q16, q17, [%1, #16 * 16]\\n\\t\"\n                     \"ldp q18, q19, [%1, #16 * 18]\\n\\t\"\n                     \"ldp q20, q21, [%1, #16 * 20]\\n\\t\"\n                     \"ldp q22, q23, [%1, #16 * 22]\\n\\t\"\n                     \"ldp q24, q25, [%1, #16 * 24]\\n\\t\"\n                     \"ldp q26, q27, [%1, #16 * 26]\\n\\t\"\n                     \"ldp q28, q29, [%1, #16 * 28]\\n\\t\"\n                     \"ldp q30, q31, [%1, #16 * 30]\\n\\t\"\n                     : : \"Q\" (*c->regs), \"r\" (c->regs));\n}\n\nstatic int vfp_vmodule_init(struct vmodule *vmodule)\n{\n\tvmodule->context_size\t= sizeof(struct vfp_context);\n\tvmodule->state_init\t= vfp_state_init;\n\tvmodule->state_save\t= vfp_state_save;\n\tvmodule->state_restore\t= vfp_state_restore;\n\n\treturn 0;\n}\nMINOS_MODULE_DECLARE(vfp, \"vfp\", (void *)vfp_vmodule_init);\n"
  },
  {
    "path": "kernel/arch/aarch64/virt/vmsa.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <asm/arch.h>\n#include <asm/aarch64_reg.h>\n\nstruct aa64mmfr0 {\n\tuint64_t pa_range : 4;\n\tuint64_t asid : 4;\n\tuint64_t big_end : 4;\n\tuint64_t sns_mem : 4;\n\tuint64_t big_end_el0 : 4;\n\tuint64_t t_gran_16k : 4;\n\tuint64_t t_gran_64k : 4;\n\tuint64_t t_gran_4k : 4;\n\tuint64_t res : 32;\n};\n\nstatic int __init_text el2_stage2_init(void)\n{\n\t/*\n\t * now just support arm fvp, TBD to support more\n\t * platform\n\t */\n\tuint64_t value, dcache, icache;\n\tstruct aa64mmfr0 *aa64mmfr0;\n\n\tvalue = read_id_aa64mmfr0_el1();\n\taa64mmfr0 = (struct aa64mmfr0 *)&value;\n\tpr_info(\"aa64mmfr0: pa_range:0x%x t_gran_16k:0x%x t_gran_64k\"\n\t\t \":0x%x t_gran_4k:0x%x\\n\", aa64mmfr0->pa_range,\n\t\t aa64mmfr0->t_gran_16k, aa64mmfr0->t_gran_64k,\n\t\t aa64mmfr0->t_gran_4k);\n\n\tvalue = read_sysreg(CTR_EL0);\n\tdcache = 4 << ((value & 0xf0000) >> 16);\n\ticache = 4 << ((value & 0xf));\n\tpr_info(\"dcache_line_size:%d ichache_line_size:%d\\n\", dcache, icache);\n\n\treturn 0;\n}\nearly_initcall(el2_stage2_init);\n"
  },
  {
    "path": "kernel/arch/aarch64/virt/vtimer.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n#include <minos/minos.h>\n#include <virt/vmodule.h>\n#include <minos/timer.h>\n#include <asm/io.h>\n#include <asm/reg.h>\n#include <asm/trap.h>\n#include <minos/timer.h>\n#include <minos/irq.h>\n#include <minos/sched.h>\n#include <virt/virq.h>\n#include <virt/os.h>\n#include <asm/aarch64_reg.h>\n\n#define REG_CNTCR\t\t0x000\n#define REG_CNTSR\t\t0x004\n#define REG_CNTCV_L\t\t0x008\n#define REG_CNTCV_H\t\t0x00c\n#define REG_CNTFID0\t\t0x020\n\n#define REG_CNTVCT_LO\t\t0x08\n#define REG_CNTVCT_HI\t\t0x0c\n#define REG_CNTFRQ\t\t0x10\n#define REG_CNTP_CVAL\t\t0x24\n#define REG_CNTP_TVAL\t\t0x28\n#define REG_CNTP_CTL\t\t0x2c\n#define REG_CNTV_CVAL\t\t0x30\n#define REG_CNTV_TVAL\t\t0x38\n#define REG_CNTV_CTL\t\t0x3c\n\n#define ACCESS_REG\t\t0x0\n#define ACCESS_MEM\t\t0x1\n\nstruct vtimer {\n\tstruct vcpu *vcpu;\n\tstruct timer timer;\n\tint virq;\n\tuint32_t cnt_ctl;\n\tuint64_t cnt_cval;\n\tuint64_t freq;\n};\n\nstruct vtimer_context {\n\tstruct vtimer phy_timer;\n\tstruct vtimer virt_timer;\n\tunsigned long offset;\n};\n\nstatic int arm_phy_timer_trap(struct vcpu *vcpu,\n\t\tint reg, int read, unsigned long *value);\n\nstatic int vtimer_vmodule_id = INVALID_MODULE_ID;\n\n#define get_access_vtimer(vtimer, c, access)\t\t\\\n\tdo {\t\t\t\t\t\t\\\n\t\tvtimer = &c->phy_timer;\t\t\t\\\n\t} while (0)\n\nstatic void phys_timer_expire_function(unsigned long data)\n{\n\tstruct vtimer *vtimer = (struct vtimer *)data;\n\n\tvtimer->cnt_ctl |= CNT_CTL_ISTATUS;\n\tvtimer->cnt_cval = 0;\n\n\tif (!(vtimer->cnt_ctl & CNT_CTL_IMASK))\n\t\tsend_virq_to_vcpu(vtimer->vcpu, vtimer->virq);\n}\n\nstatic void virt_timer_expire_function(unsigned long data)\n{\n\tstruct vtimer *vtimer = (struct vtimer *)data;\n\n\t/*\n\t * just wake up the target vCPU. when switch to\n\t * this vcpu, the value of vtimer will restore and\n\t * if the irq is not mask, the vtimer will trigger\n\t * the hardware irq again.\n\t */\n\twake(&vtimer->vcpu->vcpu_event);\n}\n\nstatic void vtimer_state_restore(struct vcpu *vcpu, void *context)\n{\n\tstruct vtimer_context *c = (struct vtimer_context *)context;\n\tstruct vtimer *vtimer = &c->virt_timer;\n\n\tstop_timer(&vtimer->timer);\n\n\twrite_sysreg64(c->offset, ARM64_CNTVOFF_EL2);\n\twrite_sysreg64(vtimer->cnt_cval, ARM64_CNTV_CVAL_EL0);\n\twrite_sysreg32(vtimer->cnt_ctl, ARM64_CNTV_CTL_EL0);\n\tisb();\n}\n\nstatic void vtimer_state_save(struct vcpu *vcpu, void *context)\n{\n\tstruct task *task = vcpu->task;\n\tstruct vtimer_context *c = (struct vtimer_context *)context;\n\tstruct vtimer *vtimer = &c->virt_timer;\n\n\tvtimer->cnt_cval = read_sysreg64(ARM64_CNTV_CVAL_EL0);\n\tvtimer->cnt_ctl = read_sysreg32(ARM64_CNTV_CTL_EL0);\n\twrite_sysreg32(0, CNTV_CTL_EL0);\n\tisb();\n\n\tif ((task->state == TASK_STATE_STOP) ||\n\t\t\t(task->state == TASK_STATE_SUSPEND))\n\t\treturn;\n\n\tif ((vtimer->cnt_ctl & CNT_CTL_ENABLE) &&\n\t\t!(vtimer->cnt_ctl & CNT_CTL_IMASK)) {\n\t\tmod_timer(&vtimer->timer, ticks_to_ns(vtimer->cnt_cval +\n\t\t\t\tc->offset - boot_tick));\n\t}\n}\n\nstatic void vtimer_state_init(struct vcpu *vcpu, void *context)\n{\n\tstruct vtimer *vtimer;\n\tstruct arm_virt_data *arm_data = vcpu->vm->arch_data;\n\tstruct vtimer_context *c = (struct vtimer_context *)context;\n\n\tif (get_vcpu_id(vcpu) == 0) {\n\t\tvcpu->vm->time_offset = get_sys_ticks();\n\t\tarm_data->phy_timer_trap = arm_phy_timer_trap;\n\t}\n\n\tc->offset = vcpu->vm->time_offset;\n\n\tvtimer = &c->virt_timer;\n\tvtimer->vcpu = vcpu;\n\tvtimer->virq = vcpu->vm->vtimer_virq;\n\tvtimer->cnt_ctl = 0;\n\tvtimer->cnt_cval = 0;\n\tinit_timer(&vtimer->timer, virt_timer_expire_function,\n\t\t\t(unsigned long)vtimer);\n\n\tvtimer = &c->phy_timer;\n\tvtimer->vcpu = vcpu;\n\tvtimer->virq = 26;\n\tvtimer->cnt_ctl = 0;\n\tvtimer->cnt_cval = 0;\n\tinit_timer(&vtimer->timer, phys_timer_expire_function,\n\t\t\t(unsigned long)vtimer);\n}\n\nstatic void vtimer_state_stop(struct vcpu *vcpu, void *context)\n{\n\tstruct vtimer_context *c = (struct vtimer_context *)context;\n\n\tstop_timer(&c->virt_timer.timer);\n\tstop_timer(&c->phy_timer.timer);\n}\n\nstatic inline void\nasoc_handle_cntp_ctl(struct vcpu *vcpu, struct vtimer *vtimer)\n{\n\t/*\n\t * apple xnu use physical timer's interrupt as a fiq\n\t * and read the ctl register to check wheter the timer\n\t * is triggered, if the read access is happened in the\n\t * fiq handler, need to clear the interrupt\n\t */\n\tif ((vtimer->cnt_ctl & CNT_CTL_ISTATUS) &&\n\t\t\t(read_sysreg(HCR_EL2) & HCR_EL2_VF)) {\n\t\tvtimer->cnt_ctl &= ~CNT_CTL_ISTATUS;\n\t\tclear_pending_virq(vcpu, vtimer->virq);\n\t}\n}\n\nstatic void vtimer_handle_cntp_ctl(struct vcpu *vcpu, int access,\n\t\tint read, unsigned long *value)\n{\n\tuint32_t v;\n\tstruct vtimer *vtimer;\n\tstruct vtimer_context *c;\n\tunsigned long ns;\n\n\tc = get_vmodule_data_by_id(vcpu, vtimer_vmodule_id);\n\tget_access_vtimer(vtimer, c, access);\n\n\tif (read) {\n\t\t*value = vtimer->cnt_ctl;\n\t\tif (vcpu->vm->os->type == OS_TYPE_XNU)\n\t\t\tasoc_handle_cntp_ctl(vcpu, vtimer);\n\t} else {\n\t\tv = (uint32_t)(*value);\n\t\tv &= ~CNT_CTL_ISTATUS;\n\n\t\tif (v & CNT_CTL_ENABLE)\n\t\t\tv |= vtimer->cnt_ctl & CNT_CTL_ISTATUS;\n\t\tvtimer->cnt_ctl = v;\n\n\t\tif ((vtimer->cnt_ctl & CNT_CTL_ENABLE) &&\n\t\t\t\t(vtimer->cnt_cval != 0)) {\n\t\t\tns = ticks_to_ns(vtimer->cnt_cval + c->offset);\n\t\t\tmod_timer(&vtimer->timer, ns);\n\t\t} else {\n\t\t\tstop_timer(&vtimer->timer);\n\t\t}\n\t}\n}\n\nstatic void vtimer_handle_cntp_tval(struct vcpu *vcpu,\n\t\tint access, int read, unsigned long *value)\n{\n\tstruct vtimer *vtimer;\n\tunsigned long now;\n\tunsigned long ticks;\n\tstruct vtimer_context *c;\n\n\tc = get_vmodule_data_by_id(vcpu, vtimer_vmodule_id);\n\tget_access_vtimer(vtimer, c, access);\n\tnow = get_sys_ticks() - c->offset;\n\n\tif (read) {\n\t\tticks = (vtimer->cnt_cval - now - c->offset) & 0xffffffff;\n\t\t*value = ticks;\n\t} else {\n\t\tunsigned long v = *value;\n\n\t\tvtimer->cnt_cval = get_sys_ticks() + v;\n\t\tif (vtimer->cnt_ctl & CNT_CTL_ENABLE) {\n\t\t\tvtimer->cnt_ctl &= ~CNT_CTL_ISTATUS;\n\t\t\tticks = ticks_to_ns(vtimer->cnt_cval);\n\t\t\tmod_timer(&vtimer->timer, ticks);\n\t\t}\n\t}\n}\n\nstatic void vtimer_handle_cntp_cval(struct vcpu *vcpu,\n\t\tint access, int read, unsigned long *value)\n{\n\tunsigned long ns;\n\tstruct vtimer *vtimer;\n\tstruct vtimer_context *c;\n\n\tc = get_vmodule_data_by_id(vcpu, vtimer_vmodule_id);\n\tget_access_vtimer(vtimer, c, access);\n\n\tif (read) {\n\t\t*value = vtimer->cnt_cval - c->offset;\n\t} else {\n\t\tvtimer->cnt_cval = *value + c->offset;\n\t\tif (vtimer->cnt_ctl & CNT_CTL_ENABLE) {\n\t\t\tvtimer->cnt_ctl &= ~CNT_CTL_ISTATUS;\n\t\t\tns = ticks_to_ns(vtimer->cnt_cval);\n\t\t\tmod_timer(&vtimer->timer, ns);\n\t\t}\n\t}\n}\n\nstatic int arm_phy_timer_trap(struct vcpu *vcpu,\n\t\tint reg, int read, unsigned long *value)\n{\n\tswitch (reg) {\n\tcase ESR_SYSREG_CNTP_CTL_EL0:\n\t\tvtimer_handle_cntp_ctl(vcpu, ACCESS_REG, read, value);\n\t\tbreak;\n\tcase ESR_SYSREG_CNTP_CVAL_EL0:\n\t\tvtimer_handle_cntp_cval(vcpu, ACCESS_REG, read, value);\n\t\tbreak;\n\tcase ESR_SYSREG_CNTP_TVAL_EL0:\n\t\tvtimer_handle_cntp_tval(vcpu, ACCESS_REG, read, value);\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\nstatic int vtimer_vmodule_init(struct vmodule *vmodule)\n{\n\tvmodule->context_size = sizeof(struct vtimer_context);\n\tvmodule->state_init = vtimer_state_init;\n\tvmodule->state_save = vtimer_state_save;\n\tvmodule->state_restore = vtimer_state_restore;\n\tvmodule->state_stop = vtimer_state_stop;\n\tvmodule->state_reset = vtimer_state_stop;\n\tvtimer_vmodule_id = vmodule->id;\n\n\treturn 0;\n}\n\nint arch_vtimer_init(uint32_t virtual_irq, uint32_t phy_irq)\n{\n\treturn register_vcpu_vmodule(\"vtimer_module\", vtimer_vmodule_init);\n}\n\nint virtual_timer_irq_handler(uint32_t irq, void *data)\n{\n\tuint32_t value;\n\tstruct vcpu *vcpu = get_current_vcpu();\n\n\t/*\n\t * if the current task is not a vcpu, disable the vtimer\n\t * since the pending request vtimer irq is set to\n\t * the timer\n\t */\n\tif (!task_is_vcpu(current)) {\n\t\twrite_sysreg32(0, ARM64_CNTV_CTL_EL0);\n\t\treturn 0;\n\t}\n\n\t/*\n\t * this case ususally happened when the vcpu called\n\t * WFI to enter idle idle mode, but the vtimer irq is\n\t * triggered when context switch. then when in idle task\n\t * this IRQ is responsed. two case need consider:\n\t *\n\t * 1 - the vtimer interrup will send to wrong vcpu ?\n\t * 2 - Here the logic of idle can be optimized to avoid\n\t *     this situation\n\t */\n\tvalue = read_sysreg32(ARM64_CNTV_CTL_EL0);\n\tif (!(value & CNT_CTL_ISTATUS)) {\n\t\tpr_debug(\"vtimer is not trigger\\n\");\n\t\treturn 0;\n\t}\n\n\tvalue = value | CNT_CTL_IMASK;\n\twrite_sysreg32(value, ARM64_CNTV_CTL_EL0);\n\n\treturn send_virq_to_vcpu(vcpu, vcpu->vm->vtimer_virq);\n}\n"
  },
  {
    "path": "kernel/configs/espressobin_defconfig",
    "content": "CONFIG_ARCH_AARCH64=y\nCONFIG_64BIT=y\n\n#\n# Minos aarch64 Arch Feature\n#\nCONFIG_NR_CPUS_CLUSTER0=2\nCONFIG_NR_CPUS_CLUSTER1=0\n# CONFIG_MPIDR_SHIFT is not set\nCONFIG_EXCEPTION_STACK_SIZE=0x2000\n# end of Minos aarch64 Arch Feature\n\n#\n# Minos aarch64 virtualaztion features\n#\n\n#\n# Minos OS configuration\n#\nCONFIG_MAX_CPU_NR=8\n# CONFIG_TASK_STACK_SIZE_4K is not set\nCONFIG_TASK_STACK_SIZE_8K=y\nCONFIG_TASK_STACK_SIZE=0x2000\nCONFIG_TASK_STACK_SHIFT=13\nCONFIG_STACK_PAGE_ALIGN=y\nCONFIG_MAX_SLAB_BLOCKS=10\nCONFIG_TASK_RUN_TIME=100\nCONFIG_MINOS_IRQWORK_IRQ=5\nCONFIG_SMP_FUNCTION_CALL_IRQ=6\nCONFIG_MINOS_RESCHED_IRQ=7\nCONFIG_SMP=y\nCONFIG_NR_SGI_IRQS=16\nCONFIG_NR_PPI_IRQS=16\nCONFIG_NR_SPI_IRQS=256\n# CONFIG_OS_REALTIME_CORE0 is not set\n# CONFIG_PRINT_DEBUG is not set\n# CONFIG_PRINT_INFO is not set\nCONFIG_PRINT_NOTICE=y\n# CONFIG_PRINT_WARN is not set\n# CONFIG_PRINT_ERROR is not set\nCONFIG_DEFAULT_MM_ALLOCATOR=y\n# CONFIG_SIMPLE_MM_ALLOCATOR is not set\nCONFIG_LOG_LEVEL=3\n# end of Minos OS configuration\n\n#\n# Minos Virtualization Configuration\n#\nCONFIG_VIRT=y\nCONFIG_VIRTIO_MMIO=y\nCONFIG_MAX_VM=64\nCONFIG_VRTC_PL031=y\nCONFIG_VWDT_SP805=y\n\n#\n# Virqchip controller support\n#\nCONFIG_VIRQCHIP_VGICV2=y\nCONFIG_VIRQCHIP_VGICV3=y\n# CONFIG_VIRQCHIP_BCM2836 is not set\nCONFIG_VIRQCHIP_AIC=y\n# end of Virqchip controller support\n\nCONFIG_VMBOX=y\n\n#\n# VM operating system support\n#\nCONFIG_OS_LINUX_SUPPORT=y\nCONFIG_OS_XNU_SUPPORT=y\n# end of VM operating system support\n# end of Minos Virtualization Configuration\n\n#\n# Device Drivers\n#\n\n#\n# Interrupt Controller Driver\n#\nCONFIG_IRQCHIP_GICV3=y\nCONFIG_IRQCHIP_GICV2=y\n# CONFIG_IRQCHIP_BCM2836 is not set\n# end of Interrupt Controller Driver\n\n#\n# Serial Drivers\n#\nCONFIG_SERIAL=y\n# CONFIG_SERIAL_BCM283X_MU is not set\nCONFIG_SERIAL_MVEBU_A3700=y\n# CONFIG_SERIAL_PL011 is not set\n# CONFIG_SERIAL_AMLOGIC is not set\n# end of Serial Drivers\n\nCONFIG_DEVICE_TREE=y\n# end of Device Drivers\n\n#\n# Platform Configuration\n#\n# CONFIG_SOC_FVP is not set\nCONFIG_SOC_MARVELL_A3700=y\n# CONFIG_SOC_BCM2837 is not set\n# CONFIG_SOC_BCM2838 is not set\n# CONFIG_SOC_AMLOGIC is not set\nCONFIG_MINOS_ENTRY_ADDRESS=0x3c004000\nCONFIG_MINOS_RAM_SIZE=0x4000000\nCONFIG_NR_CPUS=2\nCONFIG_UART_BASE=0xd0012000\nCONFIG_UART_IO_SIZE=0x1000\n# end of Platform Configuration\n\n#\n# Third Party Library And Module\n#\n\n#\n# Application Config\n#\n# CONFIG_SHELL is not set\n# end of Application Config\n\n#\n# System libary config\n#\n# end of System libary config\n"
  },
  {
    "path": "kernel/configs/fvp_a76_defconfig",
    "content": "CONFIG_ARCH_AARCH64=y\nCONFIG_64BIT=y\n\n#\n# Minos aarch64 Arch Feature\n#\nCONFIG_NR_CPUS_CLUSTER0=2\nCONFIG_NR_CPUS_CLUSTER1=0\n# CONFIG_MPIDR_SHIFT is not set\nCONFIG_EXCEPTION_STACK_SIZE=0x2000\n# end of Minos aarch64 Arch Feature\n\n#\n# Minos aarch64 virtualaztion features\n#\n\n#\n# Minos OS configuration\n#\nCONFIG_MAX_CPU_NR=8\n# CONFIG_TASK_STACK_SIZE_4K is not set\nCONFIG_TASK_STACK_SIZE_8K=y\nCONFIG_TASK_STACK_SIZE=0x2000\nCONFIG_TASK_STACK_SHIFT=13\nCONFIG_STACK_PAGE_ALIGN=y\nCONFIG_MAX_SLAB_BLOCKS=10\nCONFIG_TASK_RUN_TIME=100\nCONFIG_MINOS_IRQWORK_IRQ=5\nCONFIG_SMP_FUNCTION_CALL_IRQ=6\nCONFIG_MINOS_RESCHED_IRQ=7\nCONFIG_SMP=y\nCONFIG_NR_SGI_IRQS=16\nCONFIG_NR_PPI_IRQS=16\nCONFIG_NR_SPI_IRQS=256\n# CONFIG_OS_REALTIME_CORE0 is not set\n# CONFIG_PRINT_DEBUG is not set\n# CONFIG_PRINT_INFO is not set\nCONFIG_PRINT_NOTICE=y\n# CONFIG_PRINT_WARN is not set\n# CONFIG_PRINT_ERROR is not set\nCONFIG_DEFAULT_MM_ALLOCATOR=y\n# CONFIG_SIMPLE_MM_ALLOCATOR is not set\nCONFIG_LOG_LEVEL=3\n# end of Minos OS configuration\n\n#\n# Minos Virtualization Configuration\n#\nCONFIG_VIRT=y\nCONFIG_VIRTIO_MMIO=y\nCONFIG_MAX_VM=64\nCONFIG_VRTC_PL031=y\nCONFIG_VWDT_SP805=y\n\n#\n# Virqchip controller support\n#\nCONFIG_VIRQCHIP_VGICV2=y\nCONFIG_VIRQCHIP_VGICV3=y\n# CONFIG_VIRQCHIP_BCM2836 is not set\nCONFIG_VIRQCHIP_AIC=y\n# end of Virqchip controller support\n\nCONFIG_VMBOX=y\n\n#\n# VM operating system support\n#\nCONFIG_OS_LINUX_SUPPORT=y\nCONFIG_OS_XNU_SUPPORT=y\n# end of VM operating system support\n# end of Minos Virtualization Configuration\n\n#\n# Device Drivers\n#\n\n#\n# Interrupt Controller Driver\n#\nCONFIG_IRQCHIP_GICV3=y\nCONFIG_IRQCHIP_GICV2=y\n# CONFIG_IRQCHIP_BCM2836 is not set\n# end of Interrupt Controller Driver\n\n#\n# Serial Drivers\n#\nCONFIG_SERIAL=y\n# CONFIG_SERIAL_BCM283X_MU is not set\n# CONFIG_SERIAL_MVEBU_A3700 is not set\nCONFIG_SERIAL_PL011=y\n# CONFIG_SERIAL_AMLOGIC is not set\n# end of Serial Drivers\n\nCONFIG_DEVICE_TREE=y\n# end of Device Drivers\n\n#\n# Platform Configuration\n#\nCONFIG_SOC_FVP=y\n# CONFIG_SOC_MARVELL_A3700 is not set\n# CONFIG_SOC_BCM2837 is not set\n# CONFIG_SOC_BCM2838 is not set\n# CONFIG_SOC_AMLOGIC is not set\nCONFIG_MINOS_ENTRY_ADDRESS=0xc0000000\nCONFIG_MINOS_RAM_SIZE=0x4000000\nCONFIG_NR_CPUS=2\nCONFIG_MPIDR_SHIFT=y\nCONFIG_UART_BASE=0x1c0a0000\nCONFIG_UART_IO_SIZE=0x1000\n# end of Platform Configuration\n\n#\n# Third Party Library And Module\n#\n\n#\n# Application Config\n#\nCONFIG_SHELL=y\n\n#\n# Shell config\n#\nCONFIG_SHELL_TASK_PRIO=63\n# end of Shell config\n# end of Application Config\n\n#\n# System libary config\n#\n\n#\n# Shell Command Support\n#\nCONFIG_SHELL_COMMAND_TASK=y\n# end of Shell Command Support\n# end of System libary config\n"
  },
  {
    "path": "kernel/configs/fvp_defconfig",
    "content": "CONFIG_ARCH_AARCH64=y\nCONFIG_64BIT=y\n\n#\n# Minos aarch64 Arch Feature\n#\nCONFIG_NR_CPUS_CLUSTER0=4\nCONFIG_NR_CPUS_CLUSTER1=0\n# CONFIG_MPIDR_SHIFT is not set\nCONFIG_EXCEPTION_STACK_SIZE=0x2000\n# end of Minos aarch64 Arch Feature\n\n#\n# Minos aarch64 virtualaztion features\n#\n\n#\n# Minos OS configuration\n#\nCONFIG_MAX_CPU_NR=8\n# CONFIG_TASK_STACK_SIZE_4K is not set\nCONFIG_TASK_STACK_SIZE_8K=y\nCONFIG_TASK_STACK_SIZE=0x2000\nCONFIG_TASK_STACK_SHIFT=13\nCONFIG_STACK_PAGE_ALIGN=y\nCONFIG_MAX_SLAB_BLOCKS=10\nCONFIG_TASK_RUN_TIME=100\nCONFIG_MINOS_IRQWORK_IRQ=5\nCONFIG_SMP_FUNCTION_CALL_IRQ=6\nCONFIG_MINOS_RESCHED_IRQ=7\nCONFIG_SMP=y\nCONFIG_NR_SGI_IRQS=16\nCONFIG_NR_PPI_IRQS=16\nCONFIG_NR_SPI_IRQS=256\n# CONFIG_OS_REALTIME_CORE0 is not set\n# CONFIG_PRINT_DEBUG is not set\n# CONFIG_PRINT_INFO is not set\nCONFIG_PRINT_NOTICE=y\n# CONFIG_PRINT_WARN is not set\n# CONFIG_PRINT_ERROR is not set\nCONFIG_DEFAULT_MM_ALLOCATOR=y\n# CONFIG_SIMPLE_MM_ALLOCATOR is not set\nCONFIG_LOG_LEVEL=4\n# end of Minos OS configuration\n\n#\n# Minos Virtualization Configuration\n#\nCONFIG_VIRT=y\nCONFIG_VIRTIO_MMIO=y\nCONFIG_MAX_VM=8\nCONFIG_VRTC_PL031=y\nCONFIG_VWDT_SP805=y\n\n#\n# Virqchip controller support\n#\nCONFIG_VIRQCHIP_VGICV2=y\nCONFIG_VIRQCHIP_VGICV3=y\n# CONFIG_VIRQCHIP_BCM2836 is not set\nCONFIG_VIRQCHIP_AIC=y\n# end of Virqchip controller support\n\nCONFIG_VMBOX=y\n\n#\n# VM operating system support\n#\nCONFIG_OS_LINUX_SUPPORT=y\nCONFIG_OS_XNU_SUPPORT=y\n# end of VM operating system support\n# end of Minos Virtualization Configuration\n\n#\n# Device Drivers\n#\n\n#\n# Interrupt Controller Driver\n#\nCONFIG_IRQCHIP_GICV3=y\nCONFIG_IRQCHIP_GICV2=y\n# CONFIG_IRQCHIP_BCM2836 is not set\n# end of Interrupt Controller Driver\n\n#\n# Serial Drivers\n#\nCONFIG_SERIAL=y\n# CONFIG_SERIAL_BCM283X_MU is not set\n# CONFIG_SERIAL_MVEBU_A3700 is not set\nCONFIG_SERIAL_PL011=y\n# CONFIG_SERIAL_AMLOGIC is not set\n# end of Serial Drivers\n\nCONFIG_DEVICE_TREE=y\n# end of Device Drivers\n\n#\n# Platform Configuration\n#\nCONFIG_SOC_FVP=y\n# CONFIG_SOC_MARVELL_A3700 is not set\n# CONFIG_SOC_BCM2837 is not set\n# CONFIG_SOC_BCM2838 is not set\n# CONFIG_SOC_AMLOGIC is not set\nCONFIG_MINOS_ENTRY_ADDRESS=0xc0000000\nCONFIG_MINOS_RAM_SIZE=0x4000000\nCONFIG_NR_CPUS=4\nCONFIG_UART_BASE=0x1c0a0000\nCONFIG_UART_IO_SIZE=0x1000\n# end of Platform Configuration\n\n#\n# Third Party Library And Module\n#\n\n#\n# Application Config\n#\nCONFIG_SHELL=y\n\n#\n# Shell config\n#\nCONFIG_SHELL_TASK_PRIO=63\n# end of Shell config\n# end of Application Config\n\n#\n# System libary config\n#\n\n#\n# Shell Command Support\n#\nCONFIG_SHELL_COMMAND_TASK=y\n# end of Shell Command Support\n# end of System libary config\n"
  },
  {
    "path": "kernel/configs/fvp_rtos_defconfig",
    "content": "CONFIG_ARCH_AARCH64=y\nCONFIG_DEVICE_TREE=y\nCONFIG_PLATFORM_FVP=y\nCONFIG_SERIAL_PL011=y\nCONFIG_IRQCHIP_GICV3=y\nCONFIG_IRQCHIP_GICV2=y\nCONFIG_VIRQCHIP_VGICV2=y\nCONFIG_VIRQCHIP_VGICV3=y\nCONFIG_VIRTIO_MMIO=y\nCONFIG_VRTC_PL031=y\nCONFIG_VWDT_SP805=y\n\n# 0xc0000000 + CONFIG_NR_CPUS * 8K = \nCONFIG_MINOS_ENTRY_ADDRESS=0xc0008000\n\nCONFIG_MINOS_RAM_SIZE=64M\nCONFIG_MAX_CPU_NR=8\nCONFIG_NR_CPUS=4\nCONFIG_NR_CPUS_CLUSTER0=4\nCONFIG_NR_CPUS_CLUSTER1=0\n\nCONFIG_UART_BASE=0x1c090000\nCONFIG_UART_IO_SIZE=0x40000\n\n# all realtime task will sched at core0\n# CONFIG_OS_REALTIME_CORE0\n\nCONFIG_TASK_RUN_TIME=100\n\n# CONFIG_VIRT=y\n\nCONFIG_EXCEPTION_SIZE=8192\n\nCONFIG_TASK_STACK_SIZE=8192\nCONFIG_TASK_STACK_SHIFT=13\nCONFIG_STACK_PAGE_ALIGN=y\nCONFIG_SMP=y\n"
  },
  {
    "path": "kernel/configs/kvim3_defconfig",
    "content": "CONFIG_ARCH_AARCH64=y\nCONFIG_64BIT=y\n\n#\n# Minos aarch64 Arch Feature\n#\nCONFIG_NR_CPUS_CLUSTER0=2\nCONFIG_NR_CPUS_CLUSTER1=4\n# CONFIG_MPIDR_SHIFT is not set\nCONFIG_EXCEPTION_STACK_SIZE=0x2000\n# end of Minos aarch64 Arch Feature\n\n#\n# Minos aarch64 virtualaztion features\n#\n\n#\n# Minos OS configuration\n#\nCONFIG_MAX_CPU_NR=8\n# CONFIG_TASK_STACK_SIZE_4K is not set\nCONFIG_TASK_STACK_SIZE_8K=y\nCONFIG_TASK_STACK_SIZE=0x2000\nCONFIG_TASK_STACK_SHIFT=13\nCONFIG_STACK_PAGE_ALIGN=y\nCONFIG_MAX_SLAB_BLOCKS=10\nCONFIG_TASK_RUN_TIME=100\nCONFIG_MINOS_IRQWORK_IRQ=5\nCONFIG_SMP_FUNCTION_CALL_IRQ=6\nCONFIG_MINOS_RESCHED_IRQ=7\nCONFIG_SMP=y\nCONFIG_NR_SGI_IRQS=16\nCONFIG_NR_PPI_IRQS=16\nCONFIG_NR_SPI_IRQS=512\n# CONFIG_OS_REALTIME_CORE0 is not set\n# CONFIG_PRINT_DEBUG is not set\nCONFIG_PRINT_INFO=y\n# CONFIG_PRINT_NOTICE is not set\n# CONFIG_PRINT_WARN is not set\n# CONFIG_PRINT_ERROR is not set\nCONFIG_DEFAULT_MM_ALLOCATOR=y\n# CONFIG_SIMPLE_MM_ALLOCATOR is not set\nCONFIG_LOG_LEVEL=4\n# end of Minos OS configuration\n\n#\n# Minos Virtualization Configuration\n#\nCONFIG_VIRT=y\nCONFIG_VIRTIO_MMIO=y\nCONFIG_MAX_VM=64\nCONFIG_VRTC_PL031=y\nCONFIG_VWDT_SP805=y\n\n#\n# Virqchip controller support\n#\nCONFIG_VIRQCHIP_VGICV2=y\nCONFIG_VIRQCHIP_VGICV3=y\n# CONFIG_VIRQCHIP_BCM2836 is not set\nCONFIG_VIRQCHIP_AIC=y\n# end of Virqchip controller support\n\nCONFIG_VMBOX=y\n\n#\n# VM operating system support\n#\nCONFIG_OS_LINUX_SUPPORT=y\nCONFIG_OS_XNU_SUPPORT=y\n# end of VM operating system support\n# end of Minos Virtualization Configuration\n\n#\n# Device Drivers\n#\n\n#\n# Interrupt Controller Driver\n#\n# CONFIG_IRQCHIP_GICV3 is not set\nCONFIG_IRQCHIP_GICV2=y\n# CONFIG_IRQCHIP_BCM2836 is not set\n# end of Interrupt Controller Driver\n\n#\n# Serial Drivers\n#\nCONFIG_SERIAL=y\n# CONFIG_SERIAL_BCM283X_MU is not set\n# CONFIG_SERIAL_MVEBU_A3700 is not set\n# CONFIG_SERIAL_PL011 is not set\nCONFIG_SERIAL_AMLOGIC=y\n# end of Serial Drivers\n\nCONFIG_DEVICE_TREE=y\n# end of Device Drivers\n\n#\n# Platform Configuration\n#\n# CONFIG_SOC_FVP is not set\n# CONFIG_SOC_MARVELL_A3700 is not set\n# CONFIG_SOC_BCM2837 is not set\n# CONFIG_SOC_BCM2838 is not set\nCONFIG_SOC_AMLOGIC=y\nCONFIG_MINOS_ENTRY_ADDRESS=0xeb80c000\nCONFIG_MINOS_RAM_SIZE=0x2000000\nCONFIG_NR_CPUS=6\nCONFIG_UART_BASE=0xff803000\nCONFIG_UART_IO_SIZE=0x1000\nCONFIG_DTB_LOAD_ADDRESS=0xed600000\n# end of Platform Configuration\n\n#\n# Third Party Library And Module\n#\n\n#\n# Application Config\n#\nCONFIG_SHELL=y\n\n#\n# Shell config\n#\nCONFIG_SHELL_TASK_PRIO=63\n# end of Shell config\n# end of Application Config\n\n#\n# System libary config\n#\n\n#\n# Shell Command Support\n#\nCONFIG_SHELL_COMMAND_TASK=y\n# end of Shell Command Support\n# end of System libary config\n"
  },
  {
    "path": "kernel/configs/qemu_arm64_defconfig",
    "content": "CONFIG_ARCH_AARCH64=y\nCONFIG_64BIT=y\n\n#\n# Minos aarch64 Arch Feature\n#\nCONFIG_NR_CPUS_CLUSTER0=4\nCONFIG_NR_CPUS_CLUSTER1=0\nCONFIG_EXCEPTION_STACK_SIZE=0x2000\n# CONFIG_ARM_ATOMIC_LSE is not set\nCONFIG_PTOV_MASK=0x0\nCONFIG_VTOP_MASK=0x0\n# end of Minos aarch64 Arch Feature\n\n#\n# Minos aarch64 virtualaztion features\n#\n# CONFIG_ARM_VHE is not set\n# end of Minos aarch64 virtualaztion features\n\n#\n# Minos OS configuration\n#\nCONFIG_MAX_CPU_NR=8\n# CONFIG_TASK_STACK_SIZE_4K is not set\nCONFIG_TASK_STACK_SIZE_8K=y\nCONFIG_TASK_STACK_SIZE=0x2000\nCONFIG_TASK_STACK_SHIFT=13\nCONFIG_STACK_PAGE_ALIGN=y\nCONFIG_TASK_RUN_TIME=100\nCONFIG_MINOS_IRQWORK_IRQ=5\nCONFIG_SMP_FUNCTION_CALL_IRQ=6\nCONFIG_MINOS_RESCHED_IRQ=7\nCONFIG_SMP=y\nCONFIG_NR_SGI_IRQS=16\nCONFIG_NR_PPI_IRQS=16\nCONFIG_NR_SPI_IRQS=256\n# CONFIG_PRINT_DEBUG is not set\nCONFIG_PRINT_INFO=y\n# CONFIG_PRINT_NOTICE is not set\n# CONFIG_PRINT_WARN is not set\n# CONFIG_PRINT_ERROR is not set\nCONFIG_LOG_LEVEL=4\n# end of Minos OS configuration\n\n#\n# Minos Virtualization Configuration\n#\nCONFIG_VIRT=y\nCONFIG_VIRTIO_MMIO=y\nCONFIG_MAX_VM=64\nCONFIG_VRTC_PL031=y\nCONFIG_VWDT_SP805=y\n\n#\n# Virqchip controller support\n#\nCONFIG_VIRQCHIP_VGICV2=y\nCONFIG_VIRQCHIP_VGICV3=y\n# CONFIG_VIRQCHIP_BCM2836 is not set\nCONFIG_VIRQCHIP_AIC=y\n# end of Virqchip controller support\n\nCONFIG_VMBOX=y\n\n#\n# VM operating system support\n#\nCONFIG_OS_LINUX_SUPPORT=y\nCONFIG_OS_XNU_SUPPORT=y\n# end of VM operating system support\n# end of Minos Virtualization Configuration\n\n#\n# Device Drivers\n#\n\n#\n# Interrupt Controller Driver\n#\nCONFIG_IRQCHIP_GICV3=y\nCONFIG_IRQCHIP_GICV2=y\n# CONFIG_IRQCHIP_BCM2836 is not set\n# end of Interrupt Controller Driver\n\n#\n# Serial Drivers\n#\nCONFIG_SERIAL=y\n# CONFIG_SERIAL_BCM283X_MU is not set\n# CONFIG_SERIAL_MVEBU_A3700 is not set\nCONFIG_SERIAL_PL011=y\n# CONFIG_SERIAL_AMLOGIC is not set\n# end of Serial Drivers\n\nCONFIG_DEVICE_TREE=y\n# end of Device Drivers\n\n#\n# Platform Configuration\n#\n# CONFIG_SOC_FVP is not set\n# CONFIG_SOC_MARVELL_A3700 is not set\n# CONFIG_SOC_BCM2837 is not set\n# CONFIG_SOC_BCM2838 is not set\n# CONFIG_SOC_AMLOGIC is not set\nCONFIG_SOC_QEMU=y\nCONFIG_MINOS_ENTRY_ADDRESS=0x40000000\nCONFIG_MINOS_RAM_SIZE=0x4000000\nCONFIG_NR_CPUS=4\nCONFIG_UART_BASE=0x9000000\nCONFIG_UART_IO_SIZE=0x1000\nCONFIG_UART_IRQ=33\n# end of Platform Configuration\n\nCONFIG_SHELL=y\n\n#\n# Third Party Library And Module\n#\nCONFIG_SHELL_COMMAND_TASK=y\n"
  },
  {
    "path": "kernel/configs/r8a7795_defconfig",
    "content": "CONFIG_NR_CPUS_CLUSTER1=4\nCONFIG_SMP=y\nCONFIG_NR_SPI_IRQS=480\nCONFIG_LOG_LEVEL_COLORFUL=y\nCONFIG_VIRT=y\nCONFIG_SOC_R8A7795=y\nCONFIG_SHELL=y\n"
  },
  {
    "path": "kernel/configs/rpi_3_defconfig",
    "content": "CONFIG_ARCH_AARCH64=y\nCONFIG_64BIT=y\n\n#\n# Minos aarch64 Arch Feature\n#\nCONFIG_NR_CPUS_CLUSTER0=4\nCONFIG_NR_CPUS_CLUSTER1=0\n# CONFIG_MPIDR_SHIFT is not set\nCONFIG_EXCEPTION_STACK_SIZE=0x2000\n# end of Minos aarch64 Arch Feature\n\n#\n# Minos aarch64 virtualaztion features\n#\n\n#\n# Minos OS configuration\n#\nCONFIG_MAX_CPU_NR=8\n# CONFIG_TASK_STACK_SIZE_4K is not set\nCONFIG_TASK_STACK_SIZE_8K=y\nCONFIG_TASK_STACK_SIZE=0x2000\nCONFIG_TASK_STACK_SHIFT=13\nCONFIG_STACK_PAGE_ALIGN=y\nCONFIG_MAX_SLAB_BLOCKS=10\nCONFIG_TASK_RUN_TIME=100\nCONFIG_MINOS_IRQWORK_IRQ=5\nCONFIG_SMP_FUNCTION_CALL_IRQ=6\nCONFIG_MINOS_RESCHED_IRQ=7\nCONFIG_SMP=y\nCONFIG_NR_SGI_IRQS=16\nCONFIG_NR_PPI_IRQS=16\nCONFIG_NR_SPI_IRQS=256\n# CONFIG_OS_REALTIME_CORE0 is not set\n# CONFIG_PRINT_DEBUG is not set\n# CONFIG_PRINT_INFO is not set\nCONFIG_PRINT_NOTICE=y\n# CONFIG_PRINT_WARN is not set\n# CONFIG_PRINT_ERROR is not set\nCONFIG_DEFAULT_MM_ALLOCATOR=y\n# CONFIG_SIMPLE_MM_ALLOCATOR is not set\nCONFIG_LOG_LEVEL=3\n# end of Minos OS configuration\n\n#\n# Minos Virtualization Configuration\n#\nCONFIG_VIRT=y\nCONFIG_VIRTIO_MMIO=y\nCONFIG_MAX_VM=64\nCONFIG_VRTC_PL031=y\nCONFIG_VWDT_SP805=y\n\n#\n# Virqchip controller support\n#\nCONFIG_VIRQCHIP_VGICV2=y\nCONFIG_VIRQCHIP_VGICV3=y\nCONFIG_VIRQCHIP_BCM2836=y\nCONFIG_VIRQCHIP_AIC=y\n# end of Virqchip controller support\n\nCONFIG_VMBOX=y\n\n#\n# VM operating system support\n#\nCONFIG_OS_LINUX_SUPPORT=y\nCONFIG_OS_XNU_SUPPORT=y\n# end of VM operating system support\n# end of Minos Virtualization Configuration\n\n#\n# Device Drivers\n#\n\n#\n# Interrupt Controller Driver\n#\n# CONFIG_IRQCHIP_GICV3 is not set\n# CONFIG_IRQCHIP_GICV2 is not set\nCONFIG_IRQCHIP_BCM2836=y\n# end of Interrupt Controller Driver\n\n#\n# Serial Drivers\n#\nCONFIG_SERIAL=y\nCONFIG_SERIAL_BCM283X_MU=y\n# CONFIG_SERIAL_MVEBU_A3700 is not set\n# CONFIG_SERIAL_PL011 is not set\n# CONFIG_SERIAL_AMLOGIC is not set\n# end of Serial Drivers\n\nCONFIG_DEVICE_TREE=y\n# end of Device Drivers\n\n#\n# Platform Configuration\n#\n# CONFIG_SOC_FVP is not set\n# CONFIG_SOC_MARVELL_A3700 is not set\nCONFIG_SOC_BCM2837=y\n# CONFIG_SOC_BCM2838 is not set\n# CONFIG_SOC_AMLOGIC is not set\nCONFIG_MINOS_ENTRY_ADDRESS=0x28008000\nCONFIG_MINOS_RAM_SIZE=0x2000000\nCONFIG_NR_CPUS=4\nCONFIG_UART_BASE=0x3f215040\nCONFIG_UART_IO_SIZE=0x1000\nCONFIG_PLATFORM_BCM2837=y\nCONFIG_HVM_SPI_VIRQ_NR=96\n# end of Platform Configuration\n\n#\n# Third Party Library And Module\n#\n\n#\n# Application Config\n#\n# CONFIG_SHELL is not set\n# end of Application Config\n\n#\n# System libary config\n#\n# end of System libary config\n"
  },
  {
    "path": "kernel/configs/rpi_4_defconfig",
    "content": "CONFIG_ARCH_AARCH64=y\nCONFIG_64BIT=y\n\n#\n# Minos aarch64 Arch Feature\n#\nCONFIG_NR_CPUS_CLUSTER0=4\nCONFIG_NR_CPUS_CLUSTER1=0\n# CONFIG_MPIDR_SHIFT is not set\nCONFIG_EXCEPTION_STACK_SIZE=0x2000\n# end of Minos aarch64 Arch Feature\n\n#\n# Minos aarch64 virtualaztion features\n#\n\n#\n# Minos OS configuration\n#\nCONFIG_MAX_CPU_NR=8\n# CONFIG_TASK_STACK_SIZE_4K is not set\nCONFIG_TASK_STACK_SIZE_8K=y\nCONFIG_TASK_STACK_SIZE=0x2000\nCONFIG_TASK_STACK_SHIFT=13\nCONFIG_STACK_PAGE_ALIGN=y\nCONFIG_MAX_SLAB_BLOCKS=10\nCONFIG_TASK_RUN_TIME=100\nCONFIG_MINOS_IRQWORK_IRQ=5\nCONFIG_SMP_FUNCTION_CALL_IRQ=6\nCONFIG_MINOS_RESCHED_IRQ=7\nCONFIG_SMP=y\nCONFIG_NR_SGI_IRQS=16\nCONFIG_NR_PPI_IRQS=16\nCONFIG_NR_SPI_IRQS=256\n# CONFIG_OS_REALTIME_CORE0 is not set\n# CONFIG_PRINT_DEBUG is not set\n# CONFIG_PRINT_INFO is not set\nCONFIG_PRINT_NOTICE=y\n# CONFIG_PRINT_WARN is not set\n# CONFIG_PRINT_ERROR is not set\nCONFIG_DEFAULT_MM_ALLOCATOR=y\n# CONFIG_SIMPLE_MM_ALLOCATOR is not set\nCONFIG_LOG_LEVEL=3\n# end of Minos OS configuration\n\n#\n# Minos Virtualization Configuration\n#\nCONFIG_VIRT=y\nCONFIG_VIRTIO_MMIO=y\nCONFIG_MAX_VM=64\nCONFIG_VRTC_PL031=y\nCONFIG_VWDT_SP805=y\n\n#\n# Virqchip controller support\n#\nCONFIG_VIRQCHIP_VGICV2=y\nCONFIG_VIRQCHIP_VGICV3=y\n# CONFIG_VIRQCHIP_BCM2836 is not set\nCONFIG_VIRQCHIP_AIC=y\n# end of Virqchip controller support\n\nCONFIG_VMBOX=y\n\n#\n# VM operating system support\n#\nCONFIG_OS_LINUX_SUPPORT=y\nCONFIG_OS_XNU_SUPPORT=y\n# end of VM operating system support\n# end of Minos Virtualization Configuration\n\n#\n# Device Drivers\n#\n\n#\n# Interrupt Controller Driver\n#\n# CONFIG_IRQCHIP_GICV3 is not set\nCONFIG_IRQCHIP_GICV2=y\n# CONFIG_IRQCHIP_BCM2836 is not set\n# end of Interrupt Controller Driver\n\n#\n# Serial Drivers\n#\nCONFIG_SERIAL=y\nCONFIG_SERIAL_BCM283X_MU=y\n# CONFIG_SERIAL_MVEBU_A3700 is not set\n# CONFIG_SERIAL_PL011 is not set\n# CONFIG_SERIAL_AMLOGIC is not set\n# end of Serial Drivers\n\nCONFIG_DEVICE_TREE=y\n# end of Device Drivers\n\n#\n# Platform Configuration\n#\n# CONFIG_SOC_FVP is not set\n# CONFIG_SOC_MARVELL_A3700 is not set\n# CONFIG_SOC_BCM2837 is not set\nCONFIG_SOC_BCM2838=y\n# CONFIG_SOC_AMLOGIC is not set\nCONFIG_MINOS_ENTRY_ADDRESS=0x37408000\nCONFIG_MINOS_RAM_SIZE=0x4000000\nCONFIG_NR_CPUS=4\nCONFIG_UART_BASE=0xfe215040\nCONFIG_UART_IO_SIZE=0x1000\n# end of Platform Configuration\n\n#\n# Third Party Library And Module\n#\n\n#\n# Application Config\n#\nCONFIG_SHELL=y\n\n#\n# Shell config\n#\nCONFIG_SHELL_TASK_PRIO=63\n# end of Shell config\n# end of Application Config\n\n#\n# System libary config\n#\n\n#\n# Shell Command Support\n#\nCONFIG_SHELL_COMMAND_TASK=y\n# end of Shell Command Support\n# end of System libary config\n"
  },
  {
    "path": "kernel/core/Kconfig",
    "content": "menu \"Minos OS configuration\"\n\nconfig MAX_CPU_NR\n\tint \"max cpu in system\"\n\tdefault 8\n\thelp\n\t  max cpu count in system\n\nchoice\n\tprompt \"default task stack size\"\n\tdefault TASK_STACK_SIZE_8K\n\tconfig TASK_STACK_SIZE_4K\n\t\tbool \"4K\"\n\tconfig TASK_STACK_SIZE_8K\n\t\tbool \"8k\"\nendchoice\n\nconfig TASK_STACK_SIZE\n\thex\n\tdefault 0x1000 if TASK_STACK_SIZE_4K\n\tdefault 0x2000 if TASK_STACK_SIZE_8K\n\tdefault 0x2000\n\nconfig TASK_STACK_SHIFT\n\tint\n\tdefault 12 if TASK_STACK_SIZE_4K\n\tdefault 13\n\trange 12 14\n\thelp\n\t  the shift size of task stack\n\nconfig STACK_PAGE_ALIGN\n\tbool \"stack size is 4K align\"\n\tdefault n\n\thelp\n\t  \"the stack for all the task need 4K align\"\n\nconfig MAX_SLAB_BLOCKS\n\tint \"default SLAB blocks\"\n\tdefault 10\n\nconfig TASK_RUN_TIME\n\tint \"default task run time in ms\"\n\tdefault 100\n\nconfig MINOS_IRQWORK_IRQ\n\tint \"default irq_work IRQ number\"\n\tdefault 5\n\nconfig SMP_FUNCTION_CALL_IRQ\n\tint \"default smp cpu function call irq number\"\n\tdefault 6\n\nconfig MINOS_RESCHED_IRQ\n\tint \"default resched IRQ number\"\n\tdefault 7\n\nconfig SMP\n\tbool \"SMP system\"\n\thelp\n\t  smp system\n\nconfig NR_SGI_IRQS\n\tint \"SGI irq count for each cpu\"\n\tdefault 16\n\thelp\n\t  how many SGI irq for each cpu\n\nconfig NR_PPI_IRQS\n\tint \"Percpu irq count for each cpu\"\n\tdefault 16\n\thelp\n\t  how many percpu irq for each cpu\n\nconfig NR_SPI_IRQS\n\tint \"SPI irq count for each cpu\"\n\tdefault 256\n\thelp\n\t  how many spi irq in system\n\nconfig OS_REALTIME_CORE0\n\tbool \"all realtime task will affinity to core 0\"\n\tdefault n\n\thelp\n\t  if enable this feature, all the realtime task will\n\t  affinity to cpu0\n\nchoice\n\tprompt \"Printf log level\"\n\tdefault PRINT_INFO\n\tconfig PRINT_DEBUG\n\t\tbool \"Log Level DEBUG\"\n\tconfig PRINT_INFO\n\t\tbool \"Log Level INFO\"\n\tconfig PRINT_NOTICE\n\t\tbool \"Log Level NOTICE\"\n\tconfig PRINT_WARN\n\t\tbool \"Log Level WARNING\"\n\tconfig PRINT_ERROR\n\t\tbool \"Log Level ERROR\"\nendchoice\n\nchoice\n\tprompt \"Memory allocator\"\n\tdefault DEFAULT_MM_ALLOCATOR\n\tconfig DEFAULT_MM_ALLOCATOR\n\t\tbool \"default mm allocator support\"\n\tconfig SIMPLE_MM_ALLOCATOR\n\t\tbool \"simple mm allocator for non-virtualaztion\"\nendchoice\n\nconfig LOG_LEVEL\n\tint\n\tdefault 5 if PRINT_DEBUG\n\tdefault 4 if PRINT_INFO\n\tdefault 3 if PRINT_NOTICE\n\tdefault 2 if PRINT_WARN\n\tdefault 1 if PRINT_ERROR\n\tdefault 4\n\nendmenu\n"
  },
  {
    "path": "kernel/core/Makefile",
    "content": "obj-y += bitmap.o\nobj-y += bootarg.o\nobj-y += kmem.o\nobj-y += calltrace.o\nobj-y += delay.o\nobj-y += event.o\nobj-y += find_bit.o\nobj-y += flag.o\nobj-y += hook.o\nobj-y += hweight.o\nobj-y += idle.o\nobj-y += init.o\nobj-y += irq.o\nobj-y += mbox.o\nobj-y += minos.o\nobj-y += mem.o\nobj-y += kmem.o\nobj-y += iomem.o\nobj-y += mutex.o\nobj-y += page.o\nobj-y += percpu.o\nobj-y += print.o\nobj-y += queue.o\nobj-y += ramdisk.o\nobj-y += sched.o\nobj-y += sem.o\nobj-y += slab.o\nobj-y += smp.o\nobj-y += stdlib.o\nobj-y += string.o\nobj-y += task.o\nobj-y += timer.o\nobj-y += host_vspace.o\n"
  },
  {
    "path": "kernel/core/bitmap.c",
    "content": "/*\n * lib/bitmap.c\n * Helper functions for bitmap.h.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n * This source code is licensed under the GNU General Public License,\n * Version 2.  See the file COPYING for more details.\n */\n#include <minos/types.h>\n#include <minos/errno.h>\n#include <minos/bitmap.h>\n#include <minos/bitops.h>\n#include <minos/string.h>\n\n#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))\n\nint8_t const ffs_one_table[256] = {\n\t-1, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x00 to 0x0F */\n\t4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x10 to 0x1F */\n\t5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x20 to 0x2F */\n\t4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x30 to 0x3F */\n\t6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x40 to 0x4F */\n\t4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x50 to 0x5F */\n\t5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x60 to 0x6F */\n\t4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x70 to 0x7F */\n\t7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x80 to 0x8F */\n\t4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x90 to 0x9F */\n\t5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xA0 to 0xAF */\n\t4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xB0 to 0xBF */\n\t6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xC0 to 0xCF */\n\t4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xD0 to 0xDF */\n\t5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xE0 to 0xEF */\n\t4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0  /* 0xF0 to 0xFF */\n};\n\n/*\n * bitmaps provide an array of bits, implemented using an an\n * array of unsigned longs.  The number of valid bits in a\n * given bitmap does _not_ need to be an exact multiple of\n * BITS_PER_LONG.\n *\n * The possible unused bits in the last, partially used word\n * of a bitmap are 'don't care'.  The implementation makes\n * no particular effort to keep them zero.  It ensures that\n * their value will not affect the results of any operation.\n * The bitmap operations that return Boolean (bitmap_empty,\n * for example) or scalar (bitmap_weight, for example) results\n * carefully filter out these unused bits from impacting their\n * results.\n *\n * These operations actually hold to a slightly stronger rule:\n * if you don't input any bitmaps to these ops that have some\n * unused bits set, then they won't output any set unused bits\n * in output bitmaps.\n *\n * The byte ordering of bitmaps is more natural on little\n * endian architectures.  See the big-endian headers\n * include/asm-ppc64/bitops.h and include/asm-s390/bitops.h\n * for the best explanations of this ordering.\n */\n\nint __bitmap_weight(const unsigned long *bitmap, unsigned int bits)\n{\n\tunsigned int k, lim = bits/BITS_PER_LONG;\n\tint w = 0;\n\n\tfor (k = 0; k < lim; k++)\n\t\tw += hweight_long(bitmap[k]);\n\n\tif (bits % BITS_PER_LONG)\n\t\tw += hweight_long(bitmap[k] & BITMAP_LAST_WORD_MASK(bits));\n\n\treturn w;\n}\n\nvoid bitmap_set(unsigned long *map, unsigned int start, int len)\n{\n\tunsigned long *p = map + BIT_WORD(start);\n\tconst unsigned int size = start + len;\n\tint bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG);\n\tunsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start);\n\n\twhile (len - bits_to_set >= 0) {\n\t\t*p |= mask_to_set;\n\t\tlen -= bits_to_set;\n\t\tbits_to_set = BITS_PER_LONG;\n\t\tmask_to_set = ~0UL;\n\t\tp++;\n\t}\n\tif (len) {\n\t\tmask_to_set &= BITMAP_LAST_WORD_MASK(size);\n\t\t*p |= mask_to_set;\n\t}\n}\n\nvoid bitmap_clear(unsigned long *map, unsigned int start, int len)\n{\n\tunsigned long *p = map + BIT_WORD(start);\n\tconst unsigned int size = start + len;\n\tint bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG);\n\tunsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start);\n\n\twhile (len - bits_to_clear >= 0) {\n\t\t*p &= ~mask_to_clear;\n\t\tlen -= bits_to_clear;\n\t\tbits_to_clear = BITS_PER_LONG;\n\t\tmask_to_clear = ~0UL;\n\t\tp++;\n\t}\n\tif (len) {\n\t\tmask_to_clear &= BITMAP_LAST_WORD_MASK(size);\n\t\t*p &= ~mask_to_clear;\n\t}\n}\n\n/**\n * bitmap_find_next_zero_area_off - find a contiguous aligned zero area\n * @map: The address to base the search on\n * @size: The bitmap size in bits\n * @start: The bitnumber to start searching at\n * @nr: The number of zeroed bits we're looking for\n * @align_mask: Alignment mask for zero area\n * @align_offset: Alignment offset for zero area.\n *\n * The @align_mask should be one less than a power of 2; the effect is that\n * the bit offset of all zero areas this function finds plus @align_offset\n * is multiple of that power of 2.\n */\nunsigned long bitmap_find_next_zero_area_off(unsigned long *map,\n\t\t\t\t\t     unsigned long size,\n\t\t\t\t\t     unsigned long start,\n\t\t\t\t\t     unsigned int nr,\n\t\t\t\t\t     unsigned long align_mask,\n\t\t\t\t\t     unsigned long align_offset)\n{\n\tunsigned long index, end, i;\nagain:\n\tindex = find_next_zero_bit(map, size, start);\n\n\t/* Align allocation */\n\tindex = __ALIGN_MASK(index + align_offset, align_mask) - align_offset;\n\n\tend = index + nr;\n\tif (end > size)\n\t\treturn end;\n\ti = find_next_bit(map, end, index);\n\tif (i < end) {\n\t\tstart = i + 1;\n\t\tgoto again;\n\t}\n\treturn index;\n}\n\nunsigned long bitmap_find_next_zero_area_align(unsigned long *map,\n\t\t\t\t\t     unsigned long size,\n\t\t\t\t\t     unsigned long start,\n\t\t\t\t\t     unsigned int nr,\n\t\t\t\t\t     unsigned long align)\n{\n\tunsigned long index, end, i;\nagain:\n\tindex = find_next_zero_bit(map, size, start);\n\n\tend = index + nr;\n\tif (end > size)\n\t\treturn end;\n\n\tif ((index & ((align - 1)))) {\n\t\tstart = index + 1;\n\t\tgoto again;\n\t}\n\n\ti = find_next_bit(map, end, index);\n\tif (i < end) {\n\t\tstart = i + 1;\n\t\tgoto again;\n\t}\n\treturn index;\n}\n"
  },
  {
    "path": "kernel/core/bootarg.c",
    "content": "/*\n * Copyright (C) 2020 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/bootarg.h>\n#include <minos/mm.h>\n\nstruct boot_option {\n\tchar *name;\n\tchar *args;\n\tchar *sub_args;\n\tstruct boot_option *next;\n};\n\n#define CMDLINE_SIZE 511\nstatic char cmdline[CMDLINE_SIZE + 1];\n\nstatic struct boot_option *boot_options;\n\nint __get_boot_option(char *name, void *value,\n\t\tint (*parse)(char *args, void *value))\n{\n\tstruct boot_option *bo;\n\n\tfor (bo = boot_options; bo != NULL; bo = bo->next) {\n\t\tif (strcmp(name, bo->name) != 0)\n\t\t\tcontinue;\n\n\t\treturn parse(bo->args, value);\n\t}\n\n\treturn -ENOENT;\n}\n\nstatic int __parse_hex32(char *args, void *value)\n{\n\tif (!args)\n\t\treturn -EINVAL;\n\n\t*(uint32_t *)value = strtoul(args, NULL, 16);\n\treturn 0;\n}\n\nstatic int __parse_hex64(char *args, void *value)\n{\n\tif (!args)\n\t\treturn -EINVAL;\n\n\t*(uint64_t *)value = strtoul(args, NULL, 16);\n\treturn 0;\n}\n\nstatic int __parse_uint(char *args, void *value)\n{\n\tif (!args)\n\t\treturn -EINVAL;\n\n\t*(uint32_t *)value = strtoul(args, NULL, 10);\n\treturn 0;\n}\n\nstatic int __parse_bool(char *args, void *value)\n{\n\t*(int*)value = 1;\n\treturn 0;\n}\n\nstatic int __parse_string(char *args, void *value)\n{\n\tif (!args)\n\t\treturn -EINVAL;\n\n\t*(char **)value = args;\n\n\treturn 0;\n}\n\nint bootarg_parse_hex32(char *name, uint32_t *v)\n{\n\treturn __get_boot_option(name, v, __parse_hex32);\n}\n\nint bootarg_parse_hex64(char *name, uint64_t *v)\n{\n\treturn __get_boot_option(name, v, __parse_hex64);\n}\n\nint bootarg_parse_uint(char *name, uint32_t *v)\n{\n\treturn __get_boot_option(name, v, __parse_uint);\n}\n\nint bootarg_parse_bool(char *name, int *v)\n{\n\t*v = 0;\n\treturn __get_boot_option(name, v, __parse_bool);\n}\n\nint bootarg_parse_string(char *name, char **v)\n{\n\treturn __get_boot_option(name, v, __parse_string);\n}\n\nstatic void bootarg_init_one(char *str)\n{\n\tstruct boot_option *bo;\n\n\tif ((*str == 0) || (*str == ' '))\n\t\treturn;\n\n\tbo = malloc(sizeof(struct boot_option));\n\tif (!bo)\n\t\tpanic(\"no more boot memory for boot argument\\n\");\n\n\tmemset(bo, 0, sizeof(struct boot_option));\n\tbo->name = strsep(&str, \"=\");\n\tbo->args = str;\n\n\tbo->next = boot_options;\n\tboot_options = bo;\n}\n\nint __init_text bootargs_init(const char *str, int len)\n{\n\tchar *bootarg;\n\tchar *tmp = &cmdline[0];\n\n\tpr_notice(\"bootargs: %s\\n\", str);\n\tif (len > (CMDLINE_SIZE))\n\t\tpr_warn(\"cmdline size too long information may lost\\n\");\n\n\tlen = len > CMDLINE_SIZE ? CMDLINE_SIZE : len;\n\tstrncpy(cmdline, str, len);\n\tcmdline[len] = 0;\n\n\twhile ((bootarg = strsep(&tmp, \" \")) != NULL)\n\t\tbootarg_init_one(bootarg);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "kernel/core/calltrace.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <asm/arch.h>\n#include <minos/smp.h>\n#include <minos/irq.h>\n\nstatic unsigned long *allsyms_address;\nstatic unsigned int *allsyms_offset;\nstatic int allsyms_count;\nstatic char *allsyms_names;\n\nextern unsigned char __symbols_start;\n\nstatic DEFINE_SPIN_LOCK(dump_lock);\n\nvoid dump_stack(gp_regs *regs, unsigned long *stack)\n{\n\tunsigned long flags;\n\n\tspin_lock_irqsave(&dump_lock, flags);\n\t/*\n\t * first dump some percpu data to show the stat\n\t * of the cpu such as premeept need_resched etc...\n\t */\n\tpr_fatal(\"preempt:%d need_resche:%d os_running:%d\\n\",\n\t\t\tpreempt_allowed(), need_resched(),\n\t\t\tos_is_running());\n\n\tarch_dump_stack(regs, stack);\n\tspin_unlock_irqrestore(&dump_lock, flags);\n}\n\nstatic void panic_other_cpu(void *data)\n{\n\tpr_fatal(\"[Panic called by other cpu]\\n\");\n\tdump_stack(NULL, NULL);\n\n\tfor (;;)\n\t\tcpu_relax();\n}\n\nvoid __panic(gp_regs *regs, char *fmt, ...)\n{\n\tint cpu;\n\tva_list arg;\n\tint printed;\n\tchar buffer[512];\n\n\t/*\n\t * disable local irq panic will directly called\n\t * by the code\n\t */\n\tlocal_irq_disable();\n\n\tva_start(arg, fmt);\n\tprinted = vsprintf(buffer, fmt, arg);\n\tva_end(arg);\n\n\tprinted = printed >= 512 ? 511 : printed;\n\tbuffer[printed + 1] = 0;\n\n\tpr_fatal(\"[Panic] %s\", buffer);\n\tdump_stack(regs, NULL);\n\n\t/* inform other cpu to do panic */\n\tfor (cpu = 0; cpu < NR_CPUS; cpu++) {\n\t\tif (cpu == smp_processor_id())\n\t\t\tcontinue;\n\n\t\tsmp_function_call(cpu, panic_other_cpu, NULL, 0);\n\t}\n\n\tfor (;;)\n\t\tcpu_relax();\n}\n\nstatic int locate_symbol_pos(unsigned long addr)\n{\n\tint left = 0, right = 1;\n\n\tif (allsyms_count <= 0)\n\t\treturn -1;\n\n\twhile (1) {\n\t\tif (right == allsyms_count)\n\t\t\tbreak;;\n\n\t\tif (addr == allsyms_address[right])\n\t\t\treturn right;\n\n\t\tif ((addr >= allsyms_address[left]) &&\n\t\t\t\t(addr < allsyms_address[right]))\n\t\t\treturn left;\n\n\t\tleft++;\n\t\tright++;\n\t}\n\n\tif ((addr >= allsyms_address[left]) &&\n\t\t(addr < (unsigned long)&__symbols_start))\n\t\treturn left;\n\n\treturn -1;\n}\n\nvoid print_symbol(unsigned long addr)\n{\n\tint pos;\n\tunsigned long symbol_left;\n\tunsigned long symbol_right;\n\tunsigned int offset;\n\tchar *name = NULL;\n\n\tpos = locate_symbol_pos(addr);\n\tif (pos == -1)\n\t\treturn;\n\n\tsymbol_left = allsyms_address[pos];\n\tif (pos == (allsyms_count - 1))\n\t\tsymbol_right = (unsigned long)&__symbols_start;\n\telse\n\t\tsymbol_right = allsyms_address[pos + 1];\n\n\toffset = allsyms_offset[pos];\n\tname = allsyms_names + offset;\n\n\tpr_err(\"[%p] ? %s+0x%x/0x%x\\n\", addr, name,\n\t\t\taddr - symbol_left,\n\t\t\tsymbol_right - symbol_left);\n}\n\nint allsymbols_init(void)\n{\n\tint *tmp;\n\tunsigned long *symbols_base;\n\n\tsymbols_base = (unsigned long *)&__symbols_start;\n\tallsyms_address = (unsigned long *)(*symbols_base++);\n\ttmp = (int *)(*symbols_base++);\n\tallsyms_count = *tmp;\n\tallsyms_offset = (unsigned int *)(*symbols_base++);\n\tallsyms_names = (char *)(*symbols_base);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "kernel/core/delay.c",
    "content": "/*\n * Copyright (C) 2019 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/types.h>\n#include <minos/arch.h>\n#include <minos/task.h>\n#include <minos/sched.h>\n#include <minos/time.h>\n\nvoid udelay(uint32_t us)\n{\n\tunsigned long deadline = get_sys_time() + 1000 *\n\t\t(unsigned long)us;\n\n\twhile (get_sys_time() < deadline);\n\n\tdsbsy();\n\tisb();\n}\n\nvoid mdelay(uint32_t ms)\n{\n\tunsigned long deadline = get_sys_time();\n\n\tdeadline += 1000000 * (unsigned long)ms;\n\twhile (get_sys_time() < deadline);\n\n\tdsbsy();\n\tisb();\n}\n\nvoid msleep(uint32_t ms)\n{\n\ttask_sleep(ms);\n}\n"
  },
  {
    "path": "kernel/core/event.c",
    "content": "/*\n * Copyright (C) 2019 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/task.h>\n#include <minos/sched.h>\n#include <minos/event.h>\n#include <minos/mm.h>\n#include <minos/smp.h>\n\nstatic atomic_t event_token = { 1 };\nstatic atomic_t event_token_gen = { 0 };\n\nuint32_t new_event_token(void)\n{\n\tuint32_t value;\n\n\twhile (1) {\n\t\tvalue = (uint32_t)atomic_inc_return_old(&event_token);\n\t\tif (value == 0)\n\t\t\tatomic_inc(&event_token_gen);\n\t\telse\n\t\t\tbreak;\n\t}\n\n\treturn value;\n}\n\nvoid event_init(struct event *event, int type, void *pdata)\n{\n\tevent->type = type;\n\tspin_lock_init(&event->lock);\n\tinit_list(&event->wait_list);\n\tevent->data = pdata;\n\tevent->owner = 0;\n}\n\nvoid __wait_event(void *ev, int mode, uint32_t to)\n{\n\tstruct task *task = current;\n\tstruct event *event;\n\n\tdo_not_preempt();\n\n\t/*\n\t * the process of flag is different with other IPC\n\t * method\n\t */\n\tif (mode == OS_EVENT_TYPE_FLAG) {\n\t\ttask->flag_node = ev;\n\t} else {\n\t\tevent = (struct event *)ev;\n\t\tlist_add_tail(&event->wait_list, &task->event_list);\n\t}\n\n\t/*\n\t * after event_task_wait, the process will call sched()\n\t * by itself, before sched() is called, the task can not\n\t * be sched out, since at the same time another thread\n\t * may wake up this process, which may case dead lock\n\t * with current design.\n\t */\n\ttask->state = TASK_STATE_WAIT_EVENT;\n\ttask->pend_state = TASK_STATE_PEND_OK;\n\ttask->wait_type = mode;\n\ttask->wait_event = ev;\n\ttask->delay = (to == -1 ? 0 : to);\n}\n\nstatic inline void remove_event_waiter(struct event *ev, struct task *task)\n{\n\tunsigned long flags;\n\n\tspin_lock_irqsave(&ev->lock, flags);\n\tif (task->event_list.next != NULL) {\n\t\tASSERT(task->wait_event = (void *)ev);\n\t\tlist_del(&task->event_list);\n\t\ttask->event_list.next = NULL;\n\t}\n\tspin_unlock_irqrestore(&ev->lock, flags);\n}\n\nstatic inline struct task *get_event_waiter(struct event *ev)\n{\n\tstruct task *task;\n\n\tif (is_list_empty(&ev->wait_list))\n\t\treturn NULL;\n\n\ttask = list_first_entry(&ev->wait_list, struct task, event_list);\n\tlist_del(&task->event_list);\n\n\treturn task;\n}\n\n/*\n * num - the number need to wake ? <= 0 means, wakeup all.\n * will return the number of task which have been wake.\n */\nint __wake_up_event_waiter(struct event *ev, long msg, int pend_state, int num)\n{\n\tstruct task *task;\n\tint ret, cnt = 0;\n\n\tnum = (num == 0) ? 1 : num;\n\n\tdo {\n\t\ttask = get_event_waiter(ev);\n\t\tif (!task)\n\t\t\tbreak;\n\n\t\tret = __wake_up(task, pend_state, (unsigned long)msg);\n\t\tif (ret)\n\t\t\tcontinue;\n\n\t\tif (++cnt == num)\n\t\t\tbreak;\n\t} while (1);\n\n\treturn cnt;\n}\n\nstruct task *wake_up_one_event_waiter(struct event *ev,\n\t\tlong msg, int pend_state)\n{\n\tstruct task *task;\n\n\tdo {\n\t\ttask = get_event_waiter(ev);\n\t\tif (!task)\n\t\t\tbreak;\n\t} while (__wake_up(task, pend_state, (unsigned long)msg));\n\n\treturn task;\n}\n\nvoid event_pend_down(void)\n{\n\tstruct task *task = current;\n\n\ttask->pend_state = TASK_STATE_PEND_OK;\n\ttask->wait_event = NULL;\n\ttask->wait_type = 0;\n\ttask->ipcdata = 0;\n}\n\nlong __wake(struct event *ev, int pend_state, long retcode)\n{\n\tunsigned long flags;\n\tstruct task *task;\n\n\tspin_lock_irqsave(&ev->lock, flags);\n\ttask = wake_up_one_event_waiter(ev, retcode, pend_state);\n\tspin_unlock_irqrestore(&ev->lock, flags);\n\n\treturn task ? 0 : -ENOENT;\n}\n\nlong do_wait_event(struct event *ev)\n{\n\tlong ret = 0;\n\n\tsched();\n\n\tswitch (current->pend_state) {\n\tcase TASK_STATE_PEND_OK:\n\t\tbreak;\n\tcase TASK_STATE_PEND_TO:\n\tcase TASK_STATE_PEND_ABORT:\n\tdefault:\n\t\tremove_event_waiter(ev, current);\n\t\tbreak;\n\t}\n\n\tret = current->retcode;\n\tevent_pend_down();\n\n\treturn ret;\n}\n"
  },
  {
    "path": "kernel/core/find_bit.c",
    "content": "/* bit search implementation\n *\n * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.\n * Written by David Howells (dhowells@redhat.com)\n *\n * Copyright (C) 2008 IBM Corporation\n * 'find_last_bit' is written by Rusty Russell <rusty@rustcorp.com.au>\n * (Inspired by David Howell's find_next_bit implementation)\n *\n * Rewritten by Yury Norov <yury.norov@gmail.com> to decrease\n * size and improve performance, 2015.\n *\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; either version\n * 2 of the License, or (at your option) any later version.\n */\n\n#include <minos/bitops.h>\n#include <minos/bitmap.h>\n\n/*\n * This is a common helper function for find_next_bit and\n * find_next_zero_bit.  The difference is the \"invert\" argument, which\n * is XORed with each fetched word before searching it for one bits.\n */\nstatic unsigned long _find_next_bit(const unsigned long *addr,\n\t\tunsigned long nbits, unsigned long start, unsigned long invert)\n{\n\tunsigned long tmp;\n\n\tif (!nbits || start >= nbits)\n\t\treturn nbits;\n\n\ttmp = addr[start / BITS_PER_LONG] ^ invert;\n\n\t/* Handle 1st word. */\n\ttmp &= BITMAP_FIRST_WORD_MASK(start);\n\tstart = round_down(start, BITS_PER_LONG);\n\n\twhile (!tmp) {\n\t\tstart += BITS_PER_LONG;\n\t\tif (start >= nbits)\n\t\t\treturn nbits;\n\n\t\ttmp = addr[start / BITS_PER_LONG] ^ invert;\n\t}\n\n\treturn min(start + __ffs(tmp), nbits);\n}\n\n/*\n * Find the next set bit in a memory region.\n */\nunsigned long find_next_bit(const unsigned long *addr, unsigned long size,\n\t\t\t    unsigned long offset)\n{\n\treturn _find_next_bit(addr, size, offset, 0UL);\n}\n\nunsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,\n\t\t\t\t unsigned long offset)\n{\n\treturn _find_next_bit(addr, size, offset, ~0UL);\n}\n\nunsigned long _find_next_bit_loop(const unsigned long *addr, unsigned long size,\n\t\t\t\tunsigned long offset, unsigned long invert)\n{\n\tunsigned long bit;\n\nloop:\n\tbit = _find_next_bit(addr, size, offset, invert);\n\tif (bit >= size) {\n\t\tif (offset != 0) {\n\t\t\toffset = 0;\n\t\t\tgoto loop;\n\t\t}\n\t}\n\n\treturn bit;\n}\n\nunsigned long find_next_bit_loop(const unsigned long *addr, unsigned long size,\n\t\t\t\tunsigned long offset)\n{\n\treturn _find_next_bit_loop(addr, size, offset, 0UL);\n}\n\nunsigned long find_next_zero_bit_loop(const unsigned long *addr, unsigned long size,\n\t\t\t\tunsigned long offset)\n{\n\treturn _find_next_bit_loop(addr, size, offset, ~0UL);\n}\n\n/*\n * Find the first set bit in a memory region.\n */\nunsigned long find_first_bit(const unsigned long *addr, unsigned long size)\n{\n\tunsigned long idx;\n\n\tfor (idx = 0; idx * BITS_PER_LONG < size; idx++) {\n\t\tif (addr[idx])\n\t\t\treturn min(idx * BITS_PER_LONG + __ffs(addr[idx]), size);\n\t}\n\n\treturn size;\n}\n\n/*\n * Find the first cleared bit in a memory region.\n */\nunsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size)\n{\n\tunsigned long idx;\n\n\tfor (idx = 0; idx * BITS_PER_LONG < size; idx++) {\n\t\tif (addr[idx] != ~0UL)\n\t\t\treturn min(idx * BITS_PER_LONG + ffz(addr[idx]), size);\n\t}\n\n\treturn size;\n}\n\nunsigned long find_last_bit(const unsigned long *addr, unsigned long size)\n{\n\tif (size) {\n\t\tunsigned long val = BITMAP_LAST_WORD_MASK(size);\n\t\tunsigned long idx = (size-1) / BITS_PER_LONG;\n\n\t\tdo {\n\t\t\tval &= addr[idx];\n\t\t\tif (val)\n\t\t\t\treturn idx * BITS_PER_LONG + __fls(val);\n\n\t\t\tval = ~0ul;\n\t\t} while (idx--);\n\t}\n\treturn size;\n}\n"
  },
  {
    "path": "kernel/core/flag.c",
    "content": "/*\n * Copyright (C) 2019 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/flag.h>\n#include <minos/event.h>\n#include <minos/mm.h>\n#include <minos/task.h>\n#include <minos/sched.h>\n#include <minos/spinlock.h>\n\nstruct flag_node {\n\tstruct list_head list;\n\tstruct task *task;\n\tvoid *flag_grp;\n\tflag_t flags;\n\tint wait_type;\n};\n\nstatic inline flag_t flag_wait_set_all(struct flag_grp *grp,\n\t\tflag_t flags, int consume)\n{\n\tflag_t flags_rdy;\n\n\tflags_rdy = grp->flags & flags;\n\tif (flags_rdy == flags) {\n\t\tif (consume)\n\t\t\tgrp->flags &= ~flags_rdy;\n\t} else\n\t\tflags_rdy = 0;\n\n\treturn flags_rdy;\n}\n\nstatic inline flag_t flag_wait_set_any(struct flag_grp *grp,\n\t\tflag_t flags, int consume)\n{\n\tflag_t flags_rdy;\n\n\tflags_rdy = grp->flags & flags;\n\tif ((flags_rdy != 0) && consume)\n\t\tgrp->flags &= ~flags_rdy;\n\t\n\treturn flags_rdy;\n}\n\nstatic inline flag_t flag_wait_clr_all(struct flag_grp *grp,\n\t\tflag_t flags, int consume)\n{\n\tflag_t flags_rdy;\n\n\tflags_rdy = ~grp->flags & flags;\n\tif (flags_rdy == flags) {\n\t\tif (consume)\n\t\t\tgrp->flags |= flags_rdy;\n\t} else\n\t\tflags_rdy = 0;\n\n\treturn flags_rdy;\n}\n\nstatic inline flag_t flag_wait_clr_any(struct flag_grp *grp,\n\t\tflag_t flags, int consume)\n{\n\tflag_t flags_rdy;\n\n\tflags_rdy = ~grp->flags & flags;\n\tif ((flags_rdy != 0) && consume)\n\t\tgrp->flags |= flags_rdy;\n\t\n\treturn flags_rdy;\n}\n\nflag_t flag_accept(struct flag_grp *grp, flag_t flags, int wait_type)\n{\n\tunsigned long irq;\n\tflag_t flags_rdy;\n\tint result;\n\tint consume;\n\n\tresult = wait_type & FLAG_CONSUME;\n\tif (result != 0) {\n\t\twait_type &= ~FLAG_CONSUME;\n\t\tconsume = 1;\n\t} else\n\t\tconsume = 0;\n\n\tspin_lock_irqsave(&grp->lock, irq);\n\n\tswitch (wait_type) {\n\tcase FLAG_WAIT_SET_ALL:\n\t\tflags_rdy = flag_wait_set_all(grp, flags, consume);\n\t\tbreak;\n\tcase FLAG_WAIT_SET_ANY:\n\t\tflags_rdy = flag_wait_set_any(grp, flags, consume);\n\t\tbreak;\n\tcase FLAG_WAIT_CLR_ALL:\n\t\tflags_rdy = flag_wait_clr_all(grp, flags, consume);\n\t\tbreak;\n\tcase FLAG_WAIT_CLR_ANY:\n\t\tflags_rdy = flag_wait_clr_any(grp, flags, consume);\n\t\tbreak;\n\tdefault:\n\t\tflags_rdy = 0;\n\t\tbreak;\n\t}\n\n\tspin_unlock_irqrestore(&grp->lock, irq);\n\treturn flags_rdy;\n}\n\nstatic void flag_task_ready(struct flag_node *node, flag_t flags)\n{\n\tstruct task *task = node->task;\n\n\t__wake_up(task, TASK_STATE_PEND_OK, (unsigned long)flags);\n}\n\nstatic void flag_block(struct flag_grp *grp, struct flag_node *pnode,\n\t\tflag_t flags, int wait_type, uint32_t timeout)\n{\n\tstruct task *task = get_current_task();\n\n\tmemset(pnode, 0, sizeof(struct flag_node));\n\tpnode->flags = flags;\n\tpnode->wait_type = wait_type;\n\tpnode->task = task;\n\tpnode->flag_grp = grp;\n\tlist_add_tail(&grp->wait_list, &pnode->list);\n\n\t__wait_event(pnode, OS_EVENT_TYPE_FLAG, timeout);\n}\n\nflag_t flag_pend(struct flag_grp *grp, flag_t flags,\n\t\tint wait_type, uint32_t timeout)\n{\n\tunsigned long irq;\n\tstruct flag_node node;\n\tflag_t flags_rdy = 0;\n\tint result, consume;\n\tstruct task *task = get_current_task();\n\n\tmight_sleep();\n\n\tresult = wait_type & FLAG_CONSUME;\n\tif (result) {\n\t\twait_type &= ~FLAG_CONSUME;\n\t\tconsume = 1;\n\t} else {\n\t\tconsume = 0;\n\t}\n\n\tspin_lock_irqsave(&grp->lock, irq);\n\n\t/*\n\t * check the related flags is set or clear, if the\n\t * condition is matched, then return. if the type is\n\t * not support, the task will wait forever\n\t */\n\tswitch (wait_type) {\n\tcase FLAG_WAIT_SET_ALL:\n\t\tflags_rdy = flag_wait_set_all(grp, flags, consume);\n\t\tbreak;\n\tcase FLAG_WAIT_SET_ANY:\n\t\tflags_rdy = flag_wait_set_any(grp, flags, consume);\n\t\tbreak;\n\tcase FLAG_WAIT_CLR_ALL:\n\t\tflags_rdy = flag_wait_clr_all(grp, flags, consume);\n\t\tbreak;\n\tcase FLAG_WAIT_CLR_ANY:\n\t\tflags_rdy = flag_wait_clr_any(grp, flags, consume);\n\t\tbreak;\n\tdefault:\n\t\tflags_rdy = 0;\n\t\tbreak;\n\t}\n\n\tif (flags_rdy) {\n\t\tspin_unlock_irqrestore(&grp->lock, irq);\n\t\treturn flags_rdy;\n\t}\n\n\t/*\n\t * if the condition does not matched, then the task\n\t * will suspend to wait the requested flags\n\t */\n\tflag_block(grp, &node, flags, wait_type, timeout);\n\tspin_unlock_irqrestore(&grp->lock, irq);\n\n\tsched();\n\n\tspin_lock_irqsave(&grp->lock, irq);\n\n\t/*\n\t * wait timeout or the releated event happened\n\t */\n\tif (task->pend_state != TASK_STATE_PEND_OK) {\n\t\ttask->pend_state = TASK_STATE_PEND_OK;\n\t\tlist_del(&node.list);\n\t\tflags_rdy = 0;\n\t} else {\n\t\tflags_rdy = task->flags_rdy;\n\t\tif (consume) {\n\t\t\tswitch (wait_type) {\n\t\t\tcase FLAG_WAIT_SET_ALL:\n\t\t\tcase FLAG_WAIT_SET_ANY:\n\t\t\t\tgrp->flags &= ~flags_rdy;\n\t\t\t\tbreak;\n\n\t\t\tcase FLAG_WAIT_CLR_ALL:\n\t\t\tcase FLAG_WAIT_CLR_ANY:\n\t\t\t\tgrp->flags |= flags_rdy;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tflags_rdy = 0;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tspin_unlock_irqrestore(&grp->lock, irq);\n\n\treturn flags_rdy;\n}\n\nflag_t flag_pend_get_flags_ready(void)\n{\n\treturn current->flags_rdy;\n}\n\nflag_t flag_post(struct flag_grp *grp, flag_t flags, int opt)\n{\n\tflag_t flags_rdy;\n\tunsigned long irq;\n\tstruct flag_node *pnode, *n;\n\n\tif (opt > FLAG_SET)\n\t\treturn -EINVAL;\n\n\tspin_lock_irqsave(&grp->lock, irq);\n\tswitch (opt) {\n\tcase FLAG_CLR:\n\t\tgrp->flags &= ~flags;\n\t\tbreak;\n\t\n\tcase FLAG_SET:\n\t\tgrp->flags |= flags;\n\t\tbreak;\n\t}\n\n\tlist_for_each_entry_safe(pnode, n, &grp->wait_list, list) {\n\t\tswitch (pnode->wait_type) {\n\t\tcase FLAG_WAIT_SET_ALL:\n\t\t\tflags_rdy = grp->flags & pnode->flags;\n\t\t\tif (flags_rdy == pnode->flags)\n\t\t\t\tflag_task_ready(pnode, flags_rdy);\n\t\t\tbreak;\n\n\t\tcase FLAG_WAIT_SET_ANY:\n\t\t\tflags_rdy = grp->flags & pnode->flags;\n\t\t\tif (flags_rdy != 0)\n\t\t\t\tflag_task_ready(pnode, flags_rdy);\n\t\t\tbreak;\n\n\t\tcase FLAG_WAIT_CLR_ALL:\n\t\t\tflags_rdy = ~grp->flags & pnode->flags;\n\t\t\tif (flags_rdy == pnode->flags)\n\t\t\t\tflag_task_ready(pnode, flags_rdy);\n\t\t\tbreak;\n\n\t\tcase FLAG_WAIT_CLR_ANY:\n\t\t\tflags_rdy = ~grp->flags & pnode->flags;\n\t\t\tif (flags_rdy != 0)\n\t\t\t\tflag_task_ready(pnode, flags_rdy);\n\n\t\tdefault:\n\t\t\tspin_unlock_irqrestore(&grp->lock, irq);\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\tspin_unlock_irqrestore(&grp->lock, irq);\n\n\tcond_resched();\n\n\treturn grp->flags;\n}\n"
  },
  {
    "path": "kernel/core/hook.c",
    "content": "/*\n * Copyright (C) 2019 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/mm.h>\n\nstatic struct list_head hook_lists[OS_HOOK_TYPE_UNKNOWN];\n\nstatic int hooks_init(void)\n{\n\tint i;\n\n\tfor (i = 0; i < OS_HOOK_TYPE_UNKNOWN; i++)\n\t\tinit_list(&hook_lists[i]);\n\n\treturn 0;\n}\nearly_initcall(hooks_init);\n\nint register_hook(hook_func_t fn, enum hook_type type)\n{\n\tstruct hook *hook;\n\n\tif ((fn == NULL) || (type >= OS_HOOK_TYPE_UNKNOWN)) {\n\t\tpr_err(\"Hook info is invaild\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\thook = malloc(sizeof(*hook));\n\tif (!hook)\n\t\treturn -ENOMEM;\n\n\tmemset(hook, 0, sizeof(*hook));\n\thook->fn = fn;\n\n\tlist_add_tail(&hook_lists[type], &hook->list);\n\n\treturn 0;\n}\n\nint do_hooks(void *item, void *context, enum hook_type type)\n{\n\tint err = 0;\n\tstruct hook *hook;\n\n\tlist_for_each_entry(hook, &hook_lists[type], list)\n\t\terr += hook->fn(item, context);\n\n\treturn err;\n}\n"
  },
  {
    "path": "kernel/core/host_vspace.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/mm.h>\n#include <asm/cpu_feature.h>\n\nstatic struct vspace host_vspace;\n\nint create_host_mapping(unsigned long vir, unsigned long phy,\n\t\tsize_t size, unsigned long flags)\n{\n\tint ret;\n\n\tif (!IS_PAGE_ALIGN(vir) || !IS_PAGE_ALIGN(phy) ||\n\t\t\t!IS_PAGE_ALIGN(size))\n\t\treturn -EINVAL;\n\n\tspin_lock(&host_vspace.lock);\n\tret = arch_host_map(&host_vspace, __va(vir), __va(vir + size),\n\t\t\tphy, flags | VM_HOST | VM_HUGE);\n\tspin_unlock(&host_vspace.lock);\n\n\treturn ret;\n}\n\nint destroy_host_mapping(unsigned long vir, size_t size)\n{\n\tint ret;\n\n\tif (!IS_PAGE_ALIGN(vir) || !IS_PAGE_ALIGN(size))\n\t\treturn -EINVAL;\n\n\tspin_lock(&host_vspace.lock);\n\tret = arch_host_unmap(&host_vspace, __va(vir),\n\t\t\t__va(vir + size), 0);\n\tspin_unlock(&host_vspace.lock);\n\n\treturn ret;\n}\n\nint change_host_mapping(unsigned long vir, unsigned long phy,\n\t\tunsigned long new_flags)\n{\n\tint ret;\n\n\tspin_lock(&host_vspace.lock);\n\tret = arch_host_change_map(&host_vspace, __va(vir),\n\t\t       phy, new_flags | VM_HOST);\n\tspin_unlock(&host_vspace.lock);\n\n\treturn ret;\n}\n\nunsigned long translate_va_to_pa(struct vspace *vs, unsigned long va)\n{\n\tunsigned long addr;\n\n\tspin_lock(&vs->lock);\n\taddr = (unsigned long)arch_translate_va_to_pa(vs, va);\n\tspin_unlock(&vs->lock);\n\n\treturn addr;\n}\n\nvoid *io_remap(virt_addr_t vir, size_t size)\n{\n\tsize_t new_size;\n\tunsigned long start, end;\n\n\tend = PAGE_BALIGN(vir + size);\n\tstart = PAGE_ALIGN(vir);\n\tnew_size = end - vir;\n\n\tif (!create_host_mapping(start, vir, new_size, VM_IO | VM_RW))\n\t\treturn (void *)ptov(vir);\n\n\treturn NULL;\n}\n\nint io_unmap(virt_addr_t vir, size_t size)\n{\n\tunsigned long start, end;\n\tint ret;\n\n\tvir = __va(vir);\n\tstart = PAGE_ALIGN(vir);\n\tend = PAGE_BALIGN(vir + size);\n\n\tspin_lock(&host_vspace.lock);\n\tret = arch_host_unmap(&host_vspace, start, end, 0);\n\tspin_unlock(&host_vspace.lock);\n\n\treturn ret;\n}\n\nvoid release_vspace_pages(struct vspace *vs)\n{\n\tstruct page *page = vs->release_pages;\n\tstruct page *tmp;\n\n\twhile (page) {\n\t\ttmp = page->next;\n\t\t__free_pages(page);\n\t\tpage = tmp;\n\t}\n\n\tvs->release_pages = NULL;\n}\n\nstatic void host_unmap_range(struct vspace *vs, unsigned long start,\n\t\tunsigned long end, int flags)\n{\n\trelease_vspace_pages(vs);\n}\n\nstatic struct mm_notifier_ops host_mm_notifer_ops = {\n\t.unmap_range = host_unmap_range,\n};\n\nint kernel_vspace_init(void)\n{\n\tstruct vspace *vs = &host_vspace;\n\n\t/*\n\t * init the host memory struct, the host will\n\t * use va->pa mapping, but the mmio address will\n\t * allocated a virtual range dynamicly\n\t */\n\tspin_lock_init(&vs->lock);\n\tvs->pgdp = (pgd_t *)arch_kernel_pgd_base();\n\tvs->notifier_ops = &host_mm_notifer_ops;\n\n\treturn 0;\n}\n"
  },
  {
    "path": "kernel/core/hweight.c",
    "content": "/*\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n\n#include <minos/bitops.h>\n#include <minos/types.h>\n\n/**\n * hweightN - returns the hamming weight of a N-bit word\n * @x: the word to weigh\n *\n * The Hamming Weight of a number is the total number of bits set in it.\n */\n\nunsigned int sw_hweight32(unsigned int w)\n{\n#ifdef CONFIG_ARCH_HAS_FAST_MULTIPLIER\n\tw -= (w >> 1) & 0x55555555;\n\tw =  (w & 0x33333333) + ((w >> 2) & 0x33333333);\n\tw =  (w + (w >> 4)) & 0x0f0f0f0f;\n\treturn (w * 0x01010101) >> 24;\n#else\n\tunsigned int res = w - ((w >> 1) & 0x55555555);\n\tres = (res & 0x33333333) + ((res >> 2) & 0x33333333);\n\tres = (res + (res >> 4)) & 0x0F0F0F0F;\n\tres = res + (res >> 8);\n\treturn (res + (res >> 16)) & 0x000000FF;\n#endif\n}\n\nunsigned int sw_hweight16(unsigned int w)\n{\n\tunsigned int res = w - ((w >> 1) & 0x5555);\n\tres = (res & 0x3333) + ((res >> 2) & 0x3333);\n\tres = (res + (res >> 4)) & 0x0F0F;\n\treturn (res + (res >> 8)) & 0x00FF;\n}\n\nunsigned int sw_hweight8(unsigned int w)\n{\n\tunsigned int res = w - ((w >> 1) & 0x55);\n\tres = (res & 0x33) + ((res >> 2) & 0x33);\n\treturn (res + (res >> 4)) & 0x0F;\n}\n\nunsigned long sw_hweight64(__u64 w)\n{\n#if BITS_PER_LONG == 32\n\treturn __sw_hweight32((unsigned int)(w >> 32)) +\n\t       __sw_hweight32((unsigned int)w);\n#elif BITS_PER_LONG == 64\n#ifdef CONFIG_ARCH_HAS_FAST_MULTIPLIER\n\tw -= (w >> 1) & 0x5555555555555555ul;\n\tw =  (w & 0x3333333333333333ul) + ((w >> 2) & 0x3333333333333333ul);\n\tw =  (w + (w >> 4)) & 0x0f0f0f0f0f0f0f0ful;\n\treturn (w * 0x0101010101010101ul) >> 56;\n#else\n\t__u64 res = w - ((w >> 1) & 0x5555555555555555ul);\n\tres = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul);\n\tres = (res + (res >> 4)) & 0x0F0F0F0F0F0F0F0Ful;\n\tres = res + (res >> 8);\n\tres = res + (res >> 16);\n\treturn (res + (res >> 32)) & 0x00000000000000FFul;\n#endif\n#endif\n}\n"
  },
  {
    "path": "kernel/core/idle.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <asm/arch.h>\n#include <minos/sched.h>\n#include <minos/platform.h>\n#include <minos/irq.h>\n#include <minos/mm.h>\n#include <minos/of.h>\n#include <minos/task.h>\n#include <minos/flag.h>\n#include <minos/bootarg.h>\n#include <minos/console.h>\n#include <minos/flag.h>\n\n#ifdef CONFIG_VIRT\nextern void start_all_vm(void);\n#endif\n\nvoid system_reboot(void)\n{\n\tif (platform->system_reboot)\n\t\tplatform->system_reboot(0, NULL);\n\n\tpanic(\"can not reboot system now\\n\");\n}\n\nvoid system_shutdown(void)\n{\n\tif (platform->system_shutdown)\n\t\tplatform->system_shutdown();\n\n\tpanic(\"cant not shutdown system now\\n\");\n}\n\nint system_suspend(void)\n{\n\tif (platform->system_suspend)\n\t\tplatform->system_suspend();\n\n\twfi();\n\n\treturn 0;\n}\n\nstatic inline bool pcpu_can_idle(struct pcpu *pcpu)\n{\n\treturn (pcpu->local_rdy_grp == (1 << OS_PRIO_IDLE)) &&\n\t\t(is_list_empty(&pcpu->stop_list));\n}\n\nstatic void pcpu_release_task(struct pcpu *pcpu)\n{\n\tunsigned long flags;\n\tstruct task *task;\n\n\tlocal_irq_save(flags);\n\n\twhile (!is_list_empty(&pcpu->stop_list)) {\n\t\ttask = list_first_entry(&pcpu->stop_list, struct task, state_list);\n\t\tlist_del(&task->state_list);\n\t\tdo_release_task(task);\n\t}\n\n\tlocal_irq_restore(flags);\n}\n\nstatic int kworker_task(void *data)\n{\n\tstruct pcpu *pcpu = get_pcpu();\n\tflag_t flag;\n\n\tpcpu->kworker = current;\n\tflag_init(&pcpu->kworker_flag, 0);\n\n\tfor (;;) {\n\t\tflag = flag_pend(&pcpu->kworker_flag, KWORKER_FLAG_MASK,\n\t\t\t\tFLAG_WAIT_SET_ANY | FLAG_CONSUME, 0);\n\t\tif (flag == 0) {\n\t\t\tpr_err(\"kworker: no event trigger\\n\");\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (flag & KWORKER_TASK_RECYCLE)\n\t\t\tpcpu_release_task(pcpu);\n\t}\n\n\treturn 0;\n}\n\nstatic int __init_task(void *main)\n{\n#ifdef CONFIG_VIRT\n\tprintf(\"\\n\\nStarting all VMs\\n\\n\");\n\tstart_all_vm();\n#else\n\tprintf(\"\\n\\nHello Minos\\n\\n\");\n#endif\n\treturn 0;\n}\nweak_alias(__init_task, init_task);\n\nstatic void start_system_task(void)\n{\n\textern int load_root_service(void);\n\tint cpu = smp_processor_id();\n\tstruct task *task;\n\tchar name[32];\n\n\tpr_notice(\"create kworker task...\\n\");\n\tsprintf(name, \"kworker/%d\", cpu);\n\ttask = create_kthread(name, kworker_task,\n\t\t\tOS_PRIO_DEFAULT_1, cpu, 0, NULL);\n\tASSERT(task != NULL);\n\n\tif (cpu == 0) {\n\t\tpr_notice(\"Load Root Service ...\\n\");\n\t\tinit_task(NULL);\n\t}\n}\n\nvoid cpu_idle(void)\n{\n\tstruct pcpu *pcpu = get_pcpu();\n\n\tstart_system_task();\n\n\tset_os_running();\n\tlocal_irq_enable();\n\n\tpcpu_irqwork(pcpu->pcpu_id);\n\n\twhile (1) {\n\t\tsched();\n\n\t\t/*\n\t\t * need to check whether the pcpu can go to idle\n\t\t * state to avoid the interrupt happend before wfi\n\t\t */\n\t\twhile (!need_resched() && pcpu_can_idle(pcpu)) {\n\t\t\tlocal_irq_disable();\n\t\t\tif (pcpu_can_idle(pcpu)) {\n\t\t\t\tpcpu->state = PCPU_STATE_IDLE;\n\t\t\t\twfi();\n\t\t\t\tnop();\n\t\t\t\tpcpu->state = PCPU_STATE_RUNNING;\n\t\t\t}\n\t\t\tlocal_irq_enable();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "kernel/core/init.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/init.h>\n#include <minos/types.h>\n#include <minos/print.h>\n#include <minos/arch.h>\n#include <minos/platform.h>\n#include <minos/string.h>\n#include <minos/calltrace.h>\n\nextern unsigned char __init_func_0_start;\nextern unsigned char __init_func_1_start;\nextern unsigned char __init_func_2_start;\nextern unsigned char __init_func_3_start;\nextern unsigned char __init_func_4_start;\nextern unsigned char __init_func_5_start;\nextern unsigned char __init_func_6_start;\nextern unsigned char __init_func_7_start;\nextern unsigned char __init_func_8_start;\nextern unsigned char __init_func_9_start;\nextern unsigned char __init_func_end;\nextern void log_init(void);\n\nstatic void call_init_func(unsigned long fn_start, unsigned long fn_end)\n{\n\tinit_call *fn;\n\tint size, i;\n\n\tsize = (fn_end - fn_start) / sizeof(init_call);\n\tpr_debug(\"call init func : 0x%x 0x%x %d\\n\", fn_start, fn_end, size);\n\n\tif (size <= 0)\n\t\treturn;\n\n\tfn = (init_call *)fn_start;\n\tfor (i = 0; i < size; i++) {\n\t\t(*fn)();\n\t\tfn++;\n\t}\n}\n\nvoid early_init(void)\n{\n\t/* get the platform for the minos */\n\tarch_early_init();\n\n\tcall_init_func((unsigned long)&__init_func_0_start,\n\t\t\t(unsigned long)&__init_func_1_start);\n}\n\nvoid arch_init(void)\n{\n\t__arch_init();\n\n\tcall_init_func((unsigned long)&__init_func_1_start,\n\t\t\t(unsigned long)&__init_func_2_start);\n}\n\nvoid subsys_init(void)\n{\n\tcall_init_func((unsigned long)&__init_func_2_start,\n\t\t\t(unsigned long)&__init_func_3_start);\n}\n\nvoid module_init(void)\n{\n\tcall_init_func((unsigned long)&__init_func_3_start,\n\t\t\t(unsigned long)&__init_func_4_start);\n}\n\nvoid device_init(void)\n{\n\tcall_init_func((unsigned long)&__init_func_4_start,\n\t\t\t(unsigned long)&__init_func_5_start);\n}\n\nvoid early_init_percpu(void)\n{\n\tcall_init_func((unsigned long)&__init_func_5_start,\n\t\t\t(unsigned long)&__init_func_6_start);\n}\n\nvoid arch_init_percpu(void)\n{\n\tcall_init_func((unsigned long)&__init_func_6_start,\n\t\t\t(unsigned long)&__init_func_7_start);\n}\n\nvoid subsys_init_percpu(void)\n{\n\tcall_init_func((unsigned long)&__init_func_7_start,\n\t\t\t(unsigned long)&__init_func_8_start);\n}\n\nvoid module_init_percpu(void)\n{\n\tcall_init_func((unsigned long)&__init_func_8_start,\n\t\t\t(unsigned long)&__init_func_9_start);\n}\n\nvoid device_init_percpu(void)\n{\n\tcall_init_func((unsigned long)&__init_func_9_start,\n\t\t\t(unsigned long)&__init_func_end);\n}\n"
  },
  {
    "path": "kernel/core/iomem.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/of.h>\n#include <minos/mm.h>\n\nstruct io_block {\n\tvoid *iobase;\n\tint free;\n\tstruct io_block *next;\n\tunsigned long bitmap[BITS_TO_LONGS(PAGES_PER_BLOCK)];\n};\n\nstatic struct io_block *io_block_head;\nstatic DEFINE_SPIN_LOCK(iob_lock);\n\nstatic void *get_io_pages_from_block(struct io_block *iob, int pages)\n{\n\tint start;\n\n\tstart = bitmap_find_next_zero_area(iob->bitmap,\n\t\t\tPAGES_PER_BLOCK, 0, pages, 0);\n\tif (start >= PAGES_PER_BLOCK)\n\t\treturn NULL;\n\n\tbitmap_set(iob->bitmap, start, pages);\n\n\treturn (iob->iobase + (start << PAGE_SHIFT));\n}\n\nstatic void *alloc_new_io_block(int pages)\n{\n\tvoid *base;\n\tstruct io_block *iob;\n\n\tbase = get_free_block(GFP_HUGE_IO);\n\tif (!base)\n\t\treturn NULL;\n\n\tiob = malloc(sizeof(struct io_block));\n\tif (!iob) {\n\t\tfree(base);\n\t\treturn NULL;\n\t}\n\n\tmemset(iob, 0, sizeof(struct io_block));\n\tiob->iobase = base;\n\tiob->free = PAGES_PER_BLOCK;\n\n\tbase = get_io_pages_from_block(iob, pages);\n\tASSERT(base != NULL);\n\n\t/*\n\t * add new io block to the global list.\n\t */\n\tiob->next = io_block_head;\n\tio_block_head = iob;\n\n\treturn base;\n}\n\nvoid *get_io_pages(int pages)\n{\n\tstruct io_block *bhead = io_block_head;\n\tvoid *base = NULL;\n\n\tif ((pages == 0) || (pages > PAGES_PER_BLOCK)) {\n\t\tpr_err(\"io pages can not beyond %d\\n\", PAGES_PER_BLOCK);\n\t\treturn NULL;\n\t}\n\n\tspin_lock(&iob_lock);\n\n\twhile (bhead) {\n\t\tif (bhead->free < pages)\n\t\t\tcontinue;\n\t\t\n\t\tbase = get_io_pages_from_block(bhead, pages);\n\t\tif (base)\n\t\t\tbreak;\n\t}\n\n\tif (!base)\n\t\tbase = alloc_new_io_block(pages);\n\n\tspin_unlock(&iob_lock);\n\n\treturn base;\n}\n\nvoid free_io_pages(void *addr)\n{\n\n}\n"
  },
  {
    "path": "kernel/core/irq.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/irq.h>\n#include <minos/mm.h>\n#include <config/config.h>\n#include <minos/device_id.h>\n#include <minos/sched.h>\n#include <minos/of.h>\n#include <minos/current.h>\n\nunsigned long cpu_irq_stack[NR_CPUS];\n\nstatic struct irq_chip *irq_chip;\n\nstatic int default_irq_handler(uint32_t irq, void *data);\n\nstatic struct irq_desc percpu_irq_descs[PERCPU_IRQ_DESC_SIZE] = {\n\t[0 ... (PERCPU_IRQ_DESC_SIZE - 1)] = {\n\t\tdefault_irq_handler,\n\t},\n};\n\nstatic struct irq_desc spi_irq_descs[SPI_IRQ_DESC_SIZE] = {\n\t[0 ... (SPI_IRQ_DESC_SIZE - 1)] = {\n\t\tdefault_irq_handler,\n\t},\n};\n\nvoid send_sgi(uint32_t sgi, int cpu)\n{\n\tcpumask_t mask;\n\n\tif ((cpu < 0) || (cpu >= CONFIG_NR_CPUS))\n\t\treturn;\n\n\tif (sgi >= 16)\n\t\treturn;\n\n\tcpumask_clearall(&mask);\n\tcpumask_set_cpu(cpu, &mask);\n\n\tirq_chip->send_sgi(sgi, SGI_TO_LIST, &mask);\n}\n\nstatic int default_irq_handler(uint32_t irq, void *data)\n{\n\tpr_warn(\"irq %d is not register\\n\", irq);\n\treturn 0;\n}\n\nstatic int do_handle_host_irq(int cpuid, struct irq_desc *irq_desc)\n{\n\tint ret;\n\n\tif (cpuid != irq_desc->affinity) {\n\t\tpr_notice(\"irq %d do not belong to this cpu\\n\", irq_desc->hno);\n\t\tret =  -EINVAL;\n\t\tgoto out;\n\t}\n\n\tret = irq_desc->handler(irq_desc->hno, irq_desc->pdata);\n\tirq_chip->irq_eoi(irq_desc->hno);\nout:\n\t/*\n\t * 1: if the hw irq is to vcpu do not DIR it.\n\t * 2: if the hw irq is to vcpu but failed to send then DIR it.\n\t * 3: if the hw irq is to userspace process, do not DIR it.\n\t */\n\tif (ret || !(irq_desc->flags & IRQ_FLAGS_VCPU))\n\t\tirq_chip->irq_dir(irq_desc->hno);\n\n\treturn ret;\n}\n\nstatic inline struct irq_desc *get_irq_desc_cpu(int cpuid, uint32_t irq)\n{\n\tif (irq >= MAX_IRQ_COUNT)\n\t\treturn NULL;\n\n\tif (irq < SPI_IRQ_BASE)\n\t\treturn &percpu_irq_descs[cpuid * NR_PERCPU_IRQS + irq];\n\n\treturn &spi_irq_descs[irq - SPI_IRQ_BASE];\n}\n\n/*\n * notice, when used this function to get the percpu\n * irqs need to lock the kernel to invoid the thread\n * sched out from this cpu and running on another cpu\n *\n * so usually, percpu irq will handle in kernel contex\n * and not in task context\n */\nstruct irq_desc *get_irq_desc(uint32_t irq)\n{\n\treturn get_irq_desc_cpu(smp_processor_id(), irq);\n}\n\nvoid __irq_enable(uint32_t irq, int enable)\n{\n\tstruct irq_desc *irq_desc;\n\tunsigned long flags;\n\n\tirq_desc = get_irq_desc(irq);\n\tif (!irq_desc)\n\t\treturn;\n\n\t/*\n\t * some irq controller will directly call its\n\t * own function to enable or disable the hw irq\n\t * which do not set the bit, so here force to excute\n\t * the action\n\t */\n\tspin_lock_irqsave(&irq_desc->lock, flags);\n\tif (enable) {\n\t\tirq_chip->irq_unmask(irq);\n\t\tirq_desc->flags &= ~IRQ_FLAGS_MASKED;\n\t } else {\n\t\tirq_chip->irq_mask(irq);\n\t\tirq_desc->flags |= IRQ_FLAGS_MASKED;\n\t }\n\tspin_unlock_irqrestore(&irq_desc->lock, flags);\n}\n\nvoid irq_dir(uint32_t irq)\n{\n\tirq_chip->irq_dir(irq);\n}\n\nvoid irq_clear_pending(uint32_t irq)\n{\n\tif (irq_chip->irq_clear_pending)\n\t\tirq_chip->irq_clear_pending(irq);\n}\n\nvoid irq_set_affinity(uint32_t irq, int cpu)\n{\n\tstruct irq_desc *irq_desc;\n\n\tif (cpu >= NR_CPUS)\n\t\treturn;\n\n\t/* update the hw irq affinity */\n\tirq_desc = get_irq_desc(irq);\n\tif (!irq_desc)\n\t\treturn;\n\n\tspin_lock(&irq_desc->lock);\n\tirq_desc->affinity = cpu;\n\n\tif (irq_chip->irq_set_affinity)\n\t\tirq_chip->irq_set_affinity(irq, cpu);\n\n\tspin_unlock(&irq_desc->lock);\n}\n\nvoid irq_set_type(uint32_t irq, int type)\n{\n\tstruct irq_desc *irq_desc;\n\n\tirq_desc = get_irq_desc(irq);\n\tif (!irq_desc)\n\t\treturn;\n\n\tspin_lock(&irq_desc->lock);\n\n\tif (type == (irq_desc->flags & IRQ_FLAGS_TYPE_MASK))\n\t\tgoto out;\n\n\tif (irq_chip->irq_set_type)\n\t\tirq_chip->irq_set_type(irq, type);\n\n\tirq_desc->flags &= ~IRQ_FLAGS_TYPE_MASK;\n\tirq_desc->flags |= type;\n\nout:\n\tspin_unlock(&irq_desc->lock);\n}\n\nint do_irq_handler(void)\n{\n\tuint32_t irq;\n\tstruct irq_desc *irq_desc;\n\tint cpuid = smp_processor_id();\n\n\twhile (1) {\n\t\tirq = irq_chip->get_pending_irq();\n\t\tif (irq >= BAD_IRQ)\n\t\t\treturn 0;\n\n\t\tirq_desc = get_irq_desc_cpu(cpuid, irq);\n\t\tif (unlikely(!irq_desc)) {\n\t\t\tpr_err(\"irq is not actived %d\\n\", irq);\n\t\t\tirq_chip->irq_eoi(irq);\n\t\t\tirq_chip->irq_dir(irq);\n\t\t\tcontinue;\n\t\t}\n\n\t\tdo_handle_host_irq(cpuid, irq_desc);\n\t}\n\n\treturn 0;\n}\n\nint irq_xlate(struct device_node *node, uint32_t *intspec,\n\t\tunsigned int intsize, uint32_t *hwirq, unsigned long *f)\n{\n\tif (irq_chip && irq_chip->irq_xlate)\n\t\treturn irq_chip->irq_xlate(node, intspec, intsize, hwirq, f);\n\telse\n\t\tpr_warn(\"WARN - no xlate function for the irqchip\\n\");\n\n\treturn -ENOENT;\n}\n\nint request_irq_percpu(uint32_t irq, irq_handle_t handler,\n\t\tunsigned long flags, char *name, void *data)\n{\n\tint i;\n\tstruct irq_desc *irq_desc;\n\tunsigned long flag;\n\n\tunused(name);\n\n\tif ((irq >= NR_PERCPU_IRQS) || !handler)\n\t\treturn -EINVAL;\n\n\tfor (i = 0; i < NR_CPUS; i++) {\n\t\tirq_desc = get_irq_desc_cpu(i, irq);\n\t\tif (!irq_desc)\n\t\t\tcontinue;\n\n\t\tspin_lock_irqsave(&irq_desc->lock, flag);\n\t\tirq_desc->handler = handler;\n\t\tirq_desc->pdata = data;\n\t\tirq_desc->flags |= flags;\n\t\tirq_desc->affinity = i;\n\t\tirq_desc->hno = irq;\n\n\t\t/* enable the irq here */\n\t\tirq_chip->irq_unmask_cpu(irq, i);\n\t\tirq_desc->flags &= ~IRQ_FLAGS_MASKED;\n\n\t\tspin_unlock_irqrestore(&irq_desc->lock, flag);\n\t}\n\n\treturn 0;\n}\n\nint request_irq(uint32_t irq, irq_handle_t handler,\n\t\tunsigned long flags, char *name, void *data)\n{\n\tint type;\n\tstruct irq_desc *irq_desc;\n\tunsigned long flag;\n\n\tunused(name);\n\n\tif (!handler)\n\t\treturn -EINVAL;\n\n\tirq_desc = get_irq_desc(irq);\n\tif (!irq_desc)\n\t\treturn -ENOENT;\n\n\ttype = flags & IRQ_FLAGS_TYPE_MASK;\n\tflags &= ~IRQ_FLAGS_TYPE_MASK;\n\n\tspin_lock_irqsave(&irq_desc->lock, flag);\n\tirq_desc->handler = handler;\n\tirq_desc->pdata = data;\n\tirq_desc->flags |= flags;\n\tirq_desc->hno = irq;\n\n\t/* enable the hw irq and set the mask bit */\n\tirq_chip->irq_unmask(irq);\n\tirq_desc->flags &= ~IRQ_FLAGS_MASKED;\n\n\tif (irq < SPI_IRQ_BASE)\n\t\tirq_desc->affinity = smp_processor_id();\n\n\tspin_unlock_irqrestore(&irq_desc->lock, flag);\n\n\tif (type)\n\t\tirq_set_type(irq, type);\n\n\treturn 0;\n}\n\nstatic void *irqchip_init(struct device_node *node, void *arg)\n{\n\textern unsigned char __irqchip_start;\n\textern unsigned char __irqchip_end;\n\tvoid *s, *e;\n\tstruct irq_chip *chip;\n\n\tif (node->class != DT_CLASS_IRQCHIP)\n\t\treturn NULL;\n\n\ts = (void *)&__irqchip_start;\n\te = (void *)&__irqchip_end;\n\n\tchip = (struct irq_chip *)of_device_node_match(node, s, e);\n\tif (!chip)\n\t\treturn NULL;\n\n\tirq_chip = chip;\n\tif (chip->init)\n\t\tchip->init(node);\n\n\treturn node;\n}\n\nint irq_init(void)\n{\n#ifdef CONFIG_DEVICE_TREE\n\tof_iterate_all_node(of_root_node, irqchip_init, NULL);\n#endif\n\n\tif (!irq_chip)\n\t\tpanic(\"can not find the irqchip for system\\n\");\n\n\t/*\n\t * now init the irqchip, and in the irq chip\n\t * the chip driver need to alloc the irq it\n\t * need used in the ssystem\n\t */\n\tif (!irq_chip->get_pending_irq)\n\t\tpanic(\"No function to get irq nr\\n\");\n\n\treturn 0;\n}\n\nint irq_secondary_init(void)\n{\n\tif (irq_chip)\n\t\tirq_chip->secondary_init();\n\n\treturn 0;\n}\n"
  },
  {
    "path": "kernel/core/kmem.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/slab.h>\n#include <minos/memory.h>\n#include <minos/of.h>\n\nstruct kmem_section {\n\tvoid *pbase;\n\tvoid *vbase;\n\tsize_t size;\n\n\tvoid *free_base;\n\tvoid *free_page_base;\n\tsize_t free_size;\n};\n\nextern void add_kernel_page_section(phy_addr_t base,\n\t\tsize_t size, int type);\n\nstatic struct kmem_section kmem_section;\nstatic struct kmem_section *ks;\n\nstatic inline void *alloc_kpages_from_section(int pages)\n{\n\tsize_t request_size = pages << PAGE_SHIFT;\n\tvoid *base = NULL;\n\n\tks->free_page_base -= request_size;\n\tbase = ks->free_page_base;\n\tks->free_size -= request_size;\n\n\treturn base;\n}\n\nvoid *alloc_kpages(int pages)\n{\n\tASSERT(pages >= 0);\n\treturn alloc_kpages_from_section(pages);\n}\n\nstatic inline void *alloc_kmem_from_section(size_t size)\n{\n\tvoid *base = base;\n\n\tASSERT(ks->free_size >= size);\n\tbase = ks->free_base;\n\tks->free_base += size;\n\tks->free_size -= size;\n\n\treturn base;\n}\n\n/*\n * kmem will not be freed once it has been allocated\n * kmem also can alloc small slab and one page, and\n * kmem will only used at the boot stage when the irq\n * and scheduler is disabled so there is no spin lock needed\n * when alloc kmem\n */\nvoid *alloc_kmem(size_t size)\n{\n\tsize_t request_size = BALIGN(size, sizeof(unsigned long));\n\n\treturn alloc_kmem_from_section(request_size);\n}\n\nvoid *zalloc_kmem(size_t size)\n{\n\tvoid *base;\n\n\tASSERT(size != 0);\n\tsize = BALIGN(size, sizeof(unsigned long));\n\n\tbase = alloc_kmem(size);\n\tif (base)\n\t\tmemset(base, 0, size);\n\n\treturn base;\n}\n\nvoid add_kmem_section(struct memory_region *region)\n{\n\tif (ks != NULL) {\n\t\tpr_err(\"mutiple kernel memory section ?\\n\");\n\t\treturn;\n\t}\n\n\t/*\n\t * set the kernel memory section pointer.\n\t */\n\tks = &kmem_section;\n\tks->pbase = (void *)region->phy_base;\n\tks->vbase = (void *)ptov(ks->pbase);\n\tks->size = region->size;\n\tks->free_page_base = ks->vbase + ks->size;\n\n\tif (region->phy_base == minos_start) {\n\t\tks->free_base = (void *)ptov(minos_end);\n\t\tks->free_size = ks->size - (minos_end - minos_start);\n\t} else {\n\t\tks->free_base = ks->vbase;\n\t\tks->free_size = ks->size;\n\t}\n\n\tif (ks->free_page_base == ks->free_base) {\n\t\tpr_warn(\"skip wrong kmem section [0x%x 0x%x]\\n\",\n\t\t\t\tks->pbase, ks->pbase + ks->size);\n\t\treturn;\n\t}\n\n\tASSERT(ks->free_page_base > ks->free_base);\n\tpr_notice(\"kmem [0x%x 0x%x]\\n\", ks->free_base,\n\t\t\tks->free_base + ks->free_size);\n}\n\nvoid kmem_init(void)\n{\n\tunsigned long base, size;\n\n\tbase = PAGE_BALIGN(ks->free_base);\n\tsize = (unsigned long)ks->free_page_base - base;\n\n\tadd_kernel_page_section(vtop(base), size, 0);\n}\n"
  },
  {
    "path": "kernel/core/mbox.c",
    "content": "/*\n * Copyright (C) 2019 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/event.h>\n#include <minos/sched.h>\n#include <minos/mbox.h>\n#include <minos/task.h>\n\nvoid *mbox_accept(mbox_t *m)\n{\n\tunsigned long flags;\n\tvoid *msg = NULL;\n\n\tspin_lock_irqsave(&m->lock, flags);\n\tmsg = m->data;\n\tspin_unlock_irqrestore(&m->lock, flags);\n\n\treturn msg;\n}\n\nint mbox_is_pending(mbox_t *m)\n{\n\treturn m->data ? 1 : 0;\n}\n\nvoid *mbox_pend(mbox_t *m, uint32_t timeout)\n{\n\tvoid *pmsg;\n\tunsigned long flags;\n\n\tmight_sleep();\n\n\tspin_lock_irqsave(&m->lock, flags);\n\n\tif (m->data != NULL) {\n\t\tpmsg = m->data;\n\t\tm->data = NULL;\n\t\tspin_unlock_irqrestore(&m->lock, flags);\n\t\treturn pmsg;\n\t}\n\n\t/* no mbox message need to suspend the task */\n\t__wait_event(TO_EVENT(m), OS_EVENT_TYPE_MBOX, timeout);\n\tspin_unlock_irqrestore(&m->lock, flags);\n\n\treturn (void *)do_wait_event(TO_EVENT(m));\n}\n\nstatic int __mbox_post_opt(mbox_t *m, void *pmsg, int pend_state, int opt)\n{\n\tunsigned long flags;\n\tint ret = 0;\n\n\tif (!pmsg)\n\t\treturn -EINVAL;\n\n\t/* \n\t * check whether the mbox need to broadcast to\n\t * all the waitting task\n\t */\n\tspin_lock_irqsave(&m->lock, flags);\n\tret = wake_up_event_waiter(TO_EVENT(m), (long)pmsg, pend_state, opt);\n\tif (!ret) {\n\t\tif (m->data != NULL)\n\t\t\tret = -ENOSPC;\n\t\telse\n\t\t\tm->data = pmsg;\n\t}\n\tspin_unlock_irqrestore(&m->lock, flags);\n\n\tif (ret)\n\t\tcond_resched();\n\n\treturn ret;\n}\n\nint mobox_post_abort(mbox_t *m)\n{\n\treturn __mbox_post_opt(m, NULL, TASK_STATE_PEND_ABORT,\n\t\t\tOS_EVENT_OPT_BROADCAST);\n}\n\nint mbox_post(mbox_t *m, void *pmsg)\n{\n\treturn __mbox_post_opt(m, pmsg, TASK_STATE_PEND_OK,\n\t\t\tOS_EVENT_OPT_NONE);\n}\n"
  },
  {
    "path": "kernel/core/mem.c",
    "content": "/*\n * Copyright (C) 2019 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/of.h>\n#include <minos/mm.h>\n#include <minos/memory.h>\n\n#define MAX_MEMORY_REGION 16\n\nstatic struct memory_region memory_regions[MAX_MEMORY_REGION];\nstatic int current_region_id;\nLIST_HEAD(mem_list);\n\nstruct memory_region *alloc_memory_region(void)\n{\n\tASSERT(current_region_id < MAX_MEMORY_REGION);\n\treturn &memory_regions[current_region_id++];\n}\n\nint add_memory_region(uint64_t base, uint64_t size, int type, int vmid)\n{\n\tphy_addr_t end = base + size - 1;\n\tphy_addr_t r_base, r_end;\n\tstruct memory_region *region;\n\n\tif ((size == 0) || (type >= MEMORY_REGION_TYPE_MAX))\n\t\treturn -EINVAL;\n\n\t/*\n\t * need to check whether this region is confilct with\n\t * other region\n\t */\n\tlist_for_each_entry(region, &mem_list, list) {\n\t\tr_base = region->phy_base;\n\t\tr_end = r_base + region->size - 1;\n\n\t\tif (!((base > r_end) || (end < r_base))) {\n\t\t\tpr_err(\"memory region invalid [0x%lx 0x%lx]\\n\", base, end);\n\t\t\treturn -EINVAL;\n\t\t}\n\t}\n\n\tregion = alloc_memory_region();\n\tregion->phy_base = base;\n\tregion->size = size;\n\tregion->type = type;\n\tregion->vmid = vmid;\n\n\tlist_add_tail(&mem_list, &region->list);\n\tpr_info(\"ADD   MEM: 0x%p [0x%p] 0x%x\\n\", region->phy_base,\n\t\t\tregion->size, region->type);\n\n\treturn 0;\n}\n\nint split_memory_region(uint64_t base, size_t size, int type, int vmid)\n{\n\tphy_addr_t start, end;\n\tphy_addr_t new_end = base + size;\n\tstruct memory_region *region, *n, *tmp;\n\n\tif ((size == 0) || (type >= MEMORY_REGION_TYPE_MAX))\n\t\treturn -EINVAL;\n\n\tpr_info(\"SPLIT MEM: 0x%p [0x%p] 0x%x\\n\", base, size, type);\n\n\t/*\n\t * delete the memory for host, these region\n\t * usually for vms\n\t */\n\tlist_for_each_entry_safe(region, n, &mem_list, list) {\n\t\tstart = region->phy_base;\n\t\tend = start + region->size;\n\n\t\tif ((base > end) || (base < start) || (new_end > end))\n\t\t\tcontinue;\n\n\t\t/* just delete this region from the list */\n\t\tif ((base == start) && (new_end == end)) {\n\t\t\tregion->type = type;\n\t\t\treturn 0;\n\t\t} else if ((base == start) && (new_end < end)) {\n\t\t\tregion->phy_base = new_end;\n\t\t\tregion->size -= size;\n\t\t} else if ((base > start) && (new_end < end)) {\n\t\t\t/* create a new region for the tail space */\n\t\t\tn = alloc_memory_region();\n\t\t\tn->phy_base = new_end;\n\t\t\tn->size = end - new_end;\n\t\t\tn->type = region->type;\n\t\t\tn->vmid = region->vmid;\n\t\t\tlist_add_tail(&mem_list, &n->list);\n\n\t\t\tregion->size = base - start;\n\t\t} else if ((base > start) && (end == new_end)) {\n\t\t\tregion->size = region->size - size;\n\t\t} else {\n\t\t\tpr_warn(\"incorrect memory region 0x%x 0x%x\\n\",\n\t\t\t\t\tbase, size);\n\t\t\treturn -EINVAL;\n\t\t}\n\n\t\t/* alloc a new memory region for vm memory */\n\t\ttmp = alloc_memory_region();\n\t\ttmp->phy_base = base;\n\t\ttmp->size = size;\n\t\ttmp->type = type;\n\t\ttmp->vmid = vmid;\n\t\tlist_add_tail(&mem_list, &tmp->list);\n\n\t\treturn 0;\n\t}\n\n\tpanic(\"Found Invalid memory config 0x%p [0x%p]\\n\", base, size);\n\n\treturn 0;\n}\n\nvoid dump_memory_info(void)\n{\n\tstruct memory_region *region;\n\tchar vm[8];\n\n\tchar *mem_attr[MEMORY_REGION_TYPE_MAX] = {\n\t\t\"Normal\",\n\t\t\"RSV\",\n\t\t\"VM\",\n\t\t\"DTB\",\n\t\t\"Kernel\",\n\t\t\"RamDisk\",\n\t};\n\n\tlist_for_each_entry(region, &mem_list, list) {\n\t\tsprintf(vm, \"VM%d\", region->vmid);\n\t\tpr_notice(\"MEM: 0x%p -> 0x%p [0x%p] %s/%s\\n\", region->phy_base,\n\t\t\t\tregion->phy_base + region->size,\n\t\t\t\tregion->size, mem_attr[region->type],\n\t\t\t\tregion->vmid == 0 ? \"Host\" : vm);\n\t}\n}\n\nstatic void handle_normal_memory_region(struct memory_region *region)\n{\n\tint ret;\n\n\t/*\n\t * only add the normal memory for user, other memory will used as\n\t * other purpose. kernel memeory will use alloc_kernel_mem(), once\n\t * the kernel memory is allocated, it will never freed.\n\t */\n\tret = add_page_section(region->phy_base, region->size, region->type);\n\tASSERT(ret == 0)\n}\n\nstatic void map_all_memory(void)\n{\n\tstruct memory_region *re;\n\tint ret;\n\n\tpr_notice(\"map all memory to host space\\n\");\n\n\tfor_each_memory_region(re) {\n\t\tif (re->type != MEMORY_REGION_TYPE_NORMAL)\n\t\t\tcontinue;\n\t\n\t\tret = create_host_mapping(ptov(re->phy_base),\n\t\t\t\tre->phy_base, re->size,\n\t\t\t\tVM_RW | VM_NORMAL | VM_HUGE);\n\t\tif (ret)\n\t\t\tpr_err(\"map memory region [0x%lx +0x%lx] failed\\n\",\n\t\t\t\t\tre->phy_base, re->size);\n\t}\n}\n\nstatic void prepare_memory_region(struct memory_region *re)\n{\n\tsize_t left_size, right_size;\n\tunsigned long start, end, tmp;\n\n\ttmp = PAGE_ALIGN(re->phy_base + re->size);\n\tre->phy_base = PAGE_BALIGN(re->phy_base);\n\tre->size = tmp - re->phy_base;\n\tif (re->size == 0)\n\t\treturn;\n\n\tif (IS_BLOCK_ALIGN(re->phy_base) && IS_BLOCK_ALIGN(re->size))\n\t\treturn;\n\n\tstart = re->phy_base;\n\tend = re->phy_base + re->size;\n\n\ttmp = BLOCK_ALIGN(end);\n\tre->phy_base = BLOCK_BALIGN(re->phy_base);\n\tre->size = tmp - re->phy_base;\n\n\tleft_size = re->phy_base - start;\n\tright_size = end - (re->phy_base + re->size);\n\n\t/*\n\t * add these memory to the kernel.\n\t */\n\tif (left_size)\n\t\tadd_memory_region(start, left_size, MEMORY_REGION_TYPE_NORMAL, 0);\n\tif (right_size)\n\t\tadd_memory_region(re->phy_base + re->size,\n\t\t\t\tright_size, MEMORY_REGION_TYPE_NORMAL, 0);\n}\n\nstatic inline int in_os_memory_range(unsigned long addr, size_t size)\n{\n\treturn IN_RANGE_UNSIGNED(addr, size, minos_start, CONFIG_MINOS_RAM_SIZE);\n}\n\nvoid mm_init(void)\n{\n\textern void set_ramdisk_address(void *start, void *end);\n\textern void slab_init(void);\n\textern void kmem_init(void);\n\textern int kernel_vspace_init(void);\n\n\tstruct memory_region *re, *tmp;\n\tstruct memory_region *kre = NULL;\n\tsize_t kmem_size;\n\n\tkernel_vspace_init();\n\n#ifdef CONFIG_DEVICE_TREE\n\tof_parse_memory_info();\n#endif\n\n\t/*\n\t * if there is no memory information founded then panic\n\t * the system.\n\t */\n\tBUG_ON(is_list_empty(&mem_list), \"no memory information found\\n\");\n\n\tminos_end = PAGE_BALIGN(minos_end);\n\tkmem_size = CONFIG_MINOS_RAM_SIZE - (minos_end - minos_start);\n\tif (kmem_size <= 0)\n\t\tpanic(\"kmem: memory layout is wrong after boot\\n\");\n\n\t/*\n\t * first handle the kernel memory region, so later, the mapping\n\t * function can be used.\n\t */\n\tfor_each_memory_region(re) {\n\t\tif (re->type != MEMORY_REGION_TYPE_KERNEL)\n\t\t\tcontinue;\n\n\t\tkre = re;\n\t\tif (in_os_memory_range(re->phy_base, re->size))\n\t\t\tadd_kmem_section(re);\n\t\telse\n\t\t\tpanic(\"Wrong kernel memory section [0x%x 0x%x]\\n\",\n\t\t\t\t\tre->phy_base, re->phy_base + re->size);\n\t\tbreak;\n\t}\n\tBUG_ON(kre == NULL, \"Wrong memory configuration\\n\")\n\n\t/*\n\t * for the normal and dma memory, need to make sure it is BLOCK align\n\t * since the page allocater will based BLOCK memory.\n\t */\n\tlist_for_each_entry_safe(re, tmp, &mem_list, list) {\n\t\tif (re->type == MEMORY_REGION_TYPE_NORMAL)\n\t\t\tprepare_memory_region(re);\n\t}\n\n\t/*\n\t * delete the memory region which the size is 0.\n\t */\n\tlist_for_each_entry_safe(re, tmp, &mem_list, list) {\n\t\tif (re->size == 0)\n\t\t\tlist_del(&re->list);\n\t}\n\n\tfor_each_memory_region(re) {\n\t\tif (re->type == MEMORY_REGION_TYPE_RAMDISK) {\n\t\t\tpr_notice(\"set ramdisk address 0x%lx 0x%lx\\n\",\n\t\t\t\t\tre->phy_base, re->size);\n\t\t\tset_ramdisk_address((void *)re->phy_base,\n\t\t\t\t\t(void *)(re->phy_base + re->size));\n\t\t} else if (re->type == MEMORY_REGION_TYPE_NORMAL) {\n\t\t\thandle_normal_memory_region(re);\n\t\t}\n\t}\n\n\tslab_init();\n\n\tkmem_init();\n\n\tdump_memory_info();\n\n\tmap_all_memory();\n}\n"
  },
  {
    "path": "kernel/core/minos.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/percpu.h>\n#include <minos/irq.h>\n#include <minos/mm.h>\n#include <asm/arch.h>\n#include <minos/pm.h>\n#include <minos/init.h>\n#include <minos/sched.h>\n#include <minos/smp.h>\n#include <minos/atomic.h>\n#include <minos/softirq.h>\n#include <minos/platform.h>\n#include <config/version.h>\n#include <minos/of.h>\n#include <minos/ramdisk.h>\n\nextern void cpu_idle(void);\nextern void mm_init(void);\nextern int allsymbols_init(void);\nextern void platform_init(void);\nextern int create_idle_task(void);\n\n#ifdef CONFIG_VIRT\n#include <virt/virt.h>\n#endif\n\nvoid boot_main(void)\n{\n\tallsymbols_init();\n\tpercpu_init(0);\n\n\tpr_notice(\"Minos %s\\n\", MINOS_VERSION_STR);\n\n\tASSERT(smp_processor_id() == 0);\n\n\tmm_init();\n\n#ifdef CONFIG_DEVICE_TREE\n\tof_init_bootargs();\n#endif\n\n\tearly_init();\n\tearly_init_percpu();\n\n\tarch_init();\n\tarch_init_percpu();\n\n\tplatform_init();\n\tirq_init();\n\n#ifdef CONFIG_SMP\n\tsmp_init();\n#endif\n\tsubsys_init();\n\tsubsys_init_percpu();\n\n\tmodule_init();\n\tmodule_init_percpu();\n\n\tsched_init();\n\tlocal_sched_init();\n\n\tdevice_init();\n\tdevice_init_percpu();\n\n\tcreate_idle_task();\n\n#ifdef CONFIG_SMP\n\tsmp_cpus_up();\n#endif\n\n#ifdef CONFIG_VIRT\n\tvirt_init();\n#endif\n\tramdisk_init();\n\n\tcpu_idle();\n}\n\nvoid boot_secondary(int cpuid)\n{\n\tpr_notice(\"cpu-%d is up\\n\", cpuid);\n\n\t/*\n\t * need wait for all cpus up then excuted below\n\t * task, otherwise the mem content hold by different\n\t * cpu may be different because the cache issue\n\t *\n\t * eg: the cpu1 called create_idle_task and the\n\t * idle task is created sucessfully but at the same\n\t * time the cpu2 is powered off\n\t *\n\t * waitting for all the cpu power on\n\t */\n\twhile (!is_cpus_all_up())\n\t\tmb();\n\n\tearly_init_percpu();\n\n\tarch_init_percpu();\n\n\tirq_secondary_init();\n\n\tsubsys_init_percpu();\n\n\tmodule_init_percpu();\n\n\tlocal_sched_init();\n\n\tdevice_init_percpu();\n\n\tcreate_idle_task();\n\n\tcpu_idle();\n}\n"
  },
  {
    "path": "kernel/core/mutex.c",
    "content": "/*\n * Copyright (C) 2019 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/event.h>\n#include <minos/task.h>\n#include <minos/mutex.h>\n#include <minos/sched.h>\n\nint mutex_accept(mutex_t *mutex)\n{\n\tstruct task *task = current;\n\tint ret = -EBUSY;\n\n\tspin_lock(&mutex->lock);\n\tif (mutex->cnt == OS_MUTEX_AVAILABLE) {\n\t\tmutex->owner = task->tid;\n\t\tmutex->data = task;\n\t\tmutex->cnt = task->tid;\n\t\tret = 0;\n\t}\n\tspin_unlock(&mutex->lock);\n\n\treturn ret;\n}\n\nint mutex_pend(mutex_t *m, uint32_t timeout)\n{\n\tstruct task *task = current;\n\n\tmight_sleep();\n\n\t/*\n\t * mutex_pend and mutex_post can not be used in interrupt\n\t * context.\n\t */\n\tspin_lock(&m->lock);\n\tif (m->cnt == OS_MUTEX_AVAILABLE) {\n\t\tm->owner = task->tid;\n\t\tm->data = (void *)task;\n\t\tm->cnt = task->tid;\n\t\tspin_unlock(&m->lock);\n\t\treturn 0;\n\t}\n\t__wait_event(TO_EVENT(m), OS_EVENT_TYPE_MUTEX, timeout);\n\tspin_unlock(&m->lock);\n\t\n\treturn do_wait_event(TO_EVENT(m));\n}\n\nint mutex_post(mutex_t *m)\n{\n\tstruct task *task;\n\n\tASSERT(m->owner == current->tid);\n\n\t/* \n\t * find the highest prio task to run, if there is\n\t * no task, then set the mutex is available else\n\t * resched\n\t */\n\tspin_lock(&m->lock);\n\ttask = wake_up_one_event_waiter(TO_EVENT(m), 0, TASK_STATE_PEND_OK);\n\tif (task == NULL) {\n\t\tm->cnt = OS_MUTEX_AVAILABLE;\n\t\tm->data = NULL;\n\t\tm->owner = 0;\n\t} else {\n\t\tm->owner = task->tid;\n\t\tm->data = (void *)task;\n\t\tm->cnt = task->tid;\n\t}\n\tspin_unlock(&m->lock);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "kernel/core/page.c",
    "content": "/*\n * Copyright (C) 2020 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/types.h>\n#include <config/config.h>\n#include <minos/spinlock.h>\n#include <minos/minos.h>\n#include <minos/init.h>\n#include <minos/mm.h>\n#include <minos/page.h>\n#include <minos/slab.h>\n\nextern void *alloc_kmem(size_t size);\nextern void *zalloc_kmem(size_t size);\nextern void *alloc_kpages(int pages);\n\n#define __PAGE_F_KERNL\t\t__GFP_KERNEL\n#define __PAGE_F_USER\t\t__GFP_USER\n#define __PAGE_F_GUEST\t\t__GFP_GUEST\n#define __PAGE_F_DMA\t\t__GFP_DMA\n#define __PAGE_F_SLAB\t\t__GFP_SLAB\n#define __PAGE_F_SHARED\t\t__GFP_SHARED\n#define __PAGE_F_IO\t\t__GFP_IO\n#define __PAGE_F_HUGE\t\t__GFP_HUGE\n\n#define PAGE_F_KERNL\t\tGFP_KERNEL\n#define PAGE_F_USER\t\tGFP_USER\n#define PAGE_F_GUEST\t\tGFP_GUEST\n#define PAGE_F_DMA\t\tGFP_DMA\n#define PAGE_F_SLAB\t\tGFP_SLAB\n#define PAGE_F_SHARED\t\tGFP_SHARED\n#define PAGE_F_SHARED_IO\tGFP_SHARED_IO\n#define PAGE_F_HUGE\t\tGFP_HUGE\n#define PAGE_F_HUGE_IO\t\tGFP_HUGE_IO\n#define PAGE_F_HEAD\t\t0x00000100\n#define PAGE_F_MASK\t\t0x0000ffff\n\n#define MAX_MEM_SECTIONS 32\n\nstruct mem_section {\n\tint block_section;\n\n\tunsigned long phy_base;\n\tunsigned long vir_base;\n\tunsigned long vir_end;\n\tsize_t size;\n\n\tsize_t total_cnt;\n\tsize_t free_cnt;\n\tunsigned long *bitmap;\n\tunsigned long bm_end;\n\tunsigned long bm_current;\n\n\tunsigned long *block_bitmap;\n\tsize_t total_block;\n\tint current_block;\n\tsize_t free_block;\n\n\tspinlock_t lock;\n\n\tstruct page *pages;\n};\n\n#define PAGE_ADDR(base, bit)\t((unsigned long)base + ((unsigned long)bit << PAGE_SHIFT))\n\n/*\n * ID 0 will reserver for kernel memory section.\n */\nstatic struct mem_section mem_sections[MAX_MEM_SECTIONS];\nstatic int nr_sections = 1;\n\nvoid add_kernel_page_section(phy_addr_t base, size_t size, int type)\n{\n\tunsigned long end, new_size;\n\tsize_t page_cnt;\n\tstruct mem_section *ms = &mem_sections[0];\n\n\tmemset(ms, 0, sizeof(struct mem_section));\n\tend = base + size;\n\tpage_cnt = size >> PAGE_SHIFT;\n\n\tms->bitmap = (unsigned long *)ptov(base);\n\tbase += BITMAP_SIZE(page_cnt);\n\tmemset(ms->bitmap, 0, BITMAP_SIZE(page_cnt));\n\n\tms->pages = (struct page *)ptov(base);\n\tbase += page_cnt * sizeof(struct page);\n\tmemset(ms->pages, 0, page_cnt * sizeof(struct page));\n\n\tbase = PAGE_BALIGN(base);\n\tnew_size = end - base;\n\n\tspin_lock_init(&ms->lock);\n\tms->phy_base = base;\n\tms->vir_base = ptov(base);\n\tms->size = new_size;\n\tms->vir_end = ms->vir_base + ms->size;\n\tms->total_cnt = new_size >> PAGE_SHIFT;\n\tms->free_cnt = ms->total_cnt;\n\tms->bm_current = 0;\n\tms->bm_end = ms->total_cnt;\n\n\tpr_notice(\"boot memory section [0x%lx +0x%lx]\\n\", base, new_size);\n}\n\nint add_page_section(phy_addr_t base, size_t size, int type)\n{\n\tstruct mem_section *ms;\n\tint block_align = 1;\n\n\tif ((size == 0) || (nr_sections >= MAX_MEM_SECTIONS)) {\n\t\tpr_err(\"no enough memory section for page section\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\tif (!IS_BLOCK_ALIGN(base) || !IS_BLOCK_ALIGN(size))\n\t\tblock_align = 0;\n\n\tpr_notice(\"umem [0x%x 0x%x] [%s] section\\n\", base, base + size,\n\t\t\tblock_align ? \"Block\" : \"Page\");\n\n\tms = &mem_sections[nr_sections];\n\tmemset(ms, 0, sizeof(struct mem_section));\n\tspin_lock_init(&ms->lock);\n\n\tms->phy_base = base;\n\tms->vir_base = ptov(base);\n\tms->size = size;\n\tms->vir_end = ms->vir_base + ms->size;\n\n\t/*\n\t * init the page informations.\n\t */\n\tms->total_cnt = size >> PAGE_SHIFT;\n\tms->free_cnt = ms->total_cnt;\n\tms->bitmap = alloc_kmem(BITMAP_SIZE(ms->total_cnt));\n\tASSERT(ms->bitmap != NULL);\n\n\tmemset(ms->bitmap, 0, BITMAP_SIZE(ms->total_cnt));\n\tms->bm_current = 0;\n\tms->bm_end = ms->total_cnt;\n\n\t/*\n\t * just allocate the pages struct for this section\n\t * but do not init the memory data to 0, since if the\n\t * memory size is too big will slow down the boot time\n\t */\n\tms->pages = alloc_kmem(ms->total_cnt * sizeof(struct page));\n\tASSERT(ms->pages != NULL);\n\tmemset(ms->pages, 0, ms->total_cnt * sizeof(struct page));\n\n\t/*\n\t * init the block information for this section, so\n\t * can get 2M blocks from this section if needed.\n\t */\n\tif (block_align) {\n\t\tms->block_section = 1;\n\t\tms->total_block = ms->size >> BLOCK_SHIFT;\n\t\tms->free_block = ms->total_block;\n\t\tms->block_bitmap = alloc_kmem(BITMAP_SIZE(ms->total_block));\n\t\tASSERT(ms->block_bitmap != NULL);\n\t\tmemset(ms->block_bitmap, 0, BITMAP_SIZE(ms->total_block));\n\t}\n\n\tnr_sections++;\n\n\treturn 0;\n}\n\nstatic void alloc_pages_in_block(struct page *page, struct mem_section *ms)\n{\n\tunsigned long start = page_pa(page);\n\tunsigned long base = ALIGN(start, BLOCK_SIZE);\n\tunsigned long end = BALIGN(start + page->cnt * PAGE_SIZE, BLOCK_SIZE);\n\tint size = ((end - base) >> PAGE_SHIFT) / PAGES_PER_BLOCK;\n\n\tstart = (base - start) >> BLOCK_SHIFT;\n\tbitmap_set(ms->block_bitmap, start, size);\n}\n\nstatic void free_pages_in_block(struct page *page, struct mem_section *ms)\n{\n\tint count = page_count(page);\n\tunsigned long tmp, start, end;\n\tunsigned long *baddr;\n\tint i, sum, bbit, pbit;\n\t\n\ttmp = page_pa(page);\n\tstart = ALIGN(tmp, BLOCK_SIZE);\n\tend = BALIGN(tmp + count * PAGE_SIZE, BLOCK_SIZE);\n\tbbit = (start - ms->phy_base) >> BLOCK_SHIFT;\n\tpbit = (start - ms->phy_base) >> PAGE_SHIFT;\n\n\t/*\n\t * clear the related bit in the block map if all\n\t * the pages in this block has been freed.\n\t */\n\tfor (i = 0; i < (end - start) >> BLOCK_SHIFT; i++) {\n\t\t/*\n\t\t * get the start page bit postion in page bitmap.\n\t\t * the check whether all the bits are zero.\n\t\t */\n\t\tbaddr = ms->bitmap + BITS_TO_LONGS(pbit);\n\t\tsum = 0;\n\t\tsum += (baddr[0] != 0);\n\t\tsum += (baddr[1] != 0);\n\t\tsum += (baddr[2] != 0);\n\t\tsum += (baddr[3] != 0);\n\t\tsum += (baddr[4] != 0);\n\t\tsum += (baddr[5] != 0);\n\t\tsum += (baddr[6] != 0);\n\t\tsum += (baddr[7] != 0);\n\n\t\tif (sum == 0) {\n\t\t\tclear_bit(bbit, ms->block_bitmap);\n\t\t\tms->free_block++;\n\t\t}\n\n\t\tpbit += PAGES_PER_BLOCK;\n\t\tbbit++;\n\t}\n}\n\nstatic struct mem_section *addr_to_mem_section(unsigned long addr)\n{\n\tstruct mem_section *temp;\n\tint i;\n\n\tfor (i = 0; i < nr_sections; i++) {\n\t\ttemp = &mem_sections[i];\n\t\tif ((addr >= temp->vir_base) && (addr < temp->vir_end))\n\t\t\treturn temp;\n\t}\n\n\treturn NULL;\n}\n\nstatic struct page *__alloc_pages_from_section(struct mem_section *section,\n\t\tint count, int align, int flags)\n{\n\tstruct page *page;\n\tint bit;\n\n\tif (count == 1)\n\t\tbit = find_next_zero_bit_loop(section->bitmap, section->total_cnt,\n\t\t\t\tsection->bm_current);\n\telse\n\t\tbit = bitmap_find_next_zero_area_align(section->bitmap,\n\t\t\t\tsection->total_cnt, 0, count, align);\n\tif (bit >= section->total_cnt)\n\t\treturn NULL;\n\n\tbitmap_set(section->bitmap, bit, count);\n\tif ((1 == count) || (1 == align)) {\n\t\tsection->bm_current = bit + count;\n\t\tASSERT(section->bm_current < section->total_cnt);\n\n\t\tif (section->bm_current == section->total_cnt)\n\t\t\tsection->bm_current = 0;\n\t}\n\n\tpage = section->pages + bit;\n\tpage->cnt = count;\n\tpage->flags = (flags | PAGE_F_HEAD) & 0xffff;\n\tpage->pfn = PAGE_ADDR(section->phy_base, bit) >> PAGE_SHIFT;\n\n\t/*\n\t * update the block bitmap information.\n\t */\n\tsection->free_cnt -= count;\n\tif (section->block_section)\n\t\talloc_pages_in_block(page, section);\n\n\treturn page;\n}\n\nstatic struct page *alloc_pages_from_section(int pages, int align, int flags)\n{\n\tstruct page *page = NULL;\n\tstruct mem_section *section;\n\tint i;\n\n\tflags &= PAGE_F_MASK;\n\n\tfor (i = 0; i < nr_sections; i++) {\n\t\tsection = &mem_sections[i];\n\n\t\tspin_lock(&section->lock);\n\t\tif (section->free_cnt < pages) {\n\t\t\tspin_unlock(&section->lock);\n\t\t\tcontinue;\n\t\t}\n\n\t\tpage = __alloc_pages_from_section(section, pages, align, flags);\n\t\tspin_unlock(&section->lock);\n\n\t\tif (page)\n\t\t\treturn page;\n\t}\n\n\treturn NULL;\n}\n\nstatic void bzero_pages(struct page *page, int pages)\n{\n\tmemset((void *)page_va(page), 0, pages << PAGE_SHIFT);\n}\n\nstruct page *__alloc_pages(int pages, int align, int flags)\n{\n\tstruct page *page;\n\n\tif ((pages <= 0) || (align == 0))\n\t\treturn NULL;\n\n\tpage = alloc_pages_from_section(pages, align, flags);\n\tif (!page) {\n\t\tpr_warn(\"no more pages\\n\");\n\t\treturn NULL;\n\t}\n\n\treturn page;\n}\n\nvoid *__get_free_pages(int pages, int align, int flags)\n{\n\tstruct page *page = NULL;\n\n\tpage = __alloc_pages(pages, align, flags);\n\tif (page) {\n\t\tbzero_pages(page, pages);\n\t\treturn (void *)page_va(page);\n\t}\n\n\treturn NULL;\n}\n\nstatic struct page * get_page_in_section(struct mem_section *section, unsigned long addr)\n{\n\tunsigned long start = (addr - section->vir_base) >> PAGE_SHIFT;\n\n\treturn section->pages + start;\n}\n\nstruct page *addr_to_page(unsigned long addr)\n{\n\tstruct mem_section *section;\n\n\tsection = addr_to_mem_section((unsigned long)addr);\n\tif (!section) {\n\t\tpr_err(\"bad address 0x%lx\\n\", (unsigned long)addr);\n\t\treturn NULL;\n\t}\n\n\treturn get_page_in_section(section, addr);\n}\n\nstatic int free_pages_in_section(struct page *page, struct mem_section *ms)\n{\n\tunsigned long flags = page_flags(page);\n\tunsigned long start, pstart;\n\tint count;\n\n\t/*\n\t * if the page is not the page head or the page is used\n\t * as slab or other, then it means its a slab memory\n\t * or can not release by now\n\t */\n\tASSERT((flags != 0) && (flags & PAGE_F_HEAD) &&\n\t\t\t!(flags & PAGE_F_SLAB));\n\t/*\n\t * clear all the pages in case the memory data leak.\n\t */\n\tcount = page_count(page);\n\tpstart = page_pa(page);\n\tASSERT((pstart != 0) && (count != 0));\n\n\tstart = (pstart - ms->phy_base) >> PAGE_SHIFT;\n\tbitmap_clear(ms->bitmap, start, count);\n\tms->free_cnt += count;\n\n\t/*\n\t * update the block information in this section if\n\t * needed.\n\t */\n\tif (ms->block_section)\n\t\tfree_pages_in_block(page, ms);\n\n\t/*\n\t * clear the page information last.\n\t */\n\tmemset(page, 0, sizeof(struct page));\n\n\treturn 0;\n}\n\nint __free_pages(struct page *page)\n{\n\tstruct mem_section *section;\n\n\tsection = addr_to_mem_section(page_va(page));\n\tif (!section) {\n\t\tpr_err(\"bad address to free 0x%lx\\n\", page_va(page));\n\t\treturn -EFAULT;\n\t}\n\n\tspin_lock(&section->lock);\n\tfree_pages_in_section(page, section);\n\tspin_unlock(&section->lock);\n\n\treturn 0;\n}\n\nint free_pages(void *addr)\n{\n\tstruct mem_section *section;\n\tstruct page *page;\n\n\tASSERT(is_kva(addr));\n\n\tif (!IS_PAGE_ALIGN(addr))\n\t\treturn -EINVAL;\n\n\t/*\n\t * check whether this addr is in page section or\n\t * block section or is just a slab memory\n\t */\n\tsection = addr_to_mem_section((unsigned long)addr);\n\tif (!section) {\n\t\tpr_warn(\"not page address 0x%lx\\n\", (unsigned long)addr);\n\t\treturn -EFAULT;\n\t}\n\n\tspin_lock(&section->lock);\n\n\t/*\n\t * if the page is not the page head or the page is used\n\t * as slab or other, then it means its a slab memory\n\t * or can not release by now\n\t */\n\tpage = get_page_in_section(section, (unsigned long)addr);\n\tif (page_flags(page) & PAGE_F_SLAB) {\n\t\tpr_warn(\"slab memory can not be freed by free_pages()\\n\");\n\t\tspin_unlock(&section->lock);\n\t\treturn -EINVAL;\n\t}\n\n\tfree_pages_in_section(page, section);\n\tspin_unlock(&section->lock);\n\n\treturn 0;\n}\n\nstatic void *get_free_block_from_section(struct mem_section *ms, unsigned long flags)\n{\n\tstruct page *page;\n\tunsigned long start;\n\tunsigned long base;\n\tunsigned long *bitmap_addr;\n\n\tif (ms->free_block == 0)\n\t\treturn NULL;\n\n\tstart = find_next_zero_bit_loop(ms->block_bitmap,\n\t\t\tms->current_block, ms->total_block);\n\tif (start >= ms->total_block)\n\t\treturn NULL;\n\n\t/*\n\t * mask the block bit in block bitmap.\n\t */\n\tset_bit(start, ms->block_bitmap);\n\n\tms->free_block--;\n\tms->current_block = start + 1;\n\tif (ms->current_block == ms->total_block)\n\t\tms->current_block = 0;\n\n\tflags |= PAGE_F_HEAD;\n\tpage = ms->pages + (start * PAGES_PER_BLOCK);\n\tpage->flags = (uint16_t)flags & 0xffff;\n\tpage->cnt = PAGES_PER_BLOCK;\n\tbase = ms->phy_base + (start << BLOCK_SHIFT);\n\tpage->pfn = base >> PAGE_SHIFT;\n\n\t/*\n\t * update page bitmap for this block in page bitmap.\n\t * currently need make sure below limition:\n\t * 1 - 64BIT OS, sizeof(unsigned long) = 8\n\t * 2 - 2M huge page, 512 pages per block\n\t * 3 - need 8 * unsigned long to store bitmap.\n\t */\n\tstart = BITS_TO_LONGS(start * PAGES_PER_BLOCK);\n\tbitmap_addr = ms->bitmap + start;\n\tbitmap_addr[0] = (unsigned long)-1;\n\tbitmap_addr[1] = (unsigned long)-1;\n\tbitmap_addr[2] = (unsigned long)-1;\n\tbitmap_addr[3] = (unsigned long)-1;\n\tbitmap_addr[4] = (unsigned long)-1;\n\tbitmap_addr[5] = (unsigned long)-1;\n\tbitmap_addr[6] = (unsigned long)-1;\n\tbitmap_addr[7] = (unsigned long)-1;\n\n\treturn (void *)base;\n}\n\nvoid *get_free_block(unsigned long flags)\n{\n\tstruct mem_section *ms;\n\tvoid *base = 0;\n\tint i;\n\n\tflags &= PAGE_F_MASK; \n\tflags |= PAGE_F_HUGE;\n\n\tfor (i = 0; i < nr_sections; i++) {\n\t\tms = &mem_sections[i];\n\t\tif (!ms->block_section)\n\t\t\tcontinue;\n\n\t\tspin_lock(&ms->lock);\n\t\tbase = get_free_block_from_section(ms, flags);\n\t\tspin_unlock(&ms->lock);\n\n\t\tif (base)\n\t\t\tbreak;\n\t}\n\n\treturn (void *)ptov(base);\n}\n\nvoid free_block(void *addr)\n{\n\tfree_pages(addr);\n}\n"
  },
  {
    "path": "kernel/core/percpu.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/percpu.h>\n#include <minos/sched.h>\n#include <minos/mm.h>\n\nstruct pcpu pcpus[NR_CPUS];\nunsigned long __cache_line_align percpu_offset[CONFIG_NR_CPUS];\n\n#define PCPU_STAT_OFFLINE\t0\n#define PCPU_STAT_ONLINE\t1\n\nvoid percpu_init(int cpuid)\n{\n\textern unsigned char __percpu_start;\n\textern unsigned char __percpu_section_size;\n\tint i;\n\n\t/*\n\t * the data of percpu section has been zeroed at boot code\n\t * here do not to zero it again.\n\t *\n\t * some member of pcpu has been init on boot stage, like cpuid.\n\t */\n\tfor (i = 0; i < CONFIG_NR_CPUS; i++) {\n\t\tpercpu_offset[i] = (phy_addr_t)(&__percpu_start) +\n\t\t\t(size_t)(&__percpu_section_size) * i;\n\t\tpr_info(\"percpu [%d] offset 0x%x\\n\", i, percpu_offset[i]);\n\t\tget_per_cpu(pcpu, i) = &pcpus[i];\n\t}\n}\n\nstatic int percpu_subsystem_init(void)\n{\n\tstruct pcpu *pcpu = get_pcpu();\n\tint pages = TASK_STACK_SIZE >> PAGE_SHIFT;\n\n\tpcpu->stack = get_free_pages(pages, GFP_KERNEL);\n\tASSERT(pcpu->stack != NULL);\n\tpcpu->stack += 2 * PAGE_SIZE;\n\tpcpu->state = PCPU_STATE_RUNNING;\n\n\treturn 0;\n}\nsubsys_initcall_percpu(percpu_subsystem_init);\n"
  },
  {
    "path": "kernel/core/print.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/types.h>\n#include <minos/varlist.h>\n#include <minos/string.h>\n#include <minos/print.h>\n#include <minos/preempt.h>\n#include <config/config.h>\n#include <minos/console.h>\n#include <minos/smp.h>\n#include <minos/time.h>\n#include <minos/task.h>\n#include <minos/sched.h>\n\n#ifndef CONFIG_LOG_LEVEL\n#define CONFIG_LOG_LEVEL\tPRINT_LEVEL_NOTICE\n#endif\n\nstatic DEFINE_SPIN_LOCK(print_lock);\nstatic unsigned int print_level = CONFIG_LOG_LEVEL;\n\nstatic int get_print_time(char *buffer)\n{\n\tunsigned long us;\n\tunsigned long second;\n\tint len, left;\n\tchar buf[64];\n\n\tus = get_current_time() / 1000;\n\tsecond = us / 1000000;\n\tus = us % 1000000;\n\n\tlen = uitoa(buf, second);\n\tlen = len > 8 ? 8 : len;\n\tleft = 8 - len;\n\n\tif (left > 0) {\n\t\tmemset(buffer, ' ', left);\n\t\tbuffer += left;\n\t}\n\tmemcpy(buffer, buf, len);\n\tbuffer += len;\n\n\t*buffer++ = '.';\n\n\tmemset(buf, '0', 8);\n\tlen = uitoa(buf, us);\n\tlen = len > 6 ? 6 : len;\n\tleft = 6 - len;\n\n\tif (left > 0) {\n\t\tmemset(buffer, '0', left);\n\t\tbuffer += left;\n\t}\n\tmemcpy(buffer, buf, len);\n\n\treturn 15;\n}\n\nvoid change_log_level(unsigned int level)\n{\n\tprint_level = level;\n}\n\nint level_print(int level, char *fmt, ...)\n{\n\tva_list arg;\n\tint printed, i, cpuid;\n\tchar buf[64];\n\tchar *buffer = buf;\n\tunsigned long flags;\n\tint tid = 0;\n\tstruct task *task;\n\n\tif (level > print_level)\n\t\treturn 0;\n\n\tpreempt_disable();\n\n\tcpuid = smp_processor_id();\n\ttask = get_current_task();\n\tif (task)\n\t\ttid = get_task_tid(task);\n\n\t/*\n\t * after to handle the level we change\n\t * the level to the current CPU\n\t */\n\t*buffer++ = '[';\n\n\t/* get the time of the log when it print */\n\tbuffer += get_print_time(buffer);\n\t*buffer++ = '@';\n\n\t/* add the processor id to the buffer */\n\t*buffer++ = (cpuid / 10) + '0';\n\t*buffer++ = (cpuid % 10) + '0';\n\n\t/* add the task tid to the buffer */\n\t*buffer++ = ' ';\n\t*buffer++ = (tid / 100) + '0';\n\t*buffer++ = ((tid % 100) / 10) + '0';\n\t*buffer++ = (tid % 10) + '0';\n\n\t*buffer++ = ']';\n\t*buffer++ = ' ';\n\n\t/*\n\t * printf the header first then process the string\n\t * which wanna to show\n\t */\n\tprinted = buffer - buf;\n\n\tspin_lock_irqsave(&print_lock, flags);\n\n\tfor(i = 0; i < printed; i++)\n\t\tconsole_putc(buf[i]);\n\n\tva_start(arg, fmt);\n\tprinted += vsprintf(NULL, fmt, arg);\n\tva_end(arg);\n\n\tspin_unlock_irqrestore(&print_lock, flags);\n\n\tpreempt_enable();\n\n\treturn printed;\n}\n\nint printf(char *fmt, ...)\n{\n\tva_list arg;\n\tint printed;\n\tunsigned long flags;\n\n\tspin_lock_irqsave(&print_lock, flags);\n\n\tva_start(arg, fmt);\n\tprinted = vsprintf(NULL, fmt, arg);\n\tva_end(arg);\n\n\tspin_unlock_irqrestore(&print_lock, flags);\n\n\treturn printed;\n}\n\n/*\n * TBD\n */\nint puts(char *buf, size_t size)\n{\n\tsize_t print = 0;\n\tunsigned long flags;\n\n\tspin_lock_irqsave(&print_lock, flags);\n\n\twhile (print < size)\n\t\tconsole_putc(buf[print++]);\n\n\tspin_unlock_irqrestore(&print_lock, flags);\n\n\treturn size;\n}\n"
  },
  {
    "path": "kernel/core/queue.c",
    "content": "/*\n * Copyright (C) 2019 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/queue.h>\n#include <minos/task.h>\n#include <minos/sched.h>\n#include <minos/mm.h>\n\nint queue_init(queue_t *qt, int size, char *name)\n{\n\tstruct queue *q;\n\n\tq = zalloc(sizeof(*q));\n\tif (!q)\n\t\treturn -ENOMEM;\n\n\tq->q_start = (void **)zalloc(sizeof(void *) * size);\n\tif (!q->q_start) {\n\t\tfree(q);\n\t\treturn -ENOMEM;\n\t}\n\n\tq->q_end = q->q_start + size;\n\tq->q_in = q->q_start;\n\tq->q_out = q->q_start;\n\tq->q_cnt = 0;\n\tq->q_size = size;\n\n\tevent_init(TO_EVENT(qt), OS_EVENT_TYPE_QUEUE, (void *)q);\n\n\treturn 0;\n}\n\nstatic inline void queue_free(queue_t *qt)\n{\t\n\tstruct queue *q;\n\n\tq = qt->data;\n\tif (q && q->q_start)\n\t\tfree(q->q_start);\n\tif (q)\n\t\tfree(q);\n}\n\nstatic inline void *queue_pop(struct queue *q)\n{\n\tvoid *pmsg;\n\n\tpmsg = *q->q_out++;\n\tq->q_cnt--;\n\tif (q->q_out == q->q_end)\n\t\tq->q_out = q->q_start;\n\n\treturn pmsg;\n}\n\nstatic inline void queue_push(struct queue *q, void *pmsg)\n{\n\t*q->q_in++ = pmsg;\n\tif (q->q_in == q->q_end)\n\t\tq->q_in = q->q_start;\n\tq->q_cnt++;\n}\n\nstatic inline void queue_push_front(struct queue *q, void *pmsg)\n{\n\tif (q->q_out == q->q_start)\n\t\tq->q_out = q->q_end;\n\tq->q_out--;\n\t*q->q_out = pmsg;\n\tq->q_cnt++;\n}\n\nvoid *queue_accept(queue_t *qt)\n{\n\tunsigned long flags;\n\tstruct queue *q;\n\tvoid *pmsg = NULL;\n\n\tspin_lock_irqsave(&qt->lock, flags);\n\n\tq = (struct queue *)qt->data;\n\tif (q->q_cnt > 0)\n\t\tpmsg = queue_pop(q);\n\n\tspin_unlock_irqrestore(&qt->lock, flags);\n\n\treturn pmsg;\n}\n\nint queue_flush(queue_t *qt)\n{\n\tstruct queue *q;\n\tunsigned long flags;\n\n\tspin_lock_irqsave(&qt->lock, flags);\n\tq = (struct queue *)qt->data;\n\tq->q_in = q->q_start;\n\tq->q_out = q->q_start;\n\tq->q_cnt = 0;\n\tspin_unlock_irqrestore(&qt->lock, flags);\n\n\treturn 0;\n}\n\nvoid *queue_pend(queue_t *qt, uint32_t timeout)\n{\n\tvoid *pmsg;\n\tstruct queue *q;\n\tunsigned long flags;\n\n\tmight_sleep();\n\n\tspin_lock_irqsave(&qt->lock, flags);\n\tq = (struct queue *)qt->data;\n\tif (q->q_cnt > 0) {\n\t\tpmsg = queue_pop(q);\n\t\tspin_unlock_irqrestore(&qt->lock, flags);\n\t\treturn pmsg;\n\t}\n\n\t__wait_event(TO_EVENT(qt), OS_EVENT_TYPE_QUEUE, timeout);\n\tspin_unlock_irqrestore(&qt->lock, flags);\n\n\treturn (void *)do_wait_event(TO_EVENT(qt));\n}\n\nstatic int __queue_post(queue_t *qt, void *pmsg, int front)\n{\n\tstruct queue *q;\n\tunsigned long flags;\n\tint ret;\n\n\tspin_lock_irqsave(&qt->lock, flags);\n\tret = wake_up_event_waiter(TO_EVENT(qt), (long)pmsg, TASK_STATE_PEND_OK, 1);\n\tif (ret) {\n\t\tspin_unlock_irqrestore(&qt->lock, flags);\n\t\treturn 0;\n\t}\n\n\tq = (struct queue *)qt->data;\n\tif (q->q_cnt >= q->q_size) {\n\t\tspin_unlock_irqrestore(&qt->lock, flags);\n\t\treturn -ENOSPC;\n\t}\n\n\tif (front)\n\t\tqueue_push_front(q, pmsg);\n\telse\n\t\tqueue_push(q, pmsg);\n\n\tspin_unlock_irqrestore(&qt->lock, flags);\n\n\treturn ret;\n}\n\nint queue_post_abort(queue_t *qt, int opt)\n{\n\treturn 0;\n}\n\nint queue_post(queue_t *qt, void *pmsg)\n{\n\treturn __queue_post(qt, pmsg, 0);\n}\n\nint queue_post_front(queue_t *qt, void *pmsg)\n{\n\treturn __queue_post(qt, pmsg, 1);\n}\n"
  },
  {
    "path": "kernel/core/ramdisk.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/ramdisk.h>\n#include <minos/mm.h>\n\nvoid *ramdisk_start, *ramdisk_end;\nstatic struct ramdisk_inode *root;\nstatic struct ramdisk_sb *sb;\nstatic void *ramdisk_data;\n\nvoid set_ramdisk_address(void *start, void *end)\n{\n\tramdisk_start = start;\n\tramdisk_end = end;\n}\n\nint ramdisk_init(void)\n{\n\tunsigned long start = ptov(ramdisk_start);\n\tsize_t size = ramdisk_end - ramdisk_start;\n\n\t/*\n\t * need remap the ramdisk memory space, if it\n\t * is not in the kernel memory space TBD.\n\t */\n\tif (!ramdisk_start || !ramdisk_end) {\n\t\tpr_err(\"ramdisk address is not set\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\tif (!IS_PAGE_ALIGN(ramdisk_start)) {\n\t\tpr_err(\"ramdisk start address need PAGE align\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\tif (create_host_mapping(start, (unsigned long)ramdisk_start, size, VM_RO)) {\n\t\tpr_err(\"unable map ramdisk memory\\n\");\n\t\treturn -ENOMEM;\n\t}\n\n\tif (strncmp((void *)start, RAMDISK_MAGIC, RAMDISK_MAGIC_SIZE) != 0) {\n\t\tdestroy_host_mapping(start, size);\n\t\tpr_err(\"bad ramdisk format\\n\");\n\t\treturn -EBADF;\n\t}\n\n\t/*\n\t * the ramdisk is read only, init the ramdisk\n\t * information, inclue the superblock and the\n\t * root inode\n\t */\n\tramdisk_start = (void *)ptov(ramdisk_start);\n\tramdisk_end = (void *)ptov(ramdisk_end);\n\n\tsb = ramdisk_start + RAMDISK_MAGIC_SIZE;\n\troot = ramdisk_start + sb->inode_offset;\n\tramdisk_data = ramdisk_start + sb->data_offset;\n\n\treturn 0;\n}\n\nconst char *ramdisk_file_name(struct ramdisk_file *file)\n{\n\treturn file->inode->f_name;\n}\n\nunsigned long ramdisk_file_size(struct ramdisk_file *file)\n{\n\treturn file->inode->f_size;\n}\n\nunsigned long ramdisk_file_base(struct ramdisk_file *file)\n{\n\treturn (unsigned long)ramdisk_data + file->inode->f_offset;\n}\n\nstatic struct ramdisk_inode *get_file_inode(const char *name)\n{\n\tstruct ramdisk_inode *inode;\n\n\tfor (inode = root; inode < root + sb->file_cnt; inode++) {\n\t\tif (strncmp(inode->f_name, name, RAMDISK_FNAME_SIZE - 1) == 0)\n\t\t\treturn inode;\n\t}\n\n\treturn NULL;\n}\n\nint ramdisk_read(struct ramdisk_file *file, void *buf,\n\t\tsize_t size, unsigned long offset)\n{\n\tif (!file)\n\t\treturn -EINVAL;\n\n\tif ((offset + size) > file->inode->f_size)\n\t\treturn -EINVAL;\n\n\tmemcpy(buf, ramdisk_data + file->inode->f_offset + offset, size);\n\treturn 0;\n}\n\nint ramdisk_open(char *name, struct ramdisk_file *file)\n{\n\tstruct ramdisk_inode *inode;\n\n\tif (!sb) {\n\t\tpr_debug(\"super block not found\\n\");\n\t\treturn -ENOENT;\n\t}\n\n\tinode = get_file_inode(name);\n\tif (!inode)\n\t\treturn -ENOENT;\n\n\tmemset(file, 0, sizeof(struct ramdisk_file));\n\tfile->inode = inode;\n\n\treturn 0;\n}\n"
  },
  {
    "path": "kernel/core/sched.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/task.h>\n#include <minos/sched.h>\n#include <minos/irq.h>\n#include <minos/softirq.h>\n#include <minos/of.h>\n#include <minos/bootarg.h>\n#include <minos/mm.h>\n#include <minos/flag.h>\n#include <minos/time.h>\n\n#ifdef CONFIG_VIRT\n#include <virt/virt.h>\n#include <virt/vm.h>\n#endif\n\nDEFINE_PER_CPU(struct pcpu *, pcpu);\n\nextern struct task *os_task_table[OS_NR_TASKS];\n\n#define sched_check()\t\t\t\t\t\t\t\t\\\n\tdo {\t\t\t\t\t\t\t\t\t\\\n\t\tif (in_interrupt() || (irq_disabled() && !preempt_allowed()))\t\\\n\t\t\tpanic(\"sched is disabled %s %d\\n\", __func__, __LINE__);\t\\\n\t} while (0)\n\nvoid __might_sleep(const char *file, int line, int preempt_offset)\n{\n\tstruct task *task = current;\n\n\tWARN_ONCE(task->state != TASK_STATE_RUNNING,\n\t\t\t\"do not call blocking ops when !TASK_RUNNING; \"\n\t\t\t\"state=%d\", task->state);\n\n\tif (preempt_allowed() && !irq_disabled() && !task_is_idle(task))\n\t\treturn;\n\n\tpr_err(\"BUG: sleeping function called from invalid context at %d %s:%d\\n\",\n\t\t\tcurrent->ti.preempt_count, file, line);\n\tdump_stack(NULL, (unsigned long *)arch_get_sp());\n}\n\nstatic inline void sched_update_sched_timer(void)\n{\n\tstruct pcpu *pcpu = get_pcpu();\n\tstruct task *task = current;\n\n\t/*\n\t * enable the sched timer if there are more than one\n\t * ready task on the same prio.\n\t */\n\tif ((pcpu->tasks_in_prio[task->prio] > 1))\n\t\tsetup_and_start_timer(&pcpu->sched_timer, MILLISECS(task->run_time));\n\telse\n\t\tstop_timer(&pcpu->sched_timer);\n}\n\nstatic void add_task_to_ready_list(struct pcpu *pcpu,\n\t\tstruct task *task, int preempt)\n{\n\t/*\n\t * make sure the new task is insert to front of the current\n\t * task.\n\t *\n\t * if the prio is equal to the current task's prio, insert to\n\t * the front of the current task.\n\t */\n\tASSERT(task->state_list.next == NULL);\n\tpcpu->tasks_in_prio[task->prio]++;\n\n\tif (current->prio == task->prio) {\n\t\tlist_insert_before(&current->state_list, &task->state_list);\n\t\tif (pcpu->tasks_in_prio[task->prio] == 2)\n\t\t\tsched_update_sched_timer();\n\t} else {\n\t\tlist_add_tail(&pcpu->ready_list[task->prio], &task->state_list);\n\t}\n\n\tmb();\n\tpcpu->local_rdy_grp |= BIT(task->prio);\n\n\tif (preempt || current->prio > task->prio)\n\t\tset_need_resched();\n}\n\nstatic void remove_task_from_ready_list(struct pcpu *pcpu, struct task *task)\n{\n\tASSERT(task->state_list.next != NULL);\n\n\tlist_del(&task->state_list);\n\tif (is_list_empty(&pcpu->ready_list[task->prio]))\n\t\tpcpu->local_rdy_grp &= ~BIT(task->prio);\n\tmb();\n\n\tpcpu->tasks_in_prio[task->prio]--;\n\n\t/*\n\t * check whether need to stop the sched timer.\n\t */\n\tif ((current->prio == task->prio) &&\n\t\t\t(pcpu->tasks_in_prio[task->prio] == 1))\n\t\tsched_update_sched_timer();\n}\n\nvoid pcpu_resched(int pcpu_id)\n{\n\tsend_sgi(CONFIG_MINOS_RESCHED_IRQ, pcpu_id);\n}\n\nvoid pcpu_irqwork(int pcpu_id)\n{\n\tsend_sgi(CONFIG_MINOS_IRQWORK_IRQ, pcpu_id);\n}\n\nstatic int select_task_run_cpu(void)\n{\n\t/*\n\t * TBD\n\t */\n\treturn (NR_CPUS - 1);\n}\n\nstatic void percpu_task_ready(struct pcpu *pcpu, struct task *task, int preempt)\n{\n\tunsigned long flags;\n\n\tlocal_irq_save(flags);\n\tadd_task_to_ready_list(pcpu, task, preempt);\n\tlocal_irq_restore(flags);\n}\n\nstatic inline void smp_percpu_task_ready(struct pcpu *pcpu,\n\t\tstruct task *task, int preempt)\n{\n\tunsigned long flags;\n\n\tif (preempt)\n\t\ttask_set_resched(task);\n\n\tASSERT(task->state_list.next == NULL);\n\tspin_lock_irqsave(&pcpu->lock, flags);\n\tlist_add_tail(&pcpu->new_list, &task->state_list);\n\tspin_unlock_irqrestore(&pcpu->lock, flags);\n\n\tpcpu_irqwork(pcpu->pcpu_id);\n}\n\nint task_ready(struct task *task, int preempt)\n{\n\tstruct pcpu *pcpu, *tpcpu;\n\n\tpreempt_disable();\n\n\ttask->cpu = task->affinity;\n\tif (task->cpu == -1)\n\t\ttask->cpu = select_task_run_cpu();\n\n\t/*\n\t * if the task is a precpu task and the cpu is not\n\t * the cpu which this task affinity to then put this\n\t * cpu to the new_list of the pcpu and send a resched\n\t * interrupt to the pcpu\n\t */\n\tpcpu = get_pcpu();\n\tif (pcpu->pcpu_id != task->cpu) {\n\t\ttpcpu = get_per_cpu(pcpu, task->cpu);\n\t\tsmp_percpu_task_ready(tpcpu, task, preempt);\n\t} else {\n\t\tpercpu_task_ready(pcpu, task, preempt);\n\t}\n\n\tpreempt_enable();\n\n\treturn 0;\n}\n\nvoid task_sleep(uint32_t delay)\n{\n\tstruct task *task = current;\n\tunsigned long flags;\n\n\t/*\n\t * task sleep will wait for the sleep timer expired\n\t * or the event happend\n\t */\n\tlocal_irq_save(flags);\n\tdo_not_preempt();\n\ttask->delay = (delay == (uint32_t)-1 ? TASK_WAIT_FOREVER : delay);\n\ttask->state = TASK_STATE_WAIT_EVENT;\n\ttask->wait_type = OS_EVENT_TYPE_TIMER;\n\ttask->wait_event = NULL;\n\tlocal_irq_restore(flags);\n\n\tsched();\n}\n\nstatic inline void task_stop(int state)\n{\n\tstruct task *task = current;\n\tunsigned long flags;\n\n\tdo_not_preempt();\n\tlocal_irq_save(flags);\n\ttask->delay = 0;\n\ttask->state = state;\n\ttask->wait_type = 0;\n\tlocal_irq_restore(flags);\n\n\tsched();\n}\n\nvoid task_suspend(void)\n{\n\ttask_stop(TASK_STATE_SUSPEND);\n}\n\nvoid task_die(void)\n{\n\ttask_stop(TASK_STATE_STOP);\n}\n\nstatic struct task *pick_next_task(struct pcpu *pcpu)\n{\n\tstruct list_head *head;\n\tstruct task *task = current;\n\tint prio;\n\n\t/*\n\t * if the current task need to sleep or waitting some\n\t * event happen. delete it from the ready list, then the\n\t * next run task can be got.\n\t */\n\tmb();\n\tASSERT(task->state != TASK_STATE_READY);\n\n\tif (!task_is_running(task)) {\n\t\tremove_task_from_ready_list(pcpu, task);\n                if (task->state == TASK_STATE_STOP) {\n                        list_add_tail(&pcpu->stop_list, &task->state_list);\n\t\t\tflag_set(&pcpu->kworker_flag, KWORKER_TASK_RECYCLE);\n\t\t}\n\t}\n\n\t/*\n\t * get the highest ready task list to running\n\t */\n\tprio = ffs_one_table[pcpu->local_rdy_grp];\n\tASSERT(prio != -1);\n\thead = &pcpu->ready_list[prio];\n\n\t/*\n\t * get the first task, then put the next running\n\t * task to the end of the ready list.\n\t */\n\tASSERT(!is_list_empty(head));\n\ttask = list_first_entry(head, struct task, state_list);\n\tlist_del(&task->state_list);\n\tlist_add_tail(head, &task->state_list);\n\n\treturn task;\n}\n\nstatic void switch_to_task(struct task *cur, struct task *next)\n{\n\tstruct pcpu *pcpu = get_pcpu();\n\n\tarch_task_sched_out(cur);\n\tdo_hooks(cur, NULL, OS_HOOK_TASK_SWITCH_OUT);\n\n\t/* \n\t * check the current task's state and do some action\n\t * to it, check whether it suspend time is set or not\n\t *\n\t * if the task is ready state, adjust the run time of\n\t * this task. If the task need to wait some event, and\n\t * need request a timeout timer then need setup the timer.\n\t */\n\tif ((cur->state == TASK_STATE_WAIT_EVENT) && (cur->delay > 0))\n\t\tsetup_and_start_timer(&cur->delay_timer,\n\t\t\t\tMILLISECS(cur->delay));\n\telse if (cur->state == TASK_STATE_RUNNING)\n\t\tcur->state = TASK_STATE_READY;\n\n\tcur->last_cpu = cur->cpu;\n\tcur->run_time = CONFIG_TASK_RUN_TIME;\n\tsmp_wmb();\n\n\t/*\n\t * notify the cpu which need to waku-up this task that\n\t * the task has been do to sched out, can be wakeed up\n\t * safe, the task is offline now.\n\t */\n\tcur->cpu = -1;\n\tsmp_wmb();\n\n\t/*\n\t * change the current task to next task.\n\t */\n\tnext->state = TASK_STATE_RUNNING;\n\tnext->ti.flags &= ~__TIF_TICK_EXHAUST;\n\tnext->cpu = pcpu->pcpu_id;\n\tset_current_task(next);\n\tpcpu->running_task = next;\n\n\tnext->ctx_sw_cnt++;\n\tnext->wait_event = 0;\n\tnext->start_ns = NOW();\n\tsmp_wmb();\n\n\tdo_hooks(next, NULL, OS_HOOK_TASK_SWITCH_TO);\n\tarch_task_sched_in(next);\n}\n\nstatic void sched_tick_handler(unsigned long data)\n{\n\tstruct task *task = current;\n\n\t/*\n\t * mark this task has used its running ticket, and the sched\n\t * timer is off.\n\t */\n\ttask->ti.flags |= __TIF_TICK_EXHAUST;\n\tset_need_resched();\n}\n\nstatic void inline sys_sched(void)\n{\n\tsched_check();\n\tarch_sys_sched();\n}\n\nvoid sched(void)\n{\n\t/*\n\t * tell the scheduler that I am ok to sched out.\n\t */\n\tset_need_resched();\n\tclear_do_not_preempt();\n\n\tdo {\n\t\tsys_sched();\n\t} while (need_resched());\n}\n\nstatic inline int sched_allowed(void)\n{\n\treturn preempt_allowed() && !irq_disabled();\n}\n\nvoid cond_resched(void)\n{\n\tif (need_resched() && sched_allowed())\n\t\tsched();\n}\n\nvoid task_exit(int errno)\n{\n\tset_current_state(TASK_STATE_STOP, 0);\n\tsched();\n}\n\nstatic inline int __exception_return_handler(void)\n{\n\tstruct task *next, *task = current;\n\tstruct task_info *ti = to_task_info(task);\n\tstruct pcpu *pcpu = get_pcpu();\n\n\t/*\n\t * if the task is suspend state, means next the cpu\n\t * will call sched directly, so do not sched out here\n\t *\n\t * 1 - when preempt_count > 0, the scheduler whill try\n\t *     to shced() when preempt_enable.\n\t * 2 - __TIF_DONOT_PREEMPT is set, it will call sched() at\n\t *    once.\n\t */\n\tif (!(ti->flags & __TIF_NEED_RESCHED) || (ti->preempt_count > 0) ||\n\t\t\t(ti->flags & __TIF_DONOT_PREEMPT))\n\t\tgoto task_run_again;\n\n\tti->flags &= ~__TIF_NEED_RESCHED;\n\n\tnext = pick_next_task(pcpu);\n\tif ((next == task))\n\t\tgoto task_run_again;\n\n\tswitch_to_task(task, next);\n\tdo_hooks(task, next, OS_HOOK_TASK_SWITCH);\n\n\treturn 0;\n\ntask_run_again:\n\tif (test_and_clear_bit(TIF_TICK_EXHAUST, &ti->flags))\n\t\treturn -EAGAIN;\n\telse\n\t\treturn -EACCES;\n}\n\nvoid exception_return_handler(void)\n{\n\tint ret = __exception_return_handler();\n\n\tif ((ret == 0) || (ret == -EAGAIN))\n\t\tsched_update_sched_timer();\n}\n\nstatic int irqwork_handler(uint32_t irq, void *data)\n{\n\tstruct pcpu *pcpu = get_pcpu();\n\tstruct task *task, *n;\n\tint preempt = 0, need_preempt;\n\n\t/*\n\t * check whether there are new taskes need to\n\t * set to ready state again\n\t */\n\traw_spin_lock(&pcpu->lock);\n\tlist_for_each_entry_safe(task, n, &pcpu->new_list, state_list) {\n\t\t/*\n\t\t * remove it from the new_next.\n\t\t */\n\t\tlist_del(&task->state_list);\n\n\t\tif (task->state == TASK_STATE_RUNNING) {\n\t\t\tpr_err(\"task %s state %d wrong\\n\",\n\t\t\t\ttask->name? task->name : \"Null\", task->state);\n\t\t\tcontinue;\n\t\t}\n\n\t\tneed_preempt = task_need_resched(task);\n\t\tpreempt += need_preempt;\n\t\ttask_clear_resched(task);\n\n\t\tadd_task_to_ready_list(pcpu, task, need_preempt);\n\t\ttask->state = TASK_STATE_READY;\n\n\t\t/*\n\t\t * if the task has delay timer, cancel it.\n\t\t */\n\t\tif (task->delay) {\n\t\t\tstop_timer(&task->delay_timer);\n\t\t\ttask->delay = 0;\n\t\t}\n\t}\n\traw_spin_unlock(&pcpu->lock);\n\n\tif (preempt || task_is_idle(current))\n\t\tset_need_resched();\n\n\treturn 0;\n}\n\nstatic int resched_handler(uint32_t irq, void *data)\n{\n\tset_need_resched();\n\treturn 0;\n}\n\nint local_sched_init(void)\n{\n\tstruct pcpu *pcpu = get_pcpu();\n\n\tinit_timer(&pcpu->sched_timer, sched_tick_handler, (unsigned long)pcpu);\n\n\trequest_irq(CONFIG_MINOS_RESCHED_IRQ, resched_handler,\n\t\t\t0, \"resched handler\", NULL);\n\trequest_irq(CONFIG_MINOS_IRQWORK_IRQ, irqwork_handler,\n\t\t\t0, \"irqwork handler\", NULL);\n\treturn 0;\n}\n\nstatic void pcpu_sched_init(struct pcpu *pcpu)\n{\n\tinit_list(&pcpu->new_list);\n\tinit_list(&pcpu->stop_list);\n\tinit_list(&pcpu->die_process);\n\tinit_list(&pcpu->ready_list[0]);\n\tinit_list(&pcpu->ready_list[1]);\n\tinit_list(&pcpu->ready_list[2]);\n\tinit_list(&pcpu->ready_list[3]);\n\tinit_list(&pcpu->ready_list[4]);\n\tinit_list(&pcpu->ready_list[5]);\n\tinit_list(&pcpu->ready_list[6]);\n\tinit_list(&pcpu->ready_list[7]);\n}\n\nint sched_init(void)\n{\n\tint i;\n\n\tfor (i = 0; i < NR_CPUS; i++)\n\t\tpcpu_sched_init(&pcpus[i]);\n\n\treturn 0;\n}\n\nstatic int wake_up_interrupted(struct task *task,\n\t\tlong pend_state, unsigned long data)\n{\n\tunsigned long flags;\n\n\tASSERT(pend_state != TASK_STATE_PEND_TO);\n\tif (task->state != TASK_STATE_WAIT_EVENT)\n\t\treturn -EACCES;\n\n\tif (!irq_disabled())\n\t\tpanic(\"unexpected irq happend when wait_event() ?\\n\");\n\n\t/*\n\t * the interrup occurs when task try to wait_event. in\n\t * addition:\n\t * 1 - the interrupt is happended in the same cpu.\n\t * 2 - will not the delay timer, since the delay time\n\t *     has not been set already.\n\t * 3 - the state must TASK_STATE_WAIT_EVENT\n\t * 4 - task has not been in sched routine.\n\t *\n\t * meanwhile, other cpu may already in the wake up function\n\t * try to wake up the task, then need check this suitation\n\t * since other cpu while check cpu == -1, this will lead\n\t * to dead lock if use spin_lock function. So here use\n\t * spin_trylock instead.\n\t */\n\tif (!spin_trylock_irqsave(&task->s_lock, flags))\n\t\treturn -EBUSY;\n\n\tif (task->state != TASK_STATE_WAIT_EVENT) {\n\t\tspin_unlock_irqrestore(&task->s_lock, flags);\n\t\treturn -EINVAL;\n\t}\n\n\ttask->ti.flags |= __TIF_WAIT_INTERRUPTED;\n\ttask->ti.flags &= ~__TIF_DONOT_PREEMPT;\n\n\t/*\n\t * here this cpu got this task, and can set the new\n\t * state to running and run it again.\n\t */\n\ttask->pend_state = pend_state;\n\ttask->state = TASK_STATE_RUNNING;\n\ttask->delay = 0;\n\ttask->ipcdata = data;\n\tspin_unlock_irqrestore(&task->s_lock, flags);\n\n\treturn 0;\n}\n\nstatic int wake_up_common(struct task *task, long pend_state, unsigned long data)\n{\n\tunsigned long flags;\n\tuint32_t timeout;\n\n\tpreempt_disable();\n\tspin_lock_irqsave(&task->s_lock, flags);\n\n\t/*\n\t * task already waked up, if the stat is set to\n\t * TASK_STATE_WAIT_EVENT, it means that the task will\n\t * call sched() to sleep or wait something happen.\n\t */\n\tif (task->state != TASK_STATE_WAIT_EVENT) {\n\t\tspin_unlock_irqrestore(&task->s_lock, flags);\n\t\tpreempt_enable();\n\t\treturn -EPERM;\n\t}\n\n\t/*\n\t * the task may in sched() routine on other cpu\n\t * wait the task really out of running. since the task\n\t * will not preempt in the kernel space now, so the cpu\n\t * of the task will change to -1 at one time.\n\t *\n\t * since the kernel can not be preempted so it can make\n\t * sure that sched() can be finish its work.\n\t */\n\twhile (task->cpu != -1)\n\t\tcpu_relax();\n\n\t/*\n\t * here this cpu got this task, and can set the new\n\t * state to running and run it again.\n\t */\n\ttask->pend_state = pend_state;\n\ttask->state = TASK_STATE_WAKING;\n\ttimeout = task->delay;\n\ttask->delay = 0;\n\ttask->ipcdata = data;\n\n\tspin_unlock_irqrestore(&task->s_lock, flags);\n\n\t/*\n\t * here it means that this task has not been timeout, so can\n\t * delete the timer for this task.\n\t */\n\tif (timeout && (task->pend_state != TASK_STATE_PEND_TO))\n\t\tstop_timer(&task->delay_timer);\n\n\t/*\n\t * find a best cpu to run this task.\n\t */\n\ttask_ready(task, 1);\n\tpreempt_enable();\n\n\treturn 0;\n}\n\nint __wake_up(struct task *task, long pend_state, unsigned long data)\n{\n\tif (task == current)\n\t\treturn wake_up_interrupted(task, pend_state, data);\n\telse\n\t\treturn wake_up_common(task, pend_state, data);\n}\n"
  },
  {
    "path": "kernel/core/sem.c",
    "content": "/*\n * Copyright (C) 2019 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/event.h>\n#include <minos/task.h>\n#include <minos/sem.h>\n#include <minos/sched.h>\n\nuint32_t sem_accept(sem_t *sem)\n{\n\tuint32_t cnt;\n\tunsigned long flags;\n\n\tspin_lock_irqsave(&sem->lock, flags);\n\tcnt = sem->cnt;\n\tif (cnt > 0)\n\t\tsem->cnt--;\n\tspin_unlock_irqrestore(&sem->lock, flags);\n\n\treturn cnt == 0 ? -ENOSPC : cnt;\n}\n\nint sem_pend(sem_t *sem, uint32_t timeout)\n{\n\tunsigned long flags;\n\n\tmight_sleep();\n\n\tspin_lock_irqsave(&sem->lock, flags);\n\tif (sem->cnt > 0) {\n\t\tsem->cnt--;\n\t\tspin_unlock_irqrestore(&sem->lock, flags);\n\t\treturn 0;\n\t}\n\t__wait_event(TO_EVENT(sem), OS_EVENT_TYPE_SEM, timeout);\n\tspin_unlock_irqrestore(&sem->lock, flags);\n\n\treturn do_wait_event(TO_EVENT(sem));\n}\n\nstatic int sem_post_opt(sem_t *sem, int pend_state, int opt)\n{\n\tunsigned long flags;\n\tint ret;\n\n\tspin_lock_irqsave(&sem->lock, flags);\n\tret = wake_up_event_waiter(TO_EVENT(sem), 0, pend_state,\n\t\t\topt == OS_EVENT_OPT_BROADCAST ? WAKEUP_ALL : 1);\n\tif (pend_state != TASK_STATE_PEND_ABORT) {\n\t\tif (!ret && (sem->cnt < INT_MAX))\n\t\t\tsem->cnt++;\n\t\telse\n\t\t\tret = -EOVERFLOW;\n\t}\n\tspin_unlock_irqrestore(&sem->lock, flags);\n\n\tif (ret > 0)\n\t\tcond_resched();\n\n\treturn ret;\n}\n\n/*\n * the sem is broken, wake up all the waiter.\n */\nint sem_pend_abort(sem_t *sem, int opt)\n{\n\treturn sem_post_opt(sem, TASK_STATE_PEND_ABORT,\n\t\t\tOS_EVENT_OPT_BROADCAST);\n}\n\nint sem_post(sem_t *sem)\n{\n\treturn sem_post_opt(sem, TASK_STATE_PEND_OK,\n\t\t\tOS_EVENT_OPT_NONE);\n}\n"
  },
  {
    "path": "kernel/core/slab.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/types.h>\n#include <config/config.h>\n#include <minos/spinlock.h>\n#include <minos/minos.h>\n#include <minos/init.h>\n#include <minos/mm.h>\n\nstruct slab_header {\n\tunsigned long size;\n\tunion {\n\t\tunsigned long magic;\n\t\tstruct slab_header *next;\n\t};\n} __packed;\n\n#define HASH_TABLE_SIZE\t8\n\n#define SLAB_MEM_BASE ptov(511UL * 1024 * 1024 * 1024)\n#define SLAB_MEM_SIZE (128UL * 1024 * 1024)\n#define SLAB_MEM_END (SLAB_MEM_BASE + SLAB_MEM_SIZE)\n\n#define SLAB_MIN_DATA_SIZE\t\t(16)\n#define SLAB_MIN_DATA_SIZE_SHIFT\t(4)\n#define SLAB_HEADER_SIZE\t\tsizeof(struct slab_header)\n#define SLAB_MIN_SIZE\t\t\t(SLAB_MIN_DATA_SIZE + SLAB_HEADER_SIZE)\n#define SLAB_MAGIC\t\t\t(0xdeadbeef)\n\nstruct slab_type {\n\tuint32_t size;\n\tstruct list_head list;\n\tstruct slab_header *head;\n};\n\n/*\n * will try to get hugepage when first time once\n * system bootup.\n */\nstatic DEFINE_SPIN_LOCK(slab_lock);\nstatic struct list_head slab_hash_table[HASH_TABLE_SIZE];\n\nstatic void *slab_base;\nstatic uint32_t slab_size;\nstatic uint32_t cur_free_size;\n\n#define hash_id(size) (((size) >> SLAB_MIN_DATA_SIZE_SHIFT) % HASH_TABLE_SIZE)\n\nstatic int inline is_slab_memory(void *addr)\n{\n\treturn (((unsigned long)addr >= SLAB_MEM_BASE) &&\n\t\t\t((unsigned long)addr < SLAB_MEM_END));\n}\n\nstatic size_t inline get_slab_alloc_size(size_t size)\n{\n\treturn BALIGN(size, SLAB_MIN_DATA_SIZE);\n}\n\nstatic void *malloc_from_hash_table(size_t size)\n{\n\tint id = hash_id(size);\n\tstruct slab_type *st;\n\tstruct slab_header *sh;\n\n\t/*\n\t * find the related slab mem id and try to fetch\n\t * a free slab memory from the hash cache.\n\t */\n\tlist_for_each_entry(st, &slab_hash_table[id], list) {\n\t\tif (st->size != size)\n\t\t\tcontinue;\n\n\t\tif (st->head == NULL)\n\t\t\treturn NULL;\n\n\t\tsh = st->head;\n\t\tst->head = sh->next;\n\t\tsh->magic = SLAB_MAGIC;\n\n\t\treturn ((void *)sh + SLAB_HEADER_SIZE);\n\t}\n\n\treturn NULL;\n}\n\nstatic void *malloc_from_slab_heap(size_t size)\n{\n\tunsigned long base = 0;\n\tstruct slab_header *sh;\n\tuint32_t mapsize;\n\tvoid *page;\n\tint i;\n\n\tsize += SLAB_HEADER_SIZE;\n\tif (slab_size < size)\n\t\treturn NULL;\n\n\tif (cur_free_size >= size) {\n\t\tmapsize = 0;\n\t\tcur_free_size -= size;\n\t} else {\n\t\tbase = (unsigned long)slab_base + cur_free_size;\n\t\tmapsize = PAGE_BALIGN(size - cur_free_size);\n\t\tcur_free_size = cur_free_size + mapsize - size;\n\t}\n\n\t/*\n\t * if need one new page, need to allocate the needed\n\t * pages and map it.\n\t */\n\tfor (i = 0; i < (mapsize >> PAGE_SHIFT); i++) {\n\t\tpage = get_free_page(GFP_KERNEL | GFP_SLAB);\n\t\tASSERT(page != NULL);\n\t\tASSERT(create_host_mapping(base, vtop(page),\n\t\t\t\tPAGE_SIZE, VM_HOST | VM_RW) == 0);\n\t\tbase += PAGE_SIZE;\n\t}\n\n\tsh = (struct slab_header *)slab_base;\n\tsh->magic = SLAB_MAGIC;\n\tsh->size = size - SLAB_HEADER_SIZE;\n\n\tslab_base += size;\n\tslab_size -= size;\n\n\treturn ((void *)sh + SLAB_HEADER_SIZE);\n}\n\nstatic void free_slab(void *addr)\n{\n\tstruct slab_header *header;\n\tstruct slab_type *st;\n\tint id;\n\n\theader = (struct slab_header *)((unsigned long)addr -\n\t\t\tSLAB_HEADER_SIZE);\n\tif ((header->magic != SLAB_MAGIC) ||\n\t\t\t(header->size < SLAB_MIN_DATA_SIZE)) {\n\t\tpr_warn(\"memory is not a slab mem 0x%p\\n\", (unsigned long)addr);\n\t\treturn;\n\t}\n\n\tid = hash_id(header->size);\n\tspin_lock(&slab_lock);\n\n\tlist_for_each_entry(st, &slab_hash_table[id], list) {\n\t\tif (st->size != header->size)\n\t\t\tcontinue;\n\n\t\theader->next = st->head;\n\t\tst->head = header;\n\t\tspin_unlock(&slab_lock);\n\t\treturn;\n\t}\n\n\t/*\n\t * create new slab type and add the new slab header\n\t * to the slab cache.\n\t */\n\tst = malloc_from_slab_heap(sizeof(struct slab_type));\n\tASSERT(st != NULL);\n\tpr_debug(\"create new slab type for %d %d\\n\",\n\t\t\theader->size, id);\n\tst->size = header->size;\n\tlist_add_tail(&slab_hash_table[id], &st->list);\n\n\theader->next = NULL;\n\tst->head = header;\n\n\tspin_unlock(&slab_lock);\n}\n\nvoid free(void *addr)\n{\n\tif (!is_slab_memory(addr)) {\n\t\tif (free_pages(addr) == 0)\n\t\t\treturn;\n\t}\n\n\tfree_slab(addr);\n}\n\nstatic void *__malloc(size_t size)\n{\n\tvoid *mem;\n\n\tspin_lock(&slab_lock);\n\tmem = malloc_from_hash_table(size);\n\tif (mem == NULL)\n\t\tmem = malloc_from_slab_heap(size);\n\tspin_unlock(&slab_lock);\n\n\tif (!mem) {\n\t\tpr_err(\"malloc fail for 0x%x\\n\");\n\t\tdump_stack(NULL, NULL);\n\t\tBUG();\n\t}\n\n\treturn mem;\n}\n\nvoid *malloc(size_t size)\n{\n\tASSERT(size != 0);\n\tsize = get_slab_alloc_size(size);\n\treturn __malloc(size);\n}\n\nvoid *zalloc(size_t size)\n{\n\tvoid *addr = malloc(size);\n\tif (addr)\n\t\tmemset(addr, 0, size);\n\treturn addr;\n}\n\nvoid slab_init(void)\n{\n\tint i;\n\n\tpr_notice(\"slab memory allocator init ...\\n\");\n\tslab_base = (void *)SLAB_MEM_BASE;\n\tslab_size = SLAB_MEM_SIZE;\n\n\tfor (i = 0; i < HASH_TABLE_SIZE; i++)\n\t\tinit_list(&slab_hash_table[i]);\n}\n"
  },
  {
    "path": "kernel/core/smp.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <config/config.h>\n#include <minos/percpu.h>\n#include <minos/platform.h>\n#include <minos/irq.h>\n#include <asm/cache.h>\n#include <minos/time.h>\n\n#define SMP_CALL_LOCKED\t\t(1 << 0)\n\n#define SMP_FUNCTION_CALL_IRQ\tCONFIG_SMP_FUNCTION_CALL_IRQ\n\nextern unsigned char __smp_affinity_id;\nuint64_t *smp_affinity_id;\nphy_addr_t smp_holding_address[CONFIG_NR_CPUS];\n\ncpumask_t cpu_online;\nstatic int cpus_all_up;\n\nstruct smp_call {\n\tsmp_function fn;\n\tunsigned long flags;\n\tvoid *data;\n};\n\nstruct smp_call_data {\n\tstruct smp_call smp_calls[NR_CPUS];\n};\n\nstatic DEFINE_PER_CPU(struct smp_call_data, smp_call_data);\n\nstatic void inline smp_call_wait(struct smp_call *call)\n{\n\t/* need wait for last call finished */\n\twhile (call->flags & SMP_CALL_LOCKED)\n\t\tcpu_relax();\n}\n\nstatic void inline smp_call_lock(struct smp_call *call)\n{\n\tif (call->flags & SMP_CALL_LOCKED)\n\t\tpr_warn(\"smp call is already locked\\n\");\n\n\tcall->flags |= SMP_CALL_LOCKED;\n\twmb();\n}\n\nstatic void inline smp_call_unlock(struct smp_call *call)\n{\n\tcall->flags &= ~SMP_CALL_LOCKED;\n\twmb();\n}\n\nint is_cpus_all_up(void)\n{\n\treturn cpus_all_up;\n}\n\nint smp_function_call(int cpu, smp_function fn, void *data, int wait)\n{\n\tint cpuid;\n\tstruct smp_call *call;\n\tstruct smp_call_data *cd;\n\tunsigned long flags;\n\n\tpreempt_disable();\n\tcpuid = smp_processor_id();\n\n\tif (cpu >= NR_CPUS)\n\t\treturn -EINVAL;\n\n\t/* function call itself just call the function */\n\tif (cpu == cpuid) {\n\t\tlocal_irq_save(flags);\n\t\tfn(data);\n\t\tlocal_irq_restore(flags);\n\t\tpreempt_enable();\n\t\treturn 0;\n\t}\n\n\tcd = &get_per_cpu(smp_call_data, cpu);\n\tcall = &cd->smp_calls[cpuid];\n\n\tsmp_call_wait(call);\n\tcall->fn = fn;\n\tcall->data = data;\n\tsmp_call_lock(call);\n\n\tsend_sgi(SMP_FUNCTION_CALL_IRQ, cpu);\n\n\tif (wait)\n\t\tsmp_call_wait(call);\n\n\tpreempt_enable();\n\n\treturn 0;\n}\n\nstatic irqreturn_t smp_function_call_handler(uint32_t irq, void *data)\n{\n\tint i;\n\tstruct smp_call_data *cd;\n\tstruct smp_call *call;\n\n\tcd = &get_cpu_var(smp_call_data);\n\n\tfor (i = 0; i < NR_CPUS; i++) {\n\t\tcall = &cd->smp_calls[i];\n\t\tif (call->flags & SMP_CALL_LOCKED) {\n\t\t\tcall->fn(call->data);\n\t\t\tcall->fn = NULL;\n\t\t\tcall->data = NULL;\n\t\t\tsmp_call_unlock(call);\n\t\t}\n\t}\n\n\treturn 0;\n}\n\nint smp_cpu_up(unsigned long cpu, unsigned long entry)\n{\n\tif (platform->cpu_on)\n\t\treturn platform->cpu_on(cpu, entry);\n\n\tpr_warn(\"no cpu on function\\n\");\n\treturn 0;\n}\n\nvoid smp_cpus_up(void)\n{\n\tint i, ret, cnt;\n\tuint64_t affinity;\n\n\tflush_cache_all();\n\n\tfor (i = 1; i < CONFIG_NR_CPUS; i++) {\n\t\tcnt = 0;\n\t\taffinity = cpuid_to_affinity(i);\n\n\t\tret = smp_cpu_up(affinity, CONFIG_MINOS_ENTRY_ADDRESS);\n\t\tif (ret) {\n\t\t\tpr_fatal(\"failed to bring up cpu-%d\\n\", i);\n\t\t\tcontinue;\n\t\t}\n\t}\n\n\tfor (i = 1; i < CONFIG_NR_CPUS; i++) {\n\t\tpr_notice(\"waiting 2 seconds for cpu-%d up\\n\", i);\n\t\twhile ((smp_affinity_id[i] == 0) && (cnt < 2000)) {\n\t\t\tmdelay(1);\n\t\t\tcnt++;\n\t\t}\n\n\t\tif (smp_affinity_id[i] == 0) {\n\t\t\tpr_err(\"cpu-%d is not up with affinity id 0x%p\\n\",\n\t\t\t\t\ti, smp_affinity_id[i]);\n\t\t} else {\n\t\t\tcpumask_set_cpu(i, &cpu_online);\n\t\t}\n\t}\n\n\tcpus_all_up = 1;\n\twmb();\n}\n\nvoid smp_init(void)\n{\n\tint i;\n\tstruct smp_call_data *cd;\n\n\tsmp_affinity_id = (uint64_t *)&__smp_affinity_id;\n\tmemset(smp_affinity_id, 0, sizeof(uint64_t) * NR_CPUS);\n\n\tcpumask_clearall(&cpu_online);\n\tcpumask_set_cpu(0, &cpu_online);\n\n\tfor (i = 0; i < NR_CPUS; i++) {\n\t\tcd = &get_per_cpu(smp_call_data, i);\n\t\tmemset(cd, 0, sizeof(struct smp_call_data));\n\t}\n\n\tarch_smp_init(smp_holding_address);\n\n\trequest_irq_percpu(SMP_FUNCTION_CALL_IRQ,\n\t\t\tsmp_function_call_handler, 0,\n\t\t\t\"smp_function_call\", NULL);\n}\n"
  },
  {
    "path": "kernel/core/stdlib.c",
    "content": "/*\n * Copyright (c) 2003-2004 Fabrice Bellard\n * Copyright (c) 2006 Intel Corporation\n * Copyright (c) 2007 Keir Fraser, XenSource Inc\n * Copyright (c) 2008 Intel Corporation\n * Copyright 2009 Red Hat, Inc. and/or its affiliates.\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/types.h>\n#include <minos/stdlib.h>\n#include <minos/bitops.h>\n\n#if 0\nuint64_t div64_u64(uint64_t dividend, uint64_t divisor)\n{\n\tuint32_t high = divisor >> 32;\n\tuint64_t quot;\n\n\tif (high == 0) {\n\t\tquot = div_u64(dividend, divisor);\n\t} else {\n\t\tint n = 1 + fls(high);\n\t\tquot = div_u64(dividend >> n, divisor >> n);\n\n\t\tif (quot != 0)\n\t\t\tquot--;\n\t\tif ((dividend - quot * divisor) >= divisor)\n\t\t\tquot++;\n\t}\n\n\treturn quot;\n}\n#endif\n\n/*\n * Compute with 96 bit intermediate result: (a*b)/c\n */\nuint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)\n{\n\tunion {\n\t\tuint64_t ll;\n\t\tstruct {\n\t\t\tuint32_t low, high;\n\t\t} l;\n\t} u, res;\n\tuint64_t rl, rh;\n\n\tu.ll = a;\n\trl = (uint64_t)u.l.low * (uint64_t)b;\n\trh = (uint64_t)u.l.high * (uint64_t)b;\n\trh += (rl >> 32);\n\tres.l.high = div64_u64(rh, c);\n\tres.l.low = div64_u64(((mod_64(rh, c) << 32) + (rl & 0xffffffff)), c);\n\treturn res.ll;\n}\n"
  },
  {
    "path": "kernel/core/string.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/types.h>\n#include <minos/string.h>\n#include <minos/errno.h>\n#include <minos/varlist.h>\n#include <minos/console.h>\n\n#define PRINTF_DEC\t\t0X0001\n#define PRINTF_HEX\t\t0x0002\n#define PRINTF_OCT\t\t0x0004\n#define PRINTF_BIN\t\t0x0008\n#define PRINTF_POINTER\t\t0x0010\n#define PRINTF_MASK\t\t(0xff)\n#define PRINTF_UNSIGNED\t\t0X0100\n#define PRINTF_SIGNED\t\t0x0200\n#define PRINTF_LONG\t\t0x0400\n\ntypedef char *(*vsprintf_t)(char *dst, const char *src, int size);\n\nlong absolute(long num)\n{\n\tif (num > 0)\n\t\treturn num;\n\treturn (~num) + 1;\n}\n\nlong num_to_str(char *buf, unsigned long num, int b)\n{\n\tstatic char hex[] =\"0123456789abcdef\";\n\tlong m, len, res;\n\tchar tmp_buf[64];\n\tchar *tmp = tmp_buf;\n\tint bdho = b;\n\n\tif (bdho == 32)\n\t\tbdho = 16;\n\n\tmemset(tmp_buf, '0', 16);\n\n\tdo {\n\t\tm = num % bdho;\n\t\tnum = num / bdho;\n\t\t*tmp++ = hex[m];\n\t} while (num >= bdho);\n\n\tif (num != 0)\n\t\t*tmp++ = hex[num];\n\n\tif (b == 32)\n\t\tres = len = 16;\n\telse\n\t\tres = len = tmp - tmp_buf;\n\n\twhile (len > 0) {\n\t\t*buf++ = tmp_buf[len - 1];\n\t\tlen--;\n\t}\n\n\treturn res;\n}\n\n#define xxxtoa(buf, num)\t\t\\\n({\t\t\t\t\t\\\n\tint tmp = 0;\t\t\t\\\n\t\t\t\t\t\\\n\tif ((num) < 0) {\t\t\\\n\t\tnum = ~num + 1;\t\t\\\n\t\t*buf++ = '-';\t\t\\\n\t\ttmp = 1;\t\t\\\n\t}\t\t\t\t\\\n\t\t\t\t\t\\\n\ttmp + num_to_str(buf, num, 10);\t\\\n})\n\nlong ltoa(char *buf, long num)\n{\n\treturn xxxtoa(buf, num);\n}\n\nlong itoa(char *buf, int num)\n{\n\treturn xxxtoa(buf, num);\n}\n\nlong ultoa(char *buf, unsigned long num)\n{\n\treturn num_to_str(buf, num, 10);\n}\n\nlong uitoa(char *buf, unsigned int num)\n{\n\treturn num_to_str(buf, num, 10);\n}\n\nlong hextoa(char *buf, unsigned long num)\n{\n\treturn num_to_str(buf, num, 16);\n}\n\nlong octtoa(char *buf, unsigned long num)\n{\n\treturn num_to_str(buf, num, 8);\n}\n\nlong bintoa(char *buf, unsigned long num)\n{\n\treturn num_to_str(buf, num, 2);\n}\n\nlong ptoa(char *buf, unsigned long num)\n{\n\treturn num_to_str(buf, num, 32);\n}\n\nchar *strncpy(char *des, const char *src, int len)\n{\n\tchar *tmp = des;\n\tint i;\n\n\tif (des == NULL || src == NULL)\n\t\treturn NULL;\n\n\tfor (i = 0; i < len; i++) {\n\t\tdes[i] = src[i];\n\t}\n\n\treturn tmp;\n}\n\nint numbric(char *buf, unsigned long num, int flag)\n{\n\tint len = 0;\n\n\tswitch (flag & PRINTF_MASK) {\n\tcase PRINTF_DEC:\n\t\tif (flag & PRINTF_SIGNED) {\n\t\t\tif (flag & PRINTF_LONG)\n\t\t\t\tlen = ltoa(buf, (long)num);\n\t\t\telse\n\t\t\t\tlen = itoa(buf, (int)num);\n\t\t} else {\n\t\t\tif (flag & PRINTF_LONG)\n\t\t\t\tlen = ultoa(buf, num);\n\t\t\telse\n\t\t\t\tlen = uitoa(buf, (unsigned int)num);\n\t\t}\n\t\tbreak;\n\tcase PRINTF_HEX:\n\t\tlen = hextoa(buf, num);\n\t\tbreak;\n\tcase PRINTF_OCT:\n\t\tlen = octtoa(buf, num);\n\t\tbreak;\n\tcase PRINTF_BIN:\n\t\tlen = bintoa(buf, num);\n\t\tbreak;\n\tcase PRINTF_POINTER:\n\t\tlen = ptoa(buf, num);\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn len;\n}\n\nstatic inline char *console_vsprintf(char *dst, const char *src, int size)\n{\n\tint i;\n\n\tfor (i = 0; i < size; i++)\n\t\tconsole_putc(src[i]);\n\n\treturn (dst + size);\n}\n\nstatic inline char *memory_vsprintf(char *dst, const char *src, int size)\n{\n\tmemcpy(dst, src, size);\n\n\treturn (dst + size);\n}\n\n#define PRINT_ALIGN_CHAR(str, align, len)\t\t\t\t\\\n({\t\t\t\t\t\t\t\t\t\\\n \tint index;\t\t\t\t\t\t\t\\\n\tif (align && (align > len)) {\t\t\t\t\t\\\n\t\tfor (index = 0; index < (align - len); index++)\t\t\\\n\t\t\tstr = vst(str, \" \", 1);\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n})\n\nint vsprintf(char *buf, const char *fmt, va_list arg)\n{\n\tchar *str = buf, *tmp;\n\tint len, ch, align, i;\n\tchar num_buf[96];\t\t// 96 is enough for number\n\tunsigned long unumber;\n\tint flag = 0;\n\tvsprintf_t vst;\n\n\tvst = (buf == NULL) ? console_vsprintf : memory_vsprintf;\n\n\tfor (str = buf; *fmt; fmt++) {\n\t\talign = 0;\n\t\tif (*fmt != '%') {\n\t\t\tstr = vst(str, fmt, 1);\n\t\t\tcontinue;\n\t\t}\n\n\t\tfmt++;\n\n\t\tif (is_digit(*fmt)) {\n\t\t\talign = *fmt - '0';\n\t\t\tfmt++;\n\t\t}\n\n\t\tswitch (*fmt) {\n\t\tcase 'l':\n\t\t\t/*\n\t\t\t * only support %ld %lx or %3ld %3lx style.\n\t\t\t */\n\t\t\tfmt++;\n\t\t\tch = *fmt;\n\t\t\tif ((ch != 'd') && (ch != 'x')) {\n\t\t\t\ti = 0;\n\t\t\t\tnum_buf[i++] = '%';\n\t\t\t\tif (align)\n\t\t\t\t\tnum_buf[i++]= align + '0';\n\t\t\t\tnum_buf[i++] = 'l';\n\t\t\t\tnum_buf[i++] = ch;\n\t\t\t\tstr = vst(str, num_buf, i);\n\t\t\t\tcontinue;\n\t\t\t} else {\n\t\t\t\tif (ch == 'd')\n\t\t\t\t\tflag |= PRINTF_LONG | PRINTF_DEC;\n\t\t\t\telse\n\t\t\t\t\tflag |= PRINTF_LONG | PRINTF_HEX;\n\t\t\t\tbreak;\n\t\t\t}\n\t\tcase 'd':\n\t\t\tflag |= PRINTF_DEC | PRINTF_SIGNED;\n\t\t\tbreak;\n\t\tcase 'p':\n\t\t\tlen = 0;\n\t\t\tflag |= PRINTF_POINTER | PRINTF_UNSIGNED;\n\t\t\tbreak;\n\t\tcase 'x':\n\t\t\tflag |= PRINTF_HEX | PRINTF_UNSIGNED;\n\t\t\tbreak;\n\t\tcase 'u':\n\t\t\tflag |= PRINTF_DEC | PRINTF_UNSIGNED;\n\t\t\tbreak;\n\t\tcase 's':\n\t\t\tlen = strlen(tmp = va_arg(arg, char *));\n\t\t\tPRINT_ALIGN_CHAR(str, align, len);\n\t\t\tstr = vst(str, (const char *)tmp, len);\n\t\t\tcontinue;\n\t\tcase 'c':\n\t\t\tPRINT_ALIGN_CHAR(str, align, 1);\n\t\t\tch = (char)(va_arg(arg, int));\n\t\t\tstr = vst(str, (const char *)&ch, 1);\n\t\t\tcontinue;\n\t\tcase 'o':\n\t\t\tflag |= PRINTF_DEC | PRINTF_SIGNED;\n\t\t\tbreak;\n\t\tcase '%':\n\t\t\tif (align) {\n\t\t\t\tstr = vst(str, \"%\", 1);\n\t\t\t\talign = align + '0';\n\t\t\t\tstr = vst(str, (char *)&align, 1);\n\t\t\t}\n\t\t\tstr = vst(str, \"%\", 1);\n\t\t\tcontinue;\n\t\tdefault:\n\t\t\tstr = vst(str, \"%\", 1);\n\t\t\tif (align) {\n\t\t\t\talign = align + '0';\n\t\t\t\tstr = vst(str, (char *)&align, 1);\n\t\t\t}\n\t\t\tstr = vst(str, fmt, 1);\n\t\t\tcontinue;\n\t\t}\n\n\t\tunumber = va_arg(arg, unsigned long);\n\t\tlen = numbric(num_buf, unumber, flag);\n\t\tPRINT_ALIGN_CHAR(str, align, len);\n\t\tstr = vst(str, num_buf, len);\n\n\t\tflag = 0;\n\t}\n\n\t/*\n\t * terminated with 0\n\t */\n\tch = 0;\n\tvst(str, (const char *)&ch, 1);\n\n\treturn str - buf;\n}\n\nint sprintf(char *str, const char *format, ...)\n{\n\tva_list arg;\n\tint count;\n\n\tif (!str)\n\t\treturn -EINVAL;\n\n\tva_start(arg, format);\n\tcount = vsprintf(str, format, arg);\n\tva_end(arg);\n\n\treturn count;\n}\n\n#if 0\nint strlen(char *buf)\n{\n\tint len = 0;\n\n\tif (buf == NULL)\n\t\treturn -1;\n\n\twhile (*buf++) {\n\t\tlen++;\n\t}\n\n\treturn len;\n}\n\nchar *strcpy(char *des, char *src)\n{\n\tchar *tmp = des;\n\n\tif (des == NULL || src == NULL)\n\t\treturn NULL;\n\n\twhile ((*des++=*src++) != '\\0');\n\n\treturn tmp;\n}\n\nint strcmp(const char *src, const char *dst)\n{\n\tint ret = 0;\n\n\twhile (!(ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst) {\n\t\t++src, ++dst;\n\t}\n\n\tif (ret < 0)\n\t\tret = -1;\n\telse if (ret > 0)\n\t\tret = 1;\n\n\treturn (ret);\n}\n\nint memcmp(const char *src, const char *dst, size_t size)\n{\n\tint i;\n\tchar ret;\n\n\tif (size == 0)\n\t\treturn -EINVAL;\n\n\tfor (i = 0; i < size; i++) {\n\t\tif (src[i] != dst[i]) {\n\t\t\tret = src[i] - dst[i];\n\t\t\tif (ret < 0)\n\t\t\t\treturn -1;\n\t\t\telse if (ret > 0)\n\t\t\t\treturn 1;\n\t\t}\n\t}\n\n\treturn 0;\n}\n\nint strncmp(const char *src, const char *dst, int n)\n{\n\tint ret = 0;\n\n\twhile (n && (!(ret = *(unsigned char *)src - *(unsigned char *)dst))) {\n\t\t++src, ++dst;\n\t\tn--;\n\t}\n\n\tif (ret < 0)\n\t\tret = -1;\n\telse if (ret > 0)\n\t\tret = 1;\n\n\treturn (ret);\n}\n\nchar *strchr(char *src, char ch)\n{\n\tfor (; *src != (char)ch; ++src)\n\t\tif (*src == '\\0')\n\t\t\treturn NULL;\n\treturn (char *)src;\n}\n\nint memcpy(void *target, void *source, int size)\n{\n\tchar *t = (char *)target;\n\tchar *s = (char *)source;\n\tint old_size = size;\n\n\tif(size <= 0)\n\t\treturn 0;\n\n\twhile (size--)\n\t\t*t++ = *s++;\n\n\treturn old_size;\n}\n\nvoid memset(char *base, char ch, int size)\n{\n\tint i;\n\n\tfor (i = 0; i < size; i++) {\n\t\t*(base + i) = ch;\n\t}\n}\n#endif\n\n#define TOLOWER(x)\t((x) | 0x20)\n\n#define isdigit(ch)\t((ch >= '0') && (ch <= '9'))\n#define isxdigit(ch)\t(isdigit(ch) || ((ch >= 'a') && (ch <= 'f')))\n\nunsigned long strtoul(const char *cp, char **endp, unsigned int base)\n{\n\tunsigned long result = 0;\n\n\tif (!base)\n\t\tbase = 10;\n\n\tif (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')\n\t\tcp += 2;\n\n\twhile (isxdigit(*cp)) {\n\t\tunsigned int value;\n\n\t\tvalue = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;\n\t\tif (value >= base)\n\t\t\tbreak;\n\t\tresult = result * base + value;\n\t\tcp++;\n\t}\n\n\tif (endp)\n\t\t*endp = (char *)cp;\n\n\treturn result;\n}\n\nchar *strsep(char **stringp, const char *delim)\n{\n\tchar *s;\n\tconst char *spanp;\n\tint c, sc;\n\tchar *tok;\n\n\tif ((s = *stringp)== NULL)\n\t\treturn (NULL);\n\n\tfor (tok = s;;) {\n\t\tc = *s++;\n\t\tspanp = delim;\n\n\t\tdo {\n\t\t\tif ((sc =*spanp++) == c) {\n\t\t\t\tif (c == 0)\n\t\t\t\t\ts = NULL;\n\t\t\t\telse\n\t\t\t\t\ts[-1] = 0;\n\t\t\t\t*stringp = s;\n\t\t\t\treturn (tok);\n\t\t\t}\n\t\t} while (sc != 0);\n\t}\n}\n"
  },
  {
    "path": "kernel/core/task.c",
    "content": "/*\n * Copyright (C) 2019 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/sched.h>\n#include <minos/mm.h>\n#include <minos/atomic.h>\n#include <minos/task.h>\n\nstatic DEFINE_SPIN_LOCK(tid_lock);\nstatic DECLARE_BITMAP(tid_map, OS_NR_TASKS);\nstruct task *os_task_table[OS_NR_TASKS];\nstatic LIST_HEAD(task_list);\n\n/* idle task needed be static defined */\nstruct task idle_tasks[NR_CPUS];\nstatic DEFINE_PER_CPU(struct task *, idle_task);\n\n#define TASK_INFO_INIT(__ti, task) \t\t\\\n\tdo {\t\t\t\t\t\\\n\t\t(__ti)->preempt_count = 0; \t\\\n\t\t(__ti)->flags = 0;\t\t\\\n\t} while (0)\n\nstatic int alloc_tid(void)\n{\n\tint tid = -1;\n\n\tspin_lock(&tid_lock);\n\n\ttid = find_next_zero_bit(tid_map, OS_NR_TASKS, 1);\n\tif (tid >= OS_NR_TASKS)\n\t\ttid = -1;\n\telse\n\t\tset_bit(tid, tid_map);\n\n\tspin_unlock(&tid_lock);\n\n\treturn tid;\n}\n\nstatic int request_tid(int tid)\n{\n\tBUG_ON((tid <= 0) || (tid >= OS_NR_TASKS), \"no such tid %d\\n\", tid);\n\treturn !test_and_set_bit(tid, tid_map);\n}\n\nstatic void release_tid(int tid)\n{\n\tASSERT((tid < OS_NR_TASKS) && (tid > 0));\n\tos_task_table[tid] = NULL;\n\tsmp_wmb();\n\tclear_bit(tid, tid_map);\n}\n\nstatic int tid_early_init(void)\n{\n\t/*\n\t * tid is reserved for system use.\n\t */\n\tset_bit(0, tid_map);\n\n\treturn 0;\n}\nearly_initcall(tid_early_init);\n\nstatic void task_timeout_handler(unsigned long data)\n{\n\tstruct task *task = (struct task *)data;\n\n\twake_up_timeout(task);\n\tset_need_resched();\n}\n\nstatic void task_init(struct task *task, char *name,\n\t\tvoid *stack, uint32_t stk_size, int prio,\n\t\tint tid, int aff, unsigned long opt, void *arg)\n{\n\t/*\n\t * idle task is setup by create_idle task, skip\n\t * to setup the stack information of idle task, by\n\t * default the kernel stack will set to stack top.\n\t */\n\tif (!(opt & TASK_FLAGS_IDLE)) {\n\t\ttask->stack_bottom = stack;\n\t\ttask->stack_top = stack + stk_size;\n\t\ttask->stack_base = task->stack_top;\n\n\t\tTASK_INFO_INIT(&task->ti, task);\n\t}\n\n\ttask->tid = tid;\n\ttask->prio = prio;\n\ttask->pend_state = 0;\n\ttask->flags = opt;\n\ttask->pdata = arg;\n\ttask->affinity = aff;\n\ttask->run_time = TASK_RUN_TIME;\n\tspin_lock_init(&task->s_lock);\n\ttask->state = TASK_STATE_SUSPEND;\n\ttask->cpu = -1;\n\n\tinit_timer(&task->delay_timer, task_timeout_handler,\n\t\t\t(unsigned long)task);\n\tos_task_table[tid] =  task;\n\n\tif (name)\n\t\tstrncpy(task->name, name, MIN(strlen(name), TASK_NAME_SIZE));\n\telse\n\t\tsprintf(task->name, \"task%d\", tid);\n}\n\nstatic struct task *do_create_task(char *name,\n\t\t\t\t  task_func_t func,\n\t\t\t\t  uint32_t ssize,\n\t\t\t\t  int prio,\n\t\t\t\t  int tid,\n\t\t\t\t  int aff,\n\t\t\t\t  unsigned long opt,\n\t\t\t\t  void *arg)\n{\n\tsize_t stk_size = PAGE_BALIGN(ssize);\n\tstruct task *task;\n\tvoid *stack = NULL;\n\n\t/*\n\t * allocate the task's kernel stack\n\t */\n\ttask = zalloc(sizeof(struct task));\n\tif (!task) {\n\t\tpr_err(\"no more memory for task\\n\");\n\t\treturn NULL;\n\t}\n\n\tstack = get_free_pages(PAGE_NR(stk_size), GFP_KERNEL);\n\tif (!stack) {\n\t\tpr_err(\"no more memory for task stack\\n\");\n\t\tfree(task);\n\t\treturn NULL;\n\t}\n\n\ttask_init(task, name, stack, stk_size, prio, tid, aff, opt, arg);\n\n\treturn task;\n}\n\nstatic void task_create_hook(struct task *task, void *pdata)\n{\n\tdo_hooks((void *)task, pdata, OS_HOOK_CREATE_TASK);\n}\n\nvoid task_exit_from_user(gp_regs *regs)\n{\n       struct task *task = current;\n\n       ASSERT(!(task->flags & TASK_FLAGS_KERNEL));\n       if (task->exit_from_user)\n               task->exit_from_user(task, regs);\n}\n\nvoid task_return_to_user(gp_regs *regs)\n{\n\tstruct task *task = current;\n\tunsigned long flags = task->ti.flags;\n\n\tASSERT(!(current->flags & TASK_FLAGS_KERNEL));\n\ttask->ti.flags &= ~(flags | (__TIF_NEED_STOP | __TIF_NEED_FREEZE));\n\tsmp_wmb();\n\n\tif (flags & __TIF_NEED_STOP)\n\t\ttask->state = TASK_STATE_STOP;\n\telse if (flags & __TIF_NEED_FREEZE)\n\t\ttask->state = TASK_STATE_SUSPEND;\n\n\tif (task->state != TASK_STATE_RUNNING) {\n\t\tsched();\n\t\tpanic(\"%s %d: should not be here\\n\", __func__, __LINE__);\n\t}\n\n\tif (task->return_to_user)\n\t\ttask->return_to_user(task, regs);\n}\n\nvoid do_release_task(struct task *task)\n{\n\tdo_hooks(task, NULL, OS_HOOK_RELEASE_TASK);\n\n\tarch_release_task(task);\n\tfree_pages(task->stack_bottom);\n\tfree(task);\n\n\t/*\n\t * this function can not be called at interrupt\n\t * context, use release_task is more safe\n\t */\n\trelease_tid(task->tid);\n}\n\nstruct task *__create_task(char *name,\n\t\t\ttask_func_t func,\n\t\t\tuint32_t stk_size,\n\t\t\tvoid *usp,\n\t\t\tint prio,\n\t\t\tint aff,\n\t\t\tunsigned long opt,\n\t\t\tvoid *arg)\n{\n\tstruct task *task;\n\tint tid;\n\n\tif ((aff >= NR_CPUS) && (aff != TASK_AFF_ANY)) {\n\t\tpr_warn(\"task %s afinity will set to 0x%x\\n\",\n\t\t\t\tname, TASK_AFF_ANY);\n\t\taff = TASK_AFF_ANY;\n\t}\n\n\tif ((prio >= OS_PRIO_IDLE) || (prio < 0)) {\n\t\tpr_warn(\"wrong task prio %d fallback to %d\\n\",\n\t\t\t\tprio, OS_PRIO_DEFAULT_6);\n\t\tprio = OS_PRIO_DEFAULT_6;\n\t}\n\n\ttid = alloc_tid();\n\tif (tid < 0)\n\t\treturn NULL;\n\n\tpreempt_disable();\n\n\ttask = do_create_task(name, func, stk_size, prio,\n\t\t\ttid, aff, opt, arg);\n\tif (!task) {\n\t\trelease_tid(tid);\n\t\tpreempt_enable();\n\t\treturn NULL;\n\t}\n\n\ttask_create_hook(task, arg);\n\n\tarch_init_task(task, (void *)func, usp, task->pdata);\n\n\t/*\n\t * start the task if need auto started.\n\t */\n\tif (!(task->flags & TASK_FLAGS_NO_AUTO_START))\n\t\ttask_ready(task, 0);\n\n\tpreempt_enable();\n\n\tif (os_is_running())\n\t\tsched();\n\n\treturn task;\n}\n\nstruct task *create_task(char *name,\n\t\ttask_func_t func,\n\t\tsize_t stk_size,\n\t\tvoid *usp,\n\t\tint prio,\n\t\tint aff,\n\t\tunsigned long opt,\n\t\tvoid *arg)\n{\n\tif (prio < 0) {\n\t\tif (opt & OS_PRIO_VCPU)\n\t\t\tprio = OS_PRIO_VCPU;\n\t\telse if (opt & (TASK_FLAGS_SRV | TASK_FLAGS_DRV))\n\t\t\tprio = OS_PRIO_SRV;\n\t\telse\n\t\t\tprio = OS_PRIO_DEFAULT;\n\t}\n\n\treturn __create_task(name, func, stk_size, usp,\n\t\t\tprio, aff, opt, arg);\n}\n\nint create_idle_task(void)\n{\n\tstruct task *task;\n\tchar task_name[32];\n\tint aff = smp_processor_id();\n\tint tid = OS_NR_TASKS - 1 - aff;\n\tstruct pcpu *pcpu = get_pcpu();\n\n\ttask = get_cpu_var(idle_task);\n\tBUG_ON(!request_tid(tid), \"tid is wrong for idle task cpu%d\\n\", tid);\n\n\tsprintf(task_name, \"idle/%d\", aff);\n\n\ttask_init(task, task_name, NULL, 0, OS_PRIO_IDLE, tid, aff,\n\t\t\tTASK_FLAGS_IDLE | TASK_FLAGS_KERNEL, NULL);\n\n\ttask->stack_top = (void *)ptov(minos_stack_top) -\n\t\t(aff << CONFIG_TASK_STACK_SHIFT);\n\ttask->stack_bottom = task->stack_top - TASK_STACK_SIZE;\n\ttask->state = TASK_STATE_RUNNING;\n\ttask->cpu = aff;\n\ttask->run_time = 0;\n\n\tpcpu->running_task = task;\n\tset_current_task(task);\n\n\t/* call the hooks for the idle task */\n\ttask_create_hook(task, NULL);\n\n\tlist_add_tail(&pcpu->ready_list[task->prio], &task->state_list);\n\tpcpu->local_rdy_grp |= BIT(task->prio);\n\tpcpu->idle_task = task;\n\n\treturn 0;\n}\n\nvoid os_for_all_task(void (*hdl)(struct task *task))\n{\n        struct task *task;\n\tint idx;\n\n\t// get the tid_lock ?\n\tfor_each_set_bit(idx, tid_map, OS_NR_TASKS) {\n\t\ttask = os_task_table[idx];\n\t\tif (!task)\n\t\t\tcontinue;\n\t\thdl(task);\n\t}\n}\n\n/*\n * for preempt_disable and preempt_enable need\n * to set the current task at boot stage\n */\nstatic int __init_text task_early_init(void)\n{\n\tstruct task *task;\n\tint i = smp_processor_id();\n\n\ttask = &idle_tasks[i];\n\tmemset(task, 0, sizeof(struct task));\n\tget_per_cpu(idle_task, i) = task;\n\n\t/* init the task info for the thread */\n\tTASK_INFO_INIT(current_task_info, task);\n\n\treturn 0;\n}\nearly_initcall_percpu(task_early_init);\n\nint create_percpu_tasks(char *name, task_func_t func, \n\t\tint prio, unsigned long flags, void *pdata)\n{\n\tstruct task *ret;\n\tint cpu;\n\n\tfor_each_online_cpu(cpu) {\n\t\tret = create_task(name, func, TASK_STACK_SIZE, NULL,\n\t\t\t\tprio, cpu, flags | TASK_FLAGS_PERCPU, pdata);\n\t\tif (ret == NULL)\n\t\t\tpr_err(\"create [%s] fail on cpu%d\\n\", name, cpu);\n\t}\n\n\treturn 0;\n}\n\nstruct task *create_vcpu_task(char *name, task_func_t func, int aff,\n\t\tunsigned long flags, void *vcpu)\n{\n#define VCPU_TASK_FLAG (TASK_FLAGS_VCPU | TASK_FLAGS_NO_AUTO_START)\n        return create_task(name, func, TASK_STACK_SIZE,\n\t\t\tNULL, OS_PRIO_VCPU, aff,\n\t\t\tflags | VCPU_TASK_FLAG, vcpu);\n}\n\nstruct task *create_kthread(char *name, task_func_t func, int prio,\n\t\tint aff, unsigned long opt, void *arg)\n{\n\treturn create_task(name, func, TASK_STACK_SIZE,\n\t\t\tNULL, prio, aff, opt | TASK_FLAGS_KERNEL, arg);\n}\n"
  },
  {
    "path": "kernel/core/timer.c",
    "content": "/*\n *\n *  Copyright (C) 1991, 1992  Linus Torvalds\n *\n *  1997-01-28  Modified by Finn Arne Gangstad to make timers scale better.\n *\n *  1997-09-10  Updated NTP code according to technical memorandum Jan '96\n *              \"A Kernel Model for Precision Timekeeping\" by Dave Mills\n *  1998-12-24  Fixed a xtime SMP race (we need the xtime_lock rw spinlock to\n *              serialize accesses to xtime/lost_ticks).\n *                              Copyright (C) 1998  Andrea Arcangeli\n *  1999-03-10  Improved NTP compatibility by Ulrich Windl\n *  2002-05-31\tMove sys_sysinfo here and make its locking sane, Robert Love\n *  2000-10-05  Implemented scalable SMP per-CPU timer handling.\n *                              Copyright (C) 2000, 2001, 2002  Ingo Molnar\n *  2018-05-02  Changed for Minos hypervisor\n */\n\n#include <minos/minos.h>\n#include <minos/list.h>\n#include <minos/timer.h>\n#include <minos/softirq.h>\n#include <minos/time.h>\n#include <minos/arch.h>\n\n#define TIMER_PRECISION 1000000 // 1ms 1000ns\n\nDEFINE_PER_CPU(struct raw_timer, timers);\n\n#define DEFAULT_TIMER_MARGIN\t(TIMER_PRECISION / 2)\n\nvoid soft_timer_interrupt(void)\n{\n\tstruct raw_timer *timers = &get_cpu_var(timers);\n\tstruct timer *timer, *next_timer = NULL;\n\tstruct list_head tmp_head;\n\tuint64_t now;\n\ttimer_func_t fn;\n\tunsigned long data;\n\n\traw_spin_lock(&timers->lock);\n\tinit_list(&tmp_head);\n\tnow = NOW();\n\n\twhile (!is_list_empty(&timers->active)) {\n\t\ttimer = list_first_entry(&timers->active, struct timer, entry);\n\t\tif (timer->expires <= (now + DEFAULT_TIMER_MARGIN)) {\t\n\t\t\t/* \n\t\t\t * need to release the spin lock to avoid\n\t\t\t * dead lock because on the timer handler\n\t\t\t * function the task may aquire other spinlocks\n\t\t\t * so load the function and data on the stack.\n\t\t\t */\n\t\t\ttimers->running_timer = timer;\n\t\t\tsmp_wmb();\n\n\t\t\tfn = timer->function;\n\t\t\tdata = timer->data;\n\t\t\tlist_del(&timer->entry);\n\t\t\ttimer->entry.next = NULL;\n\t\t\traw_spin_unlock(&timers->lock);\n\n\t\t\tif (!timer->stop) {\n\t\t\t\tfn(data);\n\t\t\t\tmb();\n\t\t\t}\n\n\t\t\ttimers->running_timer = NULL;\n\t\t\traw_spin_lock(&timers->lock);\n\t\t} else {\n\t\t\t/*\n\t\t\t * need to be careful one case, when do the expires\n\t\t\t * handler, the spin lock will be released, then other\n\t\t\t * cpu may get this lock to delete the timer from the\n\t\t\t * active list, if use the .next member to get the next\n\t\t\t * timer then there will be issues, so if this timer not\n\t\t\t * expires, then add it to the tmp timer list head, at\n\t\t\t * the end of this function, switch the actvie to the head\n\t\t\t */\n\t\t\tif (!next_timer || (next_timer->expires > timer->expires))\n\t\t\t\tnext_timer = timer;\n\t\t\tlist_del(&timer->entry);\n\t\t\tlist_add_tail(&tmp_head, &timer->entry);\n\t\t}\n\t}\n\n\tif (!is_list_empty(&timers->active))\n\t\tpanic(\"error in timers->active list\\n\");\n\n\t/*\n\t * swap the tmp head to the active head\n\t */\n\tif (!is_list_empty(&tmp_head)) {\n\t\ttmp_head.next->pre = &timers->active;\n\t\ttimers->active.next = tmp_head.next;\n\t\ttmp_head.pre->next = &timers->active;\n\t\ttimers->active.pre = tmp_head.pre;\n\t\twmb();\n\t}\n\n\traw_spin_unlock(&timers->lock);\n\n\t/*\n\t * already in interrupt context, will not be interrupted.\n\t */\n\ttimers->next_timer = next_timer;\n\tif (next_timer)\n\t\tenable_timer(next_timer->expires);\n}\n\nstatic inline int timer_pending(const struct timer * timer)\n{\n\treturn ((timer->entry.next) != NULL);\n}\n\nstatic int detach_timer(struct raw_timer *timers, struct timer *timer)\n{\n\tstruct list_head *entry = &timer->entry;\n\n\tif (timer_pending(timer)) {\n\t\tlist_del(entry);\n\t\tentry->next = NULL;\n\t}\n\n\treturn 0;\n}\n\nstatic int __mod_timer(struct timer *timer)\n{\n\tstruct raw_timer *timers = NULL;\n\tunsigned long flags;\n\tint cpu;\n\n\tpreempt_disable();\n\tcpu = smp_processor_id();\n\n\t/*\n\t * if the timer is not on the current cpu's\n\t * timers, need to migrate it to the current\n\t * cpu's timers list\n\t */\n\tASSERT(!((timer->cpu != -1) && (timer->cpu != cpu)));\n\ttimers = &get_per_cpu(timers, cpu);\n\n\tspin_lock_irqsave(&timers->lock, flags);\n\n\tdetach_timer(timers, timer);\n\ttimer->stop = 0;\n\ttimer->raw_timer = timers;\n\tsmp_wmb();\n\n\ttimer->cpu = cpu;\n\tlist_add_tail(&timers->active, &timer->entry);\n\n\t/*\n\t * reprogram the raw timer if the next expires bigger than\n\t * current (expires + DEFAULT_TIMER_MARGIN)\n\t */\n\tif (!timers->next_timer || (timers->next_timer->expires >\n\t\t\t\t(timer->expires + DEFAULT_TIMER_MARGIN))) {\n\t\ttimers->next_timer = timer;\n\t\tenable_timer(timer->expires);\n\t}\n\n\tspin_unlock_irqrestore(&timers->lock, flags);\n\tpreempt_enable();\n\n\treturn 0;\n}\n\nint mod_timer(struct timer *timer, uint64_t cval)\n{\n\tuint64_t now = NOW();\n\n\tif (cval < (now + TIMER_PRECISION))\n\t\ttimer->expires = now + TIMER_PRECISION;\n\telse\n\t\ttimer->expires = cval;\n\n\treturn __mod_timer(timer);\n}\n\nstatic int __start_delay_timer(struct timer *timer)\n{\n\tif (timer->timeout < TIMER_PRECISION)\n\t\ttimer->timeout = TIMER_PRECISION;\n\ttimer->expires = NOW() + timer->timeout;\n\n\treturn __mod_timer(timer);\n}\n\nvoid init_timer(struct timer *timer, timer_func_t fn, unsigned long data)\n{\n\tpreempt_disable();\n\ttimer->cpu = -1;\n\ttimer->entry.next = NULL;\n\ttimer->expires = 0;\n\ttimer->timeout = 0;\n\ttimer->function = fn;\n\ttimer->data = data;\n\ttimer->raw_timer = NULL;\n\tpreempt_enable();\n}\n\nint start_timer(struct timer *timer)\n{\n\treturn __start_delay_timer(timer);\n}\n\nvoid setup_timer(struct timer *timer, uint64_t tval)\n{\n\ttimer->timeout = tval;\n}\n\nvoid setup_and_start_timer(struct timer *timer, uint64_t tval)\n{\n\ttimer->timeout = tval;\n\tstart_timer(timer);\n}\n\nint stop_timer(struct timer *timer)\n{\n\tstruct raw_timer *timers = timer->raw_timer;\n\tunsigned long flags;\n\n\tif (timer->cpu == -1)\n\t\treturn 0;\n\n\ttimer->stop = 1;\n\tASSERT(timer->raw_timer != NULL);\n\tspin_lock_irqsave(&timers->lock, flags);\n\t/*\n\t * wait the timer finish the action if already\n\t * timedout.\n\t */\n\twhile (timers->running_timer == timer)\n\t\tcpu_relax();\n\n\tdetach_timer(timers, timer);\n\ttimer->cpu = -1;\n\ttimer->expires = 0;\n\tspin_unlock_irqrestore(&timers->lock, flags);\n\n\treturn 0;\n}\n\nstatic int init_raw_timers(void)\n{\n\tstruct raw_timer *timers;\n\tint i;\n\n\tfor (i = 0; i < CONFIG_NR_CPUS; i++) {\n\t\ttimers = &get_per_cpu(timers, i);\n\t\tinit_list(&timers->active);\n\t\ttimers->next_timer = NULL;\n\t\ttimers->running_timer = NULL;\n\t\tspin_lock_init(&timers->lock);\n\t}\n\n\treturn 0;\n}\narch_initcall(init_raw_timers);\n"
  },
  {
    "path": "kernel/drivers/Kconfig",
    "content": "menu \"Device Drivers\"\n\nsource \"drivers/irq-chips/Kconfig\"\nsource \"drivers/serial/Kconfig\"\n\nconfig DEVICE_TREE\n\tbool \"device tree libfdt support\"\n\tdefault y\n\nendmenu\n"
  },
  {
    "path": "kernel/drivers/Makefile",
    "content": "obj-$(CONFIG_SERIAL) \t\t+= serial/\nobj-y \t\t\t\t+= irq-chips/\nobj-$(CONFIG_DEVICE_TREE) \t+= of/\nobj-y \t\t\t\t+= device_id.o\nobj-y\t\t\t\t+= tty.o\nobj-y\t\t\t\t+= console.o\n"
  },
  {
    "path": "kernel/drivers/console.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/console.h>\n#include <minos/of.h>\n#include <minos/spinlock.h>\n#include <minos/sched.h>\n#include <minos/sem.h>\n\n#define MEM_CONSOLE_SIZE\t(2048)\n#define CONSOLE_INBUF_SIZE\t(2048)\n\nstatic int widx;\nstatic char mem_log_buf[MEM_CONSOLE_SIZE];\n\nstatic char console_inbuf[CONSOLE_INBUF_SIZE];\nstatic uint32_t inbuf_ridx, inbuf_widx;\n\nstatic sem_t console_sem;\n\n#define MEM_CONSOLE_IDX(idx)\t(idx & (MEM_CONSOLE_SIZE - 1))\n#define BUFIDX(idx)\t\t(idx & (CONSOLE_INBUF_SIZE - 1))\n\nstatic void mem_console_putc(char ch)\n{\n\tmem_log_buf[MEM_CONSOLE_IDX(widx++)] = ch;\n}\n\nstatic char mem_console_getc(void)\n{\n\treturn 0;\n}\nDEFINE_CONSOLE(mem_console, \"mem-console\", NULL,\n\t\tmem_console_putc, mem_console_getc);\n\nstatic struct console *console = &__console_mem_console;\n\nstruct console *get_console(char *name)\n{\n\textern unsigned long __console_start;\n\textern unsigned long __console_end;\n\tstruct console *console;\n\n\tif (!name)\n\t\treturn NULL;\n\n\tsection_for_each_item(__console_start, __console_end, console) {\n\t\tif (strcmp(console->name, name) == 0)\n\t\t\treturn console;\n\t}\n\n\treturn NULL;\n}\n\nvoid console_init(char *name)\n{\n\tint index;\n\n\tsem_init(&console_sem, 0);\n\n\tif (name)\n\t\tconsole = get_console(name);\n\tif (console->init)\n\t\tconsole->init(NULL);\n\n\t/* flush the string in the memory log buf */\n\tfor (index = 0; index < MEM_CONSOLE_IDX(widx); index++)\n\t\tconsole->putc(mem_log_buf[index]);\n}\n\nvoid console_putc(char ch)\n{\n\tconsole->putc(ch);\n}\n\nchar console_getc(void)\n{\n\treturn console->getc();\n}\n\nvoid console_recv(const char *buf, int cnt)\n{\n\tuint32_t widx;\n\tint i;\n\n\twidx = inbuf_widx;\n\trmb();\n\n\tfor (i = 0; i < cnt; i++)\n\t\tconsole_inbuf[BUFIDX(widx++)] = buf[i];\n\n\twmb();\n\tinbuf_widx = widx;\n\n\tsem_post(&console_sem);\n}\n\nvoid console_puts(char *buf, int len)\n{\n\tputs(buf, len);\n}\n\nint console_gets(char *buf, int max, uint32_t timeout)\n{\n\tuint32_t ridx, widx;\n\tlong i, copy;\n\n\tdo {\n\t\tridx = inbuf_ridx;\n\t\twidx = inbuf_widx;\n\t\trmb();\n\n\t\tASSERT((widx - ridx) <= CONSOLE_INBUF_SIZE);\n\t\tcopy = widx - ridx > max ? max : widx - ridx;\n\t\tif (copy > 0) {\n\t\t\tfor (i = 0; i < copy; i++)\n\t\t\t\tbuf[i] = console_inbuf[BUFIDX(ridx++)];\n\t\t\twmb();\n\t\t\tinbuf_ridx = ridx;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (timeout > 0)\n\t\t\tcopy = sem_pend(&console_sem, timeout);\n\t\telse\n\t\t\tbreak;\n\t} while (copy == 0);\n\n\treturn copy;\n}\n"
  },
  {
    "path": "kernel/drivers/device_id.c",
    "content": "/*\n * Copyright (C) 2018 - 2019 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/types.h>\n\nchar *gicv2_match_table[] = {\n\t\"arm,gicv2\",\n\t\"arm,gic-400\",\n\t\"arm,arm11mp-gic\",\n\t\"arm,arm1176jzf-devchip-gic\",\n\t\"arm,cortex-a15-gic\",\n\t\"arm,cortex-a9-gic\",\n\t\"arm,cortex-a7-gic\",\n\t\"qcom,msm-8660-qgic\",\n\t\"qcom,msm-qgic2\",\n\tNULL\n};\n\nchar *gicv3_match_table[] = {\n\t\"arm,gic-v3\",\n\tNULL\n};\n\nchar *bcmirq_match_table[] = {\n\t\"brcm,bcm2836-armctrl-ic\",\n\tNULL\n};\n\nchar *pl031_match_table[] = {\n\t\"arm,pl031\",\n\tNULL\n};\n\nchar *sp805_match_table[] = {\n\t\"arm,sp805\",\n\tNULL\n};\n\nchar *virtio_match_table[] = {\n\t\"virtio,mmio\",\n\tNULL\n};\n\nchar *aic_match_table[] = {\n\t\"aic\",\n\tNULL\n};\n\nchar *arm_arch_timer_match_table[] = {\n\t\"arm,armv8-timer\",\n\t\"arm,armv7-timer\",\n\tNULL,\n};\n"
  },
  {
    "path": "kernel/drivers/iommu/Kconfig",
    "content": "# SPDX-License-Identifier: GPL-2.0\n\nif VIRT\n\nmenu \"IOMMU drivers\"\n\nconfig IOMMU\n\tdef_bool y\n\nconfig IOMMU_IPMMU\n\tbool \"ipmmu driver\"\n\tdefault y if SOC_R8A7795\n\thelp\n\t  iommu driver for r8a7795\n\nendmenu\n\nendif\n\ncomment \"IOMMU drivers need virtualization support\"\n\tdepends on !VIRT\n"
  },
  {
    "path": "kernel/drivers/iommu/Makefile",
    "content": "obj-$(CONFIG_IOMMU_IPMMU) += ipmmu.o\nobj-$(CONFIG_IOMMU_IPMMU) += ipmmu-plat.o\n"
  },
  {
    "path": "kernel/drivers/iommu/ipmmu-plat.c",
    "content": "// SPDX-License-Identifier: GPL-2.0\n\n/*\n * Based on Renesas R-Car System Controller driver (rcar-sysc).\n */\n\n#include <asm/io.h>\n#include <minos/errno.h>\n#include <minos/mmu.h>\n#include <minos/of.h>\n\nstatic void *rcar_sysc_base = NULL;\n\n/* SYSC MMIO range */\n#define RCAR_SYSC_BASE\t\t0xe6180000\n#define RCAR_SYSC_SIZE\t\t0x400\n\n/*\n * These power domain indices match the numbers of the interrupt bits\n * representing the power areas in the various Interrupt Registers\n * (e.g. SYSCISR, Interrupt Status Register)\n */\n#define RCAR_GEN3_PD_A3VP\t9\n#define RCAR_GEN3_PD_A3VC\t14\n/* Always-on power area */\n#define RCAR_GEN3_PD_ALWAYS_ON\t32\n\n/* SYSC Common */\n#define SYSCSR\t\t\t0x00\t/* SYSC Status Register */\n#define SYSCISR\t\t\t0x04\t/* Interrupt Status Register */\n#define SYSCISCR\t\t0x08\t/* Interrupt Status Clear Register */\n#define SYSCIER\t\t\t0x0c\t/* Interrupt Enable Register */\n#define SYSCIMR\t\t\t0x10\t/* Interrupt Mask Register */\n\n/* SYSC Status Register */\n#define SYSCSR_PONENB\t\t1\t/* Ready for power resume requests */\n\n/* Power Control Register Offsets inside the register block for each domain */\n#define PWRSR_OFFS\t\t0x00\t/* Power Status Register */\n#define PWRONCR_OFFS\t\t0x0c\t/* Power Resume Control Register */\n#define PWRER_OFFS\t\t0x14\t/* Power Shutoff/Resume Error */\n\n#define SYSCSR_RETRIES\t\t1000\n#define SYSCSR_DELAY_US\t\t10\n\n#define PWRER_RETRIES\t\t1000\n#define PWRER_DELAY_US\t\t10\n\n#define SYSCISR_RETRIES\t\t1000\n#define SYSCISR_DELAY_US\t10\n\nstruct rcar_sysc_ch {\n\tconst char *name;\n\tu16 chan_offs;\t\t\t/* Offset of PWRSR register for this area */\n\tu8 chan_bit;\t\t\t/* Bit in PWR* (except for PWRUP in PWRSR) */\n\tu8 isr_bit;\t\t\t/* Bit in SYSCI*R */\n};\n\n/*\n * For the most of IPMMU-XX which are located in ALWAYS_ON power domain\n * we don't care at all. But some of them are located in other domains\n * and must be turned on once at boot.\n * Hopefully, the each of domains we are dealing with within this file\n * (A3VP, A3VP) is identically configured across all SoCs (H3, M3 and M3N).\n * This allow us not to introduce support for each SoC separately.\n */\nstatic const struct rcar_sysc_ch rcar_sysc_chs[2] = {\n\t{\n\t\t.name = \"A3VP\",\n\t\t.chan_offs = 0x340,\n\t\t.chan_bit = 0,\n\t\t.isr_bit = RCAR_GEN3_PD_A3VP,\n\t},\n\t{\n\t\t.name = \"A3VC\",\n\t\t.chan_offs = 0x380,\n\t\t.chan_bit = 0,\n\t\t.isr_bit = RCAR_GEN3_PD_A3VC,\n\t},\n};\n\nstatic int rcar_sysc_init(void)\n{\n\tu32 syscier, syscimr;\n\tint i;\n\n\t/*\n\t * As this function might be called more then once, just return if we\n\t * have already initialized sysc.\n\t */\n\tif (rcar_sysc_base)\n\t\treturn 0;\n\n\trcar_sysc_base = (void *)io_remap(RCAR_SYSC_BASE, RCAR_SYSC_SIZE);\n\tif (!rcar_sysc_base) {\n\t\tpr_err(\"failed to map SYSC MMIO range\\n\");\n\t\treturn -ENOMEM;\n\t}\n\n\tsyscier = 0;\n\tfor (i = 0; i < ARRAY_SIZE(rcar_sysc_chs); i++)\n\t\tsyscier |= BIT(rcar_sysc_chs[i].isr_bit);\n\n\t/*\n\t * Mask all interrupt sources to prevent the CPU from receiving them.\n\t * Make sure not to clear reserved bits that were set before.\n\t */\n\tsyscimr = readl(rcar_sysc_base + SYSCIMR);\n\tsyscimr |= syscier;\n\twritel(syscimr, rcar_sysc_base + SYSCIMR);\n\n\t/* SYSC needs all interrupt sources enabled to control power */\n\twritel(syscier, rcar_sysc_base + SYSCIER);\n\n\treturn 0;\n}\n\nstatic bool rcar_sysc_power_is_off(const struct rcar_sysc_ch *sysc_ch)\n{\n\tunsigned int status;\n\n\tstatus = readl(rcar_sysc_base + sysc_ch->chan_offs + PWRSR_OFFS);\n\tif (status & BIT(sysc_ch->chan_bit))\n\t\treturn true;\n\n\treturn false;\n}\n\nstatic int rcar_sysc_power_on(const struct rcar_sysc_ch *sysc_ch)\n{\n\tunsigned int status;\n\tint ret = 0, i, j;\n\n\twritel(BIT(sysc_ch->isr_bit), rcar_sysc_base + SYSCISCR);\n\n\t/* Submit power resume request until it was accepted */\n\tfor (i = 0; i < PWRER_RETRIES; i++) {\n\n\t\t/* Wait until SYSC is ready to accept a power request */\n\t\tfor (j = 0; j < SYSCSR_RETRIES; j++) {\n\t\t\tif (readl(rcar_sysc_base + SYSCSR) & BIT(SYSCSR_PONENB))\n\t\t\t\tbreak;\n\t\t\tudelay(SYSCSR_DELAY_US);\n\t\t}\n\n\t\tif (j == SYSCSR_RETRIES)\n\t\t\treturn -EAGAIN;\n\n\t\t/* Submit power resume request */\n\t\twritel(BIT(sysc_ch->chan_bit),\n\t\t       rcar_sysc_base + sysc_ch->chan_offs + PWRONCR_OFFS);\n\n\t\tstatus = readl(rcar_sysc_base + sysc_ch->chan_offs + PWRER_OFFS);\n\t\tif (!(status & BIT(sysc_ch->chan_bit)))\n\t\t\tbreak;\n\t\tudelay(PWRER_DELAY_US);\n\t}\n\n\tif (i == PWRER_RETRIES)\n\t\treturn -EIO;\n\n\t/* Wait until the power resume request has completed */\n\tfor (i = 0; i < SYSCISR_RETRIES; i++) {\n\t\tif (readl(rcar_sysc_base + SYSCISR) & BIT(sysc_ch->isr_bit))\n\t\t\tbreak;\n\t\tudelay(SYSCISR_DELAY_US);\n\t}\n\n\tif (i == SYSCISR_RETRIES)\n\t\tret = -EIO;\n\n\twritel(BIT(sysc_ch->isr_bit), rcar_sysc_base + SYSCISCR);\n\n\treturn ret;\n}\n\nstatic uint32_t ipmmu_get_mmu_pd(struct device_node *node)\n{\n\tuint32_t value[2];\n\tint ret;\n\n\tret = of_get_u32_array(node, \"power-domains\", value, ARRAY_SIZE(value));\n\tif (ret <= 0)\n\t\treturn -ENODEV;\n\n\treturn value[1];\n}\n\n/*\n * Some IPMMU-XX are not located in ALWAYS_ON power domain\n * (IPMMU-VP0, IPMMU-VC0 belong to A3xx power domains) and as the result\n * they are in power-off state during booting, therefore they must be\n * explicitly powered on before initializing.\n */\nint ipmmu_power_on(struct device_node *node)\n{\n\tint i, pd, ret = -ENODEV;\n\n\tpd = ipmmu_get_mmu_pd(node);\n\tif (pd < 0 || pd == RCAR_GEN3_PD_ALWAYS_ON)\n\t\treturn 0;\n\n\trcar_sysc_init();\n\n\tfor (i = 0; i < ARRAY_SIZE(rcar_sysc_chs); i++) {\n\t\tif (rcar_sysc_chs[i].isr_bit != pd)\n\t\t\tcontinue;\n\n\t\tif (!rcar_sysc_power_is_off(&rcar_sysc_chs[i])) {\n\t\t\tpr_notice(\"%s: %s domain is already powered on\\n\",\n\t\t\t\t  devnode_name(node), rcar_sysc_chs[i].name);\n\t\t\treturn 0;\n\t\t}\n\n\t\tret = rcar_sysc_power_on(&rcar_sysc_chs[i]);\n\t\tif (ret) {\n\t\t\tpr_err(\"%s: failed to power on %s domain\\n\",\n\t\t\t       devnode_name(node), rcar_sysc_chs[i].name);\n\t\t\tbreak;\n\t\t}\n\n\t\tpr_notice(\"%s: powered on %s domain\\n\", devnode_name(node),\n\t\t\t  rcar_sysc_chs[i].name);\n\t\treturn 0;\n\t}\n\n\treturn ret;\n}\n\n/*\n * Check if we will have to disable IPMMU TLB cache function of IPMMU caches\n * that belong to non ALWAYS_ON power domain (IPMMU-VP0, IPMMU-VC0 belong\n * to A3xx power domains) due to H/W restriction.\n * Required action will be performed right before enabling corresponding\n * IPMMU-XX.\n */\nbool ipmmu_is_mmu_tlb_disable_needed(struct device_node *node)\n{\n\tint i, pd;\n\n\tpd = ipmmu_get_mmu_pd(node);\n\tif (pd < 0 || pd == RCAR_GEN3_PD_ALWAYS_ON)\n\t\treturn false;\n\n\t/* Actually check among power domains we have already powered on */\n\tfor (i = 0; i < ARRAY_SIZE(rcar_sysc_chs); i++) {\n\t\tif (rcar_sysc_chs[i].isr_bit == pd)\n\t\t\treturn true;\n\t}\n\n\treturn false;\n}\n"
  },
  {
    "path": "kernel/drivers/iommu/ipmmu.c",
    "content": "// SPDX-License-Identifier: GPL-2.0\n\n#include <asm/io.h>\n#include <minos/irq.h>\n#include <virt/vm.h>\n#include <minos/of.h>\n#include <virt/iommu.h>\n\nextern int ipmmu_power_on(struct device_node *node);\nextern bool ipmmu_is_mmu_tlb_disable_needed(struct device_node *node);\n\n/*\n * Start of Minos specific code\n */\n\n/* Minos: Dummy iommu_domain */\nstruct iommu_domain {\n\tatomic_t ref;\n\t/*\n\t * Used to link iommu_domain contexts for a same VM.\n\t * There is at least one per-IPMMU to used by the VM.\n\t */\n\tstruct list_head list;\n};\n\n/* Minos: Describes informations required for a Minos VM */\nstruct vm_ipmmu {\n\tspinlock_t lock;\n\t/* List of context (i.e iommu_domain) associated to this VM */\n\tstruct list_head contexts;\n\tstruct iommu_domain *base_context;\n};\n\n#define to_vm_ipmmu(vm) ((struct vm_ipmmu *)(vm)->iommu.priv)\n#define to_node_ipmmu(node) ((struct node_ipmmu *)(node)->iommu.priv)\n\n/*\n * Start of Linux IPMMU code\n */\n\n#define IPMMU_CTX_MAX 8\n\n#define IPMMU_PER_DEV_MAX 4\n\nstruct ipmmu_device {\n\tstruct device_node *node;\n\tvoid *base;\n\tstruct list_head list;\n\tbool is_leaf;\n\tunsigned int num_utlbs;\n\tunsigned int num_ctx;\n\tspinlock_t lock;\t\t\t/* Protects ctx and domains[] */\n\tDECLARE_BITMAP(ctx, IPMMU_CTX_MAX);\n\tstruct ipmmu_domain *domains[IPMMU_CTX_MAX];\n};\n\nstruct ipmmu_domain {\n\t/* Cache IPMMUs the master device can be tied to */\n\tstruct ipmmu_device *mmus[IPMMU_PER_DEV_MAX];\n\tunsigned int num_mmus;\n\tstruct ipmmu_device *root;\n\tstruct iommu_domain io_domain;\n\n\tunsigned int context_id;\n\tspinlock_t lock;\t\t\t/* Protects mappings */\n\n\t/* Minos: VM associated to this configuration */\n\tstruct vm *vm;\n};\n\nstruct ipmmu_utlb {\n\t/* Cache IPMMU the uTLB is connected to */\n\tstruct ipmmu_device *mmu;\n\tunsigned int utlb;\n};\n\n/*\n * Minos: Information about each device stored in node->iommu.priv\n *\n * On Linux the dev->archdata.iommu only stores the arch specific information,\n * but, on Minos, we also have to store the iommu domain.\n */\nstruct node_ipmmu {\n\tstruct iommu_domain *io_domain;\n\n\t/* Cache IPMMUs the master device can be tied to */\n\tstruct ipmmu_device *mmus[IPMMU_PER_DEV_MAX];\n\tunsigned int num_mmus;\n\tstruct ipmmu_utlb *utlbs;\n\tunsigned int num_utlbs;\n\tstruct device_node *node;\n\tstruct list_head list;\n};\n\nstatic DEFINE_SPIN_LOCK(ipmmu_devices_lock);\nstatic LIST_HEAD(ipmmu_devices);\n\n#define to_ipmmu_domain(io_dom)                                                \\\n\t(container_of((io_dom), struct ipmmu_domain, io_domain))\n\n#define TLB_LOOP_TIMEOUT\t\t100\t/* 100us */\n\n/*\n * Registers Definition\n */\n\n#define IM_CTX_SIZE\t\t\t0x40\n\n#define IMCTR\t\t\t\t0x0000\n#define IMCTR_VA64\t\t\t(1 << 29)\n#define IMCTR_INTEN\t\t\t(1 << 2)\n#define IMCTR_FLUSH\t\t\t(1 << 1)\n#define IMCTR_MMUEN\t\t\t(1 << 0)\n\n#define IMTTBCR\t\t\t\t0x0008\n#define IMTTBCR_EAE\t\t\t(1 << 31)\n#define IMTTBCR_PMB\t\t\t(1 << 30)\n#define IMTTBCR_SH0_INNER_SHAREABLE\t(3 << 12)\n#define IMTTBCR_ORGN0_WB_WA\t\t(1 << 10)\n#define IMTTBCR_IRGN0_WB_WA\t\t(1 << 8)\n#define IMTTBCR_TSZ0_SHIFT\t\t0\n\n#define IMTTBCR_SL0_TWOBIT_LVL_1\t(2 << 6)\n\n#define IMTTLBR0\t\t\t0x0010\n#define IMTTUBR0\t\t\t0x0014\n\n#define IMTTLBR_MASK\t\t\t0xFFFFF000\n\n#define IMSTR\t\t\t\t0x0020\n#define IMSTR_MHIT\t\t\t(1 << 4)\n#define IMSTR_ABORT\t\t\t(1 << 2)\n#define IMSTR_PF\t\t\t(1 << 1)\n#define IMSTR_TF\t\t\t(1 << 0)\n\n#define IMEAR\t\t\t\t0x0030\n#define IMEUAR\t\t\t\t0x0034\n\n#define IMUCTR(n)\t\t\t((n) < 32 ? IMUCTR0(n) : IMUCTR32(n))\n#define IMUCTR0(n)\t\t\t(0x0300 + ((n) * 16))\n#define IMUCTR32(n)\t\t\t(0x0600 + (((n) - 32) * 16))\n#define IMUCTR_TTSEL_MMU(n)\t\t((n) << 4)\n#define IMUCTR_FLUSH\t\t\t(1 << 1)\n#define IMUCTR_MMUEN\t\t\t(1 << 0)\n\n#define IMUASID(n)\t\t\t((n) < 32 ? IMUASID0(n) : IMUASID32(n))\n#define IMUASID0(n)\t\t\t(0x0308 + ((n) * 16))\n#define IMUASID32(n)\t\t\t(0x0608 + (((n) - 32) * 16))\n\n#define IMSCTLR\t\t\t\t0x0500\n#define IMSCTLR_DISCACHE\t\t0xE0000000\n\n#define IMSAUXCTLR\t\t\t0x0504\n#define IMSAUXCTLR_S2PTE\t\t(1 << 3)\n\n/*\n * Root device handling\n */\n\nstatic bool ipmmu_is_root(struct ipmmu_device *mmu)\n{\n\t/* Minos: Fix */\n\treturn mmu && !mmu->is_leaf;\n}\n\nstatic struct ipmmu_device *ipmmu_find_root(struct ipmmu_device *leaf)\n{\n\tstruct ipmmu_device *mmu = NULL;\n\n\tif (ipmmu_is_root(leaf))\n\t\treturn leaf;\n\n\tspin_lock(&ipmmu_devices_lock);\n\n\tlist_for_each_entry (mmu, &ipmmu_devices, list) {\n\t\tif (ipmmu_is_root(mmu))\n\t\t\tbreak;\n\t}\n\n\tspin_unlock(&ipmmu_devices_lock);\n\treturn mmu;\n}\n\n/*\n * Read/Write Access\n */\n\nstatic u32 ipmmu_read(struct ipmmu_device *mmu, unsigned int offset)\n{\n\treturn ioread32(mmu->base + offset);\n}\n\nstatic void ipmmu_write(struct ipmmu_device *mmu, unsigned int offset, u32 data)\n{\n\tiowrite32(data, mmu->base + offset);\n}\n\nstatic u32 ipmmu_ctx_read_root(struct ipmmu_domain *domain, unsigned int reg)\n{\n\treturn ipmmu_read(domain->root, domain->context_id * IM_CTX_SIZE + reg);\n}\n\nstatic void ipmmu_ctx_write_root(struct ipmmu_domain *domain, unsigned int reg,\n\t\t\t\t u32 data)\n{\n\tipmmu_write(domain->root, domain->context_id * IM_CTX_SIZE + reg, data);\n}\n\n/* Minos: Write the context for cache IPMMU only. */\nstatic void ipmmu_ctx_write_cache(struct ipmmu_domain *domain, unsigned int reg,\n\t\t\t\t  u32 data)\n{\n\tunsigned int i;\n\n\tfor (i = 0; i < domain->num_mmus; i++)\n\t\tipmmu_write(domain->mmus[i],\n\t\t\t    domain->context_id * IM_CTX_SIZE + reg, data);\n}\n\n/*\n * Minos: Write the context for both root IPMMU and all cache IPMMUs\n * that assigned to this Minos VM.\n */\nstatic void ipmmu_ctx_write_all(struct ipmmu_domain *domain, unsigned int reg,\n\t\t\t\tu32 data)\n{\n\tstruct vm_ipmmu *vm_ipmmu = to_vm_ipmmu(domain->vm);\n\tstruct iommu_domain *io_domain;\n\n\tlist_for_each_entry (io_domain, &vm_ipmmu->contexts, list)\n\t\tipmmu_ctx_write_cache(to_ipmmu_domain(io_domain), reg, data);\n\n\tipmmu_ctx_write_root(domain, reg, data);\n}\n\n/*\n * TLB and microTLB Management\n */\n\n/* Wait for any pending TLB invalidations to complete */\nstatic void ipmmu_tlb_sync(struct ipmmu_domain *domain)\n{\n\tunsigned int count = 0;\n\n\twhile (ipmmu_ctx_read_root(domain, IMCTR) & IMCTR_FLUSH) {\n\t\tcpu_relax();\n\t\tif (++count == TLB_LOOP_TIMEOUT) {\n\t\t\tpr_err(\"%s: TLB sync timed out -- MMU may be deadlocked\\n\",\n\t\t\t       devnode_name(domain->root->node));\n\t\t\treturn;\n\t\t}\n\t\tudelay(1);\n\t}\n}\n\nstatic void ipmmu_tlb_invalidate(struct ipmmu_domain *domain)\n{\n\tu32 reg;\n\n\treg = ipmmu_ctx_read_root(domain, IMCTR);\n\treg |= IMCTR_FLUSH;\n\tipmmu_ctx_write_all(domain, IMCTR, reg);\n\n\tipmmu_tlb_sync(domain);\n}\n\n/* Enable MMU translation for the microTLB. */\nstatic void ipmmu_utlb_enable(struct ipmmu_domain *domain,\n\t\t\t      struct ipmmu_utlb *utlb_p)\n{\n\tstruct ipmmu_device *mmu = utlb_p->mmu;\n\tunsigned int utlb = utlb_p->utlb;\n\n\t/*\n\t * TODO: Reference-count the microTLB as several bus masters can be\n\t * connected to the same microTLB.\n\t */\n\n\t/* TODO: What should we set the ASID to ? */\n\tipmmu_write(mmu, IMUASID(utlb), 0);\n\n\t/* TODO: Do we need to flush the microTLB ? */\n\tipmmu_write(mmu, IMUCTR(utlb),\n\t\t    IMUCTR_TTSEL_MMU(domain->context_id) | IMUCTR_FLUSH |\n\t\t\t    IMUCTR_MMUEN);\n}\n\n/*\n * Domain/Context Management\n */\n\nstatic int ipmmu_domain_allocate_context(struct ipmmu_device *mmu,\n\t\t\t\t\t struct ipmmu_domain *domain)\n{\n\tunsigned long flags;\n\tint ret;\n\n\tspin_lock_irqsave(&mmu->lock, flags);\n\n\tret = find_first_zero_bit(mmu->ctx, mmu->num_ctx);\n\tif (ret != mmu->num_ctx) {\n\t\tmmu->domains[ret] = domain;\n\t\tset_bit(ret, mmu->ctx);\n\t} else\n\t\tret = -EBUSY;\n\n\tspin_unlock_irqrestore(&mmu->lock, flags);\n\n\treturn ret;\n}\n\nstatic int ipmmu_domain_init_context(struct ipmmu_domain *domain)\n{\n\tu64 ttbr;\n\tu32 tmp;\n\tint ret;\n\n\t/* Minos: Initialize context_id with non-existent value */\n\tdomain->context_id = domain->root->num_ctx;\n\n\t/* Find an unused context. */\n\tret = ipmmu_domain_allocate_context(domain->root, domain);\n\tif (ret < 0)\n\t\treturn ret;\n\n\tdomain->context_id = ret;\n\n\t/*\n\t * TTBR0\n\t * Use P2M table. With IPA size being forced to 40 bit (pa_range = 2)\n\t * we get 3-level P2M with two concatenated translation tables\n\t * at level 1. Which seems to be an appropriate case for the IPMMU.\n\t */\n\tBUG_ON(!domain->vm);\n\tttbr = domain->vm->mm.pgd_base;\n\n\t/* Minos: */\n\tpr_notice(\"%s: vm%d: Set IPMMU context %u (pgd 0x%x)\\n\",\n\t\t  devnode_name(domain->root->node), vm_id(domain->vm),\n\t\t  domain->context_id, ttbr);\n\n\tipmmu_ctx_write_root(domain, IMTTLBR0, ttbr & IMTTLBR_MASK);\n\tipmmu_ctx_write_root(domain, IMTTUBR0, ttbr >> 32);\n\n\t/*\n\t * TTBCR\n\t * We use long descriptors with inner-shareable WBWA tables and allocate\n\t * the whole 40-bit VA space to TTBR0.\n\t * Bypass stage 1 translation.\n\t */\n\ttmp = IMTTBCR_SL0_TWOBIT_LVL_1;\n\n\ttmp |= (64ULL - 40ULL) << IMTTBCR_TSZ0_SHIFT;\n\n\tipmmu_ctx_write_root(\n\t\tdomain, IMTTBCR,\n\t\tIMTTBCR_EAE | IMTTBCR_PMB | IMTTBCR_SH0_INNER_SHAREABLE |\n\t\t\tIMTTBCR_ORGN0_WB_WA | IMTTBCR_IRGN0_WB_WA | tmp);\n\n\t/*\n\t * IMSTR\n\t * Clear all interrupt flags.\n\t */\n\tipmmu_ctx_write_root(domain, IMSTR, ipmmu_ctx_read_root(domain, IMSTR));\n\n\t/*\n\t * IMCTR\n\t * Enable the MMU and interrupt generation. The long-descriptor\n\t * translation table format doesn't use TEX remapping. Don't enable AF\n\t * software management as we have no use for it. Flush the TLB as\n\t * required when modifying the context registers.\n\t * Minos: Enable the context for the root IPMMU only.\n\t */\n\tipmmu_ctx_write_root(domain, IMCTR,\n\t\t\t     IMCTR_VA64 | IMCTR_INTEN | IMCTR_FLUSH |\n\t\t\t\t     IMCTR_MMUEN);\n\n\treturn 0;\n}\n\nstatic void ipmmu_domain_free_context(struct ipmmu_device *mmu,\n\t\t\t\t      unsigned int context_id)\n{\n\tunsigned long flags;\n\n\tspin_lock_irqsave(&mmu->lock, flags);\n\n\tclear_bit(context_id, mmu->ctx);\n\tmmu->domains[context_id] = NULL;\n\n\tspin_unlock_irqrestore(&mmu->lock, flags);\n}\n\nstatic void ipmmu_domain_destroy_context(struct ipmmu_domain *domain)\n{\n\t/* Minos: Just return if context_id has non-existent value */\n\tif (!domain->root || domain->context_id >= domain->root->num_ctx)\n\t\treturn;\n\n\t/*\n\t * Disable the context. Flush the TLB as required when modifying the\n\t * context registers.\n\t *\n\t * TODO: Is TLB flush really needed ?\n\t * Minos: Disable the context for the root IPMMU only.\n\t */\n\tipmmu_ctx_write_root(domain, IMCTR, IMCTR_FLUSH);\n\tipmmu_tlb_sync(domain);\n\n\tipmmu_domain_free_context(domain->root, domain->context_id);\n\n\t/* Minos: Initialize context_id with non-existent value */\n\tdomain->context_id = domain->root->num_ctx;\n}\n\n/*\n * Fault Handling\n */\n\n/* Minos: Show vmid in every printk */\nstatic int ipmmu_domain_irq(struct ipmmu_domain *domain)\n{\n\tconst u32 err_mask = IMSTR_MHIT | IMSTR_ABORT | IMSTR_PF | IMSTR_TF;\n\tstruct ipmmu_device *mmu = domain->root;\n\tu32 status;\n\tu64 iova;\n\n\tstatus = ipmmu_ctx_read_root(domain, IMSTR);\n\tif (!(status & err_mask))\n\t\treturn -ENOENT;\n\n\tiova = ipmmu_ctx_read_root(domain, IMEAR) |\n\t       ((u64)ipmmu_ctx_read_root(domain, IMEUAR) << 32);\n\n\t/*\n\t * Clear the error status flags. Unlike traditional interrupt flag\n\t * registers that must be cleared by writing 1, this status register\n\t * seems to require 0. The error address register must be read before,\n\t * otherwise its value will be 0.\n\t */\n\tipmmu_ctx_write_root(domain, IMSTR, 0);\n\n\t/* Log fatal errors. */\n\tif (status & IMSTR_MHIT)\n\t\tpr_err(\"%s: vm%d: Multiple TLB hits @0x%x\\n\",\n\t\t       devnode_name(mmu->node), vm_id(domain->vm), iova);\n\tif (status & IMSTR_ABORT)\n\t\tpr_err(\"%s: vm%d: Page Table Walk Abort @0x%x\\n\",\n\t\t       devnode_name(mmu->node), vm_id(domain->vm), iova);\n\n\tif (!(status & (IMSTR_PF | IMSTR_TF)))\n\t\treturn -ENOENT;\n\n\t/* Flush the TLB as required when IPMMU translation error occurred. */\n\tipmmu_tlb_invalidate(domain);\n\n\t/*\n\t * Try to handle page faults and translation faults.\n\t *\n\t * TODO: We need to look up the faulty device based on the I/O VA. Use\n\t * the IOMMU device for now.\n\t */\n\n\tpr_err(\"%s: vm%d: Unhandled fault: status 0x%x iova 0x%x\\n\",\n\t       devnode_name(mmu->node), vm_id(domain->vm), status, iova);\n\n\treturn 0;\n}\n\nstatic int ipmmu_irq(uint32_t irq, void *dev)\n{\n\tstruct ipmmu_device *mmu = dev;\n\tint status = -ENOENT;\n\tunsigned int i;\n\tunsigned long flags;\n\n\tspin_lock_irqsave(&mmu->lock, flags);\n\n\t/* Check interrupts for all active contexts. */\n\tfor (i = 0; i < mmu->num_ctx; i++) {\n\t\tif (!mmu->domains[i])\n\t\t\tcontinue;\n\t\tif (ipmmu_domain_irq(mmu->domains[i]) == 0)\n\t\t\tstatus = 0;\n\t}\n\n\tspin_unlock_irqrestore(&mmu->lock, flags);\n\n\treturn status;\n}\n\nbool ipmmus_are_equal(struct ipmmu_domain *domain,\n\t\t      struct node_ipmmu *node_ipmmu)\n{\n\tunsigned int i;\n\n\tif (domain->num_mmus != node_ipmmu->num_mmus)\n\t\treturn false;\n\n\tfor (i = 0; i < node_ipmmu->num_mmus; i++) {\n\t\tif (domain->mmus[i] != node_ipmmu->mmus[i])\n\t\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nstatic int ipmmu_attach_node(struct iommu_domain *io_domain,\n\t\t\t     struct device_node *node)\n{\n\tstruct node_ipmmu *node_ipmmu = to_node_ipmmu(node);\n\tstruct ipmmu_device *root;\n\tstruct ipmmu_domain *domain = to_ipmmu_domain(io_domain);\n\tunsigned long flags;\n\tunsigned int i;\n\tint ret = 0;\n\n\tfor (i = 0; i < node_ipmmu->num_mmus; i++) {\n\t\tif (!node_ipmmu->mmus[i])\n\t\t\tbreak;\n\t}\n\n\tif (!node_ipmmu->num_mmus || i != node_ipmmu->num_mmus) {\n\t\tpr_err(\"%s: Cannot attach to IPMMU\\n\", devnode_name(node));\n\t\treturn -ENXIO;\n\t}\n\n\troot = ipmmu_find_root(node_ipmmu->mmus[0]);\n\tif (!root) {\n\t\tpr_err(\"%s: Unable to locate root IPMMU\\n\", devnode_name(node));\n\t\treturn -EAGAIN;\n\t}\n\n\tspin_lock_irqsave(&domain->lock, flags);\n\n\tif (!domain->mmus[0]) {\n\t\t/* The domain hasn't been used yet, initialize it. */\n\t\tdomain->num_mmus = node_ipmmu->num_mmus;\n\t\tmemcpy(domain->mmus, node_ipmmu->mmus,\n\t\t       node_ipmmu->num_mmus * sizeof(*node_ipmmu->mmus));\n\t\tdomain->root = root;\n\n\t\t/*\n\t\t * Minos: We have already initialized and enabled context for root IPMMU\n\t\t * for this Minos VM. Enable context for given cache IPMMU only.\n\t\t * Flush the TLB as required when modifying the context registers.\n\t\t */\n\n\t\tipmmu_ctx_write_cache(domain, IMCTR,\n\t\t\t\t      ipmmu_ctx_read_root(domain, IMCTR) |\n\t\t\t\t\t      IMCTR_FLUSH);\n\n\t\tpr_info(\"%s: Using IPMMU context %u\\n\", devnode_name(node),\n\t\t\tdomain->context_id);\n\t} else if (!ipmmus_are_equal(domain, node_ipmmu)) {\n\t\t/*\n\t\t * Something is wrong, we can't attach two devices using\n\t\t * different IOMMUs to the same domain.\n\t\t */\n\t\tfor (i = 0; i < node_ipmmu->num_mmus || i < domain->num_mmus;\n\t\t     i++)\n\t\t\tpr_err(\"%s: Can't attach IPMMU%d %s to domain on IPMMU%d %s\\n\",\n\t\t\t       devnode_name(node), i + 1,\n\t\t\t       i < node_ipmmu->num_mmus ?\n\t\t\t\t       devnode_name(node_ipmmu->mmus[i]->node) :\n\t\t\t\t       \"---\",\n\t\t\t       i + 1,\n\t\t\t       i < domain->num_mmus ?\n\t\t\t\t       devnode_name(domain->mmus[i]->node) :\n\t\t\t\t       \"---\");\n\t\tret = -EINVAL;\n\t} else {\n\t\tpr_info(\"%s: Reusing IPMMU context %u\\n\", devnode_name(node),\n\t\t\tdomain->context_id);\n\t}\n\n\tspin_unlock_irqrestore(&domain->lock, flags);\n\n\tif (ret < 0)\n\t\treturn ret;\n\n\tfor (i = 0; i < node_ipmmu->num_utlbs; ++i)\n\t\tipmmu_utlb_enable(domain, &node_ipmmu->utlbs[i]);\n\n\treturn 0;\n}\n\nstatic int ipmmu_find_utlbs(struct device_node *node, struct ipmmu_utlb *utlbs,\n\t\t\t    unsigned int num_utlbs)\n{\n\tunsigned int i;\n\tint ret = -ENODEV;\n\tuint32_t iommus[num_utlbs * 2];\n\n\tret = of_get_u32_array(node, \"iommus\", iommus, ARRAY_SIZE(iommus));\n\tif (ret != ARRAY_SIZE(iommus))\n\t\treturn -ENODEV;\n\n\tspin_lock(&ipmmu_devices_lock);\n\n\tfor (i = 0; i < num_utlbs; ++i) {\n\t\tstruct ipmmu_device *mmu;\n\t\tuint32_t phandle;\n\n\t\tret = -ENODEV;\n\t\tlist_for_each_entry (mmu, &ipmmu_devices, list) {\n\t\t\tof_get_u32_array(mmu->node, \"phandle\", &phandle, 1);\n\t\t\tif (!phandle || phandle != iommus[i * 2])\n\t\t\t\tcontinue;\n\n\t\t\t/*\n\t\t\t * TODO Take a reference to the MMU to protect\n\t\t\t * against device removal.\n\t\t\t */\n\t\t\tret = 0;\n\t\t\tbreak;\n\t\t}\n\t\tif (ret < 0)\n\t\t\tbreak;\n\n\t\tutlbs[i].utlb = iommus[i * 2 + 1];\n\t\tutlbs[i].mmu = mmu;\n\t}\n\n\tspin_unlock(&ipmmu_devices_lock);\n\n\treturn ret;\n}\n\nstatic int ipmmu_node_init(struct device_node *node)\n{\n\tstruct node_ipmmu *node_ipmmu;\n\tstruct ipmmu_device *mmus[IPMMU_PER_DEV_MAX];\n\tstruct ipmmu_utlb *utlbs;\n\tunsigned int i;\n\tint num_utlbs;\n\tint num_mmus;\n\tint ret;\n\tof32_t *iommus;\n\tint len;\n\n\t/* Find the master corresponding to the device. */\n\n\tiommus = of_getprop(node, \"iommus\", &len);\n\tif (!iommus || len < sizeof(*iommus))\n\t\treturn -ENODEV;\n\n\tnum_utlbs = len / sizeof(*iommus) / 2;\n\n\tutlbs = zalloc(num_utlbs * sizeof(*utlbs));\n\tif (!utlbs)\n\t\treturn -ENOMEM;\n\n\tret = ipmmu_find_utlbs(node, utlbs, num_utlbs);\n\tif (ret < 0)\n\t\tgoto error;\n\n\tnum_mmus = 0;\n\tfor (i = 0; i < num_utlbs; i++) {\n\t\tif (!utlbs[i].mmu || utlbs[i].utlb >= utlbs[i].mmu->num_utlbs) {\n\t\t\tret = -EINVAL;\n\t\t\tgoto error;\n\t\t}\n\n\t\tif (!num_mmus || mmus[num_mmus - 1] != utlbs[i].mmu) {\n\t\t\tif (num_mmus >= IPMMU_PER_DEV_MAX) {\n\t\t\t\tret = -EINVAL;\n\t\t\t\tgoto error;\n\t\t\t} else {\n\t\t\t\tnum_mmus++;\n\t\t\t\tmmus[num_mmus - 1] = utlbs[i].mmu;\n\t\t\t}\n\t\t}\n\t}\n\n\tnode_ipmmu = zalloc(sizeof(*node_ipmmu));\n\tif (!node_ipmmu) {\n\t\tret = -ENOMEM;\n\t\tgoto error;\n\t}\n\n\tnode_ipmmu->num_mmus = num_mmus;\n\tmemcpy(node_ipmmu->mmus, mmus, num_mmus * sizeof(*mmus));\n\tnode_ipmmu->utlbs = utlbs;\n\tnode_ipmmu->num_utlbs = num_utlbs;\n\tnode_ipmmu->node = node;\n\tnode->iommu.priv = node_ipmmu;\n\n\t/* Minos: */\n\tpr_notice(\"%s: Initialized master device (IPMMUs %u micro-TLBs %u)\\n\",\n\t\t  devnode_name(node), num_mmus, num_utlbs);\n\tfor (i = 0; i < num_mmus; i++)\n\t\tpr_notice(\"%s: IPMMU%d: %s\\n\", devnode_name(node), i + 1,\n\t\t\t  devnode_name(mmus[i]->node));\n\n\treturn 0;\n\nerror:\n\tfree(utlbs);\n\treturn ret;\n}\n\n/*\n * Probe/remove and init\n */\n\nstatic void ipmmu_device_reset(struct ipmmu_device *mmu)\n{\n\tunsigned int i;\n\n\t/* Disable all contexts. */\n\tfor (i = 0; i < mmu->num_ctx; ++i)\n\t\tipmmu_write(mmu, i * IM_CTX_SIZE + IMCTR, 0);\n}\n\n/*\n * Minos: We don't have refcount for allocated memory so manually free memory\n * when an error occured.\n */\nstatic int ipmmu_probe(struct device_node *node)\n{\n\tstruct ipmmu_device *mmu;\n\tphy_addr_t address;\n\tsize_t size;\n\tint len;\n\tuint32_t irq;\n\tunsigned long flags;\n\tint ret;\n\n\tmmu = zalloc(sizeof(*mmu));\n\tif (!mmu) {\n\t\tpr_err(\"%s: cannot allocate device data\\n\", devnode_name(node));\n\t\treturn -ENOMEM;\n\t}\n\n\tmmu->node = node;\n\tmmu->num_utlbs = 48;\n\tspin_lock_init(&mmu->lock);\n\tbitmap_zero(mmu->ctx, IPMMU_CTX_MAX);\n\n\t/* Map I/O memory and request IRQ. */\n\tret = of_translate_address(node, &address, &size);\n\tif (ret || !size) {\n\t\tret = -ENOENT;\n\t\tgoto out;\n\t}\n\n\tmmu->base = (void *)io_remap(address, size);\n\tif (!mmu->base) {\n\t\tret = -ENOMEM;\n\t\tgoto out;\n\t}\n\n\t/*\n\t * The number of contexts varies with generation and instance.\n\t * Newer SoCs get a total of 8 contexts enabled, older ones just one.\n\t */\n\tmmu->num_ctx = 8;\n\n\tBUG_ON(mmu->num_ctx > IPMMU_CTX_MAX);\n\n\t/*\n\t * Determine if this IPMMU instance is a leaf device by checking\n\t * if the renesas,ipmmu-main property exists or not.\n\t */\n\tif (of_getprop(node, \"renesas,ipmmu-main\", &len))\n\t\tmmu->is_leaf = true;\n\n\t/* Root devices have mandatory IRQs */\n\tif (ipmmu_is_root(mmu)) {\n\t\tret = get_device_irq_index(node, &irq, &flags, 0);\n\t\tif (ret) {\n\t\t\tpr_err(\"%s: no IRQ found\\n\", devnode_name(node));\n\t\t\tgoto out;\n\t\t}\n\n\t\tret = request_irq(irq, ipmmu_irq, flags, NULL, mmu);\n\t\tif (ret) {\n\t\t\tpr_err(\"%s: failed to request IRQ %d\\n\",\n\t\t\t       devnode_name(node), irq);\n\t\t\tgoto out;\n\t\t}\n\n\t\tipmmu_device_reset(mmu);\n\n\t\t/* Use stage 2 translation table format */\n\t\tipmmu_write(mmu, IMSAUXCTLR,\n\t\t\t    ipmmu_read(mmu, IMSAUXCTLR) | IMSAUXCTLR_S2PTE);\n\t} else {\n\t\t/* Only IPMMU caches are affected */\n\n\t\t/*\n\t\t * Disable IPMMU TLB cache function of IPMMU caches\n\t\t * that do require such action.\n\t\t */\n\t\tif (ipmmu_is_mmu_tlb_disable_needed(node))\n\t\t\tipmmu_write(mmu, IMSCTLR,\n\t\t\t\t    ipmmu_read(mmu, IMSCTLR) |\n\t\t\t\t\t    IMSCTLR_DISCACHE);\n\t}\n\n\tspin_lock(&ipmmu_devices_lock);\n\tlist_add(&ipmmu_devices, &mmu->list);\n\tspin_unlock(&ipmmu_devices_lock);\n\n\t/* Minos: */\n\tpr_notice(\"%s: registered %s IPMMU\\n\", devnode_name(node),\n\t\t  ipmmu_is_root(mmu) ? \"root\" : \"cache\");\n\n\treturn 0;\n\nout:\n\tif (!mmu->base)\n\t\tio_unmap((unsigned long)mmu->base, size);\n\tfree(mmu);\n\n\treturn ret;\n}\n\n/*\n * Start of Minos specific code\n */\n\nstatic int ipmmu_iotlb_flush_all(struct vm *vm)\n{\n\tstruct vm_ipmmu *vm_ipmmu = to_vm_ipmmu(vm);\n\n\tif (!vm_ipmmu || !vm_ipmmu->base_context)\n\t\treturn 0;\n\n\tspin_lock(&vm_ipmmu->lock);\n\tipmmu_tlb_invalidate(to_ipmmu_domain(vm_ipmmu->base_context));\n\tspin_unlock(&vm_ipmmu->lock);\n\treturn 0;\n}\n\nstatic struct iommu_domain *ipmmu_get_domain(struct vm *vm,\n\t\t\t\t\t     struct device_node *node)\n{\n\tstruct vm_ipmmu *vm_ipmmu = to_vm_ipmmu(vm);\n\tstruct iommu_domain *io_domain;\n\n\tif (!to_node_ipmmu(node)->mmus[0] || !to_node_ipmmu(node)->num_mmus)\n\t\treturn NULL;\n\n\t/*\n\t * Loop through the &vm_ipmmu->contexts to locate a context\n\t * assigned to this IPMMU\n\t */\n\tlist_for_each_entry (io_domain, &vm_ipmmu->contexts, list) {\n\t\tif (ipmmus_are_equal(to_ipmmu_domain(io_domain),\n\t\t\t\t     to_node_ipmmu(node)))\n\t\t\treturn io_domain;\n\t}\n\n\treturn NULL;\n}\n\nstatic void ipmmu_destroy_domain(struct iommu_domain *io_domain)\n{\n\tstruct ipmmu_domain *domain = to_ipmmu_domain(io_domain);\n\n\tlist_del(&io_domain->list);\n\n\tif (domain->num_mmus) {\n\t\t/*\n\t\t * Disable the context for cache IPMMU only. Flush the TLB as required\n\t\t * when modifying the context registers.\n\t\t */\n\t\tipmmu_ctx_write_cache(domain, IMCTR, IMCTR_FLUSH);\n\t} else {\n\t\t/*\n\t\t * Free main domain resources. We assume that all devices have already\n\t\t * been detached.\n\t\t */\n\t\tipmmu_domain_destroy_context(domain);\n\t}\n\n\tfree(domain);\n}\n\nstatic int ipmmu_alloc_page_table(struct vm *vm);\n\nstatic int ipmmu_assign_node(struct vm *vm, struct device_node *node)\n{\n\tstruct vm_ipmmu *vm_ipmmu = to_vm_ipmmu(vm);\n\tstruct iommu_domain *io_domain;\n\tstruct ipmmu_domain *domain;\n\tint ret = 0;\n\n\tif (!vm_ipmmu)\n\t\treturn -EINVAL;\n\n\tif (!vm_ipmmu->base_context) {\n\t\tret = ipmmu_alloc_page_table(vm);\n\t\tif (ret)\n\t\t\treturn ret;\n\t}\n\n\tif (!to_node_ipmmu(node)) {\n\t\tret = ipmmu_node_init(node);\n\t\tif (ret)\n\t\t\treturn ret;\n\t}\n\n\tspin_lock(&vm_ipmmu->lock);\n\n\tif (to_node_ipmmu(node)->io_domain) {\n\t\tpr_err(\"%s: already attached to IPMMU domain\\n\",\n\t\t       devnode_name(node));\n\t\tret = -EEXIST;\n\t\tgoto out;\n\t}\n\n\t/*\n\t * Check to see if a context bank (iommu_domain) already exists for\n\t * this Minos VM under the same IPMMU\n\t */\n\tio_domain = ipmmu_get_domain(vm, node);\n\tif (!io_domain) {\n\t\tdomain = zalloc(sizeof(*domain));\n\t\tif (!domain) {\n\t\t\tret = -ENOMEM;\n\t\t\tgoto out;\n\t\t}\n\t\tspin_lock_init(&domain->lock);\n\n\t\tdomain->vm = vm;\n\t\tdomain->context_id =\n\t\t\tto_ipmmu_domain(vm_ipmmu->base_context)->context_id;\n\t\tio_domain = &domain->io_domain;\n\n\t\t/* Chain the new context to the Minos VM */\n\t\tlist_add(&vm_ipmmu->contexts, &io_domain->list);\n\t}\n\n\tret = ipmmu_attach_node(io_domain, node);\n\tif (ret) {\n\t\tif (atomic_read(&io_domain->ref) == 0)\n\t\t\tipmmu_destroy_domain(io_domain);\n\t} else {\n\t\tatomic_inc(&io_domain->ref);\n\t\tto_node_ipmmu(node)->io_domain = io_domain;\n\t}\n\nout:\n\tspin_unlock(&vm_ipmmu->lock);\n\n\treturn ret;\n}\n\nstatic int ipmmu_alloc_page_table(struct vm *vm)\n{\n\tstruct vm_ipmmu *vm_ipmmu = to_vm_ipmmu(vm);\n\tstruct ipmmu_domain *domain;\n\tstruct ipmmu_device *root;\n\tint ret;\n\n\troot = ipmmu_find_root(NULL);\n\tif (!root) {\n\t\tpr_err(\"vm%d: Unable to locate root IPMMU\\n\", vm_id(vm));\n\t\treturn -EAGAIN;\n\t}\n\n\tdomain = zalloc(sizeof(*domain));\n\tif (!domain)\n\t\treturn -ENOMEM;\n\n\tspin_lock_init(&domain->lock);\n\tinit_list(&domain->io_domain.list);\n\tdomain->vm = vm;\n\tdomain->root = root;\n\t/* Clear num_mmus explicitly. */\n\tdomain->num_mmus = 0;\n\n\tspin_lock(&vm_ipmmu->lock);\n\tret = ipmmu_domain_init_context(domain);\n\tif (ret < 0) {\n\t\tpr_err(\"%s: vm%d: Unable to initialize IPMMU context\\n\",\n\t\t       devnode_name(root->node), vm_id(vm));\n\t\tspin_unlock(&vm_ipmmu->lock);\n\t\tfree(domain);\n\t\treturn ret;\n\t}\n\tvm_ipmmu->base_context = &domain->io_domain;\n\tspin_unlock(&vm_ipmmu->lock);\n\n\treturn 0;\n}\n\nstatic int ipmmu_vm_init(struct vm *vm)\n{\n\tstruct vm_ipmmu *vm_ipmmu;\n\n\tvm_ipmmu = zalloc(sizeof(*vm_ipmmu));\n\tif (!vm_ipmmu)\n\t\treturn -ENOMEM;\n\n\tspin_lock_init(&vm_ipmmu->lock);\n\tinit_list(&vm_ipmmu->contexts);\n\n\tvm->iommu.priv = vm_ipmmu;\n\n\treturn 0;\n}\n\nstatic void *populate_ipmmu_masters(struct device_node *node, void *arg)\n{\n\tstruct device_node *ipmmu_node = arg;\n\tuint32_t phandle;\n\tuint32_t iommus;\n\n\tof_get_u32_array(ipmmu_node, \"phandle\", &phandle, 1);\n\tof_get_u32_array(node, \"iommus\", &iommus, 1);\n\n\tif (!phandle || phandle != iommus)\n\t\treturn NULL;\n\n\tpr_notice(\"%s: found master device %s\\n\", devnode_name(ipmmu_node),\n\t\t  devnode_name(node));\n\n\treturn node;\n}\n\nstatic int ipmmu_init(struct device_node *node)\n{\n\tint rc;\n\n\t/*\n\t * Perform platform specific actions such as power-on, errata maintenance\n\t * if required.\n\t */\n\trc = ipmmu_power_on(node);\n\tif (rc) {\n\t\tpr_err(\"%s: failed to preinit IPMMU (%d)\\n\", devnode_name(node),\n\t\t       rc);\n\t\treturn rc;\n\t}\n\n\trc = ipmmu_probe(node);\n\tif (rc) {\n\t\tpr_err(\"%s: failed to init IPMMU\\n\", devnode_name(node));\n\t\treturn rc;\n\t}\n\n\tof_iterate_all_node_loop(hv_node, populate_ipmmu_masters, node);\n\n\treturn 0;\n}\n\nstatic struct iommu_ops ipmmu_ops = {\n\t.init = ipmmu_init,\n\t.vm_init = ipmmu_vm_init,\n\t.iotlb_flush_all = ipmmu_iotlb_flush_all,\n\t.assign_node = ipmmu_assign_node,\n};\n\nIOMMU_OPS_DECLARE(ipmmu_ops, ipmmu_match_table, (void *)&ipmmu_ops);\n"
  },
  {
    "path": "kernel/drivers/irq-chips/Kconfig",
    "content": "menu \"Interrupt Controller Driver\"\n\nconfig IRQCHIP_GICV3\n\tbool \"gicv3 driver\"\n\tdefault n\n\thelp\n\t  \"GICv3 interrupt controller driver\"\n\nconfig IRQCHIP_GICV2\n\tbool \"gicv2 driver\"\n\tdefault n\n\thelp\n\t  \"GICv2 interrupt controller driver\"\n\nconfig IRQCHIP_BCM2836\n\tbool \"bcm2836/2835 interrupt controller driver\"\n\tdefault n\n\thelp\n\t  \"interrupt controller driver for raspberry PI 3\"\n\nendmenu\n"
  },
  {
    "path": "kernel/drivers/irq-chips/Makefile",
    "content": "obj-y\t\t\t\t+= irqchip.o\nobj-$(CONFIG_IRQCHIP_GICV3) \t+= gicv3.o\nobj-$(CONFIG_IRQCHIP_GICV2) \t+= gicv2.o\nobj-$(CONFIG_IRQCHIP_BCM2836) \t+= irq-bcm2836.o\n"
  },
  {
    "path": "kernel/drivers/irq-chips/gicv2.c",
    "content": "/*\n * xen/arch/arm/gic-v2.c\n *\n * Tim Deegan <tim@xen.org>\n * Copyright (c) 2011 Citrix Systems.\n *\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n */\n\n#include <minos/minos.h>\n#include <asm/io.h>\n#include <minos/percpu.h>\n#include <minos/spinlock.h>\n#include <minos/print.h>\n#include <device/gicv2.h>\n#include <minos/errno.h>\n#include <asm/arch.h>\n#include <minos/cpumask.h>\n#include <minos/irq.h>\n#include <minos/of.h>\n#include <minos/mm.h>\n\n/*\n * LR register definitions are GIC v2 specific.\n * Moved these definitions from header file to here\n */\n#define GICH_V2_LR_VIRTUAL_MASK    0x3ff\n#define GICH_V2_LR_VIRTUAL_SHIFT   0\n#define GICH_V2_LR_PHYSICAL_MASK   0x3ff\n#define GICH_V2_LR_PHYSICAL_SHIFT  10\n#define GICH_V2_LR_STATE_MASK      0x3\n#define GICH_V2_LR_STATE_SHIFT     28\n#define GICH_V2_LR_PENDING         (1U << 28)\n#define GICH_V2_LR_ACTIVE          (1U << 29)\n#define GICH_V2_LR_PRIORITY_SHIFT  23\n#define GICH_V2_LR_PRIORITY_MASK   0x1f\n#define GICH_V2_LR_HW_SHIFT        31\n#define GICH_V2_LR_HW_MASK         0x1\n#define GICH_V2_LR_GRP_SHIFT       30\n#define GICH_V2_LR_GRP_MASK        0x1\n#define GICH_V2_LR_MAINTENANCE_IRQ (1U << 19)\n#define GICH_V2_LR_GRP1            (1U << 30)\n#define GICH_V2_LR_HW              (1U << GICH_V2_LR_HW_SHIFT)\n#define GICH_V2_LR_CPUID_SHIFT     10\n#define GICH_V2_LR_CPUID_MASK      0x7\n#define GICH_V2_VTR_NRLRGS         0x3f\n\n#define GICH_V2_VMCR_PRIORITY_MASK   0x1f\n#define GICH_V2_VMCR_PRIORITY_SHIFT  27\n\n#define GIC_PRI_LOWEST     0xf0\n#define GIC_PRI_IRQ        0xa0\n#define GIC_PRI_IPI        0x90 /* IPIs must preempt normal interrupts */\n#define GIC_PRI_HIGHEST    0x80 /* Higher priorities belong to Secure-World */\n\nstatic DEFINE_SPIN_LOCK(gicv2_lock);\nstatic void *gicv2_dbase;\nstatic void *gicv2_cbase;\nstatic void *gicv2_hbase;\nstatic int gicv2_nr_lines;\n\nstatic uint8_t gic_cpu_mask[8] = { 0xff };\n\nextern int vgicv2_init(uint64_t *data, int len);\nextern int gic_xlate_irq(struct device_node *node,\n\t\tuint32_t *intspec, unsigned int intsize,\n\t\tuint32_t *hwirq, unsigned long *type);\n\n/* Maximum cpu interface per GIC */\n#define NR_GIC_CPU_IF 8\n\nstatic inline void writeb_gicd(uint8_t val, unsigned int offset)\n{\n\twriteb_relaxed(val, gicv2_dbase + offset);\n}\n\nstatic inline void writel_gicd(uint32_t val, unsigned int offset)\n{\n\twritel_relaxed(val, gicv2_dbase + offset);\n}\n\nstatic inline uint32_t readl_gicd(unsigned int offset)\n{\n\treturn readl_relaxed(gicv2_dbase + offset);\n}\n\nstatic inline void writel_gicc(uint32_t val, unsigned int offset)\n{\n\twritel_relaxed(val, gicv2_cbase + offset);\n}\n\nstatic inline uint32_t readl_gicc(unsigned int offset)\n{\n\treturn readl_relaxed(gicv2_cbase + offset);\n}\n\nstatic inline void writel_gich(uint32_t val, unsigned int offset)\n{\n\twritel_relaxed(val, gicv2_hbase + offset);\n}\n\nstatic inline uint32_t readl_gich(int unsigned offset)\n{\n\treturn readl_relaxed(gicv2_hbase + offset);\n}\n\nstatic void gicv2_eoi_irq(uint32_t irq)\n{\n\twritel_gicc(irq, GICC_EOIR);\n\tdsb();\n}\n\nstatic void gicv2_dir_irq(uint32_t irq)\n{\n\twritel_gicc(irq, GICC_DIR);\n\tdsb();\n}\n\nstatic uint32_t gicv2_read_irq(void)\n{\n\tuint32_t irq;\n\n\tirq = readl_gicc(GICC_IAR);\n\tisb();\n\tirq = irq & GICC_IA_IRQ;\n\n\treturn irq;\n}\n\nstatic int gicv2_set_irq_type(uint32_t irq, uint32_t type)\n{\n\tuint32_t cfg, edgebit;\n\n\tif (irq < 16)\n\t\treturn 0;\n\n\tspin_lock(&gicv2_lock);\n\n\t/* Set edge / level */\n\tcfg = readl_gicd(GICD_ICFGR + (irq / 16) * 4);\n\tedgebit = 2u << (2 * (irq % 16));\n\tif ( type & IRQ_FLAGS_LEVEL_BOTH)\n\t\tcfg &= ~edgebit;\n\telse if (type & IRQ_FLAGS_EDGE_BOTH)\n\t\tcfg |= edgebit;\n\n\twritel_gicd(cfg, GICD_ICFGR + (irq / 16) * 4);\n\tspin_unlock(&gicv2_lock);\n\n\treturn 0;\n}\n\nstatic void __used gicv2_clear_pending(uint32_t irq)\n{\n\twritel_gicd(1UL << (irq % 32), GICD_ICPENDR + (irq / 32) * 4);\n\tdsb();\n}\n\nstatic int gicv2_set_irq_priority(uint32_t irq, uint32_t pr)\n{\n\tspin_lock(&gicv2_lock);\n\n\t/* Set priority */\n\twriteb_gicd(pr, GICD_IPRIORITYR + irq);\n\n\tspin_unlock(&gicv2_lock);\n\treturn 0;\n}\n\nstatic int gicv2_set_irq_affinity(uint32_t irq, uint32_t pcpu)\n{\n\tif (pcpu > NR_GIC_CPU_IF || irq < 32)\n\t\treturn -EINVAL;\n\n\tspin_lock(&gicv2_lock);\n\t/* Set target CPU mask (RAZ/WI on uniprocessor) */\n\twriteb_gicd(1 << pcpu, GICD_ITARGETSR + irq);\n\tspin_unlock(&gicv2_lock);\n\treturn 0;\n}\n\nstatic void gicv2_send_sgi(uint32_t sgi, enum sgi_mode mode, cpumask_t *mask)\n{\n\tunsigned int cpu;\n\tunsigned int value = 0;\n\n\tswitch (mode) {\n\tcase SGI_TO_OTHERS:\n\t\twritel_gicd(GICD_SGI_TARGET_OTHERS | sgi, GICD_SGIR);\n\t\tbreak;\n\tcase SGI_TO_SELF:\n\t\twritel_gicd(GICD_SGI_TARGET_SELF | sgi, GICD_SGIR);\n\t\tbreak;\n\tcase SGI_TO_LIST:\n\t\tfor_each_cpu(cpu, mask)\n\t\t\tvalue |= gic_cpu_mask[cpu];\n\n\t\twritel_gicd(GICD_SGI_TARGET_LIST |\n\t\t\t(value << GICD_SGI_TARGET_SHIFT) | sgi,\n\t\t\tGICD_SGIR);\n\t\tisb();\n\t\tbreak;\n\tdefault:\n\t\tbreak;;\n    }\n}\n\nstatic void gicv2_mask_irq(uint32_t irq)\n{\n\tunsigned long flags;\n\n\tspin_lock_irqsave(&gicv2_lock, flags);\n\twritel_gicd(1UL << (irq % 32), GICD_ICENABLER + (irq / 32) * 4);\n\tdsb();\n\tspin_unlock_irqrestore(&gicv2_lock, flags);\n}\n\nstatic void gicv2_unmask_irq(uint32_t irq)\n{\n\tunsigned long flags;\n\n\tspin_lock_irqsave(&gicv2_lock, flags);\n\twritel_gicd(1UL << (irq % 32), GICD_ISENABLER + (irq / 32) * 4);\n\tdsb();\n\tspin_unlock_irqrestore(&gicv2_lock, flags);\n}\n\nstatic void gicv2_mask_irq_cpu(uint32_t irq, int cpu)\n{\n\tpr_warn(\"not support mask irq_percpu\\n\");\n}\n\nstatic void gicv2_unmask_irq_cpu(uint32_t irq, int cpu)\n{\n\tpr_warn(\"not support unmask irq_percpu\\n\");\n}\n\nstatic int __init_text gicv2_is_aliased(unsigned long base, unsigned long size)\n{\n\tuint32_t val_low, val_high;\n\n\tif (size != SIZE_1K * 128)\n\t\treturn 0;\n\n\tval_low = readl_gicc(GICC_IIDR);\n\tval_high = readl_gicc(GICC_IIDR + 0xf000);\n\n\treturn ((val_low & 0xfff0fff) == 0x0202043B &&\n\t\t\tval_low == val_high);\n}\n\nstatic void __init_text gicv2_cpu_init(void)\n{\n\tint i;\n\tint cpuid = smp_processor_id();\n\n\tgic_cpu_mask[cpuid] = readl_gicd(GICD_ITARGETSR) & 0xff;\n\tpr_debug(\"gicv2 gic mask of cpu%d: 0x%x\\n\", cpuid, gic_cpu_mask[cpuid]);\n\tif (gic_cpu_mask[cpuid] == 0)\n\t\tgic_cpu_mask[cpuid] = 1 << cpuid;\n\n\t/* The first 32 interrupts (PPI and SGI) are banked per-cpu, so\n\t * even though they are controlled with GICD registers, they must\n\t * be set up here with the other per-cpu state. */\n\twritel_gicd(0xffff0000, GICD_ICENABLER); /* Disable all PPI */\n\twritel_gicd(0x0000ffff, GICD_ISENABLER); /* Enable all SGI */\n\n\t/* Set SGI priorities */\n\tfor ( i = 0; i < 16; i += 4 )\n\t\twritel_gicd(GIC_PRI_IPI << 24 | GIC_PRI_IPI << 16 |\n\t\t\tGIC_PRI_IPI << 8 | GIC_PRI_IPI,\n\t\t\tGICD_IPRIORITYR + (i / 4) * 4);\n\n\t/* Set PPI priorities */\n\tfor ( i = 16; i < 32; i += 4 )\n\t\twritel_gicd(GIC_PRI_IRQ << 24 | GIC_PRI_IRQ << 16 |\n\t\t\tGIC_PRI_IRQ << 8 | GIC_PRI_IRQ,\n\t\t\tGICD_IPRIORITYR + (i / 4) * 4);\n\n\t/* Local settings: interface controller */\n\t/* Don't mask by priority */\n\twritel_gicc(0xff, GICC_PMR);\n\t/* Finest granularity of priority */\n\twritel_gicc(0x0, GICC_BPR);\n\t/* Turn on delivery */\n\twritel_gicc(GICC_CTL_ENABLE|GICC_CTL_EOI, GICC_CTLR);\n\tdsb();\n}\n\n#ifdef CONFIG_VIRT\nstatic void __init_text gicv2_hyp_init(void)\n{\n\n}\n#endif\n\nstatic void __init_text gicv2_dist_init(void)\n{\n\tuint32_t type;\n\tuint32_t cpumask;\n\tuint32_t gic_cpus;\n\tunsigned int nr_lines;\n\tint i;\n\n\tcpumask = readl_gicd(GICD_ITARGETSR) & 0xff;\n\tcpumask = (cpumask == 0) ? (1 << 0) : cpumask;\n\tcpumask |= cpumask << 8;\n\tcpumask |= cpumask << 16;\n\n\t/* Disable the distributor */\n\twritel_gicd(0, GICD_CTLR);\n\n\ttype = readl_gicd(GICD_TYPER);\n\tnr_lines = 32 * ((type & GICD_TYPE_LINES) + 1);\n\tgic_cpus = 1 + ((type & GICD_TYPE_CPUS) >> 5);\n\tpr_notice(\"GICv2: %d lines, %d cpu%s%s (IID %x).\\n\",\n\t\tnr_lines, gic_cpus, (gic_cpus == 1) ? \"\" : \"s\",\n\t\t(type & GICD_TYPE_SEC) ? \", secure\" : \"\",\n\t\treadl_gicd(GICD_IIDR));\n\n\n\t/* Default all global IRQs to level, active low */\n\tfor ( i = 32; i < nr_lines; i += 16 )\n\t\twritel_gicd(0x0, GICD_ICFGR + (i / 16) * 4);\n\n\t/* Route all global IRQs to this CPU */\n\tfor ( i = 32; i < nr_lines; i += 4 )\n\t\twritel_gicd(cpumask, GICD_ITARGETSR + (i / 4) * 4);\n\n\t/* Default priority for global interrupts */\n\tfor ( i = 32; i < nr_lines; i += 4 )\n\t\twritel_gicd(GIC_PRI_IRQ << 24 | GIC_PRI_IRQ << 16 |\n\t\t\tGIC_PRI_IRQ << 8 | GIC_PRI_IRQ,\n\t\t\tGICD_IPRIORITYR + (i / 4) * 4);\n\n\t/* Disable all global interrupts */\n\tfor ( i = 32; i < nr_lines; i += 32 )\n\t\twritel_gicd(~0x0, GICD_ICENABLER + (i / 32) * 4);\n\n\t/* Only 1020 interrupts are supported */\n\tgicv2_nr_lines = min(1020U, nr_lines);\n\n\t/* Turn on the distributor */\n\twritel_gicd(GICD_CTL_ENABLE, GICD_CTLR);\n\tdsb();\n}\n\nstatic int __init_text gicv2_init(struct device_node *node)\n{\n\tuint64_t array[10];\n\n\tpr_notice(\"*** gicv2 init ***\\n\");\n\tmemset(array, 0, sizeof(array));\n\n\ttranslate_device_address_index(node, &array[0], &array[1], 0);\n\ttranslate_device_address_index(node, &array[2], &array[3], 1);\n\ttranslate_device_address_index(node, &array[4], &array[5], 2);\n\ttranslate_device_address_index(node, &array[6], &array[7], 3);\n\n\tpr_notice(\"gicv2 information: gic_dist_addr=%p size=0x%x \"\n\t\t\"gic_cpu_addr=%p size=0x%x gic_hyp_addr=%p size=0x%x \"\n\t\t\"gic_vcpu_addr=%p size=0x%x\\n\",\n\t\tarray[0], array[1], array[2], array[3],\n\t\tarray[4], array[5], array[6], array[7]);\n\n\tASSERT((array[0] != 0) && (array[1] != 0))\n\tgicv2_dbase = io_remap((virt_addr_t)array[0], (size_t)array[1]);\n\tASSERT((array[2] != 0) && array[3] !=0);\n\tgicv2_cbase = io_remap((virt_addr_t)array[2], (size_t)array[3]);\n#ifdef CONFIG_VIRT\n\tASSERT((array[4] != 0) && (array[5] != 0))\n\tgicv2_hbase = io_remap((virt_addr_t)array[4], (size_t)array[5]);\n#endif\n\n\tif (gicv2_is_aliased((unsigned long)array[2],\n\t\t\t\t(unsigned long)array[3])) {\n\t\tgicv2_cbase += 0xf000;\n\t\tpr_notice(\"gicv2 : adjust cpu interface base to 0x%x\\n\",\n\t\t\t\t(unsigned long)gicv2_cbase);\n\t}\n\n\tspin_lock(&gicv2_lock);\n\n\tgicv2_dist_init();\n\tgicv2_cpu_init();\n\n#ifdef CONFIG_VIRT\n\tgicv2_hyp_init();\n#endif\n\n\tspin_unlock(&gicv2_lock);\n\n#if defined CONFIG_VIRQCHIP_VGICV2 && defined CONFIG_VIRT\n\tvgicv2_init(array, 8);\n#endif\n\n\treturn 0;\n}\n\nstatic int __init_text gicv2_secondary_init(void)\n{\n\tspin_lock(&gicv2_lock);\n\tgicv2_cpu_init();\n#ifdef CONFIG_VIRT\n\tgicv2_hyp_init();\n#endif\n\tspin_unlock(&gicv2_lock);\n\n\treturn 0;\n}\n\nstatic struct irq_chip gicv2_chip = {\n\t.irq_mask \t\t= gicv2_mask_irq,\n\t.irq_mask_cpu\t\t= gicv2_mask_irq_cpu,\n\t.irq_unmask \t\t= gicv2_unmask_irq,\n\t.irq_unmask_cpu \t= gicv2_unmask_irq_cpu,\n\t.irq_eoi \t\t= gicv2_eoi_irq,\n\t.irq_dir\t\t= gicv2_dir_irq,\n\t.irq_set_type \t\t= gicv2_set_irq_type,\n\t.irq_set_affinity \t= gicv2_set_irq_affinity,\n\t.send_sgi\t\t= gicv2_send_sgi,\n\t.get_pending_irq\t= gicv2_read_irq,\n\t.irq_set_priority\t= gicv2_set_irq_priority,\n\t.irq_xlate\t\t= gic_xlate_irq,\n\t.init\t\t\t= gicv2_init,\n\t.secondary_init\t\t= gicv2_secondary_init,\n};\nIRQCHIP_DECLARE(gicv2_chip, gicv2_match_table, (void *)&gicv2_chip);\n"
  },
  {
    "path": "kernel/drivers/irq-chips/gicv3.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <asm/io.h>\n#include <minos/percpu.h>\n#include <minos/spinlock.h>\n#include <minos/print.h>\n#include <device/gicv3.h>\n#include <minos/errno.h>\n#include <asm/arch.h>\n#include <minos/cpumask.h>\n#include <minos/irq.h>\n#include <minos/of.h>\n#include <asm/cpu_feature.h>\n#include <minos/mm.h>\n\nspinlock_t gicv3_lock;\nstatic void *gicd_base = 0;\n\nextern int vgicv3_init(uint64_t *data, int len);\n\nstatic DEFINE_PER_CPU(void *, gicr_rd_base);\nstatic DEFINE_PER_CPU(void *, gicr_sgi_base);\n\n#define gicr_rd_base()\tget_cpu_var(gicr_rd_base)\n#define gicr_sgi_base()\tget_cpu_var(gicr_sgi_base)\n\nuint64_t cpus_affinity[NR_CPUS];\n\nextern int gic_xlate_irq(struct device_node *node,\n\t\tuint32_t *intspec, unsigned int intsize,\n\t\tuint32_t *hwirq, unsigned long *type);\n\nstatic void gicv3_gicd_wait_for_rwp(void)\n{\n\twhile (ioread32(gicd_base + GICD_CTLR) & (1 << 31));\n}\n\nstatic void gicv3_gicr_wait_for_rwp(void)\n{\n\twhile (ioread32(gicr_rd_base() + GICR_CTLR) & (1 << 31));\n}\n\nstatic void gicv3_eoi_irq(uint32_t irq)\n{\n\twrite_sysreg32(irq, ICC_EOIR1_EL1);\n\tisb();\n}\n\nstatic void gicv3_dir_irq(uint32_t irq)\n{\n\twrite_sysreg32(irq, ICC_DIR_EL1);\n\tisb();\n}\n\nstatic uint32_t gicv3_read_irq(void)\n{\n\tuint32_t irq;\n\n\tirq = read_sysreg32(ICC_IAR1_EL1);\n\tdsbsy();\n\treturn irq;\n}\n\nstatic int gicv3_set_irq_type(uint32_t irq, uint32_t type)\n{\n\tvoid *base;\n\tuint32_t cfg, edgebit;\n\n\t/* sgi are always edge-triggered */\n\tif (irq < GICV3_NR_SGI)\n\t\treturn 0;\n\n\tspin_lock(&gicv3_lock);\n\n\tif (irq >= GICV3_NR_LOCAL_IRQS)\n\t\tbase = (void *)gicd_base + GICD_ICFGR + (irq / 16) * 4;\n\telse\n\t\tbase = (void *)gicr_sgi_base() + GICR_ICFGR1;\n\n\tcfg = ioread32(base);\n\tedgebit = 2u << (2 * (irq % 16));\n\tif (type & IRQ_FLAGS_LEVEL_BOTH)\n\t\tcfg &= ~edgebit;\n\telse if (type & IRQ_FLAGS_EDGE_BOTH)\n\t\tcfg |= edgebit;\n\n\tiowrite32(cfg, base);\n\tisb();\n\n\tspin_unlock(&gicv3_lock);\n\n\treturn 0;\n}\n\nstatic void gicv3_clear_pending(uint32_t irq)\n{\n\tuint32_t offset, bit;\n\n\tspin_lock(&gicv3_lock);\n\n\tif (irq < GICV3_NR_LOCAL_IRQS) {\n\t\tiowrite32(BIT(irq), (void *)gicr_sgi_base() + GICR_ICPENDR0);\n\t} else {\n\t\tirq = irq - 32;\n\t\toffset = irq / 32;\n\t\tbit = offset % 32;\n\t\tiowrite32(BIT(bit), (void *)gicd_base + \\\n\t\t\t\tGICD_ICPENDR + (offset * 4));\n\t}\n\n\tspin_unlock(&gicv3_lock);\n}\n\nstatic int gicv3_set_irq_priority(uint32_t irq, uint32_t pr)\n{\n\tspin_lock(&gicv3_lock);\n\n\tif (irq < GICV3_NR_LOCAL_IRQS)\n\t\tiowrite8(pr, gicr_sgi_base() + GICR_IPRIORITYR0 + irq);\n\telse\n\t\tiowrite8(pr, gicd_base + GICD_IPRIORITYR + irq);\n\n\tspin_unlock(&gicv3_lock);\n\n\treturn 0;\n}\n\nstatic int gicv3_set_irq_affinity(uint32_t irq, uint32_t pcpu)\n{\n\tuint64_t affinity;\n\n\taffinity = cpuid_to_affinity(pcpu);\n\taffinity &= ~(1 << 31); //GICD_IROUTER_SPI_MODE_ANY\n\n\tspin_lock(&gicv3_lock);\n\tiowrite64(affinity, gicd_base + GICD_IROUTER + irq * 8);\n\tspin_unlock(&gicv3_lock);\n\n\treturn 0;\n}\n\nstatic inline void __gicv3_send_sgi_list(uint32_t sgi, cpumask_t *mask)\n{\n\tuint64_t val_cluster0 = 0;\n\tuint64_t val_cluster1 = 0;\n\tint cpu;\n\n\tfor_each_cpu(cpu, mask) {\n\t\tif (cpu >= CONFIG_NR_CPUS_CLUSTER0)\n\t\t\tval_cluster1 |= cpus_affinity[cpu];\n\t\telse\n\t\t\tval_cluster0 |= cpus_affinity[cpu];\n\t}\n\n\t/*\n\t * TBD: now only support two cluster\n\t */\n\tif (val_cluster0) {\n\t\tval_cluster0 |= (sgi << 24);\n\t\twrite_sysreg64(val_cluster0, ICC_SGI1R_EL1);\n\t}\n\n\tif (val_cluster1) {\n\t\tval_cluster1 |= (sgi << 24);\n\t\twrite_sysreg64(val_cluster1, ICC_SGI1R_EL1);\n\t}\n\n\tisb();\n}\n\nstatic inline void __gicv3_send_sgi_list_shif_mpidr(uint32_t sgi, cpumask_t *mask)\n{\n\tint cpu;\n\tuint64_t value;\n\n\tfor_each_cpu(cpu, mask) {\n\t\tvalue = cpus_affinity[cpu] | (sgi << 24);\n\t\twrite_sysreg64(value, ICC_SGI1R_EL1);\n\t}\n\n\tisb();\n}\n\nstatic void gicv3_send_sgi_list(uint32_t sgi, cpumask_t *mask)\n{\n\tif (cpu_has_feature(ARM_FEATURE_MPIDR_SHIFT))\n\t\t__gicv3_send_sgi_list_shif_mpidr(sgi, mask);\n\telse\n\t\t__gicv3_send_sgi_list(sgi, mask);\n}\n\nstatic void gicv3_send_sgi(uint32_t sgi, enum sgi_mode mode, cpumask_t *cpu)\n{\n\tcpumask_t cpus_mask;\n\n\tif (sgi > 15)\n\t\treturn;\n\n\tcpumask_clearall(&cpus_mask);\n\n\tswitch (mode) {\n\tcase SGI_TO_OTHERS:\n\t\twrite_sysreg64(ICH_SGI_TARGET_OTHERS << ICH_SGI_IRQMODE_SHIFT |\n\t\t\t\t(uint64_t)sgi << ICH_SGI_IRQ_SHIFT, ICC_SGI1R_EL1);\n\t\tisb();\n\t\tbreak;\n\tcase SGI_TO_SELF:\n\t\tcpumask_set_cpu(smp_processor_id(), &cpus_mask);\n\t\tgicv3_send_sgi_list(sgi, &cpus_mask);\n\t\tbreak;\n\tcase SGI_TO_LIST:\n\t\tgicv3_send_sgi_list(sgi, cpu);\n\t\tbreak;\n\tdefault:\n\t\tpr_err(\"Sgi mode not supported\\n\");\n\t\tbreak;\n\t}\n}\n\nstatic void gicv3_mask_irq(uint32_t irq)\n{\n\tuint32_t mask = 1 << (irq % 32);\n\n\tspin_lock(&gicv3_lock);\n\tif (irq < GICV3_NR_LOCAL_IRQS) {\n\t\tiowrite32(mask, gicr_sgi_base() + GICR_ICENABLER + (irq / 32) * 4);\n\t\tgicv3_gicr_wait_for_rwp();\n\t} else {\n\t\tiowrite32(mask, gicd_base + GICD_ICENABLER + (irq / 32) * 4);\n\t\tgicv3_gicd_wait_for_rwp();\n\t}\n\tspin_unlock(&gicv3_lock);\n}\n\nstatic void gicv3_unmask_irq(uint32_t irq)\n{\n\tuint32_t mask = 1 << (irq % 32);\n\n\tspin_lock(&gicv3_lock);\n\n\tif (irq < GICV3_NR_LOCAL_IRQS) {\n\t\tiowrite32(mask, gicr_sgi_base() + GICR_ISENABLER + (irq / 32) * 4);\n\t\tgicv3_gicr_wait_for_rwp();\n\t} else {\n\t\tiowrite32(mask, gicd_base + GICD_ISENABLER + (irq / 32) * 4);\n\t\tgicv3_gicd_wait_for_rwp();\n\t}\n\n\tspin_unlock(&gicv3_lock);\n}\n\nstatic void gicv3_mask_irq_cpu(uint32_t irq, int cpu)\n{\n\tvoid *base;\n\tuint32_t mask = 1 << (irq % 32);\n\n\tif (irq >= GICV3_NR_LOCAL_IRQS)\n\t\treturn;\n\n\tif (cpu >= NR_CPUS)\n\t\treturn;\n\n\tspin_lock(&gicv3_lock);\n\n\tbase = get_per_cpu(gicr_sgi_base, cpu);\n\tbase = base + GICR_ICENABLER + (irq / 32) * 4;\n\tiowrite32(mask, base);\n\tgicv3_gicr_wait_for_rwp();\n\n\tspin_unlock(&gicv3_lock);\n}\n\nstatic void gicv3_unmask_irq_cpu(uint32_t irq, int cpu)\n{\n\tvoid *base;\n\tuint32_t mask = 1 << (irq % 32);\n\n\tif (irq >= GICV3_NR_LOCAL_IRQS)\n\t\treturn;\n\n\tif (cpu >= NR_CPUS)\n\t\treturn;\n\n\tspin_lock(&gicv3_lock);\n\n\tbase = get_per_cpu(gicr_sgi_base, cpu);\n\tbase = base + GICR_ISENABLER + (irq / 32) * 4;\n\tiowrite32(mask, base);\n\tgicv3_gicr_wait_for_rwp();\n\n\tspin_unlock(&gicv3_lock);\n}\n\nstatic void gicv3_wakeup_gicr(void)\n{\n\tuint32_t gicv3_waker_value;\n\n\tgicv3_waker_value = ioread32(gicr_rd_base() + GICR_WAKER);\n\tgicv3_waker_value &= ~(GICR_WAKER_PROCESSOR_SLEEP);\n\tiowrite32(gicv3_waker_value, gicr_rd_base() + GICR_WAKER);\n\n\twhile ((ioread32(gicr_rd_base() + GICR_WAKER)\n\t\t\t& GICR_WAKER_CHILDREN_ASLEEP) != 0);\n}\n\nstatic inline uint64_t read_icc_sre(void)\n{\n#ifdef CONFIG_VIRT\n\treturn read_icc_sre_el2();\n#else\n\treturn read_icc_sre_el1();\n#endif\n}\n\nstatic inline void write_icc_sre(uint64_t val)\n{\n#ifdef CONFIG_VIRT\n\twrite_icc_sre_el2(val);\n#else\n\twrite_icc_sre_el1(val);\n#endif\n}\n\nstatic int __init_text gicv3_gicc_init(void)\n{\n\tunsigned char aff0, aff1, aff2, aff3;\n\tuint64_t reg_value;\n\tuint64_t mpidr = read_mpidr_el1();\n\tint cpu = smp_processor_id();\n\n\taff0 = mpidr & 0xff;\n\taff1 = (mpidr & 0xff00) >> 8;\n\taff2 = (mpidr & 0xff0000) >> 16;\n\taff3 = (mpidr & 0xff00000000) >> 32;\n\n\tif (aff0 > 16)\n\t\tpanic(\"mpidr 0x%x for cpu%d is wrong\\n\", mpidr, cpu);\n\n\t/*\n\t * MPDIR SHIFT means each cluster has one core\n\t */\n\tcpus_affinity[cpu] = (1 << aff0) | (aff1 << 16) |\n\t\t((uint64_t)aff2 << 32) | ((uint64_t)aff3 << 48);\n\n\t/* enable sre */\n\treg_value = read_icc_sre();\n\treg_value |= (1 << 0);\n\twrite_icc_sre(reg_value);\n\n\twrite_sysreg32(0, ICC_BPR1_EL1);\n\twrite_sysreg32(0xff, ICC_PMR_EL1);\n\twrite_sysreg32(1 << 1, ICC_CTLR_EL1);\n\twrite_sysreg32(1, ICC_IGRPEN1_EL1);\n\tisb();\n\n\treturn 0;\n}\n\nstatic int __init_text gicv3_hyp_init(void)\n{\n#ifdef CONFIG_VIRT\n\twrite_sysreg32(GICH_VMCR_VENG1 | (0xff << 24), ICH_VMCR_EL2);\n\twrite_sysreg32(GICH_HCR_EN, ICH_HCR_EL2);\n\tisb();\n#endif\n\treturn 0;\n}\n\nstatic int __init_text gicv3_gicr_init(void)\n{\n\tint i;\n\tuint64_t pr;\n\n\tgicv3_wakeup_gicr();\n\n\t/* set the priority on PPI and SGI */\n\tpr = (0x90 << 24) | (0x90 << 16) | (0x90 << 8) | 0x90;\n\tfor (i = 0; i < GICV3_NR_SGI; i += 4)\n\t\tiowrite32(pr, gicr_sgi_base() + GICR_IPRIORITYR0 + (i / 4) * 4);\n\n\tpr = (0xa0 << 24) | (0xa0 << 16) | (0xa0 << 8) | 0xa0;\n\tfor (i = GICV3_NR_SGI; i < GICV3_NR_LOCAL_IRQS; i += 4)\n\t\tiowrite32(pr, gicr_sgi_base() + GICR_IPRIORITYR0 + (i / 4) * 4);\n\n\t/* disable all PPI and enable all SGI */\n\tiowrite32(0xffff0000, gicr_sgi_base() + GICR_ICENABLER);\n\tiowrite32(0x0000ffff, gicr_sgi_base() + GICR_ISENABLER);\n\n\t/* configure SGI and PPI as non-secure Group-1 */\n\tiowrite32(0xffffffff, gicr_sgi_base() + GICR_IGROUPR0);\n\n\tgicv3_gicr_wait_for_rwp();\n\tisb();\n\n\treturn 0;\n}\n\nstatic void __init_text gicv3_icc_sre_init(void)\n{\n#ifdef CONFIG_VIRT\n\twrite_sysreg(0xf, ICC_SRE_EL2);\n#endif\n\twrite_sysreg(0xf, ICC_SRE_EL1);\n}\n\nstatic int __init_text gicv3_init(struct device_node *node)\n{\n\tint i;\n\tuint32_t type;\n\tuint32_t nr_lines, pr;\n\tvoid *rbase;\n\tuint64_t array[10];\n\tvoid *__gicr_rd_base = 0;\n\n\tpr_notice(\"*** gicv3 init ***\\n\");\n\n\tmemset(array, 0, sizeof(array));\n\ttranslate_device_address_index(node, &array[0], &array[1], 0);\n\ttranslate_device_address_index(node, &array[2], &array[3], 1);\n\ttranslate_device_address_index(node, &array[4], &array[5], 2);\n\ttranslate_device_address_index(node, &array[6], &array[7], 3);\n\n\tspin_lock_init(&gicv3_lock);\n\n\t/* only map gicd and gicr now */\n\tgicd_base = io_remap((virt_addr_t)array[0], (size_t)array[1]);\n\t__gicr_rd_base = io_remap((virt_addr_t)array[2], (size_t)array[3]);\n\n\tpr_notice(\"gicv3 gicd@0x%x gicr@0x%x\\n\", (unsigned long)gicd_base,\n\t\t\t(unsigned long)__gicr_rd_base);\n\n#ifdef CONFIG_VIRT\n\tuint64_t nr_pr;\n\tuint32_t value;\n\n\tvalue = read_sysreg32(ICH_VTR_EL2);\n\tnr_pr = ((value >> 29) & 0x7) + 1;\n\n\tif (!((nr_pr > 4) && (nr_pr < 8)))\n\t\tpanic(\"GICv3: Invalid number of priority bits\\n\");\n#endif\n\n\tfor (i = 0; i < CONFIG_NR_CPUS; i++) {\n\t\trbase = __gicr_rd_base + (128 * 1024) * i;\n\t\tget_per_cpu(gicr_rd_base, i) = rbase;\n\t\tget_per_cpu(gicr_sgi_base, i) = rbase + (64 * 1024);\n\t}\n\n\tspin_lock(&gicv3_lock);\n\n\t/* disable gicd */\n\tiowrite32(0, gicd_base + GICD_CTLR);\n\n\ttype = ioread32(gicd_base + GICD_TYPER);\n\tnr_lines = 32 * ((type & 0x1f));\n\tpr_notice(\"gicv3 typer-0x%x nr_lines-%d\\n\", type, nr_lines);\n\n\t/* default all golbal IRQS to level, active low */\n\tfor (i = GICV3_NR_LOCAL_IRQS; i < nr_lines; i += 16)\n\t\tiowrite32(0, gicd_base + GICD_ICFGR + (i / 16) * 4);\n\n\t/* default priority for global interrupts */\n\tfor (i = GICV3_NR_LOCAL_IRQS; i < nr_lines; i += 4) {\n\t\tpr = (0xa0 << 24) | (0xa0 << 16) | (0xa0 << 8) | 0xa0;\n\t\tiowrite32(pr, gicd_base + GICD_IPRIORITYR + (i / 4) * 4);\n\t\tpr = ioread32(gicd_base + GICD_IPRIORITYR + (i / 4) * 4);\n\t}\n\n\t/* disable all global interrupt */\n\tfor (i = GICV3_NR_LOCAL_IRQS; i < nr_lines; i += 32)\n\t\tiowrite32(0xffffffff, gicd_base + GICD_ICENABLER + (i / 32) *4);\n\n\t/* configure SPIs as non-secure GROUP-1 */\n\tfor (i = GICV3_NR_LOCAL_IRQS; i < nr_lines; i += 32)\n\t\tiowrite32(0xffffffff, gicd_base + GICD_IGROUPR + (i / 32) *4);\n\n\tgicv3_gicd_wait_for_rwp();\n\n\t/* enable the gicd */\n\tiowrite32(1 | GICD_CTLR_ENABLE_GRP1 | GICD_CTLR_ENABLE_GRP1A |\n\t\t\tGICD_CTLR_ARE_NS, gicd_base + GICD_CTLR);\n\tisb();\n\n\tgicv3_icc_sre_init();\n\tgicv3_gicr_init();\n\tgicv3_gicc_init();\n\tgicv3_hyp_init();\n\n\tspin_unlock(&gicv3_lock);\n\n#ifdef CONFIG_VIRT\n#ifdef CONFIG_VIRQCHIP_VGICV3\n\tvgicv3_init(array, 10);\n#else\n\tpr_err(\"vgicv3 is not enabled, using vgicv2 instead\\n\");\n\tvgicv2_init(NULL, 0);\n#endif\n#endif\n\treturn 0;\n}\n\nstatic int __init_text gicv3_secondary_init(void)\n{\n\tspin_lock(&gicv3_lock);\n\n\tgicv3_icc_sre_init();\n\tgicv3_gicr_init();\n\tgicv3_gicc_init();\n\tgicv3_hyp_init();\n\n\tspin_unlock(&gicv3_lock);\n\n\treturn 0;\n}\n\nstatic struct irq_chip gicv3_chip = {\n\t.irq_mask \t\t= gicv3_mask_irq,\n\t.irq_mask_cpu\t\t= gicv3_mask_irq_cpu,\n\t.irq_unmask \t\t= gicv3_unmask_irq,\n\t.irq_unmask_cpu \t= gicv3_unmask_irq_cpu,\n\t.irq_eoi \t\t= gicv3_eoi_irq,\n\t.irq_dir\t\t= gicv3_dir_irq,\n\t.irq_set_type \t\t= gicv3_set_irq_type,\n\t.irq_set_affinity \t= gicv3_set_irq_affinity,\n\t.send_sgi\t\t= gicv3_send_sgi,\n\t.get_pending_irq\t= gicv3_read_irq,\n\t.irq_clear_pending\t= gicv3_clear_pending,\n\t.irq_set_priority\t= gicv3_set_irq_priority,\n\t.irq_xlate\t\t= gic_xlate_irq,\n\t.init\t\t\t= gicv3_init,\n\t.secondary_init\t\t= gicv3_secondary_init,\n};\nIRQCHIP_DECLARE(gicv3_chip, gicv3_match_table, (void *)&gicv3_chip);\n"
  },
  {
    "path": "kernel/drivers/irq-chips/irq-bcm2836.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <asm/io.h>\n#include <minos/percpu.h>\n#include <minos/spinlock.h>\n#include <minos/print.h>\n#include <minos/errno.h>\n#include <asm/arch.h>\n#include <minos/cpumask.h>\n#include <minos/irq.h>\n#include <minos/of.h>\n#include <device/bcm_irq.h>\n#include <minos/mm.h>\n\nextern int bcm_virq_init(unsigned long l1_base, size_t l1_size,\n\t\tunsigned long l2_base, size_t l2_size);\n\nstatic const int reg_pending[] = { 0x00, 0x04, 0x08 };\nstatic const int reg_enable[] = { 0x18, 0x10, 0x14 };\nstatic const int reg_disable[]= { 0x24, 0x1c, 0x20 };\n\nstatic const int shortcuts[] = {\n\t7, 9, 10, 18, 19,\t\t/* Bank 1 */\n\t21, 22, 23, 24, 25, 30\t\t/* Bank 2 */\n};\n\nstruct armctrl_ic {\n\tvoid *base;\n\tvoid *pending[NR_BANKS];\n\tvoid *enable[NR_BANKS];\n\tvoid *disable[NR_BANKS];\n\tstruct irq_domain *domain;\n\tvoid *local_base;\n};\n\nstatic struct armctrl_ic intc;\nstatic void *bcm2836_base;\n\nextern int bcm2836_xlate_irq(struct device_node *node,\n\t\tuint32_t *intspec, unsigned int intsize,\n\t\tuint32_t *hwirq, unsigned long *type);\n\nstatic void bcm2835_mask_irq(uint32_t irq)\n{\n\twritel_relaxed(HWIRQ_BIT(irq), intc.disable[HWIRQ_BANK(irq)]);\n\tdsb();\n}\n\nstatic void bcm2835_unmask_irq(uint32_t irq)\n{\n\twritel_relaxed(HWIRQ_BIT(irq), intc.enable[HWIRQ_BANK(irq)]);\n\tdsb();\n}\n\nstatic uint32_t armctrl_translate_bank(int bank)\n{\n\tuint32_t stat = readl_relaxed(intc.pending[bank]);\n\n\treturn MAKE_HWIRQ(bank, __ffs(stat));\n}\n\nstatic uint32_t armctrl_translate_shortcut(int bank, u32 stat)\n{\n\treturn MAKE_HWIRQ(bank, shortcuts[__ffs(stat >> SHORTCUT_SHIFT)]);\n}\n\nstatic uint32_t bcm2835_get_pending(void)\n{\n\tuint32_t stat = readl_relaxed(intc.pending[0]) & BANK0_VALID_MASK;\n\n\tif (stat == 0)\n\t\treturn BAD_IRQ;\n\telse if (stat & BANK0_HWIRQ_MASK)\n\t\treturn MAKE_HWIRQ(0, __ffs(stat & BANK0_HWIRQ_MASK));\n\telse if (stat & SHORTCUT1_MASK)\n\t\treturn armctrl_translate_shortcut(1, stat & SHORTCUT1_MASK);\n\telse if (stat & SHORTCUT2_MASK)\n\t\treturn armctrl_translate_shortcut(2, stat & SHORTCUT2_MASK);\n\telse if (stat & BANK1_HWIRQ)\n\t\treturn armctrl_translate_bank(1);\n\telse if (stat & BANK2_HWIRQ)\n\t\treturn armctrl_translate_bank(2);\n\telse\n\t\tBUG();\n}\n\nstatic uint32_t bcm2836_get_pending(void)\n{\n\tint cpu = smp_processor_id();\n\tuint32_t stat;\n\tuint32_t irq;\n\n\tstat = readl_relaxed(bcm2836_base + LOCAL_IRQ_PENDING0 + 4 * cpu);\n\tmb();\n\n\tif (stat & BIT(LOCAL_IRQ_MAILBOX0)) {\n\t\tvoid *mailbox0;\n\t\tuint32_t mbox_val;\n\n\t\t/*\n\t\t * support 32 IPI, here only use 16 bit to routing\n\t\t * to the sgi interrupt\n\t\t */\n\t\tmailbox0 = bcm2836_base + LOCAL_MAILBOX0_CLR0 + 16 * cpu;\n\t\tmbox_val = readl_relaxed(mailbox0);\n\t\tif (mbox_val == 0)\n\t\t\treturn BAD_IRQ;\n\n\t\tirq = __ffs(mbox_val);\n\t\twritel_relaxed(1 << irq, mailbox0);\n\t\tdsb();\n\n\t\tif (irq >= 16)\n\t\t\treturn BAD_IRQ;\n\n\t\treturn irq;\n\t} else if (stat) {\n\t\t/*\n\t\t * map other irq except mailbox to PPI as below:\n\t\t * 16\t: CNTPSIRQ\n\t\t * 17\t: CNTPNSIRQ\n\t\t * 18\t: CNTHPIRQ\n\t\t * 19\t: CNTVIRQ\n\t\t * 20 - 23 : Mailbox irq\n\t\t * 24\t: GPU interrupt\n\t\t * 25\t: PMU interrupt\n\t\t * 26\t: AXI outstanding interrupt\n\t\t * 27\t: Local timer interrupt\n\t\t */\n\t\tirq = __ffs(stat) + 16;\n\t\treturn irq;\n\t}\n\n\treturn BAD_IRQ;\n}\n\nstatic void bcm2836_mask_per_cpu_irq(unsigned int reg_offset,\n\t\tunsigned int bit, int cpu)\n{\n\tvoid *reg = bcm2836_base + reg_offset + 4 * cpu;\n\n\twritel_relaxed(readl_relaxed(reg) & ~BIT(bit), reg);\n\tdsb();\n}\n\nstatic void bcm2836_unmask_per_cpu_irq(unsigned int reg_offset,\n\t\tunsigned int bit, int cpu)\n{\n\tvoid *reg = bcm2836_base + reg_offset + 4 * cpu;\n\n\twritel_relaxed(readl_relaxed(reg) | BIT(bit), reg);\n\tdsb();\n}\n\nstatic void inline __bcm2836_mask_irq(uint32_t irq, int cpu)\n{\n\tint offset;\n\n\tif (irq >= 32)\n\t\tbcm2835_mask_irq(irq);\n\n\t/* TBD : sgi always enable */\n\tif (irq < 16)\n\t\treturn;\n\n\toffset = irq - 16;\n\tswitch (offset) {\n\tcase LOCAL_IRQ_CNTPSIRQ:\n\tcase LOCAL_IRQ_CNTPNSIRQ:\n\tcase LOCAL_IRQ_CNTHPIRQ:\n\tcase LOCAL_IRQ_CNTVIRQ:\n\t\tbcm2836_mask_per_cpu_irq(LOCAL_TIMER_INT_CONTROL0, offset, cpu);\n\t\tbreak;\n\n\tcase LOCAL_IRQ_PMU_FAST:\n\t\twritel_relaxed(1 << cpu, bcm2836_base + LOCAL_PM_ROUTING_CLR);\n\t\tdsb();\n\t\tbreak;\n\n\tcase LOCAL_IRQ_GPU_FAST:\n\t\tbreak;\n\t}\n}\n\nstatic void inline __bcm2836_unmask_irq(uint32_t irq, int cpu)\n{\n\tint offset;\n\n\tif (irq >= 32)\n\t\tbcm2835_unmask_irq(irq);\n\n\tif (irq < 16)\n\t\treturn;\n\n\toffset = irq - 16;\n\tswitch (offset) {\n\tcase LOCAL_IRQ_CNTPSIRQ:\n\tcase LOCAL_IRQ_CNTPNSIRQ:\n\tcase LOCAL_IRQ_CNTHPIRQ:\n\tcase LOCAL_IRQ_CNTVIRQ:\n\t\tbcm2836_unmask_per_cpu_irq(LOCAL_TIMER_INT_CONTROL0, offset, cpu);\n\t\tbreak;\n\n\tcase LOCAL_IRQ_PMU_FAST:\n\t\twritel_relaxed(1 << cpu, bcm2836_base + LOCAL_PM_ROUTING_SET);\n\t\tdsb();\n\t\tbreak;\n\n\tcase LOCAL_IRQ_GPU_FAST:\n\t\tbreak;\n\t}\n}\n\nstatic int bcm2836_set_irq_priority(uint32_t irq, uint32_t pr)\n{\n\treturn 0;\n}\n\nstatic void bcm2836_mask_irq(uint32_t irq)\n{\n\t__bcm2836_mask_irq(irq, smp_processor_id());\n}\n\nstatic void bcm2836_unmask_irq(uint32_t irq)\n{\n\t__bcm2836_unmask_irq(irq, smp_processor_id());\n}\n\nstatic void bcm2836_mask_irq_cpu(uint32_t irq, int cpu)\n{\n\t__bcm2836_mask_irq(irq, cpu);\n}\n\nstatic void bcm2836_unmask_irq_cpu(uint32_t irq, int cpu)\n{\n\t__bcm2836_unmask_irq(irq, cpu);\n}\n\nstatic void bcm2836_send_sgi(uint32_t sgi, enum sgi_mode mode, cpumask_t *cpu)\n{\n\tint c;\n\tvoid *mailbox0_base = bcm2836_base + LOCAL_MAILBOX0_SET0;\n\n\tdsb();\n\tif (sgi >= 16)\n\t\treturn;\n\n\tswitch (mode) {\n\tcase SGI_TO_OTHERS:\n\t\tfor_each_cpu(c, cpu) {\n\t\t\tif (c == smp_processor_id())\n\t\t\t\tcontinue;\n\t\t\twritel_relaxed(1 << sgi, mailbox0_base + 16 * c);\n\t\t\tdsb();\n\t\t}\n\t\tbreak;\n\tcase SGI_TO_SELF:\n\t\twritel_relaxed(1 << sgi, mailbox0_base +\n\t\t\t\t16 * smp_processor_id());\n\t\tdsb();\n\t\tbreak;\n\tcase SGI_TO_LIST:\n\t\tfor_each_cpu(c, cpu) {\n\t\t\twritel_relaxed(1 << sgi, mailbox0_base + 16 * c);\n\t\t\tdsb();\n\t\t}\n\t\tbreak;\n\t}\n}\n\nstatic int bcm2836_set_irq_affinity(uint32_t irq, uint32_t pcpu)\n{\n\treturn 0;\n}\n\nstatic int bcm2836_set_irq_type(uint32_t irq, uint32_t type)\n{\n\treturn 0;\n}\n\nstatic void bcm2836_dir_irq(uint32_t irq)\n{\n\tif (irq >= 32)\n\t\tbcm2835_unmask_irq(irq);\n}\n\nstatic void bcm2836_eoi_irq(uint32_t irq)\n{\n\tif (irq >= 32)\n\t\tbcm2835_mask_irq(irq);\n}\n\nstatic int bcm2835_irq_handler(uint32_t irq, void *data)\n{\n\tuint32_t no;\n\tstruct irq_desc *irq_desc;\n\n\twhile ((no = bcm2835_get_pending()) != BAD_IRQ) {\n\t\tirq_desc = get_irq_desc(no);\n\t\tif (!irq_desc || !irq_desc->handler) {\n\t\t\tbcm2835_mask_irq(no);\n\t\t\tpr_err(\"irq is not register disable it %d\\n\", no);\n\t\t\tcontinue;\n\t\t}\n\n\t\tirq_desc->handler(irq_desc->hno, irq_desc->pdata);\n\n\t\t/*\n\t\t * if the hardware irq is for vm mask it here\n\t\t * until the vm notify that the hardware irq\n\t\t * is handled\n\t\t */\n\t\tif (test_bit(IRQ_FLAGS_VCPU_BIT, &irq_desc->flags))\n\t\t\tbcm2835_mask_irq(no);\n\t}\n\n\treturn 0;\n}\n\nstatic int __init_text bcm2836_irq_init(struct device_node *node)\n{\n\tvoid *base;\n\tint b;\n\n\tpr_notice(\"boardcom bcm2836 l1 interrupt init\\n\");\n\n\tbcm2836_base = io_remap(0x40000000, 0x100);\n\n\t/*\n\t * set the timer to source for the 19.2Mhz crstal clock\n\t * and set the timer prescaler to 1:1\n\t */\n\twritel_relaxed(0, bcm2836_base + LOCAL_CONTROL);\n\twritel_relaxed(ptov(0x80000000), bcm2836_base + LOCAL_PRESCALER);\n\n\t/*\n\t * int rpi-3b there are two irq_chip controller, the\n\t * bcm2836 local interrupt controller is percpu and\n\t * the bcm2835 is not percpu so :\n\t * bcm2836 id  : 0 - 31\n\t * bcm2835 id  : 32 - 127\n\t * enable mailbox0 interrupt for each core\n\t */\n\twritel_relaxed(1, bcm2836_base + LOCAL_MAILBOX_INT_CONTROL0);\n\twritel_relaxed(1, bcm2836_base + LOCAL_MAILBOX_INT_CONTROL0 + 0x4);\n\twritel_relaxed(1, bcm2836_base + LOCAL_MAILBOX_INT_CONTROL0 + 0x8);\n\twritel_relaxed(1, bcm2836_base + LOCAL_MAILBOX_INT_CONTROL0 + 0xc);\n\n\t/* init the bcm2835 interrupt controller for spi */\n\tbase = intc.base = io_remap(ptov(0x3f00b200), 0x100);\n\n\tfor (b = 0; b < NR_BANKS; b++) {\n\t\tintc.pending[b] = base + reg_pending[b];\n\t\tintc.enable[b] = base + reg_enable[b];\n\t\tintc.disable[b] = base + reg_disable[b];\n\t}\n\n\t/*\n\t * request the irq handler for the bcm2835 inc\n\t * TBD - now the hardware irq only route to cpu0\n\t */\n\trequest_irq(24, bcm2835_irq_handler, 0, \"bcm2835_irq\", NULL);\n\n\treturn 0;\n}\n\nstatic int __init_text bcm2836_secondary_init(void)\n{\n\treturn 0;\n}\n\nstatic struct irq_chip bcm2836_irq_chip = {\n\t.irq_mask\t\t= bcm2836_mask_irq,\n\t.irq_mask_cpu\t\t= bcm2836_mask_irq_cpu,\n\t.irq_unmask\t\t= bcm2836_unmask_irq,\n\t.irq_unmask_cpu\t\t= bcm2836_unmask_irq_cpu,\n\t.irq_eoi\t\t= bcm2836_eoi_irq,\n\t.irq_dir\t\t= bcm2836_dir_irq,\n\t.irq_set_type\t\t= bcm2836_set_irq_type,\n\t.get_pending_irq\t= bcm2836_get_pending,\n\t.irq_set_affinity \t= bcm2836_set_irq_affinity,\n\t.irq_xlate\t\t= bcm2836_xlate_irq,\n\t.send_sgi\t\t= bcm2836_send_sgi,\n\t.irq_set_priority\t= bcm2836_set_irq_priority,\n\t.init\t\t\t= bcm2836_irq_init,\n\t.secondary_init\t\t= bcm2836_secondary_init,\n};\nIRQCHIP_DECLARE(bcm2836_chip, bcmirq_match_table,\n\t\t(void *)&bcm2836_irq_chip);\n"
  },
  {
    "path": "kernel/drivers/irq-chips/irqchip.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <device/bcm_irq.h>\n#include <minos/device_id.h>\n#include <minos/of.h>\n\nint bcm2836_xlate_irq(struct device_node *node,\n\t\tuint32_t *intspec, unsigned int intsize,\n\t\tuint32_t *hwirq, unsigned long *type)\n{\n\tint phandle;\n\n\tphandle = of_get_phandle(node);\n\tif (phandle == 3) {\n\t\tif (intsize != 2)\n\t\t\treturn -EINVAL;\n\n\t\t/* workaroud for the bcm2835 irq */\n\t\tif (intspec[0] == 8)\n\t\t\treturn -EINVAL;\n\n\t\t*hwirq = intspec[0] + 16;\n\t\t*type = intspec[1];\n\t\treturn 0;\n\t}\n\n\tif (intsize == 1) {\n\t\tif (intspec[0] < 16) {\n\t\t\t*hwirq = intspec[0] + 16;\n\t\t\t*type = 0;\n\t\t\treturn 0;\n\t\t}\n\t\treturn -EINVAL;\n\t} else if (intsize == 2) {\n\t\tif (intspec[0] >= NR_BANKS)\n\t\t\treturn -EINVAL;\n\t\tif (intspec[1] >= IRQS_PER_BANK)\n\t\t\treturn -EINVAL;\n\n\t\t*hwirq = MAKE_HWIRQ(intspec[0], intspec[1]);\n\t\t*type = 0;\n\t\treturn 0;\n\t} else\n\t\treturn -EINVAL;\n}\n\nint gic_xlate_irq(struct device_node *node,\n\t\tuint32_t *intspec, unsigned int intsize,\n\t\tuint32_t *hwirq, unsigned long *type)\n{\n\tif (intsize != 3)\n\t\treturn -EINVAL;\n\n\tif (intspec[0] == 0)\n\t\t*hwirq = intspec[1] + 32;\n\telse if (intspec[0] == 1) {\n\t\tif (intspec[1] >= 16)\n\t\t\treturn -EINVAL;\n\t\t*hwirq = intspec[1] + 16;\n\t} else\n\t\treturn -EINVAL;\n\n\t*type = intspec[2];\n\treturn 0;\n}\n"
  },
  {
    "path": "kernel/drivers/of/Kconfig",
    "content": ""
  },
  {
    "path": "kernel/drivers/of/Makefile",
    "content": "obj-y\t+= of.o\nobj-y\t+= of_mm.o\n"
  },
  {
    "path": "kernel/drivers/of/of.c",
    "content": "/*\n * Copyright (C) 2018 - 2019 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/mm.h>\n#include <libfdt/libfdt.h>\n#include <minos/of.h>\n#include <minos/irq.h>\n#include <minos/bootarg.h>\n#include <minos/platform.h>\n\n#define OF_MAX_DEEPTH\t5\n\nvoid *dtb_address;\nstruct device_node *of_root_node;\n\nint of_spin_table_init(phy_addr_t *smp_holding)\n{\n\tint offset, node, i, len;\n\tchar name[16];\n\tconst void *data;\n\tfdt32_t *tmp;\n\n\t/*\n\t * if the smp cpu boot using spin table\n\t * get the spin table address and these\n\t * address must mapped to the hypervisor\n\t * address space\n\t */\n\n\toffset = of_get_node_by_name(dtb_address, 0, \"cpus\");\n\tif (offset <= 0) {\n\t\tpr_err(\"can not find cpus node in dtb\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\tfor (i = 0; i < CONFIG_NR_CPUS; i++) {\n\t\tsprintf(name, \"cpu@%x\", cpuid_to_affinity(i));\n\t\tnode = of_get_node_by_name(dtb_address, offset, name);\n\t\tif (node <= 0) {\n\t\t\tpr_err(\"can not find %s\\n\", name);\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* get the enable methold content */\n\t\tdata = fdt_getprop(dtb_address, node, \"enable-method\", &len);\n\t\tif (!data || len <= 0)\n\t\t\tcontinue;\n\n\t\tif (strncmp(\"spin-table\", (char *)data, 10))\n\t\t\tcontinue;\n\n\t\t/* read the holding address */\n\t\tdata = fdt_getprop(dtb_address, node, \"cpu-release-addr\", &len);\n\t\tif (!data || len <= sizeof(uint32_t))\n\t\t\tcontinue;\n\n\t\tlen = len / sizeof(uint32_t);\n\t\ttmp = (uint32_t *)data;\n\t\tif (len == 1)\n\t\t\tsmp_holding[i] = fdt32_to_cpu(tmp[0]);\n\t\telse\n\t\t\tsmp_holding[i] = fdt32_to_cpu64(tmp[0], tmp[1]);\n\n\t\tpr_notice(\"%s using spin-table relase addr 0x%p\\n\",\n\t\t\t\tname, smp_holding[i]);\n\t}\n\n\treturn 0;\n}\n\nint fdt_n_size_cells(void *dtb, int node)\n{\n\tfdt32_t *v;\n\tint parent, child = node;\n\n\tparent = fdt_parent_offset(dtb, child);\n\n\tdo {\n\t\tif (parent >= 0)\n\t\t\tchild = parent;\n\t\tv = (fdt32_t *)fdt_getprop(dtb, child, \"#size-cells\", NULL);\n\t\tif (v)\n\t\t\treturn fdt32_to_cpu(*v);\n\n\t\tparent = fdt_parent_offset(dtb, child);\n\t} while (parent >= 0);\n\n\treturn 2;\n}\n\nint fdt_n_addr_cells(void *dtb, int node)\n{\n\tfdt32_t *v;\n\tint parent, child = node;\n\n\tparent = fdt_parent_offset(dtb, child);\n\n\tdo {\n\t\tif (parent >= 0)\n\t\t\tchild = parent;\n\t\tv = (fdt32_t *)fdt_getprop(dtb, child, \"#address-cells\", NULL);\n\t\tif (v)\n\t\t\treturn fdt32_to_cpu(*v);\n\n\t\tparent = fdt_parent_offset(dtb, child);\n\t} while (parent >= 0);\n\n\treturn 2;\n}\n\nstatic inline void *__of_getprop(void *dtb, int node,\n\t\tchar *attr, int *len)\n{\n\tconst void *data;\n\tint length;\n\n\tif (!dtb || node <= 0 || !attr)\n\t\treturn NULL;\n\n\tdata = fdt_getprop(dtb, node, attr, &length);\n\tif (!data || (length <= 0))\n\t\treturn NULL;\n\n\tif (len)\n\t\t*len = length;\n\n\treturn (void *)data;\n}\n\nvoid *of_getprop(struct device_node *node, char *attr, int *len)\n{\n\treturn __of_getprop(node->data, node->offset, attr, len);\n}\n\nstatic int __of_get_node_by_name(void *data, int pnode,\n\t\tchar *str, int deepth)\n{\n\tconst char *name;\n\tint node = -1, child, len;\n\n\tif (OF_MAX_DEEPTH >= 10)\n\t\treturn -ENOENT;\n\n\tfdt_for_each_subnode(node, data, pnode) {\n\t\tif (NULL == (name = fdt_get_name(data, node, &len)))\n\t\t\tcontinue;\n\t\tif (len < 0)\n\t\t\tcontinue;\n\n\t\tif (strncmp(name, str, strlen(str)) == 0)\n\t\t\treturn node;\n\t\telse {\n\t\t\tchild = __of_get_node_by_name(data, node,\n\t\t\t\t\tstr, deepth + 1);\n\t\t\tif (child > 0)\n\t\t\t\treturn child;\n\t\t}\n\t}\n\n\treturn -ENOENT;\n}\n\nint of_get_node_by_name(void *data, int pnode, char *str)\n{\n\tif (!data || (pnode < 0) || !str)\n\t\treturn -EINVAL;\n\n\treturn __of_get_node_by_name(data, pnode, str, 0);\n}\n\nconst char *__of_get_compatible(void *dtb, int node)\n{\n\tconst void *data;\n\tint len;\n\n\tdata = fdt_getprop(dtb, node, \"compatible\", &len);\n\tif (!data || len == 0)\n\t\treturn NULL;\n\n\treturn (const char *)data;\n}\n\nint __of_get_bool(void *dtb, int node, char *attr)\n{\n\tint len;\n\tconst struct fdt_property *prop;\n\n\tprop = fdt_get_property(dtb, node, attr, &len);\n\treturn (prop != NULL);\n}\n\nint of_get_bool(struct device_node *node, char *attr)\n{\n\treturn __of_get_bool(node->data, node->offset, attr);\n}\n\nint __of_get_string(void *dtb, int node, char *attr, char *str, int len)\n{\n\tchar *s;\n\tint length;\n\n\tmemset(str, 0, len);\n\ts = (char *)__of_getprop(dtb, node, attr, &length);\n\tif (!s || !str || (length == 0))\n\t\treturn -EINVAL;\n\n\tlength = MIN(len - 1, length);\n\tstrncpy(str, s, length);\n\n\treturn length;\n}\n\nchar *of_get_cmdline(void *dtb)\n{\n\tint node, len;\n\tconst void *data = NULL;\n\n\tnode = fdt_path_offset(dtb, \"/chosen\");\n\tif (node <= 0)\n\t\treturn NULL;\n\n\tdata = fdt_getprop(dtb, node, \"bootargs\", &len);\n\treturn (char *)data;\n}\n\nint __of_get_u16_array(void *dtb, int node, char *attr,\n\t\tuint16_t *array, int len)\n{\n\tfdt16_t *val;\n\tint length, i;\n\n\tmemset(array, 0, sizeof(uint16_t) * len);\n\tval = (fdt16_t *)__of_getprop(dtb, node, attr, &length);\n\tif (!val)\n\t\treturn -EINVAL;\n\n\tif ((length % sizeof(uint16_t)) != 0) {\n\t\tpr_err(\"node is not a u32 array %d\\n\", length);\n\t\treturn -EINVAL;\n\t}\n\n\tlength = length / sizeof(fdt16_t);\n\tlength = MIN(len, length);\n\n\tfor (i = 0; i < length; i++)\n\t\t*array++ = fdt16_to_cpu(val[i]);\n\n\treturn length;\n}\n\nint __of_get_u32_array(void *dtb, int node, char *attr,\n\t\tuint32_t *array, int len)\n{\n\tfdt32_t *val;\n\tint length, i;\n\n\tmemset(array, 0, sizeof(uint32_t) * len);\n\tval = (fdt32_t *)__of_getprop(dtb, node, attr, &length);\n\tif (!val)\n\t\treturn -EINVAL;\n\n\tif ((length % sizeof(fdt32_t)) != 0) {\n\t\tpr_err(\"node is not a u32 array %d\\n\", length);\n\t\treturn -EINVAL;\n\t}\n\n\tlength = length / sizeof(fdt32_t);\n\tlength = MIN(len, length);\n\n\tfor (i = 0; i < length; i++)\n\t\t*array++ = fdt32_to_cpu(val[i]);\n\n\treturn length;\n}\n\nint __of_get_u64_array(void *dtb, int node, char *attr,\n\t\tuint64_t *array, int len)\n{\n\tfdt64_t *val;\n\tint length, i;\n\n\tmemset(array, 0, sizeof(uint64_t) * len);\n\tval = (fdt64_t *)__of_getprop(dtb, node, attr, &length);\n\tif (!val) {\n\t\tpr_err(\"of: attr %s not found\\n\", attr);\n\t\treturn -EINVAL;\n\t}\n\n\tif ((length % sizeof(fdt64_t)) != 0) {\n\t\tpr_err(\"node is not a u64 array %d\\n\", length);\n\t\treturn -EINVAL;\n\t}\n\n\tlength = length / sizeof(uint64_t);\n\tlength = MIN(len, length);\n\n\tfor (i = 0; i < length; i++)\n\t\t*array++ = fdt64_to_cpu(val[i]);\n\n\treturn length;\n}\n\nstatic inline struct device_node *alloc_device_node(void)\n{\n\tstruct device_node *node;\n\n\tnode = zalloc(sizeof(struct device_node));\n\tif (!node) {\n\t\tpr_warn(\"%s no enough memory\\n\", __func__);\n\t\treturn NULL;\n\t}\n\n\treturn node;\n}\n\nstatic int of_parse_dt_class(struct device_node *node)\n{\n\tint ret;\n\tchar type[64];\n\n\tret = __of_get_string(node->data, node->offset,\n\t\t\t\"device_type\", type, 64);\n\tif (ret > 0) {\n\t\tif (strcmp(type, \"cpu\") == 0)\n\t\t\tnode->class = DT_CLASS_CPU;\n\t\telse if (strcmp(type, \"memory\") == 0)\n\t\t\tnode->class = DT_CLASS_MEMORY;\n\t\telse if (strcmp(type, \"pci\") == 0)\n\t\t\tnode->class = DT_CLASS_PCI_BUS;\n\t\telse if (strcmp(type, \"virtual_machine\") == 0)\n\t\t\tnode->class = DT_CLASS_VM;\n\t\telse if (strcmp(type, \"vmbox\") == 0)\n\t\t\tnode->class = DT_CLASS_VMBOX;\n\t\telse\n\t\t\tnode->class = DT_CLASS_OTHER;\n\t} else {\n\t\tret = __of_get_bool(node->data, node->offset,\n\t\t\t\t\"interrupt-controller\");\n\t\tif (ret) {\n\t\t\tnode->class = DT_CLASS_IRQCHIP;\n\t\t\treturn 0;\n\t\t}\n\n\t\tif (strcmp(node->name, \"timer\") == 0) {\n\t\t\tnode->class = DT_CLASS_TIMER;\n\t\t\treturn 0;\n\t\t}\n\n\t\tif (!fdt_node_check_compatible(node->data,\n\t\t\t\tnode->offset, \"simple-bus\")) {\n\t\t\tnode->class = DT_CLASS_SIMPLE_BUS;\n\t\t\treturn 0;\n\t\t}\n\n\t\tret = __of_get_bool(node->data, node->offset,\n\t\t\t\t\"virtual_device\");\n\t\tif (ret) {\n\t\t\tnode->class = DT_CLASS_VDEV;\n\t\t\treturn 0;\n\t\t}\n\n\t\tswitch (node->parent->class) {\n\t\tcase DT_CLASS_IRQCHIP:\n\t\tcase DT_CLASS_CPU:\n\t\tcase DT_CLASS_PDEV:\n\t\tcase DT_CLASS_VDEV:\n\t\t\tnode->class = node->parent->class;\n\t\t\treturn 0;\n\t\tdefault:\n\t\t\tbreak;;\n\t\t}\n\n\t\tif (node->compatible)\n\t\t\tnode->class = DT_CLASS_PDEV;\n\t\telse\n\t\t\tnode->class = DT_CLASS_OTHER;\n\t}\n\n\treturn 0;\n}\n\nint of_device_match(struct device_node *node, char **comp)\n{\n\tif (!node || !comp)\n\t\treturn -EINVAL;\n\n\twhile (*comp != NULL) {\n\t\tif (!fdt_node_check_compatible(node->data,\n\t\t\t\tnode->offset, *comp))\n\t\t\treturn 1;\n\n\t\tcomp++;\n\t}\n\n\treturn 0;\n}\n\nstatic int __of_parse_device_node(struct device_node *root,\n\t\tstruct device_node *pnode)\n{\n\tint child, index = 0;\n\tstruct device_node *node, *prev;\n\tvoid *data = pnode->data;\n\n\tif (!pnode)\n\t\treturn -EINVAL;\n\n\tfdt_for_each_subnode(child, data, pnode->offset) {\n\t\tnode = alloc_device_node();\n\t\tif (!node)\n\t\t\treturn -ENOMEM;\n\n\t\tnode->name = fdt_get_name(data, child, NULL);\n\t\tnode->compatible = __of_get_compatible(data, child);\n\t\tnode->offset = child;\n\t\tnode->data = data;\n\t\tnode->parent = pnode;\n\t\tnode->flags |= DEVICE_NODE_F_OF;\n\n\t\t/* udpate the child and the sibling */\n\t\tif (index == 0) {\n\t\t\tpnode->child = node;\n\t\t\tindex = 1;\n\t\t} else {\n\t\t\tprev->sibling = node;\n\t\t}\n\n\t\tprev = node;\n\t\tnode->next = root->next;\n\t\troot->next = node;\n\t\tof_parse_dt_class(node);\n\t\t__of_parse_device_node(root, node);\n\t}\n\n\treturn 0;\n}\n\n/* must pass a root device node to this function */\nstatic void *__iterate_device_node(struct device_node *node,\n\t\tof_iterate_fn func, void *arg, int loop)\n{\n\tstruct device_node *child, *sibling, *n;\n\n\tif (!node)\n\t\treturn NULL;\n\n\tchild = node->child;\n\tn = func(node, arg);\n\tif (n && !loop)\n\t\treturn n;\n\n\twhile (child) {\n\t\tsibling = child->sibling;\n\t\tn = __iterate_device_node(child, func, arg, loop);\n\t\tif (n && !loop)\n\t\t\treturn n;\n\t\tchild = sibling;\n\t}\n\n\treturn NULL;\n}\n\nvoid *of_iterate_all_node_loop(struct device_node *node,\n\t\tof_iterate_fn func, void *arg)\n{\n\treturn __iterate_device_node(node, func, arg, 1);\n}\n\nvoid *of_iterate_all_node(struct device_node *node,\n\t\tof_iterate_fn func, void *arg)\n{\n\treturn __iterate_device_node(node, func, arg, 0);\n}\n\nstatic void *find_node_by_compatible(struct device_node *node, void *comp)\n{\n\tchar **str = (char **)comp;\n\n\tif (of_device_match(node, str))\n\t\treturn node;\n\n\treturn NULL;\n}\n\nstatic void *find_node_by_name(struct device_node *node, void *name)\n{\n\tif (node->name && !(strcmp(node->name, (char *)name)))\n\t\treturn node;\n\n\treturn NULL;\n}\n\nstruct device_node *\nof_find_node_by_compatible(struct device_node *root, char **comp)\n{\n\treturn (struct device_node *)__iterate_device_node(root,\n\t\t\tfind_node_by_compatible, (void *)comp, 0);\n}\n\nstruct device_node *\nof_find_node_by_name(struct device_node *root, char *name)\n{\n\treturn (struct device_node *)__iterate_device_node(root,\n\t\t\tfind_node_by_name, (void *)name, 0);\n}\n\nint of_n_addr_cells(struct device_node *node)\n{\n\tfdt32_t *ip;\n\n\tdo {\n\t\tip = (fdt32_t *)fdt_getprop(node->data, node->offset,\n\t\t\t\t\"#address-cells\", NULL);\n\t\tif (ip)\n\t\t\treturn fdt32_to_cpu(*ip);\n\n\t\tif (node->parent)\n\t\t\tnode = node->parent;\n\t} while (node);\n\n\treturn 2;\n}\n\nint of_n_size_cells(struct device_node *node)\n{\n\tfdt32_t *ip;\n\n\tdo {\n\t\tip = (fdt32_t *)fdt_getprop(node->data, node->offset,\n\t\t\t\t\"#size-cells\", NULL);\n\t\tif (ip)\n\t\t\treturn fdt32_to_cpu(*ip);\n\n\t\tif (node->parent)\n\t\t\tnode = node->parent;\n\t} while (node);\n\n\treturn 1;\n}\n\nint of_get_phandle(struct device_node *node)\n{\n\tconst struct fdt_property *prop;\n\tint len;\n\n\tprop = fdt_get_property(node->data, node->offset,\n\t\t\t\"interrupt-parent\", &len);\n\tif (!prop)\n\t\treturn -1;\n\n\treturn fdt32_to_cpu(*(fdt32_t *)prop->data);\n}\n\nint of_n_interrupt_cells(struct device_node *node)\n{\n\tint ret, len;\n\tuint32_t ni = 0;\n\tstruct device_node *parent = node;\n\tuint32_t phandle;\n\tint offset;\n\tconst struct fdt_property *prop;\n\n\twhile (parent) {\n\t\tprop = fdt_get_property(parent->data, parent->offset,\n\t\t\t\t\"interrupt-parent\", &len);\n\t\tif (!prop || !prop->data)\n\t\t\tgoto repeat;\n\n\t\tphandle = fdt32_to_cpu(*(fdt32_t *)prop->data);\n\t\toffset = fdt_node_offset_by_phandle(parent->data, phandle);\n\t\tif (offset <= 0)\n\t\t\treturn 0;\n\n\t\tret = __of_get_u32_array(parent->data, offset,\n\t\t\t\t\"#interrupt-cells\", &ni, 1);\n\t\tif (ret == 1)\n\t\t\treturn ni;\nrepeat:\n\t\tparent = parent->parent;\n\t}\n\n\treturn 0;\n}\n\nint of_n_addr_count(struct device_node *node)\n{\n\tint na, ns;\n\tint len;\n\tconst void *prop;\n\n\tna = fdt_n_addr_cells(node->data, node->offset);\n\tns = fdt_n_size_cells(node->data, node->offset);\n\n\tprop = fdt_getprop(node->data, node->offset, \"reg\", &len);\n\tif (!prop)\n\t\treturn 0;\n\n\tlen = len / ((na + ns) * sizeof(fdt32_t));\n\treturn len;\n}\n\nint of_data(void *data)\n{\n\treturn !fdt_check_header(data);\n}\n\nstatic inline u64 of_read_number(const fdt32_t *cell, int size)\n{\n\tu64 r = 0;\n\twhile (size--) {\n\t\tr = (r << 32) | fdt32_to_cpu(*cell);\n\t\tcell++;\n\t}\n\treturn r;\n}\n\nstatic inline int of_check_counts(int na, int ns)\n{\n\treturn ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && (ns) > 0);\n}\n\n/* Callbacks for bus specific translators */\nstruct of_bus {\n\tconst char *name;\n\tconst char *addresses;\n\tvoid (*count_cells)(void *blob, int parentoffset,\n\t\t\tint *addrc, int *sizec);\n\tuint64_t (*map)(u32 *addr, const u32 *range,\n\t\t\tint na, int ns, int pna);\n\tint (*translate)(u32 *addr, u64 offset, int na);\n};\n\n/* Default translator (generic bus) */\nstatic void of_bus_default_count_cells(void *blob,\n\t\tint parentoffset, int *addrc, int *sizec)\n{\n\tconst fdt32_t *prop;\n\n\tif (addrc) {\n\t\tprop = fdt_getprop(blob, parentoffset, \"#address-cells\", NULL);\n\t\tif (prop)\n\t\t\t*addrc = fdt32_to_cpu(*prop);\n\t\telse\n\t\t\t*addrc = 2;\n\t}\n\n\tif (sizec) {\n\t\tprop = fdt_getprop(blob, parentoffset, \"#size-cells\", NULL);\n\t\tif (prop)\n\t\t\t*sizec = fdt32_to_cpu(*prop);\n\t\telse\n\t\t\t*sizec = 1;\n\t}\n}\n\nstatic uint64_t of_bus_default_map(fdt32_t *addr,\n\t\tconst fdt32_t *range,\n\t\tint na, int ns, int pna)\n{\n\tuint64_t cp, s, da;\n\n\tcp = of_read_number(range, na);\n\ts  = of_read_number(range + na + pna, ns);\n\tda = of_read_number(addr, na);\n\n\tpr_debug(\"OF: default map, cp=0x%p, s=0x%p, da=0x%p\\n\", cp, s, da);\n\n\tif (da < cp || da >= (cp + s))\n\t\treturn OF_BAD_ADDR;\n\treturn da - cp;\n}\n\nstatic int of_bus_default_translate(u32 *addr, u64 offset, int na)\n{\n\tuint64_t a = of_read_number(addr, na);\n\tmemset(addr, 0, na * 4);\n\ta += offset;\n\tif (na > 1) {\n\t\taddr[na - 2] = a >> 32;\n\t\taddr[na - 2] = cpu_to_fdt32(addr[na - 2]);\n\t}\n\taddr[na - 1] = a & 0xffffffffu;\n\taddr[na - 1] = cpu_to_fdt32(addr[na - 1]);\n\n\treturn 0;\n}\n\n/* Array of bus specific translators */\nstatic struct of_bus of_busses[] = {\n\t/* Default */\n\t{\n\t\t.name = \"default\",\n\t\t.addresses = \"reg\",\n\t\t.count_cells = of_bus_default_count_cells,\n\t\t.map = of_bus_default_map,\n\t\t.translate = of_bus_default_translate,\n\t},\n};\n\nstatic int of_translate_one(void * blob, int parent, struct of_bus *bus,\n\t\t\t    struct of_bus *pbus, uint32_t *addr,\n\t\t\t    int na, int ns, int pna, const char *rprop)\n{\n\tconst uint32_t *ranges;\n\tint rlen;\n\tint rone;\n\tuint64_t offset = OF_BAD_ADDR;\n\n\t/* Normally, an absence of a \"ranges\" property means we are\n\t * crossing a non-translatable boundary, and thus the addresses\n\t * below the current not cannot be converted to CPU physical ones.\n\t * Unfortunately, while this is very clear in the spec, it's not\n\t * what Apple understood, and they do have things like /uni-n or\n\t * /ht nodes with no \"ranges\" property and a lot of perfectly\n\t * useable mapped devices below them. Thus we treat the absence of\n\t * \"ranges\" as equivalent to an empty \"ranges\" property which means\n\t * a 1:1 translation at that level. It's up to the caller not to try\n\t * to translate addresses that aren't supposed to be translated in\n\t * the first place. --BenH.\n\t */\n\tranges = (uint32_t *)fdt_getprop(blob, parent, rprop, &rlen);\n\tif (ranges == NULL || rlen == 0) {\n\t\toffset = of_read_number(addr, na);\n\t\tmemset(addr, 0, pna * 4);\n\t\tpr_debug(\"OF: no ranges, 1:1 translation\\n\");\n\t\tgoto finish;\n\t}\n\n\tpr_debug(\"OF: walking ranges...\\n\");\n\n\t/* Now walk through the ranges */\n\trlen /= 4;\n\trone = na + pna + ns;\n\tfor (; rlen >= rone; rlen -= rone, ranges += rone) {\n\t\toffset = bus->map(addr, ranges, na, ns, pna);\n\t\tif (offset != OF_BAD_ADDR)\n\t\t\tbreak;\n\t}\n\tif (offset == OF_BAD_ADDR) {\n\t\tpr_debug(\"OF: not found !\\n\");\n\t\treturn 1;\n\t}\n\tmemcpy(addr, ranges + na, 4 * pna);\n\n finish:\n\t/* Translate it into parent bus space */\n\treturn pbus->translate(addr, offset, pna);\n}\n\n/*\n * Translate an address from the device-tree into a CPU physical address,\n * this walks up the tree and applies the various bus mappings on the\n * way.\n *\n * Note: We consider that crossing any level with #size-cells == 0 to mean\n * that translation is impossible (that is we are not dealing with a value\n * that can be mapped to a cpu physical address). This is not really specified\n * that way, but this is traditionally the way IBM at least do things\n */\nstatic uint64_t __of_translate_address(struct device_node *node,\n\t\tconst fdt32_t *in_addr, const char *prop)\n{\n\tint node_offset;\n\tstruct device_node *parent;\n\tfdt32_t addr[OF_MAX_ADDR_CELLS];\n\tint na, ns, pna, pns;\n\tstruct of_bus *bus, *pbus;\n\tuint64_t result = OF_BAD_ADDR;\n\tvoid *data;\n\n\tpr_debug(\"OF: ** translation for device %s **\\n\", node->name);\n\n\t/* Get parent & match bus type */\n\tparent = node->parent;\n\tdata = node->data;\n\tif (parent == NULL)\n\t\tgoto bail;\n\tbus = &of_busses[0];\n\n\t/* Cound address cells & copy address locally */\n\tbus->count_cells(data, parent->offset, &na, &ns);\n\tif (!of_check_counts(na, ns)) {\n\t\tpr_warn(\"%s: Bad cell count for %s\\n\", __func__, parent->name);\n\t\tgoto bail;\n\t}\n\tmemcpy(addr, in_addr, na * 4);\n\n\tpr_debug(\"OF: bus is %s (na=%d, ns=%d) on %s\\n\",\n\t\t\tbus->name, na, ns, parent->name);\n\n\t/* Translate */\n\tfor (;;) {\n\t\t/* Switch to parent bus */\n\t\tnode_offset = parent->offset;\n\t\tparent = parent->parent;\n\n\t\t/* If root, we have finished */\n\t\tif (!parent || (parent->offset < 0)) {\n\t\t\tpr_debug(\"OF: reached root node\\n\");\n\t\t\tresult = of_read_number(addr, na);\n\t\t\tbreak;\n\t\t}\n\n\t\t/* Get new parent bus and counts */\n\t\tpbus = &of_busses[0];\n\t\tpbus->count_cells(data, parent->offset, &pna, &pns);\n\t\tif (!of_check_counts(pna, pns)) {\n\t\t\tpr_err(\"%s: Bad cell count for %s\\n\",\n\t\t\t\t\t__func__, parent->name);\n\t\t\tbreak;\n\t\t}\n\n\t\tpr_debug(\"OF: parent bus is %s (na=%d, ns=%d) on %s\\n\",\n\t\t\t\tpbus->name, pna, pns, parent->name);\n\n\t\t/* Apply bus translation */\n\t\tif (of_translate_one(data, node_offset, bus, pbus,\n\t\t\t\t\taddr, na, ns, pna, \"ranges\"))\n\t\t\tbreak;\n\n\t\t/* Complete the move up one level */\n\t\tna = pna;\n\t\tns = pns;\n\t\tbus = pbus;\n\t}\n bail:\n\n\treturn result;\n}\n\nint of_translate_address_index(struct device_node *np,\n\t\tuint64_t *address, uint64_t *size, int index)\n{\n\tconst fdt32_t *reg;\n\tint na, ns, node, len = 0;\n\tvoid *data;\n\n\tif (!np || !np->data || (np->offset <=0))\n\t\treturn -EINVAL;\n\n\tdata = np->data;\n\tnode = np->offset;\n\tna = fdt_n_addr_cells(np->data, np->offset);\n\tif (na < 1) {\n\t\tpr_debug(\"bad #address-cells %s\\n\", np->name);\n\t\treturn -EINVAL;\n\t}\n\n\tns = fdt_n_size_cells(np->data, np->offset);\n\tif (ns < 0) {\n\t\tpr_debug(\"bad #size-cells %s\\n\", np->name);\n\t\treturn -EINVAL;\n\t}\n\n\treg = fdt_getprop(data, node, \"reg\", &len);\n\tif (!reg || (len <= (index * 4) *(na + ns))) {\n\t\tpr_debug(\"index out of range\\n\");\n\t\treturn -ENOENT;\n\t}\n\n\treg += index * (na + ns);\n\n\tif (ns) {\n\t\t*address = __of_translate_address(np, reg, \"ranges\");\n\t\tif (*address == OF_BAD_ADDR)\n\t\t\treturn -EINVAL;\n\n\t\tif (ns == 2)\n\t\t\t*size = fdt32_to_cpu64(reg[na], reg[na + 1]);\n\t\telse\n\t\t\t*size = fdt32_to_cpu(reg[na]);\n\t} else {\n\t\t*address = of_read_number(reg, na);\n\t\t*size = 0;\n\t}\n\n\treturn 0;\n}\n\nint of_translate_address(struct device_node *node,\n\t\tuint64_t *address, uint64_t *size)\n{\n\treturn of_translate_address_index(node, address, size, 0);\n}\n\nint get_device_irq_index(struct device_node *node, uint32_t *irq,\n\t\tunsigned long *flags, int index)\n{\n\tint irq_cells, len, i;\n\tof32_t *value;\n\tuint32_t irqv[4];\n\n\tif (!node)\n\t\treturn -EINVAL;\n\n\tvalue = (of32_t *)of_getprop(node, \"interrupts\", &len);\n\tif (!value || (len < sizeof(of32_t)))\n\t\treturn -ENOENT;\n\n\tirq_cells = of_n_interrupt_cells(node);\n\tif (irq_cells == 0) {\n\t\tpr_err(\"bad irqcells - %s\\n\", node->name);\n\t\treturn -ENOENT;\n\t}\n\n\tpr_debug(\"interrupt-cells %d\\n\", irq_cells);\n\n\tlen = len / sizeof(of32_t);\n\tif (index >= len)\n\t\treturn -ENOENT;\n\n\tvalue += (index * irq_cells);\n\tfor (i = 0; i < irq_cells; i++)\n\t\tirqv[i] = of32_to_cpu(*value++);\n\n\treturn irq_xlate(node, irqv, irq_cells, irq, flags);\n}\n\nint of_init_bootargs(void)\n{\n\tvoid *dtb = dtb_address;\n\tint node, len;\n\tconst void *data = NULL;\n\n\tnode = fdt_path_offset(dtb, \"/chosen\");\n\tif (node <= 0)\n\t\treturn -ENOENT;\n\n\tdata = fdt_getprop(dtb, node, \"bootargs\", &len);\n\tif (!data || (len == 0))\n\t\treturn -ENOENT;\n\n\tbootargs_init(data, len);\n\n\treturn 0;\n}\n\nvoid *of_device_node_match(struct device_node *node, void *s, void *e)\n{\n\tint i, count;\n\tstruct module_id *module;\n\n\tif (e <= s)\n\t\treturn NULL;\n\n\tcount = (e - s) / sizeof(struct module_id);\n\tif (count == 0)\n\t\treturn NULL;\n\n\tfor (i = 0; i < count; i++) {\n\t\tmodule = (struct module_id *)s;\n\t\tif (of_device_match(node, (char **)module->comp))\n\t\t\treturn module->data;\n\n\t\ts += sizeof(struct module_id);\n\t}\n\n\treturn NULL;\n}\n\nvoid of_release_all_node(struct device_node *node)\n{\n\tstruct device_node *tmp = node;\n\tstruct device_node *tmp2;\n\n\tif (!device_node_is_root(node))\n\t\treturn;\n\n\tdo {\n\t\ttmp2 = tmp->next;\n\t\tfree(tmp);\n\t\ttmp = tmp2;\n\t} while (tmp);\n}\n\nstruct device_node *of_parse_device_tree(void *dtb)\n{\n\tstruct device_node *node;\n\tvoid *data = dtb;\n\n\tnode = alloc_device_node();\n\tif (!node)\n\t\treturn node;\n\n\tnode->data = data;\n\tnode->name = \"root node\";\n\tnode->offset = 0;\n\tnode->parent = NULL;\n\tnode->sibling = NULL;\n\tnode->next = NULL;\n\tnode->class = DT_CLASS_OTHER;\n\tnode->compatible = fdt_getprop(data, 0, \"compatible\", NULL);\n\tnode->flags = DEVICE_NODE_F_OF | DEVICE_NODE_F_ROOT;\n\n\t/*\n\t * now parse all the node and convert them to the\n\t * device node struct for the hypervisor and vm0 use\n\t */\n\t__of_parse_device_node(node, node);\n\n\treturn node;\n}\n\nvoid of_parse_host_device_tree(void)\n{\n\tof_root_node = of_parse_device_tree(dtb_address);\n\tASSERT(of_root_node);\n}\n\nstatic inline void *of_get_chosen_prop(const char *name, int len)\n{\n\tint node, length;\n\tvoid *d;\n\n\tnode = fdt_path_offset(dtb_address, \"/chosen\");\n\tif (node <= 0)\n\t\treturn NULL;\n\n\td = (void *)fdt_getprop(dtb_address, node, name, &length);\n\tif (!d || (length < len))\n\t\treturn NULL;\n\n\treturn d;\n}\n\nint of_get_console_name(char **name)\n{\n\tvoid *dtb = dtb_address;\n\tint node,  len;\n\tconst void *data = NULL;\n\n\tnode = fdt_path_offset(dtb, \"/chosen\");\n\tif (node <= 0)\n\t\treturn -ENOENT;\n\n\tdata = fdt_getprop(dtb, node, \"minos,stdout\", &len);\n\tif (!data || (len == 0))\n\t\treturn -ENOENT;\n\n\t*name = (char *)data;\n\treturn 0;\n}\n\nstatic int of_get_chosen_prop32(const char *name, uint32_t *value)\n{\n\tfdt32_t *data = of_get_chosen_prop(name, sizeof(uint32_t));\n\tif (!data)\n\t\treturn -ENOENT;\n\n\t*value = fdt32_to_cpu(*data);\n\treturn 0;\n}\n\nstatic int __used of_get_chosen_prop64(const char *name, uint64_t *value)\n{\n\tfdt64_t *data = of_get_chosen_prop(name, sizeof(uint64_t));\n\tif (!data)\n\t\treturn -ENOENT;\n\n\t*value = fdt64_to_cpu(*data);\n\treturn 0;\n}\n\nint of_get_ramdisk_address(unsigned long *start, unsigned long *end)\n{\n\tint ret;\n\tuint32_t address;\n\n\tret = of_get_chosen_prop32(\"minos,ramdisk_start\", &address);\n\tif (ret)\n\t\treturn ret;\n\t*start = (unsigned long)address;\n\n\tret = of_get_chosen_prop32(\"minos,ramdisk_end\", &address);\n\tif (ret)\n\t\treturn ret;\n\t*end = (unsigned long)address;\n\n\treturn 0;\n}\n\nvoid of_setup_platform(void)\n{\n\tint len;\n\tconst void *data;\n\n\tdata = fdt_getprop(dtb_address, 0, \"model\", &len);\n\tif (data)\n\t\tpr_notice(\"model : %s\\n\", (char *)data);\n\n\t/*\n\t * compatible may like arm,fvp-base\\0arm,vexpress\\0\n\t * but here, only parsing the first string\n\t */\n\tdata = fdt_getprop(dtb_address, 0, \"compatible\", &len);\n\tif (data) {\n\t\tpr_notice(\"platform : %s\\n\", (char *)data);\n\t\tplatform_set_to((const char *)data);\n\t}\n}\n\nint of_init(void *dtb)\n{\n\tif (!dtb || fdt_check_header(dtb)) {\n\t\tpr_err(\"bad device tree address: 0x%lx\\n\", dtb);\n\t\tBUG();\n\t}\n\n\tdtb_address = dtb;\n\treturn 0;\n}\n\nint get_system_setup_info(unsigned long *addr, size_t *size)\n{\n\tif (!dtb_address)\n\t\treturn -ENOENT;\n\n\t*addr = vtop(dtb_address);\n\t*size = PAGE_BALIGN(fdt_totalsize(dtb_address));\n\n\treturn 0;\n}\n"
  },
  {
    "path": "kernel/drivers/of/of_mm.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <libfdt/libfdt.h>\n#include <minos/of.h>\n#include <config/config.h>\n#include <minos/memory.h>\n#include <minos/ramdisk.h>\n\nstatic int __fdt_parse_memory_info(int node, char *attr)\n{\n\tint len = 0;\n\tuint64_t base, size;\n\tint size_cell, address_cell;\n\tfdt32_t *v;\n\n\tv = (fdt32_t *)fdt_getprop(dtb_address, node, attr, &len);\n\tif (!v || (len < 8)) {\n\t\tpr_warn(\"no memory info found in dtb\\n\");\n\t\treturn -ENOENT;\n\t}\n\n\tlen = len / 4;\n\tsize_cell = fdt_n_size_cells(dtb_address, node);\n\taddress_cell = fdt_n_addr_cells(dtb_address, node);\n\tpr_notice(\"memory node address_cells:%d size_cells:%d\\n\",\n\t\t\taddress_cell, size_cell);\n\tif ((size_cell > 2) || (size_cell == 0)) {\n\t\tpr_warn(\"memory node size_cells not correct\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\tif ((address_cell > 2) || (address_cell == 0)) {\n\t\tpr_warn(\"memory node address_cells not correct\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\twhile (len >= (size_cell + address_cell)) {\n\t\tif (address_cell == 2) {\n\t\t\tbase = fdt32_to_cpu64(v[0], v[1]);\n\t\t\tv += 2;\n\t\t} else {\n\t\t\tbase = fdt32_to_cpu(v[0]);\n\t\t\tv++;\n\t\t}\n\n\t\tif (size_cell == 2) {\n\t\t\tsize = fdt32_to_cpu64(v[0], v[1]);\n\t\t\tv += 2;\n\t\t} else {\n\t\t\tsize = fdt32_to_cpu(v[0]);\n\t\t\tv += 1;\n\t\t}\n\n\t\tlen -= size_cell + address_cell;\n\t\tadd_memory_region(base, size, MEMORY_REGION_TYPE_NORMAL, 0);\n\t}\n\n\treturn 0;\n}\n\nstatic void __fdt_parse_memreserve(void)\n{\n\tint count, i, ret;\n\tuint64_t address, size;\n\n\t/*\n\t * system can reseve some memory at the head of minos\n\t * memory space\n\t */\n\tif (CONFIG_MINOS_ENTRY_ADDRESS != minos_start) {\n\t\tsize = CONFIG_MINOS_ENTRY_ADDRESS - minos_start;\n\t\tsplit_memory_region(minos_start, size, MEMORY_REGION_TYPE_RSV, 1);\n\t}\n\n\tcount = fdt_num_mem_rsv(dtb_address);\n\tif (count == 0)\n\t\treturn;\n\n\tfor (i = 0; i < count; i++) {\n\t\tret = fdt_get_mem_rsv(dtb_address, i, &address, &size);\n\t\tif (ret)\n\t\t\tcontinue;\n\n\t\tpr_notice(\"find rev memory - id: %d addr: 0x%x size: 0x%x\\n\",\n\t\t\t\ti, address, size);\n\t\tsplit_memory_region(address, size, MEMORY_REGION_TYPE_RSV, 0);\n\t}\n}\n\n#ifdef CONFIG_VIRT\nstatic void __fdt_parse_vm_mem(void)\n{\n\tconst char *name;\n\tconst char *type;\n\tint node, child, len, i;\n\tuint64_t array[2 * 10];\n\tphy_addr_t base;\n\tsize_t size;\n\tint vmid;\n\n\tnode = fdt_path_offset(dtb_address, \"/vms\");\n\tif (node <= 0) {\n\t\tpr_warn(\"no virtual machine found in dts\\n\");\n\t\treturn;\n\t}\n\n\tfdt_for_each_subnode(child, dtb_address, node) {\n\t\ttype = (char *)fdt_getprop(dtb_address, child, \"device_type\", &len);\n\t\tif (!type || (strcmp(type, \"virtual_machine\") != 0))\n\t\t\tcontinue;\n\n\t\t__of_get_u32_array(dtb_address, child, \"vmid\", (uint32_t *)&vmid, 1);\n\n\t\t/*\n\t\t * get the memory information for the vm, each vm will\n\t\t * have max 10 memory region\n\t\t */\n\t\tlen = __of_get_u64_array(dtb_address, child, \"memory\", array, 2 * 10);\n\t\tif ((len <= 0) || ((len % 2) != 0)) {\n\t\t\tname = fdt_get_name(dtb_address, child, NULL);\n\t\t\tpr_err(\"wrong memory information for %s\\n\",\n\t\t\t\t\tname ? name : \"unknown\");\n\t\t\tcontinue;\n\t\t}\n\n\t\tfor (i = 0; i < len; i += 2 ) {\n\t\t\tbase = (phy_addr_t)array[i];\n\t\t\tsize = (size_t)array[i + 1];\n\t\t\tsplit_memory_region(base, size, MEMORY_REGION_TYPE_VM, vmid);\n\t\t}\n\t}\n}\n#endif\n\nstatic void __fdt_parse_kernel_mem(void)\n{\n\tsplit_memory_region(minos_start, CONFIG_MINOS_RAM_SIZE,\n\t\t\tMEMORY_REGION_TYPE_KERNEL, 0);\n}\n\nstatic void __fdt_parse_ramdisk_mem(void)\n{\n\tconst fdt32_t *data;\n\tuint64_t start, end;\n\tint node, len;\n\n\tnode = fdt_path_offset(dtb_address, \"/chosen\");\n\tif (node <= 0)\n\t\treturn;\n\n\tdata = fdt_getprop(dtb_address, node, \"minos,ramdisk-start\", &len);\n\tif (!data || (len == 0))\n\t\treturn;\n\tstart = fdt32_to_cpu64(data[0], data[1]);\n\n\tdata = fdt_getprop(dtb_address, node, \"minos,ramdisk-end\", &len);\n\tif (!data || (len == 0))\n\t\treturn;\n\tend = fdt32_to_cpu64(data[0], data[1]);\n\n\tif (!IS_PAGE_ALIGN(start)) {\n\t\tpr_err(\"ramdisk region is not page align 0x%x\\n\", start);\n\t\treturn;\n\t}\n\n\tsplit_memory_region(start, PAGE_BALIGN(end - start),\n\t\t\tMEMORY_REGION_TYPE_RAMDISK, 0);\n}\n\nint of_parse_memory_info(void)\n{\n\tint node;\n\n\tnode = of_get_node_by_name(dtb_address, 0, \"memory\");\n\tif (node <= 0) {\n\t\tpr_warn(\"no memory node found in dtb\\n\");\n\t\treturn -ENOENT;\n\t}\n\n\t__fdt_parse_memory_info(node, \"reg\");\n\n\t/*\n\t * split the minos kernel's memory region, need\n\t * before to split the dtb memory\n\t */\n\t__fdt_parse_kernel_mem();\n\t__fdt_parse_memreserve();\n\t__fdt_parse_ramdisk_mem();\n\n#ifdef CONFIG_VIRT\n\t__fdt_parse_vm_mem();\n#endif\n\treturn 0;\n}\n\nint of_mm_init(void)\n{\n\tof_parse_memory_info();\n\tdump_memory_info();\n\n\treturn 0;\n}\n"
  },
  {
    "path": "kernel/drivers/serial/Kconfig",
    "content": "menu \"Serial Drivers\"\n\nconfig SERIAL\n\tdef_bool y\n\nif SERIAL\nconfig SERIAL_BCM283X_MU\n\tbool \"support bcm283x mu serial\"\n\tdefault n\n\thelp\n\t  serial driver for rpi-3b\n\nconfig SERIAL_MVEBU_A3700\n\tbool \"support marvell a3700 serial driver\"\n\tdefault n\n\thelp\n\t  serial driver for a3700 soc\n\nconfig SERIAL_PL011\n\tbool \"pl011 serial driver\"\n\tdefault n\n\thelp\n\t  serial driver for pl011\n\nconfig SERIAL_AMLOGIC\n\tbool \"meson for amlogic soc\"\n\tdefault n\n\thelp\n\t  serial driver for amlogic soc\n\nendif\n\nendmenu\n"
  },
  {
    "path": "kernel/drivers/serial/Makefile",
    "content": "obj-$(CONFIG_SERIAL_BCM283X_MU)\t\t+= serial_bcm283x_mu.o\nobj-$(CONFIG_SERIAL_MVEBU_A3700)\t+= serial_mvebu_a3700.o\nobj-$(CONFIG_SERIAL_PL011)\t\t+= serial_pl011.o\nobj-$(CONFIG_SERIAL_AMLOGIC)\t\t+= serial_meson.o\n"
  },
  {
    "path": "kernel/drivers/serial/pl011.h",
    "content": "#ifndef _MINOS_ARM_FVP_UART_H_\n#define _MINOS_ARM_FVP_UART_H_\n\n#define UARTDR\t\t0x0\n#define UARTECR\t\t0x4\n#define UARTFR\t\t0x18\n#define UARTILPR\t0x20\n#define UARTIBRD\t0x24\n#define UARTFBRD\t0x28\n#define UARTLCR_H\t0x2c\n#define UARTCR\t\t0x30\n#define UARTIFLS\t0x34\n#define UARTIMSC\t0x38\n#define UARTRIS\t\t0x3c\n#define UARTMIS\t\t0x40\n#define UARTICR\t\t0x44\n#define UARTDMACR\t0x48\n\n#define INT_CTS                 (1 << 1)\n#define INT_RX                  (1 << 4)\n#define INT_TX                  (1 << 5)\n#define INT_RX_TIMEOUT          (1 << 6)\n#define INT_FRAMING_ERR         (1 << 7)\n#define INT_PARITY_ERR          (1 << 8)\n#define INT_BREAK_ERR           (1 << 9)\n#define INT_OVER_ERR            (1 << 10)\n\n/*\n * defines for control/status registers\n */\n#define PL011_LCR_WORD_LENGTH_8   (0x60)\n#define PL011_LCR_WORD_LENGTH_7   (0x40)\n#define PL011_LCR_WORD_LENGTH_6   (0x20)\n#define PL011_LCR_WORD_LENGTH_5   (0x00)\n\n#define PL011_LCR_FIFO_ENABLE     (0x10)\n#define PL011_LCR_FIFO_DISABLE    (0x00)\n\n#define PL011_LCR_TWO_STOP_BITS   (0x08)\n#define PL011_LCR_ONE_STOP_BIT    (0x00)\n\n#define PL011_LCR_PARITY_ENABLE   (0x02)\n#define PL011_LCR_PARITY_DISABLE  (0x00)\n\n#define PL011_LCR_BREAK_ENABLE    (0x01)\n#define PL011_LCR_BREAK_DISABLE   (0x00)\n\n#define PL011_IBRD_DIV_38400      (0x27)\n#define PL011_FBRD_DIV_38400      (0x09)\n\n#define PL011_ICR_CLR_ALL_IRQS    (0x07FF)\n\n#define PL011_FR_BUSY_FLAG        (0x08)\n#define PL011_FR_RXFE_FLAG        (0x10)\n#define PL011_FR_TXFF_FLAG        (0x20)\n#define PL011_FR_RXFF_FLAG        (0x40)\n#define PL011_FR_TXFE_FLAG        (0x80)\n\n#define PL011_CR_UART_ENABLE      (0x01)\n\n#define PL011_CR_TX_ENABLE        (0x0100)\n#define PL011_CR_RX_ENABLE        (0x0200)\n\n#endif\n"
  },
  {
    "path": "kernel/drivers/serial/serial_bcm283x_mu.c",
    "content": "/*\n * copyright (c) 2018 min le (lemin9538@gmail.com)\n *\n * this program is free software; you can redistribute it and/or modify\n * it under the terms of the gnu general public license version 2 as\n * published by the free software foundation.\n *\n * this program is distributed in the hope that it will be useful,\n * but without any warranty; without even the implied warranty of\n * merchantability or fitness for a particular purpose.  see the\n * gnu general public license for more details.\n *\n * you should have received a copy of the gnu general public license\n * along with this program.  if not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/errno.h>\n#include <asm/io.h>\n#include <minos/mm.h>\n#include <minos/init.h>\n#include <config/config.h>\n#include <minos/console.h>\n\n#define AUX_MU_IO\t0x00\n#define AUX_MU_IER\t0x04\n#define AUX_MU_IIR\t0x08\n#define AUX_MU_LCR\t0x0c\n#define AUX_MU_MCR\t0x10\n#define AUX_MU_LSR\t0x14\n#define AUX_MU_MSR\t0x18\n#define AUX_MU_SCRATCH\t0x1c\n#define AUX_MU_CNTL\t0x20\n#define AUX_MU_STAT\t0x24\n#define AUX_MU_BAUD\t0x28\n\n#define BCM283X_LCR_DATA_SIZE_8\t\t3\n#define BCM283X_MU_LSR_TX_EMPTY\t\t(1 << 5)\n#define BCM283X_MU_LSR_RX_READY\t\t(1 << 0)\n\nstatic void *serial_base = (void *)ptov(CONFIG_UART_BASE);\n\nstatic inline void __bcm283x_mu_putc(char c)\n{\n\twhile (!(ioread32(serial_base + AUX_MU_LSR) &\n\t\t\t\tBCM283X_MU_LSR_TX_EMPTY));\n\n\tiowrite32(c, serial_base + AUX_MU_IO);\n}\n\nvoid bcm283x_mu_putc(char c)\n{\n\tif (c == '\\n')\n\t\t__bcm283x_mu_putc('\\r');\n\n\t__bcm283x_mu_putc(c);\n}\n\nchar bcm283x_mu_getc(void)\n{\n\tif (!(ioread32(serial_base + AUX_MU_LSR) &\n\t\t\t\tBCM283X_MU_LSR_RX_READY))\n\t\treturn 0;\n\n\treturn ioread32(serial_base + AUX_MU_IO);\n}\n\nint bcm283x_mu_init(char *arg)\n{\n#if 0\n\tuint32_t divider;\n\n\tif (!base)\n\t\treturn -EINVAL;\n\n\tserial_base = base;\n\tdivider = clk / (baud * 8);\n\n\tiowrite32(BCM283X_LCR_DATA_SIZE_8, serial_base + AUX_MU_LCR);\n\tiowrite32(divider - 1, serial_base + AUX_MU_BAUD);\n#endif\n\n\treturn 0;\n}\nDEFINE_CONSOLE(bcm283x, \"bcm283x_mu\", bcm283x_mu_init,\n\t\tbcm283x_mu_putc, bcm283x_mu_getc);\n"
  },
  {
    "path": "kernel/drivers/serial/serial_meson.c",
    "content": "/*\n * copyright (c) 2018 min le (lemin9538@gmail.com)\n *\n * this program is free software; you can redistribute it and/or modify\n * it under the terms of the gnu general public license version 2 as\n * published by the free software foundation.\n *\n * this program is distributed in the hope that it will be useful,\n * but without any warranty; without even the implied warranty of\n * merchantability or fitness for a particular purpose.  see the\n * gnu general public license for more details.\n *\n * you should have received a copy of the gnu general public license\n * along with this program.  if not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <asm/io.h>\n#include <minos/console.h>\n\nstruct meson_uart {\n\tu32 wfifo;\n\tu32 rfifo;\n\tu32 control;\n\tu32 status;\n\tu32 misc;\n};\n\n/* AML_UART_STATUS bits */\n#define AML_UART_PARITY_ERR\t\tBIT(16)\n#define AML_UART_FRAME_ERR\t\tBIT(17)\n#define AML_UART_TX_FIFO_WERR\t\tBIT(18)\n#define AML_UART_RX_EMPTY\t\tBIT(20)\n#define AML_UART_TX_FULL\t\tBIT(21)\n#define AML_UART_TX_EMPTY\t\tBIT(22)\n#define AML_UART_XMIT_BUSY\t\tBIT(25)\n#define AML_UART_ERR\t\t\t(AML_UART_PARITY_ERR | \\\n\t\t\t\t\t AML_UART_FRAME_ERR  | \\\n\t\t\t\t\t AML_UART_TX_FIFO_WERR)\n/* AML_UART_CONTROL bits */\n#define AML_UART_TX_EN\t\t\tBIT(12)\n#define AML_UART_RX_EN\t\t\tBIT(13)\n#define AML_UART_TX_RST\t\t\tBIT(22)\n#define AML_UART_RX_RST\t\t\tBIT(23)\n#define AML_UART_CLR_ERR\t\tBIT(24)\n\nstatic volatile struct meson_uart *uart = (struct meson_uart *)ptov(0xff803000);\n\nstatic int meson_serial_init(char *arg)\n{\n#if 0\n\tu32 val;\n\n\tval = readl(&uart->control);\n\tval |= (AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLR_ERR);\n\twritel(val, &uart->control);\n\tval &= ~(AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLR_ERR);\n\twritel(val, &uart->control);\n\tval |= (AML_UART_RX_EN | AML_UART_TX_EN);\n\twritel(val, &uart->control);\n#endif\n\n\treturn 0;\n}\n\nstatic char meson_serial_getc(void)\n{\n\tif ((readl(&uart->status) & 0x7f) == 0)\n\t\treturn 0;\n\n\treturn readl(&uart->rfifo) & 0xff;\n}\n\nstatic inline void __meson_serial_putc(char c)\n{\n\twhile (readl(&uart->status) & AML_UART_TX_FULL);\n\n\twritel(c, &uart->wfifo);\n}\n\nstatic void meson_serial_putc(char c)\n{\n\tif (c == '\\n')\n\t\t__meson_serial_putc('\\r');\n\n\t__meson_serial_putc(c);\n}\nDEFINE_CONSOLE(aml_meson, \"aml_meson\", meson_serial_init,\n\t\tmeson_serial_putc, meson_serial_getc);\n"
  },
  {
    "path": "kernel/drivers/serial/serial_mvebu_a3700.c",
    "content": "/*\n * Copyright (C) 2016 Stefan Roese <sr@denx.de>\n *\n * SPDX-License-Identifier:\tGPL-2.0+\n */\n\n#include <minos/minos.h>\n#include <asm/io.h>\n#include <config/config.h>\n#include <minos/console.h>\n\nstatic void *base = (void *)ptov(CONFIG_UART_BASE);\n\n/*\n * Register offset\n */\n/* REG_UART_A3700 */\n#define UART_RX_REG\t\t\t0x00\n#define UART_TX_REG\t\t\t0x04\n#define UART_CTRL_REG\t\t\t0x08\n#define UART_STATUS_REG\t\t\t0x0c\n#define UART_BAUD_REG\t\t\t0x10\n#define UART_POSSR_REG\t\t\t0x14\n\n#define UART_STATUS_RX_RDY\t\t0x10\n#define UART_STATUS_TXFIFO_FULL\t\t0x800\n\n#define UART_CTRL_RXFIFO_RESET\t\t0x4000\n#define UART_CTRL_TXFIFO_RESET\t\t0x8000\n\n#define CONFIG_UART_BASE_CLOCK\t\t25804800\n\n/* REG_UART_A3700_EXT */\n#define UART_EXT_RX_REG\t\t\t0x18\n#define UART_EXT_TX_REG\t\t\t0x1c\n#define UART_EXT_CTRL_REG\t\t0x04\n#define UART_EXT_STATUS_RX_RDY\t\t0x4000\n\nstatic inline void __serial_putc(char ch)\n{\n\twhile (ioread32(base + UART_STATUS_REG) & UART_STATUS_TXFIFO_FULL);\n\n\tiowrite32(ch, base + UART_TX_REG);\n}\n\nstatic void serial_mvebu_putc(char ch)\n{\n\tif (ch == '\\n')\n\t\t__serial_putc('\\r');\n\n\t__serial_putc(ch);\n}\n\nstatic char serial_mvebu_getc(void)\n{\n\twhile (!(ioread32(base + UART_STATUS_REG) & UART_STATUS_RX_RDY));\n\n\treturn ioread32(base + UART_RX_REG) & 0xff;\n}\n\nstatic int mvebu_serial_setbrg(int baudrate)\n{\n\t/*\n\t * Calculate divider\n\t * baudrate = clock / 16 / divider\n\t */\n\tiowrite32(CONFIG_UART_BASE_CLOCK / baudrate / 16, base + UART_BAUD_REG);\n\n\t/*\n\t * Set Programmable Oversampling Stack to 0,\n\t * UART defaults to 16x scheme\n\t */\n\tiowrite32(0, base + UART_POSSR_REG);\n\n\treturn 0;\n}\n\nstatic int mvebu_serial_probe(char *addr)\n{\n#if 0\n\t/* reset FIFOs */\n\tiowrite32(UART_CTRL_RXFIFO_RESET | UART_CTRL_TXFIFO_RESET,\n\t\t\tbase + UART_CTRL_REG);\n\n\t/* No Parity, 1 Stop */\n\tiowrite32(0, base + UART_CTRL_REG);\n\n\t/* set brg to 115200 */\n\tmvebu_serial_setbrg(115200);\n#endif\n\treturn 0;\n}\nDEFINE_CONSOLE(mvebu, \"mvebu\", mvebu_serial_probe,\n\t\tserial_mvebu_putc, serial_mvebu_getc);\n"
  },
  {
    "path": "kernel/drivers/serial/serial_pl011.c",
    "content": "/*\n * copyright (c) 2018 min le (lemin9538@gmail.com)\n *\n * this program is free software; you can redistribute it and/or modify\n * it under the terms of the gnu general public license version 2 as\n * published by the free software foundation.\n *\n * this program is distributed in the hope that it will be useful,\n * but without any warranty; without even the implied warranty of\n * merchantability or fitness for a particular purpose.  see the\n * gnu general public license for more details.\n *\n * you should have received a copy of the gnu general public license\n * along with this program.  if not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/errno.h>\n#include <asm/io.h>\n#include <minos/init.h>\n#include <config/config.h>\n#include \"pl011.h\"\n#include <minos/console.h>\n#include <minos/irq.h>\n\nstatic void *base;\n\nstatic int __pl011_init(void *addr, int clock, int baudrate)\n{\n\tunsigned int temp;\n\tunsigned int divider;\n\tunsigned int remainder;\n\tunsigned int fraction;\n\n\tbase = (void *)ptov(addr);\n\n\ttemp = 16 * baudrate;\n\tdivider = clock / temp;\n\tremainder = clock % temp;\n\ttemp = (8 * remainder) / baudrate;\n\tfraction = (temp >> 1) + (temp & 1);\n\n\tiowrite32(0x0, base + UARTCR);\n\tiowrite32(0x0, base + UARTECR);\n\tiowrite32(0x0 | PL011_LCR_WORD_LENGTH_8 | \\\n\t\t  PL011_LCR_ONE_STOP_BIT | \\\n\t\t  PL011_LCR_PARITY_DISABLE | \\\n\t\t  PL011_LCR_BREAK_DISABLE, base + UARTLCR_H);\n\n\tiowrite32(divider, base + UARTIBRD);\n\tiowrite32(fraction, base + UARTFBRD);\n\n\tiowrite32(INT_RX, base + UARTIMSC);\t// enable rx interrupt.\n\n\tiowrite32(PL011_ICR_CLR_ALL_IRQS, base + UARTICR);\n\tiowrite32(0x0 | PL011_CR_UART_ENABLE | \\\n\t\t  PL011_CR_TX_ENABLE | \\\n\t\t  PL011_CR_RX_ENABLE, base + UARTCR);\n\n\treturn 0;\n}\n\nstatic int pl011_irq_handler(uint32_t irq, void *data)\n{\n\tunsigned int int_status;\n\tchar buf[16];\n\tint cnt = 0;\n\n\t/*\n\t * only support RX interrupt.\n\t */\n\tint_status = ioread32(base + UARTMIS);\n\tif (!(int_status & INT_RX))\n\t\treturn 0;\n\n\tiowrite32(INT_RX, base + UARTICR);\n\twhile (!(ioread32(base + UARTFR) & PL011_FR_RXFE_FLAG)) {\n\t\tbuf[cnt++] = ioread32(base + UARTDR) & 0xff;\n\t\tif (cnt == 16) {\n\t\t\tconsole_recv(buf, cnt);\n\t\t\tcnt = 0;\n\t\t}\n\t}\n\n\tif (cnt)\n\t\tconsole_recv(buf, cnt);\n\n\tiowrite32(0, base + UARTECR);\n\n\treturn 0;\n}\n\nstatic int pl011_irq_init(void)\n{\n\treturn request_irq(CONFIG_UART_IRQ, pl011_irq_handler, 0, \"pl011\", NULL);\n}\ndevice_initcall(pl011_irq_init);\n\nstatic int pl011_init(char *arg)\n{\n\treturn __pl011_init((void *)ptov(CONFIG_UART_BASE), 24000000, 115200);\n}\n\nstatic void serial_pl011_putc(char c)\n{\n\twhile (ioread32(base + UARTFR) & PL011_FR_BUSY_FLAG);\n\n\tif (c == '\\n')\n\t\tiowrite32('\\r', base + UARTDR);\n\n\tiowrite32(c, base + UARTDR);\n}\n\nstatic char serial_pl011_getc(void)\n{\n\twhile (ioread32(base + UARTFR) & PL011_FR_BUSY_FLAG);\n\n\treturn ioread32(base + UARTDR);\n}\n\nDEFINE_CONSOLE(pl011, \"pl011\", pl011_init,\n\t\tserial_pl011_putc, serial_pl011_getc);\n"
  },
  {
    "path": "kernel/drivers/serial/serial_scif.c",
    "content": "// SPDX-License-Identifier: GPL-2.0\n\n#include <asm/io.h>\n#include <minos/console.h>\n\n/* Register offsets */\n#define SCIF_SCFTDR    (0x0C)      /* Transmit FIFO data register */\n#define SCIF_SCFSR     (0x10)      /* Serial status register */\n#define SCIF_SCFRDR    (0x14)      /* Receive FIFO data register */\n\n/* Serial Status Register (SCFSR) */\n#define SCFSR_TEND     (1 << 6)    /* Transmission End */\n#define SCFSR_RDF      (1 << 1)    /* Receive FIFO Data Full */\n#define SCFSR_DR       (1 << 0)    /* Receive Data Ready */\n\nstatic void *serial_base = (void *)CONFIG_UART_BASE;\n\nstatic inline void __scif_serial_putc(char c)\n{\n    /* Check for empty space in TX FIFO */\n    while (!(readw(serial_base + SCIF_SCFSR) & SCFSR_TEND))\n        ;\n\n    writeb(c, serial_base + SCIF_SCFTDR);\n    /* Clear required TX flags */\n    writew(readw(serial_base + SCIF_SCFSR) & ~SCFSR_TEND,\n           serial_base + SCIF_SCFSR);\n}\n\nstatic void scif_serial_putc(char c)\n{\n    if (c == '\\n')\n        __scif_serial_putc('\\r');\n\n    __scif_serial_putc(c);\n}\n\nstatic char scif_serial_getc(void)\n{\n    /* Check for available data bytes in RX FIFO */\n    if (!(readw(serial_base + SCIF_SCFSR) & (SCFSR_DR | SCFSR_RDF)))\n        return 0;\n\n    char c = readb(serial_base + SCIF_SCFRDR);\n    /* dummy read */\n    readw(serial_base + SCIF_SCFSR);\n\n    /* Clear required RX flags */\n    writew(~(SCFSR_DR | SCFSR_RDF), serial_base + SCIF_SCFSR);\n\n    return c;\n}\n\nDEFINE_CONSOLE(scif, \"renesas,scif\", NULL, scif_serial_putc, scif_serial_getc);\n"
  },
  {
    "path": "kernel/drivers/tty.c",
    "content": "/*\n * Copyright (C) 2020 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/tty.h>\n#include <minos/mm.h>\n\nstatic LIST_HEAD(tty_list);\nstatic DEFINE_SPIN_LOCK(tty_lock);\n\nstruct tty *alloc_tty(char *name, uint32_t id, int flags)\n{\n\tstruct tty *tty;\n\n\tlist_for_each_entry(tty, &tty_list, list) {\n\t\tif ((tty->id == id) || (strcmp(name, tty->name)==0)) {\n\t\t\tpr_err(\"tty is areadly register 0x%x\\n\", id);\n\t\t\treturn NULL;\n\t\t}\n\t}\n\n\ttty = zalloc(sizeof(struct tty));\n\tif (!tty)\n\t\treturn NULL;\n\n\ttty->id = id;\n\ttty->flags = flags;\n\tstrncpy(tty->name, name, TTY_NAME_SIZE - 1);\n\n\treturn tty;\n}\n\nint register_tty(struct tty *tty)\n{\n\tunsigned long iflags;\n\n\tif (tty->ops == NULL)\n\t\treturn -EINVAL;\n\n\tspin_lock_irqsave(&tty_lock, iflags);\n\tlist_add_tail(&tty_list, &tty->list);\n\tspin_unlock_irqrestore(&tty_lock, iflags);\n\n\treturn 0;\n}\n\nint release_tty(struct tty *tty)\n{\n\tunsigned long flags;\n\n\tif (!tty || (tty->list.next == NULL))\n\t\treturn -EINVAL;\n\n\tspin_lock_irqsave(&tty_lock, flags);\n\tlist_del(&tty->list);\n\tspin_unlock_irqrestore(&tty_lock, flags);\n\n\tfree(tty);\n\n\treturn 0;\n}\n\nstruct tty *open_tty(char *name)\n{\n\tstruct tty *tty, *__tty = NULL;\n\n\tlist_for_each_entry(tty, &tty_list, list) {\n\t\tif (strcmp(name, tty->name) == 0) {\n\t\t\t__tty = tty;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!__tty || __tty->open)\n\t\treturn NULL;\n\n\tif (tty->ops->open)\n\t\ttty->ops->open(tty);\n\ttty->open = 1;\n\n\treturn __tty;\n}\n\nvoid close_tty(struct tty *tty)\n{\n\tif (!tty || !tty->open)\n\t\treturn;\n\n\tif (tty->ops->close)\n\t\ttty->ops->close(tty);\n\ttty->open = 0;\n}\n"
  },
  {
    "path": "kernel/dtbs/Makefile",
    "content": "obj-y += foundation-v8-gicv2.dtb\nobj-y += foundation-v8-gicv3.dtb\nobj-y += bcm2837-rpi-3-b-plus.dtb\nobj-y += armada-3720-community-v5.dtb\nobj-y += bcm2838-rpi-4-b.dtb\nobj-y += bcm2838-rpi-4-b-32bit.dtb\nobj-y += kvim3.dtb\nobj-y += foundation-v8-gicv3-zephyr.dtb\nobj-y += qemu-arm64.dtb\nobj-y += r8a7795.dtb\n"
  },
  {
    "path": "kernel/dtbs/armada-3720-community-v5.dts",
    "content": "/dts-v1/;\n\n/ {\n\tmodel = \"Marvell Armada 3720 Community Board\";\n\tcompatible = \"marvell,armada-3720-community\", \"marvell,armada3720\", \"marvell,armada3710\";\n\tinterrupt-parent = <0x1>;\n\t#address-cells = <0x2>;\n\t#size-cells = <0x2>;\n\n\tvms {\n\t\tvm0 {\n\t\t\tdevice_type = \"virtual_machine\";\n\t\t\tvmid = <0>;\n\t\t\tvm_name = \"espressobin_linux\";\n\t\t\ttype = \"linux\";\n\t\t\tvcpus = <1>;\n\t\t\tnative_wfi;\n\t\t\tentry = <0x0 0x280000>;\n\t\t\tvcpu_affinity = <0>;\n\t\t\tsetup_data = <0x0 0xfe00000>;\n\t\t\tmemory = <0x0 0x0 0x0 0x10000000>;\n\t\t\tcmdline = \"console=ttyMV0,115200 earlycon=ar3700_uart,0xd0012000 root=PARTUUID=89708921-01 rw rootwait net.ifnames=0 biosdevname=0\";\n\t\t};\n\t};\n\n\tcpus {\n\t\t#address-cells = <0x1>;\n\t\t#size-cells = <0x0>;\n\n\t\tcpu@0 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,cortex-a53\", \"arm,armv8\";\n\t\t\treg = <0x0>;\n\t\t\tclocks = <0x2 0x0>;\n\t\t\toperating-points-v2 = <0x3>;\n\t\t\tenable-method = \"psci\";\n\t\t};\n\n\t\tcpu@1 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,cortex-a53\", \"arm,armv8\";\n\t\t\treg = <0x1>;\n\t\t\tcks = <0x2 0x0>;\n\t\t\toperating-points-v2 = <0x3>;\n\t\t\tenable-method = \"psci\";\n\t\t};\n\t};\n\n\tpsci {\n\t\tcompatible = \"arm,psci-0.2\";\n\t\tmethod = \"smc\";\n\t};\n\n\ttimer {\n\t\tcompatible = \"arm,armv8-timer\";\n\t\tinterrupts = <0x1 0xd 0x304 0x1 0xe 0x304 0x1 0xb 0x304 0x1 0xa 0x304>;\n\t};\n\n\tsoc {\n\t\tcompatible = \"simple-bus\";\n\t\t#address-cells = <0x2>;\n\t\t#size-cells = <0x2>;\n\t\tranges;\n\n\t\tinternal-regs {\n\t\t\t#address-cells = <0x1>;\n\t\t\t#size-cells = <0x1>;\n\t\t\tcompatible = \"simple-bus\";\n\t\t\tranges = <0x0 0x0 0xd0000000 0x2000000>;\n\t\t\tdma-coherent;\n\n\t\t\tinterrupt-controller@1d00000 {\n\t\t\t\tcompatible = \"arm,gic-v3\";\n\t\t\t\t#interrupt-cells = <0x3>;\n\t\t\t\tinterrupt-controller;\n\t\t\t\tinterrupts = <0x1 0x9 0xf04>;\n\t\t\t\treg = <0x1d00000 0x10000 0x1d40000 0x40000>;\n\t\t\t\tlinux,phandle = <0x1>;\n\t\t\t\tphandle = <0x1>;\n\t\t\t};\n\t\t};\n\t};\n\n\tchosen {\n\t\tminos,stdout = \"mvebu\";\n\t};\n\n\tmemory {\n\t\tdevice_type = \"memory\";\n\t\treg = <0x0 0x0 0x0 0x40000000>;\n\t};\n};\n"
  },
  {
    "path": "kernel/dtbs/bcm2837-rpi-3-b-plus.dts",
    "content": "/dts-v1/;\n\n/ {\n\tcompatible = \"raspberrypi,3-model-b-plus\", \"brcm,bcm2837\";\n\tmodel = \"Raspberry Pi 3 Model B+\";\n\tinterrupt-parent = <0x1>;\n\t#address-cells = <0x1>;\n\t#size-cells = <0x1>;\n\n\tchosen {\n\t\tminos,stdout = \"bcm283x_mu\";\n\t};\n\n\tvms {\n\t\tvm0 {\n\t\t\tdevice_type = \"virtual_machine\";\n\t\t\tvmid = <0>;\n\t\t\tvm_name = \"rpi3_linux_host\";\n\t\t\ttype = \"linux\";\n\t\t\tvcpus = <2>;\n\t\t\tnative_wfi;\n\t\t\tentry = <0x0 0x00080000>;\n\t\t\tsetup_data = <0x0 0x03e00000>;\n\t\t\tvcpu_affinity = <0 1 2 3>;\n\t\t\tmemory = <0x0 0x00000000 0x0 0x28000000>;\n\t\t\tcmdline = \"8250.nr_uarts=1 dwc_otg.lpm_enable=0 net.ifnames=0 earlycon=uart8250,mmio32,0x3f215040 console=ttyS0,115200 cma=64M root=/dev/mmcblk0p2 rw rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait noinitrd\";\n\t\t};\n\t};\n\n\tsoc {\n\t\tcompatible = \"simple-bus\";\n\t\t#address-cells = <0x1>;\n\t\t#size-cells = <0x1>;\n\t\tranges = <0x7e000000 0x3f000000 0x1000000 0x40000000 0x40000000 0x1000>;\n\t\tdma-ranges = <0xc0000000 0x0 0x3f000000>;\n\n\t\tinterrupt-controller@7e00b200 {\n\t\t\tcompatible = \"brcm,bcm2836-armctrl-ic\";\n\t\t\treg = <0x7e00b200 0x200>;\n\t\t\tinterrupt-controller;\n\t\t\t#interrupt-cells = <0x2>;\n\t\t\tinterrupt-parent = <0x3>;\n\t\t\tinterrupts = <0x8 0x4>;\n\t\t\tphandle = <0x1>;\n\t\t};\n\n\t\tlocal_intc@40000000 {\n\t\t\tcompatible = \"brcm,bcm2836-l1-intc\";\n\t\t\treg = <0x40000000 0x100>;\n\t\t\tinterrupt-controller;\n\t\t\t#interrupt-cells = <0x2>;\n\t\t\tinterrupt-parent = <0x3>;\n\t\t\tphandle = <0x3>;\n\t\t};\n\n\t};\n\n\ttimer {\n\t\tcompatible = \"arm,armv7-timer\";\n\t\tinterrupt-parent = <0x3>;\n\t\tinterrupts = <0x0 0x4 0x1 0x4 0x3 0x4 0x2 0x4>;\n\t\talways-on;\n\t};\n\n\tcpus {\n\t\t#address-cells = <0x1>;\n\t\t#size-cells = <0x0>;\n\t\tenable-method = \"brcm,bcm2836-smp\";\n\n\t\tcpu@0 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,cortex-a53\";\n\t\t\treg = <0x0>;\n\t\t\tenable-method = \"spin-table\";\n\t\t\tcpu-release-addr = <0x0 0xd8>;\n\t\t};\n\n\t\tcpu@1 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,cortex-a53\";\n\t\t\treg = <0x1>;\n\t\t\tenable-method = \"spin-table\";\n\t\t\tcpu-release-addr = <0x0 0xe0>;\n\t\t};\n\n\t\tcpu@2 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,cortex-a53\";\n\t\t\treg = <0x2>;\n\t\t\tenable-method = \"spin-table\";\n\t\t\tcpu-release-addr = <0x0 0xe8>;\n\t\t};\n\n\t\tcpu@3 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,cortex-a53\";\n\t\t\treg = <0x3>;\n\t\t\tenable-method = \"spin-table\";\n\t\t\tcpu-release-addr = <0x0 0xf0>;\n\t\t};\n\t};\n\n\tmemory {\n\t\tdevice_type = \"memory\";\n\t\treg = <0x0 0x40000000>;\n\t};\n};\n"
  },
  {
    "path": "kernel/dtbs/bcm2838-rpi-4-b-32bit.dts",
    "content": "/dts-v1/;\n\n/ {\n\tcompatible = \"raspberrypi,4-model-b\", \"brcm,bcm2838\", \"brcm,bcm2837\";\n\tmodel = \"Raspberry Pi 4 Model B\";\n\tinterrupt-parent = <0x1>;\n\t#address-cells = <0x2>;\n\t#size-cells = <0x1>;\n\n\taliases {\n\t\tserial0 = \"/soc/serial@7e201000\";\n\t\tserial1 = \"/soc/serial@7e215040\";\n\t};\n\n\tchosen {\n\t\tminos,stdout = \"bcm283x_mu\";\n\t\textra-memory = <0x40000000 0xbc000000>;\n\t\tbootargs = \"bootwait=3 tty=vm0 cpu_sched_class_mask=0x0\";\n\t};\n\n\tvms {\n\t\tvm0 {\n\t\t\tdevice_type = \"virtual_machine\";\n\t\t\tvmid = <0>;\n\t\t\tvm_name = \"rpi4_linux_host\";\n\t\t\ttype = \"linux\";\n\t\t\tvm_32bit;\n\t\t\tnative_wfi;\n\t\t\tvcpus = <2>;\n\t\t\tentry = <0x0 0x00008000>;\n\t\t\tsetup_data = <0x0 0x03e00000>;\n\t\t\tvcpu_affinity = <0 1 0 0>;\n\t\t\tmemory = <0x0 0x00000000 0x0 0x30000000 0x0 0x40000000 0x0 0x7c000000>;\n\t\t\tcmdline = \"coherent_pool=1M 8250.nr_uarts=1 earlycon=dbcon,io,0x0 loglevel=9 cma=64M cma=256M video=HDMI-A-1:720x576M@50,margin_left=0,margin_right=0,margin_top=0,margin_bottom=0 smsc95xx.macaddr=DC:A6:32:1C:65:A1 vc_mem.mem_base=0x3ec00000 vc_mem.mem_size=0x40000000 dwc_otg.fiq_fix_enable=0 console=tty1 console=hvc0 root=/dev/mmcblk0p2 rw rootfstype=ext4 rootwait rootflags=noload net.ifnames=0 loglevel=9\";\n\t\t\tvm0_bdi {\n\t\t\t\tvm_console_vm0 {\n\t\t\t\t\tvirtual_device;\n\t\t\t\t\tvc-dynamic-res;\n\t\t\t\t\tcompatible = \"minos,vm_console\";\n\t\t\t\t};\n\t\t\t};\n\t\t};\n\n\t\tvm1 {\n\t\t\tdevice_type = \"virtual_machine\";\n\t\t\tvmid = <1>;\n\t\t\tvm_name = \"rpi4_vm1\";\n\t\t\ttype = \"linux\";\n\t\t\tvm_32bit;\n\t\t\tnative_wfi;\n\t\t\tvcpus = <1>;\n\t\t\tentry = <0x0 0x30008000>;\n\t\t\tsetup_data = <0x0 0x33e00000>;\n\t\t\tvcpu_affinity = <2 0 0 0>;\n\t\t\tmemory = <0x0 0x30000000 0x0 0x7200000>;\n\n\t\t\tvm1_bdi {\n\t\t\t\tvm_console_vm1 {\n\t\t\t\t\tvirtual_device;\n\t\t\t\t\tvc-dynamic-res;\n\t\t\t\t\tcompatible = \"minos,vm_console\";\n\t\t\t\t};\n\t\t\t};\n\t\t};\n\n\t\tvm2 {\n\t\t\tdevice_type = \"virtual_machine\";\n\t\t\tvmid = <2>;\n\t\t\tvm_name = \"fvp_zephyr_vm2\";\n\t\t\ttype = \"zephyr\";\n\t\t\tvcpus = <1>;\n\t\t\tentry = <0x0 0x372003b8>;\n\t\t\tsetup_data = <0x0 0x0>;\n\t\t\tvcpu_affinity = <3>;\n\t\t\tnative_wfi;\n\t\t\tmemory = <0x0 0x37200000 0x0 0x00200000>;\n\n\t\t\tvm2_bdi {\n\t\t\t\t#address-cells = <0x1>;\n\t\t\t\t#size-cells = <0x1>;\n\n\t\t\t\tvtimer_irq = <27>;\n\n\t\t\t\tvirq_chip_vm2 {\n\t\t\t\t\tcompatible = \"arm,gicv2\";\n\t\t\t\t\t#address-cells = <0x1>;\n\t\t\t\t\t#size-cells = <0x1>;\n\t\t\t\t\treg = <0x2f000000 0x10000>,\n\t\t\t\t\t\t<0x2c000000 0x2000>,\n\t\t\t\t\t\t<0x2c010000 0x2000>,\n\t\t\t\t\t\t<0x2c02f000 0x2000>;\n\t\t\t\t};\n\n\t\t\t\tvmbox_controller@20000000 {\n\t\t\t\t\tcompatible = \"minos,vmbox-controller\";\n\t\t\t\t\treg = <0x20000000 0x1000>;\n\t\t\t\t\tinterrupts = <0 10 4>;\n\t\t\t\t};\n\n\t\t\t\tvm_console_vm2 {\n\t\t\t\t\tvirtual_device;\n\t\t\t\t\tcompatible = \"minos,vm_console\";\n\t\t\t\t\treg = <0x20001000 0x2000>;\n\t\t\t\t\tinterrupts = <0 0 4>;\n\t\t\t\t};\n\t\t\t};\n\t\t};\n\n\t\tvmboxs {\n\t\t\tvmbox_hvc@0 {\n\t\t\t\tcompatible = \"minos,vmbox\";\n\t\t\t\tvmbox-type = \"hvc\";\n\t\t\t\tvmbox-owner = <0x1 0x0>;\n\t\t\t\tvmbox-shmem-size = <8192>;\n\t\t\t\tvmbox-id = <0x3420 0xffff>;\n\t\t\t\tplatform-device;\n\t\t\t};\n\n\t\t\tvmbox_veth@1 {\n\t\t\t\tcompatible = \"minos,veth\";\n\t\t\t\tvmbox-type = \"veth\";\n\t\t\t\tvmbox-owner = <0x0 0x1>;\n\t\t\t\tvmbox-id = <0x3430 0xffff>;\n\t\t\t\tvmbox-vqs = <2>;\n\t\t\t\tvmbox-vrings = <16>;\n\t\t\t\tvmbox-vring-size = <2048>;\n\t\t\t};\n\n\t\t\tvmbox_hvc@2 {\n\t\t\t\tcompatible = \"minos,vmbox\";\n\t\t\t\tvmbox-type = \"hvc\";\n\t\t\t\tvmbox-owner = <0x2 0x0>;\n\t\t\t\tvmbox-shmem-size = <8192>;\n\t\t\t\tvmbox-id = <0x3420 0xffff>;\n\t\t\t};\n\t\t};\n\t};\n\n\tsoc {\n\t\tcompatible = \"simple-bus\";\n\t\t#address-cells = <0x1>;\n\t\t#size-cells = <0x1>;\n\t\tranges = <0x7e000000 0x0 0xfe000000 0x1800000 0x7c000000 0x0 0xfc000000 0x2000000 0x40000000 0x0 0xff800000 0x800000>;\n\t\tdma-ranges = <0xc0000000 0x0 0x0 0x3c000000>;\n\n\t\tgic400@40041000 {\n\t\t\tinterrupt-controller;\n\t\t\t#interrupt-cells = <0x3>;\n\t\t\tcompatible = \"arm,gic-400\";\n\t\t\treg = <0x40041000 0x1000 0x40042000 0x2000 0x40044000 0x2000 0x40046000 0x2000>;\n\t\t\tphandle = <0x1>;\n\t\t};\n\t};\n\n\ttimer {\n\t\tcompatible = \"arm,armv7-timer\";\n\t\tinterrupts = <0x1 0xd 0xf08 0x1 0xe 0xf08 0x1 0xb 0xf08 0x1 0xa 0xf08>;\n\t\tarm,cpu-registers-not-fw-configured;\n\t\talways-on;\n\t};\n\n\tcpus {\n\t\t#address-cells = <0x1>;\n\t\t#size-cells = <0x0>;\n\t\tenable-method = \"brcm,bcm2836-smp\";\n\n\t\tcpu@0 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,cortex-a72\";\n\t\t\treg = <0x0>;\n\t\t\tenable-method = \"spin-table\";\n\t\t\tcpu-release-addr = <0x0 0xd8>;\n\t\t};\n\n\t\tcpu@1 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,cortex-a72\";\n\t\t\treg = <0x1>;\n\t\t\tenable-method = \"spin-table\";\n\t\t\tcpu-release-addr = <0x0 0xe0>;\n\t\t};\n\n\t\tcpu@2 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,cortex-a72\";\n\t\t\treg = <0x2>;\n\t\t\tenable-method = \"spin-table\";\n\t\t\tcpu-release-addr = <0x0 0xe8>;\n\t\t};\n\n\t\tcpu@3 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,cortex-a72\";\n\t\t\treg = <0x3>;\n\t\t\tenable-method = \"spin-table\";\n\t\t\tcpu-release-addr = <0x0 0xf0>;\n\t\t};\n\t};\n\n\tmemory {\n\t\tdevice_type = \"memory\";\n\t};\n};\n"
  },
  {
    "path": "kernel/dtbs/bcm2838-rpi-4-b.dts",
    "content": "/dts-v1/;\n\n/ {\n\tcompatible = \"raspberrypi,4-model-b\", \"brcm,bcm2838\", \"brcm,bcm2837\";\n\tmodel = \"Raspberry Pi 4 Model B\";\n\tinterrupt-parent = <0x1>;\n\t#address-cells = <0x2>;\n\t#size-cells = <0x1>;\n\n\taliases {\n\t\tserial0 = \"/soc/serial@7e201000\";\n\t\tserial1 = \"/soc/serial@7e215040\";\n\t};\n\n\tchosen {\n\t\tminos,stdout = \"bcm283x_mu\";\n\t};\n\n\tvms {\n\t\tvm0 {\n\t\t\tdevice_type = \"virtual_machine\";\n\t\t\tvmid = <0>;\n\t\t\tvm_name = \"rpi4_linux_host\";\n\t\t\ttype = \"linux\";\n\t\t\tvcpus = <2>;\n\t\t\tentry = <0x0 0x00080000>;\n\t\t\tsetup_data = <0x0 0x03e00000>;\n\t\t\tvcpu_affinity = <0 1 2 3>;\n\t\t\tmemory = <0x0 0x00000000 0x0 0x37400000 0x0 0x40000000 0x0 0x7c000000>;\n\t\t\tcmdline = \"coherent_pool=1M 8250.nr_uarts=1 earlycon=uart8250,mmio32,0xfe215040 loglevel=9 cma=64M cma=256M video=HDMI-A-1:720x576M@50,margin_left=0,margin_right=0,margin_top=0,margin_bottom=0 smsc95xx.macaddr=DC:A6:32:1C:65:A1 vc_mem.mem_base=0x3ec00000 vc_mem.mem_size=0x40000000 dwc_otg.fiq_fix_enable=0 console=tty1 console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootfstype=ext4 rootwait rootflags=noload net.ifnames=0 loglevel=9\";\n\t\t};\n\t};\n\n\n\tthermal-zones {\n\n\t\tcpu-thermal {\n\t\t\tpolling-delay-passive = <0x0>;\n\t\t\tpolling-delay = <0x3e8>;\n\t\t\tthermal-sensors = <0x2>;\n\t\t\tcoefficients = <0xfffffe19 0x641b8>;\n\n\t\t\ttrips {\n\n\t\t\t\tcpu-crit {\n\t\t\t\t\ttemperature = <0x13880>;\n\t\t\t\t\thysteresis = <0x0>;\n\t\t\t\t\ttype = \"critical\";\n\t\t\t\t};\n\t\t\t};\n\n\t\t\tcooling-maps {\n\t\t\t};\n\t\t};\n\t};\n\n\tsoc {\n\t\tcompatible = \"simple-bus\";\n\t\t#address-cells = <0x1>;\n\t\t#size-cells = <0x1>;\n\t\tranges = <0x7e000000 0x0 0xfe000000 0x1800000 0x7c000000 0x0 0xfc000000 0x2000000 0x40000000 0x0 0xff800000 0x800000>;\n\t\tdma-ranges = <0xc0000000 0x0 0x0 0x3c000000>;\n\n\t\ttxp@7e004000 {\n\t\t\tcompatible = \"brcm,bcm2835-txp\";\n\t\t\treg = <0x7e004000 0x20>;\n\t\t\tinterrupts = <0x1 0xb>;\n\t\t};\n\n\t\tdma@7e007000 {\n\t\t\tcompatible = \"brcm,bcm2835-dma\";\n\t\t\treg = <0x7e007000 0xb00>;\n\t\t\tinterrupts = <0x0 0x50 0x4 0x0 0x51 0x4 0x0 0x52 0x4 0x0 0x53 0x4 0x0 0x54 0x4 0x0 0x55 0x4 0x0 0x56 0x4 0x0 0x57 0x4 0x0 0x57 0x4 0x0 0x58 0x4 0x0 0x58 0x4>;\n\t\t\tinterrupt-names = \"dma0\", \"dma1\", \"dma2\", \"dma3\", \"dma4\", \"dma5\", \"dma6\", \"dma7\", \"dma8\", \"dma9\", \"dma10\";\n\t\t\t#dma-cells = <0x1>;\n\t\t\tbrcm,dma-channel-mask = <0x7f5>;\n\t\t\tphandle = <0x9>;\n\t\t};\n\n\t\twatchdog@7e100000 {\n\t\t\tcompatible = \"brcm,bcm2835-pm\", \"brcm,bcm2835-pm-wdt\";\n\t\t\t#power-domain-cells = <0x1>;\n\t\t\t#reset-cells = <0x1>;\n\t\t\treg = <0x7e100000 0x114 0x7e00a000 0x24>;\n\t\t\tclocks = <0x3 0x15 0x3 0x1d 0x3 0x17 0x3 0x16>;\n\t\t\tclock-names = \"v3d\", \"peri_image\", \"h264\", \"isp\";\n\t\t\tsystem-power-controller;\n\t\t};\n\n\t\tcprman@7e101000 {\n\t\t\tcompatible = \"brcm,bcm2838-cprman\";\n\t\t\t#clock-cells = <0x1>;\n\t\t\treg = <0x7e101000 0x2000>;\n\t\t\tclocks = <0x4 0x5 0x0 0x5 0x1 0x5 0x2 0x6 0x0 0x6 0x1 0x6 0x2>;\n\t\t\tphandle = <0x3>;\n\t\t};\n\n\t\trng@7e104000 {\n\t\t\tcompatible = \"brcm,bcm2835-rng\";\n\t\t\treg = <0x7e104000 0x10>;\n\t\t\tinterrupts = <0x2 0x1d>;\n\t\t};\n\n\t\tmailbox@7e00b880 {\n\t\t\tcompatible = \"brcm,bcm2835-mbox\";\n\t\t\treg = <0x7e00b880 0x40>;\n\t\t\tinterrupts = <0x0 0x21 0x4>;\n\t\t\t#mbox-cells = <0x0>;\n\t\t};\n\n\t\tgpio@7e200000 {\n\t\t\tcompatible = \"brcm,bcm2838-gpio\", \"brcm,bcm2835-gpio\";\n\t\t\treg = <0x7e200000 0xb4>;\n\t\t\tinterrupts = <0x0 0x71 0x4 0x0 0x72 0x4 0x0 0x73 0x4 0x0 0x74 0x4>;\n\t\t\tgpio-controller;\n\t\t\t#gpio-cells = <0x2>;\n\t\t\tinterrupt-controller;\n\t\t\t#interrupt-cells = <0x2>;\n\t\t\tphandle = <0xf>;\n\n\t\t\tdpi_gpio0 {\n\t\t\t\tbrcm,pins = <0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b>;\n\t\t\t\tbrcm,function = <0x6>;\n\t\t\t};\n\n\t\t\temmc_gpio22 {\n\t\t\t\tbrcm,pins = <0x16 0x17 0x18 0x19 0x1a 0x1b>;\n\t\t\t\tbrcm,function = <0x7>;\n\t\t\t};\n\n\t\t\temmc_gpio34 {\n\t\t\t\tbrcm,pins = <0x22 0x23 0x24 0x25 0x26 0x27>;\n\t\t\t\tbrcm,function = <0x7>;\n\t\t\t\tbrcm,pull = <0x0 0x2 0x2 0x2 0x2 0x2>;\n\t\t\t};\n\n\t\t\temmc_gpio48 {\n\t\t\t\tbrcm,pins = <0x30 0x31 0x32 0x33 0x34 0x35>;\n\t\t\t\tbrcm,function = <0x7>;\n\t\t\t};\n\n\t\t\tgpclk0_gpio4 {\n\t\t\t\tbrcm,pins = <0x4>;\n\t\t\t\tbrcm,function = <0x4>;\n\t\t\t};\n\n\t\t\tgpclk1_gpio5 {\n\t\t\t\tbrcm,pins = <0x5>;\n\t\t\t\tbrcm,function = <0x4>;\n\t\t\t};\n\n\t\t\tgpclk1_gpio42 {\n\t\t\t\tbrcm,pins = <0x2a>;\n\t\t\t\tbrcm,function = <0x4>;\n\t\t\t};\n\n\t\t\tgpclk1_gpio44 {\n\t\t\t\tbrcm,pins = <0x2c>;\n\t\t\t\tbrcm,function = <0x4>;\n\t\t\t};\n\n\t\t\tgpclk2_gpio6 {\n\t\t\t\tbrcm,pins = <0x6>;\n\t\t\t\tbrcm,function = <0x4>;\n\t\t\t};\n\n\t\t\tgpclk2_gpio43 {\n\t\t\t\tbrcm,pins = <0x2b>;\n\t\t\t\tbrcm,function = <0x4>;\n\t\t\t\tbrcm,pull = <0x0>;\n\t\t\t\tphandle = <0x8>;\n\t\t\t};\n\n\t\t\ti2c0_gpio0 {\n\t\t\t\tbrcm,pins = <0x0 0x1>;\n\t\t\t\tbrcm,function = <0x4>;\n\t\t\t};\n\n\t\t\ti2c0_gpio28 {\n\t\t\t\tbrcm,pins = <0x1c 0x1d>;\n\t\t\t\tbrcm,function = <0x4>;\n\t\t\t};\n\n\t\t\ti2c0_gpio44 {\n\t\t\t\tbrcm,pins = <0x2c 0x2d>;\n\t\t\t\tbrcm,function = <0x5>;\n\t\t\t};\n\n\t\t\ti2c1_gpio2 {\n\t\t\t\tbrcm,pins = <0x2 0x3>;\n\t\t\t\tbrcm,function = <0x4>;\n\t\t\t};\n\n\t\t\ti2c1_gpio44 {\n\t\t\t\tbrcm,pins = <0x2c 0x2d>;\n\t\t\t\tbrcm,function = <0x6>;\n\t\t\t};\n\n\t\t\tjtag_gpio22 {\n\t\t\t\tbrcm,pins = <0x16 0x17 0x18 0x19 0x1a 0x1b>;\n\t\t\t\tbrcm,function = <0x3>;\n\t\t\t};\n\n\t\t\tpcm_gpio18 {\n\t\t\t\tbrcm,pins = <0x12 0x13 0x14 0x15>;\n\t\t\t\tbrcm,function = <0x4>;\n\t\t\t};\n\n\t\t\tpcm_gpio28 {\n\t\t\t\tbrcm,pins = <0x1c 0x1d 0x1e 0x1f>;\n\t\t\t\tbrcm,function = <0x6>;\n\t\t\t};\n\n\t\t\tpwm0_gpio12 {\n\t\t\t\tbrcm,pins = <0xc>;\n\t\t\t\tbrcm,function = <0x4>;\n\t\t\t};\n\n\t\t\tpwm0_gpio18 {\n\t\t\t\tbrcm,pins = <0x12>;\n\t\t\t\tbrcm,function = <0x2>;\n\t\t\t};\n\n\t\t\tpwm0_gpio40 {\n\t\t\t\tbrcm,pins = <0x28>;\n\t\t\t\tbrcm,function = <0x4>;\n\t\t\t};\n\n\t\t\tpwm1_gpio13 {\n\t\t\t\tbrcm,pins = <0xd>;\n\t\t\t\tbrcm,function = <0x4>;\n\t\t\t};\n\n\t\t\tpwm1_gpio19 {\n\t\t\t\tbrcm,pins = <0x13>;\n\t\t\t\tbrcm,function = <0x2>;\n\t\t\t};\n\n\t\t\tpwm1_gpio41 {\n\t\t\t\tbrcm,pins = <0x29>;\n\t\t\t\tbrcm,function = <0x4>;\n\t\t\t};\n\n\t\t\tpwm1_gpio45 {\n\t\t\t\tbrcm,pins = <0x2d>;\n\t\t\t\tbrcm,function = <0x4>;\n\t\t\t};\n\n\t\t\tsdhost_gpio48 {\n\t\t\t\tbrcm,pins = <0x30 0x31 0x32 0x33 0x34 0x35>;\n\t\t\t\tbrcm,function = <0x4>;\n\t\t\t};\n\n\t\t\tspi0_gpio7 {\n\t\t\t\tbrcm,pins = <0x7 0x8 0x9 0xa 0xb>;\n\t\t\t\tbrcm,function = <0x4>;\n\t\t\t};\n\n\t\t\tspi0_gpio35 {\n\t\t\t\tbrcm,pins = <0x23 0x24 0x25 0x26 0x27>;\n\t\t\t\tbrcm,function = <0x4>;\n\t\t\t};\n\n\t\t\tspi1_gpio16 {\n\t\t\t\tbrcm,pins = <0x10 0x11 0x12 0x13 0x14 0x15>;\n\t\t\t\tbrcm,function = <0x3>;\n\t\t\t};\n\n\t\t\tspi2_gpio40 {\n\t\t\t\tbrcm,pins = <0x28 0x29 0x2a 0x2b 0x2c 0x2d>;\n\t\t\t\tbrcm,function = <0x3>;\n\t\t\t};\n\n\t\t\tuart0_gpio14 {\n\t\t\t\tbrcm,pins = <0xe 0xf>;\n\t\t\t\tbrcm,function = <0x4>;\n\t\t\t};\n\n\t\t\tuart0_ctsrts_gpio16 {\n\t\t\t\tbrcm,pins = <0x10 0x11>;\n\t\t\t\tbrcm,function = <0x7>;\n\t\t\t};\n\n\t\t\tuart0_ctsrts_gpio30 {\n\t\t\t\tbrcm,pins = <0x1e 0x1f>;\n\t\t\t\tbrcm,function = <0x7>;\n\t\t\t\tbrcm,pull = <0x2 0x0>;\n\t\t\t};\n\n\t\t\tuart0_gpio32 {\n\t\t\t\tbrcm,pins = <0x20 0x21>;\n\t\t\t\tbrcm,function = <0x7>;\n\t\t\t\tbrcm,pull = <0x0 0x2>;\n\t\t\t\tphandle = <0x7>;\n\t\t\t};\n\n\t\t\tuart0_gpio36 {\n\t\t\t\tbrcm,pins = <0x24 0x25>;\n\t\t\t\tbrcm,function = <0x6>;\n\t\t\t};\n\n\t\t\tuart0_ctsrts_gpio38 {\n\t\t\t\tbrcm,pins = <0x26 0x27>;\n\t\t\t\tbrcm,function = <0x6>;\n\t\t\t};\n\n\t\t\tuart1_gpio14 {\n\t\t\t\tbrcm,pins = <0xe 0xf>;\n\t\t\t\tbrcm,function = <0x2>;\n\t\t\t};\n\n\t\t\tuart1_ctsrts_gpio16 {\n\t\t\t\tbrcm,pins = <0x10 0x11>;\n\t\t\t\tbrcm,function = <0x2>;\n\t\t\t};\n\n\t\t\tuart1_gpio32 {\n\t\t\t\tbrcm,pins = <0x20 0x21>;\n\t\t\t\tbrcm,function = <0x2>;\n\t\t\t};\n\n\t\t\tuart1_ctsrts_gpio30 {\n\t\t\t\tbrcm,pins = <0x1e 0x1f>;\n\t\t\t\tbrcm,function = <0x2>;\n\t\t\t};\n\n\t\t\tuart1_gpio40 {\n\t\t\t\tbrcm,pins = <0x28 0x29>;\n\t\t\t\tbrcm,function = <0x2>;\n\t\t\t};\n\n\t\t\tuart1_ctsrts_gpio42 {\n\t\t\t\tbrcm,pins = <0x2a 0x2b>;\n\t\t\t\tbrcm,function = <0x2>;\n\t\t\t};\n\n\t\t\tuart1_pins {\n\t\t\t\tbrcm,pins;\n\t\t\t\tbrcm,function;\n\t\t\t\tbrcm,pull;\n\t\t\t\tphandle = <0xb>;\n\t\t\t};\n\t\t};\n\n\t\tserial@7e201000 {\n\t\t\tcompatible = \"brcm,bcm2835-pl011\", \"arm,pl011\", \"arm,primecell\";\n\t\t\treg = <0x7e201000 0x1000>;\n\t\t\tinterrupts = <0x0 0x79 0x4>;\n\t\t\tclocks = <0x3 0x13 0x3 0x14>;\n\t\t\tclock-names = \"uartclk\", \"apb_pclk\";\n\t\t\tarm,primecell-periphid = <0x241011>;\n\t\t\tpinctrl-names = \"default\";\n\t\t\tpinctrl-0 = <0x7 0x8>;\n\t\t\tstatus = \"okay\";\n\t\t};\n\n\t\tmmc@7e202000 {\n\t\t\tcompatible = \"brcm,bcm2835-sdhost\";\n\t\t\treg = <0x7e202000 0x100>;\n\t\t\tinterrupts = <0x0 0x78 0x4>;\n\t\t\tclocks = <0x3 0x14>;\n\t\t\tdmas = <0x9 0xd>;\n\t\t\tdma-names = \"rx-tx\";\n\t\t\tstatus = \"disabled\";\n\t\t};\n\n\t\ti2s@7e203000 {\n\t\t\tcompatible = \"brcm,bcm2835-i2s\";\n\t\t\treg = <0x7e203000 0x24>;\n\t\t\tclocks = <0x3 0x1f>;\n\t\t\tdmas = <0x9 0x2 0x9 0x3>;\n\t\t\tdma-names = \"tx\", \"rx\";\n\t\t\tstatus = \"disabled\";\n\t\t};\n\n\t\tspi@7e204000 {\n\t\t\tcompatible = \"brcm,bcm2835-spi\";\n\t\t\treg = <0x7e204000 0x200>;\n\t\t\tinterrupts = <0x0 0x76 0x4>;\n\t\t\tclocks = <0x3 0x14>;\n\t\t\t#address-cells = <0x1>;\n\t\t\t#size-cells = <0x0>;\n\t\t\tstatus = \"disabled\";\n\t\t};\n\n\t\ti2c@7e205000 {\n\t\t\tcompatible = \"brcm,bcm2835-i2c\";\n\t\t\treg = <0x7e205000 0x1000>;\n\t\t\tinterrupts = <0x0 0x75 0x4>;\n\t\t\tclocks = <0x3 0x14>;\n\t\t\t#address-cells = <0x1>;\n\t\t\t#size-cells = <0x0>;\n\t\t\tstatus = \"disabled\";\n\t\t};\n\n\t\tpixelvalve@7e206000 {\n\t\t\tcompatible = \"brcm,bcm2835-pixelvalve0\";\n\t\t\treg = <0x7e206000 0x100>;\n\t\t\tinterrupts = <0x0 0x6d 0x4>;\n\t\t};\n\n\t\tpixelvalve@7e207000 {\n\t\t\tcompatible = \"brcm,bcm2835-pixelvalve1\";\n\t\t\treg = <0x7e207000 0x100>;\n\t\t\tinterrupts = <0x0 0x6e 0x4>;\n\t\t};\n\n\t\tdpi@7e208000 {\n\t\t\tcompatible = \"brcm,bcm2835-dpi\";\n\t\t\treg = <0x7e208000 0x8c>;\n\t\t\tclocks = <0x3 0x14 0x3 0x2c>;\n\t\t\tclock-names = \"core\", \"pixel\";\n\t\t\t#address-cells = <0x1>;\n\t\t\t#size-cells = <0x0>;\n\t\t\tstatus = \"disabled\";\n\t\t};\n\n\t\tdsi@7e209000 {\n\t\t\tcompatible = \"brcm,bcm2835-dsi0\";\n\t\t\treg = <0x7e209000 0x78>;\n\t\t\tinterrupts = <0x0 0x64 0x4>;\n\t\t\t#address-cells = <0x1>;\n\t\t\t#size-cells = <0x0>;\n\t\t\t#clock-cells = <0x1>;\n\t\t\tclocks = <0x3 0x20 0x3 0x2f 0x3 0x31>;\n\t\t\tclock-names = \"phy\", \"escape\", \"pixel\";\n\t\t\tclock-output-names = \"dsi0_byte\", \"dsi0_ddr2\", \"dsi0_ddr\";\n\t\t\tphandle = <0x5>;\n\t\t};\n\n\t\taux@7e215000 {\n\t\t\tcompatible = \"brcm,bcm2835-aux\";\n\t\t\t#clock-cells = <0x1>;\n\t\t\treg = <0x7e215000 0x8>;\n\t\t\tclocks = <0x3 0x14>;\n\t\t\tphandle = <0xa>;\n\t\t};\n\n\t\tserial@7e215040 {\n\t\t\tcompatible = \"brcm,bcm2835-aux-uart\";\n\t\t\treg = <0x7e215040 0x40>;\n\t\t\tinterrupts = <0x0 0x5d 0x4>;\n\t\t\tclocks = <0xa 0x0>;\n\t\t\tstatus = \"okay\";\n\t\t\tpinctrl-names = \"default\";\n\t\t\tpinctrl-0 = <0xb>;\n\t\t};\n\n\t\tspi@7e215080 {\n\t\t\tcompatible = \"brcm,bcm2835-aux-spi\";\n\t\t\treg = <0x7e215080 0x40>;\n\t\t\tinterrupts = <0x0 0x5d 0x4>;\n\t\t\tclocks = <0xa 0x1>;\n\t\t\t#address-cells = <0x1>;\n\t\t\t#size-cells = <0x0>;\n\t\t\tstatus = \"disabled\";\n\t\t};\n\n\t\tspi@7e2150c0 {\n\t\t\tcompatible = \"brcm,bcm2835-aux-spi\";\n\t\t\treg = <0x7e2150c0 0x40>;\n\t\t\tinterrupts = <0x0 0x5d 0x4>;\n\t\t\tclocks = <0xa 0x2>;\n\t\t\t#address-cells = <0x1>;\n\t\t\t#size-cells = <0x0>;\n\t\t\tstatus = \"disabled\";\n\t\t};\n\n\t\tpwm@7e20c000 {\n\t\t\tcompatible = \"brcm,bcm2835-pwm\";\n\t\t\treg = <0x7e20c000 0x28>;\n\t\t\tclocks = <0x3 0x1e>;\n\t\t\tassigned-clocks = <0x3 0x1e>;\n\t\t\tassigned-clock-rates = <0x989680>;\n\t\t\t#pwm-cells = <0x2>;\n\t\t\tstatus = \"disabled\";\n\t\t};\n\n\t\tsdhci@7e300000 {\n\t\t\tcompatible = \"brcm,bcm2835-sdhci\";\n\t\t\treg = <0x7e300000 0x100>;\n\t\t\tinterrupts = <0x2 0x1e>;\n\t\t\tclocks = <0x3 0x1c>;\n\t\t\tstatus = \"disabled\";\n\t\t};\n\n\t\thvs@7e400000 {\n\t\t\tcompatible = \"brcm,bcm2835-hvs\";\n\t\t\treg = <0x7e400000 0x6000>;\n\t\t\tinterrupts = <0x0 0x61 0x4>;\n\t\t};\n\n\t\tdsi@7e700000 {\n\t\t\tcompatible = \"brcm,bcm2835-dsi1\";\n\t\t\treg = <0x7e700000 0x8c>;\n\t\t\tinterrupts = <0x0 0x6c 0x4>;\n\t\t\t#address-cells = <0x1>;\n\t\t\t#size-cells = <0x0>;\n\t\t\t#clock-cells = <0x1>;\n\t\t\tclocks = <0x3 0x23 0x3 0x30 0x3 0x32>;\n\t\t\tclock-names = \"phy\", \"escape\", \"pixel\";\n\t\t\tclock-output-names = \"dsi1_byte\", \"dsi1_ddr2\", \"dsi1_ddr\";\n\t\t\tstatus = \"disabled\";\n\t\t\tphandle = <0x6>;\n\t\t};\n\n\t\ti2c@7e804000 {\n\t\t\tcompatible = \"brcm,bcm2835-i2c\";\n\t\t\treg = <0x7e804000 0x1000>;\n\t\t\tinterrupts = <0x0 0x75 0x4>;\n\t\t\tclocks = <0x3 0x14>;\n\t\t\t#address-cells = <0x1>;\n\t\t\t#size-cells = <0x0>;\n\t\t\tstatus = \"disabled\";\n\t\t};\n\n\t\ti2c@7e805000 {\n\t\t\tcompatible = \"brcm,bcm2835-i2c\";\n\t\t\treg = <0x7e805000 0x1000>;\n\t\t\tinterrupts = <0x0 0x75 0x4>;\n\t\t\tclocks = <0x3 0x14>;\n\t\t\t#address-cells = <0x1>;\n\t\t\t#size-cells = <0x0>;\n\t\t\tstatus = \"disabled\";\n\t\t\tphandle = <0xc>;\n\t\t};\n\n\t\tvec@7e806000 {\n\t\t\tcompatible = \"brcm,bcm2835-vec\";\n\t\t\treg = <0x7e806000 0x1000>;\n\t\t\tclocks = <0x3 0x18>;\n\t\t\tinterrupts = <0x0 0x7b 0x4>;\n\t\t\tstatus = \"disabled\";\n\t\t};\n\n\t\tpixelvalve@7e807000 {\n\t\t\tcompatible = \"brcm,bcm2835-pixelvalve2\";\n\t\t\treg = <0x7e807000 0x100>;\n\t\t\tinterrupts = <0x0 0x6a 0x4>;\n\t\t};\n\n\t\thdmi@7e902000 {\n\t\t\tcompatible = \"brcm,bcm2835-hdmi\";\n\t\t\treg = <0x7e902000 0x600 0x7e808000 0x100>;\n\t\t\tinterrupts = <0x0 0x68 0x4 0x0 0x69 0x4>;\n\t\t\tddc = <0xc>;\n\t\t\tclocks = <0x3 0x10 0x3 0x19>;\n\t\t\tclock-names = \"pixel\", \"hdmi\";\n\t\t\tdmas = <0x9 0x11>;\n\t\t\tdma-names = \"audio-rx\";\n\t\t\tstatus = \"disabled\";\n\t\t};\n\n\t\tusb@7e980000 {\n\t\t\tcompatible = \"brcm,bcm2835-usb\";\n\t\t\treg = <0x7e980000 0x10000>;\n\t\t\tinterrupts = <0x0 0x49 0x4>;\n\t\t\t#address-cells = <0x1>;\n\t\t\t#size-cells = <0x0>;\n\t\t\tclocks = <0xd>;\n\t\t\tclock-names = \"otg\";\n\t\t\tphys = <0xe>;\n\t\t\tphy-names = \"usb2-phy\";\n\t\t};\n\n\t\tgpu {\n\t\t\tcompatible = \"brcm,bcm2835-vc4\";\n\t\t};\n\n\t\tgic400@40041000 {\n\t\t\tinterrupt-controller;\n\t\t\t#interrupt-cells = <0x3>;\n\t\t\tcompatible = \"arm,gic-400\";\n\t\t\treg = <0x40041000 0x1000 0x40042000 0x2000 0x40044000 0x2000 0x40046000 0x2000>;\n\t\t\tphandle = <0x1>;\n\t\t};\n\n\t\tthermal@7d5d2200 {\n\t\t\tcompatible = \"brcm,avs-tmon-bcm2838\";\n\t\t\treg = <0x7d5d2200 0x2c>;\n\t\t\tinterrupts = <0x0 0x89 0x4>;\n\t\t\tinterrupt-names = \"tmon\";\n\t\t\tclocks = <0x3 0x1b>;\n\t\t\t#thermal-sensor-cells = <0x0>;\n\t\t\tstatus = \"okay\";\n\t\t\tphandle = <0x2>;\n\t\t};\n\n\t\temmc2@7e340000 {\n\t\t\tcompatible = \"brcm,bcm2711-emmc2\";\n\t\t\tstatus = \"okay\";\n\t\t\tinterrupts = <0x0 0x7e 0x4>;\n\t\t\tclocks = <0x3 0x33>;\n\t\t\treg = <0x7e340000 0x100>;\n\t\t};\n\t};\n\n\tclocks {\n\t\tcompatible = \"simple-bus\";\n\t\t#address-cells = <0x1>;\n\t\t#size-cells = <0x0>;\n\n\t\tclock@3 {\n\t\t\tcompatible = \"fixed-clock\";\n\t\t\treg = <0x3>;\n\t\t\t#clock-cells = <0x0>;\n\t\t\tclock-output-names = \"osc\";\n\t\t\tclock-frequency = <0x337f980>;\n\t\t\tphandle = <0x4>;\n\t\t};\n\n\t\tclock@4 {\n\t\t\tcompatible = \"fixed-clock\";\n\t\t\treg = <0x4>;\n\t\t\t#clock-cells = <0x0>;\n\t\t\tclock-output-names = \"otg\";\n\t\t\tclock-frequency = <0x1c9c3800>;\n\t\t\tphandle = <0xd>;\n\t\t};\n\t};\n\n\tphy {\n\t\tcompatible = \"usb-nop-xceiv\";\n\t\t#phy-cells = <0x0>;\n\t\tphandle = <0xe>;\n\t};\n\n\tarm-pmu {\n\t\tcompatible = \"arm,cortex-a72-pmu\", \"arm,cortex-a53-pmu\";\n\t\tinterrupts = <0x0 0x10 0x4 0x0 0x11 0x4 0x0 0x12 0x4 0x0 0x13 0x4>;\n\t};\n\n\ttimer {\n\t\tcompatible = \"arm,armv7-timer\";\n\t\tinterrupts = <0x1 0xd 0xf08 0x1 0xe 0xf08 0x1 0xb 0xf08 0x1 0xa 0xf08>;\n\t\tarm,cpu-registers-not-fw-configured;\n\t\talways-on;\n\t};\n\n\tcpus {\n\t\t#address-cells = <0x1>;\n\t\t#size-cells = <0x0>;\n\t\tenable-method = \"brcm,bcm2836-smp\";\n\n\t\tcpu@0 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,cortex-a72\";\n\t\t\treg = <0x0>;\n\t\t\tenable-method = \"spin-table\";\n\t\t\tcpu-release-addr = <0x0 0xd8>;\n\t\t};\n\n\t\tcpu@1 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,cortex-a72\";\n\t\t\treg = <0x1>;\n\t\t\tenable-method = \"spin-table\";\n\t\t\tcpu-release-addr = <0x0 0xe0>;\n\t\t};\n\n\t\tcpu@2 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,cortex-a72\";\n\t\t\treg = <0x2>;\n\t\t\tenable-method = \"spin-table\";\n\t\t\tcpu-release-addr = <0x0 0xe8>;\n\t\t};\n\n\t\tcpu@3 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,cortex-a72\";\n\t\t\treg = <0x3>;\n\t\t\tenable-method = \"spin-table\";\n\t\t\tcpu-release-addr = <0x0 0xf0>;\n\t\t};\n\t};\n\n\tmemory {\n\t\tdevice_type = \"memory\";\n\t};\n\n\tleds {\n\n\t\tact {\n\t\t\tgpios = <0xf 0x2f 0x0>;\n\t\t};\n\t};\n};\n"
  },
  {
    "path": "kernel/dtbs/foundation-v8-gicv2.dts",
    "content": "/dts-v1/;\n\n/ {\n\tmodel = \"FVP Foundation\";\n\tcompatible = \"arm,fvp-base\", \"arm,vexpress\";\n\tinterrupt-parent = <0x1>;\n\t#address-cells = <0x2>;\n\t#size-cells = <0x2>;\n\n\tchosen {\n\t\tbootargs = \"console=ttyAMA0 earlycon=pl011,0x1c090000 loglevel=8 consolelog=9 root=/dev/vda2 rw\";\n\t\tminos,stdout = \"pl011\";\n\t};\n\n\taliases {\n\t\tserial0 = \"/smb/motherboard/iofpga@3,00000000/uart@090000\";\n\t\tserial1 = \"/smb/motherboard/iofpga@3,00000000/uart@0a0000\";\n\t\tserial2 = \"/smb/motherboard/iofpga@3,00000000/uart@0b0000\";\n\t};\n\n\tvms {\n\t\tvm1 {\n\t\t\tdevice_type = \"virtual_machine\";\n\t\t\tvm_name = \"fvp_linux_host\";\n\t\t\thost_vm;\n\t\t\tvmid = <1>;\n\t\t\ttype = \"linux\";\n\t\t\tvcpus = <2>;\n\t\t\tentry = <0x0 0x80080000>;\n\t\t\tsetup_data = <0x0 0x83e00000>;\n\t\t\tvcpu_affinity = <0 1 2 3>;\n\t\t\tcmdline = \"console=hvc0 earlycon=dbcon,io,0x0 loglevel=8 consolelog=9 root=/dev/vda2 rw\";\n\t\t\tmemory = <0x0 0x80000000 0x0 0x10000000>;\n\n\t\t\tvm1_bdi {\n\t\t\t\tvm_console_vm1 {\n\t\t\t\t\tvirtual_device;\n\t\t\t\t\tvc-dynamic-res;\n\t\t\t\t\tcompatible = \"minos,vm_console\";\n\t\t\t\t};\n\t\t\t};\n\t\t};\n\n\t};\n\n\tpsci {\n\t\tcompatible = \"arm,psci-1.0\", \"arm,psci-0.2\", \"arm,psci\";\n\t\tmethod = \"smc\";\n\t\tcpu_suspend = <0xc4000001>;\n\t\tcpu_off = <0x84000002>;\n\t\tcpu_on = <0xc4000003>;\n\t\tsys_poweroff = <0x84000008>;\n\t\tsys_reset = <0x84000009>;\n\t};\n\n\tcpus {\n\t\t#address-cells = <0x2>;\n\t\t#size-cells = <0x0>;\n\n\t\tcpu-map {\n\n\t\t\tcluster0 {\n\n\t\t\t\tcore0 {\n\t\t\t\t\tcpu = <0x2>;\n\t\t\t\t};\n\n\t\t\t\tcore1 {\n\t\t\t\t\tcpu = <0x3>;\n\t\t\t\t};\n\n\t\t\t\tcore2 {\n\t\t\t\t\tcpu = <0x4>;\n\t\t\t\t};\n\n\t\t\t\tcore3 {\n\t\t\t\t\tcpu = <0x5>;\n\t\t\t\t};\n\t\t\t};\n\t\t};\n\n\t\tidle-states {\n\t\t\tentry-method = \"arm,psci\";\n\n\t\t\tcpu-sleep-0 {\n\t\t\t\tcompatible = \"arm,idle-state\";\n\t\t\t\tlocal-timer-stop;\n\t\t\t\tarm,psci-suspend-param = <0x10000>;\n\t\t\t\tentry-latency-us = <0x28>;\n\t\t\t\texit-latency-us = <0x64>;\n\t\t\t\tmin-residency-us = <0x96>;\n\t\t\t\tlinux,phandle = <0x6>;\n\t\t\t\tphandle = <0x6>;\n\t\t\t};\n\n\t\t\tcluster-sleep-0 {\n\t\t\t\tcompatible = \"arm,idle-state\";\n\t\t\t\tlocal-timer-stop;\n\t\t\t\tarm,psci-suspend-param = <0x1010000>;\n\t\t\t\tentry-latency-us = <0x1f4>;\n\t\t\t\texit-latency-us = <0x3e8>;\n\t\t\t\tmin-residency-us = <0x9c4>;\n\t\t\t\tlinux,phandle = <0x7>;\n\t\t\t\tphandle = <0x7>;\n\t\t\t};\n\t\t};\n\n\t\tcpu@0 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,armv8\";\n\t\t\treg = <0x0 0x0>;\n\t\t\tenable-method = \"psci\";\n\t\t\tcpu-idle-states = <0x6 0x7>;\n\t\t\tnext-level-cache = <0x8>;\n\t\t\tlinux,phandle = <0x2>;\n\t\t\tphandle = <0x2>;\n\t\t};\n\n\t\tcpu@1 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,armv8\";\n\t\t\treg = <0x0 0x1>;\n\t\t\tenable-method = \"psci\";\n\t\t\tcpu-idle-states = <0x6 0x7>;\n\t\t\tnext-level-cache = <0x8>;\n\t\t\tlinux,phandle = <0x3>;\n\t\t\tphandle = <0x3>;\n\t\t};\n\n\t\tcpu@2 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,armv8\";\n\t\t\treg = <0x0 0x2>;\n\t\t\tenable-method = \"psci\";\n\t\t\tcpu-idle-states = <0x6 0x7>;\n\t\t\tnext-level-cache = <0x8>;\n\t\t\tlinux,phandle = <0x4>;\n\t\t\tphandle = <0x4>;\n\t\t};\n\n\t\tcpu@3 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,armv8\";\n\t\t\treg = <0x0 0x3>;\n\t\t\tenable-method = \"psci\";\n\t\t\tcpu-idle-states = <0x6 0x7>;\n\t\t\tnext-level-cache = <0x8>;\n\t\t\tlinux,phandle = <0x5>;\n\t\t\tphandle = <0x5>;\n\t\t};\n\n\t\tl2-cache0 {\n\t\t\tcompatible = \"cache\";\n\t\t\tlinux,phandle = <0x8>;\n\t\t\tphandle = <0x8>;\n\t\t};\n\t};\n\n\tmemory@80000000 {\n\t\tdevice_type = \"memory\";\n\t\treg = <0x0 0x80000000 0x0 0x80000000 0x8 0x80000000 0x0 0x80000000>;\n\t};\n\n\tinterrupt-controller@2f000000 {\n\t\tcompatible = \"arm,cortex-a15-gic\", \"arm,cortex-a9-gic\";\n\t\t#interrupt-cells = <0x3>;\n\t\t#address-cells = <0x2>;\n\t\t#size-cells = <0x2>;\n\t\tinterrupt-controller;\n\t\treg = <0x0 0x2f000000 0x0 0x10000 0x0 0x2c000000 0x0 0x2000 0x0 0x2c010000 0x0 0x2000 0x0 0x2c02f000 0x0 0x2000>;\n\t\tinterrupts = <0x1 0x9 0x4>;\n\t\tlinux,phandle = <0x1>;\n\t\tphandle = <0x1>;\n\n\t\tits@2f020000 {\n\t\t\tcompatible = \"arm,gic-v3-its\";\n\t\t\tmsi-controller;\n\t\t\treg = <0x0 0x2f020000 0x0 0x20000>;\n\t\t};\n\t};\n\n\ttimer {\n\t\tcompatible = \"arm,armv8-timer\";\n\t\tinterrupts = <0x1 0xd 0xff01 0x1 0xe 0xff01 0x1 0xb 0xff01 0x1 0xa 0xff01>;\n\t\tclock-frequency = <0x5f5e100>;\n\t};\n\n\tpmu {\n\t\tcompatible = \"arm,armv8-pmuv3\";\n\t\tinterrupts = <0x0 0x3c 0x4 0x0 0x3d 0x4 0x0 0x3e 0x4 0x0 0x3f 0x4>;\n\t};\n\n\tsmb {\n\t\tcompatible = \"simple-bus\";\n\t\t#address-cells = <0x2>;\n\t\t#size-cells = <0x1>;\n\t\tranges = <0x0 0x0 0x0 0x8000000 0x4000000 0x1 0x0 0x0 0x14000000 0x4000000 0x2 0x0 0x0 0x18000000 0x4000000 0x3 0x0 0x0 0x1c000000 0x4000000 0x4 0x0 0x0 0xc000000 0x4000000 0x5 0x0 0x0 0x10000000 0x4000000>;\n\n\t\tmotherboard {\n\t\t\tarm,v2m-memory-map = \"rs1\";\n\t\t\tcompatible = \"arm,vexpress,v2m-p1\", \"simple-bus\";\n\t\t\t#address-cells = <0x2>;\n\t\t\t#size-cells = <0x1>;\n\t\t\tranges;\n\n\t\t\tethernet@2,02000000 {\n\t\t\t\tcompatible = \"smsc,lan91c111\";\n\t\t\t\treg = <0x2 0x2000000 0x10000>;\n\t\t\t\tinterrupts = <0x0 0xf 0x4>;\n\t\t\t};\n\n\t\t\tclk24mhz {\n\t\t\t\tcompatible = \"fixed-clock\";\n\t\t\t\t#clock-cells = <0x0>;\n\t\t\t\tclock-frequency = <0x16e3600>;\n\t\t\t\tclock-output-names = \"v2m:clk24mhz\";\n\t\t\t\tlinux,phandle = <0xb>;\n\t\t\t\tphandle = <0xb>;\n\t\t\t};\n\n\t\t\trefclk1mhz {\n\t\t\t\tcompatible = \"fixed-clock\";\n\t\t\t\t#clock-cells = <0x0>;\n\t\t\t\tclock-frequency = <0xf4240>;\n\t\t\t\tclock-output-names = \"v2m:refclk1mhz\";\n\t\t\t\tlinux,phandle = <0xa>;\n\t\t\t\tphandle = <0xa>;\n\t\t\t};\n\n\t\t\trefclk32khz {\n\t\t\t\tcompatible = \"fixed-clock\";\n\t\t\t\t#clock-cells = <0x0>;\n\t\t\t\tclock-frequency = <0x8000>;\n\t\t\t\tclock-output-names = \"v2m:refclk32khz\";\n\t\t\t\tlinux,phandle = <0x9>;\n\t\t\t\tphandle = <0x9>;\n\t\t\t};\n\n\t\t\tiofpga@3,00000000 {\n\t\t\t\tcompatible = \"arm,amba-bus\", \"simple-bus\";\n\t\t\t\t#address-cells = <0x1>;\n\t\t\t\t#size-cells = <0x1>;\n\t\t\t\tranges = <0x0 0x3 0x0 0x200000>;\n\n\t\t\t\tsysreg@010000 {\n\t\t\t\t\tcompatible = \"arm,vexpress-sysreg\";\n\t\t\t\t\treg = <0x10000 0x1000>;\n\t\t\t\t\tgpio-controller;\n\t\t\t\t\t#gpio-cells = <0x2>;\n\t\t\t\t\tlinux,phandle = <0xd>;\n\t\t\t\t\tphandle = <0xd>;\n\t\t\t\t};\n\n\t\t\t\tsysctl@020000 {\n\t\t\t\t\tcompatible = \"arm,sp810\", \"arm,primecell\";\n\t\t\t\t\treg = <0x20000 0x1000>;\n\t\t\t\t\tclocks = <0x9 0xa 0xb>;\n\t\t\t\t\tclock-names = \"refclk\", \"timclk\", \"apb_pclk\";\n\t\t\t\t\t#clock-cells = <0x1>;\n\t\t\t\t\tclock-output-names = \"timerclken0\", \"timerclken1\", \"timerclken2\", \"timerclken3\";\n\t\t\t\t\tlinux,phandle = <0xc>;\n\t\t\t\t\tphandle = <0xc>;\n\t\t\t\t};\n\n\t\t\t\tuart@090000 {\n\t\t\t\t\tcompatible = \"arm,pl011\", \"arm,primecell\";\n\t\t\t\t\treg = <0x90000 0x1000>;\n\t\t\t\t\tinterrupts = <0x0 0x5 0x4>;\n\t\t\t\t\tclocks = <0xb 0xb>;\n\t\t\t\t\tclock-names = \"uartclk\", \"apb_pclk\";\n\t\t\t\t};\n\n\t\t\t\tuart@0a0000 {\n\t\t\t\t\tcompatible = \"arm,pl011\", \"arm,primecell\";\n\t\t\t\t\treg = <0xa0000 0x1000>;\n\t\t\t\t\tinterrupts = <0x0 0x6 0x4>;\n\t\t\t\t\tclocks = <0xb 0xb>;\n\t\t\t\t\tclock-names = \"uartclk\", \"apb_pclk\";\n\t\t\t\t};\n\n\t\t\t\tuart@0b0000 {\n\t\t\t\t\tcompatible = \"arm,pl011\", \"arm,primecell\";\n\t\t\t\t\treg = <0xb0000 0x1000>;\n\t\t\t\t\tinterrupts = <0x0 0x7 0x4>;\n\t\t\t\t\tclocks = <0xb 0xb>;\n\t\t\t\t\tclock-names = \"uartclk\", \"apb_pclk\";\n\t\t\t\t};\n\n\t\t\t\twdt@0f0000 {\n\t\t\t\t\tcompatible = \"arm,sp805\", \"arm,primecell\";\n\t\t\t\t\treg = <0xf0000 0x1000>;\n\t\t\t\t\tinterrupts = <0x0 0x0 0x4>;\n\t\t\t\t\tclocks = <0x9 0xb>;\n\t\t\t\t\tclock-names = \"wdogclk\", \"apb_pclk\";\n\t\t\t\t};\n\n\t\t\t\ttimer@120000 {\n\t\t\t\t\tcompatible = \"arm,sp804\", \"arm,primecell\";\n\t\t\t\t\treg = <0x120000 0x1000>;\n\t\t\t\t\tinterrupts = <0x0 0x3 0x4>;\n\t\t\t\t\tclocks = <0xc 0x2 0xc 0x3 0xb>;\n\t\t\t\t\tclock-names = \"timclken1\", \"timclken2\", \"apb_pclk\";\n\t\t\t\t};\n\n\t\t\t\trtc@170000 {\n\t\t\t\t\tcompatible = \"arm,pl031\", \"arm,primecell\";\n\t\t\t\t\treg = <0x170000 0x1000>;\n\t\t\t\t\tinterrupts = <0x0 0x4 0x4>;\n\t\t\t\t\tclocks = <0xb>;\n\t\t\t\t\tclock-names = \"apb_pclk\";\n\t\t\t\t};\n\n\t\t\t\tvirtio_block@0130000 {\n\t\t\t\t\tcompatible = \"virtio,mmio\";\n\t\t\t\t\treg = <0x130000 0x1000>;\n\t\t\t\t\tinterrupts = <0x0 0x2a 0x4>;\n\t\t\t\t};\n\t\t\t};\n\n\t\t\tfixedregulator@0 {\n\t\t\t\tcompatible = \"regulator-fixed\";\n\t\t\t\tregulator-name = \"3V3\";\n\t\t\t\tregulator-min-microvolt = <0x325aa0>;\n\t\t\t\tregulator-max-microvolt = <0x325aa0>;\n\t\t\t\tregulator-always-on;\n\t\t\t};\n\n\t\t\tmcc {\n\t\t\t\tcompatible = \"arm,vexpress,config-bus\", \"simple-bus\";\n\t\t\t\tarm,vexpress,config-bridge = <0xd>;\n\n\t\t\t\tmuxfpga@0 {\n\t\t\t\t\tcompatible = \"arm,vexpress-muxfpga\";\n\t\t\t\t\tarm,vexpress-sysreg,func = <0x7 0x0>;\n\t\t\t\t};\n\n\t\t\t\tdvimode@0 {\n\t\t\t\t\tcompatible = \"arm,vexpress-dvimode\";\n\t\t\t\t\tarm,vexpress-sysreg,func = <0xb 0x0>;\n\t\t\t\t};\n\t\t\t};\n\t\t};\n\t};\n};\n"
  },
  {
    "path": "kernel/dtbs/foundation-v8-gicv3-zephyr.dts",
    "content": "/dts-v1/;\n\n/ {\n\tmodel = \"FVP Base\";\n\tcompatible = \"arm,fvp-base\", \"arm,vexpress\";\n\tinterrupt-parent = < 0x01 >;\n\t#address-cells = < 0x02 >;\n\t#size-cells = < 0x02 >;\n\n\tchosen {\n\t\tminos,stdout = \"pl011\";\n\t\tbootargs = \"bootwait=3 tty=vm0 rootfs=virtio-blk.drv\";\n\t\tminos,ramdisk-start = <0x0 0xc4000000>;\n\t\tminos,ramdisk-end = <0x0 0xC40E7000>;\n\t};\n\n\taliases {\n\t\tserial0 = \"/smb@0,0/motherboard/iofpga@3,00000000/uart@90000\";\n\t\tserial1 = \"/smb@0,0/motherboard/iofpga@3,00000000/uart@a0000\";\n\t\tserial2 = \"/smb@0,0/motherboard/iofpga@3,00000000/uart@b0000\";\n\t\tserial3 = \"/smb@0,0/motherboard/iofpga@3,00000000/uart@c0000\";\n\t};\n\n\tpsci {\n\t\tcompatible = \"arm,psci-1.0\", \"arm,psci-0.2\", \"arm,psci\";\n\t\tmethod = \"smc\";\n\t\tcpu_suspend = < 0xc4000001 >;\n\t\tcpu_off = < 0x84000002 >;\n\t\tcpu_on = < 0xc4000003 >;\n\t\tsys_poweroff = < 0x84000008 >;\n\t\tsys_reset = < 0x84000009 >;\n\t};\n\n\tcpus {\n\t\t#address-cells = < 0x02 >;\n\t\t#size-cells = < 0x00 >;\n\n\t\tcpu-map {\n\n\t\t\tcluster0 {\n\n\t\t\t\tcore0 {\n\t\t\t\t\tcpu = < 0x02 >;\n\t\t\t\t};\n\n\t\t\t\tcore1 {\n\t\t\t\t\tcpu = < 0x03 >;\n\t\t\t\t};\n\n\t\t\t\tcore2 {\n\t\t\t\t\tcpu = < 0x04 >;\n\t\t\t\t};\n\n\t\t\t\tcore3 {\n\t\t\t\t\tcpu = < 0x05 >;\n\t\t\t\t};\n\t\t\t};\n\n\t\t\tcluster1 {\n\n\t\t\t\tcore0 {\n\t\t\t\t\tcpu = < 0x06 >;\n\t\t\t\t};\n\n\t\t\t\tcore1 {\n\t\t\t\t\tcpu = < 0x07 >;\n\t\t\t\t};\n\n\t\t\t\tcore2 {\n\t\t\t\t\tcpu = < 0x08 >;\n\t\t\t\t};\n\n\t\t\t\tcore3 {\n\t\t\t\t\tcpu = < 0x09 >;\n\t\t\t\t};\n\t\t\t};\n\t\t};\n\n\t\tidle-states {\n\t\t\tentry-method = \"arm,psci\";\n\n\t\t\tcpu-sleep-0 {\n\t\t\t\tcompatible = \"arm,idle-state\";\n\t\t\t\tlocal-timer-stop;\n\t\t\t\tarm,psci-suspend-param = < 0x10000 >;\n\t\t\t\tentry-latency-us = < 0x28 >;\n\t\t\t\texit-latency-us = < 0x64 >;\n\t\t\t\tmin-residency-us = < 0x96 >;\n\t\t\t\tlinux,phandle = < 0x0a >;\n\t\t\t\tphandle = < 0x0a >;\n\t\t\t};\n\n\t\t\tcluster-sleep-0 {\n\t\t\t\tcompatible = \"arm,idle-state\";\n\t\t\t\tlocal-timer-stop;\n\t\t\t\tarm,psci-suspend-param = < 0x1010000 >;\n\t\t\t\tentry-latency-us = < 0x1f4 >;\n\t\t\t\texit-latency-us = < 0x3e8 >;\n\t\t\t\tmin-residency-us = < 0x9c4 >;\n\t\t\t\tlinux,phandle = < 0x0b >;\n\t\t\t\tphandle = < 0x0b >;\n\t\t\t};\n\t\t};\n\n\t\tcpu@0 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,armv8\";\n\t\t\treg = < 0x00 0x00 >;\n\t\t\tenable-method = \"psci\";\n\t\t\tcpu-idle-states = < 0x0a 0x0b >;\n\t\t\tnext-level-cache = < 0x0c >;\n\t\t\tlinux,phandle = < 0x02 >;\n\t\t\tphandle = < 0x02 >;\n\t\t};\n\n\t\tcpu@1 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,armv8\";\n\t\t\treg = < 0x00 0x01 >;\n\t\t\tenable-method = \"psci\";\n\t\t\tcpu-idle-states = < 0x0a 0x0b >;\n\t\t\tnext-level-cache = < 0x0c >;\n\t\t\tlinux,phandle = < 0x03 >;\n\t\t\tphandle = < 0x03 >;\n\t\t};\n\n\t\tcpu@2 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,armv8\";\n\t\t\treg = < 0x00 0x02 >;\n\t\t\tenable-method = \"psci\";\n\t\t\tcpu-idle-states = < 0x0a 0x0b >;\n\t\t\tnext-level-cache = < 0x0c >;\n\t\t\tlinux,phandle = < 0x04 >;\n\t\t\tphandle = < 0x04 >;\n\t\t};\n\n\t\tcpu@3 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,armv8\";\n\t\t\treg = < 0x00 0x03 >;\n\t\t\tenable-method = \"psci\";\n\t\t\tcpu-idle-states = < 0x0a 0x0b >;\n\t\t\tnext-level-cache = < 0x0c >;\n\t\t\tlinux,phandle = < 0x05 >;\n\t\t\tphandle = < 0x05 >;\n\t\t};\n\n\t\tcpu@100 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,armv8\";\n\t\t\treg = < 0x00 0x100 >;\n\t\t\tenable-method = \"psci\";\n\t\t\tcpu-idle-states = < 0x0a 0x0b >;\n\t\t\tnext-level-cache = < 0x0c >;\n\t\t\tlinux,phandle = < 0x06 >;\n\t\t\tphandle = < 0x06 >;\n\t\t};\n\n\t\tcpu@101 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,armv8\";\n\t\t\treg = < 0x00 0x101 >;\n\t\t\tenable-method = \"psci\";\n\t\t\tcpu-idle-states = < 0x0a 0x0b >;\n\t\t\tnext-level-cache = < 0x0c >;\n\t\t\tlinux,phandle = < 0x07 >;\n\t\t\tphandle = < 0x07 >;\n\t\t};\n\n\t\tcpu@102 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,armv8\";\n\t\t\treg = < 0x00 0x102 >;\n\t\t\tenable-method = \"psci\";\n\t\t\tcpu-idle-states = < 0x0a 0x0b >;\n\t\t\tnext-level-cache = < 0x0c >;\n\t\t\tlinux,phandle = < 0x08 >;\n\t\t\tphandle = < 0x08 >;\n\t\t};\n\n\t\tcpu@103 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,armv8\";\n\t\t\treg = < 0x00 0x103 >;\n\t\t\tenable-method = \"psci\";\n\t\t\tcpu-idle-states = < 0x0a 0x0b >;\n\t\t\tnext-level-cache = < 0x0c >;\n\t\t\tlinux,phandle = < 0x09 >;\n\t\t\tphandle = < 0x09 >;\n\t\t};\n\n\t\tl2-cache0 {\n\t\t\tcompatible = \"cache\";\n\t\t\tlinux,phandle = < 0x0c >;\n\t\t\tphandle = < 0x0c >;\n\t\t};\n\t};\n\n\tmemory@80000000 {\n\t\tdevice_type = \"memory\";\n\t\treg = <0x0 0x80000000 0x0 0x80000000 0x8 0x80000000 0x0 0x80000000>;\n\t};\n\n\tinterrupt-controller@2f000000 {\n\t\tcompatible = \"arm,gic-v3\";\n\t\t#interrupt-cells = < 0x03 >;\n\t\t#address-cells = < 0x02 >;\n\t\t#size-cells = < 0x02 >;\n\t\tranges;\n\t\tinterrupt-controller;\n\t\treg = < 0x00 0x2f000000 0x00 0x10000 0x00 0x2f100000 0x00 0x200000 0x00 0x2c000000 0x00 0x2000 0x00 0x2c010000 0x00 0x2000 0x00 0x2c02f000 0x00 0x2000 >;\n\t\tinterrupts = < 0x01 0x09 0x04 >;\n\t\tlinux,phandle = < 0x01 >;\n\t\tphandle = < 0x01 >;\n\n\t\tits@2f020000 {\n\t\t\tcompatible = \"arm,gic-v3-its\";\n\t\t\tmsi-controller;\n\t\t\treg = < 0x00 0x2f020000 0x00 0x20000 >;\n\t\t};\n\t};\n\n\ttimer {\n\t\tcompatible = \"arm,armv8-timer\";\n\t\tinterrupts = < 0x01 0x0d 0xff01 0x01 0x0e 0xff01 0x01 0x0b 0xff01 0x01 0x0a 0xff01 >;\n\t\tclock-frequency = < 0x5f5e100 >;\n\t};\n\n\ttimer@2a810000 {\n\t\tcompatible = \"arm,armv7-timer-mem\";\n\t\treg = < 0x00 0x2a810000 0x00 0x10000 >;\n\t\tclock-frequency = < 0x5f5e100 >;\n\t\t#address-cells = < 0x02 >;\n\t\t#size-cells = < 0x02 >;\n\t\tranges;\n\n\t\tframe@2a830000 {\n\t\t\tframe-number = < 0x01 >;\n\t\t\tinterrupts = < 0x00 0x1a 0x04 >;\n\t\t\treg = < 0x00 0x2a830000 0x00 0x10000 >;\n\t\t};\n\t};\n\n\tpmu {\n\t\tcompatible = \"arm,armv8-pmuv3\";\n\t\tinterrupts = < 0x00 0x3c 0x04 0x00 0x3d 0x04 0x00 0x3e 0x04 0x00 0x3f 0x04 >;\n\t};\n\n\tsmb@0,0 {\n\t\tcompatible = \"simple-bus\";\n\t\t#address-cells = < 0x02 >;\n\t\t#size-cells = < 0x01 >;\n\t\tranges = < 0x00 0x00 0x00 0x8000000 0x4000000 0x01 0x00 0x00 0x14000000 0x4000000 0x02 0x00 0x00 0x18000000 0x4000000 0x03 0x00 0x00 0x1c000000 0x4000000 0x04 0x00 0x00 0xc000000 0x4000000 0x05 0x00 0x00 0x10000000 0x4000000 >;\n\n\t\tmotherboard {\n\t\t\tarm,v2m-memory-map = \"rs1\";\n\t\t\tcompatible = \"arm,vexpress,v2m-p1\\0simple-bus\";\n\t\t\t#address-cells = < 0x02 >;\n\t\t\t#size-cells = < 0x01 >;\n\t\t\tranges;\n\n\t\t\tflash@0,00000000 {\n\t\t\t\tcompatible = \"arm,vexpress-flash\\0cfi-flash\";\n\t\t\t\treg = < 0x00 0x00 0x4000000 0x04 0x00 0x4000000 >;\n\t\t\t\tbank-width = < 0x04 >;\n\t\t\t};\n\n\t\t\tvram@2,00000000 {\n\t\t\t\tcompatible = \"arm,vexpress-vram\";\n\t\t\t\treg = < 0x02 0x00 0x800000 >;\n\t\t\t};\n\n\t\t\tethernet@2,02000000 {\n\t\t\t\tcompatible = \"smsc,lan91c111\";\n\t\t\t\treg = < 0x02 0x2000000 0x10000 >;\n\t\t\t\tinterrupts = < 0x00 0x0f 0x04 >;\n\t\t\t};\n\n\t\t\tclk24mhz {\n\t\t\t\tcompatible = \"fixed-clock\";\n\t\t\t\t#clock-cells = < 0x00 >;\n\t\t\t\tclock-frequency = < 0x16e3600 >;\n\t\t\t\tclock-output-names = \"v2m:clk24mhz\";\n\t\t\t\tlinux,phandle = < 0x0f >;\n\t\t\t\tphandle = < 0x0f >;\n\t\t\t};\n\n\t\t\trefclk1mhz {\n\t\t\t\tcompatible = \"fixed-clock\";\n\t\t\t\t#clock-cells = < 0x00 >;\n\t\t\t\tclock-frequency = < 0xf4240 >;\n\t\t\t\tclock-output-names = \"v2m:refclk1mhz\";\n\t\t\t\tlinux,phandle = < 0x0e >;\n\t\t\t\tphandle = < 0x0e >;\n\t\t\t};\n\n\t\t\trefclk32khz {\n\t\t\t\tcompatible = \"fixed-clock\";\n\t\t\t\t#clock-cells = < 0x00 >;\n\t\t\t\tclock-frequency = < 0x8000 >;\n\t\t\t\tclock-output-names = \"v2m:refclk32khz\";\n\t\t\t\tlinux,phandle = < 0x0d >;\n\t\t\t\tphandle = < 0x0d >;\n\t\t\t};\n\n\t\t\tiofpga@3,00000000 {\n\t\t\t\tcompatible = \"arm,amba-bus\\0simple-bus\";\n\t\t\t\t#address-cells = < 0x01 >;\n\t\t\t\t#size-cells = < 0x01 >;\n\t\t\t\tranges = < 0x00 0x03 0x00 0x200000 >;\n\n\t\t\t\tsysreg@10000 {\n\t\t\t\t\tcompatible = \"arm,vexpress-sysreg\";\n\t\t\t\t\treg = < 0x10000 0x1000 >;\n\t\t\t\t\tgpio-controller;\n\t\t\t\t\t#gpio-cells = < 0x02 >;\n\t\t\t\t\tlinux,phandle = < 0x10 >;\n\t\t\t\t\tphandle = < 0x10 >;\n\t\t\t\t};\n\n\t\t\t\tsysctl@20000 {\n\t\t\t\t\tcompatible = \"arm,sp810\\0arm,primecell\";\n\t\t\t\t\treg = < 0x20000 0x1000 >;\n\t\t\t\t\tclocks = < 0x0d 0x0e 0x0f >;\n\t\t\t\t\tclock-names = \"refclk\\0timclk\\0apb_pclk\";\n\t\t\t\t\t#clock-cells = < 0x01 >;\n\t\t\t\t\tclock-output-names = \"timerclken0\\0timerclken1\\0timerclken2\\0timerclken3\";\n\t\t\t\t\tlinux,phandle = < 0x12 >;\n\t\t\t\t\tphandle = < 0x12 >;\n\t\t\t\t};\n\n\t\t\t\taaci@40000 {\n\t\t\t\t\tcompatible = \"arm,pl041\\0arm,primecell\";\n\t\t\t\t\treg = < 0x40000 0x1000 >;\n\t\t\t\t\tinterrupts = < 0x00 0x0b 0x04 >;\n\t\t\t\t\tclocks = < 0x0f >;\n\t\t\t\t\tclock-names = \"apb_pclk\";\n\t\t\t\t};\n\n\t\t\t\tmmci@50000 {\n\t\t\t\t\tcompatible = \"arm,pl180\\0arm,primecell\";\n\t\t\t\t\treg = < 0x50000 0x1000 >;\n\t\t\t\t\tinterrupts = < 0x00 0x09 0x04 0x00 0x0a 0x04 >;\n\t\t\t\t\tcd-gpios = < 0x10 0x00 0x00 >;\n\t\t\t\t\twp-gpios = < 0x10 0x01 0x00 >;\n\t\t\t\t\tmax-frequency = < 0xb71b00 >;\n\t\t\t\t\tvmmc-supply = < 0x11 >;\n\t\t\t\t\tclocks = < 0x0f 0x0f >;\n\t\t\t\t\tclock-names = \"mclk\\0apb_pclk\";\n\t\t\t\t};\n\n\t\t\t\tkmi@60000 {\n\t\t\t\t\tcompatible = \"arm,pl050\\0arm,primecell\";\n\t\t\t\t\treg = < 0x60000 0x1000 >;\n\t\t\t\t\tinterrupts = < 0x00 0x0c 0x04 >;\n\t\t\t\t\tclocks = < 0x0f 0x0f >;\n\t\t\t\t\tclock-names = \"KMIREFCLK\\0apb_pclk\";\n\t\t\t\t};\n\n\t\t\t\tkmi@70000 {\n\t\t\t\t\tcompatible = \"arm,pl050\\0arm,primecell\";\n\t\t\t\t\treg = < 0x70000 0x1000 >;\n\t\t\t\t\tinterrupts = < 0x00 0x0d 0x04 >;\n\t\t\t\t\tclocks = < 0x0f 0x0f >;\n\t\t\t\t\tclock-names = \"KMIREFCLK\\0apb_pclk\";\n\t\t\t\t};\n\n\t\t\t\tuart@90000 {\n\t\t\t\t\tcompatible = \"arm,pl011\\0arm,primecell\";\n\t\t\t\t\treg = < 0x90000 0x1000 >;\n\t\t\t\t\tinterrupts = < 0x00 0x05 0x04 >;\n\t\t\t\t\tclocks = < 0x0f 0x0f >;\n\t\t\t\t\tclock-names = \"uartclk\\0apb_pclk\";\n\t\t\t\t};\n\n\t\t\t\tuart@a0000 {\n\t\t\t\t\tcompatible = \"arm,pl011\\0arm,primecell\";\n\t\t\t\t\treg = < 0xa0000 0x1000 >;\n\t\t\t\t\tinterrupts = < 0x00 0x06 0x04 >;\n\t\t\t\t\tclocks = < 0x0f 0x0f >;\n\t\t\t\t\tclock-names = \"uartclk\\0apb_pclk\";\n\t\t\t\t};\n\n\t\t\t\tuart@b0000 {\n\t\t\t\t\tcompatible = \"arm,pl011\\0arm,primecell\";\n\t\t\t\t\treg = < 0xb0000 0x1000 >;\n\t\t\t\t\tinterrupts = < 0x00 0x07 0x04 >;\n\t\t\t\t\tclocks = < 0x0f 0x0f >;\n\t\t\t\t\tclock-names = \"uartclk\\0apb_pclk\";\n\t\t\t\t};\n\n\t\t\t\tuart@c0000 {\n\t\t\t\t\tcompatible = \"arm,pl011\\0arm,primecell\";\n\t\t\t\t\treg = < 0xc0000 0x1000 >;\n\t\t\t\t\tinterrupts = < 0x00 0x08 0x04 >;\n\t\t\t\t\tclocks = < 0x0f 0x0f >;\n\t\t\t\t\tclock-names = \"uartclk\\0apb_pclk\";\n\t\t\t\t};\n\n\t\t\t\twdt@f0000 {\n\t\t\t\t\tcompatible = \"arm,sp805\\0arm,primecell\";\n\t\t\t\t\treg = < 0xf0000 0x1000 >;\n\t\t\t\t\tinterrupts = < 0x00 0x00 0x04 >;\n\t\t\t\t\tclocks = < 0x0d 0x0f >;\n\t\t\t\t\tclock-names = \"wdogclk\\0apb_pclk\";\n\t\t\t\t};\n\n\t\t\t\ttimer@110000 {\n\t\t\t\t\tcompatible = \"arm,sp804\\0arm,primecell\";\n\t\t\t\t\treg = < 0x110000 0x1000 >;\n\t\t\t\t\tinterrupts = < 0x00 0x02 0x04 >;\n\t\t\t\t\tclocks = < 0x12 0x00 0x12 0x01 0x0f >;\n\t\t\t\t\tclock-names = \"timclken1\\0timclken2\\0apb_pclk\";\n\t\t\t\t};\n\n\t\t\t\ttimer@120000 {\n\t\t\t\t\tcompatible = \"arm,sp804\\0arm,primecell\";\n\t\t\t\t\treg = < 0x120000 0x1000 >;\n\t\t\t\t\tinterrupts = < 0x00 0x03 0x04 >;\n\t\t\t\t\tclocks = < 0x12 0x02 0x12 0x03 0x0f >;\n\t\t\t\t\tclock-names = \"timclken1\\0timclken2\\0apb_pclk\";\n\t\t\t\t};\n\n\t\t\t\trtc@170000 {\n\t\t\t\t\tcompatible = \"arm,pl031\\0arm,primecell\";\n\t\t\t\t\treg = < 0x170000 0x1000 >;\n\t\t\t\t\tinterrupts = < 0x00 0x04 0x04 >;\n\t\t\t\t\tclocks = < 0x0f >;\n\t\t\t\t\tclock-names = \"apb_pclk\";\n\t\t\t\t};\n\n\t\t\t\tclcd@1f0000 {\n\t\t\t\t\tcompatible = \"arm,pl111\\0arm,primecell\";\n\t\t\t\t\treg = < 0x1f0000 0x1000 >;\n\t\t\t\t\tinterrupts = < 0x00 0x0e 0x04 >;\n\t\t\t\t\tclocks = < 0x13 0x0f >;\n\t\t\t\t\tclock-names = \"clcdclk\\0apb_pclk\";\n\t\t\t\t\tmode = \"XVGA\";\n\t\t\t\t\tuse_dma = < 0x00 >;\n\t\t\t\t\tframebuffer = < 0x18000000 0x180000 >;\n\t\t\t\t};\n\n\t\t\t\tvirtio_block@130000 {\n\t\t\t\t\tcompatible = \"virtio,mmio\";\n\t\t\t\t\treg = < 0x130000 0x1000 >;\n\t\t\t\t\tinterrupts = < 0x00 0x2a 0x04 >;\n\t\t\t\t};\n\t\t\t};\n\n\t\t\tfixedregulator {\n\t\t\t\tcompatible = \"regulator-fixed\";\n\t\t\t\tregulator-name = \"3V3\";\n\t\t\t\tregulator-min-microvolt = < 0x325aa0 >;\n\t\t\t\tregulator-max-microvolt = < 0x325aa0 >;\n\t\t\t\tregulator-always-on;\n\t\t\t\tlinux,phandle = < 0x11 >;\n\t\t\t\tphandle = < 0x11 >;\n\t\t\t};\n\n\t\t\tmcc {\n\t\t\t\tcompatible = \"arm,vexpress,config-bus\\0simple-bus\";\n\t\t\t\tarm,vexpress,config-bridge = < 0x10 >;\n\n\t\t\t\tosc {\n\t\t\t\t\tcompatible = \"arm,vexpress-osc\";\n\t\t\t\t\tarm,vexpress-sysreg,func = < 0x01 0x01 >;\n\t\t\t\t\tfreq-range = < 0x16a6570 0x3c8eee0 >;\n\t\t\t\t\t#clock-cells = < 0x00 >;\n\t\t\t\t\tclock-output-names = \"v2m:oscclk1\";\n\t\t\t\t\tlinux,phandle = < 0x13 >;\n\t\t\t\t\tphandle = < 0x13 >;\n\t\t\t\t};\n\n\t\t\t\tmuxfpga {\n\t\t\t\t\tcompatible = \"arm,vexpress-muxfpga\";\n\t\t\t\t\tarm,vexpress-sysreg,func = < 0x07 0x00 >;\n\t\t\t\t};\n\n\t\t\t\tdvimode {\n\t\t\t\t\tcompatible = \"arm,vexpress-dvimode\";\n\t\t\t\t\tarm,vexpress-sysreg,func = < 0x0b 0x00 >;\n\t\t\t\t};\n\t\t\t};\n\t\t};\n\t};\n\n\tpanels {\n\n\t\tpanel {\n\t\t\tcompatible = \"panel\";\n\t\t\tmode = \"XVGA\";\n\t\t\trefresh = < 0x3c >;\n\t\t\txres = < 0x400 >;\n\t\t\tyres = < 0x300 >;\n\t\t\tpixclock = < 0x3d84 >;\n\t\t\tleft_margin = < 0x98 >;\n\t\t\tright_margin = < 0x30 >;\n\t\t\tupper_margin = < 0x17 >;\n\t\t\tlower_margin = < 0x03 >;\n\t\t\thsync_len = < 0x68 >;\n\t\t\tvsync_len = < 0x04 >;\n\t\t\tsync = < 0x00 >;\n\t\t\tvmode = \"FB_VMODE_NONINTERLACED\";\n\t\t\ttim2 = \"TIM2_BCD\\0TIM2_IPC\";\n\t\t\tcntl = \"CNTL_LCDTFT\\0CNTL_BGR\\0CNTL_LCDVCOMP(1)\";\n\t\t\tcaps = \"CLCD_CAP_5551\\0CLCD_CAP_565\\0CLCD_CAP_888\";\n\t\t\tbpp = < 0x10 >;\n\t\t};\n\t};\n};\n"
  },
  {
    "path": "kernel/dtbs/foundation-v8-gicv3.dts",
    "content": "/dts-v1/;\n\n/ {\n\tmodel = \"FVP Base\";\n\tcompatible = \"arm,fvp-base\", \"arm,vexpress\";\n\tinterrupt-parent = <0x1>;\n\t#address-cells = <0x2>;\n\t#size-cells = <0x2>;\n\n\tchosen {\n\t\tminos,stdout = \"pl011\";\n\t\tbootargs = \"bootwait=3 tty=vm1\";\n\t\tminos,ramdisk-start = <0x0 0xc4000000>;\n\t\tminos,ramdisk-end = <0x0 0xC522F000>;\n\t};\n\n\taliases {\n\t\tserial0 = \"/smb@0,0/motherboard/iofpga@3,00000000/uart@90000\";\n\t};\n\n\tvms {\n\t\tvm1 {\n\t\t\tdevice_type = \"virtual_machine\";\n\t\t\tvm_name = \"fvp_linux_host\";\n\t\t\thost_vm;\n\t\t\tvmid = <1>;\n\t\t\ttype = \"linux\";\n\t\t\tvcpus = <2>;\n\t\t\tentry = <0x0 0x80080000>;\n\t\t\tsetup_data = <0x0 0x83e00000>;\n\t\t\tvcpu_affinity = <0 1 2 3>;\n\t\t\tcmdline = \"console=hvc0 earlycon=dbcon,io,0x0 loglevel=8 consolelog=9 root=/dev/vda2 rw\";\n\t\t\tmemory = <0x0 0x80000000 0x0 0x10000000>;\n\n\t\t\tvm1_bdi {\n\t\t\t\tvm_console_vm1 {\n\t\t\t\t\tvirtual_device;\n\t\t\t\t\tvc-dynamic-res;\n\t\t\t\t\tcompatible = \"minos,vm_console\";\n\t\t\t\t};\n\t\t\t};\n\t\t};\n\t};\n\n\tpsci {\n\t\tcompatible = \"arm,psci-1.0\", \"arm,psci-0.2\", \"arm,psci\";\n\t\tmethod = \"smc\";\n\t\tcpu_suspend = <0xc4000001>;\n\t\tcpu_off = <0x84000002>;\n\t\tcpu_on = <0xc4000003>;\n\t\tsys_poweroff = <0x84000008>;\n\t\tsys_reset = <0x84000009>;\n\t};\n\n\tcpus {\n\t\t#address-cells = <0x2>;\n\t\t#size-cells = <0x0>;\n\n\t\tcpu-map {\n\n\t\t\tcluster0 {\n\n\t\t\t\tcore0 {\n\t\t\t\t\tcpu = <0x2>;\n\t\t\t\t};\n\n\t\t\t\tcore1 {\n\t\t\t\t\tcpu = <0x3>;\n\t\t\t\t};\n\n\t\t\t\tcore2 {\n\t\t\t\t\tcpu = <0x4>;\n\t\t\t\t};\n\n\t\t\t\tcore3 {\n\t\t\t\t\tcpu = <0x5>;\n\t\t\t\t};\n\t\t\t};\n\t\t};\n\n\t\tidle-states {\n\t\t\tentry-method = \"arm,psci\";\n\n\t\t\tcpu-sleep-0 {\n\t\t\t\tcompatible = \"arm,idle-state\";\n\t\t\t\tlocal-timer-stop;\n\t\t\t\tarm,psci-suspend-param = <0x10000>;\n\t\t\t\tentry-latency-us = <0x28>;\n\t\t\t\texit-latency-us = <0x64>;\n\t\t\t\tmin-residency-us = <0x96>;\n\t\t\t\tlinux,phandle = <0xa>;\n\t\t\t\tphandle = <0xa>;\n\t\t\t};\n\n\t\t\tcluster-sleep-0 {\n\t\t\t\tcompatible = \"arm,idle-state\";\n\t\t\t\tlocal-timer-stop;\n\t\t\t\tarm,psci-suspend-param = <0x1010000>;\n\t\t\t\tentry-latency-us = <0x1f4>;\n\t\t\t\texit-latency-us = <0x3e8>;\n\t\t\t\tmin-residency-us = <0x9c4>;\n\t\t\t\tlinux,phandle = <0xb>;\n\t\t\t\tphandle = <0xb>;\n\t\t\t};\n\t\t};\n\n\t\tcpu@0 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,armv8\";\n\t\t\treg = <0x0 0x0>;\n\t\t\tenable-method = \"psci\";\n\t\t\tcpu-idle-states = <0xa 0xb>;\n\t\t\tnext-level-cache = <0xc>;\n\t\t\tlinux,phandle = <0x2>;\n\t\t\tphandle = <0x2>;\n\t\t};\n\n\t\tcpu@1 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,armv8\";\n\t\t\treg = <0x0 0x1>;\n\t\t\tenable-method = \"psci\";\n\t\t\tcpu-idle-states = <0xa 0xb>;\n\t\t\tnext-level-cache = <0xc>;\n\t\t\tlinux,phandle = <0x3>;\n\t\t\tphandle = <0x3>;\n\t\t};\n\n\t\tcpu@2 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,armv8\";\n\t\t\treg = <0x0 0x2>;\n\t\t\tenable-method = \"psci\";\n\t\t\tcpu-idle-states = <0xa 0xb>;\n\t\t\tnext-level-cache = <0xc>;\n\t\t\tlinux,phandle = <0x4>;\n\t\t\tphandle = <0x4>;\n\t\t};\n\n\t\tcpu@3 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,armv8\";\n\t\t\treg = <0x0 0x3>;\n\t\t\tenable-method = \"psci\";\n\t\t\tcpu-idle-states = <0xa 0xb>;\n\t\t\tnext-level-cache = <0xc>;\n\t\t\tlinux,phandle = <0x5>;\n\t\t\tphandle = <0x5>;\n\t\t};\n\n\t\tl2-cache0 {\n\t\t\tcompatible = \"cache\";\n\t\t\tlinux,phandle = <0xc>;\n\t\t\tphandle = <0xc>;\n\t\t};\n\t};\n\n\tmemory@80000000 {\n\t\tdevice_type = \"memory\";\n\t\treg = <0x0 0x80000000 0x0 0x80000000 0x8 0x80000000 0x0 0x80000000>;\n\t};\n\n\tinterrupt-controller@2f000000 {\n\t\tcompatible = \"arm,gic-v3\";\n\t\t#interrupt-cells = <0x3>;\n\t\t#address-cells = <0x2>;\n\t\t#size-cells = <0x2>;\n\t\tranges;\n\t\tinterrupt-controller;\n\t\treg = <0x0 0x2f000000 0x0 0x10000 0x0 0x2f100000 0x0 0x200000 0x0 0x2c000000 0x0 0x2000 0x0 0x2c010000 0x0 0x2000 0x0 0x2c02f000 0x0 0x2000>;\n\t\tinterrupts = <0x1 0x9 0x4>;\n\t\tlinux,phandle = <0x1>;\n\t\tphandle = <0x1>;\n\n\t\tits@2f020000 {\n\t\t\tcompatible = \"arm,gic-v3-its\";\n\t\t\tmsi-controller;\n\t\t\treg = <0x0 0x2f020000 0x0 0x20000>;\n\t\t};\n\t};\n\n\ttimer {\n\t\tcompatible = \"arm,armv8-timer\";\n\t\tinterrupts = <0x1 0xd 0xff01 0x1 0xe 0xff01 0x1 0xb 0xff01 0x1 0xa 0xff01>;\n\t\tclock-frequency = <0x5f5e100>;\n\t};\n\n\tpmu {\n\t\tcompatible = \"arm,armv8-pmuv3\";\n\t\tinterrupts = <0x0 0x3c 0x4 0x0 0x3d 0x4 0x0 0x3e 0x4 0x0 0x3f 0x4>;\n\t};\n\n\tsmb@0,0 {\n\t\tcompatible = \"simple-bus\";\n\t\t#address-cells = <0x2>;\n\t\t#size-cells = <0x1>;\n\t\tranges = <0x0 0x0 0x0 0x8000000 0x4000000 0x1 0x0 0x0 0x14000000 0x4000000 0x2 0x0 0x0 0x18000000 0x4000000 0x3 0x0 0x0 0x1c000000 0x4000000 0x4 0x0 0x0 0xc000000 0x4000000 0x5 0x0 0x0 0x10000000 0x4000000>;\n\n\t\tmotherboard {\n\t\t\tarm,v2m-memory-map = \"rs1\";\n\t\t\tcompatible = \"arm,vexpress,v2m-p1\", \"simple-bus\";\n\t\t\t#address-cells = <0x2>;\n\t\t\t#size-cells = <0x1>;\n\t\t\tranges;\n\n\t\t\tclk24mhz {\n\t\t\t\tcompatible = \"fixed-clock\";\n\t\t\t\t#clock-cells = <0x0>;\n\t\t\t\tclock-frequency = <0x16e3600>;\n\t\t\t\tclock-output-names = \"v2m:clk24mhz\";\n\t\t\t\tlinux,phandle = <0xf>;\n\t\t\t\tphandle = <0xf>;\n\t\t\t};\n\n\t\t\trefclk1mhz {\n\t\t\t\tcompatible = \"fixed-clock\";\n\t\t\t\t#clock-cells = <0x0>;\n\t\t\t\tclock-frequency = <0xf4240>;\n\t\t\t\tclock-output-names = \"v2m:refclk1mhz\";\n\t\t\t\tlinux,phandle = <0xe>;\n\t\t\t\tphandle = <0xe>;\n\t\t\t};\n\n\t\t\trefclk32khz {\n\t\t\t\tcompatible = \"fixed-clock\";\n\t\t\t\t#clock-cells = <0x0>;\n\t\t\t\tclock-frequency = <0x8000>;\n\t\t\t\tclock-output-names = \"v2m:refclk32khz\";\n\t\t\t\tlinux,phandle = <0xd>;\n\t\t\t\tphandle = <0xd>;\n\t\t\t};\n\n\t\t};\n\t};\n};\n"
  },
  {
    "path": "kernel/dtbs/kvim3.dts",
    "content": "/dts-v1/;\n\n/ {\n\tinterrupt-parent = < 0x01 >;\n\t#address-cells = < 0x02 >;\n\t#size-cells = < 0x02 >;\n\tcompatible = \"khadas,vim3\";\n\tmodel = \"Khadas VIM3\";\n\n\tchosen {\n\t\tminos,stdout = \"aml_meson\";\n\t\tbootargs = \"bootwait=3 tty=vm0\";\n\t};\n\n\tpsci {\n\t\tcompatible = \"arm,psci-1.0\";\n\t\tmethod = \"smc\";\n\t};\n\n\tsoc {\n\t\tcompatible = \"simple-bus\";\n\t\t#address-cells = < 0x02 >;\n\t\t#size-cells = < 0x02 >;\n\t\tranges;\n\n\t\tinterrupt-controller@ffc01000 {\n\t\t\tcompatible = \"arm,gic-400\";\n\t\t\treg = < 0x00 0xffc01000 0x00 0x1000 0x00 0xffc02000 0x00 0x2000 0x00 0xffc04000 0x00 0x2000 0x00 0xffc06000 0x00 0x2000 >;\n\t\t\tinterrupt-controller;\n\t\t\tinterrupts = < 0x01 0x09 0xff04 >;\n\t\t\t#interrupt-cells = < 0x03 >;\n\t\t\t#address-cells = < 0x00 >;\n\t\t\tphandle = < 0x01 >;\n\t\t};\n\t};\n\n\tvms {\n\t\tvm0 {\n\t\t\tdevice_type = \"virtual_machine\";\n\t\t\tvmid = <0>;\n\t\t\tvm_name = \"android\";\n\t\t\ttype = \"linux\";\n\t\t\tvm_32bit;\n\t\t\tnative_wfi;\n\t\t\tno_of_resource;\n\t\t\tvcpus = <4>;\n\t\t\tentry = <0x0 0x00108000>;\n\t\t\tsetup_data = <0x0 0x1ffe6000>;\n\t\t\tvcpu_affinity = <0 1 2 3>;\n\t\t\tmemory = <0x0 0x00000000 0x0 0x80000000>;\n\t\t\tcmdline = \"init=/init console=hvc0 no_console_suspend earlycon=earlycon=dbcon,io,0x0 ramoops.pstore_en=1 ramoops.record_size=0x8000 ramoops.console_size=0x4000 otg_device=1 reboot_mode_android=normal logo=viu2_osd0,loaded,0x3d800000 fb_width=1920 fb_height=1080 vout2=panel,enable vout=1080p60hz,enable panel_type=lcd_1 lcd_ctrl=0x00000083 hdmitx=,444,8bit hdmimode=1080p60hz frac_rate_policy=1 hdmi_read_edid=1 cvbsmode=576cvbs osd_reverse=0 video_reverse=0 irq_check_en=0 androidboot.selinux=permissive androidboot.firstboot=0 jtag=disable wol_enable=0 spi_state=0 fusb302_state=1 hwver=VIM3.V12 factory_mac=c8:63:14:70:47:ac lcd_exist=1 androidboot.hardware=amlogic androidboot.serialno=c863147047ac mac=c8:63:14:70:47:ac androidboot.mac=c8:63:14:70:47:ac ro rootwait skip_initramfs androidboot.dtbo_idx=0 --cmdline root=/dev/mmcblk0p18 buildvariant=userdebug\";\n\n\t\t\tvm0_bdi {\n\t\t\t\t#address-cells = <0x1>;\n\t\t\t\t#size-cells = <0x1>;\n\n\t\t\t\tvtimer_irq = <27>;\n\n\t\t\t\tiomem = <0x0 0xff600000 0x0 0xff600000 0x0 0x45000>, /* 0xff620000 ----> 0xff645000 */\n\t\t\t\t\t<0x0 0xff650000 0x0 0xff650000 0x0 0x8000>, /* 0xff650000 ----> 0xff658000 */\n\t\t\t\t\t<0x0 0xff646000 0x0 0xff646000 0x0 0x7000>, /* 0xff646000 ----> 0xff64d000 */\n\t\t\t\t\t<0x0 0xff900000 0x0 0xff900000 0x0 0x51000>, /* 0xff900000 ----> 0xff951000 */\n\t\t\t\t\t<0x0 0xff800000 0x0 0xff800000 0x0 0x10000>, /* 0xff800000 ----> 0xff810000 */\n\t\t\t\t\t<0x0 0xffd00000 0x0 0xffd00000 0x0 0x100000>, /* 0xffd00000 ----> 0xffe00000 */\n\t\t\t\t\t<0x0 0xff000000 0x0 0xff000000 0x0 0x440000>, /* 0xff000000 ----> 0xff440000 */\n\t\t\t\t\t<0x0 0xfc000000 0x0 0xfc000000 0x0 0x600000>, /* 0xfc000000 ----> 0xfc600000 */\n\t\t\t\t\t<0x0 0xff500000 0x0 0xff500000 0x0 0x100000>, /* 0xff500000 ----> 0xff600000 */\n\t\t\t\t\t<0x0 0xffe01000 0x0 0xffe01000 0x0 0x7f000>, /* 0xffe01000 ----> 0xffe80000 */\n\t\t\t\t\t<0x0 0xfffe7000 0x0 0xfffe7000 0x0 0x1000>; /* 0xfffe7000 ----> 0xfffe8000 */\n\n\t\t\t\tvirqs = <0x21 0x21>, /* 33 locker */\n\t\t\t\t\t<0x48 0x48>, /* 72 deinterlace */\n\t\t\t\t\t<0x4e 0x4e>, /* 78 deinterlace */\n\t\t\t\t\t<0x78 0x78>, /* 120 phy-csi@ff650000 */\n\t\t\t\t\t<0x77 0x77>, /* 119 phy-csi@ff650000 */\n\t\t\t\t\t<0x6a 0x6a>, /* 106 phy-csi@ff650000 */\n\t\t\t\t\t<0x68 0x68>, /* 104 phy-csi@ff650000 */\n\t\t\t\t\t<0x4a 0x4a>, /* 74 phy-csi@ff650000 */\n\t\t\t\t\t<0x49 0x49>, /* 73 phy-csi@ff650000 */\n\t\t\t\t\t<0xd3 0xd3>, /* 211 isp-adapter@ff650000 */\n\t\t\t\t\t<0xae 0xae>, /* 174 isp@ff140000 */\n\t\t\t\t\t<0x31 0x31>, /* 49 isp-sc@ff655400 */\n\t\t\t\t\t<0x53 0x53>, /* 83 dmc_monitor */\n\t\t\t\t\t<0x54 0x54>, /* 84 ddr_bandwidth */\n\t\t\t\t\t<0x42 0x42>, /* 66 nfc@0 */\n\t\t\t\t\t<0xdd 0xdd>, /* 221 sdio@ffe03000 */\n\t\t\t\t\t<0xde 0xde>, /* 222 sd@ffe05000 */\n\t\t\t\t\t<0xdf 0xdf>, /* 223 emmc@ffe07000 */\n\t\t\t\t\t<0xe6 0xe6>, /* 230 meson-irblaster */\n\t\t\t\t\t<0x58 0x58>, /* 88 meson-fb */\n\t\t\t\t\t<0x79 0x79>, /* 121 rdma */\n\t\t\t\t\t<0xdb 0xdb>, /* 219 hevc_enc */\n\t\t\t\t\t<0x4d 0x4d>, /* 77 vdec */\n\t\t\t\t\t<0x4c 0x4c>, /* 76 vdec */\n\t\t\t\t\t<0x4b 0x4b>, /* 75 vdec */\n\t\t\t\t\t<0x40 0x40>, /* 64 vdec */\n\t\t\t\t\t<0x37 0x37>, /* 55 vdec */\n\t\t\t\t\t<0xb0 0xb0>, /* 176 gdc */\n\t\t\t\t\t<0x23 0x23>, /* 35 meson-amvideom */\n\t\t\t\t\t<0xb2 0xb2>, /* 178 ge2d */\n\t\t\t\t\t<0x75 0x75>, /* 117 vdin1 */\n\t\t\t\t\t<0x73 0x73>, /* 115 vdin0 */\n\t\t\t\t\t<0xe7 0xe7>, /* 231 aocec */\n\t\t\t\t\t<0xeb 0xeb>, /* 235 aocec */\n\t\t\t\t\t<0xb3 0xb3>, /* 179 galcore */\n\t\t\t\t\t<0x59 0x59>, /* 89 amhdmitx */\n\t\t\t\t\t<0xfd 0xfd>, /* 253 pcieA@fc000000 */\n\t\t\t\t\t<0x7d 0x7d>, /* 125 serial@ffd22000 */\n\t\t\t\t\t<0x6b 0x6b>, /* 107 serial@ffd23000 */\n\t\t\t\t\t<0x3a 0x3a>, /* 58 serial@ffd24000 */\n\t\t\t\t\t<0xe4 0xe4>, /* 228 rc@0xff808040 */\n\t\t\t\t\t<0xbb 0xbb>, /* 187 pwrdet */\n\t\t\t\t\t<0xb7 0xb7>, /* 183 spdif */\n\t\t\t\t\t<0xba 0xba>, /* 186 ddr_manager */\n\t\t\t\t\t<0xb9 0xb9>, /* 185 ddr_manager */\n\t\t\t\t\t<0xb8 0xb8>, /* 184 ddr_manager */\n\t\t\t\t\t<0xb6 0xb6>, /* 182 ddr_manager */\n\t\t\t\t\t<0xb5 0xb5>, /* 181 ddr_manager */\n\t\t\t\t\t<0xb4 0xb4>, /* 180 ddr_manager */\n\t\t\t\t\t<0xe5 0xe5>, /* 229 serial@4000 */\n\t\t\t\t\t<0xe1 0xe1>, /* 225 serial@3000 */\n\t\t\t\t\t<0xe2 0xe2>, /* 226 i2c_slave@6000 */\n\t\t\t\t\t<0xe9 0xe9>, /* 233 i2c@5000 */\n\t\t\t\t\t<0xe3 0xe3>, /* 227 i2c@5000 */\n\t\t\t\t\t<0x7a 0x7a>, /* 122 spi@15000 */\n\t\t\t\t\t<0x71 0x71>, /* 113 spi@13000 */\n\t\t\t\t\t<0x7f 0x7f>, /* 127 i2c@1c000 */\n\t\t\t\t\t<0x47 0x47>, /* 71 i2c@1c000 */\n\t\t\t\t\t<0x7e 0x7e>, /* 126 i2c@1d000 */\n\t\t\t\t\t<0xf7 0xf7>, /* 247 i2c@1d000 */\n\t\t\t\t\t<0x7c 0x7c>, /* 124 i2c@1e000 */\n\t\t\t\t\t<0xf6 0xf6>, /* 246 i2c@1e000 */\n\t\t\t\t\t<0x7b 0x7b>, /* 123 i2c@1f000 */\n\t\t\t\t\t<0x35 0x35>, /* 53 i2c@1f000 */\n\t\t\t\t\t<0x44 0x44>, /* 68 d_tsensor@ff800228 */\n\t\t\t\t\t<0x43 0x43>, /* 67 p_tsensor@ff634594 */\n\t\t\t\t\t<0xe8 0xe8>, /* 232 saradc */\n\t\t\t\t\t<0x3f 0x3f>, /* 63 dwc2_a@ff400000 */\n\t\t\t\t\t<0x30 0x30>, /* 48 usb3phy@ffe09080 */\n\t\t\t\t\t<0x3e 0x3e>, /* 62 dwc3@ff500000 */\n\t\t\t\t\t<0x28 0x28>, /* 40 ethernet@ff3f0000 */\n\t\t\t\t\t<0xf2 0xf2>, /* 242 mhu@c883c400 */\n\t\t\t\t\t<0xf1 0xf1>, /* 241 mhu@c883c400 */\n\t\t\t\t\t<0xcb 0xcb>, /* 203 arm_pmu */\n\t\t\t\t\t<0xa9 0xa9>, /* 169 arm_pmu */\n\t\t\t\t\t<0x5c 0x5c>, /* 92 timer_bc */\n\t\t\t\t\t<0xc2 0xc2>, /* 194 bifrost */\n\t\t\t\t\t<0xc1 0xc1>, /* 193 bifrost */\n\t\t\t\t\t<0xc0 0xc0>; /* 192 bifrost */\n\n\t\t\t\tvirq_chip_vm0 {\n\t\t\t\t\tcompatible = \"arm,gicv2\";\n\t\t\t\t\t#address-cells = <0x1>;\n\t\t\t\t\t#size-cells = <0x1>;\n\t\t\t\t\treg = <0xffc01000 0x1000>,\n\t\t\t\t\t\t<0xffc02000 0x2000>,\n\t\t\t\t\t\t<0xffc04000 0x2000>,\n\t\t\t\t\t\t<0xffc06000 0x2000>;\n\t\t\t\t};\n\n\t\t\t\tvm_console_vm0 {\n\t\t\t\t\tvirtual_device;\n\t\t\t\t\tvc-dynamic-res;\n\t\t\t\t\tcompatible = \"minos,vm_console\";\n\t\t\t\t};\n\t\t\t};\n\t\t};\n\n\t\tvm1 {\n\t\t\tdevice_type = \"virtual_machine\";\n\t\t\tvmid = <1>;\n\t\t\tvm_name = \"vim3_pro_vm1\";\n\t\t\ttype = \"linux\";\n\t\t\tnative_wfi;\n\t\t\tvcpus = <1>;\n\t\t\tentry = <0x0 0x80080000>;\n\t\t\tsetup_data = <0x0 0x83e00000>;\n\t\t\tvcpu_affinity = <4 0 0 0>;\n\t\t\tmemory = <0x0 0x80000000 0x0 0x8000000>;\n\t\t\tcmdline = \"console=hvc0 earlycon=earlycon=dbcon,io,0x0 loglevel=8 consolelog=9\";\n\n\t\t\tvm1_bdi {\n\t\t\t\tvm_console_vm1 {\n\t\t\t\t\tvirtual_device;\n\t\t\t\t\tvc-dynamic-res;\n\t\t\t\t\tcompatible = \"minos,vm_console\";\n\t\t\t\t};\n\t\t\t};\n\t\t};\n\n\t\tvm2 {\n\t\t\tdevice_type = \"virtual_machine\";\n\t\t\tvmid = <2>;\n\t\t\tvm_name = \"fvp_zephyr_vm2\";\n\t\t\ttype = \"zephyr\";\n\t\t\tvcpus = <1>;\n\t\t\tentry = <0x0 0x880003b8>;\n\t\t\tsetup_data = <0x0 0x0>;\n\t\t\tvcpu_affinity = <5>;\n\t\t\tnative_wfi;\n\t\t\tmemory = <0x0 0x88000000 0x0 0x00200000>;\n\n\t\t\tvm2_bdi {\n\t\t\t\t#address-cells = <0x1>;\n\t\t\t\t#size-cells = <0x1>;\n\n\t\t\t\tvtimer_irq = <27>;\n\n\t\t\t\tvirq_chip_vm2 {\n\t\t\t\t\tcompatible = \"arm,gicv2\";\n\t\t\t\t\t#address-cells = <0x1>;\n\t\t\t\t\t#size-cells = <0x1>;\n\t\t\t\t\treg = <0x2f000000 0x10000>,\n\t\t\t\t\t\t<0x2c000000 0x2000>,\n\t\t\t\t\t\t<0x2c010000 0x2000>,\n\t\t\t\t\t\t<0x2c02f000 0x2000>;\n\t\t\t\t};\n\n\t\t\t\tvmbox_controller@20000000 {\n\t\t\t\t\tcompatible = \"minos,vmbox-controller\";\n\t\t\t\t\treg = <0x20000000 0x1000>;\n\t\t\t\t\tinterrupts = <0 10 4>;\n\t\t\t\t};\n\n\t\t\t\tvm_console_vm2 {\n\t\t\t\t\tvirtual_device;\n\t\t\t\t\tcompatible = \"minos,vm_console\";\n\t\t\t\t\treg = <0x20001000 0x2000>;\n\t\t\t\t\tinterrupts = <0 0 4>;\n\t\t\t\t};\n\t\t\t};\n\t\t};\n\t};\n\n\n\ttimer {\n\t\tcompatible = \"arm,armv8-timer\";\n\t\tinterrupts = < 0x01 0x0d 0xff08 0x01 0x0e 0xff08 0x01 0x0b 0xff08 0x01 0x0a 0xff08 >;\n\t\tarm,no-tick-in-suspend;\n\t};\n\n\tcpus {\n\t\t#address-cells = < 0x02 >;\n\t\t#size-cells = < 0x00 >;\n\n\t\tcpu-map {\n\n\t\t\tcluster0 {\n\n\t\t\t\tcore0 {\n\t\t\t\t\tcpu = < 0x0a >;\n\t\t\t\t};\n\n\t\t\t\tcore1 {\n\t\t\t\t\tcpu = < 0x0b >;\n\t\t\t\t};\n\t\t\t};\n\n\t\t\tcluster1 {\n\n\t\t\t\tcore0 {\n\t\t\t\t\tcpu = < 0x0c >;\n\t\t\t\t};\n\n\t\t\t\tcore1 {\n\t\t\t\t\tcpu = < 0x0d >;\n\t\t\t\t};\n\n\t\t\t\tcore2 {\n\t\t\t\t\tcpu = < 0x0e >;\n\t\t\t\t};\n\n\t\t\t\tcore3 {\n\t\t\t\t\tcpu = < 0x0f >;\n\t\t\t\t};\n\t\t\t};\n\t\t};\n\n\t\tcpu@0 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,cortex-a53\";\n\t\t\treg = < 0x00 0x00 >;\n\t\t\tenable-method = \"psci\";\n\t\t\tcapacity-dmips-mhz = < 0x250 >;\n\t\t\tnext-level-cache = < 0x46 >;\n\t\t\t#cooling-cells = < 0x02 >;\n\t\t\tcpu-supply = < 0x47 >;\n\t\t\toperating-points-v2 = < 0x48 >;\n\t\t\tclocks = < 0x02 0xbb >;\n\t\t\tclock-latency = < 0xc350 >;\n\t\t\tphandle = < 0x0a >;\n\t\t};\n\n\t\tcpu@1 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,cortex-a53\";\n\t\t\treg = < 0x00 0x01 >;\n\t\t\tenable-method = \"psci\";\n\t\t\tcapacity-dmips-mhz = < 0x250 >;\n\t\t\tnext-level-cache = < 0x46 >;\n\t\t\t#cooling-cells = < 0x02 >;\n\t\t\tcpu-supply = < 0x47 >;\n\t\t\toperating-points-v2 = < 0x48 >;\n\t\t\tclocks = < 0x02 0xbb >;\n\t\t\tclock-latency = < 0xc350 >;\n\t\t\tphandle = < 0x0b >;\n\t\t};\n\n\t\tcpu@100 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,cortex-a73\";\n\t\t\treg = < 0x00 0x100 >;\n\t\t\tenable-method = \"psci\";\n\t\t\tcapacity-dmips-mhz = < 0x400 >;\n\t\t\tnext-level-cache = < 0x46 >;\n\t\t\t#cooling-cells = < 0x02 >;\n\t\t\tcpu-supply = < 0x49 >;\n\t\t\toperating-points-v2 = < 0x4a >;\n\t\t\tclocks = < 0x02 0xe0 >;\n\t\t\tclock-latency = < 0xc350 >;\n\t\t\tphandle = < 0x0c >;\n\t\t};\n\n\t\tcpu@101 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,cortex-a73\";\n\t\t\treg = < 0x00 0x101 >;\n\t\t\tenable-method = \"psci\";\n\t\t\tcapacity-dmips-mhz = < 0x400 >;\n\t\t\tnext-level-cache = < 0x46 >;\n\t\t\t#cooling-cells = < 0x02 >;\n\t\t\tcpu-supply = < 0x49 >;\n\t\t\toperating-points-v2 = < 0x4a >;\n\t\t\tclocks = < 0x02 0xe0 >;\n\t\t\tclock-latency = < 0xc350 >;\n\t\t\tphandle = < 0x0d >;\n\t\t};\n\n\t\tcpu@102 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,cortex-a73\";\n\t\t\treg = < 0x00 0x102 >;\n\t\t\tenable-method = \"psci\";\n\t\t\tcapacity-dmips-mhz = < 0x400 >;\n\t\t\tnext-level-cache = < 0x46 >;\n\t\t\t#cooling-cells = < 0x02 >;\n\t\t\tcpu-supply = < 0x49 >;\n\t\t\toperating-points-v2 = < 0x4a >;\n\t\t\tclocks = < 0x02 0xe0 >;\n\t\t\tclock-latency = < 0xc350 >;\n\t\t\tphandle = < 0x0e >;\n\t\t};\n\n\t\tcpu@103 {\n\t\t\tdevice_type = \"cpu\";\n\t\t\tcompatible = \"arm,cortex-a73\";\n\t\t\treg = < 0x00 0x103 >;\n\t\t\tenable-method = \"psci\";\n\t\t\tcapacity-dmips-mhz = < 0x400 >;\n\t\t\tnext-level-cache = < 0x46 >;\n\t\t\t#cooling-cells = < 0x02 >;\n\t\t\tcpu-supply = < 0x49 >;\n\t\t\toperating-points-v2 = < 0x4a >;\n\t\t\tclocks = < 0x02 0xe0 >;\n\t\t\tclock-latency = < 0xc350 >;\n\t\t\tphandle = < 0x0f >;\n\t\t};\n\n\t\tl2-cache0 {\n\t\t\tcompatible = \"cache\";\n\t\t\tphandle = < 0x46 >;\n\t\t};\n\t};\n\n\tmemory@0 {\n\t\tdevice_type = \"memory\";\n\t\treg = < 0x00 0x00 0x00 0xed800000 >;\n\t};\n};\n"
  },
  {
    "path": "kernel/dtbs/qemu-arm64.dts",
    "content": "/dts-v1/;\n\n/ {\n\tinterrupt-parent = < 0x8001 >;\n\t#size-cells = < 0x02 >;\n\t#address-cells = < 0x02 >;\n\tcompatible = \"linux,qemu-arm64\";\n\n\tchosen {\n\t\tminos,stdout = \"pl011\";\n\t\tbootargs = \"bootwait=3 tty=vm1 rootfs=virtio-blk.drv\";\n\t\tminos,ramdisk-start = <0x0 0x44000000>;\n\t\tminos,ramdisk-end = <0x0 0x464ae000>;\n\t};\n\n\tpsci {\n\t\tmigrate = < 0xc4000005 >;\n\t\tcpu_on = < 0xc4000003 >;\n\t\tcpu_off = < 0x84000002 >;\n\t\tcpu_suspend = < 0xc4000001 >;\n\t\tmethod = \"smc\";\n\t\tcompatible = \"arm,psci-0.2\\0arm,psci\";\n\t};\n\n\tmemory@40000000 {\n\t\treg = < 0x00 0x40000000 0x01 0x00 >;\n\t\tdevice_type = \"memory\";\n\t};\n\n\tvms {\n\t\tvm1 {\n\t\t\tdevice_type = \"virtual_machine\";\n\t\t\tvm_name = \"fvp_linux_host\";\n\t\t\thost_vm;\n\t\t\tvmid = <1>;\n\t\t\ttype = \"linux\";\n\t\t\tkernel_image = \"Image\";\n\t\t\tdtb_image = \"qemu-virt.dtb\";\n\t\t\tvcpus = <1>;\n\t\t\tentry = <0x0 0x46680000>;\n\t\t\tsetup_data = <0x0 0x50000000>;\n\t\t\tvcpu_affinity = <0 1 2 3>;\n\t\t\tcmdline = \"console=hvc0 earlycon=dbcon,io,0x0 loglevel=8 consolelog=9 root=/dev/vda2 rw\";\n\t\t\tmemory = <0x0 0x46600000 0x0 0x40000000>;\n\t\t\tvm1_bdi {\n\t\t\t\tvm_console_vm1 {\n\t\t\t\t\tvirtual_device;\n\t\t\t\t\tvc-dynamic-res;\n\t\t\t\t\tcompatible = \"minos,vm_console\";\n\t\t\t\t};\n\t\t\t};\n\t\t};\n\t};\n\n\tplatform@c000000 {\n\t\tinterrupt-parent = < 0x8001 >;\n\t\tranges = < 0x00 0x00 0xc000000 0x2000000 >;\n\t\t#address-cells = < 0x01 >;\n\t\t#size-cells = < 0x01 >;\n\t\tcompatible = \"qemu,platform\\0simple-bus\";\n\t};\n\n\tfw-cfg@9020000 {\n\t\tdma-coherent;\n\t\treg = < 0x00 0x9020000 0x00 0x18 >;\n\t\tcompatible = \"qemu,fw-cfg-mmio\";\n\t};\n\n\tvirtio_mmio@a003e00 {\n\t\tdma-coherent;\n\t\tinterrupts = < 0x00 0x2f 0x01 >;\n\t\treg = < 0x00 0xa003e00 0x00 0x200 >;\n\t\tcompatible = \"virtio,mmio\";\n\t};\n\n\tgpio-keys {\n\t\t#address-cells = < 0x01 >;\n\t\t#size-cells = < 0x00 >;\n\t\tcompatible = \"gpio-keys\";\n\n\t\tpoweroff {\n\t\t\tgpios = < 0x8002 0x03 0x00 >;\n\t\t\tlinux,code = < 0x74 >;\n\t\t\tlabel = \"GPIO Key Poweroff\";\n\t\t};\n\t};\n\n\tpl061@9030000 {\n\t\tphandle = < 0x8002 >;\n\t\tclock-names = \"apb_pclk\";\n\t\tclocks = < 0x8000 >;\n\t\tinterrupts = < 0x00 0x07 0x04 >;\n\t\tgpio-controller;\n\t\t#gpio-cells = < 0x02 >;\n\t\tcompatible = \"arm,pl061\\0arm,primecell\";\n\t\treg = < 0x00 0x9030000 0x00 0x1000 >;\n\t};\n\n\tpcie@10000000 {\n\t\tinterrupt-map-mask = < 0x1800 0x00 0x00 0x07 >;\n\t\tinterrupt-map = < 0x00 0x00 0x00 0x01 0x8001 0x00 0x00 0x00 0x03 0x04 0x00 0x00 0x00 0x02 0x8001 0x00 0x00 0x00 0x04 0x04 0x00 0x00 0x00 0x03 0x8001 0x00 0x00 0x00 0x05 0x04 0x00 0x00 0x00 0x04 0x8001 0x00 0x00 0x00 0x06 0x04 0x800 0x00 0x00 0x01 0x8001 0x00 0x00 0x00 0x04 0x04 0x800 0x00 0x00 0x02 0x8001 0x00 0x00 0x00 0x05 0x04 0x800 0x00 0x00 0x03 0x8001 0x00 0x00 0x00 0x06 0x04 0x800 0x00 0x00 0x04 0x8001 0x00 0x00 0x00 0x03 0x04 0x1000 0x00 0x00 0x01 0x8001 0x00 0x00 0x00 0x05 0x04 0x1000 0x00 0x00 0x02 0x8001 0x00 0x00 0x00 0x06 0x04 0x1000 0x00 0x00 0x03 0x8001 0x00 0x00 0x00 0x03 0x04 0x1000 0x00 0x00 0x04 0x8001 0x00 0x00 0x00 0x04 0x04 0x1800 0x00 0x00 0x01 0x8001 0x00 0x00 0x00 0x06 0x04 0x1800 0x00 0x00 0x02 0x8001 0x00 0x00 0x00 0x03 0x04 0x1800 0x00 0x00 0x03 0x8001 0x00 0x00 0x00 0x04 0x04 0x1800 0x00 0x00 0x04 0x8001 0x00 0x00 0x00 0x05 0x04 >;\n\t\t#interrupt-cells = < 0x01 >;\n\t\tranges = < 0x1000000 0x00 0x00 0x00 0x3eff0000 0x00 0x10000 0x2000000 0x00 0x10000000 0x00 0x10000000 0x00 0x2eff0000 0x3000000 0x80 0x00 0x80 0x00 0x80 0x00 >;\n\t\treg = < 0x40 0x10000000 0x00 0x10000000 >;\n\t\tdma-coherent;\n\t\tbus-range = < 0x00 0xff >;\n\t\tlinux,pci-domain = < 0x00 >;\n\t\t#size-cells = < 0x02 >;\n\t\t#address-cells = < 0x03 >;\n\t\tdevice_type = \"pci\";\n\t\tcompatible = \"pci-host-ecam-generic\";\n\t};\n\n\tpl031@9010000 {\n\t\tclock-names = \"apb_pclk\";\n\t\tclocks = < 0x8000 >;\n\t\tinterrupts = < 0x00 0x02 0x04 >;\n\t\treg = < 0x00 0x9010000 0x00 0x1000 >;\n\t\tcompatible = \"arm,pl031\\0arm,primecell\";\n\t};\n\n\tpl011@9000000 {\n\t\tclock-names = \"uartclk\\0apb_pclk\";\n\t\tclocks = < 0x8000 0x8000 >;\n\t\tinterrupts = < 0x00 0x01 0x04 >;\n\t\treg = < 0x00 0x9000000 0x00 0x1000 >;\n\t\tcompatible = \"arm,pl011\\0arm,primecell\";\n\t};\n\n\tpmu {\n\t\tinterrupts = < 0x01 0x07 0x04 >;\n\t\tcompatible = \"arm,armv8-pmuv3\";\n\t};\n\n\tintc@8000000 {\n\t\tphandle = < 0x8001 >;\n\t\tinterrupts = < 0x01 0x09 0x04 >;\n\t\treg = <0x0 0x08000000 0 0x10000>,\t// GICD\n\t\t      <0x0 0x080a0000 0 0x200000>,\t// GICR\n\t\t      <0x0 0x08010000 0 0x2000>,\t// GICC\n\t\t      <0x0 0x08030000 0 0x2000>,\t// GICH\n\t\t      <0x0 0x08040000 0 0x2000>;\t// GICV\n\t\t#redistributor-regions = < 0x01 >;\n\t\tcompatible = \"arm,gic-v3\";\n\t\tranges;\n\t\t#size-cells = < 0x02 >;\n\t\t#address-cells = < 0x02 >;\n\t\tinterrupt-controller;\n\t\t#interrupt-cells = < 0x03 >;\n\t};\n\n\tflash@0 {\n\t\tbank-width = < 0x04 >;\n\t\treg = < 0x00 0x00 0x00 0x4000000 0x00 0x4000000 0x00 0x4000000 >;\n\t\tcompatible = \"cfi-flash\";\n\t};\n\n\tcpus {\n\t\t#size-cells = < 0x00 >;\n\t\t#address-cells = < 0x01 >;\n\n\t\tcpu@0 {\n\t\t\treg = < 0x00 >;\n\t\t\tenable-method = \"psci\";\n\t\t\tcompatible = \"arm,cortex-a53\";\n\t\t\tdevice_type = \"cpu\";\n\t\t};\n\n\t\tcpu@1 {\n\t\t\treg = < 0x01 >;\n\t\t\tenable-method = \"psci\";\n\t\t\tcompatible = \"arm,cortex-a53\";\n\t\t\tdevice_type = \"cpu\";\n\t\t};\n\n\t\tcpu@2 {\n\t\t\treg = < 0x02 >;\n\t\t\tenable-method = \"psci\";\n\t\t\tcompatible = \"arm,cortex-a53\";\n\t\t\tdevice_type = \"cpu\";\n\t\t};\n\n\t\tcpu@3 {\n\t\t\treg = < 0x03 >;\n\t\t\tenable-method = \"psci\";\n\t\t\tcompatible = \"arm,cortex-a53\";\n\t\t\tdevice_type = \"cpu\";\n\t\t};\n\t};\n\n\ttimer {\n\t\tinterrupts = < 0x01 0x0d 0x04 0x01 0x0e 0x04 0x01 0x0b 0x04 0x01 0x0a 0x04 >;\n\t\talways-on;\n\t\tcompatible = \"arm,armv8-timer\\0arm,armv7-timer\";\n\t};\n\n\tapb-pclk {\n\t\tphandle = < 0x8000 >;\n\t\tclock-output-names = \"clk24mhz\";\n\t\tclock-frequency = < 0x16e3600 >;\n\t\t#clock-cells = < 0x00 >;\n\t\tcompatible = \"fixed-clock\";\n\t};\n};\n"
  },
  {
    "path": "kernel/dtbs/r8a7795.dts",
    "content": "// SPDX-License-Identifier: GPL-2.0\n\n/dts-v1/;\n\n/ {\n    model = \"board based on r8a7795\";\n    compatible = \"renesas,r8a7795\";\n    #address-cells = <2>;\n    #size-cells = <2>;\n    interrupt-parent = <&gic>;\n\n    chosen {\n        minos,stdout = \"renesas,scif\";\n    };\n\n    soc {\n        #address-cells = <2>;\n        #size-cells = <2>;\n\n        gic: interrupt-controller@f1010000 {\n            compatible = \"arm,gic-400\";\n            #interrupt-cells = <3>;\n            interrupt-controller;\n            reg = <0x0 0xf1010000 0 0x1000>,\n                  <0x0 0xf1020000 0 0x20000>,\n                  <0x0 0xf1040000 0 0x20000>,\n                  <0x0 0xf1060000 0 0x20000>;\n        };\n    };\n\n    timer {\n        compatible = \"arm,armv8-timer\";\n        interrupts = <1 13 0xff08>,\n                     <1 14 0xff08>,\n                     <1 11 0xff08>,\n                     <1 10 0xff08>;\n    };\n\n    cpus {\n        #address-cells = <1>;\n        #size-cells = <0>;\n\n        cpu@0 {\n            reg = <0x0>;\n        };\n\n        cpu@1 {\n            reg = <0x1>;\n        };\n\n        cpu@2 {\n            reg = <0x2>;\n        };\n\n        cpu@3 {\n            reg = <0x3>;\n        };\n\n        cpu@100 {\n            reg = <0x100>;\n        };\n\n        cpu@101 {\n            reg = <0x101>;\n        };\n\n        cpu@102 {\n            reg = <0x102>;\n        };\n\n        cpu@103 {\n            reg = <0x103>;\n        };\n    };\n\n    memory@48000000 {\n        /* first 128MB is reserved for secure area. */\n        reg = <0x0 0x48000000 0x0 0x38000000>,\n              <0x5 0x00000000 0x0 0x40000000>,\n              <0x6 0x00000000 0x0 0x40000000>,\n              <0x7 0x00000000 0x0 0x40000000>;\n    };\n\n    /*\n     *   0x48000000 -  0x4a000000   32 MB  Minos\n     *   0x4a000000 -  0x65000000  432 MB  VM0\n     *   0x65000000 -  0x80000000  432 MB  VM1\n     *  0x500000000 - 0x540000000    1 GB  VM0\n     *  0x600000000 - 0x620000000  512 MB  VM0\n     *  0x620000000 - 0x640000000  512 MB  VM1\n     *  0x700000000 - 0x740000000    1 GB  VM1\n     *\n     * Minos' memory size should be equal to MINOS_RAM_SIZE.\n     */\n\n    vms {\n        vm0 {\n            device_type = \"virtual_machine\";\n            vmid = <0>;\n            vm_name = \"r8a7795_vm0\";\n            type = \"linux\";\n            vcpus = <4>;\n            vcpu_affinity = <0 1 2 3>;\n            memory = <0x0 0x4a000000 0x0 0x1b000000>,\n                     <0x5 0x00000000 0x0 0x40000000>,\n                     <0x6 0x00000000 0x0 0x20000000>;\n            /*\n             * The entry must be equal to the memory start address plus Linux's\n             * TEXT_OFFSET.\n             */\n            entry = <0x0 0x4a080000>;\n            setup_data = <0x0 0x4a000000>;\n            native_wfi;\n\n            vm0_bdi {\n                vm_console_vm0 {\n                    virtual_device;\n                    compatible = \"minos,vm_console\";\n                    vc-dynamic-res;\n                };\n            };\n        };\n\n        vm1 {\n            device_type = \"virtual_machine\";\n            vmid = <1>;\n            vm_name = \"r8a7795_vm1\";\n            type = \"linux\";\n            vcpus = <4>;\n            vcpu_affinity = <4 5 6 7>;\n            /*\n             * The first memory range must be 32-bits for DMA addressing.\n             */\n            memory = <0x0 0x65000000 0x0 0x1b000000>,\n                     <0x6 0x20000000 0x0 0x20000000>,\n                     <0x7 0x00000000 0x0 0x40000000>;\n            entry = <0x0 0x65080000>;\n            setup_data = <0x0 0x65000000>;\n            native_wfi;\n\n            vm1_bdi {\n                vm_console_vm1 {\n                    virtual_device;\n                    compatible = \"minos,vm_console\";\n                    vc-dynamic-res;\n                };\n            };\n        };\n    };\n};\n"
  },
  {
    "path": "kernel/include/device/bcm_irq.h",
    "content": "#ifndef __BCM_IRQ_H__\n#define __BCM_IRQ_H__\n\n#define LOCAL_CONTROL\t\t\t0x000\n#define LOCAL_PRESCALER\t\t\t0x008\n\n/*\n * The low 2 bits identify the CPU that the GPU IRQ goes to, and the\n * next 2 bits identify the CPU that the GPU FIQ goes to.\n */\n#define LOCAL_GPU_ROUTING\t\t0x00c\n/* When setting bits 0-3, enables PMU interrupts on that CPU. */\n#define LOCAL_PM_ROUTING_SET\t\t0x010\n/* When setting bits 0-3, disables PMU interrupts on that CPU. */\n#define LOCAL_PM_ROUTING_CLR\t\t0x014\n/*\n * The low 4 bits of this are the CPU's timer IRQ enables, and the\n * next 4 bits are the CPU's timer FIQ enables (which override the IRQ\n * bits).\n */\n#define LOCAL_TIMER_INT_CONTROL0\t0x040\n#define LOCAL_TIMER_INT_CONTROL3\t0x04c\n/*\n * The low 4 bits of this are the CPU's per-mailbox IRQ enables, and\n * the next 4 bits are the CPU's per-mailbox FIQ enables (which\n * override the IRQ bits).\n */\n#define LOCAL_MAILBOX_INT_CONTROL0\t0x050\n#define LOCAL_MAILBOX_INT_CONTROL3\t0x05c\n/*\n * The CPU's interrupt status register.  Bits are defined by the the\n * LOCAL_IRQ_* bits below.\n */\n#define LOCAL_IRQ_PENDING0\t\t0x060\n/* Same status bits as above, but for FIQ. */\n#define LOCAL_FIQ_PENDING0\t\t0x070\n/*\n * Mailbox write-to-set bits.  There are 16 mailboxes, 4 per CPU, and\n * these bits are organized by mailbox number and then CPU number.  We\n * use mailbox 0 for IPIs.  The mailbox's interrupt is raised while\n * any bit is set.\n */\n#define LOCAL_MAILBOX0_SET0\t\t0x080\n#define LOCAL_MAILBOX3_SET0\t\t0x08c\n\n#define LOCAL_MAILBOX_SET_START\t\t0x80\n#define LOCAL_MAILBOX_SET_END\t\t0xbc\n\n/* Mailbox write-to-clear bits. */\n#define LOCAL_MAILBOX0_CLR0\t\t0x0c0\n#define LOCAL_MAILBOX3_CLR0\t\t0x0cc\n\n#define LOCAL_MAILBOX_CLR_START\t\t0x0c0\n#define LOCAL_MAILBOX_CLR_END\t\t0x0fc\n\n#define LOCAL_IRQ_CNTPSIRQ\t0\n#define LOCAL_IRQ_CNTPNSIRQ\t1\n#define LOCAL_IRQ_CNTHPIRQ\t2\n#define LOCAL_IRQ_CNTVIRQ\t3\n#define LOCAL_IRQ_MAILBOX0\t4\n#define LOCAL_IRQ_MAILBOX1\t5\n#define LOCAL_IRQ_MAILBOX2\t6\n#define LOCAL_IRQ_MAILBOX3\t7\n#define LOCAL_IRQ_GPU_FAST\t8\n#define LOCAL_IRQ_PMU_FAST\t9\n#define LAST_IRQ\t\tLOCAL_IRQ_PMU_FAST\n\n#define BCM2836_INC_BASE\t\t0x40000000\n#define BCM2835_INC_OFFSET\t\t0x200\n\n/* max support 8 cpus */\n#define BCM2836_RELEASE_ADDR\t\t0x40000180\n#define BCM2836_RELEASE_OFFSET\t\t0x180\n#define BCM2836_RELEASE_OFFSET_END\t0x1bf\n#define BCM2836_IRQ_ACK\t\t\t0x1c0\n\n#define BCM2835_IRQ_BASIC_PENDING\t0x200\n#define BCM2835_IRQ_PENDING1\t\t0x204\n#define BCM2835_IRQ_PENDING2\t\t0x208\n#define BCM2835_FIQ_CRTL\t\t0x20c\n#define BCM2835_IRQ_ENABLE1\t\t0x210\n#define BCM2835_IRQ_ENABLE2\t\t0x214\n#define BCM2835_IRQ_BASIC_ENABLE\t0x218\n#define BCM2835_IRQ_DISABLE1\t\t0x21c\n#define BCM2835_IRQ_DISABLE2\t\t0x220\n#define BCM2835_IRQ_DISABLE_BASIC\t0x224\n#define BCM2835_IRQ_ACK\t\t\t0x228\n\n/* Put the bank and irq (32 bits) into the hwirq */\n#define MAKE_HWIRQ(b, n)\t(((b + 1) << 5) | (n))\n#define HWIRQ_BANK(i)\t\t((i >> 5) - 1)\n#define HWIRQ_BIT(i)\t\tBIT(i & 0x1f)\n\n#define NR_IRQS_BANK0\t\t8\n#define BANK0_HWIRQ_MASK\t0xff\n/* Shortcuts can't be disabled so any unknown new ones need to be masked */\n#define SHORTCUT1_MASK\t\t0x00007c00\n#define SHORTCUT2_MASK\t\t0x001f8000\n#define SHORTCUT_SHIFT\t\t10\n#define BANK1_HWIRQ\t\tBIT(8)\n#define BANK2_HWIRQ\t\tBIT(9)\n#define BANK0_VALID_MASK\t(BANK0_HWIRQ_MASK | BANK1_HWIRQ | BANK2_HWIRQ \\\n\t\t\t\t\t| SHORTCUT1_MASK | SHORTCUT2_MASK)\n\n#undef ARM_LOCAL_GPU_INT_ROUTING\n#define ARM_LOCAL_GPU_INT_ROUTING 0x0c\n\n#define REG_FIQ_CONTROL\t\t0x0c\n#define REG_FIQ_ENABLE\t\t0x80\n#define REG_FIQ_DISABLE\t\t0\n\n#define NR_BANKS\t\t3\n#define IRQS_PER_BANK\t\t32\n#define NUMBER_IRQS\t\tMAKE_HWIRQ(NR_BANKS, 0)\n#undef FIQ_START\n#define FIQ_START\t\t(NR_IRQS_BANK0 + MAKE_HWIRQ(NR_BANKS - 1, 0))\n\n/*********\nThe interrupt sources are as follows:\n\nBank 0:\n0: ARM_TIMER\n1: ARM_MAILBOX\n2: ARM_DOORBELL_0\n3: ARM_DOORBELL_1\n4: VPU0_HALTED\n5: VPU1_HALTED\n6: ILLEGAL_TYPE0\n7: ILLEGAL_TYPE1\n8 - 20 : used for gpu\n21 - 31 : used for vm0 VMCS\n\nBank 1:\n0: TIMER0\n1: TIMER1\n2: TIMER2\n3: TIMER3\n4: CODEC0\n5: CODEC1\n6: CODEC2\n7: VC_JPEG\n8: ISP\n9: VC_USB\n10: VC_3D\n11: TRANSPOSER\n12: MULTICORESYNC0\n13: MULTICORESYNC1\n14: MULTICORESYNC2\n15: MULTICORESYNC3\n16: DMA0\n17: DMA1\n18: VC_DMA2\n19: VC_DMA3\n20: DMA4\n21: DMA5\n22: DMA6\n23: DMA7\n24: DMA8\n25: DMA9\n26: DMA10\n27: DMA11-14 - shared interrupt for DMA 11 to 14\n28: DMAALL - triggers on all dma interrupts (including chanel 15)\n29: AUX\n30: ARM\n31: VPUDMA\n\nBank 2:\n0: HOSTPORT\n1: VIDEOSCALER\n2: CCP2TX\n3: SDC\n4: DSI0\n5: AVE\n6: CAM0\n7: CAM1\n8: HDMI0\n9: HDMI1\n10: PIXELVALVE1\n11: I2CSPISLV\n12: DSI1\n13: PWA0\n14: PWA1\n15: CPR\n16: SMI\n17: GPIO0\n18: GPIO1\n19: GPIO2\n20: GPIO3\n21: VC_I2C\n22: VC_SPI\n23: VC_I2SPCM\n24: VC_SDIO\n25: VC_UART\n26: SLIMBUS\n27: VEC\n28: CPG\n29: RNG\n30: VC_ARASANSDIO\n31: AVSPMON\n\n**********/\n\n#endif\n"
  },
  {
    "path": "kernel/include/device/gicv2.h",
    "content": "/*\n * ARM Generic Interrupt Controller support\n *\n * Tim Deegan <tim@xen.org>\n * Copyright (c) 2011 Citrix Systems.\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n */\n\n#ifndef __ASM_ARM_GIC_H__\n#define __ASM_ARM_GIC_H__\n\n#define NR_GIC_LOCAL_IRQS  NR_LOCAL_IRQS\n#define NR_GIC_SGI         16\n\n#define GICD_CTLR       \t(0x000)\n#define GICD_TYPER      \t(0x004)\n#define GICD_IIDR       \t(0x008)\n#define GICD_IGROUPR    \t(0x080)\n#define GICD_IGROUPRN   \t(0x0FC)\n#define GICD_ISENABLER  \t(0x100)\n#define GICD_ISENABLERN \t(0x17C)\n#define GICD_ICENABLER  \t(0x180)\n#define GICD_ICENABLERN \t(0x1fC)\n#define GICD_ISPENDR    \t(0x200)\n#define GICD_ISPENDRN   \t(0x27C)\n#define GICD_ICPENDR    \t(0x280)\n#define GICD_ICPENDRN   \t(0x2FC)\n#define GICD_ISACTIVER  \t(0x300)\n#define GICD_ISACTIVERN \t(0x37C)\n#define GICD_ICACTIVER  \t(0x380)\n#define GICD_ICACTIVERN \t(0x3FC)\n#define GICD_IPRIORITYR \t(0x400)\n#define GICD_IPRIORITYRN \t(0x7F8)\n#define GICD_ITARGETSR  \t(0x800)\n#define GICD_ITARGETSR7 \t(0x81C)\n#define GICD_ITARGETSR8 \t(0x820)\n#define GICD_ITARGETSRN \t(0xBF8)\n#define GICD_ICFGR      \t(0xC00)\n#define GICD_ICFGR1     \t(0xC04)\n#define GICD_ICFGR2     \t(0xC08)\n#define GICD_ICFGRN     \t(0xCFC)\n#define GICD_NSACR      \t(0xE00)\n#define GICD_NSACRN     \t(0xEFC)\n#define GICD_SGIR       \t(0xF00)\n#define GICD_CPENDSGIR  \t(0xF10)\n#define GICD_CPENDSGIRN \t(0xF1C)\n#define GICD_SPENDSGIR  \t(0xF20)\n#define GICD_SPENDSGIRN \t(0xF2C)\n#define GICD_ICPIDR2    \t(0xFE8)\n\n#define GICD_SGI_TARGET_LIST_SHIFT   (24)\n#define GICD_SGI_TARGET_LIST_MASK    (0x3UL << GICD_SGI_TARGET_LIST_SHIFT)\n#define GICD_SGI_TARGET_SHIFT        (16)\n#define GICD_SGI_TARGET_MASK         (0xFFUL << GICD_SGI_TARGET_SHIFT)\n#define GICD_SGI_GROUP1              (1UL << 15)\n#define GICD_SGI_INTID_MASK          (0xFUL)\n#define GICD_SGI_TARGET_OTHERS       (1UL << GICD_SGI_TARGET_LIST_SHIFT)\n#define GICD_SGI_TARGET_SELF         (2UL << GICD_SGI_TARGET_LIST_SHIFT)\n#define GICD_SGI_TARGET_LIST         (0UL << GICD_SGI_TARGET_LIST_SHIFT)\n\n#define GICC_CTLR       \t(0x0000)\n#define GICC_PMR        \t(0x0004)\n#define GICC_BPR        \t(0x0008)\n#define GICC_IAR        \t(0x000C)\n#define GICC_EOIR       \t(0x0010)\n#define GICC_RPR        \t(0x0014)\n#define GICC_HPPIR      \t(0x0018)\n#define GICC_APR        \t(0x00D0)\n#define GICC_NSAPR      \t(0x00E0)\n#define GICC_IIDR       \t(0x00FC)\n#define GICC_DIR        \t(0x1000)\n\n#define GICH_HCR        \t(0x00)\n#define GICH_VTR        \t(0x04)\n#define GICH_VMCR       \t(0x08)\n#define GICH_MISR       \t(0x10)\n#define GICH_EISR0      \t(0x20)\n#define GICH_EISR1      \t(0x24)\n#define GICH_ELSR0      \t(0x30)\n#define GICH_ELSR1      \t(0x34)\n#define GICH_APR        \t(0xF0)\n#define GICH_LR         \t(0x100)\n\n/* Register bits */\n#define GICD_CTL_ENABLE \t0x1\n\n#define GICD_TYPE_LINES \t0x01f\n#define GICD_TYPE_CPUS_SHIFT \t5\n#define GICD_TYPE_CPUS  \t0x0e0\n#define GICD_TYPE_SEC   \t0x400\n#define GICD_TYPER_DVIS \t(1U << 18)\n\n#define GICC_CTL_ENABLE \t0x1\n#define GICC_CTL_EOI    \t(0x1 << 9)\n\n#define GICC_IA_IRQ       \t0x03ff\n#define GICC_IA_CPU_MASK  \t0x1c00\n#define GICC_IA_CPU_SHIFT \t10\n\n#define GICH_HCR_EN       \t(1 << 0)\n#define GICH_HCR_UIE      \t(1 << 1)\n#define GICH_HCR_LRENPIE  \t(1 << 2)\n#define GICH_HCR_NPIE     \t(1 << 3)\n#define GICH_HCR_VGRP0EIE \t(1 << 4)\n#define GICH_HCR_VGRP0DIE \t(1 << 5)\n#define GICH_HCR_VGRP1EIE \t(1 << 6)\n#define GICH_HCR_VGRP1DIE \t(1 << 7)\n\n#define GICH_MISR_EOI     \t(1 << 0)\n#define GICH_MISR_U       \t(1 << 1)\n#define GICH_MISR_LRENP   \t(1 << 2)\n#define GICH_MISR_NP      \t(1 << 3)\n#define GICH_MISR_VGRP0E  \t(1 << 4)\n#define GICH_MISR_VGRP0D  \t(1 << 5)\n#define GICH_MISR_VGRP1E  \t(1 << 6)\n#define GICH_MISR_VGRP1D  \t(1 << 7)\n\n/*\n * The minimum GICC_BPR is required to be in the range 0-3. We set\n * GICC_BPR to 0 but we must expect that it might be 3. This means we\n * can rely on premption between the following ranges:\n * 0xf0..0xff\n * 0xe0..0xdf\n * 0xc0..0xcf\n * 0xb0..0xbf\n * 0xa0..0xaf\n * 0x90..0x9f\n * 0x80..0x8f\n *\n * Priorities within a range will not preempt each other.\n *\n * A GIC must support a mimimum of 16 priority levels.\n */\n#define GIC_PRI_LOWEST     \t0xf0\n#define GIC_PRI_IRQ        \t0xa0\n#define GIC_PRI_IPI        \t0x90 /* IPIs must preempt normal interrupts */\n#define GIC_PRI_HIGHEST    \t0x80 /* Higher priorities belong to Secure-World */\n#define GIC_PRI_TO_GUEST(pri) \t(pri >> 3) /* GICH_LR and GICH_VMCR only support\n                                            5 bits for guest irq priority */\n\nstruct gicv2_context {\n    uint32_t hcr;\n    uint32_t vmcr;\n    uint32_t apr;\n    uint32_t lr[64];\n};\n\nstruct gich_lr {\n\tuint32_t vid : 10;\n\tuint32_t pid : 10;\n\tuint32_t resv : 3;\n\tuint32_t pr : 5;\n\tuint32_t state : 2;\n\tuint32_t grp1 : 1;\n\tuint32_t hw : 1;\n};\n\n#endif\n"
  },
  {
    "path": "kernel/include/device/gicv3.h",
    "content": "#ifndef _MINOS_GICV3_H_\n#define _MINOS_GICV3_H_\n\n//#include <asm/gic_reg.h>\n\n#if 0\n#define GICD_CTLR_ENABLE_GRP0\t\t(1 << 0)\n#define GICD_CTLR_ENABLE_GRP1NS\t\t(1 << 1)\n#define GICD_CTLR_ENABLE_GRP1A\t\t(1 << 1)\n#define GICD_CTLR_ENABLE_GRP1S\t\t(1 << 2)\n#define GICD_CTLR_ENABLE_ALL\t\t((1 << 0) | (1 << 1) | (1 << 2))\n#define GICD_CTLR_ARE_S\t\t\t(1 << 4)\n#define GICD_CTLR_ARE_NS\t\t(1 << 5)\n#define GICD_CTLR_DS\t\t\t(1 << 6)\n#define GICD_CTLR_E1NWF\t\t\t(1 << 7)\n#else /* for no-secure access */\n#define GICD_CTLR_ENABLE_GRP1\t\t(0 << 1)\n#define GICD_CTLR_ENABLE_GRP1A\t\t(1 << 1)\n#define GICD_CTLR_ARE_NS\t\t(1 << 4)\n#endif\n\n#define GICD_IROUTER_MODE_SPECIFIC\t(0)\n#define GICD_IROUTER_MODE_ANY\t\t(1 << 31)\n\n#define GICD_ICFGR_LEVEL\t\t(0)\n#define GICD_ICFGR_EDGE\t\t\t(1 << 31)\n\n#define GICD_IGROUPR_G0S\t\t(0)\n#define GICD_IGROUPR_G1NS\t\t(1 << 0)\n#define GICD_IGROUPR_G1S\t\t(1 << 2)\n\n#define GICR_WAKER_PROCESSOR_SLEEP\t(1 << 1)\n#define GICR_WAKER_CHILDREN_ASLEEP\t(1 << 2)\n\n#define GICD_CTLR\t\t\t(0x0000)\n#define GICD_TYPER\t\t\t(0x0004)\n#define GICD_IIDR\t\t\t(0x0008)\n#define GICD_STATUSR\t\t\t(0x0010)\n#define GICD_SETSPI_NSR\t\t\t(0x0040)\n#define GICD_CLRSPI_NSR\t\t\t(0x0048)\n#define GICD_SETSPI_SR\t\t\t(0x0050)\n#define GICD_CLRSPI_SR\t\t\t(0x0058)\n#define GICD_SEIR\t\t\t(0x0068)\n#define GICD_IGROUPR\t\t\t(0x0080)\n#define GICD_ISENABLER\t\t\t(0x0100)\n#define GICD_ISENABLER_END\t\t(0x017c - 1)\n#define GICD_ICENABLER\t\t\t(0x0180)\n#define GICD_ICENABLER_END\t\t(0x01fc - 1)\n#define GICD_ISPENDR\t\t\t(0x0200)\n#define GICD_ICPENDR\t\t\t(0x0280)\n#define GICD_ISACTIVER\t\t\t(0x0300)\n#define GICD_ICACTIVER\t\t\t(0x0380)\n#define GICD_IPRIORITYR\t\t\t(0x0400)\n#define GICD_IPRIORITYR_END\t\t(0x07f8 - 1)\n#define GICD_ITARGETSR\t\t\t(0x0800)\n#define GICD_ICFGR\t\t\t(0x0c00)\n#define GICD_ICFGR_END\t\t\t(0x0cfc - 1)\n#define GICD_IGRPMODR\t\t\t(0x0d00)\n#define GICD_NSACR\t\t\t(0x0e00)\n#define GICD_SGIR\t\t\t(0x0f00)\n#define GICD_CPENDSGIR\t\t\t(0x0f10)\n#define GICD_SPENDSGIR\t\t\t(0x0f20)\n#define GICD_IROUTER\t\t\t(0x6000)\n#define GICD_PIDR2\t\t\t(0xffe8)\n\n#define GICR_CTLR\t\t\t(0x0000)\n#define GICR_IIDR\t\t\t(0x0004)\n#define GICR_TYPER\t\t\t(0x0008)\n#define GICR_TYPER_HIGH\t\t\t(0x000c)\n#define GICR_STATUSR\t\t\t(0X0010)\n#define GICR_WAKER\t\t\t(0x0014)\n#define GICR_SETLPIR\t\t\t(0x0040)\n#define GICR_CLRLPIR\t\t\t(0x0048)\n#define GICR_SEIR\t\t\t(0x0068)\n#define GICR_PROPBASER\t\t\t(0x0070)\n#define GICR_PENDBASER\t\t\t(0x0078)\n#define GICR_INVLPIR\t\t\t(0x00a0)\n#define GICR_INVALLR\t\t\t(0x00b0)\n#define GICR_SYNCR\t\t\t(0x00c0)\n#define GICR_MOVLPIR\t\t\t(0x0100)\n#define GICR_MOVALLR\t\t\t(0x0110)\n\n#define GICR_IGROUPR0\t\t\t(0x0080)\n#define GICR_ISENABLER\t\t\t(0x0100)\n#define GICR_ICENABLER\t\t\t(0x0180)\n#define GICR_ISPENDR0\t\t\t(0x0200)\n#define GICR_ICPENDR0\t\t\t(0x0280)\n#define GICR_ISACTIVER0\t\t\t(0x0300)\n#define GICR_ICACTIVER0\t\t\t(0x0380)\n#define GICR_IPRIORITYR0\t\t(0x0400)\n#define GICR_ICFGR0\t\t\t(0x0c00)\n#define GICR_ICFGR1\t\t\t(0x0c04)\n#define GICR_IGRPMODR0\t\t\t(0x0d00)\n#define GICR_NSACR\t\t\t(0x0e00)\n#define GICR_PIDR2\t\t\t(0xffe8)\n\n#define GICH_VMCR_VENG0\t\t\t(1 << 0)\n#define GICH_VMCR_VENG1\t\t\t(1 << 1)\n#define GICH_VMCR_VACKCTL\t\t(1 << 2)\n#define GICH_VMCR_VFIQEN\t\t(1 << 3)\n#define GICH_VMCR_VCBPR\t\t\t(1 << 4)\n#define GICH_VMCR_VEOIM\t\t\t(1 << 9)\n\n#define GICH_HCR_EN       \t\t(1 << 0)\n#define GICH_HCR_UIE      \t\t(1 << 1)\n#define GICH_HCR_LRENPIE  \t\t(1 << 2)\n#define GICH_HCR_NPIE     \t\t(1 << 3)\n#define GICH_HCR_VGRP0EIE \t\t(1 << 4)\n#define GICH_HCR_VGRP0DIE \t\t(1 << 5)\n#define GICH_HCR_VGRP1EIE \t\t(1 << 6)\n#define GICH_HCR_VGRP1DIE \t\t(1 << 7)\n\n#define ICH_SGI_IRQMODE_SHIFT        \t(40)\n#define ICH_SGI_IRQMODE_MASK         \t(0x1)\n#define ICH_SGI_TARGET_OTHERS        \t(1UL)\n#define ICH_SGI_TARGET_LIST          \t(0)\n#define ICH_SGI_IRQ_SHIFT            \t(24)\n#define ICH_SGI_IRQ_MASK             \t(0xf)\n#define ICH_SGI_TARGETLIST_MASK      \t(0xffff)\n#define ICH_SGI_AFFx_MASK            \t(0xff)\n#define ICH_SGI_AFFINITY_LEVEL(x)    \t(16 * (x))\n\n#define GICV3_NR_LOCAL_IRQS\t(32)\n#define GICV3_NR_SGI\t\t(16)\n\nstruct gicv3_context {\n\tuint64_t ich_lr0_el2;\n\tuint64_t ich_lr1_el2;\n\tuint64_t ich_lr2_el2;\n\tuint64_t ich_lr3_el2;\n\tuint64_t ich_lr4_el2;\n\tuint64_t ich_lr5_el2;\n\tuint64_t ich_lr6_el2;\n\tuint64_t ich_lr7_el2;\n\tuint64_t ich_lr8_el2;\n\tuint64_t ich_lr9_el2;\n\tuint64_t ich_lr10_el2;\n\tuint64_t ich_lr11_el2;\n\tuint64_t ich_lr12_el2;\n\tuint64_t ich_lr13_el2;\n\tuint64_t ich_lr14_el2;\n\tuint64_t ich_lr15_el2;\n\tuint32_t ich_ap0r2_el2;\n\tuint32_t ich_ap1r2_el2;\n\tuint32_t ich_ap0r1_el2;\n\tuint32_t ich_ap1r1_el2;\n\tuint32_t ich_ap0r0_el2;\n\tuint32_t ich_ap1r0_el2;\n\tuint32_t icc_sre_el1;\n\tuint32_t ich_vmcr_el2;\n\tuint32_t ich_hcr_el2;\n} __align(sizeof(unsigned long));\n\nstruct gic_lr {\n\tuint64_t v_intid : 32;\n\tuint64_t p_intid : 10;\n\tuint64_t res0 : 6;\n\tuint64_t priority : 8;\n\tuint64_t res1 : 4;\n\tuint64_t group : 1;\n\tuint64_t hw : 1;\n\tuint64_t state : 2;\n};\n\n#endif\n"
  },
  {
    "path": "kernel/include/libfdt/fdt.h",
    "content": "#ifndef FDT_H\n#define FDT_H\n/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2006 David Gibson, IBM Corporation.\n * Copyright 2012 Kim Phillips, Freescale Semiconductor.\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifndef __ASSEMBLY__\n\nstruct fdt_header {\n\tfdt32_t magic;\t\t\t /* magic word FDT_MAGIC */\n\tfdt32_t totalsize;\t\t /* total size of DT block */\n\tfdt32_t off_dt_struct;\t\t /* offset to structure */\n\tfdt32_t off_dt_strings;\t\t /* offset to strings */\n\tfdt32_t off_mem_rsvmap;\t\t /* offset to memory reserve map */\n\tfdt32_t version;\t\t /* format version */\n\tfdt32_t last_comp_version;\t /* last compatible version */\n\n\t/* version 2 fields below */\n\tfdt32_t boot_cpuid_phys;\t /* Which physical CPU id we're\n\t\t\t\t\t    booting on */\n\t/* version 3 fields below */\n\tfdt32_t size_dt_strings;\t /* size of the strings block */\n\n\t/* version 17 fields below */\n\tfdt32_t size_dt_struct;\t\t /* size of the structure block */\n};\n\nstruct fdt_reserve_entry {\n\tfdt64_t address;\n\tfdt64_t size;\n};\n\nstruct fdt_node_header {\n\tfdt32_t tag;\n\tchar name[0];\n};\n\nstruct fdt_property {\n\tfdt32_t tag;\n\tfdt32_t len;\n\tfdt32_t nameoff;\n\tchar data[0];\n};\n\n#endif /* !__ASSEMBLY */\n\n#define FDT_MAGIC\t0xd00dfeed\t/* 4: version, 4: total size */\n#define FDT_TAGSIZE\tsizeof(fdt32_t)\n\n#define FDT_BEGIN_NODE\t0x1\t\t/* Start node: full name */\n#define FDT_END_NODE\t0x2\t\t/* End node */\n#define FDT_PROP\t0x3\t\t/* Property: name off,\n\t\t\t\t\t   size, content */\n#define FDT_NOP\t\t0x4\t\t/* nop */\n#define FDT_END\t\t0x9\n\n#define FDT_V1_SIZE\t(7*sizeof(fdt32_t))\n#define FDT_V2_SIZE\t(FDT_V1_SIZE + sizeof(fdt32_t))\n#define FDT_V3_SIZE\t(FDT_V2_SIZE + sizeof(fdt32_t))\n#define FDT_V16_SIZE\tFDT_V3_SIZE\n#define FDT_V17_SIZE\t(FDT_V16_SIZE + sizeof(fdt32_t))\n\n#endif /* FDT_H */\n"
  },
  {
    "path": "kernel/include/libfdt/libfdt.h",
    "content": "#ifndef LIBFDT_H\n#define LIBFDT_H\n/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2006 David Gibson, IBM Corporation.\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include <libfdt/libfdt_env.h>\n#include <libfdt/fdt.h>\n\n#define FDT_FIRST_SUPPORTED_VERSION\t0x02\n#define FDT_LAST_SUPPORTED_VERSION\t0x11\n\n/* Error codes: informative error codes */\n#define FDT_ERR_NOTFOUND\t1\n\t/* FDT_ERR_NOTFOUND: The requested node or property does not exist */\n#define FDT_ERR_EXISTS\t\t2\n\t/* FDT_ERR_EXISTS: Attempted to create a node or property which\n\t * already exists */\n#define FDT_ERR_NOSPACE\t\t3\n\t/* FDT_ERR_NOSPACE: Operation needed to expand the device\n\t * tree, but its buffer did not have sufficient space to\n\t * contain the expanded tree. Use fdt_open_into() to move the\n\t * device tree to a buffer with more space. */\n\n/* Error codes: codes for bad parameters */\n#define FDT_ERR_BADOFFSET\t4\n\t/* FDT_ERR_BADOFFSET: Function was passed a structure block\n\t * offset which is out-of-bounds, or which points to an\n\t * unsuitable part of the structure for the operation. */\n#define FDT_ERR_BADPATH\t\t5\n\t/* FDT_ERR_BADPATH: Function was passed a badly formatted path\n\t * (e.g. missing a leading / for a function which requires an\n\t * absolute path) */\n#define FDT_ERR_BADPHANDLE\t6\n\t/* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle.\n\t * This can be caused either by an invalid phandle property\n\t * length, or the phandle value was either 0 or -1, which are\n\t * not permitted. */\n#define FDT_ERR_BADSTATE\t7\n\t/* FDT_ERR_BADSTATE: Function was passed an incomplete device\n\t * tree created by the sequential-write functions, which is\n\t * not sufficiently complete for the requested operation. */\n\n/* Error codes: codes for bad device tree blobs */\n#define FDT_ERR_TRUNCATED\t8\n\t/* FDT_ERR_TRUNCATED: FDT or a sub-block is improperly\n\t * terminated (overflows, goes outside allowed bounds, or\n\t * isn't properly terminated).  */\n#define FDT_ERR_BADMAGIC\t9\n\t/* FDT_ERR_BADMAGIC: Given \"device tree\" appears not to be a\n\t * device tree at all - it is missing the flattened device\n\t * tree magic number. */\n#define FDT_ERR_BADVERSION\t10\n\t/* FDT_ERR_BADVERSION: Given device tree has a version which\n\t * can't be handled by the requested operation.  For\n\t * read-write functions, this may mean that fdt_open_into() is\n\t * required to convert the tree to the expected version. */\n#define FDT_ERR_BADSTRUCTURE\t11\n\t/* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt\n\t * structure block or other serious error (e.g. misnested\n\t * nodes, or subnodes preceding properties). */\n#define FDT_ERR_BADLAYOUT\t12\n\t/* FDT_ERR_BADLAYOUT: For read-write functions, the given\n\t * device tree has it's sub-blocks in an order that the\n\t * function can't handle (memory reserve map, then structure,\n\t * then strings).  Use fdt_open_into() to reorganize the tree\n\t * into a form suitable for the read-write operations. */\n\n/* \"Can't happen\" error indicating a bug in libfdt */\n#define FDT_ERR_INTERNAL\t13\n\t/* FDT_ERR_INTERNAL: libfdt has failed an internal assertion.\n\t * Should never be returned, if it is, it indicates a bug in\n\t * libfdt itself. */\n\n/* Errors in device tree content */\n#define FDT_ERR_BADNCELLS\t14\n\t/* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells\n\t * or similar property with a bad format or value */\n\n#define FDT_ERR_BADVALUE\t15\n\t/* FDT_ERR_BADVALUE: Device tree has a property with an unexpected\n\t * value. For example: a property expected to contain a string list\n\t * is not NUL-terminated within the length of its value. */\n\n#define FDT_ERR_BADOVERLAY\t16\n\t/* FDT_ERR_BADOVERLAY: The device tree overlay, while\n\t * correctly structured, cannot be applied due to some\n\t * unexpected or missing value, property or node. */\n\n#define FDT_ERR_NOPHANDLES\t17\n\t/* FDT_ERR_NOPHANDLES: The device tree doesn't have any\n\t * phandle available anymore without causing an overflow */\n\n#define FDT_ERR_MAX\t\t17\n\n/**********************************************************************/\n/* Low-level functions (you probably don't need these)                */\n/**********************************************************************/\n\n#ifndef SWIG /* This function is not useful in Python */\nconst void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen);\n#endif\nstatic inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)\n{\n\treturn (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen);\n}\n\nuint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);\n\n/*\n * Alignment helpers:\n *     These helpers access words from a device tree blob.  They're\n *     built to work even with unaligned pointers on platforms (ike\n *     ARM) that don't like unaligned loads and stores\n */\n\nstatic inline uint32_t fdt32_ld(const fdt32_t *p)\n{\n\tfdt32_t v;\n\n\tmemcpy(&v, p, sizeof(v));\n\treturn fdt32_to_cpu(v);\n}\n\nstatic inline uint64_t fdt64_ld(const fdt64_t *p)\n{\n\tfdt64_t v;\n\n\tmemcpy(&v, p, sizeof(v));\n\treturn fdt64_to_cpu(v);\n}\n\n/**********************************************************************/\n/* Traversal functions                                                */\n/**********************************************************************/\n\nint fdt_next_node(const void *fdt, int offset, int *depth);\n\n/**\n * fdt_first_subnode() - get offset of first direct subnode\n *\n * @fdt:\tFDT blob\n * @offset:\tOffset of node to check\n * @return offset of first subnode, or -FDT_ERR_NOTFOUND if there is none\n */\nint fdt_first_subnode(const void *fdt, int offset);\n\n/**\n * fdt_next_subnode() - get offset of next direct subnode\n *\n * After first calling fdt_first_subnode(), call this function repeatedly to\n * get direct subnodes of a parent node.\n *\n * @fdt:\tFDT blob\n * @offset:\tOffset of previous subnode\n * @return offset of next subnode, or -FDT_ERR_NOTFOUND if there are no more\n * subnodes\n */\nint fdt_next_subnode(const void *fdt, int offset);\n\n/**\n * fdt_for_each_subnode - iterate over all subnodes of a parent\n *\n * @node:\tchild node (int, lvalue)\n * @fdt:\tFDT blob (const void *)\n * @parent:\tparent node (int)\n *\n * This is actually a wrapper around a for loop and would be used like so:\n *\n *\tfdt_for_each_subnode(node, fdt, parent) {\n *\t\tUse node\n *\t\t...\n *\t}\n *\n *\tif ((node < 0) && (node != -FDT_ERR_NOT_FOUND)) {\n *\t\tError handling\n *\t}\n *\n * Note that this is implemented as a macro and @node is used as\n * iterator in the loop. The parent variable be constant or even a\n * literal.\n *\n */\n#define fdt_for_each_subnode(node, fdt, parent)\t\t\\\n\tfor (node = fdt_first_subnode(fdt, parent);\t\\\n\t     node >= 0;\t\t\t\t\t\\\n\t     node = fdt_next_subnode(fdt, node))\n\n/**********************************************************************/\n/* General functions                                                  */\n/**********************************************************************/\n#define fdt_get_header(fdt, field) \\\n\t(fdt32_ld(&((const struct fdt_header *)(fdt))->field))\n#define fdt_magic(fdt)\t\t\t(fdt_get_header(fdt, magic))\n#define fdt_totalsize(fdt)\t\t(fdt_get_header(fdt, totalsize))\n#define fdt_off_dt_struct(fdt)\t\t(fdt_get_header(fdt, off_dt_struct))\n#define fdt_off_dt_strings(fdt)\t\t(fdt_get_header(fdt, off_dt_strings))\n#define fdt_off_mem_rsvmap(fdt)\t\t(fdt_get_header(fdt, off_mem_rsvmap))\n#define fdt_version(fdt)\t\t(fdt_get_header(fdt, version))\n#define fdt_last_comp_version(fdt)\t(fdt_get_header(fdt, last_comp_version))\n#define fdt_boot_cpuid_phys(fdt)\t(fdt_get_header(fdt, boot_cpuid_phys))\n#define fdt_size_dt_strings(fdt)\t(fdt_get_header(fdt, size_dt_strings))\n#define fdt_size_dt_struct(fdt)\t\t(fdt_get_header(fdt, size_dt_struct))\n\n#define fdt_set_hdr_(name) \\\n\tstatic inline void fdt_set_##name(void *fdt, uint32_t val) \\\n\t{ \\\n\t\tstruct fdt_header *fdth = (struct fdt_header *)fdt; \\\n\t\tfdth->name = cpu_to_fdt32(val); \\\n\t}\nfdt_set_hdr_(magic);\nfdt_set_hdr_(totalsize);\nfdt_set_hdr_(off_dt_struct);\nfdt_set_hdr_(off_dt_strings);\nfdt_set_hdr_(off_mem_rsvmap);\nfdt_set_hdr_(version);\nfdt_set_hdr_(last_comp_version);\nfdt_set_hdr_(boot_cpuid_phys);\nfdt_set_hdr_(size_dt_strings);\nfdt_set_hdr_(size_dt_struct);\n#undef fdt_set_hdr_\n\n/**\n * fdt_header_size - return the size of the tree's header\n * @fdt: pointer to a flattened device tree\n */\nsize_t fdt_header_size_(uint32_t version);\nstatic inline size_t fdt_header_size(const void *fdt)\n{\n\treturn fdt_header_size_(fdt_version(fdt));\n}\n\n/**\n * fdt_check_header - sanity check a device tree header\n\n * @fdt: pointer to data which might be a flattened device tree\n *\n * fdt_check_header() checks that the given buffer contains what\n * appears to be a flattened device tree, and that the header contains\n * valid information (to the extent that can be determined from the\n * header alone).\n *\n * returns:\n *     0, if the buffer appears to contain a valid device tree\n *     -FDT_ERR_BADMAGIC,\n *     -FDT_ERR_BADVERSION,\n *     -FDT_ERR_BADSTATE,\n *     -FDT_ERR_TRUNCATED, standard meanings, as above\n */\nint fdt_check_header(const void *fdt);\n\n/**\n * fdt_move - move a device tree around in memory\n * @fdt: pointer to the device tree to move\n * @buf: pointer to memory where the device is to be moved\n * @bufsize: size of the memory space at buf\n *\n * fdt_move() relocates, if possible, the device tree blob located at\n * fdt to the buffer at buf of size bufsize.  The buffer may overlap\n * with the existing device tree blob at fdt.  Therefore,\n *     fdt_move(fdt, fdt, fdt_totalsize(fdt))\n * should always succeed.\n *\n * returns:\n *     0, on success\n *     -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree\n *     -FDT_ERR_BADMAGIC,\n *     -FDT_ERR_BADVERSION,\n *     -FDT_ERR_BADSTATE, standard meanings\n */\nint fdt_move(const void *fdt, void *buf, int bufsize);\n\n/**********************************************************************/\n/* Read-only functions                                                */\n/**********************************************************************/\n\nint fdt_check_full(const void *fdt, size_t bufsize);\n\n/**\n * fdt_get_string - retrieve a string from the strings block of a device tree\n * @fdt: pointer to the device tree blob\n * @stroffset: offset of the string within the strings block (native endian)\n * @lenp: optional pointer to return the string's length\n *\n * fdt_get_string() retrieves a pointer to a single string from the\n * strings block of the device tree blob at fdt, and optionally also\n * returns the string's length in *lenp.\n *\n * returns:\n *     a pointer to the string, on success\n *     NULL, if stroffset is out of bounds, or doesn't point to a valid string\n */\nconst char *fdt_get_string(const void *fdt, int stroffset, int *lenp);\n\n/**\n * fdt_string - retrieve a string from the strings block of a device tree\n * @fdt: pointer to the device tree blob\n * @stroffset: offset of the string within the strings block (native endian)\n *\n * fdt_string() retrieves a pointer to a single string from the\n * strings block of the device tree blob at fdt.\n *\n * returns:\n *     a pointer to the string, on success\n *     NULL, if stroffset is out of bounds, or doesn't point to a valid string\n */\nconst char *fdt_string(const void *fdt, int stroffset);\n\n/**\n * fdt_get_max_phandle - retrieves the highest phandle in a tree\n * @fdt: pointer to the device tree blob\n *\n * fdt_get_max_phandle retrieves the highest phandle in the given\n * device tree. This will ignore badly formatted phandles, or phandles\n * with a value of 0 or -1.\n *\n * returns:\n *      the highest phandle on success\n *      0, if no phandle was found in the device tree\n *      -1, if an error occurred\n */\nuint32_t fdt_get_max_phandle(const void *fdt);\n\n/**\n * fdt_num_mem_rsv - retrieve the number of memory reserve map entries\n * @fdt: pointer to the device tree blob\n *\n * Returns the number of entries in the device tree blob's memory\n * reservation map.  This does not include the terminating 0,0 entry\n * or any other (0,0) entries reserved for expansion.\n *\n * returns:\n *     the number of entries\n */\nint fdt_num_mem_rsv(const void *fdt);\n\n/**\n * fdt_get_mem_rsv - retrieve one memory reserve map entry\n * @fdt: pointer to the device tree blob\n * @address, @size: pointers to 64-bit variables\n *\n * On success, *address and *size will contain the address and size of\n * the n-th reserve map entry from the device tree blob, in\n * native-endian format.\n *\n * returns:\n *     0, on success\n *     -FDT_ERR_BADMAGIC,\n *     -FDT_ERR_BADVERSION,\n *     -FDT_ERR_BADSTATE, standard meanings\n */\nint fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);\n\n/**\n * fdt_subnode_offset_namelen - find a subnode based on substring\n * @fdt: pointer to the device tree blob\n * @parentoffset: structure block offset of a node\n * @name: name of the subnode to locate\n * @namelen: number of characters of name to consider\n *\n * Identical to fdt_subnode_offset(), but only examine the first\n * namelen characters of name for matching the subnode name.  This is\n * useful for finding subnodes based on a portion of a larger string,\n * such as a full path.\n */\n#ifndef SWIG /* Not available in Python */\nint fdt_subnode_offset_namelen(const void *fdt, int parentoffset,\n\t\t\t       const char *name, int namelen);\n#endif\n/**\n * fdt_subnode_offset - find a subnode of a given node\n * @fdt: pointer to the device tree blob\n * @parentoffset: structure block offset of a node\n * @name: name of the subnode to locate\n *\n * fdt_subnode_offset() finds a subnode of the node at structure block\n * offset parentoffset with the given name.  name may include a unit\n * address, in which case fdt_subnode_offset() will find the subnode\n * with that unit address, or the unit address may be omitted, in\n * which case fdt_subnode_offset() will find an arbitrary subnode\n * whose name excluding unit address matches the given name.\n *\n * returns:\n *\tstructure block offset of the requested subnode (>=0), on success\n *\t-FDT_ERR_NOTFOUND, if the requested subnode does not exist\n *\t-FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE\n *\t\ttag\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings.\n */\nint fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);\n\n/**\n * fdt_path_offset_namelen - find a tree node by its full path\n * @fdt: pointer to the device tree blob\n * @path: full path of the node to locate\n * @namelen: number of characters of path to consider\n *\n * Identical to fdt_path_offset(), but only consider the first namelen\n * characters of path as the path name.\n */\n#ifndef SWIG /* Not available in Python */\nint fdt_path_offset_namelen(const void *fdt, const char *path, int namelen);\n#endif\n\n/**\n * fdt_path_offset - find a tree node by its full path\n * @fdt: pointer to the device tree blob\n * @path: full path of the node to locate\n *\n * fdt_path_offset() finds a node of a given path in the device tree.\n * Each path component may omit the unit address portion, but the\n * results of this are undefined if any such path component is\n * ambiguous (that is if there are multiple nodes at the relevant\n * level matching the given component, differentiated only by unit\n * address).\n *\n * returns:\n *\tstructure block offset of the node with the requested path (>=0), on\n *\t\tsuccess\n *\t-FDT_ERR_BADPATH, given path does not begin with '/' or is invalid\n *\t-FDT_ERR_NOTFOUND, if the requested node does not exist\n *      -FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings.\n */\nint fdt_path_offset(const void *fdt, const char *path);\n\n/**\n * fdt_get_name - retrieve the name of a given node\n * @fdt: pointer to the device tree blob\n * @nodeoffset: structure block offset of the starting node\n * @lenp: pointer to an integer variable (will be overwritten) or NULL\n *\n * fdt_get_name() retrieves the name (including unit address) of the\n * device tree node at structure block offset nodeoffset.  If lenp is\n * non-NULL, the length of this name is also returned, in the integer\n * pointed to by lenp.\n *\n * returns:\n *\tpointer to the node's name, on success\n *\t\tIf lenp is non-NULL, *lenp contains the length of that name\n *\t\t\t(>=0)\n *\tNULL, on error\n *\t\tif lenp is non-NULL *lenp contains an error code (<0):\n *\t\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE\n *\t\t\ttag\n *\t\t-FDT_ERR_BADMAGIC,\n *\t\t-FDT_ERR_BADVERSION,\n *\t\t-FDT_ERR_BADSTATE, standard meanings\n */\nconst char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);\n\n/**\n * fdt_first_property_offset - find the offset of a node's first property\n * @fdt: pointer to the device tree blob\n * @nodeoffset: structure block offset of a node\n *\n * fdt_first_property_offset() finds the first property of the node at\n * the given structure block offset.\n *\n * returns:\n *\tstructure block offset of the property (>=0), on success\n *\t-FDT_ERR_NOTFOUND, if the requested node has no properties\n *\t-FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_BEGIN_NODE tag\n *      -FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings.\n */\nint fdt_first_property_offset(const void *fdt, int nodeoffset);\n\n/**\n * fdt_next_property_offset - step through a node's properties\n * @fdt: pointer to the device tree blob\n * @offset: structure block offset of a property\n *\n * fdt_next_property_offset() finds the property immediately after the\n * one at the given structure block offset.  This will be a property\n * of the same node as the given property.\n *\n * returns:\n *\tstructure block offset of the next property (>=0), on success\n *\t-FDT_ERR_NOTFOUND, if the given property is the last in its node\n *\t-FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_PROP tag\n *      -FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings.\n */\nint fdt_next_property_offset(const void *fdt, int offset);\n\n/**\n * fdt_for_each_property_offset - iterate over all properties of a node\n *\n * @property_offset:\tproperty offset (int, lvalue)\n * @fdt:\t\tFDT blob (const void *)\n * @node:\t\tnode offset (int)\n *\n * This is actually a wrapper around a for loop and would be used like so:\n *\n *\tfdt_for_each_property_offset(property, fdt, node) {\n *\t\tUse property\n *\t\t...\n *\t}\n *\n *\tif ((property < 0) && (property != -FDT_ERR_NOT_FOUND)) {\n *\t\tError handling\n *\t}\n *\n * Note that this is implemented as a macro and property is used as\n * iterator in the loop. The node variable can be constant or even a\n * literal.\n */\n#define fdt_for_each_property_offset(property, fdt, node)\t\\\n\tfor (property = fdt_first_property_offset(fdt, node);\t\\\n\t     property >= 0;\t\t\t\t\t\\\n\t     property = fdt_next_property_offset(fdt, property))\n\n/**\n * fdt_get_property_by_offset - retrieve the property at a given offset\n * @fdt: pointer to the device tree blob\n * @offset: offset of the property to retrieve\n * @lenp: pointer to an integer variable (will be overwritten) or NULL\n *\n * fdt_get_property_by_offset() retrieves a pointer to the\n * fdt_property structure within the device tree blob at the given\n * offset.  If lenp is non-NULL, the length of the property value is\n * also returned, in the integer pointed to by lenp.\n *\n * Note that this code only works on device tree versions >= 16. fdt_getprop()\n * works on all versions.\n *\n * returns:\n *\tpointer to the structure representing the property\n *\t\tif lenp is non-NULL, *lenp contains the length of the property\n *\t\tvalue (>=0)\n *\tNULL, on error\n *\t\tif lenp is non-NULL, *lenp contains an error code (<0):\n *\t\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag\n *\t\t-FDT_ERR_BADMAGIC,\n *\t\t-FDT_ERR_BADVERSION,\n *\t\t-FDT_ERR_BADSTATE,\n *\t\t-FDT_ERR_BADSTRUCTURE,\n *\t\t-FDT_ERR_TRUNCATED, standard meanings\n */\nconst struct fdt_property *fdt_get_property_by_offset(const void *fdt,\n\t\t\t\t\t\t      int offset,\n\t\t\t\t\t\t      int *lenp);\n\n/**\n * fdt_get_property_namelen - find a property based on substring\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to find\n * @name: name of the property to find\n * @namelen: number of characters of name to consider\n * @lenp: pointer to an integer variable (will be overwritten) or NULL\n *\n * Identical to fdt_get_property(), but only examine the first namelen\n * characters of name for matching the property name.\n */\n#ifndef SWIG /* Not available in Python */\nconst struct fdt_property *fdt_get_property_namelen(const void *fdt,\n\t\t\t\t\t\t    int nodeoffset,\n\t\t\t\t\t\t    const char *name,\n\t\t\t\t\t\t    int namelen, int *lenp);\n#endif\n\n/**\n * fdt_get_property - find a given property in a given node\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to find\n * @name: name of the property to find\n * @lenp: pointer to an integer variable (will be overwritten) or NULL\n *\n * fdt_get_property() retrieves a pointer to the fdt_property\n * structure within the device tree blob corresponding to the property\n * named 'name' of the node at offset nodeoffset.  If lenp is\n * non-NULL, the length of the property value is also returned, in the\n * integer pointed to by lenp.\n *\n * returns:\n *\tpointer to the structure representing the property\n *\t\tif lenp is non-NULL, *lenp contains the length of the property\n *\t\tvalue (>=0)\n *\tNULL, on error\n *\t\tif lenp is non-NULL, *lenp contains an error code (<0):\n *\t\t-FDT_ERR_NOTFOUND, node does not have named property\n *\t\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE\n *\t\t\ttag\n *\t\t-FDT_ERR_BADMAGIC,\n *\t\t-FDT_ERR_BADVERSION,\n *\t\t-FDT_ERR_BADSTATE,\n *\t\t-FDT_ERR_BADSTRUCTURE,\n *\t\t-FDT_ERR_TRUNCATED, standard meanings\n */\nconst struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset,\n\t\t\t\t\t    const char *name, int *lenp);\nstatic inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,\n\t\t\t\t\t\t      const char *name,\n\t\t\t\t\t\t      int *lenp)\n{\n\treturn (struct fdt_property *)(uintptr_t)\n\t\tfdt_get_property(fdt, nodeoffset, name, lenp);\n}\n\n/**\n * fdt_getprop_by_offset - retrieve the value of a property at a given offset\n * @fdt: pointer to the device tree blob\n * @ffset: offset of the property to read\n * @namep: pointer to a string variable (will be overwritten) or NULL\n * @lenp: pointer to an integer variable (will be overwritten) or NULL\n *\n * fdt_getprop_by_offset() retrieves a pointer to the value of the\n * property at structure block offset 'offset' (this will be a pointer\n * to within the device blob itself, not a copy of the value).  If\n * lenp is non-NULL, the length of the property value is also\n * returned, in the integer pointed to by lenp.  If namep is non-NULL,\n * the property's namne will also be returned in the char * pointed to\n * by namep (this will be a pointer to within the device tree's string\n * block, not a new copy of the name).\n *\n * returns:\n *\tpointer to the property's value\n *\t\tif lenp is non-NULL, *lenp contains the length of the property\n *\t\tvalue (>=0)\n *\t\tif namep is non-NULL *namep contiains a pointer to the property\n *\t\tname.\n *\tNULL, on error\n *\t\tif lenp is non-NULL, *lenp contains an error code (<0):\n *\t\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag\n *\t\t-FDT_ERR_BADMAGIC,\n *\t\t-FDT_ERR_BADVERSION,\n *\t\t-FDT_ERR_BADSTATE,\n *\t\t-FDT_ERR_BADSTRUCTURE,\n *\t\t-FDT_ERR_TRUNCATED, standard meanings\n */\n#ifndef SWIG /* This function is not useful in Python */\nconst void *fdt_getprop_by_offset(const void *fdt, int offset,\n\t\t\t\t  const char **namep, int *lenp);\n#endif\n\n/**\n * fdt_getprop_namelen - get property value based on substring\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to find\n * @name: name of the property to find\n * @namelen: number of characters of name to consider\n * @lenp: pointer to an integer variable (will be overwritten) or NULL\n *\n * Identical to fdt_getprop(), but only examine the first namelen\n * characters of name for matching the property name.\n */\n#ifndef SWIG /* Not available in Python */\nconst void *fdt_getprop_namelen(const void *fdt, int nodeoffset,\n\t\t\t\tconst char *name, int namelen, int *lenp);\nstatic inline void *fdt_getprop_namelen_w(void *fdt, int nodeoffset,\n\t\t\t\t\t  const char *name, int namelen,\n\t\t\t\t\t  int *lenp)\n{\n\treturn (void *)(uintptr_t)fdt_getprop_namelen(fdt, nodeoffset, name,\n\t\t\t\t\t\t      namelen, lenp);\n}\n#endif\n\n/**\n * fdt_getprop - retrieve the value of a given property\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to find\n * @name: name of the property to find\n * @lenp: pointer to an integer variable (will be overwritten) or NULL\n *\n * fdt_getprop() retrieves a pointer to the value of the property\n * named 'name' of the node at offset nodeoffset (this will be a\n * pointer to within the device blob itself, not a copy of the value).\n * If lenp is non-NULL, the length of the property value is also\n * returned, in the integer pointed to by lenp.\n *\n * returns:\n *\tpointer to the property's value\n *\t\tif lenp is non-NULL, *lenp contains the length of the property\n *\t\tvalue (>=0)\n *\tNULL, on error\n *\t\tif lenp is non-NULL, *lenp contains an error code (<0):\n *\t\t-FDT_ERR_NOTFOUND, node does not have named property\n *\t\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE\n *\t\t\ttag\n *\t\t-FDT_ERR_BADMAGIC,\n *\t\t-FDT_ERR_BADVERSION,\n *\t\t-FDT_ERR_BADSTATE,\n *\t\t-FDT_ERR_BADSTRUCTURE,\n *\t\t-FDT_ERR_TRUNCATED, standard meanings\n */\nconst void *fdt_getprop(const void *fdt, int nodeoffset,\n\t\t\tconst char *name, int *lenp);\nstatic inline void *fdt_getprop_w(void *fdt, int nodeoffset,\n\t\t\t\t  const char *name, int *lenp)\n{\n\treturn (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp);\n}\n\n/**\n * fdt_get_phandle - retrieve the phandle of a given node\n * @fdt: pointer to the device tree blob\n * @nodeoffset: structure block offset of the node\n *\n * fdt_get_phandle() retrieves the phandle of the device tree node at\n * structure block offset nodeoffset.\n *\n * returns:\n *\tthe phandle of the node at nodeoffset, on success (!= 0, != -1)\n *\t0, if the node has no phandle, or another error occurs\n */\nuint32_t fdt_get_phandle(const void *fdt, int nodeoffset);\n\n/**\n * fdt_get_alias_namelen - get alias based on substring\n * @fdt: pointer to the device tree blob\n * @name: name of the alias th look up\n * @namelen: number of characters of name to consider\n *\n * Identical to fdt_get_alias(), but only examine the first namelen\n * characters of name for matching the alias name.\n */\n#ifndef SWIG /* Not available in Python */\nconst char *fdt_get_alias_namelen(const void *fdt,\n\t\t\t\t  const char *name, int namelen);\n#endif\n\n/**\n * fdt_get_alias - retrieve the path referenced by a given alias\n * @fdt: pointer to the device tree blob\n * @name: name of the alias th look up\n *\n * fdt_get_alias() retrieves the value of a given alias.  That is, the\n * value of the property named 'name' in the node /aliases.\n *\n * returns:\n *\ta pointer to the expansion of the alias named 'name', if it exists\n *\tNULL, if the given alias or the /aliases node does not exist\n */\nconst char *fdt_get_alias(const void *fdt, const char *name);\n\n/**\n * fdt_get_path - determine the full path of a node\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose path to find\n * @buf: character buffer to contain the returned path (will be overwritten)\n * @buflen: size of the character buffer at buf\n *\n * fdt_get_path() computes the full path of the node at offset\n * nodeoffset, and records that path in the buffer at buf.\n *\n * NOTE: This function is expensive, as it must scan the device tree\n * structure from the start to nodeoffset.\n *\n * returns:\n *\t0, on success\n *\t\tbuf contains the absolute path of the node at\n *\t\tnodeoffset, as a NUL-terminated string.\n *\t-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag\n *\t-FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1)\n *\t\tcharacters and will not fit in the given buffer.\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE, standard meanings\n */\nint fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen);\n\n/**\n * fdt_supernode_atdepth_offset - find a specific ancestor of a node\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose parent to find\n * @supernodedepth: depth of the ancestor to find\n * @nodedepth: pointer to an integer variable (will be overwritten) or NULL\n *\n * fdt_supernode_atdepth_offset() finds an ancestor of the given node\n * at a specific depth from the root (where the root itself has depth\n * 0, its immediate subnodes depth 1 and so forth).  So\n *\tfdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL);\n * will always return 0, the offset of the root node.  If the node at\n * nodeoffset has depth D, then:\n *\tfdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL);\n * will return nodeoffset itself.\n *\n * NOTE: This function is expensive, as it must scan the device tree\n * structure from the start to nodeoffset.\n *\n * returns:\n *\tstructure block offset of the node at node offset's ancestor\n *\t\tof depth supernodedepth (>=0), on success\n *\t-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag\n *\t-FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of\n *\t\tnodeoffset\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE, standard meanings\n */\nint fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,\n\t\t\t\t int supernodedepth, int *nodedepth);\n\n/**\n * fdt_node_depth - find the depth of a given node\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose parent to find\n *\n * fdt_node_depth() finds the depth of a given node.  The root node\n * has depth 0, its immediate subnodes depth 1 and so forth.\n *\n * NOTE: This function is expensive, as it must scan the device tree\n * structure from the start to nodeoffset.\n *\n * returns:\n *\tdepth of the node at nodeoffset (>=0), on success\n *\t-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE, standard meanings\n */\nint fdt_node_depth(const void *fdt, int nodeoffset);\n\n/**\n * fdt_parent_offset - find the parent of a given node\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose parent to find\n *\n * fdt_parent_offset() locates the parent node of a given node (that\n * is, it finds the offset of the node which contains the node at\n * nodeoffset as a subnode).\n *\n * NOTE: This function is expensive, as it must scan the device tree\n * structure from the start to nodeoffset, *twice*.\n *\n * returns:\n *\tstructure block offset of the parent of the node at nodeoffset\n *\t\t(>=0), on success\n *\t-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE, standard meanings\n */\nint fdt_parent_offset(const void *fdt, int nodeoffset);\n\n/**\n * fdt_node_offset_by_prop_value - find nodes with a given property value\n * @fdt: pointer to the device tree blob\n * @startoffset: only find nodes after this offset\n * @propname: property name to check\n * @propval: property value to search for\n * @proplen: length of the value in propval\n *\n * fdt_node_offset_by_prop_value() returns the offset of the first\n * node after startoffset, which has a property named propname whose\n * value is of length proplen and has value equal to propval; or if\n * startoffset is -1, the very first such node in the tree.\n *\n * To iterate through all nodes matching the criterion, the following\n * idiom can be used:\n *\toffset = fdt_node_offset_by_prop_value(fdt, -1, propname,\n *\t\t\t\t\t       propval, proplen);\n *\twhile (offset != -FDT_ERR_NOTFOUND) {\n *\t\t// other code here\n *\t\toffset = fdt_node_offset_by_prop_value(fdt, offset, propname,\n *\t\t\t\t\t\t       propval, proplen);\n *\t}\n *\n * Note the -1 in the first call to the function, if 0 is used here\n * instead, the function will never locate the root node, even if it\n * matches the criterion.\n *\n * returns:\n *\tstructure block offset of the located node (>= 0, >startoffset),\n *\t\t on success\n *\t-FDT_ERR_NOTFOUND, no node matching the criterion exists in the\n *\t\ttree after startoffset\n *\t-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE, standard meanings\n */\nint fdt_node_offset_by_prop_value(const void *fdt, int startoffset,\n\t\t\t\t  const char *propname,\n\t\t\t\t  const void *propval, int proplen);\n\n/**\n * fdt_node_offset_by_phandle - find the node with a given phandle\n * @fdt: pointer to the device tree blob\n * @phandle: phandle value\n *\n * fdt_node_offset_by_phandle() returns the offset of the node\n * which has the given phandle value.  If there is more than one node\n * in the tree with the given phandle (an invalid tree), results are\n * undefined.\n *\n * returns:\n *\tstructure block offset of the located node (>= 0), on success\n *\t-FDT_ERR_NOTFOUND, no node with that phandle exists\n *\t-FDT_ERR_BADPHANDLE, given phandle value was invalid (0 or -1)\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE, standard meanings\n */\nint fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);\n\n/**\n * fdt_node_check_compatible: check a node's compatible property\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of a tree node\n * @compatible: string to match against\n *\n *\n * fdt_node_check_compatible() returns 0 if the given node contains a\n * 'compatible' property with the given string as one of its elements,\n * it returns non-zero otherwise, or on error.\n *\n * returns:\n *\t0, if the node has a 'compatible' property listing the given string\n *\t1, if the node has a 'compatible' property, but it does not list\n *\t\tthe given string\n *\t-FDT_ERR_NOTFOUND, if the given node has no 'compatible' property\n *\t-FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE, standard meanings\n */\nint fdt_node_check_compatible(const void *fdt, int nodeoffset,\n\t\t\t      const char *compatible);\n\n/**\n * fdt_node_offset_by_compatible - find nodes with a given 'compatible' value\n * @fdt: pointer to the device tree blob\n * @startoffset: only find nodes after this offset\n * @compatible: 'compatible' string to match against\n *\n * fdt_node_offset_by_compatible() returns the offset of the first\n * node after startoffset, which has a 'compatible' property which\n * lists the given compatible string; or if startoffset is -1, the\n * very first such node in the tree.\n *\n * To iterate through all nodes matching the criterion, the following\n * idiom can be used:\n *\toffset = fdt_node_offset_by_compatible(fdt, -1, compatible);\n *\twhile (offset != -FDT_ERR_NOTFOUND) {\n *\t\t// other code here\n *\t\toffset = fdt_node_offset_by_compatible(fdt, offset, compatible);\n *\t}\n *\n * Note the -1 in the first call to the function, if 0 is used here\n * instead, the function will never locate the root node, even if it\n * matches the criterion.\n *\n * returns:\n *\tstructure block offset of the located node (>= 0, >startoffset),\n *\t\t on success\n *\t-FDT_ERR_NOTFOUND, no node matching the criterion exists in the\n *\t\ttree after startoffset\n *\t-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE, standard meanings\n */\nint fdt_node_offset_by_compatible(const void *fdt, int startoffset,\n\t\t\t\t  const char *compatible);\n\n/**\n * fdt_stringlist_contains - check a string list property for a string\n * @strlist: Property containing a list of strings to check\n * @listlen: Length of property\n * @str: String to search for\n *\n * This is a utility function provided for convenience. The list contains\n * one or more strings, each terminated by \\0, as is found in a device tree\n * \"compatible\" property.\n *\n * @return: 1 if the string is found in the list, 0 not found, or invalid list\n */\nint fdt_stringlist_contains(const char *strlist, int listlen, const char *str);\n\n/**\n * fdt_stringlist_count - count the number of strings in a string list\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of a tree node\n * @property: name of the property containing the string list\n * @return:\n *   the number of strings in the given property\n *   -FDT_ERR_BADVALUE if the property value is not NUL-terminated\n *   -FDT_ERR_NOTFOUND if the property does not exist\n */\nint fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property);\n\n/**\n * fdt_stringlist_search - find a string in a string list and return its index\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of a tree node\n * @property: name of the property containing the string list\n * @string: string to look up in the string list\n *\n * Note that it is possible for this function to succeed on property values\n * that are not NUL-terminated. That's because the function will stop after\n * finding the first occurrence of @string. This can for example happen with\n * small-valued cell properties, such as #address-cells, when searching for\n * the empty string.\n *\n * @return:\n *   the index of the string in the list of strings\n *   -FDT_ERR_BADVALUE if the property value is not NUL-terminated\n *   -FDT_ERR_NOTFOUND if the property does not exist or does not contain\n *                     the given string\n */\nint fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property,\n\t\t\t  const char *string);\n\n/**\n * fdt_stringlist_get() - obtain the string at a given index in a string list\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of a tree node\n * @property: name of the property containing the string list\n * @index: index of the string to return\n * @lenp: return location for the string length or an error code on failure\n *\n * Note that this will successfully extract strings from properties with\n * non-NUL-terminated values. For example on small-valued cell properties\n * this function will return the empty string.\n *\n * If non-NULL, the length of the string (on success) or a negative error-code\n * (on failure) will be stored in the integer pointer to by lenp.\n *\n * @return:\n *   A pointer to the string at the given index in the string list or NULL on\n *   failure. On success the length of the string will be stored in the memory\n *   location pointed to by the lenp parameter, if non-NULL. On failure one of\n *   the following negative error codes will be returned in the lenp parameter\n *   (if non-NULL):\n *     -FDT_ERR_BADVALUE if the property value is not NUL-terminated\n *     -FDT_ERR_NOTFOUND if the property does not exist\n */\nconst char *fdt_stringlist_get(const void *fdt, int nodeoffset,\n\t\t\t       const char *property, int index,\n\t\t\t       int *lenp);\n\n/**********************************************************************/\n/* Read-only functions (addressing related)                           */\n/**********************************************************************/\n\n/**\n * FDT_MAX_NCELLS - maximum value for #address-cells and #size-cells\n *\n * This is the maximum value for #address-cells, #size-cells and\n * similar properties that will be processed by libfdt.  IEE1275\n * requires that OF implementations handle values up to 4.\n * Implementations may support larger values, but in practice higher\n * values aren't used.\n */\n#define FDT_MAX_NCELLS\t\t4\n\n/**\n * fdt_address_cells - retrieve address size for a bus represented in the tree\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node to find the address size for\n *\n * When the node has a valid #address-cells property, returns its value.\n *\n * returns:\n *\t0 <= n < FDT_MAX_NCELLS, on success\n *      2, if the node has no #address-cells property\n *      -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid\n *\t\t#address-cells property\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nint fdt_address_cells(const void *fdt, int nodeoffset);\n\n/**\n * fdt_size_cells - retrieve address range size for a bus represented in the\n *                  tree\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node to find the address range size for\n *\n * When the node has a valid #size-cells property, returns its value.\n *\n * returns:\n *\t0 <= n < FDT_MAX_NCELLS, on success\n *      2, if the node has no #size-cells property\n *      -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid\n *\t\t#size-cells property\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nint fdt_size_cells(const void *fdt, int nodeoffset);\n\n\n/**********************************************************************/\n/* Write-in-place functions                                           */\n/**********************************************************************/\n\n/**\n * fdt_setprop_inplace_namelen_partial - change a property's value,\n *                                       but not its size\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n * @namelen: number of characters of name to consider\n * @idx: index of the property to change in the array\n * @val: pointer to data to replace the property value with\n * @len: length of the property value\n *\n * Identical to fdt_setprop_inplace(), but modifies the given property\n * starting from the given index, and using only the first characters\n * of the name. It is useful when you want to manipulate only one value of\n * an array and you have a string that doesn't end with \\0.\n */\n#ifndef SWIG /* Not available in Python */\nint fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset,\n\t\t\t\t\tconst char *name, int namelen,\n\t\t\t\t\tuint32_t idx, const void *val,\n\t\t\t\t\tint len);\n#endif\n\n/**\n * fdt_setprop_inplace - change a property's value, but not its size\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n * @val: pointer to data to replace the property value with\n * @len: length of the property value\n *\n * fdt_setprop_inplace() replaces the value of a given property with\n * the data in val, of length len.  This function cannot change the\n * size of a property, and so will only work if len is equal to the\n * current length of the property.\n *\n * This function will alter only the bytes in the blob which contain\n * the given property value, and will not alter or move any other part\n * of the tree.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, if len is not equal to the property's current length\n *\t-FDT_ERR_NOTFOUND, node does not have the named property\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\n#ifndef SWIG /* Not available in Python */\nint fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,\n\t\t\tconst void *val, int len);\n#endif\n\n/**\n * fdt_setprop_inplace_u32 - change the value of a 32-bit integer property\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n * @val: 32-bit integer value to replace the property with\n *\n * fdt_setprop_inplace_u32() replaces the value of a given property\n * with the 32-bit integer value in val, converting val to big-endian\n * if necessary.  This function cannot change the size of a property,\n * and so will only work if the property already exists and has length\n * 4.\n *\n * This function will alter only the bytes in the blob which contain\n * the given property value, and will not alter or move any other part\n * of the tree.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, if the property's length is not equal to 4\n *\t-FDT_ERR_NOTFOUND, node does not have the named property\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nstatic inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset,\n\t\t\t\t\t  const char *name, uint32_t val)\n{\n\tfdt32_t tmp = cpu_to_fdt32(val);\n\treturn fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp));\n}\n\n/**\n * fdt_setprop_inplace_u64 - change the value of a 64-bit integer property\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n * @val: 64-bit integer value to replace the property with\n *\n * fdt_setprop_inplace_u64() replaces the value of a given property\n * with the 64-bit integer value in val, converting val to big-endian\n * if necessary.  This function cannot change the size of a property,\n * and so will only work if the property already exists and has length\n * 8.\n *\n * This function will alter only the bytes in the blob which contain\n * the given property value, and will not alter or move any other part\n * of the tree.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, if the property's length is not equal to 8\n *\t-FDT_ERR_NOTFOUND, node does not have the named property\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nstatic inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset,\n\t\t\t\t\t  const char *name, uint64_t val)\n{\n\tfdt64_t tmp = cpu_to_fdt64(val);\n\treturn fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp));\n}\n\n/**\n * fdt_setprop_inplace_cell - change the value of a single-cell property\n *\n * This is an alternative name for fdt_setprop_inplace_u32()\n */\nstatic inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,\n\t\t\t\t\t   const char *name, uint32_t val)\n{\n\treturn fdt_setprop_inplace_u32(fdt, nodeoffset, name, val);\n}\n\n/**\n * fdt_nop_property - replace a property with nop tags\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to nop\n * @name: name of the property to nop\n *\n * fdt_nop_property() will replace a given property's representation\n * in the blob with FDT_NOP tags, effectively removing it from the\n * tree.\n *\n * This function will alter only the bytes in the blob which contain\n * the property, and will not alter or move any other part of the\n * tree.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOTFOUND, node does not have the named property\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nint fdt_nop_property(void *fdt, int nodeoffset, const char *name);\n\n/**\n * fdt_nop_node - replace a node (subtree) with nop tags\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node to nop\n *\n * fdt_nop_node() will replace a given node's representation in the\n * blob, including all its subnodes, if any, with FDT_NOP tags,\n * effectively removing it from the tree.\n *\n * This function will alter only the bytes in the blob which contain\n * the node and its properties and subnodes, and will not alter or\n * move any other part of the tree.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nint fdt_nop_node(void *fdt, int nodeoffset);\n\n/**********************************************************************/\n/* Sequential write functions                                         */\n/**********************************************************************/\n\nint fdt_create(void *buf, int bufsize);\nint fdt_resize(void *fdt, void *buf, int bufsize);\nint fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);\nint fdt_finish_reservemap(void *fdt);\nint fdt_begin_node(void *fdt, const char *name);\nint fdt_property(void *fdt, const char *name, const void *val, int len);\nstatic inline int fdt_property_u32(void *fdt, const char *name, uint32_t val)\n{\n\tfdt32_t tmp = cpu_to_fdt32(val);\n\treturn fdt_property(fdt, name, &tmp, sizeof(tmp));\n}\nstatic inline int fdt_property_u64(void *fdt, const char *name, uint64_t val)\n{\n\tfdt64_t tmp = cpu_to_fdt64(val);\n\treturn fdt_property(fdt, name, &tmp, sizeof(tmp));\n}\n\n#ifndef SWIG /* Not available in Python */\nstatic inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)\n{\n\treturn fdt_property_u32(fdt, name, val);\n}\n#endif\n\n/**\n * fdt_property_placeholder - add a new property and return a ptr to its value\n *\n * @fdt: pointer to the device tree blob\n * @name: name of property to add\n * @len: length of property value in bytes\n * @valp: returns a pointer to where where the value should be placed\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_NOSPACE, standard meanings\n */\nint fdt_property_placeholder(void *fdt, const char *name, int len, void **valp);\n\n#define fdt_property_string(fdt, name, str) \\\n\tfdt_property(fdt, name, str, strlen(str)+1)\nint fdt_end_node(void *fdt);\nint fdt_finish(void *fdt);\n\n/**********************************************************************/\n/* Read-write functions                                               */\n/**********************************************************************/\n\nint fdt_create_empty_tree(void *buf, int bufsize);\nint fdt_open_into(const void *fdt, void *buf, int bufsize);\nint fdt_pack(void *fdt);\n\n/**\n * fdt_add_mem_rsv - add one memory reserve map entry\n * @fdt: pointer to the device tree blob\n * @address, @size: 64-bit values (native endian)\n *\n * Adds a reserve map entry to the given blob reserving a region at\n * address address of length size.\n *\n * This function will insert data into the reserve map and will\n * therefore change the indexes of some entries in the table.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there is insufficient free space in the blob to\n *\t\tcontain the new reservation entry\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nint fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);\n\n/**\n * fdt_del_mem_rsv - remove a memory reserve map entry\n * @fdt: pointer to the device tree blob\n * @n: entry to remove\n *\n * fdt_del_mem_rsv() removes the n-th memory reserve map entry from\n * the blob.\n *\n * This function will delete data from the reservation table and will\n * therefore change the indexes of some entries in the table.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOTFOUND, there is no entry of the given index (i.e. there\n *\t\tare less than n+1 reserve map entries)\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nint fdt_del_mem_rsv(void *fdt, int n);\n\n/**\n * fdt_set_name - change the name of a given node\n * @fdt: pointer to the device tree blob\n * @nodeoffset: structure block offset of a node\n * @name: name to give the node\n *\n * fdt_set_name() replaces the name (including unit address, if any)\n * of the given node with the given string.  NOTE: this function can't\n * efficiently check if the new name is unique amongst the given\n * node's siblings; results are undefined if this function is invoked\n * with a name equal to one of the given node's siblings.\n *\n * This function may insert or delete data from the blob, and will\n * therefore change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there is insufficient free space in the blob\n *\t\tto contain the new name\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE, standard meanings\n */\nint fdt_set_name(void *fdt, int nodeoffset, const char *name);\n\n/**\n * fdt_setprop - create or change a property\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n * @val: pointer to data to set the property value to\n * @len: length of the property value\n *\n * fdt_setprop() sets the value of the named property in the given\n * node to the given value and length, creating the property if it\n * does not already exist.\n *\n * This function may insert or delete data from the blob, and will\n * therefore change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there is insufficient free space in the blob to\n *\t\tcontain the new property value\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nint fdt_setprop(void *fdt, int nodeoffset, const char *name,\n\t\tconst void *val, int len);\n\n/**\n * fdt_setprop_placeholder - allocate space for a property\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n * @len: length of the property value\n * @prop_data: return pointer to property data\n *\n * fdt_setprop_placeholer() allocates the named property in the given node.\n * If the property exists it is resized. In either case a pointer to the\n * property data is returned.\n *\n * This function may insert or delete data from the blob, and will\n * therefore change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there is insufficient free space in the blob to\n *\t\tcontain the new property value\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nint fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,\n\t\t\t    int len, void **prop_data);\n\n/**\n * fdt_setprop_u32 - set a property to a 32-bit integer\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n * @val: 32-bit integer value for the property (native endian)\n *\n * fdt_setprop_u32() sets the value of the named property in the given\n * node to the given 32-bit integer value (converting to big-endian if\n * necessary), or creates a new property with that value if it does\n * not already exist.\n *\n * This function may insert or delete data from the blob, and will\n * therefore change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there is insufficient free space in the blob to\n *\t\tcontain the new property value\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nstatic inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name,\n\t\t\t\t  uint32_t val)\n{\n\tfdt32_t tmp = cpu_to_fdt32(val);\n\treturn fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));\n}\n\n/**\n * fdt_setprop_u64 - set a property to a 64-bit integer\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n * @val: 64-bit integer value for the property (native endian)\n *\n * fdt_setprop_u64() sets the value of the named property in the given\n * node to the given 64-bit integer value (converting to big-endian if\n * necessary), or creates a new property with that value if it does\n * not already exist.\n *\n * This function may insert or delete data from the blob, and will\n * therefore change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there is insufficient free space in the blob to\n *\t\tcontain the new property value\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nstatic inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name,\n\t\t\t\t  uint64_t val)\n{\n\tfdt64_t tmp = cpu_to_fdt64(val);\n\treturn fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));\n}\n\n/**\n * fdt_setprop_cell - set a property to a single cell value\n *\n * This is an alternative name for fdt_setprop_u32()\n */\nstatic inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,\n\t\t\t\t   uint32_t val)\n{\n\treturn fdt_setprop_u32(fdt, nodeoffset, name, val);\n}\n\n/**\n * fdt_setprop_string - set a property to a string value\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n * @str: string value for the property\n *\n * fdt_setprop_string() sets the value of the named property in the\n * given node to the given string value (using the length of the\n * string to determine the new length of the property), or creates a\n * new property with that value if it does not already exist.\n *\n * This function may insert or delete data from the blob, and will\n * therefore change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there is insufficient free space in the blob to\n *\t\tcontain the new property value\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\n#define fdt_setprop_string(fdt, nodeoffset, name, str) \\\n\tfdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)\n\n\n/**\n * fdt_setprop_empty - set a property to an empty value\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n *\n * fdt_setprop_empty() sets the value of the named property in the\n * given node to an empty (zero length) value, or creates a new empty\n * property if it does not already exist.\n *\n * This function may insert or delete data from the blob, and will\n * therefore change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there is insufficient free space in the blob to\n *\t\tcontain the new property value\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\n#define fdt_setprop_empty(fdt, nodeoffset, name) \\\n\tfdt_setprop((fdt), (nodeoffset), (name), NULL, 0)\n\n/**\n * fdt_appendprop - append to or create a property\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to append to\n * @val: pointer to data to append to the property value\n * @len: length of the data to append to the property value\n *\n * fdt_appendprop() appends the value to the named property in the\n * given node, creating the property if it does not already exist.\n *\n * This function may insert data into the blob, and will therefore\n * change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there is insufficient free space in the blob to\n *\t\tcontain the new property value\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nint fdt_appendprop(void *fdt, int nodeoffset, const char *name,\n\t\t   const void *val, int len);\n\n/**\n * fdt_appendprop_u32 - append a 32-bit integer value to a property\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n * @val: 32-bit integer value to append to the property (native endian)\n *\n * fdt_appendprop_u32() appends the given 32-bit integer value\n * (converting to big-endian if necessary) to the value of the named\n * property in the given node, or creates a new property with that\n * value if it does not already exist.\n *\n * This function may insert data into the blob, and will therefore\n * change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there is insufficient free space in the blob to\n *\t\tcontain the new property value\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nstatic inline int fdt_appendprop_u32(void *fdt, int nodeoffset,\n\t\t\t\t     const char *name, uint32_t val)\n{\n\tfdt32_t tmp = cpu_to_fdt32(val);\n\treturn fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));\n}\n\n/**\n * fdt_appendprop_u64 - append a 64-bit integer value to a property\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n * @val: 64-bit integer value to append to the property (native endian)\n *\n * fdt_appendprop_u64() appends the given 64-bit integer value\n * (converting to big-endian if necessary) to the value of the named\n * property in the given node, or creates a new property with that\n * value if it does not already exist.\n *\n * This function may insert data into the blob, and will therefore\n * change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there is insufficient free space in the blob to\n *\t\tcontain the new property value\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nstatic inline int fdt_appendprop_u64(void *fdt, int nodeoffset,\n\t\t\t\t     const char *name, uint64_t val)\n{\n\tfdt64_t tmp = cpu_to_fdt64(val);\n\treturn fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));\n}\n\n/**\n * fdt_appendprop_cell - append a single cell value to a property\n *\n * This is an alternative name for fdt_appendprop_u32()\n */\nstatic inline int fdt_appendprop_cell(void *fdt, int nodeoffset,\n\t\t\t\t      const char *name, uint32_t val)\n{\n\treturn fdt_appendprop_u32(fdt, nodeoffset, name, val);\n}\n\n/**\n * fdt_appendprop_string - append a string to a property\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n * @str: string value to append to the property\n *\n * fdt_appendprop_string() appends the given string to the value of\n * the named property in the given node, or creates a new property\n * with that value if it does not already exist.\n *\n * This function may insert data into the blob, and will therefore\n * change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there is insufficient free space in the blob to\n *\t\tcontain the new property value\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\n#define fdt_appendprop_string(fdt, nodeoffset, name, str) \\\n\tfdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)\n\n/**\n * fdt_delprop - delete a property\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to nop\n * @name: name of the property to nop\n *\n * fdt_del_property() will delete the given property.\n *\n * This function will delete data from the blob, and will therefore\n * change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOTFOUND, node does not have the named property\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nint fdt_delprop(void *fdt, int nodeoffset, const char *name);\n\n/**\n * fdt_add_subnode_namelen - creates a new node based on substring\n * @fdt: pointer to the device tree blob\n * @parentoffset: structure block offset of a node\n * @name: name of the subnode to locate\n * @namelen: number of characters of name to consider\n *\n * Identical to fdt_add_subnode(), but use only the first namelen\n * characters of name as the name of the new node.  This is useful for\n * creating subnodes based on a portion of a larger string, such as a\n * full path.\n */\n#ifndef SWIG /* Not available in Python */\nint fdt_add_subnode_namelen(void *fdt, int parentoffset,\n\t\t\t    const char *name, int namelen);\n#endif\n\n/**\n * fdt_add_subnode - creates a new node\n * @fdt: pointer to the device tree blob\n * @parentoffset: structure block offset of a node\n * @name: name of the subnode to locate\n *\n * fdt_add_subnode() creates a new node as a subnode of the node at\n * structure block offset parentoffset, with the given name (which\n * should include the unit address, if any).\n *\n * This function will insert data into the blob, and will therefore\n * change the offsets of some existing nodes.\n\n * returns:\n *\tstructure block offset of the created nodeequested subnode (>=0), on\n *\t\tsuccess\n *\t-FDT_ERR_NOTFOUND, if the requested subnode does not exist\n *\t-FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE\n *\t\ttag\n *\t-FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of\n *\t\tthe given name\n *\t-FDT_ERR_NOSPACE, if there is insufficient free space in the\n *\t\tblob to contain the new node\n *\t-FDT_ERR_NOSPACE\n *\t-FDT_ERR_BADLAYOUT\n *      -FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings.\n */\nint fdt_add_subnode(void *fdt, int parentoffset, const char *name);\n\n/**\n * fdt_del_node - delete a node (subtree)\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node to nop\n *\n * fdt_del_node() will remove the given node, including all its\n * subnodes if any, from the blob.\n *\n * This function will delete data from the blob, and will therefore\n * change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nint fdt_del_node(void *fdt, int nodeoffset);\n\n/**\n * fdt_overlay_apply - Applies a DT overlay on a base DT\n * @fdt: pointer to the base device tree blob\n * @fdto: pointer to the device tree overlay blob\n *\n * fdt_overlay_apply() will apply the given device tree overlay on the\n * given base device tree.\n *\n * Expect the base device tree to be modified, even if the function\n * returns an error.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there's not enough space in the base device tree\n *\t-FDT_ERR_NOTFOUND, the overlay points to some inexistant nodes or\n *\t\tproperties in the base DT\n *\t-FDT_ERR_BADPHANDLE,\n *\t-FDT_ERR_BADOVERLAY,\n *\t-FDT_ERR_NOPHANDLES,\n *\t-FDT_ERR_INTERNAL,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADOFFSET,\n *\t-FDT_ERR_BADPATH,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nint fdt_overlay_apply(void *fdt, void *fdto);\n\n/**********************************************************************/\n/* Debugging / informational functions                                */\n/**********************************************************************/\n\nconst char *fdt_strerror(int errval);\n\nstatic inline uint64_t fdt32_to_cpu64(fdt32_t high, fdt32_t low)\n{\n\treturn ((uint64_t)fdt32_to_cpu(high) << 32) | fdt32_to_cpu(low);\n}\n\nint fdt_set_node_reg(void *dtb, int node,\n\t\tunsigned long iomem, size_t iomem_size);\n\n#endif /* LIBFDT_H */\n"
  },
  {
    "path": "kernel/include/libfdt/libfdt_env.h",
    "content": "#ifndef LIBFDT_ENV_H\n#define LIBFDT_ENV_H\n/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2006 David Gibson, IBM Corporation.\n * Copyright 2012 Kim Phillips, Freescale Semiconductor.\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include <minos/string.h>\n#include <minos/types.h>\n\n#ifdef __CHECKER__\n#define FDT_FORCE __attribute__((force))\n#define FDT_BITWISE __attribute__((bitwise))\n#else\n#define FDT_FORCE\n#define FDT_BITWISE\n#endif\n\ntypedef uint16_t FDT_BITWISE fdt16_t;\ntypedef uint32_t FDT_BITWISE fdt32_t;\ntypedef uint64_t FDT_BITWISE fdt64_t;\n\n#define EXTRACT_BYTE(x, n)\t((unsigned long long)((uint8_t *)&x)[n])\n#define CPU_TO_FDT16(x) ((EXTRACT_BYTE(x, 0) << 8) | EXTRACT_BYTE(x, 1))\n#define CPU_TO_FDT32(x) ((EXTRACT_BYTE(x, 0) << 24) | (EXTRACT_BYTE(x, 1) << 16) | \\\n\t\t\t (EXTRACT_BYTE(x, 2) << 8) | EXTRACT_BYTE(x, 3))\n#define CPU_TO_FDT64(x) ((EXTRACT_BYTE(x, 0) << 56) | (EXTRACT_BYTE(x, 1) << 48) | \\\n\t\t\t (EXTRACT_BYTE(x, 2) << 40) | (EXTRACT_BYTE(x, 3) << 32) | \\\n\t\t\t (EXTRACT_BYTE(x, 4) << 24) | (EXTRACT_BYTE(x, 5) << 16) | \\\n\t\t\t (EXTRACT_BYTE(x, 6) << 8) | EXTRACT_BYTE(x, 7))\n\nstatic inline uint16_t fdt16_to_cpu(fdt16_t x)\n{\n\treturn (FDT_FORCE uint16_t)CPU_TO_FDT16(x);\n}\nstatic inline fdt16_t cpu_to_fdt16(uint16_t x)\n{\n\treturn (FDT_FORCE fdt16_t)CPU_TO_FDT16(x);\n}\n\nstatic inline uint32_t fdt32_to_cpu(fdt32_t x)\n{\n\treturn (FDT_FORCE uint32_t)CPU_TO_FDT32(x);\n}\nstatic inline fdt32_t cpu_to_fdt32(uint32_t x)\n{\n\treturn (FDT_FORCE fdt32_t)CPU_TO_FDT32(x);\n}\n\nstatic inline uint64_t fdt64_to_cpu(fdt64_t x)\n{\n\treturn (FDT_FORCE uint64_t)CPU_TO_FDT64(x);\n}\nstatic inline fdt64_t cpu_to_fdt64(uint64_t x)\n{\n\treturn (FDT_FORCE fdt64_t)CPU_TO_FDT64(x);\n}\n#undef CPU_TO_FDT64\n#undef CPU_TO_FDT32\n#undef CPU_TO_FDT16\n#undef EXTRACT_BYTE\n\n#ifdef __APPLE__\n#include <AvailabilityMacros.h>\n\n/* strnlen() is not available on Mac OS < 10.7 */\n# if !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED < \\\n                                         MAC_OS_X_VERSION_10_7)\n\n#define strnlen fdt_strnlen\n\n/*\n * fdt_strnlen: returns the length of a string or max_count - which ever is\n * smallest.\n * Input 1 string: the string whose size is to be determined\n * Input 2 max_count: the maximum value returned by this function\n * Output: length of the string or max_count (the smallest of the two)\n */\nstatic inline size_t fdt_strnlen(const char *string, size_t max_count)\n{\n    const char *p = memchr(string, 0, max_count);\n    return p ? p - string : max_count;\n}\n\n#endif /* !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED <\n          MAC_OS_X_VERSION_10_7) */\n\n#endif /* __APPLE__ */\n\n#endif /* LIBFDT_ENV_H */\n"
  },
  {
    "path": "kernel/include/minos/arch.h",
    "content": "#ifndef __MINOS_ARCH_H_\n#define __MINOS_ARCH_H_\n\n#include <asm/arch.h>\n\nstruct vspace;\nstruct task;\n\n#define raw_smp_processor_id()\t\tarch_raw_smp_processor_id()\n\n#define get_virtual_address_size()\tarch_get_virtual_address_size()\n\nphy_addr_t arch_translate_va_to_pa(struct vspace *mm, unsigned long va);\n\nint arch_host_map(struct vspace *mm, unsigned long start, unsigned long end,\n\t\tunsigned long physical, unsigned long flags);\n\nint arch_host_unmap(struct vspace *mm, unsigned long start,\n\t\tunsigned long end, int mode);\n\nunsigned long arch_kernel_pgd_base(void);\n\nint arch_get_asid_size(void);\n\nint arch_host_change_map(struct vspace *vs, unsigned long vir,\n\t\tunsigned long phy, unsigned long flags);\n\npgd_t *arch_alloc_process_page_table(void);\n\nvoid arch_task_sched_out(struct task *task);\nvoid arch_task_sched_in(struct task *task);\n\nvoid arch_set_task_user_stack(struct task *task, unsigned long stack);\nvoid arch_set_task_reg0(struct task *task, unsigned long data);\nvoid arch_set_tls(struct task *task, unsigned long tls);\nvoid arch_set_task_entry_point(struct task *task, long entry);\n\n#ifdef CONFIG_VIRT\nstruct mm_struct;\n\nvoid *arch_alloc_guest_pgd(void);\n\nint arch_guest_unmap(struct mm_struct *mm, unsigned long start, unsigned long end);\n\nint arch_guest_map(struct mm_struct *mm, unsigned long start, unsigned long end,\n\t\tunsigned long physical, unsigned long flags);\n\nint arch_translate_guest_ipa(struct mm_struct *vs, unsigned long va, phy_addr_t *pa);\n\n#endif\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/atomic.h",
    "content": "#ifndef _MINOS_ATOMIC_H_\n#define _MINOS_ATOMIC_H_\n\n#include <asm/atomic.h>\n#include <asm/cmpxchg.h>\n\n#define ATOMIC_INIT(v) { (v) }\n\nstatic inline void atomic_inc(atomic_t *t)\n{\n\tatomic_add(1, t);\n}\n\nstatic inline void atomic_dec(atomic_t *t)\n{\n\tatomic_sub(1, t);\n}\n\nstatic inline int atomic_inc_return(atomic_t *t)\n{\n\treturn atomic_add_return(1, t);\n}\n\nstatic inline int atomic_dec_return(atomic_t *t)\n{\n\treturn atomic_sub_return(1, t);\n}\n\nstatic inline int atomic_inc_return_old(atomic_t *t)\n{\n\treturn atomic_add_return_old(1, t);\n}\n\nstatic inline int atomic_dec_return_old(atomic_t *t)\n{\n\treturn atomic_sub_return_old(1, t);\n}\n\nstatic inline int atomic_inc_and_test(atomic_t *t)\n{\n\treturn atomic_add_return(1, t) == 0;\n}\n\nstatic inline int atomic_dec_and_test(atomic_t *t)\n{\n\treturn atomic_sub_return(1, t) == 0;\n}\n\nstatic inline int atomic_add_negative(int i, atomic_t *t)\n{\n\treturn atomic_add_return(i, t) < 0;\n}\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/bitmap.h",
    "content": "#ifndef __LINUX_BITMAP_H\n#define __LINUX_BITMAP_H\n\n#include <minos/types.h>\n#include <minos/bitops.h>\n#include <minos/string.h>\n\n/*\n * bitmaps provide bit arrays that consume one or more unsigned\n * longs.  The bitmap interface and available operations are listed\n * here, in bitmap.h\n *\n * Function implementations generic to all architectures are in\n * lib/bitmap.c.  Functions implementations that are architecture\n * specific are in various include/asm-<arch>/bitops.h headers\n * and other arch/<arch> specific files.\n *\n * See lib/bitmap.c for more details.\n */\n\n/*\n * Also the following operations in asm/bitops.h apply to bitmaps.\n *\n * set_bit(bit, addr)\t\t\t*addr |= bit\n * clear_bit(bit, addr)\t\t\t*addr &= ~bit\n * change_bit(bit, addr)\t\t*addr ^= bit\n * test_bit(bit, addr)\t\t\tIs bit set in *addr?\n * test_and_set_bit(bit, addr)\t\tSet bit and return old value\n * test_and_clear_bit(bit, addr)\tClear bit and return old value\n * test_and_change_bit(bit, addr)\tChange bit and return old value\n * find_first_zero_bit(addr, nbits)\tPosition first zero bit in *addr\n * find_first_bit(addr, nbits)\t\tPosition first set bit in *addr\n * find_next_zero_bit(addr, nbits, bit)\tPosition next zero bit in *addr >= bit\n * find_next_bit(addr, nbits, bit)\tPosition next set bit in *addr >= bit\n */\n\n/*\n * The DECLARE_BITMAP(name,bits) macro, in linux/types.h, can be used\n * to declare an array named 'name' of just enough unsigned longs to\n * contain all bit positions from 0 to 'bits' - 1.\n */\n\nextern void bitmap_set(unsigned long *map, unsigned int start, int len);\nextern void bitmap_clear(unsigned long *map, unsigned int start, int len);\n\nextern unsigned long bitmap_find_next_zero_area_off(unsigned long *map,\n\t\t\t\t\t\t    unsigned long size,\n\t\t\t\t\t\t    unsigned long start,\n\t\t\t\t\t\t    unsigned int nr,\n\t\t\t\t\t\t    unsigned long align_mask,\n\t\t\t\t\t\t    unsigned long align_offset);\n\n/**\n * bitmap_find_next_zero_area - find a contiguous aligned zero area\n * @map: The address to base the search on\n * @size: The bitmap size in bits\n * @start: The bitnumber to start searching at\n * @nr: The number of zeroed bits we're looking for\n * @align_mask: Alignment mask for zero area\n *\n * The @align_mask should be one less than a power of 2; the effect is that\n * the bit offset of all zero areas this function finds is multiples of that\n * power of 2. A @align_mask of 0 means no alignment is required.\n */\nstatic inline unsigned long\nbitmap_find_next_zero_area(unsigned long *map,\n\t\t\t   unsigned long size,\n\t\t\t   unsigned long start,\n\t\t\t   unsigned int nr,\n\t\t\t   unsigned long align_mask)\n{\n\treturn bitmap_find_next_zero_area_off(map, size, start, nr,\n\t\t\t\t\t      align_mask, 0);\n}\n\nunsigned long bitmap_find_next_zero_area_align(unsigned long *map,\n\t\t\t\t\t     unsigned long size,\n\t\t\t\t\t     unsigned long start,\n\t\t\t\t\t     unsigned int nr,\n\t\t\t\t\t     unsigned long align);\n\n#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1)))\n#define BITMAP_LAST_WORD_MASK(nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1)))\n\n#define small_const_nbits(nbits) \\\n\t(__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG)\n\nstatic inline void bitmap_zero(unsigned long *dst, int nbits)\n{\n\tif (small_const_nbits(nbits))\n\t\t*dst = 0UL;\n\telse {\n\t\tint len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);\n\t\tmemset(dst, 0, len);\n\t}\n}\n\nstatic inline void bitmap_fill(unsigned long *dst, int nbits)\n{\n\tsize_t nlongs = BITS_TO_LONGS(nbits);\n\tif (!small_const_nbits(nbits)) {\n\t\tint len = (nlongs - 1) * sizeof(unsigned long);\n\t\tmemset(dst, 0xff, len);\n\t}\n\tdst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits);\n}\n\n#endif /* __LINUX_BITMAP_H */\n"
  },
  {
    "path": "kernel/include/minos/bitops.h",
    "content": "#ifndef _LINUX_BITOPS_H\n#define _LINUX_BITOPS_H\n\n#include <minos/types.h>\n\n/*\n * Create a contiguous bitmask starting at bit position @l and ending at\n * position @h. For example\n * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.\n */\n\nextern unsigned int sw_hweight8(unsigned int w);\nextern unsigned int sw_hweight16(unsigned int w);\nextern unsigned int sw_hweight32(unsigned int w);\nextern unsigned long sw_hweight64(__u64 w);\n\n/*\n * Include this here because some architectures need generic_ffs/fls in\n * scope\n */\n#include <asm/bitops.h>\n\nunsigned long find_next_bit(const unsigned long *addr, unsigned long size,\n\t\t\t    unsigned long offset);\nunsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,\n\t\t\t\t unsigned long offset);\nunsigned long find_next_bit_loop(const unsigned long *addr, unsigned long size,\n\t\t\t    unsigned long offset);\nunsigned long find_next_zero_bit_loop(const unsigned long *addr, unsigned long size,\n\t\t\t\t unsigned long offset);\nunsigned long find_first_bit(const unsigned long *addr, unsigned long size);\nunsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size);\nunsigned long find_last_bit(const unsigned long *addr, unsigned long size);\n\n#define for_each_set_bit(bit, addr, size) \\\n\tfor ((bit) = find_first_bit((addr), (size));\t\t\\\n\t     (bit) < (size);\t\t\t\t\t\\\n\t     (bit) = find_next_bit((addr), (size), (bit) + 1))\n\n/* same as for_each_set_bit() but use bit as value to start with */\n#define for_each_set_bit_from(bit, addr, size) \\\n\tfor ((bit) = find_next_bit((addr), (size), (bit));\t\\\n\t     (bit) < (size);\t\t\t\t\t\\\n\t     (bit) = find_next_bit((addr), (size), (bit) + 1))\n\n#define for_each_clear_bit(bit, addr, size) \\\n\tfor ((bit) = find_first_zero_bit((addr), (size));\t\\\n\t     (bit) < (size);\t\t\t\t\t\\\n\t     (bit) = find_next_zero_bit((addr), (size), (bit) + 1))\n\n/* same as for_each_clear_bit() but use bit as value to start with */\n#define for_each_clear_bit_from(bit, addr, size) \\\n\tfor ((bit) = find_next_zero_bit((addr), (size), (bit));\t\\\n\t     (bit) < (size);\t\t\t\t\t\\\n\t     (bit) = find_next_zero_bit((addr), (size), (bit) + 1))\n\nstatic inline int get_bitmask_order(unsigned int count)\n{\n\tint order;\n\n\torder = fls(count);\n\treturn order;\t/* We could be slightly more clever with -1 here... */\n}\n\nstatic inline int get_count_order(unsigned int count)\n{\n\tint order;\n\n\torder = fls(count) - 1;\n\tif (count & (count - 1))\n\t\torder++;\n\treturn order;\n}\n\nstatic inline unsigned long hweight_long(unsigned long w)\n{\n\treturn sizeof(w) == 4 ? sw_hweight32(w) : sw_hweight64(w);\n}\n\n/**\n * rol64 - rotate a 64-bit value left\n * @word: value to rotate\n * @shift: bits to roll\n */\nstatic inline __u64 rol64(__u64 word, unsigned int shift)\n{\n\treturn (word << shift) | (word >> (64 - shift));\n}\n\n/**\n * ror64 - rotate a 64-bit value right\n * @word: value to rotate\n * @shift: bits to roll\n */\nstatic inline __u64 ror64(__u64 word, unsigned int shift)\n{\n\treturn (word >> shift) | (word << (64 - shift));\n}\n\n/**\n * rol32 - rotate a 32-bit value left\n * @word: value to rotate\n * @shift: bits to roll\n */\nstatic inline __u32 rol32(__u32 word, unsigned int shift)\n{\n\treturn (word << shift) | (word >> ((-shift) & 31));\n}\n\n/**\n * ror32 - rotate a 32-bit value right\n * @word: value to rotate\n * @shift: bits to roll\n */\nstatic inline __u32 ror32(__u32 word, unsigned int shift)\n{\n\treturn (word >> shift) | (word << (32 - shift));\n}\n\n/**\n * rol16 - rotate a 16-bit value left\n * @word: value to rotate\n * @shift: bits to roll\n */\nstatic inline __u16 rol16(__u16 word, unsigned int shift)\n{\n\treturn (word << shift) | (word >> (16 - shift));\n}\n\n/**\n * ror16 - rotate a 16-bit value right\n * @word: value to rotate\n * @shift: bits to roll\n */\nstatic inline __u16 ror16(__u16 word, unsigned int shift)\n{\n\treturn (word >> shift) | (word << (16 - shift));\n}\n\n/**\n * rol8 - rotate an 8-bit value left\n * @word: value to rotate\n * @shift: bits to roll\n */\nstatic inline __u8 rol8(__u8 word, unsigned int shift)\n{\n\treturn (word << shift) | (word >> (8 - shift));\n}\n\n/**\n * ror8 - rotate an 8-bit value right\n * @word: value to rotate\n * @shift: bits to roll\n */\nstatic inline __u8 ror8(__u8 word, unsigned int shift)\n{\n\treturn (word >> shift) | (word << (8 - shift));\n}\n\n/**\n * sign_extend32 - sign extend a 32-bit value using specified bit as sign-bit\n * @value: value to sign extend\n * @index: 0 based bit index (0<=index<32) to sign bit\n *\n * This is safe to use for 16- and 8-bit types as well.\n */\nstatic inline __s32 sign_extend32(__u32 value, int index)\n{\n\t__u8 shift = 31 - index;\n\treturn (__s32)(value << shift) >> shift;\n}\n\n/**\n * sign_extend64 - sign extend a 64-bit value using specified bit as sign-bit\n * @value: value to sign extend\n * @index: 0 based bit index (0<=index<64) to sign bit\n */\nstatic inline __s64 sign_extend64(__u64 value, int index)\n{\n\t__u8 shift = 63 - index;\n\treturn (__s64)(value << shift) >> shift;\n}\n\nstatic inline unsigned fls_long(unsigned long l)\n{\n\tif (sizeof(l) == 4)\n\t\treturn fls(l);\n\treturn fls64(l);\n}\n\n/**\n * __ffs64 - find first set bit in a 64 bit word\n * @word: The 64 bit word\n *\n * On 64 bit arches this is a synomyn for __ffs\n * The result is not defined if no bits are set, so check that @word\n * is non-zero before calling this.\n */\nstatic inline unsigned long __ffs64(__u64 word)\n{\n#if BITS_PER_LONG == 32\n\tif (((u32)word) == 0UL)\n\t\treturn __ffs((u32)(word >> 32)) + 32;\n#elif BITS_PER_LONG != 64\n#error BITS_PER_LONG not 32 or 64\n#endif\n\treturn __ffs((unsigned long)word);\n}\n\n#ifndef set_mask_bits\n#define set_mask_bits(ptr, _mask, _bits)\t\\\n({\t\t\t\t\t\t\t\t\\\n\tconst typeof(*ptr) mask = (_mask), bits = (_bits);\t\\\n\ttypeof(*ptr) old, new;\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\\\n\tdo {\t\t\t\t\t\t\t\\\n\t\told = ACCESS_ONCE(*ptr);\t\t\t\\\n\t\tnew = (old & ~mask) | bits;\t\t\t\\\n\t} while (cmpxchg(ptr, old, new) != old);\t\t\\\n\t\t\t\t\t\t\t\t\\\n\tnew;\t\t\t\t\t\t\t\\\n})\n#endif\n\n#ifndef bit_clear_unless\n#define bit_clear_unless(ptr, _clear, _test)\t\\\n({\t\t\t\t\t\t\t\t\\\n\tconst typeof(*ptr) clear = (_clear), test = (_test);\t\\\n\ttypeof(*ptr) old, new;\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\\\n\tdo {\t\t\t\t\t\t\t\\\n\t\told = ACCESS_ONCE(*ptr);\t\t\t\\\n\t\tnew = old & ~clear;\t\t\t\t\\\n\t} while (!(old & test) &&\t\t\t\t\\\n\t\t cmpxchg(ptr, old, new) != old);\t\t\\\n\t\t\t\t\t\t\t\t\\\n\t!(old & test);\t\t\t\t\t\t\\\n})\n#endif\n\n#ifndef find_last_bit\n/**\n * find_last_bit - find the last set bit in a memory region\n * @addr: The address to start the search at\n * @size: The number of bits to search\n *\n * Returns the bit number of the last set bit, or size.\n */\nextern unsigned long find_last_bit(const unsigned long *addr,\n\t\t\t\t   unsigned long size);\n#endif\n\nvoid set_bit(int nr, unsigned long *p);\nvoid clear_bit(int nr, unsigned long *p);\nvoid change_bit(int nr, unsigned long *p);\nint test_bit(int nr, unsigned long *p);\nint test_and_set_bit(int nr, unsigned long *p);\nint test_and_clear_bit(int nr, unsigned long *p);\nint test_and_change_bit(int nr, unsigned long *p);\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/bootarg.h",
    "content": "#ifndef __MINOS_BOOTARG_H__\n#define __MINOS_BOOTARG_H__\n\n#include <minos/types.h>\n\nint bootargs_init(const char *str, int len);\n\nint __get_boot_option(char *name, void *value,\n\t\tint (*parse)(char *args, void *value));\n\nint bootarg_parse_hex32(char *name, uint32_t *v);\nint bootarg_parse_hex64(char *name, uint64_t *v);\nint bootarg_parse_uint(char *name, uint32_t *v);\nint bootarg_parse_bool(char *name, int *v);\nint bootarg_parse_string(char *name, char **v);\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/calltrace.h",
    "content": "#ifndef __MINOS_CALLTRACE_H_\n#define __MINOS_CALLTRACE_H_\n\n#include <minos/compiler.h>\n\nvoid __panic(gp_regs *regs, char *str, ...) __noreturn;\nvoid print_symbol(unsigned long addr);\nvoid dump_stack(gp_regs *regs, unsigned long *stack);\n\n#define panic(...)\t__panic(NULL, __VA_ARGS__)\n\n#define WARN_ON(condition, ...)\t\t \\\n\tif ((condition)) {\t\t \\\n\t\tdo {\t\t\t \\\n\t\t\tpr_err(\"WARN: \" __VA_ARGS__); \\\n\t\t} while (0); \t\t \\\n\t}\n\n#define BUG_ON(condition, ...)\t\t \\\n\tif ((condition)) {\t\t \\\n\t\tdo {\t\t\t \\\n\t\t\tpanic(\"BUG: \" __VA_ARGS__); \\\n\t\t} while (0); \t\t \\\n\t}\n\n#define ASSERT(condition)\t\t \\\n\tif (!(condition)) {\t\t \\\n\t\tdo {\t\t\t \\\n\t\t\tpanic(\"ASSERT FAIL: %s %d\\n\", __func__, __LINE__); \\\n\t\t} while (0); \t\t \\\n\t}\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/channel.h",
    "content": "#ifndef __MINOS_CHANNEL_H__\n#define __MINOS_CHANNEL_H__\n\n/*\n * object 代表内核资源，资源是全局的 每个资源就是一个object,\n * 每个但是资源会属于某个id  然后可以在各个进程中传递资源，\n * 每个资源会有唯一的id，资源从属于某一个进程，当资源授予某一个\n * 进程的时候，返回一个hanlde， 这个handle属于进程描述符表中。\n * 资源传递通过channel来传递.\n *\n * 每个server会有默认channel()  ----> channel 0, register sever的时候会\n * 注册channel的功能\n *\n * 名字叫做port. 每个server使用port对外提供服务，每个port的功能可以不一样\n * 比如一个典型的文件系统服务只有一个port\n *\n * 另外对于一个带有双工的网卡，可以有两个thread, 一个tx thread一个rx thread\n * 或者irq thread，则至少会有两个port\n *\n *  /dev/marvel/port_tx\t// 文件类型 普通 port\n *  /dev/marver/port_rx\t// 文件类型\n *  /proc/port0\n *\n */\n\nstruct object {\n\tuint8_t type;\n};\n\nstruct vma_handle {\n\tstruct object object;\n};\n\nstruct pmo {\n\tstruct object object;\n};\n\n// 客户端和服务端通信需要协议。\n\nstruct channel {\n\tint \n\tmutex_t mutex;\n};\n\n收到了vmo，调用vmo_map()map到自己的内存区域，然后可以进行读写。\n\n\nfd = open(\"/dev/procsrv\");\n\nwrite(fd, &msg, sizeof(msg));   // create_process\n\nipc_recv(&msg, sizeof(msg), NULL);\nif () {\n\n}\n\nswitch (request) {\ncase CREATE_PROCESS:\n\tbreak;\n}\n\nopen(\"/dev/data/bin.elf\");\n\nvmo_handle= create_vmo(proc, xxx);\n\nret = ipc_send(fd, &msg, sizeof(msg));\n\n\n/*\n * 解析xxx\n */\n\nipc_send(fd, &msg, );\t//read segment data\n\nipc_send(fd, &msg);\t// read segment data\n\nclose(vmo_handle); //可以不需要close\n\nipc_send(fd, void *addr, size_t size, int flags);\n\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/compiler.h",
    "content": "#ifndef __MINOS_COMPILER_H_\n#define __MINOS_COMPILER_H_\n\n#define __cache_line_size__\t(64)\n\n#define __section(S)\t\t__attribute__((__section__(#S)))\n#define __used\t\t\t__attribute__((__used__))\n#define __unused\t\t__attribute__((__unused__))\n#define __align(x)\t\t__attribute__((__aligned__(x)))\n#define __cache_line_align\t__align(__cache_line_size__)\n#define __packed\t\t__attribute__((__packed__))\n#define __noreturn\t\t__attribute__((noreturn))\n#define likely(x)\t\t__builtin_expect(!!(x), 1)\n#define unlikely(x)\t\t__builtin_expect(!!(x), 0)\n#define barrier()\t\t__asm__ __volatile__(\"\" ::: \"memory\")\n#define unused(__arg__)\t\t(void)(__arg__)\n\n#define __user\n#define __guest\n\n#ifndef weak_alias\n#define weak_alias(old, new) \\\n        extern __typeof(old) new __attribute__((__weak__, __alias__(#old)))\n#endif\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/console.h",
    "content": "#ifndef __MINOS_CONSOLE_H__\n#define __MINOS_CONSOLE_H__\n\n#include <minos/types.h>\n\nstruct console {\n\tchar *name;\n\tint (*init)(char *arg);\n\tvoid (*putc)(char ch);\n\tchar (*getc)(void);\n};\n\n#define DEFINE_CONSOLE(n, console_name, init_fn, putc_fn, getc_fn) \\\n\tstatic struct console __console_##n __used __section(\".__console\") = { \\\n\t\t.name = console_name,\t\\\n\t\t.init = init_fn,\t\\\n\t\t.putc = putc_fn,\t\\\n\t\t.getc = getc_fn,\t\\\n\t}\n\nvoid console_init(char *name);\nvoid console_putc(char ch);\nchar console_getc(void);\nvoid console_puts(char *buf, int len);\n\nvoid console_recv(const char *buf, int cnt);\nint console_gets(char *buf, int max, uint32_t timeout);\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/const.h",
    "content": "#ifndef __MINOS_CONST_H__\n#define __MINOS_CONST_H__\n\n#ifdef __ASSEMBLY__\n#define _AC(X,Y)        X\n#define _AT(T,X)        X\n#else\n#define __AC(X,Y)       (X##Y)\n#define _AC(X,Y)        __AC(X,Y)\n#define _AT(T,X)        ((T)(X))\n#endif\n\n#define _UL(x)          (_AC(x, UL))\n#define _ULL(x)         (_AC(x, ULL))\n\n#define _BITUL(x)       (_UL(1) << (x))\n#define _BITULL(x)      (_ULL(1) << (x))\n\n#define UL(x)           (_UL(x))\n#define ULL(x)          (_ULL(x))\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/cpumask.h",
    "content": "#ifndef _MINOS_CPUMASK_H_\n#define _MINOS_CPUMASK_H_\n\n#include <minos/types.h>\n#include <minos/bitmap.h>\n\ntypedef struct cpumask {\n\t DECLARE_BITMAP(bits, CONFIG_NR_CPUS);\n} cpumask_t;\n\n#define nr_cpumask_bits (BITS_TO_LONGS(CONFIG_NR_CPUS) * BITS_PER_LONG)\n#define nr_cpu_ids CONFIG_NR_CPUS\n\n/* verify cpu argument to cpumask_* operators */\nstatic inline unsigned int cpumask_check(unsigned int cpu)\n{\n\t/*\n\t * do some check\n\t */\n\treturn cpu;\n}\n\nstatic inline void cpumask_set_cpu(int cpu, cpumask_t *dstp)\n{\n\tset_bit(cpumask_check(cpu), dstp->bits);\n}\n\nstatic inline void __cpumask_set_cpu(int cpu, cpumask_t *dstp)\n{\n\tset_bit(cpumask_check(cpu), dstp->bits);\n}\n\nstatic inline void cpumask_clear_cpu(int cpu, cpumask_t *dstp)\n{\n\tclear_bit(cpumask_check(cpu), dstp->bits);\n}\n\nstatic inline void __cpumask_clear_cpu(int cpu, cpumask_t *dstp)\n{\n\tclear_bit(cpumask_check(cpu), dstp->bits);\n}\n\nstatic inline void cpumask_setall(cpumask_t *dstp)\n{\n\tbitmap_fill(dstp->bits, nr_cpumask_bits);\n}\n\nstatic inline void cpumask_clearall(cpumask_t *dstp)\n{\n\tbitmap_zero(dstp->bits, nr_cpumask_bits);\n}\n\nstatic inline int cpumask_first(const cpumask_t *srcp)\n{\n\treturn min(nr_cpu_ids, find_first_bit(srcp->bits, nr_cpu_ids));\n}\n\nstatic inline int cpumask_next(int n, const cpumask_t *srcp)\n{\n\t/* -1 is a legal arg here. */\n\tif (n != -1)\n\t\tcpumask_check(n);\n\n\treturn min(nr_cpu_ids, find_next_bit(srcp->bits, nr_cpu_ids, n + 1));\n}\n\n\n#if CONFIG_NR_CPUS > 1\n#define for_each_cpu(cpu, mask)\t\t\t\\\n\tfor ((cpu) = cpumask_first(mask);\t\\\n\t     (cpu) < CONFIG_NR_CPUS;\t\t\\\n\t     (cpu) = cpumask_next(cpu, mask))\n#else /* CONFIG_NR_CPUS == 1 */\n#define for_each_cpu(cpu, mask)\t\t\t\\\n\tfor ((cpu) = 0; (cpu) < 1; (cpu)++, (void)(mask))\n#endif /* CONFIG_NR_CPUS */\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/current.h",
    "content": "#ifndef __MINOS_CURRENT_H__\n#define __MINOS_CURRENT_H__\n\n#include <minos/task_info.h>\n#include <minos/task_def.h>\n\n#define current\t\t\tget_current_task()\n#define current_task_info\tget_current_task_info()\n#define current_pid\t\tcurrent->pid\n#define current_tid\t\tcurrent->tid\n#define current_user_regs\tcurrent->user_regs\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/device_id.h",
    "content": "#ifndef _MINOS_DEVICE_ID_H_\n#define _MINOS_DEVICE_ID_H_\n\n#include <minos/types.h>\n#include <minos/init.h>\n\ntypedef enum __device_class {\n\tDT_CLASS_CPU = 0,\n\tDT_CLASS_MEMORY,\n\tDT_CLASS_IRQCHIP,\n\tDT_CLASS_TIMER,\n\tDT_CLASS_SIMPLE_BUS,\n\tDT_CLASS_PCI_BUS,\n\tDT_CLASS_VDEV,\n\tDT_CLASS_PDEV,\n\tDT_CLASS_VM,\n\tDT_CLASS_VMBOX,\n\tDT_CLASS_VIRQCHIP,\n\tDT_CLASS_OTHER,\n} device_class_t;\n\n#define DEVICE_NODE_F_ROOT\t\t(1 << 0)\n#define DEVICE_NODE_F_OF\t\t(1 << 1)\n\n/*\n * data       - the data for all device such as dtb or acpi\n * offset     - node offset\n * name       - the name of the device node\n * compatible - the compatible used to match device\n * parent     - the parent node of device_node\n * child      - child nodes of the device_node\n * sibling    - brother of the device node\n */\nstruct device_node {\n\tvoid *data;\n\tint offset;\n\tconst char *name;\n\tconst char *compatible;\n\tstruct device_node *parent;\n\tstruct device_node *child;\n\tstruct device_node *sibling;\n\tstruct device_node *next;\n\tdevice_class_t class;\n\tunsigned long flags;\n};\n\n#define devnode_name(node)\tnode->name\n\nstruct module_id {\n\tconst char *name;\n\tchar **comp;\n\tvoid *data;\n};\n\n#define MINOS_MODULE_DECLARE(mname, mn, init_fn) \\\n\tstatic const struct module_id __used \\\n\tmodule_match_##mname __section(.__vmodule) = { \\\n\t\t.name = mn, \\\n\t\t.comp = NULL, \\\n\t\t.data = init_fn, \\\n\t}\n\n#define IRQCHIP_DECLARE(mname, mn, irqchip) \\\n\tstatic const struct module_id __used \\\n\tmodule_match_##mname __section(.__irqchip) = { \\\n\t\t.comp = mn, \\\n\t\t.data = irqchip, \\\n\t}\n\n#define VIRQCHIP_DECLARE(mname, mn, virqchip) \\\n\tstatic const struct module_id __used \\\n\tmodule_match_##mname __section(.__virqchip) = { \\\n\t\t.comp = mn, \\\n\t\t.data = virqchip, \\\n\t}\n\n#define VDEV_DECLARE(mname, mn, vdev) \\\n\tstatic const struct module_id __used \\\n\tmodule_match_##mname __section(.__vdev) = { \\\n\t\t.comp = mn, \\\n\t\t.data = vdev, \\\n\t}\n\nextern char *gicv2_match_table[];\nextern char *gicv3_match_table[];\nextern char *bcmirq_match_table[];\nextern char *pl031_match_table[];\nextern char *sp805_match_table[];\nextern char *virtio_match_table[];\nextern char *aic_match_table[];\nextern char *arm_arch_timer_match_table[];\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/errno.h",
    "content": "#ifndef _MINOS_ERRNO_H_\n#define _MINOS_ERRNO_H_\n\n#define EPERM            1      /* Operation not permitted */\n#define ENOENT           2      /* No such file or directory */\n#define ESRCH            3      /* No such process */\n#define EINTR            4      /* Interrupted system call */\n#define EIO              5      /* I/O error */\n#define ENXIO            6      /* No such device or address */\n#define E2BIG            7      /* Argument list too long */\n#define ENOEXEC          8      /* Exec format error */\n#define EBADF            9      /* Bad file number */\n#define ECHILD          10      /* No child processes */\n#define EAGAIN          11      /* Try again */\n#define ENOMEM          12      /* Out of memory */\n#define EACCES          13      /* Permission denied */\n#define EFAULT          14      /* Bad address */\n#define ENOTBLK         15      /* Block device required */\n#define EBUSY           16      /* Device or resource busy */\n#define EEXIST          17      /* File exists */\n#define EXDEV           18      /* Cross-device link */\n#define ENODEV          19      /* No such device */\n#define ENOTDIR         20      /* Not a directory */\n#define EISDIR          21      /* Is a directory */\n#define EINVAL          22      /* Invalid argument */\n#define ENFILE          23      /* File table overflow */\n#define EMFILE          24      /* Too many open files */\n#define ENOTTY          25      /* Not a typewriter */\n#define ETXTBSY         26      /* Text file busy */\n#define EFBIG           27      /* File too large */\n#define ENOSPC          28      /* No space left on device */\n#define ESPIPE          29      /* Illegal seek */\n#define EROFS           30      /* Read-only file system */\n#define EMLINK          31      /* Too many links */\n#define EPIPE           32      /* Broken pipe */\n#define EDOM            33      /* Math argument out of domain of func */\n#define ERANGE          34      /* Math result not representable */\n#define\tEDEADLK\t\t35\t/* Resource deadlock would occur */\n#define\tENAMETOOLONG\t36\t/* File name too long */\n#define\tENOLCK\t\t37\t/* No record locks available */\n#define\tENOSYS\t\t38\t/* Function not implemented */\n#define\tENOTEMPTY\t39\t/* Directory not empty */\n#define\tELOOP\t\t40\t/* Too many symbolic links encountered */\n#define\tEWOULDBLOCK\tEAGAIN\t/* Operation would block */\n#define\tENOMSG\t\t42\t/* No message of desired type */\n#define\tEIDRM\t\t43\t/* Identifier removed */\n#define\tECHRNG\t\t44\t/* Channel number out of range */\n#define\tEL2NSYNC\t45\t/* Level 2 not synchronized */\n#define\tEL3HLT\t\t46\t/* Level 3 halted */\n#define\tEL3RST\t\t47\t/* Level 3 reset */\n#define\tELNRNG\t\t48\t/* Link number out of range */\n#define\tEUNATCH\t\t49\t/* Protocol driver not attached */\n#define\tENOCSI\t\t50\t/* No CSI structure available */\n#define\tEL2HLT\t\t51\t/* Level 2 halted */\n#define\tEBADE\t\t52\t/* Invalid exchange */\n#define\tEBADR\t\t53\t/* Invalid request descriptor */\n#define\tEXFULL\t\t54\t/* Exchange full */\n#define\tENOANO\t\t55\t/* No anode */\n#define\tEBADRQC\t\t56\t/* Invalid request code */\n#define\tEBADSLT\t\t57\t/* Invalid slot */\n\n#define\tEDEADLOCK\tEDEADLK\n\n#define\tEBFONT\t\t59\t/* Bad font file format */\n#define\tENOSTR\t\t60\t/* Device not a stream */\n#define\tENODATA\t\t61\t/* No data available */\n#define\tETIME\t\t62\t/* Timer expired */\n#define\tENOSR\t\t63\t/* Out of streams resources */\n#define\tENONET\t\t64\t/* Machine is not on the network */\n#define\tENOPKG\t\t65\t/* Package not installed */\n#define\tEREMOTE\t\t66\t/* Object is remote */\n#define\tENOLINK\t\t67\t/* Link has been severed */\n#define\tEADV\t\t68\t/* Advertise error */\n#define\tESRMNT\t\t69\t/* Srmount error */\n#define\tECOMM\t\t70\t/* Communication error on send */\n#define\tEPROTO\t\t71\t/* Protocol error */\n#define\tEMULTIHOP\t72\t/* Multihop attempted */\n#define\tEDOTDOT\t\t73\t/* RFS specific error */\n#define\tEBADMSG\t\t74\t/* Not a data message */\n#define\tEOVERFLOW\t75\t/* Value too large for defined data type */\n#define\tENOTUNIQ\t76\t/* Name not unique on network */\n#define\tEBADFD\t\t77\t/* File descriptor in bad state */\n#define\tEREMCHG\t\t78\t/* Remote address changed */\n#define\tELIBACC\t\t79\t/* Can not access a needed shared library */\n#define\tELIBBAD\t\t80\t/* Accessing a corrupted shared library */\n#define\tELIBSCN\t\t81\t/* .lib section in a.out corrupted */\n#define\tELIBMAX\t\t82\t/* Attempting to link in too many shared libraries */\n#define\tELIBEXEC\t83\t/* Cannot exec a shared library directly */\n#define\tEILSEQ\t\t84\t/* Illegal byte sequence */\n#define\tERESTART\t85\t/* Interrupted system call should be restarted */\n#define\tESTRPIPE\t86\t/* Streams pipe error */\n#define\tEUSERS\t\t87\t/* Too many users */\n#define\tENOTSOCK\t88\t/* Socket operation on non-socket */\n#define\tEDESTADDRREQ\t89\t/* Destination address required */\n#define\tEMSGSIZE\t90\t/* Message too long */\n#define\tEPROTOTYPE\t91\t/* Protocol wrong type for socket */\n#define\tENOPROTOOPT\t92\t/* Protocol not available */\n#define\tEPROTONOSUPPORT\t93\t/* Protocol not supported */\n#define\tESOCKTNOSUPPORT\t94\t/* Socket type not supported */\n#define\tEOPNOTSUPP\t95\t/* Operation not supported on transport endpoint */\n#define\tEPFNOSUPPORT\t96\t/* Protocol family not supported */\n#define\tEAFNOSUPPORT\t97\t/* Address family not supported by protocol */\n#define\tEADDRINUSE\t98\t/* Address already in use */\n#define\tEADDRNOTAVAIL\t99\t/* Cannot assign requested address */\n#define\tENETDOWN\t100\t/* Network is down */\n#define\tENETUNREACH\t101\t/* Network is unreachable */\n#define\tENETRESET\t102\t/* Network dropped connection because of reset */\n#define\tECONNABORTED\t103\t/* Software caused connection abort */\n#define\tECONNRESET\t104\t/* Connection reset by peer */\n#define\tENOBUFS\t\t105\t/* No buffer space available */\n#define\tEISCONN\t\t106\t/* Transport endpoint is already connected */\n#define\tENOTCONN\t107\t/* Transport endpoint is not connected */\n#define\tESHUTDOWN\t108\t/* Cannot send after transport endpoint shutdown */\n#define\tETOOMANYREFS\t109\t/* Too many references: cannot splice */\n#define\tETIMEDOUT\t110\t/* Connection timed out */\n#define\tECONNREFUSED\t111\t/* Connection refused */\n#define\tEHOSTDOWN\t112\t/* Host is down */\n#define\tEHOSTUNREACH\t113\t/* No route to host */\n#define\tEALREADY\t114\t/* Operation already in progress */\n#define\tEINPROGRESS\t115\t/* Operation now in progress */\n#define\tESTALE\t\t116\t/* Stale NFS file handle */\n#define\tEUCLEAN\t\t117\t/* Structure needs cleaning */\n#define\tENOTNAM\t\t118\t/* Not a XENIX named type file */\n#define\tENAVAIL\t\t119\t/* No XENIX semaphores available */\n#define\tEISNAM\t\t120\t/* Is a named type file */\n#define\tEREMOTEIO\t121\t/* Remote I/O error */\n#define\tEDQUOT\t\t122\t/* Quota exceeded */\n\n#define\tENOMEDIUM\t123\t/* No medium found */\n#define\tEMEDIUMTYPE\t124\t/* Wrong medium type */\n#define\tECANCELED\t125\t/* Operation Canceled */\n#define\tENOKEY\t\t126\t/* Required key not available */\n#define\tEKEYEXPIRED\t127\t/* Key has expired */\n#define\tEKEYREVOKED\t128\t/* Key has been revoked */\n#define\tEKEYREJECTED\t129\t/* Key was rejected by service */\n\n/* for robust mutexes */\n#define\tEOWNERDEAD\t130\t/* Owner died */\n#define\tENOTRECOVERABLE\t131\t/* State not recoverable */\n\n#define ERFKILL\t\t132\t/* Operation not possible due to RF-kill */\n\n#define EHWPOISON\t133\t/* Memory page has hardware error */\n\n#define EABORT\t\t134\t/* Pend abort process is killed */\n\n#define EOTHERSIDECLOSED 135\t/* the otherside of this kobject is closed */\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/event.h",
    "content": "#ifndef __MINOS_EVENT_H__\n#define __MINOS_EVENT_H__\n\n#include <minos/preempt.h>\n#include <minos/types.h>\n#include <minos/spinlock.h>\n\n#define OS_EVENT_OPT_NONE 0x0\n#define OS_EVENT_OPT_BROADCAST 0x1\n\n#define WAKEUP_ALL (-1)\n\nenum {\n\tOS_EVENT_TYPE_NORMAL,\n\tOS_EVENT_TYPE_MBOX,\n\tOS_EVENT_TYPE_QUEUE,\n\tOS_EVENT_TYPE_SEM,\n\tOS_EVENT_TYPE_MUTEX,\n\tOS_EVENT_TYPE_FLAG,\n\tOS_EVENT_TYPE_FUTEX,\n\tOS_EVENT_TYPE_IRQ,\n\tOS_EVENT_TYPE_POLL,\n\tOS_EVENT_TYPE_MAX,\n\tOS_EVENT_TYPE_TIMER,\n};\n\nstruct task;\n\nstruct event {\n\tint type;\t\t\t\t/* event type */\n\ttid_t owner;\t\t\t\t/* event owner the tid */\n\tuint32_t cnt;\t\t\t\t/* event cnt */\n\tvoid *data;\t\t\t\t/* event pdata for transfer */\n\tspinlock_t lock;\t\t\t/* the lock of the event for smp */\n\tstruct list_head wait_list;\t\t/* non realtime task waitting list */\n};\n\n#define TO_EVENT(e)\t(struct event *)(e)\n\nuint32_t new_event_token(void);\nvoid event_init(struct event *event, int type, void *pdata);\nvoid event_pend_down(void);\n\nvoid __wait_event(void *ev, int event, uint32_t to);\nlong wake(struct event *ev, long retcode);\n\nlong do_wait_event(struct event *ev);\n\nint __wake_up_event_waiter(struct event *ev,\n\t\tlong msg, int pend_state, int num);\n\nstruct task *wake_up_one_event_waiter(struct event *ev,\n\t\tlong msg, int pend_state);\n\n#define wake_up_event_waiter(ev, msg, pend_state, num) \\\n\t__wake_up_event_waiter(TO_EVENT(ev), msg, pend_state, num)\n\n/*\n * wait_event can only get the status of the event, can not get\n * the retcode from the waker, so the retcode of the waker need\n * store in otherwhere.\n */\n#define wait_event(ev, condition, _to)\t\t\t\t\\\n({\t\t\t\t\t\t\t\t\\\n\t__label__ __out1;\t\t\t\t\t\\\n\tunsigned long flags;\t\t\t\t\t\\\n\tlong __ret = 0;\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\\\n\tif (condition)\t\t\t\t\t\t\\\n\t\tgoto __out1;\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\\\n\tif (is_task_need_stop(current)) {\t\t\t\\\n\t\t__ret = -EABORT;\t\t\t\t\\\n\t\tgoto __out1;\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\\\n\tspin_lock_irqsave(&(ev)->lock, flags);\t\t\t\\\n\tif (condition) {\t\t\t\t\t\\\n\t\tspin_unlock_irqrestore(&(ev)->lock, flags);\t\\\n\t\tgoto __out1;\t\t\t\t\t\\\n\t} else if ((_to) == 0) {\t\t\t\t\\\n\t\t__ret = -EBUSY;\t\t\t\t\t\\\n\t\tspin_unlock_irqrestore(&(ev)->lock, flags);\t\\\n\t\tgoto __out1;\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\\\n\t__wait_event(ev, OS_EVENT_TYPE_NORMAL, _to); \t\t\\\n\tspin_unlock_irqrestore(&(ev)->lock, flags);\t\t\\\n\t__ret = do_wait_event(ev);\t\t\t\t\\\n\t\t\t\t\t\t\t\t\\\n__out1: __ret;\t\t\t\t\t\t\t\\\n})\n\nlong __wake(struct event *ev, int pend_state, long retcode);\n\n#define wake(ev, retcode) __wake(ev, TASK_STATE_PEND_OK, retcode)\n#define wake_abort(ev) __wake(ev, TASK_STATE_PEND_ABORT, -EABORT)\n#define wake_timeout(ev) __wake(ev, TASK_STATE_PEND_TO, -ETIMEDOUT)\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/flag.h",
    "content": "#ifndef __MINOS_FLAG_H__\n#define __MINOS_FLAG_H__\n\n#include <minos/event.h>\n#include <minos/spinlock.h>\n\n#define FLAG_WAIT_CLR_ALL       0\n#define FLAG_WAIT_CLR_AND       0\n#define FLAG_WAIT_CLR_ANY       1\n#define FLAG_WAIT_CLR_OR        1\n#define FLAG_WAIT_SET_ALL       2\n#define FLAG_WAIT_SET_AND       2\n#define FLAG_WAIT_SET_ANY       3\n#define FLAG_WAIT_SET_OR        3\n\n#define FLAG_CONSUME\t\t0x80\n\n#define FLAG_CLR             0\n#define FLAG_SET             1\n\nstruct flag_grp {\n\tflag_t flags;\n\tspinlock_t lock;\n\tstruct list_head wait_list;\n};\n\nstatic void inline flag_init(struct flag_grp *fg, flag_t flags)\n{\n\tfg->flags = flags;\n\tinit_list(&fg->wait_list);\n\tspin_lock_init(&fg->lock);\n}\n\nflag_t flag_accept(struct flag_grp *grp, flag_t flags, int wait_type);\n\nflag_t flag_pend(struct flag_grp *grp, flag_t flags,\n\t\tint wait_type, uint32_t timeout);\n\nflag_t flag_pend_get_flags_ready(void);\nflag_t flag_post(struct flag_grp *grp, flag_t flags, int opt);\n\n#define flag_set(grp, flags)\tflag_post(grp, flags, FLAG_SET)\n#define flag_clear(grp, flags)\tflag_post(grp, flags, FLAG_CLEAR)\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/hook.h",
    "content": "#ifndef __MINOS_HOOK_H__\n#define __MINOS_HOOK_H__\n\n#include <config/config.h>\n\ntypedef int (*hook_func_t)(void *item, void *contex);\n\nenum hook_type {\n\tOS_HOOK_CREATE_TASK = 0,\n\tOS_HOOK_RELEASE_TASK,\n\tOS_HOOK_TASK_SWITCH,\n\tOS_HOOK_TASK_SWITCH_OUT,\n\tOS_HOOK_TASK_SWITCH_TO,\n\tOS_HOOK_ENTER_IRQ,\n\n#ifdef CONFIG_VIRT\n\tOS_HOOK_EXIT_FROM_GUEST,\n\tOS_HOOK_ENTER_TO_GUEST,\n\tOS_HOOK_CREATE_VM,\n\tOS_HOOK_DESTROY_VM,\n\tOS_HOOK_SUSPEND_VM,\n\tOS_HOOK_RESUME_VM,\n\tOS_HOOK_SETUP_VM,\n\tOS_HOOK_VCPU_INIT,\n#endif\n\tOS_HOOK_TYPE_UNKNOWN,\n};\n\nstruct hook {\n\thook_func_t fn;\n\tstruct list_head list;\n};\n\nint do_hooks(void *item, void *context, enum hook_type type);\nint register_hook(hook_func_t fn, enum hook_type type);\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/init.h",
    "content": "#ifndef _INIT_H\n#define _INIT_H\n\n#define INIT_PATH_SIZE\t\t128\n\n#define CMDLINE_TAG\t\t\"xxoo\"\n#define ARCH_NAME_SIZE\t\t8\n#define BOARD_NAME_SIZE\t\t16\n\n#define MEM_MAX_REGION\t\t16\n\nstruct cmdline {\n\tunsigned long tag;\n\tunsigned long head;\n\tchar arg[256];\n};\n\ntypedef int (*init_call)(void);\n\n#define __init_data \t__section(\".__init_data_section\")\n#define __init_text \t__section(\".__init_text\")\n\n#define __init_0\t__section(\".__init_func_0\")\n#define __init_1\t__section(\".__init_func_1\")\n#define __init_2\t__section(\".__init_func_2\")\n#define __init_3\t__section(\".__init_func_3\")\n#define __init_4\t__section(\".__init_func_4\")\n#define __init_5\t__section(\".__init_func_5\")\n#define __init_6\t__section(\".__init_func_6\")\n#define __init_7\t__section(\".__init_func_7\")\n#define __init_8\t__section(\".__init_func_8\")\n#define __init_9\t__section(\".__init_func_9\")\n\n#define __define_initcall(fn, id)\t\\\n\tstatic init_call __init_call_##fn __used __init_##id = fn\n\n#define early_initcall(fn) \t\t__define_initcall(fn, 0)\n#define arch_initcall(fn) \t\t__define_initcall(fn, 1)\n#define subsys_initcall(fn) \t\t__define_initcall(fn, 2)\n#define module_initcall(fn) \t\t__define_initcall(fn, 3)\n#define device_initcall(fn)\t\t__define_initcall(fn, 4)\n#define early_initcall_percpu(fn) \t__define_initcall(fn, 5)\n#define arch_initcall_percpu(fn)\t__define_initcall(fn, 6)\n#define subsys_initcall_percpu(fn)\t__define_initcall(fn, 7)\n#define module_initcall_percpu(fn)\t__define_initcall(fn, 8)\n#define device_initcall_percpu(fn)\t__define_initcall(fn, 9)\n\nvoid arch_init(void);\nvoid early_init(void);\nvoid subsys_init(void);\nvoid module_init(void);\nvoid device_init(void);\nvoid early_init_percpu(void);\nvoid arch_init_percpu(void);\nvoid subsys_init_percpu(void);\nvoid module_init_percpu(void);\nvoid device_init_percpu(void);\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/irq.h",
    "content": "#ifndef _MINOS_IRQ_H_\n#define _MINOS_IRQ_H_\n\n#include <minos/types.h>\n#include <minos/arch.h>\n#include <minos/device_id.h>\n#include <minos/init.h>\n#include <config/config.h>\n#include <minos/smp.h>\n#include <minos/spinlock.h>\n#include <minos/cpumask.h>\n\n#define NR_PERCPU_IRQS\t\t(CONFIG_NR_PPI_IRQS + CONFIG_NR_SGI_IRQS)\n#define PERCPU_IRQ_DESC_SIZE\t(NR_PERCPU_IRQS * NR_CPUS)\n#define SPI_IRQ_DESC_SIZE\tCONFIG_NR_SPI_IRQS\n#define SPI_IRQ_BASE\t\tNR_PERCPU_IRQS\n#define MAX_IRQ_COUNT\t\t(CONFIG_NR_SPI_IRQS + NR_PERCPU_IRQS)\n#define BAD_IRQ\t\t\t(1023)\n\n#define IRQ_FLAGS_NONE           \t\t(0x00000000)\n#define IRQ_FLAGS_EDGE_RISING    \t\t(0x00000001)\n#define IRQ_FLAGS_EDGE_FALLING  \t\t(0x00000002)\n#define IRQ_FLAGS_LEVEL_HIGH     \t\t(0x00000004)\n#define IRQ_FLAGS_LEVEL_LOW      \t\t(0x00000008)\n#define IRQ_FLAGS_SENSE_MASK     \t\t(0x0000000f)\n#define IRQ_FLAGS_INVALID        \t\t(0x00000010)\n#define IRQ_FLAGS_EDGE_BOTH \\\n    (IRQ_FLAGS_EDGE_FALLING | IRQ_FLAGS_EDGE_RISING)\n#define IRQ_FLAGS_LEVEL_BOTH \\\n    (IRQ_FLAGS_LEVEL_LOW | IRQ_FLAGS_LEVEL_HIGH)\n#define IRQ_FLAGS_TYPE_MASK\t\t\t(0x000000ff)\n\n#define IRQ_FLAGS_MASKED_BIT\t\t\t(8)\n#define IRQ_FLAGS_MASKED\t\t\t(BIT(IRQ_FLAGS_MASKED_BIT))\n#define IRQ_FLAGS_PERCPU_BIT\t\t\t(9)\n#define IRQ_FLAGS_PERCPU\t\t\t(BIT(IRQ_FLAGS_PERCPU_BIT))\n\n#define IRQ_FLAGS_VCPU_BIT\t\t\t(10)\n#define IRQ_FLAGS_VCPU\t\t\t\t(BIT(IRQ_FLAGS_VCPU_BIT))\n#define IRQ_FLAGS_USER_BIT\t\t\t(11)\n#define IRQ_FLAGS_USER\t\t\t\t(BIT(IRQ_FLAGS_USER_BIT))\n#define IRQ_FLAGS_RECEIVER_MASK\t\t\t(IRQ_FLAGS_USER | IRQ_FLAGS_VCPU)\n\n#define IRQ_FLAGS_PENDING_BIT\t\t\t(12)\n\ntypedef enum sgi_mode {\n\tSGI_TO_LIST = 0,\n\tSGI_TO_OTHERS,\n\tSGI_TO_SELF,\n} sgi_mode_t;\n\nstruct irq_desc;\nstruct virq_desc;\nstruct kobject;\nstruct poll_event_kernel;\n\ntypedef int (*irq_handle_t)(uint32_t irq, void *data);\n\nstruct irq_chip {\n\tuint32_t (*get_pending_irq)(void);\n\tvoid (*irq_mask)(uint32_t irq);\n\tvoid (*irq_mask_cpu)(uint32_t irq, int cpu);\n\tvoid (*irq_unmask_cpu)(uint32_t irq, int cpu);\n\tvoid (*irq_unmask)(uint32_t irq);\n\tvoid (*irq_eoi)(uint32_t irq);\n\tvoid (*irq_dir)(uint32_t irq);\n\tint (*irq_set_affinity)(uint32_t irq, uint32_t pcpu);\n\tint (*irq_set_type)(uint32_t irq, unsigned int flow_type);\n\tint (*irq_set_priority)(uint32_t irq, uint32_t pr);\n\tvoid (*irq_clear_pending)(uint32_t irq);\n\tint (*irq_xlate)(struct device_node *node, uint32_t *intspec,\n\t\t\tunsigned int intsize, uint32_t *hwirq, unsigned long *f);\n\tvoid (*send_sgi)(uint32_t irq, enum sgi_mode mode, cpumask_t *mask);\n\tint (*init)(struct device_node *node);\n\tint (*secondary_init)(void);\n};\n\n/*\n * if a irq is handled by minos, then need to register\n * the irq handler otherwise it will return the vnum\n * to the handler and pass the virq to the vm\n */\nstruct irq_desc {\n\tirq_handle_t handler;\n\tuint16_t hno;\n\tuint16_t affinity;\n\tunsigned long flags;\n\tspinlock_t lock;\n\tunsigned long irq_count;\n\tvoid *pdata;\n};\n\n#define local_irq_enable() arch_enable_local_irq()\n#define local_irq_disable() arch_disable_local_irq()\n#define irq_disabled()\tarch_irq_disabled()\n\nint irq_init(void);\nint irq_secondary_init(void);\nvoid setup_irqs(void);\nint do_irq_handler(void);\n\nint request_irq(uint32_t irq, irq_handle_t handler,\n\t\tunsigned long flags, char *name, void *data);\nint request_irq_percpu(uint32_t irq, irq_handle_t handler,\n\t\tunsigned long flags, char *name, void *data);\n\nvoid send_sgi(uint32_t sgi, int cpu);\n\nvoid irq_set_affinity(uint32_t irq, int cpu);\nvoid irq_set_type(uint32_t irq, int type);\nvoid irq_clear_pending(uint32_t irq);\n\nint irq_xlate(struct device_node *node, uint32_t *intspec,\n\t\tunsigned int intsize, uint32_t *hwirq, unsigned long *f);\n\nstruct irq_desc *get_irq_desc(uint32_t irq);\n\nvoid __irq_enable(uint32_t irq, int enable);\nvoid irq_dir(uint32_t irq);\n\nstatic inline void irq_unmask(uint32_t irq)\n{\n\t__irq_enable(irq, 1);\n}\n\nstatic inline void irq_mask(uint32_t irq)\n{\n\t__irq_enable(irq, 0);\n}\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/kbuild.h",
    "content": "#ifndef __MINOS_KBUILD_H__\n#define __MINOS_KBUILD_H__\n\n#define DEFINE(sym, val) \\\n\tasm volatile(\"\\n->\" #sym \" %0 \" #val : : \"i\" (val))\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/list.h",
    "content": "#ifndef _MINOS_LIST_H_\n#define _MINOS_LIST_H_\n\nstruct list_head;\n\nstruct list_head{\n\tstruct list_head *next, *pre;\n};\n\n#define LIST_HEAD(list)\t\\\nstruct list_head list = {\t\\\n\t.next = &list,\t\\\n\t.pre  = &list,\t\\\n}\n\nstatic void inline init_list(struct list_head *list)\n{\n\tlist->next = list;\n\tlist->pre = list;\n}\n\nstatic void inline list_add(struct list_head *head,\n\t\t\t    struct list_head *new)\n{\n\thead->next->pre = new;\n\tnew->next = head->next;\n\tnew->pre = head;\n\thead->next = new;\n}\n\nstatic void inline list_add_tail(struct list_head *head,\n\t\tstruct list_head *new)\n{\n\thead->pre->next = new;\n\tnew->next = head;\n\tnew->pre = head->pre;\n\thead->pre = new;\n}\n\nstatic void inline list_insert_before(struct list_head *head,\n\t\tstruct list_head *new)\n{\n\tnew->pre = head->pre;\n\tnew->next = head;\n\thead->pre->next = new;\n\thead->pre = new;\n}\n\nstatic void inline list_del(struct list_head *list)\n{\n\tlist->next->pre = list->pre;\n\tlist->pre->next = list->next;\n\tlist->next = (void *)0x0;\n\tlist->pre = (void *)0x0;\n}\n\nstatic void inline list_del_tail(struct list_head *head)\n{\n\thead->pre->pre->next = head;\n\thead->pre = head->pre->pre;\n}\n\nstatic int inline is_list_empty(struct list_head *head)\n{\n\treturn (head->next == head);\n}\n\nstatic int inline is_list_last(struct list_head *head,\n\t\t               struct list_head *list)\n{\n\treturn list->next == head;\n}\n\nstatic inline struct list_head *list_next(struct list_head *list)\n{\n\treturn list->next;\n}\n\nstatic inline struct list_head *list_prve(struct list_head *list)\n{\n\treturn list->pre;\n}\n\n#define list_entry(ptr, type, member)\t\\\n\tcontainer_of(ptr, type, member)\n\n#define list_first_entry(ptr, type, member) \\\n\tlist_entry((ptr)->next, type, member)\n\n#define list_next_entry(pos, member) \\\n\tlist_entry((pos)->member.next, typeof(*(pos)), member)\n\n#define list_for_each(head, list)\t\\\n\tfor(list = (head)->next; list != (head); list = list->next)\n\n#define list_for_each_entry(pos, head, member)\t\\\n\tfor (pos = list_entry((head)->next, typeof(*pos), member); \\\n\t     &pos->member != (head); \\\n\t     pos = list_entry(pos->member.next, typeof(*pos), member))\n\n#define list_for_each_entry_safe(pos, n, head, member)\t\t\t\\\n\tfor (pos = list_first_entry(head, typeof(*pos), member),\t\\\n\t\tn = list_next_entry(pos, member);\t\t\t\\\n\t     &pos->member != (head); \t\t\t\t\t\\\n\t     pos = n, n = list_next_entry(n, member))\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/math64.h",
    "content": "#ifndef _LINUX_MATH64_H\n#define _LINUX_MATH64_H\n\n#include <minos/types.h>\n#include <asm/div64.h>\n\n#if BITS_PER_LONG == 64\n\n#define div64_long(x, y) div64_s64((x), (y))\n#define div64_ul(x, y)   div64_u64((x), (y))\n\n/**\n * div_u64_rem - unsigned 64bit divide with 32bit divisor with remainder\n *\n * This is commonly provided by 32bit archs to provide an optimized 64bit\n * divide.\n */\nstatic inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)\n{\n\t*remainder = dividend % divisor;\n\treturn dividend / divisor;\n}\n\n/**\n * div_s64_rem - signed 64bit divide with 32bit divisor with remainder\n */\nstatic inline s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder)\n{\n\t*remainder = dividend % divisor;\n\treturn dividend / divisor;\n}\n\n/**\n * div64_u64 - unsigned 64bit divide with 64bit divisor\n */\nstatic inline u64 div64_u64(u64 dividend, u64 divisor)\n{\n\treturn dividend / divisor;\n}\n\n/**\n * div64_s64 - signed 64bit divide with 64bit divisor\n */\nstatic inline s64 div64_s64(s64 dividend, s64 divisor)\n{\n\treturn dividend / divisor;\n}\n\n#elif BITS_PER_LONG == 32\n\n#define div64_long(x, y) div_s64((x), (y))\n#define div64_ul(x, y)   div_u64((x), (y))\n\n#ifndef div_u64_rem\nstatic inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)\n{\n\t*remainder = do_div(dividend, divisor);\n\treturn dividend;\n}\n#endif\n\n#ifndef div_s64_rem\nextern s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder);\n#endif\n\n#ifndef div64_u64\nextern u64 div64_u64(u64 dividend, u64 divisor);\n#endif\n\n#ifndef div64_s64\nextern s64 div64_s64(s64 dividend, s64 divisor);\n#endif\n\n#endif /* BITS_PER_LONG */\n\n/**\n * div_u64 - unsigned 64bit divide with 32bit divisor\n *\n * This is the most common 64bit divide and should be used if possible,\n * as many 32bit archs can optimize this variant better than a full 64bit\n * divide.\n */\n#ifndef div_u64\nstatic inline u64 div_u64(u64 dividend, u32 divisor)\n{\n\tu32 remainder;\n\treturn div_u64_rem(dividend, divisor, &remainder);\n}\n#endif\n\n/**\n * div_s64 - signed 64bit divide with 32bit divisor\n */\n#ifndef div_s64\nstatic inline s64 div_s64(s64 dividend, s32 divisor)\n{\n\ts32 remainder;\n\treturn div_s64_rem(dividend, divisor, &remainder);\n}\n#endif\n\nu32 iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder);\n\nstatic inline u32\n__iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder)\n{\n\tu32 ret = 0;\n\n\twhile (dividend >= divisor) {\n\t\t/* The following asm() prevents the compiler from\n\t\t   optimising this loop into a modulo operation.  */\n\t\tasm(\"\" : \"+rm\"(dividend));\n\n\t\tdividend -= divisor;\n\t\tret++;\n\t}\n\n\t*remainder = dividend;\n\n\treturn ret;\n}\n\n#endif /* _LINUX_MATH64_H */\n"
  },
  {
    "path": "kernel/include/minos/mbox.h",
    "content": "#ifndef __MINOS_MBOX_H__\n#define __MINOS_MBOX_H__\n\n#include <minos/event.h>\n\ntypedef struct event mbox_t;\n\n#define DEFINE_MBOX(nam) \\\n\tmbox_t name = { \\\n\t\t.type = 0xff, \\\n\t}\n\nvoid *mbox_accept(mbox_t *m);\nvoid *mbox_pend(mbox_t *m, uint32_t timeout);\nint mbox_post(mbox_t *m, void *pmsg);\nint mbox_post_opt(mbox_t *m, void *pmsg, int opt);\nint mbox_is_pending(mbox_t *m);\n\nstatic void inline mbox_init(mbox_t *mbox, void *pmsg)\n{\n\tevent_init(TO_EVENT(mbox), OS_EVENT_TYPE_MBOX, pmsg);\n}\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/memattr.h",
    "content": "#ifndef __MINOS_MEM_ATTR_H__\n#define __MINOS_MEM_ATTR_H__\n\n#define VM_NONE\t\t\t(0x00000000)\n\n#define __VM_IO\t\t\t(0x00000001)\t/* IO memory */\n#define __VM_NORMAL\t\t(0x00000002)\t/* Normal memory */\n#define __VM_NORMAL_NC\t\t(0x00000004)\n#define __VM_WT\t\t\t(0x00000008)\t/* Write thought */\n\n#define __VM_PFNMAP\t\t(0x00000100)\t/* map to the physical normal memory directly */\n#define __VM_HUGE_2M\t\t(0x00000200)\n#define __VM_HUGE_1G\t\t(0x00000400)\n#define __VM_DEVMAP\t\t(0x00000800)\n#define __VM_SHARED\t\t(0x00001000)\t/* do not release the memory, kobject will release it */\n#define __VM_HOST\t\t(0x00002000)\n#define __VM_GUEST\t\t(0x00004000)\n#define __VM_SHMEM\t\t(0x00008000)\t/* prviate memory, will not be shared */\n#define __VM_PMA\t\t(0x00010000)\n\n#define __VM_RW_NON\t\t(0x00000000)\n#define __VM_READ\t\t(0x00100000)\n#define __VM_WRITE\t\t(0x00200000)\n#define __VM_EXEC\t\t(0x00400000)\n#define __VM_RO\t\t\t(__VM_READ)\n#define __VM_WO\t\t\t(__VM_WRITE)\n#define __VM_RW\t\t\t(__VM_READ | __VM_WRITE)\n\n#define VM_TYPE_MASK\t\t(__VM_IO | __VM_NORMAL | __VM_NORMAL_NC | __VM_WT)\n\n#define VM_HOST\t\t\t(__VM_HOST)\n#define VM_GUEST\t\t(__VM_GUEST)\n\n#define VM_RW_NON\t\t(__VM_RW_NON)\n#define VM_RO\t\t\t(__VM_RO)\n#define VM_WO\t\t\t(__VM_WO)\n#define VM_RW\t\t\t(__VM_READ | __VM_WRITE)\n#define VM_RWX\t\t\t(__VM_READ | __VM_WRITE | __VM_EXEC)\n#define VM_RW_MASK\t\t(__VM_READ | __VM_WRITE)\n\n#define VM_IO\t\t\t(__VM_IO | __VM_DEVMAP | __VM_PFNMAP)\n#define VM_NORMAL\t\t(__VM_NORMAL)\n#define VM_NORMAL_NC\t\t(__VM_NORMAL_NC)\n#define VM_NORMAL_WT\t\t(__VM_WT)\n#define VM_DMA\t\t\t(__VM_NORMAL_NC)\n#define VM_HUGE\t\t\t(__VM_HUGE_2M)\n#define VM_SHARED\t\t(__VM_SHARED)\n#define VM_SHMEM\t\t(__VM_SHMEM)\n#define VM_PFNMAP\t\t(__VM_PFNMAP)\n#define VM_DEVMAP\t\t(__VM_DEVMAP)\n#define VM_PMA\t\t\t(__VM_PMA)\n\n#define VM_MAP_BK\t\t(0X01000000)\t/* mapped as block */\n#define VM_MAP_PT\t\t(0x02000000)\t/* mapped as pass though, PFN_MAP */\n#define VM_MAP_TYPE_MASK\t(0x0f000000)\n\n#define VM_HOST_NORMAL\t\t(VM_NORMAL | VM_PFNMAP | VM_HOST)\n#define VM_HOST_NORMAL_NC\t(__VM_NORMAL_NC | VM_PFNMAP | VM_HOST)\n#define VM_HOST_IO\t\t(VM_IO | VM_HOST)\n\n#define VM_GUEST_NORMAL\t\t(VM_NORMAL | VM_RWX | VM_MAP_BK | VM_GUEST)\n#define VM_GUEST_IO\t\t(VM_IO | VM_MAP_PT | VM_DEVMAP | VM_GUEST)\t/* passthough device for guest VM */\n#define VM_GUEST_VDEV\t\t(VM_GUEST)\t\t\t\t\t/* virtual device created by host for guest VM, memory R/W will trapped */\n#define VM_GUEST_SHMEM\t\t(VM_NORMAL_NC | VM_SHMEM | VM_GUEST)\t\t/* shared memory between guests, memory will managemented by host */\n#define VM_NATIVE_NORMAL\t(VM_NORMAL | VM_RWX | VM_PFNMAP | VM_HUGE | VM_GUEST) /* native VM using the memory config from device tree */\n\n#define MEM_BLOCK_SIZE\t\t(0x200000)\n#define MEM_BLOCK_SHIFT\t\t(21)\n#define BFN2PHY(bfn)\t\t((unsigned long)(bfn) << MEM_BLOCK_SHIFT)\n#define PHY2BFN(phy)\t\t((unsigned long)(phy) >> MEM_BLOCK_SHIFT)\n#define PAGES_IN_BLOCK\t\t(MEM_BLOCK_SIZE >> PAGE_SHIFT)\n\n#define __PAGE_MASK\t\t(~((1UL << PAGE_SHIFT) - 1))\n#define __BLOCK_MASK\t\t(~((1UL << MEM_BLOCK_SHIFT) - 1))\n#define BLOCK_MASK\t\t((1 << MEM_BLOCK_SHIFT) - 1)\n\n#define GFB_SLAB               (1 << 0)\n#define GFB_PAGE               (1 << 1)\n#define GPF_PAGE_META          (1 << 2)\n#define GFB_VM                 (1 << 3)\n#define GFB_FIXED              (1 << 5)\n\n#define GFB_SLAB_BIT           (0)\n#define GFB_PAGE_BIT           (1)\n#define GFB_PAGE_META_BIT      (2)\n#define GFB_VM_BIT             (3)\n#define GFB_IO_BIT             (4)\n#define GFB_FIXED_BIT          (5)\n\n#define GFB_MASK               (0xffff)\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/memory.h",
    "content": "#ifndef __MINOS_MEMORY_H__\n#define __MINOS_MEMORY_H__\n\n#include <minos/types.h>\n#include <minos/list.h>\n\nenum {\n\tMEMORY_REGION_TYPE_NORMAL = 0,\n\tMEMORY_REGION_TYPE_RSV,\n\tMEMORY_REGION_TYPE_VM,\n\tMEMORY_REGION_TYPE_DTB,\n\tMEMORY_REGION_TYPE_KERNEL,\n\tMEMORY_REGION_TYPE_RAMDISK,\n\tMEMORY_REGION_TYPE_MAX\n};\n\nextern unsigned long minos_start;\nextern unsigned long minos_bootmem_base;\nextern unsigned long minos_stack_top;\nextern unsigned long minos_stack_bottom;\nextern unsigned long minos_end;\n\nextern struct list_head mem_list;\n\n#define for_each_memory_region(region)\t\\\n\tlist_for_each_entry(region, &mem_list, list)\n\nstruct memory_region {\n\tint type;\n\tint vmid;\t\t// 0 is host\n\tphy_addr_t phy_base;\n\tsize_t size;\n\tstruct list_head list;\n};\n\nint add_memory_region(uint64_t base, uint64_t size,\n\t\tint flags, int vmid);\n\nint split_memory_region(uint64_t base, size_t size,\n\t\tint flags, int vmid);\n\nint add_page_section(phy_addr_t base, size_t size, int type);\n\nvoid add_kmem_section(struct memory_region *region);\n\nvoid dump_memory_info(void);\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/minos.h",
    "content": "#ifndef _MINOS_MINOS_H_\n#define _MINOS_MINOS_H_\n\n#include <minos/types.h>\n#include <asm/asm-offset.h>\n#include <minos/string.h>\n#include <minos/print.h>\n#include <minos/list.h>\n#include <minos/spinlock.h>\n#include <minos/smp.h>\n#include <config/config.h>\n#include <minos/errno.h>\n#include <minos/init.h>\n#include <minos/arch.h>\n#include <minos/calltrace.h>\n#include <minos/preempt.h>\n#include <minos/os.h>\n#include <minos/hook.h>\n#include <minos/current.h>\n#include <minos/symbol.h>\n\n#define section_for_each_item_addr(__start_addr, __end_addr, __var)            \\\n\tsize_t _i, _cnt;                                                       \\\n\tunsigned long _base, _end;                                             \\\n\t_base = __start_addr;                                                  \\\n\t_end = __end_addr;                                                     \\\n\t_cnt = (_end - _base) / sizeof(*(__var));                              \\\n\t__var = (__typeof__(__var))(_base);                                    \\\n\tfor (_i = 0; _i < _cnt; ++_i, ++(__var))\n\n#define section_for_each_item(__start, __end, __var)                           \\\n\tsection_for_each_item_addr((unsigned long)&(__start),                  \\\n\t\t\t\t    (unsigned long)&(__end), __var)\n\n#define WARN(condition, format...) ({\t\t\t\t\t\t\\\n\tint __ret_warn_on = !!(condition);\t\t\t\t\\\n\tif (unlikely(__ret_warn_on))\t\t\t\t\t\\\n\t\tpr_warn(format);\t\t\t\t\t\\\n\tunlikely(__ret_warn_on);\t\t\t\t\t\\\n})\n\n#define WARN_ONCE(condition, format...)\t({\t\t\t\\\n\tstatic bool __section(.data.unlikely) __warned;\t\t\\\n\tint __ret_warn_once = !!(condition);\t\t\t\\\n\t\t\t\t\t\t\t\t\\\n\tif (unlikely(__ret_warn_once))\t\t\t\t\\\n\t\tif (WARN(!__warned, format)) \t\t\t\\\n\t\t\t__warned = true;\t\t\t\\\n\tunlikely(__ret_warn_once);\t\t\t\t\\\n})\n\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/mm.h",
    "content": "#ifndef _MINOS_MM_H_\n#define _MINOS_MM_H_\n\n#include <minos/list.h>\n#include <minos/spinlock.h>\n#include <minos/memattr.h>\n#include <minos/memory.h>\n#include <minos/page.h>\n#include <minos/slab.h>\n\nstruct vspace;\n\nstruct mm_notifier_ops {\n\tvoid (*unmap_range)(struct vspace *vspace, unsigned long start,\n\t\t\tunsigned long end, int flags);\n};\n\nstruct vspace {\n\tpgd_t *pgdp;\n\tspinlock_t lock;\n\tuint16_t asid;\n\n\t/*\n\t * indicate that the vspace is used in kernel, means\n\t * kernel is acess the userspace pagees, so do not release\n\t * the pages if unmap to avoid kernel hang or data breach.\n\t */\n\tatomic_t inuse;\n\tstruct page *release_pages;\n\tstruct mm_notifier_ops *notifier_ops;\n\tvoid *pdata;\n};\n\nvoid release_vspace_pages(struct vspace *vs);\n\nint create_host_mapping(unsigned long vir, unsigned long phy,\n\t\tsize_t size, unsigned long flags);\n\nint destroy_host_mapping(unsigned long vir, size_t size);\n\nint change_host_mapping(unsigned long vir, unsigned long phy,\n\t\tunsigned long new_flags);\n\nvoid *io_remap(virt_addr_t vir, size_t size);\n\nint io_unmap(virt_addr_t vir, size_t size);\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/mutex.h",
    "content": "#ifndef __MINOS_MUTEX_H__\n#define __MINOS_MUTEX_H__\n\n#include <minos/event.h>\n\ntypedef struct event mutex_t;\n\n#define OS_MUTEX_AVAILABLE (-1)\n\n#define DEFINE_MUTEX(name)\t\t\t\\\n\tmutex_t name = {\t\t\t\\\n\t\t.type = OS_EVENT_TYPE_MUTEX,\t\\\n\t\t.owner = 0,\t\t\t\\\n\t\t.cnt = OS_MUTEX_AVAILABLE,\t\\\n\t\t.data = NULL,\t\t\t\\\n\t\t.lock = {0, 0},\t\t\t\\\n\t\t.wait_list = {\t\t\t\\\n\t\t\t.prev = &wait_list,\t\\\n\t\t\t.next = &wait_list,\t\\\n\t\t}\t\t\t\t\\\n\t}\n\nmutex_t *mutex_create(char *name);\nint mutex_accept(mutex_t *mutex);\nint mutex_del(mutex_t *mutex, int opt);\nint mutex_pend(mutex_t *m, uint32_t timeout);\nint mutex_post(mutex_t *m);\n\nstatic void inline mutex_init(mutex_t *mutex)\n{\n\tevent_init(TO_EVENT(mutex), OS_EVENT_TYPE_MUTEX, NULL);\n\tmutex->cnt = OS_MUTEX_AVAILABLE;\n}\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/of.h",
    "content": "#ifndef __MINOS_OF_H__\n#define __MINOS_OF_H__\n\n#include <minos/device_id.h>\n#include <libfdt/libfdt.h>\n\ntypedef fdt16_t of16_t;\ntypedef fdt32_t of32_t;\ntypedef fdt64_t of64_t;\n\n#define MAX_DTB_SIZE\t(MEM_BLOCK_SIZE)\n\n#define OF_MAX_ADDR_CELLS\t4\n#define OF_BAD_ADDR\t\t((u64)-1)\n\ntypedef void * (*of_iterate_fn)(struct device_node *, void *arg);\n\nextern struct device_node *of_root_node;\nextern void *dtb_address;\n\n#define of_node_for_each_child(node, child)\t\\\n\tfor (child = node->child; child != NULL; child = child->sibling)\n\nstatic fdt32_t inline cpu_to_of32(uint32_t v)\n{\n\treturn cpu_to_fdt32(v);\n}\n\nstatic uint32_t inline of16_to_cpu(of16_t v)\n{\n\treturn fdt32_to_cpu((fdt16_t)v);\n}\n\nstatic uint32_t inline of32_to_cpu(of32_t v)\n{\n\treturn fdt32_to_cpu((fdt32_t)v);\n}\n\nstatic uint64_t inline of32_to_cpu64(of32_t high, of32_t low)\n{\n\treturn ((uint64_t)fdt32_to_cpu((fdt32_t)high) << 32) |\n\t\tfdt32_to_cpu((fdt32_t)low);\n}\n\nint __of_get_u64_array(void *, int, char *, uint64_t *, int);\nint __of_get_u32_array(void *, int, char *, uint32_t *, int);\nint __of_get_u16_array(void *, int, char *, uint16_t *, int);\nint __of_get_string(void *, int, char *, char *, int);\nint __of_get_bool(void *dtb, int node, char *attr);\nchar *of_get_cmdline(void *dtb);\n\nint of_get_bool(struct device_node *node, char *attr);\nvoid *of_getprop(struct device_node *node, char *attr, int *len);\nint of_get_node_by_name(void *data, int pnode, char *str);\nconst char *__of_get_compatible(void *dtb, int node);\nint of_device_match(struct device_node *node, char **comp);\n\nvoid *of_iterate_all_node_loop(struct device_node *node,\n\t\tof_iterate_fn func, void *arg);\nvoid *of_iterate_all_node(struct device_node *node,\n\t\tof_iterate_fn func, void *arg);\n\nstruct device_node * of_find_node_by_compatible(struct device_node *root, char **comp);\n\nint of_n_addr_cells(struct device_node *node);\nint of_n_size_cells(struct device_node *node);\nint of_n_interrupt_cells(struct device_node *node);\nint of_n_addr_count(struct device_node *node);\nint of_data(void *data);\n\nint of_translate_address_index(struct device_node *node,\n\t\tuint64_t *address, uint64_t *size, int index);\nint of_translate_address(struct device_node *node,\n\t\tuint64_t *address, uint64_t *size);\n\nstruct device_node *of_parse_device_tree(void *);\nvoid of_release_all_node(struct device_node *node);\nvoid *of_device_node_match(struct device_node *node, void *s, void *e);\nint of_get_phandle(struct device_node *node);\n\nstruct device_node *\nof_find_node_by_name(struct device_node *root, char *name);\n\nint fdt_n_size_cells(void *dtb, int node);\nint fdt_n_addr_cells(void *dtb, int node);\n\nstatic inline int of_get_u64_array(struct device_node *node,\n\t\tchar *attr, uint64_t *array, int len)\n{\n\tif (!node || !attr || !array)\n\t\treturn -EINVAL;\n\n\treturn __of_get_u64_array(node->data, node->offset,\n\t\t\tattr, array, len);\n}\n\nstatic inline int of_get_u32_array(struct device_node *node,\n\t\tchar *attr, uint32_t *array, int len)\n{\n\tif (!node || !attr || !array)\n\t\treturn -EINVAL;\n\n\treturn __of_get_u32_array(node->data, node->offset,\n\t\t\tattr, array, len);\n}\n\nstatic inline int of_get_u16_array(struct device_node *node,\n\t\tchar *attr, uint16_t *array, int len)\n{\n\tif (!node || !attr || !array)\n\t\treturn -EINVAL;\n\n\treturn __of_get_u16_array(node->data, node->offset,\n\t\t\tattr, array, len);\n}\n\nstatic inline int of_get_string(struct device_node *node,\n\t\tchar *attr, char *str, int len)\n{\n\tif (!node || !attr || !str)\n\t\treturn -EINVAL;\n\n\treturn __of_get_string(node->data, node->offset,\n\t\t\tattr, str, len);\n}\n\nstatic int inline device_node_is_root(struct device_node *node)\n{\n\treturn (node->parent == NULL);\n}\n\nstatic int inline translate_device_address_index(struct device_node *node,\n\t\tuint64_t *base, uint64_t *size, int index)\n{\n\tif (node->flags & DEVICE_NODE_F_OF)\n\t\treturn of_translate_address_index(node, base, size, index);\n\n\treturn -EINVAL;\n}\n\nstatic inline int translate_device_address(struct device_node *node,\n\t\tuint64_t *base, uint64_t *size)\n{\n\treturn translate_device_address_index(node, base, size, 0);\n}\n\nint get_device_irq_index(struct device_node *node, uint32_t *irq,\n\t\tunsigned long *flags, int index);\n\nint of_get_console_name(char **name);\nint of_init_bootargs(void);\n\nint of_init(void *dtb);\nvoid of_setup_platform(void);\nint of_get_ramdisk_address(unsigned long *start, unsigned long *end);\nint of_spin_table_init(phy_addr_t *smp_holding);\n\nint of_parse_memory_info(void);\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/os.h",
    "content": "#ifndef __MINOS_OS_H__\n#define __MINOS_OS_H__\n\n#include <minos/percpu.h>\n#include <minos/atomic.h>\n#include <asm/arch.h>\n#include <minos/bitops.h>\n#include <minos/task_def.h>\n\nstatic inline int os_is_running(void)\n{\n\treturn get_pcpu()->os_is_running;\n}\n\nstatic inline void set_os_running(void)\n{\n\t/* \n\t * os running is set before the irq is enable\n\t * so do not need to aquire lock or disable the\n\t * interrupt here\n\t */\n\tget_pcpu()->os_is_running = 1;\n\twmb();\n}\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/page.h",
    "content": "#ifndef __MINOS_PAGE_H__\n#define __MINOS_PAGE_H__\n\n#include <minos/list.h>\n#include <minos/memattr.h>\n#include <minos/memory.h>\n\n#define __GFP_KERNEL\t\t0x00000001\n#define __GFP_USER\t\t0x00000002\n#define __GFP_GUEST\t\t0x00000004\n#define __GFP_DMA\t\t0x00000008\n#define __GFP_SHARED\t\t0x00000010\n#define __GFP_SLAB\t\t0x00000020\n#define __GFP_HUGE\t\t0x00000040\n#define __GFP_IO\t\t0x00000080\n\n#define GFP_KERNEL\t\t__GFP_KERNEL\n#define GFP_USER\t\t__GFP_USER\n#define GFP_GUEST\t\t__GFP_GUEST\n#define GFP_DMA\t\t\t__GFP_DMA\n#define GFP_SLAB\t\t__GFP_SLAB\n#define GFP_SHARED\t\t__GFP_SHARED\n#define GFP_SHARED_IO\t\t(__GFP_SHARED | __GFP_IO)\n#define GFP_HUGE\t\t(__GFP_USER | __GFP_HUGE)\n#define GFP_HUGE_IO\t\t(__GFP_USER | __GFP_HUGE | __GFP_IO)\n\nstruct page {\n\tuint16_t cnt;\n\tuint16_t flags;\n\tuint32_t pfn;\t\t// this need make sure the physical range need smaller than 44BITs\n\tstruct page *next;\n} __packed;\n\n#define page_count(page)\t(page)->cnt\n#define page_pa(page)\t\t((page)->pfn << PAGE_SHIFT)\n#define page_va(page)\t\tptov(page_pa(page))\n#define page_flags(page)\t(page)->flags\n\nint free_pages(void *addr);\nstruct page *addr_to_page(unsigned long addr);\nvoid *__get_free_pages(int pages, int align, int flags);\nvoid *get_free_block(unsigned long flags);\nvoid free_block(void *addr);\nvoid page_init(void);\nvoid *get_io_pages(int pages);\nvoid free_io_pages(void *addr);\n\nint __free_pages(struct page *page);\nstruct page *__alloc_pages(int pages, int align, int flags);\n\nstatic inline struct page *alloc_pages(int pages, int flags)\n{\n\treturn __alloc_pages(pages, 1, flags);\n}\n\nstatic inline void *get_free_page(int flags)\n{\n\treturn __get_free_pages(1, 1, flags);\n}\n\nstatic inline void *get_free_pages(int pages, int flags)\n{\n//\tif (flags & __VM_IO)\n//\t\treturn get_io_pages(pages);\n//\telse\n\t\treturn __get_free_pages(pages, 1, flags);\n}\n\n#define get_static_pages(pages)\talloc_kpages(pages)\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/percpu.h",
    "content": "#ifndef _MINOS_PERCPU_H_\n#define _MINOS_PERCPU_H_\n\n#include <config/config.h>\n#include <minos/types.h>\n#include <minos/arch.h>\n#include <minos/preempt.h>\n#include <minos/flag.h>\n\ntypedef enum {\n\tPCPU_STATE_OFFLINE\t= 0x0,\n\tPCPU_STATE_RUNNING,\n\tPCPU_STATE_IDLE,\n} pcpu_state_t;\n\nstruct task;\n\nstruct pcpu {\n\tint pcpu_id;\t\t// fixed place, do not change.\n\tvolatile int state;\n\n\tvoid *stack;\n\n\tunsigned long percpu_offset;\n\n\t/*\n\t * each pcpu has its local sched list, 8 priority\n\t * local_rdy_grp only use [0 - 8], in these 8\n\t * priority:\n\t * 7 - used for idle task\n\t * 6 - used for vcpu task\n\t *\n\t * only the new_list can be changed by other cpu, the\n\t * lock is for the new_list.\n\t */\n\tspinlock_t lock;\n\tstruct list_head new_list;\n\tstruct list_head die_process;\n\n\tstruct list_head stop_list;\n\tstruct task *running_task;\n\tstruct task *idle_task;\n\tuint32_t nr_pcpu_task;\n\n\tuint8_t local_rdy_grp;\n\tuint8_t padding[3];\n\tstruct list_head ready_list[OS_PRIO_MAX];\n\tint tasks_in_prio[OS_PRIO_MAX];\n\n\tstruct timer sched_timer;\n\tint os_is_running;\n\n\tstruct task *kworker;\n\tstruct flag_grp kworker_flag;\n} __cache_line_align;\n\nextern unsigned long percpu_offset[];\n\nextern struct pcpu pcpus[NR_CPUS];\n\nvoid percpu_init(int cpuid);\n\nstatic inline int smp_processor_id(void)\n{\n\treturn ((struct pcpu *)arch_get_pcpu_data())->pcpu_id;\n}\n\n#define DEFINE_PER_CPU(type, name) \\\n\t__section(\".__percpu\") __typeof__(type) per_cpu_##name\n\n#define DECLARE_PER_CPU(type, name) \\\n\textern __section(\".__percpu\") __typeof__(type) per_cpu_##name\n\n#define get_per_cpu(name, cpu) \\\n\t(*((__typeof__(per_cpu_##name)*)((unsigned char*)&per_cpu_##name - percpu_offset[0] + percpu_offset[cpu])))\n\n#define get_cpu_var(name) get_per_cpu(name, smp_processor_id())\n\n#define get_pcpu()\t((struct pcpu *)arch_get_pcpu_data())\n\n#define __get_pcpu()\t\t\\\n({\t\t\t\t\\\n\tpreempt_disable();\t\\\n\t((struct pcpu *)arch_get_pcpu_data());\t\\\n})\n\n#define __put_pcpu(pcpu)\t\\\n({\t\t\t\t\\\n\tpreempt_enable();\t\\\n })\n\n#define get_cpu_data(name)\t\\\n({\t\t\t\t\\\n\tpreempt_disable();\t\\\n\tget_cpu_var(name);\t\\\n})\n\n#define put_cpu_data(name)\t\\\n({\t\t\t\t\\\n\tpreempt_enable();\t\\\n})\n\n#define get_cpu()\t\t\\\n({\t\t\t\t\\\n\tpreempt_disable();\t\\\n\tsmp_processor_id();\t\\\n})\t\t\t\t\\\n\n#define put_cpu()\t\t\\\n({\t\t\t\t\\\n\tpreempt_enable();\t\\\n})\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/platform.h",
    "content": "#ifndef __MINOS_PLATFORM_H__\n#define __MINOS_PLATFORM_H__\n\n#include <minos/compiler.h>\n\n#ifdef CONFIG_VIRT\nstruct vm;\n#endif\n\nstruct platform {\n\tconst char *name;\n\tint (*cpu_on)(unsigned long cpu, unsigned long entry);\n\tint (*cpu_off)(unsigned long cpu);\n\tvoid (*system_reboot)(int mode, const char *cmd);\n\tvoid (*system_shutdown)(void);\n\tint (*system_suspend)(void);\n\tint (*time_init)(void);\n\tint (*iomem_valid)(unsigned long addr);\n#ifdef CONFIG_VIRT\n\tint (*setup_hvm)(struct vm *vm, void *data);\n#endif\n\tint (*platform_init)(void);\n\tvoid (*parse_mem_info)(void);\n};\n\nextern struct platform *platform;\n\n#define DEFINE_PLATFORM(pl)\t\\\n\tstatic struct platform *__platform__##pl __used \\\n\t\t__section(\".__platform\") = &pl\n\nvoid platform_set_to(const char *name);\nint platform_iomem_valid(unsigned long addr);\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/pm.h",
    "content": "#ifndef _MINOS_PM_H_\n#define _MINOS_PM_H_\n\nvoid cpu_idle(void);\nvoid system_reboot(void);\nvoid system_shutdown(void);\nint system_suspend(void);\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/preempt.h",
    "content": "#ifndef __MINOS_PREEMPT_H__\n#define __MINOS_PREEMPT_H__\n\n#include <minos/task_info.h>\n\nextern void cond_resched(void);\n\nstatic inline int preempt_allowed(void)\n{\n\treturn !get_current_task_info()->preempt_count;\n}\n\nstatic inline void preempt_enable(void)\n{\n\tget_current_task_info()->preempt_count--;\n\twmb();\n\tcond_resched();\n}\n\nstatic void inline preempt_disable(void)\n{\n\tget_current_task_info()->preempt_count++;\n\twmb();\n}\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/print.h",
    "content": "#ifndef _MINOS_PRINT_H_\n#define _MINOS_PRINT_H_\n\n#include <minos/types.h>\n\n#define PRINT_LEVEL_FATAL\t0\n#define PRINT_LEVEL_ERROR\t1\n#define PRINT_LEVEL_WARN\t2\n#define PRINT_LEVEL_NOTICE\t3\n#define PRINT_LEVEL_INFO\t4\n#define PRINT_LEVEL_DEBUG\t5\n\nint level_print(int level, char *fmt, ...);\nvoid change_log_level(unsigned int level);\nint printf(char *fmt, ...);\nint puts(char *buf, size_t size);\n\n#define pr_debug(...)\tlevel_print(PRINT_LEVEL_DEBUG, \"DBG \" __VA_ARGS__)\n#define pr_info(...)\tlevel_print(PRINT_LEVEL_INFO,  \"INF \" __VA_ARGS__)\n#define pr_notice(...)\tlevel_print(PRINT_LEVEL_NOTICE,\"NIC \" __VA_ARGS__)\n#define pr_warn(...)\tlevel_print(PRINT_LEVEL_WARN,  \"WRN \" __VA_ARGS__)\n#define pr_err(...)\tlevel_print(PRINT_LEVEL_ERROR, \"ERR \" __VA_ARGS__)\n#define pr_fatal(...)\tlevel_print(PRINT_LEVEL_FATAL, \"FAT \" __VA_ARGS__)\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/queue.h",
    "content": "#ifndef __MINOS_QUEUE_H__\n#define __MINOS_QUEUE_H__\n\n#include <minos/event.h>\n\ntypedef struct event queue_t;\n\nstruct queue {\n\tvoid **q_start;\t\t/* contain the pointer of the data */\n\tvoid **q_end;\t\t/* end of the queue buffer */\n\tvoid **q_in;\t\t/* next message in */\n\tvoid **q_out;\t\t/* next message out */\n\tint q_size;\t\t/* the total size of the queue */\n\tint q_cnt;\t\t/* current queue entriy size */\n};\n\nint queue_init(queue_t *qt, int size, char *name);\nvoid *queue_accept(queue_t *qt);\nint queue_flush(queue_t *qt);\nvoid *queue_pend(queue_t *qt, uint32_t timeout);\nint queue_post_abort(queue_t *qt, int opt);\nint queue_post(queue_t *qt, void *pmsg);\nint queue_post_front(queue_t *qt, void *pmsg);\nint queue_post_opt(queue_t *qt, int opt, void *pmsg);\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/ramdisk.h",
    "content": "#ifndef __MINOS_RAMDISK_H__\n#define __MINOS_RAMDISK_H__\n\n#include <uapi/ramdisk.h>\n\nextern void *ramdisk_start, *ramdisk_end;\n\nvoid set_ramdisk_address(void *start, void *end);\n\nint ramdisk_init(void);\n\nint ramdisk_read(struct ramdisk_file *file, void *buf,\n\t\tsize_t size, unsigned long offset);\n\nint ramdisk_open(char *name, struct ramdisk_file *file);\n\nunsigned long ramdisk_file_base(struct ramdisk_file *file);\n\nunsigned long ramdisk_file_size(struct ramdisk_file *file);\n\nconst char *ramdisk_file_name(struct ramdisk_file *file);\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/raw_spinlock.h",
    "content": "/*\n * Created by Le Min 2017/1212\n */\n\n#ifndef __MINOS_RAW_SPINLOCK_H__\n#define __MINOS_RAW_SPINLOCK_H__\n\n#include <minos/types.h>\n#include <minos/atomic.h>\n#include <asm/asm_current.h>\n\n#ifdef CONFIG_SMP\n\nvoid arch_ticket_lock(spinlock_t *lock);\nvoid arch_ticket_unlock(spinlock_t *lock);\nint arch_ticket_trylock(spinlock_t *lock);\n\n#define DEFINE_SPIN_LOCK(name)\t\t\\\n\tspinlock_t name = {\t\t\\\n\t\t.current_ticket = 0,\t\\\n\t\t.next_ticket = 0,\t\\\n\t}\n\nstatic void inline spin_lock_init(spinlock_t *lock)\n{\n\tlock->current_ticket = 0;\n\tlock->next_ticket = 0;\n}\n\nstatic void inline raw_spin_lock(spinlock_t *lock)\n{\n\tarch_ticket_lock(lock);\n}\n\nstatic void inline raw_spin_unlock(spinlock_t *lock)\n{\n\tarch_ticket_unlock(lock);\n}\n\nstatic int inline raw_spin_trylock(spinlock_t *lock)\n{\n\treturn arch_ticket_trylock(lock);\n}\n\n#else\n\n#define DEFINE_SPIN_LOCK(name) spinlock_t name\n\nstatic void inline spin_lock_init(spinlock_t *lock)\n{\n\n}\n\nstatic void inline raw_spin_lock(spinlock_t *lock)\n{\n\n}\n\nstatic void inline raw_spin_unlock(spinlock_t *lock)\n{\n\n}\n\nstatic void inline raw_spin_trylock(spinlock_t *lock)\n{\n\treturn 1;\n}\n\n#endif\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/sched.h",
    "content": "#ifndef _MINOS_SCHED_H_\n#define _MINOS_SCHED_H_\n\n#include <minos/timer.h>\n#include <minos/atomic.h>\n#include <minos/task.h>\n#include <minos/current.h>\n\nDECLARE_PER_CPU(struct pcpu *, pcpu);\n\nstruct process;\n\nvoid sched(void);\nvoid cond_resched(void);\nint sched_init(void);\nint local_sched_init(void);\nvoid pcpu_resched(int pcpu_id);\nvoid pcpu_irqwork(int pcpu_id);\nvoid task_sleep(uint32_t ms);\nint task_ready(struct task *task, int preempt);\n\nvoid __might_sleep(const char *file, int line, int preempt_offset);\n\nint __wake_up(struct task *task, long pend_state, unsigned long data);\n\nstatic inline int wake_up(struct task *task, long retcode)\n{\n\treturn __wake_up(task, TASK_STATE_PEND_OK,\n\t\t\t(unsigned long)retcode);\n}\n\nstatic inline int wake_up_timeout(struct task *task)\n{\n\treturn __wake_up(task, TASK_STATE_PEND_TO, -ETIMEDOUT);\n}\n\nstatic inline int wake_up_abort(struct task *task)\n{\n\treturn __wake_up(task, TASK_STATE_PEND_ABORT, -EABORT);\n}\n\n#define might_sleep() \\\n\tdo { \\\n\t\t__might_sleep(__FILE__, __LINE__, 0); \\\n\t} while (0)\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/sem.h",
    "content": "#ifndef __MINOS_SEM_H__\n#define __MINOS_SEM_H__\n\n#include <minos/event.h>\n\ntypedef struct event sem_t;\n\n#define DEFINE_SEMAPHORE(name) \\\n\tsem_t name = { \\\n\t\t.type = 0xff, \\\n\t}\n\nuint32_t sem_accept(sem_t *sem);\nint sem_pend(sem_t *sem, uint32_t timeout);\nint sem_pend_abort(sem_t *sem, int opt);\nint sem_post(sem_t *sem);\n\nstatic void inline sem_init(sem_t *sem, uint32_t cnt)\n{\n\tevent_init(TO_EVENT(sem), OS_EVENT_TYPE_SEM, NULL);\n\tsem->cnt = cnt;\n}\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/shell_command.h",
    "content": "#ifndef __MINOS_COMMAND_H__\n#define __MINOS_COMMAND_H__\n\n#include <minos/compiler.h>\n\nstruct shell_command {\n\tint min_args;\n\tchar *name;\n\tchar *cmd_info;\n\tint (*hdl)(int argc, char **argv);\n};\n\n#define DEFINE_SHELL_COMMAND(a_name, c_name, c_cmd_info, c_hdl, args)\t\\\n\tstatic struct shell_command __used\t\t\t\t\\\n\tshell_command_##a_name __section(.__shell_command) = {\t\t\\\n\t\t.min_args\t= args,\t\t\t\t\t\\\n\t\t.name\t\t= c_name,\t\t\t\t\\\n\t\t.cmd_info\t= c_cmd_info,\t\t\t\t\\\n\t\t.hdl\t\t= c_hdl,\t\t\t\t\\\n\t}\n\nint excute_shell_command(int argc, char **argv);\n\nint shell_task(void *data);\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/slab.h",
    "content": "#ifndef __MINOS_SLAB_H__\n#define __MINOS_SLAB_H__\n\n#include <minos/types.h>\n\nvoid *malloc(size_t size);\nvoid *zalloc(size_t size);\nvoid free(void *addr);\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/smp.h",
    "content": "#ifndef _MINOS_SMP_H_\n#define _MINOS_SMP_H_\n\n#include <minos/types.h>\n#include <minos/percpu.h>\n#include <minos/bitmap.h>\n#include <config/config.h>\n#include <minos/cpumask.h>\n\n#define for_all_cpu(cpu)\t\\\n\tfor (cpu = 0; cpu < NR_CPUS; cpu++)\n\nextern cpumask_t cpu_online;\n\n#define for_each_online_cpu(cpu) for_each_cpu(cpu, &cpu_online)\n\ntypedef void (*smp_function)(void *);\n\nvoid smp_cpus_up(void);\nint is_cpus_all_up(void);\nvoid smp_init(void);\nint smp_function_call(int cpu, smp_function fn,\n\t\tvoid *data, int wait);\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/softirq.h",
    "content": "#ifndef _MINOS_SOFTIRQ_H_\n#define _MINOS_SOFTIRQ_H_\n\n/*\n * refer to the linux kernel softirq code\n */\n\nenum\n{\n\tTIMER_SOFTIRQ,\n\tVCPULET_SOFTIRQ,\n\tSCHED_SOFTIRQ,\n\n\tNR_SOFTIRQS\n};\n\nstruct softirq_action {\n\tvoid (*action)(struct softirq_action *);\n};\n\nvoid do_softirq(void);\nvoid open_softirq(int nr, void (*action)(struct softirq_action *));\nvoid softirq_init(void);\nvoid raise_softirq_irqoff(unsigned int nr);\nvoid raise_softirq(unsigned int nr);\nvoid irq_softirq_exit(void);\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/spinlock.h",
    "content": "/*\n * Created by Le Min 2017/1212\n */\n\n#ifndef __MINOS_SPINLOCK_H__\n#define __MINOS_SPINLOCK_H__\n\n#include <minos/preempt.h>\n#include <minos/raw_spinlock.h>\n\n#ifdef CONFIG_SMP\n#define spin_lock(l)\t\t\t\t\\\n\tdo {\t\t\t\t\t\\\n\t\tpreempt_disable();\t\t\\\n\t\traw_spin_lock(l);\t\t\\\n\t} while (0)\n\n#define spin_unlock(l)\t\t\t\t\\\n\tdo {\t\t\t\t\t\\\n\t\traw_spin_unlock(l);\t\t\\\n\t\tpreempt_enable();\t\t\\\n\t} while (0)\n\n#define spin_trylock(l)\t\t\t\t\\\n({\t\t\t\t\t\t\\\n\tpreempt_disable();\t\t\t\\\n\traw_spin_trylock(l);\t\t\t\\\n})\n\n#define spin_lock_irqsave(l, flags) \t\t\\\n\tdo { \t\t\t\t\t\\\n\t\tpreempt_disable();\t\t\\\n\t\tflags = arch_save_irqflags(); \t\\\n\t\tarch_disable_local_irq(); \t\\\n\t\traw_spin_lock(l); \t\t\\\n\t} while (0)\n\n#define spin_trylock_irqsave(l, flags)\t\t\\\n({\t\t\t\t\t\t\\\n\tint ret;\t\t\t\t\\\n\tpreempt_disable();\t\t\t\\\n\tflags = arch_save_irqflags();\t\t\\\n\tarch_disable_local_irq();\t\t\\\n\tret = raw_spin_trylock(l);\t\t\\\n\tif (!ret) {\t\t\t\t\\\n\t\tarch_restore_irqflags(flags);\t\\\n\t\tpreempt_enable();\t\t\\\n\t}\t\t\t\t\t\\\n\tret;\t\t\t\t\t\\\n})\n\n#define spin_unlock_irqrestore(l, flags)\t\\\n\tdo {\t\t\t\t\t\\\n\t\traw_spin_unlock(l);\t\t\\\n\t\tarch_restore_irqflags(flags);\t\\\n\t\tpreempt_enable();\t\t\\\n\t} while (0)\n#else\n#define spin_lock(l) \t\t\tpreempt_disable()\n#define spin_unlock(l)\t\t\tpreempt_enable()\n#define spin_trylock(l)\t\t\traw_spin_trylock()\n#define spin_lock_irqsave(l, flags)\tlocal_irq_save(flags)\n\n#define spin_trylock_irqsave(l, flags)\t\t\\\n({\t\t\t\t\t\t\\\n\tlocal_irqsave(flags);\t\t\t\\\n\traw_spin_trylock(l);\t\t\t\\\n})\n\n#define spin_lock_irqrestore(l, flags)\tlocal_irqrestore(flags);\n#endif\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/stdlib.h",
    "content": "#ifndef _MINOS_STDLIB_H_\n#define _MINOS_STDLIB_H_\n\n#include <minos/types.h>\n#include <minos/math64.h>\n#include <asm/div64.h>\n\n#ifndef CONFIG_X86_64\n#define mod_64(x, y) ((x) - (y) * div64_u64(x, y))\n#else\n#define mod_64(x, y) ((x) % (y))\n#endif\n\nuint64_t muldiv64(u64 a, u32 b, u32 c);\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/string.h",
    "content": "#ifndef _STRING_H\n#define _STRING_H\n\n#include <minos/types.h>\n#include <minos/varlist.h>\n\nlong absolute(long num);\nlong num_to_str(char *buf, unsigned long num, int bdho);\nlong itoa(char *buf, int num);\nlong ltoa(char *buf, long num);\nlong uitoa(char *buf, unsigned int num);\nlong ultoa(char *buf, unsigned long num);\nlong hextoa(char *buf, unsigned long num);\nlong octtoa(char *buf, unsigned long num);\nlong bintoa(char *buf, unsigned long num);\nsize_t strlen(const char *s);\nchar *strcpy(char *des, const char *src);\nchar *strncpy(char *des, const char *src, int len);\nint strcmp(const char *src, const char *dst);\nint memcmp(const char *src, const char *dst, size_t size);\nint strncmp(const char *src, const char *dst, int n);\nchar *strchr(const char *src, char ch);\nvoid memset(void *base, char ch, int size);\nvoid *memmove(void *dest, const void *src, size_t n);\nsize_t strnlen(const char *s, size_t maxlen);\nvoid *memcpy(void *dest, const void *src, size_t n);\nvoid *memchr(const void *s, int c, size_t n);\nint vsprintf(char *buf, const char *fmt, va_list arg);\nint sprintf(char *str, const char *format, ...);\nchar *strrchr(const char *s, int c);\nunsigned long strtoul(const char *cp, char **endp, unsigned int base);\nchar *strsep(char **stringp, const char *delim);\n\nstatic inline int is_digit(char ch)\n{\n\treturn ((ch <= '9') && (ch >= '0'));\n}\n\nstatic inline int isalpha(char ch)\n{\n\treturn (((ch >= 'a') && (ch <= 'z')) ||\n\t\t\t((ch >= 'A') && (ch <= 'Z')));\n}\n\n#define atoi(str) strtoul((str), NULL, 10)\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/symbol.h",
    "content": "#ifndef __MINOS_SYMBOL_H__\n#define __MINOS_SYMBOL_H__\n\n#define EXPORT_SYMBOL(sym)\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/task.h",
    "content": "#ifndef __MINOS_TASK_H__\n#define __MINOS_TASK_H__\n\n#include <minos/minos.h>\n#include <minos/flag.h>\n#include <config/config.h>\n#include <minos/task_def.h>\n\n#define to_task_info(task)\t(&(task)->ti)\n\n#ifdef CONFIG_TASK_RUN_TIME\n#define TASK_RUN_TIME CONFIG_TASK_RUN_TIME\n#else\n#define TASK_RUN_TIME 50\n#endif\n\nstatic int inline task_is_idle(struct task *task)\n{\n\treturn (task->flags & TASK_FLAGS_IDLE);\n}\n\nstatic inline int get_task_tid(struct task *task)\n{\n\treturn task->tid;\n}\n\nstatic inline uint8_t get_task_prio(struct task *task)\n{\n\treturn task->prio;\n}\n\nstatic inline int task_is_suspend(struct task *task)\n{\n\treturn !!(task->state & TASK_STATE_WAIT_EVENT);\n}\n\nstatic inline int task_is_running(struct task *task)\n{\n\treturn (task->state == TASK_STATE_RUNNING);\n}\n\nstatic inline int task_is_vcpu(struct task *task)\n{\n\treturn (task->flags & TASK_FLAGS_VCPU);\n}\n\nstatic inline int task_is_32bit(struct task *task)\n{\n\treturn (task->flags & TASK_FLAGS_32BIT);\n}\n\nstatic inline void task_set_resched(struct task *task)\n{\n\ttask->ti.flags |= TIF_NEED_RESCHED;\n}\n\nstatic inline void task_clear_resched(struct task *task)\n{\n\ttask->ti.flags &= ~TIF_NEED_RESCHED;\n}\n\nstatic inline int task_need_resched(struct task *task)\n{\n\treturn (task->ti.flags & TIF_NEED_RESCHED);\n}\n\nstatic inline void task_need_stop(struct task *task)\n{\n\tset_bit(TIF_NEED_STOP, &task->ti.flags);\n\tsmp_wmb();\n}\n\nstatic inline void task_need_freeze(struct task *task)\n{\n\tset_bit(TIF_NEED_FREEZE, &task->ti.flags);\n\tsmp_wmb();\n}\n\nstatic inline int is_task_need_stop(struct task *task)\n{\n\treturn !!(task->ti.flags & (__TIF_NEED_FREEZE | __TIF_NEED_STOP));\n}\n\n#define task_state_pend_ok(status)\t\\\n\t((status) == TASK_STATE_PEND_OK)\n#define task_state_pend_timeout(status)\t\\\n\t((status) == TASK_STATE_PEND_TO)\n#define task_state_pend_abort(status)\t\\\n\t((status) == TASK_STATE_PEND_ABORT)\n\n/*\n * set current running task's state do not need to obtain\n * a lock, when need to wakeup the task, below state the state\n * can be changed:\n * 1 - running -> wait_event\n * 2 - wait_event -> running (waked up by event)\n * 3 - new -> running\n * 4 - running -> stopped\n */\n#define set_current_state(_state, to) \t\t\\\n\tdo {\t\t\t \t\t\\\n\t\tcurrent->state = (_state); \t\\\n\t\tcurrent->delay = (to);\t\t\\\n\t\tsmp_mb();\t\t\t\\\n\t} while (0)\n\nvoid do_release_task(struct task *task);\n\nstruct task *create_task(char *name,\n\t\ttask_func_t func,\n\t\tsize_t stk_size,\n\t\tvoid *usp,\n\t\tint prio,\n\t\tint aff,\n\t\tunsigned long opt,\n\t\tvoid *arg);\n\nstruct task *create_vcpu_task(char *name, task_func_t func, int aff,\n\t\tunsigned long flags, void *vcpu);\n\nstruct task *create_kthread(char *name, task_func_t func, int prio,\n\t\tint aff, unsigned long opt, void *arg);\n\nvoid os_for_all_task(void (*hdl)(struct task *task));\n\nvoid task_die(void);\nvoid task_suspend(void);\n\n#endif\n\n"
  },
  {
    "path": "kernel/include/minos/task_def.h",
    "content": "#ifndef __TASK_DEF_H__\n#define __TASK_DEF_H__\n\n#include <minos/types.h>\n#include <minos/task_info.h>\n#include <minos/list.h>\n#include <minos/atomic.h>\n#include <minos/timer.h>\n#include <asm/tcb.h>\n\n#ifdef CONFIG_TASK_STACK_SIZE\n#define TASK_STACK_SIZE\tCONFIG_TASK_STACK_SIZE\n#else\n#define TASK_STACK_SIZE (2 * PAGE_SIZE)\n#endif\n\n#ifndef CONFIG_NR_TASKS\n#define CONFIG_NR_TASKS 256\n#endif\n\n#define OS_NR_TASKS CONFIG_NR_TASKS\n\n#define OS_PRIO_MAX\t\t8\n#define OS_PRIO_DEFAULT_0\t0\n#define OS_PRIO_DEFAULT_1\t1\n#define OS_PRIO_DEFAULT_2\t2\n#define OS_PRIO_DEFAULT_3\t3\n#define OS_PRIO_DEFAULT_4\t4\n#define OS_PRIO_DEFAULT_5\t5\n#define OS_PRIO_DEFAULT_6\t6\n#define OS_PRIO_DEFAULT_7\t7\n\n#define OS_PRIO_REALTIME\tOS_PRIO_DEFAULT_0\n#define OS_PRIO_SRV\t\tOS_PRIO_DEFAULT_2\n#define OS_PRIO_SYSTEM\t\tOS_PRIO_DEFAULT_3\n#define OS_PRIO_VCPU\t\tOS_PRIO_DEFAULT_4\n#define OS_PRIO_DEFAULT\t\tOS_PRIO_DEFAULT_5\n#define OS_PRIO_IDLE\t\tOS_PRIO_DEFAULT_7\n#define OS_PRIO_LOWEST\t\tOS_PRIO_IDLE\n\n#define TASK_FLAGS_SRV\t\t\tBIT(0) // should not change, need keep same as pangu\n#define TASK_FLAGS_DRV\t\t\tBIT(1)\n#define TASK_FLAGS_VCPU\t\t\tBIT(2)\n#define TASK_FLAGS_REALTIME\t\tBIT(3)\n\n#define TASK_FLAGS_IDLE\t\t\tBIT(4)\n#define TASK_FLAGS_NO_AUTO_START\tBIT(5)\n#define TASK_FLAGS_32BIT\t\tBIT(6)\n#define TASK_FLAGS_PERCPU\t\tBIT(7)\n#define TASK_FLAGS_DEDICATED_HEAP\tBIT(8)\n#define TASK_FLAGS_ROOT\t\t\tBIT(9)\n#define TASK_FLAGS_KERNEL\t\tBIT(10)\n\n#define TASK_AFF_ANY\t\t(-1)\n#define TASK_NAME_SIZE\t\t(32)\n\n#define TASK_STATE_RUNNING 0x00\n#define TASK_STATE_READY 0x01\n#define TASK_STATE_WAIT_EVENT 0x02\n#define TASK_STATE_WAKING 0x04\n#define TASK_STATE_SUSPEND 0x08\n#define TASK_STATE_STOP 0x10\n\n#define KWORKER_FLAG_MASK 0xffff\n#define KWORKER_TASK_RECYCLE BIT(0)\n\n#define TASK_STATE_PEND_OK       0u  /* Pending status OK, not pending, or pending complete */\n#define TASK_STATE_PEND_TO       1u  /* Pending timed out */\n#define TASK_STATE_PEND_ABORT    2u  /* Pending aborted */\n\n#define KWORKER_FLAG_MASK\t0xffff\n#define KWORKER_TASK_RECYCLE\tBIT(0)\n\n#define TASK_WAIT_FOREVER\t(0xfffffffe)\n\ntypedef int (*task_func_t)(void *data);\n\nstruct vspace;\n\nstruct task {\n\tstruct task_info ti;\n\n\tvoid *stack_base;\n\tvoid *stack_top;\n\tvoid *stack_bottom;\n\n\tgp_regs *user_regs;\n\n\tunsigned long flags;\n\n\tint pid;\n\tint tid;\n\n\tstruct list_head list;\n\tstruct list_head proc_list;\n\tstruct list_head task_list;\t// link to the task list, if is a thread.\n\tstruct list_head state_list;\t// link to the sched list used for sched.\n\n\tuint32_t delay;\n\tstruct timer delay_timer;\n\n\t/*\n\t * the next task belongs to the same process\n\t */\n\tstruct task *next;\n\n\t/*\n\t * the spinlock will use to protect the below member\n\t * which may modified by different cpu at the same\n\t * time:\n\t * 1 - state\n\t * 2 - pend_state\n\t */\n\tspinlock_t s_lock;\n\tint state;\n\tlong pend_state;\n\n\tint wait_type;\t\t\t// which event is task waitting for.\n\tvoid *wait_event;\t\t// the event instance which the task is waitting.\n\tstruct list_head event_list;\n\tstruct flag_node *flag_node;\t// used for the flag event.\n\tunion {\n\t\tunsigned long ipcdata;\n\t\tlong retcode;\n\t\tvoid *msg;\n\t\tlong flags_rdy;\n\t};\n\n\t/*\n\t * affinity - the cpu node which the task affinity to\n\t */\n\tint cpu;\n\tint last_cpu;\n\tint affinity;\n\tint prio;\n\n\tunsigned long run_time;\n\n\tunsigned long ctx_sw_cnt;\t// switch count of this task.\n\tunsigned long start_ns;\t\t// when the task started last time.\n\n\tchar name[TASK_NAME_SIZE];\n\n\tvoid (*exit_from_user)(struct task *task, gp_regs *regs);\n\tvoid (*return_to_user)(struct task *task, gp_regs *regs);\n\n\tstruct vspace *vs;\t\t// the virtual memory space of this task.\n\n\tvoid *pdata;\t\t\t// the private data of this task for vcpu or process.\n\n\tstruct cpu_context cpu_context;\n} __cache_line_align;\n\n#define OS_TASK_RESERVED\t((struct task *)1)\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/task_info.h",
    "content": "#ifndef __MINOS_TASK_INFO_H__\n#define __MINOS_TASK_INFO_H__\n\n#include <minos/const.h>\n\n#define TIF_NEED_RESCHED\t0\n#define TIF_32BIT\t\t1\n#define TIF_DONOT_PREEMPT\t2\n#define TIF_TICK_EXHAUST\t3\n#define TIF_IN_USER\t\t4\n#define TIF_HARDIRQ_MASK\t8\n#define TIF_SOFTIRQ_MASK\t9\n#define TIF_NEED_STOP\t\t10\n#define TIF_NEED_FREEZE\t\t11\n#define TIF_WAIT_INTERRUPTED\t12\n\n#define __TIF_NEED_RESCHED\t(UL(1) << TIF_NEED_RESCHED)\n#define __TIF_32BIT\t\t(UL(1) << TIF_32BIT)\n#define __TIF_DONOT_PREEMPT\t(UL(1) << TIF_DONOT_PREEMPT)\n#define __TIF_TICK_EXHAUST\t(UL(1) << TIF_TICK_EXHAUST)\n#define __TIF_IN_USER\t\t(UL(1) << TIF_IN_USER)\n#define __TIF_HARDIRQ_MASK\t(UL(1) << TIF_HARDIRQ_MASK)\n#define __TIF_SOFTIRQ_MASK\t(UL(1) << TIF_SOFTIRQ_MASK)\n#define __TIF_NEED_STOP\t\t(UL(1) << TIF_NEED_STOP)\n#define __TIF_NEED_FREEZE\t(UL(1) << TIF_NEED_FREEZE) // only used for VCPU.\n#define __TIF_WAIT_INTERRUPTED\t(UL(1) << TIF_WAIT_INTERRUPTED)\n\n#define __TIF_IN_INTERRUPT\t(__TIF_HARDIRQ_MASK | __TIF_SOFTIRQ_MASK)\n\n#ifndef __ASSEMBLY__\n\n#include <config/config.h>\n#include <minos/bitops.h>\n#include <asm/asm_current.h>\n\n/*\n * this task_info is stored at the top of the task's\n * stack\n */\nstruct task_info {\n\tint preempt_count;\n\tunsigned long flags;\n};\n\nstatic inline struct task *get_current_task(void)\n{\n\treturn (struct task *)asm_get_current_task();\n}\n\nstatic inline struct task_info *get_current_task_info(void)\n{\n\treturn (struct task_info *)asm_get_current_task_info();\n}\n\nstatic inline void set_current_task(struct task *task)\n{\n\tasm_set_current_task(task);\n}\n\nstatic inline void set_need_resched(void)\n{\n\tget_current_task_info()->flags |= __TIF_NEED_RESCHED;\n\twmb();\n}\n\nstatic inline void clear_need_resched(void)\n{\n\tget_current_task_info()->flags &= ~__TIF_NEED_RESCHED;\n\twmb();\n}\n\nstatic inline void clear_do_not_preempt(void)\n{\n\tget_current_task_info()->flags &= ~__TIF_DONOT_PREEMPT;\n\twmb();\n}\n\nstatic inline int need_resched(void)\n{\n\treturn !!(get_current_task_info()->flags & __TIF_NEED_RESCHED);\n}\n\nstatic inline void do_not_preempt(void)\n{\n\tget_current_task_info()->flags |= __TIF_DONOT_PREEMPT;\n\twmb();\n}\n\nstatic inline int in_interrupt(void)\n{\n\treturn (get_current_task_info()->flags & __TIF_IN_INTERRUPT);\n}\n\n#endif\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/time.h",
    "content": "#ifndef _MINOS_TIME_H_\n#define _MINOS_TIME_H_\n\n#include <asm/time.h>\n#include <minos/stdlib.h>\n\n#define NOW()\t\t\tget_sys_time()\n#define SYSTEM_TIME_HZ  \t1000000000ULL\n#define SECONDS(s)     \t\t((uint64_t)((s)  * 1000000000ULL))\n#define MILLISECS(ms)  \t\t((uint64_t)((ms) * 1000000ULL))\n#define MICROSECS(us)  \t\t((uint64_t)((us) * 1000ULL))\n\n#define CLOCK_REALTIME           0\n#define CLOCK_MONOTONIC          1\n#define CLOCK_PROCESS_CPUTIME_ID 2\n#define CLOCK_THREAD_CPUTIME_ID  3\n#define CLOCK_MONOTONIC_RAW      4\n#define CLOCK_REALTIME_COARSE    5\n#define CLOCK_MONOTONIC_COARSE   6\n#define CLOCK_BOOTTIME           7\n#define CLOCK_REALTIME_ALARM     8\n#define CLOCK_BOOTTIME_ALARM     9\n#define CLOCK_SGI_CYCLE         10\n#define CLOCK_TAI               11\n\nstruct timespec {\n\tlong tv_sec;\n\tlong tv_nsec;\n};\n\nstatic inline unsigned long ticks_to_ns(uint64_t ticks)\n{\n\treturn muldiv64(ticks, SECONDS(1), 1000 * cpu_khz);\n}\n\nstatic inline uint64_t ns_to_ticks(unsigned long ns)\n{\n\treturn muldiv64(ns, 1000 * cpu_khz, SECONDS(1));\n}\n\nstatic inline void enable_timer(unsigned long e)\n{\n\tarch_enable_timer(e);\n}\n\nvoid udelay(uint32_t us);\nvoid mdelay(uint32_t ms);\nvoid msleep(uint32_t ms);\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/timer.h",
    "content": "#ifndef _MINOS_TIMER_H_\n#define _MINOS_TIMER_H_\n\n/*\n * refer to linux kernel timer code\n */\n#include <minos/list.h>\n#include <minos/types.h>\n#include <minos/spinlock.h>\n\ntypedef void (*timer_func_t)(unsigned long);\n\nstruct timer {\n\tint cpu;\n\tint stop;\n\tuint64_t expires;\n\tuint64_t timeout;\n\ttimer_func_t function;\n\tunsigned long data;\n\tstruct list_head entry;\n\tstruct raw_timer *raw_timer;\n};\n\n/*\n * raw timer is a hardware timer which use to\n * handle timer request.\n */\nstruct raw_timer {\n\tstruct list_head active;\n\tstruct timer *next_timer;\n\tstruct timer *running_timer;\n\tspinlock_t lock;\n};\n\nvoid init_timer(struct timer *timer, timer_func_t fn,\n\t\tunsigned long data);\n\nint start_timer(struct timer *timer);\nint stop_timer(struct timer *timer);\nint read_timer(struct timer *timer);\nvoid setup_timer(struct timer *timer, uint64_t tval);\nvoid setup_and_start_timer(struct timer *timer, uint64_t tval);\nint mod_timer(struct timer *timer, uint64_t cval);\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/tty.h",
    "content": "#ifndef __MINOS__TTY_H__\n#define __MINOS_TTY_H__\n\n#include <minos/types.h>\n#include <minos/list.h>\n\nstruct tty;\n\n#define TTY_NAME_SIZE\t16\n\nstruct tty_ops {\n\tint (*put_char)(struct tty *tty, char ch);\n\tint (*put_chars)(struct tty *tty, char *str, int count);\n\tint (*open)(struct tty *tty);\n\tvoid (*close)(struct tty *tty);\n};\n\nstruct tty {\n\tchar name[TTY_NAME_SIZE];\n\tuint32_t id;\n\tint open;\n\tint flags;\n\tstruct tty_ops *ops;\n\tvoid *pdata;\n\tstruct list_head list;\n};\n\nstruct tty *alloc_tty(char *name, uint32_t id, int flags);\nint register_tty(struct tty *tty);\nint release_tty(struct tty *tty);\nvoid close_tty(struct tty *tty);\nstruct tty *open_tty(char *name);\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/types.h",
    "content": "#ifndef _MINOS_TYPES_H_\n#define _MINOS_TYPES_H_\n\n#include <asm/asm_types.h>\n#include <asm/barrier.h>\n#include <minos/compiler.h>\n#include <minos/const.h>\n#include <config/config.h>\n\ntypedef __u32\tu32;\ntypedef __s32\ts32;\ntypedef __u16\tu16;\ntypedef __s16\ts16;\ntypedef __u8\tu8;\ntypedef __s8\ts8;\ntypedef __u64\tu64;\ntypedef __s64\ts64;\n\ntypedef __u32\tuint32_t;\ntypedef __s32\tint32_t;\ntypedef __u16\tuint16_t;\ntypedef __s16\tint16_t;\ntypedef __u8\tuint8_t;\ntypedef __s8\tint8_t;\ntypedef __u64\tuint64_t;\ntypedef __s64\tint64_t;\n\ntypedef long ssize_t;\ntypedef unsigned long size_t;\n\ntypedef unsigned long phy_addr_t;\ntypedef unsigned long virt_addr_t;\ntypedef unsigned long paddr_t;\ntypedef unsigned long vaddr_t;\n\ntypedef int16_t handle_t;\ntypedef uint32_t right_t;\n\ntypedef int16_t tid_t;\ntypedef int16_t pid_t;\n\ntypedef unsigned long uintptr_t;\ntypedef int irqreturn_t;\n\ntypedef int bool;\n\ntypedef uint64_t pgd_t;\ntypedef uint64_t pud_t;\ntypedef uint64_t pmd_t;\ntypedef uint64_t pte_t;\n\nenum {\n\tfalse = 0,\n\ttrue  = 1,\n};\n\n#define FILENAME_MAX\t256\n\n#define ULONG(v)\t((unsigned long)(v))\n\n#define MAX(a, b)\t(a) > (b) ? (a) : (b)\n#define MIN(a, b)\t(a) < (b) ? (a) : (b)\n#define max(a, b)\t(a) > (b) ? (a) : (b)\n#define min(a, b)\t(a) < (b) ? (a) : (b)\n\n#define ERROR_PTR(value)\t\\\n\t(void *)(unsigned long)(value)\n\n#define IS_ERROR_PTR(ptr)\t\\\n\t(((long)(ptr)) > -4096 && ((long)(ptr) < 4096))\n\n#define u8_to_u16(low, high)\t((high << 8) | low)\n#define u8_to_u32(u1, u2, u3, u4)\t\\\n\t((u4 << 24) | (u3 << 16) | (u2 << 8) | (u1))\n#define u16_to_u32(low, high)\t((high << 16) | low)\n\n#define offsetof(TYPE, MEMBER)  ((size_t)&((TYPE *)0)->MEMBER)\n\n#define NULL ((void *)0)\ntypedef void (*void_func_t)(void);\n\n#define container_of(ptr, name, member) \\\n\t(name *)((unsigned char *)ptr - ((unsigned char *)&(((name *)0)->member)))\n\n#define BIT(nr) (ULONG(1) << (nr))\n\n#define stringify_no_expansion(x) #x\n#define stringify(x) stringify_no_expansion(x)\n\n#define SIZE_1G\t\t(0x40000000UL)\n#define SIZE_4K\t\t(0x1000)\n#define SIZE_1M\t\t(0x100000)\n#define SIZE_1K\t\t(0x400)\n\n#define SIZE_16K\t(16 * SIZE_1K)\n#define SIZE_32M\t(32 * SIZE_1M)\n#define SIZE_64K\t(64 * SIZE_1K)\n#define SIZE_512M\t(512 * SIZE_1M)\n#define SIZE_2M\t\t(2 * 1024 * 1024)\n#define SIZE_8M\t\t(8 * 1024 * 1024)\n\n#define PAGE_SIZE\t(SIZE_4K)\n#define PAGE_SHIFT\t(12)\n#define PAGE_MASK\t(0xfffUL)\n\n#define BLOCK_SIZE\t(0x200000)\n#define BLOCK_SHIFT\t(21)\n\n#define PAGES_PER_BLOCK\t(BLOCK_SIZE >> PAGE_SHIFT)\n\n#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))\n\n#define INVALID_ADDR\t0\n\n#define BITS_PER_BYTE\t(8)\n\n#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))\n\n#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))\n\n#define DECLARE_BITMAP(name, bits) \\\n\tunsigned long name[BITS_TO_LONGS(bits)]\n\n#define BITMAP_SIZE(size)\t(BITS_TO_LONGS((size)) * sizeof(long))\n\n#define BITS_PER_LONG\t\t64\n#define BIT_ULL(nr)\t\t(1ULL << (nr))\n#define BIT_MASK(nr)\t\t(1UL << ((nr) % BITS_PER_LONG))\n#define BIT_WORD(nr)\t\t((nr) / BITS_PER_LONG)\n#define BIT_ULL_MASK(nr)\t(1ULL << ((nr) % BITS_PER_LONG_LONG))\n#define BIT_ULL_WORD(nr)\t((nr) / BITS_PER_LONG_LONG)\n\n#define __round_mask(x, y) \t((__typeof__(x))((y)-1))\n#define round_up(x, y) \t\t((((x)-1) | __round_mask(x, y))+1)\n#define round_down(x, y) \t((x) & ~__round_mask(x, y))\n\n#define ALIGN(x, y)\t((x) & ~__round_mask(x, y))\n#define BALIGN(x, y)\t(((x) + (y) - 1) & ~__round_mask(x, y))\n\n#define PAGE_BALIGN(x)\tBALIGN((unsigned long)(x), PAGE_SIZE)\n#define PAGE_ALIGN(x)\tALIGN((unsigned long)(x), PAGE_SIZE)\n\n#define BLOCK_BALIGN(x)\tBALIGN((unsigned long)(x), BLOCK_SIZE)\n#define BLOCK_ALIGN(x)\tALIGN((unsigned long)(x), BLOCK_SIZE)\n\n#define PAGE_NR(size)\t(PAGE_BALIGN(size) >> PAGE_SHIFT)\n\n#define IS_PAGE_ALIGN(x)\t(!((unsigned long)(x) & (PAGE_SIZE - 1)))\n#define IS_BLOCK_ALIGN(x)\t(!((unsigned long)(x) & (0x1fffff)))\n\n#define __IN_RANGE_UNSIGNED(sbase, ssize, dbase, dsize) \\\n\t(((sbase) >= (dbase)) && (((sbase) + (ssize) - 1) < ((dbase) + (dsize))))\n\n#define IN_RANGE_UNSIGNED(sbase, ssize, dbase, dsize) \\\n\t__IN_RANGE_UNSIGNED((unsigned long)(sbase), (unsigned long)(ssize), (unsigned long)(dbase), (size_t)(dsize))\n\n#define __stringify_1(x...) #x\n#define __stringify(x...)   __stringify_1(x)\n\n#define GENMASK(h, l) \\\n    (((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h))))\n\n#define GENMASK_ULL(h, l) \\\n    (((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONG - 1 - (h))))\n\n#define INT_MAX \t(2147483647)\n#define INT_MIN\t\t(-2147483648)\n\n#define BUG() \\\n\twhile (1)\n\n#define NR_CPUS\t\tCONFIG_NR_CPUS\n\n#define BAD_ADDRESS (-1)\n\n#define OS_PRIO_MAX 8\n\nextern int8_t const ffs_one_table[256];\n\ntypedef uint32_t flag_t;\n\ntypedef struct {\n\tint value;\n} atomic_t;\n\n/*\n * [0  - 15] - current number\n * [16 - 31] - next number\n */\ntypedef struct spinlock {\n#ifdef CONFIG_SMP\n\tint current_ticket;\n\tint next_ticket;\n#endif\n} spinlock_t;\n\nstatic inline void __write_once_size(volatile void *p, void *res, int size)\n{\n\tswitch (size) {\n\tcase 1: *(volatile uint8_t *)p = *(uint8_t *)res; break;\n\tcase 2: *(volatile uint16_t *)p = *(uint16_t *)res; break;\n\tcase 4: *(volatile uint32_t *)p = *(uint32_t *)res; break;\n\tcase 8: *(volatile uint64_t *)p = *(uint64_t *)res; break;\n\tdefault:\n\t\tbarrier();\n\t\t__builtin_memcpy((void *)p, (const void *)res, size);\n\t\tbarrier();\n\t}\n}\n\n#define WRITE_ONCE(x, val) \\\n({\t\t\t\t\t\t\t\\\n\tunion { typeof(x) __val; char __c[1]; } __u =\t\\\n\t\t{ .__val = (typeof(x)) (val) }; \\\n\t__write_once_size(&(x), __u.__c, sizeof(x));\t\\\n\t__u.__val;\t\t\t\t\t\\\n})\n\n#endif\n"
  },
  {
    "path": "kernel/include/minos/varlist.h",
    "content": "#ifndef _MINOS_VARLIST_H_\n#define _MINOS_VARLIST_H_\n\n#include <stdarg.h>\n\n\n/*\n * offset(n)\t\t get the offset align of the stack for different arch\n * va_start(ap,n)\t to get the second var of the function in the stack\n * va_end\t\t just a indicate of the va_list operation ending.\n * va_arg(ap,type)\t get the value of the var,\n */\n\n#if 0\ntypedef char *va_list;\n#define addr(n)\t\t(&n)\n#define offset(n) \\\n\t((sizeof(n) + sizeof(unsigned long) - 1) & ~(sizeof(unsigned long) - 1))\n\n#define va_start(ap, n) \\\n\t((ap) = ((char *)(&n)) + offset(n))\n\n#define va_end(ap)\t(void)0\n\n#define va_arg(ap, type) \\\n\t(*(type *)((ap) += offset(type), (ap) - offset(type)))\n#define\tva_start(ap, last) \\\n\t__builtin_va_start((ap), (last))\n\n#define\tva_arg(ap, type) \\\n\t__builtin_va_arg((ap), type)\n\n#define\t__va_copy(dest, src) \\\n\t__builtin_va_copy((dest), (src))\n#endif\n\n#endif\n"
  },
  {
    "path": "kernel/include/uapi/kobject_uapi.h",
    "content": "#ifndef __MINOS_KOBJECT_UAPI_H__\n#define __MINOS_KOBJECT_UAPI_H__\n\n#define KOBJ_RIGHT_NONE\t\t0x0000\t\t// do not have any right.\n#define KOBJ_RIGHT_READ\t\t0x0001\t\t// can read this kobject, usually for IPC between two process.\n#define KOBJ_RIGHT_WRITE\t0x0002\t\t// can write this kobject, usually for IPC between two process.\n#define KOBJ_RIGHT_EXEC\t\t0x0004\t\t// can be exectued.\n#define KOBJ_RIGHT_MMAP\t\t0x0008\t\t// can be mapped to process address space\n#define KOBJ_RIGHT_CTL\t\t0x0010\t\t// can call kobject_ctl for this kobject\n#define KOBJ_RIGHT_MASK\t\t0x001f\n\n#define KOBJ_RIGHT_RW\t\t(KOBJ_RIGHT_READ | KOBJ_RIGHT_WRITE)\n#define KOBJ_RIGHT_RO\t\t(KOBJ_RIGHT_READ)\n#define KOBJ_RIGHT_WO\t\t(KOBJ_RIGHT_WRITE)\n#define KOBJ_RIGHT_RWX\t\t(KOBJ_RIGHT_RW | KOBJ_RIGHT_EXEC)\n\nenum {\n\tKOBJ_TYPE_NONE,\n\tKOBJ_TYPE_PROCESS,\t// process, can be only created by root service\n\tKOBJ_TYPE_NOTIFY,\t// a port, which is a service hub\n\tKOBJ_TYPE_PMA,\t\t// physical memory region, usually used to shared with each other.\t\n\tKOBJ_TYPE_ENDPOINT,\t// endpoint, an point to point ipc way\n\tKOBJ_TYPE_SOCKET,\t// point to point ipc way.\n\tKOBJ_TYPE_VM,\t\t// virtual machine, for Virtualization\n\tKOBJ_TYPE_VCPU,\t\t// vcpu for vm\n\tKOBJ_TYPE_IRQ,\t\t// irq for user-space driver\n\tKOBJ_TYPE_VIRQ,\t\t// virq for vcpu process in user-space.\n\tKOBJ_TYPE_STDIO,\t// dedicated for system debuging\n\tKOBJ_TYPE_POLLHUB,\t// hub for events need to send.\n\tKOBJ_TYPE_PORT,\n\tKOBJ_TYPE_MAX\n};\n\nenum {\n\tKOBJ_GET_MMAP_ADDR = 0x100,\n};\n\n/*\n * for process control\n */\nenum {\n\tKOBJ_PROCESS_GET_PID = 0x1000,\n\tKOBJ_PROCESS_SETUP_SP,\n\tKOBJ_PROCESS_SETUP_REG0,\n\tKOBJ_PROCESS_WAKEUP,\n\tKOBJ_PROCESS_KILL,\n\tKOBJ_PROCESS_GRANT_RIGHT,\n\tKOBJ_PROCESS_SET_NAME,\n};\n\nstruct process_create_arg {\n        unsigned long entry;\n\tunsigned long stack;\n\tint aff;\n\tint prio;\n\tint pid;\n\tint flags;\n};\n\n/*\n * for pma kobject\n */\nenum {\n\tPMA_TYPE_NORMAL = 0,\n\tPMA_TYPE_MMIO,\n\tPMA_TYPE_DMA,\n\tPMA_TYPE_PMEM,\n\tPMA_TYPE_KCACHE,\n\tPMA_TYPE_MAX\n};\n\nenum {\n\tKOBJ_PMA_ADD_PAGES = 0x4000,\n\tKOBJ_PMA_GET_SIZE,\n};\n\nstruct pma_create_arg {\n\tint type;\n\tint right;\n\tint consequent;\n\tunsigned long start;\n\tunsigned long size;\n};\n\n/*\n * for kobject poll\n */\nenum {\n\tKOBJ_POLLHUB_OP_BASE = 0x2000,\n\tKOBJ_POLL_OP_ADD,\n\tKOBJ_POLL_OP_DEL,\n\tKOBJ_POLL_OP_MOD,\n};\n\n#endif\n"
  },
  {
    "path": "kernel/include/uapi/procinfo_uapi.h",
    "content": "#ifndef __MINOS_PROC_UAPI_INFO_H__\n#define __MINOS_PROC_UAPI_INFO_H__\n\n#define PROC_NAME_SIZE 256\n\nstruct task_stat {\n\tint tid;\n\tint root_tid;\n\tint pid;\n\tint state;\n\tint cpu;\n\tint cpu_usage;\n\tint prio;\n\tunsigned long long start_ns;\n\tchar cmd[PROC_NAME_SIZE];\n};\n\n#endif\n"
  },
  {
    "path": "kernel/include/uspace/elf.h",
    "content": "#ifndef __MINOS_ELF_H__\n#define __MINOS_ELF_H__\n\n#include <minos/types.h>\n\ntypedef uint8_t     Elf_Byte;\n\ntypedef uint32_t    Elf32_Addr;    /* Unsigned program address */\ntypedef uint32_t    Elf32_Off;     /* Unsigned file offset */\ntypedef int32_t     Elf32_Sword;   /* Signed large integer */\ntypedef uint32_t    Elf32_Word;    /* Unsigned large integer */\ntypedef uint16_t    Elf32_Half;    /* Unsigned medium integer */\n\ntypedef uint64_t    Elf64_Addr;\ntypedef uint64_t    Elf64_Off;\ntypedef int32_t     Elf64_Shalf;\n\n#ifdef __alpha__\ntypedef int64_t     Elf64_Sword;\ntypedef uint64_t    Elf64_Word;\n#else\ntypedef int32_t     Elf64_Sword;\ntypedef uint32_t    Elf64_Word;\n#endif\n\ntypedef int64_t     Elf64_Sxword;\ntypedef uint64_t    Elf64_Xword;\n\ntypedef uint32_t    Elf64_Half;\ntypedef uint16_t    Elf64_Quarter;\n\n#if defined(__i386__)\n#define EM_THIS EM_386\n#define EL_ARCH_USES_REL\n#elif defined(__amd64__)\n#define EM_THIS EM_AMD64\n#define EL_ARCH_USES_RELA\n#elif defined(__arm__)\n#define EM_THIS EM_ARM\n#elif defined(__aarch64__)\n#define EM_THIS EM_AARCH64\n#define EL_ARCH_USES_RELA\n#define EL_ARCH_USES_REL\n#else\n#error specify your ELF architecture\n#endif\n\n#if defined(__LP64__) || defined(__LLP64__)\n#define ELFSIZE 64\n#else\n#define ELFSIZE 32\n#endif\n\n#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__\n#define ELFDATATHIS ELFDATA2LSB\n#else\n#define ELFDATATHIS ELFDATA2MSB\n#endif\n\n#define EI_MAG0        0        /* file ID */\n#define EI_MAG1        1        /* file ID */\n#define EI_MAG2        2        /* file ID */\n#define EI_MAG3        3        /* file ID */\n#define EI_CLASS       4        /* file class */\n#define EI_DATA        5        /* data encoding */\n#define EI_VERSION     6        /* ELF header version */\n#define EI_OSABI       7        /* OS/ABI ID */\n#define EI_ABIVERSION  8        /* ABI version */\n#define EI_PAD         9        /* start of pad bytes */\n#define EI_NIDENT     16        /* Size of e_ident[] */\n\n/* e_ident[] magic number */\n#define    ELFMAG0        0x7f       /* e_ident[EI_MAG0] */\n#define    ELFMAG1        'E'        /* e_ident[EI_MAG1] */\n#define    ELFMAG2        'L'        /* e_ident[EI_MAG2] */\n#define    ELFMAG3        'F'        /* e_ident[EI_MAG3] */\n#define    ELFMAG        \"\\177ELF\"   /* magic */\n#define    SELFMAG        4          /* size of magic */\n\n/* e_ident[] file class */\n#define    ELFCLASSNONE    0        /* invalid */\n#define    ELFCLASS32    1          /* 32-bit objs */\n#define    ELFCLASS64    2          /* 64-bit objs */\n#define    ELFCLASSNUM    3         /* number of classes */\n\n/* e_ident[] data encoding */\n#define ELFDATANONE    0            /* invalid */\n#define ELFDATA2LSB    1            /* Little-Endian */\n#define ELFDATA2MSB    2            /* Big-Endian */\n#define ELFDATANUM     3            /* number of data encode defines */\n\n/* e_ident[] Operating System/ABI */\n#define ELFOSABI_SYSV        0    /* UNIX System V ABI */\n#define ELFOSABI_HPUX        1    /* HP-UX operating system */\n#define ELFOSABI_NETBSD      2    /* NetBSD */\n#define ELFOSABI_LINUX       3    /* GNU/Linux */\n#define ELFOSABI_HURD        4    /* GNU/Hurd */\n#define ELFOSABI_86OPEN      5    /* 86Open common IA32 ABI */\n#define ELFOSABI_SOLARIS     6    /* Solaris */\n#define ELFOSABI_MONTEREY    7    /* Monterey */\n#define ELFOSABI_IRIX        8    /* IRIX */\n#define ELFOSABI_FREEBSD     9    /* FreeBSD */\n#define ELFOSABI_TRU64       10   /* TRU64 UNIX */\n#define ELFOSABI_MODESTO     11   /* Novell Modesto */\n#define ELFOSABI_OPENBSD     12   /* OpenBSD */\n#define ELFOSABI_ARM         97   /* ARM */\n#define ELFOSABI_STANDALONE  255  /* Standalone (embedded) application */\n\n/* e_ident */\n#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \\\n                      (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \\\n                      (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \\\n                      (ehdr).e_ident[EI_MAG3] == ELFMAG3)\n\n/* ELF Header */\ntypedef struct {\n    unsigned char    e_ident[EI_NIDENT];     /* ELF Identification */\n    Elf32_Half       e_type;                 /* object file type */\n    Elf32_Half       e_machine;              /* machine */\n    Elf32_Word       e_version;              /* object file version */\n    Elf32_Addr       e_entry;                /* virtual entry point */\n    Elf32_Off        e_phoff;                /* program header table offset */\n    Elf32_Off        e_shoff;                /* section header table offset */\n    Elf32_Word       e_flags;                /* processor-specific flags */\n    Elf32_Half       e_ehsize;               /* ELF header size */\n    Elf32_Half       e_phentsize;            /* program header entry size */\n    Elf32_Half       e_phnum;                /* number of program header entries */\n    Elf32_Half       e_shentsize;            /* section header entry size */\n    Elf32_Half       e_shnum;                /* number of section header entries */\n    Elf32_Half       e_shstrndx;             /* section header table's \"section\n                                                header string table\" entry offset */\n} Elf32_Ehdr;\n\ntypedef struct {\n    unsigned char    e_ident[EI_NIDENT];    /* Id bytes */\n    Elf64_Quarter    e_type;                /* file type */\n    Elf64_Quarter    e_machine;             /* machine type */\n    Elf64_Half       e_version;             /* version number */\n    Elf64_Addr       e_entry;               /* entry point */\n    Elf64_Off        e_phoff;               /* Program hdr offset */\n    Elf64_Off        e_shoff;               /* Section hdr offset */\n    Elf64_Half       e_flags;               /* Processor flags */\n    Elf64_Quarter    e_ehsize;              /* sizeof ehdr */\n    Elf64_Quarter    e_phentsize;           /* Program header entry size */\n    Elf64_Quarter    e_phnum;               /* Number of program headers */\n    Elf64_Quarter    e_shentsize;           /* Section header entry size */\n    Elf64_Quarter    e_shnum;               /* Number of section headers */\n    Elf64_Quarter    e_shstrndx;            /* String table index */\n} Elf64_Ehdr;\n\n/* e_type */\n#define ET_NONE        0        /* No file type */\n#define ET_REL         1        /* relocatable file */\n#define ET_EXEC        2        /* executable file */\n#define ET_DYN         3        /* shared object file */\n#define ET_CORE        4        /* core file */\n#define ET_NUM         5        /* number of types */\n#define ET_LOPROC      0xff00   /* reserved range for processor */\n#define ET_HIPROC      0xffff   /*  specific e_type */\n\n/* e_machine */\n#define EM_NONE        0        /* No Machine */\n#define EM_M32         1        /* AT&T WE 32100 */\n#define EM_SPARC       2        /* SPARC */\n#define EM_386         3        /* Intel 80386 */\n#define EM_68K         4        /* Motorola 68000 */\n#define EM_88K         5        /* Motorola 88000 */\n#define EM_486         6        /* Intel 80486 - unused? */\n#define EM_860         7        /* Intel 80860 */\n#define EM_MIPS        8        /* MIPS R3000 Big-Endian only */\n/*\n * Don't know if EM_MIPS_RS4_BE,\n * EM_SPARC64, EM_PARISC,\n * or EM_PPC are ABI compliant\n */\n#define EM_MIPS_RS4_BE 10        /* MIPS R4000 Big-Endian */\n#define EM_SPARC64     11        /* SPARC v9 64-bit unofficial */\n#define EM_PARISC      15        /* HPPA */\n#define EM_SPARC32PLUS 18        /* Enhanced instruction set SPARC */\n#define EM_PPC         20        /* PowerPC */\n#define EM_ARM         40        /* ARM AArch32 */\n#define EM_ALPHA       41        /* DEC ALPHA */\n#define EM_SH          42        /* Hitachi/Renesas Super-H */\n#define EM_SPARCV9     43        /* SPARC version 9 */\n#define EM_IA_64       50        /* Intel IA-64 Processor */\n#define EM_AMD64       62        /* AMD64 architecture */\n#define EM_VAX         75        /* DEC VAX */\n#define EM_AARCH64     183       /* ARM AArch64 */\n\n/* Non-standard */\n#define EM_ALPHA_EXP   0x9026        /* DEC ALPHA */\n\n\n/* Version */\n#define EV_NONE        0        /* Invalid */\n#define EV_CURRENT     1        /* Current */\n#define EV_NUM         2        /* number of versions */\n\n/* Section Header */\ntypedef struct {\n    Elf32_Word    sh_name;      /* name - index into section header\n                                 * string table section */\n    Elf32_Word    sh_type;      /* type */\n    Elf32_Word    sh_flags;     /* flags */\n    Elf32_Addr    sh_addr;      /* address */\n    Elf32_Off     sh_offset;    /* file offset */\n    Elf32_Word    sh_size;      /* section size */\n    Elf32_Word    sh_link;      /* section header table index link */\n    Elf32_Word    sh_info;      /* extra information */\n    Elf32_Word    sh_addralign; /* address alignment */\n    Elf32_Word    sh_entsize;   /* section entry size */\n} Elf32_Shdr;\n\ntypedef struct {\n    Elf64_Half    sh_name;       /* section name */\n    Elf64_Half    sh_type;       /* section type */\n    Elf64_Xword   sh_flags;      /* section flags */\n    Elf64_Addr    sh_addr;       /* virtual address */\n    Elf64_Off     sh_offset;     /* file offset */\n    Elf64_Xword   sh_size;       /* section size */\n    Elf64_Half    sh_link;       /* link to another */\n    Elf64_Half    sh_info;       /* misc info */\n    Elf64_Xword   sh_addralign;  /* memory alignment */\n    Elf64_Xword   sh_entsize;    /* table entry size */\n} Elf64_Shdr;\n\n/* Special Section Indexes */\n#define SHN_UNDEF     0             /* undefined */\n#define SHN_LORESERVE 0xff00        /* lower bounds of reserved indexes */\n#define SHN_LOPROC    0xff00        /* reserved range for processor */\n#define SHN_HIPROC    0xff1f        /*   specific section indexes */\n#define SHN_ABS       0xfff1        /* absolute value */\n#define SHN_COMMON    0xfff2        /* common symbol */\n#define SHN_HIRESERVE 0xffff        /* upper bounds of reserved indexes */\n\n/* sh_type */\n#define SHT_NULL     0        /* inactive */\n#define SHT_PROGBITS 1        /* program defined information */\n#define SHT_SYMTAB   2        /* symbol table section */\n#define SHT_STRTAB   3        /* string table section */\n#define SHT_RELA     4        /* relocation section with addends*/\n#define SHT_HASH     5        /* symbol hash table section */\n#define SHT_DYNAMIC  6        /* dynamic section */\n#define SHT_NOTE     7        /* note section */\n#define SHT_NOBITS   8        /* no space section */\n#define SHT_REL      9        /* relation section without addends */\n#define SHT_SHLIB    10       /* reserved - purpose unknown */\n#define SHT_DYNSYM   11       /* dynamic symbol table section */\n#define SHT_NUM      12       /* number of section types */\n#define SHT_LOPROC   0x70000000    /* reserved range for processor */\n#define SHT_HIPROC   0x7fffffff    /*  specific section header types */\n#define SHT_LOUSER   0x80000000    /* reserved range for application */\n#define SHT_HIUSER   0xffffffff    /*  specific indexes */\n\n/* Section names */\n#define ELF_BSS         \".bss\"        /* uninitialized data */\n#define ELF_DATA        \".data\"       /* initialized data */\n#define ELF_DEBUG       \".debug\"      /* debug */\n#define ELF_DYNAMIC     \".dynamic\"    /* dynamic linking information */\n#define ELF_DYNSTR      \".dynstr\"     /* dynamic string table */\n#define ELF_DYNSYM      \".dynsym\"     /* dynamic symbol table */\n#define ELF_FINI        \".fini\"       /* termination code */\n#define ELF_GOT         \".got\"        /* global offset table */\n#define ELF_HASH        \".hash\"       /* symbol hash table */\n#define ELF_INIT        \".init\"       /* initialization code */\n#define ELF_REL_DATA    \".rel.data\"   /* relocation data */\n#define ELF_REL_FINI    \".rel.fini\"   /* relocation termination code */\n#define ELF_REL_INIT    \".rel.init\"   /* relocation initialization code */\n#define ELF_REL_DYN     \".rel.dyn\"    /* relocation dynamic link info */\n#define ELF_REL_RODATA  \".rel.rodata\" /* relocation read-only data */\n#define ELF_REL_TEXT    \".rel.text\"   /* relocation code */\n#define ELF_RODATA      \".rodata\"     /* read-only data */\n#define ELF_SHSTRTAB    \".shstrtab\"   /* section header string table */\n#define ELF_STRTAB      \".strtab\"     /* string table */\n#define ELF_SYMTAB      \".symtab\"     /* symbol table */\n#define ELF_TEXT        \".text\"       /* code */\n\n\n/* Section Attribute Flags - sh_flags */\n#define SHF_WRITE        0x1           /* Writable */\n#define SHF_ALLOC        0x2           /* occupies memory */\n#define SHF_EXECINSTR    0x4           /* executable */\n#define SHF_TLS          0x400         /* thread local storage */\n#define SHF_MASKPROC     0xf0000000    /* reserved bits for processor\n                                        *  specific section attributes */\n\n/* Symbol Table Entry */\ntypedef struct elf32_sym {\n    Elf32_Word    st_name;     /* name - index into string table */\n    Elf32_Addr    st_value;    /* symbol value */\n    Elf32_Word    st_size;     /* symbol size */\n    unsigned char st_info;     /* type and binding */\n    unsigned char st_other;    /* 0 - no defined meaning */\n    Elf32_Half    st_shndx;    /* section header index */\n} Elf32_Sym;\n\ntypedef struct {\n    Elf64_Half    st_name;    /* Symbol name index in str table */\n    Elf_Byte      st_info;    /* type / binding attrs */\n    Elf_Byte      st_other;   /* unused */\n    Elf64_Quarter st_shndx;   /* section index of symbol */\n    Elf64_Xword   st_value;   /* value of symbol */\n    Elf64_Xword   st_size;    /* size of symbol */\n} Elf64_Sym;\n\n/* Symbol table index */\n#define STN_UNDEF    0        /* undefined */\n\n/* Extract symbol info - st_info */\n#define ELF32_ST_BIND(x)    ((x) >> 4)\n#define ELF32_ST_TYPE(x)    (((unsigned int) x) & 0xf)\n#define ELF32_ST_INFO(b,t)  (((b) << 4) + ((t) & 0xf))\n\n#define ELF64_ST_BIND(x)    ((x) >> 4)\n#define ELF64_ST_TYPE(x)    (((unsigned int) x) & 0xf)\n#define ELF64_ST_INFO(b,t)  (((b) << 4) + ((t) & 0xf))\n\n/* Symbol Binding - ELF32_ST_BIND - st_info */\n#define STB_LOCAL    0        /* Local symbol */\n#define STB_GLOBAL   1        /* Global symbol */\n#define STB_WEAK     2        /* like global - lower precedence */\n#define STB_NUM      3        /* number of symbol bindings */\n#define STB_LOPROC  13        /* reserved range for processor */\n#define STB_HIPROC  15        /*  specific symbol bindings */\n\n/* Symbol type - ELF32_ST_TYPE - st_info */\n#define STT_NOTYPE    0        /* not specified */\n#define STT_OBJECT    1        /* data object */\n#define STT_FUNC      2        /* function */\n#define STT_SECTION   3        /* section */\n#define STT_FILE      4        /* file */\n#define STT_TLS       6        /* thread local storage */\n#define STT_LOPROC    13       /* reserved range for processor */\n#define STT_HIPROC    15       /*  specific symbol types */\n\n/* Relocation entry with implicit addend */\ntypedef struct {\n    Elf32_Addr    r_offset;    /* offset of relocation */\n    Elf32_Word    r_info;      /* symbol table index and type */\n} Elf32_Rel;\n\n/* Relocation entry with explicit addend */\ntypedef struct {\n    Elf32_Addr    r_offset;    /* offset of relocation */\n    Elf32_Word    r_info;      /* symbol table index and type */\n    Elf32_Sword   r_addend;\n} Elf32_Rela;\n\n/* Extract relocation info - r_info */\n#define ELF32_R_SYM(i)         ((i) >> 8)\n#define ELF32_R_TYPE(i)        ((unsigned char) (i))\n#define ELF32_R_INFO(s,t)      (((s) << 8) + (unsigned char)(t))\n\ntypedef struct {\n    Elf64_Xword    r_offset;    /* where to do it */\n    Elf64_Xword    r_info;      /* index & type of relocation */\n} Elf64_Rel;\n\ntypedef struct {\n    Elf64_Xword    r_offset;    /* where to do it */\n    Elf64_Xword    r_info;      /* index & type of relocation */\n    Elf64_Sxword    r_addend;   /* adjustment value */\n} Elf64_Rela;\n\n#define    ELF64_R_SYM(info)    ((info) >> 32)\n#define    ELF64_R_TYPE(info)   ((info) & 0xFFFFFFFF)\n#define    ELF64_R_INFO(s,t)    (((s) << 32) + (__uint32_t)(t))\n\n#if defined(__mips64__) && defined(__MIPSEL__)\n/*\n * The 64-bit MIPS ELF ABI uses a slightly different relocation format\n * than the regular ELF ABI: the r_info field is split into several\n * pieces (see gnu/usr.bin/binutils/include/elf/mips.h for details).\n */\n#undef    ELF64_R_SYM\n#undef    ELF64_R_TYPE\n#undef    ELF64_R_INFO\n#define   ELF64_R_TYPE(info)   (swap32((info) >> 32))\n#define   ELF64_R_SYM(info)    ((info) & 0xFFFFFFFF)\n#define   ELF64_R_INFO(s,t)    (((__uint64_t)swap32(t) << 32) + (__uint32_t)(s))\n#endif /* __mips64__ && __MIPSEL__ */\n\n/* Program Header */\ntypedef struct {\n    Elf32_Word    p_type;     /* segment type */\n    Elf32_Off     p_offset;   /* segment offset */\n    Elf32_Addr    p_vaddr;    /* virtual address of segment */\n    Elf32_Addr    p_paddr;    /* physical address - ignored? */\n    Elf32_Word    p_filesz;   /* number of bytes in file for seg. */\n    Elf32_Word    p_memsz;    /* number of bytes in mem. for seg. */\n    Elf32_Word    p_flags;    /* flags */\n    Elf32_Word    p_align;    /* memory alignment */\n} Elf32_Phdr;\n\ntypedef struct {\n    Elf64_Half    p_type;     /* entry type */\n    Elf64_Half    p_flags;    /* flags */\n    Elf64_Off     p_offset;   /* offset */\n    Elf64_Addr    p_vaddr;    /* virtual address */\n    Elf64_Addr    p_paddr;    /* physical address */\n    Elf64_Xword   p_filesz;   /* file size */\n    Elf64_Xword   p_memsz;    /* memory size */\n    Elf64_Xword   p_align;    /* memory & file alignment */\n} Elf64_Phdr;\n\n/* Segment types - p_type */\n#define PT_NULL        0          /* unused */\n#define PT_LOAD        1          /* loadable segment */\n#define PT_DYNAMIC     2          /* dynamic linking section */\n#define PT_INTERP      3          /* the RTLD */\n#define PT_NOTE        4          /* auxiliary information */\n#define PT_SHLIB       5          /* reserved - purpose undefined */\n#define PT_PHDR        6          /* program header */\n#define PT_TLS         7          /* thread local storage */\n#define PT_LOOS        0x60000000 /* reserved range for OS */\n#define PT_HIOS        0x6fffffff /*  specific segment types */\n#define PT_LOPROC      0x70000000 /* reserved range for processor */\n#define PT_HIPROC      0x7fffffff /*  specific segment types */\n\n#define PT_OPENBSD_RANDOMIZE 0x65a3dbe6 /* fill with random data */\n#define PT_GANDR_KERNEL      0x67646b6c /* gdkl */\n\n\n/* Segment flags - p_flags */\n#define PF_X        0x1        /* Executable */\n#define PF_W        0x2        /* Writable */\n#define PF_R        0x4        /* Readable */\n#define PF_MASKPROC 0xf0000000    /* reserved bits for processor */\n                    /*  specific segment flags */\n\n/* Dynamic structure */\ntypedef struct {\n    Elf32_Sword    d_tag;    /* controls meaning of d_val */\n    union {\n        Elf32_Word d_val;    /* Multiple meanings - see d_tag */\n        Elf32_Addr d_ptr;    /* program virtual address */\n    } d_un;\n} Elf32_Dyn;\n\ntypedef struct {\n    Elf64_Xword     d_tag;   /* controls meaning of d_val */\n    union {\n        Elf64_Addr  d_ptr;\n        Elf64_Xword d_val;\n    } d_un;\n} Elf64_Dyn;\n\n/* Dynamic Array Tags - d_tag */\n#define DT_NULL        0        /* marks end of _DYNAMIC array */\n#define DT_NEEDED      1        /* string table offset of needed lib */\n#define DT_PLTRELSZ    2        /* size of relocation entries in PLT */\n#define DT_PLTGOT      3        /* address PLT/GOT */\n#define DT_HASH        4        /* address of symbol hash table */\n#define DT_STRTAB      5        /* address of string table */\n#define DT_SYMTAB      6        /* address of symbol table */\n#define DT_RELA        7        /* address of relocation table */\n#define DT_RELASZ      8        /* size of relocation table */\n#define DT_RELAENT     9        /* size of relocation entry */\n#define DT_STRSZ      10        /* size of string table */\n#define DT_SYMENT     11        /* size of symbol table entry */\n#define DT_INIT       12        /* address of initialization func. */\n#define DT_FINI       13        /* address of termination function */\n#define DT_SONAME     14        /* string table offset of shared obj */\n#define DT_RPATH      15        /* string table offset of library\n                                 * search path */\n#define DT_SYMBOLIC   16        /* start sym search in shared obj. */\n#define DT_REL        17        /* address of rel. tbl. w addends */\n#define DT_RELSZ      18        /* size of DT_REL relocation table */\n#define DT_RELENT     19        /* size of DT_REL relocation entry */\n#define DT_PLTREL     20        /* PLT referenced relocation entry */\n#define DT_DEBUG      21        /* bugger */\n#define DT_TEXTREL    22        /* Allow rel. mod. to unwritable seg */\n#define DT_JMPREL     23        /* add. of PLT's relocation entries */\n#define DT_BIND_NOW   24        /* Bind now regardless of env setting */\n#define DT_LOOS       0x6000000d    /* reserved range for OS */\n#define DT_HIOS       0x6ffff000    /*  specific dynamic array tags */\n#define DT_LOPROC     0x70000000    /* reserved range for processor */\n#define DT_HIPROC     0x7fffffff    /*  specific dynamic array tags */\n\n/* some other useful tags */\n#define DT_RELACOUNT  0x6ffffff9    /* if present, number of RELATIVE */\n#define DT_RELCOUNT   0x6ffffffa    /* relocs, which must come first */\n#define DT_FLAGS_1    0x6ffffffb\n\n/* Dynamic Flags - DT_FLAGS_1 .dynamic entry */\n#define DF_1_NOW       0x00000001\n#define DF_1_GLOBAL    0x00000002\n#define DF_1_GROUP     0x00000004\n#define DF_1_NODELETE  0x00000008\n#define DF_1_LOADFLTR  0x00000010\n#define DF_1_INITFIRST 0x00000020\n#define DF_1_NOOPEN    0x00000040\n#define DF_1_ORIGIN    0x00000080\n#define DF_1_DIRECT    0x00000100\n#define DF_1_TRANS     0x00000200\n#define DF_1_INTERPOSE 0x00000400\n#define DF_1_NODEFLIB  0x00000800\n#define DF_1_NODUMP    0x00001000\n#define DF_1_CONLFAT   0x00002000\n\n/* ld.so: number of low tags that are used saved internally (0 .. DT_NUM-1) */\n#define DT_NUM        (DT_JMPREL+1)\n\n/*\n * Note Definitions\n */\ntypedef struct {\n    Elf32_Word namesz;\n    Elf32_Word descsz;\n    Elf32_Word type;\n} Elf32_Note;\n\ntypedef struct {\n    Elf64_Half namesz;\n    Elf64_Half descsz;\n    Elf64_Half type;\n} Elf64_Note;\n\n#define ELFSIZE\t64\n\n#if defined(ELFSIZE) && (ELFSIZE == 32)\n#define Elf_Ehdr    Elf32_Ehdr\n#define Elf_Phdr    Elf32_Phdr\n#define Elf_Shdr    Elf32_Shdr\n#define Elf_Sym     Elf32_Sym\n#define Elf_Rel     Elf32_Rel\n#define Elf_RelA    Elf32_Rela\n#define Elf_Dyn     Elf32_Dyn\n#define Elf_Half    Elf32_Half\n#define Elf_Word    Elf32_Word\n#define Elf_Sword   Elf32_Sword\n#define Elf_Addr    Elf32_Addr\n#define Elf_Off     Elf32_Off\n#define Elf_Nhdr    Elf32_Nhdr\n#define Elf_Note    Elf32_Note\n\n#define ELF_R_SYM   ELF32_R_SYM\n#define ELF_R_TYPE  ELF32_R_TYPE\n#define ELF_R_INFO  ELF32_R_INFO\n#define ELFCLASS    ELFCLASS32\n\n#define ELF_ST_BIND ELF32_ST_BIND\n#define ELF_ST_TYPE ELF32_ST_TYPE\n#define ELF_ST_INFO ELF32_ST_INFO\n\n#elif defined(ELFSIZE) && (ELFSIZE == 64)\n\n#define Elf_Ehdr    Elf64_Ehdr\n#define Elf_Phdr    Elf64_Phdr\n#define Elf_Shdr    Elf64_Shdr\n#define Elf_Sym     Elf64_Sym\n#define Elf_Rel     Elf64_Rel\n#define Elf_RelA    Elf64_Rela\n#define Elf_Dyn     Elf64_Dyn\n#define Elf_Half    Elf64_Half\n#define Elf_Word    Elf64_Word\n#define Elf_Sword   Elf64_Sword\n#define Elf_Addr    Elf64_Addr\n#define Elf_Off     Elf64_Off\n#define Elf_Nhdr    Elf64_Nhdr\n#define Elf_Note    Elf64_Note\n\n#define ELF_R_SYM   ELF64_R_SYM\n#define ELF_R_TYPE  ELF64_R_TYPE\n#define ELF_R_INFO  ELF64_R_INFO\n#define ELFCLASS    ELFCLASS64\n\n#define ELF_ST_BIND ELF64_ST_BIND\n#define ELF_ST_TYPE ELF64_ST_TYPE\n#define ELF_ST_INFO ELF64_ST_INFO\n\n#endif\n\n/* dedicated for minos */\n#define AT_SERVER_HANDLE 61/* for minos talk to root service */\n#define AT_HEAP_BASE 62\n#define AT_HEAP_END 63\n\n#endif\n"
  },
  {
    "path": "kernel/include/uspace/handle.h",
    "content": "#ifndef __MINOS_HANDLE_H__\n#define __MINOS_HANDLE_H__\n\n#include <minos/types.h>\n#include <minos/compiler.h>\n\nstruct kobject;\n\nstruct handle_desc {\n\tstruct kobject *kobj;\n\tint right;\n\tint padding;\n} __packed;\n\nstruct handle_table_desc {\n\tuint32_t index;\n\tuint32_t left;\n\tstruct handle_desc *next;\n} __packed;\n\n#define HANDLE_NULL\t(-1)\n\n#define NR_DESC_PER_PAGE (PAGE_SIZE / sizeof(struct handle_desc) - 1)\n#define PROC_MAX_HANDLE\t(NR_DESC_PER_PAGE * 128)\n\n#define WRONG_HANDLE(handle)\t\\\n\t((handle == HANDLE_NULL) || (handle >= PROC_MAX_HANDLE))\n\nvoid __release_handle(struct process *proc, handle_t handle);\nint release_handle(handle_t handle, struct kobject **kobj, right_t *right);\n\nhandle_t __alloc_handle(struct process *proc, struct kobject *kobj, right_t right);\n\nhandle_t alloc_handle(struct kobject *kobj, right_t right);\n\nint get_kobject_from_process(struct process *proc, handle_t handle,\n\t\t\tstruct kobject **kobj, right_t *right);\n\nint get_kobject(handle_t handle, struct kobject **kobj, right_t *right);\n\nint put_kobject(struct kobject *kobj);\n\nvoid release_proc_kobjects(struct process *proc);\n\nvoid process_handles_deinit(struct process *proc);\n\nint init_proc_handles(struct process *proc);\n\nhandle_t send_handle(struct process *psrc, struct process *pdst,\n\t\thandle_t handle, right_t right_send);\n\n#endif\n"
  },
  {
    "path": "kernel/include/uspace/iqueue.h",
    "content": "#ifndef __MINOS_IQUEUE_H__\n#define __MINOS_IQUEUE_H__\n\n#include <minos/list.h>\n#include <minos/sem.h>\n#include <minos/current.h>\n\nstruct kobject;\nstruct task;\n\n#define IMSG_STATE_INIT 0\n#define IMSG_STATE_IN_PROCESS 1\n#define IMSG_STATE_ERROR 2\n\nstruct imsg {\n\tvoid *data;\n\tlong token;\n\tlong retcode;\n\tint state;\n\tint submit;\n\tstruct list_head list;\n\tstruct event ievent;\n};\n\nstruct iqueue {\n\tint mutil_writer;\n\tint rstate;\n\tint wstate;\n\n\tspinlock_t lock;\n\tstruct list_head pending_list;\n\tstruct list_head processing_list;\n\tstruct kobject *kobj;\n\n\tsem_t isem;\n};\n\nstatic void inline imsg_init(struct imsg *imsg, struct task *task)\n{\n\timsg->data = task;\n\timsg->retcode = 0;\n\timsg->token = new_event_token();\n\timsg->state = IMSG_STATE_INIT;\n\timsg->submit = 0;\n\tevent_init(&imsg->ievent, OS_EVENT_TYPE_NORMAL, task);\n}\n\nlong iqueue_recv(struct iqueue *iqueue, void __user *data,\n\t\tsize_t data_size, size_t *actual_data, void __user *extra,\n\t\tsize_t extra_size, size_t *actual_extra, uint32_t timeout);\n\nlong iqueue_send(struct iqueue *iqueue, void __user *data, size_t data_size,\n\t\tvoid __user *extra, size_t extra_size, uint32_t timeout);\n\nint iqueue_reply(struct iqueue *iqueue, right_t right,\n\t\tlong token, long errno, handle_t fd, right_t fd_right);\n\nint iqueue_close(struct iqueue *iqueue, right_t right, struct process *proc);\n\nvoid iqueue_init(struct iqueue *iq, int mutil_writer, struct kobject *kobj);\n\n#endif\n"
  },
  {
    "path": "kernel/include/uspace/kobject.h",
    "content": "#ifndef __MINOS_KOBJECT_H__\n#define __MINOS_KOBJECT_H__\n\n#include <minos/types.h>\n#include <minos/compiler.h>\n#include <config/config.h>\n\n#include <uapi/kobject_uapi.h>\n\nstruct task;\nstruct process;\nstruct kobject_ops;\nstruct poll_struct;\n\n#define KOBJ_FLAGS_NON_SHARED\t(1 << 0)\n\n/*\n * Kernel object is a object than can provide some ability\n * to user space thread.\n *\n * type : the type of this kobj defined as above.\n * ref  : reference count of this kernel object, when\n *        0 can be released.\n * right_mask : the right mask for this kobj used for grant\n * list : list all the kernel object for a task or global.\n */\nstruct kobject {\n\tuint8_t type;\n\tuint8_t flags;\n\tuint16_t padding;\n\n\tright_t right_mask;\n\tatomic_t ref;\n\n\tspinlock_t lock;\n\tstruct poll_struct *poll_struct;\n\n\tstruct kobject_ops *ops;\n\tunsigned long data;\n\tstruct list_head list;\n};\n\nstruct kobject_ops {\n\tlong (*send)(struct kobject *kobj, void __user *data,\n\t\t\tsize_t data_size, void __user *extra,\n\t\t\tsize_t extra_size, uint32_t timeout);\n\n\tlong (*recv)(struct kobject *kobj, void __user *data,\n\t\t\tsize_t data_size, size_t *actual_data,\n\t\t\tvoid __user *extra, size_t extra_size,\n\t\t\tsize_t *actual_extra, uint32_t timeout);\n\n\tvoid (*release)(struct kobject *kobj);\n\n\tint (*open)(struct kobject *kobj, handle_t handle, right_t right);\n\n\tint (*poll)(struct kobject *ksrc, struct kobject *kdst, int event, bool enable);\n\n\tint (*close)(struct kobject *kobj, right_t right, struct process *proc);\n\n\tint (*reply)(struct kobject *kobj, right_t right, long token,\n\t\t\tlong err_code, handle_t fd, right_t fd_right);\n\n\tint (*mmap)(struct kobject *kobj, right_t right, void **addr, unsigned long *msize);\n\n\tint (*munmap)(struct kobject *kobj, right_t right);\n\n\tlong (*ctl)(struct kobject *kobj, int req, unsigned long data);\n};\n\ntypedef int(*kobject_create_cb)(struct kobject **kobj, right_t *right, unsigned long data);\n\nstruct kobject_desc {\n\tchar *name;\n\tint type;\n\tkobject_create_cb ops;\n};\n\n#define DEFINE_KOBJECT(kname, ktype, kops)\t\\\n\tstatic struct kobject_desc __kobject_##kname __used __section(\".__kobject_desc\") = { \\\n\t\t.name = #kname,\t\\\n\t\t.type = ktype,\t\\\n\t\t.ops  = kops,\t\\\n\t}\n\nvoid register_kobject_ops(struct kobject_ops *ops, int type);\n\nuint32_t kobject_token(void);\n\nint kobject_get(struct kobject *kobj);\n\nint kobject_put(struct kobject *kobj);\n\nvoid kobject_init(struct kobject *kobj, int type,\n\t\tright_t right_mask, unsigned long data);\n\nint kobject_close(struct kobject *kobj, right_t right, struct process *proc);\n\nint kobject_create(int type, struct kobject **kobj,\n\t\tright_t *right, unsigned long data);\n\nint kobject_poll(struct kobject *ksrc,\n\t\tstruct kobject *dst, int event, int enable);\n\nlong kobject_recv(struct kobject *kobj, void __user *data,\n\t\tsize_t data_size, size_t *actual_data,\n\t\tvoid __user *extra, size_t extra_size,\n\t\tsize_t *actual_extra, uint32_t timeout);\n\nlong kobject_send(struct kobject *kobj, void __user *data,\n\t\tsize_t data_size, void __user *extra,\n\t\tsize_t extra_size, uint32_t timeout);\n\nint kobject_reply(struct kobject *kobj, right_t right,\n\t\tunsigned long token, long err_code,\n\t\thandle_t fd, right_t fd_right);\n\nint kobject_munmap(struct kobject *kobj, right_t right);\n\nint kobject_mmap(struct kobject *kobj, right_t right,\n\t\tvoid **addr, unsigned long *msize);\n\nlong kobject_ctl(struct kobject *kobj, right_t right,\n\t\tint req, unsigned long data);\n\nint kobject_open(struct kobject *kobj, handle_t handle, right_t right);\n\nint create_new_pma(struct kobject **kobj, right_t *right,\n\t\tstruct pma_create_arg *args);\n\n#endif\n"
  },
  {
    "path": "kernel/include/uspace/poll.h",
    "content": "#ifndef __MINOS_POLL_H__\n#define __MINOS_POLL_H__\n\n#include <minos/types.h>\n#include <uspace/kobject.h>\n\n#define POLLIN 0x001\n#define POLLOUT 0x002\n#define POLLROPEN 0X004\n#define POLLRCLOSE 0x008\n#define POLLWOPEN 0x010\n#define POLLWCLOSE 0x020\n#define POLLKERNEL 0x040\n\nenum {\n\tEV_IN = 0,\n\tEV_OUT,\n\tEV_ROPEN,\n\tEV_RCLOSE,\n\tEV_WOPEN,\n\tEV_WCLOSE,\n\tEV_KERNEL,\n\tEV_MAX,\n};\n\n#define POLL_EVENT_MASK \\\n\t(POLLIN | POLLOUT | POLLROPEN | POLLRCLOSE | \\\n\t POLLWOPEN | POLLWCLOSE | POLLKERNEL)\n\n#define POLL_READ_RIGHT_EVENT \\\n\t(POLLIN | POLLWOPEN | POLLWCLOSE | POLLKERNEL)\n\n#define POLL_WRITE_RIGHT_EVENT \\\n\t(POLLOUT | POLLROPEN | POLLRCLOSE)\n\n/*\n * kernel events - which sended by kernel which\n * happend on the kobject.\n */\n#define POLL_KEV_NULL 0x0\n#define POLL_KEV_PAGE_FAULT 0x1\n#define POLL_KEV_PROCESS_EXIT 0x2\n\nstruct poll_hub {\n\tstruct list_head event_list;\n\tspinlock_t lock;\n\tstruct kobject kobj;\n\tstruct event event;\n};\n\nstruct pevent_item {\n\tstruct poll_hub *poller;\n\tunsigned long data;\n\tstruct pevent_item *next;\n};\n\nstruct poll_struct {\n\tstruct pevent_item *pevents[EV_MAX];\n};\n\nstruct poll_data {\n\tunion {\n\t\tvoid *ptr;\n\t\tunsigned long pdata;\n\t};\n\tint fd;\n\tint type;\n\tuint64_t data0;\n\tuint64_t data1;\n\tuint64_t data2;\n};\n\nstruct poll_event {\n\tuint32_t events;\n\tstruct poll_data data;\n};\n\nstruct poll_event_kernel {\n\tstruct poll_event event;\n\tstruct list_head list;\n\tint release;\n};\n\nstatic inline int event_is_polled(struct poll_struct *ps, int ev)\n{\n\treturn (ps && (ps->pevents[ev]));\n}\n\nint poll_event_send_static(struct pevent_item *pi, struct poll_event_kernel *evk);\n\nint poll_event_send(struct poll_struct *ps, int ev);\n\nint poll_event_send_with_data(struct poll_struct *ps, int event, int type,\n\t\tuint64_t data0, uint64_t data1, uint64_t data2);\n\nstruct poll_event *alloc_poll_event(void);\n\nvoid release_poll_struct(struct kobject *kobj);\n\n#endif\n"
  },
  {
    "path": "kernel/include/uspace/proc.h",
    "content": "#ifndef __MINOS_PROC_H__\n#define __MINOS_PROC_H__\n\n#include <minos/current.h>\n#include <uspace/vspace.h>\n#include <uspace/kobject.h>\n#include <uspace/handle.h>\n#include <uspace/iqueue.h>\n\n#define PROCESS_NAME_SIZE\t32\n\nstruct task;\n\n#define PROC_FLAGS_VMCTL\t(1 << 0)\n#define PROC_FLAGS_HWCTL\t(1 << 1)\n#define PROC_FLAGS_ROOT\t\t(1 << 31)\n#define PROC_FLAGS_MASK\t\t(PROC_FLAGS_VMCTL | PROC_FLAGS_HWCTL)\n\nstruct process {\n\tint pid;\n\tint flags;\n\tint task_cnt;\n\tint stopped;\n\n\tstruct vspace vspace;\n\n\t/*\n\t * handle_desc_table will store all the kobjects created\n\t * and kobjects connected by this process. and\n\t *\n\t * when close or open kobject, it will only clear or\n\t * set the right for related kobject in kobj_table.\n\t */\n\tstruct handle_desc *handle_desc_table;\n\tstruct task *root_task;\n\tstruct list_head task_list;\n\tspinlock_t lock;\n\n\tstruct kobject kobj;\n\tstruct iqueue iqueue;\n};\n\n#define current_proc\t\t(struct process *)current->vs->pdata\n#define task_to_proc(task)\t(struct process *)((task)->vs->pdata)\n\nstatic inline int proc_is_root(struct process *proc)\n{\n\treturn !!(proc->flags & PROC_FLAGS_ROOT);\n}\n\nstatic inline int proc_can_vmctl(struct process *proc)\n{\n\treturn !!(proc->flags & PROC_FLAGS_VMCTL);\n}\n\nstatic inline int proc_can_hwctl(struct process *proc)\n{\n\treturn !!(proc->flags & PROC_FLAGS_HWCTL);\n}\n\nstruct process *create_process(int pid, task_func_t func,\n\t\tvoid *usp, int prio, int aff, unsigned long opt);\n\nvoid process_die(void);\n\nvoid kill_process(struct process *proc, int handle);\n\nvoid clean_process_on_pcpu(struct pcpu *pcpu);\n\nint process_page_fault(struct process *proc, uint64_t virtaddr, uint64_t info);\n\nint wake_up_process(struct process *proc);\n\n#endif\n"
  },
  {
    "path": "kernel/include/uspace/procinfo.h",
    "content": "#ifndef __MINOS_PROC_INFO_H__\n#define __MINOS_PROC_INFO_H__\n\n#include <minos/types.h>\n#include <uapi/procinfo_uapi.h>\n\nstruct task;\n\nvoid init_task_stat(struct task *task);\nvoid release_task_stat(int tid);\nvoid update_task_stat(struct task *task);\nstruct task_stat *get_task_stat(int tid);\n\n#endif\n"
  },
  {
    "path": "kernel/include/uspace/socket.h",
    "content": "#ifndef __MINOS_SOCKET_H__\n#define __MINOS_SOCKET_H__\n\n#include <uspace/kobject.h>\n\nstruct socket {\n\tint flags;\n\tvoid *data_addr;\n\tint pages;\n\tstruct kobject kobj;\n};\n\n#endif\n"
  },
  {
    "path": "kernel/include/uspace/syscall.h",
    "content": "#ifndef __MINOS_SYSCALL_H__\n#define __MINOS_SYSCALL_H__\n\n#include <minos/types.h>\n#include <asm/syscall.h>\n\nextern void sys_sched_yield(void);\n\nextern int sys_kobject_connect(char __user *path, right_t right);\nextern int sys_kobject_close(int handle);\nextern int sys_kobject_open(handle_t handle);\n\nextern handle_t sys_kobject_create(int type, unsigned long data);\n\nextern ssize_t sys_kobject_recv(handle_t handle, void __user *data, size_t data_size,\n\t\tsize_t *actual_data, void __user *extra, size_t extra_size,\n\t\tsize_t *actual_extra, uint32_t timeout);\n\nextern ssize_t sys_kobject_send(handle_t handle, void __user *data, size_t data_size,\n\t\tvoid __user *extra, size_t extra_size, uint32_t timeout);\n\nextern int sys_kobject_reply(handle_t handle, long token,\n\t\tlong err_code, handle_t fd, right_t fd_right);\n\nextern long sys_futex(uint32_t __user *uaddr, int op, uint32_t val,\n\t\tstruct timespec __user *utime,\n\t\tuint32_t __user *uaddr2, uint32_t val3);\n\nextern int sys_unmap(handle_t proc_handle, handle_t pma_handle,\n\t\tunsigned long virt, size_t size);\n\nextern int sys_map(handle_t proc_handle, handle_t pma_handle,\n\t\tunsigned long virt, size_t size, right_t right);\n\nextern unsigned long sys_mtrans(unsigned long virt);\n\nextern handle_t sys_grant(handle_t proc, handle_t handle,\n\t\tright_t right, int release);\n\nextern int sys_kobject_munmap(handle_t handle);\n\nextern int sys_kobject_mmap(handle_t handle, void **addr, unsigned long *msize);\n\nextern long sys_kobject_ctl(handle_t handle, int req, unsigned long data);\n\nextern int sys_clock_gettime(int id, struct timespec __user *ts);\n\nextern int sys_clock_nanosleep(int id, int flags, long time, long ns,\n               struct timespec __user *rem);\n\nextern int sys_exit(int errno);\n\nextern int sys_exitgroup(int errno);\n\nextern int sys_clone(int flags, void *stack, int *ptid, void *tls, int *ctid);\n\n#endif\n"
  },
  {
    "path": "kernel/include/uspace/uaccess.h",
    "content": "#ifndef __MINOS_ACCESS_H__\n#define __MINOS_ACCESS_H__\n\n#include <minos/compiler.h>\n#include <asm/uaccess.h>\n\nstruct vspace;\n\nint copy_string_from_user(char *dst, char __user *src, int max);\nint __copy_from_user(void *dst, struct vspace *vsrc, void __user *src, size_t size);\nint __copy_to_user(struct vspace *vdst, void __user *dst, void *src, size_t size);\nint copy_from_user(void *dst, void __user *src, size_t size);\nint copy_to_user(void __user *dst, void *src, size_t size);\n\nint copy_user_to_user(struct vspace *vdst, void __user *dst,\n\t\tstruct vspace *vsrc, void __user *src, size_t size);\n\nint copy_string_from_user_safe(char *dst, char __user *src, size_t max);\n\n#endif\n"
  },
  {
    "path": "kernel/include/uspace/vspace.h",
    "content": "#ifndef __MINOS_VSPACE_H__\n#define __MINOS_VSPACE_H__\n\n#include <minos/mm.h>\n#include <minos/types.h>\n#include <minos/list.h>\n#include <uspace/kobject.h>\n\n#define HUGE_PAGE_SIZE\t\t0x200000\n#define HUGE_PAGE_SHIFT\t\t21\n#define IS_HUGE_ALIGN(x)\t(!((unsigned long)(x) & (HUGE_PAGE_SIZE - 1)))\n\n#define PROCESS_TOP_HALF_BASE\t(USER_PROCESS_ADDR_LIMIT >> 1)\n#define VMA_SHARED_BASE\t\tPROCESS_TOP_HALF_BASE\n\n#define pa2sva(phy)\t\t((phy) + VMA_SHARED_BASE)\n#define va2sva(va)\t\t(pa2sva(vtop(va)))\n#define va2pa(va)\t\tvtop(va)\n#define pa2va(pa)\t\tptov(pa)\n\n/*\n * 0    - (256G - 1) user space memory region\n * 256G - (512G - 1) shared memory mapping space.\n *\n * 0    - ( 64G - 1) ELF (text data bss and other)\n * 64G -> (64G + 256M) heap area\n * 65G  - (255G - 1) VMAP area\n * ((256G - 32K - 4K) -> (256G - 4K)) stack\n *\n * system process can handle it heap by itself, the heap\n * region for system process if 64G --- 64G + 256M\n * kernel will handle the page fault for this heap region.\n */\n#define SYS_PROC_HEAP_BASE\t(64UL * 1024 * 1024 * 1024)\n#define SYS_PROC_HEAP_SIZE\t(256UL * 1024 * 1024)\n#define SYS_PROC_HEAP_END\t(SYS_PROC_HEAP_BASE + SYS_PROC_HEAP_SIZE)\n\n#define SYS_PROC_VMAP_BASE\t(65UL * 1024 * 1024 * 1024)\n#define SYS_PROC_VMAP_END\t(255UL * 1024 * 1024 * 1024)\n\n#define MIN_ELF_LOAD_BASE\t0x1000\n#define ROOTSRV_USTACK_TOP\t(PROCESS_TOP_HALF_BASE - PAGE_SIZE * 8)\n#define ROOTSRV_USTACK_BOTTOM\t(ROOTSRV_USTACK_TOP - ROOTSRV_USTACK_PAGES * PAGE_SIZE)\n#define ROOTSRV_BOOTDATA_BASE\t(PROCESS_TOP_HALF_BASE - PAGE_SIZE * 2)\n\nint vspace_init(struct process *proc);\n\nvoid vspace_deinit(struct process *proc);\n\nint map_process_memory(struct process *proc,\n\t\t       unsigned long vaddr,\n\t\t       size_t size,\n\t\t       unsigned long phy,\n\t\t       unsigned long flags);\n\nint unmap_process_memory(struct process *proc,\n\t\tunsigned long vaddr, size_t size);\n\nunsigned long translate_va_to_pa(struct vspace *vs, unsigned long va);\n\nvoid *uva_to_kva(struct vspace *vs, unsigned long va,\n\t\tsize_t size, unsigned long right);\n\nint handle_page_fault(unsigned long virt, int write, unsigned long flags);\n\nvoid inc_vspace_usage(struct vspace *vs);\nvoid dec_vspace_usage(struct vspace *vs);\nvoid add_released_page_to_vspace(struct vspace *vs, unsigned long addr);\n\n#endif\n"
  },
  {
    "path": "kernel/include/virt/hypercall.h",
    "content": "#ifndef __MINOS_HYPERCALL_H__\n#define __MINOS_HYPERCALL_h__\n\n/* below defination is for HVC call */\n#define HVC_TYPE_VM0\t\t\t(0x8)\n#define HVC_TYPE_MISC\t\t\t(0x9)\n#define HVC_TYPE_VMBOX\t\t\t(0xa)\n#define HVC_TYPE_DEBUG_CONSOLE\t\t(0xb)\n\n#define HVC_CALL_BASE\t\t\t(0xc0000000)\n\n#define HVC_CALL_NUM(t, n)\t\t(HVC_CALL_BASE + (t << 24) + n)\n\n#define HVC_VM0_FN(n)\t\t\tHVC_CALL_NUM(HVC_TYPE_VM0, n)\n#define HVC_MISC_FN(n)\t\t\tHVC_CALL_NUM(HVC_TYPE_MISC, n)\n#define HVC_VMBOX_FN(n)\t\t\tHVC_CALL_NUM(HVC_TYPE_VMBOX, n)\n#define HVC_VMBOX_DEBUG_CONSOLE(n)\tHVC_CALL_NUM(HVC_TYPE_DEBUG_CONSOLE, n)\n\n/* hypercall for vm releated operation */\n#define\tHVC_VM_CREATE\t\t\tHVC_VM0_FN(0)\n#define HVC_VM_DESTORY\t\t\tHVC_VM0_FN(1)\n#define HVC_VM_RESTART\t\t\tHVC_VM0_FN(2)\n#define HVC_VM_POWER_UP\t\t\tHVC_VM0_FN(3)\n#define HVC_VM_POWER_DOWN\t\tHVC_VM0_FN(4)\n#define HVC_VM_MMAP\t\t\tHVC_VM0_FN(5)\n#define HVC_VM_UNMMAP\t\t\tHVC_VM0_FN(6)\n#define HVC_VM_SEND_VIRQ\t\tHVC_VM0_FN(7)\n#define HVC_VM_CREATE_VMCS\t\tHVC_VM0_FN(8)\n#define HVC_VM_CREATE_VMCS_IRQ\t\tHVC_VM0_FN(9)\n#define HVC_VM_REQUEST_VIRQ\t\tHVC_VM0_FN(10)\n#define HVC_VM_VIRTIO_MMIO_INIT\t\tHVC_VM0_FN(11)\n#define HVC_VM_VIRTIO_MMIO_DEINIT\tHVC_VM0_FN(12)\n#define HVC_VM_CREATE_RESOURCE\t\tHVC_VM0_FN(13)\n#define HVC_CHANGE_LOG_LEVEL\t\tHVC_VM0_FN(14)\n\n#define HVC_GET_VMID\t\t\tHVC_MISC_FN(0)\n#define HVC_SCHED_OUT\t\t\tHVC_MISC_FN(1)\n\n#define HVC_GET_VM_CAP\t\t\tHVC_MISC_FN(2)\n#define VM_CAP_HOST\t\t\t(1 << 0)\n#define VM_CAP_NATIVE\t\t\t(1 << 1)\n\n#define HVC_DC_GET_STAT\t\t\tHVC_VMBOX_DEBUG_CONSOLE(0)\n#define HVC_DC_GET_RING\t\t\tHVC_VMBOX_DEBUG_CONSOLE(1)\n#define HVC_DC_GET_IRQ\t\t\tHVC_VMBOX_DEBUG_CONSOLE(2)\n#define HVC_DC_WRITE\t\t\tHVC_VMBOX_DEBUG_CONSOLE(3)\n#define HVC_DC_OPEN\t\t\tHVC_VMBOX_DEBUG_CONSOLE(4)\n#define HVC_DC_CLOSE\t\t\tHVC_VMBOX_DEBUG_CONSOLE(5)\n\n#endif\n"
  },
  {
    "path": "kernel/include/virt/iommu.h",
    "content": "// SPDX-License-Identifier: GPL-2.0\n\n#ifndef _MINOS_IOMMU_H_\n#define _MINOS_IOMMU_H_\n\nstruct vm;\nstruct device_node;\n\nstruct iommu_ops {\n\tint (*init)(struct device_node *node);\n\tint (*vm_init)(struct vm *vm);\n\tint (*vm_destroy)(struct vm *vm);\n\tint (*iotlb_flush_all)(struct vm *vm);\n\tint (*assign_node)(struct vm *vm, struct device_node *node);\n\tint (*deassign_node)(struct vm *vm, struct device_node *node);\n};\n\nint iommu_vm_init(struct vm *vm);\n\nint iommu_vm_destroy(struct vm *vm);\n\nint iommu_iotlb_flush_all(struct vm *vm);\n\nint iommu_assign_node(struct vm *vm, struct device_node *node);\n\nint iommu_deassign_node(struct vm *vm, struct device_node *node);\n\n#endif\n"
  },
  {
    "path": "kernel/include/virt/os.h",
    "content": "#ifndef _MINOS_OS_H_\n#define _MINOS_OS_H_\n\nstruct vcpu;\nstruct vm;\n\n#define MINOS_OS_NAME_SIZE\t(32)\n\nenum {\n\tOS_TYPE_OTHERS = 0,\n\tOS_TYPE_LINUX,\n\tOS_TYPE_XNU,\n\tOS_TYPE_LUSHAN,\n\tOS_TYPE_MAX,\n};\n\nstruct os_ops {\n\tvoid (*vm_init)(struct vm *vm);\n\tvoid (*vcpu_init)(struct vcpu *vcpu);\n\tvoid (*vcpu_power_on)(struct vcpu *vcpu, unsigned long entry);\n\tvoid (*vm_setup)(struct vm *vm);\n\tint (*create_gvm_res)(struct vm *vm);\n\tint (*create_nvm_res)(struct vm *vm);\n};\n\nstruct os {\n\tchar name[MINOS_OS_NAME_SIZE];\n\tint type;\n\tstruct os_ops *ops;\n};\n\nint register_os(char *name, int type, struct os_ops *ops);\nstruct os *alloc_os(char *name, int type);\nstruct os *get_vm_os(char *type);\nvoid os_vm_init(struct vm *vm);\nvoid os_setup_vm(struct vm *vm);\nvoid os_vcpu_init(struct vcpu *vcpu);\nvoid os_vcpu_power_on(struct vcpu *vcpu, unsigned long entry);\nint os_create_native_vm_resource(struct vm *vm);\nint os_create_guest_vm_resource(struct vm *vm);\n\n#endif\n"
  },
  {
    "path": "kernel/include/virt/resource.h",
    "content": "#ifndef __MINOS_RESOURCE_H__\n#define __MINOS_RESOURCE_H__\n\n#include <minos/types.h>\n\nstruct vm;\n\nint parse_vm_info_of(struct device_node *node, struct vmtag *vmtag);\nint create_vm_resource_of(struct vm *vm, void *data);\nint create_native_vm_resource_common(struct vm *vm);\nint vm_get_device_irq_index(struct vm *vm, struct device_node *node,\n\t\tuint32_t *irq, unsigned long *flags, int index);\n\n#endif\n"
  },
  {
    "path": "kernel/include/virt/vdev.h",
    "content": "#ifndef __MINOS_VDEV_H__\n#define __MINOS_VDEV_H__\n\n#include <minos/types.h>\n#include <minos/list.h>\n#include <asm/arch.h>\n#include <virt/virq.h>\n#include <minos/device_id.h>\n\n#define VDEV_NAME_SIZE\t(15)\n\ntypedef void *(*vdev_init_t)(struct vm *vm, struct device_node *node);\n\nstruct vdev {\n\tchar name[VDEV_NAME_SIZE + 1];\n\tint host;\n\tstruct vm *vm;\n\tstruct vmm_area *gvm_area;\n\tstruct list_head list;\n\n\tint (*read)(struct vdev *, gp_regs *, int,\n\t\t\tunsigned long, unsigned long *);\n\tint (*write)(struct vdev *, gp_regs *, int,\n\t\t\tunsigned long, unsigned long *);\n\tvoid (*deinit)(struct vdev *vdev);\n\tvoid (*reset)(struct vdev *vdev);\n\tint (*suspend)(struct vdev *vdev);\n\tint (*resume)(struct vdev *vdev);\n};\n\nstruct vdev *create_host_vdev(struct vm *vm, const char *name);\n\nvoid vdev_release(struct vdev *vdev);\n\nvoid host_vdev_init(struct vm *vm, struct vdev *vdev, const char *name);\n\nint vdev_mmio_emulation(gp_regs *regs, int write,\n\t\tunsigned long address, unsigned long *value);\n\nint vdev_add_iomem_range(struct vdev *vdev,\n\t\tunsigned long base, size_t size);\n\nstruct vmm_area *vdev_alloc_iomem_range(struct vdev *vdev,\n\t\tsize_t size, int flags);\n\nstruct vmm_area *vdev_get_vmm_area(struct vdev *vdev, int idx);\n\nvoid vdev_add(struct vdev *vdev);\n\nstatic int inline vdev_notify_gvm(struct vdev *vdev, uint32_t irq)\n{\n\treturn send_virq_to_vm(vdev->vm, irq);\n}\n\nstatic int inline vdev_notify_hvm(struct vdev *vdev, uint32_t irq)\n{\n\treturn send_virq_to_vm(get_host_vm(), irq);\n}\n\n#endif\n"
  },
  {
    "path": "kernel/include/virt/virq.h",
    "content": "#ifndef __MINOS_VIRQ_H__\n#define __MINOS_VIRQ_H__\n\n#include <virt/vm.h>\n#include <minos/cpumask.h>\n#include <config/config.h>\n\nstruct irqtag;\n\n#define VIRQ_STATE_INACTIVE\t\t(0x0)\n#define VIRQ_STATE_PENDING\t\t(0x1)\n#define VIRQ_STATE_ACTIVE\t\t(0x2)\n#define VIRQ_STATE_ACTIVE_AND_PENDING\t(0x3)\n\n#define VCPU_MAX_ACTIVE_VIRQS\t\t(64)\n#define VIRQ_INVALID_ID\t\t\t(0xff)\n\n#define VIRQ_ACTION_REMOVE\t(0x0)\n#define VIRQ_ACTION_ADD\t\t(0x1)\n#define VIRQ_ACTION_CLEAR\t(0x2)\n\n#define VIRQ_AFFINITY_VM_ANY\t(0xff)\n#define VIRQ_AFFINITY_VCPU_ANY\t(0xff)\n\n#define VM_SGI_VIRQ_NR\t\t(CONFIG_NR_SGI_IRQS)\n#define VM_PPI_VIRQ_NR\t\t(CONFIG_NR_PPI_IRQS)\n#define VM_LOCAL_VIRQ_NR\t(VM_SGI_VIRQ_NR + VM_PPI_VIRQ_NR)\n\n#ifndef CONFIG_HVM_SPI_VIRQ_NR\n#define HVM_SPI_VIRQ_NR\t\t(384)\n#else\n#define HVM_SPI_VIRQ_NR\t\tCONFIG_HVM_SPI_VIRQ_NR\n#endif\n\n#define HVM_SPI_VIRQ_BASE\t(VM_LOCAL_VIRQ_NR)\n\n#ifndef CONFIG_GVM_SPI_VIRQ_NR\n#define GVM_SPI_VIRQ_NR\t\t(64)\n#else\n#define GVM_SPI_VIRQ_NR\t\tCONFIG_GVM_SPI_VIRQ_NR\n#endif\n\n#define GVM_SPI_VIRQ_BASE\t(VM_LOCAL_VIRQ_NR)\n\n#define VIRQ_SPI_OFFSET(virq)\t((virq) - VM_LOCAL_VIRQ_NR)\n#define VIRQ_SPI_NR(count)\t((count) > VM_LOCAL_VIRQ_NR ? VIRQ_SPI_OFFSET((count)) : 0)\n\n#define VM_VIRQ_NR(nr)\t\t((nr) + VM_LOCAL_VIRQ_NR)\n\n#define MAX_HVM_VIRQ\t\t(HVM_SPI_VIRQ_NR + VM_LOCAL_VIRQ_NR)\n#define MAX_GVM_VIRQ\t\t(GVM_SPI_VIRQ_NR + VM_LOCAL_VIRQ_NR)\n\n#define VIRQS_NEED_EXPORT_BIT\t(0)\n#define VIRQS_ENABLED_BIT \t(1)\n#define VIRQS_SUSPEND_BIT\t(2)\n#define VIRQS_HW_BIT\t\t(3)\n#define VIRQS_CAN_WAKEUP_BIT\t(4)\n#define VIRQS_REQUESTED_BIT\t(6)\n#define VIRQS_FIQ_BIT\t\t(7)\n\n#define VIRQS_NEED_EXPORT\t(1 << VIRQS_NEED_EXPORT_BIT)\n#define VIRQS_ENABLED\t\t(1 << VIRQS_ENABLED_BIT)\n#define VIRQS_SUSPEND\t\t(1 << VIRQS_SUSPEND_BIT)\n#define VIRQS_HW\t\t(1 << VIRQS_HW_BIT)\n#define VIRQS_CAN_WAKEUP\t(1 << VIRQS_CAN_WAKEUP_BIT)\n#define VIRQS_REQUESTED\t\t(1 << VIRQS_REQUESTED_BIT)\n#define VIRQS_FIQ\t\t(1 << VIRQS_FIQ_BIT)\n\n#define VIRQF_CAN_WAKEUP\tVIRQS_CAN_WAKEUP\n#define VIRQF_ENABLE\t\tVIRQS_ENABLED\n#define VIRQF_FIQ\t\tVIRQS_FIQ\n#define VIRQF_NEED_EXPORT\tVIRQS_NEED_EXPORT\n\n#define FIQ_HAS_INJECT\t\t(1 << 31)\n\nstruct virq_desc {\n\tint32_t flags;\n\tuint16_t vno;\n\tuint16_t hno;\n\tuint8_t id;\n\tuint8_t state;\n\tuint8_t pr;\n\tuint8_t src;\n\tuint8_t type;\n\tuint8_t vcpu_id;\n\tuint8_t vmid;\n\tuint8_t padding;\n} __packed;\n\n#define VGIC_MAX_LRS 128\n\nstruct virq_struct {\n\tint nr_lrs;\n\tint last_fail_virq;\n\tatomic_t pending_virq;\n\tuint32_t active_virq;\n\tstruct virq_desc local_desc[VM_LOCAL_VIRQ_NR];\n\tunsigned long *pending_bitmap;\n\tunsigned long *active_bitmap;\n\tunsigned long lrs_bitmap[BITS_TO_LONGS(VGIC_MAX_LRS)];\n};\n\nstatic inline int vm_irq_count(struct vm *vm)\n{\n\treturn vm->vspi_nr + VM_LOCAL_VIRQ_NR;\n}\n\nstatic void inline virq_set_enable(struct virq_desc *d)\n{\n\td->flags |= VIRQS_ENABLED;\n}\n\nstatic void inline virq_clear_enable(struct virq_desc *d)\n{\n\td->flags &= ~VIRQS_ENABLED;\n}\n\nstatic int inline virq_is_enabled(struct virq_desc *d)\n{\n\treturn !!(d->flags & VIRQS_ENABLED);\n}\n\nstatic void inline virq_set_wakeup(struct virq_desc *d)\n{\n\td->flags |= VIRQS_CAN_WAKEUP;\n}\n\nstatic void inline virq_clear_wakeup(struct virq_desc *d)\n{\n\td->flags &= ~VIRQS_CAN_WAKEUP;\n}\n\nstatic int inline virq_can_wakeup(struct virq_desc *d)\n{\n\treturn !!(d->flags & VIRQS_CAN_WAKEUP);\n}\n\nstatic void inline virq_set_suspend(struct virq_desc *d)\n{\n\td->flags |= VIRQS_SUSPEND;\n}\n\nstatic void inline virq_clear_suspend(struct virq_desc *d)\n{\n\td->flags &= ~VIRQS_SUSPEND;\n}\n\nstatic int inline virq_is_suspend(struct virq_desc *d)\n{\n\treturn !!(d->flags & VIRQS_SUSPEND);\n}\n\nstatic void inline virq_set_hw(struct virq_desc *d)\n{\n\td->flags |= VIRQS_HW;\n}\n\nstatic void inline virq_clear_hw(struct virq_desc *d)\n{\n\td->flags &= ~VIRQS_HW;\n}\n\nstatic int inline virq_is_hw(struct virq_desc *d)\n{\n\treturn !!(d->flags & VIRQS_HW);\n}\n\nstatic int inline virq_is_requested(struct virq_desc *d)\n{\n\treturn !!(d->flags & VIRQS_REQUESTED);\n}\n\nstatic void inline __virq_set_fiq(struct virq_desc *d)\n{\n\td->flags |= VIRQS_FIQ;\n}\n\nstatic int inline virq_is_fiq(struct virq_desc *d)\n{\n\treturn !!(d->flags & VIRQS_FIQ);\n}\n\nstatic void inline virq_clear_fiq(struct virq_desc *d)\n{\n\td->flags &= ~VIRQS_FIQ;\n}\n\nint virq_enable(struct vcpu *vcpu, uint32_t virq);\nint virq_disable(struct vcpu *vcpu, uint32_t virq);\nvoid vcpu_virq_struct_init(struct vcpu *vcpu);\nvoid vcpu_virq_struct_reset(struct vcpu *vcpu);\n\nvoid vm_virq_reset(struct vm *vm);\nvoid send_vsgi(struct vcpu *sender,\n\t\tuint32_t sgi, cpumask_t *cpumask);\nvoid clear_pending_virq(struct vcpu *vcpu, uint32_t irq);\n\nint virq_set_priority(struct vcpu *vcpu, uint32_t virq, int pr);\nint virq_set_type(struct vcpu *vcpu, uint32_t virq, int value);\nuint32_t virq_get_type(struct vcpu *vcpu, uint32_t virq);\nuint32_t virq_get_affinity(struct vcpu *vcpu, uint32_t virq);\nuint32_t virq_get_pr(struct vcpu *vcpu, uint32_t virq);\nuint32_t virq_get_state(struct vcpu *vcpu, uint32_t virq);\nint virq_can_request(struct vcpu *vcpu, uint32_t virq);\nint virq_need_export(struct vcpu *vcpu, uint32_t virq);\nuint32_t get_pending_virq(struct vcpu *vcpu);\nint virq_set_fiq(struct vcpu *vcpu, uint32_t virq);\n\nint send_virq_to_vcpu(struct vcpu *vcpu, uint32_t virq);\nint send_virq_to_vm(struct vm *vm, uint32_t virq);\n\nint vcpu_has_irq(struct vcpu *vcpu);\n\nint alloc_vm_virq(struct vm *vm);\nvoid release_vm_virq(struct vm *vm, int virq);\n\nint request_virq_affinity(struct vm *vm, uint32_t virq,\n\t\tuint32_t hwirq, int affinity, unsigned long flags);\nint request_hw_virq(struct vm *vm, uint32_t virq, uint32_t hwirq,\n\t\t\tunsigned long flags);\nint request_virq_pervcpu(struct vm *vm, uint32_t virq,\n\t\t\tunsigned long flags);\nint request_virq(struct vm *vm, uint32_t virq, unsigned long flags);\n\nstruct virq_desc *get_virq_desc(struct vcpu *vcpu, uint32_t virq);\n\nstatic inline int alloc_hvm_virq(void)\n{\n\treturn alloc_vm_virq(get_host_vm());\n}\n\nstatic inline int alloc_gvm_virq(struct vm *vm)\n{\n\treturn alloc_vm_virq(vm);\n}\n\nstatic void inline release_hvm_virq(int virq)\n{\n\treturn release_vm_virq(get_host_vm(), virq);\n}\n\nstatic void inline release_gvm_virq(struct vm *vm, int virq)\n{\n\treturn release_vm_virq(vm, virq);\n}\n\nstruct virq_chip *alloc_virq_chip(void);\nint virqchip_get_virq_state(struct vcpu *vcpu, struct virq_desc *virq);\nvoid virqchip_send_virq(struct vcpu *vcpu, struct virq_desc *virq);\nvoid virqchip_update_virq(struct vcpu *vcpu,\n\t\tstruct virq_desc *virq, int action);\n\n#endif\n"
  },
  {
    "path": "kernel/include/virt/virq_chip.h",
    "content": "#ifndef __VIRQ_CHIP_H__\n#define __VIRQ_CHIP_H__\n\n#include <minos/types.h>\n#include <minos/device_id.h>\n\nstruct vcpu;\n\n#define VIRQCHIP_F_HW_VIRT\t(1 << 0)\n\nstruct virq_chip {\n\tint (*exit_from_guest)(struct vcpu *vcpu, void *data);\n\tint (*enter_to_guest)(struct vcpu *vcpu, void *data);\n\tint (*generate_virq)(uint32_t *array, int virq);\n\tint (*xlate)(struct device_node *node, uint32_t *intspec,\n\t\t\tunsigned int intsize, uint32_t *hwirq,\n\t\t\tunsigned long *type);\n\tint (*send_virq)(struct vcpu *vcpu, struct virq_desc *virq);\n\tint (*get_virq_state)(struct vcpu *vcpu, struct virq_desc *virq);\n\tint (*update_virq)(struct vcpu *vcpu, struct virq_desc *virq, int action);\n\tint (*vcpu_init)(struct vcpu *vcpu, void *pdata, unsigned long flags);\n\n\tvoid *inc_pdata;\n\tunsigned long flags;\n};\n\nstruct virq_chip *alloc_virq_chip(void);\nint virqchip_get_virq_state(struct vcpu *vcpu, struct virq_desc *virq);\nvoid virqchip_send_virq(struct vcpu *vcpu, struct virq_desc *virq);\nvoid virqchip_update_virq(struct vcpu *vcpu,\n\t\tstruct virq_desc *virq, int action);\n\n#endif\n"
  },
  {
    "path": "kernel/include/virt/virt.h",
    "content": "#ifndef __MINOS_VIRT_H__\n#define __MINOS_VIRT_H__\n\n#include <asm/virt.h>\n\nstruct mm_struct;\n\nint virt_init(void);\nvoid start_all_vm(void);\n\nvoid flush_all_tlb_mm(struct mm_struct *mm);\n\n#endif\n"
  },
  {
    "path": "kernel/include/virt/virtio.h",
    "content": "#ifndef __MINOS_VIRTIO_H__\n#define __MINOS_VIRTIO_H__\n\n#include <virt/vdev.h>\n\nstruct vm;\n\nstruct virtio_device {\n\tstruct vdev vdev;\n\tvoid *iomem;\n};\n\nint virtio_mmio_init(struct vm *vm, unsigned long gbase,\n\t\tsize_t size, unsigned long *hbase);\n\n#endif\n"
  },
  {
    "path": "kernel/include/virt/vm.h",
    "content": "/*\n * created by Le MIn 2017/12/09\n */\n\n#ifndef _MINOS_VM_H_\n#define _MINOS_VM_H_\n\n#include <minos/types.h>\n#include <minos/list.h>\n#include <config/config.h>\n#include <virt/vmm.h>\n#include <minos/errno.h>\n#include <generic/hypervisor.h>\n#include <minos/task.h>\n#include <minos/sched.h>\n#include <minos/event.h>\n\n#define VM_MAX_VCPU CONFIG_NR_CPUS\n\n#define VM_STATE_OFFLINE (0)\n#define VM_STATE_FREEZEING (1)\n#define VM_STATE_ONLINE (2)\n#define VM_STATE_SUSPEND (3)\n\n#define VCPU_MAX_LOCAL_IRQS\t\t(32)\n#define CONFIG_VCPU_MAX_ACTIVE_IRQS\t(16)\n\n#define VCPU_NAME_SIZE\t\t(64)\n\n#define VCPU_KICK_REASON_NONE 0x0\n#define VCPU_KICK_REASON_HIRQ 0x1\n#define VCPU_KICK_REASON_VIRQ 0x2\n\nstruct os;\nstruct vm;\nstruct virq_struct;\nstruct virq_chip;\nstruct device_node;\n\nextern struct list_head vm_list;\nextern struct list_head mem_list;\n\n#define VCPU_STATE_RUNNING TASK_STATE_RUNNING\n#define VCPU_STATE_IDLE TASK_STATE_WAIT_EVENT\n#define VCPU_STATE_STOP TASK_STATE_STOP\n#define VCPU_STATE_SUSPEND TASK_STATE_SUSPEND\n\nenum {\n\tIN_GUEST_MODE,\n\tOUTSIDE_GUEST_MODE,\n\tIN_ROOT_MODE,\n\tOUTSIDE_ROOT_MODE,\n};\n\nstruct vcpu {\n\tuint32_t vcpu_id;\n\tstruct vm *vm;\n\tstruct task *task;\n\tstruct vcpu *next;\n\n\tvolatile int mode;\n\n\t/*\n\t * member to record the irq list which the\n\t * vcpu is handling now\n\t */\n\tstruct virq_struct *virq_struct;\n\n\tstruct event vcpu_event;\n\n\tstruct vmcs *vmcs;\n\tint vmcs_irq;\n\n\t/*\n\t * context for this vcpu.\n\t */\n\tvoid **context;\n} __cache_line_align;\n\nstruct vm {\n\tint vmid;\n\tuint32_t vcpu_nr;\n\tint state;\n\tunsigned long flags;\n\tuint32_t vcpu_affinity[VM_MAX_VCPU];\n\tvoid *entry_point;\n\tvoid *setup_data;\n\tvoid *load_address;\n\tint native;\n\n\tstruct ramdisk_file *kernel_file;\n\tstruct ramdisk_file *dtb_file;\n\tstruct ramdisk_file *initrd_file;\n\n\tchar name[VM_NAME_SIZE];\n\tstruct vcpu **vcpus;\n\tstruct list_head vcpu_list;\n\tstruct mm_struct mm;\n\tstruct os *os;\n\tstruct list_head vm_list;\n\tstruct device_node *dev_node;\t/* the device node in dts */\n\n\tunsigned long time_offset;\n\n\tstruct list_head vdev_list;\n\n\tuint32_t vspi_nr;\n\tstruct virq_desc *vspi_desc;\n\tunsigned long *vspi_map;\n\tstruct virq_chip *virq_chip;\n\tuint32_t vtimer_virq;\n\n\tvoid *vmcs;\n\tvoid *hvm_vmcs;\n\tvoid *resource;\n\n\tvoid *os_data;\n\n\tvoid *arch_data;\n\n\tstruct vm_iommu iommu;\n} __align(sizeof(unsigned long));\n\n#define vm_name(vm)\tdevnode_name(vm->dev_node)\n\nextern struct vm *vms[CONFIG_MAX_VM];\nextern int total_vms;\n\n#define for_each_vm(vm)\t\\\n\tlist_for_each_entry(vm, &vm_list, vm_list)\n\n#define vm_for_each_vcpu(vm, vcpu)\t\\\n\tfor (vcpu = vm->vcpus[0]; vcpu != NULL; vcpu = vcpu->next)\n\n#define current_vcpu (struct vcpu *)current->pdata\n\nstatic int inline get_vcpu_id(struct vcpu *vcpu)\n{\n\treturn vcpu->vcpu_id;\n}\n\nstatic int inline get_vmid(struct vcpu *vcpu)\n{\n\treturn (vcpu->vm->vmid);\n}\n\nstatic int inline vcpu_affinity(struct vcpu *vcpu)\n{\n\treturn vcpu->task->affinity;\n}\n\nstatic inline struct vm *vcpu_to_vm(struct vcpu *vcpu)\n{\n\treturn vcpu->vm;\n}\n\nstatic inline struct vcpu *task_to_vcpu(struct task *task)\n{\n\treturn (struct vcpu *)task->pdata;\n}\n\nstatic inline struct vcpu *get_current_vcpu(void)\n{\n\treturn task_to_vcpu(get_current_task());\n}\n\nstatic inline struct vm *task_to_vm(struct task *task)\n{\n\tstruct vcpu *vcpu = (struct vcpu *)task->pdata;\n\n\treturn vcpu->vm;\n}\n\nstatic inline struct vm* get_current_vm(void)\n{\n\treturn task_to_vm(get_current_task());\n}\n\nstruct vcpu *get_vcpu_in_vm(struct vm *vm, uint32_t vcpu_id);\nstruct vcpu *get_vcpu_by_id(uint32_t vmid, uint32_t vcpu_id);\n\nstruct vcpu *create_idle_vcpu(void);\nint vm_vcpus_init(struct vm *vm);\n\nint vcpu_idle(struct vcpu *vcpu);\nint vcpu_suspend(struct vcpu *vcpu, gp_regs *c,\n\t\tuint32_t state, unsigned long entry);\nint vcpu_off(struct vcpu *vcpu);\nint vcpu_power_on(struct vcpu *caller, unsigned long affinity,\n\t\tunsigned long entry, unsigned long unsed);\nint vcpu_power_off(struct vcpu *vcpu, int timeout);\nint kick_vcpu(struct vcpu *vcpu, int preempt);\n\nstruct vm *create_vm(struct vmtag *vme, struct device_node *node);\nint create_guest_vm(struct vmtag *tag);\nvoid destroy_vm(struct vm *vm);\n\nstruct vm *get_host_vm(void);\n\nstatic inline struct vm *get_vm_by_id(uint32_t vmid)\n{\n\tif (unlikely(vmid >= CONFIG_MAX_VM) || unlikely(vmid == 0))\n\t\treturn NULL;\n\treturn vms[vmid];\n}\n\nstatic inline int vm_is_host_vm(struct vm *vm)\n{\n\treturn !!(vm->flags & VM_FLAGS_HOST);\n}\n\nstatic inline int vm_is_32bit(struct vm *vm)\n{\n\treturn vm->flags & VM_FLAGS_32BIT;\n}\n\nstatic inline int vm_is_native(struct vm *vm)\n{\n\treturn !!(vm->flags & VM_FLAGS_NATIVE);\n}\n\nstatic inline int vm_id(struct vm *vm)\n{\n\treturn vm->vmid;\n}\n\nint create_vm_mmap(int vmid,  unsigned long offset,\n\t\tunsigned long size, unsigned long *addr);\nint vm_create_host_vdev(struct vm *vm);\nint request_vm_virqs(struct vm *vm, int base, int nr);\n\nvoid arch_init_vcpu(struct vcpu *vcpu, void *entry, void *arg);\n\nstatic inline int check_vcpu_state(struct vcpu *vcpu, int state)\n{\n\treturn (vcpu->task->state == state);\n}\n\nstatic inline int check_vm_state(struct vm *vm, int state)\n{\n\treturn (vm->state == state);\n}\n\nint start_native_vm(struct vm *vm);\n\nint start_guest_vm(struct vm *vm);\n\nvoid vcpu_dump(struct vcpu *vcpu, gp_regs *regs);\n\nvoid vcpu_fault(struct vcpu *vcpu, gp_regs *regs);\n\n#endif\n"
  },
  {
    "path": "kernel/include/virt/vm_mmap.h",
    "content": "#ifndef __MINOS_VM_MMAP_H__\n#define __MINOS_VM_MMAP_H__\n\n#include <config/config.h>\n\n/*\n * guest vm memory map\n *\n * |-------------------------| -- 0x00000000\n * | 2G IO MEM\t             |\n * |-------------------------| -- 0x80000000\n * |\t\t             |\n * | 126G DRAM/NORMAL MEM    |\n * |-------------------------| -- 0x2000000000\n * | 2G GUEST VM IO MMAP     |\n * |-------------------------| -- 0x2080000000\n * | GUEST VM MMAP           |\n * |-------------------------| -- 0x10000000000\n *\n */\n\n#define VMM_VIRT_MAX (1UL << 40)\n\n#define GVM_PHYSIC_MEM_RANGE\t\t(1UL << CONFIG_PLATFORM_ADDRESS_RANGE)\n#define GVM_PHYSIC_MEM_START\t\t(0x0000000000000000UL)\n\n#define GVM_IO_MEM_START\t\t(0x00000000UL)\n#define GVM_IO_MEM_SIZE\t\t\t(0x80000000UL)\n\n#define GVM_NORMAL_MEM_START\t\t(GVM_IO_MEM_START + GVM_IO_MEM_SIZE)\n#define GVM_NORMAL_MEM_SIZE\t\t(126 * 1024 * 1024 * 1024UL)\n#define GVM_NORMAL_MEM_END\t\t(GVM_NORMAL_MEM_START + GVM_NORMAL_MEM_SIZE)\n\n#define HVM_IO_MMAP_START\t\t(GVM_NORMAL_MEM_END)\n#define HVM_IO_MMAP_SIZE\t\t(2 * 1024 * 1024 * 1024UL)\n\n#define HVM_NORMAL_MMAP_START\t\t(HVM_IO_MMAP_START + HVM_IO_MMAP_SIZE)\n#define HVM_NORMAL_MMAP_SIZE\t\t(GVM_PHYSIC_MEM_RANGE - HVM_NORMAL_MMAP_START)\n\n#define GVM_IOMEM_BASE(addr)\t\t(addr - CONFIG_PLATFORM_IO_BASE + GVM_IO_MEM_START)\n#define GVM_MEM_BASE(addr)\t\t(addr - CONFIG_PLATFORM_DRAM_BASE + GVM_NORMAL_MEM_START)\n\n#endif\n"
  },
  {
    "path": "kernel/include/virt/vm_pm.h",
    "content": "#ifndef __MINOS_VM_PM_H__\n#define __MINOS_VM_PM_H__\n\n#include <minos/types.h>\n\n#define VM_PM_ACTION_BY_SELF (1 << 0)\n#define VM_PM_ACTION_BY_MVM (1 << 1)\n#define VM_PM_ACTION_BY_HOST (1 << 2)\n#define VM_PM_FLAGS_DESTROY (1 << 8)\n\nint vm_reset(int vmid, void *args, int byself);\nint reboot_native_vm(struct vm *vm);\n\nint vm_power_off(int vmid, void *arg, int byself);\nint shutdown_native_vm(struct vm *vm);\n\nint vm_suspend(int vmid);\n\nstatic inline bool pm_action_by_self(int flags)\n{\n\treturn !!(flags & VM_PM_ACTION_BY_SELF);\n}\n\nstatic inline bool pm_action_by_mvm(int flags)\n{\n\treturn !!(flags & VM_PM_ACTION_BY_MVM);\n}\n\nstatic inline bool pm_action_by_host(int flags)\n{\n\treturn !!(flags & VM_PM_ACTION_BY_HOST);\n}\n\nstatic inline char *pm_action_caller(int flags)\n{\n\tif (pm_action_by_self(flags))\n\t\treturn \"itself\";\n\telse if (pm_action_by_mvm(flags))\n\t\treturn \"mvm\";\n\telse\n\t\treturn \"host\";\n}\n\nint send_vm_shutdown_request(struct vm *vm);\nint send_vm_reboot_request(struct vm *vm);\n\nint power_up_guest_vm(int vmid);\n\nvoid destroy_guest_vm(struct vm *vm);\n\n#endif\n"
  },
  {
    "path": "kernel/include/virt/vmbox.h",
    "content": "#ifndef __MINOS_VMBOX_H__\n#define __MINOS_VMBOX_H__\n\n#include <minos/device_id.h>\n#include <virt/vdev.h>\n\n#define VMBOX_VRING_ALGIN_SIZE\t8\n\n#define VMBOX_DEV_STAT_ONLINE\t0x1\n\n#define VMBOX_IPC_ALL_ENTRY_SIZE\t0x100\n\nstruct vmbox_device {\n\tint devid;\n\tint is_backend;\n\tint state;\n\tstruct vm *vm;\n\tstruct vmbox *vmbox;\n\n\tuint32_t vring_virq;\n\tuint32_t ipc_virq;\n\tuint32_t ipc_type;\n\tspinlock_t lock;\n\n\tunsigned long iomem;\n\tsize_t iomem_size;\n\tstruct vmbox_controller *vc;\n\tstruct vmbox_device *bro;\n};\n\n/*\n * owner : owner[0] is the server vm and the\n *         owner[1] is the client vm\n * devid : device id and vendor id of this device\n * vmbox_reg_base : the iobase of this controller\n */\nstruct vmbox {\n\tint id;\n\tchar name[32];\n\tuint32_t owner[2];\n\tuint32_t devid[2];\n\tvoid *shmem;\n\tsize_t shmem_size;\n\tuint32_t vqs;\n\tuint32_t vring_num;\n\tuint32_t vring_size;\n\tunsigned long flags;\n\tstruct vmbox_device *devices[2];\n};\n\n#define VMBOX_F_PLATFORM_DEV\t(1 << 0)\n\nstruct vmbox_hook_ops {\n\tint (*vmbox_init)(struct vmbox *vmbox);\n\tint (*vmbox_be_init)(struct vm *vm, struct vmbox *vmbox,\n\t\t\tstruct vmbox_device *vdev);\n\tint (*vmbox_fe_init)(struct vm *vm, struct vmbox *vmbox,\n\t\t\tstruct vmbox_device *vdev);\n};\n\nstruct vmbox_controller {\n\tvoid *va;\n\tstruct vm *vm;\n\tint dev_cnt;\n\tint status;\n\n\tuint32_t virq;\n\tuint32_t irq_state;\n\tuint32_t dev_state;\n\n\tstruct list_head list;\n\tstruct vdev vdev;\n\tstruct vmbox_device *devices[32];\n};\n\n#define vdev_to_vmbox_con(dev) \\\n\tcontainer_of(dev, struct vmbox_controller, vdev)\n\n/*\n * below are the defination of the vmbox controller\n * and device register map, each controller will have\n * a 4K IO memory space, 0x0-0xff is for controller\n * itself, and 0x100 - 0xfff is for the vmbox devices\n */\n#define VMBOX_DEVICE_MAGIC\t\t0xabcdef00\n\n#define VMBOX_CON_DEV_STAT\t\t0x00\t/* RO state of each device */\n#define VMBOX_CON_ONLINE\t\t0x04\t/* WO to inform the controller is online */\n#define VMBOX_CON_INT_STATUS\t\t0x08\t/* RO virq will send by hypervisor */\n\n#define VMBOX_CON_INT_TYPE_DEV_ONLINE\t(1 << 0)\n\n#define VMBOX_CON_DEV_BASE \t\t0x100\n#define VMBOX_CON_DEV_SIZE \t\t0x40\n\n#define VMBOX_DEV_ID\t\t\t0x00\t/* RO */\n#define VMBOX_DEV_VQS\t\t\t0x04\t/* RO */\n#define VMBOX_DEV_VRING_NUM \t\t0X08\t/* RO */\n#define VMBOX_DEV_VRING_SIZE \t\t0x0c\t/* RO */\n#define VMBOX_DEV_VRING_BASE_HI\t\t0x10\t/* RO */\n#define VMBOX_DEV_VRING_BASE_LOW\t0x14\t/* RO */\n#define VMBOX_DEV_MEM_SIZE\t\t0x18\n#define VMBOX_DEV_DEVICE_ID\t\t0x1c\t/* RO */\n#define VMBOX_DEV_VENDOR_ID\t\t0x20\t/* RO */\n#define VMBOX_DEV_VRING_IRQ\t\t0x24\t/* RO */\n#define VMBOX_DEV_IPC_IRQ\t\t0x28\t/* RO */\n#define VMBOX_DEV_VRING_EVENT\t\t0x2c\t/* WO trigger a vring event */\n#define VMBOX_DEV_IPC_EVENT\t\t0x30\t/* WO trigger a config event */\n#define VMBOX_DEV_VDEV_ONLINE\t\t0x34\t/* only for client device */\n#define VMBOX_DEV_IPC_TYPE\t\t0x38\t/* read and clear */\n\n#define VMBOX_DEV_IPC_COUNT\t\t32\n\nint vmbox_init(struct vm *vm);\nint register_vmbox_hook(char *name, struct vmbox_hook_ops *ops);\nint of_create_vmbox(struct device_node *node);\nint vmbox_register_platdev(struct vmbox_device *vdev,\n\t\tvoid *dtb, char *type);\n\nint create_vmbox_controller(struct vm *vm);\n\n#endif\n"
  },
  {
    "path": "kernel/include/virt/vmcs.h",
    "content": "#ifndef __VMCS_H__\n#define __VMCS_H__\n\n#include <minos/types.h>\n\nstruct vmcs {\n\tvolatile uint32_t vcpu_id;\n\tvolatile uint32_t trap_type;\n\tvolatile uint32_t trap_reason;\n\tvolatile int32_t  trap_ret;\n\tvolatile unsigned long trap_data;\n\tvolatile unsigned long trap_result;\n\tvolatile uint64_t host_index;\n\tvolatile uint64_t guest_index;\n\tvolatile unsigned long data[0];\n} __align(1024);\n\n#define VMCS_DATA_SIZE\t(1024 - 48)\n#define VMCS_SIZE(nr) \tPAGE_BALIGN(nr * sizeof(struct vmcs))\n\nenum vm_trap_type {\n\tVMTRAP_TYPE_MMIO = 0,\n\tVMTRAP_TYPE_COMMON,\n\tVMTRAP_TYPE_UNKNOWN,\n};\n\nenum vm_trap_reason {\n\tVMTRAP_REASON_READ = 0,\n\tVMTRAP_REASON_WRITE,\n\tVMTRAP_REASON_CONFIG,\n\tVMTRAP_REASON_REBOOT,\n\tVMTRAP_REASON_SHUTDOWN,\n\tVMTRAP_REASON_VM_SUSPEND,\n\tVMTRAP_REASON_VM_RESUMED,\n\tVMTRAP_REASON_WDT_TIMEOUT,\n\tVMTRAP_REASON_GET_TIME,\n\tVMTRAP_REASON_UNKNOWN,\n};\n\nint vm_create_vmcs_irq(struct vm *vm, int vcpu_id);\nunsigned long vm_create_vmcs(struct vm *vm);\nint setup_vmcs_data(void *data, size_t size);\nint __vcpu_trap(uint32_t type, uint32_t reason, unsigned long data,\n\t\tunsigned long *ret, int nonblock);\n\nstatic inline int trap_vcpu(uint32_t type, uint32_t reason,\n\t\tunsigned long data, unsigned long *ret)\n{\n\treturn __vcpu_trap(type, reason, data, ret, 0);\n}\n\nstatic inline int trap_vcpu_nonblock(uint32_t type, uint32_t reason,\n\t\tunsigned long data, unsigned long *ret)\n{\n\treturn __vcpu_trap(type, reason, data, ret, 1);\n}\n\nstatic inline int\ntrap_mmio_read(unsigned long addr, unsigned long *value)\n{\n\treturn __vcpu_trap(VMTRAP_TYPE_MMIO,\n\t\t\tVMTRAP_REASON_READ, addr, value, 0);\n}\n\nstatic inline int\ntrap_mmio_read_nonblock(unsigned long addr, unsigned long *value)\n{\n\treturn __vcpu_trap(VMTRAP_TYPE_MMIO,\n\t\t\tVMTRAP_REASON_READ, addr, value, 1);\n}\n\nstatic inline int\ntrap_mmio_write(unsigned long addr, unsigned long *value)\n{\n\treturn __vcpu_trap(VMTRAP_TYPE_MMIO,\n\t\t\tVMTRAP_REASON_WRITE, addr, value, 0);\n}\n\nstatic inline int\ntrap_mmio_write_nonblock(unsigned long addr, unsigned long *value)\n{\n\treturn __vcpu_trap(VMTRAP_TYPE_MMIO,\n\t\t\tVMTRAP_REASON_WRITE, addr, value, 1);\n}\n\n#endif\n"
  },
  {
    "path": "kernel/include/virt/vmm.h",
    "content": "#ifndef __MINOS_VIRT_VMM_H__\n#define __MINOS_VIRT_VMM_H__\n\n#include <minos/types.h>\n#include <minos/mm.h>\n#include <virt/vm_mmap.h>\n#include <virt/iommu.h>\n#include <virt/virt.h>\n\nstruct vm;\n\nstruct mem_block {\n\tuint32_t bfn;\n\tstruct mem_block *next;\n};\n\nstruct vm_iommu {\n\t/* private information for iommu drivers */\n\tvoid *priv;\n\n\tconst struct iommu_ops *ops;\n\n\t/* list of device nodes assigned to this vm */\n\tstruct list_head nodes;\n};\n\n/*\n * pstart - if this area is mapped as continous the pstart\n * is the phsical address of this vmm_area\n */\nstruct vmm_area {\n\tunsigned long start;\n\tunsigned long end;\n\tunsigned long pstart;\n\tint flags;\n\tint vmid;\t\t\t/* 0 - for self other for VM */\n\tstruct list_head list;\n\tstruct mem_block *b_head;\n\n\t/* if this vmm_area is belong to VDEV, this will link\n\t * to the next vmm_area of the VDEV */\n\tstruct vmm_area *next;\n};\n\nstruct mm_struct {\n\tvoid *pgdp;\n\tspinlock_t lock;\n\n\t/*\n\t * vmm_area_free : list to all the free vmm_area\n\t * vmm_area_used : list to all the used vmm_area\n\t * lock\t\t : spin lock for vmm_area allocate\n\t */\n\tstruct list_head vmm_area_free;\n\tstruct list_head vmm_area_used;\n};\n\nint vm_mm_init(struct vm *vm);\nint vm_mm_struct_init(struct vm *vm);\n\nint copy_from_guest(void *target, void __guest *source, size_t size);\n\nint alloc_vm_memory(struct vm *vm);\nvoid release_vm_memory(struct vm *vm);\n\nint create_guest_mapping(struct mm_struct *mm, unsigned long vir,\n\t\tunsigned long phy, size_t size, unsigned long flags);\n\nstruct vmm_area *vm_mmap(struct vm *vm, unsigned long offset,\n\t\tunsigned long size);\n\nvoid *vm_alloc_pages(struct vm *vm, int pages);\n\nunsigned long create_hvm_shmem_map(struct vm *vm,\n\t\tunsigned long phy, uint32_t size);\n\nvoid destroy_hvm_iomem_map(unsigned long vir, uint32_t size);\nint create_early_pmd_mapping(unsigned long vir, unsigned long phy);\n\nstruct vmm_area *split_vmm_area(struct mm_struct *mm,\n\t\tunsigned long base, unsigned long size, int flags);\n\nstruct vmm_area *request_vmm_area(struct mm_struct *mm,\n\t\tunsigned long base, unsigned long pbase,\n\t\tsize_t size, int flags);\n\nint map_vmm_area(struct mm_struct *mm,\n\t\tstruct vmm_area *va, unsigned long pbase);\n\nstruct vmm_area *alloc_free_vmm_area(struct mm_struct *mm,\n\t\tsize_t size, unsigned long mask, int flags);\n\nint unmap_vmm_area(struct mm_struct *mm, struct vmm_area *va);\n\nstruct mem_block *vmm_alloc_memblock(void);\nint vmm_free_memblock(struct mem_block *mb);\nint vmm_has_enough_memory(size_t size);\n\nint release_vmm_area(struct mm_struct *mm, struct vmm_area *va);\n\nint translate_guest_ipa(struct mm_struct *mm,\n\t\tunsigned long offset, unsigned long *pa);\n\nvoid free_shmem(void *addr);\nvoid *alloc_shmem(int pages);\n\n#endif\n"
  },
  {
    "path": "kernel/include/virt/vmodule.h",
    "content": "#ifndef _MINOS_MODULE_H_\n#define _MINOS_MODULE_H_\n\n#include <minos/types.h>\n#include <minos/list.h>\n#include <minos/device_id.h>\n\nstruct vcpu;\n\n#define INVALID_MODULE_ID (-1)\n\nstruct vmodule {\n\tchar name[32];\n\tint id;\n\tstruct list_head list;\n\tuint32_t context_size;\n\n\t/*\n\t * below member usually used for vcpu\n\t *\n\t * state_save - save the context when sched out\n\t * state_restore - restore the context when sched in\n\t * state_init - init the state when the vcpu is create\n\t * state_deinit - destroy the state when the vcpu is releas\n\t * state_reset - reset the state when the vcpu is reset\n\t * state_stop - stop the state when the vcpu is stop\n\t * state_suspend - suspend the state when the vcpu suspend\n\t * state_resume - resume the state when the vcpu is resume\n\t */\n\tvoid (*state_save)(struct vcpu *vcpu, void *context);\n\tvoid (*state_restore)(struct vcpu *vcpu, void *context);\n\tvoid (*state_init)(struct vcpu *vcpu, void *context);\n\tvoid (*state_deinit)(struct vcpu *vcpu, void *context);\n\tvoid (*state_reset)(struct vcpu *vcpu, void *context);\n\tvoid (*state_stop)(struct vcpu *vcpu, void *context);\n\tvoid (*state_suspend)(struct vcpu *vcpu, void *context);\n\tvoid (*state_resume)(struct vcpu *vcpu, void *context);\n\tvoid (*state_dump)(struct vcpu *vcpu, void *context);\n};\n\ntypedef int (*vmodule_init_fn)(struct vmodule *);\n\nint vcpu_vmodules_init(struct vcpu *vcpu);\nint vcpu_vmodules_deinit(struct vcpu *vcpu);\n\nvoid reset_vcpu_vmodule_state(struct vcpu *vcpu);\nvoid save_vcpu_vmodule_state(struct vcpu *vcpu);\nvoid restore_vcpu_vmodule_state(struct vcpu *vcpu);\nvoid suspend_vcpu_vmodule_state(struct vcpu *vcpu);\nvoid resume_vcpu_vmodule_state(struct vcpu *vcpu);\nvoid stop_vcpu_vmodule_state(struct vcpu *vcpu);\nvoid dump_vcpu_vmodule_state(struct vcpu *vcpu);\n\nvoid *get_vmodule_data_by_id(struct vcpu *vcpu, int id);\nint register_vcpu_vmodule(const char *name, vmodule_init_fn fn);\n\n#endif\n"
  },
  {
    "path": "kernel/libs/Kconfig",
    "content": "menu \"System libary config\"\n\nsource \"libs/shell_command/Kconfig\"\n\nendmenu\n"
  },
  {
    "path": "kernel/libs/Makefile",
    "content": "obj-$(CONFIG_SHELL)\t\t+= shell_command/\nobj-$(CONFIG_DEVICE_TREE)\t+= libfdt/\n"
  },
  {
    "path": "kernel/libs/libfdt/Makefile",
    "content": "obj-y += fdt_addresses.o fdt.o fdt_empty_tree.o fdt_overlay.o \\\n\t fdt_ro.o fdt_rw.o fdt_strerror.o fdt_sw.o fdt_wip.o\n"
  },
  {
    "path": "kernel/libs/libfdt/fdt.c",
    "content": "/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2006 David Gibson, IBM Corporation.\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n#include <libfdt/libfdt_env.h>\n\n#include <libfdt/fdt.h>\n#include <libfdt/libfdt.h>\n\n#include \"libfdt_internal.h\"\n\n/*\n * Minimal sanity check for a read-only tree. fdt_ro_probe_() checks\n * that the given buffer contains what appears to be a flattened\n * device tree with sane information in its header.\n */\nint fdt_ro_probe_(const void *fdt)\n{\n\tif (fdt_magic(fdt) == FDT_MAGIC) {\n\t\t/* Complete tree */\n\t\tif (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)\n\t\t\treturn -FDT_ERR_BADVERSION;\n\t\tif (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)\n\t\t\treturn -FDT_ERR_BADVERSION;\n\t} else if (fdt_magic(fdt) == FDT_SW_MAGIC) {\n\t\t/* Unfinished sequential-write blob */\n\t\tif (fdt_size_dt_struct(fdt) == 0)\n\t\t\treturn -FDT_ERR_BADSTATE;\n\t} else {\n\t\treturn -FDT_ERR_BADMAGIC;\n\t}\n\n\treturn 0;\n}\n\nstatic int check_off_(uint32_t hdrsize, uint32_t totalsize, uint32_t off)\n{\n\treturn (off >= hdrsize) && (off <= totalsize);\n}\n\nstatic int check_block_(uint32_t hdrsize, uint32_t totalsize,\n\t\t\tuint32_t base, uint32_t size)\n{\n\tif (!check_off_(hdrsize, totalsize, base))\n\t\treturn 0; /* block start out of bounds */\n\tif ((base + size) < base)\n\t\treturn 0; /* overflow */\n\tif (!check_off_(hdrsize, totalsize, base + size))\n\t\treturn 0; /* block end out of bounds */\n\treturn 1;\n}\n\nsize_t fdt_header_size_(uint32_t version)\n{\n\tif (version <= 1)\n\t\treturn FDT_V1_SIZE;\n\telse if (version <= 2)\n\t\treturn FDT_V2_SIZE;\n\telse if (version <= 3)\n\t\treturn FDT_V3_SIZE;\n\telse if (version <= 16)\n\t\treturn FDT_V16_SIZE;\n\telse\n\t\treturn FDT_V17_SIZE;\n}\n\nint fdt_check_header(const void *fdt)\n{\n\tsize_t hdrsize;\n\n\tif (fdt_magic(fdt) != FDT_MAGIC)\n\t\treturn -FDT_ERR_BADMAGIC;\n\thdrsize = fdt_header_size(fdt);\n\tif ((fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)\n\t    || (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION))\n\t\treturn -FDT_ERR_BADVERSION;\n\tif (fdt_version(fdt) < fdt_last_comp_version(fdt))\n\t\treturn -FDT_ERR_BADVERSION;\n\n\tif ((fdt_totalsize(fdt) < hdrsize)\n\t    || (fdt_totalsize(fdt) > INT_MAX))\n\t\treturn -FDT_ERR_TRUNCATED;\n\n\t/* Bounds check memrsv block */\n\tif (!check_off_(hdrsize, fdt_totalsize(fdt), fdt_off_mem_rsvmap(fdt)))\n\t\treturn -FDT_ERR_TRUNCATED;\n\n\t/* Bounds check structure block */\n\tif (fdt_version(fdt) < 17) {\n\t\tif (!check_off_(hdrsize, fdt_totalsize(fdt),\n\t\t\t\tfdt_off_dt_struct(fdt)))\n\t\t\treturn -FDT_ERR_TRUNCATED;\n\t} else {\n\t\tif (!check_block_(hdrsize, fdt_totalsize(fdt),\n\t\t\t\t  fdt_off_dt_struct(fdt),\n\t\t\t\t  fdt_size_dt_struct(fdt)))\n\t\t\treturn -FDT_ERR_TRUNCATED;\n\t}\n\n\t/* Bounds check strings block */\n\tif (!check_block_(hdrsize, fdt_totalsize(fdt),\n\t\t\t  fdt_off_dt_strings(fdt), fdt_size_dt_strings(fdt)))\n\t\treturn -FDT_ERR_TRUNCATED;\n\n\treturn 0;\n}\n\nconst void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)\n{\n\tunsigned absoffset = offset + fdt_off_dt_struct(fdt);\n\n\tif ((absoffset < offset)\n\t    || ((absoffset + len) < absoffset)\n\t    || (absoffset + len) > fdt_totalsize(fdt))\n\t\treturn NULL;\n\n\tif (fdt_version(fdt) >= 0x11)\n\t\tif (((offset + len) < offset)\n\t\t    || ((offset + len) > fdt_size_dt_struct(fdt)))\n\t\t\treturn NULL;\n\n\treturn fdt_offset_ptr_(fdt, offset);\n}\n\nuint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)\n{\n\tconst fdt32_t *tagp, *lenp;\n\tuint32_t tag;\n\tint offset = startoffset;\n\tconst char *p;\n\n\t*nextoffset = -FDT_ERR_TRUNCATED;\n\ttagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);\n\tif (!tagp)\n\t\treturn FDT_END; /* premature end */\n\ttag = fdt32_to_cpu(*tagp);\n\toffset += FDT_TAGSIZE;\n\n\t*nextoffset = -FDT_ERR_BADSTRUCTURE;\n\tswitch (tag) {\n\tcase FDT_BEGIN_NODE:\n\t\t/* skip name */\n\t\tdo {\n\t\t\tp = fdt_offset_ptr(fdt, offset++, 1);\n\t\t} while (p && (*p != '\\0'));\n\t\tif (!p)\n\t\t\treturn FDT_END; /* premature end */\n\t\tbreak;\n\n\tcase FDT_PROP:\n\t\tlenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));\n\t\tif (!lenp)\n\t\t\treturn FDT_END; /* premature end */\n\t\t/* skip-name offset, length and value */\n\t\toffset += sizeof(struct fdt_property) - FDT_TAGSIZE\n\t\t\t+ fdt32_to_cpu(*lenp);\n\t\tif (fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 &&\n\t\t    ((offset - fdt32_to_cpu(*lenp)) % 8) != 0)\n\t\t\toffset += 4;\n\t\tbreak;\n\n\tcase FDT_END:\n\tcase FDT_END_NODE:\n\tcase FDT_NOP:\n\t\tbreak;\n\n\tdefault:\n\t\treturn FDT_END;\n\t}\n\n\tif (!fdt_offset_ptr(fdt, startoffset, offset - startoffset))\n\t\treturn FDT_END; /* premature end */\n\n\t*nextoffset = FDT_TAGALIGN(offset);\n\treturn tag;\n}\n\nint fdt_check_node_offset_(const void *fdt, int offset)\n{\n\tif ((offset < 0) || (offset % FDT_TAGSIZE)\n\t    || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))\n\t\treturn -FDT_ERR_BADOFFSET;\n\n\treturn offset;\n}\n\nint fdt_check_prop_offset_(const void *fdt, int offset)\n{\n\tif ((offset < 0) || (offset % FDT_TAGSIZE)\n\t    || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP))\n\t\treturn -FDT_ERR_BADOFFSET;\n\n\treturn offset;\n}\n\nint fdt_next_node(const void *fdt, int offset, int *depth)\n{\n\tint nextoffset = 0;\n\tuint32_t tag;\n\n\tif (offset >= 0)\n\t\tif ((nextoffset = fdt_check_node_offset_(fdt, offset)) < 0)\n\t\t\treturn nextoffset;\n\n\tdo {\n\t\toffset = nextoffset;\n\t\ttag = fdt_next_tag(fdt, offset, &nextoffset);\n\n\t\tswitch (tag) {\n\t\tcase FDT_PROP:\n\t\tcase FDT_NOP:\n\t\t\tbreak;\n\n\t\tcase FDT_BEGIN_NODE:\n\t\t\tif (depth)\n\t\t\t\t(*depth)++;\n\t\t\tbreak;\n\n\t\tcase FDT_END_NODE:\n\t\t\tif (depth && ((--(*depth)) < 0))\n\t\t\t\treturn nextoffset;\n\t\t\tbreak;\n\n\t\tcase FDT_END:\n\t\t\tif ((nextoffset >= 0)\n\t\t\t    || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth))\n\t\t\t\treturn -FDT_ERR_NOTFOUND;\n\t\t\telse\n\t\t\t\treturn nextoffset;\n\t\t}\n\t} while (tag != FDT_BEGIN_NODE);\n\n\treturn offset;\n}\n\nint fdt_first_subnode(const void *fdt, int offset)\n{\n\tint depth = 0;\n\n\toffset = fdt_next_node(fdt, offset, &depth);\n\tif (offset < 0 || depth != 1)\n\t\treturn -FDT_ERR_NOTFOUND;\n\n\treturn offset;\n}\n\nint fdt_next_subnode(const void *fdt, int offset)\n{\n\tint depth = 1;\n\n\t/*\n\t * With respect to the parent, the depth of the next subnode will be\n\t * the same as the last.\n\t */\n\tdo {\n\t\toffset = fdt_next_node(fdt, offset, &depth);\n\t\tif (offset < 0 || depth < 1)\n\t\t\treturn -FDT_ERR_NOTFOUND;\n\t} while (depth > 1);\n\n\treturn offset;\n}\n\nconst char *fdt_find_string_(const char *strtab, int tabsize, const char *s)\n{\n\tint len = strlen(s) + 1;\n\tconst char *last = strtab + tabsize - len;\n\tconst char *p;\n\n\tfor (p = strtab; p <= last; p++)\n\t\tif (memcmp(p, s, len) == 0)\n\t\t\treturn p;\n\treturn NULL;\n}\n\nint fdt_move(const void *fdt, void *buf, int bufsize)\n{\n\tFDT_RO_PROBE(fdt);\n\n\tif (fdt_totalsize(fdt) > bufsize)\n\t\treturn -FDT_ERR_NOSPACE;\n\n\tmemmove(buf, fdt, fdt_totalsize(fdt));\n\treturn 0;\n}\n"
  },
  {
    "path": "kernel/libs/libfdt/fdt_addresses.c",
    "content": "/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2014 David Gibson <david@gibson.dropbear.id.au>\n * Copyright (C) 2018 embedded brains GmbH\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n#include <libfdt/libfdt_env.h>\n\n#include <libfdt/fdt.h>\n#include <libfdt/libfdt.h>\n\n#include \"libfdt_internal.h\"\n\nstatic int fdt_cells(const void *fdt, int nodeoffset, const char *name)\n{\n\tconst fdt32_t *c;\n\tint val;\n\tint len;\n\n\tc = fdt_getprop(fdt, nodeoffset, name, &len);\n\tif (!c)\n\t\treturn 2;\n\n\tif (len != sizeof(*c))\n\t\treturn -FDT_ERR_BADNCELLS;\n\n\tval = fdt32_to_cpu(*c);\n\tif ((val <= 0) || (val > FDT_MAX_NCELLS))\n\t\treturn -FDT_ERR_BADNCELLS;\n\n\treturn val;\n}\n\nint fdt_address_cells(const void *fdt, int nodeoffset)\n{\n\treturn fdt_cells(fdt, nodeoffset, \"#address-cells\");\n}\n\nint fdt_size_cells(const void *fdt, int nodeoffset)\n{\n\treturn fdt_cells(fdt, nodeoffset, \"#size-cells\");\n}\n"
  },
  {
    "path": "kernel/libs/libfdt/fdt_empty_tree.c",
    "content": "/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2012 David Gibson, IBM Corporation.\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n#include <libfdt/libfdt_env.h>\n\n#include <libfdt/fdt.h>\n#include <libfdt/libfdt.h>\n\n#include \"libfdt_internal.h\"\n\nint fdt_create_empty_tree(void *buf, int bufsize)\n{\n\tint err;\n\n\terr = fdt_create(buf, bufsize);\n\tif (err)\n\t\treturn err;\n\n\terr = fdt_finish_reservemap(buf);\n\tif (err)\n\t\treturn err;\n\n\terr = fdt_begin_node(buf, \"\");\n\tif (err)\n\t\treturn err;\n\n\terr =  fdt_end_node(buf);\n\tif (err)\n\t\treturn err;\n\n\terr = fdt_finish(buf);\n\tif (err)\n\t\treturn err;\n\n\treturn fdt_open_into(buf, buf, bufsize);\n}\n"
  },
  {
    "path": "kernel/libs/libfdt/fdt_overlay.c",
    "content": "/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2016 Free Electrons\n * Copyright (C) 2016 NextThing Co.\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n#include <libfdt/libfdt_env.h>\n\n#include <libfdt/fdt.h>\n#include <libfdt/libfdt.h>\n\n#include \"libfdt_internal.h\"\n\n/**\n * overlay_get_target_phandle - retrieves the target phandle of a fragment\n * @fdto: pointer to the device tree overlay blob\n * @fragment: node offset of the fragment in the overlay\n *\n * overlay_get_target_phandle() retrieves the target phandle of an\n * overlay fragment when that fragment uses a phandle (target\n * property) instead of a path (target-path property).\n *\n * returns:\n *      the phandle pointed by the target property\n *      0, if the phandle was not found\n *\t-1, if the phandle was malformed\n */\nstatic uint32_t overlay_get_target_phandle(const void *fdto, int fragment)\n{\n\tconst fdt32_t *val;\n\tint len;\n\n\tval = fdt_getprop(fdto, fragment, \"target\", &len);\n\tif (!val)\n\t\treturn 0;\n\n\tif ((len != sizeof(*val)) || (fdt32_to_cpu(*val) == (uint32_t)-1))\n\t\treturn (uint32_t)-1;\n\n\treturn fdt32_to_cpu(*val);\n}\n\n/**\n * overlay_get_target - retrieves the offset of a fragment's target\n * @fdt: Base device tree blob\n * @fdto: Device tree overlay blob\n * @fragment: node offset of the fragment in the overlay\n * @pathp: pointer which receives the path of the target (or NULL)\n *\n * overlay_get_target() retrieves the target offset in the base\n * device tree of a fragment, no matter how the actual targetting is\n * done (through a phandle or a path)\n *\n * returns:\n *      the targetted node offset in the base device tree\n *      Negative error code on error\n */\nstatic int overlay_get_target(const void *fdt, const void *fdto,\n\t\t\t      int fragment, char const **pathp)\n{\n\tuint32_t phandle;\n\tconst char *path = NULL;\n\tint path_len = 0, ret;\n\n\t/* Try first to do a phandle based lookup */\n\tphandle = overlay_get_target_phandle(fdto, fragment);\n\tif (phandle == (uint32_t)-1)\n\t\treturn -FDT_ERR_BADPHANDLE;\n\n\t/* no phandle, try path */\n\tif (!phandle) {\n\t\t/* And then a path based lookup */\n\t\tpath = fdt_getprop(fdto, fragment, \"target-path\", &path_len);\n\t\tif (path)\n\t\t\tret = fdt_path_offset(fdt, path);\n\t\telse\n\t\t\tret = path_len;\n\t} else\n\t\tret = fdt_node_offset_by_phandle(fdt, phandle);\n\n\t/*\n\t* If we haven't found either a target or a\n\t* target-path property in a node that contains a\n\t* __overlay__ subnode (we wouldn't be called\n\t* otherwise), consider it a improperly written\n\t* overlay\n\t*/\n\tif (ret < 0 && path_len == -FDT_ERR_NOTFOUND)\n\t\tret = -FDT_ERR_BADOVERLAY;\n\n\t/* return on error */\n\tif (ret < 0)\n\t\treturn ret;\n\n\t/* return pointer to path (if available) */\n\tif (pathp)\n\t\t*pathp = path ? path : NULL;\n\n\treturn ret;\n}\n\n/**\n * overlay_phandle_add_offset - Increases a phandle by an offset\n * @fdt: Base device tree blob\n * @node: Device tree overlay blob\n * @name: Name of the property to modify (phandle or linux,phandle)\n * @delta: offset to apply\n *\n * overlay_phandle_add_offset() increments a node phandle by a given\n * offset.\n *\n * returns:\n *      0 on success.\n *      Negative error code on error\n */\nstatic int overlay_phandle_add_offset(void *fdt, int node,\n\t\t\t\t      const char *name, uint32_t delta)\n{\n\tconst fdt32_t *val;\n\tuint32_t adj_val;\n\tint len;\n\n\tval = fdt_getprop(fdt, node, name, &len);\n\tif (!val)\n\t\treturn len;\n\n\tif (len != sizeof(*val))\n\t\treturn -FDT_ERR_BADPHANDLE;\n\n\tadj_val = fdt32_to_cpu(*val);\n\tif ((adj_val + delta) < adj_val)\n\t\treturn -FDT_ERR_NOPHANDLES;\n\n\tadj_val += delta;\n\tif (adj_val == (uint32_t)-1)\n\t\treturn -FDT_ERR_NOPHANDLES;\n\n\treturn fdt_setprop_inplace_u32(fdt, node, name, adj_val);\n}\n\n/**\n * overlay_adjust_node_phandles - Offsets the phandles of a node\n * @fdto: Device tree overlay blob\n * @node: Offset of the node we want to adjust\n * @delta: Offset to shift the phandles of\n *\n * overlay_adjust_node_phandles() adds a constant to all the phandles\n * of a given node. This is mainly use as part of the overlay\n * application process, when we want to update all the overlay\n * phandles to not conflict with the overlays of the base device tree.\n *\n * returns:\n *      0 on success\n *      Negative error code on failure\n */\nstatic int overlay_adjust_node_phandles(void *fdto, int node,\n\t\t\t\t\tuint32_t delta)\n{\n\tint child;\n\tint ret;\n\n\tret = overlay_phandle_add_offset(fdto, node, \"phandle\", delta);\n\tif (ret && ret != -FDT_ERR_NOTFOUND)\n\t\treturn ret;\n\n\tret = overlay_phandle_add_offset(fdto, node, \"linux,phandle\", delta);\n\tif (ret && ret != -FDT_ERR_NOTFOUND)\n\t\treturn ret;\n\n\tfdt_for_each_subnode(child, fdto, node) {\n\t\tret = overlay_adjust_node_phandles(fdto, child, delta);\n\t\tif (ret)\n\t\t\treturn ret;\n\t}\n\n\treturn 0;\n}\n\n/**\n * overlay_adjust_local_phandles - Adjust the phandles of a whole overlay\n * @fdto: Device tree overlay blob\n * @delta: Offset to shift the phandles of\n *\n * overlay_adjust_local_phandles() adds a constant to all the\n * phandles of an overlay. This is mainly use as part of the overlay\n * application process, when we want to update all the overlay\n * phandles to not conflict with the overlays of the base device tree.\n *\n * returns:\n *      0 on success\n *      Negative error code on failure\n */\nstatic int overlay_adjust_local_phandles(void *fdto, uint32_t delta)\n{\n\t/*\n\t * Start adjusting the phandles from the overlay root\n\t */\n\treturn overlay_adjust_node_phandles(fdto, 0, delta);\n}\n\n/**\n * overlay_update_local_node_references - Adjust the overlay references\n * @fdto: Device tree overlay blob\n * @tree_node: Node offset of the node to operate on\n * @fixup_node: Node offset of the matching local fixups node\n * @delta: Offset to shift the phandles of\n *\n * overlay_update_local_nodes_references() update the phandles\n * pointing to a node within the device tree overlay by adding a\n * constant delta.\n *\n * This is mainly used as part of a device tree application process,\n * where you want the device tree overlays phandles to not conflict\n * with the ones from the base device tree before merging them.\n *\n * returns:\n *      0 on success\n *      Negative error code on failure\n */\nstatic int overlay_update_local_node_references(void *fdto,\n\t\t\t\t\t\tint tree_node,\n\t\t\t\t\t\tint fixup_node,\n\t\t\t\t\t\tuint32_t delta)\n{\n\tint fixup_prop;\n\tint fixup_child;\n\tint ret;\n\n\tfdt_for_each_property_offset(fixup_prop, fdto, fixup_node) {\n\t\tconst fdt32_t *fixup_val;\n\t\tconst char *tree_val;\n\t\tconst char *name;\n\t\tint fixup_len;\n\t\tint tree_len;\n\t\tint i;\n\n\t\tfixup_val = fdt_getprop_by_offset(fdto, fixup_prop,\n\t\t\t\t\t\t  &name, &fixup_len);\n\t\tif (!fixup_val)\n\t\t\treturn fixup_len;\n\n\t\tif (fixup_len % sizeof(uint32_t))\n\t\t\treturn -FDT_ERR_BADOVERLAY;\n\n\t\ttree_val = fdt_getprop(fdto, tree_node, name, &tree_len);\n\t\tif (!tree_val) {\n\t\t\tif (tree_len == -FDT_ERR_NOTFOUND)\n\t\t\t\treturn -FDT_ERR_BADOVERLAY;\n\n\t\t\treturn tree_len;\n\t\t}\n\n\t\tfor (i = 0; i < (fixup_len / sizeof(uint32_t)); i++) {\n\t\t\tfdt32_t adj_val;\n\t\t\tuint32_t poffset;\n\n\t\t\tpoffset = fdt32_to_cpu(fixup_val[i]);\n\n\t\t\t/*\n\t\t\t * phandles to fixup can be unaligned.\n\t\t\t *\n\t\t\t * Use a memcpy for the architectures that do\n\t\t\t * not support unaligned accesses.\n\t\t\t */\n\t\t\tmemcpy(&adj_val, tree_val + poffset, sizeof(adj_val));\n\n\t\t\tadj_val = cpu_to_fdt32(fdt32_to_cpu(adj_val) + delta);\n\n\t\t\tret = fdt_setprop_inplace_namelen_partial(fdto,\n\t\t\t\t\t\t\t\t  tree_node,\n\t\t\t\t\t\t\t\t  name,\n\t\t\t\t\t\t\t\t  strlen(name),\n\t\t\t\t\t\t\t\t  poffset,\n\t\t\t\t\t\t\t\t  &adj_val,\n\t\t\t\t\t\t\t\t  sizeof(adj_val));\n\t\t\tif (ret == -FDT_ERR_NOSPACE)\n\t\t\t\treturn -FDT_ERR_BADOVERLAY;\n\n\t\t\tif (ret)\n\t\t\t\treturn ret;\n\t\t}\n\t}\n\n\tfdt_for_each_subnode(fixup_child, fdto, fixup_node) {\n\t\tconst char *fixup_child_name = fdt_get_name(fdto, fixup_child,\n\t\t\t\t\t\t\t    NULL);\n\t\tint tree_child;\n\n\t\ttree_child = fdt_subnode_offset(fdto, tree_node,\n\t\t\t\t\t\tfixup_child_name);\n\t\tif (tree_child == -FDT_ERR_NOTFOUND)\n\t\t\treturn -FDT_ERR_BADOVERLAY;\n\t\tif (tree_child < 0)\n\t\t\treturn tree_child;\n\n\t\tret = overlay_update_local_node_references(fdto,\n\t\t\t\t\t\t\t   tree_child,\n\t\t\t\t\t\t\t   fixup_child,\n\t\t\t\t\t\t\t   delta);\n\t\tif (ret)\n\t\t\treturn ret;\n\t}\n\n\treturn 0;\n}\n\n/**\n * overlay_update_local_references - Adjust the overlay references\n * @fdto: Device tree overlay blob\n * @delta: Offset to shift the phandles of\n *\n * overlay_update_local_references() update all the phandles pointing\n * to a node within the device tree overlay by adding a constant\n * delta to not conflict with the base overlay.\n *\n * This is mainly used as part of a device tree application process,\n * where you want the device tree overlays phandles to not conflict\n * with the ones from the base device tree before merging them.\n *\n * returns:\n *      0 on success\n *      Negative error code on failure\n */\nstatic int overlay_update_local_references(void *fdto, uint32_t delta)\n{\n\tint fixups;\n\n\tfixups = fdt_path_offset(fdto, \"/__local_fixups__\");\n\tif (fixups < 0) {\n\t\t/* There's no local phandles to adjust, bail out */\n\t\tif (fixups == -FDT_ERR_NOTFOUND)\n\t\t\treturn 0;\n\n\t\treturn fixups;\n\t}\n\n\t/*\n\t * Update our local references from the root of the tree\n\t */\n\treturn overlay_update_local_node_references(fdto, 0, fixups,\n\t\t\t\t\t\t    delta);\n}\n\n/**\n * overlay_fixup_one_phandle - Set an overlay phandle to the base one\n * @fdt: Base Device Tree blob\n * @fdto: Device tree overlay blob\n * @symbols_off: Node offset of the symbols node in the base device tree\n * @path: Path to a node holding a phandle in the overlay\n * @path_len: number of path characters to consider\n * @name: Name of the property holding the phandle reference in the overlay\n * @name_len: number of name characters to consider\n * @poffset: Offset within the overlay property where the phandle is stored\n * @label: Label of the node referenced by the phandle\n *\n * overlay_fixup_one_phandle() resolves an overlay phandle pointing to\n * a node in the base device tree.\n *\n * This is part of the device tree overlay application process, when\n * you want all the phandles in the overlay to point to the actual\n * base dt nodes.\n *\n * returns:\n *      0 on success\n *      Negative error code on failure\n */\nstatic int overlay_fixup_one_phandle(void *fdt, void *fdto,\n\t\t\t\t     int symbols_off,\n\t\t\t\t     const char *path, uint32_t path_len,\n\t\t\t\t     const char *name, uint32_t name_len,\n\t\t\t\t     int poffset, const char *label)\n{\n\tconst char *symbol_path;\n\tuint32_t phandle;\n\tfdt32_t phandle_prop;\n\tint symbol_off, fixup_off;\n\tint prop_len;\n\n\tif (symbols_off < 0)\n\t\treturn symbols_off;\n\n\tsymbol_path = fdt_getprop(fdt, symbols_off, label,\n\t\t\t\t  &prop_len);\n\tif (!symbol_path)\n\t\treturn prop_len;\n\n\tsymbol_off = fdt_path_offset(fdt, symbol_path);\n\tif (symbol_off < 0)\n\t\treturn symbol_off;\n\n\tphandle = fdt_get_phandle(fdt, symbol_off);\n\tif (!phandle)\n\t\treturn -FDT_ERR_NOTFOUND;\n\n\tfixup_off = fdt_path_offset_namelen(fdto, path, path_len);\n\tif (fixup_off == -FDT_ERR_NOTFOUND)\n\t\treturn -FDT_ERR_BADOVERLAY;\n\tif (fixup_off < 0)\n\t\treturn fixup_off;\n\n\tphandle_prop = cpu_to_fdt32(phandle);\n\treturn fdt_setprop_inplace_namelen_partial(fdto, fixup_off,\n\t\t\t\t\t\t   name, name_len, poffset,\n\t\t\t\t\t\t   &phandle_prop,\n\t\t\t\t\t\t   sizeof(phandle_prop));\n};\n\n/**\n * overlay_fixup_phandle - Set an overlay phandle to the base one\n * @fdt: Base Device Tree blob\n * @fdto: Device tree overlay blob\n * @symbols_off: Node offset of the symbols node in the base device tree\n * @property: Property offset in the overlay holding the list of fixups\n *\n * overlay_fixup_phandle() resolves all the overlay phandles pointed\n * to in a __fixups__ property, and updates them to match the phandles\n * in use in the base device tree.\n *\n * This is part of the device tree overlay application process, when\n * you want all the phandles in the overlay to point to the actual\n * base dt nodes.\n *\n * returns:\n *      0 on success\n *      Negative error code on failure\n */\nstatic int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off,\n\t\t\t\t int property)\n{\n\tconst char *value;\n\tconst char *label;\n\tint len;\n\n\tvalue = fdt_getprop_by_offset(fdto, property,\n\t\t\t\t      &label, &len);\n\tif (!value) {\n\t\tif (len == -FDT_ERR_NOTFOUND)\n\t\t\treturn -FDT_ERR_INTERNAL;\n\n\t\treturn len;\n\t}\n\n\tdo {\n\t\tconst char *path, *name, *fixup_end;\n\t\tconst char *fixup_str = value;\n\t\tuint32_t path_len, name_len;\n\t\tuint32_t fixup_len;\n\t\tchar *sep, *endptr;\n\t\tint poffset, ret;\n\n\t\tfixup_end = memchr(value, '\\0', len);\n\t\tif (!fixup_end)\n\t\t\treturn -FDT_ERR_BADOVERLAY;\n\t\tfixup_len = fixup_end - fixup_str;\n\n\t\tlen -= fixup_len + 1;\n\t\tvalue += fixup_len + 1;\n\n\t\tpath = fixup_str;\n\t\tsep = memchr(fixup_str, ':', fixup_len);\n\t\tif (!sep || *sep != ':')\n\t\t\treturn -FDT_ERR_BADOVERLAY;\n\n\t\tpath_len = sep - path;\n\t\tif (path_len == (fixup_len - 1))\n\t\t\treturn -FDT_ERR_BADOVERLAY;\n\n\t\tfixup_len -= path_len + 1;\n\t\tname = sep + 1;\n\t\tsep = memchr(name, ':', fixup_len);\n\t\tif (!sep || *sep != ':')\n\t\t\treturn -FDT_ERR_BADOVERLAY;\n\n\t\tname_len = sep - name;\n\t\tif (!name_len)\n\t\t\treturn -FDT_ERR_BADOVERLAY;\n\n\t\tpoffset = strtoul(sep + 1, &endptr, 10);\n\t\tif ((*endptr != '\\0') || (endptr <= (sep + 1)))\n\t\t\treturn -FDT_ERR_BADOVERLAY;\n\n\t\tret = overlay_fixup_one_phandle(fdt, fdto, symbols_off,\n\t\t\t\t\t\tpath, path_len, name, name_len,\n\t\t\t\t\t\tpoffset, label);\n\t\tif (ret)\n\t\t\treturn ret;\n\t} while (len > 0);\n\n\treturn 0;\n}\n\n/**\n * overlay_fixup_phandles - Resolve the overlay phandles to the base\n *                          device tree\n * @fdt: Base Device Tree blob\n * @fdto: Device tree overlay blob\n *\n * overlay_fixup_phandles() resolves all the overlay phandles pointing\n * to nodes in the base device tree.\n *\n * This is one of the steps of the device tree overlay application\n * process, when you want all the phandles in the overlay to point to\n * the actual base dt nodes.\n *\n * returns:\n *      0 on success\n *      Negative error code on failure\n */\nstatic int overlay_fixup_phandles(void *fdt, void *fdto)\n{\n\tint fixups_off, symbols_off;\n\tint property;\n\n\t/* We can have overlays without any fixups */\n\tfixups_off = fdt_path_offset(fdto, \"/__fixups__\");\n\tif (fixups_off == -FDT_ERR_NOTFOUND)\n\t\treturn 0; /* nothing to do */\n\tif (fixups_off < 0)\n\t\treturn fixups_off;\n\n\t/* And base DTs without symbols */\n\tsymbols_off = fdt_path_offset(fdt, \"/__symbols__\");\n\tif ((symbols_off < 0 && (symbols_off != -FDT_ERR_NOTFOUND)))\n\t\treturn symbols_off;\n\n\tfdt_for_each_property_offset(property, fdto, fixups_off) {\n\t\tint ret;\n\n\t\tret = overlay_fixup_phandle(fdt, fdto, symbols_off, property);\n\t\tif (ret)\n\t\t\treturn ret;\n\t}\n\n\treturn 0;\n}\n\n/**\n * overlay_apply_node - Merges a node into the base device tree\n * @fdt: Base Device Tree blob\n * @target: Node offset in the base device tree to apply the fragment to\n * @fdto: Device tree overlay blob\n * @node: Node offset in the overlay holding the changes to merge\n *\n * overlay_apply_node() merges a node into a target base device tree\n * node pointed.\n *\n * This is part of the final step in the device tree overlay\n * application process, when all the phandles have been adjusted and\n * resolved and you just have to merge overlay into the base device\n * tree.\n *\n * returns:\n *      0 on success\n *      Negative error code on failure\n */\nstatic int overlay_apply_node(void *fdt, int target,\n\t\t\t      void *fdto, int node)\n{\n\tint property;\n\tint subnode;\n\n\tfdt_for_each_property_offset(property, fdto, node) {\n\t\tconst char *name;\n\t\tconst void *prop;\n\t\tint prop_len;\n\t\tint ret;\n\n\t\tprop = fdt_getprop_by_offset(fdto, property, &name,\n\t\t\t\t\t     &prop_len);\n\t\tif (prop_len == -FDT_ERR_NOTFOUND)\n\t\t\treturn -FDT_ERR_INTERNAL;\n\t\tif (prop_len < 0)\n\t\t\treturn prop_len;\n\n\t\tret = fdt_setprop(fdt, target, name, prop, prop_len);\n\t\tif (ret)\n\t\t\treturn ret;\n\t}\n\n\tfdt_for_each_subnode(subnode, fdto, node) {\n\t\tconst char *name = fdt_get_name(fdto, subnode, NULL);\n\t\tint nnode;\n\t\tint ret;\n\n\t\tnnode = fdt_add_subnode(fdt, target, name);\n\t\tif (nnode == -FDT_ERR_EXISTS) {\n\t\t\tnnode = fdt_subnode_offset(fdt, target, name);\n\t\t\tif (nnode == -FDT_ERR_NOTFOUND)\n\t\t\t\treturn -FDT_ERR_INTERNAL;\n\t\t}\n\n\t\tif (nnode < 0)\n\t\t\treturn nnode;\n\n\t\tret = overlay_apply_node(fdt, nnode, fdto, subnode);\n\t\tif (ret)\n\t\t\treturn ret;\n\t}\n\n\treturn 0;\n}\n\n/**\n * overlay_merge - Merge an overlay into its base device tree\n * @fdt: Base Device Tree blob\n * @fdto: Device tree overlay blob\n *\n * overlay_merge() merges an overlay into its base device tree.\n *\n * This is the next to last step in the device tree overlay application\n * process, when all the phandles have been adjusted and resolved and\n * you just have to merge overlay into the base device tree.\n *\n * returns:\n *      0 on success\n *      Negative error code on failure\n */\nstatic int overlay_merge(void *fdt, void *fdto)\n{\n\tint fragment;\n\n\tfdt_for_each_subnode(fragment, fdto, 0) {\n\t\tint overlay;\n\t\tint target;\n\t\tint ret;\n\n\t\t/*\n\t\t * Each fragments will have an __overlay__ node. If\n\t\t * they don't, it's not supposed to be merged\n\t\t */\n\t\toverlay = fdt_subnode_offset(fdto, fragment, \"__overlay__\");\n\t\tif (overlay == -FDT_ERR_NOTFOUND)\n\t\t\tcontinue;\n\n\t\tif (overlay < 0)\n\t\t\treturn overlay;\n\n\t\ttarget = overlay_get_target(fdt, fdto, fragment, NULL);\n\t\tif (target < 0)\n\t\t\treturn target;\n\n\t\tret = overlay_apply_node(fdt, target, fdto, overlay);\n\t\tif (ret)\n\t\t\treturn ret;\n\t}\n\n\treturn 0;\n}\n\nstatic int get_path_len(const void *fdt, int nodeoffset)\n{\n\tint len = 0, namelen;\n\tconst char *name;\n\n\tFDT_RO_PROBE(fdt);\n\n\tfor (;;) {\n\t\tname = fdt_get_name(fdt, nodeoffset, &namelen);\n\t\tif (!name)\n\t\t\treturn namelen;\n\n\t\t/* root? we're done */\n\t\tif (namelen == 0)\n\t\t\tbreak;\n\n\t\tnodeoffset = fdt_parent_offset(fdt, nodeoffset);\n\t\tif (nodeoffset < 0)\n\t\t\treturn nodeoffset;\n\t\tlen += namelen + 1;\n\t}\n\n\t/* in case of root pretend it's \"/\" */\n\tif (len == 0)\n\t\tlen++;\n\treturn len;\n}\n\n/**\n * overlay_symbol_update - Update the symbols of base tree after a merge\n * @fdt: Base Device Tree blob\n * @fdto: Device tree overlay blob\n *\n * overlay_symbol_update() updates the symbols of the base tree with the\n * symbols of the applied overlay\n *\n * This is the last step in the device tree overlay application\n * process, allowing the reference of overlay symbols by subsequent\n * overlay operations.\n *\n * returns:\n *      0 on success\n *      Negative error code on failure\n */\nstatic int overlay_symbol_update(void *fdt, void *fdto)\n{\n\tint root_sym, ov_sym, prop, path_len, fragment, target;\n\tint len, frag_name_len, ret, rel_path_len;\n\tconst char *s, *e;\n\tconst char *path;\n\tconst char *name;\n\tconst char *frag_name;\n\tconst char *rel_path;\n\tconst char *target_path;\n\tchar *buf;\n\tvoid *p;\n\n\tov_sym = fdt_subnode_offset(fdto, 0, \"__symbols__\");\n\n\t/* if no overlay symbols exist no problem */\n\tif (ov_sym < 0)\n\t\treturn 0;\n\n\troot_sym = fdt_subnode_offset(fdt, 0, \"__symbols__\");\n\n\t/* it no root symbols exist we should create them */\n\tif (root_sym == -FDT_ERR_NOTFOUND)\n\t\troot_sym = fdt_add_subnode(fdt, 0, \"__symbols__\");\n\n\t/* any error is fatal now */\n\tif (root_sym < 0)\n\t\treturn root_sym;\n\n\t/* iterate over each overlay symbol */\n\tfdt_for_each_property_offset(prop, fdto, ov_sym) {\n\t\tpath = fdt_getprop_by_offset(fdto, prop, &name, &path_len);\n\t\tif (!path)\n\t\t\treturn path_len;\n\n\t\t/* verify it's a string property (terminated by a single \\0) */\n\t\tif (path_len < 1 || memchr(path, '\\0', path_len) != &path[path_len - 1])\n\t\t\treturn -FDT_ERR_BADVALUE;\n\n\t\t/* keep end marker to avoid strlen() */\n\t\te = path + path_len;\n\n\t\t/* format: /<fragment-name>/__overlay__/<relative-subnode-path> */\n\n\t\tif (*path != '/')\n\t\t\treturn -FDT_ERR_BADVALUE;\n\n\t\t/* get fragment name first */\n\t\ts = strchr(path + 1, '/');\n\t\tif (!s)\n\t\t\treturn -FDT_ERR_BADOVERLAY;\n\n\t\tfrag_name = path + 1;\n\t\tfrag_name_len = s - path - 1;\n\n\t\t/* verify format; safe since \"s\" lies in \\0 terminated prop */\n\t\tlen = sizeof(\"/__overlay__/\") - 1;\n\t\tif ((e - s) < len || memcmp(s, \"/__overlay__/\", len))\n\t\t\treturn -FDT_ERR_BADOVERLAY;\n\n\t\trel_path = s + len;\n\t\trel_path_len = e - rel_path;\n\n\t\t/* find the fragment index in which the symbol lies */\n\t\tret = fdt_subnode_offset_namelen(fdto, 0, frag_name,\n\t\t\t\t\t       frag_name_len);\n\t\t/* not found? */\n\t\tif (ret < 0)\n\t\t\treturn -FDT_ERR_BADOVERLAY;\n\t\tfragment = ret;\n\n\t\t/* an __overlay__ subnode must exist */\n\t\tret = fdt_subnode_offset(fdto, fragment, \"__overlay__\");\n\t\tif (ret < 0)\n\t\t\treturn -FDT_ERR_BADOVERLAY;\n\n\t\t/* get the target of the fragment */\n\t\tret = overlay_get_target(fdt, fdto, fragment, &target_path);\n\t\tif (ret < 0)\n\t\t\treturn ret;\n\t\ttarget = ret;\n\n\t\t/* if we have a target path use */\n\t\tif (!target_path) {\n\t\t\tret = get_path_len(fdt, target);\n\t\t\tif (ret < 0)\n\t\t\t\treturn ret;\n\t\t\tlen = ret;\n\t\t} else {\n\t\t\tlen = strlen(target_path);\n\t\t}\n\n\t\tret = fdt_setprop_placeholder(fdt, root_sym, name,\n\t\t\t\tlen + (len > 1) + rel_path_len + 1, &p);\n\t\tif (ret < 0)\n\t\t\treturn ret;\n\n\t\tif (!target_path) {\n\t\t\t/* again in case setprop_placeholder changed it */\n\t\t\tret = overlay_get_target(fdt, fdto, fragment, &target_path);\n\t\t\tif (ret < 0)\n\t\t\t\treturn ret;\n\t\t\ttarget = ret;\n\t\t}\n\n\t\tbuf = p;\n\t\tif (len > 1) { /* target is not root */\n\t\t\tif (!target_path) {\n\t\t\t\tret = fdt_get_path(fdt, target, buf, len + 1);\n\t\t\t\tif (ret < 0)\n\t\t\t\t\treturn ret;\n\t\t\t} else\n\t\t\t\tmemcpy(buf, target_path, len + 1);\n\n\t\t} else\n\t\t\tlen--;\n\n\t\tbuf[len] = '/';\n\t\tmemcpy(buf + len + 1, rel_path, rel_path_len);\n\t\tbuf[len + 1 + rel_path_len] = '\\0';\n\t}\n\n\treturn 0;\n}\n\nint fdt_overlay_apply(void *fdt, void *fdto)\n{\n\tuint32_t delta = fdt_get_max_phandle(fdt);\n\tint ret;\n\n\tFDT_RO_PROBE(fdt);\n\tFDT_RO_PROBE(fdto);\n\n\tret = overlay_adjust_local_phandles(fdto, delta);\n\tif (ret)\n\t\tgoto err;\n\n\tret = overlay_update_local_references(fdto, delta);\n\tif (ret)\n\t\tgoto err;\n\n\tret = overlay_fixup_phandles(fdt, fdto);\n\tif (ret)\n\t\tgoto err;\n\n\tret = overlay_merge(fdt, fdto);\n\tif (ret)\n\t\tgoto err;\n\n\tret = overlay_symbol_update(fdt, fdto);\n\tif (ret)\n\t\tgoto err;\n\n\t/*\n\t * The overlay has been damaged, erase its magic.\n\t */\n\tfdt_set_magic(fdto, ~0);\n\n\treturn 0;\n\nerr:\n\t/*\n\t * The overlay might have been damaged, erase its magic.\n\t */\n\tfdt_set_magic(fdto, ~0);\n\n\t/*\n\t * The base device tree might have been damaged, erase its\n\t * magic.\n\t */\n\tfdt_set_magic(fdt, ~0);\n\n\treturn ret;\n}\n"
  },
  {
    "path": "kernel/libs/libfdt/fdt_ro.c",
    "content": "/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2006 David Gibson, IBM Corporation.\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n#include <libfdt/libfdt_env.h>\n\n#include <libfdt/fdt.h>\n#include <libfdt/libfdt.h>\n\n#include \"libfdt_internal.h\"\n\nstatic int fdt_nodename_eq_(const void *fdt, int offset,\n\t\t\t    const char *s, int len)\n{\n\tint olen;\n\tconst char *p = fdt_get_name(fdt, offset, &olen);\n\n\tif (!p || olen < len)\n\t\t/* short match */\n\t\treturn 0;\n\n\tif (memcmp(p, s, len) != 0)\n\t\treturn 0;\n\n\tif (p[len] == '\\0')\n\t\treturn 1;\n\telse if (!memchr(s, '@', len) && (p[len] == '@'))\n\t\treturn 1;\n\telse\n\t\treturn 0;\n}\n\nconst char *fdt_get_string(const void *fdt, int stroffset, int *lenp)\n{\n\tuint32_t absoffset = stroffset + fdt_off_dt_strings(fdt);\n\tsize_t len;\n\tint err;\n\tconst char *s, *n;\n\n\terr = fdt_ro_probe_(fdt);\n\tif (err != 0)\n\t\tgoto fail;\n\n\terr = -FDT_ERR_BADOFFSET;\n\tif (absoffset >= fdt_totalsize(fdt))\n\t\tgoto fail;\n\tlen = fdt_totalsize(fdt) - absoffset;\n\n\tif (fdt_magic(fdt) == FDT_MAGIC) {\n\t\tif (stroffset < 0)\n\t\t\tgoto fail;\n\t\tif (fdt_version(fdt) >= 17) {\n\t\t\tif (stroffset >= fdt_size_dt_strings(fdt))\n\t\t\t\tgoto fail;\n\t\t\tif ((fdt_size_dt_strings(fdt) - stroffset) < len)\n\t\t\t\tlen = fdt_size_dt_strings(fdt) - stroffset;\n\t\t}\n\t} else if (fdt_magic(fdt) == FDT_SW_MAGIC) {\n\t\tif ((stroffset >= 0)\n\t\t    || (stroffset < -fdt_size_dt_strings(fdt)))\n\t\t\tgoto fail;\n\t\tif ((-stroffset) < len)\n\t\t\tlen = -stroffset;\n\t} else {\n\t\terr = -FDT_ERR_INTERNAL;\n\t\tgoto fail;\n\t}\n\n\ts = (const char *)fdt + absoffset;\n\tn = memchr(s, '\\0', len);\n\tif (!n) {\n\t\t/* missing terminating NULL */\n\t\terr = -FDT_ERR_TRUNCATED;\n\t\tgoto fail;\n\t}\n\n\tif (lenp)\n\t\t*lenp = n - s;\n\treturn s;\n\nfail:\n\tif (lenp)\n\t\t*lenp = err;\n\treturn NULL;\n}\n\nconst char *fdt_string(const void *fdt, int stroffset)\n{\n\treturn fdt_get_string(fdt, stroffset, NULL);\n}\n\nstatic int fdt_string_eq_(const void *fdt, int stroffset,\n\t\t\t  const char *s, int len)\n{\n\tint slen;\n\tconst char *p = fdt_get_string(fdt, stroffset, &slen);\n\n\treturn p && (slen == len) && (memcmp(p, s, len) == 0);\n}\n\nuint32_t fdt_get_max_phandle(const void *fdt)\n{\n\tuint32_t max_phandle = 0;\n\tint offset;\n\n\tfor (offset = fdt_next_node(fdt, -1, NULL);;\n\t     offset = fdt_next_node(fdt, offset, NULL)) {\n\t\tuint32_t phandle;\n\n\t\tif (offset == -FDT_ERR_NOTFOUND)\n\t\t\treturn max_phandle;\n\n\t\tif (offset < 0)\n\t\t\treturn (uint32_t)-1;\n\n\t\tphandle = fdt_get_phandle(fdt, offset);\n\t\tif (phandle == (uint32_t)-1)\n\t\t\tcontinue;\n\n\t\tif (phandle > max_phandle)\n\t\t\tmax_phandle = phandle;\n\t}\n\n\treturn 0;\n}\n\nstatic const struct fdt_reserve_entry *fdt_mem_rsv(const void *fdt, int n)\n{\n\tint offset = n * sizeof(struct fdt_reserve_entry);\n\tint absoffset = fdt_off_mem_rsvmap(fdt) + offset;\n\n\tif (absoffset < fdt_off_mem_rsvmap(fdt))\n\t\treturn NULL;\n\tif (absoffset > fdt_totalsize(fdt) - sizeof(struct fdt_reserve_entry))\n\t\treturn NULL;\n\treturn fdt_mem_rsv_(fdt, n);\n}\n\nint fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)\n{\n\tconst struct fdt_reserve_entry *re;\n\n\tFDT_RO_PROBE(fdt);\n\tre = fdt_mem_rsv(fdt, n);\n\tif (!re)\n\t\treturn -FDT_ERR_BADOFFSET;\n\n\t*address = fdt64_ld(&re->address);\n\t*size = fdt64_ld(&re->size);\n\treturn 0;\n}\n\nint fdt_num_mem_rsv(const void *fdt)\n{\n\tint i;\n\tconst struct fdt_reserve_entry *re;\n\n\tfor (i = 0; (re = fdt_mem_rsv(fdt, i)) != NULL; i++) {\n\t\tif (fdt64_ld(&re->size) == 0)\n\t\t\treturn i;\n\t}\n\treturn -FDT_ERR_TRUNCATED;\n}\n\nstatic int nextprop_(const void *fdt, int offset)\n{\n\tuint32_t tag;\n\tint nextoffset;\n\n\tdo {\n\t\ttag = fdt_next_tag(fdt, offset, &nextoffset);\n\n\t\tswitch (tag) {\n\t\tcase FDT_END:\n\t\t\tif (nextoffset >= 0)\n\t\t\t\treturn -FDT_ERR_BADSTRUCTURE;\n\t\t\telse\n\t\t\t\treturn nextoffset;\n\n\t\tcase FDT_PROP:\n\t\t\treturn offset;\n\t\t}\n\t\toffset = nextoffset;\n\t} while (tag == FDT_NOP);\n\n\treturn -FDT_ERR_NOTFOUND;\n}\n\nint fdt_subnode_offset_namelen(const void *fdt, int offset,\n\t\t\t       const char *name, int namelen)\n{\n\tint depth;\n\n\tFDT_RO_PROBE(fdt);\n\n\tfor (depth = 0;\n\t     (offset >= 0) && (depth >= 0);\n\t     offset = fdt_next_node(fdt, offset, &depth))\n\t\tif ((depth == 1)\n\t\t    && fdt_nodename_eq_(fdt, offset, name, namelen))\n\t\t\treturn offset;\n\n\tif (depth < 0)\n\t\treturn -FDT_ERR_NOTFOUND;\n\treturn offset; /* error */\n}\n\nint fdt_subnode_offset(const void *fdt, int parentoffset,\n\t\t       const char *name)\n{\n\treturn fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name));\n}\n\nint fdt_path_offset_namelen(const void *fdt, const char *path, int namelen)\n{\n\tconst char *end = path + namelen;\n\tconst char *p = path;\n\tint offset = 0;\n\n\tFDT_RO_PROBE(fdt);\n\n\t/* see if we have an alias */\n\tif (*path != '/') {\n\t\tconst char *q = memchr(path, '/', end - p);\n\n\t\tif (!q)\n\t\t\tq = end;\n\n\t\tp = fdt_get_alias_namelen(fdt, p, q - p);\n\t\tif (!p)\n\t\t\treturn -FDT_ERR_BADPATH;\n\t\toffset = fdt_path_offset(fdt, p);\n\n\t\tp = q;\n\t}\n\n\twhile (p < end) {\n\t\tconst char *q;\n\n\t\twhile (*p == '/') {\n\t\t\tp++;\n\t\t\tif (p == end)\n\t\t\t\treturn offset;\n\t\t}\n\t\tq = memchr(p, '/', end - p);\n\t\tif (! q)\n\t\t\tq = end;\n\n\t\toffset = fdt_subnode_offset_namelen(fdt, offset, p, q-p);\n\t\tif (offset < 0)\n\t\t\treturn offset;\n\n\t\tp = q;\n\t}\n\n\treturn offset;\n}\n\nint fdt_path_offset(const void *fdt, const char *path)\n{\n\treturn fdt_path_offset_namelen(fdt, path, strlen(path));\n}\n\nconst char *fdt_get_name(const void *fdt, int nodeoffset, int *len)\n{\n\tconst struct fdt_node_header *nh = fdt_offset_ptr_(fdt, nodeoffset);\n\tconst char *nameptr;\n\tint err;\n\n\tif (((err = fdt_ro_probe_(fdt)) != 0)\n\t    || ((err = fdt_check_node_offset_(fdt, nodeoffset)) < 0))\n\t\t\tgoto fail;\n\n\tnameptr = nh->name;\n\n\tif (fdt_version(fdt) < 0x10) {\n\t\t/*\n\t\t * For old FDT versions, match the naming conventions of V16:\n\t\t * give only the leaf name (after all /). The actual tree\n\t\t * contents are loosely checked.\n\t\t */\n\t\tconst char *leaf;\n\t\tleaf = strrchr(nameptr, '/');\n\t\tif (leaf == NULL) {\n\t\t\terr = -FDT_ERR_BADSTRUCTURE;\n\t\t\tgoto fail;\n\t\t}\n\t\tnameptr = leaf+1;\n\t}\n\n\tif (len)\n\t\t*len = strlen(nameptr);\n\n\treturn nameptr;\n\n fail:\n\tif (len)\n\t\t*len = err;\n\treturn NULL;\n}\n\nint fdt_first_property_offset(const void *fdt, int nodeoffset)\n{\n\tint offset;\n\n\tif ((offset = fdt_check_node_offset_(fdt, nodeoffset)) < 0)\n\t\treturn offset;\n\n\treturn nextprop_(fdt, offset);\n}\n\nint fdt_next_property_offset(const void *fdt, int offset)\n{\n\tif ((offset = fdt_check_prop_offset_(fdt, offset)) < 0)\n\t\treturn offset;\n\n\treturn nextprop_(fdt, offset);\n}\n\nstatic const struct fdt_property *fdt_get_property_by_offset_(const void *fdt,\n\t\t\t\t\t\t              int offset,\n\t\t\t\t\t\t              int *lenp)\n{\n\tint err;\n\tconst struct fdt_property *prop;\n\n\tif ((err = fdt_check_prop_offset_(fdt, offset)) < 0) {\n\t\tif (lenp)\n\t\t\t*lenp = err;\n\t\treturn NULL;\n\t}\n\n\tprop = fdt_offset_ptr_(fdt, offset);\n\n\tif (lenp)\n\t\t*lenp = fdt32_ld(&prop->len);\n\n\treturn prop;\n}\n\nconst struct fdt_property *fdt_get_property_by_offset(const void *fdt,\n\t\t\t\t\t\t      int offset,\n\t\t\t\t\t\t      int *lenp)\n{\n\t/* Prior to version 16, properties may need realignment\n\t * and this API does not work. fdt_getprop_*() will, however. */\n\n\tif (fdt_version(fdt) < 0x10) {\n\t\tif (lenp)\n\t\t\t*lenp = -FDT_ERR_BADVERSION;\n\t\treturn NULL;\n\t}\n\n\treturn fdt_get_property_by_offset_(fdt, offset, lenp);\n}\n\nstatic const struct fdt_property *fdt_get_property_namelen_(const void *fdt,\n\t\t\t\t\t\t            int offset,\n\t\t\t\t\t\t            const char *name,\n\t\t\t\t\t\t            int namelen,\n\t\t\t\t\t\t\t    int *lenp,\n\t\t\t\t\t\t\t    int *poffset)\n{\n\tfor (offset = fdt_first_property_offset(fdt, offset);\n\t     (offset >= 0);\n\t     (offset = fdt_next_property_offset(fdt, offset))) {\n\t\tconst struct fdt_property *prop;\n\n\t\tif (!(prop = fdt_get_property_by_offset_(fdt, offset, lenp))) {\n\t\t\toffset = -FDT_ERR_INTERNAL;\n\t\t\tbreak;\n\t\t}\n\t\tif (fdt_string_eq_(fdt, fdt32_ld(&prop->nameoff),\n\t\t\t\t   name, namelen)) {\n\t\t\tif (poffset)\n\t\t\t\t*poffset = offset;\n\t\t\treturn prop;\n\t\t}\n\t}\n\n\tif (lenp)\n\t\t*lenp = offset;\n\treturn NULL;\n}\n\n\nconst struct fdt_property *fdt_get_property_namelen(const void *fdt,\n\t\t\t\t\t\t    int offset,\n\t\t\t\t\t\t    const char *name,\n\t\t\t\t\t\t    int namelen, int *lenp)\n{\n\t/* Prior to version 16, properties may need realignment\n\t * and this API does not work. fdt_getprop_*() will, however. */\n\tif (fdt_version(fdt) < 0x10) {\n\t\tif (lenp)\n\t\t\t*lenp = -FDT_ERR_BADVERSION;\n\t\treturn NULL;\n\t}\n\n\treturn fdt_get_property_namelen_(fdt, offset, name, namelen, lenp,\n\t\t\t\t\t NULL);\n}\n\n\nconst struct fdt_property *fdt_get_property(const void *fdt,\n\t\t\t\t\t    int nodeoffset,\n\t\t\t\t\t    const char *name, int *lenp)\n{\n\treturn fdt_get_property_namelen(fdt, nodeoffset, name,\n\t\t\t\t\tstrlen(name), lenp);\n}\n\nconst void *fdt_getprop_namelen(const void *fdt, int nodeoffset,\n\t\t\t\tconst char *name, int namelen, int *lenp)\n{\n\tint poffset;\n\tconst struct fdt_property *prop;\n\n\tprop = fdt_get_property_namelen_(fdt, nodeoffset, name, namelen, lenp,\n\t\t\t\t\t &poffset);\n\tif (!prop)\n\t\treturn NULL;\n\n\t/* Handle realignment */\n\tif (fdt_version(fdt) < 0x10 && (poffset + sizeof(*prop)) % 8 &&\n\t    fdt32_ld(&prop->len) >= 8)\n\t\treturn prop->data + 4;\n\treturn prop->data;\n}\n\nconst void *fdt_getprop_by_offset(const void *fdt, int offset,\n\t\t\t\t  const char **namep, int *lenp)\n{\n\tconst struct fdt_property *prop;\n\n\tprop = fdt_get_property_by_offset_(fdt, offset, lenp);\n\tif (!prop)\n\t\treturn NULL;\n\tif (namep) {\n\t\tconst char *name;\n\t\tint namelen;\n\t\tname = fdt_get_string(fdt, fdt32_ld(&prop->nameoff),\n\t\t\t\t      &namelen);\n\t\tif (!name) {\n\t\t\tif (lenp)\n\t\t\t\t*lenp = namelen;\n\t\t\treturn NULL;\n\t\t}\n\t\t*namep = name;\n\t}\n\n\t/* Handle realignment */\n\tif (fdt_version(fdt) < 0x10 && (offset + sizeof(*prop)) % 8 &&\n\t    fdt32_ld(&prop->len) >= 8)\n\t\treturn prop->data + 4;\n\treturn prop->data;\n}\n\nconst void *fdt_getprop(const void *fdt, int nodeoffset,\n\t\t\tconst char *name, int *lenp)\n{\n\treturn fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), lenp);\n}\n\nuint32_t fdt_get_phandle(const void *fdt, int nodeoffset)\n{\n\tconst fdt32_t *php;\n\tint len;\n\n\t/* FIXME: This is a bit sub-optimal, since we potentially scan\n\t * over all the properties twice. */\n\tphp = fdt_getprop(fdt, nodeoffset, \"phandle\", &len);\n\tif (!php || (len != sizeof(*php))) {\n\t\tphp = fdt_getprop(fdt, nodeoffset, \"linux,phandle\", &len);\n\t\tif (!php || (len != sizeof(*php)))\n\t\t\treturn 0;\n\t}\n\n\treturn fdt32_ld(php);\n}\n\nconst char *fdt_get_alias_namelen(const void *fdt,\n\t\t\t\t  const char *name, int namelen)\n{\n\tint aliasoffset;\n\n\taliasoffset = fdt_path_offset(fdt, \"/aliases\");\n\tif (aliasoffset < 0)\n\t\treturn NULL;\n\n\treturn fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL);\n}\n\nconst char *fdt_get_alias(const void *fdt, const char *name)\n{\n\treturn fdt_get_alias_namelen(fdt, name, strlen(name));\n}\n\nint fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)\n{\n\tint pdepth = 0, p = 0;\n\tint offset, depth, namelen;\n\tconst char *name;\n\n\tFDT_RO_PROBE(fdt);\n\n\tif (buflen < 2)\n\t\treturn -FDT_ERR_NOSPACE;\n\n\tfor (offset = 0, depth = 0;\n\t     (offset >= 0) && (offset <= nodeoffset);\n\t     offset = fdt_next_node(fdt, offset, &depth)) {\n\t\twhile (pdepth > depth) {\n\t\t\tdo {\n\t\t\t\tp--;\n\t\t\t} while (buf[p-1] != '/');\n\t\t\tpdepth--;\n\t\t}\n\n\t\tif (pdepth >= depth) {\n\t\t\tname = fdt_get_name(fdt, offset, &namelen);\n\t\t\tif (!name)\n\t\t\t\treturn namelen;\n\t\t\tif ((p + namelen + 1) <= buflen) {\n\t\t\t\tmemcpy(buf + p, name, namelen);\n\t\t\t\tp += namelen;\n\t\t\t\tbuf[p++] = '/';\n\t\t\t\tpdepth++;\n\t\t\t}\n\t\t}\n\n\t\tif (offset == nodeoffset) {\n\t\t\tif (pdepth < (depth + 1))\n\t\t\t\treturn -FDT_ERR_NOSPACE;\n\n\t\t\tif (p > 1) /* special case so that root path is \"/\", not \"\" */\n\t\t\t\tp--;\n\t\t\tbuf[p] = '\\0';\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\tif ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))\n\t\treturn -FDT_ERR_BADOFFSET;\n\telse if (offset == -FDT_ERR_BADOFFSET)\n\t\treturn -FDT_ERR_BADSTRUCTURE;\n\n\treturn offset; /* error from fdt_next_node() */\n}\n\nint fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,\n\t\t\t\t int supernodedepth, int *nodedepth)\n{\n\tint offset, depth;\n\tint supernodeoffset = -FDT_ERR_INTERNAL;\n\n\tFDT_RO_PROBE(fdt);\n\n\tif (supernodedepth < 0)\n\t\treturn -FDT_ERR_NOTFOUND;\n\n\tfor (offset = 0, depth = 0;\n\t     (offset >= 0) && (offset <= nodeoffset);\n\t     offset = fdt_next_node(fdt, offset, &depth)) {\n\t\tif (depth == supernodedepth)\n\t\t\tsupernodeoffset = offset;\n\n\t\tif (offset == nodeoffset) {\n\t\t\tif (nodedepth)\n\t\t\t\t*nodedepth = depth;\n\n\t\t\tif (supernodedepth > depth)\n\t\t\t\treturn -FDT_ERR_NOTFOUND;\n\t\t\telse\n\t\t\t\treturn supernodeoffset;\n\t\t}\n\t}\n\n\tif ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))\n\t\treturn -FDT_ERR_BADOFFSET;\n\telse if (offset == -FDT_ERR_BADOFFSET)\n\t\treturn -FDT_ERR_BADSTRUCTURE;\n\n\treturn offset; /* error from fdt_next_node() */\n}\n\nint fdt_node_depth(const void *fdt, int nodeoffset)\n{\n\tint nodedepth;\n\tint err;\n\n\terr = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);\n\tif (err)\n\t\treturn (err < 0) ? err : -FDT_ERR_INTERNAL;\n\treturn nodedepth;\n}\n\nint fdt_parent_offset(const void *fdt, int nodeoffset)\n{\n\tint nodedepth = fdt_node_depth(fdt, nodeoffset);\n\n\tif (nodedepth < 0)\n\t\treturn nodedepth;\n\treturn fdt_supernode_atdepth_offset(fdt, nodeoffset,\n\t\t\t\t\t    nodedepth - 1, NULL);\n}\n\nint fdt_node_offset_by_prop_value(const void *fdt, int startoffset,\n\t\t\t\t  const char *propname,\n\t\t\t\t  const void *propval, int proplen)\n{\n\tint offset;\n\tconst void *val;\n\tint len;\n\n\tFDT_RO_PROBE(fdt);\n\n\t/* FIXME: The algorithm here is pretty horrible: we scan each\n\t * property of a node in fdt_getprop(), then if that didn't\n\t * find what we want, we scan over them again making our way\n\t * to the next node.  Still it's the easiest to implement\n\t * approach; performance can come later. */\n\tfor (offset = fdt_next_node(fdt, startoffset, NULL);\n\t     offset >= 0;\n\t     offset = fdt_next_node(fdt, offset, NULL)) {\n\t\tval = fdt_getprop(fdt, offset, propname, &len);\n\t\tif (val && (len == proplen)\n\t\t    && (memcmp(val, propval, len) == 0))\n\t\t\treturn offset;\n\t}\n\n\treturn offset; /* error from fdt_next_node() */\n}\n\nint fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)\n{\n\tint offset;\n\n\tif ((phandle == 0) || (phandle == -1))\n\t\treturn -FDT_ERR_BADPHANDLE;\n\n\tFDT_RO_PROBE(fdt);\n\n\t/* FIXME: The algorithm here is pretty horrible: we\n\t * potentially scan each property of a node in\n\t * fdt_get_phandle(), then if that didn't find what\n\t * we want, we scan over them again making our way to the next\n\t * node.  Still it's the easiest to implement approach;\n\t * performance can come later. */\n\tfor (offset = fdt_next_node(fdt, -1, NULL);\n\t     offset >= 0;\n\t     offset = fdt_next_node(fdt, offset, NULL)) {\n\t\tif (fdt_get_phandle(fdt, offset) == phandle)\n\t\t\treturn offset;\n\t}\n\n\treturn offset; /* error from fdt_next_node() */\n}\n\nint fdt_stringlist_contains(const char *strlist, int listlen, const char *str)\n{\n\tint len = strlen(str);\n\tconst char *p;\n\n\twhile (listlen >= len) {\n\t\tif (memcmp(str, strlist, len+1) == 0)\n\t\t\treturn 1;\n\t\tp = memchr(strlist, '\\0', listlen);\n\t\tif (!p)\n\t\t\treturn 0; /* malformed strlist.. */\n\t\tlistlen -= (p-strlist) + 1;\n\t\tstrlist = p + 1;\n\t}\n\treturn 0;\n}\n\nint fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property)\n{\n\tconst char *list, *end;\n\tint length, count = 0;\n\n\tlist = fdt_getprop(fdt, nodeoffset, property, &length);\n\tif (!list)\n\t\treturn length;\n\n\tend = list + length;\n\n\twhile (list < end) {\n\t\tlength = strnlen(list, end - list) + 1;\n\n\t\t/* Abort if the last string isn't properly NUL-terminated. */\n\t\tif (list + length > end)\n\t\t\treturn -FDT_ERR_BADVALUE;\n\n\t\tlist += length;\n\t\tcount++;\n\t}\n\n\treturn count;\n}\n\nint fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property,\n\t\t\t  const char *string)\n{\n\tint length, len, idx = 0;\n\tconst char *list, *end;\n\n\tlist = fdt_getprop(fdt, nodeoffset, property, &length);\n\tif (!list)\n\t\treturn length;\n\n\tlen = strlen(string) + 1;\n\tend = list + length;\n\n\twhile (list < end) {\n\t\tlength = strnlen(list, end - list) + 1;\n\n\t\t/* Abort if the last string isn't properly NUL-terminated. */\n\t\tif (list + length > end)\n\t\t\treturn -FDT_ERR_BADVALUE;\n\n\t\tif (length == len && memcmp(list, string, length) == 0)\n\t\t\treturn idx;\n\n\t\tlist += length;\n\t\tidx++;\n\t}\n\n\treturn -FDT_ERR_NOTFOUND;\n}\n\nconst char *fdt_stringlist_get(const void *fdt, int nodeoffset,\n\t\t\t       const char *property, int idx,\n\t\t\t       int *lenp)\n{\n\tconst char *list, *end;\n\tint length;\n\n\tlist = fdt_getprop(fdt, nodeoffset, property, &length);\n\tif (!list) {\n\t\tif (lenp)\n\t\t\t*lenp = length;\n\n\t\treturn NULL;\n\t}\n\n\tend = list + length;\n\n\twhile (list < end) {\n\t\tlength = strnlen(list, end - list) + 1;\n\n\t\t/* Abort if the last string isn't properly NUL-terminated. */\n\t\tif (list + length > end) {\n\t\t\tif (lenp)\n\t\t\t\t*lenp = -FDT_ERR_BADVALUE;\n\n\t\t\treturn NULL;\n\t\t}\n\n\t\tif (idx == 0) {\n\t\t\tif (lenp)\n\t\t\t\t*lenp = length - 1;\n\n\t\t\treturn list;\n\t\t}\n\n\t\tlist += length;\n\t\tidx--;\n\t}\n\n\tif (lenp)\n\t\t*lenp = -FDT_ERR_NOTFOUND;\n\n\treturn NULL;\n}\n\nint fdt_node_check_compatible(const void *fdt, int nodeoffset,\n\t\t\t      const char *compatible)\n{\n\tconst void *prop;\n\tint len;\n\n\tprop = fdt_getprop(fdt, nodeoffset, \"compatible\", &len);\n\tif (!prop)\n\t\treturn len;\n\n\treturn !fdt_stringlist_contains(prop, len, compatible);\n}\n\nint fdt_node_offset_by_compatible(const void *fdt, int startoffset,\n\t\t\t\t  const char *compatible)\n{\n\tint offset, err;\n\n\tFDT_RO_PROBE(fdt);\n\n\t/* FIXME: The algorithm here is pretty horrible: we scan each\n\t * property of a node in fdt_node_check_compatible(), then if\n\t * that didn't find what we want, we scan over them again\n\t * making our way to the next node.  Still it's the easiest to\n\t * implement approach; performance can come later. */\n\tfor (offset = fdt_next_node(fdt, startoffset, NULL);\n\t     offset >= 0;\n\t     offset = fdt_next_node(fdt, offset, NULL)) {\n\t\terr = fdt_node_check_compatible(fdt, offset, compatible);\n\t\tif ((err < 0) && (err != -FDT_ERR_NOTFOUND))\n\t\t\treturn err;\n\t\telse if (err == 0)\n\t\t\treturn offset;\n\t}\n\n\treturn offset; /* error from fdt_next_node() */\n}\n\nint fdt_check_full(const void *fdt, size_t bufsize)\n{\n\tint err;\n\tint num_memrsv;\n\tint offset, nextoffset = 0;\n\tuint32_t tag;\n\tunsigned depth = 0;\n\tconst void *prop;\n\tconst char *propname;\n\n\tif (bufsize < FDT_V1_SIZE)\n\t\treturn -FDT_ERR_TRUNCATED;\n\terr = fdt_check_header(fdt);\n\tif (err != 0)\n\t\treturn err;\n\tif (bufsize < fdt_totalsize(fdt))\n\t\treturn -FDT_ERR_TRUNCATED;\n\n\tnum_memrsv = fdt_num_mem_rsv(fdt);\n\tif (num_memrsv < 0)\n\t\treturn num_memrsv;\n\n\twhile (1) {\n\t\toffset = nextoffset;\n\t\ttag = fdt_next_tag(fdt, offset, &nextoffset);\n\n\t\tif (nextoffset < 0)\n\t\t\treturn nextoffset;\n\n\t\tswitch (tag) {\n\t\tcase FDT_NOP:\n\t\t\tbreak;\n\n\t\tcase FDT_END:\n\t\t\tif (depth != 0)\n\t\t\t\treturn -FDT_ERR_BADSTRUCTURE;\n\t\t\treturn 0;\n\n\t\tcase FDT_BEGIN_NODE:\n\t\t\tdepth++;\n\t\t\tif (depth > INT_MAX)\n\t\t\t\treturn -FDT_ERR_BADSTRUCTURE;\n\t\t\tbreak;\n\n\t\tcase FDT_END_NODE:\n\t\t\tif (depth == 0)\n\t\t\t\treturn -FDT_ERR_BADSTRUCTURE;\n\t\t\tdepth--;\n\t\t\tbreak;\n\n\t\tcase FDT_PROP:\n\t\t\tprop = fdt_getprop_by_offset(fdt, offset, &propname,\n\t\t\t\t\t\t     &err);\n\t\t\tif (!prop)\n\t\t\t\treturn err;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\treturn -FDT_ERR_INTERNAL;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "kernel/libs/libfdt/fdt_rw.c",
    "content": "/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2006 David Gibson, IBM Corporation.\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n#include <libfdt/libfdt_env.h>\n\n#include <libfdt/fdt.h>\n#include <libfdt/libfdt.h>\n\n#include \"libfdt_internal.h\"\n\nstatic int fdt_blocks_misordered_(const void *fdt,\n\t\t\t\t  int mem_rsv_size, int struct_size)\n{\n\treturn (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8))\n\t\t|| (fdt_off_dt_struct(fdt) <\n\t\t    (fdt_off_mem_rsvmap(fdt) + mem_rsv_size))\n\t\t|| (fdt_off_dt_strings(fdt) <\n\t\t    (fdt_off_dt_struct(fdt) + struct_size))\n\t\t|| (fdt_totalsize(fdt) <\n\t\t    (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));\n}\n\nstatic int fdt_rw_probe_(void *fdt)\n{\n\tFDT_RO_PROBE(fdt);\n\n\tif (fdt_version(fdt) < 17)\n\t\treturn -FDT_ERR_BADVERSION;\n\tif (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry),\n\t\t\t\t   fdt_size_dt_struct(fdt)))\n\t\treturn -FDT_ERR_BADLAYOUT;\n\tif (fdt_version(fdt) > 17)\n\t\tfdt_set_version(fdt, 17);\n\n\treturn 0;\n}\n\n#define FDT_RW_PROBE(fdt) \\\n\t{ \\\n\t\tint err_; \\\n\t\tif ((err_ = fdt_rw_probe_(fdt)) != 0) \\\n\t\t\treturn err_; \\\n\t}\n\nstatic inline int fdt_data_size_(void *fdt)\n{\n\treturn fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);\n}\n\nstatic int fdt_splice_(void *fdt, void *splicepoint, int oldlen, int newlen)\n{\n\tchar *p = splicepoint;\n\tchar *end = (char *)fdt + fdt_data_size_(fdt);\n\n\tif (((p + oldlen) < p) || ((p + oldlen) > end))\n\t\treturn -FDT_ERR_BADOFFSET;\n\tif ((p < (char *)fdt) || ((end - oldlen + newlen) < (char *)fdt))\n\t\treturn -FDT_ERR_BADOFFSET;\n\tif ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt)))\n\t\treturn -FDT_ERR_NOSPACE;\n\tmemmove(p + newlen, p + oldlen, end - p - oldlen);\n\treturn 0;\n}\n\nstatic int fdt_splice_mem_rsv_(void *fdt, struct fdt_reserve_entry *p,\n\t\t\t       int oldn, int newn)\n{\n\tint delta = (newn - oldn) * sizeof(*p);\n\tint err;\n\terr = fdt_splice_(fdt, p, oldn * sizeof(*p), newn * sizeof(*p));\n\tif (err)\n\t\treturn err;\n\tfdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta);\n\tfdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);\n\treturn 0;\n}\n\nstatic int fdt_splice_struct_(void *fdt, void *p,\n\t\t\t      int oldlen, int newlen)\n{\n\tint delta = newlen - oldlen;\n\tint err;\n\n\tif ((err = fdt_splice_(fdt, p, oldlen, newlen)))\n\t\treturn err;\n\n\tfdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta);\n\tfdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);\n\treturn 0;\n}\n\nstatic int fdt_splice_string_(void *fdt, int newlen)\n{\n\tvoid *p = (char *)fdt\n\t\t+ fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);\n\tint err;\n\n\tif ((err = fdt_splice_(fdt, p, 0, newlen)))\n\t\treturn err;\n\n\tfdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen);\n\treturn 0;\n}\n\nstatic int fdt_find_add_string_(void *fdt, const char *s)\n{\n\tchar *strtab = (char *)fdt + fdt_off_dt_strings(fdt);\n\tconst char *p;\n\tchar *new;\n\tint len = strlen(s) + 1;\n\tint err;\n\n\tp = fdt_find_string_(strtab, fdt_size_dt_strings(fdt), s);\n\tif (p)\n\t\t/* found it */\n\t\treturn (p - strtab);\n\n\tnew = strtab + fdt_size_dt_strings(fdt);\n\terr = fdt_splice_string_(fdt, len);\n\tif (err)\n\t\treturn err;\n\n\tmemcpy(new, s, len);\n\treturn (new - strtab);\n}\n\nint fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)\n{\n\tstruct fdt_reserve_entry *re;\n\tint err;\n\n\tFDT_RW_PROBE(fdt);\n\n\tre = fdt_mem_rsv_w_(fdt, fdt_num_mem_rsv(fdt));\n\terr = fdt_splice_mem_rsv_(fdt, re, 0, 1);\n\tif (err)\n\t\treturn err;\n\n\tre->address = cpu_to_fdt64(address);\n\tre->size = cpu_to_fdt64(size);\n\treturn 0;\n}\n\nint fdt_del_mem_rsv(void *fdt, int n)\n{\n\tstruct fdt_reserve_entry *re = fdt_mem_rsv_w_(fdt, n);\n\n\tFDT_RW_PROBE(fdt);\n\n\tif (n >= fdt_num_mem_rsv(fdt))\n\t\treturn -FDT_ERR_NOTFOUND;\n\n\treturn fdt_splice_mem_rsv_(fdt, re, 1, 0);\n}\n\nstatic int fdt_resize_property_(void *fdt, int nodeoffset, const char *name,\n\t\t\t\tint len, struct fdt_property **prop)\n{\n\tint oldlen;\n\tint err;\n\n\t*prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);\n\tif (!*prop)\n\t\treturn oldlen;\n\n\tif ((err = fdt_splice_struct_(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),\n\t\t\t\t      FDT_TAGALIGN(len))))\n\t\treturn err;\n\n\t(*prop)->len = cpu_to_fdt32(len);\n\treturn 0;\n}\n\nstatic int fdt_add_property_(void *fdt, int nodeoffset, const char *name,\n\t\t\t     int len, struct fdt_property **prop)\n{\n\tint proplen;\n\tint nextoffset;\n\tint namestroff;\n\tint err;\n\n\tif ((nextoffset = fdt_check_node_offset_(fdt, nodeoffset)) < 0)\n\t\treturn nextoffset;\n\n\tnamestroff = fdt_find_add_string_(fdt, name);\n\tif (namestroff < 0)\n\t\treturn namestroff;\n\n\t*prop = fdt_offset_ptr_w_(fdt, nextoffset);\n\tproplen = sizeof(**prop) + FDT_TAGALIGN(len);\n\n\terr = fdt_splice_struct_(fdt, *prop, 0, proplen);\n\tif (err)\n\t\treturn err;\n\n\t(*prop)->tag = cpu_to_fdt32(FDT_PROP);\n\t(*prop)->nameoff = cpu_to_fdt32(namestroff);\n\t(*prop)->len = cpu_to_fdt32(len);\n\treturn 0;\n}\n\nint fdt_set_name(void *fdt, int nodeoffset, const char *name)\n{\n\tchar *namep;\n\tint oldlen, newlen;\n\tint err;\n\n\tFDT_RW_PROBE(fdt);\n\n\tnamep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen);\n\tif (!namep)\n\t\treturn oldlen;\n\n\tnewlen = strlen(name);\n\n\terr = fdt_splice_struct_(fdt, namep, FDT_TAGALIGN(oldlen+1),\n\t\t\t\t FDT_TAGALIGN(newlen+1));\n\tif (err)\n\t\treturn err;\n\n\tmemcpy(namep, name, newlen+1);\n\treturn 0;\n}\n\nint fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,\n\t\t\t    int len, void **prop_data)\n{\n\tstruct fdt_property *prop;\n\tint err;\n\n\tFDT_RW_PROBE(fdt);\n\n\terr = fdt_resize_property_(fdt, nodeoffset, name, len, &prop);\n\tif (err == -FDT_ERR_NOTFOUND)\n\t\terr = fdt_add_property_(fdt, nodeoffset, name, len, &prop);\n\tif (err)\n\t\treturn err;\n\n\t*prop_data = prop->data;\n\treturn 0;\n}\n\nint fdt_setprop(void *fdt, int nodeoffset, const char *name,\n\t\tconst void *val, int len)\n{\n\tvoid *prop_data;\n\tint err;\n\n\terr = fdt_setprop_placeholder(fdt, nodeoffset, name, len, &prop_data);\n\tif (err)\n\t\treturn err;\n\n\tif (len)\n\t\tmemcpy(prop_data, val, len);\n\treturn 0;\n}\n\nint fdt_appendprop(void *fdt, int nodeoffset, const char *name,\n\t\t   const void *val, int len)\n{\n\tstruct fdt_property *prop;\n\tint err, oldlen, newlen;\n\n\tFDT_RW_PROBE(fdt);\n\n\tprop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);\n\tif (prop) {\n\t\tnewlen = len + oldlen;\n\t\terr = fdt_splice_struct_(fdt, prop->data,\n\t\t\t\t\t FDT_TAGALIGN(oldlen),\n\t\t\t\t\t FDT_TAGALIGN(newlen));\n\t\tif (err)\n\t\t\treturn err;\n\t\tprop->len = cpu_to_fdt32(newlen);\n\t\tmemcpy(prop->data + oldlen, val, len);\n\t} else {\n\t\terr = fdt_add_property_(fdt, nodeoffset, name, len, &prop);\n\t\tif (err)\n\t\t\treturn err;\n\t\tmemcpy(prop->data, val, len);\n\t}\n\treturn 0;\n}\n\nint fdt_delprop(void *fdt, int nodeoffset, const char *name)\n{\n\tstruct fdt_property *prop;\n\tint len, proplen;\n\n\tFDT_RW_PROBE(fdt);\n\n\tprop = fdt_get_property_w(fdt, nodeoffset, name, &len);\n\tif (!prop)\n\t\treturn len;\n\n\tproplen = sizeof(*prop) + FDT_TAGALIGN(len);\n\treturn fdt_splice_struct_(fdt, prop, proplen, 0);\n}\n\nint fdt_add_subnode_namelen(void *fdt, int parentoffset,\n\t\t\t    const char *name, int namelen)\n{\n\tstruct fdt_node_header *nh;\n\tint offset, nextoffset;\n\tint nodelen;\n\tint err;\n\tuint32_t tag;\n\tfdt32_t *endtag;\n\n\tFDT_RW_PROBE(fdt);\n\n\toffset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);\n\tif (offset >= 0)\n\t\treturn -FDT_ERR_EXISTS;\n\telse if (offset != -FDT_ERR_NOTFOUND)\n\t\treturn offset;\n\n\t/* Try to place the new node after the parent's properties */\n\tfdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */\n\tdo {\n\t\toffset = nextoffset;\n\t\ttag = fdt_next_tag(fdt, offset, &nextoffset);\n\t} while ((tag == FDT_PROP) || (tag == FDT_NOP));\n\n\tnh = fdt_offset_ptr_w_(fdt, offset);\n\tnodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE;\n\n\terr = fdt_splice_struct_(fdt, nh, 0, nodelen);\n\tif (err)\n\t\treturn err;\n\n\tnh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);\n\tmemset(nh->name, 0, FDT_TAGALIGN(namelen+1));\n\tmemcpy(nh->name, name, namelen);\n\tendtag = (fdt32_t *)((char *)nh + nodelen - FDT_TAGSIZE);\n\t*endtag = cpu_to_fdt32(FDT_END_NODE);\n\n\treturn offset;\n}\n\nint fdt_add_subnode(void *fdt, int parentoffset, const char *name)\n{\n\treturn fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name));\n}\n\nint fdt_del_node(void *fdt, int nodeoffset)\n{\n\tint endoffset;\n\n\tFDT_RW_PROBE(fdt);\n\n\tendoffset = fdt_node_end_offset_(fdt, nodeoffset);\n\tif (endoffset < 0)\n\t\treturn endoffset;\n\n\treturn fdt_splice_struct_(fdt, fdt_offset_ptr_w_(fdt, nodeoffset),\n\t\t\t\t  endoffset - nodeoffset, 0);\n}\n\nstatic void fdt_packblocks_(const char *old, char *new,\n\t\t\t    int mem_rsv_size, int struct_size)\n{\n\tint mem_rsv_off, struct_off, strings_off;\n\n\tmem_rsv_off = FDT_ALIGN(sizeof(struct fdt_header), 8);\n\tstruct_off = mem_rsv_off + mem_rsv_size;\n\tstrings_off = struct_off + struct_size;\n\n\tmemmove(new + mem_rsv_off, old + fdt_off_mem_rsvmap(old), mem_rsv_size);\n\tfdt_set_off_mem_rsvmap(new, mem_rsv_off);\n\n\tmemmove(new + struct_off, old + fdt_off_dt_struct(old), struct_size);\n\tfdt_set_off_dt_struct(new, struct_off);\n\tfdt_set_size_dt_struct(new, struct_size);\n\n\tmemmove(new + strings_off, old + fdt_off_dt_strings(old),\n\t\tfdt_size_dt_strings(old));\n\tfdt_set_off_dt_strings(new, strings_off);\n\tfdt_set_size_dt_strings(new, fdt_size_dt_strings(old));\n}\n\nint fdt_open_into(const void *fdt, void *buf, int bufsize)\n{\n\tint err;\n\tint mem_rsv_size, struct_size;\n\tint newsize;\n\tconst char *fdtstart = fdt;\n\tconst char *fdtend = fdtstart + fdt_totalsize(fdt);\n\tchar *tmp;\n\n\tFDT_RO_PROBE(fdt);\n\n\tmem_rsv_size = (fdt_num_mem_rsv(fdt)+1)\n\t\t* sizeof(struct fdt_reserve_entry);\n\n\tif (fdt_version(fdt) >= 17) {\n\t\tstruct_size = fdt_size_dt_struct(fdt);\n\t} else {\n\t\tstruct_size = 0;\n\t\twhile (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)\n\t\t\t;\n\t\tif (struct_size < 0)\n\t\t\treturn struct_size;\n\t}\n\n\tif (!fdt_blocks_misordered_(fdt, mem_rsv_size, struct_size)) {\n\t\t/* no further work necessary */\n\t\terr = fdt_move(fdt, buf, bufsize);\n\t\tif (err)\n\t\t\treturn err;\n\t\tfdt_set_version(buf, 17);\n\t\tfdt_set_size_dt_struct(buf, struct_size);\n\t\tfdt_set_totalsize(buf, bufsize);\n\t\treturn 0;\n\t}\n\n\t/* Need to reorder */\n\tnewsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size\n\t\t+ struct_size + fdt_size_dt_strings(fdt);\n\n\tif (bufsize < newsize)\n\t\treturn -FDT_ERR_NOSPACE;\n\n\t/* First attempt to build converted tree at beginning of buffer */\n\ttmp = buf;\n\t/* But if that overlaps with the old tree... */\n\tif (((tmp + newsize) > fdtstart) && (tmp < fdtend)) {\n\t\t/* Try right after the old tree instead */\n\t\ttmp = (char *)(uintptr_t)fdtend;\n\t\tif ((tmp + newsize) > ((char *)buf + bufsize))\n\t\t\treturn -FDT_ERR_NOSPACE;\n\t}\n\n\tfdt_packblocks_(fdt, tmp, mem_rsv_size, struct_size);\n\tmemmove(buf, tmp, newsize);\n\n\tfdt_set_magic(buf, FDT_MAGIC);\n\tfdt_set_totalsize(buf, bufsize);\n\tfdt_set_version(buf, 17);\n\tfdt_set_last_comp_version(buf, 16);\n\tfdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt));\n\n\treturn 0;\n}\n\nint fdt_pack(void *fdt)\n{\n\tint mem_rsv_size;\n\n\tFDT_RW_PROBE(fdt);\n\n\tmem_rsv_size = (fdt_num_mem_rsv(fdt)+1)\n\t\t* sizeof(struct fdt_reserve_entry);\n\tfdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));\n\tfdt_set_totalsize(fdt, fdt_data_size_(fdt));\n\n\treturn 0;\n}\n\nint fdt_set_node_reg(void *dtb, int node,\n\t\tunsigned long iomem, size_t iomem_size)\n{\n\tuint32_t tmp[4];\n\tuint32_t *args = tmp;\n\tint size = 0, size_cells, addr_cells;\n\n\tsize_cells = fdt_size_cells(dtb, 0);\n\taddr_cells = fdt_address_cells(dtb, 0);\n\n\tif (addr_cells == 1) {\n\t\t*args++ = cpu_to_fdt32(iomem);\n\t\tsize++;\n\t} else {\n\t\t*args++ = cpu_to_fdt32(iomem >> 32);\n\t\t*args++ = cpu_to_fdt32(iomem & 0xffffffff);\n\t\tsize += 2;\n\t}\n\n\tif (size_cells == 1) {\n\t\t*args++ = cpu_to_fdt32(iomem_size);\n\t\tsize++;\n\t} else {\n\t\t*args++ = cpu_to_fdt32(iomem_size >> 32);\n\t\t*args++ = cpu_to_fdt32(iomem_size & 0xffffffff);\n\t\tsize += 2;\n\t}\n\n\tfdt_setprop(dtb, node, \"reg\", (void *)tmp, size * 4);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "kernel/libs/libfdt/fdt_strerror.c",
    "content": "/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2006 David Gibson, IBM Corporation.\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n#include <libfdt/libfdt_env.h>\n\n#include <libfdt/fdt.h>\n#include <libfdt/libfdt.h>\n\n#include \"libfdt_internal.h\"\n\nstruct fdt_errtabent {\n\tconst char *str;\n};\n\n#define FDT_ERRTABENT(val) \\\n\t[(val)] = { .str = #val, }\n\nstatic struct fdt_errtabent fdt_errtable[] = {\n\tFDT_ERRTABENT(FDT_ERR_NOTFOUND),\n\tFDT_ERRTABENT(FDT_ERR_EXISTS),\n\tFDT_ERRTABENT(FDT_ERR_NOSPACE),\n\n\tFDT_ERRTABENT(FDT_ERR_BADOFFSET),\n\tFDT_ERRTABENT(FDT_ERR_BADPATH),\n\tFDT_ERRTABENT(FDT_ERR_BADPHANDLE),\n\tFDT_ERRTABENT(FDT_ERR_BADSTATE),\n\n\tFDT_ERRTABENT(FDT_ERR_TRUNCATED),\n\tFDT_ERRTABENT(FDT_ERR_BADMAGIC),\n\tFDT_ERRTABENT(FDT_ERR_BADVERSION),\n\tFDT_ERRTABENT(FDT_ERR_BADSTRUCTURE),\n\tFDT_ERRTABENT(FDT_ERR_BADLAYOUT),\n\tFDT_ERRTABENT(FDT_ERR_INTERNAL),\n\tFDT_ERRTABENT(FDT_ERR_BADNCELLS),\n\tFDT_ERRTABENT(FDT_ERR_BADVALUE),\n\tFDT_ERRTABENT(FDT_ERR_BADOVERLAY),\n\tFDT_ERRTABENT(FDT_ERR_NOPHANDLES),\n};\n#define FDT_ERRTABSIZE\t(sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))\n\nconst char *fdt_strerror(int errval)\n{\n\tif (errval > 0)\n\t\treturn \"<valid offset/length>\";\n\telse if (errval == 0)\n\t\treturn \"<no error>\";\n\telse if (errval > -FDT_ERRTABSIZE) {\n\t\tconst char *s = fdt_errtable[-errval].str;\n\n\t\tif (s)\n\t\t\treturn s;\n\t}\n\n\treturn \"<unknown error>\";\n}\n"
  },
  {
    "path": "kernel/libs/libfdt/fdt_sw.c",
    "content": "/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2006 David Gibson, IBM Corporation.\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n#include <libfdt/libfdt_env.h>\n\n#include <libfdt/fdt.h>\n#include <libfdt/libfdt.h>\n\n#include \"libfdt_internal.h\"\n\nstatic int fdt_sw_probe_(void *fdt)\n{\n\tif (fdt_magic(fdt) == FDT_MAGIC)\n\t\treturn -FDT_ERR_BADSTATE;\n\telse if (fdt_magic(fdt) != FDT_SW_MAGIC)\n\t\treturn -FDT_ERR_BADMAGIC;\n\treturn 0;\n}\n\n#define FDT_SW_PROBE(fdt) \\\n\t{ \\\n\t\tint err; \\\n\t\tif ((err = fdt_sw_probe_(fdt)) != 0) \\\n\t\t\treturn err; \\\n\t}\n\n/* 'memrsv' state:\tInitial state after fdt_create()\n *\n * Allowed functions:\n *\tfdt_add_reservmap_entry()\n *\tfdt_finish_reservemap()\t\t[moves to 'struct' state]\n */\nstatic int fdt_sw_probe_memrsv_(void *fdt)\n{\n\tint err = fdt_sw_probe_(fdt);\n\tif (err)\n\t\treturn err;\n\n\tif (fdt_off_dt_strings(fdt) != 0)\n\t\treturn -FDT_ERR_BADSTATE;\n\treturn 0;\n}\n\n#define FDT_SW_PROBE_MEMRSV(fdt) \\\n\t{ \\\n\t\tint err; \\\n\t\tif ((err = fdt_sw_probe_memrsv_(fdt)) != 0) \\\n\t\t\treturn err; \\\n\t}\n\n/* 'struct' state:\tEnter this state after fdt_finish_reservemap()\n *\n * Allowed functions:\n *\tfdt_begin_node()\n *\tfdt_end_node()\n *\tfdt_property*()\n *\tfdt_finish()\t\t\t[moves to 'complete' state]\n */\nstatic int fdt_sw_probe_struct_(void *fdt)\n{\n\tint err = fdt_sw_probe_(fdt);\n\tif (err)\n\t\treturn err;\n\n\tif (fdt_off_dt_strings(fdt) != fdt_totalsize(fdt))\n\t\treturn -FDT_ERR_BADSTATE;\n\treturn 0;\n}\n\n#define FDT_SW_PROBE_STRUCT(fdt) \\\n\t{ \\\n\t\tint err; \\\n\t\tif ((err = fdt_sw_probe_struct_(fdt)) != 0) \\\n\t\t\treturn err; \\\n\t}\n\n/* 'complete' state:\tEnter this state after fdt_finish()\n *\n * Allowed functions: none\n */\n\nstatic void *fdt_grab_space_(void *fdt, size_t len)\n{\n\tint offset = fdt_size_dt_struct(fdt);\n\tint spaceleft;\n\n\tspaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt)\n\t\t- fdt_size_dt_strings(fdt);\n\n\tif ((offset + len < offset) || (offset + len > spaceleft))\n\t\treturn NULL;\n\n\tfdt_set_size_dt_struct(fdt, offset + len);\n\treturn fdt_offset_ptr_w_(fdt, offset);\n}\n\nint fdt_create(void *buf, int bufsize)\n{\n\tconst size_t hdrsize = FDT_ALIGN(sizeof(struct fdt_header),\n\t\t\t\t\t sizeof(struct fdt_reserve_entry));\n\tvoid *fdt = buf;\n\n\tif (bufsize < hdrsize)\n\t\treturn -FDT_ERR_NOSPACE;\n\n\tmemset(buf, 0, bufsize);\n\n\tfdt_set_magic(fdt, FDT_SW_MAGIC);\n\tfdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION);\n\tfdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION);\n\tfdt_set_totalsize(fdt,  bufsize);\n\n\tfdt_set_off_mem_rsvmap(fdt, hdrsize);\n\tfdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt));\n\tfdt_set_off_dt_strings(fdt, 0);\n\n\treturn 0;\n}\n\nint fdt_resize(void *fdt, void *buf, int bufsize)\n{\n\tsize_t headsize, tailsize;\n\tchar *oldtail, *newtail;\n\n\tFDT_SW_PROBE(fdt);\n\n\theadsize = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);\n\ttailsize = fdt_size_dt_strings(fdt);\n\n\tif ((headsize + tailsize) > fdt_totalsize(fdt))\n\t\treturn -FDT_ERR_INTERNAL;\n\n\tif ((headsize + tailsize) > bufsize)\n\t\treturn -FDT_ERR_NOSPACE;\n\n\toldtail = (char *)fdt + fdt_totalsize(fdt) - tailsize;\n\tnewtail = (char *)buf + bufsize - tailsize;\n\n\t/* Two cases to avoid clobbering data if the old and new\n\t * buffers partially overlap */\n\tif (buf <= fdt) {\n\t\tmemmove(buf, fdt, headsize);\n\t\tmemmove(newtail, oldtail, tailsize);\n\t} else {\n\t\tmemmove(newtail, oldtail, tailsize);\n\t\tmemmove(buf, fdt, headsize);\n\t}\n\n\tfdt_set_totalsize(buf, bufsize);\n\tif (fdt_off_dt_strings(buf))\n\t\tfdt_set_off_dt_strings(buf, bufsize);\n\n\treturn 0;\n}\n\nint fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)\n{\n\tstruct fdt_reserve_entry *re;\n\tint offset;\n\n\tFDT_SW_PROBE_MEMRSV(fdt);\n\n\toffset = fdt_off_dt_struct(fdt);\n\tif ((offset + sizeof(*re)) > fdt_totalsize(fdt))\n\t\treturn -FDT_ERR_NOSPACE;\n\n\tre = (struct fdt_reserve_entry *)((char *)fdt + offset);\n\tre->address = cpu_to_fdt64(addr);\n\tre->size = cpu_to_fdt64(size);\n\n\tfdt_set_off_dt_struct(fdt, offset + sizeof(*re));\n\n\treturn 0;\n}\n\nint fdt_finish_reservemap(void *fdt)\n{\n\tint err = fdt_add_reservemap_entry(fdt, 0, 0);\n\n\tif (err)\n\t\treturn err;\n\n\tfdt_set_off_dt_strings(fdt, fdt_totalsize(fdt));\n\treturn 0;\n}\n\nint fdt_begin_node(void *fdt, const char *name)\n{\n\tstruct fdt_node_header *nh;\n\tint namelen;\n\n\tFDT_SW_PROBE_STRUCT(fdt);\n\n\tnamelen = strlen(name) + 1;\n\tnh = fdt_grab_space_(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen));\n\tif (! nh)\n\t\treturn -FDT_ERR_NOSPACE;\n\n\tnh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);\n\tmemcpy(nh->name, name, namelen);\n\treturn 0;\n}\n\nint fdt_end_node(void *fdt)\n{\n\tfdt32_t *en;\n\n\tFDT_SW_PROBE_STRUCT(fdt);\n\n\ten = fdt_grab_space_(fdt, FDT_TAGSIZE);\n\tif (! en)\n\t\treturn -FDT_ERR_NOSPACE;\n\n\t*en = cpu_to_fdt32(FDT_END_NODE);\n\treturn 0;\n}\n\nstatic int fdt_find_add_string_(void *fdt, const char *s)\n{\n\tchar *strtab = (char *)fdt + fdt_totalsize(fdt);\n\tconst char *p;\n\tint strtabsize = fdt_size_dt_strings(fdt);\n\tint len = strlen(s) + 1;\n\tint struct_top, offset;\n\n\tp = fdt_find_string_(strtab - strtabsize, strtabsize, s);\n\tif (p)\n\t\treturn p - strtab;\n\n\t/* Add it */\n\toffset = -strtabsize - len;\n\tstruct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);\n\tif (fdt_totalsize(fdt) + offset < struct_top)\n\t\treturn 0; /* no more room :( */\n\n\tmemcpy(strtab + offset, s, len);\n\tfdt_set_size_dt_strings(fdt, strtabsize + len);\n\treturn offset;\n}\n\nint fdt_property_placeholder(void *fdt, const char *name, int len, void **valp)\n{\n\tstruct fdt_property *prop;\n\tint nameoff;\n\n\tFDT_SW_PROBE_STRUCT(fdt);\n\n\tnameoff = fdt_find_add_string_(fdt, name);\n\tif (nameoff == 0)\n\t\treturn -FDT_ERR_NOSPACE;\n\n\tprop = fdt_grab_space_(fdt, sizeof(*prop) + FDT_TAGALIGN(len));\n\tif (! prop)\n\t\treturn -FDT_ERR_NOSPACE;\n\n\tprop->tag = cpu_to_fdt32(FDT_PROP);\n\tprop->nameoff = cpu_to_fdt32(nameoff);\n\tprop->len = cpu_to_fdt32(len);\n\t*valp = prop->data;\n\treturn 0;\n}\n\nint fdt_property(void *fdt, const char *name, const void *val, int len)\n{\n\tvoid *ptr;\n\tint ret;\n\n\tret = fdt_property_placeholder(fdt, name, len, &ptr);\n\tif (ret)\n\t\treturn ret;\n\tmemcpy(ptr, val, len);\n\treturn 0;\n}\n\nint fdt_finish(void *fdt)\n{\n\tchar *p = (char *)fdt;\n\tfdt32_t *end;\n\tint oldstroffset, newstroffset;\n\tuint32_t tag;\n\tint offset, nextoffset;\n\n\tFDT_SW_PROBE_STRUCT(fdt);\n\n\t/* Add terminator */\n\tend = fdt_grab_space_(fdt, sizeof(*end));\n\tif (! end)\n\t\treturn -FDT_ERR_NOSPACE;\n\t*end = cpu_to_fdt32(FDT_END);\n\n\t/* Relocate the string table */\n\toldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt);\n\tnewstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);\n\tmemmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt));\n\tfdt_set_off_dt_strings(fdt, newstroffset);\n\n\t/* Walk the structure, correcting string offsets */\n\toffset = 0;\n\twhile ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {\n\t\tif (tag == FDT_PROP) {\n\t\t\tstruct fdt_property *prop =\n\t\t\t\tfdt_offset_ptr_w_(fdt, offset);\n\t\t\tint nameoff;\n\n\t\t\tnameoff = fdt32_to_cpu(prop->nameoff);\n\t\t\tnameoff += fdt_size_dt_strings(fdt);\n\t\t\tprop->nameoff = cpu_to_fdt32(nameoff);\n\t\t}\n\t\toffset = nextoffset;\n\t}\n\tif (nextoffset < 0)\n\t\treturn nextoffset;\n\n\t/* Finally, adjust the header */\n\tfdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt));\n\tfdt_set_magic(fdt, FDT_MAGIC);\n\treturn 0;\n}\n"
  },
  {
    "path": "kernel/libs/libfdt/fdt_wip.c",
    "content": "/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2006 David Gibson, IBM Corporation.\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include <libfdt/libfdt_env.h>\n\n#include <libfdt/fdt.h>\n#include <libfdt/libfdt.h>\n\n#include \"libfdt_internal.h\"\n\nint fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset,\n\t\t\t\t\tconst char *name, int namelen,\n\t\t\t\t\tuint32_t idx, const void *val,\n\t\t\t\t\tint len)\n{\n\tvoid *propval;\n\tint proplen;\n\n\tpropval = fdt_getprop_namelen_w(fdt, nodeoffset, name, namelen,\n\t\t\t\t\t&proplen);\n\tif (!propval)\n\t\treturn proplen;\n\n\tif (proplen < (len + idx))\n\t\treturn -FDT_ERR_NOSPACE;\n\n\tmemcpy((char *)propval + idx, val, len);\n\treturn 0;\n}\n\nint fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,\n\t\t\tconst void *val, int len)\n{\n\tconst void *propval;\n\tint proplen;\n\n\tpropval = fdt_getprop(fdt, nodeoffset, name, &proplen);\n\tif (!propval)\n\t\treturn proplen;\n\n\tif (proplen != len)\n\t\treturn -FDT_ERR_NOSPACE;\n\n\treturn fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name,\n\t\t\t\t\t\t   strlen(name), 0,\n\t\t\t\t\t\t   val, len);\n}\n\nstatic void fdt_nop_region_(void *start, int len)\n{\n\tfdt32_t *p;\n\n\tfor (p = start; (char *)p < ((char *)start + len); p++)\n\t\t*p = cpu_to_fdt32(FDT_NOP);\n}\n\nint fdt_nop_property(void *fdt, int nodeoffset, const char *name)\n{\n\tstruct fdt_property *prop;\n\tint len;\n\n\tprop = fdt_get_property_w(fdt, nodeoffset, name, &len);\n\tif (!prop)\n\t\treturn len;\n\n\tfdt_nop_region_(prop, len + sizeof(*prop));\n\n\treturn 0;\n}\n\nint fdt_node_end_offset_(void *fdt, int offset)\n{\n\tint depth = 0;\n\n\twhile ((offset >= 0) && (depth >= 0))\n\t\toffset = fdt_next_node(fdt, offset, &depth);\n\n\treturn offset;\n}\n\nint fdt_nop_node(void *fdt, int nodeoffset)\n{\n\tint endoffset;\n\n\tendoffset = fdt_node_end_offset_(fdt, nodeoffset);\n\tif (endoffset < 0)\n\t\treturn endoffset;\n\n\tfdt_nop_region_(fdt_offset_ptr_w(fdt, nodeoffset, 0),\n\t\t\tendoffset - nodeoffset);\n\treturn 0;\n}\n"
  },
  {
    "path": "kernel/libs/libfdt/libfdt_internal.h",
    "content": "#ifndef LIBFDT_INTERNAL_H\n#define LIBFDT_INTERNAL_H\n/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2006 David Gibson, IBM Corporation.\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n#include <libfdt/fdt.h>\n\n#define FDT_ALIGN(x, a)\t\t(((x) + (a) - 1) & ~((a) - 1))\n#define FDT_TAGALIGN(x)\t\t(FDT_ALIGN((x), FDT_TAGSIZE))\n\nint fdt_ro_probe_(const void *fdt);\n#define FDT_RO_PROBE(fdt)\t\t\t\\\n\t{ \\\n\t\tint err_; \\\n\t\tif ((err_ = fdt_ro_probe_(fdt)) != 0)\t\\\n\t\t\treturn err_; \\\n\t}\n\nint fdt_check_node_offset_(const void *fdt, int offset);\nint fdt_check_prop_offset_(const void *fdt, int offset);\nconst char *fdt_find_string_(const char *strtab, int tabsize, const char *s);\nint fdt_node_end_offset_(void *fdt, int nodeoffset);\n\nstatic inline const void *fdt_offset_ptr_(const void *fdt, int offset)\n{\n\treturn (const char *)fdt + fdt_off_dt_struct(fdt) + offset;\n}\n\nstatic inline void *fdt_offset_ptr_w_(void *fdt, int offset)\n{\n\treturn (void *)(uintptr_t)fdt_offset_ptr_(fdt, offset);\n}\n\nstatic inline const struct fdt_reserve_entry *fdt_mem_rsv_(const void *fdt, int n)\n{\n\tconst struct fdt_reserve_entry *rsv_table =\n\t\t(const struct fdt_reserve_entry *)\n\t\t((const char *)fdt + fdt_off_mem_rsvmap(fdt));\n\n\treturn rsv_table + n;\n}\nstatic inline struct fdt_reserve_entry *fdt_mem_rsv_w_(void *fdt, int n)\n{\n\treturn (void *)(uintptr_t)fdt_mem_rsv_(fdt, n);\n}\n\n#define FDT_SW_MAGIC\t\t(~FDT_MAGIC)\n\n#endif /* LIBFDT_INTERNAL_H */\n"
  },
  {
    "path": "kernel/libs/shell_command/Kconfig",
    "content": "if SHELL\n\nmenu \"Shell Command Support\"\n\nconfig SHELL_COMMAND_TASK\n\tbool \"Command for task management\"\n\tdefault y\n\thelp\n\t  \"command for task management\"\n\nendmenu\n\nendif\n\n"
  },
  {
    "path": "kernel/libs/shell_command/Makefile",
    "content": "obj-y\t\t\t\t\t+= shell_command.o\nobj-y\t\t\t\t\t+= clear.o\nobj-$(CONFIG_SHELL_COMMAND_TASK)\t+= task_cmd.o\nobj-y\t\t\t\t\t+= help_cmd.o\n"
  },
  {
    "path": "kernel/libs/shell_command/clear.c",
    "content": "/*\n * Copyright (C) 2017 - 2020 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/shell_command.h>\n#include <minos/print.h>\n\nstatic int clear_cmd(int argc, char **argv)\n{\n\tprintf(\"\\x1b[2J\\x1b[H\");\n\treturn 0;\n}\nDEFINE_SHELL_COMMAND(clear, \"clear\", \"Clear the screec\", clear_cmd, 0);\n"
  },
  {
    "path": "kernel/libs/shell_command/help_cmd.c",
    "content": "// SPDX-License-Identifier: GPL-2.0\n\n#include <minos/minos.h>\n#include <minos/shell_command.h>\n\nextern unsigned long __shell_command_start;\nextern unsigned long __shell_command_end;\n\nstatic int help_cmd(int argc, char **argv)\n{\n    struct shell_command *cmd;\n    char *spaces = \"       \";\n\n    section_for_each_item(__shell_command_start, __shell_command_end, cmd) {\n        printf(\"%s%s - %s\\n\",\n               cmd->name,\n               spaces + (MIN(strlen(cmd->name), strlen(spaces))),\n               cmd->cmd_info);\n    }\n\n    return 0;\n}\n\nDEFINE_SHELL_COMMAND(help, \"help\", \"print command description\", help_cmd, 0);\n"
  },
  {
    "path": "kernel/libs/shell_command/shell_command.c",
    "content": "/*\n * Copyright (C) 2020 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/shell_command.h>\n\nint excute_shell_command(int argc, char **argv)\n{\n\tstruct shell_command *cmd;\n\textern unsigned long __shell_command_start;\n\textern unsigned long __shell_command_end;\n\n\tif ((argc == 0) || (argv[0] == NULL))\n\t\treturn -EINVAL;\n\n\tsection_for_each_item(__shell_command_start,\n\t\t\t\t__shell_command_end, cmd) {\n\t\tif (strcmp(argv[0], cmd->name) == 0) {\n\t\t\tif (cmd->hdl == NULL)\n\t\t\t\treturn -ENOENT;\n\n\t\t\treturn cmd->hdl(argc, argv);\n\t\t}\n\t}\n\n\treturn -ENOENT;\n}\n"
  },
  {
    "path": "kernel/libs/shell_command/task_cmd.c",
    "content": "/*\n * Copyright (C) 2020 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/task.h>\n#include <minos/shell_command.h>\n#include <virt/vm.h>\n\nstatic char *state_str[7] = {\n\t\"Running\",\n\t\"  Ready\",\n\t\"   Wait\",\n\t\" Waking\",\n\t\"Suspend\",\n\t\"Stopped\",\n\t\"  Wrong\",\n};\n\nstatic inline char *get_state_str(struct task *task)\n{\n\tswitch (task->state) {\n\tcase TASK_STATE_RUNNING:\n\t\treturn state_str[0];\n\tcase TASK_STATE_READY:\n\t\treturn state_str[1];\n\tcase TASK_STATE_WAIT_EVENT:\n\t\treturn state_str[2];\n\tcase TASK_STATE_WAKING:\n\t\treturn state_str[3];\n\tcase TASK_STATE_SUSPEND:\n\t\treturn state_str[4];\n\tcase TASK_STATE_STOP:\n\t\treturn state_str[5];\n\t}\n\n\treturn state_str[6];\n}\n\nstatic void dump_task_info(struct task *task)\n{\n\tchar vm_str[8] = {0};\n\tstruct vcpu *vcpu;\n\n\tif (task_is_vcpu(task)) {\n\t\tvcpu = (struct vcpu *)task->pdata;\n\t\tsprintf(vm_str, \"vm-%d/\", vcpu->vm->vmid);\n\t}\n\n\tprintf(\"%4d %3d %s %s%s\\n\", task->tid, task->cpu,\n\t\t\tget_state_str(task), vm_str, task->name);\n}\n\nstatic int ps_cmd(int argc, char **argv)\n{\n\tprintf(\" PID CPU   STATE NAME\\n\");\n\tos_for_all_task(dump_task_info);\n\n\treturn 0;\n}\nDEFINE_SHELL_COMMAND(ps, \"ps\", \"List all task information\", ps_cmd, 0);\n"
  },
  {
    "path": "kernel/platform/Kconfig",
    "content": "menu \"Platform Configuration\"\n\nchoice\n\tprompt \"SOC current used\"\n\tconfig SOC_FVP\n\t\tbool \"arm fix virtual platform\"\n\tconfig SOC_MARVELL_A3700\n\t\tbool \"marvell a3700 SOC\"\n\tconfig SOC_BCM2837\n\t\tbool \"bcm2837 SOC\"\n\tconfig SOC_BCM2838\n\t\tbool \"bcm2838 SOC\"\n\tconfig SOC_AMLOGIC\n\t\tbool \"amlogic SOC\"\n\tconfig SOC_QEMU\n\t\tbool \"qemu platform\"\nendchoice\n\nsource \"platform/espressobin/Kconfig\"\nsource \"platform/fvp/Kconfig\"\nsource \"platform/raspberry3/Kconfig\"\nsource \"platform/raspberry4/Kconfig\"\nsource \"platform/amlogic/Kconfig\"\nsource \"platform/qemu/Kconfig\"\n\nendmenu\n"
  },
  {
    "path": "kernel/platform/Makefile",
    "content": "obj-y += platform.o\nobj-$(CONFIG_SOC_MARVELL_A3700)\t+= espressobin/\nobj-$(CONFIG_SOC_FVP) \t   \t+= fvp/\nobj-$(CONFIG_SOC_BCM2837)  \t+= raspberry3/\nobj-$(CONFIG_SOC_BCM2838)  \t+= raspberry4/\nobj-$(CONFIG_SOC_AMLOGIC)  \t+= amlogic/\nobj-$(CONFIG_SOC_QEMU)\t\t+= qemu/\n"
  },
  {
    "path": "kernel/platform/amlogic/Kconfig",
    "content": "if SOC_AMLOGIC\n\nconfig MINOS_ENTRY_ADDRESS\n\thex \"entry address of system\"\n\tdefault 0xeb80c000\n\thelp\n\t  the entry address is the start address plus\n\t  nr_cpus * TASK_STACK_SIZE, the kvim3 has 6 cores\n\nconfig MINOS_RAM_SIZE\n\thex \"memory size for Minos\"\n\tdefault 0x2000000\n\trange 0x1000000 0x4000000\n\thelp\n\t  the memory size for Minos\n\nconfig NR_CPUS\n\tint \"number of cpu in system\"\n\tdefault 6\n\thelp\n\t  how many cpu in current system\n\nconfig UART_BASE\n\thex \"uart controller memory base\"\n\tdefault 0xff803000\n\nconfig UART_IO_SIZE\n\thex \"uart controller iomem size\"\n\tdefault 0x1000\n\nconfig DTB_LOAD_ADDRESS\n\thex\n\tdefault 0xed600000\n\nendif\n"
  },
  {
    "path": "kernel/platform/amlogic/Makefile",
    "content": "obj-y\t\t\t+= kvim3.o\nobj-$(CONFIG_VIRT)\t+= amlogic_smc.o\n"
  },
  {
    "path": "kernel/platform/amlogic/amlogic_smc.c",
    "content": "/*\n * Copyright (C) 2019 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <asm/svccc.h>\n#include <minos/sched.h>\n#include <asm/psci.h>\n#include <virt/vm.h>\n\n#define SECMON_IN_BASE_FUNC\t\t0x82000020\n#define SECMON_OUT_BASE_FUNC\t\t0x82000021\n\n#define SECKEY_STORAGE_QUERY\t\t0x82000060\n#define SECKEY_STORAGE_READ\t\t0x82000061\n#define SECKEY_STORAGE_WRITE\t\t0x82000062\n#define SECKEY_STORAGE_TELL\t\t0x82000063\n#define SECKEY_STORAGE_VERIFY\t\t0x82000064\n#define SECKEY_STORAGE_STATUS\t\t0x82000065\n#define SECKEY_STORAGE_LIST\t\t0x82000067\n#define SECKEY_STORAGE_REMOVE\t\t0x82000068\n#define SECKEY_STORAGE_IN_FUNC\t\t0x82000023\n#define SECKEY_STORAGE_OUT_FUNC\t\t0x82000024\n#define SECKEY_STORAGE_BLOCK_FUNC\t0x82000025\n#define SECKEY_STORAGE_SIZE_FUNC\t0x82000027\n#define SECKEY_STORAGE_SET_ENCTYPE\t0x8200006a\n#define SECKEY_STORAGE_GET_ENCTYPE\t0x8200006b\n#define SECKEY_STORAGE_VERSION\t\t0x8200006c\n\n#define EFUSE_READ_CMD\t\t\t0x82000030\n#define EFUSE_WRITE_CMD\t\t\t0x82000031\n#define EFUSE_GET_MAX_CMD\t\t0x82000033\n\n#define CPUINFO_CMD\t\t\t0x82000044\n\n#define AUDIO_QUERY_LICENSE_CMD\t\t0x82000050\n\n#define AMLOGIC_SMC_BASE\t\t0x82000000\n#define AMLOGIC_SMC_HANDLER_NUMBER\t128\n#define AMLOGIC_SMC_END\t\t\t(AMLOGIC_SMC_BASE + AMLOGIC_SMC_HANDLER_NUMBER)\n\nstatic svc_handler_t amlogic_smc_fn[128];\n\nstatic int amlogic_unknown_smc(gp_regs *c, uint32_t id, unsigned long *args)\n{\n\tstruct arm_smc_res res;\n\n\tsmc_call(id, args[0], args[1], args[2], args[3], 0, 0, 0, &res);\n\tSVC_RET4(c, res.a0, res.a1, res.a2, res.a3);\n\n\treturn 0;\n}\n\nstatic int sip_smc_handler(gp_regs *c, uint32_t id, unsigned long *args)\n{\n\tstruct vcpu *vcpu = get_current_vcpu();\n\tstruct vm *vm = vcpu->vm;\n\tsvc_handler_t fn;\n\n\tpr_debug(\"sip function for amlogic 0x%x\\n\", id);\n\n\tif (!vm_is_host_vm(vm))\n\t\treturn -EPERM;\n\n\tfn = amlogic_smc_fn[id - AMLOGIC_SMC_BASE];\n\tif (fn)\n\t\treturn fn(c, id, args);\n\telse\n\t\treturn amlogic_unknown_smc(c, id, args);\n}\nDEFINE_SMC_HANDLER(\"sip_smc_desc\", SVC_STYPE_SIP,\n\t\tSVC_STYPE_SIP, sip_smc_handler);\n\nstatic int inline amlogic_install_smc(svc_handler_t fn, uint32_t id)\n{\n\tif ((id < AMLOGIC_SMC_BASE) || (id > AMLOGIC_SMC_END))\n\t\treturn -EINVAL;\n\n\tamlogic_smc_fn[id - AMLOGIC_SMC_BASE] = fn;\n\treturn 0;\n}\n\nstatic inline int amlogic_smc_call(gp_regs *c, uint32_t id)\n{\n\tstruct arm_smc_res res;\n\n\tsmc_call(id, 0, 0, 0, 0, 0, 0, 0, &res);\n\tSVC_RET1(c, res.a0);\n\n\treturn 0;\n}\n\nstatic inline int\namlogic_smc_call2(gp_regs *c, uint32_t id, unsigned long arg)\n{\n\tstruct arm_smc_res res;\n\n\tsmc_call(id, arg, 0, 0, 0, 0, 0, 0, &res);\n\tSVC_RET1(c, res.a0);\n\n\treturn 0;\n}\n\nstatic int secmon_in_base(gp_regs *c, uint32_t id, unsigned long *args)\n{\n\treturn amlogic_smc_call(c, id);\n}\n\nstatic int secmon_out_base(gp_regs *c, uint32_t id, unsigned long *args)\n{\n\treturn amlogic_smc_call(c, id);\n}\n\nstatic int seckey_storage_query(gp_regs *c, uint32_t id, unsigned long *args)\n{\n\treturn amlogic_smc_call(c, id);\n}\n\nstatic int seckey_storage_read(gp_regs *c, uint32_t id, unsigned long *args)\n{\n\treturn amlogic_smc_call(c, id);\n}\n\nstatic int seckey_storage_write(gp_regs *c, uint32_t id, unsigned long *args)\n{\n\treturn amlogic_smc_call(c, id);\n}\n\nstatic int seckey_storage_tell(gp_regs *c, uint32_t id, unsigned long *args)\n{\n\treturn amlogic_smc_call(c, id);\n}\n\nstatic int seckey_storage_verify(gp_regs *c, uint32_t id, unsigned long *args)\n{\n\treturn amlogic_smc_call(c, id);\n}\n\nstatic int seckey_storage_status(gp_regs *c, uint32_t id, unsigned long *args)\n{\n\treturn amlogic_smc_call(c, id);\n}\n\nstatic int seckey_storage_list(gp_regs *c, uint32_t id, unsigned long *args)\n{\n\treturn amlogic_smc_call(c, id);\n}\n\nstatic int seckey_storage_remove(gp_regs *c, uint32_t id, unsigned long *args)\n{\n\treturn amlogic_smc_call(c, id);\n}\n\nstatic int seckey_storage_in_func(gp_regs *c, uint32_t id, unsigned long *args)\n{\n\treturn amlogic_smc_call(c, id);\n}\n\nstatic int seckey_storage_out_func(gp_regs *c, uint32_t id, unsigned long *args)\n{\n\treturn amlogic_smc_call(c, id);\n}\n\nstatic int seckey_storage_block_func(gp_regs *c, uint32_t id, unsigned long *args)\n{\n\treturn amlogic_smc_call(c, id);\n}\n\nstatic int seckey_storage_size_func(gp_regs *c, uint32_t id, unsigned long *args)\n{\n\treturn amlogic_smc_call(c, id);\n}\n\nstatic int seckey_storage_get_enctype(gp_regs *c, uint32_t id, unsigned long *args)\n{\n\treturn amlogic_smc_call(c, id);\n}\n\nstatic int seckey_storage_set_enctype(gp_regs *c, uint32_t id, unsigned long *args)\n{\n\treturn amlogic_smc_call2(c, id, args[0]);\n}\n\nstatic int seckey_storage_version(gp_regs *c, uint32_t id, unsigned long *args)\n{\n\treturn amlogic_smc_call(c, id);\n}\n\nstatic int efuse_read_cmd(gp_regs *c, uint32_t id, unsigned long *args)\n{\n\tstruct arm_smc_res res;\n\n\tsmc_call(id, args[0], args[1], 0, 0, 0, 0, 0, &res);\n\tSVC_RET1(c, res.a0);\n\n\treturn 0;\n}\n\nstatic int efuse_write_cmd(gp_regs *c, uint32_t id, unsigned long *args)\n{\n\tstruct arm_smc_res res;\n\n\tsmc_call(id, args[0], args[1], 0, 0, 0, 0, 0, &res);\n\tSVC_RET1(c, res.a0);\n\n\treturn 0;\n}\n\nstatic int efuse_get_max_cmd(gp_regs *c, uint32_t id, unsigned long *args)\n{\n\treturn amlogic_smc_call(c, id);\n}\n\nstatic int cpuinfo_cmd(gp_regs *c, uint32_t id, unsigned long *args)\n{\n\tstruct arm_smc_res res;\n\n\tsmc_call(id, args[0], args[1], args[2], 0, 0, 0, 0, &res);\n\tSVC_RET1(c, res.a0);\n\n\treturn 0;\n}\n\nstatic int audio_query_license_cmd(gp_regs *c, uint32_t id, unsigned long *args)\n{\n\tstruct arm_smc_res res;\n\n\tsmc_call(id, args[0], args[1], 0, 0, 0, 0, 0, &res);\n\tSVC_RET1(c, res.a0);\n\n\treturn 0;\n}\n\nstatic int __init_text amlogic_smc_init(void)\n{\n\tamlogic_install_smc(secmon_in_base, SECMON_IN_BASE_FUNC);\n\tamlogic_install_smc(secmon_out_base, SECMON_OUT_BASE_FUNC);\n\n\tamlogic_install_smc(seckey_storage_query, SECKEY_STORAGE_QUERY);\n\tamlogic_install_smc(seckey_storage_read, SECKEY_STORAGE_READ);\n\tamlogic_install_smc(seckey_storage_write, SECKEY_STORAGE_WRITE);\n\tamlogic_install_smc(seckey_storage_tell, SECKEY_STORAGE_TELL);\n\tamlogic_install_smc(seckey_storage_verify, SECKEY_STORAGE_VERIFY);\n\tamlogic_install_smc(seckey_storage_status, SECKEY_STORAGE_STATUS);\n\tamlogic_install_smc(seckey_storage_list, SECKEY_STORAGE_LIST);\n\tamlogic_install_smc(seckey_storage_remove, SECKEY_STORAGE_REMOVE);\n\tamlogic_install_smc(seckey_storage_in_func, SECKEY_STORAGE_IN_FUNC);\n\tamlogic_install_smc(seckey_storage_out_func, SECKEY_STORAGE_OUT_FUNC);\n\tamlogic_install_smc(seckey_storage_block_func, SECKEY_STORAGE_BLOCK_FUNC);\n\tamlogic_install_smc(seckey_storage_size_func, SECKEY_STORAGE_SIZE_FUNC);\n\tamlogic_install_smc(seckey_storage_get_enctype, SECKEY_STORAGE_SET_ENCTYPE);\n\tamlogic_install_smc(seckey_storage_set_enctype, SECKEY_STORAGE_GET_ENCTYPE);\n\tamlogic_install_smc(seckey_storage_version, SECKEY_STORAGE_VERSION);\n\n\tamlogic_install_smc(efuse_read_cmd, EFUSE_READ_CMD);\n\tamlogic_install_smc(efuse_write_cmd, EFUSE_WRITE_CMD);\n\tamlogic_install_smc(efuse_get_max_cmd, EFUSE_GET_MAX_CMD);\n\n\tamlogic_install_smc(cpuinfo_cmd, CPUINFO_CMD);\n\tamlogic_install_smc(audio_query_license_cmd, AUDIO_QUERY_LICENSE_CMD);\n\n\treturn 0;\n}\nmodule_initcall(amlogic_smc_init);\n"
  },
  {
    "path": "kernel/platform/amlogic/kvim3.c",
    "content": "/*\n * Copyright (C) 2019 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <asm/arch.h>\n#include <asm/io.h>\n#include <minos/mmu.h>\n#include <libfdt/libfdt.h>\n#include <minos/of.h>\n#include <minos/platform.h>\n#include <asm/power.h>\n\n#ifdef CONFIG_VIRT\n#include <virt/vm.h>\n\nstatic int kvim3_setup_hvm(struct vm *vm, void *data)\n{\n\treturn 0;\n}\n\n#endif\n\nstatic struct platform platform_kvim3 = {\n\t.name\t\t = \"khadas,vim3\",\n\t.cpu_on\t\t = psci_cpu_on,\n\t.cpu_off\t = psci_cpu_off,\n#ifdef CONFIG_VIRT\n\t.setup_hvm\t = kvim3_setup_hvm,\n#endif\n\t.system_reboot\t = psci_system_reboot,\n\t.system_shutdown = psci_system_shutdown,\n};\nDEFINE_PLATFORM(platform_kvim3);\n"
  },
  {
    "path": "kernel/platform/espressobin/Kconfig",
    "content": "if SOC_MARVELL_A3700\n\nconfig MINOS_ENTRY_ADDRESS\n\thex \"entry address of system\"\n\tdefault 0x3c004000\n\thelp\n\t  the entry address is the start address plus\n\t  nr_cpus * TASK_STACK_SIZE\n\nconfig MINOS_RAM_SIZE\n\thex \"memory size for Minos\"\n\tdefault 0x4000000\n\trange 0x1000000 0x4000000\n\thelp\n\t  the memory size for Minos\n\nconfig NR_CPUS\n\tint \"number of cpu in system\"\n\tdefault 2\n\thelp\n\t  how many cpu in current system\n\nconfig UART_BASE\n\thex \"uart controller iomem base address\"\n\tdefault 0xd0012000\n\nconfig UART_IO_SIZE\n\thex \"uart controller iomem size\"\n\tdefault 0x1000\n\nendif\n"
  },
  {
    "path": "kernel/platform/espressobin/Makefile",
    "content": "obj-y += espressobin.o\n"
  },
  {
    "path": "kernel/platform/espressobin/espressobin.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <asm/power.h>\n#include <minos/mm.h>\n#include <virt/vmm.h>\n#include <virt/vm.h>\n#include <minos/platform.h>\n\n#ifdef CONFIG_VIRT\nstatic int espressobin_setup_vm0(struct vm *vm, void *dtb)\n{\n\t/* create the pcie region for the vm0 */\n\tcreate_guest_mapping(&vm->vs, 0xe8000000, 0xe8000000, 0x1000000, VM_IO);\n\tcreate_guest_mapping(&vm->vs, 0xe9000000, 0xe9000000, 0x10000, VM_IO);\n\tcreate_guest_mapping(&vm->vs, 0xd0070000, 0xd0070000, 0x20000, VM_IO);\n\n\treturn 0;\n}\n#endif\n\nstatic struct platform platform_espressobin = {\n\t.name\t\t = \"marvell,armada-3720-community\",\n\t.cpu_on\t\t = psci_cpu_on,\n\t.cpu_off\t = psci_cpu_off,\n\t.system_reboot\t = psci_system_reboot,\n\t.system_shutdown = psci_system_shutdown,\n#ifdef CONFIG_VIRT\n\t.setup_hvm\t = espressobin_setup_vm0,\n#endif\n};\n\nDEFINE_PLATFORM(platform_espressobin);\n"
  },
  {
    "path": "kernel/platform/fvp/Kconfig",
    "content": "if SOC_FVP\n\nconfig MINOS_ENTRY_ADDRESS\n\thex \"entry address of system\"\n\tdefault 0xc0000000\n\thelp\n\t  the entry address is the start address plus\n\t  nr_cpus * TASK_STACK_SIZE\n\nconfig MINOS_RAM_SIZE\n\thex \"memory size for Minos\"\n\tdefault 0x4000000\n\trange 0x1000000 0x4000000\n\thelp\n\t  the memory size for Minos\n\nconfig NR_CPUS\n\tint \"number of cpu in system\"\n\tdefault 4\n\thelp\n\t  how many cpu in current system\n\nconfig UART_BASE\n\thex \"uart controller iomem base address\"\n\tdefault 0x1c0a0000\n\nconfig UART_IO_SIZE\n\thex \"uart controller iomem size\"\n\tdefault 0x1000\n\nconfig UART_IRQ\n\tint \"the irq number for uart\"\n\tdefault 38\n\nendif\n"
  },
  {
    "path": "kernel/platform/fvp/Makefile",
    "content": "obj-y += fvp.o\n"
  },
  {
    "path": "kernel/platform/fvp/fvp.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <asm/power.h>\n#include <asm/io.h>\n#include <minos/platform.h>\n#include <libfdt/libfdt.h>\n\n#ifdef CONFIG_VIRT\n#include <virt/vm.h>\n#endif\n\n#ifdef CONFIG_VIRT\nstatic int inline fvp_setup_hvm_of(struct vm *vm, void *data)\n{\n\tint node, len;\n\tconst void *val;\n\n\t/* disable the armv7-timer-mem for fvp*/\n\tnode = fdt_path_offset(data, \"/timer@2a810000\");\n\tif (node < 0)\n\t\treturn 0;\n\n\tval = fdt_getprop(data, node, \"compatible\", &len);\n\tif (!val || len <= 0)\n\t\treturn 0;\n\n\tif (!strcmp((char *)val, \"arm,armv7-timer-mem\")) {\n\t\tpr_notice(\"delete the armv7 mem timer\\n\");\n\t\tfdt_del_node(data, node);\n\t}\n\n\treturn 0;\n}\n\nstatic int fvp_setup_hvm(struct vm *vm, void *data)\n{\n\tif (vm->flags & VM_FLAGS_SETUP_OF)\n\t\treturn fvp_setup_hvm_of(vm, data);\n\n\treturn 0;\n}\n#endif\n\nstatic struct platform platform_fvp = {\n\t.name \t\t = \"arm,fvp-base\",\n\t.cpu_on\t\t = psci_cpu_on,\n\t.cpu_off\t = psci_cpu_off,\n#ifdef CONFIG_VIRT\n\t.setup_hvm\t = fvp_setup_hvm,\n#endif\n\t.system_reboot\t = psci_system_reboot,\n\t.system_shutdown = psci_system_shutdown,\n};\n\nDEFINE_PLATFORM(platform_fvp);\n"
  },
  {
    "path": "kernel/platform/platform.c",
    "content": "/*\n * Copyright (C) 2019 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/arch.h>\n#include <minos/platform.h>\n#include <minos/of.h>\n\nextern unsigned char __platform_start;\nextern unsigned char __platform_end;\nstruct platform *platform = NULL;\n\nvoid platform_set_to(const char *name)\n{\n\tstruct platform **pp;\n\tstruct platform *p;\n\n\tsection_for_each_item(__platform_start, __platform_end, pp) {\n\t\tp = *pp;\n\t\tif (strcmp(p->name, name) == 0) {\n\t\t\tplatform = p;\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nint platform_iomem_valid(unsigned long addr)\n{\n\tif (platform->iomem_valid)\n\t\treturn platform->iomem_valid(addr);\n\telse\n\t\treturn 1;\n}\n\nvoid platform_init(void)\n{\n\tif (platform->platform_init)\n\t\tplatform->platform_init();\n}\n\nstatic int __init_text platform_early_init(void)\n{\n\t/* check whether the platform has been set\n\t * by the arch code in the early boot stage\n\t */\n\tif (platform == NULL)\n\t\tpanic(\"no platform found ...\\n\");\n\n\tif (platform->parse_mem_info)\n\t\tplatform->parse_mem_info();\n\n\treturn 0;\n}\nearly_initcall(platform_early_init);\n"
  },
  {
    "path": "kernel/platform/qemu/Kconfig",
    "content": "if SOC_QEMU\n\nconfig MINOS_ENTRY_ADDRESS\n\thex \"entry address of system\"\n\tdefault 0x40000000\n\thelp\n\t  the entry address is the start address plus\n\t  nr_cpus * TASK_STACK_SIZE\n\nconfig MINOS_RAM_SIZE\n\thex \"memory size for Minos\"\n\tdefault 0x4000000\n\trange 0x1000000 0x4000000\n\thelp\n\t  the memory size for Minos\n\nconfig NR_CPUS\n\tint \"number of cpu in system\"\n\tdefault 4\n\thelp\n\t  how many cpu in current system\n\nconfig UART_BASE\n\thex \"uart controller iomem base address\"\n\tdefault 0x90000000\n\nconfig UART_IO_SIZE\n\thex \"uart controller iomem size\"\n\tdefault 0x1000\n\nconfig UART_IRQ\n\tint \"the irq number for uart\"\n\tdefault 33\n\nendif\n"
  },
  {
    "path": "kernel/platform/qemu/Makefile",
    "content": "obj-y += qemu.o\n"
  },
  {
    "path": "kernel/platform/qemu/qemu.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <asm/power.h>\n#include <asm/io.h>\n#include <minos/platform.h>\n#include <libfdt/libfdt.h>\n#ifdef CONFIG_VIRT\n#include <virt/vm.h>\n#include <virt/vmm.h>\n#endif\n\n#ifdef CONFIG_VIRT\nstatic int qemu_setup_hvm(void *item, void *data)\n{\n\tstruct vm *vm = (struct vm *)item;\n\tint ret;\n\n\tif (!vm_is_host_vm(vm))\n\t\treturn 0;\n\n\t/*\n\t * workaroud, create the PCIE memory region for VM\n\t * since currently minos do not support parsing the\n\t * PCI range, TBD.\n\t * pci_bus 0000:00: root bus resource [bus 00-ff]\n\t * pci_bus 0000:00: root bus resource [io  0x0000-0xffff]\n\t * pci_bus 0000:00: root bus resource [mem 0x10000000-0x3efeffff]\n\t * pci_bus 0000:00: root bus resource [mem 0x8000000000-0xffffffffff]\n\t */\n\tsplit_vmm_area(&vm->mm, 0x0, 0x10000, VM_GUEST_IO | VM_RW);\n\tsplit_vmm_area(&vm->mm, 0x10000000, 0x2EFF0000,\n\t\t\tVM_GUEST_IO | VM_RW | VM_HUGE);\n\tsplit_vmm_area(&vm->mm, 0x8000000000, 0x8000000000,\n\t\t\tVM_GUEST_IO | VM_RW | __VM_HUGE_1G);\n\n\tret = create_guest_mapping(&vm->mm, 0x0, 0x0, 0x10000, VM_GUEST_IO | VM_RW);\n\tret += create_guest_mapping(&vm->mm, 0x10000000, 0x10000000, 0x2EFF0000,\n\t\t\tVM_GUEST_IO | VM_RW | VM_HUGE);\n\tret += create_guest_mapping(&vm->mm, 0x8000000000, 0x8000000000,\n\t\t\t0x8000000000, VM_GUEST_IO | VM_RW | __VM_HUGE_1G);\n\tif (ret)\n\t\tpr_err(\"map PCIE memory region for guest failed\\n\");\n\n\treturn ret;\n}\n\nstatic int qemu_platform_init(void)\n{\n\tregister_hook(qemu_setup_hvm, OS_HOOK_CREATE_VM);\n\n\treturn 0;\n}\ndevice_initcall(qemu_platform_init);\n#endif\n\nstatic struct platform platform_qemu = {\n\t.name \t\t = \"linux,qemu-arm64\",\n#if 1\n\t.cpu_on\t\t = psci_cpu_on,\n\t.cpu_off\t = psci_cpu_off,\n\t.system_reboot\t = psci_system_reboot,\n\t.system_shutdown = psci_system_shutdown,\n#else\n\t.cpu_on\t\t = psci_cpu_on_hvc,\n\t.cpu_off\t = psci_cpu_off_hvc,\n\t.system_reboot\t = psci_system_reboot_hvc,\n\t.system_shutdown = psci_system_shutdown_hvc,\n#endif\n};\n\nDEFINE_PLATFORM(platform_qemu);\n"
  },
  {
    "path": "kernel/platform/r8a7795/Kconfig",
    "content": "# SPDX-License-Identifier: GPL-2.0\n\nif SOC_R8A7795\n\nconfig MINOS_START_ADDRESS\n\thex \"memory start address of system\"\n\tdefault 0x48000000\n\nconfig MINOS_ENTRY_ADDRESS\n\thex \"entry address of system\"\n\tdefault 0x48010000\n\thelp\n\t  MINOS_START_ADDRESS + TASK_STACK_SIZE * NR_CPUS\n\nconfig MINOS_RAM_SIZE\n\thex \"memory size for Minos\"\n\trange 0x1000000 0x4000000\n\tdefault 0x2000000\n\thelp\n\t  the memory size for Minos\n\nconfig NR_CPUS\n\tint \"number of cpu in system\"\n\trange 1 1 if !SMP\n\trange 1 8\n\tdefault 1 if !SMP\n\tdefault 8\n\thelp\n\t  how many cpu in current system\n\nconfig UART_BASE\n\thex \"uart controller iomem base address\"\n\tdefault 0xe6e88000\n\nconfig UART_IO_SIZE\n\thex \"uart controller iomem size\"\n\tdefault 0x1000\n\nconfig MINOS_TEXT_OFFSET\n\thex \"entry offset from start of ram\"\n\tdefault 0x10000\n\thelp\n\t  MINOS_ENTRY_ADDRESS - 0x48000000\n\nconfig DTB_LOAD_ADDRESS\n\thex \"device tree blob address\"\n\tdefault 0x49e00000\n\thelp\n\t  MINOS_START_ADDRESS + MINOS_RAM_SIZE - 0x200000\n\nconfig HVM_SPI_VIRQ_NR\n\tint \"SPI VIRQ for vm0\"\n\tdefault 480\n\thelp\n\t  NR_SPI_IRQS\n\nconfig GVM_SPI_VIRQ_NR\n\tint \"SPI VIRQ for non-vm0\"\n\tdefault 480\n\thelp\n\t  NR_SPI_IRQS\n\nendif\n"
  },
  {
    "path": "kernel/platform/r8a7795/Makefile",
    "content": "obj-y += r8a7795.o\n"
  },
  {
    "path": "kernel/platform/r8a7795/r8a7795.c",
    "content": "// SPDX-License-Identifier: GPL-2.0\n\n#include <asm/power.h>\n#include <minos/platform.h>\n\nstatic struct platform platform_r8a7795 = {\n    .name            = \"renesas,r8a7795\",\n    .cpu_on          = psci_cpu_on,\n    .cpu_off         = psci_cpu_off,\n    .system_reboot   = psci_system_reboot,\n    .system_shutdown = psci_system_shutdown,\n};\n\nDEFINE_PLATFORM(platform_r8a7795);\n"
  },
  {
    "path": "kernel/platform/raspberry3/Kconfig",
    "content": "if SOC_BCM2837\n\nconfig PLATFORM_BCM2837\n\tdef_bool y\n\tselect VIRQCHIP_BCM2836\n\tselect IRQCHIP_BCM2836\n\nconfig MINOS_ENTRY_ADDRESS\n\thex \"entry address of system\"\n\tdefault 0x28008000\n\thelp\n\t  the entry address is the start address plus\n\t  nr_cpus * TASK_STACK_SIZE\n\nconfig MINOS_RAM_SIZE\n\thex \"memory size for Minos\"\n\tdefault 0x2000000\n\trange 0x1000000 0x4000000\n\thelp\n\t  the memory size for Minos\n\nconfig NR_CPUS\n\tint \"number of cpu in system\"\n\tdefault 4\n\thelp\n\t  how many cpu in current system\n\nconfig UART_BASE\n\thex \"uart controller iomem base address\"\n\tdefault 0x3f215040\n\nconfig UART_IO_SIZE\n\thex \"uart controller iomem size\"\n\tdefault 0x1000\n\nconfig HVM_SPI_VIRQ_NR\n\tint \"SPI VIRQ for vm0\"\n\tdefault 96\n\nendif\n"
  },
  {
    "path": "kernel/platform/raspberry3/Makefile",
    "content": "obj-y += raspberry3.o\n"
  },
  {
    "path": "kernel/platform/raspberry3/raspberry3.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <asm/arch.h>\n#include <asm/io.h>\n#include <minos/mm.h>\n#include <device/bcm_irq.h>\n#include <libfdt/libfdt.h>\n#include <minos/of.h>\n#include <asm/power.h>\n#include <minos/platform.h>\n\n#ifdef CONFIG_VIRT\n#include <virt/virq.h>\n#include <virt/vm.h>\n#include <virt/vmm.h>\n\nstatic int raspberry3_setup_hvm(struct vm *vm, void *dtb)\n{\n\tint i, offset, node;\n\tchar name[16];\n\tuint64_t addr;\n\tuint64_t dtb_addr = 0;\n\tuint32_t *tmp = (uint32_t *)&dtb_addr;\n\n\toffset = of_get_node_by_name(dtb, 0, \"cpus\");\n\tif (offset < 0) {\n\t\tpr_err(\"can not find vcpus node for hvm\\n\");\n\t\treturn -ENOENT;\n\t}\n\n\t/*\n\t * using spin table boot methold redirect the\n\t * relase addr to the interrupt controller space\n\t */\n\tfor (i = 0; i < vm->vcpu_nr; i++) {\n\t\tmemset(name, 0, 16);\n\t\tsprintf(name, \"cpu@%d\", i);\n\t\tnode = fdt_subnode_offset(dtb, offset, name);\n\t\tif (node <= 0)\n\t\t\tcontinue;\n\n\t\taddr = BCM2836_RELEASE_ADDR + i * sizeof(uint64_t);\n\t\tpr_notice(\"vcpu-%d release addr redirect to 0x%p\\n\", i, addr);\n\t\ttmp[0] = cpu_to_fdt32(addr >> 32);\n\t\ttmp[1] = cpu_to_fdt32(addr & 0xffffffff);\n\n\t\tfdt_setprop(dtb, node, \"cpu-release-addr\", (void *)tmp,\n\t\t\t\t2 * sizeof(uint32_t));\n\t}\n\n\t/*\n\t * redirect the bcm2835 interrupt controller's iomem\n\t * to 0x40000200\n\t */\n\tnode = fdt_path_offset(dtb, \"/soc/interrupt-controller@7e00b200\");\n\tif (node <= 0) {\n\t\tpr_warn(\"can not find interrupt-controller@7e00b200\\n\");\n\t\treturn -ENOENT;\n\t}\n\n\ttmp[0] = cpu_to_fdt32(0x40000200);\n\ttmp[1] = cpu_to_fdt32(0x200);\n\tfdt_setprop(dtb, node, \"reg\", (void *)tmp, 2 * sizeof(uint32_t));\n\tfdt_set_name(dtb, node, \"interrupt-controller@40000200\");\n\n\t/* mask 40 - 52 virq for hvm which is internal use */\n\tfor (i = 40; i <= 52; i++)\n\t\trequest_virq(vm, i, 0);\n\n\tpr_notice(\"raspberry3 setup vm done\\n\");\n\n\treturn 0;\n}\n#endif\n\nstatic void raspberry3_system_reboot(int mode, const char *cmd)\n{\n\n}\n\nstatic void raspberry3_system_shutdown(void)\n{\n\n}\n\nstatic int raspberry4_iomem_valid(unsigned long addr)\n{\n\tif ((addr >= 0x40000000) && (addr < 0x40001000))\n\t\treturn 0;\n\n\treturn 1;\n}\n\nstatic void raspberry3_parse_mem_info(void)\n{\n\t/* memory start at 0x3b400000 may has been used\n\t * by other hardware, need to resve it ? */\n\t//split_memory_region(0x3b400000, 60 * 1024 * 1024, 0);\n}\n\nstatic struct platform platform_raspberry3 = {\n\t.name \t\t = \"raspberrypi,3-model-b-plus\",\n\t.cpu_on\t\t = spin_table_cpu_on,\n\t.system_reboot\t = raspberry3_system_reboot,\n\t.system_shutdown = raspberry3_system_shutdown,\n#ifdef CONFIG_VIRT\n\t.setup_hvm\t = raspberry3_setup_hvm,\n#endif\n\t.parse_mem_info  = raspberry3_parse_mem_info,\n\t.iomem_valid\t = raspberry4_iomem_valid,\n};\nDEFINE_PLATFORM(platform_raspberry3);\n"
  },
  {
    "path": "kernel/platform/raspberry4/Kconfig",
    "content": "if SOC_BCM2838\n\nconfig MINOS_ENTRY_ADDRESS\n\thex \"entry address of system\"\n\tdefault 0x37408000\n\thelp\n\t  the entry address is the start address plus\n\t  nr_cpus * TASK_STACK_SIZE\n\nconfig MINOS_RAM_SIZE\n\thex \"memory size for Minos\"\n\tdefault 0x4000000\n\trange 0x1000000 0x4000000\n\thelp\n\t  the memory size for Minos\n\nconfig NR_CPUS\n\tint \"number of cpu in system\"\n\tdefault 4\n\thelp\n\t  how many cpu in current system\n\nconfig UART_BASE\n\thex \"uart controller iomem base address\"\n\tdefault 0xfe215040\n\nconfig UART_IO_SIZE\n\thex \"uart controller iomem size\"\n\tdefault 0x1000\n\nendif\n"
  },
  {
    "path": "kernel/platform/raspberry4/Makefile",
    "content": "obj-y += raspberry4.o\n"
  },
  {
    "path": "kernel/platform/raspberry4/raspberry4.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <asm/arch.h>\n#include <asm/io.h>\n#include <libfdt/libfdt.h>\n#include <minos/of.h>\n#include <device/bcm_irq.h>\n#include <asm/power.h>\n#include <minos/platform.h>\n\n#ifdef CONFIG_VIRT\n#include <virt/virq.h>\n#include <virt/vm.h>\n#include <virt/vmm.h>\n#include <virt/vdev.h>\n\n#define BCM2838_RELEASE_ADDR\t0xff800000\n\nstatic int bcm2838_fake_scu_read(struct vdev *vdev, gp_regs *regs,\n\t\tint idx, unsigned long address, unsigned long *value)\n{\n\treturn 0;\n}\n\nstatic int inline bcm2838_bootup_secondary(struct vm *vm,\n\t\tint cpu, unsigned long entry)\n{\n\tif (cpu >= vm->vcpu_nr) {\n\t\tpr_err(\"no such vcpu vcpu-id:%d\\n\", cpu);\n\t\treturn -EINVAL;\n\t}\n\n\tif (cpu == 0)\n\t\treturn 0;\n\n\treturn vcpu_power_on(get_current_vcpu(),\n\t\t\tcpuid_to_affinity(cpu), entry, 0);\n}\n\nstatic int bcm2838_fake_64bit_scu_write(struct vdev *vdev, gp_regs *regs,\n\t\tint idx, unsigned long offset, unsigned long *value)\n{\n\tint cpu;\n\tstruct vm *vm = vdev->vm;\n\n\tif (offset % sizeof(uint64_t)) {\n\t\tpr_err(\"unsupport reg offset 0x%x\\n\", offset);\n\t\treturn -EINVAL;\n\t}\n\n\tcpu = offset / sizeof(uint64_t);\n\n\treturn bcm2838_bootup_secondary(vm, cpu, *value);\n}\n\nstatic int bcm2838_fake_32bit_scu_write(struct vdev *vdev, gp_regs *regs,\n\t\tint idx, unsigned long offset, unsigned long *value)\n{\n\tint cpu;\n\n\tcpu = (offset - LOCAL_MAILBOX3_SET0) >> 4;\n\n\treturn bcm2838_bootup_secondary(vdev->vm, cpu, *value);\n}\n\nstatic int raspberry4_setup_hvm(struct vm *vm, void *dtb)\n{\n\tint i, offset, node;\n\tchar name[16];\n\tuint64_t addr;\n\tuint64_t dtb_addr = 0;\n\tuint32_t *tmp = (uint32_t *)&dtb_addr;\n\tstruct vdev *vdev;\n\n\toffset = of_get_node_by_name(dtb, 0, \"cpus\");\n\tif (offset < 0) {\n\t\tpr_err(\"can not find vcpus node for hvm\\n\");\n\t\treturn -ENOENT;\n\t}\n\n\t/*\n\t * using spin table boot methold redirect the\n\t * relase addr to the interrupt controller space\n\t */\n\tfor (i = 0; i < vm->vcpu_nr; i++) {\n\t\tmemset(name, 0, 16);\n\t\tsprintf(name, \"cpu@%d\", i);\n\t\tnode = fdt_subnode_offset(dtb, offset, name);\n\t\tif (node <= 0)\n\t\t\tcontinue;\n\n\t\taddr = BCM2838_RELEASE_ADDR + i * sizeof(uint64_t);\n\t\tpr_notice(\"vcpu-%d release addr redirect to 0x%p\\n\", i, addr);\n\t\ttmp[0] = cpu_to_fdt32(addr >> 32);\n\t\ttmp[1] = cpu_to_fdt32(addr & 0xffffffff);\n\n\t\tfdt_setprop(dtb, node, \"cpu-release-addr\", (void *)tmp,\n\t\t\t\t2 * sizeof(uint32_t));\n\t}\n\n\t/* register a fake system controller for smp up handler */\n\tif (vm->vcpu_nr > 1) {\n\t\tvdev = zalloc(sizeof(struct vdev));\n\t\tif (!vdev)\n\t\t\tpanic(\"no more memory for spi-table\\n\");\n\n\t\thost_vdev_init(vm, vdev, \"smp-fake-con\");\n\t\tvdev_add_iomem_range(vdev, BCM2838_RELEASE_ADDR, 0x1000);\n\n\t\t/*\n\t\t * for raspberry4, currently kernel will use the local\n\t\t * interrupt IC base address to wake up other cpu in 32\n\t\t * bit mode, which is different with 64bit\n\t\t */\n\t\tvdev->read = bcm2838_fake_scu_read;\n\t\tif (vm->flags & VM_FLAGS_32BIT)\n\t\t\tvdev->write = bcm2838_fake_32bit_scu_write;\n\t\telse\n\t\t\tvdev->write = bcm2838_fake_64bit_scu_write;\n\t\tvdev_add(vdev);\n\t}\n\n\t/* create pcie address mapping for VM0 */\n\tcreate_guest_mapping(&vm->mm, 0x600000000, 0x600000000,\n\t\t\t0x4000000, VM_GUEST_IO | VM_RW);\n\n\tpr_notice(\"raspberry4 setup vm done\\n\");\n\n\treturn 0;\n}\n#endif\n\nstatic int raspberry4_iomem_valid(unsigned long addr)\n{\n\t/*\n\t * 0xff800000 ---> 0xff800fff will used for local_intc\n\t * in 32bit mode, kernel will use this address to wake\n\t * up other cpus\n\t */\n\tif ((addr >= 0xff800000) && (addr < 0xff800fff))\n\t\treturn 0;\n\n\t/*\n\t * 0x3b400000 ---> 0x3ebfffff will used for the framebuffer\n\t * in raspberry4\n\t */\n\tif ((addr >= 0x3b400000) && (addr < 0x3ebfffff))\n\t\treturn 1;\n\n\tif ((addr >= 0xf3000000) && (addr < 0xffffffff))\n\t\treturn 1;\n\n\tpr_err(\"memory region:0x%p not register\\n\", addr, addr);\n\n\treturn 0;\n}\n\nstatic void raspberry4_system_reboot(int mode, const char *cmd)\n{\n\n}\n\nstatic void raspberry4_system_shutdown(void)\n{\n\n}\n\n/*\n * VC FW passed below memory region to Linux kernel\n * 0x0\t\t- 0x3b3fffff\n * 0x40000000\t- 0xfc000000\n *\n * memory map get from vc FW and the cmdline is:\n * 0x0\t\t- 0x3b3fffff\t\t[Linux Memory]\n * 0x3b400000   - 0x3ebfffff\t\t[Unknown may be VC]\n * 0x3ec00000\t- 0x7ebfffff\t\t[VC memory]\n * 0x7ec00000   - 0xf2ffffff\t\t[Linux]\n *\n * need parse the right information to Linux kernel, from\n * the dtb just can get the first memory information, the\n * below is the memory map when using Minos Hypervisor\n *\n * 0x0\t\t- 0x373fffff\t\t[Linux Memeory]\n * 0x37400000\t- 0x3b3fffff@64M\t[Minos Memory]\n * 0x3b400000\t- 0x3ebfffff\t\t[Unknown Memory do not passed to Linux]\n * 0x3ec00000\t- 0x7ebfffff\t\t[Need to passed to Linux]\n */\nstatic void raspberry4_parse_mem_info(void)\n{\n\tint node, len;\n\tfdt32_t *v;\n\tunsigned long base, size;\n\n\t/*\n\t * need to parse other memory region to support 2G or 4G\n\t * rpi-4 version, currently, use a simple way, the memory\n\t * information will store in bootargs/extra-memory field in\n\t * minos device tree\n\t */\n\tif (!dtb_address)\n\t\treturn;\n\n\tnode = fdt_path_offset(dtb_address, \"/chosen\");\n\tif (node <= 0)\n\t\treturn;\n\n\tv = (fdt32_t *)fdt_getprop(dtb_address, node, \"extra-memory\", &len);\n\tif (!v || (len < 8))\n\t\treturn;\n\n\tlen = len / 4;\n\tif (len % 2 != 0) {\n\t\tpr_err(\"wrong memory config in extra-memory\\n\");\n\t\treturn;\n\t}\n\n\twhile (len > 0) {\n\t\tbase = fdt32_to_cpu(v[0]);\n\t\tsize = fdt32_to_cpu(v[1]);\n\n\t\tpr_notice(\"register extra memory region 0x%x 0x%x\\n\", base, size);\n\t\tadd_memory_region(base, size, MEMORY_REGION_TYPE_NORMAL, 0);\n\t\tlen -= 2;\n\t\tv += 2;\n\t}\n}\n\nstatic struct platform platform_raspberry4 = {\n\t.name \t\t = \"raspberrypi,4-model-b\",\n\t.cpu_on\t\t = spin_table_cpu_on,\n\t.system_reboot\t = raspberry4_system_reboot,\n\t.system_shutdown = raspberry4_system_shutdown,\n\t.iomem_valid\t = raspberry4_iomem_valid,\n#ifdef CONFIG_VIRT\n\t.setup_hvm\t = raspberry4_setup_hvm,\n#endif\n\t.parse_mem_info  = raspberry4_parse_mem_info,\n};\nDEFINE_PLATFORM(platform_raspberry4);\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/LICENSE.txt",
    "content": "Copyright (c) 2011-2019, Ulf Magnusson <ulfalizer@gmail.com>\n\nPermission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/MANIFEST.in",
    "content": "# Include the license file in source distributions\ninclude LICENSE.txt\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/README.rst",
    "content": ".. contents:: Table of contents\n   :backlinks: none\n\nNews\n----\n\nDependency loop with recent linux-next kernels\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nTo fix issues with dependency loops on recent linux-next kernels, apply `this\npatch <https://www.spinics.net/lists/linux-kbuild/msg23455.html>`_. Hopefully,\nit will be in ``linux-next`` soon.\n\n``windows-curses`` is no longer automatically installed on Windows\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nStarting with Kconfiglib 13.0.0, the `windows-curses\n<https://github.com/zephyrproject-rtos/windows-curses>`__ package is no longer\nautomatically installed on Windows, and needs to be installed manually for the\nterminal ``menuconfig`` to work.\n\nThis fixes installation of Kconfiglib on MSYS2, which is not compatible with\n``windows-curses``. See `this issue\n<https://github.com/ulfalizer/Kconfiglib/issues/77>`__.\n\nThe ``menuconfig`` now shows a hint re. installing ``windows-curses`` when the\n``curses`` module can't be imported on Windows.\n\nSorry if this change caused problems!\n\nOverview\n--------\n\nKconfiglib is a `Kconfig\n<https://github.com/torvalds/linux/blob/master/Documentation/kbuild/kconfig-language.rst>`__\nimplementation in Python 2/3. It started out as a helper library, but now has a\nenough functionality to also work well as a standalone Kconfig implementation\n(including `terminal and GUI menuconfig interfaces <Menuconfig interfaces_>`_\nand `Kconfig extensions`_).\n\nThe entire library is contained in `kconfiglib.py\n<https://github.com/ulfalizer/Kconfiglib/blob/master/kconfiglib.py>`_. The\nbundled scripts are implemented on top of it. Implementing your own scripts\nshould be relatively easy, if needed.\n\nKconfiglib is used exclusively by e.g. the `Zephyr\n<https://www.zephyrproject.org/>`__, `esp-idf\n<https://github.com/espressif/esp-idf>`__, and `ACRN\n<https://projectacrn.org/>`__ projects. It is also used for many small helper\nscripts in various projects.\n\nSince Kconfiglib is based around a library, it can be used e.g. to generate a\n`Kconfig cross-reference <https://docs.zephyrproject.org/latest/reference/kconfig/index.html>`_ (note: heavy page),\nusing the same robust Kconfig parser used for other Kconfig tools, instead of brittle ad-hoc parsing. The documentation generation script can be found `here <https://github.com/zephyrproject-rtos/zephyr/blob/master/doc/scripts/genrest.py>`__.\n\nKconfiglib implements the recently added `Kconfig preprocessor\n<https://github.com/torvalds/linux/blob/master/Documentation/kbuild/kconfig-macro-language.rst>`__.\nFor backwards compatibility, environment variables can be referenced both as\n``$(FOO)`` (the new syntax) and as ``$FOO`` (the old syntax). The old syntax is\ndeprecated, but will probably be supported for a long time, as it's needed to\nstay compatible with older Linux kernels. The major version will be increased\nif support is ever dropped. Using the old syntax with an undefined environment\nvariable keeps the string as is.\n\nNote: See `this issue <https://github.com/ulfalizer/Kconfiglib/issues/47>`__ if\nyou run into a \"macro expanded to blank string\" error with kernel 4.18+.\n\nSee `this page\n<https://docs.zephyrproject.org/latest/guides/kconfig/tips.html>`__ for some\nKconfig tips and best practices.\n\nInstallation\n------------\n\nInstallation with pip\n~~~~~~~~~~~~~~~~~~~~~\n\nKconfiglib is available on `PyPI <https://pypi.python.org/pypi/kconfiglib/>`_ and can be\ninstalled with e.g.\n\n.. code::\n\n    $ pip(3) install kconfiglib\n\nMicrosoft Windows is supported.\n\nThe ``pip`` installation will give you both the base library and the following\nexecutables. All but two (``genconfig`` and ``setconfig``) mirror functionality\navailable in the C tools.\n\n- `menuconfig <https://github.com/ulfalizer/Kconfiglib/blob/master/menuconfig.py>`_\n\n- `guiconfig <https://github.com/ulfalizer/Kconfiglib/blob/master/guiconfig.py>`_\n\n- `oldconfig <https://github.com/ulfalizer/Kconfiglib/blob/master/oldconfig.py>`_\n\n- `olddefconfig <https://github.com/ulfalizer/Kconfiglib/blob/master/olddefconfig.py>`_\n\n- `savedefconfig <https://github.com/ulfalizer/Kconfiglib/blob/master/savedefconfig.py>`_\n\n- `defconfig <https://github.com/ulfalizer/Kconfiglib/blob/master/defconfig.py>`_\n\n- `alldefconfig <https://github.com/ulfalizer/Kconfiglib/blob/master/alldefconfig.py>`_\n\n- `allnoconfig <https://github.com/ulfalizer/Kconfiglib/blob/master/allnoconfig.py>`_\n\n- `allmodconfig <https://github.com/ulfalizer/Kconfiglib/blob/master/allmodconfig.py>`_\n\n- `allyesconfig <https://github.com/ulfalizer/Kconfiglib/blob/master/allyesconfig.py>`_\n\n- `listnewconfig <https://github.com/ulfalizer/Kconfiglib/blob/master/listnewconfig.py>`_\n\n- `genconfig <https://github.com/ulfalizer/Kconfiglib/blob/master/genconfig.py>`_\n\n- `setconfig <https://github.com/ulfalizer/Kconfiglib/blob/master/setconfig.py>`_\n\n``genconfig`` is intended to be run at build time. It generates a C header from\nthe configuration and (optionally) information that can be used to rebuild only\nfiles that reference Kconfig symbols that have changed value.\n\nStarting with Kconfiglib version 12.2.0, all utilities are compatible with both\nPython 2 and Python 3. Previously, ``menuconfig.py`` only ran under Python 3\n(i.e., it's now more backwards compatible than before).\n\n**Note:** If you install Kconfiglib with ``pip``'s ``--user`` flag, make sure\nthat your ``PATH`` includes the directory where the executables end up. You can\nlist the installed files with ``pip(3) show -f kconfiglib``.\n\nAll releases have a corresponding tag in the git repository, e.g. ``v13.7.0``\n(the latest version).\n\n`Semantic versioning <http://semver.org/>`_ is used. There's been\nten small changes to the behavior of the API and a Windows packaging change\n(`1 <https://github.com/ulfalizer/Kconfiglib/commit/e8b4ecb6ff6ccc1c7be0818314fbccda2ef2b2ee>`_,\n`2 <https://github.com/ulfalizer/Kconfiglib/commit/db633015a4d7b0ba1e882f665e191f350932b2af>`_,\n`3 <https://github.com/ulfalizer/Kconfiglib/commit/8983f7eb297dd614faf0beee3129559bc8ba338e>`_,\n`4 <https://github.com/ulfalizer/Kconfiglib/commit/cbf32e29a130d22bc734b7778e6304ac9df2a3e8>`_,\n`5 <https://github.com/ulfalizer/Kconfiglib/commit/eb6c21a9b33a2d6e2bed9882d4f930d0cab2f03b>`_,\n`6 <https://github.com/ulfalizer/Kconfiglib/commit/c19fc11355b13d75d97286402c7a933fb23d3b70>`_,\n`7 <https://github.com/ulfalizer/Kconfiglib/commit/7a428aa415606820a44291f475248b08e3952c4b>`_,\n`8 <https://github.com/ulfalizer/Kconfiglib/commit/f247ddf618ad29718e5efd3e69f8baf75d4d347b>`_,\n`9 <https://github.com/ulfalizer/Kconfiglib/commit/4fed39d9271ceb68be4157ab3f96a45b94f77dc0>`_,\n`10 <https://github.com/ulfalizer/Kconfiglib/commit/55bc8c380869ea663092212e8fe388ad7abae596>`_,\n`packaging change <https://github.com/ulfalizer/Kconfiglib/commit/21b4c1e3b6e2867b9a0788d21a358f6b1f581d86>`_),\nwhich is why the major version is at 13 rather than 2. I do major version bumps\nfor all behavior changes, even tiny ones, and most of these were fixes for baby\nissues in the early days of the Kconfiglib 2 API.\n\nManual installation\n~~~~~~~~~~~~~~~~~~~\n\nJust drop ``kconfiglib.py`` and the scripts you want somewhere. There are no\nthird-party dependencies, but the terminal ``menuconfig`` won't work on Windows\nunless a package like `windows-curses\n<https://github.com/zephyrproject-rtos/windows-curses>`__ is installed.\n\nInstallation for the Linux kernel\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nSee the module docstring at the top of `kconfiglib.py <https://github.com/ulfalizer/Kconfiglib/blob/master/kconfiglib.py>`_.\n\nPython version compatibility (2.7/3.2+)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nKconfiglib and all utilities run under both Python 2.7 and Python 3.2 and\nlater. The code mostly uses basic Python features and has no third-party\ndependencies, so keeping it backwards-compatible is pretty low effort.\n\nThe 3.2 requirement comes from ``argparse``. ``format()`` with unnumbered\n``{}`` is used as well.\n\nA recent Python 3 version is recommended if you have a choice, as it'll give\nyou better Unicode handling.\n\nGetting started\n---------------\n\n1. `Install <Installation_>`_ the library and the utilities.\n\n2. Write `Kconfig\n   <https://github.com/torvalds/linux/blob/master/Documentation/kbuild/kconfig-language.rst>`__\n   files that describe the available configuration options. See `this page\n   <https://docs.zephyrproject.org/latest/guides/kconfig/tips.html>`__ for some\n   general Kconfig advice.\n\n3. Generate an initial configuration with e.g. ``menuconfig``/``guiconfig`` or\n   ``alldefconfig``. The configuration is saved as ``.config`` by default.\n\n   For more advanced projects, the ``defconfig`` utility can be used to\n   generate the initial configuration from an existing configuration file.\n   Usually, this existing configuration file would be a minimal configuration\n   file, as generated by e.g. ``savedefconfig``.\n\n4. Run ``genconfig`` to generate a header file. By default, it is saved as\n   ``config.h``.\n\n   Normally, ``genconfig`` would be run automatically as part of the build.\n\n   Before writing a header file or other configuration output, Kconfiglib\n   compares the old contents of the file against the new contents. If there's\n   no change, the write is skipped. This avoids updating file metadata like the\n   modification time, and might save work depending on your build setup.\n\n   Adding new configuration output formats should be relatively straightforward.\n   See the implementation of ``write_config()`` in `kconfiglib.py\n   <https://github.com/ulfalizer/Kconfiglib/blob/master/kconfiglib.py>`_.\n   The documentation for the ``Symbol.config_string`` property has some tips as\n   well.\n\n5. To update an old ``.config`` file after the Kconfig files have changed (e.g.\n   to add new options), run ``oldconfig`` (prompts for values for new options)\n   or ``olddefconfig`` (gives new options their default value). Entering the\n   ``menuconfig`` or ``guiconfig`` interface and saving the configuration will\n   also update it (the configuration interfaces always prompt for saving\n   on exit if it would modify the contents of the ``.config`` file).\n\n   Due to Kconfig semantics, simply loading an old ``.config`` file performs an\n   implicit ``olddefconfig``, so building will normally not be affected by\n   having an outdated configuration.\n\nWhenever ``.config`` is overwritten, the previous version of the file is saved\nto ``.config.old`` (or, more generally, to ``$KCONFIG_CONFIG.old``).\n\nUsing ``.config`` files as Make input\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n``.config`` files use Make syntax and can be included directly in Makefiles to\nread configuration values from there. This is why ``n``-valued\n``bool``/``tristate`` values are written out as ``# CONFIG_FOO is not set`` (a\nMake comment) in ``.config``, allowing them to be tested with ``ifdef`` in\nMake.\n\nIf you make use of this, you might want to pass ``--config-out <filename>`` to\n``genconfig`` and include the configuration file it generates instead of\nincluding ``.config`` directly. This has the advantage that the generated\nconfiguration file will always be a \"full\" configuration file, even if\n``.config`` is outdated. Otherwise, it might be necessary to run\n``old(def)config`` or ``menuconfig``/``guiconfig`` before rebuilding with an\noutdated ``.config``.\n\nIf you use ``--sync-deps`` to generate incremental build information, you can\ninclude ``deps/auto.conf`` instead, which is also a full configuration file.\n\nUseful helper macros\n~~~~~~~~~~~~~~~~~~~~\n\nThe `include/linux/kconfig.h\n<https://github.com/torvalds/linux/blob/master/include/linux/kconfig.h>`_\nheader in the Linux kernel defines some useful helper macros for testing\nKconfig configuration values.\n\n``IS_ENABLED()`` is generally useful, allowing configuration values to be\ntested in ``if`` statements with no runtime overhead.\n\nIncremental building\n~~~~~~~~~~~~~~~~~~~~\n\nSee the docstring for ``Kconfig.sync_deps()`` in `kconfiglib.py\n<https://github.com/ulfalizer/Kconfiglib/blob/master/kconfiglib.py>`_ for hints\non implementing incremental builds (rebuilding just source files that reference\nchanged configuration values).\n\nRunning the ``scripts/basic/fixdep.c`` tool from the kernel on the output of\n``gcc -MD <source file>`` might give you an idea of how it all fits together.\n\nLibrary documentation\n---------------------\n\nKconfiglib comes with extensive documentation in the form of docstrings. To view it, run e.g.\nthe following command:\n\n.. code:: sh\n\n    $ pydoc(3) kconfiglib\n\nFor HTML output, add ``-w``:\n\n.. code:: sh\n\n    $ pydoc(3) -w kconfiglib\n\nThis will also work after installing Kconfiglib with ``pip(3)``.\n\nDocumentation for other modules can be viewed in the same way (though a plain\n``--help`` will work when they're run as executables):\n\n.. code:: sh\n\n    $ pydoc(3) menuconfig/guiconfig/...\n\nA good starting point for learning the library is to read the module docstring\n(which you could also just read directly at the beginning of `kconfiglib.py\n<https://github.com/ulfalizer/Kconfiglib/blob/master/kconfiglib.py>`_). It\ngives an introduction to symbol values, the menu tree, and expressions.\n\nAfter reading the module docstring, a good next step is to read the ``Kconfig``\nclass documentation, and then the documentation for the ``Symbol``, ``Choice``,\nand ``MenuNode`` classes.\n\nPlease tell me if something is unclear or can be explained better.\n\nLibrary features\n----------------\n\nKconfiglib can do the following, among other things:\n\n- **Programmatically get and set symbol values**\n\n  See `allnoconfig.py\n  <https://github.com/ulfalizer/Kconfiglib/blob/master/allnoconfig.py>`_ and\n  `allyesconfig.py\n  <https://github.com/ulfalizer/Kconfiglib/blob/master/allyesconfig.py>`_,\n  which are automatically verified to produce identical output to the standard\n  ``make allnoconfig`` and ``make allyesconfig``.\n\n- **Read and write .config and defconfig files**\n\n  The generated ``.config`` and ``defconfig`` (minimal configuration) files are\n  character-for-character identical to what the C implementation would generate\n  (except for the header comment). The test suite relies on this, as it\n  compares the generated files.\n\n- **Write C headers**\n\n  The generated headers use the same format as ``include/generated/autoconf.h``\n  from the Linux kernel. Output for symbols appears in the order that they're\n  defined, unlike in the C tools (where the order depends on the hash table\n  implementation).\n\n- **Implement incremental builds**\n\n  This uses the same scheme as the ``include/config`` directory in the kernel:\n  Symbols are translated into files that are touched when the symbol's value\n  changes between builds, which can be used to avoid having to do a full\n  rebuild whenever the configuration is changed.\n\n  See the ``sync_deps()`` function for more information.\n\n- **Inspect symbols**\n\n  Printing a symbol or other item (which calls ``__str__()``) returns its\n  definition in Kconfig format. This also works for symbols defined in multiple\n  locations.\n\n  A helpful ``__repr__()`` is  on all objects too.\n\n  All ``__str__()`` and ``__repr__()`` methods are deliberately implemented\n  with just public APIs, so all symbol information can be fetched separately as\n  well.\n\n- **Inspect expressions**\n\n  Expressions use a simple tuple-based format that can be processed manually\n  if needed. Expression printing and evaluation functions are provided,\n  implemented with public APIs.\n\n- **Inspect the menu tree**\n\n  The underlying menu tree is exposed, including submenus created implicitly\n  from symbols depending on preceding symbols. This can be used e.g. to\n  implement menuconfig-like functionality.\n\n  See `menuconfig.py\n  <https://github.com/ulfalizer/Kconfiglib/blob/master/menuconfig.py>`_/`guiconfig.py\n  <https://github.com/ulfalizer/Kconfiglib/blob/master/guiconfig.py>`_ and the\n  minimalistic `menuconfig_example.py\n  <https://github.com/ulfalizer/Kconfiglib/blob/master/examples/menuconfig_example.py>`_\n  example.\n\nKconfig extensions\n~~~~~~~~~~~~~~~~~~\n\nThe following Kconfig extensions are available:\n\n- ``source`` supports glob patterns and includes each matching file. A pattern\n  is required to match at least one file.\n\n  A separate ``osource`` statement is available for cases where it's okay for\n  the pattern to match no files (in which case ``osource`` turns into a no-op).\n\n- A relative ``source`` statement (``rsource``) is available, where file paths\n  are specified relative to the directory of the current Kconfig file. An\n  ``orsource`` statement is available as well, analogous to ``osource``.\n\n- Preprocessor user functions can be defined in Python, which makes it simple\n  to integrate information from existing Python tools into Kconfig (e.g. to\n  have Kconfig symbols depend on hardware information stored in some other\n  format).\n\n  See the *Kconfig extensions* section in the\n  `kconfiglib.py <https://github.com/ulfalizer/Kconfiglib/blob/master/kconfiglib.py>`_\n  module docstring for more information.\n\n- ``def_int``, ``def_hex``, and ``def_string`` are available in addition to\n  ``def_bool`` and ``def_tristate``, allowing ``int``, ``hex``, and ``string``\n  symbols to be given a type and a default at the same time.\n\n  These can be useful in projects that make use of symbols defined in multiple\n  locations, and remove some Kconfig inconsistency.\n\n- Environment variables are expanded directly in e.g. ``source`` and\n  ``mainmenu`` statements, meaning ``option env`` symbols are redundant.\n\n  This is the standard behavior with the new `Kconfig preprocessor\n  <https://github.com/torvalds/linux/blob/master/Documentation/kbuild/kconfig-macro-language.rst>`__,\n  which Kconfiglib implements.\n\n  ``option env`` symbols are accepted but ignored, which leads the caveat that\n  they must have the same name as the environment variables they reference\n  (Kconfiglib warns if the names differ). This keeps Kconfiglib compatible with\n  older Linux kernels, where the name of the ``option env`` symbol always\n  matched the environment variable. Compatibility with older Linux kernels is\n  the main reason ``option env`` is still supported.\n\n  The C tools have dropped support for ``option env``.\n\n- Two extra optional warnings can be enabled by setting environment variables,\n  covering cases that are easily missed when making changes to Kconfig files:\n\n  * ``KCONFIG_WARN_UNDEF``: If set to ``y``, warnings will be generated for all\n    references to undefined symbols within Kconfig files. The only gotcha is\n    that all hex literals must be prefixed with ``0x`` or ``0X``, to make it\n    possible to distinguish them from symbol references.\n\n    Some projects (e.g. the Linux kernel) use multiple Kconfig trees with many\n    shared Kconfig files, leading to some safe undefined symbol references.\n    ``KCONFIG_WARN_UNDEF`` is useful in projects that only have a single\n    Kconfig tree though.\n\n    ``KCONFIG_STRICT`` is an older alias for this environment variable,\n    supported for backwards compatibility.\n\n  * ``KCONFIG_WARN_UNDEF_ASSIGN``: If set to ``y``, warnings will be generated\n    for all assignments to undefined symbols within ``.config`` files. By\n    default, no such warnings are generated.\n\n    This warning can also be enabled/disabled by setting\n    ``Kconfig.warn_assign_undef`` to ``True``/``False``.\n\nOther features\n--------------\n\n- **Single-file implementation**\n\n  The entire library is contained in `kconfiglib.py\n  <https://github.com/ulfalizer/Kconfiglib/blob/master/kconfiglib.py>`_.\n\n  The tools implemented on top of it are one file each.\n\n- **Robust and highly compatible with the C Kconfig tools**\n\n  The `test suite <https://github.com/ulfalizer/Kconfiglib/blob/master/testsuite.py>`_\n  automatically compares output from Kconfiglib and the C tools\n  by diffing the generated ``.config`` files for the real kernel Kconfig and\n  defconfig files, for all ARCHes.\n\n  This currently involves comparing the output for 36 ARCHes and 498 defconfig\n  files (or over 18000 ARCH/defconfig combinations in \"obsessive\" test suite\n  mode). All tests are expected to pass.\n\n  A comprehensive suite of selftests is included as well.\n\n- **Not horribly slow despite being a pure Python implementation**\n\n  The `allyesconfig.py\n  <https://github.com/ulfalizer/Kconfiglib/blob/master/allyesconfig.py>`_\n  script currently runs in about 1.3 seconds on the Linux kernel on a Core i7\n  2600K (with a warm file cache), including the ``make`` overhead from ``make\n  scriptconfig``. Note that the Linux kernel Kconfigs are absolutely massive\n  (over 14k symbols for x86) compared to most projects, and also have overhead\n  from running shell commands via the Kconfig preprocessor.\n\n  Kconfiglib is especially speedy in cases where multiple ``.config`` files\n  need to be processed, because the ``Kconfig`` files will only need to be parsed\n  once.\n\n  For long-running jobs, `PyPy <https://pypy.org/>`_ gives a big performance\n  boost. CPython is faster for short-running jobs as PyPy needs some time to\n  warm up.\n\n  Kconfiglib also works well with the\n  `multiprocessing <https://docs.python.org/3/library/multiprocessing.html>`_\n  module. No global state is kept.\n\n- **Generates more warnings than the C implementation**\n\n  Generates the same warnings as the C implementation, plus additional ones.\n  Also detects dependency and ``source`` loops.\n\n  All warnings point out the location(s) in the ``Kconfig`` files where a\n  symbol is defined, where applicable.\n\n- **Unicode support**\n\n  Unicode characters in string literals in ``Kconfig`` and ``.config`` files are\n  correctly handled. This support mostly comes for free from Python.\n\n- **Windows support**\n\n  Nothing Linux-specific is used. Universal newlines mode is used for both\n  Python 2 and Python 3.\n\n  The `Zephyr <https://www.zephyrproject.org/>`_ project uses Kconfiglib to\n  generate ``.config`` files and C headers on Linux as well as Windows.\n\n- **Internals that (mostly) mirror the C implementation**\n\n  While being simpler to understand and tweak.\n\nMenuconfig interfaces\n---------------------\n\nThree configuration interfaces are currently available:\n\n- `menuconfig.py <https://github.com/ulfalizer/Kconfiglib/blob/master/menuconfig.py>`_\n  is a terminal-based configuration interface implemented using the standard\n  Python ``curses`` module. ``xconfig`` features like showing invisible symbols and\n  showing symbol names are included, and it's possible to jump directly to a symbol\n  in the menu tree (even if it's currently invisible).\n\n  .. image:: https://raw.githubusercontent.com/ulfalizer/Kconfiglib/screenshots/screenshots/menuconfig.gif\n\n  *There is now also a show-help mode that shows the help text of the currently\n  selected symbol in the help window at the bottom.*\n\n  Starting with Kconfiglib 12.2.0, ``menuconfig.py`` runs under both Python 2\n  and Python 3 (previously, it only ran under Python 3, so this was a\n  backport). Running it under Python 3 provides better support for Unicode text\n  entry (``get_wch()`` is not available in the ``curses`` module on Python 2).\n\n  There are no third-party dependencies on \\*nix. On Windows,\n  the ``curses`` modules is not available by default, but support\n  can be added by installing the ``windows-curses`` package:\n\n  .. code-block:: shell\n\n      $ pip install windows-curses\n\n  This uses wheels built from `this repository\n  <https://github.com/zephyrproject-rtos/windows-curses>`_, which is in turn\n  based on Christoph Gohlke's `Python Extension Packages for Windows\n  <https://www.lfd.uci.edu/~gohlke/pythonlibs/#curses>`_.\n\n  See the docstring at the top of `menuconfig.py\n  <https://github.com/ulfalizer/Kconfiglib/blob/master/menuconfig.py>`_ for\n  more information about the terminal menuconfig implementation.\n\n- `guiconfig.py\n  <https://github.com/ulfalizer/Kconfiglib/blob/master/guiconfig.py>`_ is a\n  graphical configuration interface written in `Tkinter\n  <https://docs.python.org/3/library/tkinter.html>`_. Like ``menuconfig.py``,\n  it supports showing all symbols (with invisible symbols in red) and jumping\n  directly to symbols. Symbol values can also be changed directly from the\n  jump-to dialog.\n\n  When single-menu mode is enabled, a single menu is shown at a time, like in\n  the terminal menuconfig. Only this mode distinguishes between symbols defined\n  with ``config`` and symbols defined with ``menuconfig``.\n\n  ``guiconfig.py`` has been tested on X11, Windows, and macOS, and is\n  compatible with both Python 2 and Python 3.\n\n  Despite being part of the Python standard library, ``tkinter`` often isn't\n  included by default in Python installations on Linux. These commands will\n  install it on a few different distributions:\n\n  - Ubuntu: ``sudo apt install python-tk``/``sudo apt install python3-tk``\n\n  - Fedora: ``dnf install python2-tkinter``/``dnf install python3-tkinter``\n\n  - Arch: ``sudo pacman -S tk``\n\n  - Clear Linux: ``sudo swupd bundle-add python3-tcl``\n\n  Screenshot below, with show-all mode enabled and the jump-to dialog open:\n\n  .. image:: https://raw.githubusercontent.com/ulfalizer/Kconfiglib/screenshots/screenshots/guiconfig.png\n\n  To avoid having to carry around a bunch of GIFs, the image data is embedded\n  in ``guiconfig.py``. To use separate GIF files instead, change\n  ``_USE_EMBEDDED_IMAGES`` to ``False`` in ``guiconfig.py``. The image files\n  can be found in the `screenshots\n  <https://github.com/ulfalizer/Kconfiglib/tree/screenshots/guiconfig>`_\n  branch.\n\n  I did my best with the images, but some are definitely only art adjacent.\n  Touch-ups are welcome. :)\n\n- `pymenuconfig <https://github.com/RomaVis/pymenuconfig>`_, built by `RomaVis\n  <https://github.com/RomaVis>`_, is an older portable Python 2/3 TkInter\n  menuconfig implementation.\n\n  Screenshot below:\n\n  .. image:: https://raw.githubusercontent.com/RomaVis/pymenuconfig/master/screenshot.PNG\n\n  While working on the terminal menuconfig implementation, I added a few APIs\n  to Kconfiglib that turned out to be handy. ``pymenuconfig`` predates\n  ``menuconfig.py`` and ``guiconfig.py``, and so didn't have them available.\n  Blame me for any workarounds.\n\nExamples\n--------\n\nExample scripts\n~~~~~~~~~~~~~~~\n\nThe `examples/ <https://github.com/ulfalizer/Kconfiglib/blob/master/examples>`_ directory contains some simple example scripts. Among these are the following ones. Make sure you run them with the latest version of Kconfiglib, as they might make use of newly added features.\n\n- `eval_expr.py <https://github.com/ulfalizer/Kconfiglib/blob/master/examples/eval_expr.py>`_ evaluates an expression in the context of a configuration.\n\n- `find_symbol.py <https://github.com/ulfalizer/Kconfiglib/blob/master/examples/find_symbol.py>`_ searches through expressions to find references to a symbol, also printing a \"backtrace\" with parents for each reference found.\n\n- `help_grep.py <https://github.com/ulfalizer/Kconfiglib/blob/master/examples/help_grep.py>`_ searches for a string in all help texts.\n\n- `print_tree.py <https://github.com/ulfalizer/Kconfiglib/blob/master/examples/print_tree.py>`_ prints a tree of all configuration items.\n\n- `print_config_tree.py <https://github.com/ulfalizer/Kconfiglib/blob/master/examples/print_config_tree.py>`_ is similar to ``print_tree.py``, but dumps the tree as it would appear in ``menuconfig``, including values. This can be handy for visually diffing between ``.config`` files and different versions of ``Kconfig`` files.\n\n- `list_undefined.py <https://github.com/ulfalizer/Kconfiglib/blob/master/examples/list_undefined.py>`_ finds references to symbols that are not defined by any architecture in the Linux kernel.\n\n- `merge_config.py <https://github.com/ulfalizer/Kconfiglib/blob/master/examples/merge_config.py>`_ merges configuration fragments to produce a complete .config, similarly to ``scripts/kconfig/merge_config.sh`` from the kernel.\n\n- `menuconfig_example.py <https://github.com/ulfalizer/Kconfiglib/blob/master/examples/menuconfig_example.py>`_ implements a configuration interface that uses notation similar to ``make menuconfig``. It's deliberately kept as simple as possible to demonstrate just the core concepts.\n\nReal-world examples\n~~~~~~~~~~~~~~~~~~~\n\n- `kconfig.py\n  <https://github.com/zephyrproject-rtos/zephyr/blob/master/scripts/kconfig/kconfig.py>`_\n  from the `Zephyr <https://www.zephyrproject.org/>`_ project handles\n  ``.config`` and header file generation, also doing configuration fragment\n  merging\n\n- `genrest.py\n  <https://github.com/zephyrproject-rtos/zephyr/blob/master/doc/scripts/genrest.py>`_\n  generates a Kconfig symbol cross-reference, which can be viewed `here\n  <http://docs.zephyrproject.org/reference/kconfig/index.html>`__\n\n- `CMake and IDE integration\n  <https://github.com/espressif/esp-idf/tree/master/tools/kconfig_new>`_ from\n  the ESP-IDF project, via a configuration server program.\n\n- `A script for turning on USB-related options\n  <https://github.com/google/syzkaller/blob/master/dashboard/config/kconfiglib-merge-usb-configs.py>`_,\n  from the `syzkaller <https://github.com/google/syzkaller>`_ project.\n\n- `Various automated checks\n  <https://github.com/zephyrproject-rtos/ci-tools/blob/master/scripts/check_compliance.py>`_,\n  including a check for references to undefined Kconfig symbols in source code.\n  See the ``KconfigCheck`` class.\n\n- `Various utilities\n  <https://github.com/projectacrn/acrn-hypervisor/tree/master/scripts/kconfig>`_\n  from the `ACRN <https://projectacrn.org/>`_ project\n\nThese use the older Kconfiglib 1 API, which was clunkier and not as general\n(functions instead of properties, no direct access to the menu structure or\nproperties, uglier ``__str__()`` output):\n\n- `genboardscfg.py <http://git.denx.de/?p=u-boot.git;a=blob;f=tools/genboardscfg.py;hb=HEAD>`_ from `Das U-Boot <http://www.denx.de/wiki/U-Boot>`_ generates some sort of legacy board database by pulling information from a newly added Kconfig-based configuration system (as far as I understand it :).\n\n- `gen-manual-lists.py <https://git.busybox.net/buildroot/tree/support/scripts/gen-manual-lists.py?id=5676a2deea896f38123b99781da0a612865adeb0>`_ generated listings for an appendix in the `Buildroot <https://buildroot.org>`_ manual. (The listing has since been removed.)\n\n- `gen_kconfig_doc.py <https://github.com/espressif/esp-idf/blob/master/docs/gen-kconfig-doc.py>`_ from the `esp-idf <https://github.com/espressif/esp-idf>`_ project generates documentation from Kconfig files.\n\n- `SConf <https://github.com/CoryXie/SConf>`_ builds an interactive configuration interface (like ``menuconfig``) on top of Kconfiglib, for use e.g. with `SCons <scons.org>`_.\n\n- `kconfig-diff.py <https://gist.github.com/dubiousjim/5638961>`_ -- a script by `dubiousjim <https://github.com/dubiousjim>`_ that compares kernel configurations.\n\n- Originally, Kconfiglib was used in chapter 4 of my `master's thesis <http://liu.diva-portal.org/smash/get/diva2:473038/FULLTEXT01.pdf>`_ to automatically generate a \"minimal\" kernel for a given system. Parts of it bother me a bit now, but that's how it goes with old work.\n\nSample ``make iscriptconfig`` session\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe following log should give some idea of the functionality available in the API:\n\n.. code-block::\n\n    $ make iscriptconfig\n    A Kconfig instance 'kconf' for the architecture x86 has been created.\n    >>> kconf  # Calls Kconfig.__repr__()\n    <configuration with 13711 symbols, main menu prompt \"Linux/x86 4.14.0-rc7 Kernel Configuration\", srctree \".\", config symbol prefix \"CONFIG_\", warnings enabled, undef. symbol assignment warnings disabled>\n    >>> kconf.mainmenu_text  # Expanded main menu text\n    'Linux/x86 4.14.0-rc7 Kernel Configuration'\n    >>> kconf.top_node  # The implicit top-level menu\n    <menu node for menu, prompt \"Linux/x86 4.14.0-rc7 Kernel Configuration\" (visibility y), deps y, 'visible if' deps y, has child, Kconfig:5>\n    >>> kconf.top_node.list  # First child menu node\n    <menu node for symbol SRCARCH, deps y, has next, Kconfig:7>\n    >>> print(kconf.top_node.list)  # Calls MenuNode.__str__()\n    config SRCARCH\n\tstring\n\toption env=\"SRCARCH\"\n\tdefault \"x86\"\n    >>> sym = kconf.top_node.list.next.item  # Item contained in next menu node\n    >>> print(sym)  # Calls Symbol.__str__()\n    config 64BIT\n\tbool \"64-bit kernel\" if ARCH = \"x86\"\n\tdefault ARCH != \"i386\"\n\thelp\n\t  Say yes to build a 64-bit kernel - formerly known as x86_64\n\t  Say no to build a 32-bit kernel - formerly known as i386\n    >>> sym  # Calls Symbol.__repr__()\n    <symbol 64BIT, bool, \"64-bit kernel\", value y, visibility y, direct deps y, arch/x86/Kconfig:2>\n    >>> sym.assignable  # Currently assignable values (0, 1, 2 = n, m, y)\n    (0, 2)\n    >>> sym.set_value(0)  # Set it to n\n    True\n    >>> sym.tri_value  # Check the new value\n    0\n    >>> sym = kconf.syms[\"X86_MPPARSE\"]  # Look up symbol by name\n    >>> print(sym)\n    config X86_MPPARSE\n\tbool \"Enable MPS table\" if (ACPI || SFI) && X86_LOCAL_APIC\n\tdefault y if X86_LOCAL_APIC\n\thelp\n\t  For old smp systems that do not have proper acpi support. Newer systems\n\t  (esp with 64bit cpus) with acpi support, MADT and DSDT will override it\n    >>> default = sym.defaults[0]  # Fetch its first default\n    >>> sym = default[1]  # Fetch the default's condition (just a Symbol here)\n    >>> print(sym)\n    config X86_LOCAL_APIC\n\tbool\n\tdefault y\n\tselect IRQ_DOMAIN_HIERARCHY\n\tselect PCI_MSI_IRQ_DOMAIN if PCI_MSI\n\tdepends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_APIC || PCI_MSI\n    >>> sym.nodes  # Show the MenuNode(s) associated with it\n    [<menu node for symbol X86_LOCAL_APIC, deps n, has next, arch/x86/Kconfig:1015>]\n    >>> kconfiglib.expr_str(sym.defaults[0][1])  # Print the default's condition\n    'X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_APIC || PCI_MSI'\n    >>> kconfiglib.expr_value(sym.defaults[0][1])  # Evaluate it (0 = n)\n    0\n    >>> kconf.syms[\"64BIT\"].set_value(2)\n    True\n    >>> kconfiglib.expr_value(sym.defaults[0][1])  # Evaluate it again (2 = y)\n    2\n    >>> kconf.write_config(\"myconfig\")  # Save a .config\n    >>> ^D\n    $ cat myconfig\n    # Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)\n    CONFIG_64BIT=y\n    CONFIG_X86_64=y\n    CONFIG_X86=y\n    CONFIG_INSTRUCTION_DECODER=y\n    CONFIG_OUTPUT_FORMAT=\"elf64-x86-64\"\n    CONFIG_ARCH_DEFCONFIG=\"arch/x86/configs/x86_64_defconfig\"\n    CONFIG_LOCKDEP_SUPPORT=y\n    CONFIG_STACKTRACE_SUPPORT=y\n    CONFIG_MMU=y\n    ...\n\nTest suite\n----------\n\nThe test suite is run with\n\n.. code::\n\n    $ python(3) Kconfiglib/testsuite.py\n\n`pypy <https://pypy.org/>`_ works too, and is much speedier for everything except ``allnoconfig.py``/``allnoconfig_simpler.py``/``allyesconfig.py``, where it doesn't have time to warm up since\nthe scripts are run via ``make scriptconfig``.\n\nThe test suite must be run from the top-level kernel directory. It requires that the\nKconfiglib git repository has been cloned into it and that the makefile patch has been applied.\n\nTo get rid of warnings generated for the kernel ``Kconfig`` files, add ``2>/dev/null`` to the command to\ndiscard ``stderr``.\n\n**NOTE: Forgetting to apply the Makefile patch will cause some tests that compare generated configurations to fail**\n\n**NOTE: The test suite overwrites .config in the kernel root, so make sure to back it up.**\n\nThe test suite consists of a set of selftests and a set of compatibility tests that\ncompare configurations generated by Kconfiglib with\nconfigurations generated by the C tools, for a number of cases. See\n`testsuite.py <https://github.com/ulfalizer/Kconfiglib/blob/master/testsuite.py>`_\nfor the available options.\n\nThe `tests/reltest <https://github.com/ulfalizer/Kconfiglib/blob/master/tests/reltest>`_ script runs the test suite\nand all the example scripts for both Python 2 and Python 3, verifying that everything works.\n\nRarely, the output from the C tools is changed slightly (most recently due to a\n`change <https://www.spinics.net/lists/linux-kbuild/msg17074.html>`_ I added).\nIf you get test suite failures, try running the test suite again against the\n`linux-next tree <https://www.kernel.org/doc/man-pages/linux-next.html>`_,\nwhich has all the latest changes. I will make it clear if any\nnon-backwards-compatible changes appear.\n\nA lot of time is spent waiting around for ``make`` and the C utilities (which need to reparse all the\nKconfig files for each defconfig test). Adding some multiprocessing to the test suite would make sense\ntoo.\n\nNotes\n-----\n\n* This is version 2 of Kconfiglib, which is not backwards-compatible with\n  Kconfiglib 1. A summary of changes between Kconfiglib 1 and Kconfiglib\n  2 can be found `here\n  <https://github.com/ulfalizer/Kconfiglib/blob/screenshots/kconfiglib-2-changes.txt>`__.\n\n* I sometimes see people add custom output formats, which is pretty\n  straightforward to do (see the implementations of ``write_autoconf()`` and\n  ``write_config()`` for a template, and also the documentation of the\n  ``Symbol.config_string`` property). If you come up with something you think\n  might be useful to other people, I'm happy to take it in upstream. Batteries\n  included and all that.\n\n* Kconfiglib assumes the modules symbol is ``MODULES``, which is backwards-compatible.\n  A warning is printed by default if ``option modules`` is set on some other symbol.\n\n  Let me know if you need proper ``option modules`` support. It wouldn't be that\n  hard to add.\n\nThanks\n------\n\n- To `RomaVis <https://github.com/RomaVis>`_, for making\n  `pymenuconfig <https://github.com/RomaVis/pymenuconfig>`_ and suggesting\n  the ``rsource`` keyword.\n\n- To `Mitja Horvat <https://github.com/pinkfluid>`_, for adding support\n  for user-defined styles to the terminal menuconfig.\n\n- To `Philip Craig <https://github.com/philipc>`_ for adding\n  support for the ``allnoconfig_y`` option and fixing an obscure issue\n  with ``comment``\\s inside ``choice``\\s (that didn't affect correctness but\n  made outputs differ). ``allnoconfig_y`` is used to force certain symbols\n  to ``y`` during ``make allnoconfig`` to improve coverage.\n\nLicense\n-------\n\nSee `LICENSE.txt <https://github.com/ulfalizer/Kconfiglib/blob/master/LICENSE.txt>`_. SPDX license identifiers are used in the\nsource code.\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/alldefconfig.py",
    "content": "#!/usr/bin/env python\n\n# Copyright (c) 2018-2019, Ulf Magnusson\n# SPDX-License-Identifier: ISC\n\n\"\"\"\nWrites a configuration file where all symbols are set to their their default\nvalues.\n\nThe default output filename is '.config'. A different filename can be passed in\nthe KCONFIG_CONFIG environment variable.\n\nUsage for the Linux kernel:\n\n  $ make [ARCH=<arch>] scriptconfig SCRIPT=Kconfiglib/alldefconfig.py\n\"\"\"\nimport kconfiglib\n\n\ndef main():\n    kconf = kconfiglib.standard_kconfig(__doc__)\n    kconf.load_allconfig(\"alldef.config\")\n    print(kconf.write_config())\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/allmodconfig.py",
    "content": "#!/usr/bin/env python\n\n# Copyright (c) 2018-2019, Ulf Magnusson\n# SPDX-License-Identifier: ISC\n\n\"\"\"\nWrites a configuration file where as many symbols as possible are set to 'm'.\n\nThe default output filename is '.config'. A different filename can be passed\nin the KCONFIG_CONFIG environment variable.\n\nUsage for the Linux kernel:\n\n  $ make [ARCH=<arch>] scriptconfig SCRIPT=Kconfiglib/allmodconfig.py\n\"\"\"\nimport kconfiglib\n\n\ndef main():\n    kconf = kconfiglib.standard_kconfig(__doc__)\n\n    # See allnoconfig.py\n    kconf.warn = False\n\n    for sym in kconf.unique_defined_syms:\n        if sym.orig_type == kconfiglib.BOOL:\n            # 'bool' choice symbols get their default value, as determined by\n            # e.g. 'default's on the choice\n            if not sym.choice:\n                # All other bool symbols get set to 'y', like for allyesconfig\n                sym.set_value(2)\n        elif sym.orig_type == kconfiglib.TRISTATE:\n            sym.set_value(1)\n\n    for choice in kconf.unique_choices:\n        choice.set_value(2 if choice.orig_type == kconfiglib.BOOL else 1)\n\n    kconf.warn = True\n\n    kconf.load_allconfig(\"allmod.config\")\n\n    print(kconf.write_config())\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/allnoconfig.py",
    "content": "#!/usr/bin/env python\n\n# Copyright (c) 2018-2019, Ulf Magnusson\n# SPDX-License-Identifier: ISC\n\n\"\"\"\nWrites a configuration file where as many symbols as possible are set to 'n'.\n\nThe default output filename is '.config'. A different filename can be passed\nin the KCONFIG_CONFIG environment variable.\n\nUsage for the Linux kernel:\n\n  $ make [ARCH=<arch>] scriptconfig SCRIPT=Kconfiglib/allnoconfig.py\n\"\"\"\n\n# See examples/allnoconfig_walk.py for another way to implement this script\n\nimport kconfiglib\n\n\ndef main():\n    kconf = kconfiglib.standard_kconfig(__doc__)\n\n    # Avoid warnings that would otherwise get printed by Kconfiglib for the\n    # following:\n    #\n    # 1. Assigning a value to a symbol without a prompt, which never has any\n    #    effect\n    #\n    # 2. Assigning values invalid for the type (only bool/tristate symbols\n    #    accept 0/1/2, for n/m/y). The assignments will be ignored for other\n    #    symbol types, which is what we want.\n    kconf.warn = False\n    for sym in kconf.unique_defined_syms:\n        sym.set_value(2 if sym.is_allnoconfig_y else 0)\n    kconf.warn = True\n\n    kconf.load_allconfig(\"allno.config\")\n\n    print(kconf.write_config())\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/allyesconfig.py",
    "content": "#!/usr/bin/env python\n\n# Copyright (c) 2018-2019, Ulf Magnusson\n# SPDX-License-Identifier: ISC\n\n\"\"\"\nWrites a configuration file where as many symbols as possible are set to 'y'.\n\nThe default output filename is '.config'. A different filename can be passed\nin the KCONFIG_CONFIG environment variable.\n\nUsage for the Linux kernel:\n\n  $ make [ARCH=<arch>] scriptconfig SCRIPT=Kconfiglib/allyesconfig.py\n\"\"\"\nimport kconfiglib\n\n\ndef main():\n    kconf = kconfiglib.standard_kconfig(__doc__)\n\n    # See allnoconfig.py\n    kconf.warn = False\n\n    # Try to set all symbols to 'y'. Dependencies might truncate the value down\n    # later, but this will at least give the highest possible value.\n    #\n    # Assigning 0/1/2 to non-bool/tristate symbols has no effect (int/hex\n    # symbols still take a string, because they preserve formatting).\n    for sym in kconf.unique_defined_syms:\n        # Set choice symbols to 'm'. This value will be ignored for choices in\n        # 'y' mode (the \"normal\" mode), which will instead just get their\n        # default selection, but will set all symbols in m-mode choices to 'm',\n        # which is as high as they can go.\n        #\n        # Here's a convoluted example of how you might get an m-mode choice\n        # even during allyesconfig:\n        #\n        #   choice\n        #           tristate \"weird choice\"\n        #           depends on m\n        sym.set_value(1 if sym.choice else 2)\n\n    # Set all choices to the highest possible mode\n    for choice in kconf.unique_choices:\n        choice.set_value(2)\n\n    kconf.warn = True\n\n    kconf.load_allconfig(\"allyes.config\")\n\n    print(kconf.write_config())\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/defconfig.py",
    "content": "#!/usr/bin/env python\n\n# Copyright (c) 2019, Ulf Magnusson\n# SPDX-License-Identifier: ISC\n\n\"\"\"\nReads a specified configuration file, then writes a new configuration file.\nThis can be used to initialize the configuration from e.g. an arch-specific\nconfiguration file. This input configuration file would usually be a minimal\nconfiguration file, as generated by e.g. savedefconfig.\n\nThe default output filename is '.config'. A different filename can be passed in\nthe KCONFIG_CONFIG environment variable.\n\"\"\"\nimport argparse\n\nimport kconfiglib\n\n\ndef main():\n    parser = argparse.ArgumentParser(\n        formatter_class=argparse.RawDescriptionHelpFormatter,\n        description=__doc__)\n\n    parser.add_argument(\n        \"--kconfig\",\n        default=\"Kconfig\",\n        help=\"Base Kconfig file (default: Kconfig)\")\n\n    parser.add_argument(\n        \"config\",\n        metavar=\"CONFIGURATION\",\n        help=\"Input configuration file\")\n\n    args = parser.parse_args()\n\n    kconf = kconfiglib.Kconfig(args.kconfig, suppress_traceback=True)\n    print(kconf.load_config(args.config))\n    print(kconf.write_config())\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/examples/Kmenuconfig",
    "content": "mainmenu \"Example Kconfig configuration\"\n\nconfig MODULES\n\tbool \"Enable loadable module support\"\n\toption modules\n\tdefault y\n\nmenu \"Bool and tristate symbols\"\n\nconfig BOOL\n\tbool \"Bool symbol\"\n\tdefault y\n\nconfig BOOL_DEP\n\tbool \"Dependent bool symbol\"\n\tdepends on BOOL\n\n# Mix it up a bit with an 'if' instead of a 'depends on'\nif BOOL\n\nconfig TRI_DEP\n\ttristate \"Dependent tristate symbol\"\n\tselect SELECTED_BY_TRI_DEP\n\timply IMPLIED_BY_TRI_DEP\n\nendif\n\nconfig TWO_MENU_NODES\n\tbool \"First prompt\"\n\tdepends on BOOL\n\nconfig TRI\n\ttristate \"Tristate symbol\"\n\nconfig TWO_MENU_NODES\n\tbool \"Second prompt\"\n\ncomment \"These are selected by TRI_DEP\"\n\nconfig SELECTED_BY_TRI_DEP\n\ttristate \"Tristate selected by TRI_DEP\"\n\nconfig IMPLIED_BY_TRI_DEP\n\ttristate \"Tristate implied by TRI_DEP\"\n\nendmenu\n\n\nmenu \"String, int, and hex symbols\"\n\nconfig STRING\n\tstring \"String symbol\"\n\tdefault \"foo\"\n\nconfig INT\n\tint \"Int symbol\"\n\tdefault 747\n\nconfig HEX\n\thex \"Hex symbol\"\n\tdefault 0xABC\n\nendmenu\n\n\nmenu \"Various choices\"\n\nchoice BOOL_CHOICE\n\tbool \"Bool choice\"\n\nconfig BOOL_CHOICE_SYM_1\n\tbool \"Bool choice sym 1\"\n\nconfig BOOL_CHOICE_SYM_2\n\tbool \"Bool choice sym 2\"\n\nendchoice\n\nchoice TRI_CHOICE\n\ttristate \"Tristate choice\"\n\nconfig TRI_CHOICE_SYM_1\n\ttristate \"Tristate choice sym 1\"\n\nconfig TRI_CHOICE_SYM_2\n\ttristate \"Tristate choice sym 2\"\n\nendchoice\n\nchoice OPT_BOOL_CHOICE\n\tbool \"Optional bool choice\"\n\toptional\n\nconfig OPT_BOOL_CHOICE_SYM_1\n\tbool \"Optional bool choice sym 1\"\n\nconfig OPT_BOOL_CHOICE_SYM_2\n\tbool \"Optional bool choice sym 2\"\n\nendchoice\n\nendmenu\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/examples/allnoconfig_walk.py",
    "content": "# This is tree-walking version of allnoconfig.py, for demonstration purposes.\n# Verified by the test suite to generate identical output to 'make allnoconfig'\n# for all ARCHes.\n#\n# Note: A more practical version would use Kconfig.node_iter(). The manual tree\n# walking is for demonstration purposes.\n#\n# Usage for the Linux kernel:\n#\n#   $ make [ARCH=<arch>] scriptconfig SCRIPT=Kconfiglib/examples/allnoconfig_walk.py\n\nimport sys\n\nfrom kconfiglib import Kconfig, Symbol\n\n\ndef do_allnoconfig(node):\n    global changed\n\n    # Walk the tree of menu nodes. You can imagine this as going down/into menu\n    # entries in the menuconfig interface, setting each to n (or the lowest\n    # assignable value).\n\n    while node:\n        if isinstance(node.item, Symbol):\n            sym = node.item\n\n            # Is the symbol a non-allnoconfig_y symbol that can be set to a\n            # lower value than its current value?\n            if (not sym.is_allnoconfig_y and\n                sym.assignable and\n                sym.assignable[0] < sym.tri_value):\n\n                # Yup, lower it\n                sym.set_value(sym.assignable[0])\n                changed = True\n\n        # Recursively lower children\n        if node.list:\n            do_allnoconfig(node.list)\n\n        node = node.next\n\n\n# Parse the Kconfig files\nkconf = Kconfig(sys.argv[1])\n\n# Do an initial pass to set 'option allnoconfig_y' symbols to y\nfor sym in kconf.unique_defined_syms:\n    if sym.is_allnoconfig_y:\n        sym.set_value(2)\n\nwhile True:\n    # Changing later symbols in the configuration can sometimes allow earlier\n    # symbols to be lowered, e.g. if a later symbol 'select's an earlier\n    # symbol. To handle such situations, we do additional passes over the tree\n    # until we're no longer able to change the value of any symbol in a pass.\n    changed = False\n\n    do_allnoconfig(kconf.top_node)\n\n    # Did the pass change any symbols?\n    if not changed:\n        break\n\nprint(kconf.write_config())\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/examples/defconfig_oldconfig.py",
    "content": "# Produces exactly the same output as the following script:\n#\n# make defconfig\n# echo CONFIG_ETHERNET=n >> .config\n# make oldconfig\n# echo CONFIG_ETHERNET=y >> .config\n# yes n | make oldconfig\n#\n# This came up in https://github.com/ulfalizer/Kconfiglib/issues/15.\n#\n# Usage:\n#\n#   $ make [ARCH=<arch>] scriptconfig SCRIPT=Kconfiglib/examples/defconfig_oldconfig.py\n\nimport sys\n\nimport kconfiglib\n\n\nkconf = kconfiglib.Kconfig(sys.argv[1])\n\n# Mirrors defconfig\nkconf.load_config(\"arch/x86/configs/x86_64_defconfig\")\nkconf.write_config()\n\n# Mirrors the first oldconfig\nkconf.load_config()\nkconf.syms[\"ETHERNET\"].set_value(0)\nkconf.write_config()\n\n# Mirrors the second oldconfig\nkconf.load_config()\nkconf.syms[\"ETHERNET\"].set_value(2)\nfor s in kconf.unique_defined_syms:\n    if s.user_value is None and 0 in s.assignable:\n        s.set_value(0)\n\n# Write the final configuration\nprint(kconf.write_config())\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/examples/dumpvars.py",
    "content": "# Prints all (set) environment variables referenced in the Kconfig files\n# together with their values, as a list of assignments.\n#\n# Note: This only works for environment variables referenced via the $(FOO)\n# preprocessor syntax. The older $FOO syntax is maintained for backwards\n# compatibility.\n\nimport os\nimport sys\n\nimport kconfiglib\n\n\nprint(\" \".join(\"{}='{}'\".format(var, os.environ[var])\n               for var in kconfiglib.Kconfig(sys.argv[1]).env_vars))\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/examples/eval_expr.py",
    "content": "# Evaluates an expression (e.g. \"X86_64 || (X86_32 && X86_LOCAL_APIC)\") in the\n# context of a configuration. Note that this always yields a tristate value (n,\n# m, or y).\n#\n# Usage:\n#\n#   $ make [ARCH=<arch>] scriptconfig SCRIPT=Kconfiglib/examples/eval_expr.py SCRIPT_ARG=<expr>\n\nimport sys\n\nimport kconfiglib\n\n\nif len(sys.argv) < 3:\n    sys.exit(\"Pass the expression to evaluate with SCRIPT_ARG=<expression>\")\n\nkconf = kconfiglib.Kconfig(sys.argv[1])\nexpr = sys.argv[2]\n\n# Enable modules so that m doesn't get demoted to n\nkconf.modules.set_value(2)\n\nprint(\"the expression '{}' evaluates to {}\"\n      .format(expr, kconf.eval_string(expr)))\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/examples/find_symbol.py",
    "content": "# Prints all menu nodes that reference a given symbol any of their properties\n# or property conditions, along with their parent menu nodes.\n#\n# Usage:\n#\n#   $ make [ARCH=<arch>] scriptconfig SCRIPT=Kconfiglib/examples/find_symbol.py SCRIPT_ARG=<name>\n#\n# Example output for SCRIPT_ARG=X86:\n#\n#   Found 470 locations that reference X86:\n#\n#   ========== Location 1 (init/Kconfig:1108) ==========\n#\n#   config SGETMASK_SYSCALL\n#   \tbool\n#   \tprompt \"sgetmask/ssetmask syscalls support\" if EXPERT\n#   \tdefault PARISC || M68K || PPC || MIPS || X86 || SPARC || MICROBLAZE || SUPERH\n#   \thelp\n#   \t  sys_sgetmask and sys_ssetmask are obsolete system calls\n#   \t  no longer supported in libc but still enabled by default in some\n#   \t  architectures.\n#\n#   \t  If unsure, leave the default option here.\n#\n#   ---------- Parent 1 (init/Kconfig:1077)  ----------\n#\n#   menuconfig EXPERT\n#   \tbool\n#   \tprompt \"Configure standard kernel features (expert users)\"\n#   \tselect DEBUG_KERNEL\n#   \thelp\n#   \t  This option allows certain base kernel options and settings\n#   \t  to be disabled or tweaked. This is for specialized\n#   \t  environments which can tolerate a \"non-standard\" kernel.\n#   \t  Only use this if you really know what you are doing.\n#\n#   ---------- Parent 2 (init/Kconfig:39)  ----------\n#\n#   menu \"General setup\"\n#\n#   ========== Location 2 (arch/Kconfig:29) ==========\n#\n#   config OPROFILE_EVENT_MULTIPLEX\n#   \tbool\n#   \tprompt \"OProfile multiplexing support (EXPERIMENTAL)\"\n#   \tdefault \"n\"\n#   \tdepends on OPROFILE && X86\n#   \thelp\n#   \t  The number of hardware counters is limited. The multiplexing\n#   \t  feature enables OProfile to gather more events than counters\n#   \t  are provided by the hardware. This is realized by switching\n#   \t  between events at a user specified time interval.\n#\n#   \t  If unsure, say N.\n#\n#   ---------- Parent 1 (arch/Kconfig:16)  ----------\n#\n#   config OPROFILE\n#   \ttristate\n#   \tprompt \"OProfile system profiling\"\n#   \tselect RING_BUFFER\n#   \tselect RING_BUFFER_ALLOW_SWAP\n#   \tdepends on PROFILING && HAVE_OPROFILE\n#   \thelp\n#   \t  OProfile is a profiling system capable of profiling the\n#   \t  whole system, include the kernel, kernel modules, libraries,\n#   \t  and applications.\n#\n#   \t  If unsure, say N.\n#\n#   ---------- Parent 2 (init/Kconfig:39)  ----------\n#\n#   menu \"General setup\"\n#\n#   ... (tons more)\n\nimport sys\n\nimport kconfiglib\n\n\nif len(sys.argv) < 3:\n    sys.exit('Pass symbol name (without \"CONFIG_\" prefix) with SCRIPT_ARG=<name>')\n\nkconf = kconfiglib.Kconfig(sys.argv[1])\nsym_name = sys.argv[2]\nif sym_name not in kconf.syms:\n    print(\"No symbol {} exists in the configuration\".format(sym_name))\n    sys.exit(0)\n\nreferencing = [node for node in kconf.node_iter()\n               if kconf.syms[sym_name] in node.referenced]\nif not referencing:\n    print(\"No references to {} found\".format(sym_name))\n    sys.exit(0)\n\nprint(\"Found {} locations that reference {}:\\n\"\n      .format(len(referencing), sym_name))\n\nfor i, node in enumerate(referencing, 1):\n    print(\"========== Location {} ({}:{}) ==========\\n\\n{}\"\n          .format(i, node.filename, node.linenr, node))\n\n    # Print the parents of the menu node too\n\n    node = node.parent\n    parent_i = 1\n    while node is not kconf.top_node:\n        print(\"---------- Parent {} ({}:{})  ----------\\n\\n{}\"\n              .format(parent_i, node.filename, node.linenr, node))\n        node = node.parent\n        parent_i += 1\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/examples/help_grep.py",
    "content": "# Does a case-insensitive search for a regular expression in the help texts of\n# symbols and choices and the prompts of menus and comments. Prints the\n# matching items together with their locations and the matching text.\n#\n# Usage:\n#\n#   $ make [ARCH=<arch>] scriptconfig SCRIPT=Kconfiglib/examples/help_grep.py SCRIPT_ARG=<regex>\n#\n# Shortened example output for SCRIPT_ARG=general:\n#\n#   menu \"General setup\"\n#   location: init/Kconfig:39\n#\n#   config SYSVIPC\n#   \tbool\n#   \tprompt \"System V IPC\"\n#   \thelp\n#   \t  ...\n#   \t  exchange information. It is generally considered to be a good thing,\n#   \t  ...\n#\n#   location: init/Kconfig:233\n#\n#   config BSD_PROCESS_ACCT\n#   \tbool\n#   \tprompt \"BSD Process Accounting\" if MULTIUSER\n#   \thelp\n#   \t  ...\n#   \t  information.  This is generally a good idea, so say Y.\n#\n#   location: init/Kconfig:403\n#\n#   ...\n\n\nimport re\nimport sys\n\nfrom kconfiglib import Kconfig, Symbol, Choice, MENU, COMMENT\n\n\nif len(sys.argv) < 3:\n    sys.exit(\"Pass the regex with SCRIPT_ARG=<regex>\")\n\nsearch = re.compile(sys.argv[2], re.IGNORECASE).search\n\nfor node in Kconfig(sys.argv[1]).node_iter():\n    match = False\n\n    if isinstance(node.item, (Symbol, Choice)) and \\\n       node.help is not None and search(node.help):\n        print(node.item)\n        match = True\n\n    elif node.item == MENU and search(node.prompt[0]):\n        print('menu \"{}\"'.format(node.prompt[0]))\n        match = True\n\n    elif node.item == COMMENT and search(node.prompt[0]):\n        print('comment \"{}\"'.format(node.prompt[0]))\n        match = True\n\n    if match:\n        print(\"location: {}:{}\\n\".format(node.filename, node.linenr))\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/examples/list_undefined.py",
    "content": "# Prints a list of symbols that are referenced in the Kconfig files of some\n# architecture but not defined by the Kconfig files of any architecture.\n#\n# A Kconfig file might be shared between many architectures and legitimately\n# reference undefined symbols for some of them, but if no architecture defines\n# the symbol, it usually indicates a problem or potential cleanup.\n#\n# This script could be sped up a lot if needed. See the comment near the\n# referencing_nodes() call.\n#\n# Run with the following command in the kernel root:\n#\n#   $ python(3) Kconfiglib/examples/list_undefined.py\n#\n# Example output:\n#\n#   Registering defined and undefined symbols for all arches\n#     Processing mips\n#     Processing ia64\n#     Processing metag\n#     ...\n#\n#   Finding references to each undefined symbol\n#     Processing mips\n#     Processing ia64\n#     Processing metag\n#     ...\n#\n#   The following globally undefined symbols were found, listed here\n#   together with the locations of the items that reference them.\n#   References might come from enclosing menus and ifs.\n#\n#     ARM_ERRATA_753970: arch/arm/mach-mvebu/Kconfig:56, arch/arm/mach-mvebu/Kconfig:39\n#     SUNXI_CCU_MP: drivers/clk/sunxi-ng/Kconfig:14\n#     SUNXI_CCU_DIV: drivers/clk/sunxi-ng/Kconfig:14\n#     AC97: sound/ac97/Kconfig:6\n#     ...\n\nimport os\nimport subprocess\n\nfrom kconfiglib import Kconfig\n\n\n# Referenced inside the Kconfig files\nos.environ[\"KERNELVERSION\"] = str(\n    subprocess.check_output((\"make\", \"kernelversion\")).decode(\"utf-8\").rstrip()\n)\n\n\ndef all_arch_srcarch_pairs():\n    \"\"\"\n    Generates all valid (ARCH, SRCARCH) tuples for the kernel, corresponding to\n    different architectures. SRCARCH holds the arch/ subdirectory.\n    \"\"\"\n    for srcarch in os.listdir(\"arch\"):\n        # Each subdirectory of arch/ containing a Kconfig file corresponds to\n        # an architecture\n        if os.path.exists(os.path.join(\"arch\", srcarch, \"Kconfig\")):\n            yield (srcarch, srcarch)\n\n    # Some architectures define additional ARCH settings with ARCH != SRCARCH\n    # (search for \"Additional ARCH settings for\" in the top-level Makefile)\n\n    yield (\"i386\", \"x86\")\n    yield (\"x86_64\", \"x86\")\n\n    yield (\"sparc32\", \"sparc\")\n    yield (\"sparc64\", \"sparc\")\n\n    yield (\"sh64\", \"sh\")\n\n    yield (\"um\", \"um\")\n\n\ndef all_arch_srcarch_kconfigs():\n    \"\"\"\n    Generates Kconfig instances for all the architectures in the kernel\n    \"\"\"\n\n    os.environ[\"srctree\"] = \".\"\n    os.environ[\"HOSTCC\"] = \"gcc\"\n    os.environ[\"HOSTCXX\"] = \"g++\"\n    os.environ[\"CC\"] = \"gcc\"\n    os.environ[\"LD\"] = \"ld\"\n\n    for arch, srcarch in all_arch_srcarch_pairs():\n        print(\"  Processing \" + arch)\n\n        os.environ[\"ARCH\"] = arch\n        os.environ[\"SRCARCH\"] = srcarch\n\n        # um (User Mode Linux) uses a different base Kconfig file\n        yield Kconfig(\"Kconfig\" if arch != \"um\" else \"arch/x86/um/Kconfig\",\n                      warn=False)\n\n\nprint(\"Registering defined and undefined symbols for all arches\")\n\n# Sets holding the names of all defined and undefined symbols, for all\n# architectures\ndefined = set()\nundefined = set()\n\nfor kconf in all_arch_srcarch_kconfigs():\n    for name, sym in kconf.syms.items():\n        if sym.nodes:\n            # If the symbol has a menu node, it is defined\n            defined.add(name)\n        else:\n            # Undefined symbol. We skip some of the uninteresting ones.\n\n            # Due to how Kconfig works, integer literals show up as symbols\n            # (from e.g. 'default 1'). Skip those.\n            try:\n                int(name, 0)\n                continue\n            except ValueError:\n                # Interesting undefined symbol\n                undefined.add(name)\n\n\nprint(\"\\nFinding references to each undefined symbol\")\n\ndef referencing_nodes(kconf, name):\n    # Returns a list of all menu nodes that reference a symbol named 'name' in\n    # any of their properties or property conditions\n    res = []\n\n    for node in kconf.node_iter():\n        for ref in node.referenced:\n            if ref.name == name:\n                res.append(node)\n\n    return res\n\n\n# Maps each globally undefined symbol to the menu nodes that reference it\nundef_sym_refs = [(name, set()) for name in undefined - defined]\n\nfor kconf in all_arch_srcarch_kconfigs():\n    for name, refs in undef_sym_refs:\n        # This means that we search the entire configuration tree for each\n        # undefined symbol, which is terribly inefficient. We could speed\n        # things up by tweaking referencing_nodes() to compare each symbol to\n        # multiple symbols while walking the configuration tree.\n        for node in referencing_nodes(kconf, name):\n            refs.add(\"{}:{}\".format(node.filename, node.linenr))\n\n\nprint(\"\\nThe following globally undefined symbols were found, listed here\\n\"\n      \"together with the locations of the items that reference them.\\n\"\n      \"References might come from enclosing menus and ifs.\\n\")\n\nfor name, refs in undef_sym_refs:\n    print(\"  {}: {}\".format(name, \", \".join(refs)))\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/examples/menuconfig_example.py",
    "content": "#!/usr/bin/env python\n\n# Implements a simple configuration interface on top of Kconfiglib to\n# demonstrate concepts for building a menuconfig-like. Emulates how the\n# standard menuconfig prints menu entries.\n#\n# Always displays the entire Kconfig tree to keep things as simple as possible\n# (all symbols, choices, menus, and comments).\n#\n# Usage:\n#\n#   $ python(3) Kconfiglib/examples/menuconfig.py <Kconfig file>\n#\n# A sample Kconfig is available in Kconfiglib/examples/Kmenuconfig.\n#\n# Here's a notation guide. The notation matches the one used by menuconfig\n# (scripts/kconfig/mconf):\n#\n#   [ ] prompt      - Bool\n#   < > prompt      - Tristate\n#   {M} prompt      - Tristate selected to m. Can only be set to m or y.\n#   -*- prompt      - Bool/tristate selected to y, pinning it\n#   -M- prompt      - Tristate selected to m that also has m visibility,\n#                     pinning it to m\n#   (foo) prompt    - String/int/hex symbol with value \"foo\"\n#   --> prompt      - The selected symbol in a choice in y mode. This\n#                     syntax is unique to this example.\n#\n# When modules are disabled, the .type attribute of TRISTATE symbols and\n# choices automatically changes to BOOL. This trick is used by the C\n# implementation as well, and gives the expected behavior without having to do\n# anything extra here. The original type is available in .orig_type if needed.\n#\n# The Kconfiglib/examples/Kmenuconfig example uses named choices to be able to\n# refer to choices by name. Named choices are supported in the C tools too, but\n# I don't think I've ever seen them used in the wild.\n#\n# Sample session:\n#\n#   $ python Kconfiglib/examples/menuconfig.py Kconfiglib/examples/Kmenuconfig\n#\n#   ======== Example Kconfig configuration ========\n#\n#   [*] Enable loadable module support (MODULES)\n#       Bool and tristate symbols\n#           [*] Bool symbol (BOOL)\n#                   [ ] Dependent bool symbol (BOOL_DEP)\n#                   < > Dependent tristate symbol (TRI_DEP)\n#                   [ ] First prompt (TWO_MENU_NODES)\n#           < > Tristate symbol (TRI)\n#           [ ] Second prompt (TWO_MENU_NODES)\n#               *** These are selected by TRI_DEP ***\n#           < > Tristate selected by TRI_DEP (SELECTED_BY_TRI_DEP)\n#           < > Tristate implied by TRI_DEP (IMPLIED_BY_TRI_DEP)\n#       String, int, and hex symbols\n#           (foo) String symbol (STRING)\n#           (747) Int symbol (INT)\n#           (0xABC) Hex symbol (HEX)\n#       Various choices\n#           -*- Bool choice (BOOL_CHOICE)\n#                   --> Bool choice sym 1 (BOOL_CHOICE_SYM_1)\n#                       Bool choice sym 2 (BOOL_CHOICE_SYM_2)\n#           {M} Tristate choice (TRI_CHOICE)\n#                   < > Tristate choice sym 1 (TRI_CHOICE_SYM_1)\n#                   < > Tristate choice sym 2 (TRI_CHOICE_SYM_2)\n#           [ ] Optional bool choice (OPT_BOOL_CHOICE)\n#\n#   Enter a symbol/choice name, \"load_config\", or \"write_config\" (or press CTRL+D to exit): BOOL\n#   Value for BOOL (available: n, y): n\n#\n#   ======== Example Kconfig configuration ========\n#\n#   [*] Enable loadable module support (MODULES)\n#       Bool and tristate symbols\n#           [ ] Bool symbol (BOOL)\n#           < > Tristate symbol (TRI)\n#           [ ] Second prompt (TWO_MENU_NODES)\n#               *** These are selected by TRI_DEP ***\n#           < > Tristate selected by TRI_DEP (SELECTED_BY_TRI_DEP)\n#           < > Tristate implied by TRI_DEP (IMPLIED_BY_TRI_DEP)\n#       String, int, and hex symbols\n#           (foo) String symbol (STRING)\n#           (747) Int symbol (INT)\n#           (0xABC) Hex symbol (HEX)\n#       Various choices\n#           -*- Bool choice (BOOL_CHOICE)\n#                   --> Bool choice sym 1 (BOOL_CHOICE_SYM_1)\n#                       Bool choice sym 2 (BOOL_CHOICE_SYM_2)\n#           {M} Tristate choice (TRI_CHOICE)\n#                   < > Tristate choice sym 1 (TRI_CHOICE_SYM_1)\n#                   < > Tristate choice sym 2 (TRI_CHOICE_SYM_2)\n#          [ ] Optional bool choice (OPT_BOOL_CHOICE)\n#\n#   Enter a symbol/choice name, \"load_config\", or \"write_config\" (or press CTRL+D to exit): MODULES\n#   Value for MODULES (available: n, y): n\n#\n#   ======== Example Kconfig configuration ========\n#\n#   [ ] Enable loadable module support (MODULES)\n#       Bool and tristate symbols\n#           [ ] Bool symbol (BOOL)\n#           [ ] Tristate symbol (TRI)\n#           [ ] Second prompt (TWO_MENU_NODES)\n#               *** These are selected by TRI_DEP ***\n#           [ ] Tristate selected by TRI_DEP (SELECTED_BY_TRI_DEP)\n#           [ ] Tristate implied by TRI_DEP (IMPLIED_BY_TRI_DEP)\n#       String, int, and hex symbols\n#           (foo) String symbol (STRING)\n#           (747) Int symbol (INT)\n#           (0xABC) Hex symbol (HEX)\n#       Various choices\n#           -*- Bool choice (BOOL_CHOICE)\n#                   --> Bool choice sym 1 (BOOL_CHOICE_SYM_1)\n#                       Bool choice sym 2 (BOOL_CHOICE_SYM_2)\n#           -*- Tristate choice (TRI_CHOICE)\n#                   --> Tristate choice sym 1 (TRI_CHOICE_SYM_1)\n#                       Tristate choice sym 2 (TRI_CHOICE_SYM_2)\n#           [ ] Optional bool choice (OPT_BOOL_CHOICE)\n#\n#   Enter a symbol/choice name, \"load_config\", or \"write_config\" (or press CTRL+D to exit): ^D\n\nfrom __future__ import print_function\nimport readline\nimport sys\n\nfrom kconfiglib import Kconfig, \\\n                       Symbol, MENU, COMMENT, \\\n                       BOOL, TRISTATE, STRING, INT, HEX, UNKNOWN, \\\n                       expr_value, \\\n                       TRI_TO_STR\n\n\n# Python 2/3 compatibility hack\nif sys.version_info[0] < 3:\n    input = raw_input\n\n\ndef indent_print(s, indent):\n    print(indent*\" \" + s)\n\n\ndef value_str(sc):\n    \"\"\"\n    Returns the value part (\"[*]\", \"<M>\", \"(foo)\" etc.) of a menu entry.\n\n    sc: Symbol or Choice.\n    \"\"\"\n    if sc.type in (STRING, INT, HEX):\n        return \"({})\".format(sc.str_value)\n\n    # BOOL or TRISTATE\n\n    # The choice mode is an upper bound on the visibility of choice symbols, so\n    # we can check the choice symbols' own visibility to see if the choice is\n    # in y mode\n    if isinstance(sc, Symbol) and sc.choice and sc.visibility == 2:\n        # For choices in y mode, print '-->' next to the selected symbol\n        return \"-->\" if sc.choice.selection is sc else \"   \"\n\n    tri_val_str = (\" \", \"M\", \"*\")[sc.tri_value]\n\n    if len(sc.assignable) == 1:\n        # Pinned to a single value\n        return \"-{}-\".format(tri_val_str)\n\n    if sc.type == BOOL:\n        return \"[{}]\".format(tri_val_str)\n\n    if sc.type == TRISTATE:\n        if sc.assignable == (1, 2):\n            # m and y available\n            return \"{\" + tri_val_str + \"}\"  # Gets a bit confusing with .format()\n        return \"<{}>\".format(tri_val_str)\n\n\ndef node_str(node):\n    \"\"\"\n    Returns the complete menu entry text for a menu node, or \"\" for invisible\n    menu nodes. Invisible menu nodes are those that lack a prompt or that do\n    not have a satisfied prompt condition.\n\n    Example return value: \"[*] Bool symbol (BOOL)\"\n\n    The symbol name is printed in parentheses to the right of the prompt. This\n    is so that symbols can easily be referred to in the configuration\n    interface.\n    \"\"\"\n    if not node.prompt:\n        return \"\"\n\n    # Even for menu nodes for symbols and choices, it's wrong to check\n    # Symbol.visibility / Choice.visibility here. The reason is that a symbol\n    # (and a choice, in theory) can be defined in multiple locations, giving it\n    # multiple menu nodes, which do not necessarily all have the same prompt\n    # visibility. Symbol.visibility / Choice.visibility is calculated as the OR\n    # of the visibility of all the prompts.\n    prompt, prompt_cond = node.prompt\n    if not expr_value(prompt_cond):\n        return \"\"\n\n    if node.item == MENU:\n        return \"    \" + prompt\n\n    if node.item == COMMENT:\n        return \"    *** {} ***\".format(prompt)\n\n    # Symbol or Choice\n\n    sc = node.item\n\n    if sc.type == UNKNOWN:\n        # Skip symbols defined without a type (these are obscure and generate\n        # a warning)\n        return \"\"\n\n    # {:3} sets the field width to three. Gives nice alignment for empty string\n    # values.\n    res = \"{:3} {}\".format(value_str(sc), prompt)\n\n    # Don't print the name for unnamed choices (the normal kind)\n    if sc.name is not None:\n        res += \" ({})\".format(sc.name)\n\n    return res\n\n\ndef print_menuconfig_nodes(node, indent):\n    \"\"\"\n    Prints a tree with all the menu entries rooted at 'node'. Child menu\n    entries are indented.\n    \"\"\"\n    while node:\n        string = node_str(node)\n        if string:\n            indent_print(string, indent)\n\n        if node.list:\n            print_menuconfig_nodes(node.list, indent + 8)\n\n        node = node.next\n\n\ndef print_menuconfig(kconf):\n    \"\"\"\n    Prints all menu entries for the configuration.\n    \"\"\"\n    # Print the expanded mainmenu text at the top. This is the same as\n    # kconf.top_node.prompt[0], but with variable references expanded.\n    print(\"\\n======== {} ========\\n\".format(kconf.mainmenu_text))\n\n    print_menuconfig_nodes(kconf.top_node.list, 0)\n    print(\"\")\n\n\ndef get_value_from_user(sc):\n    \"\"\"\n    Prompts the user for a value for the symbol or choice 'sc'. For\n    bool/tristate symbols and choices, provides a list of all the assignable\n    values.\n    \"\"\"\n    if not sc.visibility:\n        print(sc.name + \" is not currently visible\")\n        return False\n\n    prompt = \"Value for {}\".format(sc.name)\n    if sc.type in (BOOL, TRISTATE):\n        prompt += \" (available: {})\" \\\n                  .format(\", \".join(TRI_TO_STR[val] for val in sc.assignable))\n    prompt += \": \"\n\n    val = input(prompt)\n\n    # Automatically add a \"0x\" prefix for hex symbols, like the menuconfig\n    # interface does. This isn't done when loading .config files, hence why\n    # set_value() doesn't do it automatically.\n    if sc.type == HEX and not val.startswith((\"0x\", \"0X\")):\n        val = \"0x\" + val\n\n    # Let Kconfiglib itself print a warning here if the value is invalid. We\n    # could also disable warnings temporarily with 'kconf.warn = False' and\n    # print our own warning.\n    return sc.set_value(val)\n\n\nif __name__ == \"__main__\":\n    if len(sys.argv) != 2:\n        sys.exit(\"usage: menuconfig.py <Kconfig file>\")\n\n    # Load Kconfig configuration files\n    kconf = Kconfig(sys.argv[1])\n\n    # Print the initial configuration tree\n    print_menuconfig(kconf)\n\n    while True:\n        try:\n            cmd = input('Enter a symbol/choice name, \"load_config\", or '\n                        '\"write_config\" (or press CTRL+D to exit): ').strip()\n        except EOFError:\n            print(\"\")\n            break\n\n        if cmd == \"load_config\":\n            config_filename = input(\".config file to load: \")\n            try:\n                # Returns a message telling which file got loaded\n                print(kconf.load_config(config_filename))\n            except EnvironmentError as e:\n                print(e, file=sys.stderr)\n\n            print_menuconfig(kconf)\n            continue\n\n        if cmd == \"write_config\":\n            config_filename = input(\"To this file: \")\n            try:\n                # Returns a message telling which file got saved\n                print(kconf.write_config(config_filename))\n            except EnvironmentError as e:\n                print(e, file=sys.stderr)\n\n            continue\n\n        # Assume 'cmd' is the name of a symbol or choice if it isn't one of the\n        # commands above, prompt the user for a value for it, and print the new\n        # configuration tree\n\n        if cmd in kconf.syms:\n            if get_value_from_user(kconf.syms[cmd]):\n                print_menuconfig(kconf)\n\n            continue\n\n        if cmd in kconf.named_choices:\n            if get_value_from_user(kconf.named_choices[cmd]):\n                print_menuconfig(kconf)\n\n            continue\n\n        print(\"No symbol/choice named '{}' in the configuration\".format(cmd),\n              file=sys.stderr)\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/examples/merge_config.py",
    "content": "#!/usr/bin/env python\n\n# This script functions similarly to scripts/kconfig/merge_config.sh from the\n# kernel tree, merging multiple configurations fragments to produce a complete\n# .config, with unspecified values filled in as for alldefconfig.\n#\n# The generated .config respects symbol dependencies, and a warning is printed\n# if any symbol gets a different value from the assigned value.\n#\n# For a real-world merging example based on this script, see\n# https://github.com/zephyrproject-rtos/zephyr/blob/master/scripts/kconfig/kconfig.py.\n#\n# Here's a demo:\n#\n# Kconfig contents:\n#\n#     config FOO\n#         bool \"FOO\"\n#\n#     config BAR\n#         bool \"BAR\"\n#\n#     config BAZ\n#         string \"BAZ\"\n#\n#     config QAZ\n#         bool \"QAZ\" if n\n#\n#\n# conf1 contents:\n#\n#     CONFIG_FOO=y\n#\n#\n# conf2 contents:\n#\n#     CONFIG_BAR=y\n#\n#\n# conf3 contents:\n#\n#     # Assigned twice (would generate warning if 'warn_assign_override' was\n#     # True)\n#     # CONFIG_FOO is not set\n#\n#     # Ops... this symbol doesn't exist\n#     CONFIG_OPS=y\n#\n#     CONFIG_BAZ=\"baz string\"\n#\n#\n# conf4 contents:\n#\n#     CONFIG_QAZ=y\n#\n#\n# Running:\n#\n#     $ python(3) merge_config.py Kconfig merged conf1 conf2 conf3 conf4\n#     Merged configuration 'conf1'\n#     Merged configuration 'conf2'\n#     conf3:5: warning: attempt to assign the value 'y' to the undefined symbol OPS\n#     Merged configuration 'conf3'\n#     Merged configuration 'conf4'\n#     Configuration saved to 'merged'\n#     warning: QAZ (defined at Kconfig:10) was assigned the value 'y' but got the value 'n' -- check dependencies\n#     $ cat merged\n#     Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)\n#     # CONFIG_FOO is not set\n#     CONFIG_BAR=y\n#     CONFIG_BAZ=\"baz string\"\n\nfrom __future__ import print_function\nimport sys\n\nfrom kconfiglib import Kconfig, BOOL, TRISTATE, TRI_TO_STR\n\n\nif len(sys.argv) < 4:\n    sys.exit(\"usage: merge_config.py Kconfig merged_config config1 [config2 ...]\")\n\nkconf = Kconfig(sys.argv[1], suppress_traceback=True)\n\n# Enable warnings for assignments to undefined symbols\nkconf.warn_assign_undef = True\n\n# (This script uses alldefconfig as the base. Other starting states could be\n# set up here as well. The approach in examples/allnoconfig_simpler.py could\n# provide an allnoconfig starting state for example.)\n\n# Disable warnings generated for multiple assignments to the same symbol within\n# a (set of) configuration files. Assigning a symbol multiple times might be\n# done intentionally when merging configuration files.\nkconf.warn_assign_override = False\nkconf.warn_assign_redun = False\n\n# Create a merged configuration by loading the fragments with replace=False.\n# load_config() and write_config() returns a message to print.\nfor config in sys.argv[3:]:\n    print(kconf.load_config(config, replace=False))\n\n# Write the merged configuration\nprint(kconf.write_config(sys.argv[2]))\n\n# Print warnings for symbols whose actual value doesn't match the assigned\n# value\nfor sym in kconf.defined_syms:\n    # Was the symbol assigned to?\n    if sym.user_value is not None:\n        # Tristate values are represented as 0, 1, 2. Having them as\n        # \"n\", \"m\", \"y\" is more convenient here, so convert.\n        if sym.type in (BOOL, TRISTATE):\n            user_value = TRI_TO_STR[sym.user_value]\n        else:\n            user_value = sym.user_value\n\n        if user_value != sym.str_value:\n            print(\"warning: {} was assigned the value '{}' but got the \"\n                  \"value '{}' -- check dependencies\".format(\n                      sym.name_and_loc, user_value, sym.str_value),\n                  file=sys.stderr)\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/examples/print_config_tree.py",
    "content": "# Prints menu entries as a tree with its value in the .config file. This can be\n# handy e.g. for diffing between different .config files or versions of Kconfig files.\n#\n# Usage:\n#\n#   $ make [ARCH=<arch>] scriptconfig SCRIPT=print_config_tree.py [SCRIPT_ARG=<.config>]\n#\n#   If the variable WITH_HELP_DESC is modified to 'True', the help is added\n#   to the symbols.\n#\n# Here's a notation guide. The notation matches the one used by menuconfig\n# (scripts/kconfig/mconf):\n#\n#   [ ] prompt      - Bool\n#   < > prompt      - Tristate\n#   {M} prompt      - Tristate selected to m. Can only be set to m or y.\n#   -*- prompt      - Bool/tristate selected to y, pinning it\n#   -M- prompt      - Tristate selected to m that also has m visibility,\n#                     pinning it to m\n#   (foo) prompt    - String/int/hex symbol with value \"foo\"\n#   --> prompt      - The selected symbol in a choice in y mode. This\n#                     syntax is unique to this example.\n#\n# When modules are disabled, the .type attribute of TRISTATE symbols and\n# choices automatically changes to BOOL. This trick is used by the C\n# implementation as well, and gives the expected behavior without having to do\n# anything extra here. The original type is available in .orig_type if needed.\n#\n# Example output:\n#\n#   $ make scriptconfig SCRIPT=Kconfiglib/examples/print_config_tree.py [SCRIPT_ARG=<.config file>]\n#\n#   ======== Linux/x86 4.9.82 Kernel Configuration ========\n#\n#   [*] 64-bit kernel (64BIT)\n#       General setup\n#          ()  Cross-compiler tool prefix (CROSS_COMPILE)\n#          [ ] Compile also drivers which will not load (COMPILE_TEST)\n#          ()  Local version - append to kernel release (LOCALVERSION)\n#          [*] Automatically append version information to the version string (LOCALVERSION_AUTO)\n#          -*- Kernel compression mode\n#          ...\n#\n# With the variable WITH_HELP_DESC modified to 'True':\n#\n#   ======== Linux/x86 4.9.82 Kernel Configuration ========\n#\n#   [*] 64-bit kernel - Say yes to build a 64-bit kernel - formerly known as x86_64 Say no to build a 32-bit kernel - formerly known as i386  (64BIT)\n#       General setup\n#           ()  Cross-compiler tool prefix - Same as running 'make CROSS_COMPILE=prefix-' but stored for default make runs in this kernel build directory.  You don't need to set this unless you want the configured kernel build directory to select the cross-compiler automatically.  (CROSS_COMPILE)\n#           [ ] Compile also drivers which will not load - Some drivers can be compiled on a different platform than they are intended to be run on. Despite they cannot be loaded there (or even when they load they cannot be used due to missing HW support), developers still, opposing to distributors, might want to build such drivers to compile-test them.  If you are a developer and want to build everything available, say Y here. If you are a user/distributor, say N here to exclude useless drivers to be distributed.  (COMPILE_TEST)\n#           ...\n\nimport sys\n\nfrom kconfiglib import Kconfig, \\\n                       Symbol, MENU, COMMENT, \\\n                       BOOL, TRISTATE, STRING, INT, HEX, UNKNOWN, \\\n                       expr_value\n\n\n# Add help description to output\nWITH_HELP_DESC = False\n\n\ndef indent_print(s, indent):\n    print(indent*\" \" + s)\n\n\ndef value_str(sc):\n    \"\"\"\n    Returns the value part (\"[*]\", \"<M>\", \"(foo)\" etc.) of a menu entry.\n\n    sc: Symbol or Choice.\n    \"\"\"\n    if sc.type in (STRING, INT, HEX):\n        return \"({})\".format(sc.str_value)\n\n    # BOOL or TRISTATE\n\n    # The choice mode is an upper bound on the visibility of choice symbols, so\n    # we can check the choice symbols' own visibility to see if the choice is\n    # in y mode\n    if isinstance(sc, Symbol) and sc.choice and sc.visibility == 2:\n        # For choices in y mode, print '-->' next to the selected symbol\n        return \"-->\" if sc.choice.selection is sc else \"   \"\n\n    tri_val_str = (\" \", \"M\", \"*\")[sc.tri_value]\n\n    if len(sc.assignable) == 1:\n        # Pinned to a single value\n        return \"-{}-\".format(tri_val_str)\n\n    if sc.type == BOOL:\n        return \"[{}]\".format(tri_val_str)\n\n    if sc.type == TRISTATE:\n        if sc.assignable == (1, 2):\n            # m and y available\n            return \"{\" + tri_val_str + \"}\"  # Gets a bit confusing with .format()\n        return \"<{}>\".format(tri_val_str)\n\n\ndef node_str(node):\n    \"\"\"\n    Returns the complete menu entry text for a menu node, or \"\" for invisible\n    menu nodes. Invisible menu nodes are those that lack a prompt or that do\n    not have a satisfied prompt condition.\n\n    Example return value: \"[*] Bool symbol (BOOL)\"\n\n    The symbol name is printed in parentheses to the right of the prompt.\n    \"\"\"\n    if not node.prompt:\n        return \"\"\n\n    # Even for menu nodes for symbols and choices, it's wrong to check\n    # Symbol.visibility / Choice.visibility here. The reason is that a symbol\n    # (and a choice, in theory) can be defined in multiple locations, giving it\n    # multiple menu nodes, which do not necessarily all have the same prompt\n    # visibility. Symbol.visibility / Choice.visibility is calculated as the OR\n    # of the visibility of all the prompts.\n    prompt, prompt_cond = node.prompt\n    if not expr_value(prompt_cond):\n        return \"\"\n\n    if node.item == MENU:\n        return \"    \" + prompt\n\n    if node.item == COMMENT:\n        return \"    *** {} ***\".format(prompt)\n\n    # Symbol or Choice\n\n    sc = node.item\n\n    if sc.type == UNKNOWN:\n        # Skip symbols defined without a type (these are obscure and generate\n        # a warning)\n        return \"\"\n\n    # Add help text\n    if WITH_HELP_DESC:\n        prompt += ' - ' + str(node.help).replace('\\n', ' ').replace('\\r', '')\n\n    # {:3} sets the field width to three. Gives nice alignment for empty string\n    # values.\n    res = \"{:3} {}\".format(value_str(sc), prompt)\n\n    # Don't print the name for unnamed choices (the normal kind)\n    if sc.name is not None:\n        res += \" ({})\".format(sc.name)\n\n    return res\n\n\ndef print_menuconfig_nodes(node, indent):\n    \"\"\"\n    Prints a tree with all the menu entries rooted at 'node'. Child menu\n    entries are indented.\n    \"\"\"\n    while node:\n        string = node_str(node)\n        if string:\n            indent_print(string, indent)\n\n        if node.list:\n            print_menuconfig_nodes(node.list, indent + 8)\n\n        node = node.next\n\n\ndef print_menuconfig(kconf):\n    \"\"\"\n    Prints all menu entries for the configuration.\n    \"\"\"\n    # Print the expanded mainmenu text at the top. This is the same as\n    # kconf.top_node.prompt[0], but with variable references expanded.\n    print(\"\\n======== {} ========\\n\".format(kconf.mainmenu_text))\n\n    print_menuconfig_nodes(kconf.top_node.list, 0)\n    print(\"\")\n\n\nif __name__ == \"__main__\":\n\n    # Load Kconfig configuration files\n    kconf = Kconfig(sys.argv[1])\n\n    # Set default .config file or load it from argv\n    if len(sys.argv) == 2:\n        config_filename = '.config'\n    else:\n        config_filename = sys.argv[2]\n\n    kconf.load_config(config_filename)\n\n    # Print the configuration tree\n    print_menuconfig(kconf)\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/examples/print_sym_info.py",
    "content": "# Loads a Kconfig and a .config and prints a symbol.\n#\n# Usage:\n#\n#   $ make [ARCH=<arch>] scriptconfig SCRIPT=Kconfiglib/examples/print_sym_info.py SCRIPT_ARG=<name>\n#\n# Example output for SCRIPT_ARG=MODULES:\n#\n# menuconfig MODULES\n# \tbool\n# \tprompt \"Enable loadable module support\"\n# \toption modules\n# \thelp\n# \t  Kernel modules are small pieces of compiled code which can\n# \t  be inserted in the running kernel, rather than being\n# \t  permanently built into the kernel.  You use the \"modprobe\"\n# \t  tool to add (and sometimes remove) them.  If you say Y here,\n# \t  many parts of the kernel can be built as modules (by\n# \t  answering M instead of Y where indicated): this is most\n# \t  useful for infrequently used options which are not required\n# \t  for booting.  For more information, see the man pages for\n# \t  modprobe, lsmod, modinfo, insmod and rmmod.\n#\n# \t  If you say Y here, you will need to run \"make\n# \t  modules_install\" to put the modules under /lib/modules/\n# \t  where modprobe can find them (you may need to be root to do\n# \t  this).\n#\n# \t  If unsure, say Y.\n#\n# value = n\n# visibility = y\n# currently assignable values: n, y\n# defined at init/Kconfig:1674\n\nimport sys\n\nfrom kconfiglib import Kconfig, TRI_TO_STR\n\n\nif len(sys.argv) < 3:\n    sys.exit('Pass symbol name (without \"CONFIG_\" prefix) with SCRIPT_ARG=<name>')\n\nkconf = Kconfig(sys.argv[1])\nsym = kconf.syms[sys.argv[2]]\n\nprint(sym)\nprint(\"value = \" + sym.str_value)\nprint(\"visibility = \" + TRI_TO_STR[sym.visibility])\nprint(\"currently assignable values: \" +\n      \", \".join([TRI_TO_STR[v] for v in sym.assignable]))\n\nfor node in sym.nodes:\n    print(\"defined at {}:{}\".format(node.filename, node.linenr))\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/examples/print_tree.py",
    "content": "# Prints the menu tree of the configuration. Dependencies between symbols can\n# sometimes implicitly alter the menu structure (see kconfig-language.txt), and\n# that's implemented too.\n#\n# Note: See the Kconfig.node_iter() function as well, which provides a simpler\n# interface for walking the menu tree.\n#\n# Usage:\n#\n#   $ make [ARCH=<arch>] scriptconfig SCRIPT=Kconfiglib/examples/print_tree.py\n#\n# Example output:\n#\n#   ...\n#   config HAVE_KERNEL_LZO\n#   config HAVE_KERNEL_LZ4\n#   choice\n#     config KERNEL_GZIP\n#     config KERNEL_BZIP2\n#     config KERNEL_LZMA\n#     config KERNEL_XZ\n#     config KERNEL_LZO\n#     config KERNEL_LZ4\n#   config DEFAULT_HOSTNAME\n#   config SWAP\n#   config SYSVIPC\n#     config SYSVIPC_SYSCTL\n#   config POSIX_MQUEUE\n#     config POSIX_MQUEUE_SYSCTL\n#   config CROSS_MEMORY_ATTACH\n#   config FHANDLE\n#   config USELIB\n#   config AUDIT\n#   config HAVE_ARCH_AUDITSYSCALL\n#   config AUDITSYSCALL\n#   config AUDIT_WATCH\n#   config AUDIT_TREE\n#   menu \"IRQ subsystem\"\n#     config MAY_HAVE_SPARSE_IRQ\n#     config GENERIC_IRQ_LEGACY\n#     config GENERIC_IRQ_PROBE\n#   ...\n\nimport sys\n\nfrom kconfiglib import Kconfig, Symbol, Choice, MENU, COMMENT\n\n\ndef indent_print(s, indent):\n    print(indent*\" \" + s)\n\n\ndef print_items(node, indent):\n    while node:\n        if isinstance(node.item, Symbol):\n            indent_print(\"config \" + node.item.name, indent)\n\n        elif isinstance(node.item, Choice):\n            indent_print(\"choice\", indent)\n\n        elif node.item == MENU:\n            indent_print('menu \"{}\"'.format(node.prompt[0]), indent)\n\n        elif node.item == COMMENT:\n            indent_print('comment \"{}\"'.format(node.prompt[0]), indent)\n\n\n        if node.list:\n            print_items(node.list, indent + 2)\n\n        node = node.next\n\n\nkconf = Kconfig(sys.argv[1])\nprint_items(kconf.top_node, 0)\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/genconfig.py",
    "content": "#!/usr/bin/env python\n\n# Copyright (c) 2018-2019, Ulf Magnusson\n# SPDX-License-Identifier: ISC\n\n\"\"\"\nGenerates a header file with #defines from the configuration, matching the\nformat of include/generated/autoconf.h in the Linux kernel.\n\nOptionally, also writes the configuration output as a .config file. See\n--config-out.\n\nThe --sync-deps, --file-list, and --env-list options generate information that\ncan be used to avoid needless rebuilds/reconfigurations.\n\nBefore writing a header or configuration file, Kconfiglib compares the old\ncontents of the file against the new contents. If there's no change, the write\nis skipped. This avoids updating file metadata like the modification time, and\nmight save work depending on your build setup.\n\nBy default, the configuration is generated from '.config'. A different\nconfiguration file can be passed in the KCONFIG_CONFIG environment variable.\n\nA custom header string can be inserted at the beginning of generated\nconfiguration and header files by setting the KCONFIG_CONFIG_HEADER and\nKCONFIG_AUTOHEADER_HEADER environment variables, respectively (this also works\nfor other scripts). The string is not automatically made a comment (this is by\ndesign, to allow anything to be added), and no trailing newline is added, so\nadd '/* */', '#', and newlines as appropriate.\n\nSee https://www.gnu.org/software/make/manual/make.html#Multi_002dLine for a\nhandy way to define multi-line variables in makefiles, for use with custom\nheaders. Remember to export the variable to the environment.\n\"\"\"\nimport argparse\nimport os\nimport sys\n\nimport kconfiglib\n\n\nDEFAULT_SYNC_DEPS_PATH = \"deps/\"\n\n\ndef main():\n    parser = argparse.ArgumentParser(\n        formatter_class=argparse.RawDescriptionHelpFormatter,\n        description=__doc__)\n\n    parser.add_argument(\n        \"--header-path\",\n        metavar=\"HEADER_FILE\",\n        help=\"\"\"\nPath to write the generated header file to. If not specified, the path in the\nenvironment variable KCONFIG_AUTOHEADER is used if it is set, and 'config.h'\notherwise.\n\"\"\")\n\n    parser.add_argument(\n        \"--config-out\",\n        metavar=\"CONFIG_FILE\",\n        help=\"\"\"\nWrite the configuration to CONFIG_FILE. This is useful if you include .config\nfiles in Makefiles, as the generated configuration file will be a full .config\nfile even if .config is outdated. The generated configuration matches what\nolddefconfig would produce. If you use sync-deps, you can include\ndeps/auto.conf instead. --config-out is meant for cases where incremental build\ninformation isn't needed.\n\"\"\")\n\n    parser.add_argument(\n        \"--sync-deps\",\n        metavar=\"OUTPUT_DIR\",\n        nargs=\"?\",\n        const=DEFAULT_SYNC_DEPS_PATH,\n        help=\"\"\"\nEnable generation of symbol dependency information for incremental builds,\noptionally specifying the output directory (default: {}). See the docstring of\nKconfig.sync_deps() in Kconfiglib for more information.\n\"\"\".format(DEFAULT_SYNC_DEPS_PATH))\n\n    parser.add_argument(\n        \"--file-list\",\n        metavar=\"OUTPUT_FILE\",\n        help=\"\"\"\nWrite a list of all Kconfig files to OUTPUT_FILE, with one file per line. The\npaths are relative to $srctree (or to the current directory if $srctree is\nunset). Files appear in the order they're 'source'd.\n\"\"\")\n\n    parser.add_argument(\n        \"--env-list\",\n        metavar=\"OUTPUT_FILE\",\n        help=\"\"\"\nWrite a list of all environment variables referenced in Kconfig files to\nOUTPUT_FILE, with one variable per line. Each line has the format NAME=VALUE.\nOnly environment variables referenced with the preprocessor $(VAR) syntax are\nincluded, and not variables referenced with the older $VAR syntax (which is\nonly supported for backwards compatibility).\n\"\"\")\n\n    parser.add_argument(\n        \"kconfig\",\n        metavar=\"KCONFIG\",\n        nargs=\"?\",\n        default=\"Kconfig\",\n        help=\"Top-level Kconfig file (default: Kconfig)\")\n\n    args = parser.parse_args()\n\n\n    kconf = kconfiglib.Kconfig(args.kconfig, suppress_traceback=True)\n    kconf.load_config()\n\n    if args.header_path is None:\n        if \"KCONFIG_AUTOHEADER\" in os.environ:\n            kconf.write_autoconf()\n        else:\n            # Kconfiglib defaults to include/generated/autoconf.h to be\n            # compatible with the C tools. 'config.h' is used here instead for\n            # backwards compatibility. It's probably a saner default for tools\n            # as well.\n            kconf.write_autoconf(\"config.h\")\n    else:\n        kconf.write_autoconf(args.header_path)\n\n    if args.config_out is not None:\n        kconf.write_config(args.config_out, save_old=False)\n\n    if args.sync_deps is not None:\n        kconf.sync_deps(args.sync_deps)\n\n    if args.file_list is not None:\n        with _open_write(args.file_list) as f:\n            for path in kconf.kconfig_filenames:\n                f.write(path + \"\\n\")\n\n    if args.env_list is not None:\n        with _open_write(args.env_list) as f:\n            for env_var in kconf.env_vars:\n                f.write(\"{}={}\\n\".format(env_var, os.environ[env_var]))\n\n\ndef _open_write(path):\n    # Python 2/3 compatibility. io.open() is available on both, but makes\n    # write() expect 'unicode' strings on Python 2.\n\n    if sys.version_info[0] < 3:\n        return open(path, \"w\")\n    return open(path, \"w\", encoding=\"utf-8\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/guiconfig.py",
    "content": "#!/usr/bin/env python\n\n# Copyright (c) 2019, Ulf Magnusson\n# SPDX-License-Identifier: ISC\n\n\"\"\"\nOverview\n========\n\nA Tkinter-based menuconfig implementation, based around a treeview control and\na help display. The interface should feel familiar to people used to qconf\n('make xconfig'). Compatible with both Python 2 and Python 3.\n\nThe display can be toggled between showing the full tree and showing just a\nsingle menu (like menuconfig.py). Only single-menu mode distinguishes between\nsymbols defined with 'config' and symbols defined with 'menuconfig'.\n\nA show-all mode is available that shows invisible items in red.\n\nSupports both mouse and keyboard controls. The following keyboard shortcuts are\navailable:\n\n  Ctrl-S   : Save configuration\n  Ctrl-O   : Open configuration\n  Ctrl-A   : Toggle show-all mode\n  Ctrl-N   : Toggle show-name mode\n  Ctrl-M   : Toggle single-menu mode\n  Ctrl-F, /: Open jump-to dialog\n  ESC      : Close\n\nRunning\n=======\n\nguiconfig.py can be run either as a standalone executable or by calling the\nmenuconfig() function with an existing Kconfig instance. The second option is a\nbit inflexible in that it will still load and save .config, etc.\n\nWhen run in standalone mode, the top-level Kconfig file to load can be passed\nas a command-line argument. With no argument, it defaults to \"Kconfig\".\n\nThe KCONFIG_CONFIG environment variable specifies the .config file to load (if\nit exists) and save. If KCONFIG_CONFIG is unset, \".config\" is used.\n\nWhen overwriting a configuration file, the old version is saved to\n<filename>.old (e.g. .config.old).\n\n$srctree is supported through Kconfiglib.\n\"\"\"\n\n# Note: There's some code duplication with menuconfig.py below, especially for\n# the help text. Maybe some of it could be moved into kconfiglib.py or a shared\n# helper script, but OTOH it's pretty nice to have things standalone and\n# customizable.\n\nimport errno\nimport os\nimport sys\n\n_PY2 = sys.version_info[0] < 3\n\nif _PY2:\n    # Python 2\n    from Tkinter import *\n    import ttk\n    import tkFont as font\n    import tkFileDialog as filedialog\n    import tkMessageBox as messagebox\nelse:\n    # Python 3\n    from tkinter import *\n    import tkinter.ttk as ttk\n    import tkinter.font as font\n    from tkinter import filedialog, messagebox\n\nfrom kconfiglib import Symbol, Choice, MENU, COMMENT, MenuNode, \\\n                       BOOL, TRISTATE, STRING, INT, HEX, \\\n                       AND, OR, \\\n                       expr_str, expr_value, split_expr, \\\n                       standard_sc_expr_str, \\\n                       TRI_TO_STR, TYPE_TO_STR, \\\n                       standard_kconfig, standard_config_filename\n\n\n# If True, use GIF image data embedded in this file instead of separate GIF\n# files. See _load_images().\n_USE_EMBEDDED_IMAGES = True\n\n\n# Help text for the jump-to dialog\n_JUMP_TO_HELP = \"\"\"\\\nType one or more strings/regexes and press Enter to list items that match all\nof them. Python's regex flavor is used (see the 're' module). Double-clicking\nan item will jump to it. Item values can be toggled directly within the dialog.\\\n\"\"\"\n\n\ndef _main():\n    menuconfig(standard_kconfig(__doc__))\n\n\n# Global variables used below:\n#\n#   _root:\n#     The Toplevel instance for the main window\n#\n#   _tree:\n#     The Treeview in the main window\n#\n#   _jump_to_tree:\n#     The Treeview in the jump-to dialog. None if the jump-to dialog isn't\n#     open. Doubles as a flag.\n#\n#   _jump_to_matches:\n#     List of Nodes shown in the jump-to dialog\n#\n#   _menupath:\n#     The Label that shows the menu path of the selected item\n#\n#   _backbutton:\n#     The button shown in single-menu mode for jumping to the parent menu\n#\n#   _status_label:\n#     Label with status text shown at the bottom of the main window\n#     (\"Modified\", \"Saved to ...\", etc.)\n#\n#   _id_to_node:\n#     We can't use Node objects directly as Treeview item IDs, so we use their\n#     id()s instead. This dictionary maps Node id()s back to Nodes. (The keys\n#     are actually str(id(node)), just to simplify lookups.)\n#\n#   _cur_menu:\n#     The current menu. Ignored outside single-menu mode.\n#\n#   _show_all_var/_show_name_var/_single_menu_var:\n#     Tkinter Variable instances bound to the corresponding checkboxes\n#\n#   _show_all/_single_menu:\n#     Plain Python bools that track _show_all_var and _single_menu_var, to\n#     speed up and simplify things a bit\n#\n#   _conf_filename:\n#     File to save the configuration to\n#\n#   _minconf_filename:\n#     File to save minimal configurations to\n#\n#   _conf_changed:\n#     True if the configuration has been changed. If False, we don't bother\n#     showing the save-and-quit dialog.\n#\n#     We reset this to False whenever the configuration is saved.\n#\n#   _*_img:\n#     PhotoImage instances for images\n\n\ndef menuconfig(kconf):\n    \"\"\"\n    Launches the configuration interface, returning after the user exits.\n\n    kconf:\n      Kconfig instance to be configured\n    \"\"\"\n    global _kconf\n    global _conf_filename\n    global _minconf_filename\n    global _jump_to_tree\n    global _cur_menu\n\n    _kconf = kconf\n\n    _jump_to_tree = None\n\n    _create_id_to_node()\n\n    _create_ui()\n\n    # Filename to save configuration to\n    _conf_filename = standard_config_filename()\n\n    # Load existing configuration and check if it's outdated\n    _set_conf_changed(_load_config())\n\n    # Filename to save minimal configuration to\n    _minconf_filename = \"defconfig\"\n\n    # Current menu in single-menu mode\n    _cur_menu = _kconf.top_node\n\n    # Any visible items in the top menu?\n    if not _shown_menu_nodes(kconf.top_node):\n        # Nothing visible. Start in show-all mode and try again.\n        _show_all_var.set(True)\n        if not _shown_menu_nodes(kconf.top_node):\n            # Give up and show an error. It's nice to be able to assume that\n            # the tree is non-empty in the rest of the code.\n            _root.wait_visibility()\n            messagebox.showerror(\n                \"Error\",\n                \"Empty configuration -- nothing to configure.\\n\\n\"\n                \"Check that environment variables are set properly.\")\n            _root.destroy()\n            return\n\n    # Build the initial tree\n    _update_tree()\n\n    # Select the first item and focus the Treeview, so that keyboard controls\n    # work immediately\n    _select(_tree, _tree.get_children()[0])\n    _tree.focus_set()\n\n    # Make geometry information available for centering the window. This\n    # indirectly creates the window, so hide it so that it's never shown at the\n    # old location.\n    _root.withdraw()\n    _root.update_idletasks()\n\n    # Center the window\n    _root.geometry(\"+{}+{}\".format(\n        (_root.winfo_screenwidth() - _root.winfo_reqwidth())//2,\n        (_root.winfo_screenheight() - _root.winfo_reqheight())//2))\n\n    # Show it\n    _root.deiconify()\n\n    # Prevent the window from being automatically resized. Otherwise, it\n    # changes size when scrollbars appear/disappear before the user has\n    # manually resized it.\n    _root.geometry(_root.geometry())\n\n    _root.mainloop()\n\n\ndef _load_config():\n    # Loads any existing .config file. See the Kconfig.load_config() docstring.\n    #\n    # Returns True if .config is missing or outdated. We always prompt for\n    # saving the configuration in that case.\n\n    print(_kconf.load_config())\n    if not os.path.exists(_conf_filename):\n        # No .config\n        return True\n\n    return _needs_save()\n\n\ndef _needs_save():\n    # Returns True if a just-loaded .config file is outdated (would get\n    # modified when saving)\n\n    if _kconf.missing_syms:\n        # Assignments to undefined symbols in the .config\n        return True\n\n    for sym in _kconf.unique_defined_syms:\n        if sym.user_value is None:\n            if sym.config_string:\n                # Unwritten symbol\n                return True\n        elif sym.orig_type in (BOOL, TRISTATE):\n            if sym.tri_value != sym.user_value:\n                # Written bool/tristate symbol, new value\n                return True\n        elif sym.str_value != sym.user_value:\n            # Written string/int/hex symbol, new value\n            return True\n\n    # No need to prompt for save\n    return False\n\n\ndef _create_id_to_node():\n    global _id_to_node\n\n    _id_to_node = {str(id(node)): node for node in _kconf.node_iter()}\n\n\ndef _create_ui():\n    # Creates the main window UI\n\n    global _root\n    global _tree\n\n    # Create the root window. This initializes Tkinter and makes e.g.\n    # PhotoImage available, so do it early.\n    _root = Tk()\n\n    _load_images()\n    _init_misc_ui()\n    _fix_treeview_issues()\n\n    _create_top_widgets()\n    # Create the pane with the Kconfig tree and description text\n    panedwindow, _tree = _create_kconfig_tree_and_desc(_root)\n    panedwindow.grid(column=0, row=1, sticky=\"nsew\")\n    _create_status_bar()\n\n    _root.columnconfigure(0, weight=1)\n    # Only the pane with the Kconfig tree and description grows vertically\n    _root.rowconfigure(1, weight=1)\n\n    # Start with show-name disabled\n    _do_showname()\n\n    _tree.bind(\"<Left>\", _tree_left_key)\n    _tree.bind(\"<Right>\", _tree_right_key)\n    # Note: Binding this for the jump-to tree as well would cause issues due to\n    # the Tk bug mentioned in _tree_open()\n    _tree.bind(\"<<TreeviewOpen>>\", _tree_open)\n    # add=True to avoid overriding the description text update\n    _tree.bind(\"<<TreeviewSelect>>\", _update_menu_path, add=True)\n\n    _root.bind(\"<Control-s>\", _save)\n    _root.bind(\"<Control-o>\", _open)\n    _root.bind(\"<Control-a>\", _toggle_showall)\n    _root.bind(\"<Control-n>\", _toggle_showname)\n    _root.bind(\"<Control-m>\", _toggle_tree_mode)\n    _root.bind(\"<Control-f>\", _jump_to_dialog)\n    _root.bind(\"/\", _jump_to_dialog)\n    _root.bind(\"<Escape>\", _on_quit)\n\n\ndef _load_images():\n    # Loads GIF images, creating the global _*_img PhotoImage variables.\n    # Base64-encoded images embedded in this script are used if\n    # _USE_EMBEDDED_IMAGES is True, and separate image files in the same\n    # directory as the script otherwise.\n    #\n    # Using a global variable indirectly prevents the image from being\n    # garbage-collected. Passing an image to a Tkinter function isn't enough to\n    # keep it alive.\n\n    def load_image(name, data):\n        var_name = \"_{}_img\".format(name)\n\n        if _USE_EMBEDDED_IMAGES:\n            globals()[var_name] = PhotoImage(data=data, format=\"gif\")\n        else:\n            globals()[var_name] = PhotoImage(\n                file=os.path.join(os.path.dirname(__file__), name + \".gif\"),\n                format=\"gif\")\n\n    # Note: Base64 data can be put on the clipboard with\n    #   $ base64 -w0 foo.gif | xclip\n\n    load_image(\"icon\", \"R0lGODlhMAAwAPEDAAAAAADQAO7u7v///yH5BAUKAAMALAAAAAAwADAAAAL/nI+gy+2Pokyv2jazuZxryQjiSJZmyXxHeLbumH6sEATvW8OLNtf5bfLZRLFITzgEipDJ4mYxYv6A0ubuqYhWk66tVTE4enHer7jcKvt0LLUw6P45lvEprT6c0+v7OBuqhYdHohcoqIbSAHc4ljhDwrh1UlgSydRCWWlp5wiYZvmSuSh4IzrqV6p4cwhkCsmY+nhK6uJ6t1mrOhuJqfu6+WYiCiwl7HtLjNSZZZis/MeM7NY3TaRKS40ooDeoiVqIultsrav92bi9c3a5KkkOsOJZpSS99m4k/0zPng4Gks9JSbB+8DIcoQfnjwpZCHv5W+ip4aQrKrB0uOikYhiMCBw1/uPoQUMBADs=\")\n    load_image(\"n_bool\", \"R0lGODdhEAAQAPAAAAgICP///ywAAAAAEAAQAAACIISPacHtvp5kcb5qG85hZ2+BkyiRF8BBaEqtrKkqslEAADs=\")\n    load_image(\"y_bool\", \"R0lGODdhEAAQAPEAAAgICADQAP///wAAACwAAAAAEAAQAAACMoSPacLtvlh4YrIYsst2cV19AvaVF9CUXBNJJoum7ymrsKuCnhiupIWjSSjAFuWhSCIKADs=\")\n    load_image(\"n_tri\", \"R0lGODlhEAAQAPD/AAEBAf///yH5BAUKAAIALAAAAAAQABAAAAInlI+pBrAKQnCPSUlXvFhznlkfeGwjKZhnJ65h6nrfi6h0st2QXikFADs=\")\n    load_image(\"m_tri\", \"R0lGODlhEAAQAPEDAAEBAeQMuv///wAAACH5BAUKAAMALAAAAAAQABAAAAI5nI+pBrAWAhPCjYhiAJQCnWmdoElHGVBoiK5M21ofXFpXRIrgiecqxkuNciZIhNOZFRNI24PhfEoLADs=\")\n    load_image(\"y_tri\", \"R0lGODlhEAAQAPEDAAICAgDQAP///wAAACH5BAUKAAMALAAAAAAQABAAAAI0nI+pBrAYBhDCRRUypfmergmgZ4xjMpmaw2zmxk7cCB+pWiVqp4MzDwn9FhGZ5WFjIZeGAgA7\")\n    load_image(\"m_my\", \"R0lGODlhEAAQAPEDAAAAAOQMuv///wAAACH5BAUKAAMALAAAAAAQABAAAAI5nIGpxiAPI2ghxFinq/ZygQhc94zgZopmOLYf67anGr+oZdp02emfV5n9MEHN5QhqICETxkABbQ4KADs=\")\n    load_image(\"y_my\", \"R0lGODlhEAAQAPH/AAAAAADQAAPRA////yH5BAUKAAQALAAAAAAQABAAAAM+SArcrhCMSSuIM9Q8rxxBWIXawIBkmWonupLd565Um9G1PIs59fKmzw8WnAlusBYR2SEIN6DmAmqBLBxYSAIAOw==\")\n    load_image(\"n_locked\", \"R0lGODlhEAAQAPABAAAAAP///yH5BAUKAAEALAAAAAAQABAAAAIgjB8AyKwN04pu0vMutpqqz4Hih4ydlnUpyl2r23pxUAAAOw==\")\n    load_image(\"m_locked\", \"R0lGODlhEAAQAPD/AAAAAOQMuiH5BAUKAAIALAAAAAAQABAAAAIylC8AyKwN04ohnGcqqlZmfXDWI26iInZoyiore05walolV39ftxsYHgL9QBBMBGFEFAAAOw==\")\n    load_image(\"y_locked\", \"R0lGODlhEAAQAPD/AAAAAADQACH5BAUKAAIALAAAAAAQABAAAAIylC8AyKzNgnlCtoDTwvZwrHydIYpQmR3KWq4uK74IOnp0HQPmnD3cOVlUIAgKsShkFAAAOw==\")\n    load_image(\"not_selected\", \"R0lGODlhEAAQAPD/AAAAAP///yH5BAUKAAIALAAAAAAQABAAAAIrlA2px6IBw2IpWglOvTYhzmUbGD3kNZ5QqrKn2YrqigCxZoMelU6No9gdCgA7\")\n    load_image(\"selected\", \"R0lGODlhEAAQAPD/AAAAAP///yH5BAUKAAIALAAAAAAQABAAAAIzlA2px6IBw2IpWglOvTah/kTZhimASJomiqonlLov1qptHTsgKSEzh9H8QI0QzNPwmRoFADs=\")\n    load_image(\"edit\", \"R0lGODlhEAAQAPIFAAAAAKOLAMuuEPvXCvrxvgAAAAAAAAAAACH5BAUKAAUALAAAAAAQABAAAANCWLqw/gqMBp8cszJxcwVC2FEOEIAi5kVBi3IqWZhuCGMyfdpj2e4pnK+WAshmvxeAcETWlsxPkkBtsqBMa8TIBSQAADs=\")\n\n\ndef _fix_treeview_issues():\n    # Fixes some Treeview issues\n\n    global _treeview_rowheight\n\n    style = ttk.Style()\n\n    # The treeview rowheight isn't adjusted automatically on high-DPI displays,\n    # so do it ourselves. The font will probably always be TkDefaultFont, but\n    # play it safe and look it up.\n\n    _treeview_rowheight = font.Font(font=style.lookup(\"Treeview\", \"font\")) \\\n        .metrics(\"linespace\") + 2\n\n    style.configure(\"Treeview\", rowheight=_treeview_rowheight)\n\n    # Work around regression in https://core.tcl.tk/tk/tktview?name=509cafafae,\n    # which breaks tag background colors\n\n    for option in \"foreground\", \"background\":\n        # Filter out any styles starting with (\"!disabled\", \"!selected\", ...).\n        # style.map() returns an empty list for missing options, so this should\n        # be future-safe.\n        style.map(\n            \"Treeview\",\n            **{option: [elm for elm in style.map(\"Treeview\", query_opt=option)\n                        if elm[:2] != (\"!disabled\", \"!selected\")]})\n\n\ndef _init_misc_ui():\n    # Does misc. UI initialization, like setting the title, icon, and theme\n\n    _root.title(_kconf.mainmenu_text)\n    # iconphoto() isn't available in Python 2's Tkinter\n    _root.tk.call(\"wm\", \"iconphoto\", _root._w, \"-default\", _icon_img)\n    # Reducing the width of the window to 1 pixel makes it move around, at\n    # least on GNOME. Prevent weird stuff like that.\n    _root.minsize(128, 128)\n    _root.protocol(\"WM_DELETE_WINDOW\", _on_quit)\n\n    # Use the 'clam' theme on *nix if it's available. It looks nicer than the\n    # 'default' theme.\n    if _root.tk.call(\"tk\", \"windowingsystem\") == \"x11\":\n        style = ttk.Style()\n        if \"clam\" in style.theme_names():\n            style.theme_use(\"clam\")\n\n\ndef _create_top_widgets():\n    # Creates the controls above the Kconfig tree in the main window\n\n    global _show_all_var\n    global _show_name_var\n    global _single_menu_var\n    global _menupath\n    global _backbutton\n\n    topframe = ttk.Frame(_root)\n    topframe.grid(column=0, row=0, sticky=\"ew\")\n\n    ttk.Button(topframe, text=\"Save\", command=_save) \\\n        .grid(column=0, row=0, sticky=\"ew\", padx=\".05c\", pady=\".05c\")\n\n    ttk.Button(topframe, text=\"Save as...\", command=_save_as) \\\n        .grid(column=1, row=0, sticky=\"ew\")\n\n    ttk.Button(topframe, text=\"Save minimal (advanced)...\",\n               command=_save_minimal) \\\n        .grid(column=2, row=0, sticky=\"ew\", padx=\".05c\")\n\n    ttk.Button(topframe, text=\"Open...\", command=_open) \\\n        .grid(column=3, row=0)\n\n    ttk.Button(topframe, text=\"Jump to...\", command=_jump_to_dialog) \\\n        .grid(column=4, row=0, padx=\".05c\")\n\n    _show_name_var = BooleanVar()\n    ttk.Checkbutton(topframe, text=\"Show name\", command=_do_showname,\n                    variable=_show_name_var) \\\n        .grid(column=0, row=1, sticky=\"nsew\", padx=\".05c\", pady=\"0 .05c\",\n              ipady=\".2c\")\n\n    _show_all_var = BooleanVar()\n    ttk.Checkbutton(topframe, text=\"Show all\", command=_do_showall,\n                    variable=_show_all_var) \\\n        .grid(column=1, row=1, sticky=\"nsew\", pady=\"0 .05c\")\n\n    # Allow the show-all and single-menu status to be queried via plain global\n    # Python variables, which is faster and simpler\n\n    def show_all_updated(*_):\n        global _show_all\n        _show_all = _show_all_var.get()\n\n    _trace_write(_show_all_var, show_all_updated)\n    _show_all_var.set(False)\n\n    _single_menu_var = BooleanVar()\n    ttk.Checkbutton(topframe, text=\"Single-menu mode\", command=_do_tree_mode,\n                    variable=_single_menu_var) \\\n        .grid(column=2, row=1, sticky=\"nsew\", padx=\".05c\", pady=\"0 .05c\")\n\n    _backbutton = ttk.Button(topframe, text=\"<--\", command=_leave_menu,\n                             state=\"disabled\")\n    _backbutton.grid(column=0, row=4, sticky=\"nsew\", padx=\".05c\", pady=\"0 .05c\")\n\n    def tree_mode_updated(*_):\n        global _single_menu\n        _single_menu = _single_menu_var.get()\n\n        if _single_menu:\n            _backbutton.grid()\n        else:\n            _backbutton.grid_remove()\n\n    _trace_write(_single_menu_var, tree_mode_updated)\n    _single_menu_var.set(False)\n\n    # Column to the right of the buttons that the menu path extends into, so\n    # that it can grow wider than the buttons\n    topframe.columnconfigure(5, weight=1)\n\n    _menupath = ttk.Label(topframe)\n    _menupath.grid(column=0, row=3, columnspan=6, sticky=\"w\", padx=\"0.05c\",\n                   pady=\"0 .05c\")\n\n\ndef _create_kconfig_tree_and_desc(parent):\n    # Creates a Panedwindow with a Treeview that shows Kconfig nodes and a Text\n    # that shows a description of the selected node. Returns a tuple with the\n    # Panedwindow and the Treeview. This code is shared between the main window\n    # and the jump-to dialog.\n\n    panedwindow = ttk.Panedwindow(parent, orient=VERTICAL)\n\n    tree_frame, tree = _create_kconfig_tree(panedwindow)\n    desc_frame, desc = _create_kconfig_desc(panedwindow)\n\n    panedwindow.add(tree_frame, weight=1)\n    panedwindow.add(desc_frame)\n\n    def tree_select(_):\n        # The Text widget does not allow editing the text in its disabled\n        # state. We need to temporarily enable it.\n        desc[\"state\"] = \"normal\"\n\n        sel = tree.selection()\n        if not sel:\n            desc.delete(\"1.0\", \"end\")\n            desc[\"state\"] = \"disabled\"\n            return\n\n        # Text.replace() is not available in Python 2's Tkinter\n        desc.delete(\"1.0\", \"end\")\n        desc.insert(\"end\", _info_str(_id_to_node[sel[0]]))\n\n        desc[\"state\"] = \"disabled\"\n\n    tree.bind(\"<<TreeviewSelect>>\", tree_select)\n    tree.bind(\"<1>\", _tree_click)\n    tree.bind(\"<Double-1>\", _tree_double_click)\n    tree.bind(\"<Return>\", _tree_enter)\n    tree.bind(\"<KP_Enter>\", _tree_enter)\n    tree.bind(\"<space>\", _tree_toggle)\n    tree.bind(\"n\", _tree_set_val(0))\n    tree.bind(\"m\", _tree_set_val(1))\n    tree.bind(\"y\", _tree_set_val(2))\n\n    return panedwindow, tree\n\n\ndef _create_kconfig_tree(parent):\n    # Creates a Treeview for showing Kconfig nodes\n\n    frame = ttk.Frame(parent)\n\n    tree = ttk.Treeview(frame, selectmode=\"browse\", height=20,\n                        columns=(\"name\",))\n    tree.heading(\"#0\", text=\"Option\", anchor=\"w\")\n    tree.heading(\"name\", text=\"Name\", anchor=\"w\")\n\n    tree.tag_configure(\"n-bool\", image=_n_bool_img)\n    tree.tag_configure(\"y-bool\", image=_y_bool_img)\n    tree.tag_configure(\"m-tri\", image=_m_tri_img)\n    tree.tag_configure(\"n-tri\", image=_n_tri_img)\n    tree.tag_configure(\"m-tri\", image=_m_tri_img)\n    tree.tag_configure(\"y-tri\", image=_y_tri_img)\n    tree.tag_configure(\"m-my\", image=_m_my_img)\n    tree.tag_configure(\"y-my\", image=_y_my_img)\n    tree.tag_configure(\"n-locked\", image=_n_locked_img)\n    tree.tag_configure(\"m-locked\", image=_m_locked_img)\n    tree.tag_configure(\"y-locked\", image=_y_locked_img)\n    tree.tag_configure(\"not-selected\", image=_not_selected_img)\n    tree.tag_configure(\"selected\", image=_selected_img)\n    tree.tag_configure(\"edit\", image=_edit_img)\n    tree.tag_configure(\"invisible\", foreground=\"red\")\n\n    tree.grid(column=0, row=0, sticky=\"nsew\")\n\n    _add_vscrollbar(frame, tree)\n\n    frame.columnconfigure(0, weight=1)\n    frame.rowconfigure(0, weight=1)\n\n    # Create items for all menu nodes. These can be detached/moved later.\n    # Micro-optimize this a bit.\n    insert = tree.insert\n    id_ = id\n    Symbol_ = Symbol\n    for node in _kconf.node_iter():\n        item = node.item\n        insert(\"\", \"end\", iid=id_(node),\n               values=item.name if item.__class__ is Symbol_ else \"\")\n\n    return frame, tree\n\n\ndef _create_kconfig_desc(parent):\n    # Creates a Text for showing the description of the selected Kconfig node\n\n    frame = ttk.Frame(parent)\n\n    desc = Text(frame, height=12, wrap=\"none\", borderwidth=0,\n                state=\"disabled\")\n    desc.grid(column=0, row=0, sticky=\"nsew\")\n\n    # Work around not being to Ctrl-C/V text from a disabled Text widget, with a\n    # tip found in https://stackoverflow.com/questions/3842155/is-there-a-way-to-make-the-tkinter-text-widget-read-only\n    desc.bind(\"<1>\", lambda _: desc.focus_set())\n\n    _add_vscrollbar(frame, desc)\n\n    frame.columnconfigure(0, weight=1)\n    frame.rowconfigure(0, weight=1)\n\n    return frame, desc\n\n\ndef _add_vscrollbar(parent, widget):\n    # Adds a vertical scrollbar to 'widget' that's only shown as needed\n\n    vscrollbar = ttk.Scrollbar(parent, orient=\"vertical\",\n                               command=widget.yview)\n    vscrollbar.grid(column=1, row=0, sticky=\"ns\")\n\n    def yscrollcommand(first, last):\n        # Only show the scrollbar when needed. 'first' and 'last' are\n        # strings.\n        if float(first) <= 0.0 and float(last) >= 1.0:\n            vscrollbar.grid_remove()\n        else:\n            vscrollbar.grid()\n\n        vscrollbar.set(first, last)\n\n    widget[\"yscrollcommand\"] = yscrollcommand\n\n\ndef _create_status_bar():\n    # Creates the status bar at the bottom of the main window\n\n    global _status_label\n\n    _status_label = ttk.Label(_root, anchor=\"e\", padding=\"0 0 0.4c 0\")\n    _status_label.grid(column=0, row=3, sticky=\"ew\")\n\n\ndef _set_status(s):\n    # Sets the text in the status bar to 's'\n\n    _status_label[\"text\"] = s\n\n\ndef _set_conf_changed(changed):\n    # Updates the status re. whether there are unsaved changes\n\n    global _conf_changed\n\n    _conf_changed = changed\n    if changed:\n        _set_status(\"Modified\")\n\n\ndef _update_tree():\n    # Updates the Kconfig tree in the main window by first detaching all nodes\n    # and then updating and reattaching them. The tree structure might have\n    # changed.\n\n    # If a selected/focused item is detached and later reattached, it stays\n    # selected/focused. That can give multiple selections even though\n    # selectmode=browse. Save and later restore the selection and focus as a\n    # workaround.\n    old_selection = _tree.selection()\n    old_focus = _tree.focus()\n\n    # Detach all tree items before re-stringing them. This is relatively fast,\n    # luckily.\n    _tree.detach(*_id_to_node.keys())\n\n    if _single_menu:\n        _build_menu_tree()\n    else:\n        _build_full_tree(_kconf.top_node)\n\n    _tree.selection_set(old_selection)\n    _tree.focus(old_focus)\n\n\ndef _build_full_tree(menu):\n    # Updates the tree starting from menu.list, in full-tree mode. To speed\n    # things up, only open menus are updated. The menu-at-a-time logic here is\n    # to deal with invisible items that can show up outside show-all mode (see\n    # _shown_full_nodes()).\n\n    for node in _shown_full_nodes(menu):\n        _add_to_tree(node, _kconf.top_node)\n\n        # _shown_full_nodes() includes nodes from menus rooted at symbols, so\n        # we only need to check \"real\" menus/choices here\n        if node.list and not isinstance(node.item, Symbol):\n            if _tree.item(id(node), \"open\"):\n                _build_full_tree(node)\n            else:\n                # We're just probing here, so _shown_menu_nodes() will work\n                # fine, and might be a bit faster\n                shown = _shown_menu_nodes(node)\n                if shown:\n                    # Dummy element to make the open/closed toggle appear\n                    _tree.move(id(shown[0]), id(shown[0].parent), \"end\")\n\n\ndef _shown_full_nodes(menu):\n    # Returns the list of menu nodes shown in 'menu' (a menu node for a menu)\n    # for full-tree mode. A tricky detail is that invisible items need to be\n    # shown if they have visible children.\n\n    def rec(node):\n        res = []\n\n        while node:\n            if _visible(node) or _show_all:\n                res.append(node)\n                if node.list and isinstance(node.item, Symbol):\n                    # Nodes from menu created from dependencies\n                    res += rec(node.list)\n\n            elif node.list and isinstance(node.item, Symbol):\n                # Show invisible symbols (defined with either 'config' and\n                # 'menuconfig') if they have visible children. This can happen\n                # for an m/y-valued symbol with an optional prompt\n                # ('prompt \"foo\" is COND') that is currently disabled.\n                shown_children = rec(node.list)\n                if shown_children:\n                    res.append(node)\n                    res += shown_children\n\n            node = node.next\n\n        return res\n\n    return rec(menu.list)\n\n\ndef _build_menu_tree():\n    # Updates the tree in single-menu mode. See _build_full_tree() as well.\n\n    for node in _shown_menu_nodes(_cur_menu):\n        _add_to_tree(node, _cur_menu)\n\n\ndef _shown_menu_nodes(menu):\n    # Used for single-menu mode. Similar to _shown_full_nodes(), but doesn't\n    # include children of symbols defined with 'menuconfig'.\n\n    def rec(node):\n        res = []\n\n        while node:\n            if _visible(node) or _show_all:\n                res.append(node)\n                if node.list and not node.is_menuconfig:\n                    res += rec(node.list)\n\n            elif node.list and isinstance(node.item, Symbol):\n                shown_children = rec(node.list)\n                if shown_children:\n                    # Invisible item with visible children\n                    res.append(node)\n                    if not node.is_menuconfig:\n                        res += shown_children\n\n            node = node.next\n\n        return res\n\n    return rec(menu.list)\n\n\ndef _visible(node):\n    # Returns True if the node should appear in the menu (outside show-all\n    # mode)\n\n    return node.prompt and expr_value(node.prompt[1]) and not \\\n        (node.item == MENU and not expr_value(node.visibility))\n\n\ndef _add_to_tree(node, top):\n    # Adds 'node' to the tree, at the end of its menu. We rely on going through\n    # the nodes linearly to get the correct order. 'top' holds the menu that\n    # corresponds to the top-level menu, and can vary in single-menu mode.\n\n    parent = node.parent\n    _tree.move(id(node), \"\" if parent is top else id(parent), \"end\")\n    _tree.item(\n        id(node),\n        text=_node_str(node),\n        # The _show_all test avoids showing invisible items in red outside\n        # show-all mode, which could look confusing/broken. Invisible symbols\n        # are shown outside show-all mode if an invisible symbol has visible\n        # children in an implicit menu.\n        tags=_img_tag(node) if _visible(node) or not _show_all else\n            _img_tag(node) + \" invisible\")\n\n\ndef _node_str(node):\n    # Returns the string shown to the right of the image (if any) for the node\n\n    if node.prompt:\n        if node.item == COMMENT:\n            s = \"*** {} ***\".format(node.prompt[0])\n        else:\n            s = node.prompt[0]\n\n        if isinstance(node.item, Symbol):\n            sym = node.item\n\n            # Print \"(NEW)\" next to symbols without a user value (from e.g. a\n            # .config), but skip it for choice symbols in choices in y mode,\n            # and for symbols of UNKNOWN type (which generate a warning though)\n            if sym.user_value is None and sym.type and not \\\n                (sym.choice and sym.choice.tri_value == 2):\n\n                s += \" (NEW)\"\n\n    elif isinstance(node.item, Symbol):\n        # Symbol without prompt (can show up in show-all)\n        s = \"<{}>\".format(node.item.name)\n\n    else:\n        # Choice without prompt. Use standard_sc_expr_str() so that it shows up\n        # as '<choice (name if any)>'.\n        s = standard_sc_expr_str(node.item)\n\n\n    if isinstance(node.item, Symbol):\n        sym = node.item\n        if sym.orig_type == STRING:\n            s += \": \" + sym.str_value\n        elif sym.orig_type in (INT, HEX):\n            s = \"({}) {}\".format(sym.str_value, s)\n\n    elif isinstance(node.item, Choice) and node.item.tri_value == 2:\n        # Print the prompt of the selected symbol after the choice for\n        # choices in y mode\n        sym = node.item.selection\n        if sym:\n            for sym_node in sym.nodes:\n                # Use the prompt used at this choice location, in case the\n                # choice symbol is defined in multiple locations\n                if sym_node.parent is node and sym_node.prompt:\n                    s += \" ({})\".format(sym_node.prompt[0])\n                    break\n            else:\n                # If the symbol isn't defined at this choice location, then\n                # just use whatever prompt we can find for it\n                for sym_node in sym.nodes:\n                    if sym_node.prompt:\n                        s += \" ({})\".format(sym_node.prompt[0])\n                        break\n\n    # In single-menu mode, print \"--->\" next to nodes that have menus that can\n    # potentially be entered. Print \"----\" if the menu is empty. We don't allow\n    # those to be entered.\n    if _single_menu and node.is_menuconfig:\n        s += \"  --->\" if _shown_menu_nodes(node) else \"  ----\"\n\n    return s\n\n\ndef _img_tag(node):\n    # Returns the tag for the image that should be shown next to 'node', or the\n    # empty string if it shouldn't have an image\n\n    item = node.item\n\n    if item in (MENU, COMMENT) or not item.orig_type:\n        return \"\"\n\n    if item.orig_type in (STRING, INT, HEX):\n        return \"edit\"\n\n    # BOOL or TRISTATE\n\n    if _is_y_mode_choice_sym(item):\n        # Choice symbol in y-mode choice\n        return \"selected\" if item.choice.selection is item else \"not-selected\"\n\n    if len(item.assignable) <= 1:\n        # Pinned to a single value\n        return \"\" if isinstance(item, Choice) else item.str_value + \"-locked\"\n\n    if item.type == BOOL:\n        return item.str_value + \"-bool\"\n\n    # item.type == TRISTATE\n    if item.assignable == (1, 2):\n        return item.str_value + \"-my\"\n    return item.str_value + \"-tri\"\n\n\ndef _is_y_mode_choice_sym(item):\n    # The choice mode is an upper bound on the visibility of choice symbols, so\n    # we can check the choice symbols' own visibility to see if the choice is\n    # in y mode\n    return isinstance(item, Symbol) and item.choice and item.visibility == 2\n\n\ndef _tree_click(event):\n    # Click on the Kconfig Treeview\n\n    tree = event.widget\n    if tree.identify_element(event.x, event.y) == \"image\":\n        item = tree.identify_row(event.y)\n        # Select the item before possibly popping up a dialog for\n        # string/int/hex items, so that its help is visible\n        _select(tree, item)\n        _change_node(_id_to_node[item], tree.winfo_toplevel())\n        return \"break\"\n\n\ndef _tree_double_click(event):\n    # Double-click on the Kconfig treeview\n\n    # Do an extra check to avoid weirdness when double-clicking in the tree\n    # heading area\n    if not _in_heading(event):\n        return _tree_enter(event)\n\n\ndef _in_heading(event):\n    # Returns True if 'event' took place in the tree heading\n\n    tree = event.widget\n    return hasattr(tree, \"identify_region\") and \\\n        tree.identify_region(event.x, event.y) in (\"heading\", \"separator\")\n\n\ndef _tree_enter(event):\n    # Enter press or double-click within the Kconfig treeview. Prefer to\n    # open/close/enter menus, but toggle the value if that's not possible.\n\n    tree = event.widget\n    sel = tree.focus()\n    if sel:\n        node = _id_to_node[sel]\n\n        if tree.get_children(sel):\n            _tree_toggle_open(sel)\n        elif _single_menu_mode_menu(node, tree):\n            _enter_menu_and_select_first(node)\n        else:\n            _change_node(node, tree.winfo_toplevel())\n\n        return \"break\"\n\n\ndef _tree_toggle(event):\n    # Space press within the Kconfig treeview. Prefer to toggle the value, but\n    # open/close/enter the menu if that's not possible.\n\n    tree = event.widget\n    sel = tree.focus()\n    if sel:\n        node = _id_to_node[sel]\n\n        if _changeable(node):\n            _change_node(node, tree.winfo_toplevel())\n        elif _single_menu_mode_menu(node, tree):\n            _enter_menu_and_select_first(node)\n        elif tree.get_children(sel):\n            _tree_toggle_open(sel)\n\n        return \"break\"\n\n\ndef _tree_left_key(_):\n    # Left arrow key press within the Kconfig treeview\n\n    if _single_menu:\n        # Leave the current menu in single-menu mode\n        _leave_menu()\n        return \"break\"\n\n    # Otherwise, default action\n\n\ndef _tree_right_key(_):\n    # Right arrow key press within the Kconfig treeview\n\n    sel = _tree.focus()\n    if sel:\n        node = _id_to_node[sel]\n        # If the node can be entered in single-menu mode, do it\n        if _single_menu_mode_menu(node, _tree):\n            _enter_menu_and_select_first(node)\n            return \"break\"\n\n    # Otherwise, default action\n\n\ndef _single_menu_mode_menu(node, tree):\n    # Returns True if single-menu mode is on and 'node' is an (interface)\n    # menu that can be entered\n\n    return _single_menu and tree is _tree and node.is_menuconfig and \\\n           _shown_menu_nodes(node)\n\n\ndef _changeable(node):\n    # Returns True if 'node' is a Symbol/Choice whose value can be changed\n\n    sc = node.item\n\n    if not isinstance(sc, (Symbol, Choice)):\n        return False\n\n    # This will hit for invisible symbols, which appear in show-all mode and\n    # when an invisible symbol has visible children (which can happen e.g. for\n    # symbols with optional prompts)\n    if not (node.prompt and expr_value(node.prompt[1])):\n        return False\n\n    return sc.orig_type in (STRING, INT, HEX) or len(sc.assignable) > 1 \\\n           or _is_y_mode_choice_sym(sc)\n\n\ndef _tree_toggle_open(item):\n    # Opens/closes the Treeview item 'item'\n\n    if _tree.item(item, \"open\"):\n        _tree.item(item, open=False)\n    else:\n        node = _id_to_node[item]\n        if not isinstance(node.item, Symbol):\n            # Can only get here in full-tree mode\n            _build_full_tree(node)\n        _tree.item(item, open=True)\n\n\ndef _tree_set_val(tri_val):\n    def tree_set_val(event):\n        # n/m/y press within the Kconfig treeview\n\n        # Sets the value of the currently selected item to 'tri_val', if that\n        # value can be assigned\n\n        sel = event.widget.focus()\n        if sel:\n            sc = _id_to_node[sel].item\n            if isinstance(sc, (Symbol, Choice)) and tri_val in sc.assignable:\n                _set_val(sc, tri_val)\n\n    return tree_set_val\n\n\ndef _tree_open(_):\n    # Lazily populates the Kconfig tree when menus are opened in full-tree mode\n\n    if _single_menu:\n        # Work around https://core.tcl.tk/tk/tktview?name=368fa4561e\n        # (\"ttk::treeview open/closed indicators can be toggled while hidden\").\n        # Clicking on the hidden indicator will call _build_full_tree() in\n        # single-menu mode otherwise.\n        return\n\n    node = _id_to_node[_tree.focus()]\n    # _shown_full_nodes() includes nodes from menus rooted at symbols, so we\n    # only need to check \"real\" menus and choices here\n    if not isinstance(node.item, Symbol):\n        _build_full_tree(node)\n\n\ndef _update_menu_path(_):\n    # Updates the displayed menu path when nodes are selected in the Kconfig\n    # treeview\n\n    sel = _tree.selection()\n    _menupath[\"text\"] = _menu_path_info(_id_to_node[sel[0]]) if sel else \"\"\n\n\ndef _item_row(item):\n    # Returns the row number 'item' appears on within the Kconfig treeview,\n    # starting from the top of the tree. Used to preserve scrolling.\n    #\n    # ttkTreeview.c in the Tk sources defines a RowNumber() function that does\n    # the same thing, but it's not exposed.\n\n    row = 0\n\n    while True:\n        prev = _tree.prev(item)\n        if prev:\n            item = prev\n            row += _n_rows(item)\n        else:\n            item = _tree.parent(item)\n            if not item:\n                return row\n            row += 1\n\n\ndef _n_rows(item):\n    # _item_row() helper. Returns the number of rows occupied by 'item' and #\n    # its children.\n\n    rows = 1\n\n    if _tree.item(item, \"open\"):\n        for child in _tree.get_children(item):\n            rows += _n_rows(child)\n\n    return rows\n\n\ndef _attached(item):\n    # Heuristic for checking if a Treeview item is attached. Doesn't seem to be\n    # good APIs for this. Might fail for super-obscure cases with tiny trees,\n    # but you'd just get a small scroll mess-up.\n\n    return bool(_tree.next(item) or _tree.prev(item) or _tree.parent(item))\n\n\ndef _change_node(node, parent):\n    # Toggles/changes the value of 'node'. 'parent' is the parent window\n    # (either the main window or the jump-to dialog), in case we need to pop up\n    # a dialog.\n\n    if not _changeable(node):\n        return\n\n    # sc = symbol/choice\n    sc = node.item\n\n    if sc.type in (INT, HEX, STRING):\n        s = _set_val_dialog(node, parent)\n\n        # Tkinter can return 'unicode' strings on Python 2, which Kconfiglib\n        # can't deal with. UTF-8-encode the string to work around it.\n        if _PY2 and isinstance(s, unicode):\n            s = s.encode(\"utf-8\", \"ignore\")\n\n        if s is not None:\n            _set_val(sc, s)\n\n    elif len(sc.assignable) == 1:\n        # Handles choice symbols for choices in y mode, which are a special\n        # case: .assignable can be (2,) while .tri_value is 0.\n        _set_val(sc, sc.assignable[0])\n\n    else:\n        # Set the symbol to the value after the current value in\n        # sc.assignable, with wrapping\n        val_index = sc.assignable.index(sc.tri_value)\n        _set_val(sc, sc.assignable[(val_index + 1) % len(sc.assignable)])\n\n\ndef _set_val(sc, val):\n    # Wrapper around Symbol/Choice.set_value() for updating the menu state and\n    # _conf_changed\n\n    # Use the string representation of tristate values. This makes the format\n    # consistent for all symbol types.\n    if val in TRI_TO_STR:\n        val = TRI_TO_STR[val]\n\n    if val != sc.str_value:\n        sc.set_value(val)\n        _set_conf_changed(True)\n\n        # Update the tree and try to preserve the scroll. Do a cheaper variant\n        # than in the show-all case, that might mess up the scroll slightly in\n        # rare cases, but is fast and flicker-free.\n\n        stayput = _loc_ref_item()  # Item to preserve scroll for\n        old_row = _item_row(stayput)\n\n        _update_tree()\n\n        # If the reference item disappeared (can happen if the change was done\n        # from the jump-to dialog), then avoid messing with the scroll and hope\n        # for the best\n        if _attached(stayput):\n            _tree.yview_scroll(_item_row(stayput) - old_row, \"units\")\n\n        if _jump_to_tree:\n            _update_jump_to_display()\n\n\ndef _set_val_dialog(node, parent):\n    # Pops up a dialog for setting the value of the string/int/hex\n    # symbol at node 'node'. 'parent' is the parent window.\n\n    def ok(_=None):\n        # No 'nonlocal' in Python 2\n        global _entry_res\n\n        s = entry.get()\n        if sym.type == HEX and not s.startswith((\"0x\", \"0X\")):\n            s = \"0x\" + s\n\n        if _check_valid(dialog, entry, sym, s):\n            _entry_res = s\n            dialog.destroy()\n\n    def cancel(_=None):\n        global _entry_res\n        _entry_res = None\n        dialog.destroy()\n\n    sym = node.item\n\n    dialog = Toplevel(parent)\n    dialog.title(\"Enter {} value\".format(TYPE_TO_STR[sym.type]))\n    dialog.resizable(False, False)\n    dialog.transient(parent)\n    dialog.protocol(\"WM_DELETE_WINDOW\", cancel)\n\n    ttk.Label(dialog, text=node.prompt[0] + \":\") \\\n        .grid(column=0, row=0, columnspan=2, sticky=\"w\", padx=\".3c\",\n              pady=\".2c .05c\")\n\n    entry = ttk.Entry(dialog, width=30)\n    # Start with the previous value in the editbox, selected\n    entry.insert(0, sym.str_value)\n    entry.selection_range(0, \"end\")\n    entry.grid(column=0, row=1, columnspan=2, sticky=\"ew\", padx=\".3c\")\n    entry.focus_set()\n\n    range_info = _range_info(sym)\n    if range_info:\n        ttk.Label(dialog, text=range_info) \\\n            .grid(column=0, row=2, columnspan=2, sticky=\"w\", padx=\".3c\",\n                  pady=\".2c 0\")\n\n    ttk.Button(dialog, text=\"OK\", command=ok) \\\n        .grid(column=0, row=4 if range_info else 3, sticky=\"e\", padx=\".3c\",\n              pady=\".4c\")\n\n    ttk.Button(dialog, text=\"Cancel\", command=cancel) \\\n        .grid(column=1, row=4 if range_info else 3, padx=\"0 .3c\")\n\n    # Give all horizontal space to the grid cell with the OK button, so that\n    # Cancel moves to the right\n    dialog.columnconfigure(0, weight=1)\n\n    _center_on_root(dialog)\n\n    # Hack to scroll the entry so that the end of the text is shown, from\n    # https://stackoverflow.com/questions/29334544/why-does-tkinters-entry-xview-moveto-fail.\n    # Related Tk ticket: https://core.tcl.tk/tk/info/2513186fff\n    def scroll_entry(_):\n        _root.update_idletasks()\n        entry.unbind(\"<Expose>\")\n        entry.xview_moveto(1)\n    entry.bind(\"<Expose>\", scroll_entry)\n\n    # The dialog must be visible before we can grab the input\n    dialog.wait_visibility()\n    dialog.grab_set()\n\n    dialog.bind(\"<Return>\", ok)\n    dialog.bind(\"<KP_Enter>\", ok)\n    dialog.bind(\"<Escape>\", cancel)\n\n    # Wait for the user to be done with the dialog\n    parent.wait_window(dialog)\n\n    # Regrab the input in the parent\n    parent.grab_set()\n\n    return _entry_res\n\n\ndef _center_on_root(dialog):\n    # Centers 'dialog' on the root window. It often ends up at some bad place\n    # like the top-left corner of the screen otherwise. See the menuconfig()\n    # function, which has similar logic.\n\n    dialog.withdraw()\n    _root.update_idletasks()\n\n    dialog_width = dialog.winfo_reqwidth()\n    dialog_height = dialog.winfo_reqheight()\n\n    screen_width = _root.winfo_screenwidth()\n    screen_height = _root.winfo_screenheight()\n\n    x = _root.winfo_rootx() + (_root.winfo_width() - dialog_width)//2\n    y = _root.winfo_rooty() + (_root.winfo_height() - dialog_height)//2\n\n    # Clamp so that no part of the dialog is outside the screen\n    if x + dialog_width > screen_width:\n        x = screen_width - dialog_width\n    elif x < 0:\n        x = 0\n    if y + dialog_height > screen_height:\n        y = screen_height - dialog_height\n    elif y < 0:\n        y = 0\n\n    dialog.geometry(\"+{}+{}\".format(x, y))\n\n    dialog.deiconify()\n\n\ndef _check_valid(dialog, entry, sym, s):\n    # Returns True if the string 's' is a well-formed value for 'sym'.\n    # Otherwise, pops up an error and returns False.\n\n    if sym.type not in (INT, HEX):\n        # Anything goes for non-int/hex symbols\n        return True\n\n    base = 10 if sym.type == INT else 16\n    try:\n        int(s, base)\n    except ValueError:\n        messagebox.showerror(\n            \"Bad value\",\n            \"'{}' is a malformed {} value\".format(\n                s, TYPE_TO_STR[sym.type]),\n            parent=dialog)\n        entry.focus_set()\n        return False\n\n    for low_sym, high_sym, cond in sym.ranges:\n        if expr_value(cond):\n            low_s = low_sym.str_value\n            high_s = high_sym.str_value\n\n            if not int(low_s, base) <= int(s, base) <= int(high_s, base):\n                messagebox.showerror(\n                    \"Value out of range\",\n                    \"{} is outside the range {}-{}\".format(s, low_s, high_s),\n                    parent=dialog)\n                entry.focus_set()\n                return False\n\n            break\n\n    return True\n\n\ndef _range_info(sym):\n    # Returns a string with information about the valid range for the symbol\n    # 'sym', or None if 'sym' doesn't have a range\n\n    if sym.type in (INT, HEX):\n        for low, high, cond in sym.ranges:\n            if expr_value(cond):\n                return \"Range: {}-{}\".format(low.str_value, high.str_value)\n\n    return None\n\n\ndef _save(_=None):\n    # Tries to save the configuration\n\n    if _try_save(_kconf.write_config, _conf_filename, \"configuration\"):\n        _set_conf_changed(False)\n\n    _tree.focus_set()\n\n\ndef _save_as():\n    # Pops up a dialog for saving the configuration to a specific location\n\n    global _conf_filename\n\n    filename = _conf_filename\n    while True:\n        filename = filedialog.asksaveasfilename(\n            title=\"Save configuration as\",\n            initialdir=os.path.dirname(filename),\n            initialfile=os.path.basename(filename),\n            parent=_root)\n\n        if not filename:\n            break\n\n        if _try_save(_kconf.write_config, filename, \"configuration\"):\n            _conf_filename = filename\n            break\n\n    _tree.focus_set()\n\n\ndef _save_minimal():\n    # Pops up a dialog for saving a minimal configuration (defconfig) to a\n    # specific location\n\n    global _minconf_filename\n\n    filename = _minconf_filename\n    while True:\n        filename = filedialog.asksaveasfilename(\n            title=\"Save minimal configuration as\",\n            initialdir=os.path.dirname(filename),\n            initialfile=os.path.basename(filename),\n            parent=_root)\n\n        if not filename:\n            break\n\n        if _try_save(_kconf.write_min_config, filename,\n                     \"minimal configuration\"):\n\n            _minconf_filename = filename\n            break\n\n    _tree.focus_set()\n\n\ndef _open(_=None):\n    # Pops up a dialog for loading a configuration\n\n    global _conf_filename\n\n    if _conf_changed and \\\n        not messagebox.askokcancel(\n            \"Unsaved changes\",\n            \"You have unsaved changes. Load new configuration anyway?\"):\n\n        return\n\n    filename = _conf_filename\n    while True:\n        filename = filedialog.askopenfilename(\n            title=\"Open configuration\",\n            initialdir=os.path.dirname(filename),\n            initialfile=os.path.basename(filename),\n            parent=_root)\n\n        if not filename:\n            break\n\n        if _try_load(filename):\n            # Maybe something fancier could be done here later to try to\n            # preserve the scroll\n\n            _conf_filename = filename\n            _set_conf_changed(_needs_save())\n\n            if _single_menu and not _shown_menu_nodes(_cur_menu):\n                # Turn on show-all if we're in single-menu mode and would end\n                # up with an empty menu\n                _show_all_var.set(True)\n\n            _update_tree()\n\n            break\n\n    _tree.focus_set()\n\n\ndef _toggle_showname(_):\n    # Toggles show-name mode on/off\n\n    _show_name_var.set(not _show_name_var.get())\n    _do_showname()\n\n\ndef _do_showname():\n    # Updates the UI for the current show-name setting\n\n    # Columns do not automatically shrink/expand, so we have to update\n    # column widths ourselves\n\n    tree_width = _tree.winfo_width()\n\n    if _show_name_var.get():\n        _tree[\"displaycolumns\"] = (\"name\",)\n        _tree[\"show\"] = \"tree headings\"\n        name_width = tree_width//3\n        _tree.column(\"#0\", width=max(tree_width - name_width, 1))\n        _tree.column(\"name\", width=name_width)\n    else:\n        _tree[\"displaycolumns\"] = ()\n        _tree[\"show\"] = \"tree\"\n        _tree.column(\"#0\", width=tree_width)\n\n    _tree.focus_set()\n\n\ndef _toggle_showall(_):\n    # Toggles show-all mode on/off\n\n    _show_all_var.set(not _show_all)\n    _do_showall()\n\n\ndef _do_showall():\n    # Updates the UI for the current show-all setting\n\n    # Don't allow turning off show-all if we'd end up with no visible nodes\n    if _nothing_shown():\n        _show_all_var.set(True)\n        return\n\n    # Save scroll information. old_scroll can end up negative here, if the\n    # reference item isn't shown (only invisible items on the screen, and\n    # show-all being turned off).\n\n    stayput = _vis_loc_ref_item()\n    # Probe the middle of the first row, to play it safe. identify_row(0) seems\n    # to return the row before the top row.\n    old_scroll = _item_row(stayput) - \\\n        _item_row(_tree.identify_row(_treeview_rowheight//2))\n\n    _update_tree()\n\n    if _show_all:\n        # Deep magic: Unless we call update_idletasks(), the scroll adjustment\n        # below is restricted to the height of the old tree, instead of the\n        # height of the new tree. Since the tree with show-all on is guaranteed\n        # to be taller, and we want the maximum range, we only call it when\n        # turning show-all on.\n        #\n        # Strictly speaking, something similar ought to be done when changing\n        # symbol values, but it causes annoying flicker, and in 99% of cases\n        # things work anyway there (with usually minor scroll mess-ups in the\n        # 1% case).\n        _root.update_idletasks()\n\n    # Restore scroll\n    _tree.yview(_item_row(stayput) - old_scroll)\n\n    _tree.focus_set()\n\n\ndef _nothing_shown():\n    # _do_showall() helper. Returns True if no nodes would get\n    # shown with the current show-all setting. Also handles the\n    # (obscure) case when there are no visible nodes in the entire\n    # tree, meaning guiconfig was automatically started in\n    # show-all mode, which mustn't be turned off.\n\n    return not _shown_menu_nodes(\n        _cur_menu if _single_menu else _kconf.top_node)\n\n\ndef _toggle_tree_mode(_):\n    # Toggles single-menu mode on/off\n\n    _single_menu_var.set(not _single_menu)\n    _do_tree_mode()\n\n\ndef _do_tree_mode():\n    # Updates the UI for the current tree mode (full-tree or single-menu)\n\n    loc_ref_node = _id_to_node[_loc_ref_item()]\n\n    if not _single_menu:\n        # _jump_to() -> _enter_menu() already updates the tree, but\n        # _jump_to() -> load_parents() doesn't, because it isn't always needed.\n        # We always need to update the tree here, e.g. to add/remove \"--->\".\n        _update_tree()\n\n    _jump_to(loc_ref_node)\n    _tree.focus_set()\n\n\ndef _enter_menu_and_select_first(menu):\n    # Enters the menu 'menu' and selects the first item. Used in single-menu\n    # mode.\n\n    _enter_menu(menu)\n    _select(_tree, _tree.get_children()[0])\n\n\ndef _enter_menu(menu):\n    # Enters the menu 'menu'. Used in single-menu mode.\n\n    global _cur_menu\n\n    _cur_menu = menu\n    _update_tree()\n\n    _backbutton[\"state\"] = \"disabled\" if menu is _kconf.top_node else \"normal\"\n\n\ndef _leave_menu():\n    # Leaves the current menu. Used in single-menu mode.\n\n    global _cur_menu\n\n    if _cur_menu is not _kconf.top_node:\n        old_menu = _cur_menu\n\n        _cur_menu = _parent_menu(_cur_menu)\n        _update_tree()\n\n        _select(_tree, id(old_menu))\n\n        if _cur_menu is _kconf.top_node:\n            _backbutton[\"state\"] = \"disabled\"\n\n    _tree.focus_set()\n\n\ndef _select(tree, item):\n    # Selects, focuses, and see()s 'item' in 'tree'\n\n    tree.selection_set(item)\n    tree.focus(item)\n    tree.see(item)\n\n\ndef _loc_ref_item():\n    # Returns a Treeview item that can serve as a reference for the current\n    # scroll location. We try to make this item stay on the same row on the\n    # screen when updating the tree.\n\n    # If the selected item is visible, use that\n    sel = _tree.selection()\n    if sel and _tree.bbox(sel[0]):\n        return sel[0]\n\n    # Otherwise, use the middle item on the screen. If it doesn't exist, the\n    # tree is probably really small, so use the first item in the entire tree.\n    return _tree.identify_row(_tree.winfo_height()//2) or \\\n        _tree.get_children()[0]\n\n\ndef _vis_loc_ref_item():\n    # Like _loc_ref_item(), but finds a visible item around the reference item.\n    # Used when changing show-all mode, where non-visible (red) items will\n    # disappear.\n\n    item = _loc_ref_item()\n\n    vis_before = _vis_before(item)\n    if vis_before and _tree.bbox(vis_before):\n        return vis_before\n\n    vis_after = _vis_after(item)\n    if vis_after and _tree.bbox(vis_after):\n        return vis_after\n\n    return vis_before or vis_after\n\n\ndef _vis_before(item):\n    # _vis_loc_ref_item() helper. Returns the first visible (not red) item,\n    # searching backwards from 'item'.\n\n    while item:\n        if not _tree.tag_has(\"invisible\", item):\n            return item\n\n        prev = _tree.prev(item)\n        item = prev if prev else _tree.parent(item)\n\n    return None\n\n\ndef _vis_after(item):\n    # _vis_loc_ref_item() helper. Returns the first visible (not red) item,\n    # searching forwards from 'item'.\n\n    while item:\n        if not _tree.tag_has(\"invisible\", item):\n            return item\n\n        next = _tree.next(item)\n        if next:\n            item = next\n        else:\n            item = _tree.parent(item)\n            if not item:\n                break\n            item = _tree.next(item)\n\n    return None\n\n\ndef _on_quit(_=None):\n    # Called when the user wants to exit\n\n    if not _conf_changed:\n        _quit(\"No changes to save (for '{}')\".format(_conf_filename))\n        return\n\n    while True:\n        ync = messagebox.askyesnocancel(\"Quit\", \"Save changes?\")\n        if ync is None:\n            return\n\n        if not ync:\n            _quit(\"Configuration ({}) was not saved\".format(_conf_filename))\n            return\n\n        if _try_save(_kconf.write_config, _conf_filename, \"configuration\"):\n            # _try_save() already prints the \"Configuration saved to ...\"\n            # message\n            _quit()\n            return\n\n\ndef _quit(msg=None):\n    # Quits the application\n\n    # Do not call sys.exit() here, in case we're being run from a script\n    _root.destroy()\n    if msg:\n        print(msg)\n\n\ndef _try_save(save_fn, filename, description):\n    # Tries to save a configuration file. Pops up an error and returns False on\n    # failure.\n    #\n    # save_fn:\n    #   Function to call with 'filename' to save the file\n    #\n    # description:\n    #   String describing the thing being saved\n\n    try:\n        # save_fn() returns a message to print\n        msg = save_fn(filename)\n        _set_status(msg)\n        print(msg)\n        return True\n    except EnvironmentError as e:\n        messagebox.showerror(\n            \"Error saving \" + description,\n            \"Error saving {} to '{}': {} (errno: {})\"\n            .format(description, e.filename, e.strerror,\n                    errno.errorcode[e.errno]))\n        return False\n\n\ndef _try_load(filename):\n    # Tries to load a configuration file. Pops up an error and returns False on\n    # failure.\n    #\n    # filename:\n    #   Configuration file to load\n\n    try:\n        msg = _kconf.load_config(filename)\n        _set_status(msg)\n        print(msg)\n        return True\n    except EnvironmentError as e:\n        messagebox.showerror(\n            \"Error loading configuration\",\n            \"Error loading '{}': {} (errno: {})\"\n            .format(filename, e.strerror, errno.errorcode[e.errno]))\n        return False\n\n\ndef _jump_to_dialog(_=None):\n    # Pops up a dialog for jumping directly to a particular node. Symbol values\n    # can also be changed within the dialog.\n    #\n    # Note: There's nothing preventing this from doing an incremental search\n    # like menuconfig.py does, but currently it's a bit jerky for large Kconfig\n    # trees, at least when inputting the beginning of the search string. We'd\n    # need to somehow only update the tree items that are shown in the Treeview\n    # to fix it.\n\n    global _jump_to_tree\n\n    def search(_=None):\n        _update_jump_to_matches(msglabel, entry.get())\n\n    def jump_to_selected(event=None):\n        # Jumps to the selected node and closes the dialog\n\n        # Ignore double clicks on the image and in the heading area\n        if event and (tree.identify_element(event.x, event.y) == \"image\" or\n                      _in_heading(event)):\n            return\n\n        sel = tree.selection()\n        if not sel:\n            return\n\n        node = _id_to_node[sel[0]]\n\n        if node not in _shown_menu_nodes(_parent_menu(node)):\n            _show_all_var.set(True)\n            if not _single_menu:\n                # See comment in _do_tree_mode()\n                _update_tree()\n\n        _jump_to(node)\n\n        dialog.destroy()\n\n    def tree_select(_):\n        jumpto_button[\"state\"] = \"normal\" if tree.selection() else \"disabled\"\n\n\n    dialog = Toplevel(_root)\n    dialog.geometry(\"+{}+{}\".format(\n        _root.winfo_rootx() + 50, _root.winfo_rooty() + 50))\n    dialog.title(\"Jump to symbol/choice/menu/comment\")\n    dialog.minsize(128, 128)  # See _create_ui()\n    dialog.transient(_root)\n\n    ttk.Label(dialog, text=_JUMP_TO_HELP) \\\n        .grid(column=0, row=0, columnspan=2, sticky=\"w\", padx=\".1c\",\n              pady=\".1c\")\n\n    entry = ttk.Entry(dialog)\n    entry.grid(column=0, row=1, sticky=\"ew\", padx=\".1c\", pady=\".1c\")\n    entry.focus_set()\n\n    entry.bind(\"<Return>\", search)\n    entry.bind(\"<KP_Enter>\", search)\n\n    ttk.Button(dialog, text=\"Search\", command=search) \\\n        .grid(column=1, row=1, padx=\"0 .1c\", pady=\"0 .1c\")\n\n    msglabel = ttk.Label(dialog)\n    msglabel.grid(column=0, row=2, sticky=\"w\", pady=\"0 .1c\")\n\n    panedwindow, tree = _create_kconfig_tree_and_desc(dialog)\n    panedwindow.grid(column=0, row=3, columnspan=2, sticky=\"nsew\")\n\n    # Clear tree\n    tree.set_children(\"\")\n\n    _jump_to_tree = tree\n\n    jumpto_button = ttk.Button(dialog, text=\"Jump to selected item\",\n                               state=\"disabled\", command=jump_to_selected)\n    jumpto_button.grid(column=0, row=4, columnspan=2, sticky=\"ns\", pady=\".1c\")\n\n    dialog.columnconfigure(0, weight=1)\n    # Only the pane with the Kconfig tree and description grows vertically\n    dialog.rowconfigure(3, weight=1)\n\n    # See the menuconfig() function\n    _root.update_idletasks()\n    dialog.geometry(dialog.geometry())\n\n    # The dialog must be visible before we can grab the input\n    dialog.wait_visibility()\n    dialog.grab_set()\n\n    tree.bind(\"<Double-1>\", jump_to_selected)\n    tree.bind(\"<Return>\", jump_to_selected)\n    tree.bind(\"<KP_Enter>\", jump_to_selected)\n    # add=True to avoid overriding the description text update\n    tree.bind(\"<<TreeviewSelect>>\", tree_select, add=True)\n\n    dialog.bind(\"<Escape>\", lambda _: dialog.destroy())\n\n    # Wait for the user to be done with the dialog\n    _root.wait_window(dialog)\n\n    _jump_to_tree = None\n\n    _tree.focus_set()\n\n\ndef _update_jump_to_matches(msglabel, search_string):\n    # Searches for nodes matching the search string and updates\n    # _jump_to_matches. Puts a message in 'msglabel' if there are no matches,\n    # or regex errors.\n\n    global _jump_to_matches\n\n    _jump_to_tree.selection_set(())\n\n    try:\n        # We could use re.IGNORECASE here instead of lower(), but this is\n        # faster for regexes like '.*debug$' (though the '.*' is redundant\n        # there). Those probably have bad interactions with re.search(), which\n        # matches anywhere in the string.\n        regex_searches = [re.compile(regex).search\n                          for regex in search_string.lower().split()]\n    except re.error as e:\n        msg = \"Bad regular expression\"\n        # re.error.msg was added in Python 3.5\n        if hasattr(e, \"msg\"):\n            msg += \": \" + e.msg\n        msglabel[\"text\"] = msg\n        # Clear tree\n        _jump_to_tree.set_children(\"\")\n        return\n\n    _jump_to_matches = []\n    add_match = _jump_to_matches.append\n\n    for node in _sorted_sc_nodes():\n        # Symbol/choice\n        sc = node.item\n\n        for search in regex_searches:\n            # Both the name and the prompt might be missing, since\n            # we're searching both symbols and choices\n\n            # Does the regex match either the symbol name or the\n            # prompt (if any)?\n            if not (sc.name and search(sc.name.lower()) or\n                    node.prompt and search(node.prompt[0].lower())):\n\n                # Give up on the first regex that doesn't match, to\n                # speed things up a bit when multiple regexes are\n                # entered\n                break\n\n        else:\n            add_match(node)\n\n    # Search menus and comments\n\n    for node in _sorted_menu_comment_nodes():\n        for search in regex_searches:\n            if not search(node.prompt[0].lower()):\n                break\n        else:\n            add_match(node)\n\n    msglabel[\"text\"] = \"\" if _jump_to_matches else \"No matches\"\n\n    _update_jump_to_display()\n\n    if _jump_to_matches:\n        item = id(_jump_to_matches[0])\n        _jump_to_tree.selection_set(item)\n        _jump_to_tree.focus(item)\n\n\ndef _update_jump_to_display():\n    # Updates the images and text for the items in _jump_to_matches, and sets\n    # them as the items of _jump_to_tree\n\n    # Micro-optimize a bit\n    item = _jump_to_tree.item\n    id_ = id\n    node_str = _node_str\n    img_tag = _img_tag\n    visible = _visible\n    for node in _jump_to_matches:\n        item(id_(node),\n             text=node_str(node),\n             tags=img_tag(node) if visible(node) else\n                 img_tag(node) + \" invisible\")\n\n    _jump_to_tree.set_children(\"\", *map(id, _jump_to_matches))\n\n\ndef _jump_to(node):\n    # Jumps directly to 'node' and selects it\n\n    if _single_menu:\n        _enter_menu(_parent_menu(node))\n    else:\n        _load_parents(node)\n\n    _select(_tree, id(node))\n\n\n# Obscure Python: We never pass a value for cached_nodes, and it keeps pointing\n# to the same list. This avoids a global.\ndef _sorted_sc_nodes(cached_nodes=[]):\n    # Returns a sorted list of symbol and choice nodes to search. The symbol\n    # nodes appear first, sorted by name, and then the choice nodes, sorted by\n    # prompt and (secondarily) name.\n\n    if not cached_nodes:\n        # Add symbol nodes\n        for sym in sorted(_kconf.unique_defined_syms,\n                          key=lambda sym: sym.name):\n            # += is in-place for lists\n            cached_nodes += sym.nodes\n\n        # Add choice nodes\n\n        choices = sorted(_kconf.unique_choices,\n                         key=lambda choice: choice.name or \"\")\n\n        cached_nodes += sorted(\n            [node\n             for choice in choices\n                 for node in choice.nodes],\n            key=lambda node: node.prompt[0] if node.prompt else \"\")\n\n    return cached_nodes\n\n\ndef _sorted_menu_comment_nodes(cached_nodes=[]):\n    # Returns a list of menu and comment nodes to search, sorted by prompt,\n    # with the menus first\n\n    if not cached_nodes:\n        def prompt_text(mc):\n            return mc.prompt[0]\n\n        cached_nodes += sorted(_kconf.menus, key=prompt_text)\n        cached_nodes += sorted(_kconf.comments, key=prompt_text)\n\n    return cached_nodes\n\n\ndef _load_parents(node):\n    # Menus are lazily populated as they're opened in full-tree mode, but\n    # jumping to an item needs its parent menus to be populated. This function\n    # populates 'node's parents.\n\n    # Get all parents leading up to 'node', sorted with the root first\n    parents = []\n    cur = node.parent\n    while cur is not _kconf.top_node:\n        parents.append(cur)\n        cur = cur.parent\n    parents.reverse()\n\n    for i, parent in enumerate(parents):\n        if not _tree.item(id(parent), \"open\"):\n            # Found a closed menu. Populate it and all the remaining menus\n            # leading up to 'node'.\n            for parent in parents[i:]:\n                # We only need to populate \"real\" menus/choices. Implicit menus\n                # are populated when their parents menus are entered.\n                if not isinstance(parent.item, Symbol):\n                    _build_full_tree(parent)\n            return\n\n\ndef _parent_menu(node):\n    # Returns the menu node of the menu that contains 'node'. In addition to\n    # proper 'menu's, this might also be a 'menuconfig' symbol or a 'choice'.\n    # \"Menu\" here means a menu in the interface.\n\n    menu = node.parent\n    while not menu.is_menuconfig:\n        menu = menu.parent\n    return menu\n\n\ndef _trace_write(var, fn):\n    # Makes fn() be called whenever the Tkinter Variable 'var' changes value\n\n    # trace_variable() is deprecated according to the docstring,\n    # which recommends trace_add()\n    if hasattr(var, \"trace_add\"):\n        var.trace_add(\"write\", fn)\n    else:\n        var.trace_variable(\"w\", fn)\n\n\ndef _info_str(node):\n    # Returns information about the menu node 'node' as a string.\n    #\n    # The helper functions are responsible for adding newlines. This allows\n    # them to return \"\" if they don't want to add any output.\n\n    if isinstance(node.item, Symbol):\n        sym = node.item\n\n        return (\n            _name_info(sym) +\n            _help_info(sym) +\n            _direct_dep_info(sym) +\n            _defaults_info(sym) +\n            _select_imply_info(sym) +\n            _kconfig_def_info(sym)\n        )\n\n    if isinstance(node.item, Choice):\n        choice = node.item\n\n        return (\n            _name_info(choice) +\n            _help_info(choice) +\n            'Mode: {}\\n\\n'.format(choice.str_value) +\n            _choice_syms_info(choice) +\n            _direct_dep_info(choice) +\n            _defaults_info(choice) +\n            _kconfig_def_info(choice)\n        )\n\n    # node.item in (MENU, COMMENT)\n    return _kconfig_def_info(node)\n\n\ndef _name_info(sc):\n    # Returns a string with the name of the symbol/choice. Choices are shown as\n    # <choice (name if any)>.\n\n    return (sc.name if sc.name else standard_sc_expr_str(sc)) + \"\\n\\n\"\n\n\ndef _value_info(sym):\n    # Returns a string showing 'sym's value\n\n    # Only put quotes around the value for string symbols\n    return \"Value: {}\\n\".format(\n        '\"{}\"'.format(sym.str_value)\n        if sym.orig_type == STRING\n        else sym.str_value)\n\n\ndef _choice_syms_info(choice):\n    # Returns a string listing the choice symbols in 'choice'. Adds\n    # \"(selected)\" next to the selected one.\n\n    s = \"Choice symbols:\\n\"\n\n    for sym in choice.syms:\n        s += \"  - \" + sym.name\n        if sym is choice.selection:\n            s += \" (selected)\"\n        s += \"\\n\"\n\n    return s + \"\\n\"\n\n\ndef _help_info(sc):\n    # Returns a string with the help text(s) of 'sc' (Symbol or Choice).\n    # Symbols and choices defined in multiple locations can have multiple help\n    # texts.\n\n    s = \"\"\n\n    for node in sc.nodes:\n        if node.help is not None:\n            s += node.help + \"\\n\\n\"\n\n    return s\n\n\ndef _direct_dep_info(sc):\n    # Returns a string describing the direct dependencies of 'sc' (Symbol or\n    # Choice). The direct dependencies are the OR of the dependencies from each\n    # definition location. The dependencies at each definition location come\n    # from 'depends on' and dependencies inherited from parent items.\n\n    return \"\" if sc.direct_dep is _kconf.y else \\\n        'Direct dependencies (={}):\\n{}\\n' \\\n        .format(TRI_TO_STR[expr_value(sc.direct_dep)],\n                _split_expr_info(sc.direct_dep, 2))\n\n\ndef _defaults_info(sc):\n    # Returns a string describing the defaults of 'sc' (Symbol or Choice)\n\n    if not sc.defaults:\n        return \"\"\n\n    s = \"Default\"\n    if len(sc.defaults) > 1:\n        s += \"s\"\n    s += \":\\n\"\n\n    for val, cond in sc.orig_defaults:\n        s += \"  - \"\n        if isinstance(sc, Symbol):\n            s += _expr_str(val)\n\n            # Skip the tristate value hint if the expression is just a single\n            # symbol. _expr_str() already shows its value as a string.\n            #\n            # This also avoids showing the tristate value for string/int/hex\n            # defaults, which wouldn't make any sense.\n            if isinstance(val, tuple):\n                s += '  (={})'.format(TRI_TO_STR[expr_value(val)])\n        else:\n            # Don't print the value next to the symbol name for choice\n            # defaults, as it looks a bit confusing\n            s += val.name\n        s += \"\\n\"\n\n        if cond is not _kconf.y:\n            s += \"    Condition (={}):\\n{}\" \\\n                 .format(TRI_TO_STR[expr_value(cond)],\n                         _split_expr_info(cond, 4))\n\n    return s + \"\\n\"\n\n\ndef _split_expr_info(expr, indent):\n    # Returns a string with 'expr' split into its top-level && or || operands,\n    # with one operand per line, together with the operand's value. This is\n    # usually enough to get something readable for long expressions. A fancier\n    # recursive thingy would be possible too.\n    #\n    # indent:\n    #   Number of leading spaces to add before the split expression.\n\n    if len(split_expr(expr, AND)) > 1:\n        split_op = AND\n        op_str = \"&&\"\n    else:\n        split_op = OR\n        op_str = \"||\"\n\n    s = \"\"\n    for i, term in enumerate(split_expr(expr, split_op)):\n        s += \"{}{} {}\".format(indent*\" \",\n                              \"  \" if i == 0 else op_str,\n                              _expr_str(term))\n\n        # Don't bother showing the value hint if the expression is just a\n        # single symbol. _expr_str() already shows its value.\n        if isinstance(term, tuple):\n            s += \"  (={})\".format(TRI_TO_STR[expr_value(term)])\n\n        s += \"\\n\"\n\n    return s\n\n\ndef _select_imply_info(sym):\n    # Returns a string with information about which symbols 'select' or 'imply'\n    # 'sym'. The selecting/implying symbols are grouped according to which\n    # value they select/imply 'sym' to (n/m/y).\n\n    def sis(expr, val, title):\n        # sis = selects/implies\n        sis = [si for si in split_expr(expr, OR) if expr_value(si) == val]\n        if not sis:\n            return \"\"\n\n        res = title\n        for si in sis:\n            res += \"  - {}\\n\".format(split_expr(si, AND)[0].name)\n        return res + \"\\n\"\n\n    s = \"\"\n\n    if sym.rev_dep is not _kconf.n:\n        s += sis(sym.rev_dep, 2,\n                 \"Symbols currently y-selecting this symbol:\\n\")\n        s += sis(sym.rev_dep, 1,\n                 \"Symbols currently m-selecting this symbol:\\n\")\n        s += sis(sym.rev_dep, 0,\n                 \"Symbols currently n-selecting this symbol (no effect):\\n\")\n\n    if sym.weak_rev_dep is not _kconf.n:\n        s += sis(sym.weak_rev_dep, 2,\n                 \"Symbols currently y-implying this symbol:\\n\")\n        s += sis(sym.weak_rev_dep, 1,\n                 \"Symbols currently m-implying this symbol:\\n\")\n        s += sis(sym.weak_rev_dep, 0,\n                 \"Symbols currently n-implying this symbol (no effect):\\n\")\n\n    return s\n\n\ndef _kconfig_def_info(item):\n    # Returns a string with the definition of 'item' in Kconfig syntax,\n    # together with the definition location(s) and their include and menu paths\n\n    nodes = [item] if isinstance(item, MenuNode) else item.nodes\n\n    s = \"Kconfig definition{}, with parent deps. propagated to 'depends on'\\n\" \\\n        .format(\"s\" if len(nodes) > 1 else \"\")\n    s += (len(s) - 1)*\"=\"\n\n    for node in nodes:\n        s += \"\\n\\n\" \\\n             \"At {}:{}\\n\" \\\n             \"{}\" \\\n             \"Menu path: {}\\n\\n\" \\\n             \"{}\" \\\n             .format(node.filename, node.linenr,\n                     _include_path_info(node),\n                     _menu_path_info(node),\n                     node.custom_str(_name_and_val_str))\n\n    return s\n\n\ndef _include_path_info(node):\n    if not node.include_path:\n        # In the top-level Kconfig file\n        return \"\"\n\n    return \"Included via {}\\n\".format(\n        \" -> \".join(\"{}:{}\".format(filename, linenr)\n                    for filename, linenr in node.include_path))\n\n\ndef _menu_path_info(node):\n    # Returns a string describing the menu path leading up to 'node'\n\n    path = \"\"\n\n    while node.parent is not _kconf.top_node:\n        node = node.parent\n\n        # Promptless choices might appear among the parents. Use\n        # standard_sc_expr_str() for them, so that they show up as\n        # '<choice (name if any)>'.\n        path = \" -> \" + (node.prompt[0] if node.prompt else\n                         standard_sc_expr_str(node.item)) + path\n\n    return \"(Top)\" + path\n\n\ndef _name_and_val_str(sc):\n    # Custom symbol/choice printer that shows symbol values after symbols\n\n    # Show the values of non-constant (non-quoted) symbols that don't look like\n    # numbers. Things like 123 are actually symbol references, and only work as\n    # expected due to undefined symbols getting their name as their value.\n    # Showing the symbol value for those isn't helpful though.\n    if isinstance(sc, Symbol) and not sc.is_constant and not _is_num(sc.name):\n        if not sc.nodes:\n            # Undefined symbol reference\n            return \"{}(undefined/n)\".format(sc.name)\n\n        return '{}(={})'.format(sc.name, sc.str_value)\n\n    # For other items, use the standard format\n    return standard_sc_expr_str(sc)\n\n\ndef _expr_str(expr):\n    # Custom expression printer that shows symbol values\n    return expr_str(expr, _name_and_val_str)\n\n\ndef _is_num(name):\n    # Heuristic to see if a symbol name looks like a number, for nicer output\n    # when printing expressions. Things like 16 are actually symbol names, only\n    # they get their name as their value when the symbol is undefined.\n\n    try:\n        int(name)\n    except ValueError:\n        if not name.startswith((\"0x\", \"0X\")):\n            return False\n\n        try:\n            int(name, 16)\n        except ValueError:\n            return False\n\n    return True\n\n\nif __name__ == \"__main__\":\n    _main()\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/kconfiglib.py",
    "content": "# Copyright (c) 2011-2019, Ulf Magnusson\n# SPDX-License-Identifier: ISC\n\n\"\"\"\nOverview\n========\n\nKconfiglib is a Python 2/3 library for scripting and extracting information\nfrom Kconfig (https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt)\nconfiguration systems.\n\nSee the homepage at https://github.com/ulfalizer/Kconfiglib for a longer\noverview.\n\nSince Kconfiglib 12.0.0, the library version is available in\nkconfiglib.VERSION, which is a (<major>, <minor>, <patch>) tuple, e.g.\n(12, 0, 0).\n\n\nUsing Kconfiglib on the Linux kernel with the Makefile targets\n==============================================================\n\nFor the Linux kernel, a handy interface is provided by the\nscripts/kconfig/Makefile patch, which can be applied with either 'git am' or\nthe 'patch' utility:\n\n  $ wget -qO- https://raw.githubusercontent.com/ulfalizer/Kconfiglib/master/makefile.patch | git am\n  $ wget -qO- https://raw.githubusercontent.com/ulfalizer/Kconfiglib/master/makefile.patch | patch -p1\n\nWarning: Not passing -p1 to patch will cause the wrong file to be patched.\n\nPlease tell me if the patch does not apply. It should be trivial to apply\nmanually, as it's just a block of text that needs to be inserted near the other\n*conf: targets in scripts/kconfig/Makefile.\n\nLook further down for a motivation for the Makefile patch and for instructions\non how you can use Kconfiglib without it.\n\nIf you do not wish to install Kconfiglib via pip, the Makefile patch is set up\nso that you can also just clone Kconfiglib into the kernel root:\n\n  $ git clone git://github.com/ulfalizer/Kconfiglib.git\n  $ git am Kconfiglib/makefile.patch  (or 'patch -p1 < Kconfiglib/makefile.patch')\n\nWarning: The directory name Kconfiglib/ is significant in this case, because\nit's added to PYTHONPATH by the new targets in makefile.patch.\n\nThe targets added by the Makefile patch are described in the following\nsections.\n\n\nmake kmenuconfig\n----------------\n\nThis target runs the curses menuconfig interface with Python 3. As of\nKconfiglib 12.2.0, both Python 2 and Python 3 are supported (previously, only\nPython 3 was supported, so this was a backport).\n\n\nmake guiconfig\n--------------\n\nThis target runs the Tkinter menuconfig interface. Both Python 2 and Python 3\nare supported. To change the Python interpreter used, pass\nPYTHONCMD=<executable> to 'make'. The default is 'python'.\n\n\nmake [ARCH=<arch>] iscriptconfig\n--------------------------------\n\nThis target gives an interactive Python prompt where a Kconfig instance has\nbeen preloaded and is available in 'kconf'. To change the Python interpreter\nused, pass PYTHONCMD=<executable> to 'make'. The default is 'python'.\n\nTo get a feel for the API, try evaluating and printing the symbols in\nkconf.defined_syms, and explore the MenuNode menu tree starting at\nkconf.top_node by following 'next' and 'list' pointers.\n\nThe item contained in a menu node is found in MenuNode.item (note that this can\nbe one of the constants kconfiglib.MENU and kconfiglib.COMMENT), and all\nsymbols and choices have a 'nodes' attribute containing their menu nodes\n(usually only one). Printing a menu node will print its item, in Kconfig\nformat.\n\nIf you want to look up a symbol by name, use the kconf.syms dictionary.\n\n\nmake scriptconfig SCRIPT=<script> [SCRIPT_ARG=<arg>]\n----------------------------------------------------\n\nThis target runs the Python script given by the SCRIPT parameter on the\nconfiguration. sys.argv[1] holds the name of the top-level Kconfig file\n(currently always \"Kconfig\" in practice), and sys.argv[2] holds the SCRIPT_ARG\nargument, if given.\n\nSee the examples/ subdirectory for example scripts.\n\n\nmake dumpvarsconfig\n-------------------\n\nThis target prints a list of all environment variables referenced from the\nKconfig files, together with their values. See the\nKconfiglib/examples/dumpvars.py script.\n\nOnly environment variables that are referenced via the Kconfig preprocessor\n$(FOO) syntax are included. The preprocessor was added in Linux 4.18.\n\n\nUsing Kconfiglib without the Makefile targets\n=============================================\n\nThe make targets are only needed to pick up environment variables exported from\nthe Kbuild makefiles and referenced inside Kconfig files, via e.g.\n'source \"arch/$(SRCARCH)/Kconfig\" and commands run via '$(shell,...)'.\n\nThese variables are referenced as of writing (Linux 4.18), together with sample\nvalues:\n\n  srctree          (.)\n  ARCH             (x86)\n  SRCARCH          (x86)\n  KERNELVERSION    (4.18.0)\n  CC               (gcc)\n  HOSTCC           (gcc)\n  HOSTCXX          (g++)\n  CC_VERSION_TEXT  (gcc (Ubuntu 7.3.0-16ubuntu3) 7.3.0)\n\nOlder kernels only reference ARCH, SRCARCH, and KERNELVERSION.\n\nIf your kernel is recent enough (4.18+), you can get a list of referenced\nenvironment variables via 'make dumpvarsconfig' (see above). Note that this\ncommand is added by the Makefile patch.\n\nTo run Kconfiglib without the Makefile patch, set the environment variables\nmanually:\n\n  $ srctree=. ARCH=x86 SRCARCH=x86 KERNELVERSION=`make kernelversion` ... python(3)\n  >>> import kconfiglib\n  >>> kconf = kconfiglib.Kconfig()  # filename defaults to \"Kconfig\"\n\nSearch the top-level Makefile for \"Additional ARCH settings\" to see other\npossibilities for ARCH and SRCARCH.\n\n\nIntro to symbol values\n======================\n\nKconfiglib has the same assignment semantics as the C implementation.\n\nAny symbol can be assigned a value by the user (via Kconfig.load_config() or\nSymbol.set_value()), but this user value is only respected if the symbol is\nvisible, which corresponds to it (currently) being visible in the menuconfig\ninterface.\n\nFor symbols with prompts, the visibility of the symbol is determined by the\ncondition on the prompt. Symbols without prompts are never visible, so setting\na user value on them is pointless. A warning will be printed by default if\nSymbol.set_value() is called on a promptless symbol. Assignments to promptless\nsymbols are normal within a .config file, so no similar warning will be printed\nby load_config().\n\nDependencies from parents and 'if'/'depends on' are propagated to properties,\nincluding prompts, so these two configurations are logically equivalent:\n\n(1)\n\n  menu \"menu\"\n      depends on A\n\n  if B\n\n  config FOO\n      tristate \"foo\" if D\n      default y\n      depends on C\n\n  endif\n\n  endmenu\n\n(2)\n\n  menu \"menu\"\n      depends on A\n\n  config FOO\n      tristate \"foo\" if A && B && C && D\n      default y if A && B && C\n\n  endmenu\n\nIn this example, A && B && C && D (the prompt condition) needs to be non-n for\nFOO to be visible (assignable). If its value is m, the symbol can only be\nassigned the value m: The visibility sets an upper bound on the value that can\nbe assigned by the user, and any higher user value will be truncated down.\n\n'default' properties are independent of the visibility, though a 'default' will\noften get the same condition as the prompt due to dependency propagation.\n'default' properties are used if the symbol is not visible or has no user\nvalue.\n\nSymbols with no user value (or that have a user value but are not visible) and\nno (active) 'default' default to n for bool/tristate symbols, and to the empty\nstring for other symbol types.\n\n'select' works similarly to symbol visibility, but sets a lower bound on the\nvalue of the symbol. The lower bound is determined by the value of the\nselect*ing* symbol. 'select' does not respect visibility, so non-visible\nsymbols can be forced to a particular (minimum) value by a select as well.\n\nFor non-bool/tristate symbols, it only matters whether the visibility is n or\nnon-n: m visibility acts the same as y visibility.\n\nConditions on 'default' and 'select' work in mostly intuitive ways. If the\ncondition is n, the 'default' or 'select' is disabled. If it is m, the\n'default' or 'select' value (the value of the selecting symbol) is truncated\ndown to m.\n\nWhen writing a configuration with Kconfig.write_config(), only symbols that are\nvisible, have an (active) default, or are selected will get written out (note\nthat this includes all symbols that would accept user values). Kconfiglib\nmatches the .config format produced by the C implementations down to the\ncharacter. This eases testing.\n\nFor a visible bool/tristate symbol FOO with value n, this line is written to\n.config:\n\n    # CONFIG_FOO is not set\n\nThe point is to remember the user n selection (which might differ from the\ndefault value the symbol would get), while at the same sticking to the rule\nthat undefined corresponds to n (.config uses Makefile format, making the line\nabove a comment). When the .config file is read back in, this line will be\ntreated the same as the following assignment:\n\n    CONFIG_FOO=n\n\nIn Kconfiglib, the set of (currently) assignable values for a bool/tristate\nsymbol appear in Symbol.assignable. For other symbol types, just check if\nsym.visibility is non-0 (non-n) to see whether the user value will have an\neffect.\n\n\nIntro to the menu tree\n======================\n\nThe menu structure, as seen in e.g. menuconfig, is represented by a tree of\nMenuNode objects. The top node of the configuration corresponds to an implicit\ntop-level menu, the title of which is shown at the top in the standard\nmenuconfig interface. (The title is also available in Kconfig.mainmenu_text in\nKconfiglib.)\n\nThe top node is found in Kconfig.top_node. From there, you can visit child menu\nnodes by following the 'list' pointer, and any following menu nodes by\nfollowing the 'next' pointer. Usually, a non-None 'list' pointer indicates a\nmenu or Choice, but menu nodes for symbols can sometimes have a non-None 'list'\npointer too due to submenus created implicitly from dependencies.\n\nMenuNode.item is either a Symbol or a Choice object, or one of the constants\nMENU and COMMENT. The prompt of the menu node can be found in MenuNode.prompt,\nwhich also holds the title for menus and comments. For Symbol and Choice,\nMenuNode.help holds the help text (if any, otherwise None).\n\nMost symbols will only have a single menu node. A symbol defined in multiple\nlocations will have one menu node for each location. The list of menu nodes for\na Symbol or Choice can be found in the Symbol/Choice.nodes attribute.\n\nNote that prompts and help texts for symbols and choices are stored in their\nmenu node(s) rather than in the Symbol or Choice objects themselves. This makes\nit possible to define a symbol in multiple locations with a different prompt or\nhelp text in each location. To get the help text or prompt for a symbol with a\nsingle menu node, do sym.nodes[0].help and sym.nodes[0].prompt, respectively.\nThe prompt is a (text, condition) tuple, where condition determines the\nvisibility (see 'Intro to expressions' below).\n\nThis organization mirrors the C implementation. MenuNode is called\n'struct menu' there, but I thought \"menu\" was a confusing name.\n\nIt is possible to give a Choice a name and define it in multiple locations,\nhence why Choice.nodes is also a list.\n\nAs a convenience, the properties added at a particular definition location are\navailable on the MenuNode itself, in e.g. MenuNode.defaults. This is helpful\nwhen generating documentation, so that symbols/choices defined in multiple\nlocations can be shown with the correct properties at each location.\n\n\nIntro to expressions\n====================\n\nExpressions can be evaluated with the expr_value() function and printed with\nthe expr_str() function (these are used internally as well). Evaluating an\nexpression always yields a tristate value, where n, m, and y are represented as\n0, 1, and 2, respectively.\n\nThe following table should help you figure out how expressions are represented.\nA, B, C, ... are symbols (Symbol instances), NOT is the kconfiglib.NOT\nconstant, etc.\n\nExpression            Representation\n----------            --------------\nA                     A\n\"A\"                   A (constant symbol)\n!A                    (NOT, A)\nA && B                (AND, A, B)\nA && B && C           (AND, A, (AND, B, C))\nA || B                (OR, A, B)\nA || (B && C && D)    (OR, A, (AND, B, (AND, C, D)))\nA = B                 (EQUAL, A, B)\nA != \"foo\"            (UNEQUAL, A, foo (constant symbol))\nA && B = C && D       (AND, A, (AND, (EQUAL, B, C), D))\nn                     Kconfig.n (constant symbol)\nm                     Kconfig.m (constant symbol)\ny                     Kconfig.y (constant symbol)\n\"y\"                   Kconfig.y (constant symbol)\n\nStrings like \"foo\" in 'default \"foo\"' or 'depends on SYM = \"foo\"' are\nrepresented as constant symbols, so the only values that appear in expressions\nare symbols***. This mirrors the C implementation.\n\n***For choice symbols, the parent Choice will appear in expressions as well,\nbut it's usually invisible as the value interfaces of Symbol and Choice are\nidentical. This mirrors the C implementation and makes different choice modes\n\"just work\".\n\nManual evaluation examples:\n\n  - The value of A && B is min(A.tri_value, B.tri_value)\n\n  - The value of A || B is max(A.tri_value, B.tri_value)\n\n  - The value of !A is 2 - A.tri_value\n\n  - The value of A = B is 2 (y) if A.str_value == B.str_value, and 0 (n)\n    otherwise. Note that str_value is used here instead of tri_value.\n\n    For constant (as well as undefined) symbols, str_value matches the name of\n    the symbol. This mirrors the C implementation and explains why\n    'depends on SYM = \"foo\"' above works as expected.\n\nn/m/y are automatically converted to the corresponding constant symbols\n\"n\"/\"m\"/\"y\" (Kconfig.n/m/y) during parsing.\n\nKconfig.const_syms is a dictionary like Kconfig.syms but for constant symbols.\n\nIf a condition is missing (e.g., <cond> when the 'if <cond>' is removed from\n'default A if <cond>'), it is actually Kconfig.y. The standard __str__()\nfunctions just avoid printing 'if y' conditions to give cleaner output.\n\n\nKconfig extensions\n==================\n\nKconfiglib includes a couple of Kconfig extensions:\n\n'source' with relative path\n---------------------------\n\nThe 'rsource' statement sources Kconfig files with a path relative to directory\nof the Kconfig file containing the 'rsource' statement, instead of relative to\nthe project root.\n\nConsider following directory tree:\n\n  Project\n  +--Kconfig\n  |\n  +--src\n     +--Kconfig\n     |\n     +--SubSystem1\n        +--Kconfig\n        |\n        +--ModuleA\n           +--Kconfig\n\nIn this example, assume that src/SubSystem1/Kconfig wants to source\nsrc/SubSystem1/ModuleA/Kconfig.\n\nWith 'source', this statement would be used:\n\n  source \"src/SubSystem1/ModuleA/Kconfig\"\n\nWith 'rsource', this turns into\n\n  rsource \"ModuleA/Kconfig\"\n\nIf an absolute path is given to 'rsource', it acts the same as 'source'.\n\n'rsource' can be used to create \"position-independent\" Kconfig trees that can\nbe moved around freely.\n\n\nGlobbing 'source'\n-----------------\n\n'source' and 'rsource' accept glob patterns, sourcing all matching Kconfig\nfiles. They require at least one matching file, raising a KconfigError\notherwise.\n\nFor example, the following statement might source sub1/foofoofoo and\nsub2/foobarfoo:\n\n  source \"sub[12]/foo*foo\"\n\nThe glob patterns accepted are the same as for the standard glob.glob()\nfunction.\n\nTwo additional statements are provided for cases where it's acceptable for a\npattern to match no files: 'osource' and 'orsource' (the o is for \"optional\").\n\nFor example, the following statements will be no-ops if neither \"foo\" nor any\nfiles matching \"bar*\" exist:\n\n  osource \"foo\"\n  osource \"bar*\"\n\n'orsource' does a relative optional source.\n\n'source' and 'osource' are analogous to 'include' and '-include' in Make.\n\n\nGeneralized def_* keywords\n--------------------------\n\ndef_int, def_hex, and def_string are available in addition to def_bool and\ndef_tristate, allowing int, hex, and string symbols to be given a type and a\ndefault at the same time.\n\n\nExtra optional warnings\n-----------------------\n\nSome optional warnings can be controlled via environment variables:\n\n  - KCONFIG_WARN_UNDEF: If set to 'y', warnings will be generated for all\n    references to undefined symbols within Kconfig files. The only gotcha is\n    that all hex literals must be prefixed with \"0x\" or \"0X\", to make it\n    possible to distinguish them from symbol references.\n\n    Some projects (e.g. the Linux kernel) use multiple Kconfig trees with many\n    shared Kconfig files, leading to some safe undefined symbol references.\n    KCONFIG_WARN_UNDEF is useful in projects that only have a single Kconfig\n    tree though.\n\n    KCONFIG_STRICT is an older alias for this environment variable, supported\n    for backwards compatibility.\n\n  - KCONFIG_WARN_UNDEF_ASSIGN: If set to 'y', warnings will be generated for\n    all assignments to undefined symbols within .config files. By default, no\n    such warnings are generated.\n\n    This warning can also be enabled/disabled via the Kconfig.warn_assign_undef\n    variable.\n\n\nPreprocessor user functions defined in Python\n---------------------------------------------\n\nPreprocessor functions can be defined in Python, which makes it simple to\nintegrate information from existing Python tools into Kconfig (e.g. to have\nKconfig symbols depend on hardware information stored in some other format).\n\nPutting a Python module named kconfigfunctions(.py) anywhere in sys.path will\ncause it to be imported by Kconfiglib (in Kconfig.__init__()). Note that\nsys.path can be customized via PYTHONPATH, and includes the directory of the\nmodule being run by default, as well as installation directories.\n\nIf the KCONFIG_FUNCTIONS environment variable is set, it gives a different\nmodule name to use instead of 'kconfigfunctions'.\n\nThe imported module is expected to define a global dictionary named 'functions'\nthat maps function names to Python functions, as follows:\n\n  def my_fn(kconf, name, arg_1, arg_2, ...):\n      # kconf:\n      #   Kconfig instance\n      #\n      # name:\n      #   Name of the user-defined function (\"my-fn\"). Think argv[0].\n      #\n      # arg_1, arg_2, ...:\n      #   Arguments passed to the function from Kconfig (strings)\n      #\n      # Returns a string to be substituted as the result of calling the\n      # function\n      ...\n\n  def my_other_fn(kconf, name, arg_1, arg_2, ...):\n      ...\n\n  functions = {\n      \"my-fn\":       (my_fn,       <min.args>, <max.args>/None),\n      \"my-other-fn\": (my_other_fn, <min.args>, <max.args>/None),\n      ...\n  }\n\n  ...\n\n<min.args> and <max.args> are the minimum and maximum number of arguments\nexpected by the function (excluding the implicit 'name' argument). If\n<max.args> is None, there is no upper limit to the number of arguments. Passing\nan invalid number of arguments will generate a KconfigError exception.\n\nFunctions can access the current parsing location as kconf.filename/linenr.\nAccessing other fields of the Kconfig object is not safe. See the warning\nbelow.\n\nKeep in mind that for a variable defined like 'foo = $(fn)', 'fn' will be\ncalled only when 'foo' is expanded. If 'fn' uses the parsing location and the\nintent is to use the location of the assignment, you want 'foo := $(fn)'\ninstead, which calls the function immediately.\n\nOnce defined, user functions can be called from Kconfig in the same way as\nother preprocessor functions:\n\n    config FOO\n        ...\n        depends on $(my-fn,arg1,arg2)\n\nIf my_fn() returns \"n\", this will result in\n\n    config FOO\n        ...\n        depends on n\n\nWarning\n*******\n\nUser-defined preprocessor functions are called as they're encountered at parse\ntime, before all Kconfig files have been processed, and before the menu tree\nhas been finalized. There are no guarantees that accessing Kconfig symbols or\nthe menu tree via the 'kconf' parameter will work, and it could potentially\nlead to a crash.\n\nPreferably, user-defined functions should be stateless.\n\n\nFeedback\n========\n\nSend bug reports, suggestions, and questions to ulfalizer a.t Google's email\nservice, or open a ticket on the GitHub page.\n\"\"\"\nimport errno\nimport importlib\nimport os\nimport re\nimport sys\n\n# Get rid of some attribute lookups. These are obvious in context.\nfrom glob import iglob\nfrom os.path import dirname, exists, expandvars, islink, join, realpath\n\n\nVERSION = (13, 7, 0)\n\n\n# File layout:\n#\n# Public classes\n# Public functions\n# Internal functions\n# Global constants\n\n# Line length: 79 columns\n\n\n#\n# Public classes\n#\n\n\nclass Kconfig(object):\n    \"\"\"\n    Represents a Kconfig configuration, e.g. for x86 or ARM. This is the set of\n    symbols, choices, and menu nodes appearing in the configuration. Creating\n    any number of Kconfig objects (including for different architectures) is\n    safe. Kconfiglib doesn't keep any global state.\n\n    The following attributes are available. They should be treated as\n    read-only, and some are implemented through @property magic.\n\n    syms:\n      A dictionary with all symbols in the configuration, indexed by name. Also\n      includes all symbols that are referenced in expressions but never\n      defined, except for constant (quoted) symbols.\n\n      Undefined symbols can be recognized by Symbol.nodes being empty -- see\n      the 'Intro to the menu tree' section in the module docstring.\n\n    const_syms:\n      A dictionary like 'syms' for constant (quoted) symbols\n\n    named_choices:\n      A dictionary like 'syms' for named choices (choice FOO)\n\n    defined_syms:\n      A list with all defined symbols, in the same order as they appear in the\n      Kconfig files. Symbols defined in multiple locations appear multiple\n      times.\n\n      Note: You probably want to use 'unique_defined_syms' instead. This\n      attribute is mostly maintained for backwards compatibility.\n\n    unique_defined_syms:\n      A list like 'defined_syms', but with duplicates removed. Just the first\n      instance is kept for symbols defined in multiple locations. Kconfig order\n      is preserved otherwise.\n\n      Using this attribute instead of 'defined_syms' can save work, and\n      automatically gives reasonable behavior when writing configuration output\n      (symbols defined in multiple locations only generate output once, while\n      still preserving Kconfig order for readability).\n\n    choices:\n      A list with all choices, in the same order as they appear in the Kconfig\n      files.\n\n      Note: You probably want to use 'unique_choices' instead. This attribute\n      is mostly maintained for backwards compatibility.\n\n    unique_choices:\n      Analogous to 'unique_defined_syms', for choices. Named choices can have\n      multiple definition locations.\n\n    menus:\n      A list with all menus, in the same order as they appear in the Kconfig\n      files\n\n    comments:\n      A list with all comments, in the same order as they appear in the Kconfig\n      files\n\n    kconfig_filenames:\n      A list with the filenames of all Kconfig files included in the\n      configuration, relative to $srctree (or relative to the current directory\n      if $srctree isn't set), except absolute paths (e.g.\n      'source \"/foo/Kconfig\"') are kept as-is.\n\n      The files are listed in the order they are source'd, starting with the\n      top-level Kconfig file. If a file is source'd multiple times, it will\n      appear multiple times. Use set() to get unique filenames.\n\n      Note that Kconfig.sync_deps() already indirectly catches any file\n      modifications that change configuration output.\n\n    env_vars:\n      A set() with the names of all environment variables referenced in the\n      Kconfig files.\n\n      Only environment variables referenced with the preprocessor $(FOO) syntax\n      will be registered. The older $FOO syntax is only supported for backwards\n      compatibility.\n\n      Also note that $(FOO) won't be registered unless the environment variable\n      $FOO is actually set. If it isn't, $(FOO) is an expansion of an unset\n      preprocessor variable (which gives the empty string).\n\n      Another gotcha is that environment variables referenced in the values of\n      recursively expanded preprocessor variables (those defined with =) will\n      only be registered if the variable is actually used (expanded) somewhere.\n\n      The note from the 'kconfig_filenames' documentation applies here too.\n\n    n/m/y:\n      The predefined constant symbols n/m/y. Also available in const_syms.\n\n    modules:\n      The Symbol instance for the modules symbol. Currently hardcoded to\n      MODULES, which is backwards compatible. Kconfiglib will warn if\n      'option modules' is set on some other symbol. Tell me if you need proper\n      'option modules' support.\n\n      'modules' is never None. If the MODULES symbol is not explicitly defined,\n      its tri_value will be 0 (n), as expected.\n\n      A simple way to enable modules is to do 'kconf.modules.set_value(2)'\n      (provided the MODULES symbol is defined and visible). Modules are\n      disabled by default in the kernel Kconfig files as of writing, though\n      nearly all defconfig files enable them (with 'CONFIG_MODULES=y').\n\n    defconfig_list:\n      The Symbol instance for the 'option defconfig_list' symbol, or None if no\n      defconfig_list symbol exists. The defconfig filename derived from this\n      symbol can be found in Kconfig.defconfig_filename.\n\n    defconfig_filename:\n      The filename given by the defconfig_list symbol. This is taken from the\n      first 'default' with a satisfied condition where the specified file\n      exists (can be opened for reading). If a defconfig file foo/defconfig is\n      not found and $srctree was set when the Kconfig was created,\n      $srctree/foo/defconfig is looked up as well.\n\n      'defconfig_filename' is None if either no defconfig_list symbol exists,\n      or if the defconfig_list symbol has no 'default' with a satisfied\n      condition that specifies a file that exists.\n\n      Gotcha: scripts/kconfig/Makefile might pass --defconfig=<defconfig> to\n      scripts/kconfig/conf when running e.g. 'make defconfig'. This option\n      overrides the defconfig_list symbol, meaning defconfig_filename might not\n      always match what 'make defconfig' would use.\n\n    top_node:\n      The menu node (see the MenuNode class) of the implicit top-level menu.\n      Acts as the root of the menu tree.\n\n    mainmenu_text:\n      The prompt (title) of the top menu (top_node). Defaults to \"Main menu\".\n      Can be changed with the 'mainmenu' statement (see kconfig-language.txt).\n\n    variables:\n      A dictionary with all preprocessor variables, indexed by name. See the\n      Variable class.\n\n    warn:\n      Set this variable to True/False to enable/disable warnings. See\n      Kconfig.__init__().\n\n      When 'warn' is False, the values of the other warning-related variables\n      are ignored.\n\n      This variable as well as the other warn* variables can be read to check\n      the current warning settings.\n\n    warn_to_stderr:\n      Set this variable to True/False to enable/disable warnings on stderr. See\n      Kconfig.__init__().\n\n    warn_assign_undef:\n      Set this variable to True to generate warnings for assignments to\n      undefined symbols in configuration files.\n\n      This variable is False by default unless the KCONFIG_WARN_UNDEF_ASSIGN\n      environment variable was set to 'y' when the Kconfig instance was\n      created.\n\n    warn_assign_override:\n      Set this variable to True to generate warnings for multiple assignments\n      to the same symbol in configuration files, where the assignments set\n      different values (e.g. CONFIG_FOO=m followed by CONFIG_FOO=y, where the\n      last value would get used).\n\n      This variable is True by default. Disabling it might be useful when\n      merging configurations.\n\n    warn_assign_redun:\n      Like warn_assign_override, but for multiple assignments setting a symbol\n      to the same value.\n\n      This variable is True by default. Disabling it might be useful when\n      merging configurations.\n\n    warnings:\n      A list of strings containing all warnings that have been generated, for\n      cases where more flexibility is needed.\n\n      See the 'warn_to_stderr' parameter to Kconfig.__init__() and the\n      Kconfig.warn_to_stderr variable as well. Note that warnings still get\n      added to Kconfig.warnings when 'warn_to_stderr' is True.\n\n      Just as for warnings printed to stderr, only warnings that are enabled\n      will get added to Kconfig.warnings. See the various Kconfig.warn*\n      variables.\n\n    missing_syms:\n      A list with (name, value) tuples for all assignments to undefined symbols\n      within the most recently loaded .config file(s). 'name' is the symbol\n      name without the 'CONFIG_' prefix. 'value' is a string that gives the\n      right-hand side of the assignment verbatim.\n\n      See Kconfig.load_config() as well.\n\n    srctree:\n      The value the $srctree environment variable had when the Kconfig instance\n      was created, or the empty string if $srctree wasn't set. This gives nice\n      behavior with os.path.join(), which treats \"\" as the current directory,\n      without adding \"./\".\n\n      Kconfig files are looked up relative to $srctree (unless absolute paths\n      are used), and .config files are looked up relative to $srctree if they\n      are not found in the current directory. This is used to support\n      out-of-tree builds. The C tools use this environment variable in the same\n      way.\n\n      Changing $srctree after creating the Kconfig instance has no effect. Only\n      the value when the configuration is loaded matters. This avoids surprises\n      if multiple configurations are loaded with different values for $srctree.\n\n    config_prefix:\n      The value the CONFIG_ environment variable had when the Kconfig instance\n      was created, or \"CONFIG_\" if CONFIG_ wasn't set. This is the prefix used\n      (and expected) on symbol names in .config files and C headers. Used in\n      the same way in the C tools.\n\n    config_header:\n      The value the KCONFIG_CONFIG_HEADER environment variable had when the\n      Kconfig instance was created, or the empty string if\n      KCONFIG_CONFIG_HEADER wasn't set. This string is inserted verbatim at the\n      beginning of configuration files. See write_config().\n\n    header_header:\n      The value the KCONFIG_AUTOHEADER_HEADER environment variable had when the\n      Kconfig instance was created, or the empty string if\n      KCONFIG_AUTOHEADER_HEADER wasn't set. This string is inserted verbatim at\n      the beginning of header files. See write_autoconf().\n\n    filename/linenr:\n      The current parsing location, for use in Python preprocessor functions.\n      See the module docstring.\n    \"\"\"\n    __slots__ = (\n        \"_encoding\",\n        \"_functions\",\n        \"_set_match\",\n        \"_srctree_prefix\",\n        \"_unset_match\",\n        \"_warn_assign_no_prompt\",\n        \"choices\",\n        \"comments\",\n        \"config_header\",\n        \"config_prefix\",\n        \"const_syms\",\n        \"defconfig_list\",\n        \"defined_syms\",\n        \"env_vars\",\n        \"header_header\",\n        \"kconfig_filenames\",\n        \"m\",\n        \"menus\",\n        \"missing_syms\",\n        \"modules\",\n        \"n\",\n        \"named_choices\",\n        \"srctree\",\n        \"syms\",\n        \"top_node\",\n        \"unique_choices\",\n        \"unique_defined_syms\",\n        \"variables\",\n        \"warn\",\n        \"warn_assign_override\",\n        \"warn_assign_redun\",\n        \"warn_assign_undef\",\n        \"warn_to_stderr\",\n        \"warnings\",\n        \"y\",\n\n        # Parsing-related\n        \"_parsing_kconfigs\",\n        \"_readline\",\n        \"filename\",\n        \"linenr\",\n        \"_include_path\",\n        \"_filestack\",\n        \"_line\",\n        \"_tokens\",\n        \"_tokens_i\",\n        \"_reuse_tokens\",\n    )\n\n    #\n    # Public interface\n    #\n\n    def __init__(self, filename=\"Kconfig\", warn=True, warn_to_stderr=True,\n                 encoding=\"utf-8\", suppress_traceback=False):\n        \"\"\"\n        Creates a new Kconfig object by parsing Kconfig files.\n        Note that Kconfig files are not the same as .config files (which store\n        configuration symbol values).\n\n        See the module docstring for some environment variables that influence\n        default warning settings (KCONFIG_WARN_UNDEF and\n        KCONFIG_WARN_UNDEF_ASSIGN).\n\n        Raises KconfigError on syntax/semantic errors, and OSError or (possibly\n        a subclass of) IOError on IO errors ('errno', 'strerror', and\n        'filename' are available). Note that IOError is an alias for OSError on\n        Python 3, so it's enough to catch OSError there. If you need Python 2/3\n        compatibility, it's easiest to catch EnvironmentError, which is a\n        common base class of OSError/IOError on Python 2 and an alias for\n        OSError on Python 3.\n\n        filename (default: \"Kconfig\"):\n          The Kconfig file to load. For the Linux kernel, you'll want \"Kconfig\"\n          from the top-level directory, as environment variables will make sure\n          the right Kconfig is included from there (arch/$SRCARCH/Kconfig as of\n          writing).\n\n          If $srctree is set, 'filename' will be looked up relative to it.\n          $srctree is also used to look up source'd files within Kconfig files.\n          See the class documentation.\n\n          If you are using Kconfiglib via 'make scriptconfig', the filename of\n          the base base Kconfig file will be in sys.argv[1]. It's currently\n          always \"Kconfig\" in practice.\n\n        warn (default: True):\n          True if warnings related to this configuration should be generated.\n          This can be changed later by setting Kconfig.warn to True/False. It\n          is provided as a constructor argument since warnings might be\n          generated during parsing.\n\n          See the other Kconfig.warn_* variables as well, which enable or\n          suppress certain warnings when warnings are enabled.\n\n          All generated warnings are added to the Kconfig.warnings list. See\n          the class documentation.\n\n        warn_to_stderr (default: True):\n          True if warnings should be printed to stderr in addition to being\n          added to Kconfig.warnings.\n\n          This can be changed later by setting Kconfig.warn_to_stderr to\n          True/False.\n\n        encoding (default: \"utf-8\"):\n          The encoding to use when reading and writing files, and when decoding\n          output from commands run via $(shell). If None, the encoding\n          specified in the current locale will be used.\n\n          The \"utf-8\" default avoids exceptions on systems that are configured\n          to use the C locale, which implies an ASCII encoding.\n\n          This parameter has no effect on Python 2, due to implementation\n          issues (regular strings turning into Unicode strings, which are\n          distinct in Python 2). Python 2 doesn't decode regular strings\n          anyway.\n\n          Related PEP: https://www.python.org/dev/peps/pep-0538/\n\n        suppress_traceback (default: False):\n          Helper for tools. When True, any EnvironmentError or KconfigError\n          generated during parsing is caught, the exception message is printed\n          to stderr together with the command name, and sys.exit(1) is called\n          (which generates SystemExit).\n\n          This hides the Python traceback for \"expected\" errors like syntax\n          errors in Kconfig files.\n\n          Other exceptions besides EnvironmentError and KconfigError are still\n          propagated when suppress_traceback is True.\n        \"\"\"\n        try:\n            self._init(filename, warn, warn_to_stderr, encoding)\n        except (EnvironmentError, KconfigError) as e:\n            if suppress_traceback:\n                cmd = sys.argv[0]  # Empty string if missing\n                if cmd:\n                    cmd += \": \"\n                # Some long exception messages have extra newlines for better\n                # formatting when reported as an unhandled exception. Strip\n                # them here.\n                sys.exit(cmd + str(e).strip())\n            raise\n\n    def _init(self, filename, warn, warn_to_stderr, encoding):\n        # See __init__()\n\n        self._encoding = encoding\n\n        self.srctree = os.getenv(\"srctree\", \"\")\n        # A prefix we can reliably strip from glob() results to get a filename\n        # relative to $srctree. relpath() can cause issues for symlinks,\n        # because it assumes symlink/../foo is the same as foo/.\n        self._srctree_prefix = realpath(self.srctree) + os.sep\n\n        self.warn = warn\n        self.warn_to_stderr = warn_to_stderr\n        self.warn_assign_undef = os.getenv(\"KCONFIG_WARN_UNDEF_ASSIGN\") == \"y\"\n        self.warn_assign_override = True\n        self.warn_assign_redun = True\n        self._warn_assign_no_prompt = True\n\n        self.warnings = []\n\n        self.config_prefix = os.getenv(\"CONFIG_\", \"CONFIG_\")\n        # Regular expressions for parsing .config files\n        self._set_match = _re_match(self.config_prefix + r\"([^=]+)=(.*)\")\n        self._unset_match = _re_match(r\"# {}([^ ]+) is not set\".format(\n            self.config_prefix))\n\n        self.config_header = os.getenv(\"KCONFIG_CONFIG_HEADER\", \"\")\n        self.header_header = os.getenv(\"KCONFIG_AUTOHEADER_HEADER\", \"\")\n\n        self.syms = {}\n        self.const_syms = {}\n        self.defined_syms = []\n        self.missing_syms = []\n        self.named_choices = {}\n        self.choices = []\n        self.menus = []\n        self.comments = []\n\n        for nmy in \"n\", \"m\", \"y\":\n            sym = Symbol()\n            sym.kconfig = self\n            sym.name = nmy\n            sym.is_constant = True\n            sym.orig_type = TRISTATE\n            sym._cached_tri_val = STR_TO_TRI[nmy]\n\n            self.const_syms[nmy] = sym\n\n        self.n = self.const_syms[\"n\"]\n        self.m = self.const_syms[\"m\"]\n        self.y = self.const_syms[\"y\"]\n\n        # Make n/m/y well-formed symbols\n        for nmy in \"n\", \"m\", \"y\":\n            sym = self.const_syms[nmy]\n            sym.rev_dep = sym.weak_rev_dep = sym.direct_dep = self.n\n\n        # Maps preprocessor variables names to Variable instances\n        self.variables = {}\n\n        # Predefined preprocessor functions, with min/max number of arguments\n        self._functions = {\n            \"info\":       (_info_fn,       1, 1),\n            \"error-if\":   (_error_if_fn,   2, 2),\n            \"filename\":   (_filename_fn,   0, 0),\n            \"lineno\":     (_lineno_fn,     0, 0),\n            \"shell\":      (_shell_fn,      1, 1),\n            \"warning-if\": (_warning_if_fn, 2, 2),\n        }\n\n        # Add any user-defined preprocessor functions\n        try:\n            self._functions.update(\n                importlib.import_module(\n                    os.getenv(\"KCONFIG_FUNCTIONS\", \"kconfigfunctions\")\n                ).functions)\n        except ImportError:\n            pass\n\n        # This determines whether previously unseen symbols are registered.\n        # They shouldn't be if we parse expressions after parsing, as part of\n        # Kconfig.eval_string().\n        self._parsing_kconfigs = True\n\n        self.modules = self._lookup_sym(\"MODULES\")\n        self.defconfig_list = None\n\n        self.top_node = MenuNode()\n        self.top_node.kconfig = self\n        self.top_node.item = MENU\n        self.top_node.is_menuconfig = True\n        self.top_node.visibility = self.y\n        self.top_node.prompt = (\"Main menu\", self.y)\n        self.top_node.parent = None\n        self.top_node.dep = self.y\n        self.top_node.filename = filename\n        self.top_node.linenr = 1\n        self.top_node.include_path = ()\n\n        # Parse the Kconfig files\n\n        # Not used internally. Provided as a convenience.\n        self.kconfig_filenames = [filename]\n        self.env_vars = set()\n\n        # Keeps track of the location in the parent Kconfig files. Kconfig\n        # files usually source other Kconfig files. See _enter_file().\n        self._filestack = []\n        self._include_path = ()\n\n        # The current parsing location\n        self.filename = filename\n        self.linenr = 0\n\n        # Used to avoid retokenizing lines when we discover that they're not\n        # part of the construct currently being parsed. This is kinda like an\n        # unget operation.\n        self._reuse_tokens = False\n\n        # Open the top-level Kconfig file. Store the readline() method directly\n        # as a small optimization.\n        self._readline = self._open(join(self.srctree, filename), \"r\").readline\n\n        try:\n            # Parse the Kconfig files. Returns the last node, which we\n            # terminate with '.next = None'.\n            self._parse_block(None, self.top_node, self.top_node).next = None\n            self.top_node.list = self.top_node.next\n            self.top_node.next = None\n        except UnicodeDecodeError as e:\n            _decoding_error(e, self.filename)\n\n        # Close the top-level Kconfig file. __self__ fetches the 'file' object\n        # for the method.\n        self._readline.__self__.close()\n\n        self._parsing_kconfigs = False\n\n        # Do various menu tree post-processing\n        self._finalize_node(self.top_node, self.y)\n\n        self.unique_defined_syms = _ordered_unique(self.defined_syms)\n        self.unique_choices = _ordered_unique(self.choices)\n\n        # Do sanity checks. Some of these depend on everything being finalized.\n        self._check_sym_sanity()\n        self._check_choice_sanity()\n\n        # KCONFIG_STRICT is an older alias for KCONFIG_WARN_UNDEF, supported\n        # for backwards compatibility\n        if os.getenv(\"KCONFIG_WARN_UNDEF\") == \"y\" or \\\n           os.getenv(\"KCONFIG_STRICT\") == \"y\":\n\n            self._check_undef_syms()\n\n        # Build Symbol._dependents for all symbols and choices\n        self._build_dep()\n\n        # Check for dependency loops\n        check_dep_loop_sym = _check_dep_loop_sym  # Micro-optimization\n        for sym in self.unique_defined_syms:\n            check_dep_loop_sym(sym, False)\n\n        # Add extra dependencies from choices to choice symbols that get\n        # awkward during dependency loop detection\n        self._add_choice_deps()\n\n    @property\n    def mainmenu_text(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        return self.top_node.prompt[0]\n\n    @property\n    def defconfig_filename(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        if self.defconfig_list:\n            for filename, cond in self.defconfig_list.defaults:\n                if expr_value(cond):\n                    try:\n                        with self._open_config(filename.str_value) as f:\n                            return f.name\n                    except EnvironmentError:\n                        continue\n\n        return None\n\n    def load_config(self, filename=None, replace=True, verbose=None):\n        \"\"\"\n        Loads symbol values from a file in the .config format. Equivalent to\n        calling Symbol.set_value() to set each of the values.\n\n        \"# CONFIG_FOO is not set\" within a .config file sets the user value of\n        FOO to n. The C tools work the same way.\n\n        For each symbol, the Symbol.user_value attribute holds the value the\n        symbol was assigned in the .config file (if any). The user value might\n        differ from Symbol.str/tri_value if there are unsatisfied dependencies.\n\n        Calling this function also updates the Kconfig.missing_syms attribute\n        with a list of all assignments to undefined symbols within the\n        configuration file. Kconfig.missing_syms is cleared if 'replace' is\n        True, and appended to otherwise. See the documentation for\n        Kconfig.missing_syms as well.\n\n        See the Kconfig.__init__() docstring for raised exceptions\n        (OSError/IOError). KconfigError is never raised here.\n\n        filename (default: None):\n          Path to load configuration from (a string). Respects $srctree if set\n          (see the class documentation).\n\n          If 'filename' is None (the default), the configuration file to load\n          (if any) is calculated automatically, giving the behavior you'd\n          usually want:\n\n            1. If the KCONFIG_CONFIG environment variable is set, it gives the\n               path to the configuration file to load. Otherwise, \".config\" is\n               used. See standard_config_filename().\n\n            2. If the path from (1.) doesn't exist, the configuration file\n               given by kconf.defconfig_filename is loaded instead, which is\n               derived from the 'option defconfig_list' symbol.\n\n            3. If (1.) and (2.) fail to find a configuration file to load, no\n               configuration file is loaded, and symbols retain their current\n               values (e.g., their default values). This is not an error.\n\n           See the return value as well.\n\n        replace (default: True):\n          If True, all existing user values will be cleared before loading the\n          .config. Pass False to merge configurations.\n\n        verbose (default: None):\n          Limited backwards compatibility to prevent crashes. A warning is\n          printed if anything but None is passed.\n\n          Prior to Kconfiglib 12.0.0, this option enabled printing of messages\n          to stdout when 'filename' was None. A message is (always) returned\n          now instead, which is more flexible.\n\n          Will probably be removed in some future version.\n\n        Returns a string with a message saying which file got loaded (or\n        possibly that no file got loaded, when 'filename' is None). This is\n        meant to reduce boilerplate in tools, which can do e.g.\n        print(kconf.load_config()). The returned message distinguishes between\n        loading (replace == True) and merging (replace == False).\n        \"\"\"\n        if verbose is not None:\n            _warn_verbose_deprecated(\"load_config\")\n\n        msg = None\n        if filename is None:\n            filename = standard_config_filename()\n            if not exists(filename) and \\\n               not exists(join(self.srctree, filename)):\n                defconfig = self.defconfig_filename\n                if defconfig is None:\n                    return \"Using default symbol values (no '{}')\" \\\n                           .format(filename)\n\n                msg = \" default configuration '{}' (no '{}')\" \\\n                      .format(defconfig, filename)\n                filename = defconfig\n\n        if not msg:\n            msg = \" configuration '{}'\".format(filename)\n\n        # Disable the warning about assigning to symbols without prompts. This\n        # is normal and expected within a .config file.\n        self._warn_assign_no_prompt = False\n\n        # This stub only exists to make sure _warn_assign_no_prompt gets\n        # reenabled\n        try:\n            self._load_config(filename, replace)\n        except UnicodeDecodeError as e:\n            _decoding_error(e, filename)\n        finally:\n            self._warn_assign_no_prompt = True\n\n        return (\"Loaded\" if replace else \"Merged\") + msg\n\n    def _load_config(self, filename, replace):\n        with self._open_config(filename) as f:\n            if replace:\n                self.missing_syms = []\n\n                # If we're replacing the configuration, keep track of which\n                # symbols and choices got set so that we can unset the rest\n                # later. This avoids invalidating everything and is faster.\n                # Another benefit is that invalidation must be rock solid for\n                # it to work, making it a good test.\n\n                for sym in self.unique_defined_syms:\n                    sym._was_set = False\n\n                for choice in self.unique_choices:\n                    choice._was_set = False\n\n            # Small optimizations\n            set_match = self._set_match\n            unset_match = self._unset_match\n            get_sym = self.syms.get\n\n            for linenr, line in enumerate(f, 1):\n                # The C tools ignore trailing whitespace\n                line = line.rstrip()\n\n                match = set_match(line)\n                if match:\n                    name, val = match.groups()\n                    sym = get_sym(name)\n                    if not sym or not sym.nodes:\n                        self._undef_assign(name, val, filename, linenr)\n                        continue\n\n                    if sym.orig_type in _BOOL_TRISTATE:\n                        # The C implementation only checks the first character\n                        # to the right of '=', for whatever reason\n                        if not (sym.orig_type is BOOL\n                                and val.startswith((\"y\", \"n\")) or\n                                sym.orig_type is TRISTATE\n                                and val.startswith((\"y\", \"m\", \"n\"))):\n                            self._warn(\"'{}' is not a valid value for the {} \"\n                                       \"symbol {}. Assignment ignored.\"\n                                       .format(val, TYPE_TO_STR[sym.orig_type],\n                                               sym.name_and_loc),\n                                       filename, linenr)\n                            continue\n\n                        val = val[0]\n\n                        if sym.choice and val != \"n\":\n                            # During .config loading, we infer the mode of the\n                            # choice from the kind of values that are assigned\n                            # to the choice symbols\n\n                            prev_mode = sym.choice.user_value\n                            if prev_mode is not None and \\\n                               TRI_TO_STR[prev_mode] != val:\n\n                                self._warn(\"both m and y assigned to symbols \"\n                                           \"within the same choice\",\n                                           filename, linenr)\n\n                            # Set the choice's mode\n                            sym.choice.set_value(val)\n\n                    elif sym.orig_type is STRING:\n                        match = _conf_string_match(val)\n                        if not match:\n                            self._warn(\"malformed string literal in \"\n                                       \"assignment to {}. Assignment ignored.\"\n                                       .format(sym.name_and_loc),\n                                       filename, linenr)\n                            continue\n\n                        val = unescape(match.group(1))\n\n                else:\n                    match = unset_match(line)\n                    if not match:\n                        # Print a warning for lines that match neither\n                        # set_match() nor unset_match() and that are not blank\n                        # lines or comments. 'line' has already been\n                        # rstrip()'d, so blank lines show up as \"\" here.\n                        if line and not line.lstrip().startswith(\"#\"):\n                            self._warn(\"ignoring malformed line '{}'\"\n                                       .format(line),\n                                       filename, linenr)\n\n                        continue\n\n                    name = match.group(1)\n                    sym = get_sym(name)\n                    if not sym or not sym.nodes:\n                        self._undef_assign(name, \"n\", filename, linenr)\n                        continue\n\n                    if sym.orig_type not in _BOOL_TRISTATE:\n                        continue\n\n                    val = \"n\"\n\n                # Done parsing the assignment. Set the value.\n\n                if sym._was_set:\n                    self._assigned_twice(sym, val, filename, linenr)\n\n                sym.set_value(val)\n\n        if replace:\n            # If we're replacing the configuration, unset the symbols that\n            # didn't get set\n\n            for sym in self.unique_defined_syms:\n                if not sym._was_set:\n                    sym.unset_value()\n\n            for choice in self.unique_choices:\n                if not choice._was_set:\n                    choice.unset_value()\n\n    def _undef_assign(self, name, val, filename, linenr):\n        # Called for assignments to undefined symbols during .config loading\n\n        self.missing_syms.append((name, val))\n        if self.warn_assign_undef:\n            self._warn(\n                \"attempt to assign the value '{}' to the undefined symbol {}\"\n                .format(val, name), filename, linenr)\n\n    def _assigned_twice(self, sym, new_val, filename, linenr):\n        # Called when a symbol is assigned more than once in a .config file\n\n        # Use strings for bool/tristate user values in the warning\n        if sym.orig_type in _BOOL_TRISTATE:\n            user_val = TRI_TO_STR[sym.user_value]\n        else:\n            user_val = sym.user_value\n\n        msg = '{} set more than once. Old value \"{}\", new value \"{}\".'.format(\n            sym.name_and_loc, user_val, new_val)\n\n        if user_val == new_val:\n            if self.warn_assign_redun:\n                self._warn(msg, filename, linenr)\n        elif self.warn_assign_override:\n            self._warn(msg, filename, linenr)\n\n    def load_allconfig(self, filename):\n        \"\"\"\n        Helper for all*config. Loads (merges) the configuration file specified\n        by KCONFIG_ALLCONFIG, if any. See Documentation/kbuild/kconfig.txt in\n        the Linux kernel.\n\n        Disables warnings for duplicated assignments within configuration files\n        for the duration of the call\n        (kconf.warn_assign_override/warn_assign_redun = False), and restores\n        the previous warning settings at the end. The KCONFIG_ALLCONFIG\n        configuration file is expected to override symbols.\n\n        Exits with sys.exit() (which raises a SystemExit exception) and prints\n        an error to stderr if KCONFIG_ALLCONFIG is set but the configuration\n        file can't be opened.\n\n        filename:\n          Command-specific configuration filename - \"allyes.config\",\n          \"allno.config\", etc.\n        \"\"\"\n        load_allconfig(self, filename)\n\n    def write_autoconf(self, filename=None, header=None):\n        r\"\"\"\n        Writes out symbol values as a C header file, matching the format used\n        by include/generated/autoconf.h in the kernel.\n\n        The ordering of the #defines matches the one generated by\n        write_config(). The order in the C implementation depends on the hash\n        table implementation as of writing, and so won't match.\n\n        If 'filename' exists and its contents is identical to what would get\n        written out, it is left untouched. This avoids updating file metadata\n        like the modification time and possibly triggering redundant work in\n        build tools.\n\n        filename (default: None):\n          Path to write header to.\n\n          If None (the default), the path in the environment variable\n          KCONFIG_AUTOHEADER is used if set, and \"include/generated/autoconf.h\"\n          otherwise. This is compatible with the C tools.\n\n        header (default: None):\n          Text inserted verbatim at the beginning of the file. You would\n          usually want it enclosed in '/* */' to make it a C comment, and\n          include a trailing newline.\n\n          If None (the default), the value of the environment variable\n          KCONFIG_AUTOHEADER_HEADER had when the Kconfig instance was created\n          will be used if it was set, and no header otherwise. See the\n          Kconfig.header_header attribute.\n        \"\"\"\n        if filename is None:\n            filename = os.getenv(\"KCONFIG_AUTOHEADER\",\n                                 \"include/generated/autoconf.h\")\n\n        self._write_if_changed(filename, self._autoconf_contents(header))\n\n    def _autoconf_contents(self, header):\n        # write_autoconf() helper. Returns the contents to write as a string,\n        # with 'header' or KCONFIG_AUTOHEADER_HEADER at the beginning.\n\n        if header is None:\n            header = self.header_header\n\n        chunks = [header]  # \"\".join()ed later\n        add = chunks.append\n\n        for sym in self.unique_defined_syms:\n            # _write_to_conf is determined when the value is calculated. This\n            # is a hidden function call due to property magic.\n            #\n            # Note: In client code, you can check if sym.config_string is empty\n            # instead, to avoid accessing the internal _write_to_conf variable\n            # (though it's likely to keep working).\n            val = sym.str_value\n            if not sym._write_to_conf:\n                continue\n\n            if sym.orig_type in _BOOL_TRISTATE:\n                if val == \"y\":\n                    add(\"#define {}{} 1\\n\"\n                        .format(self.config_prefix, sym.name))\n                elif val == \"m\":\n                    add(\"#define {}{}_MODULE 1\\n\"\n                        .format(self.config_prefix, sym.name))\n\n            elif sym.orig_type is STRING:\n                add('#define {}{} \"{}\"\\n'\n                    .format(self.config_prefix, sym.name, escape(val)))\n\n            else:  # sym.orig_type in _INT_HEX:\n                if sym.orig_type is HEX and \\\n                   not val.startswith((\"0x\", \"0X\")):\n                    val = \"0x\" + val\n\n                add(\"#define {}{} {}\\n\"\n                    .format(self.config_prefix, sym.name, val))\n\n        return \"\".join(chunks)\n\n    def write_config(self, filename=None, header=None, save_old=True,\n                     verbose=None):\n        r\"\"\"\n        Writes out symbol values in the .config format. The format matches the\n        C implementation, including ordering.\n\n        Symbols appear in the same order in generated .config files as they do\n        in the Kconfig files. For symbols defined in multiple locations, a\n        single assignment is written out corresponding to the first location\n        where the symbol is defined.\n\n        See the 'Intro to symbol values' section in the module docstring to\n        understand which symbols get written out.\n\n        If 'filename' exists and its contents is identical to what would get\n        written out, it is left untouched. This avoids updating file metadata\n        like the modification time and possibly triggering redundant work in\n        build tools.\n\n        See the Kconfig.__init__() docstring for raised exceptions\n        (OSError/IOError). KconfigError is never raised here.\n\n        filename (default: None):\n          Path to write configuration to (a string).\n\n          If None (the default), the path in the environment variable\n          KCONFIG_CONFIG is used if set, and \".config\" otherwise. See\n          standard_config_filename().\n\n        header (default: None):\n          Text inserted verbatim at the beginning of the file. You would\n          usually want each line to start with '#' to make it a comment, and\n          include a trailing newline.\n\n          if None (the default), the value of the environment variable\n          KCONFIG_CONFIG_HEADER had when the Kconfig instance was created will\n          be used if it was set, and no header otherwise. See the\n          Kconfig.config_header attribute.\n\n        save_old (default: True):\n          If True and <filename> already exists, a copy of it will be saved to\n          <filename>.old in the same directory before the new configuration is\n          written.\n\n          Errors are silently ignored if <filename>.old cannot be written (e.g.\n          due to being a directory, or <filename> being something like\n          /dev/null).\n\n        verbose (default: None):\n          Limited backwards compatibility to prevent crashes. A warning is\n          printed if anything but None is passed.\n\n          Prior to Kconfiglib 12.0.0, this option enabled printing of messages\n          to stdout when 'filename' was None. A message is (always) returned\n          now instead, which is more flexible.\n\n          Will probably be removed in some future version.\n\n        Returns a string with a message saying which file got saved. This is\n        meant to reduce boilerplate in tools, which can do e.g.\n        print(kconf.write_config()).\n        \"\"\"\n        if verbose is not None:\n            _warn_verbose_deprecated(\"write_config\")\n\n        if filename is None:\n            filename = standard_config_filename()\n\n        contents = self._config_contents(header)\n        if self._contents_eq(filename, contents):\n            return \"No change to '{}'\".format(filename)\n\n        if save_old:\n            _save_old(filename)\n\n        with self._open(filename, \"w\") as f:\n            f.write(contents)\n\n        return \"Configuration saved to '{}'\".format(filename)\n\n    def _config_contents(self, header):\n        # write_config() helper. Returns the contents to write as a string,\n        # with 'header' or KCONFIG_CONFIG_HEADER at the beginning.\n        #\n        # More memory friendly would be to 'yield' the strings and\n        # \"\".join(_config_contents()), but it was a bit slower on my system.\n\n        # node_iter() was used here before commit 3aea9f7 (\"Add '# end of\n        # <menu>' after menus in .config\"). Those comments get tricky to\n        # implement with it.\n\n        for sym in self.unique_defined_syms:\n            sym._visited = False\n\n        if header is None:\n            header = self.config_header\n\n        chunks = [header]  # \"\".join()ed later\n        add = chunks.append\n\n        # Did we just print an '# end of ...' comment?\n        after_end_comment = False\n\n        node = self.top_node\n        while 1:\n            # Jump to the next node with an iterative tree walk\n            if node.list:\n                node = node.list\n            elif node.next:\n                node = node.next\n            else:\n                while node.parent:\n                    node = node.parent\n\n                    # Add a comment when leaving visible menus\n                    if node.item is MENU and expr_value(node.dep) and \\\n                       expr_value(node.visibility) and \\\n                       node is not self.top_node:\n                        add(\"# end of {}\\n\".format(node.prompt[0]))\n                        after_end_comment = True\n\n                    if node.next:\n                        node = node.next\n                        break\n                else:\n                    # No more nodes\n                    return \"\".join(chunks)\n\n            # Generate configuration output for the node\n\n            item = node.item\n\n            if item.__class__ is Symbol:\n                if item._visited:\n                    continue\n                item._visited = True\n\n                conf_string = item.config_string\n                if not conf_string:\n                    continue\n\n                if after_end_comment:\n                    # Add a blank line before the first symbol printed after an\n                    # '# end of ...' comment\n                    after_end_comment = False\n                    add(\"\\n\")\n                add(conf_string)\n\n            elif expr_value(node.dep) and \\\n                 ((item is MENU and expr_value(node.visibility)) or\n                  item is COMMENT):\n\n                add(\"\\n#\\n# {}\\n#\\n\".format(node.prompt[0]))\n                after_end_comment = False\n\n    def write_min_config(self, filename, header=None):\n        \"\"\"\n        Writes out a \"minimal\" configuration file, omitting symbols whose value\n        matches their default value. The format matches the one produced by\n        'make savedefconfig'.\n\n        The resulting configuration file is incomplete, but a complete\n        configuration can be derived from it by loading it. Minimal\n        configuration files can serve as a more manageable configuration format\n        compared to a \"full\" .config file, especially when configurations files\n        are merged or edited by hand.\n\n        See the Kconfig.__init__() docstring for raised exceptions\n        (OSError/IOError). KconfigError is never raised here.\n\n        filename:\n          Path to write minimal configuration to.\n\n        header (default: None):\n          Text inserted verbatim at the beginning of the file. You would\n          usually want each line to start with '#' to make it a comment, and\n          include a final terminating newline.\n\n          if None (the default), the value of the environment variable\n          KCONFIG_CONFIG_HEADER had when the Kconfig instance was created will\n          be used if it was set, and no header otherwise. See the\n          Kconfig.config_header attribute.\n\n        Returns a string with a message saying which file got saved. This is\n        meant to reduce boilerplate in tools, which can do e.g.\n        print(kconf.write_min_config()).\n        \"\"\"\n        contents = self._min_config_contents(header)\n        if self._contents_eq(filename, contents):\n            return \"No change to '{}'\".format(filename)\n\n        with self._open(filename, \"w\") as f:\n            f.write(contents)\n\n        return \"Minimal configuration saved to '{}'\".format(filename)\n\n    def _min_config_contents(self, header):\n        # write_min_config() helper. Returns the contents to write as a string,\n        # with 'header' or KCONFIG_CONFIG_HEADER at the beginning.\n\n        if header is None:\n            header = self.config_header\n\n        chunks = [header]  # \"\".join()ed later\n        add = chunks.append\n\n        for sym in self.unique_defined_syms:\n            # Skip symbols that cannot be changed. Only check\n            # non-choice symbols, as selects don't affect choice\n            # symbols.\n            if not sym.choice and \\\n               sym.visibility <= expr_value(sym.rev_dep):\n                continue\n\n            # Skip symbols whose value matches their default\n            if sym.str_value == sym._str_default():\n                continue\n\n            # Skip symbols that would be selected by default in a\n            # choice, unless the choice is optional or the symbol type\n            # isn't bool (it might be possible to set the choice mode\n            # to n or the symbol to m in those cases).\n            if sym.choice and \\\n               not sym.choice.is_optional and \\\n               sym.choice._selection_from_defaults() is sym and \\\n               sym.orig_type is BOOL and \\\n               sym.tri_value == 2:\n                continue\n\n            add(sym.config_string)\n\n        return \"\".join(chunks)\n\n    def sync_deps(self, path):\n        \"\"\"\n        Creates or updates a directory structure that can be used to avoid\n        doing a full rebuild whenever the configuration is changed, mirroring\n        include/config/ in the kernel.\n\n        This function is intended to be called during each build, before\n        compiling source files that depend on configuration symbols.\n\n        See the Kconfig.__init__() docstring for raised exceptions\n        (OSError/IOError). KconfigError is never raised here.\n\n        path:\n          Path to directory\n\n        sync_deps(path) does the following:\n\n          1. If the directory <path> does not exist, it is created.\n\n          2. If <path>/auto.conf exists, old symbol values are loaded from it,\n             which are then compared against the current symbol values. If a\n             symbol has changed value (would generate different output in\n             autoconf.h compared to before), the change is signaled by\n             touch'ing a file corresponding to the symbol.\n\n             The first time sync_deps() is run on a directory, <path>/auto.conf\n             won't exist, and no old symbol values will be available. This\n             logically has the same effect as updating the entire\n             configuration.\n\n             The path to a symbol's file is calculated from the symbol's name\n             by replacing all '_' with '/' and appending '.h'. For example, the\n             symbol FOO_BAR_BAZ gets the file <path>/foo/bar/baz.h, and FOO\n             gets the file <path>/foo.h.\n\n             This scheme matches the C tools. The point is to avoid having a\n             single directory with a huge number of files, which the underlying\n             filesystem might not handle well.\n\n          3. A new auto.conf with the current symbol values is written, to keep\n             track of them for the next build.\n\n             If auto.conf exists and its contents is identical to what would\n             get written out, it is left untouched. This avoids updating file\n             metadata like the modification time and possibly triggering\n             redundant work in build tools.\n\n\n        The last piece of the puzzle is knowing what symbols each source file\n        depends on. Knowing that, dependencies can be added from source files\n        to the files corresponding to the symbols they depends on. The source\n        file will then get recompiled (only) when the symbol value changes\n        (provided sync_deps() is run first during each build).\n\n        The tool in the kernel that extracts symbol dependencies from source\n        files is scripts/basic/fixdep.c. Missing symbol files also correspond\n        to \"not changed\", which fixdep deals with by using the $(wildcard) Make\n        function when adding symbol prerequisites to source files.\n\n        In case you need a different scheme for your project, the sync_deps()\n        implementation can be used as a template.\n        \"\"\"\n        if not exists(path):\n            os.mkdir(path, 0o755)\n\n        # Load old values from auto.conf, if any\n        self._load_old_vals(path)\n\n        for sym in self.unique_defined_syms:\n            # _write_to_conf is determined when the value is calculated. This\n            # is a hidden function call due to property magic.\n            #\n            # Note: In client code, you can check if sym.config_string is empty\n            # instead, to avoid accessing the internal _write_to_conf variable\n            # (though it's likely to keep working).\n            val = sym.str_value\n\n            # n tristate values do not get written to auto.conf and autoconf.h,\n            # making a missing symbol logically equivalent to n\n\n            if sym._write_to_conf:\n                if sym._old_val is None and \\\n                   sym.orig_type in _BOOL_TRISTATE and \\\n                   val == \"n\":\n                    # No old value (the symbol was missing or n), new value n.\n                    # No change.\n                    continue\n\n                if val == sym._old_val:\n                    # New value matches old. No change.\n                    continue\n\n            elif sym._old_val is None:\n                # The symbol wouldn't appear in autoconf.h (because\n                # _write_to_conf is false), and it wouldn't have appeared in\n                # autoconf.h previously either (because it didn't appear in\n                # auto.conf). No change.\n                continue\n\n            # 'sym' has a new value. Flag it.\n            _touch_dep_file(path, sym.name)\n\n        # Remember the current values as the \"new old\" values.\n        #\n        # This call could go anywhere after the call to _load_old_vals(), but\n        # putting it last means _sync_deps() can be safely rerun if it fails\n        # before this point.\n        self._write_old_vals(path)\n\n    def _load_old_vals(self, path):\n        # Loads old symbol values from auto.conf into a dedicated\n        # Symbol._old_val field. Mirrors load_config().\n        #\n        # The extra field could be avoided with some trickery involving dumping\n        # symbol values and restoring them later, but this is simpler and\n        # faster. The C tools also use a dedicated field for this purpose.\n\n        for sym in self.unique_defined_syms:\n            sym._old_val = None\n\n        try:\n            auto_conf = self._open(join(path, \"auto.conf\"), \"r\")\n        except EnvironmentError as e:\n            if e.errno == errno.ENOENT:\n                # No old values\n                return\n            raise\n\n        with auto_conf as f:\n            for line in f:\n                match = self._set_match(line)\n                if not match:\n                    # We only expect CONFIG_FOO=... (and possibly a header\n                    # comment) in auto.conf\n                    continue\n\n                name, val = match.groups()\n                if name in self.syms:\n                    sym = self.syms[name]\n\n                    if sym.orig_type is STRING:\n                        match = _conf_string_match(val)\n                        if not match:\n                            continue\n                        val = unescape(match.group(1))\n\n                    self.syms[name]._old_val = val\n                else:\n                    # Flag that the symbol no longer exists, in\n                    # case something still depends on it\n                    _touch_dep_file(path, name)\n\n    def _write_old_vals(self, path):\n        # Helper for writing auto.conf. Basically just a simplified\n        # write_config() that doesn't write any comments (including\n        # '# CONFIG_FOO is not set' comments). The format matches the C\n        # implementation, though the ordering is arbitrary there (depends on\n        # the hash table implementation).\n        #\n        # A separate helper function is neater than complicating write_config()\n        # by passing a flag to it, plus we only need to look at symbols here.\n\n        self._write_if_changed(\n            os.path.join(path, \"auto.conf\"),\n            self._old_vals_contents())\n\n    def _old_vals_contents(self):\n        # _write_old_vals() helper. Returns the contents to write as a string.\n\n        # Temporary list instead of generator makes this a bit faster\n        return \"\".join([\n            sym.config_string for sym in self.unique_defined_syms\n                if not (sym.orig_type in _BOOL_TRISTATE and not sym.tri_value)\n        ])\n\n    def node_iter(self, unique_syms=False):\n        \"\"\"\n        Returns a generator for iterating through all MenuNode's in the Kconfig\n        tree. The iteration is done in Kconfig definition order (each node is\n        visited before its children, and the children of a node are visited\n        before the next node).\n\n        The Kconfig.top_node menu node is skipped. It contains an implicit menu\n        that holds the top-level items.\n\n        As an example, the following code will produce a list equal to\n        Kconfig.defined_syms:\n\n          defined_syms = [node.item for node in kconf.node_iter()\n                          if isinstance(node.item, Symbol)]\n\n        unique_syms (default: False):\n          If True, only the first MenuNode will be included for symbols defined\n          in multiple locations.\n\n          Using kconf.node_iter(True) in the example above would give a list\n          equal to unique_defined_syms.\n        \"\"\"\n        if unique_syms:\n            for sym in self.unique_defined_syms:\n                sym._visited = False\n\n        node = self.top_node\n        while 1:\n            # Jump to the next node with an iterative tree walk\n            if node.list:\n                node = node.list\n            elif node.next:\n                node = node.next\n            else:\n                while node.parent:\n                    node = node.parent\n                    if node.next:\n                        node = node.next\n                        break\n                else:\n                    # No more nodes\n                    return\n\n            if unique_syms and node.item.__class__ is Symbol:\n                if node.item._visited:\n                    continue\n                node.item._visited = True\n\n            yield node\n\n    def eval_string(self, s):\n        \"\"\"\n        Returns the tristate value of the expression 's', represented as 0, 1,\n        and 2 for n, m, and y, respectively. Raises KconfigError on syntax\n        errors. Warns if undefined symbols are referenced.\n\n        As an example, if FOO and BAR are tristate symbols at least one of\n        which has the value y, then eval_string(\"y && (FOO || BAR)\") returns\n        2 (y).\n\n        To get the string value of non-bool/tristate symbols, use\n        Symbol.str_value. eval_string() always returns a tristate value, and\n        all non-bool/tristate symbols have the tristate value 0 (n).\n\n        The expression parsing is consistent with how parsing works for\n        conditional ('if ...') expressions in the configuration, and matches\n        the C implementation. m is rewritten to 'm && MODULES', so\n        eval_string(\"m\") will return 0 (n) unless modules are enabled.\n        \"\"\"\n        # The parser is optimized to be fast when parsing Kconfig files (where\n        # an expression can never appear at the beginning of a line). We have\n        # to monkey-patch things a bit here to reuse it.\n\n        self.filename = None\n\n        self._tokens = self._tokenize(\"if \" + s)\n        # Strip \"if \" to avoid giving confusing error messages\n        self._line = s\n        self._tokens_i = 1  # Skip the 'if' token\n\n        return expr_value(self._expect_expr_and_eol())\n\n    def unset_values(self):\n        \"\"\"\n        Removes any user values from all symbols, as if Kconfig.load_config()\n        or Symbol.set_value() had never been called.\n        \"\"\"\n        self._warn_assign_no_prompt = False\n        try:\n            # set_value() already rejects undefined symbols, and they don't\n            # need to be invalidated (because their value never changes), so we\n            # can just iterate over defined symbols\n            for sym in self.unique_defined_syms:\n                sym.unset_value()\n\n            for choice in self.unique_choices:\n                choice.unset_value()\n        finally:\n            self._warn_assign_no_prompt = True\n\n    def enable_warnings(self):\n        \"\"\"\n        Do 'Kconfig.warn = True' instead. Maintained for backwards\n        compatibility.\n        \"\"\"\n        self.warn = True\n\n    def disable_warnings(self):\n        \"\"\"\n        Do 'Kconfig.warn = False' instead. Maintained for backwards\n        compatibility.\n        \"\"\"\n        self.warn = False\n\n    def enable_stderr_warnings(self):\n        \"\"\"\n        Do 'Kconfig.warn_to_stderr = True' instead. Maintained for backwards\n        compatibility.\n        \"\"\"\n        self.warn_to_stderr = True\n\n    def disable_stderr_warnings(self):\n        \"\"\"\n        Do 'Kconfig.warn_to_stderr = False' instead. Maintained for backwards\n        compatibility.\n        \"\"\"\n        self.warn_to_stderr = False\n\n    def enable_undef_warnings(self):\n        \"\"\"\n        Do 'Kconfig.warn_assign_undef = True' instead. Maintained for backwards\n        compatibility.\n        \"\"\"\n        self.warn_assign_undef = True\n\n    def disable_undef_warnings(self):\n        \"\"\"\n        Do 'Kconfig.warn_assign_undef = False' instead. Maintained for\n        backwards compatibility.\n        \"\"\"\n        self.warn_assign_undef = False\n\n    def enable_override_warnings(self):\n        \"\"\"\n        Do 'Kconfig.warn_assign_override = True' instead. Maintained for\n        backwards compatibility.\n        \"\"\"\n        self.warn_assign_override = True\n\n    def disable_override_warnings(self):\n        \"\"\"\n        Do 'Kconfig.warn_assign_override = False' instead. Maintained for\n        backwards compatibility.\n        \"\"\"\n        self.warn_assign_override = False\n\n    def enable_redun_warnings(self):\n        \"\"\"\n        Do 'Kconfig.warn_assign_redun = True' instead. Maintained for backwards\n        compatibility.\n        \"\"\"\n        self.warn_assign_redun = True\n\n    def disable_redun_warnings(self):\n        \"\"\"\n        Do 'Kconfig.warn_assign_redun = False' instead. Maintained for\n        backwards compatibility.\n        \"\"\"\n        self.warn_assign_redun = False\n\n    def __repr__(self):\n        \"\"\"\n        Returns a string with information about the Kconfig object when it is\n        evaluated on e.g. the interactive Python prompt.\n        \"\"\"\n        def status(flag):\n            return \"enabled\" if flag else \"disabled\"\n\n        return \"<{}>\".format(\", \".join((\n            \"configuration with {} symbols\".format(len(self.syms)),\n            'main menu prompt \"{}\"'.format(self.mainmenu_text),\n            \"srctree is current directory\" if not self.srctree else\n                'srctree \"{}\"'.format(self.srctree),\n            'config symbol prefix \"{}\"'.format(self.config_prefix),\n            \"warnings \" + status(self.warn),\n            \"printing of warnings to stderr \" + status(self.warn_to_stderr),\n            \"undef. symbol assignment warnings \" +\n                status(self.warn_assign_undef),\n            \"overriding symbol assignment warnings \" +\n                status(self.warn_assign_override),\n            \"redundant symbol assignment warnings \" +\n                status(self.warn_assign_redun)\n        )))\n\n    #\n    # Private methods\n    #\n\n\n    #\n    # File reading\n    #\n\n    def _open_config(self, filename):\n        # Opens a .config file. First tries to open 'filename', then\n        # '$srctree/filename' if $srctree was set when the configuration was\n        # loaded.\n\n        try:\n            return self._open(filename, \"r\")\n        except EnvironmentError as e:\n            # This will try opening the same file twice if $srctree is unset,\n            # but it's not a big deal\n            try:\n                return self._open(join(self.srctree, filename), \"r\")\n            except EnvironmentError as e2:\n                # This is needed for Python 3, because e2 is deleted after\n                # the try block:\n                #\n                # https://docs.python.org/3/reference/compound_stmts.html#the-try-statement\n                e = e2\n\n            raise _KconfigIOError(\n                e, \"Could not open '{}' ({}: {}). Check that the $srctree \"\n                   \"environment variable ({}) is set correctly.\"\n                   .format(filename, errno.errorcode[e.errno], e.strerror,\n                           \"set to '{}'\".format(self.srctree) if self.srctree\n                               else \"unset or blank\"))\n\n    def _enter_file(self, filename):\n        # Jumps to the beginning of a sourced Kconfig file, saving the previous\n        # position and file object.\n        #\n        # filename:\n        #   Absolute path to file\n\n        # Path relative to $srctree, stored in e.g. self.filename (which makes\n        # it indirectly show up in MenuNode.filename). Equals 'filename' for\n        # absolute paths passed to 'source'.\n        if filename.startswith(self._srctree_prefix):\n            # Relative path (or a redundant absolute path to within $srctree,\n            # but it's probably fine to reduce those too)\n            rel_filename = filename[len(self._srctree_prefix):]\n        else:\n            # Absolute path\n            rel_filename = filename\n\n        self.kconfig_filenames.append(rel_filename)\n\n        # The parent Kconfig files are represented as a list of\n        # (<include path>, <Python 'file' object for Kconfig file>) tuples.\n        #\n        # <include path> is immutable and holds a *tuple* of\n        # (<filename>, <linenr>) tuples, giving the locations of the 'source'\n        # statements in the parent Kconfig files. The current include path is\n        # also available in Kconfig._include_path.\n        #\n        # The point of this redundant setup is to allow Kconfig._include_path\n        # to be assigned directly to MenuNode.include_path without having to\n        # copy it, sharing it wherever possible.\n\n        # Save include path and 'file' object (via its 'readline' function)\n        # before entering the file\n        self._filestack.append((self._include_path, self._readline))\n\n        # _include_path is a tuple, so this rebinds the variable instead of\n        # doing in-place modification\n        self._include_path += ((self.filename, self.linenr),)\n\n        # Check for recursive 'source'\n        for name, _ in self._include_path:\n            if name == rel_filename:\n                raise KconfigError(\n                    \"\\n{}:{}: recursive 'source' of '{}' detected. Check that \"\n                    \"environment variables are set correctly.\\n\"\n                    \"Include path:\\n{}\"\n                    .format(self.filename, self.linenr, rel_filename,\n                            \"\\n\".join(\"{}:{}\".format(name, linenr)\n                                      for name, linenr in self._include_path)))\n\n        try:\n            self._readline = self._open(filename, \"r\").readline\n        except EnvironmentError as e:\n            # We already know that the file exists\n            raise _KconfigIOError(\n                e, \"{}:{}: Could not open '{}' (in '{}') ({}: {})\"\n                   .format(self.filename, self.linenr, filename,\n                           self._line.strip(),\n                           errno.errorcode[e.errno], e.strerror))\n\n        self.filename = rel_filename\n        self.linenr = 0\n\n    def _leave_file(self):\n        # Returns from a Kconfig file to the file that sourced it. See\n        # _enter_file().\n\n        # Restore location from parent Kconfig file\n        self.filename, self.linenr = self._include_path[-1]\n        # Restore include path and 'file' object\n        self._readline.__self__.close()  # __self__ fetches the 'file' object\n        self._include_path, self._readline = self._filestack.pop()\n\n    def _next_line(self):\n        # Fetches and tokenizes the next line from the current Kconfig file.\n        # Returns False at EOF and True otherwise.\n\n        # We might already have tokens from parsing a line and discovering that\n        # it's part of a different construct\n        if self._reuse_tokens:\n            self._reuse_tokens = False\n            # self._tokens_i is known to be 1 here, because _parse_props()\n            # leaves it like that when it can't recognize a line (or parses a\n            # help text)\n            return True\n\n        # readline() returns '' over and over at EOF, which we rely on for help\n        # texts at the end of files (see _line_after_help())\n        line = self._readline()\n        if not line:\n            return False\n        self.linenr += 1\n\n        # Handle line joining\n        while line.endswith(\"\\\\\\n\"):\n            line = line[:-2] + self._readline()\n            self.linenr += 1\n\n        self._tokens = self._tokenize(line)\n        # Initialize to 1 instead of 0 to factor out code from _parse_block()\n        # and _parse_props(). They immediately fetch self._tokens[0].\n        self._tokens_i = 1\n\n        return True\n\n    def _line_after_help(self, line):\n        # Tokenizes a line after a help text. This case is special in that the\n        # line has already been fetched (to discover that it isn't part of the\n        # help text).\n        #\n        # An earlier version used a _saved_line variable instead that was\n        # checked in _next_line(). This special-casing gets rid of it and makes\n        # _reuse_tokens alone sufficient to handle unget.\n\n        # Handle line joining\n        while line.endswith(\"\\\\\\n\"):\n            line = line[:-2] + self._readline()\n            self.linenr += 1\n\n        self._tokens = self._tokenize(line)\n        self._reuse_tokens = True\n\n    def _write_if_changed(self, filename, contents):\n        # Writes 'contents' into 'filename', but only if it differs from the\n        # current contents of the file.\n        #\n        # Another variant would be write a temporary file on the same\n        # filesystem, compare the files, and rename() the temporary file if it\n        # differs, but it breaks stuff like write_config(\"/dev/null\"), which is\n        # used out there to force evaluation-related warnings to be generated.\n        # This simple version is pretty failsafe and portable.\n\n        if not self._contents_eq(filename, contents):\n            with self._open(filename, \"w\") as f:\n                f.write(contents)\n\n    def _contents_eq(self, filename, contents):\n        # Returns True if the contents of 'filename' is 'contents' (a string),\n        # and False otherwise (including if 'filename' can't be opened/read)\n\n        try:\n            with self._open(filename, \"r\") as f:\n                # Robust re. things like encoding and line endings (mmap()\n                # trickery isn't)\n                return f.read(len(contents) + 1) == contents\n        except EnvironmentError:\n            # If the error here would prevent writing the file as well, we'll\n            # notice it later\n            return False\n\n    #\n    # Tokenization\n    #\n\n    def _lookup_sym(self, name):\n        # Fetches the symbol 'name' from the symbol table, creating and\n        # registering it if it does not exist. If '_parsing_kconfigs' is False,\n        # it means we're in eval_string(), and new symbols won't be registered.\n\n        if name in self.syms:\n            return self.syms[name]\n\n        sym = Symbol()\n        sym.kconfig = self\n        sym.name = name\n        sym.is_constant = False\n        sym.rev_dep = sym.weak_rev_dep = sym.direct_dep = self.n\n\n        if self._parsing_kconfigs:\n            self.syms[name] = sym\n        else:\n            self._warn(\"no symbol {} in configuration\".format(name))\n\n        return sym\n\n    def _lookup_const_sym(self, name):\n        # Like _lookup_sym(), for constant (quoted) symbols\n\n        if name in self.const_syms:\n            return self.const_syms[name]\n\n        sym = Symbol()\n        sym.kconfig = self\n        sym.name = name\n        sym.is_constant = True\n        sym.rev_dep = sym.weak_rev_dep = sym.direct_dep = self.n\n\n        if self._parsing_kconfigs:\n            self.const_syms[name] = sym\n\n        return sym\n\n    def _tokenize(self, s):\n        # Parses 's', returning a None-terminated list of tokens. Registers any\n        # new symbols encountered with _lookup(_const)_sym().\n        #\n        # Tries to be reasonably speedy by processing chunks of text via\n        # regexes and string operations where possible. This is the biggest\n        # hotspot during parsing.\n        #\n        # It might be possible to rewrite this to 'yield' tokens instead,\n        # working across multiple lines. Lookback and compatibility with old\n        # janky versions of the C tools complicate things though.\n\n        self._line = s  # Used for error reporting\n\n        # Initial token on the line\n        match = _command_match(s)\n        if not match:\n            if s.isspace() or s.lstrip().startswith(\"#\"):\n                return (None,)\n            self._parse_error(\"unknown token at start of line\")\n\n        # Tricky implementation detail: While parsing a token, 'token' refers\n        # to the previous token. See _STRING_LEX for why this is needed.\n        token = _get_keyword(match.group(1))\n        if not token:\n            # Backwards compatibility with old versions of the C tools, which\n            # (accidentally) accepted stuff like \"--help--\" and \"-help---\".\n            # This was fixed in the C tools by commit c2264564 (\"kconfig: warn\n            # of unhandled characters in Kconfig commands\"), committed in July\n            # 2015, but it seems people still run Kconfiglib on older kernels.\n            if s.strip(\" \\t\\n-\") == \"help\":\n                return (_T_HELP, None)\n\n            # If the first token is not a keyword (and not a weird help token),\n            # we have a preprocessor variable assignment (or a bare macro on a\n            # line)\n            self._parse_assignment(s)\n            return (None,)\n\n        tokens = [token]\n        # The current index in the string being tokenized\n        i = match.end()\n\n        # Main tokenization loop (for tokens past the first one)\n        while i < len(s):\n            # Test for an identifier/keyword first. This is the most common\n            # case.\n            match = _id_keyword_match(s, i)\n            if match:\n                # We have an identifier or keyword\n\n                # Check what it is. lookup_sym() will take care of allocating\n                # new symbols for us the first time we see them. Note that\n                # 'token' still refers to the previous token.\n\n                name = match.group(1)\n                keyword = _get_keyword(name)\n                if keyword:\n                    # It's a keyword\n                    token = keyword\n                    # Jump past it\n                    i = match.end()\n\n                elif token not in _STRING_LEX:\n                    # It's a non-const symbol, except we translate n, m, and y\n                    # into the corresponding constant symbols, like the C\n                    # implementation\n\n                    if \"$\" in name:\n                        # Macro expansion within symbol name\n                        name, s, i = self._expand_name(s, i)\n                    else:\n                        i = match.end()\n\n                    token = self.const_syms[name] if name in STR_TO_TRI else \\\n                        self._lookup_sym(name)\n\n                else:\n                    # It's a case of missing quotes. For example, the\n                    # following is accepted:\n                    #\n                    #   menu unquoted_title\n                    #\n                    #   config A\n                    #       tristate unquoted_prompt\n                    #\n                    #   endmenu\n                    #\n                    # Named choices ('choice FOO') also end up here.\n\n                    if token is not _T_CHOICE:\n                        self._warn(\"style: quotes recommended around '{}' in '{}'\"\n                                   .format(name, self._line.strip()),\n                                   self.filename, self.linenr)\n\n                    token = name\n                    i = match.end()\n\n            else:\n                # Neither a keyword nor a non-const symbol\n\n                # We always strip whitespace after tokens, so it is safe to\n                # assume that s[i] is the start of a token here.\n                c = s[i]\n\n                if c in \"\\\"'\":\n                    if \"$\" not in s and \"\\\\\" not in s:\n                        # Fast path for lines without $ and \\. Find the\n                        # matching quote.\n                        end_i = s.find(c, i + 1) + 1\n                        if not end_i:\n                            self._parse_error(\"unterminated string\")\n                        val = s[i + 1:end_i - 1]\n                        i = end_i\n                    else:\n                        # Slow path\n                        s, end_i = self._expand_str(s, i)\n\n                        # os.path.expandvars() and the $UNAME_RELEASE replace()\n                        # is a backwards compatibility hack, which should be\n                        # reasonably safe as expandvars() leaves references to\n                        # undefined env. vars. as is.\n                        #\n                        # The preprocessor functionality changed how\n                        # environment variables are referenced, to $(FOO).\n                        val = expandvars(s[i + 1:end_i - 1]\n                                         .replace(\"$UNAME_RELEASE\",\n                                                  _UNAME_RELEASE))\n\n                        i = end_i\n\n                    # This is the only place where we don't survive with a\n                    # single token of lookback: 'option env=\"FOO\"' does not\n                    # refer to a constant symbol named \"FOO\".\n                    token = \\\n                        val if token in _STRING_LEX or tokens[0] is _T_OPTION \\\n                        else self._lookup_const_sym(val)\n\n                elif s.startswith(\"&&\", i):\n                    token = _T_AND\n                    i += 2\n\n                elif s.startswith(\"||\", i):\n                    token = _T_OR\n                    i += 2\n\n                elif c == \"=\":\n                    token = _T_EQUAL\n                    i += 1\n\n                elif s.startswith(\"!=\", i):\n                    token = _T_UNEQUAL\n                    i += 2\n\n                elif c == \"!\":\n                    token = _T_NOT\n                    i += 1\n\n                elif c == \"(\":\n                    token = _T_OPEN_PAREN\n                    i += 1\n\n                elif c == \")\":\n                    token = _T_CLOSE_PAREN\n                    i += 1\n\n                elif c == \"#\":\n                    break\n\n\n                # Very rare\n\n                elif s.startswith(\"<=\", i):\n                    token = _T_LESS_EQUAL\n                    i += 2\n\n                elif c == \"<\":\n                    token = _T_LESS\n                    i += 1\n\n                elif s.startswith(\">=\", i):\n                    token = _T_GREATER_EQUAL\n                    i += 2\n\n                elif c == \">\":\n                    token = _T_GREATER\n                    i += 1\n\n\n                else:\n                    self._parse_error(\"unknown tokens in line\")\n\n\n                # Skip trailing whitespace\n                while i < len(s) and s[i].isspace():\n                    i += 1\n\n\n            # Add the token\n            tokens.append(token)\n\n        # None-terminating the token list makes token fetching simpler/faster\n        tokens.append(None)\n\n        return tokens\n\n    # Helpers for syntax checking and token fetching. See the\n    # 'Intro to expressions' section for what a constant symbol is.\n    #\n    # More of these could be added, but the single-use cases are inlined as an\n    # optimization.\n\n    def _expect_sym(self):\n        token = self._tokens[self._tokens_i]\n        self._tokens_i += 1\n\n        if token.__class__ is not Symbol:\n            self._parse_error(\"expected symbol\")\n\n        return token\n\n    def _expect_nonconst_sym(self):\n        # Used for 'select' and 'imply' only. We know the token indices.\n\n        token = self._tokens[1]\n        self._tokens_i = 2\n\n        if token.__class__ is not Symbol or token.is_constant:\n            self._parse_error(\"expected nonconstant symbol\")\n\n        return token\n\n    def _expect_str_and_eol(self):\n        token = self._tokens[self._tokens_i]\n        self._tokens_i += 1\n\n        if token.__class__ is not str:\n            self._parse_error(\"expected string\")\n\n        if self._tokens[self._tokens_i] is not None:\n            self._trailing_tokens_error()\n\n        return token\n\n    def _expect_expr_and_eol(self):\n        expr = self._parse_expr(True)\n\n        if self._tokens[self._tokens_i] is not None:\n            self._trailing_tokens_error()\n\n        return expr\n\n    def _check_token(self, token):\n        # If the next token is 'token', removes it and returns True\n\n        if self._tokens[self._tokens_i] is token:\n            self._tokens_i += 1\n            return True\n        return False\n\n    #\n    # Preprocessor logic\n    #\n\n    def _parse_assignment(self, s):\n        # Parses a preprocessor variable assignment, registering the variable\n        # if it doesn't already exist. Also takes care of bare macros on lines\n        # (which are allowed, and can be useful for their side effects).\n\n        # Expand any macros in the left-hand side of the assignment (the\n        # variable name)\n        s = s.lstrip()\n        i = 0\n        while 1:\n            i = _assignment_lhs_fragment_match(s, i).end()\n            if s.startswith(\"$(\", i):\n                s, i = self._expand_macro(s, i, ())\n            else:\n                break\n\n        if s.isspace():\n            # We also accept a bare macro on a line (e.g.\n            # $(warning-if,$(foo),ops)), provided it expands to a blank string\n            return\n\n        # Assigned variable\n        name = s[:i]\n\n\n        # Extract assignment operator (=, :=, or +=) and value\n        rhs_match = _assignment_rhs_match(s, i)\n        if not rhs_match:\n            self._parse_error(\"syntax error\")\n\n        op, val = rhs_match.groups()\n\n\n        if name in self.variables:\n            # Already seen variable\n            var = self.variables[name]\n        else:\n            # New variable\n            var = Variable()\n            var.kconfig = self\n            var.name = name\n            var._n_expansions = 0\n            self.variables[name] = var\n\n            # += acts like = on undefined variables (defines a recursive\n            # variable)\n            if op == \"+=\":\n                op = \"=\"\n\n        if op == \"=\":\n            var.is_recursive = True\n            var.value = val\n        elif op == \":=\":\n            var.is_recursive = False\n            var.value = self._expand_whole(val, ())\n        else:  # op == \"+=\"\n            # += does immediate expansion if the variable was last set\n            # with :=\n            var.value += \" \" + (val if var.is_recursive else\n                                self._expand_whole(val, ()))\n\n    def _expand_whole(self, s, args):\n        # Expands preprocessor macros in all of 's'. Used whenever we don't\n        # have to worry about delimiters. See _expand_macro() re. the 'args'\n        # parameter.\n        #\n        # Returns the expanded string.\n\n        i = 0\n        while 1:\n            i = s.find(\"$(\", i)\n            if i == -1:\n                break\n            s, i = self._expand_macro(s, i, args)\n        return s\n\n    def _expand_name(self, s, i):\n        # Expands a symbol name starting at index 'i' in 's'.\n        #\n        # Returns the expanded name, the expanded 's' (including the part\n        # before the name), and the index of the first character in the next\n        # token after the name.\n\n        s, end_i = self._expand_name_iter(s, i)\n        name = s[i:end_i]\n        # isspace() is False for empty strings\n        if not name.strip():\n            # Avoid creating a Kconfig symbol with a blank name. It's almost\n            # guaranteed to be an error.\n            self._parse_error(\"macro expanded to blank string\")\n\n        # Skip trailing whitespace\n        while end_i < len(s) and s[end_i].isspace():\n            end_i += 1\n\n        return name, s, end_i\n\n    def _expand_name_iter(self, s, i):\n        # Expands a symbol name starting at index 'i' in 's'.\n        #\n        # Returns the expanded 's' (including the part before the name) and the\n        # index of the first character after the expanded name in 's'.\n\n        while 1:\n            match = _name_special_search(s, i)\n\n            if match.group() != \"$(\":\n                return (s, match.start())\n            s, i = self._expand_macro(s, match.start(), ())\n\n    def _expand_str(self, s, i):\n        # Expands a quoted string starting at index 'i' in 's'. Handles both\n        # backslash escapes and macro expansion.\n        #\n        # Returns the expanded 's' (including the part before the string) and\n        # the index of the first character after the expanded string in 's'.\n\n        quote = s[i]\n        i += 1  # Skip over initial \"/'\n        while 1:\n            match = _string_special_search(s, i)\n            if not match:\n                self._parse_error(\"unterminated string\")\n\n\n            if match.group() == quote:\n                # Found the end of the string\n                return (s, match.end())\n\n            elif match.group() == \"\\\\\":\n                # Replace '\\x' with 'x'. 'i' ends up pointing to the character\n                # after 'x', which allows macros to be canceled with '\\$(foo)'.\n                i = match.end()\n                s = s[:match.start()] + s[i:]\n\n            elif match.group() == \"$(\":\n                # A macro call within the string\n                s, i = self._expand_macro(s, match.start(), ())\n\n            else:\n                # A ' quote within \" quotes or vice versa\n                i += 1\n\n    def _expand_macro(self, s, i, args):\n        # Expands a macro starting at index 'i' in 's'. If this macro resulted\n        # from the expansion of another macro, 'args' holds the arguments\n        # passed to that macro.\n        #\n        # Returns the expanded 's' (including the part before the macro) and\n        # the index of the first character after the expanded macro in 's'.\n\n        res = s[:i]\n        i += 2  # Skip over \"$(\"\n\n        arg_start = i  # Start of current macro argument\n        new_args = []  # Arguments of this macro call\n        nesting = 0  # Current parentheses nesting level\n\n        while 1:\n            match = _macro_special_search(s, i)\n            if not match:\n                self._parse_error(\"missing end parenthesis in macro expansion\")\n\n\n            if match.group() == \"(\":\n                nesting += 1\n                i = match.end()\n\n            elif match.group() == \")\":\n                if nesting:\n                    nesting -= 1\n                    i = match.end()\n                    continue\n\n                # Found the end of the macro\n\n                new_args.append(s[arg_start:match.start()])\n\n                # $(1) is replaced by the first argument to the function, etc.,\n                # provided at least that many arguments were passed\n\n                try:\n                    # Does the macro look like an integer, with a corresponding\n                    # argument? If so, expand it to the value of the argument.\n                    res += args[int(new_args[0])]\n                except (ValueError, IndexError):\n                    # Regular variables are just functions without arguments,\n                    # and also go through the function value path\n                    res += self._fn_val(new_args)\n\n                return (res + s[match.end():], len(res))\n\n            elif match.group() == \",\":\n                i = match.end()\n                if nesting:\n                    continue\n\n                # Found the end of a macro argument\n                new_args.append(s[arg_start:match.start()])\n                arg_start = i\n\n            else:  # match.group() == \"$(\"\n                # A nested macro call within the macro\n                s, i = self._expand_macro(s, match.start(), args)\n\n    def _fn_val(self, args):\n        # Returns the result of calling the function args[0] with the arguments\n        # args[1..len(args)-1]. Plain variables are treated as functions\n        # without arguments.\n\n        fn = args[0]\n\n        if fn in self.variables:\n            var = self.variables[fn]\n\n            if len(args) == 1:\n                # Plain variable\n                if var._n_expansions:\n                    self._parse_error(\"Preprocessor variable {} recursively \"\n                                      \"references itself\".format(var.name))\n            elif var._n_expansions > 100:\n                # Allow functions to call themselves, but guess that functions\n                # that are overly recursive are stuck\n                self._parse_error(\"Preprocessor function {} seems stuck \"\n                                  \"in infinite recursion\".format(var.name))\n\n            var._n_expansions += 1\n            res = self._expand_whole(self.variables[fn].value, args)\n            var._n_expansions -= 1\n            return res\n\n        if fn in self._functions:\n            # Built-in or user-defined function\n\n            py_fn, min_arg, max_arg = self._functions[fn]\n\n            if len(args) - 1 < min_arg or \\\n               (max_arg is not None and len(args) - 1 > max_arg):\n\n                if min_arg == max_arg:\n                    expected_args = min_arg\n                elif max_arg is None:\n                    expected_args = \"{} or more\".format(min_arg)\n                else:\n                    expected_args = \"{}-{}\".format(min_arg, max_arg)\n\n                raise KconfigError(\"{}:{}: bad number of arguments in call \"\n                                   \"to {}, expected {}, got {}\"\n                                   .format(self.filename, self.linenr, fn,\n                                           expected_args, len(args) - 1))\n\n            return py_fn(self, *args)\n\n        # Environment variables are tried last\n        if fn in os.environ:\n            self.env_vars.add(fn)\n            return os.environ[fn]\n\n        return \"\"\n\n    #\n    # Parsing\n    #\n\n    def _make_and(self, e1, e2):\n        # Constructs an AND (&&) expression. Performs trivial simplification.\n\n        if e1 is self.y:\n            return e2\n\n        if e2 is self.y:\n            return e1\n\n        if e1 is self.n or e2 is self.n:\n            return self.n\n\n        return (AND, e1, e2)\n\n    def _make_or(self, e1, e2):\n        # Constructs an OR (||) expression. Performs trivial simplification.\n\n        if e1 is self.n:\n            return e2\n\n        if e2 is self.n:\n            return e1\n\n        if e1 is self.y or e2 is self.y:\n            return self.y\n\n        return (OR, e1, e2)\n\n    def _parse_block(self, end_token, parent, prev):\n        # Parses a block, which is the contents of either a file or an if,\n        # menu, or choice statement.\n        #\n        # end_token:\n        #   The token that ends the block, e.g. _T_ENDIF (\"endif\") for ifs.\n        #   None for files.\n        #\n        # parent:\n        #   The parent menu node, corresponding to a menu, Choice, or 'if'.\n        #   'if's are flattened after parsing.\n        #\n        # prev:\n        #   The previous menu node. New nodes will be added after this one (by\n        #   modifying their 'next' pointer).\n        #\n        #   'prev' is reused to parse a list of child menu nodes (for a menu or\n        #   Choice): After parsing the children, the 'next' pointer is assigned\n        #   to the 'list' pointer to \"tilt up\" the children above the node.\n        #\n        # Returns the final menu node in the block (or 'prev' if the block is\n        # empty). This allows chaining.\n\n        while self._next_line():\n            t0 = self._tokens[0]\n\n            if t0 is _T_CONFIG or t0 is _T_MENUCONFIG:\n                # The tokenizer allocates Symbol objects for us\n                sym = self._tokens[1]\n\n                if sym.__class__ is not Symbol or sym.is_constant:\n                    self._parse_error(\"missing or bad symbol name\")\n\n                if self._tokens[2] is not None:\n                    self._trailing_tokens_error()\n\n                self.defined_syms.append(sym)\n\n                node = MenuNode()\n                node.kconfig = self\n                node.item = sym\n                node.is_menuconfig = (t0 is _T_MENUCONFIG)\n                node.prompt = node.help = node.list = None\n                node.parent = parent\n                node.filename = self.filename\n                node.linenr = self.linenr\n                node.include_path = self._include_path\n\n                sym.nodes.append(node)\n\n                self._parse_props(node)\n\n                if node.is_menuconfig and not node.prompt:\n                    self._warn(\"the menuconfig symbol {} has no prompt\"\n                               .format(sym.name_and_loc))\n\n                # Equivalent to\n                #\n                #   prev.next = node\n                #   prev = node\n                #\n                # due to tricky Python semantics. The order matters.\n                prev.next = prev = node\n\n            elif t0 is None:\n                # Blank line\n                continue\n\n            elif t0 in _SOURCE_TOKENS:\n                pattern = self._expect_str_and_eol()\n\n                if t0 in _REL_SOURCE_TOKENS:\n                    # Relative source\n                    pattern = join(dirname(self.filename), pattern)\n\n                # - glob() doesn't support globbing relative to a directory, so\n                #   we need to prepend $srctree to 'pattern'. Use join()\n                #   instead of '+' so that an absolute path in 'pattern' is\n                #   preserved.\n                #\n                # - Sort the glob results to ensure a consistent ordering of\n                #   Kconfig symbols, which indirectly ensures a consistent\n                #   ordering in e.g. .config files\n                filenames = sorted(iglob(join(self._srctree_prefix, pattern)))\n\n                if not filenames and t0 in _OBL_SOURCE_TOKENS:\n                    raise KconfigError(\n                        \"{}:{}: '{}' not found (in '{}'). Check that \"\n                        \"environment variables are set correctly (e.g. \"\n                        \"$srctree, which is {}). Also note that unset \"\n                        \"environment variables expand to the empty string.\"\n                        .format(self.filename, self.linenr, pattern,\n                                self._line.strip(),\n                                \"set to '{}'\".format(self.srctree)\n                                    if self.srctree else \"unset or blank\"))\n\n                for filename in filenames:\n                    self._enter_file(filename)\n                    prev = self._parse_block(None, parent, prev)\n                    self._leave_file()\n\n            elif t0 is end_token:\n                # Reached the end of the block. Terminate the final node and\n                # return it.\n\n                if self._tokens[1] is not None:\n                    self._trailing_tokens_error()\n\n                prev.next = None\n                return prev\n\n            elif t0 is _T_IF:\n                node = MenuNode()\n                node.item = node.prompt = None\n                node.parent = parent\n                node.dep = self._expect_expr_and_eol()\n\n                self._parse_block(_T_ENDIF, node, node)\n                node.list = node.next\n\n                prev.next = prev = node\n\n            elif t0 is _T_MENU:\n                node = MenuNode()\n                node.kconfig = self\n                node.item = t0  # _T_MENU == MENU\n                node.is_menuconfig = True\n                node.prompt = (self._expect_str_and_eol(), self.y)\n                node.visibility = self.y\n                node.parent = parent\n                node.filename = self.filename\n                node.linenr = self.linenr\n                node.include_path = self._include_path\n\n                self.menus.append(node)\n\n                self._parse_props(node)\n                self._parse_block(_T_ENDMENU, node, node)\n                node.list = node.next\n\n                prev.next = prev = node\n\n            elif t0 is _T_COMMENT:\n                node = MenuNode()\n                node.kconfig = self\n                node.item = t0  # _T_COMMENT == COMMENT\n                node.is_menuconfig = False\n                node.prompt = (self._expect_str_and_eol(), self.y)\n                node.list = None\n                node.parent = parent\n                node.filename = self.filename\n                node.linenr = self.linenr\n                node.include_path = self._include_path\n\n                self.comments.append(node)\n\n                self._parse_props(node)\n\n                prev.next = prev = node\n\n            elif t0 is _T_CHOICE:\n                if self._tokens[1] is None:\n                    choice = Choice()\n                    choice.direct_dep = self.n\n                else:\n                    # Named choice\n                    name = self._expect_str_and_eol()\n                    choice = self.named_choices.get(name)\n                    if not choice:\n                        choice = Choice()\n                        choice.name = name\n                        choice.direct_dep = self.n\n                        self.named_choices[name] = choice\n\n                self.choices.append(choice)\n\n                node = MenuNode()\n                node.kconfig = choice.kconfig = self\n                node.item = choice\n                node.is_menuconfig = True\n                node.prompt = node.help = None\n                node.parent = parent\n                node.filename = self.filename\n                node.linenr = self.linenr\n                node.include_path = self._include_path\n\n                choice.nodes.append(node)\n\n                self._parse_props(node)\n                self._parse_block(_T_ENDCHOICE, node, node)\n                node.list = node.next\n\n                prev.next = prev = node\n\n            elif t0 is _T_MAINMENU:\n                self.top_node.prompt = (self._expect_str_and_eol(), self.y)\n\n            else:\n                # A valid endchoice/endif/endmenu is caught by the 'end_token'\n                # check above\n                self._parse_error(\n                    \"no corresponding 'choice'\" if t0 is _T_ENDCHOICE else\n                    \"no corresponding 'if'\"     if t0 is _T_ENDIF else\n                    \"no corresponding 'menu'\"   if t0 is _T_ENDMENU else\n                    \"unrecognized construct\")\n\n        # End of file reached. Return the last node.\n\n        if end_token:\n            raise KconfigError(\n                \"error: expected '{}' at end of '{}'\"\n                .format(\"endchoice\" if end_token is _T_ENDCHOICE else\n                        \"endif\"     if end_token is _T_ENDIF else\n                        \"endmenu\",\n                        self.filename))\n\n        return prev\n\n    def _parse_cond(self):\n        # Parses an optional 'if <expr>' construct and returns the parsed\n        # <expr>, or self.y if the next token is not _T_IF\n\n        expr = self._parse_expr(True) if self._check_token(_T_IF) else self.y\n\n        if self._tokens[self._tokens_i] is not None:\n            self._trailing_tokens_error()\n\n        return expr\n\n    def _parse_props(self, node):\n        # Parses and adds properties to the MenuNode 'node' (type, 'prompt',\n        # 'default's, etc.) Properties are later copied up to symbols and\n        # choices in a separate pass after parsing, in e.g.\n        # _add_props_to_sym().\n        #\n        # An older version of this code added properties directly to symbols\n        # and choices instead of to their menu nodes (and handled dependency\n        # propagation simultaneously), but that loses information on where a\n        # property is added when a symbol or choice is defined in multiple\n        # locations. Some Kconfig configuration systems rely heavily on such\n        # symbols, and better docs can be generated by keeping track of where\n        # properties are added.\n        #\n        # node:\n        #   The menu node we're parsing properties on\n\n        # Dependencies from 'depends on'. Will get propagated to the properties\n        # below.\n        node.dep = self.y\n\n        while self._next_line():\n            t0 = self._tokens[0]\n\n            if t0 in _TYPE_TOKENS:\n                # Relies on '_T_BOOL is BOOL', etc., to save a conversion\n                self._set_type(node.item, t0)\n                if self._tokens[1] is not None:\n                    self._parse_prompt(node)\n\n            elif t0 is _T_DEPENDS:\n                if not self._check_token(_T_ON):\n                    self._parse_error(\"expected 'on' after 'depends'\")\n\n                node.dep = self._make_and(node.dep,\n                                          self._expect_expr_and_eol())\n\n            elif t0 is _T_HELP:\n                self._parse_help(node)\n\n            elif t0 is _T_SELECT:\n                if node.item.__class__ is not Symbol:\n                    self._parse_error(\"only symbols can select\")\n\n                node.selects.append((self._expect_nonconst_sym(),\n                                     self._parse_cond()))\n\n            elif t0 is None:\n                # Blank line\n                continue\n\n            elif t0 is _T_DEFAULT:\n                node.defaults.append((self._parse_expr(False),\n                                      self._parse_cond()))\n\n            elif t0 in _DEF_TOKEN_TO_TYPE:\n                self._set_type(node.item, _DEF_TOKEN_TO_TYPE[t0])\n                node.defaults.append((self._parse_expr(False),\n                                      self._parse_cond()))\n\n            elif t0 is _T_PROMPT:\n                self._parse_prompt(node)\n\n            elif t0 is _T_RANGE:\n                node.ranges.append((self._expect_sym(), self._expect_sym(),\n                                    self._parse_cond()))\n\n            elif t0 is _T_IMPLY:\n                if node.item.__class__ is not Symbol:\n                    self._parse_error(\"only symbols can imply\")\n\n                node.implies.append((self._expect_nonconst_sym(),\n                                     self._parse_cond()))\n\n            elif t0 is _T_VISIBLE:\n                if not self._check_token(_T_IF):\n                    self._parse_error(\"expected 'if' after 'visible'\")\n\n                node.visibility = self._make_and(node.visibility,\n                                                 self._expect_expr_and_eol())\n\n            elif t0 is _T_OPTION:\n                if self._check_token(_T_ENV):\n                    if not self._check_token(_T_EQUAL):\n                        self._parse_error(\"expected '=' after 'env'\")\n\n                    env_var = self._expect_str_and_eol()\n                    node.item.env_var = env_var\n\n                    if env_var in os.environ:\n                        node.defaults.append(\n                            (self._lookup_const_sym(os.environ[env_var]),\n                             self.y))\n                    else:\n                        self._warn(\"{1} has 'option env=\\\"{0}\\\"', \"\n                                   \"but the environment variable {0} is not \"\n                                   \"set\".format(node.item.name, env_var),\n                                   self.filename, self.linenr)\n\n                    if env_var != node.item.name:\n                        self._warn(\"Kconfiglib expands environment variables \"\n                                   \"in strings directly, meaning you do not \"\n                                   \"need 'option env=...' \\\"bounce\\\" symbols. \"\n                                   \"For compatibility with the C tools, \"\n                                   \"rename {} to {} (so that the symbol name \"\n                                   \"matches the environment variable name).\"\n                                   .format(node.item.name, env_var),\n                                   self.filename, self.linenr)\n\n                elif self._check_token(_T_DEFCONFIG_LIST):\n                    if not self.defconfig_list:\n                        self.defconfig_list = node.item\n                    else:\n                        self._warn(\"'option defconfig_list' set on multiple \"\n                                   \"symbols ({0} and {1}). Only {0} will be \"\n                                   \"used.\".format(self.defconfig_list.name,\n                                                  node.item.name),\n                                   self.filename, self.linenr)\n\n                elif self._check_token(_T_MODULES):\n                    # To reduce warning spam, only warn if 'option modules' is\n                    # set on some symbol that isn't MODULES, which should be\n                    # safe. I haven't run into any projects that make use\n                    # modules besides the kernel yet, and there it's likely to\n                    # keep being called \"MODULES\".\n                    if node.item is not self.modules:\n                        self._warn(\"the 'modules' option is not supported. \"\n                                   \"Let me know if this is a problem for you, \"\n                                   \"as it wouldn't be that hard to implement. \"\n                                   \"Note that modules are supported -- \"\n                                   \"Kconfiglib just assumes the symbol name \"\n                                   \"MODULES, like older versions of the C \"\n                                   \"implementation did when 'option modules' \"\n                                   \"wasn't used.\",\n                                   self.filename, self.linenr)\n\n                elif self._check_token(_T_ALLNOCONFIG_Y):\n                    if node.item.__class__ is not Symbol:\n                        self._parse_error(\"the 'allnoconfig_y' option is only \"\n                                          \"valid for symbols\")\n\n                    node.item.is_allnoconfig_y = True\n\n                else:\n                    self._parse_error(\"unrecognized option\")\n\n            elif t0 is _T_OPTIONAL:\n                if node.item.__class__ is not Choice:\n                    self._parse_error('\"optional\" is only valid for choices')\n\n                node.item.is_optional = True\n\n            else:\n                # Reuse the tokens for the non-property line later\n                self._reuse_tokens = True\n                return\n\n    def _set_type(self, sc, new_type):\n        # Sets the type of 'sc' (symbol or choice) to 'new_type'\n\n        # UNKNOWN is falsy\n        if sc.orig_type and sc.orig_type is not new_type:\n            self._warn(\"{} defined with multiple types, {} will be used\"\n                       .format(sc.name_and_loc, TYPE_TO_STR[new_type]))\n\n        sc.orig_type = new_type\n\n    def _parse_prompt(self, node):\n        # 'prompt' properties override each other within a single definition of\n        # a symbol, but additional prompts can be added by defining the symbol\n        # multiple times\n\n        if node.prompt:\n            self._warn(node.item.name_and_loc +\n                       \" defined with multiple prompts in single location\")\n\n        prompt = self._tokens[1]\n        self._tokens_i = 2\n\n        if prompt.__class__ is not str:\n            self._parse_error(\"expected prompt string\")\n\n        if prompt != prompt.strip():\n            self._warn(node.item.name_and_loc +\n                       \" has leading or trailing whitespace in its prompt\")\n\n            # This avoid issues for e.g. reStructuredText documentation, where\n            # '*prompt *' is invalid\n            prompt = prompt.strip()\n\n        node.prompt = (prompt, self._parse_cond())\n\n    def _parse_help(self, node):\n        if node.help is not None:\n            self._warn(node.item.name_and_loc + \" defined with more than \"\n                       \"one help text -- only the last one will be used\")\n\n        # Micro-optimization. This code is pretty hot.\n        readline = self._readline\n\n        # Find first non-blank (not all-space) line and get its\n        # indentation\n\n        while 1:\n            line = readline()\n            self.linenr += 1\n            if not line:\n                self._empty_help(node, line)\n                return\n            if not line.isspace():\n                break\n\n        len_ = len  # Micro-optimization\n\n        # Use a separate 'expline' variable here and below to avoid stomping on\n        # any tabs people might've put deliberately into the first line after\n        # the help text\n        expline = line.expandtabs()\n        indent = len_(expline) - len_(expline.lstrip())\n        if not indent:\n            self._empty_help(node, line)\n            return\n\n        # The help text goes on till the first non-blank line with less indent\n        # than the first line\n\n        # Add the first line\n        lines = [expline[indent:]]\n        add_line = lines.append  # Micro-optimization\n\n        while 1:\n            line = readline()\n            if line.isspace():\n                # No need to preserve the exact whitespace in these\n                add_line(\"\\n\")\n            elif not line:\n                # End of file\n                break\n            else:\n                expline = line.expandtabs()\n                if len_(expline) - len_(expline.lstrip()) < indent:\n                    break\n                add_line(expline[indent:])\n\n        self.linenr += len_(lines)\n        node.help = \"\".join(lines).rstrip()\n        if line:\n            self._line_after_help(line)\n\n    def _empty_help(self, node, line):\n        self._warn(node.item.name_and_loc +\n                   \" has 'help' but empty help text\")\n        node.help = \"\"\n        if line:\n            self._line_after_help(line)\n\n    def _parse_expr(self, transform_m):\n        # Parses an expression from the tokens in Kconfig._tokens using a\n        # simple top-down approach. See the module docstring for the expression\n        # format.\n        #\n        # transform_m:\n        #   True if m should be rewritten to m && MODULES. See the\n        #   Kconfig.eval_string() documentation.\n\n        # Grammar:\n        #\n        #   expr:     and_expr ['||' expr]\n        #   and_expr: factor ['&&' and_expr]\n        #   factor:   <symbol> ['='/'!='/'<'/... <symbol>]\n        #             '!' factor\n        #             '(' expr ')'\n        #\n        # It helps to think of the 'expr: and_expr' case as a single-operand OR\n        # (no ||), and of the 'and_expr: factor' case as a single-operand AND\n        # (no &&). Parsing code is always a bit tricky.\n\n        # Mind dump: parse_factor() and two nested loops for OR and AND would\n        # work as well. The straightforward implementation there gives a\n        # (op, (op, (op, A, B), C), D) parse for A op B op C op D. Representing\n        # expressions as (op, [list of operands]) instead goes nicely with that\n        # version, but is wasteful for short expressions and complicates\n        # expression evaluation and other code that works on expressions (more\n        # complicated code likely offsets any performance gain from less\n        # recursion too). If we also try to optimize the list representation by\n        # merging lists when possible (e.g. when ANDing two AND expressions),\n        # we end up allocating a ton of lists instead of reusing expressions,\n        # which is bad.\n\n        and_expr = self._parse_and_expr(transform_m)\n\n        # Return 'and_expr' directly if we have a \"single-operand\" OR.\n        # Otherwise, parse the expression on the right and make an OR node.\n        # This turns A || B || C || D into (OR, A, (OR, B, (OR, C, D))).\n        return and_expr if not self._check_token(_T_OR) else \\\n            (OR, and_expr, self._parse_expr(transform_m))\n\n    def _parse_and_expr(self, transform_m):\n        factor = self._parse_factor(transform_m)\n\n        # Return 'factor' directly if we have a \"single-operand\" AND.\n        # Otherwise, parse the right operand and make an AND node. This turns\n        # A && B && C && D into (AND, A, (AND, B, (AND, C, D))).\n        return factor if not self._check_token(_T_AND) else \\\n            (AND, factor, self._parse_and_expr(transform_m))\n\n    def _parse_factor(self, transform_m):\n        token = self._tokens[self._tokens_i]\n        self._tokens_i += 1\n\n        if token.__class__ is Symbol:\n            # Plain symbol or relation\n\n            if self._tokens[self._tokens_i] not in _RELATIONS:\n                # Plain symbol\n\n                # For conditional expressions ('depends on <expr>',\n                # '... if <expr>', etc.), m is rewritten to m && MODULES.\n                if transform_m and token is self.m:\n                    return (AND, self.m, self.modules)\n\n                return token\n\n            # Relation\n            #\n            # _T_EQUAL, _T_UNEQUAL, etc., deliberately have the same values as\n            # EQUAL, UNEQUAL, etc., so we can just use the token directly\n            self._tokens_i += 1\n            return (self._tokens[self._tokens_i - 1], token,\n                    self._expect_sym())\n\n        if token is _T_NOT:\n            # token == _T_NOT == NOT\n            return (token, self._parse_factor(transform_m))\n\n        if token is _T_OPEN_PAREN:\n            expr_parse = self._parse_expr(transform_m)\n            if self._check_token(_T_CLOSE_PAREN):\n                return expr_parse\n\n        self._parse_error(\"malformed expression\")\n\n    #\n    # Caching and invalidation\n    #\n\n    def _build_dep(self):\n        # Populates the Symbol/Choice._dependents sets, which contain all other\n        # items (symbols and choices) that immediately depend on the item in\n        # the sense that changing the value of the item might affect the value\n        # of the dependent items. This is used for caching/invalidation.\n        #\n        # The calculated sets might be larger than necessary as we don't do any\n        # complex analysis of the expressions.\n\n        depend_on = _depend_on  # Micro-optimization\n\n        # Only calculate _dependents for defined symbols. Constant and\n        # undefined symbols could theoretically be selected/implied, but it\n        # wouldn't change their value, so it's not a true dependency.\n        for sym in self.unique_defined_syms:\n            # Symbols depend on the following:\n\n            # The prompt conditions\n            for node in sym.nodes:\n                if node.prompt:\n                    depend_on(sym, node.prompt[1])\n\n            # The default values and their conditions\n            for value, cond in sym.defaults:\n                depend_on(sym, value)\n                depend_on(sym, cond)\n\n            # The reverse and weak reverse dependencies\n            depend_on(sym, sym.rev_dep)\n            depend_on(sym, sym.weak_rev_dep)\n\n            # The ranges along with their conditions\n            for low, high, cond in sym.ranges:\n                depend_on(sym, low)\n                depend_on(sym, high)\n                depend_on(sym, cond)\n\n            # The direct dependencies. This is usually redundant, as the direct\n            # dependencies get propagated to properties, but it's needed to get\n            # invalidation solid for 'imply', which only checks the direct\n            # dependencies (even if there are no properties to propagate it\n            # to).\n            depend_on(sym, sym.direct_dep)\n\n            # In addition to the above, choice symbols depend on the choice\n            # they're in, but that's handled automatically since the Choice is\n            # propagated to the conditions of the properties before\n            # _build_dep() runs.\n\n        for choice in self.unique_choices:\n            # Choices depend on the following:\n\n            # The prompt conditions\n            for node in choice.nodes:\n                if node.prompt:\n                    depend_on(choice, node.prompt[1])\n\n            # The default symbol conditions\n            for _, cond in choice.defaults:\n                depend_on(choice, cond)\n\n    def _add_choice_deps(self):\n        # Choices also depend on the choice symbols themselves, because the\n        # y-mode selection of the choice might change if a choice symbol's\n        # visibility changes.\n        #\n        # We add these dependencies separately after dependency loop detection.\n        # The invalidation algorithm can handle the resulting\n        # <choice symbol> <-> <choice> dependency loops, but they make loop\n        # detection awkward.\n\n        for choice in self.unique_choices:\n            for sym in choice.syms:\n                sym._dependents.add(choice)\n\n    def _invalidate_all(self):\n        # Undefined symbols never change value and don't need to be\n        # invalidated, so we can just iterate over defined symbols.\n        # Invalidating constant symbols would break things horribly.\n        for sym in self.unique_defined_syms:\n            sym._invalidate()\n\n        for choice in self.unique_choices:\n            choice._invalidate()\n\n    #\n    # Post-parsing menu tree processing, including dependency propagation and\n    # implicit submenu creation\n    #\n\n    def _finalize_node(self, node, visible_if):\n        # Finalizes a menu node and its children:\n        #\n        #  - Copies properties from menu nodes up to their contained\n        #    symbols/choices\n        #\n        #  - Propagates dependencies from parent to child nodes\n        #\n        #  - Creates implicit menus (see kconfig-language.txt)\n        #\n        #  - Removes 'if' nodes\n        #\n        #  - Sets 'choice' types and registers choice symbols\n        #\n        # menu_finalize() in the C implementation is similar.\n        #\n        # node:\n        #   The menu node to finalize. This node and its children will have\n        #   been finalized when the function returns, and any implicit menus\n        #   will have been created.\n        #\n        # visible_if:\n        #   Dependencies from 'visible if' on parent menus. These are added to\n        #   the prompts of symbols and choices.\n\n        if node.item.__class__ is Symbol:\n            # Copy defaults, ranges, selects, and implies to the Symbol\n            self._add_props_to_sym(node)\n\n            # Find any items that should go in an implicit menu rooted at the\n            # symbol\n            cur = node\n            while cur.next and _auto_menu_dep(node, cur.next):\n                # This makes implicit submenu creation work recursively, with\n                # implicit menus inside implicit menus\n                self._finalize_node(cur.next, visible_if)\n                cur = cur.next\n                cur.parent = node\n\n            if cur is not node:\n                # Found symbols that should go in an implicit submenu. Tilt\n                # them up above us.\n                node.list = node.next\n                node.next = cur.next\n                cur.next = None\n\n        elif node.list:\n            # The menu node is a choice, menu, or if. Finalize each child node.\n\n            if node.item is MENU:\n                visible_if = self._make_and(visible_if, node.visibility)\n\n            # Propagate the menu node's dependencies to each child menu node.\n            #\n            # This needs to go before the recursive _finalize_node() call so\n            # that implicit submenu creation can look ahead at dependencies.\n            self._propagate_deps(node, visible_if)\n\n            # Finalize the children\n            cur = node.list\n            while cur:\n                self._finalize_node(cur, visible_if)\n                cur = cur.next\n\n        if node.list:\n            # node's children have been individually finalized. Do final steps\n            # to finalize this \"level\" in the menu tree.\n            _flatten(node.list)\n            _remove_ifs(node)\n\n        # Empty choices (node.list None) are possible, so this needs to go\n        # outside\n        if node.item.__class__ is Choice:\n            # Add the node's non-node-specific properties to the choice, like\n            # _add_props_to_sym() does\n            choice = node.item\n            choice.direct_dep = self._make_or(choice.direct_dep, node.dep)\n            choice.defaults += node.defaults\n\n            _finalize_choice(node)\n\n    def _propagate_deps(self, node, visible_if):\n        # Propagates 'node's dependencies to its child menu nodes\n\n        # If the parent node holds a Choice, we use the Choice itself as the\n        # parent dependency. This makes sense as the value (mode) of the choice\n        # limits the visibility of the contained choice symbols. The C\n        # implementation works the same way.\n        #\n        # Due to the similar interface, Choice works as a drop-in replacement\n        # for Symbol here.\n        basedep = node.item if node.item.__class__ is Choice else node.dep\n\n        cur = node.list\n        while cur:\n            dep = cur.dep = self._make_and(cur.dep, basedep)\n\n            if cur.item.__class__ in _SYMBOL_CHOICE:\n                # Propagate 'visible if' and dependencies to the prompt\n                if cur.prompt:\n                    cur.prompt = (cur.prompt[0],\n                                  self._make_and(\n                                      cur.prompt[1],\n                                      self._make_and(visible_if, dep)))\n\n                # Propagate dependencies to defaults\n                if cur.defaults:\n                    cur.defaults = [(default, self._make_and(cond, dep))\n                                    for default, cond in cur.defaults]\n\n                # Propagate dependencies to ranges\n                if cur.ranges:\n                    cur.ranges = [(low, high, self._make_and(cond, dep))\n                                  for low, high, cond in cur.ranges]\n\n                # Propagate dependencies to selects\n                if cur.selects:\n                    cur.selects = [(target, self._make_and(cond, dep))\n                                   for target, cond in cur.selects]\n\n                # Propagate dependencies to implies\n                if cur.implies:\n                    cur.implies = [(target, self._make_and(cond, dep))\n                                   for target, cond in cur.implies]\n\n            elif cur.prompt:  # Not a symbol/choice\n                # Propagate dependencies to the prompt. 'visible if' is only\n                # propagated to symbols/choices.\n                cur.prompt = (cur.prompt[0],\n                              self._make_and(cur.prompt[1], dep))\n\n            cur = cur.next\n\n    def _add_props_to_sym(self, node):\n        # Copies properties from the menu node 'node' up to its contained\n        # symbol, and adds (weak) reverse dependencies to selected/implied\n        # symbols.\n        #\n        # This can't be rolled into _propagate_deps(), because that function\n        # traverses the menu tree roughly breadth-first, meaning properties on\n        # symbols defined in multiple locations could end up in the wrong\n        # order.\n\n        sym = node.item\n\n        # See the Symbol class docstring\n        sym.direct_dep = self._make_or(sym.direct_dep, node.dep)\n\n        sym.defaults += node.defaults\n        sym.ranges += node.ranges\n        sym.selects += node.selects\n        sym.implies += node.implies\n\n        # Modify the reverse dependencies of the selected symbol\n        for target, cond in node.selects:\n            target.rev_dep = self._make_or(\n                target.rev_dep,\n                self._make_and(sym, cond))\n\n        # Modify the weak reverse dependencies of the implied\n        # symbol\n        for target, cond in node.implies:\n            target.weak_rev_dep = self._make_or(\n                target.weak_rev_dep,\n                self._make_and(sym, cond))\n\n    #\n    # Misc.\n    #\n\n    def _check_sym_sanity(self):\n        # Checks various symbol properties that are handiest to check after\n        # parsing. Only generates errors and warnings.\n\n        def num_ok(sym, type_):\n            # Returns True if the (possibly constant) symbol 'sym' is valid as a value\n            # for a symbol of type type_ (INT or HEX)\n\n            # 'not sym.nodes' implies a constant or undefined symbol, e.g. a plain\n            # \"123\"\n            if not sym.nodes:\n                return _is_base_n(sym.name, _TYPE_TO_BASE[type_])\n\n            return sym.orig_type is type_\n\n        for sym in self.unique_defined_syms:\n            if sym.orig_type in _BOOL_TRISTATE:\n                # A helper function could be factored out here, but keep it\n                # speedy/straightforward\n\n                for target_sym, _ in sym.selects:\n                    if target_sym.orig_type not in _BOOL_TRISTATE_UNKNOWN:\n                        self._warn(\"{} selects the {} symbol {}, which is not \"\n                                   \"bool or tristate\"\n                                   .format(sym.name_and_loc,\n                                           TYPE_TO_STR[target_sym.orig_type],\n                                           target_sym.name_and_loc))\n\n                for target_sym, _ in sym.implies:\n                    if target_sym.orig_type not in _BOOL_TRISTATE_UNKNOWN:\n                        self._warn(\"{} implies the {} symbol {}, which is not \"\n                                   \"bool or tristate\"\n                                   .format(sym.name_and_loc,\n                                           TYPE_TO_STR[target_sym.orig_type],\n                                           target_sym.name_and_loc))\n\n            elif sym.orig_type:  # STRING/INT/HEX\n                for default, _ in sym.defaults:\n                    if default.__class__ is not Symbol:\n                        raise KconfigError(\n                            \"the {} symbol {} has a malformed default {} -- \"\n                            \"expected a single symbol\"\n                            .format(TYPE_TO_STR[sym.orig_type],\n                                    sym.name_and_loc, expr_str(default)))\n\n                    if sym.orig_type is STRING:\n                        if not default.is_constant and not default.nodes and \\\n                           not default.name.isupper():\n                            # 'default foo' on a string symbol could be either a symbol\n                            # reference or someone leaving out the quotes. Guess that\n                            # the quotes were left out if 'foo' isn't all-uppercase\n                            # (and no symbol named 'foo' exists).\n                            self._warn(\"style: quotes recommended around \"\n                                       \"default value for string symbol \"\n                                       + sym.name_and_loc)\n\n                    elif not num_ok(default, sym.orig_type):  # INT/HEX\n                        self._warn(\"the {0} symbol {1} has a non-{0} default {2}\"\n                                   .format(TYPE_TO_STR[sym.orig_type],\n                                           sym.name_and_loc,\n                                           default.name_and_loc))\n\n                if sym.selects or sym.implies:\n                    self._warn(\"the {} symbol {} has selects or implies\"\n                               .format(TYPE_TO_STR[sym.orig_type],\n                                       sym.name_and_loc))\n\n            else:  # UNKNOWN\n                self._warn(\"{} defined without a type\"\n                           .format(sym.name_and_loc))\n\n\n            if sym.ranges:\n                if sym.orig_type not in _INT_HEX:\n                    self._warn(\n                        \"the {} symbol {} has ranges, but is not int or hex\"\n                        .format(TYPE_TO_STR[sym.orig_type],\n                                sym.name_and_loc))\n                else:\n                    for low, high, _ in sym.ranges:\n                        if not num_ok(low, sym.orig_type) or \\\n                           not num_ok(high, sym.orig_type):\n\n                            self._warn(\"the {0} symbol {1} has a non-{0} \"\n                                       \"range [{2}, {3}]\"\n                                       .format(TYPE_TO_STR[sym.orig_type],\n                                               sym.name_and_loc,\n                                               low.name_and_loc,\n                                               high.name_and_loc))\n\n    def _check_choice_sanity(self):\n        # Checks various choice properties that are handiest to check after\n        # parsing. Only generates errors and warnings.\n\n        def warn_select_imply(sym, expr, expr_type):\n            msg = \"the choice symbol {} is {} by the following symbols, but \" \\\n                  \"select/imply has no effect on choice symbols\" \\\n                  .format(sym.name_and_loc, expr_type)\n\n            # si = select/imply\n            for si in split_expr(expr, OR):\n                msg += \"\\n - \" + split_expr(si, AND)[0].name_and_loc\n\n            self._warn(msg)\n\n        for choice in self.unique_choices:\n            if choice.orig_type not in _BOOL_TRISTATE:\n                self._warn(\"{} defined with type {}\"\n                           .format(choice.name_and_loc,\n                                   TYPE_TO_STR[choice.orig_type]))\n\n            for node in choice.nodes:\n                if node.prompt:\n                    break\n            else:\n                self._warn(choice.name_and_loc + \" defined without a prompt\")\n\n            for default, _ in choice.defaults:\n                if default.__class__ is not Symbol:\n                    raise KconfigError(\n                        \"{} has a malformed default {}\"\n                        .format(choice.name_and_loc, expr_str(default)))\n\n                if default.choice is not choice:\n                    self._warn(\"the default selection {} of {} is not \"\n                               \"contained in the choice\"\n                               .format(default.name_and_loc,\n                                       choice.name_and_loc))\n\n            for sym in choice.syms:\n                if sym.defaults:\n                    self._warn(\"default on the choice symbol {} will have \"\n                               \"no effect, as defaults do not affect choice \"\n                               \"symbols\".format(sym.name_and_loc))\n\n                if sym.rev_dep is not sym.kconfig.n:\n                    warn_select_imply(sym, sym.rev_dep, \"selected\")\n\n                if sym.weak_rev_dep is not sym.kconfig.n:\n                    warn_select_imply(sym, sym.weak_rev_dep, \"implied\")\n\n                for node in sym.nodes:\n                    if node.parent.item is choice:\n                        if not node.prompt:\n                            self._warn(\"the choice symbol {} has no prompt\"\n                                       .format(sym.name_and_loc))\n\n                    elif node.prompt:\n                        self._warn(\"the choice symbol {} is defined with a \"\n                                   \"prompt outside the choice\"\n                                   .format(sym.name_and_loc))\n\n    def _parse_error(self, msg):\n        raise KconfigError(\"{}error: couldn't parse '{}': {}\".format(\n            \"\" if self.filename is None else\n                \"{}:{}: \".format(self.filename, self.linenr),\n            self._line.strip(), msg))\n\n    def _trailing_tokens_error(self):\n        self._parse_error(\"extra tokens at end of line\")\n\n    def _open(self, filename, mode):\n        # open() wrapper:\n        #\n        # - Enable universal newlines mode on Python 2 to ease\n        #   interoperability between Linux and Windows. It's already the\n        #   default on Python 3.\n        #\n        #   The \"U\" flag would currently work for both Python 2 and 3, but it's\n        #   deprecated on Python 3, so play it future-safe.\n        #\n        #   io.open() defaults to universal newlines on Python 2 (and is an\n        #   alias for open() on Python 3), but it returns 'unicode' strings and\n        #   slows things down:\n        #\n        #     Parsing x86 Kconfigs on Python 2\n        #\n        #     with open(..., \"rU\"):\n        #\n        #       real  0m0.930s\n        #       user  0m0.905s\n        #       sys   0m0.025s\n        #\n        #     with io.open():\n        #\n        #       real  0m1.069s\n        #       user  0m1.040s\n        #       sys   0m0.029s\n        #\n        #   There's no appreciable performance difference between \"r\" and\n        #   \"rU\" for parsing performance on Python 2.\n        #\n        # - For Python 3, force the encoding. Forcing the encoding on Python 2\n        #   turns strings into Unicode strings, which gets messy. Python 2\n        #   doesn't decode regular strings anyway.\n        return open(filename, \"rU\" if mode == \"r\" else mode) if _IS_PY2 else \\\n               open(filename, mode, encoding=self._encoding)\n\n    def _check_undef_syms(self):\n        # Prints warnings for all references to undefined symbols within the\n        # Kconfig files\n\n        def is_num(s):\n            # Returns True if the string 's' looks like a number.\n            #\n            # Internally, all operands in Kconfig are symbols, only undefined symbols\n            # (which numbers usually are) get their name as their value.\n            #\n            # Only hex numbers that start with 0x/0X are classified as numbers.\n            # Otherwise, symbols whose names happen to contain only the letters A-F\n            # would trigger false positives.\n\n            try:\n                int(s)\n            except ValueError:\n                if not s.startswith((\"0x\", \"0X\")):\n                    return False\n\n                try:\n                    int(s, 16)\n                except ValueError:\n                    return False\n\n            return True\n\n        for sym in (self.syms.viewvalues if _IS_PY2 else self.syms.values)():\n            # - sym.nodes empty means the symbol is undefined (has no\n            #   definition locations)\n            #\n            # - Due to Kconfig internals, numbers show up as undefined Kconfig\n            #   symbols, but shouldn't be flagged\n            #\n            # - The MODULES symbol always exists\n            if not sym.nodes and not is_num(sym.name) and \\\n               sym.name != \"MODULES\":\n\n                msg = \"undefined symbol {}:\".format(sym.name)\n                for node in self.node_iter():\n                    if sym in node.referenced:\n                        msg += \"\\n\\n- Referenced at {}:{}:\\n\\n{}\" \\\n                               .format(node.filename, node.linenr, node)\n                self._warn(msg)\n\n    def _warn(self, msg, filename=None, linenr=None):\n        # For printing general warnings\n\n        if not self.warn:\n            return\n\n        msg = \"warning: \" + msg\n        if filename is not None:\n            msg = \"{}:{}: {}\".format(filename, linenr, msg)\n\n        self.warnings.append(msg)\n        if self.warn_to_stderr:\n            sys.stderr.write(msg + \"\\n\")\n\n\nclass Symbol(object):\n    \"\"\"\n    Represents a configuration symbol:\n\n      (menu)config FOO\n          ...\n\n    The following attributes are available. They should be viewed as read-only,\n    and some are implemented through @property magic (but are still efficient\n    to access due to internal caching).\n\n    Note: Prompts, help texts, and locations are stored in the Symbol's\n    MenuNode(s) rather than in the Symbol itself. Check the MenuNode class and\n    the Symbol.nodes attribute. This organization matches the C tools.\n\n    name:\n      The name of the symbol, e.g. \"FOO\" for 'config FOO'.\n\n    type:\n      The type of the symbol. One of BOOL, TRISTATE, STRING, INT, HEX, UNKNOWN.\n      UNKNOWN is for undefined symbols, (non-special) constant symbols, and\n      symbols defined without a type.\n\n      When running without modules (MODULES having the value n), TRISTATE\n      symbols magically change type to BOOL. This also happens for symbols\n      within choices in \"y\" mode. This matches the C tools, and makes sense for\n      menuconfig-like functionality.\n\n    orig_type:\n      The type as given in the Kconfig file, without any magic applied. Used\n      when printing the symbol.\n\n    tri_value:\n      The tristate value of the symbol as an integer. One of 0, 1, 2,\n      representing n, m, y. Always 0 (n) for non-bool/tristate symbols.\n\n      This is the symbol value that's used outside of relation expressions\n      (A, !A, A && B, A || B).\n\n    str_value:\n      The value of the symbol as a string. Gives the value for string/int/hex\n      symbols. For bool/tristate symbols, gives \"n\", \"m\", or \"y\".\n\n      This is the symbol value that's used in relational expressions\n      (A = B, A != B, etc.)\n\n      Gotcha: For int/hex symbols, the exact format of the value is often\n      preserved (e.g. when writing a .config file), hence why you can't get it\n      directly as an int. Do int(int_sym.str_value) or\n      int(hex_sym.str_value, 16) to get the integer value.\n\n    user_value:\n      The user value of the symbol. None if no user value has been assigned\n      (via Kconfig.load_config() or Symbol.set_value()).\n\n      Holds 0, 1, or 2 for bool/tristate symbols, and a string for the other\n      symbol types.\n\n      WARNING: Do not assign directly to this. It will break things. Use\n      Symbol.set_value().\n\n    assignable:\n      A tuple containing the tristate user values that can currently be\n      assigned to the symbol (that would be respected), ordered from lowest (0,\n      representing n) to highest (2, representing y). This corresponds to the\n      selections available in the menuconfig interface. The set of assignable\n      values is calculated from the symbol's visibility and selects/implies.\n\n      Returns the empty set for non-bool/tristate symbols and for symbols with\n      visibility n. The other possible values are (0, 2), (0, 1, 2), (1, 2),\n      (1,), and (2,). A (1,) or (2,) result means the symbol is visible but\n      \"locked\" to m or y through a select, perhaps in combination with the\n      visibility. menuconfig represents this as -M- and -*-, respectively.\n\n      For string/hex/int symbols, check if Symbol.visibility is non-0 (non-n)\n      instead to determine if the value can be changed.\n\n      Some handy 'assignable' idioms:\n\n        # Is 'sym' an assignable (visible) bool/tristate symbol?\n        if sym.assignable:\n            # What's the highest value it can be assigned? [-1] in Python\n            # gives the last element.\n            sym_high = sym.assignable[-1]\n\n            # The lowest?\n            sym_low = sym.assignable[0]\n\n            # Can the symbol be set to at least m?\n            if sym.assignable[-1] >= 1:\n                ...\n\n        # Can the symbol be set to m?\n        if 1 in sym.assignable:\n            ...\n\n    visibility:\n      The visibility of the symbol. One of 0, 1, 2, representing n, m, y. See\n      the module documentation for an overview of symbol values and visibility.\n\n    config_string:\n      The .config assignment string that would get written out for the symbol\n      by Kconfig.write_config(). Returns the empty string if no .config\n      assignment would get written out.\n\n      In general, visible symbols, symbols with (active) defaults, and selected\n      symbols get written out. This includes all non-n-valued bool/tristate\n      symbols, and all visible string/int/hex symbols.\n\n      Symbols with the (no longer needed) 'option env=...' option generate no\n      configuration output, and neither does the special\n      'option defconfig_list' symbol.\n\n      Tip: This field is useful when generating custom configuration output,\n      even for non-.config-like formats. To write just the symbols that would\n      get written out to .config files, do this:\n\n        if sym.config_string:\n            *Write symbol, e.g. by looking sym.str_value*\n\n      This is a superset of the symbols written out by write_autoconf().\n      That function skips all n-valued symbols.\n\n      There usually won't be any great harm in just writing all symbols either,\n      though you might get some special symbols and possibly some \"redundant\"\n      n-valued symbol entries in there.\n\n    name_and_loc:\n      Holds a string like\n\n        \"MY_SYMBOL (defined at foo/Kconfig:12, bar/Kconfig:14)\"\n\n      , giving the name of the symbol and its definition location(s).\n\n      If the symbol is undefined, the location is given as \"(undefined)\".\n\n    nodes:\n      A list of MenuNodes for this symbol. Will contain a single MenuNode for\n      most symbols. Undefined and constant symbols have an empty nodes list.\n      Symbols defined in multiple locations get one node for each location.\n\n    choice:\n      Holds the parent Choice for choice symbols, and None for non-choice\n      symbols. Doubles as a flag for whether a symbol is a choice symbol.\n\n    defaults:\n      List of (default, cond) tuples for the symbol's 'default' properties. For\n      example, 'default A && B if C || D' is represented as\n      ((AND, A, B), (OR, C, D)). If no condition was given, 'cond' is\n      self.kconfig.y.\n\n      Note that 'depends on' and parent dependencies are propagated to\n      'default' conditions.\n\n    selects:\n      List of (symbol, cond) tuples for the symbol's 'select' properties. For\n      example, 'select A if B && C' is represented as (A, (AND, B, C)). If no\n      condition was given, 'cond' is self.kconfig.y.\n\n      Note that 'depends on' and parent dependencies are propagated to 'select'\n      conditions.\n\n    implies:\n      Like 'selects', for imply.\n\n    ranges:\n      List of (low, high, cond) tuples for the symbol's 'range' properties. For\n      example, 'range 1 2 if A' is represented as (1, 2, A). If there is no\n      condition, 'cond' is self.kconfig.y.\n\n      Note that 'depends on' and parent dependencies are propagated to 'range'\n      conditions.\n\n      Gotcha: 1 and 2 above will be represented as (undefined) Symbols rather\n      than plain integers. Undefined symbols get their name as their string\n      value, so this works out. The C tools work the same way.\n\n    orig_defaults:\n    orig_selects:\n    orig_implies:\n    orig_ranges:\n      See the corresponding attributes on the MenuNode class.\n\n    rev_dep:\n      Reverse dependency expression from other symbols selecting this symbol.\n      Multiple selections get ORed together. A condition on a select is ANDed\n      with the selecting symbol.\n\n      For example, if A has 'select FOO' and B has 'select FOO if C', then\n      FOO's rev_dep will be (OR, A, (AND, B, C)).\n\n    weak_rev_dep:\n      Like rev_dep, for imply.\n\n    direct_dep:\n      The direct ('depends on') dependencies for the symbol, or self.kconfig.y\n      if there are no direct dependencies.\n\n      This attribute includes any dependencies from surrounding menus and ifs.\n      Those get propagated to the direct dependencies, and the resulting direct\n      dependencies in turn get propagated to the conditions of all properties.\n\n      If the symbol is defined in multiple locations, the dependencies from the\n      different locations get ORed together.\n\n    referenced:\n      A set() with all symbols and choices referenced in the properties and\n      property conditions of the symbol.\n\n      Also includes dependencies from surrounding menus and ifs, because those\n      get propagated to the symbol (see the 'Intro to symbol values' section in\n      the module docstring).\n\n      Choices appear in the dependencies of choice symbols.\n\n      For the following definitions, only B and not C appears in A's\n      'referenced'. To get transitive references, you'll have to recursively\n      expand 'references' until no new items appear.\n\n        config A\n                bool\n                depends on B\n\n        config B\n                bool\n                depends on C\n\n        config C\n                bool\n\n      See the Symbol.direct_dep attribute if you're only interested in the\n      direct dependencies of the symbol (its 'depends on'). You can extract the\n      symbols in it with the global expr_items() function.\n\n    env_var:\n      If the Symbol has an 'option env=\"FOO\"' option, this contains the name\n      (\"FOO\") of the environment variable. None for symbols without no\n      'option env'.\n\n      'option env=\"FOO\"' acts like a 'default' property whose value is the\n      value of $FOO.\n\n      Symbols with 'option env' are never written out to .config files, even if\n      they are visible. env_var corresponds to a flag called SYMBOL_AUTO in the\n      C implementation.\n\n    is_allnoconfig_y:\n      True if the symbol has 'option allnoconfig_y' set on it. This has no\n      effect internally (except when printing symbols), but can be checked by\n      scripts.\n\n    is_constant:\n      True if the symbol is a constant (quoted) symbol.\n\n    kconfig:\n      The Kconfig instance this symbol is from.\n    \"\"\"\n    __slots__ = (\n        \"_cached_assignable\",\n        \"_cached_str_val\",\n        \"_cached_tri_val\",\n        \"_cached_vis\",\n        \"_dependents\",\n        \"_old_val\",\n        \"_visited\",\n        \"_was_set\",\n        \"_write_to_conf\",\n        \"choice\",\n        \"defaults\",\n        \"direct_dep\",\n        \"env_var\",\n        \"implies\",\n        \"is_allnoconfig_y\",\n        \"is_constant\",\n        \"kconfig\",\n        \"name\",\n        \"nodes\",\n        \"orig_type\",\n        \"ranges\",\n        \"rev_dep\",\n        \"selects\",\n        \"user_value\",\n        \"weak_rev_dep\",\n    )\n\n    #\n    # Public interface\n    #\n\n    @property\n    def type(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        if self.orig_type is TRISTATE and \\\n           (self.choice and self.choice.tri_value == 2 or\n            not self.kconfig.modules.tri_value):\n\n            return BOOL\n\n        return self.orig_type\n\n    @property\n    def str_value(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        if self._cached_str_val is not None:\n            return self._cached_str_val\n\n        if self.orig_type in _BOOL_TRISTATE:\n            # Also calculates the visibility, so invalidation safe\n            self._cached_str_val = TRI_TO_STR[self.tri_value]\n            return self._cached_str_val\n\n        # As a quirk of Kconfig, undefined symbols get their name as their\n        # string value. This is why things like \"FOO = bar\" work for seeing if\n        # FOO has the value \"bar\".\n        if not self.orig_type:  # UNKNOWN\n            self._cached_str_val = self.name\n            return self.name\n\n        val = \"\"\n        # Warning: See Symbol._rec_invalidate(), and note that this is a hidden\n        # function call (property magic)\n        vis = self.visibility\n\n        self._write_to_conf = (vis != 0)\n\n        if self.orig_type in _INT_HEX:\n            # The C implementation checks the user value against the range in a\n            # separate code path (post-processing after loading a .config).\n            # Checking all values here instead makes more sense for us. It\n            # requires that we check for a range first.\n\n            base = _TYPE_TO_BASE[self.orig_type]\n\n            # Check if a range is in effect\n            for low_expr, high_expr, cond in self.ranges:\n                if expr_value(cond):\n                    has_active_range = True\n\n                    # The zeros are from the C implementation running strtoll()\n                    # on empty strings\n                    low = int(low_expr.str_value, base) if \\\n                      _is_base_n(low_expr.str_value, base) else 0\n                    high = int(high_expr.str_value, base) if \\\n                      _is_base_n(high_expr.str_value, base) else 0\n\n                    break\n            else:\n                has_active_range = False\n\n            # Defaults are used if the symbol is invisible, lacks a user value,\n            # or has an out-of-range user value\n            use_defaults = True\n\n            if vis and self.user_value:\n                user_val = int(self.user_value, base)\n                if has_active_range and not low <= user_val <= high:\n                    num2str = str if base == 10 else hex\n                    self.kconfig._warn(\n                        \"user value {} on the {} symbol {} ignored due to \"\n                        \"being outside the active range ([{}, {}]) -- falling \"\n                        \"back on defaults\"\n                        .format(num2str(user_val), TYPE_TO_STR[self.orig_type],\n                                self.name_and_loc,\n                                num2str(low), num2str(high)))\n                else:\n                    # If the user value is well-formed and satisfies range\n                    # contraints, it is stored in exactly the same form as\n                    # specified in the assignment (with or without \"0x\", etc.)\n                    val = self.user_value\n                    use_defaults = False\n\n            if use_defaults:\n                # No user value or invalid user value. Look at defaults.\n\n                # Used to implement the warning below\n                has_default = False\n\n                for sym, cond in self.defaults:\n                    if expr_value(cond):\n                        has_default = self._write_to_conf = True\n\n                        val = sym.str_value\n\n                        if _is_base_n(val, base):\n                            val_num = int(val, base)\n                        else:\n                            val_num = 0  # strtoll() on empty string\n\n                        break\n                else:\n                    val_num = 0  # strtoll() on empty string\n\n                # This clamping procedure runs even if there's no default\n                if has_active_range:\n                    clamp = None\n                    if val_num < low:\n                        clamp = low\n                    elif val_num > high:\n                        clamp = high\n\n                    if clamp is not None:\n                        # The value is rewritten to a standard form if it is\n                        # clamped\n                        val = str(clamp) \\\n                              if self.orig_type is INT else \\\n                              hex(clamp)\n\n                        if has_default:\n                            num2str = str if base == 10 else hex\n                            self.kconfig._warn(\n                                \"default value {} on {} clamped to {} due to \"\n                                \"being outside the active range ([{}, {}])\"\n                                .format(val_num, self.name_and_loc,\n                                        num2str(clamp), num2str(low),\n                                        num2str(high)))\n\n        elif self.orig_type is STRING:\n            if vis and self.user_value is not None:\n                # If the symbol is visible and has a user value, use that\n                val = self.user_value\n            else:\n                # Otherwise, look at defaults\n                for sym, cond in self.defaults:\n                    if expr_value(cond):\n                        val = sym.str_value\n                        self._write_to_conf = True\n                        break\n\n        # env_var corresponds to SYMBOL_AUTO in the C implementation, and is\n        # also set on the defconfig_list symbol there. Test for the\n        # defconfig_list symbol explicitly instead here, to avoid a nonsensical\n        # env_var setting and the defconfig_list symbol being printed\n        # incorrectly. This code is pretty cold anyway.\n        if self.env_var is not None or self is self.kconfig.defconfig_list:\n            self._write_to_conf = False\n\n        self._cached_str_val = val\n        return val\n\n    @property\n    def tri_value(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        if self._cached_tri_val is not None:\n            return self._cached_tri_val\n\n        if self.orig_type not in _BOOL_TRISTATE:\n            if self.orig_type:  # != UNKNOWN\n                # Would take some work to give the location here\n                self.kconfig._warn(\n                    \"The {} symbol {} is being evaluated in a logical context \"\n                    \"somewhere. It will always evaluate to n.\"\n                    .format(TYPE_TO_STR[self.orig_type], self.name_and_loc))\n\n            self._cached_tri_val = 0\n            return 0\n\n        # Warning: See Symbol._rec_invalidate(), and note that this is a hidden\n        # function call (property magic)\n        vis = self.visibility\n        self._write_to_conf = (vis != 0)\n\n        val = 0\n\n        if not self.choice:\n            # Non-choice symbol\n\n            if vis and self.user_value is not None:\n                # If the symbol is visible and has a user value, use that\n                val = min(self.user_value, vis)\n\n            else:\n                # Otherwise, look at defaults and weak reverse dependencies\n                # (implies)\n\n                for default, cond in self.defaults:\n                    dep_val = expr_value(cond)\n                    if dep_val:\n                        val = min(expr_value(default), dep_val)\n                        if val:\n                            self._write_to_conf = True\n                        break\n\n                # Weak reverse dependencies are only considered if our\n                # direct dependencies are met\n                dep_val = expr_value(self.weak_rev_dep)\n                if dep_val and expr_value(self.direct_dep):\n                    val = max(dep_val, val)\n                    self._write_to_conf = True\n\n            # Reverse (select-related) dependencies take precedence\n            dep_val = expr_value(self.rev_dep)\n            if dep_val:\n                if expr_value(self.direct_dep) < dep_val:\n                    self._warn_select_unsatisfied_deps()\n\n                val = max(dep_val, val)\n                self._write_to_conf = True\n\n            # m is promoted to y for (1) bool symbols and (2) symbols with a\n            # weak_rev_dep (from imply) of y\n            if val == 1 and \\\n               (self.type is BOOL or expr_value(self.weak_rev_dep) == 2):\n                val = 2\n\n        elif vis == 2:\n            # Visible choice symbol in y-mode choice. The choice mode limits\n            # the visibility of choice symbols, so it's sufficient to just\n            # check the visibility of the choice symbols themselves.\n            val = 2 if self.choice.selection is self else 0\n\n        elif vis and self.user_value:\n            # Visible choice symbol in m-mode choice, with set non-0 user value\n            val = 1\n\n        self._cached_tri_val = val\n        return val\n\n    @property\n    def assignable(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        if self._cached_assignable is None:\n            self._cached_assignable = self._assignable()\n        return self._cached_assignable\n\n    @property\n    def visibility(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        if self._cached_vis is None:\n            self._cached_vis = _visibility(self)\n        return self._cached_vis\n\n    @property\n    def config_string(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        # _write_to_conf is determined when the value is calculated. This is a\n        # hidden function call due to property magic.\n        val = self.str_value\n        if not self._write_to_conf:\n            return \"\"\n\n        if self.orig_type in _BOOL_TRISTATE:\n            return \"{}{}={}\\n\" \\\n                   .format(self.kconfig.config_prefix, self.name, val) \\\n                   if val != \"n\" else \\\n                   \"# {}{} is not set\\n\" \\\n                   .format(self.kconfig.config_prefix, self.name)\n\n        if self.orig_type in _INT_HEX:\n            return \"{}{}={}\\n\" \\\n                   .format(self.kconfig.config_prefix, self.name, val)\n\n        # sym.orig_type is STRING\n        return '{}{}=\"{}\"\\n' \\\n               .format(self.kconfig.config_prefix, self.name, escape(val))\n\n    @property\n    def name_and_loc(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        return self.name + \" \" + _locs(self)\n\n    def set_value(self, value):\n        \"\"\"\n        Sets the user value of the symbol.\n\n        Equal in effect to assigning the value to the symbol within a .config\n        file. For bool and tristate symbols, use the 'assignable' attribute to\n        check which values can currently be assigned. Setting values outside\n        'assignable' will cause Symbol.user_value to differ from\n        Symbol.str/tri_value (be truncated down or up).\n\n        Setting a choice symbol to 2 (y) sets Choice.user_selection to the\n        choice symbol in addition to setting Symbol.user_value.\n        Choice.user_selection is considered when the choice is in y mode (the\n        \"normal\" mode).\n\n        Other symbols that depend (possibly indirectly) on this symbol are\n        automatically recalculated to reflect the assigned value.\n\n        value:\n          The user value to give to the symbol. For bool and tristate symbols,\n          n/m/y can be specified either as 0/1/2 (the usual format for tristate\n          values in Kconfiglib) or as one of the strings \"n\", \"m\", or \"y\". For\n          other symbol types, pass a string.\n\n          Note that the value for an int/hex symbol is passed as a string, e.g.\n          \"123\" or \"0x0123\". The format of this string is preserved in the\n          output.\n\n          Values that are invalid for the type (such as \"foo\" or 1 (m) for a\n          BOOL or \"0x123\" for an INT) are ignored and won't be stored in\n          Symbol.user_value. Kconfiglib will print a warning by default for\n          invalid assignments, and set_value() will return False.\n\n        Returns True if the value is valid for the type of the symbol, and\n        False otherwise. This only looks at the form of the value. For BOOL and\n        TRISTATE symbols, check the Symbol.assignable attribute to see what\n        values are currently in range and would actually be reflected in the\n        value of the symbol. For other symbol types, check whether the\n        visibility is non-n.\n        \"\"\"\n        if self.orig_type in _BOOL_TRISTATE and value in STR_TO_TRI:\n            value = STR_TO_TRI[value]\n\n        # If the new user value matches the old, nothing changes, and we can\n        # avoid invalidating cached values.\n        #\n        # This optimization is skipped for choice symbols: Setting a choice\n        # symbol's user value to y might change the state of the choice, so it\n        # wouldn't be safe (symbol user values always match the values set in a\n        # .config file or via set_value(), and are never implicitly updated).\n        if value == self.user_value and not self.choice:\n            self._was_set = True\n            return True\n\n        # Check if the value is valid for our type\n        if not (self.orig_type is BOOL     and value in (2, 0)     or\n                self.orig_type is TRISTATE and value in TRI_TO_STR or\n                value.__class__ is str and\n                (self.orig_type is STRING                        or\n                 self.orig_type is INT and _is_base_n(value, 10) or\n                 self.orig_type is HEX and _is_base_n(value, 16)\n                                       and int(value, 16) >= 0)):\n\n            # Display tristate values as n, m, y in the warning\n            self.kconfig._warn(\n                \"the value {} is invalid for {}, which has type {} -- \"\n                \"assignment ignored\"\n                .format(TRI_TO_STR[value] if value in TRI_TO_STR else\n                            \"'{}'\".format(value),\n                        self.name_and_loc, TYPE_TO_STR[self.orig_type]))\n\n            return False\n\n        self.user_value = value\n        self._was_set = True\n\n        if self.choice and value == 2:\n            # Setting a choice symbol to y makes it the user selection of the\n            # choice. Like for symbol user values, the user selection is not\n            # guaranteed to match the actual selection of the choice, as\n            # dependencies come into play.\n            self.choice.user_selection = self\n            self.choice._was_set = True\n            self.choice._rec_invalidate()\n        else:\n            self._rec_invalidate_if_has_prompt()\n\n        return True\n\n    def unset_value(self):\n        \"\"\"\n        Removes any user value from the symbol, as if the symbol had never\n        gotten a user value via Kconfig.load_config() or Symbol.set_value().\n        \"\"\"\n        if self.user_value is not None:\n            self.user_value = None\n            self._rec_invalidate_if_has_prompt()\n\n    @property\n    def referenced(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        return {item for node in self.nodes for item in node.referenced}\n\n    @property\n    def orig_defaults(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        return [d for node in self.nodes for d in node.orig_defaults]\n\n    @property\n    def orig_selects(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        return [s for node in self.nodes for s in node.orig_selects]\n\n    @property\n    def orig_implies(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        return [i for node in self.nodes for i in node.orig_implies]\n\n    @property\n    def orig_ranges(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        return [r for node in self.nodes for r in node.orig_ranges]\n\n    def __repr__(self):\n        \"\"\"\n        Returns a string with information about the symbol (including its name,\n        value, visibility, and location(s)) when it is evaluated on e.g. the\n        interactive Python prompt.\n        \"\"\"\n        fields = [\"symbol \" + self.name, TYPE_TO_STR[self.type]]\n        add = fields.append\n\n        for node in self.nodes:\n            if node.prompt:\n                add('\"{}\"'.format(node.prompt[0]))\n\n        # Only add quotes for non-bool/tristate symbols\n        add(\"value \" + (self.str_value if self.orig_type in _BOOL_TRISTATE\n                        else '\"{}\"'.format(self.str_value)))\n\n        if not self.is_constant:\n            # These aren't helpful to show for constant symbols\n\n            if self.user_value is not None:\n                # Only add quotes for non-bool/tristate symbols\n                add(\"user value \" + (TRI_TO_STR[self.user_value]\n                                     if self.orig_type in _BOOL_TRISTATE\n                                     else '\"{}\"'.format(self.user_value)))\n\n            add(\"visibility \" + TRI_TO_STR[self.visibility])\n\n            if self.choice:\n                add(\"choice symbol\")\n\n            if self.is_allnoconfig_y:\n                add(\"allnoconfig_y\")\n\n            if self is self.kconfig.defconfig_list:\n                add(\"is the defconfig_list symbol\")\n\n            if self.env_var is not None:\n                add(\"from environment variable \" + self.env_var)\n\n            if self is self.kconfig.modules:\n                add(\"is the modules symbol\")\n\n            add(\"direct deps \" + TRI_TO_STR[expr_value(self.direct_dep)])\n\n        if self.nodes:\n            for node in self.nodes:\n                add(\"{}:{}\".format(node.filename, node.linenr))\n        else:\n            add(\"constant\" if self.is_constant else \"undefined\")\n\n        return \"<{}>\".format(\", \".join(fields))\n\n    def __str__(self):\n        \"\"\"\n        Returns a string representation of the symbol when it is printed.\n        Matches the Kconfig format, with any parent dependencies propagated to\n        the 'depends on' condition.\n\n        The string is constructed by joining the strings returned by\n        MenuNode.__str__() for each of the symbol's menu nodes, so symbols\n        defined in multiple locations will return a string with all\n        definitions.\n\n        The returned string does not end in a newline. An empty string is\n        returned for undefined and constant symbols.\n        \"\"\"\n        return self.custom_str(standard_sc_expr_str)\n\n    def custom_str(self, sc_expr_str_fn):\n        \"\"\"\n        Works like Symbol.__str__(), but allows a custom format to be used for\n        all symbol/choice references. See expr_str().\n        \"\"\"\n        return \"\\n\\n\".join(node.custom_str(sc_expr_str_fn)\n                           for node in self.nodes)\n\n    #\n    # Private methods\n    #\n\n    def __init__(self):\n        \"\"\"\n        Symbol constructor -- not intended to be called directly by Kconfiglib\n        clients.\n        \"\"\"\n        # These attributes are always set on the instance from outside and\n        # don't need defaults:\n        #   kconfig\n        #   direct_dep\n        #   is_constant\n        #   name\n        #   rev_dep\n        #   weak_rev_dep\n\n        # - UNKNOWN == 0\n        # - _visited is used during tree iteration and dep. loop detection\n        self.orig_type = self._visited = 0\n\n        self.nodes = []\n\n        self.defaults = []\n        self.selects = []\n        self.implies = []\n        self.ranges = []\n\n        self.user_value = \\\n        self.choice = \\\n        self.env_var = \\\n        self._cached_str_val = self._cached_tri_val = self._cached_vis = \\\n        self._cached_assignable = None\n\n        # _write_to_conf is calculated along with the value. If True, the\n        # Symbol gets a .config entry.\n\n        self.is_allnoconfig_y = \\\n        self._was_set = \\\n        self._write_to_conf = False\n\n        # See Kconfig._build_dep()\n        self._dependents = set()\n\n    def _assignable(self):\n        # Worker function for the 'assignable' attribute\n\n        if self.orig_type not in _BOOL_TRISTATE:\n            return ()\n\n        # Warning: See Symbol._rec_invalidate(), and note that this is a hidden\n        # function call (property magic)\n        vis = self.visibility\n        if not vis:\n            return ()\n\n        rev_dep_val = expr_value(self.rev_dep)\n\n        if vis == 2:\n            if self.choice:\n                return (2,)\n\n            if not rev_dep_val:\n                if self.type is BOOL or expr_value(self.weak_rev_dep) == 2:\n                    return (0, 2)\n                return (0, 1, 2)\n\n            if rev_dep_val == 2:\n                return (2,)\n\n            # rev_dep_val == 1\n\n            if self.type is BOOL or expr_value(self.weak_rev_dep) == 2:\n                return (2,)\n            return (1, 2)\n\n        # vis == 1\n\n        # Must be a tristate here, because bool m visibility gets promoted to y\n\n        if not rev_dep_val:\n            return (0, 1) if expr_value(self.weak_rev_dep) != 2 else (0, 2)\n\n        if rev_dep_val == 2:\n            return (2,)\n\n        # vis == rev_dep_val == 1\n\n        return (1,)\n\n    def _invalidate(self):\n        # Marks the symbol as needing to be recalculated\n\n        self._cached_str_val = self._cached_tri_val = self._cached_vis = \\\n        self._cached_assignable = None\n\n    def _rec_invalidate(self):\n        # Invalidates the symbol and all items that (possibly) depend on it\n\n        if self is self.kconfig.modules:\n            # Invalidating MODULES has wide-ranging effects\n            self.kconfig._invalidate_all()\n        else:\n            self._invalidate()\n\n            for item in self._dependents:\n                # _cached_vis doubles as a flag that tells us whether 'item'\n                # has cached values, because it's calculated as a side effect\n                # of calculating all other (non-constant) cached values.\n                #\n                # If item._cached_vis is None, it means there can't be cached\n                # values on other items that depend on 'item', because if there\n                # were, some value on 'item' would have been calculated and\n                # item._cached_vis set as a side effect. It's therefore safe to\n                # stop the invalidation at symbols with _cached_vis None.\n                #\n                # This approach massively speeds up scripts that set a lot of\n                # values, vs simply invalidating all possibly dependent symbols\n                # (even when you already have a list of all the dependent\n                # symbols, because some symbols get huge dependency trees).\n                #\n                # This gracefully handles dependency loops too, which is nice\n                # for choices, where the choice depends on the choice symbols\n                # and vice versa.\n                if item._cached_vis is not None:\n                    item._rec_invalidate()\n\n    def _rec_invalidate_if_has_prompt(self):\n        # Invalidates the symbol and its dependent symbols, but only if the\n        # symbol has a prompt. User values never have an effect on promptless\n        # symbols, so we skip invalidation for them as an optimization.\n        #\n        # This also prevents constant (quoted) symbols from being invalidated\n        # if set_value() is called on them, which would make them lose their\n        # value and break things.\n        #\n        # Prints a warning if the symbol has no prompt. In some contexts (e.g.\n        # when loading a .config files) assignments to promptless symbols are\n        # normal and expected, so the warning can be disabled.\n\n        for node in self.nodes:\n            if node.prompt:\n                self._rec_invalidate()\n                return\n\n        if self.kconfig._warn_assign_no_prompt:\n            self.kconfig._warn(self.name_and_loc + \" has no prompt, meaning \"\n                               \"user values have no effect on it\")\n\n    def _str_default(self):\n        # write_min_config() helper function. Returns the value the symbol\n        # would get from defaults if it didn't have a user value. Uses exactly\n        # the same algorithm as the C implementation (though a bit cleaned up),\n        # for compatibility.\n\n        if self.orig_type in _BOOL_TRISTATE:\n            val = 0\n\n            # Defaults, selects, and implies do not affect choice symbols\n            if not self.choice:\n                for default, cond in self.defaults:\n                    cond_val = expr_value(cond)\n                    if cond_val:\n                        val = min(expr_value(default), cond_val)\n                        break\n\n                val = max(expr_value(self.rev_dep),\n                          expr_value(self.weak_rev_dep),\n                          val)\n\n                # Transpose mod to yes if type is bool (possibly due to modules\n                # being disabled)\n                if val == 1 and self.type is BOOL:\n                    val = 2\n\n            return TRI_TO_STR[val]\n\n        if self.orig_type:  # STRING/INT/HEX\n            for default, cond in self.defaults:\n                if expr_value(cond):\n                    return default.str_value\n\n        return \"\"\n\n    def _warn_select_unsatisfied_deps(self):\n        # Helper for printing an informative warning when a symbol with\n        # unsatisfied direct dependencies (dependencies from 'depends on', ifs,\n        # and menus) is selected by some other symbol. Also warn if a symbol\n        # whose direct dependencies evaluate to m is selected to y.\n\n        msg = \"{} has direct dependencies {} with value {}, but is \" \\\n              \"currently being {}-selected by the following symbols:\" \\\n              .format(self.name_and_loc, expr_str(self.direct_dep),\n                      TRI_TO_STR[expr_value(self.direct_dep)],\n                      TRI_TO_STR[expr_value(self.rev_dep)])\n\n        # The reverse dependencies from each select are ORed together\n        for select in split_expr(self.rev_dep, OR):\n            if expr_value(select) <= expr_value(self.direct_dep):\n                # Only include selects that exceed the direct dependencies\n                continue\n\n            # - 'select A if B' turns into A && B\n            # - 'select A' just turns into A\n            #\n            # In both cases, we can split on AND and pick the first operand\n            selecting_sym = split_expr(select, AND)[0]\n\n            msg += \"\\n - {}, with value {}, direct dependencies {} \" \\\n                   \"(value: {})\" \\\n                   .format(selecting_sym.name_and_loc,\n                           selecting_sym.str_value,\n                           expr_str(selecting_sym.direct_dep),\n                           TRI_TO_STR[expr_value(selecting_sym.direct_dep)])\n\n            if select.__class__ is tuple:\n                msg += \", and select condition {} (value: {})\" \\\n                       .format(expr_str(select[2]),\n                               TRI_TO_STR[expr_value(select[2])])\n\n        self.kconfig._warn(msg)\n\n\nclass Choice(object):\n    \"\"\"\n    Represents a choice statement:\n\n      choice\n          ...\n      endchoice\n\n    The following attributes are available on Choice instances. They should be\n    treated as read-only, and some are implemented through @property magic (but\n    are still efficient to access due to internal caching).\n\n    Note: Prompts, help texts, and locations are stored in the Choice's\n    MenuNode(s) rather than in the Choice itself. Check the MenuNode class and\n    the Choice.nodes attribute. This organization matches the C tools.\n\n    name:\n      The name of the choice, e.g. \"FOO\" for 'choice FOO', or None if the\n      Choice has no name.\n\n    type:\n      The type of the choice. One of BOOL, TRISTATE, UNKNOWN. UNKNOWN is for\n      choices defined without a type where none of the contained symbols have a\n      type either (otherwise the choice inherits the type of the first symbol\n      defined with a type).\n\n      When running without modules (CONFIG_MODULES=n), TRISTATE choices\n      magically change type to BOOL. This matches the C tools, and makes sense\n      for menuconfig-like functionality.\n\n    orig_type:\n      The type as given in the Kconfig file, without any magic applied. Used\n      when printing the choice.\n\n    tri_value:\n      The tristate value (mode) of the choice. A choice can be in one of three\n      modes:\n\n        0 (n) - The choice is disabled and no symbols can be selected. For\n                visible choices, this mode is only possible for choices with\n                the 'optional' flag set (see kconfig-language.txt).\n\n        1 (m) - Any number of choice symbols can be set to m, the rest will\n                be n.\n\n        2 (y) - One symbol will be y, the rest n.\n\n      Only tristate choices can be in m mode. The visibility of the choice is\n      an upper bound on the mode, and the mode in turn is an upper bound on the\n      visibility of the choice symbols.\n\n      To change the mode, use Choice.set_value().\n\n      Implementation note:\n        The C tools internally represent choices as a type of symbol, with\n        special-casing in many code paths. This is why there is a lot of\n        similarity to Symbol. The value (mode) of a choice is really just a\n        normal symbol value, and an implicit reverse dependency forces its\n        lower bound to m for visible non-optional choices (the reverse\n        dependency is 'm && <visibility>').\n\n        Symbols within choices get the choice propagated as a dependency to\n        their properties. This turns the mode of the choice into an upper bound\n        on e.g. the visibility of choice symbols, and explains the gotcha\n        related to printing choice symbols mentioned in the module docstring.\n\n        Kconfiglib uses a separate Choice class only because it makes the code\n        and interface less confusing (especially in a user-facing interface).\n        Corresponding attributes have the same name in the Symbol and Choice\n        classes, for consistency and compatibility.\n\n    str_value:\n      Like choice.tri_value, but gives the value as one of the strings\n      \"n\", \"m\", or \"y\"\n\n    user_value:\n      The value (mode) selected by the user through Choice.set_value(). Either\n      0, 1, or 2, or None if the user hasn't selected a mode. See\n      Symbol.user_value.\n\n      WARNING: Do not assign directly to this. It will break things. Use\n      Choice.set_value() instead.\n\n    assignable:\n      See the symbol class documentation. Gives the assignable values (modes).\n\n    selection:\n      The Symbol instance of the currently selected symbol. None if the Choice\n      is not in y mode or has no selected symbol (due to unsatisfied\n      dependencies on choice symbols).\n\n      WARNING: Do not assign directly to this. It will break things. Call\n      sym.set_value(2) on the choice symbol you want to select instead.\n\n    user_selection:\n      The symbol selected by the user (by setting it to y). Ignored if the\n      choice is not in y mode, but still remembered so that the choice \"snaps\n      back\" to the user selection if the mode is changed back to y. This might\n      differ from 'selection' due to unsatisfied dependencies.\n\n      WARNING: Do not assign directly to this. It will break things. Call\n      sym.set_value(2) on the choice symbol to be selected instead.\n\n    visibility:\n      See the Symbol class documentation. Acts on the value (mode).\n\n    name_and_loc:\n      Holds a string like\n\n        \"<choice MY_CHOICE> (defined at foo/Kconfig:12)\"\n\n      , giving the name of the choice and its definition location(s). If the\n      choice has no name (isn't defined with 'choice MY_CHOICE'), then it will\n      be shown as \"<choice>\" before the list of locations (always a single one\n      in that case).\n\n    syms:\n      List of symbols contained in the choice.\n\n      Obscure gotcha: If a symbol depends on the previous symbol within a\n      choice so that an implicit menu is created, it won't be a choice symbol,\n      and won't be included in 'syms'.\n\n    nodes:\n      A list of MenuNodes for this choice. In practice, the list will probably\n      always contain a single MenuNode, but it is possible to give a choice a\n      name and define it in multiple locations.\n\n    defaults:\n      List of (symbol, cond) tuples for the choice's 'defaults' properties. For\n      example, 'default A if B && C' is represented as (A, (AND, B, C)). If\n      there is no condition, 'cond' is self.kconfig.y.\n\n      Note that 'depends on' and parent dependencies are propagated to\n      'default' conditions.\n\n    orig_defaults:\n      See the corresponding attribute on the MenuNode class.\n\n    direct_dep:\n      See Symbol.direct_dep.\n\n    referenced:\n      A set() with all symbols referenced in the properties and property\n      conditions of the choice.\n\n      Also includes dependencies from surrounding menus and ifs, because those\n      get propagated to the choice (see the 'Intro to symbol values' section in\n      the module docstring).\n\n    is_optional:\n      True if the choice has the 'optional' flag set on it and can be in\n      n mode.\n\n    kconfig:\n      The Kconfig instance this choice is from.\n    \"\"\"\n    __slots__ = (\n        \"_cached_assignable\",\n        \"_cached_selection\",\n        \"_cached_vis\",\n        \"_dependents\",\n        \"_visited\",\n        \"_was_set\",\n        \"defaults\",\n        \"direct_dep\",\n        \"is_constant\",\n        \"is_optional\",\n        \"kconfig\",\n        \"name\",\n        \"nodes\",\n        \"orig_type\",\n        \"syms\",\n        \"user_selection\",\n        \"user_value\",\n    )\n\n    #\n    # Public interface\n    #\n\n    @property\n    def type(self):\n        \"\"\"\n        Returns the type of the choice. See Symbol.type.\n        \"\"\"\n        if self.orig_type is TRISTATE and not self.kconfig.modules.tri_value:\n            return BOOL\n        return self.orig_type\n\n    @property\n    def str_value(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        return TRI_TO_STR[self.tri_value]\n\n    @property\n    def tri_value(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        # This emulates a reverse dependency of 'm && visibility' for\n        # non-optional choices, which is how the C implementation does it\n\n        val = 0 if self.is_optional else 1\n\n        if self.user_value is not None:\n            val = max(val, self.user_value)\n\n        # Warning: See Symbol._rec_invalidate(), and note that this is a hidden\n        # function call (property magic)\n        val = min(val, self.visibility)\n\n        # Promote m to y for boolean choices\n        return 2 if val == 1 and self.type is BOOL else val\n\n    @property\n    def assignable(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        if self._cached_assignable is None:\n            self._cached_assignable = self._assignable()\n        return self._cached_assignable\n\n    @property\n    def visibility(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        if self._cached_vis is None:\n            self._cached_vis = _visibility(self)\n        return self._cached_vis\n\n    @property\n    def name_and_loc(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        # Reuse the expression format, which is '<choice (name, if any)>'.\n        return standard_sc_expr_str(self) + \" \" + _locs(self)\n\n    @property\n    def selection(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        if self._cached_selection is _NO_CACHED_SELECTION:\n            self._cached_selection = self._selection()\n        return self._cached_selection\n\n    def set_value(self, value):\n        \"\"\"\n        Sets the user value (mode) of the choice. Like for Symbol.set_value(),\n        the visibility might truncate the value. Choices without the 'optional'\n        attribute (is_optional) can never be in n mode, but 0/\"n\" is still\n        accepted since it's not a malformed value (though it will have no\n        effect).\n\n        Returns True if the value is valid for the type of the choice, and\n        False otherwise. This only looks at the form of the value. Check the\n        Choice.assignable attribute to see what values are currently in range\n        and would actually be reflected in the mode of the choice.\n        \"\"\"\n        if value in STR_TO_TRI:\n            value = STR_TO_TRI[value]\n\n        if value == self.user_value:\n            # We know the value must be valid if it was successfully set\n            # previously\n            self._was_set = True\n            return True\n\n        if not (self.orig_type is BOOL     and value in (2, 0) or\n                self.orig_type is TRISTATE and value in TRI_TO_STR):\n\n            # Display tristate values as n, m, y in the warning\n            self.kconfig._warn(\n                \"the value {} is invalid for {}, which has type {} -- \"\n                \"assignment ignored\"\n                .format(TRI_TO_STR[value] if value in TRI_TO_STR else\n                            \"'{}'\".format(value),\n                        self.name_and_loc, TYPE_TO_STR[self.orig_type]))\n\n            return False\n\n        self.user_value = value\n        self._was_set = True\n        self._rec_invalidate()\n\n        return True\n\n    def unset_value(self):\n        \"\"\"\n        Resets the user value (mode) and user selection of the Choice, as if\n        the user had never touched the mode or any of the choice symbols.\n        \"\"\"\n        if self.user_value is not None or self.user_selection:\n            self.user_value = self.user_selection = None\n            self._rec_invalidate()\n\n    @property\n    def referenced(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        return {item for node in self.nodes for item in node.referenced}\n\n    @property\n    def orig_defaults(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        return [d for node in self.nodes for d in node.orig_defaults]\n\n    def __repr__(self):\n        \"\"\"\n        Returns a string with information about the choice when it is evaluated\n        on e.g. the interactive Python prompt.\n        \"\"\"\n        fields = [\"choice \" + self.name if self.name else \"choice\",\n                  TYPE_TO_STR[self.type]]\n        add = fields.append\n\n        for node in self.nodes:\n            if node.prompt:\n                add('\"{}\"'.format(node.prompt[0]))\n\n        add(\"mode \" + self.str_value)\n\n        if self.user_value is not None:\n            add('user mode {}'.format(TRI_TO_STR[self.user_value]))\n\n        if self.selection:\n            add(\"{} selected\".format(self.selection.name))\n\n        if self.user_selection:\n            user_sel_str = \"{} selected by user\" \\\n                           .format(self.user_selection.name)\n\n            if self.selection is not self.user_selection:\n                user_sel_str += \" (overridden)\"\n\n            add(user_sel_str)\n\n        add(\"visibility \" + TRI_TO_STR[self.visibility])\n\n        if self.is_optional:\n            add(\"optional\")\n\n        for node in self.nodes:\n            add(\"{}:{}\".format(node.filename, node.linenr))\n\n        return \"<{}>\".format(\", \".join(fields))\n\n    def __str__(self):\n        \"\"\"\n        Returns a string representation of the choice when it is printed.\n        Matches the Kconfig format (though without the contained choice\n        symbols), with any parent dependencies propagated to the 'depends on'\n        condition.\n\n        The returned string does not end in a newline.\n\n        See Symbol.__str__() as well.\n        \"\"\"\n        return self.custom_str(standard_sc_expr_str)\n\n    def custom_str(self, sc_expr_str_fn):\n        \"\"\"\n        Works like Choice.__str__(), but allows a custom format to be used for\n        all symbol/choice references. See expr_str().\n        \"\"\"\n        return \"\\n\\n\".join(node.custom_str(sc_expr_str_fn)\n                           for node in self.nodes)\n\n    #\n    # Private methods\n    #\n\n    def __init__(self):\n        \"\"\"\n        Choice constructor -- not intended to be called directly by Kconfiglib\n        clients.\n        \"\"\"\n        # These attributes are always set on the instance from outside and\n        # don't need defaults:\n        #   direct_dep\n        #   kconfig\n\n        # - UNKNOWN == 0\n        # - _visited is used during dep. loop detection\n        self.orig_type = self._visited = 0\n\n        self.nodes = []\n\n        self.syms = []\n        self.defaults = []\n\n        self.name = \\\n        self.user_value = self.user_selection = \\\n        self._cached_vis = self._cached_assignable = None\n\n        self._cached_selection = _NO_CACHED_SELECTION\n\n        # is_constant is checked by _depend_on(). Just set it to avoid having\n        # to special-case choices.\n        self.is_constant = self.is_optional = False\n\n        # See Kconfig._build_dep()\n        self._dependents = set()\n\n    def _assignable(self):\n        # Worker function for the 'assignable' attribute\n\n        # Warning: See Symbol._rec_invalidate(), and note that this is a hidden\n        # function call (property magic)\n        vis = self.visibility\n\n        if not vis:\n            return ()\n\n        if vis == 2:\n            if not self.is_optional:\n                return (2,) if self.type is BOOL else (1, 2)\n            return (0, 2) if self.type is BOOL else (0, 1, 2)\n\n        # vis == 1\n\n        return (0, 1) if self.is_optional else (1,)\n\n    def _selection(self):\n        # Worker function for the 'selection' attribute\n\n        # Warning: See Symbol._rec_invalidate(), and note that this is a hidden\n        # function call (property magic)\n        if self.tri_value != 2:\n            # Not in y mode, so no selection\n            return None\n\n        # Use the user selection if it's visible\n        if self.user_selection and self.user_selection.visibility:\n            return self.user_selection\n\n        # Otherwise, check if we have a default\n        return self._selection_from_defaults()\n\n    def _selection_from_defaults(self):\n        # Check if we have a default\n        for sym, cond in self.defaults:\n            # The default symbol must be visible too\n            if expr_value(cond) and sym.visibility:\n                return sym\n\n        # Otherwise, pick the first visible symbol, if any\n        for sym in self.syms:\n            if sym.visibility:\n                return sym\n\n        # Couldn't find a selection\n        return None\n\n    def _invalidate(self):\n        self._cached_vis = self._cached_assignable = None\n        self._cached_selection = _NO_CACHED_SELECTION\n\n    def _rec_invalidate(self):\n        # See Symbol._rec_invalidate()\n\n        self._invalidate()\n\n        for item in self._dependents:\n            if item._cached_vis is not None:\n                item._rec_invalidate()\n\n\nclass MenuNode(object):\n    \"\"\"\n    Represents a menu node in the configuration. This corresponds to an entry\n    in e.g. the 'make menuconfig' interface, though non-visible choices, menus,\n    and comments also get menu nodes. If a symbol or choice is defined in\n    multiple locations, it gets one menu node for each location.\n\n    The top-level menu node, corresponding to the implicit top-level menu, is\n    available in Kconfig.top_node.\n\n    The menu nodes for a Symbol or Choice can be found in the\n    Symbol/Choice.nodes attribute. Menus and comments are represented as plain\n    menu nodes, with their text stored in the prompt attribute (prompt[0]).\n    This mirrors the C implementation.\n\n    The following attributes are available on MenuNode instances. They should\n    be viewed as read-only.\n\n    item:\n      Either a Symbol, a Choice, or one of the constants MENU and COMMENT.\n      Menus and comments are represented as plain menu nodes. Ifs are collapsed\n      (matching the C implementation) and do not appear in the final menu tree.\n\n    next:\n      The following menu node. None if there is no following node.\n\n    list:\n      The first child menu node. None if there are no children.\n\n      Choices and menus naturally have children, but Symbols can also have\n      children because of menus created automatically from dependencies (see\n      kconfig-language.txt).\n\n    parent:\n      The parent menu node. None if there is no parent.\n\n    prompt:\n      A (string, cond) tuple with the prompt for the menu node and its\n      conditional expression (which is self.kconfig.y if there is no\n      condition). None if there is no prompt.\n\n      For symbols and choices, the prompt is stored in the MenuNode rather than\n      the Symbol or Choice instance. For menus and comments, the prompt holds\n      the text.\n\n    defaults:\n      The 'default' properties for this particular menu node. See\n      symbol.defaults.\n\n      When evaluating defaults, you should use Symbol/Choice.defaults instead,\n      as it include properties from all menu nodes (a symbol/choice can have\n      multiple definition locations/menu nodes). MenuNode.defaults is meant for\n      documentation generation.\n\n    selects:\n      Like MenuNode.defaults, for selects.\n\n    implies:\n      Like MenuNode.defaults, for implies.\n\n    ranges:\n      Like MenuNode.defaults, for ranges.\n\n    orig_prompt:\n    orig_defaults:\n    orig_selects:\n    orig_implies:\n    orig_ranges:\n      These work the like the corresponding attributes without orig_*, but omit\n      any dependencies propagated from 'depends on' and surrounding 'if's (the\n      direct dependencies, stored in MenuNode.dep).\n\n      One use for this is generating less cluttered documentation, by only\n      showing the direct dependencies in one place.\n\n    help:\n      The help text for the menu node for Symbols and Choices. None if there is\n      no help text. Always stored in the node rather than the Symbol or Choice.\n      It is possible to have a separate help text at each location if a symbol\n      is defined in multiple locations.\n\n      Trailing whitespace (including a final newline) is stripped from the help\n      text. This was not the case before Kconfiglib 10.21.0, where the format\n      was undocumented.\n\n    dep:\n      The direct ('depends on') dependencies for the menu node, or\n      self.kconfig.y if there are no direct dependencies.\n\n      This attribute includes any dependencies from surrounding menus and ifs.\n      Those get propagated to the direct dependencies, and the resulting direct\n      dependencies in turn get propagated to the conditions of all properties.\n\n      If a symbol or choice is defined in multiple locations, only the\n      properties defined at a particular location get the corresponding\n      MenuNode.dep dependencies propagated to them.\n\n    visibility:\n      The 'visible if' dependencies for the menu node (which must represent a\n      menu), or self.kconfig.y if there are no 'visible if' dependencies.\n      'visible if' dependencies are recursively propagated to the prompts of\n      symbols and choices within the menu.\n\n    referenced:\n      A set() with all symbols and choices referenced in the properties and\n      property conditions of the menu node.\n\n      Also includes dependencies inherited from surrounding menus and ifs.\n      Choices appear in the dependencies of choice symbols.\n\n    is_menuconfig:\n      Set to True if the children of the menu node should be displayed in a\n      separate menu. This is the case for the following items:\n\n        - Menus (node.item == MENU)\n\n        - Choices\n\n        - Symbols defined with the 'menuconfig' keyword. The children come from\n          implicitly created submenus, and should be displayed in a separate\n          menu rather than being indented.\n\n      'is_menuconfig' is just a hint on how to display the menu node. It's\n      ignored internally by Kconfiglib, except when printing symbols.\n\n    filename/linenr:\n      The location where the menu node appears. The filename is relative to\n      $srctree (or to the current directory if $srctree isn't set), except\n      absolute paths are used for paths outside $srctree.\n\n    include_path:\n      A tuple of (filename, linenr) tuples, giving the locations of the\n      'source' statements via which the Kconfig file containing this menu node\n      was included. The first element is the location of the 'source' statement\n      in the top-level Kconfig file passed to Kconfig.__init__(), etc.\n\n      Note that the Kconfig file of the menu node itself isn't included. Check\n      'filename' and 'linenr' for that.\n\n    kconfig:\n      The Kconfig instance the menu node is from.\n    \"\"\"\n    __slots__ = (\n        \"dep\",\n        \"filename\",\n        \"help\",\n        \"include_path\",\n        \"is_menuconfig\",\n        \"item\",\n        \"kconfig\",\n        \"linenr\",\n        \"list\",\n        \"next\",\n        \"parent\",\n        \"prompt\",\n        \"visibility\",\n\n        # Properties\n        \"defaults\",\n        \"selects\",\n        \"implies\",\n        \"ranges\",\n    )\n\n    def __init__(self):\n        # Properties defined on this particular menu node. A local 'depends on'\n        # only applies to these, in case a symbol is defined in multiple\n        # locations.\n        self.defaults = []\n        self.selects = []\n        self.implies = []\n        self.ranges = []\n\n    @property\n    def orig_prompt(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        if not self.prompt:\n            return None\n        return (self.prompt[0], self._strip_dep(self.prompt[1]))\n\n    @property\n    def orig_defaults(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        return [(default, self._strip_dep(cond))\n                for default, cond in self.defaults]\n\n    @property\n    def orig_selects(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        return [(select, self._strip_dep(cond))\n                for select, cond in self.selects]\n\n    @property\n    def orig_implies(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        return [(imply, self._strip_dep(cond))\n                for imply, cond in self.implies]\n\n    @property\n    def orig_ranges(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        return [(low, high, self._strip_dep(cond))\n                for low, high, cond in self.ranges]\n\n    @property\n    def referenced(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        # self.dep is included to catch dependencies from a lone 'depends on'\n        # when there are no properties to propagate it to\n        res = expr_items(self.dep)\n\n        if self.prompt:\n            res |= expr_items(self.prompt[1])\n\n        if self.item is MENU:\n            res |= expr_items(self.visibility)\n\n        for value, cond in self.defaults:\n            res |= expr_items(value)\n            res |= expr_items(cond)\n\n        for value, cond in self.selects:\n            res.add(value)\n            res |= expr_items(cond)\n\n        for value, cond in self.implies:\n            res.add(value)\n            res |= expr_items(cond)\n\n        for low, high, cond in self.ranges:\n            res.add(low)\n            res.add(high)\n            res |= expr_items(cond)\n\n        return res\n\n    def __repr__(self):\n        \"\"\"\n        Returns a string with information about the menu node when it is\n        evaluated on e.g. the interactive Python prompt.\n        \"\"\"\n        fields = []\n        add = fields.append\n\n        if self.item.__class__ is Symbol:\n            add(\"menu node for symbol \" + self.item.name)\n\n        elif self.item.__class__ is Choice:\n            s = \"menu node for choice\"\n            if self.item.name is not None:\n                s += \" \" + self.item.name\n            add(s)\n\n        elif self.item is MENU:\n            add(\"menu node for menu\")\n\n        else:  # self.item is COMMENT\n            add(\"menu node for comment\")\n\n        if self.prompt:\n            add('prompt \"{}\" (visibility {})'.format(\n                self.prompt[0], TRI_TO_STR[expr_value(self.prompt[1])]))\n\n        if self.item.__class__ is Symbol and self.is_menuconfig:\n            add(\"is menuconfig\")\n\n        add(\"deps \" + TRI_TO_STR[expr_value(self.dep)])\n\n        if self.item is MENU:\n            add(\"'visible if' deps \" + TRI_TO_STR[expr_value(self.visibility)])\n\n        if self.item.__class__ in _SYMBOL_CHOICE and self.help is not None:\n            add(\"has help\")\n\n        if self.list:\n            add(\"has child\")\n\n        if self.next:\n            add(\"has next\")\n\n        add(\"{}:{}\".format(self.filename, self.linenr))\n\n        return \"<{}>\".format(\", \".join(fields))\n\n    def __str__(self):\n        \"\"\"\n        Returns a string representation of the menu node. Matches the Kconfig\n        format, with any parent dependencies propagated to the 'depends on'\n        condition.\n\n        The output could (almost) be fed back into a Kconfig parser to redefine\n        the object associated with the menu node. See the module documentation\n        for a gotcha related to choice symbols.\n\n        For symbols and choices with multiple menu nodes (multiple definition\n        locations), properties that aren't associated with a particular menu\n        node are shown on all menu nodes ('option env=...', 'optional' for\n        choices, etc.).\n\n        The returned string does not end in a newline.\n        \"\"\"\n        return self.custom_str(standard_sc_expr_str)\n\n    def custom_str(self, sc_expr_str_fn):\n        \"\"\"\n        Works like MenuNode.__str__(), but allows a custom format to be used\n        for all symbol/choice references. See expr_str().\n        \"\"\"\n        return self._menu_comment_node_str(sc_expr_str_fn) \\\n               if self.item in _MENU_COMMENT else \\\n               self._sym_choice_node_str(sc_expr_str_fn)\n\n    def _menu_comment_node_str(self, sc_expr_str_fn):\n        s = '{} \"{}\"'.format(\"menu\" if self.item is MENU else \"comment\",\n                             self.prompt[0])\n\n        if self.dep is not self.kconfig.y:\n            s += \"\\n\\tdepends on {}\".format(expr_str(self.dep, sc_expr_str_fn))\n\n        if self.item is MENU and self.visibility is not self.kconfig.y:\n            s += \"\\n\\tvisible if {}\".format(expr_str(self.visibility,\n                                                     sc_expr_str_fn))\n\n        return s\n\n    def _sym_choice_node_str(self, sc_expr_str_fn):\n        def indent_add(s):\n            lines.append(\"\\t\" + s)\n\n        def indent_add_cond(s, cond):\n            if cond is not self.kconfig.y:\n                s += \" if \" + expr_str(cond, sc_expr_str_fn)\n            indent_add(s)\n\n        sc = self.item\n\n        if sc.__class__ is Symbol:\n            lines = [(\"menuconfig \" if self.is_menuconfig else \"config \")\n                     + sc.name]\n        else:\n            lines = [\"choice \" + sc.name if sc.name else \"choice\"]\n\n        if sc.orig_type and not self.prompt:  # sc.orig_type != UNKNOWN\n            # If there's a prompt, we'll use the '<type> \"prompt\"' shorthand\n            # instead\n            indent_add(TYPE_TO_STR[sc.orig_type])\n\n        if self.prompt:\n            if sc.orig_type:\n                prefix = TYPE_TO_STR[sc.orig_type]\n            else:\n                # Symbol defined without a type (which generates a warning)\n                prefix = \"prompt\"\n\n            indent_add_cond(prefix + ' \"{}\"'.format(escape(self.prompt[0])),\n                            self.orig_prompt[1])\n\n        if sc.__class__ is Symbol:\n            if sc.is_allnoconfig_y:\n                indent_add(\"option allnoconfig_y\")\n\n            if sc is sc.kconfig.defconfig_list:\n                indent_add(\"option defconfig_list\")\n\n            if sc.env_var is not None:\n                indent_add('option env=\"{}\"'.format(sc.env_var))\n\n            if sc is sc.kconfig.modules:\n                indent_add(\"option modules\")\n\n            for low, high, cond in self.orig_ranges:\n                indent_add_cond(\n                    \"range {} {}\".format(sc_expr_str_fn(low),\n                                         sc_expr_str_fn(high)),\n                    cond)\n\n        for default, cond in self.orig_defaults:\n            indent_add_cond(\"default \" + expr_str(default, sc_expr_str_fn),\n                            cond)\n\n        if sc.__class__ is Choice and sc.is_optional:\n            indent_add(\"optional\")\n\n        if sc.__class__ is Symbol:\n            for select, cond in self.orig_selects:\n                indent_add_cond(\"select \" + sc_expr_str_fn(select), cond)\n\n            for imply, cond in self.orig_implies:\n                indent_add_cond(\"imply \" + sc_expr_str_fn(imply), cond)\n\n        if self.dep is not sc.kconfig.y:\n            indent_add(\"depends on \" + expr_str(self.dep, sc_expr_str_fn))\n\n        if self.help is not None:\n            indent_add(\"help\")\n            for line in self.help.splitlines():\n                indent_add(\"  \" + line)\n\n        return \"\\n\".join(lines)\n\n    def _strip_dep(self, expr):\n        # Helper function for removing MenuNode.dep from 'expr'. Uses two\n        # pieces of internal knowledge: (1) Expressions are reused rather than\n        # copied, and (2) the direct dependencies always appear at the end.\n\n        # ... if dep -> ... if y\n        if self.dep is expr:\n            return self.kconfig.y\n\n        # (AND, X, dep) -> X\n        if expr.__class__ is tuple and expr[0] is AND and expr[2] is self.dep:\n            return expr[1]\n\n        return expr\n\n\nclass Variable(object):\n    \"\"\"\n    Represents a preprocessor variable/function.\n\n    The following attributes are available:\n\n    name:\n      The name of the variable.\n\n    value:\n      The unexpanded value of the variable.\n\n    expanded_value:\n      The expanded value of the variable. For simple variables (those defined\n      with :=), this will equal 'value'. Accessing this property will raise a\n      KconfigError if the expansion seems to be stuck in a loop.\n\n      Accessing this field is the same as calling expanded_value_w_args() with\n      no arguments. I hadn't considered function arguments when adding it. It\n      is retained for backwards compatibility though.\n\n    is_recursive:\n      True if the variable is recursive (defined with =).\n    \"\"\"\n    __slots__ = (\n        \"_n_expansions\",\n        \"is_recursive\",\n        \"kconfig\",\n        \"name\",\n        \"value\",\n    )\n\n    @property\n    def expanded_value(self):\n        \"\"\"\n        See the class documentation.\n        \"\"\"\n        return self.expanded_value_w_args()\n\n    def expanded_value_w_args(self, *args):\n        \"\"\"\n        Returns the expanded value of the variable/function. Any arguments\n        passed will be substituted for $(1), $(2), etc.\n\n        Raises a KconfigError if the expansion seems to be stuck in a loop.\n        \"\"\"\n        return self.kconfig._fn_val((self.name,) + args)\n\n    def __repr__(self):\n        return \"<variable {}, {}, value '{}'>\" \\\n               .format(self.name,\n                       \"recursive\" if self.is_recursive else \"immediate\",\n                       self.value)\n\n\nclass KconfigError(Exception):\n    \"\"\"\n    Exception raised for Kconfig-related errors.\n\n    KconfigError and KconfigSyntaxError are the same class. The\n    KconfigSyntaxError alias is only maintained for backwards compatibility.\n    \"\"\"\n\nKconfigSyntaxError = KconfigError  # Backwards compatibility\n\n\nclass InternalError(Exception):\n    \"Never raised. Kept around for backwards compatibility.\"\n\n\n# Workaround:\n#\n# If 'errno' and 'strerror' are set on IOError, then __str__() always returns\n# \"[Errno <errno>] <strerror>\", ignoring any custom message passed to the\n# constructor. By defining our own subclass, we can use a custom message while\n# also providing 'errno', 'strerror', and 'filename' to scripts.\nclass _KconfigIOError(IOError):\n    def __init__(self, ioerror, msg):\n        self.msg = msg\n        super(_KconfigIOError, self).__init__(\n            ioerror.errno, ioerror.strerror, ioerror.filename)\n\n    def __str__(self):\n        return self.msg\n\n\n#\n# Public functions\n#\n\n\ndef expr_value(expr):\n    \"\"\"\n    Evaluates the expression 'expr' to a tristate value. Returns 0 (n), 1 (m),\n    or 2 (y).\n\n    'expr' must be an already-parsed expression from a Symbol, Choice, or\n    MenuNode property. To evaluate an expression represented as a string, use\n    Kconfig.eval_string().\n\n    Passing subexpressions of expressions to this function works as expected.\n    \"\"\"\n    if expr.__class__ is not tuple:\n        return expr.tri_value\n\n    if expr[0] is AND:\n        v1 = expr_value(expr[1])\n        # Short-circuit the n case as an optimization (~5% faster\n        # allnoconfig.py and allyesconfig.py, as of writing)\n        return 0 if not v1 else min(v1, expr_value(expr[2]))\n\n    if expr[0] is OR:\n        v1 = expr_value(expr[1])\n        # Short-circuit the y case as an optimization\n        return 2 if v1 == 2 else max(v1, expr_value(expr[2]))\n\n    if expr[0] is NOT:\n        return 2 - expr_value(expr[1])\n\n    # Relation\n    #\n    # Implements <, <=, >, >= comparisons as well. These were added to\n    # kconfig in 31847b67 (kconfig: allow use of relations other than\n    # (in)equality).\n\n    rel, v1, v2 = expr\n\n    # If both operands are strings...\n    if v1.orig_type is STRING and v2.orig_type is STRING:\n        # ...then compare them lexicographically\n        comp = _strcmp(v1.str_value, v2.str_value)\n    else:\n        # Otherwise, try to compare them as numbers\n        try:\n            comp = _sym_to_num(v1) - _sym_to_num(v2)\n        except ValueError:\n            # Fall back on a lexicographic comparison if the operands don't\n            # parse as numbers\n            comp = _strcmp(v1.str_value, v2.str_value)\n\n    return 2*(comp == 0 if rel is EQUAL else\n              comp != 0 if rel is UNEQUAL else\n              comp <  0 if rel is LESS else\n              comp <= 0 if rel is LESS_EQUAL else\n              comp >  0 if rel is GREATER else\n              comp >= 0)\n\n\ndef standard_sc_expr_str(sc):\n    \"\"\"\n    Standard symbol/choice printing function. Uses plain Kconfig syntax, and\n    displays choices as <choice> (or <choice NAME>, for named choices).\n\n    See expr_str().\n    \"\"\"\n    if sc.__class__ is Symbol:\n        if sc.is_constant and sc.name not in STR_TO_TRI:\n            return '\"{}\"'.format(escape(sc.name))\n        return sc.name\n\n    return \"<choice {}>\".format(sc.name) if sc.name else \"<choice>\"\n\n\ndef expr_str(expr, sc_expr_str_fn=standard_sc_expr_str):\n    \"\"\"\n    Returns the string representation of the expression 'expr', as in a Kconfig\n    file.\n\n    Passing subexpressions of expressions to this function works as expected.\n\n    sc_expr_str_fn (default: standard_sc_expr_str):\n      This function is called for every symbol/choice (hence \"sc\") appearing in\n      the expression, with the symbol/choice as the argument. It is expected to\n      return a string to be used for the symbol/choice.\n\n      This can be used e.g. to turn symbols/choices into links when generating\n      documentation, or for printing the value of each symbol/choice after it.\n\n      Note that quoted values are represented as constants symbols\n      (Symbol.is_constant == True).\n    \"\"\"\n    if expr.__class__ is not tuple:\n        return sc_expr_str_fn(expr)\n\n    if expr[0] is AND:\n        return \"{} && {}\".format(_parenthesize(expr[1], OR, sc_expr_str_fn),\n                                 _parenthesize(expr[2], OR, sc_expr_str_fn))\n\n    if expr[0] is OR:\n        # This turns A && B || C && D into \"(A && B) || (C && D)\", which is\n        # redundant, but more readable\n        return \"{} || {}\".format(_parenthesize(expr[1], AND, sc_expr_str_fn),\n                                 _parenthesize(expr[2], AND, sc_expr_str_fn))\n\n    if expr[0] is NOT:\n        if expr[1].__class__ is tuple:\n            return \"!({})\".format(expr_str(expr[1], sc_expr_str_fn))\n        return \"!\" + sc_expr_str_fn(expr[1])  # Symbol\n\n    # Relation\n    #\n    # Relation operands are always symbols (quoted strings are constant\n    # symbols)\n    return \"{} {} {}\".format(sc_expr_str_fn(expr[1]), REL_TO_STR[expr[0]],\n                             sc_expr_str_fn(expr[2]))\n\n\ndef expr_items(expr):\n    \"\"\"\n    Returns a set() of all items (symbols and choices) that appear in the\n    expression 'expr'.\n\n    Passing subexpressions of expressions to this function works as expected.\n    \"\"\"\n    res = set()\n\n    def rec(subexpr):\n        if subexpr.__class__ is tuple:\n            # AND, OR, NOT, or relation\n\n            rec(subexpr[1])\n\n            # NOTs only have a single operand\n            if subexpr[0] is not NOT:\n                rec(subexpr[2])\n\n        else:\n            # Symbol or choice\n            res.add(subexpr)\n\n    rec(expr)\n    return res\n\n\ndef split_expr(expr, op):\n    \"\"\"\n    Returns a list containing the top-level AND or OR operands in the\n    expression 'expr', in the same (left-to-right) order as they appear in\n    the expression.\n\n    This can be handy e.g. for splitting (weak) reverse dependencies\n    from 'select' and 'imply' into individual selects/implies.\n\n    op:\n      Either AND to get AND operands, or OR to get OR operands.\n\n      (Having this as an operand might be more future-safe than having two\n      hardcoded functions.)\n\n\n    Pseudo-code examples:\n\n      split_expr( A                    , OR  )  ->  [A]\n      split_expr( A && B               , OR  )  ->  [A && B]\n      split_expr( A || B               , OR  )  ->  [A, B]\n      split_expr( A || B               , AND )  ->  [A || B]\n      split_expr( A || B || (C && D)   , OR  )  ->  [A, B, C && D]\n\n      # Second || is not at the top level\n      split_expr( A || (B && (C || D)) , OR )  ->  [A, B && (C || D)]\n\n      # Parentheses don't matter as long as we stay at the top level (don't\n      # encounter any non-'op' nodes)\n      split_expr( (A || B) || C        , OR )  ->  [A, B, C]\n      split_expr( A || (B || C)        , OR )  ->  [A, B, C]\n    \"\"\"\n    res = []\n\n    def rec(subexpr):\n        if subexpr.__class__ is tuple and subexpr[0] is op:\n            rec(subexpr[1])\n            rec(subexpr[2])\n        else:\n            res.append(subexpr)\n\n    rec(expr)\n    return res\n\n\ndef escape(s):\n    r\"\"\"\n    Escapes the string 's' in the same fashion as is done for display in\n    Kconfig format and when writing strings to a .config file. \" and \\ are\n    replaced by \\\" and \\\\, respectively.\n    \"\"\"\n    # \\ must be escaped before \" to avoid double escaping\n    return s.replace(\"\\\\\", r\"\\\\\").replace('\"', r'\\\"')\n\n\ndef unescape(s):\n    r\"\"\"\n    Unescapes the string 's'. \\ followed by any character is replaced with just\n    that character. Used internally when reading .config files.\n    \"\"\"\n    return _unescape_sub(r\"\\1\", s)\n\n# unescape() helper\n_unescape_sub = re.compile(r\"\\\\(.)\").sub\n\n\ndef standard_kconfig(description=None):\n    \"\"\"\n    Argument parsing helper for tools that take a single optional Kconfig file\n    argument (default: Kconfig). Returns the Kconfig instance for the parsed\n    configuration. Uses argparse internally.\n\n    Exits with sys.exit() (which raises SystemExit) on errors.\n\n    description (default: None):\n      The 'description' passed to argparse.ArgumentParser().\n      argparse.RawDescriptionHelpFormatter is used, so formatting is preserved.\n    \"\"\"\n    import argparse\n\n    parser = argparse.ArgumentParser(\n        formatter_class=argparse.RawDescriptionHelpFormatter,\n        description=description)\n\n    parser.add_argument(\n        \"kconfig\",\n        metavar=\"KCONFIG\",\n        default=\"Kconfig\",\n        nargs=\"?\",\n        help=\"Top-level Kconfig file (default: Kconfig)\")\n\n    return Kconfig(parser.parse_args().kconfig, suppress_traceback=True)\n\n\ndef standard_config_filename():\n    \"\"\"\n    Helper for tools. Returns the value of KCONFIG_CONFIG (which specifies the\n    .config file to load/save) if it is set, and \".config\" otherwise.\n\n    Calling load_config() with filename=None might give the behavior you want,\n    without having to use this function.\n    \"\"\"\n    return os.getenv(\"KCONFIG_CONFIG\", \".config\")\n\n\ndef load_allconfig(kconf, filename):\n    \"\"\"\n    Use Kconfig.load_allconfig() instead, which was added in Kconfiglib 13.4.0.\n    Supported for backwards compatibility. Might be removed at some point after\n    a long period of deprecation warnings.\n    \"\"\"\n    allconfig = os.getenv(\"KCONFIG_ALLCONFIG\")\n    if allconfig is None:\n        return\n\n    def std_msg(e):\n        # \"Upcasts\" a _KconfigIOError to an IOError, removing the custom\n        # __str__() message. The standard message is better here.\n        #\n        # This might also convert an OSError to an IOError in obscure cases,\n        # but it's probably not a big deal. The distinction is shaky (see\n        # PEP-3151).\n        return IOError(e.errno, e.strerror, e.filename)\n\n    old_warn_assign_override = kconf.warn_assign_override\n    old_warn_assign_redun = kconf.warn_assign_redun\n    kconf.warn_assign_override = kconf.warn_assign_redun = False\n\n    if allconfig in (\"\", \"1\"):\n        try:\n            print(kconf.load_config(filename, False))\n        except EnvironmentError as e1:\n            try:\n                print(kconf.load_config(\"all.config\", False))\n            except EnvironmentError as e2:\n                sys.exit(\"error: KCONFIG_ALLCONFIG is set, but neither {} \"\n                         \"nor all.config could be opened: {}, {}\"\n                         .format(filename, std_msg(e1), std_msg(e2)))\n    else:\n        try:\n            print(kconf.load_config(allconfig, False))\n        except EnvironmentError as e:\n            sys.exit(\"error: KCONFIG_ALLCONFIG is set to '{}', which \"\n                     \"could not be opened: {}\"\n                     .format(allconfig, std_msg(e)))\n\n    kconf.warn_assign_override = old_warn_assign_override\n    kconf.warn_assign_redun = old_warn_assign_redun\n\n\n#\n# Internal functions\n#\n\n\ndef _visibility(sc):\n    # Symbols and Choices have a \"visibility\" that acts as an upper bound on\n    # the values a user can set for them, corresponding to the visibility in\n    # e.g. 'make menuconfig'. This function calculates the visibility for the\n    # Symbol or Choice 'sc' -- the logic is nearly identical.\n\n    vis = 0\n\n    for node in sc.nodes:\n        if node.prompt:\n            vis = max(vis, expr_value(node.prompt[1]))\n\n    if sc.__class__ is Symbol and sc.choice:\n        if sc.choice.orig_type is TRISTATE and \\\n           sc.orig_type is not TRISTATE and sc.choice.tri_value != 2:\n            # Non-tristate choice symbols are only visible in y mode\n            return 0\n\n        if sc.orig_type is TRISTATE and vis == 1 and sc.choice.tri_value == 2:\n            # Choice symbols with m visibility are not visible in y mode\n            return 0\n\n    # Promote m to y if we're dealing with a non-tristate (possibly due to\n    # modules being disabled)\n    if vis == 1 and sc.type is not TRISTATE:\n        return 2\n\n    return vis\n\n\ndef _depend_on(sc, expr):\n    # Adds 'sc' (symbol or choice) as a \"dependee\" to all symbols in 'expr'.\n    # Constant symbols in 'expr' are skipped as they can never change value\n    # anyway.\n\n    if expr.__class__ is tuple:\n        # AND, OR, NOT, or relation\n\n        _depend_on(sc, expr[1])\n\n        # NOTs only have a single operand\n        if expr[0] is not NOT:\n            _depend_on(sc, expr[2])\n\n    elif not expr.is_constant:\n        # Non-constant symbol, or choice\n        expr._dependents.add(sc)\n\n\ndef _parenthesize(expr, type_, sc_expr_str_fn):\n    # expr_str() helper. Adds parentheses around expressions of type 'type_'.\n\n    if expr.__class__ is tuple and expr[0] is type_:\n        return \"({})\".format(expr_str(expr, sc_expr_str_fn))\n    return expr_str(expr, sc_expr_str_fn)\n\n\ndef _ordered_unique(lst):\n    # Returns 'lst' with any duplicates removed, preserving order. This hacky\n    # version seems to be a common idiom. It relies on short-circuit evaluation\n    # and set.add() returning None, which is falsy.\n\n    seen = set()\n    seen_add = seen.add\n    return [x for x in lst if x not in seen and not seen_add(x)]\n\n\ndef _is_base_n(s, n):\n    try:\n        int(s, n)\n        return True\n    except ValueError:\n        return False\n\n\ndef _strcmp(s1, s2):\n    # strcmp()-alike that returns -1, 0, or 1\n\n    return (s1 > s2) - (s1 < s2)\n\n\ndef _sym_to_num(sym):\n    # expr_value() helper for converting a symbol to a number. Raises\n    # ValueError for symbols that can't be converted.\n\n    # For BOOL and TRISTATE, n/m/y count as 0/1/2. This mirrors 9059a3493ef\n    # (\"kconfig: fix relational operators for bool and tristate symbols\") in\n    # the C implementation.\n    return sym.tri_value if sym.orig_type in _BOOL_TRISTATE else \\\n           int(sym.str_value, _TYPE_TO_BASE[sym.orig_type])\n\n\ndef _touch_dep_file(path, sym_name):\n    # If sym_name is MY_SYM_NAME, touches my/sym/name.h. See the sync_deps()\n    # docstring.\n\n    sym_path = path + os.sep + sym_name.lower().replace(\"_\", os.sep) + \".h\"\n    sym_path_dir = dirname(sym_path)\n    if not exists(sym_path_dir):\n        os.makedirs(sym_path_dir, 0o755)\n\n    # A kind of truncating touch, mirroring the C tools\n    os.close(os.open(\n        sym_path, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o644))\n\n\ndef _save_old(path):\n    # See write_config()\n\n    def copy(src, dst):\n        # Import as needed, to save some startup time\n        import shutil\n        shutil.copyfile(src, dst)\n\n    if islink(path):\n        # Preserve symlinks\n        copy_fn = copy\n    elif hasattr(os, \"replace\"):\n        # Python 3 (3.3+) only. Best choice when available, because it\n        # removes <filename>.old on both *nix and Windows.\n        copy_fn = os.replace\n    elif os.name == \"posix\":\n        # Removes <filename>.old on POSIX systems\n        copy_fn = os.rename\n    else:\n        # Fall back on copying\n        copy_fn = copy\n\n    try:\n        copy_fn(path, path + \".old\")\n    except Exception:\n        # Ignore errors from 'path' missing as well as other errors.\n        # <filename>.old file is usually more of a nice-to-have, and not worth\n        # erroring out over e.g. if <filename>.old happens to be a directory or\n        # <filename> is something like /dev/null.\n        pass\n\n\ndef _locs(sc):\n    # Symbol/Choice.name_and_loc helper. Returns the \"(defined at ...)\" part of\n    # the string. 'sc' is a Symbol or Choice.\n\n    if sc.nodes:\n        return \"(defined at {})\".format(\n            \", \".join(\"{0.filename}:{0.linenr}\".format(node)\n                      for node in sc.nodes))\n\n    return \"(undefined)\"\n\n\n# Menu manipulation\n\n\ndef _expr_depends_on(expr, sym):\n    # Reimplementation of expr_depends_symbol() from mconf.c. Used to determine\n    # if a submenu should be implicitly created. This also influences which\n    # items inside choice statements are considered choice items.\n\n    if expr.__class__ is not tuple:\n        return expr is sym\n\n    if expr[0] in _EQUAL_UNEQUAL:\n        # Check for one of the following:\n        # sym = m/y, m/y = sym, sym != n, n != sym\n\n        left, right = expr[1:]\n\n        if right is sym:\n            left, right = right, left\n        elif left is not sym:\n            return False\n\n        return (expr[0] is EQUAL and right is sym.kconfig.m or\n                                     right is sym.kconfig.y) or \\\n               (expr[0] is UNEQUAL and right is sym.kconfig.n)\n\n    return expr[0] is AND and \\\n           (_expr_depends_on(expr[1], sym) or\n            _expr_depends_on(expr[2], sym))\n\n\ndef _auto_menu_dep(node1, node2):\n    # Returns True if node2 has an \"automatic menu dependency\" on node1. If\n    # node2 has a prompt, we check its condition. Otherwise, we look directly\n    # at node2.dep.\n\n    return _expr_depends_on(node2.prompt[1] if node2.prompt else node2.dep,\n                            node1.item)\n\n\ndef _flatten(node):\n    # \"Flattens\" menu nodes without prompts (e.g. 'if' nodes and non-visible\n    # symbols with children from automatic menu creation) so that their\n    # children appear after them instead. This gives a clean menu structure\n    # with no unexpected \"jumps\" in the indentation.\n    #\n    # Do not flatten promptless choices (which can appear \"legitimately\" if a\n    # named choice is defined in multiple locations to add on symbols). It\n    # looks confusing, and the menuconfig already shows all choice symbols if\n    # you enter the choice at some location with a prompt.\n\n    while node:\n        if node.list and not node.prompt and \\\n           node.item.__class__ is not Choice:\n\n            last_node = node.list\n            while 1:\n                last_node.parent = node.parent\n                if not last_node.next:\n                    break\n                last_node = last_node.next\n\n            last_node.next = node.next\n            node.next = node.list\n            node.list = None\n\n        node = node.next\n\n\ndef _remove_ifs(node):\n    # Removes 'if' nodes (which can be recognized by MenuNode.item being None),\n    # which are assumed to already have been flattened. The C implementation\n    # doesn't bother to do this, but we expose the menu tree directly, and it\n    # makes it nicer to work with.\n\n    cur = node.list\n    while cur and not cur.item:\n        cur = cur.next\n\n    node.list = cur\n\n    while cur:\n        next = cur.next\n        while next and not next.item:\n            next = next.next\n\n        # Equivalent to\n        #\n        #   cur.next = next\n        #   cur = next\n        #\n        # due to tricky Python semantics. The order matters.\n        cur.next = cur = next\n\n\ndef _finalize_choice(node):\n    # Finalizes a choice, marking each symbol whose menu node has the choice as\n    # the parent as a choice symbol, and automatically determining types if not\n    # specified.\n\n    choice = node.item\n\n    cur = node.list\n    while cur:\n        if cur.item.__class__ is Symbol:\n            cur.item.choice = choice\n            choice.syms.append(cur.item)\n        cur = cur.next\n\n    # If no type is specified for the choice, its type is that of\n    # the first choice item with a specified type\n    if not choice.orig_type:\n        for item in choice.syms:\n            if item.orig_type:\n                choice.orig_type = item.orig_type\n                break\n\n    # Each choice item of UNKNOWN type gets the type of the choice\n    for sym in choice.syms:\n        if not sym.orig_type:\n            sym.orig_type = choice.orig_type\n\n\ndef _check_dep_loop_sym(sym, ignore_choice):\n    # Detects dependency loops using depth-first search on the dependency graph\n    # (which is calculated earlier in Kconfig._build_dep()).\n    #\n    # Algorithm:\n    #\n    #  1. Symbols/choices start out with _visited = 0, meaning unvisited.\n    #\n    #  2. When a symbol/choice is first visited, _visited is set to 1, meaning\n    #     \"visited, potentially part of a dependency loop\". The recursive\n    #     search then continues from the symbol/choice.\n    #\n    #  3. If we run into a symbol/choice X with _visited already set to 1,\n    #     there's a dependency loop. The loop is found on the call stack by\n    #     recording symbols while returning (\"on the way back\") until X is seen\n    #     again.\n    #\n    #  4. Once a symbol/choice and all its dependencies (or dependents in this\n    #     case) have been checked recursively without detecting any loops, its\n    #     _visited is set to 2, meaning \"visited, not part of a dependency\n    #     loop\".\n    #\n    #     This saves work if we run into the symbol/choice again in later calls\n    #     to _check_dep_loop_sym(). We just return immediately.\n    #\n    # Choices complicate things, as every choice symbol depends on every other\n    # choice symbol in a sense. When a choice is \"entered\" via a choice symbol\n    # X, we visit all choice symbols from the choice except X, and prevent\n    # immediately revisiting the choice with a flag (ignore_choice).\n    #\n    # Maybe there's a better way to handle this (different flags or the\n    # like...)\n\n    if not sym._visited:\n        # sym._visited == 0, unvisited\n\n        sym._visited = 1\n\n        for dep in sym._dependents:\n            # Choices show up in Symbol._dependents when the choice has the\n            # symbol in a 'prompt' or 'default' condition (e.g.\n            # 'default ... if SYM').\n            #\n            # Since we aren't entering the choice via a choice symbol, all\n            # choice symbols need to be checked, hence the None.\n            loop = _check_dep_loop_choice(dep, None) \\\n                   if dep.__class__ is Choice \\\n                   else _check_dep_loop_sym(dep, False)\n\n            if loop:\n                # Dependency loop found\n                return _found_dep_loop(loop, sym)\n\n        if sym.choice and not ignore_choice:\n            loop = _check_dep_loop_choice(sym.choice, sym)\n            if loop:\n                # Dependency loop found\n                return _found_dep_loop(loop, sym)\n\n        # The symbol is not part of a dependency loop\n        sym._visited = 2\n\n        # No dependency loop found\n        return None\n\n    if sym._visited == 2:\n        # The symbol was checked earlier and is already known to not be part of\n        # a dependency loop\n        return None\n\n    # sym._visited == 1, found a dependency loop. Return the symbol as the\n    # first element in it.\n    return (sym,)\n\n\ndef _check_dep_loop_choice(choice, skip):\n    if not choice._visited:\n        # choice._visited == 0, unvisited\n\n        choice._visited = 1\n\n        # Check for loops involving choice symbols. If we came here via a\n        # choice symbol, skip that one, as we'd get a false positive\n        # '<sym FOO> -> <choice> -> <sym FOO>' loop otherwise.\n        for sym in choice.syms:\n            if sym is not skip:\n                # Prevent the choice from being immediately re-entered via the\n                # \"is a choice symbol\" path by passing True\n                loop = _check_dep_loop_sym(sym, True)\n                if loop:\n                    # Dependency loop found\n                    return _found_dep_loop(loop, choice)\n\n        # The choice is not part of a dependency loop\n        choice._visited = 2\n\n        # No dependency loop found\n        return None\n\n    if choice._visited == 2:\n        # The choice was checked earlier and is already known to not be part of\n        # a dependency loop\n        return None\n\n    # choice._visited == 1, found a dependency loop. Return the choice as the\n    # first element in it.\n    return (choice,)\n\n\ndef _found_dep_loop(loop, cur):\n    # Called \"on the way back\" when we know we have a loop\n\n    # Is the symbol/choice 'cur' where the loop started?\n    if cur is not loop[0]:\n        # Nope, it's just a part of the loop\n        return loop + (cur,)\n\n    # Yep, we have the entire loop. Throw an exception that shows it.\n\n    msg = \"\\nDependency loop\\n\" \\\n            \"===============\\n\\n\"\n\n    for item in loop:\n        if item is not loop[0]:\n            msg += \"...depends on \"\n            if item.__class__ is Symbol and item.choice:\n                msg += \"the choice symbol \"\n\n        msg += \"{}, with definition...\\n\\n{}\\n\\n\" \\\n               .format(item.name_and_loc, item)\n\n        # Small wart: Since we reuse the already calculated\n        # Symbol/Choice._dependents sets for recursive dependency detection, we\n        # lose information on whether a dependency came from a 'select'/'imply'\n        # condition or e.g. a 'depends on'.\n        #\n        # This might cause selecting symbols to \"disappear\". For example,\n        # a symbol B having 'select A if C' gives a direct dependency from A to\n        # C, since it corresponds to a reverse dependency of B && C.\n        #\n        # Always print reverse dependencies for symbols that have them to make\n        # sure information isn't lost. I wonder if there's some neat way to\n        # improve this.\n\n        if item.__class__ is Symbol:\n            if item.rev_dep is not item.kconfig.n:\n                msg += \"(select-related dependencies: {})\\n\\n\" \\\n                       .format(expr_str(item.rev_dep))\n\n            if item.weak_rev_dep is not item.kconfig.n:\n                msg += \"(imply-related dependencies: {})\\n\\n\" \\\n                       .format(expr_str(item.rev_dep))\n\n    msg += \"...depends again on \" + loop[0].name_and_loc\n\n    raise KconfigError(msg)\n\n\ndef _decoding_error(e, filename, macro_linenr=None):\n    # Gives the filename and context for UnicodeDecodeError's, which are a pain\n    # to debug otherwise. 'e' is the UnicodeDecodeError object.\n    #\n    # If the decoding error is for the output of a $(shell,...) command,\n    # macro_linenr holds the line number where it was run (the exact line\n    # number isn't available for decoding errors in files).\n\n    raise KconfigError(\n        \"\\n\"\n        \"Malformed {} in {}\\n\"\n        \"Context: {}\\n\"\n        \"Problematic data: {}\\n\"\n        \"Reason: {}\".format(\n            e.encoding,\n            \"'{}'\".format(filename) if macro_linenr is None else\n                \"output from macro at {}:{}\".format(filename, macro_linenr),\n            e.object[max(e.start - 40, 0):e.end + 40],\n            e.object[e.start:e.end],\n            e.reason))\n\n\ndef _warn_verbose_deprecated(fn_name):\n    sys.stderr.write(\n        \"Deprecation warning: {0}()'s 'verbose' argument has no effect. Since \"\n        \"Kconfiglib 12.0.0, the message is returned from {0}() instead, \"\n        \"and is always generated. Do e.g. print(kconf.{0}()) if you want to \"\n        \"want to show a message like \\\"Loaded configuration '.config'\\\" on \"\n        \"stdout. The old API required ugly hacks to reuse messages in \"\n        \"configuration interfaces.\\n\".format(fn_name))\n\n\n# Predefined preprocessor functions\n\n\ndef _filename_fn(kconf, _):\n    return kconf.filename\n\n\ndef _lineno_fn(kconf, _):\n    return str(kconf.linenr)\n\n\ndef _info_fn(kconf, _, msg):\n    print(\"{}:{}: {}\".format(kconf.filename, kconf.linenr, msg))\n\n    return \"\"\n\n\ndef _warning_if_fn(kconf, _, cond, msg):\n    if cond == \"y\":\n        kconf._warn(msg, kconf.filename, kconf.linenr)\n\n    return \"\"\n\n\ndef _error_if_fn(kconf, _, cond, msg):\n    if cond == \"y\":\n        raise KconfigError(\"{}:{}: {}\".format(\n            kconf.filename, kconf.linenr, msg))\n\n    return \"\"\n\n\ndef _shell_fn(kconf, _, command):\n    # Only import as needed, to save some startup time\n    import subprocess\n\n    stdout, stderr = subprocess.Popen(\n        command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE\n    ).communicate()\n\n    if not _IS_PY2:\n        try:\n            stdout = stdout.decode(kconf._encoding)\n            stderr = stderr.decode(kconf._encoding)\n        except UnicodeDecodeError as e:\n            _decoding_error(e, kconf.filename, kconf.linenr)\n\n    if stderr:\n        kconf._warn(\"'{}' wrote to stderr: {}\".format(\n                        command, \"\\n\".join(stderr.splitlines())),\n                    kconf.filename, kconf.linenr)\n\n    # Universal newlines with splitlines() (to prevent e.g. stray \\r's in\n    # command output on Windows), trailing newline removal, and\n    # newline-to-space conversion.\n    #\n    # On Python 3 versions before 3.6, it's not possible to specify the\n    # encoding when passing universal_newlines=True to Popen() (the 'encoding'\n    # parameter was added in 3.6), so we do this manual version instead.\n    return \"\\n\".join(stdout.splitlines()).rstrip(\"\\n\").replace(\"\\n\", \" \")\n\n#\n# Global constants\n#\n\nTRI_TO_STR = {\n    0: \"n\",\n    1: \"m\",\n    2: \"y\",\n}\n\nSTR_TO_TRI = {\n    \"n\": 0,\n    \"m\": 1,\n    \"y\": 2,\n}\n\n# Constant representing that there's no cached choice selection. This is\n# distinct from a cached None (no selection). Any object that's not None or a\n# Symbol will do. We test this with 'is'.\n_NO_CACHED_SELECTION = 0\n\n# Are we running on Python 2?\n_IS_PY2 = sys.version_info[0] < 3\n\ntry:\n    _UNAME_RELEASE = os.uname()[2]\nexcept AttributeError:\n    # Only import as needed, to save some startup time\n    import platform\n    _UNAME_RELEASE = platform.uname()[2]\n\n# The token and type constants below are safe to test with 'is', which is a bit\n# faster (~30% faster on my machine, and a few % faster for total parsing\n# time), even without assuming Python's small integer optimization (which\n# caches small integer objects). The constants end up pointing to unique\n# integer objects, and since we consistently refer to them via the names below,\n# we always get the same object.\n#\n# Client code should use == though.\n\n# Tokens, with values 1, 2, ... . Avoiding 0 simplifies some checks by making\n# all tokens except empty strings truthy.\n(\n    _T_ALLNOCONFIG_Y,\n    _T_AND,\n    _T_BOOL,\n    _T_CHOICE,\n    _T_CLOSE_PAREN,\n    _T_COMMENT,\n    _T_CONFIG,\n    _T_DEFAULT,\n    _T_DEFCONFIG_LIST,\n    _T_DEF_BOOL,\n    _T_DEF_HEX,\n    _T_DEF_INT,\n    _T_DEF_STRING,\n    _T_DEF_TRISTATE,\n    _T_DEPENDS,\n    _T_ENDCHOICE,\n    _T_ENDIF,\n    _T_ENDMENU,\n    _T_ENV,\n    _T_EQUAL,\n    _T_GREATER,\n    _T_GREATER_EQUAL,\n    _T_HELP,\n    _T_HEX,\n    _T_IF,\n    _T_IMPLY,\n    _T_INT,\n    _T_LESS,\n    _T_LESS_EQUAL,\n    _T_MAINMENU,\n    _T_MENU,\n    _T_MENUCONFIG,\n    _T_MODULES,\n    _T_NOT,\n    _T_ON,\n    _T_OPEN_PAREN,\n    _T_OPTION,\n    _T_OPTIONAL,\n    _T_OR,\n    _T_ORSOURCE,\n    _T_OSOURCE,\n    _T_PROMPT,\n    _T_RANGE,\n    _T_RSOURCE,\n    _T_SELECT,\n    _T_SOURCE,\n    _T_STRING,\n    _T_TRISTATE,\n    _T_UNEQUAL,\n    _T_VISIBLE,\n) = range(1, 51)\n\n# Keyword to token map, with the get() method assigned directly as a small\n# optimization\n_get_keyword = {\n    \"---help---\":     _T_HELP,\n    \"allnoconfig_y\":  _T_ALLNOCONFIG_Y,\n    \"bool\":           _T_BOOL,\n    \"boolean\":        _T_BOOL,\n    \"choice\":         _T_CHOICE,\n    \"comment\":        _T_COMMENT,\n    \"config\":         _T_CONFIG,\n    \"def_bool\":       _T_DEF_BOOL,\n    \"def_hex\":        _T_DEF_HEX,\n    \"def_int\":        _T_DEF_INT,\n    \"def_string\":     _T_DEF_STRING,\n    \"def_tristate\":   _T_DEF_TRISTATE,\n    \"default\":        _T_DEFAULT,\n    \"defconfig_list\": _T_DEFCONFIG_LIST,\n    \"depends\":        _T_DEPENDS,\n    \"endchoice\":      _T_ENDCHOICE,\n    \"endif\":          _T_ENDIF,\n    \"endmenu\":        _T_ENDMENU,\n    \"env\":            _T_ENV,\n    \"grsource\":       _T_ORSOURCE,  # Backwards compatibility\n    \"gsource\":        _T_OSOURCE,   # Backwards compatibility\n    \"help\":           _T_HELP,\n    \"hex\":            _T_HEX,\n    \"if\":             _T_IF,\n    \"imply\":          _T_IMPLY,\n    \"int\":            _T_INT,\n    \"mainmenu\":       _T_MAINMENU,\n    \"menu\":           _T_MENU,\n    \"menuconfig\":     _T_MENUCONFIG,\n    \"modules\":        _T_MODULES,\n    \"on\":             _T_ON,\n    \"option\":         _T_OPTION,\n    \"optional\":       _T_OPTIONAL,\n    \"orsource\":       _T_ORSOURCE,\n    \"osource\":        _T_OSOURCE,\n    \"prompt\":         _T_PROMPT,\n    \"range\":          _T_RANGE,\n    \"rsource\":        _T_RSOURCE,\n    \"select\":         _T_SELECT,\n    \"source\":         _T_SOURCE,\n    \"string\":         _T_STRING,\n    \"tristate\":       _T_TRISTATE,\n    \"visible\":        _T_VISIBLE,\n}.get\n\n# The constants below match the value of the corresponding tokens to remove the\n# need for conversion\n\n# Node types\nMENU    = _T_MENU\nCOMMENT = _T_COMMENT\n\n# Expression types\nAND           = _T_AND\nOR            = _T_OR\nNOT           = _T_NOT\nEQUAL         = _T_EQUAL\nUNEQUAL       = _T_UNEQUAL\nLESS          = _T_LESS\nLESS_EQUAL    = _T_LESS_EQUAL\nGREATER       = _T_GREATER\nGREATER_EQUAL = _T_GREATER_EQUAL\n\nREL_TO_STR = {\n    EQUAL:         \"=\",\n    UNEQUAL:       \"!=\",\n    LESS:          \"<\",\n    LESS_EQUAL:    \"<=\",\n    GREATER:       \">\",\n    GREATER_EQUAL: \">=\",\n}\n\n# Symbol/choice types. UNKNOWN is 0 (falsy) to simplify some checks.\n# Client code shouldn't rely on it though, as it was non-zero in\n# older versions.\nUNKNOWN  = 0\nBOOL     = _T_BOOL\nTRISTATE = _T_TRISTATE\nSTRING   = _T_STRING\nINT      = _T_INT\nHEX      = _T_HEX\n\nTYPE_TO_STR = {\n    UNKNOWN:  \"unknown\",\n    BOOL:     \"bool\",\n    TRISTATE: \"tristate\",\n    STRING:   \"string\",\n    INT:      \"int\",\n    HEX:      \"hex\",\n}\n\n# Used in comparisons. 0 means the base is inferred from the format of the\n# string.\n_TYPE_TO_BASE = {\n    HEX:      16,\n    INT:      10,\n    STRING:   0,\n    UNKNOWN:  0,\n}\n\n# def_bool -> BOOL, etc.\n_DEF_TOKEN_TO_TYPE = {\n    _T_DEF_BOOL:     BOOL,\n    _T_DEF_HEX:      HEX,\n    _T_DEF_INT:      INT,\n    _T_DEF_STRING:   STRING,\n    _T_DEF_TRISTATE: TRISTATE,\n}\n\n# Tokens after which strings are expected. This is used to tell strings from\n# constant symbol references during tokenization, both of which are enclosed in\n# quotes.\n#\n# Identifier-like lexemes (\"missing quotes\") are also treated as strings after\n# these tokens. _T_CHOICE is included to avoid symbols being registered for\n# named choices.\n_STRING_LEX = frozenset({\n    _T_BOOL,\n    _T_CHOICE,\n    _T_COMMENT,\n    _T_HEX,\n    _T_INT,\n    _T_MAINMENU,\n    _T_MENU,\n    _T_ORSOURCE,\n    _T_OSOURCE,\n    _T_PROMPT,\n    _T_RSOURCE,\n    _T_SOURCE,\n    _T_STRING,\n    _T_TRISTATE,\n})\n\n# Various sets for quick membership tests. Gives a single global lookup and\n# avoids creating temporary dicts/tuples.\n\n_TYPE_TOKENS = frozenset({\n    _T_BOOL,\n    _T_TRISTATE,\n    _T_INT,\n    _T_HEX,\n    _T_STRING,\n})\n\n_SOURCE_TOKENS = frozenset({\n    _T_SOURCE,\n    _T_RSOURCE,\n    _T_OSOURCE,\n    _T_ORSOURCE,\n})\n\n_REL_SOURCE_TOKENS = frozenset({\n    _T_RSOURCE,\n    _T_ORSOURCE,\n})\n\n# Obligatory (non-optional) sources\n_OBL_SOURCE_TOKENS = frozenset({\n    _T_SOURCE,\n    _T_RSOURCE,\n})\n\n_BOOL_TRISTATE = frozenset({\n    BOOL,\n    TRISTATE,\n})\n\n_BOOL_TRISTATE_UNKNOWN = frozenset({\n    BOOL,\n    TRISTATE,\n    UNKNOWN,\n})\n\n_INT_HEX = frozenset({\n    INT,\n    HEX,\n})\n\n_SYMBOL_CHOICE = frozenset({\n    Symbol,\n    Choice,\n})\n\n_MENU_COMMENT = frozenset({\n    MENU,\n    COMMENT,\n})\n\n_EQUAL_UNEQUAL = frozenset({\n    EQUAL,\n    UNEQUAL,\n})\n\n_RELATIONS = frozenset({\n    EQUAL,\n    UNEQUAL,\n    LESS,\n    LESS_EQUAL,\n    GREATER,\n    GREATER_EQUAL,\n})\n\n# Helper functions for getting compiled regular expressions, with the needed\n# matching function returned directly as a small optimization.\n#\n# Use ASCII regex matching on Python 3. It's already the default on Python 2.\n\n\ndef _re_match(regex):\n    return re.compile(regex, 0 if _IS_PY2 else re.ASCII).match\n\n\ndef _re_search(regex):\n    return re.compile(regex, 0 if _IS_PY2 else re.ASCII).search\n\n\n# Various regular expressions used during parsing\n\n# The initial token on a line. Also eats leading and trailing whitespace, so\n# that we can jump straight to the next token (or to the end of the line if\n# there is only one token).\n#\n# This regex will also fail to match for empty lines and comment lines.\n#\n# '$' is included to detect preprocessor variable assignments with macro\n# expansions in the left-hand side.\n_command_match = _re_match(r\"\\s*([A-Za-z0-9_$-]+)\\s*\")\n\n# An identifier/keyword after the first token. Also eats trailing whitespace.\n# '$' is included to detect identifiers containing macro expansions.\n_id_keyword_match = _re_match(r\"([A-Za-z0-9_$/.-]+)\\s*\")\n\n# A fragment in the left-hand side of a preprocessor variable assignment. These\n# are the portions between macro expansions ($(foo)). Macros are supported in\n# the LHS (variable name).\n_assignment_lhs_fragment_match = _re_match(\"[A-Za-z0-9_-]*\")\n\n# The assignment operator and value (right-hand side) in a preprocessor\n# variable assignment\n_assignment_rhs_match = _re_match(r\"\\s*(=|:=|\\+=)\\s*(.*)\")\n\n# Special characters/strings while expanding a macro ('(', ')', ',', and '$(')\n_macro_special_search = _re_search(r\"\\(|\\)|,|\\$\\(\")\n\n# Special characters/strings while expanding a string (quotes, '\\', and '$(')\n_string_special_search = _re_search(r'\"|\\'|\\\\|\\$\\(')\n\n# Special characters/strings while expanding a symbol name. Also includes\n# end-of-line, in case the macro is the last thing on the line.\n_name_special_search = _re_search(r'[^A-Za-z0-9_$/.-]|\\$\\(|$')\n\n# A valid right-hand side for an assignment to a string symbol in a .config\n# file, including escaped characters. Extracts the contents.\n_conf_string_match = _re_match(r'\"((?:[^\\\\\"]|\\\\.)*)\"')\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/listnewconfig.py",
    "content": "#!/usr/bin/env python\n\n# Copyright (c) 2018-2019, Ulf Magnusson\n# SPDX-License-Identifier: ISC\n\n\"\"\"\nLists all user-modifiable symbols that are not given a value in the\nconfiguration file. Usually, these are new symbols that have been added to the\nKconfig files.\n\nThe default configuration filename is '.config'. A different filename can be\npassed in the KCONFIG_CONFIG environment variable.\n\"\"\"\nfrom __future__ import print_function\n\nimport argparse\nimport sys\n\nfrom kconfiglib import Kconfig, BOOL, TRISTATE, INT, HEX, STRING, TRI_TO_STR\n\n\ndef main():\n    parser = argparse.ArgumentParser(\n        formatter_class=argparse.RawDescriptionHelpFormatter,\n        description=__doc__)\n\n    parser.add_argument(\n        \"--show-help\", \"-l\",\n        action=\"store_true\",\n        help=\"Show any help texts as well\")\n\n    parser.add_argument(\n        \"kconfig\",\n        metavar=\"KCONFIG\",\n        nargs=\"?\",\n        default=\"Kconfig\",\n        help=\"Top-level Kconfig file (default: Kconfig)\")\n\n    args = parser.parse_args()\n\n    kconf = Kconfig(args.kconfig, suppress_traceback=True)\n    # Make it possible to filter this message out\n    print(kconf.load_config(), file=sys.stderr)\n\n    for sym in kconf.unique_defined_syms:\n        # Only show symbols that can be toggled. Choice symbols are a special\n        # case in that sym.assignable will be (2,) (length 1) for visible\n        # symbols in choices in y mode, but they can still be toggled by\n        # selecting some other symbol.\n        if sym.user_value is None and \\\n           (len(sym.assignable) > 1 or\n            (sym.visibility and (sym.orig_type in (INT, HEX, STRING) or\n                                 sym.choice))):\n\n            # Don't reuse the 'config_string' format for bool/tristate symbols,\n            # to show n-valued symbols as 'CONFIG_FOO=n' instead of\n            # '# CONFIG_FOO is not set'. This matches the C tools.\n            if sym.orig_type in (BOOL, TRISTATE):\n                s = \"{}{}={}\\n\".format(kconf.config_prefix, sym.name,\n                                       TRI_TO_STR[sym.tri_value])\n            else:\n                s = sym.config_string\n\n            print(s, end=\"\")\n            if args.show_help:\n                for node in sym.nodes:\n                    if node.help is not None:\n                        # Indent by two spaces. textwrap.indent() is not\n                        # available in Python 2 (it's 3.3+).\n                        print(\"\\n\".join(\"  \" + line\n                                        for line in node.help.split(\"\\n\")))\n                        break\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/menuconfig.py",
    "content": "#!/usr/bin/env python\n\n# Copyright (c) 2018-2019, Nordic Semiconductor ASA and Ulf Magnusson\n# SPDX-License-Identifier: ISC\n\n\"\"\"\nOverview\n========\n\nA curses-based Python 2/3 menuconfig implementation. The interface should feel\nfamiliar to people used to mconf ('make menuconfig').\n\nSupports the same keys as mconf, and also supports a set of keybindings\ninspired by Vi:\n\n  J/K     : Down/Up\n  L       : Enter menu/Toggle item\n  H       : Leave menu\n  Ctrl-D/U: Page Down/Page Up\n  G/End   : Jump to end of list\n  g/Home  : Jump to beginning of list\n\n[Space] toggles values if possible, and enters menus otherwise. [Enter] works\nthe other way around.\n\nThe mconf feature where pressing a key jumps to a menu entry with that\ncharacter in it in the current menu isn't supported. A jump-to feature for\njumping directly to any symbol (including invisible symbols), choice, menu or\ncomment (as in a Kconfig 'comment \"Foo\"') is available instead.\n\nA few different modes are available:\n\n  F: Toggle show-help mode, which shows the help text of the currently selected\n  item in the window at the bottom of the menu display. This is handy when\n  browsing through options.\n\n  C: Toggle show-name mode, which shows the symbol name before each symbol menu\n  entry\n\n  A: Toggle show-all mode, which shows all items, including currently invisible\n  items and items that lack a prompt. Invisible items are drawn in a different\n  style to make them stand out.\n\n\nRunning\n=======\n\nmenuconfig.py can be run either as a standalone executable or by calling the\nmenuconfig() function with an existing Kconfig instance. The second option is a\nbit inflexible in that it will still load and save .config, etc.\n\nWhen run in standalone mode, the top-level Kconfig file to load can be passed\nas a command-line argument. With no argument, it defaults to \"Kconfig\".\n\nThe KCONFIG_CONFIG environment variable specifies the .config file to load (if\nit exists) and save. If KCONFIG_CONFIG is unset, \".config\" is used.\n\nWhen overwriting a configuration file, the old version is saved to\n<filename>.old (e.g. .config.old).\n\n$srctree is supported through Kconfiglib.\n\n\nColor schemes\n=============\n\nIt is possible to customize the color scheme by setting the MENUCONFIG_STYLE\nenvironment variable. For example, setting it to 'aquatic' will enable an\nalternative, less yellow, more 'make menuconfig'-like color scheme, contributed\nby Mitja Horvat (pinkfluid).\n\nThis is the current list of built-in styles:\n    - default       classic Kconfiglib theme with a yellow accent\n    - monochrome    colorless theme (uses only bold and standout) attributes,\n                    this style is used if the terminal doesn't support colors\n    - aquatic       blue-tinted style loosely resembling the lxdialog theme\n\nIt is possible to customize the current style by changing colors of UI\nelements on the screen. This is the list of elements that can be stylized:\n\n    - path          Top row in the main display, with the menu path\n    - separator     Separator lines between windows. Also used for the top line\n                    in the symbol information display.\n    - list          List of items, e.g. the main display\n    - selection     Style for the selected item\n    - inv-list      Like list, but for invisible items. Used in show-all mode.\n    - inv-selection Like selection, but for invisible items. Used in show-all\n                    mode.\n    - help          Help text windows at the bottom of various fullscreen\n                    dialogs\n    - show-help     Window showing the help text in show-help mode\n    - frame         Frame around dialog boxes\n    - body          Body of dialog boxes\n    - edit          Edit box in pop-up dialogs\n    - jump-edit     Edit box in jump-to dialog\n    - text          Symbol information text\n\nThe color definition is a comma separated list of attributes:\n\n    - fg:COLOR      Set the foreground/background colors. COLOR can be one of\n      * or *        the basic 16 colors (black, red, green, yellow, blue,\n    - bg:COLOR      magenta, cyan, white and brighter versions, for example,\n                    brightred). On terminals that support more than 8 colors,\n                    you can also directly put in a color number, e.g. fg:123\n                    (hexadecimal and octal constants are accepted as well).\n                    Colors outside the range -1..curses.COLORS-1 (which is\n                    terminal-dependent) are ignored (with a warning). The COLOR\n                    can be also specified using a RGB value in the HTML\n                    notation, for example #RRGGBB. If the terminal supports\n                    color changing, the color is rendered accurately.\n                    Otherwise, the visually nearest color is used.\n\n                    If the background or foreground color of an element is not\n                    specified, it defaults to -1, representing the default\n                    terminal foreground or background color.\n\n                    Note: On some terminals a bright version of the color\n                    implies bold.\n    - bold          Use bold text\n    - underline     Use underline text\n    - standout      Standout text attribute (reverse color)\n\nMore often than not, some UI elements share the same color definition. In such\ncases the right value may specify an UI element from which the color definition\nwill be copied. For example, \"separator=help\" will apply the current color\ndefinition for \"help\" to \"separator\".\n\nA keyword without the '=' is assumed to be a style template. The template name\nis looked up in the built-in styles list and the style definition is expanded\nin-place. With this, built-in styles can be used as basis for new styles.\n\nFor example, take the aquatic theme and give it a red selection bar:\n\nMENUCONFIG_STYLE=\"aquatic selection=fg:white,bg:red\"\n\nIf there's an error in the style definition or if a missing style is assigned\nto, the assignment will be ignored, along with a warning being printed on\nstderr.\n\nThe 'default' theme is always implicitly parsed first, so the following two\nsettings have the same effect:\n\n    MENUCONFIG_STYLE=\"selection=fg:white,bg:red\"\n    MENUCONFIG_STYLE=\"default selection=fg:white,bg:red\"\n\nIf the terminal doesn't support colors, the 'monochrome' theme is used, and\nMENUCONFIG_STYLE is ignored. The assumption is that the environment is broken\nsomehow, and that the important thing is to get something usable.\n\n\nOther features\n==============\n\n  - Seamless terminal resizing\n\n  - No dependencies on *nix, as the 'curses' module is in the Python standard\n    library\n\n  - Unicode text entry\n\n  - Improved information screen compared to mconf:\n\n      * Expressions are split up by their top-level &&/|| operands to improve\n        readability\n\n      * Undefined symbols in expressions are pointed out\n\n      * Menus and comments have information displays\n\n      * Kconfig definitions are printed\n\n      * The include path is shown, listing the locations of the 'source'\n        statements that included the Kconfig file of the symbol (or other\n        item)\n\n\nLimitations\n===========\n\nDoesn't work out of the box on Windows, but can be made to work with\n\n    pip install windows-curses\n\nSee the https://github.com/zephyrproject-rtos/windows-curses repository.\n\"\"\"\nfrom __future__ import print_function\n\nimport os\nimport sys\n\n_IS_WINDOWS = os.name == \"nt\"  # Are we running on Windows?\n\ntry:\n    import curses\nexcept ImportError as e:\n    if not _IS_WINDOWS:\n        raise\n    sys.exit(\"\"\"\\\nmenuconfig failed to import the standard Python 'curses' library. Try\ninstalling a package like windows-curses\n(https://github.com/zephyrproject-rtos/windows-curses) by running this command\nin cmd.exe:\n\n    pip install windows-curses\n\nStarting with Kconfiglib 13.0.0, windows-curses is no longer automatically\ninstalled when installing Kconfiglib via pip on Windows (because it breaks\ninstallation on MSYS2).\n\nException:\n{}: {}\"\"\".format(type(e).__name__, e))\n\nimport errno\nimport locale\nimport re\nimport textwrap\n\nfrom kconfiglib import Symbol, Choice, MENU, COMMENT, MenuNode, \\\n                       BOOL, TRISTATE, STRING, INT, HEX, \\\n                       AND, OR, \\\n                       expr_str, expr_value, split_expr, \\\n                       standard_sc_expr_str, \\\n                       TRI_TO_STR, TYPE_TO_STR, \\\n                       standard_kconfig, standard_config_filename\n\n\n#\n# Configuration variables\n#\n\n# If True, try to change LC_CTYPE to a UTF-8 locale if it is set to the C\n# locale (which implies ASCII). This fixes curses Unicode I/O issues on systems\n# with bad defaults. ncurses configures itself from the locale settings.\n#\n# Related PEP: https://www.python.org/dev/peps/pep-0538/\n_CHANGE_C_LC_CTYPE_TO_UTF8 = True\n\n# How many steps an implicit submenu will be indented. Implicit submenus are\n# created when an item depends on the symbol before it. Note that symbols\n# defined with 'menuconfig' create a separate menu instead of indenting.\n_SUBMENU_INDENT = 4\n\n# Number of steps for Page Up/Down to jump\n_PG_JUMP = 6\n\n# Height of the help window in show-help mode\n_SHOW_HELP_HEIGHT = 8\n\n# How far the cursor needs to be from the edge of the window before it starts\n# to scroll. Used for the main menu display, the information display, the\n# search display, and for text boxes.\n_SCROLL_OFFSET = 5\n\n# Minimum width of dialogs that ask for text input\n_INPUT_DIALOG_MIN_WIDTH = 30\n\n# Number of arrows pointing up/down to draw when a window is scrolled\n_N_SCROLL_ARROWS = 14\n\n# Lines of help text shown at the bottom of the \"main\" display\n_MAIN_HELP_LINES = \"\"\"\n[Space/Enter] Toggle/enter  [ESC] Leave menu           [S] Save\n[O] Load                    [?] Symbol info            [/] Jump to symbol\n[F] Toggle show-help mode   [C] Toggle show-name mode  [A] Toggle show-all mode\n[Q] Quit (prompts for save) [D] Save minimal config (advanced)\n\"\"\"[1:-1].split(\"\\n\")\n\n# Lines of help text shown at the bottom of the information dialog\n_INFO_HELP_LINES = \"\"\"\n[ESC/q] Return to menu      [/] Jump to symbol\n\"\"\"[1:-1].split(\"\\n\")\n\n# Lines of help text shown at the bottom of the search dialog\n_JUMP_TO_HELP_LINES = \"\"\"\nType text to narrow the search. Regexes are supported (via Python's 're'\nmodule). The up/down cursor keys step in the list. [Enter] jumps to the\nselected symbol. [ESC] aborts the search. Type multiple space-separated\nstrings/regexes to find entries that match all of them. Type Ctrl-F to\nview the help of the selected item without leaving the dialog.\n\"\"\"[1:-1].split(\"\\n\")\n\n#\n# Styling\n#\n\n_STYLES = {\n    \"default\": \"\"\"\n    path=fg:black,bg:white,bold\n    separator=fg:black,bg:yellow,bold\n    list=fg:black,bg:white\n    selection=fg:white,bg:blue,bold\n    inv-list=fg:red,bg:white\n    inv-selection=fg:red,bg:blue\n    help=path\n    show-help=list\n    frame=fg:black,bg:yellow,bold\n    body=fg:white,bg:black\n    edit=fg:white,bg:blue\n    jump-edit=edit\n    text=list\n    \"\"\",\n\n    # This style is forced on terminals that do no support colors\n    \"monochrome\": \"\"\"\n    path=bold\n    separator=bold,standout\n    list=\n    selection=bold,standout\n    inv-list=bold\n    inv-selection=bold,standout\n    help=bold\n    show-help=\n    frame=bold,standout\n    body=\n    edit=standout\n    jump-edit=\n    text=\n    \"\"\",\n\n    # Blue-tinted style loosely resembling lxdialog\n    \"aquatic\": \"\"\"\n    path=fg:white,bg:blue\n    separator=fg:white,bg:cyan\n    help=path\n    frame=fg:white,bg:cyan\n    body=fg:white,bg:blue\n    edit=fg:black,bg:white\n    \"\"\"\n}\n\n_NAMED_COLORS = {\n    # Basic colors\n    \"black\":         curses.COLOR_BLACK,\n    \"red\":           curses.COLOR_RED,\n    \"green\":         curses.COLOR_GREEN,\n    \"yellow\":        curses.COLOR_YELLOW,\n    \"blue\":          curses.COLOR_BLUE,\n    \"magenta\":       curses.COLOR_MAGENTA,\n    \"cyan\":          curses.COLOR_CYAN,\n    \"white\":         curses.COLOR_WHITE,\n\n    # Bright versions\n    \"brightblack\":   curses.COLOR_BLACK + 8,\n    \"brightred\":     curses.COLOR_RED + 8,\n    \"brightgreen\":   curses.COLOR_GREEN + 8,\n    \"brightyellow\":  curses.COLOR_YELLOW + 8,\n    \"brightblue\":    curses.COLOR_BLUE + 8,\n    \"brightmagenta\": curses.COLOR_MAGENTA + 8,\n    \"brightcyan\":    curses.COLOR_CYAN + 8,\n    \"brightwhite\":   curses.COLOR_WHITE + 8,\n\n    # Aliases\n    \"purple\":        curses.COLOR_MAGENTA,\n    \"brightpurple\":  curses.COLOR_MAGENTA + 8,\n}\n\n\ndef _rgb_to_6cube(rgb):\n    # Converts an 888 RGB color to a 3-tuple (nice in that it's hashable)\n    # representing the closest xterm 256-color 6x6x6 color cube color.\n    #\n    # The xterm 256-color extension uses a RGB color palette with components in\n    # the range 0-5 (a 6x6x6 cube). The catch is that the mapping is nonlinear.\n    # Index 0 in the 6x6x6 cube is mapped to 0, index 1 to 95, then 135, 175,\n    # etc., in increments of 40. See the links below:\n    #\n    #   https://commons.wikimedia.org/wiki/File:Xterm_256color_chart.svg\n    #   https://github.com/tmux/tmux/blob/master/colour.c\n\n    # 48 is the middle ground between 0 and 95.\n    return tuple(0 if x < 48 else int(round(max(1, (x - 55)/40))) for x in rgb)\n\n\ndef _6cube_to_rgb(r6g6b6):\n    # Returns the 888 RGB color for a 666 xterm color cube index\n\n    return tuple(0 if x == 0 else 40*x + 55 for x in r6g6b6)\n\n\ndef _rgb_to_gray(rgb):\n    # Converts an 888 RGB color to the index of an xterm 256-color grayscale\n    # color with approx. the same perceived brightness\n\n    # Calculate the luminance (gray intensity) of the color. See\n    #   https://stackoverflow.com/questions/596216/formula-to-determine-brightness-of-rgb-color\n    # and\n    #   https://www.w3.org/TR/AERT/#color-contrast\n    luma = 0.299*rgb[0] + 0.587*rgb[1] + 0.114*rgb[2]\n\n    # Closest index in the grayscale palette, which starts at RGB 0x080808,\n    # with stepping 0x0A0A0A\n    index = int(round((luma - 8)/10))\n\n    # Clamp the index to 0-23, corresponding to 232-255\n    return max(0, min(index, 23))\n\n\ndef _gray_to_rgb(index):\n    # Convert a grayscale index to its closet single RGB component\n\n    return 3*(10*index + 8,)  # Returns a 3-tuple\n\n\n# Obscure Python: We never pass a value for rgb2index, and it keeps pointing to\n# the same dict. This avoids a global.\ndef _alloc_rgb(rgb, rgb2index={}):\n    # Initialize a new entry in the xterm palette to the given RGB color,\n    # returning its index. If the color has already been initialized, the index\n    # of the existing entry is returned.\n    #\n    # ncurses is palette-based, so we need to overwrite palette entries to make\n    # new colors.\n    #\n    # The colors from 0 to 15 are user-defined, and there's no way to query\n    # their RGB values, so we better leave them untouched. Also leave any\n    # hypothetical colors above 255 untouched (though we're unlikely to\n    # allocate that many colors anyway).\n\n    if rgb in rgb2index:\n        return rgb2index[rgb]\n\n    # Many terminals allow the user to customize the first 16 colors. Avoid\n    # changing their values.\n    color_index = 16 + len(rgb2index)\n    if color_index >= 256:\n        _warn(\"Unable to allocate new RGB color \", rgb, \". Too many colors \"\n              \"allocated.\")\n        return 0\n\n    # Map each RGB component from the range 0-255 to the range 0-1000, which is\n    # what curses uses\n    curses.init_color(color_index, *(int(round(1000*x/255)) for x in rgb))\n    rgb2index[rgb] = color_index\n\n    return color_index\n\n\ndef _color_from_num(num):\n    # Returns the index of a color that looks like color 'num' in the xterm\n    # 256-color palette (but that might not be 'num', if we're redefining\n    # colors)\n\n    # - _alloc_rgb() won't touch the first 16 colors or any (hypothetical)\n    #   colors above 255, so we can always return them as-is\n    #\n    # - If the terminal doesn't support changing color definitions, or if\n    #   curses.COLORS < 256, _alloc_rgb() won't touch any color, and all colors\n    #   can be returned as-is\n    if num < 16 or num > 255 or not curses.can_change_color() or \\\n       curses.COLORS < 256:\n        return num\n\n    # _alloc_rgb() might redefine colors, so emulate the xterm 256-color\n    # palette by allocating new colors instead of returning color numbers\n    # directly\n\n    if num < 232:\n        num -= 16\n        return _alloc_rgb(_6cube_to_rgb(((num//36)%6, (num//6)%6, num%6)))\n\n    return _alloc_rgb(_gray_to_rgb(num - 232))\n\n\ndef _color_from_rgb(rgb):\n    # Returns the index of a color matching the 888 RGB color 'rgb'. The\n    # returned color might be an ~exact match or an approximation, depending on\n    # terminal capabilities.\n\n    # Calculates the Euclidean distance between two RGB colors\n    def dist(r1, r2): return sum((x - y)**2 for x, y in zip(r1, r2))\n\n    if curses.COLORS >= 256:\n        # Assume we're dealing with xterm's 256-color extension\n\n        if curses.can_change_color():\n            # Best case -- the terminal supports changing palette entries via\n            # curses.init_color(). Initialize an unused palette entry and\n            # return it.\n            return _alloc_rgb(rgb)\n\n        # Second best case -- pick between the xterm 256-color extension colors\n\n        # Closest 6-cube \"color\" color\n        c6 = _rgb_to_6cube(rgb)\n        # Closest gray color\n        gray = _rgb_to_gray(rgb)\n\n        if dist(rgb, _6cube_to_rgb(c6)) < dist(rgb, _gray_to_rgb(gray)):\n            # Use the \"color\" color from the 6x6x6 color palette. Calculate the\n            # color number from the 6-cube index triplet.\n            return 16 + 36*c6[0] + 6*c6[1] + c6[2]\n\n        # Use the color from the gray palette\n        return 232 + gray\n\n    # Terminal not in xterm 256-color mode. This is probably the best we can\n    # do, or is it? Submit patches. :)\n    min_dist = float('inf')\n    best = -1\n    for color in range(curses.COLORS):\n        # ncurses uses the range 0..1000. Scale that down to 0..255.\n        d = dist(rgb, tuple(int(round(255*c/1000))\n                            for c in curses.color_content(color)))\n        if d < min_dist:\n            min_dist = d\n            best = color\n\n    return best\n\n\ndef _parse_style(style_str, parsing_default):\n    # Parses a string with '<element>=<style>' assignments. Anything not\n    # containing '=' is assumed to be a reference to a built-in style, which is\n    # treated as if all the assignments from the style were inserted at that\n    # point in the string.\n    #\n    # The parsing_default flag is set to True when we're implicitly parsing the\n    # 'default'/'monochrome' style, to prevent warnings.\n\n    for sline in style_str.split():\n        # Words without a \"=\" character represents a style template\n        if \"=\" in sline:\n            key, data = sline.split(\"=\", 1)\n\n            # The 'default' style template is assumed to define all keys. We\n            # run _style_to_curses() for non-existing keys as well, so that we\n            # print warnings for errors to the right of '=' for those too.\n            if key not in _style and not parsing_default:\n                _warn(\"Ignoring non-existent style\", key)\n\n            # If data is a reference to another key, copy its style\n            if data in _style:\n                _style[key] = _style[data]\n            else:\n                _style[key] = _style_to_curses(data)\n\n        elif sline in _STYLES:\n            # Recursively parse style template. Ignore styles that don't exist,\n            # for backwards/forwards compatibility.\n            _parse_style(_STYLES[sline], parsing_default)\n\n        else:\n            _warn(\"Ignoring non-existent style template\", sline)\n\n# Dictionary mapping element types to the curses attributes used to display\n# them\n_style = {}\n\n\ndef _style_to_curses(style_def):\n    # Parses a style definition string (<element>=<style>), returning\n    # a (fg_color, bg_color, attributes) tuple.\n\n    def parse_color(color_def):\n        color_def = color_def.split(\":\", 1)[1]\n\n        # HTML format, #RRGGBB\n        if re.match(\"#[A-Fa-f0-9]{6}\", color_def):\n            return _color_from_rgb((\n                int(color_def[1:3], 16),\n                int(color_def[3:5], 16),\n                int(color_def[5:7], 16)))\n\n        if color_def in _NAMED_COLORS:\n            color_num = _color_from_num(_NAMED_COLORS[color_def])\n        else:\n            try:\n                color_num = _color_from_num(int(color_def, 0))\n            except ValueError:\n                _warn(\"Ignoring color\", color_def, \"that's neither \"\n                      \"predefined nor a number\")\n                return -1\n\n        if not -1 <= color_num < curses.COLORS:\n            _warn(\"Ignoring color {}, which is outside the range \"\n                  \"-1..curses.COLORS-1 (-1..{})\"\n                  .format(color_def, curses.COLORS - 1))\n            return -1\n\n        return color_num\n\n    fg_color = -1\n    bg_color = -1\n    attrs = 0\n\n    if style_def:\n        for field in style_def.split(\",\"):\n            if field.startswith(\"fg:\"):\n                fg_color = parse_color(field)\n            elif field.startswith(\"bg:\"):\n                bg_color = parse_color(field)\n            elif field == \"bold\":\n                # A_BOLD tends to produce faint and hard-to-read text on the\n                # Windows console, especially with the old color scheme, before\n                # the introduction of\n                # https://blogs.msdn.microsoft.com/commandline/2017/08/02/updating-the-windows-console-colors/\n                attrs |= curses.A_NORMAL if _IS_WINDOWS else curses.A_BOLD\n            elif field == \"standout\":\n                attrs |= curses.A_STANDOUT\n            elif field == \"underline\":\n                attrs |= curses.A_UNDERLINE\n            else:\n                _warn(\"Ignoring unknown style attribute\", field)\n\n    return _style_attr(fg_color, bg_color, attrs)\n\n\ndef _init_styles():\n    if curses.has_colors():\n        try:\n            curses.use_default_colors()\n        except curses.error:\n            # Ignore errors on funky terminals that support colors but not\n            # using default colors. Worst it can do is break transparency and\n            # the like. Ran across this with the MSYS2/winpty setup in\n            # https://github.com/msys2/MINGW-packages/issues/5823, though there\n            # seems to be a lot of general brokenness there.\n            pass\n\n        # Use the 'default' theme as the base, and add any user-defined style\n        # settings from the environment\n        _parse_style(\"default\", True)\n        if \"MENUCONFIG_STYLE\" in os.environ:\n            _parse_style(os.environ[\"MENUCONFIG_STYLE\"], False)\n    else:\n        # Force the 'monochrome' theme if the terminal doesn't support colors.\n        # MENUCONFIG_STYLE is likely to mess things up here (though any colors\n        # would be ignored), so ignore it.\n        _parse_style(\"monochrome\", True)\n\n\n# color_attribs holds the color pairs we've already created, indexed by a\n# (<foreground color>, <background color>) tuple.\n#\n# Obscure Python: We never pass a value for color_attribs, and it keeps\n# pointing to the same dict. This avoids a global.\ndef _style_attr(fg_color, bg_color, attribs, color_attribs={}):\n    # Returns an attribute with the specified foreground and background color\n    # and the attributes in 'attribs'. Reuses color pairs already created if\n    # possible, and creates a new color pair otherwise.\n    #\n    # Returns 'attribs' if colors aren't supported.\n\n    if not curses.has_colors():\n        return attribs\n\n    if (fg_color, bg_color) not in color_attribs:\n        # Create new color pair. Color pair number 0 is hardcoded and cannot be\n        # changed, hence the +1s.\n        curses.init_pair(len(color_attribs) + 1, fg_color, bg_color)\n        color_attribs[(fg_color, bg_color)] = \\\n            curses.color_pair(len(color_attribs) + 1)\n\n    return color_attribs[(fg_color, bg_color)] | attribs\n\n\n#\n# Main application\n#\n\n\ndef _main():\n    menuconfig(standard_kconfig(__doc__))\n\n\ndef menuconfig(kconf):\n    \"\"\"\n    Launches the configuration interface, returning after the user exits.\n\n    kconf:\n      Kconfig instance to be configured\n    \"\"\"\n    global _kconf\n    global _conf_filename\n    global _conf_changed\n    global _minconf_filename\n    global _show_all\n\n    _kconf = kconf\n\n    # Filename to save configuration to\n    _conf_filename = standard_config_filename()\n\n    # Load existing configuration and set _conf_changed True if it is outdated\n    _conf_changed = _load_config()\n\n    # Filename to save minimal configuration to\n    _minconf_filename = \"defconfig\"\n\n    # Any visible items in the top menu?\n    _show_all = False\n    if not _shown_nodes(kconf.top_node):\n        # Nothing visible. Start in show-all mode and try again.\n        _show_all = True\n        if not _shown_nodes(kconf.top_node):\n            # Give up. The implementation relies on always having a selected\n            # node.\n            print(\"Empty configuration -- nothing to configure.\\n\"\n                  \"Check that environment variables are set properly.\")\n            return\n\n    # Disable warnings. They get mangled in curses mode, and we deal with\n    # errors ourselves.\n    kconf.warn = False\n\n    # Make curses use the locale settings specified in the environment\n    locale.setlocale(locale.LC_ALL, \"\")\n\n    # Try to fix Unicode issues on systems with bad defaults\n    if _CHANGE_C_LC_CTYPE_TO_UTF8:\n        _change_c_lc_ctype_to_utf8()\n\n    # Get rid of the delay between pressing ESC and jumping to the parent menu,\n    # unless the user has set ESCDELAY (see ncurses(3)). This makes the UI much\n    # smoother to work with.\n    #\n    # Note: This is strictly pretty iffy, since escape codes for e.g. cursor\n    # keys start with ESC, but I've never seen it cause problems in practice\n    # (probably because it's unlikely that the escape code for a key would get\n    # split up across read()s, at least with a terminal emulator). Please\n    # report if you run into issues. Some suitable small default value could be\n    # used here instead in that case. Maybe it's silly to not put in the\n    # smallest imperceptible delay here already, though I don't like guessing.\n    #\n    # (From a quick glance at the ncurses source code, ESCDELAY might only be\n    # relevant for mouse events there, so maybe escapes are assumed to arrive\n    # in one piece already...)\n    os.environ.setdefault(\"ESCDELAY\", \"0\")\n\n    # Enter curses mode. _menuconfig() returns a string to print on exit, after\n    # curses has been de-initialized.\n    print(curses.wrapper(_menuconfig))\n\n\ndef _load_config():\n    # Loads any existing .config file. See the Kconfig.load_config() docstring.\n    #\n    # Returns True if .config is missing or outdated. We always prompt for\n    # saving the configuration in that case.\n\n    print(_kconf.load_config())\n    if not os.path.exists(_conf_filename):\n        # No .config\n        return True\n\n    return _needs_save()\n\n\ndef _needs_save():\n    # Returns True if a just-loaded .config file is outdated (would get\n    # modified when saving)\n\n    if _kconf.missing_syms:\n        # Assignments to undefined symbols in the .config\n        return True\n\n    for sym in _kconf.unique_defined_syms:\n        if sym.user_value is None:\n            if sym.config_string:\n                # Unwritten symbol\n                return True\n        elif sym.orig_type in (BOOL, TRISTATE):\n            if sym.tri_value != sym.user_value:\n                # Written bool/tristate symbol, new value\n                return True\n        elif sym.str_value != sym.user_value:\n            # Written string/int/hex symbol, new value\n            return True\n\n    # No need to prompt for save\n    return False\n\n\n# Global variables used below:\n#\n#   _stdscr:\n#     stdscr from curses\n#\n#   _cur_menu:\n#     Menu node of the menu (or menuconfig symbol, or choice) currently being\n#     shown\n#\n#   _shown:\n#     List of items in _cur_menu that are shown (ignoring scrolling). In\n#     show-all mode, this list contains all items in _cur_menu. Otherwise, it\n#     contains just the visible items.\n#\n#   _sel_node_i:\n#     Index in _shown of the currently selected node\n#\n#   _menu_scroll:\n#     Index in _shown of the top row of the main display\n#\n#   _parent_screen_rows:\n#     List/stack of the row numbers that the selections in the parent menus\n#     appeared on. This is used to prevent the scrolling from jumping around\n#     when going in and out of menus.\n#\n#   _show_help/_show_name/_show_all:\n#     If True, the corresponding mode is on. See the module docstring.\n#\n#   _conf_filename:\n#     File to save the configuration to\n#\n#   _minconf_filename:\n#     File to save minimal configurations to\n#\n#   _conf_changed:\n#     True if the configuration has been changed. If False, we don't bother\n#     showing the save-and-quit dialog.\n#\n#     We reset this to False whenever the configuration is saved explicitly\n#     from the save dialog.\n\n\ndef _menuconfig(stdscr):\n    # Logic for the main display, with the list of symbols, etc.\n\n    global _stdscr\n    global _conf_filename\n    global _conf_changed\n    global _minconf_filename\n    global _show_help\n    global _show_name\n\n    _stdscr = stdscr\n\n    _init()\n\n    while True:\n        _draw_main()\n        curses.doupdate()\n\n\n        c = _getch_compat(_menu_win)\n\n        if c == curses.KEY_RESIZE:\n            _resize_main()\n\n        elif c in (curses.KEY_DOWN, \"j\", \"J\"):\n            _select_next_menu_entry()\n\n        elif c in (curses.KEY_UP, \"k\", \"K\"):\n            _select_prev_menu_entry()\n\n        elif c in (curses.KEY_NPAGE, \"\\x04\"):  # Page Down/Ctrl-D\n            # Keep it simple. This way we get sane behavior for small windows,\n            # etc., for free.\n            for _ in range(_PG_JUMP):\n                _select_next_menu_entry()\n\n        elif c in (curses.KEY_PPAGE, \"\\x15\"):  # Page Up/Ctrl-U\n            for _ in range(_PG_JUMP):\n                _select_prev_menu_entry()\n\n        elif c in (curses.KEY_END, \"G\"):\n            _select_last_menu_entry()\n\n        elif c in (curses.KEY_HOME, \"g\"):\n            _select_first_menu_entry()\n\n        elif c == \" \":\n            # Toggle the node if possible\n            sel_node = _shown[_sel_node_i]\n            if not _change_node(sel_node):\n                _enter_menu(sel_node)\n\n        elif c in (curses.KEY_RIGHT, \"\\n\", \"l\", \"L\"):\n            # Enter the node if possible\n            sel_node = _shown[_sel_node_i]\n            if not _enter_menu(sel_node):\n                _change_node(sel_node)\n\n        elif c in (\"n\", \"N\"):\n            _set_sel_node_tri_val(0)\n\n        elif c in (\"m\", \"M\"):\n            _set_sel_node_tri_val(1)\n\n        elif c in (\"y\", \"Y\"):\n            _set_sel_node_tri_val(2)\n\n        elif c in (curses.KEY_LEFT, curses.KEY_BACKSPACE, _ERASE_CHAR,\n                   \"\\x1B\", \"h\", \"H\"):  # \\x1B = ESC\n\n            if c == \"\\x1B\" and _cur_menu is _kconf.top_node:\n                res = _quit_dialog()\n                if res:\n                    return res\n            else:\n                _leave_menu()\n\n        elif c in (\"o\", \"O\"):\n            _load_dialog()\n\n        elif c in (\"s\", \"S\"):\n            filename = _save_dialog(_kconf.write_config, _conf_filename,\n                                    \"configuration\")\n            if filename:\n                _conf_filename = filename\n                _conf_changed = False\n\n        elif c in (\"d\", \"D\"):\n            filename = _save_dialog(_kconf.write_min_config, _minconf_filename,\n                                    \"minimal configuration\")\n            if filename:\n                _minconf_filename = filename\n\n        elif c == \"/\":\n            _jump_to_dialog()\n            # The terminal might have been resized while the fullscreen jump-to\n            # dialog was open\n            _resize_main()\n\n        elif c == \"?\":\n            _info_dialog(_shown[_sel_node_i], False)\n            # The terminal might have been resized while the fullscreen info\n            # dialog was open\n            _resize_main()\n\n        elif c in (\"f\", \"F\"):\n            _show_help = not _show_help\n            _set_style(_help_win, \"show-help\" if _show_help else \"help\")\n            _resize_main()\n\n        elif c in (\"c\", \"C\"):\n            _show_name = not _show_name\n\n        elif c in (\"a\", \"A\"):\n            _toggle_show_all()\n\n        elif c in (\"q\", \"Q\"):\n            res = _quit_dialog()\n            if res:\n                return res\n\n\ndef _quit_dialog():\n    if not _conf_changed:\n        return \"No changes to save (for '{}')\".format(_conf_filename)\n\n    while True:\n        c = _key_dialog(\n            \"Quit\",\n            \" Save configuration?\\n\"\n            \"\\n\"\n            \"(Y)es  (N)o  (C)ancel\",\n            \"ync\")\n\n        if c is None or c == \"c\":\n            return None\n\n        if c == \"y\":\n            # Returns a message to print\n            msg = _try_save(_kconf.write_config, _conf_filename, \"configuration\")\n            if msg:\n                return msg\n\n        elif c == \"n\":\n            return \"Configuration ({}) was not saved\".format(_conf_filename)\n\n\ndef _init():\n    # Initializes the main display with the list of symbols, etc. Also does\n    # misc. global initialization that needs to happen after initializing\n    # curses.\n\n    global _ERASE_CHAR\n\n    global _path_win\n    global _top_sep_win\n    global _menu_win\n    global _bot_sep_win\n    global _help_win\n\n    global _parent_screen_rows\n    global _cur_menu\n    global _shown\n    global _sel_node_i\n    global _menu_scroll\n\n    global _show_help\n    global _show_name\n\n    # Looking for this in addition to KEY_BACKSPACE (which is unreliable) makes\n    # backspace work with TERM=vt100. That makes it likely to work in sane\n    # environments.\n    _ERASE_CHAR = curses.erasechar()\n    if sys.version_info[0] >= 3:\n        # erasechar() returns a one-byte bytes object on Python 3. This sets\n        # _ERASE_CHAR to a blank string if it can't be decoded, which should be\n        # harmless.\n        _ERASE_CHAR = _ERASE_CHAR.decode(\"utf-8\", \"ignore\")\n\n    _init_styles()\n\n    # Hide the cursor\n    _safe_curs_set(0)\n\n    # Initialize windows\n\n    # Top row, with menu path\n    _path_win = _styled_win(\"path\")\n\n    # Separator below menu path, with title and arrows pointing up\n    _top_sep_win = _styled_win(\"separator\")\n\n    # List of menu entries with symbols, etc.\n    _menu_win = _styled_win(\"list\")\n    _menu_win.keypad(True)\n\n    # Row below menu list, with arrows pointing down\n    _bot_sep_win = _styled_win(\"separator\")\n\n    # Help window with keys at the bottom. Shows help texts in show-help mode.\n    _help_win = _styled_win(\"help\")\n\n    # The rows we'd like the nodes in the parent menus to appear on. This\n    # prevents the scroll from jumping around when going in and out of menus.\n    _parent_screen_rows = []\n\n    # Initial state\n\n    _cur_menu = _kconf.top_node\n    _shown = _shown_nodes(_cur_menu)\n    _sel_node_i = _menu_scroll = 0\n\n    _show_help = _show_name = False\n\n    # Give windows their initial size\n    _resize_main()\n\n\ndef _resize_main():\n    # Resizes the main display, with the list of symbols, etc., to fill the\n    # terminal\n\n    global _menu_scroll\n\n    screen_height, screen_width = _stdscr.getmaxyx()\n\n    _path_win.resize(1, screen_width)\n    _top_sep_win.resize(1, screen_width)\n    _bot_sep_win.resize(1, screen_width)\n\n    help_win_height = _SHOW_HELP_HEIGHT if _show_help else \\\n        len(_MAIN_HELP_LINES)\n\n    menu_win_height = screen_height - help_win_height - 3\n\n    if menu_win_height >= 1:\n        _menu_win.resize(menu_win_height, screen_width)\n        _help_win.resize(help_win_height, screen_width)\n\n        _top_sep_win.mvwin(1, 0)\n        _menu_win.mvwin(2, 0)\n        _bot_sep_win.mvwin(2 + menu_win_height, 0)\n        _help_win.mvwin(2 + menu_win_height + 1, 0)\n    else:\n        # Degenerate case. Give up on nice rendering and just prevent errors.\n\n        menu_win_height = 1\n\n        _menu_win.resize(1, screen_width)\n        _help_win.resize(1, screen_width)\n\n        for win in _top_sep_win, _menu_win, _bot_sep_win, _help_win:\n            win.mvwin(0, 0)\n\n    # Adjust the scroll so that the selected node is still within the window,\n    # if needed\n    if _sel_node_i - _menu_scroll >= menu_win_height:\n        _menu_scroll = _sel_node_i - menu_win_height + 1\n\n\ndef _height(win):\n    # Returns the height of 'win'\n\n    return win.getmaxyx()[0]\n\n\ndef _width(win):\n    # Returns the width of 'win'\n\n    return win.getmaxyx()[1]\n\n\ndef _enter_menu(menu):\n    # Makes 'menu' the currently displayed menu. In addition to actual 'menu's,\n    # \"menu\" here includes choices and symbols defined with the 'menuconfig'\n    # keyword.\n    #\n    # Returns False if 'menu' can't be entered.\n\n    global _cur_menu\n    global _shown\n    global _sel_node_i\n    global _menu_scroll\n\n    if not menu.is_menuconfig:\n        # Not a menu\n        return False\n\n    shown_sub = _shown_nodes(menu)\n    # Never enter empty menus. We depend on having a current node.\n    if not shown_sub:\n        return False\n\n    # Remember where the current node appears on the screen, so we can try\n    # to get it to appear in the same place when we leave the menu\n    _parent_screen_rows.append(_sel_node_i - _menu_scroll)\n\n    # Jump into menu\n    _cur_menu = menu\n    _shown = shown_sub\n    _sel_node_i = _menu_scroll = 0\n\n    if isinstance(menu.item, Choice):\n        _select_selected_choice_sym()\n\n    return True\n\n\ndef _select_selected_choice_sym():\n    # Puts the cursor on the currently selected (y-valued) choice symbol, if\n    # any. Does nothing if if the choice has no selection (is not visible/in y\n    # mode).\n\n    global _sel_node_i\n\n    choice = _cur_menu.item\n    if choice.selection:\n        # Search through all menu nodes to handle choice symbols being defined\n        # in multiple locations\n        for node in choice.selection.nodes:\n            if node in _shown:\n                _sel_node_i = _shown.index(node)\n                _center_vertically()\n                return\n\n\ndef _jump_to(node):\n    # Jumps directly to the menu node 'node'\n\n    global _cur_menu\n    global _shown\n    global _sel_node_i\n    global _menu_scroll\n    global _show_all\n    global _parent_screen_rows\n\n    # Clear remembered menu locations. We might not even have been in the\n    # parent menus before.\n    _parent_screen_rows = []\n\n    old_show_all = _show_all\n    jump_into = (isinstance(node.item, Choice) or node.item == MENU) and \\\n                node.list\n\n    # If we're jumping to a non-empty choice or menu, jump to the first entry\n    # in it instead of jumping to its menu node\n    if jump_into:\n        _cur_menu = node\n        node = node.list\n    else:\n        _cur_menu = _parent_menu(node)\n\n    _shown = _shown_nodes(_cur_menu)\n    if node not in _shown:\n        # The node wouldn't be shown. Turn on show-all to show it.\n        _show_all = True\n        _shown = _shown_nodes(_cur_menu)\n\n    _sel_node_i = _shown.index(node)\n\n    if jump_into and not old_show_all and _show_all:\n        # If we're jumping into a choice or menu and were forced to turn on\n        # show-all because the first entry wasn't visible, try turning it off.\n        # That will land us at the first visible node if there are visible\n        # nodes, and is a no-op otherwise.\n        _toggle_show_all()\n\n    _center_vertically()\n\n    # If we're jumping to a non-empty choice, jump to the selected symbol, if\n    # any\n    if jump_into and isinstance(_cur_menu.item, Choice):\n        _select_selected_choice_sym()\n\n\ndef _leave_menu():\n    # Jumps to the parent menu of the current menu. Does nothing if we're in\n    # the top menu.\n\n    global _cur_menu\n    global _shown\n    global _sel_node_i\n    global _menu_scroll\n\n    if _cur_menu is _kconf.top_node:\n        return\n\n    # Jump to parent menu\n    parent = _parent_menu(_cur_menu)\n    _shown = _shown_nodes(parent)\n    _sel_node_i = _shown.index(_cur_menu)\n    _cur_menu = parent\n\n    # Try to make the menu entry appear on the same row on the screen as it did\n    # before we entered the menu.\n\n    if _parent_screen_rows:\n        # The terminal might have shrunk since we were last in the parent menu\n        screen_row = min(_parent_screen_rows.pop(), _height(_menu_win) - 1)\n        _menu_scroll = max(_sel_node_i - screen_row, 0)\n    else:\n        # No saved parent menu locations, meaning we jumped directly to some\n        # node earlier\n        _center_vertically()\n\n\ndef _select_next_menu_entry():\n    # Selects the menu entry after the current one, adjusting the scroll if\n    # necessary. Does nothing if we're already at the last menu entry.\n\n    global _sel_node_i\n    global _menu_scroll\n\n    if _sel_node_i < len(_shown) - 1:\n        # Jump to the next node\n        _sel_node_i += 1\n\n        # If the new node is sufficiently close to the edge of the menu window\n        # (as determined by _SCROLL_OFFSET), increase the scroll by one. This\n        # gives nice and non-jumpy behavior even when\n        # _SCROLL_OFFSET >= _height(_menu_win).\n        if _sel_node_i >= _menu_scroll + _height(_menu_win) - _SCROLL_OFFSET \\\n           and _menu_scroll < _max_scroll(_shown, _menu_win):\n\n            _menu_scroll += 1\n\n\ndef _select_prev_menu_entry():\n    # Selects the menu entry before the current one, adjusting the scroll if\n    # necessary. Does nothing if we're already at the first menu entry.\n\n    global _sel_node_i\n    global _menu_scroll\n\n    if _sel_node_i > 0:\n        # Jump to the previous node\n        _sel_node_i -= 1\n\n        # See _select_next_menu_entry()\n        if _sel_node_i < _menu_scroll + _SCROLL_OFFSET:\n            _menu_scroll = max(_menu_scroll - 1, 0)\n\n\ndef _select_last_menu_entry():\n    # Selects the last menu entry in the current menu\n\n    global _sel_node_i\n    global _menu_scroll\n\n    _sel_node_i = len(_shown) - 1\n    _menu_scroll = _max_scroll(_shown, _menu_win)\n\n\ndef _select_first_menu_entry():\n    # Selects the first menu entry in the current menu\n\n    global _sel_node_i\n    global _menu_scroll\n\n    _sel_node_i = _menu_scroll = 0\n\n\ndef _toggle_show_all():\n    # Toggles show-all mode on/off. If turning it off would give no visible\n    # items in the current menu, it is left on.\n\n    global _show_all\n    global _shown\n    global _sel_node_i\n    global _menu_scroll\n\n    # Row on the screen the cursor is on. Preferably we want the same row to\n    # stay highlighted.\n    old_row = _sel_node_i - _menu_scroll\n\n    _show_all = not _show_all\n    # List of new nodes to be shown after toggling _show_all\n    new_shown = _shown_nodes(_cur_menu)\n\n    # Find a good node to select. The selected node might disappear if show-all\n    # mode is turned off.\n\n    # Select the previously selected node itself if it is still visible. If\n    # there are visible nodes before it, select the closest one.\n    for node in _shown[_sel_node_i::-1]:\n        if node in new_shown:\n            _sel_node_i = new_shown.index(node)\n            break\n    else:\n        # No visible nodes before the previously selected node. Select the\n        # closest visible node after it instead.\n        for node in _shown[_sel_node_i + 1:]:\n            if node in new_shown:\n                _sel_node_i = new_shown.index(node)\n                break\n        else:\n            # No visible nodes at all, meaning show-all was turned off inside\n            # an invisible menu. Don't allow that, as the implementation relies\n            # on always having a selected node.\n            _show_all = True\n            return\n\n    _shown = new_shown\n\n    # Try to make the cursor stay on the same row in the menu window. This\n    # might be impossible if too many nodes have disappeared above the node.\n    _menu_scroll = max(_sel_node_i - old_row, 0)\n\n\ndef _center_vertically():\n    # Centers the selected node vertically, if possible\n\n    global _menu_scroll\n\n    _menu_scroll = min(max(_sel_node_i - _height(_menu_win)//2, 0),\n                       _max_scroll(_shown, _menu_win))\n\n\ndef _draw_main():\n    # Draws the \"main\" display, with the list of symbols, the header, and the\n    # footer.\n    #\n    # This could be optimized to only update the windows that have actually\n    # changed, but keep it simple for now and let curses sort it out.\n\n    term_width = _width(_stdscr)\n\n\n    #\n    # Update the separator row below the menu path\n    #\n\n    _top_sep_win.erase()\n\n    # Draw arrows pointing up if the symbol window is scrolled down. Draw them\n    # before drawing the title, so the title ends up on top for small windows.\n    if _menu_scroll > 0:\n        _safe_hline(_top_sep_win, 0, 4, curses.ACS_UARROW, _N_SCROLL_ARROWS)\n\n    # Add the 'mainmenu' text as the title, centered at the top\n    _safe_addstr(_top_sep_win,\n                 0, max((term_width - len(_kconf.mainmenu_text))//2, 0),\n                 _kconf.mainmenu_text)\n\n    _top_sep_win.noutrefresh()\n\n    # Note: The menu path at the top is deliberately updated last. See below.\n\n    #\n    # Update the symbol window\n    #\n\n    _menu_win.erase()\n\n    # Draw the _shown nodes starting from index _menu_scroll up to either as\n    # many as fit in the window, or to the end of _shown\n    for i in range(_menu_scroll,\n                   min(_menu_scroll + _height(_menu_win), len(_shown))):\n\n        node = _shown[i]\n\n        # The 'not _show_all' test avoids showing invisible items in red\n        # outside show-all mode, which could look confusing/broken. Invisible\n        # symbols show up outside show-all mode if an invisible symbol has\n        # visible children in an implicit (indented) menu.\n        if _visible(node) or not _show_all:\n            style = _style[\"selection\" if i == _sel_node_i else \"list\"]\n        else:\n            style = _style[\"inv-selection\" if i == _sel_node_i else \"inv-list\"]\n\n        _safe_addstr(_menu_win, i - _menu_scroll, 0, _node_str(node), style)\n\n    _menu_win.noutrefresh()\n\n\n    #\n    # Update the bottom separator window\n    #\n\n    _bot_sep_win.erase()\n\n    # Draw arrows pointing down if the symbol window is scrolled up\n    if _menu_scroll < _max_scroll(_shown, _menu_win):\n        _safe_hline(_bot_sep_win, 0, 4, curses.ACS_DARROW, _N_SCROLL_ARROWS)\n\n    # Indicate when show-name/show-help/show-all mode is enabled\n    enabled_modes = []\n    if _show_help:\n        enabled_modes.append(\"show-help (toggle with [F])\")\n    if _show_name:\n        enabled_modes.append(\"show-name\")\n    if _show_all:\n        enabled_modes.append(\"show-all\")\n    if enabled_modes:\n        s = \" and \".join(enabled_modes) + \" mode enabled\"\n        _safe_addstr(_bot_sep_win, 0, max(term_width - len(s) - 2, 0), s)\n\n    _bot_sep_win.noutrefresh()\n\n\n    #\n    # Update the help window, which shows either key bindings or help texts\n    #\n\n    _help_win.erase()\n\n    if _show_help:\n        node = _shown[_sel_node_i]\n        if isinstance(node.item, (Symbol, Choice)) and node.help:\n            help_lines = textwrap.wrap(node.help, _width(_help_win))\n            for i in range(min(_height(_help_win), len(help_lines))):\n                _safe_addstr(_help_win, i, 0, help_lines[i])\n        else:\n            _safe_addstr(_help_win, 0, 0, \"(no help)\")\n    else:\n        for i, line in enumerate(_MAIN_HELP_LINES):\n            _safe_addstr(_help_win, i, 0, line)\n\n    _help_win.noutrefresh()\n\n\n    #\n    # Update the top row with the menu path.\n    #\n    # Doing this last leaves the cursor on the top row, which avoids some minor\n    # annoying jumpiness in gnome-terminal when reducing the height of the\n    # terminal. It seems to happen whenever the row with the cursor on it\n    # disappears.\n    #\n\n    _path_win.erase()\n\n    # Draw the menu path (\"(Top) -> Menu -> Submenu -> ...\")\n\n    menu_prompts = []\n\n    menu = _cur_menu\n    while menu is not _kconf.top_node:\n        # Promptless choices can be entered in show-all mode. Use\n        # standard_sc_expr_str() for them, so they show up as\n        # '<choice (name if any)>'.\n        menu_prompts.append(menu.prompt[0] if menu.prompt else\n                            standard_sc_expr_str(menu.item))\n        menu = menu.parent\n    menu_prompts.append(\"(Top)\")\n    menu_prompts.reverse()\n\n    # Hack: We can't put ACS_RARROW directly in the string. Temporarily\n    # represent it with NULL.\n    menu_path_str = \" \\0 \".join(menu_prompts)\n\n    # Scroll the menu path to the right if needed to make the current menu's\n    # title visible\n    if len(menu_path_str) > term_width:\n        menu_path_str = menu_path_str[len(menu_path_str) - term_width:]\n\n    # Print the path with the arrows reinserted\n    split_path = menu_path_str.split(\"\\0\")\n    _safe_addstr(_path_win, split_path[0])\n    for s in split_path[1:]:\n        _safe_addch(_path_win, curses.ACS_RARROW)\n        _safe_addstr(_path_win, s)\n\n    _path_win.noutrefresh()\n\n\ndef _parent_menu(node):\n    # Returns the menu node of the menu that contains 'node'. In addition to\n    # proper 'menu's, this might also be a 'menuconfig' symbol or a 'choice'.\n    # \"Menu\" here means a menu in the interface.\n\n    menu = node.parent\n    while not menu.is_menuconfig:\n        menu = menu.parent\n    return menu\n\n\ndef _shown_nodes(menu):\n    # Returns the list of menu nodes from 'menu' (see _parent_menu()) that\n    # would be shown when entering it\n\n    def rec(node):\n        res = []\n\n        while node:\n            if _visible(node) or _show_all:\n                res.append(node)\n                if node.list and not node.is_menuconfig:\n                    # Nodes from implicit menu created from dependencies. Will\n                    # be shown indented. Note that is_menuconfig is True for\n                    # menus and choices as well as 'menuconfig' symbols.\n                    res += rec(node.list)\n\n            elif node.list and isinstance(node.item, Symbol):\n                # Show invisible symbols if they have visible children. This\n                # can happen for an m/y-valued symbol with an optional prompt\n                # ('prompt \"foo\" is COND') that is currently disabled. Note\n                # that it applies to both 'config' and 'menuconfig' symbols.\n                shown_children = rec(node.list)\n                if shown_children:\n                    res.append(node)\n                    if not node.is_menuconfig:\n                        res += shown_children\n\n            node = node.next\n\n        return res\n\n    if isinstance(menu.item, Choice):\n        # For named choices defined in multiple locations, entering the choice\n        # at a particular menu node would normally only show the choice symbols\n        # defined there (because that's what the MenuNode tree looks like).\n        #\n        # That might look confusing, and makes extending choices by defining\n        # them in multiple locations less useful. Instead, gather all the child\n        # menu nodes for all the choices whenever a choice is entered. That\n        # makes all choice symbols visible at all locations.\n        #\n        # Choices can contain non-symbol items (people do all sorts of weird\n        # stuff with them), hence the generality here. We really need to\n        # preserve the menu tree at each choice location.\n        #\n        # Note: Named choices are pretty broken in the C tools, and this is\n        # super obscure, so you probably won't find much that relies on this.\n        # This whole 'if' could be deleted if you don't care about defining\n        # choices in multiple locations to add symbols (which will still work,\n        # just with things being displayed in a way that might be unexpected).\n\n        # Do some additional work to avoid listing choice symbols twice if all\n        # or part of the choice is copied in multiple locations (e.g. by\n        # including some Kconfig file multiple times). We give the prompts at\n        # the current location precedence.\n        seen_syms = {node.item for node in rec(menu.list)\n                     if isinstance(node.item, Symbol)}\n        res = []\n        for choice_node in menu.item.nodes:\n            for node in rec(choice_node.list):\n                # 'choice_node is menu' checks if we're dealing with the\n                # current location\n                if node.item not in seen_syms or choice_node is menu:\n                    res.append(node)\n                    if isinstance(node.item, Symbol):\n                        seen_syms.add(node.item)\n        return res\n\n    return rec(menu.list)\n\n\ndef _visible(node):\n    # Returns True if the node should appear in the menu (outside show-all\n    # mode)\n\n    return node.prompt and expr_value(node.prompt[1]) and not \\\n        (node.item == MENU and not expr_value(node.visibility))\n\n\ndef _change_node(node):\n    # Changes the value of the menu node 'node' if it is a symbol. Bools and\n    # tristates are toggled, while other symbol types pop up a text entry\n    # dialog.\n    #\n    # Returns False if the value of 'node' can't be changed.\n\n    if not _changeable(node):\n        return False\n\n    # sc = symbol/choice\n    sc = node.item\n\n    if sc.orig_type in (INT, HEX, STRING):\n        s = sc.str_value\n\n        while True:\n            s = _input_dialog(\n                \"{} ({})\".format(node.prompt[0], TYPE_TO_STR[sc.orig_type]),\n                s, _range_info(sc))\n\n            if s is None:\n                break\n\n            if sc.orig_type in (INT, HEX):\n                s = s.strip()\n\n                # 'make menuconfig' does this too. Hex values not starting with\n                # '0x' are accepted when loading .config files though.\n                if sc.orig_type == HEX and not s.startswith((\"0x\", \"0X\")):\n                    s = \"0x\" + s\n\n            if _check_valid(sc, s):\n                _set_val(sc, s)\n                break\n\n    elif len(sc.assignable) == 1:\n        # Handles choice symbols for choices in y mode, which are a special\n        # case: .assignable can be (2,) while .tri_value is 0.\n        _set_val(sc, sc.assignable[0])\n\n    else:\n        # Set the symbol to the value after the current value in\n        # sc.assignable, with wrapping\n        val_index = sc.assignable.index(sc.tri_value)\n        _set_val(sc, sc.assignable[(val_index + 1) % len(sc.assignable)])\n\n\n    if _is_y_mode_choice_sym(sc) and not node.list:\n        # Immediately jump to the parent menu after making a choice selection,\n        # like 'make menuconfig' does, except if the menu node has children\n        # (which can happen if a symbol 'depends on' a choice symbol that\n        # immediately precedes it).\n        _leave_menu()\n\n\n    return True\n\n\ndef _changeable(node):\n    # Returns True if the value if 'node' can be changed\n\n    sc = node.item\n\n    if not isinstance(sc, (Symbol, Choice)):\n        return False\n\n    # This will hit for invisible symbols, which appear in show-all mode and\n    # when an invisible symbol has visible children (which can happen e.g. for\n    # symbols with optional prompts)\n    if not (node.prompt and expr_value(node.prompt[1])):\n        return False\n\n    return sc.orig_type in (STRING, INT, HEX) or len(sc.assignable) > 1 \\\n        or _is_y_mode_choice_sym(sc)\n\n\ndef _set_sel_node_tri_val(tri_val):\n    # Sets the value of the currently selected menu entry to 'tri_val', if that\n    # value can be assigned\n\n    sc = _shown[_sel_node_i].item\n    if isinstance(sc, (Symbol, Choice)) and tri_val in sc.assignable:\n        _set_val(sc, tri_val)\n\n\ndef _set_val(sc, val):\n    # Wrapper around Symbol/Choice.set_value() for updating the menu state and\n    # _conf_changed\n\n    global _conf_changed\n\n    # Use the string representation of tristate values. This makes the format\n    # consistent for all symbol types.\n    if val in TRI_TO_STR:\n        val = TRI_TO_STR[val]\n\n    if val != sc.str_value:\n        sc.set_value(val)\n        _conf_changed = True\n\n        # Changing the value of the symbol might have changed what items in the\n        # current menu are visible. Recalculate the state.\n        _update_menu()\n\n\ndef _update_menu():\n    # Updates the current menu after the value of a symbol or choice has been\n    # changed. Changing a value might change which items in the menu are\n    # visible.\n    #\n    # If possible, preserves the location of the cursor on the screen when\n    # items are added/removed above the selected item.\n\n    global _shown\n    global _sel_node_i\n    global _menu_scroll\n\n    # Row on the screen the cursor was on\n    old_row = _sel_node_i - _menu_scroll\n\n    sel_node = _shown[_sel_node_i]\n\n    # New visible nodes\n    _shown = _shown_nodes(_cur_menu)\n\n    # New index of selected node\n    _sel_node_i = _shown.index(sel_node)\n\n    # Try to make the cursor stay on the same row in the menu window. This\n    # might be impossible if too many nodes have disappeared above the node.\n    _menu_scroll = max(_sel_node_i - old_row, 0)\n\n\ndef _input_dialog(title, initial_text, info_text=None):\n    # Pops up a dialog that prompts the user for a string\n    #\n    # title:\n    #   Title to display at the top of the dialog window's border\n    #\n    # initial_text:\n    #   Initial text to prefill the input field with\n    #\n    # info_text:\n    #   String to show next to the input field. If None, just the input field\n    #   is shown.\n\n    win = _styled_win(\"body\")\n    win.keypad(True)\n\n    info_lines = info_text.split(\"\\n\") if info_text else []\n\n    # Give the input dialog its initial size\n    _resize_input_dialog(win, title, info_lines)\n\n    _safe_curs_set(2)\n\n    # Input field text\n    s = initial_text\n\n    # Cursor position\n    i = len(initial_text)\n\n    def edit_width():\n        return _width(win) - 4\n\n    # Horizontal scroll offset\n    hscroll = max(i - edit_width() + 1, 0)\n\n    while True:\n        # Draw the \"main\" display with the menu, etc., so that resizing still\n        # works properly. This is like a stack of windows, only hardcoded for\n        # now.\n        _draw_main()\n        _draw_input_dialog(win, title, info_lines, s, i, hscroll)\n        curses.doupdate()\n\n\n        c = _getch_compat(win)\n\n        if c == curses.KEY_RESIZE:\n            # Resize the main display too. The dialog floats above it.\n            _resize_main()\n            _resize_input_dialog(win, title, info_lines)\n\n        elif c == \"\\n\":\n            _safe_curs_set(0)\n            return s\n\n        elif c == \"\\x1B\":  # \\x1B = ESC\n            _safe_curs_set(0)\n            return None\n\n        else:\n            s, i, hscroll = _edit_text(c, s, i, hscroll, edit_width())\n\n\ndef _resize_input_dialog(win, title, info_lines):\n    # Resizes the input dialog to a size appropriate for the terminal size\n\n    screen_height, screen_width = _stdscr.getmaxyx()\n\n    win_height = 5\n    if info_lines:\n        win_height += len(info_lines) + 1\n    win_height = min(win_height, screen_height)\n\n    win_width = max(_INPUT_DIALOG_MIN_WIDTH,\n                    len(title) + 4,\n                    *(len(line) + 4 for line in info_lines))\n    win_width = min(win_width, screen_width)\n\n    win.resize(win_height, win_width)\n    win.mvwin((screen_height - win_height)//2,\n              (screen_width - win_width)//2)\n\n\ndef _draw_input_dialog(win, title, info_lines, s, i, hscroll):\n    edit_width = _width(win) - 4\n\n    win.erase()\n\n    # Note: Perhaps having a separate window for the input field would be nicer\n    visible_s = s[hscroll:hscroll + edit_width]\n    _safe_addstr(win, 2, 2, visible_s + \" \"*(edit_width - len(visible_s)),\n                 _style[\"edit\"])\n\n    for linenr, line in enumerate(info_lines):\n        _safe_addstr(win, 4 + linenr, 2, line)\n\n    # Draw the frame last so that it overwrites the body text for small windows\n    _draw_frame(win, title)\n\n    _safe_move(win, 2, 2 + i - hscroll)\n\n    win.noutrefresh()\n\n\ndef _load_dialog():\n    # Dialog for loading a new configuration\n\n    global _conf_changed\n    global _conf_filename\n    global _show_all\n\n    if _conf_changed:\n        c = _key_dialog(\n            \"Load\",\n            \"You have unsaved changes. Load new\\n\"\n            \"configuration anyway?\\n\"\n            \"\\n\"\n            \"         (O)K  (C)ancel\",\n            \"oc\")\n\n        if c is None or c == \"c\":\n            return\n\n    filename = _conf_filename\n    while True:\n        filename = _input_dialog(\"File to load\", filename, _load_save_info())\n        if filename is None:\n            return\n\n        filename = os.path.expanduser(filename)\n\n        if _try_load(filename):\n            _conf_filename = filename\n            _conf_changed = _needs_save()\n\n            # Turn on show-all mode if the selected node is not visible after\n            # loading the new configuration. _shown still holds the old state.\n            if _shown[_sel_node_i] not in _shown_nodes(_cur_menu):\n                _show_all = True\n\n            _update_menu()\n\n            # The message dialog indirectly updates the menu display, so _msg()\n            # must be called after the new state has been initialized\n            _msg(\"Success\", \"Loaded \" + filename)\n            return\n\n\ndef _try_load(filename):\n    # Tries to load a configuration file. Pops up an error and returns False on\n    # failure.\n    #\n    # filename:\n    #   Configuration file to load\n\n    try:\n        _kconf.load_config(filename)\n        return True\n    except EnvironmentError as e:\n        _error(\"Error loading '{}'\\n\\n{} (errno: {})\"\n               .format(filename, e.strerror, errno.errorcode[e.errno]))\n        return False\n\n\ndef _save_dialog(save_fn, default_filename, description):\n    # Dialog for saving the current configuration\n    #\n    # save_fn:\n    #   Function to call with 'filename' to save the file\n    #\n    # default_filename:\n    #   Prefilled filename in the input field\n    #\n    # description:\n    #   String describing the thing being saved\n    #\n    # Return value:\n    #   The path to the saved file, or None if no file was saved\n\n    filename = default_filename\n    while True:\n        filename = _input_dialog(\"Filename to save {} to\".format(description),\n                                 filename, _load_save_info())\n        if filename is None:\n            return None\n\n        filename = os.path.expanduser(filename)\n\n        msg = _try_save(save_fn, filename, description)\n        if msg:\n            _msg(\"Success\", msg)\n            return filename\n\n\ndef _try_save(save_fn, filename, description):\n    # Tries to save a configuration file. Returns a message to print on\n    # success.\n    #\n    # save_fn:\n    #   Function to call with 'filename' to save the file\n    #\n    # description:\n    #   String describing the thing being saved\n    #\n    # Return value:\n    #   A message to print on success, and None on failure\n\n    try:\n        # save_fn() returns a message to print\n        return save_fn(filename)\n    except EnvironmentError as e:\n        _error(\"Error saving {} to '{}'\\n\\n{} (errno: {})\"\n               .format(description, e.filename, e.strerror,\n                       errno.errorcode[e.errno]))\n        return None\n\n\ndef _key_dialog(title, text, keys):\n    # Pops up a dialog that can be closed by pressing a key\n    #\n    # title:\n    #   Title to display at the top of the dialog window's border\n    #\n    # text:\n    #   Text to show in the dialog\n    #\n    # keys:\n    #   List of keys that will close the dialog. Other keys (besides ESC) are\n    #   ignored. The caller is responsible for providing a hint about which\n    #   keys can be pressed in 'text'.\n    #\n    # Return value:\n    #   The key that was pressed to close the dialog. Uppercase characters are\n    #   converted to lowercase. ESC will always close the dialog, and returns\n    #   None.\n\n    win = _styled_win(\"body\")\n    win.keypad(True)\n\n    _resize_key_dialog(win, text)\n\n    while True:\n        # See _input_dialog()\n        _draw_main()\n        _draw_key_dialog(win, title, text)\n        curses.doupdate()\n\n\n        c = _getch_compat(win)\n\n        if c == curses.KEY_RESIZE:\n            # Resize the main display too. The dialog floats above it.\n            _resize_main()\n            _resize_key_dialog(win, text)\n\n        elif c == \"\\x1B\":  # \\x1B = ESC\n            return None\n\n        elif isinstance(c, str):\n            c = c.lower()\n            if c in keys:\n                return c\n\n\ndef _resize_key_dialog(win, text):\n    # Resizes the key dialog to a size appropriate for the terminal size\n\n    screen_height, screen_width = _stdscr.getmaxyx()\n\n    lines = text.split(\"\\n\")\n\n    win_height = min(len(lines) + 4, screen_height)\n    win_width = min(max(len(line) for line in lines) + 4, screen_width)\n\n    win.resize(win_height, win_width)\n    win.mvwin((screen_height - win_height)//2,\n              (screen_width - win_width)//2)\n\n\ndef _draw_key_dialog(win, title, text):\n    win.erase()\n\n    for i, line in enumerate(text.split(\"\\n\")):\n        _safe_addstr(win, 2 + i, 2, line)\n\n    # Draw the frame last so that it overwrites the body text for small windows\n    _draw_frame(win, title)\n\n    win.noutrefresh()\n\n\ndef _draw_frame(win, title):\n    # Draw a frame around the inner edges of 'win', with 'title' at the top\n\n    win_height, win_width = win.getmaxyx()\n\n    win.attron(_style[\"frame\"])\n\n    # Draw top/bottom edge\n    _safe_hline(win,              0, 0, \" \", win_width)\n    _safe_hline(win, win_height - 1, 0, \" \", win_width)\n\n    # Draw left/right edge\n    _safe_vline(win, 0,             0, \" \", win_height)\n    _safe_vline(win, 0, win_width - 1, \" \", win_height)\n\n    # Draw title\n    _safe_addstr(win, 0, max((win_width - len(title))//2, 0), title)\n\n    win.attroff(_style[\"frame\"])\n\n\ndef _jump_to_dialog():\n    # Implements the jump-to dialog, where symbols can be looked up via\n    # incremental search and jumped to.\n    #\n    # Returns True if the user jumped to a symbol, and False if the dialog was\n    # canceled.\n\n    s = \"\"  # Search text\n    prev_s = None  # Previous search text\n    s_i = 0  # Search text cursor position\n    hscroll = 0  # Horizontal scroll offset\n\n    sel_node_i = 0  # Index of selected row\n    scroll = 0  # Index in 'matches' of the top row of the list\n\n    # Edit box at the top\n    edit_box = _styled_win(\"jump-edit\")\n    edit_box.keypad(True)\n\n    # List of matches\n    matches_win = _styled_win(\"list\")\n\n    # Bottom separator, with arrows pointing down\n    bot_sep_win = _styled_win(\"separator\")\n\n    # Help window with instructions at the bottom\n    help_win = _styled_win(\"help\")\n\n    # Give windows their initial size\n    _resize_jump_to_dialog(edit_box, matches_win, bot_sep_win, help_win,\n                           sel_node_i, scroll)\n\n    _safe_curs_set(2)\n\n    # Logic duplication with _select_{next,prev}_menu_entry(), except we do a\n    # functional variant that returns the new (sel_node_i, scroll) values to\n    # avoid 'nonlocal'. TODO: Can this be factored out in some nice way?\n\n    def select_next_match():\n        if sel_node_i == len(matches) - 1:\n            return sel_node_i, scroll\n\n        if sel_node_i + 1 >= scroll + _height(matches_win) - _SCROLL_OFFSET \\\n           and scroll < _max_scroll(matches, matches_win):\n\n            return sel_node_i + 1, scroll + 1\n\n        return sel_node_i + 1, scroll\n\n    def select_prev_match():\n        if sel_node_i == 0:\n            return sel_node_i, scroll\n\n        if sel_node_i - 1 < scroll + _SCROLL_OFFSET:\n            return sel_node_i - 1, max(scroll - 1, 0)\n\n        return sel_node_i - 1, scroll\n\n    while True:\n        if s != prev_s:\n            # The search text changed. Find new matching nodes.\n\n            prev_s = s\n\n            try:\n                # We could use re.IGNORECASE here instead of lower(), but this\n                # is noticeably less jerky while inputting regexes like\n                # '.*debug$' (though the '.*' is redundant there). Those\n                # probably have bad interactions with re.search(), which\n                # matches anywhere in the string.\n                #\n                # It's not horrible either way. Just a bit smoother.\n                regex_searches = [re.compile(regex).search\n                                  for regex in s.lower().split()]\n\n                # No exception thrown, so the regexes are okay\n                bad_re = None\n\n                # List of matching nodes\n                matches = []\n                add_match = matches.append\n\n                # Search symbols and choices\n\n                for node in _sorted_sc_nodes():\n                    # Symbol/choice\n                    sc = node.item\n\n                    for search in regex_searches:\n                        # Both the name and the prompt might be missing, since\n                        # we're searching both symbols and choices\n\n                        # Does the regex match either the symbol name or the\n                        # prompt (if any)?\n                        if not (sc.name and search(sc.name.lower()) or\n                                node.prompt and search(node.prompt[0].lower())):\n\n                            # Give up on the first regex that doesn't match, to\n                            # speed things up a bit when multiple regexes are\n                            # entered\n                            break\n\n                    else:\n                        add_match(node)\n\n                # Search menus and comments\n\n                for node in _sorted_menu_comment_nodes():\n                    for search in regex_searches:\n                        if not search(node.prompt[0].lower()):\n                            break\n                    else:\n                        add_match(node)\n\n            except re.error as e:\n                # Bad regex. Remember the error message so we can show it.\n                bad_re = \"Bad regular expression\"\n                # re.error.msg was added in Python 3.5\n                if hasattr(e, \"msg\"):\n                    bad_re += \": \" + e.msg\n\n                matches = []\n\n            # Reset scroll and jump to the top of the list of matches\n            sel_node_i = scroll = 0\n\n        _draw_jump_to_dialog(edit_box, matches_win, bot_sep_win, help_win,\n                             s, s_i, hscroll,\n                             bad_re, matches, sel_node_i, scroll)\n        curses.doupdate()\n\n\n        c = _getch_compat(edit_box)\n\n        if c == \"\\n\":\n            if matches:\n                _jump_to(matches[sel_node_i])\n                _safe_curs_set(0)\n                return True\n\n        elif c == \"\\x1B\":  # \\x1B = ESC\n            _safe_curs_set(0)\n            return False\n\n        elif c == curses.KEY_RESIZE:\n            # We adjust the scroll so that the selected node stays visible in\n            # the list when the terminal is resized, hence the 'scroll'\n            # assignment\n            scroll = _resize_jump_to_dialog(\n                edit_box, matches_win, bot_sep_win, help_win,\n                sel_node_i, scroll)\n\n        elif c == \"\\x06\":  # \\x06 = Ctrl-F\n            if matches:\n                _safe_curs_set(0)\n                _info_dialog(matches[sel_node_i], True)\n                _safe_curs_set(2)\n\n                scroll = _resize_jump_to_dialog(\n                    edit_box, matches_win, bot_sep_win, help_win,\n                    sel_node_i, scroll)\n\n        elif c == curses.KEY_DOWN:\n            sel_node_i, scroll = select_next_match()\n\n        elif c == curses.KEY_UP:\n            sel_node_i, scroll = select_prev_match()\n\n        elif c in (curses.KEY_NPAGE, \"\\x04\"):  # Page Down/Ctrl-D\n            # Keep it simple. This way we get sane behavior for small windows,\n            # etc., for free.\n            for _ in range(_PG_JUMP):\n                sel_node_i, scroll = select_next_match()\n\n        # Page Up (no Ctrl-U, as it's already used by the edit box)\n        elif c == curses.KEY_PPAGE:\n            for _ in range(_PG_JUMP):\n                sel_node_i, scroll = select_prev_match()\n\n        elif c == curses.KEY_END:\n            sel_node_i = len(matches) - 1\n            scroll = _max_scroll(matches, matches_win)\n\n        elif c == curses.KEY_HOME:\n            sel_node_i = scroll = 0\n\n        else:\n            s, s_i, hscroll = _edit_text(c, s, s_i, hscroll,\n                                         _width(edit_box) - 2)\n\n\n# Obscure Python: We never pass a value for cached_nodes, and it keeps pointing\n# to the same list. This avoids a global.\ndef _sorted_sc_nodes(cached_nodes=[]):\n    # Returns a sorted list of symbol and choice nodes to search. The symbol\n    # nodes appear first, sorted by name, and then the choice nodes, sorted by\n    # prompt and (secondarily) name.\n\n    if not cached_nodes:\n        # Add symbol nodes\n        for sym in sorted(_kconf.unique_defined_syms,\n                          key=lambda sym: sym.name):\n            # += is in-place for lists\n            cached_nodes += sym.nodes\n\n        # Add choice nodes\n\n        choices = sorted(_kconf.unique_choices,\n                         key=lambda choice: choice.name or \"\")\n\n        cached_nodes += sorted(\n            [node for choice in choices for node in choice.nodes],\n            key=lambda node: node.prompt[0] if node.prompt else \"\")\n\n    return cached_nodes\n\n\ndef _sorted_menu_comment_nodes(cached_nodes=[]):\n    # Returns a list of menu and comment nodes to search, sorted by prompt,\n    # with the menus first\n\n    if not cached_nodes:\n        def prompt_text(mc):\n            return mc.prompt[0]\n\n        cached_nodes += sorted(_kconf.menus, key=prompt_text)\n        cached_nodes += sorted(_kconf.comments, key=prompt_text)\n\n    return cached_nodes\n\n\ndef _resize_jump_to_dialog(edit_box, matches_win, bot_sep_win, help_win,\n                           sel_node_i, scroll):\n    # Resizes the jump-to dialog to fill the terminal.\n    #\n    # Returns the new scroll index. We adjust the scroll if needed so that the\n    # selected node stays visible.\n\n    screen_height, screen_width = _stdscr.getmaxyx()\n\n    bot_sep_win.resize(1, screen_width)\n\n    help_win_height = len(_JUMP_TO_HELP_LINES)\n    matches_win_height = screen_height - help_win_height - 4\n\n    if matches_win_height >= 1:\n        edit_box.resize(3, screen_width)\n        matches_win.resize(matches_win_height, screen_width)\n        help_win.resize(help_win_height, screen_width)\n\n        matches_win.mvwin(3, 0)\n        bot_sep_win.mvwin(3 + matches_win_height, 0)\n        help_win.mvwin(3 + matches_win_height + 1, 0)\n    else:\n        # Degenerate case. Give up on nice rendering and just prevent errors.\n\n        matches_win_height = 1\n\n        edit_box.resize(screen_height, screen_width)\n        matches_win.resize(1, screen_width)\n        help_win.resize(1, screen_width)\n\n        for win in matches_win, bot_sep_win, help_win:\n            win.mvwin(0, 0)\n\n    # Adjust the scroll so that the selected row is still within the window, if\n    # needed\n    if sel_node_i - scroll >= matches_win_height:\n        return sel_node_i - matches_win_height + 1\n    return scroll\n\n\ndef _draw_jump_to_dialog(edit_box, matches_win, bot_sep_win, help_win,\n                         s, s_i, hscroll,\n                         bad_re, matches, sel_node_i, scroll):\n\n    edit_width = _width(edit_box) - 2\n\n\n    #\n    # Update list of matches\n    #\n\n    matches_win.erase()\n\n    if matches:\n        for i in range(scroll,\n                       min(scroll + _height(matches_win), len(matches))):\n\n            node = matches[i]\n\n            if isinstance(node.item, (Symbol, Choice)):\n                node_str = _name_and_val_str(node.item)\n                if node.prompt:\n                    node_str += ' \"{}\"'.format(node.prompt[0])\n            elif node.item == MENU:\n                node_str = 'menu \"{}\"'.format(node.prompt[0])\n            else:  # node.item == COMMENT\n                node_str = 'comment \"{}\"'.format(node.prompt[0])\n\n            _safe_addstr(matches_win, i - scroll, 0, node_str,\n                         _style[\"selection\" if i == sel_node_i else \"list\"])\n\n    else:\n        # bad_re holds the error message from the re.error exception on errors\n        _safe_addstr(matches_win, 0, 0, bad_re or \"No matches\")\n\n    matches_win.noutrefresh()\n\n\n    #\n    # Update bottom separator line\n    #\n\n    bot_sep_win.erase()\n\n    # Draw arrows pointing down if the symbol list is scrolled up\n    if scroll < _max_scroll(matches, matches_win):\n        _safe_hline(bot_sep_win, 0, 4, curses.ACS_DARROW, _N_SCROLL_ARROWS)\n\n    bot_sep_win.noutrefresh()\n\n\n    #\n    # Update help window at bottom\n    #\n\n    help_win.erase()\n\n    for i, line in enumerate(_JUMP_TO_HELP_LINES):\n        _safe_addstr(help_win, i, 0, line)\n\n    help_win.noutrefresh()\n\n\n    #\n    # Update edit box. We do this last since it makes it handy to position the\n    # cursor.\n    #\n\n    edit_box.erase()\n\n    _draw_frame(edit_box, \"Jump to symbol/choice/menu/comment\")\n\n    # Draw arrows pointing up if the symbol list is scrolled down\n    if scroll > 0:\n        # TODO: Bit ugly that _style[\"frame\"] is repeated here\n        _safe_hline(edit_box, 2, 4, curses.ACS_UARROW, _N_SCROLL_ARROWS,\n                    _style[\"frame\"])\n\n    visible_s = s[hscroll:hscroll + edit_width]\n    _safe_addstr(edit_box, 1, 1, visible_s)\n\n    _safe_move(edit_box, 1, 1 + s_i - hscroll)\n\n    edit_box.noutrefresh()\n\n\ndef _info_dialog(node, from_jump_to_dialog):\n    # Shows a fullscreen window with information about 'node'.\n    #\n    # If 'from_jump_to_dialog' is True, the information dialog was opened from\n    # within the jump-to-dialog. In this case, we make '/' from within the\n    # information dialog just return, to avoid a confusing recursive invocation\n    # of the jump-to-dialog.\n\n    # Top row, with title and arrows point up\n    top_line_win = _styled_win(\"separator\")\n\n    # Text display\n    text_win = _styled_win(\"text\")\n    text_win.keypad(True)\n\n    # Bottom separator, with arrows pointing down\n    bot_sep_win = _styled_win(\"separator\")\n\n    # Help window with keys at the bottom\n    help_win = _styled_win(\"help\")\n\n    # Give windows their initial size\n    _resize_info_dialog(top_line_win, text_win, bot_sep_win, help_win)\n\n\n    # Get lines of help text\n    lines = _info_str(node).split(\"\\n\")\n\n    # Index of first row in 'lines' to show\n    scroll = 0\n\n    while True:\n        _draw_info_dialog(node, lines, scroll, top_line_win, text_win,\n                          bot_sep_win, help_win)\n        curses.doupdate()\n\n\n        c = _getch_compat(text_win)\n\n        if c == curses.KEY_RESIZE:\n            _resize_info_dialog(top_line_win, text_win, bot_sep_win, help_win)\n\n        elif c in (curses.KEY_DOWN, \"j\", \"J\"):\n            if scroll < _max_scroll(lines, text_win):\n                scroll += 1\n\n        elif c in (curses.KEY_NPAGE, \"\\x04\"):  # Page Down/Ctrl-D\n            scroll = min(scroll + _PG_JUMP, _max_scroll(lines, text_win))\n\n        elif c in (curses.KEY_PPAGE, \"\\x15\"):  # Page Up/Ctrl-U\n            scroll = max(scroll - _PG_JUMP, 0)\n\n        elif c in (curses.KEY_END, \"G\"):\n            scroll = _max_scroll(lines, text_win)\n\n        elif c in (curses.KEY_HOME, \"g\"):\n            scroll = 0\n\n        elif c in (curses.KEY_UP, \"k\", \"K\"):\n            if scroll > 0:\n                scroll -= 1\n\n        elif c == \"/\":\n            # Support starting a search from within the information dialog\n\n            if from_jump_to_dialog:\n                # Avoid recursion\n                return\n\n            if _jump_to_dialog():\n                # Jumped to a symbol. Cancel the information dialog.\n                return\n\n            # Stay in the information dialog if the jump-to dialog was\n            # canceled. Resize it in case the terminal was resized while the\n            # fullscreen jump-to dialog was open.\n            _resize_info_dialog(top_line_win, text_win, bot_sep_win, help_win)\n\n        elif c in (curses.KEY_LEFT, curses.KEY_BACKSPACE, _ERASE_CHAR,\n                   \"\\x1B\",  # \\x1B = ESC\n                   \"q\", \"Q\", \"h\", \"H\"):\n\n            return\n\n\ndef _resize_info_dialog(top_line_win, text_win, bot_sep_win, help_win):\n    # Resizes the info dialog to fill the terminal\n\n    screen_height, screen_width = _stdscr.getmaxyx()\n\n    top_line_win.resize(1, screen_width)\n    bot_sep_win.resize(1, screen_width)\n\n    help_win_height = len(_INFO_HELP_LINES)\n    text_win_height = screen_height - help_win_height - 2\n\n    if text_win_height >= 1:\n        text_win.resize(text_win_height, screen_width)\n        help_win.resize(help_win_height, screen_width)\n\n        text_win.mvwin(1, 0)\n        bot_sep_win.mvwin(1 + text_win_height, 0)\n        help_win.mvwin(1 + text_win_height + 1, 0)\n    else:\n        # Degenerate case. Give up on nice rendering and just prevent errors.\n\n        text_win.resize(1, screen_width)\n        help_win.resize(1, screen_width)\n\n        for win in text_win, bot_sep_win, help_win:\n            win.mvwin(0, 0)\n\n\ndef _draw_info_dialog(node, lines, scroll, top_line_win, text_win,\n                      bot_sep_win, help_win):\n\n    text_win_height, text_win_width = text_win.getmaxyx()\n\n\n    # Note: The top row is deliberately updated last. See _draw_main().\n\n    #\n    # Update text display\n    #\n\n    text_win.erase()\n\n    for i, line in enumerate(lines[scroll:scroll + text_win_height]):\n        _safe_addstr(text_win, i, 0, line)\n\n    text_win.noutrefresh()\n\n\n    #\n    # Update bottom separator line\n    #\n\n    bot_sep_win.erase()\n\n    # Draw arrows pointing down if the symbol window is scrolled up\n    if scroll < _max_scroll(lines, text_win):\n        _safe_hline(bot_sep_win, 0, 4, curses.ACS_DARROW, _N_SCROLL_ARROWS)\n\n    bot_sep_win.noutrefresh()\n\n\n    #\n    # Update help window at bottom\n    #\n\n    help_win.erase()\n\n    for i, line in enumerate(_INFO_HELP_LINES):\n        _safe_addstr(help_win, i, 0, line)\n\n    help_win.noutrefresh()\n\n\n    #\n    # Update top row\n    #\n\n    top_line_win.erase()\n\n    # Draw arrows pointing up if the information window is scrolled down. Draw\n    # them before drawing the title, so the title ends up on top for small\n    # windows.\n    if scroll > 0:\n        _safe_hline(top_line_win, 0, 4, curses.ACS_UARROW, _N_SCROLL_ARROWS)\n\n    title = (\"Symbol\" if isinstance(node.item, Symbol) else\n             \"Choice\" if isinstance(node.item, Choice) else\n             \"Menu\"   if node.item == MENU else\n             \"Comment\") + \" information\"\n    _safe_addstr(top_line_win, 0, max((text_win_width - len(title))//2, 0),\n                 title)\n\n    top_line_win.noutrefresh()\n\n\ndef _info_str(node):\n    # Returns information about the menu node 'node' as a string.\n    #\n    # The helper functions are responsible for adding newlines. This allows\n    # them to return \"\" if they don't want to add any output.\n\n    if isinstance(node.item, Symbol):\n        sym = node.item\n\n        return (\n            _name_info(sym) +\n            _prompt_info(sym) +\n            \"Type: {}\\n\".format(TYPE_TO_STR[sym.type]) +\n            _value_info(sym) +\n            _help_info(sym) +\n            _direct_dep_info(sym) +\n            _defaults_info(sym) +\n            _select_imply_info(sym) +\n            _kconfig_def_info(sym)\n        )\n\n    if isinstance(node.item, Choice):\n        choice = node.item\n\n        return (\n            _name_info(choice) +\n            _prompt_info(choice) +\n            \"Type: {}\\n\".format(TYPE_TO_STR[choice.type]) +\n            'Mode: {}\\n'.format(choice.str_value) +\n            _help_info(choice) +\n            _choice_syms_info(choice) +\n            _direct_dep_info(choice) +\n            _defaults_info(choice) +\n            _kconfig_def_info(choice)\n        )\n\n    # node.item in (MENU, COMMENT)\n    return _kconfig_def_info(node)\n\n\ndef _name_info(sc):\n    # Returns a string with the name of the symbol/choice. Names are optional\n    # for choices.\n\n    return \"Name: {}\\n\".format(sc.name) if sc.name else \"\"\n\n\ndef _prompt_info(sc):\n    # Returns a string listing the prompts of 'sc' (Symbol or Choice)\n\n    s = \"\"\n\n    for node in sc.nodes:\n        if node.prompt:\n            s += \"Prompt: {}\\n\".format(node.prompt[0])\n\n    return s\n\n\ndef _value_info(sym):\n    # Returns a string showing 'sym's value\n\n    # Only put quotes around the value for string symbols\n    return \"Value: {}\\n\".format(\n        '\"{}\"'.format(sym.str_value)\n        if sym.orig_type == STRING\n        else sym.str_value)\n\n\ndef _choice_syms_info(choice):\n    # Returns a string listing the choice symbols in 'choice'. Adds\n    # \"(selected)\" next to the selected one.\n\n    s = \"Choice symbols:\\n\"\n\n    for sym in choice.syms:\n        s += \"  - \" + sym.name\n        if sym is choice.selection:\n            s += \" (selected)\"\n        s += \"\\n\"\n\n    return s + \"\\n\"\n\n\ndef _help_info(sc):\n    # Returns a string with the help text(s) of 'sc' (Symbol or Choice).\n    # Symbols and choices defined in multiple locations can have multiple help\n    # texts.\n\n    s = \"\\n\"\n\n    for node in sc.nodes:\n        if node.help is not None:\n            s += \"Help:\\n\\n{}\\n\\n\".format(_indent(node.help, 2))\n\n    return s\n\n\ndef _direct_dep_info(sc):\n    # Returns a string describing the direct dependencies of 'sc' (Symbol or\n    # Choice). The direct dependencies are the OR of the dependencies from each\n    # definition location. The dependencies at each definition location come\n    # from 'depends on' and dependencies inherited from parent items.\n\n    return \"\" if sc.direct_dep is _kconf.y else \\\n        'Direct dependencies (={}):\\n{}\\n' \\\n        .format(TRI_TO_STR[expr_value(sc.direct_dep)],\n                _split_expr_info(sc.direct_dep, 2))\n\n\ndef _defaults_info(sc):\n    # Returns a string describing the defaults of 'sc' (Symbol or Choice)\n\n    if not sc.defaults:\n        return \"\"\n\n    s = \"Default\"\n    if len(sc.defaults) > 1:\n        s += \"s\"\n    s += \":\\n\"\n\n    for val, cond in sc.orig_defaults:\n        s += \"  - \"\n        if isinstance(sc, Symbol):\n            s += _expr_str(val)\n\n            # Skip the tristate value hint if the expression is just a single\n            # symbol. _expr_str() already shows its value as a string.\n            #\n            # This also avoids showing the tristate value for string/int/hex\n            # defaults, which wouldn't make any sense.\n            if isinstance(val, tuple):\n                s += '  (={})'.format(TRI_TO_STR[expr_value(val)])\n        else:\n            # Don't print the value next to the symbol name for choice\n            # defaults, as it looks a bit confusing\n            s += val.name\n        s += \"\\n\"\n\n        if cond is not _kconf.y:\n            s += \"    Condition (={}):\\n{}\" \\\n                 .format(TRI_TO_STR[expr_value(cond)],\n                         _split_expr_info(cond, 4))\n\n    return s + \"\\n\"\n\n\ndef _split_expr_info(expr, indent):\n    # Returns a string with 'expr' split into its top-level && or || operands,\n    # with one operand per line, together with the operand's value. This is\n    # usually enough to get something readable for long expressions. A fancier\n    # recursive thingy would be possible too.\n    #\n    # indent:\n    #   Number of leading spaces to add before the split expression.\n\n    if len(split_expr(expr, AND)) > 1:\n        split_op = AND\n        op_str = \"&&\"\n    else:\n        split_op = OR\n        op_str = \"||\"\n\n    s = \"\"\n    for i, term in enumerate(split_expr(expr, split_op)):\n        s += \"{}{} {}\".format(indent*\" \",\n                              \"  \" if i == 0 else op_str,\n                              _expr_str(term))\n\n        # Don't bother showing the value hint if the expression is just a\n        # single symbol. _expr_str() already shows its value.\n        if isinstance(term, tuple):\n            s += \"  (={})\".format(TRI_TO_STR[expr_value(term)])\n\n        s += \"\\n\"\n\n    return s\n\n\ndef _select_imply_info(sym):\n    # Returns a string with information about which symbols 'select' or 'imply'\n    # 'sym'. The selecting/implying symbols are grouped according to which\n    # value they select/imply 'sym' to (n/m/y).\n\n    def sis(expr, val, title):\n        # sis = selects/implies\n        sis = [si for si in split_expr(expr, OR) if expr_value(si) == val]\n        if not sis:\n            return \"\"\n\n        res = title\n        for si in sis:\n            res += \"  - {}\\n\".format(split_expr(si, AND)[0].name)\n        return res + \"\\n\"\n\n    s = \"\"\n\n    if sym.rev_dep is not _kconf.n:\n        s += sis(sym.rev_dep, 2,\n                 \"Symbols currently y-selecting this symbol:\\n\")\n        s += sis(sym.rev_dep, 1,\n                 \"Symbols currently m-selecting this symbol:\\n\")\n        s += sis(sym.rev_dep, 0,\n                 \"Symbols currently n-selecting this symbol (no effect):\\n\")\n\n    if sym.weak_rev_dep is not _kconf.n:\n        s += sis(sym.weak_rev_dep, 2,\n                 \"Symbols currently y-implying this symbol:\\n\")\n        s += sis(sym.weak_rev_dep, 1,\n                 \"Symbols currently m-implying this symbol:\\n\")\n        s += sis(sym.weak_rev_dep, 0,\n                 \"Symbols currently n-implying this symbol (no effect):\\n\")\n\n    return s\n\n\ndef _kconfig_def_info(item):\n    # Returns a string with the definition of 'item' in Kconfig syntax,\n    # together with the definition location(s) and their include and menu paths\n\n    nodes = [item] if isinstance(item, MenuNode) else item.nodes\n\n    s = \"Kconfig definition{}, with parent deps. propagated to 'depends on'\\n\" \\\n        .format(\"s\" if len(nodes) > 1 else \"\")\n    s += (len(s) - 1)*\"=\"\n\n    for node in nodes:\n        s += \"\\n\\n\" \\\n             \"At {}:{}\\n\" \\\n             \"{}\" \\\n             \"Menu path: {}\\n\\n\" \\\n             \"{}\" \\\n             .format(node.filename, node.linenr,\n                     _include_path_info(node),\n                     _menu_path_info(node),\n                     _indent(node.custom_str(_name_and_val_str), 2))\n\n    return s\n\n\ndef _include_path_info(node):\n    if not node.include_path:\n        # In the top-level Kconfig file\n        return \"\"\n\n    return \"Included via {}\\n\".format(\n        \" -> \".join(\"{}:{}\".format(filename, linenr)\n                    for filename, linenr in node.include_path))\n\n\ndef _menu_path_info(node):\n    # Returns a string describing the menu path leading up to 'node'\n\n    path = \"\"\n\n    while node.parent is not _kconf.top_node:\n        node = node.parent\n\n        # Promptless choices might appear among the parents. Use\n        # standard_sc_expr_str() for them, so that they show up as\n        # '<choice (name if any)>'.\n        path = \" -> \" + (node.prompt[0] if node.prompt else\n                         standard_sc_expr_str(node.item)) + path\n\n    return \"(Top)\" + path\n\n\ndef _indent(s, n):\n    # Returns 's' with each line indented 'n' spaces. textwrap.indent() is not\n    # available in Python 2 (it's 3.3+).\n\n    return \"\\n\".join(n*\" \" + line for line in s.split(\"\\n\"))\n\n\ndef _name_and_val_str(sc):\n    # Custom symbol/choice printer that shows symbol values after symbols\n\n    # Show the values of non-constant (non-quoted) symbols that don't look like\n    # numbers. Things like 123 are actually symbol references, and only work as\n    # expected due to undefined symbols getting their name as their value.\n    # Showing the symbol value for those isn't helpful though.\n    if isinstance(sc, Symbol) and not sc.is_constant and not _is_num(sc.name):\n        if not sc.nodes:\n            # Undefined symbol reference\n            return \"{}(undefined/n)\".format(sc.name)\n\n        return '{}(={})'.format(sc.name, sc.str_value)\n\n    # For other items, use the standard format\n    return standard_sc_expr_str(sc)\n\n\ndef _expr_str(expr):\n    # Custom expression printer that shows symbol values\n    return expr_str(expr, _name_and_val_str)\n\n\ndef _styled_win(style):\n    # Returns a new curses window with style 'style' and space as the fill\n    # character. The initial dimensions are (1, 1), so the window needs to be\n    # sized and positioned separately.\n\n    win = curses.newwin(1, 1)\n    _set_style(win, style)\n    return win\n\n\ndef _set_style(win, style):\n    # Changes the style of an existing window\n\n    win.bkgdset(\" \", _style[style])\n\n\ndef _max_scroll(lst, win):\n    # Assuming 'lst' is a list of items to be displayed in 'win',\n    # returns the maximum number of steps 'win' can be scrolled down.\n    # We stop scrolling when the bottom item is visible.\n\n    return max(0, len(lst) - _height(win))\n\n\ndef _edit_text(c, s, i, hscroll, width):\n    # Implements text editing commands for edit boxes. Takes a character (which\n    # could also be e.g. curses.KEY_LEFT) and the edit box state, and returns\n    # the new state after the character has been processed.\n    #\n    # c:\n    #   Character from user\n    #\n    # s:\n    #   Current contents of string\n    #\n    # i:\n    #   Current cursor index in string\n    #\n    # hscroll:\n    #   Index in s of the leftmost character in the edit box, for horizontal\n    #   scrolling\n    #\n    # width:\n    #   Width in characters of the edit box\n    #\n    # Return value:\n    #   An (s, i, hscroll) tuple for the new state\n\n    if c == curses.KEY_LEFT:\n        if i > 0:\n            i -= 1\n\n    elif c == curses.KEY_RIGHT:\n        if i < len(s):\n            i += 1\n\n    elif c in (curses.KEY_HOME, \"\\x01\"):  # \\x01 = CTRL-A\n        i = 0\n\n    elif c in (curses.KEY_END, \"\\x05\"):  # \\x05 = CTRL-E\n        i = len(s)\n\n    elif c in (curses.KEY_BACKSPACE, _ERASE_CHAR):\n        if i > 0:\n            s = s[:i-1] + s[i:]\n            i -= 1\n\n    elif c == curses.KEY_DC:\n        s = s[:i] + s[i+1:]\n\n    elif c == \"\\x17\":  # \\x17 = CTRL-W\n        # The \\W removes characters like ',' one at a time\n        new_i = re.search(r\"(?:\\w*|\\W)\\s*$\", s[:i]).start()\n        s = s[:new_i] + s[i:]\n        i = new_i\n\n    elif c == \"\\x0B\":  # \\x0B = CTRL-K\n        s = s[:i]\n\n    elif c == \"\\x15\":  # \\x15 = CTRL-U\n        s = s[i:]\n        i = 0\n\n    elif isinstance(c, str):\n        # Insert character\n        s = s[:i] + c + s[i:]\n        i += 1\n\n    # Adjust the horizontal scroll so that the cursor never touches the left or\n    # right edges of the edit box, except when it's at the beginning or the end\n    # of the string\n    if i < hscroll + _SCROLL_OFFSET:\n        hscroll = max(i - _SCROLL_OFFSET, 0)\n    elif i >= hscroll + width - _SCROLL_OFFSET:\n        max_scroll = max(len(s) - width + 1, 0)\n        hscroll = min(i - width + _SCROLL_OFFSET + 1, max_scroll)\n\n\n    return s, i, hscroll\n\n\ndef _load_save_info():\n    # Returns an information string for load/save dialog boxes\n\n    return \"(Relative to {})\\n\\nRefer to your home directory with ~\" \\\n           .format(os.path.join(os.getcwd(), \"\"))\n\n\ndef _msg(title, text):\n    # Pops up a message dialog that can be dismissed with Space/Enter/ESC\n\n    _key_dialog(title, text, \" \\n\")\n\n\ndef _error(text):\n    # Pops up an error dialog that can be dismissed with Space/Enter/ESC\n\n    _msg(\"Error\", text)\n\n\ndef _node_str(node):\n    # Returns the complete menu entry text for a menu node.\n    #\n    # Example return value: \"[*] Support for X\"\n\n    # Calculate the indent to print the item with by checking how many levels\n    # above it the closest 'menuconfig' item is (this includes menus and\n    # choices as well as menuconfig symbols)\n    indent = 0\n    parent = node.parent\n    while not parent.is_menuconfig:\n        indent += _SUBMENU_INDENT\n        parent = parent.parent\n\n    # This approach gives nice alignment for empty string symbols (\"()  Foo\")\n    s = \"{:{}}\".format(_value_str(node), 3 + indent)\n\n    if _should_show_name(node):\n        if isinstance(node.item, Symbol):\n            s += \" <{}>\".format(node.item.name)\n        else:\n            # For choices, use standard_sc_expr_str(). That way they show up as\n            # '<choice (name if any)>'.\n            s += \" \" + standard_sc_expr_str(node.item)\n\n    if node.prompt:\n        if node.item == COMMENT:\n            s += \" *** {} ***\".format(node.prompt[0])\n        else:\n            s += \" \" + node.prompt[0]\n\n        if isinstance(node.item, Symbol):\n            sym = node.item\n\n            # Print \"(NEW)\" next to symbols without a user value (from e.g. a\n            # .config), but skip it for choice symbols in choices in y mode,\n            # and for symbols of UNKNOWN type (which generate a warning though)\n            if sym.user_value is None and sym.orig_type and \\\n               not (sym.choice and sym.choice.tri_value == 2):\n\n                s += \" (NEW)\"\n\n    if isinstance(node.item, Choice) and node.item.tri_value == 2:\n        # Print the prompt of the selected symbol after the choice for\n        # choices in y mode\n        sym = node.item.selection\n        if sym:\n            for sym_node in sym.nodes:\n                # Use the prompt used at this choice location, in case the\n                # choice symbol is defined in multiple locations\n                if sym_node.parent is node and sym_node.prompt:\n                    s += \" ({})\".format(sym_node.prompt[0])\n                    break\n            else:\n                # If the symbol isn't defined at this choice location, then\n                # just use whatever prompt we can find for it\n                for sym_node in sym.nodes:\n                    if sym_node.prompt:\n                        s += \" ({})\".format(sym_node.prompt[0])\n                        break\n\n    # Print \"--->\" next to nodes that have menus that can potentially be\n    # entered. Print \"----\" if the menu is empty. We don't allow those to be\n    # entered.\n    if node.is_menuconfig:\n        s += \"  --->\" if _shown_nodes(node) else \"  ----\"\n\n    return s\n\n\ndef _should_show_name(node):\n    # Returns True if 'node' is a symbol or choice whose name should shown (if\n    # any, as names are optional for choices)\n\n    # The 'not node.prompt' case only hits in show-all mode, for promptless\n    # symbols and choices\n    return not node.prompt or \\\n           (_show_name and isinstance(node.item, (Symbol, Choice)))\n\n\ndef _value_str(node):\n    # Returns the value part (\"[*]\", \"<M>\", \"(foo)\" etc.) of a menu node\n\n    item = node.item\n\n    if item in (MENU, COMMENT):\n        return \"\"\n\n    # Wouldn't normally happen, and generates a warning\n    if not item.orig_type:\n        return \"\"\n\n    if item.orig_type in (STRING, INT, HEX):\n        return \"({})\".format(item.str_value)\n\n    # BOOL or TRISTATE\n\n    if _is_y_mode_choice_sym(item):\n        return \"(X)\" if item.choice.selection is item else \"( )\"\n\n    tri_val_str = (\" \", \"M\", \"*\")[item.tri_value]\n\n    if len(item.assignable) <= 1:\n        # Pinned to a single value\n        return \"\" if isinstance(item, Choice) else \"-{}-\".format(tri_val_str)\n\n    if item.type == BOOL:\n        return \"[{}]\".format(tri_val_str)\n\n    # item.type == TRISTATE\n    if item.assignable == (1, 2):\n        return \"{{{}}}\".format(tri_val_str)  # {M}/{*}\n    return \"<{}>\".format(tri_val_str)\n\n\ndef _is_y_mode_choice_sym(item):\n    # The choice mode is an upper bound on the visibility of choice symbols, so\n    # we can check the choice symbols' own visibility to see if the choice is\n    # in y mode\n    return isinstance(item, Symbol) and item.choice and item.visibility == 2\n\n\ndef _check_valid(sym, s):\n    # Returns True if the string 's' is a well-formed value for 'sym'.\n    # Otherwise, displays an error and returns False.\n\n    if sym.orig_type not in (INT, HEX):\n        # Anything goes for non-int/hex symbols\n        return True\n\n    base = 10 if sym.orig_type == INT else 16\n    try:\n        int(s, base)\n    except ValueError:\n        _error(\"'{}' is a malformed {} value\"\n               .format(s, TYPE_TO_STR[sym.orig_type]))\n        return False\n\n    for low_sym, high_sym, cond in sym.ranges:\n        if expr_value(cond):\n            low_s = low_sym.str_value\n            high_s = high_sym.str_value\n\n            if not int(low_s, base) <= int(s, base) <= int(high_s, base):\n                _error(\"{} is outside the range {}-{}\"\n                       .format(s, low_s, high_s))\n                return False\n\n            break\n\n    return True\n\n\ndef _range_info(sym):\n    # Returns a string with information about the valid range for the symbol\n    # 'sym', or None if 'sym' doesn't have a range\n\n    if sym.orig_type in (INT, HEX):\n        for low, high, cond in sym.ranges:\n            if expr_value(cond):\n                return \"Range: {}-{}\".format(low.str_value, high.str_value)\n\n    return None\n\n\ndef _is_num(name):\n    # Heuristic to see if a symbol name looks like a number, for nicer output\n    # when printing expressions. Things like 16 are actually symbol names, only\n    # they get their name as their value when the symbol is undefined.\n\n    try:\n        int(name)\n    except ValueError:\n        if not name.startswith((\"0x\", \"0X\")):\n            return False\n\n        try:\n            int(name, 16)\n        except ValueError:\n            return False\n\n    return True\n\n\ndef _getch_compat(win):\n    # Uses get_wch() if available (Python 3.3+) and getch() otherwise. Also\n    # handles a PDCurses resizing quirk.\n\n    if hasattr(win, \"get_wch\"):\n        c = win.get_wch()\n    else:\n        c = win.getch()\n        if 0 <= c <= 255:\n            c = chr(c)\n\n    # Decent resizing behavior on PDCurses requires calling resize_term(0, 0)\n    # after receiving KEY_RESIZE, while ncurses (usually) handles terminal\n    # resizing automatically in get(_w)ch() (see the end of the\n    # resizeterm(3NCURSES) man page).\n    #\n    # resize_term(0, 0) reliably fails and does nothing on ncurses, so this\n    # hack gives ncurses/PDCurses compatibility for resizing. I don't know\n    # whether it would cause trouble for other implementations.\n    if c == curses.KEY_RESIZE:\n        try:\n            curses.resize_term(0, 0)\n        except curses.error:\n            pass\n\n    return c\n\n\ndef _warn(*args):\n    # Temporarily returns from curses to shell mode and prints a warning to\n    # stderr. The warning would get lost in curses mode.\n    curses.endwin()\n    print(\"menuconfig warning: \", end=\"\", file=sys.stderr)\n    print(*args, file=sys.stderr)\n    curses.doupdate()\n\n\n# Ignore exceptions from some functions that might fail, e.g. for small\n# windows. They usually do reasonable things anyway.\n\n\ndef _safe_curs_set(visibility):\n    try:\n        curses.curs_set(visibility)\n    except curses.error:\n        pass\n\n\ndef _safe_addstr(win, *args):\n    # Clip the line to avoid wrapping to the next line, which looks glitchy.\n    # addchstr() would do it for us, but it's not available in the 'curses'\n    # module.\n\n    attr = None\n    if isinstance(args[0], str):\n        y, x = win.getyx()\n        s = args[0]\n        if len(args) == 2:\n            attr = args[1]\n    else:\n        y, x, s = args[:3]\n        if len(args) == 4:\n            attr = args[3]\n\n    maxlen = _width(win) - x\n    s = s.expandtabs()\n\n    try:\n        # The 'curses' module uses wattr_set() internally if you pass 'attr',\n        # overwriting the background style, so setting 'attr' to 0 in the first\n        # case won't do the right thing\n        if attr is None:\n            win.addnstr(y, x, s, maxlen)\n        else:\n            win.addnstr(y, x, s, maxlen, attr)\n    except curses.error:\n        pass\n\n\ndef _safe_addch(win, *args):\n    try:\n        win.addch(*args)\n    except curses.error:\n        pass\n\n\ndef _safe_hline(win, *args):\n    try:\n        win.hline(*args)\n    except curses.error:\n        pass\n\n\ndef _safe_vline(win, *args):\n    try:\n        win.vline(*args)\n    except curses.error:\n        pass\n\n\ndef _safe_move(win, *args):\n    try:\n        win.move(*args)\n    except curses.error:\n        pass\n\n\ndef _change_c_lc_ctype_to_utf8():\n    # See _CHANGE_C_LC_CTYPE_TO_UTF8\n\n    if _IS_WINDOWS:\n        # Windows rarely has issues here, and the PEP 538 implementation avoids\n        # changing the locale on it. None of the UTF-8 locales below were\n        # supported from some quick testing either. Play it safe.\n        return\n\n    def try_set_locale(loc):\n        try:\n            locale.setlocale(locale.LC_CTYPE, loc)\n            return True\n        except locale.Error:\n            return False\n\n    # Is LC_CTYPE set to the C locale?\n    if locale.setlocale(locale.LC_CTYPE) == \"C\":\n        # This list was taken from the PEP 538 implementation in the CPython\n        # code, in Python/pylifecycle.c\n        for loc in \"C.UTF-8\", \"C.utf8\", \"UTF-8\":\n            if try_set_locale(loc):\n                # LC_CTYPE successfully changed\n                return\n\n\nif __name__ == \"__main__\":\n    _main()\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/oldconfig.py",
    "content": "#!/usr/bin/env python\n\n# Copyright (c) 2018-2019, Ulf Magnusson\n# SPDX-License-Identifier: ISC\n\n\"\"\"\nImplements oldconfig functionality.\n\n  1. Loads existing .config\n  2. Prompts for the value of all modifiable symbols/choices that\n     aren't already set in the .config\n  3. Writes an updated .config\n\nThe default input/output filename is '.config'. A different filename can be\npassed in the KCONFIG_CONFIG environment variable.\n\nWhen overwriting a configuration file, the old version is saved to\n<filename>.old (e.g. .config.old).\n\nEntering '?' displays the help text of the symbol/choice, if any.\n\nUnlike 'make oldconfig', this script doesn't print menu titles and comments,\nbut gives Kconfig definition locations. Printing menus and comments would be\npretty easy to add: Look at the parents of each item, and print all menu\nprompts and comments unless they have already been printed (assuming you want\nto skip \"irrelevant\" menus).\n\"\"\"\nfrom __future__ import print_function\n\nimport sys\n\nfrom kconfiglib import Symbol, Choice, BOOL, TRISTATE, HEX, standard_kconfig\n\n\n# Python 2/3 compatibility hack\nif sys.version_info[0] < 3:\n    input = raw_input\n\n\ndef _main():\n    # Earlier symbols in Kconfig files might depend on later symbols and become\n    # visible if their values change. This flag is set to True if the value of\n    # any symbol changes, in which case we rerun the oldconfig to check for new\n    # visible symbols.\n    global conf_changed\n\n    kconf = standard_kconfig(__doc__)\n    print(kconf.load_config())\n\n    while True:\n        conf_changed = False\n\n        for node in kconf.node_iter():\n            oldconfig(node)\n\n        if not conf_changed:\n            break\n\n    print(kconf.write_config())\n\n\ndef oldconfig(node):\n    \"\"\"\n    Prompts the user for a value if node.item is a visible symbol/choice with\n    no user value.\n    \"\"\"\n    # See main()\n    global conf_changed\n\n    # Only symbols and choices can be configured\n    if not isinstance(node.item, (Symbol, Choice)):\n        return\n\n    # Skip symbols and choices that aren't visible\n    if not node.item.visibility:\n        return\n\n    # Skip symbols and choices that don't have a prompt (at this location)\n    if not node.prompt:\n        return\n\n    if isinstance(node.item, Symbol):\n        sym = node.item\n\n        # Skip symbols that already have a user value\n        if sym.user_value is not None:\n            return\n\n        # Skip symbols that can only have a single value, due to selects\n        if len(sym.assignable) == 1:\n            return\n\n        # Skip symbols in choices in y mode. We ask once for the entire choice\n        # instead.\n        if sym.choice and sym.choice.tri_value == 2:\n            return\n\n        # Loop until the user enters a valid value or enters a blank string\n        # (for the default value)\n        while True:\n            val = input(\"{} ({}) [{}] \".format(\n                node.prompt[0], _name_and_loc_str(sym),\n                _default_value_str(sym)))\n\n            if val == \"?\":\n                _print_help(node)\n                continue\n\n            # Substitute a blank string with the default value the symbol\n            # would get\n            if not val:\n                val = sym.str_value\n\n            # Automatically add a \"0x\" prefix for hex symbols, like the\n            # menuconfig interface does. This isn't done when loading .config\n            # files, hence why set_value() doesn't do it automatically.\n            if sym.type == HEX and not val.startswith((\"0x\", \"0X\")):\n                val = \"0x\" + val\n\n            old_str_val = sym.str_value\n\n            # Kconfiglib itself will print a warning here if the value\n            # is invalid, so we don't need to bother\n            if sym.set_value(val):\n                # Valid value input. We're done with this node.\n\n                if sym.str_value != old_str_val:\n                    conf_changed = True\n\n                return\n\n    else:\n        choice = node.item\n\n        # Skip choices that already have a visible user selection...\n        if choice.user_selection and choice.user_selection.visibility == 2:\n            # ...unless there are new visible symbols in the choice. (We know\n            # they have y (2) visibility in that case, because m-visible\n            # symbols get demoted to n-visibility in y-mode choices, and the\n            # user-selected symbol had visibility y.)\n            for sym in choice.syms:\n                if sym is not choice.user_selection and sym.visibility and \\\n                   sym.user_value is None:\n                    # New visible symbols in the choice\n                    break\n            else:\n                # No new visible symbols in the choice\n                return\n\n        # Get a list of available selections. The mode of the choice limits\n        # the visibility of the choice value symbols, so this will indirectly\n        # skip choices in n and m mode.\n        options = [sym for sym in choice.syms if sym.visibility == 2]\n\n        if not options:\n            # No y-visible choice value symbols\n            return\n\n        # Loop until the user enters a valid selection or a blank string (for\n        # the default selection)\n        while True:\n            print(\"{} ({})\".format(node.prompt[0], _name_and_loc_str(choice)))\n\n            for i, sym in enumerate(options, 1):\n                print(\"{} {}. {} ({})\".format(\n                    \">\" if sym is choice.selection else \" \",\n                    i,\n                    # Assume people don't define choice symbols with multiple\n                    # prompts. That generates a warning anyway.\n                    sym.nodes[0].prompt[0],\n                    sym.name))\n\n            sel_index = input(\"choice[1-{}]: \".format(len(options)))\n\n            if sel_index == \"?\":\n                _print_help(node)\n                continue\n\n            # Pick the default selection if the string is blank\n            if not sel_index:\n                choice.selection.set_value(2)\n                break\n\n            try:\n                sel_index = int(sel_index)\n            except ValueError:\n                print(\"Bad index\", file=sys.stderr)\n                continue\n\n            if not 1 <= sel_index <= len(options):\n                print(\"Bad index\", file=sys.stderr)\n                continue\n\n            # Valid selection\n\n            if options[sel_index - 1].tri_value != 2:\n                conf_changed = True\n\n            options[sel_index - 1].set_value(2)\n            break\n\n        # Give all of the non-selected visible choice symbols the user value n.\n        # This makes it so that the choice is no longer considered new once we\n        # do additional passes, if the reason that it was considered new was\n        # that it had new visible choice symbols.\n        #\n        # Only giving visible choice symbols the user value n means we will\n        # prompt for the choice again if later user selections make more new\n        # choice symbols visible, which is correct.\n        for sym in choice.syms:\n            if sym is not choice.user_selection and sym.visibility:\n                sym.set_value(0)\n\n\ndef _name_and_loc_str(sc):\n    # Helper for printing the name of the symbol/choice 'sc' along with the\n    # location(s) in the Kconfig files where it is defined. Unnamed choices\n    # return \"choice\" instead of the name.\n\n    return \"{}, defined at {}\".format(\n        sc.name or \"choice\",\n        \", \".join(\"{}:{}\".format(node.filename, node.linenr)\n                  for node in sc.nodes))\n\n\ndef _print_help(node):\n    print(\"\\n\" + (node.help or \"No help text\\n\"))\n\n\ndef _default_value_str(sym):\n    # Returns the \"m/M/y\" string in e.g.\n    #\n    #   TRISTATE_SYM prompt (TRISTATE_SYM, defined at Kconfig:9) [n/M/y]:\n    #\n    # For string/int/hex, returns the default value as-is.\n\n    if sym.type in (BOOL, TRISTATE):\n        return \"/\".join((\"NMY\" if sym.tri_value == tri else \"nmy\")[tri]\n                        for tri in sym.assignable)\n\n    # string/int/hex\n    return sym.str_value\n\n\nif __name__ == \"__main__\":\n    _main()\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/olddefconfig.py",
    "content": "#!/usr/bin/env python\n\n# Copyright (c) 2018-2019, Ulf Magnusson\n# SPDX-License-Identifier: ISC\n\n\"\"\"\nUpdates an old .config file or creates a new one, by filling in default values\nfor all new symbols. This is the same as picking the default selection for all\nsymbols in oldconfig, or entering the menuconfig interface and immediately\nsaving.\n\nThe default input/output filename is '.config'. A different filename can be\npassed in the KCONFIG_CONFIG environment variable.\n\nWhen overwriting a configuration file, the old version is saved to\n<filename>.old (e.g. .config.old).\n\"\"\"\nimport kconfiglib\n\n\ndef main():\n    kconf = kconfiglib.standard_kconfig(__doc__)\n    print(kconf.load_config())\n    print(kconf.write_config())\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/savedefconfig.py",
    "content": "#!/usr/bin/env python\n\n# Copyright (c) 2019, Ulf Magnusson\n# SPDX-License-Identifier: ISC\n\n\"\"\"\nSaves a minimal configuration file that only lists symbols that differ in value\nfrom their defaults. Loading such a configuration file is equivalent to loading\nthe \"full\" configuration file.\n\nMinimal configuration files are handy to start from when editing configuration\nfiles by hand.\n\nThe default input configuration file is '.config'. A different input filename\ncan be passed in the KCONFIG_CONFIG environment variable.\n\nNote: Minimal configurations can also be generated from within the menuconfig\ninterface.\n\"\"\"\nimport argparse\n\nimport kconfiglib\n\n\ndef main():\n    parser = argparse.ArgumentParser(\n        formatter_class=argparse.RawDescriptionHelpFormatter,\n        description=__doc__)\n\n    parser.add_argument(\n        \"--kconfig\",\n        default=\"Kconfig\",\n        help=\"Base Kconfig file (default: Kconfig)\")\n\n    parser.add_argument(\n        \"--out\",\n        metavar=\"MINIMAL_CONFIGURATION\",\n        default=\"defconfig\",\n        help=\"Output filename for minimal configuration (default: defconfig)\")\n\n    args = parser.parse_args()\n\n    kconf = kconfiglib.Kconfig(args.kconfig, suppress_traceback=True)\n    print(kconf.load_config())\n    print(kconf.write_min_config(args.out))\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/setconfig.py",
    "content": "#!/usr/bin/env python\n\n# Copyright (c) 2019, Ulf Magnusson\n# SPDX-License-Identifier: ISC\n\n\"\"\"\nSimple utility for setting configuration values from the command line.\n\nSample usage:\n\n  $ setconfig FOO_SUPPORT=y BAR_BITS=8\n\nNote: Symbol names should not be prefixed with 'CONFIG_'.\n\nThe exit status on errors is 1.\n\nThe default input/output configuration file is '.config'. A different filename\ncan be passed in the KCONFIG_CONFIG environment variable.\n\nWhen overwriting a configuration file, the old version is saved to\n<filename>.old (e.g. .config.old).\n\"\"\"\nimport argparse\nimport sys\n\nimport kconfiglib\n\n\ndef main():\n    parser = argparse.ArgumentParser(\n        formatter_class=argparse.RawDescriptionHelpFormatter,\n        description=__doc__)\n\n    parser.add_argument(\n        \"--kconfig\",\n        default=\"Kconfig\",\n        help=\"Base Kconfig file (default: Kconfig)\")\n\n    parser.add_argument(\n        \"--no-check-exists\",\n        dest=\"check_exists\",\n        action=\"store_false\",\n        help=\"Ignore assignments to non-existent symbols instead of erroring \"\n             \"out\")\n\n    parser.add_argument(\n        \"--no-check-value\",\n        dest=\"check_value\",\n        action=\"store_false\",\n        help=\"Ignore assignments that didn't \\\"take\\\" (where the symbol got a \"\n             \"different value, e.g. due to unsatisfied dependencies) instead \"\n             \"of erroring out\")\n\n    parser.add_argument(\n        \"assignments\",\n        metavar=\"ASSIGNMENT\",\n        nargs=\"*\",\n        help=\"A 'NAME=value' assignment\")\n\n    args = parser.parse_args()\n\n    kconf = kconfiglib.Kconfig(args.kconfig, suppress_traceback=True)\n    print(kconf.load_config())\n\n    for arg in args.assignments:\n        if \"=\" not in arg:\n            sys.exit(\"error: no '=' in assignment: '{}'\".format(arg))\n        name, value = arg.split(\"=\", 1)\n\n        if name not in kconf.syms:\n            if not args.check_exists:\n                continue\n            sys.exit(\"error: no symbol '{}' in configuration\".format(name))\n\n        sym = kconf.syms[name]\n\n        if not sym.set_value(value):\n            sys.exit(\"error: '{}' is an invalid value for the {} symbol {}\"\n                     .format(value, kconfiglib.TYPE_TO_STR[sym.orig_type],\n                             name))\n\n        if args.check_value and sym.str_value != value:\n            sys.exit(\"error: {} was assigned the value '{}', but got the \"\n                     \"value '{}'. Check the symbol's dependencies, and make \"\n                     \"sure that it has a prompt.\"\n                     .format(name, value, sym.str_value))\n\n    print(kconf.write_config())\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/setup.cfg",
    "content": "[bdist_wheel]\n# We support both Python 2 and Python 3\nuniversal = 1\n\n[metadata]\n# Include the license file in wheels\nlicense_file = LICENSE.txt\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/setup.py",
    "content": "import io\nimport os\n\nimport setuptools\n\n\nsetuptools.setup(\n    name=\"kconfiglib\",\n    # MAJOR.MINOR.PATCH, per http://semver.org\n    version=\"13.7.0\",\n    description=\"A flexible Python Kconfig implementation\",\n\n    # Make sure that README.rst decodes on Python 3 in environments that use\n    # the C locale (which implies ASCII), by explicitly giving the encoding.\n    #\n    # io.open() has the 'encoding' parameter on both Python 2 and 3. open()\n    # doesn't have it on Python 2. This lets us use the same code for both.\n    long_description=io.open(\n        os.path.join(os.path.dirname(__file__), \"README.rst\"),\n        encoding=\"utf-8\"\n    ).read(),\n\n    url=\"https://github.com/ulfalizer/Kconfiglib\",\n    author='Ulf \"Ulfalizer\" Magnusson',\n    author_email=\"ulfalizer@gmail.com\",\n    keywords=\"kconfig, kbuild, menuconfig, configuration-management\",\n    license=\"ISC\",\n\n    py_modules=(\n        \"kconfiglib\",\n        \"menuconfig\",\n        \"guiconfig\",\n        \"genconfig\",\n        \"oldconfig\",\n        \"olddefconfig\",\n        \"savedefconfig\",\n        \"defconfig\",\n        \"alldefconfig\",\n        \"allnoconfig\",\n        \"allmodconfig\",\n        \"allyesconfig\",\n        \"listnewconfig\",\n        \"setconfig\",\n    ),\n\n    entry_points={\n        \"console_scripts\": (\n            \"menuconfig = menuconfig:_main\",\n            \"guiconfig = guiconfig:_main\",\n            \"genconfig = genconfig:main\",\n            \"oldconfig = oldconfig:_main\",\n            \"olddefconfig = olddefconfig:main\",\n            \"savedefconfig = savedefconfig:main\",\n            \"defconfig = defconfig:main\",\n            \"alldefconfig = alldefconfig:main\",\n            \"allnoconfig = allnoconfig:main\",\n            \"allmodconfig = allmodconfig:main\",\n            \"allyesconfig = allyesconfig:main\",\n            \"listnewconfig = listnewconfig:main\",\n            \"setconfig = setconfig:main\",\n        )\n    },\n\n    # Note: windows-curses is not automatically installed on Windows anymore,\n    # because it made Kconfiglib impossible to install on MSYS2 with pip\n\n    # Needs support for unnumbered {} in format() and argparse\n    python_requires=\">=2.7,!=3.0.*,!=3.1.*\",\n\n    project_urls={\n        \"GitHub repository\": \"https://github.com/ulfalizer/Kconfiglib\",\n        \"Examples\": \"https://github.com/ulfalizer/Kconfiglib/tree/master/examples\",\n    },\n\n    classifiers=[\n        \"Development Status :: 5 - Production/Stable\",\n        \"Intended Audience :: Developers\",\n        \"Topic :: Software Development :: Build Tools\",\n        \"Topic :: System :: Operating System Kernels :: Linux\",\n        \"License :: OSI Approved :: ISC License (ISCL)\",\n        \"Operating System :: POSIX\",\n        \"Operating System :: Microsoft :: Windows\",\n        \"Programming Language :: Python :: 2\",\n        \"Programming Language :: Python :: 2.7\",\n        \"Programming Language :: Python :: 3\",\n        \"Programming Language :: Python :: 3.2\",\n        \"Programming Language :: Python :: 3.3\",\n        \"Programming Language :: Python :: 3.4\",\n        \"Programming Language :: Python :: 3.5\",\n        \"Programming Language :: Python :: 3.6\",\n        \"Programming Language :: Python :: 3.7\",\n        \"Programming Language :: Python :: 3.8\",\n        \"Programming Language :: Python :: Implementation :: CPython\",\n        \"Programming Language :: Python :: Implementation :: PyPy\",\n    ]\n)\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kappend",
    "content": "config MODULES\n    def_bool y\n\nconfig BOOL\n    bool \"bool 1\"\n\nconfig STRING\n    string \"string\"\n\nconfig IGNOREME\n    bool \"ignore me\"\n    default y\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kassignable",
    "content": "config MODULES\n\tbool \"modules\"\n\toption modules\n\n\n# Things that should never be .assignable\n\nif UNDEFINED && \"const\"\nendif\n\nconfig NO_PROMPT\n\tbool\n\nconfig STRING\n\tstring \"string\"\n\nconfig INT\n\tint \"int\"\n\nconfig HEX\n\thex \"hex\"\n\n\n# Non-selected symbols\n\nconfig Y_VIS_BOOL\n\tbool \"y-vis bool\"\n\nconfig M_VIS_BOOL\n\tbool \"m-vis bool\" if m\n\nconfig N_VIS_BOOL\n\tbool \"n-vis bool\" if n\n\nconfig Y_VIS_TRI\n\ttristate \"y-vis tri\"\n\nconfig M_VIS_TRI\n\ttristate \"m-vis tri\" if m\n\nconfig N_VIS_TRI\n\ttristate \"n-vis tri\" if n\n\n\n# Symbols selected to y\n\nconfig Y_SELECTOR\n\tdef_tristate y\n\n\tselect Y_SEL_Y_VIS_BOOL\n\tselect Y_SEL_M_VIS_BOOL\n\tselect Y_SEL_N_VIS_BOOL\n\n\tselect Y_SEL_Y_VIS_TRI\n\tselect Y_SEL_M_VIS_TRI\n\tselect Y_SEL_N_VIS_TRI\n\nconfig Y_SEL_Y_VIS_BOOL\n\tbool \"y-sel y-vis bool\"\n\nconfig Y_SEL_M_VIS_BOOL\n\tbool \"y-sel m-vis bool\" if m\n\nconfig Y_SEL_N_VIS_BOOL\n\tbool \"y-sel n-vis bool\" if n\n\nconfig Y_SEL_Y_VIS_TRI\n\ttristate \"y-sel y-vis tri\"\n\nconfig Y_SEL_M_VIS_TRI\n\ttristate \"y-sel m-vis tri\" if m\n\nconfig Y_SEL_N_VIS_TRI\n\ttristate \"y-sel n-vis tri\" if n\n\n\n# Symbols selected to m\n\nconfig M_SELECTOR\n\tdef_tristate m\n\n\tselect M_SEL_Y_VIS_BOOL\n\tselect M_SEL_M_VIS_BOOL\n\tselect M_SEL_N_VIS_BOOL\n\n\tselect M_SEL_Y_VIS_TRI\n\tselect M_SEL_M_VIS_TRI\n\tselect M_SEL_N_VIS_TRI\n\nconfig M_SEL_Y_VIS_BOOL\n\tbool \"m-sel y-vis bool\"\n\nconfig M_SEL_M_VIS_BOOL\n\tbool \"m-sel m-vis bool\" if m\n\nconfig M_SEL_N_VIS_BOOL\n\tbool \"m-sel n-vis bool\" if n\n\nconfig M_SEL_Y_VIS_TRI\n\ttristate \"m-sel y-vis tri\"\n\nconfig M_SEL_M_VIS_TRI\n\ttristate \"m-sel m-vis tri\" if m\n\nconfig M_SEL_N_VIS_TRI\n\ttristate \"m-sel n-vis tri\" if n\n\n\n# Symbols implied to y\n\nconfig Y_IMPLIER\n\tdef_tristate y\n\n\timply Y_IMP_Y_VIS_BOOL\n\timply Y_IMP_M_VIS_BOOL\n\timply Y_IMP_N_VIS_BOOL\n\n\timply Y_IMP_Y_VIS_TRI\n\timply Y_IMP_M_VIS_TRI\n\timply Y_IMP_N_VIS_TRI\n\nconfig Y_IMP_Y_VIS_BOOL\n\tbool \"y-imp y-vis bool\"\n\nconfig Y_IMP_M_VIS_BOOL\n\tbool \"y-imp m-vis bool\" if m\n\nconfig Y_IMP_N_VIS_BOOL\n\tbool \"y-imp n-vis bool\" if n\n\nconfig Y_IMP_Y_VIS_TRI\n\ttristate \"y-imp y-vis tri\"\n\nconfig Y_IMP_M_VIS_TRI\n\ttristate \"y-imp m-vis tri\" if m\n\nconfig Y_IMP_N_VIS_TRI\n\ttristate \"y-imp n-vis tri\" if n\n\n\n# Symbols implied to m (never affects assignable values)\n\nconfig M_IMPLIER\n\tdef_tristate m\n\n\timply M_IMP_Y_VIS_BOOL\n\timply M_IMP_M_VIS_BOOL\n\timply M_IMP_N_VIS_BOOL\n\n\timply M_IMP_Y_VIS_TRI\n\timply M_IMP_M_VIS_TRI\n\timply M_IMP_N_VIS_TRI\n\nconfig M_IMP_Y_VIS_BOOL\n\tbool \"m-imp y-vis bool\"\n\nconfig M_IMP_M_VIS_BOOL\n\tbool \"m-imp m-vis bool\" if m\n\nconfig M_IMP_N_VIS_BOOL\n\tbool \"m-imp n-vis bool\" if n\n\nconfig M_IMP_Y_VIS_TRI\n\ttristate \"m-imp y-vis tri\"\n\nconfig M_IMP_M_VIS_TRI\n\ttristate \"m-imp m-vis tri\" if m\n\nconfig M_IMP_N_VIS_TRI\n\ttristate \"m-imp n-vis tri\" if n\n\n\n# Symbols in y-mode choice\n\nchoice Y_CHOICE\n\tbool \"y-mode choice\"\n\nconfig Y_CHOICE_BOOL\n\tbool \"y-mode choice bool\"\n\nconfig Y_CHOICE_TRISTATE\n\ttristate \"y-mode choice tristate\"\n\nconfig Y_CHOICE_N_VIS_TRISTATE\n\ttristate \"y-mode choice tristate invisible\" if n\n\nendchoice\n\n\n# Symbols in m/y-mode choice\n\nchoice MY_CHOICE\n\ttristate \"m/y-mode choice\"\n\nconfig MY_CHOICE_BOOL\n\tbool \"m/y-mode choice bool\"\n\nconfig MY_CHOICE_TRISTATE\n\ttristate \"m/y-mode choice tristate\"\n\nconfig MY_CHOICE_N_VIS_TRISTATE\n\ttristate \"m/y-mode choice tristate invisible\" if n\n\nendchoice\n\n\n# Choices with some other possible modes\n\nchoice NMY_CHOICE\n\ttristate \"n/m/y-mode choice\"\n\toptional\nendchoice\n\nchoice NY_CHOICE\n\tbool \"n/y-mode choice\"\n\toptional\nendchoice\n\nchoice NM_CHOICE\n\ttristate \"n/m-mode choice\" if m\n\toptional\nendchoice\n\nchoice M_CHOICE\n\ttristate \"m-mode choice\" if m\nendchoice\n\nchoice N_CHOICE\n\ttristate \"n-mode choice\" if n\nendchoice\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kchoice",
    "content": "config MODULES\n    bool \"modules\"\n\n# bool/tristate and optional\n\nchoice BOOL\n    bool \"bool\"\nconfig B_1\n    tristate \"B_1\"\nconfig B_2\n    tristate \"B_2\"\nendchoice\n\nchoice BOOL_OPT\n    bool \"bool optional\"\n    optional\nconfig BO_1\n    tristate \"BO_1\"\nconfig BO_2\n    tristate \"BO_2\"\nendchoice\n\nchoice TRISTATE\n    tristate \"tristate\"\nconfig T_1\n    tristate \"T_1\"\nconfig T_2\n    tristate \"T_2\"\nendchoice\n\nchoice TRISTATE_OPT\n    tristate \"tristate optional\"\n    optional\nconfig TO_1\n    tristate \"TO_1\"\nconfig TO_2\n    tristate \"TO_2\"\nendchoice\n\n# m-visibility\n\nchoice BOOL_M\n    bool \"bool m\" if m\nconfig BM_1\n    tristate \"BM_1\"\nconfig BM_2\n    tristate \"BM_2\"\nendchoice\n\nchoice TRISTATE_M\n    tristate \"tristate m\" if m\nconfig TM_1\n    tristate \"TM_1\"\nconfig TM_2\n    tristate \"TM_2\"\nendchoice\n\n# Defaults\n\nconfig TRISTATE_SYM\n    tristate \"tristate\"\n\nchoice DEFAULTS\n    bool \"defaults\"\n    default OPT_1 if n\n    default OPT_2 if TRISTATE_SYM\n    default OPT_4\nconfig OPT_1\n    tristate \"OPT_1\"\nconfig OPT_2\n    tristate \"OPT_2\"\nconfig OPT_3\n    tristate \"OPT_3\"\nconfig OPT_4\n    tristate \"OPT_4\"\nendchoice\n\nchoice DEFAULTS_NOT_VISIBLE\n    bool \"defaults not visible\"\n    # Skipped due to condition\n    default OPT_6 if n\n    # Skipped because OPT_7 is not visible\n    default OPT_7\n    # This one should apply\n    default OPT_8\nconfig OPT_5\n    tristate \"OPT_5\"\nconfig OPT_6\n    tristate \"OPT_6\"\nconfig OPT_7\n    tristate \"OPT_7\" if n\nconfig OPT_8\n    tristate \"OPT_8\"\nconfig OPT_9\n    tristate \"OPT_9\"\nendchoice\n\n# Choices without an explicitly specified type should get the type of the first\n# symbol with a type\n\nchoice NO_TYPE_BOOL\n    prompt \"no type bool\"\nconfig NTB_1\n    bool \"NTB_1\"\nconfig NTB_2\n    tristate \"NTB_2\"\nendchoice\n\nchoice NO_TYPE_TRISTATE\n    prompt \"no type tristate\"\nconfig NTT_1\nconfig NTT_2\n    tristate \"NTB_2\"\nconfig NTT_3\n    bool \"NTT_3\"\nendchoice\n\n# Choice items without an explicitly specified type should get the type of the\n# choice\n\nchoice MISSING_MEMBER_TYPES_1\n    bool \"missing member types\"\nconfig MMT_1\nconfig MMT_2\nconfig MMT_3\n    tristate\nendchoice\n\nchoice MISSING_MEMBER_TYPES_2\nconfig MMT_4\nconfig MMT_5\n    bool\nendchoice\n\n# Choice where the default selection (the first symbol) depends on another\n# symbol. If that symbol becomes 'n', the default selection should change to\n# the first visible symbol in the choice.\n\nchoice DEFAULT_WITH_DEP\n    bool \"default with dep\"\n\nconfig A\n    bool \"A\"\n    depends on DEP\n\nconfig B\n    bool \"B\"\n\nendchoice\n\nconfig DEP\n    bool \"dep\"\n\n# Choice with symbols that shouldn't be considered choice symbols because they\n# depend on the preceding symbol. This might be a kconfig bug, but some things\n# use it, so we need to emulate it.\n\nchoice WEIRD_SYMS\n    bool \"weird symbols that aren't considered part of the choice\"\n\n# Only WS1 is part of the choice\nconfig WS1\n    bool \"WS1\"\n\nconfig WS2\n    bool \"WS2\"\n    depends on WS1\n\nconfig WS3\n    bool\n    depends on WS2\n\nconfig WS4\n    bool\n    depends on WS1\n\nconfig WS5\n    bool \"WS5\" if WS1\n\n# 'if' has the same effect, so only WS6 is part of the choice\nconfig WS6\n    bool \"WS6\"\n\nif WS6\n\nconfig WS7\n    bool\n\nconfig WS8\n    bool \"WS8\"\n\nendif\n\n# Should also be part of the choice\nconfig WS9\n    bool \"WS9\"\n\nendchoice\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kdefconfig_existent",
    "content": "# $FOO is \"defconfig_2\"\n\nconfig A\n    string\n    option defconfig_list\n    default \"Kconfiglib/tests/defconfig_1\" if y && !n && n\n    default \"Kconfiglib/tests/$FOO\"\n    default \"Kconfiglib/tests/defconfig_1\"\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kdefconfig_existent_but_n",
    "content": "# $FOO is \"defconfig_2\"\n# Should produce None due to the \"depends on n\"\n\nconfig A\n    string\n    depends on n\n    option defconfig_list\n    default \"Kconfiglib/tests/defconfig_1\" if y && !n && n\n    default \"Kconfiglib/tests/$FOO\"\n    default \"Kconfiglib/tests/defconfig_1\"\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kdefconfig_nonexistent",
    "content": "config A\n    string\n    option defconfig_list\n    default \"Kconfiglib/tests/non_existent_1\"\n    default \"Kconfiglib/tests/non_existent_2\"\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kdefconfig_srctree",
    "content": "config A\n    string\n    option defconfig_list\n    default \"sub/defconfig_in_sub\" # Assume this doesn't exist\n    default \"Kconfiglib/tests/defconfig_2\"\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kdepcopy",
    "content": "# We verify that the properties below end up in definition order\n\nconfig MULTIDEF\n    bool\n    default A\n    default B\n    select AA\n    imply AA\n\nif FOO\n\nconfig MULTIDEF\n    default C\n    default D\n    select BB\n    imply BB\n\nif BAR\n\nconfig MULTIDEF\n    default E\n    default F\n    select CC\n    imply CC\n\nmenu \"menu\"\n\nconfig MULTIDEF\n    default G\n    default H\n    select DD\n    imply DD\n\nconfig MULTIDEF\n    default I\n    default J\n    select EE\n    imply EE\n\nendmenu\n\nconfig MULTIDEF\n    default K\n    default L\n    select FF\n    imply FF\n\nconfig MULTIDEF\n    default M\n    default N\n    select GG\n    imply GG\n\nendif\n\nconfig MULTIDEF\n    default O\n    default P\n    select HH\n    select II\n    imply HH\n    imply II\n\nendif\n\nconfig MULTIDEF\n    default Q\n    default R\n    select JJ\n    imply JJ\n\n\n# Same test with choice symbols involved\n\nconfig MULTIDEF_CHOICE\n    bool\n    select A\n\nchoice\n    bool \"choice\"\n\nconfig MULTIDEF_CHOICE\n    bool \"multidef choice\"\n    select B\n\nendchoice\n\nconfig MULTIDEF_CHOICE\n    bool\n    select C\n\n\n# Same test with ranges involved\n\nconfig MULTIDEF_RANGE\n    int\n    range A _\n\nmenu \"menu\"\n\nconfig MULTIDEF_RANGE\n    int\n    range B _\n\nif FOO\n\nconfig MULTIDEF_RANGE\n    int\n    range C _\n\nendif\n\nconfig MULTIDEF_RANGE\n    int\n    range D _\n\nendmenu\n\nconfig MULTIDEF_RANGE\n    int\n    range E _\n\nconfig MULTIDEF_RANGE\n    int\n    range F _\n\n\n# Same test for a choice\n\nchoice MULTICHOICE\n    bool \"choice\"\n    default A\n\nconfig A\n    bool \"A\"\n\nconfig B\n    bool \"B\"\n\nconfig C\n    bool \"C\"\n\nconfig D\n    bool \"C\"\n\nconfig E\n    bool \"C\"\n\nendchoice\n\nif FOO\n\nchoice MULTICHOICE\n    default B\nendchoice\n\nmenu \"menu\"\n\nchoice MULTICHOICE\n    default C\nendchoice\n\nendmenu\n\nchoice MULTICHOICE\n    default D\nendchoice\n\nendif\n\nchoice MULTICHOICE\n    default E\nendchoice\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kdeploop0",
    "content": "config FOO\n    bool\n    depends on FOO\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kdeploop1",
    "content": "config FOO\n    bool\n    select FOO\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kdeploop10",
    "content": "config A\n    bool\n    depends on B\n\nconfig B\n    bool\n    depends on C = 7\n\nconfig C\n    int\n    range D 8\n\nconfig D\n    int\n    default 3 if E\n    default 8\n\nconfig E\n    bool\n\nconfig F\n    bool\n    select E if G\n\nconfig G\n    bool\n    depends on H\n\nchoice\n    bool \"choice\"\n\nconfig H\n    bool \"H\"\n    depends on I\n\nendchoice\n\nchoice\n    bool \"choice\" if J\n\nconfig I\n    bool \"I\"\n\nendchoice\n\nconfig J\n    bool\n    depends on A\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kdeploop2",
    "content": "config FOO\n    bool\n    default FOO\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kdeploop3",
    "content": "config FOO\n    bool\n    default y if FOO\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kdeploop4",
    "content": "config FOO\n    bool\n    depends on BAR\n\nconfig BAR\n    bool\n    depends on FOO\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kdeploop5",
    "content": "config FOO\n    bool\n    select BAR\n\nconfig BAR\n    bool\n    select FOO\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kdeploop6",
    "content": "config FOO\n    bool\n\nconfig BAR\n    bool\n    select FOO if FOO\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kdeploop7",
    "content": "choice\n    bool \"choice\"\n\nconfig FOO\n    bool \"foo\"\n    depends on BAR\n\nconfig BAR\n    bool \"bar\"\n\nendchoice\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kdeploop8",
    "content": "choice\n    bool \"choice\"\n    default FOO if FOO\n\nconfig FOO\n    bool \"foo\"\n\nendchoice\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kdeploop9",
    "content": "choice\n    bool \"choice\" if FOO\n\nconfig FOO\n    bool \"foo\"\n\nendchoice\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kdirdep",
    "content": "config NO_DEP_SYM\n    bool\n\nconfig DEP_SYM\n    bool\n    depends on A\n\nconfig DEP_SYM\n    depends on B && C\n\nconfig DEP_SYM\n    depends on !D\n\n\nchoice NO_DEP_CHOICE\n    bool \"no dep. choice\"\nendchoice\n\nchoice DEP_CHOICE\n    bool \"dep. choice\"\n    depends on A\nendchoice\n\nchoice DEP_CHOICE\n    depends on B\nendchoice\n\nchoice DEP_CHOICE\n    depends on C\nendchoice\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kescape",
    "content": "config STRING\n    string \"string\"\n    default \"\\\"\\\\\"\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Keval",
    "content": "# Enabled/disabled in the test\nconfig MODULES\n    bool \"modules\"\n    option modules\n\nconfig N\n    def_tristate n\n\nconfig M\n    def_tristate m\n\nmenuconfig Y\n    def_tristate y\n    prompt \"foo\"\n\nconfig Y_STRING\n    string\n    default \"y\"\n\nconfig FOO_BAR_STRING\n    string\n    default \"foo bar\"\n\nconfig INT_37\n    int\n    default 37\n\nconfig HEX_0X37\n    hex\n    default 0x37\n\nconfig HEX_37\n    hex\n    default 37\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kexpr_items",
    "content": "config TEST\n    bool\n    default A && (B || !C && D = \"E\") || F > G || !!!H\n\nchoice CHOICE\n    bool \"choice\"\n\nconfig TEST_CHOICE\n    bool \"test choice\" if A\n\nendchoice\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kheader",
    "content": "# Used to test headers in .config and header files\n\nconfig FOO\n\tbool \"foo\"\n\tdefault y\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Khelp",
    "content": "config TWO_HELP_STRINGS\n    bool\n    help\n      first help string\n\n\n\n\nconfig TWO_HELP_STRINGS\n    help\n      second help string\n\nconfig NO_BLANK_AFTER_HELP\n    bool\n    help\n      help for\n      NO_BLANK_AFTER_HELP\nchoice CHOICE_HELP\n    bool \"choice with help\"\n    help\n  help for\n  CHOICE_HELP\nendchoice\n\nconfig HELP_TERMINATED_BY_COMMENT\n  bool\n  help\n a\n b\n c\n#\n\nconfig TRICKY_HELP\n  bool\n  -help---\n\n\n  a\n   b\n    c\n\n   d\n    e\n     f\n\n\n  g\n   h\n    i\n#\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kifremoval",
    "content": "# Test some tricky cases that give consecutive 'if' nodes even after\n# flattening. Simple cases are exercised a ton elsewhere.\n\nif X\nendif\nif X\nendif\n\nconfig A\n\nif X\nendif\nif X\nendif\n\nconfig B\n\nif X\nendif\nif X\nendif\nif X\nendif\n\nconfig C\n\nif X\n  if X\n    if X\n    endif\n    if X\n    endif\n  endif\n  if X\n    if X\n    endif\n    if X\n    endif\n  endif\n  config D\nendif\nif X\nendif\n\nmenu \"E\"\n  if X\n    if X\n    endif\n  endif\n  if X\n    if X\n    endif\n  endif\nendmenu\n\nmenu \"F\"\n  if X\n  endif\n  if X\n  endif\n  if X\n    if X\n    endif\n    if X\n    endif\n    menu \"G\"\n    endmenu\n  endif\nendmenu\n\nchoice H\n  if X\n    if X\n    endif\n  endif\n  if X\n    if X\n    endif\n  endif\nendchoice\n\nchoice I\n  if X\n  endif\n  if X\n  endif\n  if X\n    if X\n    endif\n    if X\n    endif\n    config J\n  endif\nendchoice\n\nif X\nendif\nif X\nendif\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kimply",
    "content": "config MODULES\n    def_bool y\n    option modules\n\n#\n# Implied symbols with unmet and met direct dependencies\n#\n\nconfig IMPLY_DIRECT_DEPS\n    def_tristate y\n    imply UNMET_DIRECT_1\n    imply UNMET_DIRECT_2\n    imply UNMET_DIRECT_3\n    imply MET_DIRECT_1\n    imply MET_DIRECT_2\n    imply MET_DIRECT_3\n    imply MET_DIRECT_4\n\nconfig UNMET_DIRECT_1\n    tristate\n    depends on n\n\nif n\nconfig UNMET_DIRECT_2\n    tristate\nendif\n\nmenu \"menu\"\n    depends on n\n\nconfig UNMET_DIRECT_3\n    tristate\n\nendmenu\n\nconfig MET_DIRECT_1\n    tristate\n\nconfig MET_DIRECT_2\n    depends on y\n    tristate\n\nif y\nconfig MET_DIRECT_3\n    tristate\nendif\n\nmenu \"menu\"\n    depends on y\n\nconfig MET_DIRECT_4\n    tristate\n\nendmenu\n\n#\n# 'imply' with condition\n#\n\nconfig IMPLY_COND\n    def_tristate y\n    tristate\n    imply IMPLIED_N_COND if n\n    imply IMPLIED_M_COND if m\n    imply IMPLIED_Y_COND if y\n\nconfig IMPLIED_N_COND\n    tristate\n\nconfig IMPLIED_M_COND\n    tristate\n\nconfig IMPLIED_Y_COND\n    tristate\n\n#\n# Implying from symbol with value n\n#\n\n# Will default to 'n'\nconfig IMPLY_N_1\n    tristate\n    imply IMPLIED_FROM_N_1\n\n# This test also disables the imply, so it's kinda redundant, but why not\nif n\nconfig IMPLY_N_2\n    tristate\n    imply IMPLIED_FROM_N_2\nendif\n\nconfig IMPLIED_FROM_N_1\n    tristate\n\nconfig IMPLIED_FROM_N_2\n    tristate\n\n#\n# Implying from symbol with value m\n#\n\nconfig IMPLY_M\n    def_tristate m\n    imply IMPLIED_M\n    # Implying a bool to 'm' makes it default to 'y'\n    imply IMPLIED_M_BOOL\n\nconfig IMPLIED_M\n    tristate\n\nconfig IMPLIED_M_BOOL\n    bool\n\n#\n# 'imply' which should raise an 'm' default to 'y'\n#\n\nconfig IMPLY_M_TO_Y\n    tristate\n    default y\n    imply IMPLIED_M_TO_Y\n\nconfig IMPLIED_M_TO_Y\n    tristate\n    default m\n\n#\n# Used for testing user values\n#\n\nconfig DIRECT_DEP\n    tristate \"direct dep\"\n\nconfig IMPLY\n    tristate \"imply\"\n    imply IMPLIED_TRISTATE\n    imply IMPLIED_BOOL\n\nconfig IMPLIED_TRISTATE\n    tristate \"implied tristate\"\n    depends on DIRECT_DEP\n\nconfig IMPLIED_BOOL\n    bool \"implied bool\"\n    depends on DIRECT_DEP\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kinclude_path",
    "content": "config TOP\n\tbool\n\nsource \"Kinclude_path_sourced_1\"\n\nconfig TOP\n\tbool\n\nsource \"Kinclude_path_sourced_1\"\n\nconfig TOP\n\tbool\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kinclude_path_sourced_1",
    "content": "config ONE_DOWN\n\tbool\n\nsource \"Kinclude_path_sourced_2\"\n\nconfig ONE_DOWN\n\tbool\n\nsource \"Kinclude_path_sourced_2\"\n\nconfig ONE_DOWN\n\tbool\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kinclude_path_sourced_2",
    "content": "config TWO_DOWN\n\tbool\n\nmenu \"menu\"\nendmenu\n\ncomment \"comment\"\n\nchoice\n\tbool \"choice\"\nendchoice\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kitemlists",
    "content": "comment \"comment 1\"\n\nchoice\n    bool \"choice 1\"\nendchoice\n\nmenu \"menu 1\"\n\nchoice NAMED\n    bool \"choice 2\"\nendchoice\n\nmenu \"menu 2\"\nmenu \"menu 3\"\ncomment \"comment 2\"\nendmenu\n\nchoice\n    bool \"choice 3\"\nendchoice\n\nchoice NAMED\n    bool\nendchoice\n\nendmenu\n\nmenu \"menu 4\"\nendmenu\n\ncomment \"comment 3\"\n\nendmenu\n\nmenu \"menu 5\"\nendmenu\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Klocation",
    "content": "if UNDEFINED\nendif\n\nconfig ONE_DEF\n    bool\n\nconfig TWO_DEF\n    bool\n\nconfig TWO_DEF\n    bool\n\nconfig MANY_DEF\n    bool\n\n# Throw in some line continuations too to make sure it doesn't mess up the line\n# numbers\nif y && \\\n   y\nif y && \\\n   y && \\\n   y\n\n# Throw in some help texts too\n\nconfig HELP_1\n    bool \"help 1\"\n    help\nconfig HELP_2\n    bool \"help 2\"\n    help\n      foo\n      bar\n\n        baz\n\nconfig HELP_3\n    help\n      foo\n      bar\n    bool\nconfig \\\nMANY_DEF\n\nconfig MANY_DEF\n\nendif\nendif\n\n# Expands to \"tests/Klocation_sourced\"\nsource \"$TESTS_DIR_FROM_ENV/Klocation$_SOURCED\"\n\n# Expands to \"sub/Klocation_rsourced\"\nrsource \"$SUB_DIR_FROM_ENV/Klocation$_RSOURCED\"\n\n# Expands to \"tests/*ub/Klocation_gsourced[12]\", matching\n# tests/sub/Klocation_gsourced{1,2}\nsource \"$TESTS_DIR_FROM_ENV/*ub/Klocation$_GSOURCED[12]\"\n# Test old syntax too\ngsource \"$TESTS_DIR_FROM_ENV/*ub/Klocation$_GSOURCED[12]\"\n\n# Expands to \"sub/Klocation_grsourced[12]\", matching\n# tests/sub/Klocation_grsourced{1,2}\nrsource \"$SUB_DIR_FROM_ENV/Klocation$_GRSOURCED[12]\"\n# Test old syntax too\ngrsource \"$SUB_DIR_FROM_ENV/Klocation$_GRSOURCED[12]\"\n\n# No-ops\nosource \"nonexistent\"\nosource \"nonexistent*\"\ngsource \"nonexistent\"\ngsource \"nonexistent*\"\norsource \"nonexistent\"\norsource \"nonexistent*\"\ngrsource \"nonexistent\"\ngrsource \"nonexistent*\"\n\nconfig MANY_DEF\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Klocation_sourced",
    "content": "\n\nconfig MANY_DEF\n\nchoice CHOICE_ONE_DEF\n\tbool \"one-def choice\"\nendchoice\n\nchoice CHOICE_TWO_DEF\n\tbool \"two-def choice 1\"\nendchoice\n\nchoice CHOICE_TWO_DEF\n\tbool \"two-def choice 2\"\nendchoice\n\nconfig MENU_HOOK\n\tbool\n\nmenu \"menu\"\nendmenu\n\nconfig COMMENT_HOOK\n\tbool\n\ncomment \"comment\"\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kmainmenu",
    "content": "config FOO\n    string\n    option env=\"FOO\"\n\nmainmenu \"---$FOO---\"\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kmenuconfig",
    "content": "# Menu nodes with is_menuconfig False\n\nconfig NOT_MENUCONFIG_1\n\tbool\n\nconfig NOT_MENUCONFIG_2\n\tbool \"not menuconfig 2\"\n\nconfig MENUCONFIG_MULTI_DEF\n\tbool \"menuconfig multi def 1\"\n\nconfig COMMENT_HOOK\n\tbool\n\ncomment \"not menuconfig 3\"\n\n\n# Menu nodes with is_menuconfig True\n\nmenuconfig MENUCONFIG_1\n\tbool \"menuconfig 1\"\n\nmenuconfig MENUCONFIG_MULTI_DEF\n\tbool \"menuconfig multi def 2\"\n\nconfig MENU_HOOK\n\tbool\n\nmenu \"menuconfig 2\"\nendmenu\n\nconfig CHOICE_HOOK\n\tbool\n\nchoice\n\tbool \"menuconfig 3\"\nendchoice\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kmisc",
    "content": "# For testing various minor APIs\n\n# optional choices\n\nchoice NOT_OPTIONAL\n    bool \"not optional\"\nconfig A\n    bool \"A\"\nconfig B\n    bool \"B\"\nendchoice\n\nchoice OPTIONAL\n    tristate \"optional\"\n    optional\nconfig C\n    tristate \"C\"\nconfig D\n    tristate \"D\"\n# Quirky symbols - not proper choice symbol\n\nconfig Q1\n    tristate \"Q1\"\n    depends on D\n\nconfig Q2\n    tristate \"Q2\"\n    depends on Q1\n\nconfig Q3\n    tristate \"Q3\"\n    depends on D\n\nendchoice\n\n# User values\n\nconfig BOOL\n    bool \"bool\" if NOT_DEFINED_1\n\nconfig TRISTATE\n    tristate # Visibility should not affect user value\n\nconfig STRING\n    string \"string\"\n\nconfig INT\n    int # Visibility should not affect user value\n\nconfig HEX\n    hex \"hex\"\n    depends on NOT_DEFINED_2\n\nconfig COMMENT_HOOK\ncomment \"comment\"\n\nconfig MENU_HOOK\nmenu \"menu\"\n    depends on NOT_DEFINED_3 || NOT_DEFINED_2\n    depends on !NOT_DEFINED_4\nendmenu\n\nconfig FROM_ENV\n    string \"from env\"\n    option env=\"ENV_VAR\"\n\nconfig FROM_ENV_MISSING\n    string \"from env missing\"\n    option env=\"MISSING_ENV_VAR\"\n    default \"missing\"\n\nconfig FROM_ENV_WEIRD\n    string\n    default \"weird\"\n    option env=\"ENV_VAR\"\n\nconfig NOT_ALLNOCONFIG_Y\n    bool \"not allnoconfig_y\"\n\nconfig ALLNOCONFIG_Y\n    bool \"allnoconfig_y\"\n    option allnoconfig_y\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kmissingrsource",
    "content": "rsource \"nonexistent\"\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kmissingsource",
    "content": "source \"nonexistent\"\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Korder",
    "content": "config O\n\tint \"O\"\n\tdefault 0\n\nconfig R\n\tint \"R\"\n\tdefault 1\n\nconfig D\n\tint \"D\"\n\tdefault 2\n\nconfig E\n\tint \"E\"\n\tdefault 3\n\n# Defined twice\nconfig R\n\tint \"R\"\n\nconfig R2\n\tint \"R2\"\n\tdefault 4\n\nconfig I\n\tint \"I\"\n\tdefault 5\n\nconfig N\n\tint \"N\"\n\tdefault 6\n\nconfig G\n\tint \"G\"\n\tdefault 7\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kpreprocess",
    "content": "# Simple assignments (with bad formatting, as an additional test)\n\nsimple-recursive=foo\nsimple-immediate:=bar\n# Should become recursive\nsimple-recursive-2+=baz\n\n\t whitespaced\t =\t foo\n\n\n# Simple += test. += should preserve the flavor of the variable (simple vs.\n# recursive).\n\npreserve-recursive = foo\npreserve-recursive += bar\n\npreserve-immediate := foo\npreserve-immediate += bar\n\n\n# Recursive substitution\n\nrecursive = $(foo) $(bar) $($(b-char)a$(z-char))\nrecursive += $(indir)\n\nfoo = abc\nbar = def\nbaz = ghi\n\nb-char = b\nz-char = z\n\nindir = jkl $(indir-2)\nindir-2 = mno\n\n\n# Immediate substitution\n\ndef = foo\nimmediate := $(undef)$(def)$(undef)$(def)\ndef = bar\nundef = bar\n\n\n# Function calls\n\n# Chained function call\nquote = \"$(1)\" \"$(2)\"\nrev-quote = $(quote,$(2),$(1))\nsurround-rev-quote = $(0) $(rev-quote,$(1),$(2)) $(0)\nsurround-rev-quote-unused-arg = $(surround-rev-quote,$(1),$(2)) $(3)\n# No value is passed for $(3), so it expands to nothing\nfn-indir = surround-rev-quote\nmessy-fn-res = $($(fn-indir)-unused-arg, a  b (,) , c  d )\n\n# Special characters in function call\ncomma = ,\nright-paren = )\ndollar = $\nleft-paren = (\nfn = \"$(1)\"\nspecial-chars-fn-res = $(fn,$(comma)$(dollar)$(left-paren)foo$(right-paren))\n\n\n# Variable expansions in various locations (verified by checking how the symbol\n# prints)\n\nqaz = QAZ\necho = $(1)\nignore-first = $(2)\n\nconfig PRINT_ME\n\tstring \"$(ENV_1)\" if ($(echo,FOO) && $(echo,BAR)) || !$(echo,BAZ) || !(($(qaz)))\n\tdefault \"$(echo,\"foo\")\" if \"foo $(echo,\"bar\") baz\" = \"$(undefined)\"\n\n# Expansion within a symbol token, with deliberate sloppiness\nconfig PRINT_$(ignore-first,  ,ME)_TOO\n\tbool \"foo\"\n\tdefault FOO$(ignore-first,    ,BAR)BAZ$(qaz) if $(qaz)&&$(qaz)FOO&&x$(ignore-first,  ,xx)\n\n\n# Recursive expansion (throws an exception)\n\nrec-1 = x $(rec-2) y\nrec-2 = x $(rec-3) y\nrec-3 = x $(rec-1) y\n\n# Functions are allowed to reference themselves, but an exception is thrown if\n# the function seems to be stuck (the recursion gets too deep)\nsafe-fn-rec = $($(1))\nsafe-fn-rec-2 = $(safe-fn-rec,safe-fn-rec-3)\nsafe-fn-rec-3 = foo\nsafe-fn-rec-res = $(safe-fn-rec,safe-fn-rec-2)\n\nunsafe-fn-rec = $(unsafe-fn-rec,$(1))\n\n\n# Expansion in the left-hand side of assignments\n\ndummy-arg-fn = bar\nlhs-indir-1 = lhs-indir-2\nlhs-indir-2 = -baz\nrhs = value\n# LHS expands to foo-bar-baz\nfoo-$(dummy-arg-fn, ignored argument )$($(lhs-indir-1)) = $(rhs)\n# Expands to empty string, accepted\n  $(undefined)\n\n# Variable with a space in its name\nempty =\nspace = $(empty) $(empty)\nfoo$(space)bar = value\nspace-var-res = $(foo bar)\n\n\n# Built-in functions\n\n# Expands to \"baz qaz\"\nshell-res = $(shell,false && echo foo bar || echo baz qaz)\n\n# Warns about output on stderr, expands to nothing\nshell-stderr-res := $(shell,echo message on stderr >&2)\n\n# Nested parens in macro call. Should give a single argument. Test it with\n# $(shell) to get a free argument number check.\nparens-res = pre-$(shell,echo '(a,$(b-char),(c,d),e)')-post\n\n# Expands to the current location\nlocation-res := $(filename):$(lineno)\n\n# Adds one warning, expands to nothing\n$(warning-if,,no warning)\n$(warning-if,n,no warning)\nwarning-res := $(warning-if,y,a warning)\n\n# Does not cause an error, expands to nothing\nerror-n-res := $(error-if,n,oops)\n\n# Causes an error when expanded\nerror-y-res = $(error-if,y,oops)\n\n\n# Environment variables (for testing Kconfig.env_vars). ENV_1 is already\n# referenced above.\nenv_ref_1 := xxx $(ENV_2) xxx\nenv_ref_2 := $(shell,echo $(ENV_3))\nenv_ref_3 :=\nenv_ref_3 += $(ENV_4)\n$(warning-if,$(ENV_5),$(ENV_UNDEFINED))\nsource \"$(ENV_6)\"\nenv_ref_4 = $(ENV_7)  # Never evaluated\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Krange",
    "content": "#\n# No ranges\n#\n\nconfig HEX_NO_RANGE\n    hex \"hex no range\"\n\nconfig INT_NO_RANGE\n    int \"int no range\"\n\n#\n# Disabled ranges\n#\n\nconfig HEX_ALL_RANGES_DISABLED\n    hex \"hex all ranges disabled\"\n    range 0x10 0x20 if n\n    range 0x30 0x40 if n\n\nconfig INT_ALL_RANGES_DISABLED\n    int \"int all ranges disabled\"\n    range 10 20 if n\n    range 30 40 if n\n\n#\n# Ranges with defaults\n#\n\n# hex\n\nconfig HEX_RANGE_10_20_LOW_DEFAULT\n    hex \"int range 10-20 low default\"\n    range 0x10 0x20\n    default 0x9\n\nconfig HEX_RANGE_10_20_HIGH_DEFAULT\n    hex \"int range 10-20 high default\"\n    range 0x10 0x20\n    default 0x21\n\nconfig HEX_RANGE_10_20_OK_DEFAULT\n    hex \"int range 10-20 ok default\"\n    range 0x10 0x20\n    default 0x15\n\nconfig HEX_RANGE_10_20_OK_DEFAULT_ALTERNATE\n    hex \"int range 10-20 ok default alternate\"\n    range 0x10 0x20\n    default 15\n\n# int\n\nconfig INT_RANGE_10_20_LOW_DEFAULT\n    int \"int range 10-20 low default\"\n    range 10 20\n    default 9\n\nconfig INT_RANGE_10_20_HIGH_DEFAULT\n    int \"int range 10-20 high default\"\n    range 10 20\n    default 21\n\nconfig INT_RANGE_10_20_OK_DEFAULT\n    int \"int range 10-20 ok default\"\n    range 10 20\n    default 15\n\n#\n# Ranges with no defaults (should default to low end of range if > 0)\n#\n\nconfig HEX_RANGE_10_20\n    hex \"hex range 10-20\"\n    range 0x10 0x20\n\nconfig HEX_RANGE_0_10\n    hex \"hex range 0-10\"\n    range 0x0 0x10\n\nconfig INT_RANGE_10_20\n    int \"int range 10-20\"\n    range 10 20\n\nconfig INT_RANGE_0_10\n    int \"int range 0-10\"\n    range 0 10\n\nconfig INT_RANGE_NEG_10_10\n    int \"int range -10-10\"\n    range -10 10\n\n#\n# Dependent ranges\n#\n\nconfig HEX_40\n    hex\n    default 40\n\nconfig HEX_RANGE_10_40_DEPENDENT\n    hex \"hex range 10-40 dependent\"\n    range HEX_RANGE_10_20 HEX_40\n\nconfig INT_40\n    int\n    default 40\n\nconfig INT_RANGE_10_40_DEPENDENT\n    int \"int range 10-40 dependent\"\n    range INT_RANGE_10_20 INT_40\n\n#\n# Ranges on symbols defined in multiple locations\n#\n\nif n\nconfig INACTIVE_RANGE\n    range 0 1\nendif\n\nconfig INACTIVE_RANGE\n    int\n    # Default will apply and should not get clamped,\n    # because the range does not apply\n    default 2\n\nconfig ACTIVE_RANGE\n    range 0 1\n\nconfig ACTIVE_RANGE\n    int\n    # Default will apply and should be clamped to 1\n    default 2\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Krecursive1",
    "content": "source \"tests/Krecursive2\"\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Krecursive2",
    "content": "source \"tests/Krecursive1\"\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kreferenced",
    "content": "config NO_REFS\n    bool\n\nconfig JUST_DEPENDS_ON_REFS\n    bool\n    depends on A && B\n\nif A\n\nmenu \"menu\"\n    depends on B\n    visible if C\n    visible if D\n\nconfig LOTS_OF_REFS\n    bool \"lots\" if C || D\n    default E || F if G || H\n    default I || J if K || L\n    select M if N || O\n    select P if Q || R\n    imply S if T || U\n    imply V if W || X\n    depends on Y || Z\n\nendmenu\n\nendif\n\nconfig INT_REFS\n    int \"int\"\n    range A B if C && D\n    range E F if G && H\n\nchoice CHOICE\n    bool \"choice\"\n\nconfig CHOICE_REF\n    bool \"choice ref\"\n\nendchoice\n\ncomment \"comment\"\n    depends on A || B\n\n\nconfig MULTI_DEF_SYM\n    def_bool A && B\n\nconfig MULTI_DEF_SYM\n    depends on C\n\n\nchoice MULTI_DEF_CHOICE\n    bool \"choice\"\n    depends on A && B\n\nendchoice\n\nchoice MULTI_DEF_CHOICE\n    bool \"choice\"\n    depends on C\n\nendchoice\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Krelation",
    "content": "config A\n    bool\n    depends on UNDEFINED\n\nchoice CHOICE_1\n    bool \"C\"\nconfig B\n    bool \"B\"\nconfig C\n    bool \"C\" if B\nconfig D\n    bool \"D\"\nendchoice\n\nmenu \"m1\"\nconfig E\n    bool\nmenu \"m2\"\nconfig F\n    bool\nchoice CHOICE_2\n    tristate \"foo\"\nconfig G\n    bool \"g\"\nconfig H\n    bool \"h\"\nendchoice\nendmenu\nconfig I\n    bool\nendmenu\n\nmenu \"m3\"\nendmenu\nmenu \"m4\"\nendmenu\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Krepr",
    "content": "config MODULES\n    bool\n    option modules\n    default y\n\nif UNDEFINED\nendif\n\nconfig BASIC\n    bool\n    default y\n    ---help---\n\nconfig VISIBLE\n    bool \"visible\"\n\nconfig STRING\n    string \"visible\"\n\nconfig DIR_DEP_N\n    depends on n\n\nconfig OPTIONS\n    option allnoconfig_y\n    option defconfig_list\n    option env=\"ENV\"\n\nconfig MULTI_DEF\nconfig MULTI_DEF\n\nmenuconfig MENUCONFIG\n\nchoice CHOICE\n    tristate \"choice\"\n\nconfig CHOICE_1\n    tristate \"choice sym\"\n\nconfig CHOICE_2\n    tristate \"choice sym\"\n\nendchoice\n\nconfig CHOICE_HOOK\n\nchoice\n    tristate \"optional choice\" if n\n    optional\nendchoice\n\nconfig NO_VISIBLE_IF_HOOK\n\nmenu \"no visible if\"\nendmenu\n\nconfig VISIBLE_IF_HOOK\n\nmenu \"visible if\"\n    visible if m\nendmenu\n\nconfig COMMENT_HOOK\n\ncomment \"comment\"\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kstr",
    "content": "if UNDEFINED\nendif\n\nconfig NO_TYPE\n\nconfig BASIC_NO_PROMPT\n    bool\n    help\n      blah blah\n\n        blah blah blah\n\n       blah\n\nconfig BASIC_PROMPT\n    bool \"basic\"\n\nconfig ADVANCED\n    tristate \"prompt\" if DEP\n    default DEFAULT_1\n    default DEFAULT_2 if DEP\n    select SELECTED_1\n    select SELECTED_2 if DEP\n    imply IMPLIED_1\n    imply IMPLIED_2 if DEP\n    help\n      first help text\n\nconfig ADVANCED\n    prompt \"prompt 2\"\n\nmenuconfig ADVANCED\n    prompt \"prompt 3\"\n\nif DEP3\n\nmenu \"foo\"\n    depends on DEP4\n    visible if VIS\n\nconfig ADVANCED\n    help\n      second help text\n    depends on A || !B || (C && D) || !(E && F) || G = H || \\\n              (I && !J && (K || L) && !(M || N) && O = P)\n\nconfig ADVANCED\n    # Used to verify that the direct dependencies appear to the right of VIS\n    prompt \"prompt 4\"\n\nendmenu\n\nendif\n\nconfig ONLY_DIRECT_DEPS\n    int\n    depends on DEP1\n    depends on DEP2\n\nconfig STRING\n    def_string \"foo\"\n    default \"bar\" if DEP\n    default STRING2\n    default STRING3 if DEP\n\nconfig INT\n    def_int 7 if DEP\n    range 1 2\n    range FOO BAR\n    range BAZ QAZ if DEP\n\nconfig HEX\n    def_hex 0x123\n    range 0x100 0x200\n    range FOO BAR\n    range BAZ QAZ if DEP\n\nconfig MODULES\n    bool \"MODULES\"\n    option modules\n\nconfig OPTIONS\n    option allnoconfig_y\n    option defconfig_list\n    option env=\"ENV\"\n\nif LOC_1\nconfig CORRECT_PROP_LOCS_BOOL\n    prompt \"prompt 1\"\n    default DEFAULT_1\n    default DEFAULT_2\n    select SELECT_1\n    select SELECT_2\n    imply IMPLY_1\n    imply IMPLY_2\n    help\n      help 1\nendif\n\nif LOC_2\nmenuconfig CORRECT_PROP_LOCS_BOOL\n    bool \"prompt 2\"\n    default DEFAULT_3\n    default DEFAULT_4\n    select SELECT_3\n    select SELECT_4\n    imply IMPLY_3\n    imply IMPLY_4\n    help\n      help 2\nendif\n\nif LOC_3\nconfig CORRECT_PROP_LOCS_BOOL\n    prompt \"prompt 3\"\n    default DEFAULT_5\n    default DEFAULT_6\n    select SELECT_5\n    select SELECT_6\n    imply IMPLY_5\n    imply IMPLY_6\n    help\n      help 2\nendif\n\nif LOC_1\nconfig CORRECT_PROP_LOCS_INT\n    int\n    range 1 2\n    range 3 4\nendif\n\nif LOC_2\nconfig CORRECT_PROP_LOCS_INT\n    range 5 6\n    range 7 8\nendif\n\nchoice CHOICE\n    tristate \"foo\"\n    default CHOICE_1\n    default CHOICE_2 if dep\n\nconfig CHOICE_1\n    tristate \"choice 1\"\n\nconfig CHOICE_2\n    tristate \"choice 2\"\n\nendchoice\n\nchoice\n    tristate \"no name\"\n    optional\nendchoice\n\nif LOC_1\nchoice CORRECT_PROP_LOCS_CHOICE\n    bool\n    default CHOICE_3\n\nconfig CHOICE_3\n    bool \"choice 3\"\n\nconfig CHOICE_4\n    bool \"choice 3\"\n\nconfig CHOICE_5\n    bool \"choice 3\"\n\nendchoice\nendif\n\nif LOC_2\nchoice CORRECT_PROP_LOCS_CHOICE\n    default CHOICE_4\nendchoice\nendif\n\nif LOC_3\nchoice CORRECT_PROP_LOCS_CHOICE\n    default CHOICE_5\nendchoice\nendif\n\nconfig SIMPLE_MENU_HOOK\nmenu \"simple menu\"\nendmenu\n\nconfig ADVANCED_MENU_HOOK\nmenu \"advanced menu\"\n    depends on A\n    visible if B\n    visible if C || D\nendmenu\n\nconfig SIMPLE_COMMENT_HOOK\ncomment \"simple comment\"\n\nconfig ADVANCED_COMMENT_HOOK\ncomment \"advanced comment\"\n    depends on A\n    depends on B\n\n# Corner cases when removing direct dependencies\n\nconfig DEP_REM_CORNER_CASES\n    bool\n    default A\n    depends on n\n\nconfig DEP_REM_CORNER_CASES\n    default B if n\n\nconfig DEP_REM_CORNER_CASES\n    default C\n    depends on m\n\nconfig DEP_REM_CORNER_CASES\n    default D if A && y\n    depends on y\n\nconfig DEP_REM_CORNER_CASES\n    default E if !E1\n    default F if F1 = F2\n    default G if G1 || H1\n    depends on !H\n\nconfig DEP_REM_CORNER_CASES\n    default H\n    depends on \"foo\" = \"bar\"\n\nmenu \"menu\"\n    visible if FOO || BAR\n\nconfig DEP_REM_CORNER_CASES\n    prompt \"prompt\"\n    depends on BAZ && QAZ\n\nendmenu\n\n# Only prompt, no type\nconfig PROMPT_ONLY\n    prompt \"prompt only\"\n\n# {Symbol,Choice}.orig_*\n\nif BASE_DEP\n\nconfig BOOL_SYM_ORIG\n    bool\n    default D1 if DEP\n    default D2\n    select S1\n    select S2 if DEP\n    imply I1\n    imply I1\n\nconfig BOOL_SYM_ORIG\n    default D3\n    select S3\n    imply I3 if DEP\n\nconfig INT_SYM_ORIG\n    int\n    range 1 2 if DEP\n    range 3 4\n\nconfig INT_SYM_ORIG\n    range 5 6 if DEP\n\nchoice CHOICE_ORIG\n    bool \"choice orig\"\n    default A\n    default B if DEP\n\nconfig A\n    bool\n\nconfig B\n    bool\n\nendchoice\n\nchoice CHOICE_ORIG\n    default C if DEP\n\nconfig C\n    bool\n\nendchoice\n\nendif\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kundef",
    "content": "config DEF\n\tbool\n\nconfig BOOL\n\tbool \"foo\" if DEF || !UNDEF_1\n\tdefault UNDEF_2\n\nconfig INT\n\tint\n\trange UNDEF_2 8\n\tdefault 10\n\trange 5 15\n\nconfig HEX\n\thex\n\trange 0x123 0X456\n\tdefault 0x200\n\nmenu \"menu\"\n\tdepends on UNDEF_1\n\tvisible if UNDEF_3\n\nendmenu\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kuserfunctions",
    "content": "add-zero  = $(add)\nadd-one   = $(add,1)\nadd-three = $(add,1,-1,2,1)\n\none-zero = $(one)\none-one  = $(one,foo bar)\none-two  = $(one,foo bar,baz)\n\none-or-more-zero  = $(one-or-more)\none-or-more-one   = $(one-or-more,foo)\none-or-more-three = $(one-or-more,foo,bar,baz)\n\nlocation-1 := $(location)\nlocation-2 := $(location)\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/Kvisibility",
    "content": "config MODULES\n    bool \"MODULES\"\n    option modules\n\n#\n# Symbol visibility\n#\n\nconfig NO_PROMPT\n    bool\n\n# Not rewritten, so MOD will have the value 'y' when running without modules\nconfig MOD\n    def_tristate m\n\nconfig BOOL_N\n    bool \"bool n\" if n\n\nconfig BOOL_M\n    # Rewritten to m && MODULES\n    bool \"bool m\" if m\n\nconfig BOOL_MOD\n    bool \"bool MOD\"\n    # Not rewritten\n    depends on MOD\n\nconfig BOOL_Y\n    bool \"bool y\"\n    # Rewritten to m && MODULES\n    depends on y || m\n\nconfig TRISTATE_N\n    tristate \"tristate n\" if n\n\nconfig TRISTATE_M\n    # Rewritten to m && MODULES\n    tristate \"tristate m\" if m\n\nconfig TRISTATE_MOD\n    tristate \"tristate MOD\"\n    # Not rewritten\n    depends on MOD\n\nconfig TRISTATE_Y\n    bool \"tristate y\"\n    # Rewritten to m && MODULES\n    depends on y || m\n\n# Symbols nested in 'if'\n\nif n\n\nconfig BOOL_IF_N\n    bool \"bool if n\"\n\nconfig TRISTATE_IF_N\n    tristate \"tristate if n\"\n\nendif\n\nif m\n\nconfig BOOL_IF_M\n    bool \"bool if m\"\n\nconfig TRISTATE_IF_M\n    tristate \"tristate if n\"\n\nendif\n\nif y\n\nconfig BOOL_IF_Y\n    bool \"bool if y\"\n\nconfig TRISTATE_IF_Y\n    tristate \"tristate if y\"\n\nendif\n\n# Symbols nested in 'menu'\n\nmenu \"menu 1\"\n    depends on n\n\nconfig BOOL_MENU_N\n    bool \"bool menu n\"\n\nconfig TRISTATE_MENU_N\n    tristate \"tristate menu n\"\n\nendmenu\n\nmenu \"menu 2\"\n    depends on m\n\nconfig BOOL_MENU_M\n    bool \"bool menu m\"\n\nconfig TRISTATE_MENU_M\n    tristate \"tristate menu n\"\n\nendmenu\n\nmenu \"menu 3\"\n    depends on y\n\nconfig BOOL_MENU_Y\n    bool \"bool menu y\"\n\nconfig TRISTATE_MENU_Y\n    tristate \"tristate menu y\"\n\nendmenu\n\n# Symbols nested in choices\n\nchoice C1\n    tristate \"choice n\" if n\n\nconfig BOOL_CHOICE_N\n    bool \"bool choice n\"\n\nconfig TRISTATE_CHOICE_N\n    tristate \"tristate choice n\"\n\nendchoice\n\nchoice C2\n    tristate \"choice m\" if m\n\nconfig BOOL_CHOICE_M\n    bool \"bool choice m\"\n\nconfig TRISTATE_CHOICE_M\n    tristate \"tristate choice n\"\n\nendchoice\n\nchoice C3\n    tristate \"choice y\" if y\n\nconfig BOOL_CHOICE_Y\n    bool \"bool choice y\"\n\nconfig TRISTATE_CHOICE_Y\n    tristate \"tristate choice y\"\n\nendchoice\n\n#\n# Choice visibility\n#\n\nchoice BOOL_CHOICE_N\n    bool \"bool choice n\" if n\nendchoice\n\nchoice BOOL_CHOICE_M\n    bool \"bool choice m\" if m\nendchoice\n\nchoice BOOL_CHOICE_Y\n    bool \"bool choice y\" if y\nendchoice\n\nchoice TRISTATE_CHOICE_N\n    tristate \"tristate choice n\" if n\nendchoice\n\nchoice TRISTATE_CHOICE_M\n    tristate \"tristate choice m\" if m\nendchoice\n\nchoice TRISTATE_CHOICE_Y\n    tristate \"tristate choice y\" if y\n\nconfig K\n    tristate \"K\"\n\nconfig L\n    tristate \"L\"\n\nendchoice\n\nif m\nchoice TRISTATE_CHOICE_IF_M_AND_Y\n    tristate \"tristate choice if m and y\" if y\n\nconfig M\n    bool \"M\"\n\nconfig N\n    bool \"N\"\n\nendchoice\nendif\n\nmenu \"choice-containing menu\"\n    depends on n && y\n\nchoice TRISTATE_CHOICE_MENU_N_AND_Y\n    tristate \"tristate choice if n and y\"\n\nconfig O\n    tristate \"O\"\n\nconfig P\n    tristate \"P\"\n\nendchoice\n\nendmenu\n\n#\n# Menu visibility\n#\n\nmenu \"menu n\"\n    depends on n\nendmenu\n\nmenu \"menu m\"\n    depends on m\nendmenu\n\nmenu \"menu y\"\n    depends on y\nendmenu\n\nif n\nmenu \"menu if n\"\nendmenu\nendif\n\nif m\nmenu \"menu if m\"\nendmenu\nendif\n\nif y\nmenu \"menu if y\"\nendmenu\nendif\n\nif m\nmenu \"menu if m and y\"\n    depends on y\nendmenu\nendif\n\n#\n# Comment visibility\n#\n\ncomment \"comment n\"\n    depends on n\ncomment \"comment m\"\n    depends on m\ncomment \"comment y\"\n    depends on y\n\nif n\ncomment \"comment if n\"\nendif\n\nif m\ncomment \"comment if m\"\nendif\n\nif y\ncomment \"comment if y\"\nendif\n\nif \"y\"\n\nmenu \"menu with comment\"\n    depends on m\n\ncomment \"double-nested m comment\"\n    depends on y\n\nendmenu\n\nendif\n\n# Used to verify that string/int/hex symbols with m visibility accept a user\n# value\n\nif m\n\nconfig STRING_m\n    string \"string\"\n\nconfig INT_m\n    int \"int\"\n\nconfig HEX_m\n    hex \"hex\"\n\nendif\n\n# Menu 'visible if' visibility\n\nmenu \"n-visible menu\"\n    visible if n\n\nconfig VISIBLE_IF_N\n    tristate \"visible if n\"\n\nendmenu\n\nmenu \"m-visible menu\"\n    visible if m\n\nconfig VISIBLE_IF_M\n    tristate \"visible if m\"\n\nendmenu\n\nmenu \"y-visible menu\"\n    visible if y\n\nconfig VISIBLE_IF_Y\n    tristate \"visible if m\"\n\nendmenu\n\nmenu \"m-visible menu 2\"\n    visible if y || n\n    visible if m && y\n    visible if y\n\nif y\n\nconfig VISIBLE_IF_M_2\n    tristate \"visible if m 2\"\n\nendif\n\nendmenu\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/config_indented",
    "content": "# Indented assignments should be ignored to be compatible with the C\n# implementation\n CONFIG_IGNOREME=n\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/config_set_bool",
    "content": "CONFIG_BOOL=y\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/config_set_string",
    "content": "CONFIG_STRING=\"foo bar\"\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/defconfig_1",
    "content": ""
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/defconfig_2",
    "content": ""
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/empty",
    "content": ""
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/kconfigfunctions.py",
    "content": "def add(kconf, name, *args):\n    return str(sum(map(int, args)))\n\n\ndef one(kconf, name, s):\n    return name + 2*s\n\n\ndef one_or_more(kconf, name, arg, *args):\n    return arg + \" + \" + \",\".join(args)\n\n\ndef location(kconf, name):\n    return \"{}:{}\".format(kconf.filename, kconf.linenr)\n\n\nfunctions = {\n    \"add\":         (add,         0, None),\n    \"one\":         (one,         1,    1),\n    \"one-or-more\": (one_or_more, 1, None),\n    \"location\":    (location,    0,    0),\n}\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/reltest",
    "content": "#!/usr/bin/env bash\n\n# Runs the test suite and all examples scripts with Python 2 and Python 3,\n# bailing immediately if anything fails. For the examples that aren't tested in\n# the test suite, we just confirm that they at least run.\n#\n# Should be run from the kernel root with  $ Kconfiglib/tests/reltest\n\ntest_script() {\n    echo -e \"\\n================= $1 with $py =================\\n\"\n    if (($# == 1)); then\n        make scriptconfig PYTHONCMD=$py SCRIPT=$1\n    else\n        make scriptconfig PYTHONCMD=$py SCRIPT=$1 SCRIPT_ARG=\"$2\"\n    fi\n\n    if (($?)); then\n        echo \"$1 failed to run with $py\"\n        exit 1\n    fi\n}\n\nfor py in python2 python3; do\n    echo -e \"\\n================= Test suite with $py =================\\n\"\n\n    if ! $py Kconfiglib/testsuite.py; then\n        echo \"test suite failed for $py\"\n        exit 1\n    fi\n\n    # Check that the example scripts that aren't tested by the test suite run\n    # at least\n\n    test_script Kconfiglib/examples/defconfig_oldconfig.py\n    test_script Kconfiglib/examples/eval_expr.py MODULES\n    test_script Kconfiglib/examples/find_symbol.py X86\n    test_script Kconfiglib/examples/help_grep.py general\n    test_script Kconfiglib/examples/print_sym_info.py MODULES\n    test_script Kconfiglib/examples/print_tree.py\n\n    $py Kconfiglib/examples/menuconfig_example.py Kconfiglib/examples/Kmenuconfig <<END\nBOOL\nn\nEND\n    if (($?)); then\n        echo \"menuconfig_example.py failed with $py\"\n        exit 1\n    fi\ndone\n\necho \"everything okay\"\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/sub/Kconfig_symlink_2",
    "content": "rsource \"Kconfig_symlink_3\"\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/sub/Kconfig_symlink_3",
    "content": "config FOUNDME\n    bool\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/sub/Klocation_grsourced1",
    "content": "config MANY_DEF\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/sub/Klocation_grsourced2",
    "content": "config MANY_DEF\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/sub/Klocation_gsourced1",
    "content": "config MANY_DEF\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/sub/Klocation_gsourced2",
    "content": "config MANY_DEF\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/sub/Klocation_rsourced",
    "content": "\nconfig MANY_DEF\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/sub/defconfig_in_sub",
    "content": ""
  },
  {
    "path": "kernel/scripts/Kconfiglib/tests/sub/sub/Kconfig_symlink_1",
    "content": "# Sources tests/sub/Kconfig_symlink_2, with an absolute path\nsource \"$(KCONFIG_SYMLINK_2)\"\n"
  },
  {
    "path": "kernel/scripts/Kconfiglib/testsuite.py",
    "content": "# Copyright (c) 2011-2019, Ulf Magnusson\n# SPDX-License-Identifier: ISC\n\n# This is the Kconfiglib test suite. It runs selftests on Kconfigs provided by\n# us and tests compatibility with the C Kconfig implementation by comparing the\n# output of Kconfiglib with the output of the scripts/kconfig/*conf utilities\n# for different targets and defconfigs. It should be run from the top-level\n# kernel directory with\n#\n#   $ python Kconfiglib/testsuite.py\n#\n# Some additional options can be turned on by passing them as arguments. They\n# default to off.\n#\n#  - obsessive:\n#    By default, only valid arch/defconfig pairs are tested. In obsessive mode,\n#    every arch will be tested with every defconfig. Increases the testing time\n#    by an order of magnitude. Occasionally finds (usually obscure) bugs, and I\n#    make sure everything passes with it.\n#\n#  - obsessive-min-config:\n#    Like obsessive, for the minimal configuation (defconfig) tests.\n#\n#  - log:\n#    Log timestamped defconfig test failures to the file test_defconfig_fails.\n#    Handy in obsessive mode.\n#\n# For example, this commands runs the test suite in obsessive mode with logging\n# enabled:\n#\n#   $ python(3) Kconfiglib/testsuite.py obsessive log\n#\n# pypy works too, and runs most tests much faster than CPython.\n#\n# All tests should pass. Report regressions to ulfalizer a.t Google's email\n# service.\n\nimport difflib\nimport errno\nimport os\nimport re\nimport shutil\nimport subprocess\nimport sys\nimport tempfile\nimport textwrap\n\nfrom kconfiglib import Kconfig, Symbol, Choice, COMMENT, MENU, MenuNode, \\\n                       BOOL, TRISTATE, HEX, \\\n                       TRI_TO_STR, \\\n                       escape, unescape, \\\n                       expr_str, expr_items, split_expr, \\\n                       _ordered_unique, \\\n                       OR, AND, \\\n                       KconfigError\n\n\ndef shell(cmd):\n    with open(os.devnull, \"w\") as devnull:\n        subprocess.call(cmd, shell=True, stdout=devnull, stderr=devnull)\n\n\nall_passed = True\n\n\ndef fail(msg=None):\n    global all_passed\n    all_passed = False\n    if msg is not None:\n        print(\"fail: \" + msg)\n\n\ndef verify(cond, msg):\n    if not cond:\n        fail(msg)\n\n\ndef verify_equal(x, y):\n    if x != y:\n        fail(\"'{}' does not equal '{}'\".format(x, y))\n\n\n# Prevent accidental loading of configuration files by removing\n# KCONFIG_ALLCONFIG from the environment\nos.environ.pop(\"KCONFIG_ALLCONFIG\", None)\n\nobsessive = False\nobsessive_min_config = False\nlog = False\n\n\ndef run_tests():\n    global obsessive, log\n    for s in sys.argv[1:]:\n        if s == \"obsessive\":\n            obsessive = True\n            print(\"Obsessive mode enabled\")\n        elif s == \"obsessive-min-config\":\n            obsessive_min_config = True\n            print(\"Obsessive minimal config mode enabled\")\n        elif s == \"log\":\n            log = True\n            print(\"Log mode enabled\")\n        else:\n            print(\"Unrecognized option '{}'\".format(s))\n            return\n\n    run_selftests()\n    run_compatibility_tests()\n\n\ndef run_selftests():\n    #\n    # Common helper functions. These all expect 'c' to hold the current\n    # configuration.\n    #\n\n    def verify_value(sym_name, val):\n        # Verifies that a symbol has a particular value.\n\n        if isinstance(val, int):\n            val = TRI_TO_STR[val]\n\n        sym = c.syms[sym_name]\n        verify(sym.str_value == val,\n               'expected {} to have the value \"{}\", had the value \"{}\"'\n               .format(sym_name, val, sym.str_value))\n\n    def assign_and_verify_value(sym_name, val, new_val):\n        # Assigns 'val' to a symbol and verifies that its value becomes\n        # 'new_val'. Assumes (and tests) that 'val' is valid for the\n        # symbol type.\n\n        if isinstance(new_val, int):\n            new_val = TRI_TO_STR[new_val]\n\n        sym = c.syms[sym_name]\n        old_val = sym.str_value\n        verify(sym.set_value(val),\n               \"assigning '{}' to {} unexpectedly failed\"\n               .format(val, sym_name))\n        verify(sym.str_value == new_val,\n               \"expected {} to have the value '{}' after being assigned the \"\n               \"value '{}'. Instead, the value is '{}'. The old value was \"\n               \"'{}'.\"\n               .format(sym_name, new_val, val, sym.str_value, old_val))\n\n    def assign_and_verify(sym_name, user_val):\n        # Like assign_and_verify_value(), with the expected value being the\n        # value just set.\n\n        assign_and_verify_value(sym_name, user_val, user_val)\n\n    def assign_and_verify_user_value(sym_name, val, user_val, valid):\n        # Assigns a user value to the symbol and verifies the new user value.\n        # If valid is True, the user value is valid for the type, otherwise\n        # not. This is used to test the set_value() return value.\n\n        sym = c.syms[sym_name]\n        sym_old_user_val = sym.user_value\n\n        verify(sym.set_value(val) == valid,\n               \"expected the user value '{}' to be {} for {}, was not\"\n               .format(val, \"valid\" if valid else \"invalid\", sym_name))\n        verify(sym.user_value == user_val,\n               \"the assigned user value '{}' wasn't reflected in user_value \"\n               \"on the symbol {}. Instead, the new user_value was '{}'. The \"\n               \"old user value was '{}'.\"\n               .format(user_val, sym_name, sym.user_value, sym_old_user_val))\n\n    #\n    # Selftests\n    #\n\n    print(\"Testing string literal lexing\")\n\n    # Dummy empty configuration just to get a Kconfig object\n    c = Kconfig(\"Kconfiglib/tests/empty\")\n\n    def verify_string_lex(s, expected):\n        # Verifies that a constant symbol with the name 'res' is produced from\n        # lexing 's'\n\n        res = c._tokenize(\"if \" + s)[1].name\n        verify(res == expected,\n               \"expected <{}> to produced the constant symbol <{}>, \"\n               'produced <{}>'.format(s[1:-1], expected, res))\n\n    verify_string_lex(r\"\"\" \"\" \"\"\", \"\")\n    verify_string_lex(r\"\"\" '' \"\"\", \"\")\n\n    verify_string_lex(r\"\"\" \"a\" \"\"\", \"a\")\n    verify_string_lex(r\"\"\" 'a' \"\"\", \"a\")\n    verify_string_lex(r\"\"\" \"ab\" \"\"\", \"ab\")\n    verify_string_lex(r\"\"\" 'ab' \"\"\", \"ab\")\n    verify_string_lex(r\"\"\" \"abc\" \"\"\", \"abc\")\n    verify_string_lex(r\"\"\" 'abc' \"\"\", \"abc\")\n\n    verify_string_lex(r\"\"\" \"'\" \"\"\", \"'\")\n    verify_string_lex(r\"\"\" '\"' \"\"\", '\"')\n\n    verify_string_lex(r\"\"\" \"\\\"\" \"\"\", '\"')\n    verify_string_lex(r\"\"\" '\\'' \"\"\", \"'\")\n\n    verify_string_lex(r\"\"\" \"\\\"\\\"\" \"\"\", '\"\"')\n    verify_string_lex(r\"\"\" '\\'\\'' \"\"\", \"''\")\n\n    verify_string_lex(r\"\"\" \"\\'\" \"\"\", \"'\")\n    verify_string_lex(r\"\"\" '\\\"' \"\"\", '\"')\n\n    verify_string_lex(r\"\"\" \"\\\\\" \"\"\", \"\\\\\")\n    verify_string_lex(r\"\"\" '\\\\' \"\"\", \"\\\\\")\n\n    verify_string_lex(r\"\"\" \"\\a\\\\'\\b\\c\\\"'d\" \"\"\", 'a\\\\\\'bc\"\\'d')\n    verify_string_lex(r\"\"\" '\\a\\\\\"\\b\\c\\'\"d' \"\"\", \"a\\\\\\\"bc'\\\"d\")\n\n    def verify_string_bad(s):\n        # Verifies that tokenizing 's' throws a KconfigError. Strips the first\n        # and last characters from 's' so we can use readable raw strings as\n        # input.\n\n        try:\n            c.eval_string(s)\n        except KconfigError:\n            pass\n        else:\n            fail(\"expected tokenization of {} to fail, didn't\".format(s[1:-1]))\n\n    verify_string_bad(r\"\"\" \" \"\"\")\n    verify_string_bad(r\"\"\" ' \"\"\")\n    verify_string_bad(r\"\"\" \"' \"\"\")\n    verify_string_bad(r\"\"\" '\" \"\"\")\n    verify_string_bad(r\"\"\" \"\\\" \"\"\")\n    verify_string_bad(r\"\"\" '\\' \"\"\")\n    verify_string_bad(r\"\"\" \"foo \"\"\")\n    verify_string_bad(r\"\"\" 'foo \"\"\")\n\n\n    print(\"Testing escape() and unescape()\")\n\n    def verify_escape_unescape(s, sesc):\n        # Verify that 's' escapes to 'sesc' and that 'sesc' unescapes to 's'\n        verify_equal(escape(s), sesc)\n        verify_equal(unescape(sesc), s)\n\n    verify_escape_unescape(r''          , r''              )\n    verify_escape_unescape(r'foo'       , r'foo'           )\n    verify_escape_unescape(r'\"'         , r'\\\"'            )\n    verify_escape_unescape(r'\"\"'        , r'\\\"\\\"'          )\n    verify_escape_unescape('\\\\'         , r'\\\\'            )\n    verify_escape_unescape(r'\\\\'        , r'\\\\\\\\'          )\n    verify_escape_unescape(r'\\\"'        , r'\\\\\\\"'          )\n    verify_escape_unescape(r'\"ab\\cd\"ef\"', r'\\\"ab\\\\cd\\\"ef\\\"')\n\n    # Backslashes before any character should be unescaped, not just before \"\n    # and \\\n    verify_equal(unescape(r\"\\afoo\\b\\c\\\\d\\\\\\e\\\\\\\\f\"), r\"afoobc\\d\\e\\\\f\")\n\n\n    print(\"Testing _ordered_unique()\")\n\n    verify_equal(_ordered_unique([]), [])\n    verify_equal(_ordered_unique([1]), [1])\n    verify_equal(_ordered_unique([1, 2]), [1, 2])\n    verify_equal(_ordered_unique([1, 1]), [1])\n    verify_equal(_ordered_unique([1, 1, 2]), [1, 2])\n    verify_equal(_ordered_unique([1, 2, 1]), [1, 2])\n    verify_equal(_ordered_unique([1, 2, 2]), [1, 2])\n    verify_equal(_ordered_unique([1, 2, 3, 2, 1, 2, 3, 4, 3, 2, 1, 0]),\n                                 [1, 2, 3, 4, 0])\n\n\n    print(\"Testing expression evaluation\")\n\n    c = Kconfig(\"Kconfiglib/tests/Keval\", warn=False)\n\n    def verify_eval(expr, val):\n        res = c.eval_string(expr)\n        verify(res == val,\n               \"'{}' evaluated to {}, expected {}\".format(expr, res, val))\n\n    # No modules\n    verify_eval(\"n\", 0)\n    verify_eval(\"m\", 0)\n    verify_eval(\"y\", 2)\n    verify_eval(\"'n'\", 0)\n    verify_eval(\"'m'\", 0)\n    verify_eval(\"'y'\", 2)\n    verify_eval(\"M\", 2)\n\n    # Modules\n    c.modules.set_value(2)\n    verify_eval(\"n\", 0)\n    verify_eval(\"m\", 1)\n    verify_eval(\"y\", 2)\n    verify_eval(\"'n'\", 0)\n    verify_eval(\"'m'\", 1)\n    verify_eval(\"'y'\", 2)\n    verify_eval(\"M\", 1)\n    verify_eval(\"(Y || N) && (m && y)\", 1)\n\n    # Non-bool/non-tristate symbols are always n in a tristate sense\n    verify_eval(\"Y_STRING\", 0)\n    verify_eval(\"Y_STRING || m\", 1)\n\n    # As are all constants besides y and m\n    verify_eval('\"foo\"', 0)\n    verify_eval('\"foo\" || \"bar\"', 0)\n    verify_eval('\"foo\" || m', 1)\n\n    # Test equality for symbols\n\n    verify_eval(\"N = N\", 2)\n    verify_eval(\"N = n\", 2)\n    verify_eval(\"N = 'n'\", 2)\n    verify_eval(\"N != N\", 0)\n    verify_eval(\"N != n\", 0)\n    verify_eval(\"N != 'n'\", 0)\n\n    verify_eval(\"M = M\", 2)\n    verify_eval(\"M = m\", 2)\n    verify_eval(\"M = 'm'\", 2)\n    verify_eval(\"M != M\", 0)\n    verify_eval(\"M != m\", 0)\n    verify_eval(\"M != 'm'\", 0)\n\n    verify_eval(\"Y = Y\", 2)\n    verify_eval(\"Y = y\", 2)\n    verify_eval(\"Y = 'y'\", 2)\n    verify_eval(\"Y != Y\", 0)\n    verify_eval(\"Y != y\", 0)\n    verify_eval(\"Y != 'y'\", 0)\n\n    verify_eval(\"N != M\", 2)\n    verify_eval(\"N != Y\", 2)\n    verify_eval(\"M != Y\", 2)\n\n    verify_eval(\"Y_STRING = y\", 2)\n    verify_eval(\"Y_STRING = 'y'\", 2)\n    verify_eval('FOO_BAR_STRING = \"foo bar\"', 2)\n    verify_eval('FOO_BAR_STRING != \"foo bar baz\"', 2)\n    verify_eval('INT_37 = 37', 2)\n    verify_eval(\"INT_37 = '37'\", 2)\n    verify_eval('HEX_0X37 = 0x37', 2)\n    verify_eval(\"HEX_0X37 = '0x37'\", 2)\n\n    # These should also hold after 31847b67 (kconfig: allow use of relations\n    # other than (in)equality)\n    verify_eval(\"HEX_0X37 = '0x037'\", 2)\n    verify_eval(\"HEX_0X37 = '0x0037'\", 2)\n\n    # Constant symbol comparisons\n    verify_eval('\"foo\" != \"bar\"', 2)\n    verify_eval('\"foo\" = \"bar\"', 0)\n    verify_eval('\"foo\" = \"foo\"', 2)\n\n    # Undefined symbols get their name as their value\n    c.warn = False\n    verify_eval(\"'not_defined' = not_defined\", 2)\n    verify_eval(\"not_defined_2 = not_defined_2\", 2)\n    verify_eval(\"not_defined_1 != not_defined_2\", 2)\n\n    # Test less than/greater than\n\n    # Basic evaluation\n    verify_eval(\"INT_37 < 38\", 2)\n    verify_eval(\"38 < INT_37\", 0)\n    verify_eval(\"INT_37 < '38'\", 2)\n    verify_eval(\"'38' < INT_37\", 0)\n    verify_eval(\"INT_37 < 138\", 2)\n    verify_eval(\"138 < INT_37\", 0)\n    verify_eval(\"INT_37 < '138'\", 2)\n    verify_eval(\"'138' < INT_37\", 0)\n    verify_eval(\"INT_37 < -138\", 0)\n    verify_eval(\"-138 < INT_37\", 2)\n    verify_eval(\"INT_37 < '-138'\", 0)\n    verify_eval(\"'-138' < INT_37\", 2)\n    verify_eval(\"INT_37 < 37\", 0)\n    verify_eval(\"37 < INT_37\", 0)\n    verify_eval(\"INT_37 < 36\", 0)\n    verify_eval(\"36 < INT_37\", 2)\n\n    # Different formats in comparison\n    verify_eval(\"INT_37 < 0x26\", 2) # 38\n    verify_eval(\"INT_37 < 0x25\", 0) # 37\n    verify_eval(\"INT_37 < 0x24\", 0) # 36\n    verify_eval(\"HEX_0X37 < 56\", 2) # 0x38\n    verify_eval(\"HEX_0X37 < 55\", 0) # 0x37\n    verify_eval(\"HEX_0X37 < 54\", 0) # 0x36\n\n    # Other int comparisons\n    verify_eval(\"INT_37 <= 38\", 2)\n    verify_eval(\"INT_37 <= 37\", 2)\n    verify_eval(\"INT_37 <= 36\", 0)\n    verify_eval(\"INT_37 >  38\", 0)\n    verify_eval(\"INT_37 >  37\", 0)\n    verify_eval(\"INT_37 >  36\", 2)\n    verify_eval(\"INT_37 >= 38\", 0)\n    verify_eval(\"INT_37 >= 37\", 2)\n    verify_eval(\"INT_37 >= 36\", 2)\n\n    # Other hex comparisons\n    verify_eval(\"HEX_0X37 <= 0x38\", 2)\n    verify_eval(\"HEX_0X37 <= 0x37\", 2)\n    verify_eval(\"HEX_0X37 <= 0x36\", 0)\n    verify_eval(\"HEX_0X37 >  0x38\", 0)\n    verify_eval(\"HEX_0X37 >  0x37\", 0)\n    verify_eval(\"HEX_0X37 >  0x36\", 2)\n    verify_eval(\"HEX_0X37 >= 0x38\", 0)\n    verify_eval(\"HEX_0X37 >= 0x37\", 2)\n    verify_eval(\"HEX_0X37 >= 0x36\", 2)\n\n    # A hex holding a value without a \"0x\" prefix should still be treated as\n    # hexadecimal\n    verify_eval(\"HEX_37 < 0x38\", 2)\n    verify_eval(\"HEX_37 < 0x37\", 0)\n    verify_eval(\"HEX_37 < 0x36\", 0)\n\n    # Symbol comparisons\n    verify_eval(\"INT_37   <  HEX_0X37\", 2)\n    verify_eval(\"INT_37   >  HEX_0X37\", 0)\n    verify_eval(\"HEX_0X37 <  INT_37  \", 0)\n    verify_eval(\"HEX_0X37 >  INT_37  \", 2)\n    verify_eval(\"INT_37   <  INT_37  \", 0)\n    verify_eval(\"INT_37   <= INT_37  \", 2)\n    verify_eval(\"INT_37   >  INT_37  \", 0)\n    verify_eval(\"INT_37   <= INT_37  \", 2)\n\n    # Tristate value comparisons\n    verify_eval(\"n < n\", 0)\n    verify_eval(\"n < m\", 2)\n    verify_eval(\"n < y\", 2)\n    verify_eval(\"n < N\", 0)\n    verify_eval(\"n < M\", 2)\n    verify_eval(\"n < Y\", 2)\n    verify_eval(\"0 > n\", 0)\n    verify_eval(\"1 > n\", 2)\n    verify_eval(\"2 > n\", 2)\n    verify_eval(\"m < n\", 0)\n    verify_eval(\"m < m\", 0)\n    verify_eval(\"m < y\", 2)\n\n    # Strings compare lexicographically\n    verify_eval(\"'aa' < 'ab'\", 2)\n    verify_eval(\"'aa' > 'ab'\", 0)\n    verify_eval(\"'ab' < 'aa'\", 0)\n    verify_eval(\"'ab' > 'aa'\", 2)\n\n    # Comparisons where one of the operands doesn't parse as a number also give\n    # a lexicographic comparison\n    verify_eval(\"INT_37 <  '37a' \", 2)\n    verify_eval(\"'37a'  >  INT_37\", 2)\n    verify_eval(\"INT_37 <= '37a' \", 2)\n    verify_eval(\"'37a'  >= INT_37\", 2)\n    verify_eval(\"INT_37 >= '37a' \", 0)\n    verify_eval(\"INT_37 >  '37a' \", 0)\n    verify_eval(\"'37a'  <  INT_37\", 0)\n    verify_eval(\"'37a'  <= INT_37\", 0)\n\n    def verify_eval_bad(expr):\n        try:\n            c.eval_string(expr)\n        except KconfigError:\n            pass\n        else:\n            fail('expected eval_string(\"{}\") to throw KconfigError, '\n                 \"didn't\".format(expr))\n\n    # Verify that some bad stuff throws KconfigError's\n    verify_eval_bad(\"\")\n    verify_eval_bad(\"&\")\n    verify_eval_bad(\"|\")\n    verify_eval_bad(\"!\")\n    verify_eval_bad(\"(\")\n    verify_eval_bad(\")\")\n    verify_eval_bad(\"=\")\n    verify_eval_bad(\"(X\")\n    verify_eval_bad(\"X)\")\n    verify_eval_bad(\"X X\")\n    verify_eval_bad(\"!X X\")\n    verify_eval_bad(\"X !X\")\n    verify_eval_bad(\"(X) X\")\n    verify_eval_bad(\"X &&\")\n    verify_eval_bad(\"&& X\")\n    verify_eval_bad(\"X && && X\")\n    verify_eval_bad(\"X && !&&\")\n    verify_eval_bad(\"X ||\")\n    verify_eval_bad(\"|| X\")\n\n\n    print(\"Testing Symbol.__str__()/custom_str() and def_{int,hex,string}\")\n\n    def verify_str(item, s):\n        verify_equal(str(item), s[1:-1])\n\n    def verify_custom_str(item, s):\n        verify_equal(item.custom_str(lambda sc: \"[{}]\".format(sc.name)),\n                     s[1:-1])\n\n    c = Kconfig(\"Kconfiglib/tests/Kstr\", warn=False)\n\n    c.modules.set_value(2)\n\n    verify_str(c.syms[\"UNDEFINED\"], \"\"\"\n\"\"\")\n\n    verify_str(c.syms[\"BASIC_NO_PROMPT\"], \"\"\"\nconfig BASIC_NO_PROMPT\n\tbool\n\thelp\n\t  blah blah\n\n\t    blah blah blah\n\n\t   blah\n\"\"\")\n\n    verify_str(c.syms[\"BASIC_PROMPT\"], \"\"\"\nconfig BASIC_PROMPT\n\tbool \"basic\"\n\"\"\")\n\n    verify_str(c.syms[\"ADVANCED\"], \"\"\"\nconfig ADVANCED\n\ttristate \"prompt\" if DEP\n\tdefault DEFAULT_1\n\tdefault DEFAULT_2 if DEP\n\tselect SELECTED_1\n\tselect SELECTED_2 if DEP\n\timply IMPLIED_1\n\timply IMPLIED_2 if DEP\n\thelp\n\t  first help text\n\nconfig ADVANCED\n\ttristate \"prompt 2\"\n\nmenuconfig ADVANCED\n\ttristate \"prompt 3\"\n\nconfig ADVANCED\n\ttristate\n\tdepends on (A || !B || (C && D) || !(E && F) || G = H || (I && !J && (K || L) && !(M || N) && O = P)) && DEP4 && DEP3\n\thelp\n\t  second help text\n\nconfig ADVANCED\n\ttristate \"prompt 4\" if VIS\n\tdepends on DEP4 && DEP3\n\"\"\")\n\n    verify_custom_str(c.syms[\"ADVANCED\"], \"\"\"\nconfig ADVANCED\n\ttristate \"prompt\" if [DEP]\n\tdefault [DEFAULT_1]\n\tdefault [DEFAULT_2] if [DEP]\n\tselect [SELECTED_1]\n\tselect [SELECTED_2] if [DEP]\n\timply [IMPLIED_1]\n\timply [IMPLIED_2] if [DEP]\n\thelp\n\t  first help text\n\nconfig ADVANCED\n\ttristate \"prompt 2\"\n\nmenuconfig ADVANCED\n\ttristate \"prompt 3\"\n\nconfig ADVANCED\n\ttristate\n\tdepends on ([A] || ![B] || ([C] && [D]) || !([E] && [F]) || [G] = [H] || ([I] && ![J] && ([K] || [L]) && !([M] || [N]) && [O] = [P])) && [DEP4] && [DEP3]\n\thelp\n\t  second help text\n\nconfig ADVANCED\n\ttristate \"prompt 4\" if [VIS]\n\tdepends on [DEP4] && [DEP3]\n\"\"\")\n\n\n    verify_str(c.syms[\"ONLY_DIRECT_DEPS\"], \"\"\"\nconfig ONLY_DIRECT_DEPS\n\tint\n\tdepends on DEP1 && DEP2\n\"\"\")\n\n    verify_str(c.syms[\"STRING\"], \"\"\"\nconfig STRING\n\tstring\n\tdefault \"foo\"\n\tdefault \"bar\" if DEP\n\tdefault STRING2\n\tdefault STRING3 if DEP\n\"\"\")\n\n    verify_str(c.syms[\"INT\"], \"\"\"\nconfig INT\n\tint\n\trange 1 2\n\trange FOO BAR\n\trange BAZ QAZ if DEP\n\tdefault 7 if DEP\n\"\"\")\n\n    verify_str(c.syms[\"HEX\"], \"\"\"\nconfig HEX\n\thex\n\trange 0x100 0x200\n\trange FOO BAR\n\trange BAZ QAZ if DEP\n\tdefault 0x123\n\"\"\")\n\n    verify_str(c.modules, \"\"\"\nconfig MODULES\n\tbool \"MODULES\"\n\toption modules\n\"\"\")\n\n    verify_str(c.syms[\"OPTIONS\"], \"\"\"\nconfig OPTIONS\n\toption allnoconfig_y\n\toption defconfig_list\n\toption env=\"ENV\"\n\"\"\")\n\n    verify_str(c.syms[\"CORRECT_PROP_LOCS_BOOL\"], \"\"\"\nconfig CORRECT_PROP_LOCS_BOOL\n\tbool \"prompt 1\"\n\tdefault DEFAULT_1\n\tdefault DEFAULT_2\n\tselect SELECT_1\n\tselect SELECT_2\n\timply IMPLY_1\n\timply IMPLY_2\n\tdepends on LOC_1\n\thelp\n\t  help 1\n\nmenuconfig CORRECT_PROP_LOCS_BOOL\n\tbool \"prompt 2\"\n\tdefault DEFAULT_3\n\tdefault DEFAULT_4\n\tselect SELECT_3\n\tselect SELECT_4\n\timply IMPLY_3\n\timply IMPLY_4\n\tdepends on LOC_2\n\thelp\n\t  help 2\n\nconfig CORRECT_PROP_LOCS_BOOL\n\tbool \"prompt 3\"\n\tdefault DEFAULT_5\n\tdefault DEFAULT_6\n\tselect SELECT_5\n\tselect SELECT_6\n\timply IMPLY_5\n\timply IMPLY_6\n\tdepends on LOC_3\n\thelp\n\t  help 2\n\"\"\")\n\n    verify_str(c.syms[\"CORRECT_PROP_LOCS_INT\"], \"\"\"\nconfig CORRECT_PROP_LOCS_INT\n\tint\n\trange 1 2\n\trange 3 4\n\tdepends on LOC_1\n\nconfig CORRECT_PROP_LOCS_INT\n\tint\n\trange 5 6\n\trange 7 8\n\tdepends on LOC_2\n\"\"\")\n\n    verify_str(c.syms[\"PROMPT_ONLY\"], \"\"\"\nconfig PROMPT_ONLY\n\tprompt \"prompt only\"\n\"\"\")\n\n    verify_custom_str(c.syms[\"CORRECT_PROP_LOCS_INT\"], \"\"\"\nconfig CORRECT_PROP_LOCS_INT\n\tint\n\trange [1] [2]\n\trange [3] [4]\n\tdepends on [LOC_1]\n\nconfig CORRECT_PROP_LOCS_INT\n\tint\n\trange [5] [6]\n\trange [7] [8]\n\tdepends on [LOC_2]\n\"\"\")\n\n\n\n    print(\"Testing Choice.__str__()/custom_str()\")\n\n    verify_str(c.named_choices[\"CHOICE\"], \"\"\"\nchoice CHOICE\n\ttristate \"foo\"\n\tdefault CHOICE_1\n\tdefault CHOICE_2 if dep\n\"\"\")\n\n    verify_str(c.named_choices[\"CHOICE\"].nodes[0].next.item, \"\"\"\nchoice\n\ttristate \"no name\"\n\toptional\n\"\"\")\n\n    verify_str(c.named_choices[\"CORRECT_PROP_LOCS_CHOICE\"], \"\"\"\nchoice CORRECT_PROP_LOCS_CHOICE\n\tbool\n\tdefault CHOICE_3\n\tdepends on LOC_1\n\nchoice CORRECT_PROP_LOCS_CHOICE\n\tbool\n\tdefault CHOICE_4\n\tdepends on LOC_2\n\nchoice CORRECT_PROP_LOCS_CHOICE\n\tbool\n\tdefault CHOICE_5\n\tdepends on LOC_3\n\"\"\")\n\n    verify_custom_str(c.named_choices[\"CORRECT_PROP_LOCS_CHOICE\"], \"\"\"\nchoice CORRECT_PROP_LOCS_CHOICE\n\tbool\n\tdefault [CHOICE_3]\n\tdepends on [LOC_1]\n\nchoice CORRECT_PROP_LOCS_CHOICE\n\tbool\n\tdefault [CHOICE_4]\n\tdepends on [LOC_2]\n\nchoice CORRECT_PROP_LOCS_CHOICE\n\tbool\n\tdefault [CHOICE_5]\n\tdepends on [LOC_3]\n\"\"\")\n\n\n    print(\"Testing MenuNode.__str__()/custom_str() for menus and comments\")\n\n    verify_str(c.syms[\"SIMPLE_MENU_HOOK\"].nodes[0].next, \"\"\"\nmenu \"simple menu\"\n\"\"\")\n\n    verify_str(c.syms[\"ADVANCED_MENU_HOOK\"].nodes[0].next, \"\"\"\nmenu \"advanced menu\"\n\tdepends on A\n\tvisible if B && (C || D)\n\"\"\")\n\n    verify_custom_str(c.syms[\"ADVANCED_MENU_HOOK\"].nodes[0].next, \"\"\"\nmenu \"advanced menu\"\n\tdepends on [A]\n\tvisible if [B] && ([C] || [D])\n\"\"\")\n\n    verify_str(c.syms[\"SIMPLE_COMMENT_HOOK\"].nodes[0].next, \"\"\"\ncomment \"simple comment\"\n\"\"\")\n\n    verify_str(c.syms[\"ADVANCED_COMMENT_HOOK\"].nodes[0].next, \"\"\"\ncomment \"advanced comment\"\n\tdepends on A && B\n\"\"\")\n\n    verify_custom_str(c.syms[\"ADVANCED_COMMENT_HOOK\"].nodes[0].next, \"\"\"\ncomment \"advanced comment\"\n\tdepends on [A] && [B]\n\"\"\")\n\n\n    print(\"Testing {MenuNode,Symbol,Choice}.orig_*\")\n\n    # Just test some corner cases here re. MenuNode.orig_*. They are already\n    # indirectly tested above. Use MenuNode.__str__() as a proxy.\n\n    verify_str(c.syms[\"DEP_REM_CORNER_CASES\"], \"\"\"\nconfig DEP_REM_CORNER_CASES\n\tbool\n\tdefault A\n\tdepends on n\n\nconfig DEP_REM_CORNER_CASES\n\tbool\n\tdefault B if n\n\nconfig DEP_REM_CORNER_CASES\n\tbool\n\tdefault C\n\tdepends on m && MODULES\n\nconfig DEP_REM_CORNER_CASES\n\tbool\n\tdefault D if A\n\nconfig DEP_REM_CORNER_CASES\n\tbool\n\tdefault E if !E1\n\tdefault F if F1 = F2\n\tdefault G if G1 || H1\n\tdepends on !H\n\nconfig DEP_REM_CORNER_CASES\n\tbool\n\tdefault H\n\tdepends on \"foo\" = \"bar\"\n\nconfig DEP_REM_CORNER_CASES\n\tbool \"prompt\" if FOO || BAR\n\tdepends on BAZ && QAZ\n\"\"\")\n\n    # Test {Symbol,Choice}.orig_*\n\n    def verify_deps(elms, dep_index, expected):\n        verify_equal(\" \".join(expr_str(elm[dep_index]) for elm in elms),\n                     expected)\n\n    verify_deps(c.syms[\"BOOL_SYM_ORIG\"].orig_defaults,        1, \"DEP y y\")\n    verify_deps(c.syms[\"BOOL_SYM_ORIG\"].orig_selects,         1, \"y DEP y\")\n    verify_deps(c.syms[\"BOOL_SYM_ORIG\"].orig_implies,         1, \"y y DEP\")\n    verify_deps(c.syms[\"INT_SYM_ORIG\"].orig_ranges,           2, \"DEP y DEP\")\n    verify_deps(c.named_choices[\"CHOICE_ORIG\"].orig_defaults, 1, \"y DEP DEP\")\n\n\n    print(\"Testing Symbol.__repr__()\")\n\n    def verify_repr(item, s):\n        verify_equal(repr(item) + \"\\n\", s[1:])\n\n    c = Kconfig(\"Kconfiglib/tests/Krepr\", warn=False)\n\n    verify_repr(c.n, \"\"\"\n<symbol n, tristate, value n, constant>\n\"\"\")\n\n    verify_repr(c.m, \"\"\"\n<symbol m, tristate, value m, constant>\n\"\"\")\n\n    verify_repr(c.y, \"\"\"\n<symbol y, tristate, value y, constant>\n\"\"\")\n\n    verify_repr(c.syms[\"UNDEFINED\"], \"\"\"\n<symbol UNDEFINED, unknown, value \"UNDEFINED\", visibility n, direct deps n, undefined>\n\"\"\")\n\n    verify_repr(c.syms[\"BASIC\"], \"\"\"\n<symbol BASIC, bool, value y, visibility n, direct deps y, Kconfiglib/tests/Krepr:9>\n\"\"\")\n\n    verify_repr(c.syms[\"VISIBLE\"], \"\"\"\n<symbol VISIBLE, bool, \"visible\", value n, visibility y, direct deps y, Kconfiglib/tests/Krepr:14>\n\"\"\")\n\n    c.syms[\"VISIBLE\"].set_value(2)\n    c.syms[\"STRING\"].set_value(\"foo\")\n\n    verify_repr(c.syms[\"VISIBLE\"], \"\"\"\n<symbol VISIBLE, bool, \"visible\", value y, user value y, visibility y, direct deps y, Kconfiglib/tests/Krepr:14>\n\"\"\")\n\n    verify_repr(c.syms[\"STRING\"], \"\"\"\n<symbol STRING, string, \"visible\", value \"foo\", user value \"foo\", visibility y, direct deps y, Kconfiglib/tests/Krepr:17>\n\"\"\")\n\n    verify_repr(c.syms[\"DIR_DEP_N\"], \"\"\"\n<symbol DIR_DEP_N, unknown, value \"DIR_DEP_N\", visibility n, direct deps n, Kconfiglib/tests/Krepr:20>\n\"\"\")\n\n    verify_repr(c.syms[\"OPTIONS\"], \"\"\"\n<symbol OPTIONS, unknown, value \"OPTIONS\", visibility n, allnoconfig_y, is the defconfig_list symbol, from environment variable ENV, direct deps y, Kconfiglib/tests/Krepr:23>\n\"\"\")\n\n    verify_repr(c.syms[\"MULTI_DEF\"], \"\"\"\n<symbol MULTI_DEF, unknown, value \"MULTI_DEF\", visibility n, direct deps y, Kconfiglib/tests/Krepr:28, Kconfiglib/tests/Krepr:29>\n\"\"\")\n\n    verify_repr(c.syms[\"CHOICE_1\"], \"\"\"\n<symbol CHOICE_1, tristate, \"choice sym\", value n, visibility m, choice symbol, direct deps m, Kconfiglib/tests/Krepr:36>\n\"\"\")\n\n    verify_repr(c.modules, \"\"\"\n<symbol MODULES, bool, value y, visibility n, is the modules symbol, direct deps y, Kconfiglib/tests/Krepr:1>\n\"\"\")\n\n\n    print(\"Testing Choice.__repr__()\")\n\n    verify_repr(c.named_choices[\"CHOICE\"], \"\"\"\n<choice CHOICE, tristate, \"choice\", mode m, visibility y, Kconfiglib/tests/Krepr:33>\n\"\"\")\n\n    c.named_choices[\"CHOICE\"].set_value(2)\n\n    verify_repr(c.named_choices[\"CHOICE\"], \"\"\"\n<choice CHOICE, tristate, \"choice\", mode y, user mode y, CHOICE_1 selected, visibility y, Kconfiglib/tests/Krepr:33>\n\"\"\")\n\n    c.syms[\"CHOICE_2\"].set_value(2)\n\n    verify_repr(c.named_choices[\"CHOICE\"], \"\"\"\n<choice CHOICE, tristate, \"choice\", mode y, user mode y, CHOICE_2 selected, CHOICE_2 selected by user, visibility y, Kconfiglib/tests/Krepr:33>\n\"\"\")\n\n    c.named_choices[\"CHOICE\"].set_value(1)\n\n    verify_repr(c.named_choices[\"CHOICE\"], \"\"\"\n<choice CHOICE, tristate, \"choice\", mode m, user mode m, CHOICE_2 selected by user (overridden), visibility y, Kconfiglib/tests/Krepr:33>\n\"\"\")\n\n    verify_repr(c.syms[\"CHOICE_HOOK\"].nodes[0].next.item, \"\"\"\n<choice, tristate, \"optional choice\", mode n, visibility n, optional, Kconfiglib/tests/Krepr:46>\n\"\"\")\n\n\n    print(\"Testing MenuNode.__repr__()\")\n\n    verify_repr(c.syms[\"BASIC\"].nodes[0], \"\"\"\n<menu node for symbol BASIC, deps y, has help, has next, Kconfiglib/tests/Krepr:9>\n\"\"\")\n\n    verify_repr(c.syms[\"DIR_DEP_N\"].nodes[0], \"\"\"\n<menu node for symbol DIR_DEP_N, deps n, has next, Kconfiglib/tests/Krepr:20>\n\"\"\")\n\n    verify_repr(c.syms[\"MULTI_DEF\"].nodes[0], \"\"\"\n<menu node for symbol MULTI_DEF, deps y, has next, Kconfiglib/tests/Krepr:28>\n\"\"\")\n\n    verify_repr(c.syms[\"MULTI_DEF\"].nodes[1], \"\"\"\n<menu node for symbol MULTI_DEF, deps y, has next, Kconfiglib/tests/Krepr:29>\n\"\"\")\n\n    verify_repr(c.syms[\"MENUCONFIG\"].nodes[0], \"\"\"\n<menu node for symbol MENUCONFIG, is menuconfig, deps y, has next, Kconfiglib/tests/Krepr:31>\n\"\"\")\n\n    verify_repr(c.named_choices[\"CHOICE\"].nodes[0], \"\"\"\n<menu node for choice CHOICE, prompt \"choice\" (visibility y), deps y, has child, has next, Kconfiglib/tests/Krepr:33>\n\"\"\")\n\n    verify_repr(c.syms[\"CHOICE_HOOK\"].nodes[0].next, \"\"\"\n<menu node for choice, prompt \"optional choice\" (visibility n), deps y, has next, Kconfiglib/tests/Krepr:46>\n\"\"\")\n\n    verify_repr(c.syms[\"NO_VISIBLE_IF_HOOK\"].nodes[0].next, \"\"\"\n<menu node for menu, prompt \"no visible if\" (visibility y), deps y, 'visible if' deps y, has next, Kconfiglib/tests/Krepr:53>\n\"\"\")\n\n    verify_repr(c.syms[\"VISIBLE_IF_HOOK\"].nodes[0].next, \"\"\"\n<menu node for menu, prompt \"visible if\" (visibility y), deps y, 'visible if' deps m, has next, Kconfiglib/tests/Krepr:58>\n\"\"\")\n\n    verify_repr(c.syms[\"COMMENT_HOOK\"].nodes[0].next, \"\"\"\n<menu node for comment, prompt \"comment\" (visibility y), deps y, Kconfiglib/tests/Krepr:64>\n\"\"\")\n\n\n    print(\"Testing Kconfig.__repr__()\")\n\n    verify_repr(c, \"\"\"\n<configuration with 15 symbols, main menu prompt \"Main menu\", srctree is current directory, config symbol prefix \"CONFIG_\", warnings disabled, printing of warnings to stderr enabled, undef. symbol assignment warnings disabled, overriding symbol assignment warnings enabled, redundant symbol assignment warnings enabled>\n\"\"\")\n\n    os.environ[\"srctree\"] = \"Kconfiglib\"\n    os.environ[\"CONFIG_\"] = \"CONFIG_ value\"\n\n    c = Kconfig(\"tests/Krepr\", warn=False)\n    c.warn = True\n    c.warn_to_stderr = False\n    c.warn_assign_override = False\n    c.warn_assign_redun = False\n    c.warn_assign_undef = True\n\n    verify_repr(c, \"\"\"\n<configuration with 15 symbols, main menu prompt \"Main menu\", srctree \"Kconfiglib\", config symbol prefix \"CONFIG_ value\", warnings enabled, printing of warnings to stderr disabled, undef. symbol assignment warnings enabled, overriding symbol assignment warnings disabled, redundant symbol assignment warnings disabled>\n\"\"\")\n\n    os.environ.pop(\"srctree\", None)\n    os.environ.pop(\"CONFIG_\", None)\n\n\n    print(\"Testing tricky help strings\")\n\n    c = Kconfig(\"Kconfiglib/tests/Khelp\")\n\n    def verify_help(node, s):\n        verify_equal(node.help, s[1:-1])\n\n    verify_help(c.syms[\"TWO_HELP_STRINGS\"].nodes[0], \"\"\"\nfirst help string\n\"\"\")\n\n    verify_help(c.syms[\"TWO_HELP_STRINGS\"].nodes[1], \"\"\"\nsecond help string\n\"\"\")\n\n    verify_help(c.syms[\"NO_BLANK_AFTER_HELP\"].nodes[0], \"\"\"\nhelp for\nNO_BLANK_AFTER_HELP\n\"\"\")\n\n    verify_help(c.named_choices[\"CHOICE_HELP\"].nodes[0], \"\"\"\nhelp for\nCHOICE_HELP\n\"\"\")\n\n    verify_help(c.syms[\"HELP_TERMINATED_BY_COMMENT\"].nodes[0], \"\"\"\na\nb\nc\n\"\"\")\n\n    verify_help(c.syms[\"TRICKY_HELP\"].nodes[0], \"\"\"\na\n b\n  c\n\n d\n  e\n   f\n\n\ng\n h\n  i\n\"\"\")\n\n\n    print(\"Testing locations, source/rsource/gsource/grsource, and \"\n          \"Kconfig.kconfig_filenames\")\n\n    def verify_locations(nodes, *expected_locs):\n        verify(len(nodes) == len(expected_locs),\n               \"Wrong number of locations for \" + repr(nodes))\n\n        for node, expected_loc in zip(nodes, expected_locs):\n            node_loc = \"{}:{}\".format(node.filename, node.linenr)\n            verify(node_loc == expected_loc,\n                   \"expected {} to have the location {}, had the location {}\"\n                   .format(repr(node), expected_loc, node_loc))\n\n    # Expanded in the 'source' statement in Klocation\n\n    os.environ[\"TESTS_DIR_FROM_ENV\"] = \"tests\"\n    os.environ[\"SUB_DIR_FROM_ENV\"] = \"sub\"\n\n    os.environ[\"_SOURCED\"] = \"_sourced\"\n    os.environ[\"_RSOURCED\"] = \"_rsourced\"\n    os.environ[\"_GSOURCED\"] = \"_gsourced\"\n    os.environ[\"_GRSOURCED\"] = \"_grsourced\"\n\n    # Test twice, with $srctree as a relative and an absolute path,\n    # respectively\n    for srctree in \"Kconfiglib\", os.path.abspath(\"Kconfiglib\"):\n        os.environ[\"srctree\"] = srctree\n\n        # Has symbol with empty help text, so disable warnings\n        c = Kconfig(\"tests/Klocation\", warn=False)\n\n        verify_locations(c.syms[\"UNDEFINED\"].nodes)\n        verify_equal(c.syms[\"UNDEFINED\"].name_and_loc, \"UNDEFINED (undefined)\")\n\n        verify_locations(c.syms[\"ONE_DEF\"].nodes, \"tests/Klocation:4\")\n        verify_equal(c.syms[\"ONE_DEF\"].name_and_loc,\n                     \"ONE_DEF (defined at tests/Klocation:4)\")\n\n        verify_locations(c.syms[\"TWO_DEF\"].nodes,\n                         \"tests/Klocation:7\",\n                         \"tests/Klocation:10\")\n        verify_equal(c.syms[\"TWO_DEF\"].name_and_loc,\n                     \"TWO_DEF (defined at tests/Klocation:7, tests/Klocation:10)\")\n\n        verify_locations(c.syms[\"MANY_DEF\"].nodes,\n                         \"tests/Klocation:13\",\n                         \"tests/Klocation:43\",\n                         \"tests/Klocation:45\",\n                         \"tests/Klocation_sourced:3\",\n                         \"tests/sub/Klocation_rsourced:2\",\n                         \"tests/sub/Klocation_gsourced1:1\",\n                         \"tests/sub/Klocation_gsourced2:1\",\n                         \"tests/sub/Klocation_gsourced1:1\",\n                         \"tests/sub/Klocation_gsourced2:1\",\n                         \"tests/sub/Klocation_grsourced1:1\",\n                         \"tests/sub/Klocation_grsourced2:1\",\n                         \"tests/sub/Klocation_grsourced1:1\",\n                         \"tests/sub/Klocation_grsourced2:1\",\n                         \"tests/Klocation:78\")\n\n        verify_locations(c.named_choices[\"CHOICE_ONE_DEF\"].nodes,\n                         \"tests/Klocation_sourced:5\")\n        verify_equal(c.named_choices[\"CHOICE_ONE_DEF\"].name_and_loc,\n                     \"<choice CHOICE_ONE_DEF> (defined at tests/Klocation_sourced:5)\")\n\n        verify_locations(c.named_choices[\"CHOICE_TWO_DEF\"].nodes,\n                         \"tests/Klocation_sourced:9\",\n                         \"tests/Klocation_sourced:13\")\n        verify_equal(c.named_choices[\"CHOICE_TWO_DEF\"].name_and_loc,\n                     \"<choice CHOICE_TWO_DEF> (defined at tests/Klocation_sourced:9, tests/Klocation_sourced:13)\")\n\n        verify_locations([c.syms[\"MENU_HOOK\"].nodes[0].next],\n                         \"tests/Klocation_sourced:20\")\n\n        verify_locations([c.syms[\"COMMENT_HOOK\"].nodes[0].next],\n                         \"tests/Klocation_sourced:26\")\n\n        # Test Kconfig.kconfig_filenames\n\n        verify_equal(c.kconfig_filenames, [\n            \"tests/Klocation\",\n            \"tests/Klocation_sourced\",\n            \"tests/sub/Klocation_rsourced\",\n            \"tests/sub/Klocation_gsourced1\",\n            \"tests/sub/Klocation_gsourced2\",\n            \"tests/sub/Klocation_gsourced1\",\n            \"tests/sub/Klocation_gsourced2\",\n            \"tests/sub/Klocation_grsourced1\",\n            \"tests/sub/Klocation_grsourced2\",\n            \"tests/sub/Klocation_grsourced1\",\n            \"tests/sub/Klocation_grsourced2\"\n        ])\n\n        # Test recursive 'source' detection\n\n        try:\n            Kconfig(\"tests/Krecursive1\")\n        except KconfigError as e:\n            verify_equal(str(e), \"\"\"\ntests/Krecursive2:1: recursive 'source' of 'tests/Krecursive1' detected. Check that environment variables are set correctly.\nInclude path:\ntests/Krecursive1:1\ntests/Krecursive2:1\n\"\"\"[:-1])\n        except:\n            fail(\"recursive 'source' raised wrong exception\")\n        else:\n            fail(\"recursive 'source' did not raise exception\")\n\n        # Verify that source and rsource throw exceptions for missing files\n\n        # TODO: Make an exception test helper\n\n        try:\n            Kconfig(\"tests/Kmissingsource\")\n        except KconfigError as e:\n            if \"not found\" not in str(e):\n                fail(\"'source' with missing file raised wrong KconfigError\")\n        except:\n            fail(\"'source' with missing file raised wrong exception\")\n        else:\n            fail(\"'source' with missing file did not raise exception\")\n\n        try:\n            Kconfig(\"tests/Kmissingrsource\")\n        except KconfigError as e:\n            if \"not found\" not in str(e):\n                fail(\"'rsource' with missing file raised wrong KconfigError\")\n        except:\n            fail(\"'rsource' with missing file raised wrong exception\")\n        else:\n            fail(\"'rsource' with missing file did not raise exception\")\n\n    # Test a tricky case involving symlinks. $srctree is tests/symlink, which\n    # points to tests/sub/sub, meaning tests/symlink/.. != tests/. Previously,\n    # using 'rsource' from a file sourced with an absolute path triggered an\n    # unsafe relpath() with tests/symlink/.. in it, crashing.\n\n    os.environ[\"srctree\"] = \"Kconfiglib/tests/symlink\"\n    os.environ[\"KCONFIG_SYMLINK_2\"] = os.path.abspath(\n        \"Kconfiglib/tests/sub/Kconfig_symlink_2\")\n    if not os.path.isabs(\n        Kconfig(\"Kconfig_symlink_1\").syms[\"FOUNDME\"].nodes[0].filename):\n\n        fail(\"Symlink + rsource issues\")\n\n\n    print(\"Testing Kconfig.node_iter()\")\n\n    # Reuse tests/Klocation. The node_iter(unique_syms=True) case already gets\n    # plenty of testing from write_config() as well.\n\n    os.environ[\"srctree\"] = \"Kconfiglib\"\n    c = Kconfig(\"tests/Klocation\", warn=False)\n\n    verify_equal(\n        [node.item.name for node in c.node_iter()\n         if isinstance(node.item, Symbol)],\n        [\"ONE_DEF\", \"TWO_DEF\", \"TWO_DEF\", \"MANY_DEF\", \"HELP_1\", \"HELP_2\",\n         \"HELP_3\", \"MANY_DEF\", \"MANY_DEF\", \"MANY_DEF\", \"MENU_HOOK\",\n         \"COMMENT_HOOK\"] + 10*[\"MANY_DEF\"])\n\n    verify_equal(\n        [node.item.name for node in c.node_iter(True)\n         if isinstance(node.item, Symbol)],\n        [\"ONE_DEF\", \"TWO_DEF\", \"MANY_DEF\", \"HELP_1\", \"HELP_2\", \"HELP_3\",\n         \"MENU_HOOK\", \"COMMENT_HOOK\"])\n\n    verify_equal(\n        [node.prompt[0] for node in c.node_iter()\n         if not isinstance(node.item, Symbol)],\n        [\"one-def choice\", \"two-def choice 1\", \"two-def choice 2\",\n         \"menu\", \"comment\"])\n\n    verify_equal(\n        [node.prompt[0] for node in c.node_iter(True)\n         if not isinstance(node.item, Symbol)],\n        [\"one-def choice\", \"two-def choice 1\", \"two-def choice 2\",\n         \"menu\", \"comment\"])\n\n\n    print(\"Testing MenuNode.include_path\")\n\n    os.environ[\"srctree\"] = \"Kconfiglib/tests\"\n\n    c = Kconfig(\"Kinclude_path\")\n\n    def verify_node_path(node, *expected):\n        if node.include_path != expected:\n            fail(\"Wrong include path for node {!r}. Got {}, expected {}.\"\n                 .format(node, node.include_path, expected))\n\n    def verify_sym_path(sym_name, node_i, *expected):\n        verify_node_path(c.syms[sym_name].nodes[node_i], *expected)\n\n    verify_sym_path(\"TOP\", 0)\n    verify_sym_path(\"TOP\", 1)\n    verify_sym_path(\"TOP\", 2)\n\n    verify_sym_path(\"ONE_DOWN\", 0, (\"Kinclude_path\", 4))\n    verify_sym_path(\"ONE_DOWN\", 1, (\"Kinclude_path\", 4))\n    verify_sym_path(\"ONE_DOWN\", 2, (\"Kinclude_path\", 4))\n    verify_sym_path(\"ONE_DOWN\", 3, (\"Kinclude_path\", 9))\n    verify_sym_path(\"ONE_DOWN\", 4, (\"Kinclude_path\", 9))\n    verify_sym_path(\"ONE_DOWN\", 5, (\"Kinclude_path\", 9))\n\n    verify_sym_path(\"TWO_DOWN\", 0,\n                    (\"Kinclude_path\", 4), (\"Kinclude_path_sourced_1\", 4))\n    verify_sym_path(\"TWO_DOWN\", 1,\n                    (\"Kinclude_path\", 4), (\"Kinclude_path_sourced_1\", 9))\n    verify_sym_path(\"TWO_DOWN\", 2,\n                    (\"Kinclude_path\", 9), (\"Kinclude_path_sourced_1\", 4))\n    verify_sym_path(\"TWO_DOWN\", 3,\n                    (\"Kinclude_path\", 9), (\"Kinclude_path_sourced_1\", 9))\n\n    verify_node_path(c.top_node)\n    verify_node_path(c.menus[0], (\"Kinclude_path\", 4), (\"Kinclude_path_sourced_1\", 4))\n    verify_node_path(c.comments[0], (\"Kinclude_path\", 4), (\"Kinclude_path_sourced_1\", 4))\n    verify_node_path(c.choices[0].nodes[0], (\"Kinclude_path\", 4), (\"Kinclude_path_sourced_1\", 4))\n\n    os.environ.pop(\"srctree\", None)\n\n\n    print(\"Testing Kconfig.choices/menus/comments\")\n\n    c = Kconfig(\"Kconfiglib/tests/Kitemlists\")\n\n    def verify_prompts(items, *expected_prompts):\n        verify(len(items) == len(expected_prompts),\n               \"Wrong number of prompts for {}\".format(items))\n\n        for item, expected_prompt in zip(items, expected_prompts):\n            if not isinstance(item, MenuNode):\n                item = item.nodes[0]\n\n            verify(item.prompt[0] == expected_prompt,\n                   \"Wrong prompt for {}, expected '{}'\"\n                   .format(repr(item), expected_prompt))\n\n    verify_prompts(c.choices, \"choice 1\", \"choice 2\", \"choice 3\", \"choice 2\")\n    verify_prompts(c.menus, \"menu 1\", \"menu 2\", \"menu 3\", \"menu 4\", \"menu 5\")\n    verify_prompts(c.comments, \"comment 1\", \"comment 2\", \"comment 3\")\n\n\n    print(\"Testing Symbol/Choice.direct_dep\")\n\n    c = Kconfig(\"Kconfiglib/tests/Kdirdep\")\n\n    verify_equal(expr_str(c.syms[\"NO_DEP_SYM\"].direct_dep), 'y')\n    verify_equal(expr_str(c.syms[\"DEP_SYM\"].direct_dep), \"A || (B && C) || !D\")\n\n    verify_equal(expr_str(c.named_choices[\"NO_DEP_CHOICE\"].direct_dep), 'y')\n    verify_equal(expr_str(c.named_choices[\"DEP_CHOICE\"].direct_dep),\n                 \"A || B || C\")\n\n\n    print(\"Testing expr_items()\")\n\n    c = Kconfig(\"Kconfiglib/tests/Kexpr_items\")\n\n    def verify_expr_items(expr, *sym_names):\n        verify_equal(tuple(sorted(item.name for item in expr_items(expr))),\n                     sym_names)\n\n    verify_expr_items(\n        c.syms[\"TEST\"].defaults[0][0],\n        \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\"\n    )\n\n    verify_expr_items(\n        c.syms[\"TEST_CHOICE\"].nodes[0].prompt[1],\n        \"A\", \"CHOICE\"\n    )\n\n\n    print(\"Testing MenuNode/Symbol/Choice.referenced\")\n\n    c = Kconfig(\"Kconfiglib/tests/Kreferenced\", warn=False)\n\n    def verify_deps(item, *dep_names):\n        verify_equal(tuple(sorted(item.name for item in item.referenced)),\n                     dep_names)\n\n    verify_deps(c.top_node, \"y\")\n\n    verify_deps(c.syms[\"NO_REFS\"].nodes[0], \"y\")\n\n    verify_deps(c.syms[\"JUST_DEPENDS_ON_REFS\"].nodes[0], \"A\", \"B\")\n\n    verify_deps(c.syms[\"LOTS_OF_REFS\"].nodes[0],\n                *(chr(n) for n in range(ord(\"A\"), ord(\"Z\") + 1)))\n\n    verify_deps(c.syms[\"INT_REFS\"].nodes[0],\n                \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\", \"y\")\n\n    verify_deps(c.syms[\"CHOICE_REF\"].nodes[0], \"CHOICE\")\n\n    verify_deps(c.menus[0], \"A\", \"B\", \"C\", \"D\")\n\n    verify_deps(c.comments[0], \"A\", \"B\")\n\n    verify_deps(c.syms[\"MULTI_DEF_SYM\"], \"A\", \"B\", \"C\", \"y\")\n    verify_deps(c.named_choices[\"MULTI_DEF_CHOICE\"], \"A\", \"B\", \"C\")\n\n\n    print(\"Testing split_expr()\")\n\n    c = Kconfig(\"Kconfiglib/tests/empty\")\n    c.warn = False\n\n    def verify_split(to_split, op, operand_strs):\n        # The same hackage as in Kconfig.eval_string()\n        c._tokens = c._tokenize(\"if \" + to_split)[1:]\n        c._tokens_i = 0\n\n        operands = split_expr(c._parse_expr(False), op)\n\n        verify(len(operands) == len(operand_strs),\n               \"Wrong number of operands when {} was split by {}\"\n               .format(to_split, \"OR\" if op == OR else \"AND\"))\n\n        for operand, operand_str in zip(operands, operand_strs):\n            verify_equal(expr_str(operand), operand_str)\n\n    verify_split(\"A\",                    OR, (\"A\",                ))\n    verify_split(\"!A\",                   OR, (\"!A\",               ))\n    verify_split(\"A = B\",                OR, (\"A = B\",            ))\n    verify_split(\"A && B\",               OR, (\"A && B\",           ))\n    verify_split(\"A || B\",               OR, (\"A\", \"B\"            ))\n    verify_split(\"(A || B) || C\",        OR, (\"A\", \"B\", \"C\"       ))\n    verify_split(\"A || (B || C)\",        OR, (\"A\", \"B\", \"C\"       ))\n    verify_split(\"A || !(B || C)\",       OR, (\"A\", \"!(B || C)\"    ))\n    verify_split(\"A || (B && (C || D))\", OR, (\"A\", \"B && (C || D)\"))\n    verify_split(\"(A && (B || C)) || D\", OR, (\"A && (B || C)\", \"D\"))\n\n    verify_split(\"A\",                    AND, (\"A\",                ))\n    verify_split(\"!A\",                   AND, (\"!A\",               ))\n    verify_split(\"A = B\",                AND, (\"A = B\",            ))\n    verify_split(\"A || B\",               AND, (\"A || B\",           ))\n    verify_split(\"A && B\",               AND, (\"A\", \"B\"            ))\n    verify_split(\"(A && B) && C\",        AND, (\"A\", \"B\", \"C\"       ))\n    verify_split(\"A && (B && C)\",        AND, (\"A\", \"B\", \"C\"       ))\n    verify_split(\"A && !(B && C)\",       AND, (\"A\", \"!(B && C)\"    ))\n    verify_split(\"A && (B || (C && D))\", AND, (\"A\", \"B || (C && D)\"))\n    verify_split(\"(A || (B && C)) && D\", AND, (\"A || (B && C)\", \"D\"))\n\n\n    print(\"Testing visibility\")\n\n    c = Kconfig(\"Kconfiglib/tests/Kvisibility\")\n\n    def verify_visibility(item, no_module_vis, module_vis):\n        c.modules.set_value(0)\n        verify(item.visibility == no_module_vis,\n               \"expected {} to have visibility {} without modules, had \"\n               \"visibility {}\".\n               format(repr(item), no_module_vis, item.visibility))\n\n        c.modules.set_value(2)\n        verify(item.visibility == module_vis,\n               \"expected {} to have visibility {} with modules, had \"\n               \"visibility {}\".\n               format(repr(item), module_vis, item.visibility))\n\n    # Symbol visibility\n\n    verify_visibility(c.syms[\"NO_PROMPT\"],     0, 0)\n    verify_visibility(c.syms[\"BOOL_N\"],        0, 0)\n    verify_visibility(c.syms[\"BOOL_M\"],        0, 2)\n    verify_visibility(c.syms[\"BOOL_MOD\"],      2, 2)\n    verify_visibility(c.syms[\"BOOL_Y\"],        2, 2)\n    verify_visibility(c.syms[\"TRISTATE_M\"],    0, 1)\n    verify_visibility(c.syms[\"TRISTATE_MOD\"],  2, 1)\n    verify_visibility(c.syms[\"TRISTATE_Y\"],    2, 2)\n    verify_visibility(c.syms[\"BOOL_IF_N\"],     0, 0)\n    verify_visibility(c.syms[\"BOOL_IF_M\"],     0, 2)\n    verify_visibility(c.syms[\"BOOL_IF_Y\"],     2, 2)\n    verify_visibility(c.syms[\"BOOL_MENU_N\"],   0, 0)\n    verify_visibility(c.syms[\"BOOL_MENU_M\"],   0, 2)\n    verify_visibility(c.syms[\"BOOL_MENU_Y\"],   2, 2)\n    verify_visibility(c.syms[\"BOOL_CHOICE_N\"], 0, 0)\n\n    # Non-tristate symbols in tristate choices are only visible if the choice\n    # is in y mode\n\n    # The choice can't be brought to y mode because of the 'if m'\n    verify_visibility(c.syms[\"BOOL_CHOICE_M\"], 0, 0)\n    c.syms[\"BOOL_CHOICE_M\"].choice.set_value(2)\n    verify_visibility(c.syms[\"BOOL_CHOICE_M\"], 0, 0)\n\n    # The choice gets y mode only when running without modules, because it\n    # defaults to m mode\n    verify_visibility(c.syms[\"BOOL_CHOICE_Y\"], 2, 0)\n    c.syms[\"BOOL_CHOICE_Y\"].choice.set_value(2)\n    # When set to y mode, the choice symbol becomes visible both with and\n    # without modules\n    verify_visibility(c.syms[\"BOOL_CHOICE_Y\"], 2, 2)\n\n    verify_visibility(c.syms[\"TRISTATE_IF_N\"],     0, 0)\n    verify_visibility(c.syms[\"TRISTATE_IF_M\"],     0, 1)\n    verify_visibility(c.syms[\"TRISTATE_IF_Y\"],     2, 2)\n    verify_visibility(c.syms[\"TRISTATE_MENU_N\"],   0, 0)\n    verify_visibility(c.syms[\"TRISTATE_MENU_M\"],   0, 1)\n    verify_visibility(c.syms[\"TRISTATE_MENU_Y\"],   2, 2)\n    verify_visibility(c.syms[\"TRISTATE_CHOICE_N\"], 0, 0)\n    verify_visibility(c.syms[\"TRISTATE_CHOICE_M\"], 0, 1)\n    verify_visibility(c.syms[\"TRISTATE_CHOICE_Y\"], 2, 2)\n\n    verify_visibility(c.named_choices[\"BOOL_CHOICE_N\"],     0, 0)\n    verify_visibility(c.named_choices[\"BOOL_CHOICE_M\"],     0, 2)\n    verify_visibility(c.named_choices[\"BOOL_CHOICE_Y\"],     2, 2)\n    verify_visibility(c.named_choices[\"TRISTATE_CHOICE_N\"], 0, 0)\n    verify_visibility(c.named_choices[\"TRISTATE_CHOICE_M\"], 0, 1)\n    verify_visibility(c.named_choices[\"TRISTATE_CHOICE_Y\"], 2, 2)\n\n    verify_visibility(c.named_choices[\"TRISTATE_CHOICE_IF_M_AND_Y\"],   0, 1)\n    verify_visibility(c.named_choices[\"TRISTATE_CHOICE_MENU_N_AND_Y\"], 0, 0)\n\n    # Verify that 'visible if' visibility gets propagated to prompts\n\n    verify_visibility(c.syms[\"VISIBLE_IF_N\"], 0, 0)\n    verify_visibility(c.syms[\"VISIBLE_IF_M\"], 0, 1)\n    verify_visibility(c.syms[\"VISIBLE_IF_Y\"], 2, 2)\n    verify_visibility(c.syms[\"VISIBLE_IF_M_2\"], 0, 1)\n\n    # Verify that string/int/hex symbols with m visibility accept a user value\n\n    assign_and_verify(\"STRING_m\", \"foo bar\")\n    assign_and_verify(\"INT_m\", \"123\")\n    assign_and_verify(\"HEX_m\", \"0x123\")\n\n\n    print(\"Testing .assignable\")\n\n    c = Kconfig(\"Kconfiglib/tests/Kassignable\")\n\n    def verify_assignable_imp(item, assignable_no_modules, assignable_modules):\n        # Verifies the assignable values for 'item', with and without modules.\n\n        for modules_val, assignable in (0, assignable_no_modules), \\\n                                       (2, assignable_modules):\n\n            c.modules.set_value(modules_val)\n            module_msg = \"without modules\" if modules_val == 0 else \\\n                         \"with modules\"\n\n            verify(item.assignable == assignable,\n                   \"Incorrect assignable values for {} {}. Should be {}, \"\n                   \"was {}.\"\n                   .format(item.name, module_msg, assignable, item.assignable))\n\n            # Verify that the values can actually be assigned too\n\n            for val in item.assignable:\n                item.set_value(val)\n                verify(item.tri_value == val,\n                       \"Unable to set {} to {} {}, even though it was in \"\n                       \".assignable\".format(item.name, val, module_msg))\n\n    def verify_assignable(sym_name, assignable_no_modules, assignable_modules):\n        verify_assignable_imp(c.syms[sym_name],\n                              assignable_no_modules,\n                              assignable_modules)\n\n    def verify_const_unassignable(sym_name):\n        verify_assignable_imp(c.const_syms[sym_name], (), ())\n\n    # Things that shouldn't be .assignable\n    verify_const_unassignable(\"n\")\n    verify_const_unassignable(\"m\")\n    verify_const_unassignable(\"y\")\n    verify_const_unassignable(\"const\")\n    verify_assignable(\"UNDEFINED\", (), ())\n    verify_assignable(\"NO_PROMPT\", (), ())\n    verify_assignable(\"STRING\", (), ())\n    verify_assignable(\"INT\", (), ())\n    verify_assignable(\"HEX\", (), ())\n\n    # Non-selected symbols\n    verify_assignable(\"Y_VIS_BOOL\", (0, 2), (0,    2))\n    verify_assignable(\"M_VIS_BOOL\", (    ), (0,    2))  # Vis. promoted\n    verify_assignable(\"N_VIS_BOOL\", (    ), (       ))\n    verify_assignable(\"Y_VIS_TRI\",  (0, 2), (0, 1, 2))\n    verify_assignable(\"M_VIS_TRI\",  (    ), (0, 1   ))\n    verify_assignable(\"N_VIS_TRI\",  (    ), (       ))\n\n    # Symbols selected to y\n    verify_assignable(\"Y_SEL_Y_VIS_BOOL\", (2,), (2,))\n    verify_assignable(\"Y_SEL_M_VIS_BOOL\", (  ), (2,))  # Vis. promoted\n    verify_assignable(\"Y_SEL_N_VIS_BOOL\", (  ), (  ))\n    verify_assignable(\"Y_SEL_Y_VIS_TRI\",  (2,), (2,))\n    verify_assignable(\"Y_SEL_M_VIS_TRI\",  (  ), (2,))\n    verify_assignable(\"Y_SEL_N_VIS_TRI\",  (  ), (  ))\n\n    # Symbols selected to m\n    verify_assignable(\"M_SEL_Y_VIS_BOOL\", (2,), (   2,))  # Value promoted\n    verify_assignable(\"M_SEL_M_VIS_BOOL\", (  ), (   2,))  # Vis./value promoted\n    verify_assignable(\"M_SEL_N_VIS_BOOL\", (  ), (     ))\n    verify_assignable(\"M_SEL_Y_VIS_TRI\",  (2,), (1, 2 ))\n    verify_assignable(\"M_SEL_M_VIS_TRI\",  (  ), (1,   ))\n    verify_assignable(\"M_SEL_N_VIS_TRI\",  (  ), (     ))\n\n    # Symbols implied to y\n    verify_assignable(\"Y_IMP_Y_VIS_BOOL\", (0, 2), (0, 2))\n    verify_assignable(\"Y_IMP_M_VIS_BOOL\", (    ), (0, 2))  # Vis. promoted\n    verify_assignable(\"Y_IMP_N_VIS_BOOL\", (    ), (    ))\n    verify_assignable(\"Y_IMP_Y_VIS_TRI\",  (0, 2), (0, 2))  # m removed by imply\n    verify_assignable(\"Y_IMP_M_VIS_TRI\",  (    ), (0, 2))  # m promoted to y by imply\n    verify_assignable(\"Y_IMP_N_VIS_TRI\",  (    ), (    ))\n\n    # Symbols implied to m (never affects assignable values)\n    verify_assignable(\"M_IMP_Y_VIS_BOOL\", (0, 2), (0,    2))\n    verify_assignable(\"M_IMP_M_VIS_BOOL\", (    ), (0,    2))  # Vis. promoted\n    verify_assignable(\"M_IMP_N_VIS_BOOL\", (    ), (       ))\n    verify_assignable(\"M_IMP_Y_VIS_TRI\",  (0, 2), (0, 1, 2))\n    verify_assignable(\"M_IMP_M_VIS_TRI\",  (    ), (0, 1   ))\n    verify_assignable(\"M_IMP_N_VIS_TRI\",  (    ), (       ))\n\n    # Symbols in y-mode choice\n    verify_assignable(\"Y_CHOICE_BOOL\",           (2,), (2,))\n    verify_assignable(\"Y_CHOICE_TRISTATE\",       (2,), (2,))\n    verify_assignable(\"Y_CHOICE_N_VIS_TRISTATE\", (  ), (  ))\n\n    # Symbols in m/y-mode choice, starting out in m mode, or y mode when\n    # running without modules\n    verify_assignable(\"MY_CHOICE_BOOL\",           (2,), (    ))\n    verify_assignable(\"MY_CHOICE_TRISTATE\",       (2,), (0, 1))\n    verify_assignable(\"MY_CHOICE_N_VIS_TRISTATE\", (  ), (    ))\n\n    c.named_choices[\"MY_CHOICE\"].set_value(2)\n\n    # Symbols in m/y-mode choice, now in y mode\n    verify_assignable(\"MY_CHOICE_BOOL\",           (2,), (2,))\n    verify_assignable(\"MY_CHOICE_TRISTATE\",       (2,), (2,))\n    verify_assignable(\"MY_CHOICE_N_VIS_TRISTATE\", (  ), (  ))\n\n    def verify_choice_assignable(choice_name, assignable_no_modules,\n                                 assignable_modules):\n        verify_assignable_imp(c.named_choices[choice_name],\n                              assignable_no_modules,\n                              assignable_modules)\n\n    # Choices with various possible modes\n    verify_choice_assignable(\"Y_CHOICE\",   (2,  ), (      2,))\n    verify_choice_assignable(\"MY_CHOICE\",  (2,  ), (   1, 2 ))\n    verify_choice_assignable(\"NMY_CHOICE\", (0, 2), (0, 1, 2 ))\n    verify_choice_assignable(\"NY_CHOICE\",  (0, 2), (0,    2 ))\n    verify_choice_assignable(\"NM_CHOICE\",  (    ), (0, 1    ))\n    verify_choice_assignable(\"M_CHOICE\",   (    ), (   1,   ))\n    verify_choice_assignable(\"N_CHOICE\",   (    ), (        ))\n\n\n    print(\"Testing object relations\")\n\n    c = Kconfig(\"Kconfiglib/tests/Krelation\")\n\n    verify(c.syms[\"A\"].nodes[0].parent is c.top_node,\n           \"A's parent should be the top node\")\n\n    verify(c.syms[\"B\"].nodes[0].parent.item is c.named_choices[\"CHOICE_1\"],\n           \"B's parent should be the first choice\")\n\n    verify(c.syms[\"C\"].nodes[0].parent.item is c.syms[\"B\"],\n           \"C's parent should be B (due to auto menus)\")\n\n    verify(c.syms[\"E\"].nodes[0].parent.item == MENU,\n           \"E's parent should be a menu\")\n\n    verify(c.syms[\"E\"].nodes[0].parent.parent is c.top_node,\n           \"E's grandparent should be the top node\")\n\n    verify(c.syms[\"G\"].nodes[0].parent.item is c.named_choices[\"CHOICE_2\"],\n           \"G's parent should be the second choice\")\n\n    verify(c.syms[\"G\"].nodes[0].parent.parent.item == MENU,\n           \"G's grandparent should be a menu\")\n\n\n    print(\"Testing hex/int ranges\")\n\n    c = Kconfig(\"Kconfiglib/tests/Krange\", warn=False)\n\n    for sym_name in \"HEX_NO_RANGE\", \"INT_NO_RANGE\", \"HEX_40\", \"INT_40\":\n        sym = c.syms[sym_name]\n        verify(not sym.ranges,\n               \"{} should not have ranges\".format(sym_name))\n\n    for sym_name in \"HEX_ALL_RANGES_DISABLED\", \"INT_ALL_RANGES_DISABLED\", \\\n                    \"HEX_RANGE_10_20_LOW_DEFAULT\", \\\n                    \"INT_RANGE_10_20_LOW_DEFAULT\":\n        sym = c.syms[sym_name]\n        verify(sym.ranges, \"{} should have ranges\".format(sym_name))\n\n    # hex/int symbols without defaults should get no default value\n    verify_value(\"HEX_NO_RANGE\", \"\")\n    verify_value(\"INT_NO_RANGE\", \"\")\n    # And neither if all ranges are disabled\n    verify_value(\"HEX_ALL_RANGES_DISABLED\", \"\")\n    verify_value(\"INT_ALL_RANGES_DISABLED\", \"\")\n    # Make sure they are assignable though, and test that the form of the user\n    # value is reflected in the value for hex symbols\n    assign_and_verify(\"HEX_NO_RANGE\", \"0x123\")\n    assign_and_verify(\"HEX_NO_RANGE\", \"123\")\n    assign_and_verify(\"INT_NO_RANGE\", \"123\")\n\n    # Defaults outside of the valid range should be clamped\n    verify_value(\"HEX_RANGE_10_20_LOW_DEFAULT\", \"0x10\")\n    verify_value(\"HEX_RANGE_10_20_HIGH_DEFAULT\", \"0x20\")\n    verify_value(\"INT_RANGE_10_20_LOW_DEFAULT\", \"10\")\n    verify_value(\"INT_RANGE_10_20_HIGH_DEFAULT\", \"20\")\n    # Defaults inside the valid range should be preserved. For hex symbols,\n    # they should additionally use the same form as in the assignment.\n    verify_value(\"HEX_RANGE_10_20_OK_DEFAULT\", \"0x15\")\n    verify_value(\"HEX_RANGE_10_20_OK_DEFAULT_ALTERNATE\", \"15\")\n    verify_value(\"INT_RANGE_10_20_OK_DEFAULT\", \"15\")\n\n    # hex/int symbols with no defaults but valid ranges should default to the\n    # lower end of the range if it's > 0\n    verify_value(\"HEX_RANGE_10_20\", \"0x10\")\n    verify_value(\"HEX_RANGE_0_10\", \"\")\n    verify_value(\"INT_RANGE_10_20\", \"10\")\n    verify_value(\"INT_RANGE_0_10\", \"\")\n    verify_value(\"INT_RANGE_NEG_10_10\", \"\")\n\n    # User values and dependent ranges\n\n    # Avoid warnings for assigning values outside the active range\n    c.warn = False\n\n    def verify_range(sym_name, low, high, default):\n        # Verifies that all values in the range 'low'-'high' can be assigned,\n        # and that assigning values outside the range reverts the value back to\n        # 'default' (None if it should revert back to \"\").\n\n        is_hex = (c.syms[sym_name].type == HEX)\n\n        for i in range(low, high + 1):\n            assign_and_verify_user_value(sym_name, str(i), str(i), True)\n            if is_hex:\n                # The form of the user value should be preserved for hex\n                # symbols\n                assign_and_verify_user_value(sym_name, hex(i), hex(i), True)\n\n        # Verify that assigning a user value just outside the range causes\n        # defaults to be used\n\n        if default is None:\n            default_str = \"\"\n        else:\n            default_str = hex(default) if is_hex else str(default)\n\n        if is_hex:\n            too_low_str = hex(low - 1)\n            too_high_str = hex(high + 1)\n        else:\n            too_low_str = str(low - 1)\n            too_high_str = str(high + 1)\n\n        assign_and_verify_value(sym_name, too_low_str, default_str)\n        assign_and_verify_value(sym_name, too_high_str, default_str)\n\n    verify_range(\"HEX_RANGE_10_20_LOW_DEFAULT\",  0x10, 0x20,  0x10)\n    verify_range(\"HEX_RANGE_10_20_HIGH_DEFAULT\", 0x10, 0x20,  0x20)\n    verify_range(\"HEX_RANGE_10_20_OK_DEFAULT\",   0x10, 0x20,  0x15)\n\n    verify_range(\"INT_RANGE_10_20_LOW_DEFAULT\",  10,   20,    10)\n    verify_range(\"INT_RANGE_10_20_HIGH_DEFAULT\", 10,   20,    20)\n    verify_range(\"INT_RANGE_10_20_OK_DEFAULT\",   10,   20,    15)\n\n    verify_range(\"HEX_RANGE_10_20\",              0x10, 0x20,  0x10)\n\n    verify_range(\"INT_RANGE_10_20\",              10,  20,     10)\n    verify_range(\"INT_RANGE_0_10\",               0,   10,     None)\n    verify_range(\"INT_RANGE_NEG_10_10\",          -10, 10,     None)\n\n    # Dependent ranges\n\n    verify_value(\"HEX_40\", \"40\")\n    verify_value(\"INT_40\", \"40\")\n\n    c.syms[\"HEX_RANGE_10_20\"].unset_value()\n    c.syms[\"INT_RANGE_10_20\"].unset_value()\n    verify_value(\"HEX_RANGE_10_40_DEPENDENT\", \"0x10\")\n    verify_value(\"INT_RANGE_10_40_DEPENDENT\", \"10\")\n    c.syms[\"HEX_RANGE_10_20\"].set_value(\"15\")\n    c.syms[\"INT_RANGE_10_20\"].set_value(\"15\")\n    verify_value(\"HEX_RANGE_10_40_DEPENDENT\", \"0x15\")\n    verify_value(\"INT_RANGE_10_40_DEPENDENT\", \"15\")\n    c.unset_values()\n    verify_range(\"HEX_RANGE_10_40_DEPENDENT\", 0x10, 0x40,  0x10)\n    verify_range(\"INT_RANGE_10_40_DEPENDENT\", 10,   40,    10)\n\n    # Ranges and symbols defined in multiple locations\n\n    verify_value(\"INACTIVE_RANGE\", \"2\")\n    verify_value(\"ACTIVE_RANGE\", \"1\")\n\n\n    print(\"Testing defconfig_filename\")\n\n    c = Kconfig(\"Kconfiglib/tests/empty\")\n    verify(c.defconfig_filename is None,\n           \"defconfig_filename should be None with no defconfig_list symbol\")\n\n    c = Kconfig(\"Kconfiglib/tests/Kdefconfig_nonexistent\")\n    verify(c.defconfig_filename is None,\n           \"defconfig_filename should be None when none of the files in the \"\n           \"defconfig_list symbol exist\")\n\n    # Referenced in Kdefconfig_existent(_but_n)\n    os.environ[\"FOO\"] = \"defconfig_2\"\n\n    c = Kconfig(\"Kconfiglib/tests/Kdefconfig_existent_but_n\")\n    verify(c.defconfig_filename is None,\n           \"defconfig_filename should be None when the condition is n for all \"\n           \"the defaults\")\n\n    c = Kconfig(\"Kconfiglib/tests/Kdefconfig_existent\")\n    verify(c.defconfig_filename == \"Kconfiglib/tests/defconfig_2\",\n           \"defconfig_filename should return the existing file \"\n           \"Kconfiglib/tests/defconfig_2\")\n\n    # Should also look relative to $srctree if the specified defconfig is a\n    # relative path and can't be opened\n\n    c = Kconfig(\"Kconfiglib/tests/Kdefconfig_srctree\")\n    verify(c.defconfig_filename == \"Kconfiglib/tests/defconfig_2\",\n           \"defconfig_filename gave wrong file with $srctree unset\")\n\n    os.environ[\"srctree\"] = \"Kconfiglib/tests\"\n    c = Kconfig(\"Kdefconfig_srctree\")\n    verify(c.defconfig_filename == \"Kconfiglib/tests/sub/defconfig_in_sub\",\n           \"defconfig_filename gave wrong file with $srctree set\")\n\n    os.environ.pop(\"srctree\", None)\n\n\n    print(\"Testing mainmenu_text\")\n\n    c = Kconfig(\"Kconfiglib/tests/empty\")\n    verify(c.mainmenu_text == \"Main menu\",\n           \"An empty Kconfig should get a default main menu prompt\")\n\n    # Expanded in the mainmenu text\n    os.environ[\"FOO\"] = \"bar baz\"\n    c = Kconfig(\"Kconfiglib/tests/Kmainmenu\")\n    verify(c.mainmenu_text == \"---bar baz---\",\n           \"Wrong mainmenu text\")\n\n\n    print(\"Testing user_value\")\n\n    # References undefined env. var. Disable warnings.\n    c = Kconfig(\"Kconfiglib/tests/Kmisc\", warn=False)\n\n    # Avoid warnings from assigning invalid user values and assigning user\n    # values to symbols without prompts\n    c.warn = False\n\n    syms = [c.syms[name] for name in\n            (\"BOOL\", \"TRISTATE\", \"STRING\", \"INT\", \"HEX\")]\n\n    for sym in syms:\n        verify(sym.user_value is None,\n               \"{} should not have a user value to begin with\")\n\n    # Assign valid values for the types\n\n    assign_and_verify_user_value(\"BOOL\", 0, 0, True)\n    assign_and_verify_user_value(\"BOOL\", 2, 2, True)\n    assign_and_verify_user_value(\"TRISTATE\", 0, 0, True)\n    assign_and_verify_user_value(\"TRISTATE\", 1, 1, True)\n    assign_and_verify_user_value(\"TRISTATE\", 2, 2, True)\n    assign_and_verify_user_value(\"STRING\", \"foo bar\", \"foo bar\", True)\n    assign_and_verify_user_value(\"INT\", \"123\", \"123\", True)\n    assign_and_verify_user_value(\"HEX\", \"0x123\", \"0x123\", True)\n\n    # Assign invalid values for the types. They should retain their old user\n    # value.\n\n    assign_and_verify_user_value(\"BOOL\", 1, 2, False)\n    assign_and_verify_user_value(\"BOOL\", \"foo\", 2, False)\n    assign_and_verify_user_value(\"BOOL\", \"1\", 2, False)\n    assign_and_verify_user_value(\"TRISTATE\", \"foo\", 2, False)\n    assign_and_verify_user_value(\"TRISTATE\", \"1\", 2, False)\n    assign_and_verify_user_value(\"STRING\", 0, \"foo bar\", False)\n    assign_and_verify_user_value(\"INT\", \"foo\", \"123\", False)\n    assign_and_verify_user_value(\"INT\", 0, \"123\", False)\n    assign_and_verify_user_value(\"HEX\", \"foo\", \"0x123\", False)\n    assign_and_verify_user_value(\"HEX\", 0, \"0x123\", False)\n    assign_and_verify_user_value(\"HEX\", \"-0x1\", \"0x123\", False)\n\n    for s in syms:\n        s.unset_value()\n        verify(s.user_value is None,\n               \"{} should not have a user value after being reset\".\n               format(s.name))\n\n\n    print(\"Testing is_menuconfig\")\n\n    c = Kconfig(\"Kconfiglib/tests/Kmenuconfig\")\n\n    for not_menuconfig in c.syms[\"NOT_MENUCONFIG_1\"].nodes[0], \\\n                          c.syms[\"NOT_MENUCONFIG_2\"].nodes[0], \\\n                          c.syms[\"MENUCONFIG_MULTI_DEF\"].nodes[0], \\\n                          c.syms[\"COMMENT_HOOK\"].nodes[0].next:\n\n        verify(not not_menuconfig.is_menuconfig,\n               \"'{}' should have is_menuconfig False\".format(not_menuconfig))\n\n    for menuconfig in c.top_node, \\\n                      c.syms[\"MENUCONFIG_1\"].nodes[0], \\\n                      c.syms[\"MENUCONFIG_MULTI_DEF\"].nodes[1], \\\n                      c.syms[\"MENU_HOOK\"].nodes[0].next, \\\n                      c.syms[\"CHOICE_HOOK\"].nodes[0].next:\n\n        verify(menuconfig.is_menuconfig,\n               \"'{}' should have is_menuconfig True\".format(menuconfig))\n\n\n    print(\"Testing 'option env' semantics\")\n\n    os.environ[\"ENV_VAR\"] = \"ENV_VAR value\"\n\n    # References undefined env. var., so disable warnings\n    c = Kconfig(\"Kconfiglib/tests/Kmisc\", warn=False)\n\n    # Verify that 'option env' is treated like a default\n    verify_value(\"FROM_ENV\", \"ENV_VAR value\")\n    verify_value(\"FROM_ENV_MISSING\", \"missing\")\n\n    verify_value(\"FROM_ENV_WEIRD\", \"weird\")\n\n\n    print(\"Testing defined vs undefined symbols\")\n\n    for name in \"A\", \"B\", \"C\", \"D\", \"BOOL\", \"TRISTATE\", \"STRING\", \"INT\", \"HEX\":\n        verify(c.syms[name].nodes,\n               \"{} should be defined\".format(name))\n\n    for name in \"NOT_DEFINED_1\", \"NOT_DEFINED_2\", \"NOT_DEFINED_3\", \\\n                \"NOT_DEFINED_4\":\n        sym = c.syms[name]\n        verify(not c.syms[name].nodes,\n               \"{} should not be defined\".format(name))\n\n\n    print(\"Testing Symbol.choice\")\n\n    for name in \"A\", \"B\", \"C\", \"D\":\n        verify(c.syms[name].choice is not None,\n               \"{} should be a choice symbol\".format(name))\n\n    for name in \"Q1\", \"Q2\", \"Q3\", \"BOOL\", \"TRISTATE\", \"STRING\", \"INT\", \"HEX\", \\\n                \"FROM_ENV\", \"FROM_ENV_MISSING\", \"NOT_DEFINED_1\", \\\n                \"NOT_DEFINED_2\", \"NOT_DEFINED_3\", \"NOT_DEFINED_4\":\n        verify(c.syms[name].choice is None,\n               \"{} should not be a choice symbol\".format(name))\n\n\n    print(\"Testing is_allnoconfig_y\")\n\n    verify(not c.syms[\"NOT_ALLNOCONFIG_Y\"].is_allnoconfig_y,\n           \"NOT_ALLNOCONFIG_Y should not be allnoconfig_y\")\n    verify(c.syms[\"ALLNOCONFIG_Y\"].is_allnoconfig_y,\n           \"ALLNOCONFIG_Y should be allnoconfig_y\")\n\n\n    print(\"Testing .config reading and writing\")\n\n    config_test_file = \"Kconfiglib/tests/config_test\"\n\n    def verify_file_contents(fname, contents):\n        with open(fname, \"r\") as f:\n            file_contents = f.read()\n            verify(file_contents == contents,\n                   \"{} contains '{}'. Expected '{}'.\"\n                   .format(fname, file_contents, contents))\n\n    # Writing/reading strings with characters that need to be escaped\n\n    c = Kconfig(\"Kconfiglib/tests/Kescape\")\n\n    # Test the default value\n    c.write_config(config_test_file + \"_from_def\")\n    verify_file_contents(config_test_file + \"_from_def\",\n                         r'''CONFIG_STRING=\"\\\"\\\\\"''' \"\\n\")\n    # Write our own value\n    c.syms[\"STRING\"].set_value(r'''\\\"a'\\\\''')\n    c.write_config(config_test_file + \"_from_user\")\n    verify_file_contents(config_test_file + \"_from_user\",\n                         r'''CONFIG_STRING=\"\\\\\\\"a'\\\\\\\\\"''' \"\\n\")\n\n    # Read back the two configs and verify the respective values\n    c.load_config(config_test_file + \"_from_def\")\n    verify_value(\"STRING\", '\"\\\\')\n    c.load_config(config_test_file + \"_from_user\")\n    verify_value(\"STRING\", r'''\\\"a'\\\\''')\n\n    # Appending values from a .config\n\n    c = Kconfig(\"Kconfiglib/tests/Kappend\")\n\n    # Values before assigning\n    verify_value(\"BOOL\", \"n\")\n    verify_value(\"STRING\", \"\")\n\n    # Assign BOOL\n    c.load_config(\"Kconfiglib/tests/config_set_bool\", replace=False)\n    verify_value(\"BOOL\", \"y\")\n    verify_value(\"STRING\", \"\")\n\n    # Assign STRING\n    c.load_config(\"Kconfiglib/tests/config_set_string\", replace=False)\n    verify_value(\"BOOL\", \"y\")\n    verify_value(\"STRING\", \"foo bar\")\n\n    # Reset BOOL\n    c.load_config(\"Kconfiglib/tests/config_set_string\")\n    verify_value(\"BOOL\", \"n\")\n    verify_value(\"STRING\", \"foo bar\")\n\n    # Loading a completely empty .config should reset values\n    c.load_config(\"Kconfiglib/tests/empty\")\n    verify_value(\"STRING\", \"\")\n\n    # An indented assignment in a .config should be ignored\n    c.load_config(\"Kconfiglib/tests/config_indented\")\n    verify_value(\"IGNOREME\", \"y\")\n\n    # Symbol order in headers and minimal configuration files should match\n    # definition order, like in .config files\n\n    c = Kconfig(\"Kconfiglib/tests/Korder\")\n\n    c.write_autoconf(config_test_file)\n    verify_file_contents(config_test_file, \"\"\"\n#define CONFIG_O 0\n#define CONFIG_R 1\n#define CONFIG_D 2\n#define CONFIG_E 3\n#define CONFIG_R2 4\n#define CONFIG_I 5\n#define CONFIG_N 6\n#define CONFIG_G 7\n\"\"\"[1:])\n\n    # Differs from defaults\n    c.syms[\"O\"].set_value(\"-1\")\n    c.syms[\"R\"].set_value(\"-1\")\n    c.syms[\"E\"].set_value(\"-1\")\n    c.syms[\"R2\"].set_value(\"-1\")\n    c.syms[\"N\"].set_value(\"-1\")\n    c.syms[\"G\"].set_value(\"-1\")\n    c.write_min_config(config_test_file)\n    verify_file_contents(config_test_file, \"\"\"\nCONFIG_O=-1\nCONFIG_R=-1\nCONFIG_E=-1\nCONFIG_R2=-1\nCONFIG_N=-1\nCONFIG_G=-1\n\"\"\"[1:])\n\n    # Test header strings in configuration files and headers\n\n    os.environ[\"KCONFIG_CONFIG_HEADER\"] = \"config header from env.\\n\"\n    os.environ[\"KCONFIG_AUTOHEADER_HEADER\"] = \"header header from env.\\n\"\n\n    c = Kconfig(\"Kconfiglib/tests/Kheader\")\n    c.write_config(config_test_file, header=\"config header from param\\n\")\n    verify_file_contents(config_test_file, \"\"\"\\\nconfig header from param\nCONFIG_FOO=y\n\"\"\")\n    c.write_min_config(config_test_file, header=\"min. config header from param\\n\")\n    verify_file_contents(config_test_file, \"\"\"\\\nmin. config header from param\n\"\"\")\n    c.write_config(config_test_file)\n    verify_file_contents(config_test_file, \"\"\"\\\nconfig header from env.\nCONFIG_FOO=y\n\"\"\")\n    c.write_min_config(config_test_file)\n    verify_file_contents(config_test_file, \"\"\"\\\nconfig header from env.\n\"\"\")\n    c.write_autoconf(config_test_file, header=\"header header from param\\n\")\n    verify_file_contents(config_test_file, \"\"\"\\\nheader header from param\n#define CONFIG_FOO 1\n\"\"\")\n    c.write_autoconf(config_test_file)\n    verify_file_contents(config_test_file, \"\"\"\\\nheader header from env.\n#define CONFIG_FOO 1\n\"\"\")\n\n    del os.environ[\"KCONFIG_CONFIG_HEADER\"]\n    del os.environ[\"KCONFIG_AUTOHEADER_HEADER\"]\n\n\n    print(\"Testing Kconfig fetching and separation\")\n\n    for c in Kconfig(\"Kconfiglib/tests/Kmisc\", warn=False), \\\n             Kconfig(\"Kconfiglib/tests/Kmisc\", warn=False):\n        for item in c.syms[\"BOOL\"], \\\n                    c.syms[\"BOOL\"].nodes[0], \\\n                    c.named_choices[\"OPTIONAL\"], \\\n                    c.named_choices[\"OPTIONAL\"].nodes[0], \\\n                    c.syms[\"MENU_HOOK\"].nodes[0].next, \\\n                    c.syms[\"COMMENT_HOOK\"].nodes[0].next:\n            verify(item.kconfig is c,\n                   \".kconfig not properly set for \" + repr(item))\n\n\n    print(\"Testing imply semantics\")\n\n    c = Kconfig(\"Kconfiglib/tests/Kimply\")\n\n    verify_value(\"IMPLY_DIRECT_DEPS\", \"y\")\n    verify_value(\"UNMET_DIRECT_1\", \"n\")\n    verify_value(\"UNMET_DIRECT_2\", \"n\")\n    verify_value(\"UNMET_DIRECT_3\", \"n\")\n    verify_value(\"MET_DIRECT_1\", \"y\")\n    verify_value(\"MET_DIRECT_2\", \"y\")\n    verify_value(\"MET_DIRECT_3\", \"y\")\n    verify_value(\"MET_DIRECT_4\", \"y\")\n\n    verify_value(\"IMPLY_COND\", \"y\")\n    verify_value(\"IMPLIED_N_COND\", \"n\")\n    verify_value(\"IMPLIED_M_COND\", \"m\")\n    verify_value(\"IMPLIED_Y_COND\", \"y\")\n\n    verify_value(\"IMPLY_N_1\", \"n\")\n    verify_value(\"IMPLY_N_2\", \"n\")\n    verify_value(\"IMPLIED_FROM_N_1\", \"n\")\n    verify_value(\"IMPLIED_FROM_N_2\", \"n\")\n\n    verify_value(\"IMPLY_M\", \"m\")\n    verify_value(\"IMPLIED_M\", \"m\")\n    verify_value(\"IMPLIED_M_BOOL\", \"y\")\n\n    verify_value(\"IMPLY_M_TO_Y\", \"y\")\n    verify_value(\"IMPLIED_M_TO_Y\", \"y\")\n\n    # Test user value semantics\n\n    # Verify that IMPLIED_TRISTATE is invalidated if the direct\n    # dependencies change\n\n    assign_and_verify(\"IMPLY\", 2)\n    assign_and_verify(\"DIRECT_DEP\", 2)\n    verify_value(\"IMPLIED_TRISTATE\", 2)\n    assign_and_verify(\"DIRECT_DEP\", 0)\n    verify_value(\"IMPLIED_TRISTATE\", 0)\n    # Set back for later tests\n    assign_and_verify(\"DIRECT_DEP\", 2)\n\n    # Verify that IMPLIED_TRISTATE can be set to anything when IMPLY has value\n    # n, and that it gets the value n by default (for non-imply-related\n    # reasons)\n\n    assign_and_verify(\"IMPLY\", 0)\n    assign_and_verify(\"IMPLIED_TRISTATE\", 0)\n    assign_and_verify(\"IMPLIED_TRISTATE\", 1)\n    assign_and_verify(\"IMPLIED_TRISTATE\", 2)\n    c.syms[\"IMPLIED_TRISTATE\"].unset_value()\n    verify_value(\"IMPLIED_TRISTATE\", \"n\")\n\n    # Same as above for m. Anything still goes, but m by default now.\n\n    assign_and_verify(\"IMPLY\", 1)\n    assign_and_verify(\"IMPLIED_TRISTATE\", 0)\n    assign_and_verify(\"IMPLIED_TRISTATE\", 1)\n    assign_and_verify(\"IMPLIED_TRISTATE\", 2)\n    c.syms[\"IMPLIED_TRISTATE\"].unset_value()\n    verify_value(\"IMPLIED_TRISTATE\", 1)\n\n    # Same as above for y. Only n and y should be accepted. m gets promoted to\n    # y. Default should be y.\n\n    assign_and_verify(\"IMPLY\", 2)\n    assign_and_verify(\"IMPLIED_TRISTATE\", 0)\n    assign_and_verify_value(\"IMPLIED_TRISTATE\", 1, 2)\n    assign_and_verify(\"IMPLIED_TRISTATE\", 2)\n    c.syms[\"IMPLIED_TRISTATE\"].unset_value()\n    verify_value(\"IMPLIED_TRISTATE\", 2)\n\n    # Being implied to either m or y should give a bool the value y\n\n    c.syms[\"IMPLY\"].unset_value()\n    verify_value(\"IMPLIED_BOOL\", 0)\n    assign_and_verify(\"IMPLY\", 0)\n    verify_value(\"IMPLIED_BOOL\", 0)\n    assign_and_verify(\"IMPLY\", 1)\n    verify_value(\"IMPLIED_BOOL\", 2)\n    assign_and_verify(\"IMPLY\", 2)\n    verify_value(\"IMPLIED_BOOL\", 2)\n\n    # A bool implied to m or y can take the values n and y\n\n    c.syms[\"IMPLY\"].set_value(1)\n    assign_and_verify(\"IMPLIED_BOOL\", 0)\n    assign_and_verify(\"IMPLIED_BOOL\", 2)\n\n    c.syms[\"IMPLY\"].set_value(2)\n    assign_and_verify(\"IMPLIED_BOOL\", 0)\n    assign_and_verify(\"IMPLIED_BOOL\", 2)\n\n\n    print(\"Testing choice semantics\")\n\n    # Would warn for choice value symbols defined without a type, even\n    # though the type is automatically derived. This is probably more\n    # helpful than ignoring those cases, as this feature isn't used\n    # deliberately anywhere from what I've seen.\n    c = Kconfig(\"Kconfiglib/tests/Kchoice\", warn=False)\n\n    for name in \"BOOL\", \"BOOL_OPT\", \"BOOL_M\", \"DEFAULTS\":\n        verify(c.named_choices[name].orig_type == BOOL,\n               \"choice {} should have type bool\".format(name))\n\n    for name in \"TRISTATE\", \"TRISTATE_OPT\", \"TRISTATE_M\":\n        verify(c.named_choices[name].orig_type == TRISTATE,\n               \"choice {} should have type tristate\".format(name))\n\n    def select_and_verify(sym):\n        choice = sym.nodes[0].parent.item\n        choice.set_value(2)\n\n        sym.set_value(2)\n\n        verify(sym.choice.selection is sym,\n               sym.name + \" should be the selected symbol\")\n\n        verify(choice.user_selection is sym,\n               sym.name + \" should be the user selection of the choice\")\n\n        verify(sym.tri_value == 2,\n               sym.name + \" should have value y when selected\")\n\n        verify(sym.user_value == 2,\n               sym.name + \" should have user value y when selected\")\n\n        for sibling in choice.syms:\n            if sibling is not sym:\n                verify(sibling.tri_value == 0,\n                       sibling.name + \" should be n when not selected\")\n\n    def select_and_verify_all(choice_name):\n        choice = c.named_choices[choice_name]\n\n        # Select in forward order\n        for sym in choice.syms:\n            select_and_verify(sym)\n\n        # Select in reverse order\n        for sym in reversed(choice.syms):\n            select_and_verify(sym)\n\n    def verify_mode(choice_name, no_modules_mode, modules_mode):\n        choice = c.named_choices[choice_name]\n\n        c.modules.set_value(0)\n        verify(choice.tri_value == no_modules_mode,\n               'Wrong mode for choice {} with no modules. Expected {}, got {}.'\n               .format(choice.name, no_modules_mode, choice.tri_value))\n\n        c.modules.set_value(2)\n        verify(choice.tri_value == modules_mode,\n               'Wrong mode for choice {} with modules. Expected {}, got {}.'\n               .format(choice.name, modules_mode, choice.tri_value))\n\n    verify_mode(\"BOOL\",         2, 2)\n    verify_mode(\"BOOL_OPT\",     0, 0)\n    verify_mode(\"TRISTATE\",     2, 1)\n    verify_mode(\"TRISTATE_OPT\", 0, 0)\n    verify_mode(\"BOOL_M\",       0, 2)\n    verify_mode(\"TRISTATE_M\",   0, 1)\n\n    # Test defaults\n\n    choice = c.named_choices[\"DEFAULTS\"]\n\n    c.syms[\"TRISTATE_SYM\"].set_value(0)\n    verify(choice.selection is c.syms[\"OPT_4\"],\n           \"Wrong choice default with TRISTATE_SYM = n\")\n\n    c.syms[\"TRISTATE_SYM\"].set_value(2)\n    verify(choice.selection is c.syms[\"OPT_2\"],\n           \"Wrong choice default with TRISTATE_SYM = y\")\n\n    c.syms[\"OPT_1\"].set_value(2)\n    verify(choice.selection is c.syms[\"OPT_1\"],\n           \"User selection should override defaults\")\n\n    verify(c.named_choices[\"DEFAULTS_NOT_VISIBLE\"].selection\n           is c.syms[\"OPT_8\"],\n           \"Non-visible choice symbols should cause the next default to be \"\n           \"considered\")\n\n    # Test y mode selection\n\n    c.modules.set_value(2)\n\n    select_and_verify_all(\"BOOL\")\n    select_and_verify_all(\"BOOL_OPT\")\n    select_and_verify_all(\"TRISTATE\")\n    select_and_verify_all(\"TRISTATE_OPT\")\n    # For BOOL_M, the mode should have been promoted\n    select_and_verify_all(\"BOOL_M\")\n\n    # Test m mode selection\n\n    c.named_choices[\"TRISTATE\"].set_value(1)\n\n    verify(c.named_choices[\"TRISTATE\"].tri_value == 1,\n           \"TRISTATE choice should have mode m after explicit mode assignment\")\n\n    assign_and_verify_value(\"T_1\", 0, 0)\n    assign_and_verify_value(\"T_2\", 0, 0)\n    assign_and_verify_value(\"T_1\", 1, 1)\n    assign_and_verify_value(\"T_2\", 1, 1)\n    assign_and_verify_value(\"T_1\", 2, 1)\n    assign_and_verify_value(\"T_2\", 2, 1)\n\n    # Switching to y mode should cause T_2 to become selected\n    c.named_choices[\"TRISTATE\"].set_value(2)\n    verify_value(\"T_1\", 0)\n    verify_value(\"T_2\", 2)\n\n    # Verify that choices with no explicitly specified type get the type of the\n    # first contained symbol with a type\n\n    verify(c.named_choices[\"NO_TYPE_BOOL\"].orig_type == BOOL,\n           \"Expected first choice without explicit type to have type bool\")\n\n    verify(c.named_choices[\"NO_TYPE_TRISTATE\"].orig_type == TRISTATE,\n           \"Expected second choice without explicit type to have type \"\n           \"tristate\")\n\n    # Verify that symbols without a type in the choice get the type of the\n    # choice\n\n    for name in \"MMT_1\", \"MMT_2\", \"MMT_4\", \"MMT_5\":\n        verify(c.syms[name].orig_type == BOOL,\n               \"Expected {} to get type bool\".format(name))\n\n    verify(c.syms[\"MMT_3\"].orig_type == TRISTATE,\n           \"Expected MMT_3 to have type tristate\")\n\n    # Verify that the default selection can change depending on the\n    # visibility of the choice symbols\n\n    default_with_dep_choice = c.named_choices[\"DEFAULT_WITH_DEP\"]\n\n    verify(default_with_dep_choice.selection is c.syms[\"B\"],\n           \"Wrong choice default with unsatisfied deps on default\")\n\n    c.syms[\"DEP\"].set_value(\"y\")\n\n    verify(default_with_dep_choice.selection is c.syms[\"A\"],\n           \"Wrong choice default with satisfied deps on default\")\n\n    c.syms[\"DEP\"].set_value(\"n\")\n\n    verify(default_with_dep_choice.selection is c.syms[\"B\"],\n           \"Wrong choice default with unsatisfied deps on default (round two)\")\n\n    # Verify that symbols in choices that depend on the preceding symbol aren't\n    # considered choice symbols\n\n    weird_choice = c.named_choices[\"WEIRD_SYMS\"]\n\n    def verify_is_normal_choice_symbol(name):\n        sym = c.syms[name]\n        verify(sym.choice is not None and\n               sym in weird_choice.syms and\n               sym.nodes[0].parent.item is weird_choice,\n               \"{} should be a normal choice symbol\".format(sym.name))\n\n    def verify_is_weird_choice_symbol(name):\n        sym = c.syms[name]\n        verify(sym.choice is None and\n               sym not in weird_choice.syms,\n               \"{} should be a weird (non-)choice symbol\"\n               .format(sym.name))\n\n    verify_is_normal_choice_symbol(\"WS1\")\n    verify_is_weird_choice_symbol(\"WS2\")\n    verify_is_weird_choice_symbol(\"WS3\")\n    verify_is_weird_choice_symbol(\"WS4\")\n    verify_is_weird_choice_symbol(\"WS5\")\n    verify_is_normal_choice_symbol(\"WS6\")\n    verify_is_weird_choice_symbol(\"WS7\")\n    verify_is_weird_choice_symbol(\"WS8\")\n    verify_is_normal_choice_symbol(\"WS9\")\n\n\n    print(\"Testing 'if' node removal\")\n\n    c = Kconfig(\"Kconfiglib/tests/Kifremoval\", warn=False)\n\n    nodes = tuple(c.node_iter())\n    verify_equal(nodes[0].item.name, \"A\")\n    verify_equal(nodes[1].item.name, \"B\")\n    verify_equal(nodes[2].item.name, \"C\")\n    verify_equal(nodes[3].item.name, \"D\")\n    verify_equal(nodes[4].prompt[0], \"E\")\n    verify_equal(nodes[5].prompt[0], \"F\")\n    verify_equal(nodes[6].prompt[0], \"G\")\n    verify_equal(nodes[7].item.name, \"H\")\n    verify_equal(nodes[8].item.name, \"I\")\n    verify_equal(nodes[9].item.name, \"J\")\n    verify(len(nodes) == 10,\n           \"Wrong number of nodes after 'if' removal\")\n\n\n    print(\"Testing multi.def. property copying\")\n\n    c = Kconfig(\"Kconfiglib/tests/Kdepcopy\", warn=False)\n\n    def verify_props(desc, props, prop_names):\n        actual = [prop[0].name for prop in props]\n        expected = prop_names.split()\n\n        verify(actual == expected,\n               \"Wrong {} properties, expected '{}', got '{}'\"\n               .format(desc, expected, actual))\n\n    verify_props(\"default\", c.syms[\"MULTIDEF\"].defaults,\n                 \"A B C D E F G H I J K L M N O P Q R\")\n\n    verify_props(\"select\", c.syms[\"MULTIDEF\"].selects,\n                 \"AA BB CC DD EE FF GG HH II JJ\")\n\n    verify_props(\"imply\", c.syms[\"MULTIDEF\"].selects,\n                 \"AA BB CC DD EE FF GG HH II JJ\")\n\n    verify_props(\"select\", c.syms[\"MULTIDEF_CHOICE\"].selects,\n                 \"A B C\")\n\n    verify_props(\"range\", c.syms[\"MULTIDEF_RANGE\"].ranges,\n                 \"A B C D E F\")\n\n    verify_props(\"default\", c.choices[1].defaults,\n                 \"A B C D E\")\n\n\n    print(\"Testing dependency loop detection\")\n\n    # These are all expected to raise dependency loop errors\n    for i in range(11):\n        filename = \"Kconfiglib/tests/Kdeploop\" + str(i)\n        try:\n            Kconfig(filename)\n        except KconfigError as e:\n            if \"Dependency loop\" not in str(e):\n                fail(\"dependency loop in {} raised wrong KconfigError\"\n                     .format(filename))\n        except:\n            fail(\"dependency loop in {} raised wrong exception\"\n                 .format(filename))\n        else:\n            fail(\"dependency loop in {} not detected\".format(filename))\n\n    # Check the most complicated message completely\n    try:\n        Kconfig(\"Kconfiglib/tests/Kdeploop10\")\n    except KconfigError as e:\n        verify_equal(str(e), \"\"\"\nDependency loop\n===============\n\nA (defined at Kconfiglib/tests/Kdeploop10:1), with definition...\n\nconfig A\n\tbool\n\tdepends on B\n\n...depends on B (defined at Kconfiglib/tests/Kdeploop10:5), with definition...\n\nconfig B\n\tbool\n\tdepends on C = 7\n\n...depends on C (defined at Kconfiglib/tests/Kdeploop10:9), with definition...\n\nconfig C\n\tint\n\trange D 8\n\n...depends on D (defined at Kconfiglib/tests/Kdeploop10:13), with definition...\n\nconfig D\n\tint\n\tdefault 3 if E\n\tdefault 8\n\n...depends on E (defined at Kconfiglib/tests/Kdeploop10:18), with definition...\n\nconfig E\n\tbool\n\n(select-related dependencies: F && G)\n\n...depends on G (defined at Kconfiglib/tests/Kdeploop10:25), with definition...\n\nconfig G\n\tbool\n\tdepends on H\n\n...depends on the choice symbol H (defined at Kconfiglib/tests/Kdeploop10:32), with definition...\n\nconfig H\n\tbool \"H\"\n\tdepends on I && <choice>\n\n...depends on the choice symbol I (defined at Kconfiglib/tests/Kdeploop10:41), with definition...\n\nconfig I\n\tbool \"I\"\n\tdepends on <choice>\n\n...depends on <choice> (defined at Kconfiglib/tests/Kdeploop10:38), with definition...\n\nchoice\n\tbool \"choice\" if J\n\n...depends on J (defined at Kconfiglib/tests/Kdeploop10:46), with definition...\n\nconfig J\n\tbool\n\tdepends on A\n\n...depends again on A (defined at Kconfiglib/tests/Kdeploop10:1)\n\"\"\"[:-1])\n    except:\n        fail(\"Loop detection message check raised wrong exception\")\n    else:\n        fail(\"Loop detection message check did not raise exception\")\n\n\n    print(\"Testing preprocessor\")\n\n    os.environ[\"ENV_1\"] = \"env_1\"\n    os.environ[\"ENV_2\"] = \"env_2\"\n    os.environ[\"ENV_3\"] = \"env_3\"\n    os.environ[\"ENV_4\"] = \"env_4\"\n    os.environ[\"ENV_5\"] = \"n\"\n    os.environ[\"ENV_6\"] = \"Kconfiglib/tests/empty\"\n    os.environ[\"ENV_7\"] = \"env_7\"\n    # We verify warnings manually\n    c = Kconfig(\"Kconfiglib/tests/Kpreprocess\", warn_to_stderr=False)\n\n    def verify_variable(name, unexp_value, exp_value, recursive, *args):\n        var = c.variables[name]\n\n        verify(var.value == unexp_value,\n               \"expected variable '{}' to have the unexpanded value '{}', had \"\n               \"the value '{}'\".format(name, unexp_value, var.value))\n\n        if not args:\n            verify(var.expanded_value == exp_value,\n                   \"expected expanded_value for {} to be '{}', was '{}'\"\n                   .format(name, exp_value, var.expanded_value))\n\n        verify(var.expanded_value_w_args(*args) == exp_value,\n               \"expected expanded_value_w_args() for '{}' to be '{}', was '{}'\"\n               .format(name, exp_value, var.expanded_value_w_args(*args)))\n\n        verify(var.is_recursive == recursive,\n               \"{} was {}, shouldn't be\"\n               .format(name, \"recursive\" if var.is_recursive else \"simple\"))\n\n    verify_variable(\"simple-recursive\", \"foo\", \"foo\", True)\n    verify_variable(\"simple-immediate\", \"bar\", \"bar\", False)\n    verify_variable(\"simple-recursive-2\", \"baz\", \"baz\", True)\n\n    verify_variable(\"whitespaced\", \"foo\", \"foo\", True)\n\n    verify_variable(\"preserve-recursive\", \"foo bar\", \"foo bar\", True)\n    verify_variable(\"preserve-immediate\", \"foo bar\", \"foo bar\", False)\n\n    verify_variable(\"recursive\",\n                    \"$(foo) $(bar) $($(b-char)a$(z-char)) $(indir)\",\n                    \"abc def ghi jkl mno\",\n                    True)\n\n    verify_variable(\"immediate\", \"foofoo\", \"foofoo\", False)\n\n    verify_variable(\"messy-fn-res\",\n                    \"$($(fn-indir)-unused-arg, a  b (,) , c  d )\",\n                    'surround-rev-quote \" c  d \" \" a  b (,) \" surround-rev-quote ',\n                    True)\n\n    verify_variable(\"special-chars-fn-res\",\n                    \"$(fn,$(comma)$(dollar)$(left-paren)foo$(right-paren))\",\n                    '\",$(foo)\"',\n                    True)\n\n    verify_variable(\"quote\", '\"$(1)\" \"$(2)\"', '\"\" \"\"', True)\n    verify_variable(\"quote\", '\"$(1)\" \"$(2)\"', '\"one\" \"\"', True,\n                    \"one\")\n    verify_variable(\"quote\", '\"$(1)\" \"$(2)\"', '\"one\" \"two\"', True,\n                    \"one\", \"two\")\n    verify_variable(\"quote\", '\"$(1)\" \"$(2)\"', '\"one\" \"two\"', True,\n                    \"one\", \"two\", \"three\")\n\n    verify_str(c.syms[\"PRINT_ME\"], r\"\"\"\nconfig PRINT_ME\n\tstring \"env_1\" if (FOO && BAR) || !BAZ || !QAZ\n\tdefault \"\\\"foo\\\"\" if \"foo \\\"bar\\\" baz\" = \"\"\n\"\"\")\n\n    verify_str(c.syms[\"PRINT_ME_TOO\"], r\"\"\"\nconfig PRINT_ME_TOO\n\tbool \"foo\"\n\tdefault FOOBARBAZQAZ if QAZ && QAZFOO && xxx\n\"\"\")\n\n    def verify_repr(name, s):\n        verify_equal(repr(c.variables[name]), s)\n\n    verify_repr(\n        \"simple-immediate\",\n        \"<variable simple-immediate, immediate, value 'bar'>\")\n\n    verify_repr(\n        \"messy-fn-res\",\n        \"<variable messy-fn-res, recursive, value '$($(fn-indir)-unused-arg, a  b (,) , c  d )'>\")\n\n    def verify_recursive(name):\n        try:\n            c.variables[name].expanded_value\n        except KconfigError:\n            pass\n        else:\n            fail(\"Expected '{}' expansion to flag recursive expansion, didn't\"\n                 .format(name))\n\n    verify_recursive(\"rec-1\")\n    # Indirectly verifies that it's not recursive\n    verify_variable(\"safe-fn-rec-res\",\n                    \"$(safe-fn-rec,safe-fn-rec-2)\",\n                    \"foo\",\n                    True)\n    verify_recursive(\"unsafe-fn-rec\")\n\n    verify_variable(\"foo-bar-baz\", \"$(rhs)\", \"value\", True)\n\n    verify_variable(\"space-var-res\", \"$(foo bar)\", \"value\", True)\n\n    verify_variable(\"shell-res\",\n                    \"$(shell,false && echo foo bar || echo baz qaz)\",\n                    \"baz qaz\",\n                    True)\n\n    verify_variable(\"shell-stderr-res\", \"\", \"\", False)\n\n    verify_variable(\"parens-res\",\n                    \"pre-$(shell,echo '(a,$(b-char),(c,d),e)')-post\",\n                    \"pre-(a,b,(c,d),e)-post\",\n                    True)\n\n    verify_variable(\"location-res\",\n                    \"Kconfiglib/tests/Kpreprocess:129\",\n                    \"Kconfiglib/tests/Kpreprocess:129\",\n                    False)\n\n    verify_variable(\"warning-res\", \"\", \"\", False)\n    verify_variable(\"error-n-res\", \"\", \"\", False)\n\n    try:\n        c.variables[\"error-y-res\"].expanded_value\n    except KconfigError:\n        pass\n    else:\n        fail(\"expanding error-y-res didn't raise an exception\")\n\n    # Check Kconfig.env_vars\n    verify_equal(c.env_vars,\n                 set((\"ENV_1\", \"ENV_2\", \"ENV_3\", \"ENV_4\", \"ENV_5\", \"ENV_6\")))\n\n    # Check that the expected warnings were generated\n    verify_equal(c.warnings, [\n        \"Kconfiglib/tests/Kpreprocess:122: warning: 'echo message on stderr >&2' wrote to stderr: message on stderr\",\n        \"Kconfiglib/tests/Kpreprocess:134: warning: a warning\"\n    ])\n\n\n    print(\"Testing user-defined preprocessor functions\")\n\n    # Make Kconfiglib/tests/kconfigfunctions.py importable\n    sys.path.insert(0, \"Kconfiglib/tests\")\n\n    c = Kconfig(\"Kconfiglib/tests/Kuserfunctions\")\n\n    verify_variable(\"add-zero\",  \"$(add)\",          \"0\", True)\n    verify_variable(\"add-one\",   \"$(add,1)\",        \"1\", True)\n    verify_variable(\"add-three\", \"$(add,1,-1,2,1)\", \"3\", True)\n\n    verify_variable(\"one-one\", \"$(one,foo bar)\", \"onefoo barfoo bar\", True)\n\n    verify_variable(\"one-or-more-one\", \"$(one-or-more,foo)\", \"foo + \", True)\n    verify_variable(\"one-or-more-three\", \"$(one-or-more,foo,bar,baz)\",\n                    \"foo + bar,baz\", True)\n\n    verify_variable(\"location-1\", \"Kconfiglib/tests/Kuserfunctions:13\",\n                    \"Kconfiglib/tests/Kuserfunctions:13\", False)\n    verify_variable(\"location-2\", \"Kconfiglib/tests/Kuserfunctions:14\",\n                    \"Kconfiglib/tests/Kuserfunctions:14\", False)\n\n    def verify_bad_argno(name):\n        try:\n            c.variables[name].expanded_value\n        except KconfigError:\n            pass\n        else:\n            fail(\"Expected '{}' expansion to flag wrong number of arguments, \"\n                 \"didn't\".format(name))\n\n    verify_bad_argno(\"one-zero\")\n    verify_bad_argno(\"one-two\")\n    verify_bad_argno(\"one-or-more-zero\")\n\n    sys.path.pop(0)\n\n    # This test can fail on older Python 3.x versions, because they don't\n    # preserve dict insertion order during iteration. The output is still\n    # correct, just different.\n    if not (3, 0) <= sys.version_info <= (3, 5):\n        print(\"Testing KCONFIG_WARN_UNDEF\")\n\n        os.environ[\"KCONFIG_WARN_UNDEF\"] = \"y\"\n        c = Kconfig(\"Kconfiglib/tests/Kundef\", warn_to_stderr=False)\n\n        verify_equal(\"\\n\".join(c.warnings), \"\"\"\nwarning: the int symbol INT (defined at Kconfiglib/tests/Kundef:8) has a non-int range [UNDEF_2 (undefined), 8 (undefined)]\nwarning: undefined symbol UNDEF_1:\n\n- Referenced at Kconfiglib/tests/Kundef:4:\n\nconfig BOOL\n\tbool \"foo\" if DEF || !UNDEF_1\n\tdefault UNDEF_2\n\n- Referenced at Kconfiglib/tests/Kundef:19:\n\nmenu \"menu\"\n\tdepends on UNDEF_1\n\tvisible if UNDEF_3\nwarning: undefined symbol UNDEF_2:\n\n- Referenced at Kconfiglib/tests/Kundef:4:\n\nconfig BOOL\n\tbool \"foo\" if DEF || !UNDEF_1\n\tdefault UNDEF_2\n\n- Referenced at Kconfiglib/tests/Kundef:8:\n\nconfig INT\n\tint\n\trange UNDEF_2 8\n\trange 5 15\n\tdefault 10\nwarning: undefined symbol UNDEF_3:\n\n- Referenced at Kconfiglib/tests/Kundef:19:\n\nmenu \"menu\"\n\tdepends on UNDEF_1\n\tvisible if UNDEF_3\n\"\"\"[1:-1])\n\n        os.environ.pop(\"KCONFIG_WARN_UNDEF\")\n\n\n    print(\"\\nAll selftests passed\\n\" if all_passed else\n          \"\\nSome selftests failed\\n\")\n\n\ndef run_compatibility_tests():\n    # Runs tests on configurations from the kernel. Tests compability with the\n    # C implementation by comparing outputs.\n\n    # Referenced inside the kernel Kconfig files.\n    #\n    # The str() makes the type of the value 'str' on both Python 2 and Python 3,\n    # which is nice for some later dictionary key sanity checks.\n\n    os.environ[\"KERNELVERSION\"] = str(\n        subprocess.check_output(\"make kernelversion\", shell=True)\n            .decode(\"utf-8\").rstrip()\n    )\n\n    os.environ[\"CC_VERSION_TEXT\"] = str(\n        subprocess.check_output(\"gcc --version | head -n1\", shell=True)\n            .decode(\"utf-8\").rstrip()\n    )\n\n    os.environ[\"srctree\"] = \".\"\n    os.environ[\"CC\"] = \"gcc\"\n    os.environ[\"LD\"] = \"ld\"\n\n\n    if not os.path.exists(\"scripts/kconfig/conf\"):\n        print(\"\\nscripts/kconfig/conf does not exist -- running \"\n              \"'make allnoconfig' to build it...\")\n        shell(\"make allnoconfig\")\n\n\n    print(\"Running compatibility tests...\\n\")\n\n    test_fns = (test_defconfig,\n                # Fails for a few defconfigs due to a bug in the C tools. Will\n                # be enabled once patches get in.\n                #test_min_config,\n                test_alldefconfig,\n                test_allnoconfig,\n                test_allnoconfig_walk,\n                test_allmodconfig,\n                test_allyesconfig,\n                test_sanity)\n\n    for test_fn in test_fns:\n        # The test description is taken from the docstring of the corresponding\n        # function\n        print(textwrap.dedent(test_fn.__doc__))\n\n        for arch, srcarch in all_arch_srcarch():\n            # Referenced inside the Kconfig files\n            os.environ[\"ARCH\"] = arch\n            os.environ[\"SRCARCH\"] = srcarch\n\n            rm_configs()\n\n            test_fn(arch, srcarch)\n\n    if all_passed:\n        print(\"All selftests and compatibility tests passed\")\n    else:\n        sys.exit(\"Some tests failed\")\n\n\ndef all_arch_srcarch():\n    for srcarch in os.listdir(\"arch\"):\n        # arc and h8300 are currently broken with the C tools on linux-next as\n        # well. Perhaps they require cross-compilers to be installed.\n        #\n        # User-mode Linux has an unorthodox Kconfig setup that would require a\n        # different testing setup. Skip it too.\n        if srcarch in (\"arc\", \"h8300\", \"um\"):\n            continue\n\n        if os.path.exists(os.path.join(\"arch\", srcarch, \"Kconfig\")):\n            yield (srcarch, srcarch)\n\n    # Some arches define additional ARCH settings with ARCH != SRCARCH\n    # (search for \"Additional ARCH settings for\" in the top-level Makefile)\n\n    yield (\"i386\", \"x86\")\n    yield (\"x86_64\", \"x86\")\n\n    yield (\"sparc32\", \"sparc\")\n    yield (\"sparc64\", \"sparc\")\n\n    yield (\"sh64\", \"sh\")\n\n\ndef test_allnoconfig(arch, srcarch):\n    \"\"\"\n    Verify that allnoconfig.py generates the same .config as\n    'make allnoconfig', for each architecture. Runs the script via\n    'make scriptconfig'.\n    \"\"\"\n    shell(\"make scriptconfig SCRIPT=Kconfiglib/allnoconfig.py \"\n          \"PYTHONCMD='{}'\".format(sys.executable))\n    shell(\"mv .config ._config\")\n    shell(\"scripts/kconfig/conf --allnoconfig Kconfig\")\n\n    compare_configs(arch)\n\n\ndef test_allnoconfig_walk(arch, srcarch):\n    \"\"\"\n    Verify that examples/allnoconfig_walk.py generates the same .config as\n    'make allnoconfig', for each architecture. Runs the script via\n    'make scriptconfig'.\n    \"\"\"\n    shell(\"make scriptconfig SCRIPT=Kconfiglib/examples/allnoconfig_walk.py \"\n          \"PYTHONCMD='{}'\".format(sys.executable))\n    shell(\"mv .config ._config\")\n    shell(\"scripts/kconfig/conf --allnoconfig Kconfig\")\n\n    compare_configs(arch)\n\n\ndef test_allmodconfig(arch, srcarch):\n    \"\"\"\n    Verify that allmodconfig.py generates the same .config as\n    'make allmodconfig', for each architecture. Runs the script via\n    'make scriptconfig'.\n    \"\"\"\n    shell(\"make scriptconfig SCRIPT=Kconfiglib/allmodconfig.py \"\n          \"PYTHONCMD='{}'\".format(sys.executable))\n    shell(\"mv .config ._config\")\n    shell(\"scripts/kconfig/conf --allmodconfig Kconfig\")\n\n    compare_configs(arch)\n\n\ndef test_allyesconfig(arch, srcarch):\n    \"\"\"\n    Verify that allyesconfig.py generates the same .config as\n    'make allyesconfig', for each architecture. Runs the script via\n    'make scriptconfig'.\n    \"\"\"\n    shell(\"make scriptconfig SCRIPT=Kconfiglib/allyesconfig.py \"\n          \"PYTHONCMD='{}'\".format(sys.executable))\n    shell(\"mv .config ._config\")\n    shell(\"scripts/kconfig/conf --allyesconfig Kconfig\")\n\n    compare_configs(arch)\n\n\ndef test_sanity(arch, srcarch):\n    \"\"\"\n    Do sanity checks on each configuration and call all public methods on all\n    symbols, choices, and menu nodes for all architectures to make sure we\n    never crash or hang.\n    \"\"\"\n    print(\"For {}...\".format(arch))\n\n    kconf = Kconfig()\n\n    for sym in kconf.defined_syms:\n        verify(sym._visited == 2,\n               \"{} has broken dependency loop detection (_visited = {})\"\n               .format(sym.name, sym._visited))\n\n    kconf.modules\n    kconf.defconfig_list\n    kconf.defconfig_filename\n\n    # Legacy warning functions\n    kconf.enable_redun_warnings()\n    kconf.disable_redun_warnings()\n    kconf.enable_undef_warnings()\n    kconf.disable_undef_warnings()\n    kconf.enable_warnings()\n    kconf.disable_warnings()\n    kconf.enable_stderr_warnings()\n    kconf.disable_stderr_warnings()\n\n    kconf.mainmenu_text\n    kconf.unset_values()\n\n    kconf.write_autoconf(\"/dev/null\")\n\n    # No tempfile.TemporaryDirectory in Python 2\n    tmpdir = tempfile.mkdtemp()\n    kconf.sync_deps(os.path.join(tmpdir, \"deps\"))  # Create\n    kconf.sync_deps(os.path.join(tmpdir, \"deps\"))  # Update\n    shutil.rmtree(tmpdir)\n\n    # Python 2/3 compatible\n    for key, sym in kconf.syms.items():\n        verify(isinstance(key, str), \"weird key '{}' in syms dict\".format(key))\n\n        verify(not sym.is_constant, sym.name + \" in 'syms' and constant\")\n\n        verify(sym not in kconf.const_syms,\n               sym.name + \" in both 'syms' and 'const_syms'\")\n\n        for dep in sym._dependents:\n            verify(not dep.is_constant,\n                   \"the constant symbol {} depends on {}\"\n                   .format(dep.name, sym.name))\n\n        sym.__repr__()\n        sym.__str__()\n        sym.assignable\n        kconf.disable_warnings()\n        sym.set_value(2)\n        sym.set_value(\"foo\")\n        sym.unset_value()\n        kconf.enable_warnings()  # Legacy warning function\n        sym.str_value\n        sym.tri_value\n        sym.type\n        sym.user_value\n        sym.visibility\n\n    for sym in kconf.defined_syms:\n        verify(sym.nodes, sym.name + \" is defined but lacks menu nodes\")\n\n        verify(not (sym.orig_type not in (BOOL, TRISTATE) and sym.choice),\n               sym.name + \" is a choice symbol but not bool/tristate\")\n\n    for key, sym in kconf.const_syms.items():\n        verify(isinstance(key, str),\n               \"weird key '{}' in const_syms dict\".format(key))\n\n        verify(sym.is_constant,\n               '\"{}\" is in const_syms but not marked constant'\n               .format(sym.name))\n\n        verify(not sym.nodes,\n               '\"{}\" is constant but has menu nodes'.format(sym.name))\n\n        verify(not sym._dependents,\n               '\"{}\" is constant but is a dependency of some symbol'\n               .format(sym.name))\n\n        verify(not sym.choice,\n               '\"{}\" is constant and a choice symbol'.format(sym.name))\n\n        sym.__repr__()\n        sym.__str__()\n        sym.assignable\n        kconf.disable_warnings()\n        sym.set_value(2)\n        sym.set_value(\"foo\")\n        sym.unset_value()\n        kconf.enable_warnings()  # Legacy warning function\n        sym.str_value\n        sym.tri_value\n        sym.type\n        sym.visibility\n\n    for choice in kconf.choices:\n        for sym in choice.syms:\n            verify(sym.choice is choice,\n                   \"{0} is in choice.syms but 'sym.choice' is not the choice\"\n                   .format(sym.name))\n\n            verify(sym.type in (BOOL, TRISTATE),\n                   \"{} is a choice symbol but is not a bool/tristate\"\n                   .format(sym.name))\n\n        choice.__str__()\n        choice.__repr__()\n        choice.str_value\n        choice.tri_value\n        choice.user_value\n        choice.assignable\n        choice.selection\n        choice.type\n        choice.visibility\n\n    # Menu nodes\n\n    node = kconf.top_node\n\n    while 1:\n        # Everything else should be well exercised elsewhere\n        node.__repr__()\n        node.__str__()\n        verify(isinstance(node.item, (Symbol, Choice)) or \\\n               node.item in (MENU, COMMENT),\n               \"'{}' appeared as a menu item\".format(node.item))\n\n        if node.list is not None:\n            node = node.list\n\n        elif node.next is not None:\n            node = node.next\n\n        else:\n            while node.parent is not None:\n                node = node.parent\n                if node.next is not None:\n                    node = node.next\n                    break\n            else:\n                break\n\n\ndef test_alldefconfig(arch, srcarch):\n    \"\"\"\n    Verify that alldefconfig.py generates the same .config as\n    'make alldefconfig', for each architecture. Runs the script via\n    'make scriptconfig'.\n    \"\"\"\n    shell(\"make scriptconfig SCRIPT=Kconfiglib/alldefconfig.py \"\n          \"PYTHONCMD='{}'\".format(sys.executable))\n    shell(\"mv .config ._config\")\n    shell(\"scripts/kconfig/conf --alldefconfig Kconfig\")\n\n    compare_configs(arch)\n\n\ndef test_defconfig(arch, srcarch):\n    \"\"\"\n    Verify that Kconfiglib generates the same .config as scripts/kconfig/conf,\n    for each architecture/defconfig pair. In obsessive mode, this test includes\n    nonsensical groupings of arches with defconfigs from other arches (every\n    arch/defconfig combination) and takes an order of magnitude longer time to\n    run.\n\n    With logging enabled, this test appends any failures to a file\n    test_defconfig_fails in the root.\n    \"\"\"\n    kconf = Kconfig()\n\n    if obsessive:\n        defconfigs = []\n\n        # Collect all defconfigs. This could be done once instead, but it's\n        # a speedy operation comparatively.\n        for srcarch_ in os.listdir(\"arch\"):\n            defconfigs.extend(defconfig_files(srcarch_))\n    else:\n        defconfigs = defconfig_files(srcarch)\n\n    # Test architecture for each defconfig\n\n    for defconfig in defconfigs:\n        rm_configs()\n\n        kconf.load_config(defconfig)\n        kconf.write_config(\"._config\")\n        shell(\"scripts/kconfig/conf --defconfig='{}' Kconfig\".\n              format(defconfig))\n\n        arch_defconfig_str = \"  {:14}with {:60} \".format(arch, defconfig)\n\n        if equal_configs():\n            print(arch_defconfig_str + \"OK\")\n        else:\n            print(arch_defconfig_str + \"FAIL\")\n            fail()\n            if log:\n                with open(\"test_defconfig_fails\", \"a\") as fail_log:\n                    fail_log.write(\"{} with {} did not match\\n\"\n                                   .format(arch, defconfig))\n\n\ndef test_min_config(arch, srcarch):\n    \"\"\"\n    Verify that Kconfiglib generates the same .config as 'make savedefconfig'\n    for each architecture/defconfig pair.\n    \"\"\"\n    kconf = Kconfig()\n\n    if obsessive_min_config:\n        defconfigs = []\n        for srcarch_ in os.listdir(\"arch\"):\n            defconfigs.extend(defconfig_files(srcarch_))\n    else:\n        defconfigs = defconfig_files(srcarch)\n\n    for defconfig in defconfigs:\n        rm_configs()\n\n        kconf.load_config(defconfig)\n        kconf.write_min_config(\"._config\")\n\n        shell(\"cp {} .config\".format(defconfig))\n\n        shell(\"scripts/kconfig/conf --savedefconfig=.config Kconfig\")\n\n        arch_defconfig_str = \"  {:14}with {:60} \".format(arch, defconfig)\n\n        if equal_configs():\n            print(arch_defconfig_str + \"OK\")\n        else:\n            print(arch_defconfig_str + \"FAIL\")\n\n\n#\n# Helper functions\n#\n\n\ndef defconfig_files(srcarch):\n    # Yields a list of defconfig file filenames for a particular srcarch\n    # subdirectory (arch/<srcarch>/)\n\n    srcarch_dir = os.path.join(\"arch\", srcarch)\n\n    # Some arches have a defconfig in the root of their arch/<arch>/ directory\n    root_defconfig = os.path.join(srcarch_dir, \"defconfig\")\n    if os.path.exists(root_defconfig):\n        yield root_defconfig\n\n    # Assume all files in the arch/<arch>/configs/ directory (if it exists) are\n    # configurations\n    defconfigs_dir = os.path.join(srcarch_dir, \"configs\")\n\n    if not os.path.isdir(defconfigs_dir):\n        return\n\n    for dirpath, _, filenames in os.walk(defconfigs_dir):\n        for filename in filenames:\n            yield os.path.join(dirpath, filename)\n\n\ndef rm_configs():\n    # Delete any old \".config\" (generated by the C implementation) and\n    # \"._config\" (generated by us), if present.\n\n    def rm_if_exists(f):\n        if os.path.exists(f):\n            os.remove(f)\n\n    rm_if_exists(\".config\")\n    rm_if_exists(\"._config\")\n\n\ndef compare_configs(arch):\n    if equal_configs():\n        print(\"{:14}OK\".format(arch))\n    else:\n        print(\"{:14}FAIL\".format(arch))\n        fail()\n\n\ndef equal_configs():\n    with open(\".config\") as f:\n        their = f.readlines()\n\n    # Strip the header generated by 'conf'\n    i = 0\n    for line in their:\n        if not line.startswith(\"#\") or \\\n           re.match(r\"# CONFIG_(\\w+) is not set\", line):\n            break\n        i += 1\n    their = their[i:]\n\n    try:\n        f = open(\"._config\")\n    except EnvironmentError as e:\n        if e.errno != errno.ENOENT:\n            raise\n        print(\"._config not found. Did you forget to apply the Makefile patch?\")\n        return False\n    else:\n        with f:\n            our = f.readlines()\n\n    if their == our:\n        return True\n\n    # Print a unified diff to help debugging\n    print(\"Mismatched .config's! Unified diff:\")\n    sys.stdout.writelines(difflib.unified_diff(their, our, fromfile=\"their\",\n                                               tofile=\"our\"))\n\n    return False\n\n\nif __name__ == \"__main__\":\n    run_tests()\n"
  },
  {
    "path": "kernel/scripts/Minos.build.mk",
    "content": "# SPDX-License-Identifier: GPL-2.0\n\nsrc := $(obj)\n\nPHONY := __build\n__build:\n\nobj-y :=\nsubdir-y :=\nlib-y :=\ntargets :=\n\nEXTRA_AFLAGS   :=\nEXTRA_CFLAGS   :=\nEXTRA_CPPFLAGS :=\nEXTRA_LDFLAGS  :=\n\ninclude scripts/Minos.config.mk\n\n# Read auto.conf if it exists, otherwise ignore\n-include .config\n\n# The filename Kbuild has precedence over Makefile add Makefile\nkbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))\nkbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)\ninclude $(kbuild-file)\n\nifndef obj\n$(warning kbuild: Minos.mk is included improperly)\nendif\n\n__subdir-y\t:= $(patsubst %/,%,$(filter %/, $(obj-y)))\nsubdir-y\t+= $(__subdir-y)\nobj-y\t\t:= $(patsubst %/, %/built-in.o, $(obj-y))\n\n# $(subdir-obj-y) is the list of objects in $(obj-y) which uses dir/ to\n# tell kbuild to descend\nsubdir-obj-y := $(filter %/built-in.o, $(obj-y))\n\n# Replace multi-part objects by their individual parts,\n# including built-in.o from subdirectories\nreal-obj-y := $(foreach m, $(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m)))\n\n# generate the dependece file\nreal-dep-y := $(addsuffix .d, $(real-obj-y))\nreal-dep-y := $(addprefix $(obj)/., $(real-dep-y))\n\n# Add subdir path\nsubdir-obj-y\t:= $(addprefix $(obj)/,$(subdir-obj-y))\nreal-obj-y\t:= $(addprefix $(obj)/,$(real-obj-y))\n\n# remove the .lds file which is not link to built-in.o\nlds-y\t\t:= $(filter %.lds, $(real-obj-y))\nreal-obj-y\t:= $(filter-out %.lds, $(real-obj-y))\n\n# remove the .dtb file which is not link to built-in.o\ndtb-y\t\t:= $(filter %.dtb, $(real-obj-y))\nreal-obj-y\t:= $(filter-out %.dtb, $(real-obj-y))\n\n# remove the head-y which is link as the first.o\nreal-head-y\t:= $(filter $(MBUILD_MINOS_INIT), $(real-obj-y))\nreal-obj-y\t:= $(filter-out $(MBUILD_MINOS_INIT), $(real-obj-y))\n\nOBJ_DEPS\t= $(real-dep-y)\n\nCFLAGS\t\t= $(MBUILD_CFLAGS)\nCFLAGS\t\t+= -MMD -MF $(@D)/.$(@F).d\n\nbuiltin-target \t:= $(obj)/built-in.o\n\n__build: $(subdir-y) $(builtin-target) $(lds-y) $(real-head-y) $(dtb-y)\n\t@:\n\nifdef builtin-target\n$(builtin-target): $(real-obj-y)\nifeq ($(real-obj-y),)\n\t$(Q) echo \"  CC      $@\"\n\t$(Q) $(CC) $(CFLAGS) -c -x c /dev/null -o $@\nelse\n\t$(Q) echo \"  LD      $@\"\n\t$(Q) $(LD) $(MBUILD_LDFLAGS) -r -o $@ $^\nendif\n\n-include $(OBJ_DEPS)\n\n%.o: %.c $(obj)/Makefile $(srctree)/Makefile\n\t$(Q) echo \"  CC      $@\"\n\t$(Q) $(CC) $(CFLAGS) -D__KERNEL__ -c $< -o $@\n\n%.o: %.S $(obj)/Makefile $(srctree)/Makefile\n\t$(Q) echo \"  CC      $@\"\n\t$(Q) $(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $@\n\n%.lds: %.lds.S $(obj)/Makefile $(srctree)/Makefile\n\t$(Q) echo \"  CC      $@\"\n\t$(Q) $(CC) $(MBUILD_CFLAGS) -E -P $< -o $@\n\n%.dtb: %.dts $(obj)/Makefile $(srctree)/Makefile\n\t$(Q) echo \"  DTC     $@\"\n\t$(Q) $(DTC) -q -I dts -O dtb -o $@ $<\n\nPHONY += $(subdir-y)\n$(subdir-y):\n\t$(Q) $(MAKE) $(build)=$(obj)/$@\n\nendif\n\nPHONY += FORCE\nFORCE:\n\n.PHONY: $(FORCE)\n"
  },
  {
    "path": "kernel/scripts/Minos.clean.mk",
    "content": "# SPDX-License-Identifier: GPL-2.0\n# ==========================================================================\n# Cleaning up\n# ==========================================================================\n\nsrc := $(obj)\n\nPHONY := __clean\n__clean:\n\ninclude scripts/Minos.config.mk\n\n# The filename Kbuild has precedence over Makefile\nkbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))\ninclude $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile)\n\n# Figure out what we need to build from the various variables\n# ==========================================================================\n\n__subdir-y\t:= $(patsubst %/,%,$(filter %/, $(obj-y)))\nsubdir-y\t+= $(__subdir-y)\n__subdir-\t:= $(patsubst %/,%,$(filter %/, $(obj-)))\nsubdir-\t\t+= $(__subdir-)\n\n# Subdirectories we need to descend into\n\nsubdir-ym\t:= $(sort $(subdir-y))\nsubdir-ymn      := $(sort $(subdir-ym) $(subdir-))\n\n# remove the directly\n#real-obj-y\t= $(filter-out %/, $(obj-y))\n#real-dep-y\t:= $(addsuffix .d, $(real-obj-y))\n#real-dep-y\t:= $(addprefix $(obj)/., $(real-dep-y))\n\n# Add subdir path\n\nsubdir-ymn\t:= $(addprefix $(obj)/,$(subdir-ymn))\n\n# build a list of files to remove, usually relative to the current\n# directory\n\n#__clean-files\t:= $(addprefix $(obj)/, $(real-obj-y))\n__clean-files\t+= $(obj)/built-in.o\n__clean-files\t+= $(obj)/.built-in.o.d\n#__clean-files\t+= $(real-dep-y)\n__clean-files\t+= $(wildcard $(obj)/*.o)\n__clean-files\t+= $(wildcard $(obj)/.*.d)\n__clean-files\t+= $(wildcard $(obj)/*.lds)\n__clean-files\t+= $(wildcard $(obj)/*.dtb)\n\n__clean-dirs    :=\n\n# ==========================================================================\n__clean: $(subdir-ymn)\n\t$(Q) rm -f $(__clean-files)\n\t$(Q) rm -rf $(__clean-dirs)\n\n# ===========================================================================\n# Generic stuff\n# ===========================================================================\n\n# Descending\n# ---------------------------------------------------------------------------\n\nPHONY += $(subdir-ymn)\n$(subdir-ymn):\n\t$(Q)$(MAKE) $(clean)=$@\n\n.PHONY: $(PHONY)\n"
  },
  {
    "path": "kernel/scripts/Minos.config.mk",
    "content": "# SPDX-License-Identifier: GPL-2.0\n\nbuild := -f $(srctree)/scripts/Minos.build.mk obj\n\nclean := -f $(srctree)/scripts/Minos.clean.mk obj\n"
  },
  {
    "path": "kernel/scripts/generate_allsymbols.py",
    "content": "import sys\nimport os\n\n\nif __name__ == \"__main__\":\n    argv = sys.argv\n    if len(argv) < 3:\n        print(\"argument is wrong\")\n        exit()\n\n    input_name = argv[1]\n    output_name = argv[2]\n    symbols = \"#include <config/config.h>\\n\"\n    symbols += \"#ifdef CONFIG_ARCH_AARCH64\\n\"\n    symbols += \"#define PTR .quad\\n\"\n    symbols += \"#define ALGN .align 8\\n\"\n    symbols += \"#else\\n\"\n    symbols += \"#define PTR .long\\n\"\n    symbols += \"#define ALGN .align 4\\n\"\n    symbols += \"#endif\\n\\n\"\n    symbols += \".section .__symbols__, \\\"a\\\"\\n\"\n    symbols += \"        PTR        allsyms_addresses\\n\"\n    symbols += \"        PTR        allsyms_num_syms\\n\"\n    symbols += \"        PTR        allsyms_offset\\n\"\n    symbols += \"        PTR        allsyms_names\\n\\n\"\n\n    addrs = \".section .rodata, \\\"a\\\"\\n\"\n    addrs += \".global allsyms_addresses\\n        ALGN\\n\"\n    addrs += \"allsyms_addresses:\\n\"\n\n    names = \".global allsyms_names\\n        ALGN\\n\"\n    names += \"allsyms_names:\\n\"\n\n    offsets = \".global allsyms_offset\\n        ALGN\\n\"\n    offsets += \"allsyms_offset:\\n\"\n\n    total_nums_chr = 0\n    total_nums_syms = 0\n\n    with open(input_name, 'r') as fd:\n        line = fd.readline()\n        while line :\n            array = [i.strip('\\r\\t\\n') for i in line.split(' ') if i]\n            t = array[1]\n            if t is 'T' or t is 't':\n                total_nums_syms += 1\n                addrs += \"        PTR        0x%s\\n\" %(array[0])\n                offsets += \"        .long 0x%x\\n\" %(total_nums_chr)\n                names += \"        .byte \"\n                for letter in array[2]:\n                    names += \"0x%x, \" %(ord(letter))\n                    total_nums_chr += 1\n                names += \"0x0\\n\"\n                total_nums_chr += 1\n            line = fd.readline()\n        fd.close()\n\n    addrs += \".global allsyms_num_syms\\n        ALGN\\n\"\n    addrs += \"allsyms_num_syms:\\n\"\n    addrs += \"        .long    0x%x\\n\\n\" %(total_nums_syms)\n\n    with open(output_name, 'w') as ofd:\n        ofd.write(symbols)\n        ofd.write(addrs)\n        ofd.write(offsets)\n        ofd.write(names)\n\n    exit()\n"
  },
  {
    "path": "kernel/userspace/Kconfig",
    "content": "menu \"Minos Kobjects configuration\"\n\nconfig IPC_ENDPOINT\n\tbool \"support IPC by endpoint\"\n\tdefault y\n\thelp\n\t  support the endpoint IPC\n\nconfig IPC_PORT\n\tbool \"support IPC by port\"\n\tdefault y\n\thelp\n\t  support the port IPC\n\nendmenu\n"
  },
  {
    "path": "kernel/userspace/Makefile",
    "content": "obj-y\t+= endpoint.o\nobj-y\t+= stdio.o\nobj-y\t+= process.o\nobj-y\t+= pma.o\nobj-y\t+= irq.o\nobj-y\t+= poll.o\nobj-y\t+= kobject_copy.o\nobj-y\t+= notify.o\nobj-y\t+= port.o\nobj-y\t+= iqueue.o\nobj-y\t+= futex.o\nobj-y\t+= handle.o\nobj-y\t+= kobject.o\nobj-y\t+= procinfo.o\nobj-y\t+= root_service.o\nobj-y\t+= syscall.o\nobj-y\t+= thread.o\nobj-y\t+= uaccess.o\nobj-y\t+= vspace.o\nobj-y\t+= time.o\n"
  },
  {
    "path": "kernel/userspace/endpoint.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/mm.h>\n#include <minos/sched.h>\n#include <uspace/poll.h>\n#include <uspace/iqueue.h>\n#include <uspace/kobject.h>\n#include <uspace/uaccess.h>\n#include <uspace/vspace.h>\n#include <uspace/proc.h>\n\n#define EP_RIGHT_MASK\t(KOBJ_RIGHT_MMAP | KOBJ_RIGHT_CTL)\n#define EP_RIGHT\t(KOBJ_RIGHT_RW | KOBJ_RIGHT_CTL)\n\nstruct endpoint {\n\tvoid *shmem;\n\tsize_t shmem_size;\n\tstruct kobject kobj;\t\t\t// kobj for this endpoint.\n\tstruct iqueue iqueue;\n};\n\n#define kobject_to_endpoint(kobj)\t\\\n\t(struct endpoint *)((kobj)->data)\n\nstatic int endpoint_close(struct kobject *kobj, right_t right, struct process *proc)\n{\n\tstruct endpoint *ep = kobject_to_endpoint(kobj);\n\n\tiqueue_close(&ep->iqueue, right, proc);\n\n\tif (ep->shmem == NULL)\n\t\treturn 0;\n\telse\n\t\treturn unmap_process_memory(proc, va2sva(ep->shmem), ep->shmem_size);\n}\n\nstatic long endpoint_recv(struct kobject *kobj, void __user *data,\n\t\tsize_t data_size, size_t *actual_data, void __user *extra,\n\t\tsize_t extra_size, size_t *actual_extra, uint32_t timeout)\n{\n\tstruct endpoint *ep = kobject_to_endpoint(kobj);\n\treturn iqueue_recv(&ep->iqueue, data, data_size, actual_data, extra,\n\t\t\textra_size, actual_extra, timeout);\n}\n\nstatic long endpoint_send(struct kobject *kobj, void __user *data, size_t data_size,\n\t\tvoid __user *extra, size_t extra_size, uint32_t timeout)\n{\n\tstruct endpoint *ep = kobject_to_endpoint(kobj);\n\treturn iqueue_send(&ep->iqueue, data, data_size, extra, extra_size, timeout);\n}\n\nstatic int endpoint_reply(struct kobject *kobj, right_t right,\n\t\tlong token, long errno, handle_t fd, right_t fd_right)\n{\n\tstruct endpoint *ep = kobject_to_endpoint(kobj);\n\treturn iqueue_reply(&ep->iqueue, right, token, errno, fd, fd_right);\n}\n\nstatic void endpoint_release(struct kobject *kobj)\n{\n\tstruct endpoint *ep = kobject_to_endpoint(kobj);\n\n\tif (ep->shmem)\n\t\tfree_pages(ep->shmem);\n\n\tfree(ep);\n}\n\nstatic int endpoint_mmap(struct kobject *kobj, right_t right,\n\t\tvoid **addr, unsigned long *msize)\n{\n\tstruct endpoint *ep = kobject_to_endpoint(kobj);\n\tunsigned long base;\n\tint ret;\n\n\tASSERT(ep->shmem != NULL);\n\tbase = va2sva(ep->shmem);\n\n\tret = map_process_memory(current_proc, base, ep->shmem_size,\n\t\t\tvtop(ep->shmem), VM_RW | VM_SHARED);\n\tif (ret)\n\t\treturn ret;\n\n\t*addr = (void *)base;\n\t*msize = ep->shmem_size;\n\n\treturn 0;\n}\n\nstatic int endpoint_munmap(struct kobject *kobj, right_t right)\n{\n\tstruct endpoint *ep = kobject_to_endpoint(kobj);\n\tunsigned long base;\n\n\tASSERT(ep->shmem != NULL);\n\tbase = va2sva(ep->shmem);\n\n\treturn unmap_process_memory(current_proc, base, ep->shmem_size);\n}\n\nstatic struct kobject_ops endpoint_kobject_ops = {\n\t.send\t\t= endpoint_send,\n\t.recv\t\t= endpoint_recv,\n\t.release\t= endpoint_release,\n\t.close\t\t= endpoint_close,\n\t.mmap\t\t= endpoint_mmap,\n\t.munmap\t\t= endpoint_munmap,\n\t.reply\t\t= endpoint_reply,\n};\n\nstatic int endpoint_create(struct kobject **kobj, right_t *right, unsigned long data)\n{\n\tsize_t shmem_size = data;\n\tstruct endpoint *ep;\n\tright_t right_ep = EP_RIGHT;\n\n\tshmem_size = PAGE_BALIGN(shmem_size);\n\tif (shmem_size > HUGE_PAGE_SIZE)\n\t\treturn -E2BIG;\n\n\tep = zalloc(sizeof(struct endpoint));\n\tif (!ep)\n\t\treturn -ENOMEM;\n\n\tif (shmem_size > 0) {\n\t\tep->shmem = get_free_pages(shmem_size >> PAGE_SHIFT, GFP_USER);\n\t\tif (!ep->shmem) {\n\t\t\tfree(ep);\n\t\t\treturn -ENOMEM;\n\t\t}\n\t\tright_ep |= KOBJ_RIGHT_MMAP;\n\t}\n\n\tiqueue_init(&ep->iqueue, 0, &ep->kobj);\n\tkobject_init(&ep->kobj, KOBJ_TYPE_ENDPOINT, EP_RIGHT_MASK, (unsigned long)ep);\n\n\tep->shmem_size = shmem_size;\n\tep->kobj.ops = &endpoint_kobject_ops;\n\t*kobj = &ep->kobj;\n\t*right = right_ep;\n\n\treturn 0;\n}\nDEFINE_KOBJECT(endpoint, KOBJ_TYPE_ENDPOINT, endpoint_create);\n"
  },
  {
    "path": "kernel/userspace/futex.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/mm.h>\n#include <minos/time.h>\n#include <minos/task.h>\n#include <minos/sched.h>\n#include <uspace/vspace.h>\n#include <uspace/proc.h>\n\n#define FUTEX_WAIT              0\n#define FUTEX_WAKE              1\n#define FUTEX_FD                2\n#define FUTEX_REQUEUE           3\n#define FUTEX_CMP_REQUEUE       4\n#define FUTEX_WAKE_OP           5\n#define FUTEX_LOCK_PI           6\n#define FUTEX_UNLOCK_PI         7\n#define FUTEX_TRYLOCK_PI        8\n#define FUTEX_WAIT_BITSET       9\n#define FUTEX_WAKE_BITSET       10\n#define FUTEX_WAIT_REQUEUE_PI   11\n#define FUTEX_CMP_REQUEUE_PI    12\n#define FUTEX_SWAP              13\n\n#define FUTEX_PRIVATE_FLAG      128\n#define FUTEX_CLOCK_REALTIME    256\n#define FUTEX_CMD_MASK          ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME)\n\n#define FUTEX_WAIT_PRIVATE      (FUTEX_WAIT | FUTEX_PRIVATE_FLAG)\n#define FUTEX_WAKE_PRIVATE      (FUTEX_WAKE | FUTEX_PRIVATE_FLAG)\n#define FUTEX_REQUEUE_PRIVATE   (FUTEX_REQUEUE | FUTEX_PRIVATE_FLAG)\n#define FUTEX_CMP_REQUEUE_PRIVATE (FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG)\n#define FUTEX_WAKE_OP_PRIVATE   (FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG)\n#define FUTEX_LOCK_PI_PRIVATE   (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG)\n#define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG)\n#define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG)\n#define FUTEX_WAIT_BITSET_PRIVATE       (FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG)\n#define FUTEX_WAKE_BITSET_PRIVATE       (FUTEX_WAKE_BITSET | FUTEX_PRIVATE_FLAG)\n#define FUTEX_WAIT_REQUEUE_PI_PRIVATE   (FUTEX_WAIT_REQUEUE_PI | \\\n                                         FUTEX_PRIVATE_FLAG)\n#define FUTEX_CMP_REQUEUE_PI_PRIVATE    (FUTEX_CMP_REQUEUE_PI | \\\n                                         FUTEX_PRIVATE_FLAG)\n#define FUTEX_SWAP_PRIVATE              (FUTEX_SWAP | FUTEX_PRIVATE_FLAG)\n\nstruct futex {\n\tpid_t owner;\n\tunsigned long paddr;\n\tstruct list_head list;\n\tstruct event event;\n};\n\nstruct futex_queue {\n\tint cnt;\n\tspinlock_t lock;\n\tstruct list_head head;\n};\n\n#define FUTEX_KEY_SIZE\t10\nstatic struct futex_queue ft_queue[FUTEX_KEY_SIZE];\n\nstatic unsigned long futex_timeout_val(struct timespec *ktime)\n{\n\t// TBD overfolw check\n\treturn (ktime->tv_sec * 1000ULL) + (ktime->tv_nsec / 1000000ULL);\n}\n\nstatic long sys_do_futex_wait(struct futex *ft, uint32_t *kaddr,\n\t\tuint32_t val, struct timespec *ktime,\n\t\tuint32_t *kaddr2, uint32_t val3)\n{\n\tunsigned long timeout;\n\n\ttimeout = ktime ? futex_timeout_val(ktime) : 0;\n\n\t/*\n\t * the lock may has been released, return to userspace\n\t * again to require the lock at userspace. else wait on\n\t * this futex's wiat list.\n\t */\n\tspin_lock(&ft->event.lock);\n\tif (*kaddr != val) {\n\t\tspin_unlock(&ft->event.lock);\n\t\treturn 0;\n\t}\n\t__wait_event(ft, OS_EVENT_TYPE_FUTEX, timeout);\n\tspin_unlock(&ft->event.lock);\n\n\treturn do_wait_event(&ft->event);\n}\n\nstatic long sys_do_futex_wake(struct futex *ft, uint32_t *kaddr,\n\t\tuint32_t val, struct timespec *ktime,\n\t\tuint32_t *kaddr2, uint32_t val3)\n{\n\tint wakecnt = 0;\n\n\tif ((val != 1) && (val != INT_MAX)) {\n\t\tpr_warn(\"bad value for futex wake %d\\n\", val);\n\t\treturn -EINVAL;\n\t}\n\n\tspin_lock(&ft->event.lock);\n\twakecnt = __wake_up_event_waiter(&ft->event, 0, TASK_STATE_PEND_OK, val);\n\tspin_unlock(&ft->event.lock);\n\n\treturn wakecnt;\n}\n\nstatic inline int futex_key(unsigned long phy)\n{\n\treturn (phy >> PAGE_SHIFT) % 10;\n}\n\nstatic inline int is_wait_cmd(int cmd)\n{\n\tif (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI ||\n                      cmd == FUTEX_WAIT_BITSET ||\n                      cmd == FUTEX_WAIT_REQUEUE_PI)\n\t\treturn 1;\n\telse\n\t\treturn 0;\n}\n\nlong sys_futex(uint32_t __user *uaddr, int op, uint32_t val,\n\t\tstruct timespec __user *utime,\n\t\tuint32_t __user *uaddr2, uint32_t val3)\n{\n\tstruct vspace *vs = current->vs;\n\tstruct timespec *ktime = NULL;\n\tstruct futex_queue *ftq;\n\tstruct futex *ft = NULL, *tmp;\n\tuint32_t *kaddr, *kaddr2 = NULL;\n\tunsigned long paddr;\n\tunsigned int key;\n\tint cmd = op & FUTEX_CMD_MASK;\n\n\tkaddr = uva_to_kva(vs, ULONG(uaddr), sizeof(uint32_t), VM_RW);\n\tif (kaddr == NULL)\n\t\treturn -EFAULT;\n\n\tif (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI ||\n                      cmd == FUTEX_WAIT_BITSET ||\n                      cmd == FUTEX_WAIT_REQUEUE_PI)) {\n\t\tktime = uva_to_kva(vs, ULONG(utime), sizeof(struct timespec), VM_RW);\n\t\tif (ktime == NULL)\n\t\t\treturn -EFAULT;\n\t}\n\n\tif (uaddr2) {\n\t\tkaddr2 = uva_to_kva(vs, ULONG(uaddr2), sizeof(uint32_t), VM_RW);\n\t\tif (kaddr2 == NULL)\n\t\t\treturn -EFAULT;\n\t}\n\n\tpaddr = vtop(kaddr);\n\tkey = futex_key(paddr);\n\tASSERT(key < FUTEX_KEY_SIZE);\n\tftq = &ft_queue[key];\n\n\tspin_lock(&ftq->lock);\n\tlist_for_each_entry(tmp, &ftq->head, list) {\n\t\tif (tmp->paddr == paddr) {\n\t\t\tft = tmp;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!ft && !is_wait_cmd(cmd)) {\n\t\tspin_unlock(&ftq->lock);\n\t\treturn -ENOENT;\n\t}\n\n\tif (!ft) {\n\t\tft = zalloc(sizeof(struct futex));\n\t\tif (!ft) {\n\t\t\tspin_unlock(&ftq->lock);\n\t\t\treturn -ENOMEM;\n\t\t}\n\n\t\tevent_init(&ft->event, OS_EVENT_TYPE_FUTEX, ft);\n\t\tft->owner = current_pid;\n\t\tft->paddr = paddr;\n\n\t\tlist_add(&ftq->head, &ft->list);\n\t}\n\tspin_unlock(&ftq->lock);\n\n\tswitch (cmd) {\n\tcase FUTEX_WAIT:\n\t\treturn sys_do_futex_wait(ft, kaddr, val, ktime, kaddr2, val3);\n\tcase FUTEX_WAKE:\n\t\treturn sys_do_futex_wake(ft, kaddr, val, ktime, kaddr2, val3);\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn -ENOSYS;\n}\n\nstatic int futex_subsys_init(void)\n{\n\tint i;\n\n\tfor (i = 0; i < FUTEX_KEY_SIZE; i++) {\n\t\tinit_list(&ft_queue[i].head);\n\t\tspin_lock_init(&ft_queue[i].lock);\n\t}\n\n\treturn 0;\n}\nsubsys_initcall(futex_subsys_init);\n"
  },
  {
    "path": "kernel/userspace/handle.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/mm.h>\n#include <uspace/kobject.h>\n#include <uspace/handle.h>\n#include <uspace/proc.h>\n\n#define KOBJ_PLACEHOLDER\t(struct kobject *)(-1)\n\n#define to_handle_table_desc(hdesc)\t\\\n\t(struct handle_table_desc *)&hdesc[NR_DESC_PER_PAGE]\n\nstatic struct handle_desc *new_handle_desc_table(uint32_t index)\n{\n\tstruct handle_desc *dt;\n\tstruct handle_table_desc *htd;\n\n\tif (index >= PROC_MAX_HANDLE) {\n\t\tpr_err(\"handle table too big exceed %d\\n\", PROC_MAX_HANDLE);\n\t\treturn NULL;\n\t}\n\n\tdt = get_free_page(GFP_KERNEL);\n\tif (!dt)\n\t\treturn NULL;\n\tmemset(dt, 0, PAGE_SIZE);\n\n\thtd = to_handle_table_desc(dt);\n\thtd->left = NR_DESC_PER_PAGE;\n\thtd->index = index;\n\thtd->next = NULL;\n\n\treturn dt;\n}\n\nstatic int __alloc_new_handle(struct handle_table_desc *htd,\n\t\thandle_t *handle, struct handle_desc **hd)\n{\n\tstruct handle_desc *table;\n\tstruct handle_table_desc *new_htd;\n\n\ttable = new_handle_desc_table(htd->index + NR_DESC_PER_PAGE);\n\tif (!table)\n\t\treturn -ENOMEM;\n\n\thtd->next = table;\n\tnew_htd = to_handle_table_desc(table);\n\tnew_htd->left -= 1;\n\n\t*handle = new_htd->index;\n\t*hd = &table[0];\n\n\treturn 0;\n}\n\nstatic int lookup_handle_desc(struct process *proc, handle_t handle,\n\t\tstruct handle_desc **hd,\n\t\tstruct handle_table_desc **htd)\n{\n\tstruct handle_desc *table = proc->handle_desc_table;\n\tstruct handle_table_desc *tdesc = to_handle_table_desc(table);\n\n\twhile (handle >= NR_DESC_PER_PAGE) {\n\t\thandle -= NR_DESC_PER_PAGE;\n\t\ttable = tdesc->next;\n\t\ttdesc = to_handle_table_desc(table);\n\t}\n\n\t*hd = &table[handle];\n\t*htd = tdesc;\n\n\treturn 0;\n}\n\nvoid __release_handle(struct process *proc, handle_t handle)\n{\n\tstruct handle_desc *hd;\n\tstruct handle_table_desc *htd;\n\tint ret;\n\n\tspin_lock(&proc->lock);\n\tret = lookup_handle_desc(proc, handle, &hd, &htd);\n\tif (ret)\n\t\tgoto out;\n\n\tif (hd->kobj == NULL)\n\t\tgoto out;\n\n\thd->kobj = NULL;\n\thd->right = KOBJ_RIGHT_NONE;\n\thtd->left++;\nout:\n\tspin_unlock(&proc->lock);\n}\n\nint release_process_handle(struct process *proc, handle_t handle, struct kobject **kobj, right_t *right)\n{\n\tstruct handle_desc *hd;\n\tstruct handle_table_desc *htd;\n\tint ret = -ENOENT;\n\n\tif (WRONG_HANDLE(handle) || !proc)\n\t\treturn -ENOENT;\n\n\tspin_lock(&proc->lock);\n\tret = lookup_handle_desc(proc, handle, &hd, &htd);\n\tif (ret)\n\t\tgoto out;\n\n\tif (hd->kobj == NULL || hd->kobj == KOBJ_PLACEHOLDER) {\n\t\tret = -EPERM;\n\t\tgoto out;\n\t}\n\n\t*kobj = hd->kobj;\n\t*right = hd->right;\n\n\thd->kobj = NULL;\n\thd->right = KOBJ_RIGHT_NONE;\n\thtd->left++;\nout:\n\tspin_unlock(&proc->lock);\n\n\treturn ret;\n}\n\nint release_handle(handle_t handle, struct kobject **kobj, right_t *right)\n{\n\treturn release_process_handle(current_proc, handle, kobj, right);\n}\n\nstatic inline int __alloc_handle_internal(struct handle_desc *desc,\n\t\tstruct handle_table_desc *htd, handle_t *handle,\n\t\tstruct handle_desc **hd)\n{\n\tint i;\n\n\tif (htd->left == 0)\n\t\treturn -ENOSPC;\n\n\tfor (i = 0; i < NR_DESC_PER_PAGE; i++) {\n\t\tif (desc[i].kobj == NULL) {\n\t\t\t*handle = i + htd->index;\n\t\t\t*hd = &desc[i];\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\tASSERT(0);\n\treturn -ENOSPC;\n}\n\nhandle_t __alloc_handle(struct process *proc, struct kobject *kobj, right_t right)\n{\n\tstruct handle_desc *hd = proc->handle_desc_table;\n\tstruct handle_table_desc *htd = to_handle_table_desc(hd);\n\thandle_t handle = HANDLE_NULL;\n\tstruct handle_desc *hdesc;\n\tint ret = -ENOSPC;\n\n\tASSERT(kobj != NULL);\n\tASSERT(proc != NULL);\n\n\tspin_lock(&proc->lock);\n\n\tdo {\n\t\tret = __alloc_handle_internal(hd, htd, &handle, &hdesc);\n\t\tif (ret == 0)\n\t\t\tbreak;\n\t\thd = htd->next;\n\t} while (hd != NULL);\n\n\tif (ret != 0) {\n\t\tret = __alloc_new_handle(htd, &handle, &hdesc);\n\t\tif (ret) {\n\t\t\thandle = HANDLE_NULL;\n\t\t\tgoto out;\n\t\t}\n\t}\n\n\thdesc->kobj = kobj;\n\thdesc->right = right;\n\n\tif (kobj != KOBJ_PLACEHOLDER)\n\t\tkobject_get(kobj);\nout:\n\tspin_unlock(&proc->lock);\n\t\n\treturn handle;\n}\n\nhandle_t alloc_handle(struct kobject *kobj, right_t right)\n{\n\treturn __alloc_handle(current_proc, kobj, right);\n}\n\nstatic int setup_handle(struct process *proc, handle_t handle,\n\t\tstruct kobject *kobj, right_t right)\n{\n\tstruct handle_desc *hd;\n\tstruct handle_table_desc *htd;\n\tint ret;\n\n\tASSERT(!WRONG_HANDLE(handle));\n\n\tspin_lock(&proc->lock);\n\tret = lookup_handle_desc(proc, handle, &hd, &htd);\n\tif (ret)\n\t\tgoto out;\n\n\tASSERT(hd->kobj == KOBJ_PLACEHOLDER);\n\thd->kobj = kobj;\n\thd->right = right;\n\tkobject_get(kobj);\nout:\n\tspin_unlock(&proc->lock);\n\treturn ret;\n}\n\nhandle_t send_handle(struct process *proc, struct process *pdst,\n\t\thandle_t handle, right_t right_send)\n{\n\tstruct handle_table_desc *htd;\n\tstruct handle_desc *hdesc;\n\tstruct kobject *kobj;\n\tint handle_ret;\n\tint right;\n\tint ret;\n\n\tif (WRONG_HANDLE(handle))\n\t\treturn -EINVAL;\n\n\t/*\n\t * first get a empty handle from the target process, then\n\t * do the transfer, the reason why take this logic is there\n\t * are two spinlocks need to request, and may cause dead lock\n\t * in some case.\n\t */\n\thandle_ret = __alloc_handle(pdst, KOBJ_PLACEHOLDER, 0);\n\tif (handle_ret < 0)\n\t\treturn handle_ret;\n\n\tspin_lock(&proc->lock);\n\tret = lookup_handle_desc(proc, handle, &hdesc, &htd);\n\tif (ret)\n\t\tgoto out;\n\n\tkobj = hdesc->kobj;\n\tright = hdesc->right;\n\tif (!kobj || (kobj->flags & KOBJ_FLAGS_NON_SHARED) ||\n\t\t\t(kobj == KOBJ_PLACEHOLDER) || !right) {\n\t\tret = -EPERM;\n\t\tgoto out;\n\t}\n\n\t/*\n\t * if the right is 0, means need send all the right\n\t * it has to target process, then check whether this\n\t * kobject has the required rights. then clear the right\n\t * which need to transfer to other process.\n\t */\n\tright_send = (right_send == 0) ? right : right_send;\n\tif ((right & right_send) != right_send) {\n\t\tret = -EPERM;\n\t\tgoto out;\n\t}\n\n\thdesc->right = right & (~right_send | kobj->right_mask);\n\tspin_unlock(&proc->lock);\n\n\tsetup_handle(pdst, handle_ret, kobj, right_send);\n\n\treturn handle_ret;\n\nout:\n\tspin_unlock(&proc->lock);\n\t__release_handle(pdst, handle_ret);\n\tpr_err(\"send handle %d with 0x%x fail\\n\", handle, right_send);\n\n\treturn ret;\n}\n\nhandle_t sys_grant(handle_t proc_handle, handle_t handle, right_t right)\n{\n\tstruct kobject *kobj_proc;\n\tright_t right_proc;\n\tint ret;\n\n\tif (WRONG_HANDLE(proc_handle) || WRONG_HANDLE(handle))\n\t\treturn -ENOENT;\n\n\tret = get_kobject(proc_handle, &kobj_proc, &right_proc);\n\tif (ret)\n\t\treturn -ENOENT;\n\n\tif (kobj_proc->type != KOBJ_TYPE_PROCESS) {\n\t\tret = -EBADF;\n\t\tgoto out;\n\t}\n\n\tret = send_handle(current_proc, (struct process *)kobj_proc->data, handle, right);\nout:\n\tput_kobject(kobj_proc);\n\n\treturn ret;\n}\n\nint get_kobject_from_process(struct process *proc, handle_t handle,\n\t\t\tstruct kobject **kobj, right_t *right)\n{\n\tint ret;\n\tstruct kobject *tmp;\n\tstruct handle_desc *hd;\n\tstruct handle_table_desc *htd;\n\n\tif (WRONG_HANDLE(handle) || !proc)\n\t\treturn -ENOENT;\n\n\tspin_lock(&proc->lock);\n\tret = lookup_handle_desc(proc, handle, &hd, &htd);\n\tif (ret)\n\t\tgoto out;\n\n\ttmp = hd->kobj;\n\n\tif ((tmp != NULL) && (tmp != KOBJ_PLACEHOLDER)) {\n\t\tif (kobject_get(tmp)) {\n\t\t\t*kobj = tmp;\n\t\t\t*right = hd->right;\n\t\t\tret = 0;\n\t\t}\n\t}\nout:\n\tspin_unlock(&proc->lock);\n\treturn ret;\n}\n\nint get_kobject(handle_t handle, struct kobject **kobj, right_t *right)\n{\n\treturn get_kobject_from_process(current_proc, handle, kobj, right);\n}\n\nint put_kobject(struct kobject *kobj)\n{\n\treturn kobject_put(kobj);\n}\n\nvoid process_handles_deinit(struct process *proc)\n{\n\tstruct handle_desc *table = proc->handle_desc_table;\n\tstruct handle_table_desc *tdesc = to_handle_table_desc(table);\n\tstruct handle_desc *tmp;\n\n\twhile (table != NULL) {\n\t\ttmp = tdesc->next;\n\t\ttdesc = to_handle_table_desc(tmp);\n\t\tfree_pages(table);\n\t\ttable = tmp;\n\t}\n}\n\nstatic void release_handle_table(struct process *proc, struct handle_desc *table)\n{\n\tstruct handle_desc *hdesc = table;\n\tint i;\n\n\tfor (i = 0; i < NR_DESC_PER_PAGE; i++) {\n\t\tif ((hdesc->kobj) && (hdesc->kobj != KOBJ_PLACEHOLDER))\n\t\t\tkobject_close(hdesc->kobj, hdesc->right, proc);\n\t\thdesc++;\n\t}\n}\n\nvoid release_proc_kobjects(struct process *proc)\n{\n\tstruct handle_desc *table = proc->handle_desc_table;\n\tstruct handle_table_desc *tdesc = to_handle_table_desc(table);\n\tstruct handle_desc *tmp;\n\n\twhile (table != NULL) {\n\t\ttmp = tdesc->next;\n\t\ttdesc = to_handle_table_desc(tmp);\n\t\trelease_handle_table(proc, table);\n\t\ttable = tmp;\n\t}\n}\n\nint init_proc_handles(struct process *proc)\n{\n\textern struct kobject stdio_kobj;\n\thandle_t handle;\n\n\tproc->handle_desc_table = new_handle_desc_table(0);\n\tif (!proc->handle_desc_table)\n\t\treturn -ENOMEM;\n\n\t/*\n\t * Main task kobj is 0, process can use this handle\n\t * to control itself.\n\t *\n\t * stdout stdin and stderr will provided by kernel, for process\n\t * handle [1] is stdout\n\t * handle [2] is stdin\n\t * handle [3] is stderr\n\t */\n\thandle = __alloc_handle(proc, &proc->kobj, KOBJ_RIGHT_WRITE | KOBJ_RIGHT_CTL);\n\tASSERT(handle == 0);\n\thandle = __alloc_handle(proc, &stdio_kobj, KOBJ_RIGHT_READ);\n\tASSERT(handle == 1);\n\thandle = __alloc_handle(proc, &stdio_kobj, KOBJ_RIGHT_WRITE);\n\tASSERT(handle == 2);\n\thandle = __alloc_handle(proc, &stdio_kobj, KOBJ_RIGHT_WRITE);\n\tASSERT(handle == 3);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "kernel/userspace/iqueue.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/mm.h>\n#include <minos/sched.h>\n#include <uspace/poll.h>\n#include <uspace/kobject.h>\n#include <uspace/uaccess.h>\n#include <uspace/iqueue.h>\n#include <uspace/proc.h>\n\n#include \"kobject_copy.h\"\n\n#define IQ_STAT_CLOSED 1\n#define IQ_STAT_OPENED 0\n\n#define KOBJ_IN_PROCESSING ((void *)-1)\n\nlong iqueue_recv(struct iqueue *iqueue, void __user *data,\n\t\tsize_t data_size, size_t *actual_data, void __user *extra,\n\t\tsize_t extra_size, size_t *actual_extra, uint32_t timeout)\n{\n\tstruct imsg *imsg = NULL;\n\tlong ret = 0;\n\n\tif (iqueue->wstate == IQ_STAT_CLOSED)\n\t\treturn -EIO;\n\n\tif (timeout != 0) {\n\t\tret = sem_pend(&iqueue->isem, timeout);\n\t\tif (ret < 0)\n\t\t\treturn ret;\n\t}\n\n\tspin_lock(&iqueue->lock);\n\tif (!is_list_empty(&iqueue->pending_list)) {\n\t\timsg = list_first_entry(&iqueue->pending_list, struct imsg, list);\n\t\tlist_del(&imsg->list);\n\t} else {\n\t\tret = -EAGAIN;\n\t}\n\tspin_unlock(&iqueue->lock);\n\tif (ret)\n\t\treturn ret;\n\n\t/*\n\t * change the imsg's state then also check whether it\n\t * meets error.\n\t */\n\tret = cmpxchg(&imsg->state, IMSG_STATE_INIT, IMSG_STATE_IN_PROCESS);\n\tif (ret != IMSG_STATE_INIT)\n\t\treturn -EIO;\n\n\t/*\n\t * read the data from this task. if the task's data is wrong\n\t * wake up this write task directly. otherwise mask this task\n\t * as current pending task and waitting for reply.\n\t */\n\tret = kobject_copy_ipc_payload(current, imsg->data,\n\t\t\tactual_data, actual_extra, 1, 0);\n\tif (ret < 0) {\n\t\timsg->retcode = ret;\n\t\tsmp_wmb();\n\t\timsg->submit = 1;\n\n\t\twake(&imsg->ievent, 0);\n\t\treturn -EAGAIN;\n\t}\n\n\tspin_lock(&iqueue->lock);\n\tlist_add_tail(&iqueue->processing_list, &imsg->list);\n\tret = imsg->token;\n\timsg->submit = 1;\n\tspin_unlock(&iqueue->lock);\n\n\treturn ret;\n}\n\nlong iqueue_send(struct iqueue *iqueue, void __user *data, size_t data_size,\n\t\tvoid __user *extra, size_t extra_size, uint32_t timeout)\n{\n\tstruct poll_struct *ps = iqueue->kobj->poll_struct;\n\tstruct imsg imsg;\n\tlong ret, status;\n\n\t/*\n\t * setup the information which the task need waitting for\n\t * for. If the kobject has been closed, return directly.\n\t */\n\tspin_lock(&iqueue->lock);\n\tif (iqueue->rstate == IQ_STAT_CLOSED) {\n\t\tspin_unlock(&iqueue->lock);\n\t\treturn -EOTHERSIDECLOSED;\n\t}\n\timsg_init(&imsg, current);\n\tlist_add_tail(&iqueue->pending_list, &imsg.list);\n\tspin_unlock(&iqueue->lock);\n\n\t/*\n\t * if the releated kobject event is not polled, try\n\t * to wake up the reading task.\n\t */\n\tret = poll_event_send(ps, EV_IN);\n\tif (ret == -EAGAIN)\n\t\tsem_post(&iqueue->isem);\n\n\tret = wait_event(&imsg.ievent, imsg.token == 0, timeout);\n\tif (ret == 0)\n\t\treturn imsg.retcode;\n\n\tstatus = cmpxchg(&imsg.state, IMSG_STATE_INIT, IMSG_STATE_ERROR);\n\tif (status == IMSG_STATE_INIT)\n\t\tgoto out;\n\n\t/*\n\t * wait read task to finish the processing of this request.\n\t */\n\twhile (imsg.submit == 0)\n\t\tsched();\nout:\n\t/*\n\t * the writer has been teminated or timedout, need delete\n\t * this request from the pending list or processing list.\n\t */\n\tspin_lock(&iqueue->lock);\n\tif (current->list.next != NULL) {\n\t\tlist_del(&imsg.list);\n\t\tret = 0;\n\t} else {\n\t\tret = -EAGAIN;\n\t}\n\tspin_unlock(&iqueue->lock);\n\n\t/*\n\t * rewait if the msg can be handled.\n\t */\n\tif (ret)\n\t\tret = wait_event(&imsg.ievent, imsg.token == 0, timeout);\n\n\treturn imsg.retcode;\n}\n\nint iqueue_reply(struct iqueue *iqueue, right_t right,\n\t\tlong token, long errno, handle_t fd, right_t fd_right)\n{\n\tstruct imsg *imsg, *tmp;\n\tstruct task *task;\n\n\t/*\n\t * find the task who are waitting the reply token, and wake\n\t * up it with the error code.\n\t */\n\tspin_lock(&iqueue->lock);\n\tlist_for_each_entry_safe(imsg, tmp, &iqueue->processing_list, list) {\n\t\tif (imsg->token == token) {\n\t\t\tlist_del(&imsg->list);\n\t\t\tbreak;\n\t\t}\n\t}\n\tspin_unlock(&iqueue->lock);\n\n\tif (!imsg)\n\t\treturn -ENOENT;\n\n\tif (fd > 0) {\n\t\ttask = (struct task *)imsg->data;\n\t\terrno = send_handle(current_proc, task_to_proc(task), fd, fd_right);\n\t}\n\n\timsg->retcode = errno;\n\tsmp_wmb();\n\timsg->token = 0;\n\n\twake(&imsg->ievent, 0);\n\n\treturn 0;\n}\n\nstatic void wake_all_writer(struct iqueue *iqueue, int errno)\n{\n\tstruct imsg *imsg, *tmp;\n\n\tspin_lock(&iqueue->lock);\n\tlist_for_each_entry_safe(imsg, tmp, &iqueue->pending_list, list) {\n\t\tlist_del(&imsg->list);\n\t\timsg->token = 0;\n\t\twake_abort(&imsg->ievent);\n\t}\n\n\tlist_for_each_entry_safe(imsg, tmp, &iqueue->processing_list, list) {\n\t\tlist_del(&imsg->list);\n\t\timsg->token = 0;\n\t\twake_abort(&imsg->ievent);\n\t}\n\tspin_unlock(&iqueue->lock);\n}\n\nint iqueue_close(struct iqueue *iqueue, right_t right, struct process *proc)\n{\n\tif (right & KOBJ_RIGHT_READ) {\n\t\tiqueue->rstate = IQ_STAT_CLOSED;\n\t\tsmp_wmb();\n\t\twake_all_writer(iqueue, -EIO);\n\t} else if (right & KOBJ_RIGHT_WRITE){\n\t\tif (!iqueue->mutil_writer) {\n\t\t\tiqueue->wstate = IQ_STAT_CLOSED;\n\t\t\tsmp_wmb();\n\t\t\t/*\n\t\t\t * Fix me, need to fix race condition.\n\t\t\t */\n\t\t\tsem_pend_abort(&iqueue->isem, OS_EVENT_OPT_BROADCAST);\n\t\t}\n\t}\n\n\treturn 0;\n}\n\nvoid iqueue_init(struct iqueue *iq, int mutil_writer, struct kobject *kobj)\n{\n\tASSERT((iq != NULL) && (kobj != NULL));\n\tiq->mutil_writer = !!mutil_writer;\n\tiq->kobj = kobj;\n\tspin_lock_init(&iq->lock);\n\tinit_list(&iq->pending_list);\n\tinit_list(&iq->processing_list);\n\tsem_init(&iq->isem, 0);\n}\n"
  },
  {
    "path": "kernel/userspace/irq.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/mm.h>\n#include <minos/sched.h>\n#include <minos/irq.h>\n#include <uspace/poll.h>\n#include <uspace/kobject.h>\n#include <uspace/uaccess.h>\n#include <uspace/proc.h>\n\nstruct irq_event {\n\tstruct kobject kobj;\n\tstruct irq_desc *idesc;\n\tstruct event event;\n\tstruct poll_event_kernel poll_event;\n};\n\n#define kobj_to_irq_event(kobj) (struct irq_event *)kobj->data\n\n#define IRQ_RIGHT\tKOBJ_RIGHT_RW\n#define IRQ_RIGHT_MASK\t(0)\n\nstatic int do_handle_userspace_irq(uint32_t irq, void *data)\n{\n\tstruct irq_event *ievent = (struct irq_event *)data;\n\tstruct kobject *kobj = &ievent->kobj;\n\tstruct irq_desc *idesc = ievent->idesc;\n\tstruct poll_struct *ps = kobj->poll_struct;\n\n\tASSERT(idesc != NULL);\n\tirq_mask(irq);\n\n\t/*\n\t * Whether this irq has been listened. If this irq is polled\n\t * by one process, just send an event to the task.\n\t */\n\tif (event_is_polled(ps, EV_IN)) {\n\t\tpoll_event_send_static(ps->pevents[EV_IN], &ievent->poll_event);\n\t\treturn 0;\n\t} else {\n\t\tset_bit(IRQ_FLAGS_PENDING_BIT, &idesc->flags);\n\t\tsmp_wmb();\n\n\t\treturn wake(&ievent->event, 0);\n\t}\n}\n\nstatic inline int request_user_irq(uint32_t irq, unsigned long flags, void *pdata)\n{\n\treturn request_irq(irq, do_handle_userspace_irq, flags | IRQ_FLAGS_USER,\n\t\t\tcurrent->name, pdata);\n}\n\nstatic int irq_kobj_open(struct kobject *kobj, handle_t handle, right_t rigt)\n{\n\tstruct irq_event *ievent = kobj_to_irq_event(kobj);\n\tstruct irq_desc *idesc = ievent->idesc;\n\n\treturn request_user_irq(idesc->hno, idesc->flags, ievent);\n}\n\nstatic long irq_kobj_read(struct kobject *kobj, void __user *data,\n\t\tsize_t data_size, size_t *actual_data, void __user *extra,\n\t\tsize_t extra_size, size_t *actual_extra, uint32_t timeout)\n{\n\tstruct irq_event *ievent = kobj_to_irq_event(kobj);\n\tstruct irq_desc *idesc = ievent->idesc;\n\tlong ret = 0;\n\n\tif (event_is_polled(kobj->poll_struct, EV_IN))\n\t\treturn -EPERM;\n\n\tret = wait_event(&ievent->event,\n\t\t\ttest_and_clear_bit(IRQ_FLAGS_PENDING_BIT, &idesc->flags),\n\t\t\ttimeout);\n\tif (ret == 0)\n\t\tclear_bit(IRQ_FLAGS_PENDING_BIT, &idesc->flags);\n\n\treturn ret;\n}\n\nstatic long irq_kobj_write(struct kobject *kobj, void __user *data,\n\t\tsize_t data_size, void __user *extra,\n\t\tsize_t extra_size, uint32_t timeout)\n{\n\tstruct irq_event *ievent = kobj_to_irq_event(kobj);\n\n\tirq_unmask(ievent->idesc->hno);\n\n\treturn 0;\n}\n\nstatic int irq_kobj_close(struct kobject *kobj, right_t right, struct process *proc)\n{\n\treturn 0;\n}\n\nstatic struct kobject_ops irq_kobj_ops = {\n\t.open\t= irq_kobj_open,\n\t.recv\t= irq_kobj_read,\n\t.send\t= irq_kobj_write,\n\t.close\t= irq_kobj_close,\n};\n\nint irq_kobject_create(struct kobject **rkobj, right_t *right, unsigned long data)\n{\n\t/*\n\t * data[0-15] : the irq number.\n\t * data[16-31] : the irq flags\n\t */\n\tuint32_t irqnum = data & 0xffff;\n\tunsigned long flags = (data >> 16) & 0xffff;\n\tstruct irq_event *ievent;\n\tstruct irq_desc *idesc;\n\n\t/*\n\t * only root service can create an irq kobject.\n\t */\n\tif (!proc_can_hwctl(current_proc))\n\t\treturn -EPERM;\n\n\tif ((irqnum < SPI_IRQ_BASE) || (irqnum > BAD_IRQ))\n\t\treturn -EINVAL;\n\n\tidesc = get_irq_desc(irqnum);\n\tif (!idesc)\n\t\treturn -ENOENT;\n\n\tievent = zalloc(sizeof(struct irq_event));\n\tif (!ievent)\n\t\treturn -ENOMEM;\n\n\tevent_init(&ievent->event, OS_EVENT_TYPE_IRQ, ievent);\n\tievent->poll_event.event.events = POLLIN;\n\tievent->poll_event.event.data.type = 0;\n\n\tievent->idesc = idesc;\n\tidesc->flags = flags;\n\tidesc->hno = irqnum;\n\n\tkobject_init(&ievent->kobj, KOBJ_TYPE_IRQ,\n\t\t\tIRQ_RIGHT_MASK, (unsigned long)ievent);\n\tievent->kobj.ops = &irq_kobj_ops;\n\t*rkobj = &ievent->kobj;\n\t*right = IRQ_RIGHT;\n\n\treturn 0;\n}\nDEFINE_KOBJECT(irq, KOBJ_TYPE_IRQ, irq_kobject_create);\n"
  },
  {
    "path": "kernel/userspace/kobject.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/task.h>\n#include <uspace/poll.h>\n#include <uspace/kobject.h>\n\nstatic kobject_create_cb kobj_create_cbs[KOBJ_TYPE_MAX];\n\nstatic void register_kobject_type(kobject_create_cb ops, int type)\n{\n\tBUG_ON(!ops || (type >= KOBJ_TYPE_MAX));\n\n\tif (kobj_create_cbs[type] != NULL)\n\t\tpr_warn(\"overwrite kobject ops for %d\\n\", type);\n\tkobj_create_cbs[type] = ops;\n}\n\nstatic void kobject_release(struct kobject *kobj)\n{\n\t/*\n\t * release poll_struct if needed.\n\t */\n\trelease_poll_struct(kobj);\n\n\tif (kobj->ops && kobj->ops->release)\n\t\tkobj->ops->release(kobj);\n}\n\nint kobject_get(struct kobject *kobj)\n{\n\tint old;\n\n\tif (!kobj)\n\t\treturn 0;\n\n\told = atomic_inc_if_postive(&kobj->ref);\n\tASSERT(old >= 0);\n\n\treturn 1;\n}\n\nint kobject_put(struct kobject *kobj)\n{\n\tint old;\n\n\tif (!kobj)\n\t\treturn 0;\n\n\told = atomic_dec_set_negtive_if_zero(&kobj->ref);\n\tASSERT(old > 0);\n\n\t/*\n\t * if the old value is 1, then release the kobject.\n\t */\n\tif (old == 1)\n\t\tkobject_release(kobj);\n\n\treturn 1;\n}\n\nvoid kobject_init(struct kobject *kobj, int type,\n\t\tright_t right_mask, unsigned long data)\n{\n\n\tBUG_ON((!kobj));\n\tkobj->right_mask = right_mask;\n\tkobj->type = type;\n\tkobj->data = data;\n\tkobj->list.pre = NULL;\n\tkobj->list.next = NULL;\n\tspin_lock_init(&kobj->lock);\n}\n\nint kobject_create(int type, struct kobject **kobj, right_t *right, unsigned long data)\n{\n\tkobject_create_cb ops;\n\n\tif ((type <= 0) || (type >= KOBJ_TYPE_MAX))\n\t\treturn -ENOENT;\n\n\tops = kobj_create_cbs[type];\n\tif (!ops)\n\t\treturn -EOPNOTSUPP;\n\n\treturn ops(kobj, right, data);\n}\n\nint kobject_poll(struct kobject *ksrc, struct kobject *kdst, int event, bool enable)\n{\n\tif (ksrc->ops && ksrc->ops->poll)\n\t\treturn ksrc->ops->poll(ksrc, kdst, event, enable);\n\telse\n\t\treturn 0;\n}\n\nint kobject_open(struct kobject *kobj, handle_t handle, right_t right)\n{\n\tint ret;\n\n\tif (!kobj->ops || !kobj->ops->open)\n\t\treturn 0;\n\n\tret = kobj->ops->open(kobj, handle, right);\n\tif (ret)\n\t\treturn ret;\n\n\tif (right & KOBJ_RIGHT_WRITE)\n\t\tpoll_event_send(kobj->poll_struct, EV_WOPEN);\n\telse\n\t\tpoll_event_send(kobj->poll_struct, EV_ROPEN);\n\n\treturn 0;\n}\n\nint kobject_close(struct kobject *kobj, right_t right, struct process *proc)\n{\n\tint ret = 0;\n\n\t/*\n\t * just put this kobject if the right is 0.\n\t */\n\tif (right == KOBJ_RIGHT_NONE) {\n\t\tkobject_put(kobj);\n\t\treturn 0;\n\t}\n\n\tif (kobj->ops && kobj->ops->close)\n\t\tret = kobj->ops->close(kobj, right, proc);\n\n\t/*\n\t * send the close event to the poller if need.\n\t */\n\tif (right & KOBJ_RIGHT_WRITE)\n\t\tpoll_event_send(kobj->poll_struct, EV_WCLOSE);\n\telse if (right & KOBJ_RIGHT_READ)\n\t\tpoll_event_send(kobj->poll_struct, EV_RCLOSE);\n\n\t/*\n\t * dec the refcount which caused by kobject_init and\n\t * kobject_connect.\n\t */\n\tkobject_put(kobj);\n\n\treturn ret;\n}\n\nlong kobject_recv(struct kobject *kobj, void __user *data, size_t data_size,\n\t\tsize_t *actual_data, void __user *extra, size_t extra_size,\n\t\tsize_t *actual_extra, uint32_t timeout)\n{\n\tif (!kobj->ops || !kobj->ops->recv)\n\t\treturn -EACCES;\n\n\t/*\n\t * before read, if there is task waitting the event\n\t * to be read, here can send EV_OUT event to notify\n\t * the target task to send new data.\n\t */\n\tpoll_event_send(kobj->poll_struct, EV_OUT);\n\n\treturn kobj->ops->recv(kobj, data, data_size, actual_data,\n\t\t\textra, extra_size, actual_extra, timeout);\n}\n\nlong kobject_send(struct kobject *kobj, void __user *data, size_t data_size,\n\t\tvoid __user *extra, size_t extra_size, uint32_t timeout)\n{\n\tif (!kobj->ops || !kobj->ops->send)\n\t\treturn -EACCES;\n\t/*\n\t * the poll event must called by the kobject itself\n\t */\n\treturn kobj->ops->send(kobj, data, data_size, extra,\n\t\t\textra_size, timeout);\n}\n\nint kobject_reply(struct kobject *kobj, right_t right, unsigned long token,\n\t\tlong err_code, handle_t fd, right_t fd_right)\n{\n\tif (!kobj->ops || !kobj->ops->reply)\n\t\treturn -EPERM;\n\n\treturn kobj->ops->reply(kobj, right, token, err_code, fd, fd_right);\n}\n\nint kobject_munmap(struct kobject *kobj, right_t right)\n{\n\tif (!kobj->ops || !kobj->ops->munmap)\n\t\treturn -EPERM;\n\n\treturn kobj->ops->munmap(kobj, right);\n}\n\nint kobject_mmap(struct kobject *kobj, right_t right,\n\t\tvoid **addr, unsigned long *msize)\n{\n\tif (!kobj->ops || !kobj->ops->mmap)\n\t\treturn -EPERM;\n\n\treturn kobj->ops->mmap(kobj, right, addr, msize);\n}\n\nlong kobject_ctl(struct kobject *kobj, right_t right,\n\t\tint req, unsigned long data)\n{\n\tif (!kobj->ops || !kobj->ops->ctl)\n\t\treturn -EPERM;\n\n\treturn kobj->ops->ctl(kobj, req, data);\n}\n\nstatic int kobject_subsystem_init(void)\n{\n\textern unsigned long __kobject_desc_start;\n\textern unsigned long __kobject_desc_end;\n\tstruct kobject_desc *desc;\n\n\tsection_for_each_item(__kobject_desc_start, __kobject_desc_end, desc) {\n\t\tif (desc->type >= KOBJ_TYPE_MAX) {\n\t\t\tpr_err(\"Unsupported kobject type [%d] name [%s]\\n\",\n\t\t\t\t\tdesc->type, desc->name);\n\t\t\tcontinue;\n\t\t}\n\n\t\tpr_notice(\"Register kobject type [%2d] name [%s]\\n\",\n\t\t\t\tdesc->type, desc->name);\n\t\tregister_kobject_type(desc->ops, desc->type);\n\t}\n\n\treturn 0;\n}\nsubsys_initcall(kobject_subsystem_init);\n"
  },
  {
    "path": "kernel/userspace/kobject_copy.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <uspace/kobject.h>\n#include <uspace/uaccess.h>\n#include <uspace/proc.h>\n\nstruct kobject_rw_arg {\n\tvoid __user *data;\n\tsize_t data_size;\n};\n\nstruct syscall_regs {\n\tunsigned long a0;\n\tunsigned long a1;\n\tunsigned long a2;\n\tunsigned long a3;\n\tunsigned long a4;\n\tunsigned long a5;\n\tunsigned long a6;\n\tunsigned long a7;\n};\n\nstatic inline struct syscall_regs *task_syscall_regs(struct task *task)\n{\n\treturn (struct syscall_regs *)&task->user_regs->x0;\n}\n\nssize_t kobject_copy_ipc_data(struct task *tdst, struct task *tsrc, int check_size)\n{\n\tstruct syscall_regs *src_regs, *dst_regs;\n\tvoid __user *dst, *src;\n\tsize_t dsize, ssize;\n\tsize_t copy;\n\n\tsrc_regs = task_syscall_regs(tsrc);\n\tsrc = (void *)src_regs->a1;\n\tssize = (size_t)src_regs->a2;\n\n\tdst_regs = task_syscall_regs(tdst);\n\tdst = (void *)dst_regs->a1;\n\tdsize = (size_t)dst_regs->a2;\n\n\tif (check_size && (dsize != ssize))\n\t\treturn -EINVAL;\n\n\tcopy = MIN(dsize, ssize);\n\tif (copy == 0)\n\t\treturn 0;\n\n\treturn copy_user_to_user(tdst->vs, dst, tsrc->vs, src, copy);\n}\n\nssize_t kobject_copy_extra_data(struct task *tdst, struct task *tsrc, int check_size)\n{\n\tstruct syscall_regs *src_regs, *dst_regs;\n\tvoid __user *dst, *src;\n\tsize_t dsize, ssize;\n\tsize_t copy;\n\n\tsrc_regs = task_syscall_regs(tsrc);\n\tsrc = (void *)src_regs->a3;\n\tssize = (size_t)src_regs->a4;\n\n\tdst_regs = task_syscall_regs(tdst);\n\tdst = (void *)dst_regs->a3;\n\tdsize = (size_t)dst_regs->a4;\n\n\tif (check_size && (dsize != ssize))\n\t\treturn -EINVAL;\n\n\tcopy = MIN(dsize, ssize);\n\tif (copy == 0)\n\t\treturn 0;\n\n\treturn copy_user_to_user(tdst->vs, dst, tsrc->vs, src, copy);\n}\n\nssize_t kobject_copy_ipc_payload(struct task *dtsk, struct task *ttsk,\n\t\tsize_t *actual_data, size_t *actual_extra,\n\t\tint check_data, int check_extra)\n{\n\tssize_t ret;\n\n\tret = kobject_copy_ipc_data(dtsk, ttsk, check_data);\n\tif (ret < 0)\n\t\treturn ret;\n\t*actual_data = ret;\n\n\tret = kobject_copy_extra_data(dtsk, ttsk, check_extra);\n\tif (ret >= 0) {\n\t\t*actual_extra = ret;\n\t\tret = 0;\n\t}\n\n\treturn ret;\n}\n"
  },
  {
    "path": "kernel/userspace/kobject_copy.h",
    "content": "#ifndef __MINOS_KOBJECT_COPY_H__\n#define __MINOS_KOBJECT_COPY_H__\n\nssize_t kobject_copy_ipc_data(struct task *tdst,\n\t\tstruct task *tsrc, int check_size);\n\nssize_t kobject_copy_extra_data(struct task *tdst,\n\t\tstruct task *tsrc, int check_size);\n\nssize_t kobject_copy_ipc_payload(struct task *dtsk, struct task *ttsk,\n\t\tsize_t *actual_data, size_t *actual_extra,\n\t\tint check_data, int check_extra);\n\n#endif\n"
  },
  {
    "path": "kernel/userspace/notify.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/mm.h>\n#include <minos/sched.h>\n#include <uspace/poll.h>\n#include <uspace/kobject.h>\n#include <uspace/uaccess.h>\n\n#define NOTIFY_RIGHT\t\t(KOBJ_RIGHT_RW)\n#define NOTIFY_RIGHT_MASK\t(KOBJ_RIGHT_READ)\n\nstatic long notify_kobj_send(struct kobject *kobj, void __user *data,\n\t\t\tsize_t data_size, void __user *extra,\n\t\t\tsize_t extra_size, uint32_t timeout)\n{\n\tunsigned long msg[3];\n\tint ret;\n\n\tif (extra_size > sizeof(msg))\n\t\treturn -E2BIG;\n\n\tmemset(msg, 0, sizeof(msg));\n\tret = copy_from_user(msg, extra, extra_size);\n\tif (ret < 0)\n\t\treturn ret;\n\n\tpoll_event_send_with_data(kobj->poll_struct, EV_IN, 0,\n\t\t\tmsg[0], msg[1], msg[2]);\n\n\treturn 0;\n}\n\nstruct kobject_ops notify_kobj_ops = {\n\t.send\t\t= notify_kobj_send,\n};\n\nint notify_create(struct kobject **kobjr, right_t *right, unsigned long data)\n{\n\tstruct kobject *kobj;\n\n\tkobj = zalloc(sizeof(struct kobject));\n\tif (!kobj)\n\t\treturn -ENOMEM;\n\n\tkobject_init(kobj, KOBJ_TYPE_NOTIFY, NOTIFY_RIGHT_MASK, 0);\n\tkobj->ops = &notify_kobj_ops;\n\t*kobjr = kobj;\n\t*right = NOTIFY_RIGHT;\n\n\treturn 0;\n}\nDEFINE_KOBJECT(notify, KOBJ_TYPE_NOTIFY, notify_create);\n"
  },
  {
    "path": "kernel/userspace/pma.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/mm.h>\n#include <minos/sched.h>\n#include <uspace/vspace.h>\n#include <uspace/kobject.h>\n#include <uspace/uaccess.h>\n#include <uspace/proc.h>\n\n#define PMA_RIGHT\t(KOBJ_RIGHT_CTL | KOBJ_RIGHT_MMAP | KOBJ_RIGHT_RWX)\n#define PMA_RIGHT_MASK\t(KOBJ_RIGHT_CTL | KOBJ_RIGHT_MMAP | KOBJ_RIGHT_RWX)\n\nstruct pma_mapping_entry {\n\tunsigned long virt;\n\tsize_t size;\n\tstruct list_head list;\n\tstruct process *mapper;\t\t// who exected this action.\n\tstruct process *proc;\t\t// mapped at where.\n};\n\n/*\n * create_pma();\n * map_pma(-1, handle, unsigned long base, unsigned long end). // map to self\n * read_data();\n * map_pma(process_handle, handle, unsigned long base, unsigned end); // map to target\n * destroy_pma();\n */\nstruct pma {\n\tunsigned long vmflags;\n\tstruct kobject kobj;\n\tstruct list_head head;\n\tspinlock_t lock;\n\tuint8_t type;\n\tuint8_t consequent;\n\n\t/*\n\t * if the PMA is shared, the memory region will mapped\n\t * to the shared memory region of the process. if the\n\t * PMA is privated and created by the root service to\n\t * map the elf or other section of a process\n\t *\n\t * when the PMA can be shared by other process, it will\n\t * allocated consecutive memory region, so the normal process\n\t * can map it to its shared memory region, since the normal\n\t * memory region can not get its virtual address information.\n\t */\n\tunsigned long pstart;\n\tunsigned long pend;\n\tunsigned long psize;\n\tstruct page *page_list;\n};\n\nstatic void free_pma_pages(struct page *head)\n{\n\tstruct page *tmp = head;\n\tstruct page *next;\n\n\twhile (tmp) {\n\t\tnext = tmp->next;\n\t\t__free_pages(tmp);\n\t\ttmp = next;\n\t}\n}\n\nstatic void free_pma_memory(struct pma *p)\n{\n\tBUG_ON((p->pstart != 0) && (p->page_list != NULL));\n\n\tif (p->vmflags & __VM_PFNMAP)\n\t\treturn;\n\n\tif (p->pstart) {\n\t\tif (p->type == PMA_TYPE_KCACHE)\n\t\t\tfree_pages((void *)p->pstart);\n\t\telse\n\t\t\tfree_pages((void *)pa2va(p->pstart));\n\t} else {\n\t\tfree_pma_pages(p->page_list);\n\t}\n}\n\nstatic int pma_mmap(struct kobject *kobj, right_t right,\n\t\tvoid **addr, unsigned long *msize)\n{\n\tstruct pma *p = (struct pma *)kobj->data;\n\tunsigned long vstart, pstart, size;\n\n\tif (!p->pstart)\n\t\treturn -EPERM;\n\n\t/*\n\t * TBD\n\t */\n\tvstart = PAGE_ALIGN(pa2sva(p->pstart));\n\tpstart = PAGE_ALIGN(p->pstart);\n\tsize = PAGE_BALIGN(p->pstart + p->psize) - pstart;\n\n\tif (map_process_memory(current_proc, vstart, size, pstart, p->vmflags))\n\t\treturn -EFAULT;\n\n\t*addr = (void *)pa2sva(p->pstart);\n\t*msize = p->psize;\n\n\treturn 0;\n}\n\nstatic int pma_munmap(struct kobject *kobj, right_t right)\n{\n\tstruct pma *p = (struct pma *)kobj->data;\n\tunsigned long vstart, size;\n\n\tif (!p->pstart)\n\t\treturn -EPERM;\n\n\tvstart = PAGE_ALIGN(pa2sva(p->pstart));\n\tsize = PAGE_BALIGN(vstart + p->psize) - vstart;\n\n\treturn unmap_process_memory(current_proc, vstart, size);\n}\n\nstatic int pma_close(struct kobject *kobj, right_t right,\n\t\tstruct process *proc)\n{\n\tstruct pma *p = (struct pma *)kobj->data;\n\tstruct pma_mapping_entry *pme, *tmp;\n\tint ret;\n\n\tspin_lock(&p->lock);\n\tlist_for_each_entry_safe(pme, tmp, &p->head, list) {\n\t\tif (pme->mapper != proc)\n\t\t\tcontinue;\n\n\t\tlist_del(&pme->list);\n\t\tret = unmap_process_memory(pme->proc, pme->virt, pme->size);\n\t\tfree(pme);\n\t\tWARN_ON(ret, \"unmap pma in %d failed\\n\", proc->pid);\n\t}\n\tspin_unlock(&p->lock);\n\n\tif (!p->pstart)\n\t\treturn 0;\n\telse\n\t\treturn unmap_process_memory(proc, pa2sva(p->pstart), p->psize);\n}\n\nstatic void *__sys_pma_map(struct pma *p, struct process *proc,\n\t\tunsigned long virt, size_t size)\n{\n\tstruct page *page = p->page_list;\n\tunsigned long start = virt;\n\tstruct pma_mapping_entry *pme;\n\tint ret;\n\n\tsize = (size > p->psize) ? p->psize : size;\n\tpme = zalloc(sizeof(struct pma_mapping_entry));\n\tif (!pme)\n\t\treturn ERROR_PTR(-ENOMEM);\n\tpme->virt = virt;\n\tpme->size = size;\n\tpme->mapper = current_proc;\n\tpme->proc = proc;\n\n\tif (p->pstart) {\n\t\tret = map_process_memory(proc, start,\n\t\t\t\tsize, p->pstart, p->vmflags);\n\t} else {\n\t\tdo {\n\t\t\tret = map_process_memory(proc, start,\n\t\t\t\t\tPAGE_SIZE,page_pa(page), p->vmflags);\n\t\t\tif (ret)\n\t\t\t\tbreak;\n\t\t\tpage = page->next;\n\t\t\tstart += PAGE_SIZE;\n\t\t\tsize -= PAGE_SIZE;\n\t\t} while (size > 0);\n\t}\n\n\tif (ret) {\n\t\tfree(pme);\n\t\tunmap_process_memory(proc, virt, size);\n\t\treturn ERROR_PTR(ret);\n\t}\n\n\t/*\n\t * allocate a mapping entry to record the mapping info.\n\t * pme->proc is set to the process who map this memory\n\t * sice only root service will call sys_map.\n\t */\n\tspin_lock(&p->lock);\n\tlist_add_tail(&p->head, &pme->list);\n\tspin_unlock(&p->lock);\n\n\treturn (void *)pme->virt;\n}\n\nstatic int __sys_pma_unmap(struct pma *p, struct process *proc,\n\t\tunsigned long virt, size_t size)\n{\n\tstruct pma_mapping_entry *entry, *tmp, *out = NULL;\n\n\tspin_lock(&p->lock);\n\tlist_for_each_entry_safe(entry, tmp, &p->head, list) {\n\t\tif ((entry->mapper == current_proc) &&\n\t\t\t\t(entry->proc == proc) &&\n\t\t\t\t(entry->virt == virt) &&\n\t\t\t\t(entry->size == size)) {\n\t\t\tlist_del(&entry->list);\n\t\t\tout = entry;\n\t\t\tbreak;\n\t\t}\n\t}\n\tspin_unlock(&p->lock);\n\n\tif (!out)\n\t\treturn -ENOENT;\n\n\tunmap_process_memory(proc, virt, size);\n\tfree(out);\n\n\treturn 0;\n}\n\nstatic int sys_handle_pma(handle_t proc_handle, handle_t pma_handle,\n\t\tunsigned long virt, size_t size, right_t right, int map)\n{\n\tright_t right_proc, right_pma;\n\tstruct kobject *kobj_proc = NULL;\n\tstruct kobject *kobj_pma = NULL;\n\tstruct process *proc;\n\tint ret = -EACCES;\n\tvoid *addr;\n\n\t/*\n\t * only the root service can map a pma to other process's\n\t * vspace.\n\t */\n\tif (proc_handle != -1) {\n\t\tif (!proc_is_root(current_proc))\n\t\t\treturn -EPERM;\n\n\t\tret = get_kobject(proc_handle, &kobj_proc, &right_proc);\n\t\tif (ret)\n\t\t\treturn -ENOENT;\n\n\t\tif (kobj_proc->type != KOBJ_TYPE_PROCESS) {\n\t\t\tkobject_put(kobj_proc);\n\t\t\treturn -EBADF;\n\t\t}\n\t\tproc = (struct process *)kobj_proc->data;\n\t} else {\n\t\tproc = current_proc;\n\t}\n\n\tret = get_kobject(pma_handle, &kobj_pma, &right_pma);\n\tif (ret) {\n\t\tret = -ENOENT;\n\t\tgoto out_pma_kobj;\n\t}\n\n\tif (kobj_pma->type != KOBJ_TYPE_PMA) {\n\t\tret = -EBADF;\n\t\tgoto out;\n\t}\n\n\tif (map) {\n\t\taddr = __sys_pma_map((struct pma *)kobj_pma->data, proc,\n\t\t\t\tvirt, size);\n\t\tif (IS_ERROR_PTR(addr))\n\t\t\tret = (int)(unsigned long)addr;\n\t} else {\n\t\tret = __sys_pma_unmap((struct pma *)kobj_pma->data, proc,\n\t\t\t\tvirt, size);\n\t}\n\nout:\n\tput_kobject(kobj_pma);\nout_pma_kobj:\n\tif (kobj_proc)\n\t\tput_kobject(kobj_proc);\n\n\treturn ret;\n}\n\nint sys_map_pma(handle_t proc_handle, handle_t pma_handle,\n\t\tunsigned long virt, size_t size, right_t right)\n{\n\treturn sys_handle_pma(proc_handle, pma_handle, virt, size, right, 1);\n}\n\nint sys_unmap_pma(handle_t proc_handle, handle_t pma_handle,\n\t\tunsigned long virt, size_t size)\n{\n\treturn sys_handle_pma(proc_handle, pma_handle, virt, size, 0, 0);\n}\n\nstatic void pma_release(struct kobject *kobj)\n{\n\tstruct pma *p = (struct pma *)kobj->data;\n\n\tif (!is_list_empty(&p->head)) {\n\t\tpr_err(\"pma busy memleak error!\\n\");\n\t\treturn;\n\t}\n\n\tfree_pma_memory(p);\n\tfree(p);\n}\n\nstatic int pma_add_pages(struct kobject *kobj, int pages)\n{\n\tstruct pma *p = (struct pma *)kobj->data;\n\tstruct page *page;\n\tstruct page *head = NULL;\n\tstruct page *tail = NULL;\n\tint i;\n\n\tif ((pages <= 0) || (p->type != PMA_TYPE_NORMAL))\n\t\treturn -EINVAL;\n\n\tif (p->consequent)\n\t\treturn -EPERM;\n\n\tfor (i = 0; i < pages; i++) {\n\t\tpage = alloc_pages(1, GFP_USER);\n\t\tif (!page) {\n\t\t\tfree_pma_pages(head);\n\t\t\treturn -ENOMEM;\n\t\t}\n\n\t\tpage->next = head;\n\t\thead = page;\n\n\t\tif (tail == NULL)\n\t\t\ttail = page;\n\t}\n\n\t/*\n\t * insert the new pages to the pma\n\t */\n\tspin_lock(&p->lock);\n\ttail->next = p->page_list;\n\tp->page_list = head;\n\tp->psize += pages << PAGE_SHIFT;\n\tspin_unlock(&p->lock);\n\n\treturn 0;\n}\n\nstatic long pma_get_size(struct kobject *kobj)\n{\n\tstruct pma *p = (struct pma *)kobj->data;\n\n\treturn p->psize;\n}\n\nstatic long pma_ctl(struct kobject *kobj, int req, unsigned long data)\n{\n\tint ret;\n\n\tswitch (req) {\n\tcase KOBJ_PMA_ADD_PAGES:\n\t\tret = pma_add_pages(kobj, (int)data);\n\t\tbreak;\n\tcase KOBJ_PMA_GET_SIZE:\n\t\treturn pma_get_size(kobj);\n\tdefault:\n\t\tret = -ENOSYS;\n\t\tpr_err(\"unknow action 0x%x for pma kobject\\n\", req);\n\t\tbreak;\n\t}\n\n\treturn ret;\n}\n\nstatic long pma_write(struct kobject *kobj, void __user *data, size_t data_size,\n\t\tvoid __user *extra, size_t extra_size, uint32_t timeout)\n{\n\tstruct pma *p = (struct pma *)kobj->data;\n\n\tif (p->type != PMA_TYPE_KCACHE)\n\t\treturn -EPERM;\n\n\tif (data_size > p->psize)\n\t\treturn -EINVAL;\n\n\treturn copy_from_user((void *)p->pstart, data, data_size);\n}\n\nstatic long pma_read(struct kobject *kobj, void __user *data, size_t data_size,\n\t\tsize_t *actual_data, void __user *extra, size_t extra_size,\n\t\tsize_t *actual_extra, uint32_t timeout)\n{\n\tstruct pma *p = (struct pma *)kobj->data;\n\n\tif (p->type != PMA_TYPE_KCACHE)\n\t\treturn -EPERM;\n\n\tif (data_size > p->psize)\n\t\treturn -EINVAL;\n\n\treturn copy_to_user(data, (void *)p->pstart, data_size);\n}\n\nstatic struct kobject_ops pma_ops = {\n\t.mmap\t\t= pma_mmap,\n\t.munmap\t\t= pma_munmap,\n\t.send\t\t= pma_write,\n\t.recv\t\t= pma_read,\n\t.ctl\t\t= pma_ctl,\n\t.release\t= pma_release,\n\t.close\t\t= pma_close,\n};\n\nstatic inline unsigned long pma_flags(int type, right_t right)\n{\n\tunsigned long flags = 0;\n\n\tif (right & KOBJ_RIGHT_READ)\n\t\tflags |= __VM_READ;\n\tif (right & KOBJ_RIGHT_WRITE)\n\t\tflags |= __VM_WRITE;\n\tif (right & KOBJ_RIGHT_EXEC)\n\t\tflags |= __VM_EXEC;\n\n\tWARN_ON(flags == 0, \"request pma with no access right\\n\");\n\n\tif (type == PMA_TYPE_DMA)\n\t\tflags |= __VM_IO;\n\telse if (type == PMA_TYPE_MMIO)\n\t\tflags |= __VM_PFNMAP | __VM_IO;\n\telse if (type == PMA_TYPE_PMEM)\n\t\tflags |= __VM_PFNMAP;\n\n\tflags |= VM_PMA;\n\n\treturn flags;\n}\n\nstatic int allocate_pma_memory(struct pma *p, size_t size, int type)\n{\n\tsize_t cnt = size >> PAGE_SHIFT;\n\tstruct page *page;\n\tint i;\n\n\t/*\n\t * if this PMA need to shared among in different process\n\t * allocate a continuously memory region.\n\t */\n\tif (p->consequent || (type == PMA_TYPE_DMA)) {\n\t\tp->pstart = va2pa(get_free_pages(cnt, GFP_USER));\n\t\tif (!p->pstart)\n\t\t\treturn -ENOMEM;\n\n\t\tp->psize = cnt << PAGE_SHIFT;\n\t\tp->pend = p->pstart + p->psize;\n\t\treturn 0;\n\t}\n\n\tfor (i = 0; i < cnt; i++) {\n\t\tpage = alloc_pages(1, GFP_USER);\n\t\tif (!page) {\n\t\t\tfree_pma_memory(p);\n\t\t\treturn -ENOMEM;\n\t\t}\n\n\t\tpage->next = p->page_list;\n\t\tp->page_list = page;\n\t}\n\n\treturn 0;\n}\n\nstatic int __create_new_pma(struct kobject **kobj,\n\t\tright_t *right, struct pma_create_arg *args)\n{\n\tright_t right_mask = PMA_RIGHT_MASK;\n\tright_t right_ret = PMA_RIGHT;\n\tint fixup_pmem = 0;\n\tstruct pma *p;\n\tint ret;\n\n\tif ((args->type == PMA_TYPE_MMIO) || (args->type == PMA_TYPE_PMEM)) {\n\t\tif (args->size == 0)\n\t\t\treturn -EINVAL;\n\t\tfixup_pmem = 1;\n\t}\n\n\t/*\n\t * data will be the page count of the request memory size\n\t */\n\tp = zalloc(sizeof(struct pma));\n\tif (!p)\n\t\treturn -ENOMEM;\n\n\tp->vmflags = pma_flags(args->type, args->right);\n\tif (fixup_pmem) {\n\t\tp->pstart = args->start;\n\t\tp->pend = args->start + args->size;\n\t\tp->psize = args->size;\n\t\tp->consequent = 1;\n\t} else if (args->type == PMA_TYPE_KCACHE) {\n\t\tp->pstart = (unsigned long)get_free_page(GFP_KERNEL);\n\t\tif (p->pstart == 0) {\n\t\t\tfree(p);\n\t\t\treturn -ENOMEM;\n\t\t}\n\t\tp->pend = p->pstart + PAGE_SIZE;\n\t\tp->psize = PAGE_SIZE;\n\t\tright_mask &= ~KOBJ_RIGHT_MMAP;\n\t\tright_ret &= ~KOBJ_RIGHT_MMAP;\n\t\tp->consequent = 1;\n\t} else {\n\t\tp->consequent = !!args->consequent;\n\t\tif (args->size > 0) {\n\t\t\tp->psize = args->size;\n\t\t\tret = allocate_pma_memory(p, args->size, args->type);\n\t\t\tif (ret) {\n\t\t\t\tfree(p);\n\t\t\t\treturn -ENOMEM;\n\t\t\t}\n\t\t}\n\n\t\t/*\n\t\t * if the PMA is not consequented, it can not be called\n\t\t * kobject_mmap()\n\t\t */\n\t\tif (!p->consequent) {\n\t\t\tright_mask &= ~KOBJ_RIGHT_MMAP;\n\t\t\tright_ret &= ~KOBJ_RIGHT_MMAP;\n\t\t}\n\t}\n\n\tp->type = args->type;\n\tinit_list(&p->head);\n\tspin_lock_init(&p->lock);\n\tp->kobj.ops = &pma_ops;\n\tkobject_init(&p->kobj, KOBJ_TYPE_PMA, right_mask, (unsigned long)p);\n\t*kobj = &p->kobj;\n\t*right = right_ret;\n\n\treturn 0;\n}\n\nint create_new_pma(struct kobject **kobj, right_t *right, struct pma_create_arg *args)\n{\n\treturn __create_new_pma(kobj, right, args);\n}\n\nstatic int pma_create(struct kobject **kobj, right_t *right, unsigned long data)\n{\n\tstruct pma_create_arg args;\n\tint ret;\n\n\tret = copy_from_user(&args, (void __user *)data, sizeof(struct pma_create_arg));\n\tif (ret <= 0)\n\t\treturn ret;\n\n\tif (args.type >= PMA_TYPE_MAX)\n\t\treturn -EINVAL;\n\n\tswitch (args.type) {\n\tcase PMA_TYPE_DMA:\n\tcase PMA_TYPE_MMIO:\n\tcase PMA_TYPE_PMEM:\n\t\tif (!proc_can_vmctl(current_proc))\n\t\t\treturn -EPERM;\n\t\tbreak;\n\tcase PMA_TYPE_KCACHE:\n\t\tif (args.size > PAGE_SIZE)\n\t\t\treturn -E2BIG;\n\t\tbreak;\n\tcase PMA_TYPE_NORMAL:\n\t\tif (!proc_is_root(current_proc) && (args.size > HUGE_PAGE_SIZE))\n\t\t\treturn -E2BIG;\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn __create_new_pma(kobj, right, &args);\n}\nDEFINE_KOBJECT(pma, KOBJ_TYPE_PMA, pma_create);\n"
  },
  {
    "path": "kernel/userspace/poll.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/task.h>\n#include <minos/string.h>\n#include <minos/sched.h>\n#include <minos/mm.h>\n#include <minos/event.h>\n#include <minos/task.h>\n#include <uspace/vspace.h>\n#include <uspace/uaccess.h>\n#include <uspace/poll.h>\n#include <uspace/kobject.h>\n#include <uspace/proc.h>\n#include <uspace/handle.h>\n\n#define POLLHUB_RIGHT\t\t(KOBJ_RIGHT_RO | KOBJ_RIGHT_CTL)\n#define POLLHUB_RIGHT_MASK\t(0)\n\n#define to_poll_hub(kobj)\t\\\n\t(struct poll_hub *)kobj->data\n\nstruct poll_event *alloc_poll_event(void)\n{\n\tstruct poll_event_kernel *p;\n\n\tp = zalloc(sizeof(struct poll_event_kernel));\n\tif (!p)\n\t\treturn NULL;\n\tp->release = 1;\n\n\treturn &p->event;\n}\n\nint poll_event_send_static(struct pevent_item *pi, struct poll_event_kernel *evk)\n{\n\tstruct poll_hub *peh = pi->poller;\n\tunsigned long flags;\n\n\tspin_lock_irqsave(&peh->lock, flags);\n\tlist_add_tail(&peh->event_list, &evk->list);\n\tspin_unlock_irqrestore(&peh->lock, flags);\n\n\treturn wake(&peh->event, 0);\n}\n\nint poll_event_send_with_data(struct poll_struct *ps, int ev, int type,\n\t\tuint64_t data0, uint64_t data1, uint64_t data2)\n{\n\tstruct poll_event *pe;\n\tstruct pevent_item *pi;\n\tint ret = 0;\n\n\tif (!ps)\n\t\treturn -EAGAIN;\n\n\tsmp_rmb();\n\tpi = ps->pevents[ev];\n\n\t/*\n\t * need aquire the spinlock of the poll_struct ?\n\t */\n\twhile (pi) {\n\t\tpe = alloc_poll_event();\n\t\tif (!pe)\n\t\t\treturn -ENOMEM;\n\n\t\tpe->events = (1 << ev);\n\t\tpe->data.pdata = pi->data;\n\t\tpe->data.type = type;\n\t\tpe->data.data0 = data0;\n\t\tpe->data.data1 = data1;\n\t\tpe->data.data2 = data2;\n\n\t\tret += poll_event_send_static(pi, (struct poll_event_kernel *)pe);\n\t\tpi = pi->next;\n\t}\n\n\treturn ret;\n}\n\nint poll_event_send(struct poll_struct *ps, int ev)\n{\n\treturn poll_event_send_with_data(ps, ev, 0, 0, 0, 0);\n}\n\nstatic int copy_poll_event_to_user(struct poll_event __user *events,\n\t\tstruct list_head *head, int cnt)\n{\n\tstruct poll_event_kernel *pevent, *tmp;\n\tint ret, num = 0;\n\n\tlist_for_each_entry_safe(pevent, tmp, head, list) {\n\t\tlist_del(&pevent->list);\n\t\tret = copy_to_user(&events[num++], &pevent->event,\n\t\t\t\tsizeof(struct poll_event));\n\t\t/*\n\t\t * free the epoll event's memory\n\t\t */\n\t\tif (pevent->release)\n\t\t\tfree(pevent);\n\t\tASSERT(ret > 0);\n\t}\n\n\treturn cnt;\n}\n\nstatic int __poll_hub_read(struct poll_hub *peh,\n\t\tstruct poll_event __user *events,\n\t\tint max_event, uint32_t timeout)\n{\n\tstruct poll_event_kernel *pevent, *tmp;\n\tunsigned long flags;\n\tLIST_HEAD(event_list);\n\tint cnt = 0;\n\tlong ret = 0;\n\n\tif (max_event >= 32)\n\t\treturn -E2BIG;\n\n\tif (!user_ranges_ok((void *)events, max_event * sizeof(struct poll_event)))\n\t\treturn -EFAULT;\n\n\tret = wait_event(&peh->event, !is_list_empty(&peh->event_list), -1);\n\tif (ret)\n\t\treturn ret;\n\n\tspin_lock_irqsave(&peh->lock, flags);\n\tif (is_list_empty(&peh->event_list)) {\n\t\tret = -EAGAIN;\n\t\tgoto out;\n\t}\n\n\tlist_for_each_entry_safe(pevent, tmp, &peh->event_list, list) {\n\t\tlist_del(&pevent->list);\n\t\tlist_add_tail(&event_list, &pevent->list);\n\t\tif (++cnt == max_event)\n\t\t\tbreak;\n\t}\nout:\n\tspin_unlock_irqrestore(&peh->lock, flags);\n\tif (ret)\n\t\treturn ret;\n\n\tif (!is_list_empty(&event_list))\n\t\tret = copy_poll_event_to_user(events, &event_list, cnt);\n\n\treturn ret;\n}\n\nstatic long poll_hub_read(struct kobject *kobj, void __user *data, size_t data_size,\n\t\tsize_t *actual_data, void __user *extra, size_t extra_size,\n\t\tsize_t *actual_extra, uint32_t timeout)\n{\n\tstruct poll_hub *peh = to_poll_hub(kobj);\n\tint cnt;\n\n\tcnt = __poll_hub_read(peh, data,\n\t\t\tdata_size / sizeof(struct poll_event), timeout);\n\tif (cnt <= 0)\n\t\treturn cnt;\n\n\t*actual_data = cnt * sizeof(struct poll_event);\n\n\treturn 0;\n}\n\nstatic void poll_hub_release(struct kobject *kobj)\n{\n\tstruct poll_hub *peh = to_poll_hub(kobj);\n\tstruct poll_event_kernel *pek, *tmp;\n\n\t/*\n\t * currently only kernel can access this kobject\n\t * now. so do not need to acquire the poll_hub's\n\t * spinlock here.\n\t */\n\tlist_for_each_entry_safe(pek, tmp, &peh->event_list, list) {\n\t\tlist_del(&pek->list);\n\t\tif (pek->release)\n\t\t\tfree(pek);\n\t}\n\n\tfree(peh);\n}\n\nstatic int poll_hub_close(struct kobject *kobj, right_t right, struct process *proc)\n{\n\treturn 0;\n}\n\nstatic struct pevent_item *find_pevent_item(struct poll_struct *ps, int ev, struct poll_hub *ph)\n{\n\tstruct pevent_item *pi = ps->pevents[ev];\n\n\twhile (pi) {\n\t\tif (pi->poller == ph)\n\t\t\treturn pi;\n\t\tpi = pi->next;\n\t}\n\n\treturn NULL;\n}\n\nstatic inline void add_new_pevent(struct poll_struct *ps, int ev, struct pevent_item *pi)\n{\n\tstruct pevent_item *head = ps->pevents[ev];\n\n\tpi->next = head;\n\tps->pevents[ev] = pi;\n\tsmp_wmb();\n}\n\nstatic struct pevent_item * find_and_del_pevent_item(struct poll_struct *ps,\n\t\tint ev, struct poll_hub *ph)\n{\n\tstruct pevent_item *pi = ps->pevents[ev];\n\tstruct pevent_item *tmp = NULL;\n\n\twhile (pi) {\n\t\tif (pi->poller == ph) {\n\t\t\tif (tmp == NULL)\n\t\t\t\tps->pevents[ev] = pi->next;\n\t\t\telse\n\t\t\t\ttmp->next = pi->next;\n\n\t\t\tsmp_wmb();\n\t\t\treturn pi;\n\t\t}\n\n\t\ttmp = pi;\n\t\tpi = pi->next;\n\t}\n\n\treturn NULL;\n}\n\nvoid release_poll_struct(struct kobject *kobj)\n{\n\tstruct poll_struct *ps = kobj->poll_struct;\n\tstruct pevent_item *pi, *tmp;\n\tstruct poll_hub *ph;\n\tint i;\n\n\tif (!ps)\n\t\treturn;\n\n\tfor (i = 0; i < EV_MAX; i++) {\n\t\tpi = ps->pevents[i];\n\t\twhile (pi) {\n\t\t\ttmp = pi->next;\n\t\t\tph = pi->poller;\n\t\t\tfree(pi);\n\t\t\tkobject_put(&ph->kobj);\n\t\t\tpi = tmp;\n\t\t}\n\t}\n\n\tfree(ps);\n}\n\nstatic int __poll_hub_ctl(struct poll_hub *ph, struct kobject *ksrc,\n\t\tint right, int op, struct poll_event *uevent)\n{\n\tint events, ev;\n\tstruct pevent_item *ei;\n\tstruct poll_struct *ps;\n\tint i, ret = 0;\n\n\tspin_lock(&ksrc->lock);\n\n\tps = ksrc->poll_struct;\n\tif (ps == NULL) {\n\t\tps = zalloc(sizeof(struct poll_struct));\n\t\tif (ps == NULL) {\n\t\t\tspin_unlock(&ksrc->lock);\n\t\t\treturn -ENOMEM;\n\t\t}\n\n\t\tksrc->poll_struct = ps;\n\t}\n\n\tevents = uevent->events;\n\n\tfor (i = 0; i < EV_MAX; i++) {\n\t\tev = events & (1 << i);\n\t\tif (!ev)\n\t\t\tcontinue;\n\n\t\tswitch (op) {\n\t\tcase KOBJ_POLL_OP_ADD:\n\t\t\tei = find_pevent_item(ps, i, ph);\n\t\t\tif (!ei) {\n\t\t\t\tret = kobject_poll(&ph->kobj, ksrc, ev, 1);\n\t\t\t\tif (ret)\n\t\t\t\t\tbreak;\n\n\t\t\t\tei = malloc(sizeof(struct pevent_item));\n\t\t\t\tif (!ei) {\n\t\t\t\t\tpr_err(\"failed to allocate new pevent item\\n\");\n\t\t\t\t\tret = -ENOMEM;\n\t\t\t\t\tgoto out;\n\t\t\t\t}\n\n\t\t\t\tei->poller = ph;\n\t\t\t\tei->data = uevent->data.pdata;\n\t\t\t\tadd_new_pevent(ps, i, ei);\n\t\t\t\tkobject_get(&ph->kobj);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase KOBJ_POLL_OP_MOD:\n\t\t\tei = find_pevent_item(ps, i, ph);\n\t\t\tif (ei)\n\t\t\t\tei->data = uevent->data.pdata;\n\t\t\telse\n\t\t\t\tpr_err(\"epoll_mod %d is not enabled\\n\", ev);\n\t\t\tbreak;\n\t\tcase KOBJ_POLL_OP_DEL:\n\t\t\tei = find_and_del_pevent_item(ps, i, ph);\n\t\t\tif (ei) {\n\t\t\t\tkobject_poll(&ph->kobj, ksrc, ev, 0);\n\t\t\t\tkobject_put(&ph->kobj);\n\t\t\t\tfree(ei);\n\t\t\t} else {\n\t\t\t\tpr_err(\"epoll_del %d is not enabled\\n\", ev);\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tpr_err(\"unsupport epoll action\\n\");\n\t\t\tbreak;\n\t\t}\n\t}\n\nout:\n\tspin_unlock(&ksrc->lock);\n\n\treturn ret;\n}\n\nstatic int poll_hub_check_right(int events, right_t right)\n{\n\tevents &= POLL_EVENT_MASK;\n\tif (events == 0)\n\t\treturn -EINVAL;\n\n\tif ((events & POLL_READ_RIGHT_EVENT) && !(right & KOBJ_RIGHT_READ))\n\t\treturn -EPERM;\n\n\tif ((events & POLL_WRITE_RIGHT_EVENT) && !(right & KOBJ_RIGHT_WRITE))\n\t\treturn -EPERM;\n\n\treturn 0;\n}\n\nstatic long poll_hub_ctl(struct kobject *kobj, int op, unsigned long data)\n{\n\tstruct poll_hub *ph = (struct poll_hub *)kobj->data;\n\tstruct poll_event uevent;\n\tstruct kobject *kobj_polled;\n\tright_t right;\n\tint ret;\n\n\tret = copy_from_user(&uevent, (void __user *)data,\n\t\t\tsizeof(struct poll_event));\n\tif (ret <= 0)\n\t\treturn ret;\n\n\tret = get_kobject_from_process(current_proc,\n\t\t\tuevent.data.fd, &kobj_polled, &right);\n\tif (ret)\n\t\treturn -ENOENT;\n\n\tret = poll_hub_check_right(uevent.events, right);\n\tif (ret)\n\t\treturn -EPERM;\n\n\tret = __poll_hub_ctl(ph, kobj_polled, right, op, &uevent);\n\tput_kobject(kobj_polled);\n\n\treturn ret;\n}\n\nstatic struct kobject_ops poll_hub_ops = {\n\t.recv\t\t= poll_hub_read,\n\t.release\t= poll_hub_release,\n\t.close\t\t= poll_hub_close,\n\t.ctl\t\t= poll_hub_ctl,\n};\n\nstatic int poll_hub_create(struct kobject **kobj, right_t *right, unsigned long data)\n{\n\tstruct poll_hub *peh;\n\n\tpeh = zalloc(sizeof(struct poll_hub));\n\tif (!peh)\n\t\treturn -ENOMEM;\n\n\tinit_list(&peh->event_list);\n\tspin_lock_init(&peh->lock);\n\tevent_init(&peh->event, OS_EVENT_TYPE_POLL, NULL);\n\tkobject_init(&peh->kobj, KOBJ_TYPE_POLLHUB,\n\t\t\tPOLLHUB_RIGHT_MASK, (unsigned long)peh);\n\tpeh->kobj.flags |= KOBJ_FLAGS_NON_SHARED;\n\tpeh->kobj.ops = &poll_hub_ops;\n\t*kobj = &peh->kobj;\n\t*right = POLLHUB_RIGHT;\n\n\treturn 0;\n}\nDEFINE_KOBJECT(poll_hub, KOBJ_TYPE_POLLHUB, poll_hub_create);\n"
  },
  {
    "path": "kernel/userspace/port.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/mm.h>\n#include <minos/sched.h>\n#include <uspace/poll.h>\n#include <uspace/kobject.h>\n#include <uspace/uaccess.h>\n#include <uspace/iqueue.h>\n\n#include \"kobject_copy.h\"\n\n#define PORT_RIGHT \tKOBJ_RIGHT_RW\n#define PORT_RIGHT_MASK KOBJ_RIGHT_WRITE\n\nstruct port {\n\tstruct kobject kobj;\n\tstruct iqueue iqueue;\n};\n\n#define kobject_to_port(kobj) (struct port *)((kobj)->data)\n\nstatic int port_close(struct kobject *kobj, right_t right, struct process *proc)\n{\n\tstruct port *port = kobject_to_port(kobj);\n\treturn iqueue_close(&port->iqueue, right, proc);\n}\n\nstatic long port_recv(struct kobject *kobj, void __user *data,\n\t\tsize_t data_size, size_t *actual_data, void __user *extra,\n\t\tsize_t extra_size, size_t *actual_extra, uint32_t timeout)\n{\n\tstruct port *port = kobject_to_port(kobj);\n\treturn iqueue_recv(&port->iqueue, data, data_size, actual_data,\n\t\t\textra, extra_size, actual_extra, timeout);\n}\n\nstatic long port_send(struct kobject *kobj, void __user *data, size_t data_size,\n\t\tvoid __user *extra, size_t extra_size, uint32_t timeout)\n{\n\tstruct port *port = kobject_to_port(kobj);\n\treturn iqueue_send(&port->iqueue, data, data_size, extra, extra_size, timeout);\n}\n\nstatic int port_reply(struct kobject *kobj, right_t right,\n\t\tlong token, long errno, handle_t fd, right_t fd_right)\n{\n\tstruct port *port = kobject_to_port(kobj);\n\treturn iqueue_reply(&port->iqueue, right, token, errno, fd, fd_right);\n}\n\nstatic void port_release(struct kobject *kobj)\n{\n\tfree(kobject_to_port(kobj));\n}\n\nstatic int port_poll(struct kobject *ksrc,\n\t\tstruct kobject *kdst, int event, bool enable)\n{\n\treturn ((event == EV_WOPEN) || event == EV_WCLOSE ? -EINVAL : 0);\n}\n\nstatic struct kobject_ops port_kobject_ops = {\n\t.send\t\t= port_send,\n\t.recv\t\t= port_recv,\n\t.release\t= port_release,\n\t.close\t\t= port_close,\n\t.reply\t\t= port_reply,\n\t.poll\t\t= port_poll,\n};\n\nstatic int port_create(struct kobject **kobj, right_t *right, unsigned long data)\n{\n\tstruct port *port;\n\n\tport = zalloc(sizeof(struct port));\n\tif (!port)\n\t\treturn -ENOMEM;\n\n\tiqueue_init(&port->iqueue, 1, &port->kobj);\n\tkobject_init(&port->kobj, KOBJ_TYPE_PORT, PORT_RIGHT_MASK, (unsigned long)port);\n\tport->kobj.ops = &port_kobject_ops;\n\t*kobj = &port->kobj;\n\t*right = PORT_RIGHT;\n\n\treturn 0;\n}\nDEFINE_KOBJECT(port, KOBJ_TYPE_PORT, port_create);\n"
  },
  {
    "path": "kernel/userspace/process.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/mm.h>\n#include <minos/task.h>\n#include <minos/sched.h>\n#include <uspace/poll.h>\n#include <uspace/handle.h>\n#include <uspace/procinfo.h>\n#include <uspace/kobject.h>\n#include <uspace/uaccess.h>\n#include <uspace/vspace.h>\n#include <uspace/proc.h>\n\n#include \"kobject_copy.h\"\n\n#define PROC_RIGHT\t(KOBJ_RIGHT_READ | KOBJ_RIGHT_CTL)\n#define PROC_RIGHT_MASK\t(KOBJ_RIGHT_CTL)\n\nstruct process *create_process(int pid, task_func_t func,\n\t\tvoid *usp, int prio, int aff, unsigned long opt)\n{\n\tstruct process *proc = NULL;\n\tstruct task *task;\n\tint ret;\n\n\tproc = zalloc(sizeof(struct process));\n\tif (!proc)\n\t\treturn NULL;\n\n\t/*\n\t * if the process is not root service, then its right\n\t * will be given by root service, when create the process.\n\t */\n\tproc->pid = pid;\n\tinit_list(&proc->task_list);\n\tspin_lock_init(&proc->lock);\n\n\tret = vspace_init(proc);\n\tif (ret)\n\t\tgoto vspace_init_fail;\n\n\t/*\n\t * create a root task for this process\n\t */\n\ttask = create_task(NULL, func, TASK_STACK_SIZE, usp, prio, aff,\n\t\t\topt | TASK_FLAGS_NO_AUTO_START | TASK_FLAGS_ROOT, proc);\n\tif (!task)\n\t\tgoto task_create_fail;\n\n\tproc->root_task = task;\n\tlist_add_tail(&proc->task_list, &task->proc_list);\n\tproc->task_cnt++;\n\n\tret = init_proc_handles(proc);\n\tif (ret)\n\t\tgoto handle_init_fail;\n\n\treturn proc;\n\nhandle_init_fail:\n\tdo_release_task(task);\ntask_create_fail:\n\tvspace_deinit(proc);\nvspace_init_fail:\n\tfree(proc);\n\n\treturn NULL;\n}\n\nstatic void task_exit_helper(void *data)\n{\n\n}\n\nstatic void request_process_stop(struct process *proc, int handle)\n{\n\tstruct task *tmp;\n\tint old;\n\n\tASSERT(handle >= 0);\n\n\t/*\n\t * someone called exit() aready.\n\t */\n\told = cmpxchg(&proc->stopped, 0, 1);\n\tif (old != 0)\n\t\treturn;\n\n\tspin_lock(&proc->lock);\n\tlist_for_each_entry(tmp, &proc->task_list, proc_list) {\n\t\t/*\n\t\t * other task can not get the instance of this\n\t\t * task, but the task who already get the instance\n\t\t * of this task can sending data to it currently.\n\t\t */\n\t\ttask_need_stop(tmp);\n\t\tif (tmp == current)\n\t\t\tcontinue;\n\n\t\t/*\n\t\t * make all the running taskes enter into kernel, so\n\t\t * when return to user, it can detected the task need\n\t\t * to exit.\n\t\t *\n\t\t * if the task is waitting for the root service, do not\n\t\t * wakeup it, since the root service will finnally wake\n\t\t * up this task.\n\t\t */\n\t\tif (tmp->ti.flags & __TIF_IN_USER)\n\t\t\tsmp_function_call(tmp->cpu, task_exit_helper, NULL, 0);\n\t}\n\tspin_unlock(&proc->lock);\n\n\tif (handle == 0) {\n\t\t/*\n\t\t * the handle is 0 means this stop request is triggered by\n\t\t * the process self.\n\t\t */\n\t\tpoll_event_send_with_data(proc->kobj.poll_struct, EV_KERNEL,\n\t\t\tPOLL_KEV_PROCESS_EXIT, 0, 0, 0);\n\t}\n}\n\n/*\n * the process call exit() itself.\n */\nvoid process_die(void)\n{\n\tgp_regs *regs = current_user_regs;\n\n\tif (proc_is_root(current_proc)) {\n\t\tpr_fatal(\"root service exit 0x%x %d\\n\", regs->pc, regs->x0);\n\t\tpanic(\"root service hang, system crash\\n\");\n\t}\n\n\trequest_process_stop(current_proc, 0);\n}\n\n/*\n * killed by root service. handle is the process kobject\n * in root service's handle table. this used to indicate\n * wether need to send evnet to root service.\n */\nvoid kill_process(struct process *proc, int handle)\n{\n\trequest_process_stop(proc, handle);\n}\n\nint process_page_fault(struct process *proc, uint64_t virtaddr, uint64_t info)\n{\n\tstruct iqueue *iqueue = &proc->iqueue;\n\tstruct imsg imsg;\n\tint ret;\n\n\timsg_init(&imsg, current);\n\tspin_lock(&iqueue->lock);\n\tlist_add_tail(&iqueue->processing_list, &imsg.list);\n\tspin_unlock(&iqueue->lock);\n\n\t/*\n\t * send the page fault event to the root service. need\n\t * to consider when event is send failed. TBD\n\t */\n\tpoll_event_send_with_data(proc->kobj.poll_struct,\n\t\t\tEV_KERNEL, POLL_KEV_PAGE_FAULT,\n\t\t\tvirtaddr, info, imsg.token);\n\n\t/*\n\t * handle page_fault fail, then the ret is the handle\n\t * of this process in root service.\n\t */\n\tret = wait_event(&imsg.ievent, imsg.token == 0, -1);\n\tif (ret == 0)\n\t\treturn imsg.retcode;\n\n\treturn ret;\n}\n\nstatic long process_recv(struct kobject *kobj, void __user *data,\n\t\tsize_t data_size, size_t *actual_data, void __user *extra,\n\t\tsize_t extra_size, size_t *actual_extra, uint32_t timeout)\n{\n\tstruct process *proc = (struct process *)kobj->data;\n\n\tif (!proc_is_root(current_proc)) {\n\t\tpr_err(\"only root service can read process request\\n\");\n\t\treturn -EPERM;\n\t}\n\n\treturn iqueue_recv(&proc->iqueue, data, data_size, actual_data,\n\t\t\textra, extra_size, actual_extra, timeout);\n}\n\nstatic int process_reply(struct kobject *kobj, right_t right, long token,\n\t\tlong errno, handle_t fd, right_t fd_right)\n{\n\tstruct process *proc = (struct process *)kobj->data;\n\n\treturn iqueue_reply(&proc->iqueue, right, token, errno, fd, fd_right);\n}\n\nstatic int set_process_name(struct process *proc, char __user *str)\n{\n\tstruct task_stat *ts = get_task_stat(proc->root_task->tid);\n\n\treturn copy_string_from_user_safe(ts->cmd, str, PROC_NAME_SIZE);\n}\n\nstatic long do_process_ctl(struct process *proc, int req, unsigned long data)\n{\n\tswitch (req) {\n\tcase KOBJ_PROCESS_GET_PID:\n\t\treturn proc->pid;\n\tcase KOBJ_PROCESS_SETUP_SP:\n\t\tarch_set_task_user_stack(proc->root_task, data);\n\t\treturn 0;\n\tcase KOBJ_PROCESS_WAKEUP:\n\t\treturn wake_up(proc->root_task, 0);\n\tcase KOBJ_PROCESS_KILL:\n\t\tkill_process(proc, (int)data);\n\t\treturn 0;\n\tcase KOBJ_PROCESS_SET_NAME:\n\t\treturn set_process_name(proc, (char __user *)data);\n\tcase KOBJ_PROCESS_SETUP_REG0:\n\t\tarch_set_task_reg0(proc->root_task, data);\n\t\treturn 0;\n\tcase KOBJ_PROCESS_GRANT_RIGHT:\n\t\tdata &= PROC_FLAGS_MASK;\n\t\tproc->flags |= data;\n\t\treturn 0;\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn -EPROTONOSUPPORT;\n}\n\nstatic long process_ctl(struct kobject *kobj, int req, unsigned long data)\n{\n\tstruct process *proc = (struct process *)kobj->data;\n\n\tif (!proc_is_root(current_proc))\n\t\treturn -EPERM;\n\n\treturn do_process_ctl(proc, req, data);\n}\n\nint do_process_release(struct kobject *kobj)\n{\n\tstruct process *proc = (struct process *)kobj->data;\n\n\tif (!is_list_empty(&proc->task_list)) {\n\t\tpr_err(\"some task still running\\n\");\n\t\treturn -EBUSY;\n\t}\n\n\t/*\n\t * close all the kobject which has not been closed\n\t * by the task.\n\t */\n\trelease_proc_kobjects(proc);\n\n\t/*\n\t * release the all resource of the process.\n\t */\n\tvspace_deinit(proc);\n\tprocess_handles_deinit(proc);\n\tfree(proc);\n\n\treturn 0;\n}\n\nstatic void process_release(struct kobject *kobj)\n{\n\tstruct pcpu *pcpu = __get_pcpu();\n\n\t/*\n\t * here all the task of this process has been cloesd, now\n\t * the process can be safe released, for better perference\n\t * put it the local pcpu's process's list.\n\t */\n\tlist_add_tail(&pcpu->die_process, &kobj->list);\n\t__put_pcpu(pcpu);\n}\n\nvoid clean_process_on_pcpu(struct pcpu *pcpu)\n{\n\tstruct kobject *kobj;\n\tunsigned long flags;\n\n\tfor (;;) {\n\t\tkobj = NULL;\n\t\tlocal_irq_save(flags);\n\t\tif (!is_list_empty(&pcpu->die_process)) {\n\t\t\tkobj = list_first_entry(&pcpu->die_process,\n\t\t\t\t\tstruct kobject, list);\n\t\t\tlist_del(&kobj->list);\n\t\t}\n\t\tlocal_irq_restore(flags);\n\n\t\tif (!kobj)\n\t\t\tbreak;\n\n\t\t/*\n\t\t * the process can not be clean up now, re-add it to the\n\t\t * die_process list, waitting for next time.\n\t\t */\n\t\tif (do_process_release(kobj)) {\n\t\t\tlocal_irq_save(flags);\n\t\t\tlist_add(&pcpu->die_process, &kobj->list);\n\t\t\tlocal_irq_restore(flags);\n\t\t}\n\t}\n}\n\nstatic long process_send(struct kobject *kobj,\n\t\tvoid __user *data, size_t data_size,\n\t\tvoid __user *extra, size_t extra_size,\n\t\tuint32_t timeout)\n{\n\tstruct process *proc = (struct process *)kobj->data;\n\n\t/*\n\t * ROOT service will always poll to the process's\n\t * request.\n\t */\n\tASSERT(!proc_is_root(current_proc));\n\n\treturn iqueue_send(&proc->iqueue, data,\n\t\t\tdata_size, extra, extra_size, timeout);\n}\n\nstatic int process_close(struct kobject *kobj, right_t right, struct process *proc)\n{\n\treturn 0;\n}\n\nstatic struct kobject_ops proc_kobj_ops = {\n\t.recv\t\t= process_recv,\n\t.send\t\t= process_send,\n\t.reply\t\t= process_reply,\n\t.release\t= process_release,\n\t.ctl\t\t= process_ctl,\n\t.close\t\t= process_close,\n};\n\nint wake_up_process(struct process *proc)\n{\n       int ret = 0;\n       struct task *task;\n\n       if (!proc)\n               return -EINVAL;\n\n       list_for_each_entry(task, &proc->task_list, proc_list)\n\t       ret +=  __wake_up(task, TASK_STATE_PEND_OK, 0);\n\n       return ret;\n}\n\nstruct process *create_root_process(task_func_t func, void *usp,\n\t\tint prio, int aff, unsigned long opt)\n{\n\tstruct process *proc;\n\tstruct task_stat *ts;\n\n\tproc = create_process(1, func, usp, prio, aff, opt);\n\tif (!proc)\n\t\treturn NULL;\n\n\tts = get_task_stat(proc->root_task->tid);\n\tstrcpy(ts->cmd, \"pangu.srv\");\n\tiqueue_init(&proc->iqueue, 0, &proc->kobj);\n\tkobject_init(&proc->kobj, KOBJ_TYPE_PROCESS,\n\t\t\tPROC_RIGHT_MASK, (unsigned long)proc);\n\tproc->flags |= PROC_FLAGS_ROOT | PROC_FLAGS_VMCTL | PROC_FLAGS_HWCTL;\n\tproc->kobj.ops = &proc_kobj_ops;\n\n\treturn proc;\n}\n\nstatic int process_create(struct kobject **kobjr, right_t *right, unsigned long data)\n{\n\tstruct process_create_arg args;\n\tstruct process *proc;\n\tint ret;\n\n\t/*\n\t * only root service can create process directly\n\t */\n\tif (!proc_is_root(current_proc))\n\t\treturn -EPERM;\n\n\tret = copy_from_user(&args, (void *)data,\n\t\t\tsizeof(struct process_create_arg));\n\tif (ret <= 0)\n\t\treturn -EFAULT;\n\n\tproc = create_process(args.pid, (task_func_t)args.entry,\n\t\t\t(void *)args.stack, args.aff,\n\t\t\targs.prio, args.flags);\n\tif (!proc)\n\t\treturn -ENOMEM;\n\n\tiqueue_init(&proc->iqueue, 0, &proc->kobj);\n\tkobject_init(&proc->kobj, KOBJ_TYPE_PROCESS,\n\t\t\tPROC_RIGHT_MASK, (unsigned long)proc);\n\tproc->kobj.ops = &proc_kobj_ops;\n\t*kobjr = &proc->kobj;\n\t*right = PROC_RIGHT;\n\n\treturn 0;\n}\nDEFINE_KOBJECT(process, KOBJ_TYPE_PROCESS, process_create);\n\nstatic int process_task_create_hook(void *item, void *context)\n{\n\tstruct process *proc = (struct process *)context;\n\tstruct task *task = (struct task *)item;\n\n\tif (!(task->flags & TASK_FLAGS_KERNEL)) {\n\t\ttask->vs = &proc->vspace;\n\t\ttask->pid = proc->pid;\n\t\ttask->state = TASK_STATE_WAIT_EVENT;\n\t}\n\n\tinit_task_stat(task);\n\n\treturn 0;\n}\n\nstatic int process_task_release_hook(void *item, void *context)\n{\n\tstruct task *task = (struct task *)item;\n\n\trelease_task_stat(task->tid);\n\n\treturn 0;\n}\n\nstatic int process_subsys_init(void)\n{\n\tregister_hook(process_task_release_hook, OS_HOOK_RELEASE_TASK);\n\tregister_hook(process_task_create_hook, OS_HOOK_CREATE_TASK);\n\n\treturn 0;\n}\nsubsys_initcall(process_subsys_init);\n"
  },
  {
    "path": "kernel/userspace/procinfo.c",
    "content": "/*\n * Copyright (C) 2019 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/sched.h>\n#include <minos/mm.h>\n#include <minos/time.h>\n#include <minos/atomic.h>\n#include <minos/task.h>\n#include <uspace/kobject.h>\n#include <uspace/proc.h>\n#include <uapi/procinfo_uapi.h>\n\nstruct kobject *task_stat_pma;\nstatic struct task_stat *task_stat_addr;\n\nstruct task_stat *get_task_stat(int tid)\n{\n\tASSERT((tid >= 0) && (tid < OS_NR_TASKS));\n\treturn &task_stat_addr[tid]; \n}\n\nvoid release_task_stat(int tid)\n{\n\tASSERT((tid >= 0) && (tid < OS_NR_TASKS));\n\tmemset(&task_stat_addr[tid], 0, sizeof(struct task_stat));\n}\n\nvoid init_task_stat(struct task *task)\n{\n\tstruct task_stat *kstat;\n\tstruct process *proc;\n\n\tif (task_stat_addr == NULL)\n\t\treturn;\n\n\tkstat = get_task_stat(task->tid);\n\tkstat->tid = task->tid;\n\tkstat->pid = task->pid;\n\tkstat->start_ns = task->start_ns;\n\tkstat->state = task->state;\n\tkstat->cpu = task->cpu;\n\tkstat->prio = task->prio;\n\tkstat->cpu_usage = 0x0;\n\n\tif (!(task->flags & TASK_FLAGS_KERNEL)) {\n\t\tproc = task_to_proc(task);\n\t\tif (proc->root_task)\n\t\t\tkstat->root_tid = proc->root_task->tid;\n\t}\n}\n\nvoid update_task_stat(struct task *task)\n{\n\tstruct task_stat *kstat = get_task_stat(task->tid);\n\n\tkstat->state = task->state;\n\tkstat->cpu = task->cpu;\n\tkstat->cpu_usage = 0x0;\n\tkstat->prio = task->prio;\n}\n\nstatic int procinfo_switch_hook(void *item, void *data)\n{\n\tupdate_task_stat((struct task *)item);\n\tupdate_task_stat((struct task *)data);\n\n\treturn 0;\n}\n\nstatic void init_kernel_task_stat(struct task *task)\n{\n\tstruct task_stat *ts;\n\n\tif (!(task->flags & TASK_FLAGS_KERNEL))\n\t\treturn;\n\n\tts = get_task_stat(task->tid);\n\tstrcpy(ts->cmd, task->name);\n\tinit_task_stat(task);\n}\n\nint procinfo_init(void)\n{\n\tstruct pma_create_arg args;\n\tuint32_t memsz;\n\tright_t right;\n\tint ret;\n\n\t/*\n\t * allocate pma kobject for process and task info which\n\t * can shared to each process in these system.\n\t */\n\tmemsz = sizeof(struct task_stat) * OS_NR_TASKS;\n\tmemsz = PAGE_BALIGN(memsz);\n\ttask_stat_addr = get_free_pages(memsz >> PAGE_SHIFT, GFP_USER);\n\tASSERT(task_stat_addr != NULL);\n\targs.type = PMA_TYPE_PMEM;\n\targs.right = KOBJ_RIGHT_RW;\n\targs.consequent = 1;\n\targs.start = vtop(task_stat_addr);\n\targs.size = memsz;\n\tret = create_new_pma(&task_stat_pma, &right, &args);\n\tASSERT(ret == 0);\n\tmemset(task_stat_addr, 0, memsz);\n\tpr_info(\"task stat memory size 0x%x\\n\", memsz);\n\n\tregister_hook(procinfo_switch_hook, OS_HOOK_TASK_SWITCH);\n\n\t/*\n\t * init the kernel task's task stat.\n\t */\n\tos_for_all_task(init_kernel_task_stat);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "kernel/userspace/root_service.c",
    "content": "/*\n * Copyright (C) 2020 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/ramdisk.h>\n#include <minos/bootarg.h>\n#include <minos/sched.h>\n#include <minos/memattr.h>\n#include <minos/mm.h>\n#include <asm/arch.h>\n#include <asm/io.h>\n#include <uapi/bootdata.h>\n\n#include <uspace/vspace.h>\n#include <uspace/kobject.h>\n#include <uspace/handle.h>\n#include <uspace/elf.h>\n#include <uspace/proc.h>\n\nextern struct kobject *task_stat_pma;\nextern struct process *create_root_process( task_func_t func,\n\t\tvoid *usp, int prio, int aff, unsigned long opt);\n\nstruct elf_ctx {\n\tElf_Addr base_load_vbase;\n\tElf_Addr base_load_vend;\n\tElf_Addr memsz;\n\tElf_Addr align;\n\tElf_Ehdr ehdr;\n\tElf_Off  dynoff;\n\tElf_Addr dynsize;\n};\n\nenum {\n\tEL_OK         = 0,\n\tEL_EIO,\n    \tEL_ENOMEM,\n    \tEL_NOTELF,\n    \tEL_WRONGBITS,\n    \tEL_WRONGENDIAN,\n    \tEL_WRONGARCH,\n    \tEL_WRONGOS,\n    \tEL_NOTEXEC,\n    \tEL_NODYN,\n    \tEL_BADREL,\n};\n\ntypedef struct\n{\n\tuint64_t a_type;              /* Entry type */\n\tuint64_t a_val;\n} Elf64_auxv_t;\n\n/* Symbolic values for the entries in the auxiliary table\n   put on the initial stack */\n#define AT_NULL   0     /* end of vector */\n#define AT_IGNORE 1     /* entry should be ignored */\n#define AT_EXECFD 2     /* file descriptor of program */\n#define AT_PHDR   3     /* program headers for program */\n#define AT_PHENT  4     /* size of program header entry */\n#define AT_PHNUM  5     /* number of program headers */\n#define AT_PAGESZ 6     /* system page size */\n#define AT_BASE   7     /* base address of interpreter */\n#define AT_FLAGS  8     /* flags */\n#define AT_ENTRY  9     /* entry point of program */\n#define AT_NOTELF 10    /* program is not ELF */\n#define AT_UID    11    /* real uid */\n#define AT_EUID   12    /* effective uid */\n#define AT_GID    13    /* real gid */\n#define AT_EGID   14    /* effective gid */\n#define AT_PLATFORM 15  /* string identifying CPU for optimizations */\n#define AT_HWCAP  16    /* arch dependent hints at CPU capabilities */\n#define AT_CLKTCK 17    /* frequency at which times() increments */\n/* AT_* values 18 through 22 are reserved */\n#define AT_SECURE 23   /* secure mode boolean */\n#define AT_BASE_PLATFORM 24     /* string identifying real platform, may\n                                 * differ from AT_PLATFORM. */\n#define AT_RANDOM 25    /* address of 16 random bytes */\n#define AT_HWCAP2 26    /* extension of AT_HWCAP */\n\n#define AT_EXECFN  31   /* filename of program */\n\n#define EL_PHOFF(ctx, num) (((ctx)->ehdr.e_phoff + (num) * (ctx)->ehdr.e_phentsize))\n#define EL_SHOFF(ctx, num) (((ctx)->ehdr.e_shoff + (num) * (ctx)->ehdr.e_shentsize))\n\nint elf_findphdr(struct ramdisk_file *file, struct elf_ctx *ctx,\n\t\tElf_Phdr *phdr, uint32_t type, unsigned *i)\n{\n\tint rv = EL_OK;\n\n    \tfor (; *i < ctx->ehdr.e_phnum; (*i)++) {\n\t\trv = ramdisk_read(file, phdr, sizeof(Elf_Phdr), EL_PHOFF(ctx, *i));\n\t\tif (rv)\n\t\t\treturn rv;\n\t\t\n\t\tif (phdr->p_type == type)\n\t\t\treturn rv;\n    \t}\n\n    \t*i = -1;\n    \treturn rv;\n}\n\nint elf_init(struct ramdisk_file *file, struct elf_ctx *ctx)\n{\n\tElf_Phdr ph;\n\tint rv = EL_OK;\n\tunsigned i = 0;\n\n\tmemset(ctx, 0, sizeof(struct elf_ctx));\n\t\n\tif ((rv = ramdisk_read(file, &ctx->ehdr, sizeof(ctx->ehdr), 0)))\n\t\treturn rv;\n\t\n\tif (!IS_ELF(ctx->ehdr))\n\t\treturn EL_NOTELF;\n\t\n\tif (ctx->ehdr.e_ident[EI_CLASS] != ELFCLASS)\n\t        return EL_WRONGBITS;\n\t\n\tif (ctx->ehdr.e_ident[EI_DATA] != ELFDATATHIS)\n\t        return EL_WRONGENDIAN;\n\t\n\tif (ctx->ehdr.e_ident[EI_VERSION] != EV_CURRENT)\n\t        return EL_NOTELF;\n\t\n\tif (ctx->ehdr.e_type != ET_EXEC || ctx->ehdr.e_type == ET_DYN)\n\t        return EL_NOTEXEC;\n\n\tif (ctx->ehdr.e_machine != EM_THIS)\n\t        return EL_WRONGARCH;\n\t\n\tif (ctx->ehdr.e_version != EV_CURRENT)\n\t        return EL_NOTELF;\n\t\n\t/*\n\t * calculate how many memory is needed for this elf file, the\n\t * memory will allocated together.\n\t */\n\tctx->base_load_vbase = (unsigned long)-1;\n\n\tfor(;;) {\n\t\tif ((rv = elf_findphdr(file, ctx, &ph, PT_LOAD, &i)))\n\t\t\treturn rv;\n\t\n\t        if (i == (unsigned) -1)\n\t\t\tbreak;\n\n\t\tif (ph.p_vaddr < ctx->base_load_vbase)\n\t\t\tctx->base_load_vbase = ph.p_vaddr;\n\t\n\t        Elf_Addr phend = ph.p_vaddr + ph.p_memsz;\n\t        if (phend > ctx->base_load_vend)\n\t\t\tctx->base_load_vend = phend;\n\t\n\t        if (ph.p_align > ctx->align)\n\t\t\tctx->align = ph.p_align;\n\t\ti++;\n\t}\n\n\tctx->memsz = PAGE_BALIGN(ctx->base_load_vend - ctx->base_load_vbase);\n\t\n\treturn rv;\n}\n\nstatic int elf_load_section(struct ramdisk_file *file, void *vaddr, Elf_Shdr *shdr)\n{\n\t/*\n\t * bss section ?\n\t */\n\tif (shdr->sh_type == SHT_NOBITS) {\n\t\tpr_info(\"bzero elf section [0x%x 0x%x 0x%x 0x%x]\\n\",\n\t\t\tshdr->sh_offset, shdr->sh_addr, shdr->sh_size, shdr->sh_type);\n\t\tmemset(vaddr, 0, shdr->sh_size);\n\t\treturn 0;\n\t}\n\n\tpr_info(\"loading elf section [0x%x 0x%x 0x%x]\\n\",\n\t\t\tshdr->sh_offset, shdr->sh_addr, shdr->sh_size, shdr->sh_type);\n\tramdisk_read(file, vaddr, shdr->sh_size, shdr->sh_offset);\n\n\treturn 0;\n}\n\nstatic int elf_findshdr(struct ramdisk_file *file, struct elf_ctx *ctx,\n\t\tElf_Shdr *shdr, unsigned int *i)\n{\n\n\tint rv = EL_OK;\n\tint j = *i;\n\n\tfor ( ;j < ctx->ehdr.e_shnum; j++) {\n\t\trv = ramdisk_read(file, shdr, sizeof(Elf64_Ehdr), EL_SHOFF(ctx, j));\n\t\tif (rv)\n\t\t\treturn rv;\n\n\t\tif (shdr->sh_flags & SHF_ALLOC) {\n\t\t\t*i = j;\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t*i = -1;\n\treturn rv;\n}\n\nint elf_load(struct process *proc, struct ramdisk_file *file, struct elf_ctx *ctx)\n{\n\tint rv = EL_OK;\n    \tunsigned int i = 0;\n\tvoid *page;\n\tvoid *vaddr;\n\tElf_Shdr shdr;\n\n\tpage = get_free_pages(ctx->memsz >> PAGE_SHIFT, GFP_USER);\n\tif (!page)\n\t\treturn -ENOMEM;\n\n\trv = map_process_memory(proc, ctx->base_load_vbase,\n\t\t\tctx->memsz, vtop(page), VM_RWX);\n\tif (rv)\n\t\treturn rv;\n\n    \tfor(;;) {\n\t\tif ((rv = elf_findshdr(file, ctx, &shdr, &i)))\n            \t\treturn rv;\n\n        \tif (i == (unsigned int)-1)\n            \t\tbreak;\n\n\t\tvaddr = page + (shdr.sh_addr - ctx->base_load_vbase);\n\t\trv = elf_load_section(file, vaddr, &shdr);\n        \tif (rv)\n            \t\treturn EL_ENOMEM;\n        \ti++;\n    \t}\n\t\n\treturn rv;\n}\n\nlong elf_load_process(struct process *proc, struct ramdisk_file *file)\n{\n\tstruct elf_ctx ctx;\n\n\tif (elf_init(file, &ctx))\n\t\treturn -EBADF;\n\t\n\tif (elf_load(proc, file, &ctx))\n\t\treturn -EIO;\n\n\treturn ctx.ehdr.e_entry;\n}\n\nstatic int setup_user_memory_region(struct process *proc, struct bootdata *env)\n{\n\textern int get_system_setup_info(unsigned long *addr, size_t *size);\n\tstruct memory_region *region;\n\tunsigned long addr;\n\tsize_t size;\n\tint ret;\n\n\tenv->heap_start = SYS_PROC_HEAP_BASE;\n\tenv->heap_end = SYS_PROC_HEAP_END;\n\tenv->vmap_start = SYS_PROC_VMAP_BASE;\n\tenv->vmap_end = SYS_PROC_VMAP_END;\n\n\t/*\n\t * map the dtb memory to the root service.\n\t */\n\tret = get_system_setup_info(&addr, &size);\n\tif (!ret) {\n\t\tenv->dtb_start = pa2sva(addr);\n\t\tenv->dtb_end = pa2sva(addr + size);\n\n\t\tret = map_process_memory(proc, env->dtb_start, size, addr, VM_RO);\n\t\tif (ret) {\n\t\t\tpr_err(\"map DTB region for root service failed\\n\");\n\t\t\treturn ret;\n\t\t}\n\t} else {\n\t\tpr_err(\"no dtb memory found in system\\n\");\n\t}\n\n\t/*\n\t * user memory region will mapped as point to point\n\t * to the root service's address space. currently the\n\t * dtb memory and the ramdisk memory will mapped to\n\t * root service.\n\t */\n\tfor_each_memory_region(region) {\n\t\tif (region->type == MEMORY_REGION_TYPE_RAMDISK) {\n\t\t\tenv->ramdisk_start = pa2sva(region->phy_base);\n\t\t\tenv->ramdisk_end = pa2sva(region->phy_base + region->size);\n\t\t\tret = map_process_memory(proc, env->ramdisk_start, region->size,\n\t\t\t\t\tregion->phy_base, VM_RO);\n\t\t\tif (ret)\n\t\t\t\tpr_err(\"map memory region for root service failed\\n\");\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn ret;\n}\n\nstatic int setup_root_service_env(struct process *proc)\n{\n\tint ret = 0;\n\tstruct bootdata *env;\n\n\t/*\n\t * allocate one page for enve for root service, and\n\t * map it to the root service's space address\n\t */\n\tenv = get_free_page(GFP_USER);\n\tif (!env)\n\t\treturn -ENOMEM;\n\n\tmemset(env, 0, PAGE_SIZE);\n\tenv->magic = BOOTDATA_MAGIC;\n\tret = setup_user_memory_region(proc, env);\n\tif (ret)\n\t\treturn ret;\n\n\t/*\n\t * pass the task_stat pma handle to the root service.\n\t */\n\tenv->max_proc = OS_NR_TASKS;\n\tenv->task_stat_handle = __alloc_handle(proc, task_stat_pma,\n\t\t\tKOBJ_RIGHT_READ | KOBJ_RIGHT_MMAP);\n\tASSERT(env->task_stat_handle > 0);\n\n\t/*\n\t * map env page to a fix memory address\n\t */\n\tret = map_process_memory(proc, ROOTSRV_BOOTDATA_BASE,\n\t\t\tPAGE_SIZE, vtop(env), VM_RO);\n\n\treturn ret;\n}\n\n#define NEW_AUX_ENT(auxp, type, value)\t\\\n\tdo {\t\t\t\t\\\n\t\tauxp--;\t\t\t\\\n\t\tauxp->a_type = type;\t\\\n\t\tauxp->a_val = value;\t\\\n\t} while (0)\n\nstatic void *setup_auxv(void *top)\n{\n\tElf64_auxv_t *auxp = (Elf64_auxv_t *)top;\n\n\tNEW_AUX_ENT(auxp, AT_NULL, 0);\n\tNEW_AUX_ENT(auxp, AT_PAGESZ, PAGE_SIZE);\n\tNEW_AUX_ENT(auxp, AT_HWCAP, 0);\t\t// TBD cpu feature.\n\n\t/*\n\t * root service will have it own memory management\n\t * service, kernel will handle the page fault for\n\t * it.\n\t */\n\tNEW_AUX_ENT(auxp, AT_HEAP_BASE, SYS_PROC_HEAP_BASE);\n\tNEW_AUX_ENT(auxp, AT_HEAP_END, SYS_PROC_HEAP_END);\n\n\treturn (void *)auxp;\n}\n\nstatic void *set_argv_string(void *top, int i, char **argv,\n\t\tchar *opt, char *arg)\n{\n\tchar buf[256];\n\tint size;\n\n\tif (opt)\n\t\tsprintf(buf, \"%s=%s\", opt, arg);\n\telse\n\t\tsprintf(buf, \"%s\", arg);\n\n\tsize = strlen(buf) + 1;\n\tsize = BALIGN(size, sizeof(unsigned long));\n\ttop -= size;\n\tstrcpy((char *)top, buf);\n\targv[i] = (char *)top;\n\n\treturn top;\n}\n\nstatic void *set_argv_uint64(void *top, int i, char **argv,\n\t\tchar *opt, uint64_t val)\n{\n\tchar buf[64];\n\tsprintf(buf, \"0x%x\", val);\n\treturn set_argv_string(top, i, argv, opt, buf);\n}\n\nstatic void *setup_envp(void *top)\n{\n\ttop -= sizeof(unsigned long);\n\t*(char **)top = NULL;\n\n\treturn top;\n}\n\nstatic void *setup_argv(void *top, int argc, char **argv)\n{\n\tchar **str = (char **)top;\n\tint i;\n\n\tstr--;\n\t*str = NULL;\n\n\tfor (i = 0; i < argc; i++) {\n\t\tstr--;\n\t\t*str = argv[i];\n\t}\n\n\tstr--;\n\t*(unsigned long *)str = argc;\n\n\treturn (void *)str;\n}\n\nstatic int setup_root_service_ustack(struct process *proc)\n{\n\tvoid *ustack, *origin;\n\tchar *argv[8] = { NULL };\n\tint ret, i;\n\n\t/*\n\t * allocate 16KB 4 pages as the user space stack for\n\t * the root service.\n\t */\n\tustack = get_free_pages(ROOTSRV_USTACK_PAGES, GFP_USER);\n\tif (!ustack)\n\t\treturn -ENOMEM;\n\n\tret = map_process_memory(proc, ROOTSRV_USTACK_BOTTOM,\n\t\t\tROOTSRV_USTACK_PAGES * PAGE_SIZE, vtop(ustack), VM_RW);\n\tif (ret)\n\t\treturn -ENOMEM;\n\n\tustack += ROOTSRV_USTACK_PAGES << PAGE_SHIFT;\n\torigin = ustack;\n\n\t/*\n\t * set the argc and argv for this process.\n\t */\n\tustack = set_argv_uint64(ustack, 0, argv,\n\t\t\t\"bootdata\", ROOTSRV_BOOTDATA_BASE);\n\tustack = set_argv_string(ustack, 1, argv, NULL, \"pangu.srv\");\n\n\t/*\n\t * convert the argv address to user space address.\n\t */\n\tfor (i = 0; i < 2; i++)\n\t\targv[i] = (char *)ROOTSRV_USTACK_TOP - ((char *)origin - argv[i]);\n\n\tustack = setup_auxv(ustack);\n\tustack = setup_envp(ustack);\n\tustack = setup_argv(ustack, 2, argv);\n\tarch_set_task_user_stack(proc->root_task, ROOTSRV_USTACK_TOP - (origin - ustack));\n\n\treturn 0;\n}\n\n/*\n * root service will create the first user space\n * process, then response for the memory management\n * for all the task\n */\nint load_root_service(void)\n{\n\tint ret;\n\tlong entry;\n\tstruct ramdisk_file file;\n\tstruct process *proc;\n\n\tret = ramdisk_open(\"pangu.srv\", &file);\n\tif (ret) {\n\t\tpr_err(\"can not find root service pangu.srv\\n\");\n\t\tgoto out;\n\t}\n\n\tproc = create_root_process(NULL, NULL, OS_PRIO_SYSTEM, TASK_AFF_ANY,\n\t\t\tTASK_FLAGS_SRV | TASK_FLAGS_NO_AUTO_START);\n\tASSERT(proc != NULL);\n\n\tentry = elf_load_process(proc, &file);\n\tif (entry < MIN_ELF_LOAD_BASE) {\n\t\tpr_err(\"load root service elf failed\\n\");\n\t\tgoto out;\n\t}\n\tarch_set_task_entry_point(proc->root_task, entry);\n\n\tif (setup_root_service_env(proc)) {\n\t\tpr_err(\"setup root service env failed\\n\");\n\t\tgoto out;\n\t}\n\n\tret = setup_root_service_ustack(proc);\n\tif (ret) {\n\t\tpr_err(\"serup user stack for root service failed\\n\");\n\t\tgoto out;\n\t}\n\n\tpr_notice(\"Root service load successfully prepare to run...\\n\");\n\n\treturn wake_up_process(proc);\n\nout:\n\tpanic(\"load root service fail\\n\");\n\treturn -EFAULT;\n}\n\nint init_task(void *data)\n{\n\textern int procinfo_init(void);\n\n\tprocinfo_init();\n\n\treturn load_root_service();\n}\n"
  },
  {
    "path": "kernel/userspace/socket.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/mm.h>\n#include <minos/sched.h>\n#include <uspace/poll.h>\n#include <uspace/kobject.h>\n#include <uspace/uaccess.h>\n\nstruct socket {\n\tvoid *shmem;\n\tsize_t shmem_size;\n\n\tuint64_t widx;\n\tuint64_t ridx;\n\n\tspinlock_t rlock;\n\tspinlock_t wlock;\n\n\tstruct kobject kobj;\n};\n\n#define SOCKET_FULL(head, tail) ((head) == (tail) + 1)\n#define SOCKET_EMPTY(head, tail) ((head) == (tail))\n#define SOCKET_IDX(sk, idx)\t\\\n\t((idx) & (sk->shmem_size - 1))\n\nstatic void socket_release(struct kobject *kobj)\n{\n\tstruct socket *sk = (struct socket *)kobj->data;\n\n\tfree_pages(sk->shmem);\n\tfree(sk);\n}\n\nstatic long endpoint_recv(struct kobject *kobj, void __user *data,\n\t\tsize_t data_size, size_t *actual_data, void __user *extra,\n\t\tsize_t extra_size, size_t *actual_extra, uint32_t timeout)\n{\n\tstruct socket *sk = (struct socket *)kobj->data;\n\tuint64_t widx, ridx, head, tail;\n\tint ret = 0;\n\n\tspin_lock(&sk->rlock);\n\n\twidx = sk->widx;\n\tridx = sk->ridx;\n\tsmp_rmb();\n\n\tif (SOCKET_EMPTY(ridx, widx) || (widx - ridx < data_size)) {\n\t\tret = -ENOSPC;\n\t\tgoto out;\n\t}\n\n\tsk->ridx += data_size;\n\tsmp_wmb();\n\nout:\n\tspin_unlock(&sk->rlock);\n\tif (ret)\n\t\treturn ret;\n\n\t/*\n\t * copy the data to the target.\n\t */\n\tridx = SOCKET_IDX(sk, ridx);\n\ttail = ridx + data_size;\n\tif (tail > sk->shmem_size) {\n\t\thead = shmem_size - ridx;\n\t\ttail = tail - shmem_size;\n\t} else {\n\t\thead = data_size;\n\t\ttail = 0;\n\t}\n\n\tret = copy_to_user(data, sk->shmem + ridx, head);\n\tif (ret <= 0)\n\t\treturn ret;\n\n\tif (tail)\n\t\tret = copy_to_user(data + head, sk->shmem, tail);\n\n\treturn ret;\n}\n\nstatic long socket_send(struct kobject *kobj, void __user *data,\n\t\tsize_t data_size, size_t *actual_data, void __user *extra,\n\t\tsize_t extra_size, size_t *actual_extra, uint32_t timeout)\n{\n\tstruct socket *sk = (struct socket *)kobj->data;\n\tint ret = 0;\n\n\tspin_lock(&sk->wlock);\n\n\twidx = sk->widx;\n\tridx = sk->ridx;\n\tsmp_rmb();\n\n\tif (SOCKET_FULL(ridx, widx) || (sk->shmem_size - (widx - ridx) < data_size)) {\n\t\tret = -ENOSPC;\n\t\tgoto out;\n\t}\n\n\twidx = SOCKET_IDX(sk, widx);\n\ttail = widx + data_size;\n\tif (tail > sk->shmem_size) {\n\t\thead = shmem_size - widx;\n\t\ttail = tail - shmem_size;\n\t} else {\n\t\thead = data_size;\n\t\ttail = 0;\n\t}\n\n\tret = copy_from_user(sk->shmem + widx, data, head);\n\tif (ret <= 0)\n\t\tgoto out;\n\n\tif (tail) {\n\t\tret = copy_from_user(sk->shmem, data + head, tail);\n\t\tif (ret <= 0)\n\t\t\tgoto out;\n\t}\n\n\tsk->widx += data_size;\n\tsmp_wmb();\n\nout:\n\tspin_unlock(&sk->wlock);\n\treturn ret;\n}\n\nstatic struct kobject_ops socket_kobject_ops = {\n\t.send\t\t= socket_send,\n\t.recv\t\t= socket_recv,\n\t.release\t= socket_release,\n};\n\nstatic int socket_create(struct kobject **kobj, right_t *right, unsigned long data)\n{\n\tsize_t shmem_size = data;\n\tstruct socket *sk;\n\tint fls;\n\n\tif (shmem_size > HUGE_PAGE_SIZE || shmem_size == 0)\n\t\treturn -EINVAL;\n\n\tfls = __fls(shmem_size);\n\tif (shmem_size & ((1UL << fls) - 1))\n\t\tfls += 1;\n\tshmem_size = (1UL << fls) > PAGE_SIZE ? (1UL << fls) : PAGE_SIZE;\n\n\tsk = zalloc(sizeof(struct socket));\n\tif (!sk)\n\t\treturn -ENOMEM;\n\n\tsk->shmem = get_free_pages(shmem_size >> PAGE_SHIFT, GFP_USER);\n\tif (!sk->shmem) {\n\t\tfree(p);\n\t\treturn -ENOMEM;\n\t}\n\n\tsk->shmem_size = shmem_size;\n\tspin_lock_init(&sk->rlock);\n\tspin_lock_init(&sk->wlock);\n\tsk->kobj.ops = &socket_kobject_ops;\n\tkobject_init(&sk->kobj, KOBJ_TYPE_SOCKET, 0, (unsigned long)sk);\n\t*kobj = &sk->kobj;\n\t*right = KOBJ_RIGHT_RW;\n\n\treturn 0;\n}\n"
  },
  {
    "path": "kernel/userspace/stdio.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/mm.h>\n#include <minos/mutex.h>\n#include <minos/console.h>\n#include <uspace/kobject.h>\n#include <uspace/uaccess.h>\n\n#define STDIO_BUF_SIZE\t2048\n\nstruct kobject stdio_kobj;\nstatic mutex_t stdio_wlock;\nstatic char stdio_out_buf[STDIO_BUF_SIZE];\n\nstatic long stdio_send(struct kobject *kobj, void __user *data,\n\t\tsize_t data_size, void __user *extra,\n\t\tsize_t extra_size, uint32_t timeout)\n{\n\tsize_t left = data_size;\n\tint copy;\n\tint ret = 0;\n\n\tif (left <=0 )\n\t\treturn 0;\n\n\tmutex_pend(&stdio_wlock, 0);\n\n\twhile (left > 0) {\n\t\tcopy = left > STDIO_BUF_SIZE ? STDIO_BUF_SIZE : left;\n\t\tret = copy_from_user(stdio_out_buf, data, copy);\n\t\tif (ret <= 0)\n\t\t\tgoto out;\n\n\t\tconsole_puts(stdio_out_buf, copy);\n\t\tleft -= copy;\n\t\tdata += copy;\n\t}\n\n\tret = data_size;\n\nout:\n\tmutex_post(&stdio_wlock);\n\n\treturn ret;\n}\n\nstatic long stdio_recv(struct kobject *kobj, void __user *data,\n\t\tsize_t data_size, size_t *actual_data, void __user *extra,\n\t\tsize_t extra_size, size_t *actual_extra, uint32_t timeout)\n{\n\tchar buf[32];\n\tint size = 0;\n\n\t/*\n\t * currently only support one process, the shell. TBD\n\t */\n\tsize = console_gets(buf, 32, -1);\n\tif (size != 0)\n\t\tcopy_to_user(data, buf, size);\n\t*actual_data = size;\n\n\treturn 0;\n}\n\nstruct kobject_ops stdio_ops = {\n\t.send = stdio_send,\n\t.recv = stdio_recv,\n};\n\nstatic int stdio_kobject_init(void)\n{\n\tkobject_init(&stdio_kobj, KOBJ_TYPE_STDIO, KOBJ_RIGHT_RW, 0);\n\tkobject_get(&stdio_kobj);\n\tstdio_kobj.ops = &stdio_ops;\n\tmutex_init(&stdio_wlock);\n\n\treturn 0;\n}\ndevice_initcall(stdio_kobject_init);\n"
  },
  {
    "path": "kernel/userspace/syscall.c",
    "content": "/*\n * Copyright (C) 2020 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/irq.h>\n#include <minos/sched.h>\n#include <minos/arch.h>\n#include <minos/console.h>\n#include <uspace/kobject.h>\n#include <uspace/uaccess.h>\n#include <uspace/poll.h>\n#include <uspace/vspace.h>\n#include <uspace/proc.h>\n\nvoid sys_sched_yield(void)\n{\n\tlocal_irq_enable();\n\tsched();\n\tlocal_irq_disable();\n}\n\nlong sys_kobject_close(handle_t handle)\n{\n\tstruct kobject *kobj;\n\tright_t right;\n\tlong ret;\n\n\t/*\n\t * release the handle first, then other thread in\n\t * this process can not see this kobject now. if one\n\t * thread in this process called this successfully\n\t * other thread can not get ok from release_handle.\n\t */\n\tret = release_handle(handle, &kobj, &right);\n\tif (ret)\n\t\treturn ret;\n\n\treturn kobject_close(kobj, right, current_proc);\n}\n\nhandle_t sys_kobject_create(int type, unsigned long data)\n{\n\tstruct kobject *kobj;\n\tright_t right;\n\tint ret;\n\n\tret = kobject_create(type, &kobj, &right, data);\n\tif (ret)\n\t\treturn ret;\n\n\t/*\n\t * visable for all the threads in this process, and\n\t * the owner of this kobject have the GRANT right for\n\t * this kobject.\n\t */\n\treturn alloc_handle(kobj, right);\n}\n\nint sys_kobject_open(handle_t handle)\n{\n\tstruct kobject *kobj;\n\tright_t right;\n\tint ret;\n\n\tret = get_kobject(handle, &kobj, &right);\n\tif (ret)\n\t\treturn ret;\n\n\tret = kobject_open(kobj, handle, right);\n\tput_kobject(kobj);\n\n\treturn ret;\n}\n\nlong sys_kobject_recv(handle_t handle, void __user *data, size_t data_size,\n\t\tsize_t *actual_data, void __user *extra, size_t extra_size,\n\t\tsize_t *actual_extra, uint32_t timeout)\n{\n\tstruct kobject *kobj;\n\tright_t right;\n\tlong ret;\n\n\tret = get_kobject(handle, &kobj, &right);\n\tif (ret)\n\t\treturn ret;\n\n\tif (!(right & KOBJ_RIGHT_READ)) {\n\t\tret = -EPERM;\n\t\tgoto out;\n\t}\n\n\tret = kobject_recv(kobj, data, data_size, actual_data, extra,\n\t\t\textra_size, actual_extra, timeout);\nout:\n\tput_kobject(kobj);\n\treturn ret;\n}\n\nlong sys_kobject_send(handle_t handle, void __user *data, size_t data_size,\n\t\tvoid __user *extra, size_t extra_size, uint32_t timeout)\n{\n\tstruct kobject *kobj;\n\tright_t right;\n\tlong ret;\n\n\tret = get_kobject(handle, &kobj, &right);\n\tif (ret)\n\t\treturn ret;\n\n\tif (!(right & KOBJ_RIGHT_WRITE)) {\n\t\tret = -EPERM;\n\t\tgoto out;\n\t}\n\n\tret = kobject_send(kobj, data, data_size, extra, extra_size, timeout);\nout:\n\tput_kobject(kobj);\n\treturn ret;\n}\n\n/*\n * kobject reply can reply a fd to the target process\n * who obtain this handle. if need to reply a fd.\n */\nlong sys_kobject_reply(handle_t handle, unsigned long token,\n\t\tlong err_code, handle_t fd, right_t fd_right)\n{\n\tstruct kobject *kobj;\n\tright_t right;\n\tlong ret;\n\n\tret = get_kobject(handle, &kobj, &right);\n\tif (ret)\n\t\treturn ret;\n\n\tif (!(right & KOBJ_RIGHT_READ))\n\t\treturn -EPERM;\n\n\tret = kobject_reply(kobj, right, token, err_code, fd, fd_right);\n\tput_kobject(kobj);\n\n\treturn ret;\n}\n\nlong sys_kobject_ctl(handle_t handle, int req, unsigned long data)\n{\n\tstruct kobject *kobj;\n\tright_t right;\n\tlong ret;\n\n\tret = get_kobject(handle, &kobj, &right);\n\tif (ret)\n\t\treturn ret;\n\n\tif (!(right & KOBJ_RIGHT_CTL)) {\n\t\tret = -EPERM;\n\t\tgoto out;\n\t}\n\n\tret = kobject_ctl(kobj, right, req, data);\nout:\n\tput_kobject(kobj);\n\n\treturn ret;\n}\n\nint sys_kobject_mmap(handle_t handle,\n\t\tvoid **addr, unsigned long *map_size)\n{\n\tstruct kobject *kobj;\n\tright_t right;\n\tlong ret;\n\n\tret = get_kobject(handle, &kobj, &right);\n\tif (ret)\n\t\treturn ret;\n\n\tif (!(right & KOBJ_RIGHT_MMAP)) {\n\t\tret = -EPERM;\n\t\tgoto out;\n\t}\n\n\tret = kobject_mmap(kobj, right, addr, map_size);\nout:\n\tput_kobject(kobj);\n\treturn ret;\n}\n\nint sys_kobject_munmap(handle_t handle)\n{\n\tstruct kobject *kobj;\n\tright_t right;\n\tint ret;\n\n\tret = get_kobject(handle, &kobj, &right);\n\tif (ret)\n\t\treturn ret;\n\n\tif (!(right & KOBJ_RIGHT_MMAP)) {\n\t\tret = -EPERM;\n\t\tgoto out;\n\t}\n\n\tret = kobject_munmap(kobj, right);\nout:\n\tput_kobject(kobj);\n\treturn ret;\n}\n"
  },
  {
    "path": "kernel/userspace/thread.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/mm.h>\n#include <minos/task.h>\n#include <minos/sched.h>\n#include <uspace/vspace.h>\n#include <uspace/proc.h>\n#include <uspace/kobject.h>\n#include <uspace/uaccess.h>\n#include <uspace/procinfo.h>\n\nvoid sys_exit(int errno)\n{\n\tif (current->flags & TASK_FLAGS_ROOT)\n\t\tprocess_die();\n\telse\n\t\ttask_die();\n}\n\nvoid sys_exitgroup(int errno)\n{\n\tprocess_die();\n}\n\nvoid release_thread(struct task *task)\n{\n\tstruct process *proc = task_to_proc(task);\n\tunsigned long flags;\n\tint tflags = task->flags;\n\n\tspin_lock_irqsave(&proc->lock, flags);\n\tlist_del(&task->proc_list);\n\tproc->task_cnt--;\n\tspin_unlock_irqrestore(&proc->lock, flags);\n\n\tdo_release_task(task);\n\n\tif (tflags & TASK_FLAGS_ROOT)\n\t\t__release_handle(proc, 0);\n\t/*\n\t * the root task is put the refcnt of the handle 0.\n\t */\n\tkobject_put(&proc->kobj);\n}\n\nstatic int add_task_to_process(struct process *proc, struct task *task)\n{\n\tint ret = 0;\n\n\tspin_lock(&proc->lock);\n\tif (proc->stopped) {\n\t\tret = 1;\n\t\tgoto out;\n\t}\n\n\tlist_add_tail(&proc->task_list, &task->proc_list);\n\tproc->task_cnt++;\n\tkobject_get(&proc->kobj);\nout:\n\tspin_unlock(&proc->lock);\n\treturn ret;\n}\n\nint sys_clone(int flags, void *stack, int *ptid, void *tls, int *ctid)\n{\n\tstruct process *proc = current_proc;\n\tgp_regs *regs = current_user_regs;\n\tstruct task *task;\n\tint ret;\n\n\tif (proc->stopped)\n\t\treturn -EPERM;\n\n\ttask = create_task(NULL, (task_func_t)regs->pc,\n\t\t\tTASK_STACK_SIZE, stack, -1, -1,\n\t\t\tflags | TASK_FLAGS_NO_AUTO_START, proc);\n\tif (!task)\n\t\treturn -ENOSPC;\n\n\tret = copy_to_user(ptid, &task->tid, sizeof(int));\n\tif (ret <= 0) {\n\t\tdo_release_task(task);\n\t\treturn ret;\n\t}\n\n\tret = add_task_to_process(proc, task);\n\tif (ret) {\n\t\tdo_release_task(task);\n\t\treturn ret;\n\t}\n\n\tarch_set_tls(task, (unsigned long)tls);\n\ttask_ready(task, 0);\n\n\treturn task->tid;\n}\n"
  },
  {
    "path": "kernel/userspace/time.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/time.h>\n#include <uspace/uaccess.h>\n#include <uspace/syscall.h>\n\nint sys_clock_gettime(int id, struct timespec __user *ts)\n{\n\tunsigned long t;\n\tstruct timespec __ts;\n\n\tswitch (id) {\n\tcase CLOCK_REALTIME:\n\tcase CLOCK_MONOTONIC:\n\t\tt = get_current_time();\n\t\t__ts.tv_sec = t / 1000000000;\n\t\t__ts.tv_nsec = t - __ts.tv_sec;\n\t\tbreak;\n\tdefault:\n\t\tpr_err(\"unsupport clock id %d\\n\", id);\n\t\treturn -ENOSYS;\n\t}\n\n\tif (copy_to_user(ts, &__ts, sizeof(struct timespec)) <= 0)\n\t\treturn -EFAULT;\n\n\treturn 0;\n}\n\nint sys_clock_nanosleep(int id, int flags, long time, long ns,\n\t\tstruct timespec __user *rem)\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "kernel/userspace/uaccess.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <uspace/vspace.h>\n#include <uspace/proc.h>\n\nint copy_string_from_user(char *dst, char __user *src, int max)\n{\n\tint offset = (unsigned long)src - PAGE_ALIGN(src);\n\tint copy_size, left = max, copied = 0;\n\tstruct vspace *vs = current->vs;\n\tchar *ksrc;\n\n\tinc_vspace_usage(vs);\n\n\twhile (left) {\n\t\tcopy_size = PAGE_SIZE - offset;\n\t\tcopy_size = copy_size > left ? left : copy_size;\n\n\t\tksrc = (void *)arch_translate_va_to_pa(current->vs, (unsigned long)src);\n\t\tif ((phy_addr_t)ksrc == INVALID_ADDR) {\n\t\t\tcopied = -EFAULT;\n\t\t\tgoto out;\n\t\t}\n\n\t\tksrc = (char *)ptov(ksrc);\n\t\twhile (copy_size > 0) {\n\t\t\t*dst = *ksrc;\n\t\t\tcopied++;\n\n\t\t\tif (*ksrc == 0)\n\t\t\t\treturn copied;\n\n\t\t\tdst++;\n\t\t\tksrc++;\n\t\t\tcopy_size--;\n\t\t}\n\n\t\toffset = 0;\n\t\tleft -= copy_size;\n\t\tsrc += copy_size;\n\t\tdst += copy_size;\n\t}\n\nout:\n\tdec_vspace_usage(vs);\n\n\treturn copied;\n}\n\nint __copy_from_user(void *dst, struct vspace *vsrc, void __user *src, size_t size)\n{\n\tint offset = (unsigned long)src - PAGE_ALIGN(src);\n\tint copy_size;\n\tsize_t cnt = size;\n\tvoid *ksrc;\n\n\tinc_vspace_usage(vsrc);\n\n\twhile (size > 0) {\n\t\tcopy_size = PAGE_SIZE - offset;\n\t\tcopy_size = copy_size > size ? size : copy_size;\n\n\t\tksrc = (void *)arch_translate_va_to_pa(vsrc, (unsigned long)src);\n\t\tif ((phy_addr_t)ksrc == INVALID_ADDR) {\n\t\t\tcnt = -EFAULT;\n\t\t\tgoto out;\n\t\t}\n\n\t\tksrc = (char *)ptov(ksrc);\n\t\tmemcpy(dst, ksrc, copy_size);\n\t\toffset = 0;\n\t\tsize -= copy_size;\n\t\tsrc += copy_size;\n\t\tdst += copy_size;\n\t}\n\nout:\n\tdec_vspace_usage(vsrc);\n\n\treturn cnt;\n}\n\nint __copy_to_user(struct vspace *vdst, void __user *dst, void *src, size_t size)\n{\n\tint offset = (unsigned long)dst - PAGE_ALIGN(dst);\n\tint copy_size;\n\tsize_t cnt = size;\n\tvoid *kdst;\n\n\tinc_vspace_usage(vdst);\n\n\twhile (size > 0) {\n\t\tcopy_size = PAGE_SIZE - offset;\n\t\tcopy_size = copy_size > size ? size : copy_size;\n\n\t\tkdst = (void *)arch_translate_va_to_pa(vdst, (unsigned long)dst);\n\t\tif ((phy_addr_t)kdst == INVALID_ADDR) {\n\t\t\tcnt = -EFAULT;\n\t\t\tgoto out;\n\t\t}\n\n\t\tmemcpy((void *)ptov(kdst), src, copy_size);\n\t\toffset = 0;\n\t\tsize -= copy_size;\n\t\tsrc += copy_size;\n\t\tdst += copy_size;\n\t}\n\nout:\n\tdec_vspace_usage(vdst);\n\n\treturn cnt;\n}\n\nint copy_from_user(void *dst, void __user *src, size_t size)\n{\n\treturn __copy_from_user(dst, current->vs, src, size);\n}\n\nint copy_to_user(void __user *dst, void *src, size_t size)\n{\n\treturn __copy_to_user(current->vs, dst, src, size);\n}\n\nint copy_user_to_user(struct vspace *vdst, void __user *dst,\n\t\tstruct vspace *vsrc, void __user *src, size_t size)\n{\n\tint dst_offset = (unsigned long)dst - PAGE_ALIGN(dst);\n\tint copy_size, ret;\n\tsize_t cnt = size;\n\tvoid *kdst;\n\n\tinc_vspace_usage(vdst);\n\n\twhile (size > 0) {\n\t\tcopy_size = PAGE_SIZE - dst_offset;\n\t\tcopy_size = copy_size > size ? size : copy_size;\n\n\t\tkdst = (void *)arch_translate_va_to_pa(vdst, (unsigned long)dst);\n\t\tif ((phy_addr_t)kdst == INVALID_ADDR) {\n\t\t\tcnt = -EFAULT;\n\t\t\tgoto out;\n\t\t}\n\n\t\tret = __copy_from_user((void *)ptov(kdst), vsrc, src, copy_size);\n\t\tif (ret <= 0)\n\t\t\treturn ret;\n\n\t\tsize -= copy_size;\n\t\tsrc += copy_size;\n\t\tdst += copy_size;\n\t}\n\nout:\n\tdec_vspace_usage(vdst);\n\n\treturn cnt;\n}\n\nint copy_string_from_user_safe(char *dst, char __user *src, size_t max)\n{\n\tint ret;\n\n\tret = copy_string_from_user(dst, src, max - 1);\n\tif (ret <= 0)\n\t\treturn -E2BIG;\n\tdst[ret] = 0;\n\n\treturn ret;\n}\n"
  },
  {
    "path": "kernel/userspace/vspace.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/mm.h>\n#include <asm/cpu_feature.h>\n#include <uspace/proc.h>\n#include <uspace/vspace.h>\n#include <uspace/poll.h>\n#include <uspace/uaccess.h>\n#include <uspace/vspace.h>\n\n#define MAX_ASID\t\t4096\n#define FIXED_SHARED_ASID\t0\n#define FIXED_KERNEL_ASID\t1\n#define USER_ASID_BASE\t\t2\n\nstatic DECLARE_BITMAP(asid_bitmap, MAX_ASID);\nstatic DEFINE_SPIN_LOCK(asid_lock);\nstatic int max_asid;\n\nstatic int allocate_asid(void)\n{\n\tint asid = 0;\n\n\tif (max_asid <= USER_ASID_BASE)\n\t\treturn 0;\n\n\tspin_lock(&asid_lock);\n\tasid = find_next_zero_bit(asid_bitmap, max_asid, USER_ASID_BASE);\n\tif (asid >= max_asid)\n\t\tasid = 0;\n\telse\n\t\tset_bit(asid, asid_bitmap);\n\tspin_unlock(&asid_lock);\n\n\treturn asid;\n}\n\nstatic void free_asid(int asid)\n{\n\tBUG_ON((asid >= max_asid) || (asid < USER_ASID_BASE));\n\tclear_bit(asid, asid_bitmap);\n}\n\nvoid inc_vspace_usage(struct vspace *vs)\n{\n\tatomic_inc(&vs->inuse);\n}\n\nvoid dec_vspace_usage(struct vspace *vs)\n{\n\tint value;\n\n\tvalue = atomic_dec_return(&vs->inuse);\n\tASSERT(value >=0);\n\tif (value != 0)\n\t\treturn;\n\n\t/*\n\t * it is safe to release the pages here ? need double\n\t * check.\n\t */\n\tspin_lock(&vs->lock);\n\tif (atomic_read(&vs->inuse) != 0) {\n\t\tspin_unlock(&vs->lock);\n\t\treturn;\n\t}\n\trelease_vspace_pages(vs);\n\tspin_unlock(&vs->lock);\n}\n\nvoid *uva_to_kva(struct vspace *vs, unsigned long va,\n\t\tsize_t size, unsigned long right)\n{\n\treturn (void *)pa2va(translate_va_to_pa(vs, va));\n}\n\nstatic inline int __map_process_memory(struct vspace *vs, unsigned long vaddr,\n\t\tunsigned long end, unsigned long phy, unsigned long flags)\n{\n\tint ret;\n\n#if defined(CONFIG_VIRT) && !defined(CONFIG_ARM_VHE)\n\tret = arch_guest_map(vs, vaddr, end, phy, flags);\n\tif (ret)\n\t\tarch_guest_unmap(vs, vaddr, end, 0);\n#else\n\tret = arch_host_map(vs, vaddr, end, phy, flags);\n\tif (ret)\n\t\tarch_host_unmap(vs, vaddr, end, 0);\n#endif\n\treturn ret;\n}\n\nint map_process_memory(struct process *proc, unsigned long vaddr,\n\t\t       size_t size, unsigned long phy, unsigned long flags)\n{\n\tunsigned long end = vaddr + size;\n\tstruct vspace *vs = &proc->vspace;\n\tint ret;\n\n\tif (!IS_PAGE_ALIGN(vaddr) || !IS_PAGE_ALIGN(phy) ||\n\t\t\t!IS_PAGE_ALIGN(size))\n\t\treturn -EINVAL;\n\n\tspin_lock(&vs->lock);\n\tret = __map_process_memory(vs, vaddr, end, phy, flags);\n\tspin_unlock(&vs->lock);\n\n\treturn ret;\n}\n\nint unmap_process_memory(struct process *proc, unsigned long vaddr, size_t size)\n{\n\tstruct vspace *vs = &proc->vspace;\n\tint ret, inuse;\n\n\t/*\n\t * the process can be NULL when close the kobject\n\t * by kernel, this is ok for kernel, since, kernel\n\t * will unmap all the memory space for a process when\n\t * the process exit.\n\t */\n\tASSERT(proc != NULL);\n\tif (!IS_PAGE_ALIGN(vaddr) || !IS_PAGE_ALIGN(size))\n\t\treturn -EINVAL;\n\n\t/*\n\t * cpu1: inc_vspace_usage\n\t *       spin_lock\n\t *       translate_va_to_pa\n\t *\n\t * cpu2 spin_lock\n\t *      atomic_read\n\t *      arch_host_unmap\n\t *\n\t * inuse value need after spin_lock.\n\t */\n\tspin_lock(&vs->lock);\n\tinuse = atomic_read(&vs->inuse);\n\tret = arch_host_unmap(&proc->vspace, vaddr, vaddr + size, 0);\n\tasm volatile(\"ic ialluis\" : : );\n\tif (inuse == 0)\n\t\trelease_vspace_pages(vs);\n\tspin_unlock(&vs->lock);\n\n\treturn ret;\n}\n\nstatic int __map_process_page_internal(struct process *proc,\n\t\tunsigned long virt, size_t size, unsigned long flags)\n{\n\tstruct vspace *vs = &proc->vspace;\n\tunsigned long phy;\n\tint ret = 0, i;\n\tvoid *mem;\n\n\tspin_lock(&vs->lock);\n\n\tfor (i = 0; i < size >> PAGE_SHIFT; i++) {\n\t\tphy = arch_translate_va_to_pa(vs, virt);\n\t\tif (phy != 0) {\n\t\t\tpr_err(\"proc-%d 0x%x has been mapped\\n\", virt);\n\t\t\tcontinue;\n\t\t}\n\n\t\tmem = get_free_page(GFP_USER);\n\t\tif (mem == NULL) {\n\t\t\tret = -ENOMEM;\n\t\t\tbreak;\n\t\t}\n\n\t\tret = __map_process_memory(vs, virt, virt + PAGE_SIZE, vtop(mem), flags);\n\t\tif (ret) {\n\t\t\tfree_pages(mem);\n\t\t\tbreak;\n\t\t}\n\n\t\tvirt += PAGE_SIZE;\n\t}\n\n\tspin_unlock(&vs->lock);\n\treturn ret;\n}\n\nstatic int handle_page_fault_internal(struct process *proc,\n\t\tunsigned long virt, int write)\n{\n\tunsigned long flags = __VM_READ;\n\tint ret;\n\n\tif ((virt < SYS_PROC_HEAP_BASE) || (virt >= SYS_PROC_HEAP_END)) {\n\t\tpr_err(\"access invalid address 0x%x [0x%x 0x%x] 0x%x\\n\", virt,\n\t\t\t\tSYS_PROC_HEAP_BASE, SYS_PROC_HEAP_END,\n\t\t\t\tcurrent->user_regs->pc);\n\t\tgoto out;\n\t}\n\n\tif (write)\n\t\tflags |= __VM_WRITE;\n\n\tret = __map_process_page_internal(proc, PAGE_ALIGN(virt), PAGE_SIZE, flags);\n\tif (ret)\n\t\tgoto out;\n\n\treturn 0;\nout:\n\tprocess_die();\n\tpanic(\"kernel internal error when handle page fault\\n\");\n\n\treturn -EFAULT;\n}\n\nstatic int sys_map_anon(handle_t proc_handle, unsigned long virt,\n\t\tsize_t size, right_t right)\n{\n\tunsigned long flags = 0;\n\tstruct kobject *kobj_proc;\n\tright_t right_proc;\n\tint ret;\n\n\t/*\n\t * only root service can do the ANON mapping.\n\t */\n\tif (!proc_is_root(current_proc))\n\t\treturn -EPERM;\n\n\tif (!IS_PAGE_ALIGN(virt) || !IS_PAGE_ALIGN(size) || size == 0) {\n\t\tpr_err(\"%s invalid 0x%x 0x%x\\n\", virt, size);\n\t\treturn -EINVAL;\n\t}\n\n\tif (right & KOBJ_RIGHT_READ)\n\t\tflags |= __VM_READ;\n\tif (right & KOBJ_RIGHT_WRITE)\n\t\tflags |= __VM_WRITE;\n\tif (right & KOBJ_RIGHT_EXEC)\n\t\tflags |= __VM_EXEC;\n\n\t/*\n\t * only root service can call this function, so the\n\t * proc_handle will awlays bigger than 0.\n\t */\n\tret = get_kobject(proc_handle, &kobj_proc, &right_proc);\n\tif (ret)\n\t\treturn -ENOENT;\n\n\tret =  __map_process_page_internal((struct process *)kobj_proc->data,\n\t\t\tvirt, size, flags);\n\tput_kobject(kobj_proc);\n\n\treturn ret;\n}\n\nstatic int sys_unmap_anon(handle_t proc_handle, unsigned long virt, size_t size)\n{\n\tstruct kobject *kobj;\n\tright_t right;\n\tint ret;\n\n\tif (!proc_is_root(current_proc))\n\t\treturn -EPERM;\n\n\tret = get_kobject(proc_handle, &kobj, &right);\n\tif (ret)\n\t\treturn -ENOENT;\n\n\tret = unmap_process_memory((struct process *)kobj->data, virt, size);\n\tput_kobject(kobj);\n\n\treturn ret;\n}\n\nint sys_map(handle_t proc_handle, handle_t pma_handle,\n\t\tunsigned long virt, size_t size, right_t right)\n{\n\textern int sys_map_pma(handle_t proc_handle, handle_t pma_handle,\n\t\tunsigned long virt, size_t size, right_t right);\n\n\tif (!user_ranges_ok((void *)virt, size))\n\t\treturn -EFAULT;\n\n\tif (!proc_can_vmctl(current_proc))\n\t\treturn -EPERM;\n\n\tif (!IS_PAGE_ALIGN(virt) || !IS_PAGE_ALIGN(size))\n\t\treturn -EINVAL;\n\n\tif (pma_handle <= 0)\n\t\treturn sys_map_anon(proc_handle, virt, size, right);\n\telse\n\t\treturn sys_map_pma(proc_handle, pma_handle, virt, size, right);\n}\n\nint sys_unmap(handle_t proc_handle, handle_t pma_handle,\n\t\tunsigned long virt, size_t size)\n{\n\textern int sys_unmap_pma(handle_t proc_handle, handle_t pma_handle,\n\t\t\tunsigned long virt, size_t size);\n\n\tif (!user_ranges_ok((void *)virt, size))\n\t\treturn -EFAULT;\n\n\tif (!proc_can_vmctl(current_proc))\n\t\treturn -EPERM;\n\n\tif (!IS_PAGE_ALIGN(virt) || !IS_PAGE_ALIGN(size))\n\t\treturn -EINVAL;\n\n\tif (pma_handle <= 0)\n\t\treturn sys_unmap_anon(proc_handle, virt, size);\n\telse\n\t\treturn sys_unmap_pma(proc_handle, pma_handle, virt, size);\n}\n\nunsigned long sys_mtrans(unsigned long virt)\n{\n\tunsigned long addr;\n\n\tif (!user_ranges_ok((void *)virt, sizeof(unsigned long)))\n\t\treturn -EFAULT;\n\n\tif (!proc_can_vmctl(current_proc))\n\t\treturn -EPERM;\n\n\taddr = translate_va_to_pa(current->vs, virt);\n\n\treturn (addr == 0 ? -1 : addr);\n}\n\nstatic int handle_page_fault_ipc(struct process *proc, unsigned long virt, int write)\n{\n\tuint64_t info = write ? KOBJ_RIGHT_READ : KOBJ_RIGHT_WRITE;\n\n\treturn process_page_fault(proc, virt, info);\n}\n\nint handle_user_page_fault(unsigned long virt, int write, unsigned long fault_type)\n{\n\tstruct process *proc = current_proc;\n\tgp_regs *regs= current_user_regs;\n\tint ret;\n\n\tif (proc_is_root(proc))\n\t\tret = handle_page_fault_internal(proc, virt, write);\n\telse\n\t\tret = handle_page_fault_ipc(proc, virt, write);\n\tif (!ret)\n\t\treturn 0;\n\n\t/*\n\t * Can not handle this page fualt. Kill this process. TBD\n\t */\n\tpr_fatal(\"page fault fail %s [0x%x@0x%x]\\n\",\n\t\t\tproc->root_task->name, regs->pc, virt);\n\tprocess_die();\n\n\treturn -EFAULT;\n}\n\nint handle_user_ia_fault(void)\n{\n\tprocess_die();\n\n\treturn 0;\n}\n\nstatic void user_unmap_range(struct vspace *vspace, unsigned long start,\n\t\tunsigned long end, int flags)\n{\n\n}\n\nstatic struct mm_notifier_ops user_mm_notifier_ops = {\n\t.unmap_range = user_unmap_range,\n};\n\nint vspace_init(struct process *proc)\n{\n\tstruct vspace *vs = &proc->vspace;\n\n\tspin_lock_init(&vs->lock);\n\tvs->pgdp = arch_alloc_process_page_table();\n\tif (!vs->pgdp)\n\t\treturn -ENOMEM;\n\n\tvs->asid = allocate_asid();\n\tvs->pdata = proc;\n\tvs->notifier_ops = &user_mm_notifier_ops;\n\n\treturn 0;\n}\n\nvoid vspace_deinit(struct process *proc)\n{\n\tstruct vspace *vs = &proc->vspace;\n\n\tunmap_process_memory(proc, 0, USER_PROCESS_ADDR_LIMIT);\n\n\tif (vs->pgdp)\n\t\tfree(vs->pgdp);\n\tif (vs->asid != 0)\n\t\tfree_asid(vs->asid);\n}\n\nstatic int umm_init(void)\n{\n\tmax_asid = arch_get_asid_size();\n\tpr_info(\"max asid %d\\n\", max_asid);\n\tmax_asid = max_asid > MAX_ASID ? MAX_ASID : max_asid;\n\n\tif (max_asid > USER_ASID_BASE) {\n\t\tbitmap_set(asid_bitmap, max_asid, BITMAP_SIZE(MAX_ASID));\n\t\tset_bit(FIXED_SHARED_ASID, asid_bitmap);\n\t\tset_bit(FIXED_KERNEL_ASID, asid_bitmap);\n\t}\n\n\treturn 0;\n}\nsubsys_initcall(umm_init);\n"
  },
  {
    "path": "kernel/virt/Kconfig",
    "content": "menu \"Minos Virtualization Configuration\"\n\nconfig VIRT\n\tbool \"virtualization support\"\n\tselect STACK_PAGE_ALIGN\n\nif VIRT\n\nconfig VIRTIO_MMIO\n\tdef_bool y\n\nconfig MAX_VM\n\tint \"max virtual machine that system support\"\n\tdefault 64\n\nconfig VRTC_PL031\n\tbool \"vrtc pl031 support\"\n\tdefault y\n\thelp\n\t  vrtc pl031 driver for Minos\n\nconfig VWDT_SP805\n\tbool \"vwdt sp805 support\"\n\tdefault y\n\thelp\n\t  vwdt sp805 support for Minos\n\nsource \"virt/virq_chips/Kconfig\"\nsource \"virt/vmbox/Kconfig\"\nsource \"virt/os/Kconfig\"\n\nendif\n\nendmenu\n"
  },
  {
    "path": "kernel/virt/Makefile",
    "content": "obj-y\t\t\t\t+= resource.o\nobj-y\t\t\t\t+= hypercall.o\nobj-y\t\t\t\t+= os/\nobj-y\t\t\t\t+= vdev.o\nobj-y\t\t\t\t+= virq.o\nobj-y\t\t\t\t+= vm.o\nobj-y\t\t\t\t+= vmcs.o\nobj-y\t\t\t\t+= vmm.o\nobj-y\t\t\t\t+= vmbox/\nobj-y\t\t\t\t+= virq_chips/\nobj-$(CONFIG_VIRTIO_MMIO)\t+= virtio_mmio.o\nobj-$(CONFIG_VRTC_PL031)\t+= vrtc.o\nobj-$(CONFIG_VWDT_SP805)\t+= vwdt.o\nobj-y\t\t\t\t+= varm_timer.o\nobj-y\t\t\t\t+= debug_console.o\nobj-y\t\t\t\t+= vmodule.o\nobj-y\t\t\t\t+= iommu.o\nobj-y\t\t\t\t+= shmem.o\nobj-y\t\t\t\t+= vm_daemon.o\nobj-y\t\t\t\t+= vm_pm.o\nobj-y\t\t\t\t+= vfault.o\n"
  },
  {
    "path": "kernel/virt/debug_console.c",
    "content": "/*\n * Copyright (C) 2020 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/tty.h>\n#include <virt/vmm.h>\n#include <virt/virq.h>\n#include <generic/hypervisor.h>\n#include <virt/hypercall.h>\n#include <asm/svccc.h>\n#include <minos/console.h>\n#include <virt/vmm.h>\n#include <minos/of.h>\n#include <virt/resource.h>\n\n#define DCON_TTY_MAGIC\t\t0xabcd0000\n\n#define DCON_RX_RING_SIZE\t2048\n#define DCON_TX_RING_SIZE\t4096\n#define DCON_RING_SIZE\t\t8192\n\n#define NR_DC\t\t\t8\n\nstruct vm_debug_console {\n\tuint32_t irq;\n\tint open;\n\tstruct vm *vm;\n\tstruct tty *tty;\n\tunsigned long ring_addr;\n\tstruct vm_ring *tx;\n\tstruct vm_ring *rx;\n};\n\nstatic char *vm_debug_console_match[] = {\n\t\"minos,vm_console\",\n\tNULL\n};\n\nstatic struct vm_debug_console *dcons[NR_DC];\n\nstatic int dcon_putc(struct tty *tty, char ch)\n{\n\tstruct vm_debug_console *dcon = tty->pdata;\n\tstruct vm_ring *tx = dcon->tx;\n\n\tif (!dcon->open)\n\t\treturn 0;\n\n\tif ((tx->widx - tx->ridx) > tx->size) {\n\t\tpr_err(\"write buffer overflow\\n\");\n\t\treturn -EIO;\n\t}\n\n\ttx->buf[tx->widx++] = ch;\n\tmb();\n\n\tsend_virq_to_vm(dcon->vm, dcon->irq);\n\n\treturn 0;\n}\n\nstatic int dcon_putcs(struct tty *tty, char *str, int count)\n{\n\treturn 0;\n}\n\nstatic int dcon_open(struct tty *tty)\n{\n\treturn 0;\n}\n\nstatic void dcon_close(struct tty *tty)\n{\n\n}\n\nstruct tty_ops vm_tty_ops = {\n\t.put_char\t= dcon_putc,\n\t.put_chars\t= dcon_putcs,\n\t.open\t\t= dcon_open,\n\t.close\t\t= dcon_close,\n};\n\nstatic int dcon_get_resource(struct vm *vm, struct device_node *node,\n\t\tstruct vmm_area **__va, uint32_t *__irq)\n{\n\tint ret;\n\tstruct vmm_area *va;\n\tunsigned long flags;\n\tuint64_t base, size;\n\tuint32_t irq = 0;\n\n\tif (!of_get_bool(node, \"vc-dynamic-res\")) {\n\t\tret = translate_device_address(node, &base, &size);\n\t\tif (ret)\n\t\t\treturn -EINVAL;\n\n\t\tif (size < DCON_RING_SIZE) {\n\t\t\tpr_err(\"vm console size too small\\n\");\n\t\t\treturn -EINVAL;\n\t\t}\n\n\t\tret = vm_get_device_irq_index(vm, node, &irq, &flags, 0);\n\t\tif (ret)\n\t\t\treturn -EINVAL;\n\n\t\trequest_virq(vm, irq, 0);\n\t\tva = request_vmm_area(&vm->mm, base, 0, size,\n\t\t\t\tVM_GUEST_SHMEM | VM_RW);\n\t} else {\n\t\t/*\n\t\t * since the debug console is only for native vm which\n\t\t * will never released, so it is ok not set the physical\n\t\t * address in the vmm_area\n\t\t */\n\t\tva = alloc_free_vmm_area(&vm->mm, DCON_RING_SIZE,\n\t\t\tPAGE_MASK, VM_GUEST_SHMEM | VM_RW);\n\t\tif (!va)\n\t\t\treturn -ENOMEM;\n\t}\n\n\t*__va = va;\n\t*__irq = irq;\n\n\treturn 0;\n}\n\nstatic int dcon_init(struct vm *vm, struct device_node *node,\n\t\tstruct vm_debug_console *dcon, void *ring)\n{\n\tstruct vm_ring *r;\n\tstruct vmm_area *va;\n\n\tif (dcon_get_resource(vm, node, &va, &dcon->irq))\n\t\treturn -ENODEV;\n\n\tpr_notice(\"debug_console base: 0x%x\\n\", va->start);\n\n\tdcon->ring_addr = va->start;\n\tmap_vmm_area(&vm->mm, va, (unsigned long)ring);\n\n\t/*\n\t * init the vm ring struct\n\t */\n\tr = (struct vm_ring *)ring;\n\tr->ridx = 0;\n\tr->widx = 0;\n\tr->size = DCON_RX_RING_SIZE;\n\tdcon->tx = r;\n\n\tr = (struct vm_ring *)(ring + sizeof(struct vm_ring) +\n\t\t\tDCON_RX_RING_SIZE);\n\tr->ridx = 0;\n\tr->widx = 0;\n\tr->size = DCON_TX_RING_SIZE;\n\tdcon->rx = r;\n\n\treturn 0;\n}\n\nstatic int create_dconsole(struct vm *vm, struct device_node *node)\n{\n\tvoid *ring;\n\tstruct tty *tty;\n\tstruct vm_debug_console *dcon;\n\tchar name[16];\n\n\tif (!vm_is_native(vm) || (vm->vmid >= NR_DC))\n\t\treturn 0;\n\n\tmemset(name, 0, 16);\n\tsprintf(name, \"vm%d\", vm->vmid);\n\n\ttty = alloc_tty(name, vm->vmid | DCON_TTY_MAGIC, 0);\n\tif (!tty)\n\t\treturn -ENOENT;\n\n\tdcon = zalloc(sizeof(struct vm_debug_console));\n\tif (!dcon)\n\t\tgoto release_tty;\n\n\tring = alloc_shmem(PAGE_NR(DCON_RING_SIZE));\n\tif (!ring)\n\t\tgoto release_dcon;\n\n\tif (dcon_init(vm, node, dcon, ring))\n\t\tgoto free_ring;\n\n\tdcon->tty = tty;\n\tdcon->vm = vm;\n\tdcons[vm->vmid] = dcon;\n\n\ttty->ops = &vm_tty_ops;\n\ttty->pdata = dcon;\n\tregister_tty(tty);\n\n\treturn 0;\n\nfree_ring:\n\tfree_shmem(ring);\nrelease_dcon:\n\tfree(dcon);\nrelease_tty:\n\trelease_tty(tty);\n\treturn -ENOMEM;\n}\n\nVDEV_DECLARE(vm_debug_console, vm_debug_console_match, create_dconsole);\n\nstatic void dcon_write(struct vm_debug_console *dcon)\n{\n\tstruct vm_ring *ring = dcon->rx;\n\tuint32_t ridx, widx;\n\n\tif (!dcon->tty->open) {\n\t\tring->ridx = ring->widx;\n\t\twmb();\n\t\treturn;\n\t}\n\n\tridx = ring->ridx;\n\twidx = ring->widx;\n\tmb();\n\n\twhile (ridx != widx)\n\t\tconsole_putc(ring->buf[VM_RING_IDX(ridx++, ring->size)]);\n\n\tmb();\n\tring->ridx = ring->widx;\n}\n\nstatic int dcon_hvc_handler(gp_regs *c, uint32_t id, uint64_t *args)\n{\n\tstruct vm *vm = get_current_vm();\n\tstruct vm_debug_console *dcon;\n\n\tdcon = dcons[vm->vmid];\n\tif (!dcon)\n\t\tHVC_RET1(c, 0);\n\n\tswitch (id) {\n\tcase HVC_DC_GET_STAT:\n\t\tHVC_RET1(c, DCON_TTY_MAGIC | vm->vmid);\n\t\tbreak;\n\tcase HVC_DC_GET_RING:\n\t\tHVC_RET1(c, dcon->ring_addr);\n\t\tbreak;\n\tcase HVC_DC_GET_IRQ:\n\t\tif (dcon->irq == 0) {\n\t\t\tdcon->irq = alloc_vm_virq(vm);\n\t\t\tif (dcon->irq < 0)\n\t\t\t\tdcon->irq = 0;\n\t\t}\n\t\tHVC_RET1(c, dcon->irq);\n\t\tbreak;\n\tcase HVC_DC_WRITE:\n\t\tdcon_write(dcon);\n\t\tbreak;\n\tcase HVC_DC_OPEN:\n\t\tdcon->open = 1;\n\t\tbreak;\n\tcase HVC_DC_CLOSE:\n\t\tdcon->open = 0;\n\t\tbreak;\n\t}\n\n\tHVC_RET1(c, 0);\n}\nDEFINE_HVC_HANDLER(\"debug_console_hvc\", HVC_TYPE_DEBUG_CONSOLE,\n\t\tHVC_TYPE_DEBUG_CONSOLE, dcon_hvc_handler);\n"
  },
  {
    "path": "kernel/virt/hypercall.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <asm/svccc.h>\n#include <minos/sched.h>\n#include <virt/vm.h>\n#include <virt/hypercall.h>\n#include <virt/virq.h>\n#include <virt/virtio.h>\n#include <virt/vmcs.h>\n#include <virt/os.h>\n#include <virt/vm_pm.h>\n\nstatic int vm_hvc_handler(gp_regs *c, uint32_t id, uint64_t *args)\n{\n\tint vmid = -1, ret;\n\tunsigned long addr;\n\tunsigned long hbase = 0;\n\tstruct vm *vm = get_vm_by_id((uint32_t)args[0]);\n\n\tif (!vm_is_host_vm(get_current_vm()))\n\t\tpanic(\"only vm0 can call vm related hypercall\\n\");\n\n\tswitch (id) {\n\tcase HVC_VM_CREATE:\n\t\tvmid = create_guest_vm((struct vmtag *)args[0]);\n\t\tHVC_RET1(c, vmid);\n\t\tbreak;\n\n\tcase HVC_VM_DESTORY:\n\t\tdestroy_guest_vm(vm);\n\t\tHVC_RET1(c, 0);\n\t\tbreak;\n\n\tcase HVC_VM_RESTART:\n\t\tvmid = vm_reset((int)args[0], NULL, VM_PM_ACTION_BY_MVM);\n\t\tHVC_RET1(c, vmid);\n\t\tbreak;\n\n\tcase HVC_VM_POWER_UP:\n\t\tvmid = power_up_guest_vm((int)args[0]);\n\t\tHVC_RET1(c, vmid);\n\t\tbreak;\n\n\tcase HVC_VM_POWER_DOWN:\n\t\tvmid = vm_power_off((int)args[0], NULL, VM_PM_ACTION_BY_MVM);\n\t\tHVC_RET1(c, vmid);\n\t\tbreak;\n\n\tcase HVC_VM_MMAP:\n\t\tret = create_vm_mmap((int)args[0], args[1], args[2], &addr);\n\t\tHVC_RET2(c, ret, addr);\n\t\tbreak;\n\n\tcase HVC_VM_SEND_VIRQ:\n\t\tsend_virq_to_vm(get_vm_by_id((int)args[0]), (int)args[1]);\n\t\tHVC_RET1(c, 0);\n\t\tbreak;\n\n\tcase HVC_VM_CREATE_VMCS:\n\t\taddr = vm_create_vmcs(vm);\n\t\tHVC_RET1(c, addr);\n\t\tbreak;\n\n\tcase HVC_VM_REQUEST_VIRQ:\n\t\tvmid = request_vm_virqs(get_vm_by_id((int)args[0]),\n\t\t\t\t(int)args[1], (int)args[2]);\n\t\tHVC_RET1(c, vmid);\n\t\tbreak;\n\n\tcase HVC_VM_CREATE_VMCS_IRQ:\n\t\tvmid = vm_create_vmcs_irq(vm, (int)args[1]);\n\t\tHVC_RET1(c, vmid);\n\t\tbreak;\n\n\tcase HVC_VM_VIRTIO_MMIO_INIT:\n\t\tret = virtio_mmio_init(vm, args[1], args[2], &hbase);\n\t\tHVC_RET2(c, ret, hbase);\n\t\tbreak;\n\tcase HVC_VM_CREATE_RESOURCE:\n\t\tret = os_create_guest_vm_resource(vm);\n\t\tHVC_RET1(c, ret);\n\t\tbreak;\n\tcase HVC_CHANGE_LOG_LEVEL:\n\t\tchange_log_level((unsigned int)args[0]);\n\t\tbreak;\n\tdefault:\n\t\tpr_err(\"unsupport vm hypercall\");\n\t\tbreak;\n\t}\n\n\tHVC_RET1(c, -EINVAL);\n}\n\n#define CHECK_VM_CAP(vm, cap, flg, value) \\\n\t(value) |= (flg) & VM_FLAGS_HOST ? (cap) : 0;\n\nstatic unsigned long get_vm_capability(struct vm *vm)\n{\n\tunsigned long ret = 0;\n\n\tCHECK_VM_CAP(vm, VM_CAP_HOST, VM_FLAGS_HOST, ret);\n\tCHECK_VM_CAP(vm, VM_CAP_NATIVE, VM_FLAGS_NATIVE, ret);\n\n\treturn ret;\n}\n\nstatic int misc_hvc_handler(gp_regs *c, uint32_t id, uint64_t *args)\n{\n\tstruct vm *vm = get_current_vm();\n\n\tswitch (id) {\n\tcase HVC_GET_VMID:\n\t\tHVC_RET1(c, vm->vmid);\n\t\tbreak;\n\tcase HVC_SCHED_OUT:\n\t\tsched();\n\t\tHVC_RET1(c, 0);\n\t\tbreak;\n\tcase HVC_GET_VM_CAP:\n\t\tHVC_RET1(c, get_vm_capability(vm));\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\n\tHVC_RET1(c, -EINVAL);\n}\n\nDEFINE_HVC_HANDLER(\"vm_hvc_handler\", HVC_TYPE_VM0,\n\t\tHVC_TYPE_VM0, vm_hvc_handler);\n\nDEFINE_HVC_HANDLER(\"misc_hvc_handler\", HVC_TYPE_MISC,\n\t\tHVC_TYPE_MISC, misc_hvc_handler);\n"
  },
  {
    "path": "kernel/virt/iommu.c",
    "content": "// SPDX-License-Identifier: GPL-2.0\n\n#include <minos/errno.h>\n#include <minos/of.h>\n#include <virt/vm.h>\n#include <virt/iommu.h>\n\nstatic const struct iommu_ops *iommu_ops;\n\nint iommu_vm_init(struct vm *vm)\n{\n\tstruct vm_iommu *iommu = &vm->iommu;\n\tint ret;\n\n\tinit_list(&iommu->nodes);\n\n\tiommu->ops = iommu_ops;\n\n\tif (!iommu->ops || !iommu->ops->vm_init)\n\t\treturn 0;\n\n\tret = iommu->ops->vm_init(vm);\n\n\treturn ret;\n}\n\nint iommu_iotlb_flush_all(struct vm *vm)\n{\n\tstruct vm_iommu *iommu = &vm->iommu;\n\tint ret;\n\n\tif (!iommu->ops || !iommu->ops->iotlb_flush_all)\n\t\treturn 0;\n\n\t/* TODO: need to hold mm_lock? */\n\tret = iommu->ops->iotlb_flush_all(vm);\n\tif (ret)\n\t\tpr_err(\"vm%d: IOMMU IOTLB flush all failed: %d\\n\",\n\t\t\t\tvm_id(vm), ret);\n\n\treturn ret;\n}\n\nint iommu_assign_node(struct vm *vm, struct device_node *node)\n{\n\tstruct vm_iommu *iommu = &vm->iommu;\n\tint ret;\n\tchar name[32];\n\tstruct device_node *stub_node;\n\n\tret = of_get_string(node, \"minos,stub-node\", name, ARRAY_SIZE(name));\n\tif (ret <= 0)\n\t\treturn 0;\n\n\tstub_node = of_find_node_by_name(of_root_node, name);\n\tif (!stub_node)\n\t\treturn -ENOENT;\n\n\tif (!iommu->ops || !iommu->ops->assign_node)\n\t\treturn 0;\n\n\tpr_info(\"[VM%d NODE] %s <- %s\\n\", vm_id(vm), devnode_name(stub_node),\n\t\tdevnode_name(node));\n\n\tret = iommu->ops->assign_node(vm, stub_node);\n\n\treturn ret;\n}\n\nstatic void *iommu_ops_init(struct device_node *node, void *arg)\n{\n\textern unsigned char __iommu_ops_start;\n\textern unsigned char __iommu_ops_end;\n\tvoid *s, *e;\n\tstruct iommu_ops *ops;\n\n\ts = (void *)&__iommu_ops_start;\n\te = (void *)&__iommu_ops_end;\n\n\tops = (struct iommu_ops *)of_device_node_match(node, s, e);\n\tif (!ops)\n\t\treturn NULL;\n\n\t/*\n\t * Some platforms have tree-like IOMMUs, so this function may be\n\t * called multiple times.\n\t */\n\tif (!iommu_ops)\n\t\tiommu_ops = ops;\n\telse if (iommu_ops != ops)\n\t\tpr_warn(\"Cannot set IOMMU ops, already set to a different value\\n\");\n\n\tif (ops->init)\n\t\tops->init(node);\n\n\treturn node;\n}\n\nstatic void of_iommu_init(void)\n{\n\tof_iterate_all_node_loop(of_root_node, iommu_ops_init, NULL);\n}\n\nstatic int iommu_init(void)\n{\n#ifdef CONFIG_DEVICE_TREE\n\tof_iommu_init();\n#endif\n\n\treturn 0;\n}\n\nsubsys_initcall(iommu_init);\n"
  },
  {
    "path": "kernel/virt/os/Kconfig",
    "content": "menu \"VM operating system support\"\n\nconfig OS_LINUX_SUPPORT\n\tbool \"Support linux based virtual machine\"\n\tdefault y\n\nconfig OS_XNU_SUPPORT\n\tbool \"Support xnu based virtual machine\"\n\tdefault y\n\tselect VIRQCHIP_AIC\n\nendmenu\n"
  },
  {
    "path": "kernel/virt/os/Makefile",
    "content": "obj-y\t+= os.o\nobj-y\t+= os_other.o\nobj-y\t+= os_linux.o\nobj-y\t+= os_xnu.o\n"
  },
  {
    "path": "kernel/virt/os/os.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/sched.h>\n#include <virt/os.h>\n#include <virt/vm.h>\n\nstatic struct os *oses[OS_TYPE_MAX];\n\nstatic void default_vm_init(struct vm *vm)\n{\n\tpr_warn(\"vm [%s] using %s\\n\", vm->name, __func__);\n}\n\nstatic void default_vcpu_init(struct vcpu *vcpu)\n{\n\tpr_warn(\"vm [%s] using %s\\n\", vcpu->vm->name, __func__);\n}\n\nstatic void default_vcpu_power_on(struct vcpu *vcpu, unsigned long entry)\n{\n\tpr_warn(\"vm [%s] using %s\\n\", vcpu->vm->name, __func__);\n}\n\nstatic void default_vm_setup(struct vm *vm)\n{\n\tpr_warn(\"vm [%s] using %s\\n\", vm->name, __func__);\n}\n\nstatic int default_create_gvm_res(struct vm *vm)\n{\n\tpr_warn(\"vm [%s] using %s\\n\", vm->name, __func__);\n\treturn 0;\n}\n\nstatic int default_create_nvm_res(struct vm *vm)\n{\n\tpr_warn(\"vm [%s] using %s\\n\", vm->name, __func__);\n\treturn 0;\n}\n\nint register_os(char *name, int type, struct os_ops *ops)\n{\n\tstruct os *os;\n\n\tif (!ops || (oses[type] != NULL)) {\n\t\tpr_err(\"os [%d] error already register or no ops\\n\", type);\n\t\treturn -EEXIST;\n\t}\n\n\tos = (struct os *)zalloc(sizeof(struct os));\n\tif (!os)\n\t\treturn -ENOMEM;\n\n\tif (!ops->vm_init)\n\t\tops->vm_init = default_vm_init;\n\tif (!ops->vcpu_init)\n\t\tops->vcpu_init = default_vcpu_init;\n\tif (!ops->vcpu_power_on)\n\t\tops->vcpu_power_on = default_vcpu_power_on;\n\tif (!ops->vm_setup)\n\t\tops->vm_setup = default_vm_setup;\n\tif (!ops->create_gvm_res)\n\t\tops->create_gvm_res = default_create_gvm_res;\n\tif (!ops->create_nvm_res)\n\t\tops->create_nvm_res = default_create_nvm_res;\n\n\tos->type = type;\n\tos->ops = ops;\n\tstrncpy(os->name, name, sizeof(os->name) - 1);\n\toses[type] = os;\n\n\treturn 0;\n}\n\nstruct os *get_vm_os(char *type)\n{\n\tint i;\n\tstruct os *os;\n\n\tif (!type)\n\t\tgoto out;\n\n\tfor (i = 0; i < OS_TYPE_MAX; i++) {\n\t\tos = oses[i];\n\n\t\tif (!strcmp(os->name, type))\n\t\t\treturn os;\n\t}\n\nout:\n\treturn oses[OS_TYPE_OTHERS];\n}\n\nvoid os_setup_vm(struct vm *vm)\n{\n\tvm->os->ops->vm_setup(vm);\n}\n\nint os_create_native_vm_resource(struct vm *vm)\n{\n\treturn vm->os->ops->create_nvm_res(vm);\n}\n\nint os_create_guest_vm_resource(struct vm *vm)\n{\n\treturn vm->os->ops->create_gvm_res(vm);\n}\n\nvoid os_vcpu_power_on(struct vcpu *vcpu, unsigned long entry)\n{\n\tstruct os *os = vcpu->vm->os;\n\tos->ops->vcpu_power_on(vcpu, entry);\n}\n\nvoid os_vm_init(struct vm *vm)\n{\n\tvm->os->ops->vm_init(vm);\n}\n"
  },
  {
    "path": "kernel/virt/os/os_linux.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/mm.h>\n#include <virt/vmm.h>\n#include <libfdt/libfdt.h>\n#include <virt/vm.h>\n#include <minos/platform.h>\n#include <minos/of.h>\n#include <config/config.h>\n#include <virt/virq_chip.h>\n#include <virt/virq.h>\n#include <virt/vmbox.h>\n#include <minos/sched.h>\n#include <minos/arch.h>\n#include <virt/os.h>\n#include <virt/resource.h>\n#include <generic/hypervisor.h>\n#include <minos/ramdisk.h>\n#include <asm/cache.h>\n\nstatic int fdt_setup_other(struct vm *vm)\n{\n\treturn 0;\n}\n\nstatic int fdt_setup_romflash(struct vm *vm)\n{\n\tvoid *dtb = (void *)ptov(vm->setup_data);\n\tunsigned long addr;\n\tstruct vmm_area *va;\n\tuint32_t size;\n\tchar name[128];\n\tint node;\n\n\tif (!vm->initrd_file)\n\t\treturn 0;\n\n\t/*\n\t * find the best memory region for initrd ramdisk.\n\t */\n\tsize = ramdisk_file_size(vm->initrd_file);\n\tva = alloc_free_vmm_area(&vm->mm, size, PAGE_MASK,\n\t\t\tVM_NORMAL_NC | VM_PFNMAP | VM_RO | VM_SHARED);\n\tif (!va)\n\t\treturn -ENOMEM;\n\n\taddr = vtop(ramdisk_file_base(vm->initrd_file));\n\tif (map_vmm_area(&vm->mm, va, addr)) {\n\t\tpr_err(\"map ramdisk memory to vm%d failed\\n\", vm->vmid);\n\t\trelease_vmm_area(&vm->mm, va);\n\t\treturn -ENOMEM;\n\t}\n\n\t/*\n\t * add initrd information to the device tree. Here the\n\t * memory region will used as a map_rom in linux system, so\n\t * add a rom device to the dts.\n\t */\n\tmemset(name, 0, 128);\n\tstrcpy(name, \"of-flash\");\n\tnode = fdt_add_subnode(dtb, 0, name);\n\tif (node < 0) {\n\t\tpr_err(\"failed to add rom flash device to vm%d\\n\", vm->vmid);\n\t\tunmap_vmm_area(&vm->mm, va);\n\t\trelease_vmm_area(&vm->mm, va);\n\t}\n\n\tfdt_setprop(dtb, node, \"compatible\", \"minos,rom-flash\", 17);\n\tfdt_set_node_reg(dtb, node, va->start, PAGE_BALIGN(size));\n\tfdt_setprop(dtb, node, \"linux,mtd-name\", \"rom\", 4);\n\n\treturn 0;\n}\n\nstatic int fdt_setup_minos(struct vm *vm)\n{\n\tvoid *dtb = (void *)ptov(vm->setup_data);\n\tint node;\n\n\tnode = fdt_path_offset(dtb, \"/minos\");\n\tif (node < 0) {\n\t\tnode = fdt_add_subnode(dtb, 0, \"minos\");\n\t\tif (node < 0)\n\t\t\treturn node;\n\t}\n\n\tfdt_setprop(dtb, node, \"compatible\", \"minos,hypervisor\", 17);\n\treturn 0;\n}\n\nstatic int fdt_setup_vm_virqs(struct vm *vm)\n{\n\tint node, i;\n\tuint32_t *tmp = NULL;\n\tsize_t size;\n\tint vspi_nr = vm->vspi_nr;\n\tstruct virq_chip *vc = vm->virq_chip;\n\tvoid *dtb = (void *)ptov(vm->setup_data);\n\n\tnode = fdt_path_offset(dtb, \"/vm_fake_device\");\n\tif (node < 0) {\n\t\tnode = fdt_add_subnode(dtb, 0, \"vm_fake_device\");\n\t\tif (node < 0)\n\t\t\treturn node;\n\t}\n\n\tsize = vspi_nr * sizeof(uint32_t) * 3;\n\tsize = PAGE_BALIGN(size);\n\ttmp = (uint32_t *)get_free_pages(PAGE_NR(size));\n\tif (!tmp) {\n\t\tpr_err(\"fdt setup minos failed no memory\\n\");\n\t\treturn -ENOMEM;\n\t}\n\n\tfdt_setprop(dtb, node, \"compatible\", \"minos,fakedev\", 17);\n\tsize = 0;\n\n\tif (vc && vc->generate_virq) {\n\t\tfor (i = 0; i < vspi_nr; i++) {\n\t\t\tif (!virq_need_export(vm->vcpus[0],\n\t\t\t\t\ti + VM_LOCAL_VIRQ_NR))\n\t\t\t\tcontinue;\n\t\t\tsize += vc->generate_virq(tmp + size,\n\t\t\t\t\ti + VM_LOCAL_VIRQ_NR);\n\t\t}\n\t}\n\n\tif (size) {\n\t\ti = fdt_setprop(dtb, node, \"interrupts\",\n\t\t\t\t(void *)tmp, size * sizeof(uint32_t));\n\t\tif (i)\n\t\t\tpr_err(\"fdt set interrupt for minos failed\\n\");\n\t}\n\n\tfree_pages(tmp);\n\n\treturn i;\n}\n\nstatic int fdt_setup_cmdline(struct vm *vm)\n{\n\tint node, len, chosen_node;\n\tchar *new_cmdline;\n\tchar buf[128];\n\tvoid *vm_dtb = (void *)ptov(vm->setup_data);\n\tvoid *hv_dtb = dtb_address;\n\n\tchosen_node = fdt_path_offset(vm_dtb, \"/chosen\");\n\tif (chosen_node < 0) {\n\t\tchosen_node = fdt_add_subnode(vm_dtb, 0, \"chosen\");\n\t\tif (chosen_node < 0) {\n\t\t\tpr_err(\"add chosen node failed for vm%d\\n\", vm->vmid);\n\t\t\treturn chosen_node;\n\t\t}\n\t}\n\n\tlen = sprintf(buf, \"/vms/vm%d\", vm->vmid);\n\tbuf[len] = 0;\n\n\tnode = fdt_path_offset(hv_dtb, buf);\n\tif (node < 0)\n\t\treturn 0;\n\n\tnew_cmdline = (char *)fdt_getprop(hv_dtb, node, \"cmdline\", &len);\n\tif (!new_cmdline || len <= 0) {\n\t\tpr_notice(\"no new cmdline using default\\n\");\n\t\treturn 0;\n\t}\n\n\tpr_notice(\"New cmdline: %s\\n\", new_cmdline);\n\n\t/*\n\t * can not directly using new_cmdline in fdt_setprop\n\t * do not know why, there may a issue in libfdt or\n\t * other reason\n\t */\n\tfdt_setprop(vm_dtb, chosen_node, \"bootargs\", new_cmdline, len);\n\n\treturn 0;\n}\n\nstatic int fdt_setup_cpu(struct vm *vm)\n{\n\tint offset, node, i;\n\tchar name[16];\n\tvoid *dtb = (void *)ptov(vm->setup_data);\n\tuint64_t aff_id;\n\n\t/*\n\t * delete unused vcpu for hvm\n\t */\n\toffset = of_get_node_by_name(dtb, 0, \"cpus\");\n\tif (offset < 0) {\n\t\tpr_err(\"can not find cpus node in dtb\\n\");\n\t\treturn -ENOENT;\n\t}\n\n\tfor (i = vm->vcpu_nr; i < CONFIG_MAX_CPU_NR; i++) {\n\t\tif (vm_is_host_vm(vm))\n\t\t\taff_id = cpuid_to_affinity(i);\n\t\telse\n\t\t\taff_id = i;\n\n\t\tsprintf(name, \"cpu@%x\", aff_id);\n\t\tnode = fdt_subnode_offset(dtb, offset, name);\n\t\tif (node >= 0) {\n\t\t\tpr_notice(\"delete vcpu %s for vm%d\\n\", name, vm->vmid);\n\t\t\tfdt_del_node(dtb, node);\n\t\t}\n\t}\n\n\treturn 0;\n}\n\nstatic int fdt_setup_memory(struct vm *vm)\n{\n\tint offset, size;\n\tint size_cell, address_cell;\n\tuint32_t *args, *tmp;\n\tunsigned long mstart, msize;\n\tvoid *dtb = (void *)ptov(vm->setup_data);\n\tstruct vmm_area *va;\n\n\toffset = of_get_node_by_name(dtb, 0, \"memory\");\n\tif (offset < 0) {\n\t\toffset = fdt_add_subnode(dtb, 0, \"memory\");\n\t\tif (offset < 0)\n\t\t\treturn offset;\n\n\t\tfdt_setprop(dtb, offset, \"device_type\", \"memory\", 7);\n\t}\n\n\tsize_cell = fdt_n_size_cells(dtb, offset);\n\taddress_cell = fdt_n_addr_cells(dtb, offset);\n\tpr_notice(\"%s size-cells:%d address-cells:%d\\n\",\n\t\t\t__func__, size_cell, address_cell);\n\n\tif ((size_cell < 1) || (address_cell < 1))\n\t\treturn -EINVAL;\n\n\ttmp = args = (uint32_t *)get_free_page();\n\tif (!args)\n\t\treturn -ENOMEM;\n\n\tsize = 0;\n\n\tlist_for_each_entry(va, &vm->mm.vmm_area_used, list) {\n\t\tif (!(va->flags & VM_NORMAL))\n\t\t\tcontinue;\n\n\t\tmstart = va->start;\n\t\tmsize = va->end - va->start;\n\n\t\tpr_notice(\"add memory region to vm%d 0x%p 0x%p\\n\",\n\t\t\t\tvm->vmid, mstart, msize);\n\n\t\tif (address_cell == 1) {\n\t\t\t*args++ = cpu_to_fdt32(mstart);\n\t\t\tsize++;\n\t\t} else {\n\t\t\t*args++ = cpu_to_fdt32(mstart >> 32);\n\t\t\t*args++ = cpu_to_fdt32(mstart);\n\t\t\tsize += 2;\n\t\t}\n\n\t\tif (size_cell ==  1) {\n\t\t\t*args++ = cpu_to_fdt32(msize);\n\t\t\tsize++;\n\t\t} else {\n\t\t\t*args++ = cpu_to_fdt32(msize >> 32);\n\t\t\t*args++ = cpu_to_fdt32(msize);\n\t\t\tsize += 2;\n\t\t}\n\t}\n\n\tfdt_setprop(dtb, offset, \"reg\", (void *)tmp, size * 4);\n\tfree_pages(tmp);\n\n\treturn 0;\n}\n\nstatic void fdt_vm_init(struct vm *vm)\n{\n\tvoid *fdt = (void *)ptov(vm->setup_data);\n\n\tfdt_open_into(fdt, fdt, MAX_DTB_SIZE);\n\tif(fdt_check_header(fdt)) {\n\t\tpr_err(\"invaild dtb after open into\\n\");\n\t\treturn;\n\t}\n\n\tif (vm_is_host_vm(vm))\n\t\tfdt_setup_minos(vm);\n\n\t/*\n\t * current need to export all the irq number\n\t * to the VM, if one device need to request\n\t * the virq dynmaic, TO BE FIXED\n\t */\n\tif (vm_is_native(vm))\n\t\tfdt_setup_vm_virqs(vm);\n\n\tfdt_setup_cmdline(vm);\n\tfdt_setup_cpu(vm);\n\tfdt_setup_memory(vm);\n\tfdt_setup_romflash(vm);\n\tfdt_setup_other(vm);\n\n\tvmbox_init(vm);\n\n\tif (platform->setup_hvm && vm_is_host_vm(vm))\n\t\tplatform->setup_hvm(vm, fdt);\n\n\tfdt_pack(fdt);\n}\n\nstatic inline void __linux_vcpu_startup(struct vcpu *vcpu, unsigned long entry)\n{\n\tgp_regs *regs;\n\n\tarch_vcpu_init(vcpu, (void *)entry, NULL);\n\tregs = (gp_regs *)vcpu->task->stack_base;\n\n\t/* fill the dtb address to x0 */\n\tif (get_vcpu_id(vcpu) == 0) {\n\t\tif (!task_is_32bit(vcpu->task)) {\n\t\t\tregs->x0 = (uint64_t)vcpu->vm->setup_data;\n\t\t} else {\n\t\t\tregs->x0 = 0;\n\t\t\tregs->x1 = 2272;\t\t/* arm vexpress machine type */\n\t\t\tregs->x2 = (uint64_t)vcpu->vm->setup_data;\n\t\t}\n\t} else {\n\t\tregs->x0 = 0;\n\t\tregs->x1 = 0;\n\t\tregs->x2 = 0;\n\t\tregs->x3 = 0;\n\t}\n}\n\nstatic void linux_vcpu_startup(struct vcpu *vcpu)\n{\n\t__linux_vcpu_startup(vcpu, (unsigned long)vcpu->vm->entry_point);\n}\n\nstatic void linux_vcpu_power_on(struct vcpu *vcpu, unsigned long entry)\n{\n\t__linux_vcpu_startup(vcpu, entry);\n}\n\nstatic void linux_vm_setup(struct vm *vm)\n{\n\tfdt_vm_init(vm);\n}\n\nstatic int linux_create_native_vm_resource(struct vm *vm)\n{\n\tif (vm->flags & VM_FLAGS_NATIVE) {\n\t\tif (vm->kernel_file && vm->dtb_file)\n\t\t\tvm->flags |= VM_FLAGS_CAN_RESET;\n\t}\n\n\tif (vm->setup_data) {\n\t\tif (of_data((void *)ptov(vm->setup_data))) {\n\t\t\tvm->flags |= VM_FLAGS_SETUP_OF;\n\t\t\tcreate_vm_resource_of(vm, (void *)ptov(vm->setup_data));\n\t\t}\n\t}\n\n\t/*\n\t * check whether there are some resource need\n\t * to created from the hypervisor's dts\n\t */\n\tcreate_native_vm_resource_common(vm);\n\n\treturn 0;\n}\n\nstatic int linux_create_guest_vm_resource(struct vm *vm)\n{\n\tphy_addr_t addr;\n\tint ret;\n\n\tret = translate_guest_ipa(&vm->mm, (unsigned long)vm->setup_data, &addr);\n\tif (ret) {\n\t\tpr_err(\"translate 0x%p in vm%d failed\\n\",\n\t\t\t\tvm->setup_data, vm->vmid);\n\t\treturn -EFAULT;\n\t}\n\n\tret = create_host_mapping(ptov(addr), addr, MAX_DTB_SIZE,\n\t\t\tVM_NORMAL | VM_RW | VM_HUGE);\n\tif (ret) {\n\t\tpr_err(\"map guest setup data failed\\n\");\n\t\treturn ret;\n\t}\n\n\tret = create_vm_resource_of(vm, (void *)addr);\n\n\tflush_dcache_range(ptov(addr), MAX_DTB_SIZE);\n\tdestroy_host_mapping(ptov(addr), MAX_DTB_SIZE);\n\n\treturn ret;\n}\n\nstruct os_ops linux_os_ops = {\n\t.vcpu_init \t= linux_vcpu_startup,\n\t.vcpu_power_on \t= linux_vcpu_power_on,\n\t.vm_setup \t= linux_vm_setup,\n\t.create_nvm_res = linux_create_native_vm_resource,\n\t.create_gvm_res = linux_create_guest_vm_resource,\n};\n\nstatic int __init_text os_linux_init(void)\n{\n\treturn register_os(\"linux\", OS_TYPE_LINUX, &linux_os_ops);\n}\nmodule_initcall(os_linux_init);\n"
  },
  {
    "path": "kernel/virt/os/os_other.c",
    "content": "/*\n * Copyright (C) 2019 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/sched.h>\n#include <minos/init.h>\n#include <virt/vm.h>\n#include <virt/resource.h>\n#include <virt/os.h>\n#include <virt/vmbox.h>\n\nstatic void default_vcpu_init(struct vcpu *vcpu)\n{\n\tif (get_vcpu_id(vcpu) == 0)\n\t\tarch_vcpu_init(vcpu, (void *)vcpu->vm->entry_point, NULL);\n}\n\nstatic void default_vm_setup(struct vm *vm)\n{\n\tvmbox_init(vm);\n}\n\nstatic int default_create_guest_vm_resource(struct vm *vm)\n{\n\treturn 0;\n}\n\nstatic int default_create_native_vm_resource(struct vm *vm)\n{\n\treturn create_native_vm_resource_common(vm);\n}\n\nstruct os_ops default_os_ops = {\n\t.vcpu_init\t= default_vcpu_init,\n\t.vm_setup\t= default_vm_setup,\n\t.create_gvm_res = default_create_guest_vm_resource,\n\t.create_nvm_res = default_create_native_vm_resource,\n};\n\nstatic int __init_text os_default_init(void)\n{\n\treturn register_os(\"default-os\", OS_TYPE_OTHERS, &default_os_ops);\n}\nmodule_initcall(os_default_init);\n"
  },
  {
    "path": "kernel/virt/os/os_xnu.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/mm.h>\n#include <virt/vmm.h>\n#include <libfdt/libfdt.h>\n#include <virt/vm.h>\n#include <minos/platform.h>\n#include <minos/of.h>\n#include <virt/virq_chip.h>\n#include <virt/virq.h>\n#include <virt/vmbox.h>\n#include <minos/sched.h>\n#include <minos/arch.h>\n#include <virt/os.h>\n#include <virt/resource.h>\n#include <asm/virt.h>\n#include <asm/reg.h>\n\n#define ASOC_VTIMER_VIRQ\t26\n#define ASOC_DCZVA_SIZE\t\t0x40\n\nstruct virq_chip *create_aic_virqchip(struct vm *vm,\n\t\tunsigned long base, unsigned long size);\n\nstatic int apple_soc_dczva_trap(struct vcpu *vcpu, unsigned long va)\n{\n\tunsigned long pa = guest_va_to_pa(va, 0);\n\n\tif (pa > 0x80000000)\n\t\tmemset((void *)pa, 0, ASOC_DCZVA_SIZE);\n\telse {\n\t\tpa = guest_va_to_pa(va, 1);\n\t\tif (pa > 0x80000000)\n\t\t\tmemset((void *)pa, 0, ASOC_DCZVA_SIZE);\n\t\telse\n\t\t\tpr_err(\"wrong address va:0x%p pa:0x%p\\n\", va, pa);\n\t}\n\n\treturn 0;\n}\n\nstatic int apple_soc_unknow_sysreg(struct vcpu *vcpu,\n\t\tint reg, int read, unsigned long *value)\n{\n\t*value = 0;\n\n\tswitch (reg) {\n\tcase ESR_SYSREG_ASOC_HID11:\n\t\tpr_debug(\"apple soc reg: %s\\n\", \"ESR_SYSREG_ASOC_HID11\\n\");\n\t\tbreak;\n\tcase ESR_SYSREG_ASOC_HID5:\n\t\tpr_debug(\"apple soc reg: %s\\n\", \"ESR_SYSREG_ASOC_HID5\\n\");\n\t\tbreak;\n\tcase ESR_SYSREG_ASOC_HID4:\n\t\tpr_debug(\"apple soc reg: %s\\n\", \"ESR_SYSREG_ASOC_HID4\\n\");\n\t\tbreak;\n\tcase ESR_SYSREG_ASOC_HID8:\n\t\tpr_debug(\"apple soc reg: %s\\n\", \"ESR_SYSREG_ASOC_HID8\\n\");\n\t\tbreak;\n\tcase ESR_SYSREG_ASOC_HID7:\n\t\tpr_debug(\"apple soc reg: %s\\n\", \"ESR_SYSREG_ASOC_HID7\\n\");\n\t\tbreak;\n\tcase ESR_SYSREG_ASOC_LSU_ERR_STS:\n\t\tpr_debug(\"apple soc reg: %s\\n\", \"ESR_SYSREG_ASOC_LSU_ERR_STS\\n\");\n\t\tbreak;\n\tcase ESR_SYSREG_ASOC_PMC0:\n\t\tpr_debug(\"apple soc reg: %s\\n\", \"ESR_SYSREG_ASOC_PMC0\\n\");\n\t\tbreak;\n\tcase ESR_SYSREG_ASOC_PMC1:\n\t\tpr_debug(\"apple soc reg: %s\\n\", \"ESR_SYSREG_ASOC_PMC1\\n\");\n\t\tbreak;\n\tcase ESR_SYSREG_ASOC_PMCR1:\n\t\tpr_debug(\"apple soc reg: %s\\n\", \"ESR_SYSREG_ASOC_PMCR1\\n\");\n\t\tbreak;\n\tcase ESR_SYSREG_ASOC_PMSR:\n\t\tpr_debug(\"apple soc reg: %s\\n\", \"ESR_SYSREG_ASOC_PMSR\\n\");\n\t\tbreak;\n\tdefault:\n\t\tpr_debug(\"apple soc reg: %s\\n\", \"UNKNOWN\\n\");\n\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\nstatic int xnu_create_gvm_res_apple(struct vm *vm)\n{\n\tstruct arm_virt_data *arm_data = vm->arch_data;\n\n\trequest_virq_pervcpu(vm, ASOC_VTIMER_VIRQ, VIRQF_FIQ);\n\n\tvm->virq_chip = create_aic_virqchip(vm, 0x20e100000, 0x100000);\n\tif (!vm->virq_chip) {\n\t\tpr_err(\"create virq chiq for apple soc failed\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\t/*\n\t * install trap callback for apple soc\n\t */\n\tarm_data->dczva_trap = apple_soc_dczva_trap;\n\tarm_data->sysreg_emulation = apple_soc_unknow_sysreg;\n\n\treturn 0;\n}\n\nstatic void xnu_vm_init(struct vm *vm)\n{\n\n}\n\nstatic void xnu_vcpu_init(struct vcpu *vcpu)\n{\n\tgp_regs *regs;\n\n\t/*\n\t * xnu will use X0 to store the boot argument\n\t * so set the setup data address to x0\n\t */\n\tif (get_vcpu_id(vcpu) == 0) {\n\t\tarch_vcpu_init(vcpu, (void *)vcpu->vm->entry_point, NULL);\n\t\tregs = (gp_regs *)vcpu->task->stack_base;\n\t\tregs->x0 = (uint64_t)vcpu->vm->setup_data;\n\t}\n\n\tvirq_set_fiq(vcpu, vcpu->vm->vtimer_virq);\n}\n\nstatic void xnu_vcpu_power_on(struct vcpu *vcpu, unsigned long entry)\n{\n\n}\n\nstatic void xnu_vm_setup(struct vm *vm)\n{\n\n}\n\nstatic int xnu_create_gvm_res(struct vm *vm)\n{\n\t/*\n\t * if for apple soc currently only support few soc\n\t * apple use AIC and it's own timer controller\n\t */\n//\tif (vm->flags & VM_FLAGS_XNU_APPLE)\n\t\txnu_create_gvm_res_apple(vm);\n\n\treturn 0;\n}\n\nstatic int xnu_create_nvm_res(struct vm *vm)\n{\n\treturn create_native_vm_resource_common(vm);\n}\n\nstatic struct os_ops os_xnu_ops = {\n\t.vm_init\t= xnu_vm_init,\n\t.vcpu_init\t= xnu_vcpu_init,\n\t.vcpu_power_on\t= xnu_vcpu_power_on,\n\t.vm_setup\t= xnu_vm_setup,\n\t.create_gvm_res\t= xnu_create_gvm_res,\n\t.create_nvm_res = xnu_create_nvm_res,\n};\n\nstatic int __init_text os_xnu_init(void)\n{\n\treturn register_os(\"xnu\", OS_TYPE_XNU, &os_xnu_ops);\n}\nmodule_initcall(os_xnu_init);\n"
  },
  {
    "path": "kernel/virt/resource.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/list.h>\n#include <minos/of.h>\n#include <virt/vm.h>\n#include <virt/vdev.h>\n#include <virt/virq_chip.h>\n#include <minos/mm.h>\n#include <virt/vmm.h>\n#include <minos/irq.h>\n#include <virt/vmbox.h>\n#include <minos/platform.h>\n#include <virt/iommu.h>\n\nstatic void *virqchip_start;\nstatic void *virqchip_end;\nstatic void *vdev_start;\nstatic void *vdev_end;\n\nstatic int create_vm_vdev_of(struct vm *vm, struct device_node *node)\n{\n\tvdev_init_t func;\n\n\tpr_info(\"%s %s\\n\", __func__, node->name);\n\n\tif (!node->compatible)\n\t\treturn -EINVAL;\n\n\tfunc = (vdev_init_t)of_device_node_match(node,\n\t\t\tvdev_start, vdev_end);\n\tif (!func) {\n\t\tpr_warn(\"can not find vdev-%s\\n\", node->compatible);\n\t\treturn -ENOENT;\n\t}\n\n\t/* create the vdev */\n\tfunc(vm, node);\n\n\treturn 0;\n}\n\nstatic void *create_vm_irqchip_of(struct device_node *node, void *arg)\n{\n\tstruct vm *vm = (struct vm *)arg;\n\tvdev_init_t func;\n\n\tif (node->class != DT_CLASS_IRQCHIP)\n\t\treturn NULL;\n\tif (vm->virq_chip != NULL) {\n\t\tpr_warn(\"virq chip has been created\\n\");\n\t\treturn NULL;\n\t}\n\n\tfunc = (vdev_init_t)of_device_node_match(node,\n\t\t\tvirqchip_start, virqchip_end);\n\tif (!func) {\n\t\tpr_warn(\"virq-chip :%s not found\\n\", node->compatible ?\n\t\t\t\tnode->compatible : \"Null\");\n\t\treturn NULL;\n\t}\n\n\tvm->virq_chip = func(vm, (void *)node);\n\tif (!vm->virq_chip)\n\t\treturn NULL;\n\n\tnode->class = DT_CLASS_VIRQCHIP;\n\tpr_info(\"create virq_chip %s successfully\\n\", node->compatible);\n\n\treturn node;\n}\n\nint parse_vm_info_of(struct device_node *node, struct vmtag *vmtag)\n{\n\t/*\n\t * The setup data address need 2M align, since the memory will\n\t * mapped into hypervisor, and hypervisor may modify it. Currently\n\t * ususally the device tree, and the size can not beyond 2M.\n\t *\n\t * VMID can not be 0.\n\t */\n\tmemset(vmtag, 0, sizeof(*vmtag));\n\tof_get_u32_array(node, \"vmid\", &vmtag->vmid, 1);\n\tof_get_u64_array(node, \"setup_data\", (uint64_t *)&vmtag->setup_data, 1);\n\tif (!IS_BLOCK_ALIGN(vmtag->setup_data)) {\n\t\tpr_err(\"setup data address not correct %d 0x%x\\n\",\n\t\t\t\tvmtag->vmid, vmtag->setup_data);\n\t\treturn -EINVAL;\n\t}\n\n\tof_get_string(node, \"vm_name\", vmtag->name, 32);\n\tof_get_string(node, \"type\", vmtag->os_type, 16);\n\tof_get_u32_array(node, \"vcpus\", (uint32_t *)&vmtag->nr_vcpu, 1);\n\tof_get_u64_array(node, \"entry\", (uint64_t *)&vmtag->entry, 1);\n\tof_get_u32_array(node, \"vcpu_affinity\",\n\t\t\tvmtag->vcpu_affinity, vmtag->nr_vcpu);\n\tof_get_u64_array(node, \"load-address\", &vmtag->load_address, 1);\n\n\tif (of_get_bool(node, \"disabled\")) {\n\t\tpr_notice(\"vm%d [%s] disabled in dts\\n\", vmtag->vmid, vmtag->name);\n\t\treturn -EINVAL;\n\t}\n\n\tif (of_get_bool(node, \"vm_32bit\"))\n\t\tvmtag->flags |= VM_FLAGS_32BIT;\n\n\tif (of_get_bool(node, \"native_wfi\"))\n\t\tvmtag->flags |= VM_FLAGS_NATIVE_WFI;\n\n\tif (of_get_bool(node, \"no_of_resource\"))\n\t\tvmtag->flags |= VM_FLAGS_NO_OF_RESOURCE;\n\n\tif (of_get_bool(node, \"host_vm\"))\n\t\tvmtag->flags |= VM_FLAGS_HOST;\n\n\tvmtag->kernel_file = of_getprop(node, \"kernel_image\", NULL);\n\tvmtag->dtb_file = of_getprop(node, \"dtb_image\", NULL);\n\tvmtag->initrd_file = of_getprop(node, \"initrd_image\", NULL);\n\n\t/*\n\t * all the VM created by hypervisor directoly is native vm.\n\t */\n\tvmtag->flags |= VM_FLAGS_NATIVE;\n\n\treturn 0;\n}\n\nint vm_get_device_irq_index(struct vm *vm, struct device_node *node,\n\t\tuint32_t *irq, unsigned long *flags, int index)\n{\n\tint irq_cells, len, i;\n\tof32_t *value;\n\tuint32_t irqv[4];\n\n\tif (!node)\n\t\treturn -EINVAL;\n\n\tvalue = (of32_t *)of_getprop(node, \"interrupts\", &len);\n\tif (!value || (len < sizeof(of32_t)))\n\t\treturn -ENOENT;\n\n\tirq_cells = of_n_interrupt_cells(node);\n\tif (irq_cells == 0) {\n\t\tpr_err(\"bad irqcells - %s\\n\", node->name);\n\t\treturn -ENOENT;\n\t}\n\n\tpr_debug(\"interrupt-cells %d\\n\", irq_cells);\n\n\tlen = len / sizeof(of32_t);\n\tif (index >= len)\n\t\treturn -ENOENT;\n\n\tvalue += (index * irq_cells);\n\tfor (i = 0; i < irq_cells; i++)\n\t\tirqv[i] = of32_to_cpu(*value++);\n\n\tif (vm && vm->virq_chip)\n\t\treturn vm->virq_chip->xlate(node, irqv, irq_cells, irq, flags);\n\telse\n\t\treturn irq_xlate(node, irqv, irq_cells, irq, flags);\n\n\treturn -EINVAL;\n}\n\nstatic int create_pdev_virq_of(struct vm *vm, struct device_node *node)\n{\n\tof32_t *val;\n\tof32_t *virq_affinity = NULL;\n\tuint32_t irqs[4], irq, hw_irq = 0;\n\tint i, j, nr_icells, hw = 0;\n\tint len, len_aff, ret;\n\tstruct virq_chip *vc = vm->virq_chip;\n\tunsigned long type;\n\n\tif (node->class == DT_CLASS_VIRQCHIP)\n\t\treturn 0;\n\n\tval = (of32_t *)of_getprop(node, \"interrupts\", &len);\n\tif (!val || (len < sizeof(of32_t)))\n\t\treturn 0;\n\n\t/* get the irq count for the device */\n\tnr_icells = of_n_interrupt_cells(node);\n\tif (nr_icells == 0)\n\t\treturn 0;\n\n\tlen = len / sizeof(of32_t);\n\tif (vm_is_native(vm))\n\t\thw = 1;\n\telse {\n\t\tvirq_affinity = (of32_t *)of_getprop(node, \"virq_affinity\", &len_aff);\n\t\tif (virq_affinity &&\n\t\t    (len_aff / sizeof(of32_t) == len / nr_icells))\n\t\t\thw = 1;\n\t}\n\n\tfor (i = 0; i < len; i += nr_icells) {\n\t\tfor (j = 0; j < nr_icells; j++)\n\t\t\tirqs[j] = of32_to_cpu(val[i + j]);\n\n\t\tret = vc->xlate(node, irqs, nr_icells, &irq, &type);\n\t\tif (ret)\n\t\t\tcontinue;\n\n\t\tif (hw) {\n\t\t\tif (vm_is_native(vm))\n\t\t\t\thw_irq = irq;\n\t\t\telse\n\t\t\t\thw_irq = of32_to_cpu(virq_affinity[i / nr_icells]);\n\t\t}\n\n\t\t/* register the hardware irq for vm */\n\t\tpr_info(\"[VM%d VIRQ] %d->%d %s\\n\", vm->vmid,\n\t\t\t\tirq, hw_irq, node->name);\n\t\trequest_hw_virq(vm, irq, hw_irq, 0);\n\t}\n\n\treturn 0;\n}\n\nstatic int create_pdev_iomem_of(struct vm *vm, struct device_node *node)\n{\n\tuint64_t addr, size;\n\tint i, nr_addr, ret;\n\n\t/* virqchip do not need request and map the virtual\n\t * address, the virqchip will handle it. */\n\tif (node->class == DT_CLASS_VIRQCHIP)\n\t\treturn 0;\n\n\t/* get the count of memory region for the device */\n\tnr_addr = of_n_addr_count(node);\n\n\tfor (i = 0; i < nr_addr; i++) {\n\t\tret = of_translate_address_index(node, &addr, &size, i);\n\t\tif (ret || (size == 0)) {\n\t\t\tpr_warn(\"bad address index %d for %s\\n\", i, node->name);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (vm_is_host_vm(vm) && !platform_iomem_valid(addr)) {\n\t\t\tpr_warn(\"address range [0x%lx 0x%lx] droped by platform\\n\",\n\t\t\t\t\taddr, size);\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* map the physical memory for vm */\n\t\tpr_info(\"[VM%d IOMEM] 0x%x->0x%x 0x%x %s\\n\", vm->vmid,\n\t\t\t\taddr, addr, size, node->name);\n\t\tsplit_vmm_area(&vm->mm, addr, size, VM_GUEST_IO | VM_RW);\n\t\tcreate_guest_mapping(&vm->mm, addr, addr,\n\t\t\t\tsize, VM_GUEST_IO | VM_RW);\n\t}\n\n\treturn 0;\n}\n\nstatic int create_vm_pdev_of(struct vm *vm, struct device_node *node)\n{\n\tint ret = 0;\n\n\tret += create_pdev_iomem_of(vm, node);\n\tret += create_pdev_virq_of(vm, node);\n\tret += iommu_assign_node(vm, node);\n\n\tif (ret)\n\t\tpr_err(\"create %s fail\\n\", node->name);\n\n\treturn ret;\n}\n\nstatic int create_vm_res_of(struct vm *vm, struct device_node *node)\n{\n\treturn 0;\n}\n\nstatic void *__create_vm_resource_of(struct device_node *node, void *arg)\n{\n\tstruct vm *vm = (struct vm *)arg;\n\n\tswitch(node->class) {\n\tcase DT_CLASS_IRQCHIP:\n\tcase DT_CLASS_VIRQCHIP:\n\tcase DT_CLASS_PCI_BUS:\n\tcase DT_CLASS_PDEV:\n\t\tcreate_vm_pdev_of(vm, node);\n\t\tbreak;\n\tcase DT_CLASS_TIMER:\n\tcase DT_CLASS_VDEV:\n\t\tcreate_vm_vdev_of(vm, node);\n\t\tbreak;\n\tcase DT_CLASS_VM:\n\t\tcreate_vm_res_of(vm, node);\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn NULL;\n}\n\nint create_vm_resource_of(struct vm *vm, void *data)\n{\n\tstruct device_node *node;\n\n\tif (!vm || (vm->flags & VM_FLAGS_NO_OF_RESOURCE))\n\t\treturn -EINVAL;\n\n\tnode = of_parse_device_tree(data);\n\tif (!node) {\n\t\tpr_err(\"invaild setup data for vm-%d\\n\", vm->vmid);\n\t\treturn -EINVAL;\n\t}\n\n\t/*\n\t * first of all need to create the virq controller\n\t * of this vm\n\t */\n\tof_iterate_all_node(node, create_vm_irqchip_of, vm);\n\tif (!vm->virq_chip) {\n\t\tif (vm_is_native(vm))\n\t\t\tpanic(\"can not create virq chip for vm\\n\");\n\t\telse\n\t\t\tpr_err(\"create virq chip failed for vm\\n\");\n\t\treturn -ENOENT;\n\t}\n\n\tof_iterate_all_node_loop(node, __create_vm_resource_of, vm);\n\n\t/* here we can free all the device node to save memory */\n\tof_release_all_node(node);\n\n\treturn 0;\n}\n\nstatic int create_vm_virqchip_common(struct vm *vm, struct device_node *node)\n{\n\tchar name[32];\n\tstruct device_node *virq_node;\n\n\tmemset(name, 0, 32);\n\tsprintf(name, \"virq_chip_vm%d\", vm->vmid);\n\tvirq_node = of_find_node_by_name(node, name);\n\tif (!virq_node)\n\t\treturn -ENOENT;\n\n\t/* set the class to DT_CLASS_IRQCHIP temp */\n\tvirq_node->class = DT_CLASS_IRQCHIP;\n\tcreate_vm_irqchip_of(virq_node, vm);\n\tif (!vm->virq_chip)\n\t\tpr_err(\"no virq chip for %s\\n\", vm_name(vm));\n\n\tvirq_node->class = DT_CLASS_OTHER;\n\n\treturn 0;\n}\n\nstatic int inline create_vm_vtimer_common(struct vm *vm,\n\t\tstruct device_node *node)\n{\n\tof_get_u32_array(node, \"vtimer_irq\", &vm->vtimer_virq, 1);\n\tif ((vm->vtimer_virq > 31) || (vm->vtimer_virq < 16))\n\t\tpr_warn(\"wrong vtimer virq for vm\\n\");\n\n\treturn 0;\n}\n\n#define IOMEM_SIZE_CELLS\t2\n#define IOMEM_ADDR_CELLS\t2\n#define IOMEM_ENTRY_CNT\t\t6\n#define IOMEM_ENTRY_SIZE\t24\n\nstatic int create_vm_iomem_common(struct vm *vm, struct device_node *node)\n{\n\tfdt32_t *data;\n\tint len, i;\n\tunsigned long vaddr, paddr, size;\n\n\t/* vaddr paddr size */\n\tdata = (fdt32_t *)of_getprop(node, \"iomem\", &len);\n\tif (!data || (len == 0) || (len % IOMEM_ENTRY_SIZE))\n\t\treturn -EINVAL;\n\n\tlen = len / IOMEM_ENTRY_SIZE;\n\n\tfor (i = 0; i < len; i++) {\n\t\tvaddr = fdt32_to_cpu64(data[0], data[1]);\n\t\tpaddr = fdt32_to_cpu64(data[2], data[3]);\n\t\tsize = fdt32_to_cpu64(data[4], data[5]);\n\n\t\tsplit_vmm_area(&vm->mm, vaddr, size, VM_GUEST_IO);\n\t\tcreate_guest_mapping(&vm->mm, vaddr,\n\t\t\t\tpaddr, size, VM_GUEST_IO | VM_RW);\n\n\t\tdata += IOMEM_ENTRY_CNT;\n\t}\n\n\treturn 0;\n}\n\nstatic int create_vm_virqs_common(struct vm *vm, struct device_node *node)\n{\n\tfdt32_t *data;\n\tint len, i;\n\tuint32_t phy, vir;\n\n\tdata = (fdt32_t *)of_getprop(node, \"virqs\", &len);\n\tif (!data || (len == 0) || (len % 8))\n\t\treturn -EINVAL;\n\n\tlen = len / (2 * sizeof(uint32_t));\n\n\tfor (i = 0; i < len; i++) {\n\t\tphy = fdt32_to_cpu(data[0]);\n\t\tvir = fdt32_to_cpu(data[1]);\n\t\trequest_hw_virq(vm, vir, phy, 0);\n\t\tdata += 2;\n\t}\n\n\treturn 0;\n}\n\nstatic void *create_vm_vdev_common(struct device_node *node, void *vm)\n{\n\tif (of_get_bool(node, \"virtual_device\"))\n\t\tcreate_vm_vdev_of(vm, node);\n\n\treturn NULL;\n}\n\nint create_native_vm_resource_common(struct vm *vm)\n{\n\tint ret = 0;\n\tchar name[32];\n\tstruct device_node *node;\n\n\tsprintf(name, \"vm%d_bdi\", vm->vmid);\n\n\tnode = of_find_node_by_name(vm->dev_node, name);\n\tif (!node)\n\t\treturn -ENOENT;\n\n\tif (!vm->virq_chip) {\n\t\tret = create_vm_virqchip_common(vm, node);\n\t\tif (ret)\n\t\t\tpr_warn(\"virqchip is not found in hv dts\\n\");\n\t}\n\n\tif (vm->vtimer_virq <= 0)\n\t\tret += create_vm_vtimer_common(vm, node);\n\n\tret += create_vm_iomem_common(vm, node);\n\tret += create_vm_virqs_common(vm, node);\n\n\tof_iterate_all_node_loop(node, create_vm_vdev_common, vm);\n\n\treturn ret;\n}\n\nstatic int __init_text resource_init(void)\n{\n\textern unsigned char __virqchip_start;\n\textern unsigned char __virqchip_end;\n\textern unsigned char __vdev_start;\n\textern unsigned char __vdev_end;\n\n\tvirqchip_start = (void *)&__virqchip_start;\n\tvirqchip_end = (void *)&__virqchip_end;\n\tvdev_start = (void *)&__vdev_start;\n\tvdev_end = (void *)&__vdev_end;\n\n\treturn 0;\n}\narch_initcall(resource_init);\n"
  },
  {
    "path": "kernel/virt/shmem.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <virt/vmm.h>\n#include <minos/mm.h>\n#include <minos/arch.h>\n\n/*\n * one shmem_block rrepresent one mem_block which is 2M\n * so it has 512 pages.\n */\nstruct shmem_block {\n\tstruct mem_block *mb;\n\tunsigned long phy_base;\n\tuint16_t id;\n\tuint16_t free_pages;\n\tuint16_t current_index;\n\tunsigned long bitmap[BITS_TO_LONGS(PAGES_IN_BLOCK)];\n};\n\nstruct shmem {\n\tint pages;\n\tint flags;\n\tint id;\n\tuint32_t pfn;\n\tstruct shmem *next;\n};\n\n#define MAX_SHMEM_ID 32\n\nstatic struct shmem *shmem_head;\nstatic uint16_t sbid;\nstatic DEFINE_SPIN_LOCK(shmem_lock);\n\nstatic struct shmem_block *shmem_blocks[MAX_SHMEM_ID];\n\nstatic struct shmem_block *alloc_shmem_block(void)\n{\n\tstruct shmem_block *sb;\n\n\tsb = zalloc(sizeof(struct shmem_block));\n\tif (!sb) {\n\t\tpr_err(\"no memory for shmem block\\n\");\n\t\treturn NULL;\n\t}\n\n\tsb->mb = vmm_alloc_memblock();\n\tif (sb->mb == NULL) {\n\t\tfree(sb);\n\t\treturn NULL;\n\t}\n\n\tsb->phy_base = BFN2PHY(sb->mb->bfn);\n\tsb->free_pages = PAGES_IN_BLOCK;\n\t\n\t/*\n\t * mapping this memory block to the host address space.\n\t */\n\tif (create_host_mapping(ptov(sb->phy_base), ULONG(sb->phy_base),\n\t\t\tMEM_BLOCK_SIZE, VM_NORMAL_NC | VM_RW | VM_HUGE)) {\n\t\tpr_err(\"mapping share memory failed\\n\");\n\t\tfree(sb);\n\t\tvmm_free_memblock(sb->mb);\n\t\treturn NULL;\n\t}\n\n\tsb->id = sbid++;\n\tshmem_blocks[sb->id] = sb;\n\n\treturn sb;\n}\n\nstatic void *__alloc_shmem(struct shmem_block *sb, int pages, int flags)\n{\n\tstruct shmem *shmem;\n\tunsigned long addr;\n\tint bits;\n\n\tbits = bitmap_find_next_zero_area_align(sb->bitmap,\n\t\t\tPAGES_IN_BLOCK, 0, pages, 1);\n\tif (bits >= PAGES_IN_BLOCK)\n\t\treturn NULL;\n\n\tshmem = malloc(sizeof(struct shmem));\n\tif (!shmem)\n\t\treturn NULL;\n\n\taddr = sb->phy_base + pfn2phy(bits);\n\tshmem->id = sb->id;\n\tshmem->pfn = phy2pfn(addr);\n\tshmem->flags = flags;\n\tshmem->pages = pages;\n\n\tshmem->next = shmem_head;\n\tshmem_head = shmem;\n\n\tbitmap_set(sb->bitmap, bits, pages);\n\n\treturn (void *)ptov(addr);\n}\n\nvoid *alloc_shmem(int pages)\n{\n\tstruct shmem_block *sb;\n\tvoid *addr = NULL;\n\tint i;\n\n\tif (pages > PAGES_IN_BLOCK) {\n\t\tpr_err(\"share memory should be below %d pages\\n\", PAGES_IN_BLOCK);\n\t\treturn NULL;\n\t}\n\n\tspin_lock(&shmem_lock);\n\tfor (i = 0; i < sbid; i++) {\n\t\tsb = shmem_blocks[i];\n\t\tif (sb->free_pages >= pages) {\n\t\t\taddr = __alloc_shmem(sb, pages, 0);\n\t\t\tif (addr)\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (addr == NULL) {\n\t\tif (sbid >= MAX_SHMEM_ID) {\n\t\t\tpr_err(\"can not alloc more shmem block\\n\");\n\t\t\tgoto out;\n\t\t}\n\n\t\tsb = alloc_shmem_block();\n\t\tif (!sb) {\n\t\t\tpr_err(\"no more memblock for shmem\\n\");\n\t\t\tgoto out;\n\t\t}\n\n\t\taddr = __alloc_shmem(sb, pages, 0);\n\t}\nout:\n\tspin_unlock(&shmem_lock);\n\n\treturn addr;\n}\n\nstatic void free_shmem_in_block(struct shmem *shmem)\n{\n\tstruct shmem_block *sb;\n\tuint32_t pfn;\n\n\tASSERT(shmem->id < MAX_SHMEM_ID);\n\tsb = shmem_blocks[shmem->id];\n\tpfn = phy2pfn(pfn2phy(shmem->pfn) - ULONG(sb->phy_base));\n\tbitmap_clear(sb->bitmap, pfn, shmem->pages);\n\tsb->free_pages += shmem->pages;\n\tfree(shmem);\n}\n\nvoid free_shmem(void *addr)\n{\n\tstruct shmem *shmem, *tmp = NULL;\n\n\tASSERT(IS_PAGE_ALIGN(ULONG(addr)));\n\n\tspin_lock(&shmem_lock);\n\tshmem = shmem_head;\n\twhile (shmem) {\n\t\tif (shmem->pfn == phy2pfn(vtop(addr))) {\n\t\t\tfree_shmem_in_block(shmem);\n\t\t\tif (tmp == NULL)\n\t\t\t\tshmem_head = shmem->next;\n\t\t\telse\n\t\t\t\ttmp->next = shmem->next;\n\t\t\tbreak;\n\t\t\t\n\t\t}\n\t\ttmp = shmem;\n\t\tshmem = shmem->next;\n\t}\n\n\tif (shmem == NULL)\n\t\tpr_err(\"not a shemm 0x%x\\n\", ULONG(addr));\n\n\tspin_unlock(&shmem_lock);\n}\n"
  },
  {
    "path": "kernel/virt/varm_timer.c",
    "content": "/*\n * Copyright (C) 2020 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/list.h>\n#include <minos/of.h>\n#include <virt/vm.h>\n#include <virt/vdev.h>\n#include <virt/virq_chip.h>\n#include <minos/mm.h>\n#include <virt/vmm.h>\n#include <minos/irq.h>\n#include <virt/vmbox.h>\n#include <minos/platform.h>\n#include <virt/resource.h>\n\nstatic void *varm_timer_init(struct vm *vm, struct device_node *node)\n{\n\tint ret;\n\tuint32_t irq;\n\tunsigned long flags;\n\n\t/*\n\t * for armv8 need to use the virtual timer as the system\n\t * ticks, here we get the virtual timer's irq number, the\n\t * virtual timer's irq num will with the index 2\n\t */\n\tret = vm_get_device_irq_index(vm, node, &irq, &flags, 2);\n\tif (ret || (irq > 32)) {\n\t\tpr_err(\"can not find virtual timer for VM\\n\");\n\t\treturn  NULL;\n\t}\n\n\tpr_info(\"virtual arch timer irq: %d\\n\", irq);\n\tvm->vtimer_virq = irq;\n\n\treturn NULL;\n}\nVDEV_DECLARE(varm_timer, arm_arch_timer_match_table, varm_timer_init);\n"
  },
  {
    "path": "kernel/virt/vdev.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/sched.h>\n#include <virt/vdev.h>\n#include <virt/virq.h>\n#include <virt/vmcs.h>\n#include <virt/vmm.h>\n#include <virt/vm.h>\n\nstatic void vdev_set_name(struct vdev *vdev, const char *name)\n{\n\tint len;\n\n\tif (!vdev || !name)\n\t\treturn;\n\n\tlen = strlen(name);\n\tif (len > VDEV_NAME_SIZE)\n\t\tlen = VDEV_NAME_SIZE;\n\n\tstrncpy(vdev->name, name, len);\n}\n\nvoid vdev_release(struct vdev *vdev)\n{\n\tstruct vmm_area *vma = vdev->gvm_area;\n\tstruct vmm_area *next;\n\n\tif (vdev->list.next != NULL)\n\t\tlist_del(&vdev->list);\n\n\t/*\n\t * release the vmm_areas if has. just delete it, the VMM\n\t * will release all the vmm_area of VM.\n\t */\n\twhile (vma) {\n\t\tnext = vma->next;\n\t\tvma->next = NULL;\n\t\tvma = next;\n\t}\n}\n\nstatic void vdev_deinit(struct vdev *vdev)\n{\n\tpr_warn(\"using default vdev deinit routine\\n\");\n\tvdev_release(vdev);\n\tfree(vdev);\n}\n\nvoid host_vdev_init(struct vm *vm, struct vdev *vdev, const char *name)\n{\n\tif (!vm || !vdev) {\n\t\tpr_err(\"%s: no such VM or VDEV\\n\");\n\t\treturn;\n\t}\n\n\tmemset(vdev, 0, sizeof(struct vdev));\n\tvdev->vm = vm;\n\tvdev->host = 1;\n\tvdev->list.next = NULL;\n\tvdev->deinit = vdev_deinit;\n\tvdev->list.next = NULL;\n\tvdev->list.pre = NULL;\n\tvdev_set_name(vdev, name);\n}\n\nstatic void inline vdev_add_vmm_area(struct vdev *vdev, struct vmm_area *va)\n{\n\tstruct vmm_area *head = vdev->gvm_area;\n\tstruct vmm_area *prev = NULL;\n\n\t/*\n\t * add to the list tail.\n\t */\n\twhile (head) {\n\t\tprev = head;\n\t\thead = head->next;\n\t}\n\n\tva->next = NULL;\n\tif (prev == NULL)\n\t\tvdev->gvm_area = va;\n\telse\n\t\tprev->next = va;\n}\n\nint vdev_add_iomem_range(struct vdev *vdev, unsigned long base, size_t size)\n{\n\tstruct vmm_area *va;\n\n\tif (!vdev || !vdev->vm)\n\t\treturn -ENOENT;\n\n\t/*\n\t * vdev memory usually will not mapped to the real\n\t * physical space, here set the flags to 0.\n\t */\n\tva = split_vmm_area(&vdev->vm->mm, base, size, VM_GUEST_VDEV);\n\tif (!va) {\n\t\tpr_err(\"vdev: request vmm area failed 0x%lx 0x%lx\\n\",\n\t\t\t\tbase, base + size);\n\t\treturn -ENOMEM;\n\t}\n\n\tvdev_add_vmm_area(vdev, va);\n\n\treturn 0;\n}\n\nvoid vdev_add(struct vdev *vdev)\n{\n\tif (!vdev->vm)\n\t\tpr_err(\"%s vdev has not been init\\n\");\n\telse\n\t\tlist_add_tail(&vdev->vm->vdev_list, &vdev->list);\n}\n\nstruct vmm_area *vdev_alloc_iomem_range(struct vdev *vdev, size_t size, int flags)\n{\n\tstruct vmm_area *va;\n\n\tva = alloc_free_vmm_area(&vdev->vm->mm, size, PAGE_MASK, flags);\n\tif (!va)\n\t\treturn NULL;\n\n\tvdev_add_vmm_area(vdev, va);\n\n\treturn va;\n}\n\nstruct vmm_area *vdev_get_vmm_area(struct vdev *vdev, int idx)\n{\n\tstruct vmm_area *va = vdev->gvm_area;\n\n\twhile (idx || !va) {\n\t\tva = va->next;\n\t\tidx--;\n\t}\n\n\treturn va;\n}\n\nstruct vdev *create_host_vdev(struct vm *vm, const char *name)\n{\n\tstruct vdev *vdev;\n\n\tvdev = malloc(sizeof(*vdev));\n\tif (!vdev)\n\t\treturn NULL;\n\n\thost_vdev_init(vm, vdev, name);\n\n\treturn vdev;\n}\n\nstatic inline int handle_mmio_write(struct vdev *vdev, gp_regs *regs,\n\t\tint idx, unsigned long offset, unsigned long *value)\n{\n\tif (vdev->write)\n\t\treturn vdev->write(vdev, regs, idx, offset, value);\n\telse\n\t\treturn 0;\n}\n\nstatic inline int handle_mmio_read(struct vdev *vdev, gp_regs *regs,\n\t\tint idx, unsigned long offset, unsigned long *value)\n{\n\tif (vdev->read)\n\t\treturn vdev->read(vdev, regs, idx, offset, value);\n\telse\n\t\treturn 0;\n}\n\nstatic inline int handle_mmio(struct vdev *vdev, gp_regs *regs, int write,\n\t\tint idx, unsigned long offset, unsigned long *value)\n{\n\tif (write)\n\t\treturn handle_mmio_write(vdev, regs, idx, offset, value);\n\telse\n\t\treturn handle_mmio_read(vdev, regs, idx, offset, value);\n}\n\nint vdev_mmio_emulation(gp_regs *regs, int write,\n\t\tunsigned long address, unsigned long *value)\n{\n\tstruct vm *vm = get_current_vm();\n\tstruct vdev *vdev;\n\tstruct vmm_area *va;\n\tint idx, ret = 0;\n\n\tlist_for_each_entry(vdev, &vm->vdev_list, list) {\n\t\tidx = 0;\n\t\tva = vdev->gvm_area;\n\t\twhile (va) {\n\t\t\tif ((address >= va->start) && (address <= va->end)) {\n\t\t\t\tret = handle_mmio(vdev, regs, write,\n\t\t\t\t\t\tidx, address - va->start, value);\n\t\t\t\tif (ret)\n\t\t\t\t\tpr_warn(\"vm%d %s mmio 0x%lx in %s failed\\n\", vm->vmid,\n\t\t\t\t\t\t\twrite ? \"write\" : \"read\", address, vdev->name);\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tidx++;\n\t\t\tva = va->next;\n\t\t}\n\t}\n\n\t/*\n\t * trap the mmio rw event to hvm if there is no vdev\n\t * in host can handle it\n\t */\n\tif (vm_is_native(vm))\n\t\treturn -EACCES;\n\n\tret = trap_vcpu(VMTRAP_TYPE_MMIO, write, address, value);\n\tif (ret) {\n\t\tpr_warn(\"gvm%d %s mmio 0x%lx failed %d\\n\", vm->vmid,\n\t\t\t\twrite ? \"write\" : \"read\", address, ret);\n\t\tret = (ret == -EACCES) ? -EACCES : 0;\n\t}\n\n\treturn ret;\n}\n"
  },
  {
    "path": "kernel/virt/vfault.c",
    "content": "/*\n * Copyright (C) 2022 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/sched.h>\n#include <minos/irq.h>\n#include <minos/mm.h>\n#include <virt/os.h>\n#include <virt/vm.h>\n#include <virt/vmodule.h>\n#include <virt/virq.h>\n#include <virt/vmm.h>\n#include <virt/vdev.h>\n#include <minos/task.h>\n#include <minos/pm.h>\n#include <virt/virt.h>\n#include <virt/vmcs.h>\n#include <virt/vm_pm.h>\n\nvoid vcpu_dump(struct vcpu *vcpu, gp_regs *regs)\n{\n\tpr_fatal(\"!!!! VCPU%d of VM%d [%s] fault !!!!\\n\");\n\tarch_dump_register(regs);\n\tdump_vcpu_vmodule_state(vcpu);\n}\n\nvoid vcpu_fault(struct vcpu *vcpu, gp_regs *regs)\n{\n\tstruct vm *vm = vcpu->vm;\n\n\tvcpu_dump(vcpu, regs);\n\n\t/*\n\t * shoutdown the VM.\n\t */\n\tvm_power_off(vm->vmid, NULL, VM_PM_ACTION_BY_HOST);\n}\n"
  },
  {
    "path": "kernel/virt/virq.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/irq.h>\n#include <minos/sched.h>\n#include <virt/virq.h>\n#include <virt/virq_chip.h>\n\nstatic DEFINE_SPIN_LOCK(hvm_irq_lock);\n\n#define HVM_IRQ_LOCK(vm) \t\t\t\t\\\n\tdo {\t\t\t\t\t\t\\\n\t\tif (vm_is_host_vm(vm))\t\t\t\\\n\t\t\tspin_lock(&hvm_irq_lock); \t\\\n\t} while (0)\n\n#define HVM_IRQ_UNLOCK(vm) \t\t\t\t\\\n\tdo {\t\t\t\t\t\t\\\n\t\tif (vm_is_host_vm(vm))\t\t\t\\\n\t\t\tspin_unlock(&hvm_irq_lock); \t\\\n\t} while (0)\n\n\nstruct virq_desc *get_virq_desc(struct vcpu *vcpu, uint32_t virq)\n{\n\tstruct vm *vm = vcpu->vm;\n\n\tif (virq < VM_LOCAL_VIRQ_NR)\n\t\treturn &vcpu->virq_struct->local_desc[virq];\n\n\tif (virq >= VM_VIRQ_NR(vm->vspi_nr))\n\t\treturn NULL;\n\n\treturn &vm->vspi_desc[VIRQ_SPI_OFFSET(virq)];\n}\n\nstatic void inline virq_kick_vcpu(struct vcpu *vcpu,\n\t\tstruct virq_desc *desc)\n{\n\tkick_vcpu(vcpu, virq_is_hw(desc) ?\n\t\t\tVCPU_KICK_REASON_HIRQ: VCPU_KICK_REASON_VIRQ);\n}\n\nstatic int inline __send_virq(struct vcpu *vcpu, struct virq_desc *desc)\n{\n\tstruct virq_struct *virq_struct = vcpu->virq_struct;\n\n\t/*\n\t * if the virq is already at the pending state, do\n\t * nothing, other case need to send it to the vcpu\n\t * if the virq is in offline state, send it to vcpu\n\t * directly.\n\t *\n\t * SGI need set the irq source.\n\t */\n\tif (test_and_set_bit(desc->vno, virq_struct->pending_bitmap))\n\t\treturn 0;\n\n\tatomic_inc(&virq_struct->pending_virq);\n\tif (desc->vno < VM_SGI_VIRQ_NR)\n\t\tdesc->src = get_vcpu_id(get_current_vcpu());\n\n\treturn 0;\n}\n\nstatic int send_virq(struct vcpu *vcpu, struct virq_desc *desc)\n{\n\tstruct vm *vm = vcpu->vm;\n\tint ret, state = vm->state;\n\n\tif (!vcpu || !desc)\n\t\treturn -EINVAL;\n\n\t/*\n\t * Only check the VM's state here, the vcpu's state will check\n\t * in kick_vcpu and return_to_user.\n\t */\n\tif ((state != VM_STATE_ONLINE) && (state != VM_STATE_SUSPEND)) {\n\t\tpr_warn(\"VM %s is offline or reboot drop virq %d\\n\",\n\t\t\t\tvm->name, desc->vno);\n\t\treturn -EPERM;\n\t}\n\n\t/*\n\t * check the state of the vm, if the vm is in suspend state\n\t * and the irq can not wake up the vm, just return. Otherwise\n\t * need to kick the vcpu, kick_vcpu can wakeup the system.\n\t */\n\tif ((vm->state == VM_STATE_SUSPEND) && !virq_can_wakeup(desc)) {\n\t\tpr_warn(\"VM %s is suspend drop virq %d\\n\", vm->name, desc->vno);\n\t\treturn -EAGAIN;\n\t}\n\n\tret = __send_virq(vcpu, desc);\n\tif (ret) {\n\t\tpr_warn(\"send virq to vcpu-%d-%d failed\\n\",\n\t\t\t\tget_vmid(vcpu), get_vcpu_id(vcpu));\n\t\treturn ret;\n\t}\n\n\tvirq_kick_vcpu(vcpu, desc);\n\n\treturn 0;\n}\n\nstatic int guest_irq_handler(uint32_t irq, void *data)\n{\n\tstruct vcpu *vcpu;\n\tstruct virq_desc *desc = (struct virq_desc *)data;\n\n\tif ((!desc) || (!virq_is_hw(desc))) {\n\t\tpr_notice(\"virq %d is not a hw irq\\n\", desc->vno);\n\t\treturn -EINVAL;\n\t}\n\n\t/* send the virq to the guest */\n\tif ((desc->vmid == VIRQ_AFFINITY_VM_ANY) &&\n\t\t\t(desc->vcpu_id == VIRQ_AFFINITY_VCPU_ANY))\n\t\tvcpu = get_current_vcpu();\n\telse\n\t\tvcpu = get_vcpu_by_id(desc->vmid, desc->vcpu_id);\n\n\treturn send_virq(vcpu, desc);\n}\n\nuint32_t virq_get_type(struct vcpu *vcpu, uint32_t virq)\n{\n\tstruct virq_desc *desc;\n\n\tdesc = get_virq_desc(vcpu, virq);\n\tif (!desc)\n\t\treturn 0;\n\n\treturn desc->type;\n}\n\nuint32_t virq_get_state(struct vcpu *vcpu, uint32_t virq)\n{\n\tstruct virq_desc *desc;\n\n\tdesc = get_virq_desc(vcpu, virq);\n\tif (!desc)\n\t\treturn 0;\n\n\treturn !!virq_is_enabled(desc);\n}\n\nuint32_t virq_get_affinity(struct vcpu *vcpu, uint32_t virq)\n{\n\tstruct virq_desc *desc;\n\n\tdesc = get_virq_desc(vcpu, virq);\n\tif (!desc)\n\t\treturn 0;\n\n\treturn desc->vcpu_id;\n}\n\nuint32_t virq_get_pr(struct vcpu *vcpu, uint32_t virq)\n{\n\tstruct virq_desc *desc;\n\n\tdesc = get_virq_desc(vcpu, virq);\n\tif (!desc)\n\t\treturn 0;\n\n\treturn desc->pr;\n}\n\nint virq_can_request(struct vcpu *vcpu, uint32_t virq)\n{\n\tstruct virq_desc *desc;\n\n\tdesc = get_virq_desc(vcpu, virq);\n\tif (!desc)\n\t\treturn 0;\n\n\treturn !virq_is_requested(desc);\n}\n\nint virq_need_export(struct vcpu *vcpu, uint32_t virq)\n{\n\tstruct virq_desc *desc;\n\n\tdesc = get_virq_desc(vcpu, virq);\n\tif (!desc)\n\t\treturn 0;\n\n\tif (desc->flags & VIRQS_NEED_EXPORT)\n\t\treturn 1;\n\n\treturn !virq_is_requested(desc);\n}\n\nint virq_set_type(struct vcpu *vcpu, uint32_t virq, int value)\n{\n\tstruct virq_desc *desc;\n\n\tdesc = get_virq_desc(vcpu, virq);\n\tif (!desc)\n\t\treturn -ENOENT;\n\n\t/*\n\t * 0 - IRQ_TYPE_LEVEL_HIGH\n\t * 1 - IRQ_TYPE_EDGE_RISING\n\t */\n\tif (desc->type != value) {\n\t\tdesc->type = value;\n\t\tif (virq_is_hw(desc)) {\n\t\t\tif (value)\n\t\t\t\tvalue = IRQ_FLAGS_EDGE_RISING;\n\t\t\telse\n\t\t\t\tvalue = IRQ_FLAGS_LEVEL_HIGH;\n\n\t\t\tirq_set_type(desc->hno, value);\n\t\t}\n\t}\n\n\treturn 0;\n}\n\nint virq_set_priority(struct vcpu *vcpu, uint32_t virq, int pr)\n{\n\tstruct virq_desc *desc;\n\n\tdesc = get_virq_desc(vcpu, virq);\n\tif (!desc) {\n\t\tpr_debug(\"virq is no exist %d\\n\", virq);\n\t\treturn -ENOENT;\n\t}\n\n\tpr_debug(\"set the pr:%d for virq:%d\\n\", pr, virq);\n\tdesc->pr = pr;\n\n\treturn 0;\n}\n\nint virq_enable(struct vcpu *vcpu, uint32_t virq)\n{\n\tstruct virq_desc *desc;\n\n\tdesc = get_virq_desc(vcpu, virq);\n\tif (!desc)\n\t\treturn -ENOENT;\n\n\tvirq_set_enable(desc);\n\tif ((virq > VM_LOCAL_VIRQ_NR) && virq_is_hw(desc))\n\t\tirq_unmask(desc->hno);\n\n\treturn 0;\n}\n\nint virq_set_fiq(struct vcpu *vcpu, uint32_t virq)\n{\n\tstruct virq_desc *desc;\n\n\tdesc = get_virq_desc(vcpu, virq);\n\tif (!desc)\n\t\treturn -ENOENT;\n\t__virq_set_fiq(desc);\n\n\treturn 0;\n}\n\nint virq_disable(struct vcpu *vcpu, uint32_t virq)\n{\n\tstruct virq_desc *desc;\n\n\tdesc = get_virq_desc(vcpu, virq);\n\tif (!desc)\n\t\treturn -ENOENT;\n\n\tvirq_clear_enable(desc);\n\tif ((virq > VM_LOCAL_VIRQ_NR) || virq_is_hw(desc))\n\t\tirq_mask(desc->hno);\n\n\treturn 0;\n}\n\nint send_virq_to_vcpu(struct vcpu *vcpu, uint32_t virq)\n{\n\treturn send_virq(vcpu, get_virq_desc(vcpu, virq));\n}\n\nint send_virq_to_vm(struct vm *vm, uint32_t virq)\n{\n\tstruct virq_desc *desc;\n\n\t/*\n\t * only can send SPI virq in this function\n\t * if sending virq to dedicate vcpu please\n\t * use send_virq_to_vcpu()\n\t */\n\tif ((!vm) || (virq < VM_LOCAL_VIRQ_NR))\n\t\treturn -EINVAL;\n\n\tdesc = get_virq_desc(vm->vcpus[0], virq);\n\tif (!desc)\n\t\treturn -ENOENT;\n\n\tif (!virq_is_enabled(desc)) {\n\t\tpr_err(\"virq%d for %s is not enabled, drop it\\n\",\n\t\t\t\tvirq, vm->name);\n\t\treturn -EAGAIN;\n\t}\n\n\tif (virq_is_hw(desc)) {\n\t\tpr_err(\"can not send hw irq in here %d\\n\", virq);\n\t\treturn -EPERM;\n\t}\n\n\treturn send_virq(get_vcpu_in_vm(vm, desc->vcpu_id), desc);\n}\n\nvoid send_vsgi(struct vcpu *sender, uint32_t sgi, cpumask_t *cpumask)\n{\n\tint cpu;\n\tstruct vcpu *vcpu;\n\tstruct vm *vm = sender->vm;\n\tstruct virq_desc *desc;\n\n\tfor_each_set_bit(cpu, cpumask->bits, vm->vcpu_nr) {\n\t\tvcpu = vm->vcpus[cpu];\n\t\tdesc = get_virq_desc(vcpu, sgi);\n\t\tsend_virq(vcpu, desc);\n\t}\n}\n\nvoid clear_pending_virq(struct vcpu *vcpu, uint32_t irq)\n{\n\tstruct virq_struct *virq_struct = vcpu->virq_struct;\n\tstruct virq_desc *desc;\n\n\tdesc = get_virq_desc(vcpu, irq);\n\tif ((!desc) || (desc->state != VIRQ_STATE_ACTIVE))\n\t\treturn;\n\n\t/*\n\t * this function can only called by the current\n\t * running vcpu and excuted on the related pcpu\n\t *\n\t * check wether the virq is pending agagin, if yes\n\t * do not delete it from the pending list, instead\n\t * of add it to the tail of the pending list\n\t *\n\t */\n\tclear_bit(irq, virq_struct->active_bitmap);\n\tdesc->state = VIRQ_STATE_INACTIVE;\n\tvirqchip_update_virq(vcpu, desc, VIRQ_ACTION_CLEAR);\n}\n\nuint32_t get_pending_virq(struct vcpu *vcpu)\n{\n\tstruct virq_struct *virq_struct = vcpu->virq_struct;\n\tint total_irq = vm_irq_count(vcpu->vm);\n\tstruct virq_desc *desc;\n\tint bit;\n\n\tfor_each_set_bit(bit, virq_struct->pending_bitmap, total_irq) {\n\t\tif (test_bit(bit, virq_struct->active_bitmap))\n\t\t\tcontinue;\n\n\t\tdesc = get_virq_desc(vcpu, bit);\n\t\tdesc->state = VIRQ_STATE_ACTIVE;\n\t\tatomic_dec(&virq_struct->pending_virq);\n\t\tclear_bit(bit, virq_struct->pending_bitmap);\n\n\t\tset_bit(bit, virq_struct->active_bitmap);\n\t\tvirq_struct->active_virq++;\n\n\t\treturn bit;\n\t}\n\n\treturn BAD_IRQ;\n}\n\nint vcpu_has_irq(struct vcpu *vcpu)\n{\n\tstruct virq_struct *vs = vcpu->virq_struct;\n\tint total = vm_irq_count(vcpu->vm);\n\tint pend, active;\n\n\tpend = find_first_bit(vs->pending_bitmap, total);\n\tactive = find_first_bit(vs->active_bitmap, total);\n\n\treturn (pend < total) || (active < total);\n}\n\nstatic void update_virq_cap(struct virq_desc *desc, unsigned long flags)\n{\n\tdesc->flags |= flags;\n\n\tif ((flags & VIRQF_ENABLE) && virq_is_hw(desc))\n\t\tirq_unmask(desc->hno);\n\n\tif (flags & VIRQF_FIQ)\n\t\t__virq_set_fiq(desc);\n}\n\nvoid vcpu_virq_struct_init(struct vcpu *vcpu)\n{\n\tstruct virq_struct *virq_struct = vcpu->virq_struct;\n\tstruct virq_desc *desc;\n\tint i;\n\n\tvirq_struct->active_virq = 0;\n\tatomic_set(0, &virq_struct->pending_virq);\n\n\tmemset(&virq_struct->local_desc, 0,\n\t\tsizeof(struct virq_desc) * VM_LOCAL_VIRQ_NR);\n\n\tfor (i = 0; i < VM_LOCAL_VIRQ_NR; i++) {\n\t\tdesc = &virq_struct->local_desc[i];\n\t\tvirq_clear_hw(desc);\n\t\tvirq_set_enable(desc);\n\n\t\t/* this is just for ppi or sgi */\n\t\tdesc->vcpu_id = VIRQ_AFFINITY_VCPU_ANY;\n\t\tdesc->vmid = VIRQ_AFFINITY_VM_ANY;\n\t\tdesc->vno = i;\n\t\tdesc->hno = 0;\n\t\tdesc->id = VIRQ_INVALID_ID;\n\t\tdesc->state = VIRQ_STATE_INACTIVE;\n\t}\n}\n\nvoid vcpu_virq_struct_reset(struct vcpu *vcpu)\n{\n\tstruct virq_struct *vs = vcpu->virq_struct;\n\n\tmemset(vs->pending_bitmap, 0, BITMAP_SIZE(vcpu->vm->vspi_nr));\n\tmemset(vs->active_bitmap, 0, BITMAP_SIZE(vcpu->vm->vspi_nr));\n\tmemset(vs->lrs_bitmap, 0, BITMAP_SIZE(vs->nr_lrs));\n\tvcpu_virq_struct_init(vcpu);\n}\n\nstatic int __request_virq(struct vcpu *vcpu, struct virq_desc *desc,\n\t\t\tuint32_t virq, uint32_t hwirq, unsigned long flags)\n{\n\tif (test_and_set_bit(VIRQS_REQUESTED_BIT,\n\t\t\t\t(unsigned long *)&desc->flags)) {\n\t\tpr_warn(\"virq-%d may has been requested\\n\", virq);\n\t\treturn -EBUSY;\n\t}\n\n\tdesc->vno = virq;\n\tdesc->hno = hwirq;\n\tdesc->vcpu_id = get_vcpu_id(vcpu);\n\tdesc->pr = 0xa0;\n\tdesc->vmid = get_vmid(vcpu);\n\tdesc->id = VIRQ_INVALID_ID;\n\tdesc->state = VIRQ_STATE_INACTIVE;\n\n\t/* mask the bits in spi_irq_bitmap, if it is a SPI */\n\tif (virq >= VM_LOCAL_VIRQ_NR)\n\t\tset_bit(VIRQ_SPI_OFFSET(virq), vcpu->vm->vspi_map);\n\n\t/* if the virq affinity to a hwirq need to request\n\t * the hw irq */\n\tif (hwirq) {\n\t\tirq_set_affinity(hwirq, vcpu_affinity(vcpu));\n\t\tvirq_set_hw(desc);\n\t\trequest_irq(hwirq, guest_irq_handler, IRQ_FLAGS_VCPU,\n\t\t\t\tvcpu->task->name, (void *)desc);\n\t\tirq_mask(desc->hno);\n\t} else {\n\t\tvirq_clear_hw(desc);\n\t}\n\n\tupdate_virq_cap(desc, flags);\n\n\treturn 0;\n}\n\nint request_virq_affinity(struct vm *vm, uint32_t virq, uint32_t hwirq,\n\t\t\tint affinity, unsigned long flags)\n{\n\tstruct vcpu *vcpu;\n\tstruct virq_desc *desc;\n\n\tvcpu = get_vcpu_in_vm(vm, affinity);\n\tif (!vcpu) {\n\t\tpr_err(\"request virq fail no vcpu-%d in vm-%d\\n\",\n\t\t\t\taffinity, vm->vmid);\n\t\treturn -EINVAL;\n\t}\n\n\tdesc = get_virq_desc(vcpu, virq);\n\tif (!desc) {\n\t\tpr_err(\"virq-%d not exist vm-%d\", virq, vm->vmid);\n\t\treturn -ENOENT;\n\t}\n\n\treturn __request_virq(vcpu, desc, virq, hwirq, flags);\n}\n\nstatic inline int vm_max_virq_line(struct vm *vm)\n{\n\treturn (vm_is_host_vm(vm) ? MAX_HVM_VIRQ : MAX_GVM_VIRQ);\n}\n\nint request_hw_virq(struct vm *vm, uint32_t virq, uint32_t hwirq,\n\t\t\tunsigned long flags)\n{\n\tif (virq >= vm_max_virq_line(vm)) {\n\t\tpr_err(\"invaild virq-%d for vm-%d\\n\", virq, vm->vmid);\n\t\treturn -EINVAL;\n\t} else {\n\t\treturn request_virq_affinity(vm, virq, hwirq, 0, flags);\n\t}\n}\n\nint request_virq(struct vm *vm, uint32_t virq, unsigned long flags)\n{\n\treturn request_hw_virq(vm, virq, 0, flags);\n}\n\nint request_virq_pervcpu(struct vm *vm, uint32_t virq, unsigned long flags)\n{\n\tint ret;\n\tstruct vcpu *vcpu;\n\tstruct virq_desc *desc;\n\n\tif (virq >= VM_LOCAL_VIRQ_NR)\n\t\treturn -EINVAL;\n\n\tvm_for_each_vcpu(vm, vcpu) {\n\t\tdesc = get_virq_desc(vcpu, virq);\n\t\tif (!desc)\n\t\t\tcontinue;\n\n\t\tret = __request_virq(vcpu, desc, virq, 0, flags);\n\t\tif (ret) {\n\t\t\tpr_err(\"request percpu virq-%d failed vm-%d\\n\",\n\t\t\t\t\tvirq, vm->vmid);\n\t\t}\n\n\t\t/*\n\t\t * Fix me here may need to update the affinity for\n\t\t * thie virq if it is a ppi or sgi, if the ppi is\n\t\t * bind to the hw ppi, need to do this, otherwise\n\t\t * do not need to change it\n\t\t */\n\t\tdesc->vcpu_id = VIRQ_AFFINITY_VCPU_ANY;\n\t\tdesc->vmid = VIRQ_AFFINITY_VM_ANY;\n\t}\n\n\treturn 0;\n}\n\nint alloc_vm_virq(struct vm *vm)\n{\n\tint virq;\n\tint count = vm->vspi_nr;\n\n\tHVM_IRQ_LOCK(vm);\n\tvirq = find_next_zero_bit_loop(vm->vspi_map, count, 0);\n\tif (virq < count)\n\t\trequest_virq(vm, virq + VM_LOCAL_VIRQ_NR, VIRQF_NEED_EXPORT);\n\telse\n\t\tvirq = -1;\n\tHVM_IRQ_UNLOCK(vm);\n\n\treturn (virq >= 0 ? virq + VM_LOCAL_VIRQ_NR : -1);\n}\n\nvoid release_vm_virq(struct vm *vm, int virq)\n{\n\tstruct virq_desc *desc;\n\n\tvirq = VIRQ_SPI_OFFSET(virq);\n\tif (virq >= vm->vspi_nr)\n\t\treturn;\n\n\tHVM_IRQ_LOCK(vm);\n\tdesc = &vm->vspi_desc[virq];\n\tmemset(desc, 0, sizeof(struct virq_desc));\n\tclear_bit(virq, vm->vspi_map);\n\tHVM_IRQ_UNLOCK(vm);\n}\n\nstatic int virq_create_vm(void *item, void *args)\n{\n\tuint32_t size, vdesc_size, vdesc_bitmap_size, status_bitmap_size;\n\tstruct vm *vm = (struct vm *)item;\n\tstruct virq_struct *vs;\n\tvoid *base;\n\tint i;\n\n\t/*\n\t * Total size:\n\t * 1 - sizeof(struct virq_desc) * vspi_nr\n\t * 3 - vitmap_size(spi_nr)\n\t * 2 - vcpu_nr * bitmap_size * (SGI + PPI + SPI) * 2\n\t */\n\tvm->vspi_nr = vm_max_virq_line(vm);\n\tvdesc_size = sizeof(struct virq_desc) * vm->vspi_nr;\n\tvdesc_size = BALIGN(vdesc_size, sizeof(unsigned long));\n\tvdesc_bitmap_size = BITMAP_SIZE(vm->vspi_nr);\n\tstatus_bitmap_size = BITMAP_SIZE(vm->vspi_nr + VM_LOCAL_VIRQ_NR);\n\n\tsize = vdesc_size + vdesc_bitmap_size +\n\t\t(status_bitmap_size * vm->vcpu_nr * 2);\n\tsize = PAGE_BALIGN(size);\n\n\tpr_notice(\"allocate 0x%x bytes for virq struct\\n\", size);\n\tbase = get_free_pages(PAGE_NR(size));\n\tif (!base) {\n\t\tpr_err(\"no more page for virq struct\\n\");\n\t\treturn -ENOMEM;\n\t}\n\n\tmemset(base, 0, size);\n\tvm->vspi_desc = (struct virq_desc *)base;\n\tvm->vspi_map = (unsigned long *)(base + vdesc_size);\n\n\tbase = base + vdesc_size + vdesc_bitmap_size;\n\tfor (i = 0; i < vm->vcpu_nr; i++) {\n\t\tvs = vm->vcpus[i]->virq_struct;\n\t\tASSERT(vs != NULL);\n\t\tvs->pending_bitmap = base;\n\t\tbase += status_bitmap_size;\n\t\tvs->active_bitmap = base;\n\t\tbase += status_bitmap_size;\n\t}\n\n\treturn 0;\n}\n\nvoid vm_virq_reset(struct vm *vm)\n{\n\tstruct virq_desc *desc;\n\tint i;\n\n\t/* reset the all the spi virq for the vm */\n\tfor ( i = 0; i < vm->vspi_nr; i++) {\n\t\tdesc = &vm->vspi_desc[i];\n\t\tvirq_clear_enable(desc);\n\t\tdesc->pr = 0xa0;\n\t\tdesc->type = 0x0;\n\t\tdesc->id = VIRQ_INVALID_ID;\n\t\tdesc->state = VIRQ_STATE_INACTIVE;\n\n\t\tif (virq_is_hw(desc))\n\t\t\tirq_mask(desc->hno);\n\t}\n}\n\nstatic int virq_destroy_vm(void *item, void *data)\n{\n\tint i;\n\tstruct virq_desc *desc;\n\tstruct vm *vm = (struct vm *)item;\n\n\tif (vm->vspi_desc) {\n\t\tfor (i = 0; i < VIRQ_SPI_NR(vm->vspi_nr); i++) {\n\t\t\tdesc = &vm->vspi_desc[i];\n\n\t\t\t/* should check whether the hirq is pending or not */\n\t\t\tif (virq_is_enabled(desc) && virq_is_hw(desc) &&\n\t\t\t\t\tdesc->hno > VM_LOCAL_VIRQ_NR)\n\t\t\t\tirq_mask(desc->hno);\n\t\t}\n\n\t\tfree_pages(vm->vspi_desc);\n\t}\n\n\treturn 0;\n}\n\nstatic int virqs_init(void)\n{\n\tregister_hook(virq_create_vm, OS_HOOK_CREATE_VM);\n\tregister_hook(virq_destroy_vm, OS_HOOK_DESTROY_VM);\n\n\treturn 0;\n}\nsubsys_initcall(virqs_init);\n"
  },
  {
    "path": "kernel/virt/virq_chips/Kconfig",
    "content": "menu \"Virqchip controller support\"\n\nconfig VIRQCHIP_VGICV2\n\tbool \"virqchip vgicv2 support\"\n\tdefault y\n\thelp\n\t  vgicv2 virtual interrupt controller drvier\n\nconfig VIRQCHIP_VGICV3\n\tbool \"virqchip vgicv3 support\"\n\tdefault y\n\thelp\n\t  vgicv3 virtual interrupt controller drvier\n\nconfig VIRQCHIP_BCM2836\n\tbool \"virqchip bcm2835 driver\"\n\tdefault n\n\thelp\n\t  boardcom bcm2835 virtual interrupt controller\n\t  driver\n\nconfig VIRQCHIP_AIC\n\tbool \"Support Apple Interrupt Controller\"\n\tdefault n\n\thelp\n\t  support virtual AIC\n\nendmenu\n"
  },
  {
    "path": "kernel/virt/virq_chips/Makefile",
    "content": "obj-y += virq_chip.o\nobj-$(CONFIG_VIRQCHIP_BCM2836)\t+= bcm_virq.o\nobj-$(CONFIG_VIRQCHIP_VGICV2)\t+= vgicv2.o vgic.o\nobj-$(CONFIG_VIRQCHIP_VGICV3)\t+= vgicv3.o vgic.o\nobj-$(CONFIG_VIRQCHIP_AIC)\t+= vaic.o\n"
  },
  {
    "path": "kernel/virt/virq_chips/bcm_virq.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n#include <minos/minos.h>\n#include <asm/arch.h>\n#include <minos/irq.h>\n#include <asm/io.h>\n#include <virt/vmodule.h>\n#include <minos/cpumask.h>\n#include <minos/irq.h>\n#include <minos/sched.h>\n#include <virt/virq.h>\n#include <virt/vdev.h>\n#include <minos/of.h>\n#include <virt/virq_chip.h>\n#include <device/bcm_irq.h>\n#include <virt/vmm.h>\n\nstruct bcm2836_virq {\n\tstruct vdev vdev;\n\tvoid *iomem;\n\tvoid *bcm2835_pending[NR_BANKS];\n\tvoid *bcm2835_enable[NR_BANKS];\n\tvoid *bcm2835_disable[NR_BANKS];\n\tint bcm2835_pendings;;\n};\n\n#define vdev_to_bcm_virq(vdev) \\\n\t(struct bcm2836_virq *)container_of(vdev, struct bcm2836_virq, vdev)\n\nextern int vgicv2_create_vm(void *item, void *arg);\nstatic int bcm2836_clear_spi(struct vcpu *vcpu, uint32_t virq);\nstatic int bcm2836_clear_ppi(struct vcpu *vcpu, uint32_t virq);\n\nextern int bcm2836_xlate_irq(struct device_node *node,\n\t\tuint32_t *intspec, unsigned int intsize,\n\t\tuint32_t *hwirq, unsigned long *type);\n\nstatic void bcm2836_virq_deinit(struct vdev *vdev)\n{\n\tstruct bcm2836_virq *bcm2836 = vdev_to_bcm_virq(vdev);\n\n\tfree_shmem(bcm2836->iomem);\n\tvdev_release(vdev);\n\tfree(bcm2836);\n}\n\nstatic void bcm2836_virq_reset(struct vdev *vdev)\n{\n\tstruct bcm2836_virq *bcm2836 = vdev_to_bcm_virq(vdev);\n\n\tmemset(bcm2836->iomem, 0, PAGE_SIZE);\n}\n\nstatic int bcm2836_virq_read(struct vdev *vdev, gp_regs *regs,\n\t\tint idx, unsigned long offset, unsigned long *read_value)\n{\n\t/* guest can directly read the memory space */\n\n\treturn 0;\n}\n\nstatic void inline bcm2835_virq_enable(struct vcpu *vcpu,\n\t\tint base, unsigned long *value)\n{\n\tuint32_t bit;\n\n\tfor_each_set_bit(bit, value, 32)\n\t\tvirq_enable(vcpu, base + bit);\n}\n\nstatic void inline bcm2835_virq_disable(struct vcpu *vcpu,\n\t\tint base, unsigned long *value)\n{\n\tuint32_t bit;\n\n\tfor_each_set_bit(bit, value, 32)\n\t\tvirq_disable(vcpu, base + bit);\n}\n\nstatic int bcm2835_virq_write(struct vdev *vdev, gp_regs *reg,\n\t\tunsigned long offset, unsigned long *value)\n{\n\tuint32_t irq;\n\tstruct vcpu *vcpu = get_current_vcpu();\n\n\tswitch (offset) {\n\tcase BCM2835_IRQ_ACK:\n\t\tirq = *value + 32;\n\t\tbcm2836_clear_spi(vcpu, irq);\n\t\tclear_pending_virq(vcpu, irq);\n\t\tbreak;\n\tcase BCM2835_IRQ_ENABLE1:\n\t\tbcm2835_virq_enable(vcpu, 64, value);\n\t\tbreak;\n\tcase BCM2835_IRQ_ENABLE2:\n\t\tbcm2835_virq_enable(vcpu, 96, value);\n\t\tbreak;\n\tcase BCM2835_IRQ_BASIC_ENABLE:\n\t\tbcm2835_virq_enable(vcpu, 32, value);\n\t\tbreak;\n\tcase BCM2835_IRQ_DISABLE1:\n\t\tbcm2835_virq_disable(vcpu, 64, value);\n\t\tbreak;\n\tcase BCM2835_IRQ_DISABLE2:\n\t\tbcm2835_virq_disable(vcpu, 96, value);\n\t\tbreak;\n\tcase BCM2835_IRQ_DISABLE_BASIC:\n\t\tbcm2835_virq_disable(vcpu, 32, value);\n\t\tbreak;\n\tdefault:\n\t\tpr_warn(\"unsupport bcm2835 action now 0x%x\\n\", offset);\n\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\nstatic int inline bcm2836_send_vsgi(struct vcpu *vcpu, struct vdev *vdev,\n\t\tunsigned long offset, unsigned long *value)\n{\n\tint sgi;\n\tstruct vcpu *target;\n\tstruct vm *vm = vcpu->vm;\n\tint cpu = (offset - LOCAL_MAILBOX0_SET0) / 16;\n\n\tif (*value == 0)\n\t\treturn -EINVAL;\n\n\tsgi = __ffs((uint32_t)*value);\n\tpr_debug(\"send vsgi %d %d\\n\", cpu, sgi);\n\n\tif ((cpu > vm->vcpu_nr) || (sgi >= 16))\n\t\treturn -EINVAL;\n\n\ttarget = get_vcpu_in_vm(vm, cpu);\n\tif (!target)\n\t\treturn -EINVAL;\n\n\treturn send_virq_to_vcpu(target, sgi);\n}\n\nstatic int inline bcm2836_clear_vsgi(struct vcpu *vcpu, struct vdev *vdev,\n\t\tunsigned long offset, unsigned long *value)\n{\n\tuint32_t v;\n\tint sgi;\n\tint cpu = (offset - LOCAL_MAILBOX0_CLR0) / 16;\n\tvoid *base;\n\tstruct vcpu *target;\n\tstruct vm *vm = vcpu->vm;\n\tstruct bcm2836_virq *dev = vdev_to_bcm_virq(vdev);\n\n\tif (*value == 0)\n\t\treturn -EINVAL;\n\n\tsgi = __ffs((uint32_t)*value);\n\tpr_debug(\"clear vsgi %d %d\\n\", cpu, sgi);\n\n\tif ((cpu > vm->vcpu_nr) || (sgi >= 16))\n\t\treturn -EINVAL;\n\n\ttarget = get_vcpu_in_vm(vm, cpu);\n\tif (!target)\n\t\treturn -EINVAL;\n\n\tv = readl_relaxed(dev->iomem + offset);\n\tv &= ~((uint32_t)*value);\n\twritel_relaxed(v, dev->iomem + offset);\n\n\t/* clear the LOCAL_MAILBOX0 pending bit */\n\tif (v == 0) {\n\t\tbase = dev->iomem + LOCAL_IRQ_PENDING0 + 4 * cpu;\n\t\tv = readl_relaxed(base) & ~BIT(LOCAL_IRQ_MAILBOX0);\n\t\twritel_relaxed(v, base);\n\t}\n\n\tclear_pending_virq(vcpu, sgi);\n\treturn 0;\n}\n\nstatic int bcm2836_timer_int_action(struct vcpu *vcpu, struct vdev *vdev,\n\t\tunsigned long offset, unsigned long *value)\n{\n\tint i;\n\tuint32_t v = (uint32_t)*value;\n\tstruct vcpu *target;\n\tint cpu = (offset - LOCAL_TIMER_INT_CONTROL0) / 4;\n\tstruct bcm2836_virq *dev = vdev_to_bcm_virq(vdev);\n\n\ttarget = get_vcpu_in_vm(vcpu->vm, cpu);\n\tif (!target)\n\t\treturn -EINVAL;\n\n\t/* update the value for vm read */\n\twritel_relaxed(v, dev->iomem + offset);\n\n\t/* timer treated as ppi in the system */\n\tfor (i = 0; i < 4; i++) {\n\t\tif (v & (1 << i))\n\t\t\tvirq_enable(vcpu, i + 16);\n\t\telse\n\t\t\tvirq_disable(vcpu, i + 16);\n\t}\n\n\treturn 0;\n}\n\nstatic int bcm2836_virq_write(struct vdev *vdev, gp_regs *reg,\n\t\tint idx, unsigned long offset, unsigned long *write_value)\n{\n\tstruct vcpu *vcpu = get_current_vcpu();\n\tint cpu, irq;\n\n\tif (offset >= BCM2835_INC_OFFSET)\n\t\treturn bcm2835_virq_write(vdev, reg, offset, write_value);\n\n\tswitch (offset) {\n\tcase LOCAL_CONTROL:\n\tcase LOCAL_PRESCALER:\n\t\tbreak;\n\tcase BCM2836_IRQ_ACK:\n\t\tirq = *write_value;\n\t\tbcm2836_clear_ppi(vcpu, irq);\n\t\tclear_pending_virq(vcpu, irq + 16);\n\t\tbreak;\n\tcase LOCAL_MAILBOX_INT_CONTROL0...LOCAL_MAILBOX_INT_CONTROL3:\n\t\t/* mailbox interrupt aloways enabled */\n\t\tbreak;\n\n\tcase LOCAL_TIMER_INT_CONTROL0...LOCAL_TIMER_INT_CONTROL3:\n\t\tbcm2836_timer_int_action(vcpu, vdev, offset, write_value);\n\t\tbreak;\n\n\tcase LOCAL_MAILBOX_SET_START...LOCAL_MAILBOX_SET_END:\n\t\t/* send the ipi now only using mailbox0 */\n\t\tbcm2836_send_vsgi(vcpu, vdev, offset, write_value);\n\t\tbreak;\n\n\tcase LOCAL_MAILBOX_CLR_START...LOCAL_MAILBOX_CLR_END:\n\t\tbcm2836_clear_vsgi(vcpu, vdev, offset, write_value);\n\t\tbreak;\n\n\t/* used to spin table to boot up vm0's vcpu */\n\tcase BCM2836_RELEASE_OFFSET...BCM2836_RELEASE_OFFSET_END:\n\t\tcpu = (offset - BCM2836_RELEASE_OFFSET) / sizeof(uint64_t);\n\t\tif (cpu == 0) {\n\t\t\tpr_err(\"vcpu0 has alreadly power on\\n\");\n\t\t\tbreak;\n\t\t}\n\t\tvcpu_power_on(vcpu, cpuid_to_affinity(cpu), *write_value, 0);\n\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\nstatic int bcm2836_inject_sgi(struct vcpu *vcpu, uint32_t virq)\n{\n\tvoid *base;\n\tuint32_t v;\n\tstruct vm *vm = vcpu->vm;\n\tstruct bcm2836_virq *dev;\n\n\tdev = (struct bcm2836_virq *)vm->virq_chip->inc_pdata;\n\tbase = dev->iomem + (LOCAL_MAILBOX0_CLR0 + vcpu->vcpu_id * 16);\n\n\t/* set the read and clear register */\n\tv = readl_relaxed(base);\n\twritel_relaxed(v | (1 << virq), base);\n\n\t/* set the LOCAL_IRQ_MAILBOX0 bit of LOCAL_IRQ_PENDING0 */\n\tbase = dev->iomem + LOCAL_IRQ_PENDING0 + 4 * vcpu->vcpu_id;\n\tv = readl_relaxed(base) | BIT(LOCAL_IRQ_MAILBOX0);\n\twritel_relaxed(v, base);\n\n\treturn 0;\n}\n\nstatic int bcm2836_inject_ppi(struct vcpu *vcpu, uint32_t virq)\n{\n\tvoid *base;\n\tuint32_t v;\n\tstruct vm *vm = vcpu->vm;\n\tstruct bcm2836_virq *dev;\n\n\tvirq = virq - 16;\n\tif (virq == LOCAL_IRQ_GPU_FAST) {\n\t\tpr_warn(\"%d irq is for bcm2835 inc\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\tdev = (struct bcm2836_virq *)vm->virq_chip->inc_pdata;\n\tbase = dev->iomem + LOCAL_IRQ_PENDING0 + 4 * vcpu->vcpu_id;\n\tv = readl_relaxed(base) | BIT(virq);\n\twritel_relaxed(v, base);\n\n\treturn 0;\n}\n\nstatic int bcm2836_get_spi_bank(struct bcm2836_virq*dev,\n\t\tuint32_t virq, void **iomem, int *pos, int *__bank)\n{\n\tint bank, bit;\n\tvoid *base;\n\n\t*__bank = bank = HWIRQ_BANK(virq);\n\tvirq = virq % 32;\n\tif (bank >= NR_BANKS)\n\t\treturn -EINVAL;\n\n\tif (bank == 0) {\n\t\tif (virq >= 10 && virq <= 20) {\n\t\t\tpr_warn(\"10 - 20 virq in bank0 is for other\\n\");\n\t\t\treturn -EINVAL;\n\t\t}\n\n\t\tbase = dev->bcm2835_pending[0];\n\t\tbit = virq;\n\t} else if (bank == 1) {\n\t\tswitch (virq) {\n\t\tcase 19:\n\t\t\tbase = dev->bcm2835_pending[0];\n\t\t\tbit = 14;\n\t\t\tbreak;\n\t\tcase 18:\n\t\t\tbase = dev->bcm2835_pending[0];\n\t\t\tbit = 13;\n\t\t\tbreak;\n\t\tcase 10:\n\t\t\tbase = dev->bcm2835_pending[0];\n\t\t\tbit = 12;\n\t\t\tbreak;\n\t\tcase 9:\n\t\t\tbase = dev->bcm2835_pending[0];\n\t\t\tbit = 11;\n\t\t\tbreak;\n\t\tcase 7:\n\t\t\tbase = dev->bcm2835_pending[0];\n\t\t\tbit = 10;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbase = dev->bcm2835_pending[1];\n\t\t\tbit = virq;\n\t\t\tbreak;\n\t\t}\n\t} else {\n\t\tswitch (virq) {\n\t\tcase 30:\n\t\t\tbase = dev->bcm2835_pending[0];\n\t\t\tbit = 20;\n\t\t\tbreak;\n\t\tcase 25:\n\t\t\tbase = dev->bcm2835_pending[0];\n\t\t\tbit = 19;\n\t\t\tbreak;\n\t\tcase 24:\n\t\t\tbase = dev->bcm2835_pending[0];\n\t\t\tbit = 18;\n\t\t\tbreak;\n\t\tcase 23:\n\t\t\tbase = dev->bcm2835_pending[0];\n\t\t\tbit = 17;\n\t\t\tbreak;\n\t\tcase 22:\n\t\t\tbase = dev->bcm2835_pending[0];\n\t\t\tbit = 16;\n\t\t\tbreak;\n\t\tcase 21:\n\t\t\tbase = dev->bcm2835_pending[0];\n\t\t\tbit = 15;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbase = dev->bcm2835_pending[2];\n\t\t\tbit = virq;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t*iomem = base;\n\t*pos = bit;\n\n\treturn 0;\n}\n\nstatic int bcm2836_clear_spi(struct vcpu *vcpu, uint32_t virq)\n{\n\tint bit, bank;\n\tuint32_t v, p0, p1, p2;\n\tvoid *base;\n\tstruct vm *vm = vcpu->vm;\n\tstruct bcm2836_virq *dev;\n\n\tdev = (struct bcm2836_virq *)vm->virq_chip->inc_pdata;\n\tif (bcm2836_get_spi_bank(dev, virq, &base, &bit, &bank)) {\n\t\tpr_err(\"get irq bank failed %d\\n\", virq);\n\t\treturn -EINVAL;\n\t}\n\n\tv = readl_relaxed(base) & ~BIT(bit);\n\twritel_relaxed(v, base);\n\n\tp0 = readl_relaxed(dev->bcm2835_pending[0]);\n\tp1 = readl_relaxed(dev->bcm2835_pending[1]);\n\tp2 = readl_relaxed(dev->bcm2835_pending[2]);\n\n\tif (p1 == 0)\n\t\tp0 &= ~BIT(8);\n\tif (p2 == 0)\n\t\tp0 &= ~BIT(9);\n\n\twritel_relaxed(p0, dev->bcm2835_pending[0]);\n\tmb();\n\n\treturn 0;\n}\n\nstatic int bcm2836_clear_ppi(struct vcpu *vcpu, uint32_t virq)\n{\n\tuint32_t v;\n\tvoid *base;\n\tstruct vm *vm = vcpu->vm;\n\tstruct bcm2836_virq *dev;\n\n\tif (virq > LOCAL_IRQ_PMU_FAST)\n\t\treturn -EINVAL;\n\n\tdev = (struct bcm2836_virq *)vm->virq_chip->inc_pdata;\n\tbase = dev->iomem + LOCAL_IRQ_PENDING0 + (vcpu->vcpu_id * 4);\n\tv = readl_relaxed(base) & ~BIT(virq);\n\twritel_relaxed(v, base);\n\tmb();\n\n\treturn 0;\n}\n\nstatic int bcm2836_inject_spi(struct vcpu *vcpu, uint32_t virq)\n{\n\tint bit, bank;\n\tuint32_t v;\n\tvoid *base;\n\tstruct vm *vm = vcpu->vm;\n\tstruct bcm2836_virq *dev;\n\n\tdev = (struct bcm2836_virq *)vm->virq_chip->inc_pdata;\n\tif (bcm2836_get_spi_bank(dev, virq, &base, &bit, &bank)) {\n\t\tpr_notice(\"get virq bank failed %d\\n\", virq);\n\t\treturn -EINVAL;\n\t}\n\n\tif (bank > 0) {\n\t\t/* update the bank register bit */\n\t\tv = readl_relaxed(dev->iomem + BCM2835_IRQ_BASIC_PENDING);\n\t\tv |= BIT(bank + 7);\n\t\twritel_relaxed(v, dev->iomem + BCM2835_IRQ_BASIC_PENDING);\n\t}\n\n\tv = readl_relaxed(base) | BIT(bit);\n\twritel_relaxed(v, base);\n\tmb();\n\n\t/* set the bcm2836 pending register BIT8 */\n\tbase = dev->iomem + LOCAL_IRQ_PENDING0;\n\tv = readl_relaxed(base) | BIT(8);\n\twritel_relaxed(v, base);\n\tmb();\n\n\treturn 0;\n}\n\nint bcm2836_send_virq(struct vcpu *vcpu, uint32_t virq)\n{\n\t/* convert the hypervisor virq to bcm irq number */\n\tswitch (virq) {\n\tcase 0 ... 15:\n\t\tbcm2836_inject_sgi(vcpu, virq);\n\t\tbreak;\n\tcase 16 ... 31:\n\t\tbcm2836_inject_ppi(vcpu, virq);\n\t\tbreak;\n\tcase 32 ... 127:\n\t\tbcm2836_inject_spi(vcpu, virq);\n\t\tbreak;\n\tdefault:\n\t\tpr_err(\"unsupport bcm2836 virq number\\n\");\n\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\nstatic int bcm2838_generate_virq(uint32_t *addr, int virq)\n{\n\tif (virq < VM_LOCAL_VIRQ_NR)\n\t\treturn 0;\n\n\tvirq -= VM_LOCAL_VIRQ_NR;\n\taddr[0] = cpu_to_of32(virq / 32);\n\taddr[1] = cpu_to_of32(virq % 32);\n\n\treturn 2;\n}\n\nstatic int bcm2836_update_virq(struct vcpu *vcpu,\n\t\tstruct virq_desc *desc, int action)\n{\n\tswitch (action) {\n\tcase VIRQ_ACTION_CLEAR:\n\t\t/* enable the hardware irq when disable in hyp */\n\t\tif ((desc->vno >= 32) && (virq_is_hw(desc)))\n\t\t\tirq_unmask(desc->hno);\n\t\tbreak;\n\t}\n\treturn 0;\n}\n\nstatic int bcm2836_enter_to_guest(struct vcpu *vcpu, void *data)\n{\n\tstruct virq_struct *vs = vcpu->virq_struct;\n\tstruct virq_desc *virq;\n\tstruct vm *vm = vcpu->vm;\n\tint bit;\n\n\tfor_each_set_bit(bit, vs->pending_bitmap, vm_irq_count(vm)) {\n\t\tvirq = get_virq_desc(vcpu, bit);\n\t\tif (virq == NULL) {\n\t\t\tpr_err(\"bad virq %d for vm %s\\n\", bit, vm->name);\n\t\t\tclear_bit(bit, vs->pending_bitmap);\n\t\t\tcontinue;\n\t\t}\n\n\t\tbcm2836_send_virq(vcpu, virq->vno);\n\t\tvirq->state = VIRQ_STATE_ACTIVE;\n\t}\n\n\treturn 0;\n}\n\nstatic struct virq_chip *bcm2836_virqchip_init(struct vm *vm,\n\t\tstruct device_node *node)\n{\n\tstruct bcm2836_virq *bcm2836;\n\tstruct vdev *vdev;\n\tvoid *base;\n\tstruct virq_chip *vc;\n\n\tpr_notice(\"%s enter\\n\", __func__);\n\n\tbcm2836 = zalloc(sizeof(struct bcm2836_virq));\n\tif (!bcm2836)\n\t\treturn NULL;\n\n\tbcm2836->iomem = alloc_shmem(1);\n\tif (!bcm2836->iomem) {\n\t\tfree(bcm2836);\n\t\treturn NULL;\n\t}\n\n\tbase = bcm2836->iomem + 0x200;\n\tbcm2836->bcm2835_pending[0] = base + 0x0;\n\tbcm2836->bcm2835_pending[1] = base + 0x04;\n\tbcm2836->bcm2835_pending[2] = base + 0x08;\n\tbcm2836->bcm2835_enable[0] = base + 0x18;\n\tbcm2836->bcm2835_enable[1] = base + 0x10;\n\tbcm2836->bcm2835_enable[2] = base + 0x14;\n\tbcm2836->bcm2835_disable[0] = base + 0x24;\n\tbcm2836->bcm2835_disable[1] = base + 0x1c;\n\tbcm2836->bcm2835_disable[2] = base + 0x20;\n\n\tmemset(bcm2836->iomem, 0, PAGE_SIZE);\n\tvdev = &bcm2836->vdev;\n\thost_vdev_init(vm, vdev, \"bcm2836-intc\");\n\tvdev_add_iomem_range(vdev, BCM2836_INC_BASE, PAGE_SIZE);\n\tvdev->read = bcm2836_virq_read;\n\tvdev->write = bcm2836_virq_write;\n\tvdev->reset = bcm2836_virq_reset;\n\tvdev->deinit = bcm2836_virq_deinit;\n\tvdev_add(vdev);\n\n\t/*\n\t * map the io space to guest as read only Notice :\n\t * bcm2836 base address is 7e00b200 which is not\n\t * PAGE ALIG\n\t *\n\t * here map the bcm2835 and bcm2836 interrupt controller\n\t * space all to 0x40000000\n\t * 0x40000000 - 0x40000100 : bcm2836 local interrupt\n\t * 0x40000200 - 0x40000300 : bcm2835 inc controller\n\t *\n\t */\n\tsplit_vmm_area(&vm->mm, 0x400000000, 0x1000, VM_GUEST_IO);\n\tcreate_guest_mapping(&vm->mm, BCM2836_INC_BASE, (unsigned long)bcm2836->iomem,\n\t\t\tPAGE_SIZE, VM_GUEST_IO | VM_RO);\n\n\tvc = alloc_virq_chip();\n\tif (!vc)\n\t\treturn NULL;\n\n\tvc->xlate = bcm2836_xlate_irq;\n\tvc->exit_from_guest = NULL;\n\tvc->enter_to_guest = bcm2836_enter_to_guest;\n\tvc->generate_virq = bcm2838_generate_virq;\n\tvc->update_virq = bcm2836_update_virq;\n\tvc->inc_pdata = (void *)bcm2836;\n\n\tpr_notice(\"%s exit\\n\", __func__);\n\n\treturn vc;\n}\nVIRQCHIP_DECLARE(bcm2836_virqchip, bcmirq_match_table,\n\t\tbcm2836_virqchip_init);\n"
  },
  {
    "path": "kernel/virt/virq_chips/vaic.c",
    "content": "/*\n * Copyright (C) 2019 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n *\n * virtual interrupt driver for AIC (Apple Iterrupt Controller)76\n */\n\n#include <minos/minos.h>\n#include <asm/arch.h>\n#include <minos/irq.h>\n#include <asm/io.h>\n#include <minos/cpumask.h>\n#include <minos/irq.h>\n#include <minos/sched.h>\n#include <virt/virq.h>\n#include <virt/vdev.h>\n#include <virt/resource.h>\n#include <virt/virq_chip.h>\n#include <virt/vmodule.h>\n#include <minos/of.h>\n\n#define AIC_REV\t\t\t\t0x0000\n#define AIC_CAP0\t\t\t0x0004\n#define AIC_CAP1\t\t\t0x0008\n#define AIC_RST\t\t\t\t0x000c\n#define AIC_CFG\t\t\t\t0x0010\n#define AIC_MAIN_TIME_LO\t\t0x0020\n#define AIC_MAIN_TIME_HI\t\t0X0028\n#define AIC_IPI_NORMAL_DBG\t\t0x0030\n#define AIC_IPI_SELF_DBG\t\t0x0034\n\n#define AIC_WHO_AM_I\t\t\t0x2000\n#define AIC_ACK\t\t\t\t0x2004\n#define AIC_IPI_SET\t\t\t0x2008\n#define AIC_IPI_CLR\t\t\t0x200c\n#define AIC_TMR_CFG\t\t\t0x2010\n#define AIC_TMR_CNT\t\t\t0x2014\n#define AIC_TMR_INT_STAT\t\t0x2018\n#define AIC_TMR_INT_STAT_SET\t\t0x201c\n#define AIC_TMR_INT_STAT_CLR\t\t0x2020\n#define AIC_BANKED_CORE_REGS\t\t0x2000\n\n#define AIC_CAP0_INT(n)\t\t\t((n) & 0x3ff)\n#define AIC_CAP0_PROC(n)\t\t((((n) >> 16) & 0x1f) + 1)\n#define AIC_ACK_VEC_TYPE(n)\t\t(((n) >> 16) & 7)\n\n#define AIC_ACK_VEC_TYPE_SPURIOUS\t(0)\n#define AIC_ACK_VEC_TYPE_EXT\t\t(1)\n#define AIC_ACK_VEC_TYPE_IPI\t\t(4)\n#define AIC_ACK_VEC_TYPE_TIMER\t\t(7)\n#define AIC_ACK_VEC_EXT_INT(n)\t\t((n) & 0x3ff)\n#define AIC_ACK_VEC_IPI_TYPE(n)\t\t((n) & 0x003)\n#define AIC_ACK_VEC_IPI_TYPE_NORMAL\t(1)\n#define AIC_ACK_VEC_IPI_TYPE_SELF\t(2)\n\n#define AIC_IPI_CLR_SELF\t\t(0x80000000)\n\n#define AIC_TMR_CFG_EN\t\t\t1\n#define AIC_TMR_CFG_FSL_PTI\t\t(0 << 4)\n#define AIC_TMR_CFG_FSL_SGTI\t\t(1 << 4)\n#define AIC_TMR_CFG_FSL_ETI\t\t(2 << 4)\n#define AIC_TMR_INT_STAT_PCT\t\t(1)\n#define AIC_BANED_CORE_TMR_CNT\t\t0x14\n#define AIC_BANKED_CORE_TMR_INT_STAT\t0x18\n\n#define AIC_TGT_DST(n)\t\t\t(0x3000 + (n) * 4)\n#define AIC_SWGEN_SET(n)\t\t(0x4000 + (n) * 4)\n#define AIC_SWGEN_CLR(n)\t\t(0x4080 + (n) * 4)\n#define AIC_INT_MASK_SET(n)\t\t(0x4100 + (n) * 4)\n#define AIC_INTMASK_CLR(n)\t\t(0x4180 + (n) * 4)\n#define AIC_HW_INT_MON(n)\t\t(0x4200 + (n) * 4)\n\n#define AIC_ALIAS_WHO_AM_I(n)\t\t(0x5000 + (n) * 0x80 + 0x00)\n#define AIC_ALIAS_INT_ACK(n)\t\t(0x5000 + (n) * 0x80 + 0x04)\n#define AIC_ALIAS_IPI_SET(n)\t\t(0x5000 + (n) * 0x80 + 0x08)\n#define AIC_ALIAS_IPI_CLR(n)\t\t(0x5000 + (n) * 0x80 + 0x0C)\n#define AIC_ALIAS_TMR_CFG(n)\t\t(0x5000 + (n) * 0x80 + 0x10)\n#define AIC_ALIAS_TMR_CNT(n)\t\t(0x5000 + (n) * 0x80 + 0x14)\n#define AIC_ALIAS_TMR_INT_STAT(n)\t(0x5000 + (n) * 0x80 + 0x18)\n#define AIC_ALIAS_TMR_STATE_SET(n)\t(0x5000 + (n) * 0x80 + 0x1C)\n#define AIC_ALIAS_TMR_STATE_CLR(n)\t(0x5000 + (n) * 0x80 + 0x20)\n\n#define AIC_EXT_INT_SHIFT\t\t(5)\n#define AIC_EXT_INT_MASK\t\t(0x1F)\n\n#define AIC_IO_BASE\t(0x0)\n#define AIC_IO_SIZE\t(0x6000)\n\nstruct aic_vdev {\n\tstruct vdev vdev;\n};\n\nint aic_xlate_irq(struct device_node *node,\n\t\tuint32_t *intspec, unsigned int intsize,\n\t\tuint32_t *hwirq, unsigned long *type)\n{\n\treturn 0;\n}\n\nstatic int aic_generate_virq(uint32_t *addr, int virq)\n{\n\treturn 0;\n}\n\nstatic int aic_update_virq(struct vcpu *vcpu,\n\t\tstruct virq_desc *desc, int action)\n{\n\treturn 0;\n}\n\nstatic int aic_enter_to_guest(struct vcpu *vcpu, void *data)\n{\n\tint fiq = 0;\n#if 0\n\tstruct virq_desc *virq, *n;\n\tstruct virq_struct *virq_struct = vcpu->virq_struct;\n\n\tlist_for_each_entry_safe(virq, n, &virq_struct->pending_list, list) {\n\t\tif (!virq_is_pending(virq)) {\n\t\t\tpr_err(\"virq is not request %d\\n\", virq->vno);\n\t\t\tlist_del(&virq->list);\n\t\t\tvirq->list.next = NULL;\n\t\t\tcontinue;\n\t\t}\n\n\t\tvirq_clear_pending(virq);\n\t\tvirq->state = VIRQ_STATE_ACTIVE;\n\t\tlist_del(&virq->list);\n\t\tlist_add_tail(&virq_struct->active_list, &virq->list);\n\n\t\tif (virq_is_fiq(virq))\n\t\t\tfiq = 1;\n\t\tbreak;\n\t}\n#endif\n\n\treturn fiq;\n}\n\nstatic void aic_virq_deinit(struct vdev *vdev)\n{\n\tvdev_release(vdev);\n}\n\nstatic void aic_virq_reset(struct vdev *vdev)\n{\n\n}\n\nstatic int aic_virq_read(struct vdev *vdev, gp_regs *reg,\n\t\tint idx, unsigned long address, unsigned long *read_value)\n{\n\tpr_notice(\"%s\\n\", __func__);\n\treturn 0;\n}\n\nstatic int aic_virq_write(struct vdev *vdev, gp_regs *reg,\n\t\tint idx, unsigned long address, unsigned long *value)\n{\n\tpr_notice(\"%s\\n\", __func__);\n\treturn 0;\n}\n\nstruct virq_chip *create_aic_virqchip(struct vm *vm,\n\t\tunsigned long base, unsigned long size)\n{\n\tstruct aic_vdev *aic;\n\tstruct virq_chip *vc;\n\n\taic = zalloc(sizeof(struct aic_vdev));\n\tif (!aic)\n\t\treturn NULL;\n\n\thost_vdev_init(vm, &aic->vdev, \"apple-aic\");\n\taic->vdev.read = aic_virq_read;\n\taic->vdev.write = aic_virq_write;\n\taic->vdev.reset = aic_virq_reset;\n\taic->vdev.deinit = aic_virq_deinit;\n\tvdev_add(&aic->vdev);\n\n\tvc = alloc_virq_chip();\n\tif (!vc) {\n\t\treturn NULL;\n\t}\n\n\tvc->xlate = aic_xlate_irq;\n\tvc->exit_from_guest = NULL;\n\tvc->enter_to_guest = aic_enter_to_guest;\n\tvc->generate_virq = aic_generate_virq;\n\tvc->update_virq = aic_update_virq;\n\tvc->inc_pdata = aic;\n\n\treturn vc;\n}\n\nstatic struct virq_chip *aic_virqchip_init(struct vm *vm,\n\t\tstruct device_node *node)\n{\n\treturn create_aic_virqchip(vm, AIC_IO_BASE, AIC_IO_SIZE);\n}\nVIRQCHIP_DECLARE(vaic_virqchip, aic_match_table, aic_virqchip_init);\n"
  },
  {
    "path": "kernel/virt/virq_chips/vgic.c",
    "content": "/*\n * Copyright (C) 2018 - 2019 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <virt/virq.h>\n#include <virt/virq_chip.h>\n#include <minos/of.h>\n#include <libfdt/libfdt.h>\n\n/*\n * The following cases are considered software programming\n * errors and result in UNPREDICTABLE behavior:\n *\n * • Having a List register entry with ICH_LR<n>_EL2.HW= 1\n *   which is associated with a physical interrupt, inactive\n *   state or in pending state in the List registers if the\n *   Distributor does not have the corresponding physical\n *   interrupt in either the active state or the active and\n *   pending state.\n * • If ICC_CTLR_EL1.EOImode == 0 or ICC_CTLR_EL3.EOImode_EL3 == 0\n *   then either:\n *   — Having an active interrupt in the List registers with a priorit\n *   that is not set in the corresponding Active Priorities Register.\n *   — Having two interrupts in the List registers in the active stat\n *   with the same preemption priority.>\n * • Having two or more interrupts with the same pINTID in the Lis\n *   registers for a single virtual CPU interface.\n */\nint vgic_irq_enter_to_guest(struct vcpu *vcpu, void *data)\n{\n\tstruct virq_struct *vs = vcpu->virq_struct;\n\tstruct vm *vm = vcpu->vm;\n\tstruct virq_desc *virq;\n\tint id = 0, bit, flags = 0, size, old;\n\n\tbit = vs->last_fail_virq;\n\tsize = vm_irq_count(vm) - bit;\n\told = vs->last_fail_virq;\n\tvs->last_fail_virq = 0;\n\nrepeat:\n\tfor_each_set_bit_from(bit, vs->pending_bitmap, size) {\n\t\tvirq = get_virq_desc(vcpu, bit);\n\t\tif (virq == NULL) {\n\t\t\tpr_err(\"bad virq %d for vm %s\\n\", bit, vm->name);\n\t\t\tclear_bit(bit, vs->pending_bitmap);\n\t\t\tcontinue;\n\t\t}\n\n\t\t/*\n\t\t * do not send this virq if there is same virq in\n\t\t * active state, need wait the previous virq done.\n\t\t */\n\t\tif (test_bit(bit, vs->active_bitmap))\n\t\t\tcontinue;\n\n\t\t/* allocate a id for the virq */\n\t\tid = find_first_zero_bit(vs->lrs_bitmap, vs->nr_lrs);\n\t\tif (id >= vs->nr_lrs) {\n\t\t\tpr_err(\"VM%d no space to send new irq %d\\n\",\n\t\t\t\t\tvm->vmid, virq->vno);\n\t\t\tvs->last_fail_virq = bit;\n\t\t\tbreak;\n\t\t}\n\n\t\t/*\n\t\t * indicate that FIQ has been inject.\n\t\t */\n\t\tif (virq->flags & VIRQS_FIQ)\n\t\t\tflags |= FIQ_HAS_INJECT;\n\t\tflags++;\n\t\tvirq->id = id;\n\t\tset_bit(id, vs->lrs_bitmap);\n\t\tvirqchip_send_virq(vcpu, virq);\n\t\tvirq->state = VIRQ_STATE_PENDING;\n\n\t\t/*\n\t\t * mark this virq as pending state and add it\n\t\t * to the active bitmap.\n\t\t */\n\t\tset_bit(bit, vs->active_bitmap);\n\t\tvs->active_virq++;\n\n\t\t/*\n\t\t * remove this virq from pending bitmap.\n\t\t */\n\t\tatomic_dec(&vs->pending_virq);\n\t\tclear_bit(bit, vs->pending_bitmap);\n\t}\n\n\tif ((old != 0) && (vs->last_fail_virq == 0)) {\n\t\tbit = 0;\n\t\tsize = old;\n\t\told = 0;\n\t\tgoto repeat;\n\t}\n\n\treturn flags;\n}\n\nint vgic_irq_exit_from_guest(struct vcpu *vcpu, void *data)\n{\n\tstruct virq_struct *vs = vcpu->virq_struct;\n\tstruct virq_desc *virq;\n\tint bit;\n\n\tfor_each_set_bit(bit, vs->active_bitmap, vm_irq_count(vcpu->vm)) {\n\t\tvirq = get_virq_desc(vcpu, bit);\n\t\tif (virq == NULL) {\n\t\t\tpr_err(\"bad active virq %d\\n\", virq);\n\t\t\tclear_bit(bit, vs->active_bitmap);\n\t\t\tcontinue;\n\t\t}\n\n\t\t/*\n\t\t * the virq has been handled by the VCPU, if\n\t\t * the virq is not pending again, delete it\n\t\t * otherwise add the virq to the pending list\n\t\t * again\n\t\t */\n\t\tvirq->state = virqchip_get_virq_state(vcpu, virq);\n\t\tif (virq->state == VIRQ_STATE_INACTIVE) {\n\t\t\tvirqchip_update_virq(vcpu, virq, VIRQ_ACTION_CLEAR);\n\t\t\tclear_bit(virq->id, vs->lrs_bitmap);\n\t\t\tvirq->id = VIRQ_INVALID_ID;\n\t\t\tvs->active_virq--;\n\t\t\tclear_bit(bit, vs->active_bitmap);\n\t\t}\n\t}\n\n\treturn 0;\n}\n\nint vgic_generate_virq(uint32_t *array, int virq)\n{\n\tarray[0] = cpu_to_fdt32(0x0);\n\tarray[1] = cpu_to_fdt32(virq - 32);\n\tarray[2] = cpu_to_fdt32(0x4);\n\n\treturn 3;\n}\n\nstatic int virq_chip_vcpu_init(void *item, void *contex)\n{\n\tstruct vcpu *vcpu = (struct vcpu *)item;\n\tstruct virq_chip *vc = vcpu->vm->virq_chip;\n\n\tif (vc && vc->vcpu_init)\n\t\treturn vc->vcpu_init(vcpu, vc->inc_pdata, vc->flags);\n\n\treturn 0;\n}\n\nstatic int __init_text vcpu_vgic_hook_init(void)\n{\n\treturn register_hook(virq_chip_vcpu_init, OS_HOOK_VCPU_INIT);\n}\nmodule_initcall(vcpu_vgic_hook_init);\n"
  },
  {
    "path": "kernel/virt/virq_chips/vgic.h",
    "content": "#ifndef __MINOS_VGIC_H__\n#define __MINSO_VGIC_H__\n\n#include <minos/types.h>\n\nstruct vcpu;\n\nint vgic_irq_enter_to_guest(struct vcpu *vcpu, void *data);\nint vgic_irq_exit_from_guest(struct vcpu *vcpu, void *data);\nint vgic_generate_virq(uint32_t *array, int virq);\n\n#endif\n"
  },
  {
    "path": "kernel/virt/virq_chips/vgicv2.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n#include <minos/minos.h>\n#include <asm/arch.h>\n#include <device/gicv2.h>\n#include <asm/io.h>\n#include <minos/cpumask.h>\n#include <minos/irq.h>\n#include <minos/sched.h>\n#include <virt/virq.h>\n#include <virt/vdev.h>\n#include <virt/resource.h>\n#include <virt/virq_chip.h>\n#include \"vgic.h\"\n#include <virt/vmodule.h>\n#include <minos/of.h>\n\n#define VGICV2_MODE_HWA 0x0 // hardware accelerate mode\n#define VGICV2_MODE_SWE 0x1 // software emulate mode\n\nstatic int vgicv2_mode;\n\nstruct vgicv2_dev {\n\tstruct vdev vdev;\n\tuint32_t gicd_ctlr;\n\tuint32_t gicd_typer;\n\tuint32_t gicd_iidr;\n\tunsigned long gicd_base;\n\tunsigned long gicc_base;\n\tunsigned long gicc_size;\n\tuint8_t gic_cpu_id[8];\n};\n\nstruct vgicv2_info {\n\tunsigned long gicd_base;\n\tunsigned long gicd_size;\n\tunsigned long gicc_base;\n\tunsigned long gicc_size;\n\tunsigned long gich_base;\n\tunsigned long gich_size;\n\tunsigned long gicv_base;\n\tunsigned long gicv_size;\n};\n\nstruct vgicc {\n\tstruct vdev vdev;\n\tunsigned long gicc_base;\n\tuint32_t gicc_ctlr;\n\tuint32_t gicc_pmr;\n\tuint32_t gicc_bpr;\n};\n\nstatic int gicv2_nr_lrs;\nstatic struct vgicv2_info vgicv2_info;\n\n#define vdev_to_vgicv2(vdev) \\\n\t(struct vgicv2_dev *)container_of(vdev, struct vgicv2_dev, vdev)\n\n#define vdev_to_vgicc(vdev) \\\n\t(struct vgicc *)container_of(vdev, struct vgicc, vdev);\n\nextern int gic_xlate_irq(struct device_node *node,\n\t\tuint32_t *intspec, unsigned int initsize,\n\t\tuint32_t *hwirq, unsigned long *type);\n\nstatic uint32_t vgicv2_get_virq_type(struct vcpu *vcpu, uint32_t offset)\n{\n\tint i;\n\tint irq;\n\tuint32_t value = 0, tmp;\n\n\toffset = (offset - GICD_ICFGR) / 4;\n\tirq = 16 * offset;\n\n\tfor (i = 0; i < 16; i++, irq++) {\n\t\ttmp = virq_get_type(vcpu, irq);\n\t\tvalue = value | (tmp << i * 2);\n\t}\n\n\treturn value;\n}\n\nstatic void vgicv2_set_virq_type(struct vcpu *vcpu,\n\t\tuint32_t offset, uint32_t value)\n{\n\tint i;\n\tint irq;\n\n\toffset = (offset - GICD_ICFGR) / 4;\n\tirq = 16 * offset;\n\n\tfor (i = 0; i < 16; i++, irq++) {\n\t\tvirq_set_type(vcpu, irq, value & 0x3);\n\t\tvalue = value >> 2;\n\t}\n}\n\nstatic uint32_t vgicv2_get_virq_affinity(struct vcpu *vcpu,\n\t\tunsigned long offset)\n{\n\tint i;\n\tint irq;\n\tuint32_t value = 0, t;\n\n\toffset = (offset - GICD_ITARGETSR) / 4;\n\tirq = 4 * offset;\n\n\tfor (i = 0; i < 4; i++, irq++) {\n\t\tt = virq_get_affinity(vcpu, irq);\n\t\tvalue |= (1 << t) << (8 * i);\n\t}\n\n\treturn value;\n}\n\nstatic uint32_t vgicv2_get_virq_pr(struct vcpu *vcpu,\n\t\tunsigned long offset)\n{\n\tint i;\n\tuint32_t irq;\n\tuint32_t value = 0, t;\n\n\toffset = (offset - GICD_IPRIORITYR) / 4;\n\tirq = offset * 4;\n\n\tfor (i = 0; i < 4; i++, irq++) {\n\t\tt = virq_get_pr(vcpu, irq);\n\t\tvalue |= t << (8 * i);\n\t}\n\n\treturn value;\n}\n\nstatic uint32_t inline vgicv2_get_virq_state(struct vcpu *vcpu,\n\t\tunsigned long offset, unsigned long reg)\n{\n\tint i;\n\tuint32_t irq;\n\tuint32_t value = 0, t;\n\n\toffset = (offset - reg) / 4;\n\tirq = offset * 32;\n\n\tfor (i = 0; i < 32; i++, irq++) {\n\t\tt = virq_get_state(vcpu, irq);\n\t\tvalue |= t << i;\n\t}\n\n\treturn value;\n}\n\nstatic uint32_t vgicv2_get_virq_mask(struct vcpu *vcpu,\n\t\tunsigned long offset)\n{\n\treturn vgicv2_get_virq_state(vcpu, offset, GICD_ICENABLER);\n}\n\nstatic uint32_t vgicv2_get_virq_unmask(struct vcpu *vcpu,\n\t\tunsigned long offset)\n{\n\treturn vgicv2_get_virq_state(vcpu, offset, GICD_ISENABLER);\n}\n\nstatic int vgicv2_read(struct vcpu *vcpu, struct vgicv2_dev *gic,\n\t\tunsigned long offset, unsigned long *v)\n{\n\tuint32_t tmp;\n\tuint32_t *value = (uint32_t *)v;\n\n\t/* to be done */\n\tswitch (offset) {\n\tcase GICD_CTLR:\n\t\t*value = !!gic->gicd_ctlr;\n\t\tbreak;\n\tcase GICD_TYPER:\n\t\t*value = gic->gicd_typer;\n\t\tbreak;\n\tcase GICD_IGROUPR...GICD_IGROUPRN:\n\t\t/* all group 1 */\n\t\t*value = 0xffffffff;\n\t\tbreak;\n\tcase GICD_ISENABLER...GICD_ISENABLERN:\n\t\t*value = vgicv2_get_virq_unmask(vcpu, offset);\n\t\tbreak;\n\tcase GICD_ICENABLER...GICD_ICENABLERN:\n\t\t*value = vgicv2_get_virq_mask(vcpu, offset);\n\t\tbreak;\n\tcase GICD_ISPENDR...GICD_ISPENDRN:\n\t\t*value = 0;\n\t\tbreak;\n\tcase GICD_ICPENDR...GICD_ICPENDRN:\n\t\t*value = 0;\n\t\tbreak;\n\tcase GICD_ISACTIVER...GICD_ISACTIVERN:\n\t\t*value = 0;\n\t\tbreak;\n\tcase GICD_ICACTIVER...GICD_ICACTIVERN:\n\t\t*value = 0;\n\t\tbreak;\n\tcase GICD_IPRIORITYR...GICD_IPRIORITYRN:\n\t\t*value = vgicv2_get_virq_pr(vcpu, offset);\n\t\tbreak;\n\tcase GICD_ITARGETSR...GICD_ITARGETSR7:\n\t\ttmp = 1 << get_vcpu_id(vcpu);\n\t\t*value = tmp;\n\t\t*value |= tmp << 8;\n\t\t*value |= tmp << 16;\n\t\t*value |= tmp << 24;\n\t\tbreak;\n\tcase GICD_ITARGETSR8...GICD_ITARGETSRN:\n\t\t*value = vgicv2_get_virq_affinity(vcpu, offset);\n\t\tbreak;\n\tcase GICD_ICFGR...GICD_ICFGRN:\n\t\t*value = vgicv2_get_virq_type(vcpu, offset);\n\t\tbreak;\n\n\tcase GICD_ICPIDR2:\n\t\t*value = 0x2 << 4;\n\t}\n\n\treturn 0;\n}\n\nvoid vgicv2_send_sgi(struct vcpu *vcpu, uint32_t sgi_value)\n{\n\tint bit;\n\tsgi_mode_t mode;\n\tuint32_t sgi;\n\tcpumask_t cpumask;\n\tunsigned long list;\n\tstruct vm *vm = vcpu->vm;\n\tstruct vcpu *target;\n\n\tcpumask_clearall(&cpumask);\n\tlist = (sgi_value >> 16) & 0xff;\n\tsgi = sgi_value & 0xf;\n\tmode = (sgi_value >> 24) & 0x3;\n\tif (mode == 0x3) {\n\t\tpr_warn(\"invalid sgi mode\\n\");\n\t\treturn;\n\t}\n\n\tif (mode == SGI_TO_LIST) {\n\t\tfor_each_set_bit(bit, &list, 8)\n\t\t\tcpumask_set_cpu(bit, &cpumask);\n\t} else if (mode == SGI_TO_OTHERS) {\n\t\tfor (bit = 0; bit < vm->vcpu_nr; bit++) {\n\t\t\tif (bit == vcpu->vcpu_id)\n\t\t\t\tcontinue;\n\t\t\tcpumask_set_cpu(bit, &cpumask);\n\t\t}\n\t} else\n\t\tcpumask_set_cpu(vcpu->vcpu_id, &cpumask);\n\n\tfor_each_cpu(bit, &cpumask) {\n\t\ttarget = get_vcpu_in_vm(vm, bit);\n\t\tif (target == NULL)\n\t\t\tpanic(\"vcpu%d is not in vm\\n\", bit);\n\t\tsend_virq_to_vcpu(target, sgi);\n\t}\n}\n\nstatic int vgicv2_write(struct vcpu *vcpu, struct vgicv2_dev *gic,\n\t\tunsigned long offset, unsigned long *v)\n{\n\tuint32_t x, y, bit, t;\n\tuint32_t value = *(uint32_t *)v;\n\n\t/* to be done */\n\tswitch (offset) {\n\tcase GICD_CTLR:\n\t\tgic->gicd_ctlr = value;\n\t\tbreak;\n\tcase GICD_TYPER:\n\t\tbreak;\n\tcase GICD_IGROUPR...GICD_IGROUPRN:\n\t\tbreak;\n\tcase GICD_ISENABLER...GICD_ISENABLERN:\n\t\tx = (offset - GICD_ISENABLER) / 4;\n\t\ty = x * 32;\n\t\tfor_each_set_bit(bit, v, 32)\n\t\t\tvirq_enable(vcpu, y + bit);\n\t\tbreak;\n\tcase GICD_ICENABLER...GICD_ICENABLERN:\n\t\tx = (offset - GICD_ICENABLER) / 4;\n\t\ty = x * 32;\n\t\tfor_each_set_bit(bit, v, 32)\n\t\t\tvirq_disable(vcpu, y + bit);\n\t\tbreak;\n\tcase GICD_ISPENDR...GICD_ISPENDRN:\n\t\tbreak;\n\tcase GICD_ICPENDR...GICD_ICPENDRN:\n\t\tbreak;\n\tcase GICD_ISACTIVER...GICD_ISACTIVERN:\n\t\tbreak;\n\tcase GICD_ICACTIVER...GICD_ICACTIVERN:\n\t\tbreak;\n\tcase GICD_IPRIORITYR...GICD_IPRIORITYRN:\n\t\tt = value;\n\t\tx = (offset - GICD_IPRIORITYR) / 4;\n\t\ty = x * 4 - 1;\n\t\tbit = (t & 0x000000ff);\n\t\tvirq_set_priority(vcpu, y + 1, bit);\n\t\tbit = (t & 0x0000ff00) >> 8;\n\t\tvirq_set_priority(vcpu, y + 2, bit);\n\t\tbit = (t & 0x00ff0000) >> 16;\n\t\tvirq_set_priority(vcpu, y + 3, bit);\n\t\tbit = (t & 0xff000000) >> 24;\n\t\tvirq_set_priority(vcpu, y + 4, bit);\n\t\tbreak;\n\tcase GICD_ITARGETSR8...GICD_ITARGETSRN:\n\t\t/* to be done */\n\t\tbreak;\n\tcase GICD_ICFGR...GICD_ICFGRN:\n\t\tvgicv2_set_virq_type(vcpu, offset, value);\n\t\tbreak;\n\n\tcase GICD_SGIR:\n\t\tvgicv2_send_sgi(vcpu, value);\n\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\nstatic int vgicv2_mmio_handler(struct vdev *vdev, gp_regs *regs,\n\t\tint read, unsigned long offset, unsigned long *value)\n{\n\tstruct vcpu *vcpu = get_current_vcpu();\n\tstruct vgicv2_dev *gic = vdev_to_vgicv2(vdev);\n\n\tif (read)\n\t\treturn vgicv2_read(vcpu, gic, offset, value);\n\telse\n\t\treturn vgicv2_write(vcpu, gic, offset, value);\n}\n\nstatic int vgicv2_mmio_read(struct vdev *vdev, gp_regs *regs,\n\t\tint idx, unsigned long offset, unsigned long *read_value)\n{\n\treturn vgicv2_mmio_handler(vdev, regs, 1, offset, read_value);\n}\n\nstatic int vgicv2_mmio_write(struct vdev *vdev, gp_regs *regs,\n\t\tint idx, unsigned long offset, unsigned long *write_value)\n{\n\treturn vgicv2_mmio_handler(vdev, regs, 0, offset, write_value);\n}\n\nstatic void vgicv2_reset(struct vdev *vdev)\n{\n\tpr_notice(\"vgicv2 device reset\\n\");\n}\n\nstatic void vgicv2_deinit(struct vdev *vdev)\n{\n\tstruct vgicv2_dev *dev = vdev_to_vgicv2(vdev);\n\n\tif (!dev)\n\t\treturn;\n\n\tvdev_release(&dev->vdev);\n\tfree(dev);\n}\n\nstatic int vgicc_read(struct vdev *vdev, gp_regs *reg,\n\t\tint idx, unsigned long offset, unsigned long *value)\n{\n\tstruct vgicc *vgicc = vdev_to_vgicc(vdev);\n\n\tswitch (offset) {\n\tcase GICC_CTLR:\n\t\t*value = vgicc->gicc_ctlr;\n\t\tbreak;\n\tcase GICC_PMR:\n\t\t*value = vgicc->gicc_pmr;\n\t\tbreak;\n\tcase GICC_BPR:\n\t\t*value = vgicc->gicc_bpr;\n\t\tbreak;\n\tcase GICC_IAR:\n\t\t/* get the pending irq number */\n\t\t*value = get_pending_virq(get_current_vcpu());\n\t\tbreak;\n\tcase GICC_RPR:\n\t\t/* TBD - now fix to 0xa0 */\n\t\t*value = 0xa0;\n\t\tbreak;\n\tcase GICC_HPPIR:\n\t\t/* TBD - now fix to 0xa0 */\n\t\t*value = 0xa0;\n\t\tbreak;\n\tcase GICC_IIDR:\n\t\t*value = 0x43b | (0x2 << 16);\n\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\nstatic int vgicc_write(struct vdev *vdev, gp_regs *reg,\n\t\tint idx, unsigned long offset, unsigned long *value)\n{\n\tstruct vgicc *vgicc = vdev_to_vgicc(vdev);\n\n\tswitch (offset) {\n\tcase GICC_CTLR:\n\t\tvgicc->gicc_ctlr = *value;\n\t\tbreak;\n\tcase GICC_PMR:\n\t\tvgicc->gicc_pmr = *value;\n\t\tbreak;\n\tcase GICC_BPR:\n\t\tvgicc->gicc_bpr = *value;\n\t\tbreak;\n\tcase GICC_EOIR:\n\t\tclear_pending_virq(get_current_vcpu(), *value);\n\t\tbreak;\n\tcase GICC_DIR:\n\t\t/* if the virq is hw to deactive it TBD */\n\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\nstatic void vgicc_reset(struct vdev *vdev)\n{\n}\n\nstatic void vgicc_deinit(struct vdev *vdev)\n{\n\tvdev_release(vdev);\n\tfree(vdev);\n}\n\nstatic int vgicv2_create_vgicc(struct vm *vm, unsigned long base, size_t size)\n{\n\tstruct vgicc *vgicc;\n\n\tvgicc = zalloc(sizeof(*vgicc));\n\tif (!vgicc) {\n\t\tpr_err(\"no memory for vgicv2 vgicc\\n\");\n\t\treturn -ENOMEM;\n\t}\n\n\thost_vdev_init(vm, &vgicc->vdev, \"vgicv2_vgicc\");\n\tif (vdev_add_iomem_range(&vgicc->vdev, base, size)) {\n\t\tpr_err(\"vgicv2: add gicc iomem failed\\n\");\n\t\tfree(vgicc);\n\t\treturn -ENOMEM;\n\t}\n\n\tvgicc->gicc_base = base;\n\tvgicc->vdev.read = vgicc_read;\n\tvgicc->vdev.write = vgicc_write;\n\tvgicc->vdev.reset = vgicc_reset;\n\tvgicc->vdev.deinit = vgicc_deinit;\n\tvdev_add(&vgicc->vdev);\n\n\treturn 0;\n}\n\nstatic inline void writel_gich(uint32_t val, unsigned int offset)\n{\n\twritel_relaxed(val, (void *)vgicv2_info.gich_base + offset);\n}\n\nstatic inline uint32_t readl_gich(int unsigned offset)\n{\n\treturn readl_relaxed((void *)vgicv2_info.gich_base + offset);\n}\n\nint gicv2_get_virq_state(struct vcpu *vcpu, struct virq_desc *virq)\n{\n\tuint32_t value;\n\n\tif (virq->id >= gicv2_nr_lrs)\n\t\treturn 0;\n\n\tvalue = readl_gich(GICH_LR + virq->id * 4);\n\trmb();\n\tvalue = (value >> 28) & 0x3;\n\n\treturn value;\n}\n\nstatic int gicv2_send_virq(struct vcpu *vcpu, struct virq_desc *virq)\n{\n\tuint32_t val;\n\tuint32_t pid = 0;\n\tstruct gich_lr *gich_lr;\n\n\tif (virq->id >= gicv2_nr_lrs) {\n\t\tpr_err(\"invalid virq %d\\n\", virq->id);\n\t\treturn -EINVAL;\n\t}\n\n\tif (virq_is_hw(virq))\n\t\tpid = virq->hno;\n\telse {\n\t\tif (virq->vno < 16)\n\t\t\tpid = virq->src;\n\t}\n\n\tgich_lr = (struct gich_lr *)&val;\n\tgich_lr->vid = virq->vno;\n\tgich_lr->pid = pid;\n\tgich_lr->pr = virq->pr;\n\tgich_lr->grp1 = 0;\n\tgich_lr->state = 1;\n\tgich_lr->hw = !!virq_is_hw(virq);\n\n\twritel_gich(val, GICH_LR + virq->id * 4);\n\n\treturn 0;\n}\n\nstatic int gicv2_update_virq(struct vcpu *vcpu,\n\t\tstruct virq_desc *desc, int action)\n{\n\tif (!desc || desc->id >= gicv2_nr_lrs)\n\t\treturn -EINVAL;\n\n\tswitch (action) {\n\tcase VIRQ_ACTION_REMOVE:\n\t\tif (virq_is_hw(desc))\n\t\t\tirq_clear_pending(desc->hno);\n\n\tcase VIRQ_ACTION_CLEAR:\n\t\twritel_gich(0, GICH_LR + desc->id * 4);\n\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\nstatic int vgicv2_vcpu_init(struct vcpu *vcpu, void *d, unsigned long flags)\n{\n\tif (!(flags & VIRQCHIP_F_HW_VIRT))\n\t\treturn 0;\n\n\tvcpu->virq_struct->nr_lrs = gicv2_nr_lrs;\n\n\treturn 0;\n}\n\nstatic int vgicv2_init_virqchip(struct virq_chip *vc,\n\t\tstruct vgicv2_dev *dev, unsigned long flags)\n{\n\tif (flags & VIRQCHIP_F_HW_VIRT) {\n\t\tvc->exit_from_guest = vgic_irq_exit_from_guest;\n\t\tvc->enter_to_guest = vgic_irq_enter_to_guest;\n\t\tvc->send_virq = gicv2_send_virq;\n\t\tvc->update_virq = gicv2_update_virq;\n\t\tvc->get_virq_state = gicv2_get_virq_state;\n\t}\n\n\tvc->xlate = gic_xlate_irq;\n\tvc->generate_virq = vgic_generate_virq;\n\tvc->vcpu_init = vgicv2_vcpu_init;\n\tvc->flags = flags;\n\n\treturn 0;\n}\n\nstatic int get_vgicv2_info(struct device_node *node, struct vgicv2_info *vinfo)\n{\n\tint ret;\n\n\tmemset(vinfo, 0, sizeof(struct vgicv2_info));\n\tret = translate_device_address_index(node, &vinfo->gicd_base,\n\t\t\t&vinfo->gicd_size, 0);\n\tif (ret) {\n\t\tpr_err(\"no gicv3 address info found\\n\");\n\t\treturn -ENOENT;\n\t}\n\n\tret = translate_device_address_index(node, &vinfo->gicc_base,\n\t\t\t&vinfo->gicc_size, 1);\n\tif (ret) {\n\t\tpr_err(\"no gicc address info found\\n\");\n\t\treturn -ENOENT;\n\t}\n\n\tif (vinfo->gicd_base == 0 || vinfo->gicd_size == 0 ||\n\t\t\tvinfo->gicc_base == 0 || vinfo->gicc_size == 0) {\n\t\tpr_err(\"gicd or gicc address info not correct\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\ttranslate_device_address_index(node, &vinfo->gich_base,\n\t\t\t&vinfo->gich_size, 2);\n\ttranslate_device_address_index(node, &vinfo->gicv_base,\n\t\t\t&vinfo->gicv_size, 3);\n\n\tpr_notice(\"vgicv2: address 0x%x 0x%x 0x%x 0x%x\\n\",\n\t\t\tvinfo->gicd_base, vinfo->gicd_size,\n\t\t\tvinfo->gicc_base, vinfo->gicc_size);\n\n\treturn 0;\n\n}\n\nstatic struct virq_chip *vgicv2_virqchip_init(struct vm *vm,\n\t\tstruct device_node *node)\n{\n\tint ret, flags = 0;\n\tstruct vgicv2_dev *dev;\n\tstruct virq_chip *vc;\n\tstruct vgicv2_info vinfo;\n\n\tpr_notice(\"create vgicv2 for vm-%d\\n\", vm->vmid);\n\n\tret = get_vgicv2_info(node, &vinfo);\n\tif (ret) {\n\t\tpr_err(\"no gicv2 address info found\\n\");\n\t\treturn NULL;\n\t}\n\n\tdev = zalloc(sizeof(struct vgicv2_dev));\n\tif (!dev)\n\t\treturn NULL;\n\n\tdev->gicd_base = vinfo.gicd_base;\n\thost_vdev_init(vm, &dev->vdev, \"vgicv2\");\n\tret = vdev_add_iomem_range(&dev->vdev, vinfo.gicd_base, vinfo.gicd_size);\n\tif (ret)\n\t\tgoto release_vdev;\n\n\tdev->gicd_typer = vm->vcpu_nr << 5;\n\tdev->gicd_typer |= (vm->vspi_nr >> 5) - 1;\n\n\tdev->gicd_iidr = 0x0;\n\n\tdev->vdev.read = vgicv2_mmio_read;\n\tdev->vdev.write = vgicv2_mmio_write;\n\tdev->vdev.deinit = vgicv2_deinit;\n\tdev->vdev.reset = vgicv2_reset;\n\tvdev_add(&dev->vdev);\n\n\tvc = alloc_virq_chip();\n\tif (!vc)\n\t\tgoto release_vdev;\n\n\t/*\n\t * if the gicv base is set indicate that\n\t * platform has a hardware gicv2, otherwise\n\t * we need to emulated the trap.\n\t */\n\tif (vgicv2_mode != VGICV2_MODE_SWE) {\n\t\tflags |= VIRQCHIP_F_HW_VIRT;\n\t\tpr_notice(\"map gicc 0x%x to gicv 0x%x size 0x%x\\n\",\n\t\t\t\tvinfo.gicc_base, vgicv2_info.gicv_base,\n\t\t\t\tvinfo.gicc_size);\n\t\tcreate_guest_mapping(&vm->mm, vinfo.gicc_base,\n\t\t\t\tvgicv2_info.gicv_base, vinfo.gicc_size,\n\t\t\t\tVM_GUEST_IO | VM_RW);\n\t} else {\n\t\tret = vgicv2_create_vgicc(vm, vinfo.gicc_base, vinfo.gicc_size);\n\t\tif (ret)\n\t\t\tgoto release_vgic;\n\t}\n\n\tvc->inc_pdata = dev;\n\tvgicv2_init_virqchip(vc, dev, flags);\n\n\treturn vc;\n\nrelease_vgic:\n\tfree(vc);\nrelease_vdev:\n\tvdev_release(&dev->vdev);\n\tfree(dev);\n\n\treturn NULL;\n}\nVIRQCHIP_DECLARE(gic400_virqchip, gicv2_match_table,\n\t\tvgicv2_virqchip_init);\n\nstatic void gicv2_state_restore(struct vcpu *vcpu, void *context)\n{\n\tint i;\n\tstruct gicv2_context *c = (struct gicv2_context *)context;\n\n\tfor (i = 0; i < gicv2_nr_lrs; i++)\n\t\twritel_gich(c->lr[i], GICH_LR + i * 4);\n\n\twritel_gich(c->apr, GICH_APR);\n\twritel_gich(c->vmcr, GICH_VMCR);\n\twritel_gich(c->hcr, GICH_HCR);\n}\n\nstatic void gicv2_state_init(struct vcpu *vcpu, void *context)\n{\n\tstruct gicv2_context *c = (struct gicv2_context *)context;\n\n\tmemset(c, 0, sizeof(*c));\n\tc->hcr = 1;\n}\n\nstatic void gicv2_state_save(struct vcpu *vcpu, void *context)\n{\n\tint i;\n\tstruct gicv2_context *c = (struct gicv2_context *)context;\n\n\tdsb();\n\n\tfor (i = 0; i < gicv2_nr_lrs; i++)\n\t\tc->lr[i] = readl_gich(GICH_LR + i * 4);\n\n\tc->vmcr = readl_gich(GICH_VMCR);\n\tc->apr = readl_gich(GICH_APR);\n\tc->hcr = readl_gich(GICH_HCR);\n\twritel_gich(0, GICH_HCR);\n}\n\nstatic void gicv2_state_resume(struct vcpu *vcpu, void *context)\n{\n\tgicv2_state_init(vcpu, context);\n}\n\nstatic int gicv2_vmodule_init(struct vmodule *vmodule)\n{\n\tvmodule->context_size = sizeof(struct gicv2_context);\n\tvmodule->state_init = gicv2_state_init;\n\tvmodule->state_save = gicv2_state_save;\n\tvmodule->state_restore = gicv2_state_restore;\n\tvmodule->state_resume = gicv2_state_resume;\n\n\treturn 0;\n}\n\nint vgicv2_init(uint64_t *data, int len)\n{\n\tunsigned long *value = (unsigned long *)&vgicv2_info;\n\tuint32_t vtr;\n\tint i;\n\n\tif ((data == NULL) || (len == 0)) {\n\t\tpr_notice(\"vgicv2 using software emulation mode\\n\");\n\t\tvgicv2_mode = VGICV2_MODE_SWE;\n\t\treturn 0;\n\t}\n\n\tfor (i = 0; i < len; i++) {\n\t\tvalue[i] = data[i];\n\t\tif (value[i] == 0) {\n\t\t\tpr_err(\"invalid vgicv2 address, fallback to SWE mode\\n\");\n\t\t\tvgicv2_mode = VGICV2_MODE_SWE;\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\tif (vgicv2_info.gicv_base == 0) {\n\t\tpr_warn(\"no gicv base address, fall back to SWE mode\\n\");\n\t\tvgicv2_mode = VGICV2_MODE_SWE;\n\t\treturn 0;\n\t}\n\n\tvtr = readl_relaxed((void *)vgicv2_info.gich_base + GICH_VTR);\n\tgicv2_nr_lrs = (vtr & 0x3f) + 1;\n\tpr_notice(\"vgicv2: nr_lrs %d\\n\", gicv2_nr_lrs);\n\n\tregister_vcpu_vmodule(\"vgicv2\", gicv2_vmodule_init);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "kernel/virt/virq_chips/vgicv3.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n#include <minos/minos.h>\n#include <asm/arch.h>\n#include <minos/irq.h>\n#include <device/gicv3.h>\n#include <asm/io.h>\n#include <virt/vmodule.h>\n#include <minos/cpumask.h>\n#include <minos/sched.h>\n#include <virt/virq.h>\n#include <virt/vdev.h>\n#include <virt/resource.h>\n#include <virt/virq_chip.h>\n#include <minos/of.h>\n#include \"vgic.h\"\n\nstruct vgic_gicd {\n\tuint32_t gicd_ctlr;\n\tuint32_t gicd_typer;\n\tuint32_t gicd_pidr2;\n\tspinlock_t gicd_lock;\n\tunsigned long base;\n\tunsigned long end;\n};\n\nstruct vgic_gicr {\n\tuint32_t gicr_ctlr;\n\tuint32_t gicr_pidr2;\n\tuint64_t gicr_typer;\n\tuint32_t gicr_ispender;\n\tuint32_t gicr_enabler0;\n\tuint32_t vcpu_id;\n\tunsigned long rd_base;\n\tunsigned long sgi_base;\n\tunsigned long vlpi_base;\n\tstruct list_head list;\n\tspinlock_t gicr_lock;\n};\n\nstruct vgicv3_dev {\n\tstruct vdev vdev;\n\tstruct vgic_gicd gicd;\n\tstruct vgic_gicr *gicr[NR_CPUS];\n};\n\n#define GIC_TYPE_GICD\t\t(0x0)\n#define GIC_TYPE_GICR_RD\t(0x1)\n#define GIC_TYPE_GICR_SGI\t(0x2)\n#define GIC_TYPE_GICR_VLPI\t(0x3)\n#define GIC_TYPE_INVAILD\t(0xff)\n\n#define vdev_to_vgic(vdev) \\\n\t(struct vgicv3_dev *)container_of(vdev, struct vgicv3_dev, vdev)\n\nstruct vgicv3_info {\n\tunsigned long gicd_base;\n\tunsigned long gicd_size;\n\tunsigned long gicr_base;\n\tunsigned long gicr_size;\n\tunsigned long gicc_base;\n\tunsigned long gicc_size;\n\tunsigned long gich_base;\n\tunsigned long gich_size;\n\tunsigned long gicv_base;\n\tunsigned long gicv_size;\n};\n\n#define VGICV3_IDX_GICD 0x0\n#define VGICV3_IDX_GICR 0x1\n#define VGICV3_IDX_GICC 0x2\n#define VGICV3_IDX_GICH 0x3\n#define VGICV3_IDX_GICV 0x4\n\nstatic int gicv3_nr_lr = 0;\nstatic int gicv3_nr_pr = 0;\nstatic struct vgicv3_info vgicv3_info;\n\nextern int gic_xlate_irq(struct device_node *node,\n\t\tuint32_t *intspec, unsigned int initsize,\n\t\tuint32_t *hwirq, unsigned long *type);\n\nstatic int vgicv3_send_sgi(struct vcpu *vcpu, unsigned long sgi_value)\n{\n\tsgi_mode_t mode;\n\tuint32_t sgi;\n\tcpumask_t cpumask;\n\tunsigned long tmp, aff3, aff2, aff1;\n\tint bit, logic_cpu;\n\tstruct vm *vm = vcpu->vm;\n\tstruct vcpu *target;\n\n\tsgi = (sgi_value & (0xf << 24)) >> 24;\n\tif (sgi >= 16) {\n\t\tpr_err(\"vgic : sgi number is incorrect %d\\n\", sgi);\n\t\treturn -EINVAL;\n\t}\n\n\tmode = sgi_value & (1UL << 40) ? SGI_TO_OTHERS : SGI_TO_LIST;\n\tcpumask_clearall(&cpumask);\n\n\tif (mode == SGI_TO_LIST) {\n\t\ttmp = sgi_value & 0xffff;\n\t\taff3 = (sgi_value & (0xffUL << 48)) >> 48;\n\t\taff2 = (sgi_value & (0xffUL << 32)) >> 32;\n\t\taff1 = (sgi_value & (0xffUL << 16)) >> 16;\n\t\tfor_each_set_bit(bit, &tmp, 16) {\n\t\t\tlogic_cpu = affinity_to_logic_cpu(aff3, aff2, aff1, bit);\n\t\t\tcpumask_set_cpu(logic_cpu, &cpumask);\n\t\t}\n\t} else if (mode == SGI_TO_OTHERS) {\n\t\tfor (bit = 0; bit < vm->vcpu_nr; bit++) {\n\t\t\tif (bit == vcpu->vcpu_id)\n\t\t\t\tcontinue;\n\t\t\tcpumask_set_cpu(bit, &cpumask);\n\t\t}\n\t} else\n\t\tcpumask_set_cpu(smp_processor_id(), &cpumask);\n\n\t/*\n\t * here we update the gicr releated register\n\t * for some other purpose use TBD\n\t */\n\n\tfor_each_cpu(bit, &cpumask) {\n\t\ttarget = get_vcpu_in_vm(vm, bit);\n\t\tsend_virq_to_vcpu(target, sgi);\n\t}\n\n\treturn 0;\n}\n\nstatic int offset_to_gicr_type(struct vgic_gicr *gicr, unsigned long *poffset)\n{\n\tunsigned long offset = *poffset;\n\n\tif ((offset >= gicr->rd_base) &&\n\t\t(offset < (gicr->rd_base + SIZE_64K))) {\n\t\t*poffset = offset - gicr->rd_base;\n\t\treturn GIC_TYPE_GICR_RD;\n\t}\n\n\tif ((offset >= gicr->sgi_base) &&\n\t\t(offset < (gicr->sgi_base + SIZE_64K))) {\n\t\t*poffset = offset - gicr->sgi_base;\n\t\treturn GIC_TYPE_GICR_SGI;\n\t}\n#if 0\n\tif ((address >= gicr->vlpi_base) &&\n\t\t(address < (gicr->vlpi_base + SIZE_64K))) {\n\n\t\t*offset = address - gicr->vlpi_base;\n\t\treturn GIC_TYPE_GICR_VLPI;\n\t}\n#endif\n\treturn GIC_TYPE_INVAILD;\n}\n\nstatic uint32_t vgic_get_virq_type(struct vcpu *vcpu, uint32_t offset)\n{\n\tint i;\n\tint irq;\n\tuint32_t value = 0, tmp;\n\n\toffset = (offset - GICD_ICFGR) / 4;\n\tirq = 16 * offset;\n\n\tfor (i = 0; i < 16; i++, irq++) {\n\t\ttmp = virq_get_type(vcpu, irq);\n\t\tvalue = value | (tmp << i * 2);\n\t}\n\n\treturn value;\n}\n\nstatic void vgic_set_virq_type(struct vcpu *vcpu,\n\t\tuint32_t offset, uint32_t value)\n{\n\tint i;\n\tint irq;\n\n\toffset = (offset - GICD_ICFGR) / 4;\n\tirq = 16 * offset;\n\n\tfor (i = 0; i < 16; i++, irq++) {\n\t\tvirq_set_type(vcpu, irq, value & 0x3);\n\t\tvalue = value >> 2;\n\t}\n}\n\nstatic int vgic_gicd_mmio_read(struct vcpu *vcpu,\n\t\t\tstruct vgic_gicd *gicd,\n\t\t\tunsigned long offset,\n\t\t\tunsigned long *v)\n{\n\tuint32_t *value = (uint32_t *)v;\n\n\tswitch (offset) {\n\t\tcase GICD_CTLR:\n\t\t\t*value = gicd->gicd_ctlr & ~(1 << 31);\n\t\t\tbreak;\n\t\tcase GICD_TYPER:\n\t\t\t*value = gicd->gicd_typer;\n\t\t\tbreak;\n\t\tcase GICD_STATUSR:\n\t\t\t*value = 0;\n\t\t\tbreak;\n\t\tcase GICD_ISENABLER...GICD_ISENABLER_END:\n\t\t\t*value = 0;\n\t\t\tbreak;\n\t\tcase GICD_ICENABLER...GICD_ICENABLER_END:\n\t\t\t*value = 0;\n\t\t\tbreak;\n\t\tcase GICD_PIDR2:\n\t\t\t*value = gicd->gicd_pidr2;\n\t\t\tbreak;\n\t\tcase GICD_ICFGR...GICD_ICFGR_END:\n\t\t\t*value = vgic_get_virq_type(vcpu, offset);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t*value = 0;\n\t\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\nstatic int vgic_gicd_mmio_write(struct vcpu *vcpu,\n\t\t\tstruct vgic_gicd *gicd,\n\t\t\tunsigned long offset,\n\t\t\tunsigned long *value)\n{\n\tuint32_t x, y, bit, t;\n\n\tspin_lock(&gicd->gicd_lock);\n\n\tswitch (offset) {\n\tcase GICD_CTLR:\n\t\tgicd->gicd_ctlr = *value;\n\t\tbreak;\n\tcase GICD_TYPER:\n\t\tbreak;\n\tcase GICD_STATUSR:\n\t\tbreak;\n\tcase GICD_ISENABLER...GICD_ISENABLER_END:\n\t\tx = (offset - GICD_ISENABLER) / 4;\n\t\ty = x * 32;\n\t\tfor_each_set_bit(bit, value, 32)\n\t\t\tvirq_enable(vcpu, y + bit);\n\t\tbreak;\n\tcase GICD_ICENABLER...GICD_ICENABLER_END:\n\t\tx = (offset - GICD_ICENABLER) / 4;\n\t\ty = x * 32;\n\t\tfor_each_set_bit(bit, value, 32)\n\t\t\tvirq_disable(vcpu, y + bit);\n\t\tbreak;\n\tcase GICD_IPRIORITYR...GICD_IPRIORITYR_END:\n\t\tt = *value;\n\t\tx = (offset - GICD_IPRIORITYR) / 4;\n\t\ty = x * 4 - 1;\n\t\tbit = (t & 0x000000ff);\n\t\tvirq_set_priority(vcpu, y + 1, bit);\n\t\tbit = (t & 0x0000ff00) >> 8;\n\t\tvirq_set_priority(vcpu, y + 2, bit);\n\t\tbit = (t & 0x00ff0000) >> 16;\n\t\tvirq_set_priority(vcpu, y + 3, bit);\n\t\tbit = (t & 0xff000000) >> 24;\n\t\tvirq_set_priority(vcpu, y + 4, bit);\n\t\tbreak;\n\tcase GICD_ICFGR...GICD_ICFGR_END:\n\t\tvgic_set_virq_type(vcpu, offset, *value);\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\tspin_unlock(&gicd->gicd_lock);\n\treturn 0;\n}\n\nstatic int vgic_gicd_mmio(struct vcpu *vcpu, struct vgic_gicd *gicd,\n\t\tint read, unsigned long offset, unsigned long *value)\n{\n\tif (read)\n\t\treturn vgic_gicd_mmio_read(vcpu, gicd, offset, value);\n\telse\n\t\treturn vgic_gicd_mmio_write(vcpu, gicd, offset, value);\n}\n\nstatic int vgic_gicr_rd_mmio(struct vcpu *vcpu, struct vgic_gicr *gicr,\n\t\tint read, unsigned long offset, unsigned long *value)\n{\n\tif (read) {\n\t\tswitch (offset) {\n\t\tcase GICR_PIDR2:\n\t\t\t*value = gicr->gicr_pidr2;\n\t\t\tbreak;\n\t\tcase GICR_TYPER:\n\t\t\t*value = gicr->gicr_typer;\n\t\t\tbreak;\n\t\tcase GICR_TYPER_HIGH:\n\t\t\t*value = gicr->gicr_typer >> 32;\t/* for aarch32 assume 32bit read */\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t*value = 0;\n\t\t\tbreak;\n\t\t}\n\t} else {\n\n\t}\n\n\treturn 0;\n}\n\nstatic int vgic_gicr_sgi_mmio(struct vcpu *vcpu, struct vgic_gicr *gicr,\n\t\tint read, unsigned long offset, unsigned long *value)\n{\n\tint bit;\n\n\tif (read) {\n\t\tswitch (offset) {\n\t\tcase GICR_CTLR:\n\t\t\t*value = gicr->gicr_ctlr & ~(1 << 31);\n\t\t\tbreak;\n\t\tcase GICR_ISPENDR0:\n\t\t\t*value = gicr->gicr_ispender;\n\t\t\tbreak;\n\t\tcase GICR_PIDR2:\n\t\t\t*value = 0x3 << 4;\n\t\t\tbreak;\n\t\tcase GICR_ISENABLER:\n\t\tcase GICR_ICENABLER:\n\t\t\t*value = gicr->gicr_enabler0;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t*value = 0;\n\t\t\tbreak;\n\t\t}\n\t} else {\n\t\tswitch (offset) {\n\t\tcase GICR_ICPENDR0:\n\t\t\tspin_lock(&gicr->gicr_lock);\n\t\t\tfor_each_set_bit(bit, value, 32) {\n\t\t\t\tgicr->gicr_ispender &= ~BIT(bit);\n\t\t\t\tclear_pending_virq(vcpu, bit);\n\t\t\t}\n\t\t\tspin_unlock(&gicr->gicr_lock);\n\t\t\tbreak;\n\t\tcase GICR_ISENABLER:\n\t\t\tspin_lock(&gicr->gicr_lock);\n\t\t\tfor_each_set_bit(bit, value, 32) {\n\t\t\t\tif (!(gicr->gicr_enabler0 & BIT(bit))) {\n\t\t\t\t\tvirq_enable(vcpu, bit);\n\t\t\t\t\tgicr->gicr_enabler0 |= BIT(bit);\n\t\t\t\t}\n\t\t\t}\n\t\t\tspin_unlock(&gicr->gicr_lock);\n\t\t\tbreak;\n\t\tcase GICR_ICENABLER:\n\t\t\tspin_lock(&gicr->gicr_lock);\n\t\t\tfor_each_set_bit(bit, value, 32) {\n\t\t\t\tif (gicr->gicr_enabler0 & BIT(bit)) {\n\t\t\t\t\tvirq_disable(vcpu, bit);\n\t\t\t\t\tgicr->gicr_enabler0 &= ~BIT(bit);\n\t\t\t\t}\n\t\t\t}\n\t\t\tspin_unlock(&gicr->gicr_lock);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn 0;\n}\n\nstatic int vgic_gicr_vlpi_mmio(struct vcpu *vcpu, struct vgic_gicr *gicr,\n\t\tint read, unsigned long offset, unsigned long *v)\n{\n\treturn 0;\n}\n\nstatic int vgic_check_gicr_access(struct vcpu *vcpu, struct vgic_gicr *gicr,\n\t\t\tint type, unsigned long offset)\n{\n\tif (get_vcpu_id(vcpu) != gicr->vcpu_id) {\n\t\tif (type == GIC_TYPE_GICR_RD) {\n\t\t\tswitch (offset) {\n\t\t\tcase GICR_TYPER:\n\t\t\tcase GICR_PIDR2:\n\t\t\tcase GICR_TYPER_HIGH:\t\t// for aarch32 gicv3\n\t\t\t\treturn 1;\n\t\t\tdefault:\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t} else {\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\treturn 1;\n}\n\nstatic int vgic_mmio_handler(struct vdev *vdev, gp_regs *regs,\n\t\tint read, int idx, unsigned long offset,\n\t\tunsigned long *value)\n{\n\tint type = GIC_TYPE_INVAILD;\n\tstruct vgic_gicd *gicd = NULL;\n\tstruct vgic_gicr *gicr = NULL;\n\tstruct vcpu *vcpu = get_current_vcpu();\n\tstruct vgicv3_dev *gic = vdev_to_vgic(vdev);\n\tint i;\n\n\tgicr = gic->gicr[get_vcpu_id(vcpu)];\n\tgicd = &gic->gicd;\n\n\tif (idx == VGICV3_IDX_GICD) {\n\t\ttype = GIC_TYPE_GICD;\n\t} else if (idx == VGICV3_IDX_GICR) {\n\t\ttype = offset_to_gicr_type(gicr, &offset);\n\t\tif (type != GIC_TYPE_INVAILD)\n\t\t\tgoto out;\n\n\t\t/* master vcpu may access other vcpu's gicr */\n\t\tfor (i = 0; i < vcpu->vm->vcpu_nr; i++) {\n\t\t\tgicr = gic->gicr[i];\n\t\t\ttype = offset_to_gicr_type(gicr, &offset);\n\t\t\tif (type != GIC_TYPE_INVAILD)\n\t\t\t\tgoto out;\n\t\t}\n\t} else {\n\t\tpr_err(\"only support GICD and GICR emulation\\n\");\n\t\treturn -EINVAL;\n\t}\nout:\n\tif (type == GIC_TYPE_INVAILD) {\n\t\tpr_err(\"invaild gicr type and address\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\tif (type != GIC_TYPE_GICD) {\n\t\tif (!vgic_check_gicr_access(vcpu, gicr, type, offset))\n\t\t\treturn -EACCES;\n\t}\n\n\tswitch (type) {\n\tcase GIC_TYPE_GICD:\n\t\treturn vgic_gicd_mmio(vcpu, gicd, read, offset, value);\n\tcase GIC_TYPE_GICR_RD:\n\t\treturn vgic_gicr_rd_mmio(vcpu, gicr, read, offset, value);\n\tcase GIC_TYPE_GICR_SGI:\n\t\treturn vgic_gicr_sgi_mmio(vcpu, gicr, read, offset, value);\n\tcase GIC_TYPE_GICR_VLPI:\n\t\treturn vgic_gicr_vlpi_mmio(vcpu, gicr, read, offset, value);\n\tdefault:\n\t\tpr_err(\"unsupport gic type %d\\n\", type);\n\t\treturn -EINVAL;\n\t}\n\n\treturn 0;\n}\n\nstatic int vgic_mmio_read(struct vdev *vdev, gp_regs *regs, int idx,\n\t\tunsigned long address, unsigned long *read_value)\n{\n\treturn vgic_mmio_handler(vdev, regs, 1, idx, address, read_value);\n}\n\nstatic int vgic_mmio_write(struct vdev *vdev, gp_regs *regs, int idx,\n\t\tunsigned long address, unsigned long *write_value)\n{\n\treturn vgic_mmio_handler(vdev, regs, 0, idx, address, write_value);\n}\n\nstatic void vgic_gicd_init(struct vm *vm, struct vgic_gicd *gicd,\n\t\tunsigned long base, size_t size)\n{\n\tuint32_t typer = 0;\n\tint nr_spi;\n\n\t/*\n\t * when a vm is created need to create\n\t * one vgic for each vm since gicr is percpu\n\t * but gicd is shared so created it here\n\t */\n\tmemset(gicd, 0, sizeof(*gicd));\n\n\tgicd->base = base;\n\tgicd->end = base + size;\n\n\tspin_lock_init(&gicd->gicd_lock);\n\n\tgicd->gicd_ctlr = 0;\n\n\t/* GICV3 and provide vm->virq_nr interrupt */\n\tgicd->gicd_pidr2 = (0x3 << 4);\n\n\ttyper |= vm->vcpu_nr << 5;\n\ttyper |= 9 << 19;\n\tnr_spi = ((vm->vspi_nr + 32) >> 5) - 1;\n\ttyper |= nr_spi;\n\tgicd->gicd_typer = typer;\n}\n\n\nstatic void vgic_gicr_init(struct vcpu *vcpu,\n\t\tstruct vgic_gicr *gicr, unsigned long base)\n{\n\tgicr->vcpu_id = get_vcpu_id(vcpu);\n\n\t/*\n\t * now for gicv3 TBD, do not support vlpi.\n\t */\n\tbase = (128 * 1024) * vcpu->vcpu_id;\n\tgicr->rd_base = base;\n\tgicr->sgi_base = base + (64 * 1024);\n\tgicr->vlpi_base = 0;\n\n\tgicr->gicr_ctlr = 0;\n\tgicr->gicr_ispender = 0;\n\tspin_lock_init(&gicr->gicr_lock);\n\n\t/* TBD */\n\tgicr->gicr_pidr2 = 0x3 << 4;\n\n\t/*\n\t * Linux will use the Last bit (bit 4) to detect whether\n\t * this gicr is the last GICR.\n\t */\n\tgicr->gicr_typer = 0 | ((unsigned long)vcpu->vcpu_id << 32);\n\tif (vcpu->vcpu_id == (vcpu->vm->vcpu_nr - 1))\n\t\tgicr->gicr_typer |= (1 << 4);\n}\n\nstatic void vm_release_gic(struct vgicv3_dev *gic)\n{\n\tint i;\n\tstruct vm *vm = gic->vdev.vm;\n\tstruct vgic_gicr *gicr;\n\n\tif (!gic)\n\t\treturn;\n\n\tvdev_release(&gic->vdev);\n\n\tfor (i = 0; i < vm->vcpu_nr; i++) {\n\t\tgicr = gic->gicr[i];\n\t\tif (gicr)\n\t\t\tfree(gicr);\n\t}\n\n\tfree(gic);\n}\n\nstatic void vgic_deinit(struct vdev *vdev)\n{\n\tstruct vgicv3_dev *dev = vdev_to_vgic(vdev);\n\n\treturn vm_release_gic(dev);\n}\n\nstatic void vgic_reset(struct vdev *vdev)\n{\n\tpr_notice(\"vgic device reset\\n\");\n}\n\nstatic int64_t gicv3_read_lr(int lr)\n{\n\tswitch (lr) {\n\tcase 0: return read_sysreg(ICH_LR0_EL2);\n\tcase 1: return read_sysreg(ICH_LR1_EL2);\n\tcase 2: return read_sysreg(ICH_LR2_EL2);\n\tcase 3: return read_sysreg(ICH_LR3_EL2);\n\tcase 4: return read_sysreg(ICH_LR4_EL2);\n\tcase 5: return read_sysreg(ICH_LR5_EL2);\n\tcase 6: return read_sysreg(ICH_LR6_EL2);\n\tcase 7: return read_sysreg(ICH_LR7_EL2);\n\tcase 8: return read_sysreg(ICH_LR8_EL2);\n\tcase 9: return read_sysreg(ICH_LR9_EL2);\n\tcase 10: return read_sysreg(ICH_LR10_EL2);\n\tcase 11: return read_sysreg(ICH_LR11_EL2);\n\tcase 12: return read_sysreg(ICH_LR12_EL2);\n\tcase 13: return read_sysreg(ICH_LR13_EL2);\n\tcase 14: return read_sysreg(ICH_LR14_EL2);\n\tcase 15: return read_sysreg(ICH_LR15_EL2);\n\tdefault:\n\t\t return 0;\n\t}\n}\n\nstatic void gicv3_write_lr(int lr, uint64_t val)\n{\n\tswitch ( lr )\n\t{\n\tcase 0:\n\t\twrite_sysreg(val, ICH_LR0_EL2);\n\t\tbreak;\n\tcase 1:\n\t\twrite_sysreg(val, ICH_LR1_EL2);\n\t\tbreak;\n\tcase 2:\n\t\twrite_sysreg(val, ICH_LR2_EL2);\n\t\tbreak;\n\tcase 3:\n\t\twrite_sysreg(val, ICH_LR3_EL2);\n\t\tbreak;\n\tcase 4:\n\t\twrite_sysreg(val, ICH_LR4_EL2);\n\t\tbreak;\n\tcase 5:\n\t\twrite_sysreg(val, ICH_LR5_EL2);\n\t\tbreak;\n\tcase 6:\n\t\twrite_sysreg(val, ICH_LR6_EL2);\n\t\tbreak;\n\tcase 7:\n\t\twrite_sysreg(val, ICH_LR7_EL2);\n\t\tbreak;\n\tcase 8:\n\t\twrite_sysreg(val, ICH_LR8_EL2);\n\t\tbreak;\n\tcase 9:\n\t\twrite_sysreg(val, ICH_LR9_EL2);\n\t\tbreak;\n\tcase 10:\n\t\twrite_sysreg(val, ICH_LR10_EL2);\n\t\tbreak;\n\tcase 11:\n\t\twrite_sysreg(val, ICH_LR11_EL2);\n\t\tbreak;\n\tcase 12:\n\t\twrite_sysreg(val, ICH_LR12_EL2);\n\t\tbreak;\n\tcase 13:\n\t\twrite_sysreg(val, ICH_LR13_EL2);\n\t\tbreak;\n\tcase 14:\n\t\twrite_sysreg(val, ICH_LR14_EL2);\n\t\tbreak;\n\tcase 15:\n\t\twrite_sysreg(val, ICH_LR15_EL2);\n\t\tbreak;\n\tdefault:\n\t\treturn;\n\t}\n}\n\nstatic int gicv3_send_virq(struct vcpu *vcpu, struct virq_desc *virq)\n{\n\tuint64_t value = 0;\n\tstruct gic_lr *lr = (struct gic_lr *)&value;\n\n\tif (virq->id >= gicv3_nr_lr) {\n\t\tpr_err(\"invalid virq id %d\\n\", virq->id);\n\t\treturn -EINVAL;\n\t}\n\n\tlr->v_intid = virq->vno;\n\tlr->p_intid = virq->hno;\n\tlr->priority = virq->pr;\n\tlr->group = 1;\n\tlr->hw = !!virq_is_hw(virq);\n\tlr->state = 1;\n\n\tgicv3_write_lr(virq->id, value);\n\n\treturn 0;\n}\n\nstatic int gicv3_update_virq(struct vcpu *vcpu,\n\t\tstruct virq_desc *desc, int action)\n{\n\tif (!desc || desc->id >= gicv3_nr_lr)\n\t\treturn -EINVAL;\n\n\tswitch (action) {\n\t\t/*\n\t\t * wether need to update the context value?\n\t\t * TBD, since the context has not been saved\n\t\t * so do not need to update it.\n\t\t *\n\t\t * 2: if the virq is attached to a physical irq\n\t\t *    need to update the GICR register ?\n\t\t */\n\n\tcase VIRQ_ACTION_REMOVE:\n\t\tif (virq_is_hw(desc))\n\t\t\tirq_clear_pending(desc->hno);\n\n\tcase VIRQ_ACTION_CLEAR:\n\t\tgicv3_write_lr(desc->id, 0);\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\nstatic int gicv3_get_virq_state(struct vcpu *vcpu, struct virq_desc *virq)\n{\n\tuint64_t value;\n\n\tif (virq->id >= gicv3_nr_lr)\n\t\treturn 0;\n\n\tvalue = gicv3_read_lr(virq->id);\n\trmb();\n\tvalue = (value >> 62) & 0x03;\n\n\treturn ((int)value);\n}\n\nstatic int gicv3_generate_virq(uint32_t *array, int virq)\n{\n\treturn vgic_generate_virq(array, virq);\n}\n\nstatic int vgicv3_vcpu_init(struct vcpu *vcpu, void *d, unsigned long flags)\n{\n\tif (!(flags & VIRQCHIP_F_HW_VIRT))\n\t\treturn 0;\n\n\tvcpu->virq_struct->nr_lrs = gicv3_nr_lr;\n\n\treturn 0;\n}\n\nstatic void vgicv3_init_virqchip(struct virq_chip *vc,\n\t\tstruct vgicv3_dev *dev, unsigned long flags)\n{\n\tif (flags & VIRQCHIP_F_HW_VIRT) {\n\t\tvc->exit_from_guest = vgic_irq_exit_from_guest;\n\t\tvc->enter_to_guest = vgic_irq_enter_to_guest;\n\t\tvc->xlate = gic_xlate_irq;\n\t\tvc->generate_virq = gicv3_generate_virq;\n\t\tvc->send_virq = gicv3_send_virq;\n\t\tvc->update_virq = gicv3_update_virq;\n\t\tvc->get_virq_state = gicv3_get_virq_state;\n\t\tvc->vcpu_init = vgicv3_vcpu_init;\n\t\tvc->flags = flags;\n\t} else {\n\t\tpr_warn(\"***WARN***vgicv3 currently only\" \\\n\t\t\t\t\"support hard virt mode\\n\");\n\t}\n\n\tvc->inc_pdata = dev;\n}\n\nstatic int get_vgicv3_info(struct device_node *node, struct vgicv3_info *vinfo)\n{\n\tint ret;\n\n\tmemset(vinfo, 0, sizeof(struct vgicv3_info));\n\tret = translate_device_address_index(node, &vinfo->gicd_base,\n\t\t\t&vinfo->gicd_size, 0);\n\tif (ret) {\n\t\tpr_err(\"no gicv3 address info found\\n\");\n\t\treturn -ENOENT;\n\t}\n\n\tret = translate_device_address_index(node, &vinfo->gicr_base,\n\t\t\t&vinfo->gicr_size, 1);\n\tif (ret) {\n\t\tpr_err(\"no gicr address info found\\n\");\n\t\treturn -ENOENT;\n\t}\n\n\tif (vinfo->gicd_base == 0 || vinfo->gicd_size == 0 ||\n\t\t\tvinfo->gicr_base == 0 || vinfo->gicr_size == 0) {\n\t\tpr_err(\"gicd or gicr address info not correct\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\ttranslate_device_address_index(node, &vinfo->gicc_base,\n\t\t\t&vinfo->gicc_size, 2);\n\ttranslate_device_address_index(node, &vinfo->gich_base,\n\t\t\t&vinfo->gich_size, 3);\n\ttranslate_device_address_index(node, &vinfo->gicv_base,\n\t\t\t&vinfo->gicv_size, 4);\n\tpr_notice(\"vgicv3: address 0x%x 0x%x 0x%x 0x%x\\n\",\n\t\t\tvinfo->gicd_base, vinfo->gicd_size,\n\t\t\tvinfo->gicr_base, vinfo->gicr_size);\n\n\treturn 0;\n}\n\nstruct virq_chip *vgicv3_virqchip_init(struct vm *vm,\n\t\tstruct device_node *node)\n{\n\tint i, ret = 0;\n\tstruct vgic_gicr *gicr;\n\tstruct vgicv3_dev *vgicv3_dev;\n\tstruct vcpu *vcpu;\n\tstruct vgicv3_info vinfo;\n\tunsigned long flags = 0;\n\tstruct virq_chip *vc;\n\tstruct arm_virt_data *arm_data = vm->arch_data;\n\tstruct vdev *vdev;\n\n\tpr_notice(\"vgicv3: create vdev for vm-%d\\n\", vm->vmid);\n\n\tret = get_vgicv3_info(node, &vinfo);\n\tif (ret)\n\t\treturn NULL;\n\n\tvgicv3_dev = zalloc(sizeof(struct vgicv3_dev));\n\tif (!vgicv3_dev)\n\t\treturn NULL;\n\n\t/*\n\t * need create or init the vdev before add memory region\n\t * to it.\n\t */\n\tvdev = &vgicv3_dev->vdev;\n\thost_vdev_init(vm, vdev, \"vgicv3\");\n\n\tret = vdev_add_iomem_range(vdev, vinfo.gicd_base, vinfo.gicd_size);\n\tret += vdev_add_iomem_range(vdev, vinfo.gicr_base, vinfo.gicr_size);\n\tret += vdev_add_iomem_range(vdev, vinfo.gicc_base, vinfo.gicc_size);\n\tret += vdev_add_iomem_range(vdev, vinfo.gich_base, vinfo.gich_size);\n\tret += vdev_add_iomem_range(vdev, vinfo.gicv_base, vinfo.gicv_size);\n\tif (ret) {\n\t\tpr_err(\"request vmm area for gicv3 failed\\n\");\n\t\tgoto release_gic;\n\t}\n\n\t/*\n\t * Init the vgic3_gicd and vgicv3_gicr.\n\t */\n\tvgic_gicd_init(vm, &vgicv3_dev->gicd, vinfo.gicd_base, vinfo.gicd_size);\n\tfor (i = 0; i < vm->vcpu_nr; i++) {\n\t\tvcpu = vm->vcpus[i];\n\t\tgicr = malloc(sizeof(struct vgic_gicr));\n\t\tif (!gicr)\n\t\t\tgoto release_gic;\n\n\t\tvgic_gicr_init(vcpu, gicr, vinfo.gicr_base);\n\t\tvgicv3_dev->gicr[i] = gicr;\n\t}\n\n\tvdev->read = vgic_mmio_read;\n\tvdev->write = vgic_mmio_write;\n\tvdev->deinit = vgic_deinit;\n\tvdev->reset = vgic_reset;\n\tvdev_add(vdev);\n\n\tvc = alloc_virq_chip();\n\tif (!vc)\n\t\tgoto release_gic;\n\n\tif (vgicv3_info.gicd_base != 0)\n\t\tflags |= VIRQCHIP_F_HW_VIRT;\n\n\tvgicv3_init_virqchip(vc, vgicv3_dev, flags);\n\tarm_data->sgi1r_el1_trap = vgicv3_send_sgi;\n\n\treturn vc;\n\nrelease_gic:\n\tvm_release_gic(vgicv3_dev);\n\treturn NULL;\n}\nVIRQCHIP_DECLARE(vgicv3_chip, gicv3_match_table, vgicv3_virqchip_init);\n\nstatic void gicv3_save_lrs(struct gicv3_context *c, uint32_t count)\n{\n\tif (count > 16)\n\t\tpanic(\"Unsupport LR count\\n\");\n\n\tswitch (count) {\n\tcase 16:\n\t\tc->ich_lr15_el2 = read_sysreg(ICH_LR15_EL2);\n\tcase 15:\n\t\tc->ich_lr14_el2 = read_sysreg(ICH_LR14_EL2);\n\tcase 14:\n\t\tc->ich_lr13_el2 = read_sysreg(ICH_LR13_EL2);\n\tcase 13:\n\t\tc->ich_lr12_el2 = read_sysreg(ICH_LR12_EL2);\n\tcase 12:\n\t\tc->ich_lr11_el2 = read_sysreg(ICH_LR11_EL2);\n\tcase 11:\n\t\tc->ich_lr10_el2 = read_sysreg(ICH_LR10_EL2);\n\tcase 10:\n\t\tc->ich_lr9_el2 = read_sysreg(ICH_LR9_EL2);\n\tcase 9:\n\t\tc->ich_lr8_el2 = read_sysreg(ICH_LR8_EL2);\n\tcase 8:\n\t\tc->ich_lr7_el2 = read_sysreg(ICH_LR7_EL2);\n\tcase 7:\n\t\tc->ich_lr6_el2 = read_sysreg(ICH_LR6_EL2);\n\tcase 6:\n\t\tc->ich_lr5_el2 = read_sysreg(ICH_LR5_EL2);\n\tcase 5:\n\t\tc->ich_lr4_el2 = read_sysreg(ICH_LR4_EL2);\n\tcase 4:\n\t\tc->ich_lr3_el2 = read_sysreg(ICH_LR3_EL2);\n\tcase 3:\n\t\tc->ich_lr2_el2 = read_sysreg(ICH_LR2_EL2);\n\tcase 2:\n\t\tc->ich_lr1_el2 = read_sysreg(ICH_LR1_EL2);\n\tcase 1:\n\t\tc->ich_lr0_el2 = read_sysreg(ICH_LR0_EL2);\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n}\n\nstatic void gicv3_save_aprn(struct gicv3_context *c, uint32_t count)\n{\n\tswitch (count) {\n\tcase 7:\n\t\tc->ich_ap0r2_el2 = read_sysreg32(ICH_AP0R2_EL2);\n\t\tc->ich_ap1r2_el2 = read_sysreg32(ICH_AP1R2_EL2);\n\tcase 6:\n\t\tc->ich_ap0r1_el2 = read_sysreg32(ICH_AP0R1_EL2);\n\t\tc->ich_ap1r1_el2 = read_sysreg32(ICH_AP1R1_EL2);\n\tcase 5:\n\t\tc->ich_ap0r0_el2 = read_sysreg32(ICH_AP0R0_EL2);\n\t\tc->ich_ap1r0_el2 = read_sysreg32(ICH_AP1R0_EL2);\n\t\tbreak;\n\tdefault:\n\t\tpanic(\"Unsupport aprn count\\n\");\n\t}\n}\n\nstatic void gicv3_state_save(struct vcpu *vcpu, void *context)\n{\n\tstruct gicv3_context *c = (struct gicv3_context *)context;\n\n\tdsb();\n\tgicv3_save_lrs(c, gicv3_nr_lr);\n\tgicv3_save_aprn(c, gicv3_nr_pr);\n\tc->icc_sre_el1 = read_sysreg32(ICC_SRE_EL1);\n\tc->ich_vmcr_el2 = read_sysreg32(ICH_VMCR_EL2);\n\tc->ich_hcr_el2 = read_sysreg32(ICH_HCR_EL2);\n}\n\nstatic void gicv3_restore_aprn(struct gicv3_context *c, uint32_t count)\n{\n\tswitch (count) {\n\tcase 7:\n\t\twrite_sysreg32(c->ich_ap0r2_el2, ICH_AP0R2_EL2);\n\t\twrite_sysreg32(c->ich_ap1r2_el2, ICH_AP1R2_EL2);\n\tcase 6:\n\t\twrite_sysreg32(c->ich_ap0r1_el2, ICH_AP0R1_EL2);\n\t\twrite_sysreg32(c->ich_ap1r1_el2, ICH_AP1R1_EL2);\n\tcase 5:\n\t\twrite_sysreg32(c->ich_ap0r0_el2, ICH_AP0R0_EL2);\n\t\twrite_sysreg32(c->ich_ap1r0_el2, ICH_AP1R0_EL2);\n\t\tbreak;\n\tdefault:\n\t\tpanic(\"Unsupport aprn count\");\n\t}\n}\n\nstatic void gicv3_restore_lrs(struct gicv3_context *c, uint32_t count)\n{\n\tif (count > 16)\n\t\tpanic(\"Unsupport LR count\");\n\n\tswitch (count) {\n\tcase 16:\n\t\twrite_sysreg(c->ich_lr15_el2, ICH_LR15_EL2);\n\tcase 15:\n\t\twrite_sysreg(c->ich_lr14_el2, ICH_LR14_EL2);\n\tcase 14:\n\t\twrite_sysreg(c->ich_lr13_el2, ICH_LR13_EL2);\n\tcase 13:\n\t\twrite_sysreg(c->ich_lr12_el2, ICH_LR12_EL2);\n\tcase 12:\n\t\twrite_sysreg(c->ich_lr11_el2, ICH_LR11_EL2);\n\tcase 11:\n\t\twrite_sysreg(c->ich_lr10_el2, ICH_LR10_EL2);\n\tcase 10:\n\t\twrite_sysreg(c->ich_lr9_el2, ICH_LR9_EL2);\n\tcase 9:\n\t\twrite_sysreg(c->ich_lr8_el2, ICH_LR8_EL2);\n\tcase 8:\n\t\twrite_sysreg(c->ich_lr7_el2, ICH_LR7_EL2);\n\tcase 7:\n\t\twrite_sysreg(c->ich_lr6_el2, ICH_LR6_EL2);\n\tcase 6:\n\t\twrite_sysreg(c->ich_lr5_el2, ICH_LR5_EL2);\n\tcase 5:\n\t\twrite_sysreg(c->ich_lr4_el2, ICH_LR4_EL2);\n\tcase 4:\n\t\twrite_sysreg(c->ich_lr3_el2, ICH_LR3_EL2);\n\tcase 3:\n\t\twrite_sysreg(c->ich_lr2_el2, ICH_LR2_EL2);\n\tcase 2:\n\t\twrite_sysreg(c->ich_lr1_el2, ICH_LR1_EL2);\n\tcase 1:\n\t\twrite_sysreg(c->ich_lr0_el2, ICH_LR0_EL2);\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n}\n\nstatic void gicv3_state_restore(struct vcpu *vcpu, void *context)\n{\n\tstruct gicv3_context *c = (struct gicv3_context *)context;\n\n\tgicv3_restore_lrs(c, gicv3_nr_lr);\n\tgicv3_restore_aprn(c, gicv3_nr_pr);\n\twrite_sysreg32(c->icc_sre_el1, ICC_SRE_EL1);\n\twrite_sysreg32(c->ich_vmcr_el2, ICH_VMCR_EL2);\n\twrite_sysreg32(c->ich_hcr_el2, ICH_HCR_EL2);\n\tdsb();\n}\n\nstatic void gicv3_state_init(struct vcpu *vcpu, void *context)\n{\n\tstruct gicv3_context *c = (struct gicv3_context *)context;\n\n\tmemset(c, 0, sizeof(*c));\n\tc->icc_sre_el1 = 0x7;\n\tc->ich_vmcr_el2 = GICH_VMCR_VENG1 | (0xff << 24);\n\tc->ich_hcr_el2 = GICH_HCR_EN;\n}\n\nstatic void gicv3_state_resume(struct vcpu *vcpu, void *context)\n{\n\tgicv3_state_init(vcpu, context);\n}\n\nstatic int gicv3_vmodule_init(struct vmodule *vmodule)\n{\n\tvmodule->context_size = sizeof(struct gicv3_context);\n\tvmodule->state_init = gicv3_state_init;\n\tvmodule->state_save = gicv3_state_save;\n\tvmodule->state_restore = gicv3_state_restore;\n\tvmodule->state_resume = gicv3_state_resume;\n\n\treturn 0;\n}\n\nint vgicv3_init(uint64_t *data, int len)\n{\n\tint i;\n\tuint32_t val;\n\tunsigned long *value = (unsigned long *)&vgicv3_info;\n\n\tfor (i = 0; i < len; i++)\n\t\tvalue[i] = (unsigned long)data[i];\n\n\tif (vgicv3_info.gicd_base == 0 || vgicv3_info.gicr_base == 0 ||\n\t\tvgicv3_info.gicd_size == 0 || vgicv3_info.gicr_size == 0)\n\t\tpanic(\"invalid gicv3 register base from irqchip\\n\");\n\n\tval = read_sysreg32(ICH_VTR_EL2);\n\tgicv3_nr_lr = (val & 0x3f) + 1;\n\tgicv3_nr_pr = ((val >> 29) & 0x7) + 1;\n\tpr_notice(\"vgicv3: nr_lrs %d nr_prs %d\\n\", gicv3_nr_lr, gicv3_nr_pr);\n\n\tregister_vcpu_vmodule(\"gicv3-vmodule\", gicv3_vmodule_init);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "kernel/virt/virq_chips/virq_chip.c",
    "content": "/*\n * Copyright (C) 2018 - 2019 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/irq.h>\n#include <minos/of.h>\n#include <minos/mm.h>\n#include <minos/spinlock.h>\n#include <virt/vm.h>\n#include <virt/virq.h>\n#include <virt/virq_chip.h>\n\nstatic int virqchip_enter_to_guest(void *item, void *data)\n{\n\tstruct vcpu *vcpu = (struct vcpu *)item;\n\tstruct virq_chip *vc = vcpu->vm->virq_chip;\n\tint flags;\n\n\tif (!vc)\n\t\treturn -ENOENT;\n\n\t/*\n\t * if the flags is 0, then means there is no irq inject\n\t * to the vcpu, if there are FIQs inject, the bit 31 will\n\t * set, and other bit indicate how many irq has been injected.\n\t */\n\tflags = vc->enter_to_guest(vcpu, vc->inc_pdata);\n\tif (flags == 0) {\n\t\tif (!(vc->flags & VIRQCHIP_F_HW_VIRT))\n\t\t\tarch_clear_virq_flag();\n\t} else {\n\t\tif (!(vc->flags & VIRQCHIP_F_HW_VIRT)) {\n\t\t\tif (flags & FIQ_HAS_INJECT)\n\t\t\t\tarch_set_vfiq_flag();\n\t\t\telse\n\t\t\t\tarch_set_virq_flag();\n\t\t}\n\t}\n\n\treturn 0;\n}\n\nstatic int virqchip_exit_from_guest(void *item, void *data)\n{\n\tstruct vcpu *vcpu = (struct vcpu *)item;\n\tstruct virq_chip *vc = vcpu->vm->virq_chip;\n\n\tif (vc && vc->exit_from_guest)\n\t\treturn vc->exit_from_guest(vcpu, vc->inc_pdata);\n\telse\n\t\treturn 0;\n}\n\nstruct virq_chip *alloc_virq_chip(void)\n{\n\tstruct virq_chip *vchip;\n\n\tvchip = zalloc(sizeof(struct virq_chip));\n\tif (!vchip)\n\t\treturn NULL;\n\n\treturn vchip;\n}\n\nvoid virqchip_update_virq(struct vcpu *vcpu,\n\t\tstruct virq_desc *virq, int action)\n{\n\tstruct virq_chip *vc = vcpu->vm->virq_chip;\n\n\tif (vc && vc->update_virq)\n\t\tvc->update_virq(vcpu, virq, action);\n}\n\nvoid virqchip_send_virq(struct vcpu *vcpu, struct virq_desc *virq)\n{\n\tstruct virq_chip *vc = vcpu->vm->virq_chip;\n\n\tif (vc && vc->send_virq)\n\t\tvc->send_virq(vcpu, virq);\n}\n\nint virqchip_get_virq_state(struct vcpu *vcpu, struct virq_desc *virq)\n{\n\tstruct virq_chip *vc = vcpu->vm->virq_chip;\n\n\tif (vc && vc->get_virq_state)\n\t\treturn vc->get_virq_state(vcpu, virq);\n\n\treturn 0;\n}\n\nstatic int __init_text virqchip_init(void)\n{\n\tregister_hook(virqchip_enter_to_guest, OS_HOOK_ENTER_TO_GUEST);\n\tregister_hook(virqchip_exit_from_guest, OS_HOOK_EXIT_FROM_GUEST);\n\n\treturn 0;\n}\nsubsys_initcall(virqchip_init);\n"
  },
  {
    "path": "kernel/virt/virtio_mmio.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <virt/vmm.h>\n#include <minos/mm.h>\n#include <minos/bitmap.h>\n#include <virt/virtio.h>\n#include <asm/io.h>\n#include <minos/sched.h>\n#include <virt/vdev.h>\n#include <virt/virq.h>\n#include <generic/virtio_mmio.h>\n#include <virt/resource.h>\n#include <virt/vmcs.h>\n#include <minos/of.h>\n\n#define vdev_to_virtio(vd) \\\n\tcontainer_of(vd, struct virtio_device, vdev)\n\nstatic int virtio_mmio_read(struct vdev *vdev, gp_regs *regs,\n\t\tint idx, unsigned long offset, unsigned long *read_value)\n{\n\treturn 0;\n}\n\nstatic int virtio_mmio_write(struct vdev *vdev, gp_regs *regs,\n\t\tint idx, unsigned long offset, unsigned long *write_value)\n{\n\tstruct vmm_area *va = vdev_get_vmm_area(vdev, idx);\n\tstruct virtio_device *dev = vdev_to_virtio(vdev);\n\tuint32_t value = *(uint32_t *)write_value;\n\tunsigned long address = va->start + offset;\n\tvoid *iomem = dev->iomem;\n\tuint32_t tmp;\n\n\tswitch (offset) {\n\tcase VIRTIO_MMIO_HOST_FEATURES:\n\t\tbreak;\n\tcase VIRTIO_MMIO_HOST_FEATURES_SEL:\n\t\tif (value > 3) {\n\t\t\tpr_warn(\"invalid features sel value %d\\n\", value);\n\t\t\tbreak;\n\t\t}\n\t\ttmp = ioread32(iomem + VIRTIO_MMIO_HOST_FEATURE0 +\n\t\t\t\tvalue * sizeof(uint32_t));\n\t\tiowrite32(tmp, iomem + VIRTIO_MMIO_HOST_FEATURES);\n\t\tbreak;\n\tcase VIRTIO_MMIO_GUEST_FEATURES_SEL:\n\t\tiowrite32(value, iomem + VIRTIO_MMIO_GUEST_FEATURES_SEL);\n\t\tbreak;\n\tcase VIRTIO_MMIO_GUEST_FEATURES:\n\t\ttmp = ioread32(iomem + VIRTIO_MMIO_GUEST_FEATURES_SEL);\n\t\ttmp = tmp * sizeof(uint32_t) + VIRTIO_MMIO_DRIVER_FEATURE0;\n\t\tiowrite32(value, iomem + tmp);\n\t\tbreak;\n\tcase VIRTIO_MMIO_GUEST_PAGE_SIZE:\n\t\t/* version 1 virtio device */\n\t\tiowrite32(value, iomem + VIRTIO_MMIO_GUEST_PAGE_SIZE);\n\t\tbreak;\n\tcase VIRTIO_MMIO_QUEUE_SEL:\n\t\tiowrite32(value, iomem + VIRTIO_MMIO_QUEUE_SEL);\n\n\t\t/* clear the queue information in the memory */\n\t\tiowrite32(0, iomem + VIRTIO_MMIO_QUEUE_READY);\n\t\tiowrite32(0, iomem + VIRTIO_MMIO_QUEUE_NUM);\n\t\tiowrite32(0, iomem + VIRTIO_MMIO_QUEUE_DESC_LOW);\n\t\tiowrite32(0, iomem + VIRTIO_MMIO_QUEUE_DESC_HIGH);\n\t\tiowrite32(0, iomem + VIRTIO_MMIO_QUEUE_AVAIL_LOW);\n\t\tiowrite32(0, iomem + VIRTIO_MMIO_QUEUE_AVAIL_HIGH);\n\t\tiowrite32(0, iomem + VIRTIO_MMIO_QUEUE_USED_LOW);\n\t\tiowrite32(0, iomem + VIRTIO_MMIO_QUEUE_USED_HIGH);\n\t\tbreak;\n\tcase VIRTIO_MMIO_QUEUE_NUM:\n\t\ttmp = ioread32(iomem + VIRTIO_MMIO_QUEUE_NUM_MAX);\n\t\tif (value > tmp)\n\t\t\tpr_warn(\"invalid queue sel %d\\n\", value);\n\t\tiowrite32(value, iomem + VIRTIO_MMIO_QUEUE_NUM);\n\t\tbreak;\n\tcase VIRTIO_MMIO_QUEUE_ALIGN:\n\t\tiowrite32(value, iomem + VIRTIO_MMIO_QUEUE_ALIGN);\n\t\tbreak;\n\tcase VIRTIO_MMIO_QUEUE_PFN:\n\t\t/* this is for version 1 virtio device */\n\t\tiowrite32(value, iomem + VIRTIO_MMIO_QUEUE_PFN);\n\t\tbreak;\n\tcase VIRTIO_MMIO_QUEUE_NOTIFY:\n\t\t/*\n\t\t * indicate a queue is ready, need send a\n\t\t * event to hvm ?\n\t\t */\n\t\ttrap_mmio_write_nonblock(address, write_value);\n\t\tbreak;\n\tcase VIRTIO_MMIO_STATUS:\n\t\ttmp = ioread32(iomem + VIRTIO_MMIO_STATUS);\n\t\tvalue = value - tmp;\n\t\t*write_value = value;\n\t\tiowrite32(value, iomem + VIRTIO_MMIO_STATUS);\n\t\ttrap_mmio_write(address, write_value);\n\t\tbreak;\n\tcase VIRTIO_MMIO_QUEUE_DESC_LOW:\n\t\tiowrite32(value, iomem + VIRTIO_MMIO_QUEUE_DESC_LOW);\n\t\tbreak;\n\tcase VIRTIO_MMIO_QUEUE_AVAIL_LOW:\n\t\tiowrite32(value, iomem + VIRTIO_MMIO_QUEUE_AVAIL_LOW);\n\t\tbreak;\n\tcase VIRTIO_MMIO_QUEUE_USED_LOW:\n\t\tiowrite32(value, iomem + VIRTIO_MMIO_QUEUE_USED_LOW);\n\t\tbreak;\n\tcase VIRTIO_MMIO_QUEUE_DESC_HIGH:\n\t\tiowrite32(value, iomem + VIRTIO_MMIO_QUEUE_DESC_HIGH);\n\t\tbreak;\n\tcase VIRTIO_MMIO_QUEUE_USED_HIGH:\n\t\tiowrite32(value, iomem + VIRTIO_MMIO_QUEUE_USED_HIGH);\n\t\tbreak;\n\tcase VIRTIO_MMIO_QUEUE_AVAIL_HIGH:\n\t\tiowrite32(value, iomem + VIRTIO_MMIO_QUEUE_AVAIL_HIGH);\n\t\tbreak;\n\tcase VIRTIO_MMIO_QUEUE_READY:\n\t\tvalue = ioread32(iomem + VIRTIO_MMIO_QUEUE_SEL);\n\t\t*write_value = value;\n\t\ttrap_mmio_write(address, write_value);\n\t\tbreak;\n\tcase VIRTIO_MMIO_INTERRUPT_ACK:\n\t\tiowrite32(0, iomem + VIRTIO_MMIO_INTERRUPT_ACK);\n\t\tiowrite32(0, iomem + VIRTIO_MMIO_INTERRUPT_STATUS);\n\t\tbreak;\n\tdefault:\n\t\ttrap_mmio_write(address, write_value);\n\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\nvoid release_virtio_dev(struct vm *vm, struct virtio_device *dev)\n{\n\tif (!dev)\n\t\treturn;\n\n\tvdev_release(&dev->vdev);\n\tfree(dev);\n}\n\nstatic void virtio_dev_deinit(struct vdev *vdev)\n{\n\tstruct virtio_device *dev = vdev_to_virtio(vdev);\n\n\trelease_virtio_dev(vdev->vm, dev);\n}\n\nstatic void virtio_dev_reset(struct vdev *vdev)\n{\n\tpr_notice(\"virtio device reset\\n\");\n}\n\nstatic void *virtio_create_device(struct vm *vm, struct device_node *node)\n{\n\tint ret;\n\tuint32_t irq;\n\tstruct vdev *vdev;\n\tunsigned long base, size;\n\tunsigned long flags;\n\tstruct virtio_device *virtio_dev = NULL;\n\n\tpr_notice(\"create virtio-mmio device for vm-%d\\n\", vm->vmid);\n\n\tret = translate_device_address(node, &base, &size);\n\tif (ret || (size == 0))\n\t\treturn NULL;\n\n\tret = vm_get_device_irq_index(vm, node, &irq, &flags, 0);\n\tif (ret)\n\t\treturn NULL;\n\n\tvirtio_dev = zalloc(sizeof(struct virtio_device));\n\tif (!virtio_dev)\n\t\treturn NULL;\n\n\tvdev = &virtio_dev->vdev;\n\thost_vdev_init(vm, vdev, \"virtio-mmio\");\n\tret = vdev_add_iomem_range(vdev, base, VIRTIO_DEVICE_IOMEM_SIZE);\n\tif (ret)\n\t\tgoto out;\n\n\trequest_virq(vm, irq, 0);\n\n\t/* set up the iomem base of the vdev */\n\tret = translate_guest_ipa(&vm->mm, base,\n\t\t\t(unsigned long *)&virtio_dev->iomem);\n\tif (ret) {\n\t\tpr_err(\"get iomem for virtio_device failed\\n\");\n\t\trelease_virtio_dev(vm, virtio_dev);\n\t\treturn NULL;\n\t}\n\n\tvdev->read = virtio_mmio_read;\n\tvdev->write = virtio_mmio_write;\n\tvdev->deinit = virtio_dev_deinit;\n\tvdev->reset = virtio_dev_reset;\n\tvdev_add(vdev);\n\n\treturn vdev;\n\nout:\n\trelease_virtio_dev(vm, virtio_dev);\n\treturn NULL;\n}\nVDEV_DECLARE(virtio_mmio, virtio_match_table, virtio_create_device);\n\nint virtio_mmio_init(struct vm *vm, unsigned long gbase,\n\t\tsize_t size, unsigned long *hbase)\n{\n\tvoid *iomem = NULL;\n\tunsigned long hva;\n\n\tif (size == 0) {\n\t\tpr_err(\"invaild virtio mmio size\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\tsize = PAGE_BALIGN(size);\n\tiomem = alloc_shmem(PAGE_NR(size));\n\tif (!iomem)\n\t\treturn -ENOMEM;\n\n\tmemset(iomem, 0, size);\n\n\thva = create_hvm_shmem_map(vm, (unsigned long)iomem, size);\n\tif (hva == BAD_ADDRESS) {\n\t\tfree_shmem(iomem);\n\t\treturn -ENOMEM;\n\t}\n\n\t/*\n\t * virtio's io memory need to mapped to host vm mem space\n\t * then the backend driver can read/write the io memory\n\t * by the way, this memory also need to mapped to the\n\t * guest vm 's memory space\n\t */\n\tif (create_guest_mapping(&vm->mm, gbase, (unsigned long)iomem,\n\t\t\t\tsize, VM_IO | VM_RO)) {\n\t\tfree_shmem(iomem);\n\t\treturn -ENOMEM;\n\t}\n\n\t*hbase = hva;\n\treturn 0;\n}\n"
  },
  {
    "path": "kernel/virt/vm.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/sched.h>\n#include <minos/irq.h>\n#include <config/config.h>\n#include <minos/mm.h>\n#include <minos/bitmap.h>\n#include <virt/os.h>\n#include <virt/vm.h>\n#include <virt/vmodule.h>\n#include <virt/virq.h>\n#include <virt/vmm.h>\n#include <virt/vdev.h>\n#include <virt/vmcs.h>\n#include <minos/task.h>\n#include <minos/pm.h>\n#include <minos/of.h>\n#include <virt/resource.h>\n#include <generic/gvm.h>\n#include <virt/vmbox.h>\n#include <minos/shell_command.h>\n#include <virt/virt.h>\n#include <minos/ramdisk.h>\n#include <virt/iommu.h>\n#include <asm/cache.h>\n\nstatic struct vm *host_vm;\n\nstruct vm *vms[CONFIG_MAX_VM];\nint total_vms = 0;\nLIST_HEAD(vm_list);\n\nstatic DEFINE_SPIN_LOCK(vms_lock);\nstatic DECLARE_BITMAP(vmid_bitmap, CONFIG_MAX_VM);\n\nstatic int aff_current;\nstatic int native_vcpus;\nDECLARE_BITMAP(vcpu_aff_bitmap, NR_CPUS);\nDEFINE_SPIN_LOCK(affinity_lock);\n\n#define VM_NR_CPUS_CLUSTER 256\n\nstatic inline int vcpu_is_offline(struct vcpu *vcpu)\n{\n\treturn check_vcpu_state(vcpu, VCPU_STATE_SUSPEND);\n}\n\nstatic void vcpu_online(struct vcpu *vcpu)\n{\n\tASSERT(vcpu_is_offline(vcpu));\n\ttask_ready(vcpu->task, 0);\n}\n\nstatic int inline affinity_to_vcpuid(struct vm *vm, unsigned long affinity)\n{\n\tint aff0, aff1;\n\n\t/*\n\t * how to handle big-little soc ? usually the hvm's\n\t * cpu map is as same as the true hardware, so here\n\t * if the VM is the VM0, the affinity is as same as\n\t * the real hardware.\n\t *\n\t * Can be different with real hardware ? TBD.\n\t */\n\tif (vm_is_host_vm(vm))\n\t\treturn affinity_to_cpuid(affinity);\n\n\taff1 = (affinity >> 8) & 0xff;\n\taff0 = affinity & 0xff;\n\n\treturn (aff1 * VM_NR_CPUS_CLUSTER) + aff0;\n}\n\nint vcpu_power_on(struct vcpu *caller, unsigned long affinity,\n\t\tunsigned long entry, unsigned long unsed)\n{\n\tint cpuid;\n\tstruct vcpu *vcpu;\n\n\tcpuid = affinity_to_vcpuid(caller->vm, affinity);\n\n\tvcpu = get_vcpu_in_vm(caller->vm, cpuid);\n\tif (!vcpu) {\n\t\tpr_err(\"no such:%d->0x%x vcpu for this VM %s\\n\",\n\t\t\t\tcpuid, affinity, caller->vm->name);\n\t\treturn -ENOENT;\n\t}\n\n\tif (vcpu_is_offline(vcpu)) {\n\t\tpr_notice(\"vcpu-%d of vm-%d power on 0x%p\\n\",\n\t\t\t\tvcpu->vcpu_id, vcpu->vm->vmid, entry);\n\t\tos_vcpu_power_on(vcpu, ULONG(entry));\n\t\tvcpu_online(vcpu);\n\t} else {\n\t\tpr_err(\"vcpu_power_on : invalid vcpu state %d\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\treturn 0;\n}\n\nvoid vcpu_context_save(struct task *task)\n{\n\tsave_vcpu_vmodule_state(task_to_vcpu(task));\n}\n\nvoid vcpu_context_restore(struct task *task)\n{\n\trestore_vcpu_vmodule_state(task_to_vcpu(task));\n}\n\nstatic int vcpu_can_idle(struct vcpu *vcpu)\n{\n\tif (vcpu->vm->state != VM_STATE_ONLINE)\n\t\treturn 0;\n\n\tif (is_task_need_stop(vcpu->task))\n\t\treturn 0;\n\n\tif (vcpu_has_irq(vcpu))\n\t\treturn 0;\n\n\treturn 1;\n}\n\nint vcpu_idle(struct vcpu *vcpu)\n{\n\treturn wait_event(&vcpu->vcpu_event, vcpu_can_idle(vcpu), 0);\n}\n\nint vcpu_suspend(struct vcpu *vcpu, gp_regs *c,\n\t\tuint32_t state, unsigned long entry)\n{\n\t/*\n\t * just call vcpu idle to put vcpu to suspend state\n\t * and ignore the wake up entry, since the vcpu will\n\t * not really powered off\n\t */\n\treturn vcpu_idle(vcpu);\n}\n\nint vcpu_off(struct vcpu *vcpu)\n{\n\ttask_need_freeze(vcpu->task);\n\treturn 0;\n}\n\nstatic int vm_check_vcpu_affinity(int vmid, uint32_t *aff, int nr)\n{\n\tint i;\n\tuint64_t mask = 0;\n\n\tfor (i = 0; i < nr; i++) {\n\t\tif (aff[i] >= VM_MAX_VCPU)\n\t\t\treturn -EINVAL;\n\n\t\tif (mask & (1 << aff[i]))\n\t\t\treturn -EINVAL;\n\t\telse\n\t\t\tmask |= (1 << aff[i]);\n\t}\n\n\treturn 0;\n}\n\nstruct vcpu *get_vcpu_in_vm(struct vm *vm, uint32_t vcpu_id)\n{\n\tif (vcpu_id >= vm->vcpu_nr)\n\t\treturn NULL;\n\n\treturn vm->vcpus[vcpu_id];\n}\n\nstruct vcpu *get_vcpu_by_id(uint32_t vmid, uint32_t vcpu_id)\n{\n\tstruct vm *vm;\n\n\tvm = get_vm_by_id(vmid);\n\tif (!vm)\n\t\treturn NULL;\n\n\treturn get_vcpu_in_vm(vm, vcpu_id);\n}\n\nint kick_vcpu(struct vcpu *vcpu, int reason)\n{\n\tint mode, ret = 0;\n\n\t/*\n\t * 1 - whether need to wake up the task.\n\t * 2 - whether need to send a resched irq.\n\t *\n\t * if the vcpu is in stop state, only the BootCPU\n\t * can wake up it. this will be another path.\n\t */\n\tret = wake(&vcpu->vcpu_event);\n\n\t/*\n\t * 0   - wakeup successfuly\n\t * 1   - do not need wake up task\n\t * < 0 - wake up failed\n\t * if on the same cpu, just call cond_resched to\n\t * see whether need preempt this task.\n\t */\n\tif (smp_processor_id() == vcpu_affinity(vcpu))\n\t\treturn ret;\n\n\t/*\n\t * ret < 0 means the task do not need to wake up and in ready state.\n\t * if task is in ready state, or the task is running in guest mode\n\t * then need send a physical irq to the target irq.\n\t *\n\t * if the virq is not hardware virq, when the native\n\t * wfi is enabled for the target vcpu, the target vcpu\n\t * may not receive the virq immediately, and may wait\n\t * last physical irq come, then this pcpu can wakeup\n\t * from the WFI mode, so here need to send a phyical\n\t * irq to the target pcpu. Native WFI VCPU will always\n\t * in running mode in EL1.\n\t */\n\tmode = vcpu->mode;\n\tsmp_rmb();\n\n\tif ((ret < 0) && (mode != IN_ROOT_MODE))\n\t\tpcpu_resched(vcpu_affinity(vcpu));\n\telse if ((ret < 0) && (vcpu->vm->flags & VM_FLAGS_NATIVE_WFI))\n\t\tpcpu_resched(vcpu_affinity(vcpu));\n\n\treturn ret;\n}\n\nstatic void inline release_vcpu(struct vcpu *vcpu)\n{\n\t/*\n\t * need to make sure that when free the memory resource\n\t * can not be done in the interrupt context, so the\n\t * destroy a task will done in the idle task, here\n\t * just call vmodule_stop call back, then set the\n\t * task to the stop list of the pcpu, when the idle\n\t * task is run, the idle task will release this task\n\t */\n\tif (vcpu->context)\n\t\tstop_vcpu_vmodule_state(vcpu);\n\n\tif (vcpu->task)\n\t\tdo_release_task(vcpu->task);\n\n\tif (vcpu->vmcs_irq >= 0)\n\t\trelease_hvm_virq(vcpu->vmcs_irq);\n\n\tif (vcpu->virq_struct)\n\t\tfree(vcpu->virq_struct);\n\n\tfree(vcpu);\n}\n\nstatic struct vcpu *alloc_vcpu(void)\n{\n\tstruct vcpu *vcpu;\n\n\tvcpu = zalloc(sizeof(*vcpu));\n\tif (!vcpu)\n\t\treturn NULL;\n\n\tvcpu->virq_struct = zalloc(sizeof(struct virq_struct));\n\tif (!vcpu->virq_struct)\n\t\tgoto free_vcpu;\n\n\tvcpu->vmcs_irq = -1;\n\treturn vcpu;\n\nfree_vcpu:\n\tfree(vcpu);\n\n\treturn NULL;\n}\n\nstatic void vcpu_return_to_user(struct task *task, gp_regs *regs)\n{\n\tstruct vcpu *vcpu = (struct vcpu *)task->pdata;\n\n\tvcpu->mode = OUTSIDE_ROOT_MODE;\n\tsmp_wmb();\n\n\tdo_hooks(vcpu, (void *)regs, OS_HOOK_ENTER_TO_GUEST);\n\n\tsmp_wmb();\n\tvcpu->mode = IN_GUEST_MODE;\n}\n\nstatic void vcpu_exit_from_user(struct task *task, gp_regs *regs)\n{\n\tstruct vcpu *vcpu = (struct vcpu *)task->pdata;\n\n\tvcpu->mode = OUTSIDE_GUEST_MODE;\n\tsmp_wmb();\n\n\tdo_hooks(vcpu, (void *)regs, OS_HOOK_EXIT_FROM_GUEST);\n\n\tsmp_wmb();\n\tvcpu->mode = IN_ROOT_MODE;\n}\n\nstatic struct vcpu *create_vcpu(struct vm *vm, uint32_t vcpu_id)\n{\n\tchar name[64];\n\tstruct vcpu *vcpu;\n\tstruct task *task;\n\n\t/* generate the name of the vcpu task */\n\tmemset(name, 0, 64);\n\tsprintf(name, \"%s-vcpu-%d\", vm->name, vcpu_id);\n\ttask = create_vcpu_task(name, vm->entry_point,\n\t\t\tvm->vcpu_affinity[vcpu_id], 0, NULL);\n\tif (task == NULL)\n\t\treturn NULL;\n\n\ttask->return_to_user = vcpu_return_to_user;\n\ttask->exit_from_user = vcpu_exit_from_user;\n\n\tvcpu = alloc_vcpu();\n\tif (!vcpu) {\n\t\tdo_release_task(task);\n\t\treturn NULL;\n\t}\n\n\ttask->pdata = vcpu;\n\tvcpu->task = task;\n\tvcpu->vcpu_id = vcpu_id;\n\tvcpu->vm = vm;\n\tvcpu->mode = IN_ROOT_MODE;\n\n\tif (vm->flags & VM_FLAGS_32BIT)\n\t\ttask->flags |= TASK_FLAGS_32BIT;\n\n\tvcpu_virq_struct_init(vcpu);\n\tvm->vcpus[vcpu_id] = vcpu;\n\tevent_init(&vcpu->vcpu_event, OS_EVENT_TYPE_NORMAL, task);\n\n\tvcpu->next = NULL;\n\tif (vcpu_id != 0)\n\t\tvm->vcpus[vcpu_id - 1]->next = vcpu;\n\n\treturn vcpu;\n}\n\nstatic int alloc_new_vmid(void)\n{\n\tint vmid, start = total_vms;\n\n\tspin_lock(&vms_lock);\n\tvmid = find_next_zero_bit_loop(vmid_bitmap, CONFIG_MAX_VM, start);\n\tif (vmid >= CONFIG_MAX_VM) {\n\t\tvmid = 0;\n\t\tgoto out;\n\t}\n\n\tset_bit(vmid, vmid_bitmap);\nout:\n\tspin_unlock(&vms_lock);\n\n\treturn vmid;\n}\n\nstatic int vcpu_affinity_init(void)\n{\n\tint i;\n\tstruct vm *vm;\n\n\tbitmap_clear(vcpu_aff_bitmap, 0, NR_CPUS);\n\n\tfor_each_vm(vm) {\n\t\tfor (i = 0; i < vm->vcpu_nr; i++)\n\t\t\tset_bit(vm->vcpu_affinity[i], vcpu_aff_bitmap);\n\t}\n\n\taff_current = find_first_zero_bit(vcpu_aff_bitmap, NR_CPUS);\n\tif (aff_current >= NR_CPUS)\n\t\taff_current = (NR_CPUS - 1);\n\n\tfor (i = 0; i < NR_CPUS; i++) {\n\t\tif (test_bit(i, vcpu_aff_bitmap))\n\t\t\tnative_vcpus++;\n\t}\n\n\treturn 0;\n}\n\nvoid get_vcpu_affinity(uint32_t *aff, int nr)\n{\n\tint i = 0;\n\tint vm0_vcpu0_ok = 0;\n\tint vm0_vcpus_ok = 0;\n\tstruct vm *vm0 = get_host_vm();\n\tint vm0_vcpu0 = vm0->vcpu_affinity[0];\n\n\tif (nr == NR_CPUS)\n\t\tvm0_vcpu0_ok = 1;\n\telse if (nr > (NR_CPUS - native_vcpus))\n\t\tvm0_vcpus_ok = 1;\n\n\tspin_lock(&affinity_lock);\n\n\tdo {\n\t\tif (!test_bit(aff_current, vcpu_aff_bitmap)) {\n\t\t\taff[i] = aff_current;\n\t\t\ti++;\n\t\t} else {\n\t\t\tif ((aff_current == vm0_vcpu0) && vm0_vcpu0_ok) {\n\t\t\t\taff[i] = aff_current;\n\t\t\t\ti++;\n\t\t\t} else if ((aff_current != vm0_vcpu0) && vm0_vcpus_ok) {\n\t\t\t\taff[i] = aff_current;\n\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\n\t\tif (++aff_current >= NR_CPUS)\n\t\t\taff_current = 0;\n\t} while (i < nr);\n\n\tspin_unlock(&affinity_lock);\n}\n\nstatic int vmtag_check_and_config(struct vmtag *tag)\n{\n\tsize_t size;\n\n\t/*\n\t * first check whether there are enough memory for\n\t * this vm and the vm's memory base need to be start\n\t * at 0x80000000 or higher, if the mem_base is 0,\n\t * then set it to default 0x80000000\n\t */\n\tsize = tag->mem_size;\n\tif (tag->mem_base == 0)\n\t\ttag->mem_base = GVM_NORMAL_MEM_START;\n\n\tif (!vmm_has_enough_memory(size)) {\n\t\tpr_err(\"no enough memory for guest\\n\");\n\t\treturn -ENOMEM;\n\t}\n\n\tif (tag->nr_vcpu > NR_CPUS) {\n\t\tpr_err(\"to much vcpus for guest\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\t/* for the dynamic need to get the affinity dynamicly */\n\tif (tag->flags & VM_FLAGS_DYNAMIC_AFF) {\n\t\tmemset(tag->vcpu_affinity, 0, sizeof(tag->vcpu_affinity));\n\t\tget_vcpu_affinity(tag->vcpu_affinity, tag->nr_vcpu);\n\t}\n\n\treturn 0;\n}\n\nint request_vm_virqs(struct vm *vm, int base, int nr)\n{\n\tif (!vm || (base < GVM_IRQ_BASE) || (nr <= 0) ||\n\t\t\t(base + nr >= GVM_IRQ_END))\n\t\treturn -EINVAL;\n\n\twhile (nr > 0) {\n\t\tif (request_virq(vm, base, 0)) {\n\t\t\tpr_err(\"request virq %d in GVM %s failed\\n\",\n\t\t\t\t\tbase, vm->name);\n\t\t\treturn -ENOENT;\n\t\t}\n\t\tbase++;\n\t\tnr--;\n\t}\n\n\treturn 0;\n}\n\nstatic int load_vm_image(struct vm *vm)\n{\n\tvoid *addr = (void *)ptov(vm->load_address);\n\tsize_t size;\n\tint ret;\n\n\tif (!vm->kernel_file)\n\t\treturn 0;\n\n\tpr_notice(\"copying %s to 0x%x\\n\", ramdisk_file_name(vm->kernel_file),\n\t\t\tvm->load_address);\n\n\tsize = ramdisk_file_size(vm->kernel_file);\n\tret = create_host_mapping(ULONG(addr), ULONG(vm->load_address),\n\t\t\tPAGE_BALIGN(size), VM_NORMAL | VM_HUGE);\n\tASSERT(ret == 0);\n\n\tret = ramdisk_read(vm->kernel_file, addr, size, 0);\n\tASSERT(ret == 0);\n\n\tflush_dcache_range(ULONG(addr), PAGE_BALIGN(size));\n\tdestroy_host_mapping(ULONG(addr), PAGE_BALIGN(size));\n\n\treturn 0;\n}\n\nstatic int do_start_vm(struct vm *vm)\n{\n\tstruct vcpu *vcpu0;\n\n\tvcpu0 = vm->vcpus[0];\n\tif (!vcpu0) {\n\t\tpr_err(\"VM create with error, vm%d not exist\\n\", vm->vmid);\n\t\treturn -ENOENT;\n\t}\n\n\t/*\n\t * flush all the tlb for this vm.\n\t */\n\tflush_all_tlb_mm(&vm->mm);\n\n\tvcpu_online(vcpu0);\n\n\treturn 0;\n}\n\nint start_guest_vm(struct vm *vm)\n{\n\tint state;\n\n\tif (!vm) {\n\t\tpr_err(\"no such guest vm\\n\");\n\t\treturn -ENOENT;\n\t}\n\n\tstate = cmpxchg(&vm->state, VM_STATE_OFFLINE,\n\t\t\tVM_STATE_ONLINE);\n\tif (state != VM_STATE_OFFLINE) {\n\t\tpr_err(\"VM %s already stared\\n\", vm->name);\n\t\treturn -EINVAL;\n\t}\n\n\tvm_vcpus_init(vm);\n\n\t/*\n\t * start the vm now\n\t */\n\treturn do_start_vm(vm);\n}\n\nstatic int guest_mm_init(struct vm *vm, uint64_t base, uint64_t size)\n{\n\tif (split_vmm_area(&vm->mm, base, size, VM_GUEST_NORMAL) == NULL) {\n\t\tpr_err(\"invalid memory config for guest VM\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\tif (alloc_vm_memory(vm)) {\n\t\tpr_err(\"allocate memory for vm-%d failed\\n\", vm->vmid);\n\t\treturn -ENOMEM;\n\t}\n\n\treturn 0;\n}\n\nint create_vm_mmap(int vmid,  unsigned long offset,\n\t\tunsigned long size, unsigned long *addr)\n{\n\tstruct vm *vm = get_vm_by_id(vmid);\n\tstruct vmm_area *va;\n\n\tva = vm_mmap(vm, offset, size);\n\tif (va) {\n\t\t*addr = va->start;\n\t\treturn 0;\n\t}\n\n\treturn -EINVAL;\n}\n\nint create_guest_vm(struct vmtag __guest *tag)\n{\n\tint ret = 0;\n\tstruct vm *vm;\n\tstruct vmtag vmtag;\n\n\tmemset(&vmtag, 0, sizeof(struct vmtag));\n\tret = copy_from_guest(&vmtag, tag, sizeof(struct vmtag));\n\tif (ret != 0) {\n\t\tpr_err(\"copy vmtag from guest failed\\n\");\n\t\treturn -EFAULT;\n\t}\n\n\tret = vmtag_check_and_config(&vmtag);\n\tif (ret)\n\t\treturn ret;\n\n\tvmtag.vmid = 0;\n\tvmtag.flags |= VM_FLAGS_CAN_RESET;\n\tvm = create_vm(&vmtag, NULL);\n\tif (!vm)\n\t\treturn -ENOMEM;\n\n\tret = guest_mm_init(vm, vmtag.mem_base, vmtag.mem_size);\n\tif (ret) {\n\t\tdestroy_vm(vm);\n\t\treturn ret;\n\t}\n\n\treturn vm->vmid;\n}\n\nstatic int create_vm_resource(struct vm *vm)\n{\n\tint ret;\n\n\t/*\n\t * do not need to create the resource again, when reboot\n\t * or shutdown.\n\t */\n\tif (test_and_set_bit(VM_FLAGS_BIT_SKIP_CREATE_RES, &vm->flags))\n\t\treturn 0;\n\n\tif (vm_is_native(vm)) {\n\t\tret = os_create_native_vm_resource(vm);\n\t\tif (ret)\n\t\t\treturn ret;\n\t\tret = create_vmbox_controller(vm);\n\t} else {\n\t\tret = os_create_guest_vm_resource(vm);\n\t}\n\n\treturn ret;\n}\n\nstatic void __setup_native_vm(struct vm *vm)\n{\n\tvoid *setup_addr = (void *)ptov(vm->setup_data);\n\tsize_t size;\n\tint ret;\n\n\t/*\n\t * first load the setup data from the ramdisk if needed.\n\t * the setup data ususally is device tree on ARM, need\n\t * map the memory into hypervisor's space. The memory\n\t * of setup data can not beyond 2M.\n\t */\n\tif (vm->dtb_file) {\n\t\tpr_notice(\"copying %s to 0x%x\\n\", ramdisk_file_name(vm->dtb_file),\n\t\t\t\tvm->setup_data);\n\t\tsize = ramdisk_file_size(vm->dtb_file);\n\t\tret = create_host_mapping(ULONG(setup_addr), ULONG(vm->setup_data),\n\t\t\t\tMAX_DTB_SIZE, VM_NORMAL | VM_HUGE);\n\t\tASSERT(ret == 0);\n\n\t\tret = ramdisk_read(vm->dtb_file, setup_addr, size, 0);\n\t\tASSERT(ret == 0);\n\t} else {\n\t\tret = create_host_mapping(ULONG(setup_addr), ULONG(vm->setup_data),\n\t\t\t\tMAX_DTB_SIZE, VM_NORMAL | VM_HUGE);\n\t\tASSERT(ret == 0);\n\t}\n\n\t/*\n\t * here need to create the resource based on the vm's\n\t * os, when the os is a linux system, usually it will\n\t * used device tree, if the os is rtos, need to write\n\t * the iomem and virqs in the hypervisor's device tree\n\t *\n\t * here to check whether there are information in the\n\t * hypervisor's dts, if not then try to parsing the dtb\n\t * of the VM\n\t *\n\t * first map the dtb address to the hypervisor, here\n\t * map these native VM's memory as read only\n\t *\n\t * just do these step only when the VM has not been\n\t * online.\n\t */\n\tcreate_vm_resource(vm);\n\n\tos_setup_vm(vm);\n\tdo_hooks(vm, NULL, OS_HOOK_SETUP_VM);\n\n\t/*\n\t * the DTB content may modified, get the final size, and\n\t * then flush the cache and unmap the memory.\n\t */\n\tsize = fdt_totalsize(setup_addr);\n\tflush_dcache_range(ULONG(setup_addr), PAGE_BALIGN(size));\n\tdestroy_host_mapping(ULONG(setup_addr), MAX_DTB_SIZE);\n}\n\nvoid destroy_vm(struct vm *vm)\n{\n\tint i;\n\tunsigned long flags;\n\tstruct vdev *vdev, *n;\n\tstruct vcpu *vcpu;\n\n\tif (!vm)\n\t\treturn;\n\n\tif (vm_is_native(vm))\n\t\tpanic(\"can not destory native VM\\n\");\n\n\t/*\n\t * 1 : release the vdev\n\t * 2 : do hooks for each modules\n\t * 3 : release the vcpu allocated to this vm\n\t * 4 : free the memory for this VM\n\t * 5 : update the vmid bitmap\n\t * 6 : do vmodule deinit\n\t */\n\tlist_for_each_entry_safe(vdev, n, &vm->vdev_list, list) {\n\t\tlist_del(&vdev->list);\n\t\tif (vdev->deinit)\n\t\t\tvdev->deinit(vdev);\n\t}\n\n\tdo_hooks((void *)vm, NULL, OS_HOOK_DESTROY_VM);\n\n\tif (vm->vcpus) {\n\t\tfor (i = 0; i < vm->vcpu_nr; i++) {\n\t\t\tvcpu = vm->vcpus[i];\n\t\t\tif (!vcpu)\n\t\t\t\tcontinue;\n\t\t\trelease_vcpu(vcpu);\n\t\t}\n\n\t\tfree(vm->vcpus);\n\t}\n\n\trelease_vm_memory(vm);\n\n\ti = vm->vmid;\n\tspin_lock_irqsave(&vms_lock, flags);\n\tclear_bit(i, vmid_bitmap);\n\tlist_del(&vm->vm_list);\n\tvms[i] = NULL;\n\ttotal_vms--;\n\tspin_unlock_irqrestore(&vms_lock, flags);\n\n\tfree(vm);\n}\n\nint vm_vcpus_init(struct vm *vm)\n{\n\tstruct vcpu *vcpu;\n\n\tvm_for_each_vcpu(vm, vcpu) {\n\t\tpr_notice(\"vm-%d vcpu-%d affnity to pcpu-%d\\n\",\n\t\t\t\tvm->vmid, vcpu->vcpu_id,\n\t\t\t\tvcpu_affinity(vcpu));\n\t\t/*\n\t\t * init the vcpu context here.\n\t\t */\n\t\tvcpu_vmodules_init(vcpu);\n\n\t\tif (!vm_is_native(vm)) {\n\t\t\tvcpu->vmcs->host_index = 0;\n\t\t\tvcpu->vmcs->guest_index = 0;\n\t\t}\n\t}\n\n\tvm_for_each_vcpu(vm, vcpu) {\n\t\tdo_hooks(vcpu, NULL, OS_HOOK_VCPU_INIT);\n\t\tos_vcpu_power_on(vcpu, (unsigned long)vm->entry_point);\n\t}\n\n\treturn 0;\n}\n\nstatic int create_vcpus(struct vm *vm)\n{\n\tint i, j;\n\tstruct vcpu *vcpu;\n\n\tfor (i = 0; i < vm->vcpu_nr; i++) {\n\t\tvcpu = create_vcpu(vm, i);\n\t\tif (!vcpu) {\n\t\t\tpr_err(\"create vcpu:%d for %s failed\\n\", i, vm->name);\n\t\t\tfor (j = 0; j < vm->vcpu_nr; j++) {\n\t\t\t\tvcpu = vm->vcpus[j];\n\t\t\t\tif (!vcpu)\n\t\t\t\t\tcontinue;\n\t\t\t\trelease_vcpu(vcpu);\n\t\t\t}\n\n\t\t\treturn -ENOMEM;\n\t\t}\n\t}\n\n\treturn 0;\n}\n\nstatic void vm_open_ramdisk_file(struct vm *vm, struct vmtag *vme)\n{\n\tif (!vm_is_native(vm))\n\t\treturn;\n\n\tif (vme->kernel_file) {\n\t\tvm->kernel_file = malloc(sizeof(struct ramdisk_file));\n\t\tASSERT(vm->kernel_file != NULL);\n\t\tASSERT(ramdisk_open(vme->kernel_file, vm->kernel_file) == 0);\n\t}\n\n\tif (vme->dtb_file) {\n\t\tvm->dtb_file = malloc(sizeof(struct ramdisk_file));\n\t\tASSERT(vm->dtb_file != NULL);\n\t\tASSERT(ramdisk_open(vme->dtb_file, vm->dtb_file) == 0);\n\t}\n\t\t\n\tif (vme->initrd_file) {\n\t\tvm->initrd_file = malloc(sizeof(struct ramdisk_file));\n\t\tASSERT(vm->initrd_file != NULL);\n\t\tASSERT(ramdisk_open(vme->initrd_file, vm->initrd_file) == 0);\n\t}\n}\n\nstatic struct vm *__create_vm(struct vmtag *vme)\n{\n\tstruct vm *vm;\n\n\tif (vm_check_vcpu_affinity(vme->vmid, vme->vcpu_affinity,\n\t\t\t\tvme->nr_vcpu)) {\n\t\tpr_err(\"vcpu affinity for vm not correct\\n\");\n\t\treturn NULL;\n\t}\n\n\tvm = malloc(sizeof(*vm));\n\tif (!vm)\n\t\treturn NULL;\n\n\tvme->nr_vcpu = MIN(vme->nr_vcpu, VM_MAX_VCPU);\n\tmemset(vm, 0, sizeof(struct vm));\n\tvm->vcpus = malloc(sizeof(struct vcpu *) * vme->nr_vcpu);\n\tif (!vm->vcpus) {\n\t\tfree(vm);\n\t\treturn NULL;\n\t}\n\n\tvm->vmid = vme->vmid;\n\tvm->flags |= vme->flags;\n\tstrncpy(vm->name, vme->name, sizeof(vm->name) - 1);\n\tvm->vcpu_nr = vme->nr_vcpu;\n\tvm->entry_point = (void *)vme->entry;\n\tvm->setup_data = (void *)vme->setup_data;\n\tvm->load_address =\n\t\t(void *)(vme->load_address ? vme->load_address : vme->entry);\n\tvm->state = VM_STATE_OFFLINE;\n\tinit_list(&vm->vdev_list);\n\tmemcpy(vm->vcpu_affinity, vme->vcpu_affinity,\n\t\t\tsizeof(uint32_t) * VM_MAX_VCPU);\n\n\t/*\n\t * open the ramdisk file if the vm need load from\n\t * the ramdisk.\n\t */\n\tvm_open_ramdisk_file(vm, vme);\n\n\tspin_lock(&vms_lock);\n\tvms[vme->vmid] = vm;\n\tlist_add_tail(&vm_list, &vm->vm_list);\n\ttotal_vms++;\n\tspin_unlock(&vms_lock);\n\n\tvm->os = get_vm_os((char *)vme->os_type);\n\n\treturn vm;\n}\n\nstruct vm *create_vm(struct vmtag *vme, struct device_node *node)\n{\n\tint ret = 0;\n\tstruct vm *vm;\n\n\tif (vme->vmid != 0)  {\n\t\tpr_notice(\"request vmid %d\\n\", vme->vmid);\n\t\tif (test_and_set_bit(vme->vmid, vmid_bitmap))\n\t\t\treturn NULL;\n\t} else {\n\t\tvme->vmid = alloc_new_vmid();\n\t\tif (vme->vmid == 0)\n\t\t\treturn NULL;\n\t}\n\n\tvm = __create_vm(vme);\n\tif (!vm)\n\t\treturn NULL;\n\n\tvm->dev_node = node;\n\n\tret = vm_mm_struct_init(vm);\n\tif (ret) {\n\t\tpr_err(\"mm struct init failed\\n\");\n\t\tgoto release_vm;\n\t}\n\n\tiommu_vm_init(vm);\n\n\tret = create_vcpus(vm);\n\tif (ret) {\n\t\tpr_err(\"create vcpus for vm failded\\n\");\n\t\tret = 0;\n\t\tgoto release_vm;\n\t}\n\n\tif ((vm->flags & VM_FLAGS_HOST)) {\n\t\tASSERT(host_vm == NULL);\n\t\thost_vm = vm;\n\t}\n\n\tif (do_hooks((void *)vm, NULL, OS_HOOK_CREATE_VM)) {\n\t\tpr_err(\"create vm failed in hook function\\n\");\n\t\tgoto release_vm;\n\t}\n\n\treturn vm;\n\nrelease_vm:\n\tdestroy_vm(vm);\n\n\treturn NULL;\n}\n\nstruct vm *get_host_vm(void)\n{\n\treturn host_vm;\n}\n\nstatic inline const char *get_vm_type(struct vm *vm)\n{\n\tif (vm->flags & VM_FLAGS_HOST)\n\t\treturn \"Host\";\n\telse if (vm->flags & VM_FLAGS_NATIVE)\n\t\treturn \"Native\";\n\telse\n\t\treturn \"Guest\";\n}\n\nstatic void *create_native_vm_of(struct device_node *node, void *arg)\n{\n\tstruct vmtag vmtag;\n\n\tif (node->class != DT_CLASS_VM)\n\t\treturn NULL;\n\n\tif (parse_vm_info_of(node, &vmtag))\n\t\treturn NULL;\n\n\tpr_notice(\"**** create new vm ****\\n\");\n\tpr_notice(\"    vmid: %d\\n\", vmtag.vmid);\n\tpr_notice(\"    name: %s\\n\", vmtag.name);\n\tpr_notice(\"    os_type: %s\\n\", vmtag.os_type);\n\tpr_notice(\"    nr_vcpu: %d\\n\", vmtag.nr_vcpu);\n\tpr_notice(\"    entry: 0x%p\\n\", vmtag.entry);\n\tpr_notice(\"    setup_data: 0x%p\\n\", vmtag.setup_data);\n\tpr_notice(\"    load-address: 0x%p\\n\", vmtag.load_address);\n\tpr_notice(\"    kernel-file: %s\\n\", vmtag.kernel_file ? vmtag.kernel_file : \"NULL\");\n\tpr_notice(\"    dtb-file: %s\\n\", vmtag.dtb_file ? vmtag.dtb_file : \"NULL\");\n\tpr_notice(\"    initrd-file: %s\\n\", vmtag.initrd_file ? vmtag.initrd_file : \"NULL\");\n\tpr_notice(\"    %s-bit vm\\n\", vmtag.flags & VM_FLAGS_32BIT ? \"32\" : \"64\");\n\tpr_notice(\"    flags: 0x%x\\n\", vmtag.flags);\n\tpr_notice(\"    affinity: %d %d %d %d %d %d %d %d\\n\",\n\t\t\tvmtag.vcpu_affinity[0], vmtag.vcpu_affinity[1],\n\t\t\tvmtag.vcpu_affinity[2], vmtag.vcpu_affinity[3],\n\t\t\tvmtag.vcpu_affinity[4], vmtag.vcpu_affinity[5],\n\t\t\tvmtag.vcpu_affinity[6], vmtag.vcpu_affinity[7]);\n\n\treturn create_vm(&vmtag, node);\n}\n\nstatic void parse_and_create_vms(void)\n{\n#ifdef CONFIG_DEVICE_TREE\n\tstruct device_node *node;\n\n\tnode = of_find_node_by_name(of_root_node, \"vms\");\n\tif (node)\n\t\tof_iterate_all_node_loop(node, create_native_vm_of, NULL);\n#endif\n}\n\nstatic int of_create_vmboxs(void)\n{\n\tstruct device_node *mailboxes;\n\tstruct device_node *child;\n\n\tmailboxes = of_find_node_by_name(of_root_node, \"vmboxs\");\n\tif (!mailboxes)\n\t\treturn -ENOENT;\n\n\t/* parse each mailbox entry and create it */\n\tof_node_for_each_child(mailboxes, child) {\n\t\tif (of_create_vmbox(child))\n\t\t\tpr_err(\"create vmbox [%s] fail\\n\", child->name);\n\t\telse\n\t\t\tpr_notice(\"create vmbox [%s] successful\\n\", child->name);\n\t}\n\n\treturn 0;\n}\n\nstatic void setup_native_vm(struct vm *vm)\n{\n\tos_vm_init(vm);\n\t__setup_native_vm(vm);\n\tload_vm_image(vm);\n\tvm_mm_init(vm);\n\tvm_vcpus_init(vm);\n}\n\nint start_native_vm(struct vm *vm)\n{\n\tint state;\n\n\tif (!vm) {\n\t\tpr_err(\"no such vm\\n\");\n\t\treturn -ENOENT;\n\t}\n\n\tstate = cmpxchg(&vm->state, VM_STATE_OFFLINE,\n\t\t\tVM_STATE_ONLINE);\n\tif (state != VM_STATE_OFFLINE) {\n\t\tpr_err(\"VM %s already stared\\n\", vm->name);\n\t\treturn -EINVAL;\n\t}\n\n\tif (!vm_is_native(vm)) {\n\t\tpr_err(\"can not start guest vm by host\\n\");\n\t\treturn -EPERM;\n\t}\n\n\tsetup_native_vm(vm);\n\n\treturn do_start_vm(vm);\n}\n\nint virt_init(void)\n{\n\textern void vmm_init(void);\n\textern void vm_daemon_init(void);\n\tstruct vm *vm;\n\n\t/*\n\t * VMID 0 is reserved\n\t */\n\tset_bit(0, vmid_bitmap);\n\tvmm_init();\n\n\tvm_daemon_init();\n\n\tparse_and_create_vms();\n\n\t/* check whether host VM has been create correctly */\n\tvm = get_host_vm();\n\tif (!vm) {\n\t\tpr_err(\"hvm has not been create correctly\\n\");\n\t\treturn -ENOENT;\n\t}\n\n\tvcpu_affinity_init();\n\n#ifdef CONFIG_DEVICE_TREE\n\t/* here create all the mailbox for all native vm */\n\tof_create_vmboxs();\n#endif\n\n\treturn 0;\n}\n\nvoid start_all_vm(void)\n{\n\tstruct vm *vm;\n\n\tlist_for_each_entry(vm, &vm_list, vm_list)\n\t\tstart_native_vm(vm);\n}\n\n/*\n * vm start 0 - start the vm which vmid is 0\n */\nstatic int vm_command_hdl(int argc, char **argv)\n{\n\tuint32_t vmid;\n\n\tif (argc > 2 && strcmp(argv[1], \"start\") == 0) {\n\t\tvmid = atoi(argv[2]);\n\t\tif (vmid == 0)\n\t\t\tstart_all_vm();\n\t\telse\n\t\t\tstart_native_vm(get_vm_by_id(vmid));\n\t}\n\n\treturn 0;\n}\nDEFINE_SHELL_COMMAND(vm, \"vm\", \"virtual machine cmd\",\n\t\tvm_command_hdl, 2);\n"
  },
  {
    "path": "kernel/virt/vm_daemon.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/sched.h>\n#include <minos/task.h>\n#include <minos/queue.h>\n#include <virt/vm.h>\n#include <virt/vdev.h>\n#include <virt/virq.h>\n#include <virt/vm_pm.h>\n\n#define VM_SIGNAL_QUEUE_SIZE 8\n\nstatic queue_t vm_request_queue;\n\n#define VM_ACTION_NULL 0x0\n#define VM_REBOOT 0x03\n#define VM_SHUTDOWN 0X4\n\nstruct vm_request {\n\tint action;\n\tstruct vm *vm;\n};\n\nstatic int send_vm_request(struct vm *vm, int req)\n{\n\tstruct vm_request *vr;;\n\n\tvr = malloc(sizeof(struct vm_request));\n\tif (!vr)\n\t\treturn -ENOMEM;\n\n\tvr->action = req;\n\tvr->vm = vm;\n\n\treturn queue_post(&vm_request_queue, vr);\n}\n\nint send_vm_shutdown_request(struct vm *vm)\n{\n\treturn send_vm_request(vm, VM_SHUTDOWN);\n}\n\nint send_vm_reboot_request(struct vm *vm)\n{\n\treturn send_vm_request(vm, VM_REBOOT);\n}\n\nstatic void handle_vm_reboot(struct vm *vm)\n{\n\treboot_native_vm(vm);\n}\n\nstatic void handle_vm_shutdown(struct vm *vm)\n{\n\tshutdown_native_vm(vm);\n}\n\nstatic void handle_vm_request(struct vm_request *vs)\n{\n\tswitch (vs->action) {\n\tcase VM_REBOOT:\n\t\thandle_vm_reboot(vs->vm);\n\t\tbreak;\n\tcase VM_SHUTDOWN:\n\t\thandle_vm_shutdown(vs->vm);\n\t\tbreak;\n\tdefault:\n\t\tpr_err(\"unsupport vm request %d\\n\", vs->action);\n\t\tbreak;\n\t}\n}\n\nint vm_daemon_main(void *data)\n{\n\tstruct vm_request *vs;\n\n\tpr_notice(\"start VM daemon\\n\");\n\n\tfor (;;) {\n\t\tvs = queue_pend(&vm_request_queue, -1);\n\t\tif (!vs) {\n\t\t\tpr_err(\"something is wrong to receive vm request\\n\");\n\t\t\tcontinue;\n\t\t}\n\n\t\thandle_vm_request(vs);\n\t\tfree(vs);\n\t}\n}\n\nvoid vm_daemon_init(void)\n{\n\tqueue_init(&vm_request_queue, VM_SIGNAL_QUEUE_SIZE, NULL);\n\n\tif (!create_task(\"vm-daemon\", vm_daemon_main,\n\t\t\t\t0x2000, OS_PRIO_SYSTEM, -1, 0, NULL))\n\t\tpr_err(\"create vm-daemon task failed\\n\");\n}\n"
  },
  {
    "path": "kernel/virt/vm_pm.c",
    "content": "/*\n * Copyright (C) 2022 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <minos/sched.h>\n#include <minos/irq.h>\n#include <minos/mm.h>\n#include <virt/os.h>\n#include <virt/vm.h>\n#include <virt/vmodule.h>\n#include <virt/virq.h>\n#include <virt/vmm.h>\n#include <virt/vdev.h>\n#include <minos/task.h>\n#include <minos/pm.h>\n#include <virt/virt.h>\n#include <virt/vmcs.h>\n#include <virt/vm_pm.h>\n\nstatic void vcpu_power_off_call(void *data)\n{\n\tstruct vcpu *vcpu = (struct vcpu *)data;\n\n\tif (current != vcpu->task)\n\t\tset_need_resched();\n}\n\nvoid vcpu_enter_poweroff(struct vcpu *vcpu)\n{\n\tstruct task *task = vcpu->task;\n\n\tif (check_vcpu_state(vcpu, VCPU_STATE_STOP) ||\n\t\t\tcheck_vcpu_state(vcpu, VCPU_STATE_SUSPEND))\n\t\treturn;\n\n\ttask_need_freeze(task);\n\tif (vcpu->task == current)\n\t\treturn;\n\n\t/*\n\t * wake up the vcpu if need, the vcpu may in vcpu_idle\n\t * routine.\n\t */\n\twake(&vcpu->vcpu_event);\n\n\tif ((vcpu_affinity(vcpu) != smp_processor_id())) {\n\t\tpr_debug(\"call vcpu_power_off_call for vcpu-%s\\n\",\n\t\t\t\tvcpu->task->name);\n\t\tsmp_function_call(vcpu->task->affinity,\n\t\t\t\tvcpu_power_off_call, (void *)vcpu, 0);\n\t}\n}\n\nstatic int wait_vcpu_in_state(struct vcpu *vcpu, int state, uint32_t timeout)\n{\n\tint i;\n\n\ttimeout = (timeout == 0) ? -1 : timeout;\n\tpr_notice(\"wait %d ms for vcpu%d in %s goto state %d\\n\",\n\t\t\ttimeout, vcpu->vcpu_id, vcpu->vm->name, state);\n\n\t/*\n\t * if the target vcpu is on the same physical pcpu, need\n\t * call sched() to let it has time to run.\n\t */\n\tfor (i = 0; i < timeout / 10; i++) {\n\t\tif (vcpu->task->state == state)\n\t\t\treturn 0;\n\t\tmsleep(10);\n\t}\n\n\treturn -ETIMEDOUT;\n}\n\nstatic inline int wait_vm_in_state(struct vm *vm, int state)\n{\n\tstruct vcpu *vcpu;\n\n\tvm_for_each_vcpu(vm, vcpu) {\n\t\tif (wait_vcpu_in_state(vcpu, TASK_STATE_SUSPEND, 1000)) {\n\t\t\tpr_err(\"vm-%d vcpu-%d power off failed\\n\",\n\t\t\t\t\tvm->vmid, vcpu->vcpu_id);\n\t\t\treturn -EBUSY;\n\t\t}\n\t}\n\n\tpr_notice(\"all vcpu in %s has been suspend\\n\", vm->name);\n\n\treturn 0;\n}\n\nstatic int shutdown_all_guest_vm(void)\n{\n\tstruct vm *gvm;\n\tint i;\n\n\tfor (i = 1; i < CONFIG_MAX_VM; i++) {\n\t\tgvm = vms[i];\n\t\tif (!gvm || vm_is_native(gvm))\n\t\t\tcontinue;\n\n\t\tvm_power_off(gvm->vmid, NULL, VM_PM_ACTION_BY_HOST);\n\t\tpr_notice(\"waitting vm%d %s shutdown\\n\", gvm->vmid, gvm->name);\n\n\t\t/*\n\t\t * do a hardware reset ?\n\t\t */\n\t\tif (wait_vm_in_state(gvm, TASK_STATE_SUSPEND))\n\t\t\treturn -ETIMEDOUT;\n\n\t\tdestroy_vm(gvm);\n\t}\n\n\treturn 0;\n}\n\nstatic void vcpu_reset(struct vcpu *vcpu)\n{\n\t/*\n\t * 1 - reset the vcpu vmodule state (vgic, context)\n\t * 2 - reset the vcpu's irq struct.\n\t */\n\treset_vcpu_vmodule_state(vcpu);\n\tvcpu_virq_struct_reset(vcpu);\n}\n\nstatic void __native_vm_reset(struct vm *vm)\n{\n\tstruct vdev *vdev;\n\tstruct vcpu *vcpu;\n\n\tpr_notice(\"native vm %s reboot\\n\", vm->name);\n\n\tvm_for_each_vcpu(vm, vcpu)\n\t\tvcpu_reset(vcpu);\n\n\t/* reset the vdev for this vm */\n\tlist_for_each_entry(vdev, &vm->vdev_list, list) {\n\t\tif (vdev->reset)\n\t\t\tvdev->reset(vdev);\n\t}\n\n\tvm_virq_reset(vm);\n}\n\nint reboot_native_vm(struct vm *vm)\n{\n\tif (wait_vm_in_state(vm, TASK_STATE_SUSPEND))\n\t\treturn -EBUSY;\n\n\t/*\n\t * if reboot the host vm, need to kill all the guest\n\t * vm in system if has. here shutdown all the guest\n\t * vm.\n\t */\n\tif (vm_is_host_vm(vm))\n\t\tshutdown_all_guest_vm();\n\n\t__native_vm_reset(vm);\n\n\tvm->state = VM_STATE_OFFLINE;\n\twmb();\n\n\t/*\n\t * do not need to set the VM state to reboot to avoid\n\t * race with other task.\n\t */\n\tstart_native_vm(vm);\n\n\treturn 0;\n}\n\nstatic inline int native_vm_reset(struct vm *vm, int flags)\n{\n\tif (pm_action_by_self(flags)) {\n\t\tpr_notice(\"send REBOOT request to VM daemon\\n\");\n\t\treturn send_vm_reboot_request(vm);\n\t} else {\n\t\t/*\n\t\t * if called by hypervisor, then it already in another\n\t\t * task context, so can call the reset action directly\n\t\t * and get the status.\n\t\t */\n\t\treturn reboot_native_vm(vm);\n\t}\n}\n\nstatic inline int guest_vm_reset(struct vm *vm, int flags)\n{\n\tpr_notice(\"send REBOOT request to mvm\\n\");\n\tvm->state = VM_STATE_OFFLINE;\n\treturn trap_vcpu_nonblock(VMTRAP_TYPE_COMMON,\n\t\t\tVMTRAP_REASON_REBOOT, 0, NULL);\n}\n\nstatic int __vm_reset(struct vm *vm, void *args, int flags)\n{\n\tstruct vcpu *vcpu;\n\tint old_state;\n\n\told_state = cmpxchg(&vm->state, VM_STATE_ONLINE, VM_STATE_FREEZEING);\n\tif (old_state != VM_STATE_ONLINE) {\n\t\tpr_err(\"vm is not online, under state %d\\n\", old_state);\n\t\treturn -EBUSY;\n\t}\n\n\tvm_for_each_vcpu(vm, vcpu)\n\t\tvcpu_enter_poweroff(vcpu);\n\n\tif (vm_is_native(vm))\n\t\treturn native_vm_reset(vm, flags);\n\telse\n\t\treturn guest_vm_reset(vm, flags);\n}\n\nint vm_reset(int vmid, void *args, int flags)\n{\n\tstruct vm *vm;\n\n\tvm = get_vm_by_id(vmid);\n\tif (!vm)\n\t\treturn -ENOENT;\n\n\tpr_notice(\"reset vm-%d by %s\\n\",\n\t\t\tvm->vmid, pm_action_caller(flags));\n\tif (vm_is_native(vm) && (!(vm->flags & VM_FLAGS_CAN_RESET) ||\n\t\t\t\tpm_action_by_mvm(flags))) {\n\t\tpr_err(\"vm%d do not support reset\\n\", vm->vmid);\n\t\treturn -EPERM;\n\t} else if (!vm_is_native(vm) && pm_action_by_host(flags)) {\n\t\tpr_err(\"guest vm can not reset by host\\n\");\n\t\treturn -EPERM;\n\t}\n\n\treturn __vm_reset(vm, args, flags);\n}\n\nint shutdown_native_vm(struct vm *vm)\n{\n\tif (wait_vm_in_state(vm, TASK_STATE_SUSPEND)) {\n\t\tpr_warn(\"vm %s shutdown failed\\n\", vm->name);\n\t\treturn -EBUSY;\n\t}\n\n\tif (vm_is_host_vm(vm))\n\t\tshutdown_all_guest_vm();\n\n\t__native_vm_reset(vm);\n\tvm->state = VM_STATE_OFFLINE;\n\n\treturn 0;\n}\n\nstatic int __shutdown_native_vm(struct vm *vm, int flags)\n{\n\tif (!pm_action_by_self(flags))\n\t\treturn 0;\n\n\tpr_notice(\"send SHUTDOWN request to mvm\\n\");\n\treturn send_vm_shutdown_request(vm);\n}\n\nstatic int __shutdown_guest_vm(struct vm *vm, int flags)\n{\n\tif (!pm_action_by_mvm(flags))\n\t\treturn 0;\n\n\tpr_notice(\"send SHUTDOWN request to mvm\\n\");\n\treturn trap_vcpu_nonblock(VMTRAP_TYPE_COMMON,\n\t\t\tVMTRAP_REASON_SHUTDOWN, 0, NULL);\n}\n\nstatic int __vm_power_off(struct vm *vm, void *args, int flags)\n{\n\tstruct vcpu *vcpu;\n\tint old_state;\n\n\told_state = cmpxchg(&vm->state, VM_STATE_ONLINE, VM_STATE_FREEZEING);\n\tif (old_state != VM_STATE_ONLINE) {\n\t\tpr_err(\"vm is not online, under state %d\\n\", old_state);\n\t\treturn 0;\n\t}\n\n\tif (vm_is_native(vm))\n\t\t__shutdown_native_vm(vm, flags);\n\telse\n\t\t__shutdown_guest_vm(vm, flags);\n\n\tvm_for_each_vcpu(vm, vcpu)\n\t\tvcpu_enter_poweroff(vcpu);\n\n\t/*\n\t * the vcpu has been set to TIF_NEED_STOP, so when return\n\t * to guest, the task will be killed by kernel.\n\t */\n\tsmp_wmb();\n\tvm->state = VM_STATE_OFFLINE;\n\n\treturn 0;\n}\n\nvoid destroy_guest_vm(struct vm *vm)\n{\n\t__vm_power_off(vm, NULL, VM_PM_ACTION_BY_MVM);\n\twait_vm_in_state(vm, VCPU_STATE_SUSPEND);\n\tdestroy_vm(vm);\n}\n\nint vm_power_off(int vmid, void *arg, int flags)\n{\n\tstruct vm *vm = NULL;\n\n\tvm = get_vm_by_id(vmid);\n\tif (!vm)\n\t\treturn -EINVAL;\n\n\tpr_notice(\"shutdown vm-%d by %s\\n\",\n\t\t\tvm->vmid, pm_action_caller(flags));\n\tif (vm_is_native(vm) && (!(vm->flags & VM_FLAGS_CAN_RESET) ||\n\t\t\t\tpm_action_by_mvm(flags))) {\n\t\tpr_err(\"vm%d do not support shutdown\\n\", vm->vmid);\n\t\treturn -EPERM;\n\t}\n\n\treturn __vm_power_off(vm, arg, flags);\n}\n\nstatic int vm_resume(struct vm *vm)\n{\n\tstruct vcpu *vcpu;\n\n\tpr_notice(\"vm-%d resumed\\n\", vm->vmid);\n\n\tvm_for_each_vcpu(vm, vcpu) {\n\t\tif (get_vcpu_id(vcpu) == 0)\n\t\t\tcontinue;\n\n\t\tresume_vcpu_vmodule_state(vcpu);\n\t}\n\n\tdo_hooks((void *)vm, NULL, OS_HOOK_RESUME_VM);\n\n\tif (!vm_is_native(vm)) {\n\t\tpr_notice(\"send VM RESUME request to mvm\\n\");\n\t\ttrap_vcpu_nonblock(VMTRAP_TYPE_COMMON,\n\t\t\t\tVMTRAP_REASON_VM_RESUMED, 0, NULL);\n\t}\n\n\treturn 0;\n}\n\nstatic int __vm_suspend(struct vm *vm)\n{\n\tstruct vcpu *vcpu;\n\n\tpr_notice(\"suspend vm-%d\\n\", vm->vmid);\n\tif (get_vcpu_id(current_vcpu) != 0) {\n\t\tpr_err(\"vm suspend can only called by vcpu0\\n\");\n\t\treturn -EPERM;\n\t}\n\n\tvm_for_each_vcpu(vm, vcpu) {\n\t\tif (vcpu == current_vcpu)\n\t\t\tcontinue;\n\n\t\tif (!check_vcpu_state(vcpu, TASK_STATE_STOP)) {\n\t\t\tpr_err(\"vcpu-%d is not suspend vm suspend fail\\n\",\n\t\t\t\t\tget_vcpu_id(vcpu));\n\t\t\treturn -EINVAL;\n\t\t}\n\n\t\t/*\n\t\t * other VCPU will powered up by vcpu0 again when\n\t\t * it is suspended.\n\t\t */\n\t\tsuspend_vcpu_vmodule_state(vcpu);\n\t}\n\n\tvm->state = VM_STATE_SUSPEND;\n\tsmp_mb();\n\n\tdo_hooks((void *)vm, NULL, OS_HOOK_SUSPEND_VM);\n\n\tif (!vm_is_native(vm)) {\n\t\tpr_notice(\"send VM SUSPEND request to mvm\\n\");\n\t\ttrap_vcpu_nonblock(VMTRAP_TYPE_COMMON,\n\t\t\t\tVMTRAP_REASON_VM_SUSPEND, 0, NULL);\n\t}\n\n\t/*\n\t * vcpu0 will set to WAIT_EVENT state, so the interrupt\n\t * can wakeup it, other VCPU will set to STOP state. Only\n\t * can be wake up by vcpu0.\n\t */\n\tvcpu_idle(current_vcpu);\n\n\t/*\n\t * vm is resumed\n\t */\n\tvm->state = VM_STATE_ONLINE;\n\tsmp_wmb();\n\n\tvm_resume(vm);\n\n\treturn 0;\n}\n\nint vm_suspend(int vmid)\n{\n\tstruct vm *vm = get_vm_by_id(vmid);\n\n\tif (vm == NULL)\n\t\treturn -EINVAL;\n\n\treturn __vm_suspend(vm);\n}\n\nint power_up_guest_vm(int vmid)\n{\n\tstruct vm *vm = get_vm_by_id(vmid);\n\n\tif (vm == NULL)\n\t\treturn -ENOENT;\n\n\treturn start_guest_vm(vm);\n}\n"
  },
  {
    "path": "kernel/virt/vmbox/Kconfig",
    "content": "config VMBOX\n\tdef_bool y\n"
  },
  {
    "path": "kernel/virt/vmbox/Makefile",
    "content": "obj-y\t+= vmbox.o\nobj-y\t+= vmbox_hvc.o\n"
  },
  {
    "path": "kernel/virt/vmbox/vmbox.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <virt/vmbox.h>\n#include <asm/svccc.h>\n#include <virt/hypercall.h>\n#include <virt/vmm.h>\n#include <virt/vm.h>\n#include <minos/sched.h>\n#include <virt/virq.h>\n#include <libfdt/libfdt.h>\n#include <virt/virq_chip.h>\n#include <minos/of.h>\n#include <asm/io.h>\n\n#define VMBOX_MAX_COUNT\t16\n#define VMBOX_MAX_VQS\t4\n\n#define BE_IDX\t\t0\n#define FE_IDX\t\t1\n\nstruct vmbox_info {\n\tint owner[2];\n\tuint32_t id[2];\n\tuint32_t vqs;\n\tuint32_t vring_num;\n\tuint32_t vring_size;\n\tuint32_t shmem_size;\n\tunsigned long flags;\n\tchar type[32];\n};\n\nstruct vmbox_hook {\n\tchar name[32];\n\tstruct list_head list;\n\tstruct vmbox_hook_ops *ops;\n};\n\nstatic LIST_HEAD(vmbox_con_list);\nstatic LIST_HEAD(vmbox_hook_list);\n\nstruct vring_used_elem {\n\tuint32_t id;\n\tuint32_t len;\n} __packed;\n\nstruct vring_used {\n\tuint16_t flags;\n\tuint16_t idx;\n\tstruct vring_used_elem ring[];\n} __packed;\n\nstruct vring_avail {\n\tuint16_t flags;\n\tuint16_t idx;\n\tuint16_t ring[];\n} __packed;\n\nstruct vring_desc {\n\tuint64_t addr;\n\tuint32_t len;\n\tuint16_t flags;\n\tuint16_t next;\n} __packed;\n\ntypedef int (*vmbox_hvc_handler_t)(struct vm *vm,\n\t\tstruct vmbox_device *vmbox, unsigned long arg);\n\nstatic int vmbox_index = 0;\nstatic struct vmbox *vmboxs[VMBOX_MAX_COUNT];\n\nstatic inline struct vmbox_hook *vmbox_find_hook(char *name)\n{\n\tstruct vmbox_hook *hook;\n\n\tlist_for_each_entry(hook, &vmbox_hook_list, list) {\n\t\tif (strcmp(hook->name, name) == 0)\n\t\t\treturn hook;\n\t}\n\n\treturn NULL;\n}\n\nint register_vmbox_hook(char *name, struct vmbox_hook_ops *ops)\n{\n\tint len;\n\tstruct vmbox_hook *hook;\n\n\tif (!ops)\n\t\treturn -EINVAL;\n\n\thook = vmbox_find_hook(name);\n\tif (hook) {\n\t\tpr_warn(\"vmbox hook [%s] areadly register\\n\", name);\n\t\treturn -EEXIST;\n\t}\n\n\thook = zalloc(sizeof(*hook));\n\tif (!hook)\n\t\treturn -ENOMEM;\n\n\tlen = strlen(name);\n\tlen = MIN(len, 31);\n\tstrncpy(hook->name, name, len);\n\thook->ops = ops;\n\tlist_add_tail(&vmbox_hook_list, &hook->list);\n\n\treturn 0;\n}\n\nstatic void do_vmbox_hook(struct vmbox *vmbox)\n{\n\tstruct vmbox_hook *hook;\n\n\thook = vmbox_find_hook(vmbox->name);\n\tif (!hook)\n\t\treturn;\n\n\tif (hook->ops->vmbox_init)\n\t\thook->ops->vmbox_init(vmbox);\n}\n\nstatic inline unsigned int\nvmbox_virtq_vring_desc_size(unsigned int qsz, unsigned long align)\n{\n\tint desc_size;\n\n\tdesc_size = sizeof(struct vring_desc) * qsz + (align - 1);\n\tdesc_size &= ~(align - 1);\n\n\treturn desc_size;\n}\n\nstatic inline unsigned int\nvmbox_virtq_vring_avail_size(unsigned int qsz, unsigned long align)\n{\n\tint  avail_size;\n\n\tavail_size = sizeof(uint16_t) * (3 + qsz) + (align - 1);\n\tavail_size &= ~(align - 1);\n\n\treturn avail_size;\n\n}\n\nstatic inline unsigned int\nvmbox_virtq_vring_used_size(unsigned int qsz, unsigned long align)\n{\n\tint used_size;\n\n\tused_size = sizeof(uint16_t) * 2 + sizeof(struct vring_used_elem) *\n\t\t(qsz + 1) + (align - 1);\n\tused_size &= ~(align - 1);\n\n\treturn used_size;\n\n}\n\nstatic inline unsigned int\nvmbox_virtq_vring_size(unsigned int qsz, unsigned long align)\n{\n\treturn vmbox_virtq_vring_desc_size(qsz, align) +\n\t\tvmbox_virtq_vring_avail_size(qsz, align) +\n\t\tvmbox_virtq_vring_used_size(qsz, align);\n}\n\nstatic inline size_t get_vmbox_iomem_header_size(struct vmbox_info *vinfo)\n{\n\tsize_t size = VMBOX_IPC_ALL_ENTRY_SIZE;\n\n\t/*\n\t * calculate the vring desc size first, each vmbox will\n\t * have 0x100 IPC region\n\t */\n\tsize += vmbox_virtq_vring_size(vinfo->vring_num,\n\t\t\tVMBOX_VRING_ALGIN_SIZE) * vinfo->vqs;\n\n\treturn size;\n}\n\nstatic inline size_t get_vmbox_iomem_buf_size(struct vmbox_info *vinfo)\n{\n\treturn (vinfo->vring_num * vinfo->vring_size * vinfo->vqs);\n}\n\nstatic inline size_t get_vmbox_iomem_size(struct vmbox_info *vinfo)\n{\n\treturn get_vmbox_iomem_header_size(vinfo) +\n\t\t\t\tget_vmbox_iomem_buf_size(vinfo);\n}\n\nstatic struct vmbox_device *create_vmbox_device(struct vmbox *vmbox, int idx)\n{\n\tstruct vmbox_device *vdev;\n\n\tvdev = zalloc(sizeof(*vdev));\n\tif (!vdev)\n\t\treturn NULL;\n\n\tspin_lock_init(&vdev->lock);\n\tvdev->vmbox= vmbox;\n\tvdev->is_backend = (idx == BE_IDX);\n\tvdev->vm = get_vm_by_id(vmbox->owner[idx]);\n\n\treturn vdev;\n}\n\nstatic int create_vmbox_devices(struct vmbox *vmbox)\n{\n\tstruct vmbox_device *vdev_be;\n\tstruct vmbox_device *vdev_fe;\n\n\tvdev_be = create_vmbox_device(vmbox, BE_IDX);\n\tvdev_fe = create_vmbox_device(vmbox, FE_IDX);\n\n\tif (!vdev_be || !vdev_fe)\n\t\tgoto release_vdev;\n\n\t/* connect to each other */\n\tvdev_be->bro = vdev_fe;\n\tvdev_fe->bro = vdev_be;\n\tvmbox->devices[BE_IDX] = vdev_be;\n\tvmbox->devices[FE_IDX] = vdev_fe;\n\n\treturn 0;\n\nrelease_vdev:\n\tif (vdev_be)\n\t\tfree(vdev_be);\n\tif (vdev_fe)\n\t\tfree(vdev_fe);\n\treturn -ENOMEM;\n}\n\nstatic int create_vmbox(struct vmbox_info *vinfo)\n{\n\tstruct vm *vm1, *vm2;\n\tstruct vmbox *vmbox;\n\tsize_t iomem_size = 0;\n\tint o1 = vinfo->owner[BE_IDX];\n\tint o2 = vinfo->owner[FE_IDX];\n\n\tvm1 = get_vm_by_id(o1);\n\tvm2 = get_vm_by_id(o2);\n\tif (!vm1 || !vm2) {\n\t\tpr_warn(\"no such VM %d %d\\n\", o1, o2);\n\t\treturn -ENOENT;\n\t}\n\n\tvmbox = zalloc(sizeof(*vmbox));\n\tif (!vmbox)\n\t\treturn -ENOMEM;\n\n\tvmbox->owner[BE_IDX] = o1;\n\tvmbox->owner[FE_IDX] = o2;\n\tmemcpy(vmbox->devid, vinfo->id, sizeof(uint32_t) * 2);\n\tstrcpy(vmbox->name, vinfo->type);\n\tvmbox->vqs = vinfo->vqs;\n\tvmbox->vring_num = vinfo->vring_num;\n\tvmbox->vring_size = vinfo->vring_size;\n\tvmbox->id = vmbox_index;\n\tvmbox->flags = vinfo->flags;\n\tvmboxs[vmbox_index++] = vmbox;\n\n\t/*\n\t * the current memory allocation system has a limitation\n\t * that get_io_pages can not get memory which bigger than\n\t * 2M. if need to get memory bigger than 2M can use\n\t * alloc_mem_block and map these memory to IO memory ?\n\t *\n\t * if the vmbox use fix shared memory size, the shmem_size\n\t * will be set before this fucntion, otherwise it means\n\t * the vmbox is use virtq mode\n\t */\n\tif (!vinfo->shmem_size) {\n\t\tiomem_size = get_vmbox_iomem_size(vinfo);\n\t\tiomem_size = PAGE_BALIGN(iomem_size);\n\t} else {\n\t\tiomem_size = PAGE_BALIGN(vinfo->shmem_size);\n\t}\n\n\tvmbox->shmem = alloc_shmem(PAGE_NR(iomem_size));\n\tif (!vmbox->shmem)\n\t\tpanic(\"no more memory for %s\\n\", vinfo->type);\n\n\t/* init all the header memory to zero */\n\tif (!vinfo->shmem_size)\n\t\tmemset(vmbox->shmem, 0, get_vmbox_iomem_header_size(vinfo));\n\telse\n\t\tmemset(vmbox->shmem, 0, VMBOX_IPC_ALL_ENTRY_SIZE);\n\n\tvmbox->shmem_size = iomem_size;\n\n\tif (create_vmbox_devices(vmbox))\n\t\tpr_err(\"create vmbox device for %s failed\\n\", vmbox->name);\n\n\tdo_vmbox_hook(vmbox);\n\n\treturn 0;\n}\n\nint of_create_vmbox(struct device_node *node)\n{\n\tint ret;\n\tstruct vmbox_info vinfo;\n\n\tif (vmbox_index >= VMBOX_MAX_COUNT) {\n\t\tpr_err(\"vmbox count beyond the max size\\n\");\n\t\treturn -ENOSPC;\n\t}\n\n\tmemset(&vinfo, 0, sizeof(vinfo));\n\n\t/*\n\t * vmbox-id\t     - id of this vmbox dev_id and vendor_id\n\t * vmbox-type\t     - the type of this vmbox\n\t * vmbox-owner\t     - the owner of this vmbox, two owmer\n\t * vmbox-vqs         - how many virtqueue for this vmbox\n\t * vmbox-vrings      - how many vrings for each virtqueue\n\t * vmbox-vring-size  - buffer size of each vring\n\t * vmbox-shmem-size  - do not using virtq to transfer data between VM\n\t */\n\tif (of_get_u32_array(node, \"vmbox-owner\", (uint32_t *)vinfo.owner, 2) < 2)\n\t\treturn -EINVAL;\n\n\tof_get_string(node, \"vmbox-type\", vinfo.type, sizeof(vinfo.type) - 1);\n\tif (of_get_u32_array(node, \"vmbox-id\", vinfo.id, 2) <= 0)\n\t\tpr_warn(\"unknown vmbox id for %s\\n\", vinfo.type);\n\n\tif (of_get_bool(node, \"platform-device\"))\n\t\tvinfo.flags |= VMBOX_F_PLATFORM_DEV;\n\n\tret = of_get_u32_array(node, \"vmbox-shmem-size\", &vinfo.shmem_size, 1);\n\tif (ret && vinfo.shmem_size > 0)\n\t\tgoto out;\n\n\tif (of_get_u32_array(node, \"vmbox-vqs\", &vinfo.vqs, 1) <= 0)\n\t\treturn -EINVAL;\n\tof_get_u32_array(node, \"vmbox-vrings\", &vinfo.vring_num, 1);\n\tof_get_u32_array(node, \"vmbox-vring-size\", &vinfo.vring_size, 1);\n\nout:\n\treturn create_vmbox(&vinfo);\n}\n\nstatic struct vmbox_controller *vmbox_get_controller(struct vm *vm)\n{\n\tstruct vmbox_controller *vc;\n\n\tlist_for_each_entry(vc, &vmbox_con_list, list) {\n\t\tif (vc->vm == vm)\n\t\t\treturn vc;\n\t}\n\n\treturn NULL;\n}\n\nstatic int vmbox_device_attach(struct vmbox_controller *_vc,\n\t\tstruct vmbox *vmbox, struct vmbox_device *vdev)\n{\n\tstruct vmm_area *va;\n\tstruct vm *vm = vdev->vm;\n\n\tvdev->vc = _vc;\n\tvdev->vring_virq = alloc_vm_virq(vm);\n\tvdev->ipc_virq = alloc_vm_virq(vm);\n\tif (!vdev->vring_virq || !vdev->ipc_virq)\n\t\treturn -ENOSPC;\n\n\t/*\n\t * set all the vmm area to VM_SHARED, since the host\n\t * will release the memory final.\n\t */\n\tva = alloc_free_vmm_area(&vm->mm, vmbox->shmem_size,\n\t\t\tPAGE_MASK, VM_SHARED | VM_GUEST_SHMEM);\n\tif (!va)\n\t\treturn -ENOMEM;\n\n\tvdev->iomem = va->start;\n\tvdev->iomem_size = vmbox->shmem_size;\n\tmap_vmm_area(&vm->mm, va, (unsigned long)vmbox->shmem);\n\n\tvdev->devid = _vc->dev_cnt++;\n\t_vc->devices[vdev->devid] = vdev;\n\n\t/*\n\t * set the device online for the vm\n\t * if the controller of this vmbox_device is areadly\n\t * online then send a virq to the VM, or if there\n\t * are pending virqs for this controller, send a virq\n\t * too\n\t */\n\t _vc->dev_state |= (1 << vdev->devid);\n\t _vc->irq_state |= (1 << VMBOX_CON_INT_TYPE_DEV_ONLINE);\n\tsmp_wmb();\n\n\treturn 0;\n}\n\nstatic void vmbox_device_attach_to_vm(struct vmbox_controller *_vc)\n{\n\tint i;\n\tstruct vmbox *vmbox;\n\tstruct vm *vm = _vc->vm;\n\n\tfor (i = 0; i < vmbox_index; i++) {\n\t\tvmbox = vmboxs[i];\n\n\t\t/*\n\t\t * when a vmbox controller is online, we first check all\n\t\t * the clinet device which is attached to this device and\n\t\t * report the client device to the VM. VM then load the\n\t\t * driver for this client device.\n\t\t *\n\t\t * once the client device finish to setup, it will write\n\t\t * it's status to power on, at this time, get the host\n\t\t * device which the client device connected to, and\n\t\t * report the host device to the VM\n\t\t *\n\t\t * but in order to support freertos which can not allocated\n\t\t * device dynamicly, need to record all the device before\n\t\t * the vm started\n\t\t */\n\t\tif ((vmbox->owner[BE_IDX] == vm->vmid)) {\n\t\t\tif (vmbox_device_attach(_vc,\n\t\t\t\t\tvmbox, vmbox->devices[BE_IDX]))\n\t\t\t\tpr_err(\"vmbox device attached failed\\n\");\n\t\t}\n\n\t\tif ((vmbox->owner[FE_IDX]) == vm->vmid) {\n\t\t\tif (vmbox_device_attach(_vc,\n\t\t\t\t\tvmbox, vmbox->devices[FE_IDX]))\n\t\t\t\tpr_err(\"vmbox device attached failed\\n\");\n\t\t}\n\t}\n}\n\nstatic int vmbox_handle_con_read(struct vmbox_controller *vc,\n\t\tunsigned long offset, unsigned long *value)\n{\n\tswitch (offset) {\n\tcase VMBOX_CON_DEV_STAT:\n\t\t*value = vc->dev_state;\n\t\tbreak;\n\tcase VMBOX_CON_INT_STATUS:\n\t\t/* once read, clear the status */\n\t\t*value = vc->irq_state;\n\t\tvc->irq_state = 0;\n\t\tbreak;\n\tdefault:\n\t\t*value = 0;\n\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\nstatic int inline __vmbox_handle_dev_read(struct vmbox_device *vdev,\n\t\tint reg, unsigned long *v)\n{\n\tunsigned long flags;\n\tstruct vmbox *vmbox = vdev->vmbox;\n\n\tswitch (reg) {\n\tcase VMBOX_DEV_IPC_TYPE:\n\t\t/* read and clear */\n\t\tspin_lock_irqsave(&vdev->lock, flags);\n\t\t*v = vdev->ipc_type;\n\t\tvdev->ipc_type = 0;\n\t\tspin_unlock_irqrestore(&vdev->lock, flags);\n\t\tbreak;\n\n\tcase VMBOX_DEV_DEVICE_ID:\n\t\tif (vdev->is_backend)\n\t\t\t*v = vmbox->devid[0];\n\t\telse\n\t\t\t*v = vmbox->devid[0] + 1;\n\t\tbreak;\n\n\tcase VMBOX_DEV_VQS:\n\t\t*v = vmbox->vqs;\n\t\tbreak;\n\n\tcase VMBOX_DEV_VRING_NUM:\n\t\t*v = vmbox->vring_num;\n\t\tbreak;\n\n\tcase VMBOX_DEV_VRING_SIZE:\n\t\t*v = vmbox->vring_size;\n\t\tbreak;\n\n\tcase VMBOX_DEV_VRING_BASE_HI:\n\t\t*v = (unsigned long)vdev->iomem >> 32;\n\t\tbreak;\n\n\tcase VMBOX_DEV_VRING_BASE_LOW:\n\t\t*v = (unsigned long)vdev->iomem & 0xffffffff;\n\t\tbreak;\n\n\tcase VMBOX_DEV_MEM_SIZE:\n\t\t*v = vdev->iomem_size;\n\t\tbreak;\n\n\tcase VMBOX_DEV_ID:\n\t\t*v = vdev->devid | VMBOX_DEVICE_MAGIC;\n\t\tbreak;\n\n\tcase VMBOX_DEV_VENDOR_ID:\n\t\t*v = vmbox->devid[1];\n\t\tbreak;\n\n\tcase VMBOX_DEV_VRING_IRQ:\n\t\t*v = vdev->vring_virq;\n\t\tbreak;\n\n\tcase VMBOX_DEV_IPC_IRQ:\n\t\t*v = vdev->ipc_virq;\n\t\tbreak;\n\n\tdefault:\n\t\t*v = 0;\n\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\nstatic int vmbox_handle_dev_read(struct vmbox_controller *vc,\n\t\tunsigned long offset, unsigned long *value)\n{\n\tint devid;\n\tuint32_t reg;\n\tstruct vmbox_device *vdev;\n\n\toffset -= VMBOX_CON_DEV_BASE;\n\tdevid = offset / VMBOX_CON_DEV_SIZE;\n\treg = offset % VMBOX_CON_DEV_SIZE;\n\n\tif (devid >= sizeof(vc->devices)) {\n\t\tpr_err(\"vmbox devid invaild %d\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\tvdev = vc->devices[devid];\n\tif (!vdev) {\n\t\tpr_err(\"no such device %d\\n\", devid);\n\t\treturn -ENOENT;\n\t}\n\n\treturn __vmbox_handle_dev_read(vdev, reg, value);\n}\n\nstatic int vmbox_con_read(struct vdev *vdev, gp_regs *regs,\n\t\tint idx, unsigned long offset, unsigned long *value)\n{\n\tstruct vmbox_controller *vc = vdev_to_vmbox_con(vdev);\n\n\tif (offset < VMBOX_CON_DEV_BASE)\n\t\treturn vmbox_handle_con_read(vc, offset, value);\n\telse\n\t\treturn vmbox_handle_dev_read(vc, offset, value);\n}\n\nstatic int vmbox_handle_con_write(struct vmbox_controller *vc,\n\t\tunsigned long offset, unsigned long *value)\n{\n\tswitch (offset) {\n\tcase VMBOX_CON_ONLINE:\n\t\tvc->status = 1;\n\t\tvmbox_device_attach_to_vm(vc);\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\nstatic int vmbox_handle_dev_write(struct vmbox_controller *vc,\n\t\tunsigned long offset, unsigned long *value)\n{\n\tint devid, need_notify = 0;\n\tuint32_t reg;\n\tunsigned long flags;\n\tstruct vmbox_device *vdev, *bro;\n\n\toffset -= VMBOX_CON_DEV_BASE;\n\tdevid = offset / VMBOX_CON_DEV_SIZE;\n\treg = offset % VMBOX_CON_DEV_SIZE;\n\n\tif (devid >= sizeof(vc->devices)) {\n\t\tpr_err(\"vmbox devid invaild %d\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\tvdev = vc->devices[devid];\n\tif (!vdev) {\n\t\tpr_err(\"no such device %d\\n\", devid);\n\t\treturn -ENOENT;\n\t}\n\tbro = vdev->bro;\n\n\tswitch (reg) {\n\tcase VMBOX_DEV_VRING_EVENT:\n\t\tif (!bro->state)\n\t\t\treturn 0;\n\n\t\tsend_virq_to_vm(bro->vm, bro->vring_virq);\n\t\tbreak;\n\tcase VMBOX_DEV_IPC_EVENT:\n\t\t/*\n\t\t * write the event_reg and send a virq to the vm\n\t\t * wait last event finised\n\t\t */\n\t\tif (!bro->state || (*value >= VMBOX_DEV_IPC_COUNT))\n\t\t\treturn 0;\n\n\t\tspin_lock_irqsave(&bro->lock, flags);\n\t\tif (!(bro->ipc_type & (1 << *value))) {\n\t\t\tbro->ipc_type |= (1 << *value);\n\t\t\tneed_notify = 1;\n\t\t}\n\t\tspin_unlock_irqrestore(&bro->lock, flags);\n\n\t\tif (need_notify)\n\t\t\tsend_virq_to_vm(bro->vm, bro->ipc_virq);\n\t\tbreak;\n\tcase VMBOX_DEV_VDEV_ONLINE:\n\t\t/*\n\t\t * when vmbox driver write this register, it means that\n\t\t * this device is ok to receive irq or handle the related\n\t\t * event\n\t\t *\n\t\t * if otherside already online need to send a virq to\n\t\t * the otherside to inform the status change\n\t\t */\n\t\tpr_notice(\"vmbox device %s online for vm%d\\n\",\n\t\t\t\tvdev->vmbox->name, vdev->vm->vmid);\n\t\tvdev->state = VMBOX_DEV_STAT_ONLINE;\n\n\t\tif (bro->state == VMBOX_DEV_STAT_ONLINE) {\n\t\t\tspin_lock_irqsave(&bro->lock, flags);\n\t\t\tbro->ipc_type |= (1 << 0);\n\t\t\tspin_unlock_irqrestore(&bro->lock, flags);\n\n\t\t\tsend_virq_to_vm(bro->vm, bro->ipc_virq);\n\t\t}\n\n\t\tbreak;\n\tdefault:\n\t\tpr_err(\"unsupport reg 0x%x\\n\", reg);\n\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\nstatic int vmbox_con_write(struct vdev *vdev, gp_regs *regs,\n\t\tint idx, unsigned long offset, unsigned long *value)\n{\n\tstruct vmbox_controller *vc = vdev_to_vmbox_con(vdev);\n\n\tif (offset < VMBOX_CON_DEV_BASE)\n\t\treturn vmbox_handle_con_write(vc, offset, value);\n\telse\n\t\treturn vmbox_handle_dev_write(vc, offset, value);\n}\n\nstatic void vmbox_con_deinit(struct vdev *vdev)\n{\n\t/* will never called */\n}\n\nstatic void vmbox_con_reset(struct vdev *vdev)\n{\n\t/* will never called */\n}\n\nstatic int __of_setup_vmbox_con_virqs(struct vmbox_controller *vcon,\n\t\tvoid *dtb, int node)\n{\n\tint size = 0;\n\tuint32_t tmp[10];\n\tstruct vm *vm = vcon->vm;\n\tstruct virq_chip *vc = vm->virq_chip;\n\n\tif (!vc->generate_virq) {\n\t\tpr_err(\"no generate_virq in virq_chip\\n\");\n\t\treturn -ENOENT;\n\t}\n\n\tsize += vc->generate_virq(tmp + size, vcon->virq);\n\tfdt_setprop(dtb, node, \"interrupts\", (void *)tmp, size * 4);\n\n\treturn 0;\n}\n\nstatic void of_add_vmbox_controller(struct vm *vm)\n{\n\tint node;\n\tchar node_name[128];\n\tvoid *dtb = vm->setup_data;\n\tstruct vmbox_controller *vc = vmbox_get_controller(vm);\n\n\tif (!vc)\n\t\treturn;\n\n\tmemset(node_name, 0, 128);\n\tsprintf(node_name, \"vmbox-controller@%x\", vc->va);\n\n\tnode = fdt_add_subnode(dtb, 0, node_name);\n\tif (node < 0) {\n\t\tpr_err(\"failed to add vmbox device %s for vm-%d\\n\",\n\t\t\t\tnode_name, vm->vmid);\n\t\treturn;\n\t}\n\n\tfdt_setprop(dtb, node, \"compatible\", \"minos,vmbox\", 12);\n\n\tfdt_set_node_reg(dtb, node, (unsigned long)vc->va, PAGE_SIZE);\n\t__of_setup_vmbox_con_virqs(vc, dtb, node);\n}\n\nstatic int __vm_create_vmbox_controller_dynamic(struct vm *vm)\n{\n\tstruct vmbox_controller *vc;\n\tstruct vmm_area *va;\n\n\tvc = zalloc(sizeof(*vc));\n\tif (!vc)\n\t\treturn -ENOMEM;\n\n\thost_vdev_init(vm, &vc->vdev, \"vmbox-con\");\n\tva = vdev_alloc_iomem_range(&vc->vdev, PAGE_SIZE, 0);\n\tif (!va) {\n\t\tfree(vc);\n\t\treturn -ENOMEM;\n\t}\n\n\tvc->virq = alloc_vm_virq(vm);\n\tif (!vc->virq) {\n\t\tfree(vc);\n\t\treturn -ENOENT;\n\t}\n\n\tvc->va = (void *)va->start;\n\tvc->vm = vm;\n\n\t/*\n\t * register the vmbox controller for the vm, all the\n\t * operation (read/write) on the virtual address will\n\t * be trap to hypervisor\n\t */\n\tvc->vdev.read = vmbox_con_read;\n\tvc->vdev.write = vmbox_con_write;\n\tvc->vdev.deinit = vmbox_con_deinit;\n\tvc->vdev.reset = vmbox_con_reset;\n\tvdev_add(&vc->vdev);\n\n\tlist_add_tail(&vmbox_con_list, &vc->list);\n\n\treturn 0;\n}\n\nstatic int __vm_create_vmbox_controller_static(struct vm *vm)\n{\n\tint ret;\n\tuint32_t irq;\n\tstruct device_node *vc_node;\n\tunsigned long base, size, flags;\n\tstruct vmbox_controller *vc;\n\tstruct device_node *node = vm->dev_node;\n\tchar *comp[] = {\n\t\t\"minos,vmbox-controller\",\n\t\tNULL\n\t};\n\n\tvc_node = of_find_node_by_compatible(node, comp);\n\tif (!vc_node)\n\t\treturn -EAGAIN;\n\n\tret = of_translate_address_index(vc_node, &base, &size, 0);\n\tif (ret || (size == 0))\n\t\treturn -ENOENT;\n\n\tret = get_device_irq_index(vc_node, &irq, &flags, 0);\n\tif (ret || (irq < 32))\n\t\treturn -ENOENT;\n\n\tvc = zalloc(sizeof(*vc));\n\tif (!vc)\n\t\treturn -ENOMEM;\n\n\thost_vdev_init(vm, &vc->vdev, \"vmbox-con\");\n\tret = vdev_add_iomem_range(&vc->vdev, base, size);\n\tif (ret) {\n\t\tfree(vc);\n\t\treturn ret;\n\t}\n\n\trequest_virq(vm, irq, 0);\n\n\tvc->va = (void *)base;\n\tvc->vm = vm;\n\tvc->virq = irq;\n\n\tvc->vdev.read = vmbox_con_read;\n\tvc->vdev.write = vmbox_con_write;\n\tvc->vdev.deinit = vmbox_con_deinit;\n\tvc->vdev.reset = vmbox_con_reset;\n\tvdev_add(&vc->vdev);\n\n\tlist_add_tail(&vmbox_con_list, &vc->list);\n\n\treturn 0;\n}\n\nint create_vmbox_controller(struct vm *vm)\n{\n\tint ret = -EAGAIN;\n\n\t/*\n\t * first find whether need to create a static vmbox\n\t * controller from the device tree\n\t */\n\tret = __vm_create_vmbox_controller_static(vm);\n\tif (!ret)\n\t\treturn 0;\n\n\tif (ret != -EAGAIN)\n\t\treturn ret;\n\n\treturn __vm_create_vmbox_controller_dynamic(vm);\n}\n\nint vmbox_register_platdev(struct vmbox_device *vdev, void *dtb, char *type)\n{\n\tint node;\n\tchar node_name[128];\n\n\tmemset(node_name, 0, 128);\n\tsprintf(node_name, \"vmbox-%s@%x\", type, vdev->iomem);\n\n\tnode = fdt_add_subnode(dtb, 0, node_name);\n\tif (node < 0) {\n\t\tpr_err(\"failed to add platform device %s\\n\", type);\n\t\treturn -ENOENT;\n\t}\n\n\tfdt_setprop(dtb, node, \"compatible\", type, strlen(type) + 1);\n\tfdt_set_node_reg(dtb, node, (unsigned long)vdev->iomem,\n\t\t\tvdev->iomem_size);\n\treturn 0;\n}\n\nstatic int vmbox_device_do_hooks(struct vm *vm)\n{\n\tint i;\n\tstruct vmbox_device *vdev;\n\tstruct vmbox_hook *hook;\n\tstruct vmbox *vmbox;\n\n\tfor (i = 0; i < vmbox_index; i++) {\n\t\tvmbox = vmboxs[i];\n\t\thook = vmbox_find_hook(vmbox->name);\n\t\tif (!hook)\n\t\t\tcontinue;\n\n\t\tif (hook->ops->vmbox_be_init &&\n\t\t\t\t(vmbox->owner[0] == vm->vmid)) {\n\t\t\tvdev = vmbox->devices[0];\n\t\t\thook->ops->vmbox_be_init(vdev->vm, vmbox, vdev);\n\t\t}\n\n\t\tif (hook->ops->vmbox_fe_init &&\n\t\t\t\t(vmbox->owner[1] == vm->vmid)) {\n\t\t\tvdev = vmbox->devices[1];\n\t\t\thook->ops->vmbox_fe_init(vdev->vm, vmbox, vdev);\n\t\t}\n\t}\n\n\treturn 0;\n}\n\nint vmbox_init(struct vm *vm)\n{\n\tif (vm->flags & VM_FLAGS_SETUP_OF)\n\t\tof_add_vmbox_controller(vm);\n\n\treturn vmbox_device_do_hooks(vm);\n}\n"
  },
  {
    "path": "kernel/virt/vmbox/vmbox_hvc.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <virt/vmm.h>\n#include <virt/vm.h>\n#include <minos/sched.h>\n#include <virt/virq.h>\n#include <libfdt/libfdt.h>\n#include <virt/virq_chip.h>\n#include <minos/of.h>\n#include <asm/io.h>\n#include <virt/vmbox.h>\n\n#define BUF_0_SIZE\t4096\n#define BUF_1_SIZE\t2048\n\n/*\n * at least 8K size for the transfer buffer, and\n * in or out buffer size need 2^ align\n */\nstruct hvc_ring {\n\tvolatile uint32_t ridx;\n\tvolatile uint32_t widx;\n\tuint32_t size;\n\tchar buf[0];\n};\n\nstatic int hvc_be_init(struct vm *vm, struct vmbox *vmbox,\n\t\tstruct vmbox_device *vdev)\n{\n\tvoid *dtb = vm->setup_data;\n\n\t/*\n\t * only linux system need do this\n\t */\n\tif (!(vmbox->flags & VMBOX_F_PLATFORM_DEV))\n\t\treturn 0;\n\n\tpr_notice(\"register hvc platform device for vm%d\\n\", vm->vmid);\n\n\treturn vmbox_register_platdev(vdev, dtb, \"minos,hvc-be\");\n}\n\nstatic int hvc_vmbox_init(struct vmbox *vmbox)\n{\n\tvoid *base = vmbox->shmem + VMBOX_IPC_ALL_ENTRY_SIZE;\n\tint header_size = sizeof(struct hvc_ring);\n\tstruct hvc_ring *ring;\n\n\tring = (struct hvc_ring *)(base);\n\tring->ridx = 0;\n\tring->widx = 0;\n\tring->size = BUF_0_SIZE;\n\n\tring = (struct hvc_ring *)(base + header_size + BUF_0_SIZE);\n\tring->ridx = 0;\n\tring->widx = 0;\n\tring->size = BUF_1_SIZE;\n\n\treturn 0;\n}\n\nstatic struct vmbox_hook_ops hvc_ops = {\n\t.vmbox_be_init = hvc_be_init,\n\t.vmbox_init = hvc_vmbox_init,\n};\n\nstatic int __init_text vmbox_hvc_init(void)\n{\n\treturn register_vmbox_hook(\"hvc\", &hvc_ops);\n}\nsubsys_initcall(vmbox_hvc_init);\n"
  },
  {
    "path": "kernel/virt/vmcs.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <virt/vm.h>\n#include <minos/sched.h>\n#include <virt/virq.h>\n#include <minos/irq.h>\n#include <virt/vmcs.h>\n\nint __vcpu_trap(uint32_t type, uint32_t reason, unsigned long data,\n\t\tunsigned long *result, int nonblock)\n{\n\tunsigned long flags;\n\tstruct vcpu *vcpu = get_current_vcpu();\n\tstruct vmcs *vmcs = vcpu->vmcs;\n\tstruct vm *vm0 = get_host_vm();\n\n\tif (vcpu->vmcs_irq < 0) {\n\t\tpr_err(\"no hvm irq for this vcpu\\n\");\n\t\treturn -ENOENT;\n\t}\n\n\tif ((type >= VMTRAP_TYPE_UNKNOWN) ||\n\t\t\t(reason >= VMTRAP_REASON_UNKNOWN))\n\t\treturn -EINVAL;\n\n\t/*\n\t * enable the interrupt in case the vm0 shutdown\n\t * or reboot this vm when the vm is waitting for\n\t * vmcs ack\n\t */\n\tlocal_irq_save(flags);\n\tlocal_irq_enable();\n\n\t/*\n\t * wait for the last trap complete, if the gvm\n\t * has the same affinity pcpu with the vm0, need\n\t * to use sched() in case of dead lock\n\t */\n\twhile (vmcs->guest_index != vmcs->host_index) {\n\t\tif (vcpu_affinity(vcpu) < vcpu_affinity(vm0->vcpus[0]))\n\t\t\tsched();\n\t\telse\n\t\t\tcpu_relax();\n\t\tmb();\n\n\t\tif (is_task_need_stop(current)) {\n\t\t\tlocal_irq_restore(flags);\n\t\t\tpr_err(\"vcpu need stop, exit %s\\n\", __func__);\n\t\t\treturn -EABORT;\n\t\t}\n\t}\n\n\tvmcs->trap_type = type;\n\tvmcs->trap_reason = reason;\n\tvmcs->trap_data = data;\n\tvmcs->trap_ret = 0;\n\tvmcs->trap_result = result ? *result : 0;\n\tsmp_mb();\n\n\t/*\n\t * increase the host index of the vmcs, then send the\n\t * virq to the vcpu0 of the vm0\n\t */\n\tvmcs->host_index++;\n\tsmp_mb();\n\n\tif (send_virq_to_vm(vm0, vcpu->vmcs_irq)) {\n\t\tpr_err(\"vmcs failed to send virq for vm-%d\\n\",\n\t\t\t\tvcpu->vm->vmid);\n\t\tvmcs->host_index--;\n\t\tsmp_mb();\n\n\t\tvmcs->trap_ret = -EPERM;\n\t\tvmcs->trap_result = 0;\n\t\treturn -EFAULT;\n\t}\n\n\t/*\n\t * if vcpu's pcpu is equal the vm0_vcpu0's pcpu\n\t * force to block\n\t */\n\tif (vcpu_affinity(vcpu) == vcpu_affinity(vm0->vcpus[0]))\n\t\tnonblock = 0;\n\n\t/*\n\t * if gvm's vcpu is on the same pcpu which hvm\n\t * affnity, then need to call sched to sched the\n\t * hvm's vcpu in case of dead lock\n\t */\n\tif (!nonblock) {\n\t\twhile (vmcs->guest_index != vmcs->host_index) {\n\t\t\tif (vcpu_affinity(vcpu) < vm0->vcpu_nr)\n\t\t\t\tsched();\n\t\t\telse\n\t\t\t\tcpu_relax();\n\n\t\t\tif (is_task_need_stop(current)) {\n\t\t\t\tlocal_irq_restore(flags);\n\t\t\t\tpr_err(\"vcpu need stop, exit %s\\n\", __func__);\n\t\t\t\treturn -EABORT;\n\t\t\t}\n\t\t}\n\n\t\tif (result)\n\t\t\t*result = vmcs->trap_result;\n\t} else {\n\t\tif (result)\n\t\t\t*result = 0;\n\t}\n\n\tlocal_irq_restore(flags);\n\n\treturn vmcs->trap_ret;\n}\n\nint setup_vmcs_data(void *data, size_t size)\n{\n\tvoid *base = (void *)get_current_vcpu()->vmcs->data;\n\n\tif (size > VMCS_DATA_SIZE)\n\t\treturn -ENOMEM;\n\n\tmemcpy(base, data, size);\n\treturn 0;\n}\n\nstatic void vcpu_vmcs_init(struct vcpu *vcpu)\n{\n\tstruct vmcs *vmcs = vcpu->vmcs;\n\n\tif (!vmcs) {\n\t\tpr_err(\"vmcs of vcpu is NULL\\n\");\n\t\treturn;\n\t}\n\n\tvmcs->vcpu_id = get_vcpu_id(vcpu);\n}\n\nunsigned long vm_create_vmcs(struct vm *vm)\n{\n\tint i;\n\tuint32_t size;\n\tstruct vcpu *vcpu;\n\tvoid *base;\n\tunsigned long hvm_vmcs;\n\n\tif (vm->vmcs || vm->hvm_vmcs)\n\t\treturn 0;\n\n\tsize = VMCS_SIZE(vm->vcpu_nr);\n\tbase = alloc_shmem(PAGE_NR(size));\n\tif (!base)\n\t\treturn 0;\n\n\tmemset(base, 0, size);\n\n\thvm_vmcs = create_hvm_shmem_map(vm, (unsigned long)base, size);\n\tif (hvm_vmcs == BAD_ADDRESS) {\n\t\tpr_err(\"mapping vmcs to hvm failed\\n\");\n\t\tfree_shmem(base);\n\t\treturn 0;\n\t}\n\n\tfor (i = 0; i < vm->vcpu_nr; i++) {\n\t\tvcpu = vm->vcpus[i];\n\t\tvcpu->vmcs = (struct vmcs *)(base +\n\t\t\t\ti * sizeof(struct vmcs));\n\t\tvcpu_vmcs_init(vcpu);\n\t}\n\n\treturn hvm_vmcs;\n}\n\nint vm_create_vmcs_irq(struct vm *vm, int vcpu_id)\n{\n\tstruct vcpu *vcpu = get_vcpu_in_vm(vm, vcpu_id);\n\n\tif (!vcpu)\n\t\treturn -ENOENT;\n\n\tvcpu->vmcs_irq = alloc_hvm_virq();\n\tif (vcpu->vmcs_irq < 0)\n\t\tpr_err(\"alloc virq for vmcs failed\\n\");\n\n#ifdef CONFIG_PLATFORM_BCM2837\n\treturn vcpu->vmcs_irq - 32;\n#else\n\treturn vcpu->vmcs_irq;\n#endif\n}\n"
  },
  {
    "path": "kernel/virt/vmm.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <virt/vm.h>\n#include <virt/iommu.h>\n#include <minos/arch.h>\n\n#define VM_IPA_SIZE (1UL << 40)\n\nstruct block_section {\n\tunsigned long start;\n\tunsigned long size;\n\tunsigned long end;\n\tunsigned long free_blocks;\n\tunsigned long total_blocks;\n\tunsigned long current_index;\n\tunsigned long *bitmap;\n\tstruct block_section *next;\n};\n\nstatic struct block_section *bs_head;\nstatic DEFINE_SPIN_LOCK(bs_lock);\nstatic unsigned long free_blocks;\n\n#define mm_to_vm(__mm) container_of((__mm), struct vm, mm)\n#define VMA_SIZE(vma) ((vma)->end - (vma)->start)\n\nstatic int __create_guest_mapping(struct mm_struct *mm, virt_addr_t vir,\n\t\tphy_addr_t phy, size_t size, unsigned long flags)\n{\n\tstruct vm *vm = mm_to_vm(mm);\n\tunsigned long tmp;\n\tint ret;\n\n\ttmp = BALIGN(vir + size, PAGE_SIZE);\n\tvir = ALIGN(vir, PAGE_SIZE);\n\tphy = ALIGN(phy, PAGE_SIZE);\n\tsize = tmp - vir;\n\n\tpr_debug(\"map [x%x 0x%x] to [0x%x 0x%x] vm-%d\\n\",\n\t\t\tvir, vir + size, phy, phy + size, vm->vmid);\n\tret = arch_guest_map(mm, vir, vir + size, phy, flags);\n\tif (!ret)\n\t\tret = iommu_iotlb_flush_all(vm);\n\n\treturn ret;\n}\n\nint create_guest_mapping(struct mm_struct *mm, virt_addr_t vir,\n\t\tphy_addr_t phy, size_t size, unsigned long flags)\n{\n\tint ret;\n\n\tspin_lock(&mm->lock);\n\tret = __create_guest_mapping(mm, vir, phy, size, flags);\n\tspin_unlock(&mm->lock);\n\n\treturn ret;\n}\n\nstatic int __destroy_guest_mapping(struct mm_struct *mm,\n\t\tunsigned long vir, size_t size)\n{\n\tunsigned long end;\n\tint ret;\n\n\tif (!IS_PAGE_ALIGN(vir) || !IS_PAGE_ALIGN(size)) {\n\t\tpr_warn(\"WARN: destroy guest mapping [0x%x 0x%x]\\n\",\n\t\t\t\tvir, vir + size);\n\t\tend = PAGE_BALIGN(vir + size);\n\t\tvir = PAGE_ALIGN(vir);\n\t\tsize = end - vir;\n\t}\n\n\tret = arch_guest_unmap(mm, vir, vir + size);\n\tif (!ret)\n\t\tret = iommu_iotlb_flush_all(mm_to_vm(mm));\n\n\treturn ret;\n}\n\nint destroy_guest_mapping(struct mm_struct *mm, unsigned long vir, size_t size)\n{\n\tint ret;\n\n\tspin_lock(&mm->lock);\n\tret = __destroy_guest_mapping(mm, vir, size);\n\tspin_unlock(&mm->lock);\n\n\treturn ret;\n}\n\nstatic struct vmm_area *__alloc_vmm_area_entry(unsigned long base, size_t size)\n{\n\tstruct vmm_area *va;\n\n\tva = zalloc(sizeof(struct vmm_area));\n\tif (!va)\n\t\treturn NULL;\n\n\tva->start = base;\n\tva->pstart = BAD_ADDRESS;\n\tva->end = base + size;\n\tva->flags = 0;\n\n\treturn va;\n}\n\nstatic int __add_free_vmm_area(struct mm_struct *mm, struct vmm_area *area)\n{\n\tstruct vmm_area *tmp, *next, *va = area;\n\tsize_t size;\n\n\t/*\n\t * indicate it not inserted to the free list\n\t */\n\tva->list.next = NULL;\n\tsize = va->end - va->start;\n\tva->flags = 0;\n\tva->vmid = 0;\n\tva->pstart = 0;\nrepeat:\n\t/*\n\t * check whether this two vmm_area can merged to one\n\t * vmm_area and do the action\n\t */\n\tlist_for_each_entry_safe(tmp, next, &mm->vmm_area_free, list) {\n\t\tif (va->start == tmp->end) {\n\t\t\tva->start = tmp->start;\n\t\t\tlist_del(&tmp->list);\n\t\t\tfree(tmp);\n\t\t\tgoto repeat;\n\t\t}\n\n\t\tif (va->end == tmp->start) {\n\t\t\tva->end = tmp->end;\n\t\t\tlist_del(&tmp->list);\n\t\t\tfree(tmp);\n\t\t\tgoto repeat;\n\t\t}\n\n\t\tif (size <= (tmp->end - tmp->start)) {\n\t\t\tlist_insert_before(&tmp->list, &va->list);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (va->list.next == NULL)\n\t\tlist_add_tail(&mm->vmm_area_free, &va->list);\n\n\treturn 0;\n}\n\nstatic void inline release_vmm_area_bk(struct vmm_area *va)\n{\n\tstruct mem_block *block = va->b_head, *tmp;\n\n\twhile (block != NULL) {\n\t\ttmp = block->next;\n\t\tblock->next = NULL;\n\t\tvmm_free_memblock(block);\n\t\tblock = tmp;\n\t}\n\n\tva->b_head = NULL;\n}\n\nstatic void release_vmm_area_memory(struct vmm_area *va)\n{\n\t/*\n\t * can not free the physical memory when the memory\n\t * is not belong to this vmm_area, this means the va\n\t * is shareded with other vmm area, not the owner of\n\t * it.\n\t */\n\tif (va->flags & __VM_SHARED)\n\t\treturn;\n\n\tswitch (va->flags & VM_MAP_TYPE_MASK) {\n\tcase VM_MAP_PT:\n\t\tbreak;\n\tcase VM_MAP_BK:\n\t\trelease_vmm_area_bk(va);\n\t\tbreak;\n\tdefault:\n\t\tif (va->pstart != BAD_ADDRESS) {\n\t\t\tif (va->flags & __VM_SHMEM)\n\t\t\t\tfree_shmem((void *)va->pstart);\n\t\t\telse\n\t\t\t\tfree_pages((void *)va->pstart);\n\t\t\tva->pstart = BAD_ADDRESS;\n\t\t}\n\t\tbreak;\n\t}\n}\n\nint release_vmm_area(struct mm_struct *mm, struct vmm_area *va)\n{\n\trelease_vmm_area_memory(va);\n\tspin_lock(&mm->lock);\n\tlist_del(&va->list);\n\t__add_free_vmm_area(mm, va);\n\tspin_unlock(&mm->lock);\n\n\treturn 0;\n}\n\nstatic int vmm_area_map_ln(struct mm_struct *mm, struct vmm_area *va)\n{\n\treturn __create_guest_mapping(mm, va->start,\n\t\t\tva->pstart, VMA_SIZE(va), va->flags);\n}\n\nstatic int vmm_area_map_bk(struct mm_struct *mm, struct vmm_area *va)\n{\n\tstruct mem_block *block = va->b_head;;\n\tunsigned long base = va->start;\n\tunsigned long size = VMA_SIZE(va);\n\tint ret;\n\n\twhile (block) {\n\t\tret = __create_guest_mapping(mm, base, BFN2PHY(block->bfn),\n\t\t\t\tMEM_BLOCK_SIZE, va->flags | VM_HUGE | VM_GUEST);\n\t\tif (ret)\n\t\t\treturn ret;\n\n\t\tbase += MEM_BLOCK_SIZE;\n\t\tsize -= MEM_BLOCK_SIZE;\n\t\tblock = block->next;\n\t}\n\n\tASSERT(size == 0);\n\n\treturn 0;\n}\n\nint map_vmm_area(struct mm_struct *mm,\n\t\tstruct vmm_area *va, unsigned long pbase)\n{\n\tint ret;\n\n\tswitch (va->flags & VM_MAP_TYPE_MASK) {\n\tcase VM_MAP_PT:\n\t\tva->pstart = va->start;\n\t\tret = vmm_area_map_ln(mm, va);\n\t\tbreak;\n\tcase VM_MAP_BK:\n\t\tret = vmm_area_map_bk(mm, va);\n\t\tbreak;\n\tdefault:\n\t\tva->pstart = pbase;\n\t\tret = vmm_area_map_ln(mm, va);\n\t\tbreak;\n\t}\n\n\treturn ret;\n}\n\nstatic struct vmm_area *__split_vmm_area(struct mm_struct *mm,\n\t\tstruct vmm_area *vma, unsigned long base,\n\t\tunsigned long end, int flags)\n{\n\tstruct vmm_area *left = NULL, *right = NULL;\n\tsize_t left_size, right_size;\n\n\tleft_size = base - vma->start;\n\tright_size = vma->end - end;\n\n\tif (left_size == 0 && right_size == 0)\n\t\tgoto out;\n\n\tif (left_size > 0) {\n\t\tleft = __alloc_vmm_area_entry(vma->start, left_size);\n\t\tif (!left)\n\t\t\treturn NULL;\n\t\tlist_add(&mm->vmm_area_free, &left->list);\n\t}\n\n\tif (right_size > 0) {\n\t\tright = __alloc_vmm_area_entry(end, right_size);\n\t\tif (!right)\n\t\t\tgoto out_err_right;\n\t\tlist_add(&mm->vmm_area_free, &right->list);\n\t}\nout:\n\tvma->start = base;\n\tvma->end = end;\n\tvma->flags = flags;\n\tlist_del(&vma->list);\n\tlist_add_tail(&mm->vmm_area_used, &vma->list);\n\n\treturn vma;\n\nout_err_right:\n\tif (left) {\n\t\tlist_del(&left->list);\n\t\tfree(left);\n\t}\n\treturn NULL;\n}\n\nstatic struct vmm_area *__alloc_free_vmm_area(struct mm_struct *mm,\n\t\tstruct vmm_area *vma, size_t size,\n\t\tunsigned long mask, int flags)\n{\n\tunsigned long base, end;\n\n\tbase = (vma->start + mask) & ~mask;\n\tend = base + size;\n\tif (!((base >= vma->start) && (end <= vma->end)))\n\t\treturn NULL;\n\n\treturn __split_vmm_area(mm, vma, base, end, flags);\n}\n\nstruct vmm_area *alloc_free_vmm_area(struct mm_struct *mm,\n\t\tsize_t size, unsigned long mask, int flags)\n{\n\tstruct vmm_area *va;\n\tstruct vmm_area *new = NULL;\n\n\tmask = (mask == BLOCK_MASK) ? BLOCK_MASK : PAGE_MASK;\n\tsize = BALIGN(size, PAGE_SIZE);\n\n\tspin_lock(&mm->lock);\n\tlist_for_each_entry(va, &mm->vmm_area_free, list) {\n\t\tif ((va->end - va->start) < size)\n\t\t\tcontinue;\n\n\t\tnew = __alloc_free_vmm_area(mm, va, size, mask, flags);\n\t\tif (new)\n\t\t\tbreak;\n\t}\n\tspin_unlock(&mm->lock);\n\n\treturn new;\n}\n\nstruct vmm_area *split_vmm_area(struct mm_struct *mm,\n\t\tunsigned long base, size_t size, int flags)\n{\n\tunsigned long end = base + size;\n\tstruct vmm_area *va, *out = NULL;\n\n\tif ((flags & VM_NORMAL) && (!IS_PAGE_ALIGN(base) || !IS_PAGE_ALIGN(size))) {\n\t\tpr_err(\"vm_area is not PAGE align 0x%p 0x%x\\n\",\n\t\t\t\tbase, size);\n\t\treturn NULL;\n\t}\n\n\tspin_lock(&mm->lock);\n\tlist_for_each_entry(va, &mm->vmm_area_free, list) {\n\t\tif ((base >= va->start) && (end <= va->end)) {\n\t\t\tout = va;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!out)\n\t\tgoto exit;\n\n\tout = __split_vmm_area(mm, out, base, end, flags);\nexit:\n\tspin_unlock(&mm->lock);\n\n\tif (!out)\n\t\tpr_err(\"split vma [0x%lx 0x%lx] failed\\n\", base, end);\n\n\treturn out;\n}\n\nstruct vmm_area *request_vmm_area(struct mm_struct *mm,\n\t\tunsigned long base, unsigned long pbase,\n\t\tsize_t size, int flags)\n{\n\tstruct vmm_area *va;\n\n\tva = split_vmm_area(mm, base, size, flags);\n\tif (!va)\n\t\treturn NULL;\n\n\tva->pstart = pbase;\n\n\treturn va;\n}\n\nstatic void dump_vmm_areas(struct mm_struct *mm)\n{\n\tstruct vmm_area *va;\n\n\tpr_debug(\"***** free vmm areas *****\\n\");\n\tlist_for_each_entry(va, &mm->vmm_area_free, list)\n\t\tpr_debug(\"[VA] 0x%p->0x%p\\n\", va->start, va->end);\n\n\tpr_debug(\"***** used vmm areas *****\\n\");\n\tlist_for_each_entry(va, &mm->vmm_area_used, list)\n\t\tpr_debug(\"[VA] 0x%p->0x%p\\n\", va->start, va->end);\n}\n\nstatic void release_vmm_area_in_vm0(struct vm *vm)\n{\n\tstruct vm *vm0 = get_host_vm();\n\tstruct mm_struct *mm = &vm0->mm;\n\tstruct vmm_area *va, *n;\n\n\tspin_lock(&mm->lock);\n\tlist_for_each_entry_safe(va, n, &mm->vmm_area_used, list) {\n\t\tif (va->vmid != vm->vmid)\n\t\t\tcontinue;\n\n\t\t__destroy_guest_mapping(mm, va->start, VMA_SIZE(va));\n\n\t\tif (!(va->flags & VM_SHARED))\n\t\t\tfree_pages((void *)va->pstart);\n\n\t\tlist_del(&va->list);\n\t\t__add_free_vmm_area(mm, va);\n\t}\n\tspin_unlock(&mm->lock);\n}\n\nint unmap_vmm_area(struct mm_struct *mm, struct vmm_area *va)\n{\n\tint ret;\n\n\tspin_lock(&mm->lock);\n\tret = __destroy_guest_mapping(mm, va->start, VMA_SIZE(va));\n\tspin_unlock(&mm->lock);\t\n\n\treturn ret;\n}\n\nvoid release_vm_memory(struct vm *vm)\n{\n\tstruct mm_struct *mm = &vm->mm;\n\tstruct vmm_area *va, *n;\n\n\t/*\n\t * first unmap all the memory which maped to\n\t * this VM. this will free the pages which used\n\t * as the PAGE_TABLE, then free to the host.\n\t */\n\tdestroy_guest_mapping(mm, 0, VM_IPA_SIZE);\n\n\t/*\n\t * - release all the vmm_area and its memory\n\t * - release the page table\n\t * - set all the mm_struct to 0\n\t * this function will not be called when vm is\n\t * running, do not to require the lock\n\t */\n\tlist_for_each_entry_safe(va, n, &mm->vmm_area_used, list) {\n\t\trelease_vmm_area_memory(va);\n\t\tlist_del(&va->list);\n\t\tfree(va);\n\t}\n\n\tlist_for_each_entry_safe(va, n, &mm->vmm_area_free, list) {\n\t\tlist_del(&va->list);\n\t\tfree(va);\n\t}\n\n\t/* release the vm0's memory belong to this vm */\n\trelease_vmm_area_in_vm0(vm);\n\n\tfree_pages((void *)mm->pgdp);\n}\n\nunsigned long create_hvm_shmem_map(struct vm *vm,\n\t\t\tunsigned long phy, uint32_t size)\n{\n\tstruct vm *vm0 = get_host_vm();\n\tstruct vmm_area *va;\n\n\tva = alloc_free_vmm_area(&vm0->mm, size, PAGE_MASK, VM_GUEST_SHMEM |\n\t\t\tVM_SHARED | VM_RW);\n\tif (!va)\n\t\treturn BAD_ADDRESS;\n\n\tva->vmid = vm->vmid;\n\tmap_vmm_area(&vm0->mm, va, phy);\n\n\treturn va->start;\n}\n\nint copy_from_guest(void *target, void __guest *src, size_t size)\n{\n\tunsigned long start = (unsigned long)src;\n\tsize_t copy_size, left = size;\n\tunsigned long pa;\n\tint ret;\n\n\twhile (left > 0) {\n\t\tcopy_size = PAGE_BALIGN(start) - PAGE_ALIGN(start);\n\t\tif (copy_size == 0)\n\t\t\tcopy_size = PAGE_SIZE;\n\t\tif (copy_size > left)\n\t\t\tcopy_size = left;\n\n\t\tpa = guest_va_to_pa(start, 1);\n\t\tret = create_host_mapping(PAGE_ALIGN(ptov(pa)),\n\t\t\t\tPAGE_ALIGN(pa), PAGE_SIZE, VM_RO);\n\t\tif (ret)\n\t\t\treturn ret;\n\n\t\tmemcpy(target, (void *)vtop(pa), copy_size);\n\t\tdestroy_host_mapping(PAGE_ALIGN(ptov(pa)), PAGE_SIZE);\n\n\t\ttarget += copy_size;\n\t\tstart += copy_size;\n\t\tleft -= copy_size;\n\t}\n\n\treturn 0;\n}\n\nint translate_guest_ipa(struct mm_struct *mm,\n\t\tunsigned long offset, unsigned long *pa)\n{\n\tint ret;\n\n\tspin_lock(&mm->lock);\n\tret = arch_translate_guest_ipa(mm, offset, pa);\n\tspin_unlock(&mm->lock);\n\n\treturn ret;\n}\n\nstatic int do_vm_mmap(struct mm_struct *mm, unsigned long hvm_mmap_base,\n\t\tunsigned long offset, unsigned long size)\n{\n\tstruct vm *vm0 = get_host_vm();\n\tstruct mm_struct *mm0 = &vm0->mm;\n\tunsigned long pa;\n\tint ret;\n\n\tif (!IS_BLOCK_ALIGN(offset) || !IS_BLOCK_ALIGN(hvm_mmap_base) ||\n\t\t\t!IS_BLOCK_ALIGN(size)) {\n\t\tpr_err(\"__vm_mmap fail not PMD align 0x%p 0x%p 0x%x\\n\",\n\t\t\t\thvm_mmap_base, offset, size);\n\t\treturn -EINVAL;\n\t}\n\n\twhile (size > 0) {\n\t\tret = translate_guest_ipa(mm, offset, &pa);\n\t\tif (ret) {\n\t\t\tpr_err(\"addr 0x%x has not mapped in vm-%d\\n\", offset, vm0->vmid);\n\t\t\treturn -EPERM;\n\t\t}\n\n\t\tret = create_guest_mapping(mm0, hvm_mmap_base,\n\t\t\t\tpa, MEM_BLOCK_SIZE, VM_NORMAL | VM_RW);\n\t\tif (ret) {\n\t\t\tpr_err(\"%s failed\\n\", __func__);\n\t\t\treturn ret;\n\t\t}\n\n\t\thvm_mmap_base += MEM_BLOCK_SIZE;\n\t\toffset += MEM_BLOCK_SIZE;\n\t\tsize -= MEM_BLOCK_SIZE;\n\t}\n\n\treturn 0;\n}\n\n/*\n * map the guest vm memory space to vm0 to let vm0 can access\n * the memory space of the guest VM, this function can only\n * map the normal memory for the guest VM, will not map IO\n * memory\n *\n * offset - the base address need to be mapped\n * size - the size need to mapped\n */\nstruct vmm_area *vm_mmap(struct vm *vm, unsigned long offset, size_t size)\n{\n\tstruct vm *vm0 = get_host_vm();\n\tstruct vmm_area *va;\n\tint ret;\n\n\t/*\n\t * allocate all the memory the GVM request but will not\n\t * map all the memory, only map the memory which mvm request\n\t * for linux, if it need use virtio then need to map all\n\t * the memory, but for other os, may not require to map\n\t * all the memory.\n\t */\n\tva = alloc_free_vmm_area(&vm0->mm, size,\n\t\t\tBLOCK_MASK, VM_GUEST_NORMAL | VM_SHARED | VM_RW);\n\tif (!va)\n\t\treturn 0;\n\n\tpr_info(\"%s start:0x%x size:0x%x\\n\", __func__, va->start, size);\n\tret = do_vm_mmap(&vm->mm, va->start, offset, size);\n\tif (ret) {\n\t\tpr_err(\"map guest vm memory to vm0 failed\\n\");\n\t\trelease_vmm_area(&vm0->mm, va);\n\t\treturn NULL;\n\t}\n\n\t/* mark this vmm_area is for guest vm map */\n\tva->vmid = vm->vmid;\n\n\treturn va;\n}\n\nstatic int __alloc_vm_memory(struct mm_struct *mm, struct vmm_area *va)\n{\n\tint i, count;\n\tunsigned long base;\n\tstruct mem_block *block;\n\n\tbase = ALIGN(va->start, MEM_BLOCK_SIZE);\n\tif (base != va->start) {\n\t\tpr_err(\"memory base is not mem_block align\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\tva->b_head = NULL;\n\tva->flags |= VM_MAP_BK;\n\tcount = VMA_SIZE(va) >> MEM_BLOCK_SHIFT;\n\n\t/*\n\t * here get all the memory block for the vm\n\t * TBD: get contiueous memory or not contiueous ?\n\t */\n\tfor (i = 0; i < count; i++) {\n\t\tblock = vmm_alloc_memblock();\n\t\tif (!block)\n\t\t\treturn -ENOMEM;\n\n\t\tblock->next = va->b_head;\n\t\tva->b_head = block;\n\t}\n\n\treturn 0;\n}\n\nint alloc_vm_memory(struct vm *vm)\n{\n\tstruct mm_struct *mm = &vm->mm;\n\tstruct vmm_area *va;\n\n\tlist_for_each_entry(va, &mm->vmm_area_used, list) {\n\t\tif (!(va->flags & VM_NORMAL))\n\t\t\tcontinue;\n\n\t\tif (__alloc_vm_memory(mm, va)) {\n\t\t\tpr_err(\"alloc memory for vm-%d failed\\n\", vm->vmid);\n\t\t\tgoto out;\n\t\t}\n\n\t\tif (map_vmm_area(mm, va, 0)) {\n\t\t\tpr_err(\"map memory for vm-%d failed\\n\", vm->vmid);\n\t\t\tgoto out;\n\t\t}\n\t}\n\n\treturn 0;\nout:\n\trelease_vm_memory(vm);\n\treturn -ENOMEM;\n}\n\nstatic void vmm_area_init(struct mm_struct *mm, int bit64)\n{\n\tunsigned long base, size;\n\tstruct vmm_area *va;\n\n\t/*\n\t * the virtual memory space for a virtual machine:\n\t * 64bit - 40bit (1TB) IPA address space.\n\t * 32bit - 32bit (4GB) IPA address space. (Without LPAE)\n\t * 32bit - TBD (with LPAE)\n\t */\n\tif (bit64) {\n\t\tbase = 0x0;\n\t\tsize = (1UL << 40);\n\t} else {\n#ifdef CONFIG_VM_LPAE\n\t\tbase = 0x0;\n\t\tsize = 0x100000000;\n#else\n\t\tbase = 0x0;\n\t\tsize = 0x100000000;\n#endif\n\t}\n\n\tva = __alloc_vmm_area_entry(base, size);\n\tif (!va)\n\t\tpr_err(\"failed to alloc free vmm_area\\n\");\n\telse\n\t\tlist_add_tail(&mm->vmm_area_free, &va->list);\n}\n\nstatic inline int check_vm_address(struct vm *vm, unsigned long addr)\n{\n\tstruct vmm_area *va;\n\n\tlist_for_each_entry(va, &vm->mm.vmm_area_used, list) {\n\t\tif ((addr >= va->start) && (addr < va->end))\n\t\t\treturn 0;\n\t}\n\n\treturn 1;\n}\n\nstatic int vm_memory_init(struct vm *vm)\n{\n\tstruct memory_region *region;\n\tstruct vmm_area *va;\n\tint ret = 0;\n\n\tif (!vm_is_native(vm))\n\t\treturn 0;\n\n\t/*\n\t * find the memory region which belongs to this\n\t * VM and register to this VM.\n\t */\n\tfor_each_memory_region(region) {\n\t\tif (region->vmid != vm->vmid)\n\t\t\tcontinue;\n\n\t\tva = split_vmm_area(&vm->mm, region->phy_base,\n\t\t\t\tregion->size, VM_NATIVE_NORMAL);\n\t\tif (!va)\n\t\t\treturn -EINVAL;\n\t}\n\n\t/*\n\t * check whether the entry address, setup_data address and load\n\t * address are in the valid memory region.\n\t */\n\tret = check_vm_address(vm, (unsigned long)vm->load_address);\n\tret += check_vm_address(vm, (unsigned long)vm->entry_point);\n\tret += check_vm_address(vm, (unsigned long)vm->setup_data);\n\n\treturn ret;\n}\n\nint vm_mm_struct_init(struct vm *vm)\n{\n\tstruct mm_struct *mm = &vm->mm;\n\n\tmm->pgdp = NULL;\n\tspin_lock_init(&mm->lock);\n\tinit_list(&mm->vmm_area_free);\n\tinit_list(&mm->vmm_area_used);\n\n\tmm->pgdp = arch_alloc_guest_pgd();\n\tif (mm->pgdp == NULL) {\n\t\tpr_err(\"No memory for vm page table\\n\");\n\t\treturn -ENOMEM;\n\t}\n\n\tvmm_area_init(mm, !vm_is_32bit(vm));\n\n\t/*\n\t * attch the memory region to the native vm.\n\t */\n\treturn vm_memory_init(vm);\n}\n\nint vm_mm_init(struct vm *vm)\n{\n\tint ret;\n\tunsigned long base, end, size;\n\tstruct vmm_area *va, *n;\n\tstruct mm_struct *mm = &vm->mm;\n\n\tif (test_and_set_bit(VM_FLAGS_BIT_SKIP_MM_INIT, &vm->flags))\n\t\treturn 0;\n\n\tdump_vmm_areas(&vm->mm);\n\n\t/* just mapping the physical memory for native VM */\n\tlist_for_each_entry(va, &mm->vmm_area_used, list) {\n\t\tif (!(va->flags & __VM_NORMAL))\n\t\t\tcontinue;\n\n\t\tret = map_vmm_area(mm, va, va->start);\n\t\tif (ret) {\n\t\t\tpr_err(\"map mem failed for vm-%d [0x%lx 0x%lx]\\n\",\n\t\t\t\tvm->vmid, va->start, va->end);\n\t\t\treturn ret;\n\t\t}\n\t}\n\n\t/*\n\t * make sure that all the free vmm_area are PAGE aligned\n\t * when caculated the end address need to plus 1.\n\t */\n\tlist_for_each_entry_safe(va, n, &mm->vmm_area_free, list) {\n\t\tbase = BALIGN(va->start, PAGE_SIZE);\n\t\tend = ALIGN(va->end, PAGE_SIZE);\n\t\tsize = end - base;\n\n\t\tif (size < PAGE_SIZE) {\n\t\t\tpr_debug(\"drop unused vmm_area [0x%lx 0x%lx]\\n\",\n\t\t\t\t\tva->start, va->end);\n\t\t\tlist_del(&va->list);\n\t\t\tfree(va);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (size != (va->end - va->start)) {\n\t\t\tpr_debug(\"adjust vma [0x%lx 0x%lx] to [0x%lx->0x%lx]\\n\",\n\t\t\t\t\tva->start, va->end, base, end);\n\t\t\tva->start = base;\n\t\t\tva->end = end;\n\t\t}\n\t}\n\n\treturn 0;\n}\n\nint vmm_has_enough_memory(size_t size)\n{\n\treturn ((size >> MEM_BLOCK_SHIFT) <= free_blocks);\n}\n\nstatic int __vmm_free_memblock(uint32_t bfn)\n{\n\tunsigned long base = bfn << MEM_BLOCK_SHIFT;\n\tstruct block_section *bs = bs_head;\n\n\twhile (bs) {\n\t\tif ((base >= bs->start) && (base < bs->end)) {\n\t\t\tbfn = (base - bs->start) >> MEM_BLOCK_SHIFT;\n\t\t\tclear_bit(bfn, bs->bitmap);\n\t\t\tbs->free_blocks += 1;\n\t\t\tfree_blocks += 1;\n\t\t\treturn 0;\n\t\t}\n\n\t\tbs = bs->next;\n\t}\n\n\tpr_err(\"wrong memory block 0x%x\\n\", bfn);\n\n\treturn -EINVAL;\n}\n\nint vmm_free_memblock(struct mem_block *mb)\n{\n\tuint32_t bfn = mb->bfn;\n\tint ret;\n\n\tfree(mb);\n\tspin_lock(&bs_lock);\n\tret = __vmm_free_memblock(bfn);\n\tspin_unlock(&bs_lock);\n\n\treturn ret;\n}\n\nstatic int get_memblock_from_section(struct block_section *bs, uint32_t *bfn)\n{\n\tuint32_t id;\n\n\tid = find_next_zero_bit_loop(bs->bitmap,\n\t\t\tbs->total_blocks, bs->current_index);\n\tif (id >= bs->total_blocks)\n\t\treturn -ENOSPC;\n\n\tset_bit(id, bs->bitmap);\n\tbs->current_index = id + 1;\n\tbs->free_blocks -= 1;\n\tfree_blocks -= 1;\n\t*bfn = (bs->start >> MEM_BLOCK_SHIFT) + id;\n\n\treturn 0;\n}\n\nstruct mem_block *vmm_alloc_memblock(void)\n{\n\tstruct block_section *bs;\n\tstruct mem_block *mb;\n\tint success = 0, ret;\n\tuint32_t bfn = 0;\n\n\tspin_lock(&bs_lock);\n\tbs = bs_head;\n\twhile (bs) {\n\t\tif (bs->free_blocks != 0) {\n\t\t\tret = get_memblock_from_section(bs, &bfn);\n\t\t\tif (ret == 0) {\n\t\t\t\tsuccess = 1;\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tpr_err(\"memory block content wrong\\n\");\n\t\t\t}\n\t\t}\n\t\tbs = bs->next;\n\t}\n\tspin_unlock(&bs_lock);\n\n\tif (!success)\n\t\treturn NULL;\n\n\tmb = malloc(sizeof(struct mem_block));\n\tif (!mb) {\n\t\tspin_lock(&bs_lock);\n\t\t__vmm_free_memblock(bfn);\n\t\tspin_unlock(&bs_lock);\n\t\treturn NULL;\n\t}\n\n\tmb->bfn = bfn;\n\tmb->next = NULL;\n\n\treturn mb;\n}\n\nvoid vmm_init(void)\n{\n\tstruct memory_region *region;\n\tstruct block_section *bs;\n\tunsigned long start, end;\n\tint size;\n\n\tASSERT(!is_list_empty(&mem_list));\n\n\t/*\n\t * all the free memory will used as the guest VM\n\t * memory. The guest memory will allocated as block.\n\t */\n\tlist_for_each_entry(region, &mem_list, list) {\n\t\tif (region->type != MEMORY_REGION_TYPE_NORMAL)\n\t\t\tcontinue;\n\n\t\t/*\n\t\t * block section need BLOCK align.\n\t\t */\n\t\tstart = BALIGN(region->phy_base, BLOCK_SIZE);\n\t\tend = ALIGN(region->phy_base + region->size, BLOCK_SIZE);\n\t\tif (end - start <= 0) {\n\t\t\tpr_warn(\"VMM drop memory region [0x%lx 0x%lx]\\n\",\n\t\t\t\t\tregion->phy_base,\n\t\t\t\t\tregion->phy_base + region->size);\n\t\t\tcontinue;\n\t\t}\n\n\t\tpr_notice(\"VMM add memory region [0x%lx 0x%lx]\\n\", start, end);\n\t\tbs = malloc(sizeof(struct block_section));\n\t\tASSERT(bs != NULL);\n\t\tbs->start = start;\n\t\tbs->end = end;\n\t\tbs->size = bs->end - bs->start;\n\t\tbs->total_blocks = bs->free_blocks = bs->size >> BLOCK_SHIFT;\n\t\tbs->current_index = 0;\n\t\tfree_blocks += bs->total_blocks;\n\n\t\t/*\n\t\t * allocate the memory for block bitmap.\n\t\t */\n\t\tsize = BITS_TO_LONGS(bs->free_blocks) * sizeof(long);\n\t\tbs->bitmap = malloc(size);\n\t\tASSERT(bs->bitmap != NULL);\n\t\tmemset(bs->bitmap, 0, size);\n\n\t\tbs->next = bs_head;\n\t\tbs_head = bs;\n\t}\n}\n"
  },
  {
    "path": "kernel/virt/vmodule.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <virt/vmodule.h>\n#include <minos/init.h>\n#include <minos/mm.h>\n#include <minos/spinlock.h>\n#include <virt/vm.h>\n\nextern unsigned char __vmodule_start;\nextern unsigned char __vmodule_end;\n\nstatic int vmodule_class_nr = 0;\nstatic LIST_HEAD(vmodule_list);\n\nstatic struct vmodule *create_vmodule(struct module_id *id)\n{\n\tstruct vmodule *vmodule;\n\tvmodule_init_fn fn;\n\n\tvmodule = malloc(sizeof(*vmodule));\n\tif (!vmodule) {\n\t\treturn NULL;\n\t}\n\n\tmemset(vmodule, 0, sizeof(*vmodule));\n\tstrncpy(vmodule->name, id->name, sizeof(vmodule->name) - 1);\n\tinit_list(&vmodule->list);\n\tvmodule->id = vmodule_class_nr++;\n\t\n\t/* call init routine */\n\tif (id->data) {\n\t\tfn = (vmodule_init_fn)id->data;\n\t\tfn(vmodule);\n\t}\n\n\t/*\n\t * always add the vcpu_core module as the first module.\n\t */\n\tif (strcmp(vmodule->name, \"vcpu_core\") == 0)\n\t\tlist_add(&vmodule_list, &vmodule->list);\n\telse\n\t\tlist_add_tail(&vmodule_list, &vmodule->list);\n\n\treturn vmodule;\n}\n\nint register_vcpu_vmodule(const char *name, vmodule_init_fn fn)\n{\n\tstruct vmodule *vmodule;\n\tstruct module_id mid = { .name = name, .comp = NULL, .data = fn };\n\n\tvmodule = create_vmodule(&mid);\n\tif (!vmodule) {\n\t\tpr_err(\"create vmodule %s failed\\n\", name);\n\t\treturn -ENOMEM;\n\t}\n\n\treturn 0;\n}\n\nvoid *get_vmodule_data_by_id(struct vcpu *vcpu, int id)\n{\n\treturn vcpu->context[id];\n}\n\nint vcpu_vmodules_init(struct vcpu *vcpu)\n{\n\tstruct list_head *list;\n\tstruct vmodule *vmodule;\n\tvoid *data;\n\tint size;\n\n\t/*\n\t * firset allocate memory to store each vmodule\n\t * context's context data\n\t */\n\tsize = vmodule_class_nr * sizeof(void *);\n\tif (size == 0)\n\t\treturn 0;\n\n\tvcpu->context = zalloc(size);\n\tASSERT(vcpu->context != NULL);\n\n\tlist_for_each(&vmodule_list, list) {\n\t\tvmodule = list_entry(list, struct vmodule, list);\n\t\tif (vmodule->context_size) {\n\t\t\t/* for reboot if memory is areadly allocated skip it */\n\t\t\tdata = vcpu->context[vmodule->id];\n\t\t\tif (!data) {\n\t\t\t\tdata = malloc(vmodule->context_size);\n\t\t\t\tvcpu->context[vmodule->id] = data;\n\t\t\t}\n\n\t\t\tmemset(data, 0, vmodule->context_size);\n\t\t\tif (vmodule->state_init)\n\t\t\t\tvmodule->state_init(vcpu, data);\n\t\t}\n\t}\n\n\treturn 0;\n}\n\nint vcpu_vmodules_deinit(struct vcpu *vcpu)\n{\n\tstruct vmodule *vmodule;\n\tvoid *data;\n\n\tif (NULL == vcpu->context)\n\t\treturn 0;\n\n\tlist_for_each_entry(vmodule, &vmodule_list, list) {\n\t\tdata = vcpu->context[vmodule->id];\n\t\tif (vmodule->state_deinit)\n\t\t\tvmodule->state_deinit(vcpu, data);\n\n\t\tif (data)\n\t\t\tfree(data);\n\t}\n\n\treturn 0;\n}\n\n#define VCPU_VMODULE_ACTION(action)\t\t\t\t\t\\\n\tvoid action##_vcpu_vmodule_state(struct vcpu *vcpu)\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tstruct vmodule *vmodule;\t\t\t\t\\\n\t\tlist_for_each_entry(vmodule, &vmodule_list, list) {\t\\\n\t\t\tif (vmodule->state_##action) {\t\t\t\\\n\t\t\t\tvmodule->state_##action(vcpu,\t\t\\\n\t\t\t\t\tvcpu->context[vmodule->id]);\t\\\n\t\t\t}\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n\t}\n\nVCPU_VMODULE_ACTION(save)\nVCPU_VMODULE_ACTION(restore)\nVCPU_VMODULE_ACTION(reset)\nVCPU_VMODULE_ACTION(stop)\nVCPU_VMODULE_ACTION(suspend)\nVCPU_VMODULE_ACTION(resume)\nVCPU_VMODULE_ACTION(dump)\n\nstatic int vmodules_init(void)\n{\n\tstruct module_id *mid;\n\tstruct vmodule *vmodule;\n\n\tsection_for_each_item(__vmodule_start, __vmodule_end, mid) {\n\t\tvmodule = create_vmodule(mid);\n\t\tif (!vmodule)\n\t\t\tpr_err(\"create vmodule %s failed\\n\", mid->name);\n\t}\n\n\treturn 0;\n}\nsubsys_initcall(vmodules_init);\n"
  },
  {
    "path": "kernel/virt/vrtc.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <virt/vdev.h>\n#include <asm/io.h>\n#include <minos/irq.h>\n#include <minos/timer.h>\n#include <generic/gvm.h>\n#include <minos/time.h>\n#include <virt/resource.h>\n#include <virt/vmcs.h>\n#include <minos/of.h>\n\n#define\tRTC_DR\t\t0x00\t\t/* Data read register */\n#define\tRTC_MR\t\t0x04\t\t/* Match register */\n#define\tRTC_LR\t\t0x08\t\t/* Data load register */\n#define\tRTC_CR\t\t0x0c\t\t/* Control register */\n#define\tRTC_IMSC\t0x10\t\t/* Interrupt mask and set register */\n#define\tRTC_RIS\t\t0x14\t\t/* Raw interrupt status register */\n#define\tRTC_MIS\t\t0x18\t\t/* Masked interrupt status register */\n#define\tRTC_ICR\t\t0x1c\t\t/* Interrupt clear register */\n#define RTC_PID0\t0xfe0\n#define RTC_PID1\t0xfe4\n#define RTC_PID2\t0xfe8\n#define RTC_PID3\t0xfec\n#define RTC_PCID0\t0xff0\n#define RTC_PCID1\t0xff4\n#define RTC_PCID2\t0xff8\n#define RTC_PCID3\t0xffc\n\n#define RTC_CR_EN\t(1 << 0)\t/* counter enable bit */\n#define RTC_BIT_AI\t(1 << 0)\t/* Alarm interrupt bit */\n\n#define RTC_TIMER_FREQ 32768\n\nstruct vrtc_dev {\n\tstruct vdev vdev;\n\tint rtc_en;\n\tint rtc_int_en;\n\tint rtc_int_trigger;\n\tuint32_t time_base;\n\tuint32_t time_alarm;\n\tuint64_t time_offset;\n\tstruct timer alarm_timer;\n};\n\n#define vdev_to_vrtc(vdev) \\\n\t(struct vrtc_dev *)container_of(vdev, struct vrtc_dev, vdev)\n\nstatic int vrtc_mmio_read(struct vdev *vdev, gp_regs *regs,\n\t\tint idx, unsigned long offset, unsigned long *value)\n{\n\tstruct vrtc_dev *vrtc = vdev_to_vrtc(vdev);\n\tuint64_t t;\n\n\tswitch (offset) {\n\tcase RTC_DR:\n\t\tif (!vrtc->rtc_en)\n\t\t\t*value = 0;\n\t\telse {\n\t\t\tt = NOW() - vrtc->time_offset;\n\t\t\t*value = vrtc->time_base + muldiv64(t, 1, SECONDS(1));\n\t\t}\n\t\tbreak;\n\tcase RTC_MR:\n\t\t/* read the alarm */\n\t\t*value = vrtc->time_alarm;\n\t\tbreak;\n\tcase RTC_LR:\n\t\t*value = vrtc->time_base;\n\t\tbreak;\n\tcase RTC_CR:\n\t\t*value = vrtc->rtc_en;\n\t\tbreak;\n\tcase RTC_IMSC:\n\t\t*value = vrtc->rtc_int_en;\n\t\tbreak;\n\tcase RTC_RIS:\n\t\t*value = vrtc->rtc_int_trigger;\n\t\tbreak;\n\tcase RTC_MIS:\n\t\t*value = !vrtc->rtc_int_en;\n\t\tbreak;\n\tcase RTC_PID0:\n\t\t*value = 0x31;\n\t\tbreak;\n\tcase RTC_PID1:\n\t\t*value = 0x10;\n\t\tbreak;\n\tcase RTC_PID2:\n\t\t*value = 0x04;\n\t\tbreak;\n\tcase RTC_PID3:\n\t\t*value = 0x00;\n\t\tbreak;\n\tcase RTC_PCID0:\n\t\t*value = 0x0d;\n\t\tbreak;\n\tcase RTC_PCID1:\n\t\t*value = 0xf0;\n\t\tbreak;\n\tcase RTC_PCID2:\n\t\t*value = 0x05;\n\t\tbreak;\n\tcase RTC_PCID3:\n\t\t*value = 0xb1;\n\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\nstatic int vrtc_enable(struct vrtc_dev *vrtc, int en)\n{\n\tunsigned long t;\n\n\tif (vrtc->rtc_en == en)\n\t\treturn 0;\n\n\tif (en) {\n\t\t/*\n\t\t * should set it to current time or using\n\t\t * default time 1970-0-0-0 ?\n\t\t */\n\t\ttrap_vcpu(VMTRAP_TYPE_COMMON, VMTRAP_REASON_GET_TIME, 0, &t);\n\t\tvrtc->time_base = t;\n\t\tvrtc->time_offset = NOW();\n\t} else {\n\t\t/* delete the alarm if started */\n\t\tstop_timer(&vrtc->alarm_timer);\n\t\tvrtc->rtc_int_trigger = 0;\n\t\tvrtc->rtc_int_en = 0;\n\t\tvrtc->time_alarm = 0;\n\t\tvrtc->time_base = 0;\n\t\tvrtc->time_offset = 0;\n\t}\n\n\tvrtc->rtc_en = en;\n\treturn 0;\n}\n\nstatic int vrtc_int_enable(struct vrtc_dev *vrtc, int mask)\n{\n\tif (vrtc->rtc_int_en != mask)\n\t\treturn 0;\n\n\t/*\n\t * if the irq has been trigger and the int\n\t * is unmask, then send the virq to the guest\n\t */\n\tif (!mask) {\n\t\tif (vrtc->rtc_int_trigger)\n\t\t\tsend_virq_to_vm(vrtc->vdev.vm, PL031_IRQ);\n\t}\n\n\tvrtc->rtc_int_en = !mask;\n\treturn 0;\n}\n\nstatic int vrtc_set_alarm(struct vrtc_dev *vrtc, uint32_t alarm)\n{\n\tuint64_t timeout;\n\n\tif (alarm <= vrtc->time_base)\n\t\treturn -EINVAL;\n\n\ttimeout = SECONDS(alarm - vrtc->time_base) + vrtc->time_offset;\n\tmod_timer(&vrtc->alarm_timer, timeout);\n\n\treturn 0;\n}\n\nstatic int vrtc_mmio_write(struct vdev *vdev, gp_regs *regs,\n\t\tint idx, unsigned long offset, unsigned long *value)\n{\n\tuint32_t v = *((uint32_t *)value);\n\tstruct vrtc_dev *vrtc = vdev_to_vrtc(vdev);\n\n\tswitch (offset) {\n\tcase RTC_MR:\n\t\t/* set the alarm */\n\t\tvrtc_set_alarm(vrtc, v);\n\t\tbreak;\n\tcase RTC_LR:\n\t\tvrtc->time_offset = NOW();\n\t\tvrtc->time_base = v;\n\t\tbreak;\n\tcase RTC_CR:\n\t\tvrtc_enable(vrtc, v);\n\t\tbreak;\n\tcase RTC_IMSC:\n\t\tvrtc_int_enable(vrtc, v);\n\t\tbreak;\n\tcase RTC_ICR:\n\t\tvrtc->rtc_int_trigger = 0;\n\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\nstatic void vrtc_alarm_function(unsigned long data)\n{\n\tstruct vrtc_dev *vrtc = (struct vrtc_dev *)data;\n\n\tvrtc->rtc_int_trigger = 1;\n\tif (vrtc->rtc_int_en)\n\t\tsend_virq_to_vm(vrtc->vdev.vm, PL031_IRQ);\n}\n\nstatic void vrtc_reset(struct vdev *vdev)\n{\n\t/* do nothing here */\n\tpr_notice(\"vrtc reset\\n\");\n}\n\nstatic void vrtc_deinit(struct vdev *vdev)\n{\n\tstruct vrtc_dev *dev = vdev_to_vrtc(vdev);\n\n\tstop_timer(&dev->alarm_timer);\n\tdev->rtc_en = 0;\n\tdev->rtc_int_en = 0;\n\tdev->rtc_int_trigger = 0;\n\n\tvdev_release(&dev->vdev);\n\tfree(dev);\n}\n\nstatic void *vrtc_init(struct vm *vm, struct device_node *node)\n{\n\tint ret;\n\tuint32_t irq;\n\tstruct vrtc_dev *dev;\n\tuint64_t base, size;\n\tunsigned long flags;\n\n\tpr_notice(\"create virtual rtc for vm-%d\\n\", vm->vmid);\n\n\tret = translate_device_address(node, &base, &size);\n\tif (ret || (size == 0))\n\t\treturn NULL;\n\n\tret = vm_get_device_irq_index(vm, node, &irq, &flags, 0);\n\tif (ret)\n\t\treturn NULL;\n\n\tdev = zalloc(sizeof(struct vrtc_dev));\n\tif (!dev)\n\t\treturn NULL;\n\n\thost_vdev_init(vm, &dev->vdev, \"vrtc\");\n\tif (vdev_add_iomem_range(&dev->vdev, base, size)) {\n\t\tpr_err(\"add iomem for vrtc fail\\n\");\n\t\tfree(dev);\n\t}\n\n\trequest_virq(vm, irq, flags | VIRQF_CAN_WAKEUP);\n\n\tdev->vdev.read = vrtc_mmio_read;\n\tdev->vdev.write = vrtc_mmio_write;\n\tdev->vdev.deinit = vrtc_deinit;\n\tdev->vdev.reset = vrtc_reset;\n\tvdev_add(&dev->vdev);\n\n\tinit_timer(&dev->alarm_timer, vrtc_alarm_function, (unsigned long)dev);\n\n\treturn (void *)dev;\n}\nVDEV_DECLARE(pl031_vrtc, pl031_match_table, vrtc_init);\n"
  },
  {
    "path": "kernel/virt/vwdt.c",
    "content": "/*\n * Copyright (C) 2018 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <minos/minos.h>\n#include <virt/vdev.h>\n#include <asm/io.h>\n#include <minos/irq.h>\n#include <minos/timer.h>\n#include <generic/gvm.h>\n#include <minos/time.h>\n#include <virt/resource.h>\n#include <virt/vmcs.h>\n#include <minos/of.h>\n\n#define SP805_WDT_LOAD\t\t0x00\n#define SP805_WDT_VALUE\t\t0x04\n#define SP805_WDT_CTL\t\t0x08\n#define SP805_WDT_INTCLR\t0x0c\n#define SP805_WDT_RIS\t\t0x10\n#define SP805_WDT_MIS\t\t0x14\n#define SP805_WDT_LOCK\t\t0xc00\n#define SP805_WDT_ITCR\t\t0xf00\n#define SP805_WDT_ITOP\t\t0xf04\n#define SP805_WDT_PRID0\t\t0xfe0\n#define SP805_WDT_PRID1\t\t0xfe4\n#define SP805_WDT_PRID2\t\t0xfe8\n#define SP805_WDT_PRID3\t\t0xfec\n#define SP805_WDT_PCID0\t\t0xff0\n#define SP805_WDT_PCID1\t\t0xff4\n#define SP805_WDT_PCID2\t\t0xff8\n#define SP805_WDT_PCID3\t\t0xffc\n\n#define LOAD_MIN\t\t0x00000001\n#define LOAD_MAX\t\t0xffffffff\n#define INT_ENABLE\t\t(1 << 0)\n#define RESET_ENABLE\t\t(1 << 1)\n#define INT_MASK\t\t(1 << 0)\n#define WDT_LOCK\t\t0x00000001\n#define WDT_UNLOCK\t\t0x1acce551\n#define WDT_CLK_RATE\t\t32768\n\nstruct vwdt_dev {\n\tuint8_t int_enable;\n\tuint8_t reset_enable;\n\tuint8_t int_trigger;\n\tuint8_t access_lock;\n\tunsigned long load_value;\n\tunsigned long timeout_value;\n\tstruct timer wdt_timer;\n\tstruct vdev vdev;\n};\n\n#define vdev_to_vwdt(vdev) \\\n\t(struct vwdt_dev *)container_of(vdev, struct vwdt_dev, vdev)\n\nstatic uint32_t inline wdt_timeleft(struct vwdt_dev *wdt)\n{\n\tunsigned long left = wdt->timeout_value - NOW();\n\n\t/* convert the time to wdt clk rate ticks */\n\treturn (left / 1000000000) * WDT_CLK_RATE;\n}\n\nstatic int vwdt_mmio_read(struct vdev *vdev, gp_regs *regs,\n\t\tint idx, unsigned long offset, unsigned long *value)\n{\n\tstruct vwdt_dev *wdt = vdev_to_vwdt(vdev);\n\n\tswitch (offset) {\n\tcase SP805_WDT_VALUE:\n\t\t*value = (uint32_t)wdt_timeleft(wdt);\n\t\tbreak;\n\tcase SP805_WDT_CTL:\n\t\t*value = wdt->reset_enable << 1 | wdt->int_enable;\n\t\tbreak;\n\tcase SP805_WDT_LOCK:\n\t\t*value = wdt->access_lock;\n\t\tbreak;\n\tcase SP805_WDT_RIS:\n\t\t*value = wdt->int_trigger;\n\t\tbreak;\n\tcase SP805_WDT_MIS:\n\t\t*value = wdt->int_enable;\n\t\tbreak;\n\tcase SP805_WDT_PRID0:\n\t\t*value = 0x5;\n\t\tbreak;\n\tcase SP805_WDT_PRID1:\n\t\t*value = (0x1 << 4) | 0x8;\n\t\tbreak;\n\tcase SP805_WDT_PRID2:\n\t\t*value = (0x1 << 4) | 0x4;\n\t\tbreak;\n\tcase SP805_WDT_PRID3:\n\t\t*value = 0x0;\n\t\tbreak;\n\tcase SP805_WDT_PCID0:\n\t\t*value = 0x0d;\n\t\tbreak;\n\tcase SP805_WDT_PCID1:\n\t\t*value = 0xf0;\n\t\tbreak;\n\tcase SP805_WDT_PCID2:\n\t\t*value = 0x05;\n\t\tbreak;\n\tcase SP805_WDT_PCID3:\n\t\t*value = 0xb1;\n\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\nstatic void vwdt_timer_expire(unsigned long data)\n{\n\tstruct vwdt_dev *wdt = (struct vwdt_dev *)data;\n\n\t/* if the timeout int has already triggered reset\n\t * the system if the reset is enabled */\n\tif (wdt->int_trigger && wdt->reset_enable) {\n\t\tif (vm_is_native(wdt->vdev.vm))\n\t\t\tpanic(\"native vm watchdog timeout\\n\");\n\t\telse\n\t\t\ttrap_vcpu_nonblock(VMTRAP_TYPE_COMMON,\n\t\t\t\t\tVMTRAP_REASON_WDT_TIMEOUT, 0, NULL);\n\t} else {\n\t\tif (wdt->int_enable) {\n\t\t\tsend_virq_to_vm(wdt->vdev.vm, SP805_IRQ);\n\t\t\twdt->int_trigger = 1;\n\t\t\twdt->timeout_value = NOW() + wdt->load_value;\n\t\t\tmod_timer(&wdt->wdt_timer, wdt->timeout_value);\n\t\t}\n\t}\n}\n\nstatic void inline vwdt_config_ctrl(struct vwdt_dev *wdt,\n\t\tint int_enable, int reset_enable)\n{\n\tif (wdt->int_enable != int_enable) {\n\t\twdt->int_enable = int_enable;\n\n\t\tif (int_enable) {\n\t\t\twdt->timeout_value = NOW() + wdt->load_value;\n\t\t\tmod_timer(&wdt->wdt_timer, wdt->timeout_value);\n\t\t} else {\n\t\t\twdt->int_trigger = 0;\n\t\t\tstop_timer(&wdt->wdt_timer);\n\t\t}\n\t}\n\n\tif (wdt->reset_enable != reset_enable)\n\t\twdt->reset_enable = reset_enable;\n}\n\nstatic void inline vwdt_config_intclr(struct vwdt_dev *wdt)\n{\n\twdt->int_trigger = 0;\n\n\t/* reload the value and restart the timer */\n\tif (wdt->int_enable) {\n\t\twdt->timeout_value = NOW() + wdt->load_value;\n\t\tmod_timer(&wdt->wdt_timer, wdt->timeout_value);\n\t}\n}\n\nstatic void inline vwdt_config_load(struct vwdt_dev *wdt, uint32_t v)\n{\n\tunsigned long timeout = 0;\n\n\ttimeout = (v + WDT_CLK_RATE - 1) / WDT_CLK_RATE;\n\twdt->load_value = SECONDS(timeout);\n\tpr_notice(\"set the timeout value to 0x%x 0x%x\\n\",\n\t\t\ttimeout, wdt->load_value);\n}\n\nstatic int vwdt_mmio_write(struct vdev *vdev, gp_regs *regs,\n\t\tint idx, unsigned long offset, unsigned long *value)\n{\n\tuint32_t v = (uint32_t)(*value);\n\tstruct vwdt_dev *wdt = vdev_to_vwdt(vdev);\n\n\tif ((offset != SP805_WDT_LOCK) && wdt->access_lock) {\n\t\tpr_err(\"register is locked of the wdt\\n\");\n\t\treturn -EPERM;\n\t}\n\n\tswitch (offset) {\n\tcase SP805_WDT_LOAD:\n\t\tvwdt_config_load(wdt, v);\n\t\tbreak;\n\tcase SP805_WDT_CTL:\n\t\tvwdt_config_ctrl(wdt, !!(v & INT_ENABLE),\n\t\t\t\t!!(v & RESET_ENABLE));\n\t\tbreak;\n\tcase SP805_WDT_INTCLR:\n\t\tvwdt_config_intclr(wdt);\n\t\tbreak;\n\tcase SP805_WDT_LOCK:\n\t\tif (v == WDT_UNLOCK)\n\t\t\twdt->access_lock = 0;\n\t\telse if (v == WDT_LOCK)\n\t\t\twdt->access_lock = 1;\n\t\telse\n\t\t\tpr_warn(\"unsupport value of wdt_lock\\n\");\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\nstatic void vwdt_reset(struct vdev *vdev)\n{\n\tstruct vwdt_dev *dev = vdev_to_vwdt(vdev);\n\n\tpr_notice(\"vwdt reset\\n\");\n\n\tdev->int_enable = 0;\n\tdev->access_lock = 1;\n\tdev->reset_enable = 0;\n\tdev->int_trigger = 0;\n\tdev->load_value = 0;\n\tdev->timeout_value = 0;\n\tstop_timer(&dev->wdt_timer);\n}\n\nstatic void vwdt_deinit(struct vdev *vdev)\n{\n\tstruct vwdt_dev *dev = vdev_to_vwdt(vdev);\n\n\tstop_timer(&dev->wdt_timer);\n\tdev->int_enable = 0;\n\tdev->access_lock = 1;\n\tdev->reset_enable = 0;\n\tdev->int_trigger = 0;\n\n\tvdev_release(&dev->vdev);\n\tfree(dev);\n}\n\nstatic void *vwdt_init(struct vm *vm, struct device_node *node)\n{\n\tint ret;\n\tuint32_t irq;\n\tstruct vwdt_dev *dev;\n\tuint64_t base, size;\n\tunsigned long flags;\n\n\tpr_notice(\"create virtual watchdog for vm-%d\\n\", vm->vmid);\n\n\tret = translate_device_address(node, &base, &size);\n\tif (ret || (size == 0))\n\t\treturn NULL;\n\n\tret = vm_get_device_irq_index(vm, node, &irq, &flags, 0);\n\tif (ret)\n\t\treturn NULL;\n\n\tdev = zalloc(sizeof(struct vwdt_dev));\n\tif (!dev)\n\t\treturn NULL;\n\n\thost_vdev_init(vm, &dev->vdev, \"vwdt\");\n\tif (vdev_add_iomem_range(&dev->vdev, base, size)) {\n\t\tpr_err(\"add iomem for vwdt failed\\n\");\n\t\tfree(dev);\n\t\treturn NULL;\n\t}\n\n\trequest_virq(vm, irq, 0);\n\n\tdev->access_lock = 1;\n\tdev->vdev.read = vwdt_mmio_read;\n\tdev->vdev.write = vwdt_mmio_write;\n\tdev->vdev.deinit = vwdt_deinit;\n\tdev->vdev.reset = vwdt_reset;\n\tvdev_add(&dev->vdev);\n\n\tinit_timer(&dev->wdt_timer, vwdt_timer_expire,\n\t\t\t(unsigned long)dev);\n\n\treturn NULL;\n}\nVDEV_DECLARE(sp805_wdt, sp805_match_table, vwdt_init);\n"
  },
  {
    "path": "scripts/app_build.mk",
    "content": "ARCH \t\t?= $(TARGET_ARCH)\nCROSS_COMPILE \t?= $(TARGET_CROSS_COMPILE)\n\nifeq ($(TARGET_APP_CC),)\n  CC = musl-gcc\nelse\n  CC = $(TARGET_APP_CC)\nendif\n\nLD \t\t:= $(CROSS_COMPILE)ld\nOBJ_COPY\t:= $(CROSS_COMPILE)objcopy\nOBJ_DUMP \t:= $(CROSS_COMPILE)objdump\nNM\t\t:= $(CROSS_COMPILE)nm\nSTRIP\t\t:= $(CROSS_COMPILE)strip\n\nPWD\t\t:= $(shell pwd)\n\nifeq ($(VERBOSE),1)\n  QUIET =\nelse\n  QUIET = @\nendif\n\nifeq ($(QUIET),@)\nPROGRESS = @echo Compiling $@ ...\nendif\n\nifeq ($(BUILD_DEBUG), 1)\n  O_LEVEL=0\nelse\n  O_LEVEL=2\nendif\n\nifeq ($(TARGET),)\n  $(error \"target is not defined\")\nendif\n\nifeq ($(APP_TAG),)\n  APP_TAG = $(TARGET)\nendif\n\nDBG_TAG = $(basename $(APP_TAG))\n\nAPP_INSTALL_DIR ?= rootfs/bin\n\nLINK_LIBS = $(addprefix -l, $(APP_LINK_LIBS))\n__LIBS_DEPS = $(addprefix $(TARGET_LIBS_DIR)/lib, $(APP_LINK_LIBS))\nLIBS_DEPS = $(addsuffix .a, $(__LIBS_DEPS))\nLIBS_DEPS += $(TARGET_LIBS_DIR)/libc.a\n\nCFLAGS := -Wall -g -D_XOPEN_SOURCE -D_GNU_SOURCE \\\n\t-Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing \\\n\t-fno-common -Werror-implicit-function-declaration -O$(O_LEVEL) \\\n\t-Wno-format-security -I$(TARGET_INCLUDE_DIR) -I$(UAPI_INCLUDE_DIR)\n\nLDFLAGS :=\nLDFLAGS += $(APP_LDFLAGS)\n\nCFLAGS\t+= --static -L$(TARGET_LIBS_DIR) -DAPP_TAG=\\\"$(DBG_TAG)\\\" $(LINK_LIBS)\nCFLAGS\t+= $(APP_CFLAGS)\nCFLAGS  += -MD -MP\n\nifeq ($(BUILD_DEBUG),1)\n  CFLAGS += -g\nendif\n\nifeq ($(ARCH),aarch64)\n  CFLAGS += -march=armv8-a\nendif\n\nifneq ($(TEXT_START),)\n  CFLAGS += -Wl,-Ttext=$(TEXT_START)\nendif\n\nsrc_c\t:= $(SRC_C)\nsrc_s\t:= $(SRC_S)\n\nOBJS\t:= $(src_c:%.c=%.o)\nOBJS\t+= $(src_s:%.S=%.o)\n\nOBJS_D\t= $(OBJS:%.o=%.d)\n\n$(TARGET) : $(OBJS) $(LIBS_DEPS)\n\t$(PROGRESS)\n\t$(QUIET) $(CC) $^ -o $@ $(LDFLAGS) $(CFLAGS)\n\t$(QUIET) echo \"Build $(TARGET) Done ...\"\n\n%.o : %.c\n\t$(PROGRESS)\n\t$(QUIET) $(CC) $(CFLAGS) -c $< -o $@\n\n%.o : %.S\n\t$(PROGRESS)\n\t$(QUIET) $(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $@\n\n.PHONY: clean distclean install\n\n$(TARGET_OUT_DIR)/$(APP_INSTALL_DIR)/%: %\n\t$(TARGET_INSTALL) -D -m 755 $< $@\n\t$(STRIP) -s $@\n\ninstall: $(TARGET_OUT_DIR)/$(APP_INSTALL_DIR)/$(TARGET)\n\nclean:\n\t$(QUIET) rm -rf $(TARGET) $(OBJS) $(LDS) $(OBJS_D)\n\ndistclean: clean\n\trm -rf cscope.in.out cscope.out cscope.po.out tags\n\n-include $(OBJS_D)\n"
  },
  {
    "path": "scripts/lib_build.mk",
    "content": "ARCH \t\t?= $(TARGET_ARCH)\nCROSS_COMPILE \t?= $(TARGET_CROSS_COMPILE)\n\nifeq ($(TARGET_APP_CC),)\n  CC = musl-gcc\nelse\n  CC = $(TARGET_APP_CC)\nendif\n\nLD \t\t:= $(CROSS_COMPILE)ld\nOBJ_COPY\t:= $(CROSS_COMPILE)objcopy\nOBJ_DUMP \t:= $(CROSS_COMPILE)objdump\nNM\t\t:= $(CROSS_COMPILE)nm\nSTRIP\t\t:= $(CROSS_COMPILE)strip\n\nPWD\t\t:= $(shell pwd)\n\nifeq ($(VERBOSE),1)\n  QUIET =\nelse\n  QUIET = @\nendif\n\nifeq ($(QUIET),@)\nPROGRESS = @echo Compiling $@ ...\nendif\n\nifeq ($(BUILD_DEBUG), 1)\n  O_LEVEL=0\nelse\n  O_LEVEL=2\nendif\n\nifeq ($(TARGET),)\n  $(error \"target is not defined\")\nendif\n\nifeq ($(APP_TAG),)\n  APP_TAG = $(TARGET)\nendif\n\nDBG_TAG = $(basename $(APP_TAG))\n\nCFLAGS := -Wall -D_XOPEN_SOURCE -D_GNU_SOURCE \\\n\t-Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing \\\n\t-fno-common -Werror-implicit-function-declaration -O$(O_LEVEL) \\\n\t-Wno-format-security -I$(TARGET_INCLUDE_DIR) -I$(UAPI_INCLUDE_DIR)\n\nCFLAGS\t+= $(LIB_CFLAGS)\nCFLAGS  += -MD -MP\nCFLAGS\t+= -DAPP_TAG=\\\"$(DBG_TAG)\\\"\n\nifeq ($(BUILD_DEBUG),1)\n  CFLAGS += -g\nendif\n\nifeq ($(ARCH),aarch64)\n  CFLAGS += -march=armv8-a\nendif\n\nsrc_c\t:= $(SRC_C)\nsrc_s\t:= $(SRC_S)\n\nOBJS\t:= $(src_c:%.c=%.o)\nOBJS\t+= $(src_s:%.S=%.o)\n\nOBJS_D\t= $(OBJS:%.o=%.d)\n\n$(TARGET) : $(OBJS)\n\t$(PROGRESS)\n\t$(QUIET) $(AR) crv $@ $^\n\t$(QUIET) echo \"Build $(TARGET) Done ...\"\n\n%.o : %.c\n\t$(PROGRESS)\n\t$(QUIET) $(CC) $(CFLAGS) -c $< -o $@\n\n%.o : %.S\n\t$(PROGRESS)\n\t$(QUIET) $(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $@\n\n.PHONY: clean distclean install\n\n$(TARGET_INCLUDE_DIR)/%: $(PWD)/include/%\n\t$(TARGET_INSTALL) -D -m 644 $< $@\n\n$(TARGET_LIBS_DIR)/%: %\n\t$(TARGET_INSTALL) -D -m 755 $< $@\n\ninstall-headers: $(INSTALL_HEADERS:include/%=$(TARGET_INCLUDE_DIR)/%)\ninstall-libs: $(TARGET_LIBS_DIR)/$(TARGET)\n\ninstall: install-headers install-libs\n\nclean:\n\t$(QUIET) rm -rf $(TARGET) $(OBJS) $(LDS) $(OBJS_D)\n\ndistclean: clean\n\trm -rf cscope.in.out cscope.out cscope.po.out tags\n\n-include $(OBJS_D)\n"
  },
  {
    "path": "tools/install.sh",
    "content": "#!/bin/sh\n#\n# This is an actually-safe install command which installs the new\n# file atomically in the new location, rather than overwriting\n# existing files.\n#\n\nusage() {\nprintf \"usage: %s [-D] [-l] [-m mode] src dest\\n\" \"$0\" 1>&2\nexit 1\n}\n\nmkdirp=\nsymlink=\nmode=755\n\nwhile getopts Dlm: name ; do\ncase \"$name\" in\nD) mkdirp=yes ;;\nl) symlink=yes ;;\nm) mode=$OPTARG ;;\n?) usage ;;\nesac\ndone\nshift $(($OPTIND - 1))\n\ntest \"$#\" -eq 2 || usage\nsrc=$1\ndst=$2\ntmp=\"$dst.tmp.$$\"\n\ncase \"$dst\" in\n*/) printf \"%s: %s ends in /\\n\", \"$0\" \"$dst\" 1>&2 ; exit 1 ;;\nesac\n\nset -C\nset -e\n\nif test \"$mkdirp\" ; then\numask 022\ncase \"$2\" in\n*/*) mkdir -p \"${dst%/*}\" ;;\nesac\nfi\n\ntrap 'rm -f \"$tmp\"' EXIT INT QUIT TERM HUP\n\numask 077\n\nif test \"$symlink\" ; then\nln -s \"$1\" \"$tmp\"\nelse\ncat < \"$1\" > \"$tmp\"\nchmod \"$mode\" \"$tmp\"\nfi\n\nmv -f \"$tmp\" \"$2\"\ntest -d \"$2\" && {\nrm -f \"$2/$tmp\"\nprintf \"%s: %s is a directory\\n\" \"$0\" \"$dst\" 1>&2\nexit 1\n}\n\nexit 0\n"
  },
  {
    "path": "tools/make_ramdisk.sh",
    "content": "#!/bin/bash\n\n# SPDX-License-Identifier: ISC\n\nset -e -o pipefail\n\nMAGIC_SIZE=16\nSB_SIZE=$(((32 + 32 + 64 + 64) / 8))\nFNAME_SIZE=32\nINODE_SIZE=$((FNAME_SIZE + (64 + 64) / 8))\n\nprint_help() {\n    cat << EOF\nUsage: $(basename ${0}) -o IMAGE -- [FILE]...\nPack FILE(s) into IMAGE as Minos ramdisk.\nExamples:\n    # Pack list of files into ramdisk\n    $(basename ${0}) -o IMAGE -- KERNEL FDT\n    # Pack top-level files in directory into ramdisk\n    $(basename ${0}) -o IMAGE -- DIR/*\nEOF\n}\n\n# ${1}: bit\n# ${2}: number\nencode_number() {\n    local len=$((${1} / 8 * 2))\n    local hex=$(printf \"%0${len}x\" ${2})\n\n    local i=${len}\n    while ((i > 0)); do\n        i=$((i - 2))\n        printf \"\\x${hex:i:2}\"\n    done\n}\n\n# ${1}: file\npack_file() {\n    printf \"%.*s\\0\" $((FNAME_SIZE - 1)) $(basename ${1}) |\n        dd conv=notrunc obs=${off1} of=${image} seek=1 2> /dev/null\n\n    local size=$(stat -c \"%s\" ${1})\n    {\n        encode_number 64 ${off2}\n        encode_number 64 ${size}\n    } |\n        dd conv=notrunc obs=$((off1 + FNAME_SIZE)) of=${image} seek=1 2> /dev/null\n\n    dd conv=notrunc if=${1} obs=${off2} of=${image} seek=1 2> /dev/null\n\n    off1=$((off1 + INODE_SIZE))\n    off2=$((off2 + size))\n}\n\nmake_ramdisk() {\n    {\n        printf \"MINOSRAMDISK....\"\n        encode_number 32 ${#files[@]}\n        encode_number 32 0\n        encode_number 64 $((MAGIC_SIZE + SB_SIZE))\n        encode_number 64 0\n    } |\n        dd conv=notrunc of=${image} 2> /dev/null\n\n    local file\n    for file in ${files[@]}; do\n        printf \"Packing %.*s\\n\" $((FNAME_SIZE - 1)) $(basename ${file})\n        pack_file ${file}\n    done\n\n    printf \"Done\\n\"\n}\n\nfilter_files() {\n    local i\n    for i in ${!files[@]}; do\n        if [[ ! -f ${files[i]} ]]; then\n            unset files[i]\n        fi\n    done\n}\n\n# files: input files\n# image: output image\n# off1: inode offset\n# off2: file offset\nmain() {\n    while (($# > 0)); do\n        case ${1} in\n        -o)\n            image=${2}\n            shift\n            shift || true\n            ;;\n        --)\n            shift\n            break\n            ;;\n        *)\n            printf \"Invalid option '%s'\\n\" ${1}\n            print_help\n            exit 2\n            ;;\n        esac\n    done\n\n    if [[ -z ${image} ]]; then\n        printf \"Missing option '-o'\\n\"\n        print_help\n        exit 2\n    fi\n\n    files=($@)\n    filter_files\n\n    off1=$((MAGIC_SIZE + SB_SIZE))\n    off2=$((MAGIC_SIZE + SB_SIZE + INODE_SIZE * ${#files[@]}))\n\n    rm -f ${image}\n    make_ramdisk\n}\n\nmain $@\n"
  },
  {
    "path": "tools/mkrmd/Makefile",
    "content": "all: mkrmd\n\nCFLAGS := -Wall -g -D_XOPEN_SOURCE -D_GNU_SOURCE \\\n\t-Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing \\\n\t-fno-common -Werror-implicit-function-declaration -Wno-format-overflow \\\n\t-Wno-format-security -I../../generic/include -MD -MP\n\nmkrmd: mkrmd.c\n\t@ echo \"  Building mkrmd ...\"\n\t@ gcc mkrmd.c -o mkrmd $(CFLAGS)\n\n.PHONY: clean\n\nclean:\n\t@rm -f mkrmd.o mkrmd mkrmd.d\n\n-include mkrmd.d\n"
  },
  {
    "path": "tools/mkrmd/mkrmd.c",
    "content": "/*\n * Copyright (C) 2022 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <unistd.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <sys/mman.h>\n#include <fcntl.h>\n#include <dirent.h>\n#include <sys/types.h>\n#include <errno.h>\n#include <string.h>\n\n#include <uapi/ramdisk.h>\n\n#define MODE_NULL 0x0\n#define MODE_DIR 0x1\n#define MODE_FILE 0x2\n\nstruct ramdisk_sb ramdisk_sb;\n\nstruct memblock {\n\tsize_t size;\n\tsize_t free;\n\tsize_t used;\n\tvoid *mem;\n};\n\nstruct memblock imem;\nstruct memblock fmem;\n\n#define FMEMBLOCK_SIZE 128 * 1024 * 1024\n#define IMEMBLOCK_SIZE 32 * 1024 * 1024\n\nstatic void print_help(void)\n{\n\tprintf(\"mkrmd Usage:\\n\");\n\tprintf(\"    mkrmd -d $target /tmp/ramdisk/\\n\");\n\tprintf(\"    mkrmd -f $target vm0.img vm1.img\\n\");\n}\n\nstatic void memblock_init(void)\n{\n\timem.used = 0;\n\timem.size = imem.free = IMEMBLOCK_SIZE;\n\timem.mem = malloc(imem.free);\n\n\tfmem.used = 0;\n\tfmem.size = fmem.free = FMEMBLOCK_SIZE;\n\tfmem.mem = malloc(fmem.free);\n\n\tif (!imem.mem || !fmem.mem) {\n\t\tprintf(\"alloc memory for ramdisk failed\\n\");\n\t\texit(-ENOMEM);\n\t}\n}\n\nstatic int add_new_file(char *name, size_t size)\n{\n\tstruct ramdisk_inode *inode;\n\tsize_t total_size;\n\n\tif (imem.free <= sizeof(struct ramdisk_inode))\n\t\treturn -ENOMEM;\n\n\tinode = (struct ramdisk_inode *)(imem.mem + imem.used);\n\tinode->f_offset = fmem.used;\n\tinode->f_size = size;\n\tmemset(inode->f_name, 0, RAMDISK_FNAME_SIZE);\n\tstrcpy(inode->f_name, name);\n\n\tprintf(\"%s f_offset 0x%lx 0%lx\\n\", name,\n\t\t\tinode->f_offset, inode->f_size);\n\n\timem.used += sizeof(struct ramdisk_inode);\n\timem.free -= sizeof(struct ramdisk_inode);\n\n\t/*\n\t * whether read() will read last char EOF of an file ?\n\t * if not, need add it.\n\t */\n\tramdisk_sb.file_cnt += 1;\n\n\t/*\n\t * file memory need PAGE_SIZE (4096) aligned.\n\t */\n\ttotal_size = (size + 4095) & ~(4095);\n\tfmem.used += size;\n\n\t/*\n\t * adjust it.\n\t */\n\tsize = total_size - size;\n\tif (size > 0) {\n\t\tmemset(fmem.mem + fmem.used, 0, size);\n\t\tfmem.used += size;\n\t\tfmem.free -= size;\n\t}\n\n\treturn 0;\n}\n\nstatic int __add_file(int fd, char *name)\n{\n\tsize_t size = 0, cnt, read_size;\n\tchar *base = fmem.mem + fmem.used;\n\n\twhile (1) {\n\t\tif (fmem.free == 0) {\n\t\t\tprintf(\"no more memory in fmemblock\\n\");\n\t\t\treturn -ENOMEM;\n\t\t}\n\n\t\tread_size = fmem.free > 4096 ? 4096 : fmem.free;\n\t\tcnt = read(fd, base, read_size);\n\t\tif (cnt == 0)\n\t\t\tbreak;\n\n\t\tsize += cnt;\n\t\tbase += cnt;\n\t\tfmem.free -= cnt;\n\t}\n\n\tif (size == 0) {\n\t\tprintf(\"%s size is 0\\n\", name);\n\t\treturn 0;\n\t}\n\n\tif (add_new_file(name, size)) {\n\t\tprintf(\"no more memory in inode memory\\n\");\n\t\treturn -ENOMEM;\n\t}\n\n\treturn 0;\n}\n\nstatic int add_file(char *path)\n{\n\tchar *name;\n\tint fd, ret;\n\n\tfd = open(path, O_RDONLY);\n\tif (fd < 0) {\n\t\tprintf(\"open %s failed\\n\", path);\n\t\treturn fd;\n\t}\n\n\t/*\n\t * get the ramdisk file name.\n\t */\n\tname = strrchr(path, '/');\n\tif (name == NULL)\n\t\tname = path;\n\telse\n\t\tname = name + 1;\n\n\tret = __add_file(fd, name);\n\n\tclose(fd);\n\n\treturn ret;\n}\n\nstatic int make_ramdisk_file_mode(int cnt, char **filep)\n{\n\tint i;\n\n\tfor (i = 0; i < cnt; i++) {\n\t\tif (add_file(filep[i]))\n\t\t\treturn -ENOENT;\n\t}\n\n\treturn 0;\n}\n\nstatic int make_ramdisk_dir_mode(char *dirname)\n{\n\tstruct dirent *dirp;\n\tchar path[256];\n\tDIR *dp;\n\n\tif (dirname[strlen(dirname) - 1] == '/')\n\t\tdirname[strlen(dirname)] = 0;\n\n\tdp = opendir(dirname);\n\tif (dp == NULL) {\n\t\tprintf(\"can not open directory %s\\n\", dirname);\n\t\treturn -ENOENT;\n\t}\n\n\twhile ((dirp = readdir(dp)) != NULL) {\n\t\tif (!strcmp(dirp->d_name, \".\") || !strcmp(dirp->d_name, \"..\"))\n\t\t\tcontinue;\n\t\t\n\t\tif (dirp->d_type != 8) {\n\t\t\tprintf(\"skip %s\\n\", dirp->d_name);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif ((strlen(dirname) + strlen(dirp->d_name)) > 255 ||\n\t\t\t\t(strlen(dirp->d_name) + 1) > RAMDISK_FNAME_SIZE) {\n\t\t\tprintf(\"skip file %s: filename too long\\n\", dirp->d_name);\n\t\t\tcontinue;\n\t\t}\n\n\t\tsprintf(path, \"%s/%s\", dirname, dirp->d_name);\n\t\tadd_file(path);\n\t}\n\n\tclosedir(dp);\n\n\treturn 0;\n}\n\nstatic int packing_ramdisk(int fd)\n{\n\t/*\n\t * write the ramdisk magic.\n\t */\n\tchar magic[RAMDISK_MAGIC_SIZE] = {0};\n\tunsigned long inode_offset;\n\tunsigned long file_offset;\n\tint ret;\n\n\tmemcpy(magic, RAMDISK_MAGIC, RAMDISK_MAGIC_SIZE);\n\tret = write(fd, magic, RAMDISK_MAGIC_SIZE);\n\tif (ret != RAMDISK_MAGIC_SIZE) {\n\t\tprintf(\"write ramdisk magic failed\\n\");\n\t\treturn -EIO;\n\t}\n\n\tinode_offset = RAMDISK_MAGIC_SIZE + sizeof(struct ramdisk_sb);\n\tinode_offset = (inode_offset + 15) & ~(15);\t// 16 byte align\n\tramdisk_sb.inode_offset = inode_offset;\n\n\tfile_offset = inode_offset + imem.used;\n\tfile_offset = (file_offset + 4095) & ~(4095);\t// 4096 byte align\n\tramdisk_sb.data_offset = file_offset; \n\n\tramdisk_sb.ramdisk_size = ramdisk_sb.data_offset + fmem.used;\n\tramdisk_sb.ramdisk_size = (ramdisk_sb.ramdisk_size) & ~(4095);\n\n\t/*\n\t * write the superblock.\n\t */\n\tret = write(fd, &ramdisk_sb, sizeof(struct ramdisk_sb));\n\tif (ret != sizeof(struct ramdisk_sb)) {\n\t\tprintf(\"write ramdisk super block failed\\n\");\n\t\treturn -EIO;\n\t}\n\n\t/*\n\t * write inode.\n\t */\n\tret = lseek(fd, inode_offset, SEEK_SET);\n\tif (ret < 0) {\n\t\tprintf(\"seek indoe offset failed\\n\");\n\t\treturn -EIO;\n\t}\n\n\tret = write(fd, imem.mem, imem.used);\n\tif (ret != imem.used) {\n\t\tprintf(\"write inode data failed\\n\");\n\t\treturn -EIO;\n\t}\n\n\t/*\n\t * write data\n\t */\n\tret = lseek(fd, file_offset, SEEK_SET);\n\tif (ret < 0) {\n\t\tprintf(\"seek file offset failed\\n\");\n\t\treturn -EIO;\n\t}\n\n\tret = write(fd, fmem.mem, fmem.used);\n\tif (ret != fmem.used) {\n\t\tprintf(\"write file data failed\\n\");\n\t\treturn -EIO;\n\t}\n\n\treturn 0;\n}\n\nint main(int argc, char **argv)\n{\n\tint mode = MODE_NULL;\n\tint ret;\n\tint target;\n\n\tif (argc < 4) {\n\t\tprint_help();\n\t\texit(-1);\n\t}\n\n\tif (strcmp(argv[1], \"-d\") == 0)\n\t\tmode = MODE_DIR;\n\telse if (strcmp(argv[1], \"-f\") == 0)\n\t\tmode = MODE_FILE;\n\n\tif (mode == MODE_NULL) {\n\t\tprintf(\"unsupported mode\\n\");\n\t\tprint_help();\n\t\texit(-1);\n\t}\n\n\tprintf(\"open or create target file [%s]\\n\", argv[2]);\n\ttarget = open(argv[2], O_RDWR | O_CREAT, 0666);\n\tif (target < 0) {\n\t\tprintf(\"can not open target file %d\\n\", errno);\n\t\treturn target;\n\t}\n\n\tmemblock_init();\n\n\tprintf(\"create ramdisk using %s mode\\n\", mode == MODE_DIR ? \"DIR\" : \"FILE\");\n\tif (mode == MODE_DIR)\n\t\tret = make_ramdisk_dir_mode(argv[3]);\n\telse\n\t\tret = make_ramdisk_file_mode(argc - 3, &argv[3]);\n\tif (ret) {\n\t\tprintf(\"create %s failed wit %d\\n\", argv[2], ret);\n\t\tgoto out;\n\t}\n\n\tret = packing_ramdisk(target);\n\tif (!ret) {\n\t\tprintf(\"generate ramdisk %s done\\n\", argv[2]);\n\t\tprintf(\"file_cnt %d inode_offset 0x%lx data_offset 0x%lx\\n\",\n\t\t\t\t\tramdisk_sb.file_cnt,\n\t\t\t\t\tramdisk_sb.inode_offset,\n\t\t\t\t\tramdisk_sb.data_offset);\n\t\tprintf(\"ramdisk size 0x%lx\\n\", ramdisk_sb.ramdisk_size);\n\t}\n\nout:\n\tclose(target);\n\n\treturn ret;\n}\n"
  },
  {
    "path": "tools/qemu.sh",
    "content": "#!/bin/bash\n\nqemu-system-aarch64 -nographic -machine virt -bios u-boot.bin -cpu cortex-a57 -smp 4 -m 2G \\\n    -drive if=none,file=sd.img,format=raw,id=hd0 \\\n    -device virtio-blk-device,drive=hd0\n"
  },
  {
    "path": "user.driver/virtio-blk/Makefile",
    "content": "TARGET \t\t:= virtio-blk.drv\nAPP_LINK_LIBS \t:= lwext4\nAPP_CFLAGS\t:= -DCONFIG_USE_DEFAULT_CFG\n\nSRC_C\t\t:= $(wildcard *.c)\n\nTEXT_START\t:= 0x2000000\n\nAPP_INSTALL_DIR := ramdisk\n\ninclude $(projtree)/scripts/app_build.mk\n"
  },
  {
    "path": "user.driver/virtio-blk/main.c",
    "content": "/*\n * Copyright (C) 2020 Min Le (lemin9538@gmail.com)\n */\n\n#include <stdio.h>\n#include <unistd.h>\n#include <inttypes.h>\n#include <stdlib.h>\n#include <string.h>\n#include <getopt.h>\n#include <errno.h>\n#include <minos/debug.h>\n#include <minos/list.h>\n#include <minos/device.h>\n\n#include \"virtio.h\"\n\nstatic int irq_handle, mmio_handle;\n\nint main(int argc, char **argv)\n{\n\tint ret;\n\tvoid *mmio;\n\n\tmmio_handle = get_device_mmio_handle(\"virtio,mmio\", 0);\n\tirq_handle = get_device_irq_handle(\"virtio,mmio\", 0);\n\tif (irq_handle <= 0 || mmio_handle <= 0) {\n\t\tpr_err(\"virtio-blk: wrong irq or mmio information\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\tmmio = request_mmio_by_handle(mmio_handle);\n\tif (mmio == (void *)-1)\n\t\treturn -EACCES;\n\n\tret = request_irq_by_handle(irq_handle);\n\tif (ret) {\n\t\tpr_err(\"failed to request virtio block irq\\n\");\n\t\treturn -EIO;\n\t}\n\n\treturn virtio_dev_init((unsigned long)mmio, irq_handle);\n}\n"
  },
  {
    "path": "user.driver/virtio-blk/virtio-blk.c",
    "content": "/**\n * Block device driver based on virtio.\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <inttypes.h>\n#include <errno.h>\n#include <sys/mman.h>\n\n#include <minos/debug.h>\n#include <minos/list.h>\n#include <minos/types.h>\n#include <minos/sched.h>\n#include <minos/kobject.h>\n#include <minos/proto.h>\n#include <minos/service.h>\n#include <minos/device.h>\n\n#include <lwext4/ext4_blkdev.h>\n\n#include \"virtio.h\"\n\n#define VFS_MAX_EVENTS 16\n\nstruct virtio_cap blk_caps[] = {\n\t{ \"VIRTIO_BLK_F_SIZE_MAX\", 1, false,\n\t  \"Maximum size of any single segment is in size_max.\" },\n\t{ \"VIRTIO_BLK_F_SEG_MAX\", 2, false,\n\t  \"Maximum number of segments in a request is in seg_max.\" },\n\t{ \"VIRTIO_BLK_F_GEOMETRY\", 4, false,\n\t  \"Disk-style geometry specified in geometry.\" },\n\t{ \"VIRTIO_BLK_F_RO\", 5, false, \"Device is read-only.\" },\n\t{ \"VIRTIO_BLK_F_BLK_SIZE\", 6, false,\n\t  \"Block size of disk is in blk_size.\" },\n\t{ \"VIRTIO_BLK_F_FLUSH\", 9, false, \"Cache flush command support.\" },\n\t{ \"VIRTIO_BLK_F_TOPOLOGY\", 10, false,\n\t  \"Device exports information on optimal I/O alignment.\" },\n\t{ \"VIRTIO_BLK_F_CONFIG_WCE\", 11, false,\n\t  \"Device can toggle its cache between writeback and \"\n\t  \"writethrough modes.\" },\n\tVIRTIO_INDP_CAPS\n};\n\n#define get_vblkreq(req) container_of(req, struct virtio_blk_req, blkreq)\n\nstatic struct virtio_blk vblk_dev;\n\nstruct virtio_blk {\n\tvirtio_regs *regs;\n\tstruct virtio_blk_config config;\n\tstruct virtqueue *virtq;\n\tuint32_t intid;\n\tuint64_t sector_cnt;\n};\n#define get_vblkdev(dev) container_of(dev, struct virtio_blk, blkdev)\n\n#define HI32(u64) ((uint32_t)((0xFFFFFFFF00000000ULL & (u64)) >> 32))\n#define LO32(u64) ((uint32_t)(0x00000000FFFFFFFFULL & (u64)))\n\nstatic void virtio_blk_handle_used(struct virtio_blk *dev, uint32_t usedidx)\n{\n\tstruct virtqueue *virtq = dev->virtq;\n\tuint32_t desc1, desc2, desc3;\n\tstruct virtio_blk_req *req;\n\n\tdesc1 = virtq->used->ring[usedidx].id;\n\tif (!(virtq->desc[desc1].flags & VIRTQ_DESC_F_NEXT))\n\t\tgoto bad_desc;\n\tdesc2 = virtq->desc[desc1].next;\n\tif (!(virtq->desc[desc2].flags & VIRTQ_DESC_F_NEXT))\n\t\tgoto bad_desc;\n\tdesc3 = virtq->desc[desc2].next;\n\tif (virtq->desc[desc1].len != VIRTIO_BLK_REQ_HEADER_SIZE ||\n\t    virtq->desc[desc2].len != VIRTIO_BLK_SECTOR_SIZE ||\n\t    virtq->desc[desc3].len != VIRTIO_BLK_REQ_FOOTER_SIZE)\n\t\tgoto bad_desc;\n\n\treq = virtq->desc_virt[desc1];\n\n\tvirtq_free_desc(virtq, desc1);\n\tvirtq_free_desc(virtq, desc2);\n\tvirtq_free_desc(virtq, desc3);\n\n\tswitch (req->status) {\n\tcase VIRTIO_BLK_S_OK:\n\t\treq->blkreq.status = BLKREQ_OK;\n\t\tbreak;\n\tcase VIRTIO_BLK_S_IOERR:\n\t\treq->blkreq.status = BLKREQ_ERR;\n\t\tbreak;\n\tdefault:\n\t\tputs(\"Unhandled status in virtio_blk irq\\n\");\n\t\tbreak;\n\t}\n\n\treturn;\n\nbad_desc:\n\tpr_err(\"virtio-blk received malformed descriptors\\n\");\n\treturn;\n}\n\nstatic void virtio_blk_isr(void)\n{\n\tint i, len;\n\tstruct virtio_blk *dev = &vblk_dev;\n\n\tlen = dev->virtq->len;\n\tWRITE32(dev->regs->InterruptACK, READ32(dev->regs->InterruptStatus));\n\tmb();\n\n\tfor (i = dev->virtq->seen_used; i != (dev->virtq->used->idx % len);\n\t     i = wrap(i + 1, len)) {\n\t\tvirtio_blk_handle_used(dev, i);\n\t}\n\n\tdev->virtq->seen_used = dev->virtq->used->idx % len;\n\tmb();\n}\n\nstatic int virtio_blk_poll(struct virtio_blk *blk, struct blkreq *req)\n{\n\tint ret;\n\n\tret = kobject_read(blk->intid, NULL, 0, NULL, NULL, 0, NULL, 500);\n\tif (ret != 0)\n\t\tpr_err(\"get wrong virtio irq state %d\\n\", ret);\n\n\tvirtio_blk_isr();\n\n\tkobject_write(blk->intid, NULL, 0, NULL, 0, 0);\n\n\treturn 0;\n}\n\nstatic void virtio_blk_send(struct virtio_blk *blk, struct virtio_blk_req *hdr)\n{\n\tblk->virtq->avail->ring[blk->virtq->avail->idx % blk->virtq->len] =\n\t        hdr->descriptor;\n\tblk->virtq->avail->idx += 1;\n\tmb();\n\n\tWRITE32(blk->regs->QueueNotify, 0);\n}\n\n#if 0\nstatic int virtio_blk_status(struct virtio_blk *blkdev)\n{\n\tpr_info(\"    Status=0x%x\\n\", READ32(blkdev->regs->Status));\n\tpr_info(\"    DeviceID=0x%x\\n\", READ32(blkdev->regs->DeviceID));\n\tpr_info(\"    VendorID=0x%x\\n\", READ32(blkdev->regs->VendorID));\n\tpr_info(\"    InterruptStatus=0x%x\\n\",\n\t       READ32(blkdev->regs->InterruptStatus));\n\tpr_info(\"    MagicValue=0x%x\\n\", READ32(blkdev->regs->MagicValue));\n\tpr_info(\"  Queue 0:\\n\");\n\tpr_info(\"    avail.idx = %u\\n\", blkdev->virtq->avail->idx);\n\tpr_info(\"    used.idx = %u\\n\", blkdev->virtq->used->idx);\n\tWRITE32(blkdev->regs->QueueSel, 0);\n\tmb();\n\tpr_info(\"    ready = 0x%x\\n\", READ32(blkdev->regs->QueueReady));\n\tvirtq_show(blkdev->virtq);\n\treturn 0;\n}\n#endif\n\nstatic struct blkreq *virtio_blk_alloc(struct virtio_blk *dev)\n{\n\tstruct virtio_blk_req *vblkreq;\n\t\n\tvblkreq = zalloc(sizeof(struct virtio_blk_req));\n\tif (!vblkreq)\n\t\treturn NULL;\n\n\treturn &vblkreq->blkreq;\n}\n\nstatic void virtio_blk_free(struct virtio_blk *blk, struct blkreq *req)\n{\n\tstruct virtio_blk_req *vblkreq = get_vblkreq(req);\n\tfree(vblkreq);\n}\n\nstatic int virtio_blk_submit(struct virtio_blk *blk, struct blkreq *req)\n{\n\tstruct virtio_blk_req *hdr = get_vblkreq(req);\n\tuint32_t d1, d2, d3, datamode = 0;\n\n\tif (req->type == BLKREQ_READ) {\n\t\thdr->type = VIRTIO_BLK_T_IN;\n\t\tdatamode = VIRTQ_DESC_F_WRITE; /* mark page writeable */\n\t} else {\n\t\thdr->type = VIRTIO_BLK_T_OUT;\n\t}\n\thdr->sector = req->blkidx;\n\n\td1 = virtq_alloc_desc(blk->virtq, hdr);\n\thdr->descriptor = d1;\n\tblk->virtq->desc[d1].len = VIRTIO_BLK_REQ_HEADER_SIZE;\n\tblk->virtq->desc[d1].flags = VIRTQ_DESC_F_NEXT;\n\n\td2 = virtq_alloc_desc(blk->virtq, req->buf);\n\tblk->virtq->desc[d2].len = VIRTIO_BLK_SECTOR_SIZE;\n\tblk->virtq->desc[d2].flags = datamode | VIRTQ_DESC_F_NEXT;\n\n\td3 = virtq_alloc_desc(blk->virtq,\n\t                      (void *)hdr + VIRTIO_BLK_REQ_HEADER_SIZE);\n\tblk->virtq->desc[d3].len = VIRTIO_BLK_REQ_FOOTER_SIZE;\n\tblk->virtq->desc[d3].flags = VIRTQ_DESC_F_WRITE;\n\n\tblk->virtq->desc[d1].next = d2;\n\tblk->virtq->desc[d2].next = d3;\n\n\tvirtio_blk_send(blk, hdr);\n\n\treturn 0;\n}\n\n#define __raw_read8(a)\t(*(volatile uint8_t *)(a))\n\nstatic void get_config(void *base, unsigned offset, void *buf, unsigned len)\n{\n\tuint8_t *ptr = buf;\n\tint i;\n\n\tfor (i = 0; i < len; i++)\n\t\tptr[i] = __raw_read8(base + offset + i);\n}\n\nstatic int blkreq_wait_all(struct virtio_blk *bdev, struct list_head *breq_list)\n{\n\tstruct blkreq *breq;\n\n\tlist_for_each_entry(breq, breq_list, list) {\n\t\tif (breq->status != BLKREQ_INIT)\n\t\t\tcontinue;\n\n\t\twhile (breq->status == BLKREQ_INIT)\n\t\t\tvirtio_blk_poll(bdev, breq);\n\t}\n\n\tlist_for_each_entry(breq, breq_list, list) {\n\t\tif (breq->status == BLKREQ_ERR)\n\t\t\treturn BLKREQ_ERR;\n\t}\n\n\treturn BLKREQ_OK;\n}\n\nint submit_blkreq_one(struct virtio_blk *bdev, struct blkreq *breq)\n{\n\tint ret;\n\n\tret = virtio_blk_submit(bdev, breq);\n\tif (ret)\n\t\treturn ret;\n\n\twhile (breq->status == 0)\n\t\tyield();\n\n\treturn (breq->status == BLKREQ_ERR);\n}\n\nint submit_blkreq_many(struct virtio_blk *vdev, struct list_head *breq_list)\n{\n\tstruct blkreq *breq;\n\tint ret, status;\n\n\tif (is_list_empty(breq_list)) {\n\t\tpr_err(\"block request list is empty\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\tlist_for_each_entry(breq, breq_list, list) {\n\t\tret = virtio_blk_submit(vdev, breq);\n\t\tif (ret) {\n\t\t\tret = -EIO;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tstatus = blkreq_wait_all(vdev, breq_list);\n\tif (status != BLKREQ_OK)\n\t\tret = -EIO;\n\n\treturn ret;\n}\n\nstatic int request_virtio_blkdev_sectors(struct virtio_blk *vdev, void *buf,\n\t\tuint64_t start, uint32_t cnt, int op)\n{\n\tLIST_HEAD(blkreq_list);\n\tstruct blkreq *breq, *next;\n\tint i, ret = 0, status;\n\n\tfor (i = 0; i < cnt; i++) {\n\t\tbreq = virtio_blk_alloc(vdev);\n\t\tif (!breq) {\n\t\t\tret = -ENOMEM;\n\t\t\tgoto out;\n\t\t}\n\n\t\tbreq->status = BLKREQ_INIT;\n\t\tbreq->blkidx = start + i;\n\t\tbreq->type = op;\n\t\tbreq->buf = buf + i * VIRTIO_BLK_SECTOR_SIZE;\n\t\tbreq->size = VIRTIO_BLK_SECTOR_SIZE;\n\t\tret = virtio_blk_submit(vdev, breq);\n\t\tif (ret) {\n\t\t\tvirtio_blk_free(vdev, breq);\n\t\t\tret = -EIO;\n\t\t\tbreak;\n\t\t}\n\t\tlist_add_tail(&blkreq_list, &breq->list);\n\t}\n\n\tstatus = blkreq_wait_all(vdev, &blkreq_list);\n\tif (status != BLKREQ_OK)\n\t\tret = -EIO;\n\nout:\n\tlist_for_each_entry_safe(breq, next, &blkreq_list, list) {\n\t\tlist_del(&breq->list);\n\t\tvirtio_blk_free(vdev, breq);\n\t}\n\n\treturn ret;\n}\n\nstatic int virtio_ext4_iface_bread(struct ext4_blockdev *bdev, void *buf,\n\t\tuint64_t blk_id, uint32_t blk_cnt)\n{\n\tstruct virtio_blk *vdev = bdev->bdif->p_user;\n\n\treturn request_virtio_blkdev_sectors(vdev, buf, blk_id,\n\t\t\tblk_cnt, BLKREQ_READ);\n}\n\nstatic int virtio_ext4_iface_bwrite(struct ext4_blockdev *bdev, const void *buf,\n\t\tuint64_t blk_id, uint32_t blk_cnt)\n{\n\tstruct virtio_blk *vdev = bdev->bdif->p_user;\n\n\treturn request_virtio_blkdev_sectors(vdev, (void *)buf,\n\t\t\tblk_id, blk_cnt, BLKREQ_READ);\n}\n\nstatic int virtio_ext4_iface_open(struct ext4_blockdev *bdev)\n{\n\tbdev->bdif->ph_bcnt = bdev->part_size / bdev->bdif->ph_bsize;\n\n\treturn 0;\n}\n\nstatic int virtio_ext4_iface_close(struct ext4_blockdev *bdev)\n{\n\treturn 0;\n}\n\nstatic uint8_t ext4_phbuf[PAGE_SIZE];\nstatic struct ext4_blockdev_iface virtio_ext4_iface = {\n\t.open\t= virtio_ext4_iface_open,\n\t.bread\t= virtio_ext4_iface_bread,\n\t.bwrite = virtio_ext4_iface_bwrite,\n\t.close\t= virtio_ext4_iface_close,\n\t.lock\t= NULL,\n\t.unlock = NULL,\n\t.ph_bsize = VIRTIO_BLK_SECTOR_SIZE,\n\t.p_user = &vblk_dev,\n\t.ph_bbuf = ext4_phbuf,\n};\n\nstatic int run_virtio_block_ext4_server(void)\n{\n\tstatic struct ext4_blockdev bdev;\n\tstruct virtio_blk *vdev = &vblk_dev;\n\n\tmemset(&bdev, 0, sizeof(struct ext4_blockdev));\n\tbdev.bdif = &virtio_ext4_iface;\n\tbdev.part_offset = 0;\n\tbdev.part_size = vdev->sector_cnt * VIRTIO_BLK_SECTOR_SIZE;\n\n\treturn run_ext4_file_server(&bdev);\n}\n\nint virtio_blk_init(virtio_regs *regs, uint32_t intid)\n{\n\tstruct virtio_blk *vdev;\n\tstruct virtqueue *virtq;\n\tuint32_t genbefore, genafter;\n\n\tvdev = &vblk_dev;\n\tmemset(vdev, 0, sizeof(struct virtio_blk));\n\n\tvirtio_check_capabilities(regs, blk_caps,\n\t\t\tARRAY_SIZE(blk_caps), \"virtio-blk\");\n\n\tWRITE32(regs->Status, READ32(regs->Status) | VIRTIO_STATUS_FEATURES_OK);\n\tmb();\n\n\tif (!(regs->Status & VIRTIO_STATUS_FEATURES_OK)) {\n\t\tputs(\"error: virtio-blk did not accept our features\\n\");\n\t\treturn -1;\n\t}\n\n\tvirtq = virtq_create(regs, 32);\n\tvirtq_add_to_device(regs, virtq, 0);\n\n\tvdev->regs = regs;\n\tvdev->virtq = virtq;\n\tvdev->intid = intid;\n\n\t/* capacity is 64 bit, configuration reg read is not atomic */\n\tdo {\n\t\tgenbefore = READ32(vdev->regs->ConfigGeneration);\n\t\tget_config((void *)regs, 0x100, &vdev->config,\n\t\t\t\tsizeof(struct virtio_blk_config));\n\t\tgenafter = READ32(vdev->regs->ConfigGeneration);\n\t} while (genbefore != genafter);\n\n\tvdev->sector_cnt = vdev->config.capacity;\n\tpr_info(\"vd0 capacity : %ldMB\\n\", vdev->config.capacity * VIRTIO_BLK_SECTOR_SIZE / 1024 / 1024);\n\n\tWRITE32(regs->Status, READ32(regs->Status) | VIRTIO_STATUS_DRIVER_OK);\n\tmb();\n\n\treturn run_virtio_block_ext4_server();\n}\n"
  },
  {
    "path": "user.driver/virtio-blk/virtio.c",
    "content": "/**\n * Implements virtio device drivers, particularly mmio ones.\n *\n * Reference:\n *\n * http://docs.oasis-open.org/virtio/virtio/v1.0/cs04/virtio-v1.0-cs04.html\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <errno.h>\n#include <sys/mman.h>\n#include <minos/debug.h>\n#include <minos/kobject.h>\n#include <minos/types.h>\n\n#include \"virtio.h\"\n\n#define VIRTQ_ALIGN(x)\t(((x) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))\n\nstatic inline unsigned int virtq_size(unsigned int qsz)\n{\n\treturn VIRTQ_ALIGN(sizeof(struct virtqueue_desc) * qsz + sizeof(uint16_t) * (3 + qsz)) +\n\t\tVIRTQ_ALIGN(sizeof(uint16_t) * 3 + sizeof(struct virtqueue_used_elem) * qsz);\n}\n\nstruct virtqueue *virtq_create(virtio_regs *regs, uint32_t len)\n{\n\tint i, pma_handle;\n\tvoid *page_virt = 0;\n\tstruct virtqueue *virtq;\n\tuint32_t max_queue_size;\n\tuint32_t memsize;\n\n\tmax_queue_size = READ32(regs->QueueNumMax);\n\tif (len > max_queue_size) {\n\t\tpr_warn(\"virtio queue size not ready or too big %d %d\\n\",\n\t\t\t\tlen, max_queue_size);\n\t\tlen = max_queue_size;\n\t}\n\n\tvirtq = zalloc(sizeof(struct virtqueue) + sizeof(void *) * len);\n\tif (!virtq)\n\t\treturn NULL;\n\n\t/*\n\t * allocate the total virtq ring size, must PAGE_SIZE alignment.\n\t */\n\tmemsize = virtq_size(len);\n\tpr_info(\"virtio-blk virtq size %d\\n\", memsize);\n\n\tpma_handle = request_consequent_pma(memsize, KR_RW);\n\tif (pma_handle <= 0)\n\t\treturn NULL;\n\n\tif (kobject_mmap(pma_handle, &page_virt, NULL)) {\n\t\tfree(virtq);\n\t\tkobject_close(pma_handle);\n\t\treturn NULL;\n\t}\n\n\t/*\n\t * clear it, than kernel will handle page fault for\n\t * this page.\n\t */\n\tmemset(page_virt, 0, memsize);\n\tvirtq->len = len;\n\tvirtq->vq_virt = (unsigned long)page_virt;\n\tvirtq->vq_phys = sys_mtrans((unsigned long)page_virt);\n\tif (virtq->vq_phys == -1) {\n\t\tfree(virtq);\n\t\tkobject_close(pma_handle);\n\t\treturn NULL;\n\t}\n\n\tvirtq->desc = (struct virtqueue_desc *)page_virt;\n\tvirtq->avail = page_virt + len * sizeof(struct virtqueue_desc);\n\tvirtq->used = (void *)&virtq->avail->ring[len];\n\tvirtq->used = (void *)VIRTQ_ALIGN((unsigned long)virtq->used);\n\n\tvirtq->avail->idx = 0;\n\tvirtq->used->idx = 0;\n\tvirtq->seen_used = virtq->used->idx;\n\tvirtq->free_desc = 0;\n\n\tfor (i = 0; i < len; i++) {\n\t\tvirtq->desc[i].next = i + 1;\n\t}\n\n\treturn virtq;\n}\n\nuint32_t virtq_alloc_desc(struct virtqueue *virtq, void *addr)\n{\n\tuint32_t desc = virtq->free_desc;\n\tuint32_t next = virtq->desc[desc].next;\n\tif (desc == virtq->len)\n\t\tpr_err(\"ran out of virtqueue descriptors\\n\");\n\tvirtq->free_desc = next;\n\n\tvirtq->desc[desc].addr = sys_mtrans((unsigned long)addr);\n\tif (virtq->desc[desc].addr == -1) {\n\t\tpr_err(\"translate VA to PA failed\\n\");\n\t\texit(-EFAULT);\n\t}\n\n\tvirtq->desc_virt[desc] = addr;\n\treturn desc;\n}\n\nvoid virtq_free_desc(struct virtqueue *virtq, uint32_t desc)\n{\n\tvirtq->desc[desc].next = virtq->free_desc;\n\tvirtq->free_desc = desc;\n\tvirtq->desc_virt[desc] = NULL;\n}\n\n#define U64_HIGH(addr)\t(uint32_t)((uint64_t)(addr) >> 32)\n#define U64_LOW(addr)\t(uint32_t)((uint64_t)(addr) & 0xffffffff)\n#define nop()\t\tasm volatile (\"nop\\n\");\n\nstatic void virtq_add_to_device_legacy(volatile virtio_regs *regs,\n\t\t\tstruct virtqueue *virtq, uint32_t queue_sel)\n{\n\tWRITE32(regs->QueueSel, queue_sel);\n\twhile (READ32(regs->QueuePfn) != 0)\n\t\tnop();\n\n\tWRITE32(regs->QueueNum, virtq->len);\n\tWRITE32(regs->QueueAlign, PAGE_SIZE);\n\tWRITE32(regs->QueuePfn, virtq->vq_phys >> PAGE_SHIFT);\n}\n\nstatic void virtq_add_to_device_common(volatile virtio_regs *regs,\n\t\tstruct virtqueue *virtq, uint32_t queue_sel)\n{\n\tuint64_t address;\n\n\tWRITE32(regs->QueueSel, queue_sel);\n\twhile (READ32(regs->QueueReady) != 0)\n\t\tnop();\n\n\tWRITE32(regs->QueueNum, virtq->len);\n\tmb();\n\n\taddress = virtq->vq_phys + (unsigned long)virtq->desc - virtq->vq_virt;\n\tWRITE32(regs->QueueDescLow, U64_LOW(address));\n\tWRITE32(regs->QueueDescHigh, U64_HIGH(address));\n\n\taddress = virtq->vq_phys + (unsigned long)virtq->avail - virtq->vq_virt;\n\tWRITE32(regs->QueueAvailLow, U64_LOW(address));\n\tWRITE32(regs->QueueAvailHigh, U64_HIGH(address));\n\n\taddress = virtq->vq_phys + (unsigned long)virtq->used - virtq->vq_virt;\n\tWRITE32(regs->QueueUsedLow, U64_LOW(address));\n\tWRITE32(regs->QueueUsedHigh, U64_HIGH(address));\n\n\tmb();\n\tWRITE32(regs->QueueReady, 1);\n}\n\nvoid virtq_add_to_device(volatile virtio_regs *regs,\n\t\tstruct virtqueue *virtq, uint32_t queue_sel)\n{\n\tif (READ32(regs->Version) == 1)\n\t\tvirtq_add_to_device_legacy(regs, virtq, queue_sel);\n\telse\n\t\tvirtq_add_to_device_common(regs, virtq, queue_sel);\n}\n\nvoid virtq_show(struct virtqueue *virtq)\n{\n\tint count = 0;\n\tuint32_t i = virtq->free_desc;\n\tpr_info(\"Current free_desc: %lu, len=%lu\\n\", virtq->free_desc, virtq->len);\n\twhile (i != virtq->len && count++ <= virtq->len) {\n\t\tpr_info(\"  next: %u -> %u\\n\", i, virtq->desc[i].next);\n\t\ti = virtq->desc[i].next;\n\t}\n\tif (count > virtq->len) {\n\t\tputs(\"Overflowed descriptors?\\n\");\n\t}\n}\n\nvoid virtio_check_capabilities(virtio_regs *regs, struct virtio_cap *caps,\n                               uint32_t n, char *whom)\n{\n\tuint32_t i;\n\tuint32_t bank = 0;\n\tuint32_t driver = 0;\n\tuint32_t device;\n\n\tWRITE32(regs->DeviceFeaturesSel, bank);\n\tmb();\n\tdevice = READ32(regs->DeviceFeatures);\n\n\tfor (i = 0; i < n; i++) {\n\t\tif (caps[i].bit / 32 != bank) {\n\t\t\t/* Time to write our selected bits for this bank */\n\t\t\tWRITE32(regs->DriverFeaturesSel, bank);\n\t\t\tmb();\n\t\t\tWRITE32(regs->DriverFeatures, driver);\n\t\t\tif (device) {\n\t\t\t\tpr_info(\"%s: device supports unknown bits\"\n\t\t\t\t       \" 0x%x in bank %u\\n\", whom, device,bank);\n\t\t\t}\n\t\t\t/* Now we set these variables for next time. */\n\t\t\tbank = caps[i].bit / 32;\n\t\t\tWRITE32(regs->DeviceFeaturesSel, bank);\n\t\t\tmb();\n\t\t\tdevice = READ32(regs->DeviceFeatures);\n\t\t}\n\t\tif (device & (1 << caps[i].bit)) {\n\t\t\tif (caps[i].support) {\n\t\t\t\tdriver |= (1 << caps[i].bit);\n\t\t\t} else {\n\t\t\t\tpr_info(\"virtio supports unsupported option %s (%s)\\n\",\n\t\t\t\t       caps[i].name, caps[i].help);\n\t\t\t}\n\t\t\t/* clear this from device now */\n\t\t\tdevice &= ~(1 << caps[i].bit);\n\t\t}\n\t}\n\n\t/* Time to write our selected bits for this bank */\n\tWRITE32(regs->DriverFeaturesSel, bank);\n\tmb();\n\tWRITE32(regs->DriverFeatures, driver);\n\tif (device) {\n\t\tpr_info(\"%s: device supports unknown bits\"\n\t\t       \" 0x%x in bank %u\\n\", whom, device, bank);\n\t}\n}\n\nint virtio_dev_init(unsigned long virt, uint32_t intid)\n{\n\tvirtio_regs *regs = (virtio_regs *)virt;\n\n\tif (READ32(regs->MagicValue) != VIRTIO_MAGIC) {\n\t\tpr_err(\"error: virtio at 0x%lx had wrong magic value 0x%x, \"\n\t\t       \"expected 0x%x\\n\",\n\t\t       virt, regs->MagicValue, VIRTIO_MAGIC);\n\t\treturn -1;\n\t}\n\n\tif (READ32(regs->Version) == 1) {\n\t\tpr_err(\"virtio-dev: legacy mode\\n\");\n\t\tWRITE32(regs->GuestPageSize, PAGE_SIZE);\n\t}\n\n\tif (READ32(regs->DeviceID) == 0) {\n\t\tpr_warn(\"warn: virtio has DeviceID=0, skipping\\n\");\n\t\treturn -1;\n\t}\n\n\t/* First step of initialization: reset */\n\tWRITE32(regs->Status, 0);\n\tmb();\n\t/* Hello there, I see you */\n\tWRITE32(regs->Status, READ32(regs->Status) | VIRTIO_STATUS_ACKNOWLEDGE);\n\tmb();\n\n\t/* Hello, I am a driver for you */\n\tWRITE32(regs->Status, READ32(regs->Status) | VIRTIO_STATUS_DRIVER);\n\tmb();\n\n\tswitch (READ32(regs->DeviceID)) {\n\tcase VIRTIO_DEV_BLK:\n\t\treturn virtio_blk_init(regs, intid);\n\tdefault:\n\t\tpr_err(\"unsupported virtio device ID 0x%x\\n\",\n\t\t       READ32(regs->DeviceID));\n\t}\n\treturn 0;\n}\n"
  },
  {
    "path": "user.driver/virtio-blk/virtio.h",
    "content": "/**\n * virtio declarations (mmio, queue)\n */\n\n#pragma once\n#include <stdbool.h>\n#include <stdint.h>\n#include <minos/list.h>\n#include <minos/device.h>\n\n#define VIRTIO_MAGIC   0x74726976\n#define VIRTIO_VERSION 0x2\n#define VIRTIO_DEV_NET 0x1\n#define VIRTIO_DEV_BLK 0x2\n#define wrap(x, len)   ((x) & ~(len))\n\n/*\n * See Section 4.2.2 of VIRTIO 1.0 Spec:\n * http://docs.oasis-open.org/virtio/virtio/v1.0/cs04/virtio-v1.0-cs04.html\n */\ntypedef volatile struct __attribute__((packed)) {\n\tuint32_t MagicValue;\t\t// 00\n\tuint32_t Version;\t\t// 04\n\tuint32_t DeviceID;\t\t// 08\n\tuint32_t VendorID;\t\t// 0c\n\tuint32_t DeviceFeatures;\t// 10\n\tuint32_t DeviceFeaturesSel;\t// 14\n\tuint32_t _reserved0[2];\t\t// 18 1c\n\tuint32_t DriverFeatures;\t// 20\n\tuint32_t DriverFeaturesSel;\t// 24\n\tuint32_t GuestPageSize;\t\t// 28\n\tuint32_t _reserved1[1];\t\t// 2c\n\tuint32_t QueueSel;\t\t// 30\n\tuint32_t QueueNumMax;\t\t// 34\n\tuint32_t QueueNum;\t\t// 38\n\tuint32_t QueueAlign;\t\t// 3c\n\tuint32_t QueuePfn;\t\t// 40\n\tuint32_t QueueReady;\t\t// 44\n\tuint32_t _reserved3[2];\t\t// 48 4c\n\tuint32_t QueueNotify;\t\t// 50\n\tuint32_t _reserved4[3];\t\t// 54 58 5c\n\tuint32_t InterruptStatus;\t// 60\n\tuint32_t InterruptACK;\t\t// 64\n\tuint32_t _reserved5[2];\t\t// 68 6c\n\tuint32_t Status;\t\t// 70\n\tuint32_t _reserved6[3];\n\tuint32_t QueueDescLow;\n\tuint32_t QueueDescHigh;\n\tuint32_t _reserved7[2];\n\tuint32_t QueueAvailLow;\n\tuint32_t QueueAvailHigh;\n\tuint32_t _reserved8[2];\n\tuint32_t QueueUsedLow;\n\tuint32_t QueueUsedHigh;\n\tuint32_t _reserved9[21];\n\tuint32_t ConfigGeneration;\n\tuint32_t Config[0];\n} virtio_regs;\n\n#define VIRTIO_STATUS_ACKNOWLEDGE        (1)\n#define VIRTIO_STATUS_DRIVER             (2)\n#define VIRTIO_STATUS_FAILED             (128)\n#define VIRTIO_STATUS_FEATURES_OK        (8)\n#define VIRTIO_STATUS_DRIVER_OK          (4)\n#define VIRTIO_STATUS_DEVICE_NEEDS_RESET (64)\n\nstruct virtio_cap {\n\tchar *name;\n\tuint32_t bit;\n\tbool support;\n\tchar *help;\n};\n\nstruct virtqueue_desc {\n\tuint64_t addr;\n\tuint32_t len;\n/* This marks a buffer as continuing via the next field. */\n#define VIRTQ_DESC_F_NEXT 1\n/* This marks a buffer as device write-only (otherwise device read-only). */\n#define VIRTQ_DESC_F_WRITE 2\n/* This means the buffer contains a list of buffer descriptors. */\n#define VIRTQ_DESC_F_INDIRECT 4\n\t/* The flags as indicated above. */\n\tuint16_t flags;\n\t/* Next field if flags & NEXT */\n\tuint16_t next;\n} __attribute__((packed));\n\nstruct virtqueue_avail {\n#define VIRTQ_AVAIL_F_NO_INTERRUPT 1\n\tuint16_t flags;\n\tuint16_t idx;\n\tuint16_t ring[0];\n} __attribute__((packed));\n\nstruct virtqueue_used_elem {\n\tuint32_t id;\n\tuint32_t len;\n} __attribute__((packed));\n\nstruct virtqueue_used {\n#define VIRTQ_USED_F_NO_NOTIFY 1\n\tuint16_t flags;\n\tuint16_t idx;\n\tstruct virtqueue_used_elem ring[0];\n} __attribute__((packed));\n\n/*\n * For simplicity, we lay out the virtqueue in contiguous memory on a single\n * page. See virtq_create for the layout and alignment requirements.\n */\nstruct virtqueue {\n\t/* Physical base address of the full data structure. */\n\tunsigned long vq_phys;\n\tunsigned long vq_virt;\n\tsize_t len;\n\tsize_t seen_used;\n\tsize_t free_desc;\n\n\tvolatile struct virtqueue_desc *desc;\n\tvolatile struct virtqueue_avail *avail;\n\tvolatile struct virtqueue_used *used;\n\n\tvolatile uint16_t *used_event;\n\tvolatile uint16_t *avail_event;\n\tvoid *desc_virt[0];\n} __attribute__((packed));\n\nstruct virtio_blk_config {\n\tuint64_t capacity;\n\tuint32_t size_max;\n\tuint32_t seg_max;\n\tstruct {\n\t\tuint16_t cylinders;\n\t\tuint8_t heads;\n\t\tuint8_t sectors;\n\t} geometry;\n\tuint32_t blk_size;\n\tstruct {\n\t\tuint8_t physical_block_exp;\n\t\tuint8_t alignment_offset;\n\t\tuint16_t min_io_size;\n\t\tuint32_t opt_io_size;\n\t} topology;\n\tuint8_t writeback;\n} __attribute__((packed));\n\nstruct virtio_net_config {\n\tuint8_t mac[6];\n#define VIRTIO_NET_S_LINK_UP  1\n#define VIRTIO_NET_S_ANNOUNCE 2\n\tuint16_t status;\n\tuint16_t max_virtqueue_pairs;\n} __attribute__((packed));\n\n#define BLKREQ_READ\t0x0\n#define BLKREQ_WRITE\t0x1\n\n#define BLKREQ_INIT 0x0\n#define BLKREQ_OK 0x1\n#define BLKREQ_ERR 0x2\n\nstruct blkreq {\n\tint type;\n\tuint64_t blkidx;\t\t// which block need to read. default block size 4096\n\tuint64_t size;\t\t\t// blkreq buf size\n\tuint8_t *buf;\t\t\t// blkreq buf address.\n\tint status;\t\t\t// blkreq status.\n\tvoid *pdata;\t\t\t// the private data for the realy device req if has.\n\tstruct list_head list;\n};\n\n#define VIRTIO_BLK_REQ_HEADER_SIZE 16\n#define VIRTIO_BLK_REQ_FOOTER_SIZE 1\nstruct virtio_blk_req {\n#define VIRTIO_BLK_T_IN    0\n#define VIRTIO_BLK_T_OUT   1\n#define VIRTIO_BLK_T_SCSI  2\n#define VIRTIO_BLK_T_FLUSH 4\n\tuint32_t type;\n\tuint32_t reserved;\n\tuint64_t sector;\n\tuint8_t status;\n\t/* end standard fields, begin helpers */\n\tuint8_t _pad[3];\n\tuint32_t descriptor;\n\tstruct blkreq blkreq;\n} __attribute__((packed));\n\n#define VIRTIO_BLK_SECTOR_SIZE 512\n\n#define VIRTIO_BLK_S_OK     0\n#define VIRTIO_BLK_S_IOERR  1\n#define VIRTIO_BLK_S_UNSUPP 2\n\n/*\n * virtqueue routines\n */\nstruct virtqueue *virtq_create(virtio_regs *regs, uint32_t len);\nuint32_t virtq_alloc_desc(struct virtqueue *virtq, void *addr);\nvoid virtq_free_desc(struct virtqueue *virtq, uint32_t desc);\nvoid virtq_add_to_device(volatile virtio_regs *regs, struct virtqueue *virtq,\n                         uint32_t queue_sel);\nvoid virtq_show(struct virtqueue *virtq);\n\n/*\n * General purpose routines for virtio drivers\n */\nvoid virtio_check_capabilities(virtio_regs *device, struct virtio_cap *caps,\n                               uint32_t n, char *whom);\n\n#define VIRTIO_INDP_CAPS                                                       \\\n\t{ \"VIRTIO_F_RING_INDIRECT_DESC\", 28, false,                            \\\n\t  \"Negotiating this feature indicates that the driver can use\"         \\\n\t  \" descriptors with the VIRTQ_DESC_F_INDIRECT flag set, as\"           \\\n\t  \" described in 2.4.5.3 Indirect Descriptors.\" },                     \\\n\t{ \"VIRTIO_F_RING_EVENT_IDX\", 29, false,                        \t       \\\n\t  \"This feature enables the used_event and the avail_event \"           \\\n\t  \"fields as described in 2.4.7 and 2.4.8.\" },                         \\\n\t{ \"VIRTIO_F_VERSION_1\", 32, false,                                     \\\n\t  \"This indicates compliance with this specification, giving \"         \\\n\t  \"a simple way to detect legacy devices or drivers.\" },\n\nint virtio_dev_init(unsigned long virt, uint32_t intid);\n\nint virtio_blk_init(virtio_regs *regs, uint32_t intid);\n"
  },
  {
    "path": "user.libc/.gitignore",
    "content": "*.o\n*.lo\n*.a\n*.so\n*.so.1\nconfig.mak\nlib/musl-gcc.specs\n/obj/\ntags\ncscope.in.out\ncscope.out\ncscope.po.out\nlinkmap.txt\n*.patch\n"
  },
  {
    "path": "user.libc/.mailmap",
    "content": "Ada Worcester <oss@ada.pikhq.com> <josiahw@gmail.com>\n"
  },
  {
    "path": "user.libc/COPYRIGHT",
    "content": "musl as a whole is licensed under the following standard MIT license:\n\n----------------------------------------------------------------------\nCopyright © 2005-2020 Rich Felker, et al.\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n----------------------------------------------------------------------\n\nAuthors/contributors include:\n\nA. Wilcox\nAda Worcester\nAlex Dowad\nAlex Suykov\nAlexander Monakov\nAndre McCurdy\nAndrew Kelley\nAnthony G. Basile\nAric Belsito\nArvid Picciani\nBartosz Brachaczek\nBenjamin Peterson\nBobby Bingham\nBoris Brezillon\nBrent Cook\nChris Spiegel\nClément Vasseur\nDaniel Micay\nDaniel Sabogal\nDaurnimator\nDavid Carlier\nDavid Edelsohn\nDenys Vlasenko\nDmitry Ivanov\nDmitry V. Levin\nDrew DeVault\nEmil Renner Berthing\nFangrui Song\nFelix Fietkau\nFelix Janda\nGianluca Anzolin\nHauke Mehrtens\nHe X\nHiltjo Posthuma\nIsaac Dunham\nJaydeep Patil\nJens Gustedt\nJeremy Huntwork\nJo-Philipp Wich\nJoakim Sindholt\nJohn Spencer\nJulien Ramseier\nJustin Cormack\nKaarle Ritvanen\nKhem Raj\nKylie McClain\nLeah Neukirchen\nLuca Barbato\nLuka Perkov\nM Farkas-Dyck (Strake)\nMahesh Bodapati\nMarkus Wichmann\nMasanori Ogino\nMichael Clark\nMichael Forney\nMikhail Kremnyov\nNatanael Copa\nNicholas J. Kain\norc\nPascal Cuoq\nPatrick Oppenlander\nPetr Hosek\nPetr Skocik\nPierre Carrier\nReini Urban\nRich Felker\nRichard Pennington\nRyan Fairfax\nSamuel Holland\nSegev Finer\nShiz\nsin\nSolar Designer\nStefan Kristiansson\nStefan O'Rear\nSzabolcs Nagy\nTimo Teräs\nTrutz Behn\nValentin Ochs\nWill Dietz\nWilliam Haddon\nWilliam Pitcock\n\nPortions of this software are derived from third-party works licensed\nunder terms compatible with the above MIT license:\n\nThe TRE regular expression implementation (src/regex/reg* and\nsrc/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed\nunder a 2-clause BSD license (license text in the source files). The\nincluded version has been heavily modified by Rich Felker in 2012, in\nthe interests of size, simplicity, and namespace cleanliness.\n\nMuch of the math library code (src/math/* and src/complex/*) is\nCopyright © 1993,2004 Sun Microsystems or\nCopyright © 2003-2011 David Schultz or\nCopyright © 2003-2009 Steven G. Kargl or\nCopyright © 2003-2009 Bruce D. Evans or\nCopyright © 2008 Stephen L. Moshier or\nCopyright © 2017-2018 Arm Limited\nand labelled as such in comments in the individual source files. All\nhave been licensed under extremely permissive terms.\n\nThe ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008\nThe Android Open Source Project and is licensed under a two-clause BSD\nlicense. It was taken from Bionic libc, used on Android.\n\nThe AArch64 memcpy and memset code (src/string/aarch64/*) are\nCopyright © 1999-2019, Arm Limited.\n\nThe implementation of DES for crypt (src/crypt/crypt_des.c) is\nCopyright © 1994 David Burren. It is licensed under a BSD license.\n\nThe implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was\noriginally written by Solar Designer and placed into the public\ndomain. The code also comes with a fallback permissive license for use\nin jurisdictions that may not recognize the public domain.\n\nThe smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011\nValentin Ochs and is licensed under an MIT-style license.\n\nThe x86_64 port was written by Nicholas J. Kain and is licensed under\nthe standard MIT terms.\n\nThe mips and microblaze ports were originally written by Richard\nPennington for use in the ellcc project. The original code was adapted\nby Rich Felker for build system and code conventions during upstream\nintegration. It is licensed under the standard MIT terms.\n\nThe mips64 port was contributed by Imagination Technologies and is\nlicensed under the standard MIT terms.\n\nThe powerpc port was also originally written by Richard Pennington,\nand later supplemented and integrated by John Spencer. It is licensed\nunder the standard MIT terms.\n\nAll other files which have no copyright comments are original works\nproduced specifically for use as part of this library, written either\nby Rich Felker, the main author of the library, or by one or more\ncontibutors listed above. Details on authorship of individual files\ncan be found in the git version control history of the project. The\nomission of copyright and license comments in each file is in the\ninterest of source tree size.\n\nIn addition, permission is hereby granted for all public header files\n(include/* and arch/*/bits/*) and crt files intended to be linked into\napplications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit\nthe copyright notice and permission notice otherwise required by the\nlicense, and to use these files without any requirement of\nattribution. These files include substantial contributions from:\n\nBobby Bingham\nJohn Spencer\nNicholas J. Kain\nRich Felker\nRichard Pennington\nStefan Kristiansson\nSzabolcs Nagy\n\nall of whom have explicitly granted such permission.\n\nThis file previously contained text expressing a belief that most of\nthe files covered by the above exception were sufficiently trivial not\nto be subject to copyright, resulting in confusion over whether it\nnegated the permissions granted in the license. In the spirit of\npermissive licensing, and of not having licensing issues being an\nobstacle to adoption, that text has been removed.\n"
  },
  {
    "path": "user.libc/INSTALL",
    "content": "\nQuick Installation Guide for musl libc\n======================================\n\nThere are many different ways to install musl depending on your usage\ncase. This document covers only the build and installation of musl by\nitself, which is useful for upgrading an existing musl-based system or\ncompiler toolchain, or for using the provided musl-gcc wrapper with an\nexisting non-musl-based compiler.\n\nBuilding complete native or cross-compiler toolchains is outside the\nscope of this INSTALL file. More information can be found on the musl\nwebsite and community wiki.\n\n\nBuild Prerequisites\n-------------------\n\nThe only build-time prerequisites for musl are GNU Make and a\nfreestanding C99 compiler toolchain targeting the desired instruction\nset architecture and ABI, with support for a minimal subset of \"GNU C\"\nextensions consisting mainly of gcc-style inline assembly, weak\naliases, hidden visibility, and stand-alone assembly source files.\n\nGCC, LLVM/clang, Firm/cparser, and PCC have all successfully built\nmusl, but GCC is the most widely used/tested. Recent compiler (and\nbinutils) versions should be used if possible since some older\nversions have bugs which affect musl.\n\nThe system used to build musl does not need to be Linux-based, nor do\nthe Linux kernel headers need to be available.\n\n\n\nSupported Targets\n-----------------\n\nmusl can be built for the following CPU instruction set architecture\nand ABI combinations:\n\n* i386\n    * Minimum CPU model is actually 80486 unless kernel emulation of\n      the `cmpxchg` instruction is added\n\n* x86_64\n    * ILP32 ABI (x32) is available as a separate arch but is still\n      experimental\n\n* ARM\n    * EABI, standard or hard-float VFP variant\n    * Little-endian default; big-endian variants also supported\n    * Compiler toolchains only support armv4t and later\n\n* AArch64\n    * Little-endian default; big-endian variants also supported\n\n* MIPS\n    * ABI is o32, fp32/fpxx (except on r6 which is fp64)\n    * Big-endian default; little-endian variants also supported\n    * Default ABI variant uses FPU registers; alternate soft-float ABI\n      that does not use FPU registers or instructions is available\n    * MIPS2 or later, or kernel emulation of ll/sc (standard in Linux)\n      is required\n    * MIPS32r6, an incompatible ISA, is supported as a variant \"mipsr6\"\n\n* MIPS64\n    * ABI is n64 (LP64) or n32 (ILP32)\n    * Big-endian default; little-endian variants also supported\n    * Default ABI variant uses FPU registers; alternate soft-float ABI\n      that does not use FPU registers or instructions is available\n\n* PowerPC\n    * Compiler toolchain must provide 64-bit long double, not IBM\n      double-double or IEEE quad\n    * For dynamic linking, compiler toolchain must be configured for\n      \"secure PLT\" variant\n\n* PowerPC64\n    * Both little and big endian variants are supported\n    * Compiler toolchain must provide 64-bit long double, not IBM\n      double-double or IEEE quad\n    * Compiler toolchain must use the new (ELFv2) ABI regardless of\n      whether it is for little or big endian\n\n* S390X (64-bit S390)\n\n* SuperH (SH)\n    * Standard ELF ABI or FDPIC ABI (shared-text without MMU)\n    * Little-endian by default; big-endian variant also supported\n    * Full FPU ABI or soft-float ABI is supported, but the\n      single-precision-only FPU ABI is not\n\n* Microblaze\n    * Big-endian default; little-endian variants also supported\n    * Soft-float\n    * Requires support for lwx/swx instructions\n\n* OpenRISC 1000 (or1k)\n\n* RISC-V 64\n    * Little endian\n    * Hard, soft, and hard-single/soft-double floating point ABIs\n    * Standard ELF; no shared-text NOMMU support\n\n\n\nBuild and Installation Procedure\n--------------------------------\n\nTo build and install musl:\n\n1. Run the provided configure script from the top-level source\n   directory, passing on its command line any desired options.\n\n2. Run \"make\" to compile.\n\n3. Run \"make install\" with appropriate privileges to write to the\n   target locations.\n\nThe configure script attempts to determine automatically the correct\ntarget architecture based on the compiler being used. For some\ncompilers, this may not be possible. If detection fails or selects the\nwrong architecture, you can provide an explicit selection on the\nconfigure command line.\n\nBy default, configure installs to a prefix of \"/usr/local/musl\". This\ndiffers from the behavior of most configure scripts, and is chosen\nspecifically to avoid clashing with libraries already present on the\nsystem. DO NOT set the prefix to \"/usr\", \"/usr/local\", or \"/\" unless\nyou're upgrading libc on an existing musl-based system. Doing so will\nbreak your existing system when you run \"make install\" and it may be\ndifficult to recover.\n\n\n\nNotes on Dynamic Linking\n------------------------\n\nIf dynamic linking is enabled, one file needs to be installed outside\nof the installation prefix: /lib/ld-musl-$ARCH.so.1. This is the\ndynamic linker. Its pathname is hard-coded into all dynamic-linked\nprograms, so for the sake of being able to share binaries between\nsystems, a consistent location should be used everywhere. Note that\nthe same applies to glibc and its dynamic linker, which is named\n/lib/ld-linux.so.2 on i386 systems.\n\nIf for some reason it is impossible to install the dynamic linker in\nits standard location (for example, if you are installing without root\nprivileges), the --syslibdir option to configure can be used to\nprovide a different location\n\nAt runtime, the dynamic linker needs to know the paths to search for\nshared libraries. You should create a text file named\n/etc/ld-musl-$ARCH.path (where $ARCH matches the architecture name\nused in the dynamic linker) containing a list of directories where you\nwant the dynamic linker to search for shared libraries, separated by\ncolons or newlines. If the dynamic linker has been installed in a\nnon-default location, the path file also needs to reside at that\nlocation (../etc relative to the chosen syslibdir).\n\nIf you do not intend to use dynamic linking, you may disable it by\npassing --disable-shared to configure; this also cuts the build time\nin half.\n\n\n\nChecking for Successful Installation\n------------------------------------\n\nAfter installing, you should be able to use musl via the musl-gcc\nwrapper. For example:\n\ncat > hello.c <<EOF\n#include <stdio.h>\nint main()\n{\n\tprintf(\"hello, world!\\n\");\n\treturn 0;\n}\nEOF\n/usr/local/musl/bin/musl-gcc hello.c\n./a.out\n\nTo configure autoconf-based program to compile and link against musl,\nset the CC variable to musl-gcc when running configure, as in:\n\nCC=musl-gcc ./configure ...\n\nYou will probably also want to use --prefix when building libraries to\nensure that they are installed under the musl prefix and not in the\nmain host system library directories.\n"
  },
  {
    "path": "user.libc/Makefile",
    "content": "#\n# Makefile for musl (requires GNU make)\n#\n# This is how simple every makefile should be...\n# No, I take that back - actually most should be less than half this size.\n#\n# Use config.mak to override any of the following variables.\n# Do not make changes here.\n#\n\nsrcdir = .\nexec_prefix = /usr/local\nbindir = $(exec_prefix)/bin\n\nprefix = /usr/local/musl\nincludedir = $(prefix)/include\nlibdir = $(prefix)/lib\nsyslibdir = /lib\n\nMALLOC_DIR = mallocng\nSRC_DIRS = $(addprefix $(srcdir)/,src/* src/malloc/$(MALLOC_DIR) crt ldso $(COMPAT_SRC_DIRS))\nBASE_GLOBS = $(addsuffix /*.c,$(SRC_DIRS))\nARCH_GLOBS = $(addsuffix /$(ARCH)/*.[csS],$(SRC_DIRS))\nBASE_SRCS = $(sort $(wildcard $(BASE_GLOBS)))\nARCH_SRCS = $(sort $(wildcard $(ARCH_GLOBS)))\nBASE_OBJS = $(patsubst $(srcdir)/%,%.o,$(basename $(BASE_SRCS)))\nARCH_OBJS = $(patsubst $(srcdir)/%,%.o,$(basename $(ARCH_SRCS)))\nREPLACED_OBJS = $(sort $(subst /$(ARCH)/,/,$(ARCH_OBJS)))\nALL_OBJS = $(addprefix obj/, $(filter-out $(REPLACED_OBJS), $(sort $(BASE_OBJS) $(ARCH_OBJS))))\n\nLIBC_OBJS = $(filter obj/src/%,$(ALL_OBJS)) $(filter obj/compat/%,$(ALL_OBJS))\nLDSO_OBJS = $(filter obj/ldso/%,$(ALL_OBJS:%.o=%.lo))\nCRT_OBJS = $(filter obj/crt/%,$(ALL_OBJS))\n\nAOBJS = $(LIBC_OBJS)\nLOBJS = $(LIBC_OBJS:.o=.lo)\nGENH = obj/include/bits/alltypes.h obj/include/bits/syscall.h\nGENH_INT = obj/src/internal/version.h\nIMPH = $(addprefix $(srcdir)/, src/internal/stdio_impl.h src/internal/pthread_impl.h src/internal/locale_impl.h src/internal/libc.h)\n\nLDFLAGS =\nLDFLAGS_AUTO =\nLIBCC = -lgcc\nCPPFLAGS =\nCFLAGS =\nCFLAGS_AUTO = -pipe\nCFLAGS_C99FSE = -std=c99 -ffreestanding -nostdinc \n\nCFLAGS_ALL = $(CFLAGS_C99FSE)\nCFLAGS_ALL += -D_XOPEN_SOURCE=700 -I$(srcdir)/arch/$(ARCH) -I$(srcdir)/arch/generic -Iobj/src/internal -I$(srcdir)/src/include -I$(srcdir)/src/internal -Iobj/include -I$(srcdir)/include\nCFLAGS_ALL += $(CPPFLAGS) $(CFLAGS_AUTO) $(CFLAGS)\n\nLDFLAGS_ALL = $(LDFLAGS_AUTO) $(LDFLAGS)\n\nAR      = $(CROSS_COMPILE)ar\nRANLIB  = $(CROSS_COMPILE)ranlib\nINSTALL = $(srcdir)/tools/install.sh\n\nARCH_INCLUDES = $(wildcard $(srcdir)/arch/$(ARCH)/bits/*.h)\nGENERIC_INCLUDES = $(wildcard $(srcdir)/arch/generic/bits/*.h)\nINCLUDES = $(wildcard $(srcdir)/include/*.h $(srcdir)/include/*/*.h)\nALL_INCLUDES = $(sort $(INCLUDES:$(srcdir)/%=%) $(GENH:obj/%=%) $(ARCH_INCLUDES:$(srcdir)/arch/$(ARCH)/%=include/%) $(GENERIC_INCLUDES:$(srcdir)/arch/generic/%=include/%))\n\nEMPTY_LIB_NAMES = m rt pthread crypt util xnet resolv dl\nEMPTY_LIBS = $(EMPTY_LIB_NAMES:%=lib/lib%.a)\nCRT_LIBS = $(addprefix lib/,$(notdir $(CRT_OBJS)))\nSTATIC_LIBS = lib/libc.a\nSHARED_LIBS = lib/libc.so\nTOOL_LIBS = lib/musl-gcc.specs\nALL_LIBS = $(CRT_LIBS) $(STATIC_LIBS) $(SHARED_LIBS) $(EMPTY_LIBS) $(TOOL_LIBS)\nALL_TOOLS = obj/musl-gcc\n\nWRAPCC_GCC = gcc\nWRAPCC_CLANG = clang\n\nLDSO_PATHNAME = $(syslibdir)/ld-musl-$(ARCH)$(SUBARCH).so.1\n\n-include config.mak\n-include $(srcdir)/arch/$(ARCH)/arch.mak\n\nifeq ($(ARCH),)\n\nall:\n\t@echo \"Please set ARCH in config.mak before running make.\"\n\t@exit 1\n\nelse\n\nall: $(ALL_LIBS) $(ALL_TOOLS)\n\nOBJ_DIRS = $(sort $(patsubst %/,%,$(dir $(ALL_LIBS) $(ALL_TOOLS) $(ALL_OBJS) $(GENH) $(GENH_INT))) obj/include)\n\n$(ALL_LIBS) $(ALL_TOOLS) $(ALL_OBJS) $(ALL_OBJS:%.o=%.lo) $(GENH) $(GENH_INT): | $(OBJ_DIRS)\n\n$(OBJ_DIRS):\n\tmkdir -p $@\n\nobj/include/bits/alltypes.h: $(srcdir)/arch/$(ARCH)/bits/alltypes.h.in $(srcdir)/include/alltypes.h.in $(srcdir)/tools/mkalltypes.sed\n\tsed -f $(srcdir)/tools/mkalltypes.sed $(srcdir)/arch/$(ARCH)/bits/alltypes.h.in $(srcdir)/include/alltypes.h.in > $@\n\nobj/include/bits/syscall.h: $(srcdir)/arch/$(ARCH)/bits/syscall.h.in\n\tcp $< $@\n\tsed -n -e s/__NR_/SYS_/p < $< >> $@\n\nobj/src/internal/version.h: $(wildcard $(srcdir)/VERSION $(srcdir)/.git)\n\tprintf '#define VERSION \"%s\"\\n' \"$$(cd $(srcdir); sh tools/version.sh)\" > $@\n\nobj/src/internal/version.o obj/src/internal/version.lo: obj/src/internal/version.h\n\nobj/crt/rcrt1.o obj/ldso/dlstart.lo obj/ldso/dynlink.lo: $(srcdir)/src/internal/dynlink.h $(srcdir)/arch/$(ARCH)/reloc.h\n\nobj/crt/crt1.o obj/crt/scrt1.o obj/crt/rcrt1.o obj/ldso/dlstart.lo: $(srcdir)/arch/$(ARCH)/crt_arch.h\n\nobj/crt/rcrt1.o: $(srcdir)/ldso/dlstart.c\n\nobj/crt/Scrt1.o obj/crt/rcrt1.o: CFLAGS_ALL += -fPIC\n\nOPTIMIZE_SRCS = $(wildcard $(OPTIMIZE_GLOBS:%=$(srcdir)/src/%))\n$(OPTIMIZE_SRCS:$(srcdir)/%.c=obj/%.o) $(OPTIMIZE_SRCS:$(srcdir)/%.c=obj/%.lo): CFLAGS += -O3\n\nMEMOPS_OBJS = $(filter %/memcpy.o %/memmove.o %/memcmp.o %/memset.o, $(LIBC_OBJS))\n$(MEMOPS_OBJS) $(MEMOPS_OBJS:%.o=%.lo): CFLAGS_ALL += $(CFLAGS_MEMOPS)\n\nNOSSP_OBJS = $(CRT_OBJS) $(LDSO_OBJS) $(filter \\\n\t%/__libc_start_main.o %/__init_tls.o %/__stack_chk_fail.o \\\n\t%/__set_thread_area.o %/memset.o %/memcpy.o \\\n\t, $(LIBC_OBJS))\n$(NOSSP_OBJS) $(NOSSP_OBJS:%.o=%.lo): CFLAGS_ALL += $(CFLAGS_NOSSP)\n\nifeq ($(BUILD_DEBUG), 1)\n  CFLAGS += -O0 -g\nelse\n  CFLAGS += -Os\nendif\n\n$(CRT_OBJS): CFLAGS_ALL += -DCRT\n\n$(LOBJS) $(LDSO_OBJS): CFLAGS_ALL += -fPIC\n\nCC_CMD = $(CC) $(CFLAGS_ALL) -c -o $@ $<\n\n# Choose invocation of assembler to be used\nifeq ($(ADD_CFI),yes)\n\tAS_CMD = LC_ALL=C awk -f $(srcdir)/tools/add-cfi.common.awk -f $(srcdir)/tools/add-cfi.$(ARCH).awk $< | $(CC) $(CFLAGS_ALL) -x assembler -c -o $@ -\nelse\n\tAS_CMD = $(CC_CMD)\nendif\n\nobj/%.o: $(srcdir)/%.s\n\t$(AS_CMD)\n\nobj/%.o: $(srcdir)/%.S\n\t$(CC_CMD)\n\nobj/%.o: $(srcdir)/%.c $(GENH) $(IMPH)\n\t$(CC_CMD)\n\nobj/%.lo: $(srcdir)/%.s\n\t$(AS_CMD)\n\nobj/%.lo: $(srcdir)/%.S\n\t$(CC_CMD)\n\nobj/%.lo: $(srcdir)/%.c $(GENH) $(IMPH)\n\t$(CC_CMD)\n\nlib/libc.so: $(LOBJS) $(LDSO_OBJS)\n\t$(CC) $(CFLAGS_ALL) $(LDFLAGS_ALL) -nostdlib -shared \\\n\t-Wl,-e,_dlstart -o $@ $(LOBJS) $(LDSO_OBJS) $(LIBCC)\n\nlib/libc.a: $(AOBJS)\n\trm -f $@\n\t$(AR) rc $@ $(AOBJS)\n\t$(RANLIB) $@\n\n$(EMPTY_LIBS):\n\trm -f $@\n\t$(AR) rc $@\n\nlib/%.o: obj/crt/$(ARCH)/%.o\n\tcp $< $@\n\nlib/%.o: obj/crt/%.o\n\tcp $< $@\n\nlib/musl-gcc.specs: $(srcdir)/tools/musl-gcc.specs.sh config.mak\n\tsh $< \"$(includedir)\" \"$(libdir)\" \"$(LDSO_PATHNAME)\" > $@\n\nobj/musl-gcc: config.mak\n\tprintf '#!/bin/sh\\nexec \"$${REALGCC:-$(WRAPCC_GCC)}\" \"$$@\" -specs \"%s/musl-gcc.specs\"\\n' \"$(libdir)\" > $@\n\tchmod +x $@\n\nobj/%-clang: $(srcdir)/tools/%-clang.in config.mak\n\tsed -e 's!@CC@!$(WRAPCC_CLANG)!g' -e 's!@PREFIX@!$(prefix)!g' -e 's!@INCDIR@!$(includedir)!g' -e 's!@LIBDIR@!$(libdir)!g' -e 's!@LDSO@!$(LDSO_PATHNAME)!g' $< > $@\n\tchmod +x $@\n\n$(DESTDIR)$(bindir)/%: obj/%\n\t$(INSTALL) -D $< $@\n\n$(DESTDIR)$(libdir)/%.so: lib/%.so\n\t$(INSTALL) -D -m 755 $< $@\n\n$(DESTDIR)$(libdir)/%: lib/%\n\t$(INSTALL) -D -m 644 $< $@\n\n$(DESTDIR)$(includedir)/bits/%: $(srcdir)/arch/$(ARCH)/bits/%\n\t$(INSTALL) -D -m 644 $< $@\n\n$(DESTDIR)$(includedir)/bits/%: $(srcdir)/arch/generic/bits/%\n\t$(INSTALL) -D -m 644 $< $@\n\n$(DESTDIR)$(includedir)/bits/%: obj/include/bits/%\n\t$(INSTALL) -D -m 644 $< $@\n\n$(DESTDIR)$(includedir)/%: $(srcdir)/include/%\n\t$(INSTALL) -D -m 644 $< $@\n\n$(DESTDIR)$(LDSO_PATHNAME): $(DESTDIR)$(libdir)/libc.so\n\t$(INSTALL) -D -l $(libdir)/libc.so $@ || true\n\ninstall-libs: $(ALL_LIBS:lib/%=$(DESTDIR)$(libdir)/%) $(if $(SHARED_LIBS),$(DESTDIR)$(LDSO_PATHNAME),)\n\ninstall-headers: $(ALL_INCLUDES:include/%=$(DESTDIR)$(includedir)/%)\n\ninstall-tools: $(ALL_TOOLS:obj/%=$(DESTDIR)$(bindir)/%)\n\ninstall: install-libs install-headers install-tools\n\nmusl-git-%.tar.gz: .git\n\t git --git-dir=$(srcdir)/.git archive --format=tar.gz --prefix=$(patsubst %.tar.gz,%,$@)/ -o $@ $(patsubst musl-git-%.tar.gz,%,$@)\n\nmusl-%.tar.gz: .git\n\t git --git-dir=$(srcdir)/.git archive --format=tar.gz --prefix=$(patsubst %.tar.gz,%,$@)/ -o $@ v$(patsubst musl-%.tar.gz,%,$@)\n\nendif\n\nclean:\n\t@ rm -rf obj lib\n\ndistclean: clean\n\t@ rm -f config.mak\n\n.PHONY: all clean install install-libs install-headers install-tools\n"
  },
  {
    "path": "user.libc/README",
    "content": "\n    musl libc\n\nmusl, pronounced like the word \"mussel\", is an MIT-licensed\nimplementation of the standard C library targetting the Linux syscall\nAPI, suitable for use in a wide range of deployment environments. musl\noffers efficient static and dynamic linking support, lightweight code\nand low runtime overhead, strong fail-safe guarantees under correct\nusage, and correctness in the sense of standards conformance and\nsafety. musl is built on the principle that these goals are best\nachieved through simple code that is easy to understand and maintain.\n\nThe 1.1 release series for musl features coverage for all interfaces\ndefined in ISO C99 and POSIX 2008 base, along with a number of\nnon-standardized interfaces for compatibility with Linux, BSD, and\nglibc functionality.\n\nFor basic installation instructions, see the included INSTALL file.\nInformation on full musl-targeted compiler toolchains, system\nbootstrapping, and Linux distributions built on musl can be found on\nthe project website:\n\n    http://www.musl-libc.org/\n"
  },
  {
    "path": "user.libc/VERSION",
    "content": "1.2.2\n"
  },
  {
    "path": "user.libc/WHATSNEW",
    "content": "0.5.0 - initial release\n\n\n\n0.5.9 - signal ABI bugfix, various cleanup and fixes:\n\nsigset_t was wrongly defined as 1024 bytes instead of 1024 bits,\nbreaking the intended ABI compatibility with the LSB/glibc sigaction\nstructure. users should upgrade immediately and rebuild any libraries\nor object files that might be using the incorrect definitions.\n\nimproved security against DoS with tcb shadow passwords by checking\nthat the file opened was really an ordinary file.\n\nfixed a bug in the implementation of atomic ops that could have\nallowed the compiler to incorrectly reorder them (in practice, gcc\nwith the default settings on i386 was not reordering them).\n\ngreatly improved conformance to the C and POSIX standards regarding\nwhat the standard header files make visible. _POSIX_C_SOURCE is now\nneeded to get POSIX functions in standard C headers, and _XOPEN_SOURCE\nor _GNU_SOURCE are required to get XSI interfaces or GNU extensions,\nrespectively.\n\nmany internal improvements have been made to the syscall-related code\nin preparation for porting to x86_64 and other archs.\n\n\n\n0.6.0 - x86_64 port, various important bugs fixed\n\nnew x86_64 (amd64) architecture port, contributed by Nicholas J. Kain,\nalong with PORTING guide. source tree layout and build system have\nbeen improved to accommodate further ports.\n\nvarious bugs that were introduced while making the headers respect C\nand POSIX namespace standards have been fixed. conformance to the\nstandards has been improved.\n\nfixed an inefficiency in qsort that triggered a bug (occasionaly\ninternal compiler error) in some versions of gcc.\n\nfixed a major bug in the printf %n specifier that prevented it from\nworking and caused memory corruption.\n\n\n\n0.7.0 - major improvements to posix conformance and completeness\n\nimplemented posix shared memory and semaphore interfaces.\n\nimplemented all remaining required pthread and clock interfaces.\n\nmajor fixes to signal semantics.\n\ngreatly improved temporary file name generation for safety against\ndenial of service due to intentional name collisions.\n\nadded syscall wrappers for the linux inotify interface.\n\nmalloc(0) now returns a non-null pointer.\n\nfixed printf %n specifier (again), pthread_once (it was always\nhanging), and non-default-type mutex behavior.\n\nadded ucontext/sigcontext support in headers to facilitate building\nlibgcc with dwarf2 unwind support, and possibly other low-level tools.\n\nimproved musl-gcc compiler wrapper.\n\nimplemented many small missing functions here and there, minor header\nfixes, etc.\n\n\n\n0.7.1 - improvements to completeness, bug fixes\n\nimplemented flockfile, wprintf, and robust mutex functions.\n\nfixed stack corruption bug in times(), minor header bugs, and some\nerror return value bugs in thread interfaces.\n\n\n\n0.7.5 - new features, major optimization, and robustness\n\nimplemented POSIX timers.\n\noptimized and simplified many thread-related functions.\n\neliminated resource leak races in thread cancellation. (almost all\nexisting implementations, including glibc, have these leaks.)\n\noverhauled stdio implementation to take advantage of readv/writev for\nreduced syscall load, and improved stdio's handling of error status.\n\nadded syscall header and interface for applications to use and\ngreatly simplified internal system for making syscalls.\n\nstrangthened tmpnam/tempnam/tmpfile filename generation and made the\nstraight C functions not depend on POSIX symbols.\n\nfixed pthread cancellation ABI on i386 to match the LSB/glibc ABI\n\nbetter double-free handling in malloc\n\nvarious minor bug fixes\n\n\n\n0.7.6 - major bug fixes\n\nfixed rare but serious under-allocation bug in malloc.\n\nfixed signedness bug in strchr that prevented finding high bytes.\n\nfixed serious parsing bugs in strtold.\n\nfixed statvfs syscall (it was always failing with EINVAL).\n\nfixed race condition in set*id() functions with threads (possible\ndeadlock). further audit still needed though.\n\nfseek no longer sets the stream error flag on failed seeks (this was\nwrong and broke some programs, notably GNU m4).\n\nnl_langinfo is no longer a dummy function. (the functionality was\npreviously implemented but accidentally left unused).\n\nvarious small fixes have been made to the implementations and\nprototypes for nonstandard and obsolete functions\n\n\n\n0.7.7 - more bug fixes and program-compatibility improvements\n\nfixed floating point formatting and rounding bugs in printf.\n\nfixed broken %N$ positional argument specifiers in printf.\n\nfixed misaligned read/overread bug in strchr which could lead to\ncrashes scanning tiny strings at the end of a page when the next page\nis not readable, or on archs (not yet supported) that forbid\nmisaligned reads.\n\nfixed breakage of statvfs on x86_64\n\nfixed crash in getmntent_r\n\nfixed bug in POSIX timers created with NULL sigevent argument\n\nimproved semaphore performance, and sem_wait is now interruptable by\nsignals, as required by POSIX.\n\nadded many compatibility and system-level interfaces, increasing the\nproportion of busybox that works with musl.\n\n\n\n0.7.8 - more bug fixes and compatibility improvements\n\nfixed problems with ipv6 dns and address printing code that made ipv6\nsupport practically unusable, and some other getaddrinfo bugs.\n\nfixed broken sendmsg/recvmsg functions on x86_64 (caused by incorrect\nmsghdr structure).\n\nfixed broken sigsetjmp asm on x86_64.\n\nworked around a problem with input buffering on terminals reblocking\nafter getting a blank line, due to a bug in the linux readv syscall.\n\nvarious improvements to the \"rsyscall\" system used to implement\nthreaded setuid, setgid, etc.\n\nexiting/cancelling the a timer handler thread no longer kills the\ntimer.\n\nfixed incorrect trailing zeros on some %g conversions in printf.\n\nfixed buggy byte-swapping functions and moved them to inlines in\nbyteswap.h.\n\nmany small improvements to header/application compatibility, support\nfor nonstandard macros, etc.\n\n\n\n0.7.9 release notes\n\nnew pthread cancellation implementation:\n- safe against resource-leak/side-effect-leak race conditions\n- safe against interruption by signal handlers\n- reduced bloat in all cancellable functions\n- reduced bloat for blocking cancellation\n\nnew interfaces implemented:\n- realpath (limited functionality)\n- wordexp (limited functionality)\n- flock (nonstandard)\n- forkpty (nonstandard)\n- posix_fadvise\n- posix_fallocate\n\ngeneral bug fixes:\n- syslog function failure to communicate with syslogd\n- bug in siginfo_t definition if wait.h was included before signal.h\n- incorrect struct definitions for most of sysv ipc\n- pthread_exit/cancel on timer handler wrongly destroying the timer\n- linux dup2 ebusy workaround\n- obscure issues in non-threaded programs using some pthread functions\n- getopt_long allowed mismatch in last char of option name\n- incorrect parsing of obscure ip address forms\n- initgroups not working reliably (uninitialized var)\n- shadow pass treating empty expiry field as pass-expired-in-1970\n- bogus longjmp if pthread_exit was called from cancellation handlers\n\nx86_64-specific bug fixes:\n- fcntl file locking\n- thread stack alignment\n- broken select timeouts due to incorrect timeval definition\n\n\n\n0.7.10 release notes\n\nnew features:\n- ipv6 numeric string parsing\n- eventfd syscall wrappers\n\noptimizations:\n- new qsort implementation using the smoothsort algorithm\n- much smaller/faster sigset_t handling functions\n- lowered spin count before futex wait in synchronization functions\n\ngeneral bug fixes:\n- incorrect floating point round-to-even behavior in printf\n- major bugs in pthread barrier implementation\n- off-by-one error in scanf %n results\n- scanf failure to report EOF when scanning for literal text\n- minor missing/incorrect prototype issues\n- dependency on undefined call order in fclose\n\ncompiler issue workarounds:\n- incorrect inlining of variadic functions on recent gcc versions\n- pcc preprocessor bug with recursive macro expansion\n\n\n\n0.7.11 release notes\n\nnew features:\n- integrated dynamic linker\n- dynamic loading (dlopen/dlsym) (for dynamic-linked programs only)\n- XSI search.h API\n- POSIX message queues\n- POSIX spawn interfaces\n- BSD pseudo-random number generator API (random/srandom/initstate/etc.)\n- floating point environment (limited usefulness due to gcc bugs)\n\ngeneral bug fixes:\n- possible crashes with wordexp due to uninitialized variable\n- race condition in pthread_kill (also present and unfixed in glibc/nptl)\n- pthread exit destructors called too late\n- dangerous unbounded vla in glob\n- brk/sbrk legacy functions mismatching legacy semantics\n- wcsncpy dest buffer overflow\n- strncat and wcsncat possible overflows due to double-termination\n\n\n\n0.7.12 release notes\n\nnew features:\n- support for textrels in shared objects\n- rpath support in dynamic linker\n- stdio_ext.h functions (for better gnu software compatibility)\n\nbug fixes:\n- some compilers miscompiling dlopen due to misuse of longjmp\n- safe handling of invalid long-double bit patterns (affects printf)\n- workaround for bugs in linux mprotect syscall\n- thread-safety for random() functions\n- various minor issues\n\n\n\n0.8.0 release notes\n\nnew features:\n- chinese and japanese legacy charset support in iconv\n- zero-syscall clock_gettime support (dynamic-linked x86_64 only)\n- futex-based locking for stdio (previously used spinlocks)\n- LD_PRELOAD and RTLD_NEXT support in dynamic linker\n- strptime (mostly working but incomplete)\n- posix aio (mostly working but not entirely conformant)\n- memory streams (fmemopen, open_memstream, ...)\n- stub/dummy implementations for various useless legacy functions\n- if_nameindex\n\nsecurity hardening:\n- setuid, etc. should not longer be able to \"partially fail\" with threads\n- ensure suid programs start with fd 0,1,2 open\n- improved openpty/forkpty failure checks\n\nthreads/synchronization bug fixes:\n- dangerous spurious wakeup in pthread_join lead to early return\n- race condition enabling async cancellation (delayed/lost cancellation)\n- destruction/unmapping race conditions in semaphores, mutexes, rwlocks\n- recursive rwlock_rdlock deadlock when a writer is waiting\n- race condition in sigqueue with fork\n- timer expiration thread exit wasn't running dtors\n- timer threads weren't blocking signals\n- close was wrongly cancellable after succeeding on some devices\n- robust mutex list was not reset on fork\n\ngeneral bug fixes:\n- incorrect logic in fread (spurious blocking; crash on write-only files)\n- many corner cases and overflow cases for strtol-family functions\n- various printf integer formatting issues with flags/width/precision\n- incorrect iconv return value on failure\n- broken FD_* macros on 64-bit targets\n- clock function returning wrong value (real time not cpu time)\n- siglongjmp signal mask clobbering (off-by-one pointer error)\n- dynamic linker weak symbol resolution issues\n- fdopendir failure to set errno\n- various minor header fixes\n\n\n\n0.8.1 release notes\n\nbug fixes:\n- mismatching prototypes caused build failure on 64-bit\n- other minor prototype errors in the headers have been fixed\n- various other small omissions fixed\n\n\n\n0.8.2 release notes\n\nnew features:\n- ptrace syscall support\n\nbug fixes:\n- const error (only a warning with many compilers) in lio_listio\n- minor portability fixes aimed at supporting new arch targets\n\n\n\n0.8.3 release notes\n\nnew features:\n- arm port (experimental)\n- better musl-gcc wrapper script for building against musl\n- added clone system call\n\nbug fixes:\n- numerous header file typos, copy/paste errors, omissions\n- statfs and statvfs ABI are now LSB-conformant (and actually work)\n\n\n\n0.8.4 release notes\n\nnew features: \n- arm dynamic linker support\n- process-shared pthread barriers now work\n- efficient futex-requeue-based cond var broadcast\n- more optional cancellation points are now cancellable\n- printf accepts null pointers with %s, prints as \"(null)\"\n- recursive mutexes are now fully reentrant\n- __cxa_atexit support\n- real vfork\n- dynamic linker now gold-compatible\n- prlimit syscall\n- support for large limits with setrlimit/getrlimit (even on 32-bit)\n- glob now supports GLOB_PERIOD option (GNU extension)\n\nbug fixes:\n- many serious issues in condition variables\n- rwlock failure-to-wake deadlock issues\n- various small header files bugs/omissions\n- wrong failure return for pthread_create\n- path handling issues on execvp\n- lock count corruption with robust recursive mutexes on owner death\n- integer overflows in atoi, etc. reading most-negative value\n- spurious mremaps on every realloc of large memory chunks\n- pthread cancellation failure in single-threaded programs\n\nsecurity:\n- avoid fd_set overflow in dns lookups\n\n\n\n0.8.5 release notes\n\nnew features:\n- stdio operations are now cancellable (only when low-level io happens)\n- global ctor/dtor support in main program start code and shared libs\n- dynamic linker support for PIE executables (but missing startup code)\n- vfork support on x86_64\n- complete set of locale_t functions (all ignore the locale argument)\n- provide define float_t and double_t in math.h\n- lighter/faster cancellation cleanup handler register/unregister\n\nbug fixes:\n- gcc wrapper now supports -shared, -nostdlib, -nostartfiles\n- removed one wrongly-classified character from iswspace set (zwsp)\n- fixed crashes in dns lookup on some errors, e.g. resolv.conf missing\n- \"make install\" no longer tries to build shared libc if disabled\n- ptrace argument handling bugs fixed\n- work around visibility-hidden bugs in gcc 3.x\n- fix thread-pointer-loss issue when it's initialized in signal handlers\n- various minor typo/misc fixes in headers\n\ncompatibility:\n- glob behaves more like traditional implementations w.r.t. GLOB_MARK\n- added legacy futimes, lutimes functions\n- more compatibility macros in sys/param.h (nonstandard header)\n- setfs[ug]id syscall wrappers (linux specific)\n- fgetpwent function (nonstandard)\n- utmp.h matches traditional version more closely\n- caddr_t now matches glibc type (void * instead of long)\n- dummy (always-fail) dlopen and dlsym functions for static linked programs\n- [efg]cvt functions (previously posix, removed from standard)\n- get_current_dir_name function (nonstandard)\n\n\n\n0.8.6 release notes\n\nbug fixes:\n- fix crash in dns lookups for all static-linked, non-threaded programs\n\n\n\n0.8.7 release notes\n\nnew features:\n- c++ support with g++'s libstdc++\n- c99 math library (float, long double, complex, etc.)\n- numerous wchar_t functions\n- a64l, l64a functions\n- getdate function\n\ncompatibility:\n- c89 compatibility in math.h\n- syscall.h alias for sys/syscall.h\n- memory.h alias for string.h\n- getcwd supports null buffer argument (auto-allocation)\n\nbug fixes:\n- major fenv (floating point environment) fixes and optimizations\n- strptime mishandling of day/month names\n- strtoull wrongly rejecting the highest 16 possible values as overflow\n- math.h constant expression fixes for INFINITY/NAN/etc.\n- scanf mishandling of \"0\" with \"%x\"\n\n\n\n0.8.8 release notes\n\nnew feature:\n- major math correctness and performance improvements\n- many math functions implemented in asm for i386\n- some math functions (mostly long double) in asm for x86_64\n- new floating point parser/converter with correct rounding\n- implement wcstod, wcstof, and wcstold\n- new scanf implementation - cleaner, faster, more correct\n- minimal/incomplete strfmon implementation\n\ncompatibility:\n- header fixes for c++\n- regex code resync with TRE; support common regex extensions\n- support for compiling apps with gcc's -funsigned-char\n- sysconf now returns dynamic limits for open files, processes\n- give dlerror proper error status stickiness\n- make alloca work even with -fno-builtin\n\ncritical security fixes:\n- stack-based buffer overflow in fprintf on unbuffered files\n\nother bug fixes:\n- rare gcc register allocation (miscompilation) bug in syscall wrappers\n- printf was rejecting the valid (but redundant) %lf format specifier\n- fixed big data bloat (missing const) in math functions\n- many math fixes related to floating point exceptions and rounding\n- corrected DECIMAL_DIG definitions\n- tgammal was wrongly setting global signgam\n- crash in wordfree with uninitialized we_offs\n- fix wordexp not null-initializing the we_offs initial slots\n\n\n\n0.8.9 release notes\n\nbug fixes:\n- major breakage in strtol and family: failure to accept leading spaces\n- incorrect name for MATH_ERREXCEPT in math.h\n\ncompatibility:\n- prototypes for a few additional nonstandard functions\n\n\n\n0.8.10 release notes\n\nnew features:\n- correct over/underflow detection (ERANGE setting) for strtod\n- new musl-gcc wrapper, specfile based, faster and more robust\n- meaningful return strings for dlerror\n- new iswalpha, iswpunct, and wcwidth; sync'd to Unicode 6.1\n- towupper/towlower sync'd with Unicode 6.1\n- new futex-based libc-internal locks instead of spinlocks\n- experimental stack protector support (minimal; no random canary)\n- experimental gdb shared library tracking support\n\ncompatibility:\n- getusershell family functions\n- getresuid and getresgid syscall wrappers\n- byte swapping macros in endian.h\n- getdtablesize was wrongly declared in unistd.h for _XOPEN_SOURCE\n\nbug fixes:\n- iconv_open wrongly rejecting most dest charsets (broken in 0.8.0)\n- sysconf failure when correct value is -1 (broken in 0.8.8)\n- scanf and strtod family functions overreading past NAN (4 bytes vs 3)\n- scanf and strtod wrongly treating \"0.00000000001\", etc. as 0\n- many bugs in towupper/towlower (never seriously tested before)\n- int8_t definition was wrong when gcc -funsigned-char was used\n\n\n\n0.9.0 release notes\n\nlicense change: MIT\n\nnew features:\n- configure script, improved build system\n- full stack protector support\n- PIE support on x86 and x86_64\n- new O(1) space, O(nm) time implementation of fnmatch\n- improved support for sse2 floating point mode on x86\n\ncompatibility:\n- added linux unshare syscall\n- exp10/pow10 function\n- sqrtl support on arm (previously missing)\n- removed minimal linux/*.h headers that could conflict with real ones\n- support for _LARGEFILE64_SOURCE (mapped to standard fcns with #define)\n- better c89 compatibility in headers\n- stub versions of sched_* functions (previously missing)\n- pthread stacks no longer executable (compat with hardened kernels)\n- new ar.h and lastlog.h (legacy junk)\n- various other header improvements\n\noptimization:\n- additional x86_64 math asm\n- better formula for acos use in i386 asm\n\nbug fixes:\n- large (up to a few %) errors in strtod for certain values due to bug\n- mbsnrtowcs and wcsnrtombs were completely broken (bad exit logic)\n- wide printf %.0s could fail due to uninitialized variable\n- missing dlerror strings for dlsym in some cases\n\n\n\n0.9.1 release notes\n\nnew features:\n- dynamic linker can be used as a program to explicitly load/run executables\n- ldd command, usable by making a symlink to the dynamic linker named ldd\n\nbug fixes:\n- major bugs in POSIX BRE parsing inherited from TRE regex code\n- character matching bug in regex on ARM: WCHAR_MAX was assumed to be signed\n- various obscure fixes related to signals and pthread cancellation\n- remquot subnormal remainder bug\n- buggy macros in (nonstandard) sys/param.h\n- major bug in pthread barriers on x86_64 (out of bounds write)\n- utimes (legacy) function was making wrong syscall (utime instead of utimes)\n- avoid using \"old\" syscalls that don't exist on arm eabi linux\n- broken strrchr(str, 0)\n- broken mbsinit(0)\n- broken wcsncmp\n- syntax error in nextafter macro in tgmath.h\n- missing support for -pie in musl-gcc wrapper\n- abort could wrongly fail to terminate the program in some cases\n\ncompatibility:\n- increase default thread stack size to 80k\n- support _BSD_SOURCE feature test macro\n- support _LARGEFILE64_SOURCE feature test macro (merely exposes alt names)\n- lots of legacy-compatibility improvements in headers\n- various minor GNU extension functions\n- sysconf reporting number of available CPUs/cores\n- various LSB/glibc ABI interfaces aimed at compatibility with some binaries\n- use fistpll asm mnemonic instead of fistpq for compat with clang\n\n\n\n0.9.2 release notes\n\nbug fixes:\n- pointer overflow in printf (crash on 32bit userspace, 64bit kernel)\n- printf %ls over-read bug\n- strtod failure to read -0x as negative zero\n- flush stdio after dtors, not before\n- wrong file position for buffered input streams on exit\n- popen was broken when stdin/out were already closed\n- broken wcwidth tables (missing many characters)\n- fwrite: wrong return value of partial/failed write\n- broken utf-16 conversions\n- bad buffer length check in getlogin_r\n- bad perror(\"\") behavior; did not match perror(0)\n- broken sysinfo syscall/structure\n- stdint.h const macro signedness bugs\n- broken include guards in some headers\n- bogus localeconv values\n- cancellation-safety for popen and pclose\n- fma corner cases wrong on i386\n- fcntl F_GETOWN errno missing on failure.\n- char signedness bug in dynamic linker broke dlopen on arm\n- mprotect failure in dynamic linker caused crash instead of error\n\nbuild system:\n- configure check to work around hacked-up gcc versions\n- test for old binutils that can't support musl dynamic linker\n\ncompatibility:\n- make _GNU_SOURCE imply _LARGEFILE64_SOURCE\n- syscall wrapper for lots of nonstandard and/or legacy linux syscalls\n- versionsort stub\n- timegm function (inverse of gmtime)\n- various minor header tweaks\n- make __freading/__fwriting semantics match traditional ones\n- added gnulib-compatibility stdio interfaces\n- added pthread_attr_setstack interface\n- make strerror_r return partial string when buffer is too small\n- duplocale should accept LC_GLOBAL_LOCALE\n- align ptsname_r to upcoming posix requirements\n- support invalid ld80 bit patterns as extra nans.\n\n\n\n0.9.3 release notes\n\nnew features:\n- mips (32-bit, o32 abi) port, currently static-linked only\n- newly overhauled crypt implementation\n- improved library pathname info for debugger from the dynamic linker\n- getaddrinfo (and getservbyname) now support /etc/services lookups\n- pipe2 syscall wrapper\n- splice and vmsplice syscall wrappers\n- syscall wrappers for extended attribute interfaces\n- ioperm/iopl syscall wrappers on archs that support these operations\n\nbug fixes:\n- dlsym RTLD_NEXT library search order was wrong\n- multiple dlopen pathname and library name handling errors\n- potential race condition in detached thread exit\n- broken internal-lock-handling code not updated for futex-based __lock\n- sem_trywait spurious EAGAIN errors arising from CAS failures\n- workaround kernel bug in cmsghdr size_t vs socklen_t issue (64-bit)\n- getservby* crash on null protocol argument\n- logic error skipping failed interfaces in if_nameindex\n- various minor header/declaration related issues\n\narm-specific bug fixes:\n- broken crti/crtn startup code when gcc crtbegin/end files are linked\n- sigsetjmp tail call optimization failure broke the function\n- incorrect little-endian assumptions in atomic.h functions\n- use of blx instruction in asm (not supported on pre-v5 arm)\n\nbuild system:\n- only use expensive -ffloat-store cflag on archs/compilers that need it\n- make musl-gcc wrapper support -lgcc (mainly for self-hosting)\n\n\n\n0.9.4 release notes\n\nnew features:\n- blowfish crypt\n- dynamic linking on mips\n- arm hard float support\n- BSD fgetln function in stdio\n- minor header improvements for compatibility\n- support for CROSS_COMPILE variable to configure\n- legacy significand function\n- better support for SUSv3-targeted programs\n\nperformance:\n- assembly (string ops based) memcpy for i386 and x86_64\n- reduce printf overhead\n\nbug fixes:\n- failure of strtod, etc. to process extremely long strings correctly\n- read overrun in wcsstr for short needles\n- various major mips issues that prevented most software from working\n- erroneous floating point exception behavior in i386/x86_64 exp asm\n- crashes on null arguments to legacy err.h functions\n- various header file/type issues\n- extremely rare/obscure race condition with robust mutexes\n- crypt now never returns null (most programs don't check, then crash)\n- missing xattr remove functions\n\n\n\n0.9.5 release notes\n\ncompatibility and headers:\n- POSIX+XSI+BSD features enabled by default with no macros defined\n- most programs can now be built without adding -D_GNU_SOURCE\n- added C99 restrict keyword where required in all prototypes\n- greater C89 compatibility\n- cleaner, more-compatible public syscall.h\n- many other header fixes\n- support for compiling musl with clang/llvm\n\nnew features:\n- sha 256/512 password hash functions in crypt\n- GNU hash support in dynamic linker\n- partial C11 coverage\n- dladdr function added\n- dynamic linker reports all errors instead of exiting on first error\n- syscall wrappers added for most remaining linux syscalls\n- provide POSIX O_SEARCH open mode using linux O_PATH\n\nbug fixes:\n- most atexit functions were being skipped when exiting\n- some BSD functions were not being exposed under _BSD_SOURCE\n- issues loading ssp-protected DSO into non-ssp program with dlopen\n\ndebloating:\n- eliminate .eh_frame (10-15% loaded size bloat)\n- optimal inline syscall asm for ARM and MIPS\n- no longer force -O3 for shared libs\n\n\n\n0.9.6 release notes\n\nbug fixes:\n- serious breakage in definition of O_ACCMODE mask (missing a bit)\n\nnew features:\n- O_EXEC open mode\n- md5 crypt hash function\n\n\n\n0.9.7 release notes\n\nnew features:\n- thread-local storage (__thread/_Thread_local)\n- microblaze port\n- getopt option parsing reset support\n- vsyscall (sysenter, etc.) support on i386 (faster syscalls)\n- memmem function (GNU extension)\n- mips fenv support\n- accept \"nan(n-char-sequence)\" in strtod/scanf family functions\n- configure now supports compiling with pcc\n\nquality and correctness improvements:\n- close-on-exec flag for all library-internal file descriptors\n- cancellation-safety and corner-case overhaul in shm_open/sem_open\n- close EINTR vs EINPROGRESS issue\n- mark binaries as not requiring executable stack\n- better gdb compatibility in dynamic linker\n- support recursive dlopen (dlopen called from constructors)\n- posix_spawn/system/popen no longer momentarily double commit charge\n- all stdio functions wait for locks\n\nbug fixes:\n- broken sysvipc *ctl functions on 64-bit archs\n- broken shmdt on some archs\n- getaddrinfo failure with port \"0\"\n- dirname handling of trailing slash\n- vfork race in posix_spawn\n\n\n\n0.9.8 release notes\n\nnew features:\n- powerpc port\n- dl_iterate_phdr interface\n- added mips-specific syscalls\n- thread priority scheduling\n- C11 CMPLX macro in complex.h\n- x86 port io functions in sys/io.h\n\ncompatibility:\n- improved headers for trace/debugging/machine-access\n- stub functions for unsupported thread-related functionality\n\nbug fixes:\n- numerous math bugs (mostly exception flags and excess-precision issues)\n- register clobber error in i386 vsyscall asm (did not affect most callers)\n- various incorrect definitions in mips headers\n- broken dlsym asm on mips\n- empty prefix handling in configure script (--prefix=\"\")\n- ldso search path logic issues\n- lock handling for stdio memory streams at exit time\n- invalid SO_REUSEPORT definition in socket.h (not supported by Linux)\n- broken redirection attempt to /dev/null in configure script\n\n\n\n0.9.9 release notes\n\nnew features:\n- tgamma implementation (no longer lgamma wrapper with low precision)\n- various gnu extensions: sigandset, sigorset, etc.\n- futimesat function (obsolete)\n- various linux syscalls: arch_prctl, personality, etc.\n\noptimizations:\n- hyperbolic, inverse hyperbolic, and inverse trig, bessel functions\n- is* comparison macros in math.h now expand inline properly\n\nlibrary bugs fixed:\n- calling getenv from shared library ctors was broken\n- invalid read in mmap-serviced aligned_alloc/memalign (possible crash)\n- wrong errno result in fallback path of pipe2 \n- various math functions raising spurious exceptions\n- mmap errno value on invalid offsets\n- backwards alignment logic in strlcpy\n- integer overflows in bessel functions\n- large (up to 60ulp) error in erfcf\n- dlsym/dlclose crashing on invalid library handles\n- failure to handle arch variations for cloexec/nonblock flags\n- lio_listio wrong return value for LIO_WAIT mode\n- dladdr failure to resolve PLT addresses\n- time_t/struct tm conversion off-by-one-day in december\n- malloc corruption on nonstandard kernels with non-page-aligned brk\n\narch-specific bugs fixed:\n- arm ctors/dtors were not working with recent gcc versions\n- arm and mips setjmp/longjmp wrongly saved/restored fenv state\n- loss of precision in i386/x86_64 expl\n\nheader bugs fixed:\n- incorrect PRI/SCN macros in inttypes.h for some types\n- arm sys/user.h regressions\n- failure of offsetof() to be an integer constant expression\n- tgmath return value type problems\n\nheader compatibility improvements:\n- _GNU_SOURCE now enables everything; _ALL_SOURCE also works\n- scsi/scsi.h and scsi/sg.h are now provided\n- additional MAP_* flags for mmap\n- additional F_* commands and flags for fcntl\n- additional socket option, IPPROTO_* values, and multicase macros\n- thread-related waitpid flags\n- EHWPOISON added to errno.h\n- additional macros for mount, swap, and reboot operations\n- expose additional link.h structures\n- always ensure sizeof(NULL)==sizeof(void *), even in c++\n- additional flags for poll, epoll, inotify, timerfd, timex, dlfcn\n- register names in signal.h/ucontext.h for x86\n- ipc.h ipc_perm nonstandard struct field name compatibility improve\n\n\n\n0.9.10 release notes\n\nnew features:\n- getifaddrs \n- pthread_getattr_np (widely used by garbage collectors)\n- mkostemps, mkostemp, mkstemps functions (mkostemp is future-POSIX)\n- strcasestr and strverscmp (previously stubs)\n\nimprovements:\n- major performance improvements in mbtowc\n- avoid filling caller-provided thread stacks with large TLS\n- debloat unnecessary static buffers\n- robust posix_spawn based on CLONE_VM instead of vfork\n- new system() and popen() based on posix_spawn\n- better strerror strings\n- further emulation of atomic close-on-exec/nonblock options for old kernels\n- provide macro constants for new-ish kernel features\n\ncompatibility:\n- several nonstandard but widely-available pwd/grp/shadow functions\n- program_invocation_[short_]name\n- re-added useconds_t type used by some programs\n- some legacy arpa headers\n- dn_skipname function (legacy resolver API)\n- additional ABI aliases for supporting glibc-linked libraries/binaries\n\ngeneral bugs fixed:\n- stale locks and bogus munmap call when pthread_create fails\n- uninitialized argument to munmap when dynlink load_library fails\n- incorrect error returns in gethostby*_r\n- memory leak in gethostbyname family\n- blank ai_canonname in getaddrinfo for non-CNAME records\n- undefined HZ macro in scsi/sg.h\n- wrong return value for wmemmove on forward-copy\n- namespace conformance in strings.h\n- various utmp.h bugs\n- unnecessary DT_SONAME in libc.so caused problems on some systems\n- multiple bugs in syslog, some possibly dangerous\n- non-functional setpriority function\n- slight mishandling of 0xf5 byte in UTF-8 decoder\n- misaligned memory accesses in mbsrtowcs\n\narch-specific bugs fixed:\n- crash in shared library loading on arm\n- missing __aeabi_atexit needed by arm eabi\n- wrong float_t definition on x86_64\n- various low-impact type size/alignment mismatches in some headers\n- epoll struct alignment wrong on non-x86[_64] archs\n- broken pipe2 fallback code on mips with old kernels\n\n\n\n0.9.11 release notes\n\nnew features:\n- %m allocation modifier for scanf\n- week number and ISO week-based-year functionality in strftime\n- per-process and per-thread cputime clocks\n- ethernet address conversion interfaces\n- legacy classful ipv4 network address interfaces\n- minimal dlinfo function (nonstandard)\n\nother improvements:\n- dynamic linker path file can now use newlines to separate paths\n- math optimizations for archs with extended precision (i386)\n- musl-gcc wrapper now exposes gcc's intrinsic headers\n- quality of rand and rand_r pseudo-random sequences\n- support for large device minor numbers (greater than 8 bits)\n- various header conformance and compatibility fixes\n\ndirectly user-visible bugs fixed:\n- scanf losing characters on unbuffered streams and fmemopen streams\n- failure of mbsrtowcs to record stop position when dest is full\n- failure of iconv to convert to legacy codepages\n- non-working pthread_[sg]etschedparam functions (wrong syscall arguments)\n\nother potentially-serious bugs fixed:\n- resource leaks in sem_open\n- various bugs in thread exit synchronization\n- invalid access in aio notification after aiocb free/reuse\n- synchronization in dynamic linker when new thread dlopens during ctors\n- lack of error handling for failure to read dynamic linker path file\n- creation by mmap or shmget of objects larger than PTRDIFF_MAX\n\nminor conformance bugs fixed:\n- overflow handling for the clock function\n- workaround for incorrect exceptions in fma due to compiler bugs\n- workaround wrong kernel type for sem_nsems field in struct semid_ds\n\narch-specific bugs fixed:\n- x86_64 sigsetjmp clobbered the signal mask rather than saving it\n- misaligned stack when calling ctors/dtors (crashing on x86_64)\n\n\n\n0.9.12 release notes\n\nnew features:\n- zoneinfo time zone support\n- PIE support on all supported archs\n- named sub-archs for endian and float ABI variants\n- improved support for non-root installs of the dynamic linker\n- ability to selectively build only performance-critical modules with -O3\n- simple buffer overflow detection in free/realloc\n- inet_ntop now presents v4-mapped addresses in ::ffff:a.b.c.d form\n- ldd now reports libc and the dynamic linker in its output\n\ncompatibility:\n- support for new init/fini array (needed for ctors/dtors on newer gcc)\n- C++ ABI fully matches glibc/LSB, at least on x86\n- many added ABI compatibility symbols for using glibc-linked libs\n- support for STB_GNU_UNIQUE symbol bindings (found in some C++ libs)\n- macros/types for new Linux kernel features in headers\n\nbugs fixed:\n- crashes in scanf on literal mismatches (regression from adding %m)\n- dl_iterate_phdr was passing invalid phdr pointers to its callback\n- getaddrinfo with null host and AF_UNSPEC was failing to report IPv6\n- integer overflows in date/time conversion code\n- misinterpretation of pre-1930s dates as post-2038 on 32-bit archs\n- make install failed to install bits headers if make was not run first\n- shm_open was wrongly cancellable\n- low- or no-impact heap corruption in memalign\n- explicitly running the dynamic linker on PIE programs did not work\n- missing macros and sysconf for some supported POSIX option groups\n- missing close-on-exec flags for several internal fd uses\n\narch-specific bugs:\n- wrong SIG_ATOMIC_MIN/MAX macros on x86_64\n- erfcl was missing on archs where long double is same as double\n- broken dynamic-model TLS in static-linked arm/mips/powerpc programs\n\n\n\n0.9.13 release notes\n\nnew features:\n- iconv support for EUC-KR and Big5 (including HKSCS) encodings\n- field widths (POSIX 2008 feature) in strftime\n- recursive rpath and $ORIGIN support in dynamic linker\n- cpu affinity interfaces\n- support for armhf (hardfloat) floating point environment (fenv)\n- support for SSE fenv on i386 (for apps using -mfpmath=sse -msse2)\n- strftime %s format (seconds since the epoch, future POSIX requirement)\n- configure script now saves its command line as a comment in config.mak\n- legacy functions valloc and euidaccess\n\nperformance:\n- optimized asm memcpy for arm\n- optimized asm memset for i386 and x86_64\n- optimized C versions of memcpy and memset for all archs\n- eliminated major spurious syscalls from posix_spawn\n- some math asm for armhf (hardfloat)\n\nworkarounds for:\n- qemu-user's rt_sigaction syscall does not allow old to alias new\n- qemu-user's madvise always succeeds (broke pthread_getattr_np)\n- passing PT_INTERP to dlopen attempted to double-load libc\n- gcc 4.8.x generating self-referential (infinite recursion) memcpy/memset\n- linux's lack of support for fchdir, fchmod, fchown, fstat on O_PATH fds\n\nbugs fixed:\n- failure to honor flags for fchmodat and faccessat (linux syscall api flaws)\n- SIGEV_THREAD timer id corruption and race condition issues\n- timer thread TLS incorrectly keeping values from previous expiry run\n- ecvt/fcvt decimal position off-by-one\n- in symbol-versioned libs, symbol resolved to oldest instead of newest\n- posix_spawn not correctly reporting errno from exec failure\n- \"make install\" was not atomic (overwrote files rather than replacing)\n- integer overflows in strftime\n- unset/empty TZ variable was mishandled\n- strftime could crash if the struct tm did not have valid tm_zone field\n- failure of fenv functions to handle invalid arguments (required by ISO C)\n- failure of some math functions (C and i386 asm) to raise underflow flag\n- broken dn_expand function (previously not used internally)\n- race conditions with signals during fork\n- incorrect access check in mktemp (obsolete function)\n- unnecessary arbitrary limits on size of program headers in dynamic loader\n- text formatting bugs in output of err.h functions\n\narch-specific bugs:\n- fesetenv(FE_DFL_ENV) crashed on i386\n- breakage of arm crt code when libc is compiled as thumb\n- arm/armhf (hardfloat) misidentified by configure\n- ambiguity of wait (exit status) macros on mips with signal number 127\n- wrong value of _NSIG and SIGRTMAX on mips\n\n\n\n0.9.14 release notes\n\nbugs fixed:\n- failure to properly install dynamic linker with DESTDIR set (symlink wrong)\n- rare deadlock in libc-internal locking routines\n- dynamic linker used fallback paths wrongly on (possibly transient) errors\n- popen broken when stdin or stdout was already closed in parent\n- deadlock/memory-corruption in multithreaded set*id and setrlimit functions\n- realpath failed when file was not readable\n- readpath mistakenly had cancellation points in it\n- crashes in scanf with invalid %m conversion specifiers\n- misclassificiation of some invalid ld80 float representation in fpclassify\n- various overflow and underflow flag issues in math functions\n- domain handling errors for acoshf and acoshl\n- wrong values for some sysconf properties\n- lack of proper memory barriers on arm\n\nmips-specific bugs:\n- broken sysv ipc structures\n- multiple stack-related bugs in clone, leading to crashes in parent or child\n- overflow writing sigset_t in multithreaded set*id and setrlimit functions\n\nother improvements:\n- size and performance improvements to various math functions\n- wait.h as a compatibility alias for sys/wait.h\n- various header improvements\n- support for runtime-variable page size on archs that need it (mainly mips)\n\n\n\n0.9.15 release notes\n\nnew features:\n- support for mixing IPv4 and v6 nameserver addresses in resolv.conf\n- RFC 3678 multicast structures/macros in netinet/in.h\n- putspent and fgetspent functions (shadow password API)\n- timef function (obsolete, removed in POSIX 2008)\n- fanotify syscalls (Linux-specific feature)\n- semtimedop syscall (Linux-specific sysvipc extension)\n- quotactl syscall and header (filesystem quotas support)\n- drem and finite functions (obsolete BSD functions)\n- getloadavg function (non-standard)\n- herror function (non-standard and obsolete)\n- libc.so now stores and prints its version information\n- expose constants for new Linux features including O_TMPFILE\n- implement FNM_LEADING_DIR option to fnmatch (GNU extension)\n- posix_close function (accepted for inclusion in next POSIX issue)\n\nbugs fixed:\n- buffer overflow in mbsrtowcs\n- clobbering of gr_name in getgrnam_r and getgrgid_r\n- execle ignoring the environment argument\n- setenv crash on malloc failure\n- out-of-bounds access in fnmatch with FNM_PATHNAME and certain patterns\n- failure of malloc to set errno when failing to extend heap\n- incorrect errno value from getcwd with zero size\n- spurious failure in faccessat with AT_EACCESS flag with suid/sgid programs\n- several fd leaks due to missing close-on-exec flag\n- misspellings/typos in macro names in several headers\n- incorrect failure return value in inet_pton\n- various numeric ip address parsing and validation fixes\n- namespace conformance issues in several headers\n- minor header issues\n- zombie processes left by faccessat with AT_EACCESS\n- timezone file parser failing/crashing on 64-bit archs\n- hang in localtime with near-overflowing time_t values on 64-bit archs\n- timezone path search was only trying first path\n- incorrect handling of excessive-length TZ environment strings\n- timezone file loading was wrongly enforcing O_NOFOLLOW/rejecting symlinks\n- iswspace was wrongly returning true for the null character\n- various bugs in wordexp\n- putgrent could write corrupt lines after write failures\n- dn_expand misinterpreted in-packet offsets greater than 255\n- spurious strftime/wcsftime failure on len+1==bufsize case\n- incorrect underflow flag in fma corner cases\n- log*(0) wrongly returned +inf in downward-rounding mode\n- failure of fchmod, fstat, fchdir, and fchown to produce EBADF\n\narch-specific bugs fixed:\n- i386: failure of fesetround to set sse rounding mode\n- i386: floating point limit constants misinterpreted due to excess precision\n- powerpc: broken thread pointer access when compiled with clang\n- microblaze: dynamic linker entry point code possibly clobbering argv\n\nstrict conformance issues:\n- NULL definition re-aligned with POSIX (requires (void *) cast)\n- alignment of math.h is* comparison functions with C11 annex F requirements\n\n\n\n1.0.0 release notes\n\nnew features:\n- support for mips softfloat ABI variant\n- legacy setkey and encrypt API for DES\n- support for BSD version of struct tcphdr in addition to GNU version\n- added ipv6 and icmpv6 protocol lookups to getprotoent-family functions\n\nnew experimental ports:\n- sh (SuperH)\n- x32 (ILP32 ABI for x86_64)\n\ncompatibility:\n- improved c89 compiler support in math.h\n- eliminate some compiler warnings in public headers\n- added some missing things for LFS64 APIs\n- added fallback emulation of accept4 for older kernels\n\nbugs fixed:\n- buffer overflow in printf when printing smallest denormal exactly\n- rounding errors in printf in some just-over-halfway cases\n- posix_spawn did not accept null pid pointer (crashed)\n- ftello gave incorrect result for unflushed append-mode streams\n- mishandling of n=0 case in wcsxfrm (wild buffer overrun)\n- possible system breakage during libc upgrade due to install.sh bugs\n- nftw FTW_MOUNT flag prevented walking any directories at all\n- ptsname/ptsname_r returned negated error codes\n- getprotoent function returned junk after listing valid protocols\n- wrong error code from readdir when the directory has been deleted\n- various prototype/argument-type fixes, mostly to legacy functions\n- various header namespace violations\n\narch-specific bugs fixed:\n- fesetenv(FE_DFL_ENV) was broken on i386 and x86_64\n- strerror(EDQUOT) did not work on mips\n- recvmsg/sendmsg were broken on powerpc\n- sysv ipc was broken on powerpc and mips\n- statfs/statvfs were broken on mips\n- sigaltstack was broken on mips\n\n\n\n1.1.0 release notes\n\nnew features:\n- relro memory protection in dynamic linker\n- malloc can now extend heap with mmap if brk fails\n- vdso clock_gettime/gettimeofday/time acceleration on x86_64\n- thread/library-safe versions of search.h functions (nonstandard)\n- getauxval function (nonstandard)\n- sysconf extensions to query physical memory size\n\nbugs fixed:\n- floating point printf output corruption from carry into uninitialized slot\n- possible runaway carry overflow in printf floating point\n- printf %g failure to strip trailing zeros in some cases\n- search past end of haystack in memmem\n- off-by-one error in confstr return value\n- crashes in some near-empty static programs that use stack protector\n- deadlock race in pthread_once\n- non-working clock_gettime fallback for old kernels\n\narch-specific bugs fixed:\n- crash from missing syscall asm register clobbers on real microblaze kernel\n- crash in all nontrivial dynamic linker use on microblaze\n- incorrect rlimit constants on mips\n- broken, possibly dangerous, use of getrlimit syscall on x32 in sysconf\n\n\n\n1.1.1 release notes\n\nnew features:\n- new options --preload and --library-path to dynamic linker\n- public execvpe function (nonstandard extension)\n- iconv support for cp437 and cp850\n\nbugs fixed:\n- false negatives with some periodic needles in strstr, wcsstr, and memmem\n- crash on invalid zoneinfo files\n- incorrect zero-padding of some outputs for strftime %s specifier\n- misreporting of errors in configure script when $CC does not work at all\n- treating not-yet-implemented strptime specifiers as errors\n\ncompatibility:\n- configure now detects serious constant-folding bug in gcc 4.9.0\n- removed __yield symbol (unused) that clashed with some compilers\n- improvements to sysconf's handling of unsupported/invalid arguments\n\narch-specific bugs fixed:\n- misdetection of superh ABI variant by configure on gcc 3.x\n- missing SO_RCVBUFFORCE and SO_SNDBUFFORCE in mips socket.h\n- build regression on armv6 and later with -mthumb\n\n\n\n1.1.2 release notes\n\nnew features:\n- multi-protocol matches (tcp and udp) in getaddrinfo\n- support for AI_V4MAPPED and AI_ALL flags to getaddrinfo\n- reverse name lookups from /etc/hosts\n- reverse service lookups from /etc/services\n- support for service aliases in /etc/services\n- ipsec and tunneling protocols to getprotoent-family functions\n- res_send, res_mkquery, res_querydomain, and dn_comp functions\n- ipv6 scope id handling for link-local scope addresses\n- previously-unimplemented %C and %y in strptime now work\n- vdso clock_gettime acceleration on i386 (new kernel feature)\n- better O_CLOEXEC/SOCK_CLOEXEC fallbacks for old kernels\n\nbugs fixed:\n- buffer overflow in dns response parsing (CVE-2014-3484)\n- possible infinite loop in dns response parsing\n- sendfile off_t 32/64-bit size mismatch\n- incorrect end pointer in some cases when wcsrtombs stops early\n- incorrect if_nametoindex return value when interface does not exist\n- dummy \"ent\" function aliases that possibly shadowed real ones\n- tmpfile fd leak on memory exhaustion\n- getaddrinfo returning EAI_NONAME for some transient failures\n\narch-specific bugs fixed:\n- broken kernel side RLIM_INFINITY on mips\n- incorrect syscall argument 6/7 types for pselect on x32\n\n\n\n1.1.3 release notes\n\nnew features:\n- address sorting in getaddrinfo, etc. modeled on rfc 3484/6724\n- default timezone taken from /etc/localtime when $TZ is unset\n- getopt double-colon extension for optional arguments\n- support for TLSDESC-based (gnu2) TLS dialect on i386 and x86_64\n- sendmmsg/recvmmsg (linux-specific)\n- fmtmsg (last mandatory XSI function that was missing)\n\ncompatibility:\n- treat dns rcode=2 as temporary failure, not negative result\n- working thread-pointer for pre-2.6 kernels on i386\n- further ABI-compat symbols: __xmknod[at], __sysv_signal\n\nbugs fixed:\n- memmem false positives/false negatives/crashes from invalid logic\n- gethostby*_r not setting result pointer to null on failure\n- aliasing violations in syscall.h SYSLOG_NAMES feature\n- fanotify_mark syscall arguments wrong\n\narch-specific bugs fixed:\n- various subtle relocation bugs in powerpc and sh dynamic linker\n\n\n\n1.1.4 release notes\n\nnew features:\n- experimental locale support for LC_MESSAGES and LC_TIME\n- non-stub gettext family functions for message translation\n- or1k (OpenRISC 1000) port\n- syslog options LOG_CONS and LOG_PERROR\n- issetugid function (from OpenBSD)\n- improved if_nameindex and getifaddrs functions\n\ncompatibility:\n- work around bug #61144 in gcc 4.9.0 and 4.9.1\n- support getauxval(AT_SECURE) even on kernels without AT_SECURE\n\nbugs fixed:\n- empty dynamic linker error messages (regression in 1.1.3)\n- if_nameindex omitted unconfigured and ipv6-only interfaces\n- incorrect return value for fwide function\n- failure of wide printf/scanf functions to set wide orientation\n- multiple issues in legacy function getpass\n- dynamic linker did not accept colon as a separator for LD_PRELOAD\n- errno clobber in syslog caused wrong output for %m specifier\n- crash in regexec for nonzero nmatch argument with REG_NOSUB\n- minor bugs in rarely-used nl_langinfo item lookups\n\narch-specific bugs fixed:\n- broken relocations in mips dynamic linker (regression in 1.1.3)\n- register state corruption in setjmp asm for microblaze\n- broken struct stat st_ino field on microblaze\n- broken struct stat st_dev field on big endian mips\n- broken asm register constraints in atomics on powerpc\n- missing barriers in atomics on mips, powerpc, microblaze, and sh\n\n\n\n1.1.5 release notes\n\nnew features:\n- full C11 coverage (threads, UTF-16/32 API, timespec_get, etc.)\n- malloc_usable_size function (nonstandard)\n- support for new F_OFD_* fcntl operations (linux 3.15, POSIX-future)\n- new _DEFAULT_SOURCE feature test macro to request default profile\n\nperformance:\n- private-futex support\n- redesigned cond var implementation with major performance improvement\n- tweaked spinning in userspace before performing futex waits\n\nbugs fixed:\n- failure of dn_expand to null-terminate name for crafted DNS packets\n- corruption of cond var mutex state when switching mutexes\n- use of uninitialized memory with application-provided thread stacks\n- false ownership of orphaned mutexes due to tid reuse\n- possible failure-to-wake for robust mutexes on owner death\n- subtle errors in robust mutex unrecoverable status handling\n- missing memory/compiler barrier spinning to obtain locks\n- wrong behavior in various zero-length stdio operations\n- buffer overflow in swab with odd argument\n- incorrect sequence generation in the rand48 family of prng functions\n- missing cancellation check in non-wait paths of sem_wait, pthread_join\n- missing barrier in pthread_once fast path\n- memory leak in regexec when input contains illegal sequence\n- various parser bugs in regcomp\n- wrong return value on overflow in some strtoul-family functions\n- broken CPU_EQUAL macro in sched.h\n- dlerror not working in static-linked programs\n- mishandling of negative non-whole-hour TZ offsets\n- incorrect case mappings for U+00DF\n- namespace pollution via accidentally-non-static function named \"dummy\"\n- missing __fpclassifyl and __signbitl definitions for ld64 archs\n\n\n\n1.1.6 release notes\n\nnew features:\n- getopt '-' flag for processing non-option arguments\n- getopt_long argument permutation extension\n- getopt_long abbreviated options\n- ns_parserr and related DNS-packet-parsing functions\n- fnmatch FNM_CASEFOLD extension\n- support for translation of getopt error messages\n- login_tty function (legacy)\n\nperformance:\n- efficient atomics on armv7+ targets\n- pthread_once shrink-wrapping of fast path\n\ncompatibility:\n- baseline arm binaries now work on new cpus/kernels without kuser_helper\n- dynamic linker now honors DT_RUNPATH without DT_RPATH (new binutils)\n- arm asm is now compatible with clang's internal assembler\n- suppress macro implementations of functions when headers are used in C++\n- increased message length limit for syslog\n\nbugs fixed:\n- open ignored file creation mode argument for O_TMPFILE\n- wrong printf formatting for %#.0o with value zero\n- missing private state for uchar.h functions (null ps pointer)\n- sched_getaffinity left uninitialized data in output bit array\n- wrong return values for pthread_getaffinity_np and pthread_setaffinity_np\n- buggy handling of multibyte option chars with arguments in getopt\n- printf failed to report or stop on write errors\n- printf failed to honor '+' modifier when printing NANs\n- wcsnrtombs returned the wrong value in one code path\n- syslog failed to check for connect error\n- multi-threaded set*id() had spurious failures from ugly workaround code\n- various minor header conformance bugs (signedness, constant expressions, ...)\n\narch-specific bugs fixed:\n- on or1k, some syscalls with 64-bit arguments were broken (misaligned)\n- usage of sahf instruction on x86_64 crashed on some early cpu models\n\n\n\n1.1.7 release notes\n\nnew features:\n- alternate passwd/group backend support via nscd protocol\n- masked cancellation mode extension (experimental)\n- aio cancellation\n- aarch64 port (experimental)\n\nperformance:\n- significant memset asm optimizations on i386 and x86_64\n\ncompatibility:\n- suppress EINTR in semaphores for old kernels where futex restart is broken\n- always set optarg in getopt_long\n- support SOCK_RAW socket type in getaddrinfo\n- report success instead of EINPROGRESS when close is interrupted\n\nbugs fixed:\n- multithreaded set*id() was not async-signal safe, had various race bugs\n- getspnam_r returned results for partial username matches\n- wordexp bad character checker mis-counted parentheses\n- close on fd with pending aio could lead to file corruption\n- old aio implementation had numerous conformance bugs\n- malloc init code could deadlock due to race condition\n- pthread_exit did not disable cancellation\n- pthread_cond_wait could wrongly consume signal on cancellation\n- execvp wrongly stopped path search on EACCESS\n- fsync, fdatasync, and msync were not honored as cancellation points\n- fchmodat was subject to fd leak race (missing O_CLOEXEC)\n- fchmodat failed to report EOPNOTSUPP in race path\n- passwd/group lookup functions had various minor error-reporting bugs\n- isatty had false-positives/device-state-corruption for OSS sound devices\n- configure script failed to detect gcc with translated messages\n- FLT_ROUNDS macro failed to reflect rounding mode changes in fenv\n\narch-specific bugs fixed:\n- mips fesetenv did not handle FE_DFL_ENV\n- mips POLLWRNORM and POLLWRBAND macros had wrong values\n- x32 pthread synchronization object type definitions were wrong\n- powerpc minimum signal stack size was insufficient\n\n\n\n1.1.8 release notes\n\nbugs fixed:\n- stack-based buffer overflow in inet_pton (CVE-2015-1817)\n- regcomp crash/mem-corruption with illegal bytes after backslash\n- regcomp wrongly allowed backrefs in ER\n- regcomp miscompiled character class brace-repetitions\n- regcomp wrongly processed \\0 as an unmatchable backref\n- new FLT_ROUNDS definition failed to work in C++ code\n\narch-specific bugs fixed:\n- aarch64 was missing max_align_t definition\n\n\n\n1.1.9 release notes\n\nnew features:\n- ability to protect libc code itself with stack protector\n- sigsetjmp now restores signal mask after restoring context, not before\n- thread-local dlerror status/messages\n- dlerror messages are no longer truncated\n- diagnostics for constraint violations with ctype.h macros\n\noptimizations:\n- reduce cost of PIC on archs where PLT calls need a fixed GOT register\n- spin locks no longer constantly invalidate cache lines while spinning\n- code size reduction in static-linked TLS init\n\nbugs fixed:\n- failure to process robust mutexes on detached-thread exit\n- possible memory corruption due to robust mutex list on detached-thread exit\n- crash on memory exhaustion in getgr* internals\n- misaligned memory accesses in static binaries with low-alignment TLS blocks\n- multiple cases of wrongful path search continuation after transient failure\n- small memory leak on failure of dlopen with RPATH $ORIGIN\n- several small math bugs related to exception flags with non-finite args\n- mmap leak in sem_open failure path for link call\n- duplocale clobbered new locale struct with memcpy of old\n- futimes crashed with null timeval argument\n\narch-specific bugs fixed:\n- stack protector spuriously aborted after forking on x32\n- stack protector spuriously aborted with flockfile on powerpc\n- theoretically-possible clobbering of syscall return value on mips\n- random thread-pointer setup failure on sh (uninitialized return value)\n- possible crash in dlsym on sh due to incorrectly-computed branch target\n- broken fesetenv(FE_DFL_ENV) on mips\n- dynamic linker name for sh ignored fpu/nofpu and endianness\n- various minor aarch64 bugs\n- dangling pointers in x32 syscall timespec fixup code\n\n\n\n1.1.10 release notes\n\nnew features:\n- fail-safe (allocation-free) C locale for newlocale to return\n- all locale categories track requested locale name\n- rcrt1.o start file for static PIE\n\noptimizations:\n- inline atomics for sh4a\n- removed heavy atomics from locale-related code paths\n- removed global data accesses from CURRENT_LOCALE macro & callers\n- dynamic linker stage 1 size reduction\n\ncompatibility:\n- better configure detection of unsupported compiler options\n- support for more relocation types in libc.so, not currently used\n- iconv_open accepts \"\" and \"CHAR\" as aliases for native (UTF-8)\n- additional LFS64 macros in sys/resource.h\n\nregressions fixed:\n- dynamic linker crash on NONE-type relocations (only mips affected)\n- inability to build as thumb2 on arm\n- failure to run under qemu-i386 user-level emulation\n- inability to access globals from libc on powerpc\n- PIE link errors in Scrt1.o under unusual usage on some archs\n\nother bugs fixed:\n- failure of ungetc/ungetwc to work on FILE streams in EOF state\n- possible null pointer dereference in gettext\n- possible initial stack misalignment on mips with PIE\n\n\n\n1.1.11 release notes\n\nnew features:\n- byte-based C locale\n- vdso clock_gettime on arm\n- musl-clang wrapper\n- sh2 nommu target support\n\nperformance:\n- major speed-up for dynamic linker symbol lookups with GNU hash\n\ncompatibility:\n- strverscmp now matches GNU behavior in corner cases\n- empty TZ environment variable gives GMT rather than system default\n- reconnection on syslog server socket loss (syslogd restart)\n- mmap fallback in simple_malloc when brk fails\n- support for %m and %s with null pointers in wide printf variants\n- call frame information in i386 asm for improved debugger support\n\nbugs fixed:\n- spurious errors from pwd/grp functions when nscd backend is absent\n- possible invalid access on calloc with simple_malloc\n- null pointer dereferences after calling uselocale((locale_t)0)\n- erroneous support for cancellation in stdio caused data loss\n- inconsistent handling of atexit called from atexit handler\n- missing locking in error paths for ungetwc\n- btowc mishandling of out-of-range non-EOF inputs\n- negated return value of ns_skiprr, failure in related functions\n- incorrect void return type for syncfs, missing error status\n- possible failure of tempnam due to missing null termination\n- negated tm_gmtoff field in struct tm\n- off-by-one error in getsubopt leaving equals sign in value result\n\narch-specific bugs fixed:\n- soft deadlocks on i386/x86_64 due to missing barrier in internal locks\n- regression in arm pre-v7 support for kernels with kuser helper removed\n- runaway PC on mips detached thread exit (due to kernel regression)\n- mismatched ABI for local-dynamic model TLS on mips and powerpc\n- incorrect value of some SO_* constants on mips\n- broken 64-bit syscall argument passing on aarch64\n\n\n\n1.1.12 release notes\n\nnew features:\n- fdpic abi on sh2 for shareable text segment without mmu\n- general fdpic elf support in dynamic linker\n- CFI generation for x86_64 asm source files\n- protection against silently building a libc.so with missing symbols\n\ncompatibility:\n- nl_langinfo(CODESET) now returns \"ASCII\" in byte-based C locale\n- fixed build regression due to buggy .SECONDARY in some GNU make versions\n- additional arm eabi functions needed by llvm arm backend\n- added format argument attributes to gettext function prototypes\n- static PIE no longer requires linking with -E/-rdynamic\n- eliminated spurious protected-data warnings linking against libc.so\n- avoided spurious fpu asm errors with some armhf toolchains\n\nbugs fixed:\n- fclose of stdin/stdout caused deadlock at exit\n- missing memory barrier in pthread_join\n- open_[w]memstream produced no buffer when no writes took place\n- uninitialized scopeid in address lookups from hosts file and ip literals\n- ip literals for mismatching family (v4 vs v6) were queried as hostnames\n- possible crash on OOM in regcomp\n- incorrect contents in localeconv structure (-1 instead of CHAR_MAX)\n- strftime mishandling of out-of-range struct tm members\n- wrongful attribute((const)) on pthread_self and errno location function\n\narch-specific bugs fixed:\n- arm crt1 entry point failed to align stack pointer in some cases\n- mips fesetround failed to actually set rounding mode\n- i386 asm source CFI generation had multiple bugs\n\n\n\n1.1.13 release notes\n\nnew features:\n- out-of-tree builds\n- search domains in resolv.conf\n- sh arch supports j-core (j2) cas.l atomics\n- dynamic linker includes arch/abi in output when run as a command\n- header support for new kernel features through linux 4.4\n- mips vdso clock_gettime support\n- regex BRE extensions: \\|, \\+, \\?\n\nperformance:\n- improved atomics performance on all archs with ll/sc model\n- atomic instructions are now inlined on armv6\n- use fpu sqrt for arm softfp abi on targets with vfp\n\ncompatibility:\n- getnameinfo now accepts sockaddr sizes larger than needed\n- new default CFLAGS/LDFLAGS avoid entire classes of toolchain bugs\n- explicit use of float_t/double_t avoids compiler float spill bugs\n- i386 max_align_t definition now works with g++ 4.7's pseudo-c++11\n- all known protocols are added to protoent functions\n- stub utmpname, utmpxname functions\n- linker support for -Bsymbolic-functions is no longer mandatory\n- regex parsing size limits increased\n- malloc_usable_size now accepts null pointer input\n\nbugs fixed:\n- potential single-byte heap overflow in getdelim\n- mishandling of transient failure opening hosts, services, resolv.conf\n- mremap was sometimes able to allocate objects larger than PTRDIFF_MAX\n- nl_langinfo wrongly returned NULL instead of \"\" for invalid items\n- out-of-bounds dynamic tls allocation due to pointer/index scaling error\n- getifaddrs misreported point-to-point interface addresses\n- tdelete left tsearch trees misbalanced\n- tsearch crashed on allocation failure\n- tsearch, tfind, and tdelete failed to handle null pointer input\n- passing signal number 0 to sigaction resulted in a crash\n- getdelim updated caller's size wrongly when realloc failed\n- getdelim realloc strategy was wasteful\n- if_nametoindex returned wrong value on failure\n- missing ssp-suppression for some source files called from early-init\n- various minor resolv.conf parsing bugs\n- fwrite wrongly reported success on write errors in line-buffered flush\n- fwrite and fread wrongly returned nmemb (not 0) when size was 0\n\nnommu-specific bugs fix:\n- failure to zero bss in FDPIC shared library loader\n- unsafe writes to read-only file mapping in non-FDPIC library loader\n\narch-specific bugs fixed:\n- sh[eb]-nofpu-fdpic was using fpu-dependent setjmp/longjmp variants\n- dynamic linker path file name was wrong for arm \"softfp\" targets\n- mips siginfo_t and related macros were defined incorrectly\n- possibly misaligned pointer globals on arm (from an asm source file)\n- mips dynamic linker failed to provide info needed by debugger\n- mips cancellation asm wrongly assumed validity of $gp register value\n\n\n\n1.1.14 release notes\n\nregressions fixed:\n- treatment of empty string argument as error by puts and fputs\n- make clean and distclean failure in unconfigured trees\n- sh/fdpic dynamic linker entry point hang due to wrong code\n- armhf (and arm softfp model) build failure with clang\n\nother bugs fixed:\n- wrongly clamping (rather than failing) excessive rounds in crypt-sha*\n\n\n\n1.1.15 release notes\n\nnew features:\n- mips64 (full 64-bit and n32) port\n- mips r6 isa support (subarch for mips, mips64, and mipsn32 archs)\n- powerpc64 port\n- powerpc (32-bit) soft-float ABI support (subarch)\n- pthread_tryjoin_np and pthread_timedjoin_np (nonstandard extensions)\n- header-level support for linux 4.5 and 4.6 features\n- sched_getcpu (nonstandard extension) support, including vdso version\n- __STDC_ISO_10646__, __STDC_IEC_559__ macros predefined via stdc-predef.h\n- support for new elf/arch features in elf.h\n\ncompatibility:\n- configure now correctly chooses cross-prefix based on build/host/target\n- abort now successfully terminates pid 1 in a container (or top-level)\n\nbugs fixed:\n- memmem read past end of haystack, possible false positives or crashes\n- buffer underflow (reverse-overflow) in ungetwc\n- double-free under certain usage of putenv\n- incorrect treatment by regcomp of * at start of BRE subexpression\n- gethostbyname[2][_r] produced ip addresses in misaligned buffers\n- looking up some invalid hostnames caused malformed dns queries\n- lookups from hosts file were inconsistent with non-matching family\n- missing h_length value in gethostbyaddr results\n- a64l function produced wrong-signed results on 64-bit archs\n- broken padding of string formats to width in wide printf variants\n- wrong results for expf(-NAN) and exp2f(-NAN)\n- wrong value for RUSAGE_CHILDREN prevented it from working\n- abort failed to provide abnormal termination with SIGABRT blocked\n\narch-specific bugs fixed:\n- broken posix_fadvise on arm and powerpc (32-bit)\n- thread structure/dtv corruption on powerpc at thread startup\n- various wrong mips and powerpc ioctl and termios constant values\n\n\n\n1.1.16 release notes\n\nnew features:\n- s390x (64-bit S/390) port\n- pthread_setname_np extension function\n- limited pthread_setattr_default_np function to set stack size defaults\n- header-level support for linux 4.7, 4.8, and 4.9 features\n- confstr _CS_V6_ENV and _CS_V7_ENV items\n\ncompatibility:\n- public prototypes for abi-compat *_unlocked symbols, etc.\n- fflush_unlocked(NULL) now works\n- resolv.h __RES version macro now matches supported APIs\n- workaround for gdb bugs backtracing across signals on x86_64\n- anchors ^ and $ are now accepted in BRE subexpressions\n- building for thumb2-only arm isa levels is now possible\n\nbugs fixed:\n- integer overflows in regexec buffer allocation (CVE-2016-8859)\n- failure of regexec to report matches at offsets past INT_MAX\n- static-pie executables with initialized thread-local storage crashed\n- printf failed to catch EOVERFLOW in some cases, wrongly produced it in others\n- printf produced wrong output, result for float with precision near INT_MAX\n- printf produced wrong results with alt-form octal, zero flag, & field width\n- printf float rounding was wrong for some midpoint cases\n- swprintf printed junk after internal (256-byte) buffer filled up\n- strtod family rounded incorrectly in several corner cases\n- getmntent failed to handle long records\n- getopt_long_only wrongly treated \"--\" as an option\n- asctime output wrongly varied by locale\n- strftime %y specifier produced wrong output for negative tm_year\n- time zone names quoted with <> were misparsed\n- corner case integer overflow in tm_year for some date conversions\n- failure to load shared libs whose names were prefixes of standard lib names\n- wrong error codes for several failure cases in various functions\n- various asymptomatic undefined behavior\n- various minor namespace issues in headers\n\narch-specific bugs fixed:\n- tcsetattr regression on mips (completely non-working)\n- wrong pread/pwrite syscall calling convention on sh\n- wrong preadv2/pwritev2 syscall numbers on x32\n- mrand48/jrand48 produced wrong-signedness results on 64-bit archs\n\n\n1.1.17 release notes\n\nnew features:\n- RTLD_LAZY deferred symbol binding, functionally equivalent to lazy binding\n- safeguard against dlopen of multiple libc versions/instances\n- new posix_spawn flag POSIX_SPAWN_SETSID\n- posix_spawnattr_setflags now reports unknown flags as error\n- ldso option --argv0 to set argv[0]\n- added _NL_LOCALE_NAME extension to nl_langinfo\n\ncompatibility:\n- dlopen local-to-global promotion no longer changes existing symbols\n- gettext now searches locale name variants for translation files\n- increased locale name length limit from 15 to 23 bytes\n- setlocale(LC_ALL, 0) returns single name if all categories are same\n- realloc no longer fails when mremap doesn't work\n- getservby* no longer treat numeric port strings as service records\n- mmap now works around incorrect EPERM error codes from kernel\n- impact of REG_* namespace pollution in x86[_64] signal.h is reduced\n- arm atomic asm now assembles correctly with new binutils\n- PAGE_SIZE on arm is no longer constant (quiet upstream ABI relaxation)\n- lsearch/lfind now pass args to compare callback in canonical order\n- STB_WEAK and STB_GNU_UNIQUE symbols now behave same as STB_GLOBAL\n- better clang CFLAGS checks in configure\n- global vis.h hack, which made lld refuse to link to libc.so, is disabled\n\nperformance:\n- single-instruction optimized math functions for aarch64, s390x, powerpc64\n- fast path for ASCII in towupper/towlower\n- new mostly-integer-math fma function\n\nsemantic bugs fixed:\n- POSIX-format TZ dst time transitions were wrong for southern hemisphere\n- regex REG_NEWLINE semantics were wrong with negated brackets\n- various bugs in strptime %j, %p, %C formats\n- iconv mapped some characters to legacy 8bit encodings incorrectly\n- glob failed to match \"/\"\n- UTF-8 decoder accepted invalid f4 9x xx xx code sequences\n- scanf %% conversion failed to consume whitespace\n- glob with GLOB_PERIOD wrongly descended into . and ..\n- nftw gave incorrect base name offset when pathname ends in \"/\"\n- functional regression in resolv.conf attempts option\n- scalbn could produce wrong result due to double rounding in subnormal range\n- strftime %y format wrong with negative years\n- mbsnrtowcs and wcsnrtombs mishandled input limits\n- minor issues with error codes for various functions\n\nsafety/consistency bugs fixed:\n- stack-based buffer overflow in dns response processing\n- invalid free in regexec on certain error paths\n- invalid free in globfree after failed glob\n- one-byte buffer overflow in legacy getpass function\n- failed dlopen corrupted thread-local storage module list\n- race in pthread_create with priority attributes could leave signals masked\n- multithreaded set*id() functions could induce spurious EINTRs\n- dl_iterate_phdr reported wrong base address in static PIE\n- fd leak and wrong cancellation state after dns socket failure\n- memory leaks and other issues in environment-modification functions\n- read-after-free race in pthread_detach\n- memmem performed single-byte over-read in short-needle code paths\n- read via uninitialized pointer in gettext core\n- bindtextdomain broke bindings for all other domains\n- various silent undefined behavior\n- getopt clobbered optopt on success\n\narch-specific bugs fixed:\n- x32 dynamic TLS accesses crashed\n- s390x was missing dlsym entry point (needed for RTLD_NEXT)\n- powerpc64 ldso startup could crash depending on link order\n- powerpc64 setjmp/longjmp didn't properly save/restore TOC pointer\n- thumb2 setjmp/longjmp silently broke at ld-time with text not aligned\n- fchown was broken on archs without SYS_fchown syscall\n- fstatat was broken on mips64\n- various incorrect constants in powerpc64 and mips headers\n\n\n1.1.18 release notes\n\nregression fixes:\n- glob failed to match literal . and .. path components\n- build for armv4t ISA level was broken\n\nother bug fixes:\n- stack overflow in posix_spawnp with large PATH variable in environment\n\n\n1.1.19 release notes\n\nnew features:\n- iconv framework for processing stateful encodings\n- iconv support for iso-2022-jp\n- iconv support for converting to legacy JIS-based Japanese encodings\n- iconv support for UTF-16/32 with BOM-determined endianness\n- iconv ibm1047 (ebcdic latin1-equivalent) support\n- iconv cp866 (dos cyrillic) support\n- character data tables & case mappings updated to Unicode 10.0\n- fopencookie stdio extension\n- strftime padding character extensions\n- header-level support for new linux features through 4.13\n\ncompatibility:\n- UTC timezone is now called UTC instead of GMT\n- _DIRENT_HAVE_D_* macros in dirent.h\n- dladdr dli_fbase definition now matches other implementations\n- pthread_getattr_np now reports guard size\n- strftime '+' modifier better matches apparent intent of POSIX\n- getopt_long handles long option names containing '='\n- better compatibility with linux uapi headers\n- workaround linux bug where getcwd can return non-absolute pathname\n- configure logic for finding compiler_rt with clang\n- execvp path search now continues after ENOTDIR components\n\nbugs fixed:\n- fgetwc failed when character crossed buffer boundary\n- memory corruption after failing to dlopen a second libc\n- sysconf reported infinite rlimits incorrectly\n- getopt_long --opt=arg did not work with partial matches\n- printf was wrong for alt-form octal with value 0, no explicit precision\n- endian errors in arpa/nameser.h and netinet/icmp6.h (missing endian.h)\n- atfork handler could clobber fork's errno\n- iconv could wrongly output surrogate pairs in ucs2\n- fmemopen buffer underallocation with extreme size argument\n- getaddrinfo AI_NUMERICSERV wrong error code\n- data race in at_quick_exit\n- ldd failed to honor rpath $ORIGIN for program in . without \"./\" prefix\n\narch-specfic bugs fixed:\n- x32 unistd.h wrongly reported LP64 instead of ILP32\n- aarch64 signal.h had wrong type for ucontext_t uc_link member\n\n\n1.1.20 release notes\n\nnew features:\n- m68k port\n- replacement of malloc is now allowed/supported\n- setvbuf now accepts caller-provided buffers for stdio streams\n- getrandom syscall wrapper, getentropy function\n- mlock2 syscall wrapper\n- memfd_create syscall wrapper\n- explicit_bzero function\n- header-level support for new linux features through 4.17\n- wcsftime now supports padding specifier extensions\n- dynamic linker's reclaim_gaps now works on fdpic archs\n- getaddrinfo now honors AI_ADDRCONFIG\n- pthread_attr_init now honors pthread_setattr_default_np defaults\n\nhardening:\n- prevent bypass of guarantee that suids start with fd 0/1/2 open\n- dlopen now rejects libraries with initial-exec refs to dynamic TLS\n\ncompatibility:\n- elf.h: new flags, aux vector entry types, etc.\n- minor namespace issues in several headers\n- intNN_t types used in bitfields now safe against -funsigned-bitfields\n- complex arc trig/hyperbolic functions were badly broken\n- nice function returned wrong value\n- stdio locks no longer depend on read-after-free not faulting\n- avoid excessive stack usage in getcwd\n- inet_ntop no longer compresses single zeros in IPv6 (RFC 5952)\n- resolver routability probe for sorting results works on no-IPv6 systems\n- added missing ST_RELATIME definition to statvfs.h\n- uchar.h now works with old C++ profiles\n- added missing and arch-specific commands to ptrace.h\n- musl-gcc wrapper now works with default-pie host toolchains\n\nbugs fixed:\n- getopt wrongly treating colons in optstring as valid option chars\n- nl_langinfo_l(CODESET, loc) reported wrong locale's value\n- out-of-tree build produced broken crt files with stack protector enabled\n- fmaf produced wrong result for some corner cases\n- out of bounds write for zero length buffer passed to gethostname\n- getopt_long_only wrongly prefix-matched long-options over short ones\n- pthread_kill wrongly returned ESRCH for exited by valid pthread_t's\n- iconv buffer overflow converting to legacy JIS-based encodings\n- iconv conversion to \"UTF-32\" (no explicit endianness) failed (regression)\n- iconv mishandled big5-hkscs characters that map to two unicode chars\n- dynamic linker didn't map/clear bss for libraries with single LOAD segment\n- resolver wrongly duplicated trailing dot from query into canonical name\n- some futex waits omitted timeout arg to syscall, thereby spun on EFAULT\n- dladdr mishandled addresses not matching symbols\n- alignment of dirent structures from readdir was broken (regression)\n- strftime %z output wrong sign for offsets <1 hour west of UTC\n- limits.h, pathconf erroneously defined SYMLINK_MAX\n- FP_ILOGB0 and FP_ILOGBNAN definitions were not valid for use in #if\n- getopt failed to update optarg and optind correctly on missing argument\n- EMULTIHOP error lacked strerror text\n- mktime malfunctioned with tm_isdst>0 but no-DST POSIX-format time zone\n- async thread self-cancellation produced a deadlock condition\n- pthread_barrierattr_setpshared failed to produce EINVAL for bad argument\n- fileno failed to produce EBADF for non-fd-associated FILEs\n- fmemopen's w+ mode failed to truncate buffer at open\n- open_[w]memstream did not bind stream orientation at open time\n- system wrongly returned 0x7f00 instead of -1 on error\n- wide printf functions ignored field width for %c formats\n- fprintf failed to set stream orientation for unbuffered stream or no output\n- psignal, psiginfo, and perror wrongly set stream orientation for stderr\n- psignal, psiginfo potentially clobbered errno on success\n\narch-specfic bugs fixed:\n- on arm/aarch64/sh, local-exec TLS layout mismatched ABI with large align\n- on arm/microblaze/sh, struct ipc_perm mismatched (buggy) kernel ABI\n- SO_PEERSEC definition was wrong on mips\n- on mips, return from start function passed to clone crashed (runaway exec)\n- printf %a precision specifier malfunctioned except on ld80 archs\n- async thread cancellation crashed on powerpc64 and sh-fdpic\n\n\n1.1.21 release notes\n\nnew features:\n- setting default thread stack size via PT_GNU_STACK program header\n- arm vfork implementation\n- arm tlsdesc/gnu2 tls dialect support\n- name_to_handle_at and name_to_handle_at syscall wrappers\n- header-level support for new linux features through 4.18\n\noptimizations:\n- glob rewrite with much better performance and stack usage properties\n- single-threaded and already-locked fast paths for getc/putc variants\n- single-instruction fma implementations for arm, s390x, powerpc, & x86_64\n- single-instruction fabs and sqrt implementations for powerpc\n- size and performance from making all internal-only functions/data hidden\n- made &errno and pthread_self results cachable again (attribute((const)))\n- significant speedup in strtod with short inputs\n- new tsearch AVL tree implementation, smaller and faster\n- special-cased nop calls to wmemmove\n- fixed erroneously suboptimal skip conditions in strstr and memmem\n\nhardening:\n- default thread stack guard size increased from 4k to 8k\n\ncompatibility:\n- default thread stack size increased from 80k to 128k\n- building for arm as thumb2 with clang internal assembler now works\n- aio threads could overflow stack on kernels that break MINSIGSTKSZ ABI\n- aio threads no longer call malloc (problematic with malloc replacement)\n- pthread_sigmask/sigprocmask now ignore an invalid how when not changing mask\n\nbugs fixed:\n- soft deadlock regression in stdio FILE locks with >2 threads contending\n- deadlock and buffered data loss race in fclose\n- race condition leading to possible crash in dcngettext plural forms\n- glob failed to see past searchable-but-unreadable path components\n- getdelim wrongly realloc'd buffer that was already exactly right size\n- getdelim failed to set stream orientation on early error\n- ttyname[_r] reported wrong error when given bad fd\n- pthread_key_delete left old tsd values exposed if slot was reused\n- freeaddrinfo failed to support freeing sublists\n- access to optopt was broken by copy relocations\n- memccpy returned wrong result if first byte past buffer end matched\n- wordexp read past end of input string ending in backslash\n- sem_wait and sem_timedwait were wrongly not interruptible by signals\n- getspnam[_r] wrongly treated not-found as an error\n\narch-specfic bugs fixed:\n- soft deadlocks (missing futex wake) on powerpc locking\n- dlsym returned wrong address for thread-local symbols on ppc/mips/m68k\n\n\n1.1.22 release notes\n\nnew features:\n- priority-inheritance mutexes\n- membarrier syscall, pre-registration to use it, fallback emulation\n- header-level support for new linux features in 4.19, 4.20, 5.0\n\nmajor internal changes:\n- complete, async-safe view of all existent threads as global list\n- robust __synccall based on new thread list\n- new dynamic TLS is installed synchronously at dlopen\n- TLSDESC resolver functions no longer make bad ABI assumptions to call C\n- resolved shared library dependencies are now recorded\n\ncompatibility & conformance:\n- dependency-order shared library constructor execution\n- sigaltstack no longer rejects SS_AUTODISARM, future flags\n- FILE is now a complete (dummy) type in pre-C11 feature profiles\n- setvbuf reports failure on invalid arguments\n- TSVTX is exposed unconditionally in tar.h\n- multithreaded set*id() no longer depends on /proc\n- key slot reuse after pthread_key_delete no longer depends on /proc\n\nbugs fixed:\n- failures in multithreaded set*id() with concurrent thread creation/exit\n- interposed free was called from invalid/inconsistent contexts\n- freeaddrinfo performed invalid free of some partial results lists\n- dlsym dependency order search had false negatives and false positives\n- dn_skipname gave wrong results for labels with 8-bit content\n- dcngettext clobbered errno, often breaking printing of error messages\n- sscanf read past end of buffer under certain conditions (1.1.21 regression)\n- pthread_key_create spuriously failed under race condition (1.1.21 regression)\n- fdopendir wrongly succeeded with O_PATH file descriptors\n- gets behaved incorrectly in presence of null bytes\n- namespace violations in c11 tsd and mutex function dependencies\n- incorrect prototype for makecontext (unimplemented)\n\narch-specfic bugs fixed:\n- s390x had wrong values for POSIX_FADV_DONTNEED/_NOREUSE\n\n\n\n1.1.23 release notes\n\nnew features:\n- riscv64 port\n- configure now allows customizing AR and RANLIB vars\n- header-level support for new linux features in 5.1\n\nmajor internal changes:\n- removed extern __syscall; syscall header code is now fully self-contained\n\nperformance:\n- new math library implementation for log/exp/pow\n- aarch64 dynamic tlsdesc function is streamlined\n\ncompatibility & conformance:\n- O_TTY_INIT is now defined\n- sys/types.h no longer pollutes namespace with sys/sysmacros.h in any profile\n- powerpc asm is now compatible with clang internal assembler\n\nchanges for new POSIX interpretations:\n- fgetwc now sets stream error indicator on encoding errors\n- fmemopen no longer rejects 0 size\n\nbugs fixed:\n- static TLS for shared libraries was allocated wrong on \"Variant I\" archs\n- crash in dladdr reading through uninitialized pointer on non-match\n- sigaltstack wrongly errored out on invalid ss_size when doing SS_DISABLE\n- getdents function misbehaved with buffer length larger than INT_MAX\n- set*id could deadlock after fork from multithreaded process\n\narch-specfic bugs fixed:\n- s390x SO_PEERSEC definition was wrong\n- passing of 64-bit syscall arguments was broken on microblaze\n- posix_fadvise was broken on mips due to missing 7-arg syscall support\n- vrregset_t layout and member naming was wrong on powerpc64\n\n\n\n1.1.24 release notes\n\nnew features:\n- GLOB_TILDE extension to glob\n- non-stub catgets localization API, using netbsd binary catalog format\n- posix_spawn file actions for [f]chdir (extension, pending future standard)\n- secure_getenv function (extension)\n- copy_file_range syscall wrapper (Linux extension)\n- header-level support for new linux features in 5.2\n\nperformance:\n- new fast path for lrint (generic C version) on 32-bit archs\n\nmajor internal changes:\n- functions involving time are overhauled to be time64-ready in 32-bit archs\n- x32 uses the new time64 code paths to replace nasty hacks in syscall glue\n\ncompatibility & conformance:\n- support for powerpc[64] unaligned relocation types\n- powerpc[64] and sh sys/user.h no longer clash with kernel asm/ptrace.h\n- select no longer modifies timeout on failure (or at all)\n- mips64 stat results are no longer limited to 32-bit time range\n- optreset (BSD extension) now has a public declaration\n- support for clang inconsistencies in wchar_t type vs some 32-bit archs\n- mips r6 syscall asm no longer has invalid lo/hi register clobbers\n- vestigial asm declarations of __tls_get_new are removed (broke some tooling)\n- riscv64 mcontext_t mismatch glibc's member naming is corrected\n\nbugs fixed:\n- glob failed to match broken symlinks consistently\n- invalid use of interposed calloc to allocate initial TLS\n- various dlsym symbol resolution logic errors\n- semctl with SEM_STAT_ANY didn't work\n- pthread_create with explicit scheduling was subject to priority inversion\n- pthread_create failure path had data race for thread count\n- timer_create with SIGEV_THREAD notification had data race getting timer id\n- wide printf family failed to support l modifier for float formats\n\narch-specific bugs fixed:\n- x87 floating point stack imbalance in math asm (i386-only CVE-2019-14697)\n- x32 clock_adjtime, getrusage, wait3, wait4 produced junk (struct mismatches)\n- lseek broken on x32 and mipsn32 with large file offsets\n- riscv64 atomics weren't compiler barriers\n- riscv64 atomics had broken asm constraints (missing earlyclobber flag)\n- arm clone() was broken when compiled as thumb if start function returned\n- mipsr6 setjmp/longjmp did not preserve fpu register state correctly\n\n\n\n1.2.0 release notes\n\nnew features:\n- time_t is now 64-bit on all archs (not just 64-bit archs)\n- character type & case mapping data updated to Unicode 12.1.0\n- header-level support for new linux features in 5.3 and 5.4\n\nperformance:\n- new O(1) wchar_t case mapping implementation\n- i386 now uses C math code for exp, faster than old asm\n- mips math asm\n\ncompatibility & conformance:\n- endian.h now aims to conform to future POSIX definition\n- support older compilers that don't accept powerpc math asm constraints\n- fdpic code in ldso was incompatible with valid optimizations in gcc 9+\n- RLIMIT_RTTIME was missing from sys/resource.h\n\nbugs fixed:\n- wcwidth wrongly returned 0 for most of planes 4 and up\n- missing case mapping between U+03F3 and U+037F\n- wrong cacosh results for arguments with negative imaginary part\n- wrong catanf/catanl results for various classes of arguments\n- wrong return value for ungetc with argument outside [0,UCHAR_MAX]\n- posix_openpt with no ptys available produced wrong errno\n\narch-specific bugs fixed:\n- sigcontext/regset definition mistakes & omissions on m68k, powerpc64\n- fesetenv(FE_DFL_ENV) crashed on riscv64\n- sh2 dynamic linker was broken since 1.1.21 (crash in stage 2b)\n- arm dynamic linker chose wrong tls/atomic variants since 1.1.21\n- some math library functions returned excess precision on i386\n- unconfirmed regression in fchmodat AT_SYMLINK_NOFOLLOW on mips*\n\n\n\n1.2.1 release notes\n\nmajor changes:\n- new malloc implementation (mallocng & overhauled bump allocator)\n\nnew features:\n- DNS queries via res_* now set AD flag, report zone signedness (DNSSEC)\n- PTHREAD_NULL macro (POSIX-future)\n\nperformance:\n- optimized memcpy and memset for aarch64\n- optimized memcpy for arm now supports big endian\n- optimized x86_64 remquol\n- improved strerror without linear search\n\nbugs fixed:\n- lock-skipping for processes that returned to single-threaded was wrong\n- AF_UNSPEC dns lookups mishandled single failure in paired A+AAAA\n- res_send and res_query returned wrong value on errors from nameserver\n- corrupted sysvipc timestamps on 32-bit archs with old kernels\n- incorrect parsing of timezone offsets after overly-long zone name\n- clock_adjtime was broken on 32-bit archs (time64)\n- pthread_kill as not async-signal-safe\n- pthread_cancel was not async-cancel-safe\n- large-ulp errors in various math functions in non-default rounding modes\n\narch-specific bugs fixed:\n- arm clock_gettime was broken on some hw due to bad time64 vdso\n- m68k sqrtl lacked long double precision\n- mips* syscall mechanism regressions on older kernels\n- mips* had negated error codes for some syscalls (kernel bug)\n- mips* SIGEMT was wrongly called SIGSTKFLT\n- sh fesetround didn't work correctly on sh\n\n\n\n1.2.2 release notes\n\nmajor changes:\n- child restrictions lifted after fork of multithreaded parent\n\nnew features:\n- _Fork function (POSIX-future)\n- reallocarray function (extension from OpenBSD, now widespread)\n- gettid function (kernel tid as supported concept)\n- SIGEV_THREAD_ID sigevent API (Linux extension)\n- tcgetwinsize and tcsetwinsize functions (POSIX-future)\n\nperformance:\n- faster software sqrt on archs without native sqrt instruction\n\ncompatibility:\n- realpath no longer depends on procfs availability & accuracy\n- time zone parser now always prefers 64-bit tables if present\n- crypt_blowfish now supports $2b$ prefix\n- res_query now reports errors via h_errno\n- set*id and setrlimit are now safe in vforked/cloned child\n- setgroups now applies to all threads\n- dlopen debugger notification is improved, should work with lldb\n- setrlimit no longer needs __synccall broadcast on linux 2.6.36+\n- faccessat with AT_EACCESS no longer needs child process on linux 5.8+\n\nbugs fixed:\n- buffer overflow and infinite loop errors in wcsnrtombs (CVE-2020-28928)\n- sem_close unmapped still-referenced semaphores\n- fork of process with active aio could deadlock or crash paren\n- pthread_cond_wait was broken with priority-inheritance mutex\n- getgrouplist wrongly failed when nscd reported an empty list\n- abort could leak modified SIGABRT disposition to fork or posix_spawn child\n- regression with mallocng: malloc_usable_size(0) crashed\n- readlink wrongly gave EINVAL on zero length dest buffer\n- sqrtl was severely inaccurate (not correctly rounded) on ldquad archs\n- assert failure wrongly flushed stdio (possible deadlock)\n- MUSL_LOCPATH search was broken with multiple components\n- missing newline in herror output\n- possible deadlock in pthread_exit with pshared mutex or barrier usage\n- pthread_mutexattr_getprotocol didn't read back protocol\n- v4l2 ioctl translation for pre-time64 kernels didn't work\n\narch-specific bugs fixed:\n- x86_64 longjmp failed to handle 0 argument reliably\n- i386 __set_thread_area fallback for pre-2.6 kernels didn't work\n- missing O_LARGEFILE macro value on x86_64, x32, mips64\n- unpredictable s390x breakage from failure to preserve call-saved registers\n"
  },
  {
    "path": "user.libc/arch/aarch64/atomic_arch.h",
    "content": "#define a_ll a_ll\nstatic inline int a_ll(volatile int *p)\n{\n\tint v;\n\t__asm__ __volatile__ (\"ldaxr %w0,%1\" : \"=r\"(v) : \"Q\"(*p));\n\treturn v;\n}\n\n#define a_sc a_sc\nstatic inline int a_sc(volatile int *p, int v)\n{\n\tint r;\n\t__asm__ __volatile__ (\"stlxr %w0,%w2,%1\" : \"=&r\"(r), \"=Q\"(*p) : \"r\"(v) : \"memory\");\n\treturn !r;\n}\n\n#define a_barrier a_barrier\nstatic inline void a_barrier()\n{\n\t__asm__ __volatile__ (\"dmb ish\" : : : \"memory\");\n}\n\n#define a_cas a_cas\nstatic inline int a_cas(volatile int *p, int t, int s)\n{\n\tint old;\n\tdo {\n\t\told = a_ll(p);\n\t\tif (old != t) {\n\t\t\ta_barrier();\n\t\t\tbreak;\n\t\t}\n\t} while (!a_sc(p, s));\n\treturn old;\n}\n\n#define a_ll_p a_ll_p\nstatic inline void *a_ll_p(volatile void *p)\n{\n\tvoid *v;\n\t__asm__ __volatile__ (\"ldaxr %0, %1\" : \"=r\"(v) : \"Q\"(*(void *volatile *)p));\n\treturn v;\n}\n\n#define a_sc_p a_sc_p\nstatic inline int a_sc_p(volatile int *p, void *v)\n{\n\tint r;\n\t__asm__ __volatile__ (\"stlxr %w0,%2,%1\" : \"=&r\"(r), \"=Q\"(*(void *volatile *)p) : \"r\"(v) : \"memory\");\n\treturn !r;\n}\n\n#define a_cas_p a_cas_p\nstatic inline void *a_cas_p(volatile void *p, void *t, void *s)\n{\n\tvoid *old;\n\tdo {\n\t\told = a_ll_p(p);\n\t\tif (old != t) {\n\t\t\ta_barrier();\n\t\t\tbreak;\n\t\t}\n\t} while (!a_sc_p(p, s));\n\treturn old;\n}\n\n#define a_ctz_64 a_ctz_64\nstatic inline int a_ctz_64(uint64_t x)\n{\n\t__asm__(\n\t\t\"\trbit %0, %1\\n\"\n\t\t\"\tclz %0, %0\\n\"\n\t\t: \"=r\"(x) : \"r\"(x));\n\treturn x;\n}\n\n#define a_clz_64 a_clz_64\nstatic inline int a_clz_64(uint64_t x)\n{\n\t__asm__(\"clz %0, %1\" : \"=r\"(x) : \"r\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/arch/aarch64/bits/alltypes.h.in",
    "content": "#define _Addr long\n#define _Int64 long\n#define _Reg long\n\n#if __AARCH64EB__\n#define __BYTE_ORDER 4321\n#else\n#define __BYTE_ORDER 1234\n#endif\n\n#define __LONG_MAX 0x7fffffffffffffffL\n\n#ifndef __cplusplus\nTYPEDEF unsigned wchar_t;\n#endif\nTYPEDEF unsigned wint_t;\n\nTYPEDEF int blksize_t;\nTYPEDEF unsigned int nlink_t;\n\nTYPEDEF float float_t;\nTYPEDEF double double_t;\n\nTYPEDEF struct { long long __ll; long double __ld; } max_align_t;\n"
  },
  {
    "path": "user.libc/arch/aarch64/bits/fcntl.h",
    "content": "#define O_CREAT        0100\n#define O_EXCL         0200\n#define O_NOCTTY       0400\n#define O_TRUNC       01000\n#define O_APPEND      02000\n#define O_NONBLOCK    04000\n#define O_DSYNC      010000\n#define O_SYNC     04010000\n#define O_RSYNC    04010000\n#define O_DIRECTORY  040000\n#define O_NOFOLLOW  0100000\n#define O_CLOEXEC  02000000\n\n#define O_ASYNC      020000\n#define O_DIRECT    0200000\n#define O_LARGEFILE 0400000\n#define O_NOATIME  01000000\n#define O_PATH    010000000\n#define O_TMPFILE 020040000\n#define O_NDELAY O_NONBLOCK\n\n#define F_DUPFD  0\n#define F_GETFD  1\n#define F_SETFD  2\n#define F_GETFL  3\n#define F_SETFL  4\n#define F_GETLK  5\n#define F_SETLK  6\n#define F_SETLKW 7\n#define F_SETOWN 8\n#define F_GETOWN 9\n#define F_SETSIG 10\n#define F_GETSIG 11\n\n#define F_SETOWN_EX 15\n#define F_GETOWN_EX 16\n\n#define F_GETOWNER_UIDS 17\n"
  },
  {
    "path": "user.libc/arch/aarch64/bits/fenv.h",
    "content": "#define FE_INVALID    1\n#define FE_DIVBYZERO  2\n#define FE_OVERFLOW   4\n#define FE_UNDERFLOW  8\n#define FE_INEXACT    16\n#define FE_ALL_EXCEPT 31\n#define FE_TONEAREST  0\n#define FE_DOWNWARD   0x800000\n#define FE_UPWARD     0x400000\n#define FE_TOWARDZERO 0xc00000\n\ntypedef unsigned int fexcept_t;\n\ntypedef struct {\n\tunsigned int __fpcr;\n\tunsigned int __fpsr;\n} fenv_t;\n\n#define FE_DFL_ENV      ((const fenv_t *) -1)\n"
  },
  {
    "path": "user.libc/arch/aarch64/bits/float.h",
    "content": "#define FLT_EVAL_METHOD 0\n\n#define LDBL_TRUE_MIN 6.47517511943802511092443895822764655e-4966L\n#define LDBL_MIN 3.36210314311209350626267781732175260e-4932L\n#define LDBL_MAX 1.18973149535723176508575932662800702e+4932L\n#define LDBL_EPSILON 1.92592994438723585305597794258492732e-34L\n\n#define LDBL_MANT_DIG 113\n#define LDBL_MIN_EXP (-16381)\n#define LDBL_MAX_EXP 16384\n\n#define LDBL_DIG 33\n#define LDBL_MIN_10_EXP (-4931)\n#define LDBL_MAX_10_EXP 4932\n\n#define DECIMAL_DIG 36\n"
  },
  {
    "path": "user.libc/arch/aarch64/bits/hwcap.h",
    "content": "#define HWCAP_FP\t\t(1 << 0)\n#define HWCAP_ASIMD\t\t(1 << 1)\n#define HWCAP_EVTSTRM\t\t(1 << 2)\n#define HWCAP_AES\t\t(1 << 3)\n#define HWCAP_PMULL\t\t(1 << 4)\n#define HWCAP_SHA1\t\t(1 << 5)\n#define HWCAP_SHA2\t\t(1 << 6)\n#define HWCAP_CRC32\t\t(1 << 7)\n#define HWCAP_ATOMICS\t\t(1 << 8)\n#define HWCAP_FPHP\t\t(1 << 9)\n#define HWCAP_ASIMDHP\t\t(1 << 10)\n#define HWCAP_CPUID\t\t(1 << 11)\n#define HWCAP_ASIMDRDM\t\t(1 << 12)\n#define HWCAP_JSCVT\t\t(1 << 13)\n#define HWCAP_FCMA\t\t(1 << 14)\n#define HWCAP_LRCPC\t\t(1 << 15)\n#define HWCAP_DCPOP\t\t(1 << 16)\n#define HWCAP_SHA3\t\t(1 << 17)\n#define HWCAP_SM3\t\t(1 << 18)\n#define HWCAP_SM4\t\t(1 << 19)\n#define HWCAP_ASIMDDP\t\t(1 << 20)\n#define HWCAP_SHA512\t\t(1 << 21)\n#define HWCAP_SVE\t\t(1 << 22)\n#define HWCAP_ASIMDFHM\t\t(1 << 23)\n#define HWCAP_DIT\t\t(1 << 24)\n#define HWCAP_USCAT\t\t(1 << 25)\n#define HWCAP_ILRCPC\t\t(1 << 26)\n#define HWCAP_FLAGM\t\t(1 << 27)\n#define HWCAP_SSBS\t\t(1 << 28)\n#define HWCAP_SB\t\t(1 << 29)\n#define HWCAP_PACA\t\t(1 << 30)\n#define HWCAP_PACG\t\t(1UL << 31)\n\n#define HWCAP2_DCPODP\t\t(1 << 0)\n#define HWCAP2_SVE2\t\t(1 << 1)\n#define HWCAP2_SVEAES\t\t(1 << 2)\n#define HWCAP2_SVEPMULL\t\t(1 << 3)\n#define HWCAP2_SVEBITPERM\t(1 << 4)\n#define HWCAP2_SVESHA3\t\t(1 << 5)\n#define HWCAP2_SVESM4\t\t(1 << 6)\n#define HWCAP2_FLAGM2\t\t(1 << 7)\n#define HWCAP2_FRINT\t\t(1 << 8)\n#define HWCAP2_SVEI8MM\t\t(1 << 9)\n#define HWCAP2_SVEF32MM\t\t(1 << 10)\n#define HWCAP2_SVEF64MM\t\t(1 << 11)\n#define HWCAP2_SVEBF16\t\t(1 << 12)\n#define HWCAP2_I8MM\t\t(1 << 13)\n#define HWCAP2_BF16\t\t(1 << 14)\n#define HWCAP2_DGH\t\t(1 << 15)\n#define HWCAP2_RNG\t\t(1 << 16)\n"
  },
  {
    "path": "user.libc/arch/aarch64/bits/posix.h",
    "content": "#define _POSIX_V6_LP64_OFF64  1\n#define _POSIX_V7_LP64_OFF64  1\n"
  },
  {
    "path": "user.libc/arch/aarch64/bits/reg.h",
    "content": "#undef __WORDSIZE\n#define __WORDSIZE 64\n"
  },
  {
    "path": "user.libc/arch/aarch64/bits/setjmp.h",
    "content": "typedef unsigned long __jmp_buf[22];\n"
  },
  {
    "path": "user.libc/arch/aarch64/bits/signal.h",
    "content": "#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define MINSIGSTKSZ 6144\n#define SIGSTKSZ 12288\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\ntypedef unsigned long greg_t;\ntypedef unsigned long gregset_t[34];\n\ntypedef struct {\n\t__uint128_t vregs[32];\n\tunsigned int fpsr;\n\tunsigned int fpcr;\n} fpregset_t;\ntypedef struct sigcontext {\n\tunsigned long fault_address;\n\tunsigned long regs[31];\n\tunsigned long sp, pc, pstate;\n\tlong double __reserved[256];\n} mcontext_t;\n\n#define FPSIMD_MAGIC 0x46508001\n#define ESR_MAGIC 0x45535201\n#define EXTRA_MAGIC 0x45585401\n#define SVE_MAGIC 0x53564501\nstruct _aarch64_ctx {\n\tunsigned int magic;\n\tunsigned int size;\n};\nstruct fpsimd_context {\n\tstruct _aarch64_ctx head;\n\tunsigned int fpsr;\n\tunsigned int fpcr;\n\t__uint128_t vregs[32];\n};\nstruct esr_context {\n\tstruct _aarch64_ctx head;\n\tunsigned long esr;\n};\nstruct extra_context {\n\tstruct _aarch64_ctx head;\n\tunsigned long datap;\n\tunsigned int size;\n\tunsigned int __reserved[3];\n};\nstruct sve_context {\n\tstruct _aarch64_ctx head;\n\tunsigned short vl;\n\tunsigned short __reserved[3];\n};\n#define SVE_VQ_BYTES\t\t16\n#define SVE_VQ_MIN\t\t1\n#define SVE_VQ_MAX\t\t512\n#define SVE_VL_MIN\t\t(SVE_VQ_MIN * SVE_VQ_BYTES)\n#define SVE_VL_MAX\t\t(SVE_VQ_MAX * SVE_VQ_BYTES)\n#define SVE_NUM_ZREGS\t\t32\n#define SVE_NUM_PREGS\t\t16\n#define sve_vl_valid(vl) \\\n\t((vl) % SVE_VQ_BYTES == 0 && (vl) >= SVE_VL_MIN && (vl) <= SVE_VL_MAX)\n#define sve_vq_from_vl(vl)\t((vl) / SVE_VQ_BYTES)\n#define sve_vl_from_vq(vq)\t((vq) * SVE_VQ_BYTES)\n#define SVE_SIG_ZREG_SIZE(vq)\t((unsigned)(vq) * SVE_VQ_BYTES)\n#define SVE_SIG_PREG_SIZE(vq)\t((unsigned)(vq) * (SVE_VQ_BYTES / 8))\n#define SVE_SIG_FFR_SIZE(vq)\tSVE_SIG_PREG_SIZE(vq)\n#define SVE_SIG_REGS_OFFSET\t\t\t\t\t\\\n\t((sizeof(struct sve_context) + (SVE_VQ_BYTES - 1))\t\\\n\t\t/ SVE_VQ_BYTES * SVE_VQ_BYTES)\n#define SVE_SIG_ZREGS_OFFSET\tSVE_SIG_REGS_OFFSET\n#define SVE_SIG_ZREG_OFFSET(vq, n) \\\n\t(SVE_SIG_ZREGS_OFFSET + SVE_SIG_ZREG_SIZE(vq) * (n))\n#define SVE_SIG_ZREGS_SIZE(vq) \\\n\t(SVE_SIG_ZREG_OFFSET(vq, SVE_NUM_ZREGS) - SVE_SIG_ZREGS_OFFSET)\n#define SVE_SIG_PREGS_OFFSET(vq) \\\n\t(SVE_SIG_ZREGS_OFFSET + SVE_SIG_ZREGS_SIZE(vq))\n#define SVE_SIG_PREG_OFFSET(vq, n) \\\n\t(SVE_SIG_PREGS_OFFSET(vq) + SVE_SIG_PREG_SIZE(vq) * (n))\n#define SVE_SIG_PREGS_SIZE(vq) \\\n\t(SVE_SIG_PREG_OFFSET(vq, SVE_NUM_PREGS) - SVE_SIG_PREGS_OFFSET(vq))\n#define SVE_SIG_FFR_OFFSET(vq) \\\n\t(SVE_SIG_PREGS_OFFSET(vq) + SVE_SIG_PREGS_SIZE(vq))\n#define SVE_SIG_REGS_SIZE(vq) \\\n\t(SVE_SIG_FFR_OFFSET(vq) + SVE_SIG_FFR_SIZE(vq) - SVE_SIG_REGS_OFFSET)\n#define SVE_SIG_CONTEXT_SIZE(vq) (SVE_SIG_REGS_OFFSET + SVE_SIG_REGS_SIZE(vq))\n#else\ntypedef struct {\n\tlong double __regs[18+256];\n} mcontext_t;\n#endif\n\nstruct sigaltstack {\n\tvoid *ss_sp;\n\tint ss_flags;\n\tsize_t ss_size;\n};\n\ntypedef struct __ucontext {\n\tunsigned long uc_flags;\n\tstruct __ucontext *uc_link;\n\tstack_t uc_stack;\n\tsigset_t uc_sigmask;\n\tmcontext_t uc_mcontext;\n} ucontext_t;\n\n#define SA_NOCLDSTOP  1\n#define SA_NOCLDWAIT  2\n#define SA_SIGINFO    4\n#define SA_ONSTACK    0x08000000\n#define SA_RESTART    0x10000000\n#define SA_NODEFER    0x40000000\n#define SA_RESETHAND  0x80000000\n#define SA_RESTORER   0x04000000\n\n#endif\n\n#define SIGHUP    1\n#define SIGINT    2\n#define SIGQUIT   3\n#define SIGILL    4\n#define SIGTRAP   5\n#define SIGABRT   6\n#define SIGIOT    SIGABRT\n#define SIGBUS    7\n#define SIGFPE    8\n#define SIGKILL   9\n#define SIGUSR1   10\n#define SIGSEGV   11\n#define SIGUSR2   12\n#define SIGPIPE   13\n#define SIGALRM   14\n#define SIGTERM   15\n#define SIGSTKFLT 16\n#define SIGCHLD   17\n#define SIGCONT   18\n#define SIGSTOP   19\n#define SIGTSTP   20\n#define SIGTTIN   21\n#define SIGTTOU   22\n#define SIGURG    23\n#define SIGXCPU   24\n#define SIGXFSZ   25\n#define SIGVTALRM 26\n#define SIGPROF   27\n#define SIGWINCH  28\n#define SIGIO     29\n#define SIGPOLL   29\n#define SIGPWR    30\n#define SIGSYS    31\n#define SIGUNUSED SIGSYS\n\n#define _NSIG 65\n"
  },
  {
    "path": "user.libc/arch/aarch64/bits/stat.h",
    "content": "struct stat {\n\tdev_t st_dev;\n\tino_t st_ino;\n\tmode_t st_mode;\n\tnlink_t st_nlink;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tdev_t st_rdev;\n\tunsigned long __pad;\n\toff_t st_size;\n\tblksize_t st_blksize;\n\tint __pad2;\n\tblkcnt_t st_blocks;\n\tstruct timespec st_atim;\n\tstruct timespec st_mtim;\n\tstruct timespec st_ctim;\n\tunsigned __unused[2];\n};\n"
  },
  {
    "path": "user.libc/arch/aarch64/bits/stdint.h",
    "content": "typedef int32_t int_fast16_t;\ntypedef int32_t int_fast32_t;\ntypedef uint32_t uint_fast16_t;\ntypedef uint32_t uint_fast32_t;\n\n#define INT_FAST16_MIN  INT32_MIN\n#define INT_FAST32_MIN  INT32_MIN\n\n#define INT_FAST16_MAX  INT32_MAX\n#define INT_FAST32_MAX  INT32_MAX\n\n#define UINT_FAST16_MAX UINT32_MAX\n#define UINT_FAST32_MAX UINT32_MAX\n\n#define INTPTR_MIN      INT64_MIN\n#define INTPTR_MAX      INT64_MAX\n#define UINTPTR_MAX     UINT64_MAX\n#define PTRDIFF_MIN     INT64_MIN\n#define PTRDIFF_MAX     INT64_MAX\n#define SIZE_MAX        UINT64_MAX\n"
  },
  {
    "path": "user.libc/arch/aarch64/bits/syscall.h.in",
    "content": "#define __NR_kobject_create 0\n#define __NR_kobject_open 1\n#define __NR_kobject_close 2\n#define __NR_kobject_recv 3\n#define __NR_kobject_send 4\n#define __NR_kobject_reply 5\n#define __NR_kobject_reply_recv 6\n#define __NR_kobject_ctl 7\n#define __NR_kobject_mmap 8\n#define __NR_kobject_munmap 9\n#define __NR_grant 10\n#define __NR_futex 11\n#define __NR_yield 12\n#define __NR_map 13\n#define __NR_unmap 14\n#define __NR_mtrans 15\n#define __NR_clock_gettime 16\n#define __NR_clock_nanosleep 17\n#define __NR_exit 18\n#define __NR_exitgroup 19\n#define __NR_clone 20\n"
  },
  {
    "path": "user.libc/arch/aarch64/bits/user.h",
    "content": "struct user_regs_struct {\n\tunsigned long long regs[31];\n\tunsigned long long sp;\n\tunsigned long long pc;\n\tunsigned long long pstate;\n};\n\nstruct user_fpsimd_struct {\n\t__uint128_t vregs[32];\n\tunsigned int fpsr;\n\tunsigned int fpcr;\n};\n\n#define ELF_NREG 34\ntypedef unsigned long elf_greg_t, elf_gregset_t[ELF_NREG];\ntypedef struct user_fpsimd_struct elf_fpregset_t;\n"
  },
  {
    "path": "user.libc/arch/aarch64/crt_arch.h",
    "content": "__asm__(\n\".text \\n\"\n\".global \" START \"\\n\"\n\".type \" START \",%function\\n\"\nSTART \":\\n\"\n\"\tmov x29, #0\\n\"\n\"\tmov x30, #0\\n\"\n\"\tmov x0, sp\\n\"\n\".weak _DYNAMIC\\n\"\n\".hidden _DYNAMIC\\n\"\n\"\tadrp x1, _DYNAMIC\\n\"\n\"\tadd x1, x1, #:lo12:_DYNAMIC\\n\"\n\"\tand sp, x0, #-16\\n\"\n\"\tb \" START \"_c\\n\"\n);\n"
  },
  {
    "path": "user.libc/arch/aarch64/fp_arch.h",
    "content": "#define fp_barrierf fp_barrierf\nstatic inline float fp_barrierf(float x)\n{\n\t__asm__ __volatile__ (\"\" : \"+w\"(x));\n\treturn x;\n}\n\n#define fp_barrier fp_barrier\nstatic inline double fp_barrier(double x)\n{\n\t__asm__ __volatile__ (\"\" : \"+w\"(x));\n\treturn x;\n}\n\n#define fp_force_evalf fp_force_evalf\nstatic inline void fp_force_evalf(float x)\n{\n\t__asm__ __volatile__ (\"\" : \"+w\"(x));\n}\n\n#define fp_force_eval fp_force_eval\nstatic inline void fp_force_eval(double x)\n{\n\t__asm__ __volatile__ (\"\" : \"+w\"(x));\n}\n"
  },
  {
    "path": "user.libc/arch/aarch64/kstat.h",
    "content": "struct kstat {\n\tdev_t st_dev;\n\tino_t st_ino;\n\tmode_t st_mode;\n\tnlink_t st_nlink;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tdev_t st_rdev;\n\tunsigned long __pad;\n\toff_t st_size;\n\tblksize_t st_blksize;\n\tint __pad2;\n\tblkcnt_t st_blocks;\n\tlong st_atime_sec;\n\tlong st_atime_nsec;\n\tlong st_mtime_sec;\n\tlong st_mtime_nsec;\n\tlong st_ctime_sec;\n\tlong st_ctime_nsec;\n\tunsigned __unused[2];\n};\n"
  },
  {
    "path": "user.libc/arch/aarch64/pthread_arch.h",
    "content": "static inline uintptr_t __get_tp()\n{\n\tuintptr_t tp;\n\t__asm__ (\"mrs %0,tpidr_el0\" : \"=r\"(tp));\n\treturn tp;\n}\n\n#define TLS_ABOVE_TP\n#define GAP_ABOVE_TP 16\n\n#define MC_PC pc\n"
  },
  {
    "path": "user.libc/arch/aarch64/reloc.h",
    "content": "#if __BYTE_ORDER == __BIG_ENDIAN\n#define ENDIAN_SUFFIX \"_be\"\n#else\n#define ENDIAN_SUFFIX \"\"\n#endif\n\n#define LDSO_ARCH \"aarch64\" ENDIAN_SUFFIX\n\n#define NO_LEGACY_INITFINI\n\n#define TPOFF_K 0\n\n#define REL_SYMBOLIC    R_AARCH64_ABS64\n#define REL_GOT         R_AARCH64_GLOB_DAT\n#define REL_PLT         R_AARCH64_JUMP_SLOT\n#define REL_RELATIVE    R_AARCH64_RELATIVE\n#define REL_COPY        R_AARCH64_COPY\n#define REL_DTPMOD      R_AARCH64_TLS_DTPMOD64\n#define REL_DTPOFF      R_AARCH64_TLS_DTPREL64\n#define REL_TPOFF       R_AARCH64_TLS_TPREL64\n#define REL_TLSDESC     R_AARCH64_TLSDESC\n\n#define CRTJMP(pc,sp) __asm__ __volatile__( \\\n\t\"mov sp,%1 ; br %0\" : : \"r\"(pc), \"r\"(sp) : \"memory\" )\n"
  },
  {
    "path": "user.libc/arch/aarch64/syscall_arch.h",
    "content": "#define __SYSCALL_LL_E(x) (x)\n#define __SYSCALL_LL_O(x) (x)\n\n#define __asm_syscall(...) do { \\\n\t__asm__ __volatile__ ( \"svc 0\" \\\n\t: \"=r\"(x0) : __VA_ARGS__ : \"memory\", \"cc\"); \\\n\treturn x0; \\\n\t} while (0)\n\nstatic inline long __syscall0(long n)\n{\n\tregister long x8 __asm__(\"x8\") = n;\n\tregister long x0 __asm__(\"x0\");\n\t__asm_syscall(\"r\"(x8));\n}\n\nstatic inline long __syscall1(long n, long a)\n{\n\tregister long x8 __asm__(\"x8\") = n;\n\tregister long x0 __asm__(\"x0\") = a;\n\t__asm_syscall(\"r\"(x8), \"0\"(x0));\n}\n\nstatic inline long __syscall2(long n, long a, long b)\n{\n\tregister long x8 __asm__(\"x8\") = n;\n\tregister long x0 __asm__(\"x0\") = a;\n\tregister long x1 __asm__(\"x1\") = b;\n\t__asm_syscall(\"r\"(x8), \"0\"(x0), \"r\"(x1));\n}\n\nstatic inline long __syscall3(long n, long a, long b, long c)\n{\n\tregister long x8 __asm__(\"x8\") = n;\n\tregister long x0 __asm__(\"x0\") = a;\n\tregister long x1 __asm__(\"x1\") = b;\n\tregister long x2 __asm__(\"x2\") = c;\n\t__asm_syscall(\"r\"(x8), \"0\"(x0), \"r\"(x1), \"r\"(x2));\n}\n\nstatic inline long __syscall4(long n, long a, long b, long c, long d)\n{\n\tregister long x8 __asm__(\"x8\") = n;\n\tregister long x0 __asm__(\"x0\") = a;\n\tregister long x1 __asm__(\"x1\") = b;\n\tregister long x2 __asm__(\"x2\") = c;\n\tregister long x3 __asm__(\"x3\") = d;\n\t__asm_syscall(\"r\"(x8), \"0\"(x0), \"r\"(x1), \"r\"(x2), \"r\"(x3));\n}\n\nstatic inline long __syscall5(long n, long a, long b, long c, long d, long e)\n{\n\tregister long x8 __asm__(\"x8\") = n;\n\tregister long x0 __asm__(\"x0\") = a;\n\tregister long x1 __asm__(\"x1\") = b;\n\tregister long x2 __asm__(\"x2\") = c;\n\tregister long x3 __asm__(\"x3\") = d;\n\tregister long x4 __asm__(\"x4\") = e;\n\t__asm_syscall(\"r\"(x8), \"0\"(x0), \"r\"(x1), \"r\"(x2), \"r\"(x3), \"r\"(x4));\n}\n\nstatic inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)\n{\n\tregister long x8 __asm__(\"x8\") = n;\n\tregister long x0 __asm__(\"x0\") = a;\n\tregister long x1 __asm__(\"x1\") = b;\n\tregister long x2 __asm__(\"x2\") = c;\n\tregister long x3 __asm__(\"x3\") = d;\n\tregister long x4 __asm__(\"x4\") = e;\n\tregister long x5 __asm__(\"x5\") = f;\n\t__asm_syscall(\"r\"(x8), \"0\"(x0), \"r\"(x1), \"r\"(x2), \"r\"(x3), \"r\"(x4), \"r\"(x5));\n}\n\nstatic inline long __syscall7(long n, long a, long b, long c, long d, long e, long f, long g)\n{\n\tregister long x8 __asm__(\"x8\") = n;\n\tregister long x0 __asm__(\"x0\") = a;\n\tregister long x1 __asm__(\"x1\") = b;\n\tregister long x2 __asm__(\"x2\") = c;\n\tregister long x3 __asm__(\"x3\") = d;\n\tregister long x4 __asm__(\"x4\") = e;\n\tregister long x5 __asm__(\"x5\") = f;\n\tregister long x6 __asm__(\"x6\") = g;\n\t__asm_syscall(\"r\"(x8), \"0\"(x0), \"r\"(x1), \"r\"(x2), \"r\"(x3), \"r\"(x4), \"r\"(x5), \"r\"(x6));\n}\n\n#define VDSO_USEFUL\n#define VDSO_CGT_SYM \"__kernel_clock_gettime\"\n#define VDSO_CGT_VER \"LINUX_2.6.39\"\n\n#define IPC_64 0\n"
  },
  {
    "path": "user.libc/arch/arm/arch.mak",
    "content": "COMPAT_SRC_DIRS = compat/time32\n"
  },
  {
    "path": "user.libc/arch/arm/atomic_arch.h",
    "content": "#include \"libc.h\"\n\n#if __ARM_ARCH_4__ || __ARM_ARCH_4T__ || __ARM_ARCH == 4\n#define BLX \"mov lr,pc\\n\\tbx\"\n#else\n#define BLX \"blx\"\n#endif\n\nextern hidden uintptr_t __a_cas_ptr, __a_barrier_ptr;\n\n#if ((__ARM_ARCH_6__ || __ARM_ARCH_6K__ || __ARM_ARCH_6KZ__ || __ARM_ARCH_6ZK__) && !__thumb__) \\\n || __ARM_ARCH_6T2__ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7\n\n#define a_ll a_ll\nstatic inline int a_ll(volatile int *p)\n{\n\tint v;\n\t__asm__ __volatile__ (\"ldrex %0, %1\" : \"=r\"(v) : \"Q\"(*p));\n\treturn v;\n}\n\n#define a_sc a_sc\nstatic inline int a_sc(volatile int *p, int v)\n{\n\tint r;\n\t__asm__ __volatile__ (\"strex %0,%2,%1\" : \"=&r\"(r), \"=Q\"(*p) : \"r\"(v) : \"memory\");\n\treturn !r;\n}\n\n#if __ARM_ARCH_7A__ || __ARM_ARCH_7R__ ||  __ARM_ARCH >= 7\n\n#define a_barrier a_barrier\nstatic inline void a_barrier()\n{\n\t__asm__ __volatile__ (\"dmb ish\" : : : \"memory\");\n}\n\n#endif\n\n#define a_pre_llsc a_barrier\n#define a_post_llsc a_barrier\n\n#else\n\n#define a_cas a_cas\nstatic inline int a_cas(volatile int *p, int t, int s)\n{\n\tfor (;;) {\n\t\tregister int r0 __asm__(\"r0\") = t;\n\t\tregister int r1 __asm__(\"r1\") = s;\n\t\tregister volatile int *r2 __asm__(\"r2\") = p;\n\t\tregister uintptr_t r3 __asm__(\"r3\") = __a_cas_ptr;\n\t\tint old;\n\t\t__asm__ __volatile__ (\n\t\t\tBLX \" r3\"\n\t\t\t: \"+r\"(r0), \"+r\"(r3) : \"r\"(r1), \"r\"(r2)\n\t\t\t: \"memory\", \"lr\", \"ip\", \"cc\" );\n\t\tif (!r0) return t;\n\t\tif ((old=*p)!=t) return old;\n\t}\n}\n\n#endif\n\n#ifndef a_barrier\n#define a_barrier a_barrier\nstatic inline void a_barrier()\n{\n\tregister uintptr_t ip __asm__(\"ip\") = __a_barrier_ptr;\n\t__asm__ __volatile__( BLX \" ip\" : \"+r\"(ip) : : \"memory\", \"cc\", \"lr\" );\n}\n#endif\n\n#define a_crash a_crash\nstatic inline void a_crash()\n{\n\t__asm__ __volatile__(\n#ifndef __thumb__\n\t\t\".word 0xe7f000f0\"\n#else\n\t\t\".short 0xdeff\"\n#endif\n\t\t: : : \"memory\");\n}\n\n#if __ARM_ARCH >= 5 && (!__thumb__ || __thumb2__)\n\n#define a_clz_32 a_clz_32\nstatic inline int a_clz_32(uint32_t x)\n{\n\t__asm__ (\"clz %0, %1\" : \"=r\"(x) : \"r\"(x));\n\treturn x;\n}\n\n#if __ARM_ARCH_6T2__ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7\n\n#define a_ctz_32 a_ctz_32\nstatic inline int a_ctz_32(uint32_t x)\n{\n\tuint32_t xr;\n\t__asm__ (\"rbit %0, %1\" : \"=r\"(xr) : \"r\"(x));\n\treturn a_clz_32(xr);\n}\n\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/arch/arm/bits/alltypes.h.in",
    "content": "#define _REDIR_TIME64 1\n#define _Addr int\n#define _Int64 long long\n#define _Reg int\n\n#if __ARMEB__\n#define __BYTE_ORDER 4321\n#else\n#define __BYTE_ORDER 1234\n#endif\n\n#define __LONG_MAX 0x7fffffffL\n\n#ifndef __cplusplus\nTYPEDEF unsigned wchar_t;\n#endif\n\nTYPEDEF float float_t;\nTYPEDEF double double_t;\n\nTYPEDEF struct { long long __ll; long double __ld; } max_align_t;\n"
  },
  {
    "path": "user.libc/arch/arm/bits/fcntl.h",
    "content": "#define O_CREAT        0100\n#define O_EXCL         0200\n#define O_NOCTTY       0400\n#define O_TRUNC       01000\n#define O_APPEND      02000\n#define O_NONBLOCK    04000\n#define O_DSYNC      010000\n#define O_SYNC     04010000\n#define O_RSYNC    04010000\n#define O_DIRECTORY  040000\n#define O_NOFOLLOW  0100000\n#define O_CLOEXEC  02000000\n\n#define O_ASYNC      020000\n#define O_DIRECT    0200000\n#define O_LARGEFILE 0400000\n#define O_NOATIME  01000000\n#define O_PATH    010000000\n#define O_TMPFILE 020040000\n#define O_NDELAY O_NONBLOCK\n\n#define F_DUPFD  0\n#define F_GETFD  1\n#define F_SETFD  2\n#define F_GETFL  3\n#define F_SETFL  4\n\n#define F_SETOWN 8\n#define F_GETOWN 9\n#define F_SETSIG 10\n#define F_GETSIG 11\n\n#define F_GETLK 12\n#define F_SETLK 13\n#define F_SETLKW 14\n\n#define F_SETOWN_EX 15\n#define F_GETOWN_EX 16\n\n#define F_GETOWNER_UIDS 17\n"
  },
  {
    "path": "user.libc/arch/arm/bits/fenv.h",
    "content": "#ifndef __ARM_PCS_VFP\n#define FE_ALL_EXCEPT 0\n#define FE_TONEAREST  0\n#else\n#define FE_INVALID    1\n#define FE_DIVBYZERO  2\n#define FE_OVERFLOW   4\n#define FE_UNDERFLOW  8\n#define FE_INEXACT    16\n#define FE_ALL_EXCEPT 31\n#define FE_TONEAREST  0\n#define FE_DOWNWARD   0x800000\n#define FE_UPWARD     0x400000\n#define FE_TOWARDZERO 0xc00000\n#endif\n\ntypedef unsigned long fexcept_t;\n\ntypedef struct {\n\tunsigned long __cw;\n} fenv_t;\n\n#define FE_DFL_ENV      ((const fenv_t *) -1)\n"
  },
  {
    "path": "user.libc/arch/arm/bits/float.h",
    "content": "#define FLT_EVAL_METHOD 0\n\n#define LDBL_TRUE_MIN 4.94065645841246544177e-324L\n#define LDBL_MIN 2.22507385850720138309e-308L\n#define LDBL_MAX 1.79769313486231570815e+308L\n#define LDBL_EPSILON 2.22044604925031308085e-16L\n\n#define LDBL_MANT_DIG 53\n#define LDBL_MIN_EXP (-1021)\n#define LDBL_MAX_EXP 1024\n\n#define LDBL_DIG 15\n#define LDBL_MIN_10_EXP (-307)\n#define LDBL_MAX_10_EXP 308\n\n#define DECIMAL_DIG 17\n"
  },
  {
    "path": "user.libc/arch/arm/bits/hwcap.h",
    "content": "#define HWCAP_SWP\t(1 << 0)\n#define HWCAP_HALF\t(1 << 1)\n#define HWCAP_THUMB\t(1 << 2)\n#define HWCAP_26BIT\t(1 << 3)\n#define HWCAP_FAST_MULT\t(1 << 4)\n#define HWCAP_FPA\t(1 << 5)\n#define HWCAP_VFP\t(1 << 6)\n#define HWCAP_EDSP\t(1 << 7)\n#define HWCAP_JAVA\t(1 << 8)\n#define HWCAP_IWMMXT\t(1 << 9)\n#define HWCAP_CRUNCH\t(1 << 10)\n#define HWCAP_THUMBEE\t(1 << 11)\n#define HWCAP_NEON\t(1 << 12)\n#define HWCAP_VFPv3\t(1 << 13)\n#define HWCAP_VFPv3D16\t(1 << 14)\n#define HWCAP_TLS\t(1 << 15)\n#define HWCAP_VFPv4\t(1 << 16)\n#define HWCAP_IDIVA\t(1 << 17)\n#define HWCAP_IDIVT\t(1 << 18)\n#define HWCAP_VFPD32\t(1 << 19)\n#define HWCAP_IDIV\t(HWCAP_IDIVA | HWCAP_IDIVT)\n#define HWCAP_LPAE\t(1 << 20)\n#define HWCAP_EVTSTRM\t(1 << 21)\n\n#define HWCAP2_AES\t(1 << 0)\n#define HWCAP2_PMULL\t(1 << 1)\n#define HWCAP2_SHA1\t(1 << 2)\n#define HWCAP2_SHA2\t(1 << 3)\n#define HWCAP2_CRC32\t(1 << 4)\n\n#define HWCAP_ARM_SWP\t(1 << 0)\n#define HWCAP_ARM_HALF\t(1 << 1)\n#define HWCAP_ARM_THUMB\t(1 << 2)\n#define HWCAP_ARM_26BIT\t(1 << 3)\n#define HWCAP_ARM_FAST_MULT\t(1 << 4)\n#define HWCAP_ARM_FPA\t(1 << 5)\n#define HWCAP_ARM_VFP\t(1 << 6)\n#define HWCAP_ARM_EDSP\t(1 << 7)\n#define HWCAP_ARM_JAVA\t(1 << 8)\n#define HWCAP_ARM_IWMMXT\t(1 << 9)\n#define HWCAP_ARM_CRUNCH\t(1 << 10)\n#define HWCAP_ARM_THUMBEE\t(1 << 11)\n#define HWCAP_ARM_NEON\t(1 << 12)\n#define HWCAP_ARM_VFPv3\t(1 << 13)\n#define HWCAP_ARM_VFPv3D16\t(1 << 14)\n#define HWCAP_ARM_TLS\t(1 << 15)\n#define HWCAP_ARM_VFPv4\t(1 << 16)\n#define HWCAP_ARM_IDIVA\t(1 << 17)\n#define HWCAP_ARM_IDIVT\t(1 << 18)\n#define HWCAP_ARM_VFPD32\t(1 << 19)\n#define HWCAP_ARM_IDIV\t(HWCAP_ARM_IDIVA | HWCAP_ARM_IDIVT)\n#define HWCAP_ARM_LPAE\t(1 << 20)\n#define HWCAP_ARM_EVTSTRM\t(1 << 21)\n"
  },
  {
    "path": "user.libc/arch/arm/bits/ioctl_fix.h",
    "content": "#undef FIOQSIZE\n#define FIOQSIZE 0x545e\n"
  },
  {
    "path": "user.libc/arch/arm/bits/ipcstat.h",
    "content": "#define IPC_STAT 0x102\n"
  },
  {
    "path": "user.libc/arch/arm/bits/msg.h",
    "content": "struct msqid_ds {\n\tstruct ipc_perm msg_perm;\n\tunsigned long __msg_stime_lo;\n\tunsigned long __msg_stime_hi;\n\tunsigned long __msg_rtime_lo;\n\tunsigned long __msg_rtime_hi;\n\tunsigned long __msg_ctime_lo;\n\tunsigned long __msg_ctime_hi;\n\tunsigned long msg_cbytes;\n\tmsgqnum_t msg_qnum;\n\tmsglen_t msg_qbytes;\n\tpid_t msg_lspid;\n\tpid_t msg_lrpid;\n\tunsigned long __unused[2];\n\ttime_t msg_stime;\n\ttime_t msg_rtime;\n\ttime_t msg_ctime;\n};\n"
  },
  {
    "path": "user.libc/arch/arm/bits/posix.h",
    "content": "#define _POSIX_V6_ILP32_OFFBIG  1\n#define _POSIX_V7_ILP32_OFFBIG  1\n"
  },
  {
    "path": "user.libc/arch/arm/bits/ptrace.h",
    "content": "#define PTRACE_GETWMMXREGS\t18\n#define PTRACE_SETWMMXREGS\t19\n#define PTRACE_GET_THREAD_AREA\t22\n#define PTRACE_SET_SYSCALL\t23\n#define PTRACE_GETCRUNCHREGS\t25\n#define PTRACE_SETCRUNCHREGS\t26\n#define PTRACE_GETVFPREGS\t27\n#define PTRACE_SETVFPREGS\t28\n#define PTRACE_GETHBPREGS\t29\n#define PTRACE_SETHBPREGS\t30\n#define PTRACE_GETFDPIC\t\t31\n#define PTRACE_GETFDPIC_EXEC\t0\n#define PTRACE_GETFDPIC_INTERP\t1\n\n#define PT_GETWMMXREGS PTRACE_GETWMMXREGS\n#define PT_SETWMMXREGS PTRACE_SETWMMXREGS\n#define PT_GET_THREAD_AREA PTRACE_GET_THREAD_AREA\n#define PT_SET_SYSCALL PTRACE_SET_SYSCALL\n#define PT_GETCRUNCHREGS PTRACE_GETCRUNCHREGS\n#define PT_SETCRUNCHREGS PTRACE_SETCRUNCHREGS\n#define PT_GETVFPREGS PTRACE_GETVFPREGS\n#define PT_SETVFPREGS PTRACE_SETVFPREGS\n#define PT_GETHBPREGS PTRACE_GETHBPREGS\n#define PT_SETHBPREGS PTRACE_SETHBPREGS\n#define PT_GETFDPIC PTRACE_GETFDPIC\n"
  },
  {
    "path": "user.libc/arch/arm/bits/reg.h",
    "content": "#undef __WORDSIZE\n#define __WORDSIZE 32\n/* FIXME */\n"
  },
  {
    "path": "user.libc/arch/arm/bits/sem.h",
    "content": "struct semid_ds {\n\tstruct ipc_perm sem_perm;\n\tunsigned long __sem_otime_lo;\n\tunsigned long __sem_otime_hi;\n\tunsigned long __sem_ctime_lo;\n\tunsigned long __sem_ctime_hi;\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n\tunsigned short sem_nsems;\n\tchar __sem_nsems_pad[sizeof(long)-sizeof(short)];\n#else\n\tchar __sem_nsems_pad[sizeof(long)-sizeof(short)];\n\tunsigned short sem_nsems;\n#endif\n\tlong __unused3;\n\tlong __unused4;\n\ttime_t sem_otime;\n\ttime_t sem_ctime;\n};\n"
  },
  {
    "path": "user.libc/arch/arm/bits/setjmp.h",
    "content": "typedef unsigned long long __jmp_buf[32];\n"
  },
  {
    "path": "user.libc/arch/arm/bits/shm.h",
    "content": "#define SHMLBA 4096\n\nstruct shmid_ds {\n\tstruct ipc_perm shm_perm;\n\tsize_t shm_segsz;\n\tunsigned long __shm_atime_lo;\n\tunsigned long __shm_atime_hi;\n\tunsigned long __shm_dtime_lo;\n\tunsigned long __shm_dtime_hi;\n\tunsigned long __shm_ctime_lo;\n\tunsigned long __shm_ctime_hi;\n\tpid_t shm_cpid;\n\tpid_t shm_lpid;\n\tunsigned long shm_nattch;\n\tunsigned long __pad1;\n\tunsigned long __pad2;\n\tunsigned long __pad3;\n\ttime_t shm_atime;\n\ttime_t shm_dtime;\n\ttime_t shm_ctime;\n};\n\nstruct shminfo {\n\tunsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];\n};\n\nstruct shm_info {\n\tint __used_ids;\n\tunsigned long shm_tot, shm_rss, shm_swp;\n\tunsigned long __swap_attempts, __swap_successes;\n};\n"
  },
  {
    "path": "user.libc/arch/arm/bits/signal.h",
    "content": "#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define MINSIGSTKSZ 2048\n#define SIGSTKSZ 8192\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\ntypedef int greg_t, gregset_t[18];\ntypedef struct sigcontext {\n\tunsigned long trap_no, error_code, oldmask;\n\tunsigned long arm_r0, arm_r1, arm_r2, arm_r3;\n\tunsigned long arm_r4, arm_r5, arm_r6, arm_r7;\n\tunsigned long arm_r8, arm_r9, arm_r10, arm_fp;\n\tunsigned long arm_ip, arm_sp, arm_lr, arm_pc;\n\tunsigned long arm_cpsr, fault_address;\n} mcontext_t;\n#else\ntypedef struct {\n\tunsigned long __regs[21];\n} mcontext_t;\n#endif\n\nstruct sigaltstack {\n\tvoid *ss_sp;\n\tint ss_flags;\n\tsize_t ss_size;\n};\n\ntypedef struct __ucontext {\n\tunsigned long uc_flags;\n\tstruct __ucontext *uc_link;\n\tstack_t uc_stack;\n\tmcontext_t uc_mcontext;\n\tsigset_t uc_sigmask;\n\tunsigned long long uc_regspace[64];\n} ucontext_t;\n\n#define SA_NOCLDSTOP  1\n#define SA_NOCLDWAIT  2\n#define SA_SIGINFO    4\n#define SA_ONSTACK    0x08000000\n#define SA_RESTART    0x10000000\n#define SA_NODEFER    0x40000000\n#define SA_RESETHAND  0x80000000\n#define SA_RESTORER   0x04000000\n\n#endif\n\n#define SIGHUP    1\n#define SIGINT    2\n#define SIGQUIT   3\n#define SIGILL    4\n#define SIGTRAP   5\n#define SIGABRT   6\n#define SIGIOT    SIGABRT\n#define SIGBUS    7\n#define SIGFPE    8\n#define SIGKILL   9\n#define SIGUSR1   10\n#define SIGSEGV   11\n#define SIGUSR2   12\n#define SIGPIPE   13\n#define SIGALRM   14\n#define SIGTERM   15\n#define SIGSTKFLT 16\n#define SIGCHLD   17\n#define SIGCONT   18\n#define SIGSTOP   19\n#define SIGTSTP   20\n#define SIGTTIN   21\n#define SIGTTOU   22\n#define SIGURG    23\n#define SIGXCPU   24\n#define SIGXFSZ   25\n#define SIGVTALRM 26\n#define SIGPROF   27\n#define SIGWINCH  28\n#define SIGIO     29\n#define SIGPOLL   29\n#define SIGPWR    30\n#define SIGSYS    31\n#define SIGUNUSED SIGSYS\n\n#define _NSIG 65\n"
  },
  {
    "path": "user.libc/arch/arm/bits/stat.h",
    "content": "/* copied from kernel definition, but with padding replaced\n * by the corresponding correctly-sized userspace types. */\n\nstruct stat {\n\tdev_t st_dev;\n\tint __st_dev_padding;\n\tlong __st_ino_truncated;\n\tmode_t st_mode;\n\tnlink_t st_nlink;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tdev_t st_rdev;\n\tint __st_rdev_padding;\n\toff_t st_size;\n\tblksize_t st_blksize;\n\tblkcnt_t st_blocks;\n\tstruct {\n\t\tlong tv_sec;\n\t\tlong tv_nsec;\n\t} __st_atim32, __st_mtim32, __st_ctim32;\n\tino_t st_ino;\n\tstruct timespec st_atim;\n\tstruct timespec st_mtim;\n\tstruct timespec st_ctim;\n};\n"
  },
  {
    "path": "user.libc/arch/arm/bits/stdint.h",
    "content": "typedef int32_t int_fast16_t;\ntypedef int32_t int_fast32_t;\ntypedef uint32_t uint_fast16_t;\ntypedef uint32_t uint_fast32_t;\n\n#define INT_FAST16_MIN  INT32_MIN\n#define INT_FAST32_MIN  INT32_MIN\n\n#define INT_FAST16_MAX  INT32_MAX\n#define INT_FAST32_MAX  INT32_MAX\n\n#define UINT_FAST16_MAX UINT32_MAX\n#define UINT_FAST32_MAX UINT32_MAX\n\n#define INTPTR_MIN      INT32_MIN\n#define INTPTR_MAX      INT32_MAX\n#define UINTPTR_MAX     UINT32_MAX\n#define PTRDIFF_MIN     INT32_MIN\n#define PTRDIFF_MAX     INT32_MAX\n#define SIZE_MAX        UINT32_MAX\n"
  },
  {
    "path": "user.libc/arch/arm/bits/syscall.h.in",
    "content": "#define __NR_restart_syscall\t0\n#define __NR_exit\t1\n#define __NR_fork\t2\n#define __NR_read\t3\n#define __NR_write\t4\n#define __NR_open\t5\n#define __NR_close\t6\n#define __NR_creat\t8\n#define __NR_link\t9\n#define __NR_unlink\t10\n#define __NR_execve\t11\n#define __NR_chdir\t12\n#define __NR_mknod\t14\n#define __NR_chmod\t15\n#define __NR_lchown\t16\n#define __NR_lseek\t19\n#define __NR_getpid\t20\n#define __NR_mount\t21\n#define __NR_setuid\t23\n#define __NR_getuid\t24\n#define __NR_ptrace\t26\n#define __NR_pause\t29\n#define __NR_access\t33\n#define __NR_nice\t34\n#define __NR_sync\t36\n#define __NR_kill\t37\n#define __NR_rename\t38\n#define __NR_mkdir\t39\n#define __NR_rmdir\t40\n#define __NR_dup\t41\n#define __NR_pipe\t42\n#define __NR_times\t43\n#define __NR_brk\t45\n#define __NR_setgid\t46\n#define __NR_getgid\t47\n#define __NR_geteuid\t49\n#define __NR_getegid\t50\n#define __NR_acct\t51\n#define __NR_umount2\t52\n#define __NR_ioctl\t54\n#define __NR_fcntl\t55\n#define __NR_setpgid\t57\n#define __NR_umask\t60\n#define __NR_chroot\t61\n#define __NR_ustat\t62\n#define __NR_dup2\t63\n#define __NR_getppid\t64\n#define __NR_getpgrp\t65\n#define __NR_setsid\t66\n#define __NR_sigaction\t67\n#define __NR_setreuid\t70\n#define __NR_setregid\t71\n#define __NR_sigsuspend\t72\n#define __NR_sigpending\t73\n#define __NR_sethostname\t74\n#define __NR_setrlimit\t75\n#define __NR_getrusage\t77\n#define __NR_gettimeofday_time32\t78\n#define __NR_settimeofday_time32\t79\n#define __NR_getgroups\t80\n#define __NR_setgroups\t81\n#define __NR_symlink\t83\n#define __NR_readlink\t85\n#define __NR_uselib\t86\n#define __NR_swapon\t87\n#define __NR_reboot\t88\n#define __NR_munmap\t91\n#define __NR_truncate\t92\n#define __NR_ftruncate\t93\n#define __NR_fchmod\t94\n#define __NR_fchown\t95\n#define __NR_getpriority\t96\n#define __NR_setpriority\t97\n#define __NR_statfs\t99\n#define __NR_fstatfs\t100\n#define __NR_syslog\t103\n#define __NR_setitimer\t104\n#define __NR_getitimer\t105\n#define __NR_stat\t106\n#define __NR_lstat\t107\n#define __NR_fstat\t108\n#define __NR_vhangup\t111\n#define __NR_wait4\t114\n#define __NR_swapoff\t115\n#define __NR_sysinfo\t116\n#define __NR_fsync\t118\n#define __NR_sigreturn\t119\n#define __NR_clone\t120\n#define __NR_setdomainname\t121\n#define __NR_uname\t122\n#define __NR_adjtimex\t124\n#define __NR_mprotect\t125\n#define __NR_sigprocmask\t126\n#define __NR_init_module\t128\n#define __NR_delete_module\t129\n#define __NR_quotactl\t131\n#define __NR_getpgid\t132\n#define __NR_fchdir\t133\n#define __NR_bdflush\t134\n#define __NR_sysfs\t135\n#define __NR_personality\t136\n#define __NR_setfsuid\t138\n#define __NR_setfsgid\t139\n#define __NR__llseek\t140\n#define __NR_getdents\t141\n#define __NR__newselect\t142\n#define __NR_flock\t143\n#define __NR_msync\t144\n#define __NR_readv\t145\n#define __NR_writev\t146\n#define __NR_getsid\t147\n#define __NR_fdatasync\t148\n#define __NR__sysctl\t149\n#define __NR_mlock\t150\n#define __NR_munlock\t151\n#define __NR_mlockall\t152\n#define __NR_munlockall\t153\n#define __NR_sched_setparam\t154\n#define __NR_sched_getparam\t155\n#define __NR_sched_setscheduler\t156\n#define __NR_sched_getscheduler\t157\n#define __NR_sched_yield\t158\n#define __NR_sched_get_priority_max\t159\n#define __NR_sched_get_priority_min\t160\n#define __NR_sched_rr_get_interval\t161\n#define __NR_nanosleep\t162\n#define __NR_mremap\t163\n#define __NR_setresuid\t164\n#define __NR_getresuid\t165\n#define __NR_poll\t168\n#define __NR_nfsservctl\t169\n#define __NR_setresgid\t170\n#define __NR_getresgid\t171\n#define __NR_prctl\t172\n#define __NR_rt_sigreturn\t173\n#define __NR_rt_sigaction\t174\n#define __NR_rt_sigprocmask\t175\n#define __NR_rt_sigpending\t176\n#define __NR_rt_sigtimedwait\t177\n#define __NR_rt_sigqueueinfo\t178\n#define __NR_rt_sigsuspend\t179\n#define __NR_pread64\t180\n#define __NR_pwrite64\t181\n#define __NR_chown\t182\n#define __NR_getcwd\t183\n#define __NR_capget\t184\n#define __NR_capset\t185\n#define __NR_sigaltstack\t186\n#define __NR_sendfile\t187\n#define __NR_vfork\t190\n#define __NR_ugetrlimit\t191\n#define __NR_mmap2\t192\n#define __NR_truncate64\t193\n#define __NR_ftruncate64\t194\n#define __NR_stat64\t195\n#define __NR_lstat64\t196\n#define __NR_fstat64\t197\n#define __NR_lchown32\t198\n#define __NR_getuid32\t199\n#define __NR_getgid32\t200\n#define __NR_geteuid32\t201\n#define __NR_getegid32\t202\n#define __NR_setreuid32\t203\n#define __NR_setregid32\t204\n#define __NR_getgroups32\t205\n#define __NR_setgroups32\t206\n#define __NR_fchown32\t207\n#define __NR_setresuid32\t208\n#define __NR_getresuid32\t209\n#define __NR_setresgid32\t210\n#define __NR_getresgid32\t211\n#define __NR_chown32\t212\n#define __NR_setuid32\t213\n#define __NR_setgid32\t214\n#define __NR_setfsuid32\t215\n#define __NR_setfsgid32\t216\n#define __NR_getdents64\t217\n#define __NR_pivot_root\t218\n#define __NR_mincore\t219\n#define __NR_madvise\t220\n#define __NR_fcntl64\t221\n#define __NR_gettid\t224\n#define __NR_readahead\t225\n#define __NR_setxattr\t226\n#define __NR_lsetxattr\t227\n#define __NR_fsetxattr\t228\n#define __NR_getxattr\t229\n#define __NR_lgetxattr\t230\n#define __NR_fgetxattr\t231\n#define __NR_listxattr\t232\n#define __NR_llistxattr\t233\n#define __NR_flistxattr\t234\n#define __NR_removexattr\t235\n#define __NR_lremovexattr\t236\n#define __NR_fremovexattr\t237\n#define __NR_tkill\t238\n#define __NR_sendfile64\t239\n#define __NR_futex\t240\n#define __NR_sched_setaffinity\t241\n#define __NR_sched_getaffinity\t242\n#define __NR_io_setup\t243\n#define __NR_io_destroy\t244\n#define __NR_io_getevents\t245\n#define __NR_io_submit\t246\n#define __NR_io_cancel\t247\n#define __NR_exit_group\t248\n#define __NR_lookup_dcookie\t249\n#define __NR_epoll_create\t250\n#define __NR_epoll_ctl\t251\n#define __NR_epoll_wait\t252\n#define __NR_remap_file_pages\t253\n#define __NR_set_tid_address\t256\n#define __NR_timer_create\t257\n#define __NR_timer_settime32\t258\n#define __NR_timer_gettime32\t259\n#define __NR_timer_getoverrun\t260\n#define __NR_timer_delete\t261\n#define __NR_clock_settime32\t262\n#define __NR_clock_gettime32\t263\n#define __NR_clock_getres_time32\t264\n#define __NR_clock_nanosleep_time32\t265\n#define __NR_statfs64\t266\n#define __NR_fstatfs64\t267\n#define __NR_tgkill\t268\n#define __NR_utimes\t269\n#define __NR_fadvise64_64\t270\n#define __NR_arm_fadvise64_64\t270\n#define __NR_pciconfig_iobase\t271\n#define __NR_pciconfig_read\t272\n#define __NR_pciconfig_write\t273\n#define __NR_mq_open\t274\n#define __NR_mq_unlink\t275\n#define __NR_mq_timedsend\t276\n#define __NR_mq_timedreceive\t277\n#define __NR_mq_notify\t278\n#define __NR_mq_getsetattr\t279\n#define __NR_waitid\t280\n#define __NR_socket\t281\n#define __NR_bind\t282\n#define __NR_connect\t283\n#define __NR_listen\t284\n#define __NR_accept\t285\n#define __NR_getsockname\t286\n#define __NR_getpeername\t287\n#define __NR_socketpair\t288\n#define __NR_send\t289\n#define __NR_sendto\t290\n#define __NR_recv\t291\n#define __NR_recvfrom\t292\n#define __NR_shutdown\t293\n#define __NR_setsockopt\t294\n#define __NR_getsockopt\t295\n#define __NR_sendmsg\t296\n#define __NR_recvmsg\t297\n#define __NR_semop\t298\n#define __NR_semget\t299\n#define __NR_semctl\t300\n#define __NR_msgsnd\t301\n#define __NR_msgrcv\t302\n#define __NR_msgget\t303\n#define __NR_msgctl\t304\n#define __NR_shmat\t305\n#define __NR_shmdt\t306\n#define __NR_shmget\t307\n#define __NR_shmctl\t308\n#define __NR_add_key\t309\n#define __NR_request_key\t310\n#define __NR_keyctl\t311\n#define __NR_semtimedop\t312\n#define __NR_vserver\t313\n#define __NR_ioprio_set\t314\n#define __NR_ioprio_get\t315\n#define __NR_inotify_init\t316\n#define __NR_inotify_add_watch\t317\n#define __NR_inotify_rm_watch\t318\n#define __NR_mbind\t319\n#define __NR_get_mempolicy\t320\n#define __NR_set_mempolicy\t321\n#define __NR_openat\t322\n#define __NR_mkdirat\t323\n#define __NR_mknodat\t324\n#define __NR_fchownat\t325\n#define __NR_futimesat\t326\n#define __NR_fstatat64\t327\n#define __NR_unlinkat\t328\n#define __NR_renameat\t329\n#define __NR_linkat\t330\n#define __NR_symlinkat\t331\n#define __NR_readlinkat\t332\n#define __NR_fchmodat\t333\n#define __NR_faccessat\t334\n#define __NR_pselect6\t335\n#define __NR_ppoll\t336\n#define __NR_unshare\t337\n#define __NR_set_robust_list\t338\n#define __NR_get_robust_list\t339\n#define __NR_splice\t340\n#define __NR_sync_file_range2\t341\n#define __NR_arm_sync_file_range\t341\n#define __NR_tee\t342\n#define __NR_vmsplice\t343\n#define __NR_move_pages\t344\n#define __NR_getcpu\t345\n#define __NR_epoll_pwait\t346\n#define __NR_kexec_load\t347\n#define __NR_utimensat\t348\n#define __NR_signalfd\t349\n#define __NR_timerfd_create\t350\n#define __NR_eventfd\t351\n#define __NR_fallocate\t352\n#define __NR_timerfd_settime32\t353\n#define __NR_timerfd_gettime32\t354\n#define __NR_signalfd4\t355\n#define __NR_eventfd2\t356\n#define __NR_epoll_create1\t357\n#define __NR_dup3\t358\n#define __NR_pipe2\t359\n#define __NR_inotify_init1\t360\n#define __NR_preadv\t361\n#define __NR_pwritev\t362\n#define __NR_rt_tgsigqueueinfo\t363\n#define __NR_perf_event_open\t364\n#define __NR_recvmmsg\t365\n#define __NR_accept4\t366\n#define __NR_fanotify_init\t367\n#define __NR_fanotify_mark\t368\n#define __NR_prlimit64\t369\n#define __NR_name_to_handle_at\t370\n#define __NR_open_by_handle_at\t371\n#define __NR_clock_adjtime\t372\n#define __NR_syncfs\t373\n#define __NR_sendmmsg\t374\n#define __NR_setns\t375\n#define __NR_process_vm_readv\t376\n#define __NR_process_vm_writev\t377\n#define __NR_kcmp\t\t378\n#define __NR_finit_module\t379\n#define __NR_sched_setattr\t380\n#define __NR_sched_getattr\t381\n#define __NR_renameat2\t382\n#define __NR_seccomp\t383\n#define __NR_getrandom\t384\n#define __NR_memfd_create\t385\n#define __NR_bpf\t386\n#define __NR_execveat\t387\n#define __NR_userfaultfd\t388\n#define __NR_membarrier\t\t389\n#define __NR_mlock2\t\t390\n#define __NR_copy_file_range\t391\n#define __NR_preadv2\t392\n#define __NR_pwritev2\t393\n#define __NR_pkey_mprotect\t394\n#define __NR_pkey_alloc\t395\n#define __NR_pkey_free\t396\n#define __NR_statx\t397\n#define __NR_rseq\t398\n#define __NR_io_pgetevents\t399\n#define __NR_migrate_pages\t400\n#define __NR_kexec_file_load\t401\n#define __NR_clock_gettime64\t403\n#define __NR_clock_settime64\t404\n#define __NR_clock_adjtime64\t405\n#define __NR_clock_getres_time64\t406\n#define __NR_clock_nanosleep_time64\t407\n#define __NR_timer_gettime64\t408\n#define __NR_timer_settime64\t409\n#define __NR_timerfd_gettime64\t410\n#define __NR_timerfd_settime64\t411\n#define __NR_utimensat_time64\t412\n#define __NR_pselect6_time64\t413\n#define __NR_ppoll_time64\t414\n#define __NR_io_pgetevents_time64\t416\n#define __NR_recvmmsg_time64\t417\n#define __NR_mq_timedsend_time64\t418\n#define __NR_mq_timedreceive_time64\t419\n#define __NR_semtimedop_time64\t420\n#define __NR_rt_sigtimedwait_time64\t421\n#define __NR_futex_time64\t422\n#define __NR_sched_rr_get_interval_time64\t423\n#define __NR_pidfd_send_signal\t424\n#define __NR_io_uring_setup\t425\n#define __NR_io_uring_enter\t426\n#define __NR_io_uring_register\t427\n#define __NR_open_tree\t\t428\n#define __NR_move_mount\t\t429\n#define __NR_fsopen\t\t430\n#define __NR_fsconfig\t\t431\n#define __NR_fsmount\t\t432\n#define __NR_fspick\t\t433\n#define __NR_pidfd_open\t\t434\n#define __NR_clone3\t\t435\n#define __NR_close_range\t436\n#define __NR_openat2\t\t437\n#define __NR_pidfd_getfd\t438\n#define __NR_faccessat2\t\t439\n\n#define __ARM_NR_breakpoint\t0x0f0001\n#define __ARM_NR_cacheflush\t0x0f0002\n#define __ARM_NR_usr26\t\t0x0f0003\n#define __ARM_NR_usr32\t\t0x0f0004\n#define __ARM_NR_set_tls\t0x0f0005\n#define __ARM_NR_get_tls\t0x0f0006\n\n"
  },
  {
    "path": "user.libc/arch/arm/bits/user.h",
    "content": "typedef struct user_fpregs {\n\tstruct fp_reg {\n\t\tunsigned sign1:1;\n\t\tunsigned unused:15;\n\t\tunsigned sign2:1;\n\t\tunsigned exponent:14;\n\t\tunsigned j:1;\n\t\tunsigned mantissa1:31;\n\t\tunsigned mantissa0:32;\n\t} fpregs[8];\n\tunsigned fpsr:32;\n\tunsigned fpcr:32;\n\tunsigned char ftype[8];\n\tunsigned int init_flag;\n} elf_fpregset_t;\n\nstruct user_regs {\n\tunsigned long uregs[18];\n};\n#define ELF_NGREG 18\ntypedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG];\n\nstruct user {\n\tstruct user_regs regs;\n\tint u_fpvalid;\n\tunsigned long u_tsize, u_dsize, u_ssize;\n\tunsigned long start_code, start_stack;\n\tlong signal;\n\tint reserved;\n\tstruct user_regs *u_ar0;\n\tunsigned long magic;\n\tchar u_comm[32];\n\tint u_debugreg[8];\n\tstruct user_fpregs u_fp;\n\tstruct user_fpregs *u_fp0;\n};\n"
  },
  {
    "path": "user.libc/arch/arm/crt_arch.h",
    "content": "__asm__(\n\".text \\n\"\n\".global \" START \" \\n\"\n\".type \" START \",%function \\n\"\nSTART \": \\n\"\n\"\tmov fp, #0 \\n\"\n\"\tmov lr, #0 \\n\"\n\"\tldr a2, 1f \\n\"\n\"\tadd a2, pc, a2 \\n\"\n\"\tmov a1, sp \\n\"\n\"2:\tand ip, a1, #-16 \\n\"\n\"\tmov sp, ip \\n\"\n\"\tbl \" START \"_c \\n\"\n\".weak _DYNAMIC \\n\"\n\".hidden _DYNAMIC \\n\"\n\".align 2 \\n\"\n\"1:\t.word _DYNAMIC-2b \\n\"\n);\n"
  },
  {
    "path": "user.libc/arch/arm/kstat.h",
    "content": "struct kstat {\n\tdev_t st_dev;\n\tint __st_dev_padding;\n\tlong __st_ino_truncated;\n\tmode_t st_mode;\n\tnlink_t st_nlink;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tdev_t st_rdev;\n\tint __st_rdev_padding;\n\toff_t st_size;\n\tblksize_t st_blksize;\n\tblkcnt_t st_blocks;\n\tlong st_atime_sec;\n\tlong st_atime_nsec;\n\tlong st_mtime_sec;\n\tlong st_mtime_nsec;\n\tlong st_ctime_sec;\n\tlong st_ctime_nsec;\n\tino_t st_ino;\n};\n"
  },
  {
    "path": "user.libc/arch/arm/pthread_arch.h",
    "content": "#if ((__ARM_ARCH_6K__ || __ARM_ARCH_6KZ__ || __ARM_ARCH_6ZK__) && !__thumb__) \\\n || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7\n\nstatic inline uintptr_t __get_tp()\n{\n\tuintptr_t tp;\n\t__asm__ ( \"mrc p15,0,%0,c13,c0,3\" : \"=r\"(tp) );\n\treturn tp;\n}\n\n#else\n\n#if __ARM_ARCH_4__ || __ARM_ARCH_4T__ || __ARM_ARCH == 4\n#define BLX \"mov lr,pc\\n\\tbx\"\n#else\n#define BLX \"blx\"\n#endif\n\nstatic inline uintptr_t __get_tp()\n{\n\textern hidden uintptr_t __a_gettp_ptr;\n\tregister uintptr_t tp __asm__(\"r0\");\n\t__asm__ ( BLX \" %1\" : \"=r\"(tp) : \"r\"(__a_gettp_ptr) : \"cc\", \"lr\" );\n\treturn tp;\n}\n\n#endif\n\n#define TLS_ABOVE_TP\n#define GAP_ABOVE_TP 8\n\n#define MC_PC arm_pc\n"
  },
  {
    "path": "user.libc/arch/arm/reloc.h",
    "content": "#if __BYTE_ORDER == __BIG_ENDIAN\n#define ENDIAN_SUFFIX \"eb\"\n#else\n#define ENDIAN_SUFFIX \"\"\n#endif\n\n#if __ARM_PCS_VFP\n#define FP_SUFFIX \"hf\"\n#else\n#define FP_SUFFIX \"\"\n#endif\n\n#define LDSO_ARCH \"arm\" ENDIAN_SUFFIX FP_SUFFIX\n\n#define NO_LEGACY_INITFINI\n\n#define TPOFF_K 0\n\n#define REL_SYMBOLIC    R_ARM_ABS32\n#define REL_GOT         R_ARM_GLOB_DAT\n#define REL_PLT         R_ARM_JUMP_SLOT\n#define REL_RELATIVE    R_ARM_RELATIVE\n#define REL_COPY        R_ARM_COPY\n#define REL_DTPMOD      R_ARM_TLS_DTPMOD32\n#define REL_DTPOFF      R_ARM_TLS_DTPOFF32\n#define REL_TPOFF       R_ARM_TLS_TPOFF32\n#define REL_TLSDESC     R_ARM_TLS_DESC\n\n#define TLSDESC_BACKWARDS\n\n#define CRTJMP(pc,sp) __asm__ __volatile__( \\\n\t\"mov sp,%1 ; bx %0\" : : \"r\"(pc), \"r\"(sp) : \"memory\" )\n"
  },
  {
    "path": "user.libc/arch/arm/syscall_arch.h",
    "content": "#define __SYSCALL_LL_E(x) \\\n((union { long long ll; long l[2]; }){ .ll = x }).l[0], \\\n((union { long long ll; long l[2]; }){ .ll = x }).l[1]\n#define __SYSCALL_LL_O(x) 0, __SYSCALL_LL_E((x))\n\n#ifdef __thumb__\n\n/* Avoid use of r7 in asm constraints when producing thumb code,\n * since it's reserved as frame pointer and might not be supported. */\n#define __ASM____R7__\n#define __asm_syscall(...) do { \\\n\t__asm__ __volatile__ ( \"mov %1,r7 ; mov r7,%2 ; svc 0 ; mov r7,%1\" \\\n\t: \"=r\"(r0), \"=&r\"((int){0}) : __VA_ARGS__ : \"memory\"); \\\n\treturn r0; \\\n\t} while (0)\n\n#else\n\n#define __ASM____R7__ __asm__(\"r7\")\n#define __asm_syscall(...) do { \\\n\t__asm__ __volatile__ ( \"svc 0\" \\\n\t: \"=r\"(r0) : __VA_ARGS__ : \"memory\"); \\\n\treturn r0; \\\n\t} while (0)\n#endif\n\n/* For thumb2, we can allow 8-bit immediate syscall numbers, saving a\n * register in the above dance around r7. Does not work for thumb1 where\n * only movs, not mov, supports immediates, and we can't use movs because\n * it doesn't support high regs. */\n#ifdef __thumb2__\n#define R7_OPERAND \"rI\"(r7)\n#else\n#define R7_OPERAND \"r\"(r7)\n#endif\n\nstatic inline long __syscall0(long n)\n{\n\tregister long r7 __ASM____R7__ = n;\n\tregister long r0 __asm__(\"r0\");\n\t__asm_syscall(R7_OPERAND);\n}\n\nstatic inline long __syscall1(long n, long a)\n{\n\tregister long r7 __ASM____R7__ = n;\n\tregister long r0 __asm__(\"r0\") = a;\n\t__asm_syscall(R7_OPERAND, \"0\"(r0));\n}\n\nstatic inline long __syscall2(long n, long a, long b)\n{\n\tregister long r7 __ASM____R7__ = n;\n\tregister long r0 __asm__(\"r0\") = a;\n\tregister long r1 __asm__(\"r1\") = b;\n\t__asm_syscall(R7_OPERAND, \"0\"(r0), \"r\"(r1));\n}\n\nstatic inline long __syscall3(long n, long a, long b, long c)\n{\n\tregister long r7 __ASM____R7__ = n;\n\tregister long r0 __asm__(\"r0\") = a;\n\tregister long r1 __asm__(\"r1\") = b;\n\tregister long r2 __asm__(\"r2\") = c;\n\t__asm_syscall(R7_OPERAND, \"0\"(r0), \"r\"(r1), \"r\"(r2));\n}\n\nstatic inline long __syscall4(long n, long a, long b, long c, long d)\n{\n\tregister long r7 __ASM____R7__ = n;\n\tregister long r0 __asm__(\"r0\") = a;\n\tregister long r1 __asm__(\"r1\") = b;\n\tregister long r2 __asm__(\"r2\") = c;\n\tregister long r3 __asm__(\"r3\") = d;\n\t__asm_syscall(R7_OPERAND, \"0\"(r0), \"r\"(r1), \"r\"(r2), \"r\"(r3));\n}\n\nstatic inline long __syscall5(long n, long a, long b, long c, long d, long e)\n{\n\tregister long r7 __ASM____R7__ = n;\n\tregister long r0 __asm__(\"r0\") = a;\n\tregister long r1 __asm__(\"r1\") = b;\n\tregister long r2 __asm__(\"r2\") = c;\n\tregister long r3 __asm__(\"r3\") = d;\n\tregister long r4 __asm__(\"r4\") = e;\n\t__asm_syscall(R7_OPERAND, \"0\"(r0), \"r\"(r1), \"r\"(r2), \"r\"(r3), \"r\"(r4));\n}\n\nstatic inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)\n{\n\tregister long r7 __ASM____R7__ = n;\n\tregister long r0 __asm__(\"r0\") = a;\n\tregister long r1 __asm__(\"r1\") = b;\n\tregister long r2 __asm__(\"r2\") = c;\n\tregister long r3 __asm__(\"r3\") = d;\n\tregister long r4 __asm__(\"r4\") = e;\n\tregister long r5 __asm__(\"r5\") = f;\n\t__asm_syscall(R7_OPERAND, \"0\"(r0), \"r\"(r1), \"r\"(r2), \"r\"(r3), \"r\"(r4), \"r\"(r5));\n}\n\n#define SYSCALL_FADVISE_6_ARG\n\n#define SYSCALL_IPC_BROKEN_MODE\n"
  },
  {
    "path": "user.libc/arch/generic/bits/dirent.h",
    "content": "#define _DIRENT_HAVE_D_RECLEN\n#define _DIRENT_HAVE_D_OFF\n#define _DIRENT_HAVE_D_TYPE\n\nstruct dirent {\n\tino_t d_ino;\n\toff_t d_off;\n\tunsigned short d_reclen;\n\tunsigned char d_type;\n\tchar d_name[256];\n};\n"
  },
  {
    "path": "user.libc/arch/generic/bits/errno.h",
    "content": "#define EPERM            1\n#define ENOENT           2\n#define ESRCH            3\n#define EINTR            4\n#define EIO              5\n#define ENXIO            6\n#define E2BIG            7\n#define ENOEXEC          8\n#define EBADF            9\n#define ECHILD          10\n#define EAGAIN          11\n#define ENOMEM          12\n#define EACCES          13\n#define EFAULT          14\n#define ENOTBLK         15\n#define EBUSY           16\n#define EEXIST          17\n#define EXDEV           18\n#define ENODEV          19\n#define ENOTDIR         20\n#define EISDIR          21\n#define EINVAL          22\n#define ENFILE          23\n#define EMFILE          24\n#define ENOTTY          25\n#define ETXTBSY         26\n#define EFBIG           27\n#define ENOSPC          28\n#define ESPIPE          29\n#define EROFS           30\n#define EMLINK          31\n#define EPIPE           32\n#define EDOM            33\n#define ERANGE          34\n#define EDEADLK         35\n#define ENAMETOOLONG    36\n#define ENOLCK          37\n#define ENOSYS          38\n#define ENOTEMPTY       39\n#define ELOOP           40\n#define EWOULDBLOCK     EAGAIN\n#define ENOMSG          42\n#define EIDRM           43\n#define ECHRNG          44\n#define EL2NSYNC        45\n#define EL3HLT          46\n#define EL3RST          47\n#define ELNRNG          48\n#define EUNATCH         49\n#define ENOCSI          50\n#define EL2HLT          51\n#define EBADE           52\n#define EBADR           53\n#define EXFULL          54\n#define ENOANO          55\n#define EBADRQC         56\n#define EBADSLT         57\n#define EDEADLOCK       EDEADLK\n#define EBFONT          59\n#define ENOSTR          60\n#define ENODATA         61\n#define ETIME           62\n#define ENOSR           63\n#define ENONET          64\n#define ENOPKG          65\n#define EREMOTE         66\n#define ENOLINK         67\n#define EADV            68\n#define ESRMNT          69\n#define ECOMM           70\n#define EPROTO          71\n#define EMULTIHOP       72\n#define EDOTDOT         73\n#define EBADMSG         74\n#define EOVERFLOW       75\n#define ENOTUNIQ        76\n#define EBADFD          77\n#define EREMCHG         78\n#define ELIBACC         79\n#define ELIBBAD         80\n#define ELIBSCN         81\n#define ELIBMAX         82\n#define ELIBEXEC        83\n#define EILSEQ          84\n#define ERESTART        85\n#define ESTRPIPE        86\n#define EUSERS          87\n#define ENOTSOCK        88\n#define EDESTADDRREQ    89\n#define EMSGSIZE        90\n#define EPROTOTYPE      91\n#define ENOPROTOOPT     92\n#define EPROTONOSUPPORT 93\n#define ESOCKTNOSUPPORT 94\n#define EOPNOTSUPP      95\n#define ENOTSUP         EOPNOTSUPP\n#define EPFNOSUPPORT    96\n#define EAFNOSUPPORT    97\n#define EADDRINUSE      98\n#define EADDRNOTAVAIL   99\n#define ENETDOWN        100\n#define ENETUNREACH     101\n#define ENETRESET       102\n#define ECONNABORTED    103\n#define ECONNRESET      104\n#define ENOBUFS         105\n#define EISCONN         106\n#define ENOTCONN        107\n#define ESHUTDOWN       108\n#define ETOOMANYREFS    109\n#define ETIMEDOUT       110\n#define ECONNREFUSED    111\n#define EHOSTDOWN       112\n#define EHOSTUNREACH    113\n#define EALREADY        114\n#define EINPROGRESS     115\n#define ESTALE          116\n#define EUCLEAN         117\n#define ENOTNAM         118\n#define ENAVAIL         119\n#define EISNAM          120\n#define EREMOTEIO       121\n#define EDQUOT          122\n#define ENOMEDIUM       123\n#define EMEDIUMTYPE     124\n#define ECANCELED       125\n#define ENOKEY          126\n#define EKEYEXPIRED     127\n#define EKEYREVOKED     128\n#define EKEYREJECTED    129\n#define EOWNERDEAD      130\n#define ENOTRECOVERABLE 131\n#define ERFKILL         132\n#define EHWPOISON       133\n\n#define EABORT\t\t134\n#define EOTHERSIDECLOSED 135\t/* the otherside of this kobject is closed */\n"
  },
  {
    "path": "user.libc/arch/generic/bits/fcntl.h",
    "content": "#define O_CREAT        0100\n#define O_EXCL         0200\n#define O_NOCTTY       0400\n#define O_TRUNC       01000\n#define O_APPEND      02000\n#define O_NONBLOCK    04000\n#define O_DSYNC      010000\n#define O_SYNC     04010000\n#define O_RSYNC    04010000\n#define O_DIRECTORY 0200000\n#define O_NOFOLLOW  0400000\n#define O_CLOEXEC  02000000\n\n#define O_ASYNC      020000\n#define O_DIRECT     040000\n#define O_LARGEFILE 0100000\n#define O_NOATIME  01000000\n#define O_PATH    010000000\n#define O_TMPFILE 020200000\n#define O_NDELAY O_NONBLOCK\n\n#define F_DUPFD  0\n#define F_GETFD  1\n#define F_SETFD  2\n#define F_GETFL  3\n#define F_SETFL  4\n\n#define F_SETOWN 8\n#define F_GETOWN 9\n#define F_SETSIG 10\n#define F_GETSIG 11\n\n#if __LONG_MAX == 0x7fffffffL\n#define F_GETLK 12\n#define F_SETLK 13\n#define F_SETLKW 14\n#else\n#define F_GETLK 5\n#define F_SETLK 6\n#define F_SETLKW 7\n#endif\n\n#define F_SETOWN_EX 15\n#define F_GETOWN_EX 16\n\n#define F_GETOWNER_UIDS 17\n"
  },
  {
    "path": "user.libc/arch/generic/bits/fenv.h",
    "content": "#define FE_ALL_EXCEPT 0\n#define FE_TONEAREST  0\n\ntypedef unsigned long fexcept_t;\n\ntypedef struct {\n\tunsigned long __cw;\n} fenv_t;\n\n#define FE_DFL_ENV      ((const fenv_t *) -1)\n"
  },
  {
    "path": "user.libc/arch/generic/bits/hwcap.h",
    "content": ""
  },
  {
    "path": "user.libc/arch/generic/bits/io.h",
    "content": ""
  },
  {
    "path": "user.libc/arch/generic/bits/ioctl.h",
    "content": "#define _IOC(a,b,c,d) ( ((a)<<30) | ((b)<<8) | (c) | ((d)<<16) )\n#define _IOC_NONE  0U\n#define _IOC_WRITE 1U\n#define _IOC_READ  2U\n\n#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)\n#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c))\n#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c))\n#define _IOWR(a,b,c) _IOC(_IOC_READ|_IOC_WRITE,(a),(b),sizeof(c))\n\n#define TCGETS\t\t0x5401\n#define TCSETS\t\t0x5402\n#define TCSETSW\t\t0x5403\n#define TCSETSF\t\t0x5404\n#define TCGETA\t\t0x5405\n#define TCSETA\t\t0x5406\n#define TCSETAW\t\t0x5407\n#define TCSETAF\t\t0x5408\n#define TCSBRK\t\t0x5409\n#define TCXONC\t\t0x540A\n#define TCFLSH\t\t0x540B\n#define TIOCEXCL\t0x540C\n#define TIOCNXCL\t0x540D\n#define TIOCSCTTY\t0x540E\n#define TIOCGPGRP\t0x540F\n#define TIOCSPGRP\t0x5410\n#define TIOCOUTQ\t0x5411\n#define TIOCSTI\t\t0x5412\n#define TIOCGWINSZ\t0x5413\n#define TIOCSWINSZ\t0x5414\n#define TIOCMGET\t0x5415\n#define TIOCMBIS\t0x5416\n#define TIOCMBIC\t0x5417\n#define TIOCMSET\t0x5418\n#define TIOCGSOFTCAR\t0x5419\n#define TIOCSSOFTCAR\t0x541A\n#define FIONREAD\t0x541B\n#define TIOCINQ\t\tFIONREAD\n#define TIOCLINUX\t0x541C\n#define TIOCCONS\t0x541D\n#define TIOCGSERIAL\t0x541E\n#define TIOCSSERIAL\t0x541F\n#define TIOCPKT\t\t0x5420\n#define FIONBIO\t\t0x5421\n#define TIOCNOTTY\t0x5422\n#define TIOCSETD\t0x5423\n#define TIOCGETD\t0x5424\n#define TCSBRKP\t\t0x5425\n#define TIOCSBRK\t0x5427\n#define TIOCCBRK\t0x5428\n#define TIOCGSID\t0x5429\n#define TIOCGRS485\t0x542E\n#define TIOCSRS485\t0x542F\n#define TIOCGPTN\t0x80045430\n#define TIOCSPTLCK\t0x40045431\n#define TIOCGDEV\t0x80045432\n#define TCGETX\t\t0x5432\n#define TCSETX\t\t0x5433\n#define TCSETXF\t\t0x5434\n#define TCSETXW\t\t0x5435\n#define TIOCSIG\t\t0x40045436\n#define TIOCVHANGUP\t0x5437\n#define TIOCGPKT\t0x80045438\n#define TIOCGPTLCK\t0x80045439\n#define TIOCGEXCL\t0x80045440\n#define TIOCGPTPEER\t0x5441\n#define TIOCGISO7816\t0x80285442\n#define TIOCSISO7816\t0xc0285443\n\n#define FIONCLEX\t0x5450\n#define FIOCLEX\t\t0x5451\n#define FIOASYNC\t0x5452\n#define TIOCSERCONFIG\t0x5453\n#define TIOCSERGWILD\t0x5454\n#define TIOCSERSWILD\t0x5455\n#define TIOCGLCKTRMIOS\t0x5456\n#define TIOCSLCKTRMIOS\t0x5457\n#define TIOCSERGSTRUCT\t0x5458\n#define TIOCSERGETLSR   0x5459\n#define TIOCSERGETMULTI 0x545A\n#define TIOCSERSETMULTI 0x545B\n\n#define TIOCMIWAIT\t0x545C\n#define TIOCGICOUNT\t0x545D\n#define FIOQSIZE\t0x5460\n\n#define TIOCM_LE        0x001\n#define TIOCM_DTR       0x002\n#define TIOCM_RTS       0x004\n#define TIOCM_ST        0x008\n#define TIOCM_SR        0x010\n#define TIOCM_CTS       0x020\n#define TIOCM_CAR       0x040\n#define TIOCM_RNG       0x080\n#define TIOCM_DSR       0x100\n#define TIOCM_CD        TIOCM_CAR\n#define TIOCM_RI        TIOCM_RNG\n#define TIOCM_OUT1      0x2000\n#define TIOCM_OUT2      0x4000\n#define TIOCM_LOOP      0x8000\n\n#define FIOSETOWN       0x8901\n#define SIOCSPGRP       0x8902\n#define FIOGETOWN       0x8903\n#define SIOCGPGRP       0x8904\n#define SIOCATMARK      0x8905\n#if __LONG_MAX == 0x7fffffff\n#define SIOCGSTAMP      _IOR(0x89, 6, char[16])\n#define SIOCGSTAMPNS    _IOR(0x89, 7, char[16])\n#else\n#define SIOCGSTAMP      0x8906\n#define SIOCGSTAMPNS    0x8907\n#endif\n\n#include <bits/ioctl_fix.h>\n"
  },
  {
    "path": "user.libc/arch/generic/bits/ioctl_fix.h",
    "content": ""
  },
  {
    "path": "user.libc/arch/generic/bits/ipc.h",
    "content": "struct ipc_perm {\n\tkey_t __ipc_perm_key;\n\tuid_t uid;\n\tgid_t gid;\n\tuid_t cuid;\n\tgid_t cgid;\n\tmode_t mode;\n\tint __ipc_perm_seq;\n\tlong __pad1;\n\tlong __pad2;\n};\n"
  },
  {
    "path": "user.libc/arch/generic/bits/ipcstat.h",
    "content": "#define IPC_STAT 2\n"
  },
  {
    "path": "user.libc/arch/generic/bits/kd.h",
    "content": "#include <linux/kd.h>\n"
  },
  {
    "path": "user.libc/arch/generic/bits/limits.h",
    "content": ""
  },
  {
    "path": "user.libc/arch/generic/bits/link.h",
    "content": "typedef uint32_t Elf_Symndx;\n"
  },
  {
    "path": "user.libc/arch/generic/bits/mman.h",
    "content": ""
  },
  {
    "path": "user.libc/arch/generic/bits/msg.h",
    "content": "struct msqid_ds {\n\tstruct ipc_perm msg_perm;\n\ttime_t msg_stime;\n\ttime_t msg_rtime;\n\ttime_t msg_ctime;\n\tunsigned long msg_cbytes;\n\tmsgqnum_t msg_qnum;\n\tmsglen_t msg_qbytes;\n\tpid_t msg_lspid;\n\tpid_t msg_lrpid;\n\tunsigned long __unused[2];\n};\n"
  },
  {
    "path": "user.libc/arch/generic/bits/poll.h",
    "content": ""
  },
  {
    "path": "user.libc/arch/generic/bits/ptrace.h",
    "content": ""
  },
  {
    "path": "user.libc/arch/generic/bits/resource.h",
    "content": ""
  },
  {
    "path": "user.libc/arch/generic/bits/sem.h",
    "content": "struct semid_ds {\n\tstruct ipc_perm sem_perm;\n\ttime_t sem_otime;\n\ttime_t sem_ctime;\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n\tunsigned short sem_nsems;\n\tchar __sem_nsems_pad[sizeof(long)-sizeof(short)];\n#else\n\tchar __sem_nsems_pad[sizeof(long)-sizeof(short)];\n\tunsigned short sem_nsems;\n#endif\n\tlong __unused3;\n\tlong __unused4;\n};\n"
  },
  {
    "path": "user.libc/arch/generic/bits/shm.h",
    "content": "#define SHMLBA 4096\n\nstruct shmid_ds {\n\tstruct ipc_perm shm_perm;\n\tsize_t shm_segsz;\n\ttime_t shm_atime;\n\ttime_t shm_dtime;\n\ttime_t shm_ctime;\n\tpid_t shm_cpid;\n\tpid_t shm_lpid;\n\tunsigned long shm_nattch;\n\tunsigned long __pad1;\n\tunsigned long __pad2;\n};\n\nstruct shminfo {\n\tunsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];\n};\n\nstruct shm_info {\n\tint __used_ids;\n\tunsigned long shm_tot, shm_rss, shm_swp;\n\tunsigned long __swap_attempts, __swap_successes;\n};\n"
  },
  {
    "path": "user.libc/arch/generic/bits/socket.h",
    "content": ""
  },
  {
    "path": "user.libc/arch/generic/bits/soundcard.h",
    "content": "#include <linux/soundcard.h>\n"
  },
  {
    "path": "user.libc/arch/generic/bits/statfs.h",
    "content": "struct statfs {\n\tunsigned long f_type, f_bsize;\n\tfsblkcnt_t f_blocks, f_bfree, f_bavail;\n\tfsfilcnt_t f_files, f_ffree;\n\tfsid_t f_fsid;\n\tunsigned long f_namelen, f_frsize, f_flags, f_spare[4];\n};\n"
  },
  {
    "path": "user.libc/arch/generic/bits/termios.h",
    "content": "struct termios {\n\ttcflag_t c_iflag;\n\ttcflag_t c_oflag;\n\ttcflag_t c_cflag;\n\ttcflag_t c_lflag;\n\tcc_t c_line;\n\tcc_t c_cc[NCCS];\n\tspeed_t __c_ispeed;\n\tspeed_t __c_ospeed;\n};\n\n#define VINTR     0\n#define VQUIT     1\n#define VERASE    2\n#define VKILL     3\n#define VEOF      4\n#define VTIME     5\n#define VMIN      6\n#define VSWTC     7\n#define VSTART    8\n#define VSTOP     9\n#define VSUSP    10\n#define VEOL     11\n#define VREPRINT 12\n#define VDISCARD 13\n#define VWERASE  14\n#define VLNEXT   15\n#define VEOL2    16\n\n#define IGNBRK  0000001\n#define BRKINT  0000002\n#define IGNPAR  0000004\n#define PARMRK  0000010\n#define INPCK   0000020\n#define ISTRIP  0000040\n#define INLCR   0000100\n#define IGNCR   0000200\n#define ICRNL   0000400\n#define IUCLC   0001000\n#define IXON    0002000\n#define IXANY   0004000\n#define IXOFF   0010000\n#define IMAXBEL 0020000\n#define IUTF8   0040000\n\n#define OPOST  0000001\n#define OLCUC  0000002\n#define ONLCR  0000004\n#define OCRNL  0000010\n#define ONOCR  0000020\n#define ONLRET 0000040\n#define OFILL  0000100\n#define OFDEL  0000200\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_XOPEN_SOURCE)\n#define NLDLY  0000400\n#define NL0    0000000\n#define NL1    0000400\n#define CRDLY  0003000\n#define CR0    0000000\n#define CR1    0001000\n#define CR2    0002000\n#define CR3    0003000\n#define TABDLY 0014000\n#define TAB0   0000000\n#define TAB1   0004000\n#define TAB2   0010000\n#define TAB3   0014000\n#define BSDLY  0020000\n#define BS0    0000000\n#define BS1    0020000\n#define FFDLY  0100000\n#define FF0    0000000\n#define FF1    0100000\n#endif\n\n#define VTDLY  0040000\n#define VT0    0000000\n#define VT1    0040000\n\n#define B0       0000000\n#define B50      0000001\n#define B75      0000002\n#define B110     0000003\n#define B134     0000004\n#define B150     0000005\n#define B200     0000006\n#define B300     0000007\n#define B600     0000010\n#define B1200    0000011\n#define B1800    0000012\n#define B2400    0000013\n#define B4800    0000014\n#define B9600    0000015\n#define B19200   0000016\n#define B38400   0000017\n\n#define B57600   0010001\n#define B115200  0010002\n#define B230400  0010003\n#define B460800  0010004\n#define B500000  0010005\n#define B576000  0010006\n#define B921600  0010007\n#define B1000000 0010010\n#define B1152000 0010011\n#define B1500000 0010012\n#define B2000000 0010013\n#define B2500000 0010014\n#define B3000000 0010015\n#define B3500000 0010016\n#define B4000000 0010017\n\n#define CSIZE  0000060\n#define CS5    0000000\n#define CS6    0000020\n#define CS7    0000040\n#define CS8    0000060\n#define CSTOPB 0000100\n#define CREAD  0000200\n#define PARENB 0000400\n#define PARODD 0001000\n#define HUPCL  0002000\n#define CLOCAL 0004000\n\n#define ISIG   0000001\n#define ICANON 0000002\n#define ECHO   0000010\n#define ECHOE  0000020\n#define ECHOK  0000040\n#define ECHONL 0000100\n#define NOFLSH 0000200\n#define TOSTOP 0000400\n#define IEXTEN 0100000\n\n#define TCOOFF 0\n#define TCOON  1\n#define TCIOFF 2\n#define TCION  3\n\n#define TCIFLUSH  0\n#define TCOFLUSH  1\n#define TCIOFLUSH 2\n\n#define TCSANOW   0\n#define TCSADRAIN 1\n#define TCSAFLUSH 2\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define EXTA    0000016\n#define EXTB    0000017\n#define CBAUD   0010017\n#define CBAUDEX 0010000\n#define CIBAUD  002003600000\n#define CMSPAR  010000000000\n#define CRTSCTS 020000000000\n\n#define XCASE   0000004\n#define ECHOCTL 0001000\n#define ECHOPRT 0002000\n#define ECHOKE  0004000\n#define FLUSHO  0010000\n#define PENDIN  0040000\n#define EXTPROC 0200000\n\n#define XTABS  0014000\n#endif\n"
  },
  {
    "path": "user.libc/arch/generic/bits/vt.h",
    "content": "#include <linux/vt.h>\n"
  },
  {
    "path": "user.libc/arch/generic/fp_arch.h",
    "content": ""
  },
  {
    "path": "user.libc/arch/i386/arch.mak",
    "content": "COMPAT_SRC_DIRS = compat/time32\n"
  },
  {
    "path": "user.libc/arch/i386/atomic_arch.h",
    "content": "#define a_cas a_cas\nstatic inline int a_cas(volatile int *p, int t, int s)\n{\n\t__asm__ __volatile__ (\n\t\t\"lock ; cmpxchg %3, %1\"\n\t\t: \"=a\"(t), \"=m\"(*p) : \"a\"(t), \"r\"(s) : \"memory\" );\n\treturn t;\n}\n\n#define a_swap a_swap\nstatic inline int a_swap(volatile int *p, int v)\n{\n\t__asm__ __volatile__(\n\t\t\"xchg %0, %1\"\n\t\t: \"=r\"(v), \"=m\"(*p) : \"0\"(v) : \"memory\" );\n\treturn v;\n}\n\n#define a_fetch_add a_fetch_add\nstatic inline int a_fetch_add(volatile int *p, int v)\n{\n\t__asm__ __volatile__(\n\t\t\"lock ; xadd %0, %1\"\n\t\t: \"=r\"(v), \"=m\"(*p) : \"0\"(v) : \"memory\" );\n\treturn v;\n}\n\n#define a_and a_and\nstatic inline void a_and(volatile int *p, int v)\n{\n\t__asm__ __volatile__(\n\t\t\"lock ; and %1, %0\"\n\t\t: \"=m\"(*p) : \"r\"(v) : \"memory\" );\n}\n\n#define a_or a_or\nstatic inline void a_or(volatile int *p, int v)\n{\n\t__asm__ __volatile__(\n\t\t\"lock ; or %1, %0\"\n\t\t: \"=m\"(*p) : \"r\"(v) : \"memory\" );\n}\n\n#define a_inc a_inc\nstatic inline void a_inc(volatile int *p)\n{\n\t__asm__ __volatile__(\n\t\t\"lock ; incl %0\"\n\t\t: \"=m\"(*p) : \"m\"(*p) : \"memory\" );\n}\n\n#define a_dec a_dec\nstatic inline void a_dec(volatile int *p)\n{\n\t__asm__ __volatile__(\n\t\t\"lock ; decl %0\"\n\t\t: \"=m\"(*p) : \"m\"(*p) : \"memory\" );\n}\n\n#define a_store a_store\nstatic inline void a_store(volatile int *p, int x)\n{\n\t__asm__ __volatile__(\n\t\t\"mov %1, %0 ; lock ; orl $0,(%%esp)\"\n\t\t: \"=m\"(*p) : \"r\"(x) : \"memory\" );\n}\n\n#define a_barrier a_barrier\nstatic inline void a_barrier()\n{\n\t__asm__ __volatile__( \"\" : : : \"memory\" );\n}\n\n#define a_spin a_spin\nstatic inline void a_spin()\n{\n\t__asm__ __volatile__( \"pause\" : : : \"memory\" );\n}\n\n#define a_crash a_crash\nstatic inline void a_crash()\n{\n\t__asm__ __volatile__( \"hlt\" : : : \"memory\" );\n}\n\n#define a_ctz_64 a_ctz_64\nstatic inline int a_ctz_64(uint64_t x)\n{\n\tint r;\n\t__asm__( \"bsf %1,%0 ; jnz 1f ; bsf %2,%0 ; add $32,%0\\n1:\"\n\t\t: \"=&r\"(r) : \"r\"((unsigned)x), \"r\"((unsigned)(x>>32)) );\n\treturn r;\n}\n\n#define a_ctz_32 a_ctz_32\nstatic inline int a_ctz_32(uint32_t x)\n{\n\tint r;\n\t__asm__( \"bsf %1,%0\" : \"=r\"(r) : \"r\"(x) );\n\treturn r;\n}\n\n#define a_clz_32 a_clz_32\nstatic inline int a_clz_32(uint32_t x)\n{\n\t__asm__( \"bsr %1,%0 ; xor $31,%0\" : \"=r\"(x) : \"r\"(x) );\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/arch/i386/bits/alltypes.h.in",
    "content": "#define _REDIR_TIME64 1\n#define _Addr int\n#define _Int64 long long\n#define _Reg int\n\n#define __BYTE_ORDER 1234\n#define __LONG_MAX 0x7fffffffL\n\n#ifndef __cplusplus\n#ifdef __WCHAR_TYPE__\nTYPEDEF __WCHAR_TYPE__ wchar_t;\n#else\nTYPEDEF long wchar_t;\n#endif\n#endif\n\n#if defined(__FLT_EVAL_METHOD__) && __FLT_EVAL_METHOD__ == 0\nTYPEDEF float float_t;\nTYPEDEF double double_t;\n#else\nTYPEDEF long double float_t;\nTYPEDEF long double double_t;\n#endif\n\n#if !defined(__cplusplus)\nTYPEDEF struct { _Alignas(8) long long __ll; long double __ld; } max_align_t;\n#elif defined(__GNUC__)\nTYPEDEF struct { __attribute__((__aligned__(8))) long long __ll; long double __ld; } max_align_t;\n#else\nTYPEDEF struct { alignas(8) long long __ll; long double __ld; } max_align_t;\n#endif\n"
  },
  {
    "path": "user.libc/arch/i386/bits/fenv.h",
    "content": "#define FE_INVALID    1\n#define __FE_DENORM   2\n#define FE_DIVBYZERO  4\n#define FE_OVERFLOW   8\n#define FE_UNDERFLOW  16\n#define FE_INEXACT    32\n\n#define FE_ALL_EXCEPT 63\n\n#define FE_TONEAREST  0\n#define FE_DOWNWARD   0x400\n#define FE_UPWARD     0x800\n#define FE_TOWARDZERO 0xc00\n\ntypedef unsigned short fexcept_t;\n\ntypedef struct {\n\tunsigned short __control_word;\n\tunsigned short __unused1;\n\tunsigned short __status_word;\n\tunsigned short __unused2;\n\tunsigned short __tags;\n\tunsigned short __unused3;\n\tunsigned int __eip;\n\tunsigned short __cs_selector;\n\tunsigned int __opcode:11;\n\tunsigned int __unused4:5;\n\tunsigned int __data_offset;\n\tunsigned short __data_selector;\n\tunsigned short __unused5;\n} fenv_t;\n\n#define FE_DFL_ENV      ((const fenv_t *) -1)\n"
  },
  {
    "path": "user.libc/arch/i386/bits/float.h",
    "content": "#ifdef __FLT_EVAL_METHOD__\n#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__\n#else\n#define FLT_EVAL_METHOD 2\n#endif\n\n#define LDBL_TRUE_MIN 3.6451995318824746025e-4951L\n#define LDBL_MIN     3.3621031431120935063e-4932L\n#define LDBL_MAX     1.1897314953572317650e+4932L\n#define LDBL_EPSILON 1.0842021724855044340e-19L\n\n#define LDBL_MANT_DIG 64\n#define LDBL_MIN_EXP (-16381)\n#define LDBL_MAX_EXP 16384\n\n#define LDBL_DIG 18\n#define LDBL_MIN_10_EXP (-4931)\n#define LDBL_MAX_10_EXP 4932\n\n#define DECIMAL_DIG 21\n"
  },
  {
    "path": "user.libc/arch/i386/bits/io.h",
    "content": "static __inline void outb(unsigned char __val, unsigned short __port)\n{\n\t__asm__ volatile (\"outb %0,%1\" : : \"a\" (__val), \"dN\" (__port));\n}\n\nstatic __inline void outw(unsigned short __val, unsigned short __port)\n{\n\t__asm__ volatile (\"outw %0,%1\" : : \"a\" (__val), \"dN\" (__port));\n}\n\nstatic __inline void outl(unsigned int __val, unsigned short __port)\n{\n\t__asm__ volatile (\"outl %0,%1\" : : \"a\" (__val), \"dN\" (__port));\n}\n\nstatic __inline unsigned char inb(unsigned short __port)\n{\n\tunsigned char __val;\n\t__asm__ volatile (\"inb %1,%0\" : \"=a\" (__val) : \"dN\" (__port));\n\treturn __val;\n}\n\nstatic __inline unsigned short inw(unsigned short __port)\n{\n\tunsigned short __val;\n\t__asm__ volatile (\"inw %1,%0\" : \"=a\" (__val) : \"dN\" (__port));\n\treturn __val;\n}\n\nstatic __inline unsigned int inl(unsigned short __port)\n{\n\tunsigned int __val;\n\t__asm__ volatile (\"inl %1,%0\" : \"=a\" (__val) : \"dN\" (__port));\n\treturn __val;\n}\n\nstatic __inline void outsb(unsigned short __port, const void *__buf, unsigned long __n)\n{\n\t__asm__ volatile (\"cld; rep; outsb\"\n\t\t      : \"+S\" (__buf), \"+c\" (__n)\n\t\t      : \"d\" (__port));\n}\n\nstatic __inline void outsw(unsigned short __port, const void *__buf, unsigned long __n)\n{\n\t__asm__ volatile (\"cld; rep; outsw\"\n\t\t      : \"+S\" (__buf), \"+c\" (__n)\n\t\t      : \"d\" (__port));\n}\n\nstatic __inline void outsl(unsigned short __port, const void *__buf, unsigned long __n)\n{\n\t__asm__ volatile (\"cld; rep; outsl\"\n\t\t      : \"+S\" (__buf), \"+c\"(__n)\n\t\t      : \"d\" (__port));\n}\n\nstatic __inline void insb(unsigned short __port, void *__buf, unsigned long __n)\n{\n\t__asm__ volatile (\"cld; rep; insb\"\n\t\t      : \"+D\" (__buf), \"+c\" (__n)\n\t\t      : \"d\" (__port));\n}\n\nstatic __inline void insw(unsigned short __port, void *__buf, unsigned long __n)\n{\n\t__asm__ volatile (\"cld; rep; insw\"\n\t\t      : \"+D\" (__buf), \"+c\" (__n)\n\t\t      : \"d\" (__port));\n}\n\nstatic __inline void insl(unsigned short __port, void *__buf, unsigned long __n)\n{\n\t__asm__ volatile (\"cld; rep; insl\"\n\t\t      : \"+D\" (__buf), \"+c\" (__n)\n\t\t      : \"d\" (__port));\n}\n"
  },
  {
    "path": "user.libc/arch/i386/bits/ipcstat.h",
    "content": "#define IPC_STAT 0x102\n"
  },
  {
    "path": "user.libc/arch/i386/bits/limits.h",
    "content": "#define PAGESIZE 4096\n"
  },
  {
    "path": "user.libc/arch/i386/bits/mman.h",
    "content": "#define MAP_32BIT      0x40\n"
  },
  {
    "path": "user.libc/arch/i386/bits/msg.h",
    "content": "struct msqid_ds {\n\tstruct ipc_perm msg_perm;\n\tunsigned long __msg_stime_lo;\n\tunsigned long __msg_stime_hi;\n\tunsigned long __msg_rtime_lo;\n\tunsigned long __msg_rtime_hi;\n\tunsigned long __msg_ctime_lo;\n\tunsigned long __msg_ctime_hi;\n\tunsigned long msg_cbytes;\n\tmsgqnum_t msg_qnum;\n\tmsglen_t msg_qbytes;\n\tpid_t msg_lspid;\n\tpid_t msg_lrpid;\n\tunsigned long __unused[2];\n\ttime_t msg_stime;\n\ttime_t msg_rtime;\n\ttime_t msg_ctime;\n};\n"
  },
  {
    "path": "user.libc/arch/i386/bits/posix.h",
    "content": "#define _POSIX_V6_ILP32_OFFBIG  1\n#define _POSIX_V7_ILP32_OFFBIG  1\n"
  },
  {
    "path": "user.libc/arch/i386/bits/ptrace.h",
    "content": "#define PTRACE_GET_THREAD_AREA\t\t25\n#define PTRACE_SET_THREAD_AREA\t\t26\n#define PTRACE_SYSEMU\t\t\t31\n#define PTRACE_SYSEMU_SINGLESTEP\t32\n#define PTRACE_SINGLEBLOCK\t\t33\n\n#define PT_GET_THREAD_AREA PTRACE_GET_THREAD_AREA\n#define PT_SET_THREAD_AREA PTRACE_SET_THREAD_AREA\n#define PT_SYSEMU PTRACE_SYSEMU\n#define PT_SYSEMU_SINGLESTEP PTRACE_SYSEMU_SINGLESTEP\n#define PT_STEPBLOCK PTRACE_SINGLEBLOCK\n"
  },
  {
    "path": "user.libc/arch/i386/bits/reg.h",
    "content": "#undef __WORDSIZE\n#define __WORDSIZE 32\n#define EBX 0\n#define ECX 1\n#define EDX 2\n#define ESI 3\n#define EDI 4\n#define EBP 5\n#define EAX 6\n#define DS 7\n#define ES 8\n#define FS 9\n#define GS 10\n#define ORIG_EAX 11\n#define EIP 12\n#define CS 13\n#define EFL 14\n#define UESP 15\n#define SS 16\n"
  },
  {
    "path": "user.libc/arch/i386/bits/sem.h",
    "content": "struct semid_ds {\n\tstruct ipc_perm sem_perm;\n\tunsigned long __sem_otime_lo;\n\tunsigned long __sem_otime_hi;\n\tunsigned long __sem_ctime_lo;\n\tunsigned long __sem_ctime_hi;\n\tunsigned short sem_nsems;\n\tchar __sem_nsems_pad[sizeof(long)-sizeof(short)];\n\tlong __unused3;\n\tlong __unused4;\n\ttime_t sem_otime;\n\ttime_t sem_ctime;\n};\n"
  },
  {
    "path": "user.libc/arch/i386/bits/setjmp.h",
    "content": "typedef unsigned long __jmp_buf[6];\n"
  },
  {
    "path": "user.libc/arch/i386/bits/shm.h",
    "content": "#define SHMLBA 4096\n\nstruct shmid_ds {\n\tstruct ipc_perm shm_perm;\n\tsize_t shm_segsz;\n\tunsigned long __shm_atime_lo;\n\tunsigned long __shm_atime_hi;\n\tunsigned long __shm_dtime_lo;\n\tunsigned long __shm_dtime_hi;\n\tunsigned long __shm_ctime_lo;\n\tunsigned long __shm_ctime_hi;\n\tpid_t shm_cpid;\n\tpid_t shm_lpid;\n\tunsigned long shm_nattch;\n\tunsigned long __pad1;\n\tunsigned long __pad2;\n\tunsigned long __pad3;\n\ttime_t shm_atime;\n\ttime_t shm_dtime;\n\ttime_t shm_ctime;\n};\n\nstruct shminfo {\n\tunsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];\n};\n\nstruct shm_info {\n\tint __used_ids;\n\tunsigned long shm_tot, shm_rss, shm_swp;\n\tunsigned long __swap_attempts, __swap_successes;\n};\n"
  },
  {
    "path": "user.libc/arch/i386/bits/signal.h",
    "content": "#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define MINSIGSTKSZ 2048\n#define SIGSTKSZ 8192\n#endif\n\n#ifdef _GNU_SOURCE\nenum { REG_GS = 0 };\n#define REG_GS REG_GS\nenum { REG_FS = 1 };\n#define REG_FS REG_FS\nenum { REG_ES = 2 };\n#define REG_ES REG_ES\nenum { REG_DS = 3 };\n#define REG_DS REG_DS\nenum { REG_EDI = 4 };\n#define REG_EDI REG_EDI\nenum { REG_ESI = 5 };\n#define REG_ESI REG_ESI\nenum { REG_EBP = 6 };\n#define REG_EBP REG_EBP\nenum { REG_ESP = 7 };\n#define REG_ESP REG_ESP\nenum { REG_EBX = 8 };\n#define REG_EBX REG_EBX\nenum { REG_EDX = 9 };\n#define REG_EDX REG_EDX\nenum { REG_ECX = 10 };\n#define REG_ECX REG_ECX\nenum { REG_EAX = 11 };\n#define REG_EAX REG_EAX\nenum { REG_TRAPNO = 12 };\n#define REG_TRAPNO REG_TRAPNO\nenum { REG_ERR = 13 };\n#define REG_ERR REG_ERR\nenum { REG_EIP = 14 };\n#define REG_EIP REG_EIP\nenum { REG_CS = 15 };\n#define REG_CS REG_CS\nenum { REG_EFL = 16 };\n#define REG_EFL REG_EFL\nenum { REG_UESP = 17 };\n#define REG_UESP REG_UESP\nenum { REG_SS = 18 };\n#define REG_SS REG_SS\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\ntypedef int greg_t, gregset_t[19];\ntypedef struct _fpstate {\n\tunsigned long cw, sw, tag, ipoff, cssel, dataoff, datasel;\n\tstruct {\n\t\tunsigned short significand[4], exponent;\n\t} _st[8];\n\tunsigned long status;\n} *fpregset_t;\nstruct sigcontext {\n\tunsigned short gs, __gsh, fs, __fsh, es, __esh, ds, __dsh;\n\tunsigned long edi, esi, ebp, esp, ebx, edx, ecx, eax;\n\tunsigned long trapno, err, eip;\n\tunsigned short cs, __csh;\n\tunsigned long eflags, esp_at_signal;\n\tunsigned short ss, __ssh;\n\tstruct _fpstate *fpstate;\n\tunsigned long oldmask, cr2;\n};\ntypedef struct {\n\tgregset_t gregs;\n\tfpregset_t fpregs;\n\tunsigned long oldmask, cr2;\n} mcontext_t;\n#else\ntypedef struct {\n\tunsigned __space[22];\n} mcontext_t;\n#endif\n\nstruct sigaltstack {\n\tvoid *ss_sp;\n\tint ss_flags;\n\tsize_t ss_size;\n};\n\ntypedef struct __ucontext {\n\tunsigned long uc_flags;\n\tstruct __ucontext *uc_link;\n\tstack_t uc_stack;\n\tmcontext_t uc_mcontext;\n\tsigset_t uc_sigmask;\n\tunsigned long __fpregs_mem[28];\n} ucontext_t;\n\n#define SA_NOCLDSTOP  1\n#define SA_NOCLDWAIT  2\n#define SA_SIGINFO    4\n#define SA_ONSTACK    0x08000000\n#define SA_RESTART    0x10000000\n#define SA_NODEFER    0x40000000\n#define SA_RESETHAND  0x80000000\n#define SA_RESTORER   0x04000000\n\n#endif\n\n#define SIGHUP    1\n#define SIGINT    2\n#define SIGQUIT   3\n#define SIGILL    4\n#define SIGTRAP   5\n#define SIGABRT   6\n#define SIGIOT    SIGABRT\n#define SIGBUS    7\n#define SIGFPE    8\n#define SIGKILL   9\n#define SIGUSR1   10\n#define SIGSEGV   11\n#define SIGUSR2   12\n#define SIGPIPE   13\n#define SIGALRM   14\n#define SIGTERM   15\n#define SIGSTKFLT 16\n#define SIGCHLD   17\n#define SIGCONT   18\n#define SIGSTOP   19\n#define SIGTSTP   20\n#define SIGTTIN   21\n#define SIGTTOU   22\n#define SIGURG    23\n#define SIGXCPU   24\n#define SIGXFSZ   25\n#define SIGVTALRM 26\n#define SIGPROF   27\n#define SIGWINCH  28\n#define SIGIO     29\n#define SIGPOLL   29\n#define SIGPWR    30\n#define SIGSYS    31\n#define SIGUNUSED SIGSYS\n\n#define _NSIG 65\n\n"
  },
  {
    "path": "user.libc/arch/i386/bits/stat.h",
    "content": "/* copied from kernel definition, but with padding replaced\n * by the corresponding correctly-sized userspace types. */\n\nstruct stat {\n\tdev_t st_dev;\n\tint __st_dev_padding;\n\tlong __st_ino_truncated;\n\tmode_t st_mode;\n\tnlink_t st_nlink;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tdev_t st_rdev;\n\tint __st_rdev_padding;\n\toff_t st_size;\n\tblksize_t st_blksize;\n\tblkcnt_t st_blocks;\n\tstruct {\n\t\tlong tv_sec;\n\t\tlong tv_nsec;\n\t} __st_atim32, __st_mtim32, __st_ctim32;\n\tino_t st_ino;\n\tstruct timespec st_atim;\n\tstruct timespec st_mtim;\n\tstruct timespec st_ctim;\n};\n"
  },
  {
    "path": "user.libc/arch/i386/bits/stdint.h",
    "content": "typedef int32_t int_fast16_t;\ntypedef int32_t int_fast32_t;\ntypedef uint32_t uint_fast16_t;\ntypedef uint32_t uint_fast32_t;\n\n#define INT_FAST16_MIN  INT32_MIN\n#define INT_FAST32_MIN  INT32_MIN\n\n#define INT_FAST16_MAX  INT32_MAX\n#define INT_FAST32_MAX  INT32_MAX\n\n#define UINT_FAST16_MAX UINT32_MAX\n#define UINT_FAST32_MAX UINT32_MAX\n\n#define INTPTR_MIN      INT32_MIN\n#define INTPTR_MAX      INT32_MAX\n#define UINTPTR_MAX     UINT32_MAX\n#define PTRDIFF_MIN     INT32_MIN\n#define PTRDIFF_MAX     INT32_MAX\n#define SIZE_MAX        UINT32_MAX\n"
  },
  {
    "path": "user.libc/arch/i386/bits/syscall.h.in",
    "content": "#define __NR_restart_syscall      0\n#define __NR_exit\t\t  1\n#define __NR_fork\t\t  2\n#define __NR_read\t\t  3\n#define __NR_write\t\t  4\n#define __NR_open\t\t  5\n#define __NR_close\t\t  6\n#define __NR_waitpid\t\t  7\n#define __NR_creat\t\t  8\n#define __NR_link\t\t  9\n#define __NR_unlink\t\t 10\n#define __NR_execve\t\t 11\n#define __NR_chdir\t\t 12\n#define __NR_time\t\t 13\n#define __NR_mknod\t\t 14\n#define __NR_chmod\t\t 15\n#define __NR_lchown\t\t 16\n#define __NR_break\t\t 17\n#define __NR_oldstat\t\t 18\n#define __NR_lseek\t\t 19\n#define __NR_getpid\t\t 20\n#define __NR_mount\t\t 21\n#define __NR_umount\t\t 22\n#define __NR_setuid\t\t 23\n#define __NR_getuid\t\t 24\n#define __NR_stime\t\t 25\n#define __NR_ptrace\t\t 26\n#define __NR_alarm\t\t 27\n#define __NR_oldfstat\t\t 28\n#define __NR_pause\t\t 29\n#define __NR_utime\t\t 30\n#define __NR_stty\t\t 31\n#define __NR_gtty\t\t 32\n#define __NR_access\t\t 33\n#define __NR_nice\t\t 34\n#define __NR_ftime\t\t 35\n#define __NR_sync\t\t 36\n#define __NR_kill\t\t 37\n#define __NR_rename\t\t 38\n#define __NR_mkdir\t\t 39\n#define __NR_rmdir\t\t 40\n#define __NR_dup\t\t 41\n#define __NR_pipe\t\t 42\n#define __NR_times\t\t 43\n#define __NR_prof\t\t 44\n#define __NR_brk\t\t 45\n#define __NR_setgid\t\t 46\n#define __NR_getgid\t\t 47\n#define __NR_signal\t\t 48\n#define __NR_geteuid\t\t 49\n#define __NR_getegid\t\t 50\n#define __NR_acct\t\t 51\n#define __NR_umount2\t\t 52\n#define __NR_lock\t\t 53\n#define __NR_ioctl\t\t 54\n#define __NR_fcntl\t\t 55\n#define __NR_mpx\t\t 56\n#define __NR_setpgid\t\t 57\n#define __NR_ulimit\t\t 58\n#define __NR_oldolduname\t 59\n#define __NR_umask\t\t 60\n#define __NR_chroot\t\t 61\n#define __NR_ustat\t\t 62\n#define __NR_dup2\t\t 63\n#define __NR_getppid\t\t 64\n#define __NR_getpgrp\t\t 65\n#define __NR_setsid\t\t 66\n#define __NR_sigaction\t\t 67\n#define __NR_sgetmask\t\t 68\n#define __NR_ssetmask\t\t 69\n#define __NR_setreuid\t\t 70\n#define __NR_setregid\t\t 71\n#define __NR_sigsuspend\t\t 72\n#define __NR_sigpending\t\t 73\n#define __NR_sethostname\t 74\n#define __NR_setrlimit\t\t 75\n#define __NR_getrlimit\t\t 76   /* Back compatible 2Gig limited rlimit */\n#define __NR_getrusage\t\t 77\n#define __NR_gettimeofday_time32\t 78\n#define __NR_settimeofday_time32\t 79\n#define __NR_getgroups\t\t 80\n#define __NR_setgroups\t\t 81\n#define __NR_select\t\t 82\n#define __NR_symlink\t\t 83\n#define __NR_oldlstat\t\t 84\n#define __NR_readlink\t\t 85\n#define __NR_uselib\t\t 86\n#define __NR_swapon\t\t 87\n#define __NR_reboot\t\t 88\n#define __NR_readdir\t\t 89\n#define __NR_mmap\t\t 90\n#define __NR_munmap\t\t 91\n#define __NR_truncate\t\t 92\n#define __NR_ftruncate\t\t 93\n#define __NR_fchmod\t\t 94\n#define __NR_fchown\t\t 95\n#define __NR_getpriority\t 96\n#define __NR_setpriority\t 97\n#define __NR_profil\t\t 98\n#define __NR_statfs\t\t99\n#define __NR_fstatfs\t\t100\n#define __NR_ioperm\t\t101\n#define __NR_socketcall\t\t102\n#define __NR_syslog\t\t103\n#define __NR_setitimer\t\t104\n#define __NR_getitimer\t\t105\n#define __NR_stat\t\t106\n#define __NR_lstat\t\t107\n#define __NR_fstat\t\t108\n#define __NR_olduname\t\t109\n#define __NR_iopl\t\t110\n#define __NR_vhangup\t\t111\n#define __NR_idle\t\t112\n#define __NR_vm86old\t\t113\n#define __NR_wait4\t\t114\n#define __NR_swapoff\t\t115\n#define __NR_sysinfo\t\t116\n#define __NR_ipc\t\t117\n#define __NR_fsync\t\t118\n#define __NR_sigreturn\t\t119\n#define __NR_clone\t\t120\n#define __NR_setdomainname\t121\n#define __NR_uname\t\t122\n#define __NR_modify_ldt\t\t123\n#define __NR_adjtimex\t\t124\n#define __NR_mprotect\t\t125\n#define __NR_sigprocmask\t126\n#define __NR_create_module\t127\n#define __NR_init_module\t128\n#define __NR_delete_module\t129\n#define __NR_get_kernel_syms\t130\n#define __NR_quotactl\t\t131\n#define __NR_getpgid\t\t132\n#define __NR_fchdir\t\t133\n#define __NR_bdflush\t\t134\n#define __NR_sysfs\t\t135\n#define __NR_personality\t136\n#define __NR_afs_syscall\t137\n#define __NR_setfsuid\t\t138\n#define __NR_setfsgid\t\t139\n#define __NR__llseek\t\t140\n#define __NR_getdents\t\t141\n#define __NR__newselect\t\t142\n#define __NR_flock\t\t143\n#define __NR_msync\t\t144\n#define __NR_readv\t\t145\n#define __NR_writev\t\t146\n#define __NR_getsid\t\t147\n#define __NR_fdatasync\t\t148\n#define __NR__sysctl\t\t149\n#define __NR_mlock\t\t150\n#define __NR_munlock\t\t151\n#define __NR_mlockall\t\t152\n#define __NR_munlockall\t\t153\n#define __NR_sched_setparam\t\t154\n#define __NR_sched_getparam\t\t155\n#define __NR_sched_setscheduler\t\t156\n#define __NR_sched_getscheduler\t\t157\n#define __NR_sched_yield\t\t158\n#define __NR_sched_get_priority_max\t159\n#define __NR_sched_get_priority_min\t160\n#define __NR_sched_rr_get_interval\t161\n#define __NR_nanosleep\t\t162\n#define __NR_mremap\t\t163\n#define __NR_setresuid\t\t164\n#define __NR_getresuid\t\t165\n#define __NR_vm86\t\t166\n#define __NR_query_module\t167\n#define __NR_poll\t\t168\n#define __NR_nfsservctl\t\t169\n#define __NR_setresgid\t\t170\n#define __NR_getresgid\t\t171\n#define __NR_prctl              172\n#define __NR_rt_sigreturn\t173\n#define __NR_rt_sigaction\t174\n#define __NR_rt_sigprocmask\t175\n#define __NR_rt_sigpending\t176\n#define __NR_rt_sigtimedwait\t177\n#define __NR_rt_sigqueueinfo\t178\n#define __NR_rt_sigsuspend\t179\n#define __NR_pread64\t\t180\n#define __NR_pwrite64\t\t181\n#define __NR_chown\t\t182\n#define __NR_getcwd\t\t183\n#define __NR_capget\t\t184\n#define __NR_capset\t\t185\n#define __NR_sigaltstack\t186\n#define __NR_sendfile\t\t187\n#define __NR_getpmsg\t\t188\n#define __NR_putpmsg\t\t189\n#define __NR_vfork\t\t190\n#define __NR_ugetrlimit\t\t191\n#define __NR_mmap2\t\t192\n#define __NR_truncate64\t\t193\n#define __NR_ftruncate64\t194\n#define __NR_stat64\t\t195\n#define __NR_lstat64\t\t196\n#define __NR_fstat64\t\t197\n#define __NR_lchown32\t\t198\n#define __NR_getuid32\t\t199\n#define __NR_getgid32\t\t200\n#define __NR_geteuid32\t\t201\n#define __NR_getegid32\t\t202\n#define __NR_setreuid32\t\t203\n#define __NR_setregid32\t\t204\n#define __NR_getgroups32\t205\n#define __NR_setgroups32\t206\n#define __NR_fchown32\t\t207\n#define __NR_setresuid32\t208\n#define __NR_getresuid32\t209\n#define __NR_setresgid32\t210\n#define __NR_getresgid32\t211\n#define __NR_chown32\t\t212\n#define __NR_setuid32\t\t213\n#define __NR_setgid32\t\t214\n#define __NR_setfsuid32\t\t215\n#define __NR_setfsgid32\t\t216\n#define __NR_pivot_root\t\t217\n#define __NR_mincore\t\t218\n#define __NR_madvise\t\t219\n#define __NR_getdents64\t\t220\n#define __NR_fcntl64\t\t221\n/* 223 is unused */\n#define __NR_gettid\t\t224\n#define __NR_readahead\t\t225\n#define __NR_setxattr\t\t226\n#define __NR_lsetxattr\t\t227\n#define __NR_fsetxattr\t\t228\n#define __NR_getxattr\t\t229\n#define __NR_lgetxattr\t\t230\n#define __NR_fgetxattr\t\t231\n#define __NR_listxattr\t\t232\n#define __NR_llistxattr\t\t233\n#define __NR_flistxattr\t\t234\n#define __NR_removexattr\t235\n#define __NR_lremovexattr\t236\n#define __NR_fremovexattr\t237\n#define __NR_tkill\t\t238\n#define __NR_sendfile64\t\t239\n#define __NR_futex\t\t240\n#define __NR_sched_setaffinity\t241\n#define __NR_sched_getaffinity\t242\n#define __NR_set_thread_area\t243\n#define __NR_get_thread_area\t244\n#define __NR_io_setup\t\t245\n#define __NR_io_destroy\t\t246\n#define __NR_io_getevents\t247\n#define __NR_io_submit\t\t248\n#define __NR_io_cancel\t\t249\n#define __NR_fadvise64\t\t250\n/* 251 is available for reuse (was briefly sys_set_zone_reclaim) */\n#define __NR_exit_group\t\t252\n#define __NR_lookup_dcookie\t253\n#define __NR_epoll_create\t254\n#define __NR_epoll_ctl\t\t255\n#define __NR_epoll_wait\t\t256\n#define __NR_remap_file_pages\t257\n#define __NR_set_tid_address\t258\n#define __NR_timer_create\t259\n#define __NR_timer_settime32\t(__NR_timer_create+1)\n#define __NR_timer_gettime32\t(__NR_timer_create+2)\n#define __NR_timer_getoverrun\t(__NR_timer_create+3)\n#define __NR_timer_delete\t(__NR_timer_create+4)\n#define __NR_clock_settime32\t(__NR_timer_create+5)\n#define __NR_clock_gettime32\t(__NR_timer_create+6)\n#define __NR_clock_getres_time32\t(__NR_timer_create+7)\n#define __NR_clock_nanosleep_time32\t(__NR_timer_create+8)\n#define __NR_statfs64\t\t268\n#define __NR_fstatfs64\t\t269\n#define __NR_tgkill\t\t270\n#define __NR_utimes\t\t271\n#define __NR_fadvise64_64\t272\n#define __NR_vserver\t\t273\n#define __NR_mbind\t\t274\n#define __NR_get_mempolicy\t275\n#define __NR_set_mempolicy\t276\n#define __NR_mq_open \t\t277\n#define __NR_mq_unlink\t\t(__NR_mq_open+1)\n#define __NR_mq_timedsend\t(__NR_mq_open+2)\n#define __NR_mq_timedreceive\t(__NR_mq_open+3)\n#define __NR_mq_notify\t\t(__NR_mq_open+4)\n#define __NR_mq_getsetattr\t(__NR_mq_open+5)\n#define __NR_kexec_load\t\t283\n#define __NR_waitid\t\t284\n/* #define __NR_sys_setaltroot\t285 */\n#define __NR_add_key\t\t286\n#define __NR_request_key\t287\n#define __NR_keyctl\t\t288\n#define __NR_ioprio_set\t\t289\n#define __NR_ioprio_get\t\t290\n#define __NR_inotify_init\t291\n#define __NR_inotify_add_watch\t292\n#define __NR_inotify_rm_watch\t293\n#define __NR_migrate_pages\t294\n#define __NR_openat\t\t295\n#define __NR_mkdirat\t\t296\n#define __NR_mknodat\t\t297\n#define __NR_fchownat\t\t298\n#define __NR_futimesat\t\t299\n#define __NR_fstatat64\t\t300\n#define __NR_unlinkat\t\t301\n#define __NR_renameat\t\t302\n#define __NR_linkat\t\t303\n#define __NR_symlinkat\t\t304\n#define __NR_readlinkat\t\t305\n#define __NR_fchmodat\t\t306\n#define __NR_faccessat\t\t307\n#define __NR_pselect6\t\t308\n#define __NR_ppoll\t\t309\n#define __NR_unshare\t\t310\n#define __NR_set_robust_list\t311\n#define __NR_get_robust_list\t312\n#define __NR_splice\t\t313\n#define __NR_sync_file_range\t314\n#define __NR_tee\t\t315\n#define __NR_vmsplice\t\t316\n#define __NR_move_pages\t\t317\n#define __NR_getcpu\t\t318\n#define __NR_epoll_pwait\t319\n#define __NR_utimensat\t\t320\n#define __NR_signalfd\t\t321\n#define __NR_timerfd_create\t322\n#define __NR_eventfd\t\t323\n#define __NR_fallocate\t\t324\n#define __NR_timerfd_settime32\t325\n#define __NR_timerfd_gettime32\t326\n#define __NR_signalfd4\t\t327\n#define __NR_eventfd2\t\t328\n#define __NR_epoll_create1\t329\n#define __NR_dup3\t\t330\n#define __NR_pipe2\t\t331\n#define __NR_inotify_init1\t332\n#define __NR_preadv\t\t333\n#define __NR_pwritev\t\t334\n#define __NR_rt_tgsigqueueinfo\t335\n#define __NR_perf_event_open\t336\n#define __NR_recvmmsg\t\t337\n#define __NR_fanotify_init\t338\n#define __NR_fanotify_mark\t339\n#define __NR_prlimit64\t\t340\n#define __NR_name_to_handle_at\t341\n#define __NR_open_by_handle_at\t342\n#define __NR_clock_adjtime\t343\n#define __NR_syncfs\t\t344\n#define __NR_sendmmsg\t\t345\n#define __NR_setns\t\t346\n#define __NR_process_vm_readv\t347\n#define __NR_process_vm_writev\t348\n#define __NR_kcmp\t\t349\n#define __NR_finit_module\t350\n#define __NR_sched_setattr\t351\n#define __NR_sched_getattr\t352\n#define __NR_renameat2\t\t353\n#define __NR_seccomp\t\t354\n#define __NR_getrandom\t\t355\n#define __NR_memfd_create\t356\n#define __NR_bpf\t\t357\n#define __NR_execveat\t\t358\n#define __NR_socket\t\t359\n#define __NR_socketpair\t\t360\n#define __NR_bind\t\t361\n#define __NR_connect\t\t362\n#define __NR_listen\t\t363\n#define __NR_accept4\t\t364\n#define __NR_getsockopt\t\t365\n#define __NR_setsockopt\t\t366\n#define __NR_getsockname\t367\n#define __NR_getpeername\t368\n#define __NR_sendto\t\t369\n#define __NR_sendmsg\t\t370\n#define __NR_recvfrom\t\t371\n#define __NR_recvmsg\t\t372\n#define __NR_shutdown\t\t373\n#define __NR_userfaultfd\t374\n#define __NR_membarrier\t\t375\n#define __NR_mlock2\t\t376\n#define __NR_copy_file_range\t377\n#define __NR_preadv2\t\t378\n#define __NR_pwritev2\t\t379\n#define __NR_pkey_mprotect\t380\n#define __NR_pkey_alloc\t\t381\n#define __NR_pkey_free\t\t382\n#define __NR_statx\t\t383\n#define __NR_arch_prctl\t\t384\n#define __NR_io_pgetevents\t385\n#define __NR_rseq\t\t386\n#define __NR_semget\t\t393\n#define __NR_semctl\t\t394\n#define __NR_shmget\t\t395\n#define __NR_shmctl\t\t396\n#define __NR_shmat\t\t397\n#define __NR_shmdt\t\t398\n#define __NR_msgget\t\t399\n#define __NR_msgsnd\t\t400\n#define __NR_msgrcv\t\t401\n#define __NR_msgctl\t\t402\n#define __NR_clock_gettime64\t403\n#define __NR_clock_settime64\t404\n#define __NR_clock_adjtime64\t405\n#define __NR_clock_getres_time64 406\n#define __NR_clock_nanosleep_time64 407\n#define __NR_timer_gettime64\t408\n#define __NR_timer_settime64\t409\n#define __NR_timerfd_gettime64\t410\n#define __NR_timerfd_settime64\t411\n#define __NR_utimensat_time64\t412\n#define __NR_pselect6_time64\t413\n#define __NR_ppoll_time64\t414\n#define __NR_io_pgetevents_time64 416\n#define __NR_recvmmsg_time64\t417\n#define __NR_mq_timedsend_time64 418\n#define __NR_mq_timedreceive_time64 419\n#define __NR_semtimedop_time64\t420\n#define __NR_rt_sigtimedwait_time64 421\n#define __NR_futex_time64\t422\n#define __NR_sched_rr_get_interval_time64 423\n#define __NR_pidfd_send_signal\t424\n#define __NR_io_uring_setup\t425\n#define __NR_io_uring_enter\t426\n#define __NR_io_uring_register\t427\n#define __NR_open_tree\t\t428\n#define __NR_move_mount\t\t429\n#define __NR_fsopen\t\t430\n#define __NR_fsconfig\t\t431\n#define __NR_fsmount\t\t432\n#define __NR_fspick\t\t433\n#define __NR_pidfd_open\t\t434\n#define __NR_clone3\t\t435\n#define __NR_close_range\t436\n#define __NR_openat2\t\t437\n#define __NR_pidfd_getfd\t438\n#define __NR_faccessat2\t\t439\n\n"
  },
  {
    "path": "user.libc/arch/i386/bits/user.h",
    "content": "#undef __WORDSIZE\n#define __WORDSIZE 32\n\ntypedef struct user_fpregs_struct {\n\tlong cwd, swd, twd, fip, fcs, foo, fos, st_space[20];\n} elf_fpregset_t;\n\ntypedef struct user_fpxregs_struct {\n\tunsigned short cwd, swd, twd, fop;\n\tlong fip, fcs, foo, fos, mxcsr, reserved;\n\tlong st_space[32], xmm_space[32], padding[56];\n} elf_fpxregset_t;\n\nstruct user_regs_struct {\n\tlong ebx, ecx, edx, esi, edi, ebp, eax, xds, xes, xfs, xgs;\n\tlong orig_eax, eip, xcs, eflags, esp, xss;\n};\n\n#define ELF_NGREG 17\ntypedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG];\n\nstruct user {\n\tstruct user_regs_struct\t\tregs;\n\tint\t\t\t\tu_fpvalid;\n\tstruct user_fpregs_struct\ti387;\n\tunsigned long\t\t\tu_tsize;\n\tunsigned long\t\t\tu_dsize;\n\tunsigned long\t\t\tu_ssize;\n\tunsigned long\t\t\tstart_code;\n\tunsigned long\t\t\tstart_stack;\n\tlong\t\t\t\tsignal;\n\tint\t\t\t\treserved;\n\tstruct user_regs_struct\t\t*u_ar0;\n\tstruct user_fpregs_struct\t*u_fpstate;\n\tunsigned long\t\t\tmagic;\n\tchar\t\t\t\tu_comm[32];\n\tint\t\t\t\tu_debugreg[8];\n};\n\n#define PAGE_MASK\t\t(~(PAGESIZE-1))\n#define NBPG\t\t\tPAGESIZE\n#define UPAGES\t\t\t1\n#define HOST_TEXT_START_ADDR\t(u.start_code)\n#define HOST_STACK_END_ADDR\t(u.start_stack + u.u_ssize * NBPG)\n"
  },
  {
    "path": "user.libc/arch/i386/crt_arch.h",
    "content": "__asm__(\n\".text\\n\"\n\".weak _DYNAMIC \\n\"\n\".hidden _DYNAMIC \\n\"\n\".global \" START \"\\n\"\nSTART \":\\n\"\n\"\txor %ebp,%ebp \\n\"\n\"\tmov %esp,%eax \\n\"\n\"\tand $-16,%esp \\n\"\n\"\tpush %eax \\n\"\n\"\tpush %eax \\n\"\n\"\tcall 1f \\n\"\n\"1:\taddl $_DYNAMIC-1b,(%esp) \\n\"\n\"\tpush %eax \\n\"\n\"\tcall \" START \"_c \\n\"\n);\n"
  },
  {
    "path": "user.libc/arch/i386/kstat.h",
    "content": "struct kstat {\n\tdev_t st_dev;\n\tint __st_dev_padding;\n\tlong __st_ino_truncated;\n\tmode_t st_mode;\n\tnlink_t st_nlink;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tdev_t st_rdev;\n\tint __st_rdev_padding;\n\toff_t st_size;\n\tblksize_t st_blksize;\n\tblkcnt_t st_blocks;\n\tlong st_atime_sec;\n\tlong st_atime_nsec;\n\tlong st_mtime_sec;\n\tlong st_mtime_nsec;\n\tlong st_ctime_sec;\n\tlong st_ctime_nsec;\n\tino_t st_ino;\n};\n"
  },
  {
    "path": "user.libc/arch/i386/pthread_arch.h",
    "content": "static inline uintptr_t __get_tp()\n{\n\tuintptr_t tp;\n\t__asm__ (\"movl %%gs:0,%0\" : \"=r\" (tp) );\n\treturn tp;\n}\n\n#define MC_PC gregs[REG_EIP]\n"
  },
  {
    "path": "user.libc/arch/i386/reloc.h",
    "content": "#define LDSO_ARCH \"i386\"\n\n#define REL_SYMBOLIC    R_386_32\n#define REL_OFFSET      R_386_PC32\n#define REL_GOT         R_386_GLOB_DAT\n#define REL_PLT         R_386_JMP_SLOT\n#define REL_RELATIVE    R_386_RELATIVE\n#define REL_COPY        R_386_COPY\n#define REL_DTPMOD      R_386_TLS_DTPMOD32\n#define REL_DTPOFF      R_386_TLS_DTPOFF32\n#define REL_TPOFF       R_386_TLS_TPOFF\n#define REL_TPOFF_NEG   R_386_TLS_TPOFF32\n#define REL_TLSDESC     R_386_TLS_DESC\n\n#define CRTJMP(pc,sp) __asm__ __volatile__( \\\n\t\"mov %1,%%esp ; jmp *%0\" : : \"r\"(pc), \"r\"(sp) : \"memory\" )\n\n#define GETFUNCSYM(fp, sym, got) __asm__ ( \\\n\t\".hidden \" #sym \"\\n\" \\\n\t\"\tcall 1f\\n\" \\\n\t\"1:\taddl $\" #sym \"-.,(%%esp)\\n\" \\\n\t\"\tpop %0\" \\\n\t: \"=r\"(*fp) : : \"memory\" )\n"
  },
  {
    "path": "user.libc/arch/i386/syscall_arch.h",
    "content": "#define __SYSCALL_LL_E(x) \\\n((union { long long ll; long l[2]; }){ .ll = x }).l[0], \\\n((union { long long ll; long l[2]; }){ .ll = x }).l[1]\n#define __SYSCALL_LL_O(x) __SYSCALL_LL_E((x))\n\n#if SYSCALL_NO_TLS\n#define SYSCALL_INSNS \"int $128\"\n#else\n#define SYSCALL_INSNS \"call *%%gs:16\"\n#endif\n\n#define SYSCALL_INSNS_12 \"xchg %%ebx,%%edx ; \" SYSCALL_INSNS \" ; xchg %%ebx,%%edx\"\n#define SYSCALL_INSNS_34 \"xchg %%ebx,%%edi ; \" SYSCALL_INSNS \" ; xchg %%ebx,%%edi\"\n\nstatic inline long __syscall0(long n)\n{\n\tunsigned long __ret;\n\t__asm__ __volatile__ (SYSCALL_INSNS : \"=a\"(__ret) : \"a\"(n) : \"memory\");\n\treturn __ret;\n}\n\nstatic inline long __syscall1(long n, long a1)\n{\n\tunsigned long __ret;\n\t__asm__ __volatile__ (SYSCALL_INSNS_12 : \"=a\"(__ret) : \"a\"(n), \"d\"(a1) : \"memory\");\n\treturn __ret;\n}\n\nstatic inline long __syscall2(long n, long a1, long a2)\n{\n\tunsigned long __ret;\n\t__asm__ __volatile__ (SYSCALL_INSNS_12 : \"=a\"(__ret) : \"a\"(n), \"d\"(a1), \"c\"(a2) : \"memory\");\n\treturn __ret;\n}\n\nstatic inline long __syscall3(long n, long a1, long a2, long a3)\n{\n\tunsigned long __ret;\n#if !defined(__PIC__) || !defined(BROKEN_EBX_ASM)\n\t__asm__ __volatile__ (SYSCALL_INSNS : \"=a\"(__ret) : \"a\"(n), \"b\"(a1), \"c\"(a2), \"d\"(a3) : \"memory\");\n#else\n\t__asm__ __volatile__ (SYSCALL_INSNS_34 : \"=a\"(__ret) : \"a\"(n), \"D\"(a1), \"c\"(a2), \"d\"(a3) : \"memory\");\n#endif\n\treturn __ret;\n}\n\nstatic inline long __syscall4(long n, long a1, long a2, long a3, long a4)\n{\n\tunsigned long __ret;\n#if !defined(__PIC__) || !defined(BROKEN_EBX_ASM)\n\t__asm__ __volatile__ (SYSCALL_INSNS : \"=a\"(__ret) : \"a\"(n), \"b\"(a1), \"c\"(a2), \"d\"(a3), \"S\"(a4) : \"memory\");\n#else\n\t__asm__ __volatile__ (SYSCALL_INSNS_34 : \"=a\"(__ret) : \"a\"(n), \"D\"(a1), \"c\"(a2), \"d\"(a3), \"S\"(a4) : \"memory\");\n#endif\n\treturn __ret;\n}\n\nstatic inline long __syscall5(long n, long a1, long a2, long a3, long a4, long a5)\n{\n\tunsigned long __ret;\n#if !defined(__PIC__) || !defined(BROKEN_EBX_ASM)\n\t__asm__ __volatile__ (SYSCALL_INSNS\n\t\t: \"=a\"(__ret) : \"a\"(n), \"b\"(a1), \"c\"(a2), \"d\"(a3), \"S\"(a4), \"D\"(a5) : \"memory\");\n#else\n\t__asm__ __volatile__ (\"pushl %2 ; push %%ebx ; mov 4(%%esp),%%ebx ; \" SYSCALL_INSNS \" ; pop %%ebx ; add $4,%%esp\"\n\t\t: \"=a\"(__ret) : \"a\"(n), \"g\"(a1), \"c\"(a2), \"d\"(a3), \"S\"(a4), \"D\"(a5) : \"memory\");\n#endif\n\treturn __ret;\n}\n\nstatic inline long __syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6)\n{\n\tunsigned long __ret;\n#if !defined(__PIC__) || !defined(BROKEN_EBX_ASM)\n\t__asm__ __volatile__ (\"pushl %7 ; push %%ebp ; mov 4(%%esp),%%ebp ; \" SYSCALL_INSNS \" ; pop %%ebp ; add $4,%%esp\"\n\t\t: \"=a\"(__ret) : \"a\"(n), \"b\"(a1), \"c\"(a2), \"d\"(a3), \"S\"(a4), \"D\"(a5), \"g\"(a6) : \"memory\");\n#else\n\tunsigned long a1a6[2] = { a1, a6 };\n\t__asm__ __volatile__ (\"pushl %1 ; push %%ebx ; push %%ebp ; mov 8(%%esp),%%ebx ; mov 4(%%ebx),%%ebp ; mov (%%ebx),%%ebx ; \" SYSCALL_INSNS \" ; pop %%ebp ; pop %%ebx ; add $4,%%esp\"\n\t\t: \"=a\"(__ret) : \"g\"(&a1a6), \"a\"(n), \"c\"(a2), \"d\"(a3), \"S\"(a4), \"D\"(a5) : \"memory\");\n#endif\n\treturn __ret;\n}\n\n#define VDSO_USEFUL\n#define VDSO_CGT32_SYM \"__vdso_clock_gettime\"\n#define VDSO_CGT32_VER \"LINUX_2.6\"\n#define VDSO_CGT_SYM \"__vdso_clock_gettime64\"\n#define VDSO_CGT_VER \"LINUX_2.6\"\n"
  },
  {
    "path": "user.libc/arch/m68k/arch.mak",
    "content": "COMPAT_SRC_DIRS = compat/time32\n"
  },
  {
    "path": "user.libc/arch/m68k/atomic_arch.h",
    "content": "#define a_cas a_cas\nstatic inline int a_cas(volatile int *p, int t, int s)\n{\n\t__asm__ __volatile__ (\n\t\t\"cas.l %0, %2, (%1)\"\n\t\t: \"+d\"(t) : \"a\"(p), \"d\"(s) : \"memory\", \"cc\");\n\treturn t;\n}\n"
  },
  {
    "path": "user.libc/arch/m68k/bits/alltypes.h.in",
    "content": "#define _REDIR_TIME64 1\n#define _Addr int\n#define _Int64 long long\n#define _Reg int\n\n#define __BYTE_ORDER 4321\n#define __LONG_MAX 0x7fffffffL\n\n#ifndef __cplusplus\n#ifdef __WCHAR_TYPE__\nTYPEDEF __WCHAR_TYPE__ wchar_t;\n#else\nTYPEDEF long wchar_t;\n#endif\n#endif\n\n#if __mcffpu__\nTYPEDEF float float_t;\nTYPEDEF double double_t;\n#else\nTYPEDEF long double float_t;\nTYPEDEF long double double_t;\n#endif\n\nTYPEDEF struct { long long __ll; long double __ld; } max_align_t;\n"
  },
  {
    "path": "user.libc/arch/m68k/bits/fcntl.h",
    "content": "#define O_CREAT        0100\n#define O_EXCL         0200\n#define O_NOCTTY       0400\n#define O_TRUNC       01000\n#define O_APPEND      02000\n#define O_NONBLOCK    04000\n#define O_DSYNC      010000\n#define O_SYNC     04010000\n#define O_RSYNC    04010000\n#define O_DIRECTORY  040000\n#define O_NOFOLLOW  0100000\n#define O_CLOEXEC  02000000\n\n#define O_ASYNC      020000\n#define O_DIRECT    0200000\n#define O_LARGEFILE 0400000\n#define O_NOATIME  01000000\n#define O_PATH    010000000\n#define O_TMPFILE 020200000\n#define O_NDELAY O_NONBLOCK\n\n#define F_DUPFD  0\n#define F_GETFD  1\n#define F_SETFD  2\n#define F_GETFL  3\n#define F_SETFL  4\n\n#define F_SETOWN 8\n#define F_GETOWN 9\n#define F_SETSIG 10\n#define F_GETSIG 11\n\n#define F_GETLK 12\n#define F_SETLK 13\n#define F_SETLKW 14\n\n#define F_SETOWN_EX 15\n#define F_GETOWN_EX 16\n\n#define F_GETOWNER_UIDS 17\n"
  },
  {
    "path": "user.libc/arch/m68k/bits/fenv.h",
    "content": "#if __HAVE_68881__ || __mcffpu__\n\n#define FE_INEXACT    8\n#define FE_DIVBYZERO  16\n#define FE_UNDERFLOW  32\n#define FE_OVERFLOW   64\n#define FE_INVALID    128\n\n#define FE_ALL_EXCEPT 0xf8\n\n#define FE_TONEAREST  0\n#define FE_TOWARDZERO 16\n#define FE_DOWNWARD   32\n#define FE_UPWARD     48\n\n#else\n\n#define FE_ALL_EXCEPT 0\n#define FE_TONEAREST  0\n\n#endif\n\ntypedef unsigned fexcept_t;\n\ntypedef struct {\n\tunsigned __control_register, __status_register, __instruction_address;\n} fenv_t;\n\n#define FE_DFL_ENV      ((const fenv_t *) -1)\n"
  },
  {
    "path": "user.libc/arch/m68k/bits/float.h",
    "content": "#if !__mcffpu__\n\n#define FLT_EVAL_METHOD 2\n\n#define LDBL_TRUE_MIN 3.6451995318824746025e-4951L\n#define LDBL_MIN     1.68105157155604675313e-4932L\n#define LDBL_MAX     1.1897314953572317650e+4932L\n#define LDBL_EPSILON 1.0842021724855044340e-19L\n\n#define LDBL_MANT_DIG 64\n#define LDBL_MIN_EXP (-16382)\n#define LDBL_MAX_EXP 16384\n\n#define LDBL_DIG 18\n#define LDBL_MIN_10_EXP (-4931)\n#define LDBL_MAX_10_EXP 4932\n\n#define DECIMAL_DIG 21\n\n#else\n\n#define FLT_EVAL_METHOD 0\n\n#define LDBL_TRUE_MIN 4.94065645841246544177e-324L\n#define LDBL_MIN 2.22507385850720138309e-308L\n#define LDBL_MAX 1.79769313486231570815e+308L\n#define LDBL_EPSILON 2.22044604925031308085e-16L\n\n#define LDBL_MANT_DIG 53\n#define LDBL_MIN_EXP (-1021)\n#define LDBL_MAX_EXP 1024\n\n#define LDBL_DIG 15\n#define LDBL_MIN_10_EXP (-307)\n#define LDBL_MAX_10_EXP 308\n\n#define DECIMAL_DIG 17\n\n#endif\n"
  },
  {
    "path": "user.libc/arch/m68k/bits/ipcstat.h",
    "content": "#define IPC_STAT 0x102\n"
  },
  {
    "path": "user.libc/arch/m68k/bits/msg.h",
    "content": "struct msqid_ds {\n\tstruct ipc_perm msg_perm;\n\tunsigned long __msg_stime_lo;\n\tunsigned long __msg_stime_hi;\n\tunsigned long __msg_rtime_lo;\n\tunsigned long __msg_rtime_hi;\n\tunsigned long __msg_ctime_lo;\n\tunsigned long __msg_ctime_hi;\n\tunsigned long msg_cbytes;\n\tmsgqnum_t msg_qnum;\n\tmsglen_t msg_qbytes;\n\tpid_t msg_lspid;\n\tpid_t msg_lrpid;\n\tunsigned long __unused[2];\n\ttime_t msg_stime;\n\ttime_t msg_rtime;\n\ttime_t msg_ctime;\n};\n"
  },
  {
    "path": "user.libc/arch/m68k/bits/posix.h",
    "content": "#define _POSIX_V6_ILP32_OFFBIG  1\n#define _POSIX_V7_ILP32_OFFBIG  1\n"
  },
  {
    "path": "user.libc/arch/m68k/bits/ptrace.h",
    "content": "#define PTRACE_GET_THREAD_AREA\t25\n#define PTRACE_SINGLEBLOCK\t33\n"
  },
  {
    "path": "user.libc/arch/m68k/bits/reg.h",
    "content": "#undef __WORDSIZE\n#define __WORDSIZE 32\n#define PT_D1 0\n#define PT_D2 1\n#define PT_D3 2\n#define PT_D4 3\n#define PT_D5 4\n#define PT_D6 5\n#define PT_D7 6\n#define PT_A0 7\n#define PT_A1 8\n#define PT_A2 9\n#define PT_A3 10\n#define PT_A4 11\n#define PT_A5 12\n#define PT_A6 13\n#define PT_D0 14\n#define PT_USP 15\n#define PT_ORIG_D0 16\n#define PT_SR 17\n#define PT_PC 18\n\n#if __mcffpu__\n#define PT_FP0 21\n#define PT_FP1 23\n#define PT_FP2 25\n#define PT_FP3 27\n#define PT_FP4 29\n#define PT_FP5 31\n#define PT_FP6 33\n#define PT_FP7 35\n#else\n#define PT_FP0 21\n#define PT_FP1 24\n#define PT_FP2 27\n#define PT_FP3 30\n#define PT_FP4 33\n#define PT_FP5 36\n#define PT_FP6 39\n#define PT_FP7 42\n#endif\n\n#define PT_FPCR 45\n#define PT_FPSR 46\n#define PT_FPIAR 47\n"
  },
  {
    "path": "user.libc/arch/m68k/bits/sem.h",
    "content": "struct semid_ds {\n\tstruct ipc_perm sem_perm;\n\tunsigned long __sem_otime_lo;\n\tunsigned long __sem_otime_hi;\n\tunsigned long __sem_ctime_lo;\n\tunsigned long __sem_ctime_hi;\n\tchar __sem_nsems_pad[sizeof(long)-sizeof(short)];\n\tunsigned short sem_nsems;\n\tlong __unused3;\n\tlong __unused4;\n\ttime_t sem_otime;\n\ttime_t sem_ctime;\n};\n"
  },
  {
    "path": "user.libc/arch/m68k/bits/setjmp.h",
    "content": "typedef unsigned long __jmp_buf[39];\n"
  },
  {
    "path": "user.libc/arch/m68k/bits/shm.h",
    "content": "#define SHMLBA 4096\n\nstruct shmid_ds {\n\tstruct ipc_perm shm_perm;\n\tsize_t shm_segsz;\n\tunsigned long __shm_atime_lo;\n\tunsigned long __shm_atime_hi;\n\tunsigned long __shm_dtime_lo;\n\tunsigned long __shm_dtime_hi;\n\tunsigned long __shm_ctime_lo;\n\tunsigned long __shm_ctime_hi;\n\tpid_t shm_cpid;\n\tpid_t shm_lpid;\n\tunsigned long shm_nattch;\n\tunsigned long __pad1;\n\tunsigned long __pad2;\n\tunsigned long __pad3;\n\ttime_t shm_atime;\n\ttime_t shm_dtime;\n\ttime_t shm_ctime;\n};\n\nstruct shminfo {\n\tunsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];\n};\n\nstruct shm_info {\n\tint __used_ids;\n\tunsigned long shm_tot, shm_rss, shm_swp;\n\tunsigned long __swap_attempts, __swap_successes;\n};\n"
  },
  {
    "path": "user.libc/arch/m68k/bits/signal.h",
    "content": "#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define MINSIGSTKSZ 2048\n#define SIGSTKSZ 8192\n#endif\n\n#ifdef _GNU_SOURCE\nenum { R_D0 = 0 };\n#define R_D0 R_D0\nenum { R_D1 = 1 };\n#define R_D1 R_D1\nenum { R_D2 = 2 };\n#define R_D2 R_D2\nenum { R_D3 = 3 };\n#define R_D3 R_D3\nenum { R_D4 = 4 };\n#define R_D4 R_D4\nenum { R_D5 = 5 };\n#define R_D5 R_D5\nenum { R_D6 = 6 };\n#define R_D6 R_D6\nenum { R_D7 = 7 };\n#define R_D7 R_D7\nenum { R_A0 = 8 };\n#define R_A0 R_A0\nenum { R_A1 = 9 };\n#define R_A1 R_A1\nenum { R_A2 = 10 };\n#define R_A2 R_A2\nenum { R_A3 = 11 };\n#define R_A3 R_A3\nenum { R_A4 = 12 };\n#define R_A4 R_A4\nenum { R_A5 = 13 };\n#define R_A5 R_A5\nenum { R_A6 = 14 };\n#define R_A6 R_A6\nenum { R_A7 = 15 };\n#define R_A7 R_A7\nenum { R_SP = 15 };\n#define R_SP R_SP\nenum { R_PC = 16 };\n#define R_PC R_PC\nenum { R_PS = 17 };\n#define R_PS R_PS\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n\nstruct sigcontext {\n\tunsigned long sc_mask, sc_usp, sc_d0, sc_d1, sc_a0, sc_a1;\n\tunsigned short sc_sr;\n\tunsigned long sc_pc;\n\tunsigned short sc_formatvec;\n\tunsigned long sc_fpregs[6], sc_fpcntl[3];\n\tunsigned char sc_fpstate[216];\n};\n\ntypedef int greg_t, gregset_t[18];\ntypedef struct {\n\tint f_pcr, f_psr, f_fpiaddr, f_fpregs[8][3];\n} fpregset_t;\n\ntypedef struct {\n\tint version;\n\tgregset_t gregs;\n\tfpregset_t fpregs;\n} mcontext_t;\n#else\ntypedef struct {\n\tint __version;\n\tint __gregs[18];\n\tint __fpregs[27];\n} mcontext_t;\n#endif\n\nstruct sigaltstack {\n\tvoid *ss_sp;\n\tint ss_flags;\n\tsize_t ss_size;\n};\n\ntypedef struct __ucontext {\n\tunsigned long uc_flags;\n\tstruct __ucontext *uc_link;\n\tstack_t uc_stack;\n\tmcontext_t uc_mcontext;\n\tlong __reserved[80];\n\tsigset_t uc_sigmask;\n} ucontext_t;\n\n#define SA_NOCLDSTOP  1\n#define SA_NOCLDWAIT  2\n#define SA_SIGINFO    4\n#define SA_ONSTACK    0x08000000\n#define SA_RESTART    0x10000000\n#define SA_NODEFER    0x40000000\n#define SA_RESETHAND  0x80000000\n#define SA_RESTORER   0x04000000\n\n#endif\n\n#define SIGHUP    1\n#define SIGINT    2\n#define SIGQUIT   3\n#define SIGILL    4\n#define SIGTRAP   5\n#define SIGABRT   6\n#define SIGIOT    SIGABRT\n#define SIGBUS    7\n#define SIGFPE    8\n#define SIGKILL   9\n#define SIGUSR1   10\n#define SIGSEGV   11\n#define SIGUSR2   12\n#define SIGPIPE   13\n#define SIGALRM   14\n#define SIGTERM   15\n#define SIGSTKFLT 16\n#define SIGCHLD   17\n#define SIGCONT   18\n#define SIGSTOP   19\n#define SIGTSTP   20\n#define SIGTTIN   21\n#define SIGTTOU   22\n#define SIGURG    23\n#define SIGXCPU   24\n#define SIGXFSZ   25\n#define SIGVTALRM 26\n#define SIGPROF   27\n#define SIGWINCH  28\n#define SIGIO     29\n#define SIGPOLL   29\n#define SIGPWR    30\n#define SIGSYS    31\n#define SIGUNUSED SIGSYS\n\n#define _NSIG 65\n"
  },
  {
    "path": "user.libc/arch/m68k/bits/stat.h",
    "content": "/* copied from kernel definition, but with padding replaced\n * by the corresponding correctly-sized userspace types. */\n\nstruct stat {\n\tdev_t st_dev;\n\tshort __st_dev_padding;\n\tlong __st_ino_truncated;\n\tmode_t st_mode;\n\tnlink_t st_nlink;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tdev_t st_rdev;\n\tshort __st_rdev_padding;\n\toff_t st_size;\n\tblksize_t st_blksize;\n\tblkcnt_t st_blocks;\n\tstruct {\n\t\tlong tv_sec;\n\t\tlong tv_nsec;\n\t} __st_atim32, __st_mtim32, __st_ctim32;\n\tino_t st_ino;\n\tstruct timespec st_atim;\n\tstruct timespec st_mtim;\n\tstruct timespec st_ctim;\n};\n"
  },
  {
    "path": "user.libc/arch/m68k/bits/stdint.h",
    "content": "typedef int32_t int_fast16_t;\ntypedef int32_t int_fast32_t;\ntypedef uint32_t uint_fast16_t;\ntypedef uint32_t uint_fast32_t;\n\n#define INT_FAST16_MIN  INT32_MIN\n#define INT_FAST32_MIN  INT32_MIN\n\n#define INT_FAST16_MAX  INT32_MAX\n#define INT_FAST32_MAX  INT32_MAX\n\n#define UINT_FAST16_MAX UINT32_MAX\n#define UINT_FAST32_MAX UINT32_MAX\n\n#define INTPTR_MIN      INT32_MIN\n#define INTPTR_MAX      INT32_MAX\n#define UINTPTR_MAX     UINT32_MAX\n#define PTRDIFF_MIN     INT32_MIN\n#define PTRDIFF_MAX     INT32_MAX\n#define SIZE_MAX        UINT32_MAX\n"
  },
  {
    "path": "user.libc/arch/m68k/bits/syscall.h.in",
    "content": "#define __NR_restart_syscall\t  0\n#define __NR_exit\t\t  1\n#define __NR_fork\t\t  2\n#define __NR_read\t\t  3\n#define __NR_write\t\t  4\n#define __NR_open\t\t  5\n#define __NR_close\t\t  6\n#define __NR_waitpid\t\t  7\n#define __NR_creat\t\t  8\n#define __NR_link\t\t  9\n#define __NR_unlink\t\t 10\n#define __NR_execve\t\t 11\n#define __NR_chdir\t\t 12\n#define __NR_time\t\t 13\n#define __NR_mknod\t\t 14\n#define __NR_chmod\t\t 15\n#define __NR_chown\t\t 16\n#define __NR_oldstat\t\t 18\n#define __NR_lseek\t\t 19\n#define __NR_getpid\t\t 20\n#define __NR_mount\t\t 21\n#define __NR_umount\t\t 22\n#define __NR_setuid\t\t 23\n#define __NR_getuid\t\t 24\n#define __NR_stime\t\t 25\n#define __NR_ptrace\t\t 26\n#define __NR_alarm\t\t 27\n#define __NR_oldfstat\t\t 28\n#define __NR_pause\t\t 29\n#define __NR_utime\t\t 30\n#define __NR_access\t\t 33\n#define __NR_nice\t\t 34\n#define __NR_sync\t\t 36\n#define __NR_kill\t\t 37\n#define __NR_rename\t\t 38\n#define __NR_mkdir\t\t 39\n#define __NR_rmdir\t\t 40\n#define __NR_dup\t\t 41\n#define __NR_pipe\t\t 42\n#define __NR_times\t\t 43\n#define __NR_brk\t\t 45\n#define __NR_setgid\t\t 46\n#define __NR_getgid\t\t 47\n#define __NR_signal\t\t 48\n#define __NR_geteuid\t\t 49\n#define __NR_getegid\t\t 50\n#define __NR_acct\t\t 51\n#define __NR_umount2\t\t 52\n#define __NR_ioctl\t\t 54\n#define __NR_fcntl\t\t 55\n#define __NR_setpgid\t\t 57\n#define __NR_umask\t\t 60\n#define __NR_chroot\t\t 61\n#define __NR_ustat\t\t 62\n#define __NR_dup2\t\t 63\n#define __NR_getppid\t\t 64\n#define __NR_getpgrp\t\t 65\n#define __NR_setsid\t\t 66\n#define __NR_sigaction\t\t 67\n#define __NR_sgetmask\t\t 68\n#define __NR_ssetmask\t\t 69\n#define __NR_setreuid\t\t 70\n#define __NR_setregid\t\t 71\n#define __NR_sigsuspend\t\t 72\n#define __NR_sigpending\t\t 73\n#define __NR_sethostname\t 74\n#define __NR_setrlimit\t\t 75\n#define __NR_getrlimit\t\t 76\n#define __NR_getrusage\t\t 77\n#define __NR_gettimeofday_time32\t 78\n#define __NR_settimeofday_time32\t 79\n#define __NR_getgroups\t\t 80\n#define __NR_setgroups\t\t 81\n#define __NR_select\t\t 82\n#define __NR_symlink\t\t 83\n#define __NR_oldlstat\t\t 84\n#define __NR_readlink\t\t 85\n#define __NR_uselib\t\t 86\n#define __NR_swapon\t\t 87\n#define __NR_reboot\t\t 88\n#define __NR_readdir\t\t 89\n#define __NR_mmap\t\t 90\n#define __NR_munmap\t\t 91\n#define __NR_truncate\t\t 92\n#define __NR_ftruncate\t\t 93\n#define __NR_fchmod\t\t 94\n#define __NR_fchown\t\t 95\n#define __NR_getpriority\t 96\n#define __NR_setpriority\t 97\n#define __NR_statfs\t\t 99\n#define __NR_fstatfs\t\t100\n#define __NR_socketcall\t\t102\n#define __NR_syslog\t\t103\n#define __NR_setitimer\t\t104\n#define __NR_getitimer\t\t105\n#define __NR_stat\t\t106\n#define __NR_lstat\t\t107\n#define __NR_fstat\t\t108\n#define __NR_vhangup\t\t111\n#define __NR_wait4\t\t114\n#define __NR_swapoff\t\t115\n#define __NR_sysinfo\t\t116\n#define __NR_ipc\t\t117\n#define __NR_fsync\t\t118\n#define __NR_sigreturn\t\t119\n#define __NR_clone\t\t120\n#define __NR_setdomainname\t121\n#define __NR_uname\t\t122\n#define __NR_cacheflush\t\t123\n#define __NR_adjtimex\t\t124\n#define __NR_mprotect\t\t125\n#define __NR_sigprocmask\t126\n#define __NR_create_module\t127\n#define __NR_init_module\t128\n#define __NR_delete_module\t129\n#define __NR_get_kernel_syms\t130\n#define __NR_quotactl\t\t131\n#define __NR_getpgid\t\t132\n#define __NR_fchdir\t\t133\n#define __NR_bdflush\t\t134\n#define __NR_sysfs\t\t135\n#define __NR_personality\t136\n#define __NR_setfsuid\t\t138\n#define __NR_setfsgid\t\t139\n#define __NR__llseek\t\t140\n#define __NR_getdents\t\t141\n#define __NR__newselect\t\t142\n#define __NR_flock\t\t143\n#define __NR_msync\t\t144\n#define __NR_readv\t\t145\n#define __NR_writev\t\t146\n#define __NR_getsid\t\t147\n#define __NR_fdatasync\t\t148\n#define __NR__sysctl\t\t149\n#define __NR_mlock\t\t150\n#define __NR_munlock\t\t151\n#define __NR_mlockall\t\t152\n#define __NR_munlockall\t\t153\n#define __NR_sched_setparam\t\t154\n#define __NR_sched_getparam\t\t155\n#define __NR_sched_setscheduler\t\t156\n#define __NR_sched_getscheduler\t\t157\n#define __NR_sched_yield\t\t158\n#define __NR_sched_get_priority_max\t159\n#define __NR_sched_get_priority_min\t160\n#define __NR_sched_rr_get_interval\t161\n#define __NR_nanosleep\t\t162\n#define __NR_mremap\t\t163\n#define __NR_setresuid\t\t164\n#define __NR_getresuid\t\t165\n#define __NR_getpagesize\t166\n#define __NR_query_module\t167\n#define __NR_poll\t\t168\n#define __NR_nfsservctl\t\t169\n#define __NR_setresgid\t\t170\n#define __NR_getresgid\t\t171\n#define __NR_prctl\t\t172\n#define __NR_rt_sigreturn\t173\n#define __NR_rt_sigaction\t174\n#define __NR_rt_sigprocmask\t175\n#define __NR_rt_sigpending\t176\n#define __NR_rt_sigtimedwait\t177\n#define __NR_rt_sigqueueinfo\t178\n#define __NR_rt_sigsuspend\t179\n#define __NR_pread64\t\t180\n#define __NR_pwrite64\t\t181\n#define __NR_lchown\t\t182\n#define __NR_getcwd\t\t183\n#define __NR_capget\t\t184\n#define __NR_capset\t\t185\n#define __NR_sigaltstack\t186\n#define __NR_sendfile\t\t187\n#define __NR_getpmsg\t\t188\n#define __NR_putpmsg\t\t189\n#define __NR_vfork\t\t190\n#define __NR_ugetrlimit\t\t191\n#define __NR_mmap2\t\t192\n#define __NR_truncate64\t\t193\n#define __NR_ftruncate64\t194\n#define __NR_stat64\t\t195\n#define __NR_lstat64\t\t196\n#define __NR_fstat64\t\t197\n#define __NR_chown32\t\t198\n#define __NR_getuid32\t\t199\n#define __NR_getgid32\t\t200\n#define __NR_geteuid32\t\t201\n#define __NR_getegid32\t\t202\n#define __NR_setreuid32\t\t203\n#define __NR_setregid32\t\t204\n#define __NR_getgroups32\t205\n#define __NR_setgroups32\t206\n#define __NR_fchown32\t\t207\n#define __NR_setresuid32\t208\n#define __NR_getresuid32\t209\n#define __NR_setresgid32\t210\n#define __NR_getresgid32\t211\n#define __NR_lchown32\t\t212\n#define __NR_setuid32\t\t213\n#define __NR_setgid32\t\t214\n#define __NR_setfsuid32\t\t215\n#define __NR_setfsgid32\t\t216\n#define __NR_pivot_root\t\t217\n#define __NR_getdents64\t\t220\n#define __NR_gettid\t\t221\n#define __NR_tkill\t\t222\n#define __NR_setxattr\t\t223\n#define __NR_lsetxattr\t\t224\n#define __NR_fsetxattr\t\t225\n#define __NR_getxattr\t\t226\n#define __NR_lgetxattr\t\t227\n#define __NR_fgetxattr\t\t228\n#define __NR_listxattr\t\t229\n#define __NR_llistxattr\t\t230\n#define __NR_flistxattr\t\t231\n#define __NR_removexattr\t232\n#define __NR_lremovexattr\t233\n#define __NR_fremovexattr\t234\n#define __NR_futex\t\t235\n#define __NR_sendfile64\t\t236\n#define __NR_mincore\t\t237\n#define __NR_madvise\t\t238\n#define __NR_fcntl64\t\t239\n#define __NR_readahead\t\t240\n#define __NR_io_setup\t\t241\n#define __NR_io_destroy\t\t242\n#define __NR_io_getevents\t243\n#define __NR_io_submit\t\t244\n#define __NR_io_cancel\t\t245\n#define __NR_fadvise64\t\t246\n#define __NR_exit_group\t\t247\n#define __NR_lookup_dcookie\t248\n#define __NR_epoll_create\t249\n#define __NR_epoll_ctl\t\t250\n#define __NR_epoll_wait\t\t251\n#define __NR_remap_file_pages\t252\n#define __NR_set_tid_address\t253\n#define __NR_timer_create\t254\n#define __NR_timer_settime32\t255\n#define __NR_timer_gettime32\t256\n#define __NR_timer_getoverrun\t257\n#define __NR_timer_delete\t258\n#define __NR_clock_settime32\t259\n#define __NR_clock_gettime32\t260\n#define __NR_clock_getres_time32\t261\n#define __NR_clock_nanosleep_time32\t262\n#define __NR_statfs64\t\t263\n#define __NR_fstatfs64\t\t264\n#define __NR_tgkill\t\t265\n#define __NR_utimes\t\t266\n#define __NR_fadvise64_64\t267\n#define __NR_mbind\t\t268\n#define __NR_get_mempolicy\t269\n#define __NR_set_mempolicy\t270\n#define __NR_mq_open\t\t271\n#define __NR_mq_unlink\t\t272\n#define __NR_mq_timedsend\t273\n#define __NR_mq_timedreceive\t274\n#define __NR_mq_notify\t\t275\n#define __NR_mq_getsetattr\t276\n#define __NR_waitid\t\t277\n#define __NR_add_key\t\t279\n#define __NR_request_key\t280\n#define __NR_keyctl\t\t281\n#define __NR_ioprio_set\t\t282\n#define __NR_ioprio_get\t\t283\n#define __NR_inotify_init\t284\n#define __NR_inotify_add_watch\t285\n#define __NR_inotify_rm_watch\t286\n#define __NR_migrate_pages\t287\n#define __NR_openat\t\t288\n#define __NR_mkdirat\t\t289\n#define __NR_mknodat\t\t290\n#define __NR_fchownat\t\t291\n#define __NR_futimesat\t\t292\n#define __NR_fstatat64\t\t293\n#define __NR_unlinkat\t\t294\n#define __NR_renameat\t\t295\n#define __NR_linkat\t\t296\n#define __NR_symlinkat\t\t297\n#define __NR_readlinkat\t\t298\n#define __NR_fchmodat\t\t299\n#define __NR_faccessat\t\t300\n#define __NR_pselect6\t\t301\n#define __NR_ppoll\t\t302\n#define __NR_unshare\t\t303\n#define __NR_set_robust_list\t304\n#define __NR_get_robust_list\t305\n#define __NR_splice\t\t306\n#define __NR_sync_file_range\t307\n#define __NR_tee\t\t308\n#define __NR_vmsplice\t\t309\n#define __NR_move_pages\t\t310\n#define __NR_sched_setaffinity\t311\n#define __NR_sched_getaffinity\t312\n#define __NR_kexec_load\t\t313\n#define __NR_getcpu\t\t314\n#define __NR_epoll_pwait\t315\n#define __NR_utimensat\t\t316\n#define __NR_signalfd\t\t317\n#define __NR_timerfd_create\t318\n#define __NR_eventfd\t\t319\n#define __NR_fallocate\t\t320\n#define __NR_timerfd_settime32\t321\n#define __NR_timerfd_gettime32\t322\n#define __NR_signalfd4\t\t323\n#define __NR_eventfd2\t\t324\n#define __NR_epoll_create1\t325\n#define __NR_dup3\t\t326\n#define __NR_pipe2\t\t327\n#define __NR_inotify_init1\t328\n#define __NR_preadv\t\t329\n#define __NR_pwritev\t\t330\n#define __NR_rt_tgsigqueueinfo\t331\n#define __NR_perf_event_open\t332\n#define __NR_get_thread_area\t333\n#define __NR_set_thread_area\t334\n#define __NR_atomic_cmpxchg_32\t335\n#define __NR_atomic_barrier\t336\n#define __NR_fanotify_init\t337\n#define __NR_fanotify_mark\t338\n#define __NR_prlimit64\t\t339\n#define __NR_name_to_handle_at\t340\n#define __NR_open_by_handle_at\t341\n#define __NR_clock_adjtime\t342\n#define __NR_syncfs\t\t343\n#define __NR_setns\t\t344\n#define __NR_process_vm_readv\t345\n#define __NR_process_vm_writev\t346\n#define __NR_kcmp\t\t347\n#define __NR_finit_module\t348\n#define __NR_sched_setattr\t349\n#define __NR_sched_getattr\t350\n#define __NR_renameat2\t\t351\n#define __NR_getrandom\t\t352\n#define __NR_memfd_create\t353\n#define __NR_bpf\t\t354\n#define __NR_execveat\t\t355\n#define __NR_socket\t\t356\n#define __NR_socketpair\t\t357\n#define __NR_bind\t\t358\n#define __NR_connect\t\t359\n#define __NR_listen\t\t360\n#define __NR_accept4\t\t361\n#define __NR_getsockopt\t\t362\n#define __NR_setsockopt\t\t363\n#define __NR_getsockname\t364\n#define __NR_getpeername\t365\n#define __NR_sendto\t\t366\n#define __NR_sendmsg\t\t367\n#define __NR_recvfrom\t\t368\n#define __NR_recvmsg\t\t369\n#define __NR_shutdown\t\t370\n#define __NR_recvmmsg\t\t371\n#define __NR_sendmmsg\t\t372\n#define __NR_userfaultfd\t373\n#define __NR_membarrier\t\t374\n#define __NR_mlock2\t\t375\n#define __NR_copy_file_range\t376\n#define __NR_preadv2\t\t377\n#define __NR_pwritev2\t\t378\n#define __NR_statx\t\t379\n#define __NR_seccomp\t\t380\n#define __NR_pkey_mprotect\t381\n#define __NR_pkey_alloc\t\t382\n#define __NR_pkey_free\t\t383\n#define __NR_rseq\t\t384\n#define __NR_semget\t\t393\n#define __NR_semctl\t\t394\n#define __NR_shmget\t\t395\n#define __NR_shmctl\t\t396\n#define __NR_shmat\t\t397\n#define __NR_shmdt\t\t398\n#define __NR_msgget\t\t399\n#define __NR_msgsnd\t\t400\n#define __NR_msgrcv\t\t401\n#define __NR_msgctl\t\t402\n#define __NR_clock_gettime64\t403\n#define __NR_clock_settime64\t404\n#define __NR_clock_adjtime64\t405\n#define __NR_clock_getres_time64 406\n#define __NR_clock_nanosleep_time64 407\n#define __NR_timer_gettime64\t408\n#define __NR_timer_settime64\t409\n#define __NR_timerfd_gettime64\t410\n#define __NR_timerfd_settime64\t411\n#define __NR_utimensat_time64\t412\n#define __NR_pselect6_time64\t413\n#define __NR_ppoll_time64\t414\n#define __NR_io_pgetevents_time64 416\n#define __NR_recvmmsg_time64\t417\n#define __NR_mq_timedsend_time64 418\n#define __NR_mq_timedreceive_time64 419\n#define __NR_semtimedop_time64\t420\n#define __NR_rt_sigtimedwait_time64 421\n#define __NR_futex_time64\t422\n#define __NR_sched_rr_get_interval_time64 423\n#define __NR_pidfd_send_signal\t424\n#define __NR_io_uring_setup\t425\n#define __NR_io_uring_enter\t426\n#define __NR_io_uring_register\t427\n#define __NR_open_tree\t\t428\n#define __NR_move_mount\t\t429\n#define __NR_fsopen\t\t430\n#define __NR_fsconfig\t\t431\n#define __NR_fsmount\t\t432\n#define __NR_fspick\t\t433\n#define __NR_pidfd_open\t\t434\n#define __NR_clone3\t\t435\n#define __NR_close_range\t436\n#define __NR_openat2\t\t437\n#define __NR_pidfd_getfd\t438\n#define __NR_faccessat2\t\t439\n"
  },
  {
    "path": "user.libc/arch/m68k/bits/user.h",
    "content": "#undef __WORDSIZE\n#define __WORDSIZE 32\n\nstruct user_m68kfp_struct {\n\tunsigned long fpregs[24], fpcntl[3];\n};\n\nstruct user_regs_struct {\n\tlong d1, d2, d3, d4, d5, d6, d7;\n\tlong a0, a1, a2, a3, a4, a5, a6;\n\tlong d0, usp, orig_d0;\n\tshort stkadj, sr;\n\tlong pc;\n\tshort fmtvec, __pad;\n};\n\nstruct user {\n\tstruct user_regs_struct regs;\n\tint u_fpvalid;\n\tstruct user_m68kfp_struct m68kfp;\n\tunsigned long u_tsize, u_dsize, u_ssize, start_code, start_stack;\n\tlong signal;\n\tint reserved;\n\tunsigned long u_ar0;\n\tstruct user_m68kfp_struct *u_fpstate;\n\tunsigned long magic;\n\tchar u_comm[32];\n};\n\n#define ELF_NGREG 20\ntypedef unsigned long elf_greg_t;\ntypedef elf_greg_t elf_gregset_t[ELF_NGREG];\ntypedef struct user_m68kfp_struct elf_fpregset_t;\n\n#define NBPG\t\t\t4096\n#define UPAGES\t\t\t1\n#define HOST_TEXT_START_ADDR\t(u.start_code)\n#define HOST_STACK_END_ADDR\t(u.start_stack + u.u_ssize * NBPG)\n"
  },
  {
    "path": "user.libc/arch/m68k/crt_arch.h",
    "content": "__asm__(\n\".text\\n\"\n\".weak _DYNAMIC \\n\"\n\".hidden _DYNAMIC \\n\"\n\".global \" START \"\\n\"\nSTART \":\\n\"\n\"\tsuba.l %fp,%fp \\n\"\n\"\tmovea.l %sp,%a0 \\n\"\n\"\tlea _DYNAMIC-.-8,%a1 \\n\"\n\"\tpea (%pc,%a1) \\n\"\n\"\tpea (%a0) \\n\"\n\"\tlea \" START \"_c-.-8,%a1 \\n\"\n\"\tjsr (%pc,%a1) \\n\"\n);\n"
  },
  {
    "path": "user.libc/arch/m68k/kstat.h",
    "content": "struct kstat {\n\tdev_t st_dev;\n\tshort __st_dev_padding;\n\tlong __st_ino_truncated;\n\tmode_t st_mode;\n\tnlink_t st_nlink;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tdev_t st_rdev;\n\tshort __st_rdev_padding;\n\toff_t st_size;\n\tblksize_t st_blksize;\n\tblkcnt_t st_blocks;\n\tlong st_atime_sec;\n\tlong st_atime_nsec;\n\tlong st_mtime_sec;\n\tlong st_mtime_nsec;\n\tlong st_ctime_sec;\n\tlong st_ctime_nsec;\n\tino_t st_ino;\n};\n"
  },
  {
    "path": "user.libc/arch/m68k/pthread_arch.h",
    "content": "static inline uintptr_t __get_tp()\n{\n\treturn __syscall(SYS_get_thread_area);\n}\n\n#define TLS_ABOVE_TP\n#define GAP_ABOVE_TP 0\n\n#define TP_OFFSET 0x7000\n#define DTP_OFFSET 0x8000\n\n#define MC_PC gregs[R_PC]\n"
  },
  {
    "path": "user.libc/arch/m68k/reloc.h",
    "content": "#if __HAVE_68881__\n#define FP_SUFFIX \"\"\n#elif __mcffpu__\n#define FP_SUFFIX \"-fp64\"\n#else\n#define FP_SUFFIX \"-sf\"\n#endif\n\n#define LDSO_ARCH \"m68k\" FP_SUFFIX\n\n#define TPOFF_K (-0x7000)\n\n#define REL_SYMBOLIC    R_68K_32\n#define REL_OFFSET      R_68K_PC32\n#define REL_GOT         R_68K_GLOB_DAT\n#define REL_PLT         R_68K_JMP_SLOT\n#define REL_RELATIVE    R_68K_RELATIVE\n#define REL_COPY        R_68K_COPY\n#define REL_DTPMOD      R_68K_TLS_DTPMOD32\n#define REL_DTPOFF      R_68K_TLS_DTPREL32\n#define REL_TPOFF       R_68K_TLS_TPREL32\n\n#define CRTJMP(pc,sp) __asm__ __volatile__( \\\n\t\"move.l %1,%%sp ; jmp (%0)\" : : \"r\"(pc), \"r\"(sp) : \"memory\" )\n\n#define GETFUNCSYM(fp, sym, got) __asm__ ( \\\n\t\".hidden \" #sym \"\\n\" \\\n\t\"lea \" #sym \"-.-8,%0 \\n\" \\\n\t\"lea (%%pc,%0),%0 \\n\" \\\n\t: \"=a\"(*fp) : : \"memory\" )\n"
  },
  {
    "path": "user.libc/arch/m68k/syscall_arch.h",
    "content": "#define __SYSCALL_LL_E(x) \\\n((union { long long ll; long l[2]; }){ .ll = x }).l[0], \\\n((union { long long ll; long l[2]; }){ .ll = x }).l[1]\n#define __SYSCALL_LL_O(x) __SYSCALL_LL_E((x))\n\nstatic __inline long __syscall0(long n)\n{\n\tregister unsigned long d0 __asm__(\"d0\") = n;\n\t__asm__ __volatile__ (\"trap #0\" : \"+r\"(d0)\n\t\t:\n\t\t: \"memory\");\n\treturn d0;\n}\n\nstatic inline long __syscall1(long n, long a)\n{\n\tregister unsigned long d0 __asm__(\"d0\") = n;\n\tregister unsigned long d1 __asm__(\"d1\") = a;\n\t__asm__ __volatile__ (\"trap #0\" : \"+r\"(d0)\n\t\t: \"r\"(d1)\n\t\t: \"memory\");\n\treturn d0;\n}\n\nstatic inline long __syscall2(long n, long a, long b)\n{\n\tregister unsigned long d0 __asm__(\"d0\") = n;\n\tregister unsigned long d1 __asm__(\"d1\") = a;\n\tregister unsigned long d2 __asm__(\"d2\") = b;\n\t__asm__ __volatile__ (\"trap #0\" : \"+r\"(d0)\n\t\t: \"r\"(d1), \"r\"(d2)\n\t\t: \"memory\");\n\treturn d0;\n}\n\nstatic inline long __syscall3(long n, long a, long b, long c)\n{\n\tregister unsigned long d0 __asm__(\"d0\") = n;\n\tregister unsigned long d1 __asm__(\"d1\") = a;\n\tregister unsigned long d2 __asm__(\"d2\") = b;\n\tregister unsigned long d3 __asm__(\"d3\") = c;\n\t__asm__ __volatile__ (\"trap #0\" : \"+r\"(d0)\n\t\t: \"r\"(d1), \"r\"(d2), \"r\"(d3)\n\t\t: \"memory\");\n\treturn d0;\n}\n\nstatic inline long __syscall4(long n, long a, long b, long c, long d)\n{\n\tregister unsigned long d0 __asm__(\"d0\") = n;\n\tregister unsigned long d1 __asm__(\"d1\") = a;\n\tregister unsigned long d2 __asm__(\"d2\") = b;\n\tregister unsigned long d3 __asm__(\"d3\") = c;\n\tregister unsigned long d4 __asm__(\"d4\") = d;\n\t__asm__ __volatile__ (\"trap #0\" : \"+r\"(d0)\n\t\t: \"r\"(d1), \"r\"(d2), \"r\"(d3), \"r\"(d4)\n\t\t: \"memory\");\n\treturn d0;\n}\n\nstatic inline long __syscall5(long n, long a, long b, long c, long d, long e)\n{\n\tregister unsigned long d0 __asm__(\"d0\") = n;\n\tregister unsigned long d1 __asm__(\"d1\") = a;\n\tregister unsigned long d2 __asm__(\"d2\") = b;\n\tregister unsigned long d3 __asm__(\"d3\") = c;\n\tregister unsigned long d4 __asm__(\"d4\") = d;\n\tregister unsigned long d5 __asm__(\"d5\") = e;\n\t__asm__ __volatile__ (\"trap #0\" : \"+r\"(d0)\n\t\t: \"r\"(d1), \"r\"(d2), \"r\"(d3), \"r\"(d4), \"r\"(d5)\n\t\t: \"memory\");\n\treturn d0;\n}\n\nstatic inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)\n{\n\tregister unsigned long d0 __asm__(\"d0\") = n;\n\tregister unsigned long d1 __asm__(\"d1\") = a;\n\tregister unsigned long d2 __asm__(\"d2\") = b;\n\tregister unsigned long d3 __asm__(\"d3\") = c;\n\tregister unsigned long d4 __asm__(\"d4\") = d;\n\tregister unsigned long d5 __asm__(\"d5\") = e;\n\tregister unsigned long a0 __asm__(\"a0\") = f;\n\t__asm__ __volatile__ (\"trap #0\" : \"+r\"(d0)\n\t\t: \"r\"(d1), \"r\"(d2), \"r\"(d3), \"r\"(d4), \"r\"(d5), \"r\"(a0)\n\t\t: \"memory\");\n\treturn d0;\n}\n\n#define SYSCALL_IPC_BROKEN_MODE\n"
  },
  {
    "path": "user.libc/arch/microblaze/arch.mak",
    "content": "COMPAT_SRC_DIRS = compat/time32\n"
  },
  {
    "path": "user.libc/arch/microblaze/atomic_arch.h",
    "content": "#define a_cas a_cas\nstatic inline int a_cas(volatile int *p, int t, int s)\n{\n\tregister int old, tmp;\n\t__asm__ __volatile__ (\n\t\t\"\taddi %0, r0, 0\\n\"\n\t\t\"1:\tlwx %0, %2, r0\\n\"\n\t\t\"\trsubk %1, %0, %3\\n\"\n\t\t\"\tbnei %1, 1f\\n\"\n\t\t\"\tswx %4, %2, r0\\n\"\n\t\t\"\taddic %1, r0, 0\\n\"\n\t\t\"\tbnei %1, 1b\\n\"\n\t\t\"1:\t\"\n\t\t: \"=&r\"(old), \"=&r\"(tmp)\n\t\t: \"r\"(p), \"r\"(t), \"r\"(s)\n\t\t: \"cc\", \"memory\" );\n\treturn old;\n}\n\n#define a_swap a_swap\nstatic inline int a_swap(volatile int *x, int v)\n{\n\tregister int old, tmp;\n\t__asm__ __volatile__ (\n\t\t\"\taddi %0, r0, 0\\n\"\n\t\t\"1:\tlwx %0, %2, r0\\n\"\n\t\t\"\tswx %3, %2, r0\\n\"\n\t\t\"\taddic %1, r0, 0\\n\"\n\t\t\"\tbnei %1, 1b\\n\"\n\t\t\"1:\t\"\n\t\t: \"=&r\"(old), \"=&r\"(tmp)\n\t\t: \"r\"(x), \"r\"(v)\n\t\t: \"cc\", \"memory\" );\n\treturn old;\n}\n\n#define a_fetch_add a_fetch_add\nstatic inline int a_fetch_add(volatile int *x, int v)\n{\n\tregister int new, tmp;\n\t__asm__ __volatile__ (\n\t\t\"\taddi %0, r0, 0\\n\"\n\t\t\"1:\tlwx %0, %2, r0\\n\"\n\t\t\"\taddk %0, %0, %3\\n\"\n\t\t\"\tswx %0, %2, r0\\n\"\n\t\t\"\taddic %1, r0, 0\\n\"\n\t\t\"\tbnei %1, 1b\\n\"\n\t\t\"1:\t\"\n\t\t: \"=&r\"(new), \"=&r\"(tmp)\n\t\t: \"r\"(x), \"r\"(v)\n\t\t: \"cc\", \"memory\" );\n\treturn new-v;\n}\n"
  },
  {
    "path": "user.libc/arch/microblaze/bits/alltypes.h.in",
    "content": "#define _REDIR_TIME64 1\n#define _Addr int\n#define _Int64 long long\n#define _Reg int\n\n#if __MICROBLAZEEL__\n#define __BYTE_ORDER 1234\n#else\n#define __BYTE_ORDER 4321\n#endif\n\n#define __LONG_MAX 0x7fffffffL\n\n#ifndef __cplusplus\nTYPEDEF int wchar_t;\n#endif\n\nTYPEDEF float float_t;\nTYPEDEF double double_t;\n\nTYPEDEF struct { long long __ll; long double __ld; } max_align_t;\n"
  },
  {
    "path": "user.libc/arch/microblaze/bits/float.h",
    "content": "#define FLT_EVAL_METHOD 0\n\n#define LDBL_TRUE_MIN 4.94065645841246544177e-324L\n#define LDBL_MIN 2.22507385850720138309e-308L\n#define LDBL_MAX 1.79769313486231570815e+308L\n#define LDBL_EPSILON 2.22044604925031308085e-16L\n\n#define LDBL_MANT_DIG 53\n#define LDBL_MIN_EXP (-1021)\n#define LDBL_MAX_EXP 1024\n\n#define LDBL_DIG 15\n#define LDBL_MIN_10_EXP (-307)\n#define LDBL_MAX_10_EXP 308\n\n#define DECIMAL_DIG 17\n"
  },
  {
    "path": "user.libc/arch/microblaze/bits/ipcstat.h",
    "content": "#define IPC_STAT 0x102\n"
  },
  {
    "path": "user.libc/arch/microblaze/bits/msg.h",
    "content": "struct msqid_ds {\n\tstruct ipc_perm msg_perm;\n\tunsigned long __msg_stime_lo;\n\tunsigned long __msg_stime_hi;\n\tunsigned long __msg_rtime_lo;\n\tunsigned long __msg_rtime_hi;\n\tunsigned long __msg_ctime_lo;\n\tunsigned long __msg_ctime_hi;\n\tunsigned long msg_cbytes;\n\tmsgqnum_t msg_qnum;\n\tmsglen_t msg_qbytes;\n\tpid_t msg_lspid;\n\tpid_t msg_lrpid;\n\tunsigned long __unused[2];\n\ttime_t msg_stime;\n\ttime_t msg_rtime;\n\ttime_t msg_ctime;\n};\n"
  },
  {
    "path": "user.libc/arch/microblaze/bits/posix.h",
    "content": "#define _POSIX_V6_ILP32_OFFBIG  1\n#define _POSIX_V7_ILP32_OFFBIG  1\n"
  },
  {
    "path": "user.libc/arch/microblaze/bits/reg.h",
    "content": "#undef __WORDSIZE\n#define __WORDSIZE 32\n/* FIXME */\n"
  },
  {
    "path": "user.libc/arch/microblaze/bits/sem.h",
    "content": "struct semid_ds {\n\tstruct ipc_perm sem_perm;\n\tunsigned long __sem_otime_lo;\n\tunsigned long __sem_otime_hi;\n\tunsigned long __sem_ctime_lo;\n\tunsigned long __sem_ctime_hi;\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n\tunsigned short sem_nsems;\n\tchar __sem_nsems_pad[sizeof(long)-sizeof(short)];\n#else\n\tchar __sem_nsems_pad[sizeof(long)-sizeof(short)];\n\tunsigned short sem_nsems;\n#endif\n\tlong __unused3;\n\tlong __unused4;\n\ttime_t sem_otime;\n\ttime_t sem_ctime;\n};\n"
  },
  {
    "path": "user.libc/arch/microblaze/bits/setjmp.h",
    "content": "typedef unsigned long __jmp_buf[18];\n"
  },
  {
    "path": "user.libc/arch/microblaze/bits/shm.h",
    "content": "#define SHMLBA 4096\n\nstruct shmid_ds {\n\tstruct ipc_perm shm_perm;\n\tsize_t shm_segsz;\n\tunsigned long __shm_atime_lo;\n\tunsigned long __shm_atime_hi;\n\tunsigned long __shm_dtime_lo;\n\tunsigned long __shm_dtime_hi;\n\tunsigned long __shm_ctime_lo;\n\tunsigned long __shm_ctime_hi;\n\tpid_t shm_cpid;\n\tpid_t shm_lpid;\n\tunsigned long shm_nattch;\n\tunsigned long __pad1;\n\tunsigned long __pad2;\n\tunsigned long __pad3;\n\ttime_t shm_atime;\n\ttime_t shm_dtime;\n\ttime_t shm_ctime;\n};\n\nstruct shminfo {\n\tunsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];\n};\n\nstruct shm_info {\n\tint __used_ids;\n\tunsigned long shm_tot, shm_rss, shm_swp;\n\tunsigned long __swap_attempts, __swap_successes;\n};\n"
  },
  {
    "path": "user.libc/arch/microblaze/bits/signal.h",
    "content": "#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define MINSIGSTKSZ 2048\n#define SIGSTKSZ 8192\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\ntypedef unsigned long greg_t, gregset_t[38];\ntypedef struct sigcontext {\n\tstruct {\n\t\tunsigned long r0, r1, r2, r3, r4, r5, r6, r7;\n\t\tunsigned long r8, r9, r10, r11, r12, r13, r14, r15;\n\t\tunsigned long r16, r17, r18, r19, r20, r21, r22, r23;\n\t\tunsigned long r24, r25, r26, r27, r28, r29, r30, r31;\n\t\tunsigned long pc, msr, ear, esr, fsr;\n\t\tint pt_mode;\n\t} regs;\n\tunsigned long oldmask;\n} mcontext_t;\n#else\ntypedef struct {\n\tunsigned long __regs[39];\n} mcontext_t;\n#endif\n\nstruct sigaltstack {\n\tvoid *ss_sp;\n\tint ss_flags;\n\tsize_t ss_size;\n};\n\ntypedef struct __ucontext {\n\tunsigned long uc_flags;\n\tstruct __ucontext *uc_link;\n\tstack_t uc_stack;\n\tmcontext_t uc_mcontext;\n\tsigset_t uc_sigmask;\n} ucontext_t;\n\n#define SA_NOCLDSTOP  1\n#define SA_NOCLDWAIT  2\n#define SA_SIGINFO    4\n#define SA_ONSTACK    0x08000000\n#define SA_RESTART    0x10000000\n#define SA_NODEFER    0x40000000\n#define SA_RESETHAND  0x80000000\n#define SA_RESTORER   0x04000000\n\n#endif\n\n#define SIGHUP    1\n#define SIGINT    2\n#define SIGQUIT   3\n#define SIGILL    4\n#define SIGTRAP   5\n#define SIGABRT   6\n#define SIGIOT    SIGABRT\n#define SIGBUS    7\n#define SIGFPE    8\n#define SIGKILL   9\n#define SIGUSR1   10\n#define SIGSEGV   11\n#define SIGUSR2   12\n#define SIGPIPE   13\n#define SIGALRM   14\n#define SIGTERM   15\n#define SIGSTKFLT 16\n#define SIGCHLD   17\n#define SIGCONT   18\n#define SIGSTOP   19\n#define SIGTSTP   20\n#define SIGTTIN   21\n#define SIGTTOU   22\n#define SIGURG    23\n#define SIGXCPU   24\n#define SIGXFSZ   25\n#define SIGVTALRM 26\n#define SIGPROF   27\n#define SIGWINCH  28\n#define SIGIO     29\n#define SIGPOLL   29\n#define SIGPWR    30\n#define SIGSYS    31\n#define SIGUNUSED SIGSYS\n\n#define _NSIG 65\n"
  },
  {
    "path": "user.libc/arch/microblaze/bits/stat.h",
    "content": "/* copied from kernel definition, but with padding replaced\n * by the corresponding correctly-sized userspace types. */\n\nstruct stat {\n\tdev_t st_dev;\n\tino_t st_ino;\n\tmode_t st_mode;\n\tnlink_t st_nlink;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tdev_t st_rdev;\n\tlong long __st_rdev_padding;\n\toff_t st_size;\n\tblksize_t st_blksize;\n\tint __st_blksize_padding;\n\tblkcnt_t st_blocks;\n\tstruct {\n\t\tlong tv_sec;\n\t\tlong tv_nsec;\n\t} __st_atim32, __st_mtim32, __st_ctim32;\n\tunsigned __unused[2];\n\tstruct timespec st_atim;\n\tstruct timespec st_mtim;\n\tstruct timespec st_ctim;\n};\n"
  },
  {
    "path": "user.libc/arch/microblaze/bits/stdint.h",
    "content": "typedef int32_t int_fast16_t;\ntypedef int32_t int_fast32_t;\ntypedef uint32_t uint_fast16_t;\ntypedef uint32_t uint_fast32_t;\n\n#define INT_FAST16_MIN  INT32_MIN\n#define INT_FAST32_MIN  INT32_MIN\n\n#define INT_FAST16_MAX  INT32_MAX\n#define INT_FAST32_MAX  INT32_MAX\n\n#define UINT_FAST16_MAX UINT32_MAX\n#define UINT_FAST32_MAX UINT32_MAX\n\n#define INTPTR_MIN      INT32_MIN\n#define INTPTR_MAX      INT32_MAX\n#define UINTPTR_MAX     UINT32_MAX\n#define PTRDIFF_MIN     INT32_MIN\n#define PTRDIFF_MAX     INT32_MAX\n#define SIZE_MAX        UINT32_MAX\n"
  },
  {
    "path": "user.libc/arch/microblaze/bits/syscall.h.in",
    "content": "#define __NR_restart_syscall 0\n#define __NR_exit 1\n#define __NR_fork 2\n#define __NR_read 3\n#define __NR_write 4\n#define __NR_open 5\n#define __NR_close 6\n#define __NR_waitpid 7\n#define __NR_creat 8\n#define __NR_link 9\n#define __NR_unlink 10\n#define __NR_execve 11\n#define __NR_chdir 12\n#define __NR_time 13\n#define __NR_mknod 14\n#define __NR_chmod 15\n#define __NR_lchown 16\n#define __NR_break 17\n#define __NR_oldstat 18\n#define __NR_lseek 19\n#define __NR_getpid 20\n#define __NR_mount 21\n#define __NR_umount 22\n#define __NR_setuid 23\n#define __NR_getuid 24\n#define __NR_stime 25\n#define __NR_ptrace 26\n#define __NR_alarm 27\n#define __NR_oldfstat 28\n#define __NR_pause 29\n#define __NR_utime 30\n#define __NR_stty 31\n#define __NR_gtty 32\n#define __NR_access 33\n#define __NR_nice 34\n#define __NR_ftime 35\n#define __NR_sync 36\n#define __NR_kill 37\n#define __NR_rename 38\n#define __NR_mkdir 39\n#define __NR_rmdir 40\n#define __NR_dup 41\n#define __NR_pipe 42\n#define __NR_times 43\n#define __NR_prof 44\n#define __NR_brk 45\n#define __NR_setgid 46\n#define __NR_getgid 47\n#define __NR_signal 48\n#define __NR_geteuid 49\n#define __NR_getegid 50\n#define __NR_acct 51\n#define __NR_umount2 52\n#define __NR_lock 53\n#define __NR_ioctl 54\n#define __NR_fcntl 55\n#define __NR_mpx 56\n#define __NR_setpgid 57\n#define __NR_ulimit 58\n#define __NR_oldolduname 59\n#define __NR_umask 60\n#define __NR_chroot 61\n#define __NR_ustat 62\n#define __NR_dup2 63\n#define __NR_getppid 64\n#define __NR_getpgrp 65\n#define __NR_setsid 66\n#define __NR_sigaction 67\n#define __NR_sgetmask 68\n#define __NR_ssetmask 69\n#define __NR_setreuid 70\n#define __NR_setregid 71\n#define __NR_sigsuspend 72\n#define __NR_sigpending 73\n#define __NR_sethostname 74\n#define __NR_setrlimit 75\n#define __NR_getrlimit 76\n#define __NR_getrusage 77\n#define __NR_gettimeofday_time32 78\n#define __NR_settimeofday_time32 79\n#define __NR_getgroups 80\n#define __NR_setgroups 81\n#define __NR_select 82\n#define __NR_symlink 83\n#define __NR_oldlstat 84\n#define __NR_readlink 85\n#define __NR_uselib 86\n#define __NR_swapon 87\n#define __NR_reboot 88\n#define __NR_readdir 89\n#define __NR_mmap 90\n#define __NR_munmap 91\n#define __NR_truncate 92\n#define __NR_ftruncate 93\n#define __NR_fchmod 94\n#define __NR_fchown 95\n#define __NR_getpriority 96\n#define __NR_setpriority 97\n#define __NR_profil 98\n#define __NR_statfs 99\n#define __NR_fstatfs 100\n#define __NR_ioperm 101\n#define __NR_socketcall 102\n#define __NR_syslog 103\n#define __NR_setitimer 104\n#define __NR_getitimer 105\n#define __NR_stat 106\n#define __NR_lstat 107\n#define __NR_fstat 108\n#define __NR_olduname 109\n#define __NR_iopl 110\n#define __NR_vhangup 111\n#define __NR_idle 112\n#define __NR_vm86old 113\n#define __NR_wait4 114\n#define __NR_swapoff 115\n#define __NR_sysinfo 116\n#define __NR_ipc 117\n#define __NR_fsync 118\n#define __NR_sigreturn 119\n#define __NR_clone 120\n#define __NR_setdomainname 121\n#define __NR_uname 122\n#define __NR_modify_ldt 123\n#define __NR_adjtimex 124\n#define __NR_mprotect 125\n#define __NR_sigprocmask 126\n#define __NR_create_module 127\n#define __NR_init_module 128\n#define __NR_delete_module 129\n#define __NR_get_kernel_syms 130\n#define __NR_quotactl 131\n#define __NR_getpgid 132\n#define __NR_fchdir 133\n#define __NR_bdflush 134\n#define __NR_sysfs 135\n#define __NR_personality 136\n#define __NR_afs_syscall 137\n#define __NR_setfsuid 138\n#define __NR_setfsgid 139\n#define __NR__llseek 140\n#define __NR_getdents 141\n#define __NR__newselect 142\n#define __NR_flock 143\n#define __NR_msync 144\n#define __NR_readv 145\n#define __NR_writev 146\n#define __NR_getsid 147\n#define __NR_fdatasync 148\n#define __NR__sysctl 149\n#define __NR_mlock 150\n#define __NR_munlock 151\n#define __NR_mlockall 152\n#define __NR_munlockall 153\n#define __NR_sched_setparam 154\n#define __NR_sched_getparam 155\n#define __NR_sched_setscheduler 156\n#define __NR_sched_getscheduler 157\n#define __NR_sched_yield 158\n#define __NR_sched_get_priority_max 159\n#define __NR_sched_get_priority_min 160\n#define __NR_sched_rr_get_interval 161\n#define __NR_nanosleep 162\n#define __NR_mremap 163\n#define __NR_setresuid 164\n#define __NR_getresuid 165\n#define __NR_vm86 166\n#define __NR_query_module 167\n#define __NR_poll 168\n#define __NR_nfsservctl 169\n#define __NR_setresgid 170\n#define __NR_getresgid 171\n#define __NR_prctl 172\n#define __NR_rt_sigreturn 173\n#define __NR_rt_sigaction 174\n#define __NR_rt_sigprocmask 175\n#define __NR_rt_sigpending 176\n#define __NR_rt_sigtimedwait 177\n#define __NR_rt_sigqueueinfo 178\n#define __NR_rt_sigsuspend 179\n#define __NR_pread64 180\n#define __NR_pwrite64 181\n#define __NR_chown 182\n#define __NR_getcwd 183\n#define __NR_capget 184\n#define __NR_capset 185\n#define __NR_sigaltstack 186\n#define __NR_sendfile 187\n#define __NR_getpmsg 188\n#define __NR_putpmsg 189\n#define __NR_vfork 190\n#define __NR_ugetrlimit 191\n#define __NR_mmap2 192\n#define __NR_truncate64 193\n#define __NR_ftruncate64 194\n#define __NR_stat64 195\n#define __NR_lstat64 196\n#define __NR_fstat64 197\n#define __NR_lchown32 198\n#define __NR_getuid32 199\n#define __NR_getgid32 200\n#define __NR_geteuid32 201\n#define __NR_getegid32 202\n#define __NR_setreuid32 203\n#define __NR_setregid32 204\n#define __NR_getgroups32 205\n#define __NR_setgroups32 206\n#define __NR_fchown32 207\n#define __NR_setresuid32 208\n#define __NR_getresuid32 209\n#define __NR_setresgid32 210\n#define __NR_getresgid32 211\n#define __NR_chown32 212\n#define __NR_setuid32 213\n#define __NR_setgid32 214\n#define __NR_setfsuid32 215\n#define __NR_setfsgid32 216\n#define __NR_pivot_root 217\n#define __NR_mincore 218\n#define __NR_madvise 219\n#define __NR_getdents64 220\n#define __NR_fcntl64 221\n#define __NR_gettid 224\n#define __NR_readahead 225\n#define __NR_setxattr 226\n#define __NR_lsetxattr 227\n#define __NR_fsetxattr 228\n#define __NR_getxattr 229\n#define __NR_lgetxattr 230\n#define __NR_fgetxattr 231\n#define __NR_listxattr 232\n#define __NR_llistxattr 233\n#define __NR_flistxattr 234\n#define __NR_removexattr 235\n#define __NR_lremovexattr 236\n#define __NR_fremovexattr 237\n#define __NR_tkill 238\n#define __NR_sendfile64 239\n#define __NR_futex 240\n#define __NR_sched_setaffinity 241\n#define __NR_sched_getaffinity 242\n#define __NR_set_thread_area 243\n#define __NR_get_thread_area 244\n#define __NR_io_setup 245\n#define __NR_io_destroy 246\n#define __NR_io_getevents 247\n#define __NR_io_submit 248\n#define __NR_io_cancel 249\n#define __NR_fadvise64 250\n#define __NR_exit_group 252\n#define __NR_lookup_dcookie 253\n#define __NR_epoll_create 254\n#define __NR_epoll_ctl 255\n#define __NR_epoll_wait 256\n#define __NR_remap_file_pages 257\n#define __NR_set_tid_address 258\n#define __NR_timer_create 259\n#define __NR_timer_settime32 260\n#define __NR_timer_gettime32 261\n#define __NR_timer_getoverrun 262\n#define __NR_timer_delete 263\n#define __NR_clock_settime32 264\n#define __NR_clock_gettime32 265\n#define __NR_clock_getres_time32 266\n#define __NR_clock_nanosleep_time32 267\n#define __NR_statfs64 268\n#define __NR_fstatfs64 269\n#define __NR_tgkill 270\n#define __NR_utimes 271\n#define __NR_fadvise64_64 272\n#define __NR_vserver 273\n#define __NR_mbind 274\n#define __NR_get_mempolicy 275\n#define __NR_set_mempolicy 276\n#define __NR_mq_open 277\n#define __NR_mq_unlink 278\n#define __NR_mq_timedsend 279\n#define __NR_mq_timedreceive 280\n#define __NR_mq_notify 281\n#define __NR_mq_getsetattr 282\n#define __NR_kexec_load 283\n#define __NR_waitid 284\n#define __NR_add_key 286\n#define __NR_request_key 287\n#define __NR_keyctl 288\n#define __NR_ioprio_set 289\n#define __NR_ioprio_get 290\n#define __NR_inotify_init 291\n#define __NR_inotify_add_watch 292\n#define __NR_inotify_rm_watch 293\n#define __NR_migrate_pages 294\n#define __NR_openat 295\n#define __NR_mkdirat 296\n#define __NR_mknodat 297\n#define __NR_fchownat 298\n#define __NR_futimesat 299\n#define __NR_fstatat64 300\n#define __NR_unlinkat 301\n#define __NR_renameat 302\n#define __NR_linkat 303\n#define __NR_symlinkat 304\n#define __NR_readlinkat 305\n#define __NR_fchmodat 306\n#define __NR_faccessat 307\n#define __NR_pselect6 308\n#define __NR_ppoll 309\n#define __NR_unshare 310\n#define __NR_set_robust_list 311\n#define __NR_get_robust_list 312\n#define __NR_splice 313\n#define __NR_sync_file_range 314\n#define __NR_tee 315\n#define __NR_vmsplice 316\n#define __NR_move_pages 317\n#define __NR_getcpu 318\n#define __NR_epoll_pwait 319\n#define __NR_utimensat 320\n#define __NR_signalfd 321\n#define __NR_timerfd_create 322\n#define __NR_eventfd 323\n#define __NR_fallocate 324\n#define __NR_semtimedop 325\n#define __NR_timerfd_settime32 326\n#define __NR_timerfd_gettime32 327\n#define __NR_semctl 328\n#define __NR_semget 329\n#define __NR_semop 330\n#define __NR_msgctl 331\n#define __NR_msgget 332\n#define __NR_msgrcv 333\n#define __NR_msgsnd 334\n#define __NR_shmat 335\n#define __NR_shmctl 336\n#define __NR_shmdt 337\n#define __NR_shmget 338\n#define __NR_signalfd4 339\n#define __NR_eventfd2 340\n#define __NR_epoll_create1 341\n#define __NR_dup3 342\n#define __NR_pipe2 343\n#define __NR_inotify_init1 344\n#define __NR_socket 345\n#define __NR_socketpair 346\n#define __NR_bind 347\n#define __NR_listen 348\n#define __NR_accept 349\n#define __NR_connect 350\n#define __NR_getsockname 351\n#define __NR_getpeername 352\n#define __NR_sendto 353\n#define __NR_send 354\n#define __NR_recvfrom 355\n#define __NR_recv 356\n#define __NR_setsockopt 357\n#define __NR_getsockopt 358\n#define __NR_shutdown 359\n#define __NR_sendmsg 360\n#define __NR_recvmsg 361\n#define __NR_accept4 362\n#define __NR_preadv 363\n#define __NR_pwritev 364\n#define __NR_rt_tgsigqueueinfo 365\n#define __NR_perf_event_open 366\n#define __NR_recvmmsg 367\n#define __NR_fanotify_init 368\n#define __NR_fanotify_mark 369\n#define __NR_prlimit64 370\n#define __NR_name_to_handle_at 371\n#define __NR_open_by_handle_at 372\n#define __NR_clock_adjtime 373\n#define __NR_syncfs 374\n#define __NR_setns 375\n#define __NR_sendmmsg 376\n#define __NR_process_vm_readv 377\n#define __NR_process_vm_writev 378\n#define __NR_kcmp 379\n#define __NR_finit_module 380\n#define __NR_sched_setattr 381\n#define __NR_sched_getattr 382\n#define __NR_renameat2 383\n#define __NR_seccomp 384\n#define __NR_getrandom 385\n#define __NR_memfd_create 386\n#define __NR_bpf 387\n#define __NR_execveat 388\n#define __NR_userfaultfd 389\n#define __NR_membarrier 390\n#define __NR_mlock2 391\n#define __NR_copy_file_range 392\n#define __NR_preadv2 393\n#define __NR_pwritev2 394\n#define __NR_pkey_mprotect 395\n#define __NR_pkey_alloc 396\n#define __NR_pkey_free 397\n#define __NR_statx 398\n#define __NR_io_pgetevents 399\n#define __NR_rseq 400\n#define __NR_clock_gettime64 403\n#define __NR_clock_settime64 404\n#define __NR_clock_adjtime64 405\n#define __NR_clock_getres_time64 406\n#define __NR_clock_nanosleep_time64 407\n#define __NR_timer_gettime64 408\n#define __NR_timer_settime64 409\n#define __NR_timerfd_gettime64 410\n#define __NR_timerfd_settime64 411\n#define __NR_utimensat_time64 412\n#define __NR_pselect6_time64 413\n#define __NR_ppoll_time64 414\n#define __NR_io_pgetevents_time64 416\n#define __NR_recvmmsg_time64 417\n#define __NR_mq_timedsend_time64 418\n#define __NR_mq_timedreceive_time64 419\n#define __NR_semtimedop_time64 420\n#define __NR_rt_sigtimedwait_time64 421\n#define __NR_futex_time64 422\n#define __NR_sched_rr_get_interval_time64 423\n#define __NR_pidfd_send_signal 424\n#define __NR_io_uring_setup 425\n#define __NR_io_uring_enter 426\n#define __NR_io_uring_register 427\n#define __NR_open_tree\t\t428\n#define __NR_move_mount\t\t429\n#define __NR_fsopen\t\t430\n#define __NR_fsconfig\t\t431\n#define __NR_fsmount\t\t432\n#define __NR_fspick\t\t433\n#define __NR_pidfd_open\t\t434\n#define __NR_clone3\t\t435\n#define __NR_close_range\t436\n#define __NR_openat2\t\t437\n#define __NR_pidfd_getfd\t438\n#define __NR_faccessat2\t\t439\n\n"
  },
  {
    "path": "user.libc/arch/microblaze/bits/user.h",
    "content": "struct user_fpregs_struct {\n\tlong cwd, swd, twd, fip, fcs, foo, fos, st_space[20];\n};\n\nstruct user_regs_struct {\n\tunsigned grp[32], pc, msr, ear, esr, fsr, btr, pvr[12];\n};\n\nstruct user {\n\tstruct user_regs_struct regs;\n\tint u_fpvalid;\n\tstruct user_fpregs_struct elf_fpregset_t;\n\tunsigned long u_tsize, u_dsize, u_ssize, start_code, start_stack;\n\tlong signal;\n\tint reserved;\n\tstruct user_regs_struct *u_ar0;\n\tstruct user_fpregs_struct *u_fpstate;\n\tunsigned long magic;\n\tchar u_comm[32];\n\tint u_debugreg[8];\n};\n\n#define ELF_NGREG 50\ntypedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG];\ntypedef struct user_fpregs_struct elf_fpregset_t;\n"
  },
  {
    "path": "user.libc/arch/microblaze/crt_arch.h",
    "content": "__asm__(\n\".text \\n\"\n\".global \" START \" \\n\"\n\".align  2 \\n\"\nSTART \": \\n\"\n\"\tadd r19, r0, r0 \\n\"\n\"\tori r5, r1, 0 \\n\"\n\"1:\tmfs r6, rpc \\n\"\n\".weak _DYNAMIC \\n\"\n\".hidden _DYNAMIC \\n\"\n\"\taddik r6, r6, _GLOBAL_OFFSET_TABLE_+8 \\n\"\n\"\taddik r6, r6, _DYNAMIC@GOTOFF \\n\"\n\"\tandi r1, r1, -8 \\n\"\n\"\taddik r1, r1, -8 \\n\"\n\"\tbri \" START \"_c \\n\"\n\"\tnop \\n\"\n);\n"
  },
  {
    "path": "user.libc/arch/microblaze/kstat.h",
    "content": "struct kstat {\n\tdev_t st_dev;\n\tino_t st_ino;\n\tmode_t st_mode;\n\tnlink_t st_nlink;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tdev_t st_rdev;\n\tlong long __st_rdev_padding;\n\toff_t st_size;\n\tblksize_t st_blksize;\n\tint __st_blksize_padding;\n\tblkcnt_t st_blocks;\n\tlong st_atime_sec;\n\tlong st_atime_nsec;\n\tlong st_mtime_sec;\n\tlong st_mtime_nsec;\n\tlong st_ctime_sec;\n\tlong st_ctime_nsec;\n\tunsigned __unused[2];\n};\n"
  },
  {
    "path": "user.libc/arch/microblaze/pthread_arch.h",
    "content": "static inline uintptr_t __get_tp()\n{\n\tuintptr_t tp;\n\t__asm__ (\"ori %0, r21, 0\" : \"=r\" (tp) );\n\treturn tp;\n}\n\n#define MC_PC regs.pc\n"
  },
  {
    "path": "user.libc/arch/microblaze/reloc.h",
    "content": "#if __BYTE_ORDER == __LITTLE_ENDIAN\n#define ENDIAN_SUFFIX \"el\"\n#else\n#define ENDIAN_SUFFIX \"\"\n#endif\n\n#define LDSO_ARCH \"microblaze\" ENDIAN_SUFFIX\n\n#define TPOFF_K 0\n\n#define REL_SYMBOLIC    R_MICROBLAZE_32\n#define REL_GOT         R_MICROBLAZE_GLOB_DAT\n#define REL_PLT         R_MICROBLAZE_JUMP_SLOT\n#define REL_RELATIVE    R_MICROBLAZE_REL\n#define REL_COPY        R_MICROBLAZE_COPY\n#define REL_DTPMOD      R_MICROBLAZE_TLSDTPMOD32\n#define REL_DTPOFF      R_MICROBLAZE_TLSDTPREL32\n\n#define CRTJMP(pc,sp) __asm__ __volatile__( \\\n\t\"addik r1,%1,0 ; bra %0\" : : \"r\"(pc), \"r\"(sp) : \"memory\" )\n\n#define GETFUNCSYM(fp, sym, got) __asm__ ( \\\n\t\".hidden \" #sym \" \\n\" \\\n\t\"\tmfs %0, rpc \\n\" \\\n\t\"\taddik %0, %0, _GLOBAL_OFFSET_TABLE_+8 \\n\" \\\n\t\"\taddik %0, %0, \" #sym \"@GOTOFF \\n\" \\\n\t: \"=r\"(*(fp)) : : \"memory\" )\n"
  },
  {
    "path": "user.libc/arch/microblaze/syscall_arch.h",
    "content": "#define __SYSCALL_LL_E(x) \\\n((union { long long ll; long l[2]; }){ .ll = x }).l[0], \\\n((union { long long ll; long l[2]; }){ .ll = x }).l[1]\n#define __SYSCALL_LL_O(x) __SYSCALL_LL_E((x))\n\nstatic __inline long __syscall0(long n)\n{\n\tregister unsigned long r12 __asm__(\"r12\") = n;\n\tregister unsigned long r3 __asm__(\"r3\");\n\t__asm__ __volatile__ (\"brki r14, 0x8\" : \"=r\"(r3)\n\t\t: \"r\"(r12)\n\t\t: \"memory\", \"r4\");\n\treturn r3;\n}\n\nstatic inline long __syscall1(long n, long a)\n{\n\tregister unsigned long r12 __asm__(\"r12\") = n;\n\tregister unsigned long r3 __asm__(\"r3\");\n\tregister unsigned long r5 __asm__(\"r5\") = a;\n\t__asm__ __volatile__ (\"brki r14, 0x8\" : \"=r\"(r3)\n\t\t: \"r\"(r12), \"r\"(r5)\n\t\t: \"memory\", \"r4\");\n\treturn r3;\n}\n\nstatic inline long __syscall2(long n, long a, long b)\n{\n\tregister unsigned long r12 __asm__(\"r12\") = n;\n\tregister unsigned long r3 __asm__(\"r3\");\n\tregister unsigned long r5 __asm__(\"r5\") = a;\n\tregister unsigned long r6 __asm__(\"r6\") = b;\n\t__asm__ __volatile__ (\"brki r14, 0x8\" : \"=r\"(r3)\n\t\t: \"r\"(r12), \"r\"(r5), \"r\"(r6)\n\t\t: \"memory\", \"r4\");\n\treturn r3;\n}\n\nstatic inline long __syscall3(long n, long a, long b, long c)\n{\n\tregister unsigned long r12 __asm__(\"r12\") = n;\n\tregister unsigned long r3 __asm__(\"r3\");\n\tregister unsigned long r5 __asm__(\"r5\") = a;\n\tregister unsigned long r6 __asm__(\"r6\") = b;\n\tregister unsigned long r7 __asm__(\"r7\") = c;\n\t__asm__ __volatile__ (\"brki r14, 0x8\" : \"=r\"(r3)\n\t\t: \"r\"(r12), \"r\"(r5), \"r\"(r6), \"r\"(r7)\n\t\t: \"memory\", \"r4\");\n\treturn r3;\n}\n\nstatic inline long __syscall4(long n, long a, long b, long c, long d)\n{\n\tregister unsigned long r12 __asm__(\"r12\") = n;\n\tregister unsigned long r3 __asm__(\"r3\");\n\tregister unsigned long r5 __asm__(\"r5\") = a;\n\tregister unsigned long r6 __asm__(\"r6\") = b;\n\tregister unsigned long r7 __asm__(\"r7\") = c;\n\tregister unsigned long r8 __asm__(\"r8\") = d;\n\t__asm__ __volatile__ (\"brki r14, 0x8\" : \"=r\"(r3)\n\t\t: \"r\"(r12), \"r\"(r5), \"r\"(r6), \"r\"(r7), \"r\"(r8)\n\t\t: \"memory\", \"r4\");\n\treturn r3;\n}\n\nstatic inline long __syscall5(long n, long a, long b, long c, long d, long e)\n{\n\tregister unsigned long r12 __asm__(\"r12\") = n;\n\tregister unsigned long r3 __asm__(\"r3\");\n\tregister unsigned long r5 __asm__(\"r5\") = a;\n\tregister unsigned long r6 __asm__(\"r6\") = b;\n\tregister unsigned long r7 __asm__(\"r7\") = c;\n\tregister unsigned long r8 __asm__(\"r8\") = d;\n\tregister unsigned long r9 __asm__(\"r9\") = e;\n\t__asm__ __volatile__ (\"brki r14, 0x8\" : \"=r\"(r3)\n\t\t: \"r\"(r12), \"r\"(r5), \"r\"(r6), \"r\"(r7), \"r\"(r8), \"r\"(r9)\n\t\t: \"memory\", \"r4\");\n\treturn r3;\n}\n\nstatic inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)\n{\n\tregister unsigned long r12 __asm__(\"r12\") = n;\n\tregister unsigned long r3 __asm__(\"r3\");\n\tregister unsigned long r5 __asm__(\"r5\") = a;\n\tregister unsigned long r6 __asm__(\"r6\") = b;\n\tregister unsigned long r7 __asm__(\"r7\") = c;\n\tregister unsigned long r8 __asm__(\"r8\") = d;\n\tregister unsigned long r9 __asm__(\"r9\") = e;\n\tregister unsigned long r10 __asm__(\"r10\") = f;\n\t__asm__ __volatile__ (\"brki r14, 0x8\" : \"=r\"(r3)\n\t\t: \"r\"(r12), \"r\"(r5), \"r\"(r6), \"r\"(r7), \"r\"(r8), \"r\"(r9), \"r\"(r10)\n\t\t: \"memory\", \"r4\");\n\treturn r3;\n}\n\n#define SYSCALL_IPC_BROKEN_MODE\n\n#undef SYS_socketcall\n"
  },
  {
    "path": "user.libc/arch/mips/arch.mak",
    "content": "COMPAT_SRC_DIRS = compat/time32\n"
  },
  {
    "path": "user.libc/arch/mips/atomic_arch.h",
    "content": "#if __mips_isa_rev < 6\n#define LLSC_M \"m\"\n#else\n#define LLSC_M \"ZC\"\n#endif\n\n#define a_ll a_ll\nstatic inline int a_ll(volatile int *p)\n{\n\tint v;\n#if __mips < 2\n\t__asm__ __volatile__ (\n\t\t\".set push ; .set mips2\\n\\t\"\n\t\t\"ll %0, %1\"\n\t\t\"\\n\\t.set pop\"\n\t\t: \"=r\"(v) : \"m\"(*p));\n#else\n\t__asm__ __volatile__ (\n\t\t\"ll %0, %1\"\n\t\t: \"=r\"(v) : LLSC_M(*p));\n#endif\n\treturn v;\n}\n\n#define a_sc a_sc\nstatic inline int a_sc(volatile int *p, int v)\n{\n\tint r;\n#if __mips < 2\n\t__asm__ __volatile__ (\n\t\t\".set push ; .set mips2\\n\\t\"\n\t\t\"sc %0, %1\"\n\t\t\"\\n\\t.set pop\"\n\t\t: \"=r\"(r), \"=m\"(*p) : \"0\"(v) : \"memory\");\n#else\n\t__asm__ __volatile__ (\n\t\t\"sc %0, %1\"\n\t\t: \"=r\"(r), \"=\"LLSC_M(*p) : \"0\"(v) : \"memory\");\n#endif\n\treturn r;\n}\n\n#define a_barrier a_barrier\nstatic inline void a_barrier()\n{\n#if __mips < 2\n\t/* mips2 sync, but using too many directives causes\n\t * gcc not to inline it, so encode with .long instead. */\n\t__asm__ __volatile__ (\".long 0xf\" : : : \"memory\");\n#else\n\t__asm__ __volatile__ (\"sync\" : : : \"memory\");\n#endif\n}\n\n#define a_pre_llsc a_barrier\n#define a_post_llsc a_barrier\n\n#undef LLSC_M\n"
  },
  {
    "path": "user.libc/arch/mips/bits/alltypes.h.in",
    "content": "#define _REDIR_TIME64 1\n#define _Addr int\n#define _Int64 long long\n#define _Reg int\n\n#if _MIPSEL || __MIPSEL || __MIPSEL__\n#define __BYTE_ORDER 1234\n#else\n#define __BYTE_ORDER 4321\n#endif\n\n#define __LONG_MAX 0x7fffffffL\n\n#ifndef __cplusplus\nTYPEDEF int wchar_t;\n#endif\n\nTYPEDEF float float_t;\nTYPEDEF double double_t;\n\nTYPEDEF struct { long long __ll; long double __ld; } max_align_t;\n"
  },
  {
    "path": "user.libc/arch/mips/bits/errno.h",
    "content": "#define EPERM            1\n#define ENOENT           2\n#define ESRCH            3\n#define EINTR            4\n#define EIO              5\n#define ENXIO            6\n#define E2BIG            7\n#define ENOEXEC          8\n#define EBADF            9\n#define ECHILD          10\n#define EAGAIN          11\n#define ENOMEM          12\n#define EACCES          13\n#define EFAULT          14\n#define ENOTBLK         15\n#define EBUSY           16\n#define EEXIST          17\n#define EXDEV           18\n#define ENODEV          19\n#define ENOTDIR         20\n#define EISDIR          21\n#define EINVAL          22\n#define ENFILE          23\n#define EMFILE          24\n#define ENOTTY          25\n#define ETXTBSY         26\n#define EFBIG           27\n#define ENOSPC          28\n#define ESPIPE          29\n#define EROFS           30\n#define EMLINK          31\n#define EPIPE           32\n#define EDOM            33\n#define ERANGE          34\n#define ENOMSG          35\n#define EIDRM           36\n#define ECHRNG          37\n#define EL2NSYNC        38\n#define EL3HLT          39\n#define EL3RST          40\n#define ELNRNG          41\n#define EUNATCH         42\n#define ENOCSI          43\n#define EL2HLT          44\n#define EDEADLK         45\n#define ENOLCK          46\n#define EBADE           50\n#define EBADR           51\n#define EXFULL          52\n#define ENOANO          53\n#define EBADRQC         54\n#define EBADSLT         55\n#define EDEADLOCK       56\n#define EBFONT          59\n#define ENOSTR          60\n#define ENODATA         61\n#define ETIME           62\n#define ENOSR           63\n#define ENONET          64\n#define ENOPKG          65\n#define EREMOTE         66\n#define ENOLINK         67\n#define EADV            68\n#define ESRMNT          69\n#define ECOMM           70\n#define EPROTO          71\n#define EDOTDOT         73\n#define EMULTIHOP       74\n#define EBADMSG         77\n#define ENAMETOOLONG    78\n#define EOVERFLOW       79\n#define ENOTUNIQ        80\n#define EBADFD          81\n#define EREMCHG         82\n#define ELIBACC         83\n#define ELIBBAD         84\n#define ELIBSCN         85\n#define ELIBMAX         86\n#define ELIBEXEC        87\n#define EILSEQ          88\n#define ENOSYS          89\n#define ELOOP           90\n#define ERESTART        91\n#define ESTRPIPE        92\n#define ENOTEMPTY       93\n#define EUSERS          94\n#define ENOTSOCK        95\n#define EDESTADDRREQ    96\n#define EMSGSIZE        97\n#define EPROTOTYPE      98\n#define ENOPROTOOPT     99\n#define EPROTONOSUPPORT 120\n#define ESOCKTNOSUPPORT 121\n#define EOPNOTSUPP      122\n#define ENOTSUP         EOPNOTSUPP\n#define EPFNOSUPPORT    123\n#define EAFNOSUPPORT    124\n#define EADDRINUSE      125\n#define EADDRNOTAVAIL   126\n#define ENETDOWN        127\n#define ENETUNREACH     128\n#define ENETRESET       129\n#define ECONNABORTED    130\n#define ECONNRESET      131\n#define ENOBUFS         132\n#define EISCONN         133\n#define ENOTCONN        134\n#define EUCLEAN         135\n#define ENOTNAM         137\n#define ENAVAIL         138\n#define EISNAM          139\n#define EREMOTEIO       140\n#define ESHUTDOWN       143\n#define ETOOMANYREFS    144\n#define ETIMEDOUT       145\n#define ECONNREFUSED    146\n#define EHOSTDOWN       147\n#define EHOSTUNREACH    148\n#define EWOULDBLOCK     EAGAIN\n#define EALREADY        149\n#define EINPROGRESS     150\n#define ESTALE          151\n#define ECANCELED       158\n#define ENOMEDIUM       159\n#define EMEDIUMTYPE     160\n#define ENOKEY          161\n#define EKEYEXPIRED     162\n#define EKEYREVOKED     163\n#define EKEYREJECTED    164\n#define EOWNERDEAD      165\n#define ENOTRECOVERABLE 166\n#define ERFKILL         167\n#define EHWPOISON       168\n#define EDQUOT          1133\n"
  },
  {
    "path": "user.libc/arch/mips/bits/fcntl.h",
    "content": "#define O_CREAT        0400\n#define O_EXCL        02000\n#define O_NOCTTY      04000\n#define O_TRUNC       01000\n#define O_APPEND       0010\n#define O_NONBLOCK     0200\n#define O_DSYNC        0020\n#define O_SYNC       040020\n#define O_RSYNC      040020\n#define O_DIRECTORY 0200000\n#define O_NOFOLLOW  0400000\n#define O_CLOEXEC  02000000\n\n#define O_ASYNC      010000\n#define O_DIRECT    0100000\n#define O_LARGEFILE  020000\n#define O_NOATIME  01000000\n#define O_PATH    010000000\n#define O_TMPFILE 020200000\n#define O_NDELAY O_NONBLOCK\n\n#define F_DUPFD  0\n#define F_GETFD  1\n#define F_SETFD  2\n#define F_GETFL  3\n#define F_SETFL  4\n\n#define F_SETOWN 24\n#define F_GETOWN 23\n#define F_SETSIG 10\n#define F_GETSIG 11\n\n#define F_GETLK 33\n#define F_SETLK 34\n#define F_SETLKW 35\n\n#define F_SETOWN_EX 15\n#define F_GETOWN_EX 16\n\n#define F_GETOWNER_UIDS 17\n"
  },
  {
    "path": "user.libc/arch/mips/bits/fenv.h",
    "content": "#ifdef __mips_soft_float\n#define FE_ALL_EXCEPT 0\n#define FE_TONEAREST  0\n#else\n#define FE_INEXACT    4\n#define FE_UNDERFLOW  8\n#define FE_OVERFLOW   16\n#define FE_DIVBYZERO  32\n#define FE_INVALID    64\n\n#define FE_ALL_EXCEPT 124\n\n#define FE_TONEAREST  0\n#define FE_TOWARDZERO 1\n#define FE_UPWARD     2\n#define FE_DOWNWARD   3\n#endif\n\ntypedef unsigned short fexcept_t;\n\ntypedef struct {\n\tunsigned __cw;\n} fenv_t;\n\n#define FE_DFL_ENV      ((const fenv_t *) -1)\n"
  },
  {
    "path": "user.libc/arch/mips/bits/float.h",
    "content": "#define FLT_EVAL_METHOD 0\n\n#define LDBL_TRUE_MIN 4.94065645841246544177e-324L\n#define LDBL_MIN 2.22507385850720138309e-308L\n#define LDBL_MAX 1.79769313486231570815e+308L\n#define LDBL_EPSILON 2.22044604925031308085e-16L\n\n#define LDBL_MANT_DIG 53\n#define LDBL_MIN_EXP (-1021)\n#define LDBL_MAX_EXP 1024\n\n#define LDBL_DIG 15\n#define LDBL_MIN_10_EXP (-307)\n#define LDBL_MAX_10_EXP 308\n\n#define DECIMAL_DIG 17\n"
  },
  {
    "path": "user.libc/arch/mips/bits/hwcap.h",
    "content": "#define HWCAP_MIPS_R6\t\t(1 << 0)\n#define HWCAP_MIPS_MSA\t\t(1 << 1)\n#define HWCAP_MIPS_CRC32\t(1 << 2)\n#define HWCAP_MIPS_MIPS16\t(1 << 3)\n#define HWCAP_MIPS_MDMX\t\t(1 << 4)\n#define HWCAP_MIPS_MIPS3D\t(1 << 5)\n#define HWCAP_MIPS_SMARTMIPS\t(1 << 6)\n#define HWCAP_MIPS_DSP\t\t(1 << 7)\n#define HWCAP_MIPS_DSP2\t\t(1 << 8)\n#define HWCAP_MIPS_DSP3\t\t(1 << 9)\n#define HWCAP_MIPS_MIPS16E2\t(1 << 10)\n#define HWCAP_LOONGSON_MMI\t(1 << 11)\n#define HWCAP_LOONGSON_EXT\t(1 << 12)\n#define HWCAP_LOONGSON_EXT2\t(1 << 13)\n"
  },
  {
    "path": "user.libc/arch/mips/bits/ioctl.h",
    "content": "#define _IOC(a,b,c,d) ( ((a)<<29) | ((b)<<8) | (c) | ((d)<<16) )\n#define _IOC_NONE  1U\n#define _IOC_READ  2U\n#define _IOC_WRITE 4U\n\n#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)\n#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c))\n#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c))\n#define _IOWR(a,b,c) _IOC(_IOC_READ|_IOC_WRITE,(a),(b),sizeof(c))\n\n#define TCGETA\t\t0x5401\n#define TCSETA\t\t0x5402\n#define TCSETAW\t\t0x5403\n#define TCSETAF\t\t0x5404\n#define TCSBRK\t\t0x5405\n#define TCXONC\t\t0x5406\n#define TCFLSH\t\t0x5407\n#define TCGETS\t\t0x540D\n#define TCSETS\t\t0x540E\n#define TCSETSW\t\t0x540F\n#define TCSETSF\t\t0x5410\n\n#define TIOCEXCL\t0x740D\n#define TIOCNXCL\t0x740E\n#define TIOCOUTQ\t0x7472\n#define TIOCSTI\t\t0x5472\n#define TIOCMGET\t0x741D\n#define TIOCMBIS\t0x741B\n#define TIOCMBIC\t0x741C\n#define TIOCMSET\t0x741A\n\n#define TIOCPKT\t\t0x5470\n#define TIOCSWINSZ\t_IOW('t', 103, struct winsize)\n#define TIOCGWINSZ\t_IOR('t', 104, struct winsize)\n#define TIOCNOTTY\t0x5471\n#define TIOCSETD\t0x7401\n#define TIOCGETD\t0x7400\n\n#define FIOCLEX\t\t0x6601\n#define FIONCLEX\t0x6602\n#define FIOASYNC\t0x667D\n#define FIONBIO\t\t0x667E\n#define FIOQSIZE\t0x667F\n\n#define TIOCGLTC        0x7474\n#define TIOCSLTC        0x7475\n#define TIOCSPGRP\t_IOW('t', 118, int)\n#define TIOCGPGRP\t_IOR('t', 119, int)\n#define TIOCCONS\t_IOW('t', 120, int)\n\n#define FIONREAD\t0x467F\n#define TIOCINQ\t\tFIONREAD\n\n#define TIOCGETP        0x7408\n#define TIOCSETP        0x7409\n#define TIOCSETN        0x740A\n\n#define TIOCSBRK\t0x5427\n#define TIOCCBRK\t0x5428\n#define TIOCGSID\t0x7416\n#define TIOCGRS485\t_IOR('T', 0x2E, char[32])\n#define TIOCSRS485\t_IOWR('T', 0x2F, char[32])\n#define TIOCGPTN\t_IOR('T', 0x30, unsigned int)\n#define TIOCSPTLCK\t_IOW('T', 0x31, int)\n#define TIOCGDEV\t_IOR('T', 0x32, unsigned int)\n#define TIOCSIG\t\t_IOW('T', 0x36, int)\n#define TIOCVHANGUP\t0x5437\n#define TIOCGPKT\t_IOR('T', 0x38, int)\n#define TIOCGPTLCK\t_IOR('T', 0x39, int)\n#define TIOCGEXCL\t_IOR('T', 0x40, int)\n#define TIOCGPTPEER\t_IO('T', 0x41)\n\n#define TIOCSCTTY\t0x5480\n#define TIOCGSOFTCAR\t0x5481\n#define TIOCSSOFTCAR\t0x5482\n#define TIOCLINUX\t0x5483\n#define TIOCGSERIAL\t0x5484\n#define TIOCSSERIAL\t0x5485\n#define TCSBRKP\t\t0x5486\n\n#define TIOCSERCONFIG\t0x5488\n#define TIOCSERGWILD\t0x5489\n#define TIOCSERSWILD\t0x548A\n#define TIOCGLCKTRMIOS\t0x548B\n#define TIOCSLCKTRMIOS\t0x548C\n#define TIOCSERGSTRUCT\t0x548D\n#define TIOCSERGETLSR   0x548E\n#define TIOCSERGETMULTI 0x548F\n#define TIOCSERSETMULTI 0x5490\n#define TIOCMIWAIT\t0x5491\n#define TIOCGICOUNT\t0x5492\n\n#define TIOCM_LE\t0x001\n#define TIOCM_DTR\t0x002\n#define TIOCM_RTS\t0x004\n#define TIOCM_ST\t0x010\n#define TIOCM_SR\t0x020\n#define TIOCM_CTS\t0x040\n#define TIOCM_CAR\t0x100\n#define TIOCM_CD\tTIOCM_CAR\n#define TIOCM_RNG\t0x200\n#define TIOCM_RI\tTIOCM_RNG\n#define TIOCM_DSR\t0x400\n#define TIOCM_OUT1\t0x2000\n#define TIOCM_OUT2\t0x4000\n#define TIOCM_LOOP\t0x8000\n\n#define FIOGETOWN       _IOR('f', 123, int)\n#define FIOSETOWN       _IOW('f', 124, int)\n#define SIOCATMARK      _IOR('s', 7, int)\n#define SIOCSPGRP       _IOW('s', 8, pid_t)\n#define SIOCGPGRP       _IOR('s', 9, pid_t)\n#define SIOCGSTAMP      _IOR(0x89, 6, char[16])\n#define SIOCGSTAMPNS    _IOR(0x89, 7, char[16])\n"
  },
  {
    "path": "user.libc/arch/mips/bits/ipcstat.h",
    "content": "#define IPC_STAT 0x102\n"
  },
  {
    "path": "user.libc/arch/mips/bits/mman.h",
    "content": "#undef MAP_ANON\n#define MAP_ANON       0x800\n#undef MAP_NORESERVE\n#define MAP_NORESERVE  0x0400\n#undef MAP_GROWSDOWN\n#define MAP_GROWSDOWN  0x1000\n#undef MAP_DENYWRITE\n#define MAP_DENYWRITE  0x2000\n#undef MAP_EXECUTABLE\n#define MAP_EXECUTABLE 0x4000\n#undef MAP_LOCKED\n#define MAP_LOCKED     0x8000\n#undef MAP_POPULATE\n#define MAP_POPULATE   0x10000\n#undef MAP_NONBLOCK\n#define MAP_NONBLOCK   0x20000\n#undef MAP_STACK\n#define MAP_STACK      0x40000\n#undef MAP_HUGETLB\n#define MAP_HUGETLB    0x80000\n#undef MAP_SYNC\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#undef MADV_SOFT_OFFLINE\n#endif\n"
  },
  {
    "path": "user.libc/arch/mips/bits/msg.h",
    "content": "struct msqid_ds {\n\tstruct ipc_perm msg_perm;\n#if _MIPSEL || __MIPSEL || __MIPSEL__\n\tunsigned long __msg_stime_lo;\n\tunsigned long __msg_stime_hi;\n\tunsigned long __msg_rtime_lo;\n\tunsigned long __msg_rtime_hi;\n\tunsigned long __msg_ctime_lo;\n\tunsigned long __msg_ctime_hi;\n#else\n\tunsigned long __msg_stime_hi;\n\tunsigned long __msg_stime_lo;\n\tunsigned long __msg_rtime_hi;\n\tunsigned long __msg_rtime_lo;\n\tunsigned long __msg_ctime_hi;\n\tunsigned long __msg_ctime_lo;\n#endif\n\tunsigned long msg_cbytes;\n\tmsgqnum_t msg_qnum;\n\tmsglen_t msg_qbytes;\n\tpid_t msg_lspid;\n\tpid_t msg_lrpid;\n\tunsigned long __unused[2];\n\ttime_t msg_stime;\n\ttime_t msg_rtime;\n\ttime_t msg_ctime;\n};\n"
  },
  {
    "path": "user.libc/arch/mips/bits/poll.h",
    "content": "#define POLLWRNORM POLLOUT\n#define POLLWRBAND 0x100\n"
  },
  {
    "path": "user.libc/arch/mips/bits/posix.h",
    "content": "#define _POSIX_V6_ILP32_OFFBIG  1\n#define _POSIX_V7_ILP32_OFFBIG  1\n"
  },
  {
    "path": "user.libc/arch/mips/bits/ptrace.h",
    "content": "#define PTRACE_GET_THREAD_AREA\t25\n#define PTRACE_SET_THREAD_AREA\t26\n#define PTRACE_PEEKTEXT_3264\t0xc0\n#define PTRACE_PEEKDATA_3264\t0xc1\n#define PTRACE_POKETEXT_3264\t0xc2\n#define PTRACE_POKEDATA_3264\t0xc3\n#define PTRACE_GET_THREAD_AREA_3264\t0xc4\n#define PTRACE_GET_WATCH_REGS\t0xd0\n#define PTRACE_SET_WATCH_REGS\t0xd1\n"
  },
  {
    "path": "user.libc/arch/mips/bits/reg.h",
    "content": "#undef __WORDSIZE\n#define __WORDSIZE 32\n\n#define EF_R0 6\n#define EF_R1 7\n#define EF_R2 8\n#define EF_R3 9\n#define EF_R4 10\n#define EF_R5 11\n#define EF_R6 12\n#define EF_R7 13\n#define EF_R8 14\n#define EF_R9 15\n#define EF_R10 16\n#define EF_R11 17\n#define EF_R12 18\n#define EF_R13 19\n#define EF_R14 20\n#define EF_R15 21\n#define EF_R16 22\n#define EF_R17 23\n#define EF_R18 24\n#define EF_R19 25\n#define EF_R20 26\n#define EF_R21 27\n#define EF_R22 28\n#define EF_R23 29\n#define EF_R24 30\n#define EF_R25 31\n\n#define EF_R26 32\n#define EF_R27 33\n#define EF_R28 34\n#define EF_R29 35\n#define EF_R30 36\n#define EF_R31 37\n\n#define EF_LO 38\n#define EF_HI 39\n\n#define EF_CP0_EPC 40\n#define EF_CP0_BADVADDR 41\n#define EF_CP0_STATUS 42\n#define EF_CP0_CAUSE 43\n#define EF_UNUSED0 44\n\n#define EF_SIZE 180\n"
  },
  {
    "path": "user.libc/arch/mips/bits/resource.h",
    "content": "#define RLIMIT_NOFILE  5\n#define RLIMIT_AS      6\n#define RLIMIT_RSS     7\n#define RLIMIT_NPROC   8\n#define RLIMIT_MEMLOCK 9\n"
  },
  {
    "path": "user.libc/arch/mips/bits/sem.h",
    "content": "struct semid_ds {\n\tstruct ipc_perm sem_perm;\n\tunsigned long __sem_otime_lo;\n\tunsigned long __sem_ctime_lo;\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n\tunsigned short sem_nsems;\n\tchar __sem_nsems_pad[sizeof(long)-sizeof(short)];\n#else\n\tchar __sem_nsems_pad[sizeof(long)-sizeof(short)];\n\tunsigned short sem_nsems;\n#endif\n\tunsigned long __sem_otime_hi;\n\tunsigned long __sem_ctime_hi;\n\ttime_t sem_otime;\n\ttime_t sem_ctime;\n};\n"
  },
  {
    "path": "user.libc/arch/mips/bits/setjmp.h",
    "content": "typedef unsigned long long __jmp_buf[13];\n"
  },
  {
    "path": "user.libc/arch/mips/bits/shm.h",
    "content": "#define SHMLBA 4096\n\nstruct shmid_ds {\n\tstruct ipc_perm shm_perm;\n\tsize_t shm_segsz;\n\tunsigned long __shm_atime_lo;\n\tunsigned long __shm_dtime_lo;\n\tunsigned long __shm_ctime_lo;\n\tpid_t shm_cpid;\n\tpid_t shm_lpid;\n\tunsigned long shm_nattch;\n\tunsigned short __shm_atime_hi;\n\tunsigned short __shm_dtime_hi;\n\tunsigned short __shm_ctime_hi;\n\tunsigned short __pad1;\n\ttime_t shm_atime;\n\ttime_t shm_dtime;\n\ttime_t shm_ctime;\n};\n\nstruct shminfo {\n\tunsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];\n};\n\nstruct shm_info {\n\tint __used_ids;\n\tunsigned long shm_tot, shm_rss, shm_swp;\n\tunsigned long __swap_attempts, __swap_successes;\n};\n"
  },
  {
    "path": "user.libc/arch/mips/bits/signal.h",
    "content": "#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define MINSIGSTKSZ 2048\n#define SIGSTKSZ 8192\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\ntypedef unsigned long long greg_t, gregset_t[32];\ntypedef struct {\n\tunion {\n\t\tdouble fp_dregs[32];\n\t\tstruct {\n\t\t\tfloat _fp_fregs;\n\t\t\tunsigned _fp_pad;\n\t\t} fp_fregs[32];\n\t} fp_r;\n} fpregset_t;\nstruct sigcontext {\n\tunsigned sc_regmask, sc_status;\n\tunsigned long long sc_pc;\n\tgregset_t sc_regs;\n\tfpregset_t sc_fpregs;\n\tunsigned sc_ownedfp, sc_fpc_csr, sc_fpc_eir, sc_used_math, sc_dsp;\n\tunsigned long long sc_mdhi, sc_mdlo;\n\tunsigned long sc_hi1, sc_lo1, sc_hi2, sc_lo2, sc_hi3, sc_lo3;\n};\ntypedef struct {\n\tunsigned regmask, status;\n\tunsigned long long pc;\n\tgregset_t gregs;\n\tfpregset_t fpregs;\n\tunsigned ownedfp, fpc_csr, fpc_eir, used_math, dsp;\n\tunsigned long long mdhi, mdlo;\n\tunsigned long hi1, lo1, hi2, lo2, hi3, lo3;\n} mcontext_t;\n#else\ntypedef struct {\n\tunsigned __mc1[2];\n\tunsigned long long __mc2[65];\n\tunsigned __mc3[5];\n\tunsigned long long __mc4[2];\n\tunsigned __mc5[6];\n} mcontext_t;\n#endif\n\nstruct sigaltstack {\n\tvoid *ss_sp;\n\tsize_t ss_size;\n\tint ss_flags;\n};\n\ntypedef struct __ucontext {\n\tunsigned long uc_flags;\n\tstruct __ucontext *uc_link;\n\tstack_t uc_stack;\n\tmcontext_t uc_mcontext;\n\tsigset_t uc_sigmask;\n} ucontext_t;\n\n#define SA_NOCLDSTOP  1\n#define SA_NOCLDWAIT  0x10000\n#define SA_SIGINFO    8\n#define SA_ONSTACK    0x08000000\n#define SA_RESTART    0x10000000\n#define SA_NODEFER    0x40000000\n#define SA_RESETHAND  0x80000000\n#define SA_RESTORER   0x04000000\n\n#undef SIG_BLOCK\n#undef SIG_UNBLOCK\n#undef SIG_SETMASK\n#define SIG_BLOCK     1\n#define SIG_UNBLOCK   2\n#define SIG_SETMASK   3\n\n#undef SI_ASYNCIO\n#undef SI_MESGQ\n#undef SI_TIMER\n#define SI_ASYNCIO (-2)\n#define SI_MESGQ (-4)\n#define SI_TIMER (-3)\n\n#define __SI_SWAP_ERRNO_CODE\n\n#endif\n\n#define SIGHUP    1\n#define SIGINT    2\n#define SIGQUIT   3\n#define SIGILL    4\n#define SIGTRAP   5\n#define SIGABRT   6\n#define SIGIOT    SIGABRT\n#define SIGEMT    7\n#define SIGFPE    8\n#define SIGKILL   9\n#define SIGBUS    10\n#define SIGSEGV   11\n#define SIGSYS    12\n#define SIGPIPE   13\n#define SIGALRM   14\n#define SIGTERM   15\n#define SIGUSR1   16\n#define SIGUSR2   17\n#define SIGCHLD   18\n#define SIGPWR    19\n#define SIGWINCH  20\n#define SIGURG    21\n#define SIGIO     22\n#define SIGPOLL   SIGIO\n#define SIGSTOP   23\n#define SIGTSTP   24\n#define SIGCONT   25\n#define SIGTTIN   26\n#define SIGTTOU   27\n#define SIGVTALRM 28\n#define SIGPROF   29\n#define SIGXCPU   30\n#define SIGXFSZ   31\n#define SIGUNUSED SIGSYS\n\n#define _NSIG 128\n"
  },
  {
    "path": "user.libc/arch/mips/bits/socket.h",
    "content": "#define SOCK_STREAM    2\n#define SOCK_DGRAM     1\n\n#define SOL_SOCKET     65535\n\n#define SO_DEBUG        1\n\n#define SO_REUSEADDR    0x0004\n#define SO_KEEPALIVE    0x0008\n#define SO_DONTROUTE    0x0010\n#define SO_BROADCAST    0x0020\n#define SO_LINGER       0x0080\n#define SO_OOBINLINE    0x0100\n#define SO_REUSEPORT    0x0200\n#define SO_SNDBUF       0x1001\n#define SO_RCVBUF       0x1002\n#define SO_SNDLOWAT     0x1003\n#define SO_RCVLOWAT     0x1004\n#define SO_ERROR        0x1007\n#define SO_TYPE         0x1008\n#define SO_ACCEPTCONN   0x1009\n#define SO_PROTOCOL     0x1028\n#define SO_DOMAIN       0x1029\n\n#define SO_NO_CHECK     11\n#define SO_PRIORITY     12\n#define SO_BSDCOMPAT    14\n#define SO_PASSCRED     17\n#define SO_PEERCRED     18\n#define SO_PEERSEC      30\n#define SO_SNDBUFFORCE  31\n#define SO_RCVBUFFORCE  33\n\n#define SOCK_NONBLOCK     0200\n#define SOCK_CLOEXEC  02000000\n"
  },
  {
    "path": "user.libc/arch/mips/bits/stat.h",
    "content": "/* copied from kernel definition, but with padding replaced\n * by the corresponding correctly-sized userspace types. */\n\nstruct stat {\n\tdev_t st_dev;\n\tlong __st_padding1[2];\n\tino_t st_ino;\n\tmode_t st_mode;\n\tnlink_t st_nlink;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tdev_t st_rdev;\n\tlong __st_padding2[2];\n\toff_t st_size;\n\tstruct {\n\t\tlong tv_sec;\n\t\tlong tv_nsec;\n\t} __st_atim32, __st_mtim32, __st_ctim32;\n\tblksize_t st_blksize;\n\tlong __st_padding3;\n\tblkcnt_t st_blocks;\n\tstruct timespec st_atim;\n\tstruct timespec st_mtim;\n\tstruct timespec st_ctim;\n\tlong __st_padding4[2];\n};\n"
  },
  {
    "path": "user.libc/arch/mips/bits/statfs.h",
    "content": "struct statfs {\n\tunsigned long f_type, f_bsize, f_frsize;\n\tfsblkcnt_t f_blocks, f_bfree;\n\tfsfilcnt_t f_files, f_ffree;\n\tfsblkcnt_t f_bavail;\n\tfsid_t f_fsid;\n\tunsigned long f_namelen, f_flags, f_spare[5];\n};\n"
  },
  {
    "path": "user.libc/arch/mips/bits/stdint.h",
    "content": "typedef int32_t int_fast16_t;\ntypedef int32_t int_fast32_t;\ntypedef uint32_t uint_fast16_t;\ntypedef uint32_t uint_fast32_t;\n\n#define INT_FAST16_MIN  INT32_MIN\n#define INT_FAST32_MIN  INT32_MIN\n\n#define INT_FAST16_MAX  INT32_MAX\n#define INT_FAST32_MAX  INT32_MAX\n\n#define UINT_FAST16_MAX UINT32_MAX\n#define UINT_FAST32_MAX UINT32_MAX\n\n#define INTPTR_MIN      INT32_MIN\n#define INTPTR_MAX      INT32_MAX\n#define UINTPTR_MAX     UINT32_MAX\n#define PTRDIFF_MIN     INT32_MIN\n#define PTRDIFF_MAX     INT32_MAX\n#define SIZE_MAX        UINT32_MAX\n"
  },
  {
    "path": "user.libc/arch/mips/bits/syscall.h.in",
    "content": "#define __NR_syscall                 4000\n#define __NR_exit                    4001\n#define __NR_fork                    4002\n#define __NR_read                    4003\n#define __NR_write                   4004\n#define __NR_open                    4005\n#define __NR_close                   4006\n#define __NR_waitpid                 4007\n#define __NR_creat                   4008\n#define __NR_link                    4009\n#define __NR_unlink                  4010\n#define __NR_execve                  4011\n#define __NR_chdir                   4012\n#define __NR_time                    4013\n#define __NR_mknod                   4014\n#define __NR_chmod                   4015\n#define __NR_lchown                  4016\n#define __NR_break                   4017\n#define __NR_unused18                4018\n#define __NR_lseek                   4019\n#define __NR_getpid                  4020\n#define __NR_mount                   4021\n#define __NR_umount                  4022\n#define __NR_setuid                  4023\n#define __NR_getuid                  4024\n#define __NR_stime                   4025\n#define __NR_ptrace                  4026\n#define __NR_alarm                   4027\n#define __NR_unused28                4028\n#define __NR_pause                   4029\n#define __NR_utime                   4030\n#define __NR_stty                    4031\n#define __NR_gtty                    4032\n#define __NR_access                  4033\n#define __NR_nice                    4034\n#define __NR_ftime                   4035\n#define __NR_sync                    4036\n#define __NR_kill                    4037\n#define __NR_rename                  4038\n#define __NR_mkdir                   4039\n#define __NR_rmdir                   4040\n#define __NR_dup                     4041\n#define __NR_pipe                    4042\n#define __NR_times                   4043\n#define __NR_prof                    4044\n#define __NR_brk                     4045\n#define __NR_setgid                  4046\n#define __NR_getgid                  4047\n#define __NR_signal                  4048\n#define __NR_geteuid                 4049\n#define __NR_getegid                 4050\n#define __NR_acct                    4051\n#define __NR_umount2                 4052\n#define __NR_lock                    4053\n#define __NR_ioctl                   4054\n#define __NR_fcntl                   4055\n#define __NR_mpx                     4056\n#define __NR_setpgid                 4057\n#define __NR_ulimit                  4058\n#define __NR_unused59                4059\n#define __NR_umask                   4060\n#define __NR_chroot                  4061\n#define __NR_ustat                   4062\n#define __NR_dup2                    4063\n#define __NR_getppid                 4064\n#define __NR_getpgrp                 4065\n#define __NR_setsid                  4066\n#define __NR_sigaction               4067\n#define __NR_sgetmask                4068\n#define __NR_ssetmask                4069\n#define __NR_setreuid                4070\n#define __NR_setregid                4071\n#define __NR_sigsuspend              4072\n#define __NR_sigpending              4073\n#define __NR_sethostname             4074\n#define __NR_setrlimit               4075\n#define __NR_getrlimit               4076\n#define __NR_getrusage               4077\n#define __NR_gettimeofday_time32            4078\n#define __NR_settimeofday_time32            4079\n#define __NR_getgroups               4080\n#define __NR_setgroups               4081\n#define __NR_reserved82              4082\n#define __NR_symlink                 4083\n#define __NR_unused84                4084\n#define __NR_readlink                4085\n#define __NR_uselib                  4086\n#define __NR_swapon                  4087\n#define __NR_reboot                  4088\n#define __NR_readdir                 4089\n#define __NR_mmap                    4090\n#define __NR_munmap                  4091\n#define __NR_truncate                4092\n#define __NR_ftruncate               4093\n#define __NR_fchmod                  4094\n#define __NR_fchown                  4095\n#define __NR_getpriority             4096\n#define __NR_setpriority             4097\n#define __NR_profil                  4098\n#define __NR_statfs                  4099\n#define __NR_fstatfs                 4100\n#define __NR_ioperm                  4101\n#define __NR_socketcall              4102\n#define __NR_syslog                  4103\n#define __NR_setitimer               4104\n#define __NR_getitimer               4105\n#define __NR_stat                    4106\n#define __NR_lstat                   4107\n#define __NR_fstat                   4108\n#define __NR_unused109               4109\n#define __NR_iopl                    4110\n#define __NR_vhangup                 4111\n#define __NR_idle                    4112\n#define __NR_vm86                    4113\n#define __NR_wait4                   4114\n#define __NR_swapoff                 4115\n#define __NR_sysinfo                 4116\n#define __NR_ipc                     4117\n#define __NR_fsync                   4118\n#define __NR_sigreturn               4119\n#define __NR_clone                   4120\n#define __NR_setdomainname           4121\n#define __NR_uname                   4122\n#define __NR_modify_ldt              4123\n#define __NR_adjtimex                4124\n#define __NR_mprotect                4125\n#define __NR_sigprocmask             4126\n#define __NR_create_module           4127\n#define __NR_init_module             4128\n#define __NR_delete_module           4129\n#define __NR_get_kernel_syms         4130\n#define __NR_quotactl                4131\n#define __NR_getpgid                 4132\n#define __NR_fchdir                  4133\n#define __NR_bdflush                 4134\n#define __NR_sysfs                   4135\n#define __NR_personality             4136\n#define __NR_afs_syscall             4137\n#define __NR_setfsuid                4138\n#define __NR_setfsgid                4139\n#define __NR__llseek                 4140\n#define __NR_getdents                4141\n#define __NR__newselect              4142\n#define __NR_flock                   4143\n#define __NR_msync                   4144\n#define __NR_readv                   4145\n#define __NR_writev                  4146\n#define __NR_cacheflush              4147\n#define __NR_cachectl                4148\n#define __NR_sysmips                 4149\n#define __NR_unused150               4150\n#define __NR_getsid                  4151\n#define __NR_fdatasync               4152\n#define __NR__sysctl                 4153\n#define __NR_mlock                   4154\n#define __NR_munlock                 4155\n#define __NR_mlockall                4156\n#define __NR_munlockall              4157\n#define __NR_sched_setparam          4158\n#define __NR_sched_getparam          4159\n#define __NR_sched_setscheduler      4160\n#define __NR_sched_getscheduler      4161\n#define __NR_sched_yield             4162\n#define __NR_sched_get_priority_max  4163\n#define __NR_sched_get_priority_min  4164\n#define __NR_sched_rr_get_interval   4165\n#define __NR_nanosleep               4166\n#define __NR_mremap                  4167\n#define __NR_accept                  4168\n#define __NR_bind                    4169\n#define __NR_connect                 4170\n#define __NR_getpeername             4171\n#define __NR_getsockname             4172\n#define __NR_getsockopt              4173\n#define __NR_listen                  4174\n#define __NR_recv                    4175\n#define __NR_recvfrom                4176\n#define __NR_recvmsg                 4177\n#define __NR_send                    4178\n#define __NR_sendmsg                 4179\n#define __NR_sendto                  4180\n#define __NR_setsockopt              4181\n#define __NR_shutdown                4182\n#define __NR_socket                  4183\n#define __NR_socketpair              4184\n#define __NR_setresuid               4185\n#define __NR_getresuid               4186\n#define __NR_query_module            4187\n#define __NR_poll                    4188\n#define __NR_nfsservctl              4189\n#define __NR_setresgid               4190\n#define __NR_getresgid               4191\n#define __NR_prctl                   4192\n#define __NR_rt_sigreturn            4193\n#define __NR_rt_sigaction            4194\n#define __NR_rt_sigprocmask          4195\n#define __NR_rt_sigpending           4196\n#define __NR_rt_sigtimedwait         4197\n#define __NR_rt_sigqueueinfo         4198\n#define __NR_rt_sigsuspend           4199\n#define __NR_pread64                 4200\n#define __NR_pwrite64                4201\n#define __NR_chown                   4202\n#define __NR_getcwd                  4203\n#define __NR_capget                  4204\n#define __NR_capset                  4205\n#define __NR_sigaltstack             4206\n#define __NR_sendfile                4207\n#define __NR_getpmsg                 4208\n#define __NR_putpmsg                 4209\n#define __NR_mmap2                   4210\n#define __NR_truncate64              4211\n#define __NR_ftruncate64             4212\n#define __NR_stat64                  4213\n#define __NR_lstat64                 4214\n#define __NR_fstat64                 4215\n#define __NR_pivot_root              4216\n#define __NR_mincore                 4217\n#define __NR_madvise                 4218\n#define __NR_getdents64              4219\n#define __NR_fcntl64                 4220\n#define __NR_reserved221             4221\n#define __NR_gettid                  4222\n#define __NR_readahead               4223\n#define __NR_setxattr                4224\n#define __NR_lsetxattr               4225\n#define __NR_fsetxattr               4226\n#define __NR_getxattr                4227\n#define __NR_lgetxattr               4228\n#define __NR_fgetxattr               4229\n#define __NR_listxattr               4230\n#define __NR_llistxattr              4231\n#define __NR_flistxattr              4232\n#define __NR_removexattr             4233\n#define __NR_lremovexattr            4234\n#define __NR_fremovexattr            4235\n#define __NR_tkill                   4236\n#define __NR_sendfile64              4237\n#define __NR_futex                   4238\n#define __NR_sched_setaffinity       4239\n#define __NR_sched_getaffinity       4240\n#define __NR_io_setup                4241\n#define __NR_io_destroy              4242\n#define __NR_io_getevents            4243\n#define __NR_io_submit               4244\n#define __NR_io_cancel               4245\n#define __NR_exit_group              4246\n#define __NR_lookup_dcookie          4247\n#define __NR_epoll_create            4248\n#define __NR_epoll_ctl               4249\n#define __NR_epoll_wait              4250\n#define __NR_remap_file_pages        4251\n#define __NR_set_tid_address         4252\n#define __NR_restart_syscall         4253\n#define __NR_fadvise64               4254\n#define __NR_statfs64                4255\n#define __NR_fstatfs64               4256\n#define __NR_timer_create            4257\n#define __NR_timer_settime32           4258\n#define __NR_timer_gettime32           4259\n#define __NR_timer_getoverrun        4260\n#define __NR_timer_delete            4261\n#define __NR_clock_settime32           4262\n#define __NR_clock_gettime32           4263\n#define __NR_clock_getres_time32            4264\n#define __NR_clock_nanosleep_time32         4265\n#define __NR_tgkill                  4266\n#define __NR_utimes                  4267\n#define __NR_mbind                   4268\n#define __NR_get_mempolicy           4269\n#define __NR_set_mempolicy           4270\n#define __NR_mq_open                 4271\n#define __NR_mq_unlink               4272\n#define __NR_mq_timedsend            4273\n#define __NR_mq_timedreceive         4274\n#define __NR_mq_notify               4275\n#define __NR_mq_getsetattr           4276\n#define __NR_vserver                 4277\n#define __NR_waitid                  4278\n#define __NR_add_key                 4280\n#define __NR_request_key             4281\n#define __NR_keyctl                  4282\n#define __NR_set_thread_area         4283\n#define __NR_inotify_init            4284\n#define __NR_inotify_add_watch       4285\n#define __NR_inotify_rm_watch        4286\n#define __NR_migrate_pages           4287\n#define __NR_openat                  4288\n#define __NR_mkdirat                 4289\n#define __NR_mknodat                 4290\n#define __NR_fchownat                4291\n#define __NR_futimesat               4292\n#define __NR_fstatat64               4293\n#define __NR_unlinkat                4294\n#define __NR_renameat                4295\n#define __NR_linkat                  4296\n#define __NR_symlinkat               4297\n#define __NR_readlinkat              4298\n#define __NR_fchmodat                4299\n#define __NR_faccessat               4300\n#define __NR_pselect6                4301\n#define __NR_ppoll                   4302\n#define __NR_unshare                 4303\n#define __NR_splice                  4304\n#define __NR_sync_file_range         4305\n#define __NR_tee                     4306\n#define __NR_vmsplice                4307\n#define __NR_move_pages              4308\n#define __NR_set_robust_list         4309\n#define __NR_get_robust_list         4310\n#define __NR_kexec_load              4311\n#define __NR_getcpu                  4312\n#define __NR_epoll_pwait             4313\n#define __NR_ioprio_set              4314\n#define __NR_ioprio_get              4315\n#define __NR_utimensat               4316\n#define __NR_signalfd                4317\n#define __NR_timerfd                 4318\n#define __NR_eventfd                 4319\n#define __NR_fallocate               4320\n#define __NR_timerfd_create          4321\n#define __NR_timerfd_gettime32         4322\n#define __NR_timerfd_settime32         4323\n#define __NR_signalfd4               4324\n#define __NR_eventfd2                4325\n#define __NR_epoll_create1           4326\n#define __NR_dup3                    4327\n#define __NR_pipe2                   4328\n#define __NR_inotify_init1           4329\n#define __NR_preadv                  4330\n#define __NR_pwritev                 4331\n#define __NR_rt_tgsigqueueinfo       4332\n#define __NR_perf_event_open         4333\n#define __NR_accept4                 4334\n#define __NR_recvmmsg                4335\n#define __NR_fanotify_init           4336\n#define __NR_fanotify_mark           4337\n#define __NR_prlimit64               4338\n#define __NR_name_to_handle_at       4339\n#define __NR_open_by_handle_at       4340\n#define __NR_clock_adjtime           4341\n#define __NR_syncfs                  4342\n#define __NR_sendmmsg                4343\n#define __NR_setns                   4344\n#define __NR_process_vm_readv        4345\n#define __NR_process_vm_writev       4346\n#define __NR_kcmp                    4347\n#define __NR_finit_module            4348\n#define __NR_sched_setattr           4349\n#define __NR_sched_getattr           4350\n#define __NR_renameat2               4351\n#define __NR_seccomp                 4352\n#define __NR_getrandom               4353\n#define __NR_memfd_create            4354\n#define __NR_bpf                     4355\n#define __NR_execveat                4356\n#define __NR_userfaultfd             4357\n#define __NR_membarrier              4358\n#define __NR_mlock2                  4359\n#define __NR_copy_file_range         4360\n#define __NR_preadv2                 4361\n#define __NR_pwritev2                4362\n#define __NR_pkey_mprotect           4363\n#define __NR_pkey_alloc              4364\n#define __NR_pkey_free               4365\n#define __NR_statx                   4366\n#define __NR_rseq                    4367\n#define __NR_io_pgetevents           4368\n#define __NR_semget                  4393\n#define __NR_semctl                  4394\n#define __NR_shmget                  4395\n#define __NR_shmctl                  4396\n#define __NR_shmat                   4397\n#define __NR_shmdt                   4398\n#define __NR_msgget                  4399\n#define __NR_msgsnd                  4400\n#define __NR_msgrcv                  4401\n#define __NR_msgctl                  4402\n#define __NR_clock_gettime64         4403\n#define __NR_clock_settime64         4404\n#define __NR_clock_adjtime64         4405\n#define __NR_clock_getres_time64     4406\n#define __NR_clock_nanosleep_time64  4407\n#define __NR_timer_gettime64         4408\n#define __NR_timer_settime64         4409\n#define __NR_timerfd_gettime64       4410\n#define __NR_timerfd_settime64       4411\n#define __NR_utimensat_time64        4412\n#define __NR_pselect6_time64         4413\n#define __NR_ppoll_time64            4414\n#define __NR_io_pgetevents_time64    4416\n#define __NR_recvmmsg_time64         4417\n#define __NR_mq_timedsend_time64     4418\n#define __NR_mq_timedreceive_time64  4419\n#define __NR_semtimedop_time64       4420\n#define __NR_rt_sigtimedwait_time64  4421\n#define __NR_futex_time64            4422\n#define __NR_sched_rr_get_interval_time64 4423\n#define __NR_pidfd_send_signal       4424\n#define __NR_io_uring_setup          4425\n#define __NR_io_uring_enter          4426\n#define __NR_io_uring_register       4427\n#define __NR_open_tree\t\t4428\n#define __NR_move_mount\t\t4429\n#define __NR_fsopen\t\t4430\n#define __NR_fsconfig\t\t4431\n#define __NR_fsmount\t\t4432\n#define __NR_fspick\t\t4433\n#define __NR_pidfd_open\t\t4434\n#define __NR_clone3\t\t4435\n#define __NR_close_range\t4436\n#define __NR_openat2\t\t4437\n#define __NR_pidfd_getfd\t4438\n#define __NR_faccessat2\t\t4439\n\n"
  },
  {
    "path": "user.libc/arch/mips/bits/termios.h",
    "content": "struct termios {\n\ttcflag_t c_iflag;\n\ttcflag_t c_oflag;\n\ttcflag_t c_cflag;\n\ttcflag_t c_lflag;\n\tcc_t c_line;\n\tcc_t c_cc[NCCS];\n\tspeed_t __c_ispeed;\n\tspeed_t __c_ospeed;\n};\n\n#define VINTR     0\n#define VQUIT     1\n#define VERASE    2\n#define VKILL     3\n#define VMIN      4\n#define VTIME     5\n#define VEOL2     6\n#define VSWTC     7\n#define VSWTCH    7\n#define VSTART    8\n#define VSTOP     9\n#define VSUSP    10\n#define VREPRINT 12\n#define VDISCARD 13\n#define VWERASE  14\n#define VLNEXT   15\n#define VEOF     16\n#define VEOL     17\n\n#define IGNBRK  0000001\n#define BRKINT  0000002\n#define IGNPAR  0000004\n#define PARMRK  0000010\n#define INPCK   0000020\n#define ISTRIP  0000040\n#define INLCR   0000100\n#define IGNCR   0000200\n#define ICRNL   0000400\n#define IUCLC   0001000\n#define IXON    0002000\n#define IXANY   0004000\n#define IXOFF   0010000\n#define IMAXBEL 0020000\n#define IUTF8   0040000\n\n#define OPOST  0000001\n#define OLCUC  0000002\n#define ONLCR  0000004\n#define OCRNL  0000010\n#define ONOCR  0000020\n#define ONLRET 0000040\n#define OFILL  0000100\n#define OFDEL  0000200\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_XOPEN_SOURCE)\n#define NLDLY  0000400\n#define NL0    0000000\n#define NL1    0000400\n#define CRDLY  0003000\n#define CR0    0000000\n#define CR1    0001000\n#define CR2    0002000\n#define CR3    0003000\n#define TABDLY 0014000\n#define TAB0   0000000\n#define TAB1   0004000\n#define TAB2   0010000\n#define TAB3   0014000\n#define BSDLY  0020000\n#define BS0    0000000\n#define BS1    0020000\n#define FFDLY  0100000\n#define FF0    0000000\n#define FF1    0100000\n#endif\n\n#define VTDLY  0040000\n#define VT0    0000000\n#define VT1    0040000\n\n#define B0       0000000\n#define B50      0000001\n#define B75      0000002\n#define B110     0000003\n#define B134     0000004\n#define B150     0000005\n#define B200     0000006\n#define B300     0000007\n#define B600     0000010\n#define B1200    0000011\n#define B1800    0000012\n#define B2400    0000013\n#define B4800    0000014\n#define B9600    0000015\n#define B19200   0000016\n#define B38400   0000017\n\n#define B57600   0010001\n#define B115200  0010002\n#define B230400  0010003\n#define B460800  0010004\n#define B500000  0010005\n#define B576000  0010006\n#define B921600  0010007\n#define B1000000 0010010\n#define B1152000 0010011\n#define B1500000 0010012\n#define B2000000 0010013\n#define B2500000 0010014\n#define B3000000 0010015\n#define B3500000 0010016\n#define B4000000 0010017\n\n#define CSIZE  0000060\n#define CS5    0000000\n#define CS6    0000020\n#define CS7    0000040\n#define CS8    0000060\n#define CSTOPB 0000100\n#define CREAD  0000200\n#define PARENB 0000400\n#define PARODD 0001000\n#define HUPCL  0002000\n#define CLOCAL 0004000\n\n#define ISIG   0000001\n#define ICANON 0000002\n#define ECHO   0000010\n#define ECHOE  0000020\n#define ECHOK  0000040\n#define ECHONL 0000100\n#define NOFLSH 0000200\n#define IEXTEN 0000400\n#define TOSTOP 0100000\n#define ITOSTOP 0100000\n\n#define TCOOFF 0\n#define TCOON  1\n#define TCIOFF 2\n#define TCION  3\n\n#define TCIFLUSH  0\n#define TCOFLUSH  1\n#define TCIOFLUSH 2\n\n#define TCSANOW   0\n#define TCSADRAIN 1\n#define TCSAFLUSH 2\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define EXTA    0000016\n#define EXTB    0000017\n#define CBAUD   0010017\n#define CBAUDEX 0010000\n#define CIBAUD  002003600000\n#define CMSPAR  010000000000\n#define CRTSCTS 020000000000\n\n#define XCASE   0000004\n#define ECHOCTL 0001000\n#define ECHOPRT 0002000\n#define ECHOKE  0004000\n#define FLUSHO  0020000\n#define PENDIN  0040000\n#define EXTPROC 0200000\n\n#define XTABS  0014000\n#define TIOCSER_TEMT 1\n#endif\n"
  },
  {
    "path": "user.libc/arch/mips/bits/user.h",
    "content": "struct user {\n\tunsigned long regs[45+64];\n\tunsigned long u_tsize, u_dsize, u_ssize;\n\tunsigned long start_code, start_data, start_stack;\n\tlong signal;\n\tvoid *u_ar0;\n\tunsigned long magic;\n\tchar u_comm[32];\n};\n#define ELF_NGREG 45\n#define ELF_NFPREG 33\ntypedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG];\ntypedef double elf_fpreg_t, elf_fpregset_t[ELF_NFPREG];\n"
  },
  {
    "path": "user.libc/arch/mips/crt_arch.h",
    "content": "__asm__(\n\".set push\\n\"\n\".set noreorder\\n\"\n\".text \\n\"\n\".global _\" START \"\\n\"\n\".global \" START \"\\n\"\n\".type   _\" START \", @function\\n\"\n\".type   \" START \", @function\\n\"\n\"_\" START \":\\n\"\n\"\" START \":\\n\"\n\"\tbal 1f \\n\"\n\"\t move $fp, $0 \\n\"\n\"\t.gpword . \\n\"\n\"\t.gpword \" START \"_c \\n\"\n\".weak _DYNAMIC \\n\"\n\".hidden _DYNAMIC \\n\"\n\"\t.gpword _DYNAMIC \\n\"\n\"1:\tlw $gp, 0($ra) \\n\"\n\"\tsubu $gp, $ra, $gp \\n\"\n\"\tmove $4, $sp \\n\"\n\"\tlw $5, 8($ra) \\n\"\n\"\taddu $5, $5, $gp \\n\"\n\"\tlw $25, 4($ra) \\n\"\n\"\taddu $25, $25, $gp \\n\"\n\"\tand $sp, $sp, -8 \\n\"\n\"\tjalr $25 \\n\"\n\"\t subu $sp, $sp, 16 \\n\"\n\".set pop \\n\"\n);\n"
  },
  {
    "path": "user.libc/arch/mips/ksigaction.h",
    "content": "#include <features.h>\n\nstruct k_sigaction {\n\tunsigned flags;\n\tvoid (*handler)(int);\n\tunsigned long mask[4];\n\t/* The following field is past the end of the structure the\n\t * kernel will read or write, and exists only to avoid having\n\t * mips-specific preprocessor conditionals in sigaction.c. */\n\tvoid (*restorer)();\n};\n\nhidden void __restore(), __restore_rt();\n"
  },
  {
    "path": "user.libc/arch/mips/kstat.h",
    "content": "struct kstat {\n\tunsigned st_dev;\n\tlong __st_padding1[3];\n\tino_t st_ino;\n\tmode_t st_mode;\n\tnlink_t st_nlink;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tunsigned st_rdev;\n\tlong __st_padding2[3];\n\toff_t st_size;\n\tlong st_atime_sec;\n\tlong st_atime_nsec;\n\tlong st_mtime_sec;\n\tlong st_mtime_nsec;\n\tlong st_ctime_sec;\n\tlong st_ctime_nsec;\n\tblksize_t st_blksize;\n\tlong __st_padding3;\n\tblkcnt_t st_blocks;\n        long __st_padding4[14];\n};\n"
  },
  {
    "path": "user.libc/arch/mips/pthread_arch.h",
    "content": "static inline uintptr_t __get_tp()\n{\n#if __mips_isa_rev < 2\n\tregister uintptr_t tp __asm__(\"$3\");\n\t__asm__ (\".word 0x7c03e83b\" : \"=r\" (tp) );\n#else\n\tuintptr_t tp;\n\t__asm__ (\"rdhwr %0, $29\" : \"=r\" (tp) );\n#endif\n\treturn tp;\n}\n\n#define TLS_ABOVE_TP\n#define GAP_ABOVE_TP 0\n\n#define TP_OFFSET 0x7000\n#define DTP_OFFSET 0x8000\n\n#define MC_PC pc\n"
  },
  {
    "path": "user.libc/arch/mips/reloc.h",
    "content": "#if __mips_isa_rev >= 6\n#define ISA_SUFFIX \"r6\"\n#else\n#define ISA_SUFFIX \"\"\n#endif\n\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n#define ENDIAN_SUFFIX \"el\"\n#else\n#define ENDIAN_SUFFIX \"\"\n#endif\n\n#ifdef __mips_soft_float\n#define FP_SUFFIX \"-sf\"\n#else\n#define FP_SUFFIX \"\"\n#endif\n\n#define LDSO_ARCH \"mips\" ISA_SUFFIX ENDIAN_SUFFIX FP_SUFFIX\n\n#define TPOFF_K (-0x7000)\n\n#define REL_SYM_OR_REL  R_MIPS_REL32\n#define REL_PLT         R_MIPS_JUMP_SLOT\n#define REL_COPY        R_MIPS_COPY\n#define REL_DTPMOD      R_MIPS_TLS_DTPMOD32\n#define REL_DTPOFF      R_MIPS_TLS_DTPREL32\n#define REL_TPOFF       R_MIPS_TLS_TPREL32\n\n#define NEED_MIPS_GOT_RELOCS 1\n#define DT_DEBUG_INDIRECT DT_MIPS_RLD_MAP\n#define ARCH_SYM_REJECT_UND(s) (!((s)->st_other & STO_MIPS_PLT))\n\n#define CRTJMP(pc,sp) __asm__ __volatile__( \\\n\t\"move $sp,%1 ; jr %0\" : : \"r\"(pc), \"r\"(sp) : \"memory\" )\n\n#define GETFUNCSYM(fp, sym, got) __asm__ ( \\\n\t\".hidden \" #sym \"\\n\" \\\n\t\".set push \\n\" \\\n\t\".set noreorder \\n\" \\\n\t\"\tbal 1f \\n\" \\\n\t\"\t nop \\n\" \\\n\t\"\t.gpword . \\n\" \\\n\t\"\t.gpword \" #sym \" \\n\" \\\n\t\"1:\tlw %0, ($ra) \\n\" \\\n\t\"\tsubu %0, $ra, %0 \\n\" \\\n\t\"\tlw $ra, 4($ra) \\n\" \\\n\t\"\taddu %0, %0, $ra \\n\" \\\n\t\".set pop \\n\" \\\n\t: \"=r\"(*(fp)) : : \"memory\", \"ra\" )\n"
  },
  {
    "path": "user.libc/arch/mips/syscall_arch.h",
    "content": "#define __SYSCALL_LL_E(x) \\\n((union { long long ll; long l[2]; }){ .ll = x }).l[0], \\\n((union { long long ll; long l[2]; }){ .ll = x }).l[1]\n#define __SYSCALL_LL_O(x) 0, __SYSCALL_LL_E((x))\n\n#define SYSCALL_RLIM_INFINITY (-1UL/2)\n\n#if __mips_isa_rev >= 6\n#define SYSCALL_CLOBBERLIST \\\n\t\"$1\", \"$3\", \"$11\", \"$12\", \"$13\", \\\n\t\"$14\", \"$15\", \"$24\", \"$25\", \"memory\"\n#else\n#define SYSCALL_CLOBBERLIST \\\n\t\"$1\", \"$3\", \"$11\", \"$12\", \"$13\", \\\n\t\"$14\", \"$15\", \"$24\", \"$25\", \"hi\", \"lo\", \"memory\"\n#endif\n\nstatic inline long __syscall0(long n)\n{\n\tregister long r7 __asm__(\"$7\");\n\tregister long r2 __asm__(\"$2\");\n\t__asm__ __volatile__ (\n\t\t\"addu $2,$0,%2 ; syscall\"\n\t\t: \"=&r\"(r2), \"=r\"(r7)\n\t\t: \"ir\"(n), \"0\"(r2)\n\t\t: SYSCALL_CLOBBERLIST, \"$8\", \"$9\", \"$10\");\n\treturn r7 && r2>0 ? -r2 : r2;\n}\n\nstatic inline long __syscall1(long n, long a)\n{\n\tregister long r4 __asm__(\"$4\") = a;\n\tregister long r7 __asm__(\"$7\");\n\tregister long r2 __asm__(\"$2\");\n\t__asm__ __volatile__ (\n\t\t\"addu $2,$0,%2 ; syscall\"\n\t\t: \"=&r\"(r2), \"=r\"(r7)\n\t\t: \"ir\"(n), \"0\"(r2), \"r\"(r4)\n\t\t: SYSCALL_CLOBBERLIST, \"$8\", \"$9\", \"$10\");\n\treturn r7 && r2>0 ? -r2 : r2;\n}\n\nstatic inline long __syscall2(long n, long a, long b)\n{\n\tregister long r4 __asm__(\"$4\") = a;\n\tregister long r5 __asm__(\"$5\") = b;\n\tregister long r7 __asm__(\"$7\");\n\tregister long r2 __asm__(\"$2\");\n\t__asm__ __volatile__ (\n\t\t\"addu $2,$0,%2 ; syscall\"\n\t\t: \"=&r\"(r2), \"=r\"(r7)\n\t\t: \"ir\"(n), \"0\"(r2), \"r\"(r4), \"r\"(r5)\n\t\t: SYSCALL_CLOBBERLIST, \"$8\", \"$9\", \"$10\");\n\treturn r7 && r2>0 ? -r2 : r2;\n}\n\nstatic inline long __syscall3(long n, long a, long b, long c)\n{\n\tregister long r4 __asm__(\"$4\") = a;\n\tregister long r5 __asm__(\"$5\") = b;\n\tregister long r6 __asm__(\"$6\") = c;\n\tregister long r7 __asm__(\"$7\");\n\tregister long r2 __asm__(\"$2\");\n\t__asm__ __volatile__ (\n\t\t\"addu $2,$0,%2 ; syscall\"\n\t\t: \"=&r\"(r2), \"=r\"(r7)\n\t\t: \"ir\"(n), \"0\"(r2), \"r\"(r4), \"r\"(r5), \"r\"(r6)\n\t\t: SYSCALL_CLOBBERLIST, \"$8\", \"$9\", \"$10\");\n\treturn r7 && r2>0 ? -r2 : r2;\n}\n\nstatic inline long __syscall4(long n, long a, long b, long c, long d)\n{\n\tregister long r4 __asm__(\"$4\") = a;\n\tregister long r5 __asm__(\"$5\") = b;\n\tregister long r6 __asm__(\"$6\") = c;\n\tregister long r7 __asm__(\"$7\") = d;\n\tregister long r2 __asm__(\"$2\");\n\t__asm__ __volatile__ (\n\t\t\"addu $2,$0,%2 ; syscall\"\n\t\t: \"=&r\"(r2), \"+r\"(r7)\n\t\t: \"ir\"(n), \"0\"(r2), \"r\"(r4), \"r\"(r5), \"r\"(r6)\n\t\t: SYSCALL_CLOBBERLIST, \"$8\", \"$9\", \"$10\");\n\treturn r7 && r2>0 ? -r2 : r2;\n}\n\nstatic inline long __syscall5(long n, long a, long b, long c, long d, long e)\n{\n\tregister long r4 __asm__(\"$4\") = a;\n\tregister long r5 __asm__(\"$5\") = b;\n\tregister long r6 __asm__(\"$6\") = c;\n\tregister long r7 __asm__(\"$7\") = d;\n\tregister long r8 __asm__(\"$8\") = e;\n\tregister long r2 __asm__(\"$2\");\n\t__asm__ __volatile__ (\n\t\t\"subu $sp,$sp,32 ; sw $8,16($sp) ; \"\n\t\t\"addu $2,$0,%3 ; syscall ;\"\n\t\t\"addu $sp,$sp,32\"\n\t\t: \"=&r\"(r2), \"+r\"(r7), \"+r\"(r8)\n\t\t: \"ir\"(n), \"0\"(r2), \"r\"(r4), \"r\"(r5), \"r\"(r6)\n\t\t: SYSCALL_CLOBBERLIST, \"$9\", \"$10\");\n\treturn r7 && r2>0 ? -r2 : r2;\n}\n\nstatic inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)\n{\n\tregister long r4 __asm__(\"$4\") = a;\n\tregister long r5 __asm__(\"$5\") = b;\n\tregister long r6 __asm__(\"$6\") = c;\n\tregister long r7 __asm__(\"$7\") = d;\n\tregister long r8 __asm__(\"$8\") = e;\n\tregister long r9 __asm__(\"$9\") = f;\n\tregister long r2 __asm__(\"$2\");\n\t__asm__ __volatile__ (\n\t\t\"subu $sp,$sp,32 ; sw $8,16($sp) ; sw $9,20($sp) ; \"\n\t\t\"addu $2,$0,%4 ; syscall ;\"\n\t\t\"addu $sp,$sp,32\"\n\t\t: \"=&r\"(r2), \"+r\"(r7), \"+r\"(r8), \"+r\"(r9)\n\t\t: \"ir\"(n), \"0\"(r2), \"r\"(r4), \"r\"(r5), \"r\"(r6)\n\t\t: SYSCALL_CLOBBERLIST, \"$10\");\n\treturn r7 && r2>0 ? -r2 : r2;\n}\n\nstatic inline long __syscall7(long n, long a, long b, long c, long d, long e, long f, long g)\n{\n\tregister long r4 __asm__(\"$4\") = a;\n\tregister long r5 __asm__(\"$5\") = b;\n\tregister long r6 __asm__(\"$6\") = c;\n\tregister long r7 __asm__(\"$7\") = d;\n\tregister long r8 __asm__(\"$8\") = e;\n\tregister long r9 __asm__(\"$9\") = f;\n\tregister long r10 __asm__(\"$10\") = g;\n\tregister long r2 __asm__(\"$2\");\n\t__asm__ __volatile__ (\n\t\t\"subu $sp,$sp,32 ; sw $8,16($sp) ; sw $9,20($sp) ; sw $10,24($sp) ; \"\n\t\t\"addu $2,$0,%5 ; syscall ;\"\n\t\t\"addu $sp,$sp,32\"\n\t\t: \"=&r\"(r2), \"+r\"(r7), \"+r\"(r8), \"+r\"(r9), \"+r\"(r10)\n\t\t: \"ir\"(n), \"0\"(r2), \"r\"(r4), \"r\"(r5), \"r\"(r6)\n\t\t: SYSCALL_CLOBBERLIST);\n\treturn r7 && r2>0 ? -r2 : r2;\n}\n\n#define VDSO_USEFUL\n#define VDSO_CGT32_SYM \"__vdso_clock_gettime\"\n#define VDSO_CGT32_VER \"LINUX_2.6\"\n#define VDSO_CGT_SYM \"__vdso_clock_gettime64\"\n#define VDSO_CGT_VER \"LINUX_2.6\"\n\n#define SO_SNDTIMEO_OLD 0x1005\n#define SO_RCVTIMEO_OLD 0x1006\n\n#undef SYS_socketcall\n"
  },
  {
    "path": "user.libc/arch/mips64/atomic_arch.h",
    "content": "#if __mips_isa_rev < 6\n#define LLSC_M \"m\"\n#else\n#define LLSC_M \"ZC\"\n#endif\n\n#define a_ll a_ll\nstatic inline int a_ll(volatile int *p)\n{\n\tint v;\n\t__asm__ __volatile__ (\n\t\t\"ll %0, %1\"\n\t\t: \"=r\"(v) : LLSC_M(*p));\n\treturn v;\n}\n\n#define a_sc a_sc\nstatic inline int a_sc(volatile int *p, int v)\n{\n\tint r;\n\t__asm__ __volatile__ (\n\t\t\"sc %0, %1\"\n\t\t: \"=r\"(r), \"=\"LLSC_M(*p) : \"0\"(v) : \"memory\");\n\treturn r;\n}\n\n#define a_ll_p a_ll_p\nstatic inline void *a_ll_p(volatile void *p)\n{\n\tvoid *v;\n\t__asm__ __volatile__ (\n\t\t\"lld %0, %1\"\n\t\t: \"=r\"(v) : LLSC_M(*(void *volatile *)p));\n\treturn v;\n}\n\n#define a_sc_p a_sc_p\nstatic inline int a_sc_p(volatile void *p, void *v)\n{\n\tlong r;\n\t__asm__ __volatile__ (\n\t\t\"scd %0, %1\"\n\t\t: \"=r\"(r), \"=\"LLSC_M(*(void *volatile *)p) : \"0\"(v) : \"memory\");\n\treturn r;\n}\n\n#define a_barrier a_barrier\nstatic inline void a_barrier()\n{\n\t__asm__ __volatile__ (\"sync\" : : : \"memory\");\n}\n\n#define a_pre_llsc a_barrier\n#define a_post_llsc a_barrier\n\n#undef LLSC_M\n"
  },
  {
    "path": "user.libc/arch/mips64/bits/alltypes.h.in",
    "content": "#define _Addr long\n#define _Int64 long\n#define _Reg long\n\n#if _MIPSEL || __MIPSEL || __MIPSEL__\n#define __BYTE_ORDER 1234\n#else\n#define __BYTE_ORDER 4321\n#endif\n\n#define __LONG_MAX 0x7fffffffffffffffL\n\n#ifndef __cplusplus\nTYPEDEF int wchar_t;\n#endif\n\nTYPEDEF float float_t;\nTYPEDEF double double_t;\n\nTYPEDEF struct { long long __ll; long double __ld; } max_align_t;\n\nTYPEDEF unsigned nlink_t;\n"
  },
  {
    "path": "user.libc/arch/mips64/bits/errno.h",
    "content": "#define EPERM            1\n#define ENOENT           2\n#define ESRCH            3\n#define EINTR            4\n#define EIO              5\n#define ENXIO            6\n#define E2BIG            7\n#define ENOEXEC          8\n#define EBADF            9\n#define ECHILD          10\n#define EAGAIN          11\n#define ENOMEM          12\n#define EACCES          13\n#define EFAULT          14\n#define ENOTBLK         15\n#define EBUSY           16\n#define EEXIST          17\n#define EXDEV           18\n#define ENODEV          19\n#define ENOTDIR         20\n#define EISDIR          21\n#define EINVAL          22\n#define ENFILE          23\n#define EMFILE          24\n#define ENOTTY          25\n#define ETXTBSY         26\n#define EFBIG           27\n#define ENOSPC          28\n#define ESPIPE          29\n#define EROFS           30\n#define EMLINK          31\n#define EPIPE           32\n#define EDOM            33\n#define ERANGE          34\n#define ENOMSG          35\n#define EIDRM           36\n#define ECHRNG          37\n#define EL2NSYNC        38\n#define EL3HLT          39\n#define EL3RST          40\n#define ELNRNG          41\n#define EUNATCH         42\n#define ENOCSI          43\n#define EL2HLT          44\n#define EDEADLK         45\n#define ENOLCK          46\n#define EBADE           50\n#define EBADR           51\n#define EXFULL          52\n#define ENOANO          53\n#define EBADRQC         54\n#define EBADSLT         55\n#define EDEADLOCK       56\n#define EBFONT          59\n#define ENOSTR          60\n#define ENODATA         61\n#define ETIME           62\n#define ENOSR           63\n#define ENONET          64\n#define ENOPKG          65\n#define EREMOTE         66\n#define ENOLINK         67\n#define EADV            68\n#define ESRMNT          69\n#define ECOMM           70\n#define EPROTO          71\n#define EDOTDOT         73\n#define EMULTIHOP       74\n#define EBADMSG         77\n#define ENAMETOOLONG    78\n#define EOVERFLOW       79\n#define ENOTUNIQ        80\n#define EBADFD          81\n#define EREMCHG         82\n#define ELIBACC         83\n#define ELIBBAD         84\n#define ELIBSCN         85\n#define ELIBMAX         86\n#define ELIBEXEC        87\n#define EILSEQ          88\n#define ENOSYS          89\n#define ELOOP           90\n#define ERESTART        91\n#define ESTRPIPE        92\n#define ENOTEMPTY       93\n#define EUSERS          94\n#define ENOTSOCK        95\n#define EDESTADDRREQ    96\n#define EMSGSIZE        97\n#define EPROTOTYPE      98\n#define ENOPROTOOPT     99\n#define EPROTONOSUPPORT 120\n#define ESOCKTNOSUPPORT 121\n#define EOPNOTSUPP      122\n#define ENOTSUP         EOPNOTSUPP\n#define EPFNOSUPPORT    123\n#define EAFNOSUPPORT    124\n#define EADDRINUSE      125\n#define EADDRNOTAVAIL   126\n#define ENETDOWN        127\n#define ENETUNREACH     128\n#define ENETRESET       129\n#define ECONNABORTED    130\n#define ECONNRESET      131\n#define ENOBUFS         132\n#define EISCONN         133\n#define ENOTCONN        134\n#define EUCLEAN         135\n#define ENOTNAM         137\n#define ENAVAIL         138\n#define EISNAM          139\n#define EREMOTEIO       140\n#define ESHUTDOWN       143\n#define ETOOMANYREFS    144\n#define ETIMEDOUT       145\n#define ECONNREFUSED    146\n#define EHOSTDOWN       147\n#define EHOSTUNREACH    148\n#define EWOULDBLOCK     EAGAIN\n#define EALREADY        149\n#define EINPROGRESS     150\n#define ESTALE          151\n#define ECANCELED       158\n#define ENOMEDIUM       159\n#define EMEDIUMTYPE     160\n#define ENOKEY          161\n#define EKEYEXPIRED     162\n#define EKEYREVOKED     163\n#define EKEYREJECTED    164\n#define EOWNERDEAD      165\n#define ENOTRECOVERABLE 166\n#define ERFKILL         167\n#define EHWPOISON       168\n#define EDQUOT          1133\n"
  },
  {
    "path": "user.libc/arch/mips64/bits/fcntl.h",
    "content": "#define O_CREAT        0400\n#define O_EXCL        02000\n#define O_NOCTTY      04000\n#define O_TRUNC       01000\n#define O_APPEND       0010\n#define O_NONBLOCK     0200\n#define O_DSYNC        0020\n#define O_SYNC       040020\n#define O_RSYNC      040020\n#define O_DIRECTORY 0200000\n#define O_NOFOLLOW  0400000\n#define O_CLOEXEC  02000000\n\n#define O_ASYNC      010000\n#define O_DIRECT    0100000\n#define O_LARGEFILE  020000\n#define O_NOATIME  01000000\n#define O_PATH    010000000\n#define O_TMPFILE 020200000\n#define O_NDELAY O_NONBLOCK\n\n#define F_DUPFD  0\n#define F_GETFD  1\n#define F_SETFD  2\n#define F_GETFL  3\n#define F_SETFL  4\n\n#define F_SETOWN 24\n#define F_GETOWN 23\n#define F_SETSIG 10\n#define F_GETSIG 11\n\n#define F_GETLK 14\n#define F_SETLK  6\n#define F_SETLKW 7\n\n#define F_SETOWN_EX 15\n#define F_GETOWN_EX 16\n\n#define F_GETOWNER_UIDS 17\n"
  },
  {
    "path": "user.libc/arch/mips64/bits/fenv.h",
    "content": "#ifdef __mips_soft_float\n#define FE_ALL_EXCEPT 0\n#define FE_TONEAREST  0\n#else\n#define FE_INEXACT    4\n#define FE_UNDERFLOW  8\n#define FE_OVERFLOW   16\n#define FE_DIVBYZERO  32\n#define FE_INVALID    64\n\n#define FE_ALL_EXCEPT 124\n\n#define FE_TONEAREST  0\n#define FE_TOWARDZERO 1\n#define FE_UPWARD     2\n#define FE_DOWNWARD   3\n#endif\n\ntypedef unsigned short fexcept_t;\n\ntypedef struct {\n\tunsigned __cw;\n} fenv_t;\n\n#define FE_DFL_ENV ((const fenv_t *) -1)\n"
  },
  {
    "path": "user.libc/arch/mips64/bits/float.h",
    "content": "#define FLT_EVAL_METHOD 0\n\n#define LDBL_TRUE_MIN 6.47517511943802511092443895822764655e-4966L\n#define LDBL_MIN 3.36210314311209350626267781732175260e-4932L\n#define LDBL_MAX 1.18973149535723176508575932662800702e+4932L\n#define LDBL_EPSILON 1.92592994438723585305597794258492732e-34L\n\n#define LDBL_MANT_DIG 113\n#define LDBL_MIN_EXP (-16381)\n#define LDBL_MAX_EXP 16384\n\n#define LDBL_DIG 33\n#define LDBL_MIN_10_EXP (-4931)\n#define LDBL_MAX_10_EXP 4932\n\n#define DECIMAL_DIG 36\n"
  },
  {
    "path": "user.libc/arch/mips64/bits/hwcap.h",
    "content": "#define HWCAP_MIPS_R6\t\t(1 << 0)\n#define HWCAP_MIPS_MSA\t\t(1 << 1)\n#define HWCAP_MIPS_CRC32\t(1 << 2)\n"
  },
  {
    "path": "user.libc/arch/mips64/bits/ioctl.h",
    "content": "#define _IOC(a,b,c,d) ( ((a)<<29) | ((b)<<8) | (c) | ((d)<<16) )\n#define _IOC_NONE  1U\n#define _IOC_READ  2U\n#define _IOC_WRITE 4U\n\n#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)\n#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c))\n#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c))\n#define _IOWR(a,b,c) _IOC(_IOC_READ|_IOC_WRITE,(a),(b),sizeof(c))\n\n#define TCGETA\t\t0x5401\n#define TCSETA\t\t0x5402\n#define TCSETAW\t\t0x5403\n#define TCSETAF\t\t0x5404\n#define TCSBRK\t\t0x5405\n#define TCXONC\t\t0x5406\n#define TCFLSH\t\t0x5407\n#define TCGETS\t\t0x540D\n#define TCSETS\t\t0x540E\n#define TCSETSW\t\t0x540F\n#define TCSETSF\t\t0x5410\n\n#define TIOCEXCL\t0x740D\n#define TIOCNXCL\t0x740E\n#define TIOCOUTQ\t0x7472\n#define TIOCSTI\t\t0x5472\n#define TIOCMGET\t0x741D\n#define TIOCMBIS\t0x741B\n#define TIOCMBIC\t0x741C\n#define TIOCMSET\t0x741A\n\n#define TIOCPKT\t\t0x5470\n#define TIOCSWINSZ\t_IOW('t', 103, struct winsize)\n#define TIOCGWINSZ\t_IOR('t', 104, struct winsize)\n#define TIOCNOTTY\t0x5471\n#define TIOCSETD\t0x7401\n#define TIOCGETD\t0x7400\n\n#define FIOCLEX\t\t0x6601\n#define FIONCLEX\t0x6602\n#define FIOASYNC\t0x667D\n#define FIONBIO\t\t0x667E\n#define FIOQSIZE\t0x667F\n\n#define TIOCGLTC        0x7474\n#define TIOCSLTC        0x7475\n#define TIOCSPGRP\t_IOW('t', 118, int)\n#define TIOCGPGRP\t_IOR('t', 119, int)\n#define TIOCCONS\t_IOW('t', 120, int)\n\n#define FIONREAD\t0x467F\n#define TIOCINQ\t\tFIONREAD\n\n#define TIOCGETP        0x7408\n#define TIOCSETP        0x7409\n#define TIOCSETN        0x740A\n\n#define TIOCSBRK\t0x5427\n#define TIOCCBRK\t0x5428\n#define TIOCGSID\t0x7416\n#define TIOCGRS485\t_IOR('T', 0x2E, char[32])\n#define TIOCSRS485\t_IOWR('T', 0x2F, char[32])\n#define TIOCGPTN\t_IOR('T', 0x30, unsigned int)\n#define TIOCSPTLCK\t_IOW('T', 0x31, int)\n#define TIOCGDEV\t_IOR('T', 0x32, unsigned int)\n#define TIOCSIG\t\t_IOW('T', 0x36, int)\n#define TIOCVHANGUP\t0x5437\n#define TIOCGPKT\t_IOR('T', 0x38, int)\n#define TIOCGPTLCK\t_IOR('T', 0x39, int)\n#define TIOCGEXCL\t_IOR('T', 0x40, int)\n#define TIOCGPTPEER\t_IO('T', 0x41)\n\n#define TIOCSCTTY\t0x5480\n#define TIOCGSOFTCAR\t0x5481\n#define TIOCSSOFTCAR\t0x5482\n#define TIOCLINUX\t0x5483\n#define TIOCGSERIAL\t0x5484\n#define TIOCSSERIAL\t0x5485\n#define TCSBRKP\t\t0x5486\n\n#define TIOCSERCONFIG\t0x5488\n#define TIOCSERGWILD\t0x5489\n#define TIOCSERSWILD\t0x548A\n#define TIOCGLCKTRMIOS\t0x548B\n#define TIOCSLCKTRMIOS\t0x548C\n#define TIOCSERGSTRUCT\t0x548D\n#define TIOCSERGETLSR   0x548E\n#define TIOCSERGETMULTI 0x548F\n#define TIOCSERSETMULTI 0x5490\n#define TIOCMIWAIT\t0x5491\n#define TIOCGICOUNT\t0x5492\n\n#define TIOCM_LE\t0x001\n#define TIOCM_DTR\t0x002\n#define TIOCM_RTS\t0x004\n#define TIOCM_ST\t0x010\n#define TIOCM_SR\t0x020\n#define TIOCM_CTS\t0x040\n#define TIOCM_CAR\t0x100\n#define TIOCM_CD\tTIOCM_CAR\n#define TIOCM_RNG\t0x200\n#define TIOCM_RI\tTIOCM_RNG\n#define TIOCM_DSR\t0x400\n#define TIOCM_OUT1\t0x2000\n#define TIOCM_OUT2\t0x4000\n#define TIOCM_LOOP\t0x8000\n\n#define FIOGETOWN       _IOR('f', 123, int)\n#define FIOSETOWN       _IOW('f', 124, int)\n#define SIOCATMARK      _IOR('s', 7, int)\n#define SIOCSPGRP       _IOW('s', 8, pid_t)\n#define SIOCGPGRP       _IOR('s', 9, pid_t)\n#define SIOCGSTAMP      0x8906\n#define SIOCGSTAMPNS    0x8907\n"
  },
  {
    "path": "user.libc/arch/mips64/bits/ipc.h",
    "content": "struct ipc_perm {\n\tkey_t __ipc_perm_key;\n\tuid_t uid;\n\tgid_t gid;\n\tuid_t cuid;\n\tgid_t cgid;\n\tmode_t mode;\n\tint __ipc_perm_seq;\n\tint __pad1;\n\tunsigned long __unused1;\n\tunsigned long __unused2;\n};\n"
  },
  {
    "path": "user.libc/arch/mips64/bits/mman.h",
    "content": "#undef MAP_ANON\n#define MAP_ANON       0x800\n#undef MAP_NORESERVE\n#define MAP_NORESERVE  0x0400\n#undef MAP_GROWSDOWN\n#define MAP_GROWSDOWN  0x1000\n#undef MAP_DENYWRITE\n#define MAP_DENYWRITE  0x2000\n#undef MAP_EXECUTABLE\n#define MAP_EXECUTABLE 0x4000\n#undef MAP_LOCKED\n#define MAP_LOCKED     0x8000\n#undef MAP_POPULATE\n#define MAP_POPULATE   0x10000\n#undef MAP_NONBLOCK\n#define MAP_NONBLOCK   0x20000\n#undef MAP_STACK\n#define MAP_STACK      0x40000\n#undef MAP_HUGETLB\n#define MAP_HUGETLB    0x80000\n#undef MAP_SYNC\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#undef MADV_SOFT_OFFLINE\n#endif\n"
  },
  {
    "path": "user.libc/arch/mips64/bits/poll.h",
    "content": "#define POLLWRNORM POLLOUT\n#define POLLWRBAND 0x100\n"
  },
  {
    "path": "user.libc/arch/mips64/bits/posix.h",
    "content": "#define _POSIX_V6_LP64_OFFBIG 1\n#define _POSIX_V7_LP64_OFFBIG 1\n"
  },
  {
    "path": "user.libc/arch/mips64/bits/ptrace.h",
    "content": "#define PTRACE_GET_THREAD_AREA\t25\n#define PTRACE_SET_THREAD_AREA\t26\n#define PTRACE_PEEKTEXT_3264\t0xc0\n#define PTRACE_PEEKDATA_3264\t0xc1\n#define PTRACE_POKETEXT_3264\t0xc2\n#define PTRACE_POKEDATA_3264\t0xc3\n#define PTRACE_GET_THREAD_AREA_3264\t0xc4\n#define PTRACE_GET_WATCH_REGS\t0xd0\n#define PTRACE_SET_WATCH_REGS\t0xd1\n"
  },
  {
    "path": "user.libc/arch/mips64/bits/reg.h",
    "content": "#undef __WORDSIZE\n#define __WORDSIZE 64\n\n#define EF_R0 0\n#define EF_R1 1\n#define EF_R2 2\n#define EF_R3 3\n#define EF_R4 4\n#define EF_R5 5\n#define EF_R6 6\n#define EF_R7 7\n#define EF_R8 8\n#define EF_R9 9\n#define EF_R10 10\n#define EF_R11 11\n#define EF_R12 12\n#define EF_R13 13\n#define EF_R14 14\n#define EF_R15 15\n#define EF_R16 16\n#define EF_R17 17\n#define EF_R18 18\n#define EF_R19 19\n#define EF_R20 20\n#define EF_R21 21\n#define EF_R22 22\n#define EF_R23 23\n#define EF_R24 24\n#define EF_R25 25\n\n#define EF_R26 26\n#define EF_R27 27\n#define EF_R28 28\n#define EF_R29 29\n#define EF_R30 30\n#define EF_R31 31\n\n#define EF_LO 32\n#define EF_HI 33\n\n#define EF_CP0_EPC 34\n#define EF_CP0_BADVADDR 35\n#define EF_CP0_STATUS 36\n#define EF_CP0_CAUSE 37\n#define EF_UNUSED0 38\n\n#define EF_SIZE 304\n"
  },
  {
    "path": "user.libc/arch/mips64/bits/resource.h",
    "content": "#define RLIMIT_NOFILE  5\n#define RLIMIT_AS      6\n#define RLIMIT_RSS     7\n#define RLIMIT_NPROC   8\n#define RLIMIT_MEMLOCK 9\n"
  },
  {
    "path": "user.libc/arch/mips64/bits/setjmp.h",
    "content": "typedef unsigned long long __jmp_buf[23];\n"
  },
  {
    "path": "user.libc/arch/mips64/bits/signal.h",
    "content": "#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define MINSIGSTKSZ 2048\n#define SIGSTKSZ 8192\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\ntypedef unsigned long long greg_t, gregset_t[32];\n\ntypedef struct {\n\tunion {\n\t\tdouble fp_dregs[32];\n\t\tstruct {\n\t\t\tfloat _fp_fregs;\n\t\t\tunsigned _fp_pad;\n\t\t} fp_fregs[32];\n\t} fp_r;\n} fpregset_t;\n\nstruct sigcontext {\n\tunsigned long long sc_regs[32];\n\tunsigned long long sc_fpregs[32];\n\tunsigned long long sc_mdhi;\n\tunsigned long long sc_hi1;\n\tunsigned long long sc_hi2;\n\tunsigned long long sc_hi3;\n\tunsigned long long sc_mdlo;\n\tunsigned long long sc_lo1;\n\tunsigned long long sc_lo2;\n\tunsigned long long sc_lo3;\n\tunsigned long long sc_pc;\n\tunsigned int sc_fpc_csr;\n\tunsigned int sc_used_math;\n\tunsigned int sc_dsp;\n\tunsigned int sc_reserved;\n};\n\ntypedef struct {\n\tgregset_t gregs;\n\tfpregset_t fpregs;\n\tgreg_t mdhi;\n\tgreg_t hi1;\n\tgreg_t hi2;\n\tgreg_t hi3;\n\tgreg_t mdlo;\n\tgreg_t lo1;\n\tgreg_t lo2;\n\tgreg_t lo3;\n\tgreg_t pc;\n\tunsigned int fpc_csr;\n\tunsigned int used_math;\n\tunsigned int dsp;\n\tunsigned int reserved;\n} mcontext_t;\n\n#else\ntypedef struct {\n\tunsigned long long __mc1[32];\n\tdouble __mc2[32];\n\tunsigned long long __mc3[9];\n\tunsigned __mc4[4];\n} mcontext_t;\n#endif\n\nstruct sigaltstack {\n\tvoid *ss_sp;\n\tsize_t ss_size;\n\tint ss_flags;\n};\n\ntypedef struct __ucontext {\n\tunsigned long uc_flags;\n\tstruct __ucontext *uc_link;\n\tstack_t uc_stack;\n\tmcontext_t uc_mcontext;\n\tsigset_t uc_sigmask;\n} ucontext_t;\n\n#define SA_NOCLDSTOP  1\n#define SA_NOCLDWAIT  0x10000\n#define SA_SIGINFO    8\n#define SA_ONSTACK    0x08000000\n#define SA_RESTART    0x10000000\n#define SA_NODEFER    0x40000000\n#define SA_RESETHAND  0x80000000\n#define SA_RESTORER   0x04000000\n\n#undef SIG_BLOCK\n#undef SIG_UNBLOCK\n#undef SIG_SETMASK\n#define SIG_BLOCK     1\n#define SIG_UNBLOCK   2\n#define SIG_SETMASK   3\n\n#undef SI_ASYNCIO\n#undef SI_MESGQ\n#undef SI_TIMER\n#define SI_ASYNCIO (-2)\n#define SI_MESGQ (-4)\n#define SI_TIMER (-3)\n\n#define __SI_SWAP_ERRNO_CODE\n\n#endif\n\n#define SIGHUP    1\n#define SIGINT    2\n#define SIGQUIT   3\n#define SIGILL    4\n#define SIGTRAP   5\n#define SIGABRT   6\n#define SIGIOT    SIGABRT\n#define SIGEMT    7\n#define SIGFPE    8\n#define SIGKILL   9\n#define SIGBUS    10\n#define SIGSEGV   11\n#define SIGSYS    12\n#define SIGPIPE   13\n#define SIGALRM   14\n#define SIGTERM   15\n#define SIGUSR1   16\n#define SIGUSR2   17\n#define SIGCHLD   18\n#define SIGPWR    19\n#define SIGWINCH  20\n#define SIGURG    21\n#define SIGIO     22\n#define SIGPOLL   SIGIO\n#define SIGSTOP   23\n#define SIGTSTP   24\n#define SIGCONT   25\n#define SIGTTIN   26\n#define SIGTTOU   27\n#define SIGVTALRM 28\n#define SIGPROF   29\n#define SIGXCPU   30\n#define SIGXFSZ   31\n#define SIGUNUSED SIGSYS\n\n#define _NSIG 128\n"
  },
  {
    "path": "user.libc/arch/mips64/bits/socket.h",
    "content": "#define SOCK_STREAM    2\n#define SOCK_DGRAM     1\n#define SOL_SOCKET     65535\n#define SO_DEBUG       1\n\n#define SO_REUSEADDR    0x0004\n#define SO_KEEPALIVE    0x0008\n#define SO_DONTROUTE    0x0010\n#define SO_BROADCAST    0x0020\n#define SO_LINGER       0x0080\n#define SO_OOBINLINE    0x0100\n#define SO_REUSEPORT    0x0200\n#define SO_SNDBUF       0x1001\n#define SO_RCVBUF       0x1002\n#define SO_SNDLOWAT     0x1003\n#define SO_RCVLOWAT     0x1004\n#define SO_RCVTIMEO     0x1006\n#define SO_SNDTIMEO     0x1005\n#define SO_ERROR        0x1007\n#define SO_TYPE         0x1008\n#define SO_ACCEPTCONN   0x1009\n#define SO_PROTOCOL     0x1028\n#define SO_DOMAIN       0x1029\n\n#define SO_NO_CHECK     11\n#define SO_PRIORITY     12\n#define SO_BSDCOMPAT    14\n#define SO_PASSCRED     17\n#define SO_PEERCRED     18\n#define SO_PEERSEC      30\n#define SO_SNDBUFFORCE  31\n#define SO_RCVBUFFORCE  33\n\n#define SOCK_NONBLOCK     0200\n#define SOCK_CLOEXEC  02000000\n"
  },
  {
    "path": "user.libc/arch/mips64/bits/stat.h",
    "content": "struct stat {\n\tdev_t st_dev;\n\tint __pad1[3];\n\tino_t st_ino;\n\tmode_t st_mode;\n\tnlink_t st_nlink;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tdev_t st_rdev;\n\tunsigned int __pad2[2];\n\toff_t st_size;\n\tint __pad3;\n\tstruct timespec st_atim;\n\tstruct timespec st_mtim;\n\tstruct timespec st_ctim;\n\tblksize_t st_blksize;\n\tunsigned int __pad4;\n\tblkcnt_t st_blocks;\n\tint __pad5[14];\n};\n"
  },
  {
    "path": "user.libc/arch/mips64/bits/statfs.h",
    "content": "struct statfs {\n\tunsigned long f_type, f_bsize, f_frsize;\n\tfsblkcnt_t f_blocks, f_bfree;\n\tfsfilcnt_t f_files, f_ffree;\n\tfsblkcnt_t f_bavail;\n\tfsid_t f_fsid;\n\tunsigned long f_namelen, f_flags, f_spare[5];\n};\n"
  },
  {
    "path": "user.libc/arch/mips64/bits/stdint.h",
    "content": "typedef int32_t int_fast16_t;\ntypedef int32_t int_fast32_t;\ntypedef uint32_t uint_fast16_t;\ntypedef uint32_t uint_fast32_t;\n\n#define INT_FAST16_MIN  INT32_MIN\n#define INT_FAST32_MIN  INT32_MIN\n\n#define INT_FAST16_MAX  INT32_MAX\n#define INT_FAST32_MAX  INT32_MAX\n\n#define UINT_FAST16_MAX UINT32_MAX\n#define UINT_FAST32_MAX UINT32_MAX\n\n#define INTPTR_MIN      INT64_MIN\n#define INTPTR_MAX      INT64_MAX\n#define UINTPTR_MAX     UINT64_MAX\n#define PTRDIFF_MIN     INT64_MIN\n#define PTRDIFF_MAX     INT64_MAX\n#define SIZE_MAX        UINT64_MAX\n"
  },
  {
    "path": "user.libc/arch/mips64/bits/syscall.h.in",
    "content": "#define __NR_read\t\t\t5000\n#define __NR_write\t\t\t5001\n#define __NR_open\t\t\t5002\n#define __NR_close\t\t\t5003\n#define __NR_stat\t\t\t5004\n#define __NR_fstat\t\t\t5005\n#define __NR_lstat\t\t\t5006\n#define __NR_poll\t\t\t5007\n#define __NR_lseek\t\t\t5008\n#define __NR_mmap\t\t\t5009\n#define __NR_mprotect\t\t\t5010\n#define __NR_munmap\t\t\t5011\n#define __NR_brk\t\t\t5012\n#define __NR_rt_sigaction\t\t5013\n#define __NR_rt_sigprocmask\t\t5014\n#define __NR_ioctl\t\t\t5015\n#define __NR_pread64\t\t\t5016\n#define __NR_pwrite64\t\t\t5017\n#define __NR_readv\t\t\t5018\n#define __NR_writev\t\t\t5019\n#define __NR_access\t\t\t5020\n#define __NR_pipe\t\t\t5021\n#define __NR__newselect\t\t\t5022\n#define __NR_sched_yield\t\t5023\n#define __NR_mremap\t\t\t5024\n#define __NR_msync\t\t\t5025\n#define __NR_mincore\t\t\t5026\n#define __NR_madvise\t\t\t5027\n#define __NR_shmget\t\t\t5028\n#define __NR_shmat\t\t\t5029\n#define __NR_shmctl\t\t\t5030\n#define __NR_dup\t\t\t5031\n#define __NR_dup2\t\t\t5032\n#define __NR_pause\t\t\t5033\n#define __NR_nanosleep\t\t\t5034\n#define __NR_getitimer\t\t\t5035\n#define __NR_setitimer\t\t\t5036\n#define __NR_alarm\t\t\t5037\n#define __NR_getpid\t\t\t5038\n#define __NR_sendfile\t\t\t5039\n#define __NR_socket\t\t\t5040\n#define __NR_connect\t\t\t5041\n#define __NR_accept\t\t\t5042\n#define __NR_sendto\t\t\t5043\n#define __NR_recvfrom\t\t\t5044\n#define __NR_sendmsg\t\t\t5045\n#define __NR_recvmsg\t\t\t5046\n#define __NR_shutdown\t\t\t5047\n#define __NR_bind\t\t\t5048\n#define __NR_listen\t\t\t5049\n#define __NR_getsockname\t\t5050\n#define __NR_getpeername\t\t5051\n#define __NR_socketpair\t\t\t5052\n#define __NR_setsockopt\t\t\t5053\n#define __NR_getsockopt\t\t\t5054\n#define __NR_clone\t\t\t5055\n#define __NR_fork\t\t\t5056\n#define __NR_execve\t\t\t5057\n#define __NR_exit\t\t\t5058\n#define __NR_wait4\t\t\t5059\n#define __NR_kill\t\t\t5060\n#define __NR_uname\t\t\t5061\n#define __NR_semget\t\t\t5062\n#define __NR_semop\t\t\t5063\n#define __NR_semctl\t\t\t5064\n#define __NR_shmdt\t\t\t5065\n#define __NR_msgget\t\t\t5066\n#define __NR_msgsnd\t\t\t5067\n#define __NR_msgrcv\t\t\t5068\n#define __NR_msgctl\t\t\t5069\n#define __NR_fcntl\t\t\t5070\n#define __NR_flock\t\t\t5071\n#define __NR_fsync\t\t\t5072\n#define __NR_fdatasync\t\t\t5073\n#define __NR_truncate\t\t\t5074\n#define __NR_ftruncate\t\t\t5075\n#define __NR_getdents\t\t\t5076\n#define __NR_getcwd\t\t\t5077\n#define __NR_chdir\t\t\t5078\n#define __NR_fchdir\t\t\t5079\n#define __NR_rename\t\t\t5080\n#define __NR_mkdir\t\t\t5081\n#define __NR_rmdir\t\t\t5082\n#define __NR_creat\t\t\t5083\n#define __NR_link\t\t\t5084\n#define __NR_unlink\t\t\t5085\n#define __NR_symlink\t\t\t5086\n#define __NR_readlink\t\t\t5087\n#define __NR_chmod\t\t\t5088\n#define __NR_fchmod\t\t\t5089\n#define __NR_chown\t\t\t5090\n#define __NR_fchown\t\t\t5091\n#define __NR_lchown\t\t\t5092\n#define __NR_umask\t\t\t5093\n#define __NR_gettimeofday\t\t5094\n#define __NR_getrlimit\t\t\t5095\n#define __NR_getrusage\t\t\t5096\n#define __NR_sysinfo\t\t\t5097\n#define __NR_times\t\t\t5098\n#define __NR_ptrace\t\t\t5099\n#define __NR_getuid\t\t\t5100\n#define __NR_syslog\t\t\t5101\n#define __NR_getgid\t\t\t5102\n#define __NR_setuid\t\t\t5103\n#define __NR_setgid\t\t\t5104\n#define __NR_geteuid\t\t\t5105\n#define __NR_getegid\t\t\t5106\n#define __NR_setpgid\t\t\t5107\n#define __NR_getppid\t\t\t5108\n#define __NR_getpgrp\t\t\t5109\n#define __NR_setsid\t\t\t5110\n#define __NR_setreuid\t\t\t5111\n#define __NR_setregid\t\t\t5112\n#define __NR_getgroups\t\t\t5113\n#define __NR_setgroups\t\t\t5114\n#define __NR_setresuid\t\t\t5115\n#define __NR_getresuid\t\t\t5116\n#define __NR_setresgid\t\t\t5117\n#define __NR_getresgid\t\t\t5118\n#define __NR_getpgid\t\t\t5119\n#define __NR_setfsuid\t\t\t5120\n#define __NR_setfsgid\t\t\t5121\n#define __NR_getsid\t\t\t5122\n#define __NR_capget\t\t\t5123\n#define __NR_capset\t\t\t5124\n#define __NR_rt_sigpending\t\t5125\n#define __NR_rt_sigtimedwait\t\t5126\n#define __NR_rt_sigqueueinfo\t\t5127\n#define __NR_rt_sigsuspend\t\t5128\n#define __NR_sigaltstack\t\t5129\n#define __NR_utime\t\t\t5130\n#define __NR_mknod\t\t\t5131\n#define __NR_personality\t\t5132\n#define __NR_ustat\t\t\t5133\n#define __NR_statfs\t\t\t5134\n#define __NR_fstatfs\t\t\t5135\n#define __NR_sysfs\t\t\t5136\n#define __NR_getpriority\t\t5137\n#define __NR_setpriority\t\t5138\n#define __NR_sched_setparam\t\t5139\n#define __NR_sched_getparam\t\t5140\n#define __NR_sched_setscheduler\t\t5141\n#define __NR_sched_getscheduler\t\t5142\n#define __NR_sched_get_priority_max\t5143\n#define __NR_sched_get_priority_min\t5144\n#define __NR_sched_rr_get_interval\t5145\n#define __NR_mlock\t\t\t5146\n#define __NR_munlock\t\t\t5147\n#define __NR_mlockall\t\t\t5148\n#define __NR_munlockall\t\t\t5149\n#define __NR_vhangup\t\t\t5150\n#define __NR_pivot_root\t\t\t5151\n#define __NR__sysctl\t\t\t5152\n#define __NR_prctl\t\t\t5153\n#define __NR_adjtimex\t\t\t5154\n#define __NR_setrlimit\t\t\t5155\n#define __NR_chroot\t\t\t5156\n#define __NR_sync\t\t\t5157\n#define __NR_acct\t\t\t5158\n#define __NR_settimeofday\t\t5159\n#define __NR_mount\t\t\t5160\n#define __NR_umount2\t\t\t5161\n#define __NR_swapon\t\t\t5162\n#define __NR_swapoff\t\t\t5163\n#define __NR_reboot\t\t\t5164\n#define __NR_sethostname\t\t5165\n#define __NR_setdomainname\t\t5166\n#define __NR_create_module\t\t5167\n#define __NR_init_module\t\t5168\n#define __NR_delete_module\t\t5169\n#define __NR_get_kernel_syms\t\t5170\n#define __NR_query_module\t\t5171\n#define __NR_quotactl\t\t\t5172\n#define __NR_nfsservctl\t\t\t5173\n#define __NR_getpmsg\t\t\t5174\n#define __NR_putpmsg\t\t\t5175\n#define __NR_afs_syscall\t\t5176\n#define __NR_reserved177\t\t5177\n#define __NR_gettid\t\t\t5178\n#define __NR_readahead\t\t\t5179\n#define __NR_setxattr\t\t\t5180\n#define __NR_lsetxattr\t\t\t5181\n#define __NR_fsetxattr\t\t\t5182\n#define __NR_getxattr\t\t\t5183\n#define __NR_lgetxattr\t\t\t5184\n#define __NR_fgetxattr\t\t\t5185\n#define __NR_listxattr\t\t\t5186\n#define __NR_llistxattr\t\t\t5187\n#define __NR_flistxattr\t\t\t5188\n#define __NR_removexattr\t\t5189\n#define __NR_lremovexattr\t\t5190\n#define __NR_fremovexattr\t\t5191\n#define __NR_tkill\t\t\t5192\n#define __NR_reserved193\t\t5193\n#define __NR_futex\t\t\t5194\n#define __NR_sched_setaffinity\t\t5195\n#define __NR_sched_getaffinity\t\t5196\n#define __NR_cacheflush\t\t\t5197\n#define __NR_cachectl\t\t\t5198\n#define __NR_sysmips\t\t\t5199\n#define __NR_io_setup\t\t\t5200\n#define __NR_io_destroy\t\t\t5201\n#define __NR_io_getevents\t\t5202\n#define __NR_io_submit\t\t\t5203\n#define __NR_io_cancel\t\t\t5204\n#define __NR_exit_group\t\t\t5205\n#define __NR_lookup_dcookie\t\t5206\n#define __NR_epoll_create\t\t5207\n#define __NR_epoll_ctl\t\t\t5208\n#define __NR_epoll_wait\t\t\t5209\n#define __NR_remap_file_pages\t\t5210\n#define __NR_rt_sigreturn\t\t5211\n#define __NR_set_tid_address\t\t5212\n#define __NR_restart_syscall\t\t5213\n#define __NR_semtimedop\t\t\t5214\n#define __NR_fadvise64\t\t\t5215\n#define __NR_timer_create\t\t5216\n#define __NR_timer_settime\t\t5217\n#define __NR_timer_gettime\t\t5218\n#define __NR_timer_getoverrun\t\t5219\n#define __NR_timer_delete\t\t5220\n#define __NR_clock_settime\t\t5221\n#define __NR_clock_gettime\t\t5222\n#define __NR_clock_getres\t\t5223\n#define __NR_clock_nanosleep\t\t5224\n#define __NR_tgkill\t\t\t5225\n#define __NR_utimes\t\t\t5226\n#define __NR_mbind\t\t\t5227\n#define __NR_get_mempolicy\t\t5228\n#define __NR_set_mempolicy\t\t5229\n#define __NR_mq_open\t\t\t5230\n#define __NR_mq_unlink\t\t\t5231\n#define __NR_mq_timedsend\t\t5232\n#define __NR_mq_timedreceive\t\t5233\n#define __NR_mq_notify\t\t\t5234\n#define __NR_mq_getsetattr\t\t5235\n#define __NR_vserver\t\t\t5236\n#define __NR_waitid\t\t\t5237\n#define __NR_add_key\t\t\t5239\n#define __NR_request_key\t\t5240\n#define __NR_keyctl\t\t\t5241\n#define __NR_set_thread_area\t\t5242\n#define __NR_inotify_init\t\t5243\n#define __NR_inotify_add_watch\t\t5244\n#define __NR_inotify_rm_watch\t\t5245\n#define __NR_migrate_pages\t\t5246\n#define __NR_openat\t\t\t5247\n#define __NR_mkdirat\t\t\t5248\n#define __NR_mknodat\t\t\t5249\n#define __NR_fchownat\t\t\t5250\n#define __NR_futimesat\t\t\t5251\n#define __NR_newfstatat\t\t\t5252\n#define __NR_unlinkat\t\t\t5253\n#define __NR_renameat\t\t\t5254\n#define __NR_linkat\t\t\t5255\n#define __NR_symlinkat\t\t\t5256\n#define __NR_readlinkat\t\t\t5257\n#define __NR_fchmodat\t\t\t5258\n#define __NR_faccessat\t\t\t5259\n#define __NR_pselect6\t\t\t5260\n#define __NR_ppoll\t\t\t5261\n#define __NR_unshare\t\t\t5262\n#define __NR_splice\t\t\t5263\n#define __NR_sync_file_range\t\t5264\n#define __NR_tee\t\t\t5265\n#define __NR_vmsplice\t\t\t5266\n#define __NR_move_pages\t\t\t5267\n#define __NR_set_robust_list\t\t5268\n#define __NR_get_robust_list\t\t5269\n#define __NR_kexec_load\t\t\t5270\n#define __NR_getcpu\t\t\t5271\n#define __NR_epoll_pwait\t\t5272\n#define __NR_ioprio_set\t\t\t5273\n#define __NR_ioprio_get\t\t\t5274\n#define __NR_utimensat\t\t\t5275\n#define __NR_signalfd\t\t\t5276\n#define __NR_timerfd\t\t\t5277\n#define __NR_eventfd\t\t\t5278\n#define __NR_fallocate\t\t\t5279\n#define __NR_timerfd_create\t\t5280\n#define __NR_timerfd_gettime\t\t5281\n#define __NR_timerfd_settime\t\t5282\n#define __NR_signalfd4\t\t\t5283\n#define __NR_eventfd2\t\t\t5284\n#define __NR_epoll_create1\t\t5285\n#define __NR_dup3\t\t\t5286\n#define __NR_pipe2\t\t\t5287\n#define __NR_inotify_init1\t\t5288\n#define __NR_preadv\t\t\t5289\n#define __NR_pwritev\t\t\t5290\n#define __NR_rt_tgsigqueueinfo\t\t5291\n#define __NR_perf_event_open\t\t5292\n#define __NR_accept4\t\t\t5293\n#define __NR_recvmmsg\t\t\t5294\n#define __NR_fanotify_init\t\t5295\n#define __NR_fanotify_mark\t\t5296\n#define __NR_prlimit64\t\t\t5297\n#define __NR_name_to_handle_at\t\t5298\n#define __NR_open_by_handle_at\t\t5299\n#define __NR_clock_adjtime\t\t5300\n#define __NR_syncfs\t\t\t5301\n#define __NR_sendmmsg\t\t\t5302\n#define __NR_setns\t\t\t5303\n#define __NR_process_vm_readv\t\t5304\n#define __NR_process_vm_writev\t\t5305\n#define __NR_kcmp\t\t\t5306\n#define __NR_finit_module\t\t5307\n#define __NR_getdents64\t\t\t5308\n#define __NR_sched_setattr\t\t5309\n#define __NR_sched_getattr\t\t5310\n#define __NR_renameat2\t\t\t5311\n#define __NR_seccomp\t\t\t5312\n#define __NR_getrandom\t\t\t5313\n#define __NR_memfd_create\t\t5314\n#define __NR_bpf\t\t\t5315\n#define __NR_execveat\t\t\t5316\n#define __NR_userfaultfd\t\t5317\n#define __NR_membarrier\t\t\t5318\n#define __NR_mlock2\t\t\t5319\n#define __NR_copy_file_range\t\t5320\n#define __NR_preadv2\t\t\t5321\n#define __NR_pwritev2\t\t\t5322\n#define __NR_pkey_mprotect\t\t5323\n#define __NR_pkey_alloc\t\t\t5324\n#define __NR_pkey_free\t\t\t5325\n#define __NR_statx\t\t\t5326\n#define __NR_rseq\t\t\t5327\n#define __NR_io_pgetevents\t\t5328\n#define __NR_pidfd_send_signal\t\t5424\n#define __NR_io_uring_setup\t\t5425\n#define __NR_io_uring_enter\t\t5426\n#define __NR_io_uring_register\t\t5427\n#define __NR_open_tree\t\t5428\n#define __NR_move_mount\t\t5429\n#define __NR_fsopen\t\t5430\n#define __NR_fsconfig\t\t5431\n#define __NR_fsmount\t\t5432\n#define __NR_fspick\t\t5433\n#define __NR_pidfd_open\t\t5434\n#define __NR_clone3\t\t5435\n#define __NR_close_range\t5436\n#define __NR_openat2\t\t5437\n#define __NR_pidfd_getfd\t5438\n#define __NR_faccessat2\t\t5439\n\n"
  },
  {
    "path": "user.libc/arch/mips64/bits/termios.h",
    "content": "struct termios {\n\ttcflag_t c_iflag;\n\ttcflag_t c_oflag;\n\ttcflag_t c_cflag;\n\ttcflag_t c_lflag;\n\tcc_t c_line;\n\tcc_t c_cc[NCCS];\n\tspeed_t __c_ispeed;\n\tspeed_t __c_ospeed;\n};\n\n#define VINTR     0\n#define VQUIT     1\n#define VERASE    2\n#define VKILL     3\n#define VMIN      4\n#define VTIME     5\n#define VEOL2     6\n#define VSWTC     7\n#define VSWTCH    7\n#define VSTART    8\n#define VSTOP     9\n#define VSUSP    10\n#define VREPRINT 12\n#define VDISCARD 13\n#define VWERASE  14\n#define VLNEXT   15\n#define VEOF     16\n#define VEOL     17\n\n#define IGNBRK  0000001\n#define BRKINT  0000002\n#define IGNPAR  0000004\n#define PARMRK  0000010\n#define INPCK   0000020\n#define ISTRIP  0000040\n#define INLCR   0000100\n#define IGNCR   0000200\n#define ICRNL   0000400\n#define IUCLC   0001000\n#define IXON    0002000\n#define IXANY   0004000\n#define IXOFF   0010000\n#define IMAXBEL 0020000\n#define IUTF8   0040000\n\n#define OPOST  0000001\n#define OLCUC  0000002\n#define ONLCR  0000004\n#define OCRNL  0000010\n#define ONOCR  0000020\n#define ONLRET 0000040\n#define OFILL  0000100\n#define OFDEL  0000200\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_XOPEN_SOURCE)\n#define NLDLY  0000400\n#define NL0    0000000\n#define NL1    0000400\n#define CRDLY  0003000\n#define CR0    0000000\n#define CR1    0001000\n#define CR2    0002000\n#define CR3    0003000\n#define TABDLY 0014000\n#define TAB0   0000000\n#define TAB1   0004000\n#define TAB2   0010000\n#define TAB3   0014000\n#define BSDLY  0020000\n#define BS0    0000000\n#define BS1    0020000\n#define FFDLY  0100000\n#define FF0    0000000\n#define FF1    0100000\n#endif\n\n#define VTDLY  0040000\n#define VT0    0000000\n#define VT1    0040000\n\n#define B0       0000000\n#define B50      0000001\n#define B75      0000002\n#define B110     0000003\n#define B134     0000004\n#define B150     0000005\n#define B200     0000006\n#define B300     0000007\n#define B600     0000010\n#define B1200    0000011\n#define B1800    0000012\n#define B2400    0000013\n#define B4800    0000014\n#define B9600    0000015\n#define B19200   0000016\n#define B38400   0000017\n\n#define B57600   0010001\n#define B115200  0010002\n#define B230400  0010003\n#define B460800  0010004\n#define B500000  0010005\n#define B576000  0010006\n#define B921600  0010007\n#define B1000000 0010010\n#define B1152000 0010011\n#define B1500000 0010012\n#define B2000000 0010013\n#define B2500000 0010014\n#define B3000000 0010015\n#define B3500000 0010016\n#define B4000000 0010017\n\n#define CSIZE  0000060\n#define CS5    0000000\n#define CS6    0000020\n#define CS7    0000040\n#define CS8    0000060\n#define CSTOPB 0000100\n#define CREAD  0000200\n#define PARENB 0000400\n#define PARODD 0001000\n#define HUPCL  0002000\n#define CLOCAL 0004000\n\n#define ISIG   0000001\n#define ICANON 0000002\n#define ECHO   0000010\n#define ECHOE  0000020\n#define ECHOK  0000040\n#define ECHONL 0000100\n#define NOFLSH 0000200\n#define IEXTEN 0000400\n#define TOSTOP 0100000\n#define ITOSTOP 0100000\n\n#define TCOOFF 0\n#define TCOON  1\n#define TCIOFF 2\n#define TCION  3\n\n#define TCIFLUSH  0\n#define TCOFLUSH  1\n#define TCIOFLUSH 2\n\n#define TCSANOW   0\n#define TCSADRAIN 1\n#define TCSAFLUSH 2\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define EXTA    0000016\n#define EXTB    0000017\n#define CBAUD   0010017\n#define CBAUDEX 0010000\n#define CIBAUD  002003600000\n#define CMSPAR  010000000000\n#define CRTSCTS 020000000000\n\n#define XCASE   0000004\n#define ECHOCTL 0001000\n#define ECHOPRT 0002000\n#define ECHOKE  0004000\n#define FLUSHO  0020000\n#define PENDIN  0040000\n#define EXTPROC 0200000\n\n#define XTABS  0014000\n#define TIOCSER_TEMT 1\n#endif\n"
  },
  {
    "path": "user.libc/arch/mips64/bits/user.h",
    "content": "struct user {\n\tunsigned long regs[102];\n\tunsigned long u_tsize, u_dsize, u_ssize;\n\tunsigned long long start_code, start_data, start_stack;\n\tlong long signal;\n\tunsigned long long *u_ar0;\n\tunsigned long long magic;\n\tchar u_comm[32];\n};\n\n#define ELF_NGREG 45\n#define ELF_NFPREG 33\n\ntypedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG];\ntypedef double elf_fpreg_t, elf_fpregset_t[ELF_NFPREG];\n"
  },
  {
    "path": "user.libc/arch/mips64/crt_arch.h",
    "content": "__asm__(\n\".set push\\n\"\n\".set noreorder\\n\"\n\".text \\n\"\n\".global _\" START \"\\n\"\n\".global \" START \"\\n\"\n\".global \" START \"_data\\n\"\n\".type   _\" START \", @function\\n\"\n\".type   \" START \", @function\\n\"\n\".type   \" START \"_data, @function\\n\"\n\"_\" START \":\\n\"\n\"\" START \":\\n\"\n\".align 8 \\n\"\n\"\tbal 1f \\n\"\n\"\t move $fp, $0 \\n\"\n\"\" START \"_data: \\n\"\n\"\t.gpdword \" START \"_data \\n\"\n\"\t.gpdword \" START \"_c \\n\"\n\".weak _DYNAMIC \\n\"\n\".hidden _DYNAMIC \\n\"\n\"\t.gpdword _DYNAMIC \\n\"\n\"1:\tld $gp, 0($ra) \\n\"\n\"\tdsubu $gp, $ra, $gp \\n\"\n\"\tmove $4, $sp \\n\"\n\"\tld $5, 16($ra) \\n\"\n\"\tdaddu $5, $5, $gp \\n\"\n\"\tld $25, 8($ra) \\n\"\n\"\tdaddu $25, $25, $gp \\n\"\n\"\tand $sp, $sp, -16 \\n\"\n\"\tjalr $25 \\n\"\n\"\tnop \\n\"\n\".set pop \\n\"\n);\n"
  },
  {
    "path": "user.libc/arch/mips64/ksigaction.h",
    "content": "#include <features.h>\n\nstruct k_sigaction {\n\tunsigned flags;\n\tvoid (*handler)(int);\n\tunsigned long mask[2];\n\tvoid (*restorer)();\n};\n\nhidden void __restore(), __restore_rt();\n"
  },
  {
    "path": "user.libc/arch/mips64/kstat.h",
    "content": "struct kstat {\n\tunsigned st_dev;\n\tint __pad1[3];\n\tino_t st_ino;\n\tmode_t st_mode;\n\tunsigned st_nlink;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tunsigned st_rdev;\n\tint __pad2[3];\n\toff_t st_size;\n\tint st_atime_sec;\n\tint st_atime_nsec;\n\tint st_mtime_sec;\n\tint st_mtime_nsec;\n\tint st_ctime_sec;\n\tint st_ctime_nsec;\n\tunsigned st_blksize;\n\tunsigned __pad3;\n\tblkcnt_t st_blocks;\n};\n"
  },
  {
    "path": "user.libc/arch/mips64/pthread_arch.h",
    "content": "static inline uintptr_t __get_tp()\n{\n#if __mips_isa_rev < 2\n\tregister uintptr_t tp __asm__(\"$3\");\n\t__asm__ (\".word 0x7c03e83b\" : \"=r\" (tp) );\n#else\n\tuintptr_t tp;\n\t__asm__ (\"rdhwr %0, $29\" : \"=r\" (tp) );\n#endif\n\treturn tp;\n}\n\n#define TLS_ABOVE_TP\n#define GAP_ABOVE_TP 0\n\n#define TP_OFFSET 0x7000\n#define DTP_OFFSET 0x8000\n\n#define MC_PC pc\n"
  },
  {
    "path": "user.libc/arch/mips64/reloc.h",
    "content": "#if __mips_isa_rev >= 6\n#define ISA_SUFFIX \"r6\"\n#else\n#define ISA_SUFFIX \"\"\n#endif\n\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n#define ENDIAN_SUFFIX \"el\"\n#else\n#define ENDIAN_SUFFIX \"\"\n#endif\n\n#ifdef __mips_soft_float\n#define FP_SUFFIX \"-sf\"\n#else\n#define FP_SUFFIX \"\"\n#endif\n\n#define LDSO_ARCH \"mips64\" ISA_SUFFIX ENDIAN_SUFFIX FP_SUFFIX\n\n#define TPOFF_K (-0x7000)\n\n#define REL_SYM_OR_REL  4611\n#define REL_PLT         R_MIPS_JUMP_SLOT\n#define REL_COPY        R_MIPS_COPY\n#define REL_DTPMOD      R_MIPS_TLS_DTPMOD64\n#define REL_DTPOFF      R_MIPS_TLS_DTPREL64\n#define REL_TPOFF       R_MIPS_TLS_TPREL64\n\n#include <endian.h>\n\n#undef R_TYPE\n#undef R_SYM\n#undef R_INFO\n#define R_TYPE(x) (be64toh(x)&0x7fffffff)\n#define R_SYM(x) (be32toh(be64toh(x)>>32))\n#define R_INFO(s,t) (htobe64((uint64_t)htobe32(s)<<32 | (uint64_t)t))\n\n#define NEED_MIPS_GOT_RELOCS 1\n#define DT_DEBUG_INDIRECT DT_MIPS_RLD_MAP\n#define ARCH_SYM_REJECT_UND(s) (!((s)->st_other & STO_MIPS_PLT))\n\n#define CRTJMP(pc,sp) __asm__ __volatile__( \\\n\t\"move $sp,%1 ; jr %0\" : : \"r\"(pc), \"r\"(sp) : \"memory\" )\n\n#define GETFUNCSYM(fp, sym, got) __asm__ ( \\\n\t\".hidden \" #sym \"\\n\" \\\n\t\".set push \\n\" \\\n\t\".set noreorder \\n\" \\\n\t\".align 8 \\n\" \\\n\t\"\tbal 1f \\n\" \\\n\t\"\t nop \\n\" \\\n\t\"\t.gpdword . \\n\" \\\n\t\"\t.gpdword \" #sym \" \\n\" \\\n\t\"1:\tld %0, ($ra) \\n\" \\\n\t\"\tdsubu %0, $ra, %0 \\n\" \\\n\t\"\tld $ra, 8($ra) \\n\" \\\n\t\"\tdaddu %0, %0, $ra \\n\" \\\n\t\".set pop \\n\" \\\n\t: \"=r\"(*(fp)) : : \"memory\", \"ra\" )\n"
  },
  {
    "path": "user.libc/arch/mips64/syscall_arch.h",
    "content": "#define __SYSCALL_LL_E(x) (x)\n#define __SYSCALL_LL_O(x) (x)\n\n#define SYSCALL_RLIM_INFINITY (-1UL/2)\n\n#if __mips_isa_rev >= 6\n#define SYSCALL_CLOBBERLIST \\\n\t\"$1\", \"$3\", \"$10\", \"$11\", \"$12\", \"$13\", \\\n\t\"$14\", \"$15\", \"$24\", \"$25\", \"memory\"\n#else\n#define SYSCALL_CLOBBERLIST \\\n\t\"$1\", \"$3\", \"$10\", \"$11\", \"$12\", \"$13\", \\\n\t\"$14\", \"$15\", \"$24\", \"$25\", \"hi\", \"lo\", \"memory\"\n#endif\n\nstatic inline long __syscall0(long n)\n{\n\tregister long r7 __asm__(\"$7\");\n\tregister long r2 __asm__(\"$2\");\n\t__asm__ __volatile__ (\n\t\t\"daddu $2,$0,%2 ; syscall\"\n\t\t: \"=&r\"(r2), \"=r\"(r7)\n\t\t: \"ir\"(n), \"0\"(r2)\n\t\t: SYSCALL_CLOBBERLIST);\n\treturn r7 && r2>0 ? -r2 : r2;\n}\n\nstatic inline long __syscall1(long n, long a)\n{\n\tregister long r4 __asm__(\"$4\") = a;\n\tregister long r7 __asm__(\"$7\");\n\tregister long r2 __asm__(\"$2\");\n\t__asm__ __volatile__ (\n\t\t\"daddu $2,$0,%2 ; syscall\"\n\t\t: \"=&r\"(r2), \"=r\"(r7)\n\t\t: \"ir\"(n), \"0\"(r2), \"r\"(r4)\n\t\t: SYSCALL_CLOBBERLIST);\n\treturn r7 && r2>0 ? -r2 : r2;\n}\n\nstatic inline long __syscall2(long n, long a, long b)\n{\n\tregister long r4 __asm__(\"$4\") = a;\n\tregister long r5 __asm__(\"$5\") = b;\n\tregister long r7 __asm__(\"$7\");\n\tregister long r2 __asm__(\"$2\");\n\n\t__asm__ __volatile__ (\n\t\t\"daddu $2,$0,%2 ; syscall\"\n\t\t: \"=&r\"(r2), \"=r\"(r7)\n\t\t: \"ir\"(n), \"0\"(r2), \"r\"(r4), \"r\"(r5)\n\t\t: SYSCALL_CLOBBERLIST);\n\treturn r7 && r2>0 ? -r2 : r2;\n}\n\nstatic inline long __syscall3(long n, long a, long b, long c)\n{\n\tregister long r4 __asm__(\"$4\") = a;\n\tregister long r5 __asm__(\"$5\") = b;\n\tregister long r6 __asm__(\"$6\") = c;\n\tregister long r7 __asm__(\"$7\");\n\tregister long r2 __asm__(\"$2\");\n\n\t__asm__ __volatile__ (\n\t\t\"daddu $2,$0,%2 ; syscall\"\n\t\t: \"=&r\"(r2), \"=r\"(r7)\n\t\t: \"ir\"(n), \"0\"(r2), \"r\"(r4), \"r\"(r5), \"r\"(r6)\n\t\t: SYSCALL_CLOBBERLIST);\n\treturn r7 && r2>0 ? -r2 : r2;\n}\n\nstatic inline long __syscall4(long n, long a, long b, long c, long d)\n{\n\tregister long r4 __asm__(\"$4\") = a;\n\tregister long r5 __asm__(\"$5\") = b;\n\tregister long r6 __asm__(\"$6\") = c;\n\tregister long r7 __asm__(\"$7\") = d;\n\tregister long r2 __asm__(\"$2\");\n\n\t__asm__ __volatile__ (\n\t\t\"daddu $2,$0,%2 ; syscall\"\n\t\t: \"=&r\"(r2), \"+r\"(r7)\n\t\t: \"ir\"(n), \"0\"(r2), \"r\"(r4), \"r\"(r5), \"r\"(r6)\n\t\t: SYSCALL_CLOBBERLIST);\n\treturn r7 && r2>0 ? -r2 : r2;\n}\n\nstatic inline long __syscall5(long n, long a, long b, long c, long d, long e)\n{\n\tregister long r4 __asm__(\"$4\") = a;\n\tregister long r5 __asm__(\"$5\") = b;\n\tregister long r6 __asm__(\"$6\") = c;\n\tregister long r7 __asm__(\"$7\") = d;\n\tregister long r8 __asm__(\"$8\") = e;\n\tregister long r2 __asm__(\"$2\");\n\n\t__asm__ __volatile__ (\n\t\t\"daddu $2,$0,%2 ; syscall\"\n\t\t: \"=&r\"(r2), \"+r\"(r7)\n\t\t: \"ir\"(n), \"0\"(r2), \"r\"(r4), \"r\"(r5), \"r\"(r6), \"r\"(r8)\n\t\t: SYSCALL_CLOBBERLIST);\n\treturn r7 && r2>0 ? -r2 : r2;\n}\n\nstatic inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)\n{\n\tregister long r4 __asm__(\"$4\") = a;\n\tregister long r5 __asm__(\"$5\") = b;\n\tregister long r6 __asm__(\"$6\") = c;\n\tregister long r7 __asm__(\"$7\") = d;\n\tregister long r8 __asm__(\"$8\") = e;\n\tregister long r9 __asm__(\"$9\") = f;\n\tregister long r2 __asm__(\"$2\");\n\n\t__asm__ __volatile__ (\n\t\t\"daddu $2,$0,%2 ; syscall\"\n\t\t: \"=&r\"(r2), \"+r\"(r7)\n\t\t: \"ir\"(n), \"0\"(r2), \"r\"(r4), \"r\"(r5), \"r\"(r6), \"r\"(r8), \"r\"(r9)\n\t\t: SYSCALL_CLOBBERLIST);\n\treturn r7 && r2>0 ? -r2 : r2;\n}\n\n#define VDSO_USEFUL\n#define VDSO_CGT_SYM \"__vdso_clock_gettime\"\n#define VDSO_CGT_VER \"LINUX_2.6\"\n\n#define SO_SNDTIMEO_OLD 0x1005\n#define SO_RCVTIMEO_OLD 0x1006\n"
  },
  {
    "path": "user.libc/arch/mipsn32/arch.mak",
    "content": "COMPAT_SRC_DIRS = compat/time32\n"
  },
  {
    "path": "user.libc/arch/mipsn32/atomic_arch.h",
    "content": "#if __mips_isa_rev < 6\n#define LLSC_M \"m\"\n#else\n#define LLSC_M \"ZC\"\n#endif\n\n#define a_ll a_ll\nstatic inline int a_ll(volatile int *p)\n{\n\tint v;\n#if __mips < 2\n\t__asm__ __volatile__ (\n\t\t\".set push ; .set mips2\\n\\t\"\n\t\t\"ll %0, %1\"\n\t\t\"\\n\\t.set pop\"\n\t\t: \"=r\"(v) : \"m\"(*p));\n#else\n\t__asm__ __volatile__ (\n\t\t\"ll %0, %1\"\n\t\t: \"=r\"(v) : LLSC_M(*p));\n#endif\n\treturn v;\n}\n\n#define a_sc a_sc\nstatic inline int a_sc(volatile int *p, int v)\n{\n\tint r;\n#if __mips < 2\n\t__asm__ __volatile__ (\n\t\t\".set push ; .set mips2\\n\\t\"\n\t\t\"sc %0, %1\"\n\t\t\"\\n\\t.set pop\"\n\t\t: \"=r\"(r), \"=m\"(*p) : \"0\"(v) : \"memory\");\n#else\n\t__asm__ __volatile__ (\n\t\t\"sc %0, %1\"\n\t\t: \"=r\"(r), \"=\"LLSC_M(*p) : \"0\"(v) : \"memory\");\n#endif\n\treturn r;\n}\n\n#define a_barrier a_barrier\nstatic inline void a_barrier()\n{\n\t__asm__ __volatile__ (\"sync\" : : : \"memory\");\n}\n\n#define a_pre_llsc a_barrier\n#define a_post_llsc a_barrier\n\n#undef LLSC_M\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/alltypes.h.in",
    "content": "#define _REDIR_TIME64 1\n#define _Addr int\n#define _Int64 long long\n#define _Reg int\n\n#if _MIPSEL || __MIPSEL || __MIPSEL__\n#define __BYTE_ORDER 1234\n#else\n#define __BYTE_ORDER 4321\n#endif\n\n#define __LONG_MAX 0x7fffffffL\n\n#ifndef __cplusplus\nTYPEDEF int wchar_t;\n#endif\n\nTYPEDEF float float_t;\nTYPEDEF double double_t;\n\nTYPEDEF struct { long long __ll; long double __ld; } max_align_t;\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/errno.h",
    "content": "#define EPERM            1\n#define ENOENT           2\n#define ESRCH            3\n#define EINTR            4\n#define EIO              5\n#define ENXIO            6\n#define E2BIG            7\n#define ENOEXEC          8\n#define EBADF            9\n#define ECHILD          10\n#define EAGAIN          11\n#define ENOMEM          12\n#define EACCES          13\n#define EFAULT          14\n#define ENOTBLK         15\n#define EBUSY           16\n#define EEXIST          17\n#define EXDEV           18\n#define ENODEV          19\n#define ENOTDIR         20\n#define EISDIR          21\n#define EINVAL          22\n#define ENFILE          23\n#define EMFILE          24\n#define ENOTTY          25\n#define ETXTBSY         26\n#define EFBIG           27\n#define ENOSPC          28\n#define ESPIPE          29\n#define EROFS           30\n#define EMLINK          31\n#define EPIPE           32\n#define EDOM            33\n#define ERANGE          34\n#define ENOMSG          35\n#define EIDRM           36\n#define ECHRNG          37\n#define EL2NSYNC        38\n#define EL3HLT          39\n#define EL3RST          40\n#define ELNRNG          41\n#define EUNATCH         42\n#define ENOCSI          43\n#define EL2HLT          44\n#define EDEADLK         45\n#define ENOLCK          46\n#define EBADE           50\n#define EBADR           51\n#define EXFULL          52\n#define ENOANO          53\n#define EBADRQC         54\n#define EBADSLT         55\n#define EDEADLOCK       56\n#define EBFONT          59\n#define ENOSTR          60\n#define ENODATA         61\n#define ETIME           62\n#define ENOSR           63\n#define ENONET          64\n#define ENOPKG          65\n#define EREMOTE         66\n#define ENOLINK         67\n#define EADV            68\n#define ESRMNT          69\n#define ECOMM           70\n#define EPROTO          71\n#define EDOTDOT         73\n#define EMULTIHOP       74\n#define EBADMSG         77\n#define ENAMETOOLONG    78\n#define EOVERFLOW       79\n#define ENOTUNIQ        80\n#define EBADFD          81\n#define EREMCHG         82\n#define ELIBACC         83\n#define ELIBBAD         84\n#define ELIBSCN         85\n#define ELIBMAX         86\n#define ELIBEXEC        87\n#define EILSEQ          88\n#define ENOSYS          89\n#define ELOOP           90\n#define ERESTART        91\n#define ESTRPIPE        92\n#define ENOTEMPTY       93\n#define EUSERS          94\n#define ENOTSOCK        95\n#define EDESTADDRREQ    96\n#define EMSGSIZE        97\n#define EPROTOTYPE      98\n#define ENOPROTOOPT     99\n#define EPROTONOSUPPORT 120\n#define ESOCKTNOSUPPORT 121\n#define EOPNOTSUPP      122\n#define ENOTSUP         EOPNOTSUPP\n#define EPFNOSUPPORT    123\n#define EAFNOSUPPORT    124\n#define EADDRINUSE      125\n#define EADDRNOTAVAIL   126\n#define ENETDOWN        127\n#define ENETUNREACH     128\n#define ENETRESET       129\n#define ECONNABORTED    130\n#define ECONNRESET      131\n#define ENOBUFS         132\n#define EISCONN         133\n#define ENOTCONN        134\n#define EUCLEAN         135\n#define ENOTNAM         137\n#define ENAVAIL         138\n#define EISNAM          139\n#define EREMOTEIO       140\n#define ESHUTDOWN       143\n#define ETOOMANYREFS    144\n#define ETIMEDOUT       145\n#define ECONNREFUSED    146\n#define EHOSTDOWN       147\n#define EHOSTUNREACH    148\n#define EWOULDBLOCK     EAGAIN\n#define EALREADY        149\n#define EINPROGRESS     150\n#define ESTALE          151\n#define ECANCELED       158\n#define ENOMEDIUM       159\n#define EMEDIUMTYPE     160\n#define ENOKEY          161\n#define EKEYEXPIRED     162\n#define EKEYREVOKED     163\n#define EKEYREJECTED    164\n#define EOWNERDEAD      165\n#define ENOTRECOVERABLE 166\n#define ERFKILL         167\n#define EHWPOISON       168\n#define EDQUOT          1133\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/fcntl.h",
    "content": "#define O_CREAT        0400\n#define O_EXCL        02000\n#define O_NOCTTY      04000\n#define O_TRUNC       01000\n#define O_APPEND       0010\n#define O_NONBLOCK     0200\n#define O_DSYNC        0020\n#define O_SYNC       040020\n#define O_RSYNC      040020\n#define O_DIRECTORY 0200000\n#define O_NOFOLLOW  0400000\n#define O_CLOEXEC  02000000\n\n#define O_ASYNC      010000\n#define O_DIRECT    0100000\n#define O_LARGEFILE  020000\n#define O_NOATIME  01000000\n#define O_PATH    010000000\n#define O_TMPFILE 020200000\n#define O_NDELAY O_NONBLOCK\n\n#define F_DUPFD  0\n#define F_GETFD  1\n#define F_SETFD  2\n#define F_GETFL  3\n#define F_SETFL  4\n\n#define F_SETOWN 24\n#define F_GETOWN 23\n#define F_SETSIG 10\n#define F_GETSIG 11\n\n#define F_GETLK 33\n#define F_SETLK 34\n#define F_SETLKW 35\n\n#define F_SETOWN_EX 15\n#define F_GETOWN_EX 16\n\n#define F_GETOWNER_UIDS 17\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/fenv.h",
    "content": "#ifdef __mips_soft_float\n#define FE_ALL_EXCEPT 0\n#define FE_TONEAREST  0\n#else\n#define FE_INEXACT    4\n#define FE_UNDERFLOW  8\n#define FE_OVERFLOW   16\n#define FE_DIVBYZERO  32\n#define FE_INVALID    64\n\n#define FE_ALL_EXCEPT 124\n\n#define FE_TONEAREST  0\n#define FE_TOWARDZERO 1\n#define FE_UPWARD     2\n#define FE_DOWNWARD   3\n#endif\n\ntypedef unsigned short fexcept_t;\n\ntypedef struct {\n\tunsigned __cw;\n} fenv_t;\n\n#define FE_DFL_ENV      ((const fenv_t *) -1)\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/float.h",
    "content": "#define FLT_EVAL_METHOD 0\n\n#define LDBL_TRUE_MIN 6.47517511943802511092443895822764655e-4966L\n#define LDBL_MIN 3.36210314311209350626267781732175260e-4932L\n#define LDBL_MAX 1.18973149535723176508575932662800702e+4932L\n#define LDBL_EPSILON 1.92592994438723585305597794258492732e-34L\n\n#define LDBL_MANT_DIG 113\n#define LDBL_MIN_EXP (-16381)\n#define LDBL_MAX_EXP 16384\n\n#define LDBL_DIG 33\n#define LDBL_MIN_10_EXP (-4931)\n#define LDBL_MAX_10_EXP 4932\n\n#define DECIMAL_DIG 36\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/hwcap.h",
    "content": "#define HWCAP_MIPS_R6\t\t(1 << 0)\n#define HWCAP_MIPS_MSA\t\t(1 << 1)\n#define HWCAP_MIPS_CRC32\t(1 << 2)\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/ioctl.h",
    "content": "#define _IOC(a,b,c,d) ( ((a)<<29) | ((b)<<8) | (c) | ((d)<<16) )\n#define _IOC_NONE  1U\n#define _IOC_READ  2U\n#define _IOC_WRITE 4U\n\n#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)\n#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c))\n#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c))\n#define _IOWR(a,b,c) _IOC(_IOC_READ|_IOC_WRITE,(a),(b),sizeof(c))\n\n#define TCGETA\t\t0x5401\n#define TCSETA\t\t0x5402\n#define TCSETAW\t\t0x5403\n#define TCSETAF\t\t0x5404\n#define TCSBRK\t\t0x5405\n#define TCXONC\t\t0x5406\n#define TCFLSH\t\t0x5407\n#define TCGETS\t\t0x540D\n#define TCSETS\t\t0x540E\n#define TCSETSW\t\t0x540F\n#define TCSETSF\t\t0x5410\n\n#define TIOCEXCL\t0x740D\n#define TIOCNXCL\t0x740E\n#define TIOCOUTQ\t0x7472\n#define TIOCSTI\t\t0x5472\n#define TIOCMGET\t0x741D\n#define TIOCMBIS\t0x741B\n#define TIOCMBIC\t0x741C\n#define TIOCMSET\t0x741A\n\n#define TIOCPKT\t\t0x5470\n#define TIOCSWINSZ\t_IOW('t', 103, struct winsize)\n#define TIOCGWINSZ\t_IOR('t', 104, struct winsize)\n#define TIOCNOTTY\t0x5471\n#define TIOCSETD\t0x7401\n#define TIOCGETD\t0x7400\n\n#define FIOCLEX\t\t0x6601\n#define FIONCLEX\t0x6602\n#define FIOASYNC\t0x667D\n#define FIONBIO\t\t0x667E\n#define FIOQSIZE\t0x667F\n\n#define TIOCGLTC        0x7474\n#define TIOCSLTC        0x7475\n#define TIOCSPGRP\t_IOW('t', 118, int)\n#define TIOCGPGRP\t_IOR('t', 119, int)\n#define TIOCCONS\t_IOW('t', 120, int)\n\n#define FIONREAD\t0x467F\n#define TIOCINQ\t\tFIONREAD\n\n#define TIOCGETP        0x7408\n#define TIOCSETP        0x7409\n#define TIOCSETN        0x740A\n\n#define TIOCSBRK\t0x5427\n#define TIOCCBRK\t0x5428\n#define TIOCGSID\t0x7416\n#define TIOCGRS485\t_IOR('T', 0x2E, char[32])\n#define TIOCSRS485\t_IOWR('T', 0x2F, char[32])\n#define TIOCGPTN\t_IOR('T', 0x30, unsigned int)\n#define TIOCSPTLCK\t_IOW('T', 0x31, int)\n#define TIOCGDEV\t_IOR('T', 0x32, unsigned int)\n#define TIOCSIG\t\t_IOW('T', 0x36, int)\n#define TIOCVHANGUP\t0x5437\n#define TIOCGPKT\t_IOR('T', 0x38, int)\n#define TIOCGPTLCK\t_IOR('T', 0x39, int)\n#define TIOCGEXCL\t_IOR('T', 0x40, int)\n#define TIOCGPTPEER\t_IO('T', 0x41)\n\n#define TIOCSCTTY\t0x5480\n#define TIOCGSOFTCAR\t0x5481\n#define TIOCSSOFTCAR\t0x5482\n#define TIOCLINUX\t0x5483\n#define TIOCGSERIAL\t0x5484\n#define TIOCSSERIAL\t0x5485\n#define TCSBRKP\t\t0x5486\n\n#define TIOCSERCONFIG\t0x5488\n#define TIOCSERGWILD\t0x5489\n#define TIOCSERSWILD\t0x548A\n#define TIOCGLCKTRMIOS\t0x548B\n#define TIOCSLCKTRMIOS\t0x548C\n#define TIOCSERGSTRUCT\t0x548D\n#define TIOCSERGETLSR   0x548E\n#define TIOCSERGETMULTI 0x548F\n#define TIOCSERSETMULTI 0x5490\n#define TIOCMIWAIT\t0x5491\n#define TIOCGICOUNT\t0x5492\n\n#define TIOCM_LE\t0x001\n#define TIOCM_DTR\t0x002\n#define TIOCM_RTS\t0x004\n#define TIOCM_ST\t0x010\n#define TIOCM_SR\t0x020\n#define TIOCM_CTS\t0x040\n#define TIOCM_CAR\t0x100\n#define TIOCM_CD\tTIOCM_CAR\n#define TIOCM_RNG\t0x200\n#define TIOCM_RI\tTIOCM_RNG\n#define TIOCM_DSR\t0x400\n#define TIOCM_OUT1\t0x2000\n#define TIOCM_OUT2\t0x4000\n#define TIOCM_LOOP\t0x8000\n\n#define FIOGETOWN       _IOR('f', 123, int)\n#define FIOSETOWN       _IOW('f', 124, int)\n#define SIOCATMARK      _IOR('s', 7, int)\n#define SIOCSPGRP       _IOW('s', 8, pid_t)\n#define SIOCGPGRP       _IOR('s', 9, pid_t)\n#define SIOCGSTAMP      _IOR(0x89, 6, char[16])\n#define SIOCGSTAMPNS    _IOR(0x89, 7, char[16])\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/ipcstat.h",
    "content": "#define IPC_STAT 0x102\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/mman.h",
    "content": "#undef MAP_ANON\n#define MAP_ANON       0x800\n#undef MAP_NORESERVE\n#define MAP_NORESERVE  0x0400\n#undef MAP_GROWSDOWN\n#define MAP_GROWSDOWN  0x1000\n#undef MAP_DENYWRITE\n#define MAP_DENYWRITE  0x2000\n#undef MAP_EXECUTABLE\n#define MAP_EXECUTABLE 0x4000\n#undef MAP_LOCKED\n#define MAP_LOCKED     0x8000\n#undef MAP_POPULATE\n#define MAP_POPULATE   0x10000\n#undef MAP_NONBLOCK\n#define MAP_NONBLOCK   0x20000\n#undef MAP_STACK\n#define MAP_STACK      0x40000\n#undef MAP_HUGETLB\n#define MAP_HUGETLB    0x80000\n#undef MAP_SYNC\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#undef MADV_SOFT_OFFLINE\n#endif\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/msg.h",
    "content": "struct msqid_ds {\n\tstruct ipc_perm msg_perm;\n#if _MIPSEL || __MIPSEL || __MIPSEL__\n\tunsigned long __msg_stime_lo;\n\tunsigned long __msg_stime_hi;\n\tunsigned long __msg_rtime_lo;\n\tunsigned long __msg_rtime_hi;\n\tunsigned long __msg_ctime_lo;\n\tunsigned long __msg_ctime_hi;\n#else\n\tunsigned long __msg_stime_hi;\n\tunsigned long __msg_stime_lo;\n\tunsigned long __msg_rtime_hi;\n\tunsigned long __msg_rtime_lo;\n\tunsigned long __msg_ctime_hi;\n\tunsigned long __msg_ctime_lo;\n#endif\n\tunsigned long msg_cbytes;\n\tmsgqnum_t msg_qnum;\n\tmsglen_t msg_qbytes;\n\tpid_t msg_lspid;\n\tpid_t msg_lrpid;\n\tunsigned long __unused[2];\n\ttime_t msg_stime;\n\ttime_t msg_rtime;\n\ttime_t msg_ctime;\n};\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/poll.h",
    "content": "#define POLLWRNORM POLLOUT\n#define POLLWRBAND 0x100\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/posix.h",
    "content": "#define _POSIX_V6_ILP32_OFFBIG  1\n#define _POSIX_V7_ILP32_OFFBIG  1\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/ptrace.h",
    "content": "#define PTRACE_GET_THREAD_AREA\t25\n#define PTRACE_SET_THREAD_AREA\t26\n#define PTRACE_PEEKTEXT_3264\t0xc0\n#define PTRACE_PEEKDATA_3264\t0xc1\n#define PTRACE_POKETEXT_3264\t0xc2\n#define PTRACE_POKEDATA_3264\t0xc3\n#define PTRACE_GET_THREAD_AREA_3264\t0xc4\n#define PTRACE_GET_WATCH_REGS\t0xd0\n#define PTRACE_SET_WATCH_REGS\t0xd1\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/reg.h",
    "content": "#undef __WORDSIZE\n#define __WORDSIZE 64\n\n#define EF_R0 0\n#define EF_R1 1\n#define EF_R2 2\n#define EF_R3 3\n#define EF_R4 4\n#define EF_R5 5\n#define EF_R6 6\n#define EF_R7 7\n#define EF_R8 8\n#define EF_R9 9\n#define EF_R10 10\n#define EF_R11 11\n#define EF_R12 12\n#define EF_R13 13\n#define EF_R14 14\n#define EF_R15 15\n#define EF_R16 16\n#define EF_R17 17\n#define EF_R18 18\n#define EF_R19 19\n#define EF_R20 20\n#define EF_R21 21\n#define EF_R22 22\n#define EF_R23 23\n#define EF_R24 24\n#define EF_R25 25\n\n#define EF_R26 26\n#define EF_R27 27\n#define EF_R28 28\n#define EF_R29 29\n#define EF_R30 30\n#define EF_R31 31\n\n#define EF_LO 32\n#define EF_HI 33\n\n#define EF_CP0_EPC 34\n#define EF_CP0_BADVADDR 35\n#define EF_CP0_STATUS 36\n#define EF_CP0_CAUSE 37\n#define EF_UNUSED0 38\n\n#define EF_SIZE 304\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/resource.h",
    "content": "#define RLIMIT_NOFILE  5\n#define RLIMIT_AS      6\n#define RLIMIT_RSS     7\n#define RLIMIT_NPROC   8\n#define RLIMIT_MEMLOCK 9\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/sem.h",
    "content": "struct semid_ds {\n\tstruct ipc_perm sem_perm;\n\tunsigned long __sem_otime_lo;\n\tunsigned long __sem_ctime_lo;\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n\tunsigned short sem_nsems;\n\tchar __sem_nsems_pad[sizeof(long)-sizeof(short)];\n#else\n\tchar __sem_nsems_pad[sizeof(long)-sizeof(short)];\n\tunsigned short sem_nsems;\n#endif\n\tunsigned long __sem_otime_hi;\n\tunsigned long __sem_ctime_hi;\n\ttime_t sem_otime;\n\ttime_t sem_ctime;\n};\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/setjmp.h",
    "content": "typedef unsigned long long __jmp_buf[23];\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/shm.h",
    "content": "#define SHMLBA 4096\n\nstruct shmid_ds {\n\tstruct ipc_perm shm_perm;\n\tsize_t shm_segsz;\n\tunsigned long __shm_atime_lo;\n\tunsigned long __shm_dtime_lo;\n\tunsigned long __shm_ctime_lo;\n\tpid_t shm_cpid;\n\tpid_t shm_lpid;\n\tunsigned long shm_nattch;\n\tunsigned short __shm_atime_hi;\n\tunsigned short __shm_dtime_hi;\n\tunsigned short __shm_ctime_hi;\n\tunsigned short __pad1;\n\ttime_t shm_atime;\n\ttime_t shm_dtime;\n\ttime_t shm_ctime;\n};\n\nstruct shminfo {\n\tunsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];\n};\n\nstruct shm_info {\n\tint __used_ids;\n\tunsigned long shm_tot, shm_rss, shm_swp;\n\tunsigned long __swap_attempts, __swap_successes;\n};\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/signal.h",
    "content": "#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define MINSIGSTKSZ 2048\n#define SIGSTKSZ 8192\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\ntypedef unsigned long long greg_t, gregset_t[32];\n\ntypedef struct {\n\tunion {\n\t\tdouble fp_dregs[32];\n\t\tstruct {\n\t\t\tfloat _fp_fregs;\n\t\t\tunsigned _fp_pad;\n\t\t} fp_fregs[32];\n\t} fp_r;\n} fpregset_t;\n\nstruct sigcontext {\n\tunsigned long long sc_regs[32];\n\tunsigned long long sc_fpregs[32];\n\tunsigned long long sc_mdhi;\n\tunsigned long long sc_hi1;\n\tunsigned long long sc_hi2;\n\tunsigned long long sc_hi3;\n\tunsigned long long sc_mdlo;\n\tunsigned long long sc_lo1;\n\tunsigned long long sc_lo2;\n\tunsigned long long sc_lo3;\n\tunsigned long long sc_pc;\n\tunsigned int sc_fpc_csr;\n\tunsigned int sc_used_math;\n\tunsigned int sc_dsp;\n\tunsigned int sc_reserved;\n};\n\ntypedef struct {\n\tgregset_t gregs;\n\tfpregset_t fpregs;\n\tgreg_t mdhi;\n\tgreg_t hi1;\n\tgreg_t hi2;\n\tgreg_t hi3;\n\tgreg_t mdlo;\n\tgreg_t lo1;\n\tgreg_t lo2;\n\tgreg_t lo3;\n\tgreg_t pc;\n\tunsigned int fpc_csr;\n\tunsigned int used_math;\n\tunsigned int dsp;\n\tunsigned int reserved;\n} mcontext_t;\n\n#else\ntypedef struct {\n\tunsigned long long __mc1[32];\n\tdouble __mc2[32];\n\tunsigned long long __mc3[9];\n\tunsigned __mc4[4];\n} mcontext_t;\n#endif\n\nstruct sigaltstack {\n\tvoid *ss_sp;\n\tsize_t ss_size;\n\tint ss_flags;\n};\n\ntypedef struct __ucontext {\n\tunsigned long uc_flags;\n\tstruct __ucontext *uc_link;\n\tstack_t uc_stack;\n\tmcontext_t uc_mcontext;\n\tsigset_t uc_sigmask;\n} ucontext_t;\n\n#define SA_NOCLDSTOP  1\n#define SA_NOCLDWAIT  0x10000\n#define SA_SIGINFO    8\n#define SA_ONSTACK    0x08000000\n#define SA_RESTART    0x10000000\n#define SA_NODEFER    0x40000000\n#define SA_RESETHAND  0x80000000\n#define SA_RESTORER   0x04000000\n\n#undef SIG_BLOCK\n#undef SIG_UNBLOCK\n#undef SIG_SETMASK\n#define SIG_BLOCK     1\n#define SIG_UNBLOCK   2\n#define SIG_SETMASK   3\n\n#undef SI_ASYNCIO\n#undef SI_MESGQ\n#undef SI_TIMER\n#define SI_ASYNCIO (-2)\n#define SI_MESGQ (-4)\n#define SI_TIMER (-3)\n\n#define __SI_SWAP_ERRNO_CODE\n\n#endif\n\n#define SIGHUP    1\n#define SIGINT    2\n#define SIGQUIT   3\n#define SIGILL    4\n#define SIGTRAP   5\n#define SIGABRT   6\n#define SIGIOT    SIGABRT\n#define SIGEMT    7\n#define SIGFPE    8\n#define SIGKILL   9\n#define SIGBUS    10\n#define SIGSEGV   11\n#define SIGSYS    12\n#define SIGPIPE   13\n#define SIGALRM   14\n#define SIGTERM   15\n#define SIGUSR1   16\n#define SIGUSR2   17\n#define SIGCHLD   18\n#define SIGPWR    19\n#define SIGWINCH  20\n#define SIGURG    21\n#define SIGIO     22\n#define SIGPOLL   SIGIO\n#define SIGSTOP   23\n#define SIGTSTP   24\n#define SIGCONT   25\n#define SIGTTIN   26\n#define SIGTTOU   27\n#define SIGVTALRM 28\n#define SIGPROF   29\n#define SIGXCPU   30\n#define SIGXFSZ   31\n#define SIGUNUSED SIGSYS\n\n#define _NSIG 128\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/socket.h",
    "content": "#define SOCK_STREAM    2\n#define SOCK_DGRAM     1\n\n#define SOL_SOCKET     65535\n\n#define SO_DEBUG        1\n\n#define SO_REUSEADDR    0x0004\n#define SO_KEEPALIVE    0x0008\n#define SO_DONTROUTE    0x0010\n#define SO_BROADCAST    0x0020\n#define SO_LINGER       0x0080\n#define SO_OOBINLINE    0x0100\n#define SO_REUSEPORT    0x0200\n#define SO_SNDBUF       0x1001\n#define SO_RCVBUF       0x1002\n#define SO_SNDLOWAT     0x1003\n#define SO_RCVLOWAT     0x1004\n#define SO_ERROR        0x1007\n#define SO_TYPE         0x1008\n#define SO_ACCEPTCONN   0x1009\n#define SO_PROTOCOL     0x1028\n#define SO_DOMAIN       0x1029\n\n#define SO_NO_CHECK     11\n#define SO_PRIORITY     12\n#define SO_BSDCOMPAT    14\n#define SO_PASSCRED     17\n#define SO_PEERCRED     18\n#define SO_PEERSEC      30\n#define SO_SNDBUFFORCE  31\n#define SO_RCVBUFFORCE  33\n\n#define SOCK_NONBLOCK     0200\n#define SOCK_CLOEXEC  02000000\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/stat.h",
    "content": "struct stat {\n\tdev_t st_dev;\n\tlong __pad1[2];\n\tino_t st_ino;\n\tmode_t st_mode;\n\tnlink_t st_nlink;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tdev_t st_rdev;\n\tlong __pad2[2];\n\toff_t st_size;\n\tstruct {\n\t\tlong tv_sec;\n\t\tlong tv_nsec;\n\t} __st_atim32, __st_mtim32, __st_ctim32;\n\tblksize_t st_blksize;\n\tlong __pad3;\n\tblkcnt_t st_blocks;\n\tstruct timespec st_atim;\n\tstruct timespec st_mtim;\n\tstruct timespec st_ctim;\n\tlong __pad4[2];\n};\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/statfs.h",
    "content": "struct statfs {\n\tunsigned long f_type, f_bsize, f_frsize;\n\tfsblkcnt_t f_blocks, f_bfree;\n\tfsfilcnt_t f_files, f_ffree;\n\tfsblkcnt_t f_bavail;\n\tfsid_t f_fsid;\n\tunsigned long f_namelen, f_flags, f_spare[5];\n};\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/stdint.h",
    "content": "typedef int32_t int_fast16_t;\ntypedef int32_t int_fast32_t;\ntypedef uint32_t uint_fast16_t;\ntypedef uint32_t uint_fast32_t;\n\n#define INT_FAST16_MIN  INT32_MIN\n#define INT_FAST32_MIN  INT32_MIN\n\n#define INT_FAST16_MAX  INT32_MAX\n#define INT_FAST32_MAX  INT32_MAX\n\n#define UINT_FAST16_MAX UINT32_MAX\n#define UINT_FAST32_MAX UINT32_MAX\n\n#define INTPTR_MIN      INT32_MIN\n#define INTPTR_MAX      INT32_MAX\n#define UINTPTR_MAX     UINT32_MAX\n#define PTRDIFF_MIN     INT32_MIN\n#define PTRDIFF_MAX     INT32_MAX\n#define SIZE_MAX        UINT32_MAX\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/syscall.h.in",
    "content": "#define __NR_read\t\t\t6000\n#define __NR_write\t\t\t6001\n#define __NR_open\t\t\t6002\n#define __NR_close\t\t\t6003\n#define __NR_stat\t\t\t6004\n#define __NR_fstat\t\t\t6005\n#define __NR_lstat\t\t\t6006\n#define __NR_poll\t\t\t6007\n#define __NR_lseek\t\t\t6008\n#define __NR_mmap\t\t\t6009\n#define __NR_mprotect\t\t\t6010\n#define __NR_munmap\t\t\t6011\n#define __NR_brk\t\t\t6012\n#define __NR_rt_sigaction\t\t6013\n#define __NR_rt_sigprocmask\t\t6014\n#define __NR_ioctl\t\t\t6015\n#define __NR_pread64\t\t\t6016\n#define __NR_pwrite64\t\t\t6017\n#define __NR_readv\t\t\t6018\n#define __NR_writev\t\t\t6019\n#define __NR_access\t\t\t6020\n#define __NR_pipe\t\t\t6021\n#define __NR__newselect\t\t\t6022\n#define __NR_sched_yield\t\t6023\n#define __NR_mremap\t\t\t6024\n#define __NR_msync\t\t\t6025\n#define __NR_mincore\t\t\t6026\n#define __NR_madvise\t\t\t6027\n#define __NR_shmget\t\t\t6028\n#define __NR_shmat\t\t\t6029\n#define __NR_shmctl\t\t\t6030\n#define __NR_dup\t\t\t6031\n#define __NR_dup2\t\t\t6032\n#define __NR_pause\t\t\t6033\n#define __NR_nanosleep\t\t\t6034\n#define __NR_getitimer\t\t\t6035\n#define __NR_setitimer\t\t\t6036\n#define __NR_alarm\t\t\t6037\n#define __NR_getpid\t\t\t6038\n#define __NR_sendfile\t\t\t6039\n#define __NR_socket\t\t\t6040\n#define __NR_connect\t\t\t6041\n#define __NR_accept\t\t\t6042\n#define __NR_sendto\t\t\t6043\n#define __NR_recvfrom\t\t\t6044\n#define __NR_sendmsg\t\t\t6045\n#define __NR_recvmsg\t\t\t6046\n#define __NR_shutdown\t\t\t6047\n#define __NR_bind\t\t\t6048\n#define __NR_listen\t\t\t6049\n#define __NR_getsockname\t\t6050\n#define __NR_getpeername\t\t6051\n#define __NR_socketpair\t\t\t6052\n#define __NR_setsockopt\t\t\t6053\n#define __NR_getsockopt\t\t\t6054\n#define __NR_clone\t\t\t6055\n#define __NR_fork\t\t\t6056\n#define __NR_execve\t\t\t6057\n#define __NR_exit\t\t\t6058\n#define __NR_wait4\t\t\t6059\n#define __NR_kill\t\t\t6060\n#define __NR_uname\t\t\t6061\n#define __NR_semget\t\t\t6062\n#define __NR_semop\t\t\t6063\n#define __NR_semctl\t\t\t6064\n#define __NR_shmdt\t\t\t6065\n#define __NR_msgget\t\t\t6066\n#define __NR_msgsnd\t\t\t6067\n#define __NR_msgrcv\t\t\t6068\n#define __NR_msgctl\t\t\t6069\n#define __NR_fcntl\t\t\t6070\n#define __NR_flock\t\t\t6071\n#define __NR_fsync\t\t\t6072\n#define __NR_fdatasync\t\t\t6073\n#define __NR_truncate\t\t\t6074\n#define __NR_ftruncate\t\t\t6075\n#define __NR_getdents\t\t\t6076\n#define __NR_getcwd\t\t\t6077\n#define __NR_chdir\t\t\t6078\n#define __NR_fchdir\t\t\t6079\n#define __NR_rename\t\t\t6080\n#define __NR_mkdir\t\t\t6081\n#define __NR_rmdir\t\t\t6082\n#define __NR_creat\t\t\t6083\n#define __NR_link\t\t\t6084\n#define __NR_unlink\t\t\t6085\n#define __NR_symlink\t\t\t6086\n#define __NR_readlink\t\t\t6087\n#define __NR_chmod\t\t\t6088\n#define __NR_fchmod\t\t\t6089\n#define __NR_chown\t\t\t6090\n#define __NR_fchown\t\t\t6091\n#define __NR_lchown\t\t\t6092\n#define __NR_umask\t\t\t6093\n#define __NR_gettimeofday_time32\t\t6094\n#define __NR_getrlimit\t\t\t6095\n#define __NR_getrusage\t\t\t6096\n#define __NR_sysinfo\t\t\t6097\n#define __NR_times\t\t\t6098\n#define __NR_ptrace\t\t\t6099\n#define __NR_getuid\t\t\t6100\n#define __NR_syslog\t\t\t6101\n#define __NR_getgid\t\t\t6102\n#define __NR_setuid\t\t\t6103\n#define __NR_setgid\t\t\t6104\n#define __NR_geteuid\t\t\t6105\n#define __NR_getegid\t\t\t6106\n#define __NR_setpgid\t\t\t6107\n#define __NR_getppid\t\t\t6108\n#define __NR_getpgrp\t\t\t6109\n#define __NR_setsid\t\t\t6110\n#define __NR_setreuid\t\t\t6111\n#define __NR_setregid\t\t\t6112\n#define __NR_getgroups\t\t\t6113\n#define __NR_setgroups\t\t\t6114\n#define __NR_setresuid\t\t\t6115\n#define __NR_getresuid\t\t\t6116\n#define __NR_setresgid\t\t\t6117\n#define __NR_getresgid\t\t\t6118\n#define __NR_getpgid\t\t\t6119\n#define __NR_setfsuid\t\t\t6120\n#define __NR_setfsgid\t\t\t6121\n#define __NR_getsid\t\t\t6122\n#define __NR_capget\t\t\t6123\n#define __NR_capset\t\t\t6124\n#define __NR_rt_sigpending\t\t6125\n#define __NR_rt_sigtimedwait\t\t6126\n#define __NR_rt_sigqueueinfo\t\t6127\n#define __NR_rt_sigsuspend\t\t6128\n#define __NR_sigaltstack\t\t6129\n#define __NR_utime\t\t\t6130\n#define __NR_mknod\t\t\t6131\n#define __NR_personality\t\t6132\n#define __NR_ustat\t\t\t6133\n#define __NR_statfs\t\t\t6134\n#define __NR_fstatfs\t\t\t6135\n#define __NR_sysfs\t\t\t6136\n#define __NR_getpriority\t\t6137\n#define __NR_setpriority\t\t6138\n#define __NR_sched_setparam\t\t6139\n#define __NR_sched_getparam\t\t6140\n#define __NR_sched_setscheduler\t\t6141\n#define __NR_sched_getscheduler\t\t6142\n#define __NR_sched_get_priority_max\t6143\n#define __NR_sched_get_priority_min\t6144\n#define __NR_sched_rr_get_interval\t6145\n#define __NR_mlock\t\t\t6146\n#define __NR_munlock\t\t\t6147\n#define __NR_mlockall\t\t\t6148\n#define __NR_munlockall\t\t\t6149\n#define __NR_vhangup\t\t\t6150\n#define __NR_pivot_root\t\t\t6151\n#define __NR__sysctl\t\t\t6152\n#define __NR_prctl\t\t\t6153\n#define __NR_adjtimex\t\t\t6154\n#define __NR_setrlimit\t\t\t6155\n#define __NR_chroot\t\t\t6156\n#define __NR_sync\t\t\t6157\n#define __NR_acct\t\t\t6158\n#define __NR_settimeofday_time32\t\t6159\n#define __NR_mount\t\t\t6160\n#define __NR_umount2\t\t\t6161\n#define __NR_swapon\t\t\t6162\n#define __NR_swapoff\t\t\t6163\n#define __NR_reboot\t\t\t6164\n#define __NR_sethostname\t\t6165\n#define __NR_setdomainname\t\t6166\n#define __NR_create_module\t\t6167\n#define __NR_init_module\t\t6168\n#define __NR_delete_module\t\t6169\n#define __NR_get_kernel_syms\t\t6170\n#define __NR_query_module\t\t6171\n#define __NR_quotactl\t\t\t6172\n#define __NR_nfsservctl\t\t\t6173\n#define __NR_getpmsg\t\t\t6174\n#define __NR_putpmsg\t\t\t6175\n#define __NR_afs_syscall\t\t6176\n#define __NR_reserved177\t\t6177\n#define __NR_gettid\t\t\t6178\n#define __NR_readahead\t\t\t6179\n#define __NR_setxattr\t\t\t6180\n#define __NR_lsetxattr\t\t\t6181\n#define __NR_fsetxattr\t\t\t6182\n#define __NR_getxattr\t\t\t6183\n#define __NR_lgetxattr\t\t\t6184\n#define __NR_fgetxattr\t\t\t6185\n#define __NR_listxattr\t\t\t6186\n#define __NR_llistxattr\t\t\t6187\n#define __NR_flistxattr\t\t\t6188\n#define __NR_removexattr\t\t6189\n#define __NR_lremovexattr\t\t6190\n#define __NR_fremovexattr\t\t6191\n#define __NR_tkill\t\t\t6192\n#define __NR_reserved193\t\t6193\n#define __NR_futex\t\t\t6194\n#define __NR_sched_setaffinity\t\t6195\n#define __NR_sched_getaffinity\t\t6196\n#define __NR_cacheflush\t\t\t6197\n#define __NR_cachectl\t\t\t6198\n#define __NR_sysmips\t\t\t6199\n#define __NR_io_setup\t\t\t6200\n#define __NR_io_destroy\t\t\t6201\n#define __NR_io_getevents\t\t6202\n#define __NR_io_submit\t\t\t6203\n#define __NR_io_cancel\t\t\t6204\n#define __NR_exit_group\t\t\t6205\n#define __NR_lookup_dcookie\t\t6206\n#define __NR_epoll_create\t\t6207\n#define __NR_epoll_ctl\t\t\t6208\n#define __NR_epoll_wait\t\t\t6209\n#define __NR_remap_file_pages\t\t6210\n#define __NR_rt_sigreturn\t\t6211\n#define __NR_fcntl64\t\t\t6212\n#define __NR_set_tid_address\t\t6213\n#define __NR_restart_syscall\t\t6214\n#define __NR_semtimedop\t\t\t6215\n#define __NR_fadvise64\t\t\t6216\n#define __NR_statfs64\t\t\t6217\n#define __NR_fstatfs64\t\t\t6218\n#define __NR_sendfile64\t\t\t6219\n#define __NR_timer_create\t\t6220\n#define __NR_timer_settime32\t\t6221\n#define __NR_timer_gettime32\t\t6222\n#define __NR_timer_getoverrun\t\t6223\n#define __NR_timer_delete\t\t6224\n#define __NR_clock_settime32\t\t6225\n#define __NR_clock_gettime32\t\t6226\n#define __NR_clock_getres_time32\t\t6227\n#define __NR_clock_nanosleep_time32\t\t6228\n#define __NR_tgkill\t\t\t6229\n#define __NR_utimes\t\t\t6230\n#define __NR_mbind\t\t\t6231\n#define __NR_get_mempolicy\t\t6232\n#define __NR_set_mempolicy\t\t6233\n#define __NR_mq_open\t\t\t6234\n#define __NR_mq_unlink\t\t\t6235\n#define __NR_mq_timedsend\t\t6236\n#define __NR_mq_timedreceive\t\t6237\n#define __NR_mq_notify\t\t\t6238\n#define __NR_mq_getsetattr\t\t6239\n#define __NR_vserver\t\t\t6240\n#define __NR_waitid\t\t\t6241\n#define __NR_add_key\t\t\t6243\n#define __NR_request_key\t\t6244\n#define __NR_keyctl\t\t\t6245\n#define __NR_set_thread_area\t\t6246\n#define __NR_inotify_init\t\t6247\n#define __NR_inotify_add_watch\t\t6248\n#define __NR_inotify_rm_watch\t\t6249\n#define __NR_migrate_pages\t\t6250\n#define __NR_openat\t\t\t6251\n#define __NR_mkdirat\t\t\t6252\n#define __NR_mknodat\t\t\t6253\n#define __NR_fchownat\t\t\t6254\n#define __NR_futimesat\t\t\t6255\n#define __NR_newfstatat\t\t\t6256\n#define __NR_unlinkat\t\t\t6257\n#define __NR_renameat\t\t\t6258\n#define __NR_linkat\t\t\t6259\n#define __NR_symlinkat\t\t\t6260\n#define __NR_readlinkat\t\t\t6261\n#define __NR_fchmodat\t\t\t6262\n#define __NR_faccessat\t\t\t6263\n#define __NR_pselect6\t\t\t6264\n#define __NR_ppoll\t\t\t6265\n#define __NR_unshare\t\t\t6266\n#define __NR_splice\t\t\t6267\n#define __NR_sync_file_range\t\t6268\n#define __NR_tee\t\t\t6269\n#define __NR_vmsplice\t\t\t6270\n#define __NR_move_pages\t\t\t6271\n#define __NR_set_robust_list\t\t6272\n#define __NR_get_robust_list\t\t6273\n#define __NR_kexec_load\t\t\t6274\n#define __NR_getcpu\t\t\t6275\n#define __NR_epoll_pwait\t\t6276\n#define __NR_ioprio_set\t\t\t6277\n#define __NR_ioprio_get\t\t\t6278\n#define __NR_utimensat\t\t\t6279\n#define __NR_signalfd\t\t\t6280\n#define __NR_timerfd\t\t\t6281\n#define __NR_eventfd\t\t\t6282\n#define __NR_fallocate\t\t\t6283\n#define __NR_timerfd_create\t\t6284\n#define __NR_timerfd_gettime32\t\t6285\n#define __NR_timerfd_settime32\t\t6286\n#define __NR_signalfd4\t\t\t6287\n#define __NR_eventfd2\t\t\t6288\n#define __NR_epoll_create1\t\t6289\n#define __NR_dup3\t\t\t6290\n#define __NR_pipe2\t\t\t6291\n#define __NR_inotify_init1\t\t6292\n#define __NR_preadv\t\t\t6293\n#define __NR_pwritev\t\t\t6294\n#define __NR_rt_tgsigqueueinfo\t\t6295\n#define __NR_perf_event_open\t\t6296\n#define __NR_accept4\t\t\t6297\n#define __NR_recvmmsg\t\t\t6298\n#define __NR_getdents64\t\t\t6299\n#define __NR_fanotify_init\t\t6300\n#define __NR_fanotify_mark\t\t6301\n#define __NR_prlimit64\t\t\t6302\n#define __NR_name_to_handle_at\t\t6303\n#define __NR_open_by_handle_at\t\t6304\n#define __NR_clock_adjtime\t\t6305\n#define __NR_syncfs\t\t\t6306\n#define __NR_sendmmsg\t\t\t6307\n#define __NR_setns\t\t\t6308\n#define __NR_process_vm_readv\t\t6309\n#define __NR_process_vm_writev\t\t6310\n#define __NR_kcmp\t\t\t6311\n#define __NR_finit_module\t\t6312\n#define __NR_sched_setattr\t\t6313\n#define __NR_sched_getattr\t\t6314\n#define __NR_renameat2\t\t\t6315\n#define __NR_seccomp\t\t\t6316\n#define __NR_getrandom\t\t\t6317\n#define __NR_memfd_create\t\t6318\n#define __NR_bpf\t\t\t6319\n#define __NR_execveat\t\t\t6320\n#define __NR_userfaultfd\t\t6321\n#define __NR_membarrier\t\t\t6322\n#define __NR_mlock2\t\t\t6323\n#define __NR_copy_file_range\t\t6324\n#define __NR_preadv2\t\t\t6325\n#define __NR_pwritev2\t\t\t6326\n#define __NR_pkey_mprotect\t\t6327\n#define __NR_pkey_alloc\t\t\t6328\n#define __NR_pkey_free\t\t\t6329\n#define __NR_statx\t\t\t6330\n#define __NR_rseq\t\t\t6331\n#define __NR_io_pgetevents\t\t6332\n#define __NR_clock_gettime64\t\t6403\n#define __NR_clock_settime64\t\t6404\n#define __NR_clock_adjtime64\t\t6405\n#define __NR_clock_getres_time64\t6406\n#define __NR_clock_nanosleep_time64\t6407\n#define __NR_timer_gettime64\t\t6408\n#define __NR_timer_settime64\t\t6409\n#define __NR_timerfd_gettime64\t\t6410\n#define __NR_timerfd_settime64\t\t6411\n#define __NR_utimensat_time64\t\t6412\n#define __NR_pselect6_time64\t\t6413\n#define __NR_ppoll_time64\t\t6414\n#define __NR_io_pgetevents_time64\t6416\n#define __NR_recvmmsg_time64\t\t6417\n#define __NR_mq_timedsend_time64\t6418\n#define __NR_mq_timedreceive_time64\t6419\n#define __NR_semtimedop_time64\t\t6420\n#define __NR_rt_sigtimedwait_time64\t6421\n#define __NR_futex_time64\t\t6422\n#define __NR_sched_rr_get_interval_time64 6423\n#define __NR_pidfd_send_signal\t\t6424\n#define __NR_io_uring_setup\t\t6425\n#define __NR_io_uring_enter\t\t6426\n#define __NR_io_uring_register\t\t6427\n#define __NR_open_tree\t\t6428\n#define __NR_move_mount\t\t6429\n#define __NR_fsopen\t\t6430\n#define __NR_fsconfig\t\t6431\n#define __NR_fsmount\t\t6432\n#define __NR_fspick\t\t6433\n#define __NR_pidfd_open\t\t6434\n#define __NR_clone3\t\t6435\n#define __NR_close_range\t6436\n#define __NR_openat2\t\t6437\n#define __NR_pidfd_getfd\t6438\n#define __NR_faccessat2\t\t6439\n\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/termios.h",
    "content": "struct termios {\n\ttcflag_t c_iflag;\n\ttcflag_t c_oflag;\n\ttcflag_t c_cflag;\n\ttcflag_t c_lflag;\n\tcc_t c_line;\n\tcc_t c_cc[NCCS];\n\tspeed_t __c_ispeed;\n\tspeed_t __c_ospeed;\n};\n\n#define VINTR     0\n#define VQUIT     1\n#define VERASE    2\n#define VKILL     3\n#define VMIN      4\n#define VTIME     5\n#define VEOL2     6\n#define VSWTC     7\n#define VSWTCH    7\n#define VSTART    8\n#define VSTOP     9\n#define VSUSP    10\n#define VREPRINT 12\n#define VDISCARD 13\n#define VWERASE  14\n#define VLNEXT   15\n#define VEOF     16\n#define VEOL     17\n\n#define IGNBRK  0000001\n#define BRKINT  0000002\n#define IGNPAR  0000004\n#define PARMRK  0000010\n#define INPCK   0000020\n#define ISTRIP  0000040\n#define INLCR   0000100\n#define IGNCR   0000200\n#define ICRNL   0000400\n#define IUCLC   0001000\n#define IXON    0002000\n#define IXANY   0004000\n#define IXOFF   0010000\n#define IMAXBEL 0020000\n#define IUTF8   0040000\n\n#define OPOST  0000001\n#define OLCUC  0000002\n#define ONLCR  0000004\n#define OCRNL  0000010\n#define ONOCR  0000020\n#define ONLRET 0000040\n#define OFILL  0000100\n#define OFDEL  0000200\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_XOPEN_SOURCE)\n#define NLDLY  0000400\n#define NL0    0000000\n#define NL1    0000400\n#define CRDLY  0003000\n#define CR0    0000000\n#define CR1    0001000\n#define CR2    0002000\n#define CR3    0003000\n#define TABDLY 0014000\n#define TAB0   0000000\n#define TAB1   0004000\n#define TAB2   0010000\n#define TAB3   0014000\n#define BSDLY  0020000\n#define BS0    0000000\n#define BS1    0020000\n#define FFDLY  0100000\n#define FF0    0000000\n#define FF1    0100000\n#endif\n\n#define VTDLY  0040000\n#define VT0    0000000\n#define VT1    0040000\n\n#define B0       0000000\n#define B50      0000001\n#define B75      0000002\n#define B110     0000003\n#define B134     0000004\n#define B150     0000005\n#define B200     0000006\n#define B300     0000007\n#define B600     0000010\n#define B1200    0000011\n#define B1800    0000012\n#define B2400    0000013\n#define B4800    0000014\n#define B9600    0000015\n#define B19200   0000016\n#define B38400   0000017\n\n#define B57600   0010001\n#define B115200  0010002\n#define B230400  0010003\n#define B460800  0010004\n#define B500000  0010005\n#define B576000  0010006\n#define B921600  0010007\n#define B1000000 0010010\n#define B1152000 0010011\n#define B1500000 0010012\n#define B2000000 0010013\n#define B2500000 0010014\n#define B3000000 0010015\n#define B3500000 0010016\n#define B4000000 0010017\n\n#define CSIZE  0000060\n#define CS5    0000000\n#define CS6    0000020\n#define CS7    0000040\n#define CS8    0000060\n#define CSTOPB 0000100\n#define CREAD  0000200\n#define PARENB 0000400\n#define PARODD 0001000\n#define HUPCL  0002000\n#define CLOCAL 0004000\n\n#define ISIG   0000001\n#define ICANON 0000002\n#define ECHO   0000010\n#define ECHOE  0000020\n#define ECHOK  0000040\n#define ECHONL 0000100\n#define NOFLSH 0000200\n#define IEXTEN 0000400\n#define TOSTOP 0100000\n#define ITOSTOP 0100000\n\n#define TCOOFF 0\n#define TCOON  1\n#define TCIOFF 2\n#define TCION  3\n\n#define TCIFLUSH  0\n#define TCOFLUSH  1\n#define TCIOFLUSH 2\n\n#define TCSANOW   0\n#define TCSADRAIN 1\n#define TCSAFLUSH 2\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define EXTA    0000016\n#define EXTB    0000017\n#define CBAUD   0010017\n#define CBAUDEX 0010000\n#define CIBAUD  002003600000\n#define CMSPAR  010000000000\n#define CRTSCTS 020000000000\n\n#define XCASE   0000004\n#define ECHOCTL 0001000\n#define ECHOPRT 0002000\n#define ECHOKE  0004000\n#define FLUSHO  0020000\n#define PENDIN  0040000\n#define EXTPROC 0200000\n\n#define XTABS  0014000\n#define TIOCSER_TEMT 1\n#endif\n"
  },
  {
    "path": "user.libc/arch/mipsn32/bits/user.h",
    "content": "struct user {\n\tunsigned long regs[102];\n\tunsigned long u_tsize, u_dsize, u_ssize;\n\tunsigned long long start_code, start_data, start_stack;\n\tlong long signal;\n\tunsigned long long *u_ar0;\n\tunsigned long long magic;\n\tchar u_comm[32];\n};\n\n#define ELF_NGREG 45\n#define ELF_NFPREG 33\n\ntypedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG];\ntypedef double elf_fpreg_t, elf_fpregset_t[ELF_NFPREG];\n"
  },
  {
    "path": "user.libc/arch/mipsn32/crt_arch.h",
    "content": "__asm__(\n\".set push\\n\"\n\".set noreorder\\n\"\n\".text \\n\"\n\".global _\" START \"\\n\"\n\".global \" START \"\\n\"\n\".global \" START \"_data\\n\"\n\".type   _\" START \", @function\\n\"\n\".type   \" START \", @function\\n\"\n\".type   \" START \"_data, @function\\n\"\n\"_\" START \":\\n\"\n\"\" START \":\\n\"\n\"\tbal 1f \\n\"\n\"\tmove $fp, $0 \\n\"\n\"\" START \"_data: \\n\"\n\"\t.gpword \" START \"_data \\n\"\n\"\t.gpword \" START \"_c \\n\"\n\".weak _DYNAMIC \\n\"\n\".hidden _DYNAMIC \\n\"\n\"\t.gpword _DYNAMIC \\n\"\n\"1:\tlw $gp, 0($ra) \\n\"\n\"\tsubu $gp, $ra, $gp \\n\"\n\"\tmove $4, $sp \\n\"\n\"\tlw $5, 8($ra) \\n\"\n\"\taddu $5, $5, $gp \\n\"\n\"\tlw $25, 4($ra) \\n\"\n\"\taddu $25, $25, $gp \\n\"\n\"\tand $sp, $sp, -8 \\n\"\n\"\tjalr $25 \\n\"\n\"\tsubu $sp, $sp, 16 \\n\"\n\".set pop \\n\"\n);\n"
  },
  {
    "path": "user.libc/arch/mipsn32/ksigaction.h",
    "content": "#include <features.h>\n\nstruct k_sigaction {\n\tunsigned flags;\n\tvoid (*handler)(int);\n\tunsigned long mask[4];\n\tvoid (*restorer)();\n};\n\nhidden void __restore(), __restore_rt();\n"
  },
  {
    "path": "user.libc/arch/mipsn32/kstat.h",
    "content": "struct kstat {\n\tunsigned st_dev;\n\tlong __pad1[3];\n\tino_t st_ino;\n\tmode_t st_mode;\n\tnlink_t st_nlink;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tunsigned st_rdev;\n\tlong __pad2[3];\n\toff_t st_size;\n\tlong st_atime_sec;\n\tlong st_atime_nsec;\n\tlong st_mtime_sec;\n\tlong st_mtime_nsec;\n\tlong st_ctime_sec;\n\tlong st_ctime_nsec;\n\tblksize_t st_blksize;\n\tlong __pad3;\n\tblkcnt_t st_blocks;\n\tlong __pad4[14];\n};\n"
  },
  {
    "path": "user.libc/arch/mipsn32/pthread_arch.h",
    "content": "static inline uintptr_t __get_tp()\n{\n#if __mips_isa_rev < 2\n\tregister uintptr_t tp __asm__(\"$3\");\n\t__asm__ (\".word 0x7c03e83b\" : \"=r\" (tp) );\n#else\n\tuintptr_t tp;\n\t__asm__ (\"rdhwr %0, $29\" : \"=r\" (tp) );\n#endif\n\treturn tp;\n}\n\n#define TLS_ABOVE_TP\n#define GAP_ABOVE_TP 0\n\n#define TP_OFFSET 0x7000\n#define DTP_OFFSET 0x8000\n\n#define MC_PC pc\n"
  },
  {
    "path": "user.libc/arch/mipsn32/reloc.h",
    "content": "#if __mips_isa_rev >= 6\n#define ISA_SUFFIX \"r6\"\n#else\n#define ISA_SUFFIX \"\"\n#endif\n\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n#define ENDIAN_SUFFIX \"el\"\n#else\n#define ENDIAN_SUFFIX \"\"\n#endif\n\n#ifdef __mips_soft_float\n#define FP_SUFFIX \"-sf\"\n#else\n#define FP_SUFFIX \"\"\n#endif\n\n#define LDSO_ARCH \"mipsn32\" ISA_SUFFIX ENDIAN_SUFFIX FP_SUFFIX\n\n#define TPOFF_K (-0x7000)\n\n#define REL_SYM_OR_REL  R_MIPS_REL32\n#define REL_PLT         R_MIPS_JUMP_SLOT\n#define REL_COPY        R_MIPS_COPY\n#define REL_DTPMOD      R_MIPS_TLS_DTPMOD32\n#define REL_DTPOFF      R_MIPS_TLS_DTPREL32\n#define REL_TPOFF       R_MIPS_TLS_TPREL32\n\n#define NEED_MIPS_GOT_RELOCS 1\n#define DT_DEBUG_INDIRECT DT_MIPS_RLD_MAP\n#define ARCH_SYM_REJECT_UND(s) (!((s)->st_other & STO_MIPS_PLT))\n\n#define CRTJMP(pc,sp) __asm__ __volatile__( \\\n\t\"move $sp,%1 ; jr %0\" : : \"r\"(pc), \"r\"(sp) : \"memory\" )\n\n#define GETFUNCSYM(fp, sym, got) __asm__ ( \\\n\t\".hidden \" #sym \"\\n\" \\\n\t\".set push \\n\" \\\n\t\".set noreorder \\n\" \\\n\t\"\tbal 1f \\n\" \\\n\t\"\tnop \\n\" \\\n\t\"\t.gpword . \\n\" \\\n\t\"\t.gpword \" #sym \" \\n\" \\\n\t\"1:\tlw %0, ($ra) \\n\" \\\n\t\"\tsubu %0, $ra, %0 \\n\" \\\n\t\"\tlw $ra, 4($ra) \\n\" \\\n\t\"\taddu %0, %0, $ra \\n\" \\\n\t\".set pop \\n\" \\\n\t: \"=r\"(*(fp)) : : \"memory\", \"ra\" )\n"
  },
  {
    "path": "user.libc/arch/mipsn32/syscall_arch.h",
    "content": "#define __SYSCALL_LL_E(x) (x)\n#define __SYSCALL_LL_O(x) (x)\n\n#define SYSCALL_RLIM_INFINITY (-1UL/2)\n\n#if __mips_isa_rev >= 6\n#define SYSCALL_CLOBBERLIST \\\n\t\"$1\", \"$3\", \"$10\", \"$11\", \"$12\", \"$13\", \\\n\t\"$14\", \"$15\", \"$24\", \"$25\", \"memory\"\n#else\n#define SYSCALL_CLOBBERLIST \\\n\t\"$1\", \"$3\", \"$10\", \"$11\", \"$12\", \"$13\", \\\n\t\"$14\", \"$15\", \"$24\", \"$25\", \"hi\", \"lo\", \"memory\"\n#endif\n\nstatic inline long __syscall0(long n)\n{\n\tregister long r7 __asm__(\"$7\");\n\tregister long r2 __asm__(\"$2\");\n\t__asm__ __volatile__ (\n\t\t\"daddu $2,$0,%2 ; syscall\"\n\t\t: \"=&r\"(r2), \"=r\"(r7)\n\t\t: \"ir\"(n), \"0\"(r2)\n\t\t: SYSCALL_CLOBBERLIST);\n\treturn r7 && r2>0 ? -r2 : r2;\n}\n\nstatic inline long __syscall1(long n, long a)\n{\n\tregister long r4 __asm__(\"$4\") = a;\n\tregister long r7 __asm__(\"$7\");\n\tregister long r2 __asm__(\"$2\");\n\t__asm__ __volatile__ (\n\t\t\"daddu $2,$0,%2 ; syscall\"\n\t\t: \"=&r\"(r2), \"=r\"(r7)\n\t\t: \"ir\"(n), \"0\"(r2), \"r\"(r4)\n\t\t: SYSCALL_CLOBBERLIST);\n\treturn r7 && r2>0 ? -r2 : r2;\n}\n\nstatic inline long __syscall2(long n, long a, long b)\n{\n\tregister long r4 __asm__(\"$4\") = a;\n\tregister long r5 __asm__(\"$5\") = b;\n\tregister long r7 __asm__(\"$7\");\n\tregister long r2 __asm__(\"$2\");\n\n\t__asm__ __volatile__ (\n\t\t\"daddu $2,$0,%2 ; syscall\"\n\t\t: \"=&r\"(r2), \"=r\"(r7)\n\t\t: \"ir\"(n), \"0\"(r2), \"r\"(r4), \"r\"(r5)\n\t\t: SYSCALL_CLOBBERLIST);\n\treturn r7 && r2>0 ? -r2 : r2;\n}\n\nstatic inline long __syscall3(long n, long a, long b, long c)\n{\n\tregister long r4 __asm__(\"$4\") = a;\n\tregister long r5 __asm__(\"$5\") = b;\n\tregister long r6 __asm__(\"$6\") = c;\n\tregister long r7 __asm__(\"$7\");\n\tregister long r2 __asm__(\"$2\");\n\n\t__asm__ __volatile__ (\n\t\t\"daddu $2,$0,%2 ; syscall\"\n\t\t: \"=&r\"(r2), \"=r\"(r7)\n\t\t: \"ir\"(n), \"0\"(r2), \"r\"(r4), \"r\"(r5), \"r\"(r6)\n\t\t: SYSCALL_CLOBBERLIST);\n\treturn r7 && r2>0 ? -r2 : r2;\n}\n\nstatic inline long __syscall4(long n, long a, long b, long c, long d)\n{\n\tregister long r4 __asm__(\"$4\") = a;\n\tregister long r5 __asm__(\"$5\") = b;\n\tregister long r6 __asm__(\"$6\") = c;\n\tregister long r7 __asm__(\"$7\") = d;\n\tregister long r2 __asm__(\"$2\");\n\n\t__asm__ __volatile__ (\n\t\t\"daddu $2,$0,%2 ; syscall\"\n\t\t: \"=&r\"(r2), \"+r\"(r7)\n\t\t: \"ir\"(n), \"0\"(r2), \"r\"(r4), \"r\"(r5), \"r\"(r6)\n\t\t: SYSCALL_CLOBBERLIST);\n\treturn r7 && r2>0 ? -r2 : r2;\n}\n\nstatic inline long __syscall5(long n, long a, long b, long c, long d, long e)\n{\n\tregister long r4 __asm__(\"$4\") = a;\n\tregister long r5 __asm__(\"$5\") = b;\n\tregister long r6 __asm__(\"$6\") = c;\n\tregister long r7 __asm__(\"$7\") = d;\n\tregister long r8 __asm__(\"$8\") = e;\n\tregister long r2 __asm__(\"$2\");\n\n\t__asm__ __volatile__ (\n\t\t\"daddu $2,$0,%2 ; syscall\"\n\t\t: \"=&r\"(r2), \"+r\"(r7)\n\t\t: \"ir\"(n), \"0\"(r2), \"r\"(r4), \"r\"(r5), \"r\"(r6), \"r\"(r8)\n\t\t: SYSCALL_CLOBBERLIST);\n\treturn r7 && r2>0 ? -r2 : r2;\n}\n\nstatic inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)\n{\n\tregister long r4 __asm__(\"$4\") = a;\n\tregister long r5 __asm__(\"$5\") = b;\n\tregister long r6 __asm__(\"$6\") = c;\n\tregister long r7 __asm__(\"$7\") = d;\n\tregister long r8 __asm__(\"$8\") = e;\n\tregister long r9 __asm__(\"$9\") = f;\n\tregister long r2 __asm__(\"$2\");\n\n\t__asm__ __volatile__ (\n\t\t\"daddu $2,$0,%2 ; syscall\"\n\t\t: \"=&r\"(r2), \"+r\"(r7)\n\t\t: \"ir\"(n), \"0\"(r2), \"r\"(r4), \"r\"(r5), \"r\"(r6), \"r\"(r8), \"r\"(r9)\n\t\t: SYSCALL_CLOBBERLIST);\n\treturn r7 && r2>0 ? -r2 : r2;\n}\n\n#define VDSO_USEFUL\n#define VDSO_CGT32_SYM \"__vdso_clock_gettime\"\n#define VDSO_CGT32_VER \"LINUX_2.6\"\n#define VDSO_CGT_SYM \"__vdso_clock_gettime64\"\n#define VDSO_CGT_VER \"LINUX_2.6\"\n\n#define SO_SNDTIMEO_OLD 0x1005\n#define SO_RCVTIMEO_OLD 0x1006\n"
  },
  {
    "path": "user.libc/arch/or1k/arch.mak",
    "content": "COMPAT_SRC_DIRS = compat/time32\n"
  },
  {
    "path": "user.libc/arch/or1k/atomic_arch.h",
    "content": "#define a_cas a_cas\nstatic inline int a_cas(volatile int *p, int t, int s)\n{\n\t__asm__(\"1:\tl.lwa %0, %1\\n\"\n\t\t\"\tl.sfeq %0, %2\\n\"\n\t\t\"\tl.bnf 1f\\n\"\n\t\t\"\t l.nop\\n\"\n\t\t\"\tl.swa %1, %3\\n\"\n\t\t\"\tl.bnf 1b\\n\"\n\t\t\"\t l.nop\\n\"\n\t\t\"1:\t\\n\"\n\t\t: \"=&r\"(t), \"+m\"(*p) : \"r\"(t), \"r\"(s) : \"cc\", \"memory\" );\n        return t;\n}\n"
  },
  {
    "path": "user.libc/arch/or1k/bits/alltypes.h.in",
    "content": "#define _REDIR_TIME64 1\n#define _Addr int\n#define _Int64 long long\n#define _Reg int\n\n#define __BYTE_ORDER 4321\n#define __LONG_MAX 0x7fffffffL\n\n#ifndef __cplusplus\nTYPEDEF unsigned wchar_t;\n#endif\n\nTYPEDEF float float_t;\nTYPEDEF double double_t;\n\nTYPEDEF struct { long long __ll; long double __ld; } max_align_t;\n"
  },
  {
    "path": "user.libc/arch/or1k/bits/float.h",
    "content": "#define FLT_EVAL_METHOD 0\n\n#define LDBL_TRUE_MIN 4.94065645841246544177e-324L\n#define LDBL_MIN 2.22507385850720138309e-308L\n#define LDBL_MAX 1.79769313486231570815e+308L\n#define LDBL_EPSILON 2.22044604925031308085e-16L\n\n#define LDBL_MANT_DIG 53\n#define LDBL_MIN_EXP (-1021)\n#define LDBL_MAX_EXP 1024\n\n#define LDBL_DIG 15\n#define LDBL_MIN_10_EXP (-307)\n#define LDBL_MAX_10_EXP 308\n\n#define DECIMAL_DIG 17\n"
  },
  {
    "path": "user.libc/arch/or1k/bits/ipcstat.h",
    "content": "#define IPC_STAT 0x102\n"
  },
  {
    "path": "user.libc/arch/or1k/bits/limits.h",
    "content": "#define PAGESIZE 8192\n"
  },
  {
    "path": "user.libc/arch/or1k/bits/msg.h",
    "content": "struct msqid_ds {\n\tstruct ipc_perm msg_perm;\n\tunsigned long __msg_stime_lo;\n\tunsigned long __msg_stime_hi;\n\tunsigned long __msg_rtime_lo;\n\tunsigned long __msg_rtime_hi;\n\tunsigned long __msg_ctime_lo;\n\tunsigned long __msg_ctime_hi;\n\tunsigned long msg_cbytes;\n\tmsgqnum_t msg_qnum;\n\tmsglen_t msg_qbytes;\n\tpid_t msg_lspid;\n\tpid_t msg_lrpid;\n\tunsigned long __unused[2];\n\ttime_t msg_stime;\n\ttime_t msg_rtime;\n\ttime_t msg_ctime;\n};\n"
  },
  {
    "path": "user.libc/arch/or1k/bits/posix.h",
    "content": "#define _POSIX_V6_ILP32_OFFBIG  1\n#define _POSIX_V7_ILP32_OFFBIG  1\n"
  },
  {
    "path": "user.libc/arch/or1k/bits/reg.h",
    "content": "#undef __WORDSIZE\n#define __WORDSIZE 32\n/* FIXME */\n"
  },
  {
    "path": "user.libc/arch/or1k/bits/sem.h",
    "content": "struct semid_ds {\n\tstruct ipc_perm sem_perm;\n\tunsigned long __sem_otime_lo;\n\tunsigned long __sem_otime_hi;\n\tunsigned long __sem_ctime_lo;\n\tunsigned long __sem_ctime_hi;\n\tchar __sem_nsems_pad[sizeof(long)-sizeof(short)];\n\tunsigned short sem_nsems;\n\tlong __unused3;\n\tlong __unused4;\n\ttime_t sem_otime;\n\ttime_t sem_ctime;\n};\n"
  },
  {
    "path": "user.libc/arch/or1k/bits/setjmp.h",
    "content": "typedef unsigned long __jmp_buf[13];\n"
  },
  {
    "path": "user.libc/arch/or1k/bits/shm.h",
    "content": "#define SHMLBA 4096\n\nstruct shmid_ds {\n\tstruct ipc_perm shm_perm;\n\tsize_t shm_segsz;\n\tunsigned long __shm_atime_lo;\n\tunsigned long __shm_atime_hi;\n\tunsigned long __shm_dtime_lo;\n\tunsigned long __shm_dtime_hi;\n\tunsigned long __shm_ctime_lo;\n\tunsigned long __shm_ctime_hi;\n\tpid_t shm_cpid;\n\tpid_t shm_lpid;\n\tunsigned long shm_nattch;\n\tunsigned long __pad1;\n\tunsigned long __pad2;\n\tunsigned long __pad3;\n\ttime_t shm_atime;\n\ttime_t shm_dtime;\n\ttime_t shm_ctime;\n};\n\nstruct shminfo {\n\tunsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];\n};\n\nstruct shm_info {\n\tint __used_ids;\n\tunsigned long shm_tot, shm_rss, shm_swp;\n\tunsigned long __swap_attempts, __swap_successes;\n};\n"
  },
  {
    "path": "user.libc/arch/or1k/bits/signal.h",
    "content": "#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define MINSIGSTKSZ 2048\n#define SIGSTKSZ 8192\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\ntypedef unsigned long greg_t, gregset_t[34];\ntypedef struct sigcontext {\n\tstruct {\n\t\tunsigned long gpr[32];\n\t\tunsigned long pc;\n\t\tunsigned long sr;\n\t} regs;\n\tunsigned long oldmask;\n} mcontext_t;\n#else\ntypedef struct {\n\tunsigned long __regs[35];\n} mcontext_t;\n#endif\n\nstruct sigaltstack {\n\tvoid *ss_sp;\n\tint ss_flags;\n\tsize_t ss_size;\n};\n\ntypedef struct __ucontext {\n\tunsigned long uc_flags;\n\tstruct __ucontext *uc_link;\n\tstack_t uc_stack;\n\tmcontext_t uc_mcontext;\n\tsigset_t uc_sigmask;\n} ucontext_t;\n\n#define SA_NOCLDSTOP  1\n#define SA_NOCLDWAIT  2\n#define SA_SIGINFO    4\n#define SA_ONSTACK    0x08000000\n#define SA_RESTART    0x10000000\n#define SA_NODEFER    0x40000000\n#define SA_RESETHAND  0x80000000\n#define SA_RESTORER   0x04000000\n\n#endif\n\n#define SIGHUP    1\n#define SIGINT    2\n#define SIGQUIT   3\n#define SIGILL    4\n#define SIGTRAP   5\n#define SIGABRT   6\n#define SIGIOT    SIGABRT\n#define SIGBUS    7\n#define SIGFPE    8\n#define SIGKILL   9\n#define SIGUSR1   10\n#define SIGSEGV   11\n#define SIGUSR2   12\n#define SIGPIPE   13\n#define SIGALRM   14\n#define SIGTERM   15\n#define SIGSTKFLT 16\n#define SIGCHLD   17\n#define SIGCONT   18\n#define SIGSTOP   19\n#define SIGTSTP   20\n#define SIGTTIN   21\n#define SIGTTOU   22\n#define SIGURG    23\n#define SIGXCPU   24\n#define SIGXFSZ   25\n#define SIGVTALRM 26\n#define SIGPROF   27\n#define SIGWINCH  28\n#define SIGIO     29\n#define SIGPOLL   29\n#define SIGPWR    30\n#define SIGSYS    31\n#define SIGUNUSED SIGSYS\n\n#define _NSIG 65\n"
  },
  {
    "path": "user.libc/arch/or1k/bits/stat.h",
    "content": "/* copied from kernel definition, but with padding replaced\n * by the corresponding correctly-sized userspace types. */\n\nstruct stat {\n\tdev_t st_dev;\n\tino_t st_ino;\n\tmode_t st_mode;\n\tnlink_t st_nlink;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tdev_t st_rdev;\n\tlong long __st_rdev_padding;\n\toff_t st_size;\n\tblksize_t st_blksize;\n\tint __st_blksize_padding;\n\tblkcnt_t st_blocks;\n\tstruct {\n\t\tlong tv_sec;\n\t\tlong tv_nsec;\n\t} __st_atim32, __st_mtim32, __st_ctim32;\n\tunsigned __unused[2];\n \tstruct timespec st_atim;\n \tstruct timespec st_mtim;\n \tstruct timespec st_ctim;\n};\n"
  },
  {
    "path": "user.libc/arch/or1k/bits/stdint.h",
    "content": "typedef int32_t int_fast16_t;\ntypedef int32_t int_fast32_t;\ntypedef uint32_t uint_fast16_t;\ntypedef uint32_t uint_fast32_t;\n\n#define INT_FAST16_MIN  INT32_MIN\n#define INT_FAST32_MIN  INT32_MIN\n\n#define INT_FAST16_MAX  INT32_MAX\n#define INT_FAST32_MAX  INT32_MAX\n\n#define UINT_FAST16_MAX UINT32_MAX\n#define UINT_FAST32_MAX UINT32_MAX\n\n#define INTPTR_MIN      INT32_MIN\n#define INTPTR_MAX      INT32_MAX\n#define UINTPTR_MAX     UINT32_MAX\n#define PTRDIFF_MIN     INT32_MIN\n#define PTRDIFF_MAX     INT32_MAX\n#define SIZE_MAX        UINT32_MAX\n"
  },
  {
    "path": "user.libc/arch/or1k/bits/syscall.h.in",
    "content": "#define __NR_io_setup 0\n#define __NR_io_destroy 1\n#define __NR_io_submit 2\n#define __NR_io_cancel 3\n#define __NR_io_getevents 4\n#define __NR_setxattr 5\n#define __NR_lsetxattr 6\n#define __NR_fsetxattr 7\n#define __NR_getxattr 8\n#define __NR_lgetxattr 9\n#define __NR_fgetxattr 10\n#define __NR_listxattr 11\n#define __NR_llistxattr 12\n#define __NR_flistxattr 13\n#define __NR_removexattr 14\n#define __NR_lremovexattr 15\n#define __NR_fremovexattr 16\n#define __NR_getcwd 17\n#define __NR_lookup_dcookie 18\n#define __NR_eventfd2 19\n#define __NR_epoll_create1 20\n#define __NR_epoll_ctl 21\n#define __NR_epoll_pwait 22\n#define __NR_dup 23\n#define __NR_dup3 24\n#define __NR_fcntl64 25\n#define __NR_inotify_init1 26\n#define __NR_inotify_add_watch 27\n#define __NR_inotify_rm_watch 28\n#define __NR_ioctl 29\n#define __NR_ioprio_set 30\n#define __NR_ioprio_get 31\n#define __NR_flock 32\n#define __NR_mknodat 33\n#define __NR_mkdirat 34\n#define __NR_unlinkat 35\n#define __NR_symlinkat 36\n#define __NR_linkat 37\n#define __NR_renameat 38\n#define __NR_umount2 39\n#define __NR_mount 40\n#define __NR_pivot_root 41\n#define __NR_nfsservctl 42\n#define __NR_statfs64 43\n#define __NR_fstatfs64 44\n#define __NR_truncate64 45\n#define __NR_ftruncate64 46\n#define __NR_fallocate 47\n#define __NR_faccessat 48\n#define __NR_chdir 49\n#define __NR_fchdir 50\n#define __NR_chroot 51\n#define __NR_fchmod 52\n#define __NR_fchmodat 53\n#define __NR_fchownat 54\n#define __NR_fchown 55\n#define __NR_openat 56\n#define __NR_close 57\n#define __NR_vhangup 58\n#define __NR_pipe2 59\n#define __NR_quotactl 60\n#define __NR_getdents64 61\n#define __NR__llseek 62\n#define __NR_llseek 62\n#define __NR_read 63\n#define __NR_write 64\n#define __NR_readv 65\n#define __NR_writev 66\n#define __NR_pread64 67\n#define __NR_pwrite64 68\n#define __NR_preadv 69\n#define __NR_pwritev 70\n#define __NR_sendfile64 71\n#define __NR_pselect6 72\n#define __NR_ppoll 73\n#define __NR_signalfd4 74\n#define __NR_vmsplice 75\n#define __NR_splice 76\n#define __NR_tee 77\n#define __NR_readlinkat 78\n#define __NR_fstatat64 79\n#define __NR_fstat64 80\n#define __NR_sync 81\n#define __NR_fsync 82\n#define __NR_fdatasync 83\n#define __NR_sync_file_range 84\n#define __NR_timerfd_create 85\n#define __NR_timerfd_settime32 86\n#define __NR_timerfd_gettime32 87\n#define __NR_utimensat 88\n#define __NR_acct 89\n#define __NR_capget 90\n#define __NR_capset 91\n#define __NR_personality 92\n#define __NR_exit 93\n#define __NR_exit_group 94\n#define __NR_waitid 95\n#define __NR_set_tid_address 96\n#define __NR_unshare 97\n#define __NR_futex 98\n#define __NR_set_robust_list 99\n#define __NR_get_robust_list 100\n#define __NR_nanosleep 101\n#define __NR_getitimer 102\n#define __NR_setitimer 103\n#define __NR_kexec_load 104\n#define __NR_init_module 105\n#define __NR_delete_module 106\n#define __NR_timer_create 107\n#define __NR_timer_gettime32 108\n#define __NR_timer_getoverrun 109\n#define __NR_timer_settime32 110\n#define __NR_timer_delete 111\n#define __NR_clock_settime32 112\n#define __NR_clock_gettime32 113\n#define __NR_clock_getres_time32 114\n#define __NR_clock_nanosleep_time32 115\n#define __NR_syslog 116\n#define __NR_ptrace 117\n#define __NR_sched_setparam 118\n#define __NR_sched_setscheduler 119\n#define __NR_sched_getscheduler 120\n#define __NR_sched_getparam 121\n#define __NR_sched_setaffinity 122\n#define __NR_sched_getaffinity 123\n#define __NR_sched_yield 124\n#define __NR_sched_get_priority_max 125\n#define __NR_sched_get_priority_min 126\n#define __NR_sched_rr_get_interval 127\n#define __NR_restart_syscall 128\n#define __NR_kill 129\n#define __NR_tkill 130\n#define __NR_tgkill 131\n#define __NR_sigaltstack 132\n#define __NR_rt_sigsuspend 133\n#define __NR_rt_sigaction 134\n#define __NR_rt_sigprocmask 135\n#define __NR_rt_sigpending 136\n#define __NR_rt_sigtimedwait 137\n#define __NR_rt_sigqueueinfo 138\n#define __NR_rt_sigreturn 139\n#define __NR_setpriority 140\n#define __NR_getpriority 141\n#define __NR_reboot 142\n#define __NR_setregid 143\n#define __NR_setgid 144\n#define __NR_setreuid 145\n#define __NR_setuid 146\n#define __NR_setresuid 147\n#define __NR_getresuid 148\n#define __NR_setresgid 149\n#define __NR_getresgid 150\n#define __NR_setfsuid 151\n#define __NR_setfsgid 152\n#define __NR_times 153\n#define __NR_setpgid 154\n#define __NR_getpgid 155\n#define __NR_getsid 156\n#define __NR_setsid 157\n#define __NR_getgroups 158\n#define __NR_setgroups 159\n#define __NR_uname 160\n#define __NR_sethostname 161\n#define __NR_setdomainname 162\n#define __NR_getrlimit 163\n#define __NR_setrlimit 164\n#define __NR_getrusage 165\n#define __NR_umask 166\n#define __NR_prctl 167\n#define __NR_getcpu 168\n#define __NR_gettimeofday_time32 169\n#define __NR_settimeofday_time32 170\n#define __NR_adjtimex 171\n#define __NR_getpid 172\n#define __NR_getppid 173\n#define __NR_getuid 174\n#define __NR_geteuid 175\n#define __NR_getgid 176\n#define __NR_getegid 177\n#define __NR_gettid 178\n#define __NR_sysinfo 179\n#define __NR_mq_open 180\n#define __NR_mq_unlink 181\n#define __NR_mq_timedsend 182\n#define __NR_mq_timedreceive 183\n#define __NR_mq_notify 184\n#define __NR_mq_getsetattr 185\n#define __NR_msgget 186\n#define __NR_msgctl 187\n#define __NR_msgrcv 188\n#define __NR_msgsnd 189\n#define __NR_semget 190\n#define __NR_semctl 191\n#define __NR_semtimedop 192\n#define __NR_semop 193\n#define __NR_shmget 194\n#define __NR_shmctl 195\n#define __NR_shmat 196\n#define __NR_shmdt 197\n#define __NR_socket 198\n#define __NR_socketpair 199\n#define __NR_bind 200\n#define __NR_listen 201\n#define __NR_accept 202\n#define __NR_connect 203\n#define __NR_getsockname 204\n#define __NR_getpeername 205\n#define __NR_sendto 206\n#define __NR_recvfrom 207\n#define __NR_setsockopt 208\n#define __NR_getsockopt 209\n#define __NR_shutdown 210\n#define __NR_sendmsg 211\n#define __NR_recvmsg 212\n#define __NR_readahead 213\n#define __NR_brk 214\n#define __NR_munmap 215\n#define __NR_mremap 216\n#define __NR_add_key 217\n#define __NR_request_key 218\n#define __NR_keyctl 219\n#define __NR_clone 220\n#define __NR_execve 221\n#define __NR_mmap2 222\n#define __NR_fadvise64_64 223\n#define __NR_swapon 224\n#define __NR_swapoff 225\n#define __NR_mprotect 226\n#define __NR_msync 227\n#define __NR_mlock 228\n#define __NR_munlock 229\n#define __NR_mlockall 230\n#define __NR_munlockall 231\n#define __NR_mincore 232\n#define __NR_madvise 233\n#define __NR_remap_file_pages 234\n#define __NR_mbind 235\n#define __NR_get_mempolicy 236\n#define __NR_set_mempolicy 237\n#define __NR_migrate_pages 238\n#define __NR_move_pages 239\n#define __NR_rt_tgsigqueueinfo 240\n#define __NR_perf_event_open 241\n#define __NR_accept4 242\n#define __NR_recvmmsg 243\n#define __NR_or1k_atomic 244\n#define __NR_wait4 260\n#define __NR_prlimit64 261\n#define __NR_fanotify_init 262\n#define __NR_fanotify_mark 263\n#define __NR_name_to_handle_at 264\n#define __NR_open_by_handle_at 265\n#define __NR_clock_adjtime 266\n#define __NR_syncfs 267\n#define __NR_setns 268\n#define __NR_sendmmsg 269\n#define __NR_process_vm_readv 270\n#define __NR_process_vm_writev 271\n#define __NR_kcmp 272\n#define __NR_finit_module 273\n#define __NR_sched_setattr 274\n#define __NR_sched_getattr 275\n#define __NR_renameat2 276\n#define __NR_seccomp 277\n#define __NR_getrandom 278\n#define __NR_memfd_create 279\n#define __NR_bpf 280\n#define __NR_execveat 281\n#define __NR_userfaultfd 282\n#define __NR_membarrier 283\n#define __NR_mlock2 284\n#define __NR_copy_file_range 285\n#define __NR_preadv2 286\n#define __NR_pwritev2 287\n#define __NR_pkey_mprotect 288\n#define __NR_pkey_alloc 289\n#define __NR_pkey_free 290\n#define __NR_statx 291\n#define __NR_io_pgetevents 292\n#define __NR_rseq 293\n#define __NR_kexec_file_load 294\n#define __NR_clock_gettime64 403\n#define __NR_clock_settime64 404\n#define __NR_clock_adjtime64 405\n#define __NR_clock_getres_time64 406\n#define __NR_clock_nanosleep_time64 407\n#define __NR_timer_gettime64 408\n#define __NR_timer_settime64 409\n#define __NR_timerfd_gettime64 410\n#define __NR_timerfd_settime64 411\n#define __NR_utimensat_time64 412\n#define __NR_pselect6_time64 413\n#define __NR_ppoll_time64 414\n#define __NR_io_pgetevents_time64 416\n#define __NR_recvmmsg_time64 417\n#define __NR_mq_timedsend_time64 418\n#define __NR_mq_timedreceive_time64 419\n#define __NR_semtimedop_time64 420\n#define __NR_rt_sigtimedwait_time64 421\n#define __NR_futex_time64 422\n#define __NR_sched_rr_get_interval_time64 423\n#define __NR_pidfd_send_signal 424\n#define __NR_io_uring_setup 425\n#define __NR_io_uring_enter 426\n#define __NR_io_uring_register 427\n#define __NR_open_tree\t\t428\n#define __NR_move_mount\t\t429\n#define __NR_fsopen\t\t430\n#define __NR_fsconfig\t\t431\n#define __NR_fsmount\t\t432\n#define __NR_fspick\t\t433\n#define __NR_pidfd_open\t\t434\n#define __NR_clone3\t\t435\n#define __NR_close_range\t436\n#define __NR_openat2\t\t437\n#define __NR_pidfd_getfd\t438\n#define __NR_faccessat2\t\t439\n\n"
  },
  {
    "path": "user.libc/arch/or1k/bits/user.h",
    "content": ""
  },
  {
    "path": "user.libc/arch/or1k/crt_arch.h",
    "content": "__asm__(\n\".text \\n\"\n\".global \" START \" \\n\"\n\".align  4 \\n\"\nSTART \": \\n\"\n\"\tl.jal 1f \\n\"\n\"\t l.ori r3, r1, 0 \\n\"\n\".weak _DYNAMIC \\n\"\n\".hidden _DYNAMIC \\n\"\n\"\t.word _DYNAMIC-. \\n\"\n\"1:\tl.lwz r4, 0(r9) \\n\"\n\"\tl.add r4, r4, r9 \\n\"\n\"\tl.addi r2, r0, -8 \\n\"\n\"\tl.and r1, r1, r2 \\n\"\n\"\tl.addi r1, r1, -16 \\n\"\n\"\tl.jal \" START \"_c \\n\"\n\"\t l.ori r2, r0, 0 \\n\"\n);\n"
  },
  {
    "path": "user.libc/arch/or1k/kstat.h",
    "content": "struct kstat {\n\tdev_t st_dev;\n\tino_t st_ino;\n\tmode_t st_mode;\n\tnlink_t st_nlink;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tdev_t st_rdev;\n\tlong long __st_rdev_padding;\n\toff_t st_size;\n\tblksize_t st_blksize;\n\tint __st_blksize_padding;\n\tblkcnt_t st_blocks;\n\tlong st_atime_sec;\n\tlong st_atime_nsec;\n\tlong st_mtime_sec;\n\tlong st_mtime_nsec;\n\tlong st_ctime_sec;\n\tlong st_ctime_nsec;\n\tunsigned __unused[2];\n};\n"
  },
  {
    "path": "user.libc/arch/or1k/pthread_arch.h",
    "content": "static inline uintptr_t __get_tp()\n{\n#ifdef __clang__\n\tuintptr_t tp;\n\t__asm__ (\"l.ori %0, r10, 0\" : \"=r\" (tp) );\n#else\n\tregister uintptr_t tp __asm__(\"r10\");\n\t__asm__ (\"\" : \"=r\" (tp) );\n#endif\n\treturn tp;\n}\n\n#define TLS_ABOVE_TP\n#define GAP_ABOVE_TP 0\n\n#define MC_PC regs.pc\n"
  },
  {
    "path": "user.libc/arch/or1k/reloc.h",
    "content": "#define LDSO_ARCH \"or1k\"\n\n#define TPOFF_K 0\n\n#define REL_SYMBOLIC    R_OR1K_32\n#define REL_GOT         R_OR1K_GLOB_DAT\n#define REL_PLT         R_OR1K_JMP_SLOT\n#define REL_RELATIVE    R_OR1K_RELATIVE\n#define REL_COPY        R_OR1K_COPY\n#define REL_DTPMOD      R_OR1K_TLS_DTPMOD\n#define REL_DTPOFF      R_OR1K_TLS_DTPOFF\n#define REL_TPOFF       R_OR1K_TLS_TPOFF\n\n#define CRTJMP(pc,sp) __asm__ __volatile__( \\\n\t\"l.jr %0 ; l.ori r1,%1,0\" : : \"r\"(pc), \"r\"(sp) : \"memory\" )\n\n#define GETFUNCSYM(fp, sym, got) __asm__ ( \\\n\t\".hidden \" #sym \" \\n\" \\\n\t\"\tl.jal 1f \\n\" \\\n\t\"\t l.nop \\n\" \\\n\t\"\t.word \" #sym \"-. \\n\" \\\n\t\"1:\tl.lwz %0, 0(r9) \\n\" \\\n\t\"\tl.add %0, %0, r9 \\n\" \\\n\t: \"=r\"(*(fp)) : : \"memory\", \"r9\" )\n"
  },
  {
    "path": "user.libc/arch/or1k/syscall_arch.h",
    "content": "#define __SYSCALL_LL_E(x) \\\n((union { long long ll; long l[2]; }){ .ll = x }).l[0], \\\n((union { long long ll; long l[2]; }){ .ll = x }).l[1]\n#define __SYSCALL_LL_O(x) __SYSCALL_LL_E((x))\n\n#define SYSCALL_MMAP2_UNIT 8192ULL\n\nstatic __inline long __syscall0(long n)\n{\n\tregister unsigned long r11 __asm__(\"r11\") = n;\n\t__asm__ __volatile__ (\"l.sys 1\"\n\t\t\t      : \"=r\"(r11)\n\t\t\t      : \"r\"(r11)\n\t\t\t      : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\",\n\t\t\t\t\"r12\", \"r13\", \"r15\", \"r17\", \"r19\", \"r21\",\n\t\t\t\t\"r23\", \"r25\", \"r27\", \"r29\", \"r31\");\n\treturn r11;\n}\n\nstatic inline long __syscall1(long n, long a)\n{\n\tregister unsigned long r11 __asm__(\"r11\") = n;\n\tregister unsigned long r3 __asm__(\"r3\") = a;\n\t__asm__ __volatile__ (\"l.sys 1\"\n\t\t\t      : \"=r\"(r11)\n\t\t\t      : \"r\"(r11), \"r\"(r3)\n\t\t\t      : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\",\n\t\t\t\t\"r12\", \"r13\", \"r15\", \"r17\", \"r19\", \"r21\",\n\t\t\t\t\"r23\", \"r25\", \"r27\", \"r29\", \"r31\");\n\treturn r11;\n}\n\nstatic inline long __syscall2(long n, long a, long b)\n{\n\tregister unsigned long r11 __asm__(\"r11\") = n;\n\tregister unsigned long r3 __asm__(\"r3\") = a;\n\tregister unsigned long r4 __asm__(\"r4\") = b;\n\t__asm__ __volatile__ (\"l.sys 1\"\n\t\t\t      : \"=r\"(r11)\n\t\t\t      : \"r\"(r11), \"r\"(r3), \"r\"(r4)\n\t\t\t      : \"memory\", \"r5\", \"r6\", \"r7\", \"r8\",\n\t\t\t\t\"r12\", \"r13\", \"r15\", \"r17\", \"r19\", \"r21\",\n\t\t\t\t\"r23\", \"r25\", \"r27\", \"r29\", \"r31\");\n\treturn r11;\n}\n\nstatic inline long __syscall3(long n, long a, long b, long c)\n{\n\tregister unsigned long r11 __asm__(\"r11\") = n;\n\tregister unsigned long r3 __asm__(\"r3\") = a;\n\tregister unsigned long r4 __asm__(\"r4\") = b;\n\tregister unsigned long r5 __asm__(\"r5\") = c;\n\t__asm__ __volatile__ (\"l.sys 1\"\n\t\t\t      : \"=r\"(r11)\n\t\t\t      : \"r\"(r11), \"r\"(r3), \"r\"(r4), \"r\"(r5)\n\t\t\t      : \"memory\", \"r6\", \"r7\", \"r8\",\n\t\t\t\t\"r12\", \"r13\", \"r15\", \"r17\", \"r19\", \"r21\",\n\t\t\t\t\"r23\", \"r25\", \"r27\", \"r29\", \"r31\");\n\treturn r11;\n}\n\nstatic inline long __syscall4(long n, long a, long b, long c, long d)\n{\n\tregister unsigned long r11 __asm__(\"r11\") = n;\n\tregister unsigned long r3 __asm__(\"r3\") = a;\n\tregister unsigned long r4 __asm__(\"r4\") = b;\n\tregister unsigned long r5 __asm__(\"r5\") = c;\n\tregister unsigned long r6 __asm__(\"r6\") = d;\n\t__asm__ __volatile__ (\"l.sys 1\"\n\t\t\t      : \"=r\"(r11)\n\t\t\t      : \"r\"(r11), \"r\"(r3), \"r\"(r4), \"r\"(r5), \"r\"(r6)\n\t\t\t      : \"memory\", \"r7\", \"r8\",\n\t\t\t\t\"r12\", \"r13\", \"r15\", \"r17\", \"r19\", \"r21\",\n\t\t\t\t\"r23\", \"r25\", \"r27\", \"r29\", \"r31\");\n\treturn r11;\n}\n\nstatic inline long __syscall5(long n, long a, long b, long c, long d, long e)\n{\n\tregister unsigned long r11 __asm__(\"r11\") = n;\n\tregister unsigned long r3 __asm__(\"r3\") = a;\n\tregister unsigned long r4 __asm__(\"r4\") = b;\n\tregister unsigned long r5 __asm__(\"r5\") = c;\n\tregister unsigned long r6 __asm__(\"r6\") = d;\n\tregister unsigned long r7 __asm__(\"r7\") = e;\n\t__asm__ __volatile__ (\"l.sys 1\"\n\t\t\t      : \"=r\"(r11)\n\t\t\t      : \"r\"(r11), \"r\"(r3), \"r\"(r4), \"r\"(r5), \"r\"(r6),\n\t\t\t\t\"r\"(r7)\n\t\t\t      : \"memory\", \"r8\",\n\t\t\t\t\"r12\", \"r13\", \"r15\", \"r17\", \"r19\", \"r21\",\n\t\t\t\t\"r23\", \"r25\", \"r27\", \"r29\", \"r31\");\n\treturn r11;\n}\n\nstatic inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)\n{\n\tregister unsigned long r11 __asm__(\"r11\") = n;\n\tregister unsigned long r3 __asm__(\"r3\") = a;\n\tregister unsigned long r4 __asm__(\"r4\") = b;\n\tregister unsigned long r5 __asm__(\"r5\") = c;\n\tregister unsigned long r6 __asm__(\"r6\") = d;\n\tregister unsigned long r7 __asm__(\"r7\") = e;\n\tregister unsigned long r8 __asm__(\"r8\") = f;\n\t__asm__ __volatile__ (\"l.sys 1\"\n\t\t\t      : \"=r\"(r11)\n\t\t\t      : \"r\"(r11), \"r\"(r3), \"r\"(r4), \"r\"(r5), \"r\"(r6),\n\t\t\t\t\"r\"(r7), \"r\"(r8)\n\t\t\t      : \"memory\",\n\t\t\t\t\"r12\", \"r13\", \"r15\", \"r17\", \"r19\", \"r21\",\n\t\t\t\t\"r23\", \"r25\", \"r27\", \"r29\", \"r31\");\n\treturn r11;\n}\n\n#define IPC_64 0\n"
  },
  {
    "path": "user.libc/arch/powerpc/arch.mak",
    "content": "COMPAT_SRC_DIRS = compat/time32\n"
  },
  {
    "path": "user.libc/arch/powerpc/atomic_arch.h",
    "content": "#define a_ll a_ll\nstatic inline int a_ll(volatile int *p)\n{\n\tint v;\n\t__asm__ __volatile__ (\"lwarx %0, 0, %2\" : \"=r\"(v) : \"m\"(*p), \"r\"(p));\n\treturn v;\n}\n\n#define a_sc a_sc\nstatic inline int a_sc(volatile int *p, int v)\n{\n\tint r;\n\t__asm__ __volatile__ (\n\t\t\"stwcx. %2, 0, %3 ; mfcr %0\"\n\t\t: \"=r\"(r), \"=m\"(*p) : \"r\"(v), \"r\"(p) : \"memory\", \"cc\");\n\treturn r & 0x20000000; /* \"bit 2\" of \"cr0\" (backwards bit order) */\n}\n\n#define a_barrier a_barrier\nstatic inline void a_barrier()\n{\n\t__asm__ __volatile__ (\"sync\" : : : \"memory\");\n}\n\n#define a_pre_llsc a_barrier\n\n#define a_post_llsc a_post_llsc\nstatic inline void a_post_llsc()\n{\n\t__asm__ __volatile__ (\"isync\" : : : \"memory\");\n}\n\n#define a_clz_32 a_clz_32\nstatic inline int a_clz_32(uint32_t x)\n{\n\t__asm__ (\"cntlzw %0, %1\" : \"=r\"(x) : \"r\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/arch/powerpc/bits/alltypes.h.in",
    "content": "#define _REDIR_TIME64 1\n#define _Addr int\n#define _Int64 long long\n#define _Reg int\n\n#define __BYTE_ORDER 4321\n#define __LONG_MAX 0x7fffffffL\n\n#ifndef __cplusplus\n#ifdef __WCHAR_TYPE__\nTYPEDEF __WCHAR_TYPE__ wchar_t;\n#else\nTYPEDEF long wchar_t;\n#endif\n#endif\n\nTYPEDEF float float_t;\nTYPEDEF double double_t;\n\nTYPEDEF struct { long long __ll; long double __ld; } max_align_t;\n"
  },
  {
    "path": "user.libc/arch/powerpc/bits/errno.h",
    "content": "#define EPERM            1\n#define ENOENT           2\n#define ESRCH            3\n#define EINTR            4\n#define EIO              5\n#define ENXIO            6\n#define E2BIG            7\n#define ENOEXEC          8\n#define EBADF            9\n#define ECHILD          10\n#define EAGAIN          11\n#define ENOMEM          12\n#define EACCES          13\n#define EFAULT          14\n#define ENOTBLK         15\n#define EBUSY           16\n#define EEXIST          17\n#define EXDEV           18\n#define ENODEV          19\n#define ENOTDIR         20\n#define EISDIR          21\n#define EINVAL          22\n#define ENFILE          23\n#define EMFILE          24\n#define ENOTTY          25\n#define ETXTBSY         26\n#define EFBIG           27\n#define ENOSPC          28\n#define ESPIPE          29\n#define EROFS           30\n#define EMLINK          31\n#define EPIPE           32\n#define EDOM            33\n#define ERANGE          34\n#define EDEADLK         35\n#define ENAMETOOLONG    36\n#define ENOLCK          37\n#define ENOSYS          38\n#define ENOTEMPTY       39\n#define ELOOP           40\n#define EWOULDBLOCK     EAGAIN\n#define ENOMSG          42\n#define EIDRM           43\n#define ECHRNG          44\n#define EL2NSYNC        45\n#define EL3HLT          46\n#define EL3RST          47\n#define ELNRNG          48\n#define EUNATCH         49\n#define ENOCSI          50\n#define EL2HLT          51\n#define EBADE           52\n#define EBADR           53\n#define EXFULL          54\n#define ENOANO          55\n#define EBADRQC         56\n#define EBADSLT         57\n#define EDEADLOCK       58\n#define EBFONT          59\n#define ENOSTR          60\n#define ENODATA         61\n#define ETIME           62\n#define ENOSR           63\n#define ENONET          64\n#define ENOPKG          65\n#define EREMOTE         66\n#define ENOLINK         67\n#define EADV            68\n#define ESRMNT          69\n#define ECOMM           70\n#define EPROTO          71\n#define EMULTIHOP       72\n#define EDOTDOT         73\n#define EBADMSG         74\n#define EOVERFLOW       75\n#define ENOTUNIQ        76\n#define EBADFD          77\n#define EREMCHG         78\n#define ELIBACC         79\n#define ELIBBAD         80\n#define ELIBSCN         81\n#define ELIBMAX         82\n#define ELIBEXEC        83\n#define EILSEQ          84\n#define ERESTART        85\n#define ESTRPIPE        86\n#define EUSERS          87\n#define ENOTSOCK        88\n#define EDESTADDRREQ    89\n#define EMSGSIZE        90\n#define EPROTOTYPE      91\n#define ENOPROTOOPT     92\n#define EPROTONOSUPPORT 93\n#define ESOCKTNOSUPPORT 94\n#define EOPNOTSUPP      95\n#define ENOTSUP         EOPNOTSUPP\n#define EPFNOSUPPORT    96\n#define EAFNOSUPPORT    97\n#define EADDRINUSE      98\n#define EADDRNOTAVAIL   99\n#define ENETDOWN        100\n#define ENETUNREACH     101\n#define ENETRESET       102\n#define ECONNABORTED    103\n#define ECONNRESET      104\n#define ENOBUFS         105\n#define EISCONN         106\n#define ENOTCONN        107\n#define ESHUTDOWN       108\n#define ETOOMANYREFS    109\n#define ETIMEDOUT       110\n#define ECONNREFUSED    111\n#define EHOSTDOWN       112\n#define EHOSTUNREACH    113\n#define EALREADY        114\n#define EINPROGRESS     115\n#define ESTALE          116\n#define EUCLEAN         117\n#define ENOTNAM         118\n#define ENAVAIL         119\n#define EISNAM          120\n#define EREMOTEIO       121\n#define EDQUOT          122\n#define ENOMEDIUM       123\n#define EMEDIUMTYPE     124\n#define ECANCELED       125\n#define ENOKEY          126\n#define EKEYEXPIRED     127\n#define EKEYREVOKED     128\n#define EKEYREJECTED    129\n#define EOWNERDEAD      130\n#define ENOTRECOVERABLE 131\n#define ERFKILL         132\n#define EHWPOISON       133\n"
  },
  {
    "path": "user.libc/arch/powerpc/bits/fcntl.h",
    "content": "#define O_CREAT        0100\n#define O_EXCL         0200\n#define O_NOCTTY       0400\n#define O_TRUNC       01000\n#define O_APPEND      02000\n#define O_NONBLOCK    04000\n#define O_DSYNC      010000\n#define O_SYNC     04010000\n#define O_RSYNC    04010000\n#define O_DIRECTORY  040000\n#define O_NOFOLLOW  0100000\n#define O_CLOEXEC  02000000\n\n#define O_ASYNC      020000\n#define O_DIRECT    0400000\n#define O_LARGEFILE 0200000\n#define O_NOATIME  01000000\n#define O_PATH    010000000\n#define O_TMPFILE 020040000\n#define O_NDELAY O_NONBLOCK\n\n#define F_DUPFD  0\n#define F_GETFD  1\n#define F_SETFD  2\n#define F_GETFL  3\n#define F_SETFL  4\n\n#define F_SETOWN 8\n#define F_GETOWN 9\n#define F_SETSIG 10\n#define F_GETSIG 11\n\n#define F_GETLK 12\n#define F_SETLK 13\n#define F_SETLKW 14\n\n#define F_SETOWN_EX 15\n#define F_GETOWN_EX 16\n\n#define F_GETOWNER_UIDS 17\n"
  },
  {
    "path": "user.libc/arch/powerpc/bits/fenv.h",
    "content": "#ifdef _SOFT_FLOAT\n#define FE_ALL_EXCEPT 0\n#define FE_TONEAREST  0\n#else\n#define FE_TONEAREST\t0\n#define FE_TOWARDZERO\t1\n#define FE_UPWARD\t2\n#define FE_DOWNWARD\t3\n\n#define FE_INEXACT\t0x02000000\n#define FE_DIVBYZERO\t0x04000000\n#define FE_UNDERFLOW\t0x08000000\n#define FE_OVERFLOW\t0x10000000\n#define FE_INVALID\t0x20000000\n\n#define FE_ALL_EXCEPT\t0x3e000000\n\n#ifdef _GNU_SOURCE\n#define FE_INVALID_SNAN\t\t0x01000000\n#define FE_INVALID_ISI\t\t0x00800000\n#define FE_INVALID_IDI\t\t0x00400000\n#define FE_INVALID_ZDZ\t\t0x00200000\n#define FE_INVALID_IMZ\t\t0x00100000\n#define FE_INVALID_COMPARE\t0x00080000\n#define FE_INVALID_SOFTWARE\t0x00000400\n#define FE_INVALID_SQRT\t\t0x00000200\n#define FE_INVALID_INTEGER_CONVERSION\t0x00000100\n\n#define FE_ALL_INVALID\t\t0x01f80700\n#endif\n#endif\n\ntypedef unsigned fexcept_t;\ntypedef double fenv_t;\n\n#define FE_DFL_ENV ((const fenv_t *)-1)\n"
  },
  {
    "path": "user.libc/arch/powerpc/bits/float.h",
    "content": "#define FLT_EVAL_METHOD 0\n\n#define LDBL_TRUE_MIN 4.94065645841246544177e-324L\n#define LDBL_MIN 2.22507385850720138309e-308L\n#define LDBL_MAX 1.79769313486231570815e+308L\n#define LDBL_EPSILON 2.22044604925031308085e-16L\n\n#define LDBL_MANT_DIG 53\n#define LDBL_MIN_EXP (-1021)\n#define LDBL_MAX_EXP 1024\n\n#define LDBL_DIG 15\n#define LDBL_MIN_10_EXP (-307)\n#define LDBL_MAX_10_EXP 308\n\n#define DECIMAL_DIG 17\n"
  },
  {
    "path": "user.libc/arch/powerpc/bits/hwcap.h",
    "content": "#define PPC_FEATURE_32\t\t\t0x80000000\n#define PPC_FEATURE_64\t\t\t0x40000000\n#define PPC_FEATURE_601_INSTR\t\t0x20000000\n#define PPC_FEATURE_HAS_ALTIVEC\t\t0x10000000\n#define PPC_FEATURE_HAS_FPU\t\t0x08000000\n#define PPC_FEATURE_HAS_MMU\t\t0x04000000\n#define PPC_FEATURE_HAS_4xxMAC\t\t0x02000000\n#define PPC_FEATURE_UNIFIED_CACHE\t0x01000000\n#define PPC_FEATURE_HAS_SPE\t\t0x00800000\n#define PPC_FEATURE_HAS_EFP_SINGLE\t0x00400000\n#define PPC_FEATURE_HAS_EFP_DOUBLE\t0x00200000\n#define PPC_FEATURE_NO_TB\t\t0x00100000\n#define PPC_FEATURE_POWER4\t\t0x00080000\n#define PPC_FEATURE_POWER5\t\t0x00040000\n#define PPC_FEATURE_POWER5_PLUS\t\t0x00020000\n#define PPC_FEATURE_CELL\t\t0x00010000\n#define PPC_FEATURE_BOOKE\t\t0x00008000\n#define PPC_FEATURE_SMT\t\t\t0x00004000\n#define PPC_FEATURE_ICACHE_SNOOP\t0x00002000\n#define PPC_FEATURE_ARCH_2_05\t\t0x00001000\n#define PPC_FEATURE_PA6T\t\t0x00000800\n#define PPC_FEATURE_HAS_DFP\t\t0x00000400\n#define PPC_FEATURE_POWER6_EXT\t\t0x00000200\n#define PPC_FEATURE_ARCH_2_06\t\t0x00000100\n#define PPC_FEATURE_HAS_VSX\t\t0x00000080\n#define PPC_FEATURE_PSERIES_PERFMON_COMPAT 0x00000040\n\n#define PPC_FEATURE_TRUE_LE\t\t0x00000002\n#define PPC_FEATURE_PPC_LE\t\t0x00000001\n\n#define PPC_FEATURE2_ARCH_2_07\t\t0x80000000\n#define PPC_FEATURE2_HTM\t\t0x40000000\n#define PPC_FEATURE2_DSCR\t\t0x20000000\n#define PPC_FEATURE2_EBB\t\t0x10000000\n#define PPC_FEATURE2_ISEL\t\t0x08000000\n#define PPC_FEATURE2_TAR\t\t0x04000000\n#define PPC_FEATURE2_VEC_CRYPTO\t\t0x02000000\n#define PPC_FEATURE2_HTM_NOSC\t\t0x01000000\n#define PPC_FEATURE2_ARCH_3_00\t\t0x00800000\n#define PPC_FEATURE2_HAS_IEEE128\t0x00400000\n#define PPC_FEATURE2_DARN\t\t0x00200000\n#define PPC_FEATURE2_SCV\t\t0x00100000\n#define PPC_FEATURE2_HTM_NO_SUSPEND\t0x00080000\n"
  },
  {
    "path": "user.libc/arch/powerpc/bits/ioctl.h",
    "content": "#define _IOC(a,b,c,d) ( ((a)<<29) | ((b)<<8) | (c) | ((d)<<16) )\n#define _IOC_NONE  1U\n#define _IOC_WRITE 4U\n#define _IOC_READ  2U\n\n#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)\n#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c))\n#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c))\n#define _IOWR(a,b,c) _IOC(_IOC_READ|_IOC_WRITE,(a),(b),sizeof(c))\n\n#define FIONCLEX\t_IO('f', 2)\n#define FIOCLEX\t\t_IO('f', 1)\n#define FIOASYNC\t_IOW('f', 125, int)\n#define FIONBIO\t\t_IOW('f', 126, int)\n#define FIONREAD\t_IOR('f', 127, int)\n#define TIOCINQ\t\tFIONREAD\n#define FIOQSIZE\t_IOR('f', 128, char[8])\n#define TIOCGETP\t_IOR('t', 8, char[6])\n#define TIOCSETP\t_IOW('t', 9, char[6])\n#define TIOCSETN\t_IOW('t', 10, char[6])\n\n#define TIOCSETC\t_IOW('t', 17, char[6])\n#define TIOCGETC\t_IOR('t', 18, char[6])\n#define TCGETS\t\t_IOR('t', 19, char[44])\n#define TCSETS\t\t_IOW('t', 20, char[44])\n#define TCSETSW\t\t_IOW('t', 21, char[44])\n#define TCSETSF\t\t_IOW('t', 22, char[44])\n\n#define TCGETA\t\t_IOR('t', 23, char[20])\n#define TCSETA\t\t_IOW('t', 24, char[20])\n#define TCSETAW\t\t_IOW('t', 25, char[20])\n#define TCSETAF\t\t_IOW('t', 28, char[20])\n\n#define TCSBRK\t\t_IO('t', 29)\n#define TCXONC\t\t_IO('t', 30)\n#define TCFLSH\t\t_IO('t', 31)\n\n#define TIOCSWINSZ\t_IOW('t', 103, char[8])\n#define TIOCGWINSZ\t_IOR('t', 104, char[8])\n#define TIOCSTART\t_IO('t', 110)\n#define TIOCSTOP\t_IO('t', 111)\n\n#define TIOCOUTQ\t_IOR('t', 115, int)\n\n#define TIOCGLTC\t_IOR('t', 116, char[6])\n#define TIOCSLTC\t_IOW('t', 117, char[6])\n#define TIOCSPGRP\t_IOW('t', 118, int)\n#define TIOCGPGRP\t_IOR('t', 119, int)\n\n#define TIOCEXCL\t0x540C\n#define TIOCNXCL\t0x540D\n#define TIOCSCTTY\t0x540E\n\n#define TIOCSTI\t\t0x5412\n#define TIOCMGET\t0x5415\n#define TIOCMBIS\t0x5416\n#define TIOCMBIC\t0x5417\n#define TIOCMSET\t0x5418\n#define TIOCM_LE\t0x001\n#define TIOCM_DTR\t0x002\n#define TIOCM_RTS\t0x004\n#define TIOCM_ST\t0x008\n#define TIOCM_SR\t0x010\n#define TIOCM_CTS\t0x020\n#define TIOCM_CAR\t0x040\n#define TIOCM_RNG\t0x080\n#define TIOCM_DSR\t0x100\n#define TIOCM_CD\tTIOCM_CAR\n#define TIOCM_RI\tTIOCM_RNG\n#define TIOCM_OUT1\t0x2000\n#define TIOCM_OUT2\t0x4000\n#define TIOCM_LOOP\t0x8000\n\n#define TIOCGSOFTCAR\t0x5419\n#define TIOCSSOFTCAR\t0x541A\n#define TIOCLINUX\t0x541C\n#define TIOCCONS\t0x541D\n#define TIOCGSERIAL\t0x541E\n#define TIOCSSERIAL\t0x541F\n#define TIOCPKT\t0x5420\n\n#define TIOCNOTTY\t0x5422\n#define TIOCSETD\t0x5423\n#define TIOCGETD\t0x5424\n#define TCSBRKP\t\t0x5425\n#define TIOCSBRK\t0x5427\n#define TIOCCBRK\t0x5428\n#define TIOCGSID\t0x5429\n#define TIOCGRS485\t0x542e\n#define TIOCSRS485\t0x542f\n#define TIOCGPTN\t_IOR('T',0x30, unsigned int)\n#define TIOCSPTLCK\t_IOW('T',0x31, int)\n#define TIOCGDEV\t_IOR('T',0x32, unsigned int)\n#define TIOCSIG\t\t_IOW('T',0x36, int)\n#define TIOCVHANGUP\t0x5437\n#define TIOCGPKT\t_IOR('T', 0x38, int)\n#define TIOCGPTLCK\t_IOR('T', 0x39, int)\n#define TIOCGEXCL\t_IOR('T', 0x40, int)\n#define TIOCGPTPEER\t_IO('T', 0x41)\n\n#define TIOCSERCONFIG\t0x5453\n#define TIOCSERGWILD\t0x5454\n#define TIOCSERSWILD\t0x5455\n#define TIOCGLCKTRMIOS\t0x5456\n#define TIOCSLCKTRMIOS\t0x5457\n#define TIOCSERGSTRUCT\t0x5458\n#define TIOCSERGETLSR\t0x5459\n#define TIOCSERGETMULTI\t0x545A\n#define TIOCSERSETMULTI\t0x545B\n\n#define TIOCMIWAIT\t0x545C\n#define TIOCGICOUNT\t0x545D\n\n#define FIOSETOWN       0x8901\n#define SIOCSPGRP       0x8902\n#define FIOGETOWN       0x8903\n#define SIOCGPGRP       0x8904\n#define SIOCATMARK      0x8905\n#define SIOCGSTAMP      _IOR(0x89, 6, char[16])\n#define SIOCGSTAMPNS    _IOR(0x89, 7, char[16])\n"
  },
  {
    "path": "user.libc/arch/powerpc/bits/ipc.h",
    "content": "struct ipc_perm {\n\tkey_t __ipc_perm_key;\n\tuid_t uid;\n\tgid_t gid;\n\tuid_t cuid;\n\tgid_t cgid;\n\tmode_t mode;\n\tint __ipc_perm_seq;\n\tint __pad1;\n\tlong long __pad2;\n\tlong long __pad3;\n};\n"
  },
  {
    "path": "user.libc/arch/powerpc/bits/ipcstat.h",
    "content": "#define IPC_STAT 0x102\n"
  },
  {
    "path": "user.libc/arch/powerpc/bits/mman.h",
    "content": "#define PROT_SAO       0x10\n\n#undef MAP_NORESERVE\n#define MAP_NORESERVE   0x40\n#undef MAP_LOCKED\n#define MAP_LOCKED\t0x80\n\n#undef MCL_CURRENT\n#define MCL_CURRENT     0x2000\n#undef MCL_FUTURE\n#define MCL_FUTURE      0x4000\n#undef MCL_ONFAULT\n#define MCL_ONFAULT     0x8000\n"
  },
  {
    "path": "user.libc/arch/powerpc/bits/msg.h",
    "content": "struct msqid_ds {\n\tstruct ipc_perm msg_perm;\n\tunsigned long __msg_stime_hi;\n\tunsigned long __msg_stime_lo;\n\tunsigned long __msg_rtime_hi;\n\tunsigned long __msg_rtime_lo;\n\tunsigned long __msg_ctime_hi;\n\tunsigned long __msg_ctime_lo;\n\tunsigned long msg_cbytes;\n\tmsgqnum_t msg_qnum;\n\tmsglen_t msg_qbytes;\n\tpid_t msg_lspid;\n\tpid_t msg_lrpid;\n\tunsigned long __unused[2];\n\ttime_t msg_stime;\n\ttime_t msg_rtime;\n\ttime_t msg_ctime;\n};\n"
  },
  {
    "path": "user.libc/arch/powerpc/bits/posix.h",
    "content": "#define _POSIX_V6_ILP32_OFFBIG  1\n#define _POSIX_V7_ILP32_OFFBIG  1\n"
  },
  {
    "path": "user.libc/arch/powerpc/bits/ptrace.h",
    "content": "#define PTRACE_GETVRREGS\t0x12\n#define PTRACE_SETVRREGS\t0x13\n#define PTRACE_GETEVRREGS\t0x14\n#define PTRACE_SETEVRREGS\t0x15\n#define PTRACE_GETREGS64\t0x16\n#define PTRACE_SETREGS64\t0x17\n#define PTRACE_GET_DEBUGREG\t0x19\n#define PTRACE_SET_DEBUGREG\t0x1a\n#define PTRACE_GETVSRREGS\t0x1b\n#define PTRACE_SETVSRREGS\t0x1c\n#define PTRACE_SYSEMU\t\t0x1d\n#define PTRACE_SYSEMU_SINGLESTEP\t0x1e\n#define PTRACE_SINGLEBLOCK\t0x100\n\n#define PT_GETVRREGS PTRACE_GETVRREGS\n#define PT_SETVRREGS PTRACE_SETVRREGS\n#define PT_GETEVRREGS PTRACE_GETEVRREGS\n#define PT_SETEVRREGS PTRACE_SETEVRREGS\n#define PT_GETREGS64 PTRACE_GETREGS64\n#define PT_SETREGS64 PTRACE_SETREGS64\n#define PT_GET_DEBUGREG PTRACE_GET_DEBUGREG\n#define PT_SET_DEBUGREG PTRACE_SET_DEBUGREG\n#define PT_GETVSRREGS PTRACE_GETVSRREGS\n#define PT_SETVSRREGS PTRACE_SETVSRREGS\n#define PT_STEPBLOCK PTRACE_SINGLEBLOCK\n"
  },
  {
    "path": "user.libc/arch/powerpc/bits/reg.h",
    "content": "#undef __WORDSIZE\n#define __WORDSIZE 32\n/* FIXME */\n"
  },
  {
    "path": "user.libc/arch/powerpc/bits/sem.h",
    "content": "struct semid_ds {\n\tstruct ipc_perm sem_perm;\n\tunsigned long __sem_otime_hi;\n\tunsigned long __sem_otime_lo;\n\tunsigned long __sem_ctime_hi;\n\tunsigned long __sem_ctime_lo;\n\tunsigned short __sem_nsems_pad, sem_nsems;\n\tlong __unused3;\n\tlong __unused4;\n\ttime_t sem_otime;\n\ttime_t sem_ctime;\n};\n"
  },
  {
    "path": "user.libc/arch/powerpc/bits/setjmp.h",
    "content": "typedef unsigned long long __jmp_buf[56];\n"
  },
  {
    "path": "user.libc/arch/powerpc/bits/shm.h",
    "content": "#define SHMLBA 4096\n\nstruct shmid_ds {\n\tstruct ipc_perm shm_perm;\n\tunsigned long __shm_atime_hi;\n\tunsigned long __shm_atime_lo;\n\tunsigned long __shm_dtime_hi;\n\tunsigned long __shm_dtime_lo;\n\tunsigned long __shm_ctime_hi;\n\tunsigned long __shm_ctime_lo;\n\tsize_t shm_segsz;\n\tpid_t shm_cpid;\n\tpid_t shm_lpid;\n\tunsigned long shm_nattch;\n\tunsigned long __pad1;\n\tunsigned long __pad2;\n\ttime_t shm_atime;\n\ttime_t shm_dtime;\n\ttime_t shm_ctime;\n};\n\nstruct shminfo {\n\tunsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];\n};\n\nstruct shm_info {\n\tint __used_ids;\n\tunsigned long shm_tot, shm_rss, shm_swp;\n\tunsigned long __swap_attempts, __swap_successes;\n};\n"
  },
  {
    "path": "user.libc/arch/powerpc/bits/signal.h",
    "content": "#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define MINSIGSTKSZ 4096\n#define SIGSTKSZ 10240\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n\ntypedef unsigned long greg_t, gregset_t[48];\n\ntypedef struct {\n\tdouble fpregs[32];\n\tdouble fpscr;\n\tunsigned _pad[2];\n} fpregset_t;\n\ntypedef struct {\n\tunsigned vrregs[32][4];\n\tunsigned vrsave;\n\tunsigned _pad[2];\n\tunsigned vscr;\n} vrregset_t;\n\nstruct sigcontext {\n\tunsigned long _unused[4];\n\tint signal;\n\tunsigned long handler;\n\tunsigned long oldmask;\n\tstruct pt_regs *regs;\n};\n\ntypedef struct {\n\tgregset_t gregs;\n\tfpregset_t fpregs;\n\tvrregset_t vrregs\n#ifdef __GNUC__\n\t__attribute__((__aligned__(16)))\n#endif\n\t;\n} mcontext_t;\n\n#else\n\ntypedef struct {\n\tlong __regs[48+68+4*32+4]\n#ifdef __GNUC__\n\t__attribute__((__aligned__(16)))\n#endif\n\t;\n} mcontext_t;\n\n#endif\n\nstruct sigaltstack {\n\tvoid *ss_sp;\n\tint ss_flags;\n\tsize_t ss_size;\n};\n\ntypedef struct __ucontext {\n\tunsigned long uc_flags;\n\tstruct __ucontext *uc_link;\n\tstack_t uc_stack;\n\tint uc_pad[7];\n\tmcontext_t *uc_regs;\n\tsigset_t uc_sigmask;\n        int             uc_pad2[3];\n\tmcontext_t uc_mcontext;\n} ucontext_t;\n\n#define SA_NOCLDSTOP  1U\n#define SA_NOCLDWAIT  2U\n#define SA_SIGINFO    4U\n#define SA_ONSTACK    0x08000000U\n#define SA_RESTART    0x10000000U\n#define SA_NODEFER    0x40000000U\n#define SA_RESETHAND  0x80000000U\n#define SA_RESTORER   0x04000000U\n\n#endif\n\n#define SIGHUP    1\n#define SIGINT    2\n#define SIGQUIT   3\n#define SIGILL    4\n#define SIGTRAP   5\n#define SIGABRT   6\n#define SIGIOT    SIGABRT\n#define SIGBUS    7\n#define SIGFPE    8\n#define SIGKILL   9\n#define SIGUSR1   10\n#define SIGSEGV   11\n#define SIGUSR2   12\n#define SIGPIPE   13\n#define SIGALRM   14\n#define SIGTERM   15\n#define SIGSTKFLT 16\n#define SIGCHLD   17\n#define SIGCONT   18\n#define SIGSTOP   19\n#define SIGTSTP   20\n#define SIGTTIN   21\n#define SIGTTOU   22\n#define SIGURG    23\n#define SIGXCPU   24\n#define SIGXFSZ   25\n#define SIGVTALRM 26\n#define SIGPROF   27\n#define SIGWINCH  28\n#define SIGIO     29\n#define SIGPOLL   29\n#define SIGPWR    30\n#define SIGSYS    31\n#define SIGUNUSED SIGSYS\n\n#define _NSIG 65\n"
  },
  {
    "path": "user.libc/arch/powerpc/bits/socket.h",
    "content": "#define SO_DEBUG        1\n#define SO_REUSEADDR    2\n#define SO_TYPE         3\n#define SO_ERROR        4\n#define SO_DONTROUTE    5\n#define SO_BROADCAST    6\n#define SO_SNDBUF       7\n#define SO_RCVBUF       8\n#define SO_KEEPALIVE    9\n#define SO_OOBINLINE    10\n#define SO_NO_CHECK     11\n#define SO_PRIORITY     12\n#define SO_LINGER       13\n#define SO_BSDCOMPAT    14\n#define SO_REUSEPORT    15\n#define SO_RCVLOWAT     16\n#define SO_SNDLOWAT     17\n#define SO_PASSCRED     20\n#define SO_PEERCRED     21\n#define SO_ACCEPTCONN   30\n#define SO_PEERSEC      31\n#define SO_SNDBUFFORCE  32\n#define SO_RCVBUFFORCE  33\n#define SO_PROTOCOL     38\n#define SO_DOMAIN       39\n"
  },
  {
    "path": "user.libc/arch/powerpc/bits/stat.h",
    "content": "/* copied from kernel definition, but with padding replaced\n * by the corresponding correctly-sized userspace types. */\n\nstruct stat {\n\tdev_t st_dev;\n\tino_t st_ino;\n\tmode_t st_mode;\n\tnlink_t st_nlink;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tdev_t st_rdev;\n\tshort __st_rdev_padding;\n\toff_t st_size;\n\tblksize_t st_blksize;\n\tblkcnt_t st_blocks;\n\tstruct {\n\t\tlong tv_sec;\n\t\tlong tv_nsec;\n\t} __st_atim32, __st_mtim32, __st_ctim32;\n\tunsigned __unused[2];\n\tstruct timespec st_atim;\n\tstruct timespec st_mtim;\n\tstruct timespec st_ctim;\n};\n"
  },
  {
    "path": "user.libc/arch/powerpc/bits/stdint.h",
    "content": "typedef int32_t int_fast16_t;\ntypedef int32_t int_fast32_t;\ntypedef uint32_t uint_fast16_t;\ntypedef uint32_t uint_fast32_t;\n\n#define INT_FAST16_MIN  INT32_MIN\n#define INT_FAST32_MIN  INT32_MIN\n\n#define INT_FAST16_MAX  INT32_MAX\n#define INT_FAST32_MAX  INT32_MAX\n\n#define UINT_FAST16_MAX UINT32_MAX\n#define UINT_FAST32_MAX UINT32_MAX\n\n#define INTPTR_MIN      INT32_MIN\n#define INTPTR_MAX      INT32_MAX\n#define UINTPTR_MAX     UINT32_MAX\n#define PTRDIFF_MIN     INT32_MIN\n#define PTRDIFF_MAX     INT32_MAX\n#define SIZE_MAX        UINT32_MAX\n"
  },
  {
    "path": "user.libc/arch/powerpc/bits/syscall.h.in",
    "content": "#define __NR_restart_syscall          0\n#define __NR_exit                     1\n#define __NR_fork                     2\n#define __NR_read                     3\n#define __NR_write                    4\n#define __NR_open                     5\n#define __NR_close                    6\n#define __NR_waitpid                  7\n#define __NR_creat                    8\n#define __NR_link                     9\n#define __NR_unlink                  10\n#define __NR_execve                  11\n#define __NR_chdir                   12\n#define __NR_time                    13\n#define __NR_mknod                   14\n#define __NR_chmod                   15\n#define __NR_lchown                  16\n#define __NR_break                   17\n#define __NR_oldstat                 18\n#define __NR_lseek                   19\n#define __NR_getpid                  20\n#define __NR_mount                   21\n#define __NR_umount                  22\n#define __NR_setuid                  23\n#define __NR_getuid                  24\n#define __NR_stime                   25\n#define __NR_ptrace                  26\n#define __NR_alarm                   27\n#define __NR_oldfstat                28\n#define __NR_pause                   29\n#define __NR_utime                   30\n#define __NR_stty                    31\n#define __NR_gtty                    32\n#define __NR_access                  33\n#define __NR_nice                    34\n#define __NR_ftime                   35\n#define __NR_sync                    36\n#define __NR_kill                    37\n#define __NR_rename                  38\n#define __NR_mkdir                   39\n#define __NR_rmdir                   40\n#define __NR_dup                     41\n#define __NR_pipe                    42\n#define __NR_times                   43\n#define __NR_prof                    44\n#define __NR_brk                     45\n#define __NR_setgid                  46\n#define __NR_getgid                  47\n#define __NR_signal                  48\n#define __NR_geteuid                 49\n#define __NR_getegid                 50\n#define __NR_acct                    51\n#define __NR_umount2                 52\n#define __NR_lock                    53\n#define __NR_ioctl                   54\n#define __NR_fcntl                   55\n#define __NR_mpx                     56\n#define __NR_setpgid                 57\n#define __NR_ulimit                  58\n#define __NR_oldolduname             59\n#define __NR_umask                   60\n#define __NR_chroot                  61\n#define __NR_ustat                   62\n#define __NR_dup2                    63\n#define __NR_getppid                 64\n#define __NR_getpgrp                 65\n#define __NR_setsid                  66\n#define __NR_sigaction               67\n#define __NR_sgetmask                68\n#define __NR_ssetmask                69\n#define __NR_setreuid                70\n#define __NR_setregid                71\n#define __NR_sigsuspend              72\n#define __NR_sigpending              73\n#define __NR_sethostname             74\n#define __NR_setrlimit               75\n#define __NR_getrlimit               76\n#define __NR_getrusage               77\n#define __NR_gettimeofday_time32            78\n#define __NR_settimeofday_time32            79\n#define __NR_getgroups               80\n#define __NR_setgroups               81\n#define __NR_select                  82\n#define __NR_symlink                 83\n#define __NR_oldlstat                84\n#define __NR_readlink                85\n#define __NR_uselib                  86\n#define __NR_swapon                  87\n#define __NR_reboot                  88\n#define __NR_readdir                 89\n#define __NR_mmap                    90\n#define __NR_munmap                  91\n#define __NR_truncate                92\n#define __NR_ftruncate               93\n#define __NR_fchmod                  94\n#define __NR_fchown                  95\n#define __NR_getpriority             96\n#define __NR_setpriority             97\n#define __NR_profil                  98\n#define __NR_statfs                  99\n#define __NR_fstatfs                100\n#define __NR_ioperm                 101\n#define __NR_socketcall             102\n#define __NR_syslog                 103\n#define __NR_setitimer              104\n#define __NR_getitimer              105\n#define __NR_stat                   106\n#define __NR_lstat                  107\n#define __NR_fstat                  108\n#define __NR_olduname               109\n#define __NR_iopl                   110\n#define __NR_vhangup                111\n#define __NR_idle                   112\n#define __NR_vm86                   113\n#define __NR_wait4                  114\n#define __NR_swapoff                115\n#define __NR_sysinfo                116\n#define __NR_ipc                    117\n#define __NR_fsync                  118\n#define __NR_sigreturn              119\n#define __NR_clone                  120\n#define __NR_setdomainname          121\n#define __NR_uname                  122\n#define __NR_modify_ldt             123\n#define __NR_adjtimex               124\n#define __NR_mprotect               125\n#define __NR_sigprocmask            126\n#define __NR_create_module          127\n#define __NR_init_module            128\n#define __NR_delete_module          129\n#define __NR_get_kernel_syms        130\n#define __NR_quotactl               131\n#define __NR_getpgid                132\n#define __NR_fchdir                 133\n#define __NR_bdflush                134\n#define __NR_sysfs                  135\n#define __NR_personality            136\n#define __NR_afs_syscall            137\n#define __NR_setfsuid               138\n#define __NR_setfsgid               139\n#define __NR__llseek                140\n#define __NR_getdents               141\n#define __NR__newselect             142\n#define __NR_flock                  143\n#define __NR_msync                  144\n#define __NR_readv                  145\n#define __NR_writev                 146\n#define __NR_getsid                 147\n#define __NR_fdatasync              148\n#define __NR__sysctl                149\n#define __NR_mlock                  150\n#define __NR_munlock                151\n#define __NR_mlockall               152\n#define __NR_munlockall             153\n#define __NR_sched_setparam         154\n#define __NR_sched_getparam         155\n#define __NR_sched_setscheduler     156\n#define __NR_sched_getscheduler     157\n#define __NR_sched_yield            158\n#define __NR_sched_get_priority_max 159\n#define __NR_sched_get_priority_min 160\n#define __NR_sched_rr_get_interval  161\n#define __NR_nanosleep              162\n#define __NR_mremap                 163\n#define __NR_setresuid              164\n#define __NR_getresuid              165\n#define __NR_query_module           166\n#define __NR_poll                   167\n#define __NR_nfsservctl             168\n#define __NR_setresgid              169\n#define __NR_getresgid              170\n#define __NR_prctl                  171\n#define __NR_rt_sigreturn           172\n#define __NR_rt_sigaction           173\n#define __NR_rt_sigprocmask         174\n#define __NR_rt_sigpending          175\n#define __NR_rt_sigtimedwait        176\n#define __NR_rt_sigqueueinfo        177\n#define __NR_rt_sigsuspend          178\n#define __NR_pread64                179\n#define __NR_pwrite64               180\n#define __NR_chown                  181\n#define __NR_getcwd                 182\n#define __NR_capget                 183\n#define __NR_capset                 184\n#define __NR_sigaltstack            185\n#define __NR_sendfile               186\n#define __NR_getpmsg                187\n#define __NR_putpmsg                188\n#define __NR_vfork                  189\n#define __NR_ugetrlimit             190\n#define __NR_readahead              191\n#define __NR_mmap2                  192\n#define __NR_truncate64             193\n#define __NR_ftruncate64            194\n#define __NR_stat64                 195\n#define __NR_lstat64                196\n#define __NR_fstat64                197\n#define __NR_pciconfig_read         198\n#define __NR_pciconfig_write        199\n#define __NR_pciconfig_iobase       200\n#define __NR_multiplexer            201\n#define __NR_getdents64             202\n#define __NR_pivot_root             203\n#define __NR_fcntl64                204\n#define __NR_madvise                205\n#define __NR_mincore                206\n#define __NR_gettid                 207\n#define __NR_tkill                  208\n#define __NR_setxattr               209\n#define __NR_lsetxattr              210\n#define __NR_fsetxattr              211\n#define __NR_getxattr               212\n#define __NR_lgetxattr              213\n#define __NR_fgetxattr              214\n#define __NR_listxattr              215\n#define __NR_llistxattr             216\n#define __NR_flistxattr             217\n#define __NR_removexattr            218\n#define __NR_lremovexattr           219\n#define __NR_fremovexattr           220\n#define __NR_futex                  221\n#define __NR_sched_setaffinity      222\n#define __NR_sched_getaffinity      223\n#define __NR_tuxcall                225\n#define __NR_sendfile64             226\n#define __NR_io_setup               227\n#define __NR_io_destroy             228\n#define __NR_io_getevents           229\n#define __NR_io_submit              230\n#define __NR_io_cancel              231\n#define __NR_set_tid_address        232\n#define __NR_fadvise64              233\n#define __NR_exit_group             234\n#define __NR_lookup_dcookie         235\n#define __NR_epoll_create           236\n#define __NR_epoll_ctl              237\n#define __NR_epoll_wait             238\n#define __NR_remap_file_pages       239\n#define __NR_timer_create           240\n#define __NR_timer_settime32          241\n#define __NR_timer_gettime32          242\n#define __NR_timer_getoverrun       243\n#define __NR_timer_delete           244\n#define __NR_clock_settime32          245\n#define __NR_clock_gettime32          246\n#define __NR_clock_getres_time32           247\n#define __NR_clock_nanosleep_time32        248\n#define __NR_swapcontext            249\n#define __NR_tgkill                 250\n#define __NR_utimes                 251\n#define __NR_statfs64               252\n#define __NR_fstatfs64              253\n#define __NR_fadvise64_64           254\n#define __NR_rtas\t\t255\n#define __NR_sys_debug_setcontext 256\n#define __NR_migrate_pages\t258\n#define __NR_mbind\t\t259\n#define __NR_get_mempolicy\t260\n#define __NR_set_mempolicy\t261\n#define __NR_mq_open\t\t262\n#define __NR_mq_unlink\t\t263\n#define __NR_mq_timedsend\t264\n#define __NR_mq_timedreceive\t265\n#define __NR_mq_notify\t\t266\n#define __NR_mq_getsetattr\t267\n#define __NR_kexec_load\t\t268\n#define __NR_add_key\t\t269\n#define __NR_request_key\t270\n#define __NR_keyctl\t\t271\n#define __NR_waitid\t\t272\n#define __NR_ioprio_set\t\t273\n#define __NR_ioprio_get\t\t274\n#define __NR_inotify_init\t275\n#define __NR_inotify_add_watch\t276\n#define __NR_inotify_rm_watch\t277\n#define __NR_spu_run\t\t278\n#define __NR_spu_create\t\t279\n#define __NR_pselect6\t\t280\n#define __NR_ppoll\t\t281\n#define __NR_unshare\t\t282\n#define __NR_splice\t\t283\n#define __NR_tee\t\t284\n#define __NR_vmsplice\t\t285\n#define __NR_openat\t\t286\n#define __NR_mkdirat\t\t287\n#define __NR_mknodat\t\t288\n#define __NR_fchownat\t\t289\n#define __NR_futimesat\t\t290\n#define __NR_fstatat64\t\t291\n#define __NR_unlinkat\t\t292\n#define __NR_renameat\t\t293\n#define __NR_linkat\t\t294\n#define __NR_symlinkat\t\t295\n#define __NR_readlinkat\t\t296\n#define __NR_fchmodat\t\t297\n#define __NR_faccessat\t\t298\n#define __NR_get_robust_list\t299\n#define __NR_set_robust_list\t300\n#define __NR_move_pages\t\t301\n#define __NR_getcpu\t\t302\n#define __NR_epoll_pwait\t303\n#define __NR_utimensat\t\t304\n#define __NR_signalfd\t\t305\n#define __NR_timerfd_create     306\n#define __NR_eventfd\t\t307\n#define __NR_sync_file_range2\t308\n#define __NR_fallocate\t\t309\n#define __NR_subpage_prot\t\t310\n#define __NR_timerfd_settime32\t311\n#define __NR_timerfd_gettime32\t312\n#define __NR_signalfd4\t\t313\n#define __NR_eventfd2\t\t314\n#define __NR_epoll_create1\t315\n#define __NR_dup3\t\t\t316\n#define __NR_pipe2\t\t317\n#define __NR_inotify_init1\t318\n#define __NR_perf_event_open       319\n#define __NR_preadv                320\n#define __NR_pwritev               321\n#define __NR_rt_tgsigqueueinfo     322\n#define __NR_fanotify_init         323\n#define __NR_fanotify_mark         324\n#define __NR_prlimit64             325\n#define __NR_socket                326\n#define __NR_bind                  327\n#define __NR_connect               328\n#define __NR_listen                329\n#define __NR_accept                330\n#define __NR_getsockname           331\n#define __NR_getpeername           332\n#define __NR_socketpair            333\n#define __NR_send                  334\n#define __NR_sendto                335\n#define __NR_recv                  336\n#define __NR_recvfrom              337\n#define __NR_shutdown              338\n#define __NR_setsockopt            339\n#define __NR_getsockopt            340\n#define __NR_sendmsg               341\n#define __NR_recvmsg               342\n#define __NR_recvmmsg              343\n#define __NR_accept4               344\n#define __NR_name_to_handle_at     345\n#define __NR_open_by_handle_at     346\n#define __NR_clock_adjtime         347\n#define __NR_syncfs                348\n#define __NR_sendmmsg              349\n#define __NR_setns                 350\n#define __NR_process_vm_readv      351\n#define __NR_process_vm_writev     352\n#define __NR_finit_module          353\n#define __NR_kcmp                  354\n#define __NR_sched_setattr         355\n#define __NR_sched_getattr         356\n#define __NR_renameat2             357\n#define __NR_seccomp               358\n#define __NR_getrandom             359\n#define __NR_memfd_create          360\n#define __NR_bpf                   361\n#define __NR_execveat              362\n#define __NR_switch_endian         363\n#define __NR_userfaultfd           364\n#define __NR_membarrier            365\n#define __NR_mlock2                378\n#define __NR_copy_file_range       379\n#define __NR_preadv2               380\n#define __NR_pwritev2              381\n#define __NR_kexec_file_load       382\n#define __NR_statx                 383\n#define __NR_pkey_alloc            384\n#define __NR_pkey_free             385\n#define __NR_pkey_mprotect         386\n#define __NR_rseq                  387\n#define __NR_io_pgetevents         388\n#define __NR_semget                393\n#define __NR_semctl                394\n#define __NR_shmget                395\n#define __NR_shmctl                396\n#define __NR_shmat                 397\n#define __NR_shmdt                 398\n#define __NR_msgget                399\n#define __NR_msgsnd                400\n#define __NR_msgrcv                401\n#define __NR_msgctl                402\n#define __NR_clock_gettime64       403\n#define __NR_clock_settime64       404\n#define __NR_clock_adjtime64       405\n#define __NR_clock_getres_time64   406\n#define __NR_clock_nanosleep_time64 407\n#define __NR_timer_gettime64       408\n#define __NR_timer_settime64       409\n#define __NR_timerfd_gettime64     410\n#define __NR_timerfd_settime64     411\n#define __NR_utimensat_time64      412\n#define __NR_pselect6_time64       413\n#define __NR_ppoll_time64          414\n#define __NR_io_pgetevents_time64  416\n#define __NR_recvmmsg_time64       417\n#define __NR_mq_timedsend_time64   418\n#define __NR_mq_timedreceive_time64 419\n#define __NR_semtimedop_time64     420\n#define __NR_rt_sigtimedwait_time64 421\n#define __NR_futex_time64          422\n#define __NR_sched_rr_get_interval_time64 423\n#define __NR_pidfd_send_signal     424\n#define __NR_io_uring_setup        425\n#define __NR_io_uring_enter        426\n#define __NR_io_uring_register     427\n#define __NR_open_tree\t\t428\n#define __NR_move_mount\t\t429\n#define __NR_fsopen\t\t430\n#define __NR_fsconfig\t\t431\n#define __NR_fsmount\t\t432\n#define __NR_fspick\t\t433\n#define __NR_pidfd_open\t\t434\n#define __NR_clone3\t\t435\n#define __NR_close_range\t436\n#define __NR_openat2\t\t437\n#define __NR_pidfd_getfd\t438\n#define __NR_faccessat2\t\t439\n\n"
  },
  {
    "path": "user.libc/arch/powerpc/bits/termios.h",
    "content": "#undef NCCS\n#define NCCS 19\nstruct termios {\n\ttcflag_t c_iflag;\n\ttcflag_t c_oflag;\n\ttcflag_t c_cflag;\n\ttcflag_t c_lflag;\n\tcc_t c_cc[NCCS];\n\tcc_t c_line;\n\tspeed_t __c_ispeed;\n\tspeed_t __c_ospeed;\n};\n\n#define VINTR     0\n#define VQUIT     1\n#define VERASE    2\n#define VKILL     3\n#define VEOF      4\n#define VMIN      5\n#define VEOL      6\n#define VTIME     7\n#define VEOL2     8\n#define VSWTC     9\n#define VWERASE  10\n#define VREPRINT 11\n#define VSUSP    12\n#define VSTART   13\n#define VSTOP    14\n#define VLNEXT   15\n#define VDISCARD 16\n\n#define IGNBRK  0000001\n#define BRKINT  0000002\n#define IGNPAR  0000004\n#define PARMRK  0000010\n#define INPCK   0000020\n#define ISTRIP  0000040\n#define INLCR   0000100\n#define IGNCR   0000200\n#define ICRNL   0000400\n#define IXON    0001000\n#define IXOFF   0002000\n#define IXANY   0004000\n#define IUCLC   0010000\n#define IMAXBEL 0020000\n#define IUTF8   0040000\n\n#define OPOST  0000001\n#define ONLCR  0000002\n#define OLCUC  0000004\n#define OCRNL  0000010\n#define ONOCR  0000020\n#define ONLRET 0000040\n#define OFILL  0000100\n#define OFDEL  0000200\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_XOPEN_SOURCE)\n#define NLDLY  0001400\n#define NL0    0000000\n#define NL1    0000400\n#define NL2    0001000\n#define NL3    0001400\n#define TABDLY 0006000\n#define TAB0   0000000\n#define TAB1   0002000\n#define TAB2   0004000\n#define TAB3   0006000\n#define CRDLY  0030000\n#define CR0    0000000\n#define CR1    0010000\n#define CR2    0020000\n#define CR3    0030000\n#define FFDLY  0040000\n#define FF0    0000000\n#define FF1    0040000\n#define BSDLY  0100000\n#define BS0    0000000\n#define BS1    0100000\n#endif\n\n#define VTDLY  0200000\n#define VT0    0000000\n#define VT1    0200000\n\n#define B0       0000000\n#define B50      0000001\n#define B75      0000002\n#define B110     0000003\n#define B134     0000004\n#define B150     0000005\n#define B200     0000006\n#define B300     0000007\n#define B600     0000010\n#define B1200    0000011\n#define B1800    0000012\n#define B2400    0000013\n#define B4800    0000014\n#define B9600    0000015\n#define B19200   0000016\n#define B38400   0000017\n\n#define B57600   00020\n#define B115200  00021\n#define B230400  00022\n#define B460800  00023\n#define B500000  00024\n#define B576000  00025\n#define B921600  00026\n#define B1000000 00027\n#define B1152000 00030\n#define B1500000 00031\n#define B2000000 00032\n#define B2500000 00033\n#define B3000000 00034\n#define B3500000 00035\n#define B4000000 00036\n\n#define CSIZE  00001400\n#define CS5    00000000\n#define CS6    00000400\n#define CS7    00001000\n#define CS8    00001400\n#define CSTOPB 00002000\n#define CREAD  00004000\n#define PARENB 00010000\n#define PARODD 00020000\n#define HUPCL  00040000\n#define CLOCAL 00100000\n\n#define ECHOE   0x00000002\n#define ECHOK   0x00000004\n#define ECHO    0x00000008\n#define ECHONL  0x00000010\n#define ISIG    0x00000080\n#define ICANON  0x00000100\n#define IEXTEN  0x00000400\n#define TOSTOP  0x00400000\n#define NOFLSH  0x80000000\n\n#define TCOOFF 0\n#define TCOON  1\n#define TCIOFF 2\n#define TCION  3\n\n#define TCIFLUSH  0\n#define TCOFLUSH  1\n#define TCIOFLUSH 2\n\n#define TCSANOW   0\n#define TCSADRAIN 1\n#define TCSAFLUSH 2\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define EXTA    0000016\n#define EXTB    0000017\n#define CBAUD   00377\n#define CBAUDEX 0000020\n#define CIBAUD  077600000\n#define CMSPAR  010000000000\n#define CRTSCTS 020000000000\n\n#define XCASE   0x00004000\n#define ECHOCTL 0x00000040\n#define ECHOPRT 0x00000020\n#define ECHOKE  0x00000001\n#define FLUSHO  0x00800000\n#define PENDIN  0x20000000\n#define EXTPROC 0x10000000\n\n#define XTABS   00006000\n#define TIOCSER_TEMT 1\n#endif\n"
  },
  {
    "path": "user.libc/arch/powerpc/bits/user.h",
    "content": "struct user {\n\tstruct {\n\t\tunsigned long gpr[32], nip, msr, orig_gpr3, ctr, link, xer, ccr, mq;\n\t\tunsigned long trap, dar, dsisr, result;\n\t} regs;\n\tunsigned long u_tsize, u_dsize, u_ssize;\n\tunsigned long start_code, start_data, start_stack;\n\tlong signal;\n\tvoid *u_ar0;\n\tunsigned long magic;\n\tchar u_comm[32];\n};\n\n#define ELF_NGREG 48\n#define ELF_NFPREG 33\n#define ELF_NVRREG 33\ntypedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG];\ntypedef double elf_fpreg_t, elf_fpregset_t[ELF_NFPREG];\ntypedef struct { unsigned u[4]; }\n#ifdef __GNUC__\n__attribute__((__aligned__(16)))\n#endif\n\telf_vrreg_t, elf_vrregset_t[ELF_NVRREG];\n"
  },
  {
    "path": "user.libc/arch/powerpc/crt_arch.h",
    "content": "__asm__(\n\".text \\n\"\n\".global \" START \" \\n\"\n\".type   \" START \", %function \\n\"\nSTART \": \\n\"\n\"\tbl 1f \\n\"\n\".weak _DYNAMIC \\n\"\n\".hidden _DYNAMIC \\n\"\n\"\t.long _DYNAMIC-. \\n\"\n\"1:\tmflr 4 \\n\"\n\"\tlwz 3, 0(4) \\n\"\n\"\tadd 4, 3, 4 \\n\"\n\"\tmr 3, 1 \\n\"\n\"\tclrrwi 1, 1, 4 \\n\"\n\"\tli 0, 0 \\n\"\n\"\tstwu 1, -16(1) \\n\"\n\"\tmtlr 0 \\n\"\n\"\tstw 0, 0(1) \\n\"\n\"\tbl \" START \"_c \\n\"\n);\n"
  },
  {
    "path": "user.libc/arch/powerpc/kstat.h",
    "content": "struct kstat {\n\tdev_t st_dev;\n\tino_t st_ino;\n\tmode_t st_mode;\n\tnlink_t st_nlink;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tdev_t st_rdev;\n\tshort __st_rdev_padding;\n\toff_t st_size;\n\tblksize_t st_blksize;\n\tblkcnt_t st_blocks;\n\tlong st_atime_sec;\n\tlong st_atime_nsec;\n\tlong st_mtime_sec;\n\tlong st_mtime_nsec;\n\tlong st_ctime_sec;\n\tlong st_ctime_nsec;\n\tunsigned __unused[2];\n};\n"
  },
  {
    "path": "user.libc/arch/powerpc/pthread_arch.h",
    "content": "static inline uintptr_t __get_tp()\n{\n\tregister uintptr_t tp __asm__(\"r2\");\n\t__asm__ (\"\" : \"=r\" (tp) );\n\treturn tp;\n}\n                        \n#define TLS_ABOVE_TP\n#define GAP_ABOVE_TP 0\n\n#define TP_OFFSET 0x7000\n#define DTP_OFFSET 0x8000\n\n// the kernel calls the ip \"nip\", it's the first saved value after the 32\n// GPRs.\n#define MC_PC gregs[32]\n"
  },
  {
    "path": "user.libc/arch/powerpc/reloc.h",
    "content": "#ifdef _SOFT_FLOAT\n#define FP_SUFFIX \"-sf\"\n#else\n#define FP_SUFFIX \"\"\n#endif\n\n#define LDSO_ARCH \"powerpc\" FP_SUFFIX\n\n#define TPOFF_K (-0x7000)\n\n#define REL_SYMBOLIC    R_PPC_ADDR32\n#define REL_USYMBOLIC   R_PPC_UADDR32\n#define REL_GOT         R_PPC_GLOB_DAT\n#define REL_PLT         R_PPC_JMP_SLOT\n#define REL_RELATIVE    R_PPC_RELATIVE\n#define REL_COPY        R_PPC_COPY\n#define REL_DTPMOD      R_PPC_DTPMOD32\n#define REL_DTPOFF      R_PPC_DTPREL32\n#define REL_TPOFF       R_PPC_TPREL32\n\n#define CRTJMP(pc,sp) __asm__ __volatile__( \\\n\t\"mr 1,%1 ; mtlr %0 ; blr\" : : \"r\"(pc), \"r\"(sp) : \"memory\" )\n\n#define GETFUNCSYM(fp, sym, got) __asm__ ( \\\n\t\".hidden \" #sym \" \\n\" \\\n\t\"\tbl 1f \\n\" \\\n\t\"\t.long \" #sym \"-. \\n\" \\\n\t\"1:\tmflr %1 \\n\" \\\n\t\"\tlwz %0, 0(%1) \\n\" \\\n\t\"\tadd %0, %0, %1 \\n\" \\\n\t: \"=r\"(*(fp)), \"=r\"((int){0}) : : \"memory\", \"lr\" )\n"
  },
  {
    "path": "user.libc/arch/powerpc/syscall_arch.h",
    "content": "#define __SYSCALL_LL_E(x) \\\n((union { long long ll; long l[2]; }){ .ll = x }).l[0], \\\n((union { long long ll; long l[2]; }){ .ll = x }).l[1]\n#define __SYSCALL_LL_O(x) 0, __SYSCALL_LL_E((x))\n\nstatic inline long __syscall0(long n)\n{\n\tregister long r0 __asm__(\"r0\") = n;\n\tregister long r3 __asm__(\"r3\");\n\t__asm__ __volatile__(\"sc ; bns+ 1f ; neg %1, %1 ; 1:\"\n\t: \"+r\"(r0), \"=r\"(r3)\n\t:: \"memory\", \"cr0\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\");\n\treturn r3;\n}\n\nstatic inline long __syscall1(long n, long a)\n{\n\tregister long r0 __asm__(\"r0\") = n;\n\tregister long r3 __asm__(\"r3\") = a;\n\t__asm__ __volatile__(\"sc ; bns+ 1f ; neg %1, %1 ; 1:\"\n\t: \"+r\"(r0), \"+r\"(r3)\n\t:: \"memory\", \"cr0\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\");\n\treturn r3;\n}\n\nstatic inline long __syscall2(long n, long a, long b)\n{\n\tregister long r0 __asm__(\"r0\") = n;\n\tregister long r3 __asm__(\"r3\") = a;\n\tregister long r4 __asm__(\"r4\") = b;\n\t__asm__ __volatile__(\"sc ; bns+ 1f ; neg %1, %1 ; 1:\"\n\t: \"+r\"(r0), \"+r\"(r3), \"+r\"(r4)\n\t:: \"memory\", \"cr0\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\");\n\treturn r3;\n}\n\nstatic inline long __syscall3(long n, long a, long b, long c)\n{\n\tregister long r0 __asm__(\"r0\") = n;\n\tregister long r3 __asm__(\"r3\") = a;\n\tregister long r4 __asm__(\"r4\") = b;\n\tregister long r5 __asm__(\"r5\") = c;\n\t__asm__ __volatile__(\"sc ; bns+ 1f ; neg %1, %1 ; 1:\"\n\t: \"+r\"(r0), \"+r\"(r3), \"+r\"(r4), \"+r\"(r5)\n\t:: \"memory\", \"cr0\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\");\n\treturn r3;\n}\n\nstatic inline long __syscall4(long n, long a, long b, long c, long d)\n{\n\tregister long r0 __asm__(\"r0\") = n;\n\tregister long r3 __asm__(\"r3\") = a;\n\tregister long r4 __asm__(\"r4\") = b;\n\tregister long r5 __asm__(\"r5\") = c;\n\tregister long r6 __asm__(\"r6\") = d;\n\t__asm__ __volatile__(\"sc ; bns+ 1f ; neg %1, %1 ; 1:\"\n\t: \"+r\"(r0), \"+r\"(r3), \"+r\"(r4), \"+r\"(r5), \"+r\"(r6)\n\t:: \"memory\", \"cr0\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\");\n\treturn r3;\n}\n\nstatic inline long __syscall5(long n, long a, long b, long c, long d, long e)\n{\n\tregister long r0 __asm__(\"r0\") = n;\n\tregister long r3 __asm__(\"r3\") = a;\n\tregister long r4 __asm__(\"r4\") = b;\n\tregister long r5 __asm__(\"r5\") = c;\n\tregister long r6 __asm__(\"r6\") = d;\n\tregister long r7 __asm__(\"r7\") = e;\n\t__asm__ __volatile__(\"sc ; bns+ 1f ; neg %1, %1 ; 1:\"\n\t: \"+r\"(r0), \"+r\"(r3), \"+r\"(r4), \"+r\"(r5), \"+r\"(r6), \"+r\"(r7)\n\t:: \"memory\", \"cr0\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\");\n\treturn r3;\n}\n\nstatic inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)\n{\n\tregister long r0 __asm__(\"r0\") = n;\n\tregister long r3 __asm__(\"r3\") = a;\n\tregister long r4 __asm__(\"r4\") = b;\n\tregister long r5 __asm__(\"r5\") = c;\n\tregister long r6 __asm__(\"r6\") = d;\n\tregister long r7 __asm__(\"r7\") = e;\n\tregister long r8 __asm__(\"r8\") = f;\n\t__asm__ __volatile__(\"sc ; bns+ 1f ; neg %1, %1 ; 1:\"\n\t: \"+r\"(r0), \"+r\"(r3), \"+r\"(r4), \"+r\"(r5), \"+r\"(r6), \"+r\"(r7), \"+r\"(r8)\n\t:: \"memory\", \"cr0\", \"r9\", \"r10\", \"r11\", \"r12\");\n\treturn r3;\n}\n\n#define SYSCALL_FADVISE_6_ARG\n\n#define SO_RCVTIMEO_OLD  18\n#define SO_SNDTIMEO_OLD  19\n"
  },
  {
    "path": "user.libc/arch/powerpc64/atomic_arch.h",
    "content": "#define a_ll a_ll\nstatic inline int a_ll(volatile int *p)\n{\n\tint v;\n\t__asm__ __volatile__ (\"lwarx %0, 0, %2\" : \"=r\"(v) : \"m\"(*p), \"r\"(p));\n\treturn v;\n}\n\n#define a_sc a_sc\nstatic inline int a_sc(volatile int *p, int v)\n{\n\tint r;\n\t__asm__ __volatile__ (\n\t\t\"stwcx. %2, 0, %3 ; mfcr %0\"\n\t\t: \"=r\"(r), \"=m\"(*p) : \"r\"(v), \"r\"(p) : \"memory\", \"cc\");\n\treturn r & 0x20000000; /* \"bit 2\" of \"cr0\" (backwards bit order) */\n}\n\n#define a_ll_p a_ll_p\nstatic inline void *a_ll_p(volatile void *p)\n{\n\tvoid *v;\n\t__asm__ __volatile__ (\"ldarx %0, 0, %2\" : \"=r\"(v) : \"m\"(*(void *volatile *)p), \"r\"(p));\n\treturn v;\n}\n\n#define a_sc_p a_sc_p\nstatic inline int a_sc_p(volatile void *p, void *v)\n{\n\tint r;\n\t__asm__ __volatile__ (\n\t\t\"stdcx. %2, 0, %3 ; mfcr %0\"\n\t\t: \"=r\"(r), \"=m\"(*(void *volatile *)p) : \"r\"(v), \"r\"(p) : \"memory\", \"cc\");\n\treturn r & 0x20000000; /* \"bit 2\" of \"cr0\" (backwards bit order) */\n}\n\n#define a_barrier a_barrier\nstatic inline void a_barrier()\n{\n\t__asm__ __volatile__ (\"sync\" : : : \"memory\");\n}\n\n#define a_pre_llsc a_barrier\n\n#define a_post_llsc a_post_llsc\nstatic inline void a_post_llsc()\n{\n\t__asm__ __volatile__ (\"isync\" : : : \"memory\");\n}\n\n#define a_crash a_crash\nstatic inline void a_crash()\n{\n\t__asm__ __volatile__ (\".long 0\");\n}\n\n#define a_clz_64 a_clz_64\nstatic inline int a_clz_64(uint64_t x)\n{\n\t__asm__ (\"cntlzd %0, %1\" : \"=r\"(x) : \"r\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/arch/powerpc64/bits/alltypes.h.in",
    "content": "#define _Addr long\n#define _Int64 long\n#define _Reg long\n\n#if __BIG_ENDIAN__\n#define __BYTE_ORDER 4321\n#else\n#define __BYTE_ORDER 1234\n#endif\n\n#define __LONG_MAX 0x7fffffffffffffffL\n\n#ifndef __cplusplus\nTYPEDEF int wchar_t;\n#endif\n\nTYPEDEF float float_t;\nTYPEDEF double double_t;\n\nTYPEDEF struct { long long __ll; long double __ld; } max_align_t;\n"
  },
  {
    "path": "user.libc/arch/powerpc64/bits/errno.h",
    "content": "#define EPERM            1\n#define ENOENT           2\n#define ESRCH            3\n#define EINTR            4\n#define EIO              5\n#define ENXIO            6\n#define E2BIG            7\n#define ENOEXEC          8\n#define EBADF            9\n#define ECHILD          10\n#define EAGAIN          11\n#define ENOMEM          12\n#define EACCES          13\n#define EFAULT          14\n#define ENOTBLK         15\n#define EBUSY           16\n#define EEXIST          17\n#define EXDEV           18\n#define ENODEV          19\n#define ENOTDIR         20\n#define EISDIR          21\n#define EINVAL          22\n#define ENFILE          23\n#define EMFILE          24\n#define ENOTTY          25\n#define ETXTBSY         26\n#define EFBIG           27\n#define ENOSPC          28\n#define ESPIPE          29\n#define EROFS           30\n#define EMLINK          31\n#define EPIPE           32\n#define EDOM            33\n#define ERANGE          34\n#define EDEADLK         35\n#define ENAMETOOLONG    36\n#define ENOLCK          37\n#define ENOSYS          38\n#define ENOTEMPTY       39\n#define ELOOP           40\n#define EWOULDBLOCK     EAGAIN\n#define ENOMSG          42\n#define EIDRM           43\n#define ECHRNG          44\n#define EL2NSYNC        45\n#define EL3HLT          46\n#define EL3RST          47\n#define ELNRNG          48\n#define EUNATCH         49\n#define ENOCSI          50\n#define EL2HLT          51\n#define EBADE           52\n#define EBADR           53\n#define EXFULL          54\n#define ENOANO          55\n#define EBADRQC         56\n#define EBADSLT         57\n#define EDEADLOCK       58\n#define EBFONT          59\n#define ENOSTR          60\n#define ENODATA         61\n#define ETIME           62\n#define ENOSR           63\n#define ENONET          64\n#define ENOPKG          65\n#define EREMOTE         66\n#define ENOLINK         67\n#define EADV            68\n#define ESRMNT          69\n#define ECOMM           70\n#define EPROTO          71\n#define EMULTIHOP       72\n#define EDOTDOT         73\n#define EBADMSG         74\n#define EOVERFLOW       75\n#define ENOTUNIQ        76\n#define EBADFD          77\n#define EREMCHG         78\n#define ELIBACC         79\n#define ELIBBAD         80\n#define ELIBSCN         81\n#define ELIBMAX         82\n#define ELIBEXEC        83\n#define EILSEQ          84\n#define ERESTART        85\n#define ESTRPIPE        86\n#define EUSERS          87\n#define ENOTSOCK        88\n#define EDESTADDRREQ    89\n#define EMSGSIZE        90\n#define EPROTOTYPE      91\n#define ENOPROTOOPT     92\n#define EPROTONOSUPPORT 93\n#define ESOCKTNOSUPPORT 94\n#define EOPNOTSUPP      95\n#define ENOTSUP         EOPNOTSUPP\n#define EPFNOSUPPORT    96\n#define EAFNOSUPPORT    97\n#define EADDRINUSE      98\n#define EADDRNOTAVAIL   99\n#define ENETDOWN        100\n#define ENETUNREACH     101\n#define ENETRESET       102\n#define ECONNABORTED    103\n#define ECONNRESET      104\n#define ENOBUFS         105\n#define EISCONN         106\n#define ENOTCONN        107\n#define ESHUTDOWN       108\n#define ETOOMANYREFS    109\n#define ETIMEDOUT       110\n#define ECONNREFUSED    111\n#define EHOSTDOWN       112\n#define EHOSTUNREACH    113\n#define EALREADY        114\n#define EINPROGRESS     115\n#define ESTALE          116\n#define EUCLEAN         117\n#define ENOTNAM         118\n#define ENAVAIL         119\n#define EISNAM          120\n#define EREMOTEIO       121\n#define EDQUOT          122\n#define ENOMEDIUM       123\n#define EMEDIUMTYPE     124\n#define ECANCELED       125\n#define ENOKEY          126\n#define EKEYEXPIRED     127\n#define EKEYREVOKED     128\n#define EKEYREJECTED    129\n#define EOWNERDEAD      130\n#define ENOTRECOVERABLE 131\n#define ERFKILL         132\n#define EHWPOISON       133\n"
  },
  {
    "path": "user.libc/arch/powerpc64/bits/fcntl.h",
    "content": "#define O_CREAT        0100\n#define O_EXCL         0200\n#define O_NOCTTY       0400\n#define O_TRUNC       01000\n#define O_APPEND      02000\n#define O_NONBLOCK    04000\n#define O_DSYNC      010000\n#define O_SYNC     04010000\n#define O_RSYNC    04010000\n#define O_DIRECTORY  040000\n#define O_NOFOLLOW  0100000\n#define O_CLOEXEC  02000000\n\n#define O_ASYNC      020000\n#define O_DIRECT    0400000\n#define O_LARGEFILE 0200000\n#define O_NOATIME  01000000\n#define O_PATH    010000000\n#define O_TMPFILE 020040000\n#define O_NDELAY O_NONBLOCK\n\n#define F_DUPFD  0\n#define F_GETFD  1\n#define F_SETFD  2\n#define F_GETFL  3\n#define F_SETFL  4\n\n#define F_GETLK  5\n#define F_SETLK  6\n#define F_SETLKW 7\n\n#define F_SETOWN 8\n#define F_GETOWN 9\n#define F_SETSIG 10\n#define F_GETSIG 11\n\n#define F_SETOWN_EX 15\n#define F_GETOWN_EX 16\n\n#define F_GETOWNER_UIDS 17\n"
  },
  {
    "path": "user.libc/arch/powerpc64/bits/fenv.h",
    "content": "#define FE_TONEAREST\t0\n#define FE_TOWARDZERO\t1\n#define FE_UPWARD\t2\n#define FE_DOWNWARD\t3\n\n#define FE_INEXACT\t0x02000000\n#define FE_DIVBYZERO\t0x04000000\n#define FE_UNDERFLOW\t0x08000000\n#define FE_OVERFLOW\t0x10000000\n#define FE_INVALID\t0x20000000\n\n#define FE_ALL_EXCEPT\t0x3e000000\n\n#ifdef _GNU_SOURCE\n#define FE_INVALID_SNAN\t\t0x01000000\n#define FE_INVALID_ISI\t\t0x00800000\n#define FE_INVALID_IDI\t\t0x00400000\n#define FE_INVALID_ZDZ\t\t0x00200000\n#define FE_INVALID_IMZ\t\t0x00100000\n#define FE_INVALID_COMPARE\t0x00080000\n#define FE_INVALID_SOFTWARE\t0x00000400\n#define FE_INVALID_SQRT\t\t0x00000200\n#define FE_INVALID_INTEGER_CONVERSION\t0x00000100\n\n#define FE_ALL_INVALID\t\t0x01f80700\n#endif\n\ntypedef unsigned fexcept_t;\ntypedef double fenv_t;\n\n#define FE_DFL_ENV ((const fenv_t *)-1)\n"
  },
  {
    "path": "user.libc/arch/powerpc64/bits/float.h",
    "content": "#define FLT_EVAL_METHOD 0\n\n#define LDBL_TRUE_MIN 4.94065645841246544177e-324L\n#define LDBL_MIN 2.22507385850720138309e-308L\n#define LDBL_MAX 1.79769313486231570815e+308L\n#define LDBL_EPSILON 2.22044604925031308085e-16L\n\n#define LDBL_MANT_DIG 53\n#define LDBL_MIN_EXP (-1021)\n#define LDBL_MAX_EXP 1024\n\n#define LDBL_DIG 15\n#define LDBL_MIN_10_EXP (-307)\n#define LDBL_MAX_10_EXP 308\n\n#define DECIMAL_DIG 17\n"
  },
  {
    "path": "user.libc/arch/powerpc64/bits/hwcap.h",
    "content": "#define PPC_FEATURE_32\t\t\t0x80000000\n#define PPC_FEATURE_64\t\t\t0x40000000\n#define PPC_FEATURE_601_INSTR\t\t0x20000000\n#define PPC_FEATURE_HAS_ALTIVEC\t\t0x10000000\n#define PPC_FEATURE_HAS_FPU\t\t0x08000000\n#define PPC_FEATURE_HAS_MMU\t\t0x04000000\n#define PPC_FEATURE_HAS_4xxMAC\t\t0x02000000\n#define PPC_FEATURE_UNIFIED_CACHE\t0x01000000\n#define PPC_FEATURE_HAS_SPE\t\t0x00800000\n#define PPC_FEATURE_HAS_EFP_SINGLE\t0x00400000\n#define PPC_FEATURE_HAS_EFP_DOUBLE\t0x00200000\n#define PPC_FEATURE_NO_TB\t\t0x00100000\n#define PPC_FEATURE_POWER4\t\t0x00080000\n#define PPC_FEATURE_POWER5\t\t0x00040000\n#define PPC_FEATURE_POWER5_PLUS\t\t0x00020000\n#define PPC_FEATURE_CELL\t\t0x00010000\n#define PPC_FEATURE_BOOKE\t\t0x00008000\n#define PPC_FEATURE_SMT\t\t\t0x00004000\n#define PPC_FEATURE_ICACHE_SNOOP\t0x00002000\n#define PPC_FEATURE_ARCH_2_05\t\t0x00001000\n#define PPC_FEATURE_PA6T\t\t0x00000800\n#define PPC_FEATURE_HAS_DFP\t\t0x00000400\n#define PPC_FEATURE_POWER6_EXT\t\t0x00000200\n#define PPC_FEATURE_ARCH_2_06\t\t0x00000100\n#define PPC_FEATURE_HAS_VSX\t\t0x00000080\n#define PPC_FEATURE_PSERIES_PERFMON_COMPAT 0x00000040\n\n#define PPC_FEATURE_TRUE_LE\t\t0x00000002\n#define PPC_FEATURE_PPC_LE\t\t0x00000001\n\n#define PPC_FEATURE2_ARCH_2_07\t\t0x80000000\n#define PPC_FEATURE2_HTM\t\t0x40000000\n#define PPC_FEATURE2_DSCR\t\t0x20000000\n#define PPC_FEATURE2_EBB\t\t0x10000000\n#define PPC_FEATURE2_ISEL\t\t0x08000000\n#define PPC_FEATURE2_TAR\t\t0x04000000\n#define PPC_FEATURE2_VEC_CRYPTO\t\t0x02000000\n#define PPC_FEATURE2_HTM_NOSC\t\t0x01000000\n#define PPC_FEATURE2_ARCH_3_00\t\t0x00800000\n#define PPC_FEATURE2_HAS_IEEE128\t0x00400000\n#define PPC_FEATURE2_DARN\t\t0x00200000\n#define PPC_FEATURE2_SCV\t\t0x00100000\n#define PPC_FEATURE2_HTM_NO_SUSPEND\t0x00080000\n"
  },
  {
    "path": "user.libc/arch/powerpc64/bits/ioctl.h",
    "content": "#define _IOC(a,b,c,d) ( ((a)<<29) | ((b)<<8) | (c) | ((d)<<16) )\n#define _IOC_NONE  1U\n#define _IOC_WRITE 4U\n#define _IOC_READ  2U\n\n#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)\n#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c))\n#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c))\n#define _IOWR(a,b,c) _IOC(_IOC_READ|_IOC_WRITE,(a),(b),sizeof(c))\n\n#define FIONCLEX\t_IO('f', 2)\n#define FIOCLEX\t\t_IO('f', 1)\n#define FIOASYNC\t_IOW('f', 125, int)\n#define FIONBIO\t\t_IOW('f', 126, int)\n#define FIONREAD\t_IOR('f', 127, int)\n#define TIOCINQ\t\tFIONREAD\n#define FIOQSIZE\t_IOR('f', 128, char[8])\n#define TIOCGETP\t_IOR('t', 8, char[6])\n#define TIOCSETP\t_IOW('t', 9, char[6])\n#define TIOCSETN\t_IOW('t', 10, char[6])\n\n#define TIOCSETC\t_IOW('t', 17, char[6])\n#define TIOCGETC\t_IOR('t', 18, char[6])\n#define TCGETS\t\t_IOR('t', 19, char[44])\n#define TCSETS\t\t_IOW('t', 20, char[44])\n#define TCSETSW\t\t_IOW('t', 21, char[44])\n#define TCSETSF\t\t_IOW('t', 22, char[44])\n\n#define TCGETA\t\t_IOR('t', 23, char[20])\n#define TCSETA\t\t_IOW('t', 24, char[20])\n#define TCSETAW\t\t_IOW('t', 25, char[20])\n#define TCSETAF\t\t_IOW('t', 28, char[20])\n\n#define TCSBRK\t\t_IO('t', 29)\n#define TCXONC\t\t_IO('t', 30)\n#define TCFLSH\t\t_IO('t', 31)\n\n#define TIOCSWINSZ\t_IOW('t', 103, char[8])\n#define TIOCGWINSZ\t_IOR('t', 104, char[8])\n#define TIOCSTART\t_IO('t', 110)\n#define TIOCSTOP\t_IO('t', 111)\n\n#define TIOCOUTQ\t_IOR('t', 115, int)\n\n#define TIOCGLTC\t_IOR('t', 116, char[6])\n#define TIOCSLTC\t_IOW('t', 117, char[6])\n#define TIOCSPGRP\t_IOW('t', 118, int)\n#define TIOCGPGRP\t_IOR('t', 119, int)\n\n#define TIOCEXCL\t0x540C\n#define TIOCNXCL\t0x540D\n#define TIOCSCTTY\t0x540E\n\n#define TIOCSTI\t\t0x5412\n#define TIOCMGET\t0x5415\n#define TIOCMBIS\t0x5416\n#define TIOCMBIC\t0x5417\n#define TIOCMSET\t0x5418\n#define TIOCM_LE\t0x001\n#define TIOCM_DTR\t0x002\n#define TIOCM_RTS\t0x004\n#define TIOCM_ST\t0x008\n#define TIOCM_SR\t0x010\n#define TIOCM_CTS\t0x020\n#define TIOCM_CAR\t0x040\n#define TIOCM_RNG\t0x080\n#define TIOCM_DSR\t0x100\n#define TIOCM_CD\tTIOCM_CAR\n#define TIOCM_RI\tTIOCM_RNG\n#define TIOCM_OUT1\t0x2000\n#define TIOCM_OUT2\t0x4000\n#define TIOCM_LOOP\t0x8000\n\n#define TIOCGSOFTCAR\t0x5419\n#define TIOCSSOFTCAR\t0x541A\n#define TIOCLINUX\t0x541C\n#define TIOCCONS\t0x541D\n#define TIOCGSERIAL\t0x541E\n#define TIOCSSERIAL\t0x541F\n#define TIOCPKT\t0x5420\n\n#define TIOCNOTTY\t0x5422\n#define TIOCSETD\t0x5423\n#define TIOCGETD\t0x5424\n#define TCSBRKP\t\t0x5425\n#define TIOCSBRK\t0x5427\n#define TIOCCBRK\t0x5428\n#define TIOCGSID\t0x5429\n#define TIOCGRS485\t0x542e\n#define TIOCSRS485\t0x542f\n#define TIOCGPTN\t_IOR('T',0x30, unsigned int)\n#define TIOCSPTLCK\t_IOW('T',0x31, int)\n#define TIOCGDEV\t_IOR('T',0x32, unsigned int)\n#define TIOCSIG\t\t_IOW('T',0x36, int)\n#define TIOCVHANGUP\t0x5437\n#define TIOCGPKT\t_IOR('T', 0x38, int)\n#define TIOCGPTLCK\t_IOR('T', 0x39, int)\n#define TIOCGEXCL\t_IOR('T', 0x40, int)\n#define TIOCGPTPEER\t_IO('T', 0x41)\n\n#define TIOCSERCONFIG\t0x5453\n#define TIOCSERGWILD\t0x5454\n#define TIOCSERSWILD\t0x5455\n#define TIOCGLCKTRMIOS\t0x5456\n#define TIOCSLCKTRMIOS\t0x5457\n#define TIOCSERGSTRUCT\t0x5458\n#define TIOCSERGETLSR\t0x5459\n#define TIOCSERGETMULTI\t0x545A\n#define TIOCSERSETMULTI\t0x545B\n\n#define TIOCMIWAIT\t0x545C\n#define TIOCGICOUNT\t0x545D\n\n#define FIOSETOWN       0x8901\n#define SIOCSPGRP       0x8902\n#define FIOGETOWN       0x8903\n#define SIOCGPGRP       0x8904\n#define SIOCATMARK      0x8905\n#define SIOCGSTAMP      0x8906\n#define SIOCGSTAMPNS    0x8907\n"
  },
  {
    "path": "user.libc/arch/powerpc64/bits/ipc.h",
    "content": "struct ipc_perm {\n\tkey_t __ipc_perm_key;\n\tuid_t uid;\n\tgid_t gid;\n\tuid_t cuid;\n\tgid_t cgid;\n\tmode_t mode;\n\tint __ipc_perm_seq;\n\tint __pad1;\n\tlong long __pad2;\n\tlong long __pad3;\n};\n"
  },
  {
    "path": "user.libc/arch/powerpc64/bits/mman.h",
    "content": "#define PROT_SAO       0x10\n\n#undef MAP_NORESERVE\n#define MAP_NORESERVE   0x40\n#undef MAP_LOCKED\n#define MAP_LOCKED\t0x80\n\n#undef MCL_CURRENT\n#define MCL_CURRENT     0x2000\n#undef MCL_FUTURE\n#define MCL_FUTURE      0x4000\n#undef MCL_ONFAULT\n#define MCL_ONFAULT     0x8000\n"
  },
  {
    "path": "user.libc/arch/powerpc64/bits/posix.h",
    "content": "#define _POSIX_V6_LP64_OFF64  1\n#define _POSIX_V7_LP64_OFF64  1\n"
  },
  {
    "path": "user.libc/arch/powerpc64/bits/ptrace.h",
    "content": "#define PTRACE_GETVRREGS\t0x12\n#define PTRACE_SETVRREGS\t0x13\n#define PTRACE_GETEVRREGS\t0x14\n#define PTRACE_SETEVRREGS\t0x15\n#define PTRACE_GETREGS64\t0x16\n#define PTRACE_SETREGS64\t0x17\n#define PTRACE_GET_DEBUGREG\t0x19\n#define PTRACE_SET_DEBUGREG\t0x1a\n#define PTRACE_GETVSRREGS\t0x1b\n#define PTRACE_SETVSRREGS\t0x1c\n#define PTRACE_SYSEMU\t\t0x1d\n#define PTRACE_SYSEMU_SINGLESTEP\t0x1e\n#define PTRACE_SINGLEBLOCK\t0x100\n\n#define PT_GETVRREGS PTRACE_GETVRREGS\n#define PT_SETVRREGS PTRACE_SETVRREGS\n#define PT_GETEVRREGS PTRACE_GETEVRREGS\n#define PT_SETEVRREGS PTRACE_SETEVRREGS\n#define PT_GETREGS64 PTRACE_GETREGS64\n#define PT_SETREGS64 PTRACE_SETREGS64\n#define PT_GET_DEBUGREG PTRACE_GET_DEBUGREG\n#define PT_SET_DEBUGREG PTRACE_SET_DEBUGREG\n#define PT_GETVSRREGS PTRACE_GETVSRREGS\n#define PT_SETVSRREGS PTRACE_SETVSRREGS\n#define PT_STEPBLOCK PTRACE_SINGLEBLOCK\n"
  },
  {
    "path": "user.libc/arch/powerpc64/bits/reg.h",
    "content": "#undef __WORDSIZE\n#define __WORDSIZE 64\n/* FIXME */\n"
  },
  {
    "path": "user.libc/arch/powerpc64/bits/setjmp.h",
    "content": "typedef unsigned __int128 __jmp_buf[32];\n"
  },
  {
    "path": "user.libc/arch/powerpc64/bits/shm.h",
    "content": "#define SHMLBA 4096\n\nstruct shmid_ds {\n\tstruct ipc_perm shm_perm;\n\ttime_t shm_atime;\n\ttime_t shm_dtime;\n\ttime_t shm_ctime;\n\tsize_t shm_segsz;\n\tpid_t shm_cpid;\n\tpid_t shm_lpid;\n\tunsigned long shm_nattch;\n\tunsigned long __unused[2];\n};\n\nstruct shminfo {\n\tunsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];\n};\n\nstruct shm_info {\n\tint __used_ids;\n\tunsigned long shm_tot, shm_rss, shm_swp;\n\tunsigned long __swap_attempts, __swap_successes;\n};\n"
  },
  {
    "path": "user.libc/arch/powerpc64/bits/signal.h",
    "content": "#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define MINSIGSTKSZ 4096\n#define SIGSTKSZ    10240\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n\ntypedef unsigned long greg_t, gregset_t[48];\ntypedef double fpregset_t[33];\n\ntypedef struct {\n#ifdef __GNUC__\n\t__attribute__((__aligned__(16)))\n#endif\n\tunsigned vrregs[32][4];\n\tstruct {\n#if __BIG_ENDIAN__\n\t\tunsigned _pad[3], vscr_word;\n#else\n\t\tunsigned vscr_word, _pad[3];\n#endif\n\t} vscr;\n\tunsigned vrsave, _pad[3];\n} vrregset_t;\n\ntypedef struct sigcontext {\n\tunsigned long _unused[4];\n\tint signal;\n\tint _pad0;\n\tunsigned long handler;\n\tunsigned long oldmask;\n\tstruct pt_regs *regs;\n\tgregset_t gp_regs;\n\tfpregset_t fp_regs;\n\tvrregset_t *v_regs;\n\tlong vmx_reserve[34+34+32+1];\n} mcontext_t;\n\n#else\n\ntypedef struct {\n\tlong __regs[4+4+48+33+1+34+34+32+1];\n} mcontext_t;\n\n#endif\n\nstruct sigaltstack {\n\tvoid *ss_sp;\n\tint ss_flags;\n\tsize_t ss_size;\n};\n\ntypedef struct __ucontext {\n\tunsigned long uc_flags;\n\tstruct __ucontext *uc_link;\n\tstack_t uc_stack;\n\tsigset_t uc_sigmask;\n\tmcontext_t uc_mcontext;\n} ucontext_t;\n\n#define SA_NOCLDSTOP  1U\n#define SA_NOCLDWAIT  2U\n#define SA_SIGINFO    4U\n#define SA_ONSTACK    0x08000000U\n#define SA_RESTART    0x10000000U\n#define SA_NODEFER    0x40000000U\n#define SA_RESETHAND  0x80000000U\n#define SA_RESTORER   0x04000000U\n\n#endif\n\n#define SIGHUP    1\n#define SIGINT    2\n#define SIGQUIT   3\n#define SIGILL    4\n#define SIGTRAP   5\n#define SIGABRT   6\n#define SIGIOT    SIGABRT\n#define SIGBUS    7\n#define SIGFPE    8\n#define SIGKILL   9\n#define SIGUSR1   10\n#define SIGSEGV   11\n#define SIGUSR2   12\n#define SIGPIPE   13\n#define SIGALRM   14\n#define SIGTERM   15\n#define SIGSTKFLT 16\n#define SIGCHLD   17\n#define SIGCONT   18\n#define SIGSTOP   19\n#define SIGTSTP   20\n#define SIGTTIN   21\n#define SIGTTOU   22\n#define SIGURG    23\n#define SIGXCPU   24\n#define SIGXFSZ   25\n#define SIGVTALRM 26\n#define SIGPROF   27\n#define SIGWINCH  28\n#define SIGIO     29\n#define SIGPOLL   SIGIO\n#define SIGPWR    30\n#define SIGSYS    31\n#define SIGUNUSED SIGSYS\n\n#define _NSIG 65\n"
  },
  {
    "path": "user.libc/arch/powerpc64/bits/socket.h",
    "content": "#define SO_DEBUG        1\n#define SO_REUSEADDR    2\n#define SO_TYPE         3\n#define SO_ERROR        4\n#define SO_DONTROUTE    5\n#define SO_BROADCAST    6\n#define SO_SNDBUF       7\n#define SO_RCVBUF       8\n#define SO_KEEPALIVE    9\n#define SO_OOBINLINE    10\n#define SO_NO_CHECK     11\n#define SO_PRIORITY     12\n#define SO_LINGER       13\n#define SO_BSDCOMPAT    14\n#define SO_REUSEPORT    15\n#define SO_RCVLOWAT     16\n#define SO_SNDLOWAT     17\n#define SO_RCVTIMEO     18\n#define SO_SNDTIMEO     19\n#define SO_PASSCRED     20\n#define SO_PEERCRED     21\n#define SO_ACCEPTCONN   30\n#define SO_PEERSEC      31\n#define SO_SNDBUFFORCE  32\n#define SO_RCVBUFFORCE  33\n#define SO_PROTOCOL     38\n#define SO_DOMAIN       39\n"
  },
  {
    "path": "user.libc/arch/powerpc64/bits/stat.h",
    "content": "struct stat {\n\tdev_t st_dev;\n\tino_t st_ino;\n\tnlink_t st_nlink;\n\tmode_t st_mode;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tdev_t st_rdev;\n\toff_t st_size;\n\tblksize_t st_blksize;\n\tblkcnt_t st_blocks;\n\tstruct timespec st_atim;\n\tstruct timespec st_mtim;\n\tstruct timespec st_ctim;\n\tunsigned long __unused[3];\n};\n"
  },
  {
    "path": "user.libc/arch/powerpc64/bits/stdint.h",
    "content": "typedef int32_t int_fast16_t;\ntypedef int32_t int_fast32_t;\ntypedef uint32_t uint_fast16_t;\ntypedef uint32_t uint_fast32_t;\n\n#define INT_FAST16_MIN  INT32_MIN\n#define INT_FAST32_MIN  INT32_MIN\n\n#define INT_FAST16_MAX  INT32_MAX\n#define INT_FAST32_MAX  INT32_MAX\n\n#define UINT_FAST16_MAX UINT32_MAX\n#define UINT_FAST32_MAX UINT32_MAX\n\n#define INTPTR_MIN      INT64_MIN\n#define INTPTR_MAX      INT64_MAX\n#define UINTPTR_MAX     UINT64_MAX\n#define PTRDIFF_MIN     INT64_MIN\n#define PTRDIFF_MAX     INT64_MAX\n#define SIZE_MAX        UINT64_MAX\n"
  },
  {
    "path": "user.libc/arch/powerpc64/bits/syscall.h.in",
    "content": "#define __NR_restart_syscall          0\n#define __NR_exit                     1\n#define __NR_fork                     2\n#define __NR_read                     3\n#define __NR_write                    4\n#define __NR_open                     5\n#define __NR_close                    6\n#define __NR_waitpid                  7\n#define __NR_creat                    8\n#define __NR_link                     9\n#define __NR_unlink                  10\n#define __NR_execve                  11\n#define __NR_chdir                   12\n#define __NR_time                    13\n#define __NR_mknod                   14\n#define __NR_chmod                   15\n#define __NR_lchown                  16\n#define __NR_break                   17\n#define __NR_oldstat                 18\n#define __NR_lseek                   19\n#define __NR_getpid                  20\n#define __NR_mount                   21\n#define __NR_umount                  22\n#define __NR_setuid                  23\n#define __NR_getuid                  24\n#define __NR_stime                   25\n#define __NR_ptrace                  26\n#define __NR_alarm                   27\n#define __NR_oldfstat                28\n#define __NR_pause                   29\n#define __NR_utime                   30\n#define __NR_stty                    31\n#define __NR_gtty                    32\n#define __NR_access                  33\n#define __NR_nice                    34\n#define __NR_ftime                   35\n#define __NR_sync                    36\n#define __NR_kill                    37\n#define __NR_rename                  38\n#define __NR_mkdir                   39\n#define __NR_rmdir                   40\n#define __NR_dup                     41\n#define __NR_pipe                    42\n#define __NR_times                   43\n#define __NR_prof                    44\n#define __NR_brk                     45\n#define __NR_setgid                  46\n#define __NR_getgid                  47\n#define __NR_signal                  48\n#define __NR_geteuid                 49\n#define __NR_getegid                 50\n#define __NR_acct                    51\n#define __NR_umount2                 52\n#define __NR_lock                    53\n#define __NR_ioctl                   54\n#define __NR_fcntl                   55\n#define __NR_mpx                     56\n#define __NR_setpgid                 57\n#define __NR_ulimit                  58\n#define __NR_oldolduname             59\n#define __NR_umask                   60\n#define __NR_chroot                  61\n#define __NR_ustat                   62\n#define __NR_dup2                    63\n#define __NR_getppid                 64\n#define __NR_getpgrp                 65\n#define __NR_setsid                  66\n#define __NR_sigaction               67\n#define __NR_sgetmask                68\n#define __NR_ssetmask                69\n#define __NR_setreuid                70\n#define __NR_setregid                71\n#define __NR_sigsuspend              72\n#define __NR_sigpending              73\n#define __NR_sethostname             74\n#define __NR_setrlimit               75\n#define __NR_getrlimit               76\n#define __NR_getrusage               77\n#define __NR_gettimeofday            78\n#define __NR_settimeofday            79\n#define __NR_getgroups               80\n#define __NR_setgroups               81\n#define __NR_select                  82\n#define __NR_symlink                 83\n#define __NR_oldlstat                84\n#define __NR_readlink                85\n#define __NR_uselib                  86\n#define __NR_swapon                  87\n#define __NR_reboot                  88\n#define __NR_readdir                 89\n#define __NR_mmap                    90\n#define __NR_munmap                  91\n#define __NR_truncate                92\n#define __NR_ftruncate               93\n#define __NR_fchmod                  94\n#define __NR_fchown                  95\n#define __NR_getpriority             96\n#define __NR_setpriority             97\n#define __NR_profil                  98\n#define __NR_statfs                  99\n#define __NR_fstatfs                100\n#define __NR_ioperm                 101\n#define __NR_socketcall             102\n#define __NR_syslog                 103\n#define __NR_setitimer              104\n#define __NR_getitimer              105\n#define __NR_stat                   106\n#define __NR_lstat                  107\n#define __NR_fstat                  108\n#define __NR_olduname               109\n#define __NR_iopl                   110\n#define __NR_vhangup                111\n#define __NR_idle                   112\n#define __NR_vm86                   113\n#define __NR_wait4                  114\n#define __NR_swapoff                115\n#define __NR_sysinfo                116\n#define __NR_ipc                    117\n#define __NR_fsync                  118\n#define __NR_sigreturn              119\n#define __NR_clone                  120\n#define __NR_setdomainname          121\n#define __NR_uname                  122\n#define __NR_modify_ldt             123\n#define __NR_adjtimex               124\n#define __NR_mprotect               125\n#define __NR_sigprocmask            126\n#define __NR_create_module          127\n#define __NR_init_module            128\n#define __NR_delete_module          129\n#define __NR_get_kernel_syms        130\n#define __NR_quotactl               131\n#define __NR_getpgid                132\n#define __NR_fchdir                 133\n#define __NR_bdflush                134\n#define __NR_sysfs                  135\n#define __NR_personality            136\n#define __NR_afs_syscall            137\n#define __NR_setfsuid               138\n#define __NR_setfsgid               139\n#define __NR__llseek                140\n#define __NR_getdents               141\n#define __NR__newselect             142\n#define __NR_flock                  143\n#define __NR_msync                  144\n#define __NR_readv                  145\n#define __NR_writev                 146\n#define __NR_getsid                 147\n#define __NR_fdatasync              148\n#define __NR__sysctl                149\n#define __NR_mlock                  150\n#define __NR_munlock                151\n#define __NR_mlockall               152\n#define __NR_munlockall             153\n#define __NR_sched_setparam         154\n#define __NR_sched_getparam         155\n#define __NR_sched_setscheduler     156\n#define __NR_sched_getscheduler     157\n#define __NR_sched_yield            158\n#define __NR_sched_get_priority_max 159\n#define __NR_sched_get_priority_min 160\n#define __NR_sched_rr_get_interval  161\n#define __NR_nanosleep              162\n#define __NR_mremap                 163\n#define __NR_setresuid              164\n#define __NR_getresuid              165\n#define __NR_query_module           166\n#define __NR_poll                   167\n#define __NR_nfsservctl             168\n#define __NR_setresgid              169\n#define __NR_getresgid              170\n#define __NR_prctl                  171\n#define __NR_rt_sigreturn           172\n#define __NR_rt_sigaction           173\n#define __NR_rt_sigprocmask         174\n#define __NR_rt_sigpending          175\n#define __NR_rt_sigtimedwait        176\n#define __NR_rt_sigqueueinfo        177\n#define __NR_rt_sigsuspend          178\n#define __NR_pread64                179\n#define __NR_pwrite64               180\n#define __NR_chown                  181\n#define __NR_getcwd                 182\n#define __NR_capget                 183\n#define __NR_capset                 184\n#define __NR_sigaltstack            185\n#define __NR_sendfile               186\n#define __NR_getpmsg                187\n#define __NR_putpmsg                188\n#define __NR_vfork                  189\n#define __NR_ugetrlimit             190\n#define __NR_readahead              191\n#define __NR_pciconfig_read         198\n#define __NR_pciconfig_write        199\n#define __NR_pciconfig_iobase       200\n#define __NR_multiplexer            201\n#define __NR_getdents64             202\n#define __NR_pivot_root             203\n#define __NR_madvise                205\n#define __NR_mincore                206\n#define __NR_gettid                 207\n#define __NR_tkill                  208\n#define __NR_setxattr               209\n#define __NR_lsetxattr              210\n#define __NR_fsetxattr              211\n#define __NR_getxattr               212\n#define __NR_lgetxattr              213\n#define __NR_fgetxattr              214\n#define __NR_listxattr              215\n#define __NR_llistxattr             216\n#define __NR_flistxattr             217\n#define __NR_removexattr            218\n#define __NR_lremovexattr           219\n#define __NR_fremovexattr           220\n#define __NR_futex                  221\n#define __NR_sched_setaffinity      222\n#define __NR_sched_getaffinity      223\n#define __NR_tuxcall                225\n#define __NR_io_setup               227\n#define __NR_io_destroy             228\n#define __NR_io_getevents           229\n#define __NR_io_submit              230\n#define __NR_io_cancel              231\n#define __NR_set_tid_address        232\n#define __NR_fadvise64              233\n#define __NR_exit_group             234\n#define __NR_lookup_dcookie         235\n#define __NR_epoll_create           236\n#define __NR_epoll_ctl              237\n#define __NR_epoll_wait             238\n#define __NR_remap_file_pages       239\n#define __NR_timer_create           240\n#define __NR_timer_settime          241\n#define __NR_timer_gettime          242\n#define __NR_timer_getoverrun       243\n#define __NR_timer_delete           244\n#define __NR_clock_settime          245\n#define __NR_clock_gettime          246\n#define __NR_clock_getres           247\n#define __NR_clock_nanosleep        248\n#define __NR_swapcontext            249\n#define __NR_tgkill                 250\n#define __NR_utimes                 251\n#define __NR_statfs64               252\n#define __NR_fstatfs64              253\n#define __NR_rtas                   255\n#define __NR_sys_debug_setcontext   256\n#define __NR_migrate_pages          258\n#define __NR_mbind                  259\n#define __NR_get_mempolicy          260\n#define __NR_set_mempolicy          261\n#define __NR_mq_open                262\n#define __NR_mq_unlink              263\n#define __NR_mq_timedsend           264\n#define __NR_mq_timedreceive        265\n#define __NR_mq_notify              266\n#define __NR_mq_getsetattr          267\n#define __NR_kexec_load             268\n#define __NR_add_key                269\n#define __NR_request_key            270\n#define __NR_keyctl                 271\n#define __NR_waitid                 272\n#define __NR_ioprio_set             273\n#define __NR_ioprio_get             274\n#define __NR_inotify_init           275\n#define __NR_inotify_add_watch      276\n#define __NR_inotify_rm_watch       277\n#define __NR_spu_run                278\n#define __NR_spu_create             279\n#define __NR_pselect6               280\n#define __NR_ppoll                  281\n#define __NR_unshare                282\n#define __NR_splice                 283\n#define __NR_tee                    284\n#define __NR_vmsplice               285\n#define __NR_openat                 286\n#define __NR_mkdirat                287\n#define __NR_mknodat                288\n#define __NR_fchownat               289\n#define __NR_futimesat              290\n#define __NR_newfstatat             291\n#define __NR_unlinkat               292\n#define __NR_renameat               293\n#define __NR_linkat                 294\n#define __NR_symlinkat              295\n#define __NR_readlinkat             296\n#define __NR_fchmodat               297\n#define __NR_faccessat              298\n#define __NR_get_robust_list        299\n#define __NR_set_robust_list        300\n#define __NR_move_pages             301\n#define __NR_getcpu                 302\n#define __NR_epoll_pwait            303\n#define __NR_utimensat              304\n#define __NR_signalfd               305\n#define __NR_timerfd_create         306\n#define __NR_eventfd                307\n#define __NR_sync_file_range2       308\n#define __NR_fallocate              309\n#define __NR_subpage_prot           310\n#define __NR_timerfd_settime        311\n#define __NR_timerfd_gettime        312\n#define __NR_signalfd4              313\n#define __NR_eventfd2               314\n#define __NR_epoll_create1          315\n#define __NR_dup3                   316\n#define __NR_pipe2                  317\n#define __NR_inotify_init1          318\n#define __NR_perf_event_open        319\n#define __NR_preadv                 320\n#define __NR_pwritev                321\n#define __NR_rt_tgsigqueueinfo      322\n#define __NR_fanotify_init          323\n#define __NR_fanotify_mark          324\n#define __NR_prlimit64              325\n#define __NR_socket                 326\n#define __NR_bind                   327\n#define __NR_connect                328\n#define __NR_listen                 329\n#define __NR_accept                 330\n#define __NR_getsockname            331\n#define __NR_getpeername            332\n#define __NR_socketpair             333\n#define __NR_send                   334\n#define __NR_sendto                 335\n#define __NR_recv                   336\n#define __NR_recvfrom               337\n#define __NR_shutdown               338\n#define __NR_setsockopt             339\n#define __NR_getsockopt             340\n#define __NR_sendmsg                341\n#define __NR_recvmsg                342\n#define __NR_recvmmsg               343\n#define __NR_accept4                344\n#define __NR_name_to_handle_at      345\n#define __NR_open_by_handle_at      346\n#define __NR_clock_adjtime          347\n#define __NR_syncfs                 348\n#define __NR_sendmmsg               349\n#define __NR_setns                  350\n#define __NR_process_vm_readv       351\n#define __NR_process_vm_writev      352\n#define __NR_finit_module           353\n#define __NR_kcmp                   354\n#define __NR_sched_setattr          355\n#define __NR_sched_getattr          356\n#define __NR_renameat2              357\n#define __NR_seccomp                358\n#define __NR_getrandom              359\n#define __NR_memfd_create           360\n#define __NR_bpf                    361\n#define __NR_execveat               362\n#define __NR_switch_endian          363\n#define __NR_userfaultfd            364\n#define __NR_membarrier             365\n#define __NR_mlock2                 378\n#define __NR_copy_file_range        379\n#define __NR_preadv2                380\n#define __NR_pwritev2               381\n#define __NR_kexec_file_load        382\n#define __NR_statx                  383\n#define __NR_pkey_alloc             384\n#define __NR_pkey_free              385\n#define __NR_pkey_mprotect          386\n#define __NR_rseq                   387\n#define __NR_io_pgetevents          388\n#define __NR_semtimedop             392\n#define __NR_semget                 393\n#define __NR_semctl                 394\n#define __NR_shmget                 395\n#define __NR_shmctl                 396\n#define __NR_shmat                  397\n#define __NR_shmdt                  398\n#define __NR_msgget                 399\n#define __NR_msgsnd                 400\n#define __NR_msgrcv                 401\n#define __NR_msgctl                 402\n#define __NR_pidfd_send_signal      424\n#define __NR_io_uring_setup         425\n#define __NR_io_uring_enter         426\n#define __NR_io_uring_register      427\n#define __NR_open_tree\t\t428\n#define __NR_move_mount\t\t429\n#define __NR_fsopen\t\t430\n#define __NR_fsconfig\t\t431\n#define __NR_fsmount\t\t432\n#define __NR_fspick\t\t433\n#define __NR_pidfd_open\t\t434\n#define __NR_clone3\t\t435\n#define __NR_close_range\t436\n#define __NR_openat2\t\t437\n#define __NR_pidfd_getfd\t438\n#define __NR_faccessat2\t\t439\n\n"
  },
  {
    "path": "user.libc/arch/powerpc64/bits/termios.h",
    "content": "#undef NCCS\n#define NCCS 19\nstruct termios {\n\ttcflag_t c_iflag;\n\ttcflag_t c_oflag;\n\ttcflag_t c_cflag;\n\ttcflag_t c_lflag;\n\tcc_t c_cc[NCCS];\n\tcc_t c_line;\n\tspeed_t __c_ispeed;\n\tspeed_t __c_ospeed;\n};\n\n#define VINTR     0\n#define VQUIT     1\n#define VERASE    2\n#define VKILL     3\n#define VEOF      4\n#define VMIN      5\n#define VEOL      6\n#define VTIME     7\n#define VEOL2     8\n#define VSWTC     9\n#define VWERASE  10\n#define VREPRINT 11\n#define VSUSP    12\n#define VSTART   13\n#define VSTOP    14\n#define VLNEXT   15\n#define VDISCARD 16\n\n#define IGNBRK  0000001\n#define BRKINT  0000002\n#define IGNPAR  0000004\n#define PARMRK  0000010\n#define INPCK   0000020\n#define ISTRIP  0000040\n#define INLCR   0000100\n#define IGNCR   0000200\n#define ICRNL   0000400\n#define IXON    0001000\n#define IXOFF   0002000\n#define IXANY   0004000\n#define IUCLC   0010000\n#define IMAXBEL 0020000\n#define IUTF8   0040000\n\n#define OPOST  0000001\n#define ONLCR  0000002\n#define OLCUC  0000004\n#define OCRNL  0000010\n#define ONOCR  0000020\n#define ONLRET 0000040\n#define OFILL  0000100\n#define OFDEL  0000200\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_XOPEN_SOURCE)\n#define NLDLY  0001400\n#define NL0    0000000\n#define NL1    0000400\n#define NL2    0001000\n#define NL3    0001400\n#define TABDLY 0006000\n#define TAB0   0000000\n#define TAB1   0002000\n#define TAB2   0004000\n#define TAB3   0006000\n#define CRDLY  0030000\n#define CR0    0000000\n#define CR1    0010000\n#define CR2    0020000\n#define CR3    0030000\n#define FFDLY  0040000\n#define FF0    0000000\n#define FF1    0040000\n#define BSDLY  0100000\n#define BS0    0000000\n#define BS1    0100000\n#endif\n\n#define VTDLY  0200000\n#define VT0    0000000\n#define VT1    0200000\n\n#define B0       0000000\n#define B50      0000001\n#define B75      0000002\n#define B110     0000003\n#define B134     0000004\n#define B150     0000005\n#define B200     0000006\n#define B300     0000007\n#define B600     0000010\n#define B1200    0000011\n#define B1800    0000012\n#define B2400    0000013\n#define B4800    0000014\n#define B9600    0000015\n#define B19200   0000016\n#define B38400   0000017\n\n#define B57600   00020\n#define B115200  00021\n#define B230400  00022\n#define B460800  00023\n#define B500000  00024\n#define B576000  00025\n#define B921600  00026\n#define B1000000 00027\n#define B1152000 00030\n#define B1500000 00031\n#define B2000000 00032\n#define B2500000 00033\n#define B3000000 00034\n#define B3500000 00035\n#define B4000000 00036\n\n#define CSIZE  00001400\n#define CS5    00000000\n#define CS6    00000400\n#define CS7    00001000\n#define CS8    00001400\n#define CSTOPB 00002000\n#define CREAD  00004000\n#define PARENB 00010000\n#define PARODD 00020000\n#define HUPCL  00040000\n#define CLOCAL 00100000\n\n#define ECHOE   0x00000002\n#define ECHOK   0x00000004\n#define ECHO    0x00000008\n#define ECHONL  0x00000010\n#define ISIG    0x00000080\n#define ICANON  0x00000100\n#define IEXTEN  0x00000400\n#define TOSTOP  0x00400000\n#define NOFLSH  0x80000000\n\n#define TCOOFF 0\n#define TCOON  1\n#define TCIOFF 2\n#define TCION  3\n\n#define TCIFLUSH  0\n#define TCOFLUSH  1\n#define TCIOFLUSH 2\n\n#define TCSANOW   0\n#define TCSADRAIN 1\n#define TCSAFLUSH 2\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define EXTA    0000016\n#define EXTB    0000017\n#define CBAUD   00377\n#define CBAUDEX 0000020\n#define CIBAUD  077600000\n#define CMSPAR  010000000000\n#define CRTSCTS 020000000000\n\n#define XCASE   0x00004000\n#define ECHOCTL 0x00000040\n#define ECHOPRT 0x00000020\n#define ECHOKE  0x00000001\n#define FLUSHO  0x00800000\n#define PENDIN  0x20000000\n#define EXTPROC 0x10000000\n\n#define XTABS   00006000\n#define TIOCSER_TEMT 1\n#endif\n"
  },
  {
    "path": "user.libc/arch/powerpc64/bits/user.h",
    "content": "struct user {\n\tstruct {\n\t\tunsigned long gpr[32], nip, msr, orig_gpr3, ctr, link, xer, ccr, softe;\n\t\tunsigned long trap, dar, dsisr, result;\n\t} regs;\n\tunsigned long u_tsize, u_dsize, u_ssize;\n\tunsigned long start_code, start_data, start_stack;\n\tlong signal;\n\tvoid *u_ar0;\n\tunsigned long magic;\n\tchar u_comm[32];\n};\n\n#define ELF_NGREG 48\n#define ELF_NFPREG 33\n#define ELF_NVRREG 34\ntypedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG];\ntypedef double elf_fpreg_t, elf_fpregset_t[ELF_NFPREG];\ntypedef struct { unsigned u[4]; }\n#ifdef __GNUC__\n__attribute__((__aligned__(16)))\n#endif\n\telf_vrreg_t, elf_vrregset_t[ELF_NVRREG];\n"
  },
  {
    "path": "user.libc/arch/powerpc64/crt_arch.h",
    "content": "__asm__(\n\".text \\n\"\n\".global \" START \" \\n\"\n\".type   \" START \", %function \\n\"\nSTART \": \\n\"\n\"\taddis  2, 12, .TOC.-\" START \"@ha \\n\"\n\"\taddi   2,  2, .TOC.-\" START \"@l \\n\"\n\"\tlwz    4, 1f-\" START \"(12)\\n\"\n\"\tadd    4, 4, 12 \\n\"\n\"\tmr     3, 1 \\n\"\n\"\tclrrdi 1, 1, 4 \\n\"\n\"\tli     0, 0 \\n\"\n\"\tstdu   0, -32(1) \\n\"\n\"\tmtlr   0 \\n\"\n\"\tbl \" START \"_c \\n\"\n\".weak   _DYNAMIC \\n\"\n\".hidden _DYNAMIC \\n\"\n\"1:\t.long _DYNAMIC-\" START \"\\n\"\n);\n"
  },
  {
    "path": "user.libc/arch/powerpc64/kstat.h",
    "content": "struct kstat {\n\tdev_t st_dev;\n\tino_t st_ino;\n\tnlink_t st_nlink;\n\tmode_t st_mode;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tdev_t st_rdev;\n\toff_t st_size;\n\tblksize_t st_blksize;\n\tblkcnt_t st_blocks;\n\tlong st_atime_sec;\n\tlong st_atime_nsec;\n\tlong st_mtime_sec;\n\tlong st_mtime_nsec;\n\tlong st_ctime_sec;\n\tlong st_ctime_nsec;\n\tunsigned long __unused[3];\n};\n"
  },
  {
    "path": "user.libc/arch/powerpc64/pthread_arch.h",
    "content": "static inline uintptr_t __get_tp()\n{\n\tregister uintptr_t tp __asm__(\"r13\");\n\t__asm__ (\"\" : \"=r\" (tp) );\n\treturn tp;\n}\n\n#define TLS_ABOVE_TP\n#define GAP_ABOVE_TP 0\n\n#define TP_OFFSET 0x7000\n#define DTP_OFFSET 0x8000\n\n// the kernel calls the ip \"nip\", it's the first saved value after the 32\n// GPRs.\n#define MC_PC gp_regs[32]\n"
  },
  {
    "path": "user.libc/arch/powerpc64/reloc.h",
    "content": "#if __BYTE_ORDER == __LITTLE_ENDIAN\n#define ENDIAN_SUFFIX \"le\"\n#else\n#define ENDIAN_SUFFIX \"\"\n#endif\n\n#define LDSO_ARCH \"powerpc64\" ENDIAN_SUFFIX\n\n#define TPOFF_K (-0x7000)\n\n#define REL_SYMBOLIC    R_PPC64_ADDR64\n#define REL_USYMBOLIC   R_PPC64_UADDR64\n#define REL_GOT         R_PPC64_GLOB_DAT\n#define REL_PLT         R_PPC64_JMP_SLOT\n#define REL_RELATIVE    R_PPC64_RELATIVE\n#define REL_COPY        R_PPC64_COPY\n#define REL_DTPMOD      R_PPC64_DTPMOD64\n#define REL_DTPOFF      R_PPC64_DTPREL64\n#define REL_TPOFF       R_PPC64_TPREL64\n\n#define CRTJMP(pc,sp) __asm__ __volatile__( \\\n\t\"mr 1,%1; mr 12,%0; mtctr 12; bctrl\" : : \"r\"(pc), \"r\"(sp) : \"memory\" )\n\n#define GETFUNCSYM(fp, sym, got) __asm__ ( \\\n\t\".hidden \" #sym \" \\n\" \\\n\t\"\tbl 1f \\n\" \\\n\t\"\t.long \" #sym \"-. \\n\" \\\n\t\"1:\tmflr %1 \\n\" \\\n\t\"\tlwa %0, 0(%1) \\n\" \\\n\t\"\tadd %0, %0, %1 \\n\" \\\n\t: \"=r\"(*(fp)), \"=r\"((long){0}) : : \"memory\", \"lr\" )\n"
  },
  {
    "path": "user.libc/arch/powerpc64/syscall_arch.h",
    "content": "#define __SYSCALL_LL_E(x) (x)\n#define __SYSCALL_LL_O(x) (x)\n\nstatic inline long __syscall0(long n)\n{\n\tregister long r0 __asm__(\"r0\") = n;\n\tregister long r3 __asm__(\"r3\");\n\t__asm__ __volatile__(\"sc ; bns+ 1f ; neg %1, %1 ; 1:\"\n\t: \"+r\"(r0), \"=r\"(r3)\n\t:: \"memory\", \"cr0\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\");\n\treturn r3;\n}\n\nstatic inline long __syscall1(long n, long a)\n{\n\tregister long r0 __asm__(\"r0\") = n;\n\tregister long r3 __asm__(\"r3\") = a;\n\t__asm__ __volatile__(\"sc ; bns+ 1f ; neg %1, %1 ; 1:\"\n\t: \"+r\"(r0), \"+r\"(r3)\n\t:: \"memory\", \"cr0\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\");\n\treturn r3;\n}\n\nstatic inline long __syscall2(long n, long a, long b)\n{\n\tregister long r0 __asm__(\"r0\") = n;\n\tregister long r3 __asm__(\"r3\") = a;\n\tregister long r4 __asm__(\"r4\") = b;\n\t__asm__ __volatile__(\"sc ; bns+ 1f ; neg %1, %1 ; 1:\"\n\t: \"+r\"(r0), \"+r\"(r3), \"+r\"(r4)\n\t:: \"memory\", \"cr0\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\");\n\treturn r3;\n}\n\nstatic inline long __syscall3(long n, long a, long b, long c)\n{\n\tregister long r0 __asm__(\"r0\") = n;\n\tregister long r3 __asm__(\"r3\") = a;\n\tregister long r4 __asm__(\"r4\") = b;\n\tregister long r5 __asm__(\"r5\") = c;\n\t__asm__ __volatile__(\"sc ; bns+ 1f ; neg %1, %1 ; 1:\"\n\t: \"+r\"(r0), \"+r\"(r3), \"+r\"(r4), \"+r\"(r5)\n\t:: \"memory\", \"cr0\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\");\n\treturn r3;\n}\n\nstatic inline long __syscall4(long n, long a, long b, long c, long d)\n{\n\tregister long r0 __asm__(\"r0\") = n;\n\tregister long r3 __asm__(\"r3\") = a;\n\tregister long r4 __asm__(\"r4\") = b;\n\tregister long r5 __asm__(\"r5\") = c;\n\tregister long r6 __asm__(\"r6\") = d;\n\t__asm__ __volatile__(\"sc ; bns+ 1f ; neg %1, %1 ; 1:\"\n\t: \"+r\"(r0), \"+r\"(r3), \"+r\"(r4), \"+r\"(r5), \"+r\"(r6)\n\t:: \"memory\", \"cr0\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\");\n\treturn r3;\n}\n\nstatic inline long __syscall5(long n, long a, long b, long c, long d, long e)\n{\n\tregister long r0 __asm__(\"r0\") = n;\n\tregister long r3 __asm__(\"r3\") = a;\n\tregister long r4 __asm__(\"r4\") = b;\n\tregister long r5 __asm__(\"r5\") = c;\n\tregister long r6 __asm__(\"r6\") = d;\n\tregister long r7 __asm__(\"r7\") = e;\n\t__asm__ __volatile__(\"sc ; bns+ 1f ; neg %1, %1 ; 1:\"\n\t: \"+r\"(r0), \"+r\"(r3), \"+r\"(r4), \"+r\"(r5), \"+r\"(r6), \"+r\"(r7)\n\t:: \"memory\", \"cr0\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\");\n\treturn r3;\n}\n\nstatic inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)\n{\n\tregister long r0 __asm__(\"r0\") = n;\n\tregister long r3 __asm__(\"r3\") = a;\n\tregister long r4 __asm__(\"r4\") = b;\n\tregister long r5 __asm__(\"r5\") = c;\n\tregister long r6 __asm__(\"r6\") = d;\n\tregister long r7 __asm__(\"r7\") = e;\n\tregister long r8 __asm__(\"r8\") = f;\n\t__asm__ __volatile__(\"sc ; bns+ 1f ; neg %1, %1 ; 1:\"\n\t: \"+r\"(r0), \"+r\"(r3), \"+r\"(r4), \"+r\"(r5), \"+r\"(r6), \"+r\"(r7), \"+r\"(r8)\n\t:: \"memory\", \"cr0\", \"r9\", \"r10\", \"r11\", \"r12\");\n\treturn r3;\n}\n\n#define SO_RCVTIMEO_OLD  18\n#define SO_SNDTIMEO_OLD  19\n"
  },
  {
    "path": "user.libc/arch/riscv64/atomic_arch.h",
    "content": "#define a_barrier a_barrier\nstatic inline void a_barrier()\n{\n\t__asm__ __volatile__ (\"fence rw,rw\" : : : \"memory\");\n}\n\n#define a_cas a_cas\nstatic inline int a_cas(volatile int *p, int t, int s)\n{\n\tint old, tmp;\n\t__asm__ __volatile__ (\n\t\t\"\\n1:\tlr.w.aqrl %0, (%2)\\n\"\n\t\t\"\tbne %0, %3, 1f\\n\"\n\t\t\"\tsc.w.aqrl %1, %4, (%2)\\n\"\n\t\t\"\tbnez %1, 1b\\n\"\n\t\t\"1:\"\n\t\t: \"=&r\"(old), \"=&r\"(tmp)\n\t\t: \"r\"(p), \"r\"((long)t), \"r\"((long)s)\n\t\t: \"memory\");\n\treturn old;\n}\n\n#define a_cas_p a_cas_p\nstatic inline void *a_cas_p(volatile void *p, void *t, void *s)\n{\n\tvoid *old;\n\tint tmp;\n\t__asm__ __volatile__ (\n\t\t\"\\n1:\tlr.d.aqrl %0, (%2)\\n\"\n\t\t\"\tbne %0, %3, 1f\\n\"\n\t\t\"\tsc.d.aqrl %1, %4, (%2)\\n\"\n\t\t\"\tbnez %1, 1b\\n\"\n\t\t\"1:\"\n\t\t: \"=&r\"(old), \"=&r\"(tmp)\n\t\t: \"r\"(p), \"r\"(t), \"r\"(s)\n\t\t: \"memory\");\n\treturn old;\n}\n"
  },
  {
    "path": "user.libc/arch/riscv64/bits/alltypes.h.in",
    "content": "#define _Addr long\n#define _Int64 long\n#define _Reg long\n\n#define __BYTE_ORDER 1234\n#define __LONG_MAX 0x7fffffffffffffffL\n\n#ifndef __cplusplus\nTYPEDEF int wchar_t;\n#endif\n\nTYPEDEF int blksize_t;\nTYPEDEF unsigned int nlink_t;\n\nTYPEDEF float float_t;\nTYPEDEF double double_t;\n\nTYPEDEF struct { long long __ll; long double __ld; } max_align_t;\n"
  },
  {
    "path": "user.libc/arch/riscv64/bits/fenv.h",
    "content": "#define FE_INVALID      16\n#define FE_DIVBYZERO    8\n#define FE_OVERFLOW     4\n#define FE_UNDERFLOW    2\n#define FE_INEXACT      1\n\n#define FE_ALL_EXCEPT   31\n\n#define FE_TONEAREST    0\n#define FE_DOWNWARD     2\n#define FE_UPWARD       3\n#define FE_TOWARDZERO   1\n\ntypedef unsigned int fexcept_t;\ntypedef unsigned int fenv_t;\n\n#define FE_DFL_ENV      ((const fenv_t *) -1)\n"
  },
  {
    "path": "user.libc/arch/riscv64/bits/float.h",
    "content": "#define FLT_EVAL_METHOD 0\n\n#define LDBL_TRUE_MIN 6.47517511943802511092443895822764655e-4966L\n#define LDBL_MIN 3.36210314311209350626267781732175260e-4932L\n#define LDBL_MAX 1.18973149535723176508575932662800702e+4932L\n#define LDBL_EPSILON 1.92592994438723585305597794258492732e-34L\n\n#define LDBL_MANT_DIG 113\n#define LDBL_MIN_EXP (-16381)\n#define LDBL_MAX_EXP 16384\n\n#define LDBL_DIG 33\n#define LDBL_MIN_10_EXP (-4931)\n#define LDBL_MAX_10_EXP 4932\n\n#define DECIMAL_DIG 36\n"
  },
  {
    "path": "user.libc/arch/riscv64/bits/posix.h",
    "content": "#define _POSIX_V6_LP64_OFF64 1\n#define _POSIX_V7_LP64_OFF64 1\n"
  },
  {
    "path": "user.libc/arch/riscv64/bits/reg.h",
    "content": "#undef __WORDSIZE\n#define __WORDSIZE 64\n"
  },
  {
    "path": "user.libc/arch/riscv64/bits/setjmp.h",
    "content": "typedef unsigned long __jmp_buf[26];\n"
  },
  {
    "path": "user.libc/arch/riscv64/bits/signal.h",
    "content": "#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n# define MINSIGSTKSZ 2048\n# define SIGSTKSZ 8192\n#endif\n\ntypedef unsigned long __riscv_mc_gp_state[32];\n\nstruct __riscv_mc_f_ext_state {\n\tunsigned int __f[32];\n\tunsigned int __fcsr;\n};\n\nstruct __riscv_mc_d_ext_state {\n\tunsigned long long __f[32];\n\tunsigned int __fcsr;\n};\n\nstruct __riscv_mc_q_ext_state {\n\tunsigned long long __f[64] __attribute__((aligned(16)));\n\tunsigned int __fcsr;\n\tunsigned int __reserved[3];\n};\n\nunion __riscv_mc_fp_state {\n\tstruct __riscv_mc_f_ext_state __f;\n\tstruct __riscv_mc_d_ext_state __d;\n\tstruct __riscv_mc_q_ext_state __q;\n};\n\ntypedef struct mcontext_t {\n\t__riscv_mc_gp_state __gregs;\n\tunion __riscv_mc_fp_state __fpregs;\n} mcontext_t;\n\n#if defined(_GNU_SOURCE)\n#define REG_PC 0\n#define REG_RA 1\n#define REG_SP 2\n#define REG_TP 4\n#define REG_S0 8\n#define REG_A0 10\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\ntypedef unsigned long greg_t;\ntypedef unsigned long gregset_t[32];\ntypedef union __riscv_mc_fp_state fpregset_t;\nstruct sigcontext {\n\tgregset_t gregs;\n\tfpregset_t fpregs;\n};\n#endif\n\nstruct sigaltstack {\n\tvoid *ss_sp;\n\tint ss_flags;\n\tsize_t ss_size;\n};\n\ntypedef struct __ucontext\n{\n\tunsigned long uc_flags;\n\tstruct __ucontext *uc_link;\n\tstack_t uc_stack;\n\tsigset_t uc_sigmask;\n\tmcontext_t uc_mcontext;\n} ucontext_t;\n\n#define SA_NOCLDSTOP 1\n#define SA_NOCLDWAIT 2\n#define SA_SIGINFO   4\n#define SA_ONSTACK   0x08000000\n#define SA_RESTART   0x10000000\n#define SA_NODEFER   0x40000000\n#define SA_RESETHAND 0x80000000\n#define SA_RESTORER  0x04000000\n\n#endif\n\n#define SIGHUP     1\n#define SIGINT     2\n#define SIGQUIT    3\n#define SIGILL     4\n#define SIGTRAP    5\n#define SIGABRT    6\n#define SIGIOT     SIGABRT\n#define SIGBUS     7\n#define SIGFPE     8\n#define SIGKILL    9\n#define SIGUSR1   10\n#define SIGSEGV   11\n#define SIGUSR2   12\n#define SIGPIPE   13\n#define SIGALRM   14\n#define SIGTERM   15\n#define SIGSTKFLT 16\n#define SIGCHLD   17\n#define SIGCONT   18\n#define SIGSTOP   19\n#define SIGTSTP   20\n#define SIGTTIN   21\n#define SIGTTOU   22\n#define SIGURG    23\n#define SIGXCPU   24\n#define SIGXFSZ   25\n#define SIGVTALRM 26\n#define SIGPROF   27\n#define SIGWINCH  28\n#define SIGIO     29\n#define SIGPOLL   SIGIO\n#define SIGPWR    30\n#define SIGSYS    31\n#define SIGUNUSED SIGSYS\n\n#define _NSIG     65\n"
  },
  {
    "path": "user.libc/arch/riscv64/bits/stat.h",
    "content": "struct stat {\n\tdev_t st_dev;\n\tino_t st_ino;\n\tmode_t st_mode;\n\tnlink_t st_nlink;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tdev_t st_rdev;\n\tunsigned long __pad;\n\toff_t st_size;\n\tblksize_t st_blksize;\n\tint __pad2;\n\tblkcnt_t st_blocks;\n\tstruct timespec st_atim;\n\tstruct timespec st_mtim;\n\tstruct timespec st_ctim;\n\tunsigned __unused[2];\n};\n"
  },
  {
    "path": "user.libc/arch/riscv64/bits/stdint.h",
    "content": "typedef int32_t int_fast16_t;\ntypedef int32_t int_fast32_t;\ntypedef uint32_t uint_fast16_t;\ntypedef uint32_t uint_fast32_t;\n\n#define INT_FAST16_MIN  INT32_MIN\n#define INT_FAST32_MIN  INT32_MIN\n\n#define INT_FAST16_MAX  INT32_MAX\n#define INT_FAST32_MAX  INT32_MAX\n\n#define UINT_FAST16_MAX UINT32_MAX\n#define UINT_FAST32_MAX UINT32_MAX\n\n#define INTPTR_MIN      INT64_MIN\n#define INTPTR_MAX      INT64_MAX\n#define UINTPTR_MAX     UINT64_MAX\n#define PTRDIFF_MIN     INT64_MIN\n#define PTRDIFF_MAX     INT64_MAX\n#define SIZE_MAX        UINT64_MAX\n"
  },
  {
    "path": "user.libc/arch/riscv64/bits/syscall.h.in",
    "content": "#define __NR_io_setup 0\n#define __NR_io_destroy 1\n#define __NR_io_submit 2\n#define __NR_io_cancel 3\n#define __NR_io_getevents 4\n#define __NR_setxattr 5\n#define __NR_lsetxattr 6\n#define __NR_fsetxattr 7\n#define __NR_getxattr 8\n#define __NR_lgetxattr 9\n#define __NR_fgetxattr 10\n#define __NR_listxattr 11\n#define __NR_llistxattr 12\n#define __NR_flistxattr 13\n#define __NR_removexattr 14\n#define __NR_lremovexattr 15\n#define __NR_fremovexattr 16\n#define __NR_getcwd 17\n#define __NR_lookup_dcookie 18\n#define __NR_eventfd2 19\n#define __NR_epoll_create1 20\n#define __NR_epoll_ctl 21\n#define __NR_epoll_pwait 22\n#define __NR_dup 23\n#define __NR_dup3 24\n#define __NR_fcntl 25\n#define __NR_inotify_init1 26\n#define __NR_inotify_add_watch 27\n#define __NR_inotify_rm_watch 28\n#define __NR_ioctl 29\n#define __NR_ioprio_set 30\n#define __NR_ioprio_get 31\n#define __NR_flock 32\n#define __NR_mknodat 33\n#define __NR_mkdirat 34\n#define __NR_unlinkat 35\n#define __NR_symlinkat 36\n#define __NR_linkat 37\n#define __NR_umount2 39\n#define __NR_mount 40\n#define __NR_pivot_root 41\n#define __NR_nfsservctl 42\n#define __NR_statfs 43\n#define __NR_fstatfs 44\n#define __NR_truncate 45\n#define __NR_ftruncate 46\n#define __NR_fallocate 47\n#define __NR_faccessat 48\n#define __NR_chdir 49\n#define __NR_fchdir 50\n#define __NR_chroot 51\n#define __NR_fchmod 52\n#define __NR_fchmodat 53\n#define __NR_fchownat 54\n#define __NR_fchown 55\n#define __NR_openat 56\n#define __NR_close 57\n#define __NR_vhangup 58\n#define __NR_pipe2 59\n#define __NR_quotactl 60\n#define __NR_getdents64 61\n#define __NR_lseek 62\n#define __NR_read 63\n#define __NR_write 64\n#define __NR_readv 65\n#define __NR_writev 66\n#define __NR_pread64 67\n#define __NR_pwrite64 68\n#define __NR_preadv 69\n#define __NR_pwritev 70\n#define __NR_sendfile 71\n#define __NR_pselect6 72\n#define __NR_ppoll 73\n#define __NR_signalfd4 74\n#define __NR_vmsplice 75\n#define __NR_splice 76\n#define __NR_tee 77\n#define __NR_readlinkat 78\n#define __NR_fstatat 79\n#define __NR_fstat 80\n#define __NR_sync 81\n#define __NR_fsync 82\n#define __NR_fdatasync 83\n#define __NR_sync_file_range 84\n#define __NR_timerfd_create 85\n#define __NR_timerfd_settime 86\n#define __NR_timerfd_gettime 87\n#define __NR_utimensat 88\n#define __NR_acct 89\n#define __NR_capget 90\n#define __NR_capset 91\n#define __NR_personality 92\n#define __NR_exit 93\n#define __NR_exit_group 94\n#define __NR_waitid 95\n#define __NR_set_tid_address 96\n#define __NR_unshare 97\n#define __NR_futex 98\n#define __NR_set_robust_list 99\n#define __NR_get_robust_list 100\n#define __NR_nanosleep 101\n#define __NR_getitimer 102\n#define __NR_setitimer 103\n#define __NR_kexec_load 104\n#define __NR_init_module 105\n#define __NR_delete_module 106\n#define __NR_timer_create 107\n#define __NR_timer_gettime 108\n#define __NR_timer_getoverrun 109\n#define __NR_timer_settime 110\n#define __NR_timer_delete 111\n#define __NR_clock_settime 112\n#define __NR_clock_gettime 113\n#define __NR_clock_getres 114\n#define __NR_clock_nanosleep 115\n#define __NR_syslog 116\n#define __NR_ptrace 117\n#define __NR_sched_setparam 118\n#define __NR_sched_setscheduler 119\n#define __NR_sched_getscheduler 120\n#define __NR_sched_getparam 121\n#define __NR_sched_setaffinity 122\n#define __NR_sched_getaffinity 123\n#define __NR_sched_yield 124\n#define __NR_sched_get_priority_max 125\n#define __NR_sched_get_priority_min 126\n#define __NR_sched_rr_get_interval 127\n#define __NR_restart_syscall 128\n#define __NR_kill 129\n#define __NR_tkill 130\n#define __NR_tgkill 131\n#define __NR_sigaltstack 132\n#define __NR_rt_sigsuspend 133\n#define __NR_rt_sigaction 134\n#define __NR_rt_sigprocmask 135\n#define __NR_rt_sigpending 136\n#define __NR_rt_sigtimedwait 137\n#define __NR_rt_sigqueueinfo 138\n#define __NR_rt_sigreturn 139\n#define __NR_setpriority 140\n#define __NR_getpriority 141\n#define __NR_reboot 142\n#define __NR_setregid 143\n#define __NR_setgid 144\n#define __NR_setreuid 145\n#define __NR_setuid 146\n#define __NR_setresuid 147\n#define __NR_getresuid 148\n#define __NR_setresgid 149\n#define __NR_getresgid 150\n#define __NR_setfsuid 151\n#define __NR_setfsgid 152\n#define __NR_times 153\n#define __NR_setpgid 154\n#define __NR_getpgid 155\n#define __NR_getsid 156\n#define __NR_setsid 157\n#define __NR_getgroups 158\n#define __NR_setgroups 159\n#define __NR_uname 160\n#define __NR_sethostname 161\n#define __NR_setdomainname 162\n#define __NR_getrlimit 163\n#define __NR_setrlimit 164\n#define __NR_getrusage 165\n#define __NR_umask 166\n#define __NR_prctl 167\n#define __NR_getcpu 168\n#define __NR_gettimeofday 169\n#define __NR_settimeofday 170\n#define __NR_adjtimex 171\n#define __NR_getpid 172\n#define __NR_getppid 173\n#define __NR_getuid 174\n#define __NR_geteuid 175\n#define __NR_getgid 176\n#define __NR_getegid 177\n#define __NR_gettid 178\n#define __NR_sysinfo 179\n#define __NR_mq_open 180\n#define __NR_mq_unlink 181\n#define __NR_mq_timedsend 182\n#define __NR_mq_timedreceive 183\n#define __NR_mq_notify 184\n#define __NR_mq_getsetattr 185\n#define __NR_msgget 186\n#define __NR_msgctl 187\n#define __NR_msgrcv 188\n#define __NR_msgsnd 189\n#define __NR_semget 190\n#define __NR_semctl 191\n#define __NR_semtimedop 192\n#define __NR_semop 193\n#define __NR_shmget 194\n#define __NR_shmctl 195\n#define __NR_shmat 196\n#define __NR_shmdt 197\n#define __NR_socket 198\n#define __NR_socketpair 199\n#define __NR_bind 200\n#define __NR_listen 201\n#define __NR_accept 202\n#define __NR_connect 203\n#define __NR_getsockname 204\n#define __NR_getpeername 205\n#define __NR_sendto 206\n#define __NR_recvfrom 207\n#define __NR_setsockopt 208\n#define __NR_getsockopt 209\n#define __NR_shutdown 210\n#define __NR_sendmsg 211\n#define __NR_recvmsg 212\n#define __NR_readahead 213\n#define __NR_brk 214\n#define __NR_munmap 215\n#define __NR_mremap 216\n#define __NR_add_key 217\n#define __NR_request_key 218\n#define __NR_keyctl 219\n#define __NR_clone 220\n#define __NR_execve 221\n#define __NR_mmap 222\n#define __NR_fadvise64 223\n#define __NR_swapon 224\n#define __NR_swapoff 225\n#define __NR_mprotect 226\n#define __NR_msync 227\n#define __NR_mlock 228\n#define __NR_munlock 229\n#define __NR_mlockall 230\n#define __NR_munlockall 231\n#define __NR_mincore 232\n#define __NR_madvise 233\n#define __NR_remap_file_pages 234\n#define __NR_mbind 235\n#define __NR_get_mempolicy 236\n#define __NR_set_mempolicy 237\n#define __NR_migrate_pages 238\n#define __NR_move_pages 239\n#define __NR_rt_tgsigqueueinfo 240\n#define __NR_perf_event_open 241\n#define __NR_accept4 242\n#define __NR_recvmmsg 243\n#define __NR_arch_specific_syscall 244\n#define __NR_wait4 260\n#define __NR_prlimit64 261\n#define __NR_fanotify_init 262\n#define __NR_fanotify_mark 263\n#define __NR_name_to_handle_at 264\n#define __NR_open_by_handle_at 265\n#define __NR_clock_adjtime 266\n#define __NR_syncfs 267\n#define __NR_setns 268\n#define __NR_sendmmsg 269\n#define __NR_process_vm_readv 270\n#define __NR_process_vm_writev 271\n#define __NR_kcmp 272\n#define __NR_finit_module 273\n#define __NR_sched_setattr 274\n#define __NR_sched_getattr 275\n#define __NR_renameat2 276\n#define __NR_seccomp 277\n#define __NR_getrandom 278\n#define __NR_memfd_create 279\n#define __NR_bpf 280\n#define __NR_execveat 281\n#define __NR_userfaultfd 282\n#define __NR_membarrier 283\n#define __NR_mlock2 284\n#define __NR_copy_file_range 285\n#define __NR_preadv2 286\n#define __NR_pwritev2 287\n#define __NR_pkey_mprotect 288\n#define __NR_pkey_alloc 289\n#define __NR_pkey_free 290\n#define __NR_statx 291\n#define __NR_io_pgetevents 292\n#define __NR_rseq 293\n#define __NR_kexec_file_load 294\n#define __NR_pidfd_send_signal 424\n#define __NR_io_uring_setup 425\n#define __NR_io_uring_enter 426\n#define __NR_io_uring_register 427\n#define __NR_open_tree\t\t428\n#define __NR_move_mount\t\t429\n#define __NR_fsopen\t\t430\n#define __NR_fsconfig\t\t431\n#define __NR_fsmount\t\t432\n#define __NR_fspick\t\t433\n#define __NR_pidfd_open\t\t434\n#define __NR_clone3\t\t435\n#define __NR_close_range\t436\n#define __NR_openat2\t\t437\n#define __NR_pidfd_getfd\t438\n#define __NR_faccessat2\t\t439\n\n#define __NR_sysriscv __NR_arch_specific_syscall\n#define __NR_riscv_flush_icache (__NR_sysriscv + 15)\n"
  },
  {
    "path": "user.libc/arch/riscv64/bits/user.h",
    "content": "#include <signal.h>\n\n#define ELF_NGREG 32\ntypedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG];\ntypedef union __riscv_mc_fp_state elf_fpregset_t;\n"
  },
  {
    "path": "user.libc/arch/riscv64/crt_arch.h",
    "content": "__asm__(\n\".section .sdata,\\\"aw\\\"\\n\"\n\".text\\n\"\n\".global \" START \"\\n\"\n\".type \" START \",%function\\n\"\nSTART \":\\n\"\n\".weak __global_pointer$\\n\"\n\".hidden __global_pointer$\\n\"\n\".option push\\n\"\n\".option norelax\\n\\t\"\n\"lla gp, __global_pointer$\\n\"\n\".option pop\\n\\t\"\n\"mv a0, sp\\n\"\n\".weak _DYNAMIC\\n\"\n\".hidden _DYNAMIC\\n\\t\"\n\"lla a1, _DYNAMIC\\n\\t\"\n\"andi sp, sp, -16\\n\\t\"\n\"tail \" START \"_c\"\n);\n"
  },
  {
    "path": "user.libc/arch/riscv64/kstat.h",
    "content": "struct kstat {\n\tdev_t st_dev;\n\tino_t st_ino;\n\tmode_t st_mode;\n\tnlink_t st_nlink;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tdev_t st_rdev;\n\tunsigned long __pad;\n\toff_t st_size;\n\tblksize_t st_blksize;\n\tint __pad2;\n\tblkcnt_t st_blocks;\n\tlong st_atime_sec;\n\tlong st_atime_nsec;\n\tlong st_mtime_sec;\n\tlong st_mtime_nsec;\n\tlong st_ctime_sec;\n\tlong st_ctime_nsec;\n\tunsigned __unused[2];\n};\n"
  },
  {
    "path": "user.libc/arch/riscv64/pthread_arch.h",
    "content": "static inline uintptr_t __get_tp()\n{\n\tuintptr_t tp;\n\t__asm__ __volatile__(\"mv %0, tp\" : \"=r\"(tp));\n\treturn tp;\n}\n\n#define TLS_ABOVE_TP\n#define GAP_ABOVE_TP 0\n\n#define DTP_OFFSET 0x800\n\n#define MC_PC __gregs[0]\n"
  },
  {
    "path": "user.libc/arch/riscv64/reloc.h",
    "content": "#if defined __riscv_float_abi_soft\n#define RISCV_FP_SUFFIX \"-sf\"\n#elif defined __riscv_float_abi_single\n#define RISCV_FP_SUFFIX \"-sp\"\n#elif defined __riscv_float_abi_double\n#define RISCV_FP_SUFFIX \"\"\n#endif\n\n#define LDSO_ARCH \"riscv64\" RISCV_FP_SUFFIX\n\n#define TPOFF_K 0\n\n#define REL_SYMBOLIC    R_RISCV_64\n#define REL_PLT         R_RISCV_JUMP_SLOT\n#define REL_RELATIVE    R_RISCV_RELATIVE\n#define REL_COPY        R_RISCV_COPY\n#define REL_DTPMOD      R_RISCV_TLS_DTPMOD64\n#define REL_DTPOFF      R_RISCV_TLS_DTPREL64\n#define REL_TPOFF       R_RISCV_TLS_TPREL64\n\n#define CRTJMP(pc,sp) __asm__ __volatile__( \\\n\t\"mv sp, %1 ; jr %0\" : : \"r\"(pc), \"r\"(sp) : \"memory\" )\n"
  },
  {
    "path": "user.libc/arch/riscv64/syscall_arch.h",
    "content": "#define __SYSCALL_LL_E(x) (x)\n#define __SYSCALL_LL_O(x) (x)\n\n#define __asm_syscall(...) \\\n\t__asm__ __volatile__ (\"ecall\\n\\t\" \\\n\t: \"=r\"(a0) : __VA_ARGS__ : \"memory\"); \\\n\treturn a0; \\\n\nstatic inline long __syscall0(long n)\n{\n\tregister long a7 __asm__(\"a7\") = n;\n\tregister long a0 __asm__(\"a0\");\n\t__asm_syscall(\"r\"(a7))\n}\n\nstatic inline long __syscall1(long n, long a)\n{\n\tregister long a7 __asm__(\"a7\") = n;\n\tregister long a0 __asm__(\"a0\") = a;\n\t__asm_syscall(\"r\"(a7), \"0\"(a0))\n}\n\nstatic inline long __syscall2(long n, long a, long b)\n{\n\tregister long a7 __asm__(\"a7\") = n;\n\tregister long a0 __asm__(\"a0\") = a;\n\tregister long a1 __asm__(\"a1\") = b;\n\t__asm_syscall(\"r\"(a7), \"0\"(a0), \"r\"(a1))\n}\n\nstatic inline long __syscall3(long n, long a, long b, long c)\n{\n\tregister long a7 __asm__(\"a7\") = n;\n\tregister long a0 __asm__(\"a0\") = a;\n\tregister long a1 __asm__(\"a1\") = b;\n\tregister long a2 __asm__(\"a2\") = c;\n\t__asm_syscall(\"r\"(a7), \"0\"(a0), \"r\"(a1), \"r\"(a2))\n}\n\nstatic inline long __syscall4(long n, long a, long b, long c, long d)\n{\n\tregister long a7 __asm__(\"a7\") = n;\n\tregister long a0 __asm__(\"a0\") = a;\n\tregister long a1 __asm__(\"a1\") = b;\n\tregister long a2 __asm__(\"a2\") = c;\n\tregister long a3 __asm__(\"a3\") = d;\n\t__asm_syscall(\"r\"(a7), \"0\"(a0), \"r\"(a1), \"r\"(a2), \"r\"(a3))\n}\n\nstatic inline long __syscall5(long n, long a, long b, long c, long d, long e)\n{\n\tregister long a7 __asm__(\"a7\") = n;\n\tregister long a0 __asm__(\"a0\") = a;\n\tregister long a1 __asm__(\"a1\") = b;\n\tregister long a2 __asm__(\"a2\") = c;\n\tregister long a3 __asm__(\"a3\") = d;\n\tregister long a4 __asm__(\"a4\") = e;\n\t__asm_syscall(\"r\"(a7), \"0\"(a0), \"r\"(a1), \"r\"(a2), \"r\"(a3), \"r\"(a4))\n}\n\nstatic inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)\n{\n\tregister long a7 __asm__(\"a7\") = n;\n\tregister long a0 __asm__(\"a0\") = a;\n\tregister long a1 __asm__(\"a1\") = b;\n\tregister long a2 __asm__(\"a2\") = c;\n\tregister long a3 __asm__(\"a3\") = d;\n\tregister long a4 __asm__(\"a4\") = e;\n\tregister long a5 __asm__(\"a5\") = f;\n\t__asm_syscall(\"r\"(a7), \"0\"(a0), \"r\"(a1), \"r\"(a2), \"r\"(a3), \"r\"(a4), \"r\"(a5))\n}\n\n#define VDSO_USEFUL\n/* We don't have a clock_gettime function.\n#define VDSO_CGT_SYM \"__vdso_clock_gettime\"\n#define VDSO_CGT_VER \"LINUX_2.6\" */\n\n#define IPC_64 0\n"
  },
  {
    "path": "user.libc/arch/s390x/atomic_arch.h",
    "content": "#define a_cas a_cas\nstatic inline int a_cas(volatile int *p, int t, int s)\n{\n\t__asm__ __volatile__ (\n\t\t\"cs %0, %2, %1\"\n\t\t: \"+d\"(t), \"+Q\"(*p) : \"d\"(s) : \"memory\", \"cc\");\n\treturn t;\n}\n\n#define a_cas_p a_cas_p\nstatic inline void *a_cas_p(volatile void *p, void *t, void *s)\n{\n\t__asm__ __volatile__ (\n\t\t\"csg %0, %2, %1\"\n\t\t: \"+d\"(t), \"+Q\"(*(void *volatile *)p) : \"d\"(s)\n\t\t: \"memory\", \"cc\");\n\treturn t;\n}\n\n#define a_barrier a_barrier\nstatic inline void a_barrier()\n{\n\t__asm__ __volatile__ (\"bcr 15,0\" : : : \"memory\");\n}\n\n#define a_crash a_crash\nstatic inline void a_crash()\n{\n\t__asm__ __volatile__ (\".insn e,0\");\n}\n"
  },
  {
    "path": "user.libc/arch/s390x/bits/alltypes.h.in",
    "content": "#define _Addr long\n#define _Int64 long\n#define _Reg long\n\n#define __BYTE_ORDER 4321\n#define __LONG_MAX 0x7fffffffffffffffL\n\n#ifndef __cplusplus\nTYPEDEF int wchar_t;\n#endif\n\n#if defined(__FLT_EVAL_METHOD__) && __FLT_EVAL_METHOD__ == 1\nTYPEDEF double float_t;\n#else\nTYPEDEF float float_t;\n#endif\nTYPEDEF double double_t;\n\nTYPEDEF struct { long long __ll; long double __ld; } max_align_t;\n"
  },
  {
    "path": "user.libc/arch/s390x/bits/fcntl.h",
    "content": "#define O_CREAT        0100\n#define O_EXCL         0200\n#define O_NOCTTY       0400\n#define O_TRUNC       01000\n#define O_APPEND      02000\n#define O_NONBLOCK    04000\n#define O_DSYNC      010000\n#define O_SYNC     04010000\n#define O_RSYNC    04010000\n#define O_DIRECTORY 0200000\n#define O_NOFOLLOW  0400000\n#define O_CLOEXEC  02000000\n\n#define O_ASYNC      020000\n#define O_DIRECT     040000\n#define O_LARGEFILE 0100000\n#define O_NOATIME  01000000\n#define O_PATH    010000000\n#define O_TMPFILE 020200000\n#define O_NDELAY O_NONBLOCK\n\n#define F_DUPFD  0\n#define F_GETFD  1\n#define F_SETFD  2\n#define F_GETFL  3\n#define F_SETFL  4\n\n#define F_GETLK  5\n#define F_SETLK  6\n#define F_SETLKW 7\n\n#define F_SETOWN 8\n#define F_GETOWN 9\n#define F_SETSIG 10\n#define F_GETSIG 11\n\n#define F_SETOWN_EX 15\n#define F_GETOWN_EX 16\n\n#define F_GETOWNER_UIDS 17\n\n#define POSIX_FADV_DONTNEED   6\n#define POSIX_FADV_NOREUSE    7\n"
  },
  {
    "path": "user.libc/arch/s390x/bits/fenv.h",
    "content": "#define FE_TONEAREST\t0\n#define FE_TOWARDZERO\t1\n#define FE_UPWARD\t2\n#define FE_DOWNWARD\t3\n\n#define FE_INEXACT\t0x00080000\n#define FE_UNDERFLOW\t0x00100000\n#define FE_OVERFLOW\t0x00200000\n#define FE_DIVBYZERO\t0x00400000\n#define FE_INVALID\t0x00800000\n\n#define FE_ALL_EXCEPT\t0x00f80000\n\ntypedef unsigned fexcept_t;\ntypedef unsigned fenv_t;\n\n#define FE_DFL_ENV ((const fenv_t *)-1)\n"
  },
  {
    "path": "user.libc/arch/s390x/bits/float.h",
    "content": "#ifdef __FLT_EVAL_METHOD__\n#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__\n#else\n#define FLT_EVAL_METHOD 0\n#endif\n\n#define LDBL_TRUE_MIN 6.47517511943802511092443895822764655e-4966L\n#define LDBL_MIN 3.36210314311209350626267781732175260e-4932L\n#define LDBL_MAX 1.18973149535723176508575932662800702e+4932L\n#define LDBL_EPSILON 1.92592994438723585305597794258492732e-34L\n\n#define LDBL_MANT_DIG 113\n#define LDBL_MIN_EXP (-16381)\n#define LDBL_MAX_EXP 16384\n\n#define LDBL_DIG 33\n#define LDBL_MIN_10_EXP (-4931)\n#define LDBL_MAX_10_EXP 4932\n\n#define DECIMAL_DIG 36\n"
  },
  {
    "path": "user.libc/arch/s390x/bits/hwcap.h",
    "content": "#define HWCAP_S390_ESAN3\t1\n#define HWCAP_S390_ZARCH\t2\n#define HWCAP_S390_STFLE\t4\n#define HWCAP_S390_MSA\t\t8\n#define HWCAP_S390_LDISP\t16\n#define HWCAP_S390_EIMM\t\t32\n#define HWCAP_S390_DFP\t\t64\n#define HWCAP_S390_HPAGE\t128\n#define HWCAP_S390_ETF3EH\t256\n#define HWCAP_S390_HIGH_GPRS\t512\n#define HWCAP_S390_TE\t\t1024\n#define HWCAP_S390_VXRS\t\t2048\n#define HWCAP_S390_VXRS_BCD\t4096\n#define HWCAP_S390_VXRS_EXT\t8192\n#define HWCAP_S390_GS\t\t16384\n"
  },
  {
    "path": "user.libc/arch/s390x/bits/ioctl_fix.h",
    "content": "#undef FIOQSIZE\n#define FIOQSIZE 0x545e\n"
  },
  {
    "path": "user.libc/arch/s390x/bits/limits.h",
    "content": "#define PAGESIZE 4096\n"
  },
  {
    "path": "user.libc/arch/s390x/bits/link.h",
    "content": "typedef uint64_t Elf_Symndx;\n"
  },
  {
    "path": "user.libc/arch/s390x/bits/posix.h",
    "content": "#define _POSIX_V6_LP64_OFF64  1\n#define _POSIX_V7_LP64_OFF64  1\n"
  },
  {
    "path": "user.libc/arch/s390x/bits/ptrace.h",
    "content": "#define PTRACE_SINGLEBLOCK\t\t12\n#define PTRACE_PEEKUSR_AREA\t\t0x5000\n#define PTRACE_POKEUSR_AREA\t\t0x5001\n#define PTRACE_GET_LAST_BREAK\t\t0x5006\n#define PTRACE_ENABLE_TE\t\t0x5009\n#define PTRACE_DISABLE_TE\t\t0x5010\n#define PTRACE_TE_ABORT_RAND\t\t0x5011\n\n#define PT_STEPBLOCK PTRACE_SINGLEBLOCK\n"
  },
  {
    "path": "user.libc/arch/s390x/bits/reg.h",
    "content": "#undef __WORDSIZE\n#define __WORDSIZE 64\n"
  },
  {
    "path": "user.libc/arch/s390x/bits/setjmp.h",
    "content": "typedef unsigned long __jmp_buf[18];\n"
  },
  {
    "path": "user.libc/arch/s390x/bits/signal.h",
    "content": "#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define MINSIGSTKSZ 4096\n#define SIGSTKSZ    10240\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n\ntypedef unsigned long greg_t, gregset_t[27];\n\ntypedef struct {\n\tunsigned long mask;\n\tunsigned long addr;\n} __psw_t;\n\ntypedef union {\n\tdouble d;\n\tfloat f;\n} fpreg_t;\n\ntypedef struct {\n\tunsigned fpc;\n\tfpreg_t fprs[16];\n} fpregset_t;\n\ntypedef struct\n{\n\t__psw_t psw;\n\tunsigned long gregs[16];\n\tunsigned aregs[16];\n\tfpregset_t fpregs;\n} mcontext_t;\n\nstruct sigcontext {\n\tunsigned long oldmask[1];\n\tstruct {\n\t\tstruct {\n\t\t\t__psw_t psw;\n\t\t\tunsigned long gprs[16];\n\t\t\tunsigned acrs[16];\n\t\t} regs;\n\t\tstruct {\n\t\t\tunsigned fpc;\n\t\t\tdouble fprs[16];\n\t\t} fpregs;\n\t} *sregs;\n};\n\n#else\n\ntypedef struct {\n\tunsigned long __regs1[18];\n\tunsigned __regs2[18];\n\tdouble __regs3[16];\n} mcontext_t;\n\n#endif\n\nstruct sigaltstack {\n\tvoid *ss_sp;\n\tint ss_flags;\n\tsize_t ss_size;\n};\n\ntypedef struct __ucontext {\n\tunsigned long uc_flags;\n\tstruct __ucontext *uc_link;\n\tstack_t uc_stack;\n\tmcontext_t uc_mcontext;\n\tsigset_t uc_sigmask;\n} ucontext_t;\n\n#define SA_NOCLDSTOP  1U\n#define SA_NOCLDWAIT  2U\n#define SA_SIGINFO    4U\n#define SA_ONSTACK    0x08000000U\n#define SA_RESTART    0x10000000U\n#define SA_NODEFER    0x40000000U\n#define SA_RESETHAND  0x80000000U\n#define SA_RESTORER   0x04000000U\n\n#endif\n\n#define SIGHUP    1\n#define SIGINT    2\n#define SIGQUIT   3\n#define SIGILL    4\n#define SIGTRAP   5\n#define SIGABRT   6\n#define SIGIOT    SIGABRT\n#define SIGBUS    7\n#define SIGFPE    8\n#define SIGKILL   9\n#define SIGUSR1   10\n#define SIGSEGV   11\n#define SIGUSR2   12\n#define SIGPIPE   13\n#define SIGALRM   14\n#define SIGTERM   15\n#define SIGSTKFLT 16\n#define SIGCHLD   17\n#define SIGCONT   18\n#define SIGSTOP   19\n#define SIGTSTP   20\n#define SIGTTIN   21\n#define SIGTTOU   22\n#define SIGURG    23\n#define SIGXCPU   24\n#define SIGXFSZ   25\n#define SIGVTALRM 26\n#define SIGPROF   27\n#define SIGWINCH  28\n#define SIGIO     29\n#define SIGPOLL   SIGIO\n#define SIGPWR    30\n#define SIGSYS    31\n#define SIGUNUSED SIGSYS\n\n#define _NSIG 65\n"
  },
  {
    "path": "user.libc/arch/s390x/bits/stat.h",
    "content": "struct stat {\n\tdev_t st_dev;\n\tino_t st_ino;\n\tnlink_t st_nlink;\n\tmode_t st_mode;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tdev_t st_rdev;\n\toff_t st_size;\n\tstruct timespec st_atim;\n\tstruct timespec st_mtim;\n\tstruct timespec st_ctim;\n\tblksize_t st_blksize;\n\tblkcnt_t st_blocks;\n\tunsigned long __unused[3];\n};\n"
  },
  {
    "path": "user.libc/arch/s390x/bits/statfs.h",
    "content": "struct statfs {\n\tunsigned f_type, f_bsize;\n\tfsblkcnt_t f_blocks, f_bfree, f_bavail;\n\tfsfilcnt_t f_files, f_ffree;\n\tfsid_t f_fsid;\n\tunsigned f_namelen, f_frsize, f_flags, f_spare[4];\n};\n"
  },
  {
    "path": "user.libc/arch/s390x/bits/stdint.h",
    "content": "typedef int32_t int_fast16_t;\ntypedef int32_t int_fast32_t;\ntypedef uint32_t uint_fast16_t;\ntypedef uint32_t uint_fast32_t;\n\n#define INT_FAST16_MIN  INT32_MIN\n#define INT_FAST32_MIN  INT32_MIN\n\n#define INT_FAST16_MAX  INT32_MAX\n#define INT_FAST32_MAX  INT32_MAX\n\n#define UINT_FAST16_MAX UINT32_MAX\n#define UINT_FAST32_MAX UINT32_MAX\n\n#define INTPTR_MIN      INT64_MIN\n#define INTPTR_MAX      INT64_MAX\n#define UINTPTR_MAX     UINT64_MAX\n#define PTRDIFF_MIN     INT64_MIN\n#define PTRDIFF_MAX     INT64_MAX\n#define SIZE_MAX        UINT64_MAX\n"
  },
  {
    "path": "user.libc/arch/s390x/bits/syscall.h.in",
    "content": "#define __NR_exit                         1\n#define __NR_fork                         2\n#define __NR_read                         3\n#define __NR_write                        4\n#define __NR_open                         5\n#define __NR_close                        6\n#define __NR_restart_syscall              7\n#define __NR_creat                        8\n#define __NR_link                         9\n#define __NR_unlink                      10\n#define __NR_execve                      11\n#define __NR_chdir                       12\n#define __NR_mknod                       14\n#define __NR_chmod                       15\n#define __NR_lseek                       19\n#define __NR_getpid                      20\n#define __NR_mount                       21\n#define __NR_umount                      22\n#define __NR_ptrace                      26\n#define __NR_alarm                       27\n#define __NR_pause                       29\n#define __NR_utime                       30\n#define __NR_access                      33\n#define __NR_nice                        34\n#define __NR_sync                        36\n#define __NR_kill                        37\n#define __NR_rename                      38\n#define __NR_mkdir                       39\n#define __NR_rmdir                       40\n#define __NR_dup                         41\n#define __NR_pipe                        42\n#define __NR_times                       43\n#define __NR_brk                         45\n#define __NR_signal                      48\n#define __NR_acct                        51\n#define __NR_umount2                     52\n#define __NR_ioctl                       54\n#define __NR_fcntl                       55\n#define __NR_setpgid                     57\n#define __NR_umask                       60\n#define __NR_chroot                      61\n#define __NR_ustat                       62\n#define __NR_dup2                        63\n#define __NR_getppid                     64\n#define __NR_getpgrp                     65\n#define __NR_setsid                      66\n#define __NR_sigaction                   67\n#define __NR_sigsuspend                  72\n#define __NR_sigpending                  73\n#define __NR_sethostname                 74\n#define __NR_setrlimit                   75\n#define __NR_getrusage                   77\n#define __NR_gettimeofday                78\n#define __NR_settimeofday                79\n#define __NR_symlink                     83\n#define __NR_readlink                    85\n#define __NR_uselib                      86\n#define __NR_swapon                      87\n#define __NR_reboot                      88\n#define __NR_readdir                     89\n#define __NR_mmap                        90\n#define __NR_munmap                      91\n#define __NR_truncate                    92\n#define __NR_ftruncate                   93\n#define __NR_fchmod                      94\n#define __NR_getpriority                 96\n#define __NR_setpriority                 97\n#define __NR_statfs                      99\n#define __NR_fstatfs                    100\n#define __NR_socketcall                 102\n#define __NR_syslog                     103\n#define __NR_setitimer                  104\n#define __NR_getitimer                  105\n#define __NR_stat                       106\n#define __NR_lstat                      107\n#define __NR_fstat                      108\n#define __NR_lookup_dcookie             110\n#define __NR_vhangup                    111\n#define __NR_idle                       112\n#define __NR_wait4                      114\n#define __NR_swapoff                    115\n#define __NR_sysinfo                    116\n#define __NR_ipc                        117\n#define __NR_fsync                      118\n#define __NR_sigreturn                  119\n#define __NR_clone                      120\n#define __NR_setdomainname              121\n#define __NR_uname                      122\n#define __NR_adjtimex                   124\n#define __NR_mprotect                   125\n#define __NR_sigprocmask                126\n#define __NR_create_module              127\n#define __NR_init_module                128\n#define __NR_delete_module              129\n#define __NR_get_kernel_syms            130\n#define __NR_quotactl                   131\n#define __NR_getpgid                    132\n#define __NR_fchdir                     133\n#define __NR_bdflush                    134\n#define __NR_sysfs                      135\n#define __NR_personality                136\n#define __NR_afs_syscall                137\n#define __NR_getdents                   141\n#define __NR_select                     142\n#define __NR_flock                      143\n#define __NR_msync                      144\n#define __NR_readv                      145\n#define __NR_writev                     146\n#define __NR_getsid                     147\n#define __NR_fdatasync                  148\n#define __NR__sysctl                    149\n#define __NR_mlock                      150\n#define __NR_munlock                    151\n#define __NR_mlockall                   152\n#define __NR_munlockall                 153\n#define __NR_sched_setparam             154\n#define __NR_sched_getparam             155\n#define __NR_sched_setscheduler         156\n#define __NR_sched_getscheduler         157\n#define __NR_sched_yield                158\n#define __NR_sched_get_priority_max     159\n#define __NR_sched_get_priority_min     160\n#define __NR_sched_rr_get_interval      161\n#define __NR_nanosleep                  162\n#define __NR_mremap                     163\n#define __NR_query_module               167\n#define __NR_poll                       168\n#define __NR_nfsservctl                 169\n#define __NR_prctl                      172\n#define __NR_rt_sigreturn               173\n#define __NR_rt_sigaction               174\n#define __NR_rt_sigprocmask             175\n#define __NR_rt_sigpending              176\n#define __NR_rt_sigtimedwait            177\n#define __NR_rt_sigqueueinfo            178\n#define __NR_rt_sigsuspend              179\n#define __NR_pread64                    180\n#define __NR_pwrite64                   181\n#define __NR_getcwd                     183\n#define __NR_capget                     184\n#define __NR_capset                     185\n#define __NR_sigaltstack                186\n#define __NR_sendfile                   187\n#define __NR_getpmsg                    188\n#define __NR_putpmsg                    189\n#define __NR_vfork                      190\n#define __NR_getrlimit                  191\n#define __NR_lchown                     198\n#define __NR_getuid                     199\n#define __NR_getgid                     200\n#define __NR_geteuid                    201\n#define __NR_getegid                    202\n#define __NR_setreuid                   203\n#define __NR_setregid                   204\n#define __NR_getgroups                  205\n#define __NR_setgroups                  206\n#define __NR_fchown                     207\n#define __NR_setresuid                  208\n#define __NR_getresuid                  209\n#define __NR_setresgid                  210\n#define __NR_getresgid                  211\n#define __NR_chown                      212\n#define __NR_setuid                     213\n#define __NR_setgid                     214\n#define __NR_setfsuid                   215\n#define __NR_setfsgid                   216\n#define __NR_pivot_root                 217\n#define __NR_mincore                    218\n#define __NR_madvise                    219\n#define __NR_getdents64                 220\n#define __NR_readahead                  222\n#define __NR_setxattr                   224\n#define __NR_lsetxattr                  225\n#define __NR_fsetxattr                  226\n#define __NR_getxattr                   227\n#define __NR_lgetxattr                  228\n#define __NR_fgetxattr                  229\n#define __NR_listxattr                  230\n#define __NR_llistxattr                 231\n#define __NR_flistxattr                 232\n#define __NR_removexattr                233\n#define __NR_lremovexattr               234\n#define __NR_fremovexattr               235\n#define __NR_gettid                     236\n#define __NR_tkill                      237\n#define __NR_futex                      238\n#define __NR_sched_setaffinity          239\n#define __NR_sched_getaffinity          240\n#define __NR_tgkill                     241\n#define __NR_io_setup                   243\n#define __NR_io_destroy                 244\n#define __NR_io_getevents               245\n#define __NR_io_submit                  246\n#define __NR_io_cancel                  247\n#define __NR_exit_group                 248\n#define __NR_epoll_create               249\n#define __NR_epoll_ctl                  250\n#define __NR_epoll_wait                 251\n#define __NR_set_tid_address            252\n#define __NR_fadvise64                  253\n#define __NR_timer_create               254\n#define __NR_timer_settime              255\n#define __NR_timer_gettime              256\n#define __NR_timer_getoverrun           257\n#define __NR_timer_delete               258\n#define __NR_clock_settime              259\n#define __NR_clock_gettime              260\n#define __NR_clock_getres               261\n#define __NR_clock_nanosleep            262\n#define __NR_statfs64                   265\n#define __NR_fstatfs64                  266\n#define __NR_remap_file_pages           267\n#define __NR_mbind                      268\n#define __NR_get_mempolicy              269\n#define __NR_set_mempolicy              270\n#define __NR_mq_open                    271\n#define __NR_mq_unlink                  272\n#define __NR_mq_timedsend               273\n#define __NR_mq_timedreceive            274\n#define __NR_mq_notify                  275\n#define __NR_mq_getsetattr              276\n#define __NR_kexec_load                 277\n#define __NR_add_key                    278\n#define __NR_request_key                279\n#define __NR_keyctl                     280\n#define __NR_waitid                     281\n#define __NR_ioprio_set                 282\n#define __NR_ioprio_get                 283\n#define __NR_inotify_init               284\n#define __NR_inotify_add_watch          285\n#define __NR_inotify_rm_watch           286\n#define __NR_migrate_pages              287\n#define __NR_openat                     288\n#define __NR_mkdirat                    289\n#define __NR_mknodat                    290\n#define __NR_fchownat                   291\n#define __NR_futimesat                  292\n#define __NR_newfstatat                 293\n#define __NR_unlinkat                   294\n#define __NR_renameat                   295\n#define __NR_linkat                     296\n#define __NR_symlinkat                  297\n#define __NR_readlinkat                 298\n#define __NR_fchmodat                   299\n#define __NR_faccessat                  300\n#define __NR_pselect6                   301\n#define __NR_ppoll                      302\n#define __NR_unshare                    303\n#define __NR_set_robust_list            304\n#define __NR_get_robust_list            305\n#define __NR_splice                     306\n#define __NR_sync_file_range            307\n#define __NR_tee                        308\n#define __NR_vmsplice                   309\n#define __NR_move_pages                 310\n#define __NR_getcpu                     311\n#define __NR_epoll_pwait                312\n#define __NR_utimes                     313\n#define __NR_fallocate                  314\n#define __NR_utimensat                  315\n#define __NR_signalfd                   316\n#define __NR_timerfd                    317\n#define __NR_eventfd                    318\n#define __NR_timerfd_create             319\n#define __NR_timerfd_settime            320\n#define __NR_timerfd_gettime            321\n#define __NR_signalfd4                  322\n#define __NR_eventfd2                   323\n#define __NR_inotify_init1              324\n#define __NR_pipe2                      325\n#define __NR_dup3                       326\n#define __NR_epoll_create1              327\n#define __NR_preadv                     328\n#define __NR_pwritev                    329\n#define __NR_rt_tgsigqueueinfo          330\n#define __NR_perf_event_open            331\n#define __NR_fanotify_init              332\n#define __NR_fanotify_mark              333\n#define __NR_prlimit64                  334\n#define __NR_name_to_handle_at          335\n#define __NR_open_by_handle_at          336\n#define __NR_clock_adjtime              337\n#define __NR_syncfs                     338\n#define __NR_setns                      339\n#define __NR_process_vm_readv           340\n#define __NR_process_vm_writev          341\n#define __NR_s390_runtime_instr         342\n#define __NR_kcmp                       343\n#define __NR_finit_module               344\n#define __NR_sched_setattr              345\n#define __NR_sched_getattr              346\n#define __NR_renameat2                  347\n#define __NR_seccomp                    348\n#define __NR_getrandom                  349\n#define __NR_memfd_create               350\n#define __NR_bpf                        351\n#define __NR_s390_pci_mmio_write        352\n#define __NR_s390_pci_mmio_read         353\n#define __NR_execveat                   354\n#define __NR_userfaultfd                355\n#define __NR_membarrier                 356\n#define __NR_recvmmsg                   357\n#define __NR_sendmmsg                   358\n#define __NR_socket                     359\n#define __NR_socketpair                 360\n#define __NR_bind                       361\n#define __NR_connect                    362\n#define __NR_listen                     363\n#define __NR_accept4                    364\n#define __NR_getsockopt                 365\n#define __NR_setsockopt                 366\n#define __NR_getsockname                367\n#define __NR_getpeername                368\n#define __NR_sendto                     369\n#define __NR_sendmsg                    370\n#define __NR_recvfrom                   371\n#define __NR_recvmsg                    372\n#define __NR_shutdown                   373\n#define __NR_mlock2                     374\n#define __NR_copy_file_range            375\n#define __NR_preadv2                    376\n#define __NR_pwritev2                   377\n#define __NR_s390_guarded_storage       378\n#define __NR_statx                      379\n#define __NR_s390_sthyi                 380\n#define __NR_kexec_file_load            381\n#define __NR_io_pgetevents              382\n#define __NR_rseq                       383\n#define __NR_pkey_mprotect              384\n#define __NR_pkey_alloc                 385\n#define __NR_pkey_free                  386\n#define __NR_semtimedop                 392\n#define __NR_semget                     393\n#define __NR_semctl                     394\n#define __NR_shmget                     395\n#define __NR_shmctl                     396\n#define __NR_shmat                      397\n#define __NR_shmdt                      398\n#define __NR_msgget                     399\n#define __NR_msgsnd                     400\n#define __NR_msgrcv                     401\n#define __NR_msgctl                     402\n#define __NR_pidfd_send_signal          424\n#define __NR_io_uring_setup             425\n#define __NR_io_uring_enter             426\n#define __NR_io_uring_register          427\n#define __NR_open_tree\t\t428\n#define __NR_move_mount\t\t429\n#define __NR_fsopen\t\t430\n#define __NR_fsconfig\t\t431\n#define __NR_fsmount\t\t432\n#define __NR_fspick\t\t433\n#define __NR_pidfd_open\t\t434\n#define __NR_clone3\t\t435\n#define __NR_close_range\t436\n#define __NR_openat2\t\t437\n#define __NR_pidfd_getfd\t438\n#define __NR_faccessat2\t\t439\n\n"
  },
  {
    "path": "user.libc/arch/s390x/bits/user.h",
    "content": "#undef __WORDSIZE\n#define __WORDSIZE 64\n\ntypedef union {\n\tdouble d;\n\tfloat f;\n} elf_fpreg_t;\n\ntypedef struct {\n\tunsigned fpc;\n\telf_fpreg_t fprs[16];\n} elf_fpregset_t;\n\n#define ELF_NGREG 27\ntypedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG];\n\nstruct _user_psw_struct {\n\tunsigned long mask, addr;\n};\n\nstruct _user_fpregs_struct {\n\tunsigned fpc;\n\tdouble fprs[16];\n};\n\nstruct _user_per_struct {\n\tunsigned long control_regs[3];\n\tunsigned single_step       : 1;\n\tunsigned instruction_fetch : 1;\n\tunsigned                   : 30;\n\tunsigned long starting_addr, ending_addr;\n\tunsigned short perc_atmid;\n\tunsigned long address;\n\tunsigned char access_id;\n};\n\nstruct _user_regs_struct {\n\tstruct _user_psw_struct psw;\n\tunsigned long gprs[16];\n\tunsigned acrs[16];\n\tunsigned long orig_gpr2;\n\tstruct _user_fpregs_struct fp_regs;\n\tstruct _user_per_struct per_info;\n\tunsigned long ieee_instruction_pointer;\n};\n\nstruct user {\n\tstruct _user_regs_struct regs;\n\tunsigned long u_tsize, u_dsize, u_ssize;\n\tunsigned long start_code, start_stack;\n\tlong signal;\n\tstruct _user_regs_struct *u_ar0;\n\tunsigned long magic;\n\tchar u_comm[32];\n};\n\n#define PAGE_MASK            (~(PAGESIZE-1))\n#define NBPG                 PAGESIZE\n#define UPAGES               1\n#define HOST_TEXT_START_ADDR (u.start_code)\n#define HOST_STACK_END_ADDR  (u.start_stack + u.u_ssize * NBPG)\n\n"
  },
  {
    "path": "user.libc/arch/s390x/crt_arch.h",
    "content": "__asm__(\n\".text\\n\"\n\".global \" START \"\\n\"\n\".type   \" START \", %function\\n\"\nSTART \":\\n\"\n\"\tlgr  %r2, %r15\\n\"\n\"\tlarl %r3, 1f\\n\"\n\"\tagf  %r3, 0(%r3)\\n\"\n\"\taghi %r15, -160\\n\"\n\"\tlghi %r0, 0\\n\"\n\"\tstg  %r0, 0(%r15)\\n\"\n\"\tjg \" START \"_c\\n\"\n\"\t.align 8\\n\"\n\".weak   _DYNAMIC\\n\"\n\".hidden _DYNAMIC\\n\"\n\"1:\t.long _DYNAMIC-.\\n\"\n);\n"
  },
  {
    "path": "user.libc/arch/s390x/kstat.h",
    "content": "struct kstat {\n\tdev_t st_dev;\n\tino_t st_ino;\n\tnlink_t st_nlink;\n\tmode_t st_mode;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tdev_t st_rdev;\n\toff_t st_size;\n\tlong st_atime_sec;\n\tlong st_atime_nsec;\n\tlong st_mtime_sec;\n\tlong st_mtime_nsec;\n\tlong st_ctime_sec;\n\tlong st_ctime_nsec;\n\tblksize_t st_blksize;\n\tblkcnt_t st_blocks;\n\tunsigned long __unused[3];\n};\n"
  },
  {
    "path": "user.libc/arch/s390x/pthread_arch.h",
    "content": "static inline uintptr_t __get_tp()\n{\n\tuintptr_t tp;\n\t__asm__ (\n\t\t\"ear  %0, %%a0\\n\"\n\t\t\"sllg %0, %0, 32\\n\"\n\t\t\"ear  %0, %%a1\\n\"\n\t\t: \"=r\"(tp));\n\treturn tp;\n}\n\n#define MC_PC psw.addr\n"
  },
  {
    "path": "user.libc/arch/s390x/reloc.h",
    "content": "#define LDSO_ARCH \"s390x\"\n\n#define REL_SYMBOLIC    R_390_64\n#define REL_GOT         R_390_GLOB_DAT\n#define REL_PLT         R_390_JMP_SLOT\n#define REL_RELATIVE    R_390_RELATIVE\n#define REL_COPY        R_390_COPY\n#define REL_DTPMOD      R_390_TLS_DTPMOD\n#define REL_DTPOFF      R_390_TLS_DTPOFF\n#define REL_TPOFF       R_390_TLS_TPOFF\n\n#define CRTJMP(pc,sp) __asm__ __volatile__( \\\n\t\"lgr %%r15,%1; br %0\" : : \"r\"(pc), \"r\"(sp) : \"memory\" )\n"
  },
  {
    "path": "user.libc/arch/s390x/syscall_arch.h",
    "content": "#define __SYSCALL_LL_E(x) (x)\n#define __SYSCALL_LL_O(x) (x)\n\n#define __asm_syscall(ret, ...) do { \\\n\t__asm__ __volatile__ (\"svc 0\\n\" \\\n\t: ret : __VA_ARGS__ : \"memory\"); \\\n\treturn r2; \\\n\t} while (0)\n\nstatic inline long __syscall0(long n)\n{\n\tregister long r1 __asm__(\"r1\") = n;\n\tregister long r2 __asm__(\"r2\");\n\t__asm_syscall(\"=r\"(r2), \"r\"(r1));\n}\n\nstatic inline long __syscall1(long n, long a)\n{\n\tregister long r1 __asm__(\"r1\") = n;\n\tregister long r2 __asm__(\"r2\") = a;\n\t__asm_syscall(\"+r\"(r2), \"r\"(r1));\n}\n\nstatic inline long __syscall2(long n, long a, long b)\n{\n\tregister long r1 __asm__(\"r1\") = n;\n\tregister long r2 __asm__(\"r2\") = a;\n\tregister long r3 __asm__(\"r3\") = b;\n\t__asm_syscall(\"+r\"(r2), \"r\"(r1), \"r\"(r3));\n}\n\nstatic inline long __syscall3(long n, long a, long b, long c)\n{\n\tregister long r1 __asm__(\"r1\") = n;\n\tregister long r2 __asm__(\"r2\") = a;\n\tregister long r3 __asm__(\"r3\") = b;\n\tregister long r4 __asm__(\"r4\") = c;\n\t__asm_syscall(\"+r\"(r2), \"r\"(r1), \"r\"(r3), \"r\"(r4));\n}\n\nstatic inline long __syscall4(long n, long a, long b, long c, long d)\n{\n\tregister long r1 __asm__(\"r1\") = n;\n\tregister long r2 __asm__(\"r2\") = a;\n\tregister long r3 __asm__(\"r3\") = b;\n\tregister long r4 __asm__(\"r4\") = c;\n\tregister long r5 __asm__(\"r5\") = d;\n\t__asm_syscall(\"+r\"(r2), \"r\"(r1), \"r\"(r3), \"r\"(r4), \"r\"(r5));\n}\n\nstatic inline long __syscall5(long n, long a, long b, long c, long d, long e)\n{\n\tregister long r1 __asm__(\"r1\") = n;\n\tregister long r2 __asm__(\"r2\") = a;\n\tregister long r3 __asm__(\"r3\") = b;\n\tregister long r4 __asm__(\"r4\") = c;\n\tregister long r5 __asm__(\"r5\") = d;\n\tregister long r6 __asm__(\"r6\") = e;\n\t__asm_syscall(\"+r\"(r2), \"r\"(r1), \"r\"(r3), \"r\"(r4), \"r\"(r5), \"r\"(r6));\n}\n\nstatic inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)\n{\n\tif (n == SYS_mmap) return __syscall1(n, (long)(long[]){a,b,c,d,e,f});\n\n\tregister long r1 __asm__(\"r1\") = n;\n\tregister long r2 __asm__(\"r2\") = a;\n\tregister long r3 __asm__(\"r3\") = b;\n\tregister long r4 __asm__(\"r4\") = c;\n\tregister long r5 __asm__(\"r5\") = d;\n\tregister long r6 __asm__(\"r6\") = e;\n\tregister long r7 __asm__(\"r7\") = f;\n\t__asm_syscall(\"+r\"(r2), \"r\"(r1), \"r\"(r3), \"r\"(r4), \"r\"(r5), \"r\"(r6), \"r\"(r7));\n}\n"
  },
  {
    "path": "user.libc/arch/sh/arch.mak",
    "content": "COMPAT_SRC_DIRS = compat/time32\n"
  },
  {
    "path": "user.libc/arch/sh/atomic_arch.h",
    "content": "#include \"libc.h\"\n\n#if defined(__SH4A__)\n\n#define a_ll a_ll\nstatic inline int a_ll(volatile int *p)\n{\n\tint v;\n\t__asm__ __volatile__ (\"movli.l @%1, %0\" : \"=z\"(v) : \"r\"(p), \"m\"(*p));\n\treturn v;\n}\n\n#define a_sc a_sc\nstatic inline int a_sc(volatile int *p, int v)\n{\n\tint r;\n\t__asm__ __volatile__ (\n\t\t\"movco.l %2, @%3 ; movt %0\"\n\t\t: \"=r\"(r), \"=m\"(*p) : \"z\"(v), \"r\"(p) : \"memory\", \"cc\");\n\treturn r;\n}\n\n#define a_barrier a_barrier\nstatic inline void a_barrier()\n{\n\t__asm__ __volatile__ (\"synco\" ::: \"memory\");\n}\n\n#define a_pre_llsc a_barrier\n#define a_post_llsc a_barrier\n\n#else\n\n#define a_cas a_cas\nextern hidden const void *__sh_cas_ptr;\nstatic inline int a_cas(volatile int *p, int t, int s)\n{\n\tregister int r1 __asm__(\"r1\");\n\tregister int r2 __asm__(\"r2\") = t;\n\tregister int r3 __asm__(\"r3\") = s;\n\t__asm__ __volatile__ (\n\t\t\"jsr @%4 ; nop\"\n\t\t: \"=r\"(r1), \"+r\"(r3) : \"z\"(p), \"r\"(r2), \"r\"(__sh_cas_ptr)\n\t\t: \"memory\", \"pr\", \"cc\");\n\treturn r3;\n}\n\n#endif\n"
  },
  {
    "path": "user.libc/arch/sh/bits/alltypes.h.in",
    "content": "#define _REDIR_TIME64 1\n#define _Addr int\n#define _Int64 long long\n#define _Reg int\n\n#if __BIG_ENDIAN__\n#define __BYTE_ORDER 4321\n#else\n#define __BYTE_ORDER 1234\n#endif\n\n#define __LONG_MAX 0x7fffffffL\n\n#ifndef __cplusplus\n#ifdef __WCHAR_TYPE__\nTYPEDEF __WCHAR_TYPE__ wchar_t;\n#else\nTYPEDEF long wchar_t;\n#endif\n#endif\n\nTYPEDEF float float_t;\nTYPEDEF double double_t;\n\nTYPEDEF struct { long long __ll; long double __ld; } max_align_t;\n"
  },
  {
    "path": "user.libc/arch/sh/bits/fenv.h",
    "content": "#ifndef __SH_FPU_ANY__\n\n#define FE_ALL_EXCEPT 0\n#define FE_TONEAREST  0\n\n#else\n\n#define FE_TONEAREST  0\n#define FE_TOWARDZERO 1\n\n#define FE_INEXACT    0x04\n#define FE_UNDERFLOW  0x08\n#define FE_OVERFLOW   0x10\n#define FE_DIVBYZERO  0x20\n#define FE_INVALID    0x40\n#define FE_ALL_EXCEPT 0x7c\n\n#endif\n\ntypedef unsigned long fexcept_t;\n\ntypedef struct {\n\tunsigned long __cw;\n} fenv_t;\n\n#define FE_DFL_ENV    ((const fenv_t *) -1)\n"
  },
  {
    "path": "user.libc/arch/sh/bits/float.h",
    "content": "#define FLT_EVAL_METHOD 0\n\n#define LDBL_TRUE_MIN 4.94065645841246544177e-324L\n#define LDBL_MIN 2.22507385850720138309e-308L\n#define LDBL_MAX 1.79769313486231570815e+308L\n#define LDBL_EPSILON 2.22044604925031308085e-16L\n\n#define LDBL_MANT_DIG 53\n#define LDBL_MIN_EXP (-1021)\n#define LDBL_MAX_EXP 1024\n\n#define LDBL_DIG 15\n#define LDBL_MIN_10_EXP (-307)\n#define LDBL_MAX_10_EXP 308\n\n#define DECIMAL_DIG 17\n"
  },
  {
    "path": "user.libc/arch/sh/bits/hwcap.h",
    "content": "#define CPU_HAS_FPU\t\t0x0001\n#define CPU_HAS_P2_FLUSH_BUG\t0x0002\n#define CPU_HAS_MMU_PAGE_ASSOC\t0x0004\n#define CPU_HAS_DSP\t\t0x0008\n#define CPU_HAS_PERF_COUNTER\t0x0010\n#define CPU_HAS_PTEA\t\t0x0020\n#define CPU_HAS_LLSC\t\t0x0040\n#define CPU_HAS_L2_CACHE\t0x0080\n#define CPU_HAS_OP32\t\t0x0100\n#define CPU_HAS_PTEAEX\t\t0x0200\n#define CPU_HAS_CAS_L\t\t0x0400\n"
  },
  {
    "path": "user.libc/arch/sh/bits/ioctl.h",
    "content": "#define _IOC(a,b,c,d) ( ((a)<<30) | ((b)<<8) | (c) | ((d)<<16) )\n#define _IOC_NONE  0U\n#define _IOC_WRITE 1U\n#define _IOC_READ  2U\n\n#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)\n#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c))\n#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c))\n#define _IOWR(a,b,c) _IOC(_IOC_READ|_IOC_WRITE,(a),(b),sizeof(c))\n\n#define FIOCLEX             _IO('f',  1)\n#define FIONCLEX            _IO('f',  2)\n#define FIOASYNC            _IOW('f', 125, int)\n#define FIONBIO             _IOW('f', 126, int)\n#define FIONREAD            _IOR('f', 127, int)\n#define TIOCINQ             FIONREAD\n#define FIOQSIZE            _IOR('f', 128, char[8])\n\n#define TCGETA              _IOR('t', 23, char[18])\n#define TCSETA              _IOW('t', 24, char[18])\n#define TCSETAW             _IOW('t', 25, char[18])\n#define TCSETAF             _IOW('t', 28, char[18])\n\n#define TCSBRK              _IO('t', 29)\n#define TCXONC              _IO('t', 30)\n#define TCFLSH              _IO('t', 31)\n\n#define TIOCSWINSZ          _IOW('t', 103, char[8])\n#define TIOCGWINSZ          _IOR('t', 104, char[8])\n#define TIOCSTART           _IO('t',  110)\n#define TIOCSTOP            _IO('t',  111)\n#define TIOCOUTQ            _IOR('t', 115, int)\n\n#define TIOCSPGRP           _IOW('t', 118, int)\n#define TIOCGPGRP           _IOR('t', 119, int)\n\n#define TIOCEXCL            _IO('T', 12)\n#define TIOCNXCL            _IO('T', 13)\n#define TIOCSCTTY           _IO('T', 14)\n\n#define TIOCSTI             _IOW('T', 18, char)\n#define TIOCMGET            _IOR('T', 21, unsigned int)\n#define TIOCMBIS            _IOW('T', 22, unsigned int)\n#define TIOCMBIC            _IOW('T', 23, unsigned int)\n#define TIOCMSET            _IOW('T', 24, unsigned int)\n#define TIOCM_LE            0x001\n#define TIOCM_DTR           0x002\n#define TIOCM_RTS           0x004\n#define TIOCM_ST            0x008\n#define TIOCM_SR            0x010\n#define TIOCM_CTS           0x020\n#define TIOCM_CAR           0x040\n#define TIOCM_RNG           0x080\n#define TIOCM_DSR           0x100\n#define TIOCM_CD            TIOCM_CAR\n#define TIOCM_RI            TIOCM_RNG\n#define TIOCM_OUT1          0x2000\n#define TIOCM_OUT2          0x4000\n#define TIOCM_LOOP          0x8000\n\n#define TIOCGSOFTCAR        _IOR('T', 25, unsigned int)\n#define TIOCSSOFTCAR        _IOW('T', 26, unsigned int)\n#define TIOCLINUX           _IOW('T', 28, char)\n#define TIOCCONS            _IO('T',  29)\n#define TIOCGSERIAL         _IOR('T', 30, char[60])\n#define TIOCSSERIAL         _IOW('T', 31, char[60])\n#define TIOCPKT             _IOW('T', 32, int)\n\n#define TIOCNOTTY           _IO('T',  34)\n#define TIOCSETD            _IOW('T', 35, int)\n#define TIOCGETD            _IOR('T', 36, int)\n#define TCSBRKP             _IOW('T', 37, int)\n#define TIOCSBRK            _IO('T',  39)\n#define TIOCCBRK            _IO('T',  40)\n#define TIOCGSID            _IOR('T', 41, int)\n#define TCGETS              _IO('T', 1)\n#define TCSETS              _IO('T', 2)\n#define TCSETSW             _IO('T', 3)\n#define TCSETSF             _IO('T', 4)\n#define TIOCGRS485          _IOR('T', 46, char[32])\n#define TIOCSRS485          _IOWR('T', 47, char[32])\n#define TIOCGPTN            _IOR('T', 48, unsigned int)\n#define TIOCSPTLCK          _IOW('T', 49, int)\n#define TIOCGDEV            _IOR('T', 50, unsigned int)\n#define TIOCSIG             _IOW('T', 54, int)\n#define TIOCVHANGUP         _IO('T',  55)\n#define TIOCGPKT            _IOR('T', 56, int)\n#define TIOCGPTLCK          _IOR('T', 57, int)\n#define TIOCGEXCL           _IOR('T', 64, int)\n#define TIOCGPTPEER         _IO('T', 0x41)\n\n#define TIOCSERCONFIG       _IO('T',  83)\n#define TIOCSERGWILD        _IOR('T', 84, int)\n#define TIOCSERSWILD        _IOW('T', 85, int)\n#define TIOCGLCKTRMIOS      _IO('T',  86)\n#define TIOCSLCKTRMIOS      _IO('T',  87)\n#define TIOCSERGSTRUCT      _IOR('T', 88, char[216])\n#define TIOCSERGETLSR       _IOR('T', 89, unsigned int)\n#define TIOCSERGETMULTI     _IOR('T', 90, char[168])\n#define TIOCSERSETMULTI     _IOW('T', 91, char[168])\n\n#define TIOCMIWAIT          _IO('T', 92)\n#define TIOCGICOUNT         _IO('T', 93)\n\n#define FIOGETOWN       _IOR('f', 123, int)\n#define FIOSETOWN       _IOW('f', 124, int)\n\n#define SIOCATMARK      _IOR('s', 7, int)\n#define SIOCSPGRP       _IOW('s', 8, int)\n#define SIOCGPGRP       _IOW('s', 9, int)\n#define SIOCGSTAMP      _IOR(0x89, 6, char[16])\n#define SIOCGSTAMPNS    _IOR(0x89, 7, char[16])\n"
  },
  {
    "path": "user.libc/arch/sh/bits/ipcstat.h",
    "content": "#define IPC_STAT 0x102\n"
  },
  {
    "path": "user.libc/arch/sh/bits/limits.h",
    "content": "#define PAGESIZE 4096\n"
  },
  {
    "path": "user.libc/arch/sh/bits/msg.h",
    "content": "struct msqid_ds {\n\tstruct ipc_perm msg_perm;\n\tunsigned long __msg_stime_lo;\n\tunsigned long __msg_stime_hi;\n\tunsigned long __msg_rtime_lo;\n\tunsigned long __msg_rtime_hi;\n\tunsigned long __msg_ctime_lo;\n\tunsigned long __msg_ctime_hi;\n\tunsigned long msg_cbytes;\n\tmsgqnum_t msg_qnum;\n\tmsglen_t msg_qbytes;\n\tpid_t msg_lspid;\n\tpid_t msg_lrpid;\n\tunsigned long __unused[2];\n\ttime_t msg_stime;\n\ttime_t msg_rtime;\n\ttime_t msg_ctime;\n};\n"
  },
  {
    "path": "user.libc/arch/sh/bits/posix.h",
    "content": "#define _POSIX_V6_ILP32_OFFBIG  1\n#define _POSIX_V7_ILP32_OFFBIG  1\n"
  },
  {
    "path": "user.libc/arch/sh/bits/ptrace.h",
    "content": "#define PTRACE_GETFDPIC\t\t31\n#define PTRACE_GETFDPIC_EXEC\t0\n#define PTRACE_GETFDPIC_INTERP\t1\n#define PTRACE_GETDSPREGS\t55\n#define PTRACE_SETDSPREGS\t56\n"
  },
  {
    "path": "user.libc/arch/sh/bits/sem.h",
    "content": "struct semid_ds {\n\tstruct ipc_perm sem_perm;\n\tunsigned long __sem_otime_lo;\n\tunsigned long __sem_otime_hi;\n\tunsigned long __sem_ctime_lo;\n\tunsigned long __sem_ctime_hi;\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n\tunsigned short sem_nsems;\n\tchar __sem_nsems_pad[sizeof(long)-sizeof(short)];\n#else\n\tchar __sem_nsems_pad[sizeof(long)-sizeof(short)];\n\tunsigned short sem_nsems;\n#endif\n\tlong __unused3;\n\tlong __unused4;\n\ttime_t sem_otime;\n\ttime_t sem_ctime;\n};\n"
  },
  {
    "path": "user.libc/arch/sh/bits/setjmp.h",
    "content": "typedef unsigned long __jmp_buf[15];\n"
  },
  {
    "path": "user.libc/arch/sh/bits/shm.h",
    "content": "#define SHMLBA 16384\n\nstruct shmid_ds {\n\tstruct ipc_perm shm_perm;\n\tsize_t shm_segsz;\n\tunsigned long __shm_atime_lo;\n\tunsigned long __shm_atime_hi;\n\tunsigned long __shm_dtime_lo;\n\tunsigned long __shm_dtime_hi;\n\tunsigned long __shm_ctime_lo;\n\tunsigned long __shm_ctime_hi;\n\tpid_t shm_cpid;\n\tpid_t shm_lpid;\n\tunsigned long shm_nattch;\n\tunsigned long __pad1;\n\tunsigned long __pad2;\n\tunsigned long __pad3;\n\ttime_t shm_atime;\n\ttime_t shm_dtime;\n\ttime_t shm_ctime;\n};\n\nstruct shminfo {\n\tunsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];\n};\n\nstruct shm_info {\n\tint __used_ids;\n\tunsigned long shm_tot, shm_rss, shm_swp;\n\tunsigned long __swap_attempts, __swap_successes;\n};\n"
  },
  {
    "path": "user.libc/arch/sh/bits/signal.h",
    "content": "#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define MINSIGSTKSZ 2048\n#define SIGSTKSZ 8192\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\ntypedef int greg_t, gregset_t[16];\ntypedef int freg_t, fpregset_t[16];\ntypedef struct {\n\tunsigned long oldmask;\n\tunsigned long gregs[16];\n\tunsigned long pc, pr, sr;\n\tunsigned long gbr, mach, macl;\n\tunsigned long fpregs[16];\n\tunsigned long xfpregs[16];\n\tunsigned int fpscr, fpul, ownedfp;\n} mcontext_t;\nstruct sigcontext {\n\tunsigned long oldmask;\n\tunsigned long sc_regs[16];\n\tunsigned long sc_pc, sc_pr, sc_sr;\n\tunsigned long sc_gbr, sc_mach, sc_macl;\n\tunsigned long sc_fpregs[16];\n\tunsigned long sc_xfpregs[16];\n\tunsigned int sc_fpscr, sc_fpul, sc_ownedfp;\n};\n#else\ntypedef struct {\n\tunsigned long __regs[58];\n} mcontext_t;\n#endif\n\nstruct sigaltstack {\n\tvoid *ss_sp;\n\tint ss_flags;\n\tsize_t ss_size;\n};\n\ntypedef struct __ucontext {\n\tunsigned long uc_flags;\n\tstruct __ucontext *uc_link;\n\tstack_t uc_stack;\n\tmcontext_t uc_mcontext;\n\tsigset_t uc_sigmask;\n} ucontext_t;\n\n#define SA_NOCLDSTOP  1\n#define SA_NOCLDWAIT  2\n#define SA_SIGINFO    4\n#define SA_ONSTACK    0x08000000\n#define SA_RESTART    0x10000000\n#define SA_NODEFER    0x40000000\n#define SA_RESETHAND  0x80000000\n#define SA_RESTORER   0x04000000\n\n#endif\n\n#define SIGHUP    1\n#define SIGINT    2\n#define SIGQUIT   3\n#define SIGILL    4\n#define SIGTRAP   5\n#define SIGABRT   6\n#define SIGIOT    SIGABRT\n#define SIGBUS    7\n#define SIGFPE    8\n#define SIGKILL   9\n#define SIGUSR1   10\n#define SIGSEGV   11\n#define SIGUSR2   12\n#define SIGPIPE   13\n#define SIGALRM   14\n#define SIGTERM   15\n#define SIGSTKFLT 16\n#define SIGCHLD   17\n#define SIGCONT   18\n#define SIGSTOP   19\n#define SIGTSTP   20\n#define SIGTTIN   21\n#define SIGTTOU   22\n#define SIGURG    23\n#define SIGXCPU   24\n#define SIGXFSZ   25\n#define SIGVTALRM 26\n#define SIGPROF   27\n#define SIGWINCH  28\n#define SIGIO     29\n#define SIGPOLL   29\n#define SIGPWR    30\n#define SIGSYS    31\n#define SIGUNUSED SIGSYS\n\n#define _NSIG 65\n"
  },
  {
    "path": "user.libc/arch/sh/bits/stat.h",
    "content": "/* copied from kernel definition, but with padding replaced\n * by the corresponding correctly-sized userspace types. */\n\nstruct stat {\n\tdev_t st_dev;\n\tint __st_dev_padding;\n\tlong __st_ino_truncated;\n\tmode_t st_mode;\n\tnlink_t st_nlink;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tdev_t st_rdev;\n\tint __st_rdev_padding;\n\toff_t st_size;\n\tblksize_t st_blksize;\n\tblkcnt_t st_blocks;\n\tstruct {\n\t\tlong tv_sec;\n\t\tlong tv_nsec;\n\t} __st_atim32, __st_mtim32, __st_ctim32;\n\tino_t st_ino;\n\tstruct timespec st_atim;\n\tstruct timespec st_mtim;\n\tstruct timespec st_ctim;\n};\n"
  },
  {
    "path": "user.libc/arch/sh/bits/stdint.h",
    "content": "typedef int32_t int_fast16_t;\ntypedef int32_t int_fast32_t;\ntypedef uint32_t uint_fast16_t;\ntypedef uint32_t uint_fast32_t;\n\n#define INT_FAST16_MIN  INT32_MIN\n#define INT_FAST32_MIN  INT32_MIN\n\n#define INT_FAST16_MAX  INT32_MAX\n#define INT_FAST32_MAX  INT32_MAX\n\n#define UINT_FAST16_MAX UINT32_MAX\n#define UINT_FAST32_MAX UINT32_MAX\n\n#define INTPTR_MIN      INT32_MIN\n#define INTPTR_MAX      INT32_MAX\n#define UINTPTR_MAX     UINT32_MAX\n#define PTRDIFF_MIN     INT32_MIN\n#define PTRDIFF_MAX     INT32_MAX\n#define SIZE_MAX        UINT32_MAX\n"
  },
  {
    "path": "user.libc/arch/sh/bits/syscall.h.in",
    "content": "#define __NR_restart_syscall        0\n#define __NR_exit                   1\n#define __NR_fork                   2\n#define __NR_read                   3\n#define __NR_write                  4\n#define __NR_open                   5\n#define __NR_close                  6\n#define __NR_waitpid                7\n#define __NR_creat                  8\n#define __NR_link                   9\n#define __NR_unlink                 10\n#define __NR_execve                 11\n#define __NR_chdir                  12\n#define __NR_time                   13\n#define __NR_mknod                  14\n#define __NR_chmod                  15\n#define __NR_lchown                 16\n#define __NR_oldstat                18\n#define __NR_lseek                  19\n#define __NR_getpid                 20\n#define __NR_mount                  21\n#define __NR_umount                 22\n#define __NR_setuid                 23\n#define __NR_getuid                 24\n#define __NR_stime                  25\n#define __NR_ptrace                 26\n#define __NR_alarm                  27\n#define __NR_oldfstat               28\n#define __NR_pause                  29\n#define __NR_utime                  30\n#define __NR_access                 33\n#define __NR_nice                   34\n#define __NR_sync                   36\n#define __NR_kill                   37\n#define __NR_rename                 38\n#define __NR_mkdir                  39\n#define __NR_rmdir                  40\n#define __NR_dup                    41\n#define __NR_pipe                   42\n#define __NR_times                  43\n#define __NR_brk                    45\n#define __NR_setgid                 46\n#define __NR_getgid                 47\n#define __NR_signal                 48\n#define __NR_geteuid                49\n#define __NR_getegid                50\n#define __NR_acct                   51\n#define __NR_umount2                52\n#define __NR_ioctl                  54\n#define __NR_fcntl                  55\n#define __NR_setpgid                57\n#define __NR_umask                  60\n#define __NR_chroot                 61\n#define __NR_ustat                  62\n#define __NR_dup2                   63\n#define __NR_getppid                64\n#define __NR_getpgrp                65\n#define __NR_setsid                 66\n#define __NR_sigaction              67\n#define __NR_sgetmask               68\n#define __NR_ssetmask               69\n#define __NR_setreuid               70\n#define __NR_setregid               71\n#define __NR_sigsuspend             72\n#define __NR_sigpending             73\n#define __NR_sethostname            74\n#define __NR_setrlimit              75\n#define __NR_getrlimit              76\n#define __NR_getrusage              77\n#define __NR_gettimeofday_time32           78\n#define __NR_settimeofday_time32           79\n#define __NR_getgroups              80\n#define __NR_setgroups              81\n#define __NR_symlink                83\n#define __NR_oldlstat               84\n#define __NR_readlink               85\n#define __NR_uselib                 86\n#define __NR_swapon                 87\n#define __NR_reboot                 88\n#define __NR_readdir                89\n#define __NR_mmap                   90\n#define __NR_munmap                 91\n#define __NR_truncate               92\n#define __NR_ftruncate              93\n#define __NR_fchmod                 94\n#define __NR_fchown                 95\n#define __NR_getpriority            96\n#define __NR_setpriority            97\n#define __NR_statfs                 99\n#define __NR_fstatfs                100\n#define __NR_socketcall             102\n#define __NR_syslog                 103\n#define __NR_setitimer              104\n#define __NR_getitimer              105\n#define __NR_stat                   106\n#define __NR_lstat                  107\n#define __NR_fstat                  108\n#define __NR_olduname               109\n#define __NR_vhangup                111\n#define __NR_wait4                  114\n#define __NR_swapoff                115\n#define __NR_sysinfo                116\n#define __NR_ipc                    117\n#define __NR_fsync                  118\n#define __NR_sigreturn              119\n#define __NR_clone                  120\n#define __NR_setdomainname          121\n#define __NR_uname                  122\n#define __NR_cacheflush             123\n#define __NR_adjtimex               124\n#define __NR_mprotect               125\n#define __NR_sigprocmask            126\n#define __NR_init_module            128\n#define __NR_delete_module          129\n#define __NR_quotactl               131\n#define __NR_getpgid                132\n#define __NR_fchdir                 133\n#define __NR_bdflush                134\n#define __NR_sysfs                  135\n#define __NR_personality            136\n#define __NR_setfsuid               138\n#define __NR_setfsgid               139\n#define __NR__llseek                140\n#define __NR_getdents               141\n#define __NR__newselect             142\n#define __NR_flock                  143\n#define __NR_msync                  144\n#define __NR_readv                  145\n#define __NR_writev                 146\n#define __NR_getsid                 147\n#define __NR_fdatasync              148\n#define __NR__sysctl                149\n#define __NR_mlock                  150\n#define __NR_munlock                151\n#define __NR_mlockall               152\n#define __NR_munlockall             153\n#define __NR_sched_setparam         154\n#define __NR_sched_getparam         155\n#define __NR_sched_setscheduler     156\n#define __NR_sched_getscheduler     157\n#define __NR_sched_yield            158\n#define __NR_sched_get_priority_max 159\n#define __NR_sched_get_priority_min 160\n#define __NR_sched_rr_get_interval  161\n#define __NR_nanosleep              162\n#define __NR_mremap                 163\n#define __NR_setresuid              164\n#define __NR_getresuid              165\n#define __NR_poll                   168\n#define __NR_nfsservctl             169\n#define __NR_setresgid              170\n#define __NR_getresgid              171\n#define __NR_prctl                  172\n#define __NR_rt_sigreturn           173\n#define __NR_rt_sigaction           174\n#define __NR_rt_sigprocmask         175\n#define __NR_rt_sigpending          176\n#define __NR_rt_sigtimedwait        177\n#define __NR_rt_sigqueueinfo        178\n#define __NR_rt_sigsuspend          179\n#define __NR_pread64                180\n#define __NR_pwrite64               181\n#define __NR_chown                  182\n#define __NR_getcwd                 183\n#define __NR_capget                 184\n#define __NR_capset                 185\n#define __NR_sigaltstack            186\n#define __NR_sendfile               187\n#define __NR_vfork                  190\n#define __NR_ugetrlimit             191\n#define __NR_mmap2                  192\n#define __NR_truncate64             193\n#define __NR_ftruncate64            194\n#define __NR_stat64                 195\n#define __NR_lstat64                196\n#define __NR_fstat64                197\n#define __NR_lchown32               198\n#define __NR_getuid32               199\n#define __NR_getgid32               200\n#define __NR_geteuid32              201\n#define __NR_getegid32              202\n#define __NR_setreuid32             203\n#define __NR_setregid32             204\n#define __NR_getgroups32            205\n#define __NR_setgroups32            206\n#define __NR_fchown32               207\n#define __NR_setresuid32            208\n#define __NR_getresuid32            209\n#define __NR_setresgid32            210\n#define __NR_getresgid32            211\n#define __NR_chown32                212\n#define __NR_setuid32               213\n#define __NR_setgid32               214\n#define __NR_setfsuid32             215\n#define __NR_setfsgid32             216\n#define __NR_pivot_root             217\n#define __NR_mincore                218\n#define __NR_madvise                219\n#define __NR_getdents64             220\n#define __NR_fcntl64                221\n#define __NR_gettid                 224\n#define __NR_readahead              225\n#define __NR_setxattr               226\n#define __NR_lsetxattr              227\n#define __NR_fsetxattr              228\n#define __NR_getxattr               229\n#define __NR_lgetxattr              230\n#define __NR_fgetxattr              231\n#define __NR_listxattr              232\n#define __NR_llistxattr             233\n#define __NR_flistxattr             234\n#define __NR_removexattr            235\n#define __NR_lremovexattr           236\n#define __NR_fremovexattr           237\n#define __NR_tkill                  238\n#define __NR_sendfile64             239\n#define __NR_futex                  240\n#define __NR_sched_setaffinity      241\n#define __NR_sched_getaffinity      242\n#define __NR_io_setup               245\n#define __NR_io_destroy             246\n#define __NR_io_getevents           247\n#define __NR_io_submit              248\n#define __NR_io_cancel              249\n#define __NR_fadvise64              250\n#define __NR_exit_group             252\n#define __NR_lookup_dcookie         253\n#define __NR_epoll_create           254\n#define __NR_epoll_ctl              255\n#define __NR_epoll_wait             256\n#define __NR_remap_file_pages       257\n#define __NR_set_tid_address        258\n#define __NR_timer_create           259\n#define __NR_timer_settime32          260\n#define __NR_timer_gettime32          261\n#define __NR_timer_getoverrun       262\n#define __NR_timer_delete           263\n#define __NR_clock_settime32          264\n#define __NR_clock_gettime32          265\n#define __NR_clock_getres_time32           266\n#define __NR_clock_nanosleep_time32        267\n#define __NR_statfs64               268\n#define __NR_fstatfs64              269\n#define __NR_tgkill                 270\n#define __NR_utimes                 271\n#define __NR_fadvise64_64           272\n#define __NR_mbind                  274\n#define __NR_get_mempolicy          275\n#define __NR_set_mempolicy          276\n#define __NR_mq_open                277\n#define __NR_mq_unlink              278\n#define __NR_mq_timedsend           279\n#define __NR_mq_timedreceive        280\n#define __NR_mq_notify              281\n#define __NR_mq_getsetattr          282\n#define __NR_kexec_load             283\n#define __NR_waitid                 284\n#define __NR_add_key                285\n#define __NR_request_key            286\n#define __NR_keyctl                 287\n#define __NR_ioprio_set             288\n#define __NR_ioprio_get             289\n#define __NR_inotify_init           290\n#define __NR_inotify_add_watch      291\n#define __NR_inotify_rm_watch       292\n#define __NR_migrate_pages          294\n#define __NR_openat                 295\n#define __NR_mkdirat                296\n#define __NR_mknodat                297\n#define __NR_fchownat               298\n#define __NR_futimesat              299\n#define __NR_fstatat64              300\n#define __NR_unlinkat               301\n#define __NR_renameat               302\n#define __NR_linkat                 303\n#define __NR_symlinkat              304\n#define __NR_readlinkat             305\n#define __NR_fchmodat               306\n#define __NR_faccessat              307\n#define __NR_pselect6               308\n#define __NR_ppoll                  309\n#define __NR_unshare                310\n#define __NR_set_robust_list        311\n#define __NR_get_robust_list        312\n#define __NR_splice                 313\n#define __NR_sync_file_range        314\n#define __NR_tee                    315\n#define __NR_vmsplice               316\n#define __NR_move_pages             317\n#define __NR_getcpu                 318\n#define __NR_epoll_pwait            319\n#define __NR_utimensat              320\n#define __NR_signalfd               321\n#define __NR_timerfd_create         322\n#define __NR_eventfd                323\n#define __NR_fallocate              324\n#define __NR_timerfd_settime32        325\n#define __NR_timerfd_gettime32        326\n#define __NR_signalfd4              327\n#define __NR_eventfd2               328\n#define __NR_epoll_create1          329\n#define __NR_dup3                   330\n#define __NR_pipe2                  331\n#define __NR_inotify_init1          332\n#define __NR_preadv                 333\n#define __NR_pwritev                334\n#define __NR_rt_tgsigqueueinfo      335\n#define __NR_perf_event_open        336\n#define __NR_fanotify_init          337\n#define __NR_fanotify_mark          338\n#define __NR_prlimit64              339\n#define __NR_socket                 340\n#define __NR_bind                   341\n#define __NR_connect                342\n#define __NR_listen                 343\n#define __NR_accept                 344\n#define __NR_getsockname            345\n#define __NR_getpeername            346\n#define __NR_socketpair             347\n#define __NR_send                   348\n#define __NR_sendto                 349\n#define __NR_recv                   350\n#define __NR_recvfrom               351\n#define __NR_shutdown               352\n#define __NR_setsockopt             353\n#define __NR_getsockopt             354\n#define __NR_sendmsg                355\n#define __NR_recvmsg                356\n#define __NR_recvmmsg               357\n#define __NR_accept4                358\n#define __NR_name_to_handle_at      359\n#define __NR_open_by_handle_at      360\n#define __NR_clock_adjtime          361\n#define __NR_syncfs                 362\n#define __NR_sendmmsg               363\n#define __NR_setns                  364\n#define __NR_process_vm_readv       365\n#define __NR_process_vm_writev      366\n#define __NR_kcmp                   367\n#define __NR_finit_module           368\n#define __NR_sched_getattr          369\n#define __NR_sched_setattr          370\n#define __NR_renameat2              371\n#define __NR_seccomp                372\n#define __NR_getrandom              373\n#define __NR_memfd_create           374\n#define __NR_bpf                    375\n#define __NR_execveat               376\n#define __NR_userfaultfd            377\n#define __NR_membarrier             378\n#define __NR_mlock2                 379\n#define __NR_copy_file_range        380\n#define __NR_preadv2                381\n#define __NR_pwritev2               382\n#define __NR_statx                  383\n#define __NR_pkey_mprotect          384\n#define __NR_pkey_alloc             385\n#define __NR_pkey_free              386\n#define __NR_rseq                   387\n#define __NR_semget                 393\n#define __NR_semctl                 394\n#define __NR_shmget                 395\n#define __NR_shmctl                 396\n#define __NR_shmat                  397\n#define __NR_shmdt                  398\n#define __NR_msgget                 399\n#define __NR_msgsnd                 400\n#define __NR_msgrcv                 401\n#define __NR_msgctl                 402\n#define __NR_clock_gettime64        403\n#define __NR_clock_settime64        404\n#define __NR_clock_adjtime64        405\n#define __NR_clock_getres_time64    406\n#define __NR_clock_nanosleep_time64 407\n#define __NR_timer_gettime64        408\n#define __NR_timer_settime64        409\n#define __NR_timerfd_gettime64      410\n#define __NR_timerfd_settime64      411\n#define __NR_utimensat_time64       412\n#define __NR_pselect6_time64        413\n#define __NR_ppoll_time64           414\n#define __NR_io_pgetevents_time64   416\n#define __NR_recvmmsg_time64        417\n#define __NR_mq_timedsend_time64    418\n#define __NR_mq_timedreceive_time64 419\n#define __NR_semtimedop_time64      420\n#define __NR_rt_sigtimedwait_time64 421\n#define __NR_futex_time64           422\n#define __NR_sched_rr_get_interval_time64 423\n#define __NR_pidfd_send_signal      424\n#define __NR_io_uring_setup         425\n#define __NR_io_uring_enter         426\n#define __NR_io_uring_register      427\n#define __NR_open_tree\t\t428\n#define __NR_move_mount\t\t429\n#define __NR_fsopen\t\t430\n#define __NR_fsconfig\t\t431\n#define __NR_fsmount\t\t432\n#define __NR_fspick\t\t433\n#define __NR_pidfd_open\t\t434\n#define __NR_clone3\t\t435\n#define __NR_close_range\t436\n#define __NR_openat2\t\t437\n#define __NR_pidfd_getfd\t438\n#define __NR_faccessat2\t\t439\n\n"
  },
  {
    "path": "user.libc/arch/sh/bits/user.h",
    "content": "#undef __WORDSIZE\n#define __WORDSIZE 32\n\n#define REG_REG0\t 0\n#define REG_REG15\t15\n#define REG_PC\t\t16\n#define REG_PR\t\t17\n#define REG_SR\t\t18\n#define REG_GBR\t\t19\n#define REG_MACH\t20\n#define REG_MACL\t21\n#define REG_SYSCALL\t22\n#define REG_FPREG0\t23\n#define REG_FPREG15\t38\n#define REG_XFREG0\t39\n#define REG_XFREG15\t54\n#define REG_FPSCR\t55\n#define REG_FPUL\t56\n\nstruct user_fpu_struct {\n\tunsigned long fp_regs[16];\n\tunsigned long xfp_regs[16];\n\tunsigned long fpscr;\n\tunsigned long fpul;\n};\n\n#define ELF_NGREG 23\ntypedef unsigned long elf_greg_t;\ntypedef elf_greg_t elf_gregset_t[ELF_NGREG];\ntypedef struct user_fpu_struct elf_fpregset_t;\n\nstruct user {\n\tstruct {\n\t\tunsigned long regs[16];\n\t\tunsigned long pc, pr, sr, gbr, mach, macl;\n\t\tlong tra;\n\t} regs;\n\tstruct user_fpu_struct fpu;\n\tint u_fpvalid;\n\tunsigned long u_tsize;\n\tunsigned long u_dsize;\n\tunsigned long u_ssize;\n\tunsigned long start_code;\n\tunsigned long start_data;\n\tunsigned long start_stack;\n\tlong int signal;\n\tunsigned long u_ar0;\n\tstruct user_fpu_struct *u_fpstate;\n\tunsigned long magic;\n\tchar u_comm[32];\n};\n"
  },
  {
    "path": "user.libc/arch/sh/crt_arch.h",
    "content": "#ifdef __SH_FDPIC__\n\n__asm__(\n\".text \\n\"\n\".global \" START \" \\n\"\nSTART \": \\n\"\n\"\ttst r8, r8 \\n\"\n\"\tbf 1f \\n\"\n\"\tmov #68, r3 \\n\"\n\"\tadd r3, r3 \\n\"\n\"\tmov #8, r4 \\n\"\n\"\tswap.w r4, r4 \\n\"\n\"\ttrapa #31 \\n\"\n\"\tnop \\n\"\n\"\tnop \\n\"\n\"\tnop \\n\"\n\"\tnop \\n\"\n\"1:\tnop \\n\"\n#ifndef SHARED\n\"\tmov r8, r4 \\n\"\n\"\tmova 1f, r0 \\n\"\n\"\tmov.l 1f, r5 \\n\"\n\"\tmov.l 1f+4, r6 \\n\"\n\"\tadd r0, r5 \\n\"\n\"\tmov.l 4f, r1 \\n\"\n\"5:\tbsrf r1 \\n\"\n\"\t add r0, r6 \\n\"\n\"\tmov r0, r12 \\n\"\n#endif\n\"\tmov r10, r5 \\n\"\n\"\tmov r15, r4 \\n\"\n\"\tmov.l r9, @-r15 \\n\"\n\"\tmov.l r8, @-r15 \\n\"\n\"\tmov #-16, r0 \\n\"\n\"\tmov.l 2f, r1 \\n\"\n\"3:\tbsrf r1 \\n\"\n\"\t and r0, r15 \\n\"\n\".align 2 \\n\"\n\"1:\t.long __ROFIXUP_LIST__@PCREL \\n\"\n\"\t.long __ROFIXUP_END__@PCREL + 4 \\n\"\n\"2:\t.long \" START \"_c@PCREL - (3b+4-.) \\n\"\n#ifndef SHARED\n\"4:\t.long __fdpic_fixup@PCREL - (5b+4-.) \\n\"\n#endif\n);\n\n#ifndef SHARED\n#include \"fdpic_crt.h\"\n#endif\n\n#else\n\n__asm__(\n\".text \\n\"\n\".global \" START \" \\n\"\nSTART \": \\n\"\n\"\tmova 1f, r0 \\n\"\n\"\tmov.l 1f, r5 \\n\"\n\"\tadd r0, r5 \\n\"\n\"\tmov r15, r4 \\n\"\n\"\tmov #-16, r0 \\n\"\n\"\tmov.l 2f, r1 \\n\"\n\"3:\tbsrf r1 \\n\"\n\"\t and r0, r15 \\n\"\n\".align 2 \\n\"\n\".weak _DYNAMIC \\n\"\n\".hidden _DYNAMIC \\n\"\n\"1:\t.long _DYNAMIC-. \\n\"\n\"2:\t.long \" START \"_c@PCREL - (3b+4-.) \\n\"\n);\n\n#endif\n\n/* used by gcc for switching the FPU between single and double precision */\n#ifdef SHARED\n__attribute__((__visibility__(\"hidden\")))\n#endif\nconst unsigned long __fpscr_values[2] = { 0, 0x80000 };\n"
  },
  {
    "path": "user.libc/arch/sh/ksigaction.h",
    "content": "#include <features.h>\n\nstruct k_sigaction {\n\tvoid (*handler)(int);\n\tunsigned long flags;\n\tvoid *restorer;\n\tunsigned mask[2];\n};\n\nextern hidden unsigned char __restore[], __restore_rt[];\n"
  },
  {
    "path": "user.libc/arch/sh/kstat.h",
    "content": "struct kstat {\n\tdev_t st_dev;\n\tint __st_dev_padding;\n\tlong __st_ino_truncated;\n\tmode_t st_mode;\n\tnlink_t st_nlink;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tdev_t st_rdev;\n\tint __st_rdev_padding;\n\toff_t st_size;\n\tblksize_t st_blksize;\n\tblkcnt_t st_blocks;\n\tlong st_atime_sec;\n\tlong st_atime_nsec;\n\tlong st_mtime_sec;\n\tlong st_mtime_nsec;\n\tlong st_ctime_sec;\n\tlong st_ctime_nsec;\n\tino_t st_ino;\n};\n"
  },
  {
    "path": "user.libc/arch/sh/pthread_arch.h",
    "content": "static inline uintptr_t __get_tp()\n{\n\tuintptr_t tp;\n\t__asm__ (\"stc gbr,%0\" : \"=r\" (tp) );\n\treturn tp;\n}\n\n#define TLS_ABOVE_TP\n#define GAP_ABOVE_TP 8\n\n#define MC_PC pc\n\n#ifdef __FDPIC__\n#define MC_GOT gregs[12]\n#define CANCEL_GOT (*(uintptr_t *)((char *)__syscall_cp_asm+sizeof(uintptr_t)))\n#endif\n"
  },
  {
    "path": "user.libc/arch/sh/reloc.h",
    "content": "#if __BYTE_ORDER == __BIG_ENDIAN\n#define ENDIAN_SUFFIX \"eb\"\n#else\n#define ENDIAN_SUFFIX \"\"\n#endif\n\n#if __SH_FPU_ANY__ || __SH4__\n#define FP_SUFFIX \"\"\n#else\n#define FP_SUFFIX \"-nofpu\"\n#endif\n\n#if __SH_FDPIC__\n#define ABI_SUFFIX \"-fdpic\"\n#else\n#define ABI_SUFFIX \"\"\n#endif\n\n#define LDSO_ARCH \"sh\" ENDIAN_SUFFIX FP_SUFFIX ABI_SUFFIX\n\n#define TPOFF_K 0\n\n#define REL_SYMBOLIC    R_SH_DIR32\n#define REL_OFFSET      R_SH_REL32\n#define REL_GOT         R_SH_GLOB_DAT\n#define REL_PLT         R_SH_JMP_SLOT\n#define REL_RELATIVE    R_SH_RELATIVE\n#define REL_COPY        R_SH_COPY\n#define REL_DTPMOD      R_SH_TLS_DTPMOD32\n#define REL_DTPOFF      R_SH_TLS_DTPOFF32\n#define REL_TPOFF       R_SH_TLS_TPOFF32\n\n#define DL_NOMMU_SUPPORT 1\n\n#if __SH_FDPIC__\n#define REL_FUNCDESC    R_SH_FUNCDESC\n#define REL_FUNCDESC_VAL R_SH_FUNCDESC_VALUE\n#undef  REL_RELATIVE\n#define DL_FDPIC 1\n#define FDPIC_CONSTDISP_FLAG 0x100\n#define CRTJMP(pc,sp) do { \\\n\tregister size_t r8 __asm__(\"r8\") = ((size_t *)(sp))[-2]; \\\n\t__asm__ __volatile__( \"jmp @%0 ; mov %1,r15\" \\\n\t: : \"r\"(pc), \"r\"(sp), \"r\"(r8) : \"memory\" ); } while(0)\n#define GETFUNCSYM(fp, sym, got) __asm__ ( \\\n\t\"mov.l 1f,%0 ; add %1,%0 ; bra 2f ; nop ; .align 2 \\n\" \\\n\t\"1:\t.long \" #sym \"@GOTOFFFUNCDESC \\n2:\" \\\n\t: \"=&r\"(*fp) : \"r\"(got) : \"memory\" )\n#else\n#define CRTJMP(pc,sp) __asm__ __volatile__( \\\n\t\"jmp @%0 ; mov %1,r15\" : : \"r\"(pc), \"r\"(sp) : \"memory\" )\n#endif\n"
  },
  {
    "path": "user.libc/arch/sh/syscall_arch.h",
    "content": "#define __SYSCALL_LL_E(x) \\\n((union { long long ll; long l[2]; }){ .ll = x }).l[0], \\\n((union { long long ll; long l[2]; }){ .ll = x }).l[1]\n#define __SYSCALL_LL_O(x) __SYSCALL_LL_E((x))\n#define __SYSCALL_LL_PRW(x) 0, __SYSCALL_LL_E((x))\n\n/* The extra OR instructions are to work around a hardware bug:\n * http://documentation.renesas.com/doc/products/mpumcu/tu/tnsh7456ae.pdf\n */\n#define __asm_syscall(trapno, ...) do {   \\\n\t__asm__ __volatile__ (                \\\n\t\t\"trapa #31\\n\"            \\\n\t\t\"or r0, r0\\n\"                     \\\n\t\t\"or r0, r0\\n\"                     \\\n\t\t\"or r0, r0\\n\"                     \\\n\t\t\"or r0, r0\\n\"                     \\\n\t\t\"or r0, r0\\n\"                     \\\n\t: \"=r\"(r0) : __VA_ARGS__ : \"memory\"); \\\n\treturn r0;                            \\\n\t} while (0)\n\nstatic inline long __syscall0(long n)\n{\n\tregister long r3 __asm__(\"r3\") = n;\n\tregister long r0 __asm__(\"r0\");\n\t__asm_syscall(16, \"r\"(r3));\n}\n\nstatic inline long __syscall1(long n, long a)\n{\n\tregister long r3 __asm__(\"r3\") = n;\n\tregister long r4 __asm__(\"r4\") = a;\n\tregister long r0 __asm__(\"r0\");\n\t__asm_syscall(17, \"r\"(r3), \"r\"(r4));\n}\n\nstatic inline long __syscall2(long n, long a, long b)\n{\n\tregister long r3 __asm__(\"r3\") = n;\n\tregister long r4 __asm__(\"r4\") = a;\n\tregister long r5 __asm__(\"r5\") = b;\n\tregister long r0 __asm__(\"r0\");\n\t__asm_syscall(18, \"r\"(r3), \"r\"(r4), \"r\"(r5));\n}\n\nstatic inline long __syscall3(long n, long a, long b, long c)\n{\n\tregister long r3 __asm__(\"r3\") = n;\n\tregister long r4 __asm__(\"r4\") = a;\n\tregister long r5 __asm__(\"r5\") = b;\n\tregister long r6 __asm__(\"r6\") = c;\n\tregister long r0 __asm__(\"r0\");\n\t__asm_syscall(19, \"r\"(r3), \"r\"(r4), \"r\"(r5), \"r\"(r6));\n}\n\nstatic inline long __syscall4(long n, long a, long b, long c, long d)\n{\n\tregister long r3 __asm__(\"r3\") = n;\n\tregister long r4 __asm__(\"r4\") = a;\n\tregister long r5 __asm__(\"r5\") = b;\n\tregister long r6 __asm__(\"r6\") = c;\n\tregister long r7 __asm__(\"r7\") = d;\n\tregister long r0 __asm__(\"r0\");\n\t__asm_syscall(20, \"r\"(r3), \"r\"(r4), \"r\"(r5), \"r\"(r6), \"r\"(r7));\n}\n\nstatic inline long __syscall5(long n, long a, long b, long c, long d, long e)\n{\n\tregister long r3 __asm__(\"r3\") = n;\n\tregister long r4 __asm__(\"r4\") = a;\n\tregister long r5 __asm__(\"r5\") = b;\n\tregister long r6 __asm__(\"r6\") = c;\n\tregister long r7 __asm__(\"r7\") = d;\n\tregister long r0 __asm__(\"r0\") = e;\n\t__asm_syscall(21, \"r\"(r3), \"r\"(r4), \"r\"(r5), \"r\"(r6), \"r\"(r7), \"0\"(r0));\n}\n\nstatic inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)\n{\n\tregister long r3 __asm__(\"r3\") = n;\n\tregister long r4 __asm__(\"r4\") = a;\n\tregister long r5 __asm__(\"r5\") = b;\n\tregister long r6 __asm__(\"r6\") = c;\n\tregister long r7 __asm__(\"r7\") = d;\n\tregister long r0 __asm__(\"r0\") = e;\n\tregister long r1 __asm__(\"r1\") = f;\n\t__asm_syscall(22, \"r\"(r3), \"r\"(r4), \"r\"(r5), \"r\"(r6), \"r\"(r7), \"0\"(r0), \"r\"(r1));\n}\n\n#define SYSCALL_IPC_BROKEN_MODE\n\n#define SIOCGSTAMP_OLD   (2U<<30 | 's'<<8 | 100 | 8<<16)\n#define SIOCGSTAMPNS_OLD (2U<<30 | 's'<<8 | 101 | 8<<16)\n"
  },
  {
    "path": "user.libc/arch/x32/atomic_arch.h",
    "content": "#define a_cas a_cas\nstatic inline int a_cas(volatile int *p, int t, int s)\n{\n\t__asm__ __volatile__ (\n\t\t\"lock ; cmpxchg %3, %1\"\n\t\t: \"=a\"(t), \"=m\"(*p) : \"a\"(t), \"r\"(s) : \"memory\" );\n\treturn t;\n}\n\n#define a_swap a_swap\nstatic inline int a_swap(volatile int *p, int v)\n{\n\t__asm__ __volatile__(\n\t\t\"xchg %0, %1\"\n\t\t: \"=r\"(v), \"=m\"(*p) : \"0\"(v) : \"memory\" );\n\treturn v;\n}\n\n#define a_fetch_add a_fetch_add\nstatic inline int a_fetch_add(volatile int *p, int v)\n{\n\t__asm__ __volatile__(\n\t\t\"lock ; xadd %0, %1\"\n\t\t: \"=r\"(v), \"=m\"(*p) : \"0\"(v) : \"memory\" );\n\treturn v;\n}\n\n#define a_and a_and\nstatic inline void a_and(volatile int *p, int v)\n{\n\t__asm__ __volatile__(\n\t\t\"lock ; and %1, %0\"\n\t\t: \"=m\"(*p) : \"r\"(v) : \"memory\" );\n}\n\n#define a_or a_or\nstatic inline void a_or(volatile int *p, int v)\n{\n\t__asm__ __volatile__(\n\t\t\"lock ; or %1, %0\"\n\t\t: \"=m\"(*p) : \"r\"(v) : \"memory\" );\n}\n\n#define a_and_64 a_and_64\nstatic inline void a_and_64(volatile uint64_t *p, uint64_t v)\n{\n\t__asm__ __volatile(\n\t\t\"lock ; and %1, %0\"\n\t\t : \"=m\"(*p) : \"r\"(v) : \"memory\" );\n}\n\n#define a_or_64 a_or_64\nstatic inline void a_or_64(volatile uint64_t *p, uint64_t v)\n{\n\t__asm__ __volatile__(\n\t\t\"lock ; or %1, %0\"\n\t\t : \"=m\"(*p) : \"r\"(v) : \"memory\" );\n}\n\n#define a_inc a_inc\nstatic inline void a_inc(volatile int *p)\n{\n\t__asm__ __volatile__(\n\t\t\"lock ; incl %0\"\n\t\t: \"=m\"(*p) : \"m\"(*p) : \"memory\" );\n}\n\n#define a_dec a_dec\nstatic inline void a_dec(volatile int *p)\n{\n\t__asm__ __volatile__(\n\t\t\"lock ; decl %0\"\n\t\t: \"=m\"(*p) : \"m\"(*p) : \"memory\" );\n}\n\n#define a_store a_store\nstatic inline void a_store(volatile int *p, int x)\n{\n\t__asm__ __volatile__(\n\t\t\"mov %1, %0 ; lock ; orl $0,(%%rsp)\"\n\t\t: \"=m\"(*p) : \"r\"(x) : \"memory\" );\n}\n\n#define a_barrier a_barrier\nstatic inline void a_barrier()\n{\n\t__asm__ __volatile__( \"\" : : : \"memory\" );\n}\n\n#define a_spin a_spin\nstatic inline void a_spin()\n{\n\t__asm__ __volatile__( \"pause\" : : : \"memory\" );\n}\n\n#define a_crash a_crash\nstatic inline void a_crash()\n{\n\t__asm__ __volatile__( \"hlt\" : : : \"memory\" );\n}\n\n#define a_ctz_64 a_ctz_64\nstatic inline int a_ctz_64(uint64_t x)\n{\n\t__asm__( \"bsf %1,%0\" : \"=r\"(x) : \"r\"(x) );\n\treturn x;\n}\n\n#define a_ctz_32 a_ctz_32\nstatic inline int a_ctz_32(uint32_t x)\n{\n\t__asm__( \"bsf %1,%0\" : \"=r\"(x) : \"r\"(x) );\n\treturn x;\n}\n\n#define a_clz_64 a_clz_64\nstatic inline int a_clz_64(uint64_t x)\n{\n\t__asm__( \"bsr %1,%0 ; xor $63,%0\" : \"=r\"(x) : \"r\"(x) );\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/arch/x32/bits/alltypes.h.in",
    "content": "#define _Addr int\n#define _Int64 long long\n#define _Reg long long\n\n#define __BYTE_ORDER 1234\n#define __LONG_MAX 0x7fffffffL\n\n#ifndef __cplusplus\n#ifdef __WCHAR_TYPE__\nTYPEDEF __WCHAR_TYPE__ wchar_t;\n#else\nTYPEDEF long wchar_t;\n#endif\n#endif\n\n#if defined(__FLT_EVAL_METHOD__) && __FLT_EVAL_METHOD__ == 2\nTYPEDEF long double float_t;\nTYPEDEF long double double_t;\n#else\nTYPEDEF float float_t;\nTYPEDEF double double_t;\n#endif\n\nTYPEDEF struct { long long __ll; long double __ld; } max_align_t;\n"
  },
  {
    "path": "user.libc/arch/x32/bits/fcntl.h",
    "content": "#define O_CREAT        0100\n#define O_EXCL         0200\n#define O_NOCTTY       0400\n#define O_TRUNC       01000\n#define O_APPEND      02000\n#define O_NONBLOCK    04000\n#define O_DSYNC      010000\n#define O_SYNC     04010000\n#define O_RSYNC    04010000\n#define O_DIRECTORY 0200000\n#define O_NOFOLLOW  0400000\n#define O_CLOEXEC  02000000\n\n#define O_ASYNC      020000\n#define O_DIRECT     040000\n#define O_LARGEFILE 0100000\n#define O_NOATIME  01000000\n#define O_PATH    010000000\n#define O_TMPFILE 020200000\n#define O_NDELAY O_NONBLOCK\n\n#define F_DUPFD  0\n#define F_GETFD  1\n#define F_SETFD  2\n#define F_GETFL  3\n#define F_SETFL  4\n\n#define F_SETOWN 8\n#define F_GETOWN 9\n#define F_SETSIG 10\n#define F_GETSIG 11\n\n#define F_GETLK 5\n#define F_SETLK 6\n#define F_SETLKW 7\n\n#define F_SETOWN_EX 15\n#define F_GETOWN_EX 16\n\n#define F_GETOWNER_UIDS 17\n"
  },
  {
    "path": "user.libc/arch/x32/bits/fenv.h",
    "content": "#define FE_INVALID    1\n#define __FE_DENORM   2\n#define FE_DIVBYZERO  4\n#define FE_OVERFLOW   8\n#define FE_UNDERFLOW  16\n#define FE_INEXACT    32\n\n#define FE_ALL_EXCEPT 63\n\n#define FE_TONEAREST  0\n#define FE_DOWNWARD   0x400\n#define FE_UPWARD     0x800\n#define FE_TOWARDZERO 0xc00\n\ntypedef unsigned short fexcept_t;\n\ntypedef struct {\n\tunsigned short __control_word;\n\tunsigned short __unused1;\n\tunsigned short __status_word;\n\tunsigned short __unused2;\n\tunsigned short __tags;\n\tunsigned short __unused3;\n\tunsigned int __eip;\n\tunsigned short __cs_selector;\n\tunsigned int __opcode:11;\n\tunsigned int __unused4:5;\n\tunsigned int __data_offset;\n\tunsigned short __data_selector;\n\tunsigned short __unused5;\n\tunsigned int __mxcsr;\n} fenv_t;\n\n#define FE_DFL_ENV      ((const fenv_t *) -1)\n"
  },
  {
    "path": "user.libc/arch/x32/bits/float.h",
    "content": "#ifdef __FLT_EVAL_METHOD__\n#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__\n#else\n#define FLT_EVAL_METHOD 0\n#endif\n\n#define LDBL_TRUE_MIN 3.6451995318824746025e-4951L\n#define LDBL_MIN     3.3621031431120935063e-4932L\n#define LDBL_MAX     1.1897314953572317650e+4932L\n#define LDBL_EPSILON 1.0842021724855044340e-19L\n\n#define LDBL_MANT_DIG 64\n#define LDBL_MIN_EXP (-16381)\n#define LDBL_MAX_EXP 16384\n\n#define LDBL_DIG 18\n#define LDBL_MIN_10_EXP (-4931)\n#define LDBL_MAX_10_EXP 4932\n\n#define DECIMAL_DIG 21\n"
  },
  {
    "path": "user.libc/arch/x32/bits/io.h",
    "content": "static __inline void outb(unsigned char __val, unsigned short __port)\n{\n\t__asm__ volatile (\"outb %0,%1\" : : \"a\" (__val), \"dN\" (__port));\n}\n\nstatic __inline void outw(unsigned short __val, unsigned short __port)\n{\n\t__asm__ volatile (\"outw %0,%1\" : : \"a\" (__val), \"dN\" (__port));\n}\n\nstatic __inline void outl(unsigned int __val, unsigned short __port)\n{\n\t__asm__ volatile (\"outl %0,%1\" : : \"a\" (__val), \"dN\" (__port));\n}\n\nstatic __inline unsigned char inb(unsigned short __port)\n{\n\tunsigned char __val;\n\t__asm__ volatile (\"inb %1,%0\" : \"=a\" (__val) : \"dN\" (__port));\n\treturn __val;\n}\n\nstatic __inline unsigned short inw(unsigned short __port)\n{\n\tunsigned short __val;\n\t__asm__ volatile (\"inw %1,%0\" : \"=a\" (__val) : \"dN\" (__port));\n\treturn __val;\n}\n\nstatic __inline unsigned int inl(unsigned short __port)\n{\n\tunsigned int __val;\n\t__asm__ volatile (\"inl %1,%0\" : \"=a\" (__val) : \"dN\" (__port));\n\treturn __val;\n}\n\nstatic __inline void outsb(unsigned short __port, const void *__buf, unsigned long __n)\n{\n\t__asm__ volatile (\"cld; rep; outsb\"\n\t\t      : \"+S\" (__buf), \"+c\" (__n)\n\t\t      : \"d\" (__port));\n}\n\nstatic __inline void outsw(unsigned short __port, const void *__buf, unsigned long __n)\n{\n\t__asm__ volatile (\"cld; rep; outsw\"\n\t\t      : \"+S\" (__buf), \"+c\" (__n)\n\t\t      : \"d\" (__port));\n}\n\nstatic __inline void outsl(unsigned short __port, const void *__buf, unsigned long __n)\n{\n\t__asm__ volatile (\"cld; rep; outsl\"\n\t\t      : \"+S\" (__buf), \"+c\"(__n)\n\t\t      : \"d\" (__port));\n}\n\nstatic __inline void insb(unsigned short __port, void *__buf, unsigned long __n)\n{\n\t__asm__ volatile (\"cld; rep; insb\"\n\t\t      : \"+D\" (__buf), \"+c\" (__n)\n\t\t      : \"d\" (__port));\n}\n\nstatic __inline void insw(unsigned short __port, void *__buf, unsigned long __n)\n{\n\t__asm__ volatile (\"cld; rep; insw\"\n\t\t      : \"+D\" (__buf), \"+c\" (__n)\n\t\t      : \"d\" (__port));\n}\n\nstatic __inline void insl(unsigned short __port, void *__buf, unsigned long __n)\n{\n\t__asm__ volatile (\"cld; rep; insl\"\n\t\t      : \"+D\" (__buf), \"+c\" (__n)\n\t\t      : \"d\" (__port));\n}\n"
  },
  {
    "path": "user.libc/arch/x32/bits/ioctl_fix.h",
    "content": "#undef SIOCGSTAMP\n#undef SIOCGSTAMPNS\n#define SIOCGSTAMP      0x8906\n#define SIOCGSTAMPNS    0x8907\n"
  },
  {
    "path": "user.libc/arch/x32/bits/ipc.h",
    "content": "struct ipc_perm {\n\tkey_t __ipc_perm_key;\n\tuid_t uid;\n\tgid_t gid;\n\tuid_t cuid;\n\tgid_t cgid;\n\tmode_t mode;\n\tint __ipc_perm_seq;\n\tlong long __pad1;\n\tlong long __pad2;\n};\n"
  },
  {
    "path": "user.libc/arch/x32/bits/limits.h",
    "content": "#define PAGESIZE 4096\n"
  },
  {
    "path": "user.libc/arch/x32/bits/mman.h",
    "content": "#define MAP_32BIT      0x40\n"
  },
  {
    "path": "user.libc/arch/x32/bits/msg.h",
    "content": "struct msqid_ds {\n\tstruct ipc_perm msg_perm;\n\ttime_t msg_stime;\n\ttime_t msg_rtime;\n\ttime_t msg_ctime;\n\tunsigned long msg_cbytes;\n\tlong __unused1;\n\tmsgqnum_t msg_qnum;\n\tlong __unused2;\n\tmsglen_t msg_qbytes;\n\tlong __unused3;\n\tpid_t msg_lspid;\n\tpid_t msg_lrpid;\n\tunsigned long long __unused[2];\n};\n"
  },
  {
    "path": "user.libc/arch/x32/bits/posix.h",
    "content": "#define _POSIX_V6_ILP32_OFFBIG  1\n#define _POSIX_V7_ILP32_OFFBIG  1\n"
  },
  {
    "path": "user.libc/arch/x32/bits/ptrace.h",
    "content": "#define PTRACE_GET_THREAD_AREA\t\t25\n#define PTRACE_SET_THREAD_AREA\t\t26\n#define PTRACE_ARCH_PRCTL\t\t30\n#define PTRACE_SYSEMU\t\t\t31\n#define PTRACE_SYSEMU_SINGLESTEP\t32\n#define PTRACE_SINGLEBLOCK\t\t33\n\n#define PT_GET_THREAD_AREA PTRACE_GET_THREAD_AREA\n#define PT_SET_THREAD_AREA PTRACE_SET_THREAD_AREA\n#define PT_ARCH_PRCTL PTRACE_ARCH_PRCTL\n#define PT_SYSEMU PTRACE_SYSEMU\n#define PT_SYSEMU_SINGLESTEP PTRACE_SYSEMU_SINGLESTEP\n#define PT_STEPBLOCK PTRACE_SINGLEBLOCK\n"
  },
  {
    "path": "user.libc/arch/x32/bits/reg.h",
    "content": "#undef __WORDSIZE\n#define __WORDSIZE 32\n#define R15    0\n#define R14    1\n#define R13    2\n#define R12    3\n#define RBP    4\n#define RBX    5\n#define R11    6\n#define R10    7\n#define R9     8\n#define R8     9\n#define RAX    10\n#define RCX    11\n#define RDX    12\n#define RSI    13\n#define RDI    14\n#define ORIG_RAX 15\n#define RIP    16\n#define CS     17\n#define EFLAGS 18\n#define RSP    19\n#define SS     20\n#define FS_BASE 21\n#define GS_BASE 22\n#define DS     23\n#define ES     24\n#define FS     25\n#define GS     26\n"
  },
  {
    "path": "user.libc/arch/x32/bits/sem.h",
    "content": "struct semid_ds {\n\tstruct ipc_perm sem_perm;\n\ttime_t sem_otime;\n\tlong long __unused1;\n\ttime_t sem_ctime;\n\tlong long __unused2;\n\tunsigned short sem_nsems;\n\tchar __sem_nsems_pad[sizeof(long long)-sizeof(short)];\n\tlong long __unused3;\n\tlong long __unused4;\n};\n"
  },
  {
    "path": "user.libc/arch/x32/bits/setjmp.h",
    "content": "typedef unsigned long long __jmp_buf[8];\n"
  },
  {
    "path": "user.libc/arch/x32/bits/shm.h",
    "content": "#define SHMLBA 4096\n\nstruct shmid_ds {\n\tstruct ipc_perm shm_perm;\n\tsize_t shm_segsz;\n\ttime_t shm_atime;\n\ttime_t shm_dtime;\n\ttime_t shm_ctime;\n\tpid_t shm_cpid;\n\tpid_t shm_lpid;\n\tunsigned long shm_nattch;\n\tunsigned long __pad0;\n\tunsigned long long __pad1;\n\tunsigned long long __pad2;\n};\n\nstruct shminfo {\n\tunsigned long shmmax, __pad0, shmmin, __pad1, shmmni, __pad2,\n\t              shmseg, __pad3, shmall, __pad4;\n\tunsigned long long __unused[4];\n};\n\nstruct shm_info {\n\tint __used_ids;\n\tint __pad_ids;\n\tunsigned long shm_tot, __pad0, shm_rss, __pad1, shm_swp, __pad2;\n\tunsigned long __swap_attempts, __pad3, __swap_successes, __pad4;\n}\n#ifdef __GNUC__\n__attribute__((__aligned__(8)))\n#endif\n;\n"
  },
  {
    "path": "user.libc/arch/x32/bits/signal.h",
    "content": "#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define MINSIGSTKSZ 2048\n#define SIGSTKSZ 8192\n#endif\n\n#ifdef _GNU_SOURCE\nenum { REG_R8 = 0 };\n#define REG_R8 REG_R8\nenum { REG_R9 = 1 };\n#define REG_R9 REG_R9\nenum { REG_R10 = 2 };\n#define REG_R10 REG_R10\nenum { REG_R11 = 3 };\n#define REG_R11 REG_R11\nenum { REG_R12 = 4 };\n#define REG_R12 REG_R12\nenum { REG_R13 = 5 };\n#define REG_R13 REG_R13\nenum { REG_R14 = 6 };\n#define REG_R14 REG_R14\nenum { REG_R15 = 7 };\n#define REG_R15 REG_R15\nenum { REG_RDI = 8 };\n#define REG_RDI REG_RDI\nenum { REG_RSI = 9 };\n#define REG_RSI REG_RSI\nenum { REG_RBP = 10 };\n#define REG_RBP REG_RBP\nenum { REG_RBX = 11 };\n#define REG_RBX REG_RBX\nenum { REG_RDX = 12 };\n#define REG_RDX REG_RDX\nenum { REG_RAX = 13 };\n#define REG_RAX REG_RAX\nenum { REG_RCX = 14 };\n#define REG_RCX REG_RCX\nenum { REG_RSP = 15 };\n#define REG_RSP REG_RSP\nenum { REG_RIP = 16 };\n#define REG_RIP REG_RIP\nenum { REG_EFL = 17 };\n#define REG_EFL REG_EFL\nenum { REG_CSGSFS = 18 };\n#define REG_CSGSFS REG_CSGSFS\nenum { REG_ERR = 19 };\n#define REG_ERR REG_ERR\nenum { REG_TRAPNO = 20 };\n#define REG_TRAPNO REG_TRAPNO\nenum { REG_OLDMASK = 21 };\n#define REG_OLDMASK REG_OLDMASK\nenum { REG_CR2 = 22 };\n#define REG_CR2 REG_CR2\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\ntypedef long long greg_t, gregset_t[23];\ntypedef struct _fpstate {\n\tunsigned short cwd, swd, ftw, fop;\n\tunsigned long long rip, rdp;\n\tunsigned mxcsr, mxcr_mask;\n\tstruct {\n\t\tunsigned short significand[4], exponent, padding[3];\n\t} _st[8];\n\tstruct {\n\t\tunsigned element[4];\n\t} _xmm[16];\n\tunsigned padding[24];\n} *fpregset_t;\nstruct sigcontext {\n\tunsigned long long r8, r9, r10, r11, r12, r13, r14, r15;\n\tunsigned long long rdi, rsi, rbp, rbx, rdx, rax, rcx, rsp, rip, eflags;\n\tunsigned short cs, gs, fs, __pad0;\n\tunsigned long long err, trapno, oldmask, cr2;\n\tstruct _fpstate *fpstate;\n\tunsigned long long __reserved1[8];\n};\ntypedef struct {\n\tgregset_t gregs;\n\tfpregset_t fpregs;\n\tunsigned long long __reserved1[8];\n} mcontext_t;\n#else\ntypedef struct {\n\tunsigned long long __space[32];\n} mcontext_t;\n#endif\n\nstruct sigaltstack {\n\tvoid *ss_sp;\n\tint ss_flags;\n\tsize_t ss_size;\n};\n\ntypedef struct __ucontext {\n\tunsigned long uc_flags;\n\tstruct __ucontext *uc_link;\n\tstack_t uc_stack;\n\tmcontext_t uc_mcontext;\n\tsigset_t uc_sigmask;\n\tunsigned long long __fpregs_mem[64];\n} ucontext_t;\n\n#define SA_NOCLDSTOP  1\n#define SA_NOCLDWAIT  2\n#define SA_SIGINFO    4\n#define SA_ONSTACK    0x08000000\n#define SA_RESTART    0x10000000\n#define SA_NODEFER    0x40000000\n#define SA_RESETHAND  0x80000000\n#define SA_RESTORER   0x04000000\n\n#endif\n\n#define SIGHUP    1\n#define SIGINT    2\n#define SIGQUIT   3\n#define SIGILL    4\n#define SIGTRAP   5\n#define SIGABRT   6\n#define SIGIOT    SIGABRT\n#define SIGBUS    7\n#define SIGFPE    8\n#define SIGKILL   9\n#define SIGUSR1   10\n#define SIGSEGV   11\n#define SIGUSR2   12\n#define SIGPIPE   13\n#define SIGALRM   14\n#define SIGTERM   15\n#define SIGSTKFLT 16\n#define SIGCHLD   17\n#define SIGCONT   18\n#define SIGSTOP   19\n#define SIGTSTP   20\n#define SIGTTIN   21\n#define SIGTTOU   22\n#define SIGURG    23\n#define SIGXCPU   24\n#define SIGXFSZ   25\n#define SIGVTALRM 26\n#define SIGPROF   27\n#define SIGWINCH  28\n#define SIGIO     29\n#define SIGPOLL   29\n#define SIGPWR    30\n#define SIGSYS    31\n#define SIGUNUSED SIGSYS\n\n#define _NSIG 65\n\n"
  },
  {
    "path": "user.libc/arch/x32/bits/socket.h",
    "content": "#define SO_RCVTIMEO     20\n#define SO_SNDTIMEO     21\n#define SO_TIMESTAMP    29\n#define SO_TIMESTAMPNS  35\n#define SO_TIMESTAMPING 37\n"
  },
  {
    "path": "user.libc/arch/x32/bits/stat.h",
    "content": "/* copied from kernel definition, but with padding replaced\n * by the corresponding correctly-sized userspace types. */\n\nstruct stat {\n\tdev_t st_dev;\n\tino_t st_ino;\n\tnlink_t st_nlink;\n\n\tmode_t st_mode;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tunsigned int    __pad0;\n\tdev_t st_rdev;\n\toff_t st_size;\n\tblksize_t st_blksize;\n\tblkcnt_t st_blocks;\n\n\tstruct timespec st_atim;\n\tstruct timespec st_mtim;\n\tstruct timespec st_ctim;\n\tlong long __unused[3];\n};\n"
  },
  {
    "path": "user.libc/arch/x32/bits/statfs.h",
    "content": "struct statfs {\n\tunsigned long f_type, __pad0, f_bsize, __pad1;\n\tfsblkcnt_t f_blocks, f_bfree, f_bavail;\n\tfsfilcnt_t f_files, f_ffree;\n\tfsid_t f_fsid;\n\tunsigned long f_namelen, __pad2, f_frsize, __pad3;\n\tunsigned long f_flags, __pad4;\n\tunsigned long long f_spare[4];\n};\n"
  },
  {
    "path": "user.libc/arch/x32/bits/stdint.h",
    "content": "typedef int32_t int_fast16_t;\ntypedef int32_t int_fast32_t;\ntypedef uint32_t uint_fast16_t;\ntypedef uint32_t uint_fast32_t;\n\n#define INT_FAST16_MIN  INT32_MIN\n#define INT_FAST32_MIN  INT32_MIN\n\n#define INT_FAST16_MAX  INT32_MAX\n#define INT_FAST32_MAX  INT32_MAX\n\n#define UINT_FAST16_MAX UINT32_MAX\n#define UINT_FAST32_MAX UINT32_MAX\n\n#define INTPTR_MIN      INT32_MIN\n#define INTPTR_MAX      INT32_MAX\n#define UINTPTR_MAX     UINT32_MAX\n#define PTRDIFF_MIN     INT32_MIN\n#define PTRDIFF_MAX     INT32_MAX\n#define SIZE_MAX        UINT32_MAX\n"
  },
  {
    "path": "user.libc/arch/x32/bits/syscall.h.in",
    "content": "#define __NR_read (0x40000000 + 0)\n#define __NR_write (0x40000000 + 1)\n#define __NR_open (0x40000000 + 2)\n#define __NR_close (0x40000000 + 3)\n#define __NR_stat (0x40000000 + 4)\n#define __NR_fstat (0x40000000 + 5)\n#define __NR_lstat (0x40000000 + 6)\n#define __NR_poll (0x40000000 + 7)\n#define __NR_lseek (0x40000000 + 8)\n#define __NR_mmap (0x40000000 + 9)\n#define __NR_mprotect (0x40000000 + 10)\n#define __NR_munmap (0x40000000 + 11)\n#define __NR_brk (0x40000000 + 12)\n#define __NR_rt_sigprocmask (0x40000000 + 14)\n#define __NR_pread64 (0x40000000 + 17)\n#define __NR_pwrite64 (0x40000000 + 18)\n#define __NR_access (0x40000000 + 21)\n#define __NR_pipe (0x40000000 + 22)\n#define __NR_select (0x40000000 + 23)\n#define __NR_sched_yield (0x40000000 + 24)\n#define __NR_mremap (0x40000000 + 25)\n#define __NR_msync (0x40000000 + 26)\n#define __NR_mincore (0x40000000 + 27)\n#define __NR_madvise (0x40000000 + 28)\n#define __NR_shmget (0x40000000 + 29)\n#define __NR_shmat (0x40000000 + 30)\n#define __NR_shmctl (0x40000000 + 31)\n#define __NR_dup (0x40000000 + 32)\n#define __NR_dup2 (0x40000000 + 33)\n#define __NR_pause (0x40000000 + 34)\n#define __NR_nanosleep (0x40000000 + 35)\n#define __NR_getitimer (0x40000000 + 36)\n#define __NR_alarm (0x40000000 + 37)\n#define __NR_setitimer (0x40000000 + 38)\n#define __NR_getpid (0x40000000 + 39)\n#define __NR_sendfile (0x40000000 + 40)\n#define __NR_socket (0x40000000 + 41)\n#define __NR_connect (0x40000000 + 42)\n#define __NR_accept (0x40000000 + 43)\n#define __NR_sendto (0x40000000 + 44)\n#define __NR_shutdown (0x40000000 + 48)\n#define __NR_bind (0x40000000 + 49)\n#define __NR_listen (0x40000000 + 50)\n#define __NR_getsockname (0x40000000 + 51)\n#define __NR_getpeername (0x40000000 + 52)\n#define __NR_socketpair (0x40000000 + 53)\n#define __NR_clone (0x40000000 + 56)\n#define __NR_fork (0x40000000 + 57)\n#define __NR_vfork (0x40000000 + 58)\n#define __NR_exit (0x40000000 + 60)\n#define __NR_wait4 (0x40000000 + 61)\n#define __NR_kill (0x40000000 + 62)\n#define __NR_uname (0x40000000 + 63)\n#define __NR_semget (0x40000000 + 64)\n#define __NR_semop (0x40000000 + 65)\n#define __NR_semctl (0x40000000 + 66)\n#define __NR_shmdt (0x40000000 + 67)\n#define __NR_msgget (0x40000000 + 68)\n#define __NR_msgsnd (0x40000000 + 69)\n#define __NR_msgrcv (0x40000000 + 70)\n#define __NR_msgctl (0x40000000 + 71)\n#define __NR_fcntl (0x40000000 + 72)\n#define __NR_flock (0x40000000 + 73)\n#define __NR_fsync (0x40000000 + 74)\n#define __NR_fdatasync (0x40000000 + 75)\n#define __NR_truncate (0x40000000 + 76)\n#define __NR_ftruncate (0x40000000 + 77)\n#define __NR_getdents (0x40000000 + 78)\n#define __NR_getcwd (0x40000000 + 79)\n#define __NR_chdir (0x40000000 + 80)\n#define __NR_fchdir (0x40000000 + 81)\n#define __NR_rename (0x40000000 + 82)\n#define __NR_mkdir (0x40000000 + 83)\n#define __NR_rmdir (0x40000000 + 84)\n#define __NR_creat (0x40000000 + 85)\n#define __NR_link (0x40000000 + 86)\n#define __NR_unlink (0x40000000 + 87)\n#define __NR_symlink (0x40000000 + 88)\n#define __NR_readlink (0x40000000 + 89)\n#define __NR_chmod (0x40000000 + 90)\n#define __NR_fchmod (0x40000000 + 91)\n#define __NR_chown (0x40000000 + 92)\n#define __NR_fchown (0x40000000 + 93)\n#define __NR_lchown (0x40000000 + 94)\n#define __NR_umask (0x40000000 + 95)\n#define __NR_gettimeofday (0x40000000 + 96)\n#define __NR_getrlimit (0x40000000 + 97)\n#define __NR_getrusage (0x40000000 + 98)\n#define __NR_sysinfo (0x40000000 + 99)\n#define __NR_times (0x40000000 + 100)\n#define __NR_getuid (0x40000000 + 102)\n#define __NR_syslog (0x40000000 + 103)\n#define __NR_getgid (0x40000000 + 104)\n#define __NR_setuid (0x40000000 + 105)\n#define __NR_setgid (0x40000000 + 106)\n#define __NR_geteuid (0x40000000 + 107)\n#define __NR_getegid (0x40000000 + 108)\n#define __NR_setpgid (0x40000000 + 109)\n#define __NR_getppid (0x40000000 + 110)\n#define __NR_getpgrp (0x40000000 + 111)\n#define __NR_setsid (0x40000000 + 112)\n#define __NR_setreuid (0x40000000 + 113)\n#define __NR_setregid (0x40000000 + 114)\n#define __NR_getgroups (0x40000000 + 115)\n#define __NR_setgroups (0x40000000 + 116)\n#define __NR_setresuid (0x40000000 + 117)\n#define __NR_getresuid (0x40000000 + 118)\n#define __NR_setresgid (0x40000000 + 119)\n#define __NR_getresgid (0x40000000 + 120)\n#define __NR_getpgid (0x40000000 + 121)\n#define __NR_setfsuid (0x40000000 + 122)\n#define __NR_setfsgid (0x40000000 + 123)\n#define __NR_getsid (0x40000000 + 124)\n#define __NR_capget (0x40000000 + 125)\n#define __NR_capset (0x40000000 + 126)\n#define __NR_rt_sigsuspend (0x40000000 + 130)\n#define __NR_utime (0x40000000 + 132)\n#define __NR_mknod (0x40000000 + 133)\n#define __NR_personality (0x40000000 + 135)\n#define __NR_ustat (0x40000000 + 136)\n#define __NR_statfs (0x40000000 + 137)\n#define __NR_fstatfs (0x40000000 + 138)\n#define __NR_sysfs (0x40000000 + 139)\n#define __NR_getpriority (0x40000000 + 140)\n#define __NR_setpriority (0x40000000 + 141)\n#define __NR_sched_setparam (0x40000000 + 142)\n#define __NR_sched_getparam (0x40000000 + 143)\n#define __NR_sched_setscheduler (0x40000000 + 144)\n#define __NR_sched_getscheduler (0x40000000 + 145)\n#define __NR_sched_get_priority_max (0x40000000 + 146)\n#define __NR_sched_get_priority_min (0x40000000 + 147)\n#define __NR_sched_rr_get_interval (0x40000000 + 148)\n#define __NR_mlock (0x40000000 + 149)\n#define __NR_munlock (0x40000000 + 150)\n#define __NR_mlockall (0x40000000 + 151)\n#define __NR_munlockall (0x40000000 + 152)\n#define __NR_vhangup (0x40000000 + 153)\n#define __NR_modify_ldt (0x40000000 + 154)\n#define __NR_pivot_root (0x40000000 + 155)\n#define __NR_prctl (0x40000000 + 157)\n#define __NR_arch_prctl (0x40000000 + 158)\n#define __NR_adjtimex (0x40000000 + 159)\n#define __NR_setrlimit (0x40000000 + 160)\n#define __NR_chroot (0x40000000 + 161)\n#define __NR_sync (0x40000000 + 162)\n#define __NR_acct (0x40000000 + 163)\n#define __NR_settimeofday (0x40000000 + 164)\n#define __NR_mount (0x40000000 + 165)\n#define __NR_umount2 (0x40000000 + 166)\n#define __NR_swapon (0x40000000 + 167)\n#define __NR_swapoff (0x40000000 + 168)\n#define __NR_reboot (0x40000000 + 169)\n#define __NR_sethostname (0x40000000 + 170)\n#define __NR_setdomainname (0x40000000 + 171)\n#define __NR_iopl (0x40000000 + 172)\n#define __NR_ioperm (0x40000000 + 173)\n#define __NR_init_module (0x40000000 + 175)\n#define __NR_delete_module (0x40000000 + 176)\n#define __NR_quotactl (0x40000000 + 179)\n#define __NR_getpmsg (0x40000000 + 181)\n#define __NR_putpmsg (0x40000000 + 182)\n#define __NR_afs_syscall (0x40000000 + 183)\n#define __NR_tuxcall (0x40000000 + 184)\n#define __NR_security (0x40000000 + 185)\n#define __NR_gettid (0x40000000 + 186)\n#define __NR_readahead (0x40000000 + 187)\n#define __NR_setxattr (0x40000000 + 188)\n#define __NR_lsetxattr (0x40000000 + 189)\n#define __NR_fsetxattr (0x40000000 + 190)\n#define __NR_getxattr (0x40000000 + 191)\n#define __NR_lgetxattr (0x40000000 + 192)\n#define __NR_fgetxattr (0x40000000 + 193)\n#define __NR_listxattr (0x40000000 + 194)\n#define __NR_llistxattr (0x40000000 + 195)\n#define __NR_flistxattr (0x40000000 + 196)\n#define __NR_removexattr (0x40000000 + 197)\n#define __NR_lremovexattr (0x40000000 + 198)\n#define __NR_fremovexattr (0x40000000 + 199)\n#define __NR_tkill (0x40000000 + 200)\n#define __NR_time (0x40000000 + 201)\n#define __NR_futex (0x40000000 + 202)\n#define __NR_sched_setaffinity (0x40000000 + 203)\n#define __NR_sched_getaffinity (0x40000000 + 204)\n#define __NR_io_destroy (0x40000000 + 207)\n#define __NR_io_getevents (0x40000000 + 208)\n#define __NR_io_cancel (0x40000000 + 210)\n#define __NR_lookup_dcookie (0x40000000 + 212)\n#define __NR_epoll_create (0x40000000 + 213)\n#define __NR_remap_file_pages (0x40000000 + 216)\n#define __NR_getdents64 (0x40000000 + 217)\n#define __NR_set_tid_address (0x40000000 + 218)\n#define __NR_restart_syscall (0x40000000 + 219)\n#define __NR_semtimedop (0x40000000 + 220)\n#define __NR_fadvise64 (0x40000000 + 221)\n#define __NR_timer_settime (0x40000000 + 223)\n#define __NR_timer_gettime (0x40000000 + 224)\n#define __NR_timer_getoverrun (0x40000000 + 225)\n#define __NR_timer_delete (0x40000000 + 226)\n#define __NR_clock_settime (0x40000000 + 227)\n#define __NR_clock_gettime (0x40000000 + 228)\n#define __NR_clock_getres (0x40000000 + 229)\n#define __NR_clock_nanosleep (0x40000000 + 230)\n#define __NR_exit_group (0x40000000 + 231)\n#define __NR_epoll_wait (0x40000000 + 232)\n#define __NR_epoll_ctl (0x40000000 + 233)\n#define __NR_tgkill (0x40000000 + 234)\n#define __NR_utimes (0x40000000 + 235)\n#define __NR_mbind (0x40000000 + 237)\n#define __NR_set_mempolicy (0x40000000 + 238)\n#define __NR_get_mempolicy (0x40000000 + 239)\n#define __NR_mq_open (0x40000000 + 240)\n#define __NR_mq_unlink (0x40000000 + 241)\n#define __NR_mq_timedsend (0x40000000 + 242)\n#define __NR_mq_timedreceive (0x40000000 + 243)\n#define __NR_mq_getsetattr (0x40000000 + 245)\n#define __NR_add_key (0x40000000 + 248)\n#define __NR_request_key (0x40000000 + 249)\n#define __NR_keyctl (0x40000000 + 250)\n#define __NR_ioprio_set (0x40000000 + 251)\n#define __NR_ioprio_get (0x40000000 + 252)\n#define __NR_inotify_init (0x40000000 + 253)\n#define __NR_inotify_add_watch (0x40000000 + 254)\n#define __NR_inotify_rm_watch (0x40000000 + 255)\n#define __NR_migrate_pages (0x40000000 + 256)\n#define __NR_openat (0x40000000 + 257)\n#define __NR_mkdirat (0x40000000 + 258)\n#define __NR_mknodat (0x40000000 + 259)\n#define __NR_fchownat (0x40000000 + 260)\n#define __NR_futimesat (0x40000000 + 261)\n#define __NR_newfstatat (0x40000000 + 262)\n#define __NR_unlinkat (0x40000000 + 263)\n#define __NR_renameat (0x40000000 + 264)\n#define __NR_linkat (0x40000000 + 265)\n#define __NR_symlinkat (0x40000000 + 266)\n#define __NR_readlinkat (0x40000000 + 267)\n#define __NR_fchmodat (0x40000000 + 268)\n#define __NR_faccessat (0x40000000 + 269)\n#define __NR_pselect6 (0x40000000 + 270)\n#define __NR_ppoll (0x40000000 + 271)\n#define __NR_unshare (0x40000000 + 272)\n#define __NR_splice (0x40000000 + 275)\n#define __NR_tee (0x40000000 + 276)\n#define __NR_sync_file_range (0x40000000 + 277)\n#define __NR_utimensat (0x40000000 + 280)\n#define __NR_epoll_pwait (0x40000000 + 281)\n#define __NR_signalfd (0x40000000 + 282)\n#define __NR_timerfd_create (0x40000000 + 283)\n#define __NR_eventfd (0x40000000 + 284)\n#define __NR_fallocate (0x40000000 + 285)\n#define __NR_timerfd_settime (0x40000000 + 286)\n#define __NR_timerfd_gettime (0x40000000 + 287)\n#define __NR_accept4 (0x40000000 + 288)\n#define __NR_signalfd4 (0x40000000 + 289)\n#define __NR_eventfd2 (0x40000000 + 290)\n#define __NR_epoll_create1 (0x40000000 + 291)\n#define __NR_dup3 (0x40000000 + 292)\n#define __NR_pipe2 (0x40000000 + 293)\n#define __NR_inotify_init1 (0x40000000 + 294)\n#define __NR_perf_event_open (0x40000000 + 298)\n#define __NR_fanotify_init (0x40000000 + 300)\n#define __NR_fanotify_mark (0x40000000 + 301)\n#define __NR_prlimit64 (0x40000000 + 302)\n#define __NR_name_to_handle_at (0x40000000 + 303)\n#define __NR_open_by_handle_at (0x40000000 + 304)\n#define __NR_clock_adjtime (0x40000000 + 305)\n#define __NR_syncfs (0x40000000 + 306)\n#define __NR_setns (0x40000000 + 308)\n#define __NR_getcpu (0x40000000 + 309)\n#define __NR_kcmp (0x40000000 + 312)\n#define __NR_finit_module (0x40000000 + 313)\n#define __NR_sched_setattr (0x40000000 + 314)\n#define __NR_sched_getattr (0x40000000 + 315)\n#define __NR_renameat2 (0x40000000 + 316)\n#define __NR_seccomp (0x40000000 + 317)\n#define __NR_getrandom (0x40000000 + 318)\n#define __NR_memfd_create (0x40000000 + 319)\n#define __NR_kexec_file_load (0x40000000 + 320)\n#define __NR_bpf (0x40000000 + 321)\n#define __NR_userfaultfd (0x40000000 + 323)\n#define __NR_membarrier (0x40000000 + 324)\n#define __NR_mlock2 (0x40000000 + 325)\n#define __NR_copy_file_range (0x40000000 + 326)\n#define __NR_pkey_mprotect (0x40000000 + 329)\n#define __NR_pkey_alloc (0x40000000 + 330)\n#define __NR_pkey_free (0x40000000 + 331)\n#define __NR_statx (0x40000000 + 332)\n#define __NR_io_pgetevents (0x40000000 + 333)\n#define __NR_rseq (0x40000000 + 334)\n#define __NR_pidfd_send_signal (0x40000000 + 424)\n#define __NR_io_uring_setup (0x40000000 + 425)\n#define __NR_io_uring_enter (0x40000000 + 426)\n#define __NR_io_uring_register (0x40000000 + 427)\n#define __NR_open_tree\t\t(0x40000000 + 428)\n#define __NR_move_mount\t\t(0x40000000 + 429)\n#define __NR_fsopen\t\t(0x40000000 + 430)\n#define __NR_fsconfig\t\t(0x40000000 + 431)\n#define __NR_fsmount\t\t(0x40000000 + 432)\n#define __NR_fspick\t\t(0x40000000 + 433)\n#define __NR_pidfd_open\t\t(0x40000000 + 434)\n#define __NR_clone3\t\t(0x40000000 + 435)\n#define __NR_close_range\t(0x40000000 + 436)\n#define __NR_openat2\t\t(0x40000000 + 437)\n#define __NR_pidfd_getfd\t(0x40000000 + 438)\n#define __NR_faccessat2\t\t(0x40000000 + 439)\n\n\n#define __NR_rt_sigaction (0x40000000 + 512)\n#define __NR_rt_sigreturn (0x40000000 + 513)\n#define __NR_ioctl (0x40000000 + 514)\n#define __NR_readv (0x40000000 + 515)\n#define __NR_writev (0x40000000 + 516)\n#define __NR_recvfrom (0x40000000 + 517)\n#define __NR_sendmsg (0x40000000 + 518)\n#define __NR_recvmsg (0x40000000 + 519)\n#define __NR_execve (0x40000000 + 520)\n#define __NR_ptrace (0x40000000 + 521)\n#define __NR_rt_sigpending (0x40000000 + 522)\n#define __NR_rt_sigtimedwait (0x40000000 + 523)\n#define __NR_rt_sigqueueinfo (0x40000000 + 524)\n#define __NR_sigaltstack (0x40000000 + 525)\n#define __NR_timer_create (0x40000000 + 526)\n#define __NR_mq_notify (0x40000000 + 527)\n#define __NR_kexec_load (0x40000000 + 528)\n#define __NR_waitid (0x40000000 + 529)\n#define __NR_set_robust_list (0x40000000 + 530)\n#define __NR_get_robust_list (0x40000000 + 531)\n#define __NR_vmsplice (0x40000000 + 532)\n#define __NR_move_pages (0x40000000 + 533)\n#define __NR_preadv (0x40000000 + 534)\n#define __NR_pwritev (0x40000000 + 535)\n#define __NR_rt_tgsigqueueinfo (0x40000000 + 536)\n#define __NR_recvmmsg (0x40000000 + 537)\n#define __NR_sendmmsg (0x40000000 + 538)\n#define __NR_process_vm_readv (0x40000000 + 539)\n#define __NR_process_vm_writev (0x40000000 + 540)\n#define __NR_setsockopt (0x40000000 + 541)\n#define __NR_getsockopt (0x40000000 + 542)\n#define __NR_io_setup (0x40000000 + 543)\n#define __NR_io_submit (0x40000000 + 544)\n#define __NR_execveat (0x40000000 + 545)\n#define __NR_preadv2 (0x40000000 + 546)\n#define __NR_pwritev2 (0x40000000 + 547)\n\n"
  },
  {
    "path": "user.libc/arch/x32/bits/user.h",
    "content": "#undef __WORDSIZE\n#define __WORDSIZE 64\n\ntypedef struct user_fpregs_struct {\n\tuint16_t cwd, swd, ftw, fop;\n\tuint64_t rip, rdp;\n\tuint32_t mxcsr, mxcr_mask;\n\tuint32_t st_space[32], xmm_space[64], padding[24];\n} elf_fpregset_t;\n\nstruct user_regs_struct {\n\tunsigned long r15, r14, r13, r12, rbp, rbx, r11, r10, r9, r8;\n\tunsigned long rax, rcx, rdx, rsi, rdi, orig_rax, rip;\n\tunsigned long cs, eflags, rsp, ss, fs_base, gs_base, ds, es, fs, gs;\n};\n#define ELF_NGREG 27\ntypedef unsigned long long elf_greg_t, elf_gregset_t[ELF_NGREG];\n\nstruct user {\n\tstruct user_regs_struct\t\tregs;\n\tint\t\t\t\tu_fpvalid;\n\tstruct user_fpregs_struct\ti387;\n\tunsigned long\t\t\tu_tsize;\n\tunsigned long\t\t\tu_dsize;\n\tunsigned long\t\t\tu_ssize;\n\tunsigned long\t\t\tstart_code;\n\tunsigned long\t\t\tstart_stack;\n\tlong\t\t\t\tsignal;\n\tint\t\t\t\treserved;\n\tstruct user_regs_struct\t\t*u_ar0;\n\tstruct user_fpregs_struct\t*u_fpstate;\n\tunsigned long\t\t\tmagic;\n\tchar\t\t\t\tu_comm[32];\n\tunsigned long\t\t\tu_debugreg[8];\n};\n\n#define PAGE_MASK\t\t(~(PAGESIZE-1))\n#define NBPG\t\t\tPAGESIZE\n#define UPAGES\t\t\t1\n#define HOST_TEXT_START_ADDR\t(u.start_code)\n#define HOST_STACK_END_ADDR\t(u.start_stack + u.u_ssize * NBPG)\n"
  },
  {
    "path": "user.libc/arch/x32/crt_arch.h",
    "content": "__asm__(\n\".text \\n\"\n\".global \" START \" \\n\"\nSTART \": \\n\"\n\"\txor %rbp,%rbp \\n\"\n\"\tmov %rsp,%rdi \\n\"\n\".weak _DYNAMIC \\n\"\n\".hidden _DYNAMIC \\n\"\n\"\tlea _DYNAMIC(%rip),%rsi \\n\"\n\"\tandq $-16,%rsp \\n\"\n\"\tcall \" START \"_c \\n\"\n);\n"
  },
  {
    "path": "user.libc/arch/x32/ksigaction.h",
    "content": "#include <features.h>\n\nstruct k_sigaction {\n\tvoid (*handler)(int);\n\tunsigned long flags;\n\tvoid (*restorer)(void);\n\tunsigned mask[2];\n};\n\nhidden void __restore_rt();\n#define __restore __restore_rt\n"
  },
  {
    "path": "user.libc/arch/x32/kstat.h",
    "content": "struct kstat {\n\tdev_t st_dev;\n\tino_t st_ino;\n\tnlink_t st_nlink;\n\n\tmode_t st_mode;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tunsigned int    __pad0;\n\tdev_t st_rdev;\n\toff_t st_size;\n\tblksize_t st_blksize;\n\tblkcnt_t st_blocks;\n\n\tlong long st_atime_sec;\n\tlong st_atime_nsec;\n\tlong long st_mtime_sec;\n\tlong st_mtime_nsec;\n\tlong long st_ctime_sec;\n\tlong st_ctime_nsec;\n\tlong long __unused[3];\n};\n"
  },
  {
    "path": "user.libc/arch/x32/pthread_arch.h",
    "content": "static inline uintptr_t __get_tp()\n{\n\tuintptr_t tp;\n\t__asm__ (\"mov %%fs:0,%0\" : \"=r\" (tp) );\n\treturn tp;\n}\n\n#define MC_PC gregs[REG_RIP]\n\n#define CANARY_PAD\n\n#define tls_mod_off_t unsigned long long\n"
  },
  {
    "path": "user.libc/arch/x32/reloc.h",
    "content": "#define LDSO_ARCH \"x32\"\n\n/* FIXME: x32 is very strange in its use of 64-bit relocation types in\n * a 32-bit environment. As long as the memory at reloc_addr is\n * zero-filled prior to relocations, just treating 64-bit relocations\n * as operating on 32-bit slots should be fine, but this should be\n * checked. In particular, R_X86_64_64, R_X86_64_DTPOFF64, and\n * R_X86_64_TPOFF64 may need checking. */\n\n/* The R_X86_64_64, R_X86_64_DTPOFF32, and R_X86_64_TPOFF32 reloc types\n * were previously mapped in the switch table form of this file; however,\n * they do not seem to be used/usable for anything. If needed, new\n * mappings will have to be added. */\n\n#define REL_SYMBOLIC    R_X86_64_32\n#define REL_OFFSET      R_X86_64_PC32\n#define REL_GOT         R_X86_64_GLOB_DAT\n#define REL_PLT         R_X86_64_JUMP_SLOT\n#define REL_RELATIVE    R_X86_64_RELATIVE\n#define REL_COPY        R_X86_64_COPY\n#define REL_DTPMOD      R_X86_64_DTPMOD64\n#define REL_DTPOFF      R_X86_64_DTPOFF64\n#define REL_TPOFF       R_X86_64_TPOFF64\n\n#define CRTJMP(pc,sp) __asm__ __volatile__( \\\n\t\"mov %1,%%esp ; jmp *%0\" : : \"r\"((uint64_t)(uintptr_t)pc), \"r\"(sp) : \"memory\" )\n\n#define GETFUNCSYM(fp, sym, got) __asm__ ( \\\n\t\".hidden \" #sym \"\\n\" \\\n\t\"\tlea \" #sym \"(%%rip),%0\\n\" \\\n\t: \"=r\"(*fp) : : \"memory\" )\n"
  },
  {
    "path": "user.libc/arch/x32/syscall_arch.h",
    "content": "#define __SYSCALL_LL_E(x) (x)\n#define __SYSCALL_LL_O(x) (x)\n\n#define __scc(X) sizeof(1?(X):0ULL) < 8 ? (unsigned long) (X) : (long long) (X)\ntypedef long long syscall_arg_t;\n\nstatic __inline long __syscall0(long long n)\n{\n\tunsigned long ret;\n\t__asm__ __volatile__ (\"syscall\" : \"=a\"(ret) : \"a\"(n) : \"rcx\", \"r11\", \"memory\");\n\treturn ret;\n}\n\nstatic __inline long __syscall1(long long n, long long a1)\n{\n\tunsigned long ret;\n\t__asm__ __volatile__ (\"syscall\" : \"=a\"(ret) : \"a\"(n), \"D\"(a1) : \"rcx\", \"r11\", \"memory\");\n\treturn ret;\n}\n\nstatic __inline long __syscall2(long long n, long long a1, long long a2)\n{\n\tunsigned long ret;\n\t__asm__ __volatile__ (\"syscall\" : \"=a\"(ret) : \"a\"(n), \"D\"(a1), \"S\"(a2)\n\t\t\t\t\t: \"rcx\", \"r11\", \"memory\");\n\treturn ret;\n}\n\nstatic __inline long __syscall3(long long n, long long a1, long long a2, long long a3)\n{\n\tunsigned long ret;\n\t__asm__ __volatile__ (\"syscall\" : \"=a\"(ret) : \"a\"(n), \"D\"(a1), \"S\"(a2),\n\t\t\t\t\t\t  \"d\"(a3) : \"rcx\", \"r11\", \"memory\");\n\treturn ret;\n}\n\nstatic __inline long __syscall4(long long n, long long a1, long long a2, long long a3,\n                                     long long a4_)\n{\n\tunsigned long ret;\n\tregister long long a4 __asm__(\"r10\") = a4_;\n\t__asm__ __volatile__ (\"syscall\" : \"=a\"(ret) : \"a\"(n), \"D\"(a1), \"S\"(a2),\n\t\t\t\t\t  \"d\"(a3), \"r\"(a4): \"rcx\", \"r11\", \"memory\");\n\treturn ret;\n}\n\nstatic __inline long __syscall5(long long n, long long a1, long long a2, long long a3,\n                                     long long a4_, long long a5_)\n{\n\tunsigned long ret;\n\tregister long long a4 __asm__(\"r10\") = a4_;\n\tregister long long a5 __asm__(\"r8\") = a5_;\n\t__asm__ __volatile__ (\"syscall\" : \"=a\"(ret) : \"a\"(n), \"D\"(a1), \"S\"(a2),\n\t\t\t\t\t  \"d\"(a3), \"r\"(a4), \"r\"(a5) : \"rcx\", \"r11\", \"memory\");\n\treturn ret;\n}\n\nstatic __inline long __syscall6(long long n, long long a1, long long a2, long long a3,\n                                     long long a4_, long long a5_, long long a6_)\n{\n\tunsigned long ret;\n\tregister long long a4 __asm__(\"r10\") = a4_;\n\tregister long long a5 __asm__(\"r8\") = a5_;\n\tregister long long a6 __asm__(\"r9\") = a6_;\n\t__asm__ __volatile__ (\"syscall\" : \"=a\"(ret) : \"a\"(n), \"D\"(a1), \"S\"(a2),\n\t\t\t\t\t  \"d\"(a3), \"r\"(a4), \"r\"(a5), \"r\"(a6) : \"rcx\", \"r11\", \"memory\");\n\treturn ret;\n}\n\n#undef SYS_futimesat\n\n#define SYS_clock_gettime64 SYS_clock_gettime\n#define SYS_clock_settime64 SYS_clock_settime\n#define SYS_clock_adjtime64 SYS_clock_adjtime\n#define SYS_clock_nanosleep_time64 SYS_clock_nanosleep\n#define SYS_timer_gettime64 SYS_timer_gettime\n#define SYS_timer_settime64 SYS_timer_settime\n#define SYS_timerfd_gettime64 SYS_timerfd_gettime\n#define SYS_timerfd_settime64 SYS_timerfd_settime\n#define SYS_utimensat_time64 SYS_utimensat\n#define SYS_pselect6_time64 SYS_pselect6\n#define SYS_ppoll_time64 SYS_ppoll\n#define SYS_recvmmsg_time64 SYS_recvmmsg\n#define SYS_mq_timedsend_time64 SYS_mq_timedsend\n#define SYS_mq_timedreceive_time64 SYS_mq_timedreceive\n#define SYS_semtimedop_time64 SYS_semtimedop\n#define SYS_rt_sigtimedwait_time64 SYS_rt_sigtimedwait\n#define SYS_futex_time64 SYS_futex\n#define SYS_sched_rr_get_interval_time64 SYS_sched_rr_get_interval\n#define SYS_getrusage_time64 SYS_getrusage\n#define SYS_wait4_time64 SYS_wait4\n\n#define IPC_64 0\n"
  },
  {
    "path": "user.libc/arch/x86_64/atomic_arch.h",
    "content": "#define a_cas a_cas\nstatic inline int a_cas(volatile int *p, int t, int s)\n{\n\t__asm__ __volatile__ (\n\t\t\"lock ; cmpxchg %3, %1\"\n\t\t: \"=a\"(t), \"=m\"(*p) : \"a\"(t), \"r\"(s) : \"memory\" );\n\treturn t;\n}\n\n#define a_cas_p a_cas_p\nstatic inline void *a_cas_p(volatile void *p, void *t, void *s)\n{\n\t__asm__( \"lock ; cmpxchg %3, %1\"\n\t\t: \"=a\"(t), \"=m\"(*(void *volatile *)p)\n\t\t: \"a\"(t), \"r\"(s) : \"memory\" );\n\treturn t;\n}\n\n#define a_swap a_swap\nstatic inline int a_swap(volatile int *p, int v)\n{\n\t__asm__ __volatile__(\n\t\t\"xchg %0, %1\"\n\t\t: \"=r\"(v), \"=m\"(*p) : \"0\"(v) : \"memory\" );\n\treturn v;\n}\n\n#define a_fetch_add a_fetch_add\nstatic inline int a_fetch_add(volatile int *p, int v)\n{\n\t__asm__ __volatile__(\n\t\t\"lock ; xadd %0, %1\"\n\t\t: \"=r\"(v), \"=m\"(*p) : \"0\"(v) : \"memory\" );\n\treturn v;\n}\n\n#define a_and a_and\nstatic inline void a_and(volatile int *p, int v)\n{\n\t__asm__ __volatile__(\n\t\t\"lock ; and %1, %0\"\n\t\t: \"=m\"(*p) : \"r\"(v) : \"memory\" );\n}\n\n#define a_or a_or\nstatic inline void a_or(volatile int *p, int v)\n{\n\t__asm__ __volatile__(\n\t\t\"lock ; or %1, %0\"\n\t\t: \"=m\"(*p) : \"r\"(v) : \"memory\" );\n}\n\n#define a_and_64 a_and_64\nstatic inline void a_and_64(volatile uint64_t *p, uint64_t v)\n{\n\t__asm__ __volatile(\n\t\t\"lock ; and %1, %0\"\n\t\t : \"=m\"(*p) : \"r\"(v) : \"memory\" );\n}\n\n#define a_or_64 a_or_64\nstatic inline void a_or_64(volatile uint64_t *p, uint64_t v)\n{\n\t__asm__ __volatile__(\n\t\t\"lock ; or %1, %0\"\n\t\t : \"=m\"(*p) : \"r\"(v) : \"memory\" );\n}\n\n#define a_inc a_inc\nstatic inline void a_inc(volatile int *p)\n{\n\t__asm__ __volatile__(\n\t\t\"lock ; incl %0\"\n\t\t: \"=m\"(*p) : \"m\"(*p) : \"memory\" );\n}\n\n#define a_dec a_dec\nstatic inline void a_dec(volatile int *p)\n{\n\t__asm__ __volatile__(\n\t\t\"lock ; decl %0\"\n\t\t: \"=m\"(*p) : \"m\"(*p) : \"memory\" );\n}\n\n#define a_store a_store\nstatic inline void a_store(volatile int *p, int x)\n{\n\t__asm__ __volatile__(\n\t\t\"mov %1, %0 ; lock ; orl $0,(%%rsp)\"\n\t\t: \"=m\"(*p) : \"r\"(x) : \"memory\" );\n}\n\n#define a_barrier a_barrier\nstatic inline void a_barrier()\n{\n\t__asm__ __volatile__( \"\" : : : \"memory\" );\n}\n\n#define a_spin a_spin\nstatic inline void a_spin()\n{\n\t__asm__ __volatile__( \"pause\" : : : \"memory\" );\n}\n\n#define a_crash a_crash\nstatic inline void a_crash()\n{\n\t__asm__ __volatile__( \"hlt\" : : : \"memory\" );\n}\n\n#define a_ctz_64 a_ctz_64\nstatic inline int a_ctz_64(uint64_t x)\n{\n\t__asm__( \"bsf %1,%0\" : \"=r\"(x) : \"r\"(x) );\n\treturn x;\n}\n\n#define a_clz_64 a_clz_64\nstatic inline int a_clz_64(uint64_t x)\n{\n\t__asm__( \"bsr %1,%0 ; xor $63,%0\" : \"=r\"(x) : \"r\"(x) );\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/arch/x86_64/bits/alltypes.h.in",
    "content": "#define _Addr long\n#define _Int64 long\n#define _Reg long\n\n#define __BYTE_ORDER 1234\n#define __LONG_MAX 0x7fffffffffffffffL\n\n#ifndef __cplusplus\nTYPEDEF int wchar_t;\n#endif\n\n#if defined(__FLT_EVAL_METHOD__) && __FLT_EVAL_METHOD__ == 2\nTYPEDEF long double float_t;\nTYPEDEF long double double_t;\n#else\nTYPEDEF float float_t;\nTYPEDEF double double_t;\n#endif\n\nTYPEDEF struct { long long __ll; long double __ld; } max_align_t;\n"
  },
  {
    "path": "user.libc/arch/x86_64/bits/fenv.h",
    "content": "#define FE_INVALID    1\n#define __FE_DENORM   2\n#define FE_DIVBYZERO  4\n#define FE_OVERFLOW   8\n#define FE_UNDERFLOW  16\n#define FE_INEXACT    32\n\n#define FE_ALL_EXCEPT 63\n\n#define FE_TONEAREST  0\n#define FE_DOWNWARD   0x400\n#define FE_UPWARD     0x800\n#define FE_TOWARDZERO 0xc00\n\ntypedef unsigned short fexcept_t;\n\ntypedef struct {\n\tunsigned short __control_word;\n\tunsigned short __unused1;\n\tunsigned short __status_word;\n\tunsigned short __unused2;\n\tunsigned short __tags;\n\tunsigned short __unused3;\n\tunsigned int __eip;\n\tunsigned short __cs_selector;\n\tunsigned int __opcode:11;\n\tunsigned int __unused4:5;\n\tunsigned int __data_offset;\n\tunsigned short __data_selector;\n\tunsigned short __unused5;\n\tunsigned int __mxcsr;\n} fenv_t;\n\n#define FE_DFL_ENV      ((const fenv_t *) -1)\n"
  },
  {
    "path": "user.libc/arch/x86_64/bits/float.h",
    "content": "#ifdef __FLT_EVAL_METHOD__\n#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__\n#else\n#define FLT_EVAL_METHOD 0\n#endif\n\n#define LDBL_TRUE_MIN 3.6451995318824746025e-4951L\n#define LDBL_MIN     3.3621031431120935063e-4932L\n#define LDBL_MAX     1.1897314953572317650e+4932L\n#define LDBL_EPSILON 1.0842021724855044340e-19L\n\n#define LDBL_MANT_DIG 64\n#define LDBL_MIN_EXP (-16381)\n#define LDBL_MAX_EXP 16384\n\n#define LDBL_DIG 18\n#define LDBL_MIN_10_EXP (-4931)\n#define LDBL_MAX_10_EXP 4932\n\n#define DECIMAL_DIG 21\n"
  },
  {
    "path": "user.libc/arch/x86_64/bits/io.h",
    "content": "static __inline void outb(unsigned char __val, unsigned short __port)\n{\n\t__asm__ volatile (\"outb %0,%1\" : : \"a\" (__val), \"dN\" (__port));\n}\n\nstatic __inline void outw(unsigned short __val, unsigned short __port)\n{\n\t__asm__ volatile (\"outw %0,%1\" : : \"a\" (__val), \"dN\" (__port));\n}\n\nstatic __inline void outl(unsigned int __val, unsigned short __port)\n{\n\t__asm__ volatile (\"outl %0,%1\" : : \"a\" (__val), \"dN\" (__port));\n}\n\nstatic __inline unsigned char inb(unsigned short __port)\n{\n\tunsigned char __val;\n\t__asm__ volatile (\"inb %1,%0\" : \"=a\" (__val) : \"dN\" (__port));\n\treturn __val;\n}\n\nstatic __inline unsigned short inw(unsigned short __port)\n{\n\tunsigned short __val;\n\t__asm__ volatile (\"inw %1,%0\" : \"=a\" (__val) : \"dN\" (__port));\n\treturn __val;\n}\n\nstatic __inline unsigned int inl(unsigned short __port)\n{\n\tunsigned int __val;\n\t__asm__ volatile (\"inl %1,%0\" : \"=a\" (__val) : \"dN\" (__port));\n\treturn __val;\n}\n\nstatic __inline void outsb(unsigned short __port, const void *__buf, unsigned long __n)\n{\n\t__asm__ volatile (\"cld; rep; outsb\"\n\t\t      : \"+S\" (__buf), \"+c\" (__n)\n\t\t      : \"d\" (__port));\n}\n\nstatic __inline void outsw(unsigned short __port, const void *__buf, unsigned long __n)\n{\n\t__asm__ volatile (\"cld; rep; outsw\"\n\t\t      : \"+S\" (__buf), \"+c\" (__n)\n\t\t      : \"d\" (__port));\n}\n\nstatic __inline void outsl(unsigned short __port, const void *__buf, unsigned long __n)\n{\n\t__asm__ volatile (\"cld; rep; outsl\"\n\t\t      : \"+S\" (__buf), \"+c\"(__n)\n\t\t      : \"d\" (__port));\n}\n\nstatic __inline void insb(unsigned short __port, void *__buf, unsigned long __n)\n{\n\t__asm__ volatile (\"cld; rep; insb\"\n\t\t      : \"+D\" (__buf), \"+c\" (__n)\n\t\t      : \"d\" (__port));\n}\n\nstatic __inline void insw(unsigned short __port, void *__buf, unsigned long __n)\n{\n\t__asm__ volatile (\"cld; rep; insw\"\n\t\t      : \"+D\" (__buf), \"+c\" (__n)\n\t\t      : \"d\" (__port));\n}\n\nstatic __inline void insl(unsigned short __port, void *__buf, unsigned long __n)\n{\n\t__asm__ volatile (\"cld; rep; insl\"\n\t\t      : \"+D\" (__buf), \"+c\" (__n)\n\t\t      : \"d\" (__port));\n}\n"
  },
  {
    "path": "user.libc/arch/x86_64/bits/limits.h",
    "content": "#define PAGESIZE 4096\n"
  },
  {
    "path": "user.libc/arch/x86_64/bits/mman.h",
    "content": "#define MAP_32BIT      0x40\n"
  },
  {
    "path": "user.libc/arch/x86_64/bits/posix.h",
    "content": "#define _POSIX_V6_LP64_OFF64  1\n#define _POSIX_V7_LP64_OFF64  1\n"
  },
  {
    "path": "user.libc/arch/x86_64/bits/ptrace.h",
    "content": "#define PTRACE_GET_THREAD_AREA\t\t25\n#define PTRACE_SET_THREAD_AREA\t\t26\n#define PTRACE_ARCH_PRCTL\t\t30\n#define PTRACE_SYSEMU\t\t\t31\n#define PTRACE_SYSEMU_SINGLESTEP\t32\n#define PTRACE_SINGLEBLOCK\t\t33\n\n#define PT_GET_THREAD_AREA PTRACE_GET_THREAD_AREA\n#define PT_SET_THREAD_AREA PTRACE_SET_THREAD_AREA\n#define PT_ARCH_PRCTL PTRACE_ARCH_PRCTL\n#define PT_SYSEMU PTRACE_SYSEMU\n#define PT_SYSEMU_SINGLESTEP PTRACE_SYSEMU_SINGLESTEP\n#define PT_STEPBLOCK PTRACE_SINGLEBLOCK\n"
  },
  {
    "path": "user.libc/arch/x86_64/bits/reg.h",
    "content": "#undef __WORDSIZE\n#define __WORDSIZE 64\n#define R15    0\n#define R14    1\n#define R13    2\n#define R12    3\n#define RBP    4\n#define RBX    5\n#define R11    6\n#define R10    7\n#define R9     8\n#define R8     9\n#define RAX    10\n#define RCX    11\n#define RDX    12\n#define RSI    13\n#define RDI    14\n#define ORIG_RAX 15\n#define RIP    16\n#define CS     17\n#define EFLAGS 18\n#define RSP    19\n#define SS     20\n#define FS_BASE 21\n#define GS_BASE 22\n#define DS     23\n#define ES     24\n#define FS     25\n#define GS     26\n"
  },
  {
    "path": "user.libc/arch/x86_64/bits/sem.h",
    "content": "struct semid_ds {\n\tstruct ipc_perm sem_perm;\n\ttime_t sem_otime;\n\tlong __unused1;\n\ttime_t sem_ctime;\n\tlong __unused2;\n\tunsigned short sem_nsems;\n\tchar __sem_nsems_pad[sizeof(long)-sizeof(short)];\n\tlong __unused3;\n\tlong __unused4;\n};\n"
  },
  {
    "path": "user.libc/arch/x86_64/bits/setjmp.h",
    "content": "typedef unsigned long __jmp_buf[8];\n"
  },
  {
    "path": "user.libc/arch/x86_64/bits/signal.h",
    "content": "#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define MINSIGSTKSZ 2048\n#define SIGSTKSZ 8192\n#endif\n\n#ifdef _GNU_SOURCE\nenum { REG_R8 = 0 };\n#define REG_R8 REG_R8\nenum { REG_R9 = 1 };\n#define REG_R9 REG_R9\nenum { REG_R10 = 2 };\n#define REG_R10 REG_R10\nenum { REG_R11 = 3 };\n#define REG_R11 REG_R11\nenum { REG_R12 = 4 };\n#define REG_R12 REG_R12\nenum { REG_R13 = 5 };\n#define REG_R13 REG_R13\nenum { REG_R14 = 6 };\n#define REG_R14 REG_R14\nenum { REG_R15 = 7 };\n#define REG_R15 REG_R15\nenum { REG_RDI = 8 };\n#define REG_RDI REG_RDI\nenum { REG_RSI = 9 };\n#define REG_RSI REG_RSI\nenum { REG_RBP = 10 };\n#define REG_RBP REG_RBP\nenum { REG_RBX = 11 };\n#define REG_RBX REG_RBX\nenum { REG_RDX = 12 };\n#define REG_RDX REG_RDX\nenum { REG_RAX = 13 };\n#define REG_RAX REG_RAX\nenum { REG_RCX = 14 };\n#define REG_RCX REG_RCX\nenum { REG_RSP = 15 };\n#define REG_RSP REG_RSP\nenum { REG_RIP = 16 };\n#define REG_RIP REG_RIP\nenum { REG_EFL = 17 };\n#define REG_EFL REG_EFL\nenum { REG_CSGSFS = 18 };\n#define REG_CSGSFS REG_CSGSFS\nenum { REG_ERR = 19 };\n#define REG_ERR REG_ERR\nenum { REG_TRAPNO = 20 };\n#define REG_TRAPNO REG_TRAPNO\nenum { REG_OLDMASK = 21 };\n#define REG_OLDMASK REG_OLDMASK\nenum { REG_CR2 = 22 };\n#define REG_CR2 REG_CR2\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\ntypedef long long greg_t, gregset_t[23];\ntypedef struct _fpstate {\n\tunsigned short cwd, swd, ftw, fop;\n\tunsigned long long rip, rdp;\n\tunsigned mxcsr, mxcr_mask;\n\tstruct {\n\t\tunsigned short significand[4], exponent, padding[3];\n\t} _st[8];\n\tstruct {\n\t\tunsigned element[4];\n\t} _xmm[16];\n\tunsigned padding[24];\n} *fpregset_t;\nstruct sigcontext {\n\tunsigned long r8, r9, r10, r11, r12, r13, r14, r15;\n\tunsigned long rdi, rsi, rbp, rbx, rdx, rax, rcx, rsp, rip, eflags;\n\tunsigned short cs, gs, fs, __pad0;\n\tunsigned long err, trapno, oldmask, cr2;\n\tstruct _fpstate *fpstate;\n\tunsigned long __reserved1[8];\n};\ntypedef struct {\n\tgregset_t gregs;\n\tfpregset_t fpregs;\n\tunsigned long long __reserved1[8];\n} mcontext_t;\n#else\ntypedef struct {\n\tunsigned long __space[32];\n} mcontext_t;\n#endif\n\nstruct sigaltstack {\n\tvoid *ss_sp;\n\tint ss_flags;\n\tsize_t ss_size;\n};\n\ntypedef struct __ucontext {\n\tunsigned long uc_flags;\n\tstruct __ucontext *uc_link;\n\tstack_t uc_stack;\n\tmcontext_t uc_mcontext;\n\tsigset_t uc_sigmask;\n\tunsigned long __fpregs_mem[64];\n} ucontext_t;\n\n#define SA_NOCLDSTOP  1\n#define SA_NOCLDWAIT  2\n#define SA_SIGINFO    4\n#define SA_ONSTACK    0x08000000\n#define SA_RESTART    0x10000000\n#define SA_NODEFER    0x40000000\n#define SA_RESETHAND  0x80000000\n#define SA_RESTORER   0x04000000\n\n#endif\n\n#define SIGHUP    1\n#define SIGINT    2\n#define SIGQUIT   3\n#define SIGILL    4\n#define SIGTRAP   5\n#define SIGABRT   6\n#define SIGIOT    SIGABRT\n#define SIGBUS    7\n#define SIGFPE    8\n#define SIGKILL   9\n#define SIGUSR1   10\n#define SIGSEGV   11\n#define SIGUSR2   12\n#define SIGPIPE   13\n#define SIGALRM   14\n#define SIGTERM   15\n#define SIGSTKFLT 16\n#define SIGCHLD   17\n#define SIGCONT   18\n#define SIGSTOP   19\n#define SIGTSTP   20\n#define SIGTTIN   21\n#define SIGTTOU   22\n#define SIGURG    23\n#define SIGXCPU   24\n#define SIGXFSZ   25\n#define SIGVTALRM 26\n#define SIGPROF   27\n#define SIGWINCH  28\n#define SIGIO     29\n#define SIGPOLL   29\n#define SIGPWR    30\n#define SIGSYS    31\n#define SIGUNUSED SIGSYS\n\n#define _NSIG 65\n\n"
  },
  {
    "path": "user.libc/arch/x86_64/bits/stat.h",
    "content": "/* copied from kernel definition, but with padding replaced\n * by the corresponding correctly-sized userspace types. */\n\nstruct stat {\n\tdev_t st_dev;\n\tino_t st_ino;\n\tnlink_t st_nlink;\n\n\tmode_t st_mode;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tunsigned int    __pad0;\n\tdev_t st_rdev;\n\toff_t st_size;\n\tblksize_t st_blksize;\n\tblkcnt_t st_blocks;\n\n\tstruct timespec st_atim;\n\tstruct timespec st_mtim;\n\tstruct timespec st_ctim;\n\tlong __unused[3];\n};\n"
  },
  {
    "path": "user.libc/arch/x86_64/bits/stdint.h",
    "content": "typedef int32_t int_fast16_t;\ntypedef int32_t int_fast32_t;\ntypedef uint32_t uint_fast16_t;\ntypedef uint32_t uint_fast32_t;\n\n#define INT_FAST16_MIN  INT32_MIN\n#define INT_FAST32_MIN  INT32_MIN\n\n#define INT_FAST16_MAX  INT32_MAX\n#define INT_FAST32_MAX  INT32_MAX\n\n#define UINT_FAST16_MAX UINT32_MAX\n#define UINT_FAST32_MAX UINT32_MAX\n\n#define INTPTR_MIN      INT64_MIN\n#define INTPTR_MAX      INT64_MAX\n#define UINTPTR_MAX     UINT64_MAX\n#define PTRDIFF_MIN     INT64_MIN\n#define PTRDIFF_MAX     INT64_MAX\n#define SIZE_MAX        UINT64_MAX\n"
  },
  {
    "path": "user.libc/arch/x86_64/bits/syscall.h.in",
    "content": "#define __NR_read\t\t\t\t0\n#define __NR_write\t\t\t\t1\n#define __NR_open\t\t\t\t2\n#define __NR_close\t\t\t\t3\n#define __NR_stat\t\t\t\t4\n#define __NR_fstat\t\t\t\t5\n#define __NR_lstat\t\t\t\t6\n#define __NR_poll\t\t\t\t7\n#define __NR_lseek\t\t\t\t8\n#define __NR_mmap\t\t\t\t9\n#define __NR_mprotect\t\t\t10\n#define __NR_munmap\t\t\t\t11\n#define __NR_brk\t\t\t\t12\n#define __NR_rt_sigaction\t\t13\n#define __NR_rt_sigprocmask\t\t14\n#define __NR_rt_sigreturn\t\t15\n#define __NR_ioctl\t\t\t\t16\n#define __NR_pread64\t\t\t17\n#define __NR_pwrite64\t\t\t18\n#define __NR_readv\t\t\t\t19\n#define __NR_writev\t\t\t\t20\n#define __NR_access\t\t\t\t21\n#define __NR_pipe\t\t\t\t22\n#define __NR_select\t\t\t\t23\n#define __NR_sched_yield\t\t24\n#define __NR_mremap\t\t\t\t25\n#define __NR_msync\t\t\t\t26\n#define __NR_mincore\t\t\t27\n#define __NR_madvise\t\t\t28\n#define __NR_shmget\t\t\t\t29\n#define __NR_shmat\t\t\t\t30\n#define __NR_shmctl\t\t\t\t31\n#define __NR_dup\t\t\t\t32\n#define __NR_dup2\t\t\t\t33\n#define __NR_pause\t\t\t\t34\n#define __NR_nanosleep\t\t\t35\n#define __NR_getitimer\t\t\t36\n#define __NR_alarm\t\t\t\t37\n#define __NR_setitimer\t\t\t38\n#define __NR_getpid\t\t\t\t39\n#define __NR_sendfile\t\t\t40\n#define __NR_socket\t\t\t\t41\n#define __NR_connect\t\t\t42\n#define __NR_accept\t\t\t\t43\n#define __NR_sendto\t\t\t\t44\n#define __NR_recvfrom\t\t\t45\n#define __NR_sendmsg\t\t\t46\n#define __NR_recvmsg\t\t\t47\n#define __NR_shutdown\t\t\t48\n#define __NR_bind\t\t\t\t49\n#define __NR_listen\t\t\t\t50\n#define __NR_getsockname\t\t51\n#define __NR_getpeername\t\t52\n#define __NR_socketpair\t\t\t53\n#define __NR_setsockopt\t\t\t54\n#define __NR_getsockopt\t\t\t55\n#define __NR_clone\t\t\t\t56\n#define __NR_fork\t\t\t\t57\n#define __NR_vfork\t\t\t\t58\n#define __NR_execve\t\t\t\t59\n#define __NR_exit\t\t\t\t60\n#define __NR_wait4\t\t\t\t61\n#define __NR_kill\t\t\t\t62\n#define __NR_uname\t\t\t\t63\n#define __NR_semget\t\t\t\t64\n#define __NR_semop\t\t\t\t65\n#define __NR_semctl\t\t\t\t66\n#define __NR_shmdt\t\t\t\t67\n#define __NR_msgget\t\t\t\t68\n#define __NR_msgsnd\t\t\t\t69\n#define __NR_msgrcv\t\t\t\t70\n#define __NR_msgctl\t\t\t\t71\n#define __NR_fcntl\t\t\t\t72\n#define __NR_flock\t\t\t\t73\n#define __NR_fsync\t\t\t\t74\n#define __NR_fdatasync\t\t\t75\n#define __NR_truncate\t\t\t76\n#define __NR_ftruncate\t\t\t77\n#define __NR_getdents\t\t\t78\n#define __NR_getcwd\t\t\t\t79\n#define __NR_chdir\t\t\t\t80\n#define __NR_fchdir\t\t\t\t81\n#define __NR_rename\t\t\t\t82\n#define __NR_mkdir\t\t\t\t83\n#define __NR_rmdir\t\t\t\t84\n#define __NR_creat\t\t\t\t85\n#define __NR_link\t\t\t\t86\n#define __NR_unlink\t\t\t\t87\n#define __NR_symlink\t\t\t88\n#define __NR_readlink\t\t\t89\n#define __NR_chmod\t\t\t\t90\n#define __NR_fchmod\t\t\t\t91\n#define __NR_chown\t\t\t\t92\n#define __NR_fchown\t\t\t\t93\n#define __NR_lchown\t\t\t\t94\n#define __NR_umask\t\t\t\t95\n#define __NR_gettimeofday\t\t96\n#define __NR_getrlimit\t\t\t97\n#define __NR_getrusage\t\t\t98\n#define __NR_sysinfo\t\t\t99\n#define __NR_times\t\t\t\t100\n#define __NR_ptrace\t\t\t\t101\n#define __NR_getuid\t\t\t\t102\n#define __NR_syslog\t\t\t\t103\n#define __NR_getgid\t\t\t\t104\n#define __NR_setuid\t\t\t\t105\n#define __NR_setgid\t\t\t\t106\n#define __NR_geteuid\t\t\t107\n#define __NR_getegid\t\t\t108\n#define __NR_setpgid\t\t\t109\n#define __NR_getppid\t\t\t110\n#define __NR_getpgrp\t\t\t111\n#define __NR_setsid\t\t\t\t112\n#define __NR_setreuid\t\t\t113\n#define __NR_setregid\t\t\t114\n#define __NR_getgroups\t\t\t115\n#define __NR_setgroups\t\t\t116\n#define __NR_setresuid\t\t\t117\n#define __NR_getresuid\t\t\t118\n#define __NR_setresgid\t\t\t119\n#define __NR_getresgid\t\t\t120\n#define __NR_getpgid\t\t\t121\n#define __NR_setfsuid\t\t\t122\n#define __NR_setfsgid\t\t\t123\n#define __NR_getsid\t\t\t\t124\n#define __NR_capget\t\t\t\t125\n#define __NR_capset\t\t\t\t126\n#define __NR_rt_sigpending\t\t127\n#define __NR_rt_sigtimedwait\t128\n#define __NR_rt_sigqueueinfo\t129\n#define __NR_rt_sigsuspend\t\t130\n#define __NR_sigaltstack\t\t131\n#define __NR_utime\t\t\t\t132\n#define __NR_mknod\t\t\t\t133\n#define __NR_uselib\t\t\t\t134\n#define __NR_personality\t\t135\n#define __NR_ustat\t\t\t\t136\n#define __NR_statfs\t\t\t\t137\n#define __NR_fstatfs\t\t\t138\n#define __NR_sysfs\t\t\t\t139\n#define __NR_getpriority\t\t\t140\n#define __NR_setpriority\t\t\t141\n#define __NR_sched_setparam\t\t\t142\n#define __NR_sched_getparam\t\t\t143\n#define __NR_sched_setscheduler\t\t144\n#define __NR_sched_getscheduler\t\t145\n#define __NR_sched_get_priority_max\t146\n#define __NR_sched_get_priority_min\t147\n#define __NR_sched_rr_get_interval\t148\n#define __NR_mlock\t\t\t\t\t149\n#define __NR_munlock\t\t\t\t150\n#define __NR_mlockall\t\t\t\t151\n#define __NR_munlockall\t\t\t\t152\n#define __NR_vhangup\t\t\t\t153\n#define __NR_modify_ldt\t\t\t\t154\n#define __NR_pivot_root\t\t\t\t155\n#define __NR__sysctl\t\t\t\t156\n#define __NR_prctl\t\t\t\t\t157\n#define __NR_arch_prctl\t\t\t\t158\n#define __NR_adjtimex\t\t\t\t159\n#define __NR_setrlimit\t\t\t\t160\n#define __NR_chroot\t\t\t\t\t161\n#define __NR_sync\t\t\t\t\t162\n#define __NR_acct\t\t\t\t\t163\n#define __NR_settimeofday\t\t\t164\n#define __NR_mount\t\t\t\t\t165\n#define __NR_umount2\t\t\t\t166\n#define __NR_swapon\t\t\t\t\t167\n#define __NR_swapoff\t\t\t\t168\n#define __NR_reboot\t\t\t\t\t169\n#define __NR_sethostname\t\t\t170\n#define __NR_setdomainname\t\t\t171\n#define __NR_iopl\t\t\t\t\t172\n#define __NR_ioperm\t\t\t\t\t173\n#define __NR_create_module\t\t\t174\n#define __NR_init_module\t\t\t175\n#define __NR_delete_module\t\t\t176\n#define __NR_get_kernel_syms\t\t177\n#define __NR_query_module\t\t\t178\n#define __NR_quotactl\t\t\t\t179\n#define __NR_nfsservctl\t\t\t\t180\n#define __NR_getpmsg\t\t\t\t181\n#define __NR_putpmsg\t\t\t\t182\n#define __NR_afs_syscall\t\t\t183\n#define __NR_tuxcall\t\t\t\t184\n#define __NR_security\t\t\t\t185\n#define __NR_gettid\t\t\t\t\t186\n#define __NR_readahead\t\t\t\t187\n#define __NR_setxattr\t\t\t\t188\n#define __NR_lsetxattr\t\t\t\t189\n#define __NR_fsetxattr\t\t\t\t190\n#define __NR_getxattr\t\t\t\t191\n#define __NR_lgetxattr\t\t\t\t192\n#define __NR_fgetxattr\t\t\t\t193\n#define __NR_listxattr\t\t\t\t194\n#define __NR_llistxattr\t\t\t\t195\n#define __NR_flistxattr\t\t\t\t196\n#define __NR_removexattr\t\t\t197\n#define __NR_lremovexattr\t\t\t198\n#define __NR_fremovexattr\t\t\t199\n#define __NR_tkill\t\t\t\t\t200\n#define __NR_time\t\t\t\t\t201\n#define __NR_futex\t\t\t\t\t202\n#define __NR_sched_setaffinity\t\t203\n#define __NR_sched_getaffinity\t\t204\n#define __NR_set_thread_area\t\t205\n#define __NR_io_setup\t\t\t\t206\n#define __NR_io_destroy\t\t\t\t207\n#define __NR_io_getevents\t\t\t208\n#define __NR_io_submit\t\t\t\t209\n#define __NR_io_cancel\t\t\t\t210\n#define __NR_get_thread_area\t\t211\n#define __NR_lookup_dcookie\t\t\t212\n#define __NR_epoll_create\t\t\t213\n#define __NR_epoll_ctl_old\t\t\t214\n#define __NR_epoll_wait_old\t\t\t215\n#define __NR_remap_file_pages\t\t216\n#define __NR_getdents64\t\t\t\t217\n#define __NR_set_tid_address\t\t218\n#define __NR_restart_syscall\t\t219\n#define __NR_semtimedop\t\t\t\t220\n#define __NR_fadvise64\t\t\t\t221\n#define __NR_timer_create\t\t\t222\n#define __NR_timer_settime\t\t\t223\n#define __NR_timer_gettime\t\t\t224\n#define __NR_timer_getoverrun\t\t225\n#define __NR_timer_delete\t\t\t226\n#define __NR_clock_settime\t\t\t227\n#define __NR_clock_gettime\t\t\t228\n#define __NR_clock_getres\t\t\t229\n#define __NR_clock_nanosleep\t\t230\n#define __NR_exit_group\t\t\t\t231\n#define __NR_epoll_wait\t\t\t\t232\n#define __NR_epoll_ctl\t\t\t\t233\n#define __NR_tgkill\t\t\t\t\t234\n#define __NR_utimes\t\t\t\t\t235\n#define __NR_vserver\t\t\t\t236\n#define __NR_mbind\t\t\t\t\t237\n#define __NR_set_mempolicy\t\t\t238\n#define __NR_get_mempolicy\t\t\t239\n#define __NR_mq_open\t\t\t\t240\n#define __NR_mq_unlink\t\t\t\t241\n#define __NR_mq_timedsend\t\t\t242\n#define __NR_mq_timedreceive\t\t243\n#define __NR_mq_notify\t\t\t\t244\n#define __NR_mq_getsetattr\t\t\t245\n#define __NR_kexec_load\t\t\t\t246\n#define __NR_waitid\t\t\t\t\t247\n#define __NR_add_key\t\t\t\t248\n#define __NR_request_key\t\t\t249\n#define __NR_keyctl\t\t\t\t\t250\n#define __NR_ioprio_set\t\t\t\t251\n#define __NR_ioprio_get\t\t\t\t252\n#define __NR_inotify_init\t\t\t253\n#define __NR_inotify_add_watch\t\t254\n#define __NR_inotify_rm_watch\t\t255\n#define __NR_migrate_pages\t\t\t256\n#define __NR_openat\t\t\t\t\t257\n#define __NR_mkdirat\t\t\t\t258\n#define __NR_mknodat\t\t\t\t259\n#define __NR_fchownat\t\t\t\t260\n#define __NR_futimesat\t\t\t\t261\n#define __NR_newfstatat\t\t\t\t262\n#define __NR_unlinkat\t\t\t\t263\n#define __NR_renameat\t\t\t\t264\n#define __NR_linkat\t\t\t\t\t265\n#define __NR_symlinkat\t\t\t\t266\n#define __NR_readlinkat\t\t\t\t267\n#define __NR_fchmodat\t\t\t\t268\n#define __NR_faccessat\t\t\t\t269\n#define __NR_pselect6\t\t\t\t270\n#define __NR_ppoll\t\t\t\t\t271\n#define __NR_unshare\t\t\t\t272\n#define __NR_set_robust_list\t\t273\n#define __NR_get_robust_list\t\t274\n#define __NR_splice\t\t\t\t\t275\n#define __NR_tee\t\t\t\t\t276\n#define __NR_sync_file_range\t\t277\n#define __NR_vmsplice\t\t\t\t278\n#define __NR_move_pages\t\t\t\t279\n#define __NR_utimensat\t\t\t\t280\n#define __NR_epoll_pwait\t\t\t281\n#define __NR_signalfd\t\t\t\t282\n#define __NR_timerfd_create\t\t\t283\n#define __NR_eventfd\t\t\t\t284\n#define __NR_fallocate\t\t\t\t285\n#define __NR_timerfd_settime\t\t286\n#define __NR_timerfd_gettime\t\t287\n#define __NR_accept4\t\t\t\t288\n#define __NR_signalfd4\t\t\t\t289\n#define __NR_eventfd2\t\t\t\t290\n#define __NR_epoll_create1\t\t\t291\n#define __NR_dup3\t\t\t\t\t292\n#define __NR_pipe2\t\t\t\t\t293\n#define __NR_inotify_init1\t\t\t294\n#define __NR_preadv\t\t\t\t\t295\n#define __NR_pwritev\t\t\t\t296\n#define __NR_rt_tgsigqueueinfo\t\t297\n#define __NR_perf_event_open\t\t298\n#define __NR_recvmmsg\t\t\t\t299\n#define __NR_fanotify_init\t\t\t300\n#define __NR_fanotify_mark\t\t\t301\n#define __NR_prlimit64\t\t\t\t302\n#define __NR_name_to_handle_at\t\t\t303\n#define __NR_open_by_handle_at\t\t\t304\n#define __NR_clock_adjtime\t\t\t305\n#define __NR_syncfs\t\t\t\t306\n#define __NR_sendmmsg\t\t\t\t307\n#define __NR_setns\t\t\t\t308\n#define __NR_getcpu\t\t\t\t309\n#define __NR_process_vm_readv\t\t\t310\n#define __NR_process_vm_writev\t\t\t311\n#define __NR_kcmp\t\t\t\t312\n#define __NR_finit_module\t\t\t313\n#define __NR_sched_setattr\t\t\t314\n#define __NR_sched_getattr\t\t\t315\n#define __NR_renameat2\t\t\t\t316\n#define __NR_seccomp\t\t\t\t317\n#define __NR_getrandom\t\t\t\t318\n#define __NR_memfd_create\t\t\t319\n#define __NR_kexec_file_load\t\t\t320\n#define __NR_bpf\t\t\t\t321\n#define __NR_execveat\t\t\t\t322\n#define __NR_userfaultfd\t\t\t323\n#define __NR_membarrier\t\t\t\t324\n#define __NR_mlock2\t\t\t\t325\n#define __NR_copy_file_range\t\t\t326\n#define __NR_preadv2\t\t\t\t327\n#define __NR_pwritev2\t\t\t\t328\n#define __NR_pkey_mprotect\t\t\t329\n#define __NR_pkey_alloc\t\t\t\t330\n#define __NR_pkey_free\t\t\t\t331\n#define __NR_statx\t\t\t\t332\n#define __NR_io_pgetevents\t\t\t333\n#define __NR_rseq\t\t\t\t334\n#define __NR_pidfd_send_signal\t\t\t424\n#define __NR_io_uring_setup\t\t\t425\n#define __NR_io_uring_enter\t\t\t426\n#define __NR_io_uring_register\t\t\t427\n#define __NR_open_tree\t\t428\n#define __NR_move_mount\t\t429\n#define __NR_fsopen\t\t430\n#define __NR_fsconfig\t\t431\n#define __NR_fsmount\t\t432\n#define __NR_fspick\t\t433\n#define __NR_pidfd_open\t\t434\n#define __NR_clone3\t\t435\n#define __NR_close_range\t436\n#define __NR_openat2\t\t437\n#define __NR_pidfd_getfd\t438\n#define __NR_faccessat2\t\t439\n\n"
  },
  {
    "path": "user.libc/arch/x86_64/bits/user.h",
    "content": "#undef __WORDSIZE\n#define __WORDSIZE 64\n\ntypedef struct user_fpregs_struct {\n\tuint16_t cwd, swd, ftw, fop;\n\tuint64_t rip, rdp;\n\tuint32_t mxcsr, mxcr_mask;\n\tuint32_t st_space[32], xmm_space[64], padding[24];\n} elf_fpregset_t;\n\nstruct user_regs_struct {\n\tunsigned long r15, r14, r13, r12, rbp, rbx, r11, r10, r9, r8;\n\tunsigned long rax, rcx, rdx, rsi, rdi, orig_rax, rip;\n\tunsigned long cs, eflags, rsp, ss, fs_base, gs_base, ds, es, fs, gs;\n};\n#define ELF_NGREG 27\ntypedef unsigned long long elf_greg_t, elf_gregset_t[ELF_NGREG];\n\nstruct user {\n\tstruct user_regs_struct\t\tregs;\n\tint\t\t\t\tu_fpvalid;\n\tstruct user_fpregs_struct\ti387;\n\tunsigned long\t\t\tu_tsize;\n\tunsigned long\t\t\tu_dsize;\n\tunsigned long\t\t\tu_ssize;\n\tunsigned long\t\t\tstart_code;\n\tunsigned long\t\t\tstart_stack;\n\tlong\t\t\t\tsignal;\n\tint\t\t\t\treserved;\n\tstruct user_regs_struct\t\t*u_ar0;\n\tstruct user_fpregs_struct\t*u_fpstate;\n\tunsigned long\t\t\tmagic;\n\tchar\t\t\t\tu_comm[32];\n\tunsigned long\t\t\tu_debugreg[8];\n};\n\n#define PAGE_MASK\t\t(~(PAGESIZE-1))\n#define NBPG\t\t\tPAGESIZE\n#define UPAGES\t\t\t1\n#define HOST_TEXT_START_ADDR\t(u.start_code)\n#define HOST_STACK_END_ADDR\t(u.start_stack + u.u_ssize * NBPG)\n"
  },
  {
    "path": "user.libc/arch/x86_64/crt_arch.h",
    "content": "__asm__(\n\".text \\n\"\n\".global \" START \" \\n\"\nSTART \": \\n\"\n\"\txor %rbp,%rbp \\n\"\n\"\tmov %rsp,%rdi \\n\"\n\".weak _DYNAMIC \\n\"\n\".hidden _DYNAMIC \\n\"\n\"\tlea _DYNAMIC(%rip),%rsi \\n\"\n\"\tandq $-16,%rsp \\n\"\n\"\tcall \" START \"_c \\n\"\n);\n"
  },
  {
    "path": "user.libc/arch/x86_64/ksigaction.h",
    "content": "#include <features.h>\n\nstruct k_sigaction {\n\tvoid (*handler)(int);\n\tunsigned long flags;\n\tvoid (*restorer)(void);\n\tunsigned mask[2];\n};\n\nhidden void __restore_rt();\n#define __restore __restore_rt\n"
  },
  {
    "path": "user.libc/arch/x86_64/kstat.h",
    "content": "struct kstat {\n\tdev_t st_dev;\n\tino_t st_ino;\n\tnlink_t st_nlink;\n\n\tmode_t st_mode;\n\tuid_t st_uid;\n\tgid_t st_gid;\n\tunsigned int    __pad0;\n\tdev_t st_rdev;\n\toff_t st_size;\n\tblksize_t st_blksize;\n\tblkcnt_t st_blocks;\n\n\tlong st_atime_sec;\n\tlong st_atime_nsec;\n\tlong st_mtime_sec;\n\tlong st_mtime_nsec;\n\tlong st_ctime_sec;\n\tlong st_ctime_nsec;\n\tlong __unused[3];\n};\n"
  },
  {
    "path": "user.libc/arch/x86_64/pthread_arch.h",
    "content": "static inline uintptr_t __get_tp()\n{\n\tuintptr_t tp;\n\t__asm__ (\"mov %%fs:0,%0\" : \"=r\" (tp) );\n\treturn tp;\n}\n\n#define MC_PC gregs[REG_RIP]\n"
  },
  {
    "path": "user.libc/arch/x86_64/reloc.h",
    "content": "#define LDSO_ARCH \"x86_64\"\n\n#define REL_SYMBOLIC    R_X86_64_64\n#define REL_OFFSET32    R_X86_64_PC32\n#define REL_GOT         R_X86_64_GLOB_DAT\n#define REL_PLT         R_X86_64_JUMP_SLOT\n#define REL_RELATIVE    R_X86_64_RELATIVE\n#define REL_COPY        R_X86_64_COPY\n#define REL_DTPMOD      R_X86_64_DTPMOD64\n#define REL_DTPOFF      R_X86_64_DTPOFF64\n#define REL_TPOFF       R_X86_64_TPOFF64\n#define REL_TLSDESC     R_X86_64_TLSDESC\n\n#define CRTJMP(pc,sp) __asm__ __volatile__( \\\n\t\"mov %1,%%rsp ; jmp *%0\" : : \"r\"(pc), \"r\"(sp) : \"memory\" )\n\n#define GETFUNCSYM(fp, sym, got) __asm__ ( \\\n\t\".hidden \" #sym \"\\n\" \\\n\t\"\tlea \" #sym \"(%%rip),%0\\n\" \\\n\t: \"=r\"(*fp) : : \"memory\" )\n"
  },
  {
    "path": "user.libc/arch/x86_64/syscall_arch.h",
    "content": "#define __SYSCALL_LL_E(x) (x)\n#define __SYSCALL_LL_O(x) (x)\n\nstatic __inline long __syscall0(long n)\n{\n\tunsigned long ret;\n\t__asm__ __volatile__ (\"syscall\" : \"=a\"(ret) : \"a\"(n) : \"rcx\", \"r11\", \"memory\");\n\treturn ret;\n}\n\nstatic __inline long __syscall1(long n, long a1)\n{\n\tunsigned long ret;\n\t__asm__ __volatile__ (\"syscall\" : \"=a\"(ret) : \"a\"(n), \"D\"(a1) : \"rcx\", \"r11\", \"memory\");\n\treturn ret;\n}\n\nstatic __inline long __syscall2(long n, long a1, long a2)\n{\n\tunsigned long ret;\n\t__asm__ __volatile__ (\"syscall\" : \"=a\"(ret) : \"a\"(n), \"D\"(a1), \"S\"(a2)\n\t\t\t\t\t\t  : \"rcx\", \"r11\", \"memory\");\n\treturn ret;\n}\n\nstatic __inline long __syscall3(long n, long a1, long a2, long a3)\n{\n\tunsigned long ret;\n\t__asm__ __volatile__ (\"syscall\" : \"=a\"(ret) : \"a\"(n), \"D\"(a1), \"S\"(a2),\n\t\t\t\t\t\t  \"d\"(a3) : \"rcx\", \"r11\", \"memory\");\n\treturn ret;\n}\n\nstatic __inline long __syscall4(long n, long a1, long a2, long a3, long a4)\n{\n\tunsigned long ret;\n\tregister long r10 __asm__(\"r10\") = a4;\n\t__asm__ __volatile__ (\"syscall\" : \"=a\"(ret) : \"a\"(n), \"D\"(a1), \"S\"(a2),\n\t\t\t\t\t\t  \"d\"(a3), \"r\"(r10): \"rcx\", \"r11\", \"memory\");\n\treturn ret;\n}\n\nstatic __inline long __syscall5(long n, long a1, long a2, long a3, long a4, long a5)\n{\n\tunsigned long ret;\n\tregister long r10 __asm__(\"r10\") = a4;\n\tregister long r8 __asm__(\"r8\") = a5;\n\t__asm__ __volatile__ (\"syscall\" : \"=a\"(ret) : \"a\"(n), \"D\"(a1), \"S\"(a2),\n\t\t\t\t\t\t  \"d\"(a3), \"r\"(r10), \"r\"(r8) : \"rcx\", \"r11\", \"memory\");\n\treturn ret;\n}\n\nstatic __inline long __syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6)\n{\n\tunsigned long ret;\n\tregister long r10 __asm__(\"r10\") = a4;\n\tregister long r8 __asm__(\"r8\") = a5;\n\tregister long r9 __asm__(\"r9\") = a6;\n\t__asm__ __volatile__ (\"syscall\" : \"=a\"(ret) : \"a\"(n), \"D\"(a1), \"S\"(a2),\n\t\t\t\t\t\t  \"d\"(a3), \"r\"(r10), \"r\"(r8), \"r\"(r9) : \"rcx\", \"r11\", \"memory\");\n\treturn ret;\n}\n\n#define VDSO_USEFUL\n#define VDSO_CGT_SYM \"__vdso_clock_gettime\"\n#define VDSO_CGT_VER \"LINUX_2.6\"\n#define VDSO_GETCPU_SYM \"__vdso_getcpu\"\n#define VDSO_GETCPU_VER \"LINUX_2.6\"\n\n#define IPC_64 0\n"
  },
  {
    "path": "user.libc/build.sh",
    "content": "#!/bin/sh\n\nINSTALL_DIR=$1\nLIBC_TAGET_ARCH=$2\nLIBC_CROSS_COMPILE=$3\n\nif [ -z \"$INSTALL_DIR\" ]; then\n\tINSTALL_DIR=$(dirname $(pwd))/out\nfi\n\nif [ -z \"$LIBC_TAGET_ARCH\" ]; then\n\tLIBC_TAGET_ARCH=\"$(uname -m)\"\nfi\n\necho \"LIBC INSTALL-DIR:${INSTALL_DIR} ARCH:${LIBC_TAGET_ARCH} CROSS:${LIBC_CROSS_COMPILE}\"\n\nHOST_ARCH=\"$(uname -m)\"\n\n# if build on aarch64 host, do not set th --target\nif [ \"$HOST_ARCH\" = \"aarch64\" ]; then\n\techo \"Build on aarch64 host\"\n\t./configure --disable-shared --prefix=${INSTALL_DIR} --with-malloc=mallocng\nelse\n\techo \"Build on x86 host\"\n\t./configure CROSS_COMPILE=${LIBC_CROSS_COMPILE} --disable-shared --target=${LIBC_TAGET_ARCH} \\\n\t\t--prefix=${INSTALL_DIR} --with-malloc=mallocng\nfi\n"
  },
  {
    "path": "user.libc/compat/time32/__xstat.c",
    "content": "#include \"time32.h\"\n#include <sys/stat.h>\n\nstruct stat32;\n\nint __fxstat64(int ver, int fd, struct stat32 *buf)\n{\n\treturn __fstat_time32(fd, buf);\n}\n\nint __fxstatat64(int ver, int fd, const char *path, struct stat32 *buf, int flag)\n{\n\treturn __fstatat_time32(fd, path, buf, flag);\n}\n\nint __lxstat64(int ver, const char *path, struct stat32 *buf)\n{\n\treturn __lstat_time32(path, buf);\n}\n\nint __xstat64(int ver, const char *path, struct stat32 *buf)\n{\n\treturn __stat_time32(path, buf);\n}\n"
  },
  {
    "path": "user.libc/compat/time32/adjtime32.c",
    "content": "#define _GNU_SOURCE\n#include \"time32.h\"\n#include <time.h>\n#include <sys/time.h>\n#include <sys/timex.h>\n\nint __adjtime32(const struct timeval32 *in32, struct timeval32 *out32)\n{\n\tstruct timeval out;\n\tint r = adjtime((&(struct timeval){\n\t\t.tv_sec = in32->tv_sec,\n\t\t.tv_usec = in32->tv_usec}), &out);\n\tif (r) return r;\n\t/* We can't range-check the result because success was already\n\t * committed by the above call. */\n\tif (out32) {\n\t\tout32->tv_sec = out.tv_sec;\n\t\tout32->tv_usec = out.tv_usec;\n\t}\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/compat/time32/adjtimex_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <sys/timex.h>\n\nstruct timex32;\n\nint __adjtimex_time32(struct timex32 *tx32)\n{\n\treturn __clock_adjtime32(CLOCK_REALTIME, tx32);\n}\n"
  },
  {
    "path": "user.libc/compat/time32/aio_suspend_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <aio.h>\n\nint __aio_suspend_time32(const struct aiocb *const cbs[], int cnt, const struct timespec32 *ts32)\n{\n\treturn aio_suspend(cbs, cnt, ts32 ? (&(struct timespec){\n\t\t.tv_sec = ts32->tv_sec, .tv_nsec = ts32->tv_nsec}) : 0);\n}\n\nweak_alias(aio_suspend, aio_suspend64);\n"
  },
  {
    "path": "user.libc/compat/time32/clock_adjtime32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <sys/time.h>\n#include <sys/timex.h>\n#include <string.h>\n#include <stddef.h>\n\nstruct timex32 {\n\tunsigned modes;\n\tlong offset, freq, maxerror, esterror;\n\tint status;\n\tlong constant, precision, tolerance;\n\tstruct timeval32 time;\n\tlong tick, ppsfreq, jitter;\n\tint shift;\n\tlong stabil, jitcnt, calcnt, errcnt, stbcnt;\n\tint tai;\n\tint __padding[11];\n};\n\nint __clock_adjtime32(clockid_t clock_id, struct timex32 *tx32)\n{\n\tstruct timex utx = {\n\t\t.modes = tx32->modes,\n\t\t.offset = tx32->offset,\n\t\t.freq = tx32->freq,\n\t\t.maxerror = tx32->maxerror,\n\t\t.esterror = tx32->esterror,\n\t\t.status = tx32->status,\n\t\t.constant = tx32->constant,\n\t\t.precision = tx32->precision,\n\t\t.tolerance = tx32->tolerance,\n\t\t.time.tv_sec = tx32->time.tv_sec,\n\t\t.time.tv_usec = tx32->time.tv_usec,\n\t\t.tick = tx32->tick,\n\t\t.ppsfreq = tx32->ppsfreq,\n\t\t.jitter = tx32->jitter,\n\t\t.shift = tx32->shift,\n\t\t.stabil = tx32->stabil,\n\t\t.jitcnt = tx32->jitcnt,\n\t\t.calcnt = tx32->calcnt,\n\t\t.errcnt = tx32->errcnt,\n\t\t.stbcnt = tx32->stbcnt,\n\t\t.tai = tx32->tai,\n\t};\n\tint r = clock_adjtime(clock_id, &utx);\n\tif (r<0) return r;\n\ttx32->modes = utx.modes;\n\ttx32->offset = utx.offset;\n\ttx32->freq = utx.freq;\n\ttx32->maxerror = utx.maxerror;\n\ttx32->esterror = utx.esterror;\n\ttx32->status = utx.status;\n\ttx32->constant = utx.constant;\n\ttx32->precision = utx.precision;\n\ttx32->tolerance = utx.tolerance;\n\ttx32->time.tv_sec = utx.time.tv_sec;\n\ttx32->time.tv_usec = utx.time.tv_usec;\n\ttx32->tick = utx.tick;\n\ttx32->ppsfreq = utx.ppsfreq;\n\ttx32->jitter = utx.jitter;\n\ttx32->shift = utx.shift;\n\ttx32->stabil = utx.stabil;\n\ttx32->jitcnt = utx.jitcnt;\n\ttx32->calcnt = utx.calcnt;\n\ttx32->errcnt = utx.errcnt;\n\ttx32->stbcnt = utx.stbcnt;\n\ttx32->tai = utx.tai;\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/compat/time32/clock_getres_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n\nint __clock_getres_time32(clockid_t clk, struct timespec32 *ts32)\n{\n\tstruct timespec ts;\n\tint r = clock_getres(clk, &ts);\n\tif (!r && ts32) {\n\t\tts32->tv_sec = ts.tv_sec;\n\t\tts32->tv_nsec = ts.tv_nsec;\n\t}\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/compat/time32/clock_gettime32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <errno.h>\n#include <stdint.h>\n\nint __clock_gettime32(clockid_t clk, struct timespec32 *ts32)\n{\n\tstruct timespec ts;\n\tint r = clock_gettime(clk, &ts);\n\tif (r) return r;\n\tif (ts.tv_sec < INT32_MIN || ts.tv_sec > INT32_MAX) {\n\t\terrno = EOVERFLOW;\n\t\treturn -1;\n\t}\n\tts32->tv_sec = ts.tv_sec;\n\tts32->tv_nsec = ts.tv_nsec;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/compat/time32/clock_nanosleep_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <errno.h>\n\nint __clock_nanosleep_time32(clockid_t clk, int flags, const struct timespec32 *req32, struct timespec32 *rem32)\n{\n\tstruct timespec rem;\n\tint ret = clock_nanosleep(clk, flags, (&(struct timespec){\n\t\t.tv_sec = req32->tv_sec, .tv_nsec = req32->tv_nsec}), &rem);\n\tif (ret==EINTR && rem32 && !(flags & TIMER_ABSTIME)) {\n\t\trem32->tv_sec = rem.tv_sec;\n\t\trem32->tv_nsec = rem.tv_nsec;\n\t}\n\treturn ret;\n}\n"
  },
  {
    "path": "user.libc/compat/time32/clock_settime32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n\nint __clock_settime32(clockid_t clk, const struct timespec32 *ts32)\n{\n\treturn clock_settime(clk, (&(struct timespec){\n\t\t.tv_sec = ts32->tv_sec,\n\t\t.tv_nsec = ts32->tv_nsec}));\n}\n"
  },
  {
    "path": "user.libc/compat/time32/cnd_timedwait_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <threads.h>\n\nint __cnd_timedwait_time32(cnd_t *restrict c, mtx_t *restrict m, const struct timespec32 *restrict ts32)\n{\n\treturn cnd_timedwait(c, m, ts32 ? (&(struct timespec){\n\t\t.tv_sec = ts32->tv_sec, .tv_nsec = ts32->tv_nsec}) : 0);\n}\n"
  },
  {
    "path": "user.libc/compat/time32/ctime32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n\nchar *__ctime32(time32_t *t)\n{\n\treturn ctime(&(time_t){*t});\n}\n"
  },
  {
    "path": "user.libc/compat/time32/ctime32_r.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n\nchar *__ctime32_r(time32_t *t, char *buf)\n{\n\treturn ctime_r(&(time_t){*t}, buf);\n}\n"
  },
  {
    "path": "user.libc/compat/time32/difftime32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n\ndouble __difftime32(time32_t t1, time32_t t2)\n{\n\treturn difftime(t1, t2);\n}\n"
  },
  {
    "path": "user.libc/compat/time32/fstat_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <string.h>\n#include <sys/stat.h>\n#include <stddef.h>\n\nstruct stat32;\n\nint __fstat_time32(int fd, struct stat32 *restrict st32)\n{\n\tstruct stat st;\n\tint r = fstat(fd, &st);\n\tif (!r) memcpy(st32, &st, offsetof(struct stat, st_atim));\n\treturn r;\n}\n\nweak_alias(fstat, fstat64);\n"
  },
  {
    "path": "user.libc/compat/time32/fstatat_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <string.h>\n#include <sys/stat.h>\n#include <stddef.h>\n\nstruct stat32;\n\nint __fstatat_time32(int fd, const char *restrict path, struct stat32 *restrict st32, int flag)\n{\n\tstruct stat st;\n\tint r = fstatat(fd, path, &st, flag);\n\tif (!r) memcpy(st32, &st, offsetof(struct stat, st_atim));\n\treturn r;\n}\n\nweak_alias(fstatat, fstatat64);\n"
  },
  {
    "path": "user.libc/compat/time32/ftime32.c",
    "content": "#include \"time32.h\"\n#include <sys/timeb.h>\n#include <errno.h>\n#include <stdint.h>\n\nstruct timeb32 {\n\tint32_t time;\n\tunsigned short millitm;\n\tshort timezone, dstflag;\n};\n\nint __ftime32(struct timeb32 *tp)\n{\n\tstruct timeb tb;\n\tif (ftime(&tb) < 0) return -1;\n\tif (tb.time < INT32_MIN || tb.time > INT32_MAX) {\n\t\terrno = EOVERFLOW;\n\t\treturn -1;\n\t}\n\ttp->time = tb.time;\n\ttp->millitm = tb.millitm;\n\ttp->timezone = tb.timezone;\n\ttp->dstflag = tb.dstflag;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/compat/time32/futimens_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <sys/stat.h>\n\nint __futimens_time32(int fd, const struct timespec32 *times32)\n{\n\treturn futimens(fd, !times32 ? 0 : ((struct timespec[2]){\n\t\t{.tv_sec = times32[0].tv_sec,.tv_nsec = times32[0].tv_nsec},\n\t\t{.tv_sec = times32[1].tv_sec,.tv_nsec = times32[1].tv_nsec}}));\n}\n"
  },
  {
    "path": "user.libc/compat/time32/futimes_time32.c",
    "content": "#define _GNU_SOURCE\n#include \"time32.h\"\n#include <time.h>\n#include <sys/time.h>\n#include <sys/stat.h>\n\nint __futimes_time32(int fd, const struct timeval32 times32[2])\n{\n\treturn futimes(fd, !times32 ? 0 : ((struct timeval[2]){\n\t\t{.tv_sec = times32[0].tv_sec,.tv_usec = times32[0].tv_usec},\n\t\t{.tv_sec = times32[1].tv_sec,.tv_usec = times32[1].tv_usec}}));\n}\n"
  },
  {
    "path": "user.libc/compat/time32/futimesat_time32.c",
    "content": "#define _GNU_SOURCE\n#include \"time32.h\"\n#include <time.h>\n#include <sys/time.h>\n#include <sys/stat.h>\n\nint __futimesat_time32(int dirfd, const char *pathname, const struct timeval32 times32[2])\n{\n\treturn futimesat(dirfd, pathname, !times32 ? 0 : ((struct timeval[2]){\n\t\t{.tv_sec = times32[0].tv_sec,.tv_usec = times32[0].tv_usec},\n\t\t{.tv_sec = times32[1].tv_sec,.tv_usec = times32[1].tv_usec}}));\n}\n"
  },
  {
    "path": "user.libc/compat/time32/getitimer_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <sys/time.h>\n\nint __getitimer_time32(int which, struct itimerval32 *old32)\n{\n\tstruct itimerval old;\n\tint r = getitimer(which, &old);\n\tif (r) return r;\n\told32->it_interval.tv_sec = old.it_interval.tv_sec;\n\told32->it_interval.tv_usec = old.it_interval.tv_usec;\n\told32->it_value.tv_sec = old.it_value.tv_sec;\n\told32->it_value.tv_usec = old.it_value.tv_usec;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/compat/time32/getrusage_time32.c",
    "content": "#include \"time32.h\"\n#include <string.h>\n#include <stddef.h>\n#include <sys/resource.h>\n\nstruct compat_rusage {\n\tstruct timeval32 ru_utime;\n\tstruct timeval32 ru_stime;\n\tlong\tru_maxrss;\n\tlong\tru_ixrss;\n\tlong\tru_idrss;\n\tlong\tru_isrss;\n\tlong\tru_minflt;\n\tlong\tru_majflt;\n\tlong\tru_nswap;\n\tlong\tru_inblock;\n\tlong\tru_oublock;\n\tlong\tru_msgsnd;\n\tlong\tru_msgrcv;\n\tlong\tru_nsignals;\n\tlong\tru_nvcsw;\n\tlong\tru_nivcsw;\n};\n\nint __getrusage_time32(int who, struct compat_rusage *usage)\n{\n\tstruct rusage ru;\n\tint r = getrusage(who, &ru);\n\tif (!r) {\n\t\tusage->ru_utime.tv_sec = ru.ru_utime.tv_sec;\n\t\tusage->ru_utime.tv_usec = ru.ru_utime.tv_usec;\n\t\tusage->ru_stime.tv_sec = ru.ru_stime.tv_sec;\n\t\tusage->ru_stime.tv_usec = ru.ru_stime.tv_usec;\n\t\tmemcpy(&usage->ru_maxrss, &ru.ru_maxrss,\n\t\t\tsizeof(struct compat_rusage) -\n\t\t\toffsetof(struct compat_rusage, ru_maxrss));\n\t}\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/compat/time32/gettimeofday_time32.c",
    "content": "#include \"time32.h\"\n#include <sys/time.h>\n#include <errno.h>\n#include <stdint.h>\n\nint __gettimeofday_time32(struct timeval32 *tv32, void *tz)\n{\n\tstruct timeval tv;\n\tif (!tv32) return 0;\n\tint r = gettimeofday(&tv, 0);\n\tif (r) return r;\n\tif (tv.tv_sec < INT32_MIN || tv.tv_sec > INT32_MAX) {\n\t\terrno = EOVERFLOW;\n\t\treturn -1;\n\t}\n\ttv32->tv_sec = tv.tv_sec;\n\ttv32->tv_usec = tv.tv_usec;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/compat/time32/gmtime32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n\nstruct tm *__gmtime32(time32_t *t)\n{\n\treturn gmtime(&(time_t){*t});\n}\n"
  },
  {
    "path": "user.libc/compat/time32/gmtime32_r.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n\nstruct tm *__gmtime32_r(time32_t *t, struct tm *tm)\n{\n\treturn gmtime_r(&(time_t){*t}, tm);\n}\n"
  },
  {
    "path": "user.libc/compat/time32/localtime32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n\nstruct tm *__localtime32(time32_t *t)\n{\n\treturn localtime(&(time_t){*t});\n}\n"
  },
  {
    "path": "user.libc/compat/time32/localtime32_r.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n\nstruct tm *__localtime32_r(time32_t *t, struct tm *tm)\n{\n\treturn localtime_r(&(time_t){*t}, tm);\n}\n"
  },
  {
    "path": "user.libc/compat/time32/lstat_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <string.h>\n#include <sys/stat.h>\n#include <stddef.h>\n\nstruct stat32;\n\nint __lstat_time32(const char *restrict path, struct stat32 *restrict st32)\n{\n\tstruct stat st;\n\tint r = lstat(path, &st);\n\tif (!r) memcpy(st32, &st, offsetof(struct stat, st_atim));\n\treturn r;\n}\n\nweak_alias(lstat, lstat64);\n"
  },
  {
    "path": "user.libc/compat/time32/lutimes_time32.c",
    "content": "#define _GNU_SOURCE\n#include \"time32.h\"\n#include <time.h>\n#include <sys/time.h>\n#include <sys/stat.h>\n\nint __lutimes_time32(const char *path, const struct timeval32 times32[2])\n{\n\treturn lutimes(path, !times32 ? 0 : ((struct timeval[2]){\n\t\t{.tv_sec = times32[0].tv_sec,.tv_usec = times32[0].tv_usec},\n\t\t{.tv_sec = times32[1].tv_sec,.tv_usec = times32[1].tv_usec}}));\n}\n"
  },
  {
    "path": "user.libc/compat/time32/mktime32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <errno.h>\n#include <stdint.h>\n\ntime32_t __mktime32(struct tm *tm)\n{\n\tstruct tm tmp = *tm;\n\ttime_t t = mktime(&tmp);\n\tif (t < INT32_MIN || t > INT32_MAX) {\n\t\terrno = EOVERFLOW;\n\t\treturn -1;\n\t}\n\t*tm = tmp;\n\treturn t;\n}\n"
  },
  {
    "path": "user.libc/compat/time32/mq_timedreceive_time32.c",
    "content": "#include \"time32.h\"\n#include <mqueue.h>\n#include <time.h>\n\nssize_t __mq_timedreceive_time32(mqd_t mqd, char *restrict msg, size_t len, unsigned *restrict prio, const struct timespec32 *restrict ts32)\n{\n\treturn mq_timedreceive(mqd, msg, len, prio, ts32 ? (&(struct timespec){\n\t\t.tv_sec = ts32->tv_sec, .tv_nsec = ts32->tv_nsec}) : 0);\n}\n"
  },
  {
    "path": "user.libc/compat/time32/mq_timedsend_time32.c",
    "content": "#include \"time32.h\"\n#include <mqueue.h>\n#include <time.h>\n\nint __mq_timedsend_time32(mqd_t mqd, const char *msg, size_t len, unsigned prio, const struct timespec32 *ts32)\n{\n\treturn mq_timedsend(mqd, msg, len, prio, ts32 ? (&(struct timespec){\n\t\t.tv_sec = ts32->tv_sec, .tv_nsec = ts32->tv_nsec}) : 0);\n}\n"
  },
  {
    "path": "user.libc/compat/time32/mtx_timedlock_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <threads.h>\n\nint __mtx_timedlock_time32(mtx_t *restrict m, const struct timespec32 *restrict ts32)\n{\n\treturn mtx_timedlock(m, !ts32 ? 0 : (&(struct timespec){\n\t\t.tv_sec = ts32->tv_sec, .tv_nsec = ts32->tv_nsec}));\n}\n"
  },
  {
    "path": "user.libc/compat/time32/nanosleep_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <errno.h>\n\nint __nanosleep_time32(const struct timespec32 *req32, struct timespec32 *rem32)\n{\n\tstruct timespec rem;\n\tint ret = nanosleep((&(struct timespec){\n\t\t.tv_sec = req32->tv_sec, .tv_nsec = req32->tv_nsec}), &rem);\n\tif (ret<0 && errno==EINTR && rem32) {\n\t\trem32->tv_sec = rem.tv_sec;\n\t\trem32->tv_nsec = rem.tv_nsec;\n\t}\n\treturn ret;\n}\n"
  },
  {
    "path": "user.libc/compat/time32/ppoll_time32.c",
    "content": "#include \"time32.h\"\n#define _GNU_SOURCE\n#include <time.h>\n#include <poll.h>\n\nint __ppoll_time32(struct pollfd *fds, nfds_t n, const struct timespec32 *ts32, const sigset_t *mask)\n{\n\treturn ppoll(fds, n, !ts32 ? 0 : (&(struct timespec){\n\t\t.tv_sec = ts32->tv_sec, .tv_nsec = ts32->tv_nsec}), mask);\n}\n"
  },
  {
    "path": "user.libc/compat/time32/pselect_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <sys/select.h>\n\nint __pselect_time32(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict efds, const struct timespec32 *restrict ts32, const sigset_t *restrict mask)\n{\n\treturn pselect(n, rfds, wfds, efds, !ts32 ? 0 : (&(struct timespec){\n\t\t.tv_sec = ts32->tv_sec, .tv_nsec = ts32->tv_nsec}), mask);\n}\n"
  },
  {
    "path": "user.libc/compat/time32/pthread_cond_timedwait_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <pthread.h>\n\nint __pthread_cond_timedwait_time32(pthread_cond_t *restrict c, pthread_mutex_t *restrict m, const struct timespec32 *restrict ts32)\n{\n\treturn pthread_cond_timedwait(c, m, !ts32 ? 0 : (&(struct timespec){\n\t\t.tv_sec = ts32->tv_sec, .tv_nsec = ts32->tv_nsec}));\n}\n"
  },
  {
    "path": "user.libc/compat/time32/pthread_mutex_timedlock_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <pthread.h>\n\nint __pthread_mutex_timedlock_time32(pthread_mutex_t *restrict m, const struct timespec32 *restrict ts32)\n{\n\treturn pthread_mutex_timedlock(m, !ts32 ? 0 : (&(struct timespec){\n\t\t.tv_sec = ts32->tv_sec, .tv_nsec = ts32->tv_nsec}));\n}\n"
  },
  {
    "path": "user.libc/compat/time32/pthread_rwlock_timedrdlock_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <pthread.h>\n\nint __pthread_rwlock_timedrdlock_time32(pthread_rwlock_t *restrict rw, const struct timespec32 *restrict ts32)\n{\n\treturn pthread_rwlock_timedrdlock(rw, !ts32 ? 0 : (&(struct timespec){\n\t\t.tv_sec = ts32->tv_sec, .tv_nsec = ts32->tv_nsec}));\n}\n"
  },
  {
    "path": "user.libc/compat/time32/pthread_rwlock_timedwrlock_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <pthread.h>\n\nint __pthread_rwlock_timedwrlock_time32(pthread_rwlock_t *restrict rw, const struct timespec32 *restrict ts32)\n{\n\treturn pthread_rwlock_timedwrlock(rw, !ts32 ? 0 : (&(struct timespec){\n\t\t.tv_sec = ts32->tv_sec, .tv_nsec = ts32->tv_nsec}));\n}\n"
  },
  {
    "path": "user.libc/compat/time32/pthread_timedjoin_np_time32.c",
    "content": "#define _GNU_SOURCE\n#include \"time32.h\"\n#include <time.h>\n#include <pthread.h>\n\nint __pthread_timedjoin_np_time32(pthread_t t, void **res, const struct timespec32 *at32)\n{\n\treturn pthread_timedjoin_np(t, res, !at32 ? 0 : (&(struct timespec){\n\t\t.tv_sec = at32->tv_sec, .tv_nsec = at32->tv_nsec}));\n}\n"
  },
  {
    "path": "user.libc/compat/time32/recvmmsg_time32.c",
    "content": "#include \"time32.h\"\n#define _GNU_SOURCE\n#include <time.h>\n#include <sys/socket.h>\n\nint __recvmmsg_time32(int fd, struct mmsghdr *msgvec, unsigned int vlen, unsigned int flags, struct timespec32 *ts32)\n{\n\treturn recvmmsg(fd, msgvec, vlen, flags, ts32 ? (&(struct timespec){\n\t\t.tv_sec = ts32->tv_sec, .tv_nsec = ts32->tv_nsec}) : 0);\n}\n"
  },
  {
    "path": "user.libc/compat/time32/sched_rr_get_interval_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <sched.h>\n\nint __sched_rr_get_interval_time32(pid_t pid, struct timespec32 *ts32)\n{\n\tstruct timespec ts;\n\tint r = sched_rr_get_interval(pid, &ts);\n\tif (r) return r;\n\tts32->tv_sec = ts.tv_sec;\n\tts32->tv_nsec = ts.tv_nsec;\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/compat/time32/select_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <sys/time.h>\n#include <sys/select.h>\n\nint __select_time32(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict efds, struct timeval32 *restrict tv32)\n{\n\treturn select(n, rfds, wfds, efds, !tv32 ? 0 : (&(struct timeval){\n\t\t.tv_sec = tv32->tv_sec, .tv_usec = tv32->tv_usec}));\n}\n"
  },
  {
    "path": "user.libc/compat/time32/sem_timedwait_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <semaphore.h>\n\nint __sem_timedwait_time32(sem_t *sem, const struct timespec32 *restrict ts32)\n{\n\treturn sem_timedwait(sem, !ts32 ? 0 : (&(struct timespec){\n\t\t.tv_sec = ts32->tv_sec, .tv_nsec = ts32->tv_nsec}));\n}\n"
  },
  {
    "path": "user.libc/compat/time32/semtimedop_time32.c",
    "content": "#include \"time32.h\"\n#define _GNU_SOURCE\n#include <sys/sem.h>\n#include <time.h>\n\nint __semtimedop_time32(int id, struct sembuf *buf, size_t n, const struct timespec32 *ts32)\n{\n\treturn semtimedop(id, buf, n, !ts32 ? 0 : (&(struct timespec){\n\t\t.tv_sec = ts32->tv_sec, .tv_nsec = ts32->tv_nsec}));\n}\n"
  },
  {
    "path": "user.libc/compat/time32/setitimer_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <sys/time.h>\n\nint __setitimer_time32(int which, const struct itimerval32 *restrict new32, struct itimerval32 *restrict old32)\n{\n\tstruct itimerval old;\n\tint r = setitimer(which, (&(struct itimerval){\n\t\t.it_interval.tv_sec = new32->it_interval.tv_sec,\n\t\t.it_interval.tv_usec = new32->it_interval.tv_usec,\n\t\t.it_value.tv_sec = new32->it_value.tv_sec,\n\t\t.it_value.tv_usec = new32->it_value.tv_usec}), &old);\n\tif (r) return r;\n\t/* The above call has already committed to success by changing the\n\t * timer setting, so we can't fail on out-of-range old value.\n\t * Since these are relative times, values large enough to overflow\n\t * don't make sense anyway. */\n\tif (old32) {\n\t\told32->it_interval.tv_sec = old.it_interval.tv_sec;\n\t\told32->it_interval.tv_usec = old.it_interval.tv_usec;\n\t\told32->it_value.tv_sec = old.it_value.tv_sec;\n\t\told32->it_value.tv_usec = old.it_value.tv_usec;\n\t}\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/compat/time32/settimeofday_time32.c",
    "content": "#define _BSD_SOURCE\n#include \"time32.h\"\n#include <sys/time.h>\n\nint __settimeofday_time32(const struct timeval32 *tv32, const void *tz)\n{\n\treturn settimeofday(!tv32 ? 0 : (&(struct timeval){\n\t\t.tv_sec = tv32->tv_sec,\n\t\t.tv_usec = tv32->tv_usec}), 0);\n}\n"
  },
  {
    "path": "user.libc/compat/time32/sigtimedwait_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <signal.h>\n\nint __sigtimedwait_time32(const sigset_t *restrict set, siginfo_t *restrict si, const struct timespec32 *restrict ts32)\n{\n\treturn sigtimedwait(set, si, !ts32 ? 0 : (&(struct timespec){\n\t\t.tv_sec = ts32->tv_sec, .tv_nsec = ts32->tv_nsec}));\n}\n"
  },
  {
    "path": "user.libc/compat/time32/stat_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <string.h>\n#include <sys/stat.h>\n#include <stddef.h>\n\nstruct stat32;\n\nint __stat_time32(const char *restrict path, struct stat32 *restrict st32)\n{\n\tstruct stat st;\n\tint r = stat(path, &st);\n\tif (!r) memcpy(st32, &st, offsetof(struct stat, st_atim));\n\treturn r;\n}\n\nweak_alias(stat, stat64);\n"
  },
  {
    "path": "user.libc/compat/time32/stime32.c",
    "content": "#define _GNU_SOURCE\n#include \"time32.h\"\n#include <time.h>\n\nint __stime32(const time32_t *t)\n{\n\treturn stime(&(time_t){*t});\n}\n"
  },
  {
    "path": "user.libc/compat/time32/thrd_sleep_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <threads.h>\n#include <errno.h>\n\nint __thrd_sleep_time32(const struct timespec32 *req32, struct timespec32 *rem32)\n{\n\tstruct timespec rem;\n\tint ret = thrd_sleep((&(struct timespec){\n\t\t.tv_sec = req32->tv_sec, .tv_nsec = req32->tv_nsec}), &rem);\n\tif (ret<0 && errno==EINTR && rem32) {\n\t\trem32->tv_sec = rem.tv_sec;\n\t\trem32->tv_nsec = rem.tv_nsec;\n\t}\n\treturn ret;\n}\n"
  },
  {
    "path": "user.libc/compat/time32/time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <errno.h>\n#include <stdint.h>\n\ntime32_t __time32(time32_t *p)\n{\n\ttime_t t = time(0);\n\tif (t < INT32_MIN || t > INT32_MAX) {\n\t\terrno = EOVERFLOW;\n\t\treturn -1;\n\t}\n\tif (p) *p = t;\n\treturn t;\n}\n"
  },
  {
    "path": "user.libc/compat/time32/time32.h",
    "content": "#ifndef TIME32_H\n#define TIME32_H\n\n#include <sys/types.h>\n\ntypedef long time32_t;\n\nstruct timeval32 {\n\tlong tv_sec;\n\tlong tv_usec;\n};\n\nstruct itimerval32 {\n\tstruct timeval32 it_interval;\n\tstruct timeval32 it_value;\n};\n\nstruct timespec32 {\n\tlong tv_sec;\n\tlong tv_nsec;\n};\n\nstruct itimerspec32 {\n\tstruct timespec32 it_interval;\n\tstruct timespec32 it_value;\n};\n\nint __adjtime32() __asm__(\"adjtime\");\nint __adjtimex_time32() __asm__(\"adjtimex\");\nint __aio_suspend_time32() __asm__(\"aio_suspend\");\nint __clock_adjtime32() __asm__(\"clock_adjtime\");\nint __clock_getres_time32() __asm__(\"clock_getres\");\nint __clock_gettime32() __asm__(\"clock_gettime\");\nint __clock_nanosleep_time32() __asm__(\"clock_nanosleep\");\nint __clock_settime32() __asm__(\"clock_settime\");\nint __cnd_timedwait_time32() __asm__(\"cnd_timedwait\");\nchar *__ctime32() __asm__(\"ctime\");\nchar *__ctime32_r() __asm__(\"ctime_r\");\ndouble __difftime32() __asm__(\"difftime\");\nint __fstat_time32() __asm__(\"fstat\");\nint __fstatat_time32() __asm__(\"fstatat\");\nint __ftime32() __asm__(\"ftime\");\nint __futimens_time32() __asm__(\"futimens\");\nint __futimes_time32() __asm__(\"futimes\");\nint __futimesat_time32() __asm__(\"futimesat\");\nint __getitimer_time32() __asm__(\"getitimer\");\nint __getrusage_time32() __asm__(\"getrusage\");\nint __gettimeofday_time32() __asm__(\"gettimeofday\");\nstruct tm *__gmtime32() __asm__(\"gmtime\");\nstruct tm *__gmtime32_r() __asm__(\"gmtime_r\");\nstruct tm *__localtime32() __asm__(\"localtime\");\nstruct tm *__localtime32_r() __asm__(\"localtime_r\");\nint __lstat_time32() __asm__(\"lstat\");\nint __lutimes_time32() __asm__(\"lutimes\");\ntime32_t __mktime32() __asm__(\"mktime\");\nssize_t __mq_timedreceive_time32() __asm__(\"mq_timedreceive\");\nint __mq_timedsend_time32() __asm__(\"mq_timedsend\");\nint __mtx_timedlock_time32() __asm__(\"mtx_timedlock\");\nint __nanosleep_time32() __asm__(\"nanosleep\");\nint __ppoll_time32() __asm__(\"ppoll\");\nint __pselect_time32() __asm__(\"pselect\");\nint __pthread_cond_timedwait_time32() __asm__(\"pthread_cond_timedwait\");\nint __pthread_mutex_timedlock_time32() __asm__(\"pthread_mutex_timedlock\");\nint __pthread_rwlock_timedrdlock_time32() __asm__(\"pthread_rwlock_timedrdlock\");\nint __pthread_rwlock_timedwrlock_time32() __asm__(\"pthread_rwlock_timedwrlock\");\nint __pthread_timedjoin_np_time32() __asm__(\"pthread_timedjoin_np\");\nint __recvmmsg_time32() __asm__(\"recvmmsg\");\nint __sched_rr_get_interval_time32() __asm__(\"sched_rr_get_interval\");\nint __select_time32() __asm__(\"select\");\nint __sem_timedwait_time32() __asm__(\"sem_timedwait\");\nint __semtimedop_time32() __asm__(\"semtimedop\");\nint __setitimer_time32() __asm__(\"setitimer\");\nint __settimeofday_time32() __asm__(\"settimeofday\");\nint __sigtimedwait_time32() __asm__(\"sigtimedwait\");\nint __stat_time32() __asm__(\"stat\");\nint __stime32() __asm__(\"stime\");\nint __thrd_sleep_time32() __asm__(\"thrd_sleep\");\ntime32_t __time32() __asm__(\"time\");\ntime32_t __time32gm() __asm__(\"timegm\");\nint __timer_gettime32() __asm__(\"timer_gettime\");\nint __timer_settime32() __asm__(\"timer_settime\");\nint __timerfd_gettime32() __asm__(\"timerfd_gettime\");\nint __timerfd_settime32() __asm__(\"timerfd_settime\");\nint __timespec_get_time32() __asm__(\"timespec_get\");\nint __utime_time32() __asm__(\"utime\");\nint __utimensat_time32() __asm__(\"utimensat\");\nint __utimes_time32() __asm__(\"utimes\");\npid_t __wait3_time32() __asm__(\"wait3\");\npid_t __wait4_time32() __asm__(\"wait4\");\n\n#endif\n"
  },
  {
    "path": "user.libc/compat/time32/time32gm.c",
    "content": "#define _GNU_SOURCE\n#include \"time32.h\"\n#include <time.h>\n#include <errno.h>\n#include <stdint.h>\n\ntime32_t __time32gm(struct tm *tm)\n{\n\ttime_t t = timegm(tm);\n\tif (t < INT32_MIN || t > INT32_MAX) {\n\t\terrno = EOVERFLOW;\n\t\treturn -1;\n\t}\n\treturn t;\n}\n"
  },
  {
    "path": "user.libc/compat/time32/timer_gettime32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n\nint __timer_gettime32(timer_t t, struct itimerspec32 *val32)\n{\n\tstruct itimerspec old;\n\tint r = timer_gettime(t, &old);\n\tif (r) return r;\n\t/* No range checking for consistency with settime */\n\tval32->it_interval.tv_sec = old.it_interval.tv_sec;\n\tval32->it_interval.tv_nsec = old.it_interval.tv_nsec;\n\tval32->it_value.tv_sec = old.it_value.tv_sec;\n\tval32->it_value.tv_nsec = old.it_value.tv_nsec;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/compat/time32/timer_settime32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n\nint __timer_settime32(timer_t t, int flags, const struct itimerspec32 *restrict val32, struct itimerspec32 *restrict old32)\n{\n\tstruct itimerspec old;\n\tint r = timer_settime(t, flags, (&(struct itimerspec){\n\t\t.it_interval.tv_sec = val32->it_interval.tv_sec,\n\t\t.it_interval.tv_nsec = val32->it_interval.tv_nsec,\n\t\t.it_value.tv_sec = val32->it_value.tv_sec,\n\t\t.it_value.tv_nsec = val32->it_value.tv_nsec}),\n\t\told32 ? &old : 0);\n\tif (r) return r;\n\t/* The above call has already committed to success by changing the\n\t * timer setting, so we can't fail on out-of-range old value.\n\t * Since these are relative times, values large enough to overflow\n\t * don't make sense anyway. */\n\tif (old32) {\n\t\told32->it_interval.tv_sec = old.it_interval.tv_sec;\n\t\told32->it_interval.tv_nsec = old.it_interval.tv_nsec;\n\t\told32->it_value.tv_sec = old.it_value.tv_sec;\n\t\told32->it_value.tv_nsec = old.it_value.tv_nsec;\n\t}\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/compat/time32/timerfd_gettime32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <sys/timerfd.h>\n\nint __timerfd_gettime32(int t, struct itimerspec32 *val32)\n{\n\tstruct itimerspec old;\n\tint r = timerfd_gettime(t, &old);\n\tif (r) return r;\n\t/* No range checking for consistency with settime */\n\tval32->it_interval.tv_sec = old.it_interval.tv_sec;\n\tval32->it_interval.tv_nsec = old.it_interval.tv_nsec;\n\tval32->it_value.tv_sec = old.it_value.tv_sec;\n\tval32->it_value.tv_nsec = old.it_value.tv_nsec;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/compat/time32/timerfd_settime32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <sys/timerfd.h>\n\nint __timerfd_settime32(int t, int flags, const struct itimerspec32 *restrict val32, struct itimerspec32 *restrict old32)\n{\n\tstruct itimerspec old;\n\tint r = timerfd_settime(t, flags, (&(struct itimerspec){\n\t\t.it_interval.tv_sec = val32->it_interval.tv_sec,\n\t\t.it_interval.tv_nsec = val32->it_interval.tv_nsec,\n\t\t.it_value.tv_sec = val32->it_value.tv_sec,\n\t\t.it_value.tv_nsec = val32->it_value.tv_nsec}),\n\t\told32 ? &old : 0);\n\tif (r) return r;\n\t/* The above call has already committed to success by changing the\n\t * timer setting, so we can't fail on out-of-range old value.\n\t * Since these are relative times, values large enough to overflow\n\t * don't make sense anyway. */\n\tif (old32) {\n\t\told32->it_interval.tv_sec = old.it_interval.tv_sec;\n\t\told32->it_interval.tv_nsec = old.it_interval.tv_nsec;\n\t\told32->it_value.tv_sec = old.it_value.tv_sec;\n\t\told32->it_value.tv_nsec = old.it_value.tv_nsec;\n\t}\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/compat/time32/timespec_get_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <errno.h>\n#include <stdint.h>\n\nint __timespec_get_time32(struct timespec32 *ts32, int base)\n{\n\tstruct timespec ts;\n\tint r = timespec_get(&ts, base);\n\tif (!r) return r;\n\tif (ts.tv_sec < INT32_MIN || ts.tv_sec > INT32_MAX) {\n\t\terrno = EOVERFLOW;\n\t\treturn 0;\n\t}\n\tts32->tv_sec = ts.tv_sec;\n\tts32->tv_nsec = ts.tv_nsec;\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/compat/time32/utime_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <utime.h>\n\nstruct utimbuf32 {\n\ttime32_t actime;\n\ttime32_t modtime;\n};\n\nint __utime_time32(const char *path, const struct utimbuf32 *times32)\n{\n\treturn utime(path, !times32 ? 0 : (&(struct utimbuf){\n\t\t.actime = times32->actime, .modtime = times32->modtime}));\n}\n"
  },
  {
    "path": "user.libc/compat/time32/utimensat_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <sys/stat.h>\n\nint __utimensat_time32(int fd, const char *path, const struct timespec32 times32[2], int flags)\n{\n\treturn utimensat(fd, path, !times32 ? 0 : ((struct timespec[2]){\n\t\t{.tv_sec = times32[0].tv_sec,.tv_nsec = times32[0].tv_nsec},\n\t\t{.tv_sec = times32[1].tv_sec,.tv_nsec = times32[1].tv_nsec}}),\n\t\tflags);\n}\n"
  },
  {
    "path": "user.libc/compat/time32/utimes_time32.c",
    "content": "#include \"time32.h\"\n#include <time.h>\n#include <sys/time.h>\n#include <sys/stat.h>\n\nint __utimes_time32(const char *path, const struct timeval32 times32[2])\n{\n\treturn utimes(path, !times32 ? 0 : ((struct timeval[2]){\n\t\t{.tv_sec = times32[0].tv_sec,.tv_usec = times32[0].tv_usec},\n\t\t{.tv_sec = times32[1].tv_sec,.tv_usec = times32[1].tv_usec}}));\n}\n"
  },
  {
    "path": "user.libc/compat/time32/wait3_time32.c",
    "content": "#define _BSD_SOURCE\n#include \"time32.h\"\n#include <string.h>\n#include <stddef.h>\n#include <sys/wait.h>\n\nstruct compat_rusage {\n\tstruct timeval32 ru_utime;\n\tstruct timeval32 ru_stime;\n\tlong\tru_maxrss;\n\tlong\tru_ixrss;\n\tlong\tru_idrss;\n\tlong\tru_isrss;\n\tlong\tru_minflt;\n\tlong\tru_majflt;\n\tlong\tru_nswap;\n\tlong\tru_inblock;\n\tlong\tru_oublock;\n\tlong\tru_msgsnd;\n\tlong\tru_msgrcv;\n\tlong\tru_nsignals;\n\tlong\tru_nvcsw;\n\tlong\tru_nivcsw;\n};\n\npid_t __wait3_time32(int *status, int options, struct compat_rusage *usage)\n{\n\tstruct rusage ru;\n\tint r = wait3(status, options, usage ? &ru : 0);\n\tif (!r && usage) {\n\t\tusage->ru_utime.tv_sec = ru.ru_utime.tv_sec;\n\t\tusage->ru_utime.tv_usec = ru.ru_utime.tv_usec;\n\t\tusage->ru_stime.tv_sec = ru.ru_stime.tv_sec;\n\t\tusage->ru_stime.tv_usec = ru.ru_stime.tv_usec;\n\t\tmemcpy(&usage->ru_maxrss, &ru.ru_maxrss,\n\t\t\tsizeof(struct compat_rusage) -\n\t\t\toffsetof(struct compat_rusage, ru_maxrss));\n\t}\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/compat/time32/wait4_time32.c",
    "content": "#define _BSD_SOURCE\n#include \"time32.h\"\n#include <string.h>\n#include <stddef.h>\n#include <sys/wait.h>\n\nstruct compat_rusage {\n\tstruct timeval32 ru_utime;\n\tstruct timeval32 ru_stime;\n\tlong\tru_maxrss;\n\tlong\tru_ixrss;\n\tlong\tru_idrss;\n\tlong\tru_isrss;\n\tlong\tru_minflt;\n\tlong\tru_majflt;\n\tlong\tru_nswap;\n\tlong\tru_inblock;\n\tlong\tru_oublock;\n\tlong\tru_msgsnd;\n\tlong\tru_msgrcv;\n\tlong\tru_nsignals;\n\tlong\tru_nvcsw;\n\tlong\tru_nivcsw;\n};\n\npid_t __wait4_time32(pid_t pid, int *status, int options, struct compat_rusage *usage)\n{\n\tstruct rusage ru;\n\tint r = wait4(pid, status, options, usage ? &ru : 0);\n\tif (!r && usage) {\n\t\tusage->ru_utime.tv_sec = ru.ru_utime.tv_sec;\n\t\tusage->ru_utime.tv_usec = ru.ru_utime.tv_usec;\n\t\tusage->ru_stime.tv_sec = ru.ru_stime.tv_sec;\n\t\tusage->ru_stime.tv_usec = ru.ru_stime.tv_usec;\n\t\tmemcpy(&usage->ru_maxrss, &ru.ru_maxrss,\n\t\t\tsizeof(struct compat_rusage) -\n\t\t\toffsetof(struct compat_rusage, ru_maxrss));\n\t}\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/configure",
    "content": "#!/bin/sh\n\nusage () {\ncat <<EOF\nUsage: $0 [OPTION]... [VAR=VALUE]... [TARGET]\n\nTo assign environment variables (e.g., CC, CFLAGS...), specify them as\nVAR=VALUE.  See below for descriptions of some of the useful variables.\n\nDefaults for the options are specified in brackets.\n\nConfiguration:\n  --srcdir=DIR            source directory [detected]\n\nInstallation directories:\n  --prefix=PREFIX         main installation prefix [/usr/local/musl]\n  --exec-prefix=EPREFIX   installation prefix for executable files [PREFIX]\n\nFine tuning of the installation directories:\n  --bindir=DIR            user executables [EPREFIX/bin]\n  --libdir=DIR            library files for the linker [PREFIX/lib]\n  --includedir=DIR        include files for the C compiler [PREFIX/include]\n  --syslibdir=DIR         location for the dynamic linker [/lib]\n\nSystem types:\n  --target=TARGET         configure to run on target TARGET [detected]\n  --host=HOST             same as --target\n  --build=BUILD           build system type; used only to infer cross-compiling\n\nOptional features:\n  --enable-optimize=...   optimize listed components for speed over size [auto]\n  --enable-debug          build with debugging information [disabled]\n  --disable-warnings      build with recommended warnings flags [enabled]\n  --enable-wrapper=...    build given musl toolchain wrapper [auto]\n  --disable-shared        inhibit building shared library [enabled]\n  --disable-static        inhibit building static library [enabled]\n\nOptional packages:\n  --with-malloc=...       choose malloc implementation [mallocng]\n\nSome influential environment variables:\n  CC                      C compiler command [detected]\n  CFLAGS                  C compiler flags [-Os -pipe ...]\n  CROSS_COMPILE           prefix for cross compiler and tools [none]\n  LIBCC                   compiler runtime library [detected]\n\nUse these variables to override the choices made by configure.\n\nEOF\nexit 0\n}\n\n# Helper functions\n\nquote () {\ntr '\\n' ' ' <<EOF | grep '^[-[:alnum:]_=,./:]* $' >/dev/null 2>&1 && { echo \"$1\" ; return 0 ; }\n$1\nEOF\nprintf %s\\\\n \"$1\" | sed -e \"s/'/'\\\\\\\\''/g\" -e \"1s/^/'/\" -e \"\\$s/\\$/'/\" -e \"s#^'\\([-[:alnum:]_,./:]*\\)=\\(.*\\)\\$#\\1='\\2#\"\n}\necho () { printf \"%s\\n\" \"$*\" ; }\nfail () { echo \"$*\" ; exit 1 ; }\nfnmatch () { eval \"case \\\"\\$2\\\" in $1) return 0 ;; *) return 1 ;; esac\" ; }\ncmdexists () { type \"$1\" >/dev/null 2>&1 ; }\ntrycc () { test -z \"$CC\" && cmdexists \"$1\" && CC=$1 ; }\n\nstripdir () {\nwhile eval \"fnmatch '*/' \\\"\\${$1}\\\"\" ; do eval \"$1=\\${$1%/}\" ; done\n}\n\ntrycppif () {\nprintf \"checking preprocessor condition %s... \" \"$1\"\necho \"typedef int x;\" > \"$tmpc\"\necho \"#if $1\" >> \"$tmpc\"\necho \"#error yes\" >> \"$tmpc\"\necho \"#endif\" >> \"$tmpc\"\nif $CC $2 -c -o /dev/null \"$tmpc\" >/dev/null 2>&1 ; then\nprintf \"false\\n\"\nreturn 1\nelse\nprintf \"true\\n\"\nreturn 0\nfi\n}\n\ntryflag () {\nprintf \"checking whether compiler accepts %s... \" \"$2\"\necho \"typedef int x;\" > \"$tmpc\"\nif $CC $CFLAGS_TRY $2 -c -o /dev/null \"$tmpc\" >/dev/null 2>&1 ; then\nprintf \"yes\\n\"\neval \"$1=\\\"\\${$1} \\$2\\\"\"\neval \"$1=\\${$1# }\"\nreturn 0\nelse\nprintf \"no\\n\"\nreturn 1\nfi\n}\n\ntryldflag () {\nprintf \"checking whether linker accepts %s... \" \"$2\"\necho \"typedef int x;\" > \"$tmpc\"\nif $CC $LDFLAGS_TRY -nostdlib -shared \"$2\" -o /dev/null \"$tmpc\" >/dev/null 2>&1 ; then\nprintf \"yes\\n\"\neval \"$1=\\\"\\${$1} \\$2\\\"\"\neval \"$1=\\${$1# }\"\nreturn 0\nelse\nprintf \"no\\n\"\nreturn 1\nfi\n}\n\n\n\n# Beginning of actual script\n\nCFLAGS_C99FSE=\nCFLAGS_AUTO=\nCFLAGS_MEMOPS=\nCFLAGS_NOSSP=\nCFLAGS_TRY=\nLDFLAGS_AUTO=\nLDFLAGS_TRY=\nOPTIMIZE_GLOBS=\nsrcdir=\nprefix=/usr/local/musl\nexec_prefix='$(prefix)'\nbindir='$(exec_prefix)/bin'\nlibdir='$(prefix)/lib'\nincludedir='$(prefix)/include'\nsyslibdir='/lib'\ntools=\ntool_libs=\nbuild=\ntarget=\noptimize=auto\ndebug=no\nwarnings=yes\nshared=auto\nstatic=yes\nwrapper=auto\ngcc_wrapper=no\nclang_wrapper=no\nmalloc_dir=mallocng\n\nfor arg ; do\ncase \"$arg\" in\n--help|-h) usage ;;\n--srcdir=*) srcdir=${arg#*=} ;;\n--prefix=*) prefix=${arg#*=} ;;\n--exec-prefix=*) exec_prefix=${arg#*=} ;;\n--bindir=*) bindir=${arg#*=} ;;\n--libdir=*) libdir=${arg#*=} ;;\n--includedir=*) includedir=${arg#*=} ;;\n--syslibdir=*) syslibdir=${arg#*=} ;;\n--enable-shared|--enable-shared=yes) shared=yes ;;\n--disable-shared|--enable-shared=no) shared=no ;;\n--enable-static|--enable-static=yes) static=yes ;;\n--disable-static|--enable-static=no) static=no ;;\n--enable-optimize) optimize=yes ;;\n--enable-optimize=*) optimize=${arg#*=} ;;\n--disable-optimize) optimize=no ;;\n--enable-debug|--enable-debug=yes) debug=yes ;;\n--disable-debug|--enable-debug=no) debug=no ;;\n--enable-warnings|--enable-warnings=yes) warnings=yes ;;\n--disable-warnings|--enable-warnings=no) warnings=no ;;\n--enable-wrapper|--enable-wrapper=yes) wrapper=detect ;;\n--enable-wrapper=all) wrapper=yes ; gcc_wrapper=yes ; clang_wrapper=yes ;;\n--enable-wrapper=gcc) wrapper=yes ; gcc_wrapper=yes ;;\n--enable-wrapper=clang) wrapper=yes ; clang_wrapper=yes ;;\n--disable-wrapper|--enable-wrapper=no) wrapper=no ;;\n--enable-gcc-wrapper|--enable-gcc-wrapper=yes) wrapper=yes ; gcc_wrapper=yes ;;\n--disable-gcc-wrapper|--enable-gcc-wrapper=no) wrapper=no ;;\n--with-malloc=*) malloc_dir=${arg#*=} ;;\n--enable-*|--disable-*|--with-*|--without-*|--*dir=*) ;;\n--host=*|--target=*) target=${arg#*=} ;;\n--build=*) build=${arg#*=} ;;\n-* ) echo \"$0: unknown option $arg\" ;;\nAR=*) AR=${arg#*=} ;;\nRANLIB=*) RANLIB=${arg#*=} ;;\nCC=*) CC=${arg#*=} ;;\nCFLAGS=*) CFLAGS=${arg#*=} ;;\nCPPFLAGS=*) CPPFLAGS=${arg#*=} ;;\nLDFLAGS=*) LDFLAGS=${arg#*=} ;;\nCROSS_COMPILE=*) CROSS_COMPILE=${arg#*=} ;;\nLIBCC=*) LIBCC=${arg#*=} ;;\n*=*) ;;\n*) build=$arg ; target=$arg ;;\nesac\ndone\n\nfor i in srcdir prefix exec_prefix bindir libdir includedir syslibdir ; do\nstripdir $i\ndone\n\n#\n# Get the source dir for out-of-tree builds\n#\nif test -z \"$srcdir\" ; then\nsrcdir=\"${0%/configure}\"\nstripdir srcdir\nfi\nabs_builddir=\"$(pwd)\" || fail \"$0: cannot determine working directory\"\nabs_srcdir=\"$(cd $srcdir && pwd)\" || fail \"$0: invalid source directory $srcdir\"\ntest \"$abs_srcdir\" = \"$abs_builddir\" && srcdir=.\ntest \"$srcdir\" != \".\" && test -f Makefile && test ! -h Makefile && fail \"$0: Makefile already exists in the working directory\"\n\n#\n# Get a temp filename we can use\n#\ni=0\nset -C\nwhile : ; do i=$(($i+1))\ntmpc=\"./conf$$-$PPID-$i.c\"\n2>|/dev/null > \"$tmpc\" && break\ntest \"$i\" -gt 50 && fail \"$0: cannot create temporary file $tmpc\"\ndone\nset +C\ntrap 'rm \"$tmpc\"' EXIT INT QUIT TERM HUP\n\n#\n# Check that the requested malloc implementation exists\n#\ntest -d \"$srcdir/src/malloc/$malloc_dir\" \\\n|| fail \"$0: error: chosen malloc implementation '$malloc_dir' does not exist\"\n\n#\n# Check whether we are cross-compiling, and set a default\n# CROSS_COMPILE prefix if none was provided.\n#\ntest \"$target\" && \\\ntest \"$target\" != \"$build\" && \\\ntest -z \"$CROSS_COMPILE\" && \\\nCROSS_COMPILE=\"$target-\"\n\n#\n# Find a C compiler to use\n#\nprintf \"checking for C compiler... \"\ntrycc ${CROSS_COMPILE}gcc\ntrycc ${CROSS_COMPILE}c99\ntrycc ${CROSS_COMPILE}cc\nprintf \"%s\\n\" \"$CC\"\ntest -n \"$CC\" || { echo \"$0: cannot find a C compiler\" ; exit 1 ; }\n\nprintf \"checking whether C compiler works... \"\necho \"typedef int x;\" > \"$tmpc\"\nif output=$($CC $CPPFLAGS $CFLAGS -c -o /dev/null \"$tmpc\" 2>&1) ; then\nprintf \"yes\\n\"\nelse\nprintf \"no; compiler output follows:\\n%s\\n\" \"$output\"\nexit 1\nfi\n\n#\n# Figure out options to force errors on unknown flags.\n#\ntryflag   CFLAGS_TRY  -Werror=unknown-warning-option\ntryflag   CFLAGS_TRY  -Werror=unused-command-line-argument\ntryflag   CFLAGS_TRY  -Werror=ignored-optimization-argument\ntryldflag LDFLAGS_TRY -Werror=unknown-warning-option\ntryldflag LDFLAGS_TRY -Werror=unused-command-line-argument\n\n#\n# Need to know if the compiler is gcc or clang to decide which toolchain\n# wrappers to build.\n#\nprintf \"checking for C compiler family... \"\ncc_ver=\"$(LC_ALL=C $CC -v 2>&1)\"\ncc_family=unknown\nif fnmatch '*gcc\\ version*' \"$cc_ver\" ; then\ncc_family=gcc\nelif fnmatch '*clang\\ version*' \"$cc_ver\" ; then\ncc_family=clang\nfi\necho \"$cc_family\"\n\n#\n# Figure out toolchain wrapper to build\n#\nif test \"$wrapper\" = auto || test \"$wrapper\" = detect ; then\necho \"#include <stdlib.h>\" > \"$tmpc\"\necho \"#if ! __GLIBC__\" >> \"$tmpc\"\necho \"#error no\" >> \"$tmpc\"\necho \"#endif\" >> \"$tmpc\"\nprintf \"checking for toolchain wrapper to build... \"\nif test \"$wrapper\" = auto && ! $CC -c -o /dev/null \"$tmpc\" >/dev/null 2>&1 ; then\necho \"none\"\nelif test \"$cc_family\" = gcc ; then\ngcc_wrapper=yes\necho \"gcc\"\nelif test \"$cc_family\" = clang ; then\nclang_wrapper=yes\necho \"clang\"\nelse\necho \"none\"\nif test \"$wrapper\" = detect ; then\nfail \"$0: could not find an appropriate toolchain wrapper\"\nfi\nfi\nfi\n\nif test \"$gcc_wrapper\" = yes ; then\ntools=\"$tools obj/musl-gcc\"\ntool_libs=\"$tool_libs lib/musl-gcc.specs\"\nfi\nif test \"$clang_wrapper\" = yes ; then\ntools=\"$tools obj/musl-clang obj/ld.musl-clang\"\nfi\n\n#\n# Find the target architecture\n#\nprintf \"checking target system type... \"\ntest -n \"$target\" || target=$($CC -dumpmachine 2>/dev/null) || target=unknown\nprintf \"%s\\n\" \"$target\"\n\n#\n# Convert to just ARCH\n#\ncase \"$target\" in\n# Catch these early to simplify matching for 32-bit archs\narm*) ARCH=arm ;;\naarch64*) ARCH=aarch64 ;;\ni?86-nt32*) ARCH=nt32 ;;\ni?86*) ARCH=i386 ;;\nx86_64-x32*|x32*|x86_64*x32) ARCH=x32 ;;\nx86_64-nt64*) ARCH=nt64 ;;\nx86_64*) ARCH=x86_64 ;;\nm68k*) ARCH=m68k ;;\nmips64*|mipsisa64*) ARCH=mips64 ;;\nmips*) ARCH=mips ;;\nmicroblaze*) ARCH=microblaze ;;\nor1k*) ARCH=or1k ;;\npowerpc64*|ppc64*) ARCH=powerpc64 ;;\npowerpc*|ppc*) ARCH=powerpc ;;\nriscv64*) ARCH=riscv64 ;;\nsh[1-9bel-]*|sh|superh*) ARCH=sh ;;\ns390x*) ARCH=s390x ;;\nunknown) fail \"$0: unable to detect target arch; try $0 --target=...\" ;;\n*) fail \"$0: unknown or unsupported target \\\"$target\\\"\" ;;\nesac\n\n#\n# Try to get a conforming C99 freestanding environment\n#\ntryflag CFLAGS_C99FSE -std=c99\ntryflag CFLAGS_C99FSE -nostdinc\ntryflag CFLAGS_C99FSE -ffreestanding \\\n|| tryflag CFLAGS_C99FSE -fno-builtin\ntryflag CFLAGS_C99FSE -fexcess-precision=standard \\\n|| { test \"$ARCH\" = i386 && tryflag CFLAGS_C99FSE -ffloat-store ; }\ntryflag CFLAGS_C99FSE -frounding-math\n\n#\n# We may use the may_alias attribute if __GNUC__ is defined, so\n# if the compiler defines __GNUC__ but does not provide it,\n# it must be defined away as part of the CFLAGS.\n#\nprintf \"checking whether compiler needs attribute((may_alias)) suppression... \"\ncat > \"$tmpc\" <<EOF\ntypedef int\n#ifdef __GNUC__\n__attribute__((__may_alias__))\n#endif\nx;\nEOF\nif $CC $CFLAGS_C99FSE $CPPFLAGS $CFLAGS \\\n  -c -o /dev/null \"$tmpc\" >/dev/null 2>&1 ; then\nprintf \"no\\n\"\nelse\nprintf \"yes\\n\"\nCFLAGS_C99FSE=\"$CFLAGS_C99FSE -D__may_alias__=\"\nfi\n\n#\n# The GNU toolchain defaults to assuming unmarked files need an\n# executable stack, potentially exposing vulnerabilities in programs\n# linked with such object files. Fix this.\n#\ntryflag CFLAGS_C99FSE -Wa,--noexecstack\n\n#\n# Check for options to disable stack protector, which needs to be\n# disabled for a few early-bootstrap translation units. If not found,\n# this is not an error; we assume the toolchain does not do ssp.\n#\ntryflag CFLAGS_NOSSP -fno-stack-protector\n\n#\n# Check for options that may be needed to prevent the compiler from\n# generating self-referential versions of memcpy,, memmove, memcmp,\n# and memset. Really, we should add a check to determine if this\n# option is sufficient, and if not, add a macro to cripple these\n# functions with volatile...\n#\ntryflag CFLAGS_MEMOPS -fno-tree-loop-distribute-patterns\n\n#\n# Enable debugging if requessted.\n#\ntest \"$debug\" = yes && CFLAGS_AUTO=-g\n\n#\n# Preprocess asm files to add extra debugging information if debug is\n# enabled, our assembler supports the needed directives, and the\n# preprocessing script has been written for our architecture.\n#\nprintf \"checking whether we should preprocess assembly to add debugging information... \"\nif fnmatch '-g*|*\\ -g*' \"$CFLAGS_AUTO $CFLAGS\" &&\n   test -f \"tools/add-cfi.$ARCH.awk\" &&\n   printf \".file 1 \\\"srcfile.s\\\"\\n.line 1\\n.cfi_startproc\\n.cfi_endproc\" | $CC -g -x assembler -c -o /dev/null 2>/dev/null -\nthen\n  ADD_CFI=yes\nelse\n  ADD_CFI=no\nfi\nprintf \"%s\\n\" \"$ADD_CFI\"\n\n#\n# Possibly add a -O option to CFLAGS and select modules to optimize with\n# -O3 based on the status of --enable-optimize and provided CFLAGS.\n#\nprintf \"checking for optimization settings... \"\ncase \"x$optimize\" in\nxauto)\nif fnmatch '-O*|*\\ -O*' \"$CFLAGS_AUTO $CFLAGS\" ; then\nprintf \"using provided CFLAGS\\n\" ;optimize=no\nelse\nprintf \"using defaults\\n\" ; optimize=yes\nfi\n;;\nxsize|xnone) printf \"minimize size\\n\" ; optimize=size ;;\nxno|x) printf \"disabled\\n\" ; optimize=no ;;\n*) printf \"custom\\n\" ;;\nesac\n\n# test \"$optimize\" = no || tryflag CFLAGS_AUTO -Os || tryflag CFLAGS_AUTO -O2\n# test \"$optimize\" = yes && optimize=\"internal,malloc,string\"\n\nif fnmatch 'no|size' \"$optimize\" ; then :\nelse\nprintf \"components to be optimized for speed:\"\nwhile test \"$optimize\" ; do\ncase \"$optimize\" in\n*,*) this=${optimize%%,*} optimize=${optimize#*,} ;;\n*) this=$optimize optimize=\nesac\nprintf \" $this\"\ncase \"$this\" in\n*/*.c) ;;\n*/*) this=$this*.c ;;\n*) this=$this/*.c ;;\nesac\nOPTIMIZE_GLOBS=\"$OPTIMIZE_GLOBS $this\"\ndone\nOPTIMIZE_GLOBS=${OPTIMIZE_GLOBS# }\nprintf \"\\n\"\nfi\n\n# Always try -pipe\ntryflag CFLAGS_AUTO -pipe\n\n#\n# If debugging is disabled, omit frame pointer. Modern GCC does this\n# anyway on most archs even when debugging is enabled since the frame\n# pointer is no longer needed for debugging.\n#\nif fnmatch '-g*|*\\ -g*' \"$CFLAGS_AUTO $CFLAGS\" ; then :\nelse\ntryflag CFLAGS_AUTO -fomit-frame-pointer\nfi\n\n#\n# Modern GCC wants to put DWARF tables (used for debugging and\n# unwinding) in the loaded part of the program where they are\n# unstrippable. These options force them back to debug sections (and\n# cause them not to get generated at all if debugging is off).\n#\ntryflag CFLAGS_AUTO -fno-unwind-tables\ntryflag CFLAGS_AUTO -fno-asynchronous-unwind-tables\n\n#\n# Attempt to put each function and each data object in its own\n# section. This both allows additional size optimizations at link\n# time and works around a dangerous class of compiler/assembler bugs\n# whereby relative address expressions are constant-folded by the\n# assembler even when one or more of the symbols involved is\n# replaceable. See gas pr 18561 and gcc pr 66609, 68178, etc.\n#\ntryflag CFLAGS_AUTO -ffunction-sections\ntryflag CFLAGS_AUTO -fdata-sections\n\n#\n# On x86, make sure we don't have incompatible instruction set\n# extensions enabled by default. This is bad for making static binaries.\n# We cheat and use i486 rather than i386 because i386 really does not\n# work anyway (issues with atomic ops).\n# Some build environments pass -march and -mtune options via CC, so\n# check both CC and CFLAGS.\n#\nif test \"$ARCH\" = \"i386\" ; then\nfnmatch '-march=*|*\\ -march=*' \"$CC $CFLAGS\" || tryldflag CFLAGS_AUTO -march=i486\nfnmatch '-mtune=*|*\\ -mtune=*' \"$CC $CFLAGS\" || tryldflag CFLAGS_AUTO -mtune=generic\nfi\n\n#\n# GCC defines -w as overriding any -W options, regardless of order, but\n# clang has a bunch of annoying warnings enabled by default and needs -w\n# to start from a clean slate. So use -w if building with clang. Also\n# turn off a common on-by-default cast warning regardless of compiler.\n#\ntest \"$cc_family\" = clang && tryflag CFLAGS_AUTO -w\n\ntryflag CFLAGS_AUTO -Wno-pointer-to-int-cast\n\n#\n# Even with -std=c99, gcc accepts some constructs which are constraint\n# violations. We want to treat these as errors regardless of whether\n# other purely stylistic warnings are enabled -- especially implicit\n# function declarations, which are a dangerous programming error.\n#\ntryflag CFLAGS_AUTO -Werror=implicit-function-declaration\ntryflag CFLAGS_AUTO -Werror=implicit-int\ntryflag CFLAGS_AUTO -Werror=pointer-sign\ntryflag CFLAGS_AUTO -Werror=pointer-arith\ntryflag CFLAGS_AUTO -Werror=int-conversion\ntryflag CFLAGS_AUTO -Werror=incompatible-pointer-types\ntryflag CFLAGS_AUTO -Werror=discarded-qualifiers\ntryflag CFLAGS_AUTO -Werror=discarded-array-qualifiers\n\n#\n# GCC ignores unused arguements by default, but Clang needs this extra\n# parameter to stop printing warnings about LDFLAGS passed during\n# compiling stage and CFLAGS passed during linking stage.\n#\ntest \"$cc_family\" = clang && tryflag CFLAGS_AUTO -Qunused-arguments\n\nif test \"x$warnings\" = xyes ; then\ntryflag CFLAGS_AUTO -Waddress\ntryflag CFLAGS_AUTO -Warray-bounds\ntryflag CFLAGS_AUTO -Wchar-subscripts\ntryflag CFLAGS_AUTO -Wduplicate-decl-specifier\ntryflag CFLAGS_AUTO -Winit-self\ntryflag CFLAGS_AUTO -Wreturn-type\ntryflag CFLAGS_AUTO -Wsequence-point\ntryflag CFLAGS_AUTO -Wstrict-aliasing\ntryflag CFLAGS_AUTO -Wunused-function\ntryflag CFLAGS_AUTO -Wunused-label\ntryflag CFLAGS_AUTO -Wunused-variable\nfi\n\n# Determine if the compiler produces position-independent code (PIC)\n# by default. If so, we don't need to compile separate object files\n# for libc.a and libc.so.\nif trycppif __PIC__ \"$CFLAGS_C99FSE $CPPFLAGS $CFLAGS\" ; then\npic_default=yes\nelse\npic_default=no\nfi\n\n# Reduce space lost to padding for alignment purposes by sorting data\n# objects according to their alignment reqirements. This approximates\n# optimal packing.\ntryldflag LDFLAGS_AUTO -Wl,--sort-section,alignment\ntryldflag LDFLAGS_AUTO -Wl,--sort-common\n\n# When linking shared library, drop dummy weak definitions that were\n# replaced by strong definitions from other translation units.\ntryldflag LDFLAGS_AUTO -Wl,--gc-sections\n\n# Some patched GCC builds have these defaults messed up...\ntryldflag LDFLAGS_AUTO -Wl,--hash-style=both\n\n# Prevent linking if there are undefined symbols; if any exist,\n# libc.so will crash at runtime during relocation processing.\n# The common way this can happen is failure to link the compiler\n# runtime library; implementation error is also a possibility.\ntryldflag LDFLAGS_AUTO -Wl,--no-undefined\n\n# Avoid exporting symbols from compiler runtime libraries. They\n# should be hidden anyway, but some toolchains including old gcc\n# versions built without shared library support and pcc are broken.\ntryldflag LDFLAGS_AUTO -Wl,--exclude-libs=ALL\n\n# Public data symbols must be interposable to allow for copy\n# relocations, but otherwise we want to bind symbols at libc link\n# time to eliminate startup relocations and PLT overhead. Use\n# --dynamic-list rather than -Bsymbolic-functions for greater\n# control over what symbols are left unbound.\ntryldflag LDFLAGS_AUTO -Wl,--dynamic-list=\"$srcdir/dynamic.list\"\n\n# Find compiler runtime library\ntest -z \"$LIBCC\" && tryldflag LIBCC -lgcc && tryldflag LIBCC -lgcc_eh\ntest -z \"$LIBCC\" && tryldflag LIBCC -lcompiler_rt\ntest -z \"$LIBCC\" && try_libcc=`$CC -print-libgcc-file-name 2>/dev/null` \\\n                 && tryldflag LIBCC \"$try_libcc\"\ntest -z \"$LIBCC\" && try_libcc=`$CC -print-file-name=libpcc.a 2>/dev/null` \\\n                 && tryldflag LIBCC \"$try_libcc\"\nprintf \"using compiler runtime libraries: %s\\n\" \"$LIBCC\"\n\n# Figure out arch variants for archs with variants\nSUBARCH=\nt=\"$CFLAGS_C99FSE $CPPFLAGS $CFLAGS\"\n\nif test \"$ARCH\" = \"i386\" ; then\nprintf \"checking whether compiler can use ebx in PIC asm constraints... \"\ncat > \"$tmpc\" <<EOF\nint foo(int x) { __asm__ ( \"\" : \"+b\"(x) ); return x; }\nEOF\nif $CC $CFLAGS_C99FSE $CPPFLAGS $CFLAGS -fPIC \\\n  -c -o /dev/null \"$tmpc\" >/dev/null 2>&1 ; then\nprintf \"yes\\n\"\nelse\nprintf \"no\\n\"\nCFLAGS_AUTO=\"$CFLAGS_AUTO -DBROKEN_EBX_ASM\"\nfi\nfi\n\nif test \"$ARCH\" = \"x86_64\" ; then\ntrycppif __ILP32__ \"$t\" && ARCH=x32\nfi\n\nif test \"$ARCH\" = \"arm\" ; then\nif trycppif __thumb2__ \"$t\" ; then\ntryflag CFLAGS_AUTO -mimplicit-it=always\ntryflag CFLAGS_AUTO -Wa,-mimplicit-it=always\ntryflag CFLAGS_AUTO -Wa,-mthumb\nfi\ntrycppif __ARMEB__ \"$t\" && SUBARCH=${SUBARCH}eb\ntrycppif __ARM_PCS_VFP \"$t\" && SUBARCH=${SUBARCH}hf\n# Versions of clang up until at least 3.8 have the wrong constraint codes\n# for floating point operands to inline asm. Detect this so the affected\n# source files can just disable the asm.\nif test \"$cc_family\" = clang ; then\nprintf \"checking whether clang's vfp asm constraints work... \"\necho 'float f(float x) { __asm__(\"\":\"+t\"(x)); return x; }' > \"$tmpc\"\nif $CC $CFLAGS_C99FSE $CPPFLAGS $CFLAGS -c -o /dev/null \"$tmpc\" >/dev/null 2>&1 ; then\nprintf \"yes\\n\"\nelse\nprintf \"no\\n\"\nCFLAGS_AUTO=\"$CFLAGS_AUTO -DBROKEN_VFP_ASM\"\nCFLAGS_AUTO=\"${CFLAGS_AUTO# }\"\nfi\nfi\nfi\n\nif test \"$ARCH\" = \"aarch64\" ; then\ntrycppif __AARCH64EB__ \"$t\" && SUBARCH=${SUBARCH}_be\nfi\n\nif test \"$ARCH\" = \"m68k\" ; then\nif trycppif \"__HAVE_68881__\" ; then : ;\nelif trycppif \"__mcffpu__\" ; then SUBARCH=\"-fp64\"\nelse SUBARCH=\"-sf\"\nfi\nfi\n\nif test \"$ARCH\" = \"mips\" ; then\ntrycppif \"__mips_isa_rev >= 6\" \"$t\" && SUBARCH=${SUBARCH}r6\ntrycppif \"_MIPSEL || __MIPSEL || __MIPSEL__\" \"$t\" && SUBARCH=${SUBARCH}el\ntrycppif __mips_soft_float \"$t\" && SUBARCH=${SUBARCH}-sf\nfi\n\nif test \"$ARCH\" = \"mips64\" ; then\ntrycppif \"_MIPS_SIM != _ABI64\" \"$t\" && ARCH=mipsn32\ntrycppif \"__mips_isa_rev >= 6\" \"$t\" && SUBARCH=${SUBARCH}r6\ntrycppif \"_MIPSEL || __MIPSEL || __MIPSEL__\" \"$t\" && SUBARCH=${SUBARCH}el\ntrycppif __mips_soft_float \"$t\" && SUBARCH=${SUBARCH}-sf\nfi\n\nif test \"$ARCH\" = \"powerpc\" ; then\ntrycppif \"__NO_FPRS__ && !_SOFT_FLOAT\" \"$t\" && fail \\\n  \"$0: error: compiler's floating point configuration is unsupported\"\ntrycppif _SOFT_FLOAT \"$t\" && SUBARCH=${SUBARCH}-sf\nprintf \"checking whether compiler can use 'd' constraint in asm... \"\necho 'double f(double x) { __asm__ (\"fabs %0, %1\" : \"=d\"(x) : \"d\"(x)); return x; }' > \"$tmpc\"\nif $CC $CFLAGS_C99FSE $CPPFLAGS $CFLAGS -c -o /dev/null \"$tmpc\" >/dev/null 2>&1 ; then\nprintf \"yes\\n\"\nelse\nprintf \"no\\n\"\nCFLAGS_AUTO=\"$CFLAGS_AUTO -DBROKEN_PPC_D_ASM\"\nCFLAGS_AUTO=\"${CFLAGS_AUTO# }\"\nfi\nfi\n\ntest \"$ARCH\" = \"microblaze\" && trycppif __MICROBLAZEEL__ \"$t\" \\\n&& SUBARCH=${SUBARCH}el\n\nif test \"$ARCH\" = \"powerpc64\" ; then\ntrycppif \"_CALL_ELF == 2\" \"$t\" || fail \"$0: error: unsupported powerpc64 ABI\"\ntrycppif __LITTLE_ENDIAN__ \"$t\" && SUBARCH=${SUBARCH}le\ntrycppif _SOFT_FLOAT \"$t\" && fail \"$0: error: soft-float not supported on powerpc64\"\nfi\n\nif test \"$ARCH\" = \"riscv64\" ; then\ntrycppif __riscv_float_abi_soft \"$t\" && SUBARCH=${SUBARCH}-sf\ntrycppif __riscv_float_abi_single \"$t\" && SUBARCH=${SUBARCH}-sp\nfi\n\nif test \"$ARCH\" = \"sh\" ; then\ntryflag CFLAGS_AUTO -Wa,--isa=any\ntrycppif __BIG_ENDIAN__ \"$t\" && SUBARCH=${SUBARCH}eb\nif trycppif \"__SH_FPU_ANY__ || __SH4__\" \"$t\" ; then\n# Some sh configurations are broken and replace double with float\n# rather than using softfloat when the fpu is present but only\n# supports single precision. Reject them.\nprintf \"checking whether compiler's double type is IEEE double... \"\necho 'typedef char dblcheck[(int)sizeof(double)-5];' > \"$tmpc\"\nif $CC $CFLAGS_C99FSE $CPPFLAGS $CFLAGS -c -o /dev/null \"$tmpc\" >/dev/null 2>&1 ; then\nprintf \"yes\\n\"\nelse\nprintf \"no\\n\"\nfail \"$0: error: compiler's floating point configuration is unsupported\"\nfi\nelse\nSUBARCH=${SUBARCH}-nofpu\nfi\nif trycppif __SH_FDPIC__ \"$t\" ; then\nSUBARCH=${SUBARCH}-fdpic\nfi\nfi\n\ntest \"$SUBARCH\" \\\n&& printf \"configured for %s variant: %s\\n\" \"$ARCH\" \"$ARCH$SUBARCH\"\n\ncase \"$ARCH$SUBARCH\" in\narm) ASMSUBARCH=el ;;\n*) ASMSUBARCH=$SUBARCH ;;\nesac\n\n#\n# Some archs (powerpc) have different possible long double formats\n# that the compiler can be configured for. The logic for whether this\n# is supported is in bits/float.h; in general, it is not. We need to\n# check for mismatches here or code in printf, strotd, and scanf will\n# be dangerously incorrect because it depends on (1) the macros being\n# correct, and (2) IEEE semantics.\n#\nprintf \"checking whether compiler's long double definition matches float.h... \"\necho '#include <float.h>' > \"$tmpc\"\necho '#define C(m,s) (m==LDBL_MANT_DIG && s==sizeof(long double))' >> \"$tmpc\"\necho 'typedef char ldcheck[(C(53,8)||C(64,12)||C(64,16)||C(113,16))*2-1];' >> \"$tmpc\"\nif $CC $CFLAGS_C99FSE \\\n  -I$srcdir/arch/$ARCH -I$srcdir/arch/generic -I$srcdir/include \\\n  $CPPFLAGS $CFLAGS -c -o /dev/null \"$tmpc\" >/dev/null 2>&1 ; then\nprintf \"yes\\n\"\nelse\nprintf \"no\\n\"\nfail \"$0: error: unsupported long double type\"\nfi\n\n#\n# Some build systems globally pass in broken CFLAGS like -ffast-math\n# for all packages. On recent GCC we can detect this and error out\n# early rather than producing a seriously-broken math library.\n#\nif trycppif \"__FAST_MATH__\" \\\n  \"$CFLAGS_C99FSE $CPPFLAGS $CFLAGS\" ; then\nfail \"$0: error: compiler has broken floating point; check CFLAGS\"\nfi\n\nprintf \"creating config.mak... \"\n\ncmdline=$(quote \"$0\")\nfor i ; do cmdline=\"$cmdline $(quote \"$i\")\" ; done\n\nexec 3>&1 1>config.mak\n\n\ncat << EOF\n# This version of config.mak was generated by:\n# $cmdline\n# Any changes made here will be lost if configure is re-run\nAR = ${AR:-\\$(CROSS_COMPILE)ar}\nRANLIB = ${RANLIB:-\\$(CROSS_COMPILE)ranlib}\nARCH = $ARCH\nSUBARCH = $SUBARCH\nASMSUBARCH = $ASMSUBARCH\nsrcdir = $srcdir\nprefix = $prefix\nexec_prefix = $exec_prefix\nbindir = $bindir\nlibdir = $libdir\nincludedir = $includedir\nsyslibdir = $syslibdir\nCC = $CC\nCFLAGS = $CFLAGS\nCFLAGS_AUTO = $CFLAGS_AUTO\nCFLAGS_C99FSE = $CFLAGS_C99FSE\nCFLAGS_MEMOPS = $CFLAGS_MEMOPS\nCFLAGS_NOSSP = $CFLAGS_NOSSP\nCPPFLAGS = $CPPFLAGS\nLDFLAGS = $LDFLAGS\nLDFLAGS_AUTO = $LDFLAGS_AUTO\nCROSS_COMPILE = $CROSS_COMPILE\nLIBCC = $LIBCC\nOPTIMIZE_GLOBS = $OPTIMIZE_GLOBS\nALL_TOOLS = $tools\nTOOL_LIBS = $tool_libs\nADD_CFI = $ADD_CFI\nMALLOC_DIR = $malloc_dir\nEOF\ntest \"x$static\" = xno && echo \"STATIC_LIBS =\"\ntest \"x$shared\" = xno && echo \"SHARED_LIBS =\"\ntest \"x$cc_family\" = xgcc && echo 'WRAPCC_GCC = $(CC)'\ntest \"x$cc_family\" = xclang && echo 'WRAPCC_CLANG = $(CC)'\ntest \"x$pic_default\" = xyes && echo 'AOBJS = $(LOBJS)'\nexec 1>&3 3>&-\n\ntest \"$srcdir\" = \".\" || ln -sf $srcdir/Makefile .\n\nprintf \"done\\n\"\n"
  },
  {
    "path": "user.libc/crt/Scrt1.c",
    "content": "#include \"crt1.c\"\n"
  },
  {
    "path": "user.libc/crt/crt1.c",
    "content": "#include <features.h>\n#include \"libc.h\"\n\n#define START \"_start\"\n\n#include \"crt_arch.h\"\n\nint main();\nweak void _init();\nweak void _fini();\nint __libc_start_main(int (*)(), int, char **,\n\tvoid (*)(), void(*)(), void(*)());\n\nvoid _start_c(long *p)\n{\n\tint argc = p[0];\n\tchar **argv = (void *)(p+1);\n\t__libc_start_main(main, argc, argv, _init, _fini, 0);\n}\n"
  },
  {
    "path": "user.libc/crt/crti.c",
    "content": ""
  },
  {
    "path": "user.libc/crt/crtn.c",
    "content": ""
  },
  {
    "path": "user.libc/crt/rcrt1.c",
    "content": "#define START \"_start\"\n#define _dlstart_c _start_c\n#include \"../ldso/dlstart.c\"\n\nint main();\nweak void _init();\nweak void _fini();\nint __libc_start_main(int (*)(), int, char **,\n\tvoid (*)(), void(*)(), void(*)());\n\nhidden void __dls2(unsigned char *base, size_t *sp)\n{\n\t__libc_start_main(main, *sp, (void *)(sp+1), _init, _fini, 0);\n}\n"
  },
  {
    "path": "user.libc/dynamic.list",
    "content": "{\nenviron;\n__environ;\n\nstdin;\nstdout;\nstderr;\n\nmalloc;\ncalloc;\nrealloc;\nfree;\nmemalign;\nposix_memalign;\naligned_alloc;\nmalloc_usable_size;\n\ntimezone;\ndaylight;\ntzname;\n__timezone;\n__daylight;\n__tzname;\n\nsigngam;\n__signgam;\n\noptarg;\noptind;\nopterr;\noptopt;\noptreset;\n__optreset;\n\ngetdate_err;\n\nh_errno;\n\nprogram_invocation_name;\nprogram_invocation_short_name;\n__progname;\n__progname_full;\n\n__stack_chk_guard;\n};\n"
  },
  {
    "path": "user.libc/include/aio.h",
    "content": "#ifndef _AIO_H\n#define _AIO_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n#include <signal.h>\n#include <time.h>\n\n#define __NEED_ssize_t\n#define __NEED_off_t\n\n#include <bits/alltypes.h>\n\nstruct aiocb {\n\tint aio_fildes, aio_lio_opcode, aio_reqprio;\n\tvolatile void *aio_buf;\n\tsize_t aio_nbytes;\n\tstruct sigevent aio_sigevent;\n\tvoid *__td;\n\tint __lock[2];\n\tvolatile int __err;\n\tssize_t __ret;\n\toff_t aio_offset;\n\tvoid *__next, *__prev;\n\tchar __dummy4[32-2*sizeof(void *)];\n};\n\n#define AIO_CANCELED 0\n#define AIO_NOTCANCELED 1\n#define AIO_ALLDONE 2\n\n#define LIO_READ 0\n#define LIO_WRITE 1\n#define LIO_NOP 2\n\n#define LIO_WAIT 0\n#define LIO_NOWAIT 1\n\nint aio_read(struct aiocb *);\nint aio_write(struct aiocb *);\nint aio_error(const struct aiocb *);\nssize_t aio_return(struct aiocb *);\nint aio_cancel(int, struct aiocb *);\nint aio_suspend(const struct aiocb *const [], int, const struct timespec *);\nint aio_fsync(int, struct aiocb *);\n\nint lio_listio(int, struct aiocb *__restrict const *__restrict, int, struct sigevent *__restrict);\n\n#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)\n#define aiocb64 aiocb\n#define aio_read64 aio_read\n#define aio_write64 aio_write\n#define aio_error64 aio_error\n#define aio_return64 aio_return\n#define aio_cancel64 aio_cancel\n#define aio_suspend64 aio_suspend\n#define aio_fsync64 aio_fsync\n#define lio_listio64 lio_listio\n#define off64_t off_t\n#endif\n\n#if _REDIR_TIME64\n__REDIR(aio_suspend, __aio_suspend_time64);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/alloca.h",
    "content": "#ifndef\t_ALLOCA_H\n#define\t_ALLOCA_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define\t__NEED_size_t\n#include <bits/alltypes.h>\n\nvoid *alloca(size_t);\n\n#define alloca __builtin_alloca\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/alltypes.h.in",
    "content": "#define __LITTLE_ENDIAN 1234\n#define __BIG_ENDIAN 4321\n#define __USE_TIME_BITS64 1\n\nTYPEDEF unsigned _Addr size_t;\nTYPEDEF unsigned _Addr uintptr_t;\nTYPEDEF _Addr ptrdiff_t;\nTYPEDEF _Addr ssize_t;\nTYPEDEF _Addr intptr_t;\nTYPEDEF _Addr regoff_t;\nTYPEDEF _Reg register_t;\nTYPEDEF _Int64 time_t;\nTYPEDEF _Int64 suseconds_t;\n\nTYPEDEF signed char     int8_t;\nTYPEDEF signed short    int16_t;\nTYPEDEF signed int      int32_t;\nTYPEDEF signed _Int64   int64_t;\nTYPEDEF signed _Int64   intmax_t;\nTYPEDEF unsigned char   uint8_t;\nTYPEDEF unsigned short  uint16_t;\nTYPEDEF unsigned int    uint32_t;\nTYPEDEF unsigned _Int64 uint64_t;\nTYPEDEF unsigned _Int64 u_int64_t;\nTYPEDEF unsigned _Int64 uintmax_t;\n\nTYPEDEF unsigned mode_t;\nTYPEDEF unsigned _Reg nlink_t;\nTYPEDEF _Int64 off_t;\nTYPEDEF unsigned _Int64 ino_t;\nTYPEDEF unsigned _Int64 dev_t;\nTYPEDEF long blksize_t;\nTYPEDEF _Int64 blkcnt_t;\nTYPEDEF unsigned _Int64 fsblkcnt_t;\nTYPEDEF unsigned _Int64 fsfilcnt_t;\n\nTYPEDEF unsigned wint_t;\nTYPEDEF unsigned long wctype_t;\n\nTYPEDEF void * timer_t;\nTYPEDEF int clockid_t;\nTYPEDEF long clock_t;\nSTRUCT timeval { time_t tv_sec; suseconds_t tv_usec; };\nSTRUCT timespec { time_t tv_sec; int :8*(sizeof(time_t)-sizeof(long))*(__BYTE_ORDER==4321); long tv_nsec; int :8*(sizeof(time_t)-sizeof(long))*(__BYTE_ORDER!=4321); };\n\nTYPEDEF int pid_t;\nTYPEDEF unsigned id_t;\nTYPEDEF unsigned uid_t;\nTYPEDEF unsigned gid_t;\nTYPEDEF int key_t;\nTYPEDEF unsigned useconds_t;\n\n#ifdef __cplusplus\nTYPEDEF unsigned long pthread_t;\n#else\nTYPEDEF struct __pthread * pthread_t;\n#endif\nTYPEDEF int pthread_once_t;\nTYPEDEF unsigned pthread_key_t;\nTYPEDEF int pthread_spinlock_t;\nTYPEDEF struct { unsigned __attr; } pthread_mutexattr_t;\nTYPEDEF struct { unsigned __attr; } pthread_condattr_t;\nTYPEDEF struct { unsigned __attr; } pthread_barrierattr_t;\nTYPEDEF struct { unsigned __attr[2]; } pthread_rwlockattr_t;\n\nSTRUCT _IO_FILE { char __x; };\nTYPEDEF struct _IO_FILE FILE;\n\nTYPEDEF __builtin_va_list va_list;\nTYPEDEF __builtin_va_list __isoc_va_list;\n\nTYPEDEF struct __mbstate_t { unsigned __opaque1, __opaque2; } mbstate_t;\n\nTYPEDEF struct __locale_struct * locale_t;\n\nTYPEDEF struct __sigset_t { unsigned long __bits[128/sizeof(long)]; } sigset_t;\n\nSTRUCT iovec { void *iov_base; size_t iov_len; };\n\nSTRUCT winsize { unsigned short ws_row, ws_col, ws_xpixel, ws_ypixel; };\n\nTYPEDEF unsigned socklen_t;\nTYPEDEF unsigned short sa_family_t;\n\nTYPEDEF struct { union { int __i[sizeof(long)==8?14:9]; volatile int __vi[sizeof(long)==8?14:9]; unsigned long __s[sizeof(long)==8?7:9]; } __u; } pthread_attr_t;\nTYPEDEF struct { union { int __i[sizeof(long)==8?10:6]; volatile int __vi[sizeof(long)==8?10:6]; volatile void *volatile __p[sizeof(long)==8?5:6]; } __u; } pthread_mutex_t;\nTYPEDEF struct { union { int __i[sizeof(long)==8?10:6]; volatile int __vi[sizeof(long)==8?10:6]; volatile void *volatile __p[sizeof(long)==8?5:6]; } __u; } mtx_t;\nTYPEDEF struct { union { int __i[12]; volatile int __vi[12]; void *__p[12*sizeof(int)/sizeof(void*)]; } __u; } pthread_cond_t;\nTYPEDEF struct { union { int __i[12]; volatile int __vi[12]; void *__p[12*sizeof(int)/sizeof(void*)]; } __u; } cnd_t;\nTYPEDEF struct { union { int __i[sizeof(long)==8?14:8]; volatile int __vi[sizeof(long)==8?14:8]; void *__p[sizeof(long)==8?7:8]; } __u; } pthread_rwlock_t;\nTYPEDEF struct { union { int __i[sizeof(long)==8?8:5]; volatile int __vi[sizeof(long)==8?8:5]; void *__p[sizeof(long)==8?4:5]; } __u; } pthread_barrier_t;\n\n#undef _Addr\n#undef _Int64\n#undef _Reg\n"
  },
  {
    "path": "user.libc/include/ar.h",
    "content": "#ifndef _AR_H\n#define _AR_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define ARMAG \"!<arch>\\n\"\n#define SARMAG 8\n#define ARFMAG \"`\\n\"\n\nstruct ar_hdr {\n\tchar ar_name[16];\n\tchar ar_date[12];\n\tchar ar_uid[6], ar_gid[6];\n\tchar ar_mode[8];\n\tchar ar_size[10];\n\tchar ar_fmag[2];\n};\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/arpa/ftp.h",
    "content": "#ifndef _ARPA_FTP_H\n#define _ARPA_FTP_H\n#define PRELIM 1\n#define COMPLETE 2\n#define CONTINUE 3\n#define TRANSIENT 4\n#define ERROR 5\n#define TYPE_A 1\n#define TYPE_E 2\n#define TYPE_I 3\n#define TYPE_L 4\n#define FORM_N 1\n#define FORM_T 2\n#define FORM_C 3\n#define STRU_F 1\n#define STRU_R 2\n#define STRU_P 3\n#define MODE_S 1\n#define MODE_B 2\n#define MODE_C 3\n#define REC_ESC '\\377'\n#define REC_EOR '\\001'\n#define REC_EOF '\\002'\n#define BLK_EOR 0x80\n#define BLK_EOF 0x40\n#define BLK_ERRORS 0x20\n#define BLK_RESTART 0x10\n#define BLK_BYTECOUNT 2\n#ifdef FTP_NAMES\nchar *modenames[] =  {\"0\", \"Stream\", \"Block\", \"Compressed\" };\nchar *strunames[] =  {\"0\", \"File\", \"Record\", \"Page\" };\nchar *typenames[] =  {\"0\", \"ASCII\", \"EBCDIC\", \"Image\", \"Local\" };\nchar *formnames[] =  {\"0\", \"Nonprint\", \"Telnet\", \"Carriage-control\" };\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/arpa/inet.h",
    "content": "#ifndef _ARPA_INET_H\n#define\t_ARPA_INET_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n#include <netinet/in.h>\n\nuint32_t htonl(uint32_t);\nuint16_t htons(uint16_t);\nuint32_t ntohl(uint32_t);\nuint16_t ntohs(uint16_t);\n\nin_addr_t inet_addr (const char *);\nin_addr_t inet_network (const char *);\nchar *inet_ntoa (struct in_addr);\nint inet_pton (int, const char *__restrict, void *__restrict);\nconst char *inet_ntop (int, const void *__restrict, char *__restrict, socklen_t);\n\nint inet_aton (const char *, struct in_addr *);\nstruct in_addr inet_makeaddr(in_addr_t, in_addr_t);\nin_addr_t inet_lnaof(struct in_addr);\nin_addr_t inet_netof(struct in_addr);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/arpa/nameser.h",
    "content": "#ifndef _ARPA_NAMESER_H\n#define _ARPA_NAMESER_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stddef.h>\n#include <stdint.h>\n\n#define __NAMESER\t19991006\n#define NS_PACKETSZ\t512\n#define NS_MAXDNAME\t1025\n#define NS_MAXMSG\t65535\n#define NS_MAXCDNAME\t255\n#define NS_MAXLABEL\t63\n#define NS_HFIXEDSZ\t12\n#define NS_QFIXEDSZ\t4\n#define NS_RRFIXEDSZ\t10\n#define NS_INT32SZ\t4\n#define NS_INT16SZ\t2\n#define NS_INT8SZ\t1\n#define NS_INADDRSZ\t4\n#define NS_IN6ADDRSZ\t16\n#define NS_CMPRSFLGS\t0xc0\n#define NS_DEFAULTPORT\t53\n\ntypedef enum __ns_sect {\n\tns_s_qd = 0,\n\tns_s_zn = 0,\n\tns_s_an = 1,\n\tns_s_pr = 1,\n\tns_s_ns = 2,\n\tns_s_ud = 2,\n\tns_s_ar = 3,\n\tns_s_max = 4\n} ns_sect;\n\ntypedef struct __ns_msg {\n\tconst unsigned char *_msg, *_eom;\n\tuint16_t _id, _flags, _counts[ns_s_max];\n\tconst unsigned char *_sections[ns_s_max];\n\tns_sect _sect;\n\tint _rrnum;\n\tconst unsigned char *_msg_ptr;\n} ns_msg;\n\nstruct _ns_flagdata {  int mask, shift;  };\nextern const struct _ns_flagdata _ns_flagdata[];\n\n#define ns_msg_id(handle) ((handle)._id + 0)\n#define ns_msg_base(handle) ((handle)._msg + 0)\n#define ns_msg_end(handle) ((handle)._eom + 0)\n#define ns_msg_size(handle) ((handle)._eom - (handle)._msg)\n#define ns_msg_count(handle, section) ((handle)._counts[section] + 0)\n#define ns_msg_getflag(handle, flag) \\\n\t(((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift)\n\ntypedef\tstruct __ns_rr {\n\tchar\t\tname[NS_MAXDNAME];\n\tuint16_t\ttype;\n\tuint16_t\trr_class;\n\tuint32_t\tttl;\n\tuint16_t\trdlength;\n\tconst unsigned char *rdata;\n} ns_rr;\n\n#define ns_rr_name(rr)\t(((rr).name[0] != '\\0') ? (rr).name : \".\")\n#define ns_rr_type(rr)\t((ns_type)((rr).type + 0))\n#define ns_rr_class(rr)\t((ns_class)((rr).rr_class + 0))\n#define ns_rr_ttl(rr)\t((rr).ttl + 0)\n#define ns_rr_rdlen(rr)\t((rr).rdlength + 0)\n#define ns_rr_rdata(rr)\t((rr).rdata + 0)\n\ntypedef enum __ns_flag {\n\tns_f_qr,\n\tns_f_opcode,\n\tns_f_aa,\n\tns_f_tc,\n\tns_f_rd,\n\tns_f_ra,\n\tns_f_z,\n\tns_f_ad,\n\tns_f_cd,\n\tns_f_rcode,\n\tns_f_max\n} ns_flag;\n\ntypedef enum __ns_opcode {\n\tns_o_query = 0,\n\tns_o_iquery = 1,\n\tns_o_status = 2,\n\tns_o_notify = 4,\n\tns_o_update = 5,\n\tns_o_max = 6\n} ns_opcode;\n\ntypedef\tenum __ns_rcode {\n\tns_r_noerror = 0,\n\tns_r_formerr = 1,\n\tns_r_servfail = 2,\n\tns_r_nxdomain = 3,\n\tns_r_notimpl = 4,\n\tns_r_refused = 5,\n\tns_r_yxdomain = 6,\n\tns_r_yxrrset = 7,\n\tns_r_nxrrset = 8,\n\tns_r_notauth = 9,\n\tns_r_notzone = 10,\n\tns_r_max = 11,\n\tns_r_badvers = 16,\n\tns_r_badsig = 16,\n\tns_r_badkey = 17,\n\tns_r_badtime = 18\n} ns_rcode;\n\ntypedef enum __ns_update_operation {\n\tns_uop_delete = 0,\n\tns_uop_add = 1,\n\tns_uop_max = 2\n} ns_update_operation;\n\nstruct ns_tsig_key {\n        char name[NS_MAXDNAME], alg[NS_MAXDNAME];\n        unsigned char *data;\n        int len;\n};\ntypedef struct ns_tsig_key ns_tsig_key;\n\nstruct ns_tcp_tsig_state {\n\tint counter;\n\tstruct dst_key *key;\n\tvoid *ctx;\n\tunsigned char sig[NS_PACKETSZ];\n\tint siglen;\n};\ntypedef struct ns_tcp_tsig_state ns_tcp_tsig_state;\n\n#define NS_TSIG_FUDGE 300\n#define NS_TSIG_TCP_COUNT 100\n#define NS_TSIG_ALG_HMAC_MD5 \"HMAC-MD5.SIG-ALG.REG.INT\"\n\n#define NS_TSIG_ERROR_NO_TSIG -10\n#define NS_TSIG_ERROR_NO_SPACE -11\n#define NS_TSIG_ERROR_FORMERR -12\n\ntypedef enum __ns_type {\n\tns_t_invalid = 0,\n\tns_t_a = 1,\n\tns_t_ns = 2,\n\tns_t_md = 3,\n\tns_t_mf = 4,\n\tns_t_cname = 5,\n\tns_t_soa = 6,\n\tns_t_mb = 7,\n\tns_t_mg = 8,\n\tns_t_mr = 9,\n\tns_t_null = 10,\n\tns_t_wks = 11,\n\tns_t_ptr = 12,\n\tns_t_hinfo = 13,\n\tns_t_minfo = 14,\n\tns_t_mx = 15,\n\tns_t_txt = 16,\n\tns_t_rp = 17,\n\tns_t_afsdb = 18,\n\tns_t_x25 = 19,\n\tns_t_isdn = 20,\n\tns_t_rt = 21,\n\tns_t_nsap = 22,\n\tns_t_nsap_ptr = 23,\n\tns_t_sig = 24,\n\tns_t_key = 25,\n\tns_t_px = 26,\n\tns_t_gpos = 27,\n\tns_t_aaaa = 28,\n\tns_t_loc = 29,\n\tns_t_nxt = 30,\n\tns_t_eid = 31,\n\tns_t_nimloc = 32,\n\tns_t_srv = 33,\n\tns_t_atma = 34,\n\tns_t_naptr = 35,\n\tns_t_kx = 36,\n\tns_t_cert = 37,\n\tns_t_a6 = 38,\n\tns_t_dname = 39,\n\tns_t_sink = 40,\n\tns_t_opt = 41,\n\tns_t_apl = 42,\n\tns_t_tkey = 249,\n\tns_t_tsig = 250,\n\tns_t_ixfr = 251,\n\tns_t_axfr = 252,\n\tns_t_mailb = 253,\n\tns_t_maila = 254,\n\tns_t_any = 255,\n\tns_t_zxfr = 256,\n\tns_t_max = 65536\n} ns_type;\n\n#define\tns_t_qt_p(t) (ns_t_xfr_p(t) || (t) == ns_t_any || \\\n\t\t      (t) == ns_t_mailb || (t) == ns_t_maila)\n#define\tns_t_mrr_p(t) ((t) == ns_t_tsig || (t) == ns_t_opt)\n#define ns_t_rr_p(t) (!ns_t_qt_p(t) && !ns_t_mrr_p(t))\n#define ns_t_udp_p(t) ((t) != ns_t_axfr && (t) != ns_t_zxfr)\n#define ns_t_xfr_p(t) ((t) == ns_t_axfr || (t) == ns_t_ixfr || \\\n\t\t       (t) == ns_t_zxfr)\n\ntypedef enum __ns_class {\n\tns_c_invalid = 0,\n\tns_c_in = 1,\n\tns_c_2 = 2,\n\tns_c_chaos = 3,\n\tns_c_hs = 4,\n\tns_c_none = 254,\n\tns_c_any = 255,\n\tns_c_max = 65536\n} ns_class;\n\ntypedef enum __ns_key_types {\n\tns_kt_rsa = 1,\n\tns_kt_dh  = 2,\n\tns_kt_dsa = 3,\n\tns_kt_private = 254\n} ns_key_types;\n\ntypedef enum __ns_cert_types {\n\tcert_t_pkix = 1,\n\tcert_t_spki = 2,\n\tcert_t_pgp  = 3,\n\tcert_t_url  = 253,\n\tcert_t_oid  = 254\n} ns_cert_types;\n\n#define\tNS_KEY_TYPEMASK\t\t0xC000\n#define\tNS_KEY_TYPE_AUTH_CONF\t0x0000\n#define\tNS_KEY_TYPE_CONF_ONLY\t0x8000\n#define\tNS_KEY_TYPE_AUTH_ONLY\t0x4000\n#define\tNS_KEY_TYPE_NO_KEY\t0xC000\n#define\tNS_KEY_NO_AUTH\t\t0x8000\n#define\tNS_KEY_NO_CONF\t\t0x4000\n#define\tNS_KEY_RESERVED2\t0x2000\n#define\tNS_KEY_EXTENDED_FLAGS\t0x1000\n#define\tNS_KEY_RESERVED4\t0x0800\n#define\tNS_KEY_RESERVED5\t0x0400\n#define\tNS_KEY_NAME_TYPE\t0x0300\n#define\tNS_KEY_NAME_USER\t0x0000\n#define\tNS_KEY_NAME_ENTITY\t0x0200\n#define\tNS_KEY_NAME_ZONE\t0x0100\n#define\tNS_KEY_NAME_RESERVED\t0x0300\n#define\tNS_KEY_RESERVED8\t0x0080\n#define\tNS_KEY_RESERVED9\t0x0040\n#define\tNS_KEY_RESERVED10\t0x0020\n#define\tNS_KEY_RESERVED11\t0x0010\n#define\tNS_KEY_SIGNATORYMASK\t0x000F\n#define\tNS_KEY_RESERVED_BITMASK ( NS_KEY_RESERVED2 | \\\n\t\t\t\t  NS_KEY_RESERVED4 | \\\n\t\t\t\t  NS_KEY_RESERVED5 | \\\n\t\t\t\t  NS_KEY_RESERVED8 | \\\n\t\t\t\t  NS_KEY_RESERVED9 | \\\n\t\t\t\t  NS_KEY_RESERVED10 | \\\n\t\t\t\t  NS_KEY_RESERVED11 )\n#define NS_KEY_RESERVED_BITMASK2 0xFFFF\n#define\tNS_ALG_MD5RSA\t\t1\n#define\tNS_ALG_DH               2\n#define\tNS_ALG_DSA              3\n#define\tNS_ALG_DSS              NS_ALG_DSA\n#define\tNS_ALG_EXPIRE_ONLY\t253\n#define\tNS_ALG_PRIVATE_OID\t254\n\n#define NS_KEY_PROT_TLS         1\n#define NS_KEY_PROT_EMAIL       2\n#define NS_KEY_PROT_DNSSEC      3\n#define NS_KEY_PROT_IPSEC       4\n#define NS_KEY_PROT_ANY\t\t255\n\n#define\tNS_MD5RSA_MIN_BITS\t 512\n#define\tNS_MD5RSA_MAX_BITS\t4096\n#define\tNS_MD5RSA_MAX_BYTES\t((NS_MD5RSA_MAX_BITS+7/8)*2+3)\n#define\tNS_MD5RSA_MAX_BASE64\t(((NS_MD5RSA_MAX_BYTES+2)/3)*4)\n#define NS_MD5RSA_MIN_SIZE\t((NS_MD5RSA_MIN_BITS+7)/8)\n#define NS_MD5RSA_MAX_SIZE\t((NS_MD5RSA_MAX_BITS+7)/8)\n\n#define NS_DSA_SIG_SIZE         41\n#define NS_DSA_MIN_SIZE         213\n#define NS_DSA_MAX_BYTES        405\n\n#define\tNS_SIG_TYPE\t0\n#define\tNS_SIG_ALG\t2\n#define\tNS_SIG_LABELS\t3\n#define\tNS_SIG_OTTL\t4\n#define\tNS_SIG_EXPIR\t8\n#define\tNS_SIG_SIGNED\t12\n#define\tNS_SIG_FOOT\t16\n#define\tNS_SIG_SIGNER\t18\n#define\tNS_NXT_BITS 8\n#define\tNS_NXT_BIT_SET(  n,p) (p[(n)/NS_NXT_BITS] |=  (0x80>>((n)%NS_NXT_BITS)))\n#define\tNS_NXT_BIT_CLEAR(n,p) (p[(n)/NS_NXT_BITS] &= ~(0x80>>((n)%NS_NXT_BITS)))\n#define\tNS_NXT_BIT_ISSET(n,p) (p[(n)/NS_NXT_BITS] &   (0x80>>((n)%NS_NXT_BITS)))\n#define NS_NXT_MAX 127\n\n#define NS_OPT_DNSSEC_OK        0x8000U\n#define NS_OPT_NSID\t\t3\n\n#define NS_GET16(s, cp) (void)((s) = ns_get16(((cp)+=2)-2))\n#define NS_GET32(l, cp) (void)((l) = ns_get32(((cp)+=4)-4))\n#define NS_PUT16(s, cp) ns_put16((s), ((cp)+=2)-2)\n#define NS_PUT32(l, cp) ns_put32((l), ((cp)+=4)-4)\n\nunsigned ns_get16(const unsigned char *);\nunsigned long ns_get32(const unsigned char *);\nvoid ns_put16(unsigned, unsigned char *);\nvoid ns_put32(unsigned long, unsigned char *);\n\nint ns_initparse(const unsigned char *, int, ns_msg *);\nint ns_parserr(ns_msg *, ns_sect, int, ns_rr *);\nint ns_skiprr(const unsigned char *, const unsigned char *, ns_sect, int);\nint ns_name_uncompress(const unsigned char *, const unsigned char *, const unsigned char *, char *, size_t);\n\n\n#define\t__BIND\t\t19950621\n\ntypedef struct {\n\tunsigned\tid :16;\n#if __BYTE_ORDER == __BIG_ENDIAN\n\tunsigned\tqr: 1;\n\tunsigned\topcode: 4;\n\tunsigned\taa: 1;\n\tunsigned\ttc: 1;\n\tunsigned\trd: 1;\n\tunsigned\tra: 1;\n\tunsigned\tunused :1;\n\tunsigned\tad: 1;\n\tunsigned\tcd: 1;\n\tunsigned\trcode :4;\n#else\n\tunsigned\trd :1;\n\tunsigned\ttc :1;\n\tunsigned\taa :1;\n\tunsigned\topcode :4;\n\tunsigned\tqr :1;\n\tunsigned\trcode :4;\n\tunsigned\tcd: 1;\n\tunsigned\tad: 1;\n\tunsigned\tunused :1;\n\tunsigned\tra :1;\n#endif\n\tunsigned\tqdcount :16;\n\tunsigned\tancount :16;\n\tunsigned\tnscount :16;\n\tunsigned\tarcount :16;\n} HEADER;\n\n#define PACKETSZ\tNS_PACKETSZ\n#define MAXDNAME\tNS_MAXDNAME\n#define MAXCDNAME\tNS_MAXCDNAME\n#define MAXLABEL\tNS_MAXLABEL\n#define\tHFIXEDSZ\tNS_HFIXEDSZ\n#define QFIXEDSZ\tNS_QFIXEDSZ\n#define RRFIXEDSZ\tNS_RRFIXEDSZ\n#define\tINT32SZ\t\tNS_INT32SZ\n#define\tINT16SZ\t\tNS_INT16SZ\n#define INT8SZ\t\tNS_INT8SZ\n#define\tINADDRSZ\tNS_INADDRSZ\n#define\tIN6ADDRSZ\tNS_IN6ADDRSZ\n#define\tINDIR_MASK\tNS_CMPRSFLGS\n#define NAMESERVER_PORT\tNS_DEFAULTPORT\n\n#define S_ZONE\t\tns_s_zn\n#define S_PREREQ\tns_s_pr\n#define S_UPDATE\tns_s_ud\n#define S_ADDT\t\tns_s_ar\n\n#define QUERY\t\tns_o_query\n#define IQUERY\t\tns_o_iquery\n#define STATUS\t\tns_o_status\n#define\tNS_NOTIFY_OP\tns_o_notify\n#define\tNS_UPDATE_OP\tns_o_update\n\n#define NOERROR\t\tns_r_noerror\n#define FORMERR\t\tns_r_formerr\n#define SERVFAIL\tns_r_servfail\n#define NXDOMAIN\tns_r_nxdomain\n#define NOTIMP\t\tns_r_notimpl\n#define REFUSED\t\tns_r_refused\n#define YXDOMAIN\tns_r_yxdomain\n#define YXRRSET\t\tns_r_yxrrset\n#define NXRRSET\t\tns_r_nxrrset\n#define NOTAUTH\t\tns_r_notauth\n#define NOTZONE\t\tns_r_notzone\n\n#define DELETE\t\tns_uop_delete\n#define ADD\t\tns_uop_add\n\n#define T_A\t\tns_t_a\n#define T_NS\t\tns_t_ns\n#define T_MD\t\tns_t_md\n#define T_MF\t\tns_t_mf\n#define T_CNAME\t\tns_t_cname\n#define T_SOA\t\tns_t_soa\n#define T_MB\t\tns_t_mb\n#define T_MG\t\tns_t_mg\n#define T_MR\t\tns_t_mr\n#define T_NULL\t\tns_t_null\n#define T_WKS\t\tns_t_wks\n#define T_PTR\t\tns_t_ptr\n#define T_HINFO\t\tns_t_hinfo\n#define T_MINFO\t\tns_t_minfo\n#define T_MX\t\tns_t_mx\n#define T_TXT\t\tns_t_txt\n#define\tT_RP\t\tns_t_rp\n#define T_AFSDB\t\tns_t_afsdb\n#define T_X25\t\tns_t_x25\n#define T_ISDN\t\tns_t_isdn\n#define T_RT\t\tns_t_rt\n#define T_NSAP\t\tns_t_nsap\n#define T_NSAP_PTR\tns_t_nsap_ptr\n#define\tT_SIG\t\tns_t_sig\n#define\tT_KEY\t\tns_t_key\n#define\tT_PX\t\tns_t_px\n#define\tT_GPOS\t\tns_t_gpos\n#define\tT_AAAA\t\tns_t_aaaa\n#define\tT_LOC\t\tns_t_loc\n#define\tT_NXT\t\tns_t_nxt\n#define\tT_EID\t\tns_t_eid\n#define\tT_NIMLOC\tns_t_nimloc\n#define\tT_SRV\t\tns_t_srv\n#define T_ATMA\t\tns_t_atma\n#define T_NAPTR\t\tns_t_naptr\n#define T_A6\t\tns_t_a6\n#define T_DNAME\t\tns_t_dname\n#define\tT_TSIG\t\tns_t_tsig\n#define\tT_IXFR\t\tns_t_ixfr\n#define T_AXFR\t\tns_t_axfr\n#define T_MAILB\t\tns_t_mailb\n#define T_MAILA\t\tns_t_maila\n#define T_ANY\t\tns_t_any\n\n#define C_IN\t\tns_c_in\n#define C_CHAOS\t\tns_c_chaos\n#define C_HS\t\tns_c_hs\n#define C_NONE\t\tns_c_none\n#define C_ANY\t\tns_c_any\n\n#define\tGETSHORT\t\tNS_GET16\n#define\tGETLONG\t\t\tNS_GET32\n#define\tPUTSHORT\t\tNS_PUT16\n#define\tPUTLONG\t\t\tNS_PUT32\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/arpa/nameser_compat.h",
    "content": "#include <arpa/nameser.h>\n\n"
  },
  {
    "path": "user.libc/include/arpa/telnet.h",
    "content": "#ifndef _ARPA_TELNET_H\n#define\t_ARPA_TELNET_H\n\n#define\tIAC\t255\n#define\tDONT\t254\n#define\tDO\t253\n#define\tWONT\t252\n#define\tWILL\t251\n#define\tSB\t250\n#define\tGA\t249\n#define\tEL\t248\n#define\tEC\t247\n#define\tAYT\t246\n#define\tAO\t245\n#define\tIP\t244\n#define\tBREAK\t243\n#define\tDM\t242\n#define\tNOP\t241\n#define\tSE\t240\n#define EOR     239\n#define\tABORT\t238\n#define\tSUSP\t237\n#define\txEOF\t236\n\n#define SYNCH\t242\n\n#define telcmds ((char [][6]){ \"EOF\", \"SUSP\", \"ABORT\", \"EOR\", \"SE\", \"NOP\", \"DMARK\", \"BRK\", \"IP\", \"AO\", \"AYT\", \"EC\", \"EL\", \"GA\", \"SB\", \"WILL\", \"WONT\", \"DO\", \"DONT\", \"IAC\", 0 })\n\n#define\tTELCMD_FIRST\txEOF\n#define\tTELCMD_LAST\tIAC\n#define\tTELCMD_OK(x)\t((unsigned int)(x) <= TELCMD_LAST && \\\n\t\t\t (unsigned int)(x) >= TELCMD_FIRST)\n#define\tTELCMD(x)\ttelcmds[(x)-TELCMD_FIRST]\n\n#define TELOPT_BINARY\t0\n#define TELOPT_ECHO\t1\n#define\tTELOPT_RCP\t2\n#define\tTELOPT_SGA\t3\n#define\tTELOPT_NAMS\t4\n#define\tTELOPT_STATUS\t5\n#define\tTELOPT_TM\t6\n#define\tTELOPT_RCTE\t7\n#define TELOPT_NAOL \t8\n#define TELOPT_NAOP \t9\n#define TELOPT_NAOCRD\t10\n#define TELOPT_NAOHTS\t11\n#define TELOPT_NAOHTD\t12\n#define TELOPT_NAOFFD\t13\n#define TELOPT_NAOVTS\t14\n#define TELOPT_NAOVTD\t15\n#define TELOPT_NAOLFD\t16\n#define TELOPT_XASCII\t17\n#define\tTELOPT_LOGOUT\t18\n#define\tTELOPT_BM\t19\n#define\tTELOPT_DET\t20\n#define\tTELOPT_SUPDUP\t21\n#define\tTELOPT_SUPDUPOUTPUT 22\n#define\tTELOPT_SNDLOC\t23\n#define\tTELOPT_TTYPE\t24\n#define\tTELOPT_EOR\t25\n#define\tTELOPT_TUID\t26\n#define\tTELOPT_OUTMRK\t27\n#define\tTELOPT_TTYLOC\t28\n#define\tTELOPT_3270REGIME 29\n#define\tTELOPT_X3PAD\t30\n#define\tTELOPT_NAWS\t31\n#define\tTELOPT_TSPEED\t32\n#define\tTELOPT_LFLOW\t33\n#define TELOPT_LINEMODE\t34\n#define TELOPT_XDISPLOC\t35\n#define TELOPT_OLD_ENVIRON 36\n#define\tTELOPT_AUTHENTICATION 37/* Authenticate */\n#define\tTELOPT_ENCRYPT\t38\n#define TELOPT_NEW_ENVIRON 39\n#define\tTELOPT_EXOPL\t255\n\n\n#define\tNTELOPTS\t(1+TELOPT_NEW_ENVIRON)\n#ifdef TELOPTS\nchar *telopts[NTELOPTS+1] = {\n\t\"BINARY\", \"ECHO\", \"RCP\", \"SUPPRESS GO AHEAD\", \"NAME\",\n\t\"STATUS\", \"TIMING MARK\", \"RCTE\", \"NAOL\", \"NAOP\",\n\t\"NAOCRD\", \"NAOHTS\", \"NAOHTD\", \"NAOFFD\", \"NAOVTS\",\n\t\"NAOVTD\", \"NAOLFD\", \"EXTEND ASCII\", \"LOGOUT\", \"BYTE MACRO\",\n\t\"DATA ENTRY TERMINAL\", \"SUPDUP\", \"SUPDUP OUTPUT\",\n\t\"SEND LOCATION\", \"TERMINAL TYPE\", \"END OF RECORD\",\n\t\"TACACS UID\", \"OUTPUT MARKING\", \"TTYLOC\",\n\t\"3270 REGIME\", \"X.3 PAD\", \"NAWS\", \"TSPEED\", \"LFLOW\",\n\t\"LINEMODE\", \"XDISPLOC\", \"OLD-ENVIRON\", \"AUTHENTICATION\",\n\t\"ENCRYPT\", \"NEW-ENVIRON\",\n\t0,\n};\n#define\tTELOPT_FIRST\tTELOPT_BINARY\n#define\tTELOPT_LAST\tTELOPT_NEW_ENVIRON\n#define\tTELOPT_OK(x)\t((unsigned int)(x) <= TELOPT_LAST)\n#define\tTELOPT(x)\ttelopts[(x)-TELOPT_FIRST]\n#endif\n\n#define\tTELQUAL_IS\t0\n#define\tTELQUAL_SEND\t1\n#define\tTELQUAL_INFO\t2\n#define\tTELQUAL_REPLY\t2\n#define\tTELQUAL_NAME\t3\n\n#define\tLFLOW_OFF\t\t0\n#define\tLFLOW_ON\t\t1\n#define\tLFLOW_RESTART_ANY\t2\n#define\tLFLOW_RESTART_XON\t3\n\n\n#define\tLM_MODE\t\t1\n#define\tLM_FORWARDMASK\t2\n#define\tLM_SLC\t\t3\n\n#define\tMODE_EDIT\t0x01\n#define\tMODE_TRAPSIG\t0x02\n#define\tMODE_ACK\t0x04\n#define MODE_SOFT_TAB\t0x08\n#define MODE_LIT_ECHO\t0x10\n\n#define\tMODE_MASK\t0x1f\n\n#define MODE_FLOW\t\t0x0100\n#define MODE_ECHO\t\t0x0200\n#define MODE_INBIN\t\t0x0400\n#define MODE_OUTBIN\t\t0x0800\n#define MODE_FORCE\t\t0x1000\n\n#define\tSLC_SYNCH\t1\n#define\tSLC_BRK\t\t2\n#define\tSLC_IP\t\t3\n#define\tSLC_AO\t\t4\n#define\tSLC_AYT\t\t5\n#define\tSLC_EOR\t\t6\n#define\tSLC_ABORT\t7\n#define\tSLC_EOF\t\t8\n#define\tSLC_SUSP\t9\n#define\tSLC_EC\t\t10\n#define\tSLC_EL\t\t11\n#define\tSLC_EW\t\t12\n#define\tSLC_RP\t\t13\n#define\tSLC_LNEXT\t14\n#define\tSLC_XON\t\t15\n#define\tSLC_XOFF\t16\n#define\tSLC_FORW1\t17\n#define\tSLC_FORW2\t18\n\n#define\tNSLC\t\t18\n\n#define\tSLC_NAMELIST\t\"0\", \"SYNCH\", \"BRK\", \"IP\", \"AO\", \"AYT\", \"EOR\", \\\n\t\t\t\"ABORT\", \"EOF\", \"SUSP\", \"EC\", \"EL\", \"EW\", \"RP\", \\\n\t\t\t\"LNEXT\", \"XON\", \"XOFF\", \"FORW1\", \"FORW2\", 0,\n#ifdef\tSLC_NAMES\nchar *slc_names[] = {\n\tSLC_NAMELIST\n};\n#else\nextern char *slc_names[];\n#define\tSLC_NAMES SLC_NAMELIST\n#endif\n\n#define\tSLC_NAME_OK(x)\t((unsigned int)(x) <= NSLC)\n#define SLC_NAME(x)\tslc_names[x]\n\n#define\tSLC_NOSUPPORT\t0\n#define\tSLC_CANTCHANGE\t1\n#define\tSLC_VARIABLE\t2\n#define\tSLC_DEFAULT\t3\n#define\tSLC_LEVELBITS\t0x03\n\n#define\tSLC_FUNC\t0\n#define\tSLC_FLAGS\t1\n#define\tSLC_VALUE\t2\n\n#define\tSLC_ACK\t\t0x80\n#define\tSLC_FLUSHIN\t0x40\n#define\tSLC_FLUSHOUT\t0x20\n\n#define\tOLD_ENV_VAR\t1\n#define\tOLD_ENV_VALUE\t0\n#define\tNEW_ENV_VAR\t0\n#define\tNEW_ENV_VALUE\t1\n#define\tENV_ESC\t\t2\n#define ENV_USERVAR\t3\n\n#define\tAUTH_WHO_CLIENT\t\t0\n#define\tAUTH_WHO_SERVER\t\t1\n#define\tAUTH_WHO_MASK\t\t1\n\n#define\tAUTH_HOW_ONE_WAY\t0\n#define\tAUTH_HOW_MUTUAL\t\t2\n#define\tAUTH_HOW_MASK\t\t2\n\n#define\tAUTHTYPE_NULL\t\t0\n#define\tAUTHTYPE_KERBEROS_V4\t1\n#define\tAUTHTYPE_KERBEROS_V5\t2\n#define\tAUTHTYPE_SPX\t\t3\n#define\tAUTHTYPE_MINK\t\t4\n#define\tAUTHTYPE_CNT\t\t5\n\n#define\tAUTHTYPE_TEST\t\t99\n\n#ifdef\tAUTH_NAMES\nchar *authtype_names[] = {\n\t\"NULL\", \"KERBEROS_V4\", \"KERBEROS_V5\", \"SPX\", \"MINK\", 0,\n};\n#else\nextern char *authtype_names[];\n#endif\n\n#define\tAUTHTYPE_NAME_OK(x)\t((unsigned int)(x) < AUTHTYPE_CNT)\n#define\tAUTHTYPE_NAME(x)\tauthtype_names[x]\n\n#define\tENCRYPT_IS\t\t0\n#define\tENCRYPT_SUPPORT\t\t1\n#define\tENCRYPT_REPLY\t\t2\n#define\tENCRYPT_START\t\t3\n#define\tENCRYPT_END\t\t4\n#define\tENCRYPT_REQSTART\t5\n#define\tENCRYPT_REQEND\t\t6\n#define\tENCRYPT_ENC_KEYID\t7\n#define\tENCRYPT_DEC_KEYID\t8\n#define\tENCRYPT_CNT\t\t9\n\n#define\tENCTYPE_ANY\t\t0\n#define\tENCTYPE_DES_CFB64\t1\n#define\tENCTYPE_DES_OFB64\t2\n#define\tENCTYPE_CNT\t\t3\n\n#ifdef\tENCRYPT_NAMES\nchar *encrypt_names[] = {\n\t\"IS\", \"SUPPORT\", \"REPLY\", \"START\", \"END\",\n\t\"REQUEST-START\", \"REQUEST-END\", \"ENC-KEYID\", \"DEC-KEYID\",\n\t0,\n};\nchar *enctype_names[] = {\n\t\"ANY\", \"DES_CFB64\",  \"DES_OFB64\",  0,\n};\n#else\nextern char *encrypt_names[];\nextern char *enctype_names[];\n#endif\n\n\n#define\tENCRYPT_NAME_OK(x)\t((unsigned int)(x) < ENCRYPT_CNT)\n#define\tENCRYPT_NAME(x)\t\tencrypt_names[x]\n\n#define\tENCTYPE_NAME_OK(x)\t((unsigned int)(x) < ENCTYPE_CNT)\n#define\tENCTYPE_NAME(x)\t\tenctype_names[x]\n\n#endif\n"
  },
  {
    "path": "user.libc/include/arpa/tftp.h",
    "content": "#ifndef _ARPA_TFTP_H\n#define _ARPA_TFTP_H\n#define SEGSIZE 512\n#define RRQ 01\n#define WRQ 02\n#define DATA 03\n#define ACK 04\n#define ERROR 05\nstruct tftphdr {\n\tshort th_opcode;\n\tunion {\n\t\tunsigned short tu_block;\n\t\tshort tu_code;\n\t\tchar tu_stuff[1];\n\t} th_u;\n\tchar th_data[1];\n};\n#define th_block th_u.tu_block\n#define th_code th_u.tu_code\n#define th_stuff th_u.tu_stuff\n#define th_msg th_data\n#define EUNDEF 0\n#define ENOTFOUND 1\n#define EACCESS 2\n#define ENOSPACE 3\n#define EBADOP 4\n#define EBADID 5\n#define EEXISTS 6\n#define ENOUSER 7\n#endif\n\n"
  },
  {
    "path": "user.libc/include/assert.h",
    "content": "#include <features.h>\n\n#undef assert\n\n#ifdef NDEBUG\n#define\tassert(x) (void)0\n#else\n#define assert(x) ((void)((x) || (__assert_fail(#x, __FILE__, __LINE__, __func__),0)))\n#endif\n\n#if __STDC_VERSION__ >= 201112L && !defined(__cplusplus)\n#define static_assert _Static_assert\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n_Noreturn void __assert_fail (const char *, const char *, int, const char *);\n\n#ifdef __cplusplus\n}\n#endif\n"
  },
  {
    "path": "user.libc/include/bitmap.h",
    "content": "#ifndef __LIBMINOS_BITMAP_H__\n#define __LIBMINOS_BITMAP_H__\n\n#include <inttypes.h>\n#include <strings.h>\n#include <string.h>\n#include <bitops.h>\n\n#include <minos/types.h>\n\nextern void bitmap_set(unsigned long *map, unsigned int start, int len);\nextern void bitmap_clear(unsigned long *map, unsigned int start, int len);\n\nextern unsigned long bitmap_find_next_zero_area_off(unsigned long *map,\n\t\t\t\t\t\t    unsigned long size,\n\t\t\t\t\t\t    unsigned long start,\n\t\t\t\t\t\t    unsigned int nr,\n\t\t\t\t\t\t    unsigned long align_mask,\n\t\t\t\t\t\t    unsigned long align_offset);\n\nstatic inline unsigned long\nbitmap_find_next_zero_area(unsigned long *map,\n\t\t\t   unsigned long size,\n\t\t\t   unsigned long start,\n\t\t\t   unsigned int nr,\n\t\t\t   unsigned long align_mask)\n{\n\treturn bitmap_find_next_zero_area_off(map, size, start, nr,\n\t\t\t\t\t      align_mask, 0);\n}\n\nunsigned long bitmap_find_next_zero_area_align(unsigned long *map,\n\t\t\t\t\t     unsigned long size,\n\t\t\t\t\t     unsigned long start,\n\t\t\t\t\t     unsigned int nr,\n\t\t\t\t\t     unsigned long align);\n\n#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1)))\n#define BITMAP_LAST_WORD_MASK(nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1)))\n\n#define small_const_nbits(nbits) \\\n\t(__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG)\n\nstatic inline void bitmap_zero(unsigned long *dst, int nbits)\n{\n\tif (small_const_nbits(nbits))\n\t\t*dst = 0UL;\n\telse {\n\t\tint len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);\n\t\tmemset(dst, 0, len);\n\t}\n}\n\nstatic inline void bitmap_fill(unsigned long *dst, int nbits)\n{\n\tsize_t nlongs = BITS_TO_LONGS(nbits);\n\tif (!small_const_nbits(nbits)) {\n\t\tint len = (nlongs - 1) * sizeof(unsigned long);\n\t\tmemset(dst, 0xff, len);\n\t}\n\tdst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits);\n}\n\n#endif\n"
  },
  {
    "path": "user.libc/include/bitops.h",
    "content": "#ifndef _LINUX_BITOPS_H\n#define _LINUX_BITOPS_H\n\n#include <inttypes.h>\n#include <strings.h>\n#include <minos/types.h>\n\nstatic inline unsigned long __ffs(unsigned long word)\n{\n\tint num = 0;\n\n#if BITS_PER_LONG == 64\n\tif ((word & 0xffffffff) == 0) {\n\t\tnum += 32;\n\t\tword >>= 32;\n\t}\n#endif\n\tif ((word & 0xffff) == 0) {\n\t\tnum += 16;\n\t\tword >>= 16;\n\t}\n\tif ((word & 0xff) == 0) {\n\t\tnum += 8;\n\t\tword >>= 8;\n\t}\n\tif ((word & 0xf) == 0) {\n\t\tnum += 4;\n\t\tword >>= 4;\n\t}\n\tif ((word & 0x3) == 0) {\n\t\tnum += 2;\n\t\tword >>= 2;\n\t}\n\tif ((word & 0x1) == 0)\n\t\tnum += 1;\n\treturn num;\n}\n\nstatic inline unsigned long __fls(unsigned long word)\n{\n\tint num = BITS_PER_LONG - 1;\n\n#if BITS_PER_LONG == 64\n\tif (!(word & (~0ul << 32))) {\n\t\tnum -= 32;\n\t\tword <<= 32;\n\t}\n#endif\n\tif (!(word & (~0ul << (BITS_PER_LONG-16)))) {\n\t\tnum -= 16;\n\t\tword <<= 16;\n\t}\n\tif (!(word & (~0ul << (BITS_PER_LONG-8)))) {\n\t\tnum -= 8;\n\t\tword <<= 8;\n\t}\n\tif (!(word & (~0ul << (BITS_PER_LONG-4)))) {\n\t\tnum -= 4;\n\t\tword <<= 4;\n\t}\n\tif (!(word & (~0ul << (BITS_PER_LONG-2)))) {\n\t\tnum -= 2;\n\t\tword <<= 2;\n\t}\n\tif (!(word & (~0ul << (BITS_PER_LONG-1))))\n\t\tnum -= 1;\n\treturn num;\n}\n\nstatic inline int fls(int x)\n{\n\tint r = 32;\n\n\tif (!x)\n\t\treturn 0;\n\tif (!(x & 0xffff0000u)) {\n\t\tx <<= 16;\n\t\tr -= 16;\n\t}\n\tif (!(x & 0xff000000u)) {\n\t\tx <<= 8;\n\t\tr -= 8;\n\t}\n\tif (!(x & 0xf0000000u)) {\n\t\tx <<= 4;\n\t\tr -= 4;\n\t}\n\tif (!(x & 0xc0000000u)) {\n\t\tx <<= 2;\n\t\tr -= 2;\n\t}\n\tif (!(x & 0x80000000u)) {\n\t\tx <<= 1;\n\t\tr -= 1;\n\t}\n\treturn r;\n}\n\n#if BITS_PER_LONG == 32\nstatic inline int fls64(uint64_t x)\n{\n\t__u32 h = x >> 32;\n\tif (h)\n\t\treturn fls(h) + 32;\n\treturn fls(x);\n}\n#elif BITS_PER_LONG == 64\nstatic inline int fls64(uint64_t x)\n{\n\tif (x == 0)\n\t\treturn 0;\n\treturn __fls(x) + 1;\n}\n#else\n#error BITS_PER_LONG not 32 or 64\n#endif\n\n#define ffz(x)  __ffs(~(x))\n\nextern unsigned int sw_hweight8(unsigned int w);\nextern unsigned int sw_hweight16(unsigned int w);\nextern unsigned int sw_hweight32(unsigned int w);\nextern unsigned long sw_hweight64(uint64_t w);\n\nunsigned long find_next_bit(const unsigned long *addr, unsigned long size,\n\t\t\t    unsigned long offset);\nunsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,\n\t\t\t\t unsigned long offset);\nunsigned long find_next_bit_loop(const unsigned long *addr, unsigned long size,\n\t\t\t    unsigned long offset);\nunsigned long find_next_zero_bit_loop(const unsigned long *addr, unsigned long size,\n\t\t\t\t unsigned long offset);\nunsigned long find_first_bit(const unsigned long *addr, unsigned long size);\nunsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size);\nunsigned long find_last_bit(const unsigned long *addr, unsigned long size);\n\n#define for_each_set_bit(bit, addr, size) \\\n\tfor ((bit) = find_first_bit((addr), (size));\t\t\\\n\t     (bit) < (size);\t\t\t\t\t\\\n\t     (bit) = find_next_bit((addr), (size), (bit) + 1))\n\n/* same as for_each_set_bit() but use bit as value to start with */\n#define for_each_set_bit_from(bit, addr, size) \\\n\tfor ((bit) = find_next_bit((addr), (size), (bit));\t\\\n\t     (bit) < (size);\t\t\t\t\t\\\n\t     (bit) = find_next_bit((addr), (size), (bit) + 1))\n\n#define for_each_clear_bit(bit, addr, size) \\\n\tfor ((bit) = find_first_zero_bit((addr), (size));\t\\\n\t     (bit) < (size);\t\t\t\t\t\\\n\t     (bit) = find_next_zero_bit((addr), (size), (bit) + 1))\n\n/* same as for_each_clear_bit() but use bit as value to start with */\n#define for_each_clear_bit_from(bit, addr, size) \\\n\tfor ((bit) = find_next_zero_bit((addr), (size), (bit));\t\\\n\t     (bit) < (size);\t\t\t\t\t\\\n\t     (bit) = find_next_zero_bit((addr), (size), (bit) + 1))\n\nstatic inline int get_bitmask_order(unsigned int count)\n{\n\tint order;\n\n\torder = fls(count);\n\treturn order;\n}\n\nstatic inline int get_count_order(unsigned int count)\n{\n\tint order;\n\n\torder = fls(count) - 1;\n\tif (count & (count - 1))\n\t\torder++;\n\treturn order;\n}\n\nstatic inline unsigned long hweight_long(unsigned long w)\n{\n\treturn sizeof(w) == 4 ? sw_hweight32(w) : sw_hweight64(w);\n}\n\nstatic inline uint64_t rol64(uint64_t word, unsigned int shift)\n{\n\treturn (word << shift) | (word >> (64 - shift));\n}\n\nstatic inline uint64_t ror64(uint64_t word, unsigned int shift)\n{\n\treturn (word >> shift) | (word << (64 - shift));\n}\n\nstatic inline uint32_t rol32(uint32_t word, unsigned int shift)\n{\n\treturn (word << shift) | (word >> ((-shift) & 31));\n}\n\nstatic inline uint32_t ror32(uint32_t word, unsigned int shift)\n{\n\treturn (word >> shift) | (word << (32 - shift));\n}\n\nstatic inline uint16_t rol16(uint16_t word, unsigned int shift)\n{\n\treturn (word << shift) | (word >> (16 - shift));\n}\n\nstatic inline uint16_t ror16(uint16_t word, unsigned int shift)\n{\n\treturn (word >> shift) | (word << (16 - shift));\n}\n\nstatic inline uint8_t rol8(uint8_t word, unsigned int shift)\n{\n\treturn (word << shift) | (word >> (8 - shift));\n}\n\nstatic inline uint8_t ror8(uint8_t word, unsigned int shift)\n{\n\treturn (word >> shift) | (word << (8 - shift));\n}\n\nstatic inline int32_t sign_extend32(uint32_t value, int index)\n{\n\tuint8_t shift = 31 - index;\n\treturn (int32_t)(value << shift) >> shift;\n}\n\nstatic inline int64_t sign_extend64(uint64_t value, int index)\n{\n\tuint8_t shift = 63 - index;\n\treturn (int64_t)(value << shift) >> shift;\n}\n\nstatic inline unsigned fls_long(unsigned long l)\n{\n\tif (sizeof(l) == 4)\n\t\treturn fls(l);\n\treturn fls64(l);\n}\n\nstatic inline unsigned long __ffs64(uint64_t word)\n{\n#if BITS_PER_LONG == 32\n\tif (((uint32_t)word) == 0UL)\n\t\treturn __ffs((uint32_t)(word >> 32)) + 32;\n#elif BITS_PER_LONG != 64\n#error BITS_PER_LONG not 32 or 64\n#endif\n\treturn __ffs((unsigned long)word);\n}\n\n#ifndef set_mask_bits\n#define set_mask_bits(ptr, _mask, _bits)\t\\\n({\t\t\t\t\t\t\t\t\\\n\tconst typeof(*ptr) mask = (_mask), bits = (_bits);\t\\\n\ttypeof(*ptr) old, new;\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\\\n\tdo {\t\t\t\t\t\t\t\\\n\t\told = ACCESS_ONCE(*ptr);\t\t\t\\\n\t\tnew = (old & ~mask) | bits;\t\t\t\\\n\t} while (cmpxchg(ptr, old, new) != old);\t\t\\\n\t\t\t\t\t\t\t\t\\\n\tnew;\t\t\t\t\t\t\t\\\n})\n#endif\n\n#ifndef bit_clear_unless\n#define bit_clear_unless(ptr, _clear, _test)\t\\\n({\t\t\t\t\t\t\t\t\\\n\tconst typeof(*ptr) clear = (_clear), test = (_test);\t\\\n\ttypeof(*ptr) old, new;\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\\\n\tdo {\t\t\t\t\t\t\t\\\n\t\told = ACCESS_ONCE(*ptr);\t\t\t\\\n\t\tnew = old & ~clear;\t\t\t\t\\\n\t} while (!(old & test) &&\t\t\t\t\\\n\t\t cmpxchg(ptr, old, new) != old);\t\t\\\n\t\t\t\t\t\t\t\t\\\n\t!(old & test);\t\t\t\t\t\t\\\n})\n#endif\n\n#ifndef find_last_bit\nextern unsigned long find_last_bit(const unsigned long *addr,\n\t\t\t\t   unsigned long size);\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/byteswap.h",
    "content": "#ifndef _BYTESWAP_H\n#define _BYTESWAP_H\n\n#include <features.h>\n#include <stdint.h>\n\nstatic __inline uint16_t __bswap_16(uint16_t __x)\n{\n\treturn __x<<8 | __x>>8;\n}\n\nstatic __inline uint32_t __bswap_32(uint32_t __x)\n{\n\treturn __x>>24 | __x>>8&0xff00 | __x<<8&0xff0000 | __x<<24;\n}\n\nstatic __inline uint64_t __bswap_64(uint64_t __x)\n{\n\treturn __bswap_32(__x)+0ULL<<32 | __bswap_32(__x>>32);\n}\n\n#define bswap_16(x) __bswap_16(x)\n#define bswap_32(x) __bswap_32(x)\n#define bswap_64(x) __bswap_64(x)\n\n#endif\n"
  },
  {
    "path": "user.libc/include/complex.h",
    "content": "#ifndef _COMPLEX_H\n#define _COMPLEX_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define complex _Complex\n#ifdef __GNUC__\n#define _Complex_I (__extension__ (0.0f+1.0fi))\n#else\n#define _Complex_I (0.0f+1.0fi)\n#endif\n#define I _Complex_I\n\ndouble complex cacos(double complex);\nfloat complex cacosf(float complex);\nlong double complex cacosl(long double complex);\n\ndouble complex casin(double complex);\nfloat complex casinf(float complex);\nlong double complex casinl(long double complex);\n\ndouble complex catan(double complex);\nfloat complex catanf(float complex);\nlong double complex catanl(long double complex);\n\ndouble complex ccos(double complex);\nfloat complex ccosf(float complex);\nlong double complex ccosl(long double complex);\n\ndouble complex csin(double complex);\nfloat complex csinf(float complex);\nlong double complex csinl(long double complex);\n\ndouble complex ctan(double complex);\nfloat complex ctanf(float complex);\nlong double complex ctanl(long double complex);\n\ndouble complex cacosh(double complex);\nfloat complex cacoshf(float complex);\nlong double complex cacoshl(long double complex);\n\ndouble complex casinh(double complex);\nfloat complex casinhf(float complex);\nlong double complex casinhl(long double complex);\n\ndouble complex catanh(double complex);\nfloat complex catanhf(float complex);\nlong double complex catanhl(long double complex);\n\ndouble complex ccosh(double complex);\nfloat complex ccoshf(float complex);\nlong double complex ccoshl(long double complex);\n\ndouble complex csinh(double complex);\nfloat complex csinhf(float complex);\nlong double complex csinhl(long double complex);\n\ndouble complex ctanh(double complex);\nfloat complex ctanhf(float complex);\nlong double complex ctanhl(long double complex);\n\ndouble complex cexp(double complex);\nfloat complex cexpf(float complex);\nlong double complex cexpl(long double complex);\n\ndouble complex clog(double complex);\nfloat complex clogf(float complex);\nlong double complex clogl(long double complex);\n\ndouble cabs(double complex);\nfloat cabsf(float complex);\nlong double cabsl(long double complex);\n\ndouble complex cpow(double complex, double complex);\nfloat complex cpowf(float complex, float complex);\nlong double complex cpowl(long double complex, long double complex);\n\ndouble complex csqrt(double complex);\nfloat complex csqrtf(float complex);\nlong double complex csqrtl(long double complex);\n\ndouble carg(double complex);\nfloat cargf(float complex);\nlong double cargl(long double complex);\n\ndouble cimag(double complex);\nfloat cimagf(float complex);\nlong double cimagl(long double complex);\n\ndouble complex conj(double complex);\nfloat complex conjf(float complex);\nlong double complex conjl(long double complex);\n\ndouble complex cproj(double complex);\nfloat complex cprojf(float complex);\nlong double complex cprojl(long double complex);\n\ndouble creal(double complex);\nfloat crealf(float complex);\nlong double creall(long double complex);\n\n#ifndef __cplusplus\n#define __CIMAG(x, t) \\\n\t(+(union { _Complex t __z; t __xy[2]; }){(_Complex t)(x)}.__xy[1])\n\n#define creal(x) ((double)(x))\n#define crealf(x) ((float)(x))\n#define creall(x) ((long double)(x))\n\n#define cimag(x) __CIMAG(x, double)\n#define cimagf(x) __CIMAG(x, float)\n#define cimagl(x) __CIMAG(x, long double)\n#endif\n\n#if __STDC_VERSION__ >= 201112L\n#if defined(_Imaginary_I)\n#define __CMPLX(x, y, t) ((t)(x) + _Imaginary_I*(t)(y))\n#elif defined(__clang__)\n#define __CMPLX(x, y, t) (+(_Complex t){ (t)(x), (t)(y) })\n#else\n#define __CMPLX(x, y, t) (__builtin_complex((t)(x), (t)(y)))\n#endif\n#define CMPLX(x, y) __CMPLX(x, y, double)\n#define CMPLXF(x, y) __CMPLX(x, y, float)\n#define CMPLXL(x, y) __CMPLX(x, y, long double)\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/cpio.h",
    "content": "#ifndef _CPIO_H\n#define _CPIO_H\n\n#define MAGIC \"070707\"\n\n#define C_IRUSR  000400\n#define C_IWUSR  000200\n#define C_IXUSR  000100\n#define C_IRGRP  000040\n#define C_IWGRP  000020\n#define C_IXGRP  000010\n#define C_IROTH  000004\n#define C_IWOTH  000002\n#define C_IXOTH  000001\n\n#define C_ISUID  004000\n#define C_ISGID  002000\n#define C_ISVTX  001000\n\n#define C_ISBLK  060000\n#define C_ISCHR  020000\n#define C_ISDIR  040000\n#define C_ISFIFO 010000\n#define C_ISSOCK 0140000\n#define C_ISLNK  0120000\n#define C_ISCTG  0110000\n#define C_ISREG  0100000\n\n#endif\n"
  },
  {
    "path": "user.libc/include/crypt.h",
    "content": "#ifndef _CRYPT_H\n#define _CRYPT_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nstruct crypt_data {\n\tint initialized;\n\tchar __buf[256];\n};\n\nchar *crypt(const char *, const char *);\nchar *crypt_r(const char *, const char *, struct crypt_data *);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/ctype.h",
    "content": "#ifndef\t_CTYPE_H\n#define\t_CTYPE_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\nint   isalnum(int);\nint   isalpha(int);\nint   isblank(int);\nint   iscntrl(int);\nint   isdigit(int);\nint   isgraph(int);\nint   islower(int);\nint   isprint(int);\nint   ispunct(int);\nint   isspace(int);\nint   isupper(int);\nint   isxdigit(int);\nint   tolower(int);\nint   toupper(int);\n\n#ifndef __cplusplus\nstatic __inline int __isspace(int _c)\n{\n\treturn _c == ' ' || (unsigned)_c-'\\t' < 5;\n}\n\n#define isalpha(a) (0 ? isalpha(a) : (((unsigned)(a)|32)-'a') < 26)\n#define isdigit(a) (0 ? isdigit(a) : ((unsigned)(a)-'0') < 10)\n#define islower(a) (0 ? islower(a) : ((unsigned)(a)-'a') < 26)\n#define isupper(a) (0 ? isupper(a) : ((unsigned)(a)-'A') < 26)\n#define isprint(a) (0 ? isprint(a) : ((unsigned)(a)-0x20) < 0x5f)\n#define isgraph(a) (0 ? isgraph(a) : ((unsigned)(a)-0x21) < 0x5e)\n#define isspace(a) __isspace(a)\n#endif\n\n\n#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \\\n || defined(_BSD_SOURCE)\n\n#define __NEED_locale_t\n#include <bits/alltypes.h>\n\nint   isalnum_l(int, locale_t);\nint   isalpha_l(int, locale_t);\nint   isblank_l(int, locale_t);\nint   iscntrl_l(int, locale_t);\nint   isdigit_l(int, locale_t);\nint   isgraph_l(int, locale_t);\nint   islower_l(int, locale_t);\nint   isprint_l(int, locale_t);\nint   ispunct_l(int, locale_t);\nint   isspace_l(int, locale_t);\nint   isupper_l(int, locale_t);\nint   isxdigit_l(int, locale_t);\nint   tolower_l(int, locale_t);\nint   toupper_l(int, locale_t);\n\nint   isascii(int);\nint   toascii(int);\n#define _tolower(a) ((a)|0x20)\n#define _toupper(a) ((a)&0x5f)\n#define isascii(a) (0 ? isascii(a) : (unsigned)(a) < 128)\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/dirent.h",
    "content": "#ifndef\t_DIRENT_H\n#define\t_DIRENT_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_ino_t\n#define __NEED_off_t\n#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)\n#define __NEED_size_t\n#endif\n\n#include <bits/alltypes.h>\n\n#include <bits/dirent.h>\n\ntypedef struct __dirstream DIR;\n\n#define d_fileno d_ino\n\nint            closedir(DIR *);\nDIR           *fdopendir(int);\nDIR           *opendir(const char *);\nstruct dirent *readdir(DIR *);\nint            readdir_r(DIR *__restrict, struct dirent *__restrict, struct dirent **__restrict);\nvoid           rewinddir(DIR *);\nint            dirfd(DIR *);\nDIR *getcdir(void);\n\nint alphasort(const struct dirent **, const struct dirent **);\nint scandir(const char *, struct dirent ***, int (*)(const struct dirent *), int (*)(const struct dirent **, const struct dirent **));\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\nvoid           seekdir(DIR *, long);\nlong           telldir(DIR *);\n#endif\n\n#define DIRENT_SIZE(len) \\\n\t((long)(&(((struct dirent *)0)->d_name)) + len)\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define DT_UNKNOWN 0\n#define DT_FIFO 1\n#define DT_CHR 2\n#define DT_DIR 4\n#define DT_BLK 6\n#define DT_REG 8\n#define DT_LNK 10\n#define DT_SOCK 12\n#define DT_WHT 14\n#define DT_SRV 16\n#define IFTODT(x) ((x)>>12 & 017)\n#define DTTOIF(x) ((x)<<12)\nint getdents(int, struct dirent *, size_t);\n#endif\n\n#ifdef _GNU_SOURCE\nint versionsort(const struct dirent **, const struct dirent **);\n#endif\n\n#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)\n#define dirent64 dirent\n#define readdir64 readdir\n#define readdir64_r readdir_r\n#define scandir64 scandir\n#define alphasort64 alphasort\n#define versionsort64 versionsort\n#define off64_t off_t\n#define ino64_t ino_t\n#define getdents64 getdents\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/dlfcn.h",
    "content": "#ifndef\t_DLFCN_H\n#define\t_DLFCN_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define RTLD_LAZY   1\n#define RTLD_NOW    2\n#define RTLD_NOLOAD 4\n#define RTLD_NODELETE 4096\n#define RTLD_GLOBAL 256\n#define RTLD_LOCAL  0\n\n#define RTLD_NEXT    ((void *)-1)\n#define RTLD_DEFAULT ((void *)0)\n\n#define RTLD_DI_LINKMAP 2\n\nint    dlclose(void *);\nchar  *dlerror(void);\nvoid  *dlopen(const char *, int);\nvoid  *dlsym(void *__restrict, const char *__restrict);\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\ntypedef struct {\n\tconst char *dli_fname;\n\tvoid *dli_fbase;\n\tconst char *dli_sname;\n\tvoid *dli_saddr;\n} Dl_info;\nint dladdr(const void *, Dl_info *);\nint dlinfo(void *, int, void *);\n#endif\n\n#if _REDIR_TIME64\n__REDIR(dlsym, __dlsym_time64);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/elf.h",
    "content": "#ifndef _ELF_H\n#define _ELF_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\ntypedef uint16_t Elf32_Half;\ntypedef uint16_t Elf64_Half;\n\ntypedef uint32_t Elf32_Word;\ntypedef\tint32_t  Elf32_Sword;\ntypedef uint32_t Elf64_Word;\ntypedef\tint32_t  Elf64_Sword;\n\ntypedef uint64_t Elf32_Xword;\ntypedef\tint64_t  Elf32_Sxword;\ntypedef uint64_t Elf64_Xword;\ntypedef\tint64_t  Elf64_Sxword;\n\ntypedef uint32_t Elf32_Addr;\ntypedef uint64_t Elf64_Addr;\n\ntypedef uint32_t Elf32_Off;\ntypedef uint64_t Elf64_Off;\n\ntypedef uint16_t Elf32_Section;\ntypedef uint16_t Elf64_Section;\n\ntypedef Elf32_Half Elf32_Versym;\ntypedef Elf64_Half Elf64_Versym;\n\n#define EI_NIDENT (16)\n\ntypedef struct {\n  unsigned char\te_ident[EI_NIDENT];\n  Elf32_Half\te_type;\n  Elf32_Half\te_machine;\n  Elf32_Word\te_version;\n  Elf32_Addr\te_entry;\n  Elf32_Off\te_phoff;\n  Elf32_Off\te_shoff;\n  Elf32_Word\te_flags;\n  Elf32_Half\te_ehsize;\n  Elf32_Half\te_phentsize;\n  Elf32_Half\te_phnum;\n  Elf32_Half\te_shentsize;\n  Elf32_Half\te_shnum;\n  Elf32_Half\te_shstrndx;\n} Elf32_Ehdr;\n\ntypedef struct {\n  unsigned char\te_ident[EI_NIDENT];\n  Elf64_Half\te_type;\n  Elf64_Half\te_machine;\n  Elf64_Word\te_version;\n  Elf64_Addr\te_entry;\n  Elf64_Off\te_phoff;\n  Elf64_Off\te_shoff;\n  Elf64_Word\te_flags;\n  Elf64_Half\te_ehsize;\n  Elf64_Half\te_phentsize;\n  Elf64_Half\te_phnum;\n  Elf64_Half\te_shentsize;\n  Elf64_Half\te_shnum;\n  Elf64_Half\te_shstrndx;\n} Elf64_Ehdr;\n\n#define EI_MAG0\t\t0\n#define ELFMAG0\t\t0x7f\n\n#define EI_MAG1\t\t1\n#define ELFMAG1\t\t'E'\n\n#define EI_MAG2\t\t2\n#define ELFMAG2\t\t'L'\n\n#define EI_MAG3\t\t3\n#define ELFMAG3\t\t'F'\n\n\n#define\tELFMAG\t\t\"\\177ELF\"\n#define\tSELFMAG\t\t4\n\n#define EI_CLASS\t4\n#define ELFCLASSNONE\t0\n#define ELFCLASS32\t1\n#define ELFCLASS64\t2\n#define ELFCLASSNUM\t3\n\n#define EI_DATA\t\t5\n#define ELFDATANONE\t0\n#define ELFDATA2LSB\t1\n#define ELFDATA2MSB\t2\n#define ELFDATANUM\t3\n\n#define EI_VERSION\t6\n\n\n#define EI_OSABI\t7\n#define ELFOSABI_NONE\t\t0\n#define ELFOSABI_SYSV\t\t0\n#define ELFOSABI_HPUX\t\t1\n#define ELFOSABI_NETBSD\t\t2\n#define ELFOSABI_LINUX\t\t3\n#define ELFOSABI_GNU\t\t3\n#define ELFOSABI_SOLARIS\t6\n#define ELFOSABI_AIX\t\t7\n#define ELFOSABI_IRIX\t\t8\n#define ELFOSABI_FREEBSD\t9\n#define ELFOSABI_TRU64\t\t10\n#define ELFOSABI_MODESTO\t11\n#define ELFOSABI_OPENBSD\t12\n#define ELFOSABI_ARM\t\t97\n#define ELFOSABI_STANDALONE\t255\n\n#define EI_ABIVERSION\t8\n\n#define EI_PAD\t\t9\n\n\n\n#define ET_NONE\t\t0\n#define ET_REL\t\t1\n#define ET_EXEC\t\t2\n#define ET_DYN\t\t3\n#define ET_CORE\t\t4\n#define\tET_NUM\t\t5\n#define ET_LOOS\t\t0xfe00\n#define ET_HIOS\t\t0xfeff\n#define ET_LOPROC\t0xff00\n#define ET_HIPROC\t0xffff\n\n\n\n#define EM_NONE\t\t 0\n#define EM_M32\t\t 1\n#define EM_SPARC\t 2\n#define EM_386\t\t 3\n#define EM_68K\t\t 4\n#define EM_88K\t\t 5\n#define EM_860\t\t 7\n#define EM_MIPS\t\t 8\n#define EM_S370\t\t 9\n#define EM_MIPS_RS3_LE\t10\n\n#define EM_PARISC\t15\n#define EM_VPP500\t17\n#define EM_SPARC32PLUS\t18\n#define EM_960\t\t19\n#define EM_PPC\t\t20\n#define EM_PPC64\t21\n#define EM_S390\t\t22\n\n#define EM_V800\t\t36\n#define EM_FR20\t\t37\n#define EM_RH32\t\t38\n#define EM_RCE\t\t39\n#define EM_ARM\t\t40\n#define EM_FAKE_ALPHA\t41\n#define EM_SH\t\t42\n#define EM_SPARCV9\t43\n#define EM_TRICORE\t44\n#define EM_ARC\t\t45\n#define EM_H8_300\t46\n#define EM_H8_300H\t47\n#define EM_H8S\t\t48\n#define EM_H8_500\t49\n#define EM_IA_64\t50\n#define EM_MIPS_X\t51\n#define EM_COLDFIRE\t52\n#define EM_68HC12\t53\n#define EM_MMA\t\t54\n#define EM_PCP\t\t55\n#define EM_NCPU\t\t56\n#define EM_NDR1\t\t57\n#define EM_STARCORE\t58\n#define EM_ME16\t\t59\n#define EM_ST100\t60\n#define EM_TINYJ\t61\n#define EM_X86_64\t62\n#define EM_PDSP\t\t63\n\n#define EM_FX66\t\t66\n#define EM_ST9PLUS\t67\n#define EM_ST7\t\t68\n#define EM_68HC16\t69\n#define EM_68HC11\t70\n#define EM_68HC08\t71\n#define EM_68HC05\t72\n#define EM_SVX\t\t73\n#define EM_ST19\t\t74\n#define EM_VAX\t\t75\n#define EM_CRIS\t\t76\n#define EM_JAVELIN\t77\n#define EM_FIREPATH\t78\n#define EM_ZSP\t\t79\n#define EM_MMIX\t\t80\n#define EM_HUANY\t81\n#define EM_PRISM\t82\n#define EM_AVR\t\t83\n#define EM_FR30\t\t84\n#define EM_D10V\t\t85\n#define EM_D30V\t\t86\n#define EM_V850\t\t87\n#define EM_M32R\t\t88\n#define EM_MN10300\t89\n#define EM_MN10200\t90\n#define EM_PJ\t\t91\n#define EM_OR1K\t\t92\n#define EM_OPENRISC\t92\n#define EM_ARC_A5\t93\n#define EM_ARC_COMPACT\t93\n#define EM_XTENSA\t94\n#define EM_VIDEOCORE\t95\n#define EM_TMM_GPP\t96\n#define EM_NS32K\t97\n#define EM_TPC\t\t98\n#define EM_SNP1K\t99\n#define EM_ST200\t100\n#define EM_IP2K\t\t101\n#define EM_MAX\t\t102\n#define EM_CR\t\t103\n#define EM_F2MC16\t104\n#define EM_MSP430\t105\n#define EM_BLACKFIN\t106\n#define EM_SE_C33\t107\n#define EM_SEP\t\t108\n#define EM_ARCA\t\t109\n#define EM_UNICORE\t110\n#define EM_EXCESS\t111\n#define EM_DXP\t\t112\n#define EM_ALTERA_NIOS2 113\n#define EM_CRX\t\t114\n#define EM_XGATE\t115\n#define EM_C166\t\t116\n#define EM_M16C\t\t117\n#define EM_DSPIC30F\t118\n#define EM_CE\t\t119\n#define EM_M32C\t\t120\n#define EM_TSK3000\t131\n#define EM_RS08\t\t132\n#define EM_SHARC\t133\n#define EM_ECOG2\t134\n#define EM_SCORE7\t135\n#define EM_DSP24\t136\n#define EM_VIDEOCORE3\t137\n#define EM_LATTICEMICO32 138\n#define EM_SE_C17\t139\n#define EM_TI_C6000\t140\n#define EM_TI_C2000\t141\n#define EM_TI_C5500\t142\n#define EM_TI_ARP32\t143\n#define EM_TI_PRU\t144\n#define EM_MMDSP_PLUS\t160\n#define EM_CYPRESS_M8C\t161\n#define EM_R32C\t\t162\n#define EM_TRIMEDIA\t163\n#define EM_QDSP6\t164\n#define EM_8051\t\t165\n#define EM_STXP7X\t166\n#define EM_NDS32\t167\n#define EM_ECOG1X\t168\n#define EM_MAXQ30\t169\n#define EM_XIMO16\t170\n#define EM_MANIK\t171\n#define EM_CRAYNV2\t172\n#define EM_RX\t\t173\n#define EM_METAG\t174\n#define EM_MCST_ELBRUS\t175\n#define EM_ECOG16\t176\n#define EM_CR16\t\t177\n#define EM_ETPU\t\t178\n#define EM_SLE9X\t179\n#define EM_L10M\t\t180\n#define EM_K10M\t\t181\n#define EM_AARCH64\t183\n#define EM_AVR32\t185\n#define EM_STM8\t\t186\n#define EM_TILE64\t187\n#define EM_TILEPRO\t188\n#define EM_MICROBLAZE\t189\n#define EM_CUDA\t\t190\n#define EM_TILEGX\t191\n#define EM_CLOUDSHIELD\t192\n#define EM_COREA_1ST\t193\n#define EM_COREA_2ND\t194\n#define EM_ARC_COMPACT2\t195\n#define EM_OPEN8\t196\n#define EM_RL78\t\t197\n#define EM_VIDEOCORE5\t198\n#define EM_78KOR\t199\n#define EM_56800EX\t200\n#define EM_BA1\t\t201\n#define EM_BA2\t\t202\n#define EM_XCORE\t203\n#define EM_MCHP_PIC\t204\n#define EM_KM32\t\t210\n#define EM_KMX32\t211\n#define EM_EMX16\t212\n#define EM_EMX8\t\t213\n#define EM_KVARC\t214\n#define EM_CDP\t\t215\n#define EM_COGE\t\t216\n#define EM_COOL\t\t217\n#define EM_NORC\t\t218\n#define EM_CSR_KALIMBA\t219\n#define EM_Z80\t\t220\n#define EM_VISIUM\t221\n#define EM_FT32\t\t222\n#define EM_MOXIE\t223\n#define EM_AMDGPU\t224\n#define EM_RISCV\t243\n#define EM_BPF\t\t247\n#define EM_CSKY\t\t252\n#define EM_NUM\t\t253\n\n#define EM_ALPHA\t0x9026\n\n#define EV_NONE\t\t0\n#define EV_CURRENT\t1\n#define EV_NUM\t\t2\n\ntypedef struct {\n  Elf32_Word\tsh_name;\n  Elf32_Word\tsh_type;\n  Elf32_Word\tsh_flags;\n  Elf32_Addr\tsh_addr;\n  Elf32_Off\tsh_offset;\n  Elf32_Word\tsh_size;\n  Elf32_Word\tsh_link;\n  Elf32_Word\tsh_info;\n  Elf32_Word\tsh_addralign;\n  Elf32_Word\tsh_entsize;\n} Elf32_Shdr;\n\ntypedef struct {\n  Elf64_Word\tsh_name;\n  Elf64_Word\tsh_type;\n  Elf64_Xword\tsh_flags;\n  Elf64_Addr\tsh_addr;\n  Elf64_Off\tsh_offset;\n  Elf64_Xword\tsh_size;\n  Elf64_Word\tsh_link;\n  Elf64_Word\tsh_info;\n  Elf64_Xword\tsh_addralign;\n  Elf64_Xword\tsh_entsize;\n} Elf64_Shdr;\n\n\n\n#define SHN_UNDEF\t0\n#define SHN_LORESERVE\t0xff00\n#define SHN_LOPROC\t0xff00\n#define SHN_BEFORE\t0xff00\n\n#define SHN_AFTER\t0xff01\n\n#define SHN_HIPROC\t0xff1f\n#define SHN_LOOS\t0xff20\n#define SHN_HIOS\t0xff3f\n#define SHN_ABS\t\t0xfff1\n#define SHN_COMMON\t0xfff2\n#define SHN_XINDEX\t0xffff\n#define SHN_HIRESERVE\t0xffff\n\n\n\n#define SHT_NULL\t  0\n#define SHT_PROGBITS\t  1\n#define SHT_SYMTAB\t  2\n#define SHT_STRTAB\t  3\n#define SHT_RELA\t  4\n#define SHT_HASH\t  5\n#define SHT_DYNAMIC\t  6\n#define SHT_NOTE\t  7\n#define SHT_NOBITS\t  8\n#define SHT_REL\t\t  9\n#define SHT_SHLIB\t  10\n#define SHT_DYNSYM\t  11\n#define SHT_INIT_ARRAY\t  14\n#define SHT_FINI_ARRAY\t  15\n#define SHT_PREINIT_ARRAY 16\n#define SHT_GROUP\t  17\n#define SHT_SYMTAB_SHNDX  18\n#define\tSHT_NUM\t\t  19\n#define SHT_LOOS\t  0x60000000\n#define SHT_GNU_ATTRIBUTES 0x6ffffff5\n#define SHT_GNU_HASH\t  0x6ffffff6\n#define SHT_GNU_LIBLIST\t  0x6ffffff7\n#define SHT_CHECKSUM\t  0x6ffffff8\n#define SHT_LOSUNW\t  0x6ffffffa\n#define SHT_SUNW_move\t  0x6ffffffa\n#define SHT_SUNW_COMDAT   0x6ffffffb\n#define SHT_SUNW_syminfo  0x6ffffffc\n#define SHT_GNU_verdef\t  0x6ffffffd\n#define SHT_GNU_verneed\t  0x6ffffffe\n#define SHT_GNU_versym\t  0x6fffffff\n#define SHT_HISUNW\t  0x6fffffff\n#define SHT_HIOS\t  0x6fffffff\n#define SHT_LOPROC\t  0x70000000\n#define SHT_HIPROC\t  0x7fffffff\n#define SHT_LOUSER\t  0x80000000\n#define SHT_HIUSER\t  0x8fffffff\n\n#define SHF_WRITE\t     (1 << 0)\n#define SHF_ALLOC\t     (1 << 1)\n#define SHF_EXECINSTR\t     (1 << 2)\n#define SHF_MERGE\t     (1 << 4)\n#define SHF_STRINGS\t     (1 << 5)\n#define SHF_INFO_LINK\t     (1 << 6)\n#define SHF_LINK_ORDER\t     (1 << 7)\n#define SHF_OS_NONCONFORMING (1 << 8)\n\n#define SHF_GROUP\t     (1 << 9)\n#define SHF_TLS\t\t     (1 << 10)\n#define SHF_COMPRESSED\t     (1 << 11)\n#define SHF_MASKOS\t     0x0ff00000\n#define SHF_MASKPROC\t     0xf0000000\n#define SHF_ORDERED\t     (1 << 30)\n#define SHF_EXCLUDE\t     (1U << 31)\n\ntypedef struct {\n  Elf32_Word\tch_type;\n  Elf32_Word\tch_size;\n  Elf32_Word\tch_addralign;\n} Elf32_Chdr;\n\ntypedef struct {\n  Elf64_Word\tch_type;\n  Elf64_Word\tch_reserved;\n  Elf64_Xword\tch_size;\n  Elf64_Xword\tch_addralign;\n} Elf64_Chdr;\n\n#define ELFCOMPRESS_ZLIB\t1\n#define ELFCOMPRESS_LOOS\t0x60000000\n#define ELFCOMPRESS_HIOS\t0x6fffffff\n#define ELFCOMPRESS_LOPROC\t0x70000000\n#define ELFCOMPRESS_HIPROC\t0x7fffffff\n\n\n#define GRP_COMDAT\t0x1\n\ntypedef struct {\n  Elf32_Word\tst_name;\n  Elf32_Addr\tst_value;\n  Elf32_Word\tst_size;\n  unsigned char\tst_info;\n  unsigned char\tst_other;\n  Elf32_Section\tst_shndx;\n} Elf32_Sym;\n\ntypedef struct {\n  Elf64_Word\tst_name;\n  unsigned char\tst_info;\n  unsigned char st_other;\n  Elf64_Section\tst_shndx;\n  Elf64_Addr\tst_value;\n  Elf64_Xword\tst_size;\n} Elf64_Sym;\n\ntypedef struct {\n  Elf32_Half si_boundto;\n  Elf32_Half si_flags;\n} Elf32_Syminfo;\n\ntypedef struct {\n  Elf64_Half si_boundto;\n  Elf64_Half si_flags;\n} Elf64_Syminfo;\n\n#define SYMINFO_BT_SELF\t\t0xffff\n#define SYMINFO_BT_PARENT\t0xfffe\n#define SYMINFO_BT_LOWRESERVE\t0xff00\n\n#define SYMINFO_FLG_DIRECT\t0x0001\n#define SYMINFO_FLG_PASSTHRU\t0x0002\n#define SYMINFO_FLG_COPY\t0x0004\n#define SYMINFO_FLG_LAZYLOAD\t0x0008\n\n#define SYMINFO_NONE\t\t0\n#define SYMINFO_CURRENT\t\t1\n#define SYMINFO_NUM\t\t2\n\n#define ELF32_ST_BIND(val)\t\t(((unsigned char) (val)) >> 4)\n#define ELF32_ST_TYPE(val)\t\t((val) & 0xf)\n#define ELF32_ST_INFO(bind, type)\t(((bind) << 4) + ((type) & 0xf))\n\n#define ELF64_ST_BIND(val)\t\tELF32_ST_BIND (val)\n#define ELF64_ST_TYPE(val)\t\tELF32_ST_TYPE (val)\n#define ELF64_ST_INFO(bind, type)\tELF32_ST_INFO ((bind), (type))\n\n#define STB_LOCAL\t0\n#define STB_GLOBAL\t1\n#define STB_WEAK\t2\n#define\tSTB_NUM\t\t3\n#define STB_LOOS\t10\n#define STB_GNU_UNIQUE\t10\n#define STB_HIOS\t12\n#define STB_LOPROC\t13\n#define STB_HIPROC\t15\n\n#define STT_NOTYPE\t0\n#define STT_OBJECT\t1\n#define STT_FUNC\t2\n#define STT_SECTION\t3\n#define STT_FILE\t4\n#define STT_COMMON\t5\n#define STT_TLS\t\t6\n#define\tSTT_NUM\t\t7\n#define STT_LOOS\t10\n#define STT_GNU_IFUNC\t10\n#define STT_HIOS\t12\n#define STT_LOPROC\t13\n#define STT_HIPROC\t15\n\n#define STN_UNDEF\t0\n\n#define ELF32_ST_VISIBILITY(o)\t((o) & 0x03)\n#define ELF64_ST_VISIBILITY(o)\tELF32_ST_VISIBILITY (o)\n\n#define STV_DEFAULT\t0\n#define STV_INTERNAL\t1\n#define STV_HIDDEN\t2\n#define STV_PROTECTED\t3\n\n\n\n\ntypedef struct {\n  Elf32_Addr\tr_offset;\n  Elf32_Word\tr_info;\n} Elf32_Rel;\n\ntypedef struct {\n  Elf64_Addr\tr_offset;\n  Elf64_Xword\tr_info;\n} Elf64_Rel;\n\n\n\ntypedef struct {\n  Elf32_Addr\tr_offset;\n  Elf32_Word\tr_info;\n  Elf32_Sword\tr_addend;\n} Elf32_Rela;\n\ntypedef struct {\n  Elf64_Addr\tr_offset;\n  Elf64_Xword\tr_info;\n  Elf64_Sxword\tr_addend;\n} Elf64_Rela;\n\n\n\n#define ELF32_R_SYM(val)\t\t((val) >> 8)\n#define ELF32_R_TYPE(val)\t\t((val) & 0xff)\n#define ELF32_R_INFO(sym, type)\t\t(((sym) << 8) + ((type) & 0xff))\n\n#define ELF64_R_SYM(i)\t\t\t((i) >> 32)\n#define ELF64_R_TYPE(i)\t\t\t((i) & 0xffffffff)\n#define ELF64_R_INFO(sym,type)\t\t((((Elf64_Xword) (sym)) << 32) + (type))\n\n\n\ntypedef struct {\n  Elf32_Word\tp_type;\n  Elf32_Off\tp_offset;\n  Elf32_Addr\tp_vaddr;\n  Elf32_Addr\tp_paddr;\n  Elf32_Word\tp_filesz;\n  Elf32_Word\tp_memsz;\n  Elf32_Word\tp_flags;\n  Elf32_Word\tp_align;\n} Elf32_Phdr;\n\ntypedef struct {\n  Elf64_Word\tp_type;\n  Elf64_Word\tp_flags;\n  Elf64_Off\tp_offset;\n  Elf64_Addr\tp_vaddr;\n  Elf64_Addr\tp_paddr;\n  Elf64_Xword\tp_filesz;\n  Elf64_Xword\tp_memsz;\n  Elf64_Xword\tp_align;\n} Elf64_Phdr;\n\n\n\n#define\tPT_NULL\t\t0\n#define PT_LOAD\t\t1\n#define PT_DYNAMIC\t2\n#define PT_INTERP\t3\n#define PT_NOTE\t\t4\n#define PT_SHLIB\t5\n#define PT_PHDR\t\t6\n#define PT_TLS\t\t7\n#define\tPT_NUM\t\t8\n#define PT_LOOS\t\t0x60000000\n#define PT_GNU_EH_FRAME\t0x6474e550\n#define PT_GNU_STACK\t0x6474e551\n#define PT_GNU_RELRO\t0x6474e552\n#define PT_GNU_PROPERTY\t0x6474e553\n#define PT_LOSUNW\t0x6ffffffa\n#define PT_SUNWBSS\t0x6ffffffa\n#define PT_SUNWSTACK\t0x6ffffffb\n#define PT_HISUNW\t0x6fffffff\n#define PT_HIOS\t\t0x6fffffff\n#define PT_LOPROC\t0x70000000\n#define PT_HIPROC\t0x7fffffff\n\n\n#define PN_XNUM 0xffff\n\n\n#define PF_X\t\t(1 << 0)\n#define PF_W\t\t(1 << 1)\n#define PF_R\t\t(1 << 2)\n#define PF_MASKOS\t0x0ff00000\n#define PF_MASKPROC\t0xf0000000\n\n\n\n#define NT_PRSTATUS\t1\n#define NT_PRFPREG\t2\n#define NT_FPREGSET\t2\n#define NT_PRPSINFO\t3\n#define NT_PRXREG\t4\n#define NT_TASKSTRUCT\t4\n#define NT_PLATFORM\t5\n#define NT_AUXV\t\t6\n#define NT_GWINDOWS\t7\n#define NT_ASRS\t\t8\n#define NT_PSTATUS\t10\n#define NT_PSINFO\t13\n#define NT_PRCRED\t14\n#define NT_UTSNAME\t15\n#define NT_LWPSTATUS\t16\n#define NT_LWPSINFO\t17\n#define NT_PRFPXREG\t20\n#define NT_SIGINFO\t0x53494749\n#define NT_FILE\t\t0x46494c45\n#define NT_PRXFPREG\t0x46e62b7f\n#define NT_PPC_VMX\t0x100\n#define NT_PPC_SPE\t0x101\n#define NT_PPC_VSX\t0x102\n#define NT_PPC_TAR\t0x103\n#define NT_PPC_PPR\t0x104\n#define NT_PPC_DSCR\t0x105\n#define NT_PPC_EBB\t0x106\n#define NT_PPC_PMU\t0x107\n#define NT_PPC_TM_CGPR\t0x108\n#define NT_PPC_TM_CFPR\t0x109\n#define NT_PPC_TM_CVMX\t0x10a\n#define NT_PPC_TM_CVSX\t0x10b\n#define NT_PPC_TM_SPR\t0x10c\n#define NT_PPC_TM_CTAR\t0x10d\n#define NT_PPC_TM_CPPR\t0x10e\n#define NT_PPC_TM_CDSCR\t0x10f\n#define NT_386_TLS\t0x200\n#define NT_386_IOPERM\t0x201\n#define NT_X86_XSTATE\t0x202\n#define NT_S390_HIGH_GPRS\t0x300\n#define NT_S390_TIMER\t0x301\n#define NT_S390_TODCMP\t0x302\n#define NT_S390_TODPREG\t0x303\n#define NT_S390_CTRS\t0x304\n#define NT_S390_PREFIX\t0x305\n#define NT_S390_LAST_BREAK\t0x306\n#define NT_S390_SYSTEM_CALL\t0x307\n#define NT_S390_TDB\t0x308\n#define NT_S390_VXRS_LOW\t0x309\n#define NT_S390_VXRS_HIGH\t0x30a\n#define NT_S390_GS_CB\t0x30b\n#define NT_S390_GS_BC\t0x30c\n#define NT_S390_RI_CB\t0x30d\n#define NT_ARM_VFP\t0x400\n#define NT_ARM_TLS\t0x401\n#define NT_ARM_HW_BREAK\t0x402\n#define NT_ARM_HW_WATCH\t0x403\n#define NT_ARM_SYSTEM_CALL\t0x404\n#define NT_ARM_SVE\t0x405\n#define NT_ARM_PAC_MASK\t0x406\n#define NT_ARM_PACA_KEYS\t0x407\n#define NT_ARM_PACG_KEYS\t0x408\n#define NT_METAG_CBUF\t0x500\n#define NT_METAG_RPIPE\t0x501\n#define NT_METAG_TLS\t0x502\n#define NT_ARC_V2\t0x600\n#define NT_VMCOREDD\t0x700\n#define NT_MIPS_DSP\t0x800\n#define NT_MIPS_FP_MODE\t0x801\n#define NT_MIPS_MSA\t0x802\n#define NT_VERSION\t1\n\n\n\n\ntypedef struct {\n  Elf32_Sword d_tag;\n  union {\n      Elf32_Word d_val;\n      Elf32_Addr d_ptr;\n  } d_un;\n} Elf32_Dyn;\n\ntypedef struct {\n  Elf64_Sxword d_tag;\n  union {\n      Elf64_Xword d_val;\n      Elf64_Addr d_ptr;\n  } d_un;\n} Elf64_Dyn;\n\n\n\n#define DT_NULL\t\t0\n#define DT_NEEDED\t1\n#define DT_PLTRELSZ\t2\n#define DT_PLTGOT\t3\n#define DT_HASH\t\t4\n#define DT_STRTAB\t5\n#define DT_SYMTAB\t6\n#define DT_RELA\t\t7\n#define DT_RELASZ\t8\n#define DT_RELAENT\t9\n#define DT_STRSZ\t10\n#define DT_SYMENT\t11\n#define DT_INIT\t\t12\n#define DT_FINI\t\t13\n#define DT_SONAME\t14\n#define DT_RPATH\t15\n#define DT_SYMBOLIC\t16\n#define DT_REL\t\t17\n#define DT_RELSZ\t18\n#define DT_RELENT\t19\n#define DT_PLTREL\t20\n#define DT_DEBUG\t21\n#define DT_TEXTREL\t22\n#define DT_JMPREL\t23\n#define\tDT_BIND_NOW\t24\n#define\tDT_INIT_ARRAY\t25\n#define\tDT_FINI_ARRAY\t26\n#define\tDT_INIT_ARRAYSZ\t27\n#define\tDT_FINI_ARRAYSZ\t28\n#define DT_RUNPATH\t29\n#define DT_FLAGS\t30\n#define DT_ENCODING\t32\n#define DT_PREINIT_ARRAY 32\n#define DT_PREINIT_ARRAYSZ 33\n#define DT_SYMTAB_SHNDX\t34\n#define\tDT_NUM\t\t35\n#define DT_LOOS\t\t0x6000000d\n#define DT_HIOS\t\t0x6ffff000\n#define DT_LOPROC\t0x70000000\n#define DT_HIPROC\t0x7fffffff\n#define\tDT_PROCNUM\tDT_MIPS_NUM\n\n#define DT_VALRNGLO\t0x6ffffd00\n#define DT_GNU_PRELINKED 0x6ffffdf5\n#define DT_GNU_CONFLICTSZ 0x6ffffdf6\n#define DT_GNU_LIBLISTSZ 0x6ffffdf7\n#define DT_CHECKSUM\t0x6ffffdf8\n#define DT_PLTPADSZ\t0x6ffffdf9\n#define DT_MOVEENT\t0x6ffffdfa\n#define DT_MOVESZ\t0x6ffffdfb\n#define DT_FEATURE_1\t0x6ffffdfc\n#define DT_POSFLAG_1\t0x6ffffdfd\n\n#define DT_SYMINSZ\t0x6ffffdfe\n#define DT_SYMINENT\t0x6ffffdff\n#define DT_VALRNGHI\t0x6ffffdff\n#define DT_VALTAGIDX(tag)\t(DT_VALRNGHI - (tag))\n#define DT_VALNUM 12\n\n#define DT_ADDRRNGLO\t0x6ffffe00\n#define DT_GNU_HASH\t0x6ffffef5\n#define DT_TLSDESC_PLT\t0x6ffffef6\n#define DT_TLSDESC_GOT\t0x6ffffef7\n#define DT_GNU_CONFLICT\t0x6ffffef8\n#define DT_GNU_LIBLIST\t0x6ffffef9\n#define DT_CONFIG\t0x6ffffefa\n#define DT_DEPAUDIT\t0x6ffffefb\n#define DT_AUDIT\t0x6ffffefc\n#define\tDT_PLTPAD\t0x6ffffefd\n#define\tDT_MOVETAB\t0x6ffffefe\n#define DT_SYMINFO\t0x6ffffeff\n#define DT_ADDRRNGHI\t0x6ffffeff\n#define DT_ADDRTAGIDX(tag)\t(DT_ADDRRNGHI - (tag))\n#define DT_ADDRNUM 11\n\n\n\n#define DT_VERSYM\t0x6ffffff0\n\n#define DT_RELACOUNT\t0x6ffffff9\n#define DT_RELCOUNT\t0x6ffffffa\n\n\n#define DT_FLAGS_1\t0x6ffffffb\n#define\tDT_VERDEF\t0x6ffffffc\n\n#define\tDT_VERDEFNUM\t0x6ffffffd\n#define\tDT_VERNEED\t0x6ffffffe\n\n#define\tDT_VERNEEDNUM\t0x6fffffff\n#define DT_VERSIONTAGIDX(tag)\t(DT_VERNEEDNUM - (tag))\n#define DT_VERSIONTAGNUM 16\n\n\n\n#define DT_AUXILIARY    0x7ffffffd\n#define DT_FILTER       0x7fffffff\n#define DT_EXTRATAGIDX(tag)\t((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)\n#define DT_EXTRANUM\t3\n\n\n#define DF_ORIGIN\t0x00000001\n#define DF_SYMBOLIC\t0x00000002\n#define DF_TEXTREL\t0x00000004\n#define DF_BIND_NOW\t0x00000008\n#define DF_STATIC_TLS\t0x00000010\n\n\n\n#define DF_1_NOW\t0x00000001\n#define DF_1_GLOBAL\t0x00000002\n#define DF_1_GROUP\t0x00000004\n#define DF_1_NODELETE\t0x00000008\n#define DF_1_LOADFLTR\t0x00000010\n#define DF_1_INITFIRST\t0x00000020\n#define DF_1_NOOPEN\t0x00000040\n#define DF_1_ORIGIN\t0x00000080\n#define DF_1_DIRECT\t0x00000100\n#define DF_1_TRANS\t0x00000200\n#define DF_1_INTERPOSE\t0x00000400\n#define DF_1_NODEFLIB\t0x00000800\n#define DF_1_NODUMP\t0x00001000\n#define DF_1_CONFALT\t0x00002000\n#define DF_1_ENDFILTEE\t0x00004000\n#define\tDF_1_DISPRELDNE\t0x00008000\n#define\tDF_1_DISPRELPND\t0x00010000\n#define\tDF_1_NODIRECT\t0x00020000\n#define\tDF_1_IGNMULDEF\t0x00040000\n#define\tDF_1_NOKSYMS\t0x00080000\n#define\tDF_1_NOHDR\t0x00100000\n#define\tDF_1_EDITED\t0x00200000\n#define\tDF_1_NORELOC\t0x00400000\n#define\tDF_1_SYMINTPOSE\t0x00800000\n#define\tDF_1_GLOBAUDIT\t0x01000000\n#define\tDF_1_SINGLETON\t0x02000000\n#define\tDF_1_STUB\t0x04000000\n#define\tDF_1_PIE\t0x08000000\n\n#define DTF_1_PARINIT\t0x00000001\n#define DTF_1_CONFEXP\t0x00000002\n\n\n#define DF_P1_LAZYLOAD\t0x00000001\n#define DF_P1_GROUPPERM\t0x00000002\n\n\n\n\ntypedef struct {\n  Elf32_Half\tvd_version;\n  Elf32_Half\tvd_flags;\n  Elf32_Half\tvd_ndx;\n  Elf32_Half\tvd_cnt;\n  Elf32_Word\tvd_hash;\n  Elf32_Word\tvd_aux;\n  Elf32_Word\tvd_next;\n} Elf32_Verdef;\n\ntypedef struct {\n  Elf64_Half\tvd_version;\n  Elf64_Half\tvd_flags;\n  Elf64_Half\tvd_ndx;\n  Elf64_Half\tvd_cnt;\n  Elf64_Word\tvd_hash;\n  Elf64_Word\tvd_aux;\n  Elf64_Word\tvd_next;\n} Elf64_Verdef;\n\n\n\n#define VER_DEF_NONE\t0\n#define VER_DEF_CURRENT\t1\n#define VER_DEF_NUM\t2\n\n\n#define VER_FLG_BASE\t0x1\n#define VER_FLG_WEAK\t0x2\n\n\n#define\tVER_NDX_LOCAL\t\t0\n#define\tVER_NDX_GLOBAL\t\t1\n#define\tVER_NDX_LORESERVE\t0xff00\n#define\tVER_NDX_ELIMINATE\t0xff01\n\n\n\ntypedef struct {\n  Elf32_Word\tvda_name;\n  Elf32_Word\tvda_next;\n} Elf32_Verdaux;\n\ntypedef struct {\n  Elf64_Word\tvda_name;\n  Elf64_Word\tvda_next;\n} Elf64_Verdaux;\n\n\n\n\ntypedef struct {\n  Elf32_Half\tvn_version;\n  Elf32_Half\tvn_cnt;\n  Elf32_Word\tvn_file;\n  Elf32_Word\tvn_aux;\n  Elf32_Word\tvn_next;\n} Elf32_Verneed;\n\ntypedef struct {\n  Elf64_Half\tvn_version;\n  Elf64_Half\tvn_cnt;\n  Elf64_Word\tvn_file;\n  Elf64_Word\tvn_aux;\n  Elf64_Word\tvn_next;\n} Elf64_Verneed;\n\n\n\n#define VER_NEED_NONE\t 0\n#define VER_NEED_CURRENT 1\n#define VER_NEED_NUM\t 2\n\n\n\ntypedef struct {\n  Elf32_Word\tvna_hash;\n  Elf32_Half\tvna_flags;\n  Elf32_Half\tvna_other;\n  Elf32_Word\tvna_name;\n  Elf32_Word\tvna_next;\n} Elf32_Vernaux;\n\ntypedef struct {\n  Elf64_Word\tvna_hash;\n  Elf64_Half\tvna_flags;\n  Elf64_Half\tvna_other;\n  Elf64_Word\tvna_name;\n  Elf64_Word\tvna_next;\n} Elf64_Vernaux;\n\n\n\n#define VER_FLG_WEAK\t0x2\n\n\n\ntypedef struct {\n  uint32_t a_type;\n  union {\n      uint32_t a_val;\n  } a_un;\n} Elf32_auxv_t;\n\ntypedef struct {\n  uint64_t a_type;\n  union {\n      uint64_t a_val;\n  } a_un;\n} Elf64_auxv_t;\n\n\n\n#define AT_NULL\t\t0\n#define AT_IGNORE\t1\n#define AT_EXECFD\t2\n#define AT_PHDR\t\t3\n#define AT_PHENT\t4\n#define AT_PHNUM\t5\n#define AT_PAGESZ\t6\n#define AT_BASE\t\t7\n#define AT_FLAGS\t8\n#define AT_ENTRY\t9\n#define AT_NOTELF\t10\n#define AT_UID\t\t11\n#define AT_EUID\t\t12\n#define AT_GID\t\t13\n#define AT_EGID\t\t14\n#define AT_CLKTCK\t17\n\n\n#define AT_PLATFORM\t15\n#define AT_HWCAP\t16\n\n\n\n\n#define AT_FPUCW\t18\n\n\n#define AT_DCACHEBSIZE\t19\n#define AT_ICACHEBSIZE\t20\n#define AT_UCACHEBSIZE\t21\n\n\n\n#define AT_IGNOREPPC\t22\n\n#define\tAT_SECURE\t23\n\n#define AT_BASE_PLATFORM 24\n\n#define AT_RANDOM\t25\n\n#define AT_HWCAP2\t26\n\n#define AT_EXECFN\t31\n\n\n\n#define AT_SYSINFO\t32\n#define AT_SYSINFO_EHDR\t33\n\n#define AT_L1I_CACHESHAPE\t34\n#define AT_L1D_CACHESHAPE\t35\n#define AT_L2_CACHESHAPE\t36\n#define AT_L3_CACHESHAPE\t37\n\n#define AT_L1I_CACHESIZE\t40\n#define AT_L1I_CACHEGEOMETRY\t41\n#define AT_L1D_CACHESIZE\t42\n#define AT_L1D_CACHEGEOMETRY\t43\n#define AT_L2_CACHESIZE\t\t44\n#define AT_L2_CACHEGEOMETRY\t45\n#define AT_L3_CACHESIZE\t\t46\n#define AT_L3_CACHEGEOMETRY\t47\n\n#define AT_MINSIGSTKSZ\t\t51\n\n/* dedicated for minos */\n#define AT_ROOTFS_HANDLE 61\n#define AT_CHIYOU_HANDLE 62\n\ntypedef struct {\n  Elf32_Word n_namesz;\n  Elf32_Word n_descsz;\n  Elf32_Word n_type;\n} Elf32_Nhdr;\n\ntypedef struct {\n  Elf64_Word n_namesz;\n  Elf64_Word n_descsz;\n  Elf64_Word n_type;\n} Elf64_Nhdr;\n\n\n\n\n#define ELF_NOTE_SOLARIS\t\"SUNW Solaris\"\n\n\n#define ELF_NOTE_GNU\t\t\"GNU\"\n\n\n\n\n\n#define ELF_NOTE_PAGESIZE_HINT\t1\n\n\n#define NT_GNU_ABI_TAG\t1\n#define ELF_NOTE_ABI\tNT_GNU_ABI_TAG\n\n\n\n#define ELF_NOTE_OS_LINUX\t0\n#define ELF_NOTE_OS_GNU\t\t1\n#define ELF_NOTE_OS_SOLARIS2\t2\n#define ELF_NOTE_OS_FREEBSD\t3\n\n#define NT_GNU_BUILD_ID\t3\n#define NT_GNU_GOLD_VERSION\t4\n#define NT_GNU_PROPERTY_TYPE_0\t5\n\n\n\ntypedef struct {\n  Elf32_Xword m_value;\n  Elf32_Word m_info;\n  Elf32_Word m_poffset;\n  Elf32_Half m_repeat;\n  Elf32_Half m_stride;\n} Elf32_Move;\n\ntypedef struct {\n  Elf64_Xword m_value;\n  Elf64_Xword m_info;\n  Elf64_Xword m_poffset;\n  Elf64_Half m_repeat;\n  Elf64_Half m_stride;\n} Elf64_Move;\n\n\n#define ELF32_M_SYM(info)\t((info) >> 8)\n#define ELF32_M_SIZE(info)\t((unsigned char) (info))\n#define ELF32_M_INFO(sym, size)\t(((sym) << 8) + (unsigned char) (size))\n\n#define ELF64_M_SYM(info)\tELF32_M_SYM (info)\n#define ELF64_M_SIZE(info)\tELF32_M_SIZE (info)\n#define ELF64_M_INFO(sym, size)\tELF32_M_INFO (sym, size)\n\n#define EF_CPU32\t0x00810000\n\n#define R_68K_NONE\t0\n#define R_68K_32\t1\n#define R_68K_16\t2\n#define R_68K_8\t\t3\n#define R_68K_PC32\t4\n#define R_68K_PC16\t5\n#define R_68K_PC8\t6\n#define R_68K_GOT32\t7\n#define R_68K_GOT16\t8\n#define R_68K_GOT8\t9\n#define R_68K_GOT32O\t10\n#define R_68K_GOT16O\t11\n#define R_68K_GOT8O\t12\n#define R_68K_PLT32\t13\n#define R_68K_PLT16\t14\n#define R_68K_PLT8\t15\n#define R_68K_PLT32O\t16\n#define R_68K_PLT16O\t17\n#define R_68K_PLT8O\t18\n#define R_68K_COPY\t19\n#define R_68K_GLOB_DAT\t20\n#define R_68K_JMP_SLOT\t21\n#define R_68K_RELATIVE\t22\n#define R_68K_TLS_GD32\t25\n#define R_68K_TLS_GD16\t26\n#define R_68K_TLS_GD8\t27\n#define R_68K_TLS_LDM32\t28\n#define R_68K_TLS_LDM16\t29\n#define R_68K_TLS_LDM8\t30\n#define R_68K_TLS_LDO32\t31\n#define R_68K_TLS_LDO16\t32\n#define R_68K_TLS_LDO8\t33\n#define R_68K_TLS_IE32\t34\n#define R_68K_TLS_IE16\t35\n#define R_68K_TLS_IE8\t36\n#define R_68K_TLS_LE32\t37\n#define R_68K_TLS_LE16\t38\n#define R_68K_TLS_LE8\t39\n#define R_68K_TLS_DTPMOD32\t40\n#define R_68K_TLS_DTPREL32\t41\n#define R_68K_TLS_TPREL32\t42\n#define R_68K_NUM\t43\n\n#define R_386_NONE\t   0\n#define R_386_32\t   1\n#define R_386_PC32\t   2\n#define R_386_GOT32\t   3\n#define R_386_PLT32\t   4\n#define R_386_COPY\t   5\n#define R_386_GLOB_DAT\t   6\n#define R_386_JMP_SLOT\t   7\n#define R_386_RELATIVE\t   8\n#define R_386_GOTOFF\t   9\n#define R_386_GOTPC\t   10\n#define R_386_32PLT\t   11\n#define R_386_TLS_TPOFF\t   14\n#define R_386_TLS_IE\t   15\n#define R_386_TLS_GOTIE\t   16\n#define R_386_TLS_LE\t   17\n#define R_386_TLS_GD\t   18\n#define R_386_TLS_LDM\t   19\n#define R_386_16\t   20\n#define R_386_PC16\t   21\n#define R_386_8\t\t   22\n#define R_386_PC8\t   23\n#define R_386_TLS_GD_32\t   24\n#define R_386_TLS_GD_PUSH  25\n#define R_386_TLS_GD_CALL  26\n#define R_386_TLS_GD_POP   27\n#define R_386_TLS_LDM_32   28\n#define R_386_TLS_LDM_PUSH 29\n#define R_386_TLS_LDM_CALL 30\n#define R_386_TLS_LDM_POP  31\n#define R_386_TLS_LDO_32   32\n#define R_386_TLS_IE_32\t   33\n#define R_386_TLS_LE_32\t   34\n#define R_386_TLS_DTPMOD32 35\n#define R_386_TLS_DTPOFF32 36\n#define R_386_TLS_TPOFF32  37\n#define R_386_SIZE32       38\n#define R_386_TLS_GOTDESC  39\n#define R_386_TLS_DESC_CALL 40\n#define R_386_TLS_DESC     41\n#define R_386_IRELATIVE\t   42\n#define R_386_GOT32X\t   43\n#define R_386_NUM\t   44\n\n\n\n\n\n#define STT_SPARC_REGISTER\t13\n\n\n\n#define EF_SPARCV9_MM\t\t3\n#define EF_SPARCV9_TSO\t\t0\n#define EF_SPARCV9_PSO\t\t1\n#define EF_SPARCV9_RMO\t\t2\n#define EF_SPARC_LEDATA\t\t0x800000\n#define EF_SPARC_EXT_MASK\t0xFFFF00\n#define EF_SPARC_32PLUS\t\t0x000100\n#define EF_SPARC_SUN_US1\t0x000200\n#define EF_SPARC_HAL_R1\t\t0x000400\n#define EF_SPARC_SUN_US3\t0x000800\n\n\n\n#define R_SPARC_NONE\t\t0\n#define R_SPARC_8\t\t1\n#define R_SPARC_16\t\t2\n#define R_SPARC_32\t\t3\n#define R_SPARC_DISP8\t\t4\n#define R_SPARC_DISP16\t\t5\n#define R_SPARC_DISP32\t\t6\n#define R_SPARC_WDISP30\t\t7\n#define R_SPARC_WDISP22\t\t8\n#define R_SPARC_HI22\t\t9\n#define R_SPARC_22\t\t10\n#define R_SPARC_13\t\t11\n#define R_SPARC_LO10\t\t12\n#define R_SPARC_GOT10\t\t13\n#define R_SPARC_GOT13\t\t14\n#define R_SPARC_GOT22\t\t15\n#define R_SPARC_PC10\t\t16\n#define R_SPARC_PC22\t\t17\n#define R_SPARC_WPLT30\t\t18\n#define R_SPARC_COPY\t\t19\n#define R_SPARC_GLOB_DAT\t20\n#define R_SPARC_JMP_SLOT\t21\n#define R_SPARC_RELATIVE\t22\n#define R_SPARC_UA32\t\t23\n\n\n\n#define R_SPARC_PLT32\t\t24\n#define R_SPARC_HIPLT22\t\t25\n#define R_SPARC_LOPLT10\t\t26\n#define R_SPARC_PCPLT32\t\t27\n#define R_SPARC_PCPLT22\t\t28\n#define R_SPARC_PCPLT10\t\t29\n#define R_SPARC_10\t\t30\n#define R_SPARC_11\t\t31\n#define R_SPARC_64\t\t32\n#define R_SPARC_OLO10\t\t33\n#define R_SPARC_HH22\t\t34\n#define R_SPARC_HM10\t\t35\n#define R_SPARC_LM22\t\t36\n#define R_SPARC_PC_HH22\t\t37\n#define R_SPARC_PC_HM10\t\t38\n#define R_SPARC_PC_LM22\t\t39\n#define R_SPARC_WDISP16\t\t40\n#define R_SPARC_WDISP19\t\t41\n#define R_SPARC_GLOB_JMP\t42\n#define R_SPARC_7\t\t43\n#define R_SPARC_5\t\t44\n#define R_SPARC_6\t\t45\n#define R_SPARC_DISP64\t\t46\n#define R_SPARC_PLT64\t\t47\n#define R_SPARC_HIX22\t\t48\n#define R_SPARC_LOX10\t\t49\n#define R_SPARC_H44\t\t50\n#define R_SPARC_M44\t\t51\n#define R_SPARC_L44\t\t52\n#define R_SPARC_REGISTER\t53\n#define R_SPARC_UA64\t\t54\n#define R_SPARC_UA16\t\t55\n#define R_SPARC_TLS_GD_HI22\t56\n#define R_SPARC_TLS_GD_LO10\t57\n#define R_SPARC_TLS_GD_ADD\t58\n#define R_SPARC_TLS_GD_CALL\t59\n#define R_SPARC_TLS_LDM_HI22\t60\n#define R_SPARC_TLS_LDM_LO10\t61\n#define R_SPARC_TLS_LDM_ADD\t62\n#define R_SPARC_TLS_LDM_CALL\t63\n#define R_SPARC_TLS_LDO_HIX22\t64\n#define R_SPARC_TLS_LDO_LOX10\t65\n#define R_SPARC_TLS_LDO_ADD\t66\n#define R_SPARC_TLS_IE_HI22\t67\n#define R_SPARC_TLS_IE_LO10\t68\n#define R_SPARC_TLS_IE_LD\t69\n#define R_SPARC_TLS_IE_LDX\t70\n#define R_SPARC_TLS_IE_ADD\t71\n#define R_SPARC_TLS_LE_HIX22\t72\n#define R_SPARC_TLS_LE_LOX10\t73\n#define R_SPARC_TLS_DTPMOD32\t74\n#define R_SPARC_TLS_DTPMOD64\t75\n#define R_SPARC_TLS_DTPOFF32\t76\n#define R_SPARC_TLS_DTPOFF64\t77\n#define R_SPARC_TLS_TPOFF32\t78\n#define R_SPARC_TLS_TPOFF64\t79\n#define R_SPARC_GOTDATA_HIX22\t80\n#define R_SPARC_GOTDATA_LOX10\t81\n#define R_SPARC_GOTDATA_OP_HIX22\t82\n#define R_SPARC_GOTDATA_OP_LOX10\t83\n#define R_SPARC_GOTDATA_OP\t84\n#define R_SPARC_H34\t\t85\n#define R_SPARC_SIZE32\t\t86\n#define R_SPARC_SIZE64\t\t87\n#define R_SPARC_GNU_VTINHERIT\t250\n#define R_SPARC_GNU_VTENTRY\t251\n#define R_SPARC_REV32\t\t252\n\n#define R_SPARC_NUM\t\t253\n\n\n\n#define DT_SPARC_REGISTER 0x70000001\n#define DT_SPARC_NUM\t2\n\n\n#define EF_MIPS_NOREORDER   1\n#define EF_MIPS_PIC\t    2\n#define EF_MIPS_CPIC\t    4\n#define EF_MIPS_XGOT\t    8\n#define EF_MIPS_64BIT_WHIRL 16\n#define EF_MIPS_ABI2\t    32\n#define EF_MIPS_ABI_ON32    64\n#define EF_MIPS_FP64\t    512\n#define EF_MIPS_NAN2008     1024\n#define EF_MIPS_ARCH\t    0xf0000000\n\n\n\n#define EF_MIPS_ARCH_1\t    0x00000000\n#define EF_MIPS_ARCH_2\t    0x10000000\n#define EF_MIPS_ARCH_3\t    0x20000000\n#define EF_MIPS_ARCH_4\t    0x30000000\n#define EF_MIPS_ARCH_5\t    0x40000000\n#define EF_MIPS_ARCH_32     0x50000000\n#define EF_MIPS_ARCH_64     0x60000000\n#define EF_MIPS_ARCH_32R2   0x70000000\n#define EF_MIPS_ARCH_64R2   0x80000000\n\n\n#define E_MIPS_ARCH_1\t  0x00000000\n#define E_MIPS_ARCH_2\t  0x10000000\n#define E_MIPS_ARCH_3\t  0x20000000\n#define E_MIPS_ARCH_4\t  0x30000000\n#define E_MIPS_ARCH_5\t  0x40000000\n#define E_MIPS_ARCH_32\t  0x50000000\n#define E_MIPS_ARCH_64\t  0x60000000\n\n\n\n#define SHN_MIPS_ACOMMON    0xff00\n#define SHN_MIPS_TEXT\t    0xff01\n#define SHN_MIPS_DATA\t    0xff02\n#define SHN_MIPS_SCOMMON    0xff03\n#define SHN_MIPS_SUNDEFINED 0xff04\n\n\n\n#define SHT_MIPS_LIBLIST       0x70000000\n#define SHT_MIPS_MSYM\t       0x70000001\n#define SHT_MIPS_CONFLICT      0x70000002\n#define SHT_MIPS_GPTAB\t       0x70000003\n#define SHT_MIPS_UCODE\t       0x70000004\n#define SHT_MIPS_DEBUG\t       0x70000005\n#define SHT_MIPS_REGINFO       0x70000006\n#define SHT_MIPS_PACKAGE       0x70000007\n#define SHT_MIPS_PACKSYM       0x70000008\n#define SHT_MIPS_RELD\t       0x70000009\n#define SHT_MIPS_IFACE         0x7000000b\n#define SHT_MIPS_CONTENT       0x7000000c\n#define SHT_MIPS_OPTIONS       0x7000000d\n#define SHT_MIPS_SHDR\t       0x70000010\n#define SHT_MIPS_FDESC\t       0x70000011\n#define SHT_MIPS_EXTSYM\t       0x70000012\n#define SHT_MIPS_DENSE\t       0x70000013\n#define SHT_MIPS_PDESC\t       0x70000014\n#define SHT_MIPS_LOCSYM\t       0x70000015\n#define SHT_MIPS_AUXSYM\t       0x70000016\n#define SHT_MIPS_OPTSYM\t       0x70000017\n#define SHT_MIPS_LOCSTR\t       0x70000018\n#define SHT_MIPS_LINE\t       0x70000019\n#define SHT_MIPS_RFDESC\t       0x7000001a\n#define SHT_MIPS_DELTASYM      0x7000001b\n#define SHT_MIPS_DELTAINST     0x7000001c\n#define SHT_MIPS_DELTACLASS    0x7000001d\n#define SHT_MIPS_DWARF         0x7000001e\n#define SHT_MIPS_DELTADECL     0x7000001f\n#define SHT_MIPS_SYMBOL_LIB    0x70000020\n#define SHT_MIPS_EVENTS\t       0x70000021\n#define SHT_MIPS_TRANSLATE     0x70000022\n#define SHT_MIPS_PIXIE\t       0x70000023\n#define SHT_MIPS_XLATE\t       0x70000024\n#define SHT_MIPS_XLATE_DEBUG   0x70000025\n#define SHT_MIPS_WHIRL\t       0x70000026\n#define SHT_MIPS_EH_REGION     0x70000027\n#define SHT_MIPS_XLATE_OLD     0x70000028\n#define SHT_MIPS_PDR_EXCEPTION 0x70000029\n\n\n\n#define SHF_MIPS_GPREL\t 0x10000000\n#define SHF_MIPS_MERGE\t 0x20000000\n#define SHF_MIPS_ADDR\t 0x40000000\n#define SHF_MIPS_STRINGS 0x80000000\n#define SHF_MIPS_NOSTRIP 0x08000000\n#define SHF_MIPS_LOCAL\t 0x04000000\n#define SHF_MIPS_NAMES\t 0x02000000\n#define SHF_MIPS_NODUPE\t 0x01000000\n\n\n\n\n\n#define STO_MIPS_DEFAULT\t\t0x0\n#define STO_MIPS_INTERNAL\t\t0x1\n#define STO_MIPS_HIDDEN\t\t\t0x2\n#define STO_MIPS_PROTECTED\t\t0x3\n#define STO_MIPS_PLT\t\t\t0x8\n#define STO_MIPS_SC_ALIGN_UNUSED\t0xff\n\n\n#define STB_MIPS_SPLIT_COMMON\t\t13\n\n\n\ntypedef union {\n  struct {\n      Elf32_Word gt_current_g_value;\n      Elf32_Word gt_unused;\n  } gt_header;\n  struct {\n      Elf32_Word gt_g_value;\n      Elf32_Word gt_bytes;\n  } gt_entry;\n} Elf32_gptab;\n\n\n\ntypedef struct {\n  Elf32_Word\tri_gprmask;\n  Elf32_Word\tri_cprmask[4];\n  Elf32_Sword\tri_gp_value;\n} Elf32_RegInfo;\n\n\n\ntypedef struct {\n  unsigned char kind;\n\n  unsigned char size;\n  Elf32_Section section;\n\n  Elf32_Word info;\n} Elf_Options;\n\n\n\n#define ODK_NULL\t0\n#define ODK_REGINFO\t1\n#define ODK_EXCEPTIONS\t2\n#define ODK_PAD\t\t3\n#define ODK_HWPATCH\t4\n#define ODK_FILL\t5\n#define ODK_TAGS\t6\n#define ODK_HWAND\t7\n#define ODK_HWOR\t8\n\n\n\n#define OEX_FPU_MIN\t0x1f\n#define OEX_FPU_MAX\t0x1f00\n#define OEX_PAGE0\t0x10000\n#define OEX_SMM\t\t0x20000\n#define OEX_FPDBUG\t0x40000\n#define OEX_PRECISEFP\tOEX_FPDBUG\n#define OEX_DISMISS\t0x80000\n\n#define OEX_FPU_INVAL\t0x10\n#define OEX_FPU_DIV0\t0x08\n#define OEX_FPU_OFLO\t0x04\n#define OEX_FPU_UFLO\t0x02\n#define OEX_FPU_INEX\t0x01\n\n\n\n#define OHW_R4KEOP\t0x1\n#define OHW_R8KPFETCH\t0x2\n#define OHW_R5KEOP\t0x4\n#define OHW_R5KCVTL\t0x8\n\n#define OPAD_PREFIX\t0x1\n#define OPAD_POSTFIX\t0x2\n#define OPAD_SYMBOL\t0x4\n\n\n\ntypedef struct {\n  Elf32_Word hwp_flags1;\n  Elf32_Word hwp_flags2;\n} Elf_Options_Hw;\n\n\n\n#define OHWA0_R4KEOP_CHECKED\t0x00000001\n#define OHWA1_R4KEOP_CLEAN\t0x00000002\n\n\n\n#define R_MIPS_NONE\t\t0\n#define R_MIPS_16\t\t1\n#define R_MIPS_32\t\t2\n#define R_MIPS_REL32\t\t3\n#define R_MIPS_26\t\t4\n#define R_MIPS_HI16\t\t5\n#define R_MIPS_LO16\t\t6\n#define R_MIPS_GPREL16\t\t7\n#define R_MIPS_LITERAL\t\t8\n#define R_MIPS_GOT16\t\t9\n#define R_MIPS_PC16\t\t10\n#define R_MIPS_CALL16\t\t11\n#define R_MIPS_GPREL32\t\t12\n\n#define R_MIPS_SHIFT5\t\t16\n#define R_MIPS_SHIFT6\t\t17\n#define R_MIPS_64\t\t18\n#define R_MIPS_GOT_DISP\t\t19\n#define R_MIPS_GOT_PAGE\t\t20\n#define R_MIPS_GOT_OFST\t\t21\n#define R_MIPS_GOT_HI16\t\t22\n#define R_MIPS_GOT_LO16\t\t23\n#define R_MIPS_SUB\t\t24\n#define R_MIPS_INSERT_A\t\t25\n#define R_MIPS_INSERT_B\t\t26\n#define R_MIPS_DELETE\t\t27\n#define R_MIPS_HIGHER\t\t28\n#define R_MIPS_HIGHEST\t\t29\n#define R_MIPS_CALL_HI16\t30\n#define R_MIPS_CALL_LO16\t31\n#define R_MIPS_SCN_DISP\t\t32\n#define R_MIPS_REL16\t\t33\n#define R_MIPS_ADD_IMMEDIATE\t34\n#define R_MIPS_PJUMP\t\t35\n#define R_MIPS_RELGOT\t\t36\n#define R_MIPS_JALR\t\t37\n#define R_MIPS_TLS_DTPMOD32\t38\n#define R_MIPS_TLS_DTPREL32\t39\n#define R_MIPS_TLS_DTPMOD64\t40\n#define R_MIPS_TLS_DTPREL64\t41\n#define R_MIPS_TLS_GD\t\t42\n#define R_MIPS_TLS_LDM\t\t43\n#define R_MIPS_TLS_DTPREL_HI16\t44\n#define R_MIPS_TLS_DTPREL_LO16\t45\n#define R_MIPS_TLS_GOTTPREL\t46\n#define R_MIPS_TLS_TPREL32\t47\n#define R_MIPS_TLS_TPREL64\t48\n#define R_MIPS_TLS_TPREL_HI16\t49\n#define R_MIPS_TLS_TPREL_LO16\t50\n#define R_MIPS_GLOB_DAT\t\t51\n#define R_MIPS_COPY\t\t126\n#define R_MIPS_JUMP_SLOT        127\n\n#define R_MIPS_NUM\t\t128\n\n\n\n#define PT_MIPS_REGINFO\t0x70000000\n#define PT_MIPS_RTPROC  0x70000001\n#define PT_MIPS_OPTIONS 0x70000002\n#define PT_MIPS_ABIFLAGS 0x70000003\n\n\n\n#define PF_MIPS_LOCAL\t0x10000000\n\n\n\n#define DT_MIPS_RLD_VERSION  0x70000001\n#define DT_MIPS_TIME_STAMP   0x70000002\n#define DT_MIPS_ICHECKSUM    0x70000003\n#define DT_MIPS_IVERSION     0x70000004\n#define DT_MIPS_FLAGS\t     0x70000005\n#define DT_MIPS_BASE_ADDRESS 0x70000006\n#define DT_MIPS_MSYM\t     0x70000007\n#define DT_MIPS_CONFLICT     0x70000008\n#define DT_MIPS_LIBLIST\t     0x70000009\n#define DT_MIPS_LOCAL_GOTNO  0x7000000a\n#define DT_MIPS_CONFLICTNO   0x7000000b\n#define DT_MIPS_LIBLISTNO    0x70000010\n#define DT_MIPS_SYMTABNO     0x70000011\n#define DT_MIPS_UNREFEXTNO   0x70000012\n#define DT_MIPS_GOTSYM\t     0x70000013\n#define DT_MIPS_HIPAGENO     0x70000014\n#define DT_MIPS_RLD_MAP\t     0x70000016\n#define DT_MIPS_DELTA_CLASS  0x70000017\n#define DT_MIPS_DELTA_CLASS_NO    0x70000018\n\n#define DT_MIPS_DELTA_INSTANCE    0x70000019\n#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a\n\n#define DT_MIPS_DELTA_RELOC  0x7000001b\n#define DT_MIPS_DELTA_RELOC_NO 0x7000001c\n\n#define DT_MIPS_DELTA_SYM    0x7000001d\n\n#define DT_MIPS_DELTA_SYM_NO 0x7000001e\n\n#define DT_MIPS_DELTA_CLASSSYM 0x70000020\n\n#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021\n\n#define DT_MIPS_CXX_FLAGS    0x70000022\n#define DT_MIPS_PIXIE_INIT   0x70000023\n#define DT_MIPS_SYMBOL_LIB   0x70000024\n#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025\n#define DT_MIPS_LOCAL_GOTIDX 0x70000026\n#define DT_MIPS_HIDDEN_GOTIDX 0x70000027\n#define DT_MIPS_PROTECTED_GOTIDX 0x70000028\n#define DT_MIPS_OPTIONS\t     0x70000029\n#define DT_MIPS_INTERFACE    0x7000002a\n#define DT_MIPS_DYNSTR_ALIGN 0x7000002b\n#define DT_MIPS_INTERFACE_SIZE 0x7000002c\n#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d\n\n#define DT_MIPS_PERF_SUFFIX  0x7000002e\n\n#define DT_MIPS_COMPACT_SIZE 0x7000002f\n#define DT_MIPS_GP_VALUE     0x70000030\n#define DT_MIPS_AUX_DYNAMIC  0x70000031\n\n#define DT_MIPS_PLTGOT\t     0x70000032\n\n#define DT_MIPS_RWPLT        0x70000034\n#define DT_MIPS_RLD_MAP_REL  0x70000035\n#define DT_MIPS_NUM\t     0x36\n\n\n\n#define RHF_NONE\t\t   0\n#define RHF_QUICKSTART\t\t   (1 << 0)\n#define RHF_NOTPOT\t\t   (1 << 1)\n#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2)\n#define RHF_NO_MOVE\t\t   (1 << 3)\n#define RHF_SGI_ONLY\t\t   (1 << 4)\n#define RHF_GUARANTEE_INIT\t   (1 << 5)\n#define RHF_DELTA_C_PLUS_PLUS\t   (1 << 6)\n#define RHF_GUARANTEE_START_INIT   (1 << 7)\n#define RHF_PIXIE\t\t   (1 << 8)\n#define RHF_DEFAULT_DELAY_LOAD\t   (1 << 9)\n#define RHF_REQUICKSTART\t   (1 << 10)\n#define RHF_REQUICKSTARTED\t   (1 << 11)\n#define RHF_CORD\t\t   (1 << 12)\n#define RHF_NO_UNRES_UNDEF\t   (1 << 13)\n#define RHF_RLD_ORDER_SAFE\t   (1 << 14)\n\n\n\ntypedef struct {\n  Elf32_Word l_name;\n  Elf32_Word l_time_stamp;\n  Elf32_Word l_checksum;\n  Elf32_Word l_version;\n  Elf32_Word l_flags;\n} Elf32_Lib;\n\ntypedef struct {\n  Elf64_Word l_name;\n  Elf64_Word l_time_stamp;\n  Elf64_Word l_checksum;\n  Elf64_Word l_version;\n  Elf64_Word l_flags;\n} Elf64_Lib;\n\n\n\n\n#define LL_NONE\t\t  0\n#define LL_EXACT_MATCH\t  (1 << 0)\n#define LL_IGNORE_INT_VER (1 << 1)\n#define LL_REQUIRE_MINOR  (1 << 2)\n#define LL_EXPORTS\t  (1 << 3)\n#define LL_DELAY_LOAD\t  (1 << 4)\n#define LL_DELTA\t  (1 << 5)\n\n\n\ntypedef Elf32_Addr Elf32_Conflict;\n\ntypedef struct {\n  Elf32_Half version;\n  unsigned char isa_level;\n  unsigned char isa_rev;\n  unsigned char gpr_size;\n  unsigned char cpr1_size;\n  unsigned char cpr2_size;\n  unsigned char fp_abi;\n  Elf32_Word isa_ext;\n  Elf32_Word ases;\n  Elf32_Word flags1;\n  Elf32_Word flags2;\n} Elf_MIPS_ABIFlags_v0;\n\n#define MIPS_AFL_REG_NONE\t0x00\n#define MIPS_AFL_REG_32\t\t0x01\n#define MIPS_AFL_REG_64\t\t0x02\n#define MIPS_AFL_REG_128\t0x03\n\n#define MIPS_AFL_ASE_DSP\t0x00000001\n#define MIPS_AFL_ASE_DSPR2\t0x00000002\n#define MIPS_AFL_ASE_EVA\t0x00000004\n#define MIPS_AFL_ASE_MCU\t0x00000008\n#define MIPS_AFL_ASE_MDMX\t0x00000010\n#define MIPS_AFL_ASE_MIPS3D\t0x00000020\n#define MIPS_AFL_ASE_MT\t\t0x00000040\n#define MIPS_AFL_ASE_SMARTMIPS\t0x00000080\n#define MIPS_AFL_ASE_VIRT\t0x00000100\n#define MIPS_AFL_ASE_MSA\t0x00000200\n#define MIPS_AFL_ASE_MIPS16\t0x00000400\n#define MIPS_AFL_ASE_MICROMIPS\t0x00000800\n#define MIPS_AFL_ASE_XPA\t0x00001000\n#define MIPS_AFL_ASE_MASK\t0x00001fff\n\n#define MIPS_AFL_EXT_XLR\t  1\n#define MIPS_AFL_EXT_OCTEON2\t  2\n#define MIPS_AFL_EXT_OCTEONP\t  3\n#define MIPS_AFL_EXT_LOONGSON_3A  4\n#define MIPS_AFL_EXT_OCTEON\t  5\n#define MIPS_AFL_EXT_5900\t  6\n#define MIPS_AFL_EXT_4650\t  7\n#define MIPS_AFL_EXT_4010\t  8\n#define MIPS_AFL_EXT_4100\t  9\n#define MIPS_AFL_EXT_3900\t  10\n#define MIPS_AFL_EXT_10000\t  11\n#define MIPS_AFL_EXT_SB1\t  12\n#define MIPS_AFL_EXT_4111\t  13\n#define MIPS_AFL_EXT_4120\t  14\n#define MIPS_AFL_EXT_5400\t  15\n#define MIPS_AFL_EXT_5500\t  16\n#define MIPS_AFL_EXT_LOONGSON_2E  17\n#define MIPS_AFL_EXT_LOONGSON_2F  18\n\n#define MIPS_AFL_FLAGS1_ODDSPREG  1\n\nenum\n{\n  Val_GNU_MIPS_ABI_FP_ANY = 0,\n  Val_GNU_MIPS_ABI_FP_DOUBLE = 1,\n  Val_GNU_MIPS_ABI_FP_SINGLE = 2,\n  Val_GNU_MIPS_ABI_FP_SOFT = 3,\n  Val_GNU_MIPS_ABI_FP_OLD_64 = 4,\n  Val_GNU_MIPS_ABI_FP_XX = 5,\n  Val_GNU_MIPS_ABI_FP_64 = 6,\n  Val_GNU_MIPS_ABI_FP_64A = 7,\n  Val_GNU_MIPS_ABI_FP_MAX = 7\n};\n\n\n\n\n#define EF_PARISC_TRAPNIL\t0x00010000\n#define EF_PARISC_EXT\t\t0x00020000\n#define EF_PARISC_LSB\t\t0x00040000\n#define EF_PARISC_WIDE\t\t0x00080000\n#define EF_PARISC_NO_KABP\t0x00100000\n\n#define EF_PARISC_LAZYSWAP\t0x00400000\n#define EF_PARISC_ARCH\t\t0x0000ffff\n\n\n\n#define EFA_PARISC_1_0\t\t    0x020b\n#define EFA_PARISC_1_1\t\t    0x0210\n#define EFA_PARISC_2_0\t\t    0x0214\n\n\n\n#define SHN_PARISC_ANSI_COMMON\t0xff00\n\n#define SHN_PARISC_HUGE_COMMON\t0xff01\n\n\n\n#define SHT_PARISC_EXT\t\t0x70000000\n#define SHT_PARISC_UNWIND\t0x70000001\n#define SHT_PARISC_DOC\t\t0x70000002\n\n\n\n#define SHF_PARISC_SHORT\t0x20000000\n#define SHF_PARISC_HUGE\t\t0x40000000\n#define SHF_PARISC_SBP\t\t0x80000000\n\n\n\n#define STT_PARISC_MILLICODE\t13\n\n#define STT_HP_OPAQUE\t\t(STT_LOOS + 0x1)\n#define STT_HP_STUB\t\t(STT_LOOS + 0x2)\n\n\n\n#define R_PARISC_NONE\t\t0\n#define R_PARISC_DIR32\t\t1\n#define R_PARISC_DIR21L\t\t2\n#define R_PARISC_DIR17R\t\t3\n#define R_PARISC_DIR17F\t\t4\n#define R_PARISC_DIR14R\t\t6\n#define R_PARISC_PCREL32\t9\n#define R_PARISC_PCREL21L\t10\n#define R_PARISC_PCREL17R\t11\n#define R_PARISC_PCREL17F\t12\n#define R_PARISC_PCREL14R\t14\n#define R_PARISC_DPREL21L\t18\n#define R_PARISC_DPREL14R\t22\n#define R_PARISC_GPREL21L\t26\n#define R_PARISC_GPREL14R\t30\n#define R_PARISC_LTOFF21L\t34\n#define R_PARISC_LTOFF14R\t38\n#define R_PARISC_SECREL32\t41\n#define R_PARISC_SEGBASE\t48\n#define R_PARISC_SEGREL32\t49\n#define R_PARISC_PLTOFF21L\t50\n#define R_PARISC_PLTOFF14R\t54\n#define R_PARISC_LTOFF_FPTR32\t57\n#define R_PARISC_LTOFF_FPTR21L\t58\n#define R_PARISC_LTOFF_FPTR14R\t62\n#define R_PARISC_FPTR64\t\t64\n#define R_PARISC_PLABEL32\t65\n#define R_PARISC_PLABEL21L\t66\n#define R_PARISC_PLABEL14R\t70\n#define R_PARISC_PCREL64\t72\n#define R_PARISC_PCREL22F\t74\n#define R_PARISC_PCREL14WR\t75\n#define R_PARISC_PCREL14DR\t76\n#define R_PARISC_PCREL16F\t77\n#define R_PARISC_PCREL16WF\t78\n#define R_PARISC_PCREL16DF\t79\n#define R_PARISC_DIR64\t\t80\n#define R_PARISC_DIR14WR\t83\n#define R_PARISC_DIR14DR\t84\n#define R_PARISC_DIR16F\t\t85\n#define R_PARISC_DIR16WF\t86\n#define R_PARISC_DIR16DF\t87\n#define R_PARISC_GPREL64\t88\n#define R_PARISC_GPREL14WR\t91\n#define R_PARISC_GPREL14DR\t92\n#define R_PARISC_GPREL16F\t93\n#define R_PARISC_GPREL16WF\t94\n#define R_PARISC_GPREL16DF\t95\n#define R_PARISC_LTOFF64\t96\n#define R_PARISC_LTOFF14WR\t99\n#define R_PARISC_LTOFF14DR\t100\n#define R_PARISC_LTOFF16F\t101\n#define R_PARISC_LTOFF16WF\t102\n#define R_PARISC_LTOFF16DF\t103\n#define R_PARISC_SECREL64\t104\n#define R_PARISC_SEGREL64\t112\n#define R_PARISC_PLTOFF14WR\t115\n#define R_PARISC_PLTOFF14DR\t116\n#define R_PARISC_PLTOFF16F\t117\n#define R_PARISC_PLTOFF16WF\t118\n#define R_PARISC_PLTOFF16DF\t119\n#define R_PARISC_LTOFF_FPTR64\t120\n#define R_PARISC_LTOFF_FPTR14WR\t123\n#define R_PARISC_LTOFF_FPTR14DR\t124\n#define R_PARISC_LTOFF_FPTR16F\t125\n#define R_PARISC_LTOFF_FPTR16WF\t126\n#define R_PARISC_LTOFF_FPTR16DF\t127\n#define R_PARISC_LORESERVE\t128\n#define R_PARISC_COPY\t\t128\n#define R_PARISC_IPLT\t\t129\n#define R_PARISC_EPLT\t\t130\n#define R_PARISC_TPREL32\t153\n#define R_PARISC_TPREL21L\t154\n#define R_PARISC_TPREL14R\t158\n#define R_PARISC_LTOFF_TP21L\t162\n#define R_PARISC_LTOFF_TP14R\t166\n#define R_PARISC_LTOFF_TP14F\t167\n#define R_PARISC_TPREL64\t216\n#define R_PARISC_TPREL14WR\t219\n#define R_PARISC_TPREL14DR\t220\n#define R_PARISC_TPREL16F\t221\n#define R_PARISC_TPREL16WF\t222\n#define R_PARISC_TPREL16DF\t223\n#define R_PARISC_LTOFF_TP64\t224\n#define R_PARISC_LTOFF_TP14WR\t227\n#define R_PARISC_LTOFF_TP14DR\t228\n#define R_PARISC_LTOFF_TP16F\t229\n#define R_PARISC_LTOFF_TP16WF\t230\n#define R_PARISC_LTOFF_TP16DF\t231\n#define R_PARISC_GNU_VTENTRY\t232\n#define R_PARISC_GNU_VTINHERIT\t233\n#define R_PARISC_TLS_GD21L\t234\n#define R_PARISC_TLS_GD14R\t235\n#define R_PARISC_TLS_GDCALL\t236\n#define R_PARISC_TLS_LDM21L\t237\n#define R_PARISC_TLS_LDM14R\t238\n#define R_PARISC_TLS_LDMCALL\t239\n#define R_PARISC_TLS_LDO21L\t240\n#define R_PARISC_TLS_LDO14R\t241\n#define R_PARISC_TLS_DTPMOD32\t242\n#define R_PARISC_TLS_DTPMOD64\t243\n#define R_PARISC_TLS_DTPOFF32\t244\n#define R_PARISC_TLS_DTPOFF64\t245\n#define R_PARISC_TLS_LE21L\tR_PARISC_TPREL21L\n#define R_PARISC_TLS_LE14R\tR_PARISC_TPREL14R\n#define R_PARISC_TLS_IE21L\tR_PARISC_LTOFF_TP21L\n#define R_PARISC_TLS_IE14R\tR_PARISC_LTOFF_TP14R\n#define R_PARISC_TLS_TPREL32\tR_PARISC_TPREL32\n#define R_PARISC_TLS_TPREL64\tR_PARISC_TPREL64\n#define R_PARISC_HIRESERVE\t255\n\n\n\n#define PT_HP_TLS\t\t(PT_LOOS + 0x0)\n#define PT_HP_CORE_NONE\t\t(PT_LOOS + 0x1)\n#define PT_HP_CORE_VERSION\t(PT_LOOS + 0x2)\n#define PT_HP_CORE_KERNEL\t(PT_LOOS + 0x3)\n#define PT_HP_CORE_COMM\t\t(PT_LOOS + 0x4)\n#define PT_HP_CORE_PROC\t\t(PT_LOOS + 0x5)\n#define PT_HP_CORE_LOADABLE\t(PT_LOOS + 0x6)\n#define PT_HP_CORE_STACK\t(PT_LOOS + 0x7)\n#define PT_HP_CORE_SHM\t\t(PT_LOOS + 0x8)\n#define PT_HP_CORE_MMF\t\t(PT_LOOS + 0x9)\n#define PT_HP_PARALLEL\t\t(PT_LOOS + 0x10)\n#define PT_HP_FASTBIND\t\t(PT_LOOS + 0x11)\n#define PT_HP_OPT_ANNOT\t\t(PT_LOOS + 0x12)\n#define PT_HP_HSL_ANNOT\t\t(PT_LOOS + 0x13)\n#define PT_HP_STACK\t\t(PT_LOOS + 0x14)\n\n#define PT_PARISC_ARCHEXT\t0x70000000\n#define PT_PARISC_UNWIND\t0x70000001\n\n\n\n#define PF_PARISC_SBP\t\t0x08000000\n\n#define PF_HP_PAGE_SIZE\t\t0x00100000\n#define PF_HP_FAR_SHARED\t0x00200000\n#define PF_HP_NEAR_SHARED\t0x00400000\n#define PF_HP_CODE\t\t0x01000000\n#define PF_HP_MODIFY\t\t0x02000000\n#define PF_HP_LAZYSWAP\t\t0x04000000\n#define PF_HP_SBP\t\t0x08000000\n\n\n\n\n\n\n#define EF_ALPHA_32BIT\t\t1\n#define EF_ALPHA_CANRELAX\t2\n\n\n\n\n#define SHT_ALPHA_DEBUG\t\t0x70000001\n#define SHT_ALPHA_REGINFO\t0x70000002\n\n\n\n#define SHF_ALPHA_GPREL\t\t0x10000000\n\n\n#define STO_ALPHA_NOPV\t\t0x80\n#define STO_ALPHA_STD_GPLOAD\t0x88\n\n\n\n#define R_ALPHA_NONE\t\t0\n#define R_ALPHA_REFLONG\t\t1\n#define R_ALPHA_REFQUAD\t\t2\n#define R_ALPHA_GPREL32\t\t3\n#define R_ALPHA_LITERAL\t\t4\n#define R_ALPHA_LITUSE\t\t5\n#define R_ALPHA_GPDISP\t\t6\n#define R_ALPHA_BRADDR\t\t7\n#define R_ALPHA_HINT\t\t8\n#define R_ALPHA_SREL16\t\t9\n#define R_ALPHA_SREL32\t\t10\n#define R_ALPHA_SREL64\t\t11\n#define R_ALPHA_GPRELHIGH\t17\n#define R_ALPHA_GPRELLOW\t18\n#define R_ALPHA_GPREL16\t\t19\n#define R_ALPHA_COPY\t\t24\n#define R_ALPHA_GLOB_DAT\t25\n#define R_ALPHA_JMP_SLOT\t26\n#define R_ALPHA_RELATIVE\t27\n#define R_ALPHA_TLS_GD_HI\t28\n#define R_ALPHA_TLSGD\t\t29\n#define R_ALPHA_TLS_LDM\t\t30\n#define R_ALPHA_DTPMOD64\t31\n#define R_ALPHA_GOTDTPREL\t32\n#define R_ALPHA_DTPREL64\t33\n#define R_ALPHA_DTPRELHI\t34\n#define R_ALPHA_DTPRELLO\t35\n#define R_ALPHA_DTPREL16\t36\n#define R_ALPHA_GOTTPREL\t37\n#define R_ALPHA_TPREL64\t\t38\n#define R_ALPHA_TPRELHI\t\t39\n#define R_ALPHA_TPRELLO\t\t40\n#define R_ALPHA_TPREL16\t\t41\n\n#define R_ALPHA_NUM\t\t46\n\n\n#define LITUSE_ALPHA_ADDR\t0\n#define LITUSE_ALPHA_BASE\t1\n#define LITUSE_ALPHA_BYTOFF\t2\n#define LITUSE_ALPHA_JSR\t3\n#define LITUSE_ALPHA_TLS_GD\t4\n#define LITUSE_ALPHA_TLS_LDM\t5\n\n\n#define DT_ALPHA_PLTRO\t\t(DT_LOPROC + 0)\n#define DT_ALPHA_NUM\t\t1\n\n\n\n\n#define EF_PPC_EMB\t\t0x80000000\n\n\n#define EF_PPC_RELOCATABLE\t0x00010000\n#define EF_PPC_RELOCATABLE_LIB\t0x00008000\n\n\n\n#define R_PPC_NONE\t\t0\n#define R_PPC_ADDR32\t\t1\n#define R_PPC_ADDR24\t\t2\n#define R_PPC_ADDR16\t\t3\n#define R_PPC_ADDR16_LO\t\t4\n#define R_PPC_ADDR16_HI\t\t5\n#define R_PPC_ADDR16_HA\t\t6\n#define R_PPC_ADDR14\t\t7\n#define R_PPC_ADDR14_BRTAKEN\t8\n#define R_PPC_ADDR14_BRNTAKEN\t9\n#define R_PPC_REL24\t\t10\n#define R_PPC_REL14\t\t11\n#define R_PPC_REL14_BRTAKEN\t12\n#define R_PPC_REL14_BRNTAKEN\t13\n#define R_PPC_GOT16\t\t14\n#define R_PPC_GOT16_LO\t\t15\n#define R_PPC_GOT16_HI\t\t16\n#define R_PPC_GOT16_HA\t\t17\n#define R_PPC_PLTREL24\t\t18\n#define R_PPC_COPY\t\t19\n#define R_PPC_GLOB_DAT\t\t20\n#define R_PPC_JMP_SLOT\t\t21\n#define R_PPC_RELATIVE\t\t22\n#define R_PPC_LOCAL24PC\t\t23\n#define R_PPC_UADDR32\t\t24\n#define R_PPC_UADDR16\t\t25\n#define R_PPC_REL32\t\t26\n#define R_PPC_PLT32\t\t27\n#define R_PPC_PLTREL32\t\t28\n#define R_PPC_PLT16_LO\t\t29\n#define R_PPC_PLT16_HI\t\t30\n#define R_PPC_PLT16_HA\t\t31\n#define R_PPC_SDAREL16\t\t32\n#define R_PPC_SECTOFF\t\t33\n#define R_PPC_SECTOFF_LO\t34\n#define R_PPC_SECTOFF_HI\t35\n#define R_PPC_SECTOFF_HA\t36\n\n\n#define R_PPC_TLS\t\t67\n#define R_PPC_DTPMOD32\t\t68\n#define R_PPC_TPREL16\t\t69\n#define R_PPC_TPREL16_LO\t70\n#define R_PPC_TPREL16_HI\t71\n#define R_PPC_TPREL16_HA\t72\n#define R_PPC_TPREL32\t\t73\n#define R_PPC_DTPREL16\t\t74\n#define R_PPC_DTPREL16_LO\t75\n#define R_PPC_DTPREL16_HI\t76\n#define R_PPC_DTPREL16_HA\t77\n#define R_PPC_DTPREL32\t\t78\n#define R_PPC_GOT_TLSGD16\t79\n#define R_PPC_GOT_TLSGD16_LO\t80\n#define R_PPC_GOT_TLSGD16_HI\t81\n#define R_PPC_GOT_TLSGD16_HA\t82\n#define R_PPC_GOT_TLSLD16\t83\n#define R_PPC_GOT_TLSLD16_LO\t84\n#define R_PPC_GOT_TLSLD16_HI\t85\n#define R_PPC_GOT_TLSLD16_HA\t86\n#define R_PPC_GOT_TPREL16\t87\n#define R_PPC_GOT_TPREL16_LO\t88\n#define R_PPC_GOT_TPREL16_HI\t89\n#define R_PPC_GOT_TPREL16_HA\t90\n#define R_PPC_GOT_DTPREL16\t91\n#define R_PPC_GOT_DTPREL16_LO\t92\n#define R_PPC_GOT_DTPREL16_HI\t93\n#define R_PPC_GOT_DTPREL16_HA\t94\n#define R_PPC_TLSGD\t\t95\n#define R_PPC_TLSLD\t\t96\n\n\n#define R_PPC_EMB_NADDR32\t101\n#define R_PPC_EMB_NADDR16\t102\n#define R_PPC_EMB_NADDR16_LO\t103\n#define R_PPC_EMB_NADDR16_HI\t104\n#define R_PPC_EMB_NADDR16_HA\t105\n#define R_PPC_EMB_SDAI16\t106\n#define R_PPC_EMB_SDA2I16\t107\n#define R_PPC_EMB_SDA2REL\t108\n#define R_PPC_EMB_SDA21\t\t109\n#define R_PPC_EMB_MRKREF\t110\n#define R_PPC_EMB_RELSEC16\t111\n#define R_PPC_EMB_RELST_LO\t112\n#define R_PPC_EMB_RELST_HI\t113\n#define R_PPC_EMB_RELST_HA\t114\n#define R_PPC_EMB_BIT_FLD\t115\n#define R_PPC_EMB_RELSDA\t116\n\n\n#define R_PPC_DIAB_SDA21_LO\t180\n#define R_PPC_DIAB_SDA21_HI\t181\n#define R_PPC_DIAB_SDA21_HA\t182\n#define R_PPC_DIAB_RELSDA_LO\t183\n#define R_PPC_DIAB_RELSDA_HI\t184\n#define R_PPC_DIAB_RELSDA_HA\t185\n\n\n#define R_PPC_IRELATIVE\t\t248\n\n\n#define R_PPC_REL16\t\t249\n#define R_PPC_REL16_LO\t\t250\n#define R_PPC_REL16_HI\t\t251\n#define R_PPC_REL16_HA\t\t252\n\n\n\n#define R_PPC_TOC16\t\t255\n\n\n#define DT_PPC_GOT\t\t(DT_LOPROC + 0)\n#define DT_PPC_OPT\t\t(DT_LOPROC + 1)\n#define DT_PPC_NUM\t\t2\n\n#define PPC_OPT_TLS\t\t1\n\n\n#define R_PPC64_NONE\t\tR_PPC_NONE\n#define R_PPC64_ADDR32\t\tR_PPC_ADDR32\n#define R_PPC64_ADDR24\t\tR_PPC_ADDR24\n#define R_PPC64_ADDR16\t\tR_PPC_ADDR16\n#define R_PPC64_ADDR16_LO\tR_PPC_ADDR16_LO\n#define R_PPC64_ADDR16_HI\tR_PPC_ADDR16_HI\n#define R_PPC64_ADDR16_HA\tR_PPC_ADDR16_HA\n#define R_PPC64_ADDR14\t\tR_PPC_ADDR14\n#define R_PPC64_ADDR14_BRTAKEN\tR_PPC_ADDR14_BRTAKEN\n#define R_PPC64_ADDR14_BRNTAKEN\tR_PPC_ADDR14_BRNTAKEN\n#define R_PPC64_REL24\t\tR_PPC_REL24\n#define R_PPC64_REL14\t\tR_PPC_REL14\n#define R_PPC64_REL14_BRTAKEN\tR_PPC_REL14_BRTAKEN\n#define R_PPC64_REL14_BRNTAKEN\tR_PPC_REL14_BRNTAKEN\n#define R_PPC64_GOT16\t\tR_PPC_GOT16\n#define R_PPC64_GOT16_LO\tR_PPC_GOT16_LO\n#define R_PPC64_GOT16_HI\tR_PPC_GOT16_HI\n#define R_PPC64_GOT16_HA\tR_PPC_GOT16_HA\n\n#define R_PPC64_COPY\t\tR_PPC_COPY\n#define R_PPC64_GLOB_DAT\tR_PPC_GLOB_DAT\n#define R_PPC64_JMP_SLOT\tR_PPC_JMP_SLOT\n#define R_PPC64_RELATIVE\tR_PPC_RELATIVE\n\n#define R_PPC64_UADDR32\t\tR_PPC_UADDR32\n#define R_PPC64_UADDR16\t\tR_PPC_UADDR16\n#define R_PPC64_REL32\t\tR_PPC_REL32\n#define R_PPC64_PLT32\t\tR_PPC_PLT32\n#define R_PPC64_PLTREL32\tR_PPC_PLTREL32\n#define R_PPC64_PLT16_LO\tR_PPC_PLT16_LO\n#define R_PPC64_PLT16_HI\tR_PPC_PLT16_HI\n#define R_PPC64_PLT16_HA\tR_PPC_PLT16_HA\n\n#define R_PPC64_SECTOFF\t\tR_PPC_SECTOFF\n#define R_PPC64_SECTOFF_LO\tR_PPC_SECTOFF_LO\n#define R_PPC64_SECTOFF_HI\tR_PPC_SECTOFF_HI\n#define R_PPC64_SECTOFF_HA\tR_PPC_SECTOFF_HA\n#define R_PPC64_ADDR30\t\t37\n#define R_PPC64_ADDR64\t\t38\n#define R_PPC64_ADDR16_HIGHER\t39\n#define R_PPC64_ADDR16_HIGHERA\t40\n#define R_PPC64_ADDR16_HIGHEST\t41\n#define R_PPC64_ADDR16_HIGHESTA\t42\n#define R_PPC64_UADDR64\t\t43\n#define R_PPC64_REL64\t\t44\n#define R_PPC64_PLT64\t\t45\n#define R_PPC64_PLTREL64\t46\n#define R_PPC64_TOC16\t\t47\n#define R_PPC64_TOC16_LO\t48\n#define R_PPC64_TOC16_HI\t49\n#define R_PPC64_TOC16_HA\t50\n#define R_PPC64_TOC\t\t51\n#define R_PPC64_PLTGOT16\t52\n#define R_PPC64_PLTGOT16_LO\t53\n#define R_PPC64_PLTGOT16_HI\t54\n#define R_PPC64_PLTGOT16_HA\t55\n\n#define R_PPC64_ADDR16_DS\t56\n#define R_PPC64_ADDR16_LO_DS\t57\n#define R_PPC64_GOT16_DS\t58\n#define R_PPC64_GOT16_LO_DS\t59\n#define R_PPC64_PLT16_LO_DS\t60\n#define R_PPC64_SECTOFF_DS\t61\n#define R_PPC64_SECTOFF_LO_DS\t62\n#define R_PPC64_TOC16_DS\t63\n#define R_PPC64_TOC16_LO_DS\t64\n#define R_PPC64_PLTGOT16_DS\t65\n#define R_PPC64_PLTGOT16_LO_DS\t66\n\n\n#define R_PPC64_TLS\t\t67\n#define R_PPC64_DTPMOD64\t68\n#define R_PPC64_TPREL16\t\t69\n#define R_PPC64_TPREL16_LO\t70\n#define R_PPC64_TPREL16_HI\t71\n#define R_PPC64_TPREL16_HA\t72\n#define R_PPC64_TPREL64\t\t73\n#define R_PPC64_DTPREL16\t74\n#define R_PPC64_DTPREL16_LO\t75\n#define R_PPC64_DTPREL16_HI\t76\n#define R_PPC64_DTPREL16_HA\t77\n#define R_PPC64_DTPREL64\t78\n#define R_PPC64_GOT_TLSGD16\t79\n#define R_PPC64_GOT_TLSGD16_LO\t80\n#define R_PPC64_GOT_TLSGD16_HI\t81\n#define R_PPC64_GOT_TLSGD16_HA\t82\n#define R_PPC64_GOT_TLSLD16\t83\n#define R_PPC64_GOT_TLSLD16_LO\t84\n#define R_PPC64_GOT_TLSLD16_HI\t85\n#define R_PPC64_GOT_TLSLD16_HA\t86\n#define R_PPC64_GOT_TPREL16_DS\t87\n#define R_PPC64_GOT_TPREL16_LO_DS 88\n#define R_PPC64_GOT_TPREL16_HI\t89\n#define R_PPC64_GOT_TPREL16_HA\t90\n#define R_PPC64_GOT_DTPREL16_DS\t91\n#define R_PPC64_GOT_DTPREL16_LO_DS 92\n#define R_PPC64_GOT_DTPREL16_HI\t93\n#define R_PPC64_GOT_DTPREL16_HA\t94\n#define R_PPC64_TPREL16_DS\t95\n#define R_PPC64_TPREL16_LO_DS\t96\n#define R_PPC64_TPREL16_HIGHER\t97\n#define R_PPC64_TPREL16_HIGHERA\t98\n#define R_PPC64_TPREL16_HIGHEST\t99\n#define R_PPC64_TPREL16_HIGHESTA 100\n#define R_PPC64_DTPREL16_DS\t101\n#define R_PPC64_DTPREL16_LO_DS\t102\n#define R_PPC64_DTPREL16_HIGHER\t103\n#define R_PPC64_DTPREL16_HIGHERA 104\n#define R_PPC64_DTPREL16_HIGHEST 105\n#define R_PPC64_DTPREL16_HIGHESTA 106\n#define R_PPC64_TLSGD\t\t107\n#define R_PPC64_TLSLD\t\t108\n#define R_PPC64_TOCSAVE\t\t109\n#define R_PPC64_ADDR16_HIGH\t110\n#define R_PPC64_ADDR16_HIGHA\t111\n#define R_PPC64_TPREL16_HIGH\t112\n#define R_PPC64_TPREL16_HIGHA\t113\n#define R_PPC64_DTPREL16_HIGH\t114\n#define R_PPC64_DTPREL16_HIGHA\t115\n\n\n#define R_PPC64_JMP_IREL\t247\n#define R_PPC64_IRELATIVE\t248\n#define R_PPC64_REL16\t\t249\n#define R_PPC64_REL16_LO\t250\n#define R_PPC64_REL16_HI\t251\n#define R_PPC64_REL16_HA\t252\n\n#define EF_PPC64_ABI\t3\n\n#define DT_PPC64_GLINK  (DT_LOPROC + 0)\n#define DT_PPC64_OPD\t(DT_LOPROC + 1)\n#define DT_PPC64_OPDSZ\t(DT_LOPROC + 2)\n#define DT_PPC64_OPT\t(DT_LOPROC + 3)\n#define DT_PPC64_NUM\t4\n\n#define PPC64_OPT_TLS\t\t1\n#define PPC64_OPT_MULTI_TOC\t2\n#define PPC64_OPT_LOCALENTRY\t4\n\n#define STO_PPC64_LOCAL_BIT\t5\n#define STO_PPC64_LOCAL_MASK\t0xe0\n#define PPC64_LOCAL_ENTRY_OFFSET(x) (1 << (((x)&0xe0)>>5) & 0xfc)\n\n\n#define EF_ARM_RELEXEC\t\t0x01\n#define EF_ARM_HASENTRY\t\t0x02\n#define EF_ARM_INTERWORK\t0x04\n#define EF_ARM_APCS_26\t\t0x08\n#define EF_ARM_APCS_FLOAT\t0x10\n#define EF_ARM_PIC\t\t0x20\n#define EF_ARM_ALIGN8\t\t0x40\n#define EF_ARM_NEW_ABI\t\t0x80\n#define EF_ARM_OLD_ABI\t\t0x100\n#define EF_ARM_SOFT_FLOAT\t0x200\n#define EF_ARM_VFP_FLOAT\t0x400\n#define EF_ARM_MAVERICK_FLOAT\t0x800\n\n#define EF_ARM_ABI_FLOAT_SOFT\t0x200\n#define EF_ARM_ABI_FLOAT_HARD\t0x400\n\n\n#define EF_ARM_SYMSARESORTED\t0x04\n#define EF_ARM_DYNSYMSUSESEGIDX\t0x08\n#define EF_ARM_MAPSYMSFIRST\t0x10\n#define EF_ARM_EABIMASK\t\t0XFF000000\n\n\n#define EF_ARM_BE8\t    0x00800000\n#define EF_ARM_LE8\t    0x00400000\n\n#define EF_ARM_EABI_VERSION(flags)\t((flags) & EF_ARM_EABIMASK)\n#define EF_ARM_EABI_UNKNOWN\t0x00000000\n#define EF_ARM_EABI_VER1\t0x01000000\n#define EF_ARM_EABI_VER2\t0x02000000\n#define EF_ARM_EABI_VER3\t0x03000000\n#define EF_ARM_EABI_VER4\t0x04000000\n#define EF_ARM_EABI_VER5\t0x05000000\n\n\n#define STT_ARM_TFUNC\t\tSTT_LOPROC\n#define STT_ARM_16BIT\t\tSTT_HIPROC\n\n\n#define SHF_ARM_ENTRYSECT\t0x10000000\n#define SHF_ARM_COMDEF\t\t0x80000000\n\n\n\n#define PF_ARM_SB\t\t0x10000000\n\n#define PF_ARM_PI\t\t0x20000000\n#define PF_ARM_ABS\t\t0x40000000\n\n\n#define PT_ARM_EXIDX\t\t(PT_LOPROC + 1)\n\n\n#define SHT_ARM_EXIDX\t\t(SHT_LOPROC + 1)\n#define SHT_ARM_PREEMPTMAP\t(SHT_LOPROC + 2)\n#define SHT_ARM_ATTRIBUTES\t(SHT_LOPROC + 3)\n\n#define R_AARCH64_NONE            0\n#define R_AARCH64_P32_ABS32\t1\n#define R_AARCH64_P32_COPY\t180\n#define R_AARCH64_P32_GLOB_DAT\t181\n#define R_AARCH64_P32_JUMP_SLOT\t182\n#define R_AARCH64_P32_RELATIVE\t183\n#define R_AARCH64_P32_TLS_DTPMOD 184\n#define R_AARCH64_P32_TLS_DTPREL 185\n#define R_AARCH64_P32_TLS_TPREL\t186\n#define R_AARCH64_P32_TLSDESC\t187\n#define R_AARCH64_P32_IRELATIVE\t188\n#define R_AARCH64_ABS64         257\n#define R_AARCH64_ABS32         258\n#define R_AARCH64_ABS16\t\t259\n#define R_AARCH64_PREL64\t260\n#define R_AARCH64_PREL32\t261\n#define R_AARCH64_PREL16\t262\n#define R_AARCH64_MOVW_UABS_G0\t263\n#define R_AARCH64_MOVW_UABS_G0_NC 264\n#define R_AARCH64_MOVW_UABS_G1\t265\n#define R_AARCH64_MOVW_UABS_G1_NC 266\n#define R_AARCH64_MOVW_UABS_G2\t267\n#define R_AARCH64_MOVW_UABS_G2_NC 268\n#define R_AARCH64_MOVW_UABS_G3\t269\n#define R_AARCH64_MOVW_SABS_G0\t270\n#define R_AARCH64_MOVW_SABS_G1\t271\n#define R_AARCH64_MOVW_SABS_G2\t272\n#define R_AARCH64_LD_PREL_LO19\t273\n#define R_AARCH64_ADR_PREL_LO21\t274\n#define R_AARCH64_ADR_PREL_PG_HI21 275\n#define R_AARCH64_ADR_PREL_PG_HI21_NC 276\n#define R_AARCH64_ADD_ABS_LO12_NC 277\n#define R_AARCH64_LDST8_ABS_LO12_NC 278\n#define R_AARCH64_TSTBR14\t279\n#define R_AARCH64_CONDBR19\t280\n#define R_AARCH64_JUMP26\t282\n#define R_AARCH64_CALL26\t283\n#define R_AARCH64_LDST16_ABS_LO12_NC 284\n#define R_AARCH64_LDST32_ABS_LO12_NC 285\n#define R_AARCH64_LDST64_ABS_LO12_NC 286\n#define R_AARCH64_MOVW_PREL_G0\t287\n#define R_AARCH64_MOVW_PREL_G0_NC 288\n#define R_AARCH64_MOVW_PREL_G1\t289\n#define R_AARCH64_MOVW_PREL_G1_NC 290\n#define R_AARCH64_MOVW_PREL_G2\t291\n#define R_AARCH64_MOVW_PREL_G2_NC 292\n#define R_AARCH64_MOVW_PREL_G3\t293\n#define R_AARCH64_LDST128_ABS_LO12_NC 299\n#define R_AARCH64_MOVW_GOTOFF_G0 300\n#define R_AARCH64_MOVW_GOTOFF_G0_NC 301\n#define R_AARCH64_MOVW_GOTOFF_G1 302\n#define R_AARCH64_MOVW_GOTOFF_G1_NC 303\n#define R_AARCH64_MOVW_GOTOFF_G2 304\n#define R_AARCH64_MOVW_GOTOFF_G2_NC 305\n#define R_AARCH64_MOVW_GOTOFF_G3 306\n#define R_AARCH64_GOTREL64\t307\n#define R_AARCH64_GOTREL32\t308\n#define R_AARCH64_GOT_LD_PREL19\t309\n#define R_AARCH64_LD64_GOTOFF_LO15 310\n#define R_AARCH64_ADR_GOT_PAGE\t311\n#define R_AARCH64_LD64_GOT_LO12_NC 312\n#define R_AARCH64_LD64_GOTPAGE_LO15 313\n#define R_AARCH64_TLSGD_ADR_PREL21 512\n#define R_AARCH64_TLSGD_ADR_PAGE21 513\n#define R_AARCH64_TLSGD_ADD_LO12_NC 514\n#define R_AARCH64_TLSGD_MOVW_G1\t515\n#define R_AARCH64_TLSGD_MOVW_G0_NC 516\n#define R_AARCH64_TLSLD_ADR_PREL21 517\n#define R_AARCH64_TLSLD_ADR_PAGE21 518\n#define R_AARCH64_TLSLD_ADD_LO12_NC 519\n#define R_AARCH64_TLSLD_MOVW_G1\t520\n#define R_AARCH64_TLSLD_MOVW_G0_NC 521\n#define R_AARCH64_TLSLD_LD_PREL19 522\n#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523\n#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524\n#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525\n#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526\n#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527\n#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528\n#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529\n#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530\n#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531\n#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532\n#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533\n#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534\n#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535\n#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536\n#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537\n#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538\n#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539\n#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540\n#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541\n#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542\n#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543\n#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544\n#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545\n#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546\n#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547\n#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548\n#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549\n#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550\n#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551\n#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552\n#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553\n#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554\n#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555\n#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556\n#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557\n#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558\n#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559\n#define R_AARCH64_TLSDESC_LD_PREL19 560\n#define R_AARCH64_TLSDESC_ADR_PREL21 561\n#define R_AARCH64_TLSDESC_ADR_PAGE21 562\n#define R_AARCH64_TLSDESC_LD64_LO12 563\n#define R_AARCH64_TLSDESC_ADD_LO12 564\n#define R_AARCH64_TLSDESC_OFF_G1 565\n#define R_AARCH64_TLSDESC_OFF_G0_NC 566\n#define R_AARCH64_TLSDESC_LDR\t567\n#define R_AARCH64_TLSDESC_ADD\t568\n#define R_AARCH64_TLSDESC_CALL\t569\n#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570\n#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571\n#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572\n#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573\n#define R_AARCH64_COPY         1024\n#define R_AARCH64_GLOB_DAT     1025\n#define R_AARCH64_JUMP_SLOT    1026\n#define R_AARCH64_RELATIVE     1027\n#define R_AARCH64_TLS_DTPMOD   1028\n#define R_AARCH64_TLS_DTPMOD64 1028\n#define R_AARCH64_TLS_DTPREL   1029\n#define R_AARCH64_TLS_DTPREL64 1029\n#define R_AARCH64_TLS_TPREL    1030\n#define R_AARCH64_TLS_TPREL64  1030\n#define R_AARCH64_TLSDESC      1031\n\n\n#define R_ARM_NONE\t\t0\n#define R_ARM_PC24\t\t1\n#define R_ARM_ABS32\t\t2\n#define R_ARM_REL32\t\t3\n#define R_ARM_PC13\t\t4\n#define R_ARM_ABS16\t\t5\n#define R_ARM_ABS12\t\t6\n#define R_ARM_THM_ABS5\t\t7\n#define R_ARM_ABS8\t\t8\n#define R_ARM_SBREL32\t\t9\n#define R_ARM_THM_PC22\t\t10\n#define R_ARM_THM_PC8\t\t11\n#define R_ARM_AMP_VCALL9\t12\n#define R_ARM_TLS_DESC\t\t13\n#define R_ARM_THM_SWI8\t\t14\n#define R_ARM_XPC25\t\t15\n#define R_ARM_THM_XPC22\t\t16\n#define R_ARM_TLS_DTPMOD32\t17\n#define R_ARM_TLS_DTPOFF32\t18\n#define R_ARM_TLS_TPOFF32\t19\n#define R_ARM_COPY\t\t20\n#define R_ARM_GLOB_DAT\t\t21\n#define R_ARM_JUMP_SLOT\t\t22\n#define R_ARM_RELATIVE\t\t23\n#define R_ARM_GOTOFF\t\t24\n#define R_ARM_GOTPC\t\t25\n#define R_ARM_GOT32\t\t26\n#define R_ARM_PLT32\t\t27\n#define R_ARM_CALL\t\t28\n#define R_ARM_JUMP24\t\t29\n#define R_ARM_THM_JUMP24\t30\n#define R_ARM_BASE_ABS\t\t31\n#define R_ARM_ALU_PCREL_7_0\t32\n#define R_ARM_ALU_PCREL_15_8\t33\n#define R_ARM_ALU_PCREL_23_15\t34\n#define R_ARM_LDR_SBREL_11_0\t35\n#define R_ARM_ALU_SBREL_19_12\t36\n#define R_ARM_ALU_SBREL_27_20\t37\n#define R_ARM_TARGET1\t\t38\n#define R_ARM_SBREL31\t\t39\n#define R_ARM_V4BX\t\t40\n#define R_ARM_TARGET2\t\t41\n#define R_ARM_PREL31\t\t42\n#define R_ARM_MOVW_ABS_NC\t43\n#define R_ARM_MOVT_ABS\t\t44\n#define R_ARM_MOVW_PREL_NC\t45\n#define R_ARM_MOVT_PREL\t\t46\n#define R_ARM_THM_MOVW_ABS_NC\t47\n#define R_ARM_THM_MOVT_ABS\t48\n#define R_ARM_THM_MOVW_PREL_NC\t49\n#define R_ARM_THM_MOVT_PREL\t50\n#define R_ARM_THM_JUMP19\t51\n#define R_ARM_THM_JUMP6\t\t52\n#define R_ARM_THM_ALU_PREL_11_0\t53\n#define R_ARM_THM_PC12\t\t54\n#define R_ARM_ABS32_NOI\t\t55\n#define R_ARM_REL32_NOI\t\t56\n#define R_ARM_ALU_PC_G0_NC\t57\n#define R_ARM_ALU_PC_G0\t\t58\n#define R_ARM_ALU_PC_G1_NC\t59\n#define R_ARM_ALU_PC_G1\t\t60\n#define R_ARM_ALU_PC_G2\t\t61\n#define R_ARM_LDR_PC_G1\t\t62\n#define R_ARM_LDR_PC_G2\t\t63\n#define R_ARM_LDRS_PC_G0\t64\n#define R_ARM_LDRS_PC_G1\t65\n#define R_ARM_LDRS_PC_G2\t66\n#define R_ARM_LDC_PC_G0\t\t67\n#define R_ARM_LDC_PC_G1\t\t68\n#define R_ARM_LDC_PC_G2\t\t69\n#define R_ARM_ALU_SB_G0_NC\t70\n#define R_ARM_ALU_SB_G0\t\t71\n#define R_ARM_ALU_SB_G1_NC\t72\n#define R_ARM_ALU_SB_G1\t\t73\n#define R_ARM_ALU_SB_G2\t\t74\n#define R_ARM_LDR_SB_G0\t\t75\n#define R_ARM_LDR_SB_G1\t\t76\n#define R_ARM_LDR_SB_G2\t\t77\n#define R_ARM_LDRS_SB_G0\t78\n#define R_ARM_LDRS_SB_G1\t79\n#define R_ARM_LDRS_SB_G2\t80\n#define R_ARM_LDC_SB_G0\t\t81\n#define R_ARM_LDC_SB_G1\t\t82\n#define R_ARM_LDC_SB_G2\t\t83\n#define R_ARM_MOVW_BREL_NC\t84\n#define R_ARM_MOVT_BREL\t\t85\n#define R_ARM_MOVW_BREL\t\t86\n#define R_ARM_THM_MOVW_BREL_NC\t87\n#define R_ARM_THM_MOVT_BREL\t88\n#define R_ARM_THM_MOVW_BREL\t89\n#define R_ARM_TLS_GOTDESC\t90\n#define R_ARM_TLS_CALL\t\t91\n#define R_ARM_TLS_DESCSEQ\t92\n#define R_ARM_THM_TLS_CALL\t93\n#define R_ARM_PLT32_ABS\t\t94\n#define R_ARM_GOT_ABS\t\t95\n#define R_ARM_GOT_PREL\t\t96\n#define R_ARM_GOT_BREL12\t97\n#define R_ARM_GOTOFF12\t\t98\n#define R_ARM_GOTRELAX\t\t99\n#define R_ARM_GNU_VTENTRY\t100\n#define R_ARM_GNU_VTINHERIT\t101\n#define R_ARM_THM_PC11\t\t102\n#define R_ARM_THM_PC9\t\t103\n#define R_ARM_TLS_GD32\t\t104\n\n#define R_ARM_TLS_LDM32\t\t105\n\n#define R_ARM_TLS_LDO32\t\t106\n\n#define R_ARM_TLS_IE32\t\t107\n\n#define R_ARM_TLS_LE32\t\t108\n#define R_ARM_TLS_LDO12\t\t109\n#define R_ARM_TLS_LE12\t\t110\n#define R_ARM_TLS_IE12GP\t111\n#define R_ARM_ME_TOO\t\t128\n#define R_ARM_THM_TLS_DESCSEQ\t129\n#define R_ARM_THM_TLS_DESCSEQ16\t129\n#define R_ARM_THM_TLS_DESCSEQ32\t130\n#define R_ARM_THM_GOT_BREL12\t131\n#define R_ARM_IRELATIVE\t\t160\n#define R_ARM_RXPC25\t\t249\n#define R_ARM_RSBREL32\t\t250\n#define R_ARM_THM_RPC22\t\t251\n#define R_ARM_RREL32\t\t252\n#define R_ARM_RABS22\t\t253\n#define R_ARM_RPC24\t\t254\n#define R_ARM_RBASE\t\t255\n\n#define R_ARM_NUM\t\t256\n\n\n#define R_CKCORE_NONE               0\n#define R_CKCORE_ADDR32             1\n#define R_CKCORE_PCRELIMM8BY4       2\n#define R_CKCORE_PCRELIMM11BY2      3\n#define R_CKCORE_PCREL32            5\n#define R_CKCORE_PCRELJSR_IMM11BY2  6\n#define R_CKCORE_RELATIVE           9\n#define R_CKCORE_COPY               10\n#define R_CKCORE_GLOB_DAT           11\n#define R_CKCORE_JUMP_SLOT          12\n#define R_CKCORE_GOTOFF             13\n#define R_CKCORE_GOTPC              14\n#define R_CKCORE_GOT32              15\n#define R_CKCORE_PLT32              16\n#define R_CKCORE_ADDRGOT            17\n#define R_CKCORE_ADDRPLT            18\n#define R_CKCORE_PCREL_IMM26BY2     19\n#define R_CKCORE_PCREL_IMM16BY2     20\n#define R_CKCORE_PCREL_IMM16BY4     21\n#define R_CKCORE_PCREL_IMM10BY2     22\n#define R_CKCORE_PCREL_IMM10BY4     23\n#define R_CKCORE_ADDR_HI16          24\n#define R_CKCORE_ADDR_LO16          25\n#define R_CKCORE_GOTPC_HI16         26\n#define R_CKCORE_GOTPC_LO16         27\n#define R_CKCORE_GOTOFF_HI16        28\n#define R_CKCORE_GOTOFF_LO16        29\n#define R_CKCORE_GOT12              30\n#define R_CKCORE_GOT_HI16           31\n#define R_CKCORE_GOT_LO16           32\n#define R_CKCORE_PLT12              33\n#define R_CKCORE_PLT_HI16           34\n#define R_CKCORE_PLT_LO16           35\n#define R_CKCORE_ADDRGOT_HI16       36\n#define R_CKCORE_ADDRGOT_LO16       37\n#define R_CKCORE_ADDRPLT_HI16       38\n#define R_CKCORE_ADDRPLT_LO16       39\n#define R_CKCORE_PCREL_JSR_IMM26BY2 40\n#define R_CKCORE_TOFFSET_LO16       41\n#define R_CKCORE_DOFFSET_LO16       42\n#define R_CKCORE_PCREL_IMM18BY2     43\n#define R_CKCORE_DOFFSET_IMM18      44\n#define R_CKCORE_DOFFSET_IMM18BY2   45\n#define R_CKCORE_DOFFSET_IMM18BY4   46\n#define R_CKCORE_GOT_IMM18BY4       48\n#define R_CKCORE_PLT_IMM18BY4       49\n#define R_CKCORE_PCREL_IMM7BY4      50\n#define R_CKCORE_TLS_LE32           51\n#define R_CKCORE_TLS_IE32           52\n#define R_CKCORE_TLS_GD32           53\n#define R_CKCORE_TLS_LDM32          54\n#define R_CKCORE_TLS_LDO32          55\n#define R_CKCORE_TLS_DTPMOD32       56\n#define R_CKCORE_TLS_DTPOFF32       57\n#define R_CKCORE_TLS_TPOFF32        58\n\n\n#define EF_IA_64_MASKOS\t\t0x0000000f\n#define EF_IA_64_ABI64\t\t0x00000010\n#define EF_IA_64_ARCH\t\t0xff000000\n\n\n#define PT_IA_64_ARCHEXT\t(PT_LOPROC + 0)\n#define PT_IA_64_UNWIND\t\t(PT_LOPROC + 1)\n#define PT_IA_64_HP_OPT_ANOT\t(PT_LOOS + 0x12)\n#define PT_IA_64_HP_HSL_ANOT\t(PT_LOOS + 0x13)\n#define PT_IA_64_HP_STACK\t(PT_LOOS + 0x14)\n\n\n#define PF_IA_64_NORECOV\t0x80000000\n\n\n#define SHT_IA_64_EXT\t\t(SHT_LOPROC + 0)\n#define SHT_IA_64_UNWIND\t(SHT_LOPROC + 1)\n\n\n#define SHF_IA_64_SHORT\t\t0x10000000\n#define SHF_IA_64_NORECOV\t0x20000000\n\n\n#define DT_IA_64_PLT_RESERVE\t(DT_LOPROC + 0)\n#define DT_IA_64_NUM\t\t1\n\n\n#define R_IA64_NONE\t\t0x00\n#define R_IA64_IMM14\t\t0x21\n#define R_IA64_IMM22\t\t0x22\n#define R_IA64_IMM64\t\t0x23\n#define R_IA64_DIR32MSB\t\t0x24\n#define R_IA64_DIR32LSB\t\t0x25\n#define R_IA64_DIR64MSB\t\t0x26\n#define R_IA64_DIR64LSB\t\t0x27\n#define R_IA64_GPREL22\t\t0x2a\n#define R_IA64_GPREL64I\t\t0x2b\n#define R_IA64_GPREL32MSB\t0x2c\n#define R_IA64_GPREL32LSB\t0x2d\n#define R_IA64_GPREL64MSB\t0x2e\n#define R_IA64_GPREL64LSB\t0x2f\n#define R_IA64_LTOFF22\t\t0x32\n#define R_IA64_LTOFF64I\t\t0x33\n#define R_IA64_PLTOFF22\t\t0x3a\n#define R_IA64_PLTOFF64I\t0x3b\n#define R_IA64_PLTOFF64MSB\t0x3e\n#define R_IA64_PLTOFF64LSB\t0x3f\n#define R_IA64_FPTR64I\t\t0x43\n#define R_IA64_FPTR32MSB\t0x44\n#define R_IA64_FPTR32LSB\t0x45\n#define R_IA64_FPTR64MSB\t0x46\n#define R_IA64_FPTR64LSB\t0x47\n#define R_IA64_PCREL60B\t\t0x48\n#define R_IA64_PCREL21B\t\t0x49\n#define R_IA64_PCREL21M\t\t0x4a\n#define R_IA64_PCREL21F\t\t0x4b\n#define R_IA64_PCREL32MSB\t0x4c\n#define R_IA64_PCREL32LSB\t0x4d\n#define R_IA64_PCREL64MSB\t0x4e\n#define R_IA64_PCREL64LSB\t0x4f\n#define R_IA64_LTOFF_FPTR22\t0x52\n#define R_IA64_LTOFF_FPTR64I\t0x53\n#define R_IA64_LTOFF_FPTR32MSB\t0x54\n#define R_IA64_LTOFF_FPTR32LSB\t0x55\n#define R_IA64_LTOFF_FPTR64MSB\t0x56\n#define R_IA64_LTOFF_FPTR64LSB\t0x57\n#define R_IA64_SEGREL32MSB\t0x5c\n#define R_IA64_SEGREL32LSB\t0x5d\n#define R_IA64_SEGREL64MSB\t0x5e\n#define R_IA64_SEGREL64LSB\t0x5f\n#define R_IA64_SECREL32MSB\t0x64\n#define R_IA64_SECREL32LSB\t0x65\n#define R_IA64_SECREL64MSB\t0x66\n#define R_IA64_SECREL64LSB\t0x67\n#define R_IA64_REL32MSB\t\t0x6c\n#define R_IA64_REL32LSB\t\t0x6d\n#define R_IA64_REL64MSB\t\t0x6e\n#define R_IA64_REL64LSB\t\t0x6f\n#define R_IA64_LTV32MSB\t\t0x74\n#define R_IA64_LTV32LSB\t\t0x75\n#define R_IA64_LTV64MSB\t\t0x76\n#define R_IA64_LTV64LSB\t\t0x77\n#define R_IA64_PCREL21BI\t0x79\n#define R_IA64_PCREL22\t\t0x7a\n#define R_IA64_PCREL64I\t\t0x7b\n#define R_IA64_IPLTMSB\t\t0x80\n#define R_IA64_IPLTLSB\t\t0x81\n#define R_IA64_COPY\t\t0x84\n#define R_IA64_SUB\t\t0x85\n#define R_IA64_LTOFF22X\t\t0x86\n#define R_IA64_LDXMOV\t\t0x87\n#define R_IA64_TPREL14\t\t0x91\n#define R_IA64_TPREL22\t\t0x92\n#define R_IA64_TPREL64I\t\t0x93\n#define R_IA64_TPREL64MSB\t0x96\n#define R_IA64_TPREL64LSB\t0x97\n#define R_IA64_LTOFF_TPREL22\t0x9a\n#define R_IA64_DTPMOD64MSB\t0xa6\n#define R_IA64_DTPMOD64LSB\t0xa7\n#define R_IA64_LTOFF_DTPMOD22\t0xaa\n#define R_IA64_DTPREL14\t\t0xb1\n#define R_IA64_DTPREL22\t\t0xb2\n#define R_IA64_DTPREL64I\t0xb3\n#define R_IA64_DTPREL32MSB\t0xb4\n#define R_IA64_DTPREL32LSB\t0xb5\n#define R_IA64_DTPREL64MSB\t0xb6\n#define R_IA64_DTPREL64LSB\t0xb7\n#define R_IA64_LTOFF_DTPREL22\t0xba\n\n\n#define EF_SH_MACH_MASK\t\t0x1f\n#define EF_SH_UNKNOWN\t\t0x0\n#define EF_SH1\t\t\t0x1\n#define EF_SH2\t\t\t0x2\n#define EF_SH3\t\t\t0x3\n#define EF_SH_DSP\t\t0x4\n#define EF_SH3_DSP\t\t0x5\n#define EF_SH4AL_DSP\t\t0x6\n#define EF_SH3E\t\t\t0x8\n#define EF_SH4\t\t\t0x9\n#define EF_SH2E\t\t\t0xb\n#define EF_SH4A\t\t\t0xc\n#define EF_SH2A\t\t\t0xd\n#define EF_SH4_NOFPU\t\t0x10\n#define EF_SH4A_NOFPU\t\t0x11\n#define EF_SH4_NOMMU_NOFPU\t0x12\n#define EF_SH2A_NOFPU\t\t0x13\n#define EF_SH3_NOMMU\t\t0x14\n#define EF_SH2A_SH4_NOFPU\t0x15\n#define EF_SH2A_SH3_NOFPU\t0x16\n#define EF_SH2A_SH4\t\t0x17\n#define EF_SH2A_SH3E\t\t0x18\n\n#define\tR_SH_NONE\t\t0\n#define\tR_SH_DIR32\t\t1\n#define\tR_SH_REL32\t\t2\n#define\tR_SH_DIR8WPN\t\t3\n#define\tR_SH_IND12W\t\t4\n#define\tR_SH_DIR8WPL\t\t5\n#define\tR_SH_DIR8WPZ\t\t6\n#define\tR_SH_DIR8BP\t\t7\n#define\tR_SH_DIR8W\t\t8\n#define\tR_SH_DIR8L\t\t9\n#define\tR_SH_SWITCH16\t\t25\n#define\tR_SH_SWITCH32\t\t26\n#define\tR_SH_USES\t\t27\n#define\tR_SH_COUNT\t\t28\n#define\tR_SH_ALIGN\t\t29\n#define\tR_SH_CODE\t\t30\n#define\tR_SH_DATA\t\t31\n#define\tR_SH_LABEL\t\t32\n#define\tR_SH_SWITCH8\t\t33\n#define\tR_SH_GNU_VTINHERIT\t34\n#define\tR_SH_GNU_VTENTRY\t35\n#define\tR_SH_TLS_GD_32\t\t144\n#define\tR_SH_TLS_LD_32\t\t145\n#define\tR_SH_TLS_LDO_32\t\t146\n#define\tR_SH_TLS_IE_32\t\t147\n#define\tR_SH_TLS_LE_32\t\t148\n#define\tR_SH_TLS_DTPMOD32\t149\n#define\tR_SH_TLS_DTPOFF32\t150\n#define\tR_SH_TLS_TPOFF32\t151\n#define\tR_SH_GOT32\t\t160\n#define\tR_SH_PLT32\t\t161\n#define\tR_SH_COPY\t\t162\n#define\tR_SH_GLOB_DAT\t\t163\n#define\tR_SH_JMP_SLOT\t\t164\n#define\tR_SH_RELATIVE\t\t165\n#define\tR_SH_GOTOFF\t\t166\n#define\tR_SH_GOTPC\t\t167\n#define\tR_SH_GOT20\t\t201\n#define\tR_SH_GOTOFF20\t\t202\n#define\tR_SH_GOTFUNCDESC\t203\n#define\tR_SH_GOTFUNCDEST20\t204\n#define\tR_SH_GOTOFFFUNCDESC\t205\n#define\tR_SH_GOTOFFFUNCDEST20\t206\n#define\tR_SH_FUNCDESC\t\t207\n#define\tR_SH_FUNCDESC_VALUE\t208\n\n#define\tR_SH_NUM\t\t256\n\n\n\n#define R_390_NONE\t\t0\n#define R_390_8\t\t\t1\n#define R_390_12\t\t2\n#define R_390_16\t\t3\n#define R_390_32\t\t4\n#define R_390_PC32\t\t5\n#define R_390_GOT12\t\t6\n#define R_390_GOT32\t\t7\n#define R_390_PLT32\t\t8\n#define R_390_COPY\t\t9\n#define R_390_GLOB_DAT\t\t10\n#define R_390_JMP_SLOT\t\t11\n#define R_390_RELATIVE\t\t12\n#define R_390_GOTOFF32\t\t13\n#define R_390_GOTPC\t\t14\n#define R_390_GOT16\t\t15\n#define R_390_PC16\t\t16\n#define R_390_PC16DBL\t\t17\n#define R_390_PLT16DBL\t\t18\n#define R_390_PC32DBL\t\t19\n#define R_390_PLT32DBL\t\t20\n#define R_390_GOTPCDBL\t\t21\n#define R_390_64\t\t22\n#define R_390_PC64\t\t23\n#define R_390_GOT64\t\t24\n#define R_390_PLT64\t\t25\n#define R_390_GOTENT\t\t26\n#define R_390_GOTOFF16\t\t27\n#define R_390_GOTOFF64\t\t28\n#define R_390_GOTPLT12\t\t29\n#define R_390_GOTPLT16\t\t30\n#define R_390_GOTPLT32\t\t31\n#define R_390_GOTPLT64\t\t32\n#define R_390_GOTPLTENT\t\t33\n#define R_390_PLTOFF16\t\t34\n#define R_390_PLTOFF32\t\t35\n#define R_390_PLTOFF64\t\t36\n#define R_390_TLS_LOAD\t\t37\n#define R_390_TLS_GDCALL\t38\n\n#define R_390_TLS_LDCALL\t39\n\n#define R_390_TLS_GD32\t\t40\n\n#define R_390_TLS_GD64\t\t41\n\n#define R_390_TLS_GOTIE12\t42\n\n#define R_390_TLS_GOTIE32\t43\n\n#define R_390_TLS_GOTIE64\t44\n\n#define R_390_TLS_LDM32\t\t45\n\n#define R_390_TLS_LDM64\t\t46\n\n#define R_390_TLS_IE32\t\t47\n\n#define R_390_TLS_IE64\t\t48\n\n#define R_390_TLS_IEENT\t\t49\n\n#define R_390_TLS_LE32\t\t50\n\n#define R_390_TLS_LE64\t\t51\n\n#define R_390_TLS_LDO32\t\t52\n\n#define R_390_TLS_LDO64\t\t53\n\n#define R_390_TLS_DTPMOD\t54\n#define R_390_TLS_DTPOFF\t55\n#define R_390_TLS_TPOFF\t\t56\n\n#define R_390_20\t\t57\n#define R_390_GOT20\t\t58\n#define R_390_GOTPLT20\t\t59\n#define R_390_TLS_GOTIE20\t60\n\n\n#define R_390_NUM\t\t61\n\n\n\n#define R_CRIS_NONE\t\t0\n#define R_CRIS_8\t\t1\n#define R_CRIS_16\t\t2\n#define R_CRIS_32\t\t3\n#define R_CRIS_8_PCREL\t\t4\n#define R_CRIS_16_PCREL\t\t5\n#define R_CRIS_32_PCREL\t\t6\n#define R_CRIS_GNU_VTINHERIT\t7\n#define R_CRIS_GNU_VTENTRY\t8\n#define R_CRIS_COPY\t\t9\n#define R_CRIS_GLOB_DAT\t\t10\n#define R_CRIS_JUMP_SLOT\t11\n#define R_CRIS_RELATIVE\t\t12\n#define R_CRIS_16_GOT\t\t13\n#define R_CRIS_32_GOT\t\t14\n#define R_CRIS_16_GOTPLT\t15\n#define R_CRIS_32_GOTPLT\t16\n#define R_CRIS_32_GOTREL\t17\n#define R_CRIS_32_PLT_GOTREL\t18\n#define R_CRIS_32_PLT_PCREL\t19\n\n#define R_CRIS_NUM\t\t20\n\n\n\n#define R_X86_64_NONE\t\t0\n#define R_X86_64_64\t\t1\n#define R_X86_64_PC32\t\t2\n#define R_X86_64_GOT32\t\t3\n#define R_X86_64_PLT32\t\t4\n#define R_X86_64_COPY\t\t5\n#define R_X86_64_GLOB_DAT\t6\n#define R_X86_64_JUMP_SLOT\t7\n#define R_X86_64_RELATIVE\t8\n#define R_X86_64_GOTPCREL\t9\n\n#define R_X86_64_32\t\t10\n#define R_X86_64_32S\t\t11\n#define R_X86_64_16\t\t12\n#define R_X86_64_PC16\t\t13\n#define R_X86_64_8\t\t14\n#define R_X86_64_PC8\t\t15\n#define R_X86_64_DTPMOD64\t16\n#define R_X86_64_DTPOFF64\t17\n#define R_X86_64_TPOFF64\t18\n#define R_X86_64_TLSGD\t\t19\n\n#define R_X86_64_TLSLD\t\t20\n\n#define R_X86_64_DTPOFF32\t21\n#define R_X86_64_GOTTPOFF\t22\n\n#define R_X86_64_TPOFF32\t23\n#define R_X86_64_PC64\t\t24\n#define R_X86_64_GOTOFF64\t25\n#define R_X86_64_GOTPC32\t26\n#define R_X86_64_GOT64\t\t27\n#define R_X86_64_GOTPCREL64\t28\n#define R_X86_64_GOTPC64\t29\n#define R_X86_64_GOTPLT64\t30\n#define R_X86_64_PLTOFF64\t31\n#define R_X86_64_SIZE32\t\t32\n#define R_X86_64_SIZE64\t\t33\n\n#define R_X86_64_GOTPC32_TLSDESC 34\n#define R_X86_64_TLSDESC_CALL   35\n\n#define R_X86_64_TLSDESC        36\n#define R_X86_64_IRELATIVE\t37\n#define R_X86_64_RELATIVE64\t38\n#define R_X86_64_GOTPCRELX\t41\n#define R_X86_64_REX_GOTPCRELX\t42\n#define R_X86_64_NUM\t\t43\n\n\n\n#define R_MN10300_NONE\t\t0\n#define R_MN10300_32\t\t1\n#define R_MN10300_16\t\t2\n#define R_MN10300_8\t\t3\n#define R_MN10300_PCREL32\t4\n#define R_MN10300_PCREL16\t5\n#define R_MN10300_PCREL8\t6\n#define R_MN10300_GNU_VTINHERIT\t7\n#define R_MN10300_GNU_VTENTRY\t8\n#define R_MN10300_24\t\t9\n#define R_MN10300_GOTPC32\t10\n#define R_MN10300_GOTPC16\t11\n#define R_MN10300_GOTOFF32\t12\n#define R_MN10300_GOTOFF24\t13\n#define R_MN10300_GOTOFF16\t14\n#define R_MN10300_PLT32\t\t15\n#define R_MN10300_PLT16\t\t16\n#define R_MN10300_GOT32\t\t17\n#define R_MN10300_GOT24\t\t18\n#define R_MN10300_GOT16\t\t19\n#define R_MN10300_COPY\t\t20\n#define R_MN10300_GLOB_DAT\t21\n#define R_MN10300_JMP_SLOT\t22\n#define R_MN10300_RELATIVE\t23\n\n#define R_MN10300_NUM\t\t24\n\n\n\n#define R_M32R_NONE\t\t0\n#define R_M32R_16\t\t1\n#define R_M32R_32\t\t2\n#define R_M32R_24\t\t3\n#define R_M32R_10_PCREL\t\t4\n#define R_M32R_18_PCREL\t\t5\n#define R_M32R_26_PCREL\t\t6\n#define R_M32R_HI16_ULO\t\t7\n#define R_M32R_HI16_SLO\t\t8\n#define R_M32R_LO16\t\t9\n#define R_M32R_SDA16\t\t10\n#define R_M32R_GNU_VTINHERIT\t11\n#define R_M32R_GNU_VTENTRY\t12\n\n#define R_M32R_16_RELA\t\t33\n#define R_M32R_32_RELA\t\t34\n#define R_M32R_24_RELA\t\t35\n#define R_M32R_10_PCREL_RELA\t36\n#define R_M32R_18_PCREL_RELA\t37\n#define R_M32R_26_PCREL_RELA\t38\n#define R_M32R_HI16_ULO_RELA\t39\n#define R_M32R_HI16_SLO_RELA\t40\n#define R_M32R_LO16_RELA\t41\n#define R_M32R_SDA16_RELA\t42\n#define R_M32R_RELA_GNU_VTINHERIT\t43\n#define R_M32R_RELA_GNU_VTENTRY\t44\n#define R_M32R_REL32\t\t45\n\n#define R_M32R_GOT24\t\t48\n#define R_M32R_26_PLTREL\t49\n#define R_M32R_COPY\t\t50\n#define R_M32R_GLOB_DAT\t\t51\n#define R_M32R_JMP_SLOT\t\t52\n#define R_M32R_RELATIVE\t\t53\n#define R_M32R_GOTOFF\t\t54\n#define R_M32R_GOTPC24\t\t55\n#define R_M32R_GOT16_HI_ULO\t56\n\n#define R_M32R_GOT16_HI_SLO\t57\n\n#define R_M32R_GOT16_LO\t\t58\n#define R_M32R_GOTPC_HI_ULO\t59\n\n#define R_M32R_GOTPC_HI_SLO\t60\n\n#define R_M32R_GOTPC_LO\t\t61\n\n#define R_M32R_GOTOFF_HI_ULO\t62\n\n#define R_M32R_GOTOFF_HI_SLO\t63\n\n#define R_M32R_GOTOFF_LO\t64\n#define R_M32R_NUM\t\t256\n\n#define R_MICROBLAZE_NONE 0\n#define R_MICROBLAZE_32 1\n#define R_MICROBLAZE_32_PCREL 2\n#define R_MICROBLAZE_64_PCREL 3\n#define R_MICROBLAZE_32_PCREL_LO 4\n#define R_MICROBLAZE_64 5\n#define R_MICROBLAZE_32_LO 6\n#define R_MICROBLAZE_SRO32 7\n#define R_MICROBLAZE_SRW32 8\n#define R_MICROBLAZE_64_NONE 9\n#define R_MICROBLAZE_32_SYM_OP_SYM 10\n#define R_MICROBLAZE_GNU_VTINHERIT 11\n#define R_MICROBLAZE_GNU_VTENTRY 12\n#define R_MICROBLAZE_GOTPC_64 13\n#define R_MICROBLAZE_GOT_64 14\n#define R_MICROBLAZE_PLT_64 15\n#define R_MICROBLAZE_REL 16\n#define R_MICROBLAZE_JUMP_SLOT 17\n#define R_MICROBLAZE_GLOB_DAT 18\n#define R_MICROBLAZE_GOTOFF_64 19\n#define R_MICROBLAZE_GOTOFF_32 20\n#define R_MICROBLAZE_COPY 21\n#define R_MICROBLAZE_TLS 22\n#define R_MICROBLAZE_TLSGD 23\n#define R_MICROBLAZE_TLSLD 24\n#define R_MICROBLAZE_TLSDTPMOD32 25\n#define R_MICROBLAZE_TLSDTPREL32 26\n#define R_MICROBLAZE_TLSDTPREL64 27\n#define R_MICROBLAZE_TLSGOTTPREL32 28\n#define R_MICROBLAZE_TLSTPREL32\t 29\n\n#define DT_NIOS2_GP             0x70000002\n\n#define R_NIOS2_NONE\t\t0\n#define R_NIOS2_S16\t\t1\n#define R_NIOS2_U16\t\t2\n#define R_NIOS2_PCREL16\t\t3\n#define R_NIOS2_CALL26\t\t4\n#define R_NIOS2_IMM5\t\t5\n#define R_NIOS2_CACHE_OPX\t6\n#define R_NIOS2_IMM6\t\t7\n#define R_NIOS2_IMM8\t\t8\n#define R_NIOS2_HI16\t\t9\n#define R_NIOS2_LO16\t\t10\n#define R_NIOS2_HIADJ16\t\t11\n#define R_NIOS2_BFD_RELOC_32\t12\n#define R_NIOS2_BFD_RELOC_16\t13\n#define R_NIOS2_BFD_RELOC_8\t14\n#define R_NIOS2_GPREL\t\t15\n#define R_NIOS2_GNU_VTINHERIT\t16\n#define R_NIOS2_GNU_VTENTRY\t17\n#define R_NIOS2_UJMP\t\t18\n#define R_NIOS2_CJMP\t\t19\n#define R_NIOS2_CALLR\t\t20\n#define R_NIOS2_ALIGN\t\t21\n#define R_NIOS2_GOT16\t\t22\n#define R_NIOS2_CALL16\t\t23\n#define R_NIOS2_GOTOFF_LO\t24\n#define R_NIOS2_GOTOFF_HA\t25\n#define R_NIOS2_PCREL_LO\t26\n#define R_NIOS2_PCREL_HA\t27\n#define R_NIOS2_TLS_GD16\t28\n#define R_NIOS2_TLS_LDM16\t29\n#define R_NIOS2_TLS_LDO16\t30\n#define R_NIOS2_TLS_IE16\t31\n#define R_NIOS2_TLS_LE16\t32\n#define R_NIOS2_TLS_DTPMOD\t33\n#define R_NIOS2_TLS_DTPREL\t34\n#define R_NIOS2_TLS_TPREL\t35\n#define R_NIOS2_COPY\t\t36\n#define R_NIOS2_GLOB_DAT\t37\n#define R_NIOS2_JUMP_SLOT\t38\n#define R_NIOS2_RELATIVE\t39\n#define R_NIOS2_GOTOFF\t\t40\n#define R_NIOS2_CALL26_NOAT\t41\n#define R_NIOS2_GOT_LO\t\t42\n#define R_NIOS2_GOT_HA\t\t43\n#define R_NIOS2_CALL_LO\t\t44\n#define R_NIOS2_CALL_HA\t\t45\n\n#define R_OR1K_NONE\t\t0\n#define R_OR1K_32\t\t1\n#define R_OR1K_16\t\t2\n#define R_OR1K_8\t\t3\n#define R_OR1K_LO_16_IN_INSN\t4\n#define R_OR1K_HI_16_IN_INSN\t5\n#define R_OR1K_INSN_REL_26\t6\n#define R_OR1K_GNU_VTENTRY\t7\n#define R_OR1K_GNU_VTINHERIT\t8\n#define R_OR1K_32_PCREL\t\t9\n#define R_OR1K_16_PCREL\t\t10\n#define R_OR1K_8_PCREL\t\t11\n#define R_OR1K_GOTPC_HI16\t12\n#define R_OR1K_GOTPC_LO16\t13\n#define R_OR1K_GOT16\t\t14\n#define R_OR1K_PLT26\t\t15\n#define R_OR1K_GOTOFF_HI16\t16\n#define R_OR1K_GOTOFF_LO16\t17\n#define R_OR1K_COPY\t\t18\n#define R_OR1K_GLOB_DAT\t\t19\n#define R_OR1K_JMP_SLOT\t\t20\n#define R_OR1K_RELATIVE\t\t21\n#define R_OR1K_TLS_GD_HI16\t22\n#define R_OR1K_TLS_GD_LO16\t23\n#define R_OR1K_TLS_LDM_HI16\t24\n#define R_OR1K_TLS_LDM_LO16\t25\n#define R_OR1K_TLS_LDO_HI16\t26\n#define R_OR1K_TLS_LDO_LO16\t27\n#define R_OR1K_TLS_IE_HI16\t28\n#define R_OR1K_TLS_IE_LO16\t29\n#define R_OR1K_TLS_LE_HI16\t30\n#define R_OR1K_TLS_LE_LO16\t31\n#define R_OR1K_TLS_TPOFF\t32\n#define R_OR1K_TLS_DTPOFF\t33\n#define R_OR1K_TLS_DTPMOD\t34\n\n#define R_BPF_NONE\t\t0\n#define R_BPF_MAP_FD\t\t1\n\n#define R_RISCV_NONE            0\n#define R_RISCV_32              1\n#define R_RISCV_64              2\n#define R_RISCV_RELATIVE        3\n#define R_RISCV_COPY            4\n#define R_RISCV_JUMP_SLOT       5\n#define R_RISCV_TLS_DTPMOD32    6\n#define R_RISCV_TLS_DTPMOD64    7\n#define R_RISCV_TLS_DTPREL32    8\n#define R_RISCV_TLS_DTPREL64    9\n#define R_RISCV_TLS_TPREL32     10\n#define R_RISCV_TLS_TPREL64     11\n\n#define R_RISCV_BRANCH          16\n#define R_RISCV_JAL             17\n#define R_RISCV_CALL            18\n#define R_RISCV_CALL_PLT        19\n#define R_RISCV_GOT_HI20        20\n#define R_RISCV_TLS_GOT_HI20    21\n#define R_RISCV_TLS_GD_HI20     22\n#define R_RISCV_PCREL_HI20      23\n#define R_RISCV_PCREL_LO12_I    24\n#define R_RISCV_PCREL_LO12_S    25\n#define R_RISCV_HI20            26\n#define R_RISCV_LO12_I          27\n#define R_RISCV_LO12_S          28\n#define R_RISCV_TPREL_HI20      29\n#define R_RISCV_TPREL_LO12_I    30\n#define R_RISCV_TPREL_LO12_S    31\n#define R_RISCV_TPREL_ADD       32\n#define R_RISCV_ADD8            33\n#define R_RISCV_ADD16           34\n#define R_RISCV_ADD32           35\n#define R_RISCV_ADD64           36\n#define R_RISCV_SUB8            37\n#define R_RISCV_SUB16           38\n#define R_RISCV_SUB32           39\n#define R_RISCV_SUB64           40\n#define R_RISCV_GNU_VTINHERIT   41\n#define R_RISCV_GNU_VTENTRY     42\n#define R_RISCV_ALIGN           43\n#define R_RISCV_RVC_BRANCH      44\n#define R_RISCV_RVC_JUMP        45\n#define R_RISCV_RVC_LUI         46\n#define R_RISCV_GPREL_I         47\n#define R_RISCV_GPREL_S         48\n#define R_RISCV_TPREL_I         49\n#define R_RISCV_TPREL_S         50\n#define R_RISCV_RELAX           51\n#define R_RISCV_SUB6            52\n#define R_RISCV_SET6            53\n#define R_RISCV_SET8            54\n#define R_RISCV_SET16           55\n#define R_RISCV_SET32           56\n#define R_RISCV_32_PCREL        57\n\n#ifdef __cplusplus\n}\n#endif\n\n\n#endif\n"
  },
  {
    "path": "user.libc/include/endian.h",
    "content": "#ifndef _ENDIAN_H\n#define _ENDIAN_H\n\n#include <features.h>\n\n#define __NEED_uint16_t\n#define __NEED_uint32_t\n#define __NEED_uint64_t\n\n#include <bits/alltypes.h>\n\n#define __PDP_ENDIAN 3412\n\n#define BIG_ENDIAN __BIG_ENDIAN\n#define LITTLE_ENDIAN __LITTLE_ENDIAN\n#define PDP_ENDIAN __PDP_ENDIAN\n#define BYTE_ORDER __BYTE_ORDER\n\nstatic __inline uint16_t __bswap16(uint16_t __x)\n{\n\treturn __x<<8 | __x>>8;\n}\n\nstatic __inline uint32_t __bswap32(uint32_t __x)\n{\n\treturn __x>>24 | __x>>8&0xff00 | __x<<8&0xff0000 | __x<<24;\n}\n\nstatic __inline uint64_t __bswap64(uint64_t __x)\n{\n\treturn __bswap32(__x)+0ULL<<32 | __bswap32(__x>>32);\n}\n\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n#define htobe16(x) __bswap16(x)\n#define be16toh(x) __bswap16(x)\n#define htobe32(x) __bswap32(x)\n#define be32toh(x) __bswap32(x)\n#define htobe64(x) __bswap64(x)\n#define be64toh(x) __bswap64(x)\n#define htole16(x) (uint16_t)(x)\n#define le16toh(x) (uint16_t)(x)\n#define htole32(x) (uint32_t)(x)\n#define le32toh(x) (uint32_t)(x)\n#define htole64(x) (uint64_t)(x)\n#define le64toh(x) (uint64_t)(x)\n#else\n#define htobe16(x) (uint16_t)(x)\n#define be16toh(x) (uint16_t)(x)\n#define htobe32(x) (uint32_t)(x)\n#define be32toh(x) (uint32_t)(x)\n#define htobe64(x) (uint64_t)(x)\n#define be64toh(x) (uint64_t)(x)\n#define htole16(x) __bswap16(x)\n#define le16toh(x) __bswap16(x)\n#define htole32(x) __bswap32(x)\n#define le32toh(x) __bswap32(x)\n#define htole64(x) __bswap64(x)\n#define le64toh(x) __bswap64(x)\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n#define betoh16(x) __bswap16(x)\n#define betoh32(x) __bswap32(x)\n#define betoh64(x) __bswap64(x)\n#define letoh16(x) (uint16_t)(x)\n#define letoh32(x) (uint32_t)(x)\n#define letoh64(x) (uint64_t)(x)\n#else\n#define betoh16(x) (uint16_t)(x)\n#define betoh32(x) (uint32_t)(x)\n#define betoh64(x) (uint64_t)(x)\n#define letoh16(x) __bswap16(x)\n#define letoh32(x) __bswap32(x)\n#define letoh64(x) __bswap64(x)\n#endif\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/err.h",
    "content": "#ifndef _ERR_H\n#define _ERR_H\n\n#include <features.h>\n#include <stdarg.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nvoid warn(const char *, ...);\nvoid vwarn(const char *, va_list);\nvoid warnx(const char *, ...);\nvoid vwarnx(const char *, va_list);\n\n_Noreturn void err(int, const char *, ...);\n_Noreturn void verr(int, const char *, va_list);\n_Noreturn void errx(int, const char *, ...);\n_Noreturn void verrx(int, const char *, va_list);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/errno.h",
    "content": "#ifndef\t_ERRNO_H\n#define _ERRNO_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#include <bits/errno.h>\n\n#ifdef __GNUC__\n__attribute__((const))\n#endif\nint *__errno_location(void);\n#define errno (*__errno_location())\n\n#ifdef _GNU_SOURCE\nextern char *program_invocation_short_name, *program_invocation_name;\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n\n"
  },
  {
    "path": "user.libc/include/fcntl.h",
    "content": "#ifndef\t_FCNTL_H\n#define\t_FCNTL_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_off_t\n#define __NEED_pid_t\n#define __NEED_mode_t\n\n#ifdef _GNU_SOURCE\n#define __NEED_size_t\n#define __NEED_ssize_t\n#define __NEED_struct_iovec\n#endif\n\n#include <bits/alltypes.h>\n\n#include <bits/fcntl.h>\n\nstruct flock {\n\tshort l_type;\n\tshort l_whence;\n\toff_t l_start;\n\toff_t l_len;\n\tpid_t l_pid;\n};\n\nint creat(const char *, mode_t);\nint fcntl(int, int, ...);\nint open(const char *, int, ...);\nint openat(int, const char *, int, ...);\nint posix_fadvise(int, off_t, off_t, int);\nint posix_fallocate(int, off_t, off_t);\n\n#define O_SEARCH   O_PATH\n#define O_EXEC     O_PATH\n#define O_TTY_INIT 0\n\n#define O_ACCMODE (03|O_SEARCH)\n#define O_RDONLY  00\n#define O_WRONLY  01\n#define O_RDWR    02\n\n#define F_OFD_GETLK 36\n#define F_OFD_SETLK 37\n#define F_OFD_SETLKW 38\n\n#define F_DUPFD_CLOEXEC 1030\n\n#define F_RDLCK 0\n#define F_WRLCK 1\n#define F_UNLCK 2\n\n#define FD_CLOEXEC 1\n\n#define AT_FDCWD (-100)\n#define AT_SYMLINK_NOFOLLOW 0x100\n#define AT_REMOVEDIR 0x200\n#define AT_SYMLINK_FOLLOW 0x400\n#define AT_EACCESS 0x200\n\n#define POSIX_FADV_NORMAL     0\n#define POSIX_FADV_RANDOM     1\n#define POSIX_FADV_SEQUENTIAL 2\n#define POSIX_FADV_WILLNEED   3\n#ifndef POSIX_FADV_DONTNEED\n#define POSIX_FADV_DONTNEED   4\n#define POSIX_FADV_NOREUSE    5\n#endif\n\n#undef SEEK_SET\n#undef SEEK_CUR\n#undef SEEK_END\n#define SEEK_SET 0\n#define SEEK_CUR 1\n#define SEEK_END 2\n\n#ifndef S_IRUSR\n#define S_ISUID 04000\n#define S_ISGID 02000\n#define S_ISVTX 01000\n#define S_IRUSR 0400\n#define S_IWUSR 0200\n#define S_IXUSR 0100\n#define S_IRWXU 0700\n#define S_IRGRP 0040\n#define S_IWGRP 0020\n#define S_IXGRP 0010\n#define S_IRWXG 0070\n#define S_IROTH 0004\n#define S_IWOTH 0002\n#define S_IXOTH 0001\n#define S_IRWXO 0007\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define AT_NO_AUTOMOUNT 0x800\n#define AT_EMPTY_PATH 0x1000\n#define AT_STATX_SYNC_TYPE 0x6000\n#define AT_STATX_SYNC_AS_STAT 0x0000\n#define AT_STATX_FORCE_SYNC 0x2000\n#define AT_STATX_DONT_SYNC 0x4000\n#define AT_RECURSIVE 0x8000\n\n#define FAPPEND O_APPEND\n#define FFSYNC O_SYNC\n#define FASYNC O_ASYNC\n#define FNONBLOCK O_NONBLOCK\n#define FNDELAY O_NDELAY\n\n#define F_OK 0\n#define R_OK 4\n#define W_OK 2\n#define X_OK 1\n#define F_ULOCK 0\n#define F_LOCK  1\n#define F_TLOCK 2\n#define F_TEST  3\n\n#define F_SETLEASE\t1024\n#define F_GETLEASE\t1025\n#define F_NOTIFY\t1026\n#define F_CANCELLK\t1029\n#define F_SETPIPE_SZ\t1031\n#define F_GETPIPE_SZ\t1032\n#define F_ADD_SEALS\t1033\n#define F_GET_SEALS\t1034\n\n#define F_SEAL_SEAL\t0x0001\n#define F_SEAL_SHRINK\t0x0002\n#define F_SEAL_GROW\t0x0004\n#define F_SEAL_WRITE\t0x0008\n#define F_SEAL_FUTURE_WRITE\t0x0010\n\n#define F_GET_RW_HINT\t\t1035\n#define F_SET_RW_HINT\t\t1036\n#define F_GET_FILE_RW_HINT\t1037\n#define F_SET_FILE_RW_HINT\t1038\n\n#define RWF_WRITE_LIFE_NOT_SET\t0\n#define RWH_WRITE_LIFE_NONE\t1\n#define RWH_WRITE_LIFE_SHORT\t2\n#define RWH_WRITE_LIFE_MEDIUM\t3\n#define RWH_WRITE_LIFE_LONG\t4\n#define RWH_WRITE_LIFE_EXTREME\t5\n\n#define DN_ACCESS\t0x00000001\n#define DN_MODIFY\t0x00000002\n#define DN_CREATE\t0x00000004\n#define DN_DELETE\t0x00000008\n#define DN_RENAME\t0x00000010\n#define DN_ATTRIB\t0x00000020\n#define DN_MULTISHOT\t0x80000000\n\nint lockf(int, int, off_t);\n#endif\n\n#if defined(_GNU_SOURCE)\n#define F_OWNER_TID 0\n#define F_OWNER_PID 1\n#define F_OWNER_PGRP 2\n#define F_OWNER_GID 2\nstruct file_handle {\n\tunsigned handle_bytes;\n\tint handle_type;\n\tunsigned char f_handle[];\n};\nstruct f_owner_ex {\n\tint type;\n\tpid_t pid;\n};\n#define FALLOC_FL_KEEP_SIZE 1\n#define FALLOC_FL_PUNCH_HOLE 2\n#define MAX_HANDLE_SZ 128\n#define SYNC_FILE_RANGE_WAIT_BEFORE 1\n#define SYNC_FILE_RANGE_WRITE 2\n#define SYNC_FILE_RANGE_WAIT_AFTER 4\n#define SPLICE_F_MOVE 1\n#define SPLICE_F_NONBLOCK 2\n#define SPLICE_F_MORE 4\n#define SPLICE_F_GIFT 8\nint fallocate(int, int, off_t, off_t);\n#define fallocate64 fallocate\nint name_to_handle_at(int, const char *, struct file_handle *, int *, int);\nint open_by_handle_at(int, struct file_handle *, int);\nssize_t readahead(int, off_t, size_t);\nint sync_file_range(int, off_t, off_t, unsigned);\nssize_t vmsplice(int, const struct iovec *, size_t, unsigned);\nssize_t splice(int, off_t *, int, off_t *, size_t, unsigned);\nssize_t tee(int, int, size_t, unsigned);\n#define loff_t off_t\n#endif\n\n#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)\n#define F_GETLK64 F_GETLK\n#define F_SETLK64 F_SETLK\n#define F_SETLKW64 F_SETLKW\n#define flock64 flock\n#define open64 open\n#define openat64 openat\n#define creat64 creat\n#define lockf64 lockf\n#define posix_fadvise64 posix_fadvise\n#define posix_fallocate64 posix_fallocate\n#define off64_t off_t\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/features.h",
    "content": "#ifndef _FEATURES_H\n#define _FEATURES_H\n\n#if defined(_ALL_SOURCE) && !defined(_GNU_SOURCE)\n#define _GNU_SOURCE 1\n#endif\n\n#if defined(_DEFAULT_SOURCE) && !defined(_BSD_SOURCE)\n#define _BSD_SOURCE 1\n#endif\n\n#if !defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE) \\\n && !defined(_XOPEN_SOURCE) && !defined(_GNU_SOURCE) \\\n && !defined(_BSD_SOURCE) && !defined(__STRICT_ANSI__)\n#define _BSD_SOURCE 1\n#define _XOPEN_SOURCE 700\n#endif\n\n#if __STDC_VERSION__ >= 199901L\n#define __restrict restrict\n#elif !defined(__GNUC__)\n#define __restrict\n#endif\n\n#if __STDC_VERSION__ >= 199901L || defined(__cplusplus)\n#define __inline inline\n#elif !defined(__GNUC__)\n#define __inline\n#endif\n\n#if __STDC_VERSION__ >= 201112L\n#elif defined(__GNUC__)\n#define _Noreturn __attribute__((__noreturn__))\n#else\n#define _Noreturn\n#endif\n\n#define __REDIR(x,y) __typeof__(x) x __asm__(#y)\n\n#endif\n"
  },
  {
    "path": "user.libc/include/fenv.h",
    "content": "#ifndef _FENV_H\n#define _FENV_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <bits/fenv.h>\n\nint feclearexcept(int);\nint fegetexceptflag(fexcept_t *, int);\nint feraiseexcept(int);\nint fesetexceptflag(const fexcept_t *, int);\nint fetestexcept(int);\n\nint fegetround(void);\nint fesetround(int);\n\nint fegetenv(fenv_t *);\nint feholdexcept(fenv_t *);\nint fesetenv(const fenv_t *);\nint feupdateenv(const fenv_t *);\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n\n"
  },
  {
    "path": "user.libc/include/float.h",
    "content": "#ifndef _FLOAT_H\n#define _FLOAT_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nint __flt_rounds(void);\n#define FLT_ROUNDS (__flt_rounds())\n\n#define FLT_RADIX 2\n\n#define FLT_TRUE_MIN 1.40129846432481707092e-45F\n#define FLT_MIN 1.17549435082228750797e-38F\n#define FLT_MAX 3.40282346638528859812e+38F\n#define FLT_EPSILON 1.1920928955078125e-07F\n\n#define FLT_MANT_DIG 24\n#define FLT_MIN_EXP (-125)\n#define FLT_MAX_EXP 128\n#define FLT_HAS_SUBNORM 1\n\n#define FLT_DIG 6\n#define FLT_DECIMAL_DIG 9\n#define FLT_MIN_10_EXP (-37)\n#define FLT_MAX_10_EXP 38\n\n#define DBL_TRUE_MIN 4.94065645841246544177e-324\n#define DBL_MIN 2.22507385850720138309e-308\n#define DBL_MAX 1.79769313486231570815e+308\n#define DBL_EPSILON 2.22044604925031308085e-16\n\n#define DBL_MANT_DIG 53\n#define DBL_MIN_EXP (-1021)\n#define DBL_MAX_EXP 1024\n#define DBL_HAS_SUBNORM 1\n\n#define DBL_DIG 15\n#define DBL_DECIMAL_DIG 17\n#define DBL_MIN_10_EXP (-307)\n#define DBL_MAX_10_EXP 308\n\n#define LDBL_HAS_SUBNORM 1\n#define LDBL_DECIMAL_DIG DECIMAL_DIG\n\n#include <bits/float.h>\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/fmtmsg.h",
    "content": "#ifndef _FMTMSG_H\n#define _FMTMSG_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define MM_HARD\t\t1\n#define MM_SOFT\t\t2\n#define MM_FIRM\t\t4\n\n#define MM_APPL\t\t8\n#define MM_UTIL\t\t16\n#define MM_OPSYS\t32\n\n#define MM_RECOVER\t64\n#define MM_NRECOV\t128\n\n#define MM_PRINT\t256\n#define MM_CONSOLE\t512\n\n#define MM_NULLMC\t0L\n\n#define MM_HALT\t\t1\n#define MM_ERROR\t2\n#define MM_WARNING\t3\n#define MM_INFO\t\t4\n#define MM_NOSEV\t0\n\n#define MM_OK\t\t0\n#define MM_NOTOK\t(-1)\n#define MM_NOMSG\t1\n#define MM_NOCON\t4\n\n#define MM_NULLLBL\t((char*)0)\n#define MM_NULLTXT\t((char*)0)\n#define MM_NULLACT\t((char*)0)\n#define MM_NULLTAG\t((char*)0)\n#define MM_NULLSEV\t0\n\nint fmtmsg(long, const char *, int, const char *, const char *, const char *);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/fnmatch.h",
    "content": "#ifndef\t_FNMATCH_H\n#define\t_FNMATCH_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define\tFNM_PATHNAME 0x1\n#define\tFNM_NOESCAPE 0x2\n#define\tFNM_PERIOD   0x4\n#define\tFNM_LEADING_DIR\t0x8           \n#define\tFNM_CASEFOLD\t0x10\n#define\tFNM_FILE_NAME\tFNM_PATHNAME\n\n#define\tFNM_NOMATCH 1\n#define FNM_NOSYS   (-1)\n\nint fnmatch(const char *, const char *, int);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/ftw.h",
    "content": "#ifndef _FTW_H\n#define\t_FTW_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n#include <sys/stat.h>\n\n#define FTW_F   1\n#define FTW_D   2\n#define FTW_DNR 3\n#define FTW_NS  4\n#define FTW_SL  5\n#define FTW_DP  6\n#define FTW_SLN 7\n\n#define FTW_PHYS  1\n#define FTW_MOUNT 2\n#define FTW_CHDIR 4\n#define FTW_DEPTH 8\n\nstruct FTW {\n\tint base;\n\tint level;\n};\n\nint ftw(const char *, int (*)(const char *, const struct stat *, int), int);\nint nftw(const char *, int (*)(const char *, const struct stat *, int, struct FTW *), int, int);\n\n#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)\n#define ftw64 ftw\n#define nftw64 nftw\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/getopt.h",
    "content": "#ifndef _GETOPT_H\n#define _GETOPT_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nint getopt(int, char * const [], const char *);\nextern char *optarg;\nextern int optind, opterr, optopt, optreset;\n\nstruct option {\n\tconst char *name;\n\tint has_arg;\n\tint *flag;\n\tint val;\n};\n\nint getopt_long(int, char *const *, const char *, const struct option *, int *);\nint getopt_long_only(int, char *const *, const char *, const struct option *, int *);\n\n#define no_argument        0\n#define required_argument  1\n#define optional_argument  2\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/glob.h",
    "content": "#ifndef\t_GLOB_H\n#define\t_GLOB_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_size_t\n\n#include <bits/alltypes.h>\n\ntypedef struct {\n\tsize_t gl_pathc;\n\tchar **gl_pathv;\n\tsize_t gl_offs;\n\tint __dummy1;\n\tvoid *__dummy2[5];\n} glob_t;\n\nint  glob(const char *__restrict, int, int (*)(const char *, int), glob_t *__restrict);\nvoid globfree(glob_t *);\n\n#define GLOB_ERR      0x01\n#define GLOB_MARK     0x02\n#define GLOB_NOSORT   0x04\n#define GLOB_DOOFFS   0x08\n#define GLOB_NOCHECK  0x10\n#define GLOB_APPEND   0x20\n#define GLOB_NOESCAPE 0x40\n#define\tGLOB_PERIOD   0x80\n\n#define GLOB_TILDE       0x1000\n#define GLOB_TILDE_CHECK 0x4000\n\n#define GLOB_NOSPACE 1\n#define GLOB_ABORTED 2\n#define GLOB_NOMATCH 3\n#define GLOB_NOSYS   4\n\n#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)\n#define glob64 glob\n#define globfree64 globfree\n#define glob64_t glob_t\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/grp.h",
    "content": "#ifndef\t_GRP_H\n#define\t_GRP_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_size_t\n#define __NEED_gid_t\n\n#ifdef _GNU_SOURCE\n#define __NEED_FILE\n#endif\n\n#include <bits/alltypes.h>\n\nstruct group {\n\tchar *gr_name;\n\tchar *gr_passwd;\n\tgid_t gr_gid;\n\tchar **gr_mem;\n};\n\nstruct group  *getgrgid(gid_t);\nstruct group  *getgrnam(const char *);\n\nint getgrgid_r(gid_t, struct group *, char *, size_t, struct group **);\nint getgrnam_r(const char *, struct group *, char *, size_t, struct group **);\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\nstruct group  *getgrent(void);\nvoid           endgrent(void);\nvoid           setgrent(void);\n#endif\n\n#ifdef _GNU_SOURCE\nstruct group  *fgetgrent(FILE *);\nint putgrent(const struct group *, FILE *);\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\nint getgrouplist(const char *, gid_t, gid_t *, int *);\nint setgroups(size_t, const gid_t *);\nint initgroups(const char *, gid_t);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/iconv.h",
    "content": "#ifndef _ICONV_H\n#define _ICONV_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_size_t\n\n#include <bits/alltypes.h>\n\ntypedef void *iconv_t;\n\niconv_t iconv_open(const char *, const char *);\nsize_t iconv(iconv_t, char **__restrict, size_t *__restrict, char **__restrict, size_t *__restrict);\nint iconv_close(iconv_t);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/ifaddrs.h",
    "content": "#ifndef _IFADDRS_H\n#define _IFADDRS_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n#include <netinet/in.h>\n#include <sys/socket.h>\n\nstruct ifaddrs {\n\tstruct ifaddrs *ifa_next;\n\tchar *ifa_name;\n\tunsigned ifa_flags;\n\tstruct sockaddr *ifa_addr;\n\tstruct sockaddr *ifa_netmask;\n\tunion {\n\t\tstruct sockaddr *ifu_broadaddr;\n\t\tstruct sockaddr *ifu_dstaddr;\n\t} ifa_ifu;\n\tvoid *ifa_data;\n};\n#define ifa_broadaddr ifa_ifu.ifu_broadaddr\n#define ifa_dstaddr ifa_ifu.ifu_dstaddr\n\nvoid freeifaddrs(struct ifaddrs *);\nint getifaddrs(struct ifaddrs **);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n\n"
  },
  {
    "path": "user.libc/include/inttypes.h",
    "content": "#ifndef _INTTYPES_H\n#define _INTTYPES_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n#include <stdint.h>\n\n#define __NEED_wchar_t\n#include <bits/alltypes.h>\n\ntypedef struct { intmax_t quot, rem; } imaxdiv_t;\n\nintmax_t imaxabs(intmax_t);\nimaxdiv_t imaxdiv(intmax_t, intmax_t);\n\nintmax_t strtoimax(const char *__restrict, char **__restrict, int);\nuintmax_t strtoumax(const char *__restrict, char **__restrict, int);\n\nintmax_t wcstoimax(const wchar_t *__restrict, wchar_t **__restrict, int);\nuintmax_t wcstoumax(const wchar_t *__restrict, wchar_t **__restrict, int);\n\n#if UINTPTR_MAX == UINT64_MAX\n#define __PRI64  \"l\"\n#define __PRIPTR \"l\"\n#else\n#define __PRI64  \"ll\"\n#define __PRIPTR \"\"\n#endif\n\n#define PRId8  \"d\"\n#define PRId16 \"d\"\n#define PRId32 \"d\"\n#define PRId64 __PRI64 \"d\"\n\n#define PRIdLEAST8  \"d\"\n#define PRIdLEAST16 \"d\"\n#define PRIdLEAST32 \"d\"\n#define PRIdLEAST64 __PRI64 \"d\"\n\n#define PRIdFAST8  \"d\"\n#define PRIdFAST16 \"d\"\n#define PRIdFAST32 \"d\"\n#define PRIdFAST64 __PRI64 \"d\"\n\n#define PRIi8  \"i\"\n#define PRIi16 \"i\"\n#define PRIi32 \"i\"\n#define PRIi64 __PRI64 \"i\"\n\n#define PRIiLEAST8  \"i\"\n#define PRIiLEAST16 \"i\"\n#define PRIiLEAST32 \"i\"\n#define PRIiLEAST64 __PRI64 \"i\"\n\n#define PRIiFAST8  \"i\"\n#define PRIiFAST16 \"i\"\n#define PRIiFAST32 \"i\"\n#define PRIiFAST64 __PRI64 \"i\"\n\n#define PRIo8  \"o\"\n#define PRIo16 \"o\"\n#define PRIo32 \"o\"\n#define PRIo64 __PRI64 \"o\"\n\n#define PRIoLEAST8  \"o\"\n#define PRIoLEAST16 \"o\"\n#define PRIoLEAST32 \"o\"\n#define PRIoLEAST64 __PRI64 \"o\"\n\n#define PRIoFAST8  \"o\"\n#define PRIoFAST16 \"o\"\n#define PRIoFAST32 \"o\"\n#define PRIoFAST64 __PRI64 \"o\"\n\n#define PRIu8  \"u\"\n#define PRIu16 \"u\"\n#define PRIu32 \"u\"\n#define PRIu64 __PRI64 \"u\"\n\n#define PRIuLEAST8  \"u\"\n#define PRIuLEAST16 \"u\"\n#define PRIuLEAST32 \"u\"\n#define PRIuLEAST64 __PRI64 \"u\"\n\n#define PRIuFAST8  \"u\"\n#define PRIuFAST16 \"u\"\n#define PRIuFAST32 \"u\"\n#define PRIuFAST64 __PRI64 \"u\"\n\n#define PRIx8  \"x\"\n#define PRIx16 \"x\"\n#define PRIx32 \"x\"\n#define PRIx64 __PRI64 \"x\"\n\n#define PRIxLEAST8  \"x\"\n#define PRIxLEAST16 \"x\"\n#define PRIxLEAST32 \"x\"\n#define PRIxLEAST64 __PRI64 \"x\"\n\n#define PRIxFAST8  \"x\"\n#define PRIxFAST16 \"x\"\n#define PRIxFAST32 \"x\"\n#define PRIxFAST64 __PRI64 \"x\"\n\n#define PRIX8  \"X\"\n#define PRIX16 \"X\"\n#define PRIX32 \"X\"\n#define PRIX64 __PRI64 \"X\"\n\n#define PRIXLEAST8  \"X\"\n#define PRIXLEAST16 \"X\"\n#define PRIXLEAST32 \"X\"\n#define PRIXLEAST64 __PRI64 \"X\"\n\n#define PRIXFAST8  \"X\"\n#define PRIXFAST16 \"X\"\n#define PRIXFAST32 \"X\"\n#define PRIXFAST64 __PRI64 \"X\"\n\n#define PRIdMAX __PRI64 \"d\"\n#define PRIiMAX __PRI64 \"i\"\n#define PRIoMAX __PRI64 \"o\"\n#define PRIuMAX __PRI64 \"u\"\n#define PRIxMAX __PRI64 \"x\"\n#define PRIXMAX __PRI64 \"X\"\n\n#define PRIdPTR __PRIPTR \"d\"\n#define PRIiPTR __PRIPTR \"i\"\n#define PRIoPTR __PRIPTR \"o\"\n#define PRIuPTR __PRIPTR \"u\"\n#define PRIxPTR __PRIPTR \"x\"\n#define PRIXPTR __PRIPTR \"X\"\n\n#define SCNd8   \"hhd\"\n#define SCNd16  \"hd\"\n#define SCNd32  \"d\"\n#define SCNd64  __PRI64 \"d\"\n\n#define SCNdLEAST8  \"hhd\"\n#define SCNdLEAST16 \"hd\"\n#define SCNdLEAST32 \"d\"\n#define SCNdLEAST64 __PRI64 \"d\"\n\n#define SCNdFAST8  \"hhd\"\n#define SCNdFAST16 \"d\"\n#define SCNdFAST32 \"d\"\n#define SCNdFAST64 __PRI64 \"d\"\n\n#define SCNi8   \"hhi\"\n#define SCNi16  \"hi\"\n#define SCNi32  \"i\"\n#define SCNi64  __PRI64 \"i\"\n\n#define SCNiLEAST8  \"hhi\"\n#define SCNiLEAST16 \"hi\"\n#define SCNiLEAST32 \"i\"\n#define SCNiLEAST64 __PRI64 \"i\"\n\n#define SCNiFAST8  \"hhi\"\n#define SCNiFAST16 \"i\"\n#define SCNiFAST32 \"i\"\n#define SCNiFAST64 __PRI64 \"i\"\n\n#define SCNu8   \"hhu\"\n#define SCNu16  \"hu\"\n#define SCNu32  \"u\"\n#define SCNu64  __PRI64 \"u\"\n\n#define SCNuLEAST8  \"hhu\"\n#define SCNuLEAST16 \"hu\"\n#define SCNuLEAST32 \"u\"\n#define SCNuLEAST64 __PRI64 \"u\"\n\n#define SCNuFAST8 \"hhu\"\n#define SCNuFAST16 \"u\"\n#define SCNuFAST32 \"u\"\n#define SCNuFAST64 __PRI64 \"u\"\n\n#define SCNo8   \"hho\"\n#define SCNo16  \"ho\"\n#define SCNo32  \"o\"\n#define SCNo64  __PRI64 \"o\"\n\n#define SCNoLEAST8  \"hho\"\n#define SCNoLEAST16 \"ho\"\n#define SCNoLEAST32 \"o\"\n#define SCNoLEAST64 __PRI64 \"o\"\n\n#define SCNoFAST8  \"hho\"\n#define SCNoFAST16 \"o\"\n#define SCNoFAST32 \"o\"\n#define SCNoFAST64 __PRI64 \"o\"\n\n#define SCNx8   \"hhx\"\n#define SCNx16  \"hx\"\n#define SCNx32  \"x\"\n#define SCNx64  __PRI64 \"x\"\n\n#define SCNxLEAST8  \"hhx\"\n#define SCNxLEAST16 \"hx\"\n#define SCNxLEAST32 \"x\"\n#define SCNxLEAST64 __PRI64 \"x\"\n\n#define SCNxFAST8  \"hhx\"\n#define SCNxFAST16 \"x\"\n#define SCNxFAST32 \"x\"\n#define SCNxFAST64 __PRI64 \"x\"\n\n#define SCNdMAX __PRI64 \"d\"\n#define SCNiMAX __PRI64 \"i\"\n#define SCNoMAX __PRI64 \"o\"\n#define SCNuMAX __PRI64 \"u\"\n#define SCNxMAX __PRI64 \"x\"\n\n#define SCNdPTR __PRIPTR \"d\"\n#define SCNiPTR __PRIPTR \"i\"\n#define SCNoPTR __PRIPTR \"o\"\n#define SCNuPTR __PRIPTR \"u\"\n#define SCNxPTR __PRIPTR \"x\"\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n\n"
  },
  {
    "path": "user.libc/include/iso646.h",
    "content": "#ifndef _ISO646_H\n#define _ISO646_H\n\n#ifndef __cplusplus\n\n#define and    &&\n#define and_eq &=\n#define bitand &\n#define bitor  |\n#define compl  ~\n#define not    !\n#define not_eq !=\n#define or     ||\n#define or_eq  |=\n#define xor    ^\n#define xor_eq ^=\n\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/langinfo.h",
    "content": "#ifndef _LANGINFO_H\n#define _LANGINFO_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n#include <nl_types.h>\n\n#define __NEED_locale_t\n\n#include <bits/alltypes.h>\n\n#define ABDAY_1 0x20000\n#define ABDAY_2 0x20001\n#define ABDAY_3 0x20002\n#define ABDAY_4 0x20003\n#define ABDAY_5 0x20004\n#define ABDAY_6 0x20005\n#define ABDAY_7 0x20006\n\n#define DAY_1 0x20007\n#define DAY_2 0x20008\n#define DAY_3 0x20009\n#define DAY_4 0x2000A\n#define DAY_5 0x2000B\n#define DAY_6 0x2000C\n#define DAY_7 0x2000D\n\n#define ABMON_1 0x2000E\n#define ABMON_2 0x2000F\n#define ABMON_3 0x20010\n#define ABMON_4 0x20011\n#define ABMON_5 0x20012\n#define ABMON_6 0x20013\n#define ABMON_7 0x20014\n#define ABMON_8 0x20015\n#define ABMON_9 0x20016\n#define ABMON_10 0x20017\n#define ABMON_11 0x20018\n#define ABMON_12 0x20019\n\n#define MON_1 0x2001A\n#define MON_2 0x2001B\n#define MON_3 0x2001C\n#define MON_4 0x2001D\n#define MON_5 0x2001E\n#define MON_6 0x2001F\n#define MON_7 0x20020\n#define MON_8 0x20021\n#define MON_9 0x20022\n#define MON_10 0x20023\n#define MON_11 0x20024\n#define MON_12 0x20025\n\n#define AM_STR 0x20026\n#define PM_STR 0x20027\n\n#define D_T_FMT 0x20028\n#define D_FMT 0x20029\n#define T_FMT 0x2002A\n#define T_FMT_AMPM 0x2002B\n\n#define ERA 0x2002C\n#define ERA_D_FMT 0x2002E\n#define ALT_DIGITS 0x2002F\n#define ERA_D_T_FMT 0x20030\n#define ERA_T_FMT 0x20031\n\n#define CODESET 14\n\n#define CRNCYSTR 0x4000F\n\n#define RADIXCHAR 0x10000\n#define THOUSEP 0x10001\n#define YESEXPR 0x50000\n#define NOEXPR 0x50001\n\n#define _NL_LOCALE_NAME(cat) (((cat)<<16) | 0xffff)\n\n#if defined(_GNU_SOURCE)\n#define NL_LOCALE_NAME(cat) _NL_LOCALE_NAME(cat)\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define YESSTR 0x50002\n#define NOSTR 0x50003\n#endif\n\nchar *nl_langinfo(nl_item);\nchar *nl_langinfo_l(nl_item, locale_t);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/lastlog.h",
    "content": "#include <utmp.h>\n"
  },
  {
    "path": "user.libc/include/libgen.h",
    "content": "#ifndef _LIBGEN_H\n#define _LIBGEN_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nchar *dirname(char *);\nchar *basename(char *);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/libintl.h",
    "content": "#ifndef _LIBINTL_H\n#define _LIBINTL_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define __USE_GNU_GETTEXT 1\n#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 1 : -1)\n\n#if __GNUC__ >= 3\n#define __fa(n) __attribute__ ((__format_arg__ (n)))\n#else\n#define __fa(n)\n#endif\n\nchar *gettext(const char *) __fa(1);\nchar *dgettext(const char *, const char *) __fa(2);\nchar *dcgettext(const char *, const char *, int) __fa(2);\nchar *ngettext(const char *, const char *, unsigned long) __fa(1) __fa(2);\nchar *dngettext(const char *, const char *, const char *, unsigned long) __fa(2) __fa(3);\nchar *dcngettext(const char *, const char *, const char *, unsigned long, int) __fa(2) __fa(3);\nchar *textdomain(const char *);\nchar *bindtextdomain (const char *, const char *);\nchar *bind_textdomain_codeset(const char *, const char *);\n\n#undef __fa\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/limits.h",
    "content": "#ifndef _LIMITS_H\n#define _LIMITS_H\n\n#include <features.h>\n\n#include <bits/alltypes.h> /* __LONG_MAX */\n\n/* Support signed or unsigned plain-char */\n\n#if '\\xff' > 0\n#define CHAR_MIN 0\n#define CHAR_MAX 255\n#else\n#define CHAR_MIN (-128)\n#define CHAR_MAX 127\n#endif\n\n#define CHAR_BIT 8\n#define SCHAR_MIN (-128)\n#define SCHAR_MAX 127\n#define UCHAR_MAX 255\n#define SHRT_MIN  (-1-0x7fff)\n#define SHRT_MAX  0x7fff\n#define USHRT_MAX 0xffff\n#define INT_MIN  (-1-0x7fffffff)\n#define INT_MAX  0x7fffffff\n#define UINT_MAX 0xffffffffU\n#define LONG_MIN (-LONG_MAX-1)\n#define LONG_MAX __LONG_MAX\n#define ULONG_MAX (2UL*LONG_MAX+1)\n#define LLONG_MIN (-LLONG_MAX-1)\n#define LLONG_MAX  0x7fffffffffffffffLL\n#define ULLONG_MAX (2ULL*LLONG_MAX+1)\n\n#define MB_LEN_MAX 4\n\n#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n\n#include <bits/limits.h>\n\n#define PIPE_BUF 4096\n#define FILESIZEBITS 64\n#ifndef NAME_MAX\n#define NAME_MAX 255\n#endif\n#define PATH_MAX 4096\n#define NGROUPS_MAX 32\n#define ARG_MAX 131072\n#define IOV_MAX 1024\n#define SYMLOOP_MAX 40\n#define WORD_BIT 32\n#define SSIZE_MAX LONG_MAX\n#define TZNAME_MAX 6\n#define TTY_NAME_MAX 32\n#define HOST_NAME_MAX 255\n\n#if LONG_MAX == 0x7fffffffL\n#define LONG_BIT 32\n#else\n#define LONG_BIT 64\n#endif\n\n/* Implementation choices... */\n\n#define PTHREAD_KEYS_MAX 128\n#define PTHREAD_STACK_MIN 2048\n#define PTHREAD_DESTRUCTOR_ITERATIONS 4\n#define SEM_VALUE_MAX 0x7fffffff\n#define SEM_NSEMS_MAX 256\n#define DELAYTIMER_MAX 0x7fffffff\n#define MQ_PRIO_MAX 32768\n#define LOGIN_NAME_MAX 256\n\n/* Arbitrary numbers... */\n\n#define BC_BASE_MAX 99\n#define BC_DIM_MAX 2048\n#define BC_SCALE_MAX 99\n#define BC_STRING_MAX 1000\n#define CHARCLASS_NAME_MAX 14\n#define COLL_WEIGHTS_MAX 2\n#define EXPR_NEST_MAX 32\n#define LINE_MAX 4096\n#define RE_DUP_MAX 255\n\n#define NL_ARGMAX 9\n#define NL_MSGMAX 32767\n#define NL_SETMAX 255\n#define NL_TEXTMAX 2048\n\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_XOPEN_SOURCE)\n\n#ifdef PAGESIZE\n#define PAGE_SIZE PAGESIZE\n#endif\n#define NZERO 20\n#define NL_LANGMAX 32\n\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) \\\n || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 < 700)\n\n#define NL_NMAX 16\n\n#endif\n\n/* POSIX/SUS requirements follow. These numbers come directly\n * from SUS and have nothing to do with the host system. */\n\n#define _POSIX_AIO_LISTIO_MAX   2\n#define _POSIX_AIO_MAX          1\n#define _POSIX_ARG_MAX          4096\n#define _POSIX_CHILD_MAX        25\n#define _POSIX_CLOCKRES_MIN     20000000\n#define _POSIX_DELAYTIMER_MAX   32\n#define _POSIX_HOST_NAME_MAX    255\n#define _POSIX_LINK_MAX         8\n#define _POSIX_LOGIN_NAME_MAX   9\n#define _POSIX_MAX_CANON        255\n#define _POSIX_MAX_INPUT        255\n#define _POSIX_MQ_OPEN_MAX      8\n#define _POSIX_MQ_PRIO_MAX      32\n#define _POSIX_NAME_MAX         14\n#define _POSIX_NGROUPS_MAX      8\n#define _POSIX_OPEN_MAX         20\n#define _POSIX_PATH_MAX         256\n#define _POSIX_PIPE_BUF         512\n#define _POSIX_RE_DUP_MAX       255\n#define _POSIX_RTSIG_MAX        8\n#define _POSIX_SEM_NSEMS_MAX    256\n#define _POSIX_SEM_VALUE_MAX    32767\n#define _POSIX_SIGQUEUE_MAX     32\n#define _POSIX_SSIZE_MAX        32767\n#define _POSIX_STREAM_MAX       8\n#define _POSIX_SS_REPL_MAX      4\n#define _POSIX_SYMLINK_MAX      255\n#define _POSIX_SYMLOOP_MAX      8\n#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4\n#define _POSIX_THREAD_KEYS_MAX  128\n#define _POSIX_THREAD_THREADS_MAX 64\n#define _POSIX_TIMER_MAX        32\n#define _POSIX_TRACE_EVENT_NAME_MAX 30\n#define _POSIX_TRACE_NAME_MAX   8\n#define _POSIX_TRACE_SYS_MAX    8\n#define _POSIX_TRACE_USER_EVENT_MAX 32\n#define _POSIX_TTY_NAME_MAX     9\n#define _POSIX_TZNAME_MAX       6\n#define _POSIX2_BC_BASE_MAX     99\n#define _POSIX2_BC_DIM_MAX      2048\n#define _POSIX2_BC_SCALE_MAX    99\n#define _POSIX2_BC_STRING_MAX   1000\n#define _POSIX2_CHARCLASS_NAME_MAX 14\n#define _POSIX2_COLL_WEIGHTS_MAX 2\n#define _POSIX2_EXPR_NEST_MAX   32\n#define _POSIX2_LINE_MAX        2048\n#define _POSIX2_RE_DUP_MAX      255\n\n#define _XOPEN_IOV_MAX          16\n#define _XOPEN_NAME_MAX         255\n#define _XOPEN_PATH_MAX         1024\n\n#endif\n"
  },
  {
    "path": "user.libc/include/link.h",
    "content": "#ifndef _LINK_H\n#define _LINK_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <elf.h>\n#define __NEED_size_t\n#define __NEED_uint32_t\n#include <bits/alltypes.h>\n\n#if UINTPTR_MAX > 0xffffffff\n#define ElfW(type) Elf64_ ## type\n#else\n#define ElfW(type) Elf32_ ## type\n#endif\n\n#include <bits/link.h>\n\nstruct dl_phdr_info {\n\tElfW(Addr) dlpi_addr;\n\tconst char *dlpi_name;\n\tconst ElfW(Phdr) *dlpi_phdr;\n\tElfW(Half) dlpi_phnum;\n\tunsigned long long int dlpi_adds;\n\tunsigned long long int dlpi_subs;\n\tsize_t dlpi_tls_modid;\n\tvoid *dlpi_tls_data;\n};\n\nstruct link_map {\n\tElfW(Addr) l_addr;\n\tchar *l_name;\n\tElfW(Dyn) *l_ld;\n\tstruct link_map *l_next, *l_prev;\n};\n\nstruct r_debug {\n\tint r_version;\n\tstruct link_map *r_map;\n\tElfW(Addr) r_brk;\n\tenum { RT_CONSISTENT, RT_ADD, RT_DELETE } r_state;\n\tElfW(Addr) r_ldbase;\n};\n\nint dl_iterate_phdr(int (*)(struct dl_phdr_info *, size_t, void *), void *);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/locale.h",
    "content": "#ifndef\t_LOCALE_H\n#define\t_LOCALE_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#ifdef __cplusplus\n#define NULL 0L\n#else\n#define NULL ((void*)0)\n#endif\n\n#define LC_CTYPE    0\n#define LC_NUMERIC  1\n#define LC_TIME     2\n#define LC_COLLATE  3\n#define LC_MONETARY 4\n#define LC_MESSAGES 5\n#define LC_ALL      6\n\nstruct lconv {\n\tchar *decimal_point;\n\tchar *thousands_sep;\n\tchar *grouping;\n\n\tchar *int_curr_symbol;\n\tchar *currency_symbol;\n\tchar *mon_decimal_point;\n\tchar *mon_thousands_sep;\n\tchar *mon_grouping;\n\tchar *positive_sign;\n\tchar *negative_sign;\n\tchar int_frac_digits;\n\tchar frac_digits;\n\tchar p_cs_precedes;\n\tchar p_sep_by_space;\n\tchar n_cs_precedes;\n\tchar n_sep_by_space;\n\tchar p_sign_posn;\n\tchar n_sign_posn;\n\tchar int_p_cs_precedes;\n\tchar int_p_sep_by_space;\n\tchar int_n_cs_precedes;\n\tchar int_n_sep_by_space;\n\tchar int_p_sign_posn;\n\tchar int_n_sign_posn;\n};\n\n\nchar *setlocale (int, const char *);\nstruct lconv *localeconv(void);\n\n\n#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n\n#define __NEED_locale_t\n\n#include <bits/alltypes.h>\n\n#define LC_GLOBAL_LOCALE ((locale_t)-1)\n\n#define LC_CTYPE_MASK    (1<<LC_CTYPE)\n#define LC_NUMERIC_MASK  (1<<LC_NUMERIC)\n#define LC_TIME_MASK     (1<<LC_TIME)\n#define LC_COLLATE_MASK  (1<<LC_COLLATE)\n#define LC_MONETARY_MASK (1<<LC_MONETARY)\n#define LC_MESSAGES_MASK (1<<LC_MESSAGES)\n#define LC_ALL_MASK      0x7fffffff\n\nlocale_t duplocale(locale_t);\nvoid freelocale(locale_t);\nlocale_t newlocale(int, const char *, locale_t);\nlocale_t uselocale(locale_t);\n\n#endif\n\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/malloc.h",
    "content": "#ifndef _MALLOC_H\n#define _MALLOC_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define __NEED_size_t\n\n#include <bits/alltypes.h>\n\nvoid *malloc (size_t);\nvoid *calloc (size_t, size_t);\nvoid *realloc (void *, size_t);\nvoid free (void *);\nvoid *valloc (size_t);\nvoid *memalign(size_t, size_t);\n\nsize_t malloc_usable_size(void *);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/math.h",
    "content": "#ifndef _MATH_H\n#define _MATH_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_float_t\n#define __NEED_double_t\n#include <bits/alltypes.h>\n\n#if 100*__GNUC__+__GNUC_MINOR__ >= 303\n#define NAN       __builtin_nanf(\"\")\n#define INFINITY  __builtin_inff()\n#else\n#define NAN       (0.0f/0.0f)\n#define INFINITY  1e5000f\n#endif\n\n#define HUGE_VALF INFINITY\n#define HUGE_VAL  ((double)INFINITY)\n#define HUGE_VALL ((long double)INFINITY)\n\n#define MATH_ERRNO  1\n#define MATH_ERREXCEPT 2\n#define math_errhandling 2\n\n#define FP_ILOGBNAN (-1-0x7fffffff)\n#define FP_ILOGB0 FP_ILOGBNAN\n\n#define FP_NAN       0\n#define FP_INFINITE  1\n#define FP_ZERO      2\n#define FP_SUBNORMAL 3\n#define FP_NORMAL    4\n\n#ifdef __FP_FAST_FMA\n#define FP_FAST_FMA 1\n#endif\n\n#ifdef __FP_FAST_FMAF\n#define FP_FAST_FMAF 1\n#endif\n\n#ifdef __FP_FAST_FMAL\n#define FP_FAST_FMAL 1\n#endif\n\nint __fpclassify(double);\nint __fpclassifyf(float);\nint __fpclassifyl(long double);\n\nstatic __inline unsigned __FLOAT_BITS(float __f)\n{\n\tunion {float __f; unsigned __i;} __u;\n\t__u.__f = __f;\n\treturn __u.__i;\n}\nstatic __inline unsigned long long __DOUBLE_BITS(double __f)\n{\n\tunion {double __f; unsigned long long __i;} __u;\n\t__u.__f = __f;\n\treturn __u.__i;\n}\n\n#define fpclassify(x) ( \\\n\tsizeof(x) == sizeof(float) ? __fpclassifyf(x) : \\\n\tsizeof(x) == sizeof(double) ? __fpclassify(x) : \\\n\t__fpclassifyl(x) )\n\n#define isinf(x) ( \\\n\tsizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) == 0x7f800000 : \\\n\tsizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL>>1) == 0x7ffULL<<52 : \\\n\t__fpclassifyl(x) == FP_INFINITE)\n\n#define isnan(x) ( \\\n\tsizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) > 0x7f800000 : \\\n\tsizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL>>1) > 0x7ffULL<<52 : \\\n\t__fpclassifyl(x) == FP_NAN)\n\n#define isnormal(x) ( \\\n\tsizeof(x) == sizeof(float) ? ((__FLOAT_BITS(x)+0x00800000) & 0x7fffffff) >= 0x01000000 : \\\n\tsizeof(x) == sizeof(double) ? ((__DOUBLE_BITS(x)+(1ULL<<52)) & -1ULL>>1) >= 1ULL<<53 : \\\n\t__fpclassifyl(x) == FP_NORMAL)\n\n#define isfinite(x) ( \\\n\tsizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) < 0x7f800000 : \\\n\tsizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL>>1) < 0x7ffULL<<52 : \\\n\t__fpclassifyl(x) > FP_INFINITE)\n\nint __signbit(double);\nint __signbitf(float);\nint __signbitl(long double);\n\n#define signbit(x) ( \\\n\tsizeof(x) == sizeof(float) ? (int)(__FLOAT_BITS(x)>>31) : \\\n\tsizeof(x) == sizeof(double) ? (int)(__DOUBLE_BITS(x)>>63) : \\\n\t__signbitl(x) )\n\n#define isunordered(x,y) (isnan((x)) ? ((void)(y),1) : isnan((y)))\n\n#define __ISREL_DEF(rel, op, type) \\\nstatic __inline int __is##rel(type __x, type __y) \\\n{ return !isunordered(__x,__y) && __x op __y; }\n\n__ISREL_DEF(lessf, <, float_t)\n__ISREL_DEF(less, <, double_t)\n__ISREL_DEF(lessl, <, long double)\n__ISREL_DEF(lessequalf, <=, float_t)\n__ISREL_DEF(lessequal, <=, double_t)\n__ISREL_DEF(lessequall, <=, long double)\n__ISREL_DEF(lessgreaterf, !=, float_t)\n__ISREL_DEF(lessgreater, !=, double_t)\n__ISREL_DEF(lessgreaterl, !=, long double)\n__ISREL_DEF(greaterf, >, float_t)\n__ISREL_DEF(greater, >, double_t)\n__ISREL_DEF(greaterl, >, long double)\n__ISREL_DEF(greaterequalf, >=, float_t)\n__ISREL_DEF(greaterequal, >=, double_t)\n__ISREL_DEF(greaterequall, >=, long double)\n\n#define __tg_pred_2(x, y, p) ( \\\n\tsizeof((x)+(y)) == sizeof(float) ? p##f(x, y) : \\\n\tsizeof((x)+(y)) == sizeof(double) ? p(x, y) : \\\n\tp##l(x, y) )\n\n#define isless(x, y)            __tg_pred_2(x, y, __isless)\n#define islessequal(x, y)       __tg_pred_2(x, y, __islessequal)\n#define islessgreater(x, y)     __tg_pred_2(x, y, __islessgreater)\n#define isgreater(x, y)         __tg_pred_2(x, y, __isgreater)\n#define isgreaterequal(x, y)    __tg_pred_2(x, y, __isgreaterequal)\n\ndouble      acos(double);\nfloat       acosf(float);\nlong double acosl(long double);\n\ndouble      acosh(double);\nfloat       acoshf(float);\nlong double acoshl(long double);\n\ndouble      asin(double);\nfloat       asinf(float);\nlong double asinl(long double);\n\ndouble      asinh(double);\nfloat       asinhf(float);\nlong double asinhl(long double);\n\ndouble      atan(double);\nfloat       atanf(float);\nlong double atanl(long double);\n\ndouble      atan2(double, double);\nfloat       atan2f(float, float);\nlong double atan2l(long double, long double);\n\ndouble      atanh(double);\nfloat       atanhf(float);\nlong double atanhl(long double);\n\ndouble      cbrt(double);\nfloat       cbrtf(float);\nlong double cbrtl(long double);\n\ndouble      ceil(double);\nfloat       ceilf(float);\nlong double ceill(long double);\n\ndouble      copysign(double, double);\nfloat       copysignf(float, float);\nlong double copysignl(long double, long double);\n\ndouble      cos(double);\nfloat       cosf(float);\nlong double cosl(long double);\n\ndouble      cosh(double);\nfloat       coshf(float);\nlong double coshl(long double);\n\ndouble      erf(double);\nfloat       erff(float);\nlong double erfl(long double);\n\ndouble      erfc(double);\nfloat       erfcf(float);\nlong double erfcl(long double);\n\ndouble      exp(double);\nfloat       expf(float);\nlong double expl(long double);\n\ndouble      exp2(double);\nfloat       exp2f(float);\nlong double exp2l(long double);\n\ndouble      expm1(double);\nfloat       expm1f(float);\nlong double expm1l(long double);\n\ndouble      fabs(double);\nfloat       fabsf(float);\nlong double fabsl(long double);\n\ndouble      fdim(double, double);\nfloat       fdimf(float, float);\nlong double fdiml(long double, long double);\n\ndouble      floor(double);\nfloat       floorf(float);\nlong double floorl(long double);\n\ndouble      fma(double, double, double);\nfloat       fmaf(float, float, float);\nlong double fmal(long double, long double, long double);\n\ndouble      fmax(double, double);\nfloat       fmaxf(float, float);\nlong double fmaxl(long double, long double);\n\ndouble      fmin(double, double);\nfloat       fminf(float, float);\nlong double fminl(long double, long double);\n\ndouble      fmod(double, double);\nfloat       fmodf(float, float);\nlong double fmodl(long double, long double);\n\ndouble      frexp(double, int *);\nfloat       frexpf(float, int *);\nlong double frexpl(long double, int *);\n\ndouble      hypot(double, double);\nfloat       hypotf(float, float);\nlong double hypotl(long double, long double);\n\nint         ilogb(double);\nint         ilogbf(float);\nint         ilogbl(long double);\n\ndouble      ldexp(double, int);\nfloat       ldexpf(float, int);\nlong double ldexpl(long double, int);\n\ndouble      lgamma(double);\nfloat       lgammaf(float);\nlong double lgammal(long double);\n\nlong long   llrint(double);\nlong long   llrintf(float);\nlong long   llrintl(long double);\n\nlong long   llround(double);\nlong long   llroundf(float);\nlong long   llroundl(long double);\n\ndouble      log(double);\nfloat       logf(float);\nlong double logl(long double);\n\ndouble      log10(double);\nfloat       log10f(float);\nlong double log10l(long double);\n\ndouble      log1p(double);\nfloat       log1pf(float);\nlong double log1pl(long double);\n\ndouble      log2(double);\nfloat       log2f(float);\nlong double log2l(long double);\n\ndouble      logb(double);\nfloat       logbf(float);\nlong double logbl(long double);\n\nlong        lrint(double);\nlong        lrintf(float);\nlong        lrintl(long double);\n\nlong        lround(double);\nlong        lroundf(float);\nlong        lroundl(long double);\n\ndouble      modf(double, double *);\nfloat       modff(float, float *);\nlong double modfl(long double, long double *);\n\ndouble      nan(const char *);\nfloat       nanf(const char *);\nlong double nanl(const char *);\n\ndouble      nearbyint(double);\nfloat       nearbyintf(float);\nlong double nearbyintl(long double);\n\ndouble      nextafter(double, double);\nfloat       nextafterf(float, float);\nlong double nextafterl(long double, long double);\n\ndouble      nexttoward(double, long double);\nfloat       nexttowardf(float, long double);\nlong double nexttowardl(long double, long double);\n\ndouble      pow(double, double);\nfloat       powf(float, float);\nlong double powl(long double, long double);\n\ndouble      remainder(double, double);\nfloat       remainderf(float, float);\nlong double remainderl(long double, long double);\n\ndouble      remquo(double, double, int *);\nfloat       remquof(float, float, int *);\nlong double remquol(long double, long double, int *);\n\ndouble      rint(double);\nfloat       rintf(float);\nlong double rintl(long double);\n\ndouble      round(double);\nfloat       roundf(float);\nlong double roundl(long double);\n\ndouble      scalbln(double, long);\nfloat       scalblnf(float, long);\nlong double scalblnl(long double, long);\n\ndouble      scalbn(double, int);\nfloat       scalbnf(float, int);\nlong double scalbnl(long double, int);\n\ndouble      sin(double);\nfloat       sinf(float);\nlong double sinl(long double);\n\ndouble      sinh(double);\nfloat       sinhf(float);\nlong double sinhl(long double);\n\ndouble      sqrt(double);\nfloat       sqrtf(float);\nlong double sqrtl(long double);\n\ndouble      tan(double);\nfloat       tanf(float);\nlong double tanl(long double);\n\ndouble      tanh(double);\nfloat       tanhf(float);\nlong double tanhl(long double);\n\ndouble      tgamma(double);\nfloat       tgammaf(float);\nlong double tgammal(long double);\n\ndouble      trunc(double);\nfloat       truncf(float);\nlong double truncl(long double);\n\n\n#if defined(_XOPEN_SOURCE) || defined(_BSD_SOURCE)\n#undef  MAXFLOAT\n#define MAXFLOAT        3.40282346638528859812e+38F\n#endif\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define M_E             2.7182818284590452354   /* e */\n#define M_LOG2E         1.4426950408889634074   /* log_2 e */\n#define M_LOG10E        0.43429448190325182765  /* log_10 e */\n#define M_LN2           0.69314718055994530942  /* log_e 2 */\n#define M_LN10          2.30258509299404568402  /* log_e 10 */\n#define M_PI            3.14159265358979323846  /* pi */\n#define M_PI_2          1.57079632679489661923  /* pi/2 */\n#define M_PI_4          0.78539816339744830962  /* pi/4 */\n#define M_1_PI          0.31830988618379067154  /* 1/pi */\n#define M_2_PI          0.63661977236758134308  /* 2/pi */\n#define M_2_SQRTPI      1.12837916709551257390  /* 2/sqrt(pi) */\n#define M_SQRT2         1.41421356237309504880  /* sqrt(2) */\n#define M_SQRT1_2       0.70710678118654752440  /* 1/sqrt(2) */\n\nextern int signgam;\n\ndouble      j0(double);\ndouble      j1(double);\ndouble      jn(int, double);\n\ndouble      y0(double);\ndouble      y1(double);\ndouble      yn(int, double);\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define HUGE            3.40282346638528859812e+38F\n\ndouble      drem(double, double);\nfloat       dremf(float, float);\n\nint         finite(double);\nint         finitef(float);\n\ndouble      scalb(double, double);\nfloat       scalbf(float, float);\n\ndouble      significand(double);\nfloat       significandf(float);\n\ndouble      lgamma_r(double, int*);\nfloat       lgammaf_r(float, int*);\n\nfloat       j0f(float);\nfloat       j1f(float);\nfloat       jnf(int, float);\n\nfloat       y0f(float);\nfloat       y1f(float);\nfloat       ynf(int, float);\n#endif\n\n#ifdef _GNU_SOURCE\nlong double lgammal_r(long double, int*);\n\nvoid        sincos(double, double*, double*);\nvoid        sincosf(float, float*, float*);\nvoid        sincosl(long double, long double*, long double*);\n\ndouble      exp10(double);\nfloat       exp10f(float);\nlong double exp10l(long double);\n\ndouble      pow10(double);\nfloat       pow10f(float);\nlong double pow10l(long double);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/memory.h",
    "content": "#include <string.h>\n"
  },
  {
    "path": "user.libc/include/minos/barrier.h",
    "content": "#ifndef __LIBC_BARRIER_H__\n#define __LIBC_BARRIER_H__\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define __isb()\t\tasm volatile(\"isb\" : : : \"memory\")\n#define __dmb(opt)\tasm volatile(\"dmb \" #opt : : : \"memory\")\n#define __dsb(opt)\tasm volatile(\"dsb \" #opt : : : \"memory\")\n\n#define isb()\t\t__isb();\n\n#define mb()\t\t__dsb(sy)\n#define rmb()\t\t__dsb(ld)\n#define wmb()\t\t__dsb(st)\n\n#define dma_rmb()\t__dmb(oshld)\n#define dma_wmb()\t__dmb(oshst)\n\n#define iormb()\t\tdma_rmb()\n#define iowmb()\t\tdma_wmb()\n\n#define smp_mb()\t__dmb(ish)\n#define smp_rmb()\t__dmb(ishld)\n#define smp_wmb()\t__dmb(ishst)\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/minos/compiler.h",
    "content": "#ifndef __MINOS_COMPILER_H_\n#define __MINOS_COMPILER_H_\n\n#define __section(S)\t\t__attribute__((__section__(#S)))\n#define __used\t\t\t__attribute__((__used__))\n#define __unused\t\t__attribute__((__unused__))\n#define __align(x)\t\t__attribute__((__aligned__(x)))\n#define __packed\t\t__attribute__((__packed__))\n#define unused(__arg__)\t\t(void)(__arg__)\n\n#ifndef likely\n#define likely(x) __builtin_expect(!!(x), 1)\n#endif\n\n#ifndef unlikely\n#define unlikely(x) __builtin_expect(!!(x), 0)\n#endif\n\n#ifndef __noreturn\n#define __noreturn __attribute__((noreturn))\n#endif\n\n#ifndef barrier\n#define barrier() __asm__ __volatile__(\"\" ::: \"memory\")\n#endif\n\n#ifndef weak\n#define weak __attribute__((__weak__))\n#endif\n\n#ifndef hidden\n#define hidden __attribute__((__visibility__(\"hidden\")))\n#endif\n\n#ifndef weak_alias\n#define weak_alias(old, new) \\\n        extern __typeof(old) new __attribute__((__weak__, __alias__(#old)))\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/minos/debug.h",
    "content": "#ifndef __MINOS_SYS_PRINT_H__\n#define __MINOS_SYS_PRINT_H__\n\n#include <stdio.h>\n\n#ifndef APP_TAG\n#define APP_TAG \"libc\"\n#endif\n\n#if 0\n#define __pr_debug(...)\t\t\t\t\t\\\n\tdo {\t\t\t\t\t\t\\\n\t\tprintf(\"[DEBUG] \" __VA_ARGS__);\t\t\\\n\t} while (0)\n\n#ifdef __DEBUG__\n#define pr_debug(...)\t__pr_debug(__VA_ARGS__)\n#else\n#define pr_debug(...)\n#endif\n\n#define pr_err(...)\t\t\t\t\t\\\n\tdo {\t\t\t\t\t\t\\\n\t\tprintf(\"[ERROR] \" __VA_ARGS__);\t\t\\\n\t} while (0)\n\n#define pr_notice(...)\t\t\t\t\t\\\n\tdo {\t\t\t\t\t\t\\\n\t\tprintf(\"[NIC  ] \" __VA_ARGS__);\t\t\\\n\t} while (0)\n\n#define pr_info(...)\t\t\t\t\t\\\n\tdo {\t\t\t\t\t\t\\\n\t\tprintf(\"[INFO ] \" __VA_ARGS__);\t\t\\\n\t} while (0)\n\n#define pr_warn(...)\t\t\t\t\t\\\n\tdo {\t\t\t\t\t\t\\\n\t\tprintf(\"[WARN ] \" __VA_ARGS__);\t\t\\\n\t} while (0)\n#endif\n\n#define __pr_debug(...)\t\t\t\t\t\\\n\tdo {\t\t\t\t\t\t\\\n\t\tprintf(APP_TAG\": \" __VA_ARGS__);\t\\\n\t} while (0)\n\n#ifdef __DEBUG__\n#define pr_debug(...)\t__pr_debug(__VA_ARGS__)\n#else\n#define pr_debug(...)\n#endif\n\n#define pr_err(...)\t\t\t\t\t\\\n\tdo {\t\t\t\t\t\t\\\n\t\tprintf(APP_TAG\": \" __VA_ARGS__);\t\\\n\t} while (0)\n\n#define pr_notice(...)\t\t\t\t\t\\\n\tdo {\t\t\t\t\t\t\\\n\t\tprintf(APP_TAG\": \" __VA_ARGS__);\t\\\n\t} while (0)\n\n#define pr_info(...)\t\t\t\t\t\\\n\tdo {\t\t\t\t\t\t\\\n\t\tprintf(APP_TAG\": \" __VA_ARGS__);\t\\\n\t} while (0)\n\n#define pr_warn(...)\t\t\t\t\t\\\n\tdo {\t\t\t\t\t\t\\\n\t\tprintf(APP_TAG\": \" __VA_ARGS__);\t\\\n\t} while (0)\n\n\n#endif\n"
  },
  {
    "path": "user.libc/include/minos/device.h",
    "content": "#ifndef __LIBC_DEVICE_H__\n#define __LIBC_DEVICE_H__\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n#include <minos/types.h>\n#include <minos/barrier.h>\n\n#define WRITE32(_reg, _val)                                                    \\\n\tdo {                                                                   \\\n\t\tregister uint32_t __myval__ = (_val);                          \\\n\t\t*(volatile uint32_t *)&(_reg) = __myval__;                     \\\n\t} while (0)\n#define WRITE64(_reg, _val)                                                    \\\n\tdo {                                                                   \\\n\t\tregister uint64_t __myval__ = (_val);                          \\\n\t\t*(volatile uint64_t *)&(_reg) = __myval__;                     \\\n\t} while (0)\n#define READ32(_reg) (*(volatile uint32_t *)&(_reg))\n#define READ64(_reg) (*(volatile uint64_t *)&(_reg))\n\nint request_irq_by_handle(int handle);\nint request_consequent_pma(size_t memsize, int right);\nvoid *request_mmio_by_handle(int handle);\nint get_device_mmio_handle(const char *comp, int index);\nint get_device_irq_handle(const char *comp, int index);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/minos/kobject.h",
    "content": "#ifndef __LIBC_KOBJECT_H__\n#define __LIBC_KOBJECT_H__\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <sys/types.h>\n#include <stdint.h>\n#include <minos/kobject_uapi.h>\n\n#define KR_R KOBJ_RIGHT_READ\n#define KR_W KOBJ_RIGHT_WRITE\n#define KR_X KOBJ_RIGHT_EXEC\n#define KR_C KOBJ_RIGHT_CTL\n#define KR_M KOBJ_RIGHT_MMAP\n\n#define KR_RW (KR_R | KR_W)\n#define KR_RWX (KR_R | KR_W | KR_X)\n#define KR_RWC (KR_R | KR_W | KR_C)\n#define KR_RWM (KR_R | KR_W | KR_M)\n#define KR_RWCM (KR_R | KR_W | KR_C | KR_M)\n#define KR_RM (KR_R | KR_M)\n#define KR_WM (KR_W | KR_M)\n#define KR_RC (KR_R | KR_C)\n#define KR_WC (KR_W | KR_C)\n#define KR_RCM\t(KR_R | KR_C | KR_M)\n#define KR_WCM\t(KR_W | KR_C | KR_M)\n\n/*\n * kobject related API.\n */\nint kobject_open(int handle);\n\nint kobject_close(int handle);\n\nint kobject_create(int type, unsigned long data);\n\nlong kobject_read(int handle, void *data, size_t data_size,\n\t\tsize_t *actual_data, void *extra, size_t extra_size,\n\t\tsize_t *actual_extra, uint32_t timeout);\n\nstatic inline long kobject_read_simple(int handle, void *data,\n\t\tsize_t data_size, uint32_t timeout)\n{\n\treturn kobject_read(handle, data, data_size, (size_t *)0,\n\t\t\t(void *)0, 0, (size_t *)0, timeout);\n}\n\nlong kobject_write(int handle, void *data, size_t data_size,\n\t\tvoid *extra, size_t extra_size, uint32_t timeout);\n\nint kobject_reply(int handle, long token, long err_code, int fd, int right);\n\nint kobject_reply_errcode(int handle, long token, long err_code);\n\nint kobject_mmap(int handle, void *addr, size_t *msize);\n\nint kobject_munmap(int handle);\n\nlong kobject_ctl(int handle, int action, unsigned long data);\n\nint grant(int proc, int handle, int right);\n\nint kobject_create_endpoint(size_t shmem_size);\n\nint kobject_create_port(void);\n\nint kobject_create_notify(void);\n\nint kobject_create_pma(size_t memsize, int right);\n\nint kobject_create_consequent_pma(size_t memsize, int right);\n\nstatic inline int kobject_reply_handle(int fd, long token,\n\t\tint handle, int right)\n{\n\tif (handle > 0)\n\t\treturn kobject_reply(fd, token, 0, handle, right);\n\telse\n\t\treturn kobject_reply(fd, token, handle, 0, 0);\n}\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/minos/kobject_uapi.h",
    "content": "#ifndef __MINOS_KOBJECT_UAPI_H__\n#define __MINOS_KOBJECT_UAPI_H__\n\n#define KOBJ_RIGHT_NONE\t\t0x0000\t\t// do not have any right.\n#define KOBJ_RIGHT_READ\t\t0x0001\t\t// can read this kobject, usually for IPC between two process.\n#define KOBJ_RIGHT_WRITE\t0x0002\t\t// can write this kobject, usually for IPC between two process.\n#define KOBJ_RIGHT_EXEC\t\t0x0004\t\t// can be exectued.\n#define KOBJ_RIGHT_MMAP\t\t0x0008\t\t// can be mapped to process address space\n#define KOBJ_RIGHT_CTL\t\t0x0010\t\t// can call kobject_ctl for this kobject\n#define KOBJ_RIGHT_MASK\t\t0x001f\n\n#define KOBJ_RIGHT_RW\t\t(KOBJ_RIGHT_READ | KOBJ_RIGHT_WRITE)\n#define KOBJ_RIGHT_RO\t\t(KOBJ_RIGHT_READ)\n#define KOBJ_RIGHT_WO\t\t(KOBJ_RIGHT_WRITE)\n#define KOBJ_RIGHT_RWX\t\t(KOBJ_RIGHT_RW | KOBJ_RIGHT_EXEC)\n\nenum {\n\tKOBJ_TYPE_NONE,\n\tKOBJ_TYPE_PROCESS,\t// process, can be only created by root service\n\tKOBJ_TYPE_NOTIFY,\t// a port, which is a service hub\n\tKOBJ_TYPE_PMA,\t\t// physical memory region, usually used to shared with each other.\t\n\tKOBJ_TYPE_ENDPOINT,\t// endpoint, an point to point ipc way\n\tKOBJ_TYPE_SOCKET,\t// point to point ipc way.\n\tKOBJ_TYPE_VM,\t\t// virtual machine, for Virtualization\n\tKOBJ_TYPE_VCPU,\t\t// vcpu for vm\n\tKOBJ_TYPE_IRQ,\t\t// irq for user-space driver\n\tKOBJ_TYPE_VIRQ,\t\t// virq for vcpu process in user-space.\n\tKOBJ_TYPE_STDIO,\t// dedicated for system debuging\n\tKOBJ_TYPE_POLLHUB,\t// hub for events need to send.\n\tKOBJ_TYPE_PORT,\n\tKOBJ_TYPE_MAX\n};\n\nenum {\n\tKOBJ_GET_MMAP_ADDR = 0x100,\n};\n\n/*\n * for process control\n */\nenum {\n\tKOBJ_PROCESS_GET_PID = 0x1000,\n\tKOBJ_PROCESS_SETUP_SP,\n\tKOBJ_PROCESS_SETUP_REG0,\n\tKOBJ_PROCESS_WAKEUP,\n\tKOBJ_PROCESS_KILL,\n\tKOBJ_PROCESS_GRANT_RIGHT,\n\tKOBJ_PROCESS_SET_NAME,\n};\n\nstruct process_create_arg {\n        unsigned long entry;\n\tunsigned long stack;\n\tint aff;\n\tint prio;\n\tint pid;\n\tint flags;\n};\n\n/*\n * for pma kobject\n */\nenum {\n\tPMA_TYPE_NORMAL = 0,\n\tPMA_TYPE_MMIO,\n\tPMA_TYPE_DMA,\n\tPMA_TYPE_PMEM,\n\tPMA_TYPE_KCACHE,\n\tPMA_TYPE_MAX\n};\n\nenum {\n\tKOBJ_PMA_ADD_PAGES = 0x4000,\n\tKOBJ_PMA_GET_SIZE,\n};\n\nstruct pma_create_arg {\n\tint type;\n\tint right;\n\tint consequent;\n\tunsigned long start;\n\tunsigned long size;\n};\n\n/*\n * for kobject poll\n */\nenum {\n\tKOBJ_POLLHUB_OP_BASE = 0x2000,\n\tKOBJ_POLL_OP_ADD,\n\tKOBJ_POLL_OP_DEL,\n\tKOBJ_POLL_OP_MOD,\n};\n\n#endif\n"
  },
  {
    "path": "user.libc/include/minos/libc.h",
    "content": "#ifndef __LIBC_LIBC_H__\n#define __LIBC_LIBC_H__\n\nvoid libc_set_rootfs_handle(int handle);\n\n#endif\n"
  },
  {
    "path": "user.libc/include/minos/list.h",
    "content": "#ifndef __LIBMINOS_LIST_H__\n#define __LIBMINOS_LIST_H__\n\nstruct list_head;\n\nstruct list_head{\n\tstruct list_head *next, *pre;\n};\n\n#define LIST_HEAD(list)\t\\\nstruct list_head list = {\t\\\n\t.next = &list,\t\\\n\t.pre  = &list,\t\\\n}\n\n#define INIT_LIST_HEAD(list)\t\t\\\n\tdo {\t\t\t\t\\\n\t\tlist.next = &list;\t\\\n\t\tlist.pre = &list;\t\\\n\t} while (0)\n\nstatic void inline init_list(struct list_head *list)\n{\n\tlist->next = list;\n\tlist->pre = list;\n}\n\nstatic void inline list_add(struct list_head *head,\n\t\t\t    struct list_head *new)\n{\n\thead->next->pre = new;\n\tnew->next = head->next;\n\tnew->pre = head;\n\thead->next = new;\n}\n\nstatic void inline list_add_tail(struct list_head *head,\n\t\tstruct list_head *new)\n{\n\thead->pre->next = new;\n\tnew->next = head;\n\tnew->pre = head->pre;\n\thead->pre = new;\n}\n\nstatic void inline list_insert_before(struct list_head *head,\n\t\tstruct list_head *new)\n{\n\tnew->pre = head->pre;\n\tnew->next = head;\n\thead->pre->next = new;\n\thead->pre = new;\n}\n\nstatic void inline list_del(struct list_head *list)\n{\n\tlist->next->pre = list->pre;\n\tlist->pre->next = list->next;\n\tlist->next = (void *)0x0;\n\tlist->pre = (void *)0x0;\n}\n\nstatic void inline list_del_tail(struct list_head *head)\n{\n\thead->pre->pre->next = head;\n\thead->pre = head->pre->pre;\n}\n\nstatic int inline is_list_empty(struct list_head *head)\n{\n\treturn (head->next == head);\n}\n\nstatic int inline is_list_last(struct list_head *head,\n\t\t               struct list_head *list)\n{\n\treturn list->next == head;\n}\n\nstatic inline struct list_head *list_next(struct list_head *list)\n{\n\treturn list->next;\n}\n\nstatic inline struct list_head *list_prve(struct list_head *list)\n{\n\treturn list->pre;\n}\n\n#define list_entry(ptr, type, member)\t\\\n\tcontainer_of(ptr, type, member)\n\n#define list_first_entry(ptr, type, member) \\\n\tlist_entry((ptr)->next, type, member)\n\n#define list_next_entry(pos, member) \\\n\tlist_entry((pos)->member.next, __typeof__(*(pos)), member)\n\n#define list_for_each(head, list)\t\\\n\tfor(list = (head)->next; list != (head); list = list->next)\n\n#define list_for_each_entry(pos, head, member)\t\\\n\tfor (pos = list_entry((head)->next, __typeof__(*pos), member); \\\n\t     &pos->member != (head); \\\n\t     pos = list_entry(pos->member.next, __typeof__(*pos), member))\n\n#define list_for_each_entry_safe(pos, n, head, member)\t\t\t\\\n\tfor (pos = list_first_entry(head, __typeof__(*pos), member),\t\\\n\t\tn = list_next_entry(pos, member);\t\t\t\\\n\t     &pos->member != (head); \t\t\t\t\t\\\n\t     pos = n, n = list_next_entry(n, member))\n\n#endif\n"
  },
  {
    "path": "user.libc/include/minos/mutex.h",
    "content": "#ifndef _MUTEX_H_\n#define _MUTEX_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nstruct mutex {\n\tint lock;\n};\n\n#define DEFINE_MUTEX(name)\t\\\n\tstruct mutex name = {\t\\\n\t\t.lock = 0,\t\\\n\t}\n\nint mutex_lock(struct mutex *m);\nvoid mutex_unlock(struct mutex *m);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/minos/poll.h",
    "content": "#ifndef __LIBC_MINOS_POLL_H__\n#define __LIBC_MINOS_POLL_H__\n\n#include <inttypes.h>\n\n#define POLL_EV_IN\t\t0\n#define POLL_EV_KERNEL\t\t1\n#define POLL_EV_MAX\t\t2\n\n#define POLL_EVENT_DATA_SIZE\t32\n\nstruct poll_event {\n\tint event;\n\tint handle;\n\tunsigned char data[POLL_EVENT_DATA_SIZE];\n};\n\nint poll_wait(int handke, struct poll_event *events,\n\t\tint max_event, uint32_t timeout);\n\n#endif\n"
  },
  {
    "path": "user.libc/include/minos/procinfo.h",
    "content": "#ifndef __LIBC_PROCESS_INFO_H__\n#define __LIBC_PROCESS_INFO_H__\n\n#include <inttypes.h>\n#include <minos/procinfo_uapi.h>\n\nint sys_proccnt(void);\nint sys_procinfo_handle(void);\nint sys_taskstat_handle(void);\n\n#endif\n"
  },
  {
    "path": "user.libc/include/minos/procinfo_uapi.h",
    "content": "#ifndef __MINOS_PROC_UAPI_INFO_H__\n#define __MINOS_PROC_UAPI_INFO_H__\n\n#define PROC_NAME_SIZE 256\n\nstruct task_stat {\n\tint tid;\n\tint root_tid;\n\tint pid;\n\tint state;\n\tint cpu;\n\tint cpu_usage;\n\tint prio;\n\tunsigned long long start_ns;\n\tchar cmd[PROC_NAME_SIZE];\n};\n\n#endif\n"
  },
  {
    "path": "user.libc/include/minos/proto.h",
    "content": "#ifndef __MINOS_PROTO_H__\n#define __MINOS_PROTO_H__\n\n#include <stdio.h>\n#include <stdint.h>\n\nenum {\n\tPROTO_IAMOK = 0x1024,\n\tPROTO_ELF_INFO,\n\tPROTO_MMAP,\n\tPROTO_MUNMAP,\n\tPROTO_MPROTECT,\n\tPROTO_BRK,\n\tPROTO_EXECV,\n\tPROTO_PROCCNT,\n\tPROTO_PROCINFO,\n\tPROTO_TASKSTAT,\n\tPROTO_WAITPID,\n\tPROTO_PANGU_END,\n};\n\nenum {\n\tPROTO_IAMOK_ID = 0,\n\tPROTO_ELF_INFO_ID,\n\tPROTO_MMAP_ID,\n\tPROTO_MUNMAP_ID,\n\tPROTO_MPROTECT_ID,\n\tPROTO_BRK_ID,\n\tPROTO_EXECV_ID,\n\tPROTO_PROCCNT_ID,\n\tPROTO_PROCINFO_ID,\n\tPROTO_TASKSTAT_ID,\n\tPROTO_WAITPID_ID,\n\tPROTO_PROC_ID_MAX,\n};\n\nenum {\n\tPROTO_OPEN = 0x2048,\n\tPROTO_OPENAT,\n\tPROTO_READ,\n\tPROTO_WRITE,\n\tPROTO_IOCTL,\n\tPROTO_LSEEK,\n\tPROTO_STAT,\n\tPROTO_ACCESS,\n\tPROTO_GETDENTS,\n\tPROTO_REGISTER_SERVICE,\n\tPROTO_VFS_END,\n};\n\nenum {\n\tPROTO_ROOTFS_READY = 0x4096,\n\tPROTO_LOAD_DRIVER,\n\tPROTO_GET_MMIO,\n\tPROTO_GET_IRQ,\n\tPROTO_GET_DMA_CHANEL,\n\tPROTO_GET_IOMMU_SID,\n\tPROTO_CHIYOU_END,\n};\n\nstruct proto_waitpid {\n\tint pid;\n\tint options;\n};\n\nstruct proto_elf_info {\n\tint ret_code;\n\tuint64_t token;\n\tunsigned long entry;\n\tunsigned long elf_base;\n\tunsigned long elf_size;\n};\n\nstruct proto_mprotect {\n\tvoid *addr;\n\tsize_t len;\n\tint prot;\n};\n\nstruct proto_brk {\n\tvoid *addr;\n};\n\nstruct proto_mmap {\n\tvoid *addr;\n\tsize_t len;\n\tint prot;\n\tint flags;\n\tint fd;\n\toff_t offset;\n};\n\nstruct proto_munmap {\n\tvoid *start;\n\tsize_t len;\n};\n\nstruct proto_open {\n\tint flags;\n\tint mode;\n};\n\nstruct proto_openat {\n\tint flags;\n\tchar mode[4];\n};\n\nstruct proto_read {\n\tsize_t len;\n\toff_t offset;\n};\n\nstruct proto_write {\n\tsize_t len;\n\toff_t offset;\n};\n\nstruct proto_lseek {\n\toff_t off;\n\tint whence;\n};\n\nstruct proto_register_service {\n\tint type;\n\tint flags;\n\tint source_off;\n\tint target_off;\n};\n\nstruct proto_access {\n\tint amode;\n};\n\nstruct execv_extra {\n\tchar path[FILENAME_MAX];\n\tint argv[32];\n\tint argc;\n\tint flags;\n\tchar buf[0];\n};\n\nstruct proto_devinfo {\n\tuint32_t key;\n\tint index;\n};\n\nstruct proto_load_driver {\n\tchar path[FILENAME_MAX];\n};\n\nstruct proto {\n\tlong token;\n\tint proto_id;\n\tint padding;\n\tunion {\n\t\tstruct proto_mmap mmap;\n\t\tstruct proto_mprotect mprotect;\n\t\tstruct proto_munmap munmap;\n\t\tstruct proto_open open;\n\t\tstruct proto_open openat;\n\t\tstruct proto_read read;\n\t\tstruct proto_write write;\n\t\tstruct proto_lseek lseek;\n\t\tstruct proto_elf_info elf_info;\n\t\tstruct proto_brk brk;\n\t\tstruct proto_access access;\n\t\tstruct proto_waitpid waitpid;\n\t\tstruct proto_register_service register_service;\n\t\tstruct proto_devinfo devinfo;\n\t};\n};\n\nstruct service_info {\n\tint right;\n\tint type;\n\tchar name[SERVICENAME_MAX];\n};\n\n#define PROTO_SIZE sizeof(struct proto)\n\nint sys_read_proto_with_string(int handle, struct proto *proto,\n\t\tchar *extra, size_t size, uint32_t timeout);\n\nint sys_read_proto(int handle, struct proto *proto,\n\t\tchar *extra, size_t size, uint32_t timeout);\n\nlong sys_send_proto(int handle, struct proto *proto);\n\nlong sys_send_proto_nonblock(int handle, struct proto *proto);\n\nlong sys_send_proto_timeout(int handle, struct proto *proto, uint32_t to);\n\nlong sys_send_proto_with_data(int handle, struct proto *proto,\n\t\tvoid *data, size_t dsz, uint32_t to);\n\nvoid i_am_ok(void);\n\n#endif\n"
  },
  {
    "path": "user.libc/include/minos/sched.h",
    "content": "#ifndef __LIBC_SCHED_H__\n#define __LIBC_SCHED_H__\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nvoid yield(void);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n\n"
  },
  {
    "path": "user.libc/include/minos/service.h",
    "content": "#ifndef __LIBC_SERVICE_H__\n#define __LIBC_SERVICE_H__\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define SRV_NONE 0\n#define SRV_DIR 1\n#define SRV_PORT 2\n#define SRV_NOTIFY 3\n#define SRV_REMOTE 4\n\nint register_service(const char *src, const char *target, int type, int flags);\n\nint unregister_service(int fd);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/minos/spinlock.h",
    "content": "#ifndef __LIBMINOS_SPINLOCK_H__\n#define __LIBMINOS_SPINLOCK_H__\n\ntypedef struct spinlock {\n\tint value;\n} spinlock_t;\n\nextern void raw_spin_lock(spinlock_t *l);\nextern void raw_spin_unlock(spinlock_t *l);\n\nstatic inline void spinlock_init(spinlock_t *lock)\n{\n\tlock->value = 0;\n}\n\n#define DEFINE_SPINLOCK(name)\t\\\n\tspinlock_t name = {\t\\\n\t\t.lock = 0,\t\\\n\t}\n\n#define spin_lock(l)\t\t\t\\\n\tdo {\t\t\t\t\\\n\t\traw_spin_lock(l);\t\\\n\t} while (0)\n\n#define spin_unlock(l)\t\t\t\\\n\tdo {\t\t\t\t\\\n\t\traw_spin_unlock(l);\t\\\n\t} while (0)\n\n#endif\n"
  },
  {
    "path": "user.libc/include/minos/thread.h",
    "content": "#ifndef __LIBC_THREAD_H__\n#define __LIBC_THREAD_H__\n\n#include <stdlib.h>\n\nint create_thread(int (*fn)(void *), void *stack, int prio, int aff,\n\t\tint flags, void *tls, void *pdata);\n\n#endif\n"
  },
  {
    "path": "user.libc/include/minos/types.h",
    "content": "#ifndef __LIBMINOS_TYPES_H__\n#define __LIBMINOS_TYPES_H__\n\n#include <stdint.h>\n#include <inttypes.h>\n\n#define BIT(n)\t(1UL << (n))\n\n#define offsetof(TYPE, MEMBER)  ((size_t)&((TYPE *)0)->MEMBER)\n\n#define container_of(ptr, name, member) \\\n\t(name *)((unsigned char *)ptr - ((unsigned char *)&(((name *)0)->member)))\n\n#undef PAGE_SIZE\n#define PAGE_SIZE\t(4096)\n\n#undef PAGE_SHIFT\n#define PAGE_SHIFT\t(12)\n\n#undef PAGE_MASK\n#define PAGE_MASK\t(0xfffUL)\n\n#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))\n\n#define BITS_PER_BYTE\t\t(8)\n\n#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))\n\n#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))\n\n#define DECLARE_BITMAP(name, bits) \\\n\tunsigned long name[BITS_TO_LONGS(bits)]\n\n#define BITMAP_SIZE(size)\t(BITS_TO_LONGS((size)) * sizeof(long))\n\n#define BITS_PER_LONG\t\t64\n#define BIT_ULL(nr)\t\t(1ULL << (nr))\n#define BIT_MASK(nr)\t\t(1UL << ((nr) % BITS_PER_LONG))\n#define BIT_WORD(nr)\t\t((nr) / BITS_PER_LONG)\n#define BIT_ULL_MASK(nr)\t(1ULL << ((nr) % BITS_PER_LONG_LONG))\n#define BIT_ULL_WORD(nr)\t((nr) / BITS_PER_LONG_LONG)\n\n#define __round_mask(x, y) \t((__typeof__(x))((y)-1))\n#define round_up(x, y) \t\t((((x)-1) | __round_mask(x, y))+1)\n#define round_down(x, y) \t((x) & ~__round_mask(x, y))\n\n#define IS_ALIGN_PO2(n)\t(((unsigned long)(n) & (unsigned long)(-(n))) == n)\n\n#define ALIGN(x, y)\t((x) & ~__round_mask(x, y))\n#define BALIGN(x, y)\t(((x) + (y) - 1) & ~__round_mask(x, y))\n\n#define PAGE_BALIGN(x)\tBALIGN((unsigned long)(x), PAGE_SIZE)\n#define PAGE_ALIGN(x)\tALIGN((unsigned long)(x), PAGE_SIZE)\n\n#define IS_PAGE_ALIGN(x)\t(!((unsigned long)(x) & (PAGE_SIZE - 1)))\n#define IS_BLOCK_ALIGN(x)\t(!((unsigned long)(x) & (0x1fffff)))\n\n#define PAGE_NR(size)\t(PAGE_BALIGN(size) >> PAGE_SHIFT)\n\n#define u8_to_u16(low, high)\t(((uint16_t)(high) << 8) | (uint16_t)(low))\n#define u8_to_u32(u1, u2, u3, u4)\t\\\n\t(((uint32_t)(u4) << 24) | ((uint32_t)(u3) << 16) | ((uint32_t)(u2) << 8) | (uint32_t)(u1))\n#define u16_to_u32(low, high)\t(((uint32_t)(high) << 16) | (uint32_t)(low))\n\n#endif\n"
  },
  {
    "path": "user.libc/include/mntent.h",
    "content": "#ifndef _MNTENT_H\n#define _MNTENT_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define __NEED_FILE\n#include <bits/alltypes.h>\n\n#define MOUNTED \"/etc/mtab\"\n\n#define MNTTYPE_IGNORE\t\"ignore\"\n#define MNTTYPE_NFS\t\"nfs\"\n#define MNTTYPE_SWAP\t\"swap\"\n#define MNTOPT_DEFAULTS\t\"defaults\"\n#define MNTOPT_RO\t\"ro\"\n#define MNTOPT_RW\t\"rw\"\n#define MNTOPT_SUID\t\"suid\"\n#define MNTOPT_NOSUID\t\"nosuid\"\n#define MNTOPT_NOAUTO\t\"noauto\"\n\nstruct mntent {\n\tchar *mnt_fsname;\n\tchar *mnt_dir;\n\tchar *mnt_type;\n\tchar *mnt_opts;\n\tint mnt_freq;\n\tint mnt_passno;\n};\n\nFILE *setmntent(const char *, const char *);\nint endmntent(FILE *);\nstruct mntent *getmntent(FILE *);\nstruct mntent *getmntent_r(FILE *, struct mntent *, char *, int);\nint addmntent(FILE *, const struct mntent *);\nchar *hasmntopt(const struct mntent *, const char *);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/monetary.h",
    "content": "#ifndef _MONETARY_H\n#define _MONETARY_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_ssize_t\n#define __NEED_size_t\n#define __NEED_locale_t\n\n#include <bits/alltypes.h>\n\nssize_t strfmon(char *__restrict, size_t, const char *__restrict, ...);\nssize_t strfmon_l(char *__restrict, size_t, locale_t, const char *__restrict, ...);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/mqueue.h",
    "content": "#ifndef _MQUEUE_H\n#define _MQUEUE_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_size_t\n#define __NEED_ssize_t\n#define __NEED_pthread_attr_t\n#define __NEED_time_t\n#define __NEED_struct_timespec\n#include <bits/alltypes.h>\n\ntypedef int mqd_t;\nstruct mq_attr {\n\tlong mq_flags, mq_maxmsg, mq_msgsize, mq_curmsgs, __unused[4];\n};\nstruct sigevent;\n\nint mq_close(mqd_t);\nint mq_getattr(mqd_t, struct mq_attr *);\nint mq_notify(mqd_t, const struct sigevent *);\nmqd_t mq_open(const char *, int, ...);\nssize_t mq_receive(mqd_t, char *, size_t, unsigned *);\nint mq_send(mqd_t, const char *, size_t, unsigned);\nint mq_setattr(mqd_t, const struct mq_attr *__restrict, struct mq_attr *__restrict);\nssize_t mq_timedreceive(mqd_t, char *__restrict, size_t, unsigned *__restrict, const struct timespec *__restrict);\nint mq_timedsend(mqd_t, const char *, size_t, unsigned, const struct timespec *);\nint mq_unlink(const char *);\n\n#if _REDIR_TIME64\n__REDIR(mq_timedreceive, __mq_timedreceive_time64);\n__REDIR(mq_timedsend, __mq_timedsend_time64);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/net/ethernet.h",
    "content": "#ifndef _NET_ETHERNET_H\n#define _NET_ETHERNET_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n#include <sys/types.h>\n#include <netinet/if_ether.h>\n\nstruct ether_addr {\n\tuint8_t ether_addr_octet[ETH_ALEN];\n};\n\nstruct ether_header {\n\tuint8_t  ether_dhost[ETH_ALEN];\n\tuint8_t  ether_shost[ETH_ALEN];\n\tuint16_t ether_type;\n};\n\n#define\tETHERTYPE_PUP\t\t0x0200\n#define ETHERTYPE_SPRITE\t0x0500\n#define\tETHERTYPE_IP\t\t0x0800\n#define\tETHERTYPE_ARP\t\t0x0806\n#define\tETHERTYPE_REVARP\t0x8035\n#define ETHERTYPE_AT\t\t0x809B\n#define ETHERTYPE_AARP\t\t0x80F3\n#define\tETHERTYPE_VLAN\t\t0x8100\n#define ETHERTYPE_IPX\t\t0x8137\n#define\tETHERTYPE_IPV6\t\t0x86dd\n#define ETHERTYPE_LOOPBACK\t0x9000\n\n\n#define\tETHER_ADDR_LEN\tETH_ALEN\n#define\tETHER_TYPE_LEN\t2\n#define\tETHER_CRC_LEN\t4\n#define\tETHER_HDR_LEN\tETH_HLEN\n#define\tETHER_MIN_LEN\t(ETH_ZLEN + ETHER_CRC_LEN)\n#define\tETHER_MAX_LEN\t(ETH_FRAME_LEN + ETHER_CRC_LEN)\n\n#define\tETHER_IS_VALID_LEN(foo)\t\\\n\t((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN)\n\n#define\tETHERTYPE_TRAIL\t\t0x1000\n#define\tETHERTYPE_NTRAILER\t16\n\n#define\tETHERMTU\tETH_DATA_LEN\n#define\tETHERMIN\t(ETHER_MIN_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/net/if.h",
    "content": "#ifndef _NET_IF_H\n#define _NET_IF_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define IF_NAMESIZE 16\n\nstruct if_nameindex {\n\tunsigned int if_index;\n\tchar *if_name;\n};\n\nunsigned int if_nametoindex (const char *);\nchar *if_indextoname (unsigned int, char *);\nstruct if_nameindex *if_nameindex (void);\nvoid if_freenameindex (struct if_nameindex *);\n\n\n\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n\n#include <sys/socket.h>\n\n#define IFF_UP\t0x1\n#define IFF_BROADCAST 0x2\n#define IFF_DEBUG 0x4\n#define IFF_LOOPBACK 0x8\n#define IFF_POINTOPOINT 0x10\n#define IFF_NOTRAILERS 0x20\n#define IFF_RUNNING 0x40\n#define IFF_NOARP 0x80\n#define IFF_PROMISC 0x100\n#define IFF_ALLMULTI 0x200\n#define IFF_MASTER 0x400\n#define IFF_SLAVE 0x800\n#define IFF_MULTICAST 0x1000\n#define IFF_PORTSEL 0x2000\n#define IFF_AUTOMEDIA 0x4000\n#define IFF_DYNAMIC 0x8000\n#define IFF_LOWER_UP 0x10000\n#define IFF_DORMANT 0x20000\n#define IFF_ECHO 0x40000\n#define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST| \\\n        IFF_ECHO|IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT)\n\nstruct ifaddr {\n\tstruct sockaddr ifa_addr;\n\tunion {\n\t\tstruct sockaddr\tifu_broadaddr;\n\t\tstruct sockaddr\tifu_dstaddr;\n\t} ifa_ifu;\n\tstruct iface *ifa_ifp;\n\tstruct ifaddr *ifa_next;\n};\n\n#define ifa_broadaddr\tifa_ifu.ifu_broadaddr\n#define ifa_dstaddr\tifa_ifu.ifu_dstaddr\n\nstruct ifmap {\n\tunsigned long int mem_start;\n\tunsigned long int mem_end;\n\tunsigned short int base_addr;\n\tunsigned char irq;\n\tunsigned char dma;\n\tunsigned char port;\n};\n\n#define IFHWADDRLEN\t6\n#define IFNAMSIZ\tIF_NAMESIZE\n\nstruct ifreq {\n\tunion {\n\t\tchar ifrn_name[IFNAMSIZ];\n\t} ifr_ifrn;\n\tunion {\n\t\tstruct sockaddr ifru_addr;\n\t\tstruct sockaddr ifru_dstaddr;\n\t\tstruct sockaddr ifru_broadaddr;\n\t\tstruct sockaddr ifru_netmask;\n\t\tstruct sockaddr ifru_hwaddr;\n\t\tshort int ifru_flags;\n\t\tint ifru_ivalue;\n\t\tint ifru_mtu;\n\t\tstruct ifmap ifru_map;\n\t\tchar ifru_slave[IFNAMSIZ];\n\t\tchar ifru_newname[IFNAMSIZ];\n\t\tchar *ifru_data;\n\t} ifr_ifru;\n};\n\n#define ifr_name\tifr_ifrn.ifrn_name\n#define ifr_hwaddr\tifr_ifru.ifru_hwaddr\n#define ifr_addr\tifr_ifru.ifru_addr\n#define ifr_dstaddr\tifr_ifru.ifru_dstaddr\n#define ifr_broadaddr\tifr_ifru.ifru_broadaddr\n#define ifr_netmask\tifr_ifru.ifru_netmask\n#define ifr_flags\tifr_ifru.ifru_flags\n#define ifr_metric\tifr_ifru.ifru_ivalue\n#define ifr_mtu\t\tifr_ifru.ifru_mtu\n#define ifr_map\t\tifr_ifru.ifru_map\n#define ifr_slave\tifr_ifru.ifru_slave\n#define ifr_data\tifr_ifru.ifru_data\n#define ifr_ifindex\tifr_ifru.ifru_ivalue\n#define ifr_bandwidth\tifr_ifru.ifru_ivalue\n#define ifr_qlen\tifr_ifru.ifru_ivalue\n#define ifr_newname\tifr_ifru.ifru_newname\n#define _IOT_ifreq\t_IOT(_IOTS(char),IFNAMSIZ,_IOTS(char),16,0,0)\n#define _IOT_ifreq_short _IOT(_IOTS(char),IFNAMSIZ,_IOTS(short),1,0,0)\n#define _IOT_ifreq_int\t_IOT(_IOTS(char),IFNAMSIZ,_IOTS(int),1,0,0)\n\nstruct ifconf {\n\tint ifc_len;\t\t\n\tunion {\n\t\tchar *ifcu_buf;\n\t\tstruct ifreq *ifcu_req;\n\t} ifc_ifcu;\n};\n\n#define ifc_buf\t\tifc_ifcu.ifcu_buf\n#define ifc_req\t\tifc_ifcu.ifcu_req\n#define _IOT_ifconf _IOT(_IOTS(struct ifconf),1,0,0,0,0)\n\n#define __UAPI_DEF_IF_IFCONF                                    0\n#define __UAPI_DEF_IF_IFMAP                                     0\n#define __UAPI_DEF_IF_IFNAMSIZ                                  0\n#define __UAPI_DEF_IF_IFREQ                                     0\n#define __UAPI_DEF_IF_NET_DEVICE_FLAGS                          0\n#define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO    0\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/net/if_arp.h",
    "content": "/* Nonstandard header */\n#ifndef _NET_IF_ARP_H\n#define _NET_IF_ARP_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <inttypes.h>\n#include <sys/types.h>\n#include <sys/socket.h>\n\n#define MAX_ADDR_LEN\t7\n\n#define\tARPOP_REQUEST\t1\n#define\tARPOP_REPLY\t2\n#define\tARPOP_RREQUEST\t3\n#define\tARPOP_RREPLY\t4\n#define\tARPOP_InREQUEST\t8\n#define\tARPOP_InREPLY\t9\n#define\tARPOP_NAK\t10\n\nstruct arphdr {\n\tuint16_t ar_hrd;\n\tuint16_t ar_pro;\n\tuint8_t ar_hln;\n\tuint8_t ar_pln;\n\tuint16_t ar_op;\n};\n\n\n#define ARPHRD_NETROM\t0\n#define ARPHRD_ETHER \t1\n#define\tARPHRD_EETHER\t2\n#define\tARPHRD_AX25\t3\n#define\tARPHRD_PRONET\t4\n#define\tARPHRD_CHAOS\t5\n#define\tARPHRD_IEEE802\t6\n#define\tARPHRD_ARCNET\t7\n#define\tARPHRD_APPLETLK\t8\n#define\tARPHRD_DLCI\t15\n#define\tARPHRD_ATM\t19\n#define\tARPHRD_METRICOM\t23\n#define ARPHRD_IEEE1394\t24\n#define ARPHRD_EUI64\t\t27\n#define ARPHRD_INFINIBAND\t32\n#define ARPHRD_SLIP\t256\n#define ARPHRD_CSLIP\t257\n#define ARPHRD_SLIP6\t258\n#define ARPHRD_CSLIP6\t259\n#define ARPHRD_RSRVD\t260\n#define ARPHRD_ADAPT\t264\n#define ARPHRD_ROSE\t270\n#define ARPHRD_X25\t271\n#define ARPHRD_HWX25\t272\n#define ARPHRD_CAN\t280\n#define ARPHRD_PPP\t512\n#define ARPHRD_CISCO\t513\n#define ARPHRD_HDLC\tARPHRD_CISCO\n#define ARPHRD_LAPB\t516\n#define ARPHRD_DDCMP\t517\n#define\tARPHRD_RAWHDLC\t518\n#define ARPHRD_RAWIP\t519\n\n#define ARPHRD_TUNNEL\t768\n#define ARPHRD_TUNNEL6\t769\n#define ARPHRD_FRAD\t770\n#define ARPHRD_SKIP\t771\n#define ARPHRD_LOOPBACK\t772\n#define ARPHRD_LOCALTLK 773\n#define ARPHRD_FDDI\t774\n#define ARPHRD_BIF\t775\n#define ARPHRD_SIT\t776\n#define ARPHRD_IPDDP\t777\n#define ARPHRD_IPGRE\t778\n#define ARPHRD_PIMREG\t779\n#define ARPHRD_HIPPI\t780\n#define ARPHRD_ASH\t781\n#define ARPHRD_ECONET\t782\n#define ARPHRD_IRDA\t783\n#define ARPHRD_FCPP\t784\n#define ARPHRD_FCAL\t785\n#define ARPHRD_FCPL\t786\n#define ARPHRD_FCFABRIC 787\n#define ARPHRD_IEEE802_TR 800\n#define ARPHRD_IEEE80211 801\n#define ARPHRD_IEEE80211_PRISM 802\n#define ARPHRD_IEEE80211_RADIOTAP 803\n#define ARPHRD_IEEE802154 804\n#define ARPHRD_IEEE802154_MONITOR 805\n#define ARPHRD_PHONET 820\n#define ARPHRD_PHONET_PIPE 821\n#define ARPHRD_CAIF 822\n#define ARPHRD_IP6GRE 823\n#define ARPHRD_NETLINK 824\n#define ARPHRD_6LOWPAN 825\n#define ARPHRD_VSOCKMON 826\n\n#define ARPHRD_VOID\t  0xFFFF\n#define ARPHRD_NONE\t  0xFFFE\n\nstruct arpreq {\n\tstruct sockaddr arp_pa;\n\tstruct sockaddr arp_ha;\n\tint arp_flags;\n\tstruct sockaddr arp_netmask;\n\tchar arp_dev[16];\n};\n\nstruct arpreq_old {\n\tstruct sockaddr arp_pa;\n\tstruct sockaddr arp_ha;\n\tint arp_flags;\n\tstruct sockaddr arp_netmask;\n};\n\n#define ATF_COM\t\t0x02\n#define\tATF_PERM\t0x04\n#define\tATF_PUBL\t0x08\n#define\tATF_USETRAILERS\t0x10\n#define ATF_NETMASK     0x20\n#define ATF_DONTPUB\t0x40\n#define ATF_MAGIC\t0x80\n\n#define ARPD_UPDATE\t0x01\n#define ARPD_LOOKUP\t0x02\n#define ARPD_FLUSH\t0x03\n\nstruct arpd_request {\n\tunsigned short req;\n\tuint32_t ip;\n\tunsigned long dev;\n\tunsigned long stamp;\n\tunsigned long updated;\n\tunsigned char ha[MAX_ADDR_LEN];\n};\n\n\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/net/route.h",
    "content": "#ifndef _NET_ROUTE_H\n#define _NET_ROUTE_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n#include <sys/socket.h>\n#include <sys/types.h>\n#include <netinet/in.h>\n\n\nstruct rtentry {\n\tunsigned long int rt_pad1;\n\tstruct sockaddr rt_dst;\n\tstruct sockaddr rt_gateway;\n\tstruct sockaddr rt_genmask;\n\tunsigned short int rt_flags;\n\tshort int rt_pad2;\n\tunsigned long int rt_pad3;\n\tunsigned char rt_tos;\n\tunsigned char rt_class;\n\tshort int rt_pad4[sizeof(long)/2-1];\n\tshort int rt_metric;\n\tchar *rt_dev;\n\tunsigned long int rt_mtu;\n\tunsigned long int rt_window;\n\tunsigned short int rt_irtt;\n};\n\n#define rt_mss\trt_mtu\n\n\nstruct in6_rtmsg {\n\tstruct in6_addr rtmsg_dst;\n\tstruct in6_addr rtmsg_src;\n\tstruct in6_addr rtmsg_gateway;\n\tuint32_t rtmsg_type;\n\tuint16_t rtmsg_dst_len;\n\tuint16_t rtmsg_src_len;\n\tuint32_t rtmsg_metric;\n\tunsigned long int rtmsg_info;\n\tuint32_t rtmsg_flags;\n\tint rtmsg_ifindex;\n};\n\n\n#define\tRTF_UP\t\t0x0001\n#define\tRTF_GATEWAY\t0x0002\n\n#define\tRTF_HOST\t0x0004\n#define RTF_REINSTATE\t0x0008\n#define\tRTF_DYNAMIC\t0x0010\n#define\tRTF_MODIFIED\t0x0020\n#define RTF_MTU\t\t0x0040\n#define RTF_MSS\t\tRTF_MTU\n#define RTF_WINDOW\t0x0080\n#define RTF_IRTT\t0x0100\n#define RTF_REJECT\t0x0200\n#define\tRTF_STATIC\t0x0400\n#define\tRTF_XRESOLVE\t0x0800\n#define RTF_NOFORWARD   0x1000\n#define RTF_THROW\t0x2000\n#define RTF_NOPMTUDISC  0x4000\n\n#define RTF_DEFAULT\t0x00010000\n#define RTF_ALLONLINK\t0x00020000\n#define RTF_ADDRCONF\t0x00040000\n\n#define RTF_LINKRT\t0x00100000\n#define RTF_NONEXTHOP\t0x00200000\n\n#define RTF_CACHE\t0x01000000\n#define RTF_FLOW\t0x02000000\n#define RTF_POLICY\t0x04000000\n\n#define RTCF_VALVE\t0x00200000\n#define RTCF_MASQ\t0x00400000\n#define RTCF_NAT\t0x00800000\n#define RTCF_DOREDIRECT 0x01000000\n#define RTCF_LOG\t0x02000000\n#define RTCF_DIRECTSRC\t0x04000000\n\n#define RTF_LOCAL\t0x80000000\n#define RTF_INTERFACE\t0x40000000\n#define RTF_MULTICAST\t0x20000000\n#define RTF_BROADCAST\t0x10000000\n#define RTF_NAT\t\t0x08000000\n\n#define RTF_ADDRCLASSMASK\t0xF8000000\n#define RT_ADDRCLASS(flags)\t((uint32_t) flags >> 23)\n\n#define RT_TOS(tos)\t\t((tos) & IPTOS_TOS_MASK)\n\n#define RT_LOCALADDR(flags)\t((flags & RTF_ADDRCLASSMASK) \\\n\t\t\t\t == (RTF_LOCAL|RTF_INTERFACE))\n\n#define RT_CLASS_UNSPEC\t\t0\n#define RT_CLASS_DEFAULT\t253\n\n#define RT_CLASS_MAIN\t\t254\n#define RT_CLASS_LOCAL\t\t255\n#define RT_CLASS_MAX\t\t255\n\n\n#define RTMSG_ACK\t\tNLMSG_ACK\n#define RTMSG_OVERRUN\t\tNLMSG_OVERRUN\n\n#define RTMSG_NEWDEVICE\t\t0x11\n#define RTMSG_DELDEVICE\t\t0x12\n#define RTMSG_NEWROUTE\t\t0x21\n#define RTMSG_DELROUTE\t\t0x22\n#define RTMSG_NEWRULE\t\t0x31\n#define RTMSG_DELRULE\t\t0x32\n#define RTMSG_CONTROL\t\t0x40\n\n#define RTMSG_AR_FAILED\t\t0x51\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/netdb.h",
    "content": "#ifndef\t_NETDB_H\n#define\t_NETDB_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n#include <netinet/in.h>\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define __NEED_size_t\n#include <bits/alltypes.h>\n#endif\n\nstruct addrinfo {\n\tint ai_flags;\n\tint ai_family;\n\tint ai_socktype;\n\tint ai_protocol;\n\tsocklen_t ai_addrlen;\n\tstruct sockaddr *ai_addr;\n\tchar *ai_canonname;\n\tstruct addrinfo *ai_next;\n};\n\n#define AI_PASSIVE      0x01\n#define AI_CANONNAME    0x02\n#define AI_NUMERICHOST  0x04\n#define AI_V4MAPPED     0x08\n#define AI_ALL          0x10\n#define AI_ADDRCONFIG   0x20\n#define AI_NUMERICSERV  0x400\n\n\n#define NI_NUMERICHOST  0x01\n#define NI_NUMERICSERV  0x02\n#define NI_NOFQDN       0x04\n#define NI_NAMEREQD     0x08\n#define NI_DGRAM        0x10\n#define NI_NUMERICSCOPE 0x100\n\n#define EAI_BADFLAGS   -1\n#define EAI_NONAME     -2\n#define EAI_AGAIN      -3\n#define EAI_FAIL       -4\n#define EAI_FAMILY     -6\n#define EAI_SOCKTYPE   -7\n#define EAI_SERVICE    -8\n#define EAI_MEMORY     -10\n#define EAI_SYSTEM     -11\n#define EAI_OVERFLOW   -12\n\nint getaddrinfo (const char *__restrict, const char *__restrict, const struct addrinfo *__restrict, struct addrinfo **__restrict);\nvoid freeaddrinfo (struct addrinfo *);\nint getnameinfo (const struct sockaddr *__restrict, socklen_t, char *__restrict, socklen_t, char *__restrict, socklen_t, int);\nconst char *gai_strerror(int);\n\n\n/* Legacy functions follow (marked OBsolete in SUS) */\n\nstruct netent {\n\tchar *n_name;\n\tchar **n_aliases;\n\tint n_addrtype;\n\tuint32_t n_net;\n};\n\nstruct hostent {\n\tchar *h_name;\n\tchar **h_aliases;\n\tint h_addrtype;\n\tint h_length;\n\tchar **h_addr_list;\n};\n#define h_addr h_addr_list[0]\n\nstruct servent {\n\tchar *s_name;\n\tchar **s_aliases;\n\tint s_port;\n\tchar *s_proto;\n};\n\nstruct protoent {\n\tchar *p_name;\n\tchar **p_aliases;\n\tint p_proto;\n};\n\nvoid sethostent (int);\nvoid endhostent (void);\nstruct hostent *gethostent (void);\n\nvoid setnetent (int);\nvoid endnetent (void);\nstruct netent *getnetent (void);\nstruct netent *getnetbyaddr (uint32_t, int);\nstruct netent *getnetbyname (const char *);\n\nvoid setservent (int);\nvoid endservent (void);\nstruct servent *getservent (void);\nstruct servent *getservbyname (const char *, const char *);\nstruct servent *getservbyport (int, const char *);\n\nvoid setprotoent (int);\nvoid endprotoent (void);\nstruct protoent *getprotoent (void);\nstruct protoent *getprotobyname (const char *);\nstruct protoent *getprotobynumber (int);\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_POSIX_SOURCE) \\\n || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE+0 < 200809L) \\\n || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 < 700)\nstruct hostent *gethostbyname (const char *);\nstruct hostent *gethostbyaddr (const void *, socklen_t, int);\n#ifdef __GNUC__\n__attribute__((const))\n#endif\nint *__h_errno_location(void);\n#define h_errno (*__h_errno_location())\n#define HOST_NOT_FOUND 1\n#define TRY_AGAIN      2\n#define NO_RECOVERY    3\n#define NO_DATA        4\n#define NO_ADDRESS     NO_DATA\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\nvoid herror(const char *);\nconst char *hstrerror(int);\nint gethostbyname_r(const char *, struct hostent *, char *, size_t, struct hostent **, int *);\nint gethostbyname2_r(const char *, int, struct hostent *, char *, size_t, struct hostent **, int *);\nstruct hostent *gethostbyname2(const char *, int);\nint gethostbyaddr_r(const void *, socklen_t, int, struct hostent *, char *, size_t, struct hostent **, int *);\nint getservbyport_r(int, const char *, struct servent *, char *, size_t, struct servent **);\nint getservbyname_r(const char *, const char *, struct servent *, char *, size_t, struct servent **);\n#define EAI_NODATA     -5\n#define EAI_ADDRFAMILY -9\n#define EAI_INPROGRESS -100\n#define EAI_CANCELED   -101\n#define EAI_NOTCANCELED -102\n#define EAI_ALLDONE    -103\n#define EAI_INTR       -104\n#define EAI_IDN_ENCODE -105\n#define NI_MAXHOST 255\n#define NI_MAXSERV 32\n#endif\n\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/netinet/ether.h",
    "content": "#ifndef _NETINET_ETHER_H\n#define _NETINET_ETHER_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <netinet/if_ether.h>\n\nchar *ether_ntoa (const struct ether_addr *);\nstruct ether_addr *ether_aton (const char *);\nchar *ether_ntoa_r (const struct ether_addr *, char *);\nstruct ether_addr *ether_aton_r (const char *, struct ether_addr *);\nint ether_line(const char *, struct ether_addr *, char *);\nint ether_ntohost(char *, const struct ether_addr *);\nint ether_hostton(const char *, struct ether_addr *);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/netinet/icmp6.h",
    "content": "#ifndef _NETINET_ICMP6_H\n#define _NETINET_ICMP6_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n#include <string.h>\n#include <sys/types.h>\n#include <netinet/in.h>\n\n#define ICMP6_FILTER 1\n\n#define ICMP6_FILTER_BLOCK\t\t1\n#define ICMP6_FILTER_PASS\t\t2\n#define ICMP6_FILTER_BLOCKOTHERS\t3\n#define ICMP6_FILTER_PASSONLY\t\t4\n\nstruct icmp6_filter {\n\tuint32_t icmp6_filt[8];\n};\n\nstruct icmp6_hdr {\n\tuint8_t     icmp6_type;\n\tuint8_t     icmp6_code;\n\tuint16_t    icmp6_cksum;\n\tunion {\n\t\tuint32_t  icmp6_un_data32[1];\n\t\tuint16_t  icmp6_un_data16[2];\n\t\tuint8_t   icmp6_un_data8[4];\n\t} icmp6_dataun;\n};\n\n#define icmp6_data32    icmp6_dataun.icmp6_un_data32\n#define icmp6_data16    icmp6_dataun.icmp6_un_data16\n#define icmp6_data8     icmp6_dataun.icmp6_un_data8\n#define icmp6_pptr      icmp6_data32[0]\n#define icmp6_mtu       icmp6_data32[0]\n#define icmp6_id        icmp6_data16[0]\n#define icmp6_seq       icmp6_data16[1]\n#define icmp6_maxdelay  icmp6_data16[0]\n\n#define ICMP6_DST_UNREACH             1\n#define ICMP6_PACKET_TOO_BIG          2\n#define ICMP6_TIME_EXCEEDED           3\n#define ICMP6_PARAM_PROB              4\n\n#define ICMP6_INFOMSG_MASK  0x80\n\n#define ICMP6_ECHO_REQUEST          128\n#define ICMP6_ECHO_REPLY            129\n#define MLD_LISTENER_QUERY          130\n#define MLD_LISTENER_REPORT         131\n#define MLD_LISTENER_REDUCTION      132\n\n#define ICMP6_DST_UNREACH_NOROUTE     0\n#define ICMP6_DST_UNREACH_ADMIN       1\n#define ICMP6_DST_UNREACH_BEYONDSCOPE 2\n#define ICMP6_DST_UNREACH_ADDR        3\n#define ICMP6_DST_UNREACH_NOPORT      4\n\n#define ICMP6_TIME_EXCEED_TRANSIT     0\n#define ICMP6_TIME_EXCEED_REASSEMBLY  1\n\n#define ICMP6_PARAMPROB_HEADER        0\n#define ICMP6_PARAMPROB_NEXTHEADER    1\n#define ICMP6_PARAMPROB_OPTION        2\n\n#define ICMP6_FILTER_WILLPASS(type, filterp) \\\n\t((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) == 0)\n\n#define ICMP6_FILTER_WILLBLOCK(type, filterp) \\\n\t((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) != 0)\n\n#define ICMP6_FILTER_SETPASS(type, filterp) \\\n\t((((filterp)->icmp6_filt[(type) >> 5]) &= ~(1 << ((type) & 31))))\n\n#define ICMP6_FILTER_SETBLOCK(type, filterp) \\\n\t((((filterp)->icmp6_filt[(type) >> 5]) |=  (1 << ((type) & 31))))\n\n#define ICMP6_FILTER_SETPASSALL(filterp) \\\n\tmemset (filterp, 0, sizeof (struct icmp6_filter));\n\n#define ICMP6_FILTER_SETBLOCKALL(filterp) \\\n\tmemset (filterp, 0xFF, sizeof (struct icmp6_filter));\n\n#define ND_ROUTER_SOLICIT           133\n#define ND_ROUTER_ADVERT            134\n#define ND_NEIGHBOR_SOLICIT         135\n#define ND_NEIGHBOR_ADVERT          136\n#define ND_REDIRECT                 137\n\nstruct nd_router_solicit {\n\tstruct icmp6_hdr  nd_rs_hdr;\n};\n\n#define nd_rs_type               nd_rs_hdr.icmp6_type\n#define nd_rs_code               nd_rs_hdr.icmp6_code\n#define nd_rs_cksum              nd_rs_hdr.icmp6_cksum\n#define nd_rs_reserved           nd_rs_hdr.icmp6_data32[0]\n\nstruct nd_router_advert {\n\tstruct icmp6_hdr  nd_ra_hdr;\n\tuint32_t   nd_ra_reachable;\n\tuint32_t   nd_ra_retransmit;\n};\n\n#define nd_ra_type               nd_ra_hdr.icmp6_type\n#define nd_ra_code               nd_ra_hdr.icmp6_code\n#define nd_ra_cksum              nd_ra_hdr.icmp6_cksum\n#define nd_ra_curhoplimit        nd_ra_hdr.icmp6_data8[0]\n#define nd_ra_flags_reserved     nd_ra_hdr.icmp6_data8[1]\n#define ND_RA_FLAG_MANAGED       0x80\n#define ND_RA_FLAG_OTHER         0x40\n#define ND_RA_FLAG_HOME_AGENT    0x20\n#define nd_ra_router_lifetime    nd_ra_hdr.icmp6_data16[1]\n\nstruct nd_neighbor_solicit {\n\tstruct icmp6_hdr  nd_ns_hdr;\n\tstruct in6_addr   nd_ns_target;\n};\n\n#define nd_ns_type               nd_ns_hdr.icmp6_type\n#define nd_ns_code               nd_ns_hdr.icmp6_code\n#define nd_ns_cksum              nd_ns_hdr.icmp6_cksum\n#define nd_ns_reserved           nd_ns_hdr.icmp6_data32[0]\n\nstruct nd_neighbor_advert {\n\tstruct icmp6_hdr  nd_na_hdr;\n\tstruct in6_addr   nd_na_target;\n};\n\n#define nd_na_type               nd_na_hdr.icmp6_type\n#define nd_na_code               nd_na_hdr.icmp6_code\n#define nd_na_cksum              nd_na_hdr.icmp6_cksum\n#define nd_na_flags_reserved     nd_na_hdr.icmp6_data32[0]\n#if     __BYTE_ORDER == __BIG_ENDIAN\n#define ND_NA_FLAG_ROUTER        0x80000000\n#define ND_NA_FLAG_SOLICITED     0x40000000\n#define ND_NA_FLAG_OVERRIDE      0x20000000\n#else\n#define ND_NA_FLAG_ROUTER        0x00000080\n#define ND_NA_FLAG_SOLICITED     0x00000040\n#define ND_NA_FLAG_OVERRIDE      0x00000020\n#endif\n\nstruct nd_redirect {\n\tstruct icmp6_hdr  nd_rd_hdr;\n\tstruct in6_addr   nd_rd_target;\n\tstruct in6_addr   nd_rd_dst;\n};\n\n#define nd_rd_type               nd_rd_hdr.icmp6_type\n#define nd_rd_code               nd_rd_hdr.icmp6_code\n#define nd_rd_cksum              nd_rd_hdr.icmp6_cksum\n#define nd_rd_reserved           nd_rd_hdr.icmp6_data32[0]\n\nstruct nd_opt_hdr {\n\tuint8_t  nd_opt_type;\n\tuint8_t  nd_opt_len;\n};\n\n#define ND_OPT_SOURCE_LINKADDR\t\t1\n#define ND_OPT_TARGET_LINKADDR\t\t2\n#define ND_OPT_PREFIX_INFORMATION\t3\n#define ND_OPT_REDIRECTED_HEADER\t4\n#define ND_OPT_MTU\t\t\t5\n#define ND_OPT_RTR_ADV_INTERVAL\t\t7\n#define ND_OPT_HOME_AGENT_INFO\t\t8\n\nstruct nd_opt_prefix_info {\n\tuint8_t   nd_opt_pi_type;\n\tuint8_t   nd_opt_pi_len;\n\tuint8_t   nd_opt_pi_prefix_len;\n\tuint8_t   nd_opt_pi_flags_reserved;\n\tuint32_t  nd_opt_pi_valid_time;\n\tuint32_t  nd_opt_pi_preferred_time;\n\tuint32_t  nd_opt_pi_reserved2;\n\tstruct in6_addr  nd_opt_pi_prefix;\n};\n\n#define ND_OPT_PI_FLAG_ONLINK\t0x80\n#define ND_OPT_PI_FLAG_AUTO\t0x40\n#define ND_OPT_PI_FLAG_RADDR\t0x20\n\nstruct nd_opt_rd_hdr {\n\tuint8_t   nd_opt_rh_type;\n\tuint8_t   nd_opt_rh_len;\n\tuint16_t  nd_opt_rh_reserved1;\n\tuint32_t  nd_opt_rh_reserved2;\n};\n\nstruct nd_opt_mtu {\n\tuint8_t   nd_opt_mtu_type;\n\tuint8_t   nd_opt_mtu_len;\n\tuint16_t  nd_opt_mtu_reserved;\n\tuint32_t  nd_opt_mtu_mtu;\n};\n\nstruct mld_hdr {\n\tstruct icmp6_hdr    mld_icmp6_hdr;\n\tstruct in6_addr     mld_addr;\n};\n\n#define mld_type        mld_icmp6_hdr.icmp6_type\n#define mld_code        mld_icmp6_hdr.icmp6_code\n#define mld_cksum       mld_icmp6_hdr.icmp6_cksum\n#define mld_maxdelay    mld_icmp6_hdr.icmp6_data16[0]\n#define mld_reserved    mld_icmp6_hdr.icmp6_data16[1]\n\n#define ICMP6_ROUTER_RENUMBERING    138\n\nstruct icmp6_router_renum {\n\tstruct icmp6_hdr    rr_hdr;\n\tuint8_t             rr_segnum;\n\tuint8_t             rr_flags;\n\tuint16_t            rr_maxdelay;\n\tuint32_t            rr_reserved;\n};\n\n#define rr_type\t\trr_hdr.icmp6_type\n#define rr_code         rr_hdr.icmp6_code\n#define rr_cksum        rr_hdr.icmp6_cksum\n#define rr_seqnum       rr_hdr.icmp6_data32[0]\n\n#define ICMP6_RR_FLAGS_TEST             0x80\n#define ICMP6_RR_FLAGS_REQRESULT        0x40\n#define ICMP6_RR_FLAGS_FORCEAPPLY       0x20\n#define ICMP6_RR_FLAGS_SPECSITE         0x10\n#define ICMP6_RR_FLAGS_PREVDONE         0x08\n\nstruct rr_pco_match {\n\tuint8_t             rpm_code;\n\tuint8_t             rpm_len;\n\tuint8_t             rpm_ordinal;\n\tuint8_t             rpm_matchlen;\n\tuint8_t             rpm_minlen;\n\tuint8_t             rpm_maxlen;\n\tuint16_t            rpm_reserved;\n\tstruct in6_addr     rpm_prefix;\n};\n\n#define RPM_PCO_ADD             1\n#define RPM_PCO_CHANGE          2\n#define RPM_PCO_SETGLOBAL       3\n\nstruct rr_pco_use {\n\tuint8_t             rpu_uselen;\n\tuint8_t             rpu_keeplen;\n\tuint8_t             rpu_ramask;\n\tuint8_t             rpu_raflags;\n\tuint32_t            rpu_vltime;\n\tuint32_t            rpu_pltime;\n\tuint32_t            rpu_flags;\n\tstruct in6_addr     rpu_prefix;\n};\n\n#define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK  0x20\n#define ICMP6_RR_PCOUSE_RAFLAGS_AUTO    0x10\n\n#if __BYTE_ORDER == __BIG_ENDIAN\n#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80000000\n#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40000000\n#else\n#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80\n#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40\n#endif\n\nstruct rr_result {\n\tuint16_t            rrr_flags;\n\tuint8_t             rrr_ordinal;\n\tuint8_t             rrr_matchedlen;\n\tuint32_t            rrr_ifid;\n\tstruct in6_addr     rrr_prefix;\n};\n\n#if __BYTE_ORDER == __BIG_ENDIAN\n#define ICMP6_RR_RESULT_FLAGS_OOB       0x0002\n#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0001\n#else\n#define ICMP6_RR_RESULT_FLAGS_OOB       0x0200\n#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0100\n#endif\n\nstruct nd_opt_adv_interval {\n\tuint8_t   nd_opt_adv_interval_type;\n\tuint8_t   nd_opt_adv_interval_len;\n\tuint16_t  nd_opt_adv_interval_reserved;\n\tuint32_t  nd_opt_adv_interval_ival;\n};\n\nstruct nd_opt_home_agent_info {\n\tuint8_t   nd_opt_home_agent_info_type;\n\tuint8_t   nd_opt_home_agent_info_len;\n\tuint16_t  nd_opt_home_agent_info_reserved;\n\tuint16_t  nd_opt_home_agent_info_preference;\n\tuint16_t  nd_opt_home_agent_info_lifetime;\n};\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/netinet/if_ether.h",
    "content": "#ifndef _NETINET_IF_ETHER_H\n#define _NETINET_IF_ETHER_H\n\n#include <stdint.h>\n#include <sys/types.h>\n\n#define ETH_ALEN\t6\n#define ETH_TLEN\t2\n#define ETH_HLEN\t14\n#define ETH_ZLEN\t60\n#define ETH_DATA_LEN\t1500\n#define ETH_FRAME_LEN\t1514\n#define ETH_FCS_LEN\t4\n#define ETH_MIN_MTU\t68\n#define ETH_MAX_MTU\t0xFFFFU\n\n#define ETH_P_LOOP\t0x0060\n#define ETH_P_PUP\t0x0200\n#define ETH_P_PUPAT\t0x0201\n#define ETH_P_TSN\t0x22F0\n#define ETH_P_ERSPAN2\t0x22EB\n#define ETH_P_IP\t0x0800\n#define ETH_P_X25\t0x0805\n#define ETH_P_ARP\t0x0806\n#define\tETH_P_BPQ\t0x08FF\n#define ETH_P_IEEEPUP\t0x0a00\n#define ETH_P_IEEEPUPAT\t0x0a01\n#define ETH_P_BATMAN\t0x4305\n#define ETH_P_DEC       0x6000\n#define ETH_P_DNA_DL    0x6001\n#define ETH_P_DNA_RC    0x6002\n#define ETH_P_DNA_RT    0x6003\n#define ETH_P_LAT       0x6004\n#define ETH_P_DIAG      0x6005\n#define ETH_P_CUST      0x6006\n#define ETH_P_SCA       0x6007\n#define ETH_P_TEB\t0x6558\n#define ETH_P_RARP      0x8035\n#define ETH_P_ATALK\t0x809B\n#define ETH_P_AARP\t0x80F3\n#define ETH_P_8021Q\t0x8100\n#define ETH_P_IPX\t0x8137\n#define ETH_P_IPV6\t0x86DD\n#define ETH_P_PAUSE\t0x8808\n#define ETH_P_SLOW\t0x8809\n#define ETH_P_WCCP\t0x883E\n#define ETH_P_MPLS_UC\t0x8847\n#define ETH_P_MPLS_MC\t0x8848\n#define ETH_P_ATMMPOA\t0x884c\n#define ETH_P_PPP_DISC\t0x8863\n#define ETH_P_PPP_SES\t0x8864\n#define ETH_P_LINK_CTL\t0x886c\n#define ETH_P_ATMFATE\t0x8884\n#define ETH_P_PAE\t0x888E\n#define ETH_P_AOE\t0x88A2\n#define ETH_P_8021AD\t0x88A8\n#define ETH_P_802_EX1\t0x88B5\n#define ETH_P_ERSPAN\t0x88BE\n#define ETH_P_PREAUTH\t0x88C7\n#define ETH_P_TIPC\t0x88CA\n#define ETH_P_LLDP\t0x88CC\n#define ETH_P_MRP\t0x88E3\n#define ETH_P_MACSEC\t0x88E5\n#define ETH_P_8021AH\t0x88E7\n#define ETH_P_MVRP\t0x88F5\n#define ETH_P_1588\t0x88F7\n#define ETH_P_NCSI\t0x88F8\n#define ETH_P_PRP\t0x88FB\n#define ETH_P_FCOE\t0x8906\n#define ETH_P_TDLS\t0x890D\n#define ETH_P_FIP\t0x8914\n#define ETH_P_IBOE\t0x8915\n#define ETH_P_80221\t0x8917\n#define ETH_P_HSR\t0x892F\n#define ETH_P_NSH\t0x894F\n#define ETH_P_LOOPBACK\t0x9000\n#define ETH_P_QINQ1\t0x9100\n#define ETH_P_QINQ2\t0x9200\n#define ETH_P_QINQ3\t0x9300\n#define ETH_P_EDSA\t0xDADA\n#define ETH_P_DSA_8021Q\t0xDADB\n#define ETH_P_IFE\t0xED3E\n#define ETH_P_AF_IUCV\t0xFBFB\n\n#define ETH_P_802_3_MIN\t0x0600\n\n#define ETH_P_802_3\t0x0001\n#define ETH_P_AX25\t0x0002\n#define ETH_P_ALL\t0x0003\n#define ETH_P_802_2\t0x0004\n#define ETH_P_SNAP\t0x0005\n#define ETH_P_DDCMP     0x0006\n#define ETH_P_WAN_PPP   0x0007\n#define ETH_P_PPP_MP    0x0008\n#define ETH_P_LOCALTALK 0x0009\n#define ETH_P_CAN\t0x000C\n#define ETH_P_CANFD\t0x000D\n#define ETH_P_PPPTALK\t0x0010\n#define ETH_P_TR_802_2\t0x0011\n#define ETH_P_MOBITEX\t0x0015\n#define ETH_P_CONTROL\t0x0016\n#define ETH_P_IRDA\t0x0017\n#define ETH_P_ECONET\t0x0018\n#define ETH_P_HDLC\t0x0019\n#define ETH_P_ARCNET\t0x001A\n#define ETH_P_DSA\t0x001B\n#define ETH_P_TRAILER\t0x001C\n#define ETH_P_PHONET\t0x00F5\n#define ETH_P_IEEE802154 0x00F6\n#define ETH_P_CAIF\t0x00F7\n#define ETH_P_XDSA\t0x00F8\n#define ETH_P_MAP\t0x00F9\n\nstruct ethhdr {\n\tuint8_t h_dest[ETH_ALEN];\n\tuint8_t h_source[ETH_ALEN];\n\tuint16_t h_proto;\n};\n\n#include <net/ethernet.h>\n#include <net/if_arp.h>\n\nstruct\tether_arp {\n\tstruct\tarphdr ea_hdr;\n\tuint8_t arp_sha[ETH_ALEN];\n\tuint8_t arp_spa[4];\n\tuint8_t arp_tha[ETH_ALEN];\n\tuint8_t arp_tpa[4];\n};\n#define\tarp_hrd\tea_hdr.ar_hrd\n#define\tarp_pro\tea_hdr.ar_pro\n#define\tarp_hln\tea_hdr.ar_hln\n#define\tarp_pln\tea_hdr.ar_pln\n#define\tarp_op\tea_hdr.ar_op\n\n#define ETHER_MAP_IP_MULTICAST(ipaddr, enaddr) \\\ndo { \\\n\t(enaddr)[0] = 0x01; \\\n\t(enaddr)[1] = 0x00; \\\n\t(enaddr)[2] = 0x5e; \\\n\t(enaddr)[3] = ((uint8_t *)ipaddr)[1] & 0x7f; \\\n\t(enaddr)[4] = ((uint8_t *)ipaddr)[2]; \\\n\t(enaddr)[5] = ((uint8_t *)ipaddr)[3]; \\\n} while(0)\n\n#define __UAPI_DEF_ETHHDR       0\n\n#endif\n"
  },
  {
    "path": "user.libc/include/netinet/igmp.h",
    "content": "#ifndef _NETINET_IGMP_H\n#define _NETINET_IGMP_H\n\n#include <stdint.h>\n#include <netinet/in.h>\n\nstruct igmp {\n\tuint8_t igmp_type;\n\tuint8_t igmp_code;\n\tuint16_t igmp_cksum;\n\tstruct in_addr igmp_group;\n};\n\n#define IGMP_MINLEN\t\t\t8\n\n#define IGMP_MEMBERSHIP_QUERY   \t0x11\n#define IGMP_V1_MEMBERSHIP_REPORT\t0x12\n#define IGMP_V2_MEMBERSHIP_REPORT\t0x16\n#define IGMP_V2_LEAVE_GROUP\t\t0x17\n\n#define IGMP_DVMRP\t\t\t0x13\n#define IGMP_PIM\t\t\t0x14\n#define IGMP_TRACE\t\t\t0x15\n\n#define IGMP_MTRACE_RESP\t\t0x1e\n#define IGMP_MTRACE\t\t\t0x1f\n\n#define IGMP_MAX_HOST_REPORT_DELAY\t10\n#define IGMP_TIMER_SCALE\t\t10\n\n#define IGMP_DELAYING_MEMBER\t1\n#define IGMP_IDLE_MEMBER\t2\n#define IGMP_LAZY_MEMBER\t3\n#define IGMP_SLEEPING_MEMBER\t4\n#define IGMP_AWAKENING_MEMBER\t5\n\n#define IGMP_v1_ROUTER\t\t1\n#define IGMP_v2_ROUTER\t\t2\n\n#define IGMP_HOST_MEMBERSHIP_QUERY\tIGMP_MEMBERSHIP_QUERY\n#define IGMP_HOST_MEMBERSHIP_REPORT\tIGMP_V1_MEMBERSHIP_REPORT\n#define IGMP_HOST_NEW_MEMBERSHIP_REPORT\tIGMP_V2_MEMBERSHIP_REPORT\n#define IGMP_HOST_LEAVE_MESSAGE\t\tIGMP_V2_LEAVE_GROUP\n\n#endif\n"
  },
  {
    "path": "user.libc/include/netinet/in.h",
    "content": "#ifndef\t_NETINET_IN_H\n#define\t_NETINET_IN_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n#include <inttypes.h>\n#include <sys/socket.h>\n\ntypedef uint16_t in_port_t;\ntypedef uint32_t in_addr_t;\nstruct in_addr { in_addr_t s_addr; };\n\nstruct sockaddr_in {\n\tsa_family_t sin_family;\n\tin_port_t sin_port;\n\tstruct in_addr sin_addr;\n\tuint8_t sin_zero[8];\n};\n\nstruct in6_addr {\n\tunion {\n\t\tuint8_t __s6_addr[16];\n\t\tuint16_t __s6_addr16[8];\n\t\tuint32_t __s6_addr32[4];\n\t} __in6_union;\n};\n#define s6_addr __in6_union.__s6_addr\n#define s6_addr16 __in6_union.__s6_addr16\n#define s6_addr32 __in6_union.__s6_addr32\n\nstruct sockaddr_in6 {\n\tsa_family_t     sin6_family;\n\tin_port_t       sin6_port;\n\tuint32_t        sin6_flowinfo;\n\tstruct in6_addr sin6_addr;\n\tuint32_t        sin6_scope_id;\n};\n\nstruct ipv6_mreq {\n\tstruct in6_addr ipv6mr_multiaddr;\n\tunsigned        ipv6mr_interface;\n};\n\n#define INADDR_ANY        ((in_addr_t) 0x00000000)\n#define INADDR_BROADCAST  ((in_addr_t) 0xffffffff)\n#define INADDR_NONE       ((in_addr_t) 0xffffffff)\n#define INADDR_LOOPBACK   ((in_addr_t) 0x7f000001)\n\n#define INADDR_UNSPEC_GROUP     ((in_addr_t) 0xe0000000)\n#define INADDR_ALLHOSTS_GROUP   ((in_addr_t) 0xe0000001)\n#define INADDR_ALLRTRS_GROUP    ((in_addr_t) 0xe0000002)\n#define INADDR_ALLSNOOPERS_GROUP ((in_addr_t) 0xe000006a)\n#define INADDR_MAX_LOCAL_GROUP  ((in_addr_t) 0xe00000ff)\n\n#define IN6ADDR_ANY_INIT      { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }\n#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }\n\nextern const struct in6_addr in6addr_any, in6addr_loopback;\n\n#define INET_ADDRSTRLEN  16\n#define INET6_ADDRSTRLEN 46\n\nuint32_t htonl(uint32_t);\nuint16_t htons(uint16_t);\nuint32_t ntohl(uint32_t);\nuint16_t ntohs(uint16_t);\n\n#define IPPORT_RESERVED 1024\n\n#define IPPROTO_IP       0\n#define IPPROTO_HOPOPTS  0\n#define IPPROTO_ICMP     1\n#define IPPROTO_IGMP     2\n#define IPPROTO_IPIP     4\n#define IPPROTO_TCP      6\n#define IPPROTO_EGP      8\n#define IPPROTO_PUP      12\n#define IPPROTO_UDP      17\n#define IPPROTO_IDP      22\n#define IPPROTO_TP       29\n#define IPPROTO_DCCP     33\n#define IPPROTO_IPV6     41\n#define IPPROTO_ROUTING  43\n#define IPPROTO_FRAGMENT 44\n#define IPPROTO_RSVP     46\n#define IPPROTO_GRE      47\n#define IPPROTO_ESP      50\n#define IPPROTO_AH       51\n#define IPPROTO_ICMPV6   58\n#define IPPROTO_NONE     59\n#define IPPROTO_DSTOPTS  60\n#define IPPROTO_MTP      92\n#define IPPROTO_BEETPH   94\n#define IPPROTO_ENCAP    98\n#define IPPROTO_PIM      103\n#define IPPROTO_COMP     108\n#define IPPROTO_SCTP     132\n#define IPPROTO_MH       135\n#define IPPROTO_UDPLITE  136\n#define IPPROTO_MPLS     137\n#define IPPROTO_ETHERNET 143\n#define IPPROTO_RAW      255\n#define IPPROTO_MPTCP    262\n#define IPPROTO_MAX      263\n\n#define IN6_IS_ADDR_UNSPECIFIED(a) \\\n        (((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \\\n         ((uint32_t *) (a))[2] == 0 && ((uint32_t *) (a))[3] == 0)\n\n#define IN6_IS_ADDR_LOOPBACK(a) \\\n        (((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \\\n         ((uint32_t *) (a))[2] == 0 && \\\n         ((uint8_t *) (a))[12] == 0 && ((uint8_t *) (a))[13] == 0 && \\\n         ((uint8_t *) (a))[14] == 0 && ((uint8_t *) (a))[15] == 1 )\n\n#define IN6_IS_ADDR_MULTICAST(a) (((uint8_t *) (a))[0] == 0xff)\n\n#define IN6_IS_ADDR_LINKLOCAL(a) \\\n        ((((uint8_t *) (a))[0]) == 0xfe && (((uint8_t *) (a))[1] & 0xc0) == 0x80)\n\n#define IN6_IS_ADDR_SITELOCAL(a) \\\n        ((((uint8_t *) (a))[0]) == 0xfe && (((uint8_t *) (a))[1] & 0xc0) == 0xc0)\n\n#define IN6_IS_ADDR_V4MAPPED(a) \\\n        (((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \\\n         ((uint8_t *) (a))[8] == 0 && ((uint8_t *) (a))[9] == 0 && \\\n         ((uint8_t *) (a))[10] == 0xff && ((uint8_t *) (a))[11] == 0xff)\n\n#define IN6_IS_ADDR_V4COMPAT(a) \\\n        (((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \\\n         ((uint32_t *) (a))[2] == 0 && ((uint8_t *) (a))[15] > 1)\n\n#define IN6_IS_ADDR_MC_NODELOCAL(a) \\\n        (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0x1))\n\n#define IN6_IS_ADDR_MC_LINKLOCAL(a) \\\n        (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0x2))\n\n#define IN6_IS_ADDR_MC_SITELOCAL(a) \\\n        (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0x5))\n\n#define IN6_IS_ADDR_MC_ORGLOCAL(a) \\\n        (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0x8))\n\n#define IN6_IS_ADDR_MC_GLOBAL(a) \\\n        (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0xe))\n\n#define __ARE_4_EQUAL(a,b) \\\n\t(!( (0[a]-0[b]) | (1[a]-1[b]) | (2[a]-2[b]) | (3[a]-3[b]) ))\n#define IN6_ARE_ADDR_EQUAL(a,b) \\\n\t__ARE_4_EQUAL((const uint32_t *)(a), (const uint32_t *)(b))\n\n#define\tIN_CLASSA(a)\t\t((((in_addr_t)(a)) & 0x80000000) == 0)\n#define\tIN_CLASSA_NET\t\t0xff000000\n#define\tIN_CLASSA_NSHIFT\t24\n#define\tIN_CLASSA_HOST\t\t(0xffffffff & ~IN_CLASSA_NET)\n#define\tIN_CLASSA_MAX\t\t128\n#define\tIN_CLASSB(a)\t\t((((in_addr_t)(a)) & 0xc0000000) == 0x80000000)\n#define\tIN_CLASSB_NET\t\t0xffff0000\n#define\tIN_CLASSB_NSHIFT\t16\n#define\tIN_CLASSB_HOST\t\t(0xffffffff & ~IN_CLASSB_NET)\n#define\tIN_CLASSB_MAX\t\t65536\n#define\tIN_CLASSC(a)\t\t((((in_addr_t)(a)) & 0xe0000000) == 0xc0000000)\n#define\tIN_CLASSC_NET\t\t0xffffff00\n#define\tIN_CLASSC_NSHIFT\t8\n#define\tIN_CLASSC_HOST\t\t(0xffffffff & ~IN_CLASSC_NET)\n#define\tIN_CLASSD(a)\t\t((((in_addr_t)(a)) & 0xf0000000) == 0xe0000000)\n#define\tIN_MULTICAST(a)\t\tIN_CLASSD(a)\n#define\tIN_EXPERIMENTAL(a)\t((((in_addr_t)(a)) & 0xe0000000) == 0xe0000000)\n#define\tIN_BADCLASS(a)\t\t((((in_addr_t)(a)) & 0xf0000000) == 0xf0000000)\n\n#define IN_LOOPBACKNET 127\n\n\n#define IP_TOS             1\n#define IP_TTL             2\n#define IP_HDRINCL         3\n#define IP_OPTIONS         4\n#define IP_ROUTER_ALERT    5\n#define IP_RECVOPTS        6\n#define IP_RETOPTS         7\n#define IP_PKTINFO         8\n#define IP_PKTOPTIONS      9\n#define IP_PMTUDISC        10\n#define IP_MTU_DISCOVER    10\n#define IP_RECVERR         11\n#define IP_RECVTTL         12\n#define IP_RECVTOS         13\n#define IP_MTU             14\n#define IP_FREEBIND        15\n#define IP_IPSEC_POLICY    16\n#define IP_XFRM_POLICY     17\n#define IP_PASSSEC         18\n#define IP_TRANSPARENT     19\n#define IP_ORIGDSTADDR     20\n#define IP_RECVORIGDSTADDR IP_ORIGDSTADDR\n#define IP_MINTTL          21\n#define IP_NODEFRAG        22\n#define IP_CHECKSUM        23\n#define IP_BIND_ADDRESS_NO_PORT 24\n#define IP_RECVFRAGSIZE    25\n#define IP_RECVERR_RFC4884 26\n#define IP_MULTICAST_IF    32\n#define IP_MULTICAST_TTL   33\n#define IP_MULTICAST_LOOP  34\n#define IP_ADD_MEMBERSHIP  35\n#define IP_DROP_MEMBERSHIP 36\n#define IP_UNBLOCK_SOURCE  37\n#define IP_BLOCK_SOURCE    38\n#define IP_ADD_SOURCE_MEMBERSHIP  39\n#define IP_DROP_SOURCE_MEMBERSHIP 40\n#define IP_MSFILTER        41\n#define IP_MULTICAST_ALL   49\n#define IP_UNICAST_IF      50\n\n#define IP_RECVRETOPTS IP_RETOPTS\n\n#define IP_PMTUDISC_DONT   0\n#define IP_PMTUDISC_WANT   1\n#define IP_PMTUDISC_DO     2\n#define IP_PMTUDISC_PROBE  3\n#define IP_PMTUDISC_INTERFACE 4\n#define IP_PMTUDISC_OMIT   5\n\n#define IP_DEFAULT_MULTICAST_TTL        1\n#define IP_DEFAULT_MULTICAST_LOOP       1\n#define IP_MAX_MEMBERSHIPS              20\n\nstruct ip_opts {\n\tstruct in_addr ip_dst;\n\tchar ip_opts[40];\n};\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n\n#define MCAST_JOIN_GROUP   42\n#define MCAST_BLOCK_SOURCE 43\n#define MCAST_UNBLOCK_SOURCE      44\n#define MCAST_LEAVE_GROUP  45\n#define MCAST_JOIN_SOURCE_GROUP   46\n#define MCAST_LEAVE_SOURCE_GROUP  47\n#define MCAST_MSFILTER     48\n\n#define MCAST_EXCLUDE 0\n#define MCAST_INCLUDE 1\n\nstruct ip_mreq {\n\tstruct in_addr imr_multiaddr;\n\tstruct in_addr imr_interface;\n};\n\nstruct ip_mreqn {\n\tstruct in_addr imr_multiaddr;\n\tstruct in_addr imr_address;\n\tint imr_ifindex;\n};\n\nstruct ip_mreq_source {\n\tstruct in_addr imr_multiaddr;\n\tstruct in_addr imr_interface;\n\tstruct in_addr imr_sourceaddr;\n};\n\nstruct ip_msfilter {\n\tstruct in_addr imsf_multiaddr;\n\tstruct in_addr imsf_interface;\n\tuint32_t imsf_fmode;\n\tuint32_t imsf_numsrc;\n\tstruct in_addr imsf_slist[1];\n};\n#define IP_MSFILTER_SIZE(numsrc) \\\n\t(sizeof(struct ip_msfilter) - sizeof(struct in_addr) \\\n\t+ (numsrc) * sizeof(struct in_addr))\n\nstruct group_req {\n\tuint32_t gr_interface;\n\tstruct sockaddr_storage gr_group;\n};\n\nstruct group_source_req {\n\tuint32_t gsr_interface;\n\tstruct sockaddr_storage gsr_group;\n\tstruct sockaddr_storage gsr_source;\n};\n\nstruct group_filter {\n\tuint32_t gf_interface;\n\tstruct sockaddr_storage gf_group;\n\tuint32_t gf_fmode;\n\tuint32_t gf_numsrc;\n\tstruct sockaddr_storage gf_slist[1];\n};\n#define GROUP_FILTER_SIZE(numsrc) \\\n\t(sizeof(struct group_filter) - sizeof(struct sockaddr_storage) \\\n\t+ (numsrc) * sizeof(struct sockaddr_storage))\n\nstruct in_pktinfo {\n\tint ipi_ifindex;\n\tstruct in_addr ipi_spec_dst;\n\tstruct in_addr ipi_addr;\n};\n\nstruct in6_pktinfo {\n\tstruct in6_addr ipi6_addr;\n\tunsigned ipi6_ifindex;\n};\n\nstruct ip6_mtuinfo {\n\tstruct sockaddr_in6 ip6m_addr;\n\tuint32_t ip6m_mtu;\n};\n#endif\n\n#define IPV6_ADDRFORM           1\n#define IPV6_2292PKTINFO        2\n#define IPV6_2292HOPOPTS        3\n#define IPV6_2292DSTOPTS        4\n#define IPV6_2292RTHDR          5\n#define IPV6_2292PKTOPTIONS     6\n#define IPV6_CHECKSUM           7\n#define IPV6_2292HOPLIMIT       8\n#define IPV6_NEXTHOP            9\n#define IPV6_AUTHHDR            10\n#define IPV6_UNICAST_HOPS       16\n#define IPV6_MULTICAST_IF       17\n#define IPV6_MULTICAST_HOPS     18\n#define IPV6_MULTICAST_LOOP     19\n#define IPV6_JOIN_GROUP         20\n#define IPV6_LEAVE_GROUP        21\n#define IPV6_ROUTER_ALERT       22\n#define IPV6_MTU_DISCOVER       23\n#define IPV6_MTU                24\n#define IPV6_RECVERR            25\n#define IPV6_V6ONLY             26\n#define IPV6_JOIN_ANYCAST       27\n#define IPV6_LEAVE_ANYCAST      28\n#define IPV6_MULTICAST_ALL      29\n#define IPV6_ROUTER_ALERT_ISOLATE 30\n#define IPV6_IPSEC_POLICY       34\n#define IPV6_XFRM_POLICY        35\n#define IPV6_HDRINCL            36\n\n#define IPV6_RECVPKTINFO        49\n#define IPV6_PKTINFO            50\n#define IPV6_RECVHOPLIMIT       51\n#define IPV6_HOPLIMIT           52\n#define IPV6_RECVHOPOPTS        53\n#define IPV6_HOPOPTS            54\n#define IPV6_RTHDRDSTOPTS       55\n#define IPV6_RECVRTHDR          56\n#define IPV6_RTHDR              57\n#define IPV6_RECVDSTOPTS        58\n#define IPV6_DSTOPTS            59\n#define IPV6_RECVPATHMTU        60\n#define IPV6_PATHMTU            61\n#define IPV6_DONTFRAG           62\n#define IPV6_RECVTCLASS         66\n#define IPV6_TCLASS             67\n#define IPV6_AUTOFLOWLABEL      70\n#define IPV6_ADDR_PREFERENCES   72\n#define IPV6_MINHOPCOUNT        73\n#define IPV6_ORIGDSTADDR        74\n#define IPV6_RECVORIGDSTADDR    IPV6_ORIGDSTADDR\n#define IPV6_TRANSPARENT        75\n#define IPV6_UNICAST_IF         76\n#define IPV6_RECVFRAGSIZE       77\n#define IPV6_FREEBIND           78\n\n#define IPV6_ADD_MEMBERSHIP     IPV6_JOIN_GROUP\n#define IPV6_DROP_MEMBERSHIP    IPV6_LEAVE_GROUP\n#define IPV6_RXHOPOPTS          IPV6_HOPOPTS\n#define IPV6_RXDSTOPTS          IPV6_DSTOPTS\n\n#define IPV6_PMTUDISC_DONT      0\n#define IPV6_PMTUDISC_WANT      1\n#define IPV6_PMTUDISC_DO        2\n#define IPV6_PMTUDISC_PROBE     3\n#define IPV6_PMTUDISC_INTERFACE 4\n#define IPV6_PMTUDISC_OMIT      5\n\n#define IPV6_PREFER_SRC_TMP            0x0001\n#define IPV6_PREFER_SRC_PUBLIC         0x0002\n#define IPV6_PREFER_SRC_PUBTMP_DEFAULT 0x0100\n#define IPV6_PREFER_SRC_COA            0x0004\n#define IPV6_PREFER_SRC_HOME           0x0400\n#define IPV6_PREFER_SRC_CGA            0x0008\n#define IPV6_PREFER_SRC_NONCGA         0x0800\n\n#define IPV6_RTHDR_LOOSE        0\n#define IPV6_RTHDR_STRICT       1\n\n#define IPV6_RTHDR_TYPE_0       0\n\n#define __UAPI_DEF_IN_ADDR      0\n#define __UAPI_DEF_IN_IPPROTO   0\n#define __UAPI_DEF_IN_PKTINFO   0\n#define __UAPI_DEF_IP_MREQ      0\n#define __UAPI_DEF_SOCKADDR_IN  0\n#define __UAPI_DEF_IN_CLASS     0\n#define __UAPI_DEF_IN6_ADDR     0\n#define __UAPI_DEF_IN6_ADDR_ALT 0\n#define __UAPI_DEF_SOCKADDR_IN6 0\n#define __UAPI_DEF_IPV6_MREQ    0\n#define __UAPI_DEF_IPPROTO_V6   0\n#define __UAPI_DEF_IPV6_OPTIONS 0\n#define __UAPI_DEF_IN6_PKTINFO  0\n#define __UAPI_DEF_IP6_MTUINFO  0\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/netinet/in_systm.h",
    "content": "#ifndef _NETINET_IN_SYSTM_H\n#define _NETINET_IN_SYSTM_H\n\n#include <stdint.h>\n\ntypedef uint16_t n_short;\ntypedef uint32_t n_long, n_time;\n\n#endif\n"
  },
  {
    "path": "user.libc/include/netinet/ip.h",
    "content": "#ifndef _NETINET_IP_H\n#define _NETINET_IP_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n#include <netinet/in.h>\n\nstruct timestamp {\n\tuint8_t len;\n\tuint8_t ptr;\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n\tunsigned int flags:4;\n\tunsigned int overflow:4;\n#else\n\tunsigned int overflow:4;\n\tunsigned int flags:4;\n#endif\n\tuint32_t data[9];\n  };\n\nstruct iphdr {\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n\tunsigned int ihl:4;\n\tunsigned int version:4;\n#else\n\tunsigned int version:4;\n\tunsigned int ihl:4;\n#endif\n\tuint8_t tos;\n\tuint16_t tot_len;\n\tuint16_t id;\n\tuint16_t frag_off;\n\tuint8_t ttl;\n\tuint8_t protocol;\n\tuint16_t check;\n\tuint32_t saddr;\n\tuint32_t daddr;\n};\n\nstruct ip {\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n\tunsigned int ip_hl:4;\n\tunsigned int ip_v:4;\n#else\n\tunsigned int ip_v:4;\n\tunsigned int ip_hl:4;\n#endif\n\tuint8_t ip_tos;\n\tuint16_t ip_len;\n\tuint16_t ip_id;\n\tuint16_t ip_off;\n\tuint8_t ip_ttl;\n\tuint8_t ip_p;\n\tuint16_t ip_sum;\n\tstruct in_addr ip_src, ip_dst;\n};\n\n#define\tIP_RF 0x8000\n#define\tIP_DF 0x4000\n#define\tIP_MF 0x2000\n#define\tIP_OFFMASK 0x1fff\n\nstruct ip_timestamp {\n\tuint8_t ipt_code;\n\tuint8_t ipt_len;\n\tuint8_t ipt_ptr;\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n\tunsigned int ipt_flg:4;\n\tunsigned int ipt_oflw:4;\n#else\n\tunsigned int ipt_oflw:4;\n\tunsigned int ipt_flg:4;\n#endif\n\tuint32_t data[9];\n};\n\n#define\tIPVERSION\t4\n#define\tIP_MAXPACKET\t65535\n\n#define\tIPTOS_ECN_MASK\t\t0x03\n#define\tIPTOS_ECN(x)\t\t((x) & IPTOS_ECN_MASK)\n#define\tIPTOS_ECN_NOT_ECT\t0x00\n#define\tIPTOS_ECN_ECT1\t\t0x01\n#define\tIPTOS_ECN_ECT0\t\t0x02\n#define\tIPTOS_ECN_CE\t\t0x03\n\n#define\tIPTOS_DSCP_MASK\t\t0xfc\n#define\tIPTOS_DSCP(x)\t\t((x) & IPTOS_DSCP_MASK)\n#define\tIPTOS_DSCP_AF11\t\t0x28\n#define\tIPTOS_DSCP_AF12\t\t0x30\n#define\tIPTOS_DSCP_AF13\t\t0x38\n#define\tIPTOS_DSCP_AF21\t\t0x48\n#define\tIPTOS_DSCP_AF22\t\t0x50\n#define\tIPTOS_DSCP_AF23\t\t0x58\n#define\tIPTOS_DSCP_AF31\t\t0x68\n#define\tIPTOS_DSCP_AF32\t\t0x70\n#define\tIPTOS_DSCP_AF33\t\t0x78\n#define\tIPTOS_DSCP_AF41\t\t0x88\n#define\tIPTOS_DSCP_AF42\t\t0x90\n#define\tIPTOS_DSCP_AF43\t\t0x98\n#define\tIPTOS_DSCP_EF\t\t0xb8\n\n#define\tIPTOS_CLASS_MASK\t0xe0\n#define\tIPTOS_CLASS(x)\t\t((x) & IPTOS_CLASS_MASK)\n#define\tIPTOS_CLASS_CS0\t\t0x00\n#define\tIPTOS_CLASS_CS1\t\t0x20\n#define\tIPTOS_CLASS_CS2\t\t0x40\n#define\tIPTOS_CLASS_CS3\t\t0x60\n#define\tIPTOS_CLASS_CS4\t\t0x80\n#define\tIPTOS_CLASS_CS5\t\t0xa0\n#define\tIPTOS_CLASS_CS6\t\t0xc0\n#define\tIPTOS_CLASS_CS7\t\t0xe0\n#define\tIPTOS_CLASS_DEFAULT\tIPTOS_CLASS_CS0\n\n#define\tIPTOS_TOS_MASK\t\t0x1E\n#define\tIPTOS_TOS(tos)\t\t((tos) & IPTOS_TOS_MASK)\n#define\tIPTOS_LOWDELAY\t\t0x10\n#define\tIPTOS_THROUGHPUT\t0x08\n#define\tIPTOS_RELIABILITY\t0x04\n#define\tIPTOS_LOWCOST\t\t0x02\n#define\tIPTOS_MINCOST\t\tIPTOS_LOWCOST\n\n#define\tIPTOS_PREC_MASK\t\t\t0xe0\n#define\tIPTOS_PREC(tos)                ((tos) & IPTOS_PREC_MASK)\n#define\tIPTOS_PREC_NETCONTROL\t\t0xe0\n#define\tIPTOS_PREC_INTERNETCONTROL\t0xc0\n#define\tIPTOS_PREC_CRITIC_ECP\t\t0xa0\n#define\tIPTOS_PREC_FLASHOVERRIDE\t0x80\n#define\tIPTOS_PREC_FLASH\t\t0x60\n#define\tIPTOS_PREC_IMMEDIATE\t\t0x40\n#define\tIPTOS_PREC_PRIORITY\t\t0x20\n#define\tIPTOS_PREC_ROUTINE\t\t0x00\n\n#define\tIPOPT_COPY\t\t0x80\n#define\tIPOPT_CLASS_MASK\t0x60\n#define\tIPOPT_NUMBER_MASK\t0x1f\n\n#define\tIPOPT_COPIED(o)\t\t((o) & IPOPT_COPY)\n#define\tIPOPT_CLASS(o)\t\t((o) & IPOPT_CLASS_MASK)\n#define\tIPOPT_NUMBER(o)\t\t((o) & IPOPT_NUMBER_MASK)\n\n#define\tIPOPT_CONTROL\t\t0x00\n#define\tIPOPT_RESERVED1\t\t0x20\n#define\tIPOPT_DEBMEAS\t\t0x40\n#define\tIPOPT_MEASUREMENT       IPOPT_DEBMEAS\n#define\tIPOPT_RESERVED2\t\t0x60\n\n#define\tIPOPT_EOL\t\t0\n#define\tIPOPT_END\t\tIPOPT_EOL\n#define\tIPOPT_NOP\t\t1\n#define\tIPOPT_NOOP\t\tIPOPT_NOP\n\n#define\tIPOPT_RR\t\t7\n#define\tIPOPT_TS\t\t68\n#define\tIPOPT_TIMESTAMP\t\tIPOPT_TS\n#define\tIPOPT_SECURITY\t\t130\n#define\tIPOPT_SEC\t\tIPOPT_SECURITY\n#define\tIPOPT_LSRR\t\t131\n#define\tIPOPT_SATID\t\t136\n#define\tIPOPT_SID\t\tIPOPT_SATID\n#define\tIPOPT_SSRR\t\t137\n#define\tIPOPT_RA\t\t148\n\n#define\tIPOPT_OPTVAL\t\t0\n#define\tIPOPT_OLEN\t\t1\n#define\tIPOPT_OFFSET\t\t2\n#define\tIPOPT_MINOFF\t\t4\n\n#define\tMAX_IPOPTLEN\t\t40\n\n#define\tIPOPT_TS_TSONLY\t\t0\n#define\tIPOPT_TS_TSANDADDR\t1\n#define\tIPOPT_TS_PRESPEC\t3\n\n#define\tIPOPT_SECUR_UNCLASS\t0x0000\n#define\tIPOPT_SECUR_CONFID\t0xf135\n#define\tIPOPT_SECUR_EFTO\t0x789a\n#define\tIPOPT_SECUR_MMMM\t0xbc4d\n#define\tIPOPT_SECUR_RESTR\t0xaf13\n#define\tIPOPT_SECUR_SECRET\t0xd788\n#define\tIPOPT_SECUR_TOPSECRET\t0x6bc5\n\n#define\tMAXTTL\t\t255\n#define\tIPDEFTTL\t64\n#define\tIPFRAGTTL\t60\n#define\tIPTTLDEC\t1\n\n#define\tIP_MSS\t\t576\n\n#define __UAPI_DEF_IPHDR\t0\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/netinet/ip6.h",
    "content": "#ifndef _NETINET_IP6_H\n#define _NETINET_IP6_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n#include <netinet/in.h>\n\nstruct ip6_hdr {\n\tunion {\n\t\tstruct ip6_hdrctl {\n\t\t\tuint32_t ip6_un1_flow;\n\t\t\tuint16_t ip6_un1_plen;\n\t\t\tuint8_t  ip6_un1_nxt;\n\t\t\tuint8_t  ip6_un1_hlim;\n\t\t} ip6_un1;\n\t\tuint8_t ip6_un2_vfc;\n\t} ip6_ctlun;\n\tstruct in6_addr ip6_src;\n\tstruct in6_addr ip6_dst;\n};\n\n#define ip6_vfc   ip6_ctlun.ip6_un2_vfc\n#define ip6_flow  ip6_ctlun.ip6_un1.ip6_un1_flow\n#define ip6_plen  ip6_ctlun.ip6_un1.ip6_un1_plen\n#define ip6_nxt   ip6_ctlun.ip6_un1.ip6_un1_nxt\n#define ip6_hlim  ip6_ctlun.ip6_un1.ip6_un1_hlim\n#define ip6_hops  ip6_ctlun.ip6_un1.ip6_un1_hlim\n\nstruct ip6_ext {\n\tuint8_t  ip6e_nxt;\n\tuint8_t  ip6e_len;\n};\n\nstruct ip6_hbh {\n\tuint8_t  ip6h_nxt;\n\tuint8_t  ip6h_len;\n};\n\nstruct ip6_dest {\n\tuint8_t  ip6d_nxt;\n\tuint8_t  ip6d_len;\n};\n\nstruct ip6_rthdr {\n\tuint8_t  ip6r_nxt;\n\tuint8_t  ip6r_len;\n\tuint8_t  ip6r_type;\n\tuint8_t  ip6r_segleft;\n};\n\nstruct ip6_rthdr0 {\n\tuint8_t  ip6r0_nxt;\n\tuint8_t  ip6r0_len;\n\tuint8_t  ip6r0_type;\n\tuint8_t  ip6r0_segleft;\n\tuint8_t  ip6r0_reserved;\n\tuint8_t  ip6r0_slmap[3];\n\tstruct in6_addr ip6r0_addr[];\n};\n\nstruct ip6_frag {\n\tuint8_t   ip6f_nxt;\n\tuint8_t   ip6f_reserved;\n\tuint16_t  ip6f_offlg;\n\tuint32_t  ip6f_ident;\n};\n\n#if __BYTE_ORDER == __BIG_ENDIAN\n#define IP6F_OFF_MASK       0xfff8\n#define IP6F_RESERVED_MASK  0x0006\n#define IP6F_MORE_FRAG      0x0001\n#else\n#define IP6F_OFF_MASK       0xf8ff\n#define IP6F_RESERVED_MASK  0x0600\n#define IP6F_MORE_FRAG      0x0100\n#endif\n\nstruct ip6_opt {\n\tuint8_t  ip6o_type;\n\tuint8_t  ip6o_len;\n};\n\n#define IP6OPT_TYPE(o)\t\t((o) & 0xc0)\n#define IP6OPT_TYPE_SKIP\t0x00\n#define IP6OPT_TYPE_DISCARD\t0x40\n#define IP6OPT_TYPE_FORCEICMP\t0x80\n#define IP6OPT_TYPE_ICMP\t0xc0\n#define IP6OPT_TYPE_MUTABLE\t0x20\n\n#define IP6OPT_PAD1\t0\n#define IP6OPT_PADN\t1\n\n#define IP6OPT_JUMBO\t\t0xc2\n#define IP6OPT_NSAP_ADDR\t0xc3\n#define IP6OPT_TUNNEL_LIMIT\t0x04\n#define IP6OPT_ROUTER_ALERT\t0x05\n\nstruct ip6_opt_jumbo {\n\tuint8_t  ip6oj_type;\n\tuint8_t  ip6oj_len;\n\tuint8_t  ip6oj_jumbo_len[4];\n};\n#define IP6OPT_JUMBO_LEN\t6\n\nstruct ip6_opt_nsap {\n\tuint8_t  ip6on_type;\n\tuint8_t  ip6on_len;\n\tuint8_t  ip6on_src_nsap_len;\n\tuint8_t  ip6on_dst_nsap_len;\n};\n\nstruct ip6_opt_tunnel {\n\tuint8_t  ip6ot_type;\n\tuint8_t  ip6ot_len;\n\tuint8_t  ip6ot_encap_limit;\n};\n\nstruct ip6_opt_router {\n\tuint8_t  ip6or_type;\n\tuint8_t  ip6or_len;\n\tuint8_t  ip6or_value[2];\n};\n\n#if __BYTE_ORDER == __BIG_ENDIAN\n#define IP6_ALERT_MLD\t0x0000\n#define IP6_ALERT_RSVP\t0x0001\n#define IP6_ALERT_AN\t0x0002\n#else\n#define IP6_ALERT_MLD\t0x0000\n#define IP6_ALERT_RSVP\t0x0100\n#define IP6_ALERT_AN\t0x0200\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/netinet/ip_icmp.h",
    "content": "#ifndef _NETINET_IP_ICMP_H\n#define _NETINET_IP_ICMP_H\n\n#include <stdint.h>\n#include <netinet/in.h>\n#include <netinet/ip.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nstruct icmphdr {\n\tuint8_t type;\n\tuint8_t code;\n\tuint16_t checksum;\n\tunion {\n\t\tstruct {\n\t\t\tuint16_t id;\n\t\t\tuint16_t sequence;\n\t\t} echo;\n\t\tuint32_t gateway;\n\t\tstruct {\n\t\t\tuint16_t __unused;\n\t\t\tuint16_t mtu;\n\t\t} frag;\n\t\tuint8_t reserved[4];\n\t} un;\n};\n\n#define ICMP_ECHOREPLY\t\t0\n#define ICMP_DEST_UNREACH\t3\n#define ICMP_SOURCE_QUENCH\t4\n#define ICMP_REDIRECT\t\t5\n#define ICMP_ECHO\t\t8\n#define ICMP_TIME_EXCEEDED\t11\n#define ICMP_PARAMETERPROB\t12\n#define ICMP_TIMESTAMP\t\t13\n#define ICMP_TIMESTAMPREPLY\t14\n#define ICMP_INFO_REQUEST\t15\n#define ICMP_INFO_REPLY\t\t16\n#define ICMP_ADDRESS\t\t17\n#define ICMP_ADDRESSREPLY\t18\n#define NR_ICMP_TYPES\t\t18\n\n\n#define ICMP_NET_UNREACH\t0\n#define ICMP_HOST_UNREACH\t1\n#define ICMP_PROT_UNREACH\t2\n#define ICMP_PORT_UNREACH\t3\n#define ICMP_FRAG_NEEDED\t4\n#define ICMP_SR_FAILED\t\t5\n#define ICMP_NET_UNKNOWN\t6\n#define ICMP_HOST_UNKNOWN\t7\n#define ICMP_HOST_ISOLATED\t8\n#define ICMP_NET_ANO\t\t9\n#define ICMP_HOST_ANO\t\t10\n#define ICMP_NET_UNR_TOS\t11\n#define ICMP_HOST_UNR_TOS\t12\n#define ICMP_PKT_FILTERED\t13\n#define ICMP_PREC_VIOLATION\t14\n#define ICMP_PREC_CUTOFF\t15\n#define NR_ICMP_UNREACH\t\t15\n\n#define ICMP_REDIR_NET\t\t0\n#define ICMP_REDIR_HOST\t\t1\n#define ICMP_REDIR_NETTOS\t2\n#define ICMP_REDIR_HOSTTOS\t3\n\n#define ICMP_EXC_TTL\t\t0\n#define ICMP_EXC_FRAGTIME\t1\n\n\nstruct icmp_ra_addr {\n\tuint32_t ira_addr;\n\tuint32_t ira_preference;\n};\n\nstruct icmp {\n\tuint8_t  icmp_type;\n\tuint8_t  icmp_code;\n\tuint16_t icmp_cksum;\n\tunion {\n\t\tuint8_t ih_pptr;\n\t\tstruct in_addr ih_gwaddr;\n\t\tstruct ih_idseq {\n\t\t\tuint16_t icd_id;\n\t\t\tuint16_t icd_seq;\n\t\t} ih_idseq;\n\t\tuint32_t ih_void;\n\n\t\tstruct ih_pmtu {\n\t\t\tuint16_t ipm_void;\n\t\t\tuint16_t ipm_nextmtu;\n\t\t} ih_pmtu;\n\n\t\tstruct ih_rtradv {\n\t\t\tuint8_t irt_num_addrs;\n\t\t\tuint8_t irt_wpa;\n\t\t\tuint16_t irt_lifetime;\n\t\t} ih_rtradv;\n\t} icmp_hun;\n\tunion {\n\t\tstruct {\n\t\t\tuint32_t its_otime;\n\t\t\tuint32_t its_rtime;\n\t\t\tuint32_t its_ttime;\n\t\t} id_ts;\n\t\tstruct {\n\t\t\tstruct ip idi_ip;\n\t\t} id_ip;\n\t\tstruct icmp_ra_addr id_radv;\n\t\tuint32_t   id_mask;\n\t\tuint8_t    id_data[1];\n\t} icmp_dun;\n};\n\n#define\ticmp_pptr\ticmp_hun.ih_pptr\n#define\ticmp_gwaddr\ticmp_hun.ih_gwaddr\n#define\ticmp_id\t\ticmp_hun.ih_idseq.icd_id\n#define\ticmp_seq\ticmp_hun.ih_idseq.icd_seq\n#define\ticmp_void\ticmp_hun.ih_void\n#define\ticmp_pmvoid\ticmp_hun.ih_pmtu.ipm_void\n#define\ticmp_nextmtu\ticmp_hun.ih_pmtu.ipm_nextmtu\n#define\ticmp_num_addrs\ticmp_hun.ih_rtradv.irt_num_addrs\n#define\ticmp_wpa\ticmp_hun.ih_rtradv.irt_wpa\n#define\ticmp_lifetime\ticmp_hun.ih_rtradv.irt_lifetime\n#define\ticmp_otime\ticmp_dun.id_ts.its_otime\n#define\ticmp_rtime\ticmp_dun.id_ts.its_rtime\n#define\ticmp_ttime\ticmp_dun.id_ts.its_ttime\n#define\ticmp_ip\t\ticmp_dun.id_ip.idi_ip\n#define\ticmp_radv\ticmp_dun.id_radv\n#define\ticmp_mask\ticmp_dun.id_mask\n#define\ticmp_data\ticmp_dun.id_data\n\n#define\tICMP_MINLEN\t8\n#define\tICMP_TSLEN\t(8 + 3 * sizeof (n_time))\n#define\tICMP_MASKLEN\t12\n#define\tICMP_ADVLENMIN\t(8 + sizeof (struct ip) + 8)\n#define\tICMP_ADVLEN(p)\t(8 + ((p)->icmp_ip.ip_hl << 2) + 8)\n\n#define\tICMP_UNREACH\t\t3\n#define\tICMP_SOURCEQUENCH\t4\n#define\tICMP_ROUTERADVERT\t9\n#define\tICMP_ROUTERSOLICIT\t10\n#define\tICMP_TIMXCEED\t\t11\n#define\tICMP_PARAMPROB\t\t12\n#define\tICMP_TSTAMP\t\t13\n#define\tICMP_TSTAMPREPLY\t14\n#define\tICMP_IREQ\t\t15\n#define\tICMP_IREQREPLY\t\t16\n#define\tICMP_MASKREQ\t\t17\n#define\tICMP_MASKREPLY\t\t18\n#define\tICMP_MAXTYPE\t\t18\n\n#define\tICMP_UNREACH_NET\t        0\n#define\tICMP_UNREACH_HOST\t        1\n#define\tICMP_UNREACH_PROTOCOL\t        2\n#define\tICMP_UNREACH_PORT\t        3\n#define\tICMP_UNREACH_NEEDFRAG\t        4\n#define\tICMP_UNREACH_SRCFAIL\t        5\n#define\tICMP_UNREACH_NET_UNKNOWN        6\n#define\tICMP_UNREACH_HOST_UNKNOWN       7\n#define\tICMP_UNREACH_ISOLATED\t        8\n#define\tICMP_UNREACH_NET_PROHIB\t        9\n#define\tICMP_UNREACH_HOST_PROHIB        10\n#define\tICMP_UNREACH_TOSNET\t        11\n#define\tICMP_UNREACH_TOSHOST\t        12\n#define\tICMP_UNREACH_FILTER_PROHIB      13\n#define\tICMP_UNREACH_HOST_PRECEDENCE    14\n#define\tICMP_UNREACH_PRECEDENCE_CUTOFF  15\n\n#define\tICMP_REDIRECT_NET\t0\n#define\tICMP_REDIRECT_HOST\t1\n#define\tICMP_REDIRECT_TOSNET\t2\n#define\tICMP_REDIRECT_TOSHOST\t3\n\n#define\tICMP_TIMXCEED_INTRANS\t0\n#define\tICMP_TIMXCEED_REASS\t1\n\n#define\tICMP_PARAMPROB_OPTABSENT 1\n\n#define\tICMP_INFOTYPE(type) \\\n\t((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \\\n\t(type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \\\n\t(type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \\\n\t(type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \\\n\t(type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/netinet/tcp.h",
    "content": "#ifndef _NETINET_TCP_H\n#define _NETINET_TCP_H\n\n#include <features.h>\n\n#define TCP_NODELAY 1\n#define TCP_MAXSEG\t 2\n#define TCP_CORK\t 3\n#define TCP_KEEPIDLE\t 4\n#define TCP_KEEPINTVL\t 5\n#define TCP_KEEPCNT\t 6\n#define TCP_SYNCNT\t 7\n#define TCP_LINGER2\t 8\n#define TCP_DEFER_ACCEPT 9\n#define TCP_WINDOW_CLAMP 10\n#define TCP_INFO\t 11\n#define\tTCP_QUICKACK\t 12\n#define TCP_CONGESTION\t 13\n#define TCP_MD5SIG\t 14\n#define TCP_THIN_LINEAR_TIMEOUTS 16\n#define TCP_THIN_DUPACK  17\n#define TCP_USER_TIMEOUT 18\n#define TCP_REPAIR       19\n#define TCP_REPAIR_QUEUE 20\n#define TCP_QUEUE_SEQ    21\n#define TCP_REPAIR_OPTIONS 22\n#define TCP_FASTOPEN     23\n#define TCP_TIMESTAMP    24\n#define TCP_NOTSENT_LOWAT 25\n#define TCP_CC_INFO      26\n#define TCP_SAVE_SYN     27\n#define TCP_SAVED_SYN    28\n#define TCP_REPAIR_WINDOW 29\n#define TCP_FASTOPEN_CONNECT 30\n#define TCP_ULP          31\n#define TCP_MD5SIG_EXT   32\n#define TCP_FASTOPEN_KEY 33\n#define TCP_FASTOPEN_NO_COOKIE 34\n#define TCP_ZEROCOPY_RECEIVE   35\n#define TCP_INQ          36\n#define TCP_TX_DELAY     37\n\n#define TCP_CM_INQ TCP_INQ\n\n#define TCP_ESTABLISHED  1\n#define TCP_SYN_SENT     2\n#define TCP_SYN_RECV     3\n#define TCP_FIN_WAIT1    4\n#define TCP_FIN_WAIT2    5\n#define TCP_TIME_WAIT    6\n#define TCP_CLOSE        7\n#define TCP_CLOSE_WAIT   8\n#define TCP_LAST_ACK     9\n#define TCP_LISTEN       10\n#define TCP_CLOSING      11\n\nenum {\n\tTCP_NLA_PAD,\n\tTCP_NLA_BUSY,\n\tTCP_NLA_RWND_LIMITED,\n\tTCP_NLA_SNDBUF_LIMITED,\n\tTCP_NLA_DATA_SEGS_OUT,\n\tTCP_NLA_TOTAL_RETRANS,\n\tTCP_NLA_PACING_RATE,\n\tTCP_NLA_DELIVERY_RATE,\n\tTCP_NLA_SND_CWND,\n\tTCP_NLA_REORDERING,\n\tTCP_NLA_MIN_RTT,\n\tTCP_NLA_RECUR_RETRANS,\n\tTCP_NLA_DELIVERY_RATE_APP_LMT,\n\tTCP_NLA_SNDQ_SIZE,\n\tTCP_NLA_CA_STATE,\n\tTCP_NLA_SND_SSTHRESH,\n\tTCP_NLA_DELIVERED,\n\tTCP_NLA_DELIVERED_CE,\n\tTCP_NLA_BYTES_SENT,\n\tTCP_NLA_BYTES_RETRANS,\n\tTCP_NLA_DSACK_DUPS,\n\tTCP_NLA_REORD_SEEN,\n\tTCP_NLA_SRTT,\n\tTCP_NLA_TIMEOUT_REHASH,\n\tTCP_NLA_BYTES_NOTSENT,\n};\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define TCPOPT_EOL              0\n#define TCPOPT_NOP              1\n#define TCPOPT_MAXSEG           2\n#define TCPOPT_WINDOW           3\n#define TCPOPT_SACK_PERMITTED   4\n#define TCPOPT_SACK             5\n#define TCPOPT_TIMESTAMP        8\n#define TCPOLEN_SACK_PERMITTED  2\n#define TCPOLEN_WINDOW          3\n#define TCPOLEN_MAXSEG          4\n#define TCPOLEN_TIMESTAMP       10\n\n#define SOL_TCP 6\n\n#include <sys/types.h>\n#include <sys/socket.h>\n#include <stdint.h>\n\ntypedef uint32_t tcp_seq;\n\n#define TH_FIN 0x01\n#define TH_SYN 0x02\n#define TH_RST 0x04\n#define TH_PUSH 0x08\n#define TH_ACK 0x10\n#define TH_URG 0x20\n\nstruct tcphdr {\n#ifdef _GNU_SOURCE\n#ifdef __GNUC__\n\t__extension__\n#endif\n\tunion { struct {\n\n\tuint16_t source;\n\tuint16_t dest;\n\tuint32_t seq;\n\tuint32_t ack_seq;\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n\tuint16_t res1:4;\n\tuint16_t doff:4;\n\tuint16_t fin:1;\n\tuint16_t syn:1;\n\tuint16_t rst:1;\n\tuint16_t psh:1;\n\tuint16_t ack:1;\n\tuint16_t urg:1;\n\tuint16_t res2:2;\n#else\n\tuint16_t doff:4;\n\tuint16_t res1:4;\n\tuint16_t res2:2;\n\tuint16_t urg:1;\n\tuint16_t ack:1;\n\tuint16_t psh:1;\n\tuint16_t rst:1;\n\tuint16_t syn:1;\n\tuint16_t fin:1;\n#endif\n\tuint16_t window;\n\tuint16_t check;\n\tuint16_t urg_ptr;\n\n\t}; struct {\n#endif\n\n\tuint16_t th_sport;\n\tuint16_t th_dport;\n\tuint32_t th_seq;\n\tuint32_t th_ack;\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n\tuint8_t th_x2:4;\n\tuint8_t th_off:4;\n#else\n\tuint8_t th_off:4;\n\tuint8_t th_x2:4;\n#endif\n\tuint8_t th_flags;\n\tuint16_t th_win;\n\tuint16_t th_sum;\n\tuint16_t th_urp;\n\n#ifdef _GNU_SOURCE\n\t}; };\n#endif\n};\n#endif\n\n#ifdef _GNU_SOURCE\n#define TCPI_OPT_TIMESTAMPS\t1\n#define TCPI_OPT_SACK\t\t2\n#define TCPI_OPT_WSCALE\t\t4\n#define TCPI_OPT_ECN\t\t8\n\n#define TCP_CA_Open\t\t0\n#define TCP_CA_Disorder\t\t1\n#define TCP_CA_CWR\t\t2\n#define TCP_CA_Recovery\t\t3\n#define TCP_CA_Loss\t\t4\n\nenum tcp_fastopen_client_fail {\n\tTFO_STATUS_UNSPEC,\n\tTFO_COOKIE_UNAVAILABLE,\n\tTFO_DATA_NOT_ACKED,\n\tTFO_SYN_RETRANSMITTED,\n};\n\nstruct tcp_info {\n\tuint8_t tcpi_state;\n\tuint8_t tcpi_ca_state;\n\tuint8_t tcpi_retransmits;\n\tuint8_t tcpi_probes;\n\tuint8_t tcpi_backoff;\n\tuint8_t tcpi_options;\n\tuint8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;\n\tuint8_t tcpi_delivery_rate_app_limited : 1, tcpi_fastopen_client_fail : 2;\n\tuint32_t tcpi_rto;\n\tuint32_t tcpi_ato;\n\tuint32_t tcpi_snd_mss;\n\tuint32_t tcpi_rcv_mss;\n\tuint32_t tcpi_unacked;\n\tuint32_t tcpi_sacked;\n\tuint32_t tcpi_lost;\n\tuint32_t tcpi_retrans;\n\tuint32_t tcpi_fackets;\n\tuint32_t tcpi_last_data_sent;\n\tuint32_t tcpi_last_ack_sent;\n\tuint32_t tcpi_last_data_recv;\n\tuint32_t tcpi_last_ack_recv;\n\tuint32_t tcpi_pmtu;\n\tuint32_t tcpi_rcv_ssthresh;\n\tuint32_t tcpi_rtt;\n\tuint32_t tcpi_rttvar;\n\tuint32_t tcpi_snd_ssthresh;\n\tuint32_t tcpi_snd_cwnd;\n\tuint32_t tcpi_advmss;\n\tuint32_t tcpi_reordering;\n\tuint32_t tcpi_rcv_rtt;\n\tuint32_t tcpi_rcv_space;\n\tuint32_t tcpi_total_retrans;\n\tuint64_t tcpi_pacing_rate;\n\tuint64_t tcpi_max_pacing_rate;\n\tuint64_t tcpi_bytes_acked;\n\tuint64_t tcpi_bytes_received;\n\tuint32_t tcpi_segs_out;\n\tuint32_t tcpi_segs_in;\n\tuint32_t tcpi_notsent_bytes;\n\tuint32_t tcpi_min_rtt;\n\tuint32_t tcpi_data_segs_in;\n\tuint32_t tcpi_data_segs_out;\n\tuint64_t tcpi_delivery_rate;\n\tuint64_t tcpi_busy_time;\n\tuint64_t tcpi_rwnd_limited;\n\tuint64_t tcpi_sndbuf_limited;\n\tuint32_t tcpi_delivered;\n\tuint32_t tcpi_delivered_ce;\n\tuint64_t tcpi_bytes_sent;\n\tuint64_t tcpi_bytes_retrans;\n\tuint32_t tcpi_dsack_dups;\n\tuint32_t tcpi_reord_seen;\n\tuint32_t tcpi_rcv_ooopack;\n\tuint32_t tcpi_snd_wnd;\n};\n\n#define TCP_MD5SIG_MAXKEYLEN    80\n\n#define TCP_MD5SIG_FLAG_PREFIX  0x1\n#define TCP_MD5SIG_FLAG_IFINDEX 0x2\n\nstruct tcp_md5sig {\n\tstruct sockaddr_storage tcpm_addr;\n\tuint8_t tcpm_flags;\n\tuint8_t tcpm_prefixlen;\n\tuint16_t tcpm_keylen;\n\tint tcpm_ifindex;\n\tuint8_t tcpm_key[TCP_MD5SIG_MAXKEYLEN];\n};\n\nstruct tcp_diag_md5sig {\n\tuint8_t tcpm_family;\n\tuint8_t tcpm_prefixlen;\n\tuint16_t tcpm_keylen;\n\tuint32_t tcpm_addr[4];\n\tuint8_t tcpm_key[TCP_MD5SIG_MAXKEYLEN];\n};\n\n#define TCP_REPAIR_ON\t\t1\n#define TCP_REPAIR_OFF\t\t0\n#define TCP_REPAIR_OFF_NO_WP\t-1\n\nstruct tcp_repair_window {\n\tuint32_t snd_wl1;\n\tuint32_t snd_wnd;\n\tuint32_t max_window;\n\tuint32_t rcv_wnd;\n\tuint32_t rcv_wup;\n};\n\nstruct tcp_zerocopy_receive {\n\tuint64_t address;\n\tuint32_t length;\n\tuint32_t recv_skip_hint;\n\tuint32_t inq;\n\tint32_t err;\n};\n\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/netinet/udp.h",
    "content": "#ifndef _NETINET_UDP_H\n#define _NETINET_UDP_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n#include <stdint.h>\n\n#ifdef _GNU_SOURCE\n#define uh_sport source\n#define uh_dport dest\n#define uh_ulen len\n#define uh_sum check\n#endif\n\nstruct udphdr {\n\tuint16_t uh_sport;\n\tuint16_t uh_dport;\n\tuint16_t uh_ulen;\n\tuint16_t uh_sum;\n};\n\n#define UDP_CORK\t1\n#define UDP_ENCAP\t100\n#define UDP_NO_CHECK6_TX 101\n#define UDP_NO_CHECK6_RX 102\n#define UDP_SEGMENT\t103\n#define UDP_GRO\t\t104\n\n#define UDP_ENCAP_ESPINUDP_NON_IKE 1\n#define UDP_ENCAP_ESPINUDP\t2\n#define UDP_ENCAP_L2TPINUDP\t3\n#define UDP_ENCAP_GTP0\t\t4\n#define UDP_ENCAP_GTP1U\t\t5\n#define UDP_ENCAP_RXRPC\t\t6\n#define TCP_ENCAP_ESPINTCP\t7\n\n#define SOL_UDP            17\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/netpacket/packet.h",
    "content": "#ifndef _NETPACKET_PACKET_H\n#define _NETPACKET_PACKET_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nstruct sockaddr_ll {\n\tunsigned short sll_family, sll_protocol;\n\tint sll_ifindex;\n\tunsigned short sll_hatype;\n\tunsigned char sll_pkttype, sll_halen;\n\tunsigned char sll_addr[8];\n};\n\nstruct packet_mreq {\n\tint mr_ifindex;\n\tunsigned short int mr_type,  mr_alen;\n\tunsigned char mr_address[8];\n};\n\n#define PACKET_HOST\t\t0\n#define PACKET_BROADCAST\t1\n#define PACKET_MULTICAST\t2\n#define PACKET_OTHERHOST\t3\n#define PACKET_OUTGOING\t\t4\n#define PACKET_LOOPBACK\t\t5\n#define PACKET_FASTROUTE\t6\n\n#define PACKET_ADD_MEMBERSHIP\t\t1\n#define PACKET_DROP_MEMBERSHIP\t\t2\n#define\tPACKET_RECV_OUTPUT\t\t3\n#define\tPACKET_RX_RING\t\t\t5\n#define\tPACKET_STATISTICS\t\t6\n#define PACKET_COPY_THRESH\t\t7\n#define PACKET_AUXDATA\t\t\t8\n#define PACKET_ORIGDEV\t\t\t9\n#define PACKET_VERSION\t\t\t10\n#define PACKET_HDRLEN\t\t\t11\n#define PACKET_RESERVE\t\t\t12\n#define PACKET_TX_RING\t\t\t13\n#define PACKET_LOSS\t\t\t14\n#define PACKET_VNET_HDR\t\t\t15\n#define PACKET_TX_TIMESTAMP\t\t16\n#define PACKET_TIMESTAMP\t\t17\n#define PACKET_FANOUT\t\t\t18\n#define PACKET_TX_HAS_OFF\t\t19\n#define PACKET_QDISC_BYPASS\t\t20\n#define PACKET_ROLLOVER_STATS\t\t21\n#define PACKET_FANOUT_DATA\t\t22\n#define PACKET_IGNORE_OUTGOING\t\t23\n\n#define PACKET_MR_MULTICAST\t0\n#define PACKET_MR_PROMISC\t1\n#define PACKET_MR_ALLMULTI\t2\n#define PACKET_MR_UNICAST\t3\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/nl_types.h",
    "content": "#ifndef _NL_TYPES_H\n#define _NL_TYPES_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define NL_SETD 1\n#define NL_CAT_LOCALE 1\n\ntypedef int nl_item;\ntypedef void *nl_catd;\n\nnl_catd catopen (const char *, int);\nchar *catgets (nl_catd, int, int, const char *);\nint catclose (nl_catd);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/paths.h",
    "content": "#ifndef _PATHS_H\n#define _PATHS_H\n\n#define\t_PATH_DEFPATH \"/usr/local/bin:/bin:/usr/bin\"\n#define\t_PATH_STDPATH \"/bin:/usr/bin:/sbin:/usr/sbin\"\n\n#define\t_PATH_BSHELL\t\"/bin/sh\"\n#define\t_PATH_CONSOLE\t\"/dev/console\"\n#define\t_PATH_DEVNULL\t\"/dev/null\"\n#define\t_PATH_KLOG\t\"/proc/kmsg\"\n#define\t_PATH_LASTLOG\t\"/var/log/lastlog\"\n#define\t_PATH_MAILDIR\t\"/var/mail\"\n#define\t_PATH_MAN\t\"/usr/share/man\"\n#define\t_PATH_MNTTAB\t\"/etc/fstab\"\n#define\t_PATH_MOUNTED\t\"/etc/mtab\"\n#define\t_PATH_NOLOGIN\t\"/etc/nologin\"\n#define\t_PATH_SENDMAIL\t\"/usr/sbin/sendmail\"\n#define\t_PATH_SHADOW\t\"/etc/shadow\"\n#define\t_PATH_SHELLS\t\"/etc/shells\"\n#define\t_PATH_TTY\t\"/dev/tty\"\n#define _PATH_UTMP\t\"/dev/null/utmp\"\n#define\t_PATH_VI\t\"/usr/bin/vi\"\n#define _PATH_WTMP\t\"/dev/null/wtmp\"\n\n#define\t_PATH_DEV\t\"/dev/\"\n#define\t_PATH_TMP\t\"/tmp/\"\n#define\t_PATH_VARDB\t\"/var/lib/misc/\"\n#define\t_PATH_VARRUN\t\"/var/run/\"\n#define\t_PATH_VARTMP\t\"/var/tmp/\"\n\n#endif\n"
  },
  {
    "path": "user.libc/include/poll.h",
    "content": "#ifndef\t_POLL_H\n#define\t_POLL_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#include <bits/poll.h>\n\n#define POLLIN     0x001\n#define POLLPRI    0x002\n#define POLLOUT    0x004\n#define POLLERR    0x008\n#define POLLHUP    0x010\n#define POLLNVAL   0x020\n#define POLLRDNORM 0x040\n#define POLLRDBAND 0x080\n#ifndef POLLWRNORM\n#define POLLWRNORM 0x100\n#define POLLWRBAND 0x200\n#endif\n#ifndef POLLMSG\n#define POLLMSG    0x400\n#define POLLRDHUP  0x2000\n#endif\n\ntypedef unsigned long nfds_t;\n\nstruct pollfd {\n\tint fd;\n\tshort events;\n\tshort revents;\n};\n\nint poll (struct pollfd *, nfds_t, int);\n\n#ifdef _GNU_SOURCE\n#define __NEED_time_t\n#define __NEED_struct_timespec\n#define __NEED_sigset_t\n#include <bits/alltypes.h>\nint ppoll(struct pollfd *, nfds_t, const struct timespec *, const sigset_t *);\n#endif\n\n#if _REDIR_TIME64\n#ifdef _GNU_SOURCE\n__REDIR(ppoll, __ppoll_time64);\n#endif\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/pthread.h",
    "content": "#ifndef _PTHREAD_H\n#define _PTHREAD_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_time_t\n#define __NEED_clockid_t\n#define __NEED_struct_timespec\n#define __NEED_sigset_t\n#define __NEED_pthread_t\n#define __NEED_pthread_attr_t\n#define __NEED_pthread_mutexattr_t\n#define __NEED_pthread_condattr_t\n#define __NEED_pthread_rwlockattr_t\n#define __NEED_pthread_barrierattr_t\n#define __NEED_pthread_mutex_t\n#define __NEED_pthread_cond_t\n#define __NEED_pthread_rwlock_t\n#define __NEED_pthread_barrier_t\n#define __NEED_pthread_spinlock_t\n#define __NEED_pthread_key_t\n#define __NEED_pthread_once_t\n#define __NEED_size_t\n\n#include <bits/alltypes.h>\n\n#include <sched.h>\n#include <time.h>\n\n#define PTHREAD_CREATE_JOINABLE 0\n#define PTHREAD_CREATE_DETACHED 1\n\n#define PTHREAD_MUTEX_NORMAL 0\n#define PTHREAD_MUTEX_DEFAULT 0\n#define PTHREAD_MUTEX_RECURSIVE 1\n#define PTHREAD_MUTEX_ERRORCHECK 2\n\n#define PTHREAD_MUTEX_STALLED 0\n#define PTHREAD_MUTEX_ROBUST 1\n\n#define PTHREAD_PRIO_NONE 0\n#define PTHREAD_PRIO_INHERIT 1\n#define PTHREAD_PRIO_PROTECT 2\n\n#define PTHREAD_INHERIT_SCHED 0\n#define PTHREAD_EXPLICIT_SCHED 1\n\n#define PTHREAD_SCOPE_SYSTEM 0\n#define PTHREAD_SCOPE_PROCESS 1\n\n#define PTHREAD_PROCESS_PRIVATE 0\n#define PTHREAD_PROCESS_SHARED 1\n\n\n#define PTHREAD_MUTEX_INITIALIZER {{{0}}}\n#define PTHREAD_RWLOCK_INITIALIZER {{{0}}}\n#define PTHREAD_COND_INITIALIZER {{{0}}}\n#define PTHREAD_ONCE_INIT 0\n\n\n#define PTHREAD_CANCEL_ENABLE 0\n#define PTHREAD_CANCEL_DISABLE 1\n#define PTHREAD_CANCEL_MASKED 2\n\n#define PTHREAD_CANCEL_DEFERRED 0\n#define PTHREAD_CANCEL_ASYNCHRONOUS 1\n\n#define PTHREAD_CANCELED ((void *)-1)\n\n\n#define PTHREAD_BARRIER_SERIAL_THREAD (-1)\n\n\n#define PTHREAD_NULL ((pthread_t)0)\n\n\nint pthread_create(pthread_t *__restrict, const pthread_attr_t *__restrict, void *(*)(void *), void *__restrict);\nint pthread_detach(pthread_t);\n_Noreturn void pthread_exit(void *);\nint pthread_join(pthread_t, void **);\n\n#ifdef __GNUC__\n__attribute__((const))\n#endif\npthread_t pthread_self(void);\n\nint pthread_equal(pthread_t, pthread_t);\n#ifndef __cplusplus\n#define pthread_equal(x,y) ((x)==(y))\n#endif\n\nint pthread_setcancelstate(int, int *);\nint pthread_setcanceltype(int, int *);\nvoid pthread_testcancel(void);\nint pthread_cancel(pthread_t);\n\nint pthread_getschedparam(pthread_t, int *__restrict, struct sched_param *__restrict);\nint pthread_setschedparam(pthread_t, int, const struct sched_param *);\nint pthread_setschedprio(pthread_t, int);\n\nint pthread_once(pthread_once_t *, void (*)(void));\n\nint pthread_mutex_init(pthread_mutex_t *__restrict, const pthread_mutexattr_t *__restrict);\nint pthread_mutex_lock(pthread_mutex_t *);\nint pthread_mutex_unlock(pthread_mutex_t *);\nint pthread_mutex_trylock(pthread_mutex_t *);\nint pthread_mutex_timedlock(pthread_mutex_t *__restrict, const struct timespec *__restrict);\nint pthread_mutex_destroy(pthread_mutex_t *);\nint pthread_mutex_consistent(pthread_mutex_t *);\n\nint pthread_mutex_getprioceiling(const pthread_mutex_t *__restrict, int *__restrict);\nint pthread_mutex_setprioceiling(pthread_mutex_t *__restrict, int, int *__restrict);\n\nint pthread_cond_init(pthread_cond_t *__restrict, const pthread_condattr_t *__restrict);\nint pthread_cond_destroy(pthread_cond_t *);\nint pthread_cond_wait(pthread_cond_t *__restrict, pthread_mutex_t *__restrict);\nint pthread_cond_timedwait(pthread_cond_t *__restrict, pthread_mutex_t *__restrict, const struct timespec *__restrict);\nint pthread_cond_broadcast(pthread_cond_t *);\nint pthread_cond_signal(pthread_cond_t *);\n\nint pthread_rwlock_init(pthread_rwlock_t *__restrict, const pthread_rwlockattr_t *__restrict);\nint pthread_rwlock_destroy(pthread_rwlock_t *);\nint pthread_rwlock_rdlock(pthread_rwlock_t *);\nint pthread_rwlock_tryrdlock(pthread_rwlock_t *);\nint pthread_rwlock_timedrdlock(pthread_rwlock_t *__restrict, const struct timespec *__restrict);\nint pthread_rwlock_wrlock(pthread_rwlock_t *);\nint pthread_rwlock_trywrlock(pthread_rwlock_t *);\nint pthread_rwlock_timedwrlock(pthread_rwlock_t *__restrict, const struct timespec *__restrict);\nint pthread_rwlock_unlock(pthread_rwlock_t *);\n\nint pthread_spin_init(pthread_spinlock_t *, int);\nint pthread_spin_destroy(pthread_spinlock_t *);\nint pthread_spin_lock(pthread_spinlock_t *);\nint pthread_spin_trylock(pthread_spinlock_t *);\nint pthread_spin_unlock(pthread_spinlock_t *);\n\nint pthread_barrier_init(pthread_barrier_t *__restrict, const pthread_barrierattr_t *__restrict, unsigned);\nint pthread_barrier_destroy(pthread_barrier_t *);\nint pthread_barrier_wait(pthread_barrier_t *);\n\nint pthread_key_create(pthread_key_t *, void (*)(void *));\nint pthread_key_delete(pthread_key_t);\nvoid *pthread_getspecific(pthread_key_t);\nint pthread_setspecific(pthread_key_t, const void *);\n\nint pthread_attr_init(pthread_attr_t *);\nint pthread_attr_destroy(pthread_attr_t *);\n\nint pthread_attr_getguardsize(const pthread_attr_t *__restrict, size_t *__restrict);\nint pthread_attr_setguardsize(pthread_attr_t *, size_t);\nint pthread_attr_getstacksize(const pthread_attr_t *__restrict, size_t *__restrict);\nint pthread_attr_setstacksize(pthread_attr_t *, size_t);\nint pthread_attr_getdetachstate(const pthread_attr_t *, int *);\nint pthread_attr_setdetachstate(pthread_attr_t *, int);\nint pthread_attr_getstack(const pthread_attr_t *__restrict, void **__restrict, size_t *__restrict);\nint pthread_attr_setstack(pthread_attr_t *, void *, size_t);\nint pthread_attr_getscope(const pthread_attr_t *__restrict, int *__restrict);\nint pthread_attr_setscope(pthread_attr_t *, int);\nint pthread_attr_getschedpolicy(const pthread_attr_t *__restrict, int *__restrict);\nint pthread_attr_setschedpolicy(pthread_attr_t *, int);\nint pthread_attr_getschedparam(const pthread_attr_t *__restrict, struct sched_param *__restrict);\nint pthread_attr_setschedparam(pthread_attr_t *__restrict, const struct sched_param *__restrict);\nint pthread_attr_getinheritsched(const pthread_attr_t *__restrict, int *__restrict);\nint pthread_attr_setinheritsched(pthread_attr_t *, int);\n\nint pthread_mutexattr_destroy(pthread_mutexattr_t *);\nint pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *__restrict, int *__restrict);\nint pthread_mutexattr_getprotocol(const pthread_mutexattr_t *__restrict, int *__restrict);\nint pthread_mutexattr_getpshared(const pthread_mutexattr_t *__restrict, int *__restrict);\nint pthread_mutexattr_getrobust(const pthread_mutexattr_t *__restrict, int *__restrict);\nint pthread_mutexattr_gettype(const pthread_mutexattr_t *__restrict, int *__restrict);\nint pthread_mutexattr_init(pthread_mutexattr_t *);\nint pthread_mutexattr_setprioceiling(pthread_mutexattr_t *, int);\nint pthread_mutexattr_setprotocol(pthread_mutexattr_t *, int);\nint pthread_mutexattr_setpshared(pthread_mutexattr_t *, int);\nint pthread_mutexattr_setrobust(pthread_mutexattr_t *, int);\nint pthread_mutexattr_settype(pthread_mutexattr_t *, int);\n\nint pthread_condattr_init(pthread_condattr_t *);\nint pthread_condattr_destroy(pthread_condattr_t *);\nint pthread_condattr_setclock(pthread_condattr_t *, clockid_t);\nint pthread_condattr_setpshared(pthread_condattr_t *, int);\nint pthread_condattr_getclock(const pthread_condattr_t *__restrict, clockid_t *__restrict);\nint pthread_condattr_getpshared(const pthread_condattr_t *__restrict, int *__restrict);\n\nint pthread_rwlockattr_init(pthread_rwlockattr_t *);\nint pthread_rwlockattr_destroy(pthread_rwlockattr_t *);\nint pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int);\nint pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *__restrict, int *__restrict);\n\nint pthread_barrierattr_destroy(pthread_barrierattr_t *);\nint pthread_barrierattr_getpshared(const pthread_barrierattr_t *__restrict, int *__restrict);\nint pthread_barrierattr_init(pthread_barrierattr_t *);\nint pthread_barrierattr_setpshared(pthread_barrierattr_t *, int);\n\nint pthread_atfork(void (*)(void), void (*)(void), void (*)(void));\n\nint pthread_getconcurrency(void);\nint pthread_setconcurrency(int);\n\nint pthread_getcpuclockid(pthread_t, clockid_t *);\n\nstruct __ptcb {\n\tvoid (*__f)(void *);\n\tvoid *__x;\n\tstruct __ptcb *__next;\n};\n\nvoid _pthread_cleanup_push(struct __ptcb *, void (*)(void *), void *);\nvoid _pthread_cleanup_pop(struct __ptcb *, int);\n\n#define pthread_cleanup_push(f, x) do { struct __ptcb __cb; _pthread_cleanup_push(&__cb, f, x);\n#define pthread_cleanup_pop(r) _pthread_cleanup_pop(&__cb, (r)); } while(0)\n\n#ifdef _GNU_SOURCE\nstruct cpu_set_t;\nint pthread_getaffinity_np(pthread_t, size_t, struct cpu_set_t *);\nint pthread_setaffinity_np(pthread_t, size_t, const struct cpu_set_t *);\nint pthread_getattr_np(pthread_t, pthread_attr_t *);\nint pthread_setname_np(pthread_t, const char *);\nint pthread_getattr_default_np(pthread_attr_t *);\nint pthread_setattr_default_np(const pthread_attr_t *);\nint pthread_tryjoin_np(pthread_t, void **);\nint pthread_timedjoin_np(pthread_t, void **, const struct timespec *);\n#endif\n\n#if _REDIR_TIME64\n__REDIR(pthread_mutex_timedlock, __pthread_mutex_timedlock_time64);\n__REDIR(pthread_cond_timedwait, __pthread_cond_timedwait_time64);\n__REDIR(pthread_rwlock_timedrdlock, __pthread_rwlock_timedrdlock_time64);\n__REDIR(pthread_rwlock_timedwrlock, __pthread_rwlock_timedwrlock_time64);\n#ifdef _GNU_SOURCE\n__REDIR(pthread_timedjoin_np, __pthread_timedjoin_np_time64);\n#endif\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/pty.h",
    "content": "#ifndef\t_PTY_H\n#define\t_PTY_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <termios.h>\n#include <sys/ioctl.h>\n\nint openpty(int *, int *, char *, const struct termios *, const struct winsize *);\nint forkpty(int *, char *, const struct termios *, const struct winsize *);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/pwd.h",
    "content": "#ifndef _PWD_H\n#define _PWD_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_size_t\n#define __NEED_uid_t\n#define __NEED_gid_t\n\n#ifdef _GNU_SOURCE\n#define __NEED_FILE\n#endif\n\n#include <bits/alltypes.h>\n\nstruct passwd {\n\tchar *pw_name;\n\tchar *pw_passwd;\n\tuid_t pw_uid;\n\tgid_t pw_gid;\n\tchar *pw_gecos;\n\tchar *pw_dir;\n\tchar *pw_shell;\n};\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\nvoid setpwent (void);\nvoid endpwent (void);\nstruct passwd *getpwent (void);\n#endif\n\nstruct passwd *getpwuid (uid_t);\nstruct passwd *getpwnam (const char *);\nint getpwuid_r (uid_t, struct passwd *, char *, size_t, struct passwd **);\nint getpwnam_r (const char *, struct passwd *, char *, size_t, struct passwd **);\n\n#ifdef _GNU_SOURCE\nstruct passwd *fgetpwent(FILE *);\nint putpwent(const struct passwd *, FILE *);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/regex.h",
    "content": "#ifndef _REGEX_H\n#define _REGEX_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_regoff_t\n#define __NEED_size_t\n\n#include <bits/alltypes.h>\n\ntypedef struct re_pattern_buffer {\n\tsize_t re_nsub;\n\tvoid *__opaque, *__padding[4];\n\tsize_t __nsub2;\n\tchar __padding2;\n} regex_t;\n\ntypedef struct {\n\tregoff_t rm_so;\n\tregoff_t rm_eo;\n} regmatch_t;\n\n#define REG_EXTENDED    1\n#define REG_ICASE       2\n#define REG_NEWLINE     4\n#define REG_NOSUB       8\n\n#define REG_NOTBOL      1\n#define REG_NOTEOL      2\n\n#define REG_OK          0\n#define REG_NOMATCH     1\n#define REG_BADPAT      2\n#define REG_ECOLLATE    3\n#define REG_ECTYPE      4\n#define REG_EESCAPE     5\n#define REG_ESUBREG     6\n#define REG_EBRACK      7\n#define REG_EPAREN      8\n#define REG_EBRACE      9\n#define REG_BADBR       10\n#define REG_ERANGE      11\n#define REG_ESPACE      12\n#define REG_BADRPT      13\n\n#define REG_ENOSYS      -1\n\nint regcomp(regex_t *__restrict, const char *__restrict, int);\nint regexec(const regex_t *__restrict, const char *__restrict, size_t, regmatch_t *__restrict, int);\nvoid regfree(regex_t *);\n\nsize_t regerror(int, const regex_t *__restrict, char *__restrict, size_t);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/resolv.h",
    "content": "#ifndef _RESOLV_H\n#define _RESOLV_H\n\n#include <stdint.h>\n#include <arpa/nameser.h>\n#include <netinet/in.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define MAXNS\t\t\t3\n#define MAXDFLSRCH\t\t3\n#define MAXDNSRCH\t\t6\n#define LOCALDOMAINPARTS\t2\n\n#define RES_TIMEOUT\t\t5\n#define MAXRESOLVSORT\t\t10\n#define RES_MAXNDOTS\t\t15\n#define RES_MAXRETRANS\t\t30\n#define RES_MAXRETRY\t\t5\n#define RES_DFLRETRY\t\t2\n#define RES_MAXTIME\t\t65535\n\n/* unused; purely for broken apps */\ntypedef struct __res_state {\n\tint retrans;\n\tint retry;\n\tunsigned long options;\n\tint nscount;\n\tstruct sockaddr_in nsaddr_list[MAXNS];\n# define nsaddr\tnsaddr_list[0]\n\tunsigned short id;\n\tchar *dnsrch[MAXDNSRCH+1];\n\tchar defdname[256];\n\tunsigned long pfcode;\n\tunsigned ndots:4;\n\tunsigned nsort:4;\n\tunsigned ipv6_unavail:1;\n\tunsigned unused:23;\n\tstruct {\n\t\tstruct in_addr addr;\n\t\tuint32_t mask;\n\t} sort_list[MAXRESOLVSORT];\n\tvoid *qhook;\n\tvoid *rhook;\n\tint res_h_errno;\n\tint _vcsock;\n\tunsigned _flags;\n\tunion {\n\t\tchar pad[52];\n\t\tstruct {\n\t\t\tuint16_t\t\tnscount;\n\t\t\tuint16_t\t\tnsmap[MAXNS];\n\t\t\tint\t\t\tnssocks[MAXNS];\n\t\t\tuint16_t\t\tnscount6;\n\t\t\tuint16_t\t\tnsinit;\n\t\t\tstruct sockaddr_in6\t*nsaddrs[MAXNS];\n\t\t\tunsigned int\t\t_initstamp[2];\n\t\t} _ext;\n\t} _u;\n} *res_state;\n\n#define\t__RES\t19960801\n\n#ifndef _PATH_RESCONF\n#define _PATH_RESCONF        \"/etc/resolv.conf\"\n#endif\n\nstruct res_sym {\n\tint number;\n\tchar *name;\n\tchar *humanname;\n};\n\n#define\tRES_F_VC\t0x00000001\n#define\tRES_F_CONN\t0x00000002\n#define RES_F_EDNS0ERR\t0x00000004\n\n#define\tRES_EXHAUSTIVE\t0x00000001\n\n#define RES_INIT\t0x00000001\n#define RES_DEBUG\t0x00000002\n#define RES_AAONLY\t0x00000004\n#define RES_USEVC\t0x00000008\n#define RES_PRIMARY\t0x00000010\n#define RES_IGNTC\t0x00000020\n#define RES_RECURSE\t0x00000040\n#define RES_DEFNAMES\t0x00000080\n#define RES_STAYOPEN\t0x00000100\n#define RES_DNSRCH\t0x00000200\n#define\tRES_INSECURE1\t0x00000400\n#define\tRES_INSECURE2\t0x00000800\n#define\tRES_NOALIASES\t0x00001000\n#define\tRES_USE_INET6\t0x00002000\n#define RES_ROTATE\t0x00004000\n#define\tRES_NOCHECKNAME\t0x00008000\n#define\tRES_KEEPTSIG\t0x00010000\n#define\tRES_BLAST\t0x00020000\n#define RES_USEBSTRING\t0x00040000\n#define RES_NOIP6DOTINT\t0x00080000\n#define RES_USE_EDNS0\t0x00100000\n#define RES_SNGLKUP\t0x00200000\n#define RES_SNGLKUPREOP\t0x00400000\n#define RES_USE_DNSSEC\t0x00800000\n\n#define RES_DEFAULT\t(RES_RECURSE|RES_DEFNAMES|RES_DNSRCH|RES_NOIP6DOTINT)\n\n#define RES_PRF_STATS\t0x00000001\n#define RES_PRF_UPDATE\t0x00000002\n#define RES_PRF_CLASS   0x00000004\n#define RES_PRF_CMD\t0x00000008\n#define RES_PRF_QUES\t0x00000010\n#define RES_PRF_ANS\t0x00000020\n#define RES_PRF_AUTH\t0x00000040\n#define RES_PRF_ADD\t0x00000080\n#define RES_PRF_HEAD1\t0x00000100\n#define RES_PRF_HEAD2\t0x00000200\n#define RES_PRF_TTLID\t0x00000400\n#define RES_PRF_HEADX\t0x00000800\n#define RES_PRF_QUERY\t0x00001000\n#define RES_PRF_REPLY\t0x00002000\n#define RES_PRF_INIT\t0x00004000\n\nstruct __res_state *__res_state(void);\n#define _res (*__res_state())\n\nint res_init(void);\nint res_query(const char *, int, int, unsigned char *, int);\nint res_querydomain(const char *, const char *, int, int, unsigned char *, int);\nint res_search(const char *, int, int, unsigned char *, int);\nint res_mkquery(int, const char *, int, int, const unsigned char *, int, const unsigned char*, unsigned char *, int);\nint res_send(const unsigned char *, int, unsigned char *, int);\nint dn_comp(const char *, unsigned char *, int, unsigned char **, unsigned char **);\nint dn_expand(const unsigned char *, const unsigned char *, const unsigned char *, char *, int);\nint dn_skipname(const unsigned char *, const unsigned char *);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sched.h",
    "content": "#ifndef _SCHED_H\n#define _SCHED_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_struct_timespec\n#define __NEED_pid_t\n#define __NEED_time_t\n\n#ifdef _GNU_SOURCE\n#define __NEED_size_t\n#endif\n\n#include <bits/alltypes.h>\n\nstruct sched_param {\n\tint sched_priority;\n\tint __reserved1;\n#if _REDIR_TIME64\n\tlong __reserved2[4];\n#else\n\tstruct {\n\t\ttime_t __reserved1;\n\t\tlong __reserved2;\n\t} __reserved2[2];\n#endif\n\tint __reserved3;\n};\n\nint    sched_get_priority_max(int);\nint    sched_get_priority_min(int);\nint    sched_getparam(pid_t, struct sched_param *);\nint    sched_getscheduler(pid_t);\nint    sched_rr_get_interval(pid_t, struct timespec *);\nint    sched_setparam(pid_t, const struct sched_param *);\nint    sched_setscheduler(pid_t, int, const struct sched_param *);\nint     sched_yield(void);\n\n#define SCHED_OTHER 0\n#define SCHED_FIFO 1\n#define SCHED_RR 2\n#define SCHED_BATCH 3\n#define SCHED_IDLE 5\n#define SCHED_DEADLINE 6\n#define SCHED_RESET_ON_FORK 0x40000000\n\n#ifdef _GNU_SOURCE\n#define CSIGNAL\t\t0x000000ff\n#define CLONE_NEWTIME\t0x00000080\n#define CLONE_VM\t0x00000100\n#define CLONE_FS\t0x00000200\n#define CLONE_FILES\t0x00000400\n#define CLONE_SIGHAND\t0x00000800\n#define CLONE_PIDFD\t0x00001000\n#define CLONE_PTRACE\t0x00002000\n#define CLONE_VFORK\t0x00004000\n#define CLONE_PARENT\t0x00008000\n#define CLONE_THREAD\t0x00010000\n#define CLONE_NEWNS\t0x00020000\n#define CLONE_SYSVSEM\t0x00040000\n#define CLONE_SETTLS\t0x00080000\n#define CLONE_PARENT_SETTID\t0x00100000\n#define CLONE_CHILD_CLEARTID\t0x00200000\n#define CLONE_DETACHED\t0x00400000\n#define CLONE_UNTRACED\t0x00800000\n#define CLONE_CHILD_SETTID\t0x01000000\n#define CLONE_NEWCGROUP\t0x02000000\n#define CLONE_NEWUTS\t0x04000000\n#define CLONE_NEWIPC\t0x08000000\n#define CLONE_NEWUSER\t0x10000000\n#define CLONE_NEWPID\t0x20000000\n#define CLONE_NEWNET\t0x40000000\n#define CLONE_IO\t0x80000000\nint clone (int (*)(void *), void *, int, void *, ...);\nint unshare(int);\nint setns(int, int);\n\nvoid *memcpy(void *__restrict, const void *__restrict, size_t);\nint memcmp(const void *, const void *, size_t);\nvoid *memset (void *, int, size_t);\nvoid *calloc(size_t, size_t);\nvoid free(void *);\n\ntypedef struct cpu_set_t { unsigned long __bits[128/sizeof(long)]; } cpu_set_t;\nint __sched_cpucount(size_t, const cpu_set_t *);\nint sched_getcpu(void);\nint sched_getaffinity(pid_t, size_t, cpu_set_t *);\nint sched_setaffinity(pid_t, size_t, const cpu_set_t *);\n\n#define __CPU_op_S(i, size, set, op) ( (i)/8U >= (size) ? 0 : \\\n\t(((unsigned long *)(set))[(i)/8/sizeof(long)] op (1UL<<((i)%(8*sizeof(long))))) )\n\n#define CPU_SET_S(i, size, set) __CPU_op_S(i, size, set, |=)\n#define CPU_CLR_S(i, size, set) __CPU_op_S(i, size, set, &=~)\n#define CPU_ISSET_S(i, size, set) __CPU_op_S(i, size, set, &)\n\n#define __CPU_op_func_S(func, op) \\\nstatic __inline void __CPU_##func##_S(size_t __size, cpu_set_t *__dest, \\\n\tconst cpu_set_t *__src1, const cpu_set_t *__src2) \\\n{ \\\n\tsize_t __i; \\\n\tfor (__i=0; __i<__size/sizeof(long); __i++) \\\n\t\t((unsigned long *)__dest)[__i] = ((unsigned long *)__src1)[__i] \\\n\t\t\top ((unsigned long *)__src2)[__i] ; \\\n}\n\n__CPU_op_func_S(AND, &)\n__CPU_op_func_S(OR, |)\n__CPU_op_func_S(XOR, ^)\n\n#define CPU_AND_S(a,b,c,d) __CPU_AND_S(a,b,c,d)\n#define CPU_OR_S(a,b,c,d) __CPU_OR_S(a,b,c,d)\n#define CPU_XOR_S(a,b,c,d) __CPU_XOR_S(a,b,c,d)\n\n#define CPU_COUNT_S(size,set) __sched_cpucount(size,set)\n#define CPU_ZERO_S(size,set) memset(set,0,size)\n#define CPU_EQUAL_S(size,set1,set2) (!memcmp(set1,set2,size))\n\n#define CPU_ALLOC_SIZE(n) (sizeof(long) * ( (n)/(8*sizeof(long)) \\\n\t+ ((n)%(8*sizeof(long)) + 8*sizeof(long)-1)/(8*sizeof(long)) ) )\n#define CPU_ALLOC(n) ((cpu_set_t *)calloc(1,CPU_ALLOC_SIZE(n)))\n#define CPU_FREE(set) free(set)\n\n#define CPU_SETSIZE 128\n\n#define CPU_SET(i, set) CPU_SET_S(i,sizeof(cpu_set_t),set)\n#define CPU_CLR(i, set) CPU_CLR_S(i,sizeof(cpu_set_t),set)\n#define CPU_ISSET(i, set) CPU_ISSET_S(i,sizeof(cpu_set_t),set)\n#define CPU_AND(d,s1,s2) CPU_AND_S(sizeof(cpu_set_t),d,s1,s2)\n#define CPU_OR(d,s1,s2) CPU_OR_S(sizeof(cpu_set_t),d,s1,s2)\n#define CPU_XOR(d,s1,s2) CPU_XOR_S(sizeof(cpu_set_t),d,s1,s2)\n#define CPU_COUNT(set) CPU_COUNT_S(sizeof(cpu_set_t),set)\n#define CPU_ZERO(set) CPU_ZERO_S(sizeof(cpu_set_t),set)\n#define CPU_EQUAL(s1,s2) CPU_EQUAL_S(sizeof(cpu_set_t),s1,s2)\n\n#endif\n\n#if _REDIR_TIME64\n__REDIR(sched_rr_get_interval, __sched_rr_get_interval_time64);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/scsi/scsi.h",
    "content": "#ifndef _SCSI_SCSI_H\n#define _SCSI_SCSI_H\n\n#define TEST_UNIT_READY 0x00\n#define REZERO_UNIT 0x01\n#define REQUEST_SENSE 0x03\n#define FORMAT_UNIT 0x04\n#define READ_BLOCK_LIMITS 0x05\n#define REASSIGN_BLOCKS 0x07\n#define READ_6 0x08\n#define WRITE_6 0x0a\n#define SEEK_6 0x0b\n#define READ_REVERSE 0x0f\n#define WRITE_FILEMARKS 0x10\n#define SPACE 0x11\n#define INQUIRY 0x12\n#define RECOVER_BUFFERED_DATA 0x14\n#define MODE_SELECT 0x15\n#define RESERVE 0x16\n#define RELEASE 0x17\n#define COPY 0x18\n#define ERASE 0x19\n#define MODE_SENSE 0x1a\n#define START_STOP 0x1b\n#define RECEIVE_DIAGNOSTIC 0x1c\n#define SEND_DIAGNOSTIC 0x1d\n#define ALLOW_MEDIUM_REMOVAL 0x1e\n#define SET_WINDOW 0x24\n#define READ_CAPACITY 0x25\n#define READ_10 0x28\n#define WRITE_10 0x2a\n#define SEEK_10 0x2b\n#define WRITE_VERIFY 0x2e\n#define VERIFY 0x2f\n#define SEARCH_HIGH 0x30\n#define SEARCH_EQUAL 0x31\n#define SEARCH_LOW 0x32\n#define SET_LIMITS 0x33\n#define PRE_FETCH 0x34\n#define READ_POSITION 0x34\n#define SYNCHRONIZE_CACHE 0x35\n#define LOCK_UNLOCK_CACHE 0x36\n#define READ_DEFECT_DATA 0x37\n#define MEDIUM_SCAN 0x38\n#define COMPARE 0x39\n#define COPY_VERIFY 0x3a\n#define WRITE_BUFFER 0x3b\n#define READ_BUFFER 0x3c\n#define UPDATE_BLOCK 0x3d\n#define READ_LONG 0x3e\n#define WRITE_LONG 0x3f\n#define CHANGE_DEFINITION 0x40\n#define WRITE_SAME 0x41\n#define READ_TOC 0x43\n#define LOG_SELECT 0x4c\n#define LOG_SENSE 0x4d\n#define MODE_SELECT_10 0x55\n#define RESERVE_10 0x56\n#define RELEASE_10 0x57\n#define MODE_SENSE_10 0x5a\n#define PERSISTENT_RESERVE_IN 0x5e\n#define PERSISTENT_RESERVE_OUT 0x5f\n#define MOVE_MEDIUM 0xa5\n#define READ_12 0xa8\n#define WRITE_12 0xaa\n#define WRITE_VERIFY_12 0xae\n#define SEARCH_HIGH_12 0xb0\n#define SEARCH_EQUAL_12 0xb1\n#define SEARCH_LOW_12 0xb2\n#define READ_ELEMENT_STATUS 0xb8\n#define SEND_VOLUME_TAG 0xb6\n#define WRITE_LONG_2 0xea\n#define GOOD 0x00\n#define CHECK_CONDITION 0x01\n#define CONDITION_GOOD 0x02\n#define BUSY 0x04\n#define INTERMEDIATE_GOOD 0x08\n#define INTERMEDIATE_C_GOOD 0x0a\n#define RESERVATION_CONFLICT 0x0c\n#define COMMAND_TERMINATED 0x11\n#define QUEUE_FULL 0x14\n#define STATUS_MASK 0x3e\n#define NO_SENSE 0x00\n#define RECOVERED_ERROR 0x01\n#define NOT_READY 0x02\n#define MEDIUM_ERROR 0x03\n#define HARDWARE_ERROR 0x04\n#define ILLEGAL_REQUEST 0x05\n#define UNIT_ATTENTION 0x06\n#define DATA_PROTECT 0x07\n#define BLANK_CHECK 0x08\n#define COPY_ABORTED 0x0a\n#define ABORTED_COMMAND 0x0b\n#define VOLUME_OVERFLOW 0x0d\n#define MISCOMPARE 0x0e\n#define TYPE_DISK 0x00\n#define TYPE_TAPE 0x01\n#define TYPE_PROCESSOR 0x03\n#define TYPE_WORM 0x04\n#define TYPE_ROM 0x05\n#define TYPE_SCANNER 0x06\n#define TYPE_MOD 0x07\n#define TYPE_MEDIUM_CHANGER 0x08\n#define TYPE_ENCLOSURE 0x0d\n#define TYPE_NO_LUN 0x7f\n#define COMMAND_COMPLETE 0x00\n#define EXTENDED_MESSAGE 0x01\n#define EXTENDED_MODIFY_DATA_POINTER 0x00\n#define EXTENDED_SDTR 0x01\n#define EXTENDED_EXTENDED_IDENTIFY 0x02\n#define EXTENDED_WDTR 0x03\n#define SAVE_POINTERS 0x02\n#define RESTORE_POINTERS 0x03\n#define DISCONNECT 0x04\n#define INITIATOR_ERROR 0x05\n#define ABORT 0x06\n#define MESSAGE_REJECT 0x07\n#define NOP 0x08\n#define MSG_PARITY_ERROR 0x09\n#define LINKED_CMD_COMPLETE 0x0a\n#define LINKED_FLG_CMD_COMPLETE 0x0b\n#define BUS_DEVICE_RESET 0x0c\n#define INITIATE_RECOVERY 0x0f\n#define RELEASE_RECOVERY 0x10\n#define SIMPLE_QUEUE_TAG 0x20\n#define HEAD_OF_QUEUE_TAG 0x21\n#define ORDERED_QUEUE_TAG 0x22\n#define SCSI_IOCTL_GET_IDLUN 0x5382\n#define SCSI_IOCTL_TAGGED_ENABLE 0x5383\n#define SCSI_IOCTL_TAGGED_DISABLE 0x5384\n#define SCSI_IOCTL_PROBE_HOST 0x5385\n#define SCSI_IOCTL_GET_BUS_NUMBER 0x5386\n\nstruct ccs_modesel_head {\n\tunsigned char _r1;\n\tunsigned char medium;\n\tunsigned char _r2;\n\tunsigned char block_desc_length;\n\tunsigned char density;\n\tunsigned char number_blocks_hi;\n\tunsigned char number_blocks_med;\n\tunsigned char number_blocks_lo;\n\tunsigned char _r3;\n\tunsigned char block_length_hi;\n\tunsigned char block_length_med;\n\tunsigned char block_length_lo;\n};\n\n#endif\n\n"
  },
  {
    "path": "user.libc/include/scsi/scsi_ioctl.h",
    "content": "#ifndef _SCSI_IOCTL_H\n#define _SCSI_IOCTL_H\n#define SCSI_IOCTL_SEND_COMMAND 1\n#define SCSI_IOCTL_TEST_UNIT_READY 2\n#define SCSI_IOCTL_BENCHMARK_COMMAND 3\n#define SCSI_IOCTL_SYNC 4\n#define SCSI_IOCTL_START_UNIT 5\n#define SCSI_IOCTL_STOP_UNIT 6\n#define SCSI_IOCTL_DOORLOCK 0x5380\n#define SCSI_IOCTL_DOORUNLOCK 0x5381\n#endif\n"
  },
  {
    "path": "user.libc/include/scsi/sg.h",
    "content": "#ifndef _SCSI_SG_H\n#define _SCSI_SG_H\n\n#define SG_DXFER_NONE -1\n#define SG_DXFER_TO_DEV -2\n#define SG_DXFER_FROM_DEV -3\n#define SG_DXFER_TO_FROM_DEV -4\n#define SG_FLAG_DIRECT_IO 1\n#define SG_FLAG_LUN_INHIBIT 2\n#define SG_FLAG_NO_DXFER 0x10000\n#define SG_INFO_OK_MASK 0x1\n#define SG_INFO_OK 0x0\n#define SG_INFO_CHECK 0x1\n#define SG_INFO_DIRECT_IO_MASK 0x6\n#define SG_INFO_INDIRECT_IO 0x0\n#define SG_INFO_DIRECT_IO 0x2\n#define SG_INFO_MIXED_IO 0x4\n#define SG_EMULATED_HOST 0x2203\n#define SG_SET_TRANSFORM 0x2204\n#define SG_GET_TRANSFORM 0x2205\n#define SG_SET_RESERVED_SIZE 0x2275\n#define SG_GET_RESERVED_SIZE 0x2272\n#define SG_GET_SCSI_ID 0x2276\n#define SG_SET_FORCE_LOW_DMA 0x2279\n#define SG_GET_LOW_DMA 0x227a\n#define SG_SET_FORCE_PACK_ID 0x227b\n#define SG_GET_PACK_ID 0x227c\n#define SG_GET_NUM_WAITING 0x227d\n#define SG_GET_SG_TABLESIZE 0x227F\n#define SG_GET_VERSION_NUM 0x2282\n#define SG_SCSI_RESET 0x2284\n#define SG_SCSI_RESET_NOTHING 0\n#define SG_SCSI_RESET_DEVICE 1\n#define SG_SCSI_RESET_BUS 2\n#define SG_SCSI_RESET_HOST 3\n#define SG_IO 0x2285\n#define SG_GET_REQUEST_TABLE 0x2286\n#define SG_SET_KEEP_ORPHAN 0x2287\n#define SG_GET_KEEP_ORPHAN 0x2288\n#define SG_SCATTER_SZ (8 * 4096)\n#define SG_DEFAULT_RETRIES 1\n#define SG_DEF_FORCE_LOW_DMA 0\n#define SG_DEF_FORCE_PACK_ID 0\n#define SG_DEF_KEEP_ORPHAN 0\n#define SG_DEF_RESERVED_SIZE SG_SCATTER_SZ\n#define SG_MAX_QUEUE 16\n#define SG_BIG_BUFF SG_DEF_RESERVED_SIZE\n#define SG_MAX_SENSE 16\n#define SG_SET_TIMEOUT 0x2201\n#define SG_GET_TIMEOUT 0x2202\n#define SG_GET_COMMAND_Q 0x2270\n#define SG_SET_COMMAND_Q 0x2271\n#define SG_SET_DEBUG 0x227e\n#define SG_NEXT_CMD_LEN 0x2283\n#define SG_DEFAULT_TIMEOUT (60*100) /* 60*HZ */\n#define SG_DEF_COMMAND_Q 0\n#define SG_DEF_UNDERRUN_FLAG 0\n\ntypedef struct sg_iovec {\n\tvoid *iov_base;\n\tunsigned long iov_len;\n} sg_iovec_t;\n\ntypedef struct sg_io_hdr { \n\tint interface_id; \n\tint dxfer_direction; \n\tunsigned char cmd_len;\n\tunsigned char mx_sb_len;\n\tunsigned short iovec_count;\n\tunsigned dxfer_len;\n\tvoid *dxferp;\n\tunsigned char *cmdp;\n\tunsigned char *sbp;\n\tunsigned timeout;\n\tunsigned flags;\n\tint pack_id;\n\tvoid *usr_ptr;\n\tunsigned char status;\n\tunsigned char masked_status;\n\tunsigned char msg_status;\n\tunsigned char sb_len_wr;\n\tunsigned short host_status;\n\tunsigned short driver_status;\n\tint resid; \n\tunsigned int duration;\n\tunsigned int info;\n} sg_io_hdr_t;\n\nstruct sg_scsi_id {\n\tint host_no;\n\tint channel;\n\tint scsi_id;\n\tint lun;\n\tint scsi_type;\n\tshort h_cmd_per_lun;\n\tshort d_queue_depth;\n\tint unused[2];\n};\n\ntypedef struct sg_req_info {\n\tchar req_state;\n\tchar orphan;\n\tchar sg_io_owned;\n\tchar problem;\n\tint pack_id;\n\tvoid *usr_ptr;\n\tunsigned duration; \n\tint unused; \n} sg_req_info_t;\n\ntypedef struct sg_io_hdr Sg_io_hdr;\ntypedef struct sg_io_vec Sg_io_vec;\ntypedef struct sg_scsi_id Sg_scsi_id;\ntypedef struct sg_req_info Sg_req_info;\n\nstruct sg_header {\n\tint pack_len;\n\tint reply_len;\n\tint pack_id;\n\tint result;\n\tunsigned twelve_byte:1;\n\tunsigned target_status:5;\n\tunsigned host_status:8;\n\tunsigned driver_status:8;\n\tunsigned other_flags:10;\n\tunsigned char sense_buffer[SG_MAX_SENSE];\n};\n\n#endif\n"
  },
  {
    "path": "user.libc/include/search.h",
    "content": "#ifndef _SEARCH_H\n#define _SEARCH_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_size_t\n#include <bits/alltypes.h>\n\ntypedef enum { FIND, ENTER } ACTION;\ntypedef enum { preorder, postorder, endorder, leaf } VISIT;\n\ntypedef struct entry {\n\tchar *key;\n\tvoid *data;\n} ENTRY;\n\nint hcreate(size_t);\nvoid hdestroy(void);\nENTRY *hsearch(ENTRY, ACTION);\n\n#ifdef _GNU_SOURCE\nstruct hsearch_data {\n\tstruct __tab *__tab;\n\tunsigned int __unused1;\n\tunsigned int __unused2;\n};\n\nint hcreate_r(size_t, struct hsearch_data *);\nvoid hdestroy_r(struct hsearch_data *);\nint hsearch_r(ENTRY, ACTION, ENTRY **, struct hsearch_data *);\n#endif\n\nvoid insque(void *, void *);\nvoid remque(void *);\n\nvoid *lsearch(const void *, void *, size_t *, size_t,\n\tint (*)(const void *, const void *));\nvoid *lfind(const void *, const void *, size_t *, size_t,\n\tint (*)(const void *, const void *));\n\nvoid *tdelete(const void *__restrict, void **__restrict, int(*)(const void *, const void *));\nvoid *tfind(const void *, void *const *, int(*)(const void *, const void *));\nvoid *tsearch(const void *, void **, int (*)(const void *, const void *));\nvoid twalk(const void *, void (*)(const void *, VISIT, int));\n\n#ifdef _GNU_SOURCE\nstruct qelem {\n\tstruct qelem *q_forw, *q_back;\n\tchar q_data[1];\n};\n\nvoid tdestroy(void *, void (*)(void *));\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/semaphore.h",
    "content": "#ifndef _SEMAPHORE_H\n#define _SEMAPHORE_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_time_t\n#define __NEED_struct_timespec\n#include <bits/alltypes.h>\n\n#include <fcntl.h>\n\n#define SEM_FAILED ((sem_t *)0)\n\ntypedef struct {\n\tvolatile int __val[4*sizeof(long)/sizeof(int)];\n} sem_t;\n\nint    sem_close(sem_t *);\nint    sem_destroy(sem_t *);\nint    sem_getvalue(sem_t *__restrict, int *__restrict);\nint    sem_init(sem_t *, int, unsigned);\nsem_t *sem_open(const char *, int, ...);\nint    sem_post(sem_t *);\nint    sem_timedwait(sem_t *__restrict, const struct timespec *__restrict);\nint    sem_trywait(sem_t *);\nint    sem_unlink(const char *);\nint    sem_wait(sem_t *);\n\n#if _REDIR_TIME64\n__REDIR(sem_timedwait, __sem_timedwait_time64);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/setjmp.h",
    "content": "#ifndef\t_SETJMP_H\n#define\t_SETJMP_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#include <bits/setjmp.h>\n\ntypedef struct __jmp_buf_tag {\n\t__jmp_buf __jb;\n\tunsigned long __fl;\n\tunsigned long __ss[128/sizeof(long)];\n} jmp_buf[1];\n\n#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \\\n || defined(_BSD_SOURCE)\ntypedef jmp_buf sigjmp_buf;\nint sigsetjmp (sigjmp_buf, int);\n_Noreturn void siglongjmp (sigjmp_buf, int);\n#endif\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \\\n || defined(_BSD_SOURCE)\nint _setjmp (jmp_buf);\n_Noreturn void _longjmp (jmp_buf, int);\n#endif\n\nint setjmp (jmp_buf);\n_Noreturn void longjmp (jmp_buf, int);\n\n#define setjmp setjmp\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/shadow.h",
    "content": "#ifndef _SHADOW_H\n#define _SHADOW_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define\t__NEED_FILE\n#define __NEED_size_t\n\n#include <bits/alltypes.h>\n\n#define\tSHADOW \"/etc/shadow\"\n\nstruct spwd {\n\tchar *sp_namp;\n\tchar *sp_pwdp;\n\tlong sp_lstchg;\n\tlong sp_min;\n\tlong sp_max;\n\tlong sp_warn;\n\tlong sp_inact;\n\tlong sp_expire;\n\tunsigned long sp_flag;\n};\n\nvoid setspent(void);\nvoid endspent(void);\nstruct spwd *getspent(void);\nstruct spwd *fgetspent(FILE *);\nstruct spwd *sgetspent(const char *);\nint putspent(const struct spwd *, FILE *);\n\nstruct spwd *getspnam(const char *);\nint getspnam_r(const char *, struct spwd *, char *, size_t, struct spwd **);\n\nint lckpwdf(void);\nint ulckpwdf(void);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/signal.h",
    "content": "#ifndef _SIGNAL_H\n#define _SIGNAL_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \\\n || defined(_BSD_SOURCE)\n\n#ifdef _GNU_SOURCE\n#define __ucontext ucontext\n#endif\n\n#define __NEED_size_t\n#define __NEED_pid_t\n#define __NEED_uid_t\n#define __NEED_struct_timespec\n#define __NEED_pthread_t\n#define __NEED_pthread_attr_t\n#define __NEED_time_t\n#define __NEED_clock_t\n#define __NEED_sigset_t\n\n#include <bits/alltypes.h>\n\n#define SIG_BLOCK     0\n#define SIG_UNBLOCK   1\n#define SIG_SETMASK   2\n\n#define SI_ASYNCNL (-60)\n#define SI_TKILL (-6)\n#define SI_SIGIO (-5)\n#define SI_ASYNCIO (-4)\n#define SI_MESGQ (-3)\n#define SI_TIMER (-2)\n#define SI_QUEUE (-1)\n#define SI_USER 0\n#define SI_KERNEL 128\n\ntypedef struct sigaltstack stack_t;\n\n#endif\n\n#include <bits/signal.h>\n\n#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \\\n || defined(_BSD_SOURCE)\n\n#define SIG_HOLD ((void (*)(int)) 2)\n\n#define FPE_INTDIV 1\n#define FPE_INTOVF 2\n#define FPE_FLTDIV 3\n#define FPE_FLTOVF 4\n#define FPE_FLTUND 5\n#define FPE_FLTRES 6\n#define FPE_FLTINV 7\n#define FPE_FLTSUB 8\n\n#define ILL_ILLOPC 1\n#define ILL_ILLOPN 2\n#define ILL_ILLADR 3\n#define ILL_ILLTRP 4\n#define ILL_PRVOPC 5\n#define ILL_PRVREG 6\n#define ILL_COPROC 7\n#define ILL_BADSTK 8\n\n#define SEGV_MAPERR 1\n#define SEGV_ACCERR 2\n#define SEGV_BNDERR 3\n#define SEGV_PKUERR 4\n\n#define BUS_ADRALN 1\n#define BUS_ADRERR 2\n#define BUS_OBJERR 3\n#define BUS_MCEERR_AR 4\n#define BUS_MCEERR_AO 5\n\n#define CLD_EXITED 1\n#define CLD_KILLED 2\n#define CLD_DUMPED 3\n#define CLD_TRAPPED 4\n#define CLD_STOPPED 5\n#define CLD_CONTINUED 6\n\nunion sigval {\n\tint sival_int;\n\tvoid *sival_ptr;\n};\n\ntypedef struct {\n#ifdef __SI_SWAP_ERRNO_CODE\n\tint si_signo, si_code, si_errno;\n#else\n\tint si_signo, si_errno, si_code;\n#endif\n\tunion {\n\t\tchar __pad[128 - 2*sizeof(int) - sizeof(long)];\n\t\tstruct {\n\t\t\tunion {\n\t\t\t\tstruct {\n\t\t\t\t\tpid_t si_pid;\n\t\t\t\t\tuid_t si_uid;\n\t\t\t\t} __piduid;\n\t\t\t\tstruct {\n\t\t\t\t\tint si_timerid;\n\t\t\t\t\tint si_overrun;\n\t\t\t\t} __timer;\n\t\t\t} __first;\n\t\t\tunion {\n\t\t\t\tunion sigval si_value;\n\t\t\t\tstruct {\n\t\t\t\t\tint si_status;\n\t\t\t\t\tclock_t si_utime, si_stime;\n\t\t\t\t} __sigchld;\n\t\t\t} __second;\n\t\t} __si_common;\n\t\tstruct {\n\t\t\tvoid *si_addr;\n\t\t\tshort si_addr_lsb;\n\t\t\tunion {\n\t\t\t\tstruct {\n\t\t\t\t\tvoid *si_lower;\n\t\t\t\t\tvoid *si_upper;\n\t\t\t\t} __addr_bnd;\n\t\t\t\tunsigned si_pkey;\n\t\t\t} __first;\n\t\t} __sigfault;\n\t\tstruct {\n\t\t\tlong si_band;\n\t\t\tint si_fd;\n\t\t} __sigpoll;\n\t\tstruct {\n\t\t\tvoid *si_call_addr;\n\t\t\tint si_syscall;\n\t\t\tunsigned si_arch;\n\t\t} __sigsys;\n\t} __si_fields;\n} siginfo_t;\n#define si_pid     __si_fields.__si_common.__first.__piduid.si_pid\n#define si_uid     __si_fields.__si_common.__first.__piduid.si_uid\n#define si_status  __si_fields.__si_common.__second.__sigchld.si_status\n#define si_utime   __si_fields.__si_common.__second.__sigchld.si_utime\n#define si_stime   __si_fields.__si_common.__second.__sigchld.si_stime\n#define si_value   __si_fields.__si_common.__second.si_value\n#define si_addr    __si_fields.__sigfault.si_addr\n#define si_addr_lsb __si_fields.__sigfault.si_addr_lsb\n#define si_lower   __si_fields.__sigfault.__first.__addr_bnd.si_lower\n#define si_upper   __si_fields.__sigfault.__first.__addr_bnd.si_upper\n#define si_pkey    __si_fields.__sigfault.__first.si_pkey\n#define si_band    __si_fields.__sigpoll.si_band\n#define si_fd      __si_fields.__sigpoll.si_fd\n#define si_timerid __si_fields.__si_common.__first.__timer.si_timerid\n#define si_overrun __si_fields.__si_common.__first.__timer.si_overrun\n#define si_ptr     si_value.sival_ptr\n#define si_int     si_value.sival_int\n#define si_call_addr __si_fields.__sigsys.si_call_addr\n#define si_syscall __si_fields.__sigsys.si_syscall\n#define si_arch    __si_fields.__sigsys.si_arch\n\nstruct sigaction {\n\tunion {\n\t\tvoid (*sa_handler)(int);\n\t\tvoid (*sa_sigaction)(int, siginfo_t *, void *);\n\t} __sa_handler;\n\tsigset_t sa_mask;\n\tint sa_flags;\n\tvoid (*sa_restorer)(void);\n};\n#define sa_handler   __sa_handler.sa_handler\n#define sa_sigaction __sa_handler.sa_sigaction\n\nstruct sigevent {\n\tunion sigval sigev_value;\n\tint sigev_signo;\n\tint sigev_notify;\n\tunion {\n\t\tchar __pad[64 - 2*sizeof(int) - sizeof(union sigval)];\n\t\tpid_t sigev_notify_thread_id;\n\t\tstruct {\n\t\t\tvoid (*sigev_notify_function)(union sigval);\n\t\t\tpthread_attr_t *sigev_notify_attributes;\n\t\t} __sev_thread;\n\t} __sev_fields;\n};\n\n#define sigev_notify_thread_id __sev_fields.sigev_notify_thread_id\n#define sigev_notify_function __sev_fields.__sev_thread.sigev_notify_function\n#define sigev_notify_attributes __sev_fields.__sev_thread.sigev_notify_attributes\n\n#define SIGEV_SIGNAL 0\n#define SIGEV_NONE 1\n#define SIGEV_THREAD 2\n#define SIGEV_THREAD_ID 4\n\nint __libc_current_sigrtmin(void);\nint __libc_current_sigrtmax(void);\n\n#define SIGRTMIN  (__libc_current_sigrtmin())\n#define SIGRTMAX  (__libc_current_sigrtmax())\n\nint kill(pid_t, int);\n\nint sigemptyset(sigset_t *);\nint sigfillset(sigset_t *);\nint sigaddset(sigset_t *, int);\nint sigdelset(sigset_t *, int);\nint sigismember(const sigset_t *, int);\n\nint sigprocmask(int, const sigset_t *__restrict, sigset_t *__restrict);\nint sigsuspend(const sigset_t *);\nint sigaction(int, const struct sigaction *__restrict, struct sigaction *__restrict);\nint sigpending(sigset_t *);\nint sigwait(const sigset_t *__restrict, int *__restrict);\nint sigwaitinfo(const sigset_t *__restrict, siginfo_t *__restrict);\nint sigtimedwait(const sigset_t *__restrict, siginfo_t *__restrict, const struct timespec *__restrict);\nint sigqueue(pid_t, int, union sigval);\n\nint pthread_sigmask(int, const sigset_t *__restrict, sigset_t *__restrict);\nint pthread_kill(pthread_t, int);\n\nvoid psiginfo(const siginfo_t *, const char *);\nvoid psignal(int, const char *);\n\n#endif\n\n#if defined(_XOPEN_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE)\nint killpg(pid_t, int);\nint sigaltstack(const stack_t *__restrict, stack_t *__restrict);\nint sighold(int);\nint sigignore(int);\nint siginterrupt(int, int);\nint sigpause(int);\nint sigrelse(int);\nvoid (*sigset(int, void (*)(int)))(int);\n#define TRAP_BRKPT 1\n#define TRAP_TRACE 2\n#define TRAP_BRANCH 3\n#define TRAP_HWBKPT 4\n#define TRAP_UNK 5\n#define POLL_IN 1\n#define POLL_OUT 2\n#define POLL_MSG 3\n#define POLL_ERR 4\n#define POLL_PRI 5\n#define POLL_HUP 6\n#define SS_ONSTACK    1\n#define SS_DISABLE    2\n#define SS_AUTODISARM (1U << 31)\n#define SS_FLAG_BITS SS_AUTODISARM\n#endif\n\n#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)\n#define NSIG _NSIG\ntypedef void (*sig_t)(int);\n#endif\n\n#ifdef _GNU_SOURCE\ntypedef void (*sighandler_t)(int);\nvoid (*bsd_signal(int, void (*)(int)))(int);\nint sigisemptyset(const sigset_t *);\nint sigorset (sigset_t *, const sigset_t *, const sigset_t *);\nint sigandset(sigset_t *, const sigset_t *, const sigset_t *);\n\n#define SA_NOMASK SA_NODEFER\n#define SA_ONESHOT SA_RESETHAND\n#endif\n\n#define SIG_ERR  ((void (*)(int))-1)\n#define SIG_DFL  ((void (*)(int)) 0)\n#define SIG_IGN  ((void (*)(int)) 1)\n\ntypedef int sig_atomic_t;\n\nvoid (*signal(int, void (*)(int)))(int);\nint raise(int);\n\n#if _REDIR_TIME64\n#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \\\n || defined(_BSD_SOURCE)\n__REDIR(sigtimedwait, __sigtimedwait_time64);\n#endif\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/spawn.h",
    "content": "#ifndef _SPAWN_H\n#define _SPAWN_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_mode_t\n#define __NEED_pid_t\n#define __NEED_sigset_t\n\n#include <bits/alltypes.h>\n\nstruct sched_param;\n\n#define POSIX_SPAWN_RESETIDS 1\n#define POSIX_SPAWN_SETPGROUP 2\n#define POSIX_SPAWN_SETSIGDEF 4\n#define POSIX_SPAWN_SETSIGMASK 8\n#define POSIX_SPAWN_SETSCHEDPARAM 16\n#define POSIX_SPAWN_SETSCHEDULER 32\n#define POSIX_SPAWN_USEVFORK 64\n#define POSIX_SPAWN_SETSID 128\n\ntypedef struct {\n\tint __flags;\n\tpid_t __pgrp;\n\tsigset_t __def, __mask;\n\tint __prio, __pol;\n\tvoid *__fn;\n\tchar __pad[64-sizeof(void *)];\n} posix_spawnattr_t;\n\ntypedef struct {\n\tint __pad0[2];\n\tvoid *__actions;\n\tint __pad[16];\n} posix_spawn_file_actions_t;\n\nint posix_spawn(pid_t *__restrict, const char *__restrict, const posix_spawn_file_actions_t *,\n\tconst posix_spawnattr_t *__restrict, char *const *__restrict, char *const *__restrict);\nint posix_spawnp(pid_t *__restrict, const char *__restrict, const posix_spawn_file_actions_t *,\n\tconst posix_spawnattr_t *__restrict, char *const *__restrict, char *const *__restrict);\n\nint posix_spawnattr_init(posix_spawnattr_t *);\nint posix_spawnattr_destroy(posix_spawnattr_t *);\n\nint posix_spawnattr_setflags(posix_spawnattr_t *, short);\nint posix_spawnattr_getflags(const posix_spawnattr_t *__restrict, short *__restrict);\n\nint posix_spawnattr_setpgroup(posix_spawnattr_t *, pid_t);\nint posix_spawnattr_getpgroup(const posix_spawnattr_t *__restrict, pid_t *__restrict);\n\nint posix_spawnattr_setsigmask(posix_spawnattr_t *__restrict, const sigset_t *__restrict);\nint posix_spawnattr_getsigmask(const posix_spawnattr_t *__restrict, sigset_t *__restrict);\n\nint posix_spawnattr_setsigdefault(posix_spawnattr_t *__restrict, const sigset_t *__restrict);\nint posix_spawnattr_getsigdefault(const posix_spawnattr_t *__restrict, sigset_t *__restrict);\n\nint posix_spawnattr_setschedparam(posix_spawnattr_t *__restrict, const struct sched_param *__restrict);\nint posix_spawnattr_getschedparam(const posix_spawnattr_t *__restrict, struct sched_param *__restrict);\nint posix_spawnattr_setschedpolicy(posix_spawnattr_t *, int);\nint posix_spawnattr_getschedpolicy(const posix_spawnattr_t *__restrict, int *__restrict);\n\nint posix_spawn_file_actions_init(posix_spawn_file_actions_t *);\nint posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *);\n\nint posix_spawn_file_actions_addopen(posix_spawn_file_actions_t *__restrict, int, const char *__restrict, int, mode_t);\nint posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *, int);\nint posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *, int, int);\n\n#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)\nint posix_spawn_file_actions_addchdir_np(posix_spawn_file_actions_t *__restrict, const char *__restrict);\nint posix_spawn_file_actions_addfchdir_np(posix_spawn_file_actions_t *, int);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/stdalign.h",
    "content": "#ifndef _STDALIGN_H\n#define _STDALIGN_H\n\n#ifndef __cplusplus\n\n/* this whole header only works in C11 or with compiler extensions */\n#if __STDC_VERSION__ < 201112L && defined( __GNUC__)\n#define _Alignas(t) __attribute__((__aligned__(t)))\n#define _Alignof(t) __alignof__(t)\n#endif\n\n#define alignas _Alignas\n#define alignof _Alignof\n\n#endif\n\n#define __alignas_is_defined 1\n#define __alignof_is_defined 1\n\n#endif\n"
  },
  {
    "path": "user.libc/include/stdarg.h",
    "content": "#ifndef _STDARG_H\n#define _STDARG_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define __NEED_va_list\n\n#include <bits/alltypes.h>\n\n#define va_start(v,l)   __builtin_va_start(v,l)\n#define va_end(v)       __builtin_va_end(v)\n#define va_arg(v,l)     __builtin_va_arg(v,l)\n#define va_copy(d,s)    __builtin_va_copy(d,s)\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/stdbool.h",
    "content": "#ifndef _STDBOOL_H\n#define _STDBOOL_H\n\n#ifndef __cplusplus\n\n#define true 1\n#define false 0\n#define bool _Bool\n\n#endif\n\n#define __bool_true_false_are_defined 1\n\n#endif\n"
  },
  {
    "path": "user.libc/include/stdc-predef.h",
    "content": "#ifndef _STDC_PREDEF_H\n#define _STDC_PREDEF_H\n\n#define __STDC_ISO_10646__ 201206L\n\n#if !defined(__GCC_IEC_559) || __GCC_IEC_559 > 0\n#define __STDC_IEC_559__ 1\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/stddef.h",
    "content": "#ifndef _STDDEF_H\n#define _STDDEF_H\n\n#ifdef __cplusplus\n#define NULL 0L\n#else\n#define NULL ((void*)0)\n#endif\n\n#define __NEED_ptrdiff_t\n#define __NEED_size_t\n#define __NEED_wchar_t\n#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L\n#define __NEED_max_align_t\n#endif\n\n#include <bits/alltypes.h>\n\n#if __GNUC__ > 3\n#define offsetof(type, member) __builtin_offsetof(type, member)\n#else\n#define offsetof(type, member) ((size_t)( (char *)&(((type *)0)->member) - (char *)0 ))\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/stdint.h",
    "content": "#ifndef _STDINT_H\n#define _STDINT_H\n\n#define __NEED_int8_t\n#define __NEED_int16_t\n#define __NEED_int32_t\n#define __NEED_int64_t\n\n#define __NEED_uint8_t\n#define __NEED_uint16_t\n#define __NEED_uint32_t\n#define __NEED_uint64_t\n\n#define __NEED_intptr_t\n#define __NEED_uintptr_t\n\n#define __NEED_intmax_t\n#define __NEED_uintmax_t\n\n#include <bits/alltypes.h>\n\ntypedef int8_t int_fast8_t;\ntypedef int64_t int_fast64_t;\n\ntypedef int8_t  int_least8_t;\ntypedef int16_t int_least16_t;\ntypedef int32_t int_least32_t;\ntypedef int64_t int_least64_t;\n\ntypedef uint8_t uint_fast8_t;\ntypedef uint64_t uint_fast64_t;\n\ntypedef uint8_t  uint_least8_t;\ntypedef uint16_t uint_least16_t;\ntypedef uint32_t uint_least32_t;\ntypedef uint64_t uint_least64_t;\n\n#define INT8_MIN   (-1-0x7f)\n#define INT16_MIN  (-1-0x7fff)\n#define INT32_MIN  (-1-0x7fffffff)\n#define INT64_MIN  (-1-0x7fffffffffffffff)\n\n#define INT8_MAX   (0x7f)\n#define INT16_MAX  (0x7fff)\n#define INT32_MAX  (0x7fffffff)\n#define INT64_MAX  (0x7fffffffffffffff)\n\n#define UINT8_MAX  (0xff)\n#define UINT16_MAX (0xffff)\n#define UINT32_MAX (0xffffffffu)\n#define UINT64_MAX (0xffffffffffffffffu)\n\n#define INT_FAST8_MIN   INT8_MIN\n#define INT_FAST64_MIN  INT64_MIN\n\n#define INT_LEAST8_MIN   INT8_MIN\n#define INT_LEAST16_MIN  INT16_MIN\n#define INT_LEAST32_MIN  INT32_MIN\n#define INT_LEAST64_MIN  INT64_MIN\n\n#define INT_FAST8_MAX   INT8_MAX\n#define INT_FAST64_MAX  INT64_MAX\n\n#define INT_LEAST8_MAX   INT8_MAX\n#define INT_LEAST16_MAX  INT16_MAX\n#define INT_LEAST32_MAX  INT32_MAX\n#define INT_LEAST64_MAX  INT64_MAX\n\n#define UINT_FAST8_MAX  UINT8_MAX\n#define UINT_FAST64_MAX UINT64_MAX\n\n#define UINT_LEAST8_MAX  UINT8_MAX\n#define UINT_LEAST16_MAX UINT16_MAX\n#define UINT_LEAST32_MAX UINT32_MAX\n#define UINT_LEAST64_MAX UINT64_MAX\n\n#define INTMAX_MIN  INT64_MIN\n#define INTMAX_MAX  INT64_MAX\n#define UINTMAX_MAX UINT64_MAX\n\n#define WINT_MIN 0U\n#define WINT_MAX UINT32_MAX\n\n#if L'\\0'-1 > 0\n#define WCHAR_MAX (0xffffffffu+L'\\0')\n#define WCHAR_MIN (0+L'\\0')\n#else\n#define WCHAR_MAX (0x7fffffff+L'\\0')\n#define WCHAR_MIN (-1-0x7fffffff+L'\\0')\n#endif\n\n#define SIG_ATOMIC_MIN  INT32_MIN\n#define SIG_ATOMIC_MAX  INT32_MAX\n\n#include <bits/stdint.h>\n\n#define INT8_C(c)  c\n#define INT16_C(c) c\n#define INT32_C(c) c\n\n#define UINT8_C(c)  c\n#define UINT16_C(c) c\n#define UINT32_C(c) c ## U\n\n#if UINTPTR_MAX == UINT64_MAX\n#define INT64_C(c) c ## L\n#define UINT64_C(c) c ## UL\n#define INTMAX_C(c)  c ## L\n#define UINTMAX_C(c) c ## UL\n#else\n#define INT64_C(c) c ## LL\n#define UINT64_C(c) c ## ULL\n#define INTMAX_C(c)  c ## LL\n#define UINTMAX_C(c) c ## ULL\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/stdio.h",
    "content": "#ifndef _STDIO_H\n#define _STDIO_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_FILE\n#define __NEED___isoc_va_list\n#define __NEED_size_t\n\n#if __STDC_VERSION__ < 201112L\n#define __NEED_struct__IO_FILE\n#endif\n\n#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \\\n || defined(_BSD_SOURCE)\n#define __NEED_ssize_t\n#define __NEED_off_t\n#define __NEED_va_list\n#endif\n\n#include <bits/alltypes.h>\n\n#ifdef __cplusplus\n#define NULL 0L\n#else\n#define NULL ((void*)0)\n#endif\n\n#undef EOF\n#define EOF (-1)\n\n#undef SEEK_SET\n#undef SEEK_CUR\n#undef SEEK_END\n#define SEEK_SET 0\n#define SEEK_CUR 1\n#define SEEK_END 2\n\n#define _IOFBF 0\n#define _IOLBF 1\n#define _IONBF 2\n\n#define BUFSIZ 4096\n#define FILENAME_MAX 256\n#define SERVICENAME_MAX 32\n#define SERVICETYPE_MAX 16\n#define PROCESSNAME_MAX 64\n#define FOPEN_MAX 1000\n#define TMP_MAX 10000\n#define L_tmpnam 20\n\ntypedef union _G_fpos64_t {\n\tchar __opaque[16];\n\tlong long __lldata;\n\tdouble __align;\n} fpos_t;\n\nextern FILE *const stdin;\nextern FILE *const stdout;\nextern FILE *const stderr;\n\n#define stdin  (stdin)\n#define stdout (stdout)\n#define stderr (stderr)\n\nFILE *fopen(const char *__restrict, const char *__restrict);\nFILE *freopen(const char *__restrict, const char *__restrict, FILE *__restrict);\nint fclose(FILE *);\n\nint remove(const char *);\nint rename(const char *, const char *);\n\nint feof(FILE *);\nint ferror(FILE *);\nint fflush(FILE *);\nvoid clearerr(FILE *);\n\nint fseek(FILE *, long, int);\nlong ftell(FILE *);\nvoid rewind(FILE *);\n\nint fgetpos(FILE *__restrict, fpos_t *__restrict);\nint fsetpos(FILE *, const fpos_t *);\n\nsize_t fread(void *__restrict, size_t, size_t, FILE *__restrict);\nsize_t fwrite(const void *__restrict, size_t, size_t, FILE *__restrict);\n\nint fgetc(FILE *);\nint getc(FILE *);\nint getchar(void);\nint ungetc(int, FILE *);\n\nint fputc(int, FILE *);\nint putc(int, FILE *);\nint putchar(int);\n\nchar *fgets(char *__restrict, int, FILE *__restrict);\n#if __STDC_VERSION__ < 201112L\nchar *gets(char *);\n#endif\n\nint fputs(const char *__restrict, FILE *__restrict);\nint puts(const char *);\n\nint printf(const char *__restrict, ...);\nint fprintf(FILE *__restrict, const char *__restrict, ...);\nint sprintf(char *__restrict, const char *__restrict, ...);\nint snprintf(char *__restrict, size_t, const char *__restrict, ...);\n\nint vprintf(const char *__restrict, __isoc_va_list);\nint vfprintf(FILE *__restrict, const char *__restrict, __isoc_va_list);\nint vsprintf(char *__restrict, const char *__restrict, __isoc_va_list);\nint vsnprintf(char *__restrict, size_t, const char *__restrict, __isoc_va_list);\n\nint scanf(const char *__restrict, ...);\nint fscanf(FILE *__restrict, const char *__restrict, ...);\nint sscanf(const char *__restrict, const char *__restrict, ...);\nint vscanf(const char *__restrict, __isoc_va_list);\nint vfscanf(FILE *__restrict, const char *__restrict, __isoc_va_list);\nint vsscanf(const char *__restrict, const char *__restrict, __isoc_va_list);\n\nvoid perror(const char *);\n\nint setvbuf(FILE *__restrict, char *__restrict, int, size_t);\nvoid setbuf(FILE *__restrict, char *__restrict);\n\nchar *tmpnam(char *);\nFILE *tmpfile(void);\n\n#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \\\n || defined(_BSD_SOURCE)\nFILE *fmemopen(void *__restrict, size_t, const char *__restrict);\nFILE *open_memstream(char **, size_t *);\nFILE *fdopen(int, const char *);\nFILE *popen(const char *, const char *);\nint pclose(FILE *);\nint fileno(FILE *);\nint fseeko(FILE *, off_t, int);\noff_t ftello(FILE *);\nint dprintf(int, const char *__restrict, ...);\nint vdprintf(int, const char *__restrict, __isoc_va_list);\nvoid flockfile(FILE *);\nint ftrylockfile(FILE *);\nvoid funlockfile(FILE *);\nint getc_unlocked(FILE *);\nint getchar_unlocked(void);\nint putc_unlocked(int, FILE *);\nint putchar_unlocked(int);\nssize_t getdelim(char **__restrict, size_t *__restrict, int, FILE *__restrict);\nssize_t getline(char **__restrict, size_t *__restrict, FILE *__restrict);\nint renameat(int, const char *, int, const char *);\nchar *ctermid(char *);\n#define L_ctermid 20\n#endif\n\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \\\n || defined(_BSD_SOURCE)\n#define P_tmpdir \"/tmp\"\nchar *tempnam(const char *, const char *);\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define L_cuserid 20\nchar *cuserid(char *);\nvoid setlinebuf(FILE *);\nvoid setbuffer(FILE *, char *, size_t);\nint fgetc_unlocked(FILE *);\nint fputc_unlocked(int, FILE *);\nint fflush_unlocked(FILE *);\nsize_t fread_unlocked(void *, size_t, size_t, FILE *);\nsize_t fwrite_unlocked(const void *, size_t, size_t, FILE *);\nvoid clearerr_unlocked(FILE *);\nint feof_unlocked(FILE *);\nint ferror_unlocked(FILE *);\nint fileno_unlocked(FILE *);\nint getw(FILE *);\nint putw(int, FILE *);\nchar *fgetln(FILE *, size_t *);\nint asprintf(char **, const char *, ...);\nint vasprintf(char **, const char *, __isoc_va_list);\n#endif\n\n#ifdef _GNU_SOURCE\nchar *fgets_unlocked(char *, int, FILE *);\nint fputs_unlocked(const char *, FILE *);\n\ntypedef ssize_t (cookie_read_function_t)(void *, char *, size_t);\ntypedef ssize_t (cookie_write_function_t)(void *, const char *, size_t);\ntypedef int (cookie_seek_function_t)(void *, off_t *, int);\ntypedef int (cookie_close_function_t)(void *);\n\ntypedef struct _IO_cookie_io_functions_t {\n\tcookie_read_function_t *read;\n\tcookie_write_function_t *write;\n\tcookie_seek_function_t *seek;\n\tcookie_close_function_t *close;\n} cookie_io_functions_t;\n\nFILE *fopencookie(void *, const char *, cookie_io_functions_t);\n#endif\n\n#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)\n#define tmpfile64 tmpfile\n#define fopen64 fopen\n#define freopen64 freopen\n#define fseeko64 fseeko\n#define ftello64 ftello\n#define fgetpos64 fgetpos\n#define fsetpos64 fsetpos\n#define fpos64_t fpos_t\n#define off64_t off_t\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/stdio_ext.h",
    "content": "#ifndef _STDIO_EXT_H\n#define _STDIO_EXT_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdio.h>\n\n#define FSETLOCKING_QUERY 0\n#define FSETLOCKING_INTERNAL 1\n#define FSETLOCKING_BYCALLER 2\n\nvoid _flushlbf(void);\nint __fsetlocking(FILE *, int);\nint __fwriting(FILE *);\nint __freading(FILE *);\nint __freadable(FILE *);\nint __fwritable(FILE *);\nint __flbf(FILE *);\nsize_t __fbufsize(FILE *);\nsize_t __fpending(FILE *);\nint __fpurge(FILE *);\n\nsize_t __freadahead(FILE *);\nconst char *__freadptr(FILE *, size_t *);\nvoid __freadptrinc(FILE *, size_t);\nvoid __fseterr(FILE *);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/stdlib.h",
    "content": "#ifndef _STDLIB_H\n#define _STDLIB_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#ifdef __cplusplus\n#define NULL 0L\n#else\n#define NULL ((void*)0)\n#endif\n\n#define __NEED_size_t\n#define __NEED_wchar_t\n\n#include <bits/alltypes.h>\n\nint atoi (const char *);\nlong atol (const char *);\nlong long atoll (const char *);\ndouble atof (const char *);\n\nfloat strtof (const char *__restrict, char **__restrict);\ndouble strtod (const char *__restrict, char **__restrict);\nlong double strtold (const char *__restrict, char **__restrict);\n\nlong strtol (const char *__restrict, char **__restrict, int);\nunsigned long strtoul (const char *__restrict, char **__restrict, int);\nlong long strtoll (const char *__restrict, char **__restrict, int);\nunsigned long long strtoull (const char *__restrict, char **__restrict, int);\n\nint rand (void);\nvoid srand (unsigned);\n\nvoid *malloc (size_t);\nvoid *calloc (size_t, size_t);\nvoid *realloc (void *, size_t);\nvoid free (void *);\nvoid *zalloc (size_t);\nvoid *aligned_alloc(size_t, size_t);\n\n_Noreturn void abort (void);\nint atexit (void (*) (void));\n_Noreturn void exit (int);\n_Noreturn void _Exit (int);\nint at_quick_exit (void (*) (void));\n_Noreturn void quick_exit (int);\n\nchar *getenv (const char *);\n\nint system (const char *);\n\nvoid *bsearch (const void *, const void *, size_t, size_t, int (*)(const void *, const void *));\nvoid qsort (void *, size_t, size_t, int (*)(const void *, const void *));\n\nint abs (int);\nlong labs (long);\nlong long llabs (long long);\n\ntypedef struct { int quot, rem; } div_t;\ntypedef struct { long quot, rem; } ldiv_t;\ntypedef struct { long long quot, rem; } lldiv_t;\n\ndiv_t div (int, int);\nldiv_t ldiv (long, long);\nlldiv_t lldiv (long long, long long);\n\nint mblen (const char *, size_t);\nint mbtowc (wchar_t *__restrict, const char *__restrict, size_t);\nint wctomb (char *, wchar_t);\nsize_t mbstowcs (wchar_t *__restrict, const char *__restrict, size_t);\nsize_t wcstombs (char *__restrict, const wchar_t *__restrict, size_t);\n\n#define EXIT_FAILURE 1\n#define EXIT_SUCCESS 0\n\nsize_t __ctype_get_mb_cur_max(void);\n#define MB_CUR_MAX (__ctype_get_mb_cur_max())\n\n#define RAND_MAX (0x7fffffff)\n\n\n#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \\\n || defined(_BSD_SOURCE)\n\n#define WNOHANG    1\n#define WUNTRACED  2\n\n#define WEXITSTATUS(s) (((s) & 0xff00) >> 8)\n#define WTERMSIG(s) ((s) & 0x7f)\n#define WSTOPSIG(s) WEXITSTATUS(s)\n#define WIFEXITED(s) (!WTERMSIG(s))\n#define WIFSTOPPED(s) ((short)((((s)&0xffff)*0x10001)>>8) > 0x7f00)\n#define WIFSIGNALED(s) (((s)&0xffff)-1U < 0xffu)\n\nint posix_memalign (void **, size_t, size_t);\nint setenv (const char *, const char *, int);\nint unsetenv (const char *);\nint mkstemp (char *);\nint mkostemp (char *, int);\nchar *mkdtemp (char *);\nint getsubopt (char **, char *const *, char **);\nint rand_r (unsigned *);\n\n#endif\n\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \\\n || defined(_BSD_SOURCE)\nchar *realpath (const char *__restrict, char *__restrict);\nlong int random (void);\nvoid srandom (unsigned int);\nchar *initstate (unsigned int, char *, size_t);\nchar *setstate (char *);\nint putenv (char *);\nint posix_openpt (int);\nint grantpt (int);\nint unlockpt (int);\nchar *ptsname (int);\nchar *l64a (long);\nlong a64l (const char *);\nvoid setkey (const char *);\ndouble drand48 (void);\ndouble erand48 (unsigned short [3]);\nlong int lrand48 (void);\nlong int nrand48 (unsigned short [3]);\nlong mrand48 (void);\nlong jrand48 (unsigned short [3]);\nvoid srand48 (long);\nunsigned short *seed48 (unsigned short [3]);\nvoid lcong48 (unsigned short [7]);\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#include <alloca.h>\nchar *mktemp (char *);\nint mkstemps (char *, int);\nint mkostemps (char *, int, int);\nvoid *valloc (size_t);\nvoid *memalign(size_t, size_t);\nint getloadavg(double *, int);\nint clearenv(void);\n#define WCOREDUMP(s) ((s) & 0x80)\n#define WIFCONTINUED(s) ((s) == 0xffff)\nvoid *reallocarray (void *, size_t, size_t);\n#endif\n\n#ifdef _GNU_SOURCE\nint ptsname_r(int, char *, size_t);\nchar *ecvt(double, int, int *, int *);\nchar *fcvt(double, int, int *, int *);\nchar *gcvt(double, int, char *);\nchar *secure_getenv(const char *);\nstruct __locale_struct;\nfloat strtof_l(const char *__restrict, char **__restrict, struct __locale_struct *);\ndouble strtod_l(const char *__restrict, char **__restrict, struct __locale_struct *);\nlong double strtold_l(const char *__restrict, char **__restrict, struct __locale_struct *);\n#endif\n\n#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)\n#define mkstemp64 mkstemp\n#define mkostemp64 mkostemp\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define mkstemps64 mkstemps\n#define mkostemps64 mkostemps\n#endif\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/stdnoreturn.h",
    "content": "#ifndef _STDNORETURN_H\n#define _STDNORETURN_H\n#ifndef __cplusplus\n#include <features.h>\n#define noreturn _Noreturn\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/string.h",
    "content": "#ifndef\t_STRING_H\n#define\t_STRING_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#ifdef __cplusplus\n#define NULL 0L\n#else\n#define NULL ((void*)0)\n#endif\n\n#define __NEED_size_t\n#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \\\n || defined(_BSD_SOURCE)\n#define __NEED_locale_t\n#endif\n\n#include <bits/alltypes.h>\n\nvoid *memcpy (void *__restrict, const void *__restrict, size_t);\nvoid *memmove (void *, const void *, size_t);\nvoid *memset (void *, int, size_t);\nint memcmp (const void *, const void *, size_t);\nvoid *memchr (const void *, int, size_t);\n\nchar *strcpy (char *__restrict, const char *__restrict);\nchar *strncpy (char *__restrict, const char *__restrict, size_t);\n\nchar *strcat (char *__restrict, const char *__restrict);\nchar *strncat (char *__restrict, const char *__restrict, size_t);\n\nint strcmp (const char *, const char *);\nint strncmp (const char *, const char *, size_t);\n\nint strcoll (const char *, const char *);\nsize_t strxfrm (char *__restrict, const char *__restrict, size_t);\n\nchar *strchr (const char *, int);\nchar *strrchr (const char *, int);\n\nsize_t strcspn (const char *, const char *);\nsize_t strspn (const char *, const char *);\nchar *strpbrk (const char *, const char *);\nchar *strstr (const char *, const char *);\nchar *strtok (char *__restrict, const char *__restrict);\n\nsize_t strlen (const char *);\n\nchar *strerror (int);\n\n#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)\n#include <strings.h>\n#endif\n\n#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \\\n || defined(_BSD_SOURCE)\nchar *strtok_r (char *__restrict, const char *__restrict, char **__restrict);\nint strerror_r (int, char *, size_t);\nchar *stpcpy(char *__restrict, const char *__restrict);\nchar *stpncpy(char *__restrict, const char *__restrict, size_t);\nsize_t strnlen (const char *, size_t);\nchar *strdup (const char *);\nchar *strndup (const char *, size_t);\nchar *strsignal(int);\nchar *strerror_l (int, locale_t);\nint strcoll_l (const char *, const char *, locale_t);\nsize_t strxfrm_l (char *__restrict, const char *__restrict, size_t, locale_t);\n#endif\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \\\n || defined(_BSD_SOURCE)\nvoid *memccpy (void *__restrict, const void *__restrict, int, size_t);\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\nchar *strsep(char **, const char *);\nsize_t strlcat (char *, const char *, size_t);\nsize_t strlcpy (char *, const char *, size_t);\nvoid explicit_bzero (void *, size_t);\n#endif\n\n#ifdef _GNU_SOURCE\n#define\tstrdupa(x)\tstrcpy(alloca(strlen(x)+1),x)\nint strverscmp (const char *, const char *);\nchar *strchrnul(const char *, int);\nchar *strcasestr(const char *, const char *);\nvoid *memmem(const void *, size_t, const void *, size_t);\nvoid *memrchr(const void *, int, size_t);\nvoid *mempcpy(void *, const void *, size_t);\n#ifndef __cplusplus\nchar *basename();\n#endif\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/strings.h",
    "content": "#ifndef\t_STRINGS_H\n#define\t_STRINGS_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n#define __NEED_size_t\n#define __NEED_locale_t\n#include <bits/alltypes.h>\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_POSIX_SOURCE) \\\n || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE+0 < 200809L) \\\n || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 < 700)\nint bcmp (const void *, const void *, size_t);\nvoid bcopy (const void *, void *, size_t);\nvoid bzero (void *, size_t);\nchar *index (const char *, int);\nchar *rindex (const char *, int);\n#endif\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE)  || defined(_BSD_SOURCE)\nint ffs (int);\nint ffsl (long);\nint ffsll (long long);\n#endif\n\nint strcasecmp (const char *, const char *);\nint strncasecmp (const char *, const char *, size_t);\n\nint strcasecmp_l (const char *, const char *, locale_t);\nint strncasecmp_l (const char *, const char *, size_t, locale_t);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/stropts.h",
    "content": "#ifndef _STROPTS_H\n#define _STROPTS_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define __SID\t\t('S' << 8)\n\n#define I_NREAD\t\t(__SID | 1)\n#define I_PUSH\t\t(__SID | 2)\n#define I_POP\t\t(__SID | 3)\n#define I_LOOK\t\t(__SID | 4)\n#define I_FLUSH\t\t(__SID | 5)\n#define I_SRDOPT\t(__SID | 6)\n#define I_GRDOPT\t(__SID | 7)\n#define I_STR\t\t(__SID | 8)\n#define I_SETSIG\t(__SID | 9)\n#define I_GETSIG\t(__SID |10)\n#define I_FIND\t\t(__SID |11)\n#define I_LINK\t\t(__SID |12)\n#define I_UNLINK\t(__SID |13)\n#define I_PEEK\t\t(__SID |15)\n#define I_FDINSERT\t(__SID |16)\n#define I_SENDFD\t(__SID |17)\n#define I_RECVFD\t(__SID |14)\n#define I_SWROPT\t(__SID |19)\n#define I_GWROPT\t(__SID |20)\n#define I_LIST\t\t(__SID |21)\n#define I_PLINK\t\t(__SID |22)\n#define I_PUNLINK\t(__SID |23)\n#define I_FLUSHBAND\t(__SID |28)\n#define I_CKBAND\t(__SID |29)\n#define I_GETBAND\t(__SID |30)\n#define I_ATMARK\t(__SID |31)\n#define I_SETCLTIME\t(__SID |32)\n#define I_GETCLTIME\t(__SID |33)\n#define I_CANPUT\t(__SID |34)\n\n#define FMNAMESZ\t8\n\n#define FLUSHR\t\t0x01\n#define FLUSHW\t\t0x02\n#define FLUSHRW\t\t0x03\n#define FLUSHBAND\t0x04\n\n#define S_INPUT\t\t0x0001\n#define S_HIPRI\t\t0x0002\n#define S_OUTPUT\t0x0004\n#define S_MSG\t\t0x0008\n#define S_ERROR\t\t0x0010\n#define S_HANGUP\t0x0020\n#define S_RDNORM\t0x0040\n#define S_WRNORM\tS_OUTPUT\n#define S_RDBAND\t0x0080\n#define S_WRBAND\t0x0100\n#define S_BANDURG\t0x0200\n\n#define RS_HIPRI\t0x01\n\n#define RNORM\t\t0x0000\n#define RMSGD\t\t0x0001\n#define RMSGN\t\t0x0002\n#define RPROTDAT\t0x0004\n#define RPROTDIS\t0x0008\n#define RPROTNORM\t0x0010\n#define RPROTMASK\t0x001C\n\n#define SNDZERO\t\t0x001\n#define SNDPIPE\t\t0x002\n\n#define ANYMARK\t\t0x01\n#define LASTMARK\t0x02\n\n#define MUXID_ALL\t(-1)\n\n#define MSG_HIPRI\t0x01\n#define MSG_ANY\t\t0x02\n#define MSG_BAND\t0x04\n\n#define MORECTL\t\t1\n#define MOREDATA\t2\n\nstruct bandinfo {\n\tunsigned char bi_pri;\n\tint bi_flag;\n};\n\nstruct strbuf {\n\tint maxlen;\n\tint len;\n\tchar *buf;\n};\n\nstruct strpeek {\n\tstruct strbuf ctlbuf;\n\tstruct strbuf databuf;\n\tunsigned flags;\n};\n\nstruct strfdinsert {\n\tstruct strbuf ctlbuf;\n\tstruct strbuf databuf;\n\tunsigned flags;\n\tint fildes;\n\tint offset;\n};\n\nstruct strioctl {\n\tint ic_cmd;\n\tint ic_timout;\n\tint ic_len;\n\tchar *ic_dp;\n};\n\nstruct strrecvfd {\n\tint fd;\n\tint uid;\n\tint gid;\n\tchar __fill[8];\n};\n\nstruct str_mlist {\n\tchar l_name[FMNAMESZ + 1];\n};\n\nstruct str_list {\n\tint sl_nmods;\n\tstruct str_mlist *sl_modlist;\n};\n\nint isastream(int);\nint ioctl(int, int, ...);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/acct.h",
    "content": "#ifndef _SYS_ACCT_H\n#define _SYS_ACCT_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n#include <time.h>\n#include <stdint.h>\n\n#define ACCT_COMM 16\n\ntypedef uint16_t comp_t;\n\nstruct acct {\n\tchar ac_flag;\n\tuint16_t ac_uid;\n\tuint16_t ac_gid;\n\tuint16_t ac_tty;\n\tuint32_t ac_btime;\n\tcomp_t ac_utime;\n\tcomp_t ac_stime;\n\tcomp_t ac_etime;\n\tcomp_t ac_mem;\n\tcomp_t ac_io;\n\tcomp_t ac_rw;\n\tcomp_t ac_minflt;\n\tcomp_t ac_majflt;\n\tcomp_t ac_swaps;\n\tuint32_t ac_exitcode;\n\tchar ac_comm[ACCT_COMM+1];\n\tchar ac_pad[10];\n};\n\n\nstruct acct_v3 {\n\tchar ac_flag;\n\tchar ac_version;\n\tuint16_t ac_tty;\n\tuint32_t ac_exitcode;\n\tuint32_t ac_uid;\n\tuint32_t ac_gid;\n\tuint32_t ac_pid;\n\tuint32_t ac_ppid;\n\tuint32_t ac_btime;\n\tfloat ac_etime;\n\tcomp_t ac_utime;\n\tcomp_t ac_stime;\n\tcomp_t ac_mem;\n\tcomp_t ac_io;\n\tcomp_t ac_rw;\n\tcomp_t ac_minflt;\n\tcomp_t ac_majflt;\n\tcomp_t ac_swaps;\n\tchar ac_comm[ACCT_COMM];\n};\n\n#define AFORK 1\n#define ASU 2\n#define ACORE 8\n#define AXSIG 16\n#define ACCT_BYTEORDER (128*(__BYTE_ORDER==__BIG_ENDIAN))\n#define AHZ 100\n\nint acct(const char *);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/auxv.h",
    "content": "#ifndef _SYS_AUXV_H\n#define _SYS_AUXV_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <elf.h>\n#include <bits/hwcap.h>\n\nunsigned long getauxval(unsigned long);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/cachectl.h",
    "content": "#ifndef _SYS_CACHECTL_H\n#define _SYS_CACHECTL_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define ICACHE (1<<0)\n#define DCACHE (1<<1)\n#define BCACHE (ICACHE|DCACHE)\n#define CACHEABLE 0\n#define UNCACHEABLE 1\n \nint cachectl(void *, int, int);\nint cacheflush(void *, int, int);\nint _flush_cache(void *, int, int);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/dir.h",
    "content": "#include <dirent.h>\n#define direct dirent\n"
  },
  {
    "path": "user.libc/include/sys/epoll.h",
    "content": "#ifndef\t_SYS_EPOLL_H\n#define\t_SYS_EPOLL_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n#include <sys/types.h>\n#include <fcntl.h>\n\n#define __NEED_sigset_t\n\n#include <bits/alltypes.h>\n\n#define EPOLL_CLOEXEC O_CLOEXEC\n#define EPOLL_NONBLOCK O_NONBLOCK\n\nenum EPOLL_EVENTS { __EPOLL_DUMMY };\n#define EPOLLIN 0x001\n#define EPOLLOUT 0x002\n#define EPOLLROPEN 0X004\n#define EPOLLRCLOSE 0x008\n#define EPOLLWOPEN 0x010\n#define EPOLLWCLOSE 0x020\n#define EPOLLKERNEL 0x040\n\n#define EPOLLEXCLUSIVE (1U<<28)\n#define EPOLLWAKEUP (1U<<29)\n#define EPOLLONESHOT (1U<<30)\n#define EPOLLET (1U<<31)\n\n#define EPOLL_CTL_ADD 1\n#define EPOLL_CTL_DEL 2\n#define EPOLL_CTL_MOD 3\n\n#define EPOLL_KEV_NULL 0x0\n#define EPOLL_KEV_PAGE_FAULT 0x1\n#define EPOLL_KEV_PROCESS_EXIT 0x2\n\ntypedef struct epoll_data {\n\tunion {\n\t\tvoid *ptr;\n\t\tunsigned long pdata;\n\t};\n\tint fd;\n\tint type;\n\tuint64_t data0;\n\tuint64_t data1;\n\tuint64_t data2;\n} epoll_data_t;\n\nstruct epoll_event {\n\tuint32_t events;\n\tepoll_data_t data;\n}\n#ifdef __x86_64__\n__attribute__ ((__packed__))\n#endif\n;\n\nint epoll_create(int);\nint epoll_create1(int);\nint epoll_ctl(int, int, int, struct epoll_event *);\nint epoll_wait(int, struct epoll_event *, int, int);\nint epoll_pwait(int, struct epoll_event *, int, int, const sigset_t *);\n\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* sys/epoll.h */\n"
  },
  {
    "path": "user.libc/include/sys/errno.h",
    "content": "#warning redirecting incorrect #include <sys/errno.h> to <errno.h>\n#include <errno.h>\n"
  },
  {
    "path": "user.libc/include/sys/eventfd.h",
    "content": "#ifndef _SYS_EVENTFD_H\n#define _SYS_EVENTFD_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n#include <fcntl.h>\n\ntypedef uint64_t eventfd_t;\n\n#define EFD_SEMAPHORE 1\n#define EFD_CLOEXEC O_CLOEXEC\n#define EFD_NONBLOCK O_NONBLOCK\n\nint eventfd(unsigned int, int);\nint eventfd_read(int, eventfd_t *);\nint eventfd_write(int, eventfd_t);\n\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* sys/eventfd.h */\n"
  },
  {
    "path": "user.libc/include/sys/fanotify.h",
    "content": "#ifndef _FANOTIFY_H\n#define _FANOTIFY_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <sys/statfs.h>\n\nstruct fanotify_event_metadata {\n\tunsigned event_len;\n\tunsigned char vers;\n\tunsigned char reserved;\n\tunsigned short metadata_len;\n\tunsigned long long mask\n#ifdef __GNUC__\n\t__attribute__((__aligned__(8)))\n#endif\n\t;\n\tint fd;\n\tint pid;\n};\n\nstruct fanotify_event_info_header {\n\tunsigned char info_type;\n\tunsigned char pad;\n\tunsigned short len;\n};\n\nstruct fanotify_event_info_fid {\n\tstruct fanotify_event_info_header hdr;\n\tfsid_t fsid;\n\tunsigned char handle[];\n};\n\nstruct fanotify_response {\n\tint fd;\n\tunsigned response;\n};\n\n#define FAN_ACCESS 0x01\n#define FAN_MODIFY 0x02\n#define FAN_ATTRIB 0x04\n#define FAN_CLOSE_WRITE 0x08\n#define FAN_CLOSE_NOWRITE 0x10\n#define FAN_OPEN 0x20\n#define FAN_MOVED_FROM 0x40\n#define FAN_MOVED_TO 0x80\n#define FAN_CREATE 0x100\n#define FAN_DELETE 0x200\n#define FAN_DELETE_SELF 0x400\n#define FAN_MOVE_SELF 0x800\n#define FAN_OPEN_EXEC 0x1000\n#define FAN_Q_OVERFLOW 0x4000\n#define FAN_OPEN_PERM 0x10000\n#define FAN_ACCESS_PERM 0x20000\n#define FAN_OPEN_EXEC_PERM 0x40000\n#define FAN_DIR_MODIFY 0x00080000\n#define FAN_EVENT_ON_CHILD 0x08000000\n#define FAN_ONDIR 0x40000000\n#define FAN_CLOSE (FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE)\n#define FAN_MOVE (FAN_MOVED_FROM | FAN_MOVED_TO)\n#define FAN_CLOEXEC 0x01\n#define FAN_NONBLOCK 0x02\n#define FAN_CLASS_NOTIF 0\n#define FAN_CLASS_CONTENT 0x04\n#define FAN_CLASS_PRE_CONTENT 0x08\n#define FAN_ALL_CLASS_BITS (FAN_CLASS_NOTIF | FAN_CLASS_CONTENT | FAN_CLASS_PRE_CONTENT)\n#define FAN_UNLIMITED_QUEUE 0x10\n#define FAN_UNLIMITED_MARKS 0x20\n#define FAN_ENABLE_AUDIT 0x40\n#define FAN_REPORT_TID 0x100\n#define FAN_REPORT_FID 0x200\n#define FAN_REPORT_DIR_FID 0x00000400\n#define FAN_REPORT_NAME 0x00000800\n#define FAN_REPORT_DFID_NAME (FAN_REPORT_DIR_FID | FAN_REPORT_NAME)\n#define FAN_ALL_INIT_FLAGS (FAN_CLOEXEC | FAN_NONBLOCK | FAN_ALL_CLASS_BITS | FAN_UNLIMITED_QUEUE | FAN_UNLIMITED_MARKS)\n#define FAN_MARK_ADD 0x01\n#define FAN_MARK_REMOVE 0x02\n#define FAN_MARK_DONT_FOLLOW 0x04\n#define FAN_MARK_ONLYDIR 0x08\n#define FAN_MARK_IGNORED_MASK 0x20\n#define FAN_MARK_IGNORED_SURV_MODIFY 0x40\n#define FAN_MARK_FLUSH 0x80\n#define FAN_MARK_INODE 0x00\n#define FAN_MARK_MOUNT 0x10\n#define FAN_MARK_FILESYSTEM 0x100\n#define FAN_MARK_TYPE_MASK (FAN_MARK_INODE | FAN_MARK_MOUNT | FAN_MARK_FILESYSTEM)\n#define FAN_ALL_MARK_FLAGS (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_DONT_FOLLOW | FAN_MARK_ONLYDIR | FAN_MARK_MOUNT | FAN_MARK_IGNORED_MASK | FAN_MARK_IGNORED_SURV_MODIFY | FAN_MARK_FLUSH)\n#define FAN_ALL_EVENTS (FAN_ACCESS | FAN_MODIFY | FAN_CLOSE | FAN_OPEN)\n#define FAN_ALL_PERM_EVENTS (FAN_OPEN_PERM | FAN_ACCESS_PERM)\n#define FAN_ALL_OUTGOING_EVENTS (FAN_ALL_EVENTS | FAN_ALL_PERM_EVENTS | FAN_Q_OVERFLOW)\n#define FANOTIFY_METADATA_VERSION 3\n#define FAN_EVENT_INFO_TYPE_FID 1\n#define FAN_EVENT_INFO_TYPE_DFID_NAME 2\n#define FAN_EVENT_INFO_TYPE_DFID 3\n#define FAN_ALLOW 0x01\n#define FAN_DENY 0x02\n#define FAN_AUDIT 0x10\n#define FAN_NOFD -1\n#define FAN_EVENT_METADATA_LEN (sizeof(struct fanotify_event_metadata))\n#define FAN_EVENT_NEXT(meta, len) ((len) -= (meta)->event_len, (struct fanotify_event_metadata*)(((char *)(meta)) + (meta)->event_len))\n#define FAN_EVENT_OK(meta, len) ((long)(len) >= (long)FAN_EVENT_METADATA_LEN && (long)(meta)->event_len >= (long)FAN_EVENT_METADATA_LEN && (long)(meta)->event_len <= (long)(len))\n\nint fanotify_init(unsigned, unsigned);\nint fanotify_mark(int, unsigned, unsigned long long, int, const char *);\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/fcntl.h",
    "content": "#warning redirecting incorrect #include <sys/fcntl.h> to <fcntl.h>\n#include <fcntl.h>\n"
  },
  {
    "path": "user.libc/include/sys/file.h",
    "content": "#ifndef _SYS_FILE_H\n#define _SYS_FILE_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define LOCK_SH\t1\n#define LOCK_EX\t2\n#define LOCK_NB\t4\n#define LOCK_UN\t8\n\n#define L_SET 0\n#define L_INCR 1\n#define L_XTND 2\n\nint flock(int, int);\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/fsuid.h",
    "content": "#ifndef _SYS_FSUID_H\n#define _SYS_FSUID_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define __NEED_uid_t\n#define __NEED_gid_t\n\n#include <bits/alltypes.h>\n\nint setfsuid(uid_t);\nint setfsgid(gid_t);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/inotify.h",
    "content": "#ifndef _SYS_INOTIFY_H\n#define _SYS_INOTIFY_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n#include <fcntl.h>\n\nstruct inotify_event {\n\tint wd;\n\tuint32_t mask, cookie, len;\n\tchar name[];\n};\n\n#define IN_CLOEXEC O_CLOEXEC\n#define IN_NONBLOCK O_NONBLOCK\n\n#define IN_ACCESS        0x00000001\n#define IN_MODIFY        0x00000002\n#define IN_ATTRIB        0x00000004\n#define IN_CLOSE_WRITE   0x00000008\n#define IN_CLOSE_NOWRITE 0x00000010\n#define IN_CLOSE         (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)\n#define IN_OPEN          0x00000020\n#define IN_MOVED_FROM    0x00000040\n#define IN_MOVED_TO      0x00000080\n#define IN_MOVE          (IN_MOVED_FROM | IN_MOVED_TO)\n#define IN_CREATE        0x00000100\n#define IN_DELETE        0x00000200\n#define IN_DELETE_SELF   0x00000400\n#define IN_MOVE_SELF     0x00000800\n#define IN_ALL_EVENTS    0x00000fff\n\n#define IN_UNMOUNT       0x00002000\n#define IN_Q_OVERFLOW    0x00004000\n#define IN_IGNORED       0x00008000\n\n#define IN_ONLYDIR       0x01000000\n#define IN_DONT_FOLLOW   0x02000000\n#define IN_EXCL_UNLINK   0x04000000\n#define IN_MASK_CREATE   0x10000000\n#define IN_MASK_ADD      0x20000000\n\n#define IN_ISDIR         0x40000000\n#define IN_ONESHOT       0x80000000\n\nint inotify_init(void);\nint inotify_init1(int);\nint inotify_add_watch(int, const char *, uint32_t);\nint inotify_rm_watch(int, int);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/io.h",
    "content": "#ifndef\t_SYS_IO_H\n#define\t_SYS_IO_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#include <bits/io.h>\n\nint iopl(int);\nint ioperm(unsigned long, unsigned long, int);\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/ioctl.h",
    "content": "#ifndef\t_SYS_IOCTL_H\n#define\t_SYS_IOCTL_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define __NEED_struct_winsize\n\n#include <bits/alltypes.h>\n#include <bits/ioctl.h>\n\n#define N_TTY           0\n#define N_SLIP          1\n#define N_MOUSE         2\n#define N_PPP           3\n#define N_STRIP         4\n#define N_AX25          5\n#define N_X25           6\n#define N_6PACK         7\n#define N_MASC          8\n#define N_R3964         9\n#define N_PROFIBUS_FDL  10\n#define N_IRDA          11\n#define N_SMSBLOCK      12\n#define N_HDLC          13\n#define N_SYNC_PPP      14\n#define N_HCI           15\n#define N_GIGASET_M101  16\n#define N_SLCAN         17\n#define N_PPS           18\n#define N_V253          19\n#define N_CAIF          20\n#define N_GSM0710       21\n#define N_TI_WL         22\n#define N_TRACESINK     23\n#define N_TRACEROUTER   24\n#define N_NCI           25\n#define N_SPEAKUP       26\n#define N_NULL          27\n\n#define TIOCPKT_DATA       0\n#define TIOCPKT_FLUSHREAD  1\n#define TIOCPKT_FLUSHWRITE 2\n#define TIOCPKT_STOP       4\n#define TIOCPKT_START      8\n#define TIOCPKT_NOSTOP    16\n#define TIOCPKT_DOSTOP    32\n#define TIOCPKT_IOCTL     64\n\n#define TIOCSER_TEMT 1\n\n#define SIOCADDRT          0x890B\n#define SIOCDELRT          0x890C\n#define SIOCRTMSG          0x890D\n\n#define SIOCGIFNAME        0x8910\n#define SIOCSIFLINK        0x8911\n#define SIOCGIFCONF        0x8912\n#define SIOCGIFFLAGS       0x8913\n#define SIOCSIFFLAGS       0x8914\n#define SIOCGIFADDR        0x8915\n#define SIOCSIFADDR        0x8916\n#define SIOCGIFDSTADDR     0x8917\n#define SIOCSIFDSTADDR     0x8918\n#define SIOCGIFBRDADDR     0x8919\n#define SIOCSIFBRDADDR     0x891a\n#define SIOCGIFNETMASK     0x891b\n#define SIOCSIFNETMASK     0x891c\n#define SIOCGIFMETRIC      0x891d\n#define SIOCSIFMETRIC      0x891e\n#define SIOCGIFMEM         0x891f\n#define SIOCSIFMEM         0x8920\n#define SIOCGIFMTU         0x8921\n#define SIOCSIFMTU         0x8922\n#define SIOCSIFNAME        0x8923\n#define SIOCSIFHWADDR      0x8924\n#define SIOCGIFENCAP       0x8925\n#define SIOCSIFENCAP       0x8926\n#define SIOCGIFHWADDR      0x8927\n#define SIOCGIFSLAVE       0x8929\n#define SIOCSIFSLAVE       0x8930\n#define SIOCADDMULTI       0x8931\n#define SIOCDELMULTI       0x8932\n#define SIOCGIFINDEX       0x8933\n#define SIOGIFINDEX        SIOCGIFINDEX\n#define SIOCSIFPFLAGS      0x8934\n#define SIOCGIFPFLAGS      0x8935\n#define SIOCDIFADDR        0x8936\n#define SIOCSIFHWBROADCAST 0x8937\n#define SIOCGIFCOUNT       0x8938\n\n#define SIOCGIFBR          0x8940\n#define SIOCSIFBR          0x8941\n\n#define SIOCGIFTXQLEN      0x8942\n#define SIOCSIFTXQLEN      0x8943\n\n#define SIOCDARP           0x8953\n#define SIOCGARP           0x8954\n#define SIOCSARP           0x8955\n\n#define SIOCDRARP          0x8960\n#define SIOCGRARP          0x8961\n#define SIOCSRARP          0x8962\n\n#define SIOCGIFMAP         0x8970\n#define SIOCSIFMAP         0x8971\n\n#define SIOCADDDLCI        0x8980\n#define SIOCDELDLCI        0x8981\n\n#define SIOCDEVPRIVATE     0x89F0\n#define SIOCPROTOPRIVATE   0x89E0\n\nint ioctl (int, int, ...);\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/ipc.h",
    "content": "#ifndef _SYS_IPC_H\n#define _SYS_IPC_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_uid_t\n#define __NEED_gid_t\n#define __NEED_mode_t\n#define __NEED_key_t\n\n#include <bits/alltypes.h>\n\n#define __ipc_perm_key __key\n#define __ipc_perm_seq __seq\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define __key key\n#define __seq seq\n#endif\n\n#include <bits/ipc.h>\n#include <bits/ipcstat.h>\n\n#define IPC_CREAT  01000\n#define IPC_EXCL   02000\n#define IPC_NOWAIT 04000\n\n#define IPC_RMID 0\n#define IPC_SET  1\n#define IPC_INFO 3\n\n#define IPC_PRIVATE ((key_t) 0)\n\nkey_t ftok (const char *, int);\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/kd.h",
    "content": "#include <bits/kd.h>\n"
  },
  {
    "path": "user.libc/include/sys/klog.h",
    "content": "#ifndef\t_SYS_KLOG_H\n#define\t_SYS_KLOG_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nint klogctl (int, char *, int);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/membarrier.h",
    "content": "#ifndef _SYS_MEMBARRIER_H\n#define _SYS_MEMBARRIER_H\n\n#define MEMBARRIER_CMD_QUERY 0\n#define MEMBARRIER_CMD_GLOBAL 1\n#define MEMBARRIER_CMD_GLOBAL_EXPEDITED 2\n#define MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED 4\n#define MEMBARRIER_CMD_PRIVATE_EXPEDITED 8\n#define MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED 16\n#define MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE 32\n#define MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE 64\n\n#define MEMBARRIER_CMD_SHARED MEMBARRIER_CMD_GLOBAL\n\nint membarrier(int, int);\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/mman.h",
    "content": "#ifndef\t_SYS_MMAN_H\n#define\t_SYS_MMAN_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_mode_t\n#define __NEED_size_t\n#define __NEED_off_t\n\n#if defined(_GNU_SOURCE)\n#define __NEED_ssize_t\n#endif\n\n#include <bits/alltypes.h>\n\n#define MAP_FAILED ((void *) -1)\n\n#define MAP_SHARED     0x01\n#define MAP_PRIVATE    0x02\n#define MAP_SHARED_VALIDATE 0x03\n#define MAP_TYPE       0x0f\n#define MAP_FIXED      0x10\n#define MAP_ANON       0x20\n#define MAP_ANONYMOUS  MAP_ANON\n#define MAP_NORESERVE  0x4000\n#define MAP_GROWSDOWN  0x0100\n#define MAP_DENYWRITE  0x0800\n#define MAP_EXECUTABLE 0x1000\n#define MAP_LOCKED     0x2000\n#define MAP_POPULATE   0x8000\n#define MAP_NONBLOCK   0x10000\n#define MAP_STACK      0x20000\n#define MAP_HUGETLB    0x40000\n#define MAP_SYNC       0x80000\n#define MAP_FIXED_NOREPLACE 0x100000\n#define MAP_FILE       0\n\n#define MAP_HUGE_SHIFT 26\n#define MAP_HUGE_MASK  0x3f\n#define MAP_HUGE_64KB  (16 << 26)\n#define MAP_HUGE_512KB (19 << 26)\n#define MAP_HUGE_1MB   (20 << 26)\n#define MAP_HUGE_2MB   (21 << 26)\n#define MAP_HUGE_8MB   (23 << 26)\n#define MAP_HUGE_16MB  (24 << 26)\n#define MAP_HUGE_32MB  (25 << 26)\n#define MAP_HUGE_256MB (28 << 26)\n#define MAP_HUGE_512MB (29 << 26)\n#define MAP_HUGE_1GB   (30 << 26)\n#define MAP_HUGE_2GB   (31 << 26)\n#define MAP_HUGE_16GB  (34U << 26)\n\n#define PROT_NONE      0\n#define PROT_READ      1\n#define PROT_WRITE     2\n#define PROT_EXEC      4\n#define PROT_GROWSDOWN 0x01000000\n#define PROT_GROWSUP   0x02000000\n\n#define MS_ASYNC       1\n#define MS_INVALIDATE  2\n#define MS_SYNC        4\n\n#define MCL_CURRENT    1\n#define MCL_FUTURE     2\n#define MCL_ONFAULT    4\n\n#define POSIX_MADV_NORMAL     0\n#define POSIX_MADV_RANDOM     1\n#define POSIX_MADV_SEQUENTIAL 2\n#define POSIX_MADV_WILLNEED   3\n#define POSIX_MADV_DONTNEED   4\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define MADV_NORMAL      0\n#define MADV_RANDOM      1\n#define MADV_SEQUENTIAL  2\n#define MADV_WILLNEED    3\n#define MADV_DONTNEED    4\n#define MADV_FREE        8\n#define MADV_REMOVE      9\n#define MADV_DONTFORK    10\n#define MADV_DOFORK      11\n#define MADV_MERGEABLE   12\n#define MADV_UNMERGEABLE 13\n#define MADV_HUGEPAGE    14\n#define MADV_NOHUGEPAGE  15\n#define MADV_DONTDUMP    16\n#define MADV_DODUMP      17\n#define MADV_WIPEONFORK  18\n#define MADV_KEEPONFORK  19\n#define MADV_COLD        20\n#define MADV_PAGEOUT     21\n#define MADV_HWPOISON    100\n#define MADV_SOFT_OFFLINE 101\n#endif\n\n#ifdef _GNU_SOURCE\n#define MREMAP_MAYMOVE 1\n#define MREMAP_FIXED 2\n#define MREMAP_DONTUNMAP 4\n\n#define MLOCK_ONFAULT 0x01\n\n#define MFD_CLOEXEC 0x0001U\n#define MFD_ALLOW_SEALING 0x0002U\n#define MFD_HUGETLB 0x0004U\n#endif\n\n#include <bits/mman.h>\n\nvoid *mmap (void *, size_t, int, int, int, off_t);\nint munmap (void *, size_t);\n\nint mprotect (void *, size_t, int);\nint msync (void *, size_t, int);\n\nint posix_madvise (void *, size_t, int);\n\nint mlock (const void *, size_t);\nint munlock (const void *, size_t);\nint mlockall (int);\nint munlockall (void);\n\n#ifdef _GNU_SOURCE\nvoid *mremap (void *, size_t, size_t, int, ...);\nint remap_file_pages (void *, size_t, int, size_t, int);\nint memfd_create (const char *, unsigned);\nint mlock2 (const void *, size_t, unsigned);\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\nint madvise (void *, size_t, int);\nint mincore (void *, size_t, unsigned char *);\n#endif\n\nint shm_open (const char *, int, mode_t);\nint shm_unlink (const char *);\n\nint sys_map(int proc, int pma, unsigned long base, size_t size, int right);\nint sys_unmap(int proc, int pma, unsigned long base, size_t size);\nunsigned long sys_mtrans(unsigned long virt);\n\n#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)\n#define mmap64 mmap\n#define off64_t off_t\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/msg.h",
    "content": "#ifndef _SYS_MSG_H\n#define _SYS_MSG_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <sys/ipc.h>\n\n#define __NEED_pid_t\n#define __NEED_key_t\n#define __NEED_time_t\n#define __NEED_size_t\n#define __NEED_ssize_t\n\n#include <bits/alltypes.h>\n\ntypedef unsigned long msgqnum_t;\ntypedef unsigned long msglen_t;\n\n#include <bits/msg.h>\n\n#define __msg_cbytes msg_cbytes\n\n#define MSG_NOERROR 010000\n#define MSG_EXCEPT  020000\n\n#define MSG_STAT (11 | (IPC_STAT & 0x100))\n#define MSG_INFO 12\n#define MSG_STAT_ANY (13 | (IPC_STAT & 0x100))\n\nstruct msginfo {\n\tint msgpool, msgmap, msgmax, msgmnb, msgmni, msgssz, msgtql;\n\tunsigned short msgseg;\n};\n\nint msgctl (int, int, struct msqid_ds *);\nint msgget (key_t, int);\nssize_t msgrcv (int, void *, size_t, long, int);\nint msgsnd (int, const void *, size_t, int);\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\nstruct msgbuf {\n\tlong mtype;\n\tchar mtext[1];\n};\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/mtio.h",
    "content": "#ifndef _SYS_MTIO_H\n#define _SYS_MTIO_H\n\n#include <sys/types.h>\n#include <sys/ioctl.h>\n\nstruct mtop {\n\tshort mt_op;\n\tint mt_count;\n};\n\n#define _IOT_mtop _IOT (_IOTS (short), 1, _IOTS (int), 1, 0, 0)\n#define _IOT_mtget _IOT (_IOTS (long), 7, 0, 0, 0, 0)\n#define _IOT_mtpos _IOT_SIMPLE (long)\n#define _IOT_mtconfiginfo _IOT (_IOTS (long), 2, _IOTS (short), 3, _IOTS (long), 1)\n\n\n#define MTRESET 0\n#define MTFSF\t1\n#define MTBSF\t2\n#define MTFSR\t3\n#define MTBSR\t4\n#define MTWEOF\t5\n#define MTREW\t6\n#define MTOFFL\t7\n#define MTNOP\t8\n#define MTRETEN 9\n#define MTBSFM\t10\n#define MTFSFM  11\n#define MTEOM\t12\n#define MTERASE 13\n#define MTRAS1  14\n#define MTRAS2\t15\n#define MTRAS3  16\n#define MTSETBLK 20\n#define MTSETDENSITY 21\n#define MTSEEK\t22\n#define MTTELL\t23\n#define MTSETDRVBUFFER 24\n#define MTFSS\t25\n#define MTBSS\t26\n#define MTWSM\t27\n#define MTLOCK  28\n#define MTUNLOCK 29\n#define MTLOAD  30\n#define MTUNLOAD 31\n#define MTCOMPRESSION 32\n#define MTSETPART 33\n#define MTMKPART  34\n\nstruct mtget {\n\tlong mt_type;\n\tlong mt_resid;\n\tlong mt_dsreg;\n\tlong mt_gstat;\n\tlong mt_erreg;\n\tint mt_fileno;\n\tint mt_blkno;\n};\n\n#define MT_ISUNKNOWN\t\t0x01\n#define MT_ISQIC02\t\t0x02\n#define MT_ISWT5150\t\t0x03\n#define MT_ISARCHIVE_5945L2\t0x04\n#define MT_ISCMSJ500\t\t0x05\n#define MT_ISTDC3610\t\t0x06\n#define MT_ISARCHIVE_VP60I\t0x07\n#define MT_ISARCHIVE_2150L\t0x08\n#define MT_ISARCHIVE_2060L\t0x09\n#define MT_ISARCHIVESC499\t0x0A\n#define MT_ISQIC02_ALL_FEATURES\t0x0F\n#define MT_ISWT5099EEN24\t0x11\n#define MT_ISTEAC_MT2ST\t\t0x12\n#define MT_ISEVEREX_FT40A\t0x32\n#define MT_ISDDS1\t\t0x51\n#define MT_ISDDS2\t\t0x52\n#define MT_ISSCSI1\t\t0x71\n#define MT_ISSCSI2\t\t0x72\n#define MT_ISFTAPE_UNKNOWN\t0x800000\n#define MT_ISFTAPE_FLAG\t\t0x800000\n\nstruct mt_tape_info {\n\tlong t_type;\n\tchar *t_name;\n};\n\n#define MT_TAPE_INFO \\\n{\t\t\t\t\t\t\t\t\t      \\\n\t{MT_ISUNKNOWN,\t\t\"Unknown type of tape device\"},\t\t      \\\n\t{MT_ISQIC02,\t\t\"Generic QIC-02 tape streamer\"},\t      \\\n\t{MT_ISWT5150,\t\t\"Wangtek 5150, QIC-150\"},\t\t      \\\n\t{MT_ISARCHIVE_5945L2,\t\"Archive 5945L-2\"},\t\t\t      \\\n\t{MT_ISCMSJ500,\t\t\"CMS Jumbo 500\"},\t\t\t      \\\n\t{MT_ISTDC3610,\t\t\"Tandberg TDC 3610, QIC-24\"},\t\t      \\\n\t{MT_ISARCHIVE_VP60I,\t\"Archive VP60i, QIC-02\"},\t\t      \\\n\t{MT_ISARCHIVE_2150L,\t\"Archive Viper 2150L\"},\t\t\t      \\\n\t{MT_ISARCHIVE_2060L,\t\"Archive Viper 2060L\"},\t\t\t      \\\n\t{MT_ISARCHIVESC499,\t\"Archive SC-499 QIC-36 controller\"},\t      \\\n\t{MT_ISQIC02_ALL_FEATURES, \"Generic QIC-02 tape, all features\"},\t      \\\n\t{MT_ISWT5099EEN24,\t\"Wangtek 5099-een24, 60MB\"},\t\t      \\\n\t{MT_ISTEAC_MT2ST,\t\"Teac MT-2ST 155mb data cassette drive\"},     \\\n\t{MT_ISEVEREX_FT40A,\t\"Everex FT40A, QIC-40\"},\t\t      \\\n\t{MT_ISSCSI1,\t\t\"Generic SCSI-1 tape\"},\t\t\t      \\\n\t{MT_ISSCSI2,\t\t\"Generic SCSI-2 tape\"},\t\t\t      \\\n\t{0, 0}\t\t\t\t\t\t\t\t      \\\n}\n\nstruct mtpos {\n\tlong mt_blkno;\n};\n\nstruct mtconfiginfo  {\n\tlong mt_type;\n\tlong ifc_type;\n\tunsigned short irqnr;\n\tunsigned short dmanr;\n\tunsigned short port;\n\tunsigned long debug;\n\tunsigned have_dens:1;\n\tunsigned have_bsf:1;\n\tunsigned have_fsr:1;\n\tunsigned have_bsr:1;\n\tunsigned have_eod:1;\n\tunsigned have_seek:1;\n\tunsigned have_tell:1;\n\tunsigned have_ras1:1;\n\tunsigned have_ras2:1;\n\tunsigned have_ras3:1;\n\tunsigned have_qfa:1;\n\tunsigned pad1:5;\n\tchar reserved[10];\n};\n\n#define\tMTIOCTOP _IOW('m', 1, struct mtop)\n#define\tMTIOCGET _IOR('m', 2, struct mtget)\n#define\tMTIOCPOS _IOR('m', 3, struct mtpos)\n\n#define\tMTIOCGETCONFIG\t_IOR('m', 4, struct mtconfiginfo)\n#define\tMTIOCSETCONFIG\t_IOW('m', 5, struct mtconfiginfo)\n\n#define GMT_EOF(x)              ((x) & 0x80000000)\n#define GMT_BOT(x)              ((x) & 0x40000000)\n#define GMT_EOT(x)              ((x) & 0x20000000)\n#define GMT_SM(x)               ((x) & 0x10000000)\n#define GMT_EOD(x)              ((x) & 0x08000000)\n#define GMT_WR_PROT(x)          ((x) & 0x04000000)\n#define GMT_ONLINE(x)           ((x) & 0x01000000)\n#define GMT_D_6250(x)           ((x) & 0x00800000)\n#define GMT_D_1600(x)           ((x) & 0x00400000)\n#define GMT_D_800(x)            ((x) & 0x00200000)\n#define GMT_DR_OPEN(x)          ((x) & 0x00040000)\n#define GMT_IM_REP_EN(x)        ((x) & 0x00010000)\n\n#define MT_ST_BLKSIZE_SHIFT\t0\n#define MT_ST_BLKSIZE_MASK\t0xffffff\n#define MT_ST_DENSITY_SHIFT\t24\n#define MT_ST_DENSITY_MASK\t0xff000000\n#define MT_ST_SOFTERR_SHIFT\t0\n#define MT_ST_SOFTERR_MASK\t0xffff\n#define MT_ST_OPTIONS\t\t0xf0000000\n#define MT_ST_BOOLEANS\t\t0x10000000\n#define MT_ST_SETBOOLEANS\t0x30000000\n#define MT_ST_CLEARBOOLEANS\t0x40000000\n#define MT_ST_WRITE_THRESHOLD\t0x20000000\n#define MT_ST_DEF_BLKSIZE\t0x50000000\n#define MT_ST_DEF_OPTIONS\t0x60000000\n#define MT_ST_BUFFER_WRITES\t0x1\n#define MT_ST_ASYNC_WRITES\t0x2\n#define MT_ST_READ_AHEAD\t0x4\n#define MT_ST_DEBUGGING\t\t0x8\n#define MT_ST_TWO_FM\t\t0x10\n#define MT_ST_FAST_MTEOM\t0x20\n#define MT_ST_AUTO_LOCK\t\t0x40\n#define MT_ST_DEF_WRITES\t0x80\n#define MT_ST_CAN_BSR\t\t0x100\n#define MT_ST_NO_BLKLIMS\t0x200\n#define MT_ST_CAN_PARTITIONS    0x400\n#define MT_ST_SCSI2LOGICAL      0x800\n#define MT_ST_CLEAR_DEFAULT\t0xfffff\n#define MT_ST_DEF_DENSITY\t(MT_ST_DEF_OPTIONS | 0x100000)\n#define MT_ST_DEF_COMPRESSION\t(MT_ST_DEF_OPTIONS | 0x200000)\n#define MT_ST_DEF_DRVBUFFER\t(MT_ST_DEF_OPTIONS | 0x300000)\n#define MT_ST_HPLOADER_OFFSET 10000\n#ifndef DEFTAPE\n# define DEFTAPE\t\"/dev/tape\"\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/param.h",
    "content": "#ifndef _SYS_PARAM_H\n#define _SYS_PARAM_H\n\n#define MAXSYMLINKS 20\n#define MAXHOSTNAMELEN 64\n#define MAXNAMLEN 255\n#define MAXPATHLEN 4096\n#define NBBY 8\n#define NGROUPS 32\n#define CANBSIZ 255\n#define NOFILE 256\n#define NCARGS 131072\n#define DEV_BSIZE 512\n#define NOGROUP (-1)\n\n#undef MIN\n#undef MAX\n#define MIN(a,b) (((a)<(b))?(a):(b))\n#define MAX(a,b) (((a)>(b))?(a):(b))\n\n#define __bitop(x,i,o) ((x)[(i)/8] o (1<<(i)%8))\n#define setbit(x,i) __bitop(x,i,|=)\n#define clrbit(x,i) __bitop(x,i,&=~)\n#define isset(x,i) __bitop(x,i,&)\n#define isclr(x,i) !isset(x,i)\n\n#define howmany(n,d) (((n)+((d)-1))/(d))\n#define roundup(n,d) (howmany(n,d)*(d))\n#define powerof2(n) !(((n)-1) & (n))\n\n#include <sys/resource.h>\n#include <endian.h>\n#include <limits.h>\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/personality.h",
    "content": "#ifndef _PERSONALITY_H\n#define _PERSONALITY_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define UNAME26            0x0020000\n#define ADDR_NO_RANDOMIZE  0x0040000\n#define FDPIC_FUNCPTRS     0x0080000\n#define MMAP_PAGE_ZERO     0x0100000\n#define ADDR_COMPAT_LAYOUT 0x0200000\n#define READ_IMPLIES_EXEC  0x0400000\n#define ADDR_LIMIT_32BIT   0x0800000\n#define SHORT_INODE        0x1000000\n#define WHOLE_SECONDS      0x2000000\n#define STICKY_TIMEOUTS    0x4000000\n#define ADDR_LIMIT_3GB     0x8000000\n\n#define PER_LINUX 0\n#define PER_LINUX_32BIT ADDR_LIMIT_32BIT\n#define PER_LINUX_FDPIC FDPIC_FUNCPTRS\n#define PER_SVR4 (1 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO)\n#define PER_SVR3 (2 | STICKY_TIMEOUTS | SHORT_INODE)\n#define PER_SCOSVR3 (3 | STICKY_TIMEOUTS | WHOLE_SECONDS | SHORT_INODE)\n#define PER_OSR5 (3 | STICKY_TIMEOUTS | WHOLE_SECONDS)\n#define PER_WYSEV386 (4 | STICKY_TIMEOUTS | SHORT_INODE)\n#define PER_ISCR4 (5 | STICKY_TIMEOUTS)\n#define PER_BSD 6\n#define PER_SUNOS (6 | STICKY_TIMEOUTS)\n#define PER_XENIX (7 | STICKY_TIMEOUTS | SHORT_INODE)\n#define PER_LINUX32 8\n#define PER_LINUX32_3GB (8 | ADDR_LIMIT_3GB)\n#define PER_IRIX32 (9 | STICKY_TIMEOUTS)\n#define PER_IRIXN32 (0xa | STICKY_TIMEOUTS)\n#define PER_IRIX64 (0x0b | STICKY_TIMEOUTS)\n#define PER_RISCOS 0xc\n#define PER_SOLARIS (0xd | STICKY_TIMEOUTS)\n#define PER_UW7 (0xe | STICKY_TIMEOUTS | MMAP_PAGE_ZERO)\n#define PER_OSF4 0xf\n#define PER_HPUX 0x10\n#define PER_MASK 0xff\n\nint personality(unsigned long);\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/poll.h",
    "content": "#warning redirecting incorrect #include <sys/poll.h> to <poll.h>\n#include <poll.h>\n"
  },
  {
    "path": "user.libc/include/sys/prctl.h",
    "content": "#ifndef _SYS_PRCTL_H\n#define _SYS_PRCTL_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\n#define PR_SET_PDEATHSIG  1\n#define PR_GET_PDEATHSIG  2\n#define PR_GET_DUMPABLE   3\n#define PR_SET_DUMPABLE   4\n#define PR_GET_UNALIGN   5\n#define PR_SET_UNALIGN   6\n#define PR_UNALIGN_NOPRINT 1\n#define PR_UNALIGN_SIGBUS 2\n#define PR_GET_KEEPCAPS   7\n#define PR_SET_KEEPCAPS   8\n#define PR_GET_FPEMU  9\n#define PR_SET_FPEMU 10\n#define PR_FPEMU_NOPRINT 1\n#define PR_FPEMU_SIGFPE 2\n#define PR_GET_FPEXC 11\n#define PR_SET_FPEXC 12\n#define PR_FP_EXC_SW_ENABLE 0x80\n#define PR_FP_EXC_DIV  0x010000\n#define PR_FP_EXC_OVF  0x020000\n#define PR_FP_EXC_UND  0x040000\n#define PR_FP_EXC_RES  0x080000\n#define PR_FP_EXC_INV  0x100000\n#define PR_FP_EXC_DISABLED 0\n#define PR_FP_EXC_NONRECOV 1\n#define PR_FP_EXC_ASYNC 2\n#define PR_FP_EXC_PRECISE 3\n#define PR_GET_TIMING   13\n#define PR_SET_TIMING   14\n#define PR_TIMING_STATISTICAL  0\n#define PR_TIMING_TIMESTAMP    1\n#define PR_SET_NAME    15\n#define PR_GET_NAME    16\n#define PR_GET_ENDIAN 19\n#define PR_SET_ENDIAN 20\n#define PR_ENDIAN_BIG 0\n#define PR_ENDIAN_LITTLE 1\n#define PR_ENDIAN_PPC_LITTLE 2\n#define PR_GET_SECCOMP 21\n#define PR_SET_SECCOMP 22\n#define PR_CAPBSET_READ 23\n#define PR_CAPBSET_DROP 24\n#define PR_GET_TSC 25\n#define PR_SET_TSC 26\n#define PR_TSC_ENABLE 1\n#define PR_TSC_SIGSEGV 2\n#define PR_GET_SECUREBITS 27\n#define PR_SET_SECUREBITS 28\n#define PR_SET_TIMERSLACK 29\n#define PR_GET_TIMERSLACK 30\n\n#define PR_TASK_PERF_EVENTS_DISABLE             31\n#define PR_TASK_PERF_EVENTS_ENABLE              32\n\n#define PR_MCE_KILL     33\n#define PR_MCE_KILL_CLEAR   0\n#define PR_MCE_KILL_SET     1\n#define PR_MCE_KILL_LATE    0\n#define PR_MCE_KILL_EARLY   1\n#define PR_MCE_KILL_DEFAULT 2\n#define PR_MCE_KILL_GET 34\n\n#define PR_SET_MM               35\n#define PR_SET_MM_START_CODE           1\n#define PR_SET_MM_END_CODE             2\n#define PR_SET_MM_START_DATA           3\n#define PR_SET_MM_END_DATA             4\n#define PR_SET_MM_START_STACK          5\n#define PR_SET_MM_START_BRK            6\n#define PR_SET_MM_BRK                  7\n#define PR_SET_MM_ARG_START            8\n#define PR_SET_MM_ARG_END              9\n#define PR_SET_MM_ENV_START            10\n#define PR_SET_MM_ENV_END              11\n#define PR_SET_MM_AUXV                 12\n#define PR_SET_MM_EXE_FILE             13\n#define PR_SET_MM_MAP                  14\n#define PR_SET_MM_MAP_SIZE             15\n\nstruct prctl_mm_map {\n\tuint64_t start_code;\n\tuint64_t end_code;\n\tuint64_t start_data;\n\tuint64_t end_data;\n\tuint64_t start_brk;\n\tuint64_t brk;\n\tuint64_t start_stack;\n\tuint64_t arg_start;\n\tuint64_t arg_end;\n\tuint64_t env_start;\n\tuint64_t env_end;\n\tuint64_t *auxv;\n\tuint32_t auxv_size;\n\tuint32_t exe_fd;\n};\n\n#define PR_SET_PTRACER 0x59616d61\n#define PR_SET_PTRACER_ANY (-1UL)\n\n#define PR_SET_CHILD_SUBREAPER  36\n#define PR_GET_CHILD_SUBREAPER  37\n\n#define PR_SET_NO_NEW_PRIVS     38\n#define PR_GET_NO_NEW_PRIVS     39\n\n#define PR_GET_TID_ADDRESS      40\n\n#define PR_SET_THP_DISABLE      41\n#define PR_GET_THP_DISABLE      42\n\n#define PR_MPX_ENABLE_MANAGEMENT  43\n#define PR_MPX_DISABLE_MANAGEMENT 44\n\n#define PR_SET_FP_MODE          45\n#define PR_GET_FP_MODE          46\n#define PR_FP_MODE_FR (1 << 0)\n#define PR_FP_MODE_FRE (1 << 1)\n\n#define PR_CAP_AMBIENT          47\n#define PR_CAP_AMBIENT_IS_SET   1\n#define PR_CAP_AMBIENT_RAISE    2\n#define PR_CAP_AMBIENT_LOWER    3\n#define PR_CAP_AMBIENT_CLEAR_ALL 4\n\n#define PR_SVE_SET_VL           50\n#define PR_SVE_SET_VL_ONEXEC (1 << 18)\n#define PR_SVE_GET_VL           51\n#define PR_SVE_VL_LEN_MASK 0xffff\n#define PR_SVE_VL_INHERIT (1 << 17)\n\n#define PR_GET_SPECULATION_CTRL 52\n#define PR_SET_SPECULATION_CTRL 53\n#define PR_SPEC_STORE_BYPASS 0\n#define PR_SPEC_INDIRECT_BRANCH 1\n#define PR_SPEC_NOT_AFFECTED 0\n#define PR_SPEC_PRCTL (1UL << 0)\n#define PR_SPEC_ENABLE (1UL << 1)\n#define PR_SPEC_DISABLE (1UL << 2)\n#define PR_SPEC_FORCE_DISABLE (1UL << 3)\n#define PR_SPEC_DISABLE_NOEXEC (1UL << 4)\n\n#define PR_PAC_RESET_KEYS       54\n#define PR_PAC_APIAKEY (1UL << 0)\n#define PR_PAC_APIBKEY (1UL << 1)\n#define PR_PAC_APDAKEY (1UL << 2)\n#define PR_PAC_APDBKEY (1UL << 3)\n#define PR_PAC_APGAKEY (1UL << 4)\n\n#define PR_SET_TAGGED_ADDR_CTRL 55\n#define PR_GET_TAGGED_ADDR_CTRL 56\n#define PR_TAGGED_ADDR_ENABLE (1UL << 0)\n\n#define PR_SET_IO_FLUSHER 57\n#define PR_GET_IO_FLUSHER 58\n\nint prctl (int, ...);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/procfs.h",
    "content": "#ifndef _SYS_PROCFS_H\n#define _SYS_PROCFS_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <sys/time.h>\n#include <sys/types.h>\n#include <sys/user.h>\n\nstruct elf_siginfo {\n\tint si_signo;\n\tint si_code;\n\tint si_errno;\n};\n\nstruct elf_prstatus {\n\tstruct elf_siginfo pr_info;\n\tshort int pr_cursig;\n\tunsigned long int pr_sigpend;\n\tunsigned long int pr_sighold;\n\tpid_t pr_pid;\n\tpid_t pr_ppid;\n\tpid_t pr_pgrp;\n\tpid_t pr_sid;\n\tstruct {\n\t\tlong tv_sec, tv_usec;\n\t} pr_utime, pr_stime, pr_cutime, pr_cstime;\n\telf_gregset_t pr_reg;\n\tint pr_fpvalid;\n};\n\n#define ELF_PRARGSZ 80\n\nstruct elf_prpsinfo {\n\tchar pr_state;\n\tchar pr_sname;\n\tchar pr_zomb;\n\tchar pr_nice;\n\tunsigned long int pr_flag;\n#if UINTPTR_MAX == 0xffffffff\n\tunsigned short int pr_uid;\n\tunsigned short int pr_gid;\n#else\n\tunsigned int pr_uid;\n\tunsigned int pr_gid;\n#endif\n\tint pr_pid, pr_ppid, pr_pgrp, pr_sid;\n\tchar pr_fname[16];\n\tchar pr_psargs[ELF_PRARGSZ];\n};\n\ntypedef void *psaddr_t;\ntypedef elf_gregset_t prgregset_t;\ntypedef elf_fpregset_t prfpregset_t;\ntypedef pid_t lwpid_t;\ntypedef struct elf_prstatus prstatus_t;\ntypedef struct elf_prpsinfo prpsinfo_t;\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/ptrace.h",
    "content": "#ifndef _SYS_PTRACE_H\n#define _SYS_PTRACE_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\n#define PTRACE_TRACEME 0\n#define PT_TRACE_ME PTRACE_TRACEME\n\n#define PTRACE_PEEKTEXT 1\n#define PTRACE_PEEKDATA 2\n#define PTRACE_PEEKUSER 3\n#define PTRACE_POKETEXT 4\n#define PTRACE_POKEDATA 5\n#define PTRACE_POKEUSER 6\n#define PTRACE_CONT 7\n#define PTRACE_KILL 8\n#define PTRACE_SINGLESTEP 9\n#define PTRACE_GETREGS 12\n#define PTRACE_SETREGS 13\n#define PTRACE_GETFPREGS 14\n#define PTRACE_SETFPREGS 15\n#define PTRACE_ATTACH 16\n#define PTRACE_DETACH 17\n#define PTRACE_GETFPXREGS 18\n#define PTRACE_SETFPXREGS 19\n#define PTRACE_SYSCALL 24\n#define PTRACE_SETOPTIONS 0x4200\n#define PTRACE_GETEVENTMSG 0x4201\n#define PTRACE_GETSIGINFO 0x4202\n#define PTRACE_SETSIGINFO 0x4203\n#define PTRACE_GETREGSET 0x4204\n#define PTRACE_SETREGSET 0x4205\n#define PTRACE_SEIZE 0x4206\n#define PTRACE_INTERRUPT 0x4207\n#define PTRACE_LISTEN 0x4208\n#define PTRACE_PEEKSIGINFO 0x4209\n#define PTRACE_GETSIGMASK 0x420a\n#define PTRACE_SETSIGMASK 0x420b\n#define PTRACE_SECCOMP_GET_FILTER 0x420c\n#define PTRACE_SECCOMP_GET_METADATA 0x420d\n#define PTRACE_GET_SYSCALL_INFO 0x420e\n\n#define PT_READ_I PTRACE_PEEKTEXT\n#define PT_READ_D PTRACE_PEEKDATA\n#define PT_READ_U PTRACE_PEEKUSER\n#define PT_WRITE_I PTRACE_POKETEXT\n#define PT_WRITE_D PTRACE_POKEDATA\n#define PT_WRITE_U PTRACE_POKEUSER\n#define PT_CONTINUE PTRACE_CONT\n#define PT_KILL PTRACE_KILL\n#define PT_STEP PTRACE_SINGLESTEP\n#define PT_GETREGS PTRACE_GETREGS\n#define PT_SETREGS PTRACE_SETREGS\n#define PT_GETFPREGS PTRACE_GETFPREGS\n#define PT_SETFPREGS PTRACE_SETFPREGS\n#define PT_ATTACH PTRACE_ATTACH\n#define PT_DETACH PTRACE_DETACH\n#define PT_GETFPXREGS PTRACE_GETFPXREGS\n#define PT_SETFPXREGS PTRACE_SETFPXREGS\n#define PT_SYSCALL PTRACE_SYSCALL\n#define PT_SETOPTIONS PTRACE_SETOPTIONS\n#define PT_GETEVENTMSG PTRACE_GETEVENTMSG\n#define PT_GETSIGINFO PTRACE_GETSIGINFO\n#define PT_SETSIGINFO PTRACE_SETSIGINFO\n\n#define PTRACE_O_TRACESYSGOOD   0x00000001\n#define PTRACE_O_TRACEFORK      0x00000002\n#define PTRACE_O_TRACEVFORK     0x00000004\n#define PTRACE_O_TRACECLONE     0x00000008\n#define PTRACE_O_TRACEEXEC      0x00000010\n#define PTRACE_O_TRACEVFORKDONE 0x00000020\n#define PTRACE_O_TRACEEXIT      0x00000040\n#define PTRACE_O_TRACESECCOMP   0x00000080\n#define PTRACE_O_EXITKILL       0x00100000\n#define PTRACE_O_SUSPEND_SECCOMP 0x00200000\n#define PTRACE_O_MASK           0x003000ff\n\n#define PTRACE_EVENT_FORK 1\n#define PTRACE_EVENT_VFORK 2\n#define PTRACE_EVENT_CLONE 3\n#define PTRACE_EVENT_EXEC 4\n#define PTRACE_EVENT_VFORK_DONE 5\n#define PTRACE_EVENT_EXIT 6\n#define PTRACE_EVENT_SECCOMP 7\n#define PTRACE_EVENT_STOP 128\n\n#define PTRACE_PEEKSIGINFO_SHARED 1\n\n#define PTRACE_SYSCALL_INFO_NONE 0\n#define PTRACE_SYSCALL_INFO_ENTRY 1\n#define PTRACE_SYSCALL_INFO_EXIT 2\n#define PTRACE_SYSCALL_INFO_SECCOMP 3\n\n#include <bits/ptrace.h>\n\nstruct __ptrace_peeksiginfo_args {\n\tuint64_t off;\n\tuint32_t flags;\n\tint32_t nr;\n};\n\nstruct __ptrace_seccomp_metadata {\n\tuint64_t filter_off;\n\tuint64_t flags;\n};\n\nstruct __ptrace_syscall_info {\n\tuint8_t op;\n\tuint8_t __pad[3];\n\tuint32_t arch;\n\tuint64_t instruction_pointer;\n\tuint64_t stack_pointer;\n\tunion {\n\t\tstruct {\n\t\t\tuint64_t nr;\n\t\t\tuint64_t args[6];\n\t\t} entry;\n\t\tstruct {\n\t\t\tint64_t rval;\n\t\t\tuint8_t is_error;\n\t\t} exit;\n\t\tstruct {\n\t\t\tuint64_t nr;\n\t\t\tuint64_t args[6];\n\t\t\tuint32_t ret_data;\n\t\t} seccomp;\n\t};\n};\n\nlong ptrace(int, ...);\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/quota.h",
    "content": "#ifndef _SYS_QUOTA_H\n#define _SYS_QUOTA_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\n#define _LINUX_QUOTA_VERSION 2\n\n#define dbtob(num) ((num) << 10)\n#define btodb(num) ((num) >> 10)\n#define fs_to_dq_blocks(num, blksize) (((num) * (blksize)) / 1024)\n\n#define MAX_IQ_TIME 604800\n#define MAX_DQ_TIME 604800\n\n#define MAXQUOTAS 2\n#define USRQUOTA  0\n#define GRPQUOTA  1\n\n#define INITQFNAMES { \"user\", \"group\", \"undefined\" };\n\n#define QUOTAFILENAME \"quota\"\n#define QUOTAGROUP \"staff\"\n\n#define NR_DQHASH 43\n#define NR_DQUOTS 256\n\n#define SUBCMDMASK       0x00ff\n#define SUBCMDSHIFT      8\n#define QCMD(cmd, type)  (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK))\n\n#define Q_SYNC     0x800001\n#define Q_QUOTAON  0x800002\n#define Q_QUOTAOFF 0x800003\n#define Q_GETFMT   0x800004\n#define Q_GETINFO  0x800005\n#define Q_SETINFO  0x800006\n#define Q_GETQUOTA 0x800007\n#define Q_SETQUOTA 0x800008\n\n#define\tQFMT_VFS_OLD 1\n#define\tQFMT_VFS_V0 2\n#define QFMT_OCFS2 3\n#define\tQFMT_VFS_V1 4\n\n#define QIF_BLIMITS\t1\n#define QIF_SPACE\t2\n#define QIF_ILIMITS\t4\n#define QIF_INODES\t8\n#define QIF_BTIME\t16\n#define QIF_ITIME\t32\n#define QIF_LIMITS\t(QIF_BLIMITS | QIF_ILIMITS)\n#define QIF_USAGE\t(QIF_SPACE | QIF_INODES)\n#define QIF_TIMES\t(QIF_BTIME | QIF_ITIME)\n#define QIF_ALL\t\t(QIF_LIMITS | QIF_USAGE | QIF_TIMES)\n\nstruct dqblk {\n\tuint64_t dqb_bhardlimit;\n\tuint64_t dqb_bsoftlimit;\n\tuint64_t dqb_curspace;\n\tuint64_t dqb_ihardlimit;\n\tuint64_t dqb_isoftlimit;\n\tuint64_t dqb_curinodes;\n\tuint64_t dqb_btime;\n\tuint64_t dqb_itime;\n\tuint32_t dqb_valid;\n};\n\n#define\tdq_bhardlimit\tdq_dqb.dqb_bhardlimit\n#define\tdq_bsoftlimit\tdq_dqb.dqb_bsoftlimit\n#define dq_curspace\tdq_dqb.dqb_curspace\n#define dq_valid\tdq_dqb.dqb_valid\n#define\tdq_ihardlimit\tdq_dqb.dqb_ihardlimit\n#define\tdq_isoftlimit\tdq_dqb.dqb_isoftlimit\n#define\tdq_curinodes\tdq_dqb.dqb_curinodes\n#define\tdq_btime\tdq_dqb.dqb_btime\n#define\tdq_itime\tdq_dqb.dqb_itime\n\n#define dqoff(UID)      ((long long)(UID) * sizeof (struct dqblk))\n\n#define IIF_BGRACE\t1\n#define IIF_IGRACE\t2\n#define IIF_FLAGS\t4\n#define IIF_ALL\t\t(IIF_BGRACE | IIF_IGRACE | IIF_FLAGS)\n\nstruct dqinfo {\n\tuint64_t dqi_bgrace;\n\tuint64_t dqi_igrace;\n\tuint32_t dqi_flags;\n\tuint32_t dqi_valid;\n};\n\nint quotactl(int, const char *, int, char *);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/random.h",
    "content": "#ifndef _SYS_RANDOM_H\n#define _SYS_RANDOM_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define __NEED_size_t\n#define __NEED_ssize_t\n#include <bits/alltypes.h>\n\n#define GRND_NONBLOCK\t0x0001\n#define GRND_RANDOM\t0x0002\n#define GRND_INSECURE\t0x0004\n\nssize_t getrandom(void *, size_t, unsigned);\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/reboot.h",
    "content": "#ifndef _SYS_REBOOT_H\n#define _SYS_REBOOT_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define RB_AUTOBOOT     0x01234567\n#define RB_HALT_SYSTEM  0xcdef0123\n#define RB_ENABLE_CAD   0x89abcdef\n#define RB_DISABLE_CAD  0\n#define RB_POWER_OFF    0x4321fedc\n#define RB_SW_SUSPEND   0xd000fce2\n#define RB_KEXEC        0x45584543\n\nint reboot(int);\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/reg.h",
    "content": "#ifndef _SYS_REG_H\n#define _SYS_REG_H\n\n#include <limits.h>\n#include <unistd.h>\n\n#include <bits/reg.h>\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/resource.h",
    "content": "#ifndef\t_SYS_RESOURCE_H\n#define\t_SYS_RESOURCE_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n#include <sys/time.h>\n\n#define __NEED_id_t\n\n#ifdef _GNU_SOURCE\n#define __NEED_pid_t\n#endif\n\n#include <bits/alltypes.h>\n#include <bits/resource.h>\n\ntypedef unsigned long long rlim_t;\n\nstruct rlimit {\n\trlim_t rlim_cur;\n\trlim_t rlim_max;\n};\n\nstruct rusage {\n\tstruct timeval ru_utime;\n\tstruct timeval ru_stime;\n\t/* linux extentions, but useful */\n\tlong\tru_maxrss;\n\tlong\tru_ixrss;\n\tlong\tru_idrss;\n\tlong\tru_isrss;\n\tlong\tru_minflt;\n\tlong\tru_majflt;\n\tlong\tru_nswap;\n\tlong\tru_inblock;\n\tlong\tru_oublock;\n\tlong\tru_msgsnd;\n\tlong\tru_msgrcv;\n\tlong\tru_nsignals;\n\tlong\tru_nvcsw;\n\tlong\tru_nivcsw;\n\t/* room for more... */\n\tlong    __reserved[16];\n};\n\nint getrlimit (int, struct rlimit *);\nint setrlimit (int, const struct rlimit *);\nint getrusage (int, struct rusage *);\n\nint getpriority (int, id_t);\nint setpriority (int, id_t, int);\n\n#ifdef _GNU_SOURCE\nint prlimit(pid_t, int, const struct rlimit *, struct rlimit *);\n#define prlimit64 prlimit\n#endif\n\n#define PRIO_MIN (-20)\n#define PRIO_MAX 20\n\n#define PRIO_PROCESS 0\n#define PRIO_PGRP    1\n#define PRIO_USER    2\n\n#define RUSAGE_SELF     0\n#define RUSAGE_CHILDREN (-1)\n#define RUSAGE_THREAD   1\n\n#define RLIM_INFINITY (~0ULL)\n#define RLIM_SAVED_CUR RLIM_INFINITY\n#define RLIM_SAVED_MAX RLIM_INFINITY\n\n#define RLIMIT_CPU     0\n#define RLIMIT_FSIZE   1\n#define RLIMIT_DATA    2\n#define RLIMIT_STACK   3\n#define RLIMIT_CORE    4\n#ifndef RLIMIT_RSS\n#define RLIMIT_RSS     5\n#define RLIMIT_NPROC   6\n#define RLIMIT_NOFILE  7\n#define RLIMIT_MEMLOCK 8\n#define RLIMIT_AS      9\n#endif\n#define RLIMIT_LOCKS   10\n#define RLIMIT_SIGPENDING 11\n#define RLIMIT_MSGQUEUE 12\n#define RLIMIT_NICE    13\n#define RLIMIT_RTPRIO  14\n#define RLIMIT_RTTIME  15\n#define RLIMIT_NLIMITS 16\n\n#define RLIM_NLIMITS RLIMIT_NLIMITS\n\n#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)\n#define RLIM64_INFINITY RLIM_INFINITY\n#define RLIM64_SAVED_CUR RLIM_SAVED_CUR\n#define RLIM64_SAVED_MAX RLIM_SAVED_MAX\n#define getrlimit64 getrlimit\n#define setrlimit64 setrlimit\n#define rlimit64 rlimit\n#define rlim64_t rlim_t\n#endif\n\n#if _REDIR_TIME64\n__REDIR(getrusage, __getrusage_time64);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/select.h",
    "content": "#ifndef _SYS_SELECT_H\n#define _SYS_SELECT_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_size_t\n#define __NEED_time_t\n#define __NEED_suseconds_t\n#define __NEED_struct_timeval\n#define __NEED_struct_timespec\n#define __NEED_sigset_t\n\n#include <bits/alltypes.h>\n\n#define FD_SETSIZE 1024\n\ntypedef unsigned long fd_mask;\n\ntypedef struct {\n\tunsigned long fds_bits[FD_SETSIZE / 8 / sizeof(long)];\n} fd_set;\n\n#define FD_ZERO(s) do { int __i; unsigned long *__b=(s)->fds_bits; for(__i=sizeof (fd_set)/sizeof (long); __i; __i--) *__b++=0; } while(0)\n#define FD_SET(d, s)   ((s)->fds_bits[(d)/(8*sizeof(long))] |= (1UL<<((d)%(8*sizeof(long)))))\n#define FD_CLR(d, s)   ((s)->fds_bits[(d)/(8*sizeof(long))] &= ~(1UL<<((d)%(8*sizeof(long)))))\n#define FD_ISSET(d, s) !!((s)->fds_bits[(d)/(8*sizeof(long))] & (1UL<<((d)%(8*sizeof(long)))))\n\nint select (int, fd_set *__restrict, fd_set *__restrict, fd_set *__restrict, struct timeval *__restrict);\nint pselect (int, fd_set *__restrict, fd_set *__restrict, fd_set *__restrict, const struct timespec *__restrict, const sigset_t *__restrict);\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define NFDBITS (8*(int)sizeof(long))\n#endif\n\n#if _REDIR_TIME64\n__REDIR(select, __select_time64);\n__REDIR(pselect, __pselect_time64);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/sem.h",
    "content": "#ifndef _SYS_SEM_H\n#define _SYS_SEM_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_size_t\n#define __NEED_pid_t\n#define __NEED_time_t\n#ifdef _GNU_SOURCE\n#define __NEED_struct_timespec\n#endif\n#include <bits/alltypes.h>\n\n#include <sys/ipc.h>\n\n#define SEM_UNDO\t0x1000\n#define GETPID\t\t11\n#define GETVAL\t\t12\n#define GETALL\t\t13\n#define GETNCNT\t\t14\n#define GETZCNT\t\t15\n#define SETVAL\t\t16\n#define SETALL\t\t17\n\n#include <bits/sem.h>\n\n#define _SEM_SEMUN_UNDEFINED 1\n\n#define SEM_STAT (18 | (IPC_STAT & 0x100))\n#define SEM_INFO 19\n#define SEM_STAT_ANY (20 | (IPC_STAT & 0x100))\n\nstruct  seminfo {\n\tint semmap;\n\tint semmni;\n\tint semmns;\n\tint semmnu;\n\tint semmsl;\n\tint semopm;\n\tint semume;\n\tint semusz;\n\tint semvmx;\n\tint semaem;\n};\n\nstruct sembuf {\n\tunsigned short sem_num;\n\tshort sem_op;\n\tshort sem_flg;\n};\n\nint semctl(int, int, int, ...);\nint semget(key_t, int, int);\nint semop(int, struct sembuf *, size_t);\n\n#ifdef _GNU_SOURCE\nint semtimedop(int, struct sembuf *, size_t, const struct timespec *);\n#endif\n\n#if _REDIR_TIME64\n#ifdef _GNU_SOURCE\n__REDIR(semtimedop, __semtimedop_time64);\n#endif\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/sendfile.h",
    "content": "#ifndef _SYS_SENDFILE_H\n#define _SYS_SENDFILE_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n#include <unistd.h>\n\nssize_t sendfile(int, int, off_t *, size_t);\n\n#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)\n#define sendfile64 sendfile\n#define off64_t off_t\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/shm.h",
    "content": "#ifndef _SYS_SHM_H\n#define _SYS_SHM_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_time_t\n#define __NEED_size_t\n#define __NEED_pid_t\n\n#include <bits/alltypes.h>\n\n#include <sys/ipc.h>\n\n#ifdef _GNU_SOURCE\n#define __used_ids used_ids\n#define __swap_attempts swap_attempts\n#define __swap_successes swap_successes\n#endif\n\n#include <bits/shm.h>\n\n#define SHM_R 0400\n#define SHM_W 0200\n\n#define SHM_RDONLY 010000\n#define SHM_RND    020000\n#define SHM_REMAP  040000\n#define SHM_EXEC   0100000\n\n#define SHM_LOCK 11\n#define SHM_UNLOCK 12\n#define SHM_STAT (13 | (IPC_STAT & 0x100))\n#define SHM_INFO 14\n#define SHM_STAT_ANY (15 | (IPC_STAT & 0x100))\n#define SHM_DEST 01000\n#define SHM_LOCKED 02000\n#define SHM_HUGETLB 04000\n#define SHM_NORESERVE 010000\n\n#define SHM_HUGE_SHIFT 26\n#define SHM_HUGE_MASK  0x3f\n#define SHM_HUGE_64KB  (16 << 26)\n#define SHM_HUGE_512KB (19 << 26)\n#define SHM_HUGE_1MB   (20 << 26)\n#define SHM_HUGE_2MB   (21 << 26)\n#define SHM_HUGE_8MB   (23 << 26)\n#define SHM_HUGE_16MB  (24 << 26)\n#define SHM_HUGE_32MB  (25 << 26)\n#define SHM_HUGE_256MB (28 << 26)\n#define SHM_HUGE_512MB (29 << 26)\n#define SHM_HUGE_1GB   (30 << 26)\n#define SHM_HUGE_2GB   (31 << 26)\n#define SHM_HUGE_16GB  (34U << 26)\n\ntypedef unsigned long shmatt_t;\n\nvoid *shmat(int, const void *, int);\nint shmctl(int, int, struct shmid_ds *);\nint shmdt(const void *);\nint shmget(key_t, size_t, int);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/signal.h",
    "content": "#warning redirecting incorrect #include <sys/signal.h> to <signal.h>\n#include <signal.h>\n"
  },
  {
    "path": "user.libc/include/sys/signalfd.h",
    "content": "#ifndef _SYS_SIGNALFD_H\n#define _SYS_SIGNALFD_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n#include <fcntl.h>\n\n#define __NEED_sigset_t\n\n#include <bits/alltypes.h>\n\n#define SFD_CLOEXEC O_CLOEXEC\n#define SFD_NONBLOCK O_NONBLOCK\n\nint signalfd(int, const sigset_t *, int);\n\nstruct signalfd_siginfo {\n\tuint32_t  ssi_signo;\n\tint32_t   ssi_errno;\n\tint32_t   ssi_code;\n\tuint32_t  ssi_pid;\n\tuint32_t  ssi_uid;\n\tint32_t   ssi_fd;\n\tuint32_t  ssi_tid;\n\tuint32_t  ssi_band;\n\tuint32_t  ssi_overrun;\n\tuint32_t  ssi_trapno;\n\tint32_t   ssi_status;\n\tint32_t   ssi_int;\n\tuint64_t  ssi_ptr;\n\tuint64_t  ssi_utime;\n\tuint64_t  ssi_stime;\n\tuint64_t  ssi_addr;\n\tuint16_t  ssi_addr_lsb;\n\tuint16_t  __pad2;\n\tint32_t   ssi_syscall;\n\tuint64_t  ssi_call_addr;\n\tuint32_t  ssi_arch;\n\tuint8_t   __pad[128-14*4-5*8-2*2];\n};\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/socket.h",
    "content": "#ifndef\t_SYS_SOCKET_H\n#define\t_SYS_SOCKET_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_socklen_t\n#define __NEED_sa_family_t\n#define __NEED_size_t\n#define __NEED_ssize_t\n#define __NEED_uid_t\n#define __NEED_pid_t\n#define __NEED_gid_t\n#define __NEED_struct_iovec\n\n#include <bits/alltypes.h>\n\n#include <bits/socket.h>\n\nstruct msghdr {\n\tvoid *msg_name;\n\tsocklen_t msg_namelen;\n\tstruct iovec *msg_iov;\n#if __LONG_MAX > 0x7fffffff && __BYTE_ORDER == __BIG_ENDIAN\n\tint __pad1;\n#endif\n\tint msg_iovlen;\n#if __LONG_MAX > 0x7fffffff && __BYTE_ORDER == __LITTLE_ENDIAN\n\tint __pad1;\n#endif\n\tvoid *msg_control;\n#if __LONG_MAX > 0x7fffffff && __BYTE_ORDER == __BIG_ENDIAN\n\tint __pad2;\n#endif\n\tsocklen_t msg_controllen;\n#if __LONG_MAX > 0x7fffffff && __BYTE_ORDER == __LITTLE_ENDIAN\n\tint __pad2;\n#endif\n\tint msg_flags;\n};\n\nstruct cmsghdr {\n#if __LONG_MAX > 0x7fffffff && __BYTE_ORDER == __BIG_ENDIAN\n\tint __pad1;\n#endif\n\tsocklen_t cmsg_len;\n#if __LONG_MAX > 0x7fffffff && __BYTE_ORDER == __LITTLE_ENDIAN\n\tint __pad1;\n#endif\n\tint cmsg_level;\n\tint cmsg_type;\n};\n\n#ifdef _GNU_SOURCE\nstruct ucred {\n\tpid_t pid;\n\tuid_t uid;\n\tgid_t gid;\n};\n\nstruct mmsghdr {\n\tstruct msghdr msg_hdr;\n\tunsigned int  msg_len;\n};\n\nstruct timespec;\n\nint sendmmsg (int, struct mmsghdr *, unsigned int, unsigned int);\nint recvmmsg (int, struct mmsghdr *, unsigned int, unsigned int, struct timespec *);\n#endif\n\nstruct linger {\n\tint l_onoff;\n\tint l_linger;\n};\n\n#define SHUT_RD 0\n#define SHUT_WR 1\n#define SHUT_RDWR 2\n\n#ifndef SOCK_STREAM\n#define SOCK_STREAM    1\n#define SOCK_DGRAM     2\n#endif\n\n#define SOCK_RAW       3\n#define SOCK_RDM       4\n#define SOCK_SEQPACKET 5\n#define SOCK_DCCP      6\n#define SOCK_PACKET    10\n\n#ifndef SOCK_CLOEXEC\n#define SOCK_CLOEXEC   02000000\n#define SOCK_NONBLOCK  04000\n#endif\n\n#define PF_UNSPEC       0\n#define PF_LOCAL        1\n#define PF_UNIX         PF_LOCAL\n#define PF_FILE         PF_LOCAL\n#define PF_INET         2\n#define PF_AX25         3\n#define PF_IPX          4\n#define PF_APPLETALK    5\n#define PF_NETROM       6\n#define PF_BRIDGE       7\n#define PF_ATMPVC       8\n#define PF_X25          9\n#define PF_INET6        10\n#define PF_ROSE         11\n#define PF_DECnet       12\n#define PF_NETBEUI      13\n#define PF_SECURITY     14\n#define PF_KEY          15\n#define PF_NETLINK      16\n#define PF_ROUTE        PF_NETLINK\n#define PF_PACKET       17\n#define PF_ASH          18\n#define PF_ECONET       19\n#define PF_ATMSVC       20\n#define PF_RDS          21\n#define PF_SNA          22\n#define PF_IRDA         23\n#define PF_PPPOX        24\n#define PF_WANPIPE      25\n#define PF_LLC          26\n#define PF_IB           27\n#define PF_MPLS         28\n#define PF_CAN          29\n#define PF_TIPC         30\n#define PF_BLUETOOTH    31\n#define PF_IUCV         32\n#define PF_RXRPC        33\n#define PF_ISDN         34\n#define PF_PHONET       35\n#define PF_IEEE802154   36\n#define PF_CAIF         37\n#define PF_ALG          38\n#define PF_NFC          39\n#define PF_VSOCK        40\n#define PF_KCM          41\n#define PF_QIPCRTR      42\n#define PF_SMC          43\n#define PF_XDP          44\n#define PF_MAX          45\n\n#define AF_UNSPEC       PF_UNSPEC\n#define AF_LOCAL        PF_LOCAL\n#define AF_UNIX         AF_LOCAL\n#define AF_FILE         AF_LOCAL\n#define AF_INET         PF_INET\n#define AF_AX25         PF_AX25\n#define AF_IPX          PF_IPX\n#define AF_APPLETALK    PF_APPLETALK\n#define AF_NETROM       PF_NETROM\n#define AF_BRIDGE       PF_BRIDGE\n#define AF_ATMPVC       PF_ATMPVC\n#define AF_X25          PF_X25\n#define AF_INET6        PF_INET6\n#define AF_ROSE         PF_ROSE\n#define AF_DECnet       PF_DECnet\n#define AF_NETBEUI      PF_NETBEUI\n#define AF_SECURITY     PF_SECURITY\n#define AF_KEY          PF_KEY\n#define AF_NETLINK      PF_NETLINK\n#define AF_ROUTE        PF_ROUTE\n#define AF_PACKET       PF_PACKET\n#define AF_ASH          PF_ASH\n#define AF_ECONET       PF_ECONET\n#define AF_ATMSVC       PF_ATMSVC\n#define AF_RDS          PF_RDS\n#define AF_SNA          PF_SNA\n#define AF_IRDA         PF_IRDA\n#define AF_PPPOX        PF_PPPOX\n#define AF_WANPIPE      PF_WANPIPE\n#define AF_LLC          PF_LLC\n#define AF_IB           PF_IB\n#define AF_MPLS         PF_MPLS\n#define AF_CAN          PF_CAN\n#define AF_TIPC         PF_TIPC\n#define AF_BLUETOOTH    PF_BLUETOOTH\n#define AF_IUCV         PF_IUCV\n#define AF_RXRPC        PF_RXRPC\n#define AF_ISDN         PF_ISDN\n#define AF_PHONET       PF_PHONET\n#define AF_IEEE802154   PF_IEEE802154\n#define AF_CAIF         PF_CAIF\n#define AF_ALG          PF_ALG\n#define AF_NFC          PF_NFC\n#define AF_VSOCK        PF_VSOCK\n#define AF_KCM          PF_KCM\n#define AF_QIPCRTR      PF_QIPCRTR\n#define AF_SMC          PF_SMC\n#define AF_XDP          PF_XDP\n#define AF_MAX          PF_MAX\n\n#ifndef SO_DEBUG\n#define SO_DEBUG        1\n#define SO_REUSEADDR    2\n#define SO_TYPE         3\n#define SO_ERROR        4\n#define SO_DONTROUTE    5\n#define SO_BROADCAST    6\n#define SO_SNDBUF       7\n#define SO_RCVBUF       8\n#define SO_KEEPALIVE    9\n#define SO_OOBINLINE    10\n#define SO_NO_CHECK     11\n#define SO_PRIORITY     12\n#define SO_LINGER       13\n#define SO_BSDCOMPAT    14\n#define SO_REUSEPORT    15\n#define SO_PASSCRED     16\n#define SO_PEERCRED     17\n#define SO_RCVLOWAT     18\n#define SO_SNDLOWAT     19\n#define SO_ACCEPTCONN   30\n#define SO_PEERSEC      31\n#define SO_SNDBUFFORCE  32\n#define SO_RCVBUFFORCE  33\n#define SO_PROTOCOL     38\n#define SO_DOMAIN       39\n#endif\n\n#ifndef SO_RCVTIMEO\n#if __LONG_MAX == 0x7fffffff\n#define SO_RCVTIMEO     66\n#define SO_SNDTIMEO     67\n#else\n#define SO_RCVTIMEO     20\n#define SO_SNDTIMEO     21\n#endif\n#endif\n\n#ifndef SO_TIMESTAMP\n#if __LONG_MAX == 0x7fffffff\n#define SO_TIMESTAMP    63\n#define SO_TIMESTAMPNS  64\n#define SO_TIMESTAMPING 65\n#else\n#define SO_TIMESTAMP    29\n#define SO_TIMESTAMPNS  35\n#define SO_TIMESTAMPING 37\n#endif\n#endif\n\n#define SO_SECURITY_AUTHENTICATION              22\n#define SO_SECURITY_ENCRYPTION_TRANSPORT        23\n#define SO_SECURITY_ENCRYPTION_NETWORK          24\n\n#define SO_BINDTODEVICE 25\n\n#define SO_ATTACH_FILTER        26\n#define SO_DETACH_FILTER        27\n#define SO_GET_FILTER           SO_ATTACH_FILTER\n\n#define SO_PEERNAME             28\n#define SCM_TIMESTAMP           SO_TIMESTAMP\n#define SO_PASSSEC              34\n#define SCM_TIMESTAMPNS         SO_TIMESTAMPNS\n#define SO_MARK                 36\n#define SCM_TIMESTAMPING        SO_TIMESTAMPING\n#define SO_RXQ_OVFL             40\n#define SO_WIFI_STATUS          41\n#define SCM_WIFI_STATUS         SO_WIFI_STATUS\n#define SO_PEEK_OFF             42\n#define SO_NOFCS                43\n#define SO_LOCK_FILTER          44\n#define SO_SELECT_ERR_QUEUE     45\n#define SO_BUSY_POLL            46\n#define SO_MAX_PACING_RATE      47\n#define SO_BPF_EXTENSIONS       48\n#define SO_INCOMING_CPU         49\n#define SO_ATTACH_BPF           50\n#define SO_DETACH_BPF           SO_DETACH_FILTER\n#define SO_ATTACH_REUSEPORT_CBPF 51\n#define SO_ATTACH_REUSEPORT_EBPF 52\n#define SO_CNX_ADVICE           53\n#define SCM_TIMESTAMPING_OPT_STATS 54\n#define SO_MEMINFO              55\n#define SO_INCOMING_NAPI_ID     56\n#define SO_COOKIE               57\n#define SCM_TIMESTAMPING_PKTINFO 58\n#define SO_PEERGROUPS           59\n#define SO_ZEROCOPY             60\n#define SO_TXTIME               61\n#define SCM_TXTIME              SO_TXTIME\n#define SO_BINDTOIFINDEX        62\n#define SO_DETACH_REUSEPORT_BPF 68\n\n#ifndef SOL_SOCKET\n#define SOL_SOCKET      1\n#endif\n\n#define SOL_IP          0\n#define SOL_IPV6        41\n#define SOL_ICMPV6      58\n\n#define SOL_RAW         255\n#define SOL_DECNET      261\n#define SOL_X25         262\n#define SOL_PACKET      263\n#define SOL_ATM         264\n#define SOL_AAL         265\n#define SOL_IRDA        266\n#define SOL_NETBEUI     267\n#define SOL_LLC         268\n#define SOL_DCCP        269\n#define SOL_NETLINK     270\n#define SOL_TIPC        271\n#define SOL_RXRPC       272\n#define SOL_PPPOL2TP    273\n#define SOL_BLUETOOTH   274\n#define SOL_PNPIPE      275\n#define SOL_RDS         276\n#define SOL_IUCV        277\n#define SOL_CAIF        278\n#define SOL_ALG         279\n#define SOL_NFC         280\n#define SOL_KCM         281\n#define SOL_TLS         282\n#define SOL_XDP         283\n\n#define SOMAXCONN       128\n\n#define MSG_OOB       0x0001\n#define MSG_PEEK      0x0002\n#define MSG_DONTROUTE 0x0004\n#define MSG_CTRUNC    0x0008\n#define MSG_PROXY     0x0010\n#define MSG_TRUNC     0x0020\n#define MSG_DONTWAIT  0x0040\n#define MSG_EOR       0x0080\n#define MSG_WAITALL   0x0100\n#define MSG_FIN       0x0200\n#define MSG_SYN       0x0400\n#define MSG_CONFIRM   0x0800\n#define MSG_RST       0x1000\n#define MSG_ERRQUEUE  0x2000\n#define MSG_NOSIGNAL  0x4000\n#define MSG_MORE      0x8000\n#define MSG_WAITFORONE 0x10000\n#define MSG_BATCH     0x40000\n#define MSG_ZEROCOPY  0x4000000\n#define MSG_FASTOPEN  0x20000000\n#define MSG_CMSG_CLOEXEC 0x40000000\n\n#define __CMSG_LEN(cmsg) (((cmsg)->cmsg_len + sizeof(long) - 1) & ~(long)(sizeof(long) - 1))\n#define __CMSG_NEXT(cmsg) ((unsigned char *)(cmsg) + __CMSG_LEN(cmsg))\n#define __MHDR_END(mhdr) ((unsigned char *)(mhdr)->msg_control + (mhdr)->msg_controllen)\n\n#define CMSG_DATA(cmsg) ((unsigned char *) (((struct cmsghdr *)(cmsg)) + 1))\n#define CMSG_NXTHDR(mhdr, cmsg) ((cmsg)->cmsg_len < sizeof (struct cmsghdr) || \\\n\t__CMSG_LEN(cmsg) + sizeof(struct cmsghdr) >= __MHDR_END(mhdr) - (unsigned char *)(cmsg) \\\n\t? 0 : (struct cmsghdr *)__CMSG_NEXT(cmsg))\n#define CMSG_FIRSTHDR(mhdr) ((size_t) (mhdr)->msg_controllen >= sizeof (struct cmsghdr) ? (struct cmsghdr *) (mhdr)->msg_control : (struct cmsghdr *) 0)\n\n#define CMSG_ALIGN(len) (((len) + sizeof (size_t) - 1) & (size_t) ~(sizeof (size_t) - 1))\n#define CMSG_SPACE(len) (CMSG_ALIGN (len) + CMSG_ALIGN (sizeof (struct cmsghdr)))\n#define CMSG_LEN(len)   (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))\n\n#define SCM_RIGHTS      0x01\n#define SCM_CREDENTIALS 0x02\n\nstruct sockaddr {\n\tsa_family_t sa_family;\n\tchar sa_data[14];\n};\n\nstruct sockaddr_storage {\n\tsa_family_t ss_family;\n\tchar __ss_padding[128-sizeof(long)-sizeof(sa_family_t)];\n\tunsigned long __ss_align;\n};\n\nint socket (int, int, int);\nint socketpair (int, int, int, int [2]);\n\nint shutdown (int, int);\n\nint bind (int, const struct sockaddr *, socklen_t);\nint connect (int, const struct sockaddr *, socklen_t);\nint listen (int, int);\nint accept (int, struct sockaddr *__restrict, socklen_t *__restrict);\nint accept4(int, struct sockaddr *__restrict, socklen_t *__restrict, int);\n\nint getsockname (int, struct sockaddr *__restrict, socklen_t *__restrict);\nint getpeername (int, struct sockaddr *__restrict, socklen_t *__restrict);\n\nssize_t send (int, const void *, size_t, int);\nssize_t recv (int, void *, size_t, int);\nssize_t sendto (int, const void *, size_t, int, const struct sockaddr *, socklen_t);\nssize_t recvfrom (int, void *__restrict, size_t, int, struct sockaddr *__restrict, socklen_t *__restrict);\nssize_t sendmsg (int, const struct msghdr *, int);\nssize_t recvmsg (int, struct msghdr *, int);\n\nint getsockopt (int, int, int, void *__restrict, socklen_t *__restrict);\nint setsockopt (int, int, int, const void *, socklen_t);\n\nint sockatmark (int);\n\n#if _REDIR_TIME64\n#ifdef _GNU_SOURCE\n__REDIR(recvmmsg, __recvmmsg_time64);\n#endif\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/soundcard.h",
    "content": "#include <bits/soundcard.h>\n"
  },
  {
    "path": "user.libc/include/sys/stat.h",
    "content": "#ifndef\t_SYS_STAT_H\n#define\t_SYS_STAT_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_dev_t\n#define __NEED_ino_t\n#define __NEED_mode_t\n#define __NEED_nlink_t\n#define __NEED_uid_t\n#define __NEED_gid_t\n#define __NEED_off_t\n#define __NEED_time_t\n#define __NEED_blksize_t\n#define __NEED_blkcnt_t\n#define __NEED_struct_timespec\n\n#include <bits/alltypes.h>\n\n#include <bits/stat.h>\n\n#define st_atime st_atim.tv_sec\n#define st_mtime st_mtim.tv_sec\n#define st_ctime st_ctim.tv_sec\n\n#define S_IFMT  0170000\n\n#define S_IFDIR 0040000\n#define S_IFCHR 0020000\n#define S_IFBLK 0060000\n#define S_IFREG 0100000\n#define S_IFIFO 0010000\n#define S_IFLNK 0120000\n#define S_IFSOCK 0140000\n\n#define S_TYPEISMQ(buf)  0\n#define S_TYPEISSEM(buf) 0\n#define S_TYPEISSHM(buf) 0\n#define S_TYPEISTMO(buf) 0\n\n#define S_ISDIR(mode)  (((mode) & S_IFMT) == S_IFDIR)\n#define S_ISCHR(mode)  (((mode) & S_IFMT) == S_IFCHR)\n#define S_ISBLK(mode)  (((mode) & S_IFMT) == S_IFBLK)\n#define S_ISREG(mode)  (((mode) & S_IFMT) == S_IFREG)\n#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)\n#define S_ISLNK(mode)  (((mode) & S_IFMT) == S_IFLNK)\n#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)\n\n#ifndef S_IRUSR\n#define S_ISUID 04000\n#define S_ISGID 02000\n#define S_ISVTX 01000\n#define S_IRUSR 0400\n#define S_IWUSR 0200\n#define S_IXUSR 0100\n#define S_IRWXU 0700\n#define S_IRGRP 0040\n#define S_IWGRP 0020\n#define S_IXGRP 0010\n#define S_IRWXG 0070\n#define S_IROTH 0004\n#define S_IWOTH 0002\n#define S_IXOTH 0001\n#define S_IRWXO 0007\n#endif\n\n#define UTIME_NOW  0x3fffffff\n#define UTIME_OMIT 0x3ffffffe\n\nint stat(const char *__restrict, struct stat *__restrict);\nint fstat(int, struct stat *);\nint lstat(const char *__restrict, struct stat *__restrict);\nint fstatat(int, const char *__restrict, struct stat *__restrict, int);\nint chmod(const char *, mode_t);\nint fchmod(int, mode_t);\nint fchmodat(int, const char *, mode_t, int);\nmode_t umask(mode_t);\nint mkdir(const char *, mode_t);\nint mkfifo(const char *, mode_t);\nint mkdirat(int, const char *, mode_t);\nint mkfifoat(int, const char *, mode_t);\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\nint mknod(const char *, mode_t, dev_t);\nint mknodat(int, const char *, mode_t, dev_t);\n#endif\n\nint futimens(int, const struct timespec [2]);\nint utimensat(int, const char *, const struct timespec [2], int);\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\nint lchmod(const char *, mode_t);\n#define S_IREAD S_IRUSR\n#define S_IWRITE S_IWUSR\n#define S_IEXEC S_IXUSR\n#endif\n\n#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)\n#define stat64 stat\n#define fstat64 fstat\n#define lstat64 lstat\n#define fstatat64 fstatat\n#define blkcnt64_t blkcnt_t\n#define fsblkcnt64_t fsblkcnt_t\n#define fsfilcnt64_t fsfilcnt_t\n#define ino64_t ino_t\n#define off64_t off_t\n#endif\n\n#if _REDIR_TIME64\n__REDIR(stat, __stat_time64);\n__REDIR(fstat, __fstat_time64);\n__REDIR(lstat, __lstat_time64);\n__REDIR(fstatat, __fstatat_time64);\n__REDIR(futimens, __futimens_time64);\n__REDIR(utimensat, __utimensat_time64);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n\n\n"
  },
  {
    "path": "user.libc/include/sys/statfs.h",
    "content": "#ifndef\t_SYS_STATFS_H\n#define\t_SYS_STATFS_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#include <sys/statvfs.h>\n\ntypedef struct __fsid_t {\n\tint __val[2];\n} fsid_t;\n\n#include <bits/statfs.h>\n\nint statfs (const char *, struct statfs *);\nint fstatfs (int, struct statfs *);\n\n#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)\n#define statfs64 statfs\n#define fstatfs64 fstatfs\n#define fsblkcnt64_t fsblkcnt_t\n#define fsfilcnt64_t fsfilcnt_t\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/statvfs.h",
    "content": "#ifndef\t_SYS_STATVFS_H\n#define\t_SYS_STATVFS_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_fsblkcnt_t\n#define __NEED_fsfilcnt_t\n#include <bits/alltypes.h>\n\nstruct statvfs {\n\tunsigned long f_bsize, f_frsize;\n\tfsblkcnt_t f_blocks, f_bfree, f_bavail;\n\tfsfilcnt_t f_files, f_ffree, f_favail;\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n\tunsigned long f_fsid;\n\tunsigned :8*(2*sizeof(int)-sizeof(long));\n#else\n\tunsigned :8*(2*sizeof(int)-sizeof(long));\n\tunsigned long f_fsid;\n#endif\n\tunsigned long f_flag, f_namemax;\n\tint __reserved[6];\n};\n\nint statvfs (const char *__restrict, struct statvfs *__restrict);\nint fstatvfs (int, struct statvfs *);\n\n#define ST_RDONLY 1\n#define ST_NOSUID 2\n#define ST_NODEV  4\n#define ST_NOEXEC 8\n#define ST_SYNCHRONOUS 16\n#define ST_MANDLOCK    64\n#define ST_WRITE       128\n#define ST_APPEND      256\n#define ST_IMMUTABLE   512\n#define ST_NOATIME     1024\n#define ST_NODIRATIME  2048\n#define ST_RELATIME    4096\n\n#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)\n#define statvfs64 statvfs\n#define fstatvfs64 fstatvfs\n#define fsblkcnt64_t fsblkcnt_t\n#define fsfilcnt64_t fsfilcnt_t\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/stropts.h",
    "content": "#include <stropts.h>\n"
  },
  {
    "path": "user.libc/include/sys/swap.h",
    "content": "#ifndef _SYS_SWAP_H\n#define _SYS_SWAP_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n#define\tSWAP_FLAG_PREFER        0x8000\n#define\tSWAP_FLAG_PRIO_MASK     0x7fff\n#define\tSWAP_FLAG_PRIO_SHIFT    0\n#define SWAP_FLAG_DISCARD       0x10000\n\nint swapon (const char *, int);\nint swapoff (const char *);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/syscall.h",
    "content": "#ifndef _SYS_SYSCALL_H\n#define _SYS_SYSCALL_H\n\n#include <bits/syscall.h>\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/sysinfo.h",
    "content": "#ifndef _SYS_SYSINFO_H\n#define _SYS_SYSINFO_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define SI_LOAD_SHIFT 16\n\nstruct sysinfo {\n\tunsigned long uptime;\n\tunsigned long loads[3];\n\tunsigned long totalram;\n\tunsigned long freeram;\n\tunsigned long sharedram;\n\tunsigned long bufferram;\n\tunsigned long totalswap;\n\tunsigned long freeswap;\n\tunsigned short procs, pad;\n\tunsigned long totalhigh;\n\tunsigned long freehigh;\n\tunsigned mem_unit;\n\tchar __reserved[256];\n};\n\nint sysinfo (struct sysinfo *);\nint get_nprocs_conf (void);\nint get_nprocs (void);\nlong get_phys_pages (void);\nlong get_avphys_pages (void);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/syslog.h",
    "content": "#include <syslog.h>\n"
  },
  {
    "path": "user.libc/include/sys/sysmacros.h",
    "content": "#ifndef _SYS_SYSMACROS_H\n#define _SYS_SYSMACROS_H\n\n#define major(x) \\\n\t((unsigned)( (((x)>>31>>1) & 0xfffff000) | (((x)>>8) & 0x00000fff) ))\n#define minor(x) \\\n\t((unsigned)( (((x)>>12) & 0xffffff00) | ((x) & 0x000000ff) ))\n\n#define makedev(x,y) ( \\\n        (((x)&0xfffff000ULL) << 32) | \\\n\t(((x)&0x00000fffULL) << 8) | \\\n        (((y)&0xffffff00ULL) << 12) | \\\n\t(((y)&0x000000ffULL)) )\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/termios.h",
    "content": "#warning redirecting incorrect #include <sys/termios.h> to <termios.h>\n#include <termios.h>\n"
  },
  {
    "path": "user.libc/include/sys/time.h",
    "content": "#ifndef _SYS_TIME_H\n#define _SYS_TIME_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#include <sys/select.h>\n\nint gettimeofday (struct timeval *__restrict, void *__restrict);\n\n#define ITIMER_REAL    0\n#define ITIMER_VIRTUAL 1\n#define ITIMER_PROF    2\n\nstruct itimerval {\n\tstruct timeval it_interval;\n\tstruct timeval it_value;\n};\n\nint getitimer (int, struct itimerval *);\nint setitimer (int, const struct itimerval *__restrict, struct itimerval *__restrict);\nint utimes (const char *, const struct timeval [2]);\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\nstruct timezone {\n\tint tz_minuteswest;\n\tint tz_dsttime;\n};\nint futimes(int, const struct timeval [2]);\nint futimesat(int, const char *, const struct timeval [2]);\nint lutimes(const char *, const struct timeval [2]);\nint settimeofday(const struct timeval *, const struct timezone *);\nint adjtime (const struct timeval *, struct timeval *);\n#define timerisset(t) ((t)->tv_sec || (t)->tv_usec)\n#define timerclear(t) ((t)->tv_sec = (t)->tv_usec = 0)\n#define timercmp(s,t,op) ((s)->tv_sec == (t)->tv_sec ? \\\n\t(s)->tv_usec op (t)->tv_usec : (s)->tv_sec op (t)->tv_sec)\n#define timeradd(s,t,a) (void) ( (a)->tv_sec = (s)->tv_sec + (t)->tv_sec, \\\n\t((a)->tv_usec = (s)->tv_usec + (t)->tv_usec) >= 1000000 && \\\n\t((a)->tv_usec -= 1000000, (a)->tv_sec++) )\n#define timersub(s,t,a) (void) ( (a)->tv_sec = (s)->tv_sec - (t)->tv_sec, \\\n\t((a)->tv_usec = (s)->tv_usec - (t)->tv_usec) < 0 && \\\n\t((a)->tv_usec += 1000000, (a)->tv_sec--) )\n#endif\n\n#if defined(_GNU_SOURCE)\n#define TIMEVAL_TO_TIMESPEC(tv, ts) ( \\\n\t(ts)->tv_sec = (tv)->tv_sec, \\\n\t(ts)->tv_nsec = (tv)->tv_usec * 1000, \\\n\t(void)0 )\n#define TIMESPEC_TO_TIMEVAL(tv, ts) ( \\\n\t(tv)->tv_sec = (ts)->tv_sec, \\\n\t(tv)->tv_usec = (ts)->tv_nsec / 1000, \\\n\t(void)0 )\n#endif\n\n#if _REDIR_TIME64\n__REDIR(gettimeofday, __gettimeofday_time64);\n__REDIR(getitimer, __getitimer_time64);\n__REDIR(setitimer, __setitimer_time64);\n__REDIR(utimes, __utimes_time64);\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n__REDIR(futimes, __futimes_time64);\n__REDIR(futimesat, __futimesat_time64);\n__REDIR(lutimes, __lutimes_time64);\n__REDIR(settimeofday, __settimeofday_time64);\n__REDIR(adjtime, __adjtime64);\n#endif\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/timeb.h",
    "content": "#ifndef _SYS_TIMEB_H\n#define _SYS_TIMEB_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_time_t\n\n#include <bits/alltypes.h>\n\nstruct timeb {\n\ttime_t time;\n\tunsigned short millitm;\n\tshort timezone, dstflag;\n};\n\nint ftime(struct timeb *);\n\n#if _REDIR_TIME64\n__REDIR(ftime, __ftime64);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/timerfd.h",
    "content": "#ifndef _SYS_TIMERFD_H\n#define _SYS_TIMERFD_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <time.h>\n#include <fcntl.h>\n\n#define TFD_NONBLOCK O_NONBLOCK\n#define TFD_CLOEXEC O_CLOEXEC\n\n#define TFD_TIMER_ABSTIME 1\n#define TFD_TIMER_CANCEL_ON_SET (1 << 1)\n\nstruct itimerspec;\n\nint timerfd_create(int, int);\nint timerfd_settime(int, int, const struct itimerspec *, struct itimerspec *);\nint timerfd_gettime(int, struct itimerspec *);\n\n#if _REDIR_TIME64\n__REDIR(timerfd_settime, __timerfd_settime64);\n__REDIR(timerfd_gettime, __timerfd_gettime64);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/times.h",
    "content": "#ifndef\t_SYS_TIMES_H\n#define\t_SYS_TIMES_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define __NEED_clock_t\n#include <bits/alltypes.h>\n\nstruct tms {\n\tclock_t tms_utime;\n\tclock_t tms_stime;\n\tclock_t tms_cutime;\n\tclock_t tms_cstime;\n};\n\nclock_t times (struct tms *);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n\n"
  },
  {
    "path": "user.libc/include/sys/timex.h",
    "content": "#ifndef _SYS_TIMEX_H\n#define _SYS_TIMEX_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define __NEED_clockid_t\n\n#include <bits/alltypes.h>\n\n#include <sys/time.h>\n\nstruct ntptimeval {\n\tstruct timeval time;\n\tlong maxerror, esterror;\n};\n\nstruct timex {\n\tunsigned modes;\n\tlong offset, freq, maxerror, esterror;\n\tint status;\n\tlong constant, precision, tolerance;\n\tstruct timeval time;\n\tlong tick, ppsfreq, jitter;\n\tint shift;\n\tlong stabil, jitcnt, calcnt, errcnt, stbcnt;\n\tint tai;\n\tint __padding[11];\n};\n\n#define ADJ_OFFSET\t\t0x0001\n#define ADJ_FREQUENCY\t\t0x0002\n#define ADJ_MAXERROR\t\t0x0004\n#define ADJ_ESTERROR\t\t0x0008\n#define ADJ_STATUS\t\t0x0010\n#define ADJ_TIMECONST\t\t0x0020\n#define ADJ_TAI\t\t\t0x0080\n#define ADJ_SETOFFSET\t\t0x0100\n#define ADJ_MICRO\t\t0x1000\n#define ADJ_NANO\t\t0x2000\n#define ADJ_TICK\t\t0x4000\n#define ADJ_OFFSET_SINGLESHOT\t0x8001\n#define ADJ_OFFSET_SS_READ\t0xa001\n\n#define MOD_OFFSET\tADJ_OFFSET\n#define MOD_FREQUENCY\tADJ_FREQUENCY\n#define MOD_MAXERROR\tADJ_MAXERROR\n#define MOD_ESTERROR\tADJ_ESTERROR\n#define MOD_STATUS\tADJ_STATUS\n#define MOD_TIMECONST\tADJ_TIMECONST\n#define MOD_CLKB\tADJ_TICK\n#define MOD_CLKA\tADJ_OFFSET_SINGLESHOT\n#define MOD_TAI\t\tADJ_TAI\n#define MOD_MICRO\tADJ_MICRO\n#define MOD_NANO\tADJ_NANO\n\n#define STA_PLL\t\t0x0001\n#define STA_PPSFREQ\t0x0002\n#define STA_PPSTIME\t0x0004\n#define STA_FLL\t\t0x0008\n\n#define STA_INS\t\t0x0010\n#define STA_DEL\t\t0x0020\n#define STA_UNSYNC\t0x0040\n#define STA_FREQHOLD\t0x0080\n\n#define STA_PPSSIGNAL\t0x0100\n#define STA_PPSJITTER\t0x0200\n#define STA_PPSWANDER\t0x0400\n#define STA_PPSERROR\t0x0800\n\n#define STA_CLOCKERR\t0x1000\n#define STA_NANO\t0x2000\n#define STA_MODE\t0x4000\n#define STA_CLK\t\t0x8000\n\n#define STA_RONLY (STA_PPSSIGNAL | STA_PPSJITTER | STA_PPSWANDER | \\\n    STA_PPSERROR | STA_CLOCKERR | STA_NANO | STA_MODE | STA_CLK)\n\n#define TIME_OK\t\t0\n#define TIME_INS\t1\n#define TIME_DEL\t2\n#define TIME_OOP\t3\n#define TIME_WAIT\t4\n#define TIME_ERROR\t5\n#define TIME_BAD\tTIME_ERROR\n\n#define MAXTC\t\t6\n\nint adjtimex(struct timex *);\nint clock_adjtime(clockid_t, struct timex *);\n\n#if _REDIR_TIME64\n__REDIR(adjtimex, __adjtimex_time64);\n__REDIR(clock_adjtime, __clock_adjtime64);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/ttydefaults.h",
    "content": "#ifndef _SYS_TTYDEFAULTS_H\n#define _SYS_TTYDEFAULTS_H\n\n#define TTYDEF_IFLAG (BRKINT | ISTRIP | ICRNL | IMAXBEL | IXON | IXANY)\n#define TTYDEF_OFLAG (OPOST | ONLCR | XTABS)\n#define TTYDEF_LFLAG (ECHO | ICANON | ISIG | IEXTEN | ECHOE|ECHOKE|ECHOCTL)\n#define TTYDEF_CFLAG (CREAD | CS7 | PARENB | HUPCL)\n#define TTYDEF_SPEED (B9600)\n#define CTRL(x) ((x)&037)\n#define CEOF CTRL('d')\n\n#define CEOL '\\0'\n#define CSTATUS '\\0'\n\n#define CERASE 0177\n#define CINTR CTRL('c')\n#define CKILL CTRL('u')\n#define CMIN 1\n#define CQUIT 034\n#define CSUSP CTRL('z')\n#define CTIME 0\n#define CDSUSP CTRL('y')\n#define CSTART CTRL('q')\n#define CSTOP CTRL('s')\n#define CLNEXT CTRL('v')\n#define CDISCARD CTRL('o')\n#define CWERASE CTRL('w')\n#define CREPRINT CTRL('r')\n#define CEOT CEOF\n#define CBRK CEOL\n#define CRPRNT CREPRINT\n#define CFLUSH CDISCARD\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/types.h",
    "content": "#ifndef\t_SYS_TYPES_H\n#define\t_SYS_TYPES_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_ino_t\n#define __NEED_dev_t\n#define __NEED_uid_t\n#define __NEED_gid_t\n#define __NEED_mode_t\n#define __NEED_nlink_t\n#define __NEED_off_t\n#define __NEED_pid_t\n#define __NEED_size_t\n#define __NEED_ssize_t\n#define __NEED_time_t\n#define __NEED_timer_t\n#define __NEED_clockid_t\n\n#define __NEED_blkcnt_t\n#define __NEED_fsblkcnt_t\n#define __NEED_fsfilcnt_t\n\n#define __NEED_id_t\n#define __NEED_key_t\n#define __NEED_clock_t\n#define __NEED_suseconds_t\n#define __NEED_blksize_t\n\n#define __NEED_pthread_t\n#define __NEED_pthread_attr_t\n#define __NEED_pthread_mutexattr_t\n#define __NEED_pthread_condattr_t\n#define __NEED_pthread_rwlockattr_t\n#define __NEED_pthread_barrierattr_t\n#define __NEED_pthread_mutex_t\n#define __NEED_pthread_cond_t\n#define __NEED_pthread_rwlock_t\n#define __NEED_pthread_barrier_t\n#define __NEED_pthread_spinlock_t\n#define __NEED_pthread_key_t\n#define __NEED_pthread_once_t\n#define __NEED_useconds_t\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define __NEED_int8_t\n#define __NEED_int16_t\n#define __NEED_int32_t\n#define __NEED_int64_t\n#define __NEED_u_int64_t\n#define __NEED_register_t\n#endif\n\n#include <bits/alltypes.h>\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\ntypedef unsigned char u_int8_t;\ntypedef unsigned short u_int16_t;\ntypedef unsigned u_int32_t;\ntypedef char *caddr_t;\ntypedef unsigned char u_char;\ntypedef unsigned short u_short, ushort;\ntypedef unsigned u_int, uint;\ntypedef unsigned long u_long, ulong;\ntypedef long long quad_t;\ntypedef unsigned long long u_quad_t;\n#include <endian.h>\n#include <sys/select.h>\n#endif\n\n#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)\n#define blkcnt64_t blkcnt_t\n#define fsblkcnt64_t fsblkcnt_t\n#define fsfilcnt64_t fsfilcnt_t\n#define ino64_t ino_t\n#define off64_t off_t\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/ucontext.h",
    "content": "#include <ucontext.h>\n"
  },
  {
    "path": "user.libc/include/sys/uio.h",
    "content": "#ifndef _SYS_UIO_H\n#define _SYS_UIO_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_size_t\n#define __NEED_ssize_t\n#define __NEED_struct_iovec\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define __NEED_off_t\n#endif\n\n#ifdef _GNU_SOURCE\n#define __NEED_pid_t\n#endif\n\n#include <bits/alltypes.h>\n\n#define UIO_MAXIOV 1024\n\nssize_t readv (int, const struct iovec *, int);\nssize_t writev (int, const struct iovec *, int);\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\nssize_t preadv (int, const struct iovec *, int, off_t);\nssize_t pwritev (int, const struct iovec *, int, off_t);\n#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)\n#define preadv64 preadv\n#define pwritev64 pwritev\n#define off64_t off_t\n#endif\n#endif\n\n#ifdef _GNU_SOURCE\nssize_t process_vm_writev(pid_t, const struct iovec *, unsigned long, const struct iovec *, unsigned long, unsigned long);\nssize_t process_vm_readv(pid_t, const struct iovec *, unsigned long, const struct iovec *, unsigned long, unsigned long);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/un.h",
    "content": "#ifndef\t_SYS_UN_H\n#define\t_SYS_UN_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_sa_family_t\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define __NEED_size_t\n#endif\n\n#include <bits/alltypes.h>\n\nstruct sockaddr_un {\n\tsa_family_t sun_family;\n\tchar sun_path[108];\n};\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\nsize_t strlen(const char *);\n#define SUN_LEN(s) (2+strlen((s)->sun_path))\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/user.h",
    "content": "#ifndef _SYS_USER_H\n#define _SYS_USER_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <limits.h>\n#include <stdint.h>\n#include <unistd.h>\n\n#include <bits/user.h>\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/utsname.h",
    "content": "#ifndef\t_SYS_UTSNAME_H\n#define\t_SYS_UTSNAME_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\nstruct utsname {\n\tchar sysname[65];\n\tchar nodename[65];\n\tchar release[65];\n\tchar version[65];\n\tchar machine[65];\n#ifdef _GNU_SOURCE\n\tchar domainname[65];\n#else\n\tchar __domainname[65];\n#endif\n};\n\nint uname (struct utsname *);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/vfs.h",
    "content": "#include <sys/statfs.h>\n"
  },
  {
    "path": "user.libc/include/sys/vt.h",
    "content": "#include <bits/vt.h>\n"
  },
  {
    "path": "user.libc/include/sys/wait.h",
    "content": "#ifndef\t_SYS_WAIT_H\n#define\t_SYS_WAIT_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_pid_t\n#define __NEED_id_t\n#include <bits/alltypes.h>\n\ntypedef enum {\n\tP_ALL = 0,\n\tP_PID = 1,\n\tP_PGID = 2,\n\tP_PIDFD = 3\n} idtype_t;\n\npid_t wait (int *);\npid_t waitpid (pid_t, int *, int );\n\n#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \\\n || defined(_BSD_SOURCE)\n#include <signal.h>\nint waitid (idtype_t, id_t, siginfo_t *, int);\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#include <sys/resource.h>\npid_t wait3 (int *, int, struct rusage *);\npid_t wait4 (pid_t, int *, int, struct rusage *);\n#endif\n\n#define WNOHANG    1\n#define WUNTRACED  2\n\n#define WSTOPPED   2\n#define WEXITED    4\n#define WCONTINUED 8\n#define WNOWAIT    0x1000000\n\n#define __WNOTHREAD 0x20000000\n#define __WALL      0x40000000\n#define __WCLONE    0x80000000\n\n#define WEXITSTATUS(s) (((s) & 0xff00) >> 8)\n#define WTERMSIG(s) ((s) & 0x7f)\n#define WSTOPSIG(s) WEXITSTATUS(s)\n#define WCOREDUMP(s) ((s) & 0x80)\n#define WIFEXITED(s) (!WTERMSIG(s))\n#define WIFSTOPPED(s) ((short)((((s)&0xffff)*0x10001)>>8) > 0x7f00)\n#define WIFSIGNALED(s) (((s)&0xffff)-1U < 0xffu)\n#define WIFCONTINUED(s) ((s) == 0xffff)\n\n#if _REDIR_TIME64\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n__REDIR(wait3, __wait3_time64);\n__REDIR(wait4, __wait4_time64);\n#endif\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/sys/xattr.h",
    "content": "#ifndef\t_SYS_XATTR_H\n#define\t_SYS_XATTR_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define __NEED_ssize_t\n#define __NEED_size_t\n#include <bits/alltypes.h>\n\n#define XATTR_CREATE 1\n#define XATTR_REPLACE 2\n\nssize_t getxattr(const char *, const char *, void *, size_t);\nssize_t lgetxattr(const char *, const char *, void *, size_t);\nssize_t fgetxattr(int, const char *, void *, size_t);\nssize_t listxattr(const char *, char *, size_t);\nssize_t llistxattr(const char *, char *, size_t);\nssize_t flistxattr(int, char *, size_t);\nint setxattr(const char *, const char *, const void *, size_t, int);\nint lsetxattr(const char *, const char *, const void *, size_t, int);\nint fsetxattr(int, const char *, const void *, size_t, int);\nint removexattr(const char *, const char *);\nint lremovexattr(const char *, const char *);\nint fremovexattr(int, const char *);\n\n#define __UAPI_DEF_XATTR        0\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/syscall.h",
    "content": "#include <sys/syscall.h>\n"
  },
  {
    "path": "user.libc/include/sysexits.h",
    "content": "#ifndef\t_SYSEXITS_H\n#define _SYSEXITS_H\n#define EX_OK 0\n#define EX__BASE 64\n#define EX_USAGE 64\n#define EX_DATAERR 65\n#define EX_NOINPUT 66\n#define EX_NOUSER 67\n#define EX_NOHOST 68\n#define EX_UNAVAILABLE 69\n#define EX_SOFTWARE 70\n#define EX_OSERR 71\n#define EX_OSFILE 72\n#define EX_CANTCREAT 73\n#define EX_IOERR 74\n#define EX_TEMPFAIL 75\n#define EX_PROTOCOL 76\n#define EX_NOPERM 77\n#define EX_CONFIG 78\n#define EX__MAX 78\n#endif\n"
  },
  {
    "path": "user.libc/include/syslog.h",
    "content": "#ifndef _SYSLOG_H\n#define _SYSLOG_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define LOG_EMERG   0\n#define LOG_ALERT   1\n#define LOG_CRIT    2\n#define LOG_ERR     3\n#define LOG_WARNING 4\n#define LOG_NOTICE  5\n#define LOG_INFO    6\n#define LOG_DEBUG   7\n\n#define LOG_PRIMASK 7\n#define LOG_PRI(p) ((p)&LOG_PRIMASK)\n#define\tLOG_MAKEPRI(f, p) (((f)<<3)|(p))\n\n#define LOG_MASK(p) (1<<(p))\n#define LOG_UPTO(p) ((1<<((p)+1))-1)\n\n#define LOG_KERN     (0<<3)\n#define LOG_USER     (1<<3)\n#define LOG_MAIL     (2<<3)\n#define LOG_DAEMON   (3<<3)\n#define LOG_AUTH     (4<<3)\n#define LOG_SYSLOG   (5<<3)\n#define LOG_LPR      (6<<3)\n#define LOG_NEWS     (7<<3)\n#define LOG_UUCP     (8<<3)\n#define LOG_CRON     (9<<3)\n#define\tLOG_AUTHPRIV (10<<3)\n#define\tLOG_FTP      (11<<3)\n\n#define LOG_LOCAL0   (16<<3)\n#define LOG_LOCAL1   (17<<3)\n#define LOG_LOCAL2   (18<<3)\n#define LOG_LOCAL3   (19<<3)\n#define LOG_LOCAL4   (20<<3)\n#define LOG_LOCAL5   (21<<3)\n#define LOG_LOCAL6   (22<<3)\n#define LOG_LOCAL7   (23<<3)\n\n#define LOG_NFACILITIES 24\n#define LOG_FACMASK 0x3f8\n#define LOG_FAC(p) (((p)&LOG_FACMASK)>>3)\n\n#define LOG_PID    0x01\n#define LOG_CONS   0x02\n#define LOG_ODELAY 0x04\n#define LOG_NDELAY 0x08\n#define LOG_NOWAIT 0x10\n#define LOG_PERROR 0x20\n\nvoid closelog (void);\nvoid openlog (const char *, int, int);\nint setlogmask (int);\nvoid syslog (int, const char *, ...);\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define _PATH_LOG \"/dev/log\"\n#define __NEED_va_list\n#include <bits/alltypes.h>\nvoid vsyslog (int, const char *, va_list);\n#if defined(SYSLOG_NAMES)\n#define\tINTERNAL_NOPRI 0x10\n#define\tINTERNAL_MARK (LOG_NFACILITIES<<3)\ntypedef struct {\n\tchar *c_name;\n\tint c_val;\n} CODE;\n#define prioritynames ((CODE *)(const CODE []){ \\\n\t{ \"alert\", LOG_ALERT }, { \"crit\", LOG_CRIT }, { \"debug\", LOG_DEBUG }, \\\n\t{ \"emerg\", LOG_EMERG }, { \"err\", LOG_ERR }, { \"error\", LOG_ERR }, \\\n\t{ \"info\", LOG_INFO }, { \"none\", INTERNAL_NOPRI }, \\\n\t{ \"notice\", LOG_NOTICE }, { \"panic\", LOG_EMERG }, \\\n\t{ \"warn\", LOG_WARNING }, { \"warning\", LOG_WARNING }, { 0, -1 } })\n#define facilitynames ((CODE *)(const CODE []){ \\\n\t{ \"auth\", LOG_AUTH }, { \"authpriv\", LOG_AUTHPRIV }, \\\n\t{ \"cron\", LOG_CRON }, { \"daemon\", LOG_DAEMON }, { \"ftp\", LOG_FTP }, \\\n\t{ \"kern\", LOG_KERN }, { \"lpr\", LOG_LPR }, { \"mail\", LOG_MAIL }, \\\n\t{ \"mark\", INTERNAL_MARK }, { \"news\", LOG_NEWS }, \\\n\t{ \"security\", LOG_AUTH }, { \"syslog\", LOG_SYSLOG }, \\\n\t{ \"user\", LOG_USER }, { \"uucp\", LOG_UUCP }, \\\n\t{ \"local0\", LOG_LOCAL0 }, { \"local1\", LOG_LOCAL1 }, \\\n\t{ \"local2\", LOG_LOCAL2 }, { \"local3\", LOG_LOCAL3 }, \\\n\t{ \"local4\", LOG_LOCAL4 }, { \"local5\", LOG_LOCAL5 }, \\\n\t{ \"local6\", LOG_LOCAL6 }, { \"local7\", LOG_LOCAL7 }, { 0, -1 } })\n#endif\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/tar.h",
    "content": "#ifndef\t_TAR_H\n#define\t_TAR_H\n\n#define TSUID   04000\n#define TSGID   02000\n#define TSVTX   01000\n#define TUREAD  00400\n#define TUWRITE 00200\n#define TUEXEC  00100\n#define TGREAD  00040\n#define TGWRITE 00020\n#define TGEXEC  00010\n#define TOREAD  00004\n#define TOWRITE 00002\n#define TOEXEC  00001\n\n#define REGTYPE  '0'\n#define AREGTYPE '\\0'\n#define LNKTYPE  '1'\n#define SYMTYPE  '2'\n#define CHRTYPE  '3'\n#define BLKTYPE  '4'\n#define DIRTYPE  '5'\n#define FIFOTYPE '6'\n#define CONTTYPE '7'\n\n#define TMAGIC \"ustar\"\n#define TMAGLEN 6\n\n#define TVERSION \"00\"\n#define TVERSLEN 2\n\n#endif\n"
  },
  {
    "path": "user.libc/include/termios.h",
    "content": "#ifndef\t_TERMIOS_H\n#define\t_TERMIOS_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_pid_t\n#define __NEED_struct_winsize\n\n#include <bits/alltypes.h>\n\ntypedef unsigned char cc_t;\ntypedef unsigned int speed_t;\ntypedef unsigned int tcflag_t;\n\n#define NCCS 32\n\n#include <bits/termios.h>\n\nspeed_t cfgetospeed (const struct termios *);\nspeed_t cfgetispeed (const struct termios *);\nint cfsetospeed (struct termios *, speed_t);\nint cfsetispeed (struct termios *, speed_t);\n\nint tcgetattr (int, struct termios *);\nint tcsetattr (int, int, const struct termios *);\n\nint tcgetwinsize (int, struct winsize *);\nint tcsetwinsize (int, const struct winsize *);\n\nint tcsendbreak (int, int);\nint tcdrain (int);\nint tcflush (int, int);\nint tcflow (int, int);\n\npid_t tcgetsid (int);\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\nvoid cfmakeraw(struct termios *);\nint cfsetspeed(struct termios *, speed_t);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/tgmath.h",
    "content": "#ifndef _TGMATH_H\n#define _TGMATH_H\n\n/*\nthe return types are only correct with gcc (__GNUC__)\notherwise they are long double or long double complex\n\nthe long double version of a function is never chosen when\nsizeof(double) == sizeof(long double)\n(but the return type is set correctly with gcc)\n*/\n\n#include <math.h>\n#include <complex.h>\n\n#define __IS_FP(x) (sizeof((x)+1ULL) == sizeof((x)+1.0f))\n#define __IS_CX(x) (__IS_FP(x) && sizeof(x) == sizeof((x)+I))\n#define __IS_REAL(x) (__IS_FP(x) && 2*sizeof(x) == sizeof((x)+I))\n\n#define __FLT(x) (__IS_REAL(x) && sizeof(x) == sizeof(float))\n#define __LDBL(x) (__IS_REAL(x) && sizeof(x) == sizeof(long double) && sizeof(long double) != sizeof(double))\n\n#define __FLTCX(x) (__IS_CX(x) && sizeof(x) == sizeof(float complex))\n#define __DBLCX(x) (__IS_CX(x) && sizeof(x) == sizeof(double complex))\n#define __LDBLCX(x) (__IS_CX(x) && sizeof(x) == sizeof(long double complex) && sizeof(long double) != sizeof(double))\n\n/* return type */\n\n#ifdef __GNUC__\n/*\nthe result must be casted to the right type\n(otherwise the result type is determined by the conversion\nrules applied to all the function return types so it is long\ndouble or long double complex except for integral functions)\n\nthis cannot be done in c99, so the typeof gcc extension is\nused and that the type of ?: depends on wether an operand is\na null pointer constant or not\n(in c11 _Generic can be used)\n\nthe c arguments below must be integer constant expressions\nso they can be in null pointer constants\n(__IS_FP above was carefully chosen this way)\n*/\n/* if c then t else void */\n#define __type1(c,t) __typeof__(*(0?(t*)0:(void*)!(c)))\n/* if c then t1 else t2 */\n#define __type2(c,t1,t2) __typeof__(*(0?(__type1(c,t1)*)0:(__type1(!(c),t2)*)0))\n/* cast to double when x is integral, otherwise use typeof(x) */\n#define __RETCAST(x) ( \\\n\t__type2(__IS_FP(x), __typeof__(x), double))\n/* 2 args case, should work for complex types (cpow) */\n#define __RETCAST_2(x, y) ( \\\n\t__type2(__IS_FP(x) && __IS_FP(y), \\\n\t\t__typeof__((x)+(y)), \\\n\t\t__typeof__((x)+(y)+1.0)))\n/* 3 args case (fma only) */\n#define __RETCAST_3(x, y, z) ( \\\n\t__type2(__IS_FP(x) && __IS_FP(y) && __IS_FP(z), \\\n\t\t__typeof__((x)+(y)+(z)), \\\n\t\t__typeof__((x)+(y)+(z)+1.0)))\n/* drop complex from the type of x */\n/* TODO: wrong when sizeof(long double)==sizeof(double) */\n#define __RETCAST_REAL(x) (  \\\n\t__type2(__IS_FP(x) && sizeof((x)+I) == sizeof(float complex), float, \\\n\t__type2(sizeof((x)+1.0+I) == sizeof(double complex), double, \\\n\t\tlong double)))\n/* add complex to the type of x */\n#define __RETCAST_CX(x) (__typeof__(__RETCAST(x)0+I))\n#else\n#define __RETCAST(x)\n#define __RETCAST_2(x, y)\n#define __RETCAST_3(x, y, z)\n#define __RETCAST_REAL(x)\n#define __RETCAST_CX(x)\n#endif\n\n/* function selection */\n\n#define __tg_real_nocast(fun, x) ( \\\n\t__FLT(x) ? fun ## f (x) : \\\n\t__LDBL(x) ? fun ## l (x) : \\\n\tfun(x) )\n\n#define __tg_real(fun, x) (__RETCAST(x)__tg_real_nocast(fun, x))\n\n#define __tg_real_2_1(fun, x, y) (__RETCAST(x)( \\\n\t__FLT(x) ? fun ## f (x, y) : \\\n\t__LDBL(x) ? fun ## l (x, y) : \\\n\tfun(x, y) ))\n\n#define __tg_real_2(fun, x, y) (__RETCAST_2(x, y)( \\\n\t__FLT(x) && __FLT(y) ? fun ## f (x, y) : \\\n\t__LDBL((x)+(y)) ? fun ## l (x, y) : \\\n\tfun(x, y) ))\n\n#define __tg_complex(fun, x) (__RETCAST_CX(x)( \\\n\t__FLTCX((x)+I) && __IS_FP(x) ? fun ## f (x) : \\\n\t__LDBLCX((x)+I) ? fun ## l (x) : \\\n\tfun(x) ))\n\n#define __tg_complex_retreal(fun, x) (__RETCAST_REAL(x)( \\\n\t__FLTCX((x)+I) && __IS_FP(x) ? fun ## f (x) : \\\n\t__LDBLCX((x)+I) ? fun ## l (x) : \\\n\tfun(x) ))\n\n#define __tg_real_complex(fun, x) (__RETCAST(x)( \\\n\t__FLTCX(x) ? c ## fun ## f (x) : \\\n\t__DBLCX(x) ? c ## fun (x) : \\\n\t__LDBLCX(x) ? c ## fun ## l (x) : \\\n\t__FLT(x) ? fun ## f (x) : \\\n\t__LDBL(x) ? fun ## l (x) : \\\n\tfun(x) ))\n\n/* special cases */\n\n#define __tg_real_remquo(x, y, z) (__RETCAST_2(x, y)( \\\n\t__FLT(x) && __FLT(y) ? remquof(x, y, z) : \\\n\t__LDBL((x)+(y)) ? remquol(x, y, z) : \\\n\tremquo(x, y, z) ))\n\n#define __tg_real_fma(x, y, z) (__RETCAST_3(x, y, z)( \\\n\t__FLT(x) && __FLT(y) && __FLT(z) ? fmaf(x, y, z) : \\\n\t__LDBL((x)+(y)+(z)) ? fmal(x, y, z) : \\\n\tfma(x, y, z) ))\n\n#define __tg_real_complex_pow(x, y) (__RETCAST_2(x, y)( \\\n\t__FLTCX((x)+(y)) && __IS_FP(x) && __IS_FP(y) ? cpowf(x, y) : \\\n\t__FLTCX((x)+(y)) ? cpow(x, y) : \\\n\t__DBLCX((x)+(y)) ? cpow(x, y) : \\\n\t__LDBLCX((x)+(y)) ? cpowl(x, y) : \\\n\t__FLT(x) && __FLT(y) ? powf(x, y) : \\\n\t__LDBL((x)+(y)) ? powl(x, y) : \\\n\tpow(x, y) ))\n\n#define __tg_real_complex_fabs(x) (__RETCAST_REAL(x)( \\\n\t__FLTCX(x) ? cabsf(x) : \\\n\t__DBLCX(x) ? cabs(x) : \\\n\t__LDBLCX(x) ? cabsl(x) : \\\n\t__FLT(x) ? fabsf(x) : \\\n\t__LDBL(x) ? fabsl(x) : \\\n\tfabs(x) ))\n\n/* suppress any macros in math.h or complex.h */\n\n#undef acos\n#undef acosh\n#undef asin\n#undef asinh\n#undef atan\n#undef atan2\n#undef atanh\n#undef carg\n#undef cbrt\n#undef ceil\n#undef cimag\n#undef conj\n#undef copysign\n#undef cos\n#undef cosh\n#undef cproj\n#undef creal\n#undef erf\n#undef erfc\n#undef exp\n#undef exp2\n#undef expm1\n#undef fabs\n#undef fdim\n#undef floor\n#undef fma\n#undef fmax\n#undef fmin\n#undef fmod\n#undef frexp\n#undef hypot\n#undef ilogb\n#undef ldexp\n#undef lgamma\n#undef llrint\n#undef llround\n#undef log\n#undef log10\n#undef log1p\n#undef log2\n#undef logb\n#undef lrint\n#undef lround\n#undef nearbyint\n#undef nextafter\n#undef nexttoward\n#undef pow\n#undef remainder\n#undef remquo\n#undef rint\n#undef round\n#undef scalbln\n#undef scalbn\n#undef sin\n#undef sinh\n#undef sqrt\n#undef tan\n#undef tanh\n#undef tgamma\n#undef trunc\n\n/* tg functions */\n\n#define acos(x)         __tg_real_complex(acos, (x))\n#define acosh(x)        __tg_real_complex(acosh, (x))\n#define asin(x)         __tg_real_complex(asin, (x))\n#define asinh(x)        __tg_real_complex(asinh, (x))\n#define atan(x)         __tg_real_complex(atan, (x))\n#define atan2(x,y)      __tg_real_2(atan2, (x), (y))\n#define atanh(x)        __tg_real_complex(atanh, (x))\n#define carg(x)         __tg_complex_retreal(carg, (x))\n#define cbrt(x)         __tg_real(cbrt, (x))\n#define ceil(x)         __tg_real(ceil, (x))\n#define cimag(x)        __tg_complex_retreal(cimag, (x))\n#define conj(x)         __tg_complex(conj, (x))\n#define copysign(x,y)   __tg_real_2(copysign, (x), (y))\n#define cos(x)          __tg_real_complex(cos, (x))\n#define cosh(x)         __tg_real_complex(cosh, (x))\n#define cproj(x)        __tg_complex(cproj, (x))\n#define creal(x)        __tg_complex_retreal(creal, (x))\n#define erf(x)          __tg_real(erf, (x))\n#define erfc(x)         __tg_real(erfc, (x))\n#define exp(x)          __tg_real_complex(exp, (x))\n#define exp2(x)         __tg_real(exp2, (x))\n#define expm1(x)        __tg_real(expm1, (x))\n#define fabs(x)         __tg_real_complex_fabs(x)\n#define fdim(x,y)       __tg_real_2(fdim, (x), (y))\n#define floor(x)        __tg_real(floor, (x))\n#define fma(x,y,z)      __tg_real_fma((x), (y), (z))\n#define fmax(x,y)       __tg_real_2(fmax, (x), (y))\n#define fmin(x,y)       __tg_real_2(fmin, (x), (y))\n#define fmod(x,y)       __tg_real_2(fmod, (x), (y))\n#define frexp(x,y)      __tg_real_2_1(frexp, (x), (y))\n#define hypot(x,y)      __tg_real_2(hypot, (x), (y))\n#define ilogb(x)        __tg_real_nocast(ilogb, (x))\n#define ldexp(x,y)      __tg_real_2_1(ldexp, (x), (y))\n#define lgamma(x)       __tg_real(lgamma, (x))\n#define llrint(x)       __tg_real_nocast(llrint, (x))\n#define llround(x)      __tg_real_nocast(llround, (x))\n#define log(x)          __tg_real_complex(log, (x))\n#define log10(x)        __tg_real(log10, (x))\n#define log1p(x)        __tg_real(log1p, (x))\n#define log2(x)         __tg_real(log2, (x))\n#define logb(x)         __tg_real(logb, (x))\n#define lrint(x)        __tg_real_nocast(lrint, (x))\n#define lround(x)       __tg_real_nocast(lround, (x))\n#define nearbyint(x)    __tg_real(nearbyint, (x))\n#define nextafter(x,y)  __tg_real_2(nextafter, (x), (y))\n#define nexttoward(x,y) __tg_real_2(nexttoward, (x), (y))\n#define pow(x,y)        __tg_real_complex_pow((x), (y))\n#define remainder(x,y)  __tg_real_2(remainder, (x), (y))\n#define remquo(x,y,z)   __tg_real_remquo((x), (y), (z))\n#define rint(x)         __tg_real(rint, (x))\n#define round(x)        __tg_real(round, (x))\n#define scalbln(x,y)    __tg_real_2_1(scalbln, (x), (y))\n#define scalbn(x,y)     __tg_real_2_1(scalbn, (x), (y))\n#define sin(x)          __tg_real_complex(sin, (x))\n#define sinh(x)         __tg_real_complex(sinh, (x))\n#define sqrt(x)         __tg_real_complex(sqrt, (x))\n#define tan(x)          __tg_real_complex(tan, (x))\n#define tanh(x)         __tg_real_complex(tanh, (x))\n#define tgamma(x)       __tg_real(tgamma, (x))\n#define trunc(x)        __tg_real(trunc, (x))\n\n#endif\n"
  },
  {
    "path": "user.libc/include/threads.h",
    "content": "#ifndef _THREADS_H\n#define _THREADS_H\n\n#include <features.h>\n#include <time.h>\n\n#ifdef __cplusplus\nextern \"C\" {\ntypedef unsigned long thrd_t;\n#else\ntypedef struct __pthread *thrd_t;\n#define thread_local _Thread_local\n#endif\n\ntypedef int once_flag;\ntypedef unsigned tss_t;\ntypedef int (*thrd_start_t)(void *);\ntypedef void (*tss_dtor_t)(void *);\n\n#define __NEED_cnd_t\n#define __NEED_mtx_t\n\n#include <bits/alltypes.h>\n\n#define TSS_DTOR_ITERATIONS 4\n\nenum {\n\tthrd_success  = 0,\n\tthrd_busy     = 1,\n\tthrd_error    = 2,\n\tthrd_nomem    = 3,\n\tthrd_timedout = 4,\n};\n\nenum {\n\tmtx_plain     = 0,\n\tmtx_recursive = 1,\n\tmtx_timed     = 2,\n};\n\n#define ONCE_FLAG_INIT 0\n\nint thrd_create(thrd_t *, thrd_start_t, void *);\n_Noreturn void thrd_exit(int);\n\nint thrd_detach(thrd_t);\nint thrd_join(thrd_t, int *);\n\nint thrd_sleep(const struct timespec *, struct timespec *);\nvoid thrd_yield(void);\n\nthrd_t thrd_current(void);\nint thrd_equal(thrd_t, thrd_t);\n#ifndef __cplusplus\n#define thrd_equal(A, B) ((A) == (B))\n#endif\n\nvoid call_once(once_flag *, void (*)(void));\n\nint mtx_init(mtx_t *, int);\nvoid mtx_destroy(mtx_t *);\n\nint mtx_lock(mtx_t *);\nint mtx_timedlock(mtx_t *__restrict, const struct timespec *__restrict);\nint mtx_trylock(mtx_t *);\nint mtx_unlock(mtx_t *);\n\nint cnd_init(cnd_t *);\nvoid cnd_destroy(cnd_t *);\n\nint cnd_broadcast(cnd_t *);\nint cnd_signal(cnd_t *);\n\nint cnd_timedwait(cnd_t *__restrict, mtx_t *__restrict, const struct timespec *__restrict);\nint cnd_wait(cnd_t *, mtx_t *);\n\nint tss_create(tss_t *, tss_dtor_t);\nvoid tss_delete(tss_t);\n\nint tss_set(tss_t, void *);\nvoid *tss_get(tss_t);\n\n#if _REDIR_TIME64\n__REDIR(thrd_sleep, __thrd_sleep_time64);\n__REDIR(mtx_timedlock, __mtx_timedlock_time64);\n__REDIR(cnd_timedwait, __cnd_timedwait_time64);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/time.h",
    "content": "#ifndef\t_TIME_H\n#define _TIME_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#ifdef __cplusplus\n#define NULL 0L\n#else\n#define NULL ((void*)0)\n#endif\n\n\n#define __NEED_size_t\n#define __NEED_time_t\n#define __NEED_clock_t\n#define __NEED_struct_timespec\n\n#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \\\n || defined(_BSD_SOURCE)\n#define __NEED_clockid_t\n#define __NEED_timer_t\n#define __NEED_pid_t\n#define __NEED_locale_t\n#endif\n\n#include <bits/alltypes.h>\n\n#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)\n#define __tm_gmtoff tm_gmtoff\n#define __tm_zone tm_zone\n#endif\n\nstruct tm {\n\tint tm_sec;\n\tint tm_min;\n\tint tm_hour;\n\tint tm_mday;\n\tint tm_mon;\n\tint tm_year;\n\tint tm_wday;\n\tint tm_yday;\n\tint tm_isdst;\n\tlong __tm_gmtoff;\n\tconst char *__tm_zone;\n};\n\nclock_t clock (void);\ntime_t time (time_t *);\ndouble difftime (time_t, time_t);\ntime_t mktime (struct tm *);\nsize_t strftime (char *__restrict, size_t, const char *__restrict, const struct tm *__restrict);\nstruct tm *gmtime (const time_t *);\nstruct tm *localtime (const time_t *);\nchar *asctime (const struct tm *);\nchar *ctime (const time_t *);\nint timespec_get(struct timespec *, int);\n\n#define CLOCKS_PER_SEC 1000000L\n\n#define TIME_UTC 1\n\n#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \\\n || defined(_BSD_SOURCE)\n\nsize_t strftime_l (char *  __restrict, size_t, const char *  __restrict, const struct tm *  __restrict, locale_t);\n\nstruct tm *gmtime_r (const time_t *__restrict, struct tm *__restrict);\nstruct tm *localtime_r (const time_t *__restrict, struct tm *__restrict);\nchar *asctime_r (const struct tm *__restrict, char *__restrict);\nchar *ctime_r (const time_t *, char *);\n\nvoid tzset (void);\n\nstruct itimerspec {\n\tstruct timespec it_interval;\n\tstruct timespec it_value;\n};\n\n#define CLOCK_REALTIME           0\n#define CLOCK_MONOTONIC          1\n#define CLOCK_PROCESS_CPUTIME_ID 2\n#define CLOCK_THREAD_CPUTIME_ID  3\n#define CLOCK_MONOTONIC_RAW      4\n#define CLOCK_REALTIME_COARSE    5\n#define CLOCK_MONOTONIC_COARSE   6\n#define CLOCK_BOOTTIME           7\n#define CLOCK_REALTIME_ALARM     8\n#define CLOCK_BOOTTIME_ALARM     9\n#define CLOCK_SGI_CYCLE         10\n#define CLOCK_TAI               11\n\n#define TIMER_ABSTIME 1\n\nint nanosleep (const struct timespec *, struct timespec *);\nint clock_getres (clockid_t, struct timespec *);\nint clock_gettime (clockid_t, struct timespec *);\nint clock_settime (clockid_t, const struct timespec *);\nint clock_nanosleep (clockid_t, int, const struct timespec *, struct timespec *);\nint clock_getcpuclockid (pid_t, clockid_t *);\n\nstruct sigevent;\nint timer_create (clockid_t, struct sigevent *__restrict, timer_t *__restrict);\nint timer_delete (timer_t);\nint timer_settime (timer_t, int, const struct itimerspec *__restrict, struct itimerspec *__restrict);\nint timer_gettime (timer_t, struct itimerspec *);\nint timer_getoverrun (timer_t);\n\nextern char *tzname[2];\n\n#endif\n\n\n#if defined(_XOPEN_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE)\nchar *strptime (const char *__restrict, const char *__restrict, struct tm *__restrict);\nextern int daylight;\nextern long timezone;\nextern int getdate_err;\nstruct tm *getdate (const char *);\n#endif\n\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\nint stime(const time_t *);\ntime_t timegm(struct tm *);\n#endif\n\n#if _REDIR_TIME64\n__REDIR(time, __time64);\n__REDIR(difftime, __difftime64);\n__REDIR(mktime, __mktime64);\n__REDIR(gmtime, __gmtime64);\n__REDIR(localtime, __localtime64);\n__REDIR(ctime, __ctime64);\n__REDIR(timespec_get, __timespec_get_time64);\n#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \\\n || defined(_BSD_SOURCE)\n__REDIR(gmtime_r, __gmtime64_r);\n__REDIR(localtime_r, __localtime64_r);\n__REDIR(ctime_r, __ctime64_r);\n__REDIR(nanosleep, __nanosleep_time64);\n__REDIR(clock_getres, __clock_getres_time64);\n__REDIR(clock_gettime, __clock_gettime64);\n__REDIR(clock_settime, __clock_settime64);\n__REDIR(clock_nanosleep, __clock_nanosleep_time64);\n__REDIR(timer_settime, __timer_settime64);\n__REDIR(timer_gettime, __timer_gettime64);\n#endif\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n__REDIR(stime, __stime64);\n__REDIR(timegm, __timegm_time64);\n#endif\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n\n#endif\n"
  },
  {
    "path": "user.libc/include/uchar.h",
    "content": "#ifndef _UCHAR_H\n#define _UCHAR_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#if __cplusplus < 201103L\ntypedef unsigned short char16_t;\ntypedef unsigned char32_t;\n#endif\n\n#define __NEED_mbstate_t\n#define __NEED_size_t\n\n#include <features.h>\n#include <bits/alltypes.h>\n\nsize_t c16rtomb(char *__restrict, char16_t, mbstate_t *__restrict);\nsize_t mbrtoc16(char16_t *__restrict, const char *__restrict, size_t, mbstate_t *__restrict);\n\nsize_t c32rtomb(char *__restrict, char32_t, mbstate_t *__restrict);\nsize_t mbrtoc32(char32_t *__restrict, const char *__restrict, size_t, mbstate_t *__restrict);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/ucontext.h",
    "content": "#ifndef _UCONTEXT_H\n#define _UCONTEXT_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#include <signal.h>\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define NGREG (sizeof(gregset_t)/sizeof(greg_t))\n#endif\n\nstruct __ucontext;\n\nint  getcontext(struct __ucontext *);\nvoid makecontext(struct __ucontext *, void (*)(), int, ...);\nint  setcontext(const struct __ucontext *);\nint  swapcontext(struct __ucontext *, const struct __ucontext *);\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "user.libc/include/ulimit.h",
    "content": "#ifndef _ULIMIT_H\n#define _ULIMIT_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define UL_GETFSIZE 1\n#define UL_SETFSIZE 2\n\nlong ulimit (int, ...);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/unistd.h",
    "content": "#ifndef\t_UNISTD_H\n#define\t_UNISTD_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define STDIN_FILENO  0\n#define STDOUT_FILENO 1\n#define STDERR_FILENO 2\n\n#define SEEK_SET 0\n#define SEEK_CUR 1\n#define SEEK_END 2\n\n#ifdef __cplusplus\n#define NULL 0L\n#else\n#define NULL ((void*)0)\n#endif\n\n#define __NEED_size_t\n#define __NEED_ssize_t\n#define __NEED_uid_t\n#define __NEED_gid_t\n#define __NEED_off_t\n#define __NEED_pid_t\n#define __NEED_intptr_t\n#define __NEED_useconds_t\n\n#include <bits/alltypes.h>\n\nint pipe(int [2]);\nint pipe2(int [2], int);\nint close(int);\nint posix_close(int, int);\nint dup(int);\nint dup2(int, int);\nint dup3(int, int, int);\noff_t lseek(int, off_t, int);\nint fsync(int);\nint fdatasync(int);\n\nssize_t read(int, void *, size_t);\nssize_t write(int, const void *, size_t);\nssize_t pread(int, void *, size_t, off_t);\nssize_t pwrite(int, const void *, size_t, off_t);\n\nint chown(const char *, uid_t, gid_t);\nint fchown(int, uid_t, gid_t);\nint lchown(const char *, uid_t, gid_t);\nint fchownat(int, const char *, uid_t, gid_t, int);\n\nint link(const char *, const char *);\nint linkat(int, const char *, int, const char *, int);\nint symlink(const char *, const char *);\nint symlinkat(const char *, int, const char *);\nssize_t readlink(const char *__restrict, char *__restrict, size_t);\nssize_t readlinkat(int, const char *__restrict, char *__restrict, size_t);\nint unlink(const char *);\nint unlinkat(int, const char *, int);\nint rmdir(const char *);\nint truncate(const char *, off_t);\nint ftruncate(int, off_t);\n\n#define F_OK 0\n#define R_OK 4\n#define W_OK 2\n#define X_OK 1\n\nint access(const char *, int);\n\nint chdir(const char *);\nchar *getcwd(char *, size_t);\n\nunsigned alarm(unsigned);\nunsigned sleep(unsigned);\nint pause(void);\n\npid_t fork(void);\npid_t _Fork(void);\nint execve(const char *, char *const [], char *const []);\nint execv(const char *, char *const []);\nint execle(const char *, const char *, ...);\nint execl(const char *, const char *, ...);\nint execvp(const char *, char *const []);\nint execlp(const char *, const char *, ...);\nint fexecve(int, char *const [], char *const []);\n_Noreturn void _exit(int);\n\npid_t getpid(void);\npid_t getppid(void);\npid_t getpgrp(void);\npid_t getpgid(pid_t);\nint setpgid(pid_t, pid_t);\npid_t setsid(void);\npid_t getsid(pid_t);\nchar *ttyname(int);\nint ttyname_r(int, char *, size_t);\nint isatty(int);\npid_t tcgetpgrp(int);\nint tcsetpgrp(int, pid_t);\n\nuid_t getuid(void);\nuid_t geteuid(void);\ngid_t getgid(void);\ngid_t getegid(void);\nint getgroups(int, gid_t []);\nint setuid(uid_t);\nint seteuid(uid_t);\nint setgid(gid_t);\nint setegid(gid_t);\n\nchar *getlogin(void);\nint getlogin_r(char *, size_t);\nint gethostname(char *, size_t);\nchar *ctermid(char *);\n\nint getopt(int, char * const [], const char *);\nextern char *optarg;\nextern int optind, opterr, optopt;\n\nlong pathconf(const char *, int);\nlong fpathconf(int, int);\nlong sysconf(int);\nsize_t confstr(int, char *, size_t);\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define F_ULOCK 0\n#define F_LOCK  1\n#define F_TLOCK 2\n#define F_TEST  3\nint setreuid(uid_t, uid_t);\nint setregid(gid_t, gid_t);\nint lockf(int, int, off_t);\nlong gethostid(void);\nint nice(int);\nvoid sync(void);\npid_t setpgrp(void);\nchar *crypt(const char *, const char *);\nvoid encrypt(char *, int);\nvoid swab(const void *__restrict, void *__restrict, ssize_t);\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) \\\n || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 < 700)\nint usleep(unsigned);\nunsigned ualarm(unsigned, unsigned);\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define L_SET 0\n#define L_INCR 1\n#define L_XTND 2\nint brk(void *);\nvoid *sbrk(intptr_t);\npid_t vfork(void);\nint vhangup(void);\nint chroot(const char *);\nint getpagesize(void);\nint getdtablesize(void);\nint sethostname(const char *, size_t);\nint getdomainname(char *, size_t);\nint setdomainname(const char *, size_t);\nint setgroups(size_t, const gid_t *);\nchar *getpass(const char *);\nint daemon(int, int);\nvoid setusershell(void);\nvoid endusershell(void);\nchar *getusershell(void);\nint acct(const char *);\nlong syscall(long, ...);\nint execvpe(const char *, char *const [], char *const []);\nint issetugid(void);\nint getentropy(void *, size_t);\nextern int optreset;\n#endif\n\n#ifdef _GNU_SOURCE\nextern char **environ;\nint setresuid(uid_t, uid_t, uid_t);\nint setresgid(gid_t, gid_t, gid_t);\nint getresuid(uid_t *, uid_t *, uid_t *);\nint getresgid(gid_t *, gid_t *, gid_t *);\nchar *get_current_dir_name(void);\nint syncfs(int);\nint euidaccess(const char *, int);\nint eaccess(const char *, int);\nssize_t copy_file_range(int, off_t *, int, off_t *, size_t, unsigned);\npid_t gettid(void);\n#endif\n\n#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)\n#define lseek64 lseek\n#define pread64 pread\n#define pwrite64 pwrite\n#define truncate64 truncate\n#define ftruncate64 ftruncate\n#define lockf64 lockf\n#define off64_t off_t\n#endif\n\n#define POSIX_CLOSE_RESTART     0\n\n#define _XOPEN_VERSION          700\n#define _XOPEN_UNIX             1\n#define _XOPEN_ENH_I18N         1\n\n#define _POSIX_VERSION          200809L\n#define _POSIX2_VERSION         _POSIX_VERSION\n\n#define _POSIX_ADVISORY_INFO    _POSIX_VERSION\n#define _POSIX_CHOWN_RESTRICTED 1\n#define _POSIX_IPV6             _POSIX_VERSION\n#define _POSIX_JOB_CONTROL      1\n#define _POSIX_MAPPED_FILES     _POSIX_VERSION\n#define _POSIX_MEMLOCK          _POSIX_VERSION\n#define _POSIX_MEMLOCK_RANGE    _POSIX_VERSION\n#define _POSIX_MEMORY_PROTECTION _POSIX_VERSION\n#define _POSIX_MESSAGE_PASSING  _POSIX_VERSION\n#define _POSIX_FSYNC            _POSIX_VERSION\n#define _POSIX_NO_TRUNC         1\n#define _POSIX_RAW_SOCKETS      _POSIX_VERSION\n#define _POSIX_REALTIME_SIGNALS _POSIX_VERSION\n#define _POSIX_REGEXP           1\n#define _POSIX_SAVED_IDS        1\n#define _POSIX_SHELL            1\n#define _POSIX_SPAWN            _POSIX_VERSION\n#define _POSIX_VDISABLE         0\n\n#define _POSIX_THREADS          _POSIX_VERSION\n#define _POSIX_THREAD_PROCESS_SHARED _POSIX_VERSION\n#define _POSIX_THREAD_SAFE_FUNCTIONS _POSIX_VERSION\n#define _POSIX_THREAD_ATTR_STACKADDR _POSIX_VERSION\n#define _POSIX_THREAD_ATTR_STACKSIZE _POSIX_VERSION\n#define _POSIX_THREAD_PRIORITY_SCHEDULING _POSIX_VERSION\n#define _POSIX_THREAD_CPUTIME   _POSIX_VERSION\n#define _POSIX_TIMERS           _POSIX_VERSION\n#define _POSIX_TIMEOUTS         _POSIX_VERSION\n#define _POSIX_MONOTONIC_CLOCK  _POSIX_VERSION\n#define _POSIX_CPUTIME          _POSIX_VERSION\n#define _POSIX_CLOCK_SELECTION  _POSIX_VERSION\n#define _POSIX_BARRIERS         _POSIX_VERSION\n#define _POSIX_SPIN_LOCKS       _POSIX_VERSION\n#define _POSIX_READER_WRITER_LOCKS _POSIX_VERSION\n#define _POSIX_ASYNCHRONOUS_IO  _POSIX_VERSION\n#define _POSIX_SEMAPHORES       _POSIX_VERSION\n#define _POSIX_SHARED_MEMORY_OBJECTS _POSIX_VERSION\n\n#define _POSIX2_C_BIND          _POSIX_VERSION\n\n#include <bits/posix.h>\n\n\n\n#define _PC_LINK_MAX\t0\n#define _PC_MAX_CANON\t1\n#define _PC_MAX_INPUT\t2\n#define _PC_NAME_MAX\t3\n#define _PC_PATH_MAX\t4\n#define _PC_PIPE_BUF\t5\n#define _PC_CHOWN_RESTRICTED\t6\n#define _PC_NO_TRUNC\t7\n#define _PC_VDISABLE\t8\n#define _PC_SYNC_IO\t9\n#define _PC_ASYNC_IO\t10\n#define _PC_PRIO_IO\t11\n#define _PC_SOCK_MAXBUF\t12\n#define _PC_FILESIZEBITS\t13\n#define _PC_REC_INCR_XFER_SIZE\t14\n#define _PC_REC_MAX_XFER_SIZE\t15\n#define _PC_REC_MIN_XFER_SIZE\t16\n#define _PC_REC_XFER_ALIGN\t17\n#define _PC_ALLOC_SIZE_MIN\t18\n#define _PC_SYMLINK_MAX\t19\n#define _PC_2_SYMLINKS\t20\n\n#define _SC_ARG_MAX\t0\n#define _SC_CHILD_MAX\t1\n#define _SC_CLK_TCK\t2\n#define _SC_NGROUPS_MAX\t3\n#define _SC_OPEN_MAX\t4\n#define _SC_STREAM_MAX\t5\n#define _SC_TZNAME_MAX\t6\n#define _SC_JOB_CONTROL\t7\n#define _SC_SAVED_IDS\t8\n#define _SC_REALTIME_SIGNALS\t9\n#define _SC_PRIORITY_SCHEDULING\t10\n#define _SC_TIMERS\t11\n#define _SC_ASYNCHRONOUS_IO\t12\n#define _SC_PRIORITIZED_IO\t13\n#define _SC_SYNCHRONIZED_IO\t14\n#define _SC_FSYNC\t15\n#define _SC_MAPPED_FILES\t16\n#define _SC_MEMLOCK\t17\n#define _SC_MEMLOCK_RANGE\t18\n#define _SC_MEMORY_PROTECTION\t19\n#define _SC_MESSAGE_PASSING\t20\n#define _SC_SEMAPHORES\t21\n#define _SC_SHARED_MEMORY_OBJECTS\t22\n#define _SC_AIO_LISTIO_MAX\t23\n#define _SC_AIO_MAX\t24\n#define _SC_AIO_PRIO_DELTA_MAX\t25\n#define _SC_DELAYTIMER_MAX\t26\n#define _SC_MQ_OPEN_MAX\t27\n#define _SC_MQ_PRIO_MAX\t28\n#define _SC_VERSION\t29\n#define _SC_PAGE_SIZE\t30\n#define _SC_PAGESIZE\t30 /* !! */\n#define _SC_RTSIG_MAX\t31\n#define _SC_SEM_NSEMS_MAX\t32\n#define _SC_SEM_VALUE_MAX\t33\n#define _SC_SIGQUEUE_MAX\t34\n#define _SC_TIMER_MAX\t35\n#define _SC_BC_BASE_MAX\t36\n#define _SC_BC_DIM_MAX\t37\n#define _SC_BC_SCALE_MAX\t38\n#define _SC_BC_STRING_MAX\t39\n#define _SC_COLL_WEIGHTS_MAX\t40\n#define _SC_EXPR_NEST_MAX\t42\n#define _SC_LINE_MAX\t43\n#define _SC_RE_DUP_MAX\t44\n#define _SC_2_VERSION\t46\n#define _SC_2_C_BIND\t47\n#define _SC_2_C_DEV\t48\n#define _SC_2_FORT_DEV\t49\n#define _SC_2_FORT_RUN\t50\n#define _SC_2_SW_DEV\t51\n#define _SC_2_LOCALEDEF\t52\n#define _SC_UIO_MAXIOV\t60 /* !! */\n#define _SC_IOV_MAX\t60\n#define _SC_THREADS\t67\n#define _SC_THREAD_SAFE_FUNCTIONS\t68\n#define _SC_GETGR_R_SIZE_MAX\t69\n#define _SC_GETPW_R_SIZE_MAX\t70\n#define _SC_LOGIN_NAME_MAX\t71\n#define _SC_TTY_NAME_MAX\t72\n#define _SC_THREAD_DESTRUCTOR_ITERATIONS\t73\n#define _SC_THREAD_KEYS_MAX\t74\n#define _SC_THREAD_STACK_MIN\t75\n#define _SC_THREAD_THREADS_MAX\t76\n#define _SC_THREAD_ATTR_STACKADDR\t77\n#define _SC_THREAD_ATTR_STACKSIZE\t78\n#define _SC_THREAD_PRIORITY_SCHEDULING\t79\n#define _SC_THREAD_PRIO_INHERIT\t80\n#define _SC_THREAD_PRIO_PROTECT\t81\n#define _SC_THREAD_PROCESS_SHARED\t82\n#define _SC_NPROCESSORS_CONF\t83\n#define _SC_NPROCESSORS_ONLN\t84\n#define _SC_PHYS_PAGES\t85\n#define _SC_AVPHYS_PAGES\t86\n#define _SC_ATEXIT_MAX\t87\n#define _SC_PASS_MAX\t88\n#define _SC_XOPEN_VERSION\t89\n#define _SC_XOPEN_XCU_VERSION\t90\n#define _SC_XOPEN_UNIX\t91\n#define _SC_XOPEN_CRYPT\t92\n#define _SC_XOPEN_ENH_I18N\t93\n#define _SC_XOPEN_SHM\t94\n#define _SC_2_CHAR_TERM\t95\n#define _SC_2_UPE\t97\n#define _SC_XOPEN_XPG2\t98\n#define _SC_XOPEN_XPG3\t99\n#define _SC_XOPEN_XPG4\t100\n#define _SC_NZERO\t109\n#define _SC_XBS5_ILP32_OFF32\t125\n#define _SC_XBS5_ILP32_OFFBIG\t126\n#define _SC_XBS5_LP64_OFF64\t127\n#define _SC_XBS5_LPBIG_OFFBIG\t128\n#define _SC_XOPEN_LEGACY\t129\n#define _SC_XOPEN_REALTIME\t130\n#define _SC_XOPEN_REALTIME_THREADS\t131\n#define _SC_ADVISORY_INFO\t132\n#define _SC_BARRIERS\t133\n#define _SC_CLOCK_SELECTION\t137\n#define _SC_CPUTIME\t138\n#define _SC_THREAD_CPUTIME\t139\n#define _SC_MONOTONIC_CLOCK\t149\n#define _SC_READER_WRITER_LOCKS\t153\n#define _SC_SPIN_LOCKS\t154\n#define _SC_REGEXP\t155\n#define _SC_SHELL\t157\n#define _SC_SPAWN\t159\n#define _SC_SPORADIC_SERVER\t160\n#define _SC_THREAD_SPORADIC_SERVER\t161\n#define _SC_TIMEOUTS\t164\n#define _SC_TYPED_MEMORY_OBJECTS\t165\n#define _SC_2_PBS\t168\n#define _SC_2_PBS_ACCOUNTING\t169\n#define _SC_2_PBS_LOCATE\t170\n#define _SC_2_PBS_MESSAGE\t171\n#define _SC_2_PBS_TRACK\t172\n#define _SC_SYMLOOP_MAX\t173\n#define _SC_STREAMS\t174\n#define _SC_2_PBS_CHECKPOINT\t175\n#define _SC_V6_ILP32_OFF32\t176\n#define _SC_V6_ILP32_OFFBIG\t177\n#define _SC_V6_LP64_OFF64\t178\n#define _SC_V6_LPBIG_OFFBIG\t179\n#define _SC_HOST_NAME_MAX\t180\n#define _SC_TRACE\t181\n#define _SC_TRACE_EVENT_FILTER\t182\n#define _SC_TRACE_INHERIT\t183\n#define _SC_TRACE_LOG\t184\n\n#define _SC_IPV6\t235\n#define _SC_RAW_SOCKETS\t236\n#define _SC_V7_ILP32_OFF32\t237\n#define _SC_V7_ILP32_OFFBIG\t238\n#define _SC_V7_LP64_OFF64\t239\n#define _SC_V7_LPBIG_OFFBIG\t240\n#define _SC_SS_REPL_MAX\t241\n#define _SC_TRACE_EVENT_NAME_MAX\t242\n#define _SC_TRACE_NAME_MAX\t243\n#define _SC_TRACE_SYS_MAX\t244\n#define _SC_TRACE_USER_EVENT_MAX\t245\n#define _SC_XOPEN_STREAMS\t246\n#define _SC_THREAD_ROBUST_PRIO_INHERIT\t247\n#define _SC_THREAD_ROBUST_PRIO_PROTECT\t248\n\n#define _CS_PATH\t0\n#define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS\t1\n#define _CS_GNU_LIBC_VERSION\t2\n#define _CS_GNU_LIBPTHREAD_VERSION\t3\n#define _CS_POSIX_V5_WIDTH_RESTRICTED_ENVS\t4\n#define _CS_POSIX_V7_WIDTH_RESTRICTED_ENVS\t5\n\n#define _CS_POSIX_V6_ILP32_OFF32_CFLAGS\t1116\n#define _CS_POSIX_V6_ILP32_OFF32_LDFLAGS\t1117\n#define _CS_POSIX_V6_ILP32_OFF32_LIBS\t1118\n#define _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS\t1119\n#define _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS\t1120\n#define _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS\t1121\n#define _CS_POSIX_V6_ILP32_OFFBIG_LIBS\t1122\n#define _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS\t1123\n#define _CS_POSIX_V6_LP64_OFF64_CFLAGS\t1124\n#define _CS_POSIX_V6_LP64_OFF64_LDFLAGS\t1125\n#define _CS_POSIX_V6_LP64_OFF64_LIBS\t1126\n#define _CS_POSIX_V6_LP64_OFF64_LINTFLAGS\t1127\n#define _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS\t1128\n#define _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS\t1129\n#define _CS_POSIX_V6_LPBIG_OFFBIG_LIBS\t1130\n#define _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS\t1131\n#define _CS_POSIX_V7_ILP32_OFF32_CFLAGS\t1132\n#define _CS_POSIX_V7_ILP32_OFF32_LDFLAGS\t1133\n#define _CS_POSIX_V7_ILP32_OFF32_LIBS\t1134\n#define _CS_POSIX_V7_ILP32_OFF32_LINTFLAGS\t1135\n#define _CS_POSIX_V7_ILP32_OFFBIG_CFLAGS\t1136\n#define _CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS\t1137\n#define _CS_POSIX_V7_ILP32_OFFBIG_LIBS\t1138\n#define _CS_POSIX_V7_ILP32_OFFBIG_LINTFLAGS\t1139\n#define _CS_POSIX_V7_LP64_OFF64_CFLAGS\t1140\n#define _CS_POSIX_V7_LP64_OFF64_LDFLAGS\t1141\n#define _CS_POSIX_V7_LP64_OFF64_LIBS\t1142\n#define _CS_POSIX_V7_LP64_OFF64_LINTFLAGS\t1143\n#define _CS_POSIX_V7_LPBIG_OFFBIG_CFLAGS\t1144\n#define _CS_POSIX_V7_LPBIG_OFFBIG_LDFLAGS\t1145\n#define _CS_POSIX_V7_LPBIG_OFFBIG_LIBS\t1146\n#define _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS\t1147\n#define _CS_V6_ENV\t1148\n#define _CS_V7_ENV\t1149\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/utime.h",
    "content": "#ifndef\t_UTIME_H\n#define\t_UTIME_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_time_t\n\n#include <bits/alltypes.h>\n\nstruct utimbuf {\n\ttime_t actime;\n\ttime_t modtime;\n};\n\nint utime (const char *, const struct utimbuf *);\n\n#if _REDIR_TIME64\n__REDIR(utime, __utime64);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/utmp.h",
    "content": "#ifndef _UTMP_H\n#define _UTMP_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <utmpx.h>\n\n#define ACCOUNTING 9\n#define UT_NAMESIZE 32\n#define UT_HOSTSIZE 256\n#define UT_LINESIZE 32\n\nstruct lastlog {\n\ttime_t ll_time;\n\tchar ll_line[UT_LINESIZE];\n\tchar ll_host[UT_HOSTSIZE];\n};\n\n#define ut_time ut_tv.tv_sec\n#define ut_name ut_user\n#define ut_addr ut_addr_v6[0]\n#define utmp utmpx\n#define e_exit __e_exit\n#define e_termination __e_termination\n\nvoid         endutent(void);\nstruct utmp *getutent(void);\nstruct utmp *getutid(const struct utmp *);\nstruct utmp *getutline(const struct utmp *);\nstruct utmp *pututline(const struct utmp *);\nvoid         setutent(void);\n\nvoid updwtmp(const char *, const struct utmp *);\nint utmpname(const char *);\n\nint login_tty(int);\n\n#define _PATH_UTMP \"/dev/null/utmp\"\n#define _PATH_WTMP \"/dev/null/wtmp\"\n\n#define UTMP_FILE _PATH_UTMP\n#define WTMP_FILE _PATH_WTMP\n#define UTMP_FILENAME _PATH_UTMP\n#define WTMP_FILENAME _PATH_WTMP\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/utmpx.h",
    "content": "#ifndef _UTMPX_H\n#define _UTMPX_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_pid_t\n#define __NEED_time_t\n#define __NEED_suseconds_t\n#define __NEED_struct_timeval\n\n#include <bits/alltypes.h>\n\nstruct utmpx {\n\tshort ut_type;\n\tshort __ut_pad1;\n\tpid_t ut_pid;\n\tchar ut_line[32];\n\tchar ut_id[4];\n\tchar ut_user[32];\n\tchar ut_host[256];\n\tstruct {\n\t\tshort __e_termination;\n\t\tshort __e_exit;\n\t} ut_exit;\n#if __BYTE_ORDER == 1234\n\tint ut_session, __ut_pad2;\n#else\n\tint __ut_pad2, ut_session;\n#endif\n\tstruct timeval ut_tv;\n\tunsigned ut_addr_v6[4];\n\tchar __unused[20];\n};\n\nvoid          endutxent(void);\nstruct utmpx *getutxent(void);\nstruct utmpx *getutxid(const struct utmpx *);\nstruct utmpx *getutxline(const struct utmpx *);\nstruct utmpx *pututxline(const struct utmpx *);\nvoid          setutxent(void);\n\n#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)\n#define e_exit __e_exit\n#define e_termination __e_termination\nvoid updwtmpx(const char *, const struct utmpx *);\nint utmpxname(const char *);\n#endif\n\n#define EMPTY           0\n#define RUN_LVL         1\n#define BOOT_TIME       2\n#define NEW_TIME        3\n#define OLD_TIME        4\n#define INIT_PROCESS    5\n#define LOGIN_PROCESS   6\n#define USER_PROCESS    7\n#define DEAD_PROCESS    8\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/values.h",
    "content": "#ifndef _VALUES_H\n#define _VALUES_H\n\n#include <limits.h>\n\n#define CHARBITS   (sizeof(char)   * 8)\n#define SHORTBITS  (sizeof(short)  * 8)\n#define INTBITS    (sizeof(int)    * 8)\n#define LONGBITS   (sizeof(long)   * 8)\n#define PTRBITS    (sizeof(char *) * 8)\n#define DOUBLEBITS (sizeof(double) * 8)\n#define FLOATBITS  (sizeof(float)  * 8)\n\n#define MINSHORT SHRT_MIN\n#define MININT   INT_MIN\n#define MINLONG  LONG_MIN\n\n#define MAXSHORT SHRT_MAX\n#define MAXINT   INT_MAX\n#define MAXLONG  LONG_MAX\n\n#define HIBITS   MINSHORT\n#define HIBITL   MINLONG\n\n#include <float.h>\n\n#define MAXDOUBLE DBL_MAX\n#undef  MAXFLOAT\n#define MAXFLOAT  FLT_MAX\n#define MINDOUBLE DBL_MIN\n#define MINFLOAT  FLT_MIN\n#define DMINEXP   DBL_MIN_EXP\n#define FMINEXP   FLT_MIN_EXP\n#define DMAXEXP   DBL_MAX_EXP\n#define FMAXEXP   FLT_MAX_EXP\n\n#define BITSPERBYTE CHAR_BIT\n\n#endif\n"
  },
  {
    "path": "user.libc/include/wait.h",
    "content": "#warning redirecting incorrect #include <wait.h> to <sys/wait.h>\n#include <sys/wait.h>\n"
  },
  {
    "path": "user.libc/include/wchar.h",
    "content": "#ifndef _WCHAR_H\n#define _WCHAR_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_FILE\n#define __NEED___isoc_va_list\n#define __NEED_size_t\n#define __NEED_wchar_t\n#define __NEED_wint_t\n#define __NEED_mbstate_t\n\n#if __STDC_VERSION__ < 201112L\n#define __NEED_struct__IO_FILE\n#endif\n\n#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define __NEED_locale_t\n#define __NEED_va_list\n#endif\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define __NEED_wctype_t\n#endif\n\n#include <bits/alltypes.h>\n\n#if L'\\0'-1 > 0\n#define WCHAR_MAX (0xffffffffu+L'\\0')\n#define WCHAR_MIN (0+L'\\0')\n#else\n#define WCHAR_MAX (0x7fffffff+L'\\0')\n#define WCHAR_MIN (-1-0x7fffffff+L'\\0')\n#endif\n\n#ifdef __cplusplus\n#define NULL 0L\n#else\n#define NULL ((void*)0)\n#endif\n\n#undef WEOF\n#define WEOF 0xffffffffU\n\nwchar_t *wcscpy (wchar_t *__restrict, const wchar_t *__restrict);\nwchar_t *wcsncpy (wchar_t *__restrict, const wchar_t *__restrict, size_t);\n\nwchar_t *wcscat (wchar_t *__restrict, const wchar_t *__restrict);\nwchar_t *wcsncat (wchar_t *__restrict, const wchar_t *__restrict, size_t);\n\nint wcscmp (const wchar_t *, const wchar_t *);\nint wcsncmp (const wchar_t *, const wchar_t *, size_t);\n\nint wcscoll(const wchar_t *, const wchar_t *);\nsize_t wcsxfrm (wchar_t *__restrict, const wchar_t *__restrict, size_t);\n\nwchar_t *wcschr (const wchar_t *, wchar_t);\nwchar_t *wcsrchr (const wchar_t *, wchar_t);\n\nsize_t wcscspn (const wchar_t *, const wchar_t *);\nsize_t wcsspn (const wchar_t *, const wchar_t *);\nwchar_t *wcspbrk (const wchar_t *, const wchar_t *);\n\nwchar_t *wcstok (wchar_t *__restrict, const wchar_t *__restrict, wchar_t **__restrict);\n\nsize_t wcslen (const wchar_t *);\n\nwchar_t *wcsstr (const wchar_t *__restrict, const wchar_t *__restrict);\nwchar_t *wcswcs (const wchar_t *, const wchar_t *);\n\nwchar_t *wmemchr (const wchar_t *, wchar_t, size_t);\nint wmemcmp (const wchar_t *, const wchar_t *, size_t);\nwchar_t *wmemcpy (wchar_t *__restrict, const wchar_t *__restrict, size_t);\nwchar_t *wmemmove (wchar_t *, const wchar_t *, size_t);\nwchar_t *wmemset (wchar_t *, wchar_t, size_t);\n\nwint_t btowc (int);\nint wctob (wint_t);\n\nint mbsinit (const mbstate_t *);\nsize_t mbrtowc (wchar_t *__restrict, const char *__restrict, size_t, mbstate_t *__restrict);\nsize_t wcrtomb (char *__restrict, wchar_t, mbstate_t *__restrict);\n\nsize_t mbrlen (const char *__restrict, size_t, mbstate_t *__restrict);\n\nsize_t mbsrtowcs (wchar_t *__restrict, const char **__restrict, size_t, mbstate_t *__restrict);\nsize_t wcsrtombs (char *__restrict, const wchar_t **__restrict, size_t, mbstate_t *__restrict);\n\nfloat wcstof (const wchar_t *__restrict, wchar_t **__restrict);\ndouble wcstod (const wchar_t *__restrict, wchar_t **__restrict);\nlong double wcstold (const wchar_t *__restrict, wchar_t **__restrict);\n\nlong wcstol (const wchar_t *__restrict, wchar_t **__restrict, int);\nunsigned long wcstoul (const wchar_t *__restrict, wchar_t **__restrict, int);\n\nlong long wcstoll (const wchar_t *__restrict, wchar_t **__restrict, int);\nunsigned long long wcstoull (const wchar_t *__restrict, wchar_t **__restrict, int);\n\n\n\nint fwide (FILE *, int);\n\n\nint wprintf (const wchar_t *__restrict, ...);\nint fwprintf (FILE *__restrict, const wchar_t *__restrict, ...);\nint swprintf (wchar_t *__restrict, size_t, const wchar_t *__restrict, ...);\n\nint vwprintf (const wchar_t *__restrict, __isoc_va_list);\nint vfwprintf (FILE *__restrict, const wchar_t *__restrict, __isoc_va_list);\nint vswprintf (wchar_t *__restrict, size_t, const wchar_t *__restrict, __isoc_va_list);\n\nint wscanf (const wchar_t *__restrict, ...);\nint fwscanf (FILE *__restrict, const wchar_t *__restrict, ...);\nint swscanf (const wchar_t *__restrict, const wchar_t *__restrict, ...);\n\nint vwscanf (const wchar_t *__restrict, __isoc_va_list);\nint vfwscanf (FILE *__restrict, const wchar_t *__restrict, __isoc_va_list);\nint vswscanf (const wchar_t *__restrict, const wchar_t *__restrict, __isoc_va_list);\n\nwint_t fgetwc (FILE *);\nwint_t getwc (FILE *);\nwint_t getwchar (void);\n\nwint_t fputwc (wchar_t, FILE *);\nwint_t putwc (wchar_t, FILE *);\nwint_t putwchar (wchar_t);\n\nwchar_t *fgetws (wchar_t *__restrict, int, FILE *__restrict);\nint fputws (const wchar_t *__restrict, FILE *__restrict);\n\nwint_t ungetwc (wint_t, FILE *);\n\nstruct tm;\nsize_t wcsftime (wchar_t *__restrict, size_t, const wchar_t *__restrict, const struct tm *__restrict);\n\n#undef iswdigit\n\n#if defined(_GNU_SOURCE)\nwint_t fgetwc_unlocked (FILE *);\nwint_t getwc_unlocked (FILE *);\nwint_t getwchar_unlocked (void);\nwint_t fputwc_unlocked (wchar_t, FILE *);\nwint_t putwc_unlocked (wchar_t, FILE *);\nwint_t putwchar_unlocked (wchar_t);\nwchar_t *fgetws_unlocked (wchar_t *__restrict, int, FILE *__restrict);\nint fputws_unlocked (const wchar_t *__restrict, FILE *__restrict);\n#endif\n\n#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\nsize_t wcsftime_l (wchar_t *__restrict, size_t, const wchar_t *__restrict, const struct tm *__restrict, locale_t);\n#endif\n\n#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE)  || defined(_BSD_SOURCE)\nFILE *open_wmemstream(wchar_t **, size_t *);\nsize_t mbsnrtowcs(wchar_t *__restrict, const char **__restrict, size_t, size_t, mbstate_t *__restrict);\nsize_t wcsnrtombs(char *__restrict, const wchar_t **__restrict, size_t, size_t, mbstate_t *__restrict);\nwchar_t *wcsdup(const wchar_t *);\nsize_t wcsnlen (const wchar_t *, size_t);\nwchar_t *wcpcpy (wchar_t *__restrict, const wchar_t *__restrict);\nwchar_t *wcpncpy (wchar_t *__restrict, const wchar_t *__restrict, size_t);\nint wcscasecmp(const wchar_t *, const wchar_t *);\nint wcscasecmp_l(const wchar_t *, const wchar_t *, locale_t);\nint wcsncasecmp(const wchar_t *, const wchar_t *, size_t);\nint wcsncasecmp_l(const wchar_t *, const wchar_t *, size_t, locale_t);\nint wcscoll_l(const wchar_t *, const wchar_t *, locale_t);\nsize_t wcsxfrm_l(wchar_t *__restrict, const wchar_t *__restrict, size_t, locale_t);\n#endif\n\n#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\nint wcwidth (wchar_t);\nint wcswidth (const wchar_t *, size_t);\nint       iswalnum(wint_t);\nint       iswalpha(wint_t);\nint       iswblank(wint_t);\nint       iswcntrl(wint_t);\nint       iswdigit(wint_t);\nint       iswgraph(wint_t);\nint       iswlower(wint_t);\nint       iswprint(wint_t);\nint       iswpunct(wint_t);\nint       iswspace(wint_t);\nint       iswupper(wint_t);\nint       iswxdigit(wint_t);\nint       iswctype(wint_t, wctype_t);\nwint_t    towlower(wint_t);\nwint_t    towupper(wint_t);\nwctype_t  wctype(const char *);\n\n#ifndef __cplusplus\n#undef iswdigit\n#define iswdigit(a) (0 ? iswdigit(a) : ((unsigned)(a)-'0') < 10)\n#endif\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/wctype.h",
    "content": "#ifndef _WCTYPE_H\n#define _WCTYPE_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_wint_t\n#define __NEED_wctype_t\n\n#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n#define __NEED_locale_t\n#endif\n\n#include <bits/alltypes.h>\n\ntypedef const int * wctrans_t;\n\n#undef WEOF\n#define WEOF 0xffffffffU\n\n#undef iswdigit\n\nint       iswalnum(wint_t);\nint       iswalpha(wint_t);\nint       iswblank(wint_t);\nint       iswcntrl(wint_t);\nint       iswdigit(wint_t);\nint       iswgraph(wint_t);\nint       iswlower(wint_t);\nint       iswprint(wint_t);\nint       iswpunct(wint_t);\nint       iswspace(wint_t);\nint       iswupper(wint_t);\nint       iswxdigit(wint_t);\nint       iswctype(wint_t, wctype_t);\nwint_t    towctrans(wint_t, wctrans_t);\nwint_t    towlower(wint_t);\nwint_t    towupper(wint_t);\nwctrans_t wctrans(const char *);\nwctype_t  wctype(const char *);\n\n#ifndef __cplusplus\n#undef iswdigit\n#define iswdigit(a) (0 ? iswdigit(a) : ((unsigned)(a)-'0') < 10)\n#endif\n\n#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \\\n || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)\n\nint iswalnum_l(wint_t, locale_t);\nint iswalpha_l(wint_t, locale_t);\nint iswblank_l(wint_t, locale_t);\nint iswcntrl_l(wint_t, locale_t);\nint iswdigit_l(wint_t, locale_t);\nint iswgraph_l(wint_t, locale_t);\nint iswlower_l(wint_t, locale_t);\nint iswprint_l(wint_t, locale_t);\nint iswpunct_l(wint_t, locale_t);\nint iswspace_l(wint_t, locale_t);\nint iswupper_l(wint_t, locale_t);\nint iswxdigit_l(wint_t, locale_t);\nint iswctype_l(wint_t, wctype_t, locale_t);\nwint_t towlower_l(wint_t, locale_t);\nwint_t towupper_l(wint_t, locale_t);\nwint_t towctrans_l(wint_t, wctrans_t, locale_t);\nwctrans_t wctrans_l(const char *, locale_t);\nwctype_t  wctype_l(const char *, locale_t);\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/include/wordexp.h",
    "content": "#ifndef\t_WORDEXP_H\n#define\t_WORDEXP_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <features.h>\n\n#define __NEED_size_t\n\n#include <bits/alltypes.h>\n\n#define WRDE_DOOFFS  1\n#define WRDE_APPEND  2\n#define WRDE_NOCMD   4\n#define WRDE_REUSE   8\n#define WRDE_SHOWERR 16\n#define WRDE_UNDEF   32\n\ntypedef struct {\n\tsize_t we_wordc;\n\tchar **we_wordv;\n\tsize_t we_offs;\n} wordexp_t;\n\n#define WRDE_NOSYS   -1\n#define WRDE_NOSPACE 1\n#define WRDE_BADCHAR 2\n#define WRDE_BADVAL  3\n#define WRDE_CMDSUB  4\n#define WRDE_SYNTAX  5\n\nint wordexp (const char *__restrict, wordexp_t *__restrict, int);\nvoid wordfree (wordexp_t *);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/ldso/dlstart.c",
    "content": "#include <stddef.h>\n#include \"dynlink.h\"\n#include \"libc.h\"\n\n#ifndef START\n#define START \"_dlstart\"\n#endif\n\n#define SHARED\n\n#include \"crt_arch.h\"\n\n#ifndef GETFUNCSYM\n#define GETFUNCSYM(fp, sym, got) do { \\\n\thidden void sym(); \\\n\tstatic void (*static_func_ptr)() = sym; \\\n\t__asm__ __volatile__ ( \"\" : \"+m\"(static_func_ptr) : : \"memory\"); \\\n\t*(fp) = static_func_ptr; } while(0)\n#endif\n\nhidden void _dlstart_c(size_t *sp, size_t *dynv)\n{\n\tsize_t i, aux[AUX_CNT], dyn[DYN_CNT];\n\tsize_t *rel, rel_size, base;\n\n\tint argc = *sp;\n\tchar **argv = (void *)(sp+1);\n\n\tfor (i=argc+1; argv[i]; i++);\n\tsize_t *auxv = (void *)(argv+i+1);\n\n\tfor (i=0; i<AUX_CNT; i++) aux[i] = 0;\n\tfor (i=0; auxv[i]; i+=2) if (auxv[i]<AUX_CNT)\n\t\taux[auxv[i]] = auxv[i+1];\n\n#if DL_FDPIC\n\tstruct fdpic_loadseg *segs, fakeseg;\n\tsize_t j;\n\tif (dynv) {\n\t\t/* crt_arch.h entry point asm is responsible for reserving\n\t\t * space and moving the extra fdpic arguments to the stack\n\t\t * vector where they are easily accessible from C. */\n\t\tsegs = ((struct fdpic_loadmap *)(sp[-1] ? sp[-1] : sp[-2]))->segs;\n\t} else {\n\t\t/* If dynv is null, the entry point was started from loader\n\t\t * that is not fdpic-aware. We can assume normal fixed-\n\t\t * displacement ELF loading was performed, but when ldso was\n\t\t * run as a command, finding the Ehdr is a heursitic: we\n\t\t * have to assume Phdrs start in the first 4k of the file. */\n\t\tbase = aux[AT_BASE];\n\t\tif (!base) base = aux[AT_PHDR] & -4096;\n\t\tsegs = &fakeseg;\n\t\tsegs[0].addr = base;\n\t\tsegs[0].p_vaddr = 0;\n\t\tsegs[0].p_memsz = -1;\n\t\tEhdr *eh = (void *)base;\n\t\tPhdr *ph = (void *)(base + eh->e_phoff);\n\t\tsize_t phnum = eh->e_phnum;\n\t\tsize_t phent = eh->e_phentsize;\n\t\twhile (phnum-- && ph->p_type != PT_DYNAMIC)\n\t\t\tph = (void *)((size_t)ph + phent);\n\t\tdynv = (void *)(base + ph->p_vaddr);\n\t}\n#endif\n\n\tfor (i=0; i<DYN_CNT; i++) dyn[i] = 0;\n\tfor (i=0; dynv[i]; i+=2) if (dynv[i]<DYN_CNT)\n\t\tdyn[dynv[i]] = dynv[i+1];\n\n#if DL_FDPIC\n\tfor (i=0; i<DYN_CNT; i++) {\n\t\tif (i==DT_RELASZ || i==DT_RELSZ) continue;\n\t\tif (!dyn[i]) continue;\n\t\tfor (j=0; dyn[i]-segs[j].p_vaddr >= segs[j].p_memsz; j++);\n\t\tdyn[i] += segs[j].addr - segs[j].p_vaddr;\n\t}\n\tbase = 0;\n\n\tconst Sym *syms = (void *)dyn[DT_SYMTAB];\n\n\trel = (void *)dyn[DT_RELA];\n\trel_size = dyn[DT_RELASZ];\n\tfor (; rel_size; rel+=3, rel_size-=3*sizeof(size_t)) {\n\t\tif (!IS_RELATIVE(rel[1], syms)) continue;\n\t\tfor (j=0; rel[0]-segs[j].p_vaddr >= segs[j].p_memsz; j++);\n\t\tsize_t *rel_addr = (void *)\n\t\t\t(rel[0] + segs[j].addr - segs[j].p_vaddr);\n\t\tif (R_TYPE(rel[1]) == REL_FUNCDESC_VAL) {\n\t\t\t*rel_addr += segs[rel_addr[1]].addr\n\t\t\t\t- segs[rel_addr[1]].p_vaddr\n\t\t\t\t+ syms[R_SYM(rel[1])].st_value;\n\t\t\trel_addr[1] = dyn[DT_PLTGOT];\n\t\t} else {\n\t\t\tsize_t val = syms[R_SYM(rel[1])].st_value;\n\t\t\tfor (j=0; val-segs[j].p_vaddr >= segs[j].p_memsz; j++);\n\t\t\t*rel_addr = rel[2] + segs[j].addr - segs[j].p_vaddr + val;\n\t\t}\n\t}\n#else\n\t/* If the dynamic linker is invoked as a command, its load\n\t * address is not available in the aux vector. Instead, compute\n\t * the load address as the difference between &_DYNAMIC and the\n\t * virtual address in the PT_DYNAMIC program header. */\n\tbase = aux[AT_BASE];\n\tif (!base) {\n\t\tsize_t phnum = aux[AT_PHNUM];\n\t\tsize_t phentsize = aux[AT_PHENT];\n\t\tPhdr *ph = (void *)aux[AT_PHDR];\n\t\tfor (i=phnum; i--; ph = (void *)((char *)ph + phentsize)) {\n\t\t\tif (ph->p_type == PT_DYNAMIC) {\n\t\t\t\tbase = (size_t)dynv - ph->p_vaddr;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t/* MIPS uses an ugly packed form for GOT relocations. Since we\n\t * can't make function calls yet and the code is tiny anyway,\n\t * it's simply inlined here. */\n\tif (NEED_MIPS_GOT_RELOCS) {\n\t\tsize_t local_cnt = 0;\n\t\tsize_t *got = (void *)(base + dyn[DT_PLTGOT]);\n\t\tfor (i=0; dynv[i]; i+=2) if (dynv[i]==DT_MIPS_LOCAL_GOTNO)\n\t\t\tlocal_cnt = dynv[i+1];\n\t\tfor (i=0; i<local_cnt; i++) got[i] += base;\n\t}\n\n\trel = (void *)(base+dyn[DT_REL]);\n\trel_size = dyn[DT_RELSZ];\n\tfor (; rel_size; rel+=2, rel_size-=2*sizeof(size_t)) {\n\t\tif (!IS_RELATIVE(rel[1], 0)) continue;\n\t\tsize_t *rel_addr = (void *)(base + rel[0]);\n\t\t*rel_addr += base;\n\t}\n\n\trel = (void *)(base+dyn[DT_RELA]);\n\trel_size = dyn[DT_RELASZ];\n\tfor (; rel_size; rel+=3, rel_size-=3*sizeof(size_t)) {\n\t\tif (!IS_RELATIVE(rel[1], 0)) continue;\n\t\tsize_t *rel_addr = (void *)(base + rel[0]);\n\t\t*rel_addr = base + rel[2];\n\t}\n#endif\n\n\tstage2_func dls2;\n\tGETFUNCSYM(&dls2, __dls2, base+dyn[DT_PLTGOT]);\n\tdls2((void *)base, sp);\n}\n"
  },
  {
    "path": "user.libc/ldso/dynlink.c",
    "content": "#define _GNU_SOURCE\n#define SYSCALL_NO_TLS 1\n#include <stdlib.h>\n#include <stdarg.h>\n#include <stddef.h>\n#include <string.h>\n#include <unistd.h>\n#include <stdint.h>\n#include <elf.h>\n#include <sys/mman.h>\n#include <limits.h>\n#include <fcntl.h>\n#include <sys/stat.h>\n#include <errno.h>\n#include <link.h>\n#include <setjmp.h>\n#include <pthread.h>\n#include <ctype.h>\n#include <dlfcn.h>\n#include <semaphore.h>\n#include <sys/membarrier.h>\n#include \"pthread_impl.h\"\n#include \"fork_impl.h\"\n#include \"libc.h\"\n#include \"dynlink.h\"\n\n#define malloc __libc_malloc\n#define calloc __libc_calloc\n#define realloc __libc_realloc\n#define free __libc_free\n\nstatic void error(const char *, ...);\n\n#define MAXP2(a,b) (-(-(a)&-(b)))\n#define ALIGN(x,y) ((x)+(y)-1 & -(y))\n\n#define container_of(p,t,m) ((t*)((char *)(p)-offsetof(t,m)))\n#define countof(a) ((sizeof (a))/(sizeof (a)[0]))\n\nstruct debug {\n\tint ver;\n\tvoid *head;\n\tvoid (*bp)(void);\n\tint state;\n\tvoid *base;\n};\n\nstruct td_index {\n\tsize_t args[2];\n\tstruct td_index *next;\n};\n\nstruct dso {\n#if DL_FDPIC\n\tstruct fdpic_loadmap *loadmap;\n#else\n\tunsigned char *base;\n#endif\n\tchar *name;\n\tsize_t *dynv;\n\tstruct dso *next, *prev;\n\n\tPhdr *phdr;\n\tint phnum;\n\tsize_t phentsize;\n\tSym *syms;\n\tElf_Symndx *hashtab;\n\tuint32_t *ghashtab;\n\tint16_t *versym;\n\tchar *strings;\n\tstruct dso *syms_next, *lazy_next;\n\tsize_t *lazy, lazy_cnt;\n\tunsigned char *map;\n\tsize_t map_len;\n\tdev_t dev;\n\tino_t ino;\n\tchar relocated;\n\tchar constructed;\n\tchar kernel_mapped;\n\tchar mark;\n\tchar bfs_built;\n\tchar runtime_loaded;\n\tstruct dso **deps, *needed_by;\n\tsize_t ndeps_direct;\n\tsize_t next_dep;\n\tpthread_t ctor_visitor;\n\tchar *rpath_orig, *rpath;\n\tstruct tls_module tls;\n\tsize_t tls_id;\n\tsize_t relro_start, relro_end;\n\tuintptr_t *new_dtv;\n\tunsigned char *new_tls;\n\tstruct td_index *td_index;\n\tstruct dso *fini_next;\n\tchar *shortname;\n#if DL_FDPIC\n\tunsigned char *base;\n#else\n\tstruct fdpic_loadmap *loadmap;\n#endif\n\tstruct funcdesc {\n\t\tvoid *addr;\n\t\tsize_t *got;\n\t} *funcdescs;\n\tsize_t *got;\n\tchar buf[];\n};\n\nstruct symdef {\n\tSym *sym;\n\tstruct dso *dso;\n};\n\ntypedef void (*stage3_func)(size_t *, size_t *);\n\nstatic struct builtin_tls {\n\tchar c;\n\tstruct pthread pt;\n\tvoid *space[16];\n} builtin_tls[1];\n#define MIN_TLS_ALIGN offsetof(struct builtin_tls, pt)\n\n#define ADDEND_LIMIT 4096\nstatic size_t *saved_addends, *apply_addends_to;\n\nstatic struct dso ldso;\nstatic struct dso *head, *tail, *fini_head, *syms_tail, *lazy_head;\nstatic char *env_path, *sys_path;\nstatic unsigned long long gencnt;\nstatic int runtime;\nstatic int ldd_mode;\nstatic int ldso_fail;\nstatic int noload;\nstatic int shutting_down;\nstatic jmp_buf *rtld_fail;\nstatic pthread_rwlock_t lock;\nstatic struct debug debug;\nstatic struct tls_module *tls_tail;\nstatic size_t tls_cnt, tls_offset, tls_align = MIN_TLS_ALIGN;\nstatic size_t static_tls_cnt;\nstatic pthread_mutex_t init_fini_lock;\nstatic pthread_cond_t ctor_cond;\nstatic struct dso *builtin_deps[2];\nstatic struct dso *const no_deps[1];\nstatic struct dso *builtin_ctor_queue[4];\nstatic struct dso **main_ctor_queue;\nstatic struct fdpic_loadmap *app_loadmap;\nstatic struct fdpic_dummy_loadmap app_dummy_loadmap;\n\nstruct debug *_dl_debug_addr = &debug;\n\nextern hidden int __malloc_replaced;\n\nhidden void (*const __init_array_start)(void)=0, (*const __fini_array_start)(void)=0;\n\nextern hidden void (*const __init_array_end)(void), (*const __fini_array_end)(void);\n\nweak_alias(__init_array_start, __init_array_end);\nweak_alias(__fini_array_start, __fini_array_end);\n\nstatic int dl_strcmp(const char *l, const char *r)\n{\n\tfor (; *l==*r && *l; l++, r++);\n\treturn *(unsigned char *)l - *(unsigned char *)r;\n}\n#define strcmp(l,r) dl_strcmp(l,r)\n\n/* Compute load address for a virtual address in a given dso. */\n#if DL_FDPIC\nstatic void *laddr(const struct dso *p, size_t v)\n{\n\tsize_t j=0;\n\tif (!p->loadmap) return p->base + v;\n\tfor (j=0; v-p->loadmap->segs[j].p_vaddr >= p->loadmap->segs[j].p_memsz; j++);\n\treturn (void *)(v - p->loadmap->segs[j].p_vaddr + p->loadmap->segs[j].addr);\n}\nstatic void *laddr_pg(const struct dso *p, size_t v)\n{\n\tsize_t j=0;\n\tsize_t pgsz = PAGE_SIZE;\n\tif (!p->loadmap) return p->base + v;\n\tfor (j=0; ; j++) {\n\t\tsize_t a = p->loadmap->segs[j].p_vaddr;\n\t\tsize_t b = a + p->loadmap->segs[j].p_memsz;\n\t\ta &= -pgsz;\n\t\tb += pgsz-1;\n\t\tb &= -pgsz;\n\t\tif (v-a<b-a) break;\n\t}\n\treturn (void *)(v - p->loadmap->segs[j].p_vaddr + p->loadmap->segs[j].addr);\n}\nstatic void (*fdbarrier(void *p))()\n{\n\tvoid (*fd)();\n\t__asm__(\"\" : \"=r\"(fd) : \"0\"(p));\n\treturn fd;\n}\n#define fpaddr(p, v) fdbarrier((&(struct funcdesc){ \\\n\tladdr(p, v), (p)->got }))\n#else\n#define laddr(p, v) (void *)((p)->base + (v))\n#define laddr_pg(p, v) laddr(p, v)\n#define fpaddr(p, v) ((void (*)())laddr(p, v))\n#endif\n\nstatic void decode_vec(size_t *v, size_t *a, size_t cnt)\n{\n\tsize_t i;\n\tfor (i=0; i<cnt; i++) a[i] = 0;\n\tfor (; v[0]; v+=2) if (v[0]-1<cnt-1) {\n\t\ta[0] |= 1UL<<v[0];\n\t\ta[v[0]] = v[1];\n\t}\n}\n\nstatic int search_vec(size_t *v, size_t *r, size_t key)\n{\n\tfor (; v[0]!=key; v+=2)\n\t\tif (!v[0]) return 0;\n\t*r = v[1];\n\treturn 1;\n}\n\nstatic uint32_t sysv_hash(const char *s0)\n{\n\tconst unsigned char *s = (void *)s0;\n\tuint_fast32_t h = 0;\n\twhile (*s) {\n\t\th = 16*h + *s++;\n\t\th ^= h>>24 & 0xf0;\n\t}\n\treturn h & 0xfffffff;\n}\n\nstatic uint32_t gnu_hash(const char *s0)\n{\n\tconst unsigned char *s = (void *)s0;\n\tuint_fast32_t h = 5381;\n\tfor (; *s; s++)\n\t\th += h*32 + *s;\n\treturn h;\n}\n\nstatic Sym *sysv_lookup(const char *s, uint32_t h, struct dso *dso)\n{\n\tsize_t i;\n\tSym *syms = dso->syms;\n\tElf_Symndx *hashtab = dso->hashtab;\n\tchar *strings = dso->strings;\n\tfor (i=hashtab[2+h%hashtab[0]]; i; i=hashtab[2+hashtab[0]+i]) {\n\t\tif ((!dso->versym || dso->versym[i] >= 0)\n\t\t    && (!strcmp(s, strings+syms[i].st_name)))\n\t\t\treturn syms+i;\n\t}\n\treturn 0;\n}\n\nstatic Sym *gnu_lookup(uint32_t h1, uint32_t *hashtab, struct dso *dso, const char *s)\n{\n\tuint32_t nbuckets = hashtab[0];\n\tuint32_t *buckets = hashtab + 4 + hashtab[2]*(sizeof(size_t)/4);\n\tuint32_t i = buckets[h1 % nbuckets];\n\n\tif (!i) return 0;\n\n\tuint32_t *hashval = buckets + nbuckets + (i - hashtab[1]);\n\n\tfor (h1 |= 1; ; i++) {\n\t\tuint32_t h2 = *hashval++;\n\t\tif ((h1 == (h2|1)) && (!dso->versym || dso->versym[i] >= 0)\n\t\t    && !strcmp(s, dso->strings + dso->syms[i].st_name))\n\t\t\treturn dso->syms+i;\n\t\tif (h2 & 1) break;\n\t}\n\n\treturn 0;\n}\n\nstatic Sym *gnu_lookup_filtered(uint32_t h1, uint32_t *hashtab, struct dso *dso, const char *s, uint32_t fofs, size_t fmask)\n{\n\tconst size_t *bloomwords = (const void *)(hashtab+4);\n\tsize_t f = bloomwords[fofs & (hashtab[2]-1)];\n\tif (!(f & fmask)) return 0;\n\n\tf >>= (h1 >> hashtab[3]) % (8 * sizeof f);\n\tif (!(f & 1)) return 0;\n\n\treturn gnu_lookup(h1, hashtab, dso, s);\n}\n\n#define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON | 1<<STT_TLS)\n#define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK | 1<<STB_GNU_UNIQUE)\n\n#ifndef ARCH_SYM_REJECT_UND\n#define ARCH_SYM_REJECT_UND(s) 0\n#endif\n\n#if defined(__GNUC__)\n__attribute__((always_inline))\n#endif\nstatic inline struct symdef find_sym2(struct dso *dso, const char *s, int need_def, int use_deps)\n{\n\tuint32_t h = 0, gh = gnu_hash(s), gho = gh / (8*sizeof(size_t)), *ght;\n\tsize_t ghm = 1ul << gh % (8*sizeof(size_t));\n\tstruct symdef def = {0};\n\tstruct dso **deps = use_deps ? dso->deps : 0;\n\tfor (; dso; dso=use_deps ? *deps++ : dso->syms_next) {\n\t\tSym *sym;\n\t\tif ((ght = dso->ghashtab)) {\n\t\t\tsym = gnu_lookup_filtered(gh, ght, dso, s, gho, ghm);\n\t\t} else {\n\t\t\tif (!h) h = sysv_hash(s);\n\t\t\tsym = sysv_lookup(s, h, dso);\n\t\t}\n\t\tif (!sym) continue;\n\t\tif (!sym->st_shndx)\n\t\t\tif (need_def || (sym->st_info&0xf) == STT_TLS\n\t\t\t    || ARCH_SYM_REJECT_UND(sym))\n\t\t\t\tcontinue;\n\t\tif (!sym->st_value)\n\t\t\tif ((sym->st_info&0xf) != STT_TLS)\n\t\t\t\tcontinue;\n\t\tif (!(1<<(sym->st_info&0xf) & OK_TYPES)) continue;\n\t\tif (!(1<<(sym->st_info>>4) & OK_BINDS)) continue;\n\t\tdef.sym = sym;\n\t\tdef.dso = dso;\n\t\tbreak;\n\t}\n\treturn def;\n}\n\nstatic struct symdef find_sym(struct dso *dso, const char *s, int need_def)\n{\n\treturn find_sym2(dso, s, need_def, 0);\n}\n\nstatic void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stride)\n{\n\tunsigned char *base = dso->base;\n\tSym *syms = dso->syms;\n\tchar *strings = dso->strings;\n\tSym *sym;\n\tconst char *name;\n\tvoid *ctx;\n\tint type;\n\tint sym_index;\n\tstruct symdef def;\n\tsize_t *reloc_addr;\n\tsize_t sym_val;\n\tsize_t tls_val;\n\tsize_t addend;\n\tint skip_relative = 0, reuse_addends = 0, save_slot = 0;\n\n\tif (dso == &ldso) {\n\t\t/* Only ldso's REL table needs addend saving/reuse. */\n\t\tif (rel == apply_addends_to)\n\t\t\treuse_addends = 1;\n\t\tskip_relative = 1;\n\t}\n\n\tfor (; rel_size; rel+=stride, rel_size-=stride*sizeof(size_t)) {\n\t\tif (skip_relative && IS_RELATIVE(rel[1], dso->syms)) continue;\n\t\ttype = R_TYPE(rel[1]);\n\t\tif (type == REL_NONE) continue;\n\t\treloc_addr = laddr(dso, rel[0]);\n\n\t\tif (stride > 2) {\n\t\t\taddend = rel[2];\n\t\t} else if (type==REL_GOT || type==REL_PLT|| type==REL_COPY) {\n\t\t\taddend = 0;\n\t\t} else if (reuse_addends) {\n\t\t\t/* Save original addend in stage 2 where the dso\n\t\t\t * chain consists of just ldso; otherwise read back\n\t\t\t * saved addend since the inline one was clobbered. */\n\t\t\tif (head==&ldso)\n\t\t\t\tsaved_addends[save_slot] = *reloc_addr;\n\t\t\taddend = saved_addends[save_slot++];\n\t\t} else {\n\t\t\taddend = *reloc_addr;\n\t\t}\n\n\t\tsym_index = R_SYM(rel[1]);\n\t\tif (sym_index) {\n\t\t\tsym = syms + sym_index;\n\t\t\tname = strings + sym->st_name;\n\t\t\tctx = type==REL_COPY ? head->syms_next : head;\n\t\t\tdef = (sym->st_info>>4) == STB_LOCAL\n\t\t\t\t? (struct symdef){ .dso = dso, .sym = sym }\n\t\t\t\t: find_sym(ctx, name, type==REL_PLT);\n\t\t\tif (!def.sym && (sym->st_shndx != SHN_UNDEF\n\t\t\t    || sym->st_info>>4 != STB_WEAK)) {\n\t\t\t\tif (dso->lazy && (type==REL_PLT || type==REL_GOT)) {\n\t\t\t\t\tdso->lazy[3*dso->lazy_cnt+0] = rel[0];\n\t\t\t\t\tdso->lazy[3*dso->lazy_cnt+1] = rel[1];\n\t\t\t\t\tdso->lazy[3*dso->lazy_cnt+2] = addend;\n\t\t\t\t\tdso->lazy_cnt++;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\terror(\"Error relocating %s: %s: symbol not found\",\n\t\t\t\t\tdso->name, name);\n\t\t\t\tif (runtime) longjmp(*rtld_fail, 1);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t} else {\n\t\t\tsym = 0;\n\t\t\tdef.sym = 0;\n\t\t\tdef.dso = dso;\n\t\t}\n\n\t\tsym_val = def.sym ? (size_t)laddr(def.dso, def.sym->st_value) : 0;\n\t\ttls_val = def.sym ? def.sym->st_value : 0;\n\n\t\tif ((type == REL_TPOFF || type == REL_TPOFF_NEG)\n\t\t    && def.dso->tls_id > static_tls_cnt) {\n\t\t\terror(\"Error relocating %s: %s: initial-exec TLS \"\n\t\t\t\t\"resolves to dynamic definition in %s\",\n\t\t\t\tdso->name, name, def.dso->name);\n\t\t\tlongjmp(*rtld_fail, 1);\n\t\t}\n\n\t\tswitch(type) {\n\t\tcase REL_OFFSET:\n\t\t\taddend -= (size_t)reloc_addr;\n\t\tcase REL_SYMBOLIC:\n\t\tcase REL_GOT:\n\t\tcase REL_PLT:\n\t\t\t*reloc_addr = sym_val + addend;\n\t\t\tbreak;\n\t\tcase REL_USYMBOLIC:\n\t\t\tmemcpy(reloc_addr, &(size_t){sym_val + addend}, sizeof(size_t));\n\t\t\tbreak;\n\t\tcase REL_RELATIVE:\n\t\t\t*reloc_addr = (size_t)base + addend;\n\t\t\tbreak;\n\t\tcase REL_SYM_OR_REL:\n\t\t\tif (sym) *reloc_addr = sym_val + addend;\n\t\t\telse *reloc_addr = (size_t)base + addend;\n\t\t\tbreak;\n\t\tcase REL_COPY:\n\t\t\tmemcpy(reloc_addr, (void *)sym_val, sym->st_size);\n\t\t\tbreak;\n\t\tcase REL_OFFSET32:\n\t\t\t*(uint32_t *)reloc_addr = sym_val + addend\n\t\t\t\t- (size_t)reloc_addr;\n\t\t\tbreak;\n\t\tcase REL_FUNCDESC:\n\t\t\t*reloc_addr = def.sym ? (size_t)(def.dso->funcdescs\n\t\t\t\t+ (def.sym - def.dso->syms)) : 0;\n\t\t\tbreak;\n\t\tcase REL_FUNCDESC_VAL:\n\t\t\tif ((sym->st_info&0xf) == STT_SECTION) *reloc_addr += sym_val;\n\t\t\telse *reloc_addr = sym_val;\n\t\t\treloc_addr[1] = def.sym ? (size_t)def.dso->got : 0;\n\t\t\tbreak;\n\t\tcase REL_DTPMOD:\n\t\t\t*reloc_addr = def.dso->tls_id;\n\t\t\tbreak;\n\t\tcase REL_DTPOFF:\n\t\t\t*reloc_addr = tls_val + addend - DTP_OFFSET;\n\t\t\tbreak;\n#ifdef TLS_ABOVE_TP\n\t\tcase REL_TPOFF:\n\t\t\t*reloc_addr = tls_val + def.dso->tls.offset + TPOFF_K + addend;\n\t\t\tbreak;\n#else\n\t\tcase REL_TPOFF:\n\t\t\t*reloc_addr = tls_val - def.dso->tls.offset + addend;\n\t\t\tbreak;\n\t\tcase REL_TPOFF_NEG:\n\t\t\t*reloc_addr = def.dso->tls.offset - tls_val + addend;\n\t\t\tbreak;\n#endif\n\t\tcase REL_TLSDESC:\n\t\t\tif (stride<3) addend = reloc_addr[1];\n\t\t\tif (def.dso->tls_id > static_tls_cnt) {\n\t\t\t\tstruct td_index *new = malloc(sizeof *new);\n\t\t\t\tif (!new) {\n\t\t\t\t\terror(\n\t\t\t\t\t\"Error relocating %s: cannot allocate TLSDESC for %s\",\n\t\t\t\t\tdso->name, sym ? name : \"(local)\" );\n\t\t\t\t\tlongjmp(*rtld_fail, 1);\n\t\t\t\t}\n\t\t\t\tnew->next = dso->td_index;\n\t\t\t\tdso->td_index = new;\n\t\t\t\tnew->args[0] = def.dso->tls_id;\n\t\t\t\tnew->args[1] = tls_val + addend - DTP_OFFSET;\n\t\t\t\treloc_addr[0] = (size_t)__tlsdesc_dynamic;\n\t\t\t\treloc_addr[1] = (size_t)new;\n\t\t\t} else {\n\t\t\t\treloc_addr[0] = (size_t)__tlsdesc_static;\n#ifdef TLS_ABOVE_TP\n\t\t\t\treloc_addr[1] = tls_val + def.dso->tls.offset\n\t\t\t\t\t+ TPOFF_K + addend;\n#else\n\t\t\t\treloc_addr[1] = tls_val - def.dso->tls.offset\n\t\t\t\t\t+ addend;\n#endif\n\t\t\t}\n#ifdef TLSDESC_BACKWARDS\n\t\t\t/* Some archs (32-bit ARM at least) invert the order of\n\t\t\t * the descriptor members. Fix them up here. */\n\t\t\tsize_t tmp = reloc_addr[0];\n\t\t\treloc_addr[0] = reloc_addr[1];\n\t\t\treloc_addr[1] = tmp;\n#endif\n\t\t\tbreak;\n\t\tdefault:\n\t\t\terror(\"Error relocating %s: unsupported relocation type %d\",\n\t\t\t\tdso->name, type);\n\t\t\tif (runtime) longjmp(*rtld_fail, 1);\n\t\t\tcontinue;\n\t\t}\n\t}\n}\n\nstatic void redo_lazy_relocs()\n{\n\tstruct dso *p = lazy_head, *next;\n\tlazy_head = 0;\n\tfor (; p; p=next) {\n\t\tnext = p->lazy_next;\n\t\tsize_t size = p->lazy_cnt*3*sizeof(size_t);\n\t\tp->lazy_cnt = 0;\n\t\tdo_relocs(p, p->lazy, size, 3);\n\t\tif (p->lazy_cnt) {\n\t\t\tp->lazy_next = lazy_head;\n\t\t\tlazy_head = p;\n\t\t} else {\n\t\t\tfree(p->lazy);\n\t\t\tp->lazy = 0;\n\t\t\tp->lazy_next = 0;\n\t\t}\n\t}\n}\n\n/* A huge hack: to make up for the wastefulness of shared libraries\n * needing at least a page of dirty memory even if they have no global\n * data, we reclaim the gaps at the beginning and end of writable maps\n * and \"donate\" them to the heap. */\n\nstatic void reclaim(struct dso *dso, size_t start, size_t end)\n{\n\tif (start >= dso->relro_start && start < dso->relro_end) start = dso->relro_end;\n\tif (end   >= dso->relro_start && end   < dso->relro_end) end = dso->relro_start;\n\tif (start >= end) return;\n\tchar *base = laddr_pg(dso, start);\n\t__malloc_donate(base, base+(end-start));\n}\n\nstatic void reclaim_gaps(struct dso *dso)\n{\n\tPhdr *ph = dso->phdr;\n\tsize_t phcnt = dso->phnum;\n\n\tfor (; phcnt--; ph=(void *)((char *)ph+dso->phentsize)) {\n\t\tif (ph->p_type!=PT_LOAD) continue;\n\t\tif ((ph->p_flags&(PF_R|PF_W))!=(PF_R|PF_W)) continue;\n\t\treclaim(dso, ph->p_vaddr & -PAGE_SIZE, ph->p_vaddr);\n\t\treclaim(dso, ph->p_vaddr+ph->p_memsz,\n\t\t\tph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE);\n\t}\n}\n\nstatic ssize_t read_loop(int fd, void *p, size_t n)\n{\n\tfor (size_t i=0; i<n; ) {\n\t\tssize_t l = read(fd, (char *)p+i, n-i);\n\t\tif (l<0) {\n\t\t\tif (errno==EINTR) continue;\n\t\t\telse return -1;\n\t\t}\n\t\tif (l==0) return i;\n\t\ti += l;\n\t}\n\treturn n;\n}\n\nstatic void *mmap_fixed(void *p, size_t n, int prot, int flags, int fd, off_t off)\n{\n\tstatic int no_map_fixed;\n\tchar *q;\n\tif (!no_map_fixed) {\n\t\tq = mmap(p, n, prot, flags|MAP_FIXED, fd, off);\n\t\tif (!DL_NOMMU_SUPPORT || q != MAP_FAILED || errno != EINVAL)\n\t\t\treturn q;\n\t\tno_map_fixed = 1;\n\t}\n\t/* Fallbacks for MAP_FIXED failure on NOMMU kernels. */\n\tif (flags & MAP_ANONYMOUS) {\n\t\tmemset(p, 0, n);\n\t\treturn p;\n\t}\n\tssize_t r;\n\tif (lseek(fd, off, SEEK_SET) < 0) return MAP_FAILED;\n\tfor (q=p; n; q+=r, off+=r, n-=r) {\n\t\tr = read(fd, q, n);\n\t\tif (r < 0 && errno != EINTR) return MAP_FAILED;\n\t\tif (!r) {\n\t\t\tmemset(q, 0, n);\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn p;\n}\n\nstatic void unmap_library(struct dso *dso)\n{\n\tif (dso->loadmap) {\n\t\tsize_t i;\n\t\tfor (i=0; i<dso->loadmap->nsegs; i++) {\n\t\t\tif (!dso->loadmap->segs[i].p_memsz)\n\t\t\t\tcontinue;\n\t\t\tmunmap((void *)dso->loadmap->segs[i].addr,\n\t\t\t\tdso->loadmap->segs[i].p_memsz);\n\t\t}\n\t\tfree(dso->loadmap);\n\t} else if (dso->map && dso->map_len) {\n\t\tmunmap(dso->map, dso->map_len);\n\t}\n}\n\nstatic void *map_library(int fd, struct dso *dso)\n{\n\tEhdr buf[(896+sizeof(Ehdr))/sizeof(Ehdr)];\n\tvoid *allocated_buf=0;\n\tsize_t phsize;\n\tsize_t addr_min=SIZE_MAX, addr_max=0, map_len;\n\tsize_t this_min, this_max;\n\tsize_t nsegs = 0;\n\toff_t off_start;\n\tEhdr *eh;\n\tPhdr *ph, *ph0;\n\tunsigned prot;\n\tunsigned char *map=MAP_FAILED, *base;\n\tsize_t dyn=0;\n\tsize_t tls_image=0;\n\tsize_t i;\n\n\tssize_t l = read(fd, buf, sizeof buf);\n\teh = buf;\n\tif (l<0) return 0;\n\tif (l<sizeof *eh || (eh->e_type != ET_DYN && eh->e_type != ET_EXEC))\n\t\tgoto noexec;\n\tphsize = eh->e_phentsize * eh->e_phnum;\n\tif (phsize > sizeof buf - sizeof *eh) {\n\t\tallocated_buf = malloc(phsize);\n\t\tif (!allocated_buf) return 0;\n\t\tl = pread(fd, allocated_buf, phsize, eh->e_phoff);\n\t\tif (l < 0) goto error;\n\t\tif (l != phsize) goto noexec;\n\t\tph = ph0 = allocated_buf;\n\t} else if (eh->e_phoff + phsize > l) {\n\t\tl = pread(fd, buf+1, phsize, eh->e_phoff);\n\t\tif (l < 0) goto error;\n\t\tif (l != phsize) goto noexec;\n\t\tph = ph0 = (void *)(buf + 1);\n\t} else {\n\t\tph = ph0 = (void *)((char *)buf + eh->e_phoff);\n\t}\n\tfor (i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) {\n\t\tif (ph->p_type == PT_DYNAMIC) {\n\t\t\tdyn = ph->p_vaddr;\n\t\t} else if (ph->p_type == PT_TLS) {\n\t\t\ttls_image = ph->p_vaddr;\n\t\t\tdso->tls.align = ph->p_align;\n\t\t\tdso->tls.len = ph->p_filesz;\n\t\t\tdso->tls.size = ph->p_memsz;\n\t\t} else if (ph->p_type == PT_GNU_RELRO) {\n\t\t\tdso->relro_start = ph->p_vaddr & -PAGE_SIZE;\n\t\t\tdso->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE;\n\t\t} else if (ph->p_type == PT_GNU_STACK) {\n\t\t\tif (!runtime && ph->p_memsz > __default_stacksize) {\n\t\t\t\t__default_stacksize =\n\t\t\t\t\tph->p_memsz < DEFAULT_STACK_MAX ?\n\t\t\t\t\tph->p_memsz : DEFAULT_STACK_MAX;\n\t\t\t}\n\t\t}\n\t\tif (ph->p_type != PT_LOAD) continue;\n\t\tnsegs++;\n\t\tif (ph->p_vaddr < addr_min) {\n\t\t\taddr_min = ph->p_vaddr;\n\t\t\toff_start = ph->p_offset;\n\t\t\tprot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |\n\t\t\t\t((ph->p_flags&PF_W) ? PROT_WRITE: 0) |\n\t\t\t\t((ph->p_flags&PF_X) ? PROT_EXEC : 0));\n\t\t}\n\t\tif (ph->p_vaddr+ph->p_memsz > addr_max) {\n\t\t\taddr_max = ph->p_vaddr+ph->p_memsz;\n\t\t}\n\t}\n\tif (!dyn) goto noexec;\n\tif (DL_FDPIC && !(eh->e_flags & FDPIC_CONSTDISP_FLAG)) {\n\t\tdso->loadmap = calloc(1, sizeof *dso->loadmap\n\t\t\t+ nsegs * sizeof *dso->loadmap->segs);\n\t\tif (!dso->loadmap) goto error;\n\t\tdso->loadmap->nsegs = nsegs;\n\t\tfor (ph=ph0, i=0; i<nsegs; ph=(void *)((char *)ph+eh->e_phentsize)) {\n\t\t\tif (ph->p_type != PT_LOAD) continue;\n\t\t\tprot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |\n\t\t\t\t((ph->p_flags&PF_W) ? PROT_WRITE: 0) |\n\t\t\t\t((ph->p_flags&PF_X) ? PROT_EXEC : 0));\n\t\t\tmap = mmap(0, ph->p_memsz + (ph->p_vaddr & PAGE_SIZE-1),\n\t\t\t\tprot, MAP_PRIVATE,\n\t\t\t\tfd, ph->p_offset & -PAGE_SIZE);\n\t\t\tif (map == MAP_FAILED) {\n\t\t\t\tunmap_library(dso);\n\t\t\t\tgoto error;\n\t\t\t}\n\t\t\tdso->loadmap->segs[i].addr = (size_t)map +\n\t\t\t\t(ph->p_vaddr & PAGE_SIZE-1);\n\t\t\tdso->loadmap->segs[i].p_vaddr = ph->p_vaddr;\n\t\t\tdso->loadmap->segs[i].p_memsz = ph->p_memsz;\n\t\t\ti++;\n\t\t\tif (prot & PROT_WRITE) {\n\t\t\t\tsize_t brk = (ph->p_vaddr & PAGE_SIZE-1)\n\t\t\t\t\t+ ph->p_filesz;\n\t\t\t\tsize_t pgbrk = brk + PAGE_SIZE-1 & -PAGE_SIZE;\n\t\t\t\tsize_t pgend = brk + ph->p_memsz - ph->p_filesz\n\t\t\t\t\t+ PAGE_SIZE-1 & -PAGE_SIZE;\n\t\t\t\tif (pgend > pgbrk && mmap_fixed(map+pgbrk,\n\t\t\t\t\tpgend-pgbrk, prot,\n\t\t\t\t\tMAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS,\n\t\t\t\t\t-1, off_start) == MAP_FAILED)\n\t\t\t\t\tgoto error;\n\t\t\t\tmemset(map + brk, 0, pgbrk-brk);\n\t\t\t}\n\t\t}\n\t\tmap = (void *)dso->loadmap->segs[0].addr;\n\t\tmap_len = 0;\n\t\tgoto done_mapping;\n\t}\n\taddr_max += PAGE_SIZE-1;\n\taddr_max &= -PAGE_SIZE;\n\taddr_min &= -PAGE_SIZE;\n\toff_start &= -PAGE_SIZE;\n\tmap_len = addr_max - addr_min + off_start;\n\t/* The first time, we map too much, possibly even more than\n\t * the length of the file. This is okay because we will not\n\t * use the invalid part; we just need to reserve the right\n\t * amount of virtual address space to map over later. */\n\tmap = DL_NOMMU_SUPPORT\n\t\t? mmap((void *)addr_min, map_len, PROT_READ|PROT_WRITE|PROT_EXEC,\n\t\t\tMAP_PRIVATE|MAP_ANONYMOUS, -1, 0)\n\t\t: mmap((void *)addr_min, map_len, prot,\n\t\t\tMAP_PRIVATE, fd, off_start);\n\tif (map==MAP_FAILED) goto error;\n\tdso->map = map;\n\tdso->map_len = map_len;\n\t/* If the loaded file is not relocatable and the requested address is\n\t * not available, then the load operation must fail. */\n\tif (eh->e_type != ET_DYN && addr_min && map!=(void *)addr_min) {\n\t\terrno = EBUSY;\n\t\tgoto error;\n\t}\n\tbase = map - addr_min;\n\tdso->phdr = 0;\n\tdso->phnum = 0;\n\tfor (ph=ph0, i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) {\n\t\tif (ph->p_type != PT_LOAD) continue;\n\t\t/* Check if the programs headers are in this load segment, and\n\t\t * if so, record the address for use by dl_iterate_phdr. */\n\t\tif (!dso->phdr && eh->e_phoff >= ph->p_offset\n\t\t    && eh->e_phoff+phsize <= ph->p_offset+ph->p_filesz) {\n\t\t\tdso->phdr = (void *)(base + ph->p_vaddr\n\t\t\t\t+ (eh->e_phoff-ph->p_offset));\n\t\t\tdso->phnum = eh->e_phnum;\n\t\t\tdso->phentsize = eh->e_phentsize;\n\t\t}\n\t\tthis_min = ph->p_vaddr & -PAGE_SIZE;\n\t\tthis_max = ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE;\n\t\toff_start = ph->p_offset & -PAGE_SIZE;\n\t\tprot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |\n\t\t\t((ph->p_flags&PF_W) ? PROT_WRITE: 0) |\n\t\t\t((ph->p_flags&PF_X) ? PROT_EXEC : 0));\n\t\t/* Reuse the existing mapping for the lowest-address LOAD */\n\t\tif ((ph->p_vaddr & -PAGE_SIZE) != addr_min || DL_NOMMU_SUPPORT)\n\t\t\tif (mmap_fixed(base+this_min, this_max-this_min, prot, MAP_PRIVATE|MAP_FIXED, fd, off_start) == MAP_FAILED)\n\t\t\t\tgoto error;\n\t\tif (ph->p_memsz > ph->p_filesz && (ph->p_flags&PF_W)) {\n\t\t\tsize_t brk = (size_t)base+ph->p_vaddr+ph->p_filesz;\n\t\t\tsize_t pgbrk = brk+PAGE_SIZE-1 & -PAGE_SIZE;\n\t\t\tmemset((void *)brk, 0, pgbrk-brk & PAGE_SIZE-1);\n\t\t\tif (pgbrk-(size_t)base < this_max && mmap_fixed((void *)pgbrk, (size_t)base+this_max-pgbrk, prot, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) == MAP_FAILED)\n\t\t\t\tgoto error;\n\t\t}\n\t}\n\tfor (i=0; ((size_t *)(base+dyn))[i]; i+=2)\n\t\tif (((size_t *)(base+dyn))[i]==DT_TEXTREL) {\n\t\t\tif (mprotect(map, map_len, PROT_READ|PROT_WRITE|PROT_EXEC)\n\t\t\t    && errno != ENOSYS)\n\t\t\t\tgoto error;\n\t\t\tbreak;\n\t\t}\ndone_mapping:\n\tdso->base = base;\n\tdso->dynv = laddr(dso, dyn);\n\tif (dso->tls.size) dso->tls.image = laddr(dso, tls_image);\n\tfree(allocated_buf);\n\treturn map;\nnoexec:\n\terrno = ENOEXEC;\nerror:\n\tif (map!=MAP_FAILED) unmap_library(dso);\n\tfree(allocated_buf);\n\treturn 0;\n}\n\nstatic int path_open(const char *name, const char *s, char *buf, size_t buf_size)\n{\n\tsize_t l;\n\tint fd;\n\tfor (;;) {\n\t\ts += strspn(s, \":\\n\");\n\t\tl = strcspn(s, \":\\n\");\n\t\tif (l-1 >= INT_MAX) return -1;\n\t\tif (snprintf(buf, buf_size, \"%.*s/%s\", (int)l, s, name) < buf_size) {\n\t\t\tif ((fd = open(buf, O_RDONLY|O_CLOEXEC))>=0) return fd;\n\t\t\tswitch (errno) {\n\t\t\tcase ENOENT:\n\t\t\tcase ENOTDIR:\n\t\t\tcase EACCES:\n\t\t\tcase ENAMETOOLONG:\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t/* Any negative value but -1 will inhibit\n\t\t\t\t * futher path search. */\n\t\t\t\treturn -2;\n\t\t\t}\n\t\t}\n\t\ts += l;\n\t}\n}\n\nstatic int fixup_rpath(struct dso *p, char *buf, size_t buf_size)\n{\n\tsize_t n, l;\n\tconst char *s, *t, *origin;\n\tchar *d;\n\tif (p->rpath || !p->rpath_orig) return 0;\n\tif (!strchr(p->rpath_orig, '$')) {\n\t\tp->rpath = p->rpath_orig;\n\t\treturn 0;\n\t}\n\tn = 0;\n\ts = p->rpath_orig;\n\twhile ((t=strchr(s, '$'))) {\n\t\tif (strncmp(t, \"$ORIGIN\", 7) && strncmp(t, \"${ORIGIN}\", 9))\n\t\t\treturn 0;\n\t\ts = t+1;\n\t\tn++;\n\t}\n\tif (n > SSIZE_MAX/PATH_MAX) return 0;\n\n\tif (p->kernel_mapped) {\n\t\t/* $ORIGIN searches cannot be performed for the main program\n\t\t * when it is suid/sgid/AT_SECURE. This is because the\n\t\t * pathname is under the control of the caller of execve.\n\t\t * For libraries, however, $ORIGIN can be processed safely\n\t\t * since the library's pathname came from a trusted source\n\t\t * (either system paths or a call to dlopen). */\n\t\tif (libc.secure)\n\t\t\treturn 0;\n\t\tl = readlink(\"/proc/self/exe\", buf, buf_size);\n\t\tif (l == -1) switch (errno) {\n\t\tcase ENOENT:\n\t\tcase ENOTDIR:\n\t\tcase EACCES:\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn -1;\n\t\t}\n\t\tif (l >= buf_size)\n\t\t\treturn 0;\n\t\tbuf[l] = 0;\n\t\torigin = buf;\n\t} else {\n\t\torigin = p->name;\n\t}\n\tt = strrchr(origin, '/');\n\tif (t) {\n\t\tl = t-origin;\n\t} else {\n\t\t/* Normally p->name will always be an absolute or relative\n\t\t * pathname containing at least one '/' character, but in the\n\t\t * case where ldso was invoked as a command to execute a\n\t\t * program in the working directory, app.name may not. Fix. */\n\t\torigin = \".\";\n\t\tl = 1;\n\t}\n\t/* Disallow non-absolute origins for suid/sgid/AT_SECURE. */\n\tif (libc.secure && *origin != '/')\n\t\treturn 0;\n\tp->rpath = malloc(strlen(p->rpath_orig) + n*l + 1);\n\tif (!p->rpath) return -1;\n\n\td = p->rpath;\n\ts = p->rpath_orig;\n\twhile ((t=strchr(s, '$'))) {\n\t\tmemcpy(d, s, t-s);\n\t\td += t-s;\n\t\tmemcpy(d, origin, l);\n\t\td += l;\n\t\t/* It was determined previously that the '$' is followed\n\t\t * either by \"ORIGIN\" or \"{ORIGIN}\". */\n\t\ts = t + 7 + 2*(t[1]=='{');\n\t}\n\tstrcpy(d, s);\n\treturn 0;\n}\n\nstatic void decode_dyn(struct dso *p)\n{\n\tsize_t dyn[DYN_CNT];\n\tdecode_vec(p->dynv, dyn, DYN_CNT);\n\tp->syms = laddr(p, dyn[DT_SYMTAB]);\n\tp->strings = laddr(p, dyn[DT_STRTAB]);\n\tif (dyn[0]&(1<<DT_HASH))\n\t\tp->hashtab = laddr(p, dyn[DT_HASH]);\n\tif (dyn[0]&(1<<DT_RPATH))\n\t\tp->rpath_orig = p->strings + dyn[DT_RPATH];\n\tif (dyn[0]&(1<<DT_RUNPATH))\n\t\tp->rpath_orig = p->strings + dyn[DT_RUNPATH];\n\tif (dyn[0]&(1<<DT_PLTGOT))\n\t\tp->got = laddr(p, dyn[DT_PLTGOT]);\n\tif (search_vec(p->dynv, dyn, DT_GNU_HASH))\n\t\tp->ghashtab = laddr(p, *dyn);\n\tif (search_vec(p->dynv, dyn, DT_VERSYM))\n\t\tp->versym = laddr(p, *dyn);\n}\n\nstatic size_t count_syms(struct dso *p)\n{\n\tif (p->hashtab) return p->hashtab[1];\n\n\tsize_t nsym, i;\n\tuint32_t *buckets = p->ghashtab + 4 + (p->ghashtab[2]*sizeof(size_t)/4);\n\tuint32_t *hashval;\n\tfor (i = nsym = 0; i < p->ghashtab[0]; i++) {\n\t\tif (buckets[i] > nsym)\n\t\t\tnsym = buckets[i];\n\t}\n\tif (nsym) {\n\t\thashval = buckets + p->ghashtab[0] + (nsym - p->ghashtab[1]);\n\t\tdo nsym++;\n\t\twhile (!(*hashval++ & 1));\n\t}\n\treturn nsym;\n}\n\nstatic void *dl_mmap(size_t n)\n{\n\tvoid *p;\n\tint prot = PROT_READ|PROT_WRITE, flags = MAP_ANONYMOUS|MAP_PRIVATE;\n#ifdef SYS_mmap2\n\tp = (void *)__syscall(SYS_mmap2, 0, n, prot, flags, -1, 0);\n#else\n\tp = (void *)__syscall(SYS_mmap, 0, n, prot, flags, -1, 0);\n#endif\n\treturn (unsigned long)p > -4096UL ? 0 : p;\n}\n\nstatic void makefuncdescs(struct dso *p)\n{\n\tstatic int self_done;\n\tsize_t nsym = count_syms(p);\n\tsize_t i, size = nsym * sizeof(*p->funcdescs);\n\n\tif (!self_done) {\n\t\tp->funcdescs = dl_mmap(size);\n\t\tself_done = 1;\n\t} else {\n\t\tp->funcdescs = malloc(size);\n\t}\n\tif (!p->funcdescs) {\n\t\tif (!runtime) a_crash();\n\t\terror(\"Error allocating function descriptors for %s\", p->name);\n\t\tlongjmp(*rtld_fail, 1);\n\t}\n\tfor (i=0; i<nsym; i++) {\n\t\tif ((p->syms[i].st_info&0xf)==STT_FUNC && p->syms[i].st_shndx) {\n\t\t\tp->funcdescs[i].addr = laddr(p, p->syms[i].st_value);\n\t\t\tp->funcdescs[i].got = p->got;\n\t\t} else {\n\t\t\tp->funcdescs[i].addr = 0;\n\t\t\tp->funcdescs[i].got = 0;\n\t\t}\n\t}\n}\n\nstatic struct dso *load_library(const char *name, struct dso *needed_by)\n{\n\tchar buf[2*NAME_MAX+2];\n\tconst char *pathname;\n\tunsigned char *map;\n\tstruct dso *p, temp_dso = {0};\n\tint fd;\n\tstruct stat st;\n\tsize_t alloc_size;\n\tint n_th = 0;\n\tint is_self = 0;\n\n\tif (!*name) {\n\t\terrno = EINVAL;\n\t\treturn 0;\n\t}\n\n\t/* Catch and block attempts to reload the implementation itself */\n\tif (name[0]=='l' && name[1]=='i' && name[2]=='b') {\n\t\tstatic const char reserved[] =\n\t\t\t\"c.pthread.rt.m.dl.util.xnet.\";\n\t\tconst char *rp, *next;\n\t\tfor (rp=reserved; *rp; rp=next) {\n\t\t\tnext = strchr(rp, '.') + 1;\n\t\t\tif (strncmp(name+3, rp, next-rp) == 0)\n\t\t\t\tbreak;\n\t\t}\n\t\tif (*rp) {\n\t\t\tif (ldd_mode) {\n\t\t\t\t/* Track which names have been resolved\n\t\t\t\t * and only report each one once. */\n\t\t\t\tstatic unsigned reported;\n\t\t\t\tunsigned mask = 1U<<(rp-reserved);\n\t\t\t\tif (!(reported & mask)) {\n\t\t\t\t\treported |= mask;\n\t\t\t\t\tdprintf(1, \"\\t%s => %s (%p)\\n\",\n\t\t\t\t\t\tname, ldso.name,\n\t\t\t\t\t\tldso.base);\n\t\t\t\t}\n\t\t\t}\n\t\t\tis_self = 1;\n\t\t}\n\t}\n\tif (!strcmp(name, ldso.name)) is_self = 1;\n\tif (is_self) {\n\t\tif (!ldso.prev) {\n\t\t\ttail->next = &ldso;\n\t\t\tldso.prev = tail;\n\t\t\ttail = &ldso;\n\t\t}\n\t\treturn &ldso;\n\t}\n\tif (strchr(name, '/')) {\n\t\tpathname = name;\n\t\tfd = open(name, O_RDONLY|O_CLOEXEC);\n\t} else {\n\t\t/* Search for the name to see if it's already loaded */\n\t\tfor (p=head->next; p; p=p->next) {\n\t\t\tif (p->shortname && !strcmp(p->shortname, name)) {\n\t\t\t\treturn p;\n\t\t\t}\n\t\t}\n\t\tif (strlen(name) > NAME_MAX) return 0;\n\t\tfd = -1;\n\t\tif (env_path) fd = path_open(name, env_path, buf, sizeof buf);\n\t\tfor (p=needed_by; fd == -1 && p; p=p->needed_by) {\n\t\t\tif (fixup_rpath(p, buf, sizeof buf) < 0)\n\t\t\t\tfd = -2; /* Inhibit further search. */\n\t\t\tif (p->rpath)\n\t\t\t\tfd = path_open(name, p->rpath, buf, sizeof buf);\n\t\t}\n\t\tif (fd == -1) {\n\t\t\tif (!sys_path) {\n\t\t\t\tchar *prefix = 0;\n\t\t\t\tsize_t prefix_len;\n\t\t\t\tif (ldso.name[0]=='/') {\n\t\t\t\t\tchar *s, *t, *z;\n\t\t\t\t\tfor (s=t=z=ldso.name; *s; s++)\n\t\t\t\t\t\tif (*s=='/') z=t, t=s;\n\t\t\t\t\tprefix_len = z-ldso.name;\n\t\t\t\t\tif (prefix_len < PATH_MAX)\n\t\t\t\t\t\tprefix = ldso.name;\n\t\t\t\t}\n\t\t\t\tif (!prefix) {\n\t\t\t\t\tprefix = \"\";\n\t\t\t\t\tprefix_len = 0;\n\t\t\t\t}\n\t\t\t\tchar etc_ldso_path[prefix_len + 1\n\t\t\t\t\t+ sizeof \"/etc/ld-musl-\" LDSO_ARCH \".path\"];\n\t\t\t\tsnprintf(etc_ldso_path, sizeof etc_ldso_path,\n\t\t\t\t\t\"%.*s/etc/ld-musl-\" LDSO_ARCH \".path\",\n\t\t\t\t\t(int)prefix_len, prefix);\n\t\t\t\tfd = open(etc_ldso_path, O_RDONLY|O_CLOEXEC);\n\t\t\t\tif (fd>=0) {\n\t\t\t\t\tsize_t n = 0;\n\t\t\t\t\tif (!fstat(fd, &st)) n = st.st_size;\n\t\t\t\t\tif ((sys_path = malloc(n+1)))\n\t\t\t\t\t\tsys_path[n] = 0;\n\t\t\t\t\tif (!sys_path || read_loop(fd, sys_path, n)<0) {\n\t\t\t\t\t\tfree(sys_path);\n\t\t\t\t\t\tsys_path = \"\";\n\t\t\t\t\t}\n\t\t\t\t\tclose(fd);\n\t\t\t\t} else if (errno != ENOENT) {\n\t\t\t\t\tsys_path = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!sys_path) sys_path = \"/lib:/usr/local/lib:/usr/lib\";\n\t\t\tfd = path_open(name, sys_path, buf, sizeof buf);\n\t\t}\n\t\tpathname = buf;\n\t}\n\tif (fd < 0) return 0;\n\tif (fstat(fd, &st) < 0) {\n\t\tclose(fd);\n\t\treturn 0;\n\t}\n\tfor (p=head->next; p; p=p->next) {\n\t\tif (p->dev == st.st_dev && p->ino == st.st_ino) {\n\t\t\t/* If this library was previously loaded with a\n\t\t\t * pathname but a search found the same inode,\n\t\t\t * setup its shortname so it can be found by name. */\n\t\t\tif (!p->shortname && pathname != name)\n\t\t\t\tp->shortname = strrchr(p->name, '/')+1;\n\t\t\tclose(fd);\n\t\t\treturn p;\n\t\t}\n\t}\n\tmap = noload ? 0 : map_library(fd, &temp_dso);\n\tclose(fd);\n\tif (!map) return 0;\n\n\t/* Avoid the danger of getting two versions of libc mapped into the\n\t * same process when an absolute pathname was used. The symbols\n\t * checked are chosen to catch both musl and glibc, and to avoid\n\t * false positives from interposition-hack libraries. */\n\tdecode_dyn(&temp_dso);\n\tif (find_sym(&temp_dso, \"__libc_start_main\", 1).sym &&\n\t    find_sym(&temp_dso, \"stdin\", 1).sym) {\n\t\tunmap_library(&temp_dso);\n\t\treturn load_library(\"libc.so\", needed_by);\n\t}\n\t/* Past this point, if we haven't reached runtime yet, ldso has\n\t * committed either to use the mapped library or to abort execution.\n\t * Unmapping is not possible, so we can safely reclaim gaps. */\n\tif (!runtime) reclaim_gaps(&temp_dso);\n\n\t/* Allocate storage for the new DSO. When there is TLS, this\n\t * storage must include a reservation for all pre-existing\n\t * threads to obtain copies of both the new TLS, and an\n\t * extended DTV capable of storing an additional slot for\n\t * the newly-loaded DSO. */\n\talloc_size = sizeof *p + strlen(pathname) + 1;\n\tif (runtime && temp_dso.tls.image) {\n\t\tsize_t per_th = temp_dso.tls.size + temp_dso.tls.align\n\t\t\t+ sizeof(void *) * (tls_cnt+3);\n\t\tn_th = libc.threads_minus_1 + 1;\n\t\tif (n_th > SSIZE_MAX / per_th) alloc_size = SIZE_MAX;\n\t\telse alloc_size += n_th * per_th;\n\t}\n\tp = calloc(1, alloc_size);\n\tif (!p) {\n\t\tunmap_library(&temp_dso);\n\t\treturn 0;\n\t}\n\tmemcpy(p, &temp_dso, sizeof temp_dso);\n\tp->dev = st.st_dev;\n\tp->ino = st.st_ino;\n\tp->needed_by = needed_by;\n\tp->name = p->buf;\n\tp->runtime_loaded = runtime;\n\tstrcpy(p->name, pathname);\n\t/* Add a shortname only if name arg was not an explicit pathname. */\n\tif (pathname != name) p->shortname = strrchr(p->name, '/')+1;\n\tif (p->tls.image) {\n\t\tp->tls_id = ++tls_cnt;\n\t\ttls_align = MAXP2(tls_align, p->tls.align);\n#ifdef TLS_ABOVE_TP\n\t\tp->tls.offset = tls_offset + ( (p->tls.align-1) &\n\t\t\t(-tls_offset + (uintptr_t)p->tls.image) );\n\t\ttls_offset = p->tls.offset + p->tls.size;\n#else\n\t\ttls_offset += p->tls.size + p->tls.align - 1;\n\t\ttls_offset -= (tls_offset + (uintptr_t)p->tls.image)\n\t\t\t& (p->tls.align-1);\n\t\tp->tls.offset = tls_offset;\n#endif\n\t\tp->new_dtv = (void *)(-sizeof(size_t) &\n\t\t\t(uintptr_t)(p->name+strlen(p->name)+sizeof(size_t)));\n\t\tp->new_tls = (void *)(p->new_dtv + n_th*(tls_cnt+1));\n\t\tif (tls_tail) tls_tail->next = &p->tls;\n\t\telse libc.tls_head = &p->tls;\n\t\ttls_tail = &p->tls;\n\t}\n\n\ttail->next = p;\n\tp->prev = tail;\n\ttail = p;\n\n\tif (DL_FDPIC) makefuncdescs(p);\n\n\tif (ldd_mode) dprintf(1, \"\\t%s => %s (%p)\\n\", name, pathname, p->base);\n\n\treturn p;\n}\n\nstatic void load_direct_deps(struct dso *p)\n{\n\tsize_t i, cnt=0;\n\n\tif (p->deps) return;\n\t/* For head, all preloads are direct pseudo-dependencies.\n\t * Count and include them now to avoid realloc later. */\n\tif (p==head) for (struct dso *q=p->next; q; q=q->next)\n\t\tcnt++;\n\tfor (i=0; p->dynv[i]; i+=2)\n\t\tif (p->dynv[i] == DT_NEEDED) cnt++;\n\t/* Use builtin buffer for apps with no external deps, to\n\t * preserve property of no runtime failure paths. */\n\tp->deps = (p==head && cnt<2) ? builtin_deps :\n\t\tcalloc(cnt+1, sizeof *p->deps);\n\tif (!p->deps) {\n\t\terror(\"Error loading dependencies for %s\", p->name);\n\t\tif (runtime) longjmp(*rtld_fail, 1);\n\t}\n\tcnt=0;\n\tif (p==head) for (struct dso *q=p->next; q; q=q->next)\n\t\tp->deps[cnt++] = q;\n\tfor (i=0; p->dynv[i]; i+=2) {\n\t\tif (p->dynv[i] != DT_NEEDED) continue;\n\t\tstruct dso *dep = load_library(p->strings + p->dynv[i+1], p);\n\t\tif (!dep) {\n\t\t\terror(\"Error loading shared library %s: %m (needed by %s)\",\n\t\t\t\tp->strings + p->dynv[i+1], p->name);\n\t\t\tif (runtime) longjmp(*rtld_fail, 1);\n\t\t\tcontinue;\n\t\t}\n\t\tp->deps[cnt++] = dep;\n\t}\n\tp->deps[cnt] = 0;\n\tp->ndeps_direct = cnt;\n}\n\nstatic void load_deps(struct dso *p)\n{\n\tif (p->deps) return;\n\tfor (; p; p=p->next)\n\t\tload_direct_deps(p);\n}\n\nstatic void extend_bfs_deps(struct dso *p)\n{\n\tsize_t i, j, cnt, ndeps_all;\n\tstruct dso **tmp;\n\n\t/* Can't use realloc if the original p->deps was allocated at\n\t * program entry and malloc has been replaced, or if it's\n\t * the builtin non-allocated trivial main program deps array. */\n\tint no_realloc = (__malloc_replaced && !p->runtime_loaded)\n\t\t|| p->deps == builtin_deps;\n\n\tif (p->bfs_built) return;\n\tndeps_all = p->ndeps_direct;\n\n\t/* Mark existing (direct) deps so they won't be duplicated. */\n\tfor (i=0; p->deps[i]; i++)\n\t\tp->deps[i]->mark = 1;\n\n\t/* For each dependency already in the list, copy its list of direct\n\t * dependencies to the list, excluding any items already in the\n\t * list. Note that the list this loop iterates over will grow during\n\t * the loop, but since duplicates are excluded, growth is bounded. */\n\tfor (i=0; p->deps[i]; i++) {\n\t\tstruct dso *dep = p->deps[i];\n\t\tfor (j=cnt=0; j<dep->ndeps_direct; j++)\n\t\t\tif (!dep->deps[j]->mark) cnt++;\n\t\ttmp = no_realloc ? \n\t\t\tmalloc(sizeof(*tmp) * (ndeps_all+cnt+1)) :\n\t\t\trealloc(p->deps, sizeof(*tmp) * (ndeps_all+cnt+1));\n\t\tif (!tmp) {\n\t\t\terror(\"Error recording dependencies for %s\", p->name);\n\t\t\tif (runtime) longjmp(*rtld_fail, 1);\n\t\t\tcontinue;\n\t\t}\n\t\tif (no_realloc) {\n\t\t\tmemcpy(tmp, p->deps, sizeof(*tmp) * (ndeps_all+1));\n\t\t\tno_realloc = 0;\n\t\t}\n\t\tp->deps = tmp;\n\t\tfor (j=0; j<dep->ndeps_direct; j++) {\n\t\t\tif (dep->deps[j]->mark) continue;\n\t\t\tdep->deps[j]->mark = 1;\n\t\t\tp->deps[ndeps_all++] = dep->deps[j];\n\t\t}\n\t\tp->deps[ndeps_all] = 0;\n\t}\n\tp->bfs_built = 1;\n\tfor (p=head; p; p=p->next)\n\t\tp->mark = 0;\n}\n\nstatic void load_preload(char *s)\n{\n\tint tmp;\n\tchar *z;\n\tfor (z=s; *z; s=z) {\n\t\tfor (   ; *s && (isspace(*s) || *s==':'); s++);\n\t\tfor (z=s; *z && !isspace(*z) && *z!=':'; z++);\n\t\ttmp = *z;\n\t\t*z = 0;\n\t\tload_library(s, 0);\n\t\t*z = tmp;\n\t}\n}\n\nstatic void add_syms(struct dso *p)\n{\n\tif (!p->syms_next && syms_tail != p) {\n\t\tsyms_tail->syms_next = p;\n\t\tsyms_tail = p;\n\t}\n}\n\nstatic void revert_syms(struct dso *old_tail)\n{\n\tstruct dso *p, *next;\n\t/* Chop off the tail of the list of dsos that participate in\n\t * the global symbol table, reverting them to RTLD_LOCAL. */\n\tfor (p=old_tail; p; p=next) {\n\t\tnext = p->syms_next;\n\t\tp->syms_next = 0;\n\t}\n\tsyms_tail = old_tail;\n}\n\nstatic void do_mips_relocs(struct dso *p, size_t *got)\n{\n\tsize_t i, j, rel[2];\n\tunsigned char *base = p->base;\n\ti=0; search_vec(p->dynv, &i, DT_MIPS_LOCAL_GOTNO);\n\tif (p==&ldso) {\n\t\tgot += i;\n\t} else {\n\t\twhile (i--) *got++ += (size_t)base;\n\t}\n\tj=0; search_vec(p->dynv, &j, DT_MIPS_GOTSYM);\n\ti=0; search_vec(p->dynv, &i, DT_MIPS_SYMTABNO);\n\tSym *sym = p->syms + j;\n\trel[0] = (unsigned char *)got - base;\n\tfor (i-=j; i; i--, sym++, rel[0]+=sizeof(size_t)) {\n\t\trel[1] = R_INFO(sym-p->syms, R_MIPS_JUMP_SLOT);\n\t\tdo_relocs(p, rel, sizeof rel, 2);\n\t}\n}\n\nstatic void reloc_all(struct dso *p)\n{\n\tsize_t dyn[DYN_CNT];\n\tfor (; p; p=p->next) {\n\t\tif (p->relocated) continue;\n\t\tdecode_vec(p->dynv, dyn, DYN_CNT);\n\t\tif (NEED_MIPS_GOT_RELOCS)\n\t\t\tdo_mips_relocs(p, laddr(p, dyn[DT_PLTGOT]));\n\t\tdo_relocs(p, laddr(p, dyn[DT_JMPREL]), dyn[DT_PLTRELSZ],\n\t\t\t2+(dyn[DT_PLTREL]==DT_RELA));\n\t\tdo_relocs(p, laddr(p, dyn[DT_REL]), dyn[DT_RELSZ], 2);\n\t\tdo_relocs(p, laddr(p, dyn[DT_RELA]), dyn[DT_RELASZ], 3);\n\n\t\tif (head != &ldso && p->relro_start != p->relro_end &&\n\t\t    mprotect(laddr(p, p->relro_start), p->relro_end-p->relro_start, PROT_READ)\n\t\t    && errno != ENOSYS) {\n\t\t\terror(\"Error relocating %s: RELRO protection failed: %m\",\n\t\t\t\tp->name);\n\t\t\tif (runtime) longjmp(*rtld_fail, 1);\n\t\t}\n\n\t\tp->relocated = 1;\n\t}\n}\n\nstatic void kernel_mapped_dso(struct dso *p)\n{\n\tsize_t min_addr = -1, max_addr = 0, cnt;\n\tPhdr *ph = p->phdr;\n\tfor (cnt = p->phnum; cnt--; ph = (void *)((char *)ph + p->phentsize)) {\n\t\tif (ph->p_type == PT_DYNAMIC) {\n\t\t\tp->dynv = laddr(p, ph->p_vaddr);\n\t\t} else if (ph->p_type == PT_GNU_RELRO) {\n\t\t\tp->relro_start = ph->p_vaddr & -PAGE_SIZE;\n\t\t\tp->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE;\n\t\t} else if (ph->p_type == PT_GNU_STACK) {\n\t\t\tif (!runtime && ph->p_memsz > __default_stacksize) {\n\t\t\t\t__default_stacksize =\n\t\t\t\t\tph->p_memsz < DEFAULT_STACK_MAX ?\n\t\t\t\t\tph->p_memsz : DEFAULT_STACK_MAX;\n\t\t\t}\n\t\t}\n\t\tif (ph->p_type != PT_LOAD) continue;\n\t\tif (ph->p_vaddr < min_addr)\n\t\t\tmin_addr = ph->p_vaddr;\n\t\tif (ph->p_vaddr+ph->p_memsz > max_addr)\n\t\t\tmax_addr = ph->p_vaddr+ph->p_memsz;\n\t}\n\tmin_addr &= -PAGE_SIZE;\n\tmax_addr = (max_addr + PAGE_SIZE-1) & -PAGE_SIZE;\n\tp->map = p->base + min_addr;\n\tp->map_len = max_addr - min_addr;\n\tp->kernel_mapped = 1;\n}\n\nvoid __libc_exit_fini()\n{\n\tstruct dso *p;\n\tsize_t dyn[DYN_CNT];\n\tpthread_t self = __pthread_self();\n\n\t/* Take both locks before setting shutting_down, so that\n\t * either lock is sufficient to read its value. The lock\n\t * order matches that in dlopen to avoid deadlock. */\n\tpthread_rwlock_wrlock(&lock);\n\tpthread_mutex_lock(&init_fini_lock);\n\tshutting_down = 1;\n\tpthread_rwlock_unlock(&lock);\n\tfor (p=fini_head; p; p=p->fini_next) {\n\t\twhile (p->ctor_visitor && p->ctor_visitor!=self)\n\t\t\tpthread_cond_wait(&ctor_cond, &init_fini_lock);\n\t\tif (!p->constructed) continue;\n\t\tdecode_vec(p->dynv, dyn, DYN_CNT);\n\t\tif (dyn[0] & (1<<DT_FINI_ARRAY)) {\n\t\t\tsize_t n = dyn[DT_FINI_ARRAYSZ]/sizeof(size_t);\n\t\t\tsize_t *fn = (size_t *)laddr(p, dyn[DT_FINI_ARRAY])+n;\n\t\t\twhile (n--) ((void (*)(void))*--fn)();\n\t\t}\n#ifndef NO_LEGACY_INITFINI\n\t\tif ((dyn[0] & (1<<DT_FINI)) && dyn[DT_FINI])\n\t\t\tfpaddr(p, dyn[DT_FINI])();\n#endif\n\t}\n}\n\nvoid __ldso_atfork(int who)\n{\n\tif (who<0) {\n\t\tpthread_rwlock_wrlock(&lock);\n\t\tpthread_mutex_lock(&init_fini_lock);\n\t} else {\n\t\tpthread_mutex_unlock(&init_fini_lock);\n\t\tpthread_rwlock_unlock(&lock);\n\t}\n}\n\nstatic struct dso **queue_ctors(struct dso *dso)\n{\n\tsize_t cnt, qpos, spos, i;\n\tstruct dso *p, **queue, **stack;\n\n\tif (ldd_mode) return 0;\n\n\t/* Bound on queue size is the total number of indirect deps.\n\t * If a bfs deps list was built, we can use it. Otherwise,\n\t * bound by the total number of DSOs, which is always safe and\n\t * is reasonable we use it (for main app at startup). */\n\tif (dso->bfs_built) {\n\t\tfor (cnt=0; dso->deps[cnt]; cnt++)\n\t\t\tdso->deps[cnt]->mark = 0;\n\t\tcnt++; /* self, not included in deps */\n\t} else {\n\t\tfor (cnt=0, p=head; p; cnt++, p=p->next)\n\t\t\tp->mark = 0;\n\t}\n\tcnt++; /* termination slot */\n\tif (dso==head && cnt <= countof(builtin_ctor_queue))\n\t\tqueue = builtin_ctor_queue;\n\telse\n\t\tqueue = calloc(cnt, sizeof *queue);\n\n\tif (!queue) {\n\t\terror(\"Error allocating constructor queue: %m\\n\");\n\t\tif (runtime) longjmp(*rtld_fail, 1);\n\t\treturn 0;\n\t}\n\n\t/* Opposite ends of the allocated buffer serve as an output queue\n\t * and a working stack. Setup initial stack with just the argument\n\t * dso and initial queue empty... */\n\tstack = queue;\n\tqpos = 0;\n\tspos = cnt;\n\tstack[--spos] = dso;\n\tdso->next_dep = 0;\n\tdso->mark = 1;\n\n\t/* Then perform pseudo-DFS sort, but ignoring circular deps. */\n\twhile (spos<cnt) {\n\t\tp = stack[spos++];\n\t\twhile (p->next_dep < p->ndeps_direct) {\n\t\t\tif (p->deps[p->next_dep]->mark) {\n\t\t\t\tp->next_dep++;\n\t\t\t} else {\n\t\t\t\tstack[--spos] = p;\n\t\t\t\tp = p->deps[p->next_dep];\n\t\t\t\tp->next_dep = 0;\n\t\t\t\tp->mark = 1;\n\t\t\t}\n\t\t}\n\t\tqueue[qpos++] = p;\n\t}\n\tqueue[qpos] = 0;\n\tfor (i=0; i<qpos; i++) queue[i]->mark = 0;\n\tfor (i=0; i<qpos; i++)\n\t\tif (queue[i]->ctor_visitor && queue[i]->ctor_visitor->tid < 0) {\n\t\t\terror(\"State of %s is inconsistent due to multithreaded fork\\n\",\n\t\t\t\tqueue[i]->name);\n\t\t\tfree(queue);\n\t\t\tif (runtime) longjmp(*rtld_fail, 1);\n\t\t}\n\n\treturn queue;\n}\n\nstatic void do_init_fini(struct dso **queue)\n{\n\tstruct dso *p;\n\tsize_t dyn[DYN_CNT], i;\n\tpthread_t self = __pthread_self();\n\n\tpthread_mutex_lock(&init_fini_lock);\n\tfor (i=0; (p=queue[i]); i++) {\n\t\twhile ((p->ctor_visitor && p->ctor_visitor!=self) || shutting_down)\n\t\t\tpthread_cond_wait(&ctor_cond, &init_fini_lock);\n\t\tif (p->ctor_visitor || p->constructed)\n\t\t\tcontinue;\n\t\tp->ctor_visitor = self;\n\t\t\n\t\tdecode_vec(p->dynv, dyn, DYN_CNT);\n\t\tif (dyn[0] & ((1<<DT_FINI) | (1<<DT_FINI_ARRAY))) {\n\t\t\tp->fini_next = fini_head;\n\t\t\tfini_head = p;\n\t\t}\n\n\t\tpthread_mutex_unlock(&init_fini_lock);\n\n#ifndef NO_LEGACY_INITFINI\n\t\tif ((dyn[0] & (1<<DT_INIT)) && dyn[DT_INIT])\n\t\t\tfpaddr(p, dyn[DT_INIT])();\n#endif\n\t\tif (dyn[0] & (1<<DT_INIT_ARRAY)) {\n\t\t\tsize_t n = dyn[DT_INIT_ARRAYSZ]/sizeof(size_t);\n\t\t\tsize_t *fn = laddr(p, dyn[DT_INIT_ARRAY]);\n\t\t\twhile (n--) ((void (*)(void))*fn++)();\n\t\t}\n\n\t\tpthread_mutex_lock(&init_fini_lock);\n\t\tp->ctor_visitor = 0;\n\t\tp->constructed = 1;\n\t\tpthread_cond_broadcast(&ctor_cond);\n\t}\n\tpthread_mutex_unlock(&init_fini_lock);\n}\n\nvoid __libc_start_init(void)\n{\n\tdo_init_fini(main_ctor_queue);\n\tif (!__malloc_replaced && main_ctor_queue != builtin_ctor_queue)\n\t\tfree(main_ctor_queue);\n\tmain_ctor_queue = 0;\n}\n\nstatic void dl_debug_state(void)\n{\n}\n\nweak_alias(dl_debug_state, _dl_debug_state);\n\nvoid __init_tls(size_t *auxv)\n{\n}\n\nstatic void update_tls_size()\n{\n\tlibc.tls_cnt = tls_cnt;\n\tlibc.tls_align = tls_align;\n\tlibc.tls_size = ALIGN(\n\t\t(1+tls_cnt) * sizeof(void *) +\n\t\ttls_offset +\n\t\tsizeof(struct pthread) +\n\t\ttls_align * 2,\n\ttls_align);\n}\n\nstatic void install_new_tls(void)\n{\n\tsigset_t set;\n\tpthread_t self = __pthread_self(), td;\n\tstruct dso *dtv_provider = container_of(tls_tail, struct dso, tls);\n\tuintptr_t (*newdtv)[tls_cnt+1] = (void *)dtv_provider->new_dtv;\n\tstruct dso *p;\n\tsize_t i, j;\n\tsize_t old_cnt = self->dtv[0];\n\n\t__block_app_sigs(&set);\n\t__tl_lock();\n\t/* Copy existing dtv contents from all existing threads. */\n\tfor (i=0, td=self; !i || td!=self; i++, td=td->next) {\n\t\tmemcpy(newdtv+i, td->dtv,\n\t\t\t(old_cnt+1)*sizeof(uintptr_t));\n\t\tnewdtv[i][0] = tls_cnt;\n\t}\n\t/* Install new dtls into the enlarged, uninstalled dtv copies. */\n\tfor (p=head; ; p=p->next) {\n\t\tif (p->tls_id <= old_cnt) continue;\n\t\tunsigned char *mem = p->new_tls;\n\t\tfor (j=0; j<i; j++) {\n\t\t\tunsigned char *new = mem;\n\t\t\tnew += ((uintptr_t)p->tls.image - (uintptr_t)mem)\n\t\t\t\t& (p->tls.align-1);\n\t\t\tmemcpy(new, p->tls.image, p->tls.len);\n\t\t\tnewdtv[j][p->tls_id] =\n\t\t\t\t(uintptr_t)new + DTP_OFFSET;\n\t\t\tmem += p->tls.size + p->tls.align;\n\t\t}\n\t\tif (p->tls_id == tls_cnt) break;\n\t}\n\n\t/* Broadcast barrier to ensure contents of new dtv is visible\n\t * if the new dtv pointer is. The __membarrier function has a\n\t * fallback emulation using signals for kernels that lack the\n\t * feature at the syscall level. */\n\n\t__membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED, 0);\n\n\t/* Install new dtv for each thread. */\n\tfor (j=0, td=self; !j || td!=self; j++, td=td->next) {\n\t\ttd->dtv = newdtv[j];\n\t}\n\n\t__tl_unlock();\n\t__restore_sigs(&set);\n}\n\n/* Stage 1 of the dynamic linker is defined in dlstart.c. It calls the\n * following stage 2 and stage 3 functions via primitive symbolic lookup\n * since it does not have access to their addresses to begin with. */\n\n/* Stage 2 of the dynamic linker is called after relative relocations \n * have been processed. It can make function calls to static functions\n * and access string literals and static data, but cannot use extern\n * symbols. Its job is to perform symbolic relocations on the dynamic\n * linker itself, but some of the relocations performed may need to be\n * replaced later due to copy relocations in the main program. */\n\nhidden void __dls2(unsigned char *base, size_t *sp)\n{\n\tsize_t *auxv;\n\tfor (auxv=sp+1+*sp+1; *auxv; auxv++);\n\tauxv++;\n\tif (DL_FDPIC) {\n\t\tvoid *p1 = (void *)sp[-2];\n\t\tvoid *p2 = (void *)sp[-1];\n\t\tif (!p1) {\n\t\t\tsize_t aux[AUX_CNT];\n\t\t\tdecode_vec(auxv, aux, AUX_CNT);\n\t\t\tif (aux[AT_BASE]) ldso.base = (void *)aux[AT_BASE];\n\t\t\telse ldso.base = (void *)(aux[AT_PHDR] & -4096);\n\t\t}\n\t\tapp_loadmap = p2 ? p1 : 0;\n\t\tldso.loadmap = p2 ? p2 : p1;\n\t\tldso.base = laddr(&ldso, 0);\n\t} else {\n\t\tldso.base = base;\n\t}\n\tEhdr *ehdr = (void *)ldso.base;\n\tldso.name = ldso.shortname = \"libc.so\";\n\tldso.phnum = ehdr->e_phnum;\n\tldso.phdr = laddr(&ldso, ehdr->e_phoff);\n\tldso.phentsize = ehdr->e_phentsize;\n\tkernel_mapped_dso(&ldso);\n\tdecode_dyn(&ldso);\n\n\tif (DL_FDPIC) makefuncdescs(&ldso);\n\n\t/* Prepare storage for to save clobbered REL addends so they\n\t * can be reused in stage 3. There should be very few. If\n\t * something goes wrong and there are a huge number, abort\n\t * instead of risking stack overflow. */\n\tsize_t dyn[DYN_CNT];\n\tdecode_vec(ldso.dynv, dyn, DYN_CNT);\n\tsize_t *rel = laddr(&ldso, dyn[DT_REL]);\n\tsize_t rel_size = dyn[DT_RELSZ];\n\tsize_t symbolic_rel_cnt = 0;\n\tapply_addends_to = rel;\n\tfor (; rel_size; rel+=2, rel_size-=2*sizeof(size_t))\n\t\tif (!IS_RELATIVE(rel[1], ldso.syms)) symbolic_rel_cnt++;\n\tif (symbolic_rel_cnt >= ADDEND_LIMIT) a_crash();\n\tsize_t addends[symbolic_rel_cnt+1];\n\tsaved_addends = addends;\n\n\thead = &ldso;\n\treloc_all(&ldso);\n\n\tldso.relocated = 0;\n\n\t/* Call dynamic linker stage-2b, __dls2b, looking it up\n\t * symbolically as a barrier against moving the address\n\t * load across the above relocation processing. */\n\tstruct symdef dls2b_def = find_sym(&ldso, \"__dls2b\", 0);\n\tif (DL_FDPIC) ((stage3_func)&ldso.funcdescs[dls2b_def.sym-ldso.syms])(sp, auxv);\n\telse ((stage3_func)laddr(&ldso, dls2b_def.sym->st_value))(sp, auxv);\n}\n\n/* Stage 2b sets up a valid thread pointer, which requires relocations\n * completed in stage 2, and on which stage 3 is permitted to depend.\n * This is done as a separate stage, with symbolic lookup as a barrier,\n * so that loads of the thread pointer and &errno can be pure/const and\n * thereby hoistable. */\n\nvoid __dls2b(size_t *sp, size_t *auxv)\n{\n\t/* Setup early thread pointer in builtin_tls for ldso/libc itself to\n\t * use during dynamic linking. If possible it will also serve as the\n\t * thread pointer at runtime. */\n\tsearch_vec(auxv, &__hwcap, AT_HWCAP);\n\tlibc.auxv = auxv;\n\tlibc.tls_size = sizeof builtin_tls;\n\tlibc.tls_align = tls_align;\n\tif (__init_tp(__copy_tls((void *)builtin_tls)) < 0) {\n\t\ta_crash();\n\t}\n\n\tstruct symdef dls3_def = find_sym(&ldso, \"__dls3\", 0);\n\tif (DL_FDPIC) ((stage3_func)&ldso.funcdescs[dls3_def.sym-ldso.syms])(sp, auxv);\n\telse ((stage3_func)laddr(&ldso, dls3_def.sym->st_value))(sp, auxv);\n}\n\n/* Stage 3 of the dynamic linker is called with the dynamic linker/libc\n * fully functional. Its job is to load (if not already loaded) and\n * process dependencies and relocations for the main application and\n * transfer control to its entry point. */\n\nvoid __dls3(size_t *sp, size_t *auxv)\n{\n\tstatic struct dso app, vdso;\n\tsize_t aux[AUX_CNT];\n\tsize_t i;\n\tchar *env_preload=0;\n\tchar *replace_argv0=0;\n\tsize_t vdso_base;\n\tint argc = *sp;\n\tchar **argv = (void *)(sp+1);\n\tchar **argv_orig = argv;\n\tchar **envp = argv+argc+1;\n\n\t/* Find aux vector just past environ[] and use it to initialize\n\t * global data that may be needed before we can make syscalls. */\n\t__environ = envp;\n\tdecode_vec(auxv, aux, AUX_CNT);\n\tsearch_vec(auxv, &__sysinfo, AT_SYSINFO);\n\t__pthread_self()->sysinfo = __sysinfo;\n\tlibc.page_size = aux[AT_PAGESZ];\n\tlibc.secure = ((aux[0]&0x7800)!=0x7800 || aux[AT_UID]!=aux[AT_EUID]\n\t\t|| aux[AT_GID]!=aux[AT_EGID] || aux[AT_SECURE]);\n\n\t/* Only trust user/env if kernel says we're not suid/sgid */\n\tif (!libc.secure) {\n\t\tenv_path = getenv(\"LD_LIBRARY_PATH\");\n\t\tenv_preload = getenv(\"LD_PRELOAD\");\n\t}\n\n\t/* If the main program was already loaded by the kernel,\n\t * AT_PHDR will point to some location other than the dynamic\n\t * linker's program headers. */\n\tif (aux[AT_PHDR] != (size_t)ldso.phdr) {\n\t\tsize_t interp_off = 0;\n\t\tsize_t tls_image = 0;\n\t\t/* Find load address of the main program, via AT_PHDR vs PT_PHDR. */\n\t\tPhdr *phdr = app.phdr = (void *)aux[AT_PHDR];\n\t\tapp.phnum = aux[AT_PHNUM];\n\t\tapp.phentsize = aux[AT_PHENT];\n\t\tfor (i=aux[AT_PHNUM]; i; i--, phdr=(void *)((char *)phdr + aux[AT_PHENT])) {\n\t\t\tif (phdr->p_type == PT_PHDR)\n\t\t\t\tapp.base = (void *)(aux[AT_PHDR] - phdr->p_vaddr);\n\t\t\telse if (phdr->p_type == PT_INTERP)\n\t\t\t\tinterp_off = (size_t)phdr->p_vaddr;\n\t\t\telse if (phdr->p_type == PT_TLS) {\n\t\t\t\ttls_image = phdr->p_vaddr;\n\t\t\t\tapp.tls.len = phdr->p_filesz;\n\t\t\t\tapp.tls.size = phdr->p_memsz;\n\t\t\t\tapp.tls.align = phdr->p_align;\n\t\t\t}\n\t\t}\n\t\tif (DL_FDPIC) app.loadmap = app_loadmap;\n\t\tif (app.tls.size) app.tls.image = laddr(&app, tls_image);\n\t\tif (interp_off) ldso.name = laddr(&app, interp_off);\n\t\tif ((aux[0] & (1UL<<AT_EXECFN))\n\t\t    && strncmp((char *)aux[AT_EXECFN], \"/proc/\", 6))\n\t\t\tapp.name = (char *)aux[AT_EXECFN];\n\t\telse\n\t\t\tapp.name = argv[0];\n\t\tkernel_mapped_dso(&app);\n\t} else {\n\t\tint fd;\n\t\tchar *ldname = argv[0];\n\t\tsize_t l = strlen(ldname);\n\t\tif (l >= 3 && !strcmp(ldname+l-3, \"ldd\")) ldd_mode = 1;\n\t\targv++;\n\t\twhile (argv[0] && argv[0][0]=='-' && argv[0][1]=='-') {\n\t\t\tchar *opt = argv[0]+2;\n\t\t\t*argv++ = (void *)-1;\n\t\t\tif (!*opt) {\n\t\t\t\tbreak;\n\t\t\t} else if (!memcmp(opt, \"list\", 5)) {\n\t\t\t\tldd_mode = 1;\n\t\t\t} else if (!memcmp(opt, \"library-path\", 12)) {\n\t\t\t\tif (opt[12]=='=') env_path = opt+13;\n\t\t\t\telse if (opt[12]) *argv = 0;\n\t\t\t\telse if (*argv) env_path = *argv++;\n\t\t\t} else if (!memcmp(opt, \"preload\", 7)) {\n\t\t\t\tif (opt[7]=='=') env_preload = opt+8;\n\t\t\t\telse if (opt[7]) *argv = 0;\n\t\t\t\telse if (*argv) env_preload = *argv++;\n\t\t\t} else if (!memcmp(opt, \"argv0\", 5)) {\n\t\t\t\tif (opt[5]=='=') replace_argv0 = opt+6;\n\t\t\t\telse if (opt[5]) *argv = 0;\n\t\t\t\telse if (*argv) replace_argv0 = *argv++;\n\t\t\t} else {\n\t\t\t\targv[0] = 0;\n\t\t\t}\n\t\t}\n\t\targv[-1] = (void *)(argc - (argv-argv_orig));\n\t\tif (!argv[0]) {\n\t\t\tdprintf(2, \"musl libc (\" LDSO_ARCH \")\\n\"\n\t\t\t\t\"Version %s\\n\"\n\t\t\t\t\"Dynamic Program Loader\\n\"\n\t\t\t\t\"Usage: %s [options] [--] pathname%s\\n\",\n\t\t\t\t__libc_version, ldname,\n\t\t\t\tldd_mode ? \"\" : \" [args]\");\n\t\t\t_exit(1);\n\t\t}\n\t\tfd = open(argv[0], O_RDONLY);\n\t\tif (fd < 0) {\n\t\t\tdprintf(2, \"%s: cannot load %s: %s\\n\", ldname, argv[0], strerror(errno));\n\t\t\t_exit(1);\n\t\t}\n\t\tEhdr *ehdr = (void *)map_library(fd, &app);\n\t\tif (!ehdr) {\n\t\t\tdprintf(2, \"%s: %s: Not a valid dynamic program\\n\", ldname, argv[0]);\n\t\t\t_exit(1);\n\t\t}\n\t\tclose(fd);\n\t\tldso.name = ldname;\n\t\tapp.name = argv[0];\n\t\taux[AT_ENTRY] = (size_t)laddr(&app, ehdr->e_entry);\n\t\t/* Find the name that would have been used for the dynamic\n\t\t * linker had ldd not taken its place. */\n\t\tif (ldd_mode) {\n\t\t\tfor (i=0; i<app.phnum; i++) {\n\t\t\t\tif (app.phdr[i].p_type == PT_INTERP)\n\t\t\t\t\tldso.name = laddr(&app, app.phdr[i].p_vaddr);\n\t\t\t}\n\t\t\tdprintf(1, \"\\t%s (%p)\\n\", ldso.name, ldso.base);\n\t\t}\n\t}\n\tif (app.tls.size) {\n\t\tlibc.tls_head = tls_tail = &app.tls;\n\t\tapp.tls_id = tls_cnt = 1;\n#ifdef TLS_ABOVE_TP\n\t\tapp.tls.offset = GAP_ABOVE_TP;\n\t\tapp.tls.offset += (-GAP_ABOVE_TP + (uintptr_t)app.tls.image)\n\t\t\t& (app.tls.align-1);\n\t\ttls_offset = app.tls.offset + app.tls.size;\n#else\n\t\ttls_offset = app.tls.offset = app.tls.size\n\t\t\t+ ( -((uintptr_t)app.tls.image + app.tls.size)\n\t\t\t& (app.tls.align-1) );\n#endif\n\t\ttls_align = MAXP2(tls_align, app.tls.align);\n\t}\n\tdecode_dyn(&app);\n\tif (DL_FDPIC) {\n\t\tmakefuncdescs(&app);\n\t\tif (!app.loadmap) {\n\t\t\tapp.loadmap = (void *)&app_dummy_loadmap;\n\t\t\tapp.loadmap->nsegs = 1;\n\t\t\tapp.loadmap->segs[0].addr = (size_t)app.map;\n\t\t\tapp.loadmap->segs[0].p_vaddr = (size_t)app.map\n\t\t\t\t- (size_t)app.base;\n\t\t\tapp.loadmap->segs[0].p_memsz = app.map_len;\n\t\t}\n\t\targv[-3] = (void *)app.loadmap;\n\t}\n\n\t/* Initial dso chain consists only of the app. */\n\thead = tail = syms_tail = &app;\n\n\t/* Donate unused parts of app and library mapping to malloc */\n\treclaim_gaps(&app);\n\treclaim_gaps(&ldso);\n\n\t/* Load preload/needed libraries, add symbols to global namespace. */\n\tldso.deps = (struct dso **)no_deps;\n\tif (env_preload) load_preload(env_preload);\n \tload_deps(&app);\n\tfor (struct dso *p=head; p; p=p->next)\n\t\tadd_syms(p);\n\n\t/* Attach to vdso, if provided by the kernel, last so that it does\n\t * not become part of the global namespace.  */\n\tif (search_vec(auxv, &vdso_base, AT_SYSINFO_EHDR) && vdso_base) {\n\t\tEhdr *ehdr = (void *)vdso_base;\n\t\tPhdr *phdr = vdso.phdr = (void *)(vdso_base + ehdr->e_phoff);\n\t\tvdso.phnum = ehdr->e_phnum;\n\t\tvdso.phentsize = ehdr->e_phentsize;\n\t\tfor (i=ehdr->e_phnum; i; i--, phdr=(void *)((char *)phdr + ehdr->e_phentsize)) {\n\t\t\tif (phdr->p_type == PT_DYNAMIC)\n\t\t\t\tvdso.dynv = (void *)(vdso_base + phdr->p_offset);\n\t\t\tif (phdr->p_type == PT_LOAD)\n\t\t\t\tvdso.base = (void *)(vdso_base - phdr->p_vaddr + phdr->p_offset);\n\t\t}\n\t\tvdso.name = \"\";\n\t\tvdso.shortname = \"linux-gate.so.1\";\n\t\tvdso.relocated = 1;\n\t\tvdso.deps = (struct dso **)no_deps;\n\t\tdecode_dyn(&vdso);\n\t\tvdso.prev = tail;\n\t\ttail->next = &vdso;\n\t\ttail = &vdso;\n\t}\n\n\tfor (i=0; app.dynv[i]; i+=2) {\n\t\tif (!DT_DEBUG_INDIRECT && app.dynv[i]==DT_DEBUG)\n\t\t\tapp.dynv[i+1] = (size_t)&debug;\n\t\tif (DT_DEBUG_INDIRECT && app.dynv[i]==DT_DEBUG_INDIRECT) {\n\t\t\tsize_t *ptr = (size_t *) app.dynv[i+1];\n\t\t\t*ptr = (size_t)&debug;\n\t\t}\n\t}\n\n\t/* This must be done before final relocations, since it calls\n\t * malloc, which may be provided by the application. Calling any\n\t * application code prior to the jump to its entry point is not\n\t * valid in our model and does not work with FDPIC, where there\n\t * are additional relocation-like fixups that only the entry point\n\t * code can see to perform. */\n\tmain_ctor_queue = queue_ctors(&app);\n\n\t/* Initial TLS must also be allocated before final relocations\n\t * might result in calloc being a call to application code. */\n\tupdate_tls_size();\n\tvoid *initial_tls = builtin_tls;\n\tif (libc.tls_size > sizeof builtin_tls || tls_align > MIN_TLS_ALIGN) {\n\t\tinitial_tls = calloc(libc.tls_size, 1);\n\t\tif (!initial_tls) {\n\t\t\tdprintf(2, \"%s: Error getting %zu bytes thread-local storage: %m\\n\",\n\t\t\t\targv[0], libc.tls_size);\n\t\t\t_exit(127);\n\t\t}\n\t}\n\tstatic_tls_cnt = tls_cnt;\n\n\t/* The main program must be relocated LAST since it may contain\n\t * copy relocations which depend on libraries' relocations. */\n\treloc_all(app.next);\n\treloc_all(&app);\n\n\t/* Actual copying to new TLS needs to happen after relocations,\n\t * since the TLS images might have contained relocated addresses. */\n\tif (initial_tls != builtin_tls) {\n\t\tif (__init_tp(__copy_tls(initial_tls)) < 0) {\n\t\t\ta_crash();\n\t\t}\n\t} else {\n\t\tsize_t tmp_tls_size = libc.tls_size;\n\t\tpthread_t self = __pthread_self();\n\t\t/* Temporarily set the tls size to the full size of\n\t\t * builtin_tls so that __copy_tls will use the same layout\n\t\t * as it did for before. Then check, just to be safe. */\n\t\tlibc.tls_size = sizeof builtin_tls;\n\t\tif (__copy_tls((void*)builtin_tls) != self) a_crash();\n\t\tlibc.tls_size = tmp_tls_size;\n\t}\n\n\tif (ldso_fail) _exit(127);\n\tif (ldd_mode) _exit(0);\n\n\t/* Determine if malloc was interposed by a replacement implementation\n\t * so that calloc and the memalign family can harden against the\n\t * possibility of incomplete replacement. */\n\tif (find_sym(head, \"malloc\", 1).dso != &ldso)\n\t\t__malloc_replaced = 1;\n\tif (find_sym(head, \"aligned_alloc\", 1).dso != &ldso)\n\t\t__aligned_alloc_replaced = 1;\n\n\t/* Switch to runtime mode: any further failures in the dynamic\n\t * linker are a reportable failure rather than a fatal startup\n\t * error. */\n\truntime = 1;\n\n\tdebug.ver = 1;\n\tdebug.bp = dl_debug_state;\n\tdebug.head = head;\n\tdebug.base = ldso.base;\n\tdebug.state = RT_CONSISTENT;\n\t_dl_debug_state();\n\n\tif (replace_argv0) argv[0] = replace_argv0;\n\n\terrno = 0;\n\n\tCRTJMP((void *)aux[AT_ENTRY], argv-1);\n\tfor(;;);\n}\n\nstatic void prepare_lazy(struct dso *p)\n{\n\tsize_t dyn[DYN_CNT], n, flags1=0;\n\tdecode_vec(p->dynv, dyn, DYN_CNT);\n\tsearch_vec(p->dynv, &flags1, DT_FLAGS_1);\n\tif (dyn[DT_BIND_NOW] || (dyn[DT_FLAGS] & DF_BIND_NOW) || (flags1 & DF_1_NOW))\n\t\treturn;\n\tn = dyn[DT_RELSZ]/2 + dyn[DT_RELASZ]/3 + dyn[DT_PLTRELSZ]/2 + 1;\n\tif (NEED_MIPS_GOT_RELOCS) {\n\t\tsize_t j=0; search_vec(p->dynv, &j, DT_MIPS_GOTSYM);\n\t\tsize_t i=0; search_vec(p->dynv, &i, DT_MIPS_SYMTABNO);\n\t\tn += i-j;\n\t}\n\tp->lazy = calloc(n, 3*sizeof(size_t));\n\tif (!p->lazy) {\n\t\terror(\"Error preparing lazy relocation for %s: %m\", p->name);\n\t\tlongjmp(*rtld_fail, 1);\n\t}\n\tp->lazy_next = lazy_head;\n\tlazy_head = p;\n}\n\nvoid *dlopen(const char *file, int mode)\n{\n\tstruct dso *volatile p, *orig_tail, *orig_syms_tail, *orig_lazy_head, *next;\n\tstruct tls_module *orig_tls_tail;\n\tsize_t orig_tls_cnt, orig_tls_offset, orig_tls_align;\n\tsize_t i;\n\tint cs;\n\tjmp_buf jb;\n\tstruct dso **volatile ctor_queue = 0;\n\n\tif (!file) return head;\n\n\tpthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);\n\tpthread_rwlock_wrlock(&lock);\n\t__inhibit_ptc();\n\n\tdebug.state = RT_ADD;\n\t_dl_debug_state();\n\n\tp = 0;\n\tif (shutting_down) {\n\t\terror(\"Cannot dlopen while program is exiting.\");\n\t\tgoto end;\n\t}\n\torig_tls_tail = tls_tail;\n\torig_tls_cnt = tls_cnt;\n\torig_tls_offset = tls_offset;\n\torig_tls_align = tls_align;\n\torig_lazy_head = lazy_head;\n\torig_syms_tail = syms_tail;\n\torig_tail = tail;\n\tnoload = mode & RTLD_NOLOAD;\n\n\trtld_fail = &jb;\n\tif (setjmp(*rtld_fail)) {\n\t\t/* Clean up anything new that was (partially) loaded */\n\t\trevert_syms(orig_syms_tail);\n\t\tfor (p=orig_tail->next; p; p=next) {\n\t\t\tnext = p->next;\n\t\t\twhile (p->td_index) {\n\t\t\t\tvoid *tmp = p->td_index->next;\n\t\t\t\tfree(p->td_index);\n\t\t\t\tp->td_index = tmp;\n\t\t\t}\n\t\t\tfree(p->funcdescs);\n\t\t\tif (p->rpath != p->rpath_orig)\n\t\t\t\tfree(p->rpath);\n\t\t\tfree(p->deps);\n\t\t\tunmap_library(p);\n\t\t\tfree(p);\n\t\t}\n\t\tfree(ctor_queue);\n\t\tctor_queue = 0;\n\t\tif (!orig_tls_tail) libc.tls_head = 0;\n\t\ttls_tail = orig_tls_tail;\n\t\tif (tls_tail) tls_tail->next = 0;\n\t\ttls_cnt = orig_tls_cnt;\n\t\ttls_offset = orig_tls_offset;\n\t\ttls_align = orig_tls_align;\n\t\tlazy_head = orig_lazy_head;\n\t\ttail = orig_tail;\n\t\ttail->next = 0;\n\t\tp = 0;\n\t\tgoto end;\n\t} else p = load_library(file, head);\n\n\tif (!p) {\n\t\terror(noload ?\n\t\t\t\"Library %s is not already loaded\" :\n\t\t\t\"Error loading shared library %s: %m\",\n\t\t\tfile);\n\t\tgoto end;\n\t}\n\n\t/* First load handling */\n\tload_deps(p);\n\textend_bfs_deps(p);\n\tpthread_mutex_lock(&init_fini_lock);\n\tint constructed = p->constructed;\n\tpthread_mutex_unlock(&init_fini_lock);\n\tif (!constructed) ctor_queue = queue_ctors(p);\n\tif (!p->relocated && (mode & RTLD_LAZY)) {\n\t\tprepare_lazy(p);\n\t\tfor (i=0; p->deps[i]; i++)\n\t\t\tif (!p->deps[i]->relocated)\n\t\t\t\tprepare_lazy(p->deps[i]);\n\t}\n\tif (!p->relocated || (mode & RTLD_GLOBAL)) {\n\t\t/* Make new symbols global, at least temporarily, so we can do\n\t\t * relocations. If not RTLD_GLOBAL, this is reverted below. */\n\t\tadd_syms(p);\n\t\tfor (i=0; p->deps[i]; i++)\n\t\t\tadd_syms(p->deps[i]);\n\t}\n\tif (!p->relocated) {\n\t\treloc_all(p);\n\t}\n\n\t/* If RTLD_GLOBAL was not specified, undo any new additions\n\t * to the global symbol table. This is a nop if the library was\n\t * previously loaded and already global. */\n\tif (!(mode & RTLD_GLOBAL))\n\t\trevert_syms(orig_syms_tail);\n\n\t/* Processing of deferred lazy relocations must not happen until\n\t * the new libraries are committed; otherwise we could end up with\n\t * relocations resolved to symbol definitions that get removed. */\n\tredo_lazy_relocs();\n\n\tupdate_tls_size();\n\tif (tls_cnt != orig_tls_cnt)\n\t\tinstall_new_tls();\n\torig_tail = tail;\nend:\n\tdebug.state = RT_CONSISTENT;\n\t_dl_debug_state();\n\t__release_ptc();\n\tif (p) gencnt++;\n\tpthread_rwlock_unlock(&lock);\n\tif (ctor_queue) {\n\t\tdo_init_fini(ctor_queue);\n\t\tfree(ctor_queue);\n\t}\n\tpthread_setcancelstate(cs, 0);\n\treturn p;\n}\n\nhidden int __dl_invalid_handle(void *h)\n{\n\tstruct dso *p;\n\tfor (p=head; p; p=p->next) if (h==p) return 0;\n\terror(\"Invalid library handle %p\", (void *)h);\n\treturn 1;\n}\n\nstatic void *addr2dso(size_t a)\n{\n\tstruct dso *p;\n\tsize_t i;\n\tif (DL_FDPIC) for (p=head; p; p=p->next) {\n\t\ti = count_syms(p);\n\t\tif (a-(size_t)p->funcdescs < i*sizeof(*p->funcdescs))\n\t\t\treturn p;\n\t}\n\tfor (p=head; p; p=p->next) {\n\t\tif (DL_FDPIC && p->loadmap) {\n\t\t\tfor (i=0; i<p->loadmap->nsegs; i++) {\n\t\t\t\tif (a-p->loadmap->segs[i].p_vaddr\n\t\t\t\t    < p->loadmap->segs[i].p_memsz)\n\t\t\t\t\treturn p;\n\t\t\t}\n\t\t} else {\n\t\t\tPhdr *ph = p->phdr;\n\t\t\tsize_t phcnt = p->phnum;\n\t\t\tsize_t entsz = p->phentsize;\n\t\t\tsize_t base = (size_t)p->base;\n\t\t\tfor (; phcnt--; ph=(void *)((char *)ph+entsz)) {\n\t\t\t\tif (ph->p_type != PT_LOAD) continue;\n\t\t\t\tif (a-base-ph->p_vaddr < ph->p_memsz)\n\t\t\t\t\treturn p;\n\t\t\t}\n\t\t\tif (a-(size_t)p->map < p->map_len)\n\t\t\t\treturn 0;\n\t\t}\n\t}\n\treturn 0;\n}\n\nstatic void *do_dlsym(struct dso *p, const char *s, void *ra)\n{\n\tint use_deps = 0;\n\tif (p == head || p == RTLD_DEFAULT) {\n\t\tp = head;\n\t} else if (p == RTLD_NEXT) {\n\t\tp = addr2dso((size_t)ra);\n\t\tif (!p) p=head;\n\t\tp = p->next;\n\t} else if (__dl_invalid_handle(p)) {\n\t\treturn 0;\n\t} else\n\t\tuse_deps = 1;\n\tstruct symdef def = find_sym2(p, s, 0, use_deps);\n\tif (!def.sym) {\n\t\terror(\"Symbol not found: %s\", s);\n\t\treturn 0;\n\t}\n\tif ((def.sym->st_info&0xf) == STT_TLS)\n\t\treturn __tls_get_addr((tls_mod_off_t []){def.dso->tls_id, def.sym->st_value-DTP_OFFSET});\n\tif (DL_FDPIC && (def.sym->st_info&0xf) == STT_FUNC)\n\t\treturn def.dso->funcdescs + (def.sym - def.dso->syms);\n\treturn laddr(def.dso, def.sym->st_value);\n}\n\nint dladdr(const void *addr_arg, Dl_info *info)\n{\n\tsize_t addr = (size_t)addr_arg;\n\tstruct dso *p;\n\tSym *sym, *bestsym;\n\tuint32_t nsym;\n\tchar *strings;\n\tsize_t best = 0;\n\tsize_t besterr = -1;\n\n\tpthread_rwlock_rdlock(&lock);\n\tp = addr2dso(addr);\n\tpthread_rwlock_unlock(&lock);\n\n\tif (!p) return 0;\n\n\tsym = p->syms;\n\tstrings = p->strings;\n\tnsym = count_syms(p);\n\n\tif (DL_FDPIC) {\n\t\tsize_t idx = (addr-(size_t)p->funcdescs)\n\t\t\t/ sizeof(*p->funcdescs);\n\t\tif (idx < nsym && (sym[idx].st_info&0xf) == STT_FUNC) {\n\t\t\tbest = (size_t)(p->funcdescs + idx);\n\t\t\tbestsym = sym + idx;\n\t\t\tbesterr = 0;\n\t\t}\n\t}\n\n\tif (!best) for (; nsym; nsym--, sym++) {\n\t\tif (sym->st_value\n\t\t && (1<<(sym->st_info&0xf) & OK_TYPES)\n\t\t && (1<<(sym->st_info>>4) & OK_BINDS)) {\n\t\t\tsize_t symaddr = (size_t)laddr(p, sym->st_value);\n\t\t\tif (symaddr > addr || symaddr <= best)\n\t\t\t\tcontinue;\n\t\t\tbest = symaddr;\n\t\t\tbestsym = sym;\n\t\t\tbesterr = addr - symaddr;\n\t\t\tif (addr == symaddr)\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (best && besterr > bestsym->st_size-1) {\n\t\tbest = 0;\n\t\tbestsym = 0;\n\t}\n\n\tinfo->dli_fname = p->name;\n\tinfo->dli_fbase = p->map;\n\n\tif (!best) {\n\t\tinfo->dli_sname = 0;\n\t\tinfo->dli_saddr = 0;\n\t\treturn 1;\n\t}\n\n\tif (DL_FDPIC && (bestsym->st_info&0xf) == STT_FUNC)\n\t\tbest = (size_t)(p->funcdescs + (bestsym - p->syms));\n\tinfo->dli_sname = strings + bestsym->st_name;\n\tinfo->dli_saddr = (void *)best;\n\n\treturn 1;\n}\n\nhidden void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra)\n{\n\tvoid *res;\n\tpthread_rwlock_rdlock(&lock);\n\tres = do_dlsym(p, s, ra);\n\tpthread_rwlock_unlock(&lock);\n\treturn res;\n}\n\nhidden void *__dlsym_redir_time64(void *restrict p, const char *restrict s, void *restrict ra)\n{\n#if _REDIR_TIME64\n\tconst char *suffix, *suffix2 = \"\";\n\tchar redir[36];\n\n\t/* Map the symbol name to a time64 version of itself according to the\n\t * pattern used for naming the redirected time64 symbols. */\n\tsize_t l = strnlen(s, sizeof redir);\n\tif (l<4 || l==sizeof redir) goto no_redir;\n\tif (s[l-2]=='_' && s[l-1]=='r') {\n\t\tl -= 2;\n\t\tsuffix2 = s+l;\n\t}\n\tif (l<4) goto no_redir;\n\tif (!strcmp(s+l-4, \"time\")) suffix = \"64\";\n\telse suffix = \"_time64\";\n\n\t/* Use the presence of the remapped symbol name in libc to determine\n\t * whether it's one that requires time64 redirection; replace if so. */\n\tsnprintf(redir, sizeof redir, \"__%.*s%s%s\", (int)l, s, suffix, suffix2);\n\tif (find_sym(&ldso, redir, 1).sym) s = redir;\nno_redir:\n#endif\n\treturn __dlsym(p, s, ra);\n}\n\nint dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data)\n{\n\tstruct dso *current;\n\tstruct dl_phdr_info info;\n\tint ret = 0;\n\tfor(current = head; current;) {\n\t\tinfo.dlpi_addr      = (uintptr_t)current->base;\n\t\tinfo.dlpi_name      = current->name;\n\t\tinfo.dlpi_phdr      = current->phdr;\n\t\tinfo.dlpi_phnum     = current->phnum;\n\t\tinfo.dlpi_adds      = gencnt;\n\t\tinfo.dlpi_subs      = 0;\n\t\tinfo.dlpi_tls_modid = current->tls_id;\n\t\tinfo.dlpi_tls_data  = current->tls.image;\n\n\t\tret = (callback)(&info, sizeof (info), data);\n\n\t\tif (ret != 0) break;\n\n\t\tpthread_rwlock_rdlock(&lock);\n\t\tcurrent = current->next;\n\t\tpthread_rwlock_unlock(&lock);\n\t}\n\treturn ret;\n}\n\nstatic void error(const char *fmt, ...)\n{\n\tva_list ap;\n\tva_start(ap, fmt);\n\tif (!runtime) {\n\t\tvdprintf(2, fmt, ap);\n\t\tdprintf(2, \"\\n\");\n\t\tldso_fail = 1;\n\t\tva_end(ap);\n\t\treturn;\n\t}\n\t__dl_vseterr(fmt, ap);\n\tva_end(ap);\n}\n"
  },
  {
    "path": "user.libc/src/bitmap/bitmap.c",
    "content": "#include <inttypes.h>\n#include <errno.h>\n#include <string.h>\n#include <minos/types.h>\n\n#include <bitmap.h>\n\n#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))\n\nint __bitmap_weight(const unsigned long *bitmap, unsigned int bits)\n{\n\tunsigned int k, lim = bits/BITS_PER_LONG;\n\tint w = 0;\n\n\tfor (k = 0; k < lim; k++)\n\t\tw += hweight_long(bitmap[k]);\n\n\tif (bits % BITS_PER_LONG)\n\t\tw += hweight_long(bitmap[k] & BITMAP_LAST_WORD_MASK(bits));\n\n\treturn w;\n}\n\nvoid bitmap_set(unsigned long *map, unsigned int start, int len)\n{\n\tunsigned long *p = map + BIT_WORD(start);\n\tconst unsigned int size = start + len;\n\tint bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG);\n\tunsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start);\n\n\twhile (len - bits_to_set >= 0) {\n\t\t*p |= mask_to_set;\n\t\tlen -= bits_to_set;\n\t\tbits_to_set = BITS_PER_LONG;\n\t\tmask_to_set = ~0UL;\n\t\tp++;\n\t}\n\tif (len) {\n\t\tmask_to_set &= BITMAP_LAST_WORD_MASK(size);\n\t\t*p |= mask_to_set;\n\t}\n}\n\nvoid bitmap_clear(unsigned long *map, unsigned int start, int len)\n{\n\tunsigned long *p = map + BIT_WORD(start);\n\tconst unsigned int size = start + len;\n\tint bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG);\n\tunsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start);\n\n\twhile (len - bits_to_clear >= 0) {\n\t\t*p &= ~mask_to_clear;\n\t\tlen -= bits_to_clear;\n\t\tbits_to_clear = BITS_PER_LONG;\n\t\tmask_to_clear = ~0UL;\n\t\tp++;\n\t}\n\tif (len) {\n\t\tmask_to_clear &= BITMAP_LAST_WORD_MASK(size);\n\t\t*p &= ~mask_to_clear;\n\t}\n}\n\nunsigned long bitmap_find_next_zero_area_off(unsigned long *map,\n\t\t\t\t\t     unsigned long size,\n\t\t\t\t\t     unsigned long start,\n\t\t\t\t\t     unsigned int nr,\n\t\t\t\t\t     unsigned long align_mask,\n\t\t\t\t\t     unsigned long align_offset)\n{\n\tunsigned long index, end, i;\nagain:\n\tindex = find_next_zero_bit(map, size, start);\n\n\t/* Align allocation */\n\tindex = __ALIGN_MASK(index + align_offset, align_mask) - align_offset;\n\n\tend = index + nr;\n\tif (end > size)\n\t\treturn end;\n\ti = find_next_bit(map, end, index);\n\tif (i < end) {\n\t\tstart = i + 1;\n\t\tgoto again;\n\t}\n\treturn index;\n}\n\nunsigned long bitmap_find_next_zero_area_align(unsigned long *map,\n\t\t\t\t\t     unsigned long size,\n\t\t\t\t\t     unsigned long start,\n\t\t\t\t\t     unsigned int nr,\n\t\t\t\t\t     unsigned long align)\n{\n\tunsigned long index, end, i;\nagain:\n\tindex = find_next_zero_bit(map, size, start);\n\n\tend = index + nr;\n\tif (end > size)\n\t\treturn end;\n\n\tif ((index & ((align - 1)))) {\n\t\tstart = index + 1;\n\t\tgoto again;\n\t}\n\n\ti = find_next_bit(map, end, index);\n\tif (i < end) {\n\t\tstart = i + 1;\n\t\tgoto again;\n\t}\n\treturn index;\n}\n"
  },
  {
    "path": "user.libc/src/bitmap/find_bit.c",
    "content": "#include <bitops.h>\n#include <bitmap.h>\n#include <sys/param.h>\n\nstatic unsigned long _find_next_bit(const unsigned long *addr,\n\t\tunsigned long nbits, unsigned long start, unsigned long invert)\n{\n\tunsigned long tmp;\n\n\tif (!nbits || start >= nbits)\n\t\treturn nbits;\n\n\ttmp = addr[start / BITS_PER_LONG] ^ invert;\n\n\ttmp &= BITMAP_FIRST_WORD_MASK(start);\n\tstart = round_down(start, BITS_PER_LONG);\n\n\twhile (!tmp) {\n\t\tstart += BITS_PER_LONG;\n\t\tif (start >= nbits)\n\t\t\treturn nbits;\n\n\t\ttmp = addr[start / BITS_PER_LONG] ^ invert;\n\t}\n\n\treturn MIN(start + __ffs(tmp), nbits);\n}\n\nunsigned long find_next_bit(const unsigned long *addr, unsigned long size,\n\t\t\t    unsigned long offset)\n{\n\treturn _find_next_bit(addr, size, offset, 0UL);\n}\n\nunsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,\n\t\t\t\t unsigned long offset)\n{\n\treturn _find_next_bit(addr, size, offset, ~0UL);\n}\n\nunsigned long _find_next_bit_loop(const unsigned long *addr, unsigned long size,\n\t\t\t\tunsigned long offset, unsigned long invert)\n{\n\tunsigned long bit;\n\nloop:\n\tbit = _find_next_bit(addr, size, offset, invert);\n\tif (bit >= size) {\n\t\tif (offset != 0) {\n\t\t\toffset = 0;\n\t\t\tgoto loop;\n\t\t}\n\t}\n\n\treturn bit;\n}\n\nunsigned long find_next_bit_loop(const unsigned long *addr, unsigned long size,\n\t\t\t\tunsigned long offset)\n{\n\treturn _find_next_bit_loop(addr, size, offset, 0UL);\n}\n\nunsigned long find_next_zero_bit_loop(const unsigned long *addr, unsigned long size,\n\t\t\t\tunsigned long offset)\n{\n\treturn _find_next_bit_loop(addr, size, offset, ~0UL);\n}\n\nunsigned long find_first_bit(const unsigned long *addr, unsigned long size)\n{\n\tunsigned long idx;\n\n\tfor (idx = 0; idx * BITS_PER_LONG < size; idx++) {\n\t\tif (addr[idx])\n\t\t\treturn MIN(idx * BITS_PER_LONG + __ffs(addr[idx]), size);\n\t}\n\n\treturn size;\n}\n\nunsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size)\n{\n\tunsigned long idx;\n\n\tfor (idx = 0; idx * BITS_PER_LONG < size; idx++) {\n\t\tif (addr[idx] != ~0UL)\n\t\t\treturn MIN(idx * BITS_PER_LONG + ffz(addr[idx]), size);\n\t}\n\n\treturn size;\n}\n\nunsigned long find_last_bit(const unsigned long *addr, unsigned long size)\n{\n\tif (size) {\n\t\tunsigned long val = BITMAP_LAST_WORD_MASK(size);\n\t\tunsigned long idx = (size-1) / BITS_PER_LONG;\n\n\t\tdo {\n\t\t\tval &= addr[idx];\n\t\t\tif (val)\n\t\t\t\treturn idx * BITS_PER_LONG + __fls(val);\n\n\t\t\tval = ~0ul;\n\t\t} while (idx--);\n\t}\n\treturn size;\n}\n"
  },
  {
    "path": "user.libc/src/bitmap/hweight.c",
    "content": "#include <minos/types.h>\n\n#include <bitops.h>\n\nunsigned int sw_hweight32(unsigned int w)\n{\n#ifdef CONFIG_ARCH_HAS_FAST_MULTIPLIER\n\tw -= (w >> 1) & 0x55555555;\n\tw =  (w & 0x33333333) + ((w >> 2) & 0x33333333);\n\tw =  (w + (w >> 4)) & 0x0f0f0f0f;\n\treturn (w * 0x01010101) >> 24;\n#else\n\tunsigned int res = w - ((w >> 1) & 0x55555555);\n\tres = (res & 0x33333333) + ((res >> 2) & 0x33333333);\n\tres = (res + (res >> 4)) & 0x0F0F0F0F;\n\tres = res + (res >> 8);\n\treturn (res + (res >> 16)) & 0x000000FF;\n#endif\n}\n\nunsigned int sw_hweight16(unsigned int w)\n{\n\tunsigned int res = w - ((w >> 1) & 0x5555);\n\tres = (res & 0x3333) + ((res >> 2) & 0x3333);\n\tres = (res + (res >> 4)) & 0x0F0F;\n\treturn (res + (res >> 8)) & 0x00FF;\n}\n\nunsigned int sw_hweight8(unsigned int w)\n{\n\tunsigned int res = w - ((w >> 1) & 0x55);\n\tres = (res & 0x33) + ((res >> 2) & 0x33);\n\treturn (res + (res >> 4)) & 0x0F;\n}\n\nunsigned long sw_hweight64(uint64_t w)\n{\n#if BITS_PER_LONG == 32\n\treturn __sw_hweight32((unsigned int)(w >> 32)) +\n\t       __sw_hweight32((unsigned int)w);\n#elif BITS_PER_LONG == 64\n#ifdef CONFIG_ARCH_HAS_FAST_MULTIPLIER\n\tw -= (w >> 1) & 0x5555555555555555ul;\n\tw =  (w & 0x3333333333333333ul) + ((w >> 2) & 0x3333333333333333ul);\n\tw =  (w + (w >> 4)) & 0x0f0f0f0f0f0f0f0ful;\n\treturn (w * 0x0101010101010101ul) >> 56;\n#else\n\tuint64_t res = w - ((w >> 1) & 0x5555555555555555ul);\n\tres = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul);\n\tres = (res + (res >> 4)) & 0x0F0F0F0F0F0F0F0Ful;\n\tres = res + (res >> 8);\n\tres = res + (res >> 16);\n\treturn (res + (res >> 32)) & 0x00000000000000FFul;\n#endif\n#endif\n}\n"
  },
  {
    "path": "user.libc/src/complex/__cexp.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/k_exp.c */\n/*-\n * Copyright (c) 2011 David Schultz <das@FreeBSD.ORG>\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include \"complex_impl.h\"\n\nstatic const uint32_t k = 1799; /* constant for reduction */\nstatic const double kln2 = 1246.97177782734161156; /* k * ln2 */\n\n/*\n * Compute exp(x), scaled to avoid spurious overflow.  An exponent is\n * returned separately in 'expt'.\n *\n * Input:  ln(DBL_MAX) <= x < ln(2 * DBL_MAX / DBL_MIN_DENORM) ~= 1454.91\n * Output: 2**1023 <= y < 2**1024\n */\nstatic double __frexp_exp(double x, int *expt)\n{\n\tdouble exp_x;\n\tuint32_t hx;\n\n\t/*\n\t * We use exp(x) = exp(x - kln2) * 2**k, carefully chosen to\n\t * minimize |exp(kln2) - 2**k|.  We also scale the exponent of\n\t * exp_x to MAX_EXP so that the result can be multiplied by\n\t * a tiny number without losing accuracy due to denormalization.\n\t */\n\texp_x = exp(x - kln2);\n\tGET_HIGH_WORD(hx, exp_x);\n\t*expt = (hx >> 20) - (0x3ff + 1023) + k;\n\tSET_HIGH_WORD(exp_x, (hx & 0xfffff) | ((0x3ff + 1023) << 20));\n\treturn exp_x;\n}\n\n/*\n * __ldexp_cexp(x, expt) compute exp(x) * 2**expt.\n * It is intended for large arguments (real part >= ln(DBL_MAX))\n * where care is needed to avoid overflow.\n *\n * The present implementation is narrowly tailored for our hyperbolic and\n * exponential functions.  We assume expt is small (0 or -1), and the caller\n * has filtered out very large x, for which overflow would be inevitable.\n */\ndouble complex __ldexp_cexp(double complex z, int expt)\n{\n\tdouble x, y, exp_x, scale1, scale2;\n\tint ex_expt, half_expt;\n\n\tx = creal(z);\n\ty = cimag(z);\n\texp_x = __frexp_exp(x, &ex_expt);\n\texpt += ex_expt;\n\n\t/*\n\t * Arrange so that scale1 * scale2 == 2**expt.  We use this to\n\t * compensate for scalbn being horrendously slow.\n\t */\n\thalf_expt = expt / 2;\n\tINSERT_WORDS(scale1, (0x3ff + half_expt) << 20, 0);\n\thalf_expt = expt - half_expt;\n\tINSERT_WORDS(scale2, (0x3ff + half_expt) << 20, 0);\n\n\treturn CMPLX(cos(y) * exp_x * scale1 * scale2, sin(y) * exp_x * scale1 * scale2);\n}\n"
  },
  {
    "path": "user.libc/src/complex/__cexpf.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/k_expf.c */\n/*-\n * Copyright (c) 2011 David Schultz <das@FreeBSD.ORG>\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include \"complex_impl.h\"\n\nstatic const uint32_t k = 235; /* constant for reduction */\nstatic const float kln2 = 162.88958740F; /* k * ln2 */\n\n/*\n * See __cexp.c for details.\n *\n * Input:  ln(FLT_MAX) <= x < ln(2 * FLT_MAX / FLT_MIN_DENORM) ~= 192.7\n * Output: 2**127 <= y < 2**128\n */\nstatic float __frexp_expf(float x, int *expt)\n{\n\tfloat exp_x;\n\tuint32_t hx;\n\n\texp_x = expf(x - kln2);\n\tGET_FLOAT_WORD(hx, exp_x);\n\t*expt = (hx >> 23) - (0x7f + 127) + k;\n\tSET_FLOAT_WORD(exp_x, (hx & 0x7fffff) | ((0x7f + 127) << 23));\n\treturn exp_x;\n}\n\nfloat complex __ldexp_cexpf(float complex z, int expt)\n{\n\tfloat x, y, exp_x, scale1, scale2;\n\tint ex_expt, half_expt;\n\n\tx = crealf(z);\n\ty = cimagf(z);\n\texp_x = __frexp_expf(x, &ex_expt);\n\texpt += ex_expt;\n\n\thalf_expt = expt / 2;\n\tSET_FLOAT_WORD(scale1, (0x7f + half_expt) << 23);\n\thalf_expt = expt - half_expt;\n\tSET_FLOAT_WORD(scale2, (0x7f + half_expt) << 23);\n\n\treturn CMPLXF(cosf(y) * exp_x * scale1 * scale2,\n\t  sinf(y) * exp_x * scale1 * scale2);\n}\n"
  },
  {
    "path": "user.libc/src/complex/cabs.c",
    "content": "#include \"complex_impl.h\"\n\ndouble cabs(double complex z)\n{\n\treturn hypot(creal(z), cimag(z));\n}\n"
  },
  {
    "path": "user.libc/src/complex/cabsf.c",
    "content": "#include \"complex_impl.h\"\n\nfloat cabsf(float complex z)\n{\n\treturn hypotf(crealf(z), cimagf(z));\n}\n"
  },
  {
    "path": "user.libc/src/complex/cabsl.c",
    "content": "#include \"complex_impl.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double cabsl(long double complex z)\n{\n\treturn cabs(z);\n}\n#else\nlong double cabsl(long double complex z)\n{\n\treturn hypotl(creall(z), cimagl(z));\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/complex/cacos.c",
    "content": "#include \"complex_impl.h\"\n\n// FIXME: Hull et al. \"Implementing the complex arcsine and arccosine functions using exception handling\" 1997\n\n/* acos(z) = pi/2 - asin(z) */\n\ndouble complex cacos(double complex z)\n{\n\tz = casin(z);\n\treturn CMPLX(M_PI_2 - creal(z), -cimag(z));\n}\n"
  },
  {
    "path": "user.libc/src/complex/cacosf.c",
    "content": "#include \"complex_impl.h\"\n\n// FIXME\n\nfloat complex cacosf(float complex z)\n{\n\tz = casinf(z);\n\treturn CMPLXF((float)M_PI_2 - crealf(z), -cimagf(z));\n}\n"
  },
  {
    "path": "user.libc/src/complex/cacosh.c",
    "content": "#include \"complex_impl.h\"\n\n/* acosh(z) = i acos(z) */\n\ndouble complex cacosh(double complex z)\n{\n\tint zineg = signbit(cimag(z));\n\n\tz = cacos(z);\n\tif (zineg) return CMPLX(cimag(z), -creal(z));\n\telse       return CMPLX(-cimag(z), creal(z));\n}\n"
  },
  {
    "path": "user.libc/src/complex/cacoshf.c",
    "content": "#include \"complex_impl.h\"\n\nfloat complex cacoshf(float complex z)\n{\n\tint zineg = signbit(cimagf(z));\n\n\tz = cacosf(z);\n\tif (zineg) return CMPLXF(cimagf(z), -crealf(z));\n\telse       return CMPLXF(-cimagf(z), crealf(z));\n}\n"
  },
  {
    "path": "user.libc/src/complex/cacoshl.c",
    "content": "#include \"complex_impl.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double complex cacoshl(long double complex z)\n{\n\treturn cacosh(z);\n}\n#else\nlong double complex cacoshl(long double complex z)\n{\n\tint zineg = signbit(cimagl(z));\n\n\tz = cacosl(z);\n\tif (zineg) return CMPLXL(cimagl(z), -creall(z));\n\telse       return CMPLXL(-cimagl(z), creall(z));\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/complex/cacosl.c",
    "content": "#include \"complex_impl.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double complex cacosl(long double complex z)\n{\n\treturn cacos(z);\n}\n#else\n// FIXME\n#define PI_2 1.57079632679489661923132169163975144L\nlong double complex cacosl(long double complex z)\n{\n\tz = casinl(z);\n\treturn CMPLXL(PI_2 - creall(z), -cimagl(z));\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/complex/carg.c",
    "content": "#include \"complex_impl.h\"\n\ndouble carg(double complex z)\n{\n\treturn atan2(cimag(z), creal(z));\n}\n"
  },
  {
    "path": "user.libc/src/complex/cargf.c",
    "content": "#include \"complex_impl.h\"\n\nfloat cargf(float complex z)\n{\n\treturn atan2f(cimagf(z), crealf(z));\n}\n"
  },
  {
    "path": "user.libc/src/complex/cargl.c",
    "content": "#include \"complex_impl.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double cargl(long double complex z)\n{\n\treturn carg(z);\n}\n#else\nlong double cargl(long double complex z)\n{\n\treturn atan2l(cimagl(z), creall(z));\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/complex/casin.c",
    "content": "#include \"complex_impl.h\"\n\n// FIXME\n\n/* asin(z) = -i log(i z + sqrt(1 - z*z)) */\n\ndouble complex casin(double complex z)\n{\n\tdouble complex w;\n\tdouble x, y;\n\n\tx = creal(z);\n\ty = cimag(z);\n\tw = CMPLX(1.0 - (x - y)*(x + y), -2.0*x*y);\n\tdouble complex r = clog(CMPLX(-y, x) + csqrt(w));\n\treturn CMPLX(cimag(r), -creal(r));\n}\n"
  },
  {
    "path": "user.libc/src/complex/casinf.c",
    "content": "#include \"complex_impl.h\"\n\n// FIXME\n\nfloat complex casinf(float complex z)\n{\n\tfloat complex w;\n\tfloat x, y;\n\n\tx = crealf(z);\n\ty = cimagf(z);\n\tw = CMPLXF(1.0 - (x - y)*(x + y), -2.0*x*y);\n\tfloat complex r = clogf(CMPLXF(-y, x) + csqrtf(w));\n\treturn CMPLXF(cimagf(r), -crealf(r));\n}\n"
  },
  {
    "path": "user.libc/src/complex/casinh.c",
    "content": "#include \"complex_impl.h\"\n\n/* asinh(z) = -i asin(i z) */\n\ndouble complex casinh(double complex z)\n{\n\tz = casin(CMPLX(-cimag(z), creal(z)));\n\treturn CMPLX(cimag(z), -creal(z));\n}\n"
  },
  {
    "path": "user.libc/src/complex/casinhf.c",
    "content": "#include \"complex_impl.h\"\n\nfloat complex casinhf(float complex z)\n{\n\tz = casinf(CMPLXF(-cimagf(z), crealf(z)));\n\treturn CMPLXF(cimagf(z), -crealf(z));\n}\n"
  },
  {
    "path": "user.libc/src/complex/casinhl.c",
    "content": "#include \"complex_impl.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double complex casinhl(long double complex z)\n{\n\treturn casinh(z);\n}\n#else\nlong double complex casinhl(long double complex z)\n{\n\tz = casinl(CMPLXL(-cimagl(z), creall(z)));\n\treturn CMPLXL(cimagl(z), -creall(z));\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/complex/casinl.c",
    "content": "#include \"complex_impl.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double complex casinl(long double complex z)\n{\n\treturn casin(z);\n}\n#else\n// FIXME\nlong double complex casinl(long double complex z)\n{\n\tlong double complex w;\n\tlong double x, y;\n\n\tx = creall(z);\n\ty = cimagl(z);\n\tw = CMPLXL(1.0 - (x - y)*(x + y), -2.0*x*y);\n\tlong double complex r = clogl(CMPLXL(-y, x) + csqrtl(w));\n\treturn CMPLXL(cimagl(r), -creall(r));\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/complex/catan.c",
    "content": "/* origin: OpenBSD /usr/src/lib/libm/src/s_catan.c */\n/*\n * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n/*\n *      Complex circular arc tangent\n *\n *\n * SYNOPSIS:\n *\n * double complex catan();\n * double complex z, w;\n *\n * w = catan (z);\n *\n *\n * DESCRIPTION:\n *\n * If\n *     z = x + iy,\n *\n * then\n *          1       (    2x     )\n * Re w  =  - arctan(-----------)  +  k PI\n *          2       (     2    2)\n *                  (1 - x  - y )\n *\n *               ( 2         2)\n *          1    (x  +  (y+1) )\n * Im w  =  - log(------------)\n *          4    ( 2         2)\n *               (x  +  (y-1) )\n *\n * Where k is an arbitrary integer.\n *\n * catan(z) = -i catanh(iz).\n *\n * ACCURACY:\n *\n *                      Relative error:\n * arithmetic   domain     # trials      peak         rms\n *    DEC       -10,+10      5900       1.3e-16     7.8e-18\n *    IEEE      -10,+10     30000       2.3e-15     8.5e-17\n * The check catan( ctan(z) )  =  z, with |x| and |y| < PI/2,\n * had peak relative error 1.5e-16, rms relative error\n * 2.9e-17.  See also clog().\n */\n\n#include \"complex_impl.h\"\n\n#define MAXNUM 1.0e308\n\nstatic const double DP1 = 3.14159265160560607910E0;\nstatic const double DP2 = 1.98418714791870343106E-9;\nstatic const double DP3 = 1.14423774522196636802E-17;\n\nstatic double _redupi(double x)\n{\n\tdouble t;\n\tlong i;\n\n\tt = x/M_PI;\n\tif (t >= 0.0)\n\t\tt += 0.5;\n\telse\n\t\tt -= 0.5;\n\n\ti = t;  /* the multiple */\n\tt = i;\n\tt = ((x - t * DP1) - t * DP2) - t * DP3;\n\treturn t;\n}\n\ndouble complex catan(double complex z)\n{\n\tdouble complex w;\n\tdouble a, t, x, x2, y;\n\n\tx = creal(z);\n\ty = cimag(z);\n\n\tx2 = x * x;\n\ta = 1.0 - x2 - (y * y);\n\n\tt = 0.5 * atan2(2.0 * x, a);\n\tw = _redupi(t);\n\n\tt = y - 1.0;\n\ta = x2 + (t * t);\n\n\tt = y + 1.0;\n\ta = (x2 + t * t)/a;\n\tw = CMPLX(w, 0.25 * log(a));\n\treturn w;\n}\n"
  },
  {
    "path": "user.libc/src/complex/catanf.c",
    "content": "/* origin: OpenBSD /usr/src/lib/libm/src/s_catanf.c */\n/*\n * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n/*\n *      Complex circular arc tangent\n *\n *\n * SYNOPSIS:\n *\n * float complex catanf();\n * float complex z, w;\n *\n * w = catanf( z );\n *\n *\n * DESCRIPTION:\n *\n * If\n *     z = x + iy,\n *\n * then\n *          1       (    2x     )\n * Re w  =  - arctan(-----------)  +  k PI\n *          2       (     2    2)\n *                  (1 - x  - y )\n *\n *               ( 2         2)\n *          1    (x  +  (y+1) )\n * Im w  =  - log(------------)\n *          4    ( 2         2)\n *               (x  +  (y-1) )\n *\n * Where k is an arbitrary integer.\n *\n *\n * ACCURACY:\n *\n *                      Relative error:\n * arithmetic   domain     # trials      peak         rms\n *    IEEE      -10,+10     30000        2.3e-6      5.2e-8\n */\n\n#include \"complex_impl.h\"\n\n#define MAXNUMF 1.0e38F\n\nstatic const double DP1 = 3.140625;\nstatic const double DP2 = 9.67502593994140625E-4;\nstatic const double DP3 = 1.509957990978376432E-7;\n\nstatic float _redupif(float xx)\n{\n\tfloat x, t;\n\tlong i;\n\n\tx = xx;\n\tt = x/(float)M_PI;\n\tif (t >= 0.0f)\n\t\tt += 0.5f;\n\telse\n\t\tt -= 0.5f;\n\n\ti = t;  /* the multiple */\n\tt = i;\n\tt = ((x - t * DP1) - t * DP2) - t * DP3;\n\treturn t;\n}\n\nfloat complex catanf(float complex z)\n{\n\tfloat complex w;\n\tfloat a, t, x, x2, y;\n\n\tx = crealf(z);\n\ty = cimagf(z);\n\n\tx2 = x * x;\n\ta = 1.0f - x2 - (y * y);\n\n\tt = 0.5f * atan2f(2.0f * x, a);\n\tw = _redupif(t);\n\n\tt = y - 1.0f;\n\ta = x2 + (t * t);\n\n\tt = y + 1.0f;\n\ta = (x2 + (t * t))/a;\n\tw = CMPLXF(w, 0.25f * logf(a));\n\treturn w;\n}\n"
  },
  {
    "path": "user.libc/src/complex/catanh.c",
    "content": "#include \"complex_impl.h\"\n\n/* atanh = -i atan(i z) */\n\ndouble complex catanh(double complex z)\n{\n\tz = catan(CMPLX(-cimag(z), creal(z)));\n\treturn CMPLX(cimag(z), -creal(z));\n}\n"
  },
  {
    "path": "user.libc/src/complex/catanhf.c",
    "content": "#include \"complex_impl.h\"\n\nfloat complex catanhf(float complex z)\n{\n\tz = catanf(CMPLXF(-cimagf(z), crealf(z)));\n\treturn CMPLXF(cimagf(z), -crealf(z));\n}\n"
  },
  {
    "path": "user.libc/src/complex/catanhl.c",
    "content": "#include \"complex_impl.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double complex catanhl(long double complex z)\n{\n\treturn catanh(z);\n}\n#else\nlong double complex catanhl(long double complex z)\n{\n\tz = catanl(CMPLXL(-cimagl(z), creall(z)));\n\treturn CMPLXL(cimagl(z), -creall(z));\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/complex/catanl.c",
    "content": "/* origin: OpenBSD /usr/src/lib/libm/src/s_catanl.c */\n/*\n * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n/*\n *      Complex circular arc tangent\n *\n *\n * SYNOPSIS:\n *\n * long double complex catanl();\n * long double complex z, w;\n *\n * w = catanl( z );\n *\n *\n * DESCRIPTION:\n *\n * If\n *     z = x + iy,\n *\n * then\n *          1       (    2x     )\n * Re w  =  - arctan(-----------)  +  k PI\n *          2       (     2    2)\n *                  (1 - x  - y )\n *\n *               ( 2         2)\n *          1    (x  +  (y+1) )\n * Im w  =  - log(------------)\n *          4    ( 2         2)\n *               (x  +  (y-1) )\n *\n * Where k is an arbitrary integer.\n *\n *\n * ACCURACY:\n *\n *                      Relative error:\n * arithmetic   domain     # trials      peak         rms\n *    DEC       -10,+10      5900       1.3e-16     7.8e-18\n *    IEEE      -10,+10     30000       2.3e-15     8.5e-17\n * The check catan( ctan(z) )  =  z, with |x| and |y| < PI/2,\n * had peak relative error 1.5e-16, rms relative error\n * 2.9e-17.  See also clog().\n */\n\n#include <complex.h>\n#include <float.h>\n#include \"complex_impl.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double complex catanl(long double complex z)\n{\n\treturn catan(z);\n}\n#else\nstatic const long double PIL = 3.141592653589793238462643383279502884197169L;\nstatic const long double DP1 = 3.14159265358979323829596852490908531763125L;\nstatic const long double DP2 = 1.6667485837041756656403424829301998703007e-19L;\nstatic const long double DP3 = 1.8830410776607851167459095484560349402753e-39L;\n\nstatic long double redupil(long double x)\n{\n\tlong double t;\n\tlong i;\n\n\tt = x / PIL;\n\tif (t >= 0.0L)\n\t\tt += 0.5L;\n\telse\n\t\tt -= 0.5L;\n\n\ti = t;  /* the multiple */\n\tt = i;\n\tt = ((x - t * DP1) - t * DP2) - t * DP3;\n\treturn t;\n}\n\nlong double complex catanl(long double complex z)\n{\n\tlong double complex w;\n\tlong double a, t, x, x2, y;\n\n\tx = creall(z);\n\ty = cimagl(z);\n\n\tx2 = x * x;\n\ta = 1.0L - x2 - (y * y);\n\n\tt = atan2l(2.0L * x, a) * 0.5L;\n\tw = redupil(t);\n\n\tt = y - 1.0L;\n\ta = x2 + (t * t);\n\n\tt = y + 1.0L;\n\ta = (x2 + (t * t)) / a;\n\tw = CMPLXF(w, 0.25L * logl(a));\n\treturn w;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/complex/ccos.c",
    "content": "#include \"complex_impl.h\"\n\n/* cos(z) = cosh(i z) */\n\ndouble complex ccos(double complex z)\n{\n\treturn ccosh(CMPLX(-cimag(z), creal(z)));\n}\n"
  },
  {
    "path": "user.libc/src/complex/ccosf.c",
    "content": "#include \"complex_impl.h\"\n\nfloat complex ccosf(float complex z)\n{\n\treturn ccoshf(CMPLXF(-cimagf(z), crealf(z)));\n}\n"
  },
  {
    "path": "user.libc/src/complex/ccosh.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_ccosh.c */\n/*-\n * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice unmodified, this list of conditions, and the following\n *    disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n/*\n * Hyperbolic cosine of a complex argument z = x + i y.\n *\n * cosh(z) = cosh(x+iy)\n *         = cosh(x) cos(y) + i sinh(x) sin(y).\n *\n * Exceptional values are noted in the comments within the source code.\n * These values and the return value were taken from n1124.pdf.\n */\n\n#include \"complex_impl.h\"\n\nstatic const double huge = 0x1p1023;\n\ndouble complex ccosh(double complex z)\n{\n\tdouble x, y, h;\n\tint32_t hx, hy, ix, iy, lx, ly;\n\n\tx = creal(z);\n\ty = cimag(z);\n\n\tEXTRACT_WORDS(hx, lx, x);\n\tEXTRACT_WORDS(hy, ly, y);\n\n\tix = 0x7fffffff & hx;\n\tiy = 0x7fffffff & hy;\n\n\t/* Handle the nearly-non-exceptional cases where x and y are finite. */\n\tif (ix < 0x7ff00000 && iy < 0x7ff00000) {\n\t\tif ((iy | ly) == 0)\n\t\t\treturn CMPLX(cosh(x), x * y);\n\t\tif (ix < 0x40360000)    /* small x: normal case */\n\t\t\treturn CMPLX(cosh(x) * cos(y), sinh(x) * sin(y));\n\n\t\t/* |x| >= 22, so cosh(x) ~= exp(|x|) */\n\t\tif (ix < 0x40862e42) {\n\t\t\t/* x < 710: exp(|x|) won't overflow */\n\t\t\th = exp(fabs(x)) * 0.5;\n\t\t\treturn CMPLX(h * cos(y), copysign(h, x) * sin(y));\n\t\t} else if (ix < 0x4096bbaa) {\n\t\t\t/* x < 1455: scale to avoid overflow */\n\t\t\tz = __ldexp_cexp(CMPLX(fabs(x), y), -1);\n\t\t\treturn CMPLX(creal(z), cimag(z) * copysign(1, x));\n\t\t} else {\n\t\t\t/* x >= 1455: the result always overflows */\n\t\t\th = huge * x;\n\t\t\treturn CMPLX(h * h * cos(y), h * sin(y));\n\t\t}\n\t}\n\n\t/*\n\t * cosh(+-0 +- I Inf) = dNaN + I sign(d(+-0, dNaN))0.\n\t * The sign of 0 in the result is unspecified.  Choice = normally\n\t * the same as dNaN.  Raise the invalid floating-point exception.\n\t *\n\t * cosh(+-0 +- I NaN) = d(NaN) + I sign(d(+-0, NaN))0.\n\t * The sign of 0 in the result is unspecified.  Choice = normally\n\t * the same as d(NaN).\n\t */\n\tif ((ix | lx) == 0 && iy >= 0x7ff00000)\n\t\treturn CMPLX(y - y, copysign(0, x * (y - y)));\n\n\t/*\n\t * cosh(+-Inf +- I 0) = +Inf + I (+-)(+-)0.\n\t *\n\t * cosh(NaN +- I 0)   = d(NaN) + I sign(d(NaN, +-0))0.\n\t * The sign of 0 in the result is unspecified.\n\t */\n\tif ((iy | ly) == 0 && ix >= 0x7ff00000) {\n\t\tif (((hx & 0xfffff) | lx) == 0)\n\t\t\treturn CMPLX(x * x, copysign(0, x) * y);\n\t\treturn CMPLX(x * x, copysign(0, (x + x) * y));\n\t}\n\n\t/*\n\t * cosh(x +- I Inf) = dNaN + I dNaN.\n\t * Raise the invalid floating-point exception for finite nonzero x.\n\t *\n\t * cosh(x + I NaN) = d(NaN) + I d(NaN).\n\t * Optionally raises the invalid floating-point exception for finite\n\t * nonzero x.  Choice = don't raise (except for signaling NaNs).\n\t */\n\tif (ix < 0x7ff00000 && iy >= 0x7ff00000)\n\t\treturn CMPLX(y - y, x * (y - y));\n\n\t/*\n\t * cosh(+-Inf + I NaN)  = +Inf + I d(NaN).\n\t *\n\t * cosh(+-Inf +- I Inf) = +Inf + I dNaN.\n\t * The sign of Inf in the result is unspecified.  Choice = always +.\n\t * Raise the invalid floating-point exception.\n\t *\n\t * cosh(+-Inf + I y)   = +Inf cos(y) +- I Inf sin(y)\n\t */\n\tif (ix >= 0x7ff00000 && ((hx & 0xfffff) | lx) == 0) {\n\t\tif (iy >= 0x7ff00000)\n\t\t\treturn CMPLX(x * x, x * (y - y));\n\t\treturn CMPLX((x * x) * cos(y), x * sin(y));\n\t}\n\n\t/*\n\t * cosh(NaN + I NaN)  = d(NaN) + I d(NaN).\n\t *\n\t * cosh(NaN +- I Inf) = d(NaN) + I d(NaN).\n\t * Optionally raises the invalid floating-point exception.\n\t * Choice = raise.\n\t *\n\t * cosh(NaN + I y)    = d(NaN) + I d(NaN).\n\t * Optionally raises the invalid floating-point exception for finite\n\t * nonzero y.  Choice = don't raise (except for signaling NaNs).\n\t */\n\treturn CMPLX((x * x) * (y - y), (x + x) * (y - y));\n}\n"
  },
  {
    "path": "user.libc/src/complex/ccoshf.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_ccoshf.c */\n/*-\n * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice unmodified, this list of conditions, and the following\n *    disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n/*\n * Hyperbolic cosine of a complex argument.  See s_ccosh.c for details.\n */\n\n#include \"complex_impl.h\"\n\nstatic const float huge = 0x1p127;\n\nfloat complex ccoshf(float complex z)\n{\n\tfloat x, y, h;\n\tint32_t hx, hy, ix, iy;\n\n\tx = crealf(z);\n\ty = cimagf(z);\n\n\tGET_FLOAT_WORD(hx, x);\n\tGET_FLOAT_WORD(hy, y);\n\n\tix = 0x7fffffff & hx;\n\tiy = 0x7fffffff & hy;\n\n\tif (ix < 0x7f800000 && iy < 0x7f800000) {\n\t\tif (iy == 0)\n\t\t\treturn CMPLXF(coshf(x), x * y);\n\t\tif (ix < 0x41100000)    /* small x: normal case */\n\t\t\treturn CMPLXF(coshf(x) * cosf(y), sinhf(x) * sinf(y));\n\n\t\t/* |x| >= 9, so cosh(x) ~= exp(|x|) */\n\t\tif (ix < 0x42b17218) {\n\t\t\t/* x < 88.7: expf(|x|) won't overflow */\n\t\t\th = expf(fabsf(x)) * 0.5f;\n\t\t\treturn CMPLXF(h * cosf(y), copysignf(h, x) * sinf(y));\n\t\t} else if (ix < 0x4340b1e7) {\n\t\t\t/* x < 192.7: scale to avoid overflow */\n\t\t\tz = __ldexp_cexpf(CMPLXF(fabsf(x), y), -1);\n\t\t\treturn CMPLXF(crealf(z), cimagf(z) * copysignf(1, x));\n\t\t} else {\n\t\t\t/* x >= 192.7: the result always overflows */\n\t\t\th = huge * x;\n\t\t\treturn CMPLXF(h * h * cosf(y), h * sinf(y));\n\t\t}\n\t}\n\n\tif (ix == 0 && iy >= 0x7f800000)\n\t\treturn CMPLXF(y - y, copysignf(0, x * (y - y)));\n\n\tif (iy == 0 && ix >= 0x7f800000) {\n\t\tif ((hx & 0x7fffff) == 0)\n\t\t\treturn CMPLXF(x * x, copysignf(0, x) * y);\n\t\treturn CMPLXF(x * x, copysignf(0, (x + x) * y));\n\t}\n\n\tif (ix < 0x7f800000 && iy >= 0x7f800000)\n\t\treturn CMPLXF(y - y, x * (y - y));\n\n\tif (ix >= 0x7f800000 && (hx & 0x7fffff) == 0) {\n\t\tif (iy >= 0x7f800000)\n\t\t\treturn CMPLXF(x * x, x * (y - y));\n\t\treturn CMPLXF((x * x) * cosf(y), x * sinf(y));\n\t}\n\n\treturn CMPLXF((x * x) * (y - y), (x + x) * (y - y));\n}\n"
  },
  {
    "path": "user.libc/src/complex/ccoshl.c",
    "content": "#include \"complex_impl.h\"\n\n//FIXME\nlong double complex ccoshl(long double complex z)\n{\n\treturn ccosh(z);\n}\n"
  },
  {
    "path": "user.libc/src/complex/ccosl.c",
    "content": "#include \"complex_impl.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double complex ccosl(long double complex z)\n{\n\treturn ccos(z);\n}\n#else\nlong double complex ccosl(long double complex z)\n{\n\treturn ccoshl(CMPLXL(-cimagl(z), creall(z)));\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/complex/cexp.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_cexp.c */\n/*-\n * Copyright (c) 2011 David Schultz <das@FreeBSD.ORG>\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include \"complex_impl.h\"\n\nstatic const uint32_t\nexp_ovfl  = 0x40862e42,  /* high bits of MAX_EXP * ln2 ~= 710 */\ncexp_ovfl = 0x4096b8e4;  /* (MAX_EXP - MIN_DENORM_EXP) * ln2 */\n\ndouble complex cexp(double complex z)\n{\n\tdouble x, y, exp_x;\n\tuint32_t hx, hy, lx, ly;\n\n\tx = creal(z);\n\ty = cimag(z);\n\n\tEXTRACT_WORDS(hy, ly, y);\n\thy &= 0x7fffffff;\n\n\t/* cexp(x + I 0) = exp(x) + I 0 */\n\tif ((hy | ly) == 0)\n\t\treturn CMPLX(exp(x), y);\n\tEXTRACT_WORDS(hx, lx, x);\n\t/* cexp(0 + I y) = cos(y) + I sin(y) */\n\tif (((hx & 0x7fffffff) | lx) == 0)\n\t\treturn CMPLX(cos(y), sin(y));\n\n\tif (hy >= 0x7ff00000) {\n\t\tif (lx != 0 || (hx & 0x7fffffff) != 0x7ff00000) {\n\t\t\t/* cexp(finite|NaN +- I Inf|NaN) = NaN + I NaN */\n\t\t\treturn CMPLX(y - y, y - y);\n\t\t} else if (hx & 0x80000000) {\n\t\t\t/* cexp(-Inf +- I Inf|NaN) = 0 + I 0 */\n\t\t\treturn CMPLX(0.0, 0.0);\n\t\t} else {\n\t\t\t/* cexp(+Inf +- I Inf|NaN) = Inf + I NaN */\n\t\t\treturn CMPLX(x, y - y);\n\t\t}\n\t}\n\n\tif (hx >= exp_ovfl && hx <= cexp_ovfl) {\n\t\t/*\n\t\t * x is between 709.7 and 1454.3, so we must scale to avoid\n\t\t * overflow in exp(x).\n\t\t */\n\t\treturn __ldexp_cexp(z, 0);\n\t} else {\n\t\t/*\n\t\t * Cases covered here:\n\t\t *  -  x < exp_ovfl and exp(x) won't overflow (common case)\n\t\t *  -  x > cexp_ovfl, so exp(x) * s overflows for all s > 0\n\t\t *  -  x = +-Inf (generated by exp())\n\t\t *  -  x = NaN (spurious inexact exception from y)\n\t\t */\n\t\texp_x = exp(x);\n\t\treturn CMPLX(exp_x * cos(y), exp_x * sin(y));\n\t}\n}\n"
  },
  {
    "path": "user.libc/src/complex/cexpf.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_cexpf.c */\n/*-\n * Copyright (c) 2011 David Schultz <das@FreeBSD.ORG>\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include \"complex_impl.h\"\n\nstatic const uint32_t\nexp_ovfl  = 0x42b17218,  /* MAX_EXP * ln2 ~= 88.722839355 */\ncexp_ovfl = 0x43400074;  /* (MAX_EXP - MIN_DENORM_EXP) * ln2 */\n\nfloat complex cexpf(float complex z)\n{\n\tfloat x, y, exp_x;\n\tuint32_t hx, hy;\n\n\tx = crealf(z);\n\ty = cimagf(z);\n\n\tGET_FLOAT_WORD(hy, y);\n\thy &= 0x7fffffff;\n\n\t/* cexp(x + I 0) = exp(x) + I 0 */\n\tif (hy == 0)\n\t\treturn CMPLXF(expf(x), y);\n\tGET_FLOAT_WORD(hx, x);\n\t/* cexp(0 + I y) = cos(y) + I sin(y) */\n\tif ((hx & 0x7fffffff) == 0)\n\t\treturn CMPLXF(cosf(y), sinf(y));\n\n\tif (hy >= 0x7f800000) {\n\t\tif ((hx & 0x7fffffff) != 0x7f800000) {\n\t\t\t/* cexp(finite|NaN +- I Inf|NaN) = NaN + I NaN */\n\t\t\treturn CMPLXF(y - y, y - y);\n\t\t} else if (hx & 0x80000000) {\n\t\t\t/* cexp(-Inf +- I Inf|NaN) = 0 + I 0 */\n\t\t\treturn CMPLXF(0.0, 0.0);\n\t\t} else {\n\t\t\t/* cexp(+Inf +- I Inf|NaN) = Inf + I NaN */\n\t\t\treturn CMPLXF(x, y - y);\n\t\t}\n\t}\n\n\tif (hx >= exp_ovfl && hx <= cexp_ovfl) {\n\t\t/*\n\t\t * x is between 88.7 and 192, so we must scale to avoid\n\t\t * overflow in expf(x).\n\t\t */\n\t\treturn __ldexp_cexpf(z, 0);\n\t} else {\n\t\t/*\n\t\t * Cases covered here:\n\t\t *  -  x < exp_ovfl and exp(x) won't overflow (common case)\n\t\t *  -  x > cexp_ovfl, so exp(x) * s overflows for all s > 0\n\t\t *  -  x = +-Inf (generated by exp())\n\t\t *  -  x = NaN (spurious inexact exception from y)\n\t\t */\n\t\texp_x = expf(x);\n\t\treturn CMPLXF(exp_x * cosf(y), exp_x * sinf(y));\n\t}\n}\n"
  },
  {
    "path": "user.libc/src/complex/cexpl.c",
    "content": "#include \"complex_impl.h\"\n\n//FIXME\nlong double complex cexpl(long double complex z)\n{\n\treturn cexp(z);\n}\n"
  },
  {
    "path": "user.libc/src/complex/cimag.c",
    "content": "#include \"complex_impl.h\"\n\ndouble (cimag)(double complex z)\n{\n\treturn cimag(z);\n}\n"
  },
  {
    "path": "user.libc/src/complex/cimagf.c",
    "content": "#include \"complex_impl.h\"\n\nfloat (cimagf)(float complex z)\n{\n\treturn cimagf(z);\n}\n"
  },
  {
    "path": "user.libc/src/complex/cimagl.c",
    "content": "#include \"complex_impl.h\"\n\nlong double (cimagl)(long double complex z)\n{\n\treturn cimagl(z);\n}\n"
  },
  {
    "path": "user.libc/src/complex/clog.c",
    "content": "#include \"complex_impl.h\"\n\n// FIXME\n\n/* log(z) = log(|z|) + i arg(z) */\n\ndouble complex clog(double complex z)\n{\n\tdouble r, phi;\n\n\tr = cabs(z);\n\tphi = carg(z);\n\treturn CMPLX(log(r), phi);\n}\n"
  },
  {
    "path": "user.libc/src/complex/clogf.c",
    "content": "#include \"complex_impl.h\"\n\n// FIXME\n\nfloat complex clogf(float complex z)\n{\n\tfloat r, phi;\n\n\tr = cabsf(z);\n\tphi = cargf(z);\n\treturn CMPLXF(logf(r), phi);\n}\n"
  },
  {
    "path": "user.libc/src/complex/clogl.c",
    "content": "#include \"complex_impl.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double complex clogl(long double complex z)\n{\n\treturn clog(z);\n}\n#else\n// FIXME\nlong double complex clogl(long double complex z)\n{\n\tlong double r, phi;\n\n\tr = cabsl(z);\n\tphi = cargl(z);\n\treturn CMPLXL(logl(r), phi);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/complex/conj.c",
    "content": "#include \"complex_impl.h\"\n\ndouble complex conj(double complex z)\n{\n\treturn CMPLX(creal(z), -cimag(z));\n}\n"
  },
  {
    "path": "user.libc/src/complex/conjf.c",
    "content": "#include \"complex_impl.h\"\n\nfloat complex conjf(float complex z)\n{\n\treturn CMPLXF(crealf(z), -cimagf(z));\n}\n"
  },
  {
    "path": "user.libc/src/complex/conjl.c",
    "content": "#include \"complex_impl.h\"\n\nlong double complex conjl(long double complex z)\n{\n\treturn CMPLXL(creall(z), -cimagl(z));\n}\n"
  },
  {
    "path": "user.libc/src/complex/cpow.c",
    "content": "#include \"complex_impl.h\"\n\n/* pow(z, c) = exp(c log(z)), See C99 G.6.4.1 */\n\ndouble complex cpow(double complex z, double complex c)\n{\n\treturn cexp(c * clog(z));\n}\n"
  },
  {
    "path": "user.libc/src/complex/cpowf.c",
    "content": "#include \"complex_impl.h\"\n\nfloat complex cpowf(float complex z, float complex c)\n{\n\treturn cexpf(c * clogf(z));\n}\n"
  },
  {
    "path": "user.libc/src/complex/cpowl.c",
    "content": "#include \"complex_impl.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double complex cpowl(long double complex z, long double complex c)\n{\n\treturn cpow(z, c);\n}\n#else\nlong double complex cpowl(long double complex z, long double complex c)\n{\n\treturn cexpl(c * clogl(z));\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/complex/cproj.c",
    "content": "#include \"complex_impl.h\"\n\ndouble complex cproj(double complex z)\n{\n\tif (isinf(creal(z)) || isinf(cimag(z)))\n\t\treturn CMPLX(INFINITY, copysign(0.0, creal(z)));\n\treturn z;\n}\n"
  },
  {
    "path": "user.libc/src/complex/cprojf.c",
    "content": "#include \"complex_impl.h\"\n\nfloat complex cprojf(float complex z)\n{\n\tif (isinf(crealf(z)) || isinf(cimagf(z)))\n\t\treturn CMPLXF(INFINITY, copysignf(0.0, crealf(z)));\n\treturn z;\n}\n"
  },
  {
    "path": "user.libc/src/complex/cprojl.c",
    "content": "#include \"complex_impl.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double complex cprojl(long double complex z)\n{\n\treturn cproj(z);\n}\n#else\nlong double complex cprojl(long double complex z)\n{\n\tif (isinf(creall(z)) || isinf(cimagl(z)))\n\t\treturn CMPLXL(INFINITY, copysignl(0.0, creall(z)));\n\treturn z;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/complex/creal.c",
    "content": "#include <complex.h>\n\ndouble (creal)(double complex z)\n{\n\treturn creal(z);\n}\n"
  },
  {
    "path": "user.libc/src/complex/crealf.c",
    "content": "#include <complex.h>\n\nfloat (crealf)(float complex z)\n{\n\treturn crealf(z);\n}\n"
  },
  {
    "path": "user.libc/src/complex/creall.c",
    "content": "#include <complex.h>\n\nlong double (creall)(long double complex z)\n{\n\treturn creall(z);\n}\n"
  },
  {
    "path": "user.libc/src/complex/csin.c",
    "content": "#include \"complex_impl.h\"\n\n/* sin(z) = -i sinh(i z) */\n\ndouble complex csin(double complex z)\n{\n\tz = csinh(CMPLX(-cimag(z), creal(z)));\n\treturn CMPLX(cimag(z), -creal(z));\n}\n"
  },
  {
    "path": "user.libc/src/complex/csinf.c",
    "content": "#include \"complex_impl.h\"\n\nfloat complex csinf(float complex z)\n{\n\tz = csinhf(CMPLXF(-cimagf(z), crealf(z)));\n\treturn CMPLXF(cimagf(z), -crealf(z));\n}\n"
  },
  {
    "path": "user.libc/src/complex/csinh.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_csinh.c */\n/*-\n * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice unmodified, this list of conditions, and the following\n *    disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n/*\n * Hyperbolic sine of a complex argument z = x + i y.\n *\n * sinh(z) = sinh(x+iy)\n *         = sinh(x) cos(y) + i cosh(x) sin(y).\n *\n * Exceptional values are noted in the comments within the source code.\n * These values and the return value were taken from n1124.pdf.\n */\n\n#include \"complex_impl.h\"\n\nstatic const double huge = 0x1p1023;\n\ndouble complex csinh(double complex z)\n{\n\tdouble x, y, h;\n\tint32_t hx, hy, ix, iy, lx, ly;\n\n\tx = creal(z);\n\ty = cimag(z);\n\n\tEXTRACT_WORDS(hx, lx, x);\n\tEXTRACT_WORDS(hy, ly, y);\n\n\tix = 0x7fffffff & hx;\n\tiy = 0x7fffffff & hy;\n\n\t/* Handle the nearly-non-exceptional cases where x and y are finite. */\n\tif (ix < 0x7ff00000 && iy < 0x7ff00000) {\n\t\tif ((iy | ly) == 0)\n\t\t\treturn CMPLX(sinh(x), y);\n\t\tif (ix < 0x40360000)    /* small x: normal case */\n\t\t\treturn CMPLX(sinh(x) * cos(y), cosh(x) * sin(y));\n\n\t\t/* |x| >= 22, so cosh(x) ~= exp(|x|) */\n\t\tif (ix < 0x40862e42) {\n\t\t\t/* x < 710: exp(|x|) won't overflow */\n\t\t\th = exp(fabs(x)) * 0.5;\n\t\t\treturn CMPLX(copysign(h, x) * cos(y), h * sin(y));\n\t\t} else if (ix < 0x4096bbaa) {\n\t\t\t/* x < 1455: scale to avoid overflow */\n\t\t\tz = __ldexp_cexp(CMPLX(fabs(x), y), -1);\n\t\t\treturn CMPLX(creal(z) * copysign(1, x), cimag(z));\n\t\t} else {\n\t\t\t/* x >= 1455: the result always overflows */\n\t\t\th = huge * x;\n\t\t\treturn CMPLX(h * cos(y), h * h * sin(y));\n\t\t}\n\t}\n\n\t/*\n\t * sinh(+-0 +- I Inf) = sign(d(+-0, dNaN))0 + I dNaN.\n\t * The sign of 0 in the result is unspecified.  Choice = normally\n\t * the same as dNaN.  Raise the invalid floating-point exception.\n\t *\n\t * sinh(+-0 +- I NaN) = sign(d(+-0, NaN))0 + I d(NaN).\n\t * The sign of 0 in the result is unspecified.  Choice = normally\n\t * the same as d(NaN).\n\t */\n\tif ((ix | lx) == 0 && iy >= 0x7ff00000)\n\t\treturn CMPLX(copysign(0, x * (y - y)), y - y);\n\n\t/*\n\t * sinh(+-Inf +- I 0) = +-Inf + I +-0.\n\t *\n\t * sinh(NaN +- I 0)   = d(NaN) + I +-0.\n\t */\n\tif ((iy | ly) == 0 && ix >= 0x7ff00000) {\n\t\tif (((hx & 0xfffff) | lx) == 0)\n\t\t\treturn CMPLX(x, y);\n\t\treturn CMPLX(x, copysign(0, y));\n\t}\n\n\t/*\n\t * sinh(x +- I Inf) = dNaN + I dNaN.\n\t * Raise the invalid floating-point exception for finite nonzero x.\n\t *\n\t * sinh(x + I NaN) = d(NaN) + I d(NaN).\n\t * Optionally raises the invalid floating-point exception for finite\n\t * nonzero x.  Choice = don't raise (except for signaling NaNs).\n\t */\n\tif (ix < 0x7ff00000 && iy >= 0x7ff00000)\n\t\treturn CMPLX(y - y, x * (y - y));\n\n\t/*\n\t * sinh(+-Inf + I NaN)  = +-Inf + I d(NaN).\n\t * The sign of Inf in the result is unspecified.  Choice = normally\n\t * the same as d(NaN).\n\t *\n\t * sinh(+-Inf +- I Inf) = +Inf + I dNaN.\n\t * The sign of Inf in the result is unspecified.  Choice = always +.\n\t * Raise the invalid floating-point exception.\n\t *\n\t * sinh(+-Inf + I y)   = +-Inf cos(y) + I Inf sin(y)\n\t */\n\tif (ix >= 0x7ff00000 && ((hx & 0xfffff) | lx) == 0) {\n\t\tif (iy >= 0x7ff00000)\n\t\t\treturn CMPLX(x * x, x * (y - y));\n\t\treturn CMPLX(x * cos(y), INFINITY * sin(y));\n\t}\n\n\t/*\n\t * sinh(NaN + I NaN)  = d(NaN) + I d(NaN).\n\t *\n\t * sinh(NaN +- I Inf) = d(NaN) + I d(NaN).\n\t * Optionally raises the invalid floating-point exception.\n\t * Choice = raise.\n\t *\n\t * sinh(NaN + I y)    = d(NaN) + I d(NaN).\n\t * Optionally raises the invalid floating-point exception for finite\n\t * nonzero y.  Choice = don't raise (except for signaling NaNs).\n\t */\n\treturn CMPLX((x * x) * (y - y), (x + x) * (y - y));\n}\n"
  },
  {
    "path": "user.libc/src/complex/csinhf.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_csinhf.c */\n/*-\n * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice unmodified, this list of conditions, and the following\n *    disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n/*\n * Hyperbolic sine of a complex argument z.  See s_csinh.c for details.\n */\n\n#include \"complex_impl.h\"\n\nstatic const float huge = 0x1p127;\n\nfloat complex csinhf(float complex z)\n{\n\tfloat x, y, h;\n\tint32_t hx, hy, ix, iy;\n\n\tx = crealf(z);\n\ty = cimagf(z);\n\n\tGET_FLOAT_WORD(hx, x);\n\tGET_FLOAT_WORD(hy, y);\n\n\tix = 0x7fffffff & hx;\n\tiy = 0x7fffffff & hy;\n\n\tif (ix < 0x7f800000 && iy < 0x7f800000) {\n\t\tif (iy == 0)\n\t\t\treturn CMPLXF(sinhf(x), y);\n\t\tif (ix < 0x41100000)    /* small x: normal case */\n\t\t\treturn CMPLXF(sinhf(x) * cosf(y), coshf(x) * sinf(y));\n\n\t\t/* |x| >= 9, so cosh(x) ~= exp(|x|) */\n\t\tif (ix < 0x42b17218) {\n\t\t\t/* x < 88.7: expf(|x|) won't overflow */\n\t\t\th = expf(fabsf(x)) * 0.5f;\n\t\t\treturn CMPLXF(copysignf(h, x) * cosf(y), h * sinf(y));\n\t\t} else if (ix < 0x4340b1e7) {\n\t\t\t/* x < 192.7: scale to avoid overflow */\n\t\t\tz = __ldexp_cexpf(CMPLXF(fabsf(x), y), -1);\n\t\t\treturn CMPLXF(crealf(z) * copysignf(1, x), cimagf(z));\n\t\t} else {\n\t\t\t/* x >= 192.7: the result always overflows */\n\t\t\th = huge * x;\n\t\t\treturn CMPLXF(h * cosf(y), h * h * sinf(y));\n\t\t}\n\t}\n\n\tif (ix == 0 && iy >= 0x7f800000)\n\t\treturn CMPLXF(copysignf(0, x * (y - y)), y - y);\n\n\tif (iy == 0 && ix >= 0x7f800000) {\n\t\tif ((hx & 0x7fffff) == 0)\n\t\t\treturn CMPLXF(x, y);\n\t\treturn CMPLXF(x, copysignf(0, y));\n\t}\n\n\tif (ix < 0x7f800000 && iy >= 0x7f800000)\n\t\treturn CMPLXF(y - y, x * (y - y));\n\n\tif (ix >= 0x7f800000 && (hx & 0x7fffff) == 0) {\n\t\tif (iy >= 0x7f800000)\n\t\t\treturn CMPLXF(x * x, x * (y - y));\n\t\treturn CMPLXF(x * cosf(y), INFINITY * sinf(y));\n\t}\n\n\treturn CMPLXF((x * x) * (y - y), (x + x) * (y - y));\n}\n"
  },
  {
    "path": "user.libc/src/complex/csinhl.c",
    "content": "#include \"complex_impl.h\"\n\n//FIXME\nlong double complex csinhl(long double complex z)\n{\n\treturn csinh(z);\n}\n"
  },
  {
    "path": "user.libc/src/complex/csinl.c",
    "content": "#include \"complex_impl.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double complex csinl(long double complex z)\n{\n\treturn csin(z);\n}\n#else\nlong double complex csinl(long double complex z)\n{\n\tz = csinhl(CMPLXL(-cimagl(z), creall(z)));\n\treturn CMPLXL(cimagl(z), -creall(z));\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/complex/csqrt.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_csqrt.c */\n/*-\n * Copyright (c) 2007 David Schultz <das@FreeBSD.ORG>\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include \"complex_impl.h\"\n\n/*\n * gcc doesn't implement complex multiplication or division correctly,\n * so we need to handle infinities specially. We turn on this pragma to\n * notify conforming c99 compilers that the fast-but-incorrect code that\n * gcc generates is acceptable, since the special cases have already been\n * handled.\n */\n#pragma STDC CX_LIMITED_RANGE ON\n\n/* We risk spurious overflow for components >= DBL_MAX / (1 + sqrt(2)). */\n#define THRESH  0x1.a827999fcef32p+1022\n\ndouble complex csqrt(double complex z)\n{\n\tdouble complex result;\n\tdouble a, b;\n\tdouble t;\n\tint scale;\n\n\ta = creal(z);\n\tb = cimag(z);\n\n\t/* Handle special cases. */\n\tif (z == 0)\n\t\treturn CMPLX(0, b);\n\tif (isinf(b))\n\t\treturn CMPLX(INFINITY, b);\n\tif (isnan(a)) {\n\t\tt = (b - b) / (b - b);  /* raise invalid if b is not a NaN */\n\t\treturn CMPLX(a, t);   /* return NaN + NaN i */\n\t}\n\tif (isinf(a)) {\n\t\t/*\n\t\t * csqrt(inf + NaN i)  = inf +  NaN i\n\t\t * csqrt(inf + y i)    = inf +  0 i\n\t\t * csqrt(-inf + NaN i) = NaN +- inf i\n\t\t * csqrt(-inf + y i)   = 0   +  inf i\n\t\t */\n\t\tif (signbit(a))\n\t\t\treturn CMPLX(fabs(b - b), copysign(a, b));\n\t\telse\n\t\t\treturn CMPLX(a, copysign(b - b, b));\n\t}\n\t/*\n\t * The remaining special case (b is NaN) is handled just fine by\n\t * the normal code path below.\n\t */\n\n\t/* Scale to avoid overflow. */\n\tif (fabs(a) >= THRESH || fabs(b) >= THRESH) {\n\t\ta *= 0.25;\n\t\tb *= 0.25;\n\t\tscale = 1;\n\t} else {\n\t\tscale = 0;\n\t}\n\n\t/* Algorithm 312, CACM vol 10, Oct 1967. */\n\tif (a >= 0) {\n\t\tt = sqrt((a + hypot(a, b)) * 0.5);\n\t\tresult = CMPLX(t, b / (2 * t));\n\t} else {\n\t\tt = sqrt((-a + hypot(a, b)) * 0.5);\n\t\tresult = CMPLX(fabs(b) / (2 * t), copysign(t, b));\n\t}\n\n\t/* Rescale. */\n\tif (scale)\n\t\tresult *= 2;\n\treturn result;\n}\n"
  },
  {
    "path": "user.libc/src/complex/csqrtf.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_csqrtf.c */\n/*-\n * Copyright (c) 2007 David Schultz <das@FreeBSD.ORG>\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include \"complex_impl.h\"\n\n/*\n * gcc doesn't implement complex multiplication or division correctly,\n * so we need to handle infinities specially. We turn on this pragma to\n * notify conforming c99 compilers that the fast-but-incorrect code that\n * gcc generates is acceptable, since the special cases have already been\n * handled.\n */\n#pragma STDC CX_LIMITED_RANGE ON\n\nfloat complex csqrtf(float complex z)\n{\n\tfloat a = crealf(z), b = cimagf(z);\n\tdouble t;\n\n\t/* Handle special cases. */\n\tif (z == 0)\n\t\treturn CMPLXF(0, b);\n\tif (isinf(b))\n\t\treturn CMPLXF(INFINITY, b);\n\tif (isnan(a)) {\n\t\tt = (b - b) / (b - b);  /* raise invalid if b is not a NaN */\n\t\treturn CMPLXF(a, t);  /* return NaN + NaN i */\n\t}\n\tif (isinf(a)) {\n\t\t/*\n\t\t * csqrtf(inf + NaN i)  = inf +  NaN i\n\t\t * csqrtf(inf + y i)    = inf +  0 i\n\t\t * csqrtf(-inf + NaN i) = NaN +- inf i\n\t\t * csqrtf(-inf + y i)   = 0   +  inf i\n\t\t */\n\t\tif (signbit(a))\n\t\t\treturn CMPLXF(fabsf(b - b), copysignf(a, b));\n\t\telse\n\t\t\treturn CMPLXF(a, copysignf(b - b, b));\n\t}\n\t/*\n\t * The remaining special case (b is NaN) is handled just fine by\n\t * the normal code path below.\n\t */\n\n\t/*\n\t * We compute t in double precision to avoid overflow and to\n\t * provide correct rounding in nearly all cases.\n\t * This is Algorithm 312, CACM vol 10, Oct 1967.\n\t */\n\tif (a >= 0) {\n\t\tt = sqrt((a + hypot(a, b)) * 0.5);\n\t\treturn CMPLXF(t, b / (2.0 * t));\n\t} else {\n\t\tt = sqrt((-a + hypot(a, b)) * 0.5);\n\t\treturn CMPLXF(fabsf(b) / (2.0 * t), copysignf(t, b));\n\t}\n}\n"
  },
  {
    "path": "user.libc/src/complex/csqrtl.c",
    "content": "#include \"complex_impl.h\"\n\n//FIXME\nlong double complex csqrtl(long double complex z)\n{\n\treturn csqrt(z);\n}\n"
  },
  {
    "path": "user.libc/src/complex/ctan.c",
    "content": "#include \"complex_impl.h\"\n\n/* tan(z) = -i tanh(i z) */\n\ndouble complex ctan(double complex z)\n{\n\tz = ctanh(CMPLX(-cimag(z), creal(z)));\n\treturn CMPLX(cimag(z), -creal(z));\n}\n"
  },
  {
    "path": "user.libc/src/complex/ctanf.c",
    "content": "#include \"complex_impl.h\"\n\nfloat complex ctanf(float complex z)\n{\n\tz = ctanhf(CMPLXF(-cimagf(z), crealf(z)));\n\treturn CMPLXF(cimagf(z), -crealf(z));\n}\n"
  },
  {
    "path": "user.libc/src/complex/ctanh.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_ctanh.c */\n/*-\n * Copyright (c) 2011 David Schultz\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice unmodified, this list of conditions, and the following\n *    disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n/*\n * Hyperbolic tangent of a complex argument z = x + i y.\n *\n * The algorithm is from:\n *\n *   W. Kahan.  Branch Cuts for Complex Elementary Functions or Much\n *   Ado About Nothing's Sign Bit.  In The State of the Art in\n *   Numerical Analysis, pp. 165 ff.  Iserles and Powell, eds., 1987.\n *\n * Method:\n *\n *   Let t    = tan(x)\n *       beta = 1/cos^2(y)\n *       s    = sinh(x)\n *       rho  = cosh(x)\n *\n *   We have:\n *\n *   tanh(z) = sinh(z) / cosh(z)\n *\n *             sinh(x) cos(y) + i cosh(x) sin(y)\n *           = ---------------------------------\n *             cosh(x) cos(y) + i sinh(x) sin(y)\n *\n *             cosh(x) sinh(x) / cos^2(y) + i tan(y)\n *           = -------------------------------------\n *                    1 + sinh^2(x) / cos^2(y)\n *\n *             beta rho s + i t\n *           = ----------------\n *               1 + beta s^2\n *\n * Modifications:\n *\n *   I omitted the original algorithm's handling of overflow in tan(x) after\n *   verifying with nearpi.c that this can't happen in IEEE single or double\n *   precision.  I also handle large x differently.\n */\n\n#include \"complex_impl.h\"\n\ndouble complex ctanh(double complex z)\n{\n\tdouble x, y;\n\tdouble t, beta, s, rho, denom;\n\tuint32_t hx, ix, lx;\n\n\tx = creal(z);\n\ty = cimag(z);\n\n\tEXTRACT_WORDS(hx, lx, x);\n\tix = hx & 0x7fffffff;\n\n\t/*\n\t * ctanh(NaN + i 0) = NaN + i 0\n\t *\n\t * ctanh(NaN + i y) = NaN + i NaN               for y != 0\n\t *\n\t * The imaginary part has the sign of x*sin(2*y), but there's no\n\t * special effort to get this right.\n\t *\n\t * ctanh(+-Inf +- i Inf) = +-1 +- 0\n\t *\n\t * ctanh(+-Inf + i y) = +-1 + 0 sin(2y)         for y finite\n\t *\n\t * The imaginary part of the sign is unspecified.  This special\n\t * case is only needed to avoid a spurious invalid exception when\n\t * y is infinite.\n\t */\n\tif (ix >= 0x7ff00000) {\n\t\tif ((ix & 0xfffff) | lx)        /* x is NaN */\n\t\t\treturn CMPLX(x, (y == 0 ? y : x * y));\n\t\tSET_HIGH_WORD(x, hx - 0x40000000);      /* x = copysign(1, x) */\n\t\treturn CMPLX(x, copysign(0, isinf(y) ? y : sin(y) * cos(y)));\n\t}\n\n\t/*\n\t * ctanh(+-0 + i NAN) = +-0 + i NaN\n\t * ctanh(+-0 +- i Inf) = +-0 + i NaN\n\t * ctanh(x + i NAN) = NaN + i NaN\n\t * ctanh(x +- i Inf) = NaN + i NaN\n\t */\n\tif (!isfinite(y))\n\t\treturn CMPLX(x ? y - y : x, y - y);\n\n\t/*\n\t * ctanh(+-huge + i +-y) ~= +-1 +- i 2sin(2y)/exp(2x), using the\n\t * approximation sinh^2(huge) ~= exp(2*huge) / 4.\n\t * We use a modified formula to avoid spurious overflow.\n\t */\n\tif (ix >= 0x40360000) { /* x >= 22 */\n\t\tdouble exp_mx = exp(-fabs(x));\n\t\treturn CMPLX(copysign(1, x), 4 * sin(y) * cos(y) * exp_mx * exp_mx);\n\t}\n\n\t/* Kahan's algorithm */\n\tt = tan(y);\n\tbeta = 1.0 + t * t;     /* = 1 / cos^2(y) */\n\ts = sinh(x);\n\trho = sqrt(1 + s * s);  /* = cosh(x) */\n\tdenom = 1 + beta * s * s;\n\treturn CMPLX((beta * rho * s) / denom, t / denom);\n}\n"
  },
  {
    "path": "user.libc/src/complex/ctanhf.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_ctanhf.c */\n/*-\n * Copyright (c) 2011 David Schultz\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice unmodified, this list of conditions, and the following\n *    disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n/*\n * Hyperbolic tangent of a complex argument z.  See s_ctanh.c for details.\n */\n\n#include \"complex_impl.h\"\n\nfloat complex ctanhf(float complex z)\n{\n\tfloat x, y;\n\tfloat t, beta, s, rho, denom;\n\tuint32_t hx, ix;\n\n\tx = crealf(z);\n\ty = cimagf(z);\n\n\tGET_FLOAT_WORD(hx, x);\n\tix = hx & 0x7fffffff;\n\n\tif (ix >= 0x7f800000) {\n\t\tif (ix & 0x7fffff)\n\t\t\treturn CMPLXF(x, (y == 0 ? y : x * y));\n\t\tSET_FLOAT_WORD(x, hx - 0x40000000);\n\t\treturn CMPLXF(x, copysignf(0, isinf(y) ? y : sinf(y) * cosf(y)));\n\t}\n\n\tif (!isfinite(y))\n\t\treturn CMPLXF(ix ? y - y : x, y - y);\n\n\tif (ix >= 0x41300000) { /* x >= 11 */\n\t\tfloat exp_mx = expf(-fabsf(x));\n\t\treturn CMPLXF(copysignf(1, x), 4 * sinf(y) * cosf(y) * exp_mx * exp_mx);\n\t}\n\n\tt = tanf(y);\n\tbeta = 1.0 + t * t;\n\ts = sinhf(x);\n\trho = sqrtf(1 + s * s);\n\tdenom = 1 + beta * s * s;\n\treturn CMPLXF((beta * rho * s) / denom, t / denom);\n}\n"
  },
  {
    "path": "user.libc/src/complex/ctanhl.c",
    "content": "#include \"complex_impl.h\"\n\n//FIXME\nlong double complex ctanhl(long double complex z)\n{\n\treturn ctanh(z);\n}\n"
  },
  {
    "path": "user.libc/src/complex/ctanl.c",
    "content": "#include \"complex_impl.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double complex ctanl(long double complex z)\n{\n\treturn ctan(z);\n}\n#else\nlong double complex ctanl(long double complex z)\n{\n\tz = ctanhl(CMPLXL(-cimagl(z), creall(z)));\n\treturn CMPLXL(cimagl(z), -creall(z));\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/crypt/crypt.c",
    "content": "#include <unistd.h>\n#include <crypt.h>\n\nchar *crypt(const char *key, const char *salt)\n{\n\t/* This buffer is sufficiently large for all\n\t * currently-supported hash types. It needs to be updated if\n\t * longer hashes are added. The cast to struct crypt_data * is\n\t * purely to meet the public API requirements of the crypt_r\n\t * function; the implementation of crypt_r uses the object\n\t * purely as a char buffer. */\n\tstatic char buf[128];\n\treturn __crypt_r(key, salt, (struct crypt_data *)buf);\n}\n"
  },
  {
    "path": "user.libc/src/crypt/crypt_blowfish.c",
    "content": "/* Modified by Rich Felker in for inclusion in musl libc, based on\n * Solar Designer's second size-optimized version sent to the musl\n * mailing list. */\n\n/*\n * The crypt_blowfish homepage is:\n *\n *\thttp://www.openwall.com/crypt/\n *\n * This code comes from John the Ripper password cracker, with reentrant\n * and crypt(3) interfaces added, but optimizations specific to password\n * cracking removed.\n *\n * Written by Solar Designer <solar at openwall.com> in 1998-2012.\n * No copyright is claimed, and the software is hereby placed in the public\n * domain.  In case this attempt to disclaim copyright and place the software\n * in the public domain is deemed null and void, then the software is\n * Copyright (c) 1998-2014 Solar Designer and it is hereby released to the\n * general public under the following terms:\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted.\n *\n * There's ABSOLUTELY NO WARRANTY, express or implied.\n *\n * It is my intent that you should be able to use this on your system,\n * as part of a software package, or anywhere else to improve security,\n * ensure compatibility, or for any other purpose.  I would appreciate\n * it if you give credit where it is due and keep your modifications in\n * the public domain as well, but I don't require that in order to let\n * you place this code and any modifications you make under a license\n * of your choice.\n *\n * This implementation is fully compatible with OpenBSD's bcrypt.c for prefix\n * \"$2b$\", originally by Niels Provos <provos at citi.umich.edu>, and it uses\n * some of his ideas.  The password hashing algorithm was designed by David\n * Mazieres <dm at lcs.mit.edu>.  For information on the level of\n * compatibility for bcrypt hash prefixes other than \"$2b$\", please refer to\n * the comments in BF_set_key() below and to the included crypt(3) man page.\n *\n * There's a paper on the algorithm that explains its design decisions:\n *\n *\thttp://www.usenix.org/events/usenix99/provos.html\n *\n * Some of the tricks in BF_ROUND might be inspired by Eric Young's\n * Blowfish library (I can't be sure if I would think of something if I\n * hadn't seen his code).\n */\n\n#include <string.h>\n#include <stdint.h>\n\ntypedef uint32_t BF_word;\ntypedef int32_t BF_word_signed;\n\n/* Number of Blowfish rounds, this is also hardcoded into a few places */\n#define BF_N\t\t\t\t16\n\ntypedef BF_word BF_key[BF_N + 2];\n\ntypedef union {\n\tstruct {\n\t\tBF_key P;\n\t\tBF_word S[4][0x100];\n\t} s;\n\tBF_word PS[BF_N + 2 + 4 * 0x100];\n} BF_ctx;\n\n/*\n * Magic IV for 64 Blowfish encryptions that we do at the end.\n * The string is \"OrpheanBeholderScryDoubt\" on big-endian.\n */\nstatic const BF_word BF_magic_w[6] = {\n\t0x4F727068, 0x65616E42, 0x65686F6C,\n\t0x64657253, 0x63727944, 0x6F756274\n};\n\n/*\n * P-box and S-box tables initialized with digits of Pi.\n */\nstatic const BF_ctx BF_init_state = {{\n\t{\n\t\t0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,\n\t\t0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,\n\t\t0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,\n\t\t0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,\n\t\t0x9216d5d9, 0x8979fb1b\n\t}, {\n\t\t{\n\t\t\t0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,\n\t\t\t0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,\n\t\t\t0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,\n\t\t\t0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,\n\t\t\t0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,\n\t\t\t0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,\n\t\t\t0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,\n\t\t\t0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,\n\t\t\t0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,\n\t\t\t0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,\n\t\t\t0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,\n\t\t\t0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,\n\t\t\t0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,\n\t\t\t0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,\n\t\t\t0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,\n\t\t\t0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,\n\t\t\t0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,\n\t\t\t0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,\n\t\t\t0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,\n\t\t\t0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,\n\t\t\t0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,\n\t\t\t0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,\n\t\t\t0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,\n\t\t\t0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,\n\t\t\t0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,\n\t\t\t0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,\n\t\t\t0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,\n\t\t\t0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,\n\t\t\t0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,\n\t\t\t0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,\n\t\t\t0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,\n\t\t\t0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,\n\t\t\t0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,\n\t\t\t0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,\n\t\t\t0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,\n\t\t\t0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,\n\t\t\t0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,\n\t\t\t0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,\n\t\t\t0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,\n\t\t\t0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,\n\t\t\t0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,\n\t\t\t0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,\n\t\t\t0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,\n\t\t\t0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,\n\t\t\t0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,\n\t\t\t0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,\n\t\t\t0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,\n\t\t\t0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,\n\t\t\t0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,\n\t\t\t0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,\n\t\t\t0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,\n\t\t\t0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,\n\t\t\t0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,\n\t\t\t0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,\n\t\t\t0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,\n\t\t\t0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,\n\t\t\t0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,\n\t\t\t0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,\n\t\t\t0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,\n\t\t\t0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,\n\t\t\t0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,\n\t\t\t0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,\n\t\t\t0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,\n\t\t\t0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a\n\t\t}, {\n\t\t\t0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,\n\t\t\t0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,\n\t\t\t0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,\n\t\t\t0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,\n\t\t\t0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,\n\t\t\t0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,\n\t\t\t0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,\n\t\t\t0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,\n\t\t\t0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,\n\t\t\t0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,\n\t\t\t0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,\n\t\t\t0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,\n\t\t\t0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,\n\t\t\t0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,\n\t\t\t0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,\n\t\t\t0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,\n\t\t\t0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,\n\t\t\t0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,\n\t\t\t0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,\n\t\t\t0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,\n\t\t\t0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,\n\t\t\t0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,\n\t\t\t0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,\n\t\t\t0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,\n\t\t\t0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,\n\t\t\t0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,\n\t\t\t0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,\n\t\t\t0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,\n\t\t\t0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,\n\t\t\t0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,\n\t\t\t0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,\n\t\t\t0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,\n\t\t\t0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,\n\t\t\t0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,\n\t\t\t0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,\n\t\t\t0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,\n\t\t\t0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,\n\t\t\t0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,\n\t\t\t0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,\n\t\t\t0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,\n\t\t\t0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,\n\t\t\t0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,\n\t\t\t0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,\n\t\t\t0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,\n\t\t\t0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,\n\t\t\t0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,\n\t\t\t0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,\n\t\t\t0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,\n\t\t\t0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,\n\t\t\t0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,\n\t\t\t0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,\n\t\t\t0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,\n\t\t\t0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,\n\t\t\t0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,\n\t\t\t0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,\n\t\t\t0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,\n\t\t\t0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,\n\t\t\t0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,\n\t\t\t0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,\n\t\t\t0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,\n\t\t\t0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,\n\t\t\t0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,\n\t\t\t0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,\n\t\t\t0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7\n\t\t}, {\n\t\t\t0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,\n\t\t\t0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,\n\t\t\t0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,\n\t\t\t0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,\n\t\t\t0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,\n\t\t\t0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,\n\t\t\t0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,\n\t\t\t0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,\n\t\t\t0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,\n\t\t\t0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,\n\t\t\t0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,\n\t\t\t0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,\n\t\t\t0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,\n\t\t\t0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,\n\t\t\t0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,\n\t\t\t0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,\n\t\t\t0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,\n\t\t\t0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,\n\t\t\t0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,\n\t\t\t0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,\n\t\t\t0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,\n\t\t\t0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,\n\t\t\t0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,\n\t\t\t0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,\n\t\t\t0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,\n\t\t\t0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,\n\t\t\t0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,\n\t\t\t0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,\n\t\t\t0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,\n\t\t\t0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,\n\t\t\t0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,\n\t\t\t0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,\n\t\t\t0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,\n\t\t\t0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,\n\t\t\t0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,\n\t\t\t0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,\n\t\t\t0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,\n\t\t\t0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,\n\t\t\t0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,\n\t\t\t0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,\n\t\t\t0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,\n\t\t\t0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,\n\t\t\t0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,\n\t\t\t0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,\n\t\t\t0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,\n\t\t\t0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,\n\t\t\t0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,\n\t\t\t0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,\n\t\t\t0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,\n\t\t\t0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,\n\t\t\t0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,\n\t\t\t0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,\n\t\t\t0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,\n\t\t\t0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,\n\t\t\t0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,\n\t\t\t0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,\n\t\t\t0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,\n\t\t\t0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,\n\t\t\t0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,\n\t\t\t0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,\n\t\t\t0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,\n\t\t\t0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,\n\t\t\t0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,\n\t\t\t0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0\n\t\t}, {\n\t\t\t0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,\n\t\t\t0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,\n\t\t\t0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,\n\t\t\t0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,\n\t\t\t0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,\n\t\t\t0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,\n\t\t\t0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,\n\t\t\t0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,\n\t\t\t0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,\n\t\t\t0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,\n\t\t\t0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,\n\t\t\t0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,\n\t\t\t0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,\n\t\t\t0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,\n\t\t\t0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,\n\t\t\t0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,\n\t\t\t0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,\n\t\t\t0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,\n\t\t\t0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,\n\t\t\t0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,\n\t\t\t0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,\n\t\t\t0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,\n\t\t\t0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,\n\t\t\t0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,\n\t\t\t0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,\n\t\t\t0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,\n\t\t\t0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,\n\t\t\t0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,\n\t\t\t0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,\n\t\t\t0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,\n\t\t\t0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,\n\t\t\t0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,\n\t\t\t0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,\n\t\t\t0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,\n\t\t\t0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,\n\t\t\t0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,\n\t\t\t0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,\n\t\t\t0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,\n\t\t\t0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,\n\t\t\t0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,\n\t\t\t0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,\n\t\t\t0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,\n\t\t\t0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,\n\t\t\t0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,\n\t\t\t0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,\n\t\t\t0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,\n\t\t\t0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,\n\t\t\t0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,\n\t\t\t0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,\n\t\t\t0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,\n\t\t\t0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,\n\t\t\t0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,\n\t\t\t0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,\n\t\t\t0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,\n\t\t\t0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,\n\t\t\t0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,\n\t\t\t0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,\n\t\t\t0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,\n\t\t\t0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,\n\t\t\t0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,\n\t\t\t0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,\n\t\t\t0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,\n\t\t\t0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,\n\t\t\t0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6\n\t\t}\n\t}\n}};\n\nstatic const unsigned char BF_itoa64[64 + 1] =\n\t\"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n\nstatic const unsigned char BF_atoi64[0x60] = {\n\t64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,\n\t54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,\n\t64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,\n\t17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,\n\t64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,\n\t43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64\n};\n\n#define BF_safe_atoi64(dst, src) \\\n{ \\\n\ttmp = (unsigned char)(src); \\\n\tif ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \\\n\ttmp = BF_atoi64[tmp]; \\\n\tif (tmp > 63) return -1; \\\n\t(dst) = tmp; \\\n}\n\nstatic int BF_decode(BF_word *dst, const char *src, int size)\n{\n\tunsigned char *dptr = (unsigned char *)dst;\n\tunsigned char *end = dptr + size;\n\tconst unsigned char *sptr = (const unsigned char *)src;\n\tunsigned int tmp, c1, c2, c3, c4;\n\n\tdo {\n\t\tBF_safe_atoi64(c1, *sptr++);\n\t\tBF_safe_atoi64(c2, *sptr++);\n\t\t*dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);\n\t\tif (dptr >= end) break;\n\n\t\tBF_safe_atoi64(c3, *sptr++);\n\t\t*dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);\n\t\tif (dptr >= end) break;\n\n\t\tBF_safe_atoi64(c4, *sptr++);\n\t\t*dptr++ = ((c3 & 0x03) << 6) | c4;\n\t} while (dptr < end);\n\n\treturn 0;\n}\n\nstatic void BF_encode(char *dst, const BF_word *src, int size)\n{\n\tconst unsigned char *sptr = (const unsigned char *)src;\n\tconst unsigned char *end = sptr + size;\n\tunsigned char *dptr = (unsigned char *)dst;\n\tunsigned int c1, c2;\n\n\tdo {\n\t\tc1 = *sptr++;\n\t\t*dptr++ = BF_itoa64[c1 >> 2];\n\t\tc1 = (c1 & 0x03) << 4;\n\t\tif (sptr >= end) {\n\t\t\t*dptr++ = BF_itoa64[c1];\n\t\t\tbreak;\n\t\t}\n\n\t\tc2 = *sptr++;\n\t\tc1 |= c2 >> 4;\n\t\t*dptr++ = BF_itoa64[c1];\n\t\tc1 = (c2 & 0x0f) << 2;\n\t\tif (sptr >= end) {\n\t\t\t*dptr++ = BF_itoa64[c1];\n\t\t\tbreak;\n\t\t}\n\n\t\tc2 = *sptr++;\n\t\tc1 |= c2 >> 6;\n\t\t*dptr++ = BF_itoa64[c1];\n\t\t*dptr++ = BF_itoa64[c2 & 0x3f];\n\t} while (sptr < end);\n}\n\nstatic void BF_swap(BF_word *x, int count)\n{\n\tif ((union { int i; char c; }){1}.c)\n\tdo {\n\t\tBF_word tmp = *x;\n\t\ttmp = (tmp << 16) | (tmp >> 16);\n\t\t*x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);\n\t} while (--count);\n}\n\n#define BF_ROUND(L, R, N) \\\n\ttmp1 = L & 0xFF; \\\n\ttmp2 = L >> 8; \\\n\ttmp2 &= 0xFF; \\\n\ttmp3 = L >> 16; \\\n\ttmp3 &= 0xFF; \\\n\ttmp4 = L >> 24; \\\n\ttmp1 = ctx->s.S[3][tmp1]; \\\n\ttmp2 = ctx->s.S[2][tmp2]; \\\n\ttmp3 = ctx->s.S[1][tmp3]; \\\n\ttmp3 += ctx->s.S[0][tmp4]; \\\n\ttmp3 ^= tmp2; \\\n\tR ^= ctx->s.P[N + 1]; \\\n\ttmp3 += tmp1; \\\n\tR ^= tmp3;\n\nstatic BF_word BF_encrypt(BF_ctx *ctx,\n    BF_word L, BF_word R,\n    BF_word *start, BF_word *end)\n{\n\tBF_word tmp1, tmp2, tmp3, tmp4;\n\tBF_word *ptr = start;\n\n\tdo {\n\t\tL ^= ctx->s.P[0];\n#if 0\n\t\tBF_ROUND(L, R, 0);\n\t\tBF_ROUND(R, L, 1);\n\t\tBF_ROUND(L, R, 2);\n\t\tBF_ROUND(R, L, 3);\n\t\tBF_ROUND(L, R, 4);\n\t\tBF_ROUND(R, L, 5);\n\t\tBF_ROUND(L, R, 6);\n\t\tBF_ROUND(R, L, 7);\n\t\tBF_ROUND(L, R, 8);\n\t\tBF_ROUND(R, L, 9);\n\t\tBF_ROUND(L, R, 10);\n\t\tBF_ROUND(R, L, 11);\n\t\tBF_ROUND(L, R, 12);\n\t\tBF_ROUND(R, L, 13);\n\t\tBF_ROUND(L, R, 14);\n\t\tBF_ROUND(R, L, 15);\n#else\n\t\tfor (int i=0; i<16; i+=2) {\n\t\t\tBF_ROUND(L, R, i);\n\t\t\tBF_ROUND(R, L, i+1);\n\t\t}\n#endif\n\t\ttmp4 = R;\n\t\tR = L;\n\t\tL = tmp4 ^ ctx->s.P[BF_N + 1];\n\t\t*ptr++ = L;\n\t\t*ptr++ = R;\n\t} while (ptr < end);\n\n\treturn L;\n}\n\nstatic void BF_set_key(const char *key, BF_key expanded, BF_key initial,\n    unsigned char flags)\n{\n\tconst char *ptr = key;\n\tunsigned int bug, i, j;\n\tBF_word safety, sign, diff, tmp[2];\n\n/*\n * There was a sign extension bug in older revisions of this function.  While\n * we would have liked to simply fix the bug and move on, we have to provide\n * a backwards compatibility feature (essentially the bug) for some systems and\n * a safety measure for some others.  The latter is needed because for certain\n * multiple inputs to the buggy algorithm there exist easily found inputs to\n * the correct algorithm that produce the same hash.  Thus, we optionally\n * deviate from the correct algorithm just enough to avoid such collisions.\n * While the bug itself affected the majority of passwords containing\n * characters with the 8th bit set (although only a percentage of those in a\n * collision-producing way), the anti-collision safety measure affects\n * only a subset of passwords containing the '\\xff' character (not even all of\n * those passwords, just some of them).  This character is not found in valid\n * UTF-8 sequences and is rarely used in popular 8-bit character encodings.\n * Thus, the safety measure is unlikely to cause much annoyance, and is a\n * reasonable tradeoff to use when authenticating against existing hashes that\n * are not reliably known to have been computed with the correct algorithm.\n *\n * We use an approach that tries to minimize side-channel leaks of password\n * information - that is, we mostly use fixed-cost bitwise operations instead\n * of branches or table lookups.  (One conditional branch based on password\n * length remains.  It is not part of the bug aftermath, though, and is\n * difficult and possibly unreasonable to avoid given the use of C strings by\n * the caller, which results in similar timing leaks anyway.)\n *\n * For actual implementation, we set an array index in the variable \"bug\"\n * (0 means no bug, 1 means sign extension bug emulation) and a flag in the\n * variable \"safety\" (bit 16 is set when the safety measure is requested).\n * Valid combinations of settings are:\n *\n * Prefix \"$2a$\": bug = 0, safety = 0x10000\n * Prefix \"$2b$\": bug = 0, safety = 0\n * Prefix \"$2x$\": bug = 1, safety = 0\n * Prefix \"$2y$\": bug = 0, safety = 0\n */\n\tbug = flags & 1;\n\tsafety = ((BF_word)flags & 2) << 15;\n\n\tsign = diff = 0;\n\n\tfor (i = 0; i < BF_N + 2; i++) {\n\t\ttmp[0] = tmp[1] = 0;\n\t\tfor (j = 0; j < 4; j++) {\n\t\t\ttmp[0] <<= 8;\n\t\t\ttmp[0] |= (unsigned char)*ptr; /* correct */\n\t\t\ttmp[1] <<= 8;\n\t\t\ttmp[1] |= (signed char)*ptr; /* bug */\n/*\n * Sign extension in the first char has no effect - nothing to overwrite yet,\n * and those extra 24 bits will be fully shifted out of the 32-bit word.  For\n * chars 2, 3, 4 in each four-char block, we set bit 7 of \"sign\" if sign\n * extension in tmp[1] occurs.  Once this flag is set, it remains set.\n */\n\t\t\tif (j)\n\t\t\t\tsign |= tmp[1] & 0x80;\n\t\t\tif (!*ptr)\n\t\t\t\tptr = key;\n\t\t\telse\n\t\t\t\tptr++;\n\t\t}\n\t\tdiff |= tmp[0] ^ tmp[1]; /* Non-zero on any differences */\n\n\t\texpanded[i] = tmp[bug];\n\t\tinitial[i] = BF_init_state.s.P[i] ^ tmp[bug];\n\t}\n\n/*\n * At this point, \"diff\" is zero iff the correct and buggy algorithms produced\n * exactly the same result.  If so and if \"sign\" is non-zero, which indicates\n * that there was a non-benign sign extension, this means that we have a\n * collision between the correctly computed hash for this password and a set of\n * passwords that could be supplied to the buggy algorithm.  Our safety measure\n * is meant to protect from such many-buggy to one-correct collisions, by\n * deviating from the correct algorithm in such cases.  Let's check for this.\n */\n\tdiff |= diff >> 16; /* still zero iff exact match */\n\tdiff &= 0xffff; /* ditto */\n\tdiff += 0xffff; /* bit 16 set iff \"diff\" was non-zero (on non-match) */\n\tsign <<= 9; /* move the non-benign sign extension flag to bit 16 */\n\tsign &= ~diff & safety; /* action needed? */\n\n/*\n * If we have determined that we need to deviate from the correct algorithm,\n * flip bit 16 in initial expanded key.  (The choice of 16 is arbitrary, but\n * let's stick to it now.  It came out of the approach we used above, and it's\n * not any worse than any other choice we could make.)\n *\n * It is crucial that we don't do the same to the expanded key used in the main\n * Eksblowfish loop.  By doing it to only one of these two, we deviate from a\n * state that could be directly specified by a password to the buggy algorithm\n * (and to the fully correct one as well, but that's a side-effect).\n */\n\tinitial[0] ^= sign;\n}\n\nstatic const unsigned char flags_by_subtype[26] = {\n\t2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0\n};\n\nstatic char *BF_crypt(const char *key, const char *setting,\n\tchar *output, BF_word min)\n{\n\tstruct {\n\t\tBF_ctx ctx;\n\t\tBF_key expanded_key;\n\t\tunion {\n\t\t\tBF_word salt[4];\n\t\t\tBF_word output[6];\n\t\t} binary;\n\t} data;\n\tBF_word count;\n\tint i;\n\n\tif (setting[0] != '$' ||\n\t    setting[1] != '2' ||\n\t    setting[2] - 'a' > 25U ||\n\t    !flags_by_subtype[setting[2] - 'a'] ||\n\t    setting[3] != '$' ||\n\t    setting[4] - '0' > 1U ||\n\t    setting[5] - '0' > 9U ||\n\t    setting[6] != '$') {\n\t\treturn NULL;\n\t}\n\n\tcount = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));\n\tif (count < min || BF_decode(data.binary.salt, &setting[7], 16)) {\n\t\treturn NULL;\n\t}\n\tBF_swap(data.binary.salt, 4);\n\n\tBF_set_key(key, data.expanded_key, data.ctx.s.P,\n\t    flags_by_subtype[setting[2] - 'a']);\n\n\tmemcpy(data.ctx.s.S, BF_init_state.s.S, sizeof(data.ctx.s.S));\n\n\t{\n\t\tBF_word L = 0, R = 0;\n\t\tBF_word *ptr = &data.ctx.PS[0];\n\t\tdo {\n\t\t\tL = BF_encrypt(&data.ctx,\n\t\t\t    L ^ data.binary.salt[0], R ^ data.binary.salt[1],\n\t\t\t    ptr, ptr);\n\t\t\tR = *(ptr + 1);\n\t\t\tptr += 2;\n\n\t\t\tif (ptr >= &data.ctx.PS[BF_N + 2 + 4 * 0x100])\n\t\t\t\tbreak;\n\n\t\t\tL = BF_encrypt(&data.ctx,\n\t\t\t    L ^ data.binary.salt[2], R ^ data.binary.salt[3],\n\t\t\t    ptr, ptr);\n\t\t\tR = *(ptr + 1);\n\t\t\tptr += 2;\n\t\t} while (1);\n\t}\n\n\tdo {\n\t\tint done;\n\n\t\tfor (i = 0; i < BF_N + 2; i += 2) {\n\t\t\tdata.ctx.s.P[i] ^= data.expanded_key[i];\n\t\t\tdata.ctx.s.P[i + 1] ^= data.expanded_key[i + 1];\n\t\t}\n\n\t\tdone = 0;\n\t\tdo {\n\t\t\tBF_encrypt(&data.ctx, 0, 0,\n\t\t\t    &data.ctx.PS[0],\n\t\t\t    &data.ctx.PS[BF_N + 2 + 4 * 0x100]);\n\n\t\t\tif (done)\n\t\t\t\tbreak;\n\t\t\tdone = 1;\n\n\t\t\t{\n\t\t\t\tBF_word tmp1, tmp2, tmp3, tmp4;\n\n\t\t\t\ttmp1 = data.binary.salt[0];\n\t\t\t\ttmp2 = data.binary.salt[1];\n\t\t\t\ttmp3 = data.binary.salt[2];\n\t\t\t\ttmp4 = data.binary.salt[3];\n\t\t\t\tfor (i = 0; i < BF_N; i += 4) {\n\t\t\t\t\tdata.ctx.s.P[i] ^= tmp1;\n\t\t\t\t\tdata.ctx.s.P[i + 1] ^= tmp2;\n\t\t\t\t\tdata.ctx.s.P[i + 2] ^= tmp3;\n\t\t\t\t\tdata.ctx.s.P[i + 3] ^= tmp4;\n\t\t\t\t}\n\t\t\t\tdata.ctx.s.P[16] ^= tmp1;\n\t\t\t\tdata.ctx.s.P[17] ^= tmp2;\n\t\t\t}\n\t\t} while (1);\n\t} while (--count);\n\n\tfor (i = 0; i < 6; i += 2) {\n\t\tBF_word L, LR[2];\n\n\t\tL = BF_magic_w[i];\n\t\tLR[1] = BF_magic_w[i + 1];\n\n\t\tcount = 64;\n\t\tdo {\n\t\t\tL = BF_encrypt(&data.ctx, L, LR[1],\n\t\t\t    &LR[0], &LR[0]);\n\t\t} while (--count);\n\n\t\tdata.binary.output[i] = L;\n\t\tdata.binary.output[i + 1] = LR[1];\n\t}\n\n\tmemcpy(output, setting, 7 + 22 - 1);\n\toutput[7 + 22 - 1] = BF_itoa64[\n\t\tBF_atoi64[setting[7 + 22 - 1] - 0x20] & 0x30];\n\n/* This has to be bug-compatible with the original implementation, so\n * only encode 23 of the 24 bytes. :-) */\n\tBF_swap(data.binary.output, 6);\n\tBF_encode(&output[7 + 22], data.binary.output, 23);\n\toutput[7 + 22 + 31] = '\\0';\n\n\treturn output;\n}\n\n/*\n * Please preserve the runtime self-test.  It serves two purposes at once:\n *\n * 1. We really can't afford the risk of producing incompatible hashes e.g.\n * when there's something like gcc bug 26587 again, whereas an application or\n * library integrating this code might not also integrate our external tests or\n * it might not run them after every build.  Even if it does, the miscompile\n * might only occur on the production build, but not on a testing build (such\n * as because of different optimization settings).  It is painful to recover\n * from incorrectly-computed hashes - merely fixing whatever broke is not\n * enough.  Thus, a proactive measure like this self-test is needed.\n *\n * 2. We don't want to leave sensitive data from our actual password hash\n * computation on the stack or in registers.  Previous revisions of the code\n * would do explicit cleanups, but simply running the self-test after hash\n * computation is more reliable.\n *\n * The performance cost of this quick self-test is around 0.6% at the \"$2a$08\"\n * setting.\n */\nchar *__crypt_blowfish(const char *key, const char *setting, char *output)\n{\n\tconst char *test_key = \"8b \\xd0\\xc1\\xd2\\xcf\\xcc\\xd8\";\n\tconst char *test_setting = \"$2a$00$abcdefghijklmnopqrstuu\";\n\tstatic const char test_hashes[2][34] = {\n\t\t\"i1D709vfamulimlGcq0qq3UvuUasvEa\\0\\x55\", /* 'a', 'b', 'y' */\n\t\t\"VUrPmXD6q/nVSSp7pNDhCR9071IfIRe\\0\\x55\", /* 'x' */\n\t};\n\tconst char *test_hash = test_hashes[0];\n\tchar *retval;\n\tconst char *p;\n\tint ok;\n\tstruct {\n\t\tchar s[7 + 22 + 1];\n\t\tchar o[7 + 22 + 31 + 1 + 1 + 1];\n\t} buf;\n\n/* Hash the supplied password */\n\tretval = BF_crypt(key, setting, output, 16);\n\n/*\n * Do a quick self-test.  It is important that we make both calls to BF_crypt()\n * from the same scope such that they likely use the same stack locations,\n * which makes the second call overwrite the first call's sensitive data on the\n * stack and makes it more likely that any alignment related issues would be\n * detected by the self-test.\n */\n\tmemcpy(buf.s, test_setting, sizeof(buf.s));\n\tif (retval) {\n\t\tunsigned int flags = flags_by_subtype[setting[2] - 'a'];\n\t\ttest_hash = test_hashes[flags & 1];\n\t\tbuf.s[2] = setting[2];\n\t}\n\tmemset(buf.o, 0x55, sizeof(buf.o));\n\tbuf.o[sizeof(buf.o) - 1] = 0;\n\tp = BF_crypt(test_key, buf.s, buf.o, 1);\n\n\tok = (p == buf.o &&\n\t    !memcmp(p, buf.s, 7 + 22) &&\n\t    !memcmp(p + (7 + 22),\n\t    test_hash,\n\t    31 + 1 + 1 + 1));\n\n\t{\n\t\tconst char *k = \"\\xff\\xa3\" \"34\" \"\\xff\\xff\\xff\\xa3\" \"345\";\n\t\tBF_key ae, ai, ye, yi;\n\t\tBF_set_key(k, ae, ai, 2); /* $2a$ */\n\t\tBF_set_key(k, ye, yi, 4); /* $2y$ */\n\t\tai[0] ^= 0x10000; /* undo the safety (for comparison) */\n\t\tok = ok && ai[0] == 0xdb9c59bc && ye[17] == 0x33343500 &&\n\t\t    !memcmp(ae, ye, sizeof(ae)) &&\n\t\t    !memcmp(ai, yi, sizeof(ai));\n\t}\n\n\tif (ok && retval)\n\t\treturn retval;\n\n\treturn \"*\";\n}\n"
  },
  {
    "path": "user.libc/src/crypt/crypt_des.c",
    "content": "/*\n * This version has been further modified by Rich Felker, primary author\n * and maintainer of musl libc, to remove table generation code and\n * replaced all runtime-generated constant tables with static-initialized\n * tables in the binary, in the interest of minimizing non-shareable\n * memory usage and stack size requirements.\n */\n/*\n * This version is derived from the original implementation of FreeSec\n * (release 1.1) by David Burren.  I've made it reentrant, reduced its memory\n * usage from about 70 KB to about 7 KB (with only minimal performance impact\n * and keeping code size about the same), made the handling of invalid salts\n * mostly UFC-crypt compatible, added a quick runtime self-test (which also\n * serves to zeroize the stack from sensitive data), and added optional tests.\n * - Solar Designer <solar at openwall.com>\n */\n\n/*\n * FreeSec: libcrypt for NetBSD\n *\n * Copyright (c) 1994 David Burren\n * Copyright (c) 2000,2002,2010,2012 Solar Designer\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the author nor the names of other contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t$Owl: Owl/packages/glibc/crypt_freesec.c,v 1.6 2010/02/20 14:45:06 solar Exp $\n *\t$Id: crypt.c,v 1.15 1994/09/13 04:58:49 davidb Exp $\n *\n * This is an original implementation of the DES and the crypt(3) interfaces\n * by David Burren.  It has been heavily re-worked by Solar Designer.\n */\n\n#include <stdint.h>\n#include <string.h>\n\n#include \"crypt_des.h\"\n\n#define _PASSWORD_EFMT1 '_'\n\nstatic const unsigned char key_shifts[16] = {\n\t1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1\n};\n\nstatic const uint32_t psbox[8][64] = {\n\t{\n\t\t0x00808200,0x00000000,0x00008000,0x00808202,\n\t\t0x00808002,0x00008202,0x00000002,0x00008000,\n\t\t0x00000200,0x00808200,0x00808202,0x00000200,\n\t\t0x00800202,0x00808002,0x00800000,0x00000002,\n\t\t0x00000202,0x00800200,0x00800200,0x00008200,\n\t\t0x00008200,0x00808000,0x00808000,0x00800202,\n\t\t0x00008002,0x00800002,0x00800002,0x00008002,\n\t\t0x00000000,0x00000202,0x00008202,0x00800000,\n\t\t0x00008000,0x00808202,0x00000002,0x00808000,\n\t\t0x00808200,0x00800000,0x00800000,0x00000200,\n\t\t0x00808002,0x00008000,0x00008200,0x00800002,\n\t\t0x00000200,0x00000002,0x00800202,0x00008202,\n\t\t0x00808202,0x00008002,0x00808000,0x00800202,\n\t\t0x00800002,0x00000202,0x00008202,0x00808200,\n\t\t0x00000202,0x00800200,0x00800200,0x00000000,\n\t\t0x00008002,0x00008200,0x00000000,0x00808002,\n\t},{\n\t\t0x40084010,0x40004000,0x00004000,0x00084010,\n\t\t0x00080000,0x00000010,0x40080010,0x40004010,\n\t\t0x40000010,0x40084010,0x40084000,0x40000000,\n\t\t0x40004000,0x00080000,0x00000010,0x40080010,\n\t\t0x00084000,0x00080010,0x40004010,0x00000000,\n\t\t0x40000000,0x00004000,0x00084010,0x40080000,\n\t\t0x00080010,0x40000010,0x00000000,0x00084000,\n\t\t0x00004010,0x40084000,0x40080000,0x00004010,\n\t\t0x00000000,0x00084010,0x40080010,0x00080000,\n\t\t0x40004010,0x40080000,0x40084000,0x00004000,\n\t\t0x40080000,0x40004000,0x00000010,0x40084010,\n\t\t0x00084010,0x00000010,0x00004000,0x40000000,\n\t\t0x00004010,0x40084000,0x00080000,0x40000010,\n\t\t0x00080010,0x40004010,0x40000010,0x00080010,\n\t\t0x00084000,0x00000000,0x40004000,0x00004010,\n\t\t0x40000000,0x40080010,0x40084010,0x00084000,\n\t},{\n\t\t0x00000104,0x04010100,0x00000000,0x04010004,\n\t\t0x04000100,0x00000000,0x00010104,0x04000100,\n\t\t0x00010004,0x04000004,0x04000004,0x00010000,\n\t\t0x04010104,0x00010004,0x04010000,0x00000104,\n\t\t0x04000000,0x00000004,0x04010100,0x00000100,\n\t\t0x00010100,0x04010000,0x04010004,0x00010104,\n\t\t0x04000104,0x00010100,0x00010000,0x04000104,\n\t\t0x00000004,0x04010104,0x00000100,0x04000000,\n\t\t0x04010100,0x04000000,0x00010004,0x00000104,\n\t\t0x00010000,0x04010100,0x04000100,0x00000000,\n\t\t0x00000100,0x00010004,0x04010104,0x04000100,\n\t\t0x04000004,0x00000100,0x00000000,0x04010004,\n\t\t0x04000104,0x00010000,0x04000000,0x04010104,\n\t\t0x00000004,0x00010104,0x00010100,0x04000004,\n\t\t0x04010000,0x04000104,0x00000104,0x04010000,\n\t\t0x00010104,0x00000004,0x04010004,0x00010100,\n\t},{\n\t\t0x80401000,0x80001040,0x80001040,0x00000040,\n\t\t0x00401040,0x80400040,0x80400000,0x80001000,\n\t\t0x00000000,0x00401000,0x00401000,0x80401040,\n\t\t0x80000040,0x00000000,0x00400040,0x80400000,\n\t\t0x80000000,0x00001000,0x00400000,0x80401000,\n\t\t0x00000040,0x00400000,0x80001000,0x00001040,\n\t\t0x80400040,0x80000000,0x00001040,0x00400040,\n\t\t0x00001000,0x00401040,0x80401040,0x80000040,\n\t\t0x00400040,0x80400000,0x00401000,0x80401040,\n\t\t0x80000040,0x00000000,0x00000000,0x00401000,\n\t\t0x00001040,0x00400040,0x80400040,0x80000000,\n\t\t0x80401000,0x80001040,0x80001040,0x00000040,\n\t\t0x80401040,0x80000040,0x80000000,0x00001000,\n\t\t0x80400000,0x80001000,0x00401040,0x80400040,\n\t\t0x80001000,0x00001040,0x00400000,0x80401000,\n\t\t0x00000040,0x00400000,0x00001000,0x00401040,\n\t},{\n\t\t0x00000080,0x01040080,0x01040000,0x21000080,\n\t\t0x00040000,0x00000080,0x20000000,0x01040000,\n\t\t0x20040080,0x00040000,0x01000080,0x20040080,\n\t\t0x21000080,0x21040000,0x00040080,0x20000000,\n\t\t0x01000000,0x20040000,0x20040000,0x00000000,\n\t\t0x20000080,0x21040080,0x21040080,0x01000080,\n\t\t0x21040000,0x20000080,0x00000000,0x21000000,\n\t\t0x01040080,0x01000000,0x21000000,0x00040080,\n\t\t0x00040000,0x21000080,0x00000080,0x01000000,\n\t\t0x20000000,0x01040000,0x21000080,0x20040080,\n\t\t0x01000080,0x20000000,0x21040000,0x01040080,\n\t\t0x20040080,0x00000080,0x01000000,0x21040000,\n\t\t0x21040080,0x00040080,0x21000000,0x21040080,\n\t\t0x01040000,0x00000000,0x20040000,0x21000000,\n\t\t0x00040080,0x01000080,0x20000080,0x00040000,\n\t\t0x00000000,0x20040000,0x01040080,0x20000080,\n\t},{\n\t\t0x10000008,0x10200000,0x00002000,0x10202008,\n\t\t0x10200000,0x00000008,0x10202008,0x00200000,\n\t\t0x10002000,0x00202008,0x00200000,0x10000008,\n\t\t0x00200008,0x10002000,0x10000000,0x00002008,\n\t\t0x00000000,0x00200008,0x10002008,0x00002000,\n\t\t0x00202000,0x10002008,0x00000008,0x10200008,\n\t\t0x10200008,0x00000000,0x00202008,0x10202000,\n\t\t0x00002008,0x00202000,0x10202000,0x10000000,\n\t\t0x10002000,0x00000008,0x10200008,0x00202000,\n\t\t0x10202008,0x00200000,0x00002008,0x10000008,\n\t\t0x00200000,0x10002000,0x10000000,0x00002008,\n\t\t0x10000008,0x10202008,0x00202000,0x10200000,\n\t\t0x00202008,0x10202000,0x00000000,0x10200008,\n\t\t0x00000008,0x00002000,0x10200000,0x00202008,\n\t\t0x00002000,0x00200008,0x10002008,0x00000000,\n\t\t0x10202000,0x10000000,0x00200008,0x10002008,\n\t},{\n\t\t0x00100000,0x02100001,0x02000401,0x00000000,\n\t\t0x00000400,0x02000401,0x00100401,0x02100400,\n\t\t0x02100401,0x00100000,0x00000000,0x02000001,\n\t\t0x00000001,0x02000000,0x02100001,0x00000401,\n\t\t0x02000400,0x00100401,0x00100001,0x02000400,\n\t\t0x02000001,0x02100000,0x02100400,0x00100001,\n\t\t0x02100000,0x00000400,0x00000401,0x02100401,\n\t\t0x00100400,0x00000001,0x02000000,0x00100400,\n\t\t0x02000000,0x00100400,0x00100000,0x02000401,\n\t\t0x02000401,0x02100001,0x02100001,0x00000001,\n\t\t0x00100001,0x02000000,0x02000400,0x00100000,\n\t\t0x02100400,0x00000401,0x00100401,0x02100400,\n\t\t0x00000401,0x02000001,0x02100401,0x02100000,\n\t\t0x00100400,0x00000000,0x00000001,0x02100401,\n\t\t0x00000000,0x00100401,0x02100000,0x00000400,\n\t\t0x02000001,0x02000400,0x00000400,0x00100001,\n\t},{\n\t\t0x08000820,0x00000800,0x00020000,0x08020820,\n\t\t0x08000000,0x08000820,0x00000020,0x08000000,\n\t\t0x00020020,0x08020000,0x08020820,0x00020800,\n\t\t0x08020800,0x00020820,0x00000800,0x00000020,\n\t\t0x08020000,0x08000020,0x08000800,0x00000820,\n\t\t0x00020800,0x00020020,0x08020020,0x08020800,\n\t\t0x00000820,0x00000000,0x00000000,0x08020020,\n\t\t0x08000020,0x08000800,0x00020820,0x00020000,\n\t\t0x00020820,0x00020000,0x08020800,0x00000800,\n\t\t0x00000020,0x08020020,0x00000800,0x00020820,\n\t\t0x08000800,0x00000020,0x08000020,0x08020000,\n\t\t0x08020020,0x08000000,0x00020000,0x08000820,\n\t\t0x00000000,0x08020820,0x00020020,0x08000020,\n\t\t0x08020000,0x08000800,0x08000820,0x00000000,\n\t\t0x08020820,0x00020800,0x00020800,0x00000820,\n\t\t0x00000820,0x00020020,0x08000000,0x08020800,\n\t},\n};\nstatic const uint32_t ip_maskl[16][16] = {\n\t{\n\t\t0x00000000,0x00010000,0x00000000,0x00010000,\n\t\t0x01000000,0x01010000,0x01000000,0x01010000,\n\t\t0x00000000,0x00010000,0x00000000,0x00010000,\n\t\t0x01000000,0x01010000,0x01000000,0x01010000,\n\t},{\n\t\t0x00000000,0x00000001,0x00000000,0x00000001,\n\t\t0x00000100,0x00000101,0x00000100,0x00000101,\n\t\t0x00000000,0x00000001,0x00000000,0x00000001,\n\t\t0x00000100,0x00000101,0x00000100,0x00000101,\n\t},{\n\t\t0x00000000,0x00020000,0x00000000,0x00020000,\n\t\t0x02000000,0x02020000,0x02000000,0x02020000,\n\t\t0x00000000,0x00020000,0x00000000,0x00020000,\n\t\t0x02000000,0x02020000,0x02000000,0x02020000,\n\t},{\n\t\t0x00000000,0x00000002,0x00000000,0x00000002,\n\t\t0x00000200,0x00000202,0x00000200,0x00000202,\n\t\t0x00000000,0x00000002,0x00000000,0x00000002,\n\t\t0x00000200,0x00000202,0x00000200,0x00000202,\n\t},{\n\t\t0x00000000,0x00040000,0x00000000,0x00040000,\n\t\t0x04000000,0x04040000,0x04000000,0x04040000,\n\t\t0x00000000,0x00040000,0x00000000,0x00040000,\n\t\t0x04000000,0x04040000,0x04000000,0x04040000,\n\t},{\n\t\t0x00000000,0x00000004,0x00000000,0x00000004,\n\t\t0x00000400,0x00000404,0x00000400,0x00000404,\n\t\t0x00000000,0x00000004,0x00000000,0x00000004,\n\t\t0x00000400,0x00000404,0x00000400,0x00000404,\n\t},{\n\t\t0x00000000,0x00080000,0x00000000,0x00080000,\n\t\t0x08000000,0x08080000,0x08000000,0x08080000,\n\t\t0x00000000,0x00080000,0x00000000,0x00080000,\n\t\t0x08000000,0x08080000,0x08000000,0x08080000,\n\t},{\n\t\t0x00000000,0x00000008,0x00000000,0x00000008,\n\t\t0x00000800,0x00000808,0x00000800,0x00000808,\n\t\t0x00000000,0x00000008,0x00000000,0x00000008,\n\t\t0x00000800,0x00000808,0x00000800,0x00000808,\n\t},{\n\t\t0x00000000,0x00100000,0x00000000,0x00100000,\n\t\t0x10000000,0x10100000,0x10000000,0x10100000,\n\t\t0x00000000,0x00100000,0x00000000,0x00100000,\n\t\t0x10000000,0x10100000,0x10000000,0x10100000,\n\t},{\n\t\t0x00000000,0x00000010,0x00000000,0x00000010,\n\t\t0x00001000,0x00001010,0x00001000,0x00001010,\n\t\t0x00000000,0x00000010,0x00000000,0x00000010,\n\t\t0x00001000,0x00001010,0x00001000,0x00001010,\n\t},{\n\t\t0x00000000,0x00200000,0x00000000,0x00200000,\n\t\t0x20000000,0x20200000,0x20000000,0x20200000,\n\t\t0x00000000,0x00200000,0x00000000,0x00200000,\n\t\t0x20000000,0x20200000,0x20000000,0x20200000,\n\t},{\n\t\t0x00000000,0x00000020,0x00000000,0x00000020,\n\t\t0x00002000,0x00002020,0x00002000,0x00002020,\n\t\t0x00000000,0x00000020,0x00000000,0x00000020,\n\t\t0x00002000,0x00002020,0x00002000,0x00002020,\n\t},{\n\t\t0x00000000,0x00400000,0x00000000,0x00400000,\n\t\t0x40000000,0x40400000,0x40000000,0x40400000,\n\t\t0x00000000,0x00400000,0x00000000,0x00400000,\n\t\t0x40000000,0x40400000,0x40000000,0x40400000,\n\t},{\n\t\t0x00000000,0x00000040,0x00000000,0x00000040,\n\t\t0x00004000,0x00004040,0x00004000,0x00004040,\n\t\t0x00000000,0x00000040,0x00000000,0x00000040,\n\t\t0x00004000,0x00004040,0x00004000,0x00004040,\n\t},{\n\t\t0x00000000,0x00800000,0x00000000,0x00800000,\n\t\t0x80000000,0x80800000,0x80000000,0x80800000,\n\t\t0x00000000,0x00800000,0x00000000,0x00800000,\n\t\t0x80000000,0x80800000,0x80000000,0x80800000,\n\t},{\n\t\t0x00000000,0x00000080,0x00000000,0x00000080,\n\t\t0x00008000,0x00008080,0x00008000,0x00008080,\n\t\t0x00000000,0x00000080,0x00000000,0x00000080,\n\t\t0x00008000,0x00008080,0x00008000,0x00008080,\n\t},\n};\nstatic const uint32_t ip_maskr[16][16] = {\n\t{\n\t\t0x00000000,0x00000000,0x00010000,0x00010000,\n\t\t0x00000000,0x00000000,0x00010000,0x00010000,\n\t\t0x01000000,0x01000000,0x01010000,0x01010000,\n\t\t0x01000000,0x01000000,0x01010000,0x01010000,\n\t},{\n\t\t0x00000000,0x00000000,0x00000001,0x00000001,\n\t\t0x00000000,0x00000000,0x00000001,0x00000001,\n\t\t0x00000100,0x00000100,0x00000101,0x00000101,\n\t\t0x00000100,0x00000100,0x00000101,0x00000101,\n\t},{\n\t\t0x00000000,0x00000000,0x00020000,0x00020000,\n\t\t0x00000000,0x00000000,0x00020000,0x00020000,\n\t\t0x02000000,0x02000000,0x02020000,0x02020000,\n\t\t0x02000000,0x02000000,0x02020000,0x02020000,\n\t},{\n\t\t0x00000000,0x00000000,0x00000002,0x00000002,\n\t\t0x00000000,0x00000000,0x00000002,0x00000002,\n\t\t0x00000200,0x00000200,0x00000202,0x00000202,\n\t\t0x00000200,0x00000200,0x00000202,0x00000202,\n\t},{\n\t\t0x00000000,0x00000000,0x00040000,0x00040000,\n\t\t0x00000000,0x00000000,0x00040000,0x00040000,\n\t\t0x04000000,0x04000000,0x04040000,0x04040000,\n\t\t0x04000000,0x04000000,0x04040000,0x04040000,\n\t},{\n\t\t0x00000000,0x00000000,0x00000004,0x00000004,\n\t\t0x00000000,0x00000000,0x00000004,0x00000004,\n\t\t0x00000400,0x00000400,0x00000404,0x00000404,\n\t\t0x00000400,0x00000400,0x00000404,0x00000404,\n\t},{\n\t\t0x00000000,0x00000000,0x00080000,0x00080000,\n\t\t0x00000000,0x00000000,0x00080000,0x00080000,\n\t\t0x08000000,0x08000000,0x08080000,0x08080000,\n\t\t0x08000000,0x08000000,0x08080000,0x08080000,\n\t},{\n\t\t0x00000000,0x00000000,0x00000008,0x00000008,\n\t\t0x00000000,0x00000000,0x00000008,0x00000008,\n\t\t0x00000800,0x00000800,0x00000808,0x00000808,\n\t\t0x00000800,0x00000800,0x00000808,0x00000808,\n\t},{\n\t\t0x00000000,0x00000000,0x00100000,0x00100000,\n\t\t0x00000000,0x00000000,0x00100000,0x00100000,\n\t\t0x10000000,0x10000000,0x10100000,0x10100000,\n\t\t0x10000000,0x10000000,0x10100000,0x10100000,\n\t},{\n\t\t0x00000000,0x00000000,0x00000010,0x00000010,\n\t\t0x00000000,0x00000000,0x00000010,0x00000010,\n\t\t0x00001000,0x00001000,0x00001010,0x00001010,\n\t\t0x00001000,0x00001000,0x00001010,0x00001010,\n\t},{\n\t\t0x00000000,0x00000000,0x00200000,0x00200000,\n\t\t0x00000000,0x00000000,0x00200000,0x00200000,\n\t\t0x20000000,0x20000000,0x20200000,0x20200000,\n\t\t0x20000000,0x20000000,0x20200000,0x20200000,\n\t},{\n\t\t0x00000000,0x00000000,0x00000020,0x00000020,\n\t\t0x00000000,0x00000000,0x00000020,0x00000020,\n\t\t0x00002000,0x00002000,0x00002020,0x00002020,\n\t\t0x00002000,0x00002000,0x00002020,0x00002020,\n\t},{\n\t\t0x00000000,0x00000000,0x00400000,0x00400000,\n\t\t0x00000000,0x00000000,0x00400000,0x00400000,\n\t\t0x40000000,0x40000000,0x40400000,0x40400000,\n\t\t0x40000000,0x40000000,0x40400000,0x40400000,\n\t},{\n\t\t0x00000000,0x00000000,0x00000040,0x00000040,\n\t\t0x00000000,0x00000000,0x00000040,0x00000040,\n\t\t0x00004000,0x00004000,0x00004040,0x00004040,\n\t\t0x00004000,0x00004000,0x00004040,0x00004040,\n\t},{\n\t\t0x00000000,0x00000000,0x00800000,0x00800000,\n\t\t0x00000000,0x00000000,0x00800000,0x00800000,\n\t\t0x80000000,0x80000000,0x80800000,0x80800000,\n\t\t0x80000000,0x80000000,0x80800000,0x80800000,\n\t},{\n\t\t0x00000000,0x00000000,0x00000080,0x00000080,\n\t\t0x00000000,0x00000000,0x00000080,0x00000080,\n\t\t0x00008000,0x00008000,0x00008080,0x00008080,\n\t\t0x00008000,0x00008000,0x00008080,0x00008080,\n\t},\n};\nstatic const uint32_t fp_maskl[8][16] = {\n\t{\n\t\t0x00000000,0x40000000,0x00400000,0x40400000,\n\t\t0x00004000,0x40004000,0x00404000,0x40404000,\n\t\t0x00000040,0x40000040,0x00400040,0x40400040,\n\t\t0x00004040,0x40004040,0x00404040,0x40404040,\n\t},{\n\t\t0x00000000,0x10000000,0x00100000,0x10100000,\n\t\t0x00001000,0x10001000,0x00101000,0x10101000,\n\t\t0x00000010,0x10000010,0x00100010,0x10100010,\n\t\t0x00001010,0x10001010,0x00101010,0x10101010,\n\t},{\n\t\t0x00000000,0x04000000,0x00040000,0x04040000,\n\t\t0x00000400,0x04000400,0x00040400,0x04040400,\n\t\t0x00000004,0x04000004,0x00040004,0x04040004,\n\t\t0x00000404,0x04000404,0x00040404,0x04040404,\n\t},{\n\t\t0x00000000,0x01000000,0x00010000,0x01010000,\n\t\t0x00000100,0x01000100,0x00010100,0x01010100,\n\t\t0x00000001,0x01000001,0x00010001,0x01010001,\n\t\t0x00000101,0x01000101,0x00010101,0x01010101,\n\t},{\n\t\t0x00000000,0x80000000,0x00800000,0x80800000,\n\t\t0x00008000,0x80008000,0x00808000,0x80808000,\n\t\t0x00000080,0x80000080,0x00800080,0x80800080,\n\t\t0x00008080,0x80008080,0x00808080,0x80808080,\n\t},{\n\t\t0x00000000,0x20000000,0x00200000,0x20200000,\n\t\t0x00002000,0x20002000,0x00202000,0x20202000,\n\t\t0x00000020,0x20000020,0x00200020,0x20200020,\n\t\t0x00002020,0x20002020,0x00202020,0x20202020,\n\t},{\n\t\t0x00000000,0x08000000,0x00080000,0x08080000,\n\t\t0x00000800,0x08000800,0x00080800,0x08080800,\n\t\t0x00000008,0x08000008,0x00080008,0x08080008,\n\t\t0x00000808,0x08000808,0x00080808,0x08080808,\n\t},{\n\t\t0x00000000,0x02000000,0x00020000,0x02020000,\n\t\t0x00000200,0x02000200,0x00020200,0x02020200,\n\t\t0x00000002,0x02000002,0x00020002,0x02020002,\n\t\t0x00000202,0x02000202,0x00020202,0x02020202,\n\t},\n};\nstatic const uint32_t fp_maskr[8][16] = {\n\t{\n\t\t0x00000000,0x40000000,0x00400000,0x40400000,\n\t\t0x00004000,0x40004000,0x00404000,0x40404000,\n\t\t0x00000040,0x40000040,0x00400040,0x40400040,\n\t\t0x00004040,0x40004040,0x00404040,0x40404040,\n\t},{\n\t\t0x00000000,0x10000000,0x00100000,0x10100000,\n\t\t0x00001000,0x10001000,0x00101000,0x10101000,\n\t\t0x00000010,0x10000010,0x00100010,0x10100010,\n\t\t0x00001010,0x10001010,0x00101010,0x10101010,\n\t},{\n\t\t0x00000000,0x04000000,0x00040000,0x04040000,\n\t\t0x00000400,0x04000400,0x00040400,0x04040400,\n\t\t0x00000004,0x04000004,0x00040004,0x04040004,\n\t\t0x00000404,0x04000404,0x00040404,0x04040404,\n\t},{\n\t\t0x00000000,0x01000000,0x00010000,0x01010000,\n\t\t0x00000100,0x01000100,0x00010100,0x01010100,\n\t\t0x00000001,0x01000001,0x00010001,0x01010001,\n\t\t0x00000101,0x01000101,0x00010101,0x01010101,\n\t},{\n\t\t0x00000000,0x80000000,0x00800000,0x80800000,\n\t\t0x00008000,0x80008000,0x00808000,0x80808000,\n\t\t0x00000080,0x80000080,0x00800080,0x80800080,\n\t\t0x00008080,0x80008080,0x00808080,0x80808080,\n\t},{\n\t\t0x00000000,0x20000000,0x00200000,0x20200000,\n\t\t0x00002000,0x20002000,0x00202000,0x20202000,\n\t\t0x00000020,0x20000020,0x00200020,0x20200020,\n\t\t0x00002020,0x20002020,0x00202020,0x20202020,\n\t},{\n\t\t0x00000000,0x08000000,0x00080000,0x08080000,\n\t\t0x00000800,0x08000800,0x00080800,0x08080800,\n\t\t0x00000008,0x08000008,0x00080008,0x08080008,\n\t\t0x00000808,0x08000808,0x00080808,0x08080808,\n\t},{\n\t\t0x00000000,0x02000000,0x00020000,0x02020000,\n\t\t0x00000200,0x02000200,0x00020200,0x02020200,\n\t\t0x00000002,0x02000002,0x00020002,0x02020002,\n\t\t0x00000202,0x02000202,0x00020202,0x02020202,\n\t},\n};\nstatic const uint32_t key_perm_maskl[8][16] = {\n\t{\n\t\t0x00000000,0x00000000,0x00000010,0x00000010,\n\t\t0x00001000,0x00001000,0x00001010,0x00001010,\n\t\t0x00100000,0x00100000,0x00100010,0x00100010,\n\t\t0x00101000,0x00101000,0x00101010,0x00101010,\n\t},{\n\t\t0x00000000,0x00000000,0x00000020,0x00000020,\n\t\t0x00002000,0x00002000,0x00002020,0x00002020,\n\t\t0x00200000,0x00200000,0x00200020,0x00200020,\n\t\t0x00202000,0x00202000,0x00202020,0x00202020,\n\t},{\n\t\t0x00000000,0x00000000,0x00000040,0x00000040,\n\t\t0x00004000,0x00004000,0x00004040,0x00004040,\n\t\t0x00400000,0x00400000,0x00400040,0x00400040,\n\t\t0x00404000,0x00404000,0x00404040,0x00404040,\n\t},{\n\t\t0x00000000,0x00000000,0x00000080,0x00000080,\n\t\t0x00008000,0x00008000,0x00008080,0x00008080,\n\t\t0x00800000,0x00800000,0x00800080,0x00800080,\n\t\t0x00808000,0x00808000,0x00808080,0x00808080,\n\t},{\n\t\t0x00000000,0x00000001,0x00000100,0x00000101,\n\t\t0x00010000,0x00010001,0x00010100,0x00010101,\n\t\t0x01000000,0x01000001,0x01000100,0x01000101,\n\t\t0x01010000,0x01010001,0x01010100,0x01010101,\n\t},{\n\t\t0x00000000,0x00000002,0x00000200,0x00000202,\n\t\t0x00020000,0x00020002,0x00020200,0x00020202,\n\t\t0x02000000,0x02000002,0x02000200,0x02000202,\n\t\t0x02020000,0x02020002,0x02020200,0x02020202,\n\t},{\n\t\t0x00000000,0x00000004,0x00000400,0x00000404,\n\t\t0x00040000,0x00040004,0x00040400,0x00040404,\n\t\t0x04000000,0x04000004,0x04000400,0x04000404,\n\t\t0x04040000,0x04040004,0x04040400,0x04040404,\n\t},{\n\t\t0x00000000,0x00000008,0x00000800,0x00000808,\n\t\t0x00080000,0x00080008,0x00080800,0x00080808,\n\t\t0x08000000,0x08000008,0x08000800,0x08000808,\n\t\t0x08080000,0x08080008,0x08080800,0x08080808,\n\t},\n};\nstatic const uint32_t key_perm_maskr[12][16] = {\n\t{\n\t\t0x00000000,0x00000001,0x00000000,0x00000001,\n\t\t0x00000000,0x00000001,0x00000000,0x00000001,\n\t\t0x00000000,0x00000001,0x00000000,0x00000001,\n\t\t0x00000000,0x00000001,0x00000000,0x00000001,\n\t},{\n\t\t0x00000000,0x00000000,0x00100000,0x00100000,\n\t\t0x00001000,0x00001000,0x00101000,0x00101000,\n\t\t0x00000010,0x00000010,0x00100010,0x00100010,\n\t\t0x00001010,0x00001010,0x00101010,0x00101010,\n\t},{\n\t\t0x00000000,0x00000002,0x00000000,0x00000002,\n\t\t0x00000000,0x00000002,0x00000000,0x00000002,\n\t\t0x00000000,0x00000002,0x00000000,0x00000002,\n\t\t0x00000000,0x00000002,0x00000000,0x00000002,\n\t},{\n\t\t0x00000000,0x00000000,0x00200000,0x00200000,\n\t\t0x00002000,0x00002000,0x00202000,0x00202000,\n\t\t0x00000020,0x00000020,0x00200020,0x00200020,\n\t\t0x00002020,0x00002020,0x00202020,0x00202020,\n\t},{\n\t\t0x00000000,0x00000004,0x00000000,0x00000004,\n\t\t0x00000000,0x00000004,0x00000000,0x00000004,\n\t\t0x00000000,0x00000004,0x00000000,0x00000004,\n\t\t0x00000000,0x00000004,0x00000000,0x00000004,\n\t},{\n\t\t0x00000000,0x00000000,0x00400000,0x00400000,\n\t\t0x00004000,0x00004000,0x00404000,0x00404000,\n\t\t0x00000040,0x00000040,0x00400040,0x00400040,\n\t\t0x00004040,0x00004040,0x00404040,0x00404040,\n\t},{\n\t\t0x00000000,0x00000008,0x00000000,0x00000008,\n\t\t0x00000000,0x00000008,0x00000000,0x00000008,\n\t\t0x00000000,0x00000008,0x00000000,0x00000008,\n\t\t0x00000000,0x00000008,0x00000000,0x00000008,\n\t},{\n\t\t0x00000000,0x00000000,0x00800000,0x00800000,\n\t\t0x00008000,0x00008000,0x00808000,0x00808000,\n\t\t0x00000080,0x00000080,0x00800080,0x00800080,\n\t\t0x00008080,0x00008080,0x00808080,0x00808080,\n\t},{\n\t\t0x00000000,0x00000000,0x01000000,0x01000000,\n\t\t0x00010000,0x00010000,0x01010000,0x01010000,\n\t\t0x00000100,0x00000100,0x01000100,0x01000100,\n\t\t0x00010100,0x00010100,0x01010100,0x01010100,\n\t},{\n\t\t0x00000000,0x00000000,0x02000000,0x02000000,\n\t\t0x00020000,0x00020000,0x02020000,0x02020000,\n\t\t0x00000200,0x00000200,0x02000200,0x02000200,\n\t\t0x00020200,0x00020200,0x02020200,0x02020200,\n\t},{\n\t\t0x00000000,0x00000000,0x04000000,0x04000000,\n\t\t0x00040000,0x00040000,0x04040000,0x04040000,\n\t\t0x00000400,0x00000400,0x04000400,0x04000400,\n\t\t0x00040400,0x00040400,0x04040400,0x04040400,\n\t},{\n\t\t0x00000000,0x00000000,0x08000000,0x08000000,\n\t\t0x00080000,0x00080000,0x08080000,0x08080000,\n\t\t0x00000800,0x00000800,0x08000800,0x08000800,\n\t\t0x00080800,0x00080800,0x08080800,0x08080800,\n\t},\n};\nstatic const uint32_t comp_maskl0[4][8] = {\n\t{\n\t\t0x00000000,0x00020000,0x00000001,0x00020001,\n\t\t0x00080000,0x000a0000,0x00080001,0x000a0001,\n\t},{\n\t\t0x00000000,0x00001000,0x00000000,0x00001000,\n\t\t0x00000040,0x00001040,0x00000040,0x00001040,\n\t},{\n\t\t0x00000000,0x00400000,0x00000020,0x00400020,\n\t\t0x00008000,0x00408000,0x00008020,0x00408020,\n\t},{\n\t\t0x00000000,0x00100000,0x00000800,0x00100800,\n\t\t0x00000000,0x00100000,0x00000800,0x00100800,\n\t},\n};\nstatic const uint32_t comp_maskr0[4][8] = {\n\t{\n\t\t0x00000000,0x00200000,0x00020000,0x00220000,\n\t\t0x00000002,0x00200002,0x00020002,0x00220002,\n\t},{\n\t\t0x00000000,0x00000000,0x00100000,0x00100000,\n\t\t0x00000004,0x00000004,0x00100004,0x00100004,\n\t},{\n\t\t0x00000000,0x00004000,0x00000800,0x00004800,\n\t\t0x00000000,0x00004000,0x00000800,0x00004800,\n\t},{\n\t\t0x00000000,0x00400000,0x00008000,0x00408000,\n\t\t0x00000008,0x00400008,0x00008008,0x00408008,\n\t},\n};\nstatic const uint32_t comp_maskl1[4][16] = {\n\t{\n\t\t0x00000000,0x00000010,0x00004000,0x00004010,\n\t\t0x00040000,0x00040010,0x00044000,0x00044010,\n\t\t0x00000100,0x00000110,0x00004100,0x00004110,\n\t\t0x00040100,0x00040110,0x00044100,0x00044110,\n\t},{\n\t\t0x00000000,0x00800000,0x00000002,0x00800002,\n\t\t0x00000200,0x00800200,0x00000202,0x00800202,\n\t\t0x00200000,0x00a00000,0x00200002,0x00a00002,\n\t\t0x00200200,0x00a00200,0x00200202,0x00a00202,\n\t},{\n\t\t0x00000000,0x00002000,0x00000004,0x00002004,\n\t\t0x00000400,0x00002400,0x00000404,0x00002404,\n\t\t0x00000000,0x00002000,0x00000004,0x00002004,\n\t\t0x00000400,0x00002400,0x00000404,0x00002404,\n\t},{\n\t\t0x00000000,0x00010000,0x00000008,0x00010008,\n\t\t0x00000080,0x00010080,0x00000088,0x00010088,\n\t\t0x00000000,0x00010000,0x00000008,0x00010008,\n\t\t0x00000080,0x00010080,0x00000088,0x00010088,\n\t},\n};\nstatic const uint32_t comp_maskr1[4][16] = {\n\t{\n\t\t0x00000000,0x00000000,0x00000080,0x00000080,\n\t\t0x00002000,0x00002000,0x00002080,0x00002080,\n\t\t0x00000001,0x00000001,0x00000081,0x00000081,\n\t\t0x00002001,0x00002001,0x00002081,0x00002081,\n\t},{\n\t\t0x00000000,0x00000010,0x00800000,0x00800010,\n\t\t0x00010000,0x00010010,0x00810000,0x00810010,\n\t\t0x00000200,0x00000210,0x00800200,0x00800210,\n\t\t0x00010200,0x00010210,0x00810200,0x00810210,\n\t},{\n\t\t0x00000000,0x00000400,0x00001000,0x00001400,\n\t\t0x00080000,0x00080400,0x00081000,0x00081400,\n\t\t0x00000020,0x00000420,0x00001020,0x00001420,\n\t\t0x00080020,0x00080420,0x00081020,0x00081420,\n\t},{\n\t\t0x00000000,0x00000100,0x00040000,0x00040100,\n\t\t0x00000000,0x00000100,0x00040000,0x00040100,\n\t\t0x00000040,0x00000140,0x00040040,0x00040140,\n\t\t0x00000040,0x00000140,0x00040040,0x00040140,\n\t},\n};\n\nstatic const unsigned char ascii64[] =\n    \"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n/*   0000000000111111111122222222223333333333444444444455555555556666 */\n/*   0123456789012345678901234567890123456789012345678901234567890123 */\n\n/*\n * We match the behavior of UFC-crypt on systems where \"char\" is signed by\n * default (the majority), regardless of char's signedness on our system.\n */\nstatic uint32_t ascii_to_bin(int ch)\n{\n\tint sch = (ch < 0x80) ? ch : -(0x100 - ch);\n\tint retval;\n\n\tretval = sch - '.';\n\tif (sch >= 'A') {\n\t\tretval = sch - ('A' - 12);\n\t\tif (sch >= 'a')\n\t\t\tretval = sch - ('a' - 38);\n\t}\n\tretval &= 0x3f;\n\n\treturn retval;\n}\n\n/*\n * When we choose to \"support\" invalid salts, nevertheless disallow those\n * containing characters that would violate the passwd file format.\n */\nstatic inline int ascii_is_unsafe(unsigned char ch)\n{\n\treturn !ch || ch == '\\n' || ch == ':';\n}\n\nstatic uint32_t setup_salt(uint32_t salt)\n{\n\tuint32_t obit, saltbit, saltbits;\n\tunsigned int i;\n\n\tsaltbits = 0;\n\tsaltbit = 1;\n\tobit = 0x800000;\n\tfor (i = 0; i < 24; i++) {\n\t\tif (salt & saltbit)\n\t\t\tsaltbits |= obit;\n\t\tsaltbit <<= 1;\n\t\tobit >>= 1;\n\t}\n\n\treturn saltbits;\n}\n\nvoid __des_setkey(const unsigned char *key, struct expanded_key *ekey)\n{\n\tuint32_t k0, k1, rawkey0, rawkey1;\n\tunsigned int shifts, round, i, ibit;\n\n\trawkey0 =\n\t    (uint32_t)key[3] |\n\t    ((uint32_t)key[2] << 8) |\n\t    ((uint32_t)key[1] << 16) |\n\t    ((uint32_t)key[0] << 24);\n\trawkey1 =\n\t    (uint32_t)key[7] |\n\t    ((uint32_t)key[6] << 8) |\n\t    ((uint32_t)key[5] << 16) |\n\t    ((uint32_t)key[4] << 24);\n\n\t/*\n\t * Do key permutation and split into two 28-bit subkeys.\n\t */\n\tk0 = k1 = 0;\n\tfor (i = 0, ibit = 28; i < 4; i++, ibit -= 4) {\n\t\tunsigned int j = i << 1;\n\t\tk0 |= key_perm_maskl[i][(rawkey0 >> ibit) & 0xf] |\n\t\t      key_perm_maskl[i + 4][(rawkey1 >> ibit) & 0xf];\n\t\tk1 |= key_perm_maskr[j][(rawkey0 >> ibit) & 0xf];\n\t\tibit -= 4;\n\t\tk1 |= key_perm_maskr[j + 1][(rawkey0 >> ibit) & 0xf] |\n\t\t      key_perm_maskr[i + 8][(rawkey1 >> ibit) & 0xf];\n\t}\n\n\t/*\n\t * Rotate subkeys and do compression permutation.\n\t */\n\tshifts = 0;\n\tfor (round = 0; round < 16; round++) {\n\t\tuint32_t t0, t1;\n\t\tuint32_t kl, kr;\n\n\t\tshifts += key_shifts[round];\n\n\t\tt0 = (k0 << shifts) | (k0 >> (28 - shifts));\n\t\tt1 = (k1 << shifts) | (k1 >> (28 - shifts));\n\n\t\tkl = kr = 0;\n\t\tibit = 25;\n\t\tfor (i = 0; i < 4; i++) {\n\t\t\tkl |= comp_maskl0[i][(t0 >> ibit) & 7];\n\t\t\tkr |= comp_maskr0[i][(t1 >> ibit) & 7];\n\t\t\tibit -= 4;\n\t\t\tkl |= comp_maskl1[i][(t0 >> ibit) & 0xf];\n\t\t\tkr |= comp_maskr1[i][(t1 >> ibit) & 0xf];\n\t\t\tibit -= 3;\n\t\t}\n\t\tekey->l[round] = kl;\n\t\tekey->r[round] = kr;\n\t}\n}\n\n/*\n * l_in, r_in, l_out, and r_out are in pseudo-\"big-endian\" format.\n */\nvoid __do_des(uint32_t l_in, uint32_t r_in,\n    uint32_t *l_out, uint32_t *r_out,\n    uint32_t count, uint32_t saltbits, const struct expanded_key *ekey)\n{\n\tuint32_t l, r;\n\n\t/*\n\t * Do initial permutation (IP).\n\t */\n\tl = r = 0;\n\tif (l_in | r_in) {\n\t\tunsigned int i, ibit;\n\t\tfor (i = 0, ibit = 28; i < 8; i++, ibit -= 4) {\n\t\t\tl |= ip_maskl[i][(l_in >> ibit) & 0xf] |\n\t\t\t     ip_maskl[i + 8][(r_in >> ibit) & 0xf];\n\t\t\tr |= ip_maskr[i][(l_in >> ibit) & 0xf] |\n\t\t\t     ip_maskr[i + 8][(r_in >> ibit) & 0xf];\n\t\t}\n\t}\n\n\twhile (count--) {\n\t\t/*\n\t\t * Do each round.\n\t\t */\n\t\tunsigned int round = 16;\n\t\tconst uint32_t *kl = ekey->l;\n\t\tconst uint32_t *kr = ekey->r;\n\t\tuint32_t f;\n\t\twhile (round--) {\n\t\t\tuint32_t r48l, r48r;\n\t\t\t/*\n\t\t\t * Expand R to 48 bits (simulate the E-box).\n\t\t\t */\n\t\t\tr48l\t= ((r & 0x00000001) << 23)\n\t\t\t\t| ((r & 0xf8000000) >> 9)\n\t\t\t\t| ((r & 0x1f800000) >> 11)\n\t\t\t\t| ((r & 0x01f80000) >> 13)\n\t\t\t\t| ((r & 0x001f8000) >> 15);\n\n\t\t\tr48r\t= ((r & 0x0001f800) << 7)\n\t\t\t\t| ((r & 0x00001f80) << 5)\n\t\t\t\t| ((r & 0x000001f8) << 3)\n\t\t\t\t| ((r & 0x0000001f) << 1)\n\t\t\t\t| ((r & 0x80000000) >> 31);\n\t\t\t/*\n\t\t\t * Do salting for crypt() and friends, and\n\t\t\t * XOR with the permuted key.\n\t\t\t */\n\t\t\tf = (r48l ^ r48r) & saltbits;\n\t\t\tr48l ^= f ^ *kl++;\n\t\t\tr48r ^= f ^ *kr++;\n\t\t\t/*\n\t\t\t * Do S-box lookups (which shrink it back to 32 bits)\n\t\t\t * and do the P-box permutation at the same time.\n\t\t\t */\n\t\t\tf = psbox[0][r48l >> 18]\n\t\t\t  | psbox[1][(r48l >> 12) & 0x3f]\n\t\t\t  | psbox[2][(r48l >> 6) & 0x3f]\n\t\t\t  | psbox[3][r48l & 0x3f]\n\t\t\t  | psbox[4][r48r >> 18]\n\t\t\t  | psbox[5][(r48r >> 12) & 0x3f]\n\t\t\t  | psbox[6][(r48r >> 6) & 0x3f]\n\t\t\t  | psbox[7][r48r & 0x3f];\n\t\t\t/*\n\t\t\t * Now that we've permuted things, complete f().\n\t\t\t */\n\t\t\tf ^= l;\n\t\t\tl = r;\n\t\t\tr = f;\n\t\t}\n\t\tr = l;\n\t\tl = f;\n\t}\n\n\t/*\n\t * Do final permutation (inverse of IP).\n\t */\n\t{\n\t\tunsigned int i, ibit;\n\t\tuint32_t lo, ro;\n\t\tlo = ro = 0;\n\t\tfor (i = 0, ibit = 28; i < 4; i++, ibit -= 4) {\n\t\t\tro |= fp_maskr[i][(l >> ibit) & 0xf] |\n\t\t\t      fp_maskr[i + 4][(r >> ibit) & 0xf];\n\t\t\tibit -= 4;\n\t\t\tlo |= fp_maskl[i][(l >> ibit) & 0xf] |\n\t\t\t      fp_maskl[i + 4][(r >> ibit) & 0xf];\n\t\t}\n\t\t*l_out = lo;\n\t\t*r_out = ro;\n\t}\n}\n\nstatic void des_cipher(const unsigned char *in, unsigned char *out,\n    uint32_t count, uint32_t saltbits, const struct expanded_key *ekey)\n{\n\tuint32_t l_out, r_out, rawl, rawr;\n\n\trawl =\n\t    (uint32_t)in[3] |\n\t    ((uint32_t)in[2] << 8) |\n\t    ((uint32_t)in[1] << 16) |\n\t    ((uint32_t)in[0] << 24);\n\trawr =\n\t    (uint32_t)in[7] |\n\t    ((uint32_t)in[6] << 8) |\n\t    ((uint32_t)in[5] << 16) |\n\t    ((uint32_t)in[4] << 24);\n\n\t__do_des(rawl, rawr, &l_out, &r_out, count, saltbits, ekey);\n\n\tout[0] = l_out >> 24;\n\tout[1] = l_out >> 16;\n\tout[2] = l_out >> 8;\n\tout[3] = l_out;\n\tout[4] = r_out >> 24;\n\tout[5] = r_out >> 16;\n\tout[6] = r_out >> 8;\n\tout[7] = r_out;\n}\n\nstatic char *_crypt_extended_r_uut(const char *_key, const char *_setting, char *output)\n{\n\tconst unsigned char *key = (const unsigned char *)_key;\n\tconst unsigned char *setting = (const unsigned char *)_setting;\n\tstruct expanded_key ekey;\n\tunsigned char keybuf[8];\n\tunsigned char *p, *q;\n\tuint32_t count, salt, l, r0, r1;\n\tunsigned int i;\n\n\t/*\n\t * Copy the key, shifting each character left by one bit and padding\n\t * with zeroes.\n\t */\n\tq = keybuf;\n\twhile (q <= &keybuf[sizeof(keybuf) - 1]) {\n\t\t*q++ = *key << 1;\n\t\tif (*key)\n\t\t\tkey++;\n\t}\n\t__des_setkey(keybuf, &ekey);\n\n\tif (*setting == _PASSWORD_EFMT1) {\n\t\t/*\n\t\t * \"new\"-style:\n\t\t *\tsetting - underscore, 4 chars of count, 4 chars of salt\n\t\t *\tkey - unlimited characters\n\t\t */\n\t\tfor (i = 1, count = 0; i < 5; i++) {\n\t\t\tuint32_t value = ascii_to_bin(setting[i]);\n\t\t\tif (ascii64[value] != setting[i])\n\t\t\t\treturn NULL;\n\t\t\tcount |= value << (i - 1) * 6;\n\t\t}\n\t\tif (!count)\n\t\t\treturn NULL;\n\n\t\tfor (i = 5, salt = 0; i < 9; i++) {\n\t\t\tuint32_t value = ascii_to_bin(setting[i]);\n\t\t\tif (ascii64[value] != setting[i])\n\t\t\t\treturn NULL;\n\t\t\tsalt |= value << (i - 5) * 6;\n\t\t}\n\n\t\twhile (*key) {\n\t\t\t/*\n\t\t\t * Encrypt the key with itself.\n\t\t\t */\n\t\t\tdes_cipher(keybuf, keybuf, 1, 0, &ekey);\n\t\t\t/*\n\t\t\t * And XOR with the next 8 characters of the key.\n\t\t\t */\n\t\t\tq = keybuf;\n\t\t\twhile (q <= &keybuf[sizeof(keybuf) - 1] && *key)\n\t\t\t\t*q++ ^= *key++ << 1;\n\t\t\t__des_setkey(keybuf, &ekey);\n\t\t}\n\n\t\tmemcpy(output, setting, 9);\n\t\toutput[9] = '\\0';\n\t\tp = (unsigned char *)output + 9;\n\t} else {\n\t\t/*\n\t\t * \"old\"-style:\n\t\t *\tsetting - 2 chars of salt\n\t\t *\tkey - up to 8 characters\n\t\t */\n\t\tcount = 25;\n\n\t\tif (ascii_is_unsafe(setting[0]) || ascii_is_unsafe(setting[1]))\n\t\t\treturn NULL;\n\n\t\tsalt = (ascii_to_bin(setting[1]) << 6)\n\t\t     |  ascii_to_bin(setting[0]);\n\n\t\toutput[0] = setting[0];\n\t\toutput[1] = setting[1];\n\t\tp = (unsigned char *)output + 2;\n\t}\n\n\t/*\n\t * Do it.\n\t */\n\t__do_des(0, 0, &r0, &r1, count, setup_salt(salt), &ekey);\n\n\t/*\n\t * Now encode the result...\n\t */\n\tl = (r0 >> 8);\n\t*p++ = ascii64[(l >> 18) & 0x3f];\n\t*p++ = ascii64[(l >> 12) & 0x3f];\n\t*p++ = ascii64[(l >> 6) & 0x3f];\n\t*p++ = ascii64[l & 0x3f];\n\n\tl = (r0 << 16) | ((r1 >> 16) & 0xffff);\n\t*p++ = ascii64[(l >> 18) & 0x3f];\n\t*p++ = ascii64[(l >> 12) & 0x3f];\n\t*p++ = ascii64[(l >> 6) & 0x3f];\n\t*p++ = ascii64[l & 0x3f];\n\n\tl = r1 << 2;\n\t*p++ = ascii64[(l >> 12) & 0x3f];\n\t*p++ = ascii64[(l >> 6) & 0x3f];\n\t*p++ = ascii64[l & 0x3f];\n\t*p = 0;\n\n\treturn output;\n}\n\nchar *__crypt_des(const char *key, const char *setting, char *output)\n{\n\tconst char *test_key = \"\\x80\\xff\\x80\\x01 \"\n\t    \"\\x7f\\x81\\x80\\x80\\x0d\\x0a\\xff\\x7f \\x81 test\";\n\tconst char *test_setting = \"_0.../9Zz\";\n\tconst char *test_hash = \"_0.../9ZzX7iSJNd21sU\";\n\tchar test_buf[21];\n\tchar *retval;\n\tconst char *p;\n\n\tif (*setting != _PASSWORD_EFMT1) {\n\t\ttest_setting = \"\\x80x\";\n\t\ttest_hash = \"\\x80x22/wK52ZKGA\";\n\t}\n\n\t/*\n\t * Hash the supplied password.\n\t */\n\tretval = _crypt_extended_r_uut(key, setting, output);\n\n\t/*\n\t * Perform a quick self-test.  It is important that we make both calls\n\t * to _crypt_extended_r_uut() from the same scope such that they likely\n\t * use the same stack locations, which makes the second call overwrite\n\t * the first call's sensitive data on the stack and makes it more\n\t * likely that any alignment related issues would be detected.\n\t */\n\tp = _crypt_extended_r_uut(test_key, test_setting, test_buf);\n\tif (p && !strcmp(p, test_hash) && retval)\n\t\treturn retval;\n\n\treturn (setting[0]=='*') ? \"x\" : \"*\";\n}\n"
  },
  {
    "path": "user.libc/src/crypt/crypt_des.h",
    "content": "#ifndef CRYPT_DES_H\n#define CRYPT_DES_H\n\n#include <stdint.h>\n\nstruct expanded_key {\n\tuint32_t l[16], r[16];\n};\n\nhidden void __des_setkey(const unsigned char *, struct expanded_key *);\nhidden void __do_des(uint32_t, uint32_t, uint32_t *, uint32_t *,\n                     uint32_t, uint32_t, const struct expanded_key *);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/crypt/crypt_md5.c",
    "content": "/*\n * md5 crypt implementation\n *\n * original md5 crypt design is from Poul-Henning Kamp\n * this implementation was created based on the code in freebsd\n * at least 32bit int is assumed, key is limited and $1$ prefix is mandatory,\n * on error \"*\" is returned\n */\n#include <string.h>\n#include <stdint.h>\n\n/* public domain md5 implementation based on rfc1321 and libtomcrypt */\n\nstruct md5 {\n\tuint64_t len;    /* processed message length */\n\tuint32_t h[4];   /* hash state */\n\tuint8_t buf[64]; /* message block buffer */\n};\n\nstatic uint32_t rol(uint32_t n, int k) { return (n << k) | (n >> (32-k)); }\n#define F(x,y,z) (z ^ (x & (y ^ z)))\n#define G(x,y,z) (y ^ (z & (y ^ x)))\n#define H(x,y,z) (x ^ y ^ z)\n#define I(x,y,z) (y ^ (x | ~z))\n#define FF(a,b,c,d,w,s,t) a += F(b,c,d) + w + t; a = rol(a,s) + b\n#define GG(a,b,c,d,w,s,t) a += G(b,c,d) + w + t; a = rol(a,s) + b\n#define HH(a,b,c,d,w,s,t) a += H(b,c,d) + w + t; a = rol(a,s) + b\n#define II(a,b,c,d,w,s,t) a += I(b,c,d) + w + t; a = rol(a,s) + b\n\nstatic const uint32_t tab[64] = {\n0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,\n0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,\n0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,\n0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,\n0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,\n0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,\n0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,\n0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391\n};\n\nstatic void processblock(struct md5 *s, const uint8_t *buf)\n{\n\tuint32_t i, W[16], a, b, c, d;\n\n\tfor (i = 0; i < 16; i++) {\n\t\tW[i] = buf[4*i];\n\t\tW[i] |= (uint32_t)buf[4*i+1]<<8;\n\t\tW[i] |= (uint32_t)buf[4*i+2]<<16;\n\t\tW[i] |= (uint32_t)buf[4*i+3]<<24;\n\t}\n\n\ta = s->h[0];\n\tb = s->h[1];\n\tc = s->h[2];\n\td = s->h[3];\n\n\ti = 0;\n\twhile (i < 16) {\n\t\tFF(a,b,c,d, W[i],  7, tab[i]); i++;\n\t\tFF(d,a,b,c, W[i], 12, tab[i]); i++;\n\t\tFF(c,d,a,b, W[i], 17, tab[i]); i++;\n\t\tFF(b,c,d,a, W[i], 22, tab[i]); i++;\n\t}\n\twhile (i < 32) {\n\t\tGG(a,b,c,d, W[(5*i+1)%16],  5, tab[i]); i++;\n\t\tGG(d,a,b,c, W[(5*i+1)%16],  9, tab[i]); i++;\n\t\tGG(c,d,a,b, W[(5*i+1)%16], 14, tab[i]); i++;\n\t\tGG(b,c,d,a, W[(5*i+1)%16], 20, tab[i]); i++;\n\t}\n\twhile (i < 48) {\n\t\tHH(a,b,c,d, W[(3*i+5)%16],  4, tab[i]); i++;\n\t\tHH(d,a,b,c, W[(3*i+5)%16], 11, tab[i]); i++;\n\t\tHH(c,d,a,b, W[(3*i+5)%16], 16, tab[i]); i++;\n\t\tHH(b,c,d,a, W[(3*i+5)%16], 23, tab[i]); i++;\n\t}\n\twhile (i < 64) {\n\t\tII(a,b,c,d, W[7*i%16],  6, tab[i]); i++;\n\t\tII(d,a,b,c, W[7*i%16], 10, tab[i]); i++;\n\t\tII(c,d,a,b, W[7*i%16], 15, tab[i]); i++;\n\t\tII(b,c,d,a, W[7*i%16], 21, tab[i]); i++;\n\t}\n\n\ts->h[0] += a;\n\ts->h[1] += b;\n\ts->h[2] += c;\n\ts->h[3] += d;\n}\n\nstatic void pad(struct md5 *s)\n{\n\tunsigned r = s->len % 64;\n\n\ts->buf[r++] = 0x80;\n\tif (r > 56) {\n\t\tmemset(s->buf + r, 0, 64 - r);\n\t\tr = 0;\n\t\tprocessblock(s, s->buf);\n\t}\n\tmemset(s->buf + r, 0, 56 - r);\n\ts->len *= 8;\n\ts->buf[56] = s->len;\n\ts->buf[57] = s->len >> 8;\n\ts->buf[58] = s->len >> 16;\n\ts->buf[59] = s->len >> 24;\n\ts->buf[60] = s->len >> 32;\n\ts->buf[61] = s->len >> 40;\n\ts->buf[62] = s->len >> 48;\n\ts->buf[63] = s->len >> 56;\n\tprocessblock(s, s->buf);\n}\n\nstatic void md5_init(struct md5 *s)\n{\n\ts->len = 0;\n\ts->h[0] = 0x67452301;\n\ts->h[1] = 0xefcdab89;\n\ts->h[2] = 0x98badcfe;\n\ts->h[3] = 0x10325476;\n}\n\nstatic void md5_sum(struct md5 *s, uint8_t *md)\n{\n\tint i;\n\n\tpad(s);\n\tfor (i = 0; i < 4; i++) {\n\t\tmd[4*i] = s->h[i];\n\t\tmd[4*i+1] = s->h[i] >> 8;\n\t\tmd[4*i+2] = s->h[i] >> 16;\n\t\tmd[4*i+3] = s->h[i] >> 24;\n\t}\n}\n\nstatic void md5_update(struct md5 *s, const void *m, unsigned long len)\n{\n\tconst uint8_t *p = m;\n\tunsigned r = s->len % 64;\n\n\ts->len += len;\n\tif (r) {\n\t\tif (len < 64 - r) {\n\t\t\tmemcpy(s->buf + r, p, len);\n\t\t\treturn;\n\t\t}\n\t\tmemcpy(s->buf + r, p, 64 - r);\n\t\tlen -= 64 - r;\n\t\tp += 64 - r;\n\t\tprocessblock(s, s->buf);\n\t}\n\tfor (; len >= 64; len -= 64, p += 64)\n\t\tprocessblock(s, p);\n\tmemcpy(s->buf, p, len);\n}\n\n/*-\n * Copyright (c) 2003 Poul-Henning Kamp\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n/* key limit is not part of the original design, added for DoS protection */\n#define KEY_MAX 30000\n#define SALT_MAX 8\n\nstatic const unsigned char b64[] =\n\"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n\nstatic char *to64(char *s, unsigned int u, int n)\n{\n\twhile (--n >= 0) {\n\t\t*s++ = b64[u % 64];\n\t\tu /= 64;\n\t}\n\treturn s;\n}\n\nstatic char *md5crypt(const char *key, const char *setting, char *output)\n{\n\tstruct md5 ctx;\n\tunsigned char md[16];\n\tunsigned int i, klen, slen;\n\tconst char *salt;\n\tchar *p;\n\n\t/* reject large keys */\n\tklen = strnlen(key, KEY_MAX+1);\n\tif (klen > KEY_MAX)\n\t\treturn 0;\n\n\t/* setting: $1$salt$ (closing $ is optional) */\n\tif (strncmp(setting, \"$1$\", 3) != 0)\n\t\treturn 0;\n\tsalt = setting + 3;\n\tfor (i = 0; i < SALT_MAX && salt[i] && salt[i] != '$'; i++);\n\tslen = i;\n\n\t/* md5(key salt key) */\n\tmd5_init(&ctx);\n\tmd5_update(&ctx, key, klen);\n\tmd5_update(&ctx, salt, slen);\n\tmd5_update(&ctx, key, klen);\n\tmd5_sum(&ctx, md);\n\n\t/* md5(key $1$ salt repeated-md weird-key[0]-0) */\n\tmd5_init(&ctx);\n\tmd5_update(&ctx, key, klen);\n\tmd5_update(&ctx, setting, 3 + slen);\n\tfor (i = klen; i > sizeof md; i -= sizeof md)\n\t\tmd5_update(&ctx, md, sizeof md);\n\tmd5_update(&ctx, md, i);\n\tmd[0] = 0;\n\tfor (i = klen; i; i >>= 1)\n\t\tif (i & 1)\n\t\t\tmd5_update(&ctx, md, 1);\n\t\telse\n\t\t\tmd5_update(&ctx, key, 1);\n\tmd5_sum(&ctx, md);\n\n\t/* md = f(md, key, salt) iteration */\n\tfor (i = 0; i < 1000; i++) {\n\t\tmd5_init(&ctx);\n\t\tif (i % 2)\n\t\t\tmd5_update(&ctx, key, klen);\n\t\telse\n\t\t\tmd5_update(&ctx, md, sizeof md);\n\t\tif (i % 3)\n\t\t\tmd5_update(&ctx, salt, slen);\n\t\tif (i % 7)\n\t\t\tmd5_update(&ctx, key, klen);\n\t\tif (i % 2)\n\t\t\tmd5_update(&ctx, md, sizeof md);\n\t\telse\n\t\t\tmd5_update(&ctx, key, klen);\n\t\tmd5_sum(&ctx, md);\n\t}\n\n\t/* output is $1$salt$hash */\n\tmemcpy(output, setting, 3 + slen);\n\tp = output + 3 + slen;\n\t*p++ = '$';\n\tstatic const unsigned char perm[][3] = {\n\t\t0,6,12,1,7,13,2,8,14,3,9,15,4,10,5 };\n\tfor (i=0; i<5; i++) p = to64(p,\n\t\t(md[perm[i][0]]<<16)|(md[perm[i][1]]<<8)|md[perm[i][2]], 4);\n\tp = to64(p, md[11], 2);\n\t*p = 0;\n\n\treturn output;\n}\n\nchar *__crypt_md5(const char *key, const char *setting, char *output)\n{\n\tstatic const char testkey[] = \"Xy01@#\\x01\\x02\\x80\\x7f\\xff\\r\\n\\x81\\t !\";\n\tstatic const char testsetting[] = \"$1$abcd0123$\";\n\tstatic const char testhash[] = \"$1$abcd0123$9Qcg8DyviekV3tDGMZynJ1\";\n\tchar testbuf[64];\n\tchar *p, *q;\n\n\tp = md5crypt(key, setting, output);\n\t/* self test and stack cleanup */\n\tq = md5crypt(testkey, testsetting, testbuf);\n\tif (!p || q != testbuf || memcmp(testbuf, testhash, sizeof testhash))\n\t\treturn \"*\";\n\treturn p;\n}\n"
  },
  {
    "path": "user.libc/src/crypt/crypt_r.c",
    "content": "#include <crypt.h>\n\nchar *__crypt_r(const char *key, const char *salt, struct crypt_data *data)\n{\n\t/* Per the crypt_r API, the caller has provided a pointer to\n\t * struct crypt_data; however, this implementation does not\n\t * use the structure to store any internal state, and treats\n\t * it purely as a char buffer for storing the result. */\n\tchar *output = (char *)data;\n\tif (salt[0] == '$' && salt[1] && salt[2]) {\n\t\tif (salt[1] == '1' && salt[2] == '$')\n\t\t\treturn __crypt_md5(key, salt, output);\n\t\tif (salt[1] == '2' && salt[3] == '$')\n\t\t\treturn __crypt_blowfish(key, salt, output);\n\t\tif (salt[1] == '5' && salt[2] == '$')\n\t\t\treturn __crypt_sha256(key, salt, output);\n\t\tif (salt[1] == '6' && salt[2] == '$')\n\t\t\treturn __crypt_sha512(key, salt, output);\n\t}\n\treturn __crypt_des(key, salt, output);\n}\n\nweak_alias(__crypt_r, crypt_r);\n"
  },
  {
    "path": "user.libc/src/crypt/crypt_sha256.c",
    "content": "/*\n * public domain sha256 crypt implementation\n *\n * original sha crypt design: http://people.redhat.com/drepper/SHA-crypt.txt\n * in this implementation at least 32bit int is assumed,\n * key length is limited, the $5$ prefix is mandatory, '\\n' and ':' is rejected\n * in the salt and rounds= setting must contain a valid iteration count,\n * on error \"*\" is returned.\n */\n#include <ctype.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <stdint.h>\n\n/* public domain sha256 implementation based on fips180-3 */\n\nstruct sha256 {\n\tuint64_t len;    /* processed message length */\n\tuint32_t h[8];   /* hash state */\n\tuint8_t buf[64]; /* message block buffer */\n};\n\nstatic uint32_t ror(uint32_t n, int k) { return (n >> k) | (n << (32-k)); }\n#define Ch(x,y,z)  (z ^ (x & (y ^ z)))\n#define Maj(x,y,z) ((x & y) | (z & (x | y)))\n#define S0(x)      (ror(x,2) ^ ror(x,13) ^ ror(x,22))\n#define S1(x)      (ror(x,6) ^ ror(x,11) ^ ror(x,25))\n#define R0(x)      (ror(x,7) ^ ror(x,18) ^ (x>>3))\n#define R1(x)      (ror(x,17) ^ ror(x,19) ^ (x>>10))\n\nstatic const uint32_t K[64] = {\n0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n};\n\nstatic void processblock(struct sha256 *s, const uint8_t *buf)\n{\n\tuint32_t W[64], t1, t2, a, b, c, d, e, f, g, h;\n\tint i;\n\n\tfor (i = 0; i < 16; i++) {\n\t\tW[i] = (uint32_t)buf[4*i]<<24;\n\t\tW[i] |= (uint32_t)buf[4*i+1]<<16;\n\t\tW[i] |= (uint32_t)buf[4*i+2]<<8;\n\t\tW[i] |= buf[4*i+3];\n\t}\n\tfor (; i < 64; i++)\n\t\tW[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16];\n\ta = s->h[0];\n\tb = s->h[1];\n\tc = s->h[2];\n\td = s->h[3];\n\te = s->h[4];\n\tf = s->h[5];\n\tg = s->h[6];\n\th = s->h[7];\n\tfor (i = 0; i < 64; i++) {\n\t\tt1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i];\n\t\tt2 = S0(a) + Maj(a,b,c);\n\t\th = g;\n\t\tg = f;\n\t\tf = e;\n\t\te = d + t1;\n\t\td = c;\n\t\tc = b;\n\t\tb = a;\n\t\ta = t1 + t2;\n\t}\n\ts->h[0] += a;\n\ts->h[1] += b;\n\ts->h[2] += c;\n\ts->h[3] += d;\n\ts->h[4] += e;\n\ts->h[5] += f;\n\ts->h[6] += g;\n\ts->h[7] += h;\n}\n\nstatic void pad(struct sha256 *s)\n{\n\tunsigned r = s->len % 64;\n\n\ts->buf[r++] = 0x80;\n\tif (r > 56) {\n\t\tmemset(s->buf + r, 0, 64 - r);\n\t\tr = 0;\n\t\tprocessblock(s, s->buf);\n\t}\n\tmemset(s->buf + r, 0, 56 - r);\n\ts->len *= 8;\n\ts->buf[56] = s->len >> 56;\n\ts->buf[57] = s->len >> 48;\n\ts->buf[58] = s->len >> 40;\n\ts->buf[59] = s->len >> 32;\n\ts->buf[60] = s->len >> 24;\n\ts->buf[61] = s->len >> 16;\n\ts->buf[62] = s->len >> 8;\n\ts->buf[63] = s->len;\n\tprocessblock(s, s->buf);\n}\n\nstatic void sha256_init(struct sha256 *s)\n{\n\ts->len = 0;\n\ts->h[0] = 0x6a09e667;\n\ts->h[1] = 0xbb67ae85;\n\ts->h[2] = 0x3c6ef372;\n\ts->h[3] = 0xa54ff53a;\n\ts->h[4] = 0x510e527f;\n\ts->h[5] = 0x9b05688c;\n\ts->h[6] = 0x1f83d9ab;\n\ts->h[7] = 0x5be0cd19;\n}\n\nstatic void sha256_sum(struct sha256 *s, uint8_t *md)\n{\n\tint i;\n\n\tpad(s);\n\tfor (i = 0; i < 8; i++) {\n\t\tmd[4*i] = s->h[i] >> 24;\n\t\tmd[4*i+1] = s->h[i] >> 16;\n\t\tmd[4*i+2] = s->h[i] >> 8;\n\t\tmd[4*i+3] = s->h[i];\n\t}\n}\n\nstatic void sha256_update(struct sha256 *s, const void *m, unsigned long len)\n{\n\tconst uint8_t *p = m;\n\tunsigned r = s->len % 64;\n\n\ts->len += len;\n\tif (r) {\n\t\tif (len < 64 - r) {\n\t\t\tmemcpy(s->buf + r, p, len);\n\t\t\treturn;\n\t\t}\n\t\tmemcpy(s->buf + r, p, 64 - r);\n\t\tlen -= 64 - r;\n\t\tp += 64 - r;\n\t\tprocessblock(s, s->buf);\n\t}\n\tfor (; len >= 64; len -= 64, p += 64)\n\t\tprocessblock(s, p);\n\tmemcpy(s->buf, p, len);\n}\n\nstatic const unsigned char b64[] =\n\"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n\nstatic char *to64(char *s, unsigned int u, int n)\n{\n\twhile (--n >= 0) {\n\t\t*s++ = b64[u % 64];\n\t\tu /= 64;\n\t}\n\treturn s;\n}\n\n/* key limit is not part of the original design, added for DoS protection.\n * rounds limit has been lowered (versus the reference/spec), also for DoS\n * protection. runtime is O(klen^2 + klen*rounds) */\n#define KEY_MAX 256\n#define SALT_MAX 16\n#define ROUNDS_DEFAULT 5000\n#define ROUNDS_MIN 1000\n#define ROUNDS_MAX 9999999\n\n/* hash n bytes of the repeated md message digest */\nstatic void hashmd(struct sha256 *s, unsigned int n, const void *md)\n{\n\tunsigned int i;\n\n\tfor (i = n; i > 32; i -= 32)\n\t\tsha256_update(s, md, 32);\n\tsha256_update(s, md, i);\n}\n\nstatic char *sha256crypt(const char *key, const char *setting, char *output)\n{\n\tstruct sha256 ctx;\n\tunsigned char md[32], kmd[32], smd[32];\n\tunsigned int i, r, klen, slen;\n\tchar rounds[20] = \"\";\n\tconst char *salt;\n\tchar *p;\n\n\t/* reject large keys */\n\tklen = strnlen(key, KEY_MAX+1);\n\tif (klen > KEY_MAX)\n\t\treturn 0;\n\n\t/* setting: $5$rounds=n$salt$ (rounds=n$ and closing $ are optional) */\n\tif (strncmp(setting, \"$5$\", 3) != 0)\n\t\treturn 0;\n\tsalt = setting + 3;\n\n\tr = ROUNDS_DEFAULT;\n\tif (strncmp(salt, \"rounds=\", sizeof \"rounds=\" - 1) == 0) {\n\t\tunsigned long u;\n\t\tchar *end;\n\n\t\t/*\n\t\t * this is a deviation from the reference:\n\t\t * bad rounds setting is rejected if it is\n\t\t * - empty\n\t\t * - unterminated (missing '$')\n\t\t * - begins with anything but a decimal digit\n\t\t * the reference implementation treats these bad\n\t\t * rounds as part of the salt or parse them with\n\t\t * strtoul semantics which may cause problems\n\t\t * including non-portable hashes that depend on\n\t\t * the host's value of ULONG_MAX.\n\t\t */\n\t\tsalt += sizeof \"rounds=\" - 1;\n\t\tif (!isdigit(*salt))\n\t\t\treturn 0;\n\t\tu = strtoul(salt, &end, 10);\n\t\tif (*end != '$')\n\t\t\treturn 0;\n\t\tsalt = end+1;\n\t\tif (u < ROUNDS_MIN)\n\t\t\tr = ROUNDS_MIN;\n\t\telse if (u > ROUNDS_MAX)\n\t\t\treturn 0;\n\t\telse\n\t\t\tr = u;\n\t\t/* needed when rounds is zero prefixed or out of bounds */\n\t\tsprintf(rounds, \"rounds=%u$\", r);\n\t}\n\n\tfor (i = 0; i < SALT_MAX && salt[i] && salt[i] != '$'; i++)\n\t\t/* reject characters that interfere with /etc/shadow parsing */\n\t\tif (salt[i] == '\\n' || salt[i] == ':')\n\t\t\treturn 0;\n\tslen = i;\n\n\t/* B = sha(key salt key) */\n\tsha256_init(&ctx);\n\tsha256_update(&ctx, key, klen);\n\tsha256_update(&ctx, salt, slen);\n\tsha256_update(&ctx, key, klen);\n\tsha256_sum(&ctx, md);\n\n\t/* A = sha(key salt repeat-B alternate-B-key) */\n\tsha256_init(&ctx);\n\tsha256_update(&ctx, key, klen);\n\tsha256_update(&ctx, salt, slen);\n\thashmd(&ctx, klen, md);\n\tfor (i = klen; i > 0; i >>= 1)\n\t\tif (i & 1)\n\t\t\tsha256_update(&ctx, md, sizeof md);\n\t\telse\n\t\t\tsha256_update(&ctx, key, klen);\n\tsha256_sum(&ctx, md);\n\n\t/* DP = sha(repeat-key), this step takes O(klen^2) time */\n\tsha256_init(&ctx);\n\tfor (i = 0; i < klen; i++)\n\t\tsha256_update(&ctx, key, klen);\n\tsha256_sum(&ctx, kmd);\n\n\t/* DS = sha(repeat-salt) */\n\tsha256_init(&ctx);\n\tfor (i = 0; i < 16 + md[0]; i++)\n\t\tsha256_update(&ctx, salt, slen);\n\tsha256_sum(&ctx, smd);\n\n\t/* iterate A = f(A,DP,DS), this step takes O(rounds*klen) time */\n\tfor (i = 0; i < r; i++) {\n\t\tsha256_init(&ctx);\n\t\tif (i % 2)\n\t\t\thashmd(&ctx, klen, kmd);\n\t\telse\n\t\t\tsha256_update(&ctx, md, sizeof md);\n\t\tif (i % 3)\n\t\t\tsha256_update(&ctx, smd, slen);\n\t\tif (i % 7)\n\t\t\thashmd(&ctx, klen, kmd);\n\t\tif (i % 2)\n\t\t\tsha256_update(&ctx, md, sizeof md);\n\t\telse\n\t\t\thashmd(&ctx, klen, kmd);\n\t\tsha256_sum(&ctx, md);\n\t}\n\n\t/* output is $5$rounds=n$salt$hash */\n\tp = output;\n\tp += sprintf(p, \"$5$%s%.*s$\", rounds, slen, salt);\n\tstatic const unsigned char perm[][3] = {\n\t\t0,10,20,21,1,11,12,22,2,3,13,23,24,4,14,\n\t\t15,25,5,6,16,26,27,7,17,18,28,8,9,19,29 };\n\tfor (i=0; i<10; i++) p = to64(p,\n\t\t(md[perm[i][0]]<<16)|(md[perm[i][1]]<<8)|md[perm[i][2]], 4);\n\tp = to64(p, (md[31]<<8)|md[30], 3);\n\t*p = 0;\n\treturn output;\n}\n\nchar *__crypt_sha256(const char *key, const char *setting, char *output)\n{\n\tstatic const char testkey[] = \"Xy01@#\\x01\\x02\\x80\\x7f\\xff\\r\\n\\x81\\t !\";\n\tstatic const char testsetting[] = \"$5$rounds=1234$abc0123456789$\";\n\tstatic const char testhash[] = \"$5$rounds=1234$abc0123456789$3VfDjPt05VHFn47C/ojFZ6KRPYrOjj1lLbH.dkF3bZ6\";\n\tchar testbuf[128];\n\tchar *p, *q;\n\n\tp = sha256crypt(key, setting, output);\n\t/* self test and stack cleanup */\n\tq = sha256crypt(testkey, testsetting, testbuf);\n\tif (!p || q != testbuf || memcmp(testbuf, testhash, sizeof testhash))\n\t\treturn \"*\";\n\treturn p;\n}\n"
  },
  {
    "path": "user.libc/src/crypt/crypt_sha512.c",
    "content": "/*\n * public domain sha512 crypt implementation\n *\n * original sha crypt design: http://people.redhat.com/drepper/SHA-crypt.txt\n * in this implementation at least 32bit int is assumed,\n * key length is limited, the $6$ prefix is mandatory, '\\n' and ':' is rejected\n * in the salt and rounds= setting must contain a valid iteration count,\n * on error \"*\" is returned.\n */\n#include <ctype.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <stdint.h>\n\n/* public domain sha512 implementation based on fips180-3 */\n/* >=2^64 bits messages are not supported (about 2000 peta bytes) */\n\nstruct sha512 {\n\tuint64_t len;     /* processed message length */\n\tuint64_t h[8];    /* hash state */\n\tuint8_t buf[128]; /* message block buffer */\n};\n\nstatic uint64_t ror(uint64_t n, int k) { return (n >> k) | (n << (64-k)); }\n#define Ch(x,y,z)  (z ^ (x & (y ^ z)))\n#define Maj(x,y,z) ((x & y) | (z & (x | y)))\n#define S0(x)      (ror(x,28) ^ ror(x,34) ^ ror(x,39))\n#define S1(x)      (ror(x,14) ^ ror(x,18) ^ ror(x,41))\n#define R0(x)      (ror(x,1) ^ ror(x,8) ^ (x>>7))\n#define R1(x)      (ror(x,19) ^ ror(x,61) ^ (x>>6))\n\nstatic const uint64_t K[80] = {\n0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,\n0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,\n0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,\n0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,\n0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,\n0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,\n0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,\n0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,\n0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,\n0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,\n0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,\n0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,\n0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,\n0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,\n0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,\n0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,\n0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,\n0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,\n0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,\n0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL\n};\n\nstatic void processblock(struct sha512 *s, const uint8_t *buf)\n{\n\tuint64_t W[80], t1, t2, a, b, c, d, e, f, g, h;\n\tint i;\n\n\tfor (i = 0; i < 16; i++) {\n\t\tW[i] = (uint64_t)buf[8*i]<<56;\n\t\tW[i] |= (uint64_t)buf[8*i+1]<<48;\n\t\tW[i] |= (uint64_t)buf[8*i+2]<<40;\n\t\tW[i] |= (uint64_t)buf[8*i+3]<<32;\n\t\tW[i] |= (uint64_t)buf[8*i+4]<<24;\n\t\tW[i] |= (uint64_t)buf[8*i+5]<<16;\n\t\tW[i] |= (uint64_t)buf[8*i+6]<<8;\n\t\tW[i] |= buf[8*i+7];\n\t}\n\tfor (; i < 80; i++)\n\t\tW[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16];\n\ta = s->h[0];\n\tb = s->h[1];\n\tc = s->h[2];\n\td = s->h[3];\n\te = s->h[4];\n\tf = s->h[5];\n\tg = s->h[6];\n\th = s->h[7];\n\tfor (i = 0; i < 80; i++) {\n\t\tt1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i];\n\t\tt2 = S0(a) + Maj(a,b,c);\n\t\th = g;\n\t\tg = f;\n\t\tf = e;\n\t\te = d + t1;\n\t\td = c;\n\t\tc = b;\n\t\tb = a;\n\t\ta = t1 + t2;\n\t}\n\ts->h[0] += a;\n\ts->h[1] += b;\n\ts->h[2] += c;\n\ts->h[3] += d;\n\ts->h[4] += e;\n\ts->h[5] += f;\n\ts->h[6] += g;\n\ts->h[7] += h;\n}\n\nstatic void pad(struct sha512 *s)\n{\n\tunsigned r = s->len % 128;\n\n\ts->buf[r++] = 0x80;\n\tif (r > 112) {\n\t\tmemset(s->buf + r, 0, 128 - r);\n\t\tr = 0;\n\t\tprocessblock(s, s->buf);\n\t}\n\tmemset(s->buf + r, 0, 120 - r);\n\ts->len *= 8;\n\ts->buf[120] = s->len >> 56;\n\ts->buf[121] = s->len >> 48;\n\ts->buf[122] = s->len >> 40;\n\ts->buf[123] = s->len >> 32;\n\ts->buf[124] = s->len >> 24;\n\ts->buf[125] = s->len >> 16;\n\ts->buf[126] = s->len >> 8;\n\ts->buf[127] = s->len;\n\tprocessblock(s, s->buf);\n}\n\nstatic void sha512_init(struct sha512 *s)\n{\n\ts->len = 0;\n\ts->h[0] = 0x6a09e667f3bcc908ULL;\n\ts->h[1] = 0xbb67ae8584caa73bULL;\n\ts->h[2] = 0x3c6ef372fe94f82bULL;\n\ts->h[3] = 0xa54ff53a5f1d36f1ULL;\n\ts->h[4] = 0x510e527fade682d1ULL;\n\ts->h[5] = 0x9b05688c2b3e6c1fULL;\n\ts->h[6] = 0x1f83d9abfb41bd6bULL;\n\ts->h[7] = 0x5be0cd19137e2179ULL;\n}\n\nstatic void sha512_sum(struct sha512 *s, uint8_t *md)\n{\n\tint i;\n\n\tpad(s);\n\tfor (i = 0; i < 8; i++) {\n\t\tmd[8*i] = s->h[i] >> 56;\n\t\tmd[8*i+1] = s->h[i] >> 48;\n\t\tmd[8*i+2] = s->h[i] >> 40;\n\t\tmd[8*i+3] = s->h[i] >> 32;\n\t\tmd[8*i+4] = s->h[i] >> 24;\n\t\tmd[8*i+5] = s->h[i] >> 16;\n\t\tmd[8*i+6] = s->h[i] >> 8;\n\t\tmd[8*i+7] = s->h[i];\n\t}\n}\n\nstatic void sha512_update(struct sha512 *s, const void *m, unsigned long len)\n{\n\tconst uint8_t *p = m;\n\tunsigned r = s->len % 128;\n\n\ts->len += len;\n\tif (r) {\n\t\tif (len < 128 - r) {\n\t\t\tmemcpy(s->buf + r, p, len);\n\t\t\treturn;\n\t\t}\n\t\tmemcpy(s->buf + r, p, 128 - r);\n\t\tlen -= 128 - r;\n\t\tp += 128 - r;\n\t\tprocessblock(s, s->buf);\n\t}\n\tfor (; len >= 128; len -= 128, p += 128)\n\t\tprocessblock(s, p);\n\tmemcpy(s->buf, p, len);\n}\n\nstatic const unsigned char b64[] =\n\"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n\nstatic char *to64(char *s, unsigned int u, int n)\n{\n\twhile (--n >= 0) {\n\t\t*s++ = b64[u % 64];\n\t\tu /= 64;\n\t}\n\treturn s;\n}\n\n/* key limit is not part of the original design, added for DoS protection.\n * rounds limit has been lowered (versus the reference/spec), also for DoS\n * protection. runtime is O(klen^2 + klen*rounds) */\n#define KEY_MAX 256\n#define SALT_MAX 16\n#define ROUNDS_DEFAULT 5000\n#define ROUNDS_MIN 1000\n#define ROUNDS_MAX 9999999\n\n/* hash n bytes of the repeated md message digest */\nstatic void hashmd(struct sha512 *s, unsigned int n, const void *md)\n{\n\tunsigned int i;\n\n\tfor (i = n; i > 64; i -= 64)\n\t\tsha512_update(s, md, 64);\n\tsha512_update(s, md, i);\n}\n\nstatic char *sha512crypt(const char *key, const char *setting, char *output)\n{\n\tstruct sha512 ctx;\n\tunsigned char md[64], kmd[64], smd[64];\n\tunsigned int i, r, klen, slen;\n\tchar rounds[20] = \"\";\n\tconst char *salt;\n\tchar *p;\n\n\t/* reject large keys */\n\tfor (i = 0; i <= KEY_MAX && key[i]; i++);\n\tif (i > KEY_MAX)\n\t\treturn 0;\n\tklen = i;\n\n\t/* setting: $6$rounds=n$salt$ (rounds=n$ and closing $ are optional) */\n\tif (strncmp(setting, \"$6$\", 3) != 0)\n\t\treturn 0;\n\tsalt = setting + 3;\n\n\tr = ROUNDS_DEFAULT;\n\tif (strncmp(salt, \"rounds=\", sizeof \"rounds=\" - 1) == 0) {\n\t\tunsigned long u;\n\t\tchar *end;\n\n\t\t/*\n\t\t * this is a deviation from the reference:\n\t\t * bad rounds setting is rejected if it is\n\t\t * - empty\n\t\t * - unterminated (missing '$')\n\t\t * - begins with anything but a decimal digit\n\t\t * the reference implementation treats these bad\n\t\t * rounds as part of the salt or parse them with\n\t\t * strtoul semantics which may cause problems\n\t\t * including non-portable hashes that depend on\n\t\t * the host's value of ULONG_MAX.\n\t\t */\n\t\tsalt += sizeof \"rounds=\" - 1;\n\t\tif (!isdigit(*salt))\n\t\t\treturn 0;\n\t\tu = strtoul(salt, &end, 10);\n\t\tif (*end != '$')\n\t\t\treturn 0;\n\t\tsalt = end+1;\n\t\tif (u < ROUNDS_MIN)\n\t\t\tr = ROUNDS_MIN;\n\t\telse if (u > ROUNDS_MAX)\n\t\t\treturn 0;\n\t\telse\n\t\t\tr = u;\n\t\t/* needed when rounds is zero prefixed or out of bounds */\n\t\tsprintf(rounds, \"rounds=%u$\", r);\n\t}\n\n\tfor (i = 0; i < SALT_MAX && salt[i] && salt[i] != '$'; i++)\n\t\t/* reject characters that interfere with /etc/shadow parsing */\n\t\tif (salt[i] == '\\n' || salt[i] == ':')\n\t\t\treturn 0;\n\tslen = i;\n\n\t/* B = sha(key salt key) */\n\tsha512_init(&ctx);\n\tsha512_update(&ctx, key, klen);\n\tsha512_update(&ctx, salt, slen);\n\tsha512_update(&ctx, key, klen);\n\tsha512_sum(&ctx, md);\n\n\t/* A = sha(key salt repeat-B alternate-B-key) */\n\tsha512_init(&ctx);\n\tsha512_update(&ctx, key, klen);\n\tsha512_update(&ctx, salt, slen);\n\thashmd(&ctx, klen, md);\n\tfor (i = klen; i > 0; i >>= 1)\n\t\tif (i & 1)\n\t\t\tsha512_update(&ctx, md, sizeof md);\n\t\telse\n\t\t\tsha512_update(&ctx, key, klen);\n\tsha512_sum(&ctx, md);\n\n\t/* DP = sha(repeat-key), this step takes O(klen^2) time */\n\tsha512_init(&ctx);\n\tfor (i = 0; i < klen; i++)\n\t\tsha512_update(&ctx, key, klen);\n\tsha512_sum(&ctx, kmd);\n\n\t/* DS = sha(repeat-salt) */\n\tsha512_init(&ctx);\n\tfor (i = 0; i < 16 + md[0]; i++)\n\t\tsha512_update(&ctx, salt, slen);\n\tsha512_sum(&ctx, smd);\n\n\t/* iterate A = f(A,DP,DS), this step takes O(rounds*klen) time */\n\tfor (i = 0; i < r; i++) {\n\t\tsha512_init(&ctx);\n\t\tif (i % 2)\n\t\t\thashmd(&ctx, klen, kmd);\n\t\telse\n\t\t\tsha512_update(&ctx, md, sizeof md);\n\t\tif (i % 3)\n\t\t\tsha512_update(&ctx, smd, slen);\n\t\tif (i % 7)\n\t\t\thashmd(&ctx, klen, kmd);\n\t\tif (i % 2)\n\t\t\tsha512_update(&ctx, md, sizeof md);\n\t\telse\n\t\t\thashmd(&ctx, klen, kmd);\n\t\tsha512_sum(&ctx, md);\n\t}\n\n\t/* output is $6$rounds=n$salt$hash */\n\tp = output;\n\tp += sprintf(p, \"$6$%s%.*s$\", rounds, slen, salt);\n#if 1\n\tstatic const unsigned char perm[][3] = {\n\t\t0,21,42,22,43,1,44,2,23,3,24,45,25,46,4,\n\t\t47,5,26,6,27,48,28,49,7,50,8,29,9,30,51,\n\t\t31,52,10,53,11,32,12,33,54,34,55,13,56,14,35,\n\t\t15,36,57,37,58,16,59,17,38,18,39,60,40,61,19,\n\t\t62,20,41 };\n\tfor (i=0; i<21; i++) p = to64(p,\n\t\t(md[perm[i][0]]<<16)|(md[perm[i][1]]<<8)|md[perm[i][2]], 4);\n#else\n\tp = to64(p, (md[0]<<16)|(md[21]<<8)|md[42], 4);\n\tp = to64(p, (md[22]<<16)|(md[43]<<8)|md[1], 4);\n\tp = to64(p, (md[44]<<16)|(md[2]<<8)|md[23], 4);\n\tp = to64(p, (md[3]<<16)|(md[24]<<8)|md[45], 4);\n\tp = to64(p, (md[25]<<16)|(md[46]<<8)|md[4], 4);\n\tp = to64(p, (md[47]<<16)|(md[5]<<8)|md[26], 4);\n\tp = to64(p, (md[6]<<16)|(md[27]<<8)|md[48], 4);\n\tp = to64(p, (md[28]<<16)|(md[49]<<8)|md[7], 4);\n\tp = to64(p, (md[50]<<16)|(md[8]<<8)|md[29], 4);\n\tp = to64(p, (md[9]<<16)|(md[30]<<8)|md[51], 4);\n\tp = to64(p, (md[31]<<16)|(md[52]<<8)|md[10], 4);\n\tp = to64(p, (md[53]<<16)|(md[11]<<8)|md[32], 4);\n\tp = to64(p, (md[12]<<16)|(md[33]<<8)|md[54], 4);\n\tp = to64(p, (md[34]<<16)|(md[55]<<8)|md[13], 4);\n\tp = to64(p, (md[56]<<16)|(md[14]<<8)|md[35], 4);\n\tp = to64(p, (md[15]<<16)|(md[36]<<8)|md[57], 4);\n\tp = to64(p, (md[37]<<16)|(md[58]<<8)|md[16], 4);\n\tp = to64(p, (md[59]<<16)|(md[17]<<8)|md[38], 4);\n\tp = to64(p, (md[18]<<16)|(md[39]<<8)|md[60], 4);\n\tp = to64(p, (md[40]<<16)|(md[61]<<8)|md[19], 4);\n\tp = to64(p, (md[62]<<16)|(md[20]<<8)|md[41], 4);\n#endif\n\tp = to64(p, md[63], 2);\n\t*p = 0;\n\treturn output;\n}\n\nchar *__crypt_sha512(const char *key, const char *setting, char *output)\n{\n\tstatic const char testkey[] = \"Xy01@#\\x01\\x02\\x80\\x7f\\xff\\r\\n\\x81\\t !\";\n\tstatic const char testsetting[] = \"$6$rounds=1234$abc0123456789$\";\n\tstatic const char testhash[] = \"$6$rounds=1234$abc0123456789$BCpt8zLrc/RcyuXmCDOE1ALqMXB2MH6n1g891HhFj8.w7LxGv.FTkqq6Vxc/km3Y0jE0j24jY5PIv/oOu6reg1\";\n\tchar testbuf[128];\n\tchar *p, *q;\n\n\tp = sha512crypt(key, setting, output);\n\t/* self test and stack cleanup */\n\tq = sha512crypt(testkey, testsetting, testbuf);\n\tif (!p || q != testbuf || memcmp(testbuf, testhash, sizeof testhash))\n\t\treturn \"*\";\n\treturn p;\n}\n"
  },
  {
    "path": "user.libc/src/crypt/encrypt.c",
    "content": "#include <stdint.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include \"crypt_des.h\"\n\nstatic struct expanded_key __encrypt_key;\n\nvoid setkey(const char *key)\n{\n\tunsigned char bkey[8];\n\tint i, j;\n\n\tfor (i = 0; i < 8; i++) {\n\t\tbkey[i] = 0;\n\t\tfor (j = 7; j >= 0; j--, key++)\n\t\t\tbkey[i] |= (uint32_t)(*key & 1) << j;\n\t}\n\n\t__des_setkey(bkey, &__encrypt_key);\n}\n\nvoid encrypt(char *block, int edflag)\n{\n\tstruct expanded_key decrypt_key, *key;\n\tuint32_t b[2];\n\tint i, j;\n\tchar *p;\n\n\tp = block;\n\tfor (i = 0; i < 2; i++) {\n\t\tb[i] = 0;\n\t\tfor (j = 31; j >= 0; j--, p++)\n\t\t\tb[i] |= (uint32_t)(*p & 1) << j;\n\t}\n\n\tkey = &__encrypt_key;\n\tif (edflag) {\n\t\tkey = &decrypt_key;\n\t\tfor (i = 0; i < 16; i++) {\n\t\t\tdecrypt_key.l[i] = __encrypt_key.l[15-i];\n\t\t\tdecrypt_key.r[i] = __encrypt_key.r[15-i];\n\t\t}\n\t}\n\n\t__do_des(b[0], b[1], b, b + 1, 1, 0, key);\n\n\tp = block;\n\tfor (i = 0; i < 2; i++)\n\t\tfor (j = 31; j >= 0; j--)\n\t\t\t*p++ = b[i]>>j & 1;\n}\n"
  },
  {
    "path": "user.libc/src/ctype/__ctype_b_loc.c",
    "content": "#include <endian.h>\n\n#if __BYTE_ORDER == __BIG_ENDIAN\n#define X(x) x\n#else\n#define X(x) (((x)/256 | (x)*256) % 65536)\n#endif\n\nstatic const unsigned short table[] = {\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\nX(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),\nX(0x200),X(0x320),X(0x220),X(0x220),X(0x220),X(0x220),X(0x200),X(0x200),\nX(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),\nX(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),\nX(0x160),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),\nX(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),\nX(0x8d8),X(0x8d8),X(0x8d8),X(0x8d8),X(0x8d8),X(0x8d8),X(0x8d8),X(0x8d8),\nX(0x8d8),X(0x8d8),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),\nX(0x4c0),X(0x8d5),X(0x8d5),X(0x8d5),X(0x8d5),X(0x8d5),X(0x8d5),X(0x8c5),\nX(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),\nX(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),\nX(0x8c5),X(0x8c5),X(0x8c5),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),\nX(0x4c0),X(0x8d6),X(0x8d6),X(0x8d6),X(0x8d6),X(0x8d6),X(0x8d6),X(0x8c6),\nX(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),\nX(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),\nX(0x8c6),X(0x8c6),X(0x8c6),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x200),\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n};\n\nstatic const unsigned short *const ptable = table+128;\n\nconst unsigned short **__ctype_b_loc(void)\n{\n\treturn (void *)&ptable;\n}\n"
  },
  {
    "path": "user.libc/src/ctype/__ctype_get_mb_cur_max.c",
    "content": "#include <stdlib.h>\n#include \"locale_impl.h\"\n\nsize_t __ctype_get_mb_cur_max()\n{\n\treturn MB_CUR_MAX;\n}\n"
  },
  {
    "path": "user.libc/src/ctype/__ctype_tolower_loc.c",
    "content": "#include <stdint.h>\n\nstatic const int32_t table[] = {\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,\n16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,\n32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,\n48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,\n64,\n'a','b','c','d','e','f','g','h','i','j','k','l','m',\n'n','o','p','q','r','s','t','u','v','w','x','y','z',\n91,92,93,94,95,96,\n'a','b','c','d','e','f','g','h','i','j','k','l','m',\n'n','o','p','q','r','s','t','u','v','w','x','y','z',\n123,124,125,126,127,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n};\n\nstatic const int32_t *const ptable = table+128;\n\nconst int32_t **__ctype_tolower_loc(void)\n{\n\treturn (void *)&ptable;\n}\n"
  },
  {
    "path": "user.libc/src/ctype/__ctype_toupper_loc.c",
    "content": "#include <stdint.h>\n\nstatic const int32_t table[] = {\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,\n16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,\n32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,\n48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,\n64,\n'A','B','C','D','E','F','G','H','I','J','K','L','M',\n'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',\n91,92,93,94,95,96,\n'A','B','C','D','E','F','G','H','I','J','K','L','M',\n'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',\n123,124,125,126,127,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n};\n\nstatic const int32_t *const ptable = table+128;\n\nconst int32_t **__ctype_toupper_loc(void)\n{\n\treturn (void *)&ptable;\n}\n"
  },
  {
    "path": "user.libc/src/ctype/alpha.h",
    "content": "18,17,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,17,34,35,36,17,37,38,39,40,\n41,42,43,44,17,45,46,47,16,16,48,16,16,16,16,16,16,16,49,50,51,16,52,53,16,16,\n17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,54,\n17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,\n17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,\n17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,\n17,17,17,55,17,17,17,17,56,17,57,58,59,60,61,62,17,17,17,17,17,17,17,17,17,17,\n17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,\n17,17,17,17,17,17,17,63,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,64,65,17,66,67,\n68,69,70,71,72,73,74,17,75,76,77,78,79,80,81,16,82,83,84,85,86,87,88,89,90,91,\n92,93,16,94,95,96,16,17,17,17,97,98,99,16,16,16,16,16,16,16,16,16,16,17,17,17,\n17,100,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,101,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,17,17,102,103,16,16,104,105,17,17,17,17,17,17,17,17,17,17,17,17,17,17,\n17,17,17,17,17,17,17,17,17,106,17,17,107,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,\n108,109,16,16,16,16,16,16,16,16,16,110,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,111,112,113,114,16,16,16,16,16,16,16,16,115,116,\n117,16,16,16,16,16,118,119,16,16,16,16,120,16,16,121,16,16,16,16,16,16,16,16,\n16,16,16,16,16,\n16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,254,255,255,7,254,\n255,255,7,0,0,0,0,0,4,32,4,255,255,127,255,255,255,127,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,195,255,3,0,31,80,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,223,188,64,215,255,255,\n251,255,255,255,255,255,255,255,255,255,191,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,3,252,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,254,255,255,255,127,2,255,255,255,\n255,255,1,0,0,0,0,255,191,182,0,255,255,255,135,7,0,0,0,255,7,255,255,255,255,\n255,255,255,254,255,195,255,255,255,255,255,255,255,255,255,255,255,255,239,\n31,254,225,255,\n159,0,0,255,255,255,255,255,255,0,224,255,255,255,255,255,255,255,255,255,255,\n255,255,3,0,255,255,255,255,255,7,48,4,255,255,255,252,255,31,0,0,255,255,255,\n1,255,7,0,0,0,0,0,0,255,255,223,63,0,0,240,255,248,3,255,255,255,255,255,255,\n255,255,255,239,255,223,225,255,207,255,254,255,239,159,249,255,255,253,197,\n227,159,89,128,176,207,255,3,16,238,135,249,255,255,253,109,195,135,25,2,94,\n192,255,63,0,238,191,251,255,255,253,237,227,191,27,1,0,207,255,0,30,238,159,\n249,255,255,253,237,227,159,25,192,176,207,255,2,0,236,199,61,214,24,199,255,\n195,199,29,129,0,192,255,0,0,239,223,253,255,255,253,255,227,223,29,96,7,207,\n255,0,0,239,223,253,255,255,253,239,227,223,29,96,64,207,255,6,0,239,223,253,\n255,255,255,255,231,223,93,240,128,207,255,0,252,236,255,127,252,255,255,251,\n47,127,128,95,255,192,255,12,0,254,255,255,255,255,127,255,7,63,32,255,3,0,0,\n0,0,214,247,255,255,175,255,255,59,95,32,255,243,0,0,0,\n0,1,0,0,0,255,3,0,0,255,254,255,255,255,31,254,255,3,255,255,254,255,255,255,\n31,0,0,0,0,0,0,0,0,255,255,255,255,255,255,127,249,255,3,255,255,255,255,255,\n255,255,255,255,63,255,255,255,255,191,32,255,255,255,255,255,247,255,255,255,\n255,255,255,255,255,255,61,127,61,255,255,255,255,255,61,255,255,255,255,61,\n127,61,255,127,255,255,255,255,255,255,255,61,255,255,255,255,255,255,255,255,\n7,0,0,0,0,255,255,0,0,255,255,255,255,255,255,255,255,255,255,63,63,254,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,159,255,255,254,255,255,7,255,255,255,255,255,255,255,255,\n255,199,255,1,255,223,15,0,255,255,15,0,255,255,15,0,255,223,13,0,255,255,255,\n255,255,255,207,255,255,1,128,16,255,3,0,0,0,0,255,3,255,255,255,255,255,255,\n255,255,255,255,255,1,255,255,255,255,255,7,255,255,255,255,255,255,255,255,\n63,\n0,255,255,255,127,255,15,255,1,192,255,255,255,255,63,31,0,255,255,255,255,\n255,15,255,255,255,3,255,3,0,0,0,0,255,255,255,15,255,255,255,255,255,255,255,\n127,254,255,31,0,255,3,255,3,128,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,\n255,239,255,239,15,255,3,0,0,0,0,255,255,255,255,255,243,255,255,255,255,255,\n255,191,255,3,0,255,255,255,255,255,255,127,0,255,227,255,255,255,255,255,63,\n255,1,255,255,255,255,255,231,0,0,0,0,0,222,111,4,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,\n128,255,31,0,255,255,63,63,255,255,255,255,63,63,255,170,255,255,255,63,255,\n255,255,255,255,255,223,95,220,31,207,15,255,31,220,31,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,2,128,0,0,255,31,0,0,0,0,0,0,0,0,0,0,0,0,132,252,47,62,80,189,255,243,\n224,67,0,0,255,255,255,255,255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,255,255,255,255,255,255,3,0,\n0,255,255,255,255,255,127,255,255,255,255,255,127,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,31,120,12,0,255,255,255,255,191,32,255,\n255,255,255,255,255,255,128,0,0,255,255,127,0,127,127,127,127,127,127,127,127,\n255,255,255,255,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,224,0,0,0,254,3,62,31,254,255,255,255,255,255,255,255,255,255,127,224,254,\n255,255,255,255,255,255,255,255,255,255,247,224,255,255,255,255,255,254,255,\n255,255,255,255,255,255,255,255,255,127,0,0,255,255,255,7,0,0,0,0,0,0,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,63,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,\n0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,31,0,0,\n0,0,0,0,0,0,255,255,255,255,255,63,255,31,255,255,255,15,0,0,255,255,255,255,\n255,127,240,143,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,\n0,128,255,252,255,255,255,255,255,255,255,255,255,255,255,255,249,255,255,255,\n255,255,255,124,0,0,0,0,0,128,255,191,255,255,255,255,0,0,0,255,255,255,255,\n255,255,15,0,255,255,255,255,255,255,255,255,47,0,255,3,0,0,252,232,255,255,\n255,255,255,7,255,255,255,255,7,0,255,255,255,31,255,255,255,255,255,255,247,\n255,0,128,255,3,255,255,255,127,255,255,255,255,255,255,127,0,255,63,255,3,\n255,255,127,252,255,255,255,255,255,255,255,127,5,0,0,56,255,255,60,0,126,126,\n126,0,127,127,255,255,255,255,255,247,255,0,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,7,255,3,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,15,0,255,255,127,248,255,255,255,255,\n255,\n15,255,255,255,255,255,255,255,255,255,255,255,255,255,63,255,255,255,255,255,\n255,255,255,255,255,255,255,255,3,0,0,0,0,127,0,248,224,255,253,127,95,219,\n255,255,255,255,255,255,255,255,255,255,255,255,255,3,0,0,0,248,255,255,255,\n255,255,255,255,255,255,255,255,255,63,0,0,255,255,255,255,255,255,255,255,\n252,255,255,255,255,255,255,0,0,0,0,0,255,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,223,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,31,0,0,255,3,\n254,255,255,7,254,255,255,7,192,255,255,255,255,255,255,255,255,255,255,127,\n252,252,252,28,0,0,0,0,255,239,255,255,127,255,255,183,255,63,255,63,0,0,0,0,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,7,0,0,0,0,0,0,0,0,\n255,255,255,255,255,255,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,255,255,255,31,255,255,255,255,255,255,1,0,0,0,0,\n0,255,255,255,255,0,224,255,255,255,7,255,255,255,255,255,7,255,255,255,63,\n255,255,255,255,15,255,62,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,63,255,3,255,255,255,255,15,255,255,255,\n255,15,255,255,255,255,255,0,255,255,255,255,255,255,15,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,255,255,255,255,255,255,127,0,255,255,63,0,255,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,63,253,255,255,255,255,191,145,255,255,63,0,255,255,\n127,0,255,255,255,127,0,0,0,0,0,0,0,0,255,255,55,0,255,255,63,0,255,255,255,3,\n0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,192,0,0,0,0,0,0,0,0,111,240,239,\n254,255,255,63,0,0,0,0,0,255,255,255,31,255,255,255,31,0,0,0,0,255,254,255,\n255,31,0,0,0,255,255,255,255,255,255,63,0,255,255,63,0,255,255,7,0,255,255,3,\n0,0,0,0,0,0,0,0,0,0,0,0,\n0,255,255,255,255,255,255,255,255,255,1,0,0,0,0,0,0,255,255,255,255,255,255,7,\n0,255,255,255,255,255,255,7,0,255,255,255,255,255,0,255,3,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,31,128,0,255,255,63,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,255,255,127,0,255,255,255,255,255,255,255,255,63,0,0,0,\n192,255,0,0,252,255,255,255,255,255,255,1,0,0,255,255,255,1,255,3,255,255,255,\n255,255,255,199,255,112,0,255,255,255,255,71,0,255,255,255,255,255,255,255,\n255,30,0,255,23,0,0,0,0,255,255,251,255,255,255,159,64,0,0,0,0,0,0,0,0,127,\n189,255,191,255,1,255,255,255,255,255,255,255,1,255,3,239,159,249,255,255,253,\n237,227,159,25,129,224,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,\n255,255,255,255,255,187,7,255,131,0,0,0,0,255,255,255,255,255,255,255,255,179,\n0,255,3,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,63,127,0,0,0,63,0,0,\n0,0,255,255,255,255,255,255,255,127,17,0,255,3,0,0,0,0,255,255,255,255,255,\n255,63,1,255,3,0,0,0,0,0,0,255,255,255,231,255,7,255,3,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,1,0,0,0,0,0,0,0,0,0,0,0,\n0,255,255,255,255,255,255,255,255,255,3,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,255,252,255,255,255,255,255,252,26,0,0,0,255,255,255,255,255,255,231,\n127,0,0,255,255,255,255,255,255,255,255,255,32,0,0,0,0,255,255,255,255,255,\n255,255,1,255,253,255,255,255,255,127,127,1,0,255,3,0,0,252,255,255,255,252,\n255,255,254,127,0,0,0,0,0,0,0,0,0,127,251,255,255,255,255,127,180,203,0,255,3,\n191,253,255,255,255,127,123,1,255,3,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,127,0,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,3,0,0,\n0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,127,0,\n0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,\n255,255,255,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,\n255,255,255,255,255,255,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,\n255,255,255,255,255,255,1,255,255,255,127,255,3,0,0,0,0,0,0,0,0,0,0,0,0,255,\n255,255,63,0,0,255,255,255,255,255,255,0,0,15,0,255,3,248,255,255,224,255,255,\n0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,255,255,255,255,255,255,255,255,255,135,255,255,255,255,255,255,255,128,\n255,255,0,0,0,0,0,0,0,0,11,0,0,0,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,7,0,255,255,255,127,0,0,0,0,0,\n0,7,0,240,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,15,255,255,255,255,\n255,255,255,255,255,255,255,255,255,7,255,31,255,1,255,67,0,0,0,0,0,0,0,0,0,0,\n0,0,255,255,255,255,255,255,255,255,255,255,223,255,255,255,255,255,255,255,\n255,223,100,222,255,235,239,255,255,255,255,255,255,\n255,191,231,223,223,255,255,255,123,95,252,253,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,63,255,255,255,\n253,255,255,247,255,255,255,247,255,255,223,255,255,255,223,255,255,127,255,\n255,255,127,255,255,255,253,255,255,255,253,255,255,247,207,255,255,255,255,\n255,255,127,255,255,249,219,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,255,255,255,255,255,31,128,63,255,67,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,\n15,255,3,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,31,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,\n143,8,255,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,239,255,255,255,150,254,247,10,132,234,150,170,150,247,247,94,255,251,255,\n15,238,251,255,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,3,255,255,255,3,255,\n255,255,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n"
  },
  {
    "path": "user.libc/src/ctype/casemap.h",
    "content": "static const unsigned char tab[] = {\n\t7, 8, 9, 10, 11, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t13, 6, 6, 14, 6, 6, 6, 6, 6, 6, 6, 6, 15, 16, 17, 18,\n\t6, 19, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 20, 21, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 22, 23, 6, 6, 6, 24, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 25,\n\t6, 6, 6, 6, 26, 6, 6, 6, 6, 6, 6, 6, 27, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 28, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 29, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 30, 6, 6, 6, 6, 6, 6,\n\t6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36,\n\t43, 43, 43, 43, 43, 43, 43, 43, 1, 0, 84, 86, 86, 86, 86, 86,\n\t86, 86, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 43, 43, 43, 43, 43, 43,\n\t43, 7, 43, 43, 91, 86, 86, 86, 86, 86, 86, 86, 74, 86, 86, 5,\n\t49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80,\n\t36, 80, 121, 49, 80, 49, 80, 49, 56, 80, 49, 80, 49, 80, 49, 80,\n\t49, 80, 49, 80, 49, 80, 49, 80, 78, 49, 2, 78, 13, 13, 78, 3,\n\t78, 0, 36, 110, 0, 78, 49, 38, 110, 81, 78, 36, 80, 78, 57, 20,\n\t129, 27, 29, 29, 83, 49, 80, 49, 80, 13, 49, 80, 49, 80, 49, 80,\n\t27, 83, 36, 80, 49, 2, 92, 123, 92, 123, 92, 123, 92, 123, 92, 123,\n\t20, 121, 92, 123, 92, 123, 92, 45, 43, 73, 3, 72, 3, 120, 92, 123,\n\t20, 0, 150, 10, 1, 43, 40, 6, 6, 0, 42, 6, 42, 42, 43, 7,\n\t187, 181, 43, 30, 0, 43, 7, 43, 43, 43, 1, 43, 43, 43, 43, 43,\n\t43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,\n\t43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 1, 43, 43, 43, 43,\n\t43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,\n\t43, 43, 43, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,\n\t43, 205, 70, 205, 43, 0, 37, 43, 7, 1, 6, 1, 85, 86, 86, 86,\n\t86, 86, 85, 86, 86, 2, 36, 129, 129, 129, 129, 129, 21, 129, 129, 129,\n\t0, 0, 43, 0, 178, 209, 178, 209, 178, 209, 178, 209, 0, 0, 205, 204,\n\t1, 0, 215, 215, 215, 215, 215, 131, 129, 129, 129, 129, 129, 129, 129, 129,\n\t129, 129, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 28, 0, 0, 0,\n\t0, 0, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 2, 0, 0,\n\t49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80,\n\t49, 80, 78, 49, 80, 49, 80, 78, 49, 80, 49, 80, 49, 80, 49, 80,\n\t49, 80, 49, 80, 49, 80, 49, 2, 135, 166, 135, 166, 135, 166, 135, 166,\n\t135, 166, 135, 166, 135, 166, 135, 166, 42, 43, 43, 43, 43, 43, 43, 43,\n\t43, 43, 43, 43, 43, 0, 0, 0, 84, 86, 86, 86, 86, 86, 86, 86,\n\t86, 86, 86, 86, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 84, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,\n\t12, 0, 12, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,\n\t43, 7, 42, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 43, 43, 43, 43, 43, 43,\n\t43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,\n\t43, 43, 43, 43, 86, 86, 108, 129, 21, 0, 43, 43, 43, 43, 43, 43,\n\t43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,\n\t43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,\n\t43, 43, 43, 43, 7, 108, 3, 65, 43, 43, 86, 86, 86, 86, 86, 86,\n\t86, 86, 86, 86, 86, 86, 86, 86, 44, 86, 43, 43, 43, 43, 43, 43,\n\t43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 1,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 12, 108, 0, 0, 0, 0, 0, 6,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37,\n\t6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37,\n\t6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37,\n\t6, 37, 6, 37, 6, 37, 6, 37, 86, 122, 158, 38, 6, 37, 6, 37,\n\t6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 37,\n\t6, 37, 6, 37, 6, 37, 6, 37, 6, 37, 6, 1, 43, 43, 79, 86,\n\t86, 44, 43, 127, 86, 86, 57, 43, 43, 85, 86, 86, 43, 43, 79, 86,\n\t86, 44, 43, 127, 86, 86, 129, 55, 117, 91, 123, 92, 43, 43, 79, 86,\n\t86, 2, 172, 4, 0, 0, 57, 43, 43, 85, 86, 86, 43, 43, 79, 86,\n\t86, 44, 43, 43, 86, 86, 50, 19, 129, 87, 0, 111, 129, 126, 201, 215,\n\t126, 45, 129, 129, 14, 126, 57, 127, 111, 87, 0, 129, 129, 126, 21, 0,\n\t126, 3, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 7, 43,\n\t36, 43, 151, 43, 43, 43, 43, 43, 43, 43, 43, 43, 42, 43, 43, 43,\n\t43, 43, 86, 86, 86, 86, 86, 128, 129, 129, 129, 129, 57, 187, 42, 43,\n\t43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,\n\t43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,\n\t43, 43, 43, 43, 43, 43, 43, 1, 129, 129, 129, 129, 129, 129, 129, 129,\n\t129, 129, 129, 129, 129, 129, 129, 201, 172, 172, 172, 172, 172, 172, 172, 172,\n\t172, 172, 172, 172, 172, 172, 172, 208, 13, 0, 78, 49, 2, 180, 193, 193,\n\t215, 215, 36, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80,\n\t49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80, 49, 80,\n\t49, 80, 49, 80, 215, 215, 83, 193, 71, 212, 215, 215, 215, 5, 43, 43,\n\t43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 7, 1, 0, 1, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 49, 80, 49, 80, 49, 80,\n\t49, 80, 49, 80, 49, 80, 49, 80, 13, 0, 0, 0, 0, 0, 36, 80,\n\t49, 80, 49, 80, 49, 80, 49, 80, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 43, 43, 43, 43, 43,\n\t43, 43, 43, 43, 43, 121, 92, 123, 92, 123, 79, 123, 92, 123, 92, 123,\n\t92, 123, 92, 123, 92, 123, 92, 123, 92, 123, 92, 123, 92, 123, 92, 45,\n\t43, 43, 121, 20, 92, 123, 92, 45, 121, 42, 92, 39, 92, 123, 92, 123,\n\t92, 123, 164, 0, 10, 180, 92, 123, 92, 123, 79, 3, 42, 43, 43, 43,\n\t43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 1,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,\n\t43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 43, 43, 43, 43, 43, 43, 43, 43, 7, 0, 72, 86, 86, 86, 86,\n\t86, 86, 86, 86, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 43, 43, 43,\n\t43, 43, 43, 43, 43, 43, 43, 43, 43, 85, 86, 86, 86, 86, 86, 86,\n\t86, 86, 86, 86, 86, 86, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 36, 43, 43, 43, 43, 43, 43, 43, 43, 43,\n\t43, 43, 7, 0, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 43, 43, 43,\n\t43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 7, 0, 0,\n\t0, 0, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,\n\t86, 86, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 43, 43,\n\t43, 43, 43, 43, 43, 43, 43, 43, 86, 86, 86, 86, 86, 86, 86, 86,\n\t86, 86, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 86, 86,\n\t86, 86, 86, 86, 86, 86, 86, 86, 14, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 85,\n\t86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 14, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n};\nstatic const int rules[] = {\n\t0x0, 0x2001, -0x2000, 0x1dbf00, 0x2e700, 0x7900,\n\t0x2402, 0x101, -0x100, 0x0, 0x201, -0x200,\n\t-0xc6ff, -0xe800, -0x78ff, -0x12c00, 0xc300, 0xd201,\n\t0xce01, 0xcd01, 0x4f01, 0xca01, 0xcb01, 0xcf01,\n\t0x6100, 0xd301, 0xd101, 0xa300, 0xd501, 0x8200,\n\t0xd601, 0xda01, 0xd901, 0xdb01, 0x3800, 0x3,\n\t-0x4f00, -0x60ff, -0x37ff, 0x242802, 0x0, 0x101,\n\t-0x100, -0xcd00, -0xda00, -0x81ff, 0x2a2b01, -0xa2ff,\n\t0x2a2801, 0x2a3f00, -0xc2ff, 0x4501, 0x4701, 0x2a1f00,\n\t0x2a1c00, 0x2a1e00, -0xd200, -0xce00, -0xca00, -0xcb00,\n\t0xa54f00, 0xa54b00, -0xcf00, 0xa52800, 0xa54400, -0xd100,\n\t-0xd300, 0x29f700, 0xa54100, 0x29fd00, -0xd500, -0xd600,\n\t0x29e700, 0xa54300, 0xa52a00, -0x4500, -0xd900, -0x4700,\n\t-0xdb00, 0xa51500, 0xa51200, 0x4c2402, 0x0, 0x2001,\n\t-0x2000, 0x101, -0x100, 0x5400, 0x7401, 0x2601,\n\t0x2501, 0x4001, 0x3f01, -0x2600, -0x2500, -0x1f00,\n\t-0x4000, -0x3f00, 0x801, -0x3e00, -0x3900, -0x2f00,\n\t-0x3600, -0x800, -0x5600, -0x5000, 0x700, -0x7400,\n\t-0x3bff, -0x6000, -0x6ff, 0x701a02, 0x101, -0x100,\n\t0x2001, -0x2000, 0x5001, 0xf01, -0xf00, 0x0,\n\t0x3001, -0x3000, 0x101, -0x100, 0x0, 0xbc000,\n\t0x1c6001, 0x0, 0x97d001, 0x801, -0x800, 0x8a0502,\n\t0x0, -0xbbfff, -0x186200, 0x89c200, -0x182500, -0x186e00,\n\t-0x186d00, -0x186400, -0x186300, -0x185c00, 0x0, 0x8a3800,\n\t0x8a0400, 0xee600, 0x101, -0x100, 0x0, -0x3b00,\n\t-0x1dbeff, 0x8f1d02, 0x800, -0x7ff, 0x0, 0x5600,\n\t-0x55ff, 0x4a00, 0x6400, 0x8000, 0x7000, 0x7e00,\n\t0x900, -0x49ff, -0x8ff, -0x1c2500, -0x63ff, -0x6fff,\n\t-0x7fff, -0x7dff, 0xac0502, 0x0, 0x1001, -0x1000,\n\t0x1c01, 0x101, -0x1d5cff, -0x20beff, -0x2045ff, -0x1c00,\n\t0xb10b02, 0x101, -0x100, 0x3001, -0x3000, 0x0,\n\t-0x29f6ff, -0xee5ff, -0x29e6ff, -0x2a2b00, -0x2a2800, -0x2a1bff,\n\t-0x29fcff, -0x2a1eff, -0x2a1dff, -0x2a3eff, 0x0, -0x1c6000,\n\t0x0, 0x101, -0x100, 0xbc0c02, 0x0, 0x101,\n\t-0x100, -0xa543ff, 0x3a001, -0x8a03ff, -0xa527ff, 0x3000,\n\t-0xa54eff, -0xa54aff, -0xa540ff, -0xa511ff, -0xa529ff, -0xa514ff,\n\t-0x2fff, -0xa542ff, -0x8a37ff, 0x0, -0x97d000, -0x3a000,\n\t0x0, 0x2001, -0x2000, 0x0, 0x2801, -0x2800,\n\t0x0, 0x4001, -0x4000, 0x0, 0x2001, -0x2000,\n\t0x0, 0x2001, -0x2000, 0x0, 0x2201, -0x2200,\n};\nstatic const unsigned char rulebases[] = {\n\t0, 6, 39, 81, 111, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t124, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 0, 131, 142, 146, 151,\n\t0, 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 196, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 198, 201, 0, 0, 0, 219, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 222,\n\t0, 0, 0, 0, 225, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n};\nstatic const unsigned char exceptions[][2] = {\n\t{ 48, 12 }, { 49, 13 }, { 120, 14 }, { 127, 15 },\n\t{ 128, 16 }, { 129, 17 }, { 134, 18 }, { 137, 19 },\n\t{ 138, 19 }, { 142, 20 }, { 143, 21 }, { 144, 22 },\n\t{ 147, 19 }, { 148, 23 }, { 149, 24 }, { 150, 25 },\n\t{ 151, 26 }, { 154, 27 }, { 156, 25 }, { 157, 28 },\n\t{ 158, 29 }, { 159, 30 }, { 166, 31 }, { 169, 31 },\n\t{ 174, 31 }, { 177, 32 }, { 178, 32 }, { 183, 33 },\n\t{ 191, 34 }, { 197, 35 }, { 200, 35 }, { 203, 35 },\n\t{ 221, 36 }, { 242, 35 }, { 246, 37 }, { 247, 38 },\n\t{ 32, 45 }, { 58, 46 }, { 61, 47 }, { 62, 48 },\n\t{ 63, 49 }, { 64, 49 }, { 67, 50 }, { 68, 51 },\n\t{ 69, 52 }, { 80, 53 }, { 81, 54 }, { 82, 55 },\n\t{ 83, 56 }, { 84, 57 }, { 89, 58 }, { 91, 59 },\n\t{ 92, 60 }, { 97, 61 }, { 99, 62 }, { 101, 63 },\n\t{ 102, 64 }, { 104, 65 }, { 105, 66 }, { 106, 64 },\n\t{ 107, 67 }, { 108, 68 }, { 111, 66 }, { 113, 69 },\n\t{ 114, 70 }, { 117, 71 }, { 125, 72 }, { 130, 73 },\n\t{ 135, 74 }, { 137, 75 }, { 138, 76 }, { 139, 76 },\n\t{ 140, 77 }, { 146, 78 }, { 157, 79 }, { 158, 80 },\n\t{ 69, 87 }, { 123, 29 }, { 124, 29 }, { 125, 29 },\n\t{ 127, 88 }, { 134, 89 }, { 136, 90 }, { 137, 90 },\n\t{ 138, 90 }, { 140, 91 }, { 142, 92 }, { 143, 92 },\n\t{ 172, 93 }, { 173, 94 }, { 174, 94 }, { 175, 94 },\n\t{ 194, 95 }, { 204, 96 }, { 205, 97 }, { 206, 97 },\n\t{ 207, 98 }, { 208, 99 }, { 209, 100 }, { 213, 101 },\n\t{ 214, 102 }, { 215, 103 }, { 240, 104 }, { 241, 105 },\n\t{ 242, 106 }, { 243, 107 }, { 244, 108 }, { 245, 109 },\n\t{ 249, 110 }, { 253, 45 }, { 254, 45 }, { 255, 45 },\n\t{ 80, 105 }, { 81, 105 }, { 82, 105 }, { 83, 105 },\n\t{ 84, 105 }, { 85, 105 }, { 86, 105 }, { 87, 105 },\n\t{ 88, 105 }, { 89, 105 }, { 90, 105 }, { 91, 105 },\n\t{ 92, 105 }, { 93, 105 }, { 94, 105 }, { 95, 105 },\n\t{ 130, 0 }, { 131, 0 }, { 132, 0 }, { 133, 0 },\n\t{ 134, 0 }, { 135, 0 }, { 136, 0 }, { 137, 0 },\n\t{ 192, 117 }, { 207, 118 }, { 128, 137 }, { 129, 138 },\n\t{ 130, 139 }, { 133, 140 }, { 134, 141 }, { 112, 157 },\n\t{ 113, 157 }, { 118, 158 }, { 119, 158 }, { 120, 159 },\n\t{ 121, 159 }, { 122, 160 }, { 123, 160 }, { 124, 161 },\n\t{ 125, 161 }, { 179, 162 }, { 186, 163 }, { 187, 163 },\n\t{ 188, 164 }, { 190, 165 }, { 195, 162 }, { 204, 164 },\n\t{ 218, 166 }, { 219, 166 }, { 229, 106 }, { 234, 167 },\n\t{ 235, 167 }, { 236, 110 }, { 243, 162 }, { 248, 168 },\n\t{ 249, 168 }, { 250, 169 }, { 251, 169 }, { 252, 164 },\n\t{ 38, 176 }, { 42, 177 }, { 43, 178 }, { 78, 179 },\n\t{ 132, 8 }, { 98, 186 }, { 99, 187 }, { 100, 188 },\n\t{ 101, 189 }, { 102, 190 }, { 109, 191 }, { 110, 192 },\n\t{ 111, 193 }, { 112, 194 }, { 126, 195 }, { 127, 195 },\n\t{ 125, 207 }, { 141, 208 }, { 148, 209 }, { 171, 210 },\n\t{ 172, 211 }, { 173, 212 }, { 176, 213 }, { 177, 214 },\n\t{ 178, 215 }, { 196, 216 }, { 197, 217 }, { 198, 218 },\n};\n"
  },
  {
    "path": "user.libc/src/ctype/isalnum.c",
    "content": "#include <ctype.h>\n\nint isalnum(int c)\n{\n\treturn isalpha(c) || isdigit(c);\n}\n\nint __isalnum_l(int c, locale_t l)\n{\n\treturn isalnum(c);\n}\n\nweak_alias(__isalnum_l, isalnum_l);\n"
  },
  {
    "path": "user.libc/src/ctype/isalpha.c",
    "content": "#include <ctype.h>\n#undef isalpha\n\nint isalpha(int c)\n{\n\treturn ((unsigned)c|32)-'a' < 26;\n}\n\nint __isalpha_l(int c, locale_t l)\n{\n\treturn isalpha(c);\n}\n\nweak_alias(__isalpha_l, isalpha_l);\n"
  },
  {
    "path": "user.libc/src/ctype/isascii.c",
    "content": "#include <ctype.h>\n#undef isascii\n\nint isascii(int c)\n{\n\treturn !(c&~0x7f);\n}\n"
  },
  {
    "path": "user.libc/src/ctype/isblank.c",
    "content": "#include <ctype.h>\n\nint isblank(int c)\n{\n\treturn (c == ' ' || c == '\\t');\n}\n\nint __isblank_l(int c, locale_t l)\n{\n\treturn isblank(c);\n}\n\nweak_alias(__isblank_l, isblank_l);\n"
  },
  {
    "path": "user.libc/src/ctype/iscntrl.c",
    "content": "#include <ctype.h>\n\nint iscntrl(int c)\n{\n\treturn (unsigned)c < 0x20 || c == 0x7f;\n}\n\nint __iscntrl_l(int c, locale_t l)\n{\n\treturn iscntrl(c);\n}\n\nweak_alias(__iscntrl_l, iscntrl_l);\n"
  },
  {
    "path": "user.libc/src/ctype/isdigit.c",
    "content": "#include <ctype.h>\n#undef isdigit\n\nint isdigit(int c)\n{\n\treturn (unsigned)c-'0' < 10;\n}\n\nint __isdigit_l(int c, locale_t l)\n{\n\treturn isdigit(c);\n}\n\nweak_alias(__isdigit_l, isdigit_l);\n"
  },
  {
    "path": "user.libc/src/ctype/isgraph.c",
    "content": "#include <ctype.h>\n#undef isgraph\n\nint isgraph(int c)\n{\n\treturn (unsigned)c-0x21 < 0x5e;\n}\n\nint __isgraph_l(int c, locale_t l)\n{\n\treturn isgraph(c);\n}\n\nweak_alias(__isgraph_l, isgraph_l);\n"
  },
  {
    "path": "user.libc/src/ctype/islower.c",
    "content": "#include <ctype.h>\n#undef islower\n\nint islower(int c)\n{\n\treturn (unsigned)c-'a' < 26;\n}\n\nint __islower_l(int c, locale_t l)\n{\n\treturn islower(c);\n}\n\nweak_alias(__islower_l, islower_l);\n"
  },
  {
    "path": "user.libc/src/ctype/isprint.c",
    "content": "#include <ctype.h>\n#undef isprint\n\nint isprint(int c)\n{\n\treturn (unsigned)c-0x20 < 0x5f;\n}\n\nint __isprint_l(int c, locale_t l)\n{\n\treturn isprint(c);\n}\n\nweak_alias(__isprint_l, isprint_l);\n"
  },
  {
    "path": "user.libc/src/ctype/ispunct.c",
    "content": "#include <ctype.h>\n\nint ispunct(int c)\n{\n\treturn isgraph(c) && !isalnum(c);\n}\n\nint __ispunct_l(int c, locale_t l)\n{\n\treturn ispunct(c);\n}\n\nweak_alias(__ispunct_l, ispunct_l);\n"
  },
  {
    "path": "user.libc/src/ctype/isspace.c",
    "content": "#include <ctype.h>\n#undef isspace\n\nint isspace(int c)\n{\n\treturn c == ' ' || (unsigned)c-'\\t' < 5;\n}\n\nint __isspace_l(int c, locale_t l)\n{\n\treturn isspace(c);\n}\n\nweak_alias(__isspace_l, isspace_l);\n"
  },
  {
    "path": "user.libc/src/ctype/isupper.c",
    "content": "#include <ctype.h>\n#undef isupper\n\nint isupper(int c)\n{\n\treturn (unsigned)c-'A' < 26;\n}\n\nint __isupper_l(int c, locale_t l)\n{\n\treturn isupper(c);\n}\n\nweak_alias(__isupper_l, isupper_l);\n"
  },
  {
    "path": "user.libc/src/ctype/iswalnum.c",
    "content": "#include <wctype.h>\n\nint iswalnum(wint_t wc)\n{\n\treturn iswdigit(wc) || iswalpha(wc);\n}\n\nint __iswalnum_l(wint_t c, locale_t l)\n{\n\treturn iswalnum(c);\n}\n\nweak_alias(__iswalnum_l, iswalnum_l);\n"
  },
  {
    "path": "user.libc/src/ctype/iswalpha.c",
    "content": "#include <wctype.h>\n\nstatic const unsigned char table[] = {\n#include \"alpha.h\"\n};\n\nint iswalpha(wint_t wc)\n{\n\tif (wc<0x20000U)\n\t\treturn (table[table[wc>>8]*32+((wc&255)>>3)]>>(wc&7))&1;\n\tif (wc<0x2fffeU)\n\t\treturn 1;\n\treturn 0;\n}\n\nint __iswalpha_l(wint_t c, locale_t l)\n{\n\treturn iswalpha(c);\n}\n\nweak_alias(__iswalpha_l, iswalpha_l);\n"
  },
  {
    "path": "user.libc/src/ctype/iswblank.c",
    "content": "#include <wctype.h>\n#include <ctype.h>\n\nint iswblank(wint_t wc)\n{\n\treturn isblank(wc);\n}\n\nint __iswblank_l(wint_t c, locale_t l)\n{\n\treturn iswblank(c);\n}\n\nweak_alias(__iswblank_l, iswblank_l);\n"
  },
  {
    "path": "user.libc/src/ctype/iswcntrl.c",
    "content": "#include <wctype.h>\n\nint iswcntrl(wint_t wc)\n{\n\treturn (unsigned)wc < 32\n\t    || (unsigned)(wc-0x7f) < 33\n\t    || (unsigned)(wc-0x2028) < 2\n\t    || (unsigned)(wc-0xfff9) < 3;\n}\n\nint __iswcntrl_l(wint_t c, locale_t l)\n{\n\treturn iswcntrl(c);\n}\n\nweak_alias(__iswcntrl_l, iswcntrl_l);\n"
  },
  {
    "path": "user.libc/src/ctype/iswctype.c",
    "content": "#include <wctype.h>\n#include <string.h>\n\n#define WCTYPE_ALNUM  1\n#define WCTYPE_ALPHA  2\n#define WCTYPE_BLANK  3\n#define WCTYPE_CNTRL  4\n#define WCTYPE_DIGIT  5\n#define WCTYPE_GRAPH  6\n#define WCTYPE_LOWER  7\n#define WCTYPE_PRINT  8\n#define WCTYPE_PUNCT  9\n#define WCTYPE_SPACE  10\n#define WCTYPE_UPPER  11\n#define WCTYPE_XDIGIT 12\n\nint iswctype(wint_t wc, wctype_t type)\n{\n\tswitch (type) {\n\tcase WCTYPE_ALNUM:\n\t\treturn iswalnum(wc);\n\tcase WCTYPE_ALPHA:\n\t\treturn iswalpha(wc);\n\tcase WCTYPE_BLANK:\n\t\treturn iswblank(wc);\n\tcase WCTYPE_CNTRL:\n\t\treturn iswcntrl(wc);\n\tcase WCTYPE_DIGIT:\n\t\treturn iswdigit(wc);\n\tcase WCTYPE_GRAPH:\n\t\treturn iswgraph(wc);\n\tcase WCTYPE_LOWER:\n\t\treturn iswlower(wc);\n\tcase WCTYPE_PRINT:\n\t\treturn iswprint(wc);\n\tcase WCTYPE_PUNCT:\n\t\treturn iswpunct(wc);\n\tcase WCTYPE_SPACE:\n\t\treturn iswspace(wc);\n\tcase WCTYPE_UPPER:\n\t\treturn iswupper(wc);\n\tcase WCTYPE_XDIGIT:\n\t\treturn iswxdigit(wc);\n\t}\n\treturn 0;\n}\n\nwctype_t wctype(const char *s)\n{\n\tint i;\n\tconst char *p;\n\t/* order must match! */\n\tstatic const char names[] =\n\t\t\"alnum\\0\" \"alpha\\0\" \"blank\\0\"\n\t\t\"cntrl\\0\" \"digit\\0\" \"graph\\0\"\n\t\t\"lower\\0\" \"print\\0\" \"punct\\0\"\n\t\t\"space\\0\" \"upper\\0\" \"xdigit\";\n\tfor (i=1, p=names; *p; i++, p+=6)\n\t\tif (*s == *p && !strcmp(s, p))\n\t\t\treturn i;\n\treturn 0;\n}\n\nint __iswctype_l(wint_t c, wctype_t t, locale_t l)\n{\n\treturn iswctype(c, t);\n}\n\nwctype_t __wctype_l(const char *s, locale_t l)\n{\n\treturn wctype(s);\n}\n\nweak_alias(__iswctype_l, iswctype_l);\nweak_alias(__wctype_l, wctype_l);\n"
  },
  {
    "path": "user.libc/src/ctype/iswdigit.c",
    "content": "#include <wctype.h>\n\n#undef iswdigit\n\nint iswdigit(wint_t wc)\n{\n\treturn (unsigned)wc-'0' < 10;\n}\n\nint __iswdigit_l(wint_t c, locale_t l)\n{\n\treturn iswdigit(c);\n}\n\nweak_alias(__iswdigit_l, iswdigit_l);\n"
  },
  {
    "path": "user.libc/src/ctype/iswgraph.c",
    "content": "#include <wctype.h>\n\nint iswgraph(wint_t wc)\n{\n\t/* ISO C defines this function as: */\n\treturn !iswspace(wc) && iswprint(wc);\n}\n\nint __iswgraph_l(wint_t c, locale_t l)\n{\n\treturn iswgraph(c);\n}\n\nweak_alias(__iswgraph_l, iswgraph_l);\n"
  },
  {
    "path": "user.libc/src/ctype/iswlower.c",
    "content": "#include <wctype.h>\n\nint iswlower(wint_t wc)\n{\n\treturn towupper(wc) != wc;\n}\n\nint __iswlower_l(wint_t c, locale_t l)\n{\n\treturn iswlower(c);\n}\n\nweak_alias(__iswlower_l, iswlower_l);\n"
  },
  {
    "path": "user.libc/src/ctype/iswprint.c",
    "content": "#include <wctype.h>\n\n/* Consider all legal codepoints as printable except for:\n * - C0 and C1 control characters\n * - U+2028 and U+2029 (line/para break)\n * - U+FFF9 through U+FFFB (interlinear annotation controls)\n * The following code is optimized heavily to make hot paths for the\n * expected printable characters. */\n\nint iswprint(wint_t wc)\n{\n\tif (wc < 0xffU)\n\t\treturn (wc+1 & 0x7f) >= 0x21;\n\tif (wc < 0x2028U || wc-0x202aU < 0xd800-0x202a || wc-0xe000U < 0xfff9-0xe000)\n\t\treturn 1;\n\tif (wc-0xfffcU > 0x10ffff-0xfffc || (wc&0xfffe)==0xfffe)\n\t\treturn 0;\n\treturn 1;\n}\n\nint __iswprint_l(wint_t c, locale_t l)\n{\n\treturn iswprint(c);\n}\n\nweak_alias(__iswprint_l, iswprint_l);\n"
  },
  {
    "path": "user.libc/src/ctype/iswpunct.c",
    "content": "#include <wctype.h>\n\nstatic const unsigned char table[] = {\n#include \"punct.h\"\n};\n\nint iswpunct(wint_t wc)\n{\n\tif (wc<0x20000U)\n\t\treturn (table[table[wc>>8]*32+((wc&255)>>3)]>>(wc&7))&1;\n\treturn 0;\n}\n\nint __iswpunct_l(wint_t c, locale_t l)\n{\n\treturn iswpunct(c);\n}\n\nweak_alias(__iswpunct_l, iswpunct_l);\n"
  },
  {
    "path": "user.libc/src/ctype/iswspace.c",
    "content": "#include <wchar.h>\n#include <wctype.h>\n\n/* Our definition of whitespace is the Unicode White_Space property,\n * minus non-breaking spaces (U+00A0, U+2007, and U+202F) and script-\n * specific characters with non-blank glyphs (U+1680 and U+180E). */\n\nint iswspace(wint_t wc)\n{\n\tstatic const wchar_t spaces[] = {\n\t\t' ', '\\t', '\\n', '\\r', 11, 12,  0x0085,\n\t\t0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005,\n\t\t0x2006, 0x2008, 0x2009, 0x200a,\n\t\t0x2028, 0x2029, 0x205f, 0x3000, 0\n\t};\n\treturn wc && wcschr(spaces, wc);\n}\n\nint __iswspace_l(wint_t c, locale_t l)\n{\n\treturn iswspace(c);\n}\n\nweak_alias(__iswspace_l, iswspace_l);\n"
  },
  {
    "path": "user.libc/src/ctype/iswupper.c",
    "content": "#include <wctype.h>\n\nint iswupper(wint_t wc)\n{\n\treturn towlower(wc) != wc;\n}\n\nint __iswupper_l(wint_t c, locale_t l)\n{\n\treturn iswupper(c);\n}\n\nweak_alias(__iswupper_l, iswupper_l);\n"
  },
  {
    "path": "user.libc/src/ctype/iswxdigit.c",
    "content": "#include <wctype.h>\n\nint iswxdigit(wint_t wc)\n{\n\treturn (unsigned)(wc-'0') < 10 || (unsigned)((wc|32)-'a') < 6;\n}\n\nint __iswxdigit_l(wint_t c, locale_t l)\n{\n\treturn iswxdigit(c);\n}\n\nweak_alias(__iswxdigit_l, iswxdigit_l);\n"
  },
  {
    "path": "user.libc/src/ctype/isxdigit.c",
    "content": "#include <ctype.h>\n\nint isxdigit(int c)\n{\n\treturn isdigit(c) || ((unsigned)c|32)-'a' < 6;\n}\n\nint __isxdigit_l(int c, locale_t l)\n{\n\treturn isxdigit(c);\n}\n\nweak_alias(__isxdigit_l, isxdigit_l);\n"
  },
  {
    "path": "user.libc/src/ctype/nonspacing.h",
    "content": "16,16,16,18,19,20,21,22,23,24,25,26,27,28,29,30,31,16,16,32,16,16,16,33,34,35,\n36,37,38,39,16,16,40,16,16,16,16,16,16,16,16,16,16,16,41,42,16,16,43,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,44,16,45,46,47,48,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,49,16,16,50,\n51,16,52,53,54,16,16,16,16,16,16,55,16,16,56,16,57,58,59,60,61,62,63,64,65,66,\n67,68,16,69,70,71,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,72,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,73,74,16,16,16,75,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,76,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,77,78,16,16,16,16,16,16,16,79,16,16,16,16,16,80,81,82,16,16,16,16,16,83,\n84,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,248,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,254,255,255,255,255,191,182,0,0,0,0,0,0,0,63,0,255,23,0,0,0,0,0,248,255,\n255,0,0,1,0,0,0,0,0,0,0,0,0,0,0,192,191,159,61,0,0,0,128,2,0,0,0,255,255,255,\n7,0,0,0,0,0,0,0,0,0,0,192,255,1,0,0,0,0,0,0,248,15,32,0,0,192,251,239,62,0,0,\n0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,255,255,255,255,\n255,7,0,0,0,0,0,0,20,254,33,254,0,12,0,0,0,2,0,0,0,0,0,0,16,30,32,0,0,12,0,0,\n64,6,0,0,0,0,0,0,16,134,57,2,0,0,0,35,0,6,0,0,0,0,0,0,16,190,33,0,0,12,0,0,\n252,2,0,0,0,0,0,0,144,30,32,64,0,12,0,0,0,4,0,0,0,0,0,0,0,1,32,0,0,0,0,0,0,17,\n0,0,0,0,0,0,192,193,61,96,0,12,0,0,0,2,0,0,0,0,0,0,144,64,48,0,0,12,0,0,0,3,0,\n0,0,0,0,0,24,30,32,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,4,92,0,0,0,0,0,0,0,0,0,0,0,\n242,7,128,127,0,0,0,0,0,0,0,0,0,0,0,0,242,31,0,63,0,0,0,0,0,0,0,0,0,3,0,0,160,\n2,0,0,0,0,0,0,254,127,223,224,255,254,255,255,255,31,64,0,0,0,0,0,0,0,0,0,0,0,\n0,224,253,102,0,0,0,195,1,0,30,0,100,32,0,32,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28,0,\n0,0,28,0,0,0,12,0,0,0,12,0,0,0,0,0,0,0,176,63,64,254,15,32,0,0,0,0,0,120,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,96,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,135,1,4,14,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,9,0,0,0,0,0,0,64,127,\n229,31,248,159,0,0,0,0,0,0,255,127,0,0,0,0,0,0,0,0,15,0,0,0,0,0,208,23,4,0,0,\n0,0,248,15,0,3,0,0,0,60,59,0,0,0,0,0,0,64,163,3,0,0,0,0,0,0,240,207,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,247,255,253,33,16,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,\n251,0,248,0,0,0,124,0,0,0,0,0,0,223,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,\n255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,3,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,\n0,60,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,128,247,63,0,0,0,192,0,0,0,0,0,0,0,0,0,0,3,0,68,8,0,0,96,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,48,0,0,0,255,255,3,128,0,0,0,0,192,63,0,0,128,255,3,0,\n0,0,0,0,7,0,0,0,0,0,200,51,0,0,0,0,32,0,0,0,0,0,0,0,0,126,102,0,8,16,0,0,0,0,\n0,16,0,0,0,0,0,0,157,193,2,0,0,0,0,48,64,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,33,0,0,0,0,0,64,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,0,0,255,255,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,110,240,0,0,0,0,0,135,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,0,0,\n0,0,0,0,0,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,192,255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,255,\n127,0,0,0,0,0,0,128,3,0,0,0,0,0,120,38,0,32,0,0,0,0,0,0,7,0,0,0,128,239,31,0,\n0,0,0,0,0,0,8,0,3,0,0,0,0,0,192,127,0,30,0,0,0,0,0,0,0,0,0,0,0,128,211,64,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,248,7,0,0,3,0,0,0,0,0,0,24,1,0,0,0,192,\n31,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,92,0,0,64,0,0,0,0,0,\n0,0,0,0,0,248,133,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,60,176,1,0,0,48,0,0,0,\n0,0,0,0,0,0,0,248,167,1,0,0,0,0,0,0,0,0,0,0,0,0,40,191,0,0,0,0,0,0,0,0,0,0,0,\n0,224,188,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n128,255,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,240,12,1,0,0,0,254,7,0,0,0,0,248,121,128,0,\n126,14,0,0,0,0,0,252,127,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,191,0,0,0,\n0,0,0,0,0,0,0,252,255,255,252,109,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,126,180,191,0,\n0,0,0,0,0,0,0,0,163,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,\n0,0,0,0,0,0,0,255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,0,0,0,0,0,0,0,127,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,\n0,128,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,15,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,3,248,255,231,15,0,0,0,60,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,255,255,255,255,255,255,127,248,255,255,255,255,255,31,32,0,16,0,0,248,\n254,255,0,0,0,0,0,0,0,0,0,\n0,127,255,255,249,219,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,240,7,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n"
  },
  {
    "path": "user.libc/src/ctype/punct.h",
    "content": "18,16,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,16,16,34,35,16,36,37,38,39,\n40,41,42,43,16,44,45,46,17,17,47,17,17,17,17,17,17,48,49,50,51,52,53,54,55,17,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,56,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,57,16,58,59,60,61,62,63,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,64,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,65,16,16,66,16,67,68,\n69,16,70,71,72,16,73,16,16,74,75,76,77,78,16,79,80,81,82,83,84,85,86,87,88,89,\n90,91,16,92,93,94,95,16,16,16,16,96,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,97,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,98,99,16,16,100,101,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,102,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,103,104,105,106,16,16,107,108,17,17,109,16,16,16,16,16,16,110,111,16,\n16,16,16,16,112,113,16,16,114,115,116,16,117,118,119,17,17,17,120,121,122,123,\n124,16,16,16,16,\n16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,254,255,0,252,1,0,0,248,1,\n0,0,120,0,0,0,0,255,251,223,251,0,0,128,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,60,0,252,255,224,175,255,255,255,255,255,255,255,255,\n255,255,223,255,255,255,255,255,32,64,176,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,252,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,252,0,0,0,0,0,230,254,255,255,255,0,64,73,0,0,0,0,0,24,0,255,255,0,216,\n0,0,0,0,0,0,0,1,0,60,0,0,0,0,0,0,0,0,0,0,0,0,16,224,1,30,0,\n96,255,191,0,0,0,0,0,0,255,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,207,\n227,0,0,0,3,0,32,255,127,0,0,0,78,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,7,252,0,0,0,\n0,0,0,0,0,0,16,0,32,30,0,48,0,1,0,0,0,0,0,0,0,0,16,0,32,0,0,0,0,252,111,0,0,0,\n0,0,0,0,16,0,32,0,0,0,0,64,0,0,0,0,0,0,0,0,16,0,32,0,0,0,0,3,224,0,0,0,0,0,0,\n0,16,0,32,0,0,0,0,253,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,255,7,16,0,0,0,0,0,0,0,0,\n32,0,0,0,0,128,255,16,0,0,0,0,0,0,16,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,24,0,160,\n0,127,0,0,255,3,0,0,0,0,0,0,0,0,0,4,0,0,0,0,16,0,0,0,0,0,0,128,0,128,192,223,\n0,12,0,0,0,0,0,0,0,0,0,0,0,4,0,31,0,0,0,0,0,\n0,254,255,255,255,0,252,255,255,0,0,0,0,0,0,0,0,252,0,0,0,0,0,0,192,255,223,\n255,7,0,0,0,0,0,0,0,0,0,0,128,6,0,252,0,0,0,0,0,0,0,0,0,192,0,0,0,0,0,0,0,0,0,\n0,0,8,0,0,0,0,0,0,0,0,0,0,0,224,255,255,255,31,0,0,255,3,0,0,0,0,0,0,0,0,0,0,\n0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,96,0,0,1,0,0,24,0,0,0,0,0,0,0,0,0,56,0,0,0,0,16,0,0,0,112,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,48,0,0,254,127,47,0,0,255,3,255,127,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,49,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,196,255,255,255,\n255,0,0,0,192,0,0,0,0,0,0,0,0,1,0,224,159,0,0,0,0,127,63,255,127,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,16,0,16,0,0,252,255,255,255,31,0,0,0,0,0,12,0,0,0,0,0,0,64,0,\n12,240,0,0,0,0,0,0,128,248,0,0,0,0,0,0,0,192,0,0,0,0,0,0,0,0,255,0,255,255,\n255,33,144,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,\n127,0,224,251,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,160,3,224,0,224,0,\n224,0,96,128,248,255,255,255,252,255,255,255,255,255,127,223,255,241,127,255,\n127,0,0,255,255,255,255,0,0,255,255,255,255,1,0,123,3,208,193,175,66,0,12,31,\n188,255,255,0,0,0,0,0,14,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,127,0,0,0,255,7,0,0,255,255,255,255,255,255,255,255,255,\n255,63,0,0,0,0,0,0,252,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,207,255,255,255,\n63,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,224,135,3,254,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,\n128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,127,255,255,255,255,0,\n0,0,0,0,0,255,255,255,251,255,255,255,255,255,255,255,255,255,255,15,0,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,63,0,0,0,255,15,30,255,255,255,1,252,193,224,0,0,0,0,\n0,0,0,0,0,0,0,30,1,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n255,255,0,0,0,0,255,255,255,255,15,0,0,0,255,255,255,127,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,\n255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,\n255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,127,0,0,0,\n0,0,0,192,0,224,0,0,0,0,0,0,0,0,0,0,0,128,15,112,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n255,0,255,255,127,0,3,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n64,0,0,0,0,15,255,3,0,0,0,0,0,0,240,0,0,0,0,0,0,0,0,0,16,192,0,0,255,255,3,23,\n0,0,0,0,0,248,0,0,0,0,8,128,0,0,0,0,0,0,0,0,0,0,8,0,255,63,0,192,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,240,0,0,128,3,0,0,0,0,0,0,0,128,2,0,0,192,0,0,67,0,0,0,0,0,\n0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,56,0,\n0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,2,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,252,255,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,255,255,255,3,255,255,255,255,255,255,247,\n255,127,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,254,255,0,252,1,0,0,248,1,0,\n0,248,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,127,0,48,135,255,255,255,255,255,\n143,255,0,0,0,0,0,0,224,255,255,127,255,15,1,0,0,0,0,0,255,255,255,255,255,63,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,\n15,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n128,255,0,0,128,255,0,0,0,0,128,255,0,0,0,0,0,0,0,0,0,248,0,0,192,143,0,0,0,\n128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,255,255,252,255,255,255,255,255,0,0,0,0,\n0,0,0,135,255,1,255,1,0,0,0,224,0,0,0,224,0,0,0,0,0,1,0,0,96,248,127,0,0,0,0,\n0,0,0,0,254,0,0,0,255,0,0,0,255,0,0,0,30,0,254,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,252,0,0,0,0,0,0,0,0,0,0,0,\n0,255,255,255,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,224,127,0,0,0,192,255,255,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,192,63,252,255,63,0,0,128,3,0,0,0,0,0,0,254,3,32,0,0,0,0,0,0,0,\n0,0,0,0,0,24,0,15,0,0,0,0,0,56,0,0,0,0,0,0,0,0,0,225,63,0,232,254,255,31,0,0,\n0,0,0,0,0,96,63,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,\n24,0,32,0,0,192,31,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,\n248,0,104,0,0,0,0,0,0,0,0,0,0,0,0,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,128,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,128,14,0,0,0,255,\n31,0,0,0,0,0,0,0,0,192,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,8,0,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,252,7,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,24,128,255,0,0,0,0,0,\n0,0,0,0,0,223,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,62,0,0,252,255,31,3,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,0,0,0,0,0,0,0,0,0,128,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,128,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,\n255,3,\n128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,0,0,0,0,0,0,0,255,255,48,0,0,248,\n3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,\n255,255,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,176,15,0,0,0,0,0,0,\n0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,63,\n0,255,255,255,255,127,254,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,1,0,0,255,255,255,255,255,255,255,255,\n63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,15,0,255,255,255,255,255,255,\n255,255,255,255,127,0,255,255,255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,8,0,0,0,8,0,0,32,0,0,0,32,0,0,128,\n0,0,0,128,0,0,0,2,0,0,0,2,0,0,8,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,15,0,248,254,255,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,127,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,240,0,\n128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,255,127,0,0,0,0,0,0,0,\n0,0,0,0,0,0,112,7,0,192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,254,255,255,255,255,255,255,255,31,0,0,0,0,0,0,0,0,0,254,255,\n255,255,255,255,255,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,255,255,255,255,255,\n15,255,255,255,255,255,255,255,255,255,255,255,255,15,0,255,127,254,255,254,\n255,254,255,255,255,63,0,255,31,255,255,255,255,0,0,0,252,0,0,0,28,0,0,0,252,\n255,255,255,31,0,0,0,0,0,0,192,255,255,255,7,0,255,255,255,255,255,15,255,1,3,\n0,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,63,0,255,31,255,7,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,15,0,255,255,255,255,255,255,255,255,255,255,255,1,\n255,15,0,0,255,15,255,255,255,255,255,255,255,0,255,3,255,255,255,255,255,0,\n255,255,255,63,0,0,0,0,0,0,0,0,0,0,255,239,255,255,255,255,255,255,255,255,\n255,255,255,255,123,252,255,255,255,255,231,199,255,255,255,231,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,15,0,255,63,15,7,7,0,63,0,\n0,0,0,0,0,0,0,0,0,0,0,0,\n"
  },
  {
    "path": "user.libc/src/ctype/toascii.c",
    "content": "#include <ctype.h>\n\n/* nonsense function that should NEVER be used! */\nint toascii(int c)\n{\n\treturn c & 0x7f;\n}\n"
  },
  {
    "path": "user.libc/src/ctype/tolower.c",
    "content": "#include <ctype.h>\n\nint tolower(int c)\n{\n\tif (isupper(c)) return c | 32;\n\treturn c;\n}\n\nint __tolower_l(int c, locale_t l)\n{\n\treturn tolower(c);\n}\n\nweak_alias(__tolower_l, tolower_l);\n"
  },
  {
    "path": "user.libc/src/ctype/toupper.c",
    "content": "#include <ctype.h>\n\nint toupper(int c)\n{\n\tif (islower(c)) return c & 0x5f;\n\treturn c;\n}\n\nint __toupper_l(int c, locale_t l)\n{\n\treturn toupper(c);\n}\n\nweak_alias(__toupper_l, toupper_l);\n"
  },
  {
    "path": "user.libc/src/ctype/towctrans.c",
    "content": "#include <wctype.h>\n\nstatic const unsigned char tab[];\n\nstatic const unsigned char rulebases[512];\nstatic const int rules[];\n\nstatic const unsigned char exceptions[][2];\n\n#include \"casemap.h\"\n\nstatic int casemap(unsigned c, int dir)\n{\n\tunsigned b, x, y, v, rt, xb, xn;\n\tint r, rd, c0 = c;\n\n\tif (c >= 0x20000) return c;\n\n\tb = c>>8;\n\tc &= 255;\n\tx = c/3;\n\ty = c%3;\n\n\t/* lookup entry in two-level base-6 table */\n\tv = tab[tab[b]*86+x];\n\tstatic const int mt[] = { 2048, 342, 57 };\n\tv = (v*mt[y]>>11)%6;\n\n\t/* use the bit vector out of the tables as an index into\n\t * a block-specific set of rules and decode the rule into\n\t * a type and a case-mapping delta. */\n\tr = rules[rulebases[b]+v];\n\trt = r & 255;\n\trd = r >> 8;\n\n\t/* rules 0/1 are simple lower/upper case with a delta.\n\t * apply according to desired mapping direction. */\n\tif (rt < 2) return c0 + (rd & -(rt^dir));\n\n\t/* binary search. endpoints of the binary search for\n\t * this block are stored in the rule delta field. */\n\txn = rd & 0xff;\n\txb = (unsigned)rd >> 8;\n\twhile (xn) {\n\t\tunsigned try = exceptions[xb+xn/2][0];\n\t\tif (try == c) {\n\t\t\tr = rules[exceptions[xb+xn/2][1]];\n\t\t\trt = r & 255;\n\t\t\trd = r >> 8;\n\t\t\tif (rt < 2) return c0 + (rd & -(rt^dir));\n\t\t\t/* Hard-coded for the four exceptional titlecase */\n\t\t\treturn c0 + (dir ? -1 : 1);\n\t\t} else if (try > c) {\n\t\t\txn /= 2;\n\t\t} else {\n\t\t\txb += xn/2;\n\t\t\txn -= xn/2;\n\t\t}\n\t}\n\treturn c0;\n}\n\nwint_t towlower(wint_t wc)\n{\n\treturn casemap(wc, 0);\n}\n\nwint_t towupper(wint_t wc)\n{\n\treturn casemap(wc, 1);\n}\n\nwint_t __towupper_l(wint_t c, locale_t l)\n{\n\treturn towupper(c);\n}\n\nwint_t __towlower_l(wint_t c, locale_t l)\n{\n\treturn towlower(c);\n}\n\nweak_alias(__towupper_l, towupper_l);\nweak_alias(__towlower_l, towlower_l);\n"
  },
  {
    "path": "user.libc/src/ctype/wcswidth.c",
    "content": "#include <wchar.h>\n\nint wcswidth(const wchar_t *wcs, size_t n)\n{\n\tint l=0, k=0;\n\tfor (; n-- && *wcs && (k = wcwidth(*wcs)) >= 0; l+=k, wcs++);\n\treturn (k < 0) ? k : l;\n}\n"
  },
  {
    "path": "user.libc/src/ctype/wctrans.c",
    "content": "#include <wctype.h>\n#include <string.h>\n\nwctrans_t wctrans(const char *class)\n{\n\tif (!strcmp(class, \"toupper\")) return (wctrans_t)1;\n\tif (!strcmp(class, \"tolower\")) return (wctrans_t)2;\n\treturn 0;\n}\n\nwint_t towctrans(wint_t wc, wctrans_t trans)\n{\n\tif (trans == (wctrans_t)1) return towupper(wc);\n\tif (trans == (wctrans_t)2) return towlower(wc);\n\treturn wc;\n}\n\nwctrans_t __wctrans_l(const char *s, locale_t l)\n{\n\treturn wctrans(s);\n}\n\nwint_t __towctrans_l(wint_t c, wctrans_t t, locale_t l)\n{\n\treturn towctrans(c, t);\n}\n\nweak_alias(__wctrans_l, wctrans_l);\nweak_alias(__towctrans_l, towctrans_l);\n"
  },
  {
    "path": "user.libc/src/ctype/wcwidth.c",
    "content": "#include <wchar.h>\n\nstatic const unsigned char table[] = {\n#include \"nonspacing.h\"\n};\n\nstatic const unsigned char wtable[] = {\n#include \"wide.h\"\n};\n\nint wcwidth(wchar_t wc)\n{\n\tif (wc < 0xffU)\n\t\treturn (wc+1 & 0x7f) >= 0x21 ? 1 : wc ? -1 : 0;\n\tif ((wc & 0xfffeffffU) < 0xfffe) {\n\t\tif ((table[table[wc>>8]*32+((wc&255)>>3)]>>(wc&7))&1)\n\t\t\treturn 0;\n\t\tif ((wtable[wtable[wc>>8]*32+((wc&255)>>3)]>>(wc&7))&1)\n\t\t\treturn 2;\n\t\treturn 1;\n\t}\n\tif ((wc & 0xfffe) == 0xfffe)\n\t\treturn -1;\n\tif (wc-0x20000U < 0x20000)\n\t\treturn 2;\n\tif (wc == 0xe0001 || wc-0xe0020U < 0x5f || wc-0xe0100U < 0xef)\n\t\treturn 0;\n\treturn 1;\n}\n"
  },
  {
    "path": "user.libc/src/ctype/wide.h",
    "content": "16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,18,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,19,16,20,21,22,16,16,16,23,16,16,24,25,26,27,28,17,\n17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,29,\n17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,\n17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,\n17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,\n17,17,17,17,17,17,17,17,30,16,16,16,16,31,16,16,17,17,17,17,17,17,17,17,17,17,\n17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,\n17,17,17,17,17,17,17,32,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,16,16,16,33,\n34,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,35,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,\n17,17,17,17,17,17,36,17,17,37,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,38,39,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n16,16,16,16,16,16,16,40,41,42,43,44,45,46,47,16,48,49,16,16,16,16,\n16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,6,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,0,0,48,0,0,0,0,0,0,255,15,0,0,0,0,128,0,0,8,\n0,2,12,0,96,48,64,16,0,0,4,44,36,32,12,0,0,0,1,0,0,0,80,184,0,0,0,0,0,0,0,224,\n0,0,0,1,128,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0,0,0,0,33,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,251,255,255,255,255,255,255,255,\n255,255,255,15,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,63,0,0,0,255,15,255,255,255,255,\n255,255,255,127,254,255,255,255,255,255,255,255,255,255,127,254,255,255,255,\n255,255,255,255,255,255,255,255,255,224,255,255,255,255,255,254,255,255,255,\n255,255,255,255,255,255,255,127,255,255,255,255,255,7,255,255,255,255,15,0,\n255,255,255,255,255,127,255,255,255,255,255,0,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,\n0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,31,255,255,255,255,255,255,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,\n255,255,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,15,0,0,0,0,0,0,0,0,0,0,0,0,0,255,3,0,0,255,255,255,255,247,255,127,15,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,254,255,255,255,255,255,255,255,255,255,255,\n255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,7,0,255,255,255,127,0,0,0,0,0,\n0,7,0,240,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n15,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,64,254,7,0,0,0,0,0,0,0,0,0,0,0,0,7,0,255,255,255,\n255,255,15,255,1,3,0,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,\n1,224,191,255,255,255,255,255,255,255,255,223,255,255,15,0,255,255,255,255,\n255,135,15,0,255,255,17,255,255,255,255,255,255,255,255,127,253,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n159,255,255,255,255,255,255,255,63,0,120,255,255,255,0,0,4,0,0,96,0,16,0,0,0,\n0,0,0,0,0,0,0,248,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,\n255,255,255,255,255,255,63,16,39,0,0,24,240,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,255,15,0,\n0,0,224,255,255,255,255,255,255,255,255,255,255,255,255,123,252,255,255,255,\n255,231,199,255,255,255,231,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,15,7,7,0,63,0,0,0,0,0,0,0,0,0,0,0,0,0,\n"
  },
  {
    "path": "user.libc/src/dirent/__dirent.h",
    "content": "struct __dirstream\n{\n\toff_t tell;\n\tint fd;\n\tint buf_pos;\n\tint buf_end;\n\tvolatile int lock[1];\n\tint buf_size;\n\t/* Any changes to this struct must preserve the property:\n\t * offsetof(struct __dirent, buf) % sizeof(off_t) == 0 */\n\tchar *buf;\n\tstruct __dirstream *prev, *next;\n};\n"
  },
  {
    "path": "user.libc/src/dirent/alphasort.c",
    "content": "#include <string.h>\n#include <dirent.h>\n\nint alphasort(const struct dirent **a, const struct dirent **b)\n{\n\treturn strcoll((*a)->d_name, (*b)->d_name);\n}\n\nweak_alias(alphasort, alphasort64);\n"
  },
  {
    "path": "user.libc/src/dirent/closedir.c",
    "content": "#include <dirent.h>\n#include <unistd.h>\n#include <stdlib.h>\n#include \"__dirent.h\"\n#include \"stdio_impl.h\"\n\n#include <minos/kobject.h>\n#include <minos/proto.h>\n\nint closedir(DIR *dir)\n{\n\tint ret = kobject_close(dir->fd);\n\tfree(dir);\n\treturn ret;\n}\n"
  },
  {
    "path": "user.libc/src/dirent/dirfd.c",
    "content": "#include <dirent.h>\n#include \"__dirent.h\"\n\nint dirfd(DIR *d)\n{\n\treturn d->fd;\n}\n"
  },
  {
    "path": "user.libc/src/dirent/fdopendir.c",
    "content": "#include <dirent.h>\n#include <fcntl.h>\n#include <sys/stat.h>\n#include <errno.h>\n#include <stdlib.h>\n#include \"__dirent.h\"\n\nDIR *fdopendir(int fd)\n{\n#if 0\n\tDIR *dir;\n\tstruct stat st;\n\tif (fstat(fd, &st) < 0) {\n\t\treturn 0;\n\t}\n\tif (fcntl(fd, F_GETFL) & O_PATH) {\n\t\terrno = EBADF;\n\t\treturn 0;\n\t}\n\tif (!S_ISDIR(st.st_mode)) {\n\t\terrno = ENOTDIR;\n\t\treturn 0;\n\t}\n\tif (!(dir = calloc(1, sizeof *dir))) {\n\t\treturn 0;\n\t}\n\n\tfcntl(fd, F_SETFD, FD_CLOEXEC);\n\tdir->fd = fd;\n#endif\n\n\treturn NULL;\n}\n"
  },
  {
    "path": "user.libc/src/dirent/opendir.c",
    "content": "#define _GNU_SOURCE\n#include <dirent.h>\n#include <fcntl.h>\n#include <stdlib.h>\n#include \"__dirent.h\"\n#include \"syscall.h\"\n#include \"stdio_impl.h\"\n\n#include <minos/kobject.h>\n\nstatic DIR *__dirfd_open(int fd)\n{\n\tDIR *dir;\n\n\tdir = calloc(1, sizeof *dir);\n\tif (!dir)\n\t\tgoto out;\n\n\tdir->buf_size = BUFSIZ;\n\tdir->fd = fd;\n\tif (kobject_mmap(fd, &dir->buf, NULL))\n\t\tgoto out_free;\n\n\treturn dir;\n\nout_free:\n\tfree(dir);\nout:\n\tkobject_close(fd);\n\treturn NULL;\n}\n\nDIR *opendir(const char *name)\n{\n\tint fd;\n\n\tif ((fd = __sys_open(name, O_RDONLY|O_DIRECTORY|O_CLOEXEC, 0)) < 0)\n\t\treturn 0;\n\n\treturn __dirfd_open(fd);\n}\n"
  },
  {
    "path": "user.libc/src/dirent/readdir.c",
    "content": "#include <dirent.h>\n#include <errno.h>\n#include <stddef.h>\n#include \"__dirent.h\"\n#include \"syscall.h\"\n\n#include <minos/kobject.h>\n#include <minos/proto.h>\n\ntypedef char dirstream_buf_alignment_check[1-2*(int)(\n\toffsetof(struct __dirstream, buf) % sizeof(off_t))];\n\nstatic int __readdir(DIR *dir)\n{\n\tstruct proto proto;\n\n\tproto.proto_id = PROTO_GETDENTS;\n\n\treturn kobject_write(dir->fd, &proto,\n\t\t\tsizeof(struct proto), NULL, 0, 5000);\n}\n\nstruct dirent *readdir(DIR *dir)\n{\n\tstruct dirent *de;\n\n\tif (dir->buf_pos >= dir->buf_end) {\n\t\tint len = __readdir(dir);\n\t\tif (len <= 0) {\n\t\t\tif (len < 0 && len != -ENOENT) errno = -len;\n\t\t\treturn 0;\n\t\t}\n\t\tdir->buf_end = len;\n\t\tdir->buf_pos = 0;\n\t}\n\tde = (void *)(dir->buf + dir->buf_pos);\n\tdir->buf_pos += de->d_reclen;\n\tdir->tell = de->d_off;\n\treturn de;\n}\n\nweak_alias(readdir, readdir64);\n"
  },
  {
    "path": "user.libc/src/dirent/readdir_r.c",
    "content": "#include <dirent.h>\n#include <errno.h>\n#include <string.h>\n#include \"__dirent.h\"\n#include \"lock.h\"\n\nint readdir_r(DIR *restrict dir, struct dirent *restrict buf, struct dirent **restrict result)\n{\n\tstruct dirent *de;\n\tint errno_save = errno;\n\tint ret;\n\n\tLOCK(dir->lock);\n\terrno = 0;\n\tde = readdir(dir);\n\tif ((ret = errno)) {\n\t\tUNLOCK(dir->lock);\n\t\treturn ret;\n\t}\n\terrno = errno_save;\n\tif (de) memcpy(buf, de, de->d_reclen);\n\telse buf = NULL;\n\n\tUNLOCK(dir->lock);\n\t*result = buf;\n\treturn 0;\n}\n\nweak_alias(readdir_r, readdir64_r);\n"
  },
  {
    "path": "user.libc/src/dirent/rewinddir.c",
    "content": "#include <dirent.h>\n#include <unistd.h>\n#include \"__dirent.h\"\n#include \"lock.h\"\n\nvoid rewinddir(DIR *dir)\n{\n\tLOCK(dir->lock);\n\t__lseek(dir->fd, 0, SEEK_SET);\n\tdir->buf_pos = dir->buf_end = 0;\n\tdir->tell = 0;\n\tUNLOCK(dir->lock);\n}\n"
  },
  {
    "path": "user.libc/src/dirent/scandir.c",
    "content": "#include <dirent.h>\n#include <string.h>\n#include <stdlib.h>\n#include <stdint.h>\n#include <errno.h>\n#include <stddef.h>\n\nint scandir(const char *path, struct dirent ***res,\n\tint (*sel)(const struct dirent *),\n\tint (*cmp)(const struct dirent **, const struct dirent **))\n{\n\tDIR *d = opendir(path);\n\tstruct dirent *de, **names=0, **tmp;\n\tsize_t cnt=0, len=0;\n\tint old_errno = errno;\n\n\tif (!d) return -1;\n\n\twhile ((errno=0), (de = readdir(d))) {\n\t\tif (sel && !sel(de)) continue;\n\t\tif (cnt >= len) {\n\t\t\tlen = 2*len+1;\n\t\t\tif (len > SIZE_MAX/sizeof *names) break;\n\t\t\ttmp = realloc(names, len * sizeof *names);\n\t\t\tif (!tmp) break;\n\t\t\tnames = tmp;\n\t\t}\n\t\tnames[cnt] = malloc(de->d_reclen);\n\t\tif (!names[cnt]) break;\n\t\tmemcpy(names[cnt++], de, de->d_reclen);\n\t}\n\n\tclosedir(d);\n\n\tif (errno) {\n\t\tif (names) while (cnt-->0) free(names[cnt]);\n\t\tfree(names);\n\t\treturn -1;\n\t}\n\terrno = old_errno;\n\n\tif (cmp) qsort(names, cnt, sizeof *names, (int (*)(const void *, const void *))cmp);\n\t*res = names;\n\treturn cnt;\n}\n\nweak_alias(scandir, scandir64);\n"
  },
  {
    "path": "user.libc/src/dirent/seekdir.c",
    "content": "#include <dirent.h>\n#include <unistd.h>\n#include \"__dirent.h\"\n#include \"lock.h\"\n\nvoid seekdir(DIR *dir, long off)\n{\n\tLOCK(dir->lock);\n\tdir->tell = lseek(dir->fd, off, SEEK_SET);\n\tdir->buf_pos = dir->buf_end = 0;\n\tUNLOCK(dir->lock);\n}\n"
  },
  {
    "path": "user.libc/src/dirent/telldir.c",
    "content": "#include <dirent.h>\n#include \"__dirent.h\"\n\nlong telldir(DIR *dir)\n{\n\treturn dir->tell;\n}\n"
  },
  {
    "path": "user.libc/src/dirent/versionsort.c",
    "content": "#define _GNU_SOURCE\n#include <string.h>\n#include <dirent.h>\n\nint versionsort(const struct dirent **a, const struct dirent **b)\n{\n\treturn strverscmp((*a)->d_name, (*b)->d_name);\n}\n\n#undef versionsort64\nweak_alias(versionsort, versionsort64);\n"
  },
  {
    "path": "user.libc/src/env/__environ.c",
    "content": "#include <unistd.h>\n\nchar **__environ = 0;\nweak_alias(__environ, ___environ);\nweak_alias(__environ, _environ);\nweak_alias(__environ, environ);\n"
  },
  {
    "path": "user.libc/src/env/__init_tls.c",
    "content": "#define SYSCALL_NO_TLS 1\n#include <elf.h>\n#include <limits.h>\n#include <sys/mman.h>\n#include <string.h>\n#include <stddef.h>\n#include \"pthread_impl.h\"\n#include \"libc.h\"\n#include \"atomic.h\"\n#include \"syscall.h\"\n\nvolatile int __thread_list_lock;\n\nint __init_tp(void *p)\n{\n\tpthread_t td = p;\n\ttd->self = td;\n\tint r = __set_thread_area(TP_ADJ(p));\n\tif (r < 0) return -1;\n\tif (!r) libc.can_do_threads = 1;\n\ttd->detach_state = DT_JOINABLE;\n\ttd->tid = __gettid();\n\ttd->locale = &libc.global_locale;\n\ttd->robust_list.head = &td->robust_list.head;\n\ttd->sysinfo = __sysinfo;\n\ttd->next = td->prev = td;\n\treturn 0;\n}\n\nstatic struct builtin_tls {\n\tchar c;\n\tstruct pthread pt;\n\tvoid *space[16];\n} builtin_tls[1];\n#define MIN_TLS_ALIGN offsetof(struct builtin_tls, pt)\n\nstatic struct tls_module main_tls;\n\nvoid *__copy_tls(unsigned char *mem)\n{\n\tpthread_t td;\n\tstruct tls_module *p;\n\tsize_t i;\n\tuintptr_t *dtv;\n\n#ifdef TLS_ABOVE_TP\n\tdtv = (uintptr_t*)(mem + libc.tls_size) - (libc.tls_cnt + 1);\n\n\tmem += -((uintptr_t)mem + sizeof(struct pthread)) & (libc.tls_align-1);\n\ttd = (pthread_t)mem;\n\tmem += sizeof(struct pthread);\n\n\tfor (i=1, p=libc.tls_head; p; i++, p=p->next) {\n\t\tdtv[i] = (uintptr_t)(mem + p->offset) + DTP_OFFSET;\n\t\tmemcpy(mem + p->offset, p->image, p->len);\n\t}\n#else\n\tdtv = (uintptr_t *)mem;\n\n\tmem += libc.tls_size - sizeof(struct pthread);\n\tmem -= (uintptr_t)mem & (libc.tls_align-1);\n\ttd = (pthread_t)mem;\n\n\tfor (i=1, p=libc.tls_head; p; i++, p=p->next) {\n\t\tdtv[i] = (uintptr_t)(mem - p->offset) + DTP_OFFSET;\n\t\tmemcpy(mem - p->offset, p->image, p->len);\n\t}\n#endif\n\tdtv[0] = libc.tls_cnt;\n\ttd->dtv = dtv;\n\treturn td;\n}\n\n#if ULONG_MAX == 0xffffffff\ntypedef Elf32_Phdr Phdr;\n#else\ntypedef Elf64_Phdr Phdr;\n#endif\n\nextern weak hidden const size_t _DYNAMIC[];\n\nstatic void static_init_tls(size_t *aux)\n{\n\tunsigned char *p;\n\tsize_t n;\n\tPhdr *phdr, *tls_phdr=0;\n\tsize_t base = 0;\n\tvoid *mem;\n\n\tfor (p=(void *)aux[AT_PHDR],n=aux[AT_PHNUM]; n; n--,p+=aux[AT_PHENT]) {\n\t\tphdr = (void *)p;\n\t\tif (phdr->p_type == PT_PHDR)\n\t\t\tbase = aux[AT_PHDR] - phdr->p_vaddr;\n\t\tif (phdr->p_type == PT_DYNAMIC && _DYNAMIC)\n\t\t\tbase = (size_t)_DYNAMIC - phdr->p_vaddr;\n\t\tif (phdr->p_type == PT_TLS)\n\t\t\ttls_phdr = phdr;\n\t\tif (phdr->p_type == PT_GNU_STACK &&\n\t\t    phdr->p_memsz > __default_stacksize)\n\t\t\t__default_stacksize =\n\t\t\t\tphdr->p_memsz < DEFAULT_STACK_MAX ?\n\t\t\t\tphdr->p_memsz : DEFAULT_STACK_MAX;\n\t}\n\n\tif (tls_phdr) {\n\t\tmain_tls.image = (void *)(base + tls_phdr->p_vaddr);\n\t\tmain_tls.len = tls_phdr->p_filesz;\n\t\tmain_tls.size = tls_phdr->p_memsz;\n\t\tmain_tls.align = tls_phdr->p_align;\n\t\tlibc.tls_cnt = 1;\n\t\tlibc.tls_head = &main_tls;\n\t}\n\n\tmain_tls.size += (-main_tls.size - (uintptr_t)main_tls.image)\n\t\t& (main_tls.align-1);\n#ifdef TLS_ABOVE_TP\n\tmain_tls.offset = GAP_ABOVE_TP;\n\tmain_tls.offset += (-GAP_ABOVE_TP + (uintptr_t)main_tls.image)\n\t\t& (main_tls.align-1);\n#else\n\tmain_tls.offset = main_tls.size;\n#endif\n\tif (main_tls.align < MIN_TLS_ALIGN) main_tls.align = MIN_TLS_ALIGN;\n\n\tlibc.tls_align = main_tls.align;\n\tlibc.tls_size = 2*sizeof(void *) + sizeof(struct pthread)\n#ifdef TLS_ABOVE_TP\n\t\t+ main_tls.offset\n#endif\n\t\t+ main_tls.size + main_tls.align\n\t\t+ MIN_TLS_ALIGN-1 & -MIN_TLS_ALIGN;\n\n\tif (libc.tls_size > sizeof builtin_tls) {\n\t\ta_crash();\n\t} else {\n\t\tmem = builtin_tls;\n\t}\n\n\t/* Failure to initialize thread pointer is always fatal. */\n\tif (__init_tp(__copy_tls(mem)) < 0)\n\t\ta_crash();\n}\n\nweak_alias(static_init_tls, __init_tls);\n"
  },
  {
    "path": "user.libc/src/env/__libc_start_main.c",
    "content": "#include <elf.h>\n#include <poll.h>\n#include <fcntl.h>\n#include <signal.h>\n#include <unistd.h>\n#include \"syscall.h\"\n#include \"atomic.h\"\n#include \"libc.h\"\n\nstatic void dummy(void) {}\nweak_alias(dummy, _init);\n\nextern weak hidden void (*const __init_array_start)(void), (*const __init_array_end)(void);\nextern hidden void __cwd_init(void);\n\nstatic void dummy1(void *p) {}\nweak_alias(dummy1, __init_ssp);\n\n#define AUX_CNT 64\n\n#ifdef __GNUC__\n__attribute__((__noinline__))\n#endif\nvoid __init_libc(char **envp, char *pn)\n{\n\tsize_t i, *auxv, aux[AUX_CNT] = { 0 };\n\t__environ = envp;\n\tfor (i=0; envp[i]; i++);\n\tlibc.auxv = auxv = (void *)(envp+i+1);\n\tfor (i=0; auxv[i]; i+=2) if (auxv[i]<AUX_CNT) aux[auxv[i]] = auxv[i+1];\n\t__hwcap = aux[AT_HWCAP];\n\tif (aux[AT_SYSINFO]) __sysinfo = aux[AT_SYSINFO];\n\tlibc.page_size = aux[AT_PAGESZ];\n\n\tlibc.rootfs_handle = aux[AT_ROOTFS_HANDLE];\n\tlibc.chiyou_handle = aux[AT_CHIYOU_HANDLE];\n\n\tif (!pn) pn = (void*)aux[AT_EXECFN];\n\tif (!pn) pn = \"\";\n\t__progname = __progname_full = pn;\n\tfor (i=0; pn[i]; i++) if (pn[i]=='/') __progname = pn+i+1;\n\n\t__init_tls(aux);\n\t__init_ssp((void *)aux[AT_RANDOM]);\n\n\tif (aux[AT_UID]==aux[AT_EUID] && aux[AT_GID]==aux[AT_EGID]\n\t\t&& !aux[AT_SECURE]) return;\n\n\tlibc.secure = 1;\n}\n\nstatic void libc_start_init(void)\n{\n\t_init();\n\tuintptr_t a = (uintptr_t)&__init_array_start;\n\tfor (; a<(uintptr_t)&__init_array_end; a+=sizeof(void(*)()))\n\t\t(*(void (**)(void))a)();\n}\n\nweak_alias(libc_start_init, __libc_start_init);\n\ntypedef int lsm2_fn(int (*)(int,char **,char **), int, char **);\nstatic lsm2_fn libc_start_main_stage2;\n\nint __libc_start_main(int (*main)(int,char **,char **), int argc, char **argv)\n{\n\tchar **envp = argv+argc+1;\n\n\t/* External linkage, and explicit noinline attribute if available,\n\t * are used to prevent the stack frame used during init from\n\t * persisting for the entire process lifetime. */\n\t__init_libc(envp, argv[0]);\n\n\t/* Barrier against hoisting application code or anything using ssp\n\t * or thread pointer prior to its initialization above. */\n\tlsm2_fn *stage2 = libc_start_main_stage2;\n\t__asm__ ( \"\" : \"+r\"(stage2) : : \"memory\" );\n\treturn stage2(main, argc, argv);\n}\n\nstatic int libc_start_main_stage2(int (*main)(int,char **,char **), int argc, char **argv)\n{\n\tchar **envp = argv+argc+1;\n\t__libc_start_init();\n\t__cwd_init();\n\n\t/* Pass control to the application */\n\texit(main(argc, argv, envp));\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/env/__reset_tls.c",
    "content": "#include <string.h>\n#include \"pthread_impl.h\"\n#include \"libc.h\"\n\nvoid __reset_tls()\n{\n\tpthread_t self = __pthread_self();\n\tstruct tls_module *p;\n\tsize_t i, n = self->dtv[0];\n\tif (n) for (p=libc.tls_head, i=1; i<=n; i++, p=p->next) {\n\t\tchar *mem = (char *)(self->dtv[i] - DTP_OFFSET);\n\t\tmemcpy(mem, p->image, p->len);\n\t\tmemset(mem+p->len, 0, p->size - p->len);\n\t}\n}\n"
  },
  {
    "path": "user.libc/src/env/__stack_chk_fail.c",
    "content": "#include <string.h>\n#include <stdint.h>\n#include \"pthread_impl.h\"\n\nuintptr_t __stack_chk_guard;\n\nvoid __init_ssp(void *entropy)\n{\n\tif (entropy) memcpy(&__stack_chk_guard, entropy, sizeof(uintptr_t));\n\telse __stack_chk_guard = (uintptr_t)&__stack_chk_guard * 1103515245;\n\n\t__pthread_self()->canary = __stack_chk_guard;\n}\n\nvoid __stack_chk_fail(void)\n{\n\ta_crash();\n}\n\nhidden void __stack_chk_fail_local(void);\n\nweak_alias(__stack_chk_fail, __stack_chk_fail_local);\n"
  },
  {
    "path": "user.libc/src/env/clearenv.c",
    "content": "#define _GNU_SOURCE\n#include <stdlib.h>\n#include <unistd.h>\n\nstatic void dummy(char *old, char *new) {}\nweak_alias(dummy, __env_rm_add);\n\nint clearenv()\n{\n\tchar **e = __environ;\n\t__environ = 0;\n\tif (e) while (*e) __env_rm_add(*e++, 0);\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/env/getenv.c",
    "content": "#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\nchar *getenv(const char *name)\n{\n\tsize_t l = __strchrnul(name, '=') - name;\n\tif (l && !name[l] && __environ)\n\t\tfor (char **e = __environ; *e; e++)\n\t\t\tif (!strncmp(name, *e, l) && l[*e] == '=')\n\t\t\t\treturn *e + l+1;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/env/putenv.c",
    "content": "#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\nstatic void dummy(char *old, char *new) {}\nweak_alias(dummy, __env_rm_add);\n\nint __putenv(char *s, size_t l, char *r)\n{\n\tsize_t i=0;\n\tif (__environ) {\n\t\tfor (char **e = __environ; *e; e++, i++)\n\t\t\tif (!strncmp(s, *e, l+1)) {\n\t\t\t\tchar *tmp = *e;\n\t\t\t\t*e = s;\n\t\t\t\t__env_rm_add(tmp, r);\n\t\t\t\treturn 0;\n\t\t\t}\n\t}\n\tstatic char **oldenv;\n\tchar **newenv;\n\tif (__environ == oldenv) {\n\t\tnewenv = realloc(oldenv, sizeof *newenv * (i+2));\n\t\tif (!newenv) goto oom;\n\t} else {\n\t\tnewenv = malloc(sizeof *newenv * (i+2));\n\t\tif (!newenv) goto oom;\n\t\tif (i) memcpy(newenv, __environ, sizeof *newenv * i);\n\t\tfree(oldenv);\n\t}\n\tnewenv[i] = s;\n\tnewenv[i+1] = 0;\n\t__environ = oldenv = newenv;\n\tif (r) __env_rm_add(0, r);\n\treturn 0;\noom:\n\tfree(r);\n\treturn -1;\n}\n\nint putenv(char *s)\n{\n\tsize_t l = __strchrnul(s, '=') - s;\n\tif (!l || !s[l]) return unsetenv(s);\n\treturn __putenv(s, l, 0);\n}\n"
  },
  {
    "path": "user.libc/src/env/secure_getenv.c",
    "content": "#define _GNU_SOURCE\n#include <stdlib.h>\n#include \"libc.h\"\n\nchar *secure_getenv(const char *name)\n{\n\treturn libc.secure ? NULL : getenv(name);\n}\n"
  },
  {
    "path": "user.libc/src/env/setenv.c",
    "content": "#include <stdlib.h>\n#include <string.h>\n#include <errno.h>\n\nvoid __env_rm_add(char *old, char *new)\n{\n\tstatic char **env_alloced;\n\tstatic size_t env_alloced_n;\n\tfor (size_t i=0; i < env_alloced_n; i++)\n\t\tif (env_alloced[i] == old) {\n\t\t\tenv_alloced[i] = new;\n\t\t\tfree(old);\n\t\t\treturn;\n\t\t} else if (!env_alloced[i] && new) {\n\t\t\tenv_alloced[i] = new;\n\t\t\tnew = 0;\n\t\t}\n\tif (!new) return;\n\tchar **t = realloc(env_alloced, sizeof *t * (env_alloced_n+1));\n\tif (!t) return;\n\t(env_alloced = t)[env_alloced_n++] = new;\n}\n\nint setenv(const char *var, const char *value, int overwrite)\n{\n\tchar *s;\n\tsize_t l1, l2;\n\n\tif (!var || !(l1 = __strchrnul(var, '=') - var) || var[l1]) {\n\t\terrno = EINVAL;\n\t\treturn -1;\n\t}\n\tif (!overwrite && getenv(var)) return 0;\n\n\tl2 = strlen(value);\n\ts = malloc(l1+l2+2);\n\tif (!s) return -1;\n\tmemcpy(s, var, l1);\n\ts[l1] = '=';\n\tmemcpy(s+l1+1, value, l2+1);\n\treturn __putenv(s, l1, s);\n}\n"
  },
  {
    "path": "user.libc/src/env/unsetenv.c",
    "content": "#include <stdlib.h>\n#include <string.h>\n#include <errno.h>\n#include <unistd.h>\n\nstatic void dummy(char *old, char *new) {}\nweak_alias(dummy, __env_rm_add);\n\nint unsetenv(const char *name)\n{\n\tsize_t l = __strchrnul(name, '=') - name;\n\tif (!l || name[l]) {\n\t\terrno = EINVAL;\n\t\treturn -1;\n\t}\n\tif (__environ) {\n\t\tchar **e = __environ, **eo = e;\n\t\tfor (; *e; e++)\n\t\t\tif (!strncmp(name, *e, l) && l[*e] == '=')\n\t\t\t\t__env_rm_add(*e, 0);\n\t\t\telse if (eo != e)\n\t\t\t\t*eo++ = *e;\n\t\t\telse\n\t\t\t\teo++;\n\t\tif (eo != e) *eo = 0;\n\t}\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/errno/__errno_location.c",
    "content": "#include <errno.h>\n#include \"pthread_impl.h\"\n\nint *__errno_location(void)\n{\n\treturn &__pthread_self()->errno_val;\n}\n\nweak_alias(__errno_location, ___errno_location);\n"
  },
  {
    "path": "user.libc/src/errno/__strerror.h",
    "content": "/* The first entry is a catch-all for codes not enumerated here.\n * This file is included multiple times to declare and define a structure\n * with these messages, and then to define a lookup table translating\n * error codes to offsets of corresponding fields in the structure. */\n\nE(0,            \"No error information\")\n\nE(EILSEQ,       \"Illegal byte sequence\")\nE(EDOM,         \"Domain error\")\nE(ERANGE,       \"Result not representable\")\n\nE(ENOTTY,       \"Not a tty\")\nE(EACCES,       \"Permission denied\")\nE(EPERM,        \"Operation not permitted\")\nE(ENOENT,       \"No such file or directory\")\nE(ESRCH,        \"No such process\")\nE(EEXIST,       \"File exists\")\n\nE(EOVERFLOW,    \"Value too large for data type\")\nE(ENOSPC,       \"No space left on device\")\nE(ENOMEM,       \"Out of memory\")\n\nE(EBUSY,        \"Resource busy\")\nE(EINTR,        \"Interrupted system call\")\nE(EAGAIN,       \"Resource temporarily unavailable\")\nE(ESPIPE,       \"Invalid seek\")\n\nE(EXDEV,        \"Cross-device link\")\nE(EROFS,        \"Read-only file system\")\nE(ENOTEMPTY,    \"Directory not empty\")\n\nE(ECONNRESET,   \"Connection reset by peer\")\nE(ETIMEDOUT,    \"Operation timed out\")\nE(ECONNREFUSED, \"Connection refused\")\nE(EHOSTDOWN,    \"Host is down\")\nE(EHOSTUNREACH, \"Host is unreachable\")\nE(EADDRINUSE,   \"Address in use\")\n\nE(EPIPE,        \"Broken pipe\")\nE(EIO,          \"I/O error\")\nE(ENXIO,        \"No such device or address\")\nE(ENOTBLK,      \"Block device required\")\nE(ENODEV,       \"No such device\")\nE(ENOTDIR,      \"Not a directory\")\nE(EISDIR,       \"Is a directory\")\nE(ETXTBSY,      \"Text file busy\")\nE(ENOEXEC,      \"Exec format error\")\n\nE(EINVAL,       \"Invalid argument\")\n\nE(E2BIG,        \"Argument list too long\")\nE(ELOOP,        \"Symbolic link loop\")\nE(ENAMETOOLONG, \"Filename too long\")\nE(ENFILE,       \"Too many open files in system\")\nE(EMFILE,       \"No file descriptors available\")\nE(EBADF,        \"Bad file descriptor\")\nE(ECHILD,       \"No child process\")\nE(EFAULT,       \"Bad address\")\nE(EFBIG,        \"File too large\")\nE(EMLINK,       \"Too many links\")\nE(ENOLCK,       \"No locks available\")\n\nE(EDEADLK,      \"Resource deadlock would occur\")\nE(ENOTRECOVERABLE, \"State not recoverable\")\nE(EOWNERDEAD,   \"Previous owner died\")\nE(ECANCELED,    \"Operation canceled\")\nE(ENOSYS,       \"Function not implemented\")\nE(ENOMSG,       \"No message of desired type\")\nE(EIDRM,        \"Identifier removed\")\nE(ENOSTR,       \"Device not a stream\")\nE(ENODATA,      \"No data available\")\nE(ETIME,        \"Device timeout\")\nE(ENOSR,        \"Out of streams resources\")\nE(ENOLINK,      \"Link has been severed\")\nE(EPROTO,       \"Protocol error\")\nE(EBADMSG,      \"Bad message\")\nE(EBADFD,       \"File descriptor in bad state\")\nE(ENOTSOCK,     \"Not a socket\")\nE(EDESTADDRREQ, \"Destination address required\")\nE(EMSGSIZE,     \"Message too large\")\nE(EPROTOTYPE,   \"Protocol wrong type for socket\")\nE(ENOPROTOOPT,  \"Protocol not available\")\nE(EPROTONOSUPPORT,\"Protocol not supported\")\nE(ESOCKTNOSUPPORT,\"Socket type not supported\")\nE(ENOTSUP,      \"Not supported\")\nE(EPFNOSUPPORT, \"Protocol family not supported\")\nE(EAFNOSUPPORT, \"Address family not supported by protocol\")\nE(EADDRNOTAVAIL,\"Address not available\")\nE(ENETDOWN,     \"Network is down\")\nE(ENETUNREACH,  \"Network unreachable\")\nE(ENETRESET,    \"Connection reset by network\")\nE(ECONNABORTED, \"Connection aborted\")\nE(ENOBUFS,      \"No buffer space available\")\nE(EISCONN,      \"Socket is connected\")\nE(ENOTCONN,     \"Socket not connected\")\nE(ESHUTDOWN,    \"Cannot send after socket shutdown\")\nE(EALREADY,     \"Operation already in progress\")\nE(EINPROGRESS,  \"Operation in progress\")\nE(ESTALE,       \"Stale file handle\")\nE(EREMOTEIO,    \"Remote I/O error\")\nE(EDQUOT,       \"Quota exceeded\")\nE(ENOMEDIUM,    \"No medium found\")\nE(EMEDIUMTYPE,  \"Wrong medium type\")\nE(EMULTIHOP,    \"Multihop attempted\")\n"
  },
  {
    "path": "user.libc/src/errno/strerror.c",
    "content": "#include <errno.h>\n#include <stddef.h>\n#include <string.h>\n#include \"locale_impl.h\"\n\n/* mips has one error code outside of the 8-bit range due to a\n * historical typo, so we just remap it. */\n#if EDQUOT==1133\n#define EDQUOT_ORIG 1133\n#undef  EDQUOT\n#define EDQUOT 109\n#endif\n\nstatic const struct errmsgstr_t {\n#define E(n, s) char str##n[sizeof(s)];\n#include \"__strerror.h\"\n#undef E\n} errmsgstr = {\n#define E(n, s) s,\n#include \"__strerror.h\"\n#undef E\n};\n\nstatic const unsigned short errmsgidx[] = {\n#define E(n, s) [n] = offsetof(struct errmsgstr_t, str##n),\n#include \"__strerror.h\"\n#undef E\n};\n\nchar *__strerror_l(int e, locale_t loc)\n{\n\tconst char *s;\n#ifdef EDQUOT_ORIG\n\tif (e==EDQUOT) e=0;\n\telse if (e==EDQUOT_ORIG) e=EDQUOT;\n#endif\n\tif (e >= sizeof errmsgidx / sizeof *errmsgidx) e = 0;\n\ts = (char *)&errmsgstr + errmsgidx[e];\n\treturn (char *)LCTRANS(s, LC_MESSAGES, loc);\n}\n\nchar *strerror(int e)\n{\n\treturn __strerror_l(e, CURRENT_LOCALE);\n}\n\nweak_alias(__strerror_l, strerror_l);\n"
  },
  {
    "path": "user.libc/src/exit/_Exit.c",
    "content": "#include <stdlib.h>\n#include \"syscall.h\"\n#include \"pthread_impl.h\"\n\n#include <minos/kobject.h>\n\n_Noreturn void _Exit(int ec)\n{\n\tfor (;;) syscall(SYS_exitgroup, ec);\n}\n"
  },
  {
    "path": "user.libc/src/exit/abort.c",
    "content": "#include <stdlib.h>\n#include <signal.h>\n#include \"syscall.h\"\n#include \"pthread_impl.h\"\n#include \"atomic.h\"\n#include \"lock.h\"\n#include \"ksigaction.h\"\n\n_Noreturn void abort(void)\n{\n#if 0\n\traise(SIGABRT);\n\n\t/* If there was a SIGABRT handler installed and it returned, or if\n\t * SIGABRT was blocked or ignored, take an AS-safe lock to prevent\n\t * sigaction from installing a new SIGABRT handler, uninstall any\n\t * handler that may be present, and re-raise the signal to generate\n\t * the default action of abnormal termination. */\n\t__block_all_sigs(0);\n\tLOCK(__abort_lock);\n\t__syscall(SYS_rt_sigaction, SIGABRT,\n\t\t&(struct k_sigaction){.handler = SIG_DFL}, 0, _NSIG/8);\n\t__syscall(SYS_tkill, __pthread_self()->tid, SIGABRT);\n\t__syscall(SYS_rt_sigprocmask, SIG_UNBLOCK,\n\t\t&(long[_NSIG/(8*sizeof(long))]){1UL<<(SIGABRT-1)}, 0, _NSIG/8);\n\n\t/* Beyond this point should be unreachable. */\n\ta_crash();\n\traise(SIGKILL);\n#endif\n\t_Exit(127);\n}\n"
  },
  {
    "path": "user.libc/src/exit/abort_lock.c",
    "content": "#include \"pthread_impl.h\"\n\nvolatile int __abort_lock[1];\n"
  },
  {
    "path": "user.libc/src/exit/arm/__aeabi_atexit.c",
    "content": "int __cxa_atexit(void (*func)(void *), void *arg, void *dso);\n\nint __aeabi_atexit (void *obj, void (*func) (void *), void *d)\n{\n\treturn __cxa_atexit (func, obj, d);\n}\n"
  },
  {
    "path": "user.libc/src/exit/assert.c",
    "content": "#include <stdio.h>\n#include <stdlib.h>\n\n_Noreturn void __assert_fail(const char *expr, const char *file, int line, const char *func)\n{\n\tfprintf(stderr, \"Assertion failed: %s (%s: %s: %d)\\n\", expr, file, func, line);\n\tabort();\n}\n"
  },
  {
    "path": "user.libc/src/exit/at_quick_exit.c",
    "content": "#include <stdlib.h>\n#include \"libc.h\"\n#include \"lock.h\"\n#include \"fork_impl.h\"\n\n#define COUNT 32\n\nstatic void (*funcs[COUNT])(void);\nstatic int count;\nstatic volatile int lock[1];\nvolatile int *const __at_quick_exit_lockptr = lock;\n\nvoid __funcs_on_quick_exit()\n{\n\tvoid (*func)(void);\n\tLOCK(lock);\n\twhile (count > 0) {\n\t\tfunc = funcs[--count];\n\t\tUNLOCK(lock);\n\t\tfunc();\n\t\tLOCK(lock);\n\t}\n}\n\nint at_quick_exit(void (*func)(void))\n{\n\tint r = 0;\n\tLOCK(lock);\n\tif (count == 32) r = -1;\n\telse funcs[count++] = func;\n\tUNLOCK(lock);\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/src/exit/atexit.c",
    "content": "#include <stdlib.h>\n#include <stdint.h>\n#include \"libc.h\"\n#include \"lock.h\"\n#include \"fork_impl.h\"\n\n#define malloc __libc_malloc\n#define calloc __libc_calloc\n#define realloc undef\n#define free undef\n\n/* Ensure that at least 32 atexit handlers can be registered without malloc */\n#define COUNT 32\n\nstatic struct fl\n{\n\tstruct fl *next;\n\tvoid (*f[COUNT])(void *);\n\tvoid *a[COUNT];\n} builtin, *head;\n\nstatic int slot;\nstatic volatile int lock[1];\nvolatile int *const __atexit_lockptr = lock;\n\nvoid __funcs_on_exit()\n{\n\tvoid (*func)(void *), *arg;\n\tLOCK(lock);\n\tfor (; head; head=head->next, slot=COUNT) while(slot-->0) {\n\t\tfunc = head->f[slot];\n\t\targ = head->a[slot];\n\t\tUNLOCK(lock);\n\t\tfunc(arg);\n\t\tLOCK(lock);\n\t}\n}\n\nvoid __cxa_finalize(void *dso)\n{\n}\n\nint __cxa_atexit(void (*func)(void *), void *arg, void *dso)\n{\n\tLOCK(lock);\n\n\t/* Defer initialization of head so it can be in BSS */\n\tif (!head) head = &builtin;\n\n\t/* If the current function list is full, add a new one */\n\tif (slot==COUNT) {\n\t\tstruct fl *new_fl = calloc(sizeof(struct fl), 1);\n\t\tif (!new_fl) {\n\t\t\tUNLOCK(lock);\n\t\t\treturn -1;\n\t\t}\n\t\tnew_fl->next = head;\n\t\thead = new_fl;\n\t\tslot = 0;\n\t}\n\n\t/* Append function to the list. */\n\thead->f[slot] = func;\n\thead->a[slot] = arg;\n\tslot++;\n\n\tUNLOCK(lock);\n\treturn 0;\n}\n\nstatic void call(void *p)\n{\n\t((void (*)(void))(uintptr_t)p)();\n}\n\nint atexit(void (*func)(void))\n{\n\treturn __cxa_atexit(call, (void *)(uintptr_t)func, 0);\n}\n"
  },
  {
    "path": "user.libc/src/exit/exit.c",
    "content": "#include <stdlib.h>\n#include <stdint.h>\n#include \"libc.h\"\n\nstatic void dummy()\n{\n}\n\n/* atexit.c and __stdio_exit.c override these. the latter is linked\n * as a consequence of linking either __toread.c or __towrite.c. */\nweak_alias(dummy, __funcs_on_exit);\nweak_alias(dummy, __stdio_exit);\nweak_alias(dummy, _fini);\n\nextern weak hidden void (*const __fini_array_start)(void), (*const __fini_array_end)(void);\n\nstatic void libc_exit_fini(void)\n{\n\tuintptr_t a = (uintptr_t)&__fini_array_end;\n\tfor (; a>(uintptr_t)&__fini_array_start; a-=sizeof(void(*)()))\n\t\t(*(void (**)())(a-sizeof(void(*)())))();\n\t_fini();\n}\n\nweak_alias(libc_exit_fini, __libc_exit_fini);\n\n_Noreturn void exit(int code)\n{\n\t__funcs_on_exit();\n\t__libc_exit_fini();\n\t__stdio_exit();\n\t_Exit(code);\n}\n"
  },
  {
    "path": "user.libc/src/exit/quick_exit.c",
    "content": "#include <stdlib.h>\n#include \"libc.h\"\n\nstatic void dummy() { }\nweak_alias(dummy, __funcs_on_quick_exit);\n\n_Noreturn void quick_exit(int code)\n{\n\t__funcs_on_quick_exit();\n\t_Exit(code);\n}\n"
  },
  {
    "path": "user.libc/src/fcntl/creat.c",
    "content": "#include <fcntl.h>\n\nint creat(const char *filename, mode_t mode)\n{\n\treturn open(filename, O_CREAT|O_WRONLY|O_TRUNC, mode);\n}\n\nweak_alias(creat, creat64);\n"
  },
  {
    "path": "user.libc/src/fcntl/fcntl.c",
    "content": "#define _GNU_SOURCE\n#include <fcntl.h>\n#include <stdarg.h>\n#include <errno.h>\n#include \"syscall.h\"\n\nint fcntl(int fd, int cmd, ...)\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/fcntl/open.c",
    "content": "#include <fcntl.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include \"syscall.h\"\n#include \"stdio_impl.h\"\n\n#include <minos/kobject.h>\n\nint open(const char *filename, int flags, ...)\n{\n\tmode_t mode = 0;\n\tFILE *filep;\n\tint fd;\n\n\tif ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE) {\n\t\tva_list ap;\n\t\tva_start(ap, flags);\n\t\tmode = va_arg(ap, mode_t);\n\t\tva_end(ap);\n\t}\n\n\tfd = __sys_open(filename, flags, mode);\n\tif (fd <= 0)\n\t\treturn fd;\n\n\tfilep = __fdopen(fd, flags);\n\tif (filep)\n\t\treturn fd;\n\n\tkobject_close(fd);\n\n\treturn -ENOMEM;\n}\n\nweak_alias(open, open64);\n"
  },
  {
    "path": "user.libc/src/fcntl/openat.c",
    "content": "#include <fcntl.h>\n#include <stdarg.h>\n#include \"syscall.h\"\n#include <string.h>\n#include \"stdio_impl.h\"\n\n#include <minos/proto.h>\n#include <minos/kobject.h>\n\nstatic int __openat(int fd, const char *filename, int flags, mode_t mode)\n{\n\tstruct proto proto;\n\n\tproto.proto_id = PROTO_OPENAT;\n\tproto.openat.flags = flags;\n\tproto.openat.mode = mode;\n\n\treturn kobject_write(fd, &proto, sizeof(struct proto),\n\t\t\t(void *)filename, strlen(filename), -1);\n}\n\nint openat(int fd, const char *filename, int flags, ...)\n{\n\tmode_t mode = 0;\n\tint handle;\n\tFILE *f;\n\n\tif ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE) {\n\t\tva_list ap;\n\t\tva_start(ap, flags);\n\t\tmode = va_arg(ap, mode_t);\n\t\tva_end(ap);\n\t}\n\n\thandle = __openat(fd, filename, flags | O_LARGEFILE, mode);\n\tif (handle <= 0)\n\t\treturn handle;\n\n\tf = __fdopen(fd, mode);\n\tif (f)\n\t\treturn f->fd;\n\n\tkobject_close(handle);\n\n\treturn -ENOMEM;\n}\n\nweak_alias(openat, openat64);\n"
  },
  {
    "path": "user.libc/src/fcntl/posix_fadvise.c",
    "content": "#include <fcntl.h>\n#include \"syscall.h\"\n\nint posix_fadvise(int fd, off_t base, off_t len, int advice)\n{\n#if 0\n#if defined(SYSCALL_FADVISE_6_ARG)\n\t/* Some archs, at least arm and powerpc, have the syscall\n\t * arguments reordered to avoid needing 7 argument registers\n\t * due to 64-bit argument alignment. */\n\treturn -__syscall(SYS_fadvise, fd, advice,\n\t\t__SYSCALL_LL_E(base), __SYSCALL_LL_E(len));\n#else\n\treturn -__syscall(SYS_fadvise, fd, __SYSCALL_LL_O(base),\n\t\t__SYSCALL_LL_E(len), advice);\n#endif\n#endif\n\treturn -ENOSYS;\n}\n\nweak_alias(posix_fadvise, posix_fadvise64);\n"
  },
  {
    "path": "user.libc/src/fcntl/posix_fallocate.c",
    "content": "#include <fcntl.h>\n#include \"syscall.h\"\n\nint posix_fallocate(int fd, off_t base, off_t len)\n{\n#if 0\n\treturn -__syscall(SYS_fallocate, fd, 0, __SYSCALL_LL_E(base),\n\t\t__SYSCALL_LL_E(len));\n#endif\n\treturn -ENOSYS;\n}\n\nweak_alias(posix_fallocate, posix_fallocate64);\n"
  },
  {
    "path": "user.libc/src/fenv/__flt_rounds.c",
    "content": "#include <float.h>\n#include <fenv.h>\n\nint __flt_rounds()\n{\n\tswitch (fegetround()) {\n#ifdef FE_TOWARDZERO\n\tcase FE_TOWARDZERO: return 0;\n#endif\n\tcase FE_TONEAREST: return 1;\n#ifdef FE_UPWARD\n\tcase FE_UPWARD: return 2;\n#endif\n#ifdef FE_DOWNWARD\n\tcase FE_DOWNWARD: return 3;\n#endif\n\t}\n\treturn -1;\n}\n"
  },
  {
    "path": "user.libc/src/fenv/arm/fenv.c",
    "content": "#if !__ARM_PCS_VFP\n#include \"../fenv.c\"\n#endif\n"
  },
  {
    "path": "user.libc/src/fenv/fegetexceptflag.c",
    "content": "#include <fenv.h>\n\nint fegetexceptflag(fexcept_t *fp, int mask)\n{\n\t*fp = fetestexcept(mask);\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/fenv/feholdexcept.c",
    "content": "#include <fenv.h>\n\nint feholdexcept(fenv_t *envp)\n{\n\tfegetenv(envp);\n\tfeclearexcept(FE_ALL_EXCEPT);\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/fenv/fenv.c",
    "content": "#include <fenv.h>\n\n/* Dummy functions for archs lacking fenv implementation */\n\nint feclearexcept(int mask)\n{\n\treturn 0;\n}\n\nint feraiseexcept(int mask)\n{\n\treturn 0;\n}\n\nint fetestexcept(int mask)\n{\n\treturn 0;\n}\n\nint fegetround(void)\n{\n\treturn FE_TONEAREST;\n}\n\nint __fesetround(int r)\n{\n\treturn 0;\n}\n\nint fegetenv(fenv_t *envp)\n{\n\treturn 0;\n}\n\nint fesetenv(const fenv_t *envp)\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/fenv/fesetexceptflag.c",
    "content": "#include <fenv.h>\n\nint fesetexceptflag(const fexcept_t *fp, int mask)\n{\n\tfeclearexcept(~*fp & mask);\n\tferaiseexcept(*fp & mask);\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/fenv/fesetround.c",
    "content": "#include <fenv.h>\n#include <features.h>\n\n/* __fesetround wrapper for arch independent argument check */\n\nhidden int __fesetround(int);\n\nint fesetround(int r)\n{\n\tif (r != FE_TONEAREST\n#ifdef FE_DOWNWARD\n\t\t&& r != FE_DOWNWARD\n#endif\n#ifdef FE_UPWARD\n\t\t&& r != FE_UPWARD\n#endif\n#ifdef FE_TOWARDZERO\n\t\t&& r != FE_TOWARDZERO\n#endif\n\t)\n\t\treturn -1;\n\treturn __fesetround(r);\n}\n"
  },
  {
    "path": "user.libc/src/fenv/feupdateenv.c",
    "content": "#include <fenv.h>\n\nint feupdateenv(const fenv_t *envp)\n{\n\tint ex = fetestexcept(FE_ALL_EXCEPT);\n\tfesetenv(envp);\n\tferaiseexcept(ex);\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/fenv/m68k/fenv.c",
    "content": "#include <fenv.h>\n#include <features.h>\n\n#if __HAVE_68881__ || __mcffpu__\n\nstatic unsigned getsr()\n{\n\tunsigned v;\n\t__asm__ __volatile__ (\"fmove.l %%fpsr,%0\" : \"=dm\"(v));\n\treturn v;\n}\n\nstatic void setsr(unsigned v)\n{\n\t__asm__ __volatile__ (\"fmove.l %0,%%fpsr\" : : \"dm\"(v));\n}\n\nstatic unsigned getcr()\n{\n\tunsigned v;\n\t__asm__ __volatile__ (\"fmove.l %%fpcr,%0\" : \"=dm\"(v));\n\treturn v;\n}\n\nstatic void setcr(unsigned v)\n{\n\t__asm__ __volatile__ (\"fmove.l %0,%%fpcr\" : : \"dm\"(v));\n}\n\nint feclearexcept(int mask)\n{\n\tif (mask & ~FE_ALL_EXCEPT) return -1;\n\tsetsr(getsr() & ~mask);\n\treturn 0;\n}\n\nint feraiseexcept(int mask)\n{\n\tif (mask & ~FE_ALL_EXCEPT) return -1;\n\tsetsr(getsr() | mask);\n\treturn 0;\n}\n\nint fetestexcept(int mask)\n{\n\treturn getsr() & mask;\n}\n\nint fegetround(void)\n{\n\treturn getcr() & FE_UPWARD;\n}\n\nhidden int __fesetround(int r)\n{\n\tsetcr((getcr() & ~FE_UPWARD) | r);\n\treturn 0;\n}\n\nint fegetenv(fenv_t *envp)\n{\n\tenvp->__control_register = getcr();\n\tenvp->__status_register = getsr();\n\t__asm__ __volatile__ (\"fmove.l %%fpiar,%0\"\n\t\t: \"=dm\"(envp->__instruction_address));\n\treturn 0;\n}\n\nint fesetenv(const fenv_t *envp)\n{\n\tstatic const fenv_t default_env = { 0 };\n\tif (envp == FE_DFL_ENV)\n\t\tenvp = &default_env;\n\tsetcr(envp->__control_register);\n\tsetsr(envp->__status_register);\n\t__asm__ __volatile__ (\"fmove.l %0,%%fpiar\"\n\t\t: : \"dm\"(envp->__instruction_address));\n\treturn 0;\n}\n\n#else\n\n#include \"../fenv.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/fenv/mips/fenv-sf.c",
    "content": "#ifdef __mips_soft_float\n#include \"../fenv.c\"\n#endif\n"
  },
  {
    "path": "user.libc/src/fenv/mips64/fenv-sf.c",
    "content": "#ifdef __mips_soft_float\n#include \"../fenv.c\"\n#endif\n"
  },
  {
    "path": "user.libc/src/fenv/mipsn32/fenv-sf.c",
    "content": "#ifdef __mips_soft_float\n#include \"../fenv.c\"\n#endif\n"
  },
  {
    "path": "user.libc/src/fenv/powerpc/fenv-sf.c",
    "content": "#ifdef _SOFT_FLOAT\n#include \"../fenv.c\"\n#endif\n"
  },
  {
    "path": "user.libc/src/fenv/powerpc64/fenv.c",
    "content": "#define _GNU_SOURCE\n#include <fenv.h>\n#include <features.h>\n\nstatic inline double get_fpscr_f(void)\n{\n\tdouble d;\n\t__asm__ __volatile__(\"mffs %0\" : \"=d\"(d));\n\treturn d;\n}\n\nstatic inline long get_fpscr(void)\n{\n\treturn (union {double f; long i;}) {get_fpscr_f()}.i;\n}\n\nstatic inline void set_fpscr_f(double fpscr)\n{\n\t__asm__ __volatile__(\"mtfsf 255, %0\" : : \"d\"(fpscr));\n}\n\nstatic void set_fpscr(long fpscr)\n{\n\tset_fpscr_f((union {long i; double f;}) {fpscr}.f);\n}\n\nint feclearexcept(int mask)\n{\n\tmask &= FE_ALL_EXCEPT;\n\tif (mask & FE_INVALID) mask |= FE_ALL_INVALID;\n\tset_fpscr(get_fpscr() & ~mask);\n\treturn 0;\n}\n\nint feraiseexcept(int mask)\n{\n\tmask &= FE_ALL_EXCEPT;\n\tif (mask & FE_INVALID) mask |= FE_INVALID_SOFTWARE;\n\tset_fpscr(get_fpscr() | mask);\n\treturn 0;\n}\n\nint fetestexcept(int mask)\n{\n\treturn get_fpscr() & mask & FE_ALL_EXCEPT;\n}\n\nint fegetround(void)\n{\n\treturn get_fpscr() & 3;\n}\n\nhidden int __fesetround(int r)\n{\n\tset_fpscr(get_fpscr() & ~3L | r);\n\treturn 0;\n}\n\nint fegetenv(fenv_t *envp)\n{\n\t*envp = get_fpscr_f();\n\treturn 0;\n}\n\nint fesetenv(const fenv_t *envp)\n{\n\tset_fpscr_f(envp != FE_DFL_ENV ? *envp : 0);\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/fenv/riscv64/fenv-sf.c",
    "content": "#ifndef __riscv_flen\n#include \"../fenv.c\"\n#endif\n"
  },
  {
    "path": "user.libc/src/fenv/s390x/fenv.c",
    "content": "#include <fenv.h>\n#include <features.h>\n\nstatic inline unsigned get_fpc(void)\n{\n\tunsigned fpc;\n\t__asm__ __volatile__(\"efpc %0\" : \"=r\"(fpc));\n\treturn fpc;\n}\n\nstatic inline void set_fpc(unsigned fpc)\n{\n\t__asm__ __volatile__(\"sfpc %0\" :: \"r\"(fpc));\n}\n\nint feclearexcept(int mask)\n{\n\tmask &= FE_ALL_EXCEPT;\n\tset_fpc(get_fpc() & ~mask);\n\treturn 0;\n}\n\nint feraiseexcept(int mask)\n{\n\tmask &= FE_ALL_EXCEPT;\n\tset_fpc(get_fpc() | mask);\n\treturn 0;\n}\n\nint fetestexcept(int mask)\n{\n\treturn get_fpc() & mask & FE_ALL_EXCEPT;\n}\n\nint fegetround(void)\n{\n\treturn get_fpc() & 3;\n}\n\nhidden int __fesetround(int r)\n{\n\tset_fpc(get_fpc() & ~3L | r);\n\treturn 0;\n}\n\nint fegetenv(fenv_t *envp)\n{\n\t*envp = get_fpc();\n\treturn 0;\n}\n\nint fesetenv(const fenv_t *envp)\n{\n\tset_fpc(envp != FE_DFL_ENV ? *envp : 0);\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/fenv/sh/fenv-nofpu.c",
    "content": "#if !__SH_FPU_ANY__ && !__SH4__\n#include \"../fenv.c\"\n#endif\n"
  },
  {
    "path": "user.libc/src/include/arpa/inet.h",
    "content": "#ifndef ARPA_INET_H\n#define ARPA_INET_H\n\n#include \"../../../include/arpa/inet.h\"\n\nhidden int __inet_aton(const char *, struct in_addr *);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/include/crypt.h",
    "content": "#ifndef CRYPT_H\n#define CRYPT_H\n\n#include \"../../include/crypt.h\"\n\n#include <features.h>\n\nhidden char *__crypt_r(const char *, const char *, struct crypt_data *);\n\nhidden char *__crypt_des(const char *, const char *, char *);\nhidden char *__crypt_md5(const char *, const char *, char *);\nhidden char *__crypt_blowfish(const char *, const char *, char *);\nhidden char *__crypt_sha256(const char *, const char *, char *);\nhidden char *__crypt_sha512(const char *, const char *, char *);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/include/errno.h",
    "content": "#ifndef ERRNO_H\n#define ERRNO_H\n\n#include \"../../include/errno.h\"\n\n#ifdef __GNUC__\n__attribute__((const))\n#endif\nhidden int *___errno_location(void);\n\n#undef errno\n#define errno (*___errno_location())\n\n#endif\n"
  },
  {
    "path": "user.libc/src/include/features.h",
    "content": "#ifndef FEATURES_H\n#define FEATURES_H\n\n#include \"../../include/features.h\"\n\n#define weak __attribute__((__weak__))\n#define hidden __attribute__((__visibility__(\"hidden\")))\n#define weak_alias(old, new) \\\n\textern __typeof(old) new __attribute__((__weak__, __alias__(#old)))\n\n#endif\n"
  },
  {
    "path": "user.libc/src/include/langinfo.h",
    "content": "#ifndef LANGINFO_H\n#define LANGINFO_H\n\n#include \"../../include/langinfo.h\"\n\nchar *__nl_langinfo_l(nl_item, locale_t);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/include/pthread.h",
    "content": "#ifndef PTHREAD_H\n#define PTHREAD_H\n\n#include \"../../include/pthread.h\"\n\nhidden int __pthread_once(pthread_once_t *, void (*)(void));\nhidden void __pthread_testcancel(void);\nhidden int __pthread_setcancelstate(int, int *);\nhidden int __pthread_create(pthread_t *restrict, const pthread_attr_t *restrict, void *(*)(void *), void *restrict);\nhidden _Noreturn void __pthread_exit(void *);\nhidden int __pthread_join(pthread_t, void **);\nhidden int __pthread_mutex_lock(pthread_mutex_t *);\nhidden int __pthread_mutex_trylock(pthread_mutex_t *);\nhidden int __pthread_mutex_trylock_owner(pthread_mutex_t *);\nhidden int __pthread_mutex_timedlock(pthread_mutex_t *restrict, const struct timespec *restrict);\nhidden int __pthread_mutex_unlock(pthread_mutex_t *);\nhidden int __private_cond_signal(pthread_cond_t *, int);\nhidden int __pthread_cond_timedwait(pthread_cond_t *restrict, pthread_mutex_t *restrict, const struct timespec *restrict);\nhidden int __pthread_key_create(pthread_key_t *, void (*)(void *));\nhidden int __pthread_key_delete(pthread_key_t);\nhidden int __pthread_rwlock_rdlock(pthread_rwlock_t *);\nhidden int __pthread_rwlock_tryrdlock(pthread_rwlock_t *);\nhidden int __pthread_rwlock_timedrdlock(pthread_rwlock_t *__restrict, const struct timespec *__restrict);\nhidden int __pthread_rwlock_wrlock(pthread_rwlock_t *);\nhidden int __pthread_rwlock_trywrlock(pthread_rwlock_t *);\nhidden int __pthread_rwlock_timedwrlock(pthread_rwlock_t *__restrict, const struct timespec *__restrict);\nhidden int __pthread_rwlock_unlock(pthread_rwlock_t *);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/include/resolv.h",
    "content": "#ifndef RESOLV_H\n#define RESOLV_H\n\n#include \"../../include/resolv.h\"\n\nhidden int __dn_expand(const unsigned char *, const unsigned char *, const unsigned char *, char *, int);\n\nhidden int __res_mkquery(int, const char *, int, int, const unsigned char *, int, const unsigned char*, unsigned char *, int);\nhidden int __res_send(const unsigned char *, int, unsigned char *, int);\nhidden int __res_msend(int, const unsigned char *const *, const int *, unsigned char *const *, int *, int);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/include/signal.h",
    "content": "#ifndef SIGNAL_H\n#define SIGNAL_H\n\n#include \"../../include/signal.h\"\n\nhidden int __sigaction(int, const struct sigaction *, struct sigaction *);\n\nhidden void __block_all_sigs(void *);\nhidden void __block_app_sigs(void *);\nhidden void __restore_sigs(void *);\n\nhidden void __get_handler_set(sigset_t *);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/include/stdio.h",
    "content": "#ifndef STDIO_H\n#define STDIO_H\n\n#define __DEFINED_struct__IO_FILE\n\n#include \"../../include/stdio.h\"\n\n#undef stdin\n#undef stdout\n#undef stderr\n\nextern hidden FILE __stdin_FILE;\nextern hidden FILE __stdout_FILE;\nextern hidden FILE __stderr_FILE;\n\n#define stdin (&__stdin_FILE)\n#define stdout (&__stdout_FILE)\n#define stderr (&__stderr_FILE)\n\n#endif\n"
  },
  {
    "path": "user.libc/src/include/stdlib.h",
    "content": "#ifndef STDLIB_H\n#define STDLIB_H\n\n#include \"../../include/stdlib.h\"\n\nhidden int __putenv(char *, size_t, char *);\nhidden void __env_rm_add(char *, char *);\nhidden int __mkostemps(char *, int, int);\nhidden int __ptsname_r(int, char *, size_t);\nhidden char *__randname(char *);\n\nhidden void *__libc_malloc(size_t);\nhidden void *__libc_malloc_impl(size_t);\nhidden void *__libc_calloc(size_t, size_t);\nhidden void *__libc_realloc(void *, size_t);\nhidden void __libc_free(void *);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/include/string.h",
    "content": "#ifndef STRING_H\n#define STRING_H\n\n#include \"../../include/string.h\"\n\nhidden void *__memrchr(const void *, int, size_t);\nhidden char *__stpcpy(char *, const char *);\nhidden char *__stpncpy(char *, const char *, size_t);\nhidden char *__strchrnul(const char *, int);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/include/sys/auxv.h",
    "content": "#ifndef SYS_AUXV_H\n#define SYS_AUXV_H\n\n#include \"../../../include/sys/auxv.h\"\n\n#include <features.h>\n\nhidden unsigned long __getauxval(unsigned long);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/include/sys/membarrier.h",
    "content": "#ifndef SYS_MEMBARRIER_H\n#define SYS_MEMBARRIER_H\n\n#include \"../../../include/sys/membarrier.h\"\n#include <features.h>\n\nhidden int __membarrier(int, int);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/include/sys/mman.h",
    "content": "#ifndef SYS_MMAN_H\n#define SYS_MMAN_H\n\n#include \"../../../include/sys/mman.h\"\n\nhidden void __vm_wait(void);\nhidden void __vm_lock(void);\nhidden void __vm_unlock(void);\n\nhidden void *__mmap(void *, size_t, int, int, int, off_t);\nhidden int __munmap(void *, size_t);\nhidden void *__mremap(void *, size_t, size_t, int, ...);\nhidden int __madvise(void *, size_t, int);\nhidden int __mprotect(void *, size_t, int);\n\nhidden const unsigned char *__map_file(const char *, size_t *);\n\nhidden char *__shm_mapname(const char *, char *);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/include/sys/sysinfo.h",
    "content": "#ifndef SYS_SYSINFO_H\n#define SYS_SYSINFO_H\n\n#include \"../../../include/sys/sysinfo.h\"\n#include <features.h>\n\nhidden int __lsysinfo(struct sysinfo *);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/include/sys/time.h",
    "content": "#ifndef SYS_TIME_H\n#define SYS_TIME_H\n\n#include \"../../../include/sys/time.h\"\n\nhidden int __futimesat(int, const char *, const struct timeval [2]);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/include/time.h",
    "content": "#ifndef TIME_H\n#define TIME_H\n\n#include \"../../include/time.h\"\n\nhidden int __clock_gettime(clockid_t, struct timespec *);\nhidden int __clock_nanosleep(clockid_t, int, const struct timespec *, struct timespec *);\n\nhidden char *__asctime_r(const struct tm *, char *);\nhidden struct tm *__gmtime_r(const time_t *restrict, struct tm *restrict);\nhidden struct tm *__localtime_r(const time_t *restrict, struct tm *restrict);\n\nhidden size_t __strftime_l(char *restrict, size_t, const char *restrict, const struct tm *restrict, locale_t);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/include/unistd.h",
    "content": "#ifndef UNISTD_H\n#define UNISTD_H\n\n#include \"../../include/unistd.h\"\n\nextern char **__environ;\n\nhidden int __dup3(int, int, int);\nhidden int __mkostemps(char *, int, int);\nhidden int __execvpe(const char *, char *const *, char *const *);\nhidden off_t __lseek(int, off_t, int);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/include/wchar.h",
    "content": "#ifndef WCHAR_H\n#define WCHAR_H\n\n#define __DEFINED_struct__IO_FILE\n\n#include \"../../include/wchar.h\"\n\n#endif\n\n"
  },
  {
    "path": "user.libc/src/internal/aio_impl.h",
    "content": "#ifndef AIO_IMPL_H\n#define AIO_IMPL_H\n\nextern hidden volatile int __aio_fut;\n\nextern hidden int __aio_close(int);\nextern hidden void __aio_atfork(int);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/internal/asm.inc",
    "content": ".macro func _name, align=2\n\t.cfi_sections .debug_frame\n\t.section __asm_code, \"ax\"\n\t.type \\_name, %function\n\t.func \\_name\n\t.cfi_startproc\n\t.align \\align\n\t\\_name:\n.endm\n\n.macro endfunc _name\n\t.endfunc\n\t.cfi_endproc\n\t.size \\_name, . - \\_name\n.endm\n\n\n"
  },
  {
    "path": "user.libc/src/internal/atomic.h",
    "content": "#ifndef _ATOMIC_H\n#define _ATOMIC_H\n\n#include <stdint.h>\n\n#include \"atomic_arch.h\"\n\n#ifdef a_ll\n\n#ifndef a_pre_llsc\n#define a_pre_llsc()\n#endif\n\n#ifndef a_post_llsc\n#define a_post_llsc()\n#endif\n\n#ifndef a_cas\n#define a_cas a_cas\nstatic inline int a_cas(volatile int *p, int t, int s)\n{\n\tint old;\n\ta_pre_llsc();\n\tdo old = a_ll(p);\n\twhile (old==t && !a_sc(p, s));\n\ta_post_llsc();\n\treturn old;\n}\n#endif\n\n#ifndef a_swap\n#define a_swap a_swap\nstatic inline int a_swap(volatile int *p, int v)\n{\n\tint old;\n\ta_pre_llsc();\n\tdo old = a_ll(p);\n\twhile (!a_sc(p, v));\n\ta_post_llsc();\n\treturn old;\n}\n#endif\n\n#ifndef a_fetch_add\n#define a_fetch_add a_fetch_add\nstatic inline int a_fetch_add(volatile int *p, int v)\n{\n\tint old;\n\ta_pre_llsc();\n\tdo old = a_ll(p);\n\twhile (!a_sc(p, (unsigned)old + v));\n\ta_post_llsc();\n\treturn old;\n}\n#endif\n\n#ifndef a_fetch_and\n#define a_fetch_and a_fetch_and\nstatic inline int a_fetch_and(volatile int *p, int v)\n{\n\tint old;\n\ta_pre_llsc();\n\tdo old = a_ll(p);\n\twhile (!a_sc(p, old & v));\n\ta_post_llsc();\n\treturn old;\n}\n#endif\n\n#ifndef a_fetch_or\n#define a_fetch_or a_fetch_or\nstatic inline int a_fetch_or(volatile int *p, int v)\n{\n\tint old;\n\ta_pre_llsc();\n\tdo old = a_ll(p);\n\twhile (!a_sc(p, old | v));\n\ta_post_llsc();\n\treturn old;\n}\n#endif\n\n#endif\n\n#ifdef a_ll_p\n\n#ifndef a_cas_p\n#define a_cas_p a_cas_p\nstatic inline void *a_cas_p(volatile void *p, void *t, void *s)\n{\n\tvoid *old;\n\ta_pre_llsc();\n\tdo old = a_ll_p(p);\n\twhile (old==t && !a_sc_p(p, s));\n\ta_post_llsc();\n\treturn old;\n}\n#endif\n\n#endif\n\n#ifndef a_cas\n#error missing definition of a_cas\n#endif\n\n#ifndef a_swap\n#define a_swap a_swap\nstatic inline int a_swap(volatile int *p, int v)\n{\n\tint old;\n\tdo old = *p;\n\twhile (a_cas(p, old, v) != old);\n\treturn old;\n}\n#endif\n\n#ifndef a_fetch_add\n#define a_fetch_add a_fetch_add\nstatic inline int a_fetch_add(volatile int *p, int v)\n{\n\tint old;\n\tdo old = *p;\n\twhile (a_cas(p, old, (unsigned)old+v) != old);\n\treturn old;\n}\n#endif\n\n#ifndef a_fetch_and\n#define a_fetch_and a_fetch_and\nstatic inline int a_fetch_and(volatile int *p, int v)\n{\n\tint old;\n\tdo old = *p;\n\twhile (a_cas(p, old, old&v) != old);\n\treturn old;\n}\n#endif\n#ifndef a_fetch_or\n#define a_fetch_or a_fetch_or\nstatic inline int a_fetch_or(volatile int *p, int v)\n{\n\tint old;\n\tdo old = *p;\n\twhile (a_cas(p, old, old|v) != old);\n\treturn old;\n}\n#endif\n\n#ifndef a_and\n#define a_and a_and\nstatic inline void a_and(volatile int *p, int v)\n{\n\ta_fetch_and(p, v);\n}\n#endif\n\n#ifndef a_or\n#define a_or a_or\nstatic inline void a_or(volatile int *p, int v)\n{\n\ta_fetch_or(p, v);\n}\n#endif\n\n#ifndef a_inc\n#define a_inc a_inc\nstatic inline void a_inc(volatile int *p)\n{\n\ta_fetch_add(p, 1);\n}\n#endif\n\n#ifndef a_dec\n#define a_dec a_dec\nstatic inline void a_dec(volatile int *p)\n{\n\ta_fetch_add(p, -1);\n}\n#endif\n\n#ifndef a_store\n#define a_store a_store\nstatic inline void a_store(volatile int *p, int v)\n{\n#ifdef a_barrier\n\ta_barrier();\n\t*p = v;\n\ta_barrier();\n#else\n\ta_swap(p, v);\n#endif\n}\n#endif\n\n#ifndef a_barrier\n#define a_barrier a_barrier\nstatic void a_barrier()\n{\n\tvolatile int tmp = 0;\n\ta_cas(&tmp, 0, 0);\n}\n#endif\n\n#ifndef a_spin\n#define a_spin a_barrier\n#endif\n\n#ifndef a_and_64\n#define a_and_64 a_and_64\nstatic inline void a_and_64(volatile uint64_t *p, uint64_t v)\n{\n\tunion { uint64_t v; uint32_t r[2]; } u = { v };\n\tif (u.r[0]+1) a_and((int *)p, u.r[0]);\n\tif (u.r[1]+1) a_and((int *)p+1, u.r[1]);\n}\n#endif\n\n#ifndef a_or_64\n#define a_or_64 a_or_64\nstatic inline void a_or_64(volatile uint64_t *p, uint64_t v)\n{\n\tunion { uint64_t v; uint32_t r[2]; } u = { v };\n\tif (u.r[0]) a_or((int *)p, u.r[0]);\n\tif (u.r[1]) a_or((int *)p+1, u.r[1]);\n}\n#endif\n\n#ifndef a_cas_p\ntypedef char a_cas_p_undefined_but_pointer_not_32bit[-sizeof(char) == 0xffffffff ? 1 : -1];\n#define a_cas_p a_cas_p\nstatic inline void *a_cas_p(volatile void *p, void *t, void *s)\n{\n\treturn (void *)a_cas((volatile int *)p, (int)t, (int)s);\n}\n#endif\n\n#ifndef a_or_l\n#define a_or_l a_or_l\nstatic inline void a_or_l(volatile void *p, long v)\n{\n\tif (sizeof(long) == sizeof(int)) a_or(p, v);\n\telse a_or_64(p, v);\n}\n#endif\n\n#ifndef a_crash\n#define a_crash a_crash\nstatic inline void a_crash()\n{\n\t*(volatile char *)0=0;\n}\n#endif\n\n#ifndef a_ctz_32\n#define a_ctz_32 a_ctz_32\nstatic inline int a_ctz_32(uint32_t x)\n{\n#ifdef a_clz_32\n\treturn 31-a_clz_32(x&-x);\n#else\n\tstatic const char debruijn32[32] = {\n\t\t0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,\n\t\t31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14\n\t};\n\treturn debruijn32[(x&-x)*0x076be629 >> 27];\n#endif\n}\n#endif\n\n#ifndef a_ctz_64\n#define a_ctz_64 a_ctz_64\nstatic inline int a_ctz_64(uint64_t x)\n{\n\tstatic const char debruijn64[64] = {\n\t\t0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,\n\t\t62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,\n\t\t63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,\n\t\t51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12\n\t};\n\tif (sizeof(long) < 8) {\n\t\tuint32_t y = x;\n\t\tif (!y) {\n\t\t\ty = x>>32;\n\t\t\treturn 32 + a_ctz_32(y);\n\t\t}\n\t\treturn a_ctz_32(y);\n\t}\n\treturn debruijn64[(x&-x)*0x022fdd63cc95386dull >> 58];\n}\n#endif\n\nstatic inline int a_ctz_l(unsigned long x)\n{\n\treturn (sizeof(long) < 8) ? a_ctz_32(x) : a_ctz_64(x);\n}\n\n#ifndef a_clz_64\n#define a_clz_64 a_clz_64\nstatic inline int a_clz_64(uint64_t x)\n{\n#ifdef a_clz_32\n\tif (x>>32)\n\t\treturn a_clz_32(x>>32);\n\treturn a_clz_32(x) + 32;\n#else\n\tuint32_t y;\n\tint r;\n\tif (x>>32) y=x>>32, r=0; else y=x, r=32;\n\tif (y>>16) y>>=16; else r |= 16;\n\tif (y>>8) y>>=8; else r |= 8;\n\tif (y>>4) y>>=4; else r |= 4;\n\tif (y>>2) y>>=2; else r |= 2;\n\treturn r | !(y>>1);\n#endif\n}\n#endif\n\n#ifndef a_clz_32\n#define a_clz_32 a_clz_32\nstatic inline int a_clz_32(uint32_t x)\n{\n\tx >>= 1;\n\tx |= x >> 1;\n\tx |= x >> 2;\n\tx |= x >> 4;\n\tx |= x >> 8;\n\tx |= x >> 16;\n\tx++;\n\treturn 31-a_ctz_32(x);\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/src/internal/complex_impl.h",
    "content": "#ifndef _COMPLEX_IMPL_H\n#define _COMPLEX_IMPL_H\n\n#include <complex.h>\n#include \"libm.h\"\n\n#undef __CMPLX\n#undef CMPLX\n#undef CMPLXF\n#undef CMPLXL\n\n#define __CMPLX(x, y, t) \\\n\t((union { _Complex t __z; t __xy[2]; }){.__xy = {(x),(y)}}.__z)\n\n#define CMPLX(x, y) __CMPLX(x, y, double)\n#define CMPLXF(x, y) __CMPLX(x, y, float)\n#define CMPLXL(x, y) __CMPLX(x, y, long double)\n\nhidden double complex __ldexp_cexp(double complex,int);\nhidden float complex __ldexp_cexpf(float complex,int);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/internal/defsysinfo.c",
    "content": "#include \"libc.h\"\n\nsize_t __sysinfo;\n"
  },
  {
    "path": "user.libc/src/internal/dynlink.h",
    "content": "#ifndef _INTERNAL_RELOC_H\n#define _INTERNAL_RELOC_H\n\n#include <features.h>\n#include <elf.h>\n#include <stdint.h>\n#include <stddef.h>\n#include <stdarg.h>\n\n#if UINTPTR_MAX == 0xffffffff\ntypedef Elf32_Ehdr Ehdr;\ntypedef Elf32_Phdr Phdr;\ntypedef Elf32_Sym Sym;\n#define R_TYPE(x) ((x)&255)\n#define R_SYM(x) ((x)>>8)\n#define R_INFO ELF32_R_INFO\n#else\ntypedef Elf64_Ehdr Ehdr;\ntypedef Elf64_Phdr Phdr;\ntypedef Elf64_Sym Sym;\n#define R_TYPE(x) ((x)&0x7fffffff)\n#define R_SYM(x) ((x)>>32)\n#define R_INFO ELF64_R_INFO\n#endif\n\n/* These enum constants provide unmatchable default values for\n * any relocation type the arch does not use. */\nenum {\n\tREL_NONE = 0,\n\tREL_SYMBOLIC = -100,\n\tREL_USYMBOLIC,\n\tREL_GOT,\n\tREL_PLT,\n\tREL_RELATIVE,\n\tREL_OFFSET,\n\tREL_OFFSET32,\n\tREL_COPY,\n\tREL_SYM_OR_REL,\n\tREL_DTPMOD,\n\tREL_DTPOFF,\n\tREL_TPOFF,\n\tREL_TPOFF_NEG,\n\tREL_TLSDESC,\n\tREL_FUNCDESC,\n\tREL_FUNCDESC_VAL,\n};\n\nstruct fdpic_loadseg {\n\tuintptr_t addr, p_vaddr, p_memsz;\n};\n\nstruct fdpic_loadmap {\n\tunsigned short version, nsegs;\n\tstruct fdpic_loadseg segs[];\n};\n\nstruct fdpic_dummy_loadmap {\n\tunsigned short version, nsegs;\n\tstruct fdpic_loadseg segs[1];\n};\n\n#include \"reloc.h\"\n\n#ifndef FDPIC_CONSTDISP_FLAG\n#define FDPIC_CONSTDISP_FLAG 0\n#endif\n\n#ifndef DL_FDPIC\n#define DL_FDPIC 0\n#endif\n\n#ifndef DL_NOMMU_SUPPORT\n#define DL_NOMMU_SUPPORT 0\n#endif\n\n#if !DL_FDPIC\n#define IS_RELATIVE(x,s) ( \\\n\t(R_TYPE(x) == REL_RELATIVE) || \\\n\t(R_TYPE(x) == REL_SYM_OR_REL && !R_SYM(x)) )\n#else\n#define IS_RELATIVE(x,s) ( ( \\\n\t(R_TYPE(x) == REL_FUNCDESC_VAL) || \\\n\t(R_TYPE(x) == REL_SYMBOLIC) ) \\\n\t&& (((s)[R_SYM(x)].st_info & 0xf) == STT_SECTION) )\n#endif\n\n#ifndef NEED_MIPS_GOT_RELOCS\n#define NEED_MIPS_GOT_RELOCS 0\n#endif\n\n#ifndef DT_DEBUG_INDIRECT\n#define DT_DEBUG_INDIRECT 0\n#endif\n\n#define AUX_CNT 32\n#define DYN_CNT 32\n\ntypedef void (*stage2_func)(unsigned char *, size_t *);\n\nhidden void *__dlsym(void *restrict, const char *restrict, void *restrict);\n\nhidden void __dl_seterr(const char *, ...);\nhidden int __dl_invalid_handle(void *);\nhidden void __dl_vseterr(const char *, va_list);\n\nhidden ptrdiff_t __tlsdesc_static(), __tlsdesc_dynamic();\n\nhidden extern int __malloc_replaced;\nhidden extern int __aligned_alloc_replaced;\nhidden void __malloc_donate(char *, char *);\nhidden int __malloc_allzerop(void *);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/internal/fdpic_crt.h",
    "content": "#include <stdint.h>\n#include <features.h>\n\nhidden void *__fdpic_fixup(void *map, uintptr_t *a, uintptr_t *z)\n{\n\t/* If map is a null pointer, the program was loaded by a\n\t * non-FDPIC-aware ELF loader, and fixups are not needed,\n\t * but the value for the GOT pointer is. */\n\tif (!map) return (void *)z[-1];\n\n\tstruct {\n\t\tunsigned short version, nsegs;\n\t\tstruct fdpic_loadseg {\n\t\t\tuintptr_t addr, p_vaddr, p_memsz;\n\t\t} segs[];\n\t} *lm = map;\n\tint nsegs = lm->nsegs, rseg = 0, vseg = 0;\n\tfor (;;) {\n\t\twhile (*a-lm->segs[rseg].p_vaddr >= lm->segs[rseg].p_memsz)\n\t\t\tif (++rseg == nsegs) rseg = 0;\n\t\tuintptr_t *r = (uintptr_t *)\n\t\t\t(*a + lm->segs[rseg].addr - lm->segs[rseg].p_vaddr);\n\t\tif (++a == z) return r;\n\t\twhile (*r-lm->segs[vseg].p_vaddr >= lm->segs[vseg].p_memsz)\n\t\t\tif (++vseg == nsegs) vseg = 0;\n\t\t*r += lm->segs[vseg].addr - lm->segs[vseg].p_vaddr;\n\t}\n}\n"
  },
  {
    "path": "user.libc/src/internal/floatscan.c",
    "content": "#include <stdint.h>\n#include <stdio.h>\n#include <math.h>\n#include <float.h>\n#include <limits.h>\n#include <errno.h>\n#include <ctype.h>\n\n#include \"shgetc.h\"\n#include \"floatscan.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\n\n#define LD_B1B_DIG 2\n#define LD_B1B_MAX 9007199, 254740991\n#define KMAX 128\n\n#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384\n\n#define LD_B1B_DIG 3\n#define LD_B1B_MAX 18, 446744073, 709551615\n#define KMAX 2048\n\n#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384\n\n#define LD_B1B_DIG 4\n#define LD_B1B_MAX 10384593, 717069655, 257060992, 658440191\n#define KMAX 2048\n\n#else\n#error Unsupported long double representation\n#endif\n\n#define MASK (KMAX-1)\n\nstatic long long scanexp(FILE *f, int pok)\n{\n\tint c;\n\tint x;\n\tlong long y;\n\tint neg = 0;\n\t\n\tc = shgetc(f);\n\tif (c=='+' || c=='-') {\n\t\tneg = (c=='-');\n\t\tc = shgetc(f);\n\t\tif (c-'0'>=10U && pok) shunget(f);\n\t}\n\tif (c-'0'>=10U) {\n\t\tshunget(f);\n\t\treturn LLONG_MIN;\n\t}\n\tfor (x=0; c-'0'<10U && x<INT_MAX/10; c = shgetc(f))\n\t\tx = 10*x + c-'0';\n\tfor (y=x; c-'0'<10U && y<LLONG_MAX/100; c = shgetc(f))\n\t\ty = 10*y + c-'0';\n\tfor (; c-'0'<10U; c = shgetc(f));\n\tshunget(f);\n\treturn neg ? -y : y;\n}\n\n\nstatic long double decfloat(FILE *f, int c, int bits, int emin, int sign, int pok)\n{\n\tuint32_t x[KMAX];\n\tstatic const uint32_t th[] = { LD_B1B_MAX };\n\tint i, j, k, a, z;\n\tlong long lrp=0, dc=0;\n\tlong long e10=0;\n\tint lnz = 0;\n\tint gotdig = 0, gotrad = 0;\n\tint rp;\n\tint e2;\n\tint emax = -emin-bits+3;\n\tint denormal = 0;\n\tlong double y;\n\tlong double frac=0;\n\tlong double bias=0;\n\tstatic const int p10s[] = { 10, 100, 1000, 10000,\n\t\t100000, 1000000, 10000000, 100000000 };\n\n\tj=0;\n\tk=0;\n\n\t/* Don't let leading zeros consume buffer space */\n\tfor (; c=='0'; c = shgetc(f)) gotdig=1;\n\tif (c=='.') {\n\t\tgotrad = 1;\n\t\tfor (c = shgetc(f); c=='0'; c = shgetc(f)) gotdig=1, lrp--;\n\t}\n\n\tx[0] = 0;\n\tfor (; c-'0'<10U || c=='.'; c = shgetc(f)) {\n\t\tif (c == '.') {\n\t\t\tif (gotrad) break;\n\t\t\tgotrad = 1;\n\t\t\tlrp = dc;\n\t\t} else if (k < KMAX-3) {\n\t\t\tdc++;\n\t\t\tif (c!='0') lnz = dc;\n\t\t\tif (j) x[k] = x[k]*10 + c-'0';\n\t\t\telse x[k] = c-'0';\n\t\t\tif (++j==9) {\n\t\t\t\tk++;\n\t\t\t\tj=0;\n\t\t\t}\n\t\t\tgotdig=1;\n\t\t} else {\n\t\t\tdc++;\n\t\t\tif (c!='0') {\n\t\t\t\tlnz = (KMAX-4)*9;\n\t\t\t\tx[KMAX-4] |= 1;\n\t\t\t}\n\t\t}\n\t}\n\tif (!gotrad) lrp=dc;\n\n\tif (gotdig && (c|32)=='e') {\n\t\te10 = scanexp(f, pok);\n\t\tif (e10 == LLONG_MIN) {\n\t\t\tif (pok) {\n\t\t\t\tshunget(f);\n\t\t\t} else {\n\t\t\t\tshlim(f, 0);\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\te10 = 0;\n\t\t}\n\t\tlrp += e10;\n\t} else if (c>=0) {\n\t\tshunget(f);\n\t}\n\tif (!gotdig) {\n\t\terrno = EINVAL;\n\t\tshlim(f, 0);\n\t\treturn 0;\n\t}\n\n\t/* Handle zero specially to avoid nasty special cases later */\n\tif (!x[0]) return sign * 0.0;\n\n\t/* Optimize small integers (w/no exponent) and over/under-flow */\n\tif (lrp==dc && dc<10 && (bits>30 || x[0]>>bits==0))\n\t\treturn sign * (long double)x[0];\n\tif (lrp > -emin/2) {\n\t\terrno = ERANGE;\n\t\treturn sign * LDBL_MAX * LDBL_MAX;\n\t}\n\tif (lrp < emin-2*LDBL_MANT_DIG) {\n\t\terrno = ERANGE;\n\t\treturn sign * LDBL_MIN * LDBL_MIN;\n\t}\n\n\t/* Align incomplete final B1B digit */\n\tif (j) {\n\t\tfor (; j<9; j++) x[k]*=10;\n\t\tk++;\n\t\tj=0;\n\t}\n\n\ta = 0;\n\tz = k;\n\te2 = 0;\n\trp = lrp;\n\n\t/* Optimize small to mid-size integers (even in exp. notation) */\n\tif (lnz<9 && lnz<=rp && rp < 18) {\n\t\tif (rp == 9) return sign * (long double)x[0];\n\t\tif (rp < 9) return sign * (long double)x[0] / p10s[8-rp];\n\t\tint bitlim = bits-3*(int)(rp-9);\n\t\tif (bitlim>30 || x[0]>>bitlim==0)\n\t\t\treturn sign * (long double)x[0] * p10s[rp-10];\n\t}\n\n\t/* Drop trailing zeros */\n\tfor (; !x[z-1]; z--);\n\n\t/* Align radix point to B1B digit boundary */\n\tif (rp % 9) {\n\t\tint rpm9 = rp>=0 ? rp%9 : rp%9+9;\n\t\tint p10 = p10s[8-rpm9];\n\t\tuint32_t carry = 0;\n\t\tfor (k=a; k!=z; k++) {\n\t\t\tuint32_t tmp = x[k] % p10;\n\t\t\tx[k] = x[k]/p10 + carry;\n\t\t\tcarry = 1000000000/p10 * tmp;\n\t\t\tif (k==a && !x[k]) {\n\t\t\t\ta = (a+1 & MASK);\n\t\t\t\trp -= 9;\n\t\t\t}\n\t\t}\n\t\tif (carry) x[z++] = carry;\n\t\trp += 9-rpm9;\n\t}\n\n\t/* Upscale until desired number of bits are left of radix point */\n\twhile (rp < 9*LD_B1B_DIG || (rp == 9*LD_B1B_DIG && x[a]<th[0])) {\n\t\tuint32_t carry = 0;\n\t\te2 -= 29;\n\t\tfor (k=(z-1 & MASK); ; k=(k-1 & MASK)) {\n\t\t\tuint64_t tmp = ((uint64_t)x[k] << 29) + carry;\n\t\t\tif (tmp > 1000000000) {\n\t\t\t\tcarry = tmp / 1000000000;\n\t\t\t\tx[k] = tmp % 1000000000;\n\t\t\t} else {\n\t\t\t\tcarry = 0;\n\t\t\t\tx[k] = tmp;\n\t\t\t}\n\t\t\tif (k==(z-1 & MASK) && k!=a && !x[k]) z = k;\n\t\t\tif (k==a) break;\n\t\t}\n\t\tif (carry) {\n\t\t\trp += 9;\n\t\t\ta = (a-1 & MASK);\n\t\t\tif (a == z) {\n\t\t\t\tz = (z-1 & MASK);\n\t\t\t\tx[z-1 & MASK] |= x[z];\n\t\t\t}\n\t\t\tx[a] = carry;\n\t\t}\n\t}\n\n\t/* Downscale until exactly number of bits are left of radix point */\n\tfor (;;) {\n\t\tuint32_t carry = 0;\n\t\tint sh = 1;\n\t\tfor (i=0; i<LD_B1B_DIG; i++) {\n\t\t\tk = (a+i & MASK);\n\t\t\tif (k == z || x[k] < th[i]) {\n\t\t\t\ti=LD_B1B_DIG;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (x[a+i & MASK] > th[i]) break;\n\t\t}\n\t\tif (i==LD_B1B_DIG && rp==9*LD_B1B_DIG) break;\n\t\t/* FIXME: find a way to compute optimal sh */\n\t\tif (rp > 9+9*LD_B1B_DIG) sh = 9;\n\t\te2 += sh;\n\t\tfor (k=a; k!=z; k=(k+1 & MASK)) {\n\t\t\tuint32_t tmp = x[k] & (1<<sh)-1;\n\t\t\tx[k] = (x[k]>>sh) + carry;\n\t\t\tcarry = (1000000000>>sh) * tmp;\n\t\t\tif (k==a && !x[k]) {\n\t\t\t\ta = (a+1 & MASK);\n\t\t\t\ti--;\n\t\t\t\trp -= 9;\n\t\t\t}\n\t\t}\n\t\tif (carry) {\n\t\t\tif ((z+1 & MASK) != a) {\n\t\t\t\tx[z] = carry;\n\t\t\t\tz = (z+1 & MASK);\n\t\t\t} else x[z-1 & MASK] |= 1;\n\t\t}\n\t}\n\n\t/* Assemble desired bits into floating point variable */\n\tfor (y=i=0; i<LD_B1B_DIG; i++) {\n\t\tif ((a+i & MASK)==z) x[(z=(z+1 & MASK))-1] = 0;\n\t\ty = 1000000000.0L * y + x[a+i & MASK];\n\t}\n\n\ty *= sign;\n\n\t/* Limit precision for denormal results */\n\tif (bits > LDBL_MANT_DIG+e2-emin) {\n\t\tbits = LDBL_MANT_DIG+e2-emin;\n\t\tif (bits<0) bits=0;\n\t\tdenormal = 1;\n\t}\n\n\t/* Calculate bias term to force rounding, move out lower bits */\n\tif (bits < LDBL_MANT_DIG) {\n\t\tbias = copysignl(scalbn(1, 2*LDBL_MANT_DIG-bits-1), y);\n\t\tfrac = fmodl(y, scalbn(1, LDBL_MANT_DIG-bits));\n\t\ty -= frac;\n\t\ty += bias;\n\t}\n\n\t/* Process tail of decimal input so it can affect rounding */\n\tif ((a+i & MASK) != z) {\n\t\tuint32_t t = x[a+i & MASK];\n\t\tif (t < 500000000 && (t || (a+i+1 & MASK) != z))\n\t\t\tfrac += 0.25*sign;\n\t\telse if (t > 500000000)\n\t\t\tfrac += 0.75*sign;\n\t\telse if (t == 500000000) {\n\t\t\tif ((a+i+1 & MASK) == z)\n\t\t\t\tfrac += 0.5*sign;\n\t\t\telse\n\t\t\t\tfrac += 0.75*sign;\n\t\t}\n\t\tif (LDBL_MANT_DIG-bits >= 2 && !fmodl(frac, 1))\n\t\t\tfrac++;\n\t}\n\n\ty += frac;\n\ty -= bias;\n\n\tif ((e2+LDBL_MANT_DIG & INT_MAX) > emax-5) {\n\t\tif (fabsl(y) >= 2/LDBL_EPSILON) {\n\t\t\tif (denormal && bits==LDBL_MANT_DIG+e2-emin)\n\t\t\t\tdenormal = 0;\n\t\t\ty *= 0.5;\n\t\t\te2++;\n\t\t}\n\t\tif (e2+LDBL_MANT_DIG>emax || (denormal && frac))\n\t\t\terrno = ERANGE;\n\t}\n\n\treturn scalbnl(y, e2);\n}\n\nstatic long double hexfloat(FILE *f, int bits, int emin, int sign, int pok)\n{\n\tuint32_t x = 0;\n\tlong double y = 0;\n\tlong double scale = 1;\n\tlong double bias = 0;\n\tint gottail = 0, gotrad = 0, gotdig = 0;\n\tlong long rp = 0;\n\tlong long dc = 0;\n\tlong long e2 = 0;\n\tint d;\n\tint c;\n\n\tc = shgetc(f);\n\n\t/* Skip leading zeros */\n\tfor (; c=='0'; c = shgetc(f)) gotdig = 1;\n\n\tif (c=='.') {\n\t\tgotrad = 1;\n\t\tc = shgetc(f);\n\t\t/* Count zeros after the radix point before significand */\n\t\tfor (rp=0; c=='0'; c = shgetc(f), rp--) gotdig = 1;\n\t}\n\n\tfor (; c-'0'<10U || (c|32)-'a'<6U || c=='.'; c = shgetc(f)) {\n\t\tif (c=='.') {\n\t\t\tif (gotrad) break;\n\t\t\trp = dc;\n\t\t\tgotrad = 1;\n\t\t} else {\n\t\t\tgotdig = 1;\n\t\t\tif (c > '9') d = (c|32)+10-'a';\n\t\t\telse d = c-'0';\n\t\t\tif (dc<8) {\n\t\t\t\tx = x*16 + d;\n\t\t\t} else if (dc < LDBL_MANT_DIG/4+1) {\n\t\t\t\ty += d*(scale/=16);\n\t\t\t} else if (d && !gottail) {\n\t\t\t\ty += 0.5*scale;\n\t\t\t\tgottail = 1;\n\t\t\t}\n\t\t\tdc++;\n\t\t}\n\t}\n\tif (!gotdig) {\n\t\tshunget(f);\n\t\tif (pok) {\n\t\t\tshunget(f);\n\t\t\tif (gotrad) shunget(f);\n\t\t} else {\n\t\t\tshlim(f, 0);\n\t\t}\n\t\treturn sign * 0.0;\n\t}\n\tif (!gotrad) rp = dc;\n\twhile (dc<8) x *= 16, dc++;\n\tif ((c|32)=='p') {\n\t\te2 = scanexp(f, pok);\n\t\tif (e2 == LLONG_MIN) {\n\t\t\tif (pok) {\n\t\t\t\tshunget(f);\n\t\t\t} else {\n\t\t\t\tshlim(f, 0);\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\te2 = 0;\n\t\t}\n\t} else {\n\t\tshunget(f);\n\t}\n\te2 += 4*rp - 32;\n\n\tif (!x) return sign * 0.0;\n\tif (e2 > -emin) {\n\t\terrno = ERANGE;\n\t\treturn sign * LDBL_MAX * LDBL_MAX;\n\t}\n\tif (e2 < emin-2*LDBL_MANT_DIG) {\n\t\terrno = ERANGE;\n\t\treturn sign * LDBL_MIN * LDBL_MIN;\n\t}\n\n\twhile (x < 0x80000000) {\n\t\tif (y>=0.5) {\n\t\t\tx += x + 1;\n\t\t\ty += y - 1;\n\t\t} else {\n\t\t\tx += x;\n\t\t\ty += y;\n\t\t}\n\t\te2--;\n\t}\n\n\tif (bits > 32+e2-emin) {\n\t\tbits = 32+e2-emin;\n\t\tif (bits<0) bits=0;\n\t}\n\n\tif (bits < LDBL_MANT_DIG)\n\t\tbias = copysignl(scalbn(1, 32+LDBL_MANT_DIG-bits-1), sign);\n\n\tif (bits<32 && y && !(x&1)) x++, y=0;\n\n\ty = bias + sign*(long double)x + sign*y;\n\ty -= bias;\n\n\tif (!y) errno = ERANGE;\n\n\treturn scalbnl(y, e2);\n}\n\nlong double __floatscan(FILE *f, int prec, int pok)\n{\n\tint sign = 1;\n\tsize_t i;\n\tint bits;\n\tint emin;\n\tint c;\n\n\tswitch (prec) {\n\tcase 0:\n\t\tbits = FLT_MANT_DIG;\n\t\temin = FLT_MIN_EXP-bits;\n\t\tbreak;\n\tcase 1:\n\t\tbits = DBL_MANT_DIG;\n\t\temin = DBL_MIN_EXP-bits;\n\t\tbreak;\n\tcase 2:\n\t\tbits = LDBL_MANT_DIG;\n\t\temin = LDBL_MIN_EXP-bits;\n\t\tbreak;\n\tdefault:\n\t\treturn 0;\n\t}\n\n\twhile (isspace((c=shgetc(f))));\n\n\tif (c=='+' || c=='-') {\n\t\tsign -= 2*(c=='-');\n\t\tc = shgetc(f);\n\t}\n\n\tfor (i=0; i<8 && (c|32)==\"infinity\"[i]; i++)\n\t\tif (i<7) c = shgetc(f);\n\tif (i==3 || i==8 || (i>3 && pok)) {\n\t\tif (i!=8) {\n\t\t\tshunget(f);\n\t\t\tif (pok) for (; i>3; i--) shunget(f);\n\t\t}\n\t\treturn sign * INFINITY;\n\t}\n\tif (!i) for (i=0; i<3 && (c|32)==\"nan\"[i]; i++)\n\t\tif (i<2) c = shgetc(f);\n\tif (i==3) {\n\t\tif (shgetc(f) != '(') {\n\t\t\tshunget(f);\n\t\t\treturn NAN;\n\t\t}\n\t\tfor (i=1; ; i++) {\n\t\t\tc = shgetc(f);\n\t\t\tif (c-'0'<10U || c-'A'<26U || c-'a'<26U || c=='_')\n\t\t\t\tcontinue;\n\t\t\tif (c==')') return NAN;\n\t\t\tshunget(f);\n\t\t\tif (!pok) {\n\t\t\t\terrno = EINVAL;\n\t\t\t\tshlim(f, 0);\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\twhile (i--) shunget(f);\n\t\t\treturn NAN;\n\t\t}\n\t\treturn NAN;\n\t}\n\n\tif (i) {\n\t\tshunget(f);\n\t\terrno = EINVAL;\n\t\tshlim(f, 0);\n\t\treturn 0;\n\t}\n\n\tif (c=='0') {\n\t\tc = shgetc(f);\n\t\tif ((c|32) == 'x')\n\t\t\treturn hexfloat(f, bits, emin, sign, pok);\n\t\tshunget(f);\n\t\tc = '0';\n\t}\n\n\treturn decfloat(f, c, bits, emin, sign, pok);\n}\n"
  },
  {
    "path": "user.libc/src/internal/floatscan.h",
    "content": "#ifndef FLOATSCAN_H\n#define FLOATSCAN_H\n\n#include <stdio.h>\n\nhidden long double __floatscan(FILE *, int, int);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/internal/fork_impl.h",
    "content": "#include <features.h>\n\nextern hidden volatile int *const __at_quick_exit_lockptr;\nextern hidden volatile int *const __atexit_lockptr;\nextern hidden volatile int *const __dlerror_lockptr;\nextern hidden volatile int *const __gettext_lockptr;\nextern hidden volatile int *const __locale_lockptr;\nextern hidden volatile int *const __random_lockptr;\nextern hidden volatile int *const __sem_open_lockptr;\nextern hidden volatile int *const __stdio_ofl_lockptr;\nextern hidden volatile int *const __syslog_lockptr;\nextern hidden volatile int *const __timezone_lockptr;\n\nextern hidden volatile int *const __bump_lockptr;\n\nextern hidden volatile int *const __vmlock_lockptr;\n\nhidden void __malloc_atfork(int);\nhidden void __ldso_atfork(int);\n"
  },
  {
    "path": "user.libc/src/internal/futex.h",
    "content": "#ifndef _INTERNAL_FUTEX_H\n#define _INTERNAL_FUTEX_H\n\n#define FUTEX_WAIT\t\t0\n#define FUTEX_WAKE\t\t1\n#define FUTEX_FD\t\t2\n#define FUTEX_REQUEUE\t\t3\n#define FUTEX_CMP_REQUEUE\t4\n#define FUTEX_WAKE_OP\t\t5\n#define FUTEX_LOCK_PI\t\t6\n#define FUTEX_UNLOCK_PI\t\t7\n#define FUTEX_TRYLOCK_PI\t8\n#define FUTEX_WAIT_BITSET\t9\n\n#define FUTEX_PRIVATE 128\n\n#define FUTEX_CLOCK_REALTIME 256\n\n#endif\n"
  },
  {
    "path": "user.libc/src/internal/intscan.c",
    "content": "#include <limits.h>\n#include <errno.h>\n#include <ctype.h>\n#include \"shgetc.h\"\n\n/* Lookup table for digit values. -1==255>=36 -> invalid */\nstatic const unsigned char table[] = { -1,\n-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,\n-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,\n-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,\n 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,\n-1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,\n25,26,27,28,29,30,31,32,33,34,35,-1,-1,-1,-1,-1,\n-1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,\n25,26,27,28,29,30,31,32,33,34,35,-1,-1,-1,-1,-1,\n-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,\n-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,\n-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,\n-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,\n-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,\n-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,\n-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,\n-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,\n};\n\nunsigned long long __intscan(FILE *f, unsigned base, int pok, unsigned long long lim)\n{\n\tconst unsigned char *val = table+1;\n\tint c, neg=0;\n\tunsigned x;\n\tunsigned long long y;\n\tif (base > 36 || base == 1) {\n\t\terrno = EINVAL;\n\t\treturn 0;\n\t}\n\twhile (isspace((c=shgetc(f))));\n\tif (c=='+' || c=='-') {\n\t\tneg = -(c=='-');\n\t\tc = shgetc(f);\n\t}\n\tif ((base == 0 || base == 16) && c=='0') {\n\t\tc = shgetc(f);\n\t\tif ((c|32)=='x') {\n\t\t\tc = shgetc(f);\n\t\t\tif (val[c]>=16) {\n\t\t\t\tshunget(f);\n\t\t\t\tif (pok) shunget(f);\n\t\t\t\telse shlim(f, 0);\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tbase = 16;\n\t\t} else if (base == 0) {\n\t\t\tbase = 8;\n\t\t}\n\t} else {\n\t\tif (base == 0) base = 10;\n\t\tif (val[c] >= base) {\n\t\t\tshunget(f);\n\t\t\tshlim(f, 0);\n\t\t\terrno = EINVAL;\n\t\t\treturn 0;\n\t\t}\n\t}\n\tif (base == 10) {\n\t\tfor (x=0; c-'0'<10U && x<=UINT_MAX/10-1; c=shgetc(f))\n\t\t\tx = x*10 + (c-'0');\n\t\tfor (y=x; c-'0'<10U && y<=ULLONG_MAX/10 && 10*y<=ULLONG_MAX-(c-'0'); c=shgetc(f))\n\t\t\ty = y*10 + (c-'0');\n\t\tif (c-'0'>=10U) goto done;\n\t} else if (!(base & base-1)) {\n\t\tint bs = \"\\0\\1\\2\\4\\7\\3\\6\\5\"[(0x17*base)>>5&7];\n\t\tfor (x=0; val[c]<base && x<=UINT_MAX/32; c=shgetc(f))\n\t\t\tx = x<<bs | val[c];\n\t\tfor (y=x; val[c]<base && y<=ULLONG_MAX>>bs; c=shgetc(f))\n\t\t\ty = y<<bs | val[c];\n\t} else {\n\t\tfor (x=0; val[c]<base && x<=UINT_MAX/36-1; c=shgetc(f))\n\t\t\tx = x*base + val[c];\n\t\tfor (y=x; val[c]<base && y<=ULLONG_MAX/base && base*y<=ULLONG_MAX-val[c]; c=shgetc(f))\n\t\t\ty = y*base + val[c];\n\t}\n\tif (val[c]<base) {\n\t\tfor (; val[c]<base; c=shgetc(f));\n\t\terrno = ERANGE;\n\t\ty = lim;\n\t\tif (lim&1) neg = 0;\n\t}\ndone:\n\tshunget(f);\n\tif (y>=lim) {\n\t\tif (!(lim&1) && !neg) {\n\t\t\terrno = ERANGE;\n\t\t\treturn lim-1;\n\t\t} else if (y>lim) {\n\t\t\terrno = ERANGE;\n\t\t\treturn lim;\n\t\t}\n\t}\n\treturn (y^neg)-neg;\n}\n"
  },
  {
    "path": "user.libc/src/internal/intscan.h",
    "content": "#ifndef INTSCAN_H\n#define INTSCAN_H\n\n#include <stdio.h>\n\nhidden unsigned long long __intscan(FILE *, unsigned, int, unsigned long long);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/internal/ksigaction.h",
    "content": "#include <features.h>\n\n/* This is the structure used for the rt_sigaction syscall on most archs,\n * but it can be overridden by a file with the same name in the top-level\n * arch dir for a given arch, if necessary. */\nstruct k_sigaction {\n\tvoid (*handler)(int);\n\tunsigned long flags;\n\tvoid (*restorer)(void);\n\tunsigned mask[2];\n};\n\nhidden void __restore(), __restore_rt();\n"
  },
  {
    "path": "user.libc/src/internal/libc.c",
    "content": "#include \"libc.h\"\n\nstruct __libc __libc;\n\nsize_t __hwcap;\nchar *__progname=0, *__progname_full=0;\n\nweak_alias(__progname, program_invocation_short_name);\nweak_alias(__progname_full, program_invocation_name);\n"
  },
  {
    "path": "user.libc/src/internal/libc.h",
    "content": "#ifndef LIBC_H\n#define LIBC_H\n\n#include <stdlib.h>\n#include <stdio.h>\n#include <limits.h>\n\nstruct __locale_map;\n\nstruct __locale_struct {\n\tconst struct __locale_map *cat[6];\n};\n\nstruct tls_module {\n\tstruct tls_module *next;\n\tvoid *image;\n\tsize_t len, size, align, offset;\n};\n\nstruct __libc {\n\tchar can_do_threads;\n\tchar threaded;\n\tchar secure;\n\tvolatile signed char need_locks;\n\tint threads_minus_1;\n\tsize_t *auxv;\n\tstruct tls_module *tls_head;\n\tsize_t tls_size, tls_align, tls_cnt;\n\tsize_t page_size;\n\tstruct __locale_struct global_locale;\n\tint rootfs_handle;\n\tint chiyou_handle;\n};\n\n#ifndef PAGE_SIZE\n#define PAGE_SIZE libc.page_size\n#endif\n\nextern hidden struct __libc __libc;\n#define libc __libc\n\nhidden void __init_libc(char **, char *);\nhidden void __init_tls(size_t *);\nhidden void __init_ssp(void *);\nhidden void __libc_start_init(void);\nhidden void __funcs_on_exit(void);\nhidden void __funcs_on_quick_exit(void);\nhidden void __libc_exit_fini(void);\nhidden void __fork_handler(int);\n\nextern hidden size_t __hwcap;\nextern hidden size_t __sysinfo;\nextern char *__progname, *__progname_full;\n\nextern hidden const char __libc_version[];\n\nhidden void __synccall(void (*)(void *), void *);\nhidden int __setxid(int, int, int, int);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/internal/libm.h",
    "content": "#ifndef _LIBM_H\n#define _LIBM_H\n\n#include <stdint.h>\n#include <float.h>\n#include <math.h>\n#include <endian.h>\n#include \"fp_arch.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\n#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN\nunion ldshape {\n\tlong double f;\n\tstruct {\n\t\tuint64_t m;\n\t\tuint16_t se;\n\t} i;\n};\n#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __BIG_ENDIAN\n/* This is the m68k variant of 80-bit long double, and this definition only works\n * on archs where the alignment requirement of uint64_t is <= 4. */\nunion ldshape {\n\tlong double f;\n\tstruct {\n\t\tuint16_t se;\n\t\tuint16_t pad;\n\t\tuint64_t m;\n\t} i;\n};\n#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN\nunion ldshape {\n\tlong double f;\n\tstruct {\n\t\tuint64_t lo;\n\t\tuint32_t mid;\n\t\tuint16_t top;\n\t\tuint16_t se;\n\t} i;\n\tstruct {\n\t\tuint64_t lo;\n\t\tuint64_t hi;\n\t} i2;\n};\n#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __BIG_ENDIAN\nunion ldshape {\n\tlong double f;\n\tstruct {\n\t\tuint16_t se;\n\t\tuint16_t top;\n\t\tuint32_t mid;\n\t\tuint64_t lo;\n\t} i;\n\tstruct {\n\t\tuint64_t hi;\n\t\tuint64_t lo;\n\t} i2;\n};\n#else\n#error Unsupported long double representation\n#endif\n\n/* Support non-nearest rounding mode.  */\n#define WANT_ROUNDING 1\n/* Support signaling NaNs.  */\n#define WANT_SNAN 0\n\n#if WANT_SNAN\n#error SNaN is unsupported\n#else\n#define issignalingf_inline(x) 0\n#define issignaling_inline(x) 0\n#endif\n\n#ifndef TOINT_INTRINSICS\n#define TOINT_INTRINSICS 0\n#endif\n\n#if TOINT_INTRINSICS\n/* Round x to nearest int in all rounding modes, ties have to be rounded\n   consistently with converttoint so the results match.  If the result\n   would be outside of [-2^31, 2^31-1] then the semantics is unspecified.  */\nstatic double_t roundtoint(double_t);\n\n/* Convert x to nearest int in all rounding modes, ties have to be rounded\n   consistently with roundtoint.  If the result is not representible in an\n   int32_t then the semantics is unspecified.  */\nstatic int32_t converttoint(double_t);\n#endif\n\n/* Helps static branch prediction so hot path can be better optimized.  */\n#ifdef __GNUC__\n#define predict_true(x) __builtin_expect(!!(x), 1)\n#define predict_false(x) __builtin_expect(x, 0)\n#else\n#define predict_true(x) (x)\n#define predict_false(x) (x)\n#endif\n\n/* Evaluate an expression as the specified type. With standard excess\n   precision handling a type cast or assignment is enough (with\n   -ffloat-store an assignment is required, in old compilers argument\n   passing and return statement may not drop excess precision).  */\n\nstatic inline float eval_as_float(float x)\n{\n\tfloat y = x;\n\treturn y;\n}\n\nstatic inline double eval_as_double(double x)\n{\n\tdouble y = x;\n\treturn y;\n}\n\n/* fp_barrier returns its input, but limits code transformations\n   as if it had a side-effect (e.g. observable io) and returned\n   an arbitrary value.  */\n\n#ifndef fp_barrierf\n#define fp_barrierf fp_barrierf\nstatic inline float fp_barrierf(float x)\n{\n\tvolatile float y = x;\n\treturn y;\n}\n#endif\n\n#ifndef fp_barrier\n#define fp_barrier fp_barrier\nstatic inline double fp_barrier(double x)\n{\n\tvolatile double y = x;\n\treturn y;\n}\n#endif\n\n#ifndef fp_barrierl\n#define fp_barrierl fp_barrierl\nstatic inline long double fp_barrierl(long double x)\n{\n\tvolatile long double y = x;\n\treturn y;\n}\n#endif\n\n/* fp_force_eval ensures that the input value is computed when that's\n   otherwise unused.  To prevent the constant folding of the input\n   expression, an additional fp_barrier may be needed or a compilation\n   mode that does so (e.g. -frounding-math in gcc). Then it can be\n   used to evaluate an expression for its fenv side-effects only.   */\n\n#ifndef fp_force_evalf\n#define fp_force_evalf fp_force_evalf\nstatic inline void fp_force_evalf(float x)\n{\n\tvolatile float y;\n\ty = x;\n}\n#endif\n\n#ifndef fp_force_eval\n#define fp_force_eval fp_force_eval\nstatic inline void fp_force_eval(double x)\n{\n\tvolatile double y;\n\ty = x;\n}\n#endif\n\n#ifndef fp_force_evall\n#define fp_force_evall fp_force_evall\nstatic inline void fp_force_evall(long double x)\n{\n\tvolatile long double y;\n\ty = x;\n}\n#endif\n\n#define FORCE_EVAL(x) do {                        \\\n\tif (sizeof(x) == sizeof(float)) {         \\\n\t\tfp_force_evalf(x);                \\\n\t} else if (sizeof(x) == sizeof(double)) { \\\n\t\tfp_force_eval(x);                 \\\n\t} else {                                  \\\n\t\tfp_force_evall(x);                \\\n\t}                                         \\\n} while(0)\n\n#define asuint(f) ((union{float _f; uint32_t _i;}){f})._i\n#define asfloat(i) ((union{uint32_t _i; float _f;}){i})._f\n#define asuint64(f) ((union{double _f; uint64_t _i;}){f})._i\n#define asdouble(i) ((union{uint64_t _i; double _f;}){i})._f\n\n#define EXTRACT_WORDS(hi,lo,d)                    \\\ndo {                                              \\\n  uint64_t __u = asuint64(d);                     \\\n  (hi) = __u >> 32;                               \\\n  (lo) = (uint32_t)__u;                           \\\n} while (0)\n\n#define GET_HIGH_WORD(hi,d)                       \\\ndo {                                              \\\n  (hi) = asuint64(d) >> 32;                       \\\n} while (0)\n\n#define GET_LOW_WORD(lo,d)                        \\\ndo {                                              \\\n  (lo) = (uint32_t)asuint64(d);                   \\\n} while (0)\n\n#define INSERT_WORDS(d,hi,lo)                     \\\ndo {                                              \\\n  (d) = asdouble(((uint64_t)(hi)<<32) | (uint32_t)(lo)); \\\n} while (0)\n\n#define SET_HIGH_WORD(d,hi)                       \\\n  INSERT_WORDS(d, hi, (uint32_t)asuint64(d))\n\n#define SET_LOW_WORD(d,lo)                        \\\n  INSERT_WORDS(d, asuint64(d)>>32, lo)\n\n#define GET_FLOAT_WORD(w,d)                       \\\ndo {                                              \\\n  (w) = asuint(d);                                \\\n} while (0)\n\n#define SET_FLOAT_WORD(d,w)                       \\\ndo {                                              \\\n  (d) = asfloat(w);                               \\\n} while (0)\n\nhidden int    __rem_pio2_large(double*,double*,int,int,int);\n\nhidden int    __rem_pio2(double,double*);\nhidden double __sin(double,double,int);\nhidden double __cos(double,double);\nhidden double __tan(double,double,int);\nhidden double __expo2(double,double);\n\nhidden int    __rem_pio2f(float,double*);\nhidden float  __sindf(double);\nhidden float  __cosdf(double);\nhidden float  __tandf(double,int);\nhidden float  __expo2f(float,float);\n\nhidden int __rem_pio2l(long double, long double *);\nhidden long double __sinl(long double, long double, int);\nhidden long double __cosl(long double, long double);\nhidden long double __tanl(long double, long double, int);\n\nhidden long double __polevll(long double, const long double *, int);\nhidden long double __p1evll(long double, const long double *, int);\n\nextern int __signgam;\nhidden double __lgamma_r(double, int *);\nhidden float __lgammaf_r(float, int *);\n\n/* error handling functions */\nhidden float __math_xflowf(uint32_t, float);\nhidden float __math_uflowf(uint32_t);\nhidden float __math_oflowf(uint32_t);\nhidden float __math_divzerof(uint32_t);\nhidden float __math_invalidf(float);\nhidden double __math_xflow(uint32_t, double);\nhidden double __math_uflow(uint32_t);\nhidden double __math_oflow(uint32_t);\nhidden double __math_divzero(uint32_t);\nhidden double __math_invalid(double);\n#if LDBL_MANT_DIG != DBL_MANT_DIG\nhidden long double __math_invalidl(long double);\n#endif\n\n#endif\n"
  },
  {
    "path": "user.libc/src/internal/locale_impl.h",
    "content": "#ifndef _LOCALE_IMPL_H\n#define _LOCALE_IMPL_H\n\n#include <locale.h>\n#include <stdlib.h>\n#include \"libc.h\"\n#include \"pthread_impl.h\"\n\n#define LOCALE_NAME_MAX 23\n\nstruct __locale_map {\n\tconst void *map;\n\tsize_t map_size;\n\tchar name[LOCALE_NAME_MAX+1];\n\tconst struct __locale_map *next;\n};\n\nextern hidden volatile int __locale_lock[1];\n\nextern hidden const struct __locale_map __c_dot_utf8;\nextern hidden const struct __locale_struct __c_locale;\nextern hidden const struct __locale_struct __c_dot_utf8_locale;\n\nhidden const struct __locale_map *__get_locale(int, const char *);\nhidden const char *__mo_lookup(const void *, size_t, const char *);\nhidden const char *__lctrans(const char *, const struct __locale_map *);\nhidden const char *__lctrans_cur(const char *);\nhidden const char *__lctrans_impl(const char *, const struct __locale_map *);\nhidden int __loc_is_allocated(locale_t);\nhidden char *__gettextdomain(void);\n\n#define LOC_MAP_FAILED ((const struct __locale_map *)-1)\n\n#define LCTRANS(msg, lc, loc) __lctrans(msg, (loc)->cat[(lc)])\n#define LCTRANS_CUR(msg) __lctrans_cur(msg)\n\n#define C_LOCALE ((locale_t)&__c_locale)\n#define UTF8_LOCALE ((locale_t)&__c_dot_utf8_locale)\n\n#define CURRENT_LOCALE (__pthread_self()->locale)\n\n#define CURRENT_UTF8 (!!__pthread_self()->locale->cat[LC_CTYPE])\n\n#undef MB_CUR_MAX\n#define MB_CUR_MAX (CURRENT_UTF8 ? 4 : 1)\n\n#endif\n"
  },
  {
    "path": "user.libc/src/internal/lock.h",
    "content": "#ifndef LOCK_H\n#define LOCK_H\n\nhidden void __lock(volatile int *);\nhidden void __unlock(volatile int *);\n#define LOCK(x) __lock(x)\n#define UNLOCK(x) __unlock(x)\n\n#endif\n"
  },
  {
    "path": "user.libc/src/internal/procfdname.c",
    "content": "#include \"syscall.h\"\n\nvoid __procfdname(char *buf, unsigned fd)\n{\n\tunsigned i, j;\n\tfor (i=0; (buf[i] = \"/proc/self/fd/\"[i]); i++);\n\tif (!fd) {\n\t\tbuf[i] = '0';\n\t\tbuf[i+1] = 0;\n\t\treturn;\n\t}\n\tfor (j=fd; j; j/=10, i++);\n\tbuf[i] = 0;\n\tfor (; fd; fd/=10) buf[--i] = '0' + fd%10;\n}\n"
  },
  {
    "path": "user.libc/src/internal/pthread_impl.h",
    "content": "#ifndef _PTHREAD_IMPL_H\n#define _PTHREAD_IMPL_H\n\n#include <pthread.h>\n#include <signal.h>\n#include <errno.h>\n#include <limits.h>\n#include <sys/mman.h>\n#include \"libc.h\"\n#include \"syscall.h\"\n#include \"atomic.h\"\n#include \"futex.h\"\n\n#include \"pthread_arch.h\"\n\n#define pthread __pthread\n\nstruct pthread {\n\t/* Part 1 -- these fields may be external or\n\t * internal (accessed via asm) ABI. Do not change. */\n\tstruct pthread *self;\n#ifndef TLS_ABOVE_TP\n\tuintptr_t *dtv;\n#endif\n\tstruct pthread *prev, *next; /* non-ABI */\n\tuintptr_t sysinfo;\n#ifndef TLS_ABOVE_TP\n#ifdef CANARY_PAD\n\tuintptr_t canary_pad;\n#endif\n\tuintptr_t canary;\n#endif\n\n\t/* Part 2 -- implementation details, non-ABI. */\n\tint tid;\n\tint errno_val;\n\tvolatile int detach_state;\n\tvolatile int cancel;\n\tvolatile unsigned char canceldisable, cancelasync;\n\tunsigned char tsd_used:1;\n\tunsigned char dlerror_flag:1;\n\tunsigned char *map_base;\n\tsize_t map_size;\n\tvoid *stack;\n\tsize_t stack_size;\n\tsize_t guard_size;\n\tvoid *result;\n\tstruct __ptcb *cancelbuf;\n\tvoid **tsd;\n\tstruct {\n\t\tvolatile void *volatile head;\n\t\tlong off;\n\t\tvolatile void *volatile pending;\n\t} robust_list;\n\tint h_errno_val;\n\tvolatile int timer_id;\n\tlocale_t locale;\n\tvolatile int killlock[1];\n\tchar *dlerror_buf;\n\tvoid *stdio_locks;\n\n\t/* Part 3 -- the positions of these fields relative to\n\t * the end of the structure is external and internal ABI. */\n#ifdef TLS_ABOVE_TP\n\tuintptr_t canary;\n\tuintptr_t *dtv;\n#endif\n};\n\nenum {\n\tDT_EXITED = 0,\n\tDT_EXITING,\n\tDT_JOINABLE,\n\tDT_DETACHED,\n};\n\n#define __SU (sizeof(size_t)/sizeof(int))\n\n#define _a_stacksize __u.__s[0]\n#define _a_guardsize __u.__s[1]\n#define _a_stackaddr __u.__s[2]\n#define _a_detach __u.__i[3*__SU+0]\n#define _a_sched __u.__i[3*__SU+1]\n#define _a_policy __u.__i[3*__SU+2]\n#define _a_prio __u.__i[3*__SU+3]\n#define _m_type __u.__i[0]\n#define _m_lock __u.__vi[1]\n#define _m_waiters __u.__vi[2]\n#define _m_prev __u.__p[3]\n#define _m_next __u.__p[4]\n#define _m_count __u.__i[5]\n#define _c_shared __u.__p[0]\n#define _c_seq __u.__vi[2]\n#define _c_waiters __u.__vi[3]\n#define _c_clock __u.__i[4]\n#define _c_lock __u.__vi[8]\n#define _c_head __u.__p[1]\n#define _c_tail __u.__p[5]\n#define _rw_lock __u.__vi[0]\n#define _rw_waiters __u.__vi[1]\n#define _rw_shared __u.__i[2]\n#define _b_lock __u.__vi[0]\n#define _b_waiters __u.__vi[1]\n#define _b_limit __u.__i[2]\n#define _b_count __u.__vi[3]\n#define _b_waiters2 __u.__vi[4]\n#define _b_inst __u.__p[3]\n\n#ifndef TP_OFFSET\n#define TP_OFFSET 0\n#endif\n\n#ifndef DTP_OFFSET\n#define DTP_OFFSET 0\n#endif\n\n#ifdef TLS_ABOVE_TP\n#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + TP_OFFSET)\n#define __pthread_self() ((pthread_t)(__get_tp() - sizeof(struct __pthread) - TP_OFFSET))\n#else\n#define TP_ADJ(p) (p)\n#define __pthread_self() ((pthread_t)__get_tp())\n#endif\n\n#ifndef tls_mod_off_t\n#define tls_mod_off_t size_t\n#endif\n\n#define SIGTIMER 32\n#define SIGCANCEL 33\n#define SIGSYNCCALL 34\n\n#define SIGALL_SET ((sigset_t *)(const unsigned long long [2]){ -1,-1 })\n#define SIGPT_SET \\\n\t((sigset_t *)(const unsigned long [_NSIG/8/sizeof(long)]){ \\\n\t[sizeof(long)==4] = 3UL<<(32*(sizeof(long)>4)) })\n#define SIGTIMER_SET \\\n\t((sigset_t *)(const unsigned long [_NSIG/8/sizeof(long)]){ \\\n\t 0x80000000 })\n\nvoid *__tls_get_addr(tls_mod_off_t *);\nhidden int __init_tp(void *);\nhidden void *__copy_tls(unsigned char *);\nhidden void __reset_tls();\n\nhidden void __membarrier_init(void);\nhidden void __dl_thread_cleanup(void);\nhidden void __testcancel();\nhidden void __do_cleanup_push(struct __ptcb *);\nhidden void __do_cleanup_pop(struct __ptcb *);\nhidden void __pthread_tsd_run_dtors();\n\nhidden void __pthread_key_delete_synccall(void (*)(void *), void *);\nhidden int __pthread_key_delete_impl(pthread_key_t);\n\nextern hidden volatile size_t __pthread_tsd_size;\nextern hidden void *__pthread_tsd_main[];\nextern hidden volatile int __eintr_valid_flag;\n\nhidden int __clone(int (*)(void *), void *, int, void *, ...);\nhidden int __set_thread_area(void *);\nhidden int __libc_sigaction(int, const struct sigaction *, struct sigaction *);\nhidden void __unmapself(void *, size_t);\n\nhidden int __timedwait(volatile int *, int, clockid_t, const struct timespec *, int);\nhidden int __timedwait_cp(volatile int *, int, clockid_t, const struct timespec *, int);\nhidden void __wait(volatile int *, volatile int *, int, int);\nstatic inline void __wake(volatile void *addr, int cnt, int priv)\n{\n\tif (priv) priv = FUTEX_PRIVATE;\n\tif (cnt<0) cnt = INT_MAX;\n\t__syscall(SYS_futex, addr, FUTEX_WAKE|priv, cnt) != -ENOSYS ||\n\t__syscall(SYS_futex, addr, FUTEX_WAKE, cnt);\n}\nstatic inline void __futexwait(volatile void *addr, int val, int priv)\n{\n\tif (priv) priv = FUTEX_PRIVATE;\n\t__syscall(SYS_futex, addr, FUTEX_WAIT|priv, val, 0) != -ENOSYS ||\n\t__syscall(SYS_futex, addr, FUTEX_WAIT, val, 0);\n}\n\nhidden void __acquire_ptc(void);\nhidden void __release_ptc(void);\nhidden void __inhibit_ptc(void);\n\nhidden int __gettid(void);\n\nhidden void __tl_lock(void);\nhidden void __tl_unlock(void);\nhidden void __tl_sync(pthread_t);\n\nextern hidden volatile int __thread_list_lock;\n\nextern hidden volatile int __abort_lock[1];\n\nextern hidden unsigned __default_stacksize;\nextern hidden unsigned __default_guardsize;\n\n#define DEFAULT_STACK_SIZE 131072\n#define DEFAULT_GUARD_SIZE 8192\n\n#define DEFAULT_STACK_MAX (8<<20)\n#define DEFAULT_GUARD_MAX (1<<20)\n\n#define __ATTRP_C11_THREAD ((void*)(uintptr_t)-1)\n\n#define self_handle() 0\n\n#endif\n"
  },
  {
    "path": "user.libc/src/internal/sh/__shcall.c",
    "content": "#include <features.h>\n\nhidden int __shcall(void *arg, int (*func)(void *))\n{\n\treturn func(arg);\n}\n"
  },
  {
    "path": "user.libc/src/internal/shgetc.c",
    "content": "#include \"shgetc.h\"\n\n/* The shcnt field stores the number of bytes read so far, offset by\n * the value of buf-rpos at the last function call (__shlim or __shgetc),\n * so that between calls the inline shcnt macro can add rpos-buf to get\n * the actual count. */\n\nvoid __shlim(FILE *f, off_t lim)\n{\n\tf->shlim = lim;\n\tf->shcnt = f->buf - f->rpos;\n\t/* If lim is nonzero, rend must be a valid pointer. */\n\tif (lim && f->rend - f->rpos > lim)\n\t\tf->shend = f->rpos + lim;\n\telse\n\t\tf->shend = f->rend;\n}\n\nint __shgetc(FILE *f)\n{\n\tint c;\n\toff_t cnt = shcnt(f);\n\tif (f->shlim && cnt >= f->shlim || (c=__uflow(f)) < 0) {\n\t\tf->shcnt = f->buf - f->rpos + cnt;\n\t\tf->shend = f->rpos;\n\t\tf->shlim = -1;\n\t\treturn EOF;\n\t}\n\tcnt++;\n\tif (f->shlim && f->rend - f->rpos > f->shlim - cnt)\n\t\tf->shend = f->rpos + (f->shlim - cnt);\n\telse\n\t\tf->shend = f->rend;\n\tf->shcnt = f->buf - f->rpos + cnt;\n\tif (f->rpos <= f->buf) f->rpos[-1] = c;\n\treturn c;\n}\n"
  },
  {
    "path": "user.libc/src/internal/shgetc.h",
    "content": "#include \"stdio_impl.h\"\n\n/* Scan helper \"stdio\" functions for use by scanf-family and strto*-family\n * functions. These accept either a valid stdio FILE, or a minimal pseudo\n * FILE whose buffer pointers point into a null-terminated string. In the\n * latter case, the sh_fromstring macro should be used to setup the FILE;\n * the rest of the structure can be left uninitialized.\n *\n * To begin using these functions, shlim must first be called on the FILE\n * to set a field width limit, or 0 for no limit. For string pseudo-FILEs,\n * a nonzero limit is not valid and produces undefined behavior. After that,\n * shgetc, shunget, and shcnt are valid as long as no other stdio functions\n * are called on the stream.\n *\n * When used with a real FILE object, shunget has only one byte of pushback\n * available. Further shunget (up to a limit of the stdio UNGET buffer size)\n * will adjust the position but will not restore the data to be read again.\n * This functionality is needed for the wcsto*-family functions, where it's\n * okay because the FILE will be discarded immediately anyway. When used\n * with string pseudo-FILEs, shunget has unlimited pushback, back to the\n * beginning of the string. */\n\nhidden void __shlim(FILE *, off_t);\nhidden int __shgetc(FILE *);\n\n#define shcnt(f) ((f)->shcnt + ((f)->rpos - (f)->buf))\n#define shlim(f, lim) __shlim((f), (lim))\n#define shgetc(f) (((f)->rpos != (f)->shend) ? *(f)->rpos++ : __shgetc(f))\n#define shunget(f) ((f)->shlim>=0 ? (void)(f)->rpos-- : (void)0)\n\n#define sh_fromstring(f, s) \\\n\t((f)->buf = (f)->rpos = (void *)(s), (f)->rend = (void*)-1)\n"
  },
  {
    "path": "user.libc/src/internal/stdio_impl.h",
    "content": "#ifndef _STDIO_IMPL_H\n#define _STDIO_IMPL_H\n\n#include <stdio.h>\n#include \"syscall.h\"\n\n#define UNGET 8\n\n#define FFINALLOCK(f) ((f)->lock>=0 ? __lockfile((f)) : 0)\n#define FLOCK(f) int __need_unlock = ((f)->lock>=0 ? __lockfile((f)) : 0)\n#define FUNLOCK(f) do { if (__need_unlock) __unlockfile((f)); } while (0)\n\n#define F_PERM 1\n#define F_NORD 4\n#define F_NOWR 8\n#define F_EOF 16\n#define F_ERR 32\n#define F_SVB 64\n#define F_APP 128\n#define F_STREAM 256\n\nstruct _IO_FILE {\n\tunsigned flags;\n\tunsigned char *rpos, *rend;\n\tint (*close)(FILE *);\n\tunsigned char *wend, *wpos;\n\tunsigned char *mustbezero_1;\n\tunsigned char *wbase;\n\tsize_t (*read)(FILE *, unsigned char *, size_t);\n\tsize_t (*write)(FILE *, const unsigned char *, size_t);\n\toff_t (*seek)(FILE *, off_t, int);\n\tunsigned char *buf;\n\tsize_t buf_size;\n\tFILE *prev, *next;\n\tint fd;\n\tint pipe_pid;\n\tlong lockcount;\n\tint mode;\n\tvolatile int lock;\n\tint lbf;\n\tvoid *cookie;\n\toff_t off;\n\tchar *getln_buf;\n\tvoid *mustbezero_2;\n\tunsigned char *shend;\n\toff_t shlim, shcnt;\n\tFILE *prev_locked, *next_locked;\n\tstruct __locale_struct *locale;\n};\n\nextern hidden FILE *volatile __stdin_used;\nextern hidden FILE *volatile __stdout_used;\nextern hidden FILE *volatile __stderr_used;\n\nhidden int __lockfile(FILE *);\nhidden void __unlockfile(FILE *);\n\nhidden size_t __stdio_read(FILE *, unsigned char *, size_t);\nhidden size_t __stdio_write(FILE *, const unsigned char *, size_t);\nhidden size_t __stdout_write(FILE *, const unsigned char *, size_t);\nhidden off_t __stdio_seek(FILE *, off_t, int);\nhidden int __stdio_close(FILE *);\n\nhidden int __toread(FILE *);\nhidden int __towrite(FILE *);\n\nhidden void __stdio_exit(void);\nhidden void __stdio_exit_needed(void);\n\n#if defined(__PIC__) && (100*__GNUC__+__GNUC_MINOR__ >= 303)\n__attribute__((visibility(\"protected\")))\n#endif\nint __overflow(FILE *, int), __uflow(FILE *);\n\nhidden int __fseeko(FILE *, off_t, int);\nhidden int __fseeko_unlocked(FILE *, off_t, int);\nhidden off_t __ftello(FILE *);\nhidden off_t __ftello_unlocked(FILE *);\nhidden size_t __fwritex(const unsigned char *, size_t, FILE *);\nhidden int __putc_unlocked(int, FILE *);\n\nhidden FILE *__fdopen(int, int);\nhidden int __fmodeflags(const char *);\n\nhidden FILE *__ofl_add(FILE *f);\nhidden FILE **__ofl_lock(void);\nhidden void __ofl_unlock(void);\nhidden FILE *__ofl_del_fd(int fd);\nhidden void *__ofl_del(FILE *f);\nhidden FILE *__ofl_get_file(int fd);\n\nhidden int fclose_fd(int);\n\nstruct __pthread;\nhidden void __register_locked_file(FILE *, struct __pthread *);\nhidden void __unlist_locked_file(FILE *);\nhidden void __do_orphaned_stdio_locks(void);\n\n#define MAYBE_WAITERS 0x40000000\n\nhidden void __getopt_msg(const char *, const char *, const char *, size_t);\n\n#define feof(f) ((f)->flags & F_EOF)\n#define ferror(f) ((f)->flags & F_ERR)\n\n#define getc_unlocked(f) \\\n\t( ((f)->rpos != (f)->rend) ? *(f)->rpos++ : __uflow((f)) )\n\n#define putc_unlocked(c, f) \\\n\t( (((unsigned char)(c)!=(f)->lbf && (f)->wpos!=(f)->wend)) \\\n\t? *(f)->wpos++ = (unsigned char)(c) \\\n\t: __overflow((f),(unsigned char)(c)) )\n\n/* Caller-allocated FILE * operations */\nhidden FILE *__fopen_rb_ca(const char *, FILE *, unsigned char *, size_t);\nhidden int __fclose_ca(FILE *);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/internal/syscall.h",
    "content": "#ifndef _INTERNAL_SYSCALL_H\n#define _INTERNAL_SYSCALL_H\n\n#include <features.h>\n#include <errno.h>\n#include <sys/syscall.h>\n#include \"syscall_arch.h\"\n\n#ifndef SYSCALL_RLIM_INFINITY\n#define SYSCALL_RLIM_INFINITY (~0ULL)\n#endif\n\n#ifndef SYSCALL_MMAP2_UNIT\n#define SYSCALL_MMAP2_UNIT 4096ULL\n#endif\n\n#ifndef __SYSCALL_LL_PRW\n#define __SYSCALL_LL_PRW(x) __SYSCALL_LL_O(x)\n#endif\n\n#ifndef __scc\n#define __scc(X) ((long) (X))\ntypedef long syscall_arg_t;\n#endif\n\nhidden int __sys_open(const char *restrict filename, int flags, int mode);\n\nhidden long __syscall_ret(unsigned long),\n\t__syscall_cp(syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t,\n\t             syscall_arg_t, syscall_arg_t, syscall_arg_t);\n\n#define __syscall1(n,a) __syscall1(n,__scc(a))\n#define __syscall2(n,a,b) __syscall2(n,__scc(a),__scc(b))\n#define __syscall3(n,a,b,c) __syscall3(n,__scc(a),__scc(b),__scc(c))\n#define __syscall4(n,a,b,c,d) __syscall4(n,__scc(a),__scc(b),__scc(c),__scc(d))\n#define __syscall5(n,a,b,c,d,e) __syscall5(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e))\n#define __syscall6(n,a,b,c,d,e,f) __syscall6(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f))\n#define __syscall7(n,a,b,c,d,e,f,g) __syscall7(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f),__scc(g))\n\n#define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n\n#define __SYSCALL_NARGS(...) __SYSCALL_NARGS_X(__VA_ARGS__,7,6,5,4,3,2,1,0,)\n#define __SYSCALL_CONCAT_X(a,b) a##b\n#define __SYSCALL_CONCAT(a,b) __SYSCALL_CONCAT_X(a,b)\n#define __SYSCALL_DISP(b,...) __SYSCALL_CONCAT(b,__SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__)\n\n#define __syscall(...) __SYSCALL_DISP(__syscall,__VA_ARGS__)\n#define syscall(...) __syscall_ret(__syscall(__VA_ARGS__))\n\n#define socketcall(nm,a,b,c,d,e,f) __syscall_ret(__socketcall(nm,a,b,c,d,e,f))\n#define socketcall_cp(nm,a,b,c,d,e,f) __syscall_ret(__socketcall_cp(nm,a,b,c,d,e,f))\n\n#define __syscall_cp0(n) (__syscall_cp)(n,0,0,0,0,0,0)\n#define __syscall_cp1(n,a) (__syscall_cp)(n,__scc(a),0,0,0,0,0)\n#define __syscall_cp2(n,a,b) (__syscall_cp)(n,__scc(a),__scc(b),0,0,0,0)\n#define __syscall_cp3(n,a,b,c) (__syscall_cp)(n,__scc(a),__scc(b),__scc(c),0,0,0)\n#define __syscall_cp4(n,a,b,c,d) (__syscall_cp)(n,__scc(a),__scc(b),__scc(c),__scc(d),0,0)\n#define __syscall_cp5(n,a,b,c,d,e) (__syscall_cp)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),0)\n#define __syscall_cp6(n,a,b,c,d,e,f) (__syscall_cp)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f))\n\n#define __syscall_cp(...) __SYSCALL_DISP(__syscall_cp,__VA_ARGS__)\n#define syscall_cp(...) __syscall_ret(__syscall_cp(__VA_ARGS__))\n\nstatic inline long __alt_socketcall(int sys, int sock, int cp, long a, long b, long c, long d, long e, long f)\n{\n\tlong r;\n\tif (cp) r = __syscall_cp(sys, a, b, c, d, e, f);\n\telse r = __syscall(sys, a, b, c, d, e, f);\n\tif (r != -ENOSYS) return r;\n#ifdef SYS_socketcall\n\tif (cp) r = __syscall_cp(SYS_socketcall, sock, ((long[6]){a, b, c, d, e, f}));\n\telse r = __syscall(SYS_socketcall, sock, ((long[6]){a, b, c, d, e, f}));\n#endif\n\treturn r;\n}\n#define __socketcall(nm, a, b, c, d, e, f) __alt_socketcall(SYS_##nm, __SC_##nm, 0, \\\n\t(long)(a), (long)(b), (long)(c), (long)(d), (long)(e), (long)(f))\n#define __socketcall_cp(nm, a, b, c, d, e, f) __alt_socketcall(SYS_##nm, __SC_##nm, 1, \\\n\t(long)(a), (long)(b), (long)(c), (long)(d), (long)(e), (long)(f))\n\n/* fixup legacy 16-bit junk */\n\n#ifdef SYS_getuid32\n#undef SYS_lchown\n#undef SYS_getuid\n#undef SYS_getgid\n#undef SYS_geteuid\n#undef SYS_getegid\n#undef SYS_setreuid\n#undef SYS_setregid\n#undef SYS_getgroups\n#undef SYS_setgroups\n#undef SYS_fchown\n#undef SYS_setresuid\n#undef SYS_getresuid\n#undef SYS_setresgid\n#undef SYS_getresgid\n#undef SYS_chown\n#undef SYS_setuid\n#undef SYS_setgid\n#undef SYS_setfsuid\n#undef SYS_setfsgid\n#define SYS_lchown SYS_lchown32\n#define SYS_getuid SYS_getuid32\n#define SYS_getgid SYS_getgid32\n#define SYS_geteuid SYS_geteuid32\n#define SYS_getegid SYS_getegid32\n#define SYS_setreuid SYS_setreuid32\n#define SYS_setregid SYS_setregid32\n#define SYS_getgroups SYS_getgroups32\n#define SYS_setgroups SYS_setgroups32\n#define SYS_fchown SYS_fchown32\n#define SYS_setresuid SYS_setresuid32\n#define SYS_getresuid SYS_getresuid32\n#define SYS_setresgid SYS_setresgid32\n#define SYS_getresgid SYS_getresgid32\n#define SYS_chown SYS_chown32\n#define SYS_setuid SYS_setuid32\n#define SYS_setgid SYS_setgid32\n#define SYS_setfsuid SYS_setfsuid32\n#define SYS_setfsgid SYS_setfsgid32\n#endif\n\n\n/* fixup legacy 32-bit-vs-lfs64 junk */\n\n#ifdef SYS_fcntl64\n#undef SYS_fcntl\n#define SYS_fcntl SYS_fcntl64\n#endif\n\n#ifdef SYS_getdents64\n#undef SYS_getdents\n#define SYS_getdents SYS_getdents64\n#endif\n\n#ifdef SYS_ftruncate64\n#undef SYS_ftruncate\n#undef SYS_truncate\n#define SYS_ftruncate SYS_ftruncate64\n#define SYS_truncate SYS_truncate64\n#endif\n\n#ifdef SYS_stat64\n#undef SYS_stat\n#define SYS_stat SYS_stat64\n#endif\n\n#ifdef SYS_fstat64\n#undef SYS_fstat\n#define SYS_fstat SYS_fstat64\n#endif\n\n#ifdef SYS_lstat64\n#undef SYS_lstat\n#define SYS_lstat SYS_lstat64\n#endif\n\n#ifdef SYS_statfs64\n#undef SYS_statfs\n#define SYS_statfs SYS_statfs64\n#endif\n\n#ifdef SYS_fstatfs64\n#undef SYS_fstatfs\n#define SYS_fstatfs SYS_fstatfs64\n#endif\n\n#if defined(SYS_newfstatat)\n#undef SYS_fstatat\n#define SYS_fstatat SYS_newfstatat\n#elif defined(SYS_fstatat64)\n#undef SYS_fstatat\n#define SYS_fstatat SYS_fstatat64\n#endif\n\n#ifdef SYS_ugetrlimit\n#undef SYS_getrlimit\n#define SYS_getrlimit SYS_ugetrlimit\n#endif\n\n#ifdef SYS__newselect\n#undef SYS_select\n#define SYS_select SYS__newselect\n#endif\n\n#ifdef SYS_pread64\n#undef SYS_pread\n#undef SYS_pwrite\n#define SYS_pread SYS_pread64\n#define SYS_pwrite SYS_pwrite64\n#endif\n\n#ifdef SYS_fadvise64_64\n#undef SYS_fadvise\n#define SYS_fadvise SYS_fadvise64_64\n#elif defined(SYS_fadvise64)\n#undef SYS_fadvise\n#define SYS_fadvise SYS_fadvise64\n#endif\n\n#ifdef SYS_sendfile64\n#undef SYS_sendfile\n#define SYS_sendfile SYS_sendfile64\n#endif\n\n#ifndef SYS_timer_settime\n#define SYS_timer_settime SYS_timer_settime32\n#endif\n\n#ifndef SYS_timer_gettime\n#define SYS_timer_gettime SYS_timer_gettime32\n#endif\n\n#ifndef SYS_timerfd_settime\n#define SYS_timerfd_settime SYS_timerfd_settime32\n#endif\n\n#ifndef SYS_timerfd_gettime\n#define SYS_timerfd_gettime SYS_timerfd_gettime32\n#endif\n\n#ifndef SYS_clock_settime\n#define SYS_clock_settime SYS_clock_settime32\n#endif\n\n#ifndef SYS_clock_gettime\n#define SYS_clock_gettime SYS_clock_gettime32\n#endif\n\n#ifndef SYS_clock_getres\n#define SYS_clock_getres SYS_clock_getres_time32\n#endif\n\n#ifndef SYS_clock_nanosleep\n#define SYS_clock_nanosleep SYS_clock_nanosleep_time32\n#endif\n\n#ifndef SYS_gettimeofday\n#define SYS_gettimeofday SYS_gettimeofday_time32\n#endif\n\n#ifndef SYS_settimeofday\n#define SYS_settimeofday SYS_settimeofday_time32\n#endif\n\n/* Ensure that the plain syscall names are defined even for \"time64-only\"\n * archs. These facilitate callers passing null time arguments, and make\n * tests for establishing which to use/fallback-to more consistent when\n * they do need to be called with time arguments. */\n\n#ifndef SYS_clock_gettime\n#define SYS_clock_gettime SYS_clock_gettime64\n#endif\n\n#ifndef SYS_clock_settime\n#define SYS_clock_settime SYS_clock_settime64\n#endif\n\n#ifndef SYS_clock_adjtime\n#define SYS_clock_adjtime SYS_clock_adjtime64\n#endif\n\n#ifndef SYS_clock_getres\n#define SYS_clock_getres SYS_clock_getres_time64\n#endif\n\n#ifndef SYS_clock_nanosleep\n#define SYS_clock_nanosleep SYS_clock_nanosleep_time64\n#endif\n\n#ifndef SYS_timer_gettime\n#define SYS_timer_gettime SYS_timer_gettime64\n#endif\n\n#ifndef SYS_timer_settime\n#define SYS_timer_settime SYS_timer_settime64\n#endif\n\n#ifndef SYS_timerfd_gettime\n#define SYS_timerfd_gettime SYS_timerfd_gettime64\n#endif\n\n#ifndef SYS_timerfd_settime\n#define SYS_timerfd_settime SYS_timerfd_settime64\n#endif\n\n#ifndef SYS_utimensat\n#define SYS_utimensat SYS_utimensat_time64\n#endif\n\n#ifndef SYS_pselect6\n#define SYS_pselect6 SYS_pselect6_time64\n#endif\n\n#ifndef SYS_ppoll\n#define SYS_ppoll SYS_ppoll_time64\n#endif\n\n#ifndef SYS_recvmmsg\n#define SYS_recvmmsg SYS_recvmmsg_time64\n#endif\n\n#ifndef SYS_mq_timedsend\n#define SYS_mq_timedsend SYS_mq_timedsend_time64\n#endif\n\n#ifndef SYS_mq_timedreceive\n#define SYS_mq_timedreceive SYS_mq_timedreceive_time64\n#endif\n\n/* SYS_semtimedop omitted because SYS_ipc may provide it */\n\n#ifndef SYS_rt_sigtimedwait\n#define SYS_rt_sigtimedwait SYS_rt_sigtimedwait_time64\n#endif\n\n#ifndef SYS_futex\n#define SYS_futex SYS_futex_time64\n#endif\n\n#ifndef SYS_sched_rr_get_interval\n#define SYS_sched_rr_get_interval SYS_sched_rr_get_interval_time64\n#endif\n\n\n\n\n/* socketcall calls */\n\n#define __SC_socket      1\n#define __SC_bind        2\n#define __SC_connect     3\n#define __SC_listen      4\n#define __SC_accept      5\n#define __SC_getsockname 6\n#define __SC_getpeername 7\n#define __SC_socketpair  8\n#define __SC_send        9\n#define __SC_recv        10\n#define __SC_sendto      11\n#define __SC_recvfrom    12\n#define __SC_shutdown    13\n#define __SC_setsockopt  14\n#define __SC_getsockopt  15\n#define __SC_sendmsg     16\n#define __SC_recvmsg     17\n#define __SC_accept4     18\n#define __SC_recvmmsg    19\n#define __SC_sendmmsg    20\n\n/* This is valid only because all socket syscalls are made via\n * socketcall, which always fills unused argument slots with zeros. */\n#ifndef SYS_accept\n#define SYS_accept SYS_accept4\n#endif\n\n#ifndef SO_RCVTIMEO_OLD\n#define SO_RCVTIMEO_OLD  20\n#endif\n#ifndef SO_SNDTIMEO_OLD\n#define SO_SNDTIMEO_OLD  21\n#endif\n\n#define SO_TIMESTAMP_OLD    29\n#define SO_TIMESTAMPNS_OLD  35\n#define SO_TIMESTAMPING_OLD 37\n#define SCM_TIMESTAMP_OLD    SO_TIMESTAMP_OLD\n#define SCM_TIMESTAMPNS_OLD  SO_TIMESTAMPNS_OLD\n#define SCM_TIMESTAMPING_OLD SO_TIMESTAMPING_OLD\n\n#ifndef SIOCGSTAMP_OLD\n#define SIOCGSTAMP_OLD 0x8906\n#endif\n#ifndef SIOCGSTAMPNS_OLD\n#define SIOCGSTAMPNS_OLD 0x8907\n#endif\n\n#define sys_open(pn, fl) __sys_open(pn, (fl) | O_LARGEFILE, 0);\n\nhidden void __procfdname(char __buf[static 15+3*sizeof(int)], unsigned);\n\nhidden void *__vdsosym(const char *, const char *);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/internal/syscall_ret.c",
    "content": "#include <errno.h>\n#include \"syscall.h\"\n\nlong __syscall_ret(unsigned long r)\n{\n\tif (r > -4096UL) {\n\t\terrno = -r;\n\t\treturn -1;\n\t}\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/src/internal/vdso.c",
    "content": "#include <elf.h>\n#include <link.h>\n#include <limits.h>\n#include <stdint.h>\n#include <string.h>\n#include \"libc.h\"\n#include \"syscall.h\"\n\n#ifdef VDSO_USEFUL\n\n#if ULONG_MAX == 0xffffffff\ntypedef Elf32_Ehdr Ehdr;\ntypedef Elf32_Phdr Phdr;\ntypedef Elf32_Sym Sym;\ntypedef Elf32_Verdef Verdef;\ntypedef Elf32_Verdaux Verdaux;\n#else\ntypedef Elf64_Ehdr Ehdr;\ntypedef Elf64_Phdr Phdr;\ntypedef Elf64_Sym Sym;\ntypedef Elf64_Verdef Verdef;\ntypedef Elf64_Verdaux Verdaux;\n#endif\n\nstatic int checkver(Verdef *def, int vsym, const char *vername, char *strings)\n{\n\tvsym &= 0x7fff;\n\tfor (;;) {\n\t\tif (!(def->vd_flags & VER_FLG_BASE)\n\t\t  && (def->vd_ndx & 0x7fff) == vsym)\n\t\t\tbreak;\n\t\tif (def->vd_next == 0)\n\t\t\treturn 0;\n\t\tdef = (Verdef *)((char *)def + def->vd_next);\n\t}\n\tVerdaux *aux = (Verdaux *)((char *)def + def->vd_aux);\n\treturn !strcmp(vername, strings + aux->vda_name);\n}\n\n#define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON)\n#define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK | 1<<STB_GNU_UNIQUE)\n\nvoid *__vdsosym(const char *vername, const char *name)\n{\n\tsize_t i;\n\tfor (i=0; libc.auxv[i] != AT_SYSINFO_EHDR; i+=2)\n\t\tif (!libc.auxv[i]) return 0;\n\tif (!libc.auxv[i+1]) return 0;\n\tEhdr *eh = (void *)libc.auxv[i+1];\n\tPhdr *ph = (void *)((char *)eh + eh->e_phoff);\n\tsize_t *dynv=0, base=-1;\n\tfor (i=0; i<eh->e_phnum; i++, ph=(void *)((char *)ph+eh->e_phentsize)) {\n\t\tif (ph->p_type == PT_LOAD)\n\t\t\tbase = (size_t)eh + ph->p_offset - ph->p_vaddr;\n\t\telse if (ph->p_type == PT_DYNAMIC)\n\t\t\tdynv = (void *)((char *)eh + ph->p_offset);\n\t}\n\tif (!dynv || base==(size_t)-1) return 0;\n\n\tchar *strings = 0;\n\tSym *syms = 0;\n\tElf_Symndx *hashtab = 0;\n\tuint16_t *versym = 0;\n\tVerdef *verdef = 0;\n\t\n\tfor (i=0; dynv[i]; i+=2) {\n\t\tvoid *p = (void *)(base + dynv[i+1]);\n\t\tswitch(dynv[i]) {\n\t\tcase DT_STRTAB: strings = p; break;\n\t\tcase DT_SYMTAB: syms = p; break;\n\t\tcase DT_HASH: hashtab = p; break;\n\t\tcase DT_VERSYM: versym = p; break;\n\t\tcase DT_VERDEF: verdef = p; break;\n\t\t}\n\t}\t\n\n\tif (!strings || !syms || !hashtab) return 0;\n\tif (!verdef) versym = 0;\n\n\tfor (i=0; i<hashtab[1]; i++) {\n\t\tif (!(1<<(syms[i].st_info&0xf) & OK_TYPES)) continue;\n\t\tif (!(1<<(syms[i].st_info>>4) & OK_BINDS)) continue;\n\t\tif (!syms[i].st_shndx) continue;\n\t\tif (strcmp(name, strings+syms[i].st_name)) continue;\n\t\tif (versym && !checkver(verdef, versym[i], vername, strings))\n\t\t\tcontinue;\n\t\treturn (void *)(base + syms[i].st_value);\n\t}\n\n\treturn 0;\n}\n\n#endif\n"
  },
  {
    "path": "user.libc/src/internal/version.c",
    "content": "#include \"version.h\"\n#include \"libc.h\"\n\nconst char __libc_version[] = VERSION;\n"
  },
  {
    "path": "user.libc/src/ldso/__dlsym.c",
    "content": "#include <dlfcn.h>\n#include \"dynlink.h\"\n\nstatic void *stub_dlsym(void *restrict p, const char *restrict s, void *restrict ra)\n{\n\t__dl_seterr(\"Symbol not found: %s\", s);\n\treturn 0;\n}\n\nweak_alias(stub_dlsym, __dlsym);\n\n#if _REDIR_TIME64\nweak_alias(stub_dlsym, __dlsym_redir_time64);\n#endif\n"
  },
  {
    "path": "user.libc/src/ldso/arm/find_exidx.c",
    "content": "#define _GNU_SOURCE\n#include <link.h>\n#include <stdint.h>\n\nstruct find_exidx_data {\n\tuintptr_t pc, exidx_start;\n\tint exidx_len;\n};\n\nstatic int find_exidx(struct dl_phdr_info *info, size_t size, void *ptr)\n{\n\tstruct find_exidx_data *data = ptr;\n\tconst ElfW(Phdr) *phdr = info->dlpi_phdr;\n\tuintptr_t addr, exidx_start = 0;\n\tint i, match = 0, exidx_len = 0;\n\n\tfor (i = info->dlpi_phnum; i > 0; i--, phdr++) {\n\t\taddr = info->dlpi_addr + phdr->p_vaddr;\n\t\tswitch (phdr->p_type) {\n\t\tcase PT_LOAD:\n\t\t\tmatch |= data->pc >= addr && data->pc < addr + phdr->p_memsz;\n\t\t\tbreak;\n\t\tcase PT_ARM_EXIDX:\n\t\t\texidx_start = addr;\n\t\t\texidx_len = phdr->p_memsz;\n\t\t\tbreak;\n\t\t}\n\t}\n\tdata->exidx_start = exidx_start;\n\tdata->exidx_len = exidx_len;\n\treturn match;\n}\n\nuintptr_t __gnu_Unwind_Find_exidx(uintptr_t pc, int *pcount)\n{\n\tstruct find_exidx_data data;\n\tdata.pc = pc;\n\tif (dl_iterate_phdr(find_exidx, &data) <= 0)\n\t\treturn 0;\n\t*pcount = data.exidx_len / 8;\n\treturn data.exidx_start;\n}\n"
  },
  {
    "path": "user.libc/src/ldso/dl_iterate_phdr.c",
    "content": "#include <elf.h>\n#include <link.h>\n#include \"libc.h\"\n\n#define AUX_CNT 38\n\nextern weak hidden const size_t _DYNAMIC[];\n\nstatic int static_dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data)\n{\n\tunsigned char *p;\n\tElfW(Phdr) *phdr, *tls_phdr=0;\n\tsize_t base = 0;\n\tsize_t n;\n\tstruct dl_phdr_info info;\n\tsize_t i, aux[AUX_CNT] = {0};\n\n\tfor (i=0; libc.auxv[i]; i+=2)\n\t\tif (libc.auxv[i]<AUX_CNT) aux[libc.auxv[i]] = libc.auxv[i+1];\n\n\tfor (p=(void *)aux[AT_PHDR],n=aux[AT_PHNUM]; n; n--,p+=aux[AT_PHENT]) {\n\t\tphdr = (void *)p;\n\t\tif (phdr->p_type == PT_PHDR)\n\t\t\tbase = aux[AT_PHDR] - phdr->p_vaddr;\n\t\tif (phdr->p_type == PT_DYNAMIC && _DYNAMIC)\n\t\t\tbase = (size_t)_DYNAMIC - phdr->p_vaddr;\n\t\tif (phdr->p_type == PT_TLS)\n\t\t\ttls_phdr = phdr;\n\t}\n\tinfo.dlpi_addr  = base;\n\tinfo.dlpi_name  = \"/proc/self/exe\";\n\tinfo.dlpi_phdr  = (void *)aux[AT_PHDR];\n\tinfo.dlpi_phnum = aux[AT_PHNUM];\n\tinfo.dlpi_adds  = 0;\n\tinfo.dlpi_subs  = 0;\n\tif (tls_phdr) {\n\t\tinfo.dlpi_tls_modid = 1;\n\t\tinfo.dlpi_tls_data = (void *)(base + tls_phdr->p_vaddr);\n\t} else {\n\t\tinfo.dlpi_tls_modid = 0;\n\t\tinfo.dlpi_tls_data = 0;\n\t}\n\treturn (callback)(&info, sizeof (info), data);\n}\n\nweak_alias(static_dl_iterate_phdr, dl_iterate_phdr);\n"
  },
  {
    "path": "user.libc/src/ldso/dladdr.c",
    "content": "#define _GNU_SOURCE\n#include <dlfcn.h>\n\nstatic int stub_dladdr(const void *addr, Dl_info *info)\n{\n\treturn 0;\n}\n\nweak_alias(stub_dladdr, dladdr);\n"
  },
  {
    "path": "user.libc/src/ldso/dlclose.c",
    "content": "#include <dlfcn.h>\n#include \"dynlink.h\"\n\nint dlclose(void *p)\n{\n\treturn __dl_invalid_handle(p);\n}\n"
  },
  {
    "path": "user.libc/src/ldso/dlerror.c",
    "content": "#include <dlfcn.h>\n#include <stdlib.h>\n#include <stdarg.h>\n#include \"pthread_impl.h\"\n#include \"dynlink.h\"\n#include \"lock.h\"\n#include \"fork_impl.h\"\n\n#define malloc __libc_malloc\n#define calloc __libc_calloc\n#define realloc __libc_realloc\n#define free __libc_free\n\nchar *dlerror()\n{\n\tpthread_t self = __pthread_self();\n\tif (!self->dlerror_flag) return 0;\n\tself->dlerror_flag = 0;\n\tchar *s = self->dlerror_buf;\n\tif (s == (void *)-1)\n\t\treturn \"Dynamic linker failed to allocate memory for error message\";\n\telse\n\t\treturn s;\n}\n\nstatic volatile int freebuf_queue_lock[1];\nstatic void **freebuf_queue;\nvolatile int *const __dlerror_lockptr = freebuf_queue_lock;\n\nvoid __dl_thread_cleanup(void)\n{\n\tpthread_t self = __pthread_self();\n\tif (self->dlerror_buf && self->dlerror_buf != (void *)-1) {\n\t\tLOCK(freebuf_queue_lock);\n\t\tvoid **p = (void **)self->dlerror_buf;\n\t\t*p = freebuf_queue;\n\t\tfreebuf_queue = p;\n\t\tUNLOCK(freebuf_queue_lock);\n\t}\n}\n\nhidden void __dl_vseterr(const char *fmt, va_list ap)\n{\n\tLOCK(freebuf_queue_lock);\n\tvoid **q = freebuf_queue;\n\tfreebuf_queue = 0;\n\tUNLOCK(freebuf_queue_lock);\n\n\twhile (q) {\n\t\tvoid **p = *q;\n\t\tfree(q);\n\t\tq = p;\n\t}\n\n\tva_list ap2;\n\tva_copy(ap2, ap);\n\tpthread_t self = __pthread_self();\n\tif (self->dlerror_buf != (void *)-1)\n\t\tfree(self->dlerror_buf);\n\tsize_t len = vsnprintf(0, 0, fmt, ap2);\n\tif (len < sizeof(void *)) len = sizeof(void *);\n\tva_end(ap2);\n\tchar *buf = malloc(len+1);\n\tif (buf) {\n\t\tvsnprintf(buf, len+1, fmt, ap);\n\t} else {\n\t\tbuf = (void *)-1;\t\n\t}\n\tself->dlerror_buf = buf;\n\tself->dlerror_flag = 1;\n}\n\nhidden void __dl_seterr(const char *fmt, ...)\n{\n\tva_list ap;\n\tva_start(ap, fmt);\n\t__dl_vseterr(fmt, ap);\n\tva_end(ap);\n}\n\nstatic int stub_invalid_handle(void *h)\n{\n\t__dl_seterr(\"Invalid library handle %p\", (void *)h);\n\treturn 1;\n}\n\nweak_alias(stub_invalid_handle, __dl_invalid_handle);\n"
  },
  {
    "path": "user.libc/src/ldso/dlinfo.c",
    "content": "#define _GNU_SOURCE\n#include <dlfcn.h>\n#include \"dynlink.h\"\n\nint dlinfo(void *dso, int req, void *res)\n{\n\tif (__dl_invalid_handle(dso)) return -1;\n\tif (req != RTLD_DI_LINKMAP) {\n\t\t__dl_seterr(\"Unsupported request %d\", req);\n\t\treturn -1;\n\t}\n\t*(struct link_map **)res = dso;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/ldso/dlopen.c",
    "content": "#include <dlfcn.h>\n#include \"dynlink.h\"\n\nstatic void *stub_dlopen(const char *file, int mode)\n{\n\t__dl_seterr(\"Dynamic loading not supported\");\n\treturn 0;\n}\n\nweak_alias(stub_dlopen, dlopen);\n"
  },
  {
    "path": "user.libc/src/ldso/dlsym.c",
    "content": "#include <dlfcn.h>\n#include \"dynlink.h\"\n\nvoid *dlsym(void *restrict p, const char *restrict s)\n{\n\treturn __dlsym(p, s, 0);\n}\n"
  },
  {
    "path": "user.libc/src/ldso/tlsdesc.c",
    "content": "#include <stddef.h>\n#include <dynlink.h>\n\nptrdiff_t __tlsdesc_static()\n{\n\treturn 0;\n}\n\nweak_alias(__tlsdesc_static, __tlsdesc_dynamic);\n"
  },
  {
    "path": "user.libc/src/legacy/cuserid.c",
    "content": "#define _GNU_SOURCE\n#include <pwd.h>\n#include <stdio.h>\n#include <unistd.h>\n\nchar *cuserid(char *buf)\n{\n\tstruct passwd pw, *ppw;\n\tlong pwb[256];\n\tif (getpwuid_r(geteuid(), &pw, (void *)pwb, sizeof pwb, &ppw))\n\t\treturn 0;\n\tsnprintf(buf, L_cuserid, \"%s\", pw.pw_name);\n\treturn buf;\n}\n"
  },
  {
    "path": "user.libc/src/legacy/daemon.c",
    "content": "#define _GNU_SOURCE\n#include <fcntl.h>\n#include <unistd.h>\n\nint daemon(int nochdir, int noclose)\n{\n\tif (!nochdir && chdir(\"/\"))\n\t\treturn -1;\n\tif (!noclose) {\n\t\tint fd, failed = 0;\n\t\tif ((fd = open(\"/dev/null\", O_RDWR)) < 0) return -1;\n\t\tif (dup2(fd, 0) < 0 || dup2(fd, 1) < 0 || dup2(fd, 2) < 0)\n\t\t\tfailed++;\n\t\tif (fd > 2) close(fd);\n\t\tif (failed) return -1;\n\t}\n\n\tswitch(fork()) {\n\tcase 0: break;\n\tcase -1: return -1;\n\tdefault: _exit(0);\n\t}\n\n\tif (setsid() < 0) return -1;\n\n\tswitch(fork()) {\n\tcase 0: break;\n\tcase -1: return -1;\n\tdefault: _exit(0);\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/legacy/err.c",
    "content": "#include <err.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <stdlib.h>\n\nextern char *__progname;\n\nvoid vwarn(const char *fmt, va_list ap)\n{\n\tfprintf (stderr, \"%s: \", __progname);\n\tif (fmt) {\n\t\tvfprintf(stderr, fmt, ap);\n\t\tfputs (\": \", stderr);\n\t}\n\tperror(0);\n}\n\nvoid vwarnx(const char *fmt, va_list ap)\n{\n\tfprintf (stderr, \"%s: \", __progname);\n\tif (fmt) vfprintf(stderr, fmt, ap);\n\tputc('\\n', stderr);\n}\n\n_Noreturn void verr(int status, const char *fmt, va_list ap)\n{\n\tvwarn(fmt, ap);\n\texit(status);\n}\n\n_Noreturn void verrx(int status, const char *fmt, va_list ap)\n{\n\tvwarnx(fmt, ap);\n\texit(status);\n}\n\nvoid warn(const char *fmt, ...)\n{\n\tva_list ap;\n\tva_start(ap, fmt);\n\tvwarn(fmt, ap);\n\tva_end(ap);\n}\n\nvoid warnx(const char *fmt, ...)\n{\n\tva_list ap;\n\tva_start(ap, fmt);\n\tvwarnx(fmt, ap);\n\tva_end(ap);\n}\n\n_Noreturn void err(int status, const char *fmt, ...)\n{\n\tva_list ap;\n\tva_start(ap, fmt);\n\tverr(status, fmt, ap);\n\tva_end(ap);\n}\n\n_Noreturn void errx(int status, const char *fmt, ...)\n{\n\tva_list ap;\n\tva_start(ap, fmt);\n\tverrx(status, fmt, ap);\n\tva_end(ap);\n}\n"
  },
  {
    "path": "user.libc/src/legacy/euidaccess.c",
    "content": "#define _GNU_SOURCE\n#include <unistd.h>\n#include <fcntl.h>\n\nint euidaccess(const char *filename, int amode)\n{\n\treturn 0;\n}\n\nweak_alias(euidaccess, eaccess);\n"
  },
  {
    "path": "user.libc/src/legacy/ftw.c",
    "content": "#include <ftw.h>\n\nint ftw(const char *path, int (*fn)(const char *, const struct stat *, int), int fd_limit)\n{\n\t/* The following cast assumes that calling a function with one\n\t * argument more than it needs behaves as expected. This is\n\t * actually undefined, but works on all real-world machines. */\n\treturn nftw(path, (int (*)())fn, fd_limit, FTW_PHYS);\n}\n\nweak_alias(ftw, ftw64);\n"
  },
  {
    "path": "user.libc/src/legacy/futimes.c",
    "content": "#define _GNU_SOURCE\n#include <sys/stat.h>\n#include <sys/time.h>\n\nint futimes(int fd, const struct timeval tv[2])\n{\n\tstruct timespec times[2];\n\tif (!tv) return futimens(fd, 0);\n\ttimes[0].tv_sec  = tv[0].tv_sec;\n\ttimes[0].tv_nsec = tv[0].tv_usec * 1000;\n\ttimes[1].tv_sec  = tv[1].tv_sec;\n\ttimes[1].tv_nsec = tv[1].tv_usec * 1000;\n\treturn futimens(fd, times);\n}\n"
  },
  {
    "path": "user.libc/src/legacy/getdtablesize.c",
    "content": "#define _GNU_SOURCE\n#include <unistd.h>\n#include <limits.h>\n#include <sys/resource.h>\n\nint getdtablesize(void)\n{\n\tstruct rlimit rl;\n\tgetrlimit(RLIMIT_NOFILE, &rl);\n\treturn rl.rlim_cur < INT_MAX ? rl.rlim_cur : INT_MAX;\n}\n"
  },
  {
    "path": "user.libc/src/legacy/getloadavg.c",
    "content": "#define _GNU_SOURCE\n#include <stdlib.h>\n#include <sys/sysinfo.h>\n\nint getloadavg(double *a, int n)\n{\n\tstruct sysinfo si;\n\tif (n <= 0) return n ? -1 : 0;\n\tsysinfo(&si);\n\tif (n > 3) n = 3;\n\tfor (int i=0; i<n; i++)\n\t\ta[i] = 1.0/(1<<SI_LOAD_SHIFT) * si.loads[i];\n\treturn n;\n}\n"
  },
  {
    "path": "user.libc/src/legacy/getpagesize.c",
    "content": "#define _GNU_SOURCE\n#include <unistd.h>\n#include \"libc.h\"\n\nint getpagesize(void)\n{\n\treturn PAGE_SIZE;\n}\n"
  },
  {
    "path": "user.libc/src/legacy/getpass.c",
    "content": "#define _GNU_SOURCE\n#include <stdio.h>\n#include <termios.h>\n#include <unistd.h>\n#include <fcntl.h>\n#include <string.h>\n\nchar *getpass(const char *prompt)\n{\n\tint fd;\n\tstruct termios s, t;\n\tssize_t l;\n\tstatic char password[128];\n\n\tif ((fd = open(\"/dev/tty\", O_RDWR|O_NOCTTY|O_CLOEXEC)) < 0) return 0;\n\n\ttcgetattr(fd, &t);\n\ts = t;\n\tt.c_lflag &= ~(ECHO|ISIG);\n\tt.c_lflag |= ICANON;\n\tt.c_iflag &= ~(INLCR|IGNCR);\n\tt.c_iflag |= ICRNL;\n\ttcsetattr(fd, TCSAFLUSH, &t);\n\ttcdrain(fd);\n\n\tdprintf(fd, \"%s\", prompt);\n\n\tl = read(fd, password, sizeof password);\n\tif (l >= 0) {\n\t\tif (l > 0 && password[l-1] == '\\n' || l==sizeof password) l--;\n\t\tpassword[l] = 0;\n\t}\n\n\ttcsetattr(fd, TCSAFLUSH, &s);\n\n\tdprintf(fd, \"\\n\");\n\tclose(fd);\n\n\treturn l<0 ? 0 : password;\n}\n"
  },
  {
    "path": "user.libc/src/legacy/getusershell.c",
    "content": "#define _GNU_SOURCE\n#include <stdio.h>\n#include <unistd.h>\n\nstatic const char defshells[] = \"/bin/sh\\n/bin/csh\\n\";\n\nstatic char *line;\nstatic size_t linesize;\nstatic FILE *f;\n\nvoid endusershell(void)\n{\n\tif (f) fclose(f);\n\tf = 0;\n}\n\nvoid setusershell(void)\n{\n\tif (!f) f = fopen(\"/etc/shells\", \"rbe\");\n\tif (!f) f = fmemopen((void *)defshells, sizeof defshells - 1, \"rb\");\n}\n\nchar *getusershell(void)\n{\n\tssize_t l;\n\tif (!f) setusershell();\n\tif (!f) return 0;\n\tl = getline(&line, &linesize, f);\n\tif (l <= 0) return 0;\n\tif (line[l-1]=='\\n') line[l-1]=0;\n\treturn line;\n}\n"
  },
  {
    "path": "user.libc/src/legacy/isastream.c",
    "content": "#include <stropts.h>\n#include <fcntl.h>\n\nint isastream(int fd)\n{\n\treturn fcntl(fd, F_GETFD) < 0 ? -1 : 0;\n}\n"
  },
  {
    "path": "user.libc/src/legacy/lutimes.c",
    "content": "#define _GNU_SOURCE\n#include <sys/stat.h>\n#include <sys/time.h>\n#include <fcntl.h>\n\nint lutimes(const char *filename, const struct timeval tv[2])\n{\n\tstruct timespec times[2];\n\tif (tv) {\n\t\ttimes[0].tv_sec  = tv[0].tv_sec;\n\t\ttimes[0].tv_nsec = tv[0].tv_usec * 1000;\n\t\ttimes[1].tv_sec  = tv[1].tv_sec;\n\t\ttimes[1].tv_nsec = tv[1].tv_usec * 1000;\n\t}\n\treturn utimensat(AT_FDCWD, filename, tv ? times : 0, AT_SYMLINK_NOFOLLOW);\n}\n"
  },
  {
    "path": "user.libc/src/legacy/ulimit.c",
    "content": "#include <sys/resource.h>\n#include <ulimit.h>\n#include <stdarg.h>\n\nlong ulimit(int cmd, ...)\n{\n\tstruct rlimit rl;\n\tgetrlimit(RLIMIT_FSIZE, &rl);\n\tif (cmd == UL_SETFSIZE) {\n\t\tlong val;\n\t\tva_list ap;\n\t\tva_start(ap, cmd);\n\t\tval = va_arg(ap, long);\n\t\tva_end(ap);\n\t\trl.rlim_cur = 512ULL * val;\n\t\tif (setrlimit(RLIMIT_FSIZE, &rl)) return -1;\n\t}\n\treturn rl.rlim_cur / 512;\n}\n"
  },
  {
    "path": "user.libc/src/legacy/utmpx.c",
    "content": "#define _GNU_SOURCE\n#include <utmpx.h>\n#include <stddef.h>\n#include <errno.h>\n\nvoid endutxent(void)\n{\n}\n\nvoid setutxent(void)\n{\n}\n\nstruct utmpx *getutxent(void)\n{\n\treturn NULL;\n}\n\nstruct utmpx *getutxid(const struct utmpx *ut)\n{\n\treturn NULL;\n}\n\nstruct utmpx *getutxline(const struct utmpx *ut)\n{\n\treturn NULL;\n}\n\nstruct utmpx *pututxline(const struct utmpx *ut)\n{\n\treturn NULL;\n}\n\nvoid updwtmpx(const char *f, const struct utmpx *u)\n{\n}\n\nstatic int __utmpxname(const char *f)\n{\n\terrno = ENOTSUP;\n\treturn -1;\n}\n\nweak_alias(endutxent, endutent);\nweak_alias(setutxent, setutent);\nweak_alias(getutxent, getutent);\nweak_alias(getutxid, getutid);\nweak_alias(getutxline, getutline);\nweak_alias(pututxline, pututline);\nweak_alias(updwtmpx, updwtmp);\nweak_alias(__utmpxname, utmpname);\nweak_alias(__utmpxname, utmpxname);\n"
  },
  {
    "path": "user.libc/src/legacy/valloc.c",
    "content": "#define _BSD_SOURCE\n#include <stdlib.h>\n#include \"libc.h\"\n\nvoid *valloc(size_t size)\n{\n\treturn memalign(PAGE_SIZE, size);\n}\n"
  },
  {
    "path": "user.libc/src/locale/__lctrans.c",
    "content": "#include <locale.h>\n#include \"locale_impl.h\"\n\nstatic const char *dummy(const char *msg, const struct __locale_map *lm)\n{\n\treturn msg;\n}\n\nweak_alias(dummy, __lctrans_impl);\n\nconst char *__lctrans(const char *msg, const struct __locale_map *lm)\n{\n\treturn __lctrans_impl(msg, lm);\n}\n\nconst char *__lctrans_cur(const char *msg)\n{\n\treturn __lctrans_impl(msg, CURRENT_LOCALE->cat[LC_MESSAGES]);\n}\n"
  },
  {
    "path": "user.libc/src/locale/__mo_lookup.c",
    "content": "#include <stdint.h>\n#include <string.h>\n\nstatic inline uint32_t swapc(uint32_t x, int c)\n{\n\treturn c ? x>>24 | x>>8&0xff00 | x<<8&0xff0000 | x<<24 : x;\n}\n\nconst char *__mo_lookup(const void *p, size_t size, const char *s)\n{\n\tconst uint32_t *mo = p;\n\tint sw = *mo - 0x950412de;\n\tuint32_t b = 0, n = swapc(mo[2], sw);\n\tuint32_t o = swapc(mo[3], sw);\n\tuint32_t t = swapc(mo[4], sw);\n\tif (n>=size/4 || o>=size-4*n || t>=size-4*n || ((o|t)%4))\n\t\treturn 0;\n\to/=4;\n\tt/=4;\n\tfor (;;) {\n\t\tuint32_t ol = swapc(mo[o+2*(b+n/2)], sw);\n\t\tuint32_t os = swapc(mo[o+2*(b+n/2)+1], sw);\n\t\tif (os >= size || ol >= size-os || ((char *)p)[os+ol])\n\t\t\treturn 0;\n\t\tint sign = strcmp(s, (char *)p + os);\n\t\tif (!sign) {\n\t\t\tuint32_t tl = swapc(mo[t+2*(b+n/2)], sw);\n\t\t\tuint32_t ts = swapc(mo[t+2*(b+n/2)+1], sw);\n\t\t\tif (ts >= size || tl >= size-ts || ((char *)p)[ts+tl])\n\t\t\t\treturn 0;\n\t\t\treturn (char *)p + ts;\n\t\t}\n\t\telse if (n == 1) return 0;\n\t\telse if (sign < 0)\n\t\t\tn /= 2;\n\t\telse {\n\t\t\tb += n/2;\n\t\t\tn -= n/2;\n\t\t}\n\t}\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/locale/big5.h",
    "content": "12288,65292,12289,12290,65294,8231,65307,65306,65311,65281,65072,8230,8229,\n65104,65105,65106,183,65108,65109,65110,65111,65372,8211,65073,8212,65075,\n9588,65076,65103,65288,65289,65077,65078,65371,65373,65079,65080,12308,12309,\n65081,65082,12304,12305,65083,65084,12298,12299,65085,65086,12296,12297,65087,\n65088,12300,12301,65089,65090,12302,12303,65091,65092,65113,65114,65115,65116,\n65117,65118,8216,8217,8220,8221,12317,12318,8245,8242,65283,65286,65290,8251,\n167,12291,9675,9679,9651,9650,9678,9734,9733,9671,9670,9633,9632,9661,9660,\n12963,8453,175,65507,65343,717,65097,65098,65101,65102,65099,65100,65119,\n65120,65121,65291,65293,215,247,177,8730,65308,65310,65309,8806,8807,8800,\n8734,8786,8801,65122,65123,65124,65125,65126,65374,8745,8746,8869,8736,8735,\n8895,13266,13265,8747,8750,8757,8756,9792,9794,8853,8857,8593,8595,8592,8594,\n8598,8599,8601,8600,8741,8739,65295,65340,8725,65128,65284,65509,12306,65504,\n65505,65285,65312,8451,8457,65129,65130,65131,13269,13212,13213,13214,13262,\n13217,13198,13199,13252,176,20825,20827,20830,20829,20833,20835,21991,29929,\n31950,9601,9602,9603,9604,9605,9606,9607,9608,9615,9614,9613,9612,9611,9610,\n9609,9532,9524,9516,9508,9500,9620,9472,9474,9621,9484,9488,9492,9496,9581,\n9582,9584,9583,9552,9566,9578,9569,9698,9699,9701,9700,9585,9586,9587,65296,\n65297,65298,65299,65300,65301,65302,65303,65304,65305,8544,8545,8546,8547,\n8548,8549,8550,8551,8552,8553,12321,\n12322,12323,12324,12325,12326,12327,12328,12329,21313,21316,21317,65313,65314,\n65315,65316,65317,65318,65319,65320,65321,65322,65323,65324,65325,65326,65327,\n65328,65329,65330,65331,65332,65333,65334,65335,65336,65337,65338,65345,65346,\n65347,65348,65349,65350,65351,65352,65353,65354,65355,65356,65357,65358,65359,\n65360,65361,65362,65363,65364,65365,65366,65367,65368,65369,65370,913,914,915,\n916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,\n936,937,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,\n963,964,965,966,967,968,969,12549,12550,12551,12552,12553,12554,12555,12556,\n12557,12558,12559,12560,12561,12562,12563,12564,12565,12566,12567,12568,12569,\n12570,12571,12572,12573,12574,12575,12576,12577,12578,12579,12580,12581,12582,\n12583,12584,12585,729,713,714,711,715,9216,9217,9218,9219,9220,9221,9222,9223,\n9224,9225,9226,9227,9228,9229,9230,9231,9232,9233,9234,9235,9236,9237,9238,\n9239,9240,9241,9242,9243,9244,9245,9246,9247,9249,8364,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19968,20057,19969,19971,20035,20061,20102,\n20108,20154,20799,20837,20843,20960,20992,20993,21147,21269,21313,21340,21448,\n19977,19979,19976,19978,20011,20024,20961,20037,20040,20063,20062,20110,20129,\n20800,20995,21242,21315,21449,21475,22303,\n22763,22805,22823,22899,23376,23377,23379,23544,23567,23586,23608,23665,24029,\n24037,24049,24050,24051,24062,24178,24318,24331,24339,25165,19985,19984,19981,\n20013,20016,20025,20043,23609,20104,20113,20117,20114,20116,20130,20161,20160,\n20163,20166,20167,20173,20170,20171,20164,20803,20801,20839,20845,20846,20844,\n20887,20982,20998,20999,21000,21243,21246,21247,21270,21305,21320,21319,21317,\n21342,21380,21451,21450,21453,22764,22825,22827,22826,22829,23380,23569,23588,\n23610,23663,24052,24187,24319,24340,24341,24515,25096,25142,25163,25166,25903,\n25991,26007,26020,26041,26085,26352,26376,26408,27424,27490,27513,27595,27604,\n27611,27663,27700,28779,29226,29238,29243,29255,29273,29275,29356,29579,19993,\n19990,19989,19988,19992,20027,20045,20047,20046,20197,20184,20180,20181,20182,\n20183,20195,20196,20185,20190,20805,20804,20873,20874,20908,20985,20986,20984,\n21002,21152,21151,21253,21254,21271,21277,20191,21322,21321,21345,21344,21359,\n21358,21435,21487,21476,21491,21484,21486,21481,21480,21500,21496,21493,21483,\n21478,21482,21490,21489,21488,21477,21485,21499,22235,22234,22806,22830,22833,\n22900,22902,23381,23427,23612,24040,24039,24038,24066,24067,24179,24188,24321,\n24344,24343,24517,25098,25171,25172,25170,25169,26021,26086,26414,26412,26410,\n26411,26413,27491,27597,27665,27664,27704,27713,27712,27710,29359,29572,29577,\n29916,29926,29976,29983,29992,29993,30000,30001,30002,30003,30091,30333,30382,\n30399,30446,30683,30690,30707,31034,31166,31348,31435,19998,19999,20050,20051,\n20073,20121,20132,20134,20133,20223,20233,20249,20234,\n20245,20237,20240,20241,20239,20210,20214,20219,20208,20211,20221,20225,20235,\n20809,20807,20806,20808,20840,20849,20877,20912,21015,21009,21010,21006,21014,\n21155,21256,21281,21280,21360,21361,21513,21519,21516,21514,21520,21505,21515,\n21508,21521,21517,21512,21507,21518,21510,21522,22240,22238,22237,22323,22320,\n22312,22317,22316,22319,22313,22809,22810,22839,22840,22916,22904,22915,22909,\n22905,22914,22913,23383,23384,23431,23432,23429,23433,23546,23574,23673,24030,\n24070,24182,24180,24335,24347,24537,24534,25102,25100,25101,25104,25187,25179,\n25176,25910,26089,26088,26092,26093,26354,26355,26377,26429,26420,26417,26421,\n27425,27492,27515,27670,27741,27735,27737,27743,27744,27728,27733,27745,27739,\n27725,27726,28784,29279,29277,30334,31481,31859,31992,32566,32650,32701,32769,\n32771,32780,32786,32819,32895,32905,32907,32908,33251,33258,33267,33276,33292,\n33307,33311,33390,33394,33406,34411,34880,34892,34915,35199,38433,20018,20136,\n20301,20303,20295,20311,20318,20276,20315,20309,20272,20304,20305,20285,20282,\n20280,20291,20308,20284,20294,20323,20316,20320,20271,20302,20278,20313,20317,\n20296,20314,20812,20811,20813,20853,20918,20919,21029,21028,21033,21034,21032,\n21163,21161,21162,21164,21283,21363,21365,21533,21549,21534,21566,21542,21582,\n21543,21574,21571,21555,21576,21570,21531,21545,21578,21561,21563,21560,21550,\n21557,21558,21536,21564,21568,21553,21547,21535,21548,22250,22256,22244,22251,\n22346,22353,22336,22349,22343,22350,22334,22352,22351,22331,22767,22846,22941,\n22930,22952,22942,22947,22937,22934,22925,22948,22931,\n22922,22949,23389,23388,23386,23387,23436,23435,23439,23596,23616,23617,23615,\n23614,23696,23697,23700,23692,24043,24076,24207,24199,24202,24311,24324,24351,\n24420,24418,24439,24441,24536,24524,24535,24525,24561,24555,24568,24554,25106,\n25105,25220,25239,25238,25216,25206,25225,25197,25226,25212,25214,25209,25203,\n25234,25199,25240,25198,25237,25235,25233,25222,25913,25915,25912,26097,26356,\n26463,26446,26447,26448,26449,26460,26454,26462,26441,26438,26464,26451,26455,\n27493,27599,27714,27742,27801,27777,27784,27785,27781,27803,27754,27770,27792,\n27760,27788,27752,27798,27794,27773,27779,27762,27774,27764,27782,27766,27789,\n27796,27800,27778,28790,28796,28797,28792,29282,29281,29280,29380,29378,29590,\n29996,29995,30007,30008,30338,30447,30691,31169,31168,31167,31350,31995,32597,\n32918,32915,32925,32920,32923,32922,32946,33391,33426,33419,33421,35211,35282,\n35328,35895,35910,35925,35997,36196,36208,36275,36523,36554,36763,36784,36802,\n36806,36805,36804,24033,37009,37026,37034,37030,37027,37193,37318,37324,38450,\n38446,38449,38442,38444,20006,20054,20083,20107,20123,20126,20139,20140,20335,\n20381,20365,20339,20351,20332,20379,20363,20358,20355,20336,20341,20360,20329,\n20347,20374,20350,20367,20369,20346,20820,20818,20821,20841,20855,20854,20856,\n20925,20989,21051,21048,21047,21050,21040,21038,21046,21057,21182,21179,21330,\n21332,21331,21329,21350,21367,21368,21369,21462,21460,21463,21619,21621,21654,\n21624,21653,21632,21627,21623,21636,21650,21638,21628,21648,21617,21622,21644,\n21658,21602,21608,21643,21629,21646,22266,22403,22391,\n22378,22377,22369,22374,22372,22396,22812,22857,22855,22856,22852,22868,22974,\n22971,22996,22969,22958,22993,22982,22992,22989,22987,22995,22986,22959,22963,\n22994,22981,23391,23396,23395,23447,23450,23448,23452,23449,23451,23578,23624,\n23621,23622,23735,23713,23736,23721,23723,23729,23731,24088,24090,24086,24085,\n24091,24081,24184,24218,24215,24220,24213,24214,24310,24358,24359,24361,24448,\n24449,24447,24444,24541,24544,24573,24565,24575,24591,24596,24623,24629,24598,\n24618,24597,24609,24615,24617,24619,24603,25110,25109,25151,25150,25152,25215,\n25289,25292,25284,25279,25282,25273,25298,25307,25259,25299,25300,25291,25288,\n25256,25277,25276,25296,25305,25287,25293,25269,25306,25265,25304,25302,25303,\n25286,25260,25294,25918,26023,26044,26106,26132,26131,26124,26118,26114,26126,\n26112,26127,26133,26122,26119,26381,26379,26477,26507,26517,26481,26524,26483,\n26487,26503,26525,26519,26479,26480,26495,26505,26494,26512,26485,26522,26515,\n26492,26474,26482,27427,27494,27495,27519,27667,27675,27875,27880,27891,27825,\n27852,27877,27827,27837,27838,27836,27874,27819,27861,27859,27832,27844,27833,\n27841,27822,27863,27845,27889,27839,27835,27873,27867,27850,27820,27887,27868,\n27862,27872,28821,28814,28818,28810,28825,29228,29229,29240,29256,29287,29289,\n29376,29390,29401,29399,29392,29609,29608,29599,29611,29605,30013,30109,30105,\n30106,30340,30402,30450,30452,30693,30717,31038,31040,31041,31177,31176,31354,\n31353,31482,31998,32596,32652,32651,32773,32954,32933,32930,32945,32929,32939,\n32937,32948,32938,32943,33253,33278,33293,33459,33437,\n33433,33453,33469,33439,33465,33457,33452,33445,33455,33464,33443,33456,33470,\n33463,34382,34417,21021,34920,36555,36814,36820,36817,37045,37048,37041,37046,\n37319,37329,38263,38272,38428,38464,38463,38459,38468,38466,38585,38632,38738,\n38750,20127,20141,20142,20449,20405,20399,20415,20448,20433,20431,20445,20419,\n20406,20440,20447,20426,20439,20398,20432,20420,20418,20442,20430,20446,20407,\n20823,20882,20881,20896,21070,21059,21066,21069,21068,21067,21063,21191,21193,\n21187,21185,21261,21335,21371,21402,21467,21676,21696,21672,21710,21705,21688,\n21670,21683,21703,21698,21693,21674,21697,21700,21704,21679,21675,21681,21691,\n21673,21671,21695,22271,22402,22411,22432,22435,22434,22478,22446,22419,22869,\n22865,22863,22862,22864,23004,23000,23039,23011,23016,23043,23013,23018,23002,\n23014,23041,23035,23401,23459,23462,23460,23458,23461,23553,23630,23631,23629,\n23627,23769,23762,24055,24093,24101,24095,24189,24224,24230,24314,24328,24365,\n24421,24456,24453,24458,24459,24455,24460,24457,24594,24605,24608,24613,24590,\n24616,24653,24688,24680,24674,24646,24643,24684,24683,24682,24676,25153,25308,\n25366,25353,25340,25325,25345,25326,25341,25351,25329,25335,25327,25324,25342,\n25332,25361,25346,25919,25925,26027,26045,26082,26149,26157,26144,26151,26159,\n26143,26152,26161,26148,26359,26623,26579,26609,26580,26576,26604,26550,26543,\n26613,26601,26607,26564,26577,26548,26586,26597,26552,26575,26590,26611,26544,\n26585,26594,26589,26578,27498,27523,27526,27573,27602,27607,27679,27849,27915,\n27954,27946,27969,27941,27916,27953,27934,27927,27963,\n27965,27966,27958,27931,27893,27961,27943,27960,27945,27950,27957,27918,27947,\n28843,28858,28851,28844,28847,28845,28856,28846,28836,29232,29298,29295,29300,\n29417,29408,29409,29623,29642,29627,29618,29645,29632,29619,29978,29997,30031,\n30028,30030,30027,30123,30116,30117,30114,30115,30328,30342,30343,30344,30408,\n30406,30403,30405,30465,30457,30456,30473,30475,30462,30460,30471,30684,30722,\n30740,30732,30733,31046,31049,31048,31047,31161,31162,31185,31186,31179,31359,\n31361,31487,31485,31869,32002,32005,32000,32009,32007,32004,32006,32568,32654,\n32703,32772,32784,32781,32785,32822,32982,32997,32986,32963,32964,32972,32993,\n32987,32974,32990,32996,32989,33268,33314,33511,33539,33541,33507,33499,33510,\n33540,33509,33538,33545,33490,33495,33521,33537,33500,33492,33489,33502,33491,\n33503,33519,33542,34384,34425,34427,34426,34893,34923,35201,35284,35336,35330,\n35331,35998,36000,36212,36211,36276,36557,36556,36848,36838,36834,36842,36837,\n36845,36843,36836,36840,37066,37070,37057,37059,37195,37194,37325,38274,38480,\n38475,38476,38477,38754,38761,38859,38893,38899,38913,39080,39131,39135,39318,\n39321,20056,20147,20492,20493,20515,20463,20518,20517,20472,20521,20502,20486,\n20540,20511,20506,20498,20497,20474,20480,20500,20520,20465,20513,20491,20505,\n20504,20467,20462,20525,20522,20478,20523,20489,20860,20900,20901,20898,20941,\n20940,20934,20939,21078,21084,21076,21083,21085,21290,21375,21407,21405,21471,\n21736,21776,21761,21815,21756,21733,21746,21766,21754,21780,21737,21741,21729,\n21769,21742,21738,21734,21799,21767,21757,21775,22275,\n22276,22466,22484,22475,22467,22537,22799,22871,22872,22874,23057,23064,23068,\n23071,23067,23059,23020,23072,23075,23081,23077,23052,23049,23403,23640,23472,\n23475,23478,23476,23470,23477,23481,23480,23556,23633,23637,23632,23789,23805,\n23803,23786,23784,23792,23798,23809,23796,24046,24109,24107,24235,24237,24231,\n24369,24466,24465,24464,24665,24675,24677,24656,24661,24685,24681,24687,24708,\n24735,24730,24717,24724,24716,24709,24726,25159,25331,25352,25343,25422,25406,\n25391,25429,25410,25414,25423,25417,25402,25424,25405,25386,25387,25384,25421,\n25420,25928,25929,26009,26049,26053,26178,26185,26191,26179,26194,26188,26181,\n26177,26360,26388,26389,26391,26657,26680,26696,26694,26707,26681,26690,26708,\n26665,26803,26647,26700,26705,26685,26612,26704,26688,26684,26691,26666,26693,\n26643,26648,26689,27530,27529,27575,27683,27687,27688,27686,27684,27888,28010,\n28053,28040,28039,28006,28024,28023,27993,28051,28012,28041,28014,27994,28020,\n28009,28044,28042,28025,28037,28005,28052,28874,28888,28900,28889,28872,28879,\n29241,29305,29436,29433,29437,29432,29431,29574,29677,29705,29678,29664,29674,\n29662,30036,30045,30044,30042,30041,30142,30149,30151,30130,30131,30141,30140,\n30137,30146,30136,30347,30384,30410,30413,30414,30505,30495,30496,30504,30697,\n30768,30759,30776,30749,30772,30775,30757,30765,30752,30751,30770,31061,31056,\n31072,31071,31062,31070,31069,31063,31066,31204,31203,31207,31199,31206,31209,\n31192,31364,31368,31449,31494,31505,31881,32033,32023,32011,32010,32032,32034,\n32020,32016,32021,32026,32028,32013,32025,32027,32570,\n32607,32660,32709,32705,32774,32792,32789,32793,32791,32829,32831,33009,33026,\n33008,33029,33005,33012,33030,33016,33011,33032,33021,33034,33020,33007,33261,\n33260,33280,33296,33322,33323,33320,33324,33467,33579,33618,33620,33610,33592,\n33616,33609,33589,33588,33615,33586,33593,33590,33559,33600,33585,33576,33603,\n34388,34442,34474,34451,34468,34473,34444,34467,34460,34928,34935,34945,34946,\n34941,34937,35352,35344,35342,35340,35349,35338,35351,35347,35350,35343,35345,\n35912,35962,35961,36001,36002,36215,36524,36562,36564,36559,36785,36865,36870,\n36855,36864,36858,36852,36867,36861,36869,36856,37013,37089,37085,37090,37202,\n37197,37196,37336,37341,37335,37340,37337,38275,38498,38499,38497,38491,38493,\n38500,38488,38494,38587,39138,39340,39592,39640,39717,39730,39740,20094,20602,\n20605,20572,20551,20547,20556,20570,20553,20581,20598,20558,20565,20597,20596,\n20599,20559,20495,20591,20589,20828,20885,20976,21098,21103,21202,21209,21208,\n21205,21264,21263,21273,21311,21312,21310,21443,26364,21830,21866,21862,21828,\n21854,21857,21827,21834,21809,21846,21839,21845,21807,21860,21816,21806,21852,\n21804,21859,21811,21825,21847,22280,22283,22281,22495,22533,22538,22534,22496,\n22500,22522,22530,22581,22519,22521,22816,22882,23094,23105,23113,23142,23146,\n23104,23100,23138,23130,23110,23114,23408,23495,23493,23492,23490,23487,23494,\n23561,23560,23559,23648,23644,23645,23815,23814,23822,23835,23830,23842,23825,\n23849,23828,23833,23844,23847,23831,24034,24120,24118,24115,24119,24247,24248,\n24246,24245,24254,24373,24375,24407,24428,24425,24427,\n24471,24473,24478,24472,24481,24480,24476,24703,24739,24713,24736,24744,24779,\n24756,24806,24765,24773,24763,24757,24796,24764,24792,24789,24774,24799,24760,\n24794,24775,25114,25115,25160,25504,25511,25458,25494,25506,25509,25463,25447,\n25496,25514,25457,25513,25481,25475,25499,25451,25512,25476,25480,25497,25505,\n25516,25490,25487,25472,25467,25449,25448,25466,25949,25942,25937,25945,25943,\n21855,25935,25944,25941,25940,26012,26011,26028,26063,26059,26060,26062,26205,\n26202,26212,26216,26214,26206,26361,21207,26395,26753,26799,26786,26771,26805,\n26751,26742,26801,26791,26775,26800,26755,26820,26797,26758,26757,26772,26781,\n26792,26783,26785,26754,27442,27578,27627,27628,27691,28046,28092,28147,28121,\n28082,28129,28108,28132,28155,28154,28165,28103,28107,28079,28113,28078,28126,\n28153,28088,28151,28149,28101,28114,28186,28085,28122,28139,28120,28138,28145,\n28142,28136,28102,28100,28074,28140,28095,28134,28921,28937,28938,28925,28911,\n29245,29309,29313,29468,29467,29462,29459,29465,29575,29701,29706,29699,29702,\n29694,29709,29920,29942,29943,29980,29986,30053,30054,30050,30064,30095,30164,\n30165,30133,30154,30157,30350,30420,30418,30427,30519,30526,30524,30518,30520,\n30522,30827,30787,30798,31077,31080,31085,31227,31378,31381,31520,31528,31515,\n31532,31526,31513,31518,31534,31890,31895,31893,32070,32067,32113,32046,32057,\n32060,32064,32048,32051,32068,32047,32066,32050,32049,32573,32670,32666,32716,\n32718,32722,32796,32842,32838,33071,33046,33059,33067,33065,33072,33060,33282,\n33333,33335,33334,33337,33678,33694,33688,33656,33698,\n33686,33725,33707,33682,33674,33683,33673,33696,33655,33659,33660,33670,33703,\n34389,24426,34503,34496,34486,34500,34485,34502,34507,34481,34479,34505,34899,\n34974,34952,34987,34962,34966,34957,34955,35219,35215,35370,35357,35363,35365,\n35377,35373,35359,35355,35362,35913,35930,36009,36012,36011,36008,36010,36007,\n36199,36198,36286,36282,36571,36575,36889,36877,36890,36887,36899,36895,36893,\n36880,36885,36894,36896,36879,36898,36886,36891,36884,37096,37101,37117,37207,\n37326,37365,37350,37347,37351,37357,37353,38281,38506,38517,38515,38520,38512,\n38516,38518,38519,38508,38592,38634,38633,31456,31455,38914,38915,39770,40165,\n40565,40575,40613,40635,20642,20621,20613,20633,20625,20608,20630,20632,20634,\n26368,20977,21106,21108,21109,21097,21214,21213,21211,21338,21413,21883,21888,\n21927,21884,21898,21917,21912,21890,21916,21930,21908,21895,21899,21891,21939,\n21934,21919,21822,21938,21914,21947,21932,21937,21886,21897,21931,21913,22285,\n22575,22570,22580,22564,22576,22577,22561,22557,22560,22777,22778,22880,23159,\n23194,23167,23186,23195,23207,23411,23409,23506,23500,23507,23504,23562,23563,\n23601,23884,23888,23860,23879,24061,24133,24125,24128,24131,24190,24266,24257,\n24258,24260,24380,24429,24489,24490,24488,24785,24801,24754,24758,24800,24860,\n24867,24826,24853,24816,24827,24820,24936,24817,24846,24822,24841,24832,24850,\n25119,25161,25507,25484,25551,25536,25577,25545,25542,25549,25554,25571,25552,\n25569,25558,25581,25582,25462,25588,25578,25563,25682,25562,25593,25950,25958,\n25954,25955,26001,26000,26031,26222,26224,26228,26230,\n26223,26257,26234,26238,26231,26366,26367,26399,26397,26874,26837,26848,26840,\n26839,26885,26847,26869,26862,26855,26873,26834,26866,26851,26827,26829,26893,\n26898,26894,26825,26842,26990,26875,27454,27450,27453,27544,27542,27580,27631,\n27694,27695,27692,28207,28216,28244,28193,28210,28263,28234,28192,28197,28195,\n28187,28251,28248,28196,28246,28270,28205,28198,28271,28212,28237,28218,28204,\n28227,28189,28222,28363,28297,28185,28238,28259,28228,28274,28265,28255,28953,\n28954,28966,28976,28961,28982,29038,28956,29260,29316,29312,29494,29477,29492,\n29481,29754,29738,29747,29730,29733,29749,29750,29748,29743,29723,29734,29736,\n29989,29990,30059,30058,30178,30171,30179,30169,30168,30174,30176,30331,30332,\n30358,30355,30388,30428,30543,30701,30813,30828,30831,31245,31240,31243,31237,\n31232,31384,31383,31382,31461,31459,31561,31574,31558,31568,31570,31572,31565,\n31563,31567,31569,31903,31909,32094,32080,32104,32085,32043,32110,32114,32097,\n32102,32098,32112,32115,21892,32724,32725,32779,32850,32901,33109,33108,33099,\n33105,33102,33081,33094,33086,33100,33107,33140,33298,33308,33769,33795,33784,\n33805,33760,33733,33803,33729,33775,33777,33780,33879,33802,33776,33804,33740,\n33789,33778,33738,33848,33806,33796,33756,33799,33748,33759,34395,34527,34521,\n34541,34516,34523,34532,34512,34526,34903,35009,35010,34993,35203,35222,35387,\n35424,35413,35422,35388,35393,35412,35419,35408,35398,35380,35386,35382,35414,\n35937,35970,36015,36028,36019,36029,36033,36027,36032,36020,36023,36022,36031,\n36024,36234,36229,36225,36302,36317,36299,36314,36305,\n36300,36315,36294,36603,36600,36604,36764,36910,36917,36913,36920,36914,36918,\n37122,37109,37129,37118,37219,37221,37327,37396,37397,37411,37385,37406,37389,\n37392,37383,37393,38292,38287,38283,38289,38291,38290,38286,38538,38542,38539,\n38525,38533,38534,38541,38514,38532,38593,38597,38596,38598,38599,38639,38642,\n38860,38917,38918,38920,39143,39146,39151,39145,39154,39149,39342,39341,40643,\n40653,40657,20098,20653,20661,20658,20659,20677,20670,20652,20663,20667,20655,\n20679,21119,21111,21117,21215,21222,21220,21218,21219,21295,21983,21992,21971,\n21990,21966,21980,21959,21969,21987,21988,21999,21978,21985,21957,21958,21989,\n21961,22290,22291,22622,22609,22616,22615,22618,22612,22635,22604,22637,22602,\n22626,22610,22603,22887,23233,23241,23244,23230,23229,23228,23219,23234,23218,\n23913,23919,24140,24185,24265,24264,24338,24409,24492,24494,24858,24847,24904,\n24863,24819,24859,24825,24833,24840,24910,24908,24900,24909,24894,24884,24871,\n24845,24838,24887,25121,25122,25619,25662,25630,25642,25645,25661,25644,25615,\n25628,25620,25613,25654,25622,25623,25606,25964,26015,26032,26263,26249,26247,\n26248,26262,26244,26264,26253,26371,27028,26989,26970,26999,26976,26964,26997,\n26928,27010,26954,26984,26987,26974,26963,27001,27014,26973,26979,26971,27463,\n27506,27584,27583,27603,27645,28322,28335,28371,28342,28354,28304,28317,28359,\n28357,28325,28312,28348,28346,28331,28369,28310,28316,28356,28372,28330,28327,\n28340,29006,29017,29033,29028,29001,29031,29020,29036,29030,29004,29029,29022,\n28998,29032,29014,29242,29266,29495,29509,29503,29502,\n29807,29786,29781,29791,29790,29761,29759,29785,29787,29788,30070,30072,30208,\n30192,30209,30194,30193,30202,30207,30196,30195,30430,30431,30555,30571,30566,\n30558,30563,30585,30570,30572,30556,30565,30568,30562,30702,30862,30896,30871,\n30872,30860,30857,30844,30865,30867,30847,31098,31103,31105,33836,31165,31260,\n31258,31264,31252,31263,31262,31391,31392,31607,31680,31584,31598,31591,31921,\n31923,31925,32147,32121,32145,32129,32143,32091,32622,32617,32618,32626,32681,\n32680,32676,32854,32856,32902,32900,33137,33136,33144,33125,33134,33139,33131,\n33145,33146,33126,33285,33351,33922,33911,33853,33841,33909,33894,33899,33865,\n33900,33883,33852,33845,33889,33891,33897,33901,33862,34398,34396,34399,34553,\n34579,34568,34567,34560,34558,34555,34562,34563,34566,34570,34905,35039,35028,\n35033,35036,35032,35037,35041,35018,35029,35026,35228,35299,35435,35442,35443,\n35430,35433,35440,35463,35452,35427,35488,35441,35461,35437,35426,35438,35436,\n35449,35451,35390,35432,35938,35978,35977,36042,36039,36040,36036,36018,36035,\n36034,36037,36321,36319,36328,36335,36339,36346,36330,36324,36326,36530,36611,\n36617,36606,36618,36767,36786,36939,36938,36947,36930,36948,36924,36949,36944,\n36935,36943,36942,36941,36945,36926,36929,37138,37143,37228,37226,37225,37321,\n37431,37463,37432,37437,37440,37438,37467,37451,37476,37457,37428,37449,37453,\n37445,37433,37439,37466,38296,38552,38548,38549,38605,38603,38601,38602,38647,\n38651,38649,38646,38742,38772,38774,38928,38929,38931,38922,38930,38924,39164,\n39156,39165,39166,39347,39345,39348,39649,40169,40578,\n40718,40723,40736,20711,20718,20709,20694,20717,20698,20693,20687,20689,20721,\n20686,20713,20834,20979,21123,21122,21297,21421,22014,22016,22043,22039,22013,\n22036,22022,22025,22029,22030,22007,22038,22047,22024,22032,22006,22296,22294,\n22645,22654,22659,22675,22666,22649,22661,22653,22781,22821,22818,22820,22890,\n22889,23265,23270,23273,23255,23254,23256,23267,23413,23518,23527,23521,23525,\n23526,23528,23522,23524,23519,23565,23650,23940,23943,24155,24163,24149,24151,\n24148,24275,24278,24330,24390,24432,24505,24903,24895,24907,24951,24930,24931,\n24927,24922,24920,24949,25130,25735,25688,25684,25764,25720,25695,25722,25681,\n25703,25652,25709,25723,25970,26017,26071,26070,26274,26280,26269,27036,27048,\n27029,27073,27054,27091,27083,27035,27063,27067,27051,27060,27088,27085,27053,\n27084,27046,27075,27043,27465,27468,27699,28467,28436,28414,28435,28404,28457,\n28478,28448,28460,28431,28418,28450,28415,28399,28422,28465,28472,28466,28451,\n28437,28459,28463,28552,28458,28396,28417,28402,28364,28407,29076,29081,29053,\n29066,29060,29074,29246,29330,29334,29508,29520,29796,29795,29802,29808,29805,\n29956,30097,30247,30221,30219,30217,30227,30433,30435,30596,30589,30591,30561,\n30913,30879,30887,30899,30889,30883,31118,31119,31117,31278,31281,31402,31401,\n31469,31471,31649,31637,31627,31605,31639,31645,31636,31631,31672,31623,31620,\n31929,31933,31934,32187,32176,32156,32189,32190,32160,32202,32180,32178,32177,\n32186,32162,32191,32181,32184,32173,32210,32199,32172,32624,32736,32737,32735,\n32862,32858,32903,33104,33152,33167,33160,33162,33151,\n33154,33255,33274,33287,33300,33310,33355,33993,33983,33990,33988,33945,33950,\n33970,33948,33995,33976,33984,34003,33936,33980,34001,33994,34623,34588,34619,\n34594,34597,34612,34584,34645,34615,34601,35059,35074,35060,35065,35064,35069,\n35048,35098,35055,35494,35468,35486,35491,35469,35489,35475,35492,35498,35493,\n35496,35480,35473,35482,35495,35946,35981,35980,36051,36049,36050,36203,36249,\n36245,36348,36628,36626,36629,36627,36771,36960,36952,36956,36963,36953,36958,\n36962,36957,36955,37145,37144,37150,37237,37240,37239,37236,37496,37504,37509,\n37528,37526,37499,37523,37532,37544,37500,37521,38305,38312,38313,38307,38309,\n38308,38553,38556,38555,38604,38610,38656,38780,38789,38902,38935,38936,39087,\n39089,39171,39173,39180,39177,39361,39599,39600,39654,39745,39746,40180,40182,\n40179,40636,40763,40778,20740,20736,20731,20725,20729,20738,20744,20745,20741,\n20956,21127,21128,21129,21133,21130,21232,21426,22062,22075,22073,22066,22079,\n22068,22057,22099,22094,22103,22132,22070,22063,22064,22656,22687,22686,22707,\n22684,22702,22697,22694,22893,23305,23291,23307,23285,23308,23304,23534,23532,\n23529,23531,23652,23653,23965,23956,24162,24159,24161,24290,24282,24287,24285,\n24291,24288,24392,24433,24503,24501,24950,24935,24942,24925,24917,24962,24956,\n24944,24939,24958,24999,24976,25003,24974,25004,24986,24996,24980,25006,25134,\n25705,25711,25721,25758,25778,25736,25744,25776,25765,25747,25749,25769,25746,\n25774,25773,25771,25754,25772,25753,25762,25779,25973,25975,25976,26286,26283,\n26292,26289,27171,27167,27112,27137,27166,27161,27133,\n27169,27155,27146,27123,27138,27141,27117,27153,27472,27470,27556,27589,27590,\n28479,28540,28548,28497,28518,28500,28550,28525,28507,28536,28526,28558,28538,\n28528,28516,28567,28504,28373,28527,28512,28511,29087,29100,29105,29096,29270,\n29339,29518,29527,29801,29835,29827,29822,29824,30079,30240,30249,30239,30244,\n30246,30241,30242,30362,30394,30436,30606,30599,30604,30609,30603,30923,30917,\n30906,30922,30910,30933,30908,30928,31295,31292,31296,31293,31287,31291,31407,\n31406,31661,31665,31684,31668,31686,31687,31681,31648,31692,31946,32224,32244,\n32239,32251,32216,32236,32221,32232,32227,32218,32222,32233,32158,32217,32242,\n32249,32629,32631,32687,32745,32806,33179,33180,33181,33184,33178,33176,34071,\n34109,34074,34030,34092,34093,34067,34065,34083,34081,34068,34028,34085,34047,\n34054,34690,34676,34678,34656,34662,34680,34664,34649,34647,34636,34643,34907,\n34909,35088,35079,35090,35091,35093,35082,35516,35538,35527,35524,35477,35531,\n35576,35506,35529,35522,35519,35504,35542,35533,35510,35513,35547,35916,35918,\n35948,36064,36062,36070,36068,36076,36077,36066,36067,36060,36074,36065,36205,\n36255,36259,36395,36368,36381,36386,36367,36393,36383,36385,36382,36538,36637,\n36635,36639,36649,36646,36650,36636,36638,36645,36969,36974,36968,36973,36983,\n37168,37165,37159,37169,37255,37257,37259,37251,37573,37563,37559,37610,37548,\n37604,37569,37555,37564,37586,37575,37616,37554,38317,38321,38660,38662,38663,\n38665,38752,38797,38795,38799,38945,38955,38940,39091,39178,39187,39186,39192,\n39389,39376,39391,39387,39377,39381,39378,39385,39607,\n39662,39663,39719,39749,39748,39799,39791,40198,40201,40195,40617,40638,40654,\n22696,40786,20754,20760,20756,20752,20757,20864,20906,20957,21137,21139,21235,\n22105,22123,22137,22121,22116,22136,22122,22120,22117,22129,22127,22124,22114,\n22134,22721,22718,22727,22725,22894,23325,23348,23416,23536,23566,24394,25010,\n24977,25001,24970,25037,25014,25022,25034,25032,25136,25797,25793,25803,25787,\n25788,25818,25796,25799,25794,25805,25791,25810,25812,25790,25972,26310,26313,\n26297,26308,26311,26296,27197,27192,27194,27225,27243,27224,27193,27204,27234,\n27233,27211,27207,27189,27231,27208,27481,27511,27653,28610,28593,28577,28611,\n28580,28609,28583,28595,28608,28601,28598,28582,28576,28596,29118,29129,29136,\n29138,29128,29141,29113,29134,29145,29148,29123,29124,29544,29852,29859,29848,\n29855,29854,29922,29964,29965,30260,30264,30266,30439,30437,30624,30622,30623,\n30629,30952,30938,30956,30951,31142,31309,31310,31302,31308,31307,31418,31705,\n31761,31689,31716,31707,31713,31721,31718,31957,31958,32266,32273,32264,32283,\n32291,32286,32285,32265,32272,32633,32690,32752,32753,32750,32808,33203,33193,\n33192,33275,33288,33368,33369,34122,34137,34120,34152,34153,34115,34121,34157,\n34154,34142,34691,34719,34718,34722,34701,34913,35114,35122,35109,35115,35105,\n35242,35238,35558,35578,35563,35569,35584,35548,35559,35566,35582,35585,35586,\n35575,35565,35571,35574,35580,35947,35949,35987,36084,36420,36401,36404,36418,\n36409,36405,36667,36655,36664,36659,36776,36774,36981,36980,36984,36978,36988,\n36986,37172,37266,37664,37686,37624,37683,37679,37666,\n37628,37675,37636,37658,37648,37670,37665,37653,37678,37657,38331,38567,38568,\n38570,38613,38670,38673,38678,38669,38675,38671,38747,38748,38758,38808,38960,\n38968,38971,38967,38957,38969,38948,39184,39208,39198,39195,39201,39194,39405,\n39394,39409,39608,39612,39675,39661,39720,39825,40213,40227,40230,40232,40210,\n40219,40664,40660,40845,40860,20778,20767,20769,20786,21237,22158,22144,22160,\n22149,22151,22159,22741,22739,22737,22734,23344,23338,23332,23418,23607,23656,\n23996,23994,23997,23992,24171,24396,24509,25033,25026,25031,25062,25035,25138,\n25140,25806,25802,25816,25824,25840,25830,25836,25841,25826,25837,25986,25987,\n26329,26326,27264,27284,27268,27298,27292,27355,27299,27262,27287,27280,27296,\n27484,27566,27610,27656,28632,28657,28639,28640,28635,28644,28651,28655,28544,\n28652,28641,28649,28629,28654,28656,29159,29151,29166,29158,29157,29165,29164,\n29172,29152,29237,29254,29552,29554,29865,29872,29862,29864,30278,30274,30284,\n30442,30643,30634,30640,30636,30631,30637,30703,30967,30970,30964,30959,30977,\n31143,31146,31319,31423,31751,31757,31742,31735,31756,31712,31968,31964,31966,\n31970,31967,31961,31965,32302,32318,32326,32311,32306,32323,32299,32317,32305,\n32325,32321,32308,32313,32328,32309,32319,32303,32580,32755,32764,32881,32882,\n32880,32879,32883,33222,33219,33210,33218,33216,33215,33213,33225,33214,33256,\n33289,33393,34218,34180,34174,34204,34193,34196,34223,34203,34183,34216,34186,\n34407,34752,34769,34739,34770,34758,34731,34747,34746,34760,34763,35131,35126,\n35140,35128,35133,35244,35598,35607,35609,35611,35594,\n35616,35613,35588,35600,35905,35903,35955,36090,36093,36092,36088,36091,36264,\n36425,36427,36424,36426,36676,36670,36674,36677,36671,36991,36989,36996,36993,\n36994,36992,37177,37283,37278,37276,37709,37762,37672,37749,37706,37733,37707,\n37656,37758,37740,37723,37744,37722,37716,38346,38347,38348,38344,38342,38577,\n38584,38614,38684,38686,38816,38867,38982,39094,39221,39425,39423,39854,39851,\n39850,39853,40251,40255,40587,40655,40670,40668,40669,40667,40766,40779,21474,\n22165,22190,22745,22744,23352,24413,25059,25139,25844,25842,25854,25862,25850,\n25851,25847,26039,26332,26406,27315,27308,27331,27323,27320,27330,27310,27311,\n27487,27512,27567,28681,28683,28670,28678,28666,28689,28687,29179,29180,29182,\n29176,29559,29557,29863,29887,29973,30294,30296,30290,30653,30655,30651,30652,\n30990,31150,31329,31330,31328,31428,31429,31787,31783,31786,31774,31779,31777,\n31975,32340,32341,32350,32346,32353,32338,32345,32584,32761,32763,32887,32886,\n33229,33231,33290,34255,34217,34253,34256,34249,34224,34234,34233,34214,34799,\n34796,34802,34784,35206,35250,35316,35624,35641,35628,35627,35920,36101,36441,\n36451,36454,36452,36447,36437,36544,36681,36685,36999,36995,37000,37291,37292,\n37328,37780,37770,37782,37794,37811,37806,37804,37808,37784,37786,37783,38356,\n38358,38352,38357,38626,38620,38617,38619,38622,38692,38819,38822,38829,38905,\n38989,38991,38988,38990,38995,39098,39230,39231,39229,39214,39333,39438,39617,\n39683,39686,39759,39758,39757,39882,39881,39933,39880,39872,40273,40285,40288,\n40672,40725,40748,20787,22181,22750,22751,22754,23541,\n40848,24300,25074,25079,25078,25077,25856,25871,26336,26333,27365,27357,27354,\n27347,28699,28703,28712,28698,28701,28693,28696,29190,29197,29272,29346,29560,\n29562,29885,29898,29923,30087,30086,30303,30305,30663,31001,31153,31339,31337,\n31806,31807,31800,31805,31799,31808,32363,32365,32377,32361,32362,32645,32371,\n32694,32697,32696,33240,34281,34269,34282,34261,34276,34277,34295,34811,34821,\n34829,34809,34814,35168,35167,35158,35166,35649,35676,35672,35657,35674,35662,\n35663,35654,35673,36104,36106,36476,36466,36487,36470,36460,36474,36468,36692,\n36686,36781,37002,37003,37297,37294,37857,37841,37855,37827,37832,37852,37853,\n37846,37858,37837,37848,37860,37847,37864,38364,38580,38627,38698,38695,38753,\n38876,38907,39006,39000,39003,39100,39237,39241,39446,39449,39693,39912,39911,\n39894,39899,40329,40289,40306,40298,40300,40594,40599,40595,40628,21240,22184,\n22199,22198,22196,22204,22756,23360,23363,23421,23542,24009,25080,25082,25880,\n25876,25881,26342,26407,27372,28734,28720,28722,29200,29563,29903,30306,30309,\n31014,31018,31020,31019,31431,31478,31820,31811,31821,31983,31984,36782,32381,\n32380,32386,32588,32768,33242,33382,34299,34297,34321,34298,34310,34315,34311,\n34314,34836,34837,35172,35258,35320,35696,35692,35686,35695,35679,35691,36111,\n36109,36489,36481,36485,36482,37300,37323,37912,37891,37885,38369,38704,39108,\n39250,39249,39336,39467,39472,39479,39477,39955,39949,40569,40629,40680,40751,\n40799,40803,40801,20791,20792,22209,22208,22210,22804,23660,24013,25084,25086,\n25885,25884,26005,26345,27387,27396,27386,27570,28748,\n29211,29351,29910,29908,30313,30675,31824,32399,32396,32700,34327,34349,34330,\n34851,34850,34849,34847,35178,35180,35261,35700,35703,35709,36115,36490,36493,\n36491,36703,36783,37306,37934,37939,37941,37946,37944,37938,37931,38370,38712,\n38713,38706,38911,39015,39013,39255,39493,39491,39488,39486,39631,39764,39761,\n39981,39973,40367,40372,40386,40376,40605,40687,40729,40796,40806,40807,20796,\n20795,22216,22218,22217,23423,24020,24018,24398,25087,25892,27402,27489,28753,\n28760,29568,29924,30090,30318,30316,31155,31840,31839,32894,32893,33247,35186,\n35183,35324,35712,36118,36119,36497,36499,36705,37192,37956,37969,37970,38717,\n38718,38851,38849,39019,39253,39509,39501,39634,39706,40009,39985,39998,39995,\n40403,40407,40756,40812,40810,40852,22220,24022,25088,25891,25899,25898,26348,\n27408,29914,31434,31844,31843,31845,32403,32406,32404,33250,34360,34367,34865,\n35722,37008,37007,37987,37984,37988,38760,39023,39260,39514,39515,39511,39635,\n39636,39633,40020,40023,40022,40421,40607,40692,22225,22761,25900,28766,30321,\n30322,30679,32592,32648,34870,34873,34914,35731,35730,35734,33399,36123,37312,\n37994,38722,38728,38724,38854,39024,39519,39714,39768,40031,40441,40442,40572,\n40573,40711,40823,40818,24307,27414,28771,31852,31854,34875,35264,36513,37313,\n38002,38000,39025,39262,39638,39715,40652,28772,30682,35738,38007,38857,39522,\n39525,32412,35740,36522,37317,38013,38014,38012,40055,40056,40695,35924,38015,\n40474,29224,39530,39729,40475,40478,31858,9312,9313,9314,9315,9316,9317,9318,\n9319,9320,9321,9332,9333,9334,9335,9336,\n9337,9338,9339,9340,9341,8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,\n20022,20031,20101,20128,20866,20886,20907,21241,21304,21353,21430,22794,23424,\n24027,24186,24191,24308,24400,24417,25908,26080,30098,30326,36789,38582,168,\n710,12541,12542,12445,12446,0,0,12293,12294,12295,12540,65339,65341,10045,\n12353,12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,\n12366,12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,\n12379,12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,\n12392,12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,\n12405,12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,\n12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,\n12431,12432,12433,12434,12435,12449,12450,12451,12452,12453,12454,12455,12456,\n12457,12458,12459,12460,12461,12462,12463,12464,12465,12466,12467,12468,12469,\n12470,12471,12472,12473,12474,12475,12476,12477,12478,12479,12480,12481,12482,\n12483,12484,12485,12486,12487,12488,12489,12490,12491,12492,12493,12494,12495,\n12496,12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507,12508,\n12509,12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,\n12522,12523,12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,12534,\n1040,1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,1053,\n1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,\n1069,1070,\n1071,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,1082,1083,1084,\n1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,\n1100,1101,1102,1103,8679,8632,8633,12751,204,20058,138,20994,17553,40880,\n20872,40881,30215,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,65506,65508,65287,65282,12849,8470,8481,12443,12444,11904,\n11908,11910,11911,11912,11914,11916,11917,11925,11932,11933,11941,11943,11946,\n11948,11950,11958,11964,11966,11974,11978,11980,11981,11983,11990,11991,11998,\n12003,0,0,0,643,592,603,596,629,339,248,331,650,618,20034,20060,20981,21274,\n21378,19975,19980,20039,20109,22231,64012,23662,24435,19983,20871,19982,20014,\n20115,20162,20169,20168,20888,21244,21356,21433,22304,22787,22828,23568,24063,\n26081,27571,27596,27668,29247,20017,20028,20200,20188,20201,20193,20189,20186,\n21004,21276,21324,22306,22307,22807,22831,23425,23428,23570,23611,23668,23667,\n24068,24192,24194,24521,25097,25168,27669,27702,27715,27711,27707,29358,29360,\n29578,31160,32906,38430,20238,20248,20268,20213,20244,20209,20224,20215,20232,\n20253,20226,20229,20258,20243,20228,20212,20242,20913,21011,21001,21008,21158,\n21282,21279,21325,21386,21511,22241,22239,22318,22314,22324,22844,22912,22908,\n22917,22907,22910,22903,22911,23382,23573,23589,23676,23674,23675,\n23678,24031,24181,24196,24322,24346,24436,24533,24532,24527,25180,25182,25188,\n25185,25190,25186,25177,25184,25178,25189,26095,26094,26430,26425,26424,26427,\n26426,26431,26428,26419,27672,27718,27730,27740,27727,27722,27732,27723,27724,\n28785,29278,29364,29365,29582,29994,30335,31349,32593,33400,33404,33408,33405,\n33407,34381,35198,37017,37015,37016,37019,37012,38434,38436,38432,38435,20310,\n20283,20322,20297,20307,20324,20286,20327,20306,20319,20289,20312,20269,20275,\n20287,20321,20879,20921,21020,21022,21025,21165,21166,21257,21347,21362,21390,\n21391,21552,21559,21546,21588,21573,21529,21532,21541,21528,21565,21583,21569,\n21544,21540,21575,22254,22247,22245,22337,22341,22348,22345,22347,22354,22790,\n22848,22950,22936,22944,22935,22926,22946,22928,22927,22951,22945,23438,23442,\n23592,23594,23693,23695,23688,23691,23689,23698,23690,23686,23699,23701,24032,\n24074,24078,24203,24201,24204,24200,24205,24325,24349,24440,24438,24530,24529,\n24528,24557,24552,24558,24563,24545,24548,24547,24570,24559,24567,24571,24576,\n24564,25146,25219,25228,25230,25231,25236,25223,25201,25211,25210,25200,25217,\n25224,25207,25213,25202,25204,25911,26096,26100,26099,26098,26101,26437,26439,\n26457,26453,26444,26440,26461,26445,26458,26443,27600,27673,27674,27768,27751,\n27755,27780,27787,27791,27761,27759,27753,27802,27757,27783,27797,27804,27750,\n27763,27749,27771,27790,28788,28794,29283,29375,29373,29379,29382,29377,29370,\n29381,29589,29591,29587,29588,29586,30010,30009,30100,30101,30337,31037,32820,\n32917,32921,32912,32914,32924,33424,33423,33413,33422,\n33425,33427,33418,33411,33412,35960,36809,36799,37023,37025,37029,37022,37031,\n37024,38448,38440,38447,38445,20019,20376,20348,20357,20349,20352,20359,20342,\n20340,20361,20356,20343,20300,20375,20330,20378,20345,20353,20344,20368,20380,\n20372,20382,20370,20354,20373,20331,20334,20894,20924,20926,21045,21042,21043,\n21062,21041,21180,21258,21259,21308,21394,21396,21639,21631,21633,21649,21634,\n21640,21611,21626,21630,21605,21612,21620,21606,21645,21615,21601,21600,21656,\n21603,21607,21604,22263,22265,22383,22386,22381,22379,22385,22384,22390,22400,\n22389,22395,22387,22388,22370,22376,22397,22796,22853,22965,22970,22991,22990,\n22962,22988,22977,22966,22972,22979,22998,22961,22973,22976,22984,22964,22983,\n23394,23397,23443,23445,23620,23623,23726,23716,23712,23733,23727,23720,23724,\n23711,23715,23725,23714,23722,23719,23709,23717,23734,23728,23718,24087,24084,\n24089,24360,24354,24355,24356,24404,24450,24446,24445,24542,24549,24621,24614,\n24601,24626,24587,24628,24586,24599,24627,24602,24606,24620,24610,24589,24592,\n24622,24595,24593,24588,24585,24604,25108,25149,25261,25268,25297,25278,25258,\n25270,25290,25262,25267,25263,25275,25257,25264,25272,25917,26024,26043,26121,\n26108,26116,26130,26120,26107,26115,26123,26125,26117,26109,26129,26128,26358,\n26378,26501,26476,26510,26514,26486,26491,26520,26502,26500,26484,26509,26508,\n26490,26527,26513,26521,26499,26493,26497,26488,26489,26516,27429,27520,27518,\n27614,27677,27795,27884,27883,27886,27865,27830,27860,27821,27879,27831,27856,\n27842,27834,27843,27846,27885,27890,27858,27869,27828,\n27786,27805,27776,27870,27840,27952,27853,27847,27824,27897,27855,27881,27857,\n28820,28824,28805,28819,28806,28804,28817,28822,28802,28826,28803,29290,29398,\n29387,29400,29385,29404,29394,29396,29402,29388,29393,29604,29601,29613,29606,\n29602,29600,29612,29597,29917,29928,30015,30016,30014,30092,30104,30383,30451,\n30449,30448,30453,30712,30716,30713,30715,30714,30711,31042,31039,31173,31352,\n31355,31483,31861,31997,32821,32911,32942,32931,32952,32949,32941,33312,33440,\n33472,33451,33434,33432,33435,33461,33447,33454,33468,33438,33466,33460,33448,\n33441,33449,33474,33444,33475,33462,33442,34416,34415,34413,34414,35926,36818,\n36811,36819,36813,36822,36821,36823,37042,37044,37039,37043,37040,38457,38461,\n38460,38458,38467,20429,20421,20435,20402,20425,20427,20417,20436,20444,20441,\n20411,20403,20443,20423,20438,20410,20416,20409,20460,21060,21065,21184,21186,\n21309,21372,21399,21398,21401,21400,21690,21665,21677,21669,21711,21699,33549,\n21687,21678,21718,21686,21701,21702,21664,21616,21692,21666,21694,21618,21726,\n21680,22453,22430,22431,22436,22412,22423,22429,22427,22420,22424,22415,22425,\n22437,22426,22421,22772,22797,22867,23009,23006,23022,23040,23025,23005,23034,\n23037,23036,23030,23012,23026,23031,23003,23017,23027,23029,23008,23038,23028,\n23021,23464,23628,23760,23768,23756,23767,23755,23771,23774,23770,23753,23751,\n23754,23766,23763,23764,23759,23752,23750,23758,23775,23800,24057,24097,24098,\n24099,24096,24100,24240,24228,24226,24219,24227,24229,24327,24366,24406,24454,\n24631,24633,24660,24690,24670,24645,24659,24647,24649,\n24667,24652,24640,24642,24671,24612,24644,24664,24678,24686,25154,25155,25295,\n25357,25355,25333,25358,25347,25323,25337,25359,25356,25336,25334,25344,25363,\n25364,25338,25365,25339,25328,25921,25923,26026,26047,26166,26145,26162,26165,\n26140,26150,26146,26163,26155,26170,26141,26164,26169,26158,26383,26384,26561,\n26610,26568,26554,26588,26555,26616,26584,26560,26551,26565,26603,26596,26591,\n26549,26573,26547,26615,26614,26606,26595,26562,26553,26574,26599,26608,26546,\n26620,26566,26605,26572,26542,26598,26587,26618,26569,26570,26563,26602,26571,\n27432,27522,27524,27574,27606,27608,27616,27680,27681,27944,27956,27949,27935,\n27964,27967,27922,27914,27866,27955,27908,27929,27962,27930,27921,27904,27933,\n27970,27905,27928,27959,27907,27919,27968,27911,27936,27948,27912,27938,27913,\n27920,28855,28831,28862,28849,28848,28833,28852,28853,28841,29249,29257,29258,\n29292,29296,29299,29294,29386,29412,29416,29419,29407,29418,29414,29411,29573,\n29644,29634,29640,29637,29625,29622,29621,29620,29675,29631,29639,29630,29635,\n29638,29624,29643,29932,29934,29998,30023,30024,30119,30122,30329,30404,30472,\n30467,30468,30469,30474,30455,30459,30458,30695,30696,30726,30737,30738,30725,\n30736,30735,30734,30729,30723,30739,31050,31052,31051,31045,31044,31189,31181,\n31183,31190,31182,31360,31358,31441,31488,31489,31866,31864,31865,31871,31872,\n31873,32003,32008,32001,32600,32657,32653,32702,32775,32782,32783,32788,32823,\n32984,32967,32992,32977,32968,32962,32976,32965,32995,32985,32988,32970,32981,\n32969,32975,32983,32998,32973,33279,33313,33428,33497,\n33534,33529,33543,33512,33536,33493,33594,33515,33494,33524,33516,33505,33522,\n33525,33548,33531,33526,33520,33514,33508,33504,33530,33523,33517,34423,34420,\n34428,34419,34881,34894,34919,34922,34921,35283,35332,35335,36210,36835,36833,\n36846,36832,37105,37053,37055,37077,37061,37054,37063,37067,37064,37332,37331,\n38484,38479,38481,38483,38474,38478,20510,20485,20487,20499,20514,20528,20507,\n20469,20468,20531,20535,20524,20470,20471,20503,20508,20512,20519,20533,20527,\n20529,20494,20826,20884,20883,20938,20932,20933,20936,20942,21089,21082,21074,\n21086,21087,21077,21090,21197,21262,21406,21798,21730,21783,21778,21735,21747,\n21732,21786,21759,21764,21768,21739,21777,21765,21745,21770,21755,21751,21752,\n21728,21774,21763,21771,22273,22274,22476,22578,22485,22482,22458,22470,22461,\n22460,22456,22454,22463,22471,22480,22457,22465,22798,22858,23065,23062,23085,\n23086,23061,23055,23063,23050,23070,23091,23404,23463,23469,23468,23555,23638,\n23636,23788,23807,23790,23793,23799,23808,23801,24105,24104,24232,24238,24234,\n24236,24371,24368,24423,24669,24666,24679,24641,24738,24712,24704,24722,24705,\n24733,24707,24725,24731,24727,24711,24732,24718,25113,25158,25330,25360,25430,\n25388,25412,25413,25398,25411,25572,25401,25419,25418,25404,25385,25409,25396,\n25432,25428,25433,25389,25415,25395,25434,25425,25400,25431,25408,25416,25930,\n25926,26054,26051,26052,26050,26186,26207,26183,26193,26386,26387,26655,26650,\n26697,26674,26675,26683,26699,26703,26646,26673,26652,26677,26667,26669,26671,\n26702,26692,26676,26653,26642,26644,26662,26664,26670,\n26701,26682,26661,26656,27436,27439,27437,27441,27444,27501,32898,27528,27622,\n27620,27624,27619,27618,27623,27685,28026,28003,28004,28022,27917,28001,28050,\n27992,28002,28013,28015,28049,28045,28143,28031,28038,27998,28007,28000,28055,\n28016,28028,27999,28034,28056,27951,28008,28043,28030,28032,28036,27926,28035,\n28027,28029,28021,28048,28892,28883,28881,28893,28875,32569,28898,28887,28882,\n28894,28896,28884,28877,28869,28870,28871,28890,28878,28897,29250,29304,29303,\n29302,29440,29434,29428,29438,29430,29427,29435,29441,29651,29657,29669,29654,\n29628,29671,29667,29673,29660,29650,29659,29652,29661,29658,29655,29656,29672,\n29918,29919,29940,29941,29985,30043,30047,30128,30145,30139,30148,30144,30143,\n30134,30138,30346,30409,30493,30491,30480,30483,30482,30499,30481,30485,30489,\n30490,30498,30503,30755,30764,30754,30773,30767,30760,30766,30763,30753,30761,\n30771,30762,30769,31060,31067,31055,31068,31059,31058,31057,31211,31212,31200,\n31214,31213,31210,31196,31198,31197,31366,31369,31365,31371,31372,31370,31367,\n31448,31504,31492,31507,31493,31503,31496,31498,31502,31497,31506,31876,31889,\n31882,31884,31880,31885,31877,32030,32029,32017,32014,32024,32022,32019,32031,\n32018,32015,32012,32604,32609,32606,32608,32605,32603,32662,32658,32707,32706,\n32704,32790,32830,32825,33018,33010,33017,33013,33025,33019,33024,33281,33327,\n33317,33587,33581,33604,33561,33617,33573,33622,33599,33601,33574,33564,33570,\n33602,33614,33563,33578,33544,33596,33613,33558,33572,33568,33591,33583,33577,\n33607,33605,33612,33619,33566,33580,33611,33575,33608,\n34387,34386,34466,34472,34454,34445,34449,34462,34439,34455,34438,34443,34458,\n34437,34469,34457,34465,34471,34453,34456,34446,34461,34448,34452,34883,34884,\n34925,34933,34934,34930,34944,34929,34943,34927,34947,34942,34932,34940,35346,\n35911,35927,35963,36004,36003,36214,36216,36277,36279,36278,36561,36563,36862,\n36853,36866,36863,36859,36868,36860,36854,37078,37088,37081,37082,37091,37087,\n37093,37080,37083,37079,37084,37092,37200,37198,37199,37333,37346,37338,38492,\n38495,38588,39139,39647,39727,20095,20592,20586,20577,20574,20576,20563,20555,\n20573,20594,20552,20557,20545,20571,20554,20578,20501,20549,20575,20585,20587,\n20579,20580,20550,20544,20590,20595,20567,20561,20944,21099,21101,21100,21102,\n21206,21203,21293,21404,21877,21878,21820,21837,21840,21812,21802,21841,21858,\n21814,21813,21808,21842,21829,21772,21810,21861,21838,21817,21832,21805,21819,\n21824,21835,22282,22279,22523,22548,22498,22518,22492,22516,22528,22509,22525,\n22536,22520,22539,22515,22479,22535,22510,22499,22514,22501,22508,22497,22542,\n22524,22544,22503,22529,22540,22513,22505,22512,22541,22532,22876,23136,23128,\n23125,23143,23134,23096,23093,23149,23120,23135,23141,23148,23123,23140,23127,\n23107,23133,23122,23108,23131,23112,23182,23102,23117,23097,23116,23152,23145,\n23111,23121,23126,23106,23132,23410,23406,23489,23488,23641,23838,23819,23837,\n23834,23840,23820,23848,23821,23846,23845,23823,23856,23826,23843,23839,23854,\n24126,24116,24241,24244,24249,24242,24243,24374,24376,24475,24470,24479,24714,\n24720,24710,24766,24752,24762,24787,24788,24783,24804,\n24793,24797,24776,24753,24795,24759,24778,24767,24771,24781,24768,25394,25445,\n25482,25474,25469,25533,25502,25517,25501,25495,25515,25486,25455,25479,25488,\n25454,25519,25461,25500,25453,25518,25468,25508,25403,25503,25464,25477,25473,\n25489,25485,25456,25939,26061,26213,26209,26203,26201,26204,26210,26392,26745,\n26759,26768,26780,26733,26734,26798,26795,26966,26735,26787,26796,26793,26741,\n26740,26802,26767,26743,26770,26748,26731,26738,26794,26752,26737,26750,26779,\n26774,26763,26784,26761,26788,26744,26747,26769,26764,26762,26749,27446,27443,\n27447,27448,27537,27535,27533,27534,27532,27690,28096,28075,28084,28083,28276,\n28076,28137,28130,28087,28150,28116,28160,28104,28128,28127,28118,28094,28133,\n28124,28125,28123,28148,28106,28093,28141,28144,28090,28117,28098,28111,28105,\n28112,28146,28115,28157,28119,28109,28131,28091,28922,28941,28919,28951,28916,\n28940,28912,28932,28915,28944,28924,28927,28934,28947,28928,28920,28918,28939,\n28930,28942,29310,29307,29308,29311,29469,29463,29447,29457,29464,29450,29448,\n29439,29455,29470,29576,29686,29688,29685,29700,29697,29693,29703,29696,29690,\n29692,29695,29708,29707,29684,29704,30052,30051,30158,30162,30159,30155,30156,\n30161,30160,30351,30345,30419,30521,30511,30509,30513,30514,30516,30515,30525,\n30501,30523,30517,30792,30802,30793,30797,30794,30796,30758,30789,30800,31076,\n31079,31081,31082,31075,31083,31073,31163,31226,31224,31222,31223,31375,31380,\n31376,31541,31559,31540,31525,31536,31522,31524,31539,31512,31530,31517,31537,\n31531,31533,31535,31538,31544,31514,31523,31892,31896,\n31894,31907,32053,32061,32056,32054,32058,32069,32044,32041,32065,32071,32062,\n32063,32074,32059,32040,32611,32661,32668,32669,32667,32714,32715,32717,32720,\n32721,32711,32719,32713,32799,32798,32795,32839,32835,32840,33048,33061,33049,\n33051,33069,33055,33068,33054,33057,33045,33063,33053,33058,33297,33336,33331,\n33338,33332,33330,33396,33680,33699,33704,33677,33658,33651,33700,33652,33679,\n33665,33685,33689,33653,33684,33705,33661,33667,33676,33693,33691,33706,33675,\n33662,33701,33711,33672,33687,33712,33663,33702,33671,33710,33654,33690,34393,\n34390,34495,34487,34498,34497,34501,34490,34480,34504,34489,34483,34488,34508,\n34484,34491,34492,34499,34493,34494,34898,34953,34965,34984,34978,34986,34970,\n34961,34977,34975,34968,34983,34969,34971,34967,34980,34988,34956,34963,34958,\n35202,35286,35289,35285,35376,35367,35372,35358,35897,35899,35932,35933,35965,\n36005,36221,36219,36217,36284,36290,36281,36287,36289,36568,36574,36573,36572,\n36567,36576,36577,36900,36875,36881,36892,36876,36897,37103,37098,37104,37108,\n37106,37107,37076,37099,37100,37097,37206,37208,37210,37203,37205,37356,37364,\n37361,37363,37368,37348,37369,37354,37355,37367,37352,37358,38266,38278,38280,\n38524,38509,38507,38513,38511,38591,38762,38916,39141,39319,20635,20629,20628,\n20638,20619,20643,20611,20620,20622,20637,20584,20636,20626,20610,20615,20831,\n20948,21266,21265,21412,21415,21905,21928,21925,21933,21879,22085,21922,21907,\n21896,21903,21941,21889,21923,21906,21924,21885,21900,21926,21887,21909,21921,\n21902,22284,22569,22583,22553,22558,22567,22563,22568,\n22517,22600,22565,22556,22555,22579,22591,22582,22574,22585,22584,22573,22572,\n22587,22881,23215,23188,23199,23162,23202,23198,23160,23206,23164,23205,23212,\n23189,23214,23095,23172,23178,23191,23171,23179,23209,23163,23165,23180,23196,\n23183,23187,23197,23530,23501,23499,23508,23505,23498,23502,23564,23600,23863,\n23875,23915,23873,23883,23871,23861,23889,23886,23893,23859,23866,23890,23869,\n23857,23897,23874,23865,23881,23864,23868,23858,23862,23872,23877,24132,24129,\n24408,24486,24485,24491,24777,24761,24780,24802,24782,24772,24852,24818,24842,\n24854,24837,24821,24851,24824,24828,24830,24769,24835,24856,24861,24848,24831,\n24836,24843,25162,25492,25521,25520,25550,25573,25576,25583,25539,25757,25587,\n25546,25568,25590,25557,25586,25589,25697,25567,25534,25565,25564,25540,25560,\n25555,25538,25543,25548,25547,25544,25584,25559,25561,25906,25959,25962,25956,\n25948,25960,25957,25996,26013,26014,26030,26064,26066,26236,26220,26235,26240,\n26225,26233,26218,26226,26369,26892,26835,26884,26844,26922,26860,26858,26865,\n26895,26838,26871,26859,26852,26870,26899,26896,26867,26849,26887,26828,26888,\n26992,26804,26897,26863,26822,26900,26872,26832,26877,26876,26856,26891,26890,\n26903,26830,26824,26845,26846,26854,26868,26833,26886,26836,26857,26901,26917,\n26823,27449,27451,27455,27452,27540,27543,27545,27541,27581,27632,27634,27635,\n27696,28156,28230,28231,28191,28233,28296,28220,28221,28229,28258,28203,28223,\n28225,28253,28275,28188,28211,28235,28224,28241,28219,28163,28206,28254,28264,\n28252,28257,28209,28200,28256,28273,28267,28217,28194,\n28208,28243,28261,28199,28280,28260,28279,28245,28281,28242,28262,28213,28214,\n28250,28960,28958,28975,28923,28974,28977,28963,28965,28962,28978,28959,28968,\n28986,28955,29259,29274,29320,29321,29318,29317,29323,29458,29451,29488,29474,\n29489,29491,29479,29490,29485,29478,29475,29493,29452,29742,29740,29744,29739,\n29718,29722,29729,29741,29745,29732,29731,29725,29737,29728,29746,29947,29999,\n30063,30060,30183,30170,30177,30182,30173,30175,30180,30167,30357,30354,30426,\n30534,30535,30532,30541,30533,30538,30542,30539,30540,30686,30700,30816,30820,\n30821,30812,30829,30833,30826,30830,30832,30825,30824,30814,30818,31092,31091,\n31090,31088,31234,31242,31235,31244,31236,31385,31462,31460,31562,31547,31556,\n31560,31564,31566,31552,31576,31557,31906,31902,31912,31905,32088,32111,32099,\n32083,32086,32103,32106,32079,32109,32092,32107,32082,32084,32105,32081,32095,\n32078,32574,32575,32613,32614,32674,32672,32673,32727,32849,32847,32848,33022,\n32980,33091,33098,33106,33103,33095,33085,33101,33082,33254,33262,33271,33272,\n33273,33284,33340,33341,33343,33397,33595,33743,33785,33827,33728,33768,33810,\n33767,33764,33788,33782,33808,33734,33736,33771,33763,33727,33793,33757,33765,\n33752,33791,33761,33739,33742,33750,33781,33737,33801,33807,33758,33809,33798,\n33730,33779,33749,33786,33735,33745,33770,33811,33731,33772,33774,33732,33787,\n33751,33762,33819,33755,33790,34520,34530,34534,34515,34531,34522,34538,34525,\n34539,34524,34540,34537,34519,34536,34513,34888,34902,34901,35002,35031,35001,\n35000,35008,35006,34998,35004,34999,35005,34994,35073,\n35017,35221,35224,35223,35293,35290,35291,35406,35405,35385,35417,35392,35415,\n35416,35396,35397,35410,35400,35409,35402,35404,35407,35935,35969,35968,36026,\n36030,36016,36025,36021,36228,36224,36233,36312,36307,36301,36295,36310,36316,\n36303,36309,36313,36296,36311,36293,36591,36599,36602,36601,36582,36590,36581,\n36597,36583,36584,36598,36587,36593,36588,36596,36585,36909,36916,36911,37126,\n37164,37124,37119,37116,37128,37113,37115,37121,37120,37127,37125,37123,37217,\n37220,37215,37218,37216,37377,37386,37413,37379,37402,37414,37391,37388,37376,\n37394,37375,37373,37382,37380,37415,37378,37404,37412,37401,37399,37381,37398,\n38267,38285,38284,38288,38535,38526,38536,38537,38531,38528,38594,38600,38595,\n38641,38640,38764,38768,38766,38919,39081,39147,40166,40697,20099,20100,20150,\n20669,20671,20678,20654,20676,20682,20660,20680,20674,20656,20673,20666,20657,\n20683,20681,20662,20664,20951,21114,21112,21115,21116,21955,21979,21964,21968,\n21963,21962,21981,21952,21972,21956,21993,21951,21970,21901,21967,21973,21986,\n21974,21960,22002,21965,21977,21954,22292,22611,22632,22628,22607,22605,22601,\n22639,22613,22606,22621,22617,22629,22619,22589,22627,22641,22780,23239,23236,\n23243,23226,23224,23217,23221,23216,23231,23240,23227,23238,23223,23232,23242,\n23220,23222,23245,23225,23184,23510,23512,23513,23583,23603,23921,23907,23882,\n23909,23922,23916,23902,23912,23911,23906,24048,24143,24142,24138,24141,24139,\n24261,24268,24262,24267,24263,24384,24495,24493,24823,24905,24906,24875,24901,\n24886,24882,24878,24902,24879,24911,24873,24896,25120,\n37224,25123,25125,25124,25541,25585,25579,25616,25618,25609,25632,25636,25651,\n25667,25631,25621,25624,25657,25655,25634,25635,25612,25638,25648,25640,25665,\n25653,25647,25610,25626,25664,25637,25639,25611,25575,25627,25646,25633,25614,\n25967,26002,26067,26246,26252,26261,26256,26251,26250,26265,26260,26232,26400,\n26982,26975,26936,26958,26978,26993,26943,26949,26986,26937,26946,26967,26969,\n27002,26952,26953,26933,26988,26931,26941,26981,26864,27000,26932,26985,26944,\n26991,26948,26998,26968,26945,26996,26956,26939,26955,26935,26972,26959,26961,\n26930,26962,26927,27003,26940,27462,27461,27459,27458,27464,27457,27547,64013,\n27643,27644,27641,27639,27640,28315,28374,28360,28303,28352,28319,28307,28308,\n28320,28337,28345,28358,28370,28349,28353,28318,28361,28343,28336,28365,28326,\n28367,28338,28350,28355,28380,28376,28313,28306,28302,28301,28324,28321,28351,\n28339,28368,28362,28311,28334,28323,28999,29012,29010,29027,29024,28993,29021,\n29026,29042,29048,29034,29025,28994,29016,28995,29003,29040,29023,29008,29011,\n28996,29005,29018,29263,29325,29324,29329,29328,29326,29500,29506,29499,29498,\n29504,29514,29513,29764,29770,29771,29778,29777,29783,29760,29775,29776,29774,\n29762,29766,29773,29780,29921,29951,29950,29949,29981,30073,30071,27011,30191,\n30223,30211,30199,30206,30204,30201,30200,30224,30203,30198,30189,30197,30205,\n30361,30389,30429,30549,30559,30560,30546,30550,30554,30569,30567,30548,30553,\n30573,30688,30855,30874,30868,30863,30852,30869,30853,30854,30881,30851,30841,\n30873,30848,30870,30843,31100,31106,31101,31097,31249,\n31256,31257,31250,31255,31253,31266,31251,31259,31248,31395,31394,31390,31467,\n31590,31588,31597,31604,31593,31602,31589,31603,31601,31600,31585,31608,31606,\n31587,31922,31924,31919,32136,32134,32128,32141,32127,32133,32122,32142,32123,\n32131,32124,32140,32148,32132,32125,32146,32621,32619,32615,32616,32620,32678,\n32677,32679,32731,32732,32801,33124,33120,33143,33116,33129,33115,33122,33138,\n26401,33118,33142,33127,33135,33092,33121,33309,33353,33348,33344,33346,33349,\n34033,33855,33878,33910,33913,33935,33933,33893,33873,33856,33926,33895,33840,\n33869,33917,33882,33881,33908,33907,33885,34055,33886,33847,33850,33844,33914,\n33859,33912,33842,33861,33833,33753,33867,33839,33858,33837,33887,33904,33849,\n33870,33868,33874,33903,33989,33934,33851,33863,33846,33843,33896,33918,33860,\n33835,33888,33876,33902,33872,34571,34564,34551,34572,34554,34518,34549,34637,\n34552,34574,34569,34561,34550,34573,34565,35030,35019,35021,35022,35038,35035,\n35034,35020,35024,35205,35227,35295,35301,35300,35297,35296,35298,35292,35302,\n35446,35462,35455,35425,35391,35447,35458,35460,35445,35459,35457,35444,35450,\n35900,35915,35914,35941,35940,35942,35974,35972,35973,36044,36200,36201,36241,\n36236,36238,36239,36237,36243,36244,36240,36242,36336,36320,36332,36337,36334,\n36304,36329,36323,36322,36327,36338,36331,36340,36614,36607,36609,36608,36613,\n36615,36616,36610,36619,36946,36927,36932,36937,36925,37136,37133,37135,37137,\n37142,37140,37131,37134,37230,37231,37448,37458,37424,37434,37478,37427,37477,\n37470,37507,37422,37450,37446,37485,37484,37455,37472,\n37479,37487,37430,37473,37488,37425,37460,37475,37456,37490,37454,37459,37452,\n37462,37426,38303,38300,38302,38299,38546,38547,38545,38551,38606,38650,38653,\n38648,38645,38771,38775,38776,38770,38927,38925,38926,39084,39158,39161,39343,\n39346,39344,39349,39597,39595,39771,40170,40173,40167,40576,40701,20710,20692,\n20695,20712,20723,20699,20714,20701,20708,20691,20716,20720,20719,20707,20704,\n20952,21120,21121,21225,21227,21296,21420,22055,22037,22028,22034,22012,22031,\n22044,22017,22035,22018,22010,22045,22020,22015,22009,22665,22652,22672,22680,\n22662,22657,22655,22644,22667,22650,22663,22673,22670,22646,22658,22664,22651,\n22676,22671,22782,22891,23260,23278,23269,23253,23274,23258,23277,23275,23283,\n23266,23264,23259,23276,23262,23261,23257,23272,23263,23415,23520,23523,23651,\n23938,23936,23933,23942,23930,23937,23927,23946,23945,23944,23934,23932,23949,\n23929,23935,24152,24153,24147,24280,24273,24279,24270,24284,24277,24281,24274,\n24276,24388,24387,24431,24502,24876,24872,24897,24926,24945,24947,24914,24915,\n24946,24940,24960,24948,24916,24954,24923,24933,24891,24938,24929,24918,25129,\n25127,25131,25643,25677,25691,25693,25716,25718,25714,25715,25725,25717,25702,\n25766,25678,25730,25694,25692,25675,25683,25696,25680,25727,25663,25708,25707,\n25689,25701,25719,25971,26016,26273,26272,26271,26373,26372,26402,27057,27062,\n27081,27040,27086,27030,27056,27052,27068,27025,27033,27022,27047,27021,27049,\n27070,27055,27071,27076,27069,27044,27092,27065,27082,27034,27087,27059,27027,\n27050,27041,27038,27097,27031,27024,27074,27061,27045,\n27078,27466,27469,27467,27550,27551,27552,27587,27588,27646,28366,28405,28401,\n28419,28453,28408,28471,28411,28462,28425,28494,28441,28442,28455,28440,28475,\n28434,28397,28426,28470,28531,28409,28398,28461,28480,28464,28476,28469,28395,\n28423,28430,28483,28421,28413,28406,28473,28444,28412,28474,28447,28429,28446,\n28424,28449,29063,29072,29065,29056,29061,29058,29071,29051,29062,29057,29079,\n29252,29267,29335,29333,29331,29507,29517,29521,29516,29794,29811,29809,29813,\n29810,29799,29806,29952,29954,29955,30077,30096,30230,30216,30220,30229,30225,\n30218,30228,30392,30593,30588,30597,30594,30574,30592,30575,30590,30595,30898,\n30890,30900,30893,30888,30846,30891,30878,30885,30880,30892,30882,30884,31128,\n31114,31115,31126,31125,31124,31123,31127,31112,31122,31120,31275,31306,31280,\n31279,31272,31270,31400,31403,31404,31470,31624,31644,31626,31633,31632,31638,\n31629,31628,31643,31630,31621,31640,21124,31641,31652,31618,31931,31935,31932,\n31930,32167,32183,32194,32163,32170,32193,32192,32197,32157,32206,32196,32198,\n32203,32204,32175,32185,32150,32188,32159,32166,32174,32169,32161,32201,32627,\n32738,32739,32741,32734,32804,32861,32860,33161,33158,33155,33159,33165,33164,\n33163,33301,33943,33956,33953,33951,33978,33998,33986,33964,33966,33963,33977,\n33972,33985,33997,33962,33946,33969,34000,33949,33959,33979,33954,33940,33991,\n33996,33947,33961,33967,33960,34006,33944,33974,33999,33952,34007,34004,34002,\n34011,33968,33937,34401,34611,34595,34600,34667,34624,34606,34590,34593,34585,\n34587,34627,34604,34625,34622,34630,34592,34610,34602,\n34605,34620,34578,34618,34609,34613,34626,34598,34599,34616,34596,34586,34608,\n34577,35063,35047,35057,35058,35066,35070,35054,35068,35062,35067,35056,35052,\n35051,35229,35233,35231,35230,35305,35307,35304,35499,35481,35467,35474,35471,\n35478,35901,35944,35945,36053,36047,36055,36246,36361,36354,36351,36365,36349,\n36362,36355,36359,36358,36357,36350,36352,36356,36624,36625,36622,36621,37155,\n37148,37152,37154,37151,37149,37146,37156,37153,37147,37242,37234,37241,37235,\n37541,37540,37494,37531,37498,37536,37524,37546,37517,37542,37530,37547,37497,\n37527,37503,37539,37614,37518,37506,37525,37538,37501,37512,37537,37514,37510,\n37516,37529,37543,37502,37511,37545,37533,37515,37421,38558,38561,38655,38744,\n38781,38778,38782,38787,38784,38786,38779,38788,38785,38783,38862,38861,38934,\n39085,39086,39170,39168,39175,39325,39324,39363,39353,39355,39354,39362,39357,\n39367,39601,39651,39655,39742,39743,39776,39777,39775,40177,40178,40181,40615,\n20735,20739,20784,20728,20742,20743,20726,20734,20747,20748,20733,20746,21131,\n21132,21233,21231,22088,22082,22092,22069,22081,22090,22089,22086,22104,22106,\n22080,22067,22077,22060,22078,22072,22058,22074,22298,22699,22685,22705,22688,\n22691,22703,22700,22693,22689,22783,23295,23284,23293,23287,23286,23299,23288,\n23298,23289,23297,23303,23301,23311,23655,23961,23959,23967,23954,23970,23955,\n23957,23968,23964,23969,23962,23966,24169,24157,24160,24156,32243,24283,24286,\n24289,24393,24498,24971,24963,24953,25009,25008,24994,24969,24987,24979,25007,\n25005,24991,24978,25002,24993,24973,24934,25011,25133,\n25710,25712,25750,25760,25733,25751,25756,25743,25739,25738,25740,25763,25759,\n25704,25777,25752,25974,25978,25977,25979,26034,26035,26293,26288,26281,26290,\n26295,26282,26287,27136,27142,27159,27109,27128,27157,27121,27108,27168,27135,\n27116,27106,27163,27165,27134,27175,27122,27118,27156,27127,27111,27200,27144,\n27110,27131,27149,27132,27115,27145,27140,27160,27173,27151,27126,27174,27143,\n27124,27158,27473,27557,27555,27554,27558,27649,27648,27647,27650,28481,28454,\n28542,28551,28614,28562,28557,28553,28556,28514,28495,28549,28506,28566,28534,\n28524,28546,28501,28530,28498,28496,28503,28564,28563,28509,28416,28513,28523,\n28541,28519,28560,28499,28555,28521,28543,28565,28515,28535,28522,28539,29106,\n29103,29083,29104,29088,29082,29097,29109,29085,29093,29086,29092,29089,29098,\n29084,29095,29107,29336,29338,29528,29522,29534,29535,29536,29533,29531,29537,\n29530,29529,29538,29831,29833,29834,29830,29825,29821,29829,29832,29820,29817,\n29960,29959,30078,30245,30238,30233,30237,30236,30243,30234,30248,30235,30364,\n30365,30366,30363,30605,30607,30601,30600,30925,30907,30927,30924,30929,30926,\n30932,30920,30915,30916,30921,31130,31137,31136,31132,31138,31131,27510,31289,\n31410,31412,31411,31671,31691,31678,31660,31694,31663,31673,31690,31669,31941,\n31944,31948,31947,32247,32219,32234,32231,32215,32225,32259,32250,32230,32246,\n32241,32240,32238,32223,32630,32684,32688,32685,32749,32747,32746,32748,32742,\n32744,32868,32871,33187,33183,33182,33173,33186,33177,33175,33302,33359,33363,\n33362,33360,33358,33361,34084,34107,34063,34048,34089,\n34062,34057,34061,34079,34058,34087,34076,34043,34091,34042,34056,34060,34036,\n34090,34034,34069,34039,34027,34035,34044,34066,34026,34025,34070,34046,34088,\n34077,34094,34050,34045,34078,34038,34097,34086,34023,34024,34032,34031,34041,\n34072,34080,34096,34059,34073,34095,34402,34646,34659,34660,34679,34785,34675,\n34648,34644,34651,34642,34657,34650,34641,34654,34669,34666,34640,34638,34655,\n34653,34671,34668,34682,34670,34652,34661,34639,34683,34677,34658,34663,34665,\n34906,35077,35084,35092,35083,35095,35096,35097,35078,35094,35089,35086,35081,\n35234,35236,35235,35309,35312,35308,35535,35526,35512,35539,35537,35540,35541,\n35515,35543,35518,35520,35525,35544,35523,35514,35517,35545,35902,35917,35983,\n36069,36063,36057,36072,36058,36061,36071,36256,36252,36257,36251,36384,36387,\n36389,36388,36398,36373,36379,36374,36369,36377,36390,36391,36372,36370,36376,\n36371,36380,36375,36378,36652,36644,36632,36634,36640,36643,36630,36631,36979,\n36976,36975,36967,36971,37167,37163,37161,37162,37170,37158,37166,37253,37254,\n37258,37249,37250,37252,37248,37584,37571,37572,37568,37593,37558,37583,37617,\n37599,37592,37609,37591,37597,37580,37615,37570,37608,37578,37576,37582,37606,\n37581,37589,37577,37600,37598,37607,37585,37587,37557,37601,37574,37556,38268,\n38316,38315,38318,38320,38564,38562,38611,38661,38664,38658,38746,38794,38798,\n38792,38864,38863,38942,38941,38950,38953,38952,38944,38939,38951,39090,39176,\n39162,39185,39188,39190,39191,39189,39388,39373,39375,39379,39380,39374,39369,\n39382,39384,39371,39383,39372,39603,39660,39659,39667,\n39666,39665,39750,39747,39783,39796,39793,39782,39798,39797,39792,39784,39780,\n39788,40188,40186,40189,40191,40183,40199,40192,40185,40187,40200,40197,40196,\n40579,40659,40719,40720,20764,20755,20759,20762,20753,20958,21300,21473,22128,\n22112,22126,22131,22118,22115,22125,22130,22110,22135,22300,22299,22728,22717,\n22729,22719,22714,22722,22716,22726,23319,23321,23323,23329,23316,23315,23312,\n23318,23336,23322,23328,23326,23535,23980,23985,23977,23975,23989,23984,23982,\n23978,23976,23986,23981,23983,23988,24167,24168,24166,24175,24297,24295,24294,\n24296,24293,24395,24508,24989,25000,24982,25029,25012,25030,25025,25036,25018,\n25023,25016,24972,25815,25814,25808,25807,25801,25789,25737,25795,25819,25843,\n25817,25907,25983,25980,26018,26312,26302,26304,26314,26315,26319,26301,26299,\n26298,26316,26403,27188,27238,27209,27239,27186,27240,27198,27229,27245,27254,\n27227,27217,27176,27226,27195,27199,27201,27242,27236,27216,27215,27220,27247,\n27241,27232,27196,27230,27222,27221,27213,27214,27206,27477,27476,27478,27559,\n27562,27563,27592,27591,27652,27651,27654,28589,28619,28579,28615,28604,28622,\n28616,28510,28612,28605,28574,28618,28584,28676,28581,28590,28602,28588,28586,\n28623,28607,28600,28578,28617,28587,28621,28591,28594,28592,29125,29122,29119,\n29112,29142,29120,29121,29131,29140,29130,29127,29135,29117,29144,29116,29126,\n29146,29147,29341,29342,29545,29542,29543,29548,29541,29547,29546,29823,29850,\n29856,29844,29842,29845,29857,29963,30080,30255,30253,30257,30269,30259,30268,\n30261,30258,30256,30395,30438,30618,30621,30625,30620,\n30619,30626,30627,30613,30617,30615,30941,30953,30949,30954,30942,30947,30939,\n30945,30946,30957,30943,30944,31140,31300,31304,31303,31414,31416,31413,31409,\n31415,31710,31715,31719,31709,31701,31717,31706,31720,31737,31700,31722,31714,\n31708,31723,31704,31711,31954,31956,31959,31952,31953,32274,32289,32279,32268,\n32287,32288,32275,32270,32284,32277,32282,32290,32267,32271,32278,32269,32276,\n32293,32292,32579,32635,32636,32634,32689,32751,32810,32809,32876,33201,33190,\n33198,33209,33205,33195,33200,33196,33204,33202,33207,33191,33266,33365,33366,\n33367,34134,34117,34155,34125,34131,34145,34136,34112,34118,34148,34113,34146,\n34116,34129,34119,34147,34110,34139,34161,34126,34158,34165,34133,34151,34144,\n34188,34150,34141,34132,34149,34156,34403,34405,34404,34715,34703,34711,34707,\n34706,34696,34689,34710,34712,34681,34695,34723,34693,34704,34705,34717,34692,\n34708,34716,34714,34697,35102,35110,35120,35117,35118,35111,35121,35106,35113,\n35107,35119,35116,35103,35313,35552,35554,35570,35572,35573,35549,35604,35556,\n35551,35568,35528,35550,35553,35560,35583,35567,35579,35985,35986,35984,36085,\n36078,36081,36080,36083,36204,36206,36261,36263,36403,36414,36408,36416,36421,\n36406,36412,36413,36417,36400,36415,36541,36662,36654,36661,36658,36665,36663,\n36660,36982,36985,36987,36998,37114,37171,37173,37174,37267,37264,37265,37261,\n37263,37671,37662,37640,37663,37638,37647,37754,37688,37692,37659,37667,37650,\n37633,37702,37677,37646,37645,37579,37661,37626,37669,37651,37625,37623,37684,\n37634,37668,37631,37673,37689,37685,37674,37652,37644,\n37643,37630,37641,37632,37627,37654,38332,38349,38334,38329,38330,38326,38335,\n38325,38333,38569,38612,38667,38674,38672,38809,38807,38804,38896,38904,38965,\n38959,38962,39204,39199,39207,39209,39326,39406,39404,39397,39396,39408,39395,\n39402,39401,39399,39609,39615,39604,39611,39670,39674,39673,39671,39731,39808,\n39813,39815,39804,39806,39803,39810,39827,39826,39824,39802,39829,39805,39816,\n40229,40215,40224,40222,40212,40233,40221,40216,40226,40208,40217,40223,40584,\n40582,40583,40622,40621,40661,40662,40698,40722,40765,20774,20773,20770,20772,\n20768,20777,21236,22163,22156,22157,22150,22148,22147,22142,22146,22143,22145,\n22742,22740,22735,22738,23341,23333,23346,23331,23340,23335,23334,23343,23342,\n23419,23537,23538,23991,24172,24170,24510,24507,25027,25013,25020,25063,25056,\n25061,25060,25064,25054,25839,25833,25827,25835,25828,25832,25985,25984,26038,\n26074,26322,27277,27286,27265,27301,27273,27295,27291,27297,27294,27271,27283,\n27278,27285,27267,27304,27300,27281,27263,27302,27290,27269,27276,27282,27483,\n27565,27657,28620,28585,28660,28628,28643,28636,28653,28647,28646,28638,28658,\n28637,28642,28648,29153,29169,29160,29170,29156,29168,29154,29555,29550,29551,\n29847,29874,29867,29840,29866,29869,29873,29861,29871,29968,29969,29970,29967,\n30084,30275,30280,30281,30279,30372,30441,30645,30635,30642,30647,30646,30644,\n30641,30632,30704,30963,30973,30978,30971,30972,30962,30981,30969,30974,30980,\n31147,31144,31324,31323,31318,31320,31316,31322,31422,31424,31425,31749,31759,\n31730,31744,31743,31739,31758,31732,31755,31731,31746,\n31753,31747,31745,31736,31741,31750,31728,31729,31760,31754,31976,32301,32316,\n32322,32307,38984,32312,32298,32329,32320,32327,32297,32332,32304,32315,32310,\n32324,32314,32581,32639,32638,32637,32756,32754,32812,33211,33220,33228,33226,\n33221,33223,33212,33257,33371,33370,33372,34179,34176,34191,34215,34197,34208,\n34187,34211,34171,34212,34202,34206,34167,34172,34185,34209,34170,34168,34135,\n34190,34198,34182,34189,34201,34205,34177,34210,34178,34184,34181,34169,34166,\n34200,34192,34207,34408,34750,34730,34733,34757,34736,34732,34745,34741,34748,\n34734,34761,34755,34754,34764,34743,34735,34756,34762,34740,34742,34751,34744,\n34749,34782,34738,35125,35123,35132,35134,35137,35154,35127,35138,35245,35247,\n35246,35314,35315,35614,35608,35606,35601,35589,35595,35618,35599,35602,35605,\n35591,35597,35592,35590,35612,35603,35610,35919,35952,35954,35953,35951,35989,\n35988,36089,36207,36430,36429,36435,36432,36428,36423,36675,36672,36997,36990,\n37176,37274,37282,37275,37273,37279,37281,37277,37280,37793,37763,37807,37732,\n37718,37703,37756,37720,37724,37750,37705,37712,37713,37728,37741,37775,37708,\n37738,37753,37719,37717,37714,37711,37745,37751,37755,37729,37726,37731,37735,\n37760,37710,37721,38343,38336,38345,38339,38341,38327,38574,38576,38572,38688,\n38687,38680,38685,38681,38810,38817,38812,38814,38813,38869,38868,38897,38977,\n38980,38986,38985,38981,38979,39205,39211,39212,39210,39219,39218,39215,39213,\n39217,39216,39320,39331,39329,39426,39418,39412,39415,39417,39416,39414,39419,\n39421,39422,39420,39427,39614,39678,39677,39681,39676,\n39752,39834,39848,39838,39835,39846,39841,39845,39844,39814,39842,39840,39855,\n40243,40257,40295,40246,40238,40239,40241,40248,40240,40261,40258,40259,40254,\n40247,40256,40253,32757,40237,40586,40585,40589,40624,40648,40666,40699,40703,\n40740,40739,40738,40788,40864,20785,20781,20782,22168,22172,22167,22170,22173,\n22169,22896,23356,23657,23658,24000,24173,24174,25048,25055,25069,25070,25073,\n25066,25072,25067,25046,25065,25855,25860,25853,25848,25857,25859,25852,26004,\n26075,26330,26331,26328,27333,27321,27325,27361,27334,27322,27318,27319,27335,\n27316,27309,27486,27593,27659,28679,28684,28685,28673,28677,28692,28686,28671,\n28672,28667,28710,28668,28663,28682,29185,29183,29177,29187,29181,29558,29880,\n29888,29877,29889,29886,29878,29883,29890,29972,29971,30300,30308,30297,30288,\n30291,30295,30298,30374,30397,30444,30658,30650,30975,30988,30995,30996,30985,\n30992,30994,30993,31149,31148,31327,31772,31785,31769,31776,31775,31789,31773,\n31782,31784,31778,31781,31792,32348,32336,32342,32355,32344,32354,32351,32337,\n32352,32343,32339,32693,32691,32759,32760,32885,33233,33234,33232,33375,33374,\n34228,34246,34240,34243,34242,34227,34229,34237,34247,34244,34239,34251,34254,\n34248,34245,34225,34230,34258,34340,34232,34231,34238,34409,34791,34790,34786,\n34779,34795,34794,34789,34783,34803,34788,34772,34780,34771,34797,34776,34787,\n34724,34775,34777,34817,34804,34792,34781,35155,35147,35151,35148,35142,35152,\n35153,35145,35626,35623,35619,35635,35632,35637,35655,35631,35644,35646,35633,\n35621,35639,35622,35638,35630,35620,35643,35645,35642,\n35906,35957,35993,35992,35991,36094,36100,36098,36096,36444,36450,36448,36439,\n36438,36446,36453,36455,36443,36442,36449,36445,36457,36436,36678,36679,36680,\n36683,37160,37178,37179,37182,37288,37285,37287,37295,37290,37813,37772,37778,\n37815,37787,37789,37769,37799,37774,37802,37790,37798,37781,37768,37785,37791,\n37773,37809,37777,37810,37796,37800,37812,37795,37797,38354,38355,38353,38579,\n38615,38618,24002,38623,38616,38621,38691,38690,38693,38828,38830,38824,38827,\n38820,38826,38818,38821,38871,38873,38870,38872,38906,38992,38993,38994,39096,\n39233,39228,39226,39439,39435,39433,39437,39428,39441,39434,39429,39431,39430,\n39616,39644,39688,39684,39685,39721,39733,39754,39756,39755,39879,39878,39875,\n39871,39873,39861,39864,39891,39862,39876,39865,39869,40284,40275,40271,40266,\n40283,40267,40281,40278,40268,40279,40274,40276,40287,40280,40282,40590,40588,\n40671,40705,40704,40726,40741,40747,40746,40745,40744,40780,40789,20788,20789,\n21142,21239,21428,22187,22189,22182,22183,22186,22188,22746,22749,22747,22802,\n23357,23358,23359,24003,24176,24511,25083,25863,25872,25869,25865,25868,25870,\n25988,26078,26077,26334,27367,27360,27340,27345,27353,27339,27359,27356,27344,\n27371,27343,27341,27358,27488,27568,27660,28697,28711,28704,28694,28715,28705,\n28706,28707,28713,28695,28708,28700,28714,29196,29194,29191,29186,29189,29349,\n29350,29348,29347,29345,29899,29893,29879,29891,29974,30304,30665,30666,30660,\n30705,31005,31003,31009,31004,30999,31006,31152,31335,31336,31795,31804,31801,\n31788,31803,31980,31978,32374,32373,32376,32368,32375,\n32367,32378,32370,32372,32360,32587,32586,32643,32646,32695,32765,32766,32888,\n33239,33237,33380,33377,33379,34283,34289,34285,34265,34273,34280,34266,34263,\n34284,34290,34296,34264,34271,34275,34268,34257,34288,34278,34287,34270,34274,\n34816,34810,34819,34806,34807,34825,34828,34827,34822,34812,34824,34815,34826,\n34818,35170,35162,35163,35159,35169,35164,35160,35165,35161,35208,35255,35254,\n35318,35664,35656,35658,35648,35667,35670,35668,35659,35669,35665,35650,35666,\n35671,35907,35959,35958,35994,36102,36103,36105,36268,36266,36269,36267,36461,\n36472,36467,36458,36463,36475,36546,36690,36689,36687,36688,36691,36788,37184,\n37183,37296,37293,37854,37831,37839,37826,37850,37840,37881,37868,37836,37849,\n37801,37862,37834,37844,37870,37859,37845,37828,37838,37824,37842,37863,38269,\n38362,38363,38625,38697,38699,38700,38696,38694,38835,38839,38838,38877,38878,\n38879,39004,39001,39005,38999,39103,39101,39099,39102,39240,39239,39235,39334,\n39335,39450,39445,39461,39453,39460,39451,39458,39456,39463,39459,39454,39452,\n39444,39618,39691,39690,39694,39692,39735,39914,39915,39904,39902,39908,39910,\n39906,39920,39892,39895,39916,39900,39897,39909,39893,39905,39898,40311,40321,\n40330,40324,40328,40305,40320,40312,40326,40331,40332,40317,40299,40308,40309,\n40304,40297,40325,40307,40315,40322,40303,40313,40319,40327,40296,40596,40593,\n40640,40700,40749,40768,40769,40781,40790,40791,40792,21303,22194,22197,22195,\n22755,23365,24006,24007,24302,24303,24512,24513,25081,25879,25878,25877,25875,\n26079,26344,26339,26340,27379,27376,27370,27368,27385,\n27377,27374,27375,28732,28725,28719,28727,28724,28721,28738,28728,28735,28730,\n28729,28736,28731,28723,28737,29203,29204,29352,29565,29564,29882,30379,30378,\n30398,30445,30668,30670,30671,30669,30706,31013,31011,31015,31016,31012,31017,\n31154,31342,31340,31341,31479,31817,31816,31818,31815,31813,31982,32379,32382,\n32385,32384,32698,32767,32889,33243,33241,33291,33384,33385,34338,34303,34305,\n34302,34331,34304,34294,34308,34313,34309,34316,34301,34841,34832,34833,34839,\n34835,34838,35171,35174,35257,35319,35680,35690,35677,35688,35683,35685,35687,\n35693,36270,36486,36488,36484,36697,36694,36695,36693,36696,36698,37005,37187,\n37185,37303,37301,37298,37299,37899,37907,37883,37920,37903,37908,37886,37909,\n37904,37928,37913,37901,37877,37888,37879,37895,37902,37910,37906,37882,37897,\n37880,37898,37887,37884,37900,37878,37905,37894,38366,38368,38367,38702,38703,\n38841,38843,38909,38910,39008,39010,39011,39007,39105,39106,39248,39246,39257,\n39244,39243,39251,39474,39476,39473,39468,39466,39478,39465,39470,39480,39469,\n39623,39626,39622,39696,39698,39697,39947,39944,39927,39941,39954,39928,40000,\n39943,39950,39942,39959,39956,39945,40351,40345,40356,40349,40338,40344,40336,\n40347,40352,40340,40348,40362,40343,40353,40346,40354,40360,40350,40355,40383,\n40361,40342,40358,40359,40601,40603,40602,40677,40676,40679,40678,40752,40750,\n40795,40800,40798,40797,40793,40849,20794,20793,21144,21143,22211,22205,22206,\n23368,23367,24011,24015,24305,25085,25883,27394,27388,27395,27384,27392,28739,\n28740,28746,28744,28745,28741,28742,29213,29210,29209,\n29566,29975,30314,30672,31021,31025,31023,31828,31827,31986,32394,32391,32392,\n32395,32390,32397,32589,32699,32816,33245,34328,34346,34342,34335,34339,34332,\n34329,34343,34350,34337,34336,34345,34334,34341,34857,34845,34843,34848,34852,\n34844,34859,34890,35181,35177,35182,35179,35322,35705,35704,35653,35706,35707,\n36112,36116,36271,36494,36492,36702,36699,36701,37190,37188,37189,37305,37951,\n37947,37942,37929,37949,37948,37936,37945,37930,37943,37932,37952,37937,38373,\n38372,38371,38709,38714,38847,38881,39012,39113,39110,39104,39256,39254,39481,\n39485,39494,39492,39490,39489,39482,39487,39629,39701,39703,39704,39702,39738,\n39762,39979,39965,39964,39980,39971,39976,39977,39972,39969,40375,40374,40380,\n40385,40391,40394,40399,40382,40389,40387,40379,40373,40398,40377,40378,40364,\n40392,40369,40365,40396,40371,40397,40370,40570,40604,40683,40686,40685,40731,\n40728,40730,40753,40782,40805,40804,40850,20153,22214,22213,22219,22897,23371,\n23372,24021,24017,24306,25889,25888,25894,25890,27403,27400,27401,27661,28757,\n28758,28759,28754,29214,29215,29353,29567,29912,29909,29913,29911,30317,30381,\n31029,31156,31344,31345,31831,31836,31833,31835,31834,31988,31985,32401,32591,\n32647,33246,33387,34356,34357,34355,34348,34354,34358,34860,34856,34854,34858,\n34853,35185,35263,35262,35323,35710,35716,35714,35718,35717,35711,36117,36501,\n36500,36506,36498,36496,36502,36503,36704,36706,37191,37964,37968,37962,37963,\n37967,37959,37957,37960,37961,37958,38719,38883,39018,39017,39115,39252,39259,\n39502,39507,39508,39500,39503,39496,39498,39497,39506,\n39504,39632,39705,39723,39739,39766,39765,40006,40008,39999,40004,39993,39987,\n40001,39996,39991,39988,39986,39997,39990,40411,40402,40414,40410,40395,40400,\n40412,40401,40415,40425,40409,40408,40406,40437,40405,40413,40630,40688,40757,\n40755,40754,40770,40811,40853,40866,20797,21145,22760,22759,22898,23373,24024,\n34863,24399,25089,25091,25092,25897,25893,26006,26347,27409,27410,27407,27594,\n28763,28762,29218,29570,29569,29571,30320,30676,31847,31846,32405,33388,34362,\n34368,34361,34364,34353,34363,34366,34864,34866,34862,34867,35190,35188,35187,\n35326,35724,35726,35723,35720,35909,36121,36504,36708,36707,37308,37986,37973,\n37981,37975,37982,38852,38853,38912,39510,39513,39710,39711,39712,40018,40024,\n40016,40010,40013,40011,40021,40025,40012,40014,40443,40439,40431,40419,40427,\n40440,40420,40438,40417,40430,40422,40434,40432,40418,40428,40436,40435,40424,\n40429,40642,40656,40690,40691,40710,40732,40760,40759,40758,40771,40783,40817,\n40816,40814,40815,22227,22221,23374,23661,25901,26349,26350,27411,28767,28769,\n28765,28768,29219,29915,29925,30677,31032,31159,31158,31850,32407,32649,33389,\n34371,34872,34871,34869,34891,35732,35733,36510,36511,36512,36509,37310,37309,\n37314,37995,37992,37993,38629,38726,38723,38727,38855,38885,39518,39637,39769,\n40035,40039,40038,40034,40030,40032,40450,40446,40455,40451,40454,40453,40448,\n40449,40457,40447,40445,40452,40608,40734,40774,40820,40821,40822,22228,25902,\n26040,27416,27417,27415,27418,28770,29222,29354,30680,30681,31033,31849,31851,\n31990,32410,32408,32411,32409,33248,33249,34374,34375,\n34376,35193,35194,35196,35195,35327,35736,35737,36517,36516,36515,37998,37997,\n37999,38001,38003,38729,39026,39263,40040,40046,40045,40459,40461,40464,40463,\n40466,40465,40609,40693,40713,40775,40824,40827,40826,40825,22302,28774,31855,\n34876,36274,36518,37315,38004,38008,38006,38005,39520,40052,40051,40049,40053,\n40468,40467,40694,40714,40868,28776,28773,31991,34410,34878,34877,34879,35742,\n35996,36521,36553,38731,39027,39028,39116,39265,39339,39524,39526,39527,39716,\n40469,40471,40776,25095,27422,29223,34380,36520,38018,38016,38017,39529,39528,\n39726,40473,29225,34379,35743,38019,40057,40631,30325,39531,40058,40477,28777,\n28778,40612,40830,40777,40856,30849,37561,35023,22715,24658,31911,23290,9556,\n9574,9559,9568,9580,9571,9562,9577,9565,9554,9572,9557,9566,9578,9569,9560,\n9575,9563,9555,9573,9558,9567,9579,9570,9561,9576,9564,9553,9552,9581,9582,\n9584,9583,9619,\n"
  },
  {
    "path": "user.libc/src/locale/bind_textdomain_codeset.c",
    "content": "#include <libintl.h>\n#include <string.h>\n#include <strings.h>\n#include <errno.h>\n\nchar *bind_textdomain_codeset(const char *domainname, const char *codeset)\n{\n\tif (codeset && strcasecmp(codeset, \"UTF-8\"))\n\t\terrno = EINVAL;\n\treturn NULL;\n}\n"
  },
  {
    "path": "user.libc/src/locale/c_locale.c",
    "content": "#include \"locale_impl.h\"\n#include <stdint.h>\n\nstatic const uint32_t empty_mo[] = { 0x950412de, 0, -1, -1, -1 };\n\nconst struct __locale_map __c_dot_utf8 = {\n\t.map = empty_mo,\n\t.map_size = sizeof empty_mo,\n\t.name = \"C.UTF-8\"\n};\n\nconst struct __locale_struct __c_locale = { 0 };\nconst struct __locale_struct __c_dot_utf8_locale = {\n\t.cat[LC_CTYPE] = &__c_dot_utf8\n};\n"
  },
  {
    "path": "user.libc/src/locale/catclose.c",
    "content": "#define _BSD_SOURCE\n#include <nl_types.h>\n#include <stdint.h>\n#include <endian.h>\n#include <sys/mman.h>\n\n#define V(p) be32toh(*(uint32_t *)(p))\n\nint catclose (nl_catd catd)\n{\n\tchar *map = (char *)catd;\n\tmunmap(map, V(map+8)+20);\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/locale/catgets.c",
    "content": "#define _BSD_SOURCE\n#include <nl_types.h>\n#include <endian.h>\n#include <stdlib.h>\n#include <stdint.h>\n#include <errno.h>\n\n#define V(p) be32toh(*(uint32_t *)(p))\n\nstatic int cmp(const void *a, const void *b)\n{\n\tuint32_t x = V(a), y = V(b);\n\treturn x<y ? -1 : x>y ? 1 : 0;\n}\n\nchar *catgets (nl_catd catd, int set_id, int msg_id, const char *s)\n{\n\tconst char *map = (const char *)catd;\n\tuint32_t nsets = V(map+4);\n\tconst char *sets = map+20;\n\tconst char *msgs = map+20+V(map+12);\n\tconst char *strings = map+20+V(map+16);\n\tuint32_t set_id_be = htobe32(set_id);\n\tuint32_t msg_id_be = htobe32(msg_id);\n\tconst char *set = bsearch(&set_id_be, sets, nsets, 12, cmp);\n\tif (!set) {\n\t\terrno = ENOMSG;\n\t\treturn (char *)s;\n\t}\n\tuint32_t nmsgs = V(set+4);\n\tmsgs += 12*V(set+8);\n\tconst char *msg = bsearch(&msg_id_be, msgs, nmsgs, 12, cmp);\n\tif (!msg) {\n\t\terrno = ENOMSG;\n\t\treturn (char *)s;\n\t}\n\treturn (char *)(strings + V(msg+8));\n}\n"
  },
  {
    "path": "user.libc/src/locale/catopen.c",
    "content": "#define _BSD_SOURCE\n#include <nl_types.h>\n#include <string.h>\n#include <stdint.h>\n#include <endian.h>\n#include <errno.h>\n#include <langinfo.h>\n#include <locale.h>\n#include <sys/mman.h>\n#include \"libc.h\"\n\n#define V(p) be32toh(*(uint32_t *)(p))\n\nstatic nl_catd do_catopen(const char *name)\n{\n\tsize_t size;\n\tconst unsigned char *map = __map_file(name, &size);\n\t/* Size recorded in the file must match file size; otherwise\n\t * the information needed to unmap the file will be lost. */\n\tif (!map || V(map) != 0xff88ff89 || 20+V(map+8) != size) {\n\t\tif(map) munmap((void *)map, size);\n\t\terrno = ENOENT;\n\t\treturn (nl_catd)-1;\n\t}\n\treturn (nl_catd)map;\n}\n\nnl_catd catopen(const char *name, int oflag)\n{\n\tnl_catd catd;\n\n\tif (strchr(name, '/')) return do_catopen(name);\n\n\tchar buf[PATH_MAX];\n\tsize_t i;\n\tconst char *path, *lang, *p, *z;\n\tif (libc.secure || !(path = getenv(\"NLSPATH\"))) {\n\t\terrno = ENOENT;\n\t\treturn (nl_catd)-1;\n\t}\n\tlang = oflag ? nl_langinfo(_NL_LOCALE_NAME(LC_MESSAGES)) : getenv(\"LANG\");\n\tif (!lang) lang = \"\";\n\tfor (p=path; *p; p=z) {\n\t\ti = 0;\n\t\tz = __strchrnul(p, ':');\n\t\tfor (; p<z; p++) {\n\t\t\tconst char *v;\n\t\t\tsize_t l;\n\t\t\tif (*p!='%') v=p, l=1;\n\t\t\telse switch (*++p) {\n\t\t\tcase 'N': v=name; l=strlen(v); break;\n\t\t\tcase 'L': v=lang; l=strlen(v); break;\n\t\t\tcase 'l': v=lang; l=strcspn(v,\"_.@\"); break;\n\t\t\tcase 't':\n\t\t\t\tv=__strchrnul(lang,'_');\n\t\t\t\tif (*v) v++;\n\t\t\t\tl=strcspn(v,\".@\");\n\t\t\t\tbreak;\n\t\t\tcase 'c': v=\"UTF-8\"; l=5; break;\n\t\t\tcase '%': v=\"%\"; l=1; break;\n\t\t\tdefault: v=0;\n\t\t\t}\n\t\t\tif (!v || l >= sizeof buf - i) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmemcpy(buf+i, v, l);\n\t\t\ti += l;\n\t\t}\n\t\tif (!*z && (p<z || !i)) break;\n\t\tif (p<z) continue;\n\t\tif (*z) z++;\n\t\tbuf[i] = 0;\n\t\t/* Leading : or :: in NLSPATH is same as %N */\n\t\tcatd = do_catopen(i ? buf : name);\n\t\tif (catd != (nl_catd)-1) return catd;\n\t}\n\terrno = ENOENT;\n\treturn (nl_catd)-1;\n}\n"
  },
  {
    "path": "user.libc/src/locale/codepages.h",
    "content": "\"iso88591\\0\"\n\"latin1\\0\"\n\"\\0\\100\"\n\n\"iso88592\\0\"\n\"\\0\\50\"\n\"\\240\\20\\364\\127\\116\\244\\334\\364\\324\\51\\250\\124\\65\\125\\126\\156\\265\\42\\27\\134\"\n\"\\260\\24\\24\\230\\116\\264\\340\\4\\225\\137\\270\\130\\105\\225\\126\\157\\15\\66\\127\\134\"\n\"\\111\\5\\43\\214\\100\\304\\314\\144\\320\\61\\14\\45\\143\\321\\62\\30\\65\\343\\214\\103\"\n\"\\20\\355\\364\\323\\64\\324\\24\\145\\315\\65\\115\\215\\245\\115\\131\\334\\164\\163\\325\\67\"\n\"\\112\\205\\43\\316\\100\\344\\320\\164\\320\\71\\15\\245\\163\\321\\72\\31\\265\\343\\316\\103\"\n\"\\21\\361\\4\\324\\74\\364\\30\\145\\317\\75\\116\\221\\245\\217\\131\\374\\364\\203\\25\\140\"\n\n\"iso88593\\0\"\n\"\\0\\50\"\n\"\\240\\220\\364\\327\\50\\244\\0\\40\\322\\51\\250\\260\\64\\25\\107\\56\\265\\2\\0\\134\"\n\"\\260\\224\\44\\313\\54\\264\\324\\62\\322\\55\\270\\264\\104\\125\\107\\57\\365\\2\\100\\134\"\n\"\\300\\4\\43\\14\\0\\304\\50\\204\\320\\61\\310\\44\\243\\314\\62\\314\\64\\343\\314\\63\"\n\"\\0\\104\\43\\315\\64\\324\\170\\144\\315\\65\\32\\145\\243\\315\\66\\334\\204\\25\\325\\67\"\n\"\\340\\204\\43\\16\\0\\344\\54\\224\\320\\71\\350\\244\\243\\316\\72\\354\\264\\343\\316\\73\"\n\"\\0\\304\\43\\317\\74\\364\\174\\144\\317\\75\\33\\345\\243\\317\\76\\374\\210\\45\\25\\140\"\n\n\"iso88594\\0\"\n\"\\0\\50\"\n\"\\240\\20\\44\\323\\122\\244\\230\\124\\323\\51\\250\\124\\45\\21\\110\\133\\265\\42\\327\\53\"\n\"\\260\\24\\24\\30\\123\\264\\234\\144\\223\\137\\270\\130\\65\\121\\110\\134\\5\\65\\227\\120\"\n\"\\0\\5\\43\\314\\60\\304\\24\\143\\214\\112\\14\\45\\143\\321\\62\\24\\65\\343\\14\\112\"\n\"\\20\\365\\64\\24\\114\\324\\124\\143\\315\\65\\330\\234\\245\\315\\66\\334\\164\\365\\325\\67\"\n\"\\1\\205\\43\\316\\70\\344\\224\\143\\316\\112\\15\\245\\163\\321\\72\\25\\265\\343\\116\\112\"\n\"\\21\\371\\104\\124\\114\\364\\324\\143\\317\\75\\370\\240\\245\\317\\76\\374\\170\\5\\26\\140\"\n\n\"iso88595\\0\"\n\"\\0\\50\"\n\"\\240\\104\\47\\335\\164\\324\\125\\147\\335\\165\\330\\145\\247\\335\\166\"\n\"\\334\\265\\322\\235\\167\\337\\201\\27\\236\\170\\343\\221\\127\\236\\171\"\n\"\\347\\241\\227\\236\\172\\353\\261\\327\\236\\173\\357\\301\\27\\237\\174\"\n\"\\363\\321\\127\\237\\175\\367\\341\\227\\237\\176\\373\\361\\327\\237\\177\\377\\1\\30\\240\\200\"\n\"\\3\\22\\130\\240\\201\\7\\42\\230\\240\\202\\13\\62\\330\\240\\203\\17\\102\\30\\241\\204\"\n\"\\23\\122\\130\\241\\205\\27\\142\\230\\241\\206\\33\\162\\330\\241\\207\\46\\177\\10\\142\\210\"\n\"\\42\\216\\110\\142\\211\\46\\236\\210\\142\\212\\52\\236\\262\\42\\213\"\n\n\"iso88596\\0\"\n\"\\0\\50\"\n\"\\240\\0\\0\\0\\0\\244\\0\\0\\0\\0\\0\\0\\0\\0\\0\\142\\266\\2\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n\"\\0\\0\\0\\300\\230\\0\\0\\0\\0\\231\\0\\224\\151\\346\\231\\150\\246\\251\\346\\232\"\n\"\\154\\266\\351\\346\\233\\160\\306\\51\\347\\234\\164\\326\\151\\347\\235\"\n\"\\170\\346\\251\\347\\236\\174\\366\\351\\47\\0\\0\\0\\0\\0\\0\\177\\2\\32\\250\\240\"\n\"\\203\\22\\132\\250\\241\\207\\42\\232\\250\\242\\213\\62\\332\\250\\243\\217\\102\\32\\51\\0\"\n\"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n\n\"iso88597\\0\"\n\"\\0\\50\"\n\"\\240\\114\\114\\361\\50\\44\\227\\154\\312\\51\\250\\244\\222\\330\\52\\254\\264\\2\\100\\304\"\n\"\\260\\304\\42\\313\\54\\212\\55\\306\\330\\55\\215\\71\\366\\330\\56\\220\\365\\22\\231\\144\"\n\"\\223\\121\\126\\231\\145\\227\\141\\226\\231\\146\\233\\161\\326\\231\\147\"\n\"\\237\\201\\26\\232\\150\\243\\221\\6\\100\\151\\246\\235\\206\\132\\152\\252\\255\\306\\132\\153\"\n\"\\256\\275\\6\\133\\154\\262\\315\\106\\133\\155\\266\\335\\206\\133\\156\\272\\355\\306\\133\\157\"\n\"\\276\\375\\6\\134\\160\\302\\15\\107\\134\\161\\306\\35\\207\\134\\162\\312\\55\\307\\134\\163\"\n\"\\316\\75\\7\\35\\0\"\n\n\"iso88598\\0\"\n\"\\0\\50\"\n\"\\240\\0\\40\\312\\50\\244\\224\\142\\312\\51\\250\\244\\162\\315\\52\\254\\264\\342\\312\\53\"\n\"\\260\\304\\42\\313\\54\\264\\324\\142\\313\\55\\270\\344\\162\\317\\56\\274\\364\\342\\13\\0\"\n\"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n\"\\0\\0\\0\\200\\304\\102\\16\\111\\144\\221\\106\\36\\211\\144\\222\\112\\56\\311\\144\\223\"\n\"\\116\\76\\11\\145\\224\\122\\116\\111\\145\\225\\126\\136\\211\\145\\226\\132\\156\\311\\45\\0\"\n\"\\0\\64\\354\\60\\0\"\n\n\"iso88599\\0\"\n\"\\0\\64\"\n\"\\34\\105\\43\\315\\64\\324\\124\\143\\315\\65\\330\\144\\243\\315\\66\\334\\260\\64\\325\\67\"\n\"\\340\\204\\43\\316\\70\\344\\224\\143\\316\\71\\350\\244\\243\\316\\72\\354\\264\\343\\316\\73\"\n\"\\35\\305\\43\\317\\74\\364\\324\\143\\317\\75\\370\\344\\243\\317\\76\\374\\264\\104\\325\\77\"\n\n\"iso885910\\0\"\n\"\\0\\50\"\n\"\\240\\20\\44\\21\\110\\50\\231\\4\\323\\51\\65\\101\\124\\325\\126\\162\\265\\362\\125\\120\"\n\"\\260\\24\\64\\121\\110\\51\\235\\24\\323\\55\\66\\105\\144\\25\\127\\163\\105\\14\\226\\120\"\n\"\\0\\5\\43\\314\\60\\304\\24\\143\\214\\112\\14\\45\\143\\321\\62\\24\\65\\343\\314\\63\"\n\"\\320\\364\\64\\324\\64\\324\\124\\143\\115\\127\\330\\234\\245\\315\\66\\334\\164\\343\\315\\67\"\n\"\\1\\205\\43\\316\\70\\344\\224\\143\\316\\112\\15\\245\\163\\321\\72\\25\\265\\343\\316\\73\"\n\"\\360\\370\\104\\324\\74\\364\\324\\143\\217\\127\\370\\240\\245\\317\\76\\374\\364\\343\\217\\114\"\n\n\"iso885911\\0\"\n\"tis620\\0\"\n\"\\0\\50\"\n\"\\240\\170\\372\\51\\250\\241\\212\\72\\52\\251\\245\\232\\172\\52\\252\\251\\252\\272\\52\\253\"\n\"\\255\\272\\372\\52\\254\\261\\312\\72\\53\\255\\265\\332\\172\\53\\256\\271\\352\\272\\53\\257\"\n\"\\275\\372\\372\\53\\260\\301\\12\\73\\54\\261\\305\\32\\173\\54\\262\\311\\52\\273\\54\\263\"\n\"\\315\\72\\373\\54\\264\\321\\112\\73\\55\\265\\325\\132\\173\\55\\0\\0\\0\\0\\0\\266\"\n\"\\331\\152\\273\\55\\267\\335\\172\\373\\55\\270\\341\\212\\73\\56\\271\\345\\232\\173\\56\\272\"\n\"\\351\\252\\273\\56\\273\\355\\272\\373\\56\\274\\361\\312\\73\\57\\275\\0\\0\\0\\0\\0\"\n\n\"iso885913\\0\"\n\"\\0\\50\"\n\"\\240\\134\\54\\312\\50\\244\\140\\154\\312\\51\\330\\244\\262\\324\\52\\254\\264\\342\\212\\61\"\n\"\\260\\304\\42\\313\\54\\26\\327\\142\\313\\55\\370\\344\\302\\324\\56\\274\\364\\342\\213\\71\"\n\"\\4\\251\\4\\220\\101\\304\\24\\143\\221\\104\\14\\45\\343\\26\\105\\40\\301\\204\\122\\115\"\n\"\\125\\355\\324\\323\\64\\103\\125\\143\\315\\65\\147\\345\\364\\324\\127\\334\\300\\45\\327\\67\"\n\"\\5\\255\\24\\320\\101\\344\\224\\163\\321\\104\\15\\245\\363\\126\\105\\41\\305\\224\\222\\115\"\n\"\\126\\361\\344\\323\\74\\104\\325\\143\\317\\75\\150\\351\\4\\25\\130\\374\\304\\65\\27\\305\"\n\n\"iso885914\\0\"\n\"\\0\\50\"\n\"\\240\\324\\153\\357\\50\\12\\55\\164\\357\\51\\3\\247\\122\\60\\276\\11\\267\\342\\112\\133\"\n\"\\371\\352\\353\\321\\107\\373\\362\\153\\113\\277\\4\\373\\153\\360\\277\\12\\37\\214\\60\\300\"\n\"\\300\\4\\43\\314\\60\\304\\24\\143\\314\\61\\310\\44\\243\\314\\62\\314\\64\\343\\314\\63\"\n\"\\151\\105\\43\\315\\64\\324\\124\\143\\115\\300\\330\\144\\243\\315\\66\\334\\164\\263\\326\\67\"\n\"\\340\\204\\43\\316\\70\\344\\224\\143\\316\\71\\350\\244\\243\\316\\72\\354\\264\\343\\316\\73\"\n\"\\152\\305\\43\\317\\74\\364\\324\\143\\217\\300\\370\\344\\243\\317\\76\\374\\364\\303\\326\\77\"\n\n\"iso885915\\0\"\n\"latin9\\0\"\n\"\\0\\51\"\n\"\\44\\227\\122\\325\\51\\126\\245\\242\\312\\52\\254\\264\\342\\312\\53\\260\\304\\42\\313\\54\"\n\"\\162\\325\\142\\313\\55\\163\\345\\242\\313\\56\\107\\41\\325\\326\\57\\300\\4\\43\\314\\60\"\n\"\\304\\24\\143\\314\\61\\310\\44\\243\\314\\62\\314\\64\\343\\314\\63\\320\\104\\43\\315\\64\"\n\"\\324\\124\\143\\315\\65\\330\\144\\243\\315\\66\\334\\164\\343\\315\\67\\340\\204\\43\\316\\70\"\n\"\\344\\224\\143\\316\\71\\350\\244\\243\\316\\72\\354\\264\\343\\316\\73\\360\\304\\43\\317\\74\"\n\"\\364\\324\\143\\317\\75\\370\\344\\243\\317\\76\\374\\364\\343\\317\\77\"\n\n\"iso885916\\0\"\n\"\\0\\50\"\n\"\\240\\20\\124\\120\\116\\44\\143\\134\\325\\51\\126\\245\\222\\327\\52\\156\\265\\362\\26\\134\"\n\"\\260\\304\\302\\220\\116\\162\\135\\154\\313\\55\\163\\65\\244\\327\\56\\107\\41\\325\\126\\134\"\n\"\\300\\4\\43\\214\\100\\304\\30\\144\\314\\61\\310\\44\\243\\314\\62\\314\\64\\343\\314\\63\"\n\"\\20\\355\\44\\315\\64\\324\\24\\145\\315\\123\\145\\145\\243\\315\\66\\334\\130\\264\\327\\67\"\n\"\\340\\204\\43\\316\\100\\344\\34\\144\\316\\71\\350\\244\\243\\316\\72\\354\\264\\343\\316\\73\"\n\"\\21\\361\\44\\317\\74\\364\\30\\145\\17\\124\\146\\345\\243\\317\\76\\374\\134\\304\\327\\77\"\n\n\"cp1250\\0\"\n\"windows1250\\0\"\n\"\\0\\40\"\n\"\\44\\3\\120\\61\\0\\30\\163\\234\\261\\306\\0\\164\\134\\225\\307\\117\\145\\45\\227\\133\"\n\"\\0\\114\\114\\261\\305\\27\\157\\374\\60\\304\\0\\234\\154\\325\\307\\120\\151\\65\\327\\133\"\n\"\\240\\370\\365\\127\\116\\244\\20\\144\\312\\51\\250\\244\\62\\325\\52\\254\\264\\342\\12\\134\"\n\"\\260\\304\\22\\230\\116\\264\\324\\142\\313\\55\\270\\24\\104\\325\\56\\67\\15\\206\\123\\134\"\n\"\\111\\5\\43\\214\\100\\304\\314\\144\\320\\61\\14\\45\\143\\321\\62\\30\\65\\343\\214\\103\"\n\"\\20\\355\\364\\323\\64\\324\\24\\145\\315\\65\\115\\215\\245\\115\\131\\334\\164\\163\\325\\67\"\n\"\\112\\205\\43\\316\\100\\344\\320\\164\\320\\71\\15\\245\\163\\321\\72\\31\\265\\343\\316\\103\"\n\"\\21\\361\\4\\324\\74\\364\\30\\145\\317\\75\\116\\221\\245\\217\\131\\374\\364\\203\\25\\140\"\n\n\"cp1251\\0\"\n\"windows1251\\0\"\n\"\\0\\40\"\n\"\\322\\115\\127\\161\\210\\30\\163\\234\\261\\306\\44\\167\\234\\235\\307\\332\\161\\267\\235\\167\"\n\"\\40\\116\\114\\261\\305\\27\\157\\374\\60\\304\\0\\234\\174\\342\\307\\50\\252\\230\\42\\213\"\n\"\\240\\164\\267\\42\\166\\244\\264\\150\\312\\51\\321\\245\\102\\335\\52\\254\\264\\342\\312\\165\"\n\"\\260\\304\\142\\35\\211\\56\\326\\142\\313\\55\\37\\232\\54\\342\\56\\46\\126\\67\\142\\211\"\n\"\\337\\201\\27\\236\\170\\343\\221\\127\\236\\171\\347\\241\\227\\236\\172\"\n\"\\353\\261\\327\\236\\173\\357\\301\\27\\237\\174\\363\\321\\127\\237\\175\"\n\"\\367\\341\\227\\237\\176\\373\\361\\327\\237\\177\\377\\1\\30\\240\\200\\3\\22\\130\\240\\201\"\n\"\\7\\42\\230\\240\\202\\13\\62\\330\\240\\203\\17\\102\\30\\241\\204\\23\\122\\130\\241\\205\"\n\"\\27\\142\\230\\241\\206\\33\\162\\330\\241\\207\"\n\n\"cp1252\\0\"\n\"windows1252\\0\"\n\"\\0\\40\"\n\"\\44\\3\\120\\61\\135\\30\\163\\234\\261\\306\\175\\165\\134\\225\\307\\107\\1\\40\\27\\0\"\n\"\\0\\114\\114\\261\\305\\27\\157\\374\\60\\304\\202\\235\\154\\325\\307\\110\\1\\60\\127\\133\"\n\"\\240\\204\\42\\312\\50\\244\\224\\142\\312\\51\\250\\244\\242\\312\\52\\254\\264\\342\\312\\53\"\n\"\\260\\304\\42\\313\\54\\264\\324\\142\\313\\55\\270\\344\\242\\313\\56\\274\\364\\342\\313\\57\"\n\"\\300\\4\\43\\314\\60\\304\\24\\143\\314\\61\\310\\44\\243\\314\\62\\314\\64\\343\\314\\63\"\n\"\\320\\104\\43\\315\\64\\324\\124\\143\\315\\65\\330\\144\\243\\315\\66\\334\\164\\343\\315\\67\"\n\"\\340\\204\\43\\316\\70\\344\\224\\143\\316\\71\\350\\244\\243\\316\\72\\354\\264\\343\\316\\73\"\n\"\\360\\304\\43\\317\\74\\364\\324\\143\\317\\75\\370\\344\\243\\317\\76\\374\\364\\343\\317\\77\"\n\n\"cp1253\\0\"\n\"windows1253\\0\"\n\"\\0\\40\"\n\"\\44\\3\\120\\61\\135\\30\\163\\234\\261\\306\\0\\164\\14\\200\\307\\0\\0\\0\\0\\0\"\n\"\\0\\114\\114\\261\\305\\27\\157\\374\\60\\304\\0\\234\\14\\300\\307\\0\\0\\0\\0\\0\"\n\"\\240\\54\\306\\330\\50\\244\\224\\142\\312\\51\\250\\244\\2\\300\\52\\254\\264\\342\\112\\304\"\n\"\\260\\304\\42\\313\\54\\212\\325\\142\\313\\55\\215\\71\\366\\330\\56\\220\\365\\22\\231\\144\"\n\"\\223\\121\\126\\231\\145\\227\\141\\226\\231\\146\\233\\161\\326\\231\\147\"\n\"\\237\\201\\26\\232\\150\\243\\221\\6\\100\\151\\246\\235\\206\\132\\152\\252\\255\\306\\132\\153\"\n\"\\256\\275\\6\\133\\154\\262\\315\\106\\133\\155\\266\\335\\206\\133\\156\\272\\355\\306\\133\\157\"\n\"\\276\\375\\6\\134\\160\\302\\15\\107\\134\\161\\306\\35\\207\\134\\162\\312\\55\\307\\134\\163\"\n\"\\316\\75\\7\\35\\0\"\n\n\"cp1254\\0\"\n\"windows1254\\0\"\n\"\\0\\40\"\n\"\\44\\3\\120\\61\\135\\30\\163\\234\\261\\306\\175\\165\\134\\225\\307\\107\\1\\0\\0\\0\"\n\"\\0\\114\\114\\261\\305\\27\\157\\374\\60\\304\\202\\235\\154\\325\\307\\110\\1\\0\\100\\133\"\n\"\\240\\204\\42\\312\\50\\244\\224\\142\\312\\51\\250\\244\\242\\312\\52\\254\\264\\342\\312\\53\"\n\"\\260\\304\\42\\313\\54\\264\\324\\142\\313\\55\\270\\344\\242\\313\\56\\274\\364\\342\\313\\57\"\n\"\\300\\4\\43\\314\\60\\304\\24\\143\\314\\61\\310\\44\\243\\314\\62\\314\\64\\343\\314\\63\"\n\"\\34\\105\\43\\315\\64\\324\\124\\143\\315\\65\\330\\144\\243\\315\\66\\334\\260\\64\\325\\67\"\n\"\\340\\204\\43\\316\\70\\344\\224\\143\\316\\71\\350\\244\\243\\316\\72\\354\\264\\343\\316\\73\"\n\"\\35\\305\\43\\317\\74\\364\\324\\143\\317\\75\\370\\344\\243\\317\\76\\374\\264\\104\\325\\77\"\n\n\"cp1255\\0\"\n\"windows1255\\0\"\n\"\\0\\40\"\n\"\\44\\3\\120\\61\\135\\30\\163\\234\\261\\306\\175\\165\\14\\200\\307\\0\\0\\0\\0\\0\"\n\"\\0\\114\\114\\261\\305\\27\\157\\374\\60\\304\\202\\235\\14\\300\\307\\0\\0\\0\\0\\0\"\n\"\\240\\204\\42\\312\\50\\42\\227\\142\\312\\51\\250\\244\\162\\315\\52\\254\\264\\342\\312\\53\"\n\"\\260\\304\\42\\313\\54\\264\\324\\142\\313\\55\\270\\344\\162\\317\\56\\274\\364\\342\\313\\57\"\n\"\\57\\302\\30\\243\\214\\63\\322\\130\\243\\215\\67\\342\\10\\100\\216\\72\\356\\310\\143\\217\"\n\"\\76\\376\\10\\144\\220\\135\\172\\371\\45\\230\\141\\2\\0\\0\\0\\0\\0\\0\\0\\0\\102\\16\\111\\144\\221\"\n\"\\106\\36\\211\\144\\222\\112\\56\\311\\144\\223\\116\\76\\11\\145\\224\\122\\116\\111\\145\\225\"\n\"\\126\\136\\211\\145\\226\\132\\156\\311\\45\\0\\0\\64\\354\\60\\0\"\n\n\"cp1256\\0\"\n\"windows1256\\0\"\n\"\\0\\40\"\n\"\\44\\117\\132\\61\\135\\30\\163\\234\\261\\306\\175\\165\\54\\251\\307\\107\\121\\172\\151\\245\"\n\"\\231\\116\\114\\261\\305\\27\\157\\374\\60\\304\\230\\236\\154\\351\\307\\110\\55\\314\\260\\246\"\n\"\\240\\210\\51\\312\\50\\244\\224\\142\\312\\51\\250\\244\\262\\351\\52\\254\\264\\342\\312\\53\"\n\"\\260\\304\\42\\313\\54\\264\\324\\142\\313\\55\\270\\344\\62\\346\\56\\274\\364\\342\\13\\231\"\n\"\\234\\226\\151\\346\\231\\150\\246\\251\\346\\232\\154\\266\\351\\346\\233\"\n\"\\160\\306\\51\\347\\234\\164\\326\\151\\347\\235\\170\\346\\251\\347\\65\\173\\362\\331\\247\\237\"\n\"\\177\\2\\32\\250\\240\\340\\14\\52\\16\\241\\205\\32\\172\\350\\71\\350\\244\\243\\316\\72\"\n\"\\210\\46\\352\\316\\73\\212\\56\\312\\150\\243\\364\\70\\372\\350\\75\\220\\346\\23\\351\\76\"\n\"\\374\\64\\354\\160\\247\"\n\n\"cp1257\\0\"\n\"windows1257\\0\"\n\"\\0\\40\"\n\"\\44\\3\\120\\61\\0\\30\\163\\234\\261\\306\\0\\164\\14\\200\\307\\0\\240\\342\\27\\56\"\n\"\\0\\114\\114\\261\\305\\27\\157\\374\\60\\304\\0\\234\\14\\300\\307\\0\\274\\22\\30\\0\"\n\"\\240\\0\\40\\312\\50\\244\\0\\140\\312\\51\\330\\244\\262\\324\\52\\254\\264\\342\\212\\61\"\n\"\\260\\304\\42\\313\\54\\264\\324\\142\\313\\55\\370\\344\\302\\324\\56\\274\\364\\342\\213\\71\"\n\"\\4\\251\\4\\220\\101\\304\\24\\143\\221\\104\\14\\45\\343\\26\\105\\40\\301\\204\\122\\115\"\n\"\\125\\355\\324\\323\\64\\103\\125\\143\\315\\65\\147\\345\\364\\324\\127\\334\\300\\45\\327\\67\"\n\"\\5\\255\\24\\320\\101\\344\\224\\163\\321\\104\\15\\245\\363\\126\\105\\41\\305\\224\\222\\115\"\n\"\\126\\361\\344\\323\\74\\104\\325\\143\\317\\75\\150\\351\\4\\25\\130\\374\\304\\65\\27\\140\"\n\n\"cp1258\\0\"\n\"windows1258\\0\"\n\"\\0\\40\"\n\"\\44\\3\\120\\61\\135\\30\\163\\234\\261\\306\\175\\165\\14\\200\\307\\107\\1\\0\\0\\0\"\n\"\\0\\114\\114\\261\\305\\27\\157\\374\\60\\304\\202\\235\\14\\300\\307\\110\\1\\0\\100\\133\"\n\"\\240\\204\\42\\312\\50\\244\\224\\142\\312\\51\\250\\244\\242\\312\\52\\254\\264\\342\\312\\53\"\n\"\\260\\304\\42\\313\\54\\264\\324\\142\\313\\55\\270\\344\\242\\313\\56\\274\\364\\342\\313\\57\"\n\"\\300\\4\\43\\214\\100\\304\\24\\143\\314\\61\\310\\44\\243\\314\\62\\204\\65\\343\\314\\63\"\n\"\\20\\105\\163\\330\\64\\324\\324\\145\\315\\65\\330\\144\\243\\315\\66\\334\\334\\145\\330\\67\"\n\"\\340\\204\\43\\316\\100\\344\\224\\143\\316\\71\\350\\244\\243\\316\\72\\205\\265\\343\\316\\73\"\n\"\\21\\305\\203\\330\\74\\364\\330\\145\\317\\75\\370\\344\\243\\317\\76\\374\\340\\65\\362\\77\"\n\n\"koi8r\\0\"\n\"\\0\\40\"\n\"\\63\\323\\134\\263\\315\\67\\343\\234\\263\\316\\73\\363\\334\\363\\326\\134\\167\\355\\365\\327\"\n\"\\140\\207\\55\\166\\314\\143\\243\\234\\62\\313\\56\\277\\14\\212\\314\\260\\310\\162\\313\\75\"\n\"\\76\\377\\14\\364\\207\\101\\13\\75\\64\\321\\105\\33\\175\\64\\322\\111\\53\\275\\64\\323\"\n\"\\115\\73\\375\\164\\164\\120\\107\\55\\365\\324\\124\\127\\155\\365\\325\\130\\147\\255\\165\\52\"\n\"\\35\\376\\7\\140\\205\\3\\22\\70\\241\\200\\24\\36\\210\\140\\202\\12\\56\\310\\140\\203\"\n\"\\16\\172\\370\\40\\204\\21\\112\\130\\140\\200\\33\\152\\150\\340\\205\\34\\142\\150\\141\\206\"\n\"\\375\\175\\7\\136\\175\\343\\221\\67\\237\\170\\364\\235\\207\\136\\172\\352\\255\\307\\136\\173\"\n\"\\356\\371\\367\\36\\174\\361\\311\\127\\136\\170\\373\\351\\147\\336\\175\"\n\"\\374\\341\\147\\137\\176\"\n\n\"koi8u\\0\"\n\"\\0\\40\"\n\"\\63\\323\\134\\263\\315\\67\\343\\234\\263\\316\\73\\363\\334\\363\\326\\134\\167\\355\\365\\327\"\n\"\\140\\207\\55\\166\\314\\143\\243\\234\\62\\313\\56\\277\\14\\212\\314\\260\\310\\162\\313\\75\"\n\"\\76\\377\\14\\364\\207\\42\\12\\115\\142\\211\\105\\33\\175\\64\\322\\111\\273\\270\\64\\323\"\n\"\\115\\73\\375\\164\\164\\324\\105\\155\\335\\165\\124\\127\\155\\365\\325\\130\\267\\250\\165\\52\"\n\"\\35\\376\\7\\140\\205\\3\\22\\70\\241\\200\\24\\36\\210\\140\\202\\12\\56\\310\\140\\203\"\n\"\\16\\172\\370\\40\\204\\21\\112\\130\\140\\200\\33\\152\\150\\340\\205\\34\\142\\150\\141\\206\"\n\"\\375\\175\\7\\136\\175\\343\\221\\67\\237\\170\\364\\235\\207\\136\\172\\352\\255\\307\\136\\173\"\n\"\\356\\371\\367\\36\\174\\361\\311\\127\\136\\170\\373\\351\\147\\336\\175\"\n\"\\374\\341\\147\\137\\176\"\n\n\"cp437\\0\"\n\"\\0\\40\"\n\"\\307\\360\\223\\216\\70\\344\\200\\123\\316\\71\\352\\254\\203\\316\\73\\356\\260\\103\\114\\61\"\n\"\\311\\230\\143\\14\\75\\366\\310\\263\\117\\76\\377\\130\\303\\215\\50\\243\\224\\22\\62\\135\"\n\"\\341\\264\\63\\217\\76\\361\\104\\243\\212\\56\\277\\300\\314\\112\\57\\274\\204\\262\\312\\56\"\n\"\\140\\207\\55\\66\\315\\72\\77\\15\\65\\321\\103\\107\\375\\163\\321\\113\\53\\235\\264\\315\"\n\"\\67\\363\\274\\163\\316\\63\\367\\314\\164\\323\\110\\13\\175\\65\\325\\116\\373\\254\\165\\325\"\n\"\\126\\113\\75\\365\\321\\106\\3\\35\\164\\326\\130\\343\\134\\163\\327\\134\\173\\375\\365\\326\"\n\"\\263\\175\\143\\231\\160\\245\\25\\127\\213\\161\\250\\155\\266\\232\\155\\52\\43\\167\\333\\312\"\n\"\\55\\307\\362\\262\\313\\61\\313\\174\\17\\313\\260\\240\\174\\113\\312\\40\\313\\62\\66\\50\"\n\n\"cp850\\0\"\n\"\\0\\40\"\n\"\\307\\360\\223\\216\\70\\344\\200\\123\\316\\71\\352\\254\\203\\316\\73\\356\\260\\103\\114\\61\"\n\"\\311\\230\\143\\14\\75\\366\\310\\263\\117\\76\\377\\130\\303\\15\\76\\243\\140\\163\\15\\135\"\n\"\\341\\264\\63\\217\\76\\361\\104\\243\\212\\56\\277\\270\\302\\112\\57\\274\\204\\262\\312\\56\"\n\"\\140\\207\\55\\66\\315\\72\\7\\43\\14\\60\\251\\104\\375\\163\\321\\113\\213\\122\\212\\315\"\n\"\\67\\363\\274\\163\\316\\63\\367\\74\\316\\60\\110\\13\\175\\65\\325\\116\\373\\254\\65\\51\"\n\"\\360\\100\\243\\314\\62\\310\\264\\324\\214\\63\\317\\340\\134\\163\\327\\134\\233\\302\\314\\326\"\n\"\\323\\174\\103\\215\\64\\365\\124\\123\\213\\77\\336\\150\\263\\115\\66\\375\\164\\363\\12\\55\"\n\"\\255\\304\\42\\261\\57\\266\\234\\162\\17\\56\\260\\240\\162\\113\\56\\263\\310\\62\\66\\50\"\n\n\"cp866\\0\"\n\"\\0\\40\"\n\"\\337\\201\\27\\236\\170\\343\\221\\127\\236\\171\\347\\241\\227\\236\\172\"\n\"\\353\\261\\327\\236\\173\\357\\301\\27\\237\\174\\363\\321\\127\\237\\175\"\n\"\\367\\341\\227\\237\\176\\373\\361\\327\\237\\177\\377\\1\\30\\240\\200\\3\\22\\130\\240\\201\"\n\"\\7\\42\\230\\240\\202\\13\\62\\330\\240\\203\\140\\207\\55\\66\\315\\72\\77\\15\\65\\321\"\n\"\\103\\107\\375\\163\\321\\113\\53\\235\\264\\315\\67\\363\\274\\163\\316\\63\\367\\314\\164\\323\"\n\"\\110\\13\\175\\65\\325\\116\\373\\254\\165\\325\\126\\113\\75\\365\\321\\106\\3\\35\\164\\326\"\n\"\\130\\343\\134\\163\\327\\134\\173\\375\\365\\326\\17\\102\\30\\241\\204\\23\\122\\130\\241\\205\"\n\"\\27\\142\\230\\241\\206\\33\\162\\330\\241\\207\\321\\175\\110\\235\\210\\327\\225\\330\\335\\212\"\n\"\\260\\240\\174\\113\\312\\46\\223\\62\\66\\50\"\n\n\"ibm1047\\0\"\n\"cp1047\\0\"\n\"\\0\\1\"\n\"\\234\\44\\140\\310\\37\\227\\64\\342\\310\\2\\14\\64\\340\\300\\3\\20\\104\\40\\301\\4\"\n\"\\235\\24\\202\\300\\41\\30\\144\\40\\311\\43\\34\\164\\340\\301\\7\\200\\4\\42\\310\\40\"\n\"\\204\\50\\160\\301\\6\\210\\44\\242\\310\\42\\214\\24\\140\\300\\1\\220\\104\\142\\301\\44\"\n\"\\224\\124\\142\\11\\1\\230\\144\\242\\311\\46\\24\\124\\340\\211\\6\\40\\200\\42\\16\\71\"\n\"\\340\\204\\63\\116\\71\\347\\304\\43\\212\\13\\74\\240\\260\\2\\37\\46\\244\\243\\316\\72\"\n\"\\350\\264\\343\\316\\73\\354\\174\\23\\2\\11\\52\\244\\260\\203\\27\\55\\274\\40\\14\\61\"\n\"\\300\\4\\63\\114\\61\\307\\104\\143\\12\\13\\45\\174\\341\\303\\17\\370\\44\\243\\314\\62\"\n\"\\310\\64\\343\\314\\63\\314\\200\\241\\303\\10\\100\\234\\320\\203\\10\\330\\204\\41\\306\\30\"\n\"\\144\\224\\141\\306\\31\\150\\244\\261\\312\\56\\360\\364\\343\\117\\54\\260\\250\\261\\6\\33\"\n\"\\155\\270\\361\\6\\34\\161\\310\\241\\212\\56\\346\\340\\142\\14\\51\\265\\370\\61\\7\\35\"\n\"\\165\\330\\161\\7\\36\\171\\350\\21\\312\\57\\320\\154\\341\\215\\53\\254\\214\\122\\312\\55\"\n\"\\251\\234\\142\\13\\57\\275\\370\\322\\15\\52\\257\\164\\101\\313\\65\\173\\4\\41\\304\\20\"\n\"\\104\\24\\141\\304\\21\\110\\44\\321\\12\\75\\366\\310\\63\\117\\75\\175\\50\\261\\4\\23\"\n\"\\115\\70\\361\\4\\24\\121\\110\\221\\313\\76\\374\\344\\243\\317\\77\\134\\334\\63\\5\\25\"\n\"\\125\\130\\161\\5\\26\\131\\150\\41\\13\\65\\326\\110\\63\\115\\65\\60\\304\\40\\303\\14\"\n\"\\64\\324\\140\\303\\15\\70\\344\\60\\313\\66\\334\\144\\243\\315\\47\"\n\n"
  },
  {
    "path": "user.libc/src/locale/dcngettext.c",
    "content": "#include <libintl.h>\n#include <stdlib.h>\n#include <string.h>\n#include <errno.h>\n#include <limits.h>\n#include <sys/stat.h>\n#include <sys/mman.h>\n#include <ctype.h>\n#include \"locale_impl.h\"\n#include \"atomic.h\"\n#include \"pleval.h\"\n#include \"lock.h\"\n#include \"fork_impl.h\"\n\n#define malloc __libc_malloc\n#define calloc __libc_calloc\n#define realloc undef\n#define free undef\n\nstruct binding {\n\tstruct binding *next;\n\tint dirlen;\n\tvolatile int active;\n\tchar *domainname;\n\tchar *dirname;\n\tchar buf[];\n};\n\nstatic void *volatile bindings;\n\nstatic char *gettextdir(const char *domainname, size_t *dirlen)\n{\n\tstruct binding *p;\n\tfor (p=bindings; p; p=p->next) {\n\t\tif (!strcmp(p->domainname, domainname) && p->active) {\n\t\t\t*dirlen = p->dirlen;\n\t\t\treturn (char *)p->dirname;\n\t\t}\n\t}\n\treturn 0;\n}\n\nstatic volatile int lock[1];\nvolatile int *const __gettext_lockptr = lock;\n\nchar *bindtextdomain(const char *domainname, const char *dirname)\n{\n\tstruct binding *p, *q;\n\n\tif (!domainname) return 0;\n\tif (!dirname) return gettextdir(domainname, &(size_t){0});\n\n\tsize_t domlen = strnlen(domainname, NAME_MAX+1);\n\tsize_t dirlen = strnlen(dirname, PATH_MAX);\n\tif (domlen > NAME_MAX || dirlen >= PATH_MAX) {\n\t\terrno = EINVAL;\n\t\treturn 0;\n\t}\n\n\tLOCK(lock);\n\n\tfor (p=bindings; p; p=p->next) {\n\t\tif (!strcmp(p->domainname, domainname) &&\n\t\t    !strcmp(p->dirname, dirname)) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!p) {\n\t\tp = calloc(sizeof *p + domlen + dirlen + 2, 1);\n\t\tif (!p) {\n\t\t\tUNLOCK(lock);\n\t\t\treturn 0;\n\t\t}\n\t\tp->next = bindings;\n\t\tp->dirlen = dirlen;\n\t\tp->domainname = p->buf;\n\t\tp->dirname = p->buf + domlen + 1;\n\t\tmemcpy(p->domainname, domainname, domlen+1);\n\t\tmemcpy(p->dirname, dirname, dirlen+1);\n\t\ta_cas_p(&bindings, bindings, p);\n\t}\n\n\ta_store(&p->active, 1);\n\n\tfor (q=bindings; q; q=q->next) {\n\t\tif (!strcmp(q->domainname, domainname) && q != p)\n\t\t\ta_store(&q->active, 0);\n\t}\n\n\tUNLOCK(lock);\n\t\n\treturn (char *)p->dirname;\n}\n\nstatic const char catnames[][12] = {\n\t\"LC_CTYPE\",\n\t\"LC_NUMERIC\",\n\t\"LC_TIME\",\n\t\"LC_COLLATE\",\n\t\"LC_MONETARY\",\n\t\"LC_MESSAGES\",\n};\n\nstatic const char catlens[] = { 8, 10, 7, 10, 11, 11 };\n\nstruct msgcat {\n\tstruct msgcat *next;\n\tconst void *map;\n\tsize_t map_size;\n\tconst char *plural_rule;\n\tint nplurals;\n\tstruct binding *binding;\n\tconst struct __locale_map *lm;\n\tint cat;\n};\n\nstatic char *dummy_gettextdomain()\n{\n\treturn \"messages\";\n}\n\nweak_alias(dummy_gettextdomain, __gettextdomain);\n\nchar *dcngettext(const char *domainname, const char *msgid1, const char *msgid2, unsigned long int n, int category)\n{\n\tstatic struct msgcat *volatile cats;\n\tstruct msgcat *p;\n\tstruct __locale_struct *loc = CURRENT_LOCALE;\n\tconst struct __locale_map *lm;\n\tsize_t domlen;\n\tstruct binding *q;\n\tint old_errno = errno;\n\n\tif ((unsigned)category >= LC_ALL) goto notrans;\n\n\tif (!domainname) domainname = __gettextdomain();\n\n\tdomlen = strnlen(domainname, NAME_MAX+1);\n\tif (domlen > NAME_MAX) goto notrans;\n\n\tfor (q=bindings; q; q=q->next)\n\t\tif (!strcmp(q->domainname, domainname) && q->active)\n\t\t\tbreak;\n\tif (!q) goto notrans;\n\n\tlm = loc->cat[category];\n\tif (!lm) {\nnotrans:\n\t\terrno = old_errno;\n\t\treturn (char *) ((n == 1) ? msgid1 : msgid2);\n\t}\n\n\tfor (p=cats; p; p=p->next)\n\t\tif (p->binding == q && p->lm == lm && p->cat == category)\n\t\t\tbreak;\n\n\tif (!p) {\n\t\tconst char *dirname, *locname, *catname, *modname, *locp;\n\t\tsize_t dirlen, loclen, catlen, modlen, alt_modlen;\n\t\tvoid *old_cats;\n\t\tsize_t map_size;\n\n\t\tdirname = q->dirname;\n\t\tlocname = lm->name;\n\t\tcatname = catnames[category];\n\n\t\tdirlen = q->dirlen;\n\t\tloclen = strlen(locname);\n\t\tcatlen = catlens[category];\n\n\t\t/* Logically split @mod suffix from locale name. */\n\t\tmodname = memchr(locname, '@', loclen);\n\t\tif (!modname) modname = locname + loclen;\n\t\talt_modlen = modlen = loclen - (modname-locname);\n\t\tloclen = modname-locname;\n\n\t\t/* Drop .charset identifier; it is not used. */\n\t\tconst char *csp = memchr(locname, '.', loclen);\n\t\tif (csp) loclen = csp-locname;\n\n\t\tchar name[dirlen+1 + loclen+modlen+1 + catlen+1 + domlen+3 + 1];\n\t\tconst void *map;\n\n\t\tfor (;;) {\n\t\t\tsnprintf(name, sizeof name, \"%s/%.*s%.*s/%s/%s.mo\\0\",\n\t\t\t\tdirname, (int)loclen, locname,\n\t\t\t\t(int)alt_modlen, modname, catname, domainname);\n\t\t\tif (map = __map_file(name, &map_size)) break;\n\n\t\t\t/* Try dropping @mod, _YY, then both. */\n\t\t\tif (alt_modlen) {\n\t\t\t\talt_modlen = 0;\n\t\t\t} else if ((locp = memchr(locname, '_', loclen))) {\n\t\t\t\tloclen = locp-locname;\n\t\t\t\talt_modlen = modlen;\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (!map) goto notrans;\n\n\t\tp = calloc(sizeof *p, 1);\n\t\tif (!p) {\n\t\t\t__munmap((void *)map, map_size);\n\t\t\tgoto notrans;\n\t\t}\n\t\tp->cat = category;\n\t\tp->binding = q;\n\t\tp->lm = lm;\n\t\tp->map = map;\n\t\tp->map_size = map_size;\n\n\t\tconst char *rule = \"n!=1;\";\n\t\tunsigned long np = 2;\n\t\tconst char *r = __mo_lookup(p->map, p->map_size, \"\");\n\t\tchar *z;\n\t\twhile (r && strncmp(r, \"Plural-Forms:\", 13)) {\n\t\t\tz = strchr(r, '\\n');\n\t\t\tr = z ? z+1 : 0;\n\t\t}\n\t\tif (r) {\n\t\t\tr += 13;\n\t\t\twhile (isspace(*r)) r++;\n\t\t\tif (!strncmp(r, \"nplurals=\", 9)) {\n\t\t\t\tnp = strtoul(r+9, &z, 10);\n\t\t\t\tr = z;\n\t\t\t}\n\t\t\twhile (*r && *r != ';') r++;\n\t\t\tif (*r) {\n\t\t\t\tr++;\n\t\t\t\twhile (isspace(*r)) r++;\n\t\t\t\tif (!strncmp(r, \"plural=\", 7))\n\t\t\t\t\trule = r+7;\n\t\t\t}\n\t\t}\n\t\tp->nplurals = np;\n\t\tp->plural_rule = rule;\n\n\t\tdo {\n\t\t\told_cats = cats;\n\t\t\tp->next = old_cats;\n\t\t} while (a_cas_p(&cats, old_cats, p) != old_cats);\n\t}\n\n\tconst char *trans = __mo_lookup(p->map, p->map_size, msgid1);\n\tif (!trans) goto notrans;\n\n\t/* Non-plural-processing gettext forms pass a null pointer as\n\t * msgid2 to request that dcngettext suppress plural processing. */\n\n\tif (msgid2 && p->nplurals) {\n\t\tunsigned long plural = __pleval(p->plural_rule, n);\n\t\tif (plural > p->nplurals) goto notrans;\n\t\twhile (plural--) {\n\t\t\tsize_t rem = p->map_size - (trans - (char *)p->map);\n\t\t\tsize_t l = strnlen(trans, rem);\n\t\t\tif (l+1 >= rem)\n\t\t\t\tgoto notrans;\n\t\t\ttrans += l+1;\n\t\t}\n\t}\n\terrno = old_errno;\n\treturn (char *)trans;\n}\n\nchar *dcgettext(const char *domainname, const char *msgid, int category)\n{\n\treturn dcngettext(domainname, msgid, 0, 1, category);\n}\n\nchar *dngettext(const char *domainname, const char *msgid1, const char *msgid2, unsigned long int n)\n{\n\treturn dcngettext(domainname, msgid1, msgid2, n, LC_MESSAGES);\n}\n\nchar *dgettext(const char *domainname, const char *msgid)\n{\n\treturn dcngettext(domainname, msgid, 0, 1, LC_MESSAGES);\n}\n"
  },
  {
    "path": "user.libc/src/locale/duplocale.c",
    "content": "#include <stdlib.h>\n#include <string.h>\n#include \"locale_impl.h\"\n#include \"libc.h\"\n\nlocale_t __duplocale(locale_t old)\n{\n\tlocale_t new = malloc(sizeof *new);\n\tif (!new) return 0;\n\tif (old == LC_GLOBAL_LOCALE) old = &libc.global_locale;\n\t*new = *old;\n\treturn new;\n}\n\nweak_alias(__duplocale, duplocale);\n"
  },
  {
    "path": "user.libc/src/locale/freelocale.c",
    "content": "#include <stdlib.h>\n#include \"locale_impl.h\"\n\n#define malloc undef\n#define calloc undef\n#define realloc undef\n#define free __libc_free\n\nvoid freelocale(locale_t l)\n{\n\tif (__loc_is_allocated(l)) free(l);\n}\n\nweak_alias(freelocale, __freelocale);\n"
  },
  {
    "path": "user.libc/src/locale/gb18030.h",
    "content": "19970,19972,19973,19974,19983,19986,19991,19999,20000,20001,20003,20006,20009,\n20014,20015,20017,20019,20021,20023,20028,20032,20033,20034,20036,20038,20042,\n20049,20053,20055,20058,20059,20066,20067,20068,20069,20071,20072,20074,20075,\n20076,20077,20078,20079,20082,20084,20085,20086,20087,20088,20089,20090,20091,\n20092,20093,20095,20096,20097,20098,20099,20100,20101,20103,20106,20112,20118,\n20119,20121,20124,20125,20126,20131,20138,20143,20144,20145,20148,20150,20151,\n20152,20153,20156,20157,20158,20168,20172,20175,20176,20178,20186,20187,20188,\n20192,20194,20198,20199,20201,20205,20206,20207,20209,20212,20216,20217,20218,\n20220,20222,20224,20226,20227,20228,20229,20230,20231,20232,20235,20236,20242,\n20243,20244,20245,20246,20252,20253,20257,20259,20264,20265,20268,20269,20270,\n20273,20275,20277,20279,20281,20283,20286,20287,20288,20289,20290,20292,20293,\n20295,20296,20297,20298,20299,20300,20306,20308,20310,20321,20322,20326,20328,\n20330,20331,20333,20334,20337,20338,20341,20343,20344,20345,20346,20349,20352,\n20353,20354,20357,20358,20359,20362,20364,20366,20368,20370,20371,20373,20374,\n20376,20377,20378,20380,20382,20383,20385,20386,20388,20395,20397,20400,20401,\n20402,20403,20404,20406,20407,20408,20409,20410,20411,20412,20413,20414,20416,\n20417,20418,20422,20423,20424,20425,20427,20428,20429,20434,20435,20436,20437,\n20438,20441,20443,20448,20450,20452,20453,20455,20459,20460,20464,20466,20468,\n20469,20470,20471,20473,20475,20476,20477,20479,20480,20481,20482,20483,20484,\n20485,20486,20487,20488,20489,20490,20491,20494,\n20496,20497,20499,20501,20502,20503,20507,20509,20510,20512,20514,20515,20516,\n20519,20523,20527,20528,20529,20530,20531,20532,20533,20534,20535,20536,20537,\n20539,20541,20543,20544,20545,20546,20548,20549,20550,20553,20554,20555,20557,\n20560,20561,20562,20563,20564,20566,20567,20568,20569,20571,20573,20574,20575,\n20576,20577,20578,20579,20580,20582,20583,20584,20585,20586,20587,20589,20590,\n20591,20592,20593,20594,20595,20596,20597,20600,20601,20602,20604,20605,20609,\n20610,20611,20612,20614,20615,20617,20618,20619,20620,20622,20623,20624,20625,\n20626,20627,20628,20629,20630,20631,20632,20633,20634,20635,20636,20637,20638,\n20639,20640,20641,20642,20644,20646,20650,20651,20653,20654,20655,20656,20657,\n20659,20660,20661,20662,20663,20664,20665,20668,20669,20670,20671,20672,20673,\n20674,20675,20676,20677,20678,20679,20680,20681,20682,20683,20684,20685,20686,\n20688,20689,20690,20691,20692,20693,20695,20696,20697,20699,20700,20701,20702,\n20703,20704,20705,20706,20707,20708,20709,20712,20713,20714,20715,20719,20720,\n20721,20722,20724,20726,20727,20728,20729,20730,20732,20733,20734,20735,20736,\n20737,20738,20739,20740,20741,20744,20745,20746,20748,20749,20750,20751,20752,\n20753,20755,20756,20757,20758,20759,20760,20761,20762,20763,20764,20765,20766,\n20767,20768,20770,20771,20772,20773,20774,20775,20776,20777,20778,20779,20780,\n20781,20782,20783,20784,20785,20786,20787,20788,20789,20790,20791,20792,20793,\n20794,20795,20796,20797,20798,20802,20807,20810,20812,20814,20815,20816,20818,\n20819,20823,20824,20825,20827,20829,20830,20831,20832,\n20833,20835,20836,20838,20839,20841,20842,20847,20850,20858,20862,20863,20867,\n20868,20870,20871,20874,20875,20878,20879,20880,20881,20883,20884,20888,20890,\n20893,20894,20895,20897,20899,20902,20903,20904,20905,20906,20909,20910,20916,\n20920,20921,20922,20926,20927,20929,20930,20931,20933,20936,20938,20941,20942,\n20944,20946,20947,20948,20949,20950,20951,20952,20953,20954,20956,20958,20959,\n20962,20963,20965,20966,20967,20968,20969,20970,20972,20974,20977,20978,20980,\n20983,20990,20996,20997,21001,21003,21004,21007,21008,21011,21012,21013,21020,\n21022,21023,21025,21026,21027,21029,21030,21031,21034,21036,21039,21041,21042,\n21044,21045,21052,21054,21060,21061,21062,21063,21064,21065,21067,21070,21071,\n21074,21075,21077,21079,21080,21081,21082,21083,21085,21087,21088,21090,21091,\n21092,21094,21096,21099,21100,21101,21102,21104,21105,21107,21108,21109,21110,\n21111,21112,21113,21114,21115,21116,21118,21120,21123,21124,21125,21126,21127,\n21129,21130,21131,21132,21133,21134,21135,21137,21138,21140,21141,21142,21143,\n21144,21145,21146,21148,21156,21157,21158,21159,21166,21167,21168,21172,21173,\n21174,21175,21176,21177,21178,21179,21180,21181,21184,21185,21186,21188,21189,\n21190,21192,21194,21196,21197,21198,21199,21201,21203,21204,21205,21207,21209,\n21210,21211,21212,21213,21214,21216,21217,21218,21219,21221,21222,21223,21224,\n21225,21226,21227,21228,21229,21230,21231,21233,21234,21235,21236,21237,21238,\n21239,21240,21243,21244,21245,21249,21250,21251,21252,21255,21257,21258,21259,\n21260,21262,21265,21266,21267,21268,21272,21275,21276,\n21278,21279,21282,21284,21285,21287,21288,21289,21291,21292,21293,21295,21296,\n21297,21298,21299,21300,21301,21302,21303,21304,21308,21309,21312,21314,21316,\n21318,21323,21324,21325,21328,21332,21336,21337,21339,21341,21349,21352,21354,\n21356,21357,21362,21366,21369,21371,21372,21373,21374,21376,21377,21379,21383,\n21384,21386,21390,21391,21392,21393,21394,21395,21396,21398,21399,21401,21403,\n21404,21406,21408,21409,21412,21415,21418,21419,21420,21421,21423,21424,21425,\n21426,21427,21428,21429,21431,21432,21433,21434,21436,21437,21438,21440,21443,\n21444,21445,21446,21447,21454,21455,21456,21458,21459,21461,21466,21468,21469,\n21470,21473,21474,21479,21492,21498,21502,21503,21504,21506,21509,21511,21515,\n21524,21528,21529,21530,21532,21538,21540,21541,21546,21552,21555,21558,21559,\n21562,21565,21567,21569,21570,21572,21573,21575,21577,21580,21581,21582,21583,\n21585,21594,21597,21598,21599,21600,21601,21603,21605,21607,21609,21610,21611,\n21612,21613,21614,21615,21616,21620,21625,21626,21630,21631,21633,21635,21637,\n21639,21640,21641,21642,21645,21649,21651,21655,21656,21660,21662,21663,21664,\n21665,21666,21669,21678,21680,21682,21685,21686,21687,21689,21690,21692,21694,\n21699,21701,21706,21707,21718,21720,21723,21728,21729,21730,21731,21732,21739,\n21740,21743,21744,21745,21748,21749,21750,21751,21752,21753,21755,21758,21760,\n21762,21763,21764,21765,21768,21770,21771,21772,21773,21774,21778,21779,21781,\n21782,21783,21784,21785,21786,21788,21789,21790,21791,21793,21797,21798,21800,\n21801,21803,21805,21810,21812,21813,21814,21816,21817,\n21818,21819,21821,21824,21826,21829,21831,21832,21835,21836,21837,21838,21839,\n21841,21842,21843,21844,21847,21848,21849,21850,21851,21853,21854,21855,21856,\n21858,21859,21864,21865,21867,21871,21872,21873,21874,21875,21876,21881,21882,\n21885,21887,21893,21894,21900,21901,21902,21904,21906,21907,21909,21910,21911,\n21914,21915,21918,21920,21921,21922,21923,21924,21925,21926,21928,21929,21930,\n21931,21932,21933,21934,21935,21936,21938,21940,21942,21944,21946,21948,21951,\n21952,21953,21954,21955,21958,21959,21960,21962,21963,21966,21967,21968,21973,\n21975,21976,21977,21978,21979,21982,21984,21986,21991,21993,21997,21998,22000,\n22001,22004,22006,22008,22009,22010,22011,22012,22015,22018,22019,22020,22021,\n22022,22023,22026,22027,22029,22032,22033,22034,22035,22036,22037,22038,22039,\n22041,22042,22044,22045,22048,22049,22050,22053,22054,22056,22057,22058,22059,\n22062,22063,22064,22067,22069,22071,22072,22074,22076,22077,22078,22080,22081,\n22082,22083,22084,22085,22086,22087,22088,22089,22090,22091,22095,22096,22097,\n22098,22099,22101,22102,22106,22107,22109,22110,22111,22112,22113,22115,22117,\n22118,22119,22125,22126,22127,22128,22130,22131,22132,22133,22135,22136,22137,\n22138,22141,22142,22143,22144,22145,22146,22147,22148,22151,22152,22153,22154,\n22155,22156,22157,22160,22161,22162,22164,22165,22166,22167,22168,22169,22170,\n22171,22172,22173,22174,22175,22176,22177,22178,22180,22181,22182,22183,22184,\n22185,22186,22187,22188,22189,22190,22192,22193,22194,22195,22196,22197,22198,\n22200,22201,22202,22203,22205,22206,22207,22208,22209,\n22210,22211,22212,22213,22214,22215,22216,22217,22219,22220,22221,22222,22223,\n22224,22225,22226,22227,22229,22230,22232,22233,22236,22243,22245,22246,22247,\n22248,22249,22250,22252,22254,22255,22258,22259,22262,22263,22264,22267,22268,\n22272,22273,22274,22277,22279,22283,22284,22285,22286,22287,22288,22289,22290,\n22291,22292,22293,22294,22295,22296,22297,22298,22299,22301,22302,22304,22305,\n22306,22308,22309,22310,22311,22315,22321,22322,22324,22325,22326,22327,22328,\n22332,22333,22335,22337,22339,22340,22341,22342,22344,22345,22347,22354,22355,\n22356,22357,22358,22360,22361,22370,22371,22373,22375,22380,22382,22384,22385,\n22386,22388,22389,22392,22393,22394,22397,22398,22399,22400,22401,22407,22408,\n22409,22410,22413,22414,22415,22416,22417,22420,22421,22422,22423,22424,22425,\n22426,22428,22429,22430,22431,22437,22440,22442,22444,22447,22448,22449,22451,\n22453,22454,22455,22457,22458,22459,22460,22461,22462,22463,22464,22465,22468,\n22469,22470,22471,22472,22473,22474,22476,22477,22480,22481,22483,22486,22487,\n22491,22492,22494,22497,22498,22499,22501,22502,22503,22504,22505,22506,22507,\n22508,22510,22512,22513,22514,22515,22517,22518,22519,22523,22524,22526,22527,\n22529,22531,22532,22533,22536,22537,22538,22540,22542,22543,22544,22546,22547,\n22548,22550,22551,22552,22554,22555,22556,22557,22559,22562,22563,22565,22566,\n22567,22568,22569,22571,22572,22573,22574,22575,22577,22578,22579,22580,22582,\n22583,22584,22585,22586,22587,22588,22589,22590,22591,22592,22593,22594,22595,\n22597,22598,22599,22600,22601,22602,22603,22606,22607,\n22608,22610,22611,22613,22614,22615,22617,22618,22619,22620,22621,22623,22624,\n22625,22626,22627,22628,22630,22631,22632,22633,22634,22637,22638,22639,22640,\n22641,22642,22643,22644,22645,22646,22647,22648,22649,22650,22651,22652,22653,\n22655,22658,22660,22662,22663,22664,22666,22667,22668,22669,22670,22671,22672,\n22673,22676,22677,22678,22679,22680,22683,22684,22685,22688,22689,22690,22691,\n22692,22693,22694,22695,22698,22699,22700,22701,22702,22703,22704,22705,22706,\n22707,22708,22709,22710,22711,22712,22713,22714,22715,22717,22718,22719,22720,\n22722,22723,22724,22726,22727,22728,22729,22730,22731,22732,22733,22734,22735,\n22736,22738,22739,22740,22742,22743,22744,22745,22746,22747,22748,22749,22750,\n22751,22752,22753,22754,22755,22757,22758,22759,22760,22761,22762,22765,22767,\n22769,22770,22772,22773,22775,22776,22778,22779,22780,22781,22782,22783,22784,\n22785,22787,22789,22790,22792,22793,22794,22795,22796,22798,22800,22801,22802,\n22803,22807,22808,22811,22813,22814,22816,22817,22818,22819,22822,22824,22828,\n22832,22834,22835,22837,22838,22843,22845,22846,22847,22848,22851,22853,22854,\n22858,22860,22861,22864,22866,22867,22873,22875,22876,22877,22878,22879,22881,\n22883,22884,22886,22887,22888,22889,22890,22891,22892,22893,22894,22895,22896,\n22897,22898,22901,22903,22906,22907,22908,22910,22911,22912,22917,22921,22923,\n22924,22926,22927,22928,22929,22932,22933,22936,22938,22939,22940,22941,22943,\n22944,22945,22946,22950,22951,22956,22957,22960,22961,22963,22964,22965,22966,\n22967,22968,22970,22972,22973,22975,22976,22977,22978,\n22979,22980,22981,22983,22984,22985,22988,22989,22990,22991,22997,22998,23001,\n23003,23006,23007,23008,23009,23010,23012,23014,23015,23017,23018,23019,23021,\n23022,23023,23024,23025,23026,23027,23028,23029,23030,23031,23032,23034,23036,\n23037,23038,23040,23042,23050,23051,23053,23054,23055,23056,23058,23060,23061,\n23062,23063,23065,23066,23067,23069,23070,23073,23074,23076,23078,23079,23080,\n23082,23083,23084,23085,23086,23087,23088,23091,23093,23095,23096,23097,23098,\n23099,23101,23102,23103,23105,23106,23107,23108,23109,23111,23112,23115,23116,\n23117,23118,23119,23120,23121,23122,23123,23124,23126,23127,23128,23129,23131,\n23132,23133,23134,23135,23136,23137,23139,23140,23141,23142,23144,23145,23147,\n23148,23149,23150,23151,23152,23153,23154,23155,23160,23161,23163,23164,23165,\n23166,23168,23169,23170,23171,23172,23173,23174,23175,23176,23177,23178,23179,\n23180,23181,23182,23183,23184,23185,23187,23188,23189,23190,23191,23192,23193,\n23196,23197,23198,23199,23200,23201,23202,23203,23204,23205,23206,23207,23208,\n23209,23211,23212,23213,23214,23215,23216,23217,23220,23222,23223,23225,23226,\n23227,23228,23229,23231,23232,23235,23236,23237,23238,23239,23240,23242,23243,\n23245,23246,23247,23248,23249,23251,23253,23255,23257,23258,23259,23261,23262,\n23263,23266,23268,23269,23271,23272,23274,23276,23277,23278,23279,23280,23282,\n23283,23284,23285,23286,23287,23288,23289,23290,23291,23292,23293,23294,23295,\n23296,23297,23298,23299,23300,23301,23302,23303,23304,23306,23307,23308,23309,\n23310,23311,23312,23313,23314,23315,23316,23317,23320,\n23321,23322,23323,23324,23325,23326,23327,23328,23329,23330,23331,23332,23333,\n23334,23335,23336,23337,23338,23339,23340,23341,23342,23343,23344,23345,23347,\n23349,23350,23352,23353,23354,23355,23356,23357,23358,23359,23361,23362,23363,\n23364,23365,23366,23367,23368,23369,23370,23371,23372,23373,23374,23375,23378,\n23382,23390,23392,23393,23399,23400,23403,23405,23406,23407,23410,23412,23414,\n23415,23416,23417,23419,23420,23422,23423,23426,23430,23434,23437,23438,23440,\n23441,23442,23444,23446,23455,23463,23464,23465,23468,23469,23470,23471,23473,\n23474,23479,23482,23483,23484,23488,23489,23491,23496,23497,23498,23499,23501,\n23502,23503,23505,23508,23509,23510,23511,23512,23513,23514,23515,23516,23520,\n23522,23523,23526,23527,23529,23530,23531,23532,23533,23535,23537,23538,23539,\n23540,23541,23542,23543,23549,23550,23552,23554,23555,23557,23559,23560,23563,\n23564,23565,23566,23568,23570,23571,23575,23577,23579,23582,23583,23584,23585,\n23587,23590,23592,23593,23594,23595,23597,23598,23599,23600,23602,23603,23605,\n23606,23607,23619,23620,23622,23623,23628,23629,23634,23635,23636,23638,23639,\n23640,23642,23643,23644,23645,23647,23650,23652,23655,23656,23657,23658,23659,\n23660,23661,23664,23666,23667,23668,23669,23670,23671,23672,23675,23676,23677,\n23678,23680,23683,23684,23685,23686,23687,23689,23690,23691,23694,23695,23698,\n23699,23701,23709,23710,23711,23712,23713,23716,23717,23718,23719,23720,23722,\n23726,23727,23728,23730,23732,23734,23737,23738,23739,23740,23742,23744,23746,\n23747,23749,23750,23751,23752,23753,23754,23756,23757,\n23758,23759,23760,23761,23763,23764,23765,23766,23767,23768,23770,23771,23772,\n23773,23774,23775,23776,23778,23779,23783,23785,23787,23788,23790,23791,23793,\n23794,23795,23796,23797,23798,23799,23800,23801,23802,23804,23805,23806,23807,\n23808,23809,23812,23813,23816,23817,23818,23819,23820,23821,23823,23824,23825,\n23826,23827,23829,23831,23832,23833,23834,23836,23837,23839,23840,23841,23842,\n23843,23845,23848,23850,23851,23852,23855,23856,23857,23858,23859,23861,23862,\n23863,23864,23865,23866,23867,23868,23871,23872,23873,23874,23875,23876,23877,\n23878,23880,23881,23885,23886,23887,23888,23889,23890,23891,23892,23893,23894,\n23895,23897,23898,23900,23902,23903,23904,23905,23906,23907,23908,23909,23910,\n23911,23912,23914,23917,23918,23920,23921,23922,23923,23925,23926,23927,23928,\n23929,23930,23931,23932,23933,23934,23935,23936,23937,23939,23940,23941,23942,\n23943,23944,23945,23946,23947,23948,23949,23950,23951,23952,23953,23954,23955,\n23956,23957,23958,23959,23960,23962,23963,23964,23966,23967,23968,23969,23970,\n23971,23972,23973,23974,23975,23976,23977,23978,23979,23980,23981,23982,23983,\n23984,23985,23986,23987,23988,23989,23990,23992,23993,23994,23995,23996,23997,\n23998,23999,24000,24001,24002,24003,24004,24006,24007,24008,24009,24010,24011,\n24012,24014,24015,24016,24017,24018,24019,24020,24021,24022,24023,24024,24025,\n24026,24028,24031,24032,24035,24036,24042,24044,24045,24048,24053,24054,24056,\n24057,24058,24059,24060,24063,24064,24068,24071,24073,24074,24075,24077,24078,\n24082,24083,24087,24094,24095,24096,24097,24098,24099,\n24100,24101,24104,24105,24106,24107,24108,24111,24112,24114,24115,24116,24117,\n24118,24121,24122,24126,24127,24128,24129,24131,24134,24135,24136,24137,24138,\n24139,24141,24142,24143,24144,24145,24146,24147,24150,24151,24152,24153,24154,\n24156,24157,24159,24160,24163,24164,24165,24166,24167,24168,24169,24170,24171,\n24172,24173,24174,24175,24176,24177,24181,24183,24185,24190,24193,24194,24195,\n24197,24200,24201,24204,24205,24206,24210,24216,24219,24221,24225,24226,24227,\n24228,24232,24233,24234,24235,24236,24238,24239,24240,24241,24242,24244,24250,\n24251,24252,24253,24255,24256,24257,24258,24259,24260,24261,24262,24263,24264,\n24267,24268,24269,24270,24271,24272,24276,24277,24279,24280,24281,24282,24284,\n24285,24286,24287,24288,24289,24290,24291,24292,24293,24294,24295,24297,24299,\n24300,24301,24302,24303,24304,24305,24306,24307,24309,24312,24313,24315,24316,\n24317,24325,24326,24327,24329,24332,24333,24334,24336,24338,24340,24342,24345,\n24346,24348,24349,24350,24353,24354,24355,24356,24360,24363,24364,24366,24368,\n24370,24371,24372,24373,24374,24375,24376,24379,24381,24382,24383,24385,24386,\n24387,24388,24389,24390,24391,24392,24393,24394,24395,24396,24397,24398,24399,\n24401,24404,24409,24410,24411,24412,24414,24415,24416,24419,24421,24423,24424,\n24427,24430,24431,24434,24436,24437,24438,24440,24442,24445,24446,24447,24451,\n24454,24461,24462,24463,24465,24467,24468,24470,24474,24475,24477,24478,24479,\n24480,24482,24483,24484,24485,24486,24487,24489,24491,24492,24495,24496,24497,\n24498,24499,24500,24502,24504,24505,24506,24507,24510,\n24511,24512,24513,24514,24519,24520,24522,24523,24526,24531,24532,24533,24538,\n24539,24540,24542,24543,24546,24547,24549,24550,24552,24553,24556,24559,24560,\n24562,24563,24564,24566,24567,24569,24570,24572,24583,24584,24585,24587,24588,\n24592,24593,24595,24599,24600,24602,24606,24607,24610,24611,24612,24620,24621,\n24622,24624,24625,24626,24627,24628,24630,24631,24632,24633,24634,24637,24638,\n24640,24644,24645,24646,24647,24648,24649,24650,24652,24654,24655,24657,24659,\n24660,24662,24663,24664,24667,24668,24670,24671,24672,24673,24677,24678,24686,\n24689,24690,24692,24693,24695,24702,24704,24705,24706,24709,24710,24711,24712,\n24714,24715,24718,24719,24720,24721,24723,24725,24727,24728,24729,24732,24734,\n24737,24738,24740,24741,24743,24745,24746,24750,24752,24755,24757,24758,24759,\n24761,24762,24765,24766,24767,24768,24769,24770,24771,24772,24775,24776,24777,\n24780,24781,24782,24783,24784,24786,24787,24788,24790,24791,24793,24795,24798,\n24801,24802,24803,24804,24805,24810,24817,24818,24821,24823,24824,24827,24828,\n24829,24830,24831,24834,24835,24836,24837,24839,24842,24843,24844,24848,24849,\n24850,24851,24852,24854,24855,24856,24857,24859,24860,24861,24862,24865,24866,\n24869,24872,24873,24874,24876,24877,24878,24879,24880,24881,24882,24883,24884,\n24885,24886,24887,24888,24889,24890,24891,24892,24893,24894,24896,24897,24898,\n24899,24900,24901,24902,24903,24905,24907,24909,24911,24912,24914,24915,24916,\n24918,24919,24920,24921,24922,24923,24924,24926,24927,24928,24929,24931,24932,\n24933,24934,24937,24938,24939,24940,24941,24942,24943,\n24945,24946,24947,24948,24950,24952,24953,24954,24955,24956,24957,24958,24959,\n24960,24961,24962,24963,24964,24965,24966,24967,24968,24969,24970,24972,24973,\n24975,24976,24977,24978,24979,24981,24982,24983,24984,24985,24986,24987,24988,\n24990,24991,24992,24993,24994,24995,24996,24997,24998,25002,25003,25005,25006,\n25007,25008,25009,25010,25011,25012,25013,25014,25016,25017,25018,25019,25020,\n25021,25023,25024,25025,25027,25028,25029,25030,25031,25033,25036,25037,25038,\n25039,25040,25043,25045,25046,25047,25048,25049,25050,25051,25052,25053,25054,\n25055,25056,25057,25058,25059,25060,25061,25063,25064,25065,25066,25067,25068,\n25069,25070,25071,25072,25073,25074,25075,25076,25078,25079,25080,25081,25082,\n25083,25084,25085,25086,25088,25089,25090,25091,25092,25093,25095,25097,25107,\n25108,25113,25116,25117,25118,25120,25123,25126,25127,25128,25129,25131,25133,\n25135,25136,25137,25138,25141,25142,25144,25145,25146,25147,25148,25154,25156,\n25157,25158,25162,25167,25168,25173,25174,25175,25177,25178,25180,25181,25182,\n25183,25184,25185,25186,25188,25189,25192,25201,25202,25204,25205,25207,25208,\n25210,25211,25213,25217,25218,25219,25221,25222,25223,25224,25227,25228,25229,\n25230,25231,25232,25236,25241,25244,25245,25246,25251,25254,25255,25257,25258,\n25261,25262,25263,25264,25266,25267,25268,25270,25271,25272,25274,25278,25280,\n25281,25283,25291,25295,25297,25301,25309,25310,25312,25313,25316,25322,25323,\n25328,25330,25333,25336,25337,25338,25339,25344,25347,25348,25349,25350,25354,\n25355,25356,25357,25359,25360,25362,25363,25364,25365,\n25367,25368,25369,25372,25382,25383,25385,25388,25389,25390,25392,25393,25395,\n25396,25397,25398,25399,25400,25403,25404,25406,25407,25408,25409,25412,25415,\n25416,25418,25425,25426,25427,25428,25430,25431,25432,25433,25434,25435,25436,\n25437,25440,25444,25445,25446,25448,25450,25451,25452,25455,25456,25458,25459,\n25460,25461,25464,25465,25468,25469,25470,25471,25473,25475,25476,25477,25478,\n25483,25485,25489,25491,25492,25493,25495,25497,25498,25499,25500,25501,25502,\n25503,25505,25508,25510,25515,25519,25521,25522,25525,25526,25529,25531,25533,\n25535,25536,25537,25538,25539,25541,25543,25544,25546,25547,25548,25553,25555,\n25556,25557,25559,25560,25561,25562,25563,25564,25565,25567,25570,25572,25573,\n25574,25575,25576,25579,25580,25582,25583,25584,25585,25587,25589,25591,25593,\n25594,25595,25596,25598,25603,25604,25606,25607,25608,25609,25610,25613,25614,\n25617,25618,25621,25622,25623,25624,25625,25626,25629,25631,25634,25635,25636,\n25637,25639,25640,25641,25643,25646,25647,25648,25649,25650,25651,25653,25654,\n25655,25656,25657,25659,25660,25662,25664,25666,25667,25673,25675,25676,25677,\n25678,25679,25680,25681,25683,25685,25686,25687,25689,25690,25691,25692,25693,\n25695,25696,25697,25698,25699,25700,25701,25702,25704,25706,25707,25708,25710,\n25711,25712,25713,25714,25715,25716,25717,25718,25719,25723,25724,25725,25726,\n25727,25728,25729,25731,25734,25736,25737,25738,25739,25740,25741,25742,25743,\n25744,25747,25748,25751,25752,25754,25755,25756,25757,25759,25760,25761,25762,\n25763,25765,25766,25767,25768,25770,25771,25775,25777,\n25778,25779,25780,25782,25785,25787,25789,25790,25791,25793,25795,25796,25798,\n25799,25800,25801,25802,25803,25804,25807,25809,25811,25812,25813,25814,25817,\n25818,25819,25820,25821,25823,25824,25825,25827,25829,25831,25832,25833,25834,\n25835,25836,25837,25838,25839,25840,25841,25842,25843,25844,25845,25846,25847,\n25848,25849,25850,25851,25852,25853,25854,25855,25857,25858,25859,25860,25861,\n25862,25863,25864,25866,25867,25868,25869,25870,25871,25872,25873,25875,25876,\n25877,25878,25879,25881,25882,25883,25884,25885,25886,25887,25888,25889,25890,\n25891,25892,25894,25895,25896,25897,25898,25900,25901,25904,25905,25906,25907,\n25911,25914,25916,25917,25920,25921,25922,25923,25924,25926,25927,25930,25931,\n25933,25934,25936,25938,25939,25940,25943,25944,25946,25948,25951,25952,25953,\n25956,25957,25959,25960,25961,25962,25965,25966,25967,25969,25971,25973,25974,\n25976,25977,25978,25979,25980,25981,25982,25983,25984,25985,25986,25987,25988,\n25989,25990,25992,25993,25994,25997,25998,25999,26002,26004,26005,26006,26008,\n26010,26013,26014,26016,26018,26019,26022,26024,26026,26028,26030,26033,26034,\n26035,26036,26037,26038,26039,26040,26042,26043,26046,26047,26048,26050,26055,\n26056,26057,26058,26061,26064,26065,26067,26068,26069,26072,26073,26074,26075,\n26076,26077,26078,26079,26081,26083,26084,26090,26091,26098,26099,26100,26101,\n26104,26105,26107,26108,26109,26110,26111,26113,26116,26117,26119,26120,26121,\n26123,26125,26128,26129,26130,26134,26135,26136,26138,26139,26140,26142,26145,\n26146,26147,26148,26150,26153,26154,26155,26156,26158,\n26160,26162,26163,26167,26168,26169,26170,26171,26173,26175,26176,26178,26180,\n26181,26182,26183,26184,26185,26186,26189,26190,26192,26193,26200,26201,26203,\n26204,26205,26206,26208,26210,26211,26213,26215,26217,26218,26219,26220,26221,\n26225,26226,26227,26229,26232,26233,26235,26236,26237,26239,26240,26241,26243,\n26245,26246,26248,26249,26250,26251,26253,26254,26255,26256,26258,26259,26260,\n26261,26264,26265,26266,26267,26268,26270,26271,26272,26273,26274,26275,26276,\n26277,26278,26281,26282,26283,26284,26285,26287,26288,26289,26290,26291,26293,\n26294,26295,26296,26298,26299,26300,26301,26303,26304,26305,26306,26307,26308,\n26309,26310,26311,26312,26313,26314,26315,26316,26317,26318,26319,26320,26321,\n26322,26323,26324,26325,26326,26327,26328,26330,26334,26335,26336,26337,26338,\n26339,26340,26341,26343,26344,26346,26347,26348,26349,26350,26351,26353,26357,\n26358,26360,26362,26363,26365,26369,26370,26371,26372,26373,26374,26375,26380,\n26382,26383,26385,26386,26387,26390,26392,26393,26394,26396,26398,26400,26401,\n26402,26403,26404,26405,26407,26409,26414,26416,26418,26419,26422,26423,26424,\n26425,26427,26428,26430,26431,26433,26436,26437,26439,26442,26443,26445,26450,\n26452,26453,26455,26456,26457,26458,26459,26461,26466,26467,26468,26470,26471,\n26475,26476,26478,26481,26484,26486,26488,26489,26490,26491,26493,26496,26498,\n26499,26501,26502,26504,26506,26508,26509,26510,26511,26513,26514,26515,26516,\n26518,26521,26523,26527,26528,26529,26532,26534,26537,26540,26542,26545,26546,\n26548,26553,26554,26555,26556,26557,26558,26559,26560,\n26562,26565,26566,26567,26568,26569,26570,26571,26572,26573,26574,26581,26582,\n26583,26587,26591,26593,26595,26596,26598,26599,26600,26602,26603,26605,26606,\n26610,26613,26614,26615,26616,26617,26618,26619,26620,26622,26625,26626,26627,\n26628,26630,26637,26640,26642,26644,26645,26648,26649,26650,26651,26652,26654,\n26655,26656,26658,26659,26660,26661,26662,26663,26664,26667,26668,26669,26670,\n26671,26672,26673,26676,26677,26678,26682,26683,26687,26695,26699,26701,26703,\n26706,26710,26711,26712,26713,26714,26715,26716,26717,26718,26719,26730,26732,\n26733,26734,26735,26736,26737,26738,26739,26741,26744,26745,26746,26747,26748,\n26749,26750,26751,26752,26754,26756,26759,26760,26761,26762,26763,26764,26765,\n26766,26768,26769,26770,26772,26773,26774,26776,26777,26778,26779,26780,26781,\n26782,26783,26784,26785,26787,26788,26789,26793,26794,26795,26796,26798,26801,\n26802,26804,26806,26807,26808,26809,26810,26811,26812,26813,26814,26815,26817,\n26819,26820,26821,26822,26823,26824,26826,26828,26830,26831,26832,26833,26835,\n26836,26838,26839,26841,26843,26844,26845,26846,26847,26849,26850,26852,26853,\n26854,26855,26856,26857,26858,26859,26860,26861,26863,26866,26867,26868,26870,\n26871,26872,26875,26877,26878,26879,26880,26882,26883,26884,26886,26887,26888,\n26889,26890,26892,26895,26897,26899,26900,26901,26902,26903,26904,26905,26906,\n26907,26908,26909,26910,26913,26914,26915,26917,26918,26919,26920,26921,26922,\n26923,26924,26926,26927,26929,26930,26931,26933,26934,26935,26936,26938,26939,\n26940,26942,26944,26945,26947,26948,26949,26950,26951,\n26952,26953,26954,26955,26956,26957,26958,26959,26960,26961,26962,26963,26965,\n26966,26968,26969,26971,26972,26975,26977,26978,26980,26981,26983,26984,26985,\n26986,26988,26989,26991,26992,26994,26995,26996,26997,26998,27002,27003,27005,\n27006,27007,27009,27011,27013,27018,27019,27020,27022,27023,27024,27025,27026,\n27027,27030,27031,27033,27034,27037,27038,27039,27040,27041,27042,27043,27044,\n27045,27046,27049,27050,27052,27054,27055,27056,27058,27059,27061,27062,27064,\n27065,27066,27068,27069,27070,27071,27072,27074,27075,27076,27077,27078,27079,\n27080,27081,27083,27085,27087,27089,27090,27091,27093,27094,27095,27096,27097,\n27098,27100,27101,27102,27105,27106,27107,27108,27109,27110,27111,27112,27113,\n27114,27115,27116,27118,27119,27120,27121,27123,27124,27125,27126,27127,27128,\n27129,27130,27131,27132,27134,27136,27137,27138,27139,27140,27141,27142,27143,\n27144,27145,27147,27148,27149,27150,27151,27152,27153,27154,27155,27156,27157,\n27158,27161,27162,27163,27164,27165,27166,27168,27170,27171,27172,27173,27174,\n27175,27177,27179,27180,27181,27182,27184,27186,27187,27188,27190,27191,27192,\n27193,27194,27195,27196,27199,27200,27201,27202,27203,27205,27206,27208,27209,\n27210,27211,27212,27213,27214,27215,27217,27218,27219,27220,27221,27222,27223,\n27226,27228,27229,27230,27231,27232,27234,27235,27236,27238,27239,27240,27241,\n27242,27243,27244,27245,27246,27247,27248,27250,27251,27252,27253,27254,27255,\n27256,27258,27259,27261,27262,27263,27265,27266,27267,27269,27270,27271,27272,\n27273,27274,27275,27276,27277,27279,27282,27283,27284,\n27285,27286,27288,27289,27290,27291,27292,27293,27294,27295,27297,27298,27299,\n27300,27301,27302,27303,27304,27306,27309,27310,27311,27312,27313,27314,27315,\n27316,27317,27318,27319,27320,27321,27322,27323,27324,27325,27326,27327,27328,\n27329,27330,27331,27332,27333,27334,27335,27336,27337,27338,27339,27340,27341,\n27342,27343,27344,27345,27346,27347,27348,27349,27350,27351,27352,27353,27354,\n27355,27356,27357,27358,27359,27360,27361,27362,27363,27364,27365,27366,27367,\n27368,27369,27370,27371,27372,27373,27374,27375,27376,27377,27378,27379,27380,\n27381,27382,27383,27384,27385,27386,27387,27388,27389,27390,27391,27392,27393,\n27394,27395,27396,27397,27398,27399,27400,27401,27402,27403,27404,27405,27406,\n27407,27408,27409,27410,27411,27412,27413,27414,27415,27416,27417,27418,27419,\n27420,27421,27422,27423,27429,27430,27432,27433,27434,27435,27436,27437,27438,\n27439,27440,27441,27443,27444,27445,27446,27448,27451,27452,27453,27455,27456,\n27457,27458,27460,27461,27464,27466,27467,27469,27470,27471,27472,27473,27474,\n27475,27476,27477,27478,27479,27480,27482,27483,27484,27485,27486,27487,27488,\n27489,27496,27497,27499,27500,27501,27502,27503,27504,27505,27506,27507,27508,\n27509,27510,27511,27512,27514,27517,27518,27519,27520,27525,27528,27532,27534,\n27535,27536,27537,27540,27541,27543,27544,27545,27548,27549,27550,27551,27552,\n27554,27555,27556,27557,27558,27559,27560,27561,27563,27564,27565,27566,27567,\n27568,27569,27570,27574,27576,27577,27578,27579,27580,27581,27582,27584,27587,\n27588,27590,27591,27592,27593,27594,27596,27598,27600,\n27601,27608,27610,27612,27613,27614,27615,27616,27618,27619,27620,27621,27622,\n27623,27624,27625,27628,27629,27630,27632,27633,27634,27636,27638,27639,27640,\n27642,27643,27644,27646,27647,27648,27649,27650,27651,27652,27656,27657,27658,\n27659,27660,27662,27666,27671,27676,27677,27678,27680,27683,27685,27691,27692,\n27693,27697,27699,27702,27703,27705,27706,27707,27708,27710,27711,27715,27716,\n27717,27720,27723,27724,27725,27726,27727,27729,27730,27731,27734,27736,27737,\n27738,27746,27747,27749,27750,27751,27755,27756,27757,27758,27759,27761,27763,\n27765,27767,27768,27770,27771,27772,27775,27776,27780,27783,27786,27787,27789,\n27790,27793,27794,27797,27798,27799,27800,27802,27804,27805,27806,27808,27810,\n27816,27820,27823,27824,27828,27829,27830,27831,27834,27840,27841,27842,27843,\n27846,27847,27848,27851,27853,27854,27855,27857,27858,27864,27865,27866,27868,\n27869,27871,27876,27878,27879,27881,27884,27885,27890,27892,27897,27903,27904,\n27906,27907,27909,27910,27912,27913,27914,27917,27919,27920,27921,27923,27924,\n27925,27926,27928,27932,27933,27935,27936,27937,27938,27939,27940,27942,27944,\n27945,27948,27949,27951,27952,27956,27958,27959,27960,27962,27967,27968,27970,\n27972,27977,27980,27984,27989,27990,27991,27992,27995,27997,27999,28001,28002,\n28004,28005,28007,28008,28011,28012,28013,28016,28017,28018,28019,28021,28022,\n28025,28026,28027,28029,28030,28031,28032,28033,28035,28036,28038,28039,28042,\n28043,28045,28047,28048,28050,28054,28055,28056,28057,28058,28060,28066,28069,\n28076,28077,28080,28081,28083,28084,28086,28087,28089,\n28090,28091,28092,28093,28094,28097,28098,28099,28104,28105,28106,28109,28110,\n28111,28112,28114,28115,28116,28117,28119,28122,28123,28124,28127,28130,28131,\n28133,28135,28136,28137,28138,28141,28143,28144,28146,28148,28149,28150,28152,\n28154,28157,28158,28159,28160,28161,28162,28163,28164,28166,28167,28168,28169,\n28171,28175,28178,28179,28181,28184,28185,28187,28188,28190,28191,28194,28198,\n28199,28200,28202,28204,28206,28208,28209,28211,28213,28214,28215,28217,28219,\n28220,28221,28222,28223,28224,28225,28226,28229,28230,28231,28232,28233,28234,\n28235,28236,28239,28240,28241,28242,28245,28247,28249,28250,28252,28253,28254,\n28256,28257,28258,28259,28260,28261,28262,28263,28264,28265,28266,28268,28269,\n28271,28272,28273,28274,28275,28276,28277,28278,28279,28280,28281,28282,28283,\n28284,28285,28288,28289,28290,28292,28295,28296,28298,28299,28300,28301,28302,\n28305,28306,28307,28308,28309,28310,28311,28313,28314,28315,28317,28318,28320,\n28321,28323,28324,28326,28328,28329,28331,28332,28333,28334,28336,28339,28341,\n28344,28345,28348,28350,28351,28352,28355,28356,28357,28358,28360,28361,28362,\n28364,28365,28366,28368,28370,28374,28376,28377,28379,28380,28381,28387,28391,\n28394,28395,28396,28397,28398,28399,28400,28401,28402,28403,28405,28406,28407,\n28408,28410,28411,28412,28413,28414,28415,28416,28417,28419,28420,28421,28423,\n28424,28426,28427,28428,28429,28430,28432,28433,28434,28438,28439,28440,28441,\n28442,28443,28444,28445,28446,28447,28449,28450,28451,28453,28454,28455,28456,\n28460,28462,28464,28466,28468,28469,28471,28472,28473,\n28474,28475,28476,28477,28479,28480,28481,28482,28483,28484,28485,28488,28489,\n28490,28492,28494,28495,28496,28497,28498,28499,28500,28501,28502,28503,28505,\n28506,28507,28509,28511,28512,28513,28515,28516,28517,28519,28520,28521,28522,\n28523,28524,28527,28528,28529,28531,28533,28534,28535,28537,28539,28541,28542,\n28543,28544,28545,28546,28547,28549,28550,28551,28554,28555,28559,28560,28561,\n28562,28563,28564,28565,28566,28567,28568,28569,28570,28571,28573,28574,28575,\n28576,28578,28579,28580,28581,28582,28584,28585,28586,28587,28588,28589,28590,\n28591,28592,28593,28594,28596,28597,28599,28600,28602,28603,28604,28605,28606,\n28607,28609,28611,28612,28613,28614,28615,28616,28618,28619,28620,28621,28622,\n28623,28624,28627,28628,28629,28630,28631,28632,28633,28634,28635,28636,28637,\n28639,28642,28643,28644,28645,28646,28647,28648,28649,28650,28651,28652,28653,\n28656,28657,28658,28659,28660,28661,28662,28663,28664,28665,28666,28667,28668,\n28669,28670,28671,28672,28673,28674,28675,28676,28677,28678,28679,28680,28681,\n28682,28683,28684,28685,28686,28687,28688,28690,28691,28692,28693,28694,28695,\n28696,28697,28700,28701,28702,28703,28704,28705,28706,28708,28709,28710,28711,\n28712,28713,28714,28715,28716,28717,28718,28719,28720,28721,28722,28723,28724,\n28726,28727,28728,28730,28731,28732,28733,28734,28735,28736,28737,28738,28739,\n28740,28741,28742,28743,28744,28745,28746,28747,28749,28750,28752,28753,28754,\n28755,28756,28757,28758,28759,28760,28761,28762,28763,28764,28765,28767,28768,\n28769,28770,28771,28772,28773,28774,28775,28776,28777,\n28778,28782,28785,28786,28787,28788,28791,28793,28794,28795,28797,28801,28802,\n28803,28804,28806,28807,28808,28811,28812,28813,28815,28816,28817,28819,28823,\n28824,28826,28827,28830,28831,28832,28833,28834,28835,28836,28837,28838,28839,\n28840,28841,28842,28848,28850,28852,28853,28854,28858,28862,28863,28868,28869,\n28870,28871,28873,28875,28876,28877,28878,28879,28880,28881,28882,28883,28884,\n28885,28886,28887,28890,28892,28893,28894,28896,28897,28898,28899,28901,28906,\n28910,28912,28913,28914,28915,28916,28917,28918,28920,28922,28923,28924,28926,\n28927,28928,28929,28930,28931,28932,28933,28934,28935,28936,28939,28940,28941,\n28942,28943,28945,28946,28948,28951,28955,28956,28957,28958,28959,28960,28961,\n28962,28963,28964,28965,28967,28968,28969,28970,28971,28972,28973,28974,28978,\n28979,28980,28981,28983,28984,28985,28986,28987,28988,28989,28990,28991,28992,\n28993,28994,28995,28996,28998,28999,29000,29001,29003,29005,29007,29008,29009,\n29010,29011,29012,29013,29014,29015,29016,29017,29018,29019,29021,29023,29024,\n29025,29026,29027,29029,29033,29034,29035,29036,29037,29039,29040,29041,29044,\n29045,29046,29047,29049,29051,29052,29054,29055,29056,29057,29058,29059,29061,\n29062,29063,29064,29065,29067,29068,29069,29070,29072,29073,29074,29075,29077,\n29078,29079,29082,29083,29084,29085,29086,29089,29090,29091,29092,29093,29094,\n29095,29097,29098,29099,29101,29102,29103,29104,29105,29106,29108,29110,29111,\n29112,29114,29115,29116,29117,29118,29119,29120,29121,29122,29124,29125,29126,\n29127,29128,29129,29130,29131,29132,29133,29135,29136,\n29137,29138,29139,29142,29143,29144,29145,29146,29147,29148,29149,29150,29151,\n29153,29154,29155,29156,29158,29160,29161,29162,29163,29164,29165,29167,29168,\n29169,29170,29171,29172,29173,29174,29175,29176,29178,29179,29180,29181,29182,\n29183,29184,29185,29186,29187,29188,29189,29191,29192,29193,29194,29195,29196,\n29197,29198,29199,29200,29201,29202,29203,29204,29205,29206,29207,29208,29209,\n29210,29211,29212,29214,29215,29216,29217,29218,29219,29220,29221,29222,29223,\n29225,29227,29229,29230,29231,29234,29235,29236,29242,29244,29246,29248,29249,\n29250,29251,29252,29253,29254,29257,29258,29259,29262,29263,29264,29265,29267,\n29268,29269,29271,29272,29274,29276,29278,29280,29283,29284,29285,29288,29290,\n29291,29292,29293,29296,29297,29299,29300,29302,29303,29304,29307,29308,29309,\n29314,29315,29317,29318,29319,29320,29321,29324,29326,29328,29329,29331,29332,\n29333,29334,29335,29336,29337,29338,29339,29340,29341,29342,29344,29345,29346,\n29347,29348,29349,29350,29351,29352,29353,29354,29355,29358,29361,29362,29363,\n29365,29370,29371,29372,29373,29374,29375,29376,29381,29382,29383,29385,29386,\n29387,29388,29391,29393,29395,29396,29397,29398,29400,29402,29403,58566,58567,\n58568,58569,58570,58571,58572,58573,58574,58575,58576,58577,58578,58579,58580,\n58581,58582,58583,58584,58585,58586,58587,58588,58589,58590,58591,58592,58593,\n58594,58595,58596,58597,58598,58599,58600,58601,58602,58603,58604,58605,58606,\n58607,58608,58609,58610,58611,58612,58613,58614,58615,58616,58617,58618,58619,\n58620,58621,58622,58623,58624,58625,58626,58627,58628,\n58629,58630,58631,58632,58633,58634,58635,58636,58637,58638,58639,58640,58641,\n58642,58643,58644,58645,58646,58647,58648,58649,58650,58651,58652,58653,58654,\n58655,58656,58657,58658,58659,58660,58661,12288,12289,12290,183,713,711,168,\n12291,12293,8212,65374,8214,8230,8216,8217,8220,8221,12308,12309,12296,12297,\n12298,12299,12300,12301,12302,12303,12310,12311,12304,12305,177,215,247,8758,\n8743,8744,8721,8719,8746,8745,8712,8759,8730,8869,8741,8736,8978,8857,8747,\n8750,8801,8780,8776,8765,8733,8800,8814,8815,8804,8805,8734,8757,8756,9794,\n9792,176,8242,8243,8451,65284,164,65504,65505,8240,167,8470,9734,9733,9675,\n9679,9678,9671,9670,9633,9632,9651,9650,8251,8594,8592,8593,8595,12307,58662,\n58663,58664,58665,58666,58667,58668,58669,58670,58671,58672,58673,58674,58675,\n58676,58677,58678,58679,58680,58681,58682,58683,58684,58685,58686,58687,58688,\n58689,58690,58691,58692,58693,58694,58695,58696,58697,58698,58699,58700,58701,\n58702,58703,58704,58705,58706,58707,58708,58709,58710,58711,58712,58713,58714,\n58715,58716,58717,58718,58719,58720,58721,58722,58723,58724,58725,58726,58727,\n58728,58729,58730,58731,58732,58733,58734,58735,58736,58737,58738,58739,58740,\n58741,58742,58743,58744,58745,58746,58747,58748,58749,58750,58751,58752,58753,\n58754,58755,58756,58757,8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,\n59238,59239,59240,59241,59242,59243,9352,9353,9354,9355,9356,9357,9358,9359,\n9360,9361,9362,9363,9364,9365,9366,9367,9368,\n9369,9370,9371,9332,9333,9334,9335,9336,9337,9338,9339,9340,9341,9342,9343,\n9344,9345,9346,9347,9348,9349,9350,9351,9312,9313,9314,9315,9316,9317,9318,\n9319,9320,9321,8364,59245,12832,12833,12834,12835,12836,12837,12838,12839,\n12840,12841,59246,59247,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,\n8554,8555,59248,59249,58758,58759,58760,58761,58762,58763,58764,58765,58766,\n58767,58768,58769,58770,58771,58772,58773,58774,58775,58776,58777,58778,58779,\n58780,58781,58782,58783,58784,58785,58786,58787,58788,58789,58790,58791,58792,\n58793,58794,58795,58796,58797,58798,58799,58800,58801,58802,58803,58804,58805,\n58806,58807,58808,58809,58810,58811,58812,58813,58814,58815,58816,58817,58818,\n58819,58820,58821,58822,58823,58824,58825,58826,58827,58828,58829,58830,58831,\n58832,58833,58834,58835,58836,58837,58838,58839,58840,58841,58842,58843,58844,\n58845,58846,58847,58848,58849,58850,58851,58852,58853,65281,65282,65283,65509,\n65285,65286,65287,65288,65289,65290,65291,65292,65293,65294,65295,65296,65297,\n65298,65299,65300,65301,65302,65303,65304,65305,65306,65307,65308,65309,65310,\n65311,65312,65313,65314,65315,65316,65317,65318,65319,65320,65321,65322,65323,\n65324,65325,65326,65327,65328,65329,65330,65331,65332,65333,65334,65335,65336,\n65337,65338,65339,65340,65341,65342,65343,65344,65345,65346,65347,65348,65349,\n65350,65351,65352,65353,65354,65355,65356,65357,65358,65359,65360,65361,65362,\n65363,65364,65365,65366,65367,65368,65369,65370,65371,65372,65373,65507,58854,\n58855,58856,58857,58858,\n58859,58860,58861,58862,58863,58864,58865,58866,58867,58868,58869,58870,58871,\n58872,58873,58874,58875,58876,58877,58878,58879,58880,58881,58882,58883,58884,\n58885,58886,58887,58888,58889,58890,58891,58892,58893,58894,58895,58896,58897,\n58898,58899,58900,58901,58902,58903,58904,58905,58906,58907,58908,58909,58910,\n58911,58912,58913,58914,58915,58916,58917,58918,58919,58920,58921,58922,58923,\n58924,58925,58926,58927,58928,58929,58930,58931,58932,58933,58934,58935,58936,\n58937,58938,58939,58940,58941,58942,58943,58944,58945,58946,58947,58948,58949,\n12353,12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,\n12366,12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,\n12379,12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,\n12392,12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,\n12405,12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,\n12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,\n12431,12432,12433,12434,12435,59250,59251,59252,59253,59254,59255,59256,59257,\n59258,59259,59260,58950,58951,58952,58953,58954,58955,58956,58957,58958,58959,\n58960,58961,58962,58963,58964,58965,58966,58967,58968,58969,58970,58971,58972,\n58973,58974,58975,58976,58977,58978,58979,58980,58981,58982,58983,58984,58985,\n58986,58987,58988,58989,58990,58991,58992,58993,58994,58995,58996,58997,58998,\n58999,59000,59001,59002,59003,59004,59005,59006,59007,59008,59009,59010,59011,\n59012,59013,59014,59015,59016,59017,59018,59019,59020,\n59021,59022,59023,59024,59025,59026,59027,59028,59029,59030,59031,59032,59033,\n59034,59035,59036,59037,59038,59039,59040,59041,59042,59043,59044,59045,12449,\n12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,12462,\n12463,12464,12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,12475,\n12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,12486,12487,12488,\n12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,12499,12500,12501,\n12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,12512,12513,12514,\n12515,12516,12517,12518,12519,12520,12521,12522,12523,12524,12525,12526,12527,\n12528,12529,12530,12531,12532,12533,12534,59261,59262,59263,59264,59265,59266,\n59267,59268,59046,59047,59048,59049,59050,59051,59052,59053,59054,59055,59056,\n59057,59058,59059,59060,59061,59062,59063,59064,59065,59066,59067,59068,59069,\n59070,59071,59072,59073,59074,59075,59076,59077,59078,59079,59080,59081,59082,\n59083,59084,59085,59086,59087,59088,59089,59090,59091,59092,59093,59094,59095,\n59096,59097,59098,59099,59100,59101,59102,59103,59104,59105,59106,59107,59108,\n59109,59110,59111,59112,59113,59114,59115,59116,59117,59118,59119,59120,59121,\n59122,59123,59124,59125,59126,59127,59128,59129,59130,59131,59132,59133,59134,\n59135,59136,59137,59138,59139,59140,59141,913,914,915,916,917,918,919,920,921,\n922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,59269,59270,59271,\n59272,59273,59274,59275,59276,945,946,947,948,949,950,951,952,953,\n954,955,956,957,958,959,960,961,963,964,965,966,967,968,969,59277,59278,59279,\n59280,59281,59282,59283,65077,65078,65081,65082,65087,65088,65085,65086,65089,\n65090,65091,65092,59284,59285,65083,65084,65079,65080,65073,59286,65075,65076,\n59287,59288,59289,59290,59291,59292,59293,59294,59295,59142,59143,59144,59145,\n59146,59147,59148,59149,59150,59151,59152,59153,59154,59155,59156,59157,59158,\n59159,59160,59161,59162,59163,59164,59165,59166,59167,59168,59169,59170,59171,\n59172,59173,59174,59175,59176,59177,59178,59179,59180,59181,59182,59183,59184,\n59185,59186,59187,59188,59189,59190,59191,59192,59193,59194,59195,59196,59197,\n59198,59199,59200,59201,59202,59203,59204,59205,59206,59207,59208,59209,59210,\n59211,59212,59213,59214,59215,59216,59217,59218,59219,59220,59221,59222,59223,\n59224,59225,59226,59227,59228,59229,59230,59231,59232,59233,59234,59235,59236,\n59237,1040,1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,\n1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,\n1068,1069,1070,1071,59296,59297,59298,59299,59300,59301,59302,59303,59304,\n59305,59306,59307,59308,59309,59310,1072,1073,1074,1075,1076,1077,1105,1078,\n1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,\n1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,59311,59312,59313,59314,\n59315,59316,59317,59318,59319,59320,59321,59322,59323,714,715,729,8211,8213,\n8229,8245,8453,8457,8598,8599,8600,8601,\n8725,8735,8739,8786,8806,8807,8895,9552,9553,9554,9555,9556,9557,9558,9559,\n9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574,\n9575,9576,9577,9578,9579,9580,9581,9582,9583,9584,9585,9586,9587,9601,9602,\n9603,9604,9605,9606,9607,9608,9609,9610,9611,9612,9613,9614,9615,9619,9620,\n9621,9660,9661,9698,9699,9700,9701,9737,8853,12306,12317,12318,59324,59325,\n59326,59327,59328,59329,59330,59331,59332,59333,59334,257,225,462,224,275,233,\n283,232,299,237,464,236,333,243,466,242,363,250,468,249,470,472,474,476,252,\n234,593,59335,324,328,505,609,59337,59338,59339,59340,12549,12550,12551,12552,\n12553,12554,12555,12556,12557,12558,12559,12560,12561,12562,12563,12564,12565,\n12566,12567,12568,12569,12570,12571,12572,12573,12574,12575,12576,12577,12578,\n12579,12580,12581,12582,12583,12584,12585,59341,59342,59343,59344,59345,59346,\n59347,59348,59349,59350,59351,59352,59353,59354,59355,59356,59357,59358,59359,\n59360,59361,12321,12322,12323,12324,12325,12326,12327,12328,12329,12963,13198,\n13199,13212,13213,13214,13217,13252,13262,13265,13266,13269,65072,65506,65508,\n59362,8481,12849,59363,8208,59364,59365,59366,12540,12443,12444,12541,12542,\n12294,12445,12446,65097,65098,65099,65100,65101,65102,65103,65104,65105,65106,\n65108,65109,65110,65111,65113,65114,65115,65116,65117,65118,65119,65120,65121,\n65122,65123,65124,65125,65126,65128,65129,65130,65131,12350,12272,12273,12274,\n12275,12276,12277,\n12278,12279,12280,12281,12282,12283,12295,59380,59381,59382,59383,59384,59385,\n59386,59387,59388,59389,59390,59391,59392,9472,9473,9474,9475,9476,9477,9478,\n9479,9480,9481,9482,9483,9484,9485,9486,9487,9488,9489,9490,9491,9492,9493,\n9494,9495,9496,9497,9498,9499,9500,9501,9502,9503,9504,9505,9506,9507,9508,\n9509,9510,9511,9512,9513,9514,9515,9516,9517,9518,9519,9520,9521,9522,9523,\n9524,9525,9526,9527,9528,9529,9530,9531,9532,9533,9534,9535,9536,9537,9538,\n9539,9540,9541,9542,9543,9544,9545,9546,9547,59393,59394,59395,59396,59397,\n59398,59399,59400,59401,59402,59403,59404,59405,59406,59407,29404,29405,29407,\n29410,29411,29412,29413,29414,29415,29418,29419,29429,29430,29433,29437,29438,\n29439,29440,29442,29444,29445,29446,29447,29448,29449,29451,29452,29453,29455,\n29456,29457,29458,29460,29464,29465,29466,29471,29472,29475,29476,29478,29479,\n29480,29485,29487,29488,29490,29491,29493,29494,29498,29499,29500,29501,29504,\n29505,29506,29507,29508,29509,29510,29511,29512,29513,29514,29515,29516,29518,\n29519,29521,29523,29524,29525,29526,29528,29529,29530,29531,29532,29533,29534,\n29535,29537,29538,29539,29540,29541,29542,29543,29544,29545,29546,29547,29550,\n29552,29553,57344,57345,57346,57347,57348,57349,57350,57351,57352,57353,57354,\n57355,57356,57357,57358,57359,57360,57361,57362,57363,57364,57365,57366,57367,\n57368,57369,57370,57371,57372,57373,57374,57375,57376,57377,57378,57379,57380,\n57381,57382,57383,57384,57385,57386,57387,57388,57389,57390,57391,57392,\n57393,57394,57395,57396,57397,57398,57399,57400,57401,57402,57403,57404,57405,\n57406,57407,57408,57409,57410,57411,57412,57413,57414,57415,57416,57417,57418,\n57419,57420,57421,57422,57423,57424,57425,57426,57427,57428,57429,57430,57431,\n57432,57433,57434,57435,57436,57437,29554,29555,29556,29557,29558,29559,29560,\n29561,29562,29563,29564,29565,29567,29568,29569,29570,29571,29573,29574,29576,\n29578,29580,29581,29583,29584,29586,29587,29588,29589,29591,29592,29593,29594,\n29596,29597,29598,29600,29601,29603,29604,29605,29606,29607,29608,29610,29612,\n29613,29617,29620,29621,29622,29624,29625,29628,29629,29630,29631,29633,29635,\n29636,29637,29638,29639,29643,29644,29646,29650,29651,29652,29653,29654,29655,\n29656,29658,29659,29660,29661,29663,29665,29666,29667,29668,29670,29672,29674,\n29675,29676,29678,29679,29680,29681,29683,29684,29685,29686,29687,57438,57439,\n57440,57441,57442,57443,57444,57445,57446,57447,57448,57449,57450,57451,57452,\n57453,57454,57455,57456,57457,57458,57459,57460,57461,57462,57463,57464,57465,\n57466,57467,57468,57469,57470,57471,57472,57473,57474,57475,57476,57477,57478,\n57479,57480,57481,57482,57483,57484,57485,57486,57487,57488,57489,57490,57491,\n57492,57493,57494,57495,57496,57497,57498,57499,57500,57501,57502,57503,57504,\n57505,57506,57507,57508,57509,57510,57511,57512,57513,57514,57515,57516,57517,\n57518,57519,57520,57521,57522,57523,57524,57525,57526,57527,57528,57529,57530,\n57531,29688,29689,29690,29691,29692,29693,29694,29695,29696,29697,29698,29700,\n29703,29704,29707,29708,29709,29710,29713,29714,29715,\n29716,29717,29718,29719,29720,29721,29724,29725,29726,29727,29728,29729,29731,\n29732,29735,29737,29739,29741,29743,29745,29746,29751,29752,29753,29754,29755,\n29757,29758,29759,29760,29762,29763,29764,29765,29766,29767,29768,29769,29770,\n29771,29772,29773,29774,29775,29776,29777,29778,29779,29780,29782,29784,29789,\n29792,29793,29794,29795,29796,29797,29798,29799,29800,29801,29802,29803,29804,\n29806,29807,29809,29810,29811,29812,29813,29816,29817,29818,57532,57533,57534,\n57535,57536,57537,57538,57539,57540,57541,57542,57543,57544,57545,57546,57547,\n57548,57549,57550,57551,57552,57553,57554,57555,57556,57557,57558,57559,57560,\n57561,57562,57563,57564,57565,57566,57567,57568,57569,57570,57571,57572,57573,\n57574,57575,57576,57577,57578,57579,57580,57581,57582,57583,57584,57585,57586,\n57587,57588,57589,57590,57591,57592,57593,57594,57595,57596,57597,57598,57599,\n57600,57601,57602,57603,57604,57605,57606,57607,57608,57609,57610,57611,57612,\n57613,57614,57615,57616,57617,57618,57619,57620,57621,57622,57623,57624,57625,\n29819,29820,29821,29823,29826,29828,29829,29830,29832,29833,29834,29836,29837,\n29839,29841,29842,29843,29844,29845,29846,29847,29848,29849,29850,29851,29853,\n29855,29856,29857,29858,29859,29860,29861,29862,29866,29867,29868,29869,29870,\n29871,29872,29873,29874,29875,29876,29877,29878,29879,29880,29881,29883,29884,\n29885,29886,29887,29888,29889,29890,29891,29892,29893,29894,29895,29896,29897,\n29898,29899,29900,29901,29902,29903,29904,29905,29907,29908,29909,29910,29911,\n29912,29913,29914,29915,29917,29919,29921,29925,29927,\n29928,29929,29930,29931,29932,29933,29936,29937,29938,57626,57627,57628,57629,\n57630,57631,57632,57633,57634,57635,57636,57637,57638,57639,57640,57641,57642,\n57643,57644,57645,57646,57647,57648,57649,57650,57651,57652,57653,57654,57655,\n57656,57657,57658,57659,57660,57661,57662,57663,57664,57665,57666,57667,57668,\n57669,57670,57671,57672,57673,57674,57675,57676,57677,57678,57679,57680,57681,\n57682,57683,57684,57685,57686,57687,57688,57689,57690,57691,57692,57693,57694,\n57695,57696,57697,57698,57699,57700,57701,57702,57703,57704,57705,57706,57707,\n57708,57709,57710,57711,57712,57713,57714,57715,57716,57717,57718,57719,29939,\n29941,29944,29945,29946,29947,29948,29949,29950,29952,29953,29954,29955,29957,\n29958,29959,29960,29961,29962,29963,29964,29966,29968,29970,29972,29973,29974,\n29975,29979,29981,29982,29984,29985,29986,29987,29988,29990,29991,29994,29998,\n30004,30006,30009,30012,30013,30015,30017,30018,30019,30020,30022,30023,30025,\n30026,30029,30032,30033,30034,30035,30037,30038,30039,30040,30045,30046,30047,\n30048,30049,30050,30051,30052,30055,30056,30057,30059,30060,30061,30062,30063,\n30064,30065,30067,30069,30070,30071,30074,30075,30076,30077,30078,30080,30081,\n30082,30084,30085,30087,57720,57721,57722,57723,57724,57725,57726,57727,57728,\n57729,57730,57731,57732,57733,57734,57735,57736,57737,57738,57739,57740,57741,\n57742,57743,57744,57745,57746,57747,57748,57749,57750,57751,57752,57753,57754,\n57755,57756,57757,57758,57759,57760,57761,57762,57763,57764,57765,57766,57767,\n57768,57769,57770,57771,57772,57773,57774,57775,57776,\n57777,57778,57779,57780,57781,57782,57783,57784,57785,57786,57787,57788,57789,\n57790,57791,57792,57793,57794,57795,57796,57797,57798,57799,57800,57801,57802,\n57803,57804,57805,57806,57807,57808,57809,57810,57811,57812,57813,30088,30089,\n30090,30092,30093,30094,30096,30099,30101,30104,30107,30108,30110,30114,30118,\n30119,30120,30121,30122,30125,30134,30135,30138,30139,30143,30144,30145,30150,\n30155,30156,30158,30159,30160,30161,30163,30167,30169,30170,30172,30173,30175,\n30176,30177,30181,30185,30188,30189,30190,30191,30194,30195,30197,30198,30199,\n30200,30202,30203,30205,30206,30210,30212,30214,30215,30216,30217,30219,30221,\n30222,30223,30225,30226,30227,30228,30230,30234,30236,30237,30238,30241,30243,\n30247,30248,30252,30254,30255,30257,30258,30262,30263,30265,30266,30267,30269,\n30273,30274,30276,57814,57815,57816,57817,57818,57819,57820,57821,57822,57823,\n57824,57825,57826,57827,57828,57829,57830,57831,57832,57833,57834,57835,57836,\n57837,57838,57839,57840,57841,57842,57843,57844,57845,57846,57847,57848,57849,\n57850,57851,57852,57853,57854,57855,57856,57857,57858,57859,57860,57861,57862,\n57863,57864,57865,57866,57867,57868,57869,57870,57871,57872,57873,57874,57875,\n57876,57877,57878,57879,57880,57881,57882,57883,57884,57885,57886,57887,57888,\n57889,57890,57891,57892,57893,57894,57895,57896,57897,57898,57899,57900,57901,\n57902,57903,57904,57905,57906,57907,30277,30278,30279,30280,30281,30282,30283,\n30286,30287,30288,30289,30290,30291,30293,30295,30296,30297,30298,30299,30301,\n30303,30304,30305,30306,30308,30309,30310,30311,30312,\n30313,30314,30316,30317,30318,30320,30321,30322,30323,30324,30325,30326,30327,\n30329,30330,30332,30335,30336,30337,30339,30341,30345,30346,30348,30349,30351,\n30352,30354,30356,30357,30359,30360,30362,30363,30364,30365,30366,30367,30368,\n30369,30370,30371,30373,30374,30375,30376,30377,30378,30379,30380,30381,30383,\n30384,30387,30389,30390,30391,30392,30393,30394,30395,30396,30397,30398,30400,\n30401,30403,21834,38463,22467,25384,21710,21769,21696,30353,30284,34108,30702,\n33406,30861,29233,38552,38797,27688,23433,20474,25353,26263,23736,33018,26696,\n32942,26114,30414,20985,25942,29100,32753,34948,20658,22885,25034,28595,33453,\n25420,25170,21485,21543,31494,20843,30116,24052,25300,36299,38774,25226,32793,\n22365,38712,32610,29240,30333,26575,30334,25670,20336,36133,25308,31255,26001,\n29677,25644,25203,33324,39041,26495,29256,25198,25292,20276,29923,21322,21150,\n32458,37030,24110,26758,27036,33152,32465,26834,30917,34444,38225,20621,35876,\n33502,32990,21253,35090,21093,30404,30407,30409,30411,30412,30419,30421,30425,\n30426,30428,30429,30430,30432,30433,30434,30435,30436,30438,30439,30440,30441,\n30442,30443,30444,30445,30448,30451,30453,30454,30455,30458,30459,30461,30463,\n30464,30466,30467,30469,30470,30474,30476,30478,30479,30480,30481,30482,30483,\n30484,30485,30486,30487,30488,30491,30492,30493,30494,30497,30499,30500,30501,\n30503,30506,30507,30508,30510,30512,30513,30514,30515,30516,30521,30523,30525,\n30526,30527,30530,30532,30533,30534,30536,30537,30538,30539,30540,30541,30542,\n30543,30546,30547,30548,30549,30550,30551,30552,30553,\n30556,34180,38649,20445,22561,39281,23453,25265,25253,26292,35961,40077,29190,\n26479,30865,24754,21329,21271,36744,32972,36125,38049,20493,29384,22791,24811,\n28953,34987,22868,33519,26412,31528,23849,32503,29997,27893,36454,36856,36924,\n40763,27604,37145,31508,24444,30887,34006,34109,27605,27609,27606,24065,24199,\n30201,38381,25949,24330,24517,36767,22721,33218,36991,38491,38829,36793,32534,\n36140,25153,20415,21464,21342,36776,36777,36779,36941,26631,24426,33176,34920,\n40150,24971,21035,30250,24428,25996,28626,28392,23486,25672,20853,20912,26564,\n19993,31177,39292,28851,30557,30558,30559,30560,30564,30567,30569,30570,30573,\n30574,30575,30576,30577,30578,30579,30580,30581,30582,30583,30584,30586,30587,\n30588,30593,30594,30595,30598,30599,30600,30601,30602,30603,30607,30608,30611,\n30612,30613,30614,30615,30616,30617,30618,30619,30620,30621,30622,30625,30627,\n30628,30630,30632,30635,30637,30638,30639,30641,30642,30644,30646,30647,30648,\n30649,30650,30652,30654,30656,30657,30658,30659,30660,30661,30662,30663,30664,\n30665,30666,30667,30668,30670,30671,30672,30673,30674,30675,30676,30677,30678,\n30680,30681,30682,30685,30686,30687,30688,30689,30692,30149,24182,29627,33760,\n25773,25320,38069,27874,21338,21187,25615,38082,31636,20271,24091,33334,33046,\n33162,28196,27850,39539,25429,21340,21754,34917,22496,19981,24067,27493,31807,\n37096,24598,25830,29468,35009,26448,25165,36130,30572,36393,37319,24425,33756,\n34081,39184,21442,34453,27531,24813,24808,28799,33485,33329,20179,27815,34255,\n25805,31961,27133,26361,33609,21397,31574,20391,20876,\n27979,23618,36461,25554,21449,33580,33590,26597,30900,25661,23519,23700,24046,\n35815,25286,26612,35962,25600,25530,34633,39307,35863,32544,38130,20135,38416,\n39076,26124,29462,30694,30696,30698,30703,30704,30705,30706,30708,30709,30711,\n30713,30714,30715,30716,30723,30724,30725,30726,30727,30728,30730,30731,30734,\n30735,30736,30739,30741,30745,30747,30750,30752,30753,30754,30756,30760,30762,\n30763,30766,30767,30769,30770,30771,30773,30774,30781,30783,30785,30786,30787,\n30788,30790,30792,30793,30794,30795,30797,30799,30801,30803,30804,30808,30809,\n30810,30811,30812,30814,30815,30816,30817,30818,30819,30820,30821,30822,30823,\n30824,30825,30831,30832,30833,30834,30835,30836,30837,30838,30840,30841,30842,\n30843,30845,30846,30847,30848,30849,30850,30851,22330,23581,24120,38271,20607,\n32928,21378,25950,30021,21809,20513,36229,25220,38046,26397,22066,28526,24034,\n21557,28818,36710,25199,25764,25507,24443,28552,37108,33251,36784,23576,26216,\n24561,27785,38472,36225,34924,25745,31216,22478,27225,25104,21576,20056,31243,\n24809,28548,35802,25215,36894,39563,31204,21507,30196,25345,21273,27744,36831,\n24347,39536,32827,40831,20360,23610,36196,32709,26021,28861,20805,20914,34411,\n23815,23456,25277,37228,30068,36364,31264,24833,31609,20167,32504,30597,19985,\n33261,21021,20986,27249,21416,36487,38148,38607,28353,38500,26970,30852,30853,\n30854,30856,30858,30859,30863,30864,30866,30868,30869,30870,30873,30877,30878,\n30880,30882,30884,30886,30888,30889,30890,30891,30892,30893,30894,30895,30901,\n30902,30903,30904,30906,30907,30908,30909,30911,30912,\n30914,30915,30916,30918,30919,30920,30924,30925,30926,30927,30929,30930,30931,\n30934,30935,30936,30938,30939,30940,30941,30942,30943,30944,30945,30946,30947,\n30948,30949,30950,30951,30953,30954,30955,30957,30958,30959,30960,30961,30963,\n30965,30966,30968,30969,30971,30972,30973,30974,30975,30976,30978,30979,30980,\n30982,30983,30984,30985,30986,30987,30988,30784,20648,30679,25616,35302,22788,\n25571,24029,31359,26941,20256,33337,21912,20018,30126,31383,24162,24202,38383,\n21019,21561,28810,25462,38180,22402,26149,26943,37255,21767,28147,32431,34850,\n25139,32496,30133,33576,30913,38604,36766,24904,29943,35789,27492,21050,36176,\n27425,32874,33905,22257,21254,20174,19995,20945,31895,37259,31751,20419,36479,\n31713,31388,25703,23828,20652,33030,30209,31929,28140,32736,26449,23384,23544,\n30923,25774,25619,25514,25387,38169,25645,36798,31572,30249,25171,22823,21574,\n27513,20643,25140,24102,27526,20195,36151,34955,24453,36910,30989,30990,30991,\n30992,30993,30994,30996,30997,30998,30999,31000,31001,31002,31003,31004,31005,\n31007,31008,31009,31010,31011,31013,31014,31015,31016,31017,31018,31019,31020,\n31021,31022,31023,31024,31025,31026,31027,31029,31030,31031,31032,31033,31037,\n31039,31042,31043,31044,31045,31047,31050,31051,31052,31053,31054,31055,31056,\n31057,31058,31060,31061,31064,31065,31073,31075,31076,31078,31081,31082,31083,\n31084,31086,31088,31089,31090,31091,31092,31093,31094,31097,31099,31100,31101,\n31102,31103,31106,31107,31110,31111,31112,31113,31115,31116,31117,31118,31120,\n31121,31122,24608,32829,25285,20025,21333,37112,25528,\n32966,26086,27694,20294,24814,28129,35806,24377,34507,24403,25377,20826,33633,\n26723,20992,25443,36424,20498,23707,31095,23548,21040,31291,24764,36947,30423,\n24503,24471,30340,36460,28783,30331,31561,30634,20979,37011,22564,20302,28404,\n36842,25932,31515,29380,28068,32735,23265,25269,24213,22320,33922,31532,24093,\n24351,36882,32532,39072,25474,28359,30872,28857,20856,38747,22443,30005,20291,\n30008,24215,24806,22880,28096,27583,30857,21500,38613,20939,20993,25481,21514,\n38035,35843,36300,29241,30879,34678,36845,35853,21472,31123,31124,31125,31126,\n31127,31128,31129,31131,31132,31133,31134,31135,31136,31137,31138,31139,31140,\n31141,31142,31144,31145,31146,31147,31148,31149,31150,31151,31152,31153,31154,\n31156,31157,31158,31159,31160,31164,31167,31170,31172,31173,31175,31176,31178,\n31180,31182,31183,31184,31187,31188,31190,31191,31193,31194,31195,31196,31197,\n31198,31200,31201,31202,31205,31208,31210,31212,31214,31217,31218,31219,31220,\n31221,31222,31223,31225,31226,31228,31230,31231,31233,31236,31237,31239,31240,\n31241,31242,31244,31247,31248,31249,31250,31251,31253,31254,31256,31257,31259,\n31260,19969,30447,21486,38025,39030,40718,38189,23450,35746,20002,19996,20908,\n33891,25026,21160,26635,20375,24683,20923,27934,20828,25238,26007,38497,35910,\n36887,30168,37117,30563,27602,29322,29420,35835,22581,30585,36172,26460,38208,\n32922,24230,28193,22930,31471,30701,38203,27573,26029,32526,22534,20817,38431,\n23545,22697,21544,36466,25958,39039,22244,38045,30462,36929,25479,21702,22810,\n22842,22427,36530,26421,36346,33333,21057,24816,22549,\n34558,23784,40517,20420,39069,35769,23077,24694,21380,25212,36943,37122,39295,\n24681,32780,20799,32819,23572,39285,27953,20108,31261,31263,31265,31266,31268,\n31269,31270,31271,31272,31273,31274,31275,31276,31277,31278,31279,31280,31281,\n31282,31284,31285,31286,31288,31290,31294,31296,31297,31298,31299,31300,31301,\n31303,31304,31305,31306,31307,31308,31309,31310,31311,31312,31314,31315,31316,\n31317,31318,31320,31321,31322,31323,31324,31325,31326,31327,31328,31329,31330,\n31331,31332,31333,31334,31335,31336,31337,31338,31339,31340,31341,31342,31343,\n31345,31346,31347,31349,31355,31356,31357,31358,31362,31365,31367,31369,31370,\n31371,31372,31374,31375,31376,31379,31380,31385,31386,31387,31390,31393,31394,\n36144,21457,32602,31567,20240,20047,38400,27861,29648,34281,24070,30058,32763,\n27146,30718,38034,32321,20961,28902,21453,36820,33539,36137,29359,39277,27867,\n22346,33459,26041,32938,25151,38450,22952,20223,35775,32442,25918,33778,38750,\n21857,39134,32933,21290,35837,21536,32954,24223,27832,36153,33452,37210,21545,\n27675,20998,32439,22367,28954,27774,31881,22859,20221,24575,24868,31914,20016,\n23553,26539,34562,23792,38155,39118,30127,28925,36898,20911,32541,35773,22857,\n20964,20315,21542,22827,25975,32932,23413,25206,25282,36752,24133,27679,31526,\n20239,20440,26381,31395,31396,31399,31401,31402,31403,31406,31407,31408,31409,\n31410,31412,31413,31414,31415,31416,31417,31418,31419,31420,31421,31422,31424,\n31425,31426,31427,31428,31429,31430,31431,31432,31433,31434,31436,31437,31438,\n31439,31440,31441,31442,31443,31444,31445,31447,31448,\n31450,31451,31452,31453,31457,31458,31460,31463,31464,31465,31466,31467,31468,\n31470,31472,31473,31474,31475,31476,31477,31478,31479,31480,31483,31484,31486,\n31488,31489,31490,31493,31495,31497,31500,31501,31502,31504,31506,31507,31510,\n31511,31512,31514,31516,31517,31519,31521,31522,31523,31527,31529,31533,28014,\n28074,31119,34993,24343,29995,25242,36741,20463,37340,26023,33071,33105,24220,\n33104,36212,21103,35206,36171,22797,20613,20184,38428,29238,33145,36127,23500,\n35747,38468,22919,32538,21648,22134,22030,35813,25913,27010,38041,30422,28297,\n24178,29976,26438,26577,31487,32925,36214,24863,31174,25954,36195,20872,21018,\n38050,32568,32923,32434,23703,28207,26464,31705,30347,39640,33167,32660,31957,\n25630,38224,31295,21578,21733,27468,25601,25096,40509,33011,30105,21106,38761,\n33883,26684,34532,38401,38548,38124,20010,21508,32473,26681,36319,32789,26356,\n24218,32697,31535,31536,31538,31540,31541,31542,31543,31545,31547,31549,31551,\n31552,31553,31554,31555,31556,31558,31560,31562,31565,31566,31571,31573,31575,\n31577,31580,31582,31583,31585,31587,31588,31589,31590,31591,31592,31593,31594,\n31595,31596,31597,31599,31600,31603,31604,31606,31608,31610,31612,31613,31615,\n31617,31618,31619,31620,31622,31623,31624,31625,31626,31627,31628,31630,31631,\n31633,31634,31635,31638,31640,31641,31642,31643,31646,31647,31648,31651,31652,\n31653,31662,31663,31664,31666,31667,31669,31670,31671,31673,31674,31675,31676,\n31677,31678,31679,31680,31682,31683,31684,22466,32831,26775,24037,25915,21151,\n24685,40858,20379,36524,20844,23467,24339,24041,27742,\n25329,36129,20849,38057,21246,27807,33503,29399,22434,26500,36141,22815,36764,\n33735,21653,31629,20272,27837,23396,22993,40723,21476,34506,39592,35895,32929,\n25925,39038,22266,38599,21038,29916,21072,23521,25346,35074,20054,25296,24618,\n26874,20851,23448,20896,35266,31649,39302,32592,24815,28748,36143,20809,24191,\n36891,29808,35268,22317,30789,24402,40863,38394,36712,39740,35809,30328,26690,\n26588,36330,36149,21053,36746,28378,26829,38149,37101,22269,26524,35065,36807,\n21704,31685,31688,31689,31690,31691,31693,31694,31695,31696,31698,31700,31701,\n31702,31703,31704,31707,31708,31710,31711,31712,31714,31715,31716,31719,31720,\n31721,31723,31724,31725,31727,31728,31730,31731,31732,31733,31734,31736,31737,\n31738,31739,31741,31743,31744,31745,31746,31747,31748,31749,31750,31752,31753,\n31754,31757,31758,31760,31761,31762,31763,31764,31765,31767,31768,31769,31770,\n31771,31772,31773,31774,31776,31777,31778,31779,31780,31781,31784,31785,31787,\n31788,31789,31790,31791,31792,31793,31794,31795,31796,31797,31798,31799,31801,\n31802,31803,31804,31805,31806,31810,39608,23401,28023,27686,20133,23475,39559,\n37219,25000,37039,38889,21547,28085,23506,20989,21898,32597,32752,25788,25421,\n26097,25022,24717,28938,27735,27721,22831,26477,33322,22741,22158,35946,27627,\n37085,22909,32791,21495,28009,21621,21917,33655,33743,26680,31166,21644,20309,\n21512,30418,35977,38402,27827,28088,36203,35088,40548,36154,22079,40657,30165,\n24456,29408,24680,21756,20136,27178,34913,24658,36720,21700,28888,34425,40511,\n27946,23439,24344,32418,21897,20399,29492,21564,21402,\n20505,21518,21628,20046,24573,29786,22774,33899,32993,34676,29392,31946,28246,\n31811,31812,31813,31814,31815,31816,31817,31818,31819,31820,31822,31823,31824,\n31825,31826,31827,31828,31829,31830,31831,31832,31833,31834,31835,31836,31837,\n31838,31839,31840,31841,31842,31843,31844,31845,31846,31847,31848,31849,31850,\n31851,31852,31853,31854,31855,31856,31857,31858,31861,31862,31863,31864,31865,\n31866,31870,31871,31872,31873,31874,31875,31876,31877,31878,31879,31880,31882,\n31883,31884,31885,31886,31887,31888,31891,31892,31894,31897,31898,31899,31904,\n31905,31907,31910,31911,31912,31913,31915,31916,31917,31919,31920,31924,31925,\n31926,31927,31928,31930,31931,24359,34382,21804,25252,20114,27818,25143,33457,\n21719,21326,29502,28369,30011,21010,21270,35805,27088,24458,24576,28142,22351,\n27426,29615,26707,36824,32531,25442,24739,21796,30186,35938,28949,28067,23462,\n24187,33618,24908,40644,30970,34647,31783,30343,20976,24822,29004,26179,24140,\n24653,35854,28784,25381,36745,24509,24674,34516,22238,27585,24724,24935,21321,\n24800,26214,36159,31229,20250,28905,27719,35763,35826,32472,33636,26127,23130,\n39746,27985,28151,35905,27963,20249,28779,33719,25110,24785,38669,36135,31096,\n20987,22334,22522,26426,30072,31293,31215,31637,31935,31936,31938,31939,31940,\n31942,31945,31947,31950,31951,31952,31953,31954,31955,31956,31960,31962,31963,\n31965,31966,31969,31970,31971,31972,31973,31974,31975,31977,31978,31979,31980,\n31981,31982,31984,31985,31986,31987,31988,31989,31990,31991,31993,31994,31996,\n31997,31998,31999,32000,32001,32002,32003,32004,32005,\n32006,32007,32008,32009,32011,32012,32013,32014,32015,32016,32017,32018,32019,\n32020,32021,32022,32023,32024,32025,32026,32027,32028,32029,32030,32031,32033,\n32035,32036,32037,32038,32040,32041,32042,32044,32045,32046,32048,32049,32050,\n32051,32052,32053,32054,32908,39269,36857,28608,35749,40481,23020,32489,32521,\n21513,26497,26840,36753,31821,38598,21450,24613,30142,27762,21363,23241,32423,\n25380,20960,33034,24049,34015,25216,20864,23395,20238,31085,21058,24760,27982,\n23492,23490,35745,35760,26082,24524,38469,22931,32487,32426,22025,26551,22841,\n20339,23478,21152,33626,39050,36158,30002,38078,20551,31292,20215,26550,39550,\n23233,27516,30417,22362,23574,31546,38388,29006,20860,32937,33392,22904,32516,\n33575,26816,26604,30897,30839,25315,25441,31616,20461,21098,20943,33616,27099,\n37492,36341,36145,35265,38190,31661,20214,32055,32056,32057,32058,32059,32060,\n32061,32062,32063,32064,32065,32066,32067,32068,32069,32070,32071,32072,32073,\n32074,32075,32076,32077,32078,32079,32080,32081,32082,32083,32084,32085,32086,\n32087,32088,32089,32090,32091,32092,32093,32094,32095,32096,32097,32098,32099,\n32100,32101,32102,32103,32104,32105,32106,32107,32108,32109,32111,32112,32113,\n32114,32115,32116,32117,32118,32120,32121,32122,32123,32124,32125,32126,32127,\n32128,32129,32130,32131,32132,32133,32134,32135,32136,32137,32138,32139,32140,\n32141,32142,32143,32144,32145,32146,32147,32148,32149,32150,32151,32152,20581,\n33328,21073,39279,28176,28293,28071,24314,20725,23004,23558,27974,27743,30086,\n33931,26728,22870,35762,21280,37233,38477,34121,26898,\n30977,28966,33014,20132,37066,27975,39556,23047,22204,25605,38128,30699,20389,\n33050,29409,35282,39290,32564,32478,21119,25945,37237,36735,36739,21483,31382,\n25581,25509,30342,31224,34903,38454,25130,21163,33410,26708,26480,25463,30571,\n31469,27905,32467,35299,22992,25106,34249,33445,30028,20511,20171,30117,35819,\n23626,24062,31563,26020,37329,20170,27941,35167,32039,38182,20165,35880,36827,\n38771,26187,31105,36817,28908,28024,32153,32154,32155,32156,32157,32158,32159,\n32160,32161,32162,32163,32164,32165,32167,32168,32169,32170,32171,32172,32173,\n32175,32176,32177,32178,32179,32180,32181,32182,32183,32184,32185,32186,32187,\n32188,32189,32190,32191,32192,32193,32194,32195,32196,32197,32198,32199,32200,\n32201,32202,32203,32204,32205,32206,32207,32208,32209,32210,32211,32212,32213,\n32214,32215,32216,32217,32218,32219,32220,32221,32222,32223,32224,32225,32226,\n32227,32228,32229,32230,32231,32232,32233,32234,32235,32236,32237,32238,32239,\n32240,32241,32242,32243,32244,32245,32246,32247,32248,32249,32250,23613,21170,\n33606,20834,33550,30555,26230,40120,20140,24778,31934,31923,32463,20117,35686,\n26223,39048,38745,22659,25964,38236,24452,30153,38742,31455,31454,20928,28847,\n31384,25578,31350,32416,29590,38893,20037,28792,20061,37202,21417,25937,26087,\n33276,33285,21646,23601,30106,38816,25304,29401,30141,23621,39545,33738,23616,\n21632,30697,20030,27822,32858,25298,25454,24040,20855,36317,36382,38191,20465,\n21477,24807,28844,21095,25424,40515,23071,20518,30519,21367,32482,25733,25899,\n25225,25496,20500,29237,35273,20915,35776,32477,22343,\n33740,38055,20891,21531,23803,32251,32252,32253,32254,32255,32256,32257,32258,\n32259,32260,32261,32262,32263,32264,32265,32266,32267,32268,32269,32270,32271,\n32272,32273,32274,32275,32276,32277,32278,32279,32280,32281,32282,32283,32284,\n32285,32286,32287,32288,32289,32290,32291,32292,32293,32294,32295,32296,32297,\n32298,32299,32300,32301,32302,32303,32304,32305,32306,32307,32308,32309,32310,\n32311,32312,32313,32314,32316,32317,32318,32319,32320,32322,32323,32324,32325,\n32326,32328,32329,32330,32331,32332,32333,32334,32335,32336,32337,32338,32339,\n32340,32341,32342,32343,32344,32345,32346,32347,32348,32349,20426,31459,27994,\n37089,39567,21888,21654,21345,21679,24320,25577,26999,20975,24936,21002,22570,\n21208,22350,30733,30475,24247,24951,31968,25179,25239,20130,28821,32771,25335,\n28900,38752,22391,33499,26607,26869,30933,39063,31185,22771,21683,21487,28212,\n20811,21051,23458,35838,32943,21827,22438,24691,22353,21549,31354,24656,23380,\n25511,25248,21475,25187,23495,26543,21741,31391,33510,37239,24211,35044,22840,\n22446,25358,36328,33007,22359,31607,20393,24555,23485,27454,21281,31568,29378,\n26694,30719,30518,26103,20917,20111,30420,23743,31397,33909,22862,39745,20608,\n32350,32351,32352,32353,32354,32355,32356,32357,32358,32359,32360,32361,32362,\n32363,32364,32365,32366,32367,32368,32369,32370,32371,32372,32373,32374,32375,\n32376,32377,32378,32379,32380,32381,32382,32383,32384,32385,32387,32388,32389,\n32390,32391,32392,32393,32394,32395,32396,32397,32398,32399,32400,32401,32402,\n32403,32404,32405,32406,32407,32408,32409,32410,32412,\n32413,32414,32430,32436,32443,32444,32470,32484,32492,32505,32522,32528,32542,\n32567,32569,32571,32572,32573,32574,32575,32576,32577,32579,32582,32583,32584,\n32585,32586,32587,32588,32589,32590,32591,32594,32595,39304,24871,28291,22372,\n26118,25414,22256,25324,25193,24275,38420,22403,25289,21895,34593,33098,36771,\n21862,33713,26469,36182,34013,23146,26639,25318,31726,38417,20848,28572,35888,\n25597,35272,25042,32518,28866,28389,29701,27028,29436,24266,37070,26391,28010,\n25438,21171,29282,32769,20332,23013,37226,28889,28061,21202,20048,38647,38253,\n34174,30922,32047,20769,22418,25794,32907,31867,27882,26865,26974,20919,21400,\n26792,29313,40654,31729,29432,31163,28435,29702,26446,37324,40100,31036,33673,\n33620,21519,26647,20029,21385,21169,30782,21382,21033,20616,20363,20432,32598,\n32601,32603,32604,32605,32606,32608,32611,32612,32613,32614,32615,32619,32620,\n32621,32623,32624,32627,32629,32630,32631,32632,32634,32635,32636,32637,32639,\n32640,32642,32643,32644,32645,32646,32647,32648,32649,32651,32653,32655,32656,\n32657,32658,32659,32661,32662,32663,32664,32665,32667,32668,32672,32674,32675,\n32677,32678,32680,32681,32682,32683,32684,32685,32686,32689,32691,32692,32693,\n32694,32695,32698,32699,32702,32704,32706,32707,32708,32710,32711,32712,32713,\n32715,32717,32719,32720,32721,32722,32723,32726,32727,32729,32730,32731,32732,\n32733,32734,32738,32739,30178,31435,31890,27813,38582,21147,29827,21737,20457,\n32852,33714,36830,38256,24265,24604,28063,24088,25947,33080,38142,24651,28860,\n32451,31918,20937,26753,31921,33391,20004,36742,37327,\n26238,20142,35845,25769,32842,20698,30103,29134,23525,36797,28518,20102,25730,\n38243,24278,26009,21015,35010,28872,21155,29454,29747,26519,30967,38678,20020,\n37051,40158,28107,20955,36161,21533,25294,29618,33777,38646,40836,38083,20278,\n32666,20940,28789,38517,23725,39046,21478,20196,28316,29705,27060,30827,39311,\n30041,21016,30244,27969,26611,20845,40857,32843,21657,31548,31423,32740,32743,\n32744,32746,32747,32748,32749,32751,32754,32756,32757,32758,32759,32760,32761,\n32762,32765,32766,32767,32770,32775,32776,32777,32778,32782,32783,32785,32787,\n32794,32795,32797,32798,32799,32801,32803,32804,32811,32812,32813,32814,32815,\n32816,32818,32820,32825,32826,32828,32830,32832,32833,32836,32837,32839,32840,\n32841,32846,32847,32848,32849,32851,32853,32854,32855,32857,32859,32860,32861,\n32862,32863,32864,32865,32866,32867,32868,32869,32870,32871,32872,32875,32876,\n32877,32878,32879,32880,32882,32883,32884,32885,32886,32887,32888,32889,32890,\n32891,32892,32893,38534,22404,25314,38471,27004,23044,25602,31699,28431,38475,\n33446,21346,39045,24208,28809,25523,21348,34383,40065,40595,30860,38706,36335,\n36162,40575,28510,31108,24405,38470,25134,39540,21525,38109,20387,26053,23653,\n23649,32533,34385,27695,24459,29575,28388,32511,23782,25371,23402,28390,21365,\n20081,25504,30053,25249,36718,20262,20177,27814,32438,35770,33821,34746,32599,\n36923,38179,31657,39585,35064,33853,27931,39558,32476,22920,40635,29595,30721,\n34434,39532,39554,22043,21527,22475,20080,40614,21334,36808,33033,30610,39314,\n34542,28385,34067,26364,24930,28459,32894,32897,32898,\n32901,32904,32906,32909,32910,32911,32912,32913,32914,32916,32917,32919,32921,\n32926,32931,32934,32935,32936,32940,32944,32947,32949,32950,32952,32953,32955,\n32965,32967,32968,32969,32970,32971,32975,32976,32977,32978,32979,32980,32981,\n32984,32991,32992,32994,32995,32998,33006,33013,33015,33017,33019,33022,33023,\n33024,33025,33027,33028,33029,33031,33032,33035,33036,33045,33047,33049,33051,\n33052,33053,33055,33056,33057,33058,33059,33060,33061,33062,33063,33064,33065,\n33066,33067,33069,33070,33072,33075,33076,33077,33079,33081,33082,33083,33084,\n33085,33087,35881,33426,33579,30450,27667,24537,33725,29483,33541,38170,27611,\n30683,38086,21359,33538,20882,24125,35980,36152,20040,29611,26522,26757,37238,\n38665,29028,27809,30473,23186,38209,27599,32654,26151,23504,22969,23194,38376,\n38391,20204,33804,33945,27308,30431,38192,29467,26790,23391,30511,37274,38753,\n31964,36855,35868,24357,31859,31192,35269,27852,34588,23494,24130,26825,30496,\n32501,20885,20813,21193,23081,32517,38754,33495,25551,30596,34256,31186,28218,\n24217,22937,34065,28781,27665,25279,30399,25935,24751,38397,26126,34719,40483,\n38125,21517,21629,35884,25720,33088,33089,33090,33091,33092,33093,33095,33097,\n33101,33102,33103,33106,33110,33111,33112,33115,33116,33117,33118,33119,33121,\n33122,33123,33124,33126,33128,33130,33131,33132,33135,33138,33139,33141,33142,\n33143,33144,33153,33155,33156,33157,33158,33159,33161,33163,33164,33165,33166,\n33168,33170,33171,33172,33173,33174,33175,33177,33178,33182,33183,33184,33185,\n33186,33188,33189,33191,33193,33195,33196,33197,33198,\n33199,33200,33201,33202,33204,33205,33206,33207,33208,33209,33212,33213,33214,\n33215,33220,33221,33223,33224,33225,33227,33229,33230,33231,33232,33233,33234,\n33235,25721,34321,27169,33180,30952,25705,39764,25273,26411,33707,22696,40664,\n27819,28448,23518,38476,35851,29279,26576,25287,29281,20137,22982,27597,22675,\n26286,24149,21215,24917,26408,30446,30566,29287,31302,25343,21738,21584,38048,\n37027,23068,32435,27670,20035,22902,32784,22856,21335,30007,38590,22218,25376,\n33041,24700,38393,28118,21602,39297,20869,23273,33021,22958,38675,20522,27877,\n23612,25311,20320,21311,33147,36870,28346,34091,25288,24180,30910,25781,25467,\n24565,23064,37247,40479,23615,25423,32834,23421,21870,38218,38221,28037,24744,\n26592,29406,20957,23425,33236,33237,33238,33239,33240,33241,33242,33243,33244,\n33245,33246,33247,33248,33249,33250,33252,33253,33254,33256,33257,33259,33262,\n33263,33264,33265,33266,33269,33270,33271,33272,33273,33274,33277,33279,33283,\n33287,33288,33289,33290,33291,33294,33295,33297,33299,33301,33302,33303,33304,\n33305,33306,33309,33312,33316,33317,33318,33319,33321,33326,33330,33338,33340,\n33341,33343,33344,33345,33346,33347,33349,33350,33352,33354,33356,33357,33358,\n33360,33361,33362,33363,33364,33365,33366,33367,33369,33371,33372,33373,33374,\n33376,33377,33378,33379,33380,33381,33382,33383,33385,25319,27870,29275,25197,\n38062,32445,33043,27987,20892,24324,22900,21162,24594,22899,26262,34384,30111,\n25386,25062,31983,35834,21734,27431,40485,27572,34261,21589,20598,27812,21866,\n36276,29228,24085,24597,29750,25293,25490,29260,24472,\n28227,27966,25856,28504,30424,30928,30460,30036,21028,21467,20051,24222,26049,\n32810,32982,25243,21638,21032,28846,34957,36305,27873,21624,32986,22521,35060,\n36180,38506,37197,20329,27803,21943,30406,30768,25256,28921,28558,24429,34028,\n26842,30844,31735,33192,26379,40527,25447,30896,22383,30738,38713,25209,25259,\n21128,29749,27607,33386,33387,33388,33389,33393,33397,33398,33399,33400,33403,\n33404,33408,33409,33411,33413,33414,33415,33417,33420,33424,33427,33428,33429,\n33430,33434,33435,33438,33440,33442,33443,33447,33458,33461,33462,33466,33467,\n33468,33471,33472,33474,33475,33477,33478,33481,33488,33494,33497,33498,33501,\n33506,33511,33512,33513,33514,33516,33517,33518,33520,33522,33523,33525,33526,\n33528,33530,33532,33533,33534,33535,33536,33546,33547,33549,33552,33554,33555,\n33558,33560,33561,33565,33566,33567,33568,33569,33570,33571,33572,33573,33574,\n33577,33578,33582,33584,33586,33591,33595,33597,21860,33086,30130,30382,21305,\n30174,20731,23617,35692,31687,20559,29255,39575,39128,28418,29922,31080,25735,\n30629,25340,39057,36139,21697,32856,20050,22378,33529,33805,24179,20973,29942,\n35780,23631,22369,27900,39047,23110,30772,39748,36843,31893,21078,25169,38138,\n20166,33670,33889,33769,33970,22484,26420,22275,26222,28006,35889,26333,28689,\n26399,27450,26646,25114,22971,19971,20932,28422,26578,27791,20854,26827,22855,\n27495,30054,23822,33040,40784,26071,31048,31041,39569,36215,23682,20062,20225,\n21551,22865,30732,22120,27668,36804,24323,27773,27875,35755,25488,33598,33599,\n33601,33602,33604,33605,33608,33610,33611,33612,33613,\n33614,33619,33621,33622,33623,33624,33625,33629,33634,33648,33649,33650,33651,\n33652,33653,33654,33657,33658,33662,33663,33664,33665,33666,33667,33668,33671,\n33672,33674,33675,33676,33677,33679,33680,33681,33684,33685,33686,33687,33689,\n33690,33693,33695,33697,33698,33699,33700,33701,33702,33703,33708,33709,33710,\n33711,33717,33723,33726,33727,33730,33731,33732,33734,33736,33737,33739,33741,\n33742,33744,33745,33746,33747,33749,33751,33753,33754,33755,33758,33762,33763,\n33764,33766,33767,33768,33771,33772,33773,24688,27965,29301,25190,38030,38085,\n21315,36801,31614,20191,35878,20094,40660,38065,38067,21069,28508,36963,27973,\n35892,22545,23884,27424,27465,26538,21595,33108,32652,22681,34103,24378,25250,\n27207,38201,25970,24708,26725,30631,20052,20392,24039,38808,25772,32728,23789,\n20431,31373,20999,33540,19988,24623,31363,38054,20405,20146,31206,29748,21220,\n33465,25810,31165,23517,27777,38738,36731,27682,20542,21375,28165,25806,26228,\n27696,24773,39031,35831,24198,29756,31351,31179,19992,37041,29699,27714,22234,\n37195,27845,36235,21306,34502,26354,36527,23624,39537,28192,33774,33775,33779,\n33780,33781,33782,33783,33786,33787,33788,33790,33791,33792,33794,33797,33799,\n33800,33801,33802,33808,33810,33811,33812,33813,33814,33815,33817,33818,33819,\n33822,33823,33824,33825,33826,33827,33833,33834,33835,33836,33837,33838,33839,\n33840,33842,33843,33844,33845,33846,33847,33849,33850,33851,33854,33855,33856,\n33857,33858,33859,33860,33861,33863,33864,33865,33866,33867,33868,33869,33870,\n33871,33872,33874,33875,33876,33877,33878,33880,33885,\n33886,33887,33888,33890,33892,33893,33894,33895,33896,33898,33902,33903,33904,\n33906,33908,33911,33913,33915,33916,21462,23094,40843,36259,21435,22280,39079,\n26435,37275,27849,20840,30154,25331,29356,21048,21149,32570,28820,30264,21364,\n40522,27063,30830,38592,35033,32676,28982,29123,20873,26579,29924,22756,25880,\n22199,35753,39286,25200,32469,24825,28909,22764,20161,20154,24525,38887,20219,\n35748,20995,22922,32427,25172,20173,26085,25102,33592,33993,33635,34701,29076,\n28342,23481,32466,20887,25545,26580,32905,33593,34837,20754,23418,22914,36785,\n20083,27741,20837,35109,36719,38446,34122,29790,38160,38384,28070,33509,24369,\n25746,27922,33832,33134,40131,22622,36187,19977,21441,33917,33918,33919,33920,\n33921,33923,33924,33925,33926,33930,33933,33935,33936,33937,33938,33939,33940,\n33941,33942,33944,33946,33947,33949,33950,33951,33952,33954,33955,33956,33957,\n33958,33959,33960,33961,33962,33963,33964,33965,33966,33968,33969,33971,33973,\n33974,33975,33979,33980,33982,33984,33986,33987,33989,33990,33991,33992,33995,\n33996,33998,33999,34002,34004,34005,34007,34008,34009,34010,34011,34012,34014,\n34017,34018,34020,34023,34024,34025,34026,34027,34029,34030,34031,34033,34034,\n34035,34036,34037,34038,34039,34040,34041,34042,34043,34045,34046,34048,34049,\n34050,20254,25955,26705,21971,20007,25620,39578,25195,23234,29791,33394,28073,\n26862,20711,33678,30722,26432,21049,27801,32433,20667,21861,29022,31579,26194,\n29642,33515,26441,23665,21024,29053,34923,38378,38485,25797,36193,33203,21892,\n27733,25159,32558,22674,20260,21830,36175,26188,19978,\n23578,35059,26786,25422,31245,28903,33421,21242,38902,23569,21736,37045,32461,\n22882,36170,34503,33292,33293,36198,25668,23556,24913,28041,31038,35774,30775,\n30003,21627,20280,36523,28145,23072,32453,31070,27784,23457,23158,29978,32958,\n24910,28183,22768,29983,29989,29298,21319,32499,34051,34052,34053,34054,34055,\n34056,34057,34058,34059,34061,34062,34063,34064,34066,34068,34069,34070,34072,\n34073,34075,34076,34077,34078,34080,34082,34083,34084,34085,34086,34087,34088,\n34089,34090,34093,34094,34095,34096,34097,34098,34099,34100,34101,34102,34110,\n34111,34112,34113,34114,34116,34117,34118,34119,34123,34124,34125,34126,34127,\n34128,34129,34130,34131,34132,34133,34135,34136,34138,34139,34140,34141,34143,\n34144,34145,34146,34147,34149,34150,34151,34153,34154,34155,34156,34157,34158,\n34159,34160,34161,34163,34165,34166,34167,34168,34172,34173,34175,34176,34177,\n30465,30427,21097,32988,22307,24072,22833,29422,26045,28287,35799,23608,34417,\n21313,30707,25342,26102,20160,39135,34432,23454,35782,21490,30690,20351,23630,\n39542,22987,24335,31034,22763,19990,26623,20107,25325,35475,36893,21183,26159,\n21980,22124,36866,20181,20365,37322,39280,27663,24066,24643,23460,35270,35797,\n25910,25163,39318,23432,23551,25480,21806,21463,30246,20861,34092,26530,26803,\n27530,25234,36755,21460,33298,28113,30095,20070,36174,23408,29087,34223,26257,\n26329,32626,34560,40653,40736,23646,26415,36848,26641,26463,25101,31446,22661,\n24246,25968,28465,34178,34179,34182,34184,34185,34186,34187,34188,34189,34190,\n34192,34193,34194,34195,34196,34197,34198,34199,34200,\n34201,34202,34205,34206,34207,34208,34209,34210,34211,34213,34214,34215,34217,\n34219,34220,34221,34225,34226,34227,34228,34229,34230,34232,34234,34235,34236,\n34237,34238,34239,34240,34242,34243,34244,34245,34246,34247,34248,34250,34251,\n34252,34253,34254,34257,34258,34260,34262,34263,34264,34265,34266,34267,34269,\n34270,34271,34272,34273,34274,34275,34277,34278,34279,34280,34282,34283,34284,\n34285,34286,34287,34288,34289,34290,34291,34292,34293,34294,34295,34296,24661,\n21047,32781,25684,34928,29993,24069,26643,25332,38684,21452,29245,35841,27700,\n30561,31246,21550,30636,39034,33308,35828,30805,26388,28865,26031,25749,22070,\n24605,31169,21496,19997,27515,32902,23546,21987,22235,20282,20284,39282,24051,\n26494,32824,24578,39042,36865,23435,35772,35829,25628,33368,25822,22013,33487,\n37221,20439,32032,36895,31903,20723,22609,28335,23487,35785,32899,37240,33948,\n31639,34429,38539,38543,32485,39635,30862,23681,31319,36930,38567,31071,23385,\n25439,31499,34001,26797,21766,32553,29712,32034,38145,25152,22604,20182,23427,\n22905,22612,34297,34298,34300,34301,34302,34304,34305,34306,34307,34308,34310,\n34311,34312,34313,34314,34315,34316,34317,34318,34319,34320,34322,34323,34324,\n34325,34327,34328,34329,34330,34331,34332,34333,34334,34335,34336,34337,34338,\n34339,34340,34341,34342,34344,34346,34347,34348,34349,34350,34351,34352,34353,\n34354,34355,34356,34357,34358,34359,34361,34362,34363,34365,34366,34367,34368,\n34369,34370,34371,34372,34373,34374,34375,34376,34377,34378,34379,34380,34386,\n34387,34389,34390,34391,34392,34393,34395,34396,34397,\n34399,34400,34401,34403,34404,34405,34406,34407,34408,34409,34410,29549,25374,\n36427,36367,32974,33492,25260,21488,27888,37214,22826,24577,27760,22349,25674,\n36138,30251,28393,22363,27264,30192,28525,35885,35848,22374,27631,34962,30899,\n25506,21497,28845,27748,22616,25642,22530,26848,33179,21776,31958,20504,36538,\n28108,36255,28907,25487,28059,28372,32486,33796,26691,36867,28120,38518,35752,\n22871,29305,34276,33150,30140,35466,26799,21076,36386,38161,25552,39064,36420,\n21884,20307,26367,22159,24789,28053,21059,23625,22825,28155,22635,30000,29980,\n24684,33300,33094,25361,26465,36834,30522,36339,36148,38081,24086,21381,21548,\n28867,34413,34415,34416,34418,34419,34420,34421,34422,34423,34424,34435,34436,\n34437,34438,34439,34440,34441,34446,34447,34448,34449,34450,34452,34454,34455,\n34456,34457,34458,34459,34462,34463,34464,34465,34466,34469,34470,34475,34477,\n34478,34482,34483,34487,34488,34489,34491,34492,34493,34494,34495,34497,34498,\n34499,34501,34504,34508,34509,34514,34515,34517,34518,34519,34522,34524,34525,\n34528,34529,34530,34531,34533,34534,34535,34536,34538,34539,34540,34543,34549,\n34550,34551,34554,34555,34556,34557,34559,34561,34564,34565,34566,34571,34572,\n34574,34575,34576,34577,34580,34582,27712,24311,20572,20141,24237,25402,33351,\n36890,26704,37230,30643,21516,38108,24420,31461,26742,25413,31570,32479,30171,\n20599,25237,22836,36879,20984,31171,31361,22270,24466,36884,28034,23648,22303,\n21520,20820,28237,22242,25512,39059,33151,34581,35114,36864,21534,23663,33216,\n25302,25176,33073,40501,38464,39534,39548,26925,22949,\n25299,21822,25366,21703,34521,27964,23043,29926,34972,27498,22806,35916,24367,\n28286,29609,39037,20024,28919,23436,30871,25405,26202,30358,24779,23451,23113,\n19975,33109,27754,29579,20129,26505,32593,24448,26106,26395,24536,22916,23041,\n34585,34587,34589,34591,34592,34596,34598,34599,34600,34602,34603,34604,34605,\n34607,34608,34610,34611,34613,34614,34616,34617,34618,34620,34621,34624,34625,\n34626,34627,34628,34629,34630,34634,34635,34637,34639,34640,34641,34642,34644,\n34645,34646,34648,34650,34651,34652,34653,34654,34655,34657,34658,34662,34663,\n34664,34665,34666,34667,34668,34669,34671,34673,34674,34675,34677,34679,34680,\n34681,34682,34687,34688,34689,34692,34694,34695,34697,34698,34700,34702,34703,\n34704,34705,34706,34708,34709,34710,34712,34713,34714,34715,34716,34717,34718,\n34720,34721,34722,34723,34724,24013,24494,21361,38886,36829,26693,22260,21807,\n24799,20026,28493,32500,33479,33806,22996,20255,20266,23614,32428,26410,34074,\n21619,30031,32963,21890,39759,20301,28205,35859,23561,24944,21355,30239,28201,\n34442,25991,38395,32441,21563,31283,32010,38382,21985,32705,29934,25373,34583,\n28065,31389,25105,26017,21351,25569,27779,24043,21596,38056,20044,27745,35820,\n23627,26080,33436,26791,21566,21556,27595,27494,20116,25410,21320,33310,20237,\n20398,22366,25098,38654,26212,29289,21247,21153,24735,35823,26132,29081,26512,\n35199,30802,30717,26224,22075,21560,38177,29306,34725,34726,34727,34729,34730,\n34734,34736,34737,34738,34740,34742,34743,34744,34745,34747,34748,34750,34751,\n34753,34754,34755,34756,34757,34759,34760,34761,34764,\n34765,34766,34767,34768,34772,34773,34774,34775,34776,34777,34778,34780,34781,\n34782,34783,34785,34786,34787,34788,34790,34791,34792,34793,34795,34796,34797,\n34799,34800,34801,34802,34803,34804,34805,34806,34807,34808,34810,34811,34812,\n34813,34815,34816,34817,34818,34820,34821,34822,34823,34824,34825,34827,34828,\n34829,34830,34831,34832,34833,34834,34836,34839,34840,34841,34842,34844,34845,\n34846,34847,34848,34851,31232,24687,24076,24713,33181,22805,24796,29060,28911,\n28330,27728,29312,27268,34989,24109,20064,23219,21916,38115,27927,31995,38553,\n25103,32454,30606,34430,21283,38686,36758,26247,23777,20384,29421,19979,21414,\n22799,21523,25472,38184,20808,20185,40092,32420,21688,36132,34900,33335,38386,\n28046,24358,23244,26174,38505,29616,29486,21439,33146,39301,32673,23466,38519,\n38480,32447,30456,21410,38262,39321,31665,35140,28248,20065,32724,31077,35814,\n24819,21709,20139,39033,24055,27233,20687,21521,35937,33831,30813,38660,21066,\n21742,22179,38144,28040,23477,28102,26195,34852,34853,34854,34855,34856,34857,\n34858,34859,34860,34861,34862,34863,34864,34865,34867,34868,34869,34870,34871,\n34872,34874,34875,34877,34878,34879,34881,34882,34883,34886,34887,34888,34889,\n34890,34891,34894,34895,34896,34897,34898,34899,34901,34902,34904,34906,34907,\n34908,34909,34910,34911,34912,34918,34919,34922,34925,34927,34929,34931,34932,\n34933,34934,34936,34937,34938,34939,34940,34944,34947,34950,34951,34953,34954,\n34956,34958,34959,34960,34961,34963,34964,34965,34967,34968,34969,34970,34971,\n34973,34974,34975,34976,34977,34979,34981,34982,34983,\n34984,34985,34986,23567,23389,26657,32918,21880,31505,25928,26964,20123,27463,\n34638,38795,21327,25375,25658,37034,26012,32961,35856,20889,26800,21368,34809,\n25032,27844,27899,35874,23633,34218,33455,38156,27427,36763,26032,24571,24515,\n20449,34885,26143,33125,29481,24826,20852,21009,22411,24418,37026,34892,37266,\n24184,26447,24615,22995,20804,20982,33016,21256,27769,38596,29066,20241,20462,\n32670,26429,21957,38152,31168,34966,32483,22687,25100,38656,34394,22040,39035,\n24464,35768,33988,37207,21465,26093,24207,30044,24676,32110,23167,32490,32493,\n36713,21927,23459,24748,26059,29572,34988,34990,34991,34992,34994,34995,34996,\n34997,34998,35000,35001,35002,35003,35005,35006,35007,35008,35011,35012,35015,\n35016,35018,35019,35020,35021,35023,35024,35025,35027,35030,35031,35034,35035,\n35036,35037,35038,35040,35041,35046,35047,35049,35050,35051,35052,35053,35054,\n35055,35058,35061,35062,35063,35066,35067,35069,35071,35072,35073,35075,35076,\n35077,35078,35079,35080,35081,35083,35084,35085,35086,35087,35089,35092,35093,\n35094,35095,35096,35100,35101,35102,35103,35104,35106,35107,35108,35110,35111,\n35112,35113,35116,35117,35118,35119,35121,35122,35123,35125,35127,36873,30307,\n30505,32474,38772,34203,23398,31348,38634,34880,21195,29071,24490,26092,35810,\n23547,39535,24033,27529,27739,35757,35759,36874,36805,21387,25276,40486,40493,\n21568,20011,33469,29273,34460,23830,34905,28079,38597,21713,20122,35766,28937,\n21693,38409,28895,28153,30416,20005,30740,34578,23721,24310,35328,39068,38414,\n28814,27839,22852,25513,30524,34893,28436,33395,22576,\n29141,21388,30746,38593,21761,24422,28976,23476,35866,39564,27523,22830,40495,\n31207,26472,25196,20335,30113,32650,27915,38451,27687,20208,30162,20859,26679,\n28478,36992,33136,22934,29814,35128,35129,35130,35131,35132,35133,35134,35135,\n35136,35138,35139,35141,35142,35143,35144,35145,35146,35147,35148,35149,35150,\n35151,35152,35153,35154,35155,35156,35157,35158,35159,35160,35161,35162,35163,\n35164,35165,35168,35169,35170,35171,35172,35173,35175,35176,35177,35178,35179,\n35180,35181,35182,35183,35184,35185,35186,35187,35188,35189,35190,35191,35192,\n35193,35194,35196,35197,35198,35200,35202,35204,35205,35207,35208,35209,35210,\n35211,35212,35213,35214,35215,35216,35217,35218,35219,35220,35221,35222,35223,\n35224,35225,35226,35227,35228,35229,35230,35231,35232,35233,25671,23591,36965,\n31377,35875,23002,21676,33280,33647,35201,32768,26928,22094,32822,29239,37326,\n20918,20063,39029,25494,19994,21494,26355,33099,22812,28082,19968,22777,21307,\n25558,38129,20381,20234,34915,39056,22839,36951,31227,20202,33008,30097,27778,\n23452,23016,24413,26885,34433,20506,24050,20057,30691,20197,33402,25233,26131,\n37009,23673,20159,24441,33222,36920,32900,30123,20134,35028,24847,27589,24518,\n20041,30410,28322,35811,35758,35850,35793,24322,32764,32716,32462,33589,33643,\n22240,27575,38899,38452,23035,21535,38134,28139,23493,39278,23609,24341,38544,\n35234,35235,35236,35237,35238,35239,35240,35241,35242,35243,35244,35245,35246,\n35247,35248,35249,35250,35251,35252,35253,35254,35255,35256,35257,35258,35259,\n35260,35261,35262,35263,35264,35267,35277,35283,35284,\n35285,35287,35288,35289,35291,35293,35295,35296,35297,35298,35300,35303,35304,\n35305,35306,35308,35309,35310,35312,35313,35314,35316,35317,35318,35319,35320,\n35321,35322,35323,35324,35325,35326,35327,35329,35330,35331,35332,35333,35334,\n35336,35337,35338,35339,35340,35341,35342,35343,35344,35345,35346,35347,35348,\n35349,35350,35351,35352,35353,35354,35355,35356,35357,21360,33521,27185,23156,\n40560,24212,32552,33721,33828,33829,33639,34631,36814,36194,30408,24433,39062,\n30828,26144,21727,25317,20323,33219,30152,24248,38605,36362,34553,21647,27891,\n28044,27704,24703,21191,29992,24189,20248,24736,24551,23588,30001,37038,38080,\n29369,27833,28216,37193,26377,21451,21491,20305,37321,35825,21448,24188,36802,\n28132,20110,30402,27014,34398,24858,33286,20313,20446,36926,40060,24841,28189,\n28180,38533,20104,23089,38632,19982,23679,31161,23431,35821,32701,29577,22495,\n33419,37057,21505,36935,21947,23786,24481,24840,27442,29425,32946,35465,35358,\n35359,35360,35361,35362,35363,35364,35365,35366,35367,35368,35369,35370,35371,\n35372,35373,35374,35375,35376,35377,35378,35379,35380,35381,35382,35383,35384,\n35385,35386,35387,35388,35389,35391,35392,35393,35394,35395,35396,35397,35398,\n35399,35401,35402,35403,35404,35405,35406,35407,35408,35409,35410,35411,35412,\n35413,35414,35415,35416,35417,35418,35419,35420,35421,35422,35423,35424,35425,\n35426,35427,35428,35429,35430,35431,35432,35433,35434,35435,35436,35437,35438,\n35439,35440,35441,35442,35443,35444,35445,35446,35447,35448,35450,35451,35452,\n35453,35454,35455,35456,28020,23507,35029,39044,35947,\n39533,40499,28170,20900,20803,22435,34945,21407,25588,36757,22253,21592,22278,\n29503,28304,32536,36828,33489,24895,24616,38498,26352,32422,36234,36291,38053,\n23731,31908,26376,24742,38405,32792,20113,37095,21248,38504,20801,36816,34164,\n37213,26197,38901,23381,21277,30776,26434,26685,21705,28798,23472,36733,20877,\n22312,21681,25874,26242,36190,36163,33039,33900,36973,31967,20991,34299,26531,\n26089,28577,34468,36481,22122,36896,30338,28790,29157,36131,25321,21017,27901,\n36156,24590,22686,24974,26366,36192,25166,21939,28195,26413,36711,35457,35458,\n35459,35460,35461,35462,35463,35464,35467,35468,35469,35470,35471,35472,35473,\n35474,35476,35477,35478,35479,35480,35481,35482,35483,35484,35485,35486,35487,\n35488,35489,35490,35491,35492,35493,35494,35495,35496,35497,35498,35499,35500,\n35501,35502,35503,35504,35505,35506,35507,35508,35509,35510,35511,35512,35513,\n35514,35515,35516,35517,35518,35519,35520,35521,35522,35523,35524,35525,35526,\n35527,35528,35529,35530,35531,35532,35533,35534,35535,35536,35537,35538,35539,\n35540,35541,35542,35543,35544,35545,35546,35547,35548,35549,35550,35551,35552,\n35553,35554,35555,38113,38392,30504,26629,27048,21643,20045,28856,35784,25688,\n25995,23429,31364,20538,23528,30651,27617,35449,31896,27838,30415,26025,36759,\n23853,23637,34360,26632,21344,25112,31449,28251,32509,27167,31456,24432,28467,\n24352,25484,28072,26454,19976,24080,36134,20183,32960,30260,38556,25307,26157,\n25214,27836,36213,29031,32617,20806,32903,21484,36974,25240,21746,34544,36761,\n32773,38167,34071,36825,27993,29645,26015,30495,29956,\n30759,33275,36126,38024,20390,26517,30137,35786,38663,25391,38215,38453,33976,\n25379,30529,24449,29424,20105,24596,25972,25327,27491,25919,35556,35557,35558,\n35559,35560,35561,35562,35563,35564,35565,35566,35567,35568,35569,35570,35571,\n35572,35573,35574,35575,35576,35577,35578,35579,35580,35581,35582,35583,35584,\n35585,35586,35587,35588,35589,35590,35592,35593,35594,35595,35596,35597,35598,\n35599,35600,35601,35602,35603,35604,35605,35606,35607,35608,35609,35610,35611,\n35612,35613,35614,35615,35616,35617,35618,35619,35620,35621,35623,35624,35625,\n35626,35627,35628,35629,35630,35631,35632,35633,35634,35635,35636,35637,35638,\n35639,35640,35641,35642,35643,35644,35645,35646,35647,35648,35649,35650,35651,\n35652,35653,24103,30151,37073,35777,33437,26525,25903,21553,34584,30693,32930,\n33026,27713,20043,32455,32844,30452,26893,27542,25191,20540,20356,22336,25351,\n27490,36286,21482,26088,32440,24535,25370,25527,33267,33268,32622,24092,23769,\n21046,26234,31209,31258,36136,28825,30164,28382,27835,31378,20013,30405,24544,\n38047,34935,32456,31181,32959,37325,20210,20247,33311,21608,24030,27954,35788,\n31909,36724,32920,24090,21650,30385,23449,26172,39588,29664,26666,34523,26417,\n29482,35832,35803,36880,31481,28891,29038,25284,30633,22065,20027,33879,26609,\n21161,34496,36142,38136,31569,35654,35655,35656,35657,35658,35659,35660,35661,\n35662,35663,35664,35665,35666,35667,35668,35669,35670,35671,35672,35673,35674,\n35675,35676,35677,35678,35679,35680,35681,35682,35683,35684,35685,35687,35688,\n35689,35690,35691,35693,35694,35695,35696,35697,35698,\n35699,35700,35701,35702,35703,35704,35705,35706,35707,35708,35709,35710,35711,\n35712,35713,35714,35715,35716,35717,35718,35719,35720,35721,35722,35723,35724,\n35725,35726,35727,35728,35729,35730,35731,35732,35733,35734,35735,35736,35737,\n35738,35739,35740,35741,35742,35743,35756,35761,35771,35783,35792,35818,35849,\n35870,20303,27880,31069,39547,25235,29226,25341,19987,30742,36716,25776,36186,\n31686,26729,24196,35013,22918,25758,22766,29366,26894,38181,36861,36184,22368,\n32512,35846,20934,25417,25305,21331,26700,29730,33537,37196,21828,30528,28796,\n27978,20857,21672,36164,23039,28363,28100,23388,32043,20180,31869,28371,23376,\n33258,28173,23383,39683,26837,36394,23447,32508,24635,32437,37049,36208,22863,\n25549,31199,36275,21330,26063,31062,35781,38459,32452,38075,32386,22068,37257,\n26368,32618,23562,36981,26152,24038,20304,26590,20570,20316,22352,24231,59408,\n59409,59410,59411,59412,35896,35897,35898,35899,35900,35901,35902,35903,35904,\n35906,35907,35908,35909,35912,35914,35915,35917,35918,35919,35920,35921,35922,\n35923,35924,35926,35927,35928,35929,35931,35932,35933,35934,35935,35936,35939,\n35940,35941,35942,35943,35944,35945,35948,35949,35950,35951,35952,35953,35954,\n35956,35957,35958,35959,35963,35964,35965,35966,35967,35968,35969,35971,35972,\n35974,35975,35976,35979,35981,35982,35983,35984,35985,35986,35987,35989,35990,\n35991,35993,35994,35995,35996,35997,35998,35999,36000,36001,36002,36003,36004,\n36005,36006,36007,36008,36009,36010,36011,36012,36013,20109,19980,20800,19984,\n24319,21317,19989,20120,19998,39730,23404,22121,20008,\n31162,20031,21269,20039,22829,29243,21358,27664,22239,32996,39319,27603,30590,\n40727,20022,20127,40720,20060,20073,20115,33416,23387,21868,22031,20164,21389,\n21405,21411,21413,21422,38757,36189,21274,21493,21286,21294,21310,36188,21350,\n21347,20994,21000,21006,21037,21043,21055,21056,21068,21086,21089,21084,33967,\n21117,21122,21121,21136,21139,20866,32596,20155,20163,20169,20162,20200,20193,\n20203,20190,20251,20211,20258,20324,20213,20261,20263,20233,20267,20318,20327,\n25912,20314,20317,36014,36015,36016,36017,36018,36019,36020,36021,36022,36023,\n36024,36025,36026,36027,36028,36029,36030,36031,36032,36033,36034,36035,36036,\n36037,36038,36039,36040,36041,36042,36043,36044,36045,36046,36047,36048,36049,\n36050,36051,36052,36053,36054,36055,36056,36057,36058,36059,36060,36061,36062,\n36063,36064,36065,36066,36067,36068,36069,36070,36071,36072,36073,36074,36075,\n36076,36077,36078,36079,36080,36081,36082,36083,36084,36085,36086,36087,36088,\n36089,36090,36091,36092,36093,36094,36095,36096,36097,36098,36099,36100,36101,\n36102,36103,36104,36105,36106,36107,36108,36109,20319,20311,20274,20285,20342,\n20340,20369,20361,20355,20367,20350,20347,20394,20348,20396,20372,20454,20456,\n20458,20421,20442,20451,20444,20433,20447,20472,20521,20556,20467,20524,20495,\n20526,20525,20478,20508,20492,20517,20520,20606,20547,20565,20552,20558,20588,\n20603,20645,20647,20649,20666,20694,20742,20717,20716,20710,20718,20743,20747,\n20189,27709,20312,20325,20430,40864,27718,31860,20846,24061,40649,39320,20865,\n22804,21241,21261,35335,21264,20971,22809,20821,20128,\n20822,20147,34926,34980,20149,33044,35026,31104,23348,34819,32696,20907,20913,\n20925,20924,36110,36111,36112,36113,36114,36115,36116,36117,36118,36119,36120,\n36121,36122,36123,36124,36128,36177,36178,36183,36191,36197,36200,36201,36202,\n36204,36206,36207,36209,36210,36216,36217,36218,36219,36220,36221,36222,36223,\n36224,36226,36227,36230,36231,36232,36233,36236,36237,36238,36239,36240,36242,\n36243,36245,36246,36247,36248,36249,36250,36251,36252,36253,36254,36256,36257,\n36258,36260,36261,36262,36263,36264,36265,36266,36267,36268,36269,36270,36271,\n36272,36274,36278,36279,36281,36283,36285,36288,36289,36290,36293,36295,36296,\n36297,36298,36301,36304,36306,36307,36308,20935,20886,20898,20901,35744,35750,\n35751,35754,35764,35765,35767,35778,35779,35787,35791,35790,35794,35795,35796,\n35798,35800,35801,35804,35807,35808,35812,35816,35817,35822,35824,35827,35830,\n35833,35836,35839,35840,35842,35844,35847,35852,35855,35857,35858,35860,35861,\n35862,35865,35867,35864,35869,35871,35872,35873,35877,35879,35882,35883,35886,\n35887,35890,35891,35893,35894,21353,21370,38429,38434,38433,38449,38442,38461,\n38460,38466,38473,38484,38495,38503,38508,38514,38516,38536,38541,38551,38576,\n37015,37019,37021,37017,37036,37025,37044,37043,37046,37050,36309,36312,36313,\n36316,36320,36321,36322,36325,36326,36327,36329,36333,36334,36336,36337,36338,\n36340,36342,36348,36350,36351,36352,36353,36354,36355,36356,36358,36359,36360,\n36363,36365,36366,36368,36369,36370,36371,36373,36374,36375,36376,36377,36378,\n36379,36380,36384,36385,36388,36389,36390,36391,36392,\n36395,36397,36400,36402,36403,36404,36406,36407,36408,36411,36412,36414,36415,\n36419,36421,36422,36428,36429,36430,36431,36432,36435,36436,36437,36438,36439,\n36440,36442,36443,36444,36445,36446,36447,36448,36449,36450,36451,36452,36453,\n36455,36456,36458,36459,36462,36465,37048,37040,37071,37061,37054,37072,37060,\n37063,37075,37094,37090,37084,37079,37083,37099,37103,37118,37124,37154,37150,\n37155,37169,37167,37177,37187,37190,21005,22850,21154,21164,21165,21182,21759,\n21200,21206,21232,21471,29166,30669,24308,20981,20988,39727,21430,24321,30042,\n24047,22348,22441,22433,22654,22716,22725,22737,22313,22316,22314,22323,22329,\n22318,22319,22364,22331,22338,22377,22405,22379,22406,22396,22395,22376,22381,\n22390,22387,22445,22436,22412,22450,22479,22439,22452,22419,22432,22485,22488,\n22490,22489,22482,22456,22516,22511,22520,22500,22493,36467,36469,36471,36472,\n36473,36474,36475,36477,36478,36480,36482,36483,36484,36486,36488,36489,36490,\n36491,36492,36493,36494,36497,36498,36499,36501,36502,36503,36504,36505,36506,\n36507,36509,36511,36512,36513,36514,36515,36516,36517,36518,36519,36520,36521,\n36522,36525,36526,36528,36529,36531,36532,36533,36534,36535,36536,36537,36539,\n36540,36541,36542,36543,36544,36545,36546,36547,36548,36549,36550,36551,36552,\n36553,36554,36555,36556,36557,36559,36560,36561,36562,36563,36564,36565,36566,\n36567,36568,36569,36570,36571,36572,36573,36574,36575,36576,36577,36578,36579,\n36580,22539,22541,22525,22509,22528,22558,22553,22596,22560,22629,22636,22657,\n22665,22682,22656,39336,40729,25087,33401,33405,33407,\n33423,33418,33448,33412,33422,33425,33431,33433,33451,33464,33470,33456,33480,\n33482,33507,33432,33463,33454,33483,33484,33473,33449,33460,33441,33450,33439,\n33476,33486,33444,33505,33545,33527,33508,33551,33543,33500,33524,33490,33496,\n33548,33531,33491,33553,33562,33542,33556,33557,33504,33493,33564,33617,33627,\n33628,33544,33682,33596,33588,33585,33691,33630,33583,33615,33607,33603,33631,\n33600,33559,33632,33581,33594,33587,33638,33637,36581,36582,36583,36584,36585,\n36586,36587,36588,36589,36590,36591,36592,36593,36594,36595,36596,36597,36598,\n36599,36600,36601,36602,36603,36604,36605,36606,36607,36608,36609,36610,36611,\n36612,36613,36614,36615,36616,36617,36618,36619,36620,36621,36622,36623,36624,\n36625,36626,36627,36628,36629,36630,36631,36632,36633,36634,36635,36636,36637,\n36638,36639,36640,36641,36642,36643,36644,36645,36646,36647,36648,36649,36650,\n36651,36652,36653,36654,36655,36656,36657,36658,36659,36660,36661,36662,36663,\n36664,36665,36666,36667,36668,36669,36670,36671,36672,36673,36674,36675,36676,\n33640,33563,33641,33644,33642,33645,33646,33712,33656,33715,33716,33696,33706,\n33683,33692,33669,33660,33718,33705,33661,33720,33659,33688,33694,33704,33722,\n33724,33729,33793,33765,33752,22535,33816,33803,33757,33789,33750,33820,33848,\n33809,33798,33748,33759,33807,33795,33784,33785,33770,33733,33728,33830,33776,\n33761,33884,33873,33882,33881,33907,33927,33928,33914,33929,33912,33852,33862,\n33897,33910,33932,33934,33841,33901,33985,33997,34000,34022,33981,34003,33994,\n33983,33978,34016,33953,33977,33972,33943,34021,34019,\n34060,29965,34104,34032,34105,34079,34106,36677,36678,36679,36680,36681,36682,\n36683,36684,36685,36686,36687,36688,36689,36690,36691,36692,36693,36694,36695,\n36696,36697,36698,36699,36700,36701,36702,36703,36704,36705,36706,36707,36708,\n36709,36714,36736,36748,36754,36765,36768,36769,36770,36772,36773,36774,36775,\n36778,36780,36781,36782,36783,36786,36787,36788,36789,36791,36792,36794,36795,\n36796,36799,36800,36803,36806,36809,36810,36811,36812,36813,36815,36818,36822,\n36823,36826,36832,36833,36835,36839,36844,36847,36849,36850,36852,36853,36854,\n36858,36859,36860,36862,36863,36871,36872,36876,36878,36883,36885,36888,34134,\n34107,34047,34044,34137,34120,34152,34148,34142,34170,30626,34115,34162,34171,\n34212,34216,34183,34191,34169,34222,34204,34181,34233,34231,34224,34259,34241,\n34268,34303,34343,34309,34345,34326,34364,24318,24328,22844,22849,32823,22869,\n22874,22872,21263,23586,23589,23596,23604,25164,25194,25247,25275,25290,25306,\n25303,25326,25378,25334,25401,25419,25411,25517,25590,25457,25466,25486,25524,\n25453,25516,25482,25449,25518,25532,25586,25592,25568,25599,25540,25566,25550,\n25682,25542,25534,25669,25665,25611,25627,25632,25612,25638,25633,25694,25732,\n25709,25750,36889,36892,36899,36900,36901,36903,36904,36905,36906,36907,36908,\n36912,36913,36914,36915,36916,36919,36921,36922,36925,36927,36928,36931,36933,\n36934,36936,36937,36938,36939,36940,36942,36948,36949,36950,36953,36954,36956,\n36957,36958,36959,36960,36961,36964,36966,36967,36969,36970,36971,36972,36975,\n36976,36977,36978,36979,36982,36983,36984,36985,36986,\n36987,36988,36990,36993,36996,36997,36998,36999,37001,37002,37004,37005,37006,\n37007,37008,37010,37012,37014,37016,37018,37020,37022,37023,37024,37028,37029,\n37031,37032,37033,37035,37037,37042,37047,37052,37053,37055,37056,25722,25783,\n25784,25753,25786,25792,25808,25815,25828,25826,25865,25893,25902,24331,24530,\n29977,24337,21343,21489,21501,21481,21480,21499,21522,21526,21510,21579,21586,\n21587,21588,21590,21571,21537,21591,21593,21539,21554,21634,21652,21623,21617,\n21604,21658,21659,21636,21622,21606,21661,21712,21677,21698,21684,21714,21671,\n21670,21715,21716,21618,21667,21717,21691,21695,21708,21721,21722,21724,21673,\n21674,21668,21725,21711,21726,21787,21735,21792,21757,21780,21747,21794,21795,\n21775,21777,21799,21802,21863,21903,21941,21833,21869,21825,21845,21823,21840,\n21820,37058,37059,37062,37064,37065,37067,37068,37069,37074,37076,37077,37078,\n37080,37081,37082,37086,37087,37088,37091,37092,37093,37097,37098,37100,37102,\n37104,37105,37106,37107,37109,37110,37111,37113,37114,37115,37116,37119,37120,\n37121,37123,37125,37126,37127,37128,37129,37130,37131,37132,37133,37134,37135,\n37136,37137,37138,37139,37140,37141,37142,37143,37144,37146,37147,37148,37149,\n37151,37152,37153,37156,37157,37158,37159,37160,37161,37162,37163,37164,37165,\n37166,37168,37170,37171,37172,37173,37174,37175,37176,37178,37179,37180,37181,\n37182,37183,37184,37185,37186,37188,21815,21846,21877,21878,21879,21811,21808,\n21852,21899,21970,21891,21937,21945,21896,21889,21919,21886,21974,21905,21883,\n21983,21949,21950,21908,21913,21994,22007,21961,22047,\n21969,21995,21996,21972,21990,21981,21956,21999,21989,22002,22003,21964,21965,\n21992,22005,21988,36756,22046,22024,22028,22017,22052,22051,22014,22016,22055,\n22061,22104,22073,22103,22060,22093,22114,22105,22108,22092,22100,22150,22116,\n22129,22123,22139,22140,22149,22163,22191,22228,22231,22237,22241,22261,22251,\n22265,22271,22276,22282,22281,22300,24079,24089,24084,24081,24113,24123,24124,\n37189,37191,37192,37201,37203,37204,37205,37206,37208,37209,37211,37212,37215,\n37216,37222,37223,37224,37227,37229,37235,37242,37243,37244,37248,37249,37250,\n37251,37252,37254,37256,37258,37262,37263,37267,37268,37269,37270,37271,37272,\n37273,37276,37277,37278,37279,37280,37281,37284,37285,37286,37287,37288,37289,\n37291,37292,37296,37297,37298,37299,37302,37303,37304,37305,37307,37308,37309,\n37310,37311,37312,37313,37314,37315,37316,37317,37318,37320,37323,37328,37330,\n37331,37332,37333,37334,37335,37336,37337,37338,37339,37341,37342,37343,37344,\n37345,37346,37347,37348,37349,24119,24132,24148,24155,24158,24161,23692,23674,\n23693,23696,23702,23688,23704,23705,23697,23706,23708,23733,23714,23741,23724,\n23723,23729,23715,23745,23735,23748,23762,23780,23755,23781,23810,23811,23847,\n23846,23854,23844,23838,23814,23835,23896,23870,23860,23869,23916,23899,23919,\n23901,23915,23883,23882,23913,23924,23938,23961,23965,35955,23991,24005,24435,\n24439,24450,24455,24457,24460,24469,24473,24476,24488,24493,24501,24508,34914,\n24417,29357,29360,29364,29367,29368,29379,29377,29390,29389,29394,29416,29423,\n29417,29426,29428,29431,29441,29427,29443,29434,37350,\n37351,37352,37353,37354,37355,37356,37357,37358,37359,37360,37361,37362,37363,\n37364,37365,37366,37367,37368,37369,37370,37371,37372,37373,37374,37375,37376,\n37377,37378,37379,37380,37381,37382,37383,37384,37385,37386,37387,37388,37389,\n37390,37391,37392,37393,37394,37395,37396,37397,37398,37399,37400,37401,37402,\n37403,37404,37405,37406,37407,37408,37409,37410,37411,37412,37413,37414,37415,\n37416,37417,37418,37419,37420,37421,37422,37423,37424,37425,37426,37427,37428,\n37429,37430,37431,37432,37433,37434,37435,37436,37437,37438,37439,37440,37441,\n37442,37443,37444,37445,29435,29463,29459,29473,29450,29470,29469,29461,29474,\n29497,29477,29484,29496,29489,29520,29517,29527,29536,29548,29551,29566,33307,\n22821,39143,22820,22786,39267,39271,39272,39273,39274,39275,39276,39284,39287,\n39293,39296,39300,39303,39306,39309,39312,39313,39315,39316,39317,24192,24209,\n24203,24214,24229,24224,24249,24245,24254,24243,36179,24274,24273,24283,24296,\n24298,33210,24516,24521,24534,24527,24579,24558,24580,24545,24548,24574,24581,\n24582,24554,24557,24568,24601,24629,24614,24603,24591,24589,24617,24619,24586,\n24639,24609,24696,24697,24699,24698,24642,37446,37447,37448,37449,37450,37451,\n37452,37453,37454,37455,37456,37457,37458,37459,37460,37461,37462,37463,37464,\n37465,37466,37467,37468,37469,37470,37471,37472,37473,37474,37475,37476,37477,\n37478,37479,37480,37481,37482,37483,37484,37485,37486,37487,37488,37489,37490,\n37491,37493,37494,37495,37496,37497,37498,37499,37500,37501,37502,37503,37504,\n37505,37506,37507,37508,37509,37510,37511,37512,37513,\n37514,37515,37516,37517,37519,37520,37521,37522,37523,37524,37525,37526,37527,\n37528,37529,37530,37531,37532,37533,37534,37535,37536,37537,37538,37539,37540,\n37541,37542,37543,24682,24701,24726,24730,24749,24733,24707,24722,24716,24731,\n24812,24763,24753,24797,24792,24774,24794,24756,24864,24870,24853,24867,24820,\n24832,24846,24875,24906,24949,25004,24980,24999,25015,25044,25077,24541,38579,\n38377,38379,38385,38387,38389,38390,38396,38398,38403,38404,38406,38408,38410,\n38411,38412,38413,38415,38418,38421,38422,38423,38425,38426,20012,29247,25109,\n27701,27732,27740,27722,27811,27781,27792,27796,27788,27752,27753,27764,27766,\n27782,27817,27856,27860,27821,27895,27896,27889,27863,27826,27872,27862,27898,\n27883,27886,27825,27859,27887,27902,37544,37545,37546,37547,37548,37549,37551,\n37552,37553,37554,37555,37556,37557,37558,37559,37560,37561,37562,37563,37564,\n37565,37566,37567,37568,37569,37570,37571,37572,37573,37574,37575,37577,37578,\n37579,37580,37581,37582,37583,37584,37585,37586,37587,37588,37589,37590,37591,\n37592,37593,37594,37595,37596,37597,37598,37599,37600,37601,37602,37603,37604,\n37605,37606,37607,37608,37609,37610,37611,37612,37613,37614,37615,37616,37617,\n37618,37619,37620,37621,37622,37623,37624,37625,37626,37627,37628,37629,37630,\n37631,37632,37633,37634,37635,37636,37637,37638,37639,37640,37641,27961,27943,\n27916,27971,27976,27911,27908,27929,27918,27947,27981,27950,27957,27930,27983,\n27986,27988,27955,28049,28015,28062,28064,27998,28051,28052,27996,28000,28028,\n28003,28186,28103,28101,28126,28174,28095,28128,28177,\n28134,28125,28121,28182,28075,28172,28078,28203,28270,28238,28267,28338,28255,\n28294,28243,28244,28210,28197,28228,28383,28337,28312,28384,28461,28386,28325,\n28327,28349,28347,28343,28375,28340,28367,28303,28354,28319,28514,28486,28487,\n28452,28437,28409,28463,28470,28491,28532,28458,28425,28457,28553,28557,28556,\n28536,28530,28540,28538,28625,37642,37643,37644,37645,37646,37647,37648,37649,\n37650,37651,37652,37653,37654,37655,37656,37657,37658,37659,37660,37661,37662,\n37663,37664,37665,37666,37667,37668,37669,37670,37671,37672,37673,37674,37675,\n37676,37677,37678,37679,37680,37681,37682,37683,37684,37685,37686,37687,37688,\n37689,37690,37691,37692,37693,37695,37696,37697,37698,37699,37700,37701,37702,\n37703,37704,37705,37706,37707,37708,37709,37710,37711,37712,37713,37714,37715,\n37716,37717,37718,37719,37720,37721,37722,37723,37724,37725,37726,37727,37728,\n37729,37730,37731,37732,37733,37734,37735,37736,37737,37739,28617,28583,28601,\n28598,28610,28641,28654,28638,28640,28655,28698,28707,28699,28729,28725,28751,\n28766,23424,23428,23445,23443,23461,23480,29999,39582,25652,23524,23534,35120,\n23536,36423,35591,36790,36819,36821,36837,36846,36836,36841,36838,36851,36840,\n36869,36868,36875,36902,36881,36877,36886,36897,36917,36918,36909,36911,36932,\n36945,36946,36944,36968,36952,36962,36955,26297,36980,36989,36994,37000,36995,\n37003,24400,24407,24406,24408,23611,21675,23632,23641,23409,23651,23654,32700,\n24362,24361,24365,33396,24380,39739,23662,22913,22915,22925,22953,22954,22947,\n37740,37741,37742,37743,37744,37745,37746,37747,37748,\n37749,37750,37751,37752,37753,37754,37755,37756,37757,37758,37759,37760,37761,\n37762,37763,37764,37765,37766,37767,37768,37769,37770,37771,37772,37773,37774,\n37776,37777,37778,37779,37780,37781,37782,37783,37784,37785,37786,37787,37788,\n37789,37790,37791,37792,37793,37794,37795,37796,37797,37798,37799,37800,37801,\n37802,37803,37804,37805,37806,37807,37808,37809,37810,37811,37812,37813,37814,\n37815,37816,37817,37818,37819,37820,37821,37822,37823,37824,37825,37826,37827,\n37828,37829,37830,37831,37832,37833,37835,37836,37837,22935,22986,22955,22942,\n22948,22994,22962,22959,22999,22974,23045,23046,23005,23048,23011,23000,23033,\n23052,23049,23090,23092,23057,23075,23059,23104,23143,23114,23125,23100,23138,\n23157,33004,23210,23195,23159,23162,23230,23275,23218,23250,23252,23224,23264,\n23267,23281,23254,23270,23256,23260,23305,23319,23318,23346,23351,23360,23573,\n23580,23386,23397,23411,23377,23379,23394,39541,39543,39544,39546,39551,39549,\n39552,39553,39557,39560,39562,39568,39570,39571,39574,39576,39579,39580,39581,\n39583,39584,39586,39587,39589,39591,32415,32417,32419,32421,32424,32425,37838,\n37839,37840,37841,37842,37843,37844,37845,37847,37848,37849,37850,37851,37852,\n37853,37854,37855,37856,37857,37858,37859,37860,37861,37862,37863,37864,37865,\n37866,37867,37868,37869,37870,37871,37872,37873,37874,37875,37876,37877,37878,\n37879,37880,37881,37882,37883,37884,37885,37886,37887,37888,37889,37890,37891,\n37892,37893,37894,37895,37896,37897,37898,37899,37900,37901,37902,37903,37904,\n37905,37906,37907,37908,37909,37910,37911,37912,37913,\n37914,37915,37916,37917,37918,37919,37920,37921,37922,37923,37924,37925,37926,\n37927,37928,37929,37930,37931,37932,37933,37934,32429,32432,32446,32448,32449,\n32450,32457,32459,32460,32464,32468,32471,32475,32480,32481,32488,32491,32494,\n32495,32497,32498,32525,32502,32506,32507,32510,32513,32514,32515,32519,32520,\n32523,32524,32527,32529,32530,32535,32537,32540,32539,32543,32545,32546,32547,\n32548,32549,32550,32551,32554,32555,32556,32557,32559,32560,32561,32562,32563,\n32565,24186,30079,24027,30014,37013,29582,29585,29614,29602,29599,29647,29634,\n29649,29623,29619,29632,29641,29640,29669,29657,39036,29706,29673,29671,29662,\n29626,29682,29711,29738,29787,29734,29733,29736,29744,29742,29740,37935,37936,\n37937,37938,37939,37940,37941,37942,37943,37944,37945,37946,37947,37948,37949,\n37951,37952,37953,37954,37955,37956,37957,37958,37959,37960,37961,37962,37963,\n37964,37965,37966,37967,37968,37969,37970,37971,37972,37973,37974,37975,37976,\n37977,37978,37979,37980,37981,37982,37983,37984,37985,37986,37987,37988,37989,\n37990,37991,37992,37993,37994,37996,37997,37998,37999,38000,38001,38002,38003,\n38004,38005,38006,38007,38008,38009,38010,38011,38012,38013,38014,38015,38016,\n38017,38018,38019,38020,38033,38038,38040,38087,38095,38099,38100,38106,38118,\n38139,38172,38176,29723,29722,29761,29788,29783,29781,29785,29815,29805,29822,\n29852,29838,29824,29825,29831,29835,29854,29864,29865,29840,29863,29906,29882,\n38890,38891,38892,26444,26451,26462,26440,26473,26533,26503,26474,26483,26520,\n26535,26485,26536,26526,26541,26507,26487,26492,26608,\n26633,26584,26634,26601,26544,26636,26585,26549,26586,26547,26589,26624,26563,\n26552,26594,26638,26561,26621,26674,26675,26720,26721,26702,26722,26692,26724,\n26755,26653,26709,26726,26689,26727,26688,26686,26698,26697,26665,26805,26767,\n26740,26743,26771,26731,26818,26990,26876,26911,26912,26873,38183,38195,38205,\n38211,38216,38219,38229,38234,38240,38254,38260,38261,38263,38264,38265,38266,\n38267,38268,38269,38270,38272,38273,38274,38275,38276,38277,38278,38279,38280,\n38281,38282,38283,38284,38285,38286,38287,38288,38289,38290,38291,38292,38293,\n38294,38295,38296,38297,38298,38299,38300,38301,38302,38303,38304,38305,38306,\n38307,38308,38309,38310,38311,38312,38313,38314,38315,38316,38317,38318,38319,\n38320,38321,38322,38323,38324,38325,38326,38327,38328,38329,38330,38331,38332,\n38333,38334,38335,38336,38337,38338,38339,38340,38341,38342,38343,38344,38345,\n38346,38347,26916,26864,26891,26881,26967,26851,26896,26993,26937,26976,26946,\n26973,27012,26987,27008,27032,27000,26932,27084,27015,27016,27086,27017,26982,\n26979,27001,27035,27047,27067,27051,27053,27092,27057,27073,27082,27103,27029,\n27104,27021,27135,27183,27117,27159,27160,27237,27122,27204,27198,27296,27216,\n27227,27189,27278,27257,27197,27176,27224,27260,27281,27280,27305,27287,27307,\n29495,29522,27521,27522,27527,27524,27538,27539,27533,27546,27547,27553,27562,\n36715,36717,36721,36722,36723,36725,36726,36728,36727,36729,36730,36732,36734,\n36737,36738,36740,36743,36747,38348,38349,38350,38351,38352,38353,38354,38355,\n38356,38357,38358,38359,38360,38361,38362,38363,38364,\n38365,38366,38367,38368,38369,38370,38371,38372,38373,38374,38375,38380,38399,\n38407,38419,38424,38427,38430,38432,38435,38436,38437,38438,38439,38440,38441,\n38443,38444,38445,38447,38448,38455,38456,38457,38458,38462,38465,38467,38474,\n38478,38479,38481,38482,38483,38486,38487,38488,38489,38490,38492,38493,38494,\n38496,38499,38501,38502,38507,38509,38510,38511,38512,38513,38515,38520,38521,\n38522,38523,38524,38525,38526,38527,38528,38529,38530,38531,38532,38535,38537,\n38538,36749,36750,36751,36760,36762,36558,25099,25111,25115,25119,25122,25121,\n25125,25124,25132,33255,29935,29940,29951,29967,29969,29971,25908,26094,26095,\n26096,26122,26137,26482,26115,26133,26112,28805,26359,26141,26164,26161,26166,\n26165,32774,26207,26196,26177,26191,26198,26209,26199,26231,26244,26252,26279,\n26269,26302,26331,26332,26342,26345,36146,36147,36150,36155,36157,36160,36165,\n36166,36168,36169,36167,36173,36181,36185,35271,35274,35275,35276,35278,35279,\n35280,35281,29294,29343,29277,29286,29295,29310,29311,29316,29323,29325,29327,\n29330,25352,25394,25520,38540,38542,38545,38546,38547,38549,38550,38554,38555,\n38557,38558,38559,38560,38561,38562,38563,38564,38565,38566,38568,38569,38570,\n38571,38572,38573,38574,38575,38577,38578,38580,38581,38583,38584,38586,38587,\n38591,38594,38595,38600,38602,38603,38608,38609,38611,38612,38614,38615,38616,\n38617,38618,38619,38620,38621,38622,38623,38625,38626,38627,38628,38629,38630,\n38631,38635,38636,38637,38638,38640,38641,38642,38644,38645,38648,38650,38651,\n38652,38653,38655,38658,38659,38661,38666,38667,38668,\n38672,38673,38674,38676,38677,38679,38680,38681,38682,38683,38685,38687,38688,\n25663,25816,32772,27626,27635,27645,27637,27641,27653,27655,27654,27661,27669,\n27672,27673,27674,27681,27689,27684,27690,27698,25909,25941,25963,29261,29266,\n29270,29232,34402,21014,32927,32924,32915,32956,26378,32957,32945,32939,32941,\n32948,32951,32999,33000,33001,33002,32987,32962,32964,32985,32973,32983,26384,\n32989,33003,33009,33012,33005,33037,33038,33010,33020,26389,33042,35930,33078,\n33054,33068,33048,33074,33096,33100,33107,33140,33113,33114,33137,33120,33129,\n33148,33149,33133,33127,22605,23221,33160,33154,33169,28373,33187,33194,33228,\n26406,33226,33211,38689,38690,38691,38692,38693,38694,38695,38696,38697,38699,\n38700,38702,38703,38705,38707,38708,38709,38710,38711,38714,38715,38716,38717,\n38719,38720,38721,38722,38723,38724,38725,38726,38727,38728,38729,38730,38731,\n38732,38733,38734,38735,38736,38737,38740,38741,38743,38744,38746,38748,38749,\n38751,38755,38756,38758,38759,38760,38762,38763,38764,38765,38766,38767,38768,\n38769,38770,38773,38775,38776,38777,38778,38779,38781,38782,38783,38784,38785,\n38786,38787,38788,38790,38791,38792,38793,38794,38796,38798,38799,38800,38803,\n38805,38806,38807,38809,38810,38811,38812,38813,33217,33190,27428,27447,27449,\n27459,27462,27481,39121,39122,39123,39125,39129,39130,27571,24384,27586,35315,\n26000,40785,26003,26044,26054,26052,26051,26060,26062,26066,26070,28800,28828,\n28822,28829,28859,28864,28855,28843,28849,28904,28874,28944,28947,28950,28975,\n28977,29043,29020,29032,28997,29042,29002,29048,29050,\n29080,29107,29109,29096,29088,29152,29140,29159,29177,29213,29224,28780,28952,\n29030,29113,25150,25149,25155,25160,25161,31035,31040,31046,31049,31067,31068,\n31059,31066,31074,31063,31072,31087,31079,31098,31109,31114,31130,31143,31155,\n24529,24528,38814,38815,38817,38818,38820,38821,38822,38823,38824,38825,38826,\n38828,38830,38832,38833,38835,38837,38838,38839,38840,38841,38842,38843,38844,\n38845,38846,38847,38848,38849,38850,38851,38852,38853,38854,38855,38856,38857,\n38858,38859,38860,38861,38862,38863,38864,38865,38866,38867,38868,38869,38870,\n38871,38872,38873,38874,38875,38876,38877,38878,38879,38880,38881,38882,38883,\n38884,38885,38888,38894,38895,38896,38897,38898,38900,38903,38904,38905,38906,\n38907,38908,38909,38910,38911,38912,38913,38914,38915,38916,38917,38918,38919,\n38920,38921,38922,38923,38924,38925,38926,24636,24669,24666,24679,24641,24665,\n24675,24747,24838,24845,24925,25001,24989,25035,25041,25094,32896,32895,27795,\n27894,28156,30710,30712,30720,30729,30743,30744,30737,26027,30765,30748,30749,\n30777,30778,30779,30751,30780,30757,30764,30755,30761,30798,30829,30806,30807,\n30758,30800,30791,30796,30826,30875,30867,30874,30855,30876,30881,30883,30898,\n30905,30885,30932,30937,30921,30956,30962,30981,30964,30995,31012,31006,31028,\n40859,40697,40699,40700,30449,30468,30477,30457,30471,30472,30490,30498,30489,\n30509,30502,30517,30520,30544,30545,30535,30531,30554,30568,38927,38928,38929,\n38930,38931,38932,38933,38934,38935,38936,38937,38938,38939,38940,38941,38942,\n38943,38944,38945,38946,38947,38948,38949,38950,38951,\n38952,38953,38954,38955,38956,38957,38958,38959,38960,38961,38962,38963,38964,\n38965,38966,38967,38968,38969,38970,38971,38972,38973,38974,38975,38976,38977,\n38978,38979,38980,38981,38982,38983,38984,38985,38986,38987,38988,38989,38990,\n38991,38992,38993,38994,38995,38996,38997,38998,38999,39000,39001,39002,39003,\n39004,39005,39006,39007,39008,39009,39010,39011,39012,39013,39014,39015,39016,\n39017,39018,39019,39020,39021,39022,30562,30565,30591,30605,30589,30592,30604,\n30609,30623,30624,30640,30645,30653,30010,30016,30030,30027,30024,30043,30066,\n30073,30083,32600,32609,32607,35400,32616,32628,32625,32633,32641,32638,30413,\n30437,34866,38021,38022,38023,38027,38026,38028,38029,38031,38032,38036,38039,\n38037,38042,38043,38044,38051,38052,38059,38058,38061,38060,38063,38064,38066,\n38068,38070,38071,38072,38073,38074,38076,38077,38079,38084,38088,38089,38090,\n38091,38092,38093,38094,38096,38097,38098,38101,38102,38103,38105,38104,38107,\n38110,38111,38112,38114,38116,38117,38119,38120,38122,39023,39024,39025,39026,\n39027,39028,39051,39054,39058,39061,39065,39075,39080,39081,39082,39083,39084,\n39085,39086,39087,39088,39089,39090,39091,39092,39093,39094,39095,39096,39097,\n39098,39099,39100,39101,39102,39103,39104,39105,39106,39107,39108,39109,39110,\n39111,39112,39113,39114,39115,39116,39117,39119,39120,39124,39126,39127,39131,\n39132,39133,39136,39137,39138,39139,39140,39141,39142,39145,39146,39147,39148,\n39149,39150,39151,39152,39153,39154,39155,39156,39157,39158,39159,39160,39161,\n39162,39163,39164,39165,39166,39167,39168,39169,39170,\n39171,39172,39173,39174,39175,38121,38123,38126,38127,38131,38132,38133,38135,\n38137,38140,38141,38143,38147,38146,38150,38151,38153,38154,38157,38158,38159,\n38162,38163,38164,38165,38166,38168,38171,38173,38174,38175,38178,38186,38187,\n38185,38188,38193,38194,38196,38198,38199,38200,38204,38206,38207,38210,38197,\n38212,38213,38214,38217,38220,38222,38223,38226,38227,38228,38230,38231,38232,\n38233,38235,38238,38239,38237,38241,38242,38244,38245,38246,38247,38248,38249,\n38250,38251,38252,38255,38257,38258,38259,38202,30695,30700,38601,31189,31213,\n31203,31211,31238,23879,31235,31234,31262,31252,39176,39177,39178,39179,39180,\n39182,39183,39185,39186,39187,39188,39189,39190,39191,39192,39193,39194,39195,\n39196,39197,39198,39199,39200,39201,39202,39203,39204,39205,39206,39207,39208,\n39209,39210,39211,39212,39213,39215,39216,39217,39218,39219,39220,39221,39222,\n39223,39224,39225,39226,39227,39228,39229,39230,39231,39232,39233,39234,39235,\n39236,39237,39238,39239,39240,39241,39242,39243,39244,39245,39246,39247,39248,\n39249,39250,39251,39254,39255,39256,39257,39258,39259,39260,39261,39262,39263,\n39264,39265,39266,39268,39270,39283,39288,39289,39291,39294,39298,39299,39305,\n31289,31287,31313,40655,39333,31344,30344,30350,30355,30361,30372,29918,29920,\n29996,40480,40482,40488,40489,40490,40491,40492,40498,40497,40502,40504,40503,\n40505,40506,40510,40513,40514,40516,40518,40519,40520,40521,40523,40524,40526,\n40529,40533,40535,40538,40539,40540,40542,40547,40550,40551,40552,40553,40554,\n40555,40556,40561,40557,40563,30098,30100,30102,30112,\n30109,30124,30115,30131,30132,30136,30148,30129,30128,30147,30146,30166,30157,\n30179,30184,30182,30180,30187,30183,30211,30193,30204,30207,30224,30208,30213,\n30220,30231,30218,30245,30232,30229,30233,39308,39310,39322,39323,39324,39325,\n39326,39327,39328,39329,39330,39331,39332,39334,39335,39337,39338,39339,39340,\n39341,39342,39343,39344,39345,39346,39347,39348,39349,39350,39351,39352,39353,\n39354,39355,39356,39357,39358,39359,39360,39361,39362,39363,39364,39365,39366,\n39367,39368,39369,39370,39371,39372,39373,39374,39375,39376,39377,39378,39379,\n39380,39381,39382,39383,39384,39385,39386,39387,39388,39389,39390,39391,39392,\n39393,39394,39395,39396,39397,39398,39399,39400,39401,39402,39403,39404,39405,\n39406,39407,39408,39409,39410,39411,39412,39413,39414,39415,39416,39417,30235,\n30268,30242,30240,30272,30253,30256,30271,30261,30275,30270,30259,30285,30302,\n30292,30300,30294,30315,30319,32714,31462,31352,31353,31360,31366,31368,31381,\n31398,31392,31404,31400,31405,31411,34916,34921,34930,34941,34943,34946,34978,\n35014,34999,35004,35017,35042,35022,35043,35045,35057,35098,35068,35048,35070,\n35056,35105,35097,35091,35099,35082,35124,35115,35126,35137,35174,35195,30091,\n32997,30386,30388,30684,32786,32788,32790,32796,32800,32802,32805,32806,32807,\n32809,32808,32817,32779,32821,32835,32838,32845,32850,32873,32881,35203,39032,\n39040,39043,39418,39419,39420,39421,39422,39423,39424,39425,39426,39427,39428,\n39429,39430,39431,39432,39433,39434,39435,39436,39437,39438,39439,39440,39441,\n39442,39443,39444,39445,39446,39447,39448,39449,39450,\n39451,39452,39453,39454,39455,39456,39457,39458,39459,39460,39461,39462,39463,\n39464,39465,39466,39467,39468,39469,39470,39471,39472,39473,39474,39475,39476,\n39477,39478,39479,39480,39481,39482,39483,39484,39485,39486,39487,39488,39489,\n39490,39491,39492,39493,39494,39495,39496,39497,39498,39499,39500,39501,39502,\n39503,39504,39505,39506,39507,39508,39509,39510,39511,39512,39513,39049,39052,\n39053,39055,39060,39066,39067,39070,39071,39073,39074,39077,39078,34381,34388,\n34412,34414,34431,34426,34428,34427,34472,34445,34443,34476,34461,34471,34467,\n34474,34451,34473,34486,34500,34485,34510,34480,34490,34481,34479,34505,34511,\n34484,34537,34545,34546,34541,34547,34512,34579,34526,34548,34527,34520,34513,\n34563,34567,34552,34568,34570,34573,34569,34595,34619,34590,34597,34606,34586,\n34622,34632,34612,34609,34601,34615,34623,34690,34594,34685,34686,34683,34656,\n34672,34636,34670,34699,34643,34659,34684,34660,34649,34661,34707,34735,34728,\n34770,39514,39515,39516,39517,39518,39519,39520,39521,39522,39523,39524,39525,\n39526,39527,39528,39529,39530,39531,39538,39555,39561,39565,39566,39572,39573,\n39577,39590,39593,39594,39595,39596,39597,39598,39599,39602,39603,39604,39605,\n39609,39611,39613,39614,39615,39619,39620,39622,39623,39624,39625,39626,39629,\n39630,39631,39632,39634,39636,39637,39638,39639,39641,39642,39643,39644,39645,\n39646,39648,39650,39651,39652,39653,39655,39656,39657,39658,39660,39662,39664,\n39665,39666,39667,39668,39669,39670,39671,39672,39674,39676,39677,39678,39679,\n39680,39681,39682,39684,39685,39686,34758,34696,34693,\n34733,34711,34691,34731,34789,34732,34741,34739,34763,34771,34749,34769,34752,\n34762,34779,34794,34784,34798,34838,34835,34814,34826,34843,34849,34873,34876,\n32566,32578,32580,32581,33296,31482,31485,31496,31491,31492,31509,31498,31531,\n31503,31559,31544,31530,31513,31534,31537,31520,31525,31524,31539,31550,31518,\n31576,31578,31557,31605,31564,31581,31584,31598,31611,31586,31602,31601,31632,\n31654,31655,31672,31660,31645,31656,31621,31658,31644,31650,31659,31668,31697,\n31681,31692,31709,31706,31717,31718,31722,31756,31742,31740,31759,31766,31755,\n39687,39689,39690,39691,39692,39693,39694,39696,39697,39698,39700,39701,39702,\n39703,39704,39705,39706,39707,39708,39709,39710,39712,39713,39714,39716,39717,\n39718,39719,39720,39721,39722,39723,39724,39725,39726,39728,39729,39731,39732,\n39733,39734,39735,39736,39737,39738,39741,39742,39743,39744,39750,39754,39755,\n39756,39758,39760,39762,39763,39765,39766,39767,39768,39769,39770,39771,39772,\n39773,39774,39775,39776,39777,39778,39779,39780,39781,39782,39783,39784,39785,\n39786,39787,39788,39789,39790,39791,39792,39793,39794,39795,39796,39797,39798,\n39799,39800,39801,39802,39803,31775,31786,31782,31800,31809,31808,33278,33281,\n33282,33284,33260,34884,33313,33314,33315,33325,33327,33320,33323,33336,33339,\n33331,33332,33342,33348,33353,33355,33359,33370,33375,33384,34942,34949,34952,\n35032,35039,35166,32669,32671,32679,32687,32688,32690,31868,25929,31889,31901,\n31900,31902,31906,31922,31932,31933,31937,31943,31948,31949,31944,31941,31959,\n31976,33390,26280,32703,32718,32725,32741,32737,32742,\n32745,32750,32755,31992,32119,32166,32174,32327,32411,40632,40628,36211,36228,\n36244,36241,36273,36199,36205,35911,35913,37194,37200,37198,37199,37220,39804,\n39805,39806,39807,39808,39809,39810,39811,39812,39813,39814,39815,39816,39817,\n39818,39819,39820,39821,39822,39823,39824,39825,39826,39827,39828,39829,39830,\n39831,39832,39833,39834,39835,39836,39837,39838,39839,39840,39841,39842,39843,\n39844,39845,39846,39847,39848,39849,39850,39851,39852,39853,39854,39855,39856,\n39857,39858,39859,39860,39861,39862,39863,39864,39865,39866,39867,39868,39869,\n39870,39871,39872,39873,39874,39875,39876,39877,39878,39879,39880,39881,39882,\n39883,39884,39885,39886,39887,39888,39889,39890,39891,39892,39893,39894,39895,\n39896,39897,39898,39899,37218,37217,37232,37225,37231,37245,37246,37234,37236,\n37241,37260,37253,37264,37261,37265,37282,37283,37290,37293,37294,37295,37301,\n37300,37306,35925,40574,36280,36331,36357,36441,36457,36277,36287,36284,36282,\n36292,36310,36311,36314,36318,36302,36303,36315,36294,36332,36343,36344,36323,\n36345,36347,36324,36361,36349,36372,36381,36383,36396,36398,36387,36399,36410,\n36416,36409,36405,36413,36401,36425,36417,36418,36433,36434,36426,36464,36470,\n36476,36463,36468,36485,36495,36500,36496,36508,36510,35960,35970,35978,35973,\n35992,35988,26011,35286,35294,35290,35292,39900,39901,39902,39903,39904,39905,\n39906,39907,39908,39909,39910,39911,39912,39913,39914,39915,39916,39917,39918,\n39919,39920,39921,39922,39923,39924,39925,39926,39927,39928,39929,39930,39931,\n39932,39933,39934,39935,39936,39937,39938,39939,39940,\n39941,39942,39943,39944,39945,39946,39947,39948,39949,39950,39951,39952,39953,\n39954,39955,39956,39957,39958,39959,39960,39961,39962,39963,39964,39965,39966,\n39967,39968,39969,39970,39971,39972,39973,39974,39975,39976,39977,39978,39979,\n39980,39981,39982,39983,39984,39985,39986,39987,39988,39989,39990,39991,39992,\n39993,39994,39995,35301,35307,35311,35390,35622,38739,38633,38643,38639,38662,\n38657,38664,38671,38670,38698,38701,38704,38718,40832,40835,40837,40838,40839,\n40840,40841,40842,40844,40702,40715,40717,38585,38588,38589,38606,38610,30655,\n38624,37518,37550,37576,37694,37738,37834,37775,37950,37995,40063,40066,40069,\n40070,40071,40072,31267,40075,40078,40080,40081,40082,40084,40085,40090,40091,\n40094,40095,40096,40097,40098,40099,40101,40102,40103,40104,40105,40107,40109,\n40110,40112,40113,40114,40115,40116,40117,40118,40119,40122,40123,40124,40125,\n40132,40133,40134,40135,40138,40139,39996,39997,39998,39999,40000,40001,40002,\n40003,40004,40005,40006,40007,40008,40009,40010,40011,40012,40013,40014,40015,\n40016,40017,40018,40019,40020,40021,40022,40023,40024,40025,40026,40027,40028,\n40029,40030,40031,40032,40033,40034,40035,40036,40037,40038,40039,40040,40041,\n40042,40043,40044,40045,40046,40047,40048,40049,40050,40051,40052,40053,40054,\n40055,40056,40057,40058,40059,40061,40062,40064,40067,40068,40073,40074,40076,\n40079,40083,40086,40087,40088,40089,40093,40106,40108,40111,40121,40126,40127,\n40128,40129,40130,40136,40137,40145,40146,40154,40155,40160,40161,40140,40141,\n40142,40143,40144,40147,40148,40149,40151,40152,40153,\n40156,40157,40159,40162,38780,38789,38801,38802,38804,38831,38827,38819,38834,\n38836,39601,39600,39607,40536,39606,39610,39612,39617,39616,39621,39618,39627,\n39628,39633,39749,39747,39751,39753,39752,39757,39761,39144,39181,39214,39253,\n39252,39647,39649,39654,39663,39659,39675,39661,39673,39688,39695,39699,39711,\n39715,40637,40638,32315,40578,40583,40584,40587,40594,37846,40605,40607,40667,\n40668,40669,40672,40671,40674,40681,40679,40677,40682,40687,40738,40748,40751,\n40761,40759,40765,40766,40772,40163,40164,40165,40166,40167,40168,40169,40170,\n40171,40172,40173,40174,40175,40176,40177,40178,40179,40180,40181,40182,40183,\n40184,40185,40186,40187,40188,40189,40190,40191,40192,40193,40194,40195,40196,\n40197,40198,40199,40200,40201,40202,40203,40204,40205,40206,40207,40208,40209,\n40210,40211,40212,40213,40214,40215,40216,40217,40218,40219,40220,40221,40222,\n40223,40224,40225,40226,40227,40228,40229,40230,40231,40232,40233,40234,40235,\n40236,40237,40238,40239,40240,40241,40242,40243,40244,40245,40246,40247,40248,\n40249,40250,40251,40252,40253,40254,40255,40256,40257,40258,57908,57909,57910,\n57911,57912,57913,57914,57915,57916,57917,57918,57919,57920,57921,57922,57923,\n57924,57925,57926,57927,57928,57929,57930,57931,57932,57933,57934,57935,57936,\n57937,57938,57939,57940,57941,57942,57943,57944,57945,57946,57947,57948,57949,\n57950,57951,57952,57953,57954,57955,57956,57957,57958,57959,57960,57961,57962,\n57963,57964,57965,57966,57967,57968,57969,57970,57971,57972,57973,57974,57975,\n57976,57977,57978,57979,57980,57981,57982,57983,57984,\n57985,57986,57987,57988,57989,57990,57991,57992,57993,57994,57995,57996,57997,\n57998,57999,58000,58001,40259,40260,40261,40262,40263,40264,40265,40266,40267,\n40268,40269,40270,40271,40272,40273,40274,40275,40276,40277,40278,40279,40280,\n40281,40282,40283,40284,40285,40286,40287,40288,40289,40290,40291,40292,40293,\n40294,40295,40296,40297,40298,40299,40300,40301,40302,40303,40304,40305,40306,\n40307,40308,40309,40310,40311,40312,40313,40314,40315,40316,40317,40318,40319,\n40320,40321,40322,40323,40324,40325,40326,40327,40328,40329,40330,40331,40332,\n40333,40334,40335,40336,40337,40338,40339,40340,40341,40342,40343,40344,40345,\n40346,40347,40348,40349,40350,40351,40352,40353,40354,58002,58003,58004,58005,\n58006,58007,58008,58009,58010,58011,58012,58013,58014,58015,58016,58017,58018,\n58019,58020,58021,58022,58023,58024,58025,58026,58027,58028,58029,58030,58031,\n58032,58033,58034,58035,58036,58037,58038,58039,58040,58041,58042,58043,58044,\n58045,58046,58047,58048,58049,58050,58051,58052,58053,58054,58055,58056,58057,\n58058,58059,58060,58061,58062,58063,58064,58065,58066,58067,58068,58069,58070,\n58071,58072,58073,58074,58075,58076,58077,58078,58079,58080,58081,58082,58083,\n58084,58085,58086,58087,58088,58089,58090,58091,58092,58093,58094,58095,40355,\n40356,40357,40358,40359,40360,40361,40362,40363,40364,40365,40366,40367,40368,\n40369,40370,40371,40372,40373,40374,40375,40376,40377,40378,40379,40380,40381,\n40382,40383,40384,40385,40386,40387,40388,40389,40390,40391,40392,40393,40394,\n40395,40396,40397,40398,40399,40400,40401,40402,40403,\n40404,40405,40406,40407,40408,40409,40410,40411,40412,40413,40414,40415,40416,\n40417,40418,40419,40420,40421,40422,40423,40424,40425,40426,40427,40428,40429,\n40430,40431,40432,40433,40434,40435,40436,40437,40438,40439,40440,40441,40442,\n40443,40444,40445,40446,40447,40448,40449,40450,58096,58097,58098,58099,58100,\n58101,58102,58103,58104,58105,58106,58107,58108,58109,58110,58111,58112,58113,\n58114,58115,58116,58117,58118,58119,58120,58121,58122,58123,58124,58125,58126,\n58127,58128,58129,58130,58131,58132,58133,58134,58135,58136,58137,58138,58139,\n58140,58141,58142,58143,58144,58145,58146,58147,58148,58149,58150,58151,58152,\n58153,58154,58155,58156,58157,58158,58159,58160,58161,58162,58163,58164,58165,\n58166,58167,58168,58169,58170,58171,58172,58173,58174,58175,58176,58177,58178,\n58179,58180,58181,58182,58183,58184,58185,58186,58187,58188,58189,40451,40452,\n40453,40454,40455,40456,40457,40458,40459,40460,40461,40462,40463,40464,40465,\n40466,40467,40468,40469,40470,40471,40472,40473,40474,40475,40476,40477,40478,\n40484,40487,40494,40496,40500,40507,40508,40512,40525,40528,40530,40531,40532,\n40534,40537,40541,40543,40544,40545,40546,40549,40558,40559,40562,40564,40565,\n40566,40567,40568,40569,40570,40571,40572,40573,40576,40577,40579,40580,40581,\n40582,40585,40586,40588,40589,40590,40591,40592,40593,40596,40597,40598,40599,\n40600,40601,40602,40603,40604,40606,40608,40609,40610,40611,40612,40613,40615,\n40616,40617,40618,58190,58191,58192,58193,58194,58195,58196,58197,58198,58199,\n58200,58201,58202,58203,58204,58205,58206,58207,58208,\n58209,58210,58211,58212,58213,58214,58215,58216,58217,58218,58219,58220,58221,\n58222,58223,58224,58225,58226,58227,58228,58229,58230,58231,58232,58233,58234,\n58235,58236,58237,58238,58239,58240,58241,58242,58243,58244,58245,58246,58247,\n58248,58249,58250,58251,58252,58253,58254,58255,58256,58257,58258,58259,58260,\n58261,58262,58263,58264,58265,58266,58267,58268,58269,58270,58271,58272,58273,\n58274,58275,58276,58277,58278,58279,58280,58281,58282,58283,40619,40620,40621,\n40622,40623,40624,40625,40626,40627,40629,40630,40631,40633,40634,40636,40639,\n40640,40641,40642,40643,40645,40646,40647,40648,40650,40651,40652,40656,40658,\n40659,40661,40662,40663,40665,40666,40670,40673,40675,40676,40678,40680,40683,\n40684,40685,40686,40688,40689,40690,40691,40692,40693,40694,40695,40696,40698,\n40701,40703,40704,40705,40706,40707,40708,40709,40710,40711,40712,40713,40714,\n40716,40719,40721,40722,40724,40725,40726,40728,40730,40731,40732,40733,40734,\n40735,40737,40739,40740,40741,40742,40743,40744,40745,40746,40747,40749,40750,\n40752,40753,58284,58285,58286,58287,58288,58289,58290,58291,58292,58293,58294,\n58295,58296,58297,58298,58299,58300,58301,58302,58303,58304,58305,58306,58307,\n58308,58309,58310,58311,58312,58313,58314,58315,58316,58317,58318,58319,58320,\n58321,58322,58323,58324,58325,58326,58327,58328,58329,58330,58331,58332,58333,\n58334,58335,58336,58337,58338,58339,58340,58341,58342,58343,58344,58345,58346,\n58347,58348,58349,58350,58351,58352,58353,58354,58355,58356,58357,58358,58359,\n58360,58361,58362,58363,58364,58365,58366,58367,58368,\n58369,58370,58371,58372,58373,58374,58375,58376,58377,40754,40755,40756,40757,\n40758,40760,40762,40764,40767,40768,40769,40770,40771,40773,40774,40775,40776,\n40777,40778,40779,40780,40781,40782,40783,40786,40787,40788,40789,40790,40791,\n40792,40793,40794,40795,40796,40797,40798,40799,40800,40801,40802,40803,40804,\n40805,40806,40807,40808,40809,40810,40811,40812,40813,40814,40815,40816,40817,\n40818,40819,40820,40821,40822,40823,40824,40825,40826,40827,40828,40829,40830,\n40833,40834,40845,40846,40847,40848,40849,40850,40851,40852,40853,40854,40855,\n40856,40860,40861,40862,40865,40866,40867,40868,40869,63788,63865,63893,63975,\n63985,58378,58379,58380,58381,58382,58383,58384,58385,58386,58387,58388,58389,\n58390,58391,58392,58393,58394,58395,58396,58397,58398,58399,58400,58401,58402,\n58403,58404,58405,58406,58407,58408,58409,58410,58411,58412,58413,58414,58415,\n58416,58417,58418,58419,58420,58421,58422,58423,58424,58425,58426,58427,58428,\n58429,58430,58431,58432,58433,58434,58435,58436,58437,58438,58439,58440,58441,\n58442,58443,58444,58445,58446,58447,58448,58449,58450,58451,58452,58453,58454,\n58455,58456,58457,58458,58459,58460,58461,58462,58463,58464,58465,58466,58467,\n58468,58469,58470,58471,64012,64013,64014,64015,64017,64019,64020,64024,64031,\n64032,64033,64035,64036,64039,64040,64041,11905,59414,59415,59416,11908,13427,\n13383,11912,11915,59422,13726,13850,13838,11916,11927,14702,14616,59430,14799,\n14815,14963,14800,59435,59436,15182,15470,15584,11943,59441,59442,11946,16470,\n16735,11950,17207,11955,11958,11959,59451,17329,17324,\n11963,17373,17622,18017,17996,59459,18211,18217,18300,18317,11978,18759,18810,\n18813,18818,18819,18821,18822,18847,18843,18871,18870,59476,59477,19619,19615,\n19616,19617,19575,19618,19731,19732,19733,19734,19735,19736,19737,19886,59492,\n58472,58473,58474,58475,58476,58477,58478,58479,58480,58481,58482,58483,58484,\n58485,58486,58487,58488,58489,58490,58491,58492,58493,58494,58495,58496,58497,\n58498,58499,58500,58501,58502,58503,58504,58505,58506,58507,58508,58509,58510,\n58511,58512,58513,58514,58515,58516,58517,58518,58519,58520,58521,58522,58523,\n58524,58525,58526,58527,58528,58529,58530,58531,58532,58533,58534,58535,58536,\n58537,58538,58539,58540,58541,58542,58543,58544,58545,58546,58547,58548,58549,\n58550,58551,58552,58553,58554,58555,58556,58557,58558,58559,58560,58561,58562,\n58563,58564,58565,\n"
  },
  {
    "path": "user.libc/src/locale/hkscs.h",
    "content": "17392,19506,17923,17830,17784,29287,19831,17843,31921,19682,31941,15253,18230,\n18244,19527,19520,17087,13847,29522,28299,28882,19543,41809,18255,17882,19589,\n31852,19719,19108,18081,27427,29221,23124,6755,15878,16225,26189,22267,0,\n32149,22813,35769,15860,38708,31727,23515,7518,23204,13861,40624,23249,23479,\n23804,26478,34195,39237,29793,29853,14453,7507,13982,24609,16108,22750,15093,\n31484,40855,16737,35085,12778,2698,12894,17162,33924,40854,37935,18736,34323,\n22678,38730,37400,31184,31282,26208,27177,34973,29772,31685,26498,31276,21071,\n36934,13542,29636,23993,29894,40903,22451,18735,21580,16689,13966,22552,31346,\n31589,35727,18094,28296,16769,23961,31662,9404,40904,9409,9417,9420,40905,\n34052,13755,16564,40906,17633,44543,25281,28782,40907,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12736,12737,12738,12739,12740,268,12741,\n209,205,12742,12743,203,8168,12744,202,12745,12746,12747,12748,270,12749,\n12750,256,193,461,192,274,201,282,200,332,211,465,210,56320,7870,56324,7872,\n202,257,225,462,224,593,275,233,283,232,299,237,464,236,333,243,466,242,363,\n250,468,249,470,472,474,476,252,56328,7871,56332,7873,234,609,9178,9179,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41897,4421,0,25866,0,0,20029,28381,\n40270,37343,0,0,30517,25745,20250,20264,20392,20822,20852,20892,20964,21153,\n21160,21307,21326,21457,21464,22242,22768,22788,22791,22834,22836,23398,23454,\n23455,23706,24198,24635,25993,26622,26628,26725,27982,28860,30005,32420,32428,\n32442,32455,32463,32479,32518,32567,33402,33487,33647,35270,35774,35810,36710,\n36711,36718,29713,31996,32205,26950,31433,21031,0,0,0,0,37260,30904,37214,\n32956,0,36107,33014,2535,0,0,32927,40647,19661,40393,40460,19518,40438,28686,\n40458,41267,13761,0,28314,33342,29977,0,18705,39532,39567,40857,31111,33900,\n7626,1488,10982,20004,20097,20096,20103,20159,20203,20279,13388,20413,15944,\n20483,20616,13437,13459,13477,20870,22789,20955,20988,20997,20105,21113,21136,\n21287,13767,21417,13649,21424,13651,21442,21539,13677,13682,13953,21651,21667,\n21684,21689,21712,21743,21784,21795,21800,13720,21823,13733,13759,21975,13765,\n32132,21797,0,3138,3349,20779,21904,11462,14828,833,36422,19896,38117,16467,\n32958,30586,11320,14900,18389,33117,27122,19946,25821,3452,4020,3285,4340,\n25741,36478,3734,3083,3940,11433,33366,17619,0,3398,39501,33001,18420,\n20135,11458,39602,14951,38388,16365,13574,21191,38868,30920,11588,40302,38933,\n0,17369,24741,25780,21731,11596,11210,4215,14843,4207,26330,26390,31136,25834,\n20562,3139,36456,8609,35660,1841,0,18443,425,16378,22643,11661,0,17864,1276,\n24727,3916,3478,21881,16571,17338,0,19124,10854,4253,33194,39157,3484,25465,\n14846,10101,36288,22177,25724,15939,0,42497,3593,10959,11465,0,4296,14786,\n14738,14854,33435,13688,24137,8391,22098,3889,11442,38688,13500,27709,20027,0,\n0,30068,11915,8712,42587,36045,3706,3124,26652,32659,4303,10243,10553,13819,\n20963,3724,3981,3754,16275,3888,3399,4431,3660,0,3755,2985,3400,4288,4413,\n16377,9878,25650,4013,13300,30265,11214,3454,3455,11345,11349,14872,3736,4295,\n3886,42546,27472,36050,36249,36042,38314,21708,33476,21945,0,40643,39974,\n39606,30558,11758,28992,33133,33004,23580,25970,33076,14231,21343,32957,37302,\n3834,3599,3703,3835,13789,19947,13833,3286,22191,10165,4297,3600,3704,4216,\n4424,33287,5205,3705,20048,11684,23124,4125,4126,4341,4342,22428,3601,30356,\n33485,4021,3707,20862,14083,4022,4480,21208,41661,18906,6202,16759,33404,\n22681,21096,13850,22333,31666,23400,18432,19244,40743,18919,39967,39821,23412,\n12605,22011,13810,22153,20008,22786,7105,63608,38737,134,20059,20155,13630,\n23587,24401,24516,14586,25164,25909,27514,27701,27706,28780,29227,20012,29357,\n18665,32594,31035,31993,32595,25194,13505,0,25419,32770,32896,26130,26961,\n21341,34916,35265,30898,35744,36125,38021,38264,38271,38376,\n36367,38886,39029,39118,39134,39267,38928,40060,40479,40644,27503,63751,20023,\n135,38429,25143,38050,0,20539,28158,40051,40870,15817,34959,16718,28791,23797,\n19232,20941,13657,23856,24866,35378,36775,37366,29073,26393,29626,12929,41223,\n15499,6528,19216,30948,29698,20910,34575,16393,27235,41658,16931,34319,2671,\n31274,39239,35562,38741,28749,21284,8318,37876,30425,35299,40871,30685,20131,\n20464,20668,20015,20247,40872,21556,32139,22674,22736,7606,24210,24217,24514,\n10002,25995,13305,26905,27203,15459,27903,0,29184,17669,29580,16091,18963,\n23317,29881,35715,23716,22165,31379,31724,31939,32364,33528,34199,40873,34960,\n40874,36537,40875,36815,34143,39392,37409,40876,36281,5183,16497,17058,23066,\n0,0,0,39016,26475,17014,22333,0,34262,18811,33471,28941,19585,28020,23931,\n27413,28606,40877,40878,23446,40879,26343,32347,28247,31178,15752,17603,12886,\n10134,17306,17718,0,23765,15130,35577,23672,15634,13649,23928,40882,29015,\n17752,16620,7715,19575,14712,13386,420,27713,35532,20404,569,22975,33132,\n38998,39162,24379,2975,0,8641,35181,16642,18107,36985,16135,40883,41397,16632,\n14294,18167,27718,16764,34482,29695,17773,14548,21658,17761,17691,19849,19579,\n19830,17898,16328,19215,13921,17630,17597,16877,23870,23880,23894,15868,14351,\n23972,23993,14368,14392,24130,24253,24357,24451,14600,14612,14655,14669,24791,\n24893,23781,14729,25015,25017,25039,14776,25132,25232,25317,25368,14840,22193,\n14851,25570,25595,25607,25690,14923,25792,23829,22049,40863,14999,25990,15037,\n26111,26195,15090,26258,15138,\n26390,15170,26532,26624,15192,26698,26756,15218,15217,15227,26889,26947,29276,\n26980,27039,27013,15292,27094,15325,27237,27252,27249,27266,15340,27289,15346,\n27307,27317,27348,27382,27521,27585,27626,27765,27818,15563,27906,27910,27942,\n28033,15599,28068,28081,28181,28184,28201,28294,35264,28347,28386,28378,40831,\n28392,28393,28452,28468,15686,16193,28545,28606,15722,15733,29111,23705,15754,\n28716,15761,28752,28756,28783,28799,28809,805,17345,13809,3800,16087,22462,\n28371,28990,22496,13902,27042,35817,23412,31305,22753,38105,31333,31357,22956,\n31419,31408,31426,31427,29137,25741,16842,31450,31453,31466,16879,21682,23553,\n31499,31573,31529,21262,23806,31650,31599,33692,23476,27775,31696,33825,31634,\n0,23840,15789,23653,33938,31738,0,31797,23745,31812,31875,18562,31910,26237,\n17784,31945,31943,31974,31860,31987,31989,0,32359,17693,28228,32093,28374,\n29837,32137,32171,28981,32179,0,16471,24617,32228,15635,32245,6137,32229,\n33645,0,24865,24922,32366,32402,17195,37996,32295,32576,32577,32583,31030,\n25296,39393,32663,25425,32675,5729,104,17756,14182,17667,33594,32762,25737,0,\n32776,32797,0,32815,41095,27843,32827,32828,32865,10004,18825,26150,15843,\n26344,26405,32935,35400,33031,33050,22704,9974,27775,25752,20408,25831,5258,\n33304,6238,27219,19045,19093,17530,33321,2829,27218,15742,20473,5373,34018,\n33634,27402,18855,13616,6003,15864,33450,26907,63892,16859,34123,33488,33562,\n3606,6068,14017,12669,13658,33403,33506,33560,16011,28067,27397,27543,13774,\n15807,33565,21996,33669,17675,28069,33708,\n0,33747,13438,28372,27223,34138,13462,28226,12015,33880,23524,33905,15827,\n17636,27303,33866,15541,31064,0,27542,28279,28227,34014,0,33681,17568,33939,\n34020,23697,16960,23744,17731,34100,23282,28313,17703,34163,17686,26559,34326,\n34341,34363,34241,28808,34306,5506,28877,63922,17770,34344,13896,6306,21495,\n29594,34430,34673,41208,34798,11303,34737,34778,34831,22113,34412,26710,17935,\n34885,34886,30176,15801,30180,34910,34972,18011,34996,34997,25537,35013,30583,\n30479,35207,35210,0,0,35239,35260,35365,35303,31012,31421,35484,30611,37374,\n35472,31321,31465,31546,16271,18195,31544,29052,35596,35615,21552,21861,35647,\n35660,35661,35497,19066,35728,35739,35503,5855,17941,34895,35995,32084,32143,\n63956,14117,32083,36054,32152,32189,36114,36099,6416,36059,28764,36113,19657,\n16080,0,36265,32770,4116,18826,15228,33212,28940,31463,36525,36534,36547,\n37588,36633,36653,33637,33810,36773,37635,41631,2640,36787,18730,35294,34109,\n15803,24312,12898,36857,40980,34492,34049,8997,14720,28375,36919,34108,31422,\n36961,34156,34315,37032,34579,37060,34534,37038,0,37223,15088,37289,37316,\n31916,35123,7817,37390,27807,37441,37474,21945,0,35526,15515,35596,21979,3377,\n37676,37739,35553,35819,28815,23235,35554,35557,18789,37444,35820,35897,35839,\n37747,37979,36540,38277,38310,37926,38304,28662,17081,9850,34520,4732,15918,\n18911,27676,38523,38550,16748,38563,28373,25050,38582,30965,35552,38589,21452,\n18849,27832,628,25616,37039,37093,19153,6421,13066,38705,34370,38710,18959,\n17725,17797,19177,28789,23361,38683,\n0,37333,38743,23370,37355,38751,37925,20688,12471,12476,38793,38815,38833,\n38846,38848,38866,38880,21612,38894,29724,37939,0,38901,37917,31098,19153,\n38964,38963,38987,39014,15118,29045,15697,1584,16732,22278,39114,39095,39112,\n39111,19199,27943,5843,21936,39137,39142,39148,37752,39225,18985,19314,38999,\n39173,39413,39436,39483,39440,39512,22309,14020,37041,39893,39648,39650,39685,\n39668,19470,39700,39725,34304,20532,39732,27048,14531,12413,39760,39744,40254,\n23109,6243,39822,16971,39938,39935,39948,40552,40404,40887,41362,41387,41185,\n41251,41439,40318,40323,41268,40462,26760,40388,8539,41363,41504,6459,41523,\n40249,41145,41652,40592,40597,40606,40610,19764,40618,40623,17252,40641,15200,\n14821,15645,20274,14270,35883,40706,40712,19350,37924,28066,40727,0,40761,\n22175,22154,40773,39352,37003,38898,33919,40802,40809,31452,40846,29206,19390,\n18805,18875,29047,18936,17224,19025,29598,35802,6394,31135,35198,36406,37737,\n37875,35396,37612,37761,37835,35180,17593,29207,16107,30578,31299,28880,17523,\n17400,29054,6127,28835,6334,13721,16071,6277,21551,6136,14114,5883,6201,14049,\n6004,6353,24395,14115,5824,22363,18981,5118,4776,5062,5302,34051,13990,0,\n33877,18836,29029,15921,21852,16123,28754,17652,14062,39325,28454,26617,14131,\n15381,15847,22636,6434,26640,16471,14143,16609,16523,16655,27681,21707,22174,\n26289,22162,4063,2984,3597,37830,35603,37788,20216,20779,14361,17462,20156,\n1125,895,20299,20362,22097,23144,427,971,14745,778,1044,13365,20265,704,36531,\n629,35546,524,20120,20685,\n20749,20386,20227,18958,16010,20290,20526,20588,20609,20428,20453,20568,20732,\n0,0,0,0,28278,13717,15929,16063,28018,6276,16009,20904,20931,1504,17629,1187,\n1170,1169,36218,35484,1806,21081,21156,2163,21217,0,18042,29068,17292,3104,\n18860,4324,27089,3613,0,16094,29849,29716,29782,29592,19342,19132,16525,21456,\n13700,29199,16585,21940,837,21709,3014,22301,37469,38644,37734,22493,22413,\n22399,13886,22731,23193,35398,5882,5999,5904,23084,22968,37519,23166,23247,\n23058,22854,6643,6241,17045,14069,27909,29763,23073,24195,23169,35799,1043,\n37856,29836,4867,28933,18802,37896,35323,37821,14240,23582,23710,24158,24136,\n6550,6524,15086,24269,23375,6403,6404,14081,6304,14045,5886,14035,33066,35399,\n7610,13426,35240,24332,24334,6439,6059,23147,5947,23364,34324,30205,34912,\n24702,10336,9771,24539,16056,9647,9662,37000,28531,25024,62,70,9755,24985,\n24984,24693,11419,11527,18132,37197,25713,18021,11114,14889,11042,13392,39146,\n11896,25399,42075,25782,25393,25553,18915,11623,25252,11425,25659,25963,26994,\n15348,12430,12973,18825,12971,21773,13024,6361,37951,26318,12937,12723,15072,\n16784,21892,35618,21903,5884,21851,21541,30958,12547,6186,12852,13412,12815,\n12674,17097,26254,27940,26219,19347,26160,30832,7659,26211,13010,13025,26142,\n22642,14545,14394,14268,15257,14242,13310,29904,15254,26511,17962,26806,26654,\n15300,27326,14435,14293,17543,27187,27218,27337,27397,6418,25873,26776,27212,\n15319,27258,27479,16320,15514,37792,37618,35818,35531,37513,32798,35292,37991,\n28069,28427,\n18924,0,16255,15759,28164,16444,23101,28170,22599,27940,30786,28987,17178,\n17014,28913,29264,29319,29332,18319,18213,20857,19108,1515,29818,16120,13919,\n19018,18711,24545,16134,16049,19167,35875,16181,24743,16115,29900,29756,37767,\n29751,17567,28138,17745,30083,16227,19673,19718,16216,30037,30323,42438,15129,\n29800,35532,18859,18830,15099,15821,19022,16127,18885,18675,37370,22322,37698,\n35555,6244,20703,21025,20967,30584,12850,30478,30479,30587,18071,14209,14942,\n18672,29752,29851,16063,19130,19143,16584,19094,25006,37639,21889,30750,30861,\n30856,30930,29648,31065,30529,22243,16654,0,33942,31141,27181,16122,31290,\n31220,16750,5862,16690,37429,31217,3404,18828,665,15802,5998,13719,21867,\n13680,13994,468,3085,31458,23129,9973,23215,23196,23053,603,30960,23082,23494,\n31486,16889,31837,31853,16913,23475,24252,24230,31949,18937,6064,31886,31868,\n31918,27314,32220,32263,32211,32590,25185,24924,31560,32151,24194,17002,27509,\n2326,26582,78,13775,22468,25618,25592,18786,32733,31527,2092,23273,23875,\n31500,24078,39398,34373,39523,27164,13375,14818,18935,26029,39455,26016,33920,\n28967,27857,17642,33079,17410,32966,33033,33090,26548,39107,27202,33378,33381,\n27217,33875,28071,34320,29211,23174,16767,6208,23339,6305,23268,6360,34464,\n63932,15759,34861,29730,23042,34926,20293,34951,35007,35046,35173,35149,22147,\n35156,30597,30596,35829,35801,35740,35321,16045,33955,18165,18127,14322,35389,\n35356,37960,24397,37419,17028,26068,28969,28868,6213,40301,35999,36073,32220,\n22938,30659,23024,17262,14036,36394,36519,19465,\n36656,36682,17140,27736,28603,8993,18587,28537,28299,6106,39913,14005,18735,\n37051,0,21873,18694,37307,37892,35403,16482,35580,37927,35869,35899,34021,\n35371,38297,38311,38295,38294,36148,29765,16066,18687,19010,17386,16103,12837,\n38543,36583,36454,36453,16076,18925,19064,16366,29714,29803,16124,38721,37040,\n26695,18973,37011,22495,0,37736,35209,35878,35631,25534,37562,23313,35689,\n18748,29689,16923,38811,38769,39224,3878,24001,35781,19122,38943,38106,37622,\n38359,37349,17600,35664,19047,35684,39132,35397,16128,37418,18725,33812,39227,\n39245,31494,15869,39323,19311,39338,39516,35685,22728,27279,39457,23294,39471,\n39153,19344,39240,39356,19389,19351,37757,22642,4866,22562,18872,5352,30788,\n10015,15800,26821,15741,37976,14631,24912,10113,10603,24839,40015,40019,40059,\n39989,39952,39807,39887,40493,39839,41461,41214,40225,19630,16644,40472,19632,\n40204,41396,41197,41203,39215,40357,33981,28178,28639,27522,34300,17715,28068,\n28292,28144,33824,34286,28160,14295,24676,31202,13724,13888,18733,18910,15714,\n37851,37566,37704,703,30905,37495,37965,20452,13376,36964,21853,30781,30804,\n30902,30795,5975,12745,18753,13978,20338,28634,28633,0,28702,21524,16821,\n22459,22771,22410,40214,22487,28980,13487,16812,29163,27712,20375,0,6069,\n35401,24844,23246,23051,17084,17544,14124,19323,35324,37819,37816,6358,3869,\n33906,27840,5139,17146,11302,17345,22932,15799,26433,32168,24923,24740,18873,\n18827,35322,37605,29666,16105,29876,35683,6303,16097,19123,27352,29683,29691,\n16086,19006,19092,6105,19046,935,5156,18917,29768,\n18710,28837,18806,37508,29670,37727,1278,37681,35534,35350,37766,35815,21973,\n18741,35458,29035,18755,3327,22180,1562,3051,3256,21762,31172,6138,32254,5826,\n19024,6226,17710,37889,14090,35520,18861,22960,6335,6275,29828,23201,14050,\n15707,14000,37471,23161,35457,6242,37748,15565,2740,19094,14730,20724,15721,\n15692,5020,29045,17147,33304,28175,37092,17643,27991,32335,28775,27823,15574,\n16365,15917,28162,28428,15727,1013,30033,14012,13512,18048,16090,18545,22980,\n37486,18750,36673,35868,27584,22546,22472,14038,5202,28926,17250,19057,12259,\n4784,9149,26809,26983,5016,13541,31732,14047,35459,14294,13306,19615,27162,\n13997,27831,33854,17631,17614,27942,27985,27778,28638,28439,28937,33597,5946,\n33773,27776,28755,6107,22921,23170,6067,23137,23153,6405,16892,14125,23023,\n5948,14023,29070,37776,26266,17061,23150,23083,17043,27179,16121,30518,17499,\n17098,28957,16985,35297,20400,27944,23746,17614,32333,17341,27148,16982,4868,\n28838,28979,17385,15781,27871,63525,19023,32357,23019,23855,15859,24412,19037,\n6111,32164,33830,21637,15098,13056,532,22398,2261,1561,16357,8094,41654,28675,\n37211,23920,29583,31955,35417,37920,20424,32743,29389,29456,31476,29496,29497,\n22262,29505,29512,16041,31512,36972,29173,18674,29665,33270,16074,30476,16081,\n27810,22269,29721,29726,29727,16098,16112,16116,16122,29907,16142,16211,30018,\n30061,30066,30093,16252,30152,30172,16320,30285,16343,30324,16348,30330,20316,\n29064,22051,35200,22633,16413,30531,16441,26465,16453,13787,30616,16490,16495,\n23646,30654,30667,22770,30744,28857,30748,\n16552,30777,30791,30801,30822,33864,21813,31027,26627,31026,16643,16649,31121,\n31129,36795,31238,36796,16743,31377,16818,31420,33401,16836,31439,31451,16847,\n20001,31586,31596,31611,31762,31771,16992,17018,31867,31900,17036,31928,17044,\n31981,36755,28864,3279,32207,32212,32208,32253,32686,32692,29343,17303,32800,\n32805,31545,32814,32817,32852,15820,22452,28832,32951,33001,17389,33036,29482,\n33038,33042,30048,33044,17409,15161,33110,33113,33114,17427,22586,33148,33156,\n17445,33171,17453,33189,22511,33217,33252,33364,17551,33446,33398,33482,33496,\n33535,17584,33623,38505,27018,33797,28917,33892,24803,33928,17668,33982,34017,\n34040,34064,34104,34130,17723,34159,34160,34272,17783,34418,34450,34482,34543,\n38469,34699,17926,17943,34990,35071,35108,35143,35217,31079,35369,35384,35476,\n35508,35921,36052,36082,36124,18328,22623,36291,18413,20206,36410,21976,22356,\n36465,22005,36528,18487,36558,36578,36580,36589,36594,36791,36801,36810,36812,\n36915,39364,18605,39136,37395,18718,37416,37464,37483,37553,37550,37567,37603,\n37611,37619,37620,37629,37699,37764,37805,18757,18769,40639,37911,21249,37917,\n37933,37950,18794,37972,38009,38189,38306,18855,38388,38451,18917,26528,18980,\n38720,18997,38834,38850,22100,19172,24808,39097,19225,39153,22596,39182,39193,\n20916,39196,39223,39234,39261,39266,19312,39365,19357,39484,39695,31363,39785,\n39809,39901,39921,39924,19565,39968,14191,7106,40265,39994,40702,22096,40339,\n40381,40384,40444,38134,36790,40571,40620,40625,40637,40646,38108,40674,40689,\n40696,31432,40772,148,695,928,26906,38083,22956,\n1239,22592,38081,14265,1493,1557,1654,5818,22359,29043,2754,2765,3007,21610,\n63547,3019,21662,3067,3131,3155,3173,3196,24807,3213,22138,3253,3293,3309,\n3439,3506,3528,26965,39983,34725,3588,3598,3799,3984,3885,3699,23584,4028,\n24075,4188,4175,4214,26398,4219,4232,4246,13895,4287,4307,4399,4411,21348,\n33965,4835,4981,4918,35713,5495,5657,6083,6087,20088,28859,6189,6506,6701,\n6725,7210,7280,7340,7880,25283,7893,7957,29080,26709,8261,27113,14024,8828,\n9175,9210,10026,10353,10575,33533,10599,10643,10965,35237,10984,36768,11022,\n38840,11071,38983,39613,11340,0,11400,11447,23528,11528,11538,11703,11669,\n11842,12148,12236,12339,12390,13087,13278,24497,26184,26303,31353,13671,13811,\n0,18874,0,13850,14102,0,838,22709,26382,26904,15015,30295,24546,15889,16057,\n30206,8346,18640,19128,16665,35482,17134,17165,16443,17204,17302,19013,1482,\n20946,1553,22943,7848,15294,15615,17412,17622,22408,18036,14747,18223,34280,\n39369,14178,8643,35678,35662,0,18450,18683,18965,29193,19136,3192,22885,20133,\n20358,1913,36570,20524,21135,22335,29041,21145,21529,16202,19111,21948,21574,\n21614,27474,0,13427,21823,30258,21854,18200,21858,21862,22471,18751,22621,\n20582,13563,13260,0,22787,18300,35144,23214,23433,23558,7568,22433,29009,0,\n24834,31762,36950,25010,20378,35682,25602,25674,23899,27639,0,25732,6428,\n35562,18934,25736,16367,25874,19392,26047,26293,10011,37989,22497,24981,23079,\n63693,0,22201,17697,26364,20074,18740,38486,28047,27837,13848,35191,\n26521,26734,25617,26718,0,26823,31554,37056,2577,26918,0,26937,31301,0,27130,\n39462,27181,13919,25705,33,31107,27188,27483,23852,13593,0,27549,18128,27812,\n30011,34917,28078,22710,14108,9613,28747,29133,15444,29312,29317,37505,8570,\n29323,37680,29414,18896,27705,38047,29776,3832,34855,35061,10534,33907,6065,\n28344,18986,6176,14756,14009,0,0,17727,26294,40109,39076,35139,30668,30808,\n22230,16607,5642,14753,14127,33000,5061,29101,33638,31197,37288,0,19639,28847,\n35243,31229,31242,31499,32102,16762,31555,31102,32777,28597,41695,27139,33560,\n21410,28167,37823,26678,38749,33135,32803,27061,5101,12847,32840,23941,35888,\n32899,22293,38947,35145,23979,18824,26046,27093,21458,19109,16257,15377,26422,\n32912,33012,33070,8097,33103,33161,33199,33306,33542,33583,33674,13770,33896,\n34474,18682,25574,35158,30728,37461,35256,17394,35303,17375,35304,35654,35796,\n23032,35849,0,36805,37100,0,37136,37180,15863,37214,19146,36816,29327,22155,\n38119,38377,38320,38328,38706,39121,39241,39274,39363,39464,39694,40282,40347,\n32415,40696,40739,19620,38215,41619,29090,41727,19857,36882,42443,19868,3228,\n36798,21953,36794,9392,36793,19091,17673,32383,28502,27313,20202,13540,35628,\n30877,14138,36480,6133,32804,35692,35737,31294,26287,15851,30293,15543,22069,\n22870,20122,24193,25176,22207,3693,36366,23405,16008,19614,25566,0,6134,6267,\n25904,22061,23626,21530,21265,15814,40344,19581,22050,22046,32585,24280,22901,\n15680,34672,19996,4074,3401,14010,33047,40286,36120,30267,40005,30286,30649,\n37701,21554,\n33096,33527,22053,33074,33816,32957,21994,31074,22083,21526,3741,13774,22021,\n22001,26353,33506,13869,30004,22000,21946,21655,21874,3137,3222,24272,20808,\n3702,11362,3746,40619,32090,21982,4213,25245,38765,21652,36045,29174,37238,\n25596,25529,25598,21865,11075,40050,11955,20890,13535,3495,20903,21581,21790,\n21779,30310,36397,26762,30129,32950,34820,34694,35015,33206,33820,4289,17644,\n29444,18182,23440,33547,26771,22139,9972,32047,16803,32115,28368,29366,37232,\n4569,37384,15612,42665,3756,3833,29286,7330,18254,20418,32761,4075,16634,\n40029,25887,11680,18675,18400,40316,4076,3594,0,30115,4077,0,24648,4487,29091,\n32398,40272,19994,19972,13687,23309,27826,21351,13996,14812,21373,13989,17944,\n22682,19310,33325,21579,22442,23189,2425,0,14930,9317,29556,40620,19721,39917,\n15614,40752,19547,20393,38302,40926,33884,15798,29362,26547,14112,25390,32037,\n16119,15916,14890,36872,21196,15988,13946,17897,1166,30272,23280,3766,30842,\n32558,22695,16575,22140,39819,23924,30292,42036,40581,19681,0,14331,24857,\n12506,17394,0,22109,4777,22439,18787,40454,21044,28846,13741,0,40316,31830,\n39737,22494,5996,23635,25811,38096,25397,29028,34477,3368,27938,19170,3441,0,\n20990,7951,23950,38659,7633,40577,36940,31519,39682,23761,31651,25192,25397,\n39679,31695,39722,31870,0,31810,31878,39957,31740,39689,0,39963,18750,40794,\n21875,23491,20477,40600,20466,21088,15878,21201,22375,20566,22967,24082,38856,\n40363,36700,21609,38836,39232,38842,21292,24880,26924,21466,39946,40194,19515,\n38465,27008,20646,\n30022,5997,39386,21107,0,37209,38529,37212,0,37201,36503,25471,27939,27338,\n22033,37262,30074,25221,1020,29519,31856,23585,15613,0,18713,30422,39837,\n20010,3284,33726,34882,0,23626,27072,0,22394,21023,24053,20174,27697,498,\n20281,21660,21722,21146,36226,13822,0,13811,0,27474,37244,40869,39831,38958,\n39092,39610,40616,40580,29050,31508,0,27642,34840,32632,0,22048,42570,36471,\n40787,0,36308,36431,40476,36353,25218,33661,36392,36469,31443,19063,31294,\n30936,27882,35431,30215,35418,40742,27854,34774,30147,41650,30803,63552,36108,\n29410,29553,35629,29442,29937,36075,19131,34351,24506,34976,17591,0,6203,\n28165,0,35454,9499,0,24829,30311,39639,40260,37742,39823,34805,0,0,36087,\n29484,38689,39856,13782,29362,19463,31825,39242,24921,24921,19460,40598,24957,\n0,22367,24943,25254,25145,0,14940,25058,21418,13301,25444,26626,13778,23895,\n35778,36826,36409,0,20697,7494,30982,21298,38456,3899,16485,0,30718,0,31938,\n24346,31962,31277,32870,32867,32077,29957,29938,35220,33306,26380,32866,29830,\n32859,29936,33027,30500,35209,26572,30035,28369,34729,34766,33224,34700,35401,\n36013,35651,30507,29944,34010,13877,27058,36262,0,35241,0,28089,34753,16401,\n29927,15835,29046,24740,24988,15569,0,24695,0,32625,35629,0,24809,19326,21024,\n15384,15559,24279,30294,21809,6468,4862,39171,28124,28845,23745,25005,35343,\n13943,238,26694,20238,17762,23327,25420,40784,40614,25195,1351,37595,1503,\n16325,34124,17077,29679,20917,13897,18754,35300,37700,6619,\n33518,15560,30780,26436,25311,18739,35242,672,27571,4869,20395,9453,20488,\n27945,31364,13824,19121,9491,0,894,24484,896,839,28379,1055,0,20737,13434,\n20750,39020,14147,33814,18852,1159,20832,13236,20842,3071,8444,741,9520,1422,\n12851,6531,23426,34685,1459,15513,20914,20920,40244,20937,20943,20945,15580,\n20947,19110,20915,20962,21314,20973,33741,26942,14125,24443,21003,21030,21052,\n21173,21079,21140,21177,21189,31765,34114,21216,34317,27411,0,35550,21833,\n28377,16256,2388,16364,21299,0,3042,27851,5926,26651,29653,24650,16042,14540,\n5864,29149,17570,21357,21364,34475,21374,0,5526,5651,30694,21395,35483,21408,\n21419,21422,29607,22386,16217,29596,21441,21445,27721,20041,22526,21465,15019,\n2959,21472,16363,11683,21494,3191,21523,28793,21803,26199,27995,21613,27475,\n3444,21853,21647,21668,18342,5901,3805,15796,3405,35260,9880,21831,19693,\n21551,29719,21894,21929,0,6359,16442,17746,17461,26291,4276,22071,26317,12938,\n26276,26285,22093,22095,30961,22257,38791,21502,22272,22255,22253,35686,13859,\n4687,22342,16805,27758,28811,22338,14001,27774,22502,5142,22531,5204,17251,\n22566,19445,22620,22698,13665,22752,22748,4668,22779,23551,22339,41296,17016,\n37843,13729,22815,26790,14019,28249,5694,23076,21843,5778,34053,22985,3406,\n27777,27946,6108,23001,6139,6066,28070,28017,6184,5845,23033,28229,23211,\n23139,14054,18857,0,14088,23190,29797,23251,28577,9556,15749,6417,14130,5816,\n24195,21200,23414,25992,23420,31246,16388,18525,516,23509,24928,6708,22988,\n1445,23539,\n23453,19728,23557,6980,23571,29646,23572,7333,27432,23625,18653,23685,23785,\n23791,23947,7673,7735,23824,23832,23878,7844,23738,24023,33532,14381,18689,\n8265,8563,33415,14390,15298,24110,27274,0,24186,17596,3283,21414,20151,0,\n21416,6001,24073,24308,33922,24313,24315,14496,24316,26686,37915,24333,449,\n63636,15070,18606,4922,24378,26760,9168,0,9329,24419,38845,28270,24434,37696,\n35382,24487,23990,15711,21072,8042,28920,9832,37334,670,35369,24625,26245,\n6263,14691,15815,13881,22416,10164,31089,15936,24734,0,24755,18818,18831,\n31315,29860,20705,23200,24932,33828,24898,63654,28370,24961,20980,1622,24967,\n23466,16311,10335,25043,35741,39261,25040,14642,10624,10433,24611,24924,25886,\n25483,280,25285,6000,25301,11789,25452,18911,14871,25656,25592,5006,6140,0,\n28554,11830,38932,16524,22301,25825,25829,38011,14950,25658,14935,25933,28438,\n18984,18979,25989,25965,25951,12414,26037,18752,19255,26065,16600,6185,26080,\n26083,24543,13312,26136,12791,12792,26180,12708,12709,26187,3701,26215,20966,\n26227,0,7741,12849,34292,12744,21267,30661,10487,39332,26370,17308,18977,\n15147,27130,14274,0,26471,26466,16845,37101,26583,17641,26658,28240,37436,\n26625,13286,28064,26717,13423,27105,27147,35551,26995,26819,13773,26881,26880,\n15666,14849,13884,15232,26540,26977,35402,17148,26934,27032,15265,969,33635,\n20624,27129,13913,8490,27205,14083,27293,15347,26545,27336,37276,15373,27421,\n2339,24798,27445,27508,10189,28341,15067,949,6488,14144,21537,15194,27617,\n16124,27612,27703,9355,18673,27473,\n27738,33318,27769,15804,17605,15805,16804,18700,18688,15561,14053,15595,3378,\n39811,12793,9361,32655,26679,27941,28065,28139,28054,27996,28284,28420,18815,\n16517,28274,34099,28532,20935,0,0,33838,35617,0,15919,29779,16258,31180,28239,\n23185,12363,28664,14093,28573,15920,28410,5271,16445,17749,37872,28484,28508,\n15694,28532,37232,15675,28575,16708,28627,16529,16725,16441,16368,16308,16703,\n20959,16726,16727,16704,25053,28747,28798,28839,28801,28876,28885,28886,28895,\n16644,15848,29108,29078,17015,28971,28997,23176,29002,0,23708,17253,29007,\n37730,17089,28972,17498,18983,18978,29114,35816,28861,29198,37954,29205,22801,\n37955,29220,37697,22021,29230,29248,18804,26813,29269,29271,15957,12356,26637,\n28477,29314,0,29483,18467,34859,18669,34820,29480,29486,29647,29610,3130,\n27182,29641,29769,16866,5863,18980,26147,14021,18871,18829,18939,29687,29717,\n26883,18982,29753,1475,16087,0,10413,29792,36530,29767,29668,29814,33721,\n29804,14128,29812,37873,27180,29826,18771,19084,16735,19065,35727,23366,35843,\n6302,29896,6536,29966,0,29982,36569,6731,23511,36524,37765,30029,30026,30055,\n30062,20354,16132,19731,30094,29789,30110,30132,30210,30252,30289,30287,30319,\n30326,25589,30352,33263,14328,26897,26894,30369,30373,30391,30412,28575,33890,\n20637,20861,7708,30494,30502,30528,25775,21024,30552,12972,30639,35172,35176,\n5825,30708,0,4982,18962,26826,30895,30919,30931,38565,31022,21984,30935,31028,\n30897,30220,36792,34948,35627,24707,9756,31110,35072,26882,31104,22615,31133,\n31545,31036,31145,28202,28966,\n16040,31174,37133,31188,1312,17503,21007,47234,248,16384,43296,1102,0,0,2868,\n1,0,0,0,0,0,0,0,3072,64,0,0,0,1024,88,60,0,0,23680,56493,48115,17353,60910,\n4004,49446,30363,61426,64478,63482,12815,44868,61438,65277,24593,176,8448,\n33049,4128,43144,8544,9321,17408,50313,0,16387,53,33859,20785,26771,514,0,0,0,\n0,0,16384,256,44160,33380,35904,37025,20484,54368,53760,6186,26781,38709,\n55375,8440,33476,10268,30082,660,16440,41376,4293,19825,3524,47512,23390,\n17153,39327,30723,57888,2079,393,16585,775,39437,21136,20433,892,8450,49184,\n4974,46467,62939,30693,20368,39447,5942,12,47726,12041,21600,7680,26744,28706,\n40534,62245,46990,2839,59119,6007,7003,4289,36248,6162,53174,12545,6770,11355,\n49334,57888,23747,7042,56032,34254,16598,21673,53259,18447,16452,2320,16596,\n15278,7780,11076,2071,33414,6198,35232,40167,2139,900,55810,60560,34779,49029,\n44450,36509,39069,9504,70,40774,58239,51669,62596,19926,58118,6326,2322,0,\n1024,0,32,0,512,0,0,0,0,8192,0,0,0,0,0,0,8,36352,28280,16223,56702,63293,\n39932,44796,65490,27535,59377,47807,28334,61207,42972,46654,30645,37577,42455,\n19126,39790,33209,26445,21758,39921,65122,21103,14039,49150,17705,63873,26045,\n17062,57,16896,36704,37888,16448,45010,53719,219,39072,31666,20998,38944,\n51222,2365,0,1,0,2561,2226,128,0,34820,5152,19472,0,4,17569,16,321,\n2048,61504,20447,22582,62961,32949,26613,16512,20480,16718,33992,23040,55392,\n11009,20481,5793,16580,28402,44049,14624,49348,1800,2316,38552,39876,7184,\n27800,10886,422,4422,58733,50379,37568,8464,4630,29341,27124,5902,41514,62593,\n123,41992,36875,11280,14796,330,5872,2571,3136,59933,17420,17678,2,\n"
  },
  {
    "path": "user.libc/src/locale/iconv.c",
    "content": "#include <iconv.h>\n#include <errno.h>\n#include <wchar.h>\n#include <string.h>\n#include <stdlib.h>\n#include <limits.h>\n#include <stdint.h>\n#include \"locale_impl.h\"\n\n#define UTF_32BE    0300\n#define UTF_16LE    0301\n#define UTF_16BE    0302\n#define UTF_32LE    0303\n#define UCS2BE      0304\n#define UCS2LE      0305\n#define WCHAR_T     0306\n#define US_ASCII    0307\n#define UTF_8       0310\n#define UTF_16      0312\n#define UTF_32      0313\n#define UCS2        0314\n#define EUC_JP      0320\n#define SHIFT_JIS   0321\n#define ISO2022_JP  0322\n#define GB18030     0330\n#define GBK         0331\n#define GB2312      0332\n#define BIG5        0340\n#define EUC_KR      0350\n\n/* Definitions of charmaps. Each charmap consists of:\n * 1. Empty-string-terminated list of null-terminated aliases.\n * 2. Special type code or number of elided quads of entries.\n * 3. Character table (size determined by field 2), consisting\n *    of 5 bytes for every 4 characters, interpreted as 10-bit\n *    indices into the legacy_chars table. */\n\nstatic const unsigned char charmaps[] =\n\"utf8\\0char\\0\\0\\310\"\n\"wchart\\0\\0\\306\"\n\"ucs2be\\0\\0\\304\"\n\"ucs2le\\0\\0\\305\"\n\"utf16be\\0\\0\\302\"\n\"utf16le\\0\\0\\301\"\n\"ucs4be\\0utf32be\\0\\0\\300\"\n\"ucs4le\\0utf32le\\0\\0\\303\"\n\"ascii\\0usascii\\0iso646\\0iso646us\\0\\0\\307\"\n\"utf16\\0\\0\\312\"\n\"ucs4\\0utf32\\0\\0\\313\"\n\"ucs2\\0\\0\\314\"\n\"eucjp\\0\\0\\320\"\n\"shiftjis\\0sjis\\0\\0\\321\"\n\"iso2022jp\\0\\0\\322\"\n\"gb18030\\0\\0\\330\"\n\"gbk\\0\\0\\331\"\n\"gb2312\\0\\0\\332\"\n\"big5\\0bigfive\\0cp950\\0big5hkscs\\0\\0\\340\"\n\"euckr\\0ksc5601\\0ksx1001\\0cp949\\0\\0\\350\"\n#include \"codepages.h\"\n;\n\n/* Table of characters that appear in legacy 8-bit codepages,\n * limited to 1024 slots (10 bit indices). The first 256 entries\n * are elided since those characters are obviously all included. */\nstatic const unsigned short legacy_chars[] = {\n#include \"legacychars.h\"\n};\n\nstatic const unsigned short jis0208[84][94] = {\n#include \"jis0208.h\"\n};\n\nstatic const unsigned short gb18030[126][190] = {\n#include \"gb18030.h\"\n};\n\nstatic const unsigned short big5[89][157] = {\n#include \"big5.h\"\n};\n\nstatic const unsigned short hkscs[] = {\n#include \"hkscs.h\"\n};\n\nstatic const unsigned short ksc[93][94] = {\n#include \"ksc.h\"\n};\n\nstatic const unsigned short rev_jis[] = {\n#include \"revjis.h\"\n};\n\nstatic int fuzzycmp(const unsigned char *a, const unsigned char *b)\n{\n\tfor (; *a && *b; a++, b++) {\n\t\twhile (*a && (*a|32U)-'a'>26 && *a-'0'>10U) a++;\n\t\tif ((*a|32U) != *b) return 1;\n\t}\n\treturn *a != *b;\n}\n\nstatic size_t find_charmap(const void *name)\n{\n\tconst unsigned char *s;\n\tif (!*(char *)name) name=charmaps; /* \"utf8\" */\n\tfor (s=charmaps; *s; ) {\n\t\tif (!fuzzycmp(name, s)) {\n\t\t\tfor (; *s; s+=strlen((void *)s)+1);\n\t\t\treturn s+1-charmaps;\n\t\t}\n\t\ts += strlen((void *)s)+1;\n\t\tif (!*s) {\n\t\t\tif (s[1] > 0200) s+=2;\n\t\t\telse s+=2+(64U-s[1])*5;\n\t\t}\n\t}\n\treturn -1;\n}\n\nstruct stateful_cd {\n\ticonv_t base_cd;\n\tunsigned state;\n};\n\nstatic iconv_t combine_to_from(size_t t, size_t f)\n{\n\treturn (void *)(f<<16 | t<<1 | 1);\n}\n\nstatic size_t extract_from(iconv_t cd)\n{\n\treturn (size_t)cd >> 16;\n}\n\nstatic size_t extract_to(iconv_t cd)\n{\n\treturn (size_t)cd >> 1 & 0x7fff;\n}\n\niconv_t iconv_open(const char *to, const char *from)\n{\n\tsize_t f, t;\n\tstruct stateful_cd *scd;\n\n\tif ((t = find_charmap(to))==-1\n\t || (f = find_charmap(from))==-1\n\t || (charmaps[t] >= 0330)) {\n\t\terrno = EINVAL;\n\t\treturn (iconv_t)-1;\n\t}\n\ticonv_t cd = combine_to_from(t, f);\n\n\tswitch (charmaps[f]) {\n\tcase UTF_16:\n\tcase UTF_32:\n\tcase UCS2:\n\tcase ISO2022_JP:\n\t\tscd = malloc(sizeof *scd);\n\t\tif (!scd) return (iconv_t)-1;\n\t\tscd->base_cd = cd;\n\t\tscd->state = 0;\n\t\tcd = (iconv_t)scd;\n\t}\n\n\treturn cd;\n}\n\nstatic unsigned get_16(const unsigned char *s, int e)\n{\n\te &= 1;\n\treturn s[e]<<8 | s[1-e];\n}\n\nstatic void put_16(unsigned char *s, unsigned c, int e)\n{\n\te &= 1;\n\ts[e] = c>>8;\n\ts[1-e] = c;\n}\n\nstatic unsigned get_32(const unsigned char *s, int e)\n{\n\te &= 3;\n\treturn s[e]+0U<<24 | s[e^1]<<16 | s[e^2]<<8 | s[e^3];\n}\n\nstatic void put_32(unsigned char *s, unsigned c, int e)\n{\n\te &= 3;\n\ts[e^0] = c>>24;\n\ts[e^1] = c>>16;\n\ts[e^2] = c>>8;\n\ts[e^3] = c;\n}\n\n/* Adapt as needed */\n#define mbrtowc_utf8 mbrtowc\n#define wctomb_utf8 wctomb\n\nstatic unsigned legacy_map(const unsigned char *map, unsigned c)\n{\n\tif (c < 4*map[-1]) return c;\n\tunsigned x = c - 4*map[-1];\n\tx = map[x*5/4]>>2*x%8 | map[x*5/4+1]<<8-2*x%8 & 1023;\n\treturn x < 256 ? x : legacy_chars[x-256];\n}\n\nstatic unsigned uni_to_jis(unsigned c)\n{\n\tunsigned nel = sizeof rev_jis / sizeof *rev_jis;\n\tunsigned d, j, i, b = 0;\n\tfor (;;) {\n\t\ti = nel/2;\n\t\tj = rev_jis[b+i];\n\t\td = jis0208[j/256][j%256];\n\t\tif (d==c) return j + 0x2121;\n\t\telse if (nel == 1) return 0;\n\t\telse if (c < d)\n\t\t\tnel /= 2;\n\t\telse {\n\t\t\tb += i;\n\t\t\tnel -= nel/2;\n\t\t}\n\t}\n}\n\nsize_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restrict out, size_t *restrict outb)\n{\n\tsize_t x=0;\n\tstruct stateful_cd *scd=0;\n\tif (!((size_t)cd & 1)) {\n\t\tscd = (void *)cd;\n\t\tcd = scd->base_cd;\n\t}\n\tunsigned to = extract_to(cd);\n\tunsigned from = extract_from(cd);\n\tconst unsigned char *map = charmaps+from+1;\n\tconst unsigned char *tomap = charmaps+to+1;\n\tmbstate_t st = {0};\n\twchar_t wc;\n\tunsigned c, d;\n\tsize_t k, l;\n\tint err;\n\tunsigned char type = map[-1];\n\tunsigned char totype = tomap[-1];\n\tlocale_t *ploc = &CURRENT_LOCALE, loc = *ploc;\n\n\tif (!in || !*in || !*inb) return 0;\n\n\t*ploc = UTF8_LOCALE;\n\n\tfor (; *inb; *in+=l, *inb-=l) {\n\t\tc = *(unsigned char *)*in;\n\t\tl = 1;\n\n\t\tswitch (type) {\n\t\tcase UTF_8:\n\t\t\tif (c < 128) break;\n\t\t\tl = mbrtowc_utf8(&wc, *in, *inb, &st);\n\t\t\tif (l == (size_t)-1) goto ilseq;\n\t\t\tif (l == (size_t)-2) goto starved;\n\t\t\tc = wc;\n\t\t\tbreak;\n\t\tcase US_ASCII:\n\t\t\tif (c >= 128) goto ilseq;\n\t\t\tbreak;\n\t\tcase WCHAR_T:\n\t\t\tl = sizeof(wchar_t);\n\t\t\tif (*inb < l) goto starved;\n\t\t\tc = *(wchar_t *)*in;\n\t\t\tif (0) {\n\t\tcase UTF_32BE:\n\t\tcase UTF_32LE:\n\t\t\tl = 4;\n\t\t\tif (*inb < 4) goto starved;\n\t\t\tc = get_32((void *)*in, type);\n\t\t\t}\n\t\t\tif (c-0xd800u < 0x800u || c >= 0x110000u) goto ilseq;\n\t\t\tbreak;\n\t\tcase UCS2BE:\n\t\tcase UCS2LE:\n\t\tcase UTF_16BE:\n\t\tcase UTF_16LE:\n\t\t\tl = 2;\n\t\t\tif (*inb < 2) goto starved;\n\t\t\tc = get_16((void *)*in, type);\n\t\t\tif ((unsigned)(c-0xdc00) < 0x400) goto ilseq;\n\t\t\tif ((unsigned)(c-0xd800) < 0x400) {\n\t\t\t\tif (type-UCS2BE < 2U) goto ilseq;\n\t\t\t\tl = 4;\n\t\t\t\tif (*inb < 4) goto starved;\n\t\t\t\td = get_16((void *)(*in + 2), type);\n\t\t\t\tif ((unsigned)(d-0xdc00) >= 0x400) goto ilseq;\n\t\t\t\tc = ((c-0xd7c0)<<10) + (d-0xdc00);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase UCS2:\n\t\tcase UTF_16:\n\t\t\tl = 0;\n\t\t\tif (!scd->state) {\n\t\t\t\tif (*inb < 2) goto starved;\n\t\t\t\tc = get_16((void *)*in, 0);\n\t\t\t\tscd->state = type==UCS2\n\t\t\t\t\t? c==0xfffe ? UCS2LE : UCS2BE\n\t\t\t\t\t: c==0xfffe ? UTF_16LE : UTF_16BE;\n\t\t\t\tif (c == 0xfffe || c == 0xfeff)\n\t\t\t\t\tl = 2;\n\t\t\t}\n\t\t\ttype = scd->state;\n\t\t\tcontinue;\n\t\tcase UTF_32:\n\t\t\tl = 0;\n\t\t\tif (!scd->state) {\n\t\t\t\tif (*inb < 4) goto starved;\n\t\t\t\tc = get_32((void *)*in, 0);\n\t\t\t\tscd->state = c==0xfffe0000 ? UTF_32LE : UTF_32BE;\n\t\t\t\tif (c == 0xfffe0000 || c == 0xfeff)\n\t\t\t\t\tl = 4;\n\t\t\t}\n\t\t\ttype = scd->state;\n\t\t\tcontinue;\n\t\tcase SHIFT_JIS:\n\t\t\tif (c < 128) break;\n\t\t\tif (c-0xa1 <= 0xdf-0xa1) {\n\t\t\t\tc += 0xff61-0xa1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tl = 2;\n\t\t\tif (*inb < 2) goto starved;\n\t\t\td = *((unsigned char *)*in + 1);\n\t\t\tif (c-129 <= 159-129) c -= 129;\n\t\t\telse if (c-224 <= 239-224) c -= 193;\n\t\t\telse goto ilseq;\n\t\t\tc *= 2;\n\t\t\tif (d-64 <= 158-64) {\n\t\t\t\tif (d==127) goto ilseq;\n\t\t\t\tif (d>127) d--;\n\t\t\t\td -= 64;\n\t\t\t} else if (d-159 <= 252-159) {\n\t\t\t\tc++;\n\t\t\t\td -= 159;\n\t\t\t}\n\t\t\tc = jis0208[c][d];\n\t\t\tif (!c) goto ilseq;\n\t\t\tbreak;\n\t\tcase EUC_JP:\n\t\t\tif (c < 128) break;\n\t\t\tl = 2;\n\t\t\tif (*inb < 2) goto starved;\n\t\t\td = *((unsigned char *)*in + 1);\n\t\t\tif (c==0x8e) {\n\t\t\t\tc = d;\n\t\t\t\tif (c-0xa1 > 0xdf-0xa1) goto ilseq;\n\t\t\t\tc += 0xff61 - 0xa1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tc -= 0xa1;\n\t\t\td -= 0xa1;\n\t\t\tif (c >= 84 || d >= 94) goto ilseq;\n\t\t\tc = jis0208[c][d];\n\t\t\tif (!c) goto ilseq;\n\t\t\tbreak;\n\t\tcase ISO2022_JP:\n\t\t\tif (c >= 128) goto ilseq;\n\t\t\tif (c == '\\033') {\n\t\t\t\tl = 3;\n\t\t\t\tif (*inb < 3) goto starved;\n\t\t\t\tc = *((unsigned char *)*in + 1);\n\t\t\t\td = *((unsigned char *)*in + 2);\n\t\t\t\tif (c != '(' && c != '$') goto ilseq;\n\t\t\t\tswitch (128*(c=='$') + d) {\n\t\t\t\tcase 'B': scd->state=0; continue;\n\t\t\t\tcase 'J': scd->state=1; continue;\n\t\t\t\tcase 'I': scd->state=4; continue;\n\t\t\t\tcase 128+'@': scd->state=2; continue;\n\t\t\t\tcase 128+'B': scd->state=3; continue;\n\t\t\t\t}\n\t\t\t\tgoto ilseq;\n\t\t\t}\n\t\t\tswitch (scd->state) {\n\t\t\tcase 1:\n\t\t\t\tif (c=='\\\\') c = 0xa5;\n\t\t\t\tif (c=='~') c = 0x203e;\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\tcase 3:\n\t\t\t\tl = 2;\n\t\t\t\tif (*inb < 2) goto starved;\n\t\t\t\td = *((unsigned char *)*in + 1);\n\t\t\t\tc -= 0x21;\n\t\t\t\td -= 0x21;\n\t\t\t\tif (c >= 84 || d >= 94) goto ilseq;\n\t\t\t\tc = jis0208[c][d];\n\t\t\t\tif (!c) goto ilseq;\n\t\t\t\tbreak;\n\t\t\tcase 4:\n\t\t\t\tif (c-0x60 < 0x1f) goto ilseq;\n\t\t\t\tif (c-0x21 < 0x5e) c += 0xff61-0x21;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase GB2312:\n\t\t\tif (c < 128) break;\n\t\t\tif (c < 0xa1) goto ilseq;\n\t\tcase GBK:\n\t\tcase GB18030:\n\t\t\tif (c < 128) break;\n\t\t\tc -= 0x81;\n\t\t\tif (c >= 126) goto ilseq;\n\t\t\tl = 2;\n\t\t\tif (*inb < 2) goto starved;\n\t\t\td = *((unsigned char *)*in + 1);\n\t\t\tif (d < 0xa1 && type == GB2312) goto ilseq;\n\t\t\tif (d-0x40>=191 || d==127) {\n\t\t\t\tif (d-'0'>9 || type != GB18030)\n\t\t\t\t\tgoto ilseq;\n\t\t\t\tl = 4;\n\t\t\t\tif (*inb < 4) goto starved;\n\t\t\t\tc = (10*c + d-'0') * 1260;\n\t\t\t\td = *((unsigned char *)*in + 2);\n\t\t\t\tif (d-0x81>126) goto ilseq;\n\t\t\t\tc += 10*(d-0x81);\n\t\t\t\td = *((unsigned char *)*in + 3);\n\t\t\t\tif (d-'0'>9) goto ilseq;\n\t\t\t\tc += d-'0';\n\t\t\t\tc += 128;\n\t\t\t\tfor (d=0; d<=c; ) {\n\t\t\t\t\tk = 0;\n\t\t\t\t\tfor (int i=0; i<126; i++)\n\t\t\t\t\t\tfor (int j=0; j<190; j++)\n\t\t\t\t\t\t\tif (gb18030[i][j]-d <= c-d)\n\t\t\t\t\t\t\t\tk++;\n\t\t\t\t\td = c+1;\n\t\t\t\t\tc += k;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\td -= 0x40;\n\t\t\tif (d>63) d--;\n\t\t\tc = gb18030[c][d];\n\t\t\tbreak;\n\t\tcase BIG5:\n\t\t\tif (c < 128) break;\n\t\t\tl = 2;\n\t\t\tif (*inb < 2) goto starved;\n\t\t\td = *((unsigned char *)*in + 1);\n\t\t\tif (d-0x40>=0xff-0x40 || d-0x7f<0xa1-0x7f) goto ilseq;\n\t\t\td -= 0x40;\n\t\t\tif (d > 0x3e) d -= 0x22;\n\t\t\tif (c-0xa1>=0xfa-0xa1) {\n\t\t\t\tif (c-0x87>=0xff-0x87) goto ilseq;\n\t\t\t\tif (c < 0xa1) c -= 0x87;\n\t\t\t\telse c -= 0x87 + (0xfa-0xa1);\n\t\t\t\tc = (hkscs[4867+(c*157+d)/16]>>(c*157+d)%16)%2<<17\n\t\t\t\t\t| hkscs[c*157+d];\n\t\t\t\t/* A few HKSCS characters map to pairs of UCS\n\t\t\t\t * characters. These are mapped to surrogate\n\t\t\t\t * range in the hkscs table then hard-coded\n\t\t\t\t * here. Ugly, yes. */\n\t\t\t\tif (c/256 == 0xdc) {\n\t\t\t\t\tunion {\n\t\t\t\t\t\tchar c[8];\n\t\t\t\t\t\twchar_t wc[2];\n\t\t\t\t\t} tmp;\n\t\t\t\t\tchar *ptmp = tmp.c;\n\t\t\t\t\tsize_t tmpx = iconv(combine_to_from(to, find_charmap(\"utf8\")),\n\t\t\t\t\t\t&(char *){\"\\303\\212\\314\\204\"\n\t\t\t\t\t\t\"\\303\\212\\314\\214\"\n\t\t\t\t\t\t\"\\303\\252\\314\\204\"\n\t\t\t\t\t\t\"\\303\\252\\314\\214\"\n\t\t\t\t\t\t+c%256}, &(size_t){4},\n\t\t\t\t\t\t&ptmp, &(size_t){sizeof tmp});\n\t\t\t\t\tsize_t tmplen = ptmp - tmp.c;\n\t\t\t\t\tif (tmplen > *outb) goto toobig;\n\t\t\t\t\tif (tmpx) x++;\n\t\t\t\t\tmemcpy(*out, &tmp, tmplen);\n\t\t\t\t\t*out += tmplen;\n\t\t\t\t\t*outb -= tmplen;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (!c) goto ilseq;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tc -= 0xa1;\n\t\t\tc = big5[c][d]|(c==0x27&&(d==0x3a||d==0x3c||d==0x42))<<17;\n\t\t\tif (!c) goto ilseq;\n\t\t\tbreak;\n\t\tcase EUC_KR:\n\t\t\tif (c < 128) break;\n\t\t\tl = 2;\n\t\t\tif (*inb < 2) goto starved;\n\t\t\td = *((unsigned char *)*in + 1);\n\t\t\tc -= 0xa1;\n\t\t\td -= 0xa1;\n\t\t\tif (c >= 93 || d >= 94) {\n\t\t\t\tc += (0xa1-0x81);\n\t\t\t\td += 0xa1;\n\t\t\t\tif (c >= 93 || c>=0xc6-0x81 && d>0x52)\n\t\t\t\t\tgoto ilseq;\n\t\t\t\tif (d-'A'<26) d = d-'A';\n\t\t\t\telse if (d-'a'<26) d = d-'a'+26;\n\t\t\t\telse if (d-0x81<0xff-0x81) d = d-0x81+52;\n\t\t\t\telse goto ilseq;\n\t\t\t\tif (c < 0x20) c = 178*c + d;\n\t\t\t\telse c = 178*0x20 + 84*(c-0x20) + d;\n\t\t\t\tc += 0xac00;\n\t\t\t\tfor (d=0xac00; d<=c; ) {\n\t\t\t\t\tk = 0;\n\t\t\t\t\tfor (int i=0; i<93; i++)\n\t\t\t\t\t\tfor (int j=0; j<94; j++)\n\t\t\t\t\t\t\tif (ksc[i][j]-d <= c-d)\n\t\t\t\t\t\t\t\tk++;\n\t\t\t\t\td = c+1;\n\t\t\t\t\tc += k;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tc = ksc[c][d];\n\t\t\tif (!c) goto ilseq;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tif (!c) break;\n\t\t\tc = legacy_map(map, c);\n\t\t\tif (!c) goto ilseq;\n\t\t}\n\n\t\tswitch (totype) {\n\t\tcase WCHAR_T:\n\t\t\tif (*outb < sizeof(wchar_t)) goto toobig;\n\t\t\t*(wchar_t *)*out = c;\n\t\t\t*out += sizeof(wchar_t);\n\t\t\t*outb -= sizeof(wchar_t);\n\t\t\tbreak;\n\t\tcase UTF_8:\n\t\t\tif (*outb < 4) {\n\t\t\t\tchar tmp[4];\n\t\t\t\tk = wctomb_utf8(tmp, c);\n\t\t\t\tif (*outb < k) goto toobig;\n\t\t\t\tmemcpy(*out, tmp, k);\n\t\t\t} else k = wctomb_utf8(*out, c);\n\t\t\t*out += k;\n\t\t\t*outb -= k;\n\t\t\tbreak;\n\t\tcase US_ASCII:\n\t\t\tif (c > 0x7f) subst: x++, c='*';\n\t\tdefault:\n\t\t\tif (*outb < 1) goto toobig;\n\t\t\tif (c<256 && c==legacy_map(tomap, c)) {\n\t\t\trevout:\n\t\t\t\tif (*outb < 1) goto toobig;\n\t\t\t\t*(*out)++ = c;\n\t\t\t\t*outb -= 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\td = c;\n\t\t\tfor (c=4*totype; c<256; c++) {\n\t\t\t\tif (d == legacy_map(tomap, c)) {\n\t\t\t\t\tgoto revout;\n\t\t\t\t}\n\t\t\t}\n\t\t\tgoto subst;\n\t\tcase SHIFT_JIS:\n\t\t\tif (c < 128) goto revout;\n\t\t\tif (c == 0xa5) {\n\t\t\t\tx++;\n\t\t\t\tc = '\\\\';\n\t\t\t\tgoto revout;\n\t\t\t}\n\t\t\tif (c == 0x203e) {\n\t\t\t\tx++;\n\t\t\t\tc = '~';\n\t\t\t\tgoto revout;\n\t\t\t}\n\t\t\tif (c-0xff61 <= 0xdf-0xa1) {\n\t\t\t\tc += 0xa1 - 0xff61;\n\t\t\t\tgoto revout;\n\t\t\t}\n\t\t\tc = uni_to_jis(c);\n\t\t\tif (!c) goto subst;\n\t\t\tif (*outb < 2) goto toobig;\n\t\t\td = c%256;\n\t\t\tc = c/256;\n\t\t\t*(*out)++ = (c+1)/2 + (c<95 ? 112 : 176);\n\t\t\t*(*out)++ = c%2 ? d + 31 + d/96 : d + 126;\n\t\t\t*outb -= 2;\n\t\t\tbreak;\n\t\tcase EUC_JP:\n\t\t\tif (c < 128) goto revout;\n\t\t\tif (c-0xff61 <= 0xdf-0xa1) {\n\t\t\t\tc += 0x0e00 + 0x21 - 0xff61;\n\t\t\t} else {\n\t\t\t\tc = uni_to_jis(c);\n\t\t\t}\n\t\t\tif (!c) goto subst;\n\t\t\tif (*outb < 2) goto toobig;\n\t\t\t*(*out)++ = c/256 + 0x80;\n\t\t\t*(*out)++ = c%256 + 0x80;\n\t\t\t*outb -= 2;\n\t\t\tbreak;\n\t\tcase ISO2022_JP:\n\t\t\tif (c < 128) goto revout;\n\t\t\tif (c-0xff61 <= 0xdf-0xa1 || c==0xa5 || c==0x203e) {\n\t\t\t\tif (*outb < 7) goto toobig;\n\t\t\t\t*(*out)++ = '\\033';\n\t\t\t\t*(*out)++ = '(';\n\t\t\t\tif (c==0xa5) {\n\t\t\t\t\t*(*out)++ = 'J';\n\t\t\t\t\t*(*out)++ = '\\\\';\n\t\t\t\t} else if (c==0x203e) {\n\t\t\t\t\t*(*out)++ = 'J';\n\t\t\t\t\t*(*out)++ = '~';\n\t\t\t\t} else {\n\t\t\t\t\t*(*out)++ = 'I';\n\t\t\t\t\t*(*out)++ = c-0xff61+0x21;\n\t\t\t\t}\n\t\t\t\t*(*out)++ = '\\033';\n\t\t\t\t*(*out)++ = '(';\n\t\t\t\t*(*out)++ = 'B';\n\t\t\t\t*outb -= 7;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tc = uni_to_jis(c);\n\t\t\tif (!c) goto subst;\n\t\t\tif (*outb < 8) goto toobig;\n\t\t\t*(*out)++ = '\\033';\n\t\t\t*(*out)++ = '$';\n\t\t\t*(*out)++ = 'B';\n\t\t\t*(*out)++ = c/256;\n\t\t\t*(*out)++ = c%256;\n\t\t\t*(*out)++ = '\\033';\n\t\t\t*(*out)++ = '(';\n\t\t\t*(*out)++ = 'B';\n\t\t\t*outb -= 8;\n\t\t\tbreak;\n\t\tcase UCS2:\n\t\t\ttotype = UCS2BE;\n\t\tcase UCS2BE:\n\t\tcase UCS2LE:\n\t\tcase UTF_16:\n\t\tcase UTF_16BE:\n\t\tcase UTF_16LE:\n\t\t\tif (c < 0x10000 || totype-UCS2BE < 2U) {\n\t\t\t\tif (c >= 0x10000) c = 0xFFFD;\n\t\t\t\tif (*outb < 2) goto toobig;\n\t\t\t\tput_16((void *)*out, c, totype);\n\t\t\t\t*out += 2;\n\t\t\t\t*outb -= 2;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (*outb < 4) goto toobig;\n\t\t\tc -= 0x10000;\n\t\t\tput_16((void *)*out, (c>>10)|0xd800, totype);\n\t\t\tput_16((void *)(*out + 2), (c&0x3ff)|0xdc00, totype);\n\t\t\t*out += 4;\n\t\t\t*outb -= 4;\n\t\t\tbreak;\n\t\tcase UTF_32:\n\t\t\ttotype = UTF_32BE;\n\t\tcase UTF_32BE:\n\t\tcase UTF_32LE:\n\t\t\tif (*outb < 4) goto toobig;\n\t\t\tput_32((void *)*out, c, totype);\n\t\t\t*out += 4;\n\t\t\t*outb -= 4;\n\t\t\tbreak;\n\t\t}\n\t}\n\t*ploc = loc;\n\treturn x;\nilseq:\n\terr = EILSEQ;\n\tx = -1;\n\tgoto end;\ntoobig:\n\terr = E2BIG;\n\tx = -1;\n\tgoto end;\nstarved:\n\terr = EINVAL;\n\tx = -1;\nend:\n\terrno = err;\n\t*ploc = loc;\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/locale/iconv_close.c",
    "content": "#include <iconv.h>\n#include <stdlib.h>\n\nint iconv_close(iconv_t cd)\n{\n\tif (!((size_t)cd & 1)) free((void *)cd);\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/locale/jis0208.h",
    "content": "12288,12289,12290,65292,65294,12539,65306,65307,65311,65281,12443,12444,180,\n65344,168,65342,65507,65343,12541,12542,12445,12446,12291,20189,12293,12294,\n12295,12540,8213,8208,65295,92,12316,8214,65372,8230,8229,8216,8217,8220,8221,\n65288,65289,12308,12309,65339,65341,65371,65373,12296,12297,12298,12299,12300,\n12301,12302,12303,12304,12305,65291,8722,177,215,247,65309,8800,65308,65310,\n8806,8807,8734,8756,9794,9792,176,8242,8243,8451,65509,65284,162,163,65285,\n65283,65286,65290,65312,167,9734,9733,9675,9679,9678,9671,9670,9633,9632,9651,\n9650,9661,9660,8251,12306,8594,8592,8593,8595,12307,0,0,0,0,0,0,0,0,0,0,0,\n8712,8715,8838,8839,8834,8835,8746,8745,0,0,0,0,0,0,0,0,8743,8744,172,8658,\n8660,8704,8707,0,0,0,0,0,0,0,0,0,0,0,8736,8869,8978,8706,8711,8801,8786,8810,\n8811,8730,8765,8733,8757,8747,8748,0,0,0,0,0,0,0,8491,8240,9839,9837,9834,\n8224,8225,182,0,0,0,0,9711,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65296,65297,65298,\n65299,65300,65301,65302,65303,65304,65305,0,0,0,0,0,0,0,65313,65314,65315,\n65316,65317,65318,65319,65320,65321,65322,65323,65324,65325,65326,65327,65328,\n65329,65330,65331,65332,65333,65334,65335,65336,65337,65338,0,0,0,0,0,0,65345,\n65346,65347,\n65348,65349,65350,65351,65352,65353,65354,65355,65356,65357,65358,65359,65360,\n65361,65362,65363,65364,65365,65366,65367,65368,65369,65370,0,0,0,0,12353,\n12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,\n12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,\n12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,12392,\n12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,12405,\n12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,12418,\n12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431,\n12432,12433,12434,12435,0,0,0,0,0,0,0,0,0,0,0,12449,12450,12451,12452,12453,\n12454,12455,12456,12457,12458,12459,12460,12461,12462,12463,12464,12465,12466,\n12467,12468,12469,12470,12471,12472,12473,12474,12475,12476,12477,12478,12479,\n12480,12481,12482,12483,12484,12485,12486,12487,12488,12489,12490,12491,12492,\n12493,12494,12495,12496,12497,12498,12499,12500,12501,12502,12503,12504,12505,\n12506,12507,12508,12509,12510,12511,12512,12513,12514,12515,12516,12517,12518,\n12519,12520,12521,12522,12523,12524,12525,12526,12527,12528,12529,12530,12531,\n12532,12533,12534,0,0,0,0,0,0,0,0,913,914,915,916,917,918,919,920,921,922,923,\n924,925,926,927,928,929,931,932,933,934,935,936,937,0,0,0,0,0,0,0,0,945,946,\n947,948,949,950,951,952,953,\n954,955,956,957,958,959,960,961,963,964,965,966,967,968,969,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1040,1041,1042,1043,\n1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,\n1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,\n1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,\n1097,1098,1099,1100,1101,1102,1103,0,0,0,0,0,0,0,0,0,0,0,0,0,9472,9474,9484,\n9488,9496,9492,9500,9516,9508,9524,9532,9473,9475,9487,9491,9499,9495,9507,\n9523,9515,9531,9547,9504,9519,9512,9527,9535,9501,9520,9509,9528,9538,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,20124,21782,23043,38463,21696,24859,25384,23030,\n36898,33909,33564,31312,24746,25569,28197,26093,33894,33446,39925,26771,22311,\n26017,25201,23451,22992,34427,39156,32098,32190,39822,25110,31903,34999,23433,\n24245,25353,26263,26696,38343,38797,26447,20197,20234,20301,20381,20553,22258,\n22839,22996,23041,23561,24799,24847,24944,26131,26885,28858,30031,30064,31227,\n32173,32239,32963,33806,34915,35586,36949,36986,21307,20117,20133,22495,32946,\n37057,30959,19968,22769,28322,36920,31282,33576,33419,39983,20801,21360,21693,\n21729,22240,23035,24341,39154,28139,32996,34093,38498,38512,38560,38907,21515,\n21491,23431,28879,32701,36802,38632,21359,40284,31418,19985,30867,33276,28198,\n22040,21764,27421,34074,39995,23013,21417,28006,29916,38287,22082,20113,36939,\n38642,33615,39180,21473,21942,23344,24433,26144,26355,26628,27704,27891,27945,\n29787,30408,31310,38964,33521,34907,35424,37613,28082,30123,30410,39365,24742,\n35585,36234,38322,27022,21421,20870,22290,22576,22852,23476,24310,24616,25513,\n25588,27839,28436,28814,28948,29017,29141,29503,32257,33398,33489,34199,36960,\n37467,40219,22633,26044,27738,29989,20985,22830,22885,24448,24540,25276,26106,\n27178,27431,27572,29579,32705,35158,40236,40206,40644,23713,27798,33659,20740,\n23627,25014,33222,26742,29281,20057,20474,21368,24681,28201,31311,38899,19979,\n21270,20206,20309,20285,20385,20339,21152,21487,22025,22799,23233,23478,23521,\n31185,26247,26524,26550,27468,27827,28779,29634,31117,31166,31292,31623,33457,\n33499,33540,33655,33775,33747,34662,35506,22057,36008,36838,36942,38686,34442,\n20420,23784,25105,29273,30011,33253,33469,34558,36032,38597,39187,39381,20171,\n20250,35299,22238,22602,22730,24315,24555,24618,24724,24674,25040,25106,25296,\n25913,39745,26214,26800,28023,28784,30028,30342,32117,33445,34809,38283,38542,\n35997,20977,21182,22806,21683,23475,23830,24936,27010,28079,30861,33995,34903,\n35442,37799,39608,28012,39336,34521,22435,26623,34510,37390,21123,22151,21508,\n24275,25313,25785,26684,26680,27579,29554,30906,31339,35226,35282,36203,36611,\n37101,38307,38548,38761,23398,23731,27005,38989,38990,25499,31520,27179,27263,\n26806,39949,28511,21106,21917,24688,25324,27963,28167,28369,33883,35088,36676,\n19988,39993,21494,26907,27194,38788,26666,20828,31427,33970,37340,37772,22107,\n40232,26658,33541,33841,31909,21000,33477,29926,20094,\n20355,20896,23506,21002,21208,21223,24059,21914,22570,23014,23436,23448,23515,\n24178,24185,24739,24863,24931,25022,25563,25954,26577,26707,26874,27454,27475,\n27735,28450,28567,28485,29872,29976,30435,30475,31487,31649,31777,32233,32566,\n32752,32925,33382,33694,35251,35532,36011,36996,37969,38291,38289,38306,38501,\n38867,39208,33304,20024,21547,23736,24012,29609,30284,30524,23721,32747,36107,\n38593,38929,38996,39000,20225,20238,21361,21916,22120,22522,22855,23305,23492,\n23696,24076,24190,24524,25582,26426,26071,26082,26399,26827,26820,27231,24112,\n27589,27671,27773,30079,31048,23395,31232,32000,24509,35215,35352,36020,36215,\n36556,36637,39138,39438,39740,20096,20605,20736,22931,23452,25135,25216,25836,\n27450,29344,30097,31047,32681,34811,35516,35696,25516,33738,38816,21513,21507,\n21931,26708,27224,35440,30759,26485,40653,21364,23458,33050,34384,36870,19992,\n20037,20167,20241,21450,21560,23470,24339,24613,25937,26429,27714,27762,27875,\n28792,29699,31350,31406,31496,32026,31998,32102,26087,29275,21435,23621,24040,\n25298,25312,25369,28192,34394,35377,36317,37624,28417,31142,39770,20136,20139,\n20140,20379,20384,20689,20807,31478,20849,20982,21332,21281,21375,21483,21932,\n22659,23777,24375,24394,24623,24656,24685,25375,25945,27211,27841,29378,29421,\n30703,33016,33029,33288,34126,37111,37857,38911,39255,39514,20208,20957,23597,\n26241,26989,23616,26354,26997,29577,26704,31873,20677,21220,22343,24062,37670,\n26020,27427,27453,29748,31105,31165,31563,32202,33465,33740,34943,35167,35641,\n36817,37329,21535,37504,20061,20534,21477,21306,29399,\n29590,30697,33510,36527,39366,39368,39378,20855,24858,34398,21936,31354,20598,\n23507,36935,38533,20018,27355,37351,23633,23624,25496,31391,27795,38772,36705,\n31402,29066,38536,31874,26647,32368,26705,37740,21234,21531,34219,35347,32676,\n36557,37089,21350,34952,31041,20418,20670,21009,20804,21843,22317,29674,22411,\n22865,24418,24452,24693,24950,24935,25001,25522,25658,25964,26223,26690,28179,\n30054,31293,31995,32076,32153,32331,32619,33550,33610,34509,35336,35427,35686,\n36605,38938,40335,33464,36814,39912,21127,25119,25731,28608,38553,26689,20625,\n27424,27770,28500,31348,32080,34880,35363,26376,20214,20537,20518,20581,20860,\n21048,21091,21927,22287,22533,23244,24314,25010,25080,25331,25458,26908,27177,\n29309,29356,29486,30740,30831,32121,30476,32937,35211,35609,36066,36562,36963,\n37749,38522,38997,39443,40568,20803,21407,21427,24187,24358,28187,28304,29572,\n29694,32067,33335,35328,35578,38480,20046,20491,21476,21628,22266,22993,23396,\n24049,24235,24359,25144,25925,26543,28246,29392,31946,34996,32929,32993,33776,\n34382,35463,36328,37431,38599,39015,40723,20116,20114,20237,21320,21577,21566,\n23087,24460,24481,24735,26791,27278,29786,30849,35486,35492,35703,37264,20062,\n39881,20132,20348,20399,20505,20502,20809,20844,21151,21177,21246,21402,21475,\n21521,21518,21897,22353,22434,22909,23380,23389,23439,24037,24039,24055,24184,\n24195,24218,24247,24344,24658,24908,25239,25304,25511,25915,26114,26179,26356,\n26477,26657,26775,27083,27743,27946,28009,28207,28317,30002,30343,30828,31295,\n31968,32005,32024,32094,32177,32789,32771,32943,32945,\n33108,33167,33322,33618,34892,34913,35611,36002,36092,37066,37237,37489,30783,\n37628,38308,38477,38917,39321,39640,40251,21083,21163,21495,21512,22741,25335,\n28640,35946,36703,40633,20811,21051,21578,22269,31296,37239,40288,40658,29508,\n28425,33136,29969,24573,24794,39592,29403,36796,27492,38915,20170,22256,22372,\n22718,23130,24680,25031,26127,26118,26681,26801,28151,30165,32058,33390,39746,\n20123,20304,21449,21766,23919,24038,24046,26619,27801,29811,30722,35408,37782,\n35039,22352,24231,25387,20661,20652,20877,26368,21705,22622,22971,23472,24425,\n25165,25505,26685,27507,28168,28797,37319,29312,30741,30758,31085,25998,32048,\n33756,35009,36617,38555,21092,22312,26448,32618,36001,20916,22338,38442,22586,\n27018,32948,21682,23822,22524,30869,40442,20316,21066,21643,25662,26152,26388,\n26613,31364,31574,32034,37679,26716,39853,31545,21273,20874,21047,23519,25334,\n25774,25830,26413,27578,34217,38609,30352,39894,25420,37638,39851,30399,26194,\n19977,20632,21442,23665,24808,25746,25955,26719,29158,29642,29987,31639,32386,\n34453,35715,36059,37240,39184,26028,26283,27531,20181,20180,20282,20351,21050,\n21496,21490,21987,22235,22763,22987,22985,23039,23376,23629,24066,24107,24535,\n24605,25351,25903,23388,26031,26045,26088,26525,27490,27515,27663,29509,31049,\n31169,31992,32025,32043,32930,33026,33267,35222,35422,35433,35430,35468,35566,\n36039,36060,38604,39164,27503,20107,20284,20365,20816,23383,23546,24904,25345,\n26178,27425,28363,27835,29246,29885,30164,30913,31034,32780,32819,33258,33940,\n36766,27728,40575,24335,35672,40235,31482,36600,23437,\n38635,19971,21489,22519,22833,23241,23460,24713,28287,28422,30142,36074,23455,\n34048,31712,20594,26612,33437,23649,34122,32286,33294,20889,23556,25448,36198,\n26012,29038,31038,32023,32773,35613,36554,36974,34503,37034,20511,21242,23610,\n26451,28796,29237,37196,37320,37675,33509,23490,24369,24825,20027,21462,23432,\n25163,26417,27530,29417,29664,31278,33131,36259,37202,39318,20754,21463,21610,\n23551,25480,27193,32172,38656,22234,21454,21608,23447,23601,24030,20462,24833,\n25342,27954,31168,31179,32066,32333,32722,33261,33311,33936,34886,35186,35728,\n36468,36655,36913,37195,37228,38598,37276,20160,20303,20805,21313,24467,25102,\n26580,27713,28171,29539,32294,37325,37507,21460,22809,23487,28113,31069,32302,\n31899,22654,29087,20986,34899,36848,20426,23803,26149,30636,31459,33308,39423,\n20934,24490,26092,26991,27529,28147,28310,28516,30462,32020,24033,36981,37255,\n38918,20966,21021,25152,26257,26329,28186,24246,32210,32626,26360,34223,34295,\n35576,21161,21465,22899,24207,24464,24661,37604,38500,20663,20767,21213,21280,\n21319,21484,21736,21830,21809,22039,22888,22974,23100,23477,23558,23567,23569,\n23578,24196,24202,24288,24432,25215,25220,25307,25484,25463,26119,26124,26157,\n26230,26494,26786,27167,27189,27836,28040,28169,28248,28988,28966,29031,30151,\n30465,30813,30977,31077,31216,31456,31505,31911,32057,32918,33750,33931,34121,\n34909,35059,35359,35388,35412,35443,35937,36062,37284,37478,37758,37912,38556,\n38808,19978,19976,19998,20055,20887,21104,22478,22580,22732,23330,24120,24773,\n25854,26465,26454,27972,29366,30067,31331,33976,35698,\n37304,37664,22065,22516,39166,25325,26893,27542,29165,32340,32887,33394,35302,\n39135,34645,36785,23611,20280,20449,20405,21767,23072,23517,23529,24515,24910,\n25391,26032,26187,26862,27035,28024,28145,30003,30137,30495,31070,31206,32051,\n33251,33455,34218,35242,35386,36523,36763,36914,37341,38663,20154,20161,20995,\n22645,22764,23563,29978,23613,33102,35338,36805,38499,38765,31525,35535,38920,\n37218,22259,21416,36887,21561,22402,24101,25512,27700,28810,30561,31883,32736,\n34928,36930,37204,37648,37656,38543,29790,39620,23815,23913,25968,26530,36264,\n38619,25454,26441,26905,33733,38935,38592,35070,28548,25722,23544,19990,28716,\n30045,26159,20932,21046,21218,22995,24449,24615,25104,25919,25972,26143,26228,\n26866,26646,27491,28165,29298,29983,30427,31934,32854,22768,35069,35199,35488,\n35475,35531,36893,37266,38738,38745,25993,31246,33030,38587,24109,24796,25114,\n26021,26132,26512,30707,31309,31821,32318,33034,36012,36196,36321,36447,30889,\n20999,25305,25509,25666,25240,35373,31363,31680,35500,38634,32118,33292,34633,\n20185,20808,21315,21344,23459,23554,23574,24029,25126,25159,25776,26643,26676,\n27849,27973,27927,26579,28508,29006,29053,26059,31359,31661,32218,32330,32680,\n33146,33307,33337,34214,35438,36046,36341,36984,36983,37549,37521,38275,39854,\n21069,21892,28472,28982,20840,31109,32341,33203,31950,22092,22609,23720,25514,\n26366,26365,26970,29401,30095,30094,30990,31062,31199,31895,32032,32068,34311,\n35380,38459,36961,40736,20711,21109,21452,21474,20489,21930,22766,22863,29245,\n23435,23652,21277,24803,24819,25436,25475,25407,25531,\n25805,26089,26361,24035,27085,27133,28437,29157,20105,30185,30456,31379,31967,\n32207,32156,32865,33609,33624,33900,33980,34299,35013,36208,36865,36973,37783,\n38684,39442,20687,22679,24974,33235,34101,36104,36896,20419,20596,21063,21363,\n24687,25417,26463,28204,36275,36895,20439,23646,36042,26063,32154,21330,34966,\n20854,25539,23384,23403,23562,25613,26449,36956,20182,22810,22826,27760,35409,\n21822,22549,22949,24816,25171,26561,33333,26965,38464,39364,39464,20307,22534,\n23550,32784,23729,24111,24453,24608,24907,25140,26367,27888,28382,32974,33151,\n33492,34955,36024,36864,36910,38538,40667,39899,20195,21488,22823,31532,37261,\n38988,40441,28381,28711,21331,21828,23429,25176,25246,25299,27810,28655,29730,\n35351,37944,28609,35582,33592,20967,34552,21482,21481,20294,36948,36784,22890,\n33073,24061,31466,36799,26842,35895,29432,40008,27197,35504,20025,21336,22022,\n22374,25285,25506,26086,27470,28129,28251,28845,30701,31471,31658,32187,32829,\n32966,34507,35477,37723,22243,22727,24382,26029,26262,27264,27573,30007,35527,\n20516,30693,22320,24347,24677,26234,27744,30196,31258,32622,33268,34584,36933,\n39347,31689,30044,31481,31569,33988,36880,31209,31378,33590,23265,30528,20013,\n20210,23449,24544,25277,26172,26609,27880,34411,34935,35387,37198,37619,39376,\n27159,28710,29482,33511,33879,36015,19969,20806,20939,21899,23541,24086,24115,\n24193,24340,24373,24427,24500,25074,25361,26274,26397,28526,29266,30010,30522,\n32884,33081,33144,34678,35519,35548,36229,36339,37530,38263,38914,40165,21189,\n25431,30452,26389,27784,29645,36035,37806,38515,27941,\n22684,26894,27084,36861,37786,30171,36890,22618,26626,25524,27131,20291,28460,\n26584,36795,34086,32180,37716,26943,28528,22378,22775,23340,32044,29226,21514,\n37347,40372,20141,20302,20572,20597,21059,35998,21576,22564,23450,24093,24213,\n24237,24311,24351,24716,25269,25402,25552,26799,27712,30855,31118,31243,32224,\n33351,35330,35558,36420,36883,37048,37165,37336,40718,27877,25688,25826,25973,\n28404,30340,31515,36969,37841,28346,21746,24505,25764,36685,36845,37444,20856,\n22635,22825,23637,24215,28155,32399,29980,36028,36578,39003,28857,20253,27583,\n28593,30000,38651,20814,21520,22581,22615,22956,23648,24466,26007,26460,28193,\n30331,33759,36077,36884,37117,37709,30757,30778,21162,24230,22303,22900,24594,\n20498,20826,20908,20941,20992,21776,22612,22616,22871,23445,23798,23947,24764,\n25237,25645,26481,26691,26812,26847,30423,28120,28271,28059,28783,29128,24403,\n30168,31095,31561,31572,31570,31958,32113,21040,33891,34153,34276,35342,35588,\n35910,36367,36867,36879,37913,38518,38957,39472,38360,20685,21205,21516,22530,\n23566,24999,25758,27934,30643,31461,33012,33796,36947,37509,23776,40199,21311,\n24471,24499,28060,29305,30563,31167,31716,27602,29420,35501,26627,27233,20984,\n31361,26932,23626,40182,33515,23493,37193,28702,22136,23663,24775,25958,27788,\n35930,36929,38931,21585,26311,37389,22856,37027,20869,20045,20970,34201,35598,\n28760,25466,37707,26978,39348,32260,30071,21335,26976,36575,38627,27741,20108,\n23612,24336,36841,21250,36049,32905,34425,24319,26085,20083,20837,22914,23615,\n38894,20219,22922,24525,35469,28641,31152,31074,23527,\n33905,29483,29105,24180,24565,25467,25754,29123,31896,20035,24316,20043,22492,\n22178,24745,28611,32013,33021,33075,33215,36786,35223,34468,24052,25226,25773,\n35207,26487,27874,27966,29750,30772,23110,32629,33453,39340,20467,24259,25309,\n25490,25943,26479,30403,29260,32972,32954,36649,37197,20493,22521,23186,26757,\n26995,29028,29437,36023,22770,36064,38506,36889,34687,31204,30695,33833,20271,\n21093,21338,25293,26575,27850,30333,31636,31893,33334,34180,36843,26333,28448,\n29190,32283,33707,39361,40614,20989,31665,30834,31672,32903,31560,27368,24161,\n32908,30033,30048,20843,37474,28300,30330,37271,39658,20240,32624,25244,31567,\n38309,40169,22138,22617,34532,38588,20276,21028,21322,21453,21467,24070,25644,\n26001,26495,27710,27726,29256,29359,29677,30036,32321,33324,34281,36009,31684,\n37318,29033,38930,39151,25405,26217,30058,30436,30928,34115,34542,21290,21329,\n21542,22915,24199,24444,24754,25161,25209,25259,26000,27604,27852,30130,30382,\n30865,31192,32203,32631,32933,34987,35513,36027,36991,38750,39131,27147,31800,\n20633,23614,24494,26503,27608,29749,30473,32654,40763,26570,31255,21305,30091,\n39661,24422,33181,33777,32920,24380,24517,30050,31558,36924,26727,23019,23195,\n32016,30334,35628,20469,24426,27161,27703,28418,29922,31080,34920,35413,35961,\n24287,25551,30149,31186,33495,37672,37618,33948,34541,39981,21697,24428,25996,\n27996,28693,36007,36051,38971,25935,29942,19981,20184,22496,22827,23142,23500,\n20904,24067,24220,24598,25206,25975,26023,26222,28014,29238,31526,33104,33178,\n33433,35676,36000,36070,36212,38428,38468,20398,25771,\n27494,33310,33889,34154,37096,23553,26963,39080,33914,34135,20239,21103,24489,\n24133,26381,31119,33145,35079,35206,28149,24343,25173,27832,20175,29289,39826,\n20998,21563,22132,22707,24996,25198,28954,22894,31881,31966,32027,38640,25991,\n32862,19993,20341,20853,22592,24163,24179,24330,26564,20006,34109,38281,38491,\n31859,38913,20731,22721,30294,30887,21029,30629,34065,31622,20559,22793,29255,\n31687,32232,36794,36820,36941,20415,21193,23081,24321,38829,20445,33303,37610,\n22275,25429,27497,29995,35036,36628,31298,21215,22675,24917,25098,26286,27597,\n31807,33769,20515,20472,21253,21574,22577,22857,23453,23792,23791,23849,24214,\n25265,25447,25918,26041,26379,27861,27873,28921,30770,32299,32990,33459,33804,\n34028,34562,35090,35370,35914,37030,37586,39165,40179,40300,20047,20129,20621,\n21078,22346,22952,24125,24536,24537,25151,26292,26395,26576,26834,20882,32033,\n32938,33192,35584,35980,36031,37502,38450,21536,38956,21271,20693,21340,22696,\n25778,26420,29287,30566,31302,37350,21187,27809,27526,22528,24140,22868,26412,\n32763,20961,30406,25705,30952,39764,40635,22475,22969,26151,26522,27598,21737,\n27097,24149,33180,26517,39850,26622,40018,26717,20134,20451,21448,25273,26411,\n27819,36804,20397,32365,40639,19975,24930,28288,28459,34067,21619,26410,39749,\n24051,31637,23724,23494,34588,28234,34001,31252,33032,22937,31885,27665,30496,\n21209,22818,28961,29279,30683,38695,40289,26891,23167,23064,20901,21517,21629,\n26126,30431,36855,37528,40180,23018,29277,28357,20813,26825,32191,32236,38754,\n40634,25720,27169,33538,22916,23391,27611,29467,30450,\n32178,32791,33945,20786,26408,40665,30446,26466,21247,39173,23588,25147,31870,\n36016,21839,24758,32011,38272,21249,20063,20918,22812,29242,32822,37326,24357,\n30690,21380,24441,32004,34220,35379,36493,38742,26611,34222,37971,24841,24840,\n27833,30290,35565,36664,21807,20305,20778,21191,21451,23461,24189,24736,24962,\n25558,26377,26586,28263,28044,29494,29495,30001,31056,35029,35480,36938,37009,\n37109,38596,34701,22805,20104,20313,19982,35465,36671,38928,20653,24188,22934,\n23481,24248,25562,25594,25793,26332,26954,27096,27915,28342,29076,29992,31407,\n32650,32768,33865,33993,35201,35617,36362,36965,38525,39178,24958,25233,27442,\n27779,28020,32716,32764,28096,32645,34746,35064,26469,33713,38972,38647,27931,\n32097,33853,37226,20081,21365,23888,27396,28651,34253,34349,35239,21033,21519,\n23653,26446,26792,29702,29827,30178,35023,35041,37324,38626,38520,24459,29575,\n31435,33870,25504,30053,21129,27969,28316,29705,30041,30827,31890,38534,31452,\n40845,20406,24942,26053,34396,20102,20142,20698,20001,20940,23534,26009,26753,\n28092,29471,30274,30637,31260,31975,33391,35538,36988,37327,38517,38936,21147,\n32209,20523,21400,26519,28107,29136,29747,33256,36650,38563,40023,40607,29792,\n22593,28057,32047,39006,20196,20278,20363,20919,21169,23994,24604,29618,31036,\n33491,37428,38583,38646,38666,40599,40802,26278,27508,21015,21155,28872,35010,\n24265,24651,24976,28451,29001,31806,32244,32879,34030,36899,37676,21570,39791,\n27347,28809,36034,36335,38706,21172,23105,24266,24324,26391,27004,27028,28010,\n28431,29282,29436,31725,32769,32894,34635,37070,20845,\n40595,31108,32907,37682,35542,20525,21644,35441,27498,36036,33031,24785,26528,\n40434,20121,20120,39952,35435,34241,34152,26880,28286,30871,33109,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n24332,19984,19989,20010,20017,20022,20028,20031,20034,20054,20056,20098,20101,\n35947,20106,33298,24333,20110,20126,20127,20128,20130,20144,20147,20150,20174,\n20173,20164,20166,20162,20183,20190,20205,20191,20215,20233,20314,20272,20315,\n20317,20311,20295,20342,20360,20367,20376,20347,20329,20336,20369,20335,20358,\n20374,20760,20436,20447,20430,20440,20443,20433,20442,20432,20452,20453,20506,\n20520,20500,20522,20517,20485,20252,20470,20513,20521,20524,20478,20463,20497,\n20486,20547,20551,26371,20565,20560,20552,20570,20566,20588,20600,20608,20634,\n20613,20660,20658,20681,20682,20659,20674,20694,20702,20709,20717,20707,20718,\n20729,20725,20745,20737,20738,20758,20757,20756,20762,20769,20794,20791,20796,\n20795,20799,20800,20818,20812,20820,20834,31480,20841,20842,20846,20864,20866,\n22232,20876,20873,20879,20881,20883,20885,20886,20900,20902,20898,20905,20906,\n20907,20915,20913,20914,20912,20917,20925,20933,20937,20955,20960,34389,20969,\n20973,20976,20981,20990,20996,21003,21012,21006,21031,21034,21038,21043,21049,\n21071,21060,21067,21068,21086,21076,21098,21108,21097,21107,21119,21117,21133,\n21140,21138,21105,21128,21137,36776,36775,\n21164,21165,21180,21173,21185,21197,21207,21214,21219,21222,39149,21216,21235,\n21237,21240,21241,21254,21256,30008,21261,21264,21263,21269,21274,21283,21295,\n21297,21299,21304,21312,21318,21317,19991,21321,21325,20950,21342,21353,21358,\n22808,21371,21367,21378,21398,21408,21414,21413,21422,21424,21430,21443,31762,\n38617,21471,26364,29166,21486,21480,21485,21498,21505,21565,21568,21548,21549,\n21564,21550,21558,21545,21533,21582,21647,21621,21646,21599,21617,21623,21616,\n21650,21627,21632,21622,21636,21648,21638,21703,21666,21688,21669,21676,21700,\n21704,21672,21675,21698,21668,21694,21692,21720,21733,21734,21775,21780,21757,\n21742,21741,21754,21730,21817,21824,21859,21836,21806,21852,21829,21846,21847,\n21816,21811,21853,21913,21888,21679,21898,21919,21883,21886,21912,21918,21934,\n21884,21891,21929,21895,21928,21978,21957,21983,21956,21980,21988,21972,22036,\n22007,22038,22014,22013,22043,22009,22094,22096,29151,22068,22070,22066,22072,\n22123,22116,22063,22124,22122,22150,22144,22154,22176,22164,22159,22181,22190,\n22198,22196,22210,22204,22209,22211,22208,22216,22222,22225,22227,22231,22254,\n22265,22272,22271,22276,22281,22280,22283,22285,22291,22296,22294,21959,22300,\n22310,22327,22328,22350,22331,22336,22351,22377,22464,22408,22369,22399,22409,\n22419,22432,22451,22436,22442,22448,22467,22470,22484,22482,22483,22538,22486,\n22499,22539,22553,22557,22642,22561,22626,22603,22640,27584,22610,22589,22649,\n22661,22713,22687,22699,22714,22750,22715,22712,22702,22725,22739,22737,22743,\n22745,22744,22757,22748,22756,22751,22767,22778,22777,\n22779,22780,22781,22786,22794,22800,22811,26790,22821,22828,22829,22834,22840,\n22846,31442,22869,22864,22862,22874,22872,22882,22880,22887,22892,22889,22904,\n22913,22941,20318,20395,22947,22962,22982,23016,23004,22925,23001,23002,23077,\n23071,23057,23068,23049,23066,23104,23148,23113,23093,23094,23138,23146,23194,\n23228,23230,23243,23234,23229,23267,23255,23270,23273,23254,23290,23291,23308,\n23307,23318,23346,23248,23338,23350,23358,23363,23365,23360,23377,23381,23386,\n23387,23397,23401,23408,23411,23413,23416,25992,23418,23424,23427,23462,23480,\n23491,23495,23497,23508,23504,23524,23526,23522,23518,23525,23531,23536,23542,\n23539,23557,23559,23560,23565,23571,23584,23586,23592,23608,23609,23617,23622,\n23630,23635,23632,23631,23409,23660,23662,20066,23670,23673,23692,23697,23700,\n22939,23723,23739,23734,23740,23735,23749,23742,23751,23769,23785,23805,23802,\n23789,23948,23786,23819,23829,23831,23900,23839,23835,23825,23828,23842,23834,\n23833,23832,23884,23890,23886,23883,23916,23923,23926,23943,23940,23938,23970,\n23965,23980,23982,23997,23952,23991,23996,24009,24013,24019,24018,24022,24027,\n24043,24050,24053,24075,24090,24089,24081,24091,24118,24119,24132,24131,24128,\n24142,24151,24148,24159,24162,24164,24135,24181,24182,24186,40636,24191,24224,\n24257,24258,24264,24272,24271,24278,24291,24285,24282,24283,24290,24289,24296,\n24297,24300,24305,24307,24304,24308,24312,24318,24323,24329,24413,24412,24331,\n24337,24342,24361,24365,24376,24385,24392,24396,24398,24367,24401,24406,24407,\n24409,24417,24429,24435,24439,24451,24450,24447,24458,\n24456,24465,24455,24478,24473,24472,24480,24488,24493,24508,24534,24571,24548,\n24568,24561,24541,24755,24575,24609,24672,24601,24592,24617,24590,24625,24603,\n24597,24619,24614,24591,24634,24666,24641,24682,24695,24671,24650,24646,24653,\n24675,24643,24676,24642,24684,24683,24665,24705,24717,24807,24707,24730,24708,\n24731,24726,24727,24722,24743,24715,24801,24760,24800,24787,24756,24560,24765,\n24774,24757,24792,24909,24853,24838,24822,24823,24832,24820,24826,24835,24865,\n24827,24817,24845,24846,24903,24894,24872,24871,24906,24895,24892,24876,24884,\n24893,24898,24900,24947,24951,24920,24921,24922,24939,24948,24943,24933,24945,\n24927,24925,24915,24949,24985,24982,24967,25004,24980,24986,24970,24977,25003,\n25006,25036,25034,25033,25079,25032,25027,25030,25018,25035,32633,25037,25062,\n25059,25078,25082,25076,25087,25085,25084,25086,25088,25096,25097,25101,25100,\n25108,25115,25118,25121,25130,25134,25136,25138,25139,25153,25166,25182,25187,\n25179,25184,25192,25212,25218,25225,25214,25234,25235,25238,25300,25219,25236,\n25303,25297,25275,25295,25343,25286,25812,25288,25308,25292,25290,25282,25287,\n25243,25289,25356,25326,25329,25383,25346,25352,25327,25333,25424,25406,25421,\n25628,25423,25494,25486,25472,25515,25462,25507,25487,25481,25503,25525,25451,\n25449,25534,25577,25536,25542,25571,25545,25554,25590,25540,25622,25652,25606,\n25619,25638,25654,25885,25623,25640,25615,25703,25711,25718,25678,25898,25749,\n25747,25765,25769,25736,25788,25818,25810,25797,25799,25787,25816,25794,25841,\n25831,33289,25824,25825,25260,25827,25839,25900,25846,\n25844,25842,25850,25856,25853,25880,25884,25861,25892,25891,25899,25908,25909,\n25911,25910,25912,30027,25928,25942,25941,25933,25944,25950,25949,25970,25976,\n25986,25987,35722,26011,26015,26027,26039,26051,26054,26049,26052,26060,26066,\n26075,26073,26080,26081,26097,26482,26122,26115,26107,26483,26165,26166,26164,\n26140,26191,26180,26185,26177,26206,26205,26212,26215,26216,26207,26210,26224,\n26243,26248,26254,26249,26244,26264,26269,26305,26297,26313,26302,26300,26308,\n26296,26326,26330,26336,26175,26342,26345,26352,26357,26359,26383,26390,26398,\n26406,26407,38712,26414,26431,26422,26433,26424,26423,26438,26462,26464,26457,\n26467,26468,26505,26480,26537,26492,26474,26508,26507,26534,26529,26501,26551,\n26607,26548,26604,26547,26601,26552,26596,26590,26589,26594,26606,26553,26574,\n26566,26599,27292,26654,26694,26665,26688,26701,26674,26702,26803,26667,26713,\n26723,26743,26751,26783,26767,26797,26772,26781,26779,26755,27310,26809,26740,\n26805,26784,26810,26895,26765,26750,26881,26826,26888,26840,26914,26918,26849,\n26892,26829,26836,26855,26837,26934,26898,26884,26839,26851,26917,26873,26848,\n26863,26920,26922,26906,26915,26913,26822,27001,26999,26972,27000,26987,26964,\n27006,26990,26937,26996,26941,26969,26928,26977,26974,26973,27009,26986,27058,\n27054,27088,27071,27073,27091,27070,27086,23528,27082,27101,27067,27075,27047,\n27182,27025,27040,27036,27029,27060,27102,27112,27138,27163,27135,27402,27129,\n27122,27111,27141,27057,27166,27117,27156,27115,27146,27154,27329,27171,27155,\n27204,27148,27250,27190,27256,27207,27234,27225,27238,\n27208,27192,27170,27280,27277,27296,27268,27298,27299,27287,34327,27323,27331,\n27330,27320,27315,27308,27358,27345,27359,27306,27354,27370,27387,27397,34326,\n27386,27410,27414,39729,27423,27448,27447,30428,27449,39150,27463,27459,27465,\n27472,27481,27476,27483,27487,27489,27512,27513,27519,27520,27524,27523,27533,\n27544,27541,27550,27556,27562,27563,27567,27570,27569,27571,27575,27580,27590,\n27595,27603,27615,27628,27627,27635,27631,40638,27656,27667,27668,27675,27684,\n27683,27742,27733,27746,27754,27778,27789,27802,27777,27803,27774,27752,27763,\n27794,27792,27844,27889,27859,27837,27863,27845,27869,27822,27825,27838,27834,\n27867,27887,27865,27882,27935,34893,27958,27947,27965,27960,27929,27957,27955,\n27922,27916,28003,28051,28004,27994,28025,27993,28046,28053,28644,28037,28153,\n28181,28170,28085,28103,28134,28088,28102,28140,28126,28108,28136,28114,28101,\n28154,28121,28132,28117,28138,28142,28205,28270,28206,28185,28274,28255,28222,\n28195,28267,28203,28278,28237,28191,28227,28218,28238,28196,28415,28189,28216,\n28290,28330,28312,28361,28343,28371,28349,28335,28356,28338,28372,28373,28303,\n28325,28354,28319,28481,28433,28748,28396,28408,28414,28479,28402,28465,28399,\n28466,28364,28478,28435,28407,28550,28538,28536,28545,28544,28527,28507,28659,\n28525,28546,28540,28504,28558,28561,28610,28518,28595,28579,28577,28580,28601,\n28614,28586,28639,28629,28652,28628,28632,28657,28654,28635,28681,28683,28666,\n28689,28673,28687,28670,28699,28698,28532,28701,28696,28703,28720,28734,28722,\n28753,28771,28825,28818,28847,28913,28844,28856,28851,\n28846,28895,28875,28893,28889,28937,28925,28956,28953,29029,29013,29064,29030,\n29026,29004,29014,29036,29071,29179,29060,29077,29096,29100,29143,29113,29118,\n29138,29129,29140,29134,29152,29164,29159,29173,29180,29177,29183,29197,29200,\n29211,29224,29229,29228,29232,29234,29243,29244,29247,29248,29254,29259,29272,\n29300,29310,29314,29313,29319,29330,29334,29346,29351,29369,29362,29379,29382,\n29380,29390,29394,29410,29408,29409,29433,29431,20495,29463,29450,29468,29462,\n29469,29492,29487,29481,29477,29502,29518,29519,40664,29527,29546,29544,29552,\n29560,29557,29563,29562,29640,29619,29646,29627,29632,29669,29678,29662,29858,\n29701,29807,29733,29688,29746,29754,29781,29759,29791,29785,29761,29788,29801,\n29808,29795,29802,29814,29822,29835,29854,29863,29898,29903,29908,29681,29920,\n29923,29927,29929,29934,29938,29936,29937,29944,29943,29956,29955,29957,29964,\n29966,29965,29973,29971,29982,29990,29996,30012,30020,30029,30026,30025,30043,\n30022,30042,30057,30052,30055,30059,30061,30072,30070,30086,30087,30068,30090,\n30089,30082,30100,30106,30109,30117,30115,30146,30131,30147,30133,30141,30136,\n30140,30129,30157,30154,30162,30169,30179,30174,30206,30207,30204,30209,30192,\n30202,30194,30195,30219,30221,30217,30239,30247,30240,30241,30242,30244,30260,\n30256,30267,30279,30280,30278,30300,30296,30305,30306,30312,30313,30314,30311,\n30316,30320,30322,30326,30328,30332,30336,30339,30344,30347,30350,30358,30355,\n30361,30362,30384,30388,30392,30393,30394,30402,30413,30422,30418,30430,30433,\n30437,30439,30442,34351,30459,30472,30471,30468,30505,\n30500,30494,30501,30502,30491,30519,30520,30535,30554,30568,30571,30555,30565,\n30591,30590,30585,30606,30603,30609,30624,30622,30640,30646,30649,30655,30652,\n30653,30651,30663,30669,30679,30682,30684,30691,30702,30716,30732,30738,31014,\n30752,31018,30789,30862,30836,30854,30844,30874,30860,30883,30901,30890,30895,\n30929,30918,30923,30932,30910,30908,30917,30922,30956,30951,30938,30973,30964,\n30983,30994,30993,31001,31020,31019,31040,31072,31063,31071,31066,31061,31059,\n31098,31103,31114,31133,31143,40779,31146,31150,31155,31161,31162,31177,31189,\n31207,31212,31201,31203,31240,31245,31256,31257,31264,31263,31104,31281,31291,\n31294,31287,31299,31319,31305,31329,31330,31337,40861,31344,31353,31357,31368,\n31383,31381,31384,31382,31401,31432,31408,31414,31429,31428,31423,36995,31431,\n31434,31437,31439,31445,31443,31449,31450,31453,31457,31458,31462,31469,31472,\n31490,31503,31498,31494,31539,31512,31513,31518,31541,31528,31542,31568,31610,\n31492,31565,31499,31564,31557,31605,31589,31604,31591,31600,31601,31596,31598,\n31645,31640,31647,31629,31644,31642,31627,31634,31631,31581,31641,31691,31681,\n31692,31695,31668,31686,31709,31721,31761,31764,31718,31717,31840,31744,31751,\n31763,31731,31735,31767,31757,31734,31779,31783,31786,31775,31799,31787,31805,\n31820,31811,31828,31823,31808,31824,31832,31839,31844,31830,31845,31852,31861,\n31875,31888,31908,31917,31906,31915,31905,31912,31923,31922,31921,31918,31929,\n31933,31936,31941,31938,31960,31954,31964,31970,39739,31983,31986,31988,31990,\n31994,32006,32002,32028,32021,32010,32069,32075,32046,\n32050,32063,32053,32070,32115,32086,32078,32114,32104,32110,32079,32099,32147,\n32137,32091,32143,32125,32155,32186,32174,32163,32181,32199,32189,32171,32317,\n32162,32175,32220,32184,32159,32176,32216,32221,32228,32222,32251,32242,32225,\n32261,32266,32291,32289,32274,32305,32287,32265,32267,32290,32326,32358,32315,\n32309,32313,32323,32311,32306,32314,32359,32349,32342,32350,32345,32346,32377,\n32362,32361,32380,32379,32387,32213,32381,36782,32383,32392,32393,32396,32402,\n32400,32403,32404,32406,32398,32411,32412,32568,32570,32581,32588,32589,32590,\n32592,32593,32597,32596,32600,32607,32608,32616,32617,32615,32632,32642,32646,\n32643,32648,32647,32652,32660,32670,32669,32666,32675,32687,32690,32697,32686,\n32694,32696,35697,32709,32710,32714,32725,32724,32737,32742,32745,32755,32761,\n39132,32774,32772,32779,32786,32792,32793,32796,32801,32808,32831,32827,32842,\n32838,32850,32856,32858,32863,32866,32872,32883,32882,32880,32886,32889,32893,\n32895,32900,32902,32901,32923,32915,32922,32941,20880,32940,32987,32997,32985,\n32989,32964,32986,32982,33033,33007,33009,33051,33065,33059,33071,33099,38539,\n33094,33086,33107,33105,33020,33137,33134,33125,33126,33140,33155,33160,33162,\n33152,33154,33184,33173,33188,33187,33119,33171,33193,33200,33205,33214,33208,\n33213,33216,33218,33210,33225,33229,33233,33241,33240,33224,33242,33247,33248,\n33255,33274,33275,33278,33281,33282,33285,33287,33290,33293,33296,33302,33321,\n33323,33336,33331,33344,33369,33368,33373,33370,33375,33380,33378,33384,33386,\n33387,33326,33393,33399,33400,33406,33421,33426,33451,\n33439,33467,33452,33505,33507,33503,33490,33524,33523,33530,33683,33539,33531,\n33529,33502,33542,33500,33545,33497,33589,33588,33558,33586,33585,33600,33593,\n33616,33605,33583,33579,33559,33560,33669,33690,33706,33695,33698,33686,33571,\n33678,33671,33674,33660,33717,33651,33653,33696,33673,33704,33780,33811,33771,\n33742,33789,33795,33752,33803,33729,33783,33799,33760,33778,33805,33826,33824,\n33725,33848,34054,33787,33901,33834,33852,34138,33924,33911,33899,33965,33902,\n33922,33897,33862,33836,33903,33913,33845,33994,33890,33977,33983,33951,34009,\n33997,33979,34010,34000,33985,33990,34006,33953,34081,34047,34036,34071,34072,\n34092,34079,34069,34068,34044,34112,34147,34136,34120,34113,34306,34123,34133,\n34176,34212,34184,34193,34186,34216,34157,34196,34203,34282,34183,34204,34167,\n34174,34192,34249,34234,34255,34233,34256,34261,34269,34277,34268,34297,34314,\n34323,34315,34302,34298,34310,34338,34330,34352,34367,34381,20053,34388,34399,\n34407,34417,34451,34467,34473,34474,34443,34444,34486,34479,34500,34502,34480,\n34505,34851,34475,34516,34526,34537,34540,34527,34523,34543,34578,34566,34568,\n34560,34563,34555,34577,34569,34573,34553,34570,34612,34623,34615,34619,34597,\n34601,34586,34656,34655,34680,34636,34638,34676,34647,34664,34670,34649,34643,\n34659,34666,34821,34722,34719,34690,34735,34763,34749,34752,34768,38614,34731,\n34756,34739,34759,34758,34747,34799,34802,34784,34831,34829,34814,34806,34807,\n34830,34770,34833,34838,34837,34850,34849,34865,34870,34873,34855,34875,34884,\n34882,34898,34905,34910,34914,34923,34945,34942,34974,\n34933,34941,34997,34930,34946,34967,34962,34990,34969,34978,34957,34980,34992,\n35007,34993,35011,35012,35028,35032,35033,35037,35065,35074,35068,35060,35048,\n35058,35076,35084,35082,35091,35139,35102,35109,35114,35115,35137,35140,35131,\n35126,35128,35148,35101,35168,35166,35174,35172,35181,35178,35183,35188,35191,\n35198,35203,35208,35210,35219,35224,35233,35241,35238,35244,35247,35250,35258,\n35261,35263,35264,35290,35292,35293,35303,35316,35320,35331,35350,35344,35340,\n35355,35357,35365,35382,35393,35419,35410,35398,35400,35452,35437,35436,35426,\n35461,35458,35460,35496,35489,35473,35493,35494,35482,35491,35524,35533,35522,\n35546,35563,35571,35559,35556,35569,35604,35552,35554,35575,35550,35547,35596,\n35591,35610,35553,35606,35600,35607,35616,35635,38827,35622,35627,35646,35624,\n35649,35660,35663,35662,35657,35670,35675,35674,35691,35679,35692,35695,35700,\n35709,35712,35724,35726,35730,35731,35734,35737,35738,35898,35905,35903,35912,\n35916,35918,35920,35925,35938,35948,35960,35962,35970,35977,35973,35978,35981,\n35982,35988,35964,35992,25117,36013,36010,36029,36018,36019,36014,36022,36040,\n36033,36068,36067,36058,36093,36090,36091,36100,36101,36106,36103,36111,36109,\n36112,40782,36115,36045,36116,36118,36199,36205,36209,36211,36225,36249,36290,\n36286,36282,36303,36314,36310,36300,36315,36299,36330,36331,36319,36323,36348,\n36360,36361,36351,36381,36382,36368,36383,36418,36405,36400,36404,36426,36423,\n36425,36428,36432,36424,36441,36452,36448,36394,36451,36437,36470,36466,36476,\n36481,36487,36485,36484,36491,36490,36499,36497,36500,\n36505,36522,36513,36524,36528,36550,36529,36542,36549,36552,36555,36571,36579,\n36604,36603,36587,36606,36618,36613,36629,36626,36633,36627,36636,36639,36635,\n36620,36646,36659,36667,36665,36677,36674,36670,36684,36681,36678,36686,36695,\n36700,36706,36707,36708,36764,36767,36771,36781,36783,36791,36826,36837,36834,\n36842,36847,36999,36852,36869,36857,36858,36881,36885,36897,36877,36894,36886,\n36875,36903,36918,36917,36921,36856,36943,36944,36945,36946,36878,36937,36926,\n36950,36952,36958,36968,36975,36982,38568,36978,36994,36989,36993,36992,37002,\n37001,37007,37032,37039,37041,37045,37090,37092,25160,37083,37122,37138,37145,\n37170,37168,37194,37206,37208,37219,37221,37225,37235,37234,37259,37257,37250,\n37282,37291,37295,37290,37301,37300,37306,37312,37313,37321,37323,37328,37334,\n37343,37345,37339,37372,37365,37366,37406,37375,37396,37420,37397,37393,37470,\n37463,37445,37449,37476,37448,37525,37439,37451,37456,37532,37526,37523,37531,\n37466,37583,37561,37559,37609,37647,37626,37700,37678,37657,37666,37658,37667,\n37690,37685,37691,37724,37728,37756,37742,37718,37808,37804,37805,37780,37817,\n37846,37847,37864,37861,37848,37827,37853,37840,37832,37860,37914,37908,37907,\n37891,37895,37904,37942,37931,37941,37921,37946,37953,37970,37956,37979,37984,\n37986,37982,37994,37417,38000,38005,38007,38013,37978,38012,38014,38017,38015,\n38274,38279,38282,38292,38294,38296,38297,38304,38312,38311,38317,38332,38331,\n38329,38334,38346,28662,38339,38349,38348,38357,38356,38358,38364,38369,38373,\n38370,38433,38440,38446,38447,38466,38476,38479,38475,\n38519,38492,38494,38493,38495,38502,38514,38508,38541,38552,38549,38551,38570,\n38567,38577,38578,38576,38580,38582,38584,38585,38606,38603,38601,38605,35149,\n38620,38669,38613,38649,38660,38662,38664,38675,38670,38673,38671,38678,38681,\n38692,38698,38704,38713,38717,38718,38724,38726,38728,38722,38729,38748,38752,\n38756,38758,38760,21202,38763,38769,38777,38789,38780,38785,38778,38790,38795,\n38799,38800,38812,38824,38822,38819,38835,38836,38851,38854,38856,38859,38876,\n38893,40783,38898,31455,38902,38901,38927,38924,38968,38948,38945,38967,38973,\n38982,38991,38987,39019,39023,39024,39025,39028,39027,39082,39087,39089,39094,\n39108,39107,39110,39145,39147,39171,39177,39186,39188,39192,39201,39197,39198,\n39204,39200,39212,39214,39229,39230,39234,39241,39237,39248,39243,39249,39250,\n39244,39253,39319,39320,39333,39341,39342,39356,39391,39387,39389,39384,39377,\n39405,39406,39409,39410,39419,39416,39425,39439,39429,39394,39449,39467,39479,\n39493,39490,39488,39491,39486,39509,39501,39515,39511,39519,39522,39525,39524,\n39529,39531,39530,39597,39600,39612,39616,39631,39633,39635,39636,39646,39647,\n39650,39651,39654,39663,39659,39662,39668,39665,39671,39675,39686,39704,39706,\n39711,39714,39715,39717,39719,39720,39721,39722,39726,39727,39730,39748,39747,\n39759,39757,39758,39761,39768,39796,39827,39811,39825,39830,39831,39839,39840,\n39848,39860,39872,39882,39865,39878,39887,39889,39890,39907,39906,39908,39892,\n39905,39994,39922,39921,39920,39957,39956,39945,39955,39948,39942,39944,39954,\n39946,39940,39982,39963,39973,39972,39969,39984,40007,\n39986,40006,39998,40026,40032,40039,40054,40056,40167,40172,40176,40201,40200,\n40171,40195,40198,40234,40230,40367,40227,40223,40260,40213,40210,40257,40255,\n40254,40262,40264,40285,40286,40292,40273,40272,40281,40306,40329,40327,40363,\n40303,40314,40346,40356,40361,40370,40388,40385,40379,40376,40378,40390,40399,\n40386,40409,40403,40440,40422,40429,40431,40445,40474,40475,40478,40565,40569,\n40573,40577,40584,40587,40588,40594,40597,40593,40605,40613,40617,40632,40618,\n40621,38753,40652,40654,40655,40656,40660,40668,40670,40669,40672,40677,40680,\n40687,40692,40694,40695,40697,40699,40700,40701,40711,40712,30391,40725,40737,\n40748,40766,40778,40786,40788,40803,40799,40800,40801,40806,40807,40812,40810,\n40823,40818,40822,40853,40860,40864,22575,27079,36953,29796,20956,29081,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,\n"
  },
  {
    "path": "user.libc/src/locale/ksc.h",
    "content": "12288,12289,12290,183,8229,8230,168,12291,173,8213,8741,65340,8764,8216,8217,\n8220,8221,12308,12309,12296,12297,12298,12299,12300,12301,12302,12303,12304,\n12305,177,215,247,8800,8804,8805,8734,8756,176,8242,8243,8451,8491,65504,\n65505,65509,9794,9792,8736,8869,8978,8706,8711,8801,8786,167,8251,9734,9733,\n9675,9679,9678,9671,9670,9633,9632,9651,9650,9661,9660,8594,8592,8593,8595,\n8596,12307,8810,8811,8730,8765,8733,8757,8747,8748,8712,8715,8838,8839,8834,\n8835,8746,8745,8743,8744,65506,8658,8660,8704,8707,180,65374,711,728,733,730,\n729,184,731,161,191,720,8750,8721,8719,164,8457,8240,9665,9664,9655,9654,9828,\n9824,9825,9829,9831,9827,8857,9672,9635,9680,9681,9618,9636,9637,9640,9639,\n9638,9641,9832,9743,9742,9756,9758,182,8224,8225,8597,8599,8601,8598,8600,\n9837,9833,9834,9836,12927,12828,8470,13255,8482,13250,13272,8481,8364,174,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65281,65282,65283,65284,65285,65286,\n65287,65288,65289,65290,65291,65292,65293,65294,65295,65296,65297,65298,65299,\n65300,65301,65302,65303,65304,65305,65306,65307,65308,65309,65310,65311,65312,\n65313,65314,65315,65316,65317,65318,65319,65320,65321,65322,65323,65324,65325,\n65326,65327,65328,65329,65330,65331,65332,65333,65334,65335,65336,65337,65338,\n65339,65510,65341,65342,65343,65344,65345,65346,65347,\n65348,65349,65350,65351,65352,65353,65354,65355,65356,65357,65358,65359,65360,\n65361,65362,65363,65364,65365,65366,65367,65368,65369,65370,65371,65372,65373,\n65507,12593,12594,12595,12596,12597,12598,12599,12600,12601,12602,12603,12604,\n12605,12606,12607,12608,12609,12610,12611,12612,12613,12614,12615,12616,12617,\n12618,12619,12620,12621,12622,12623,12624,12625,12626,12627,12628,12629,12630,\n12631,12632,12633,12634,12635,12636,12637,12638,12639,12640,12641,12642,12643,\n12644,12645,12646,12647,12648,12649,12650,12651,12652,12653,12654,12655,12656,\n12657,12658,12659,12660,12661,12662,12663,12664,12665,12666,12667,12668,12669,\n12670,12671,12672,12673,12674,12675,12676,12677,12678,12679,12680,12681,12682,\n12683,12684,12685,12686,8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,0,0,\n0,0,0,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,0,0,0,0,0,0,0,913,914,\n915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,\n935,936,937,0,0,0,0,0,0,0,0,945,946,947,948,949,950,951,952,953,954,955,956,\n957,958,959,960,961,963,964,965,966,967,968,969,0,0,0,0,0,0,9472,9474,9484,\n9488,9496,9492,9500,9516,9508,9524,9532,9473,9475,9487,9491,9499,9495,9507,\n9523,9515,9531,9547,9504,9519,9512,9527,9535,9501,9520,9509,9528,9538,9490,\n9489,9498,9497,9494,9493,9486,9485,9502,\n9503,9505,9506,9510,9511,9513,9514,9517,9518,9521,9522,9525,9526,9529,9530,\n9533,9534,9536,9537,9539,9540,9541,9542,9543,9544,9545,9546,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13205,13206,13207,8467,13208,13252,13219,\n13220,13221,13222,13209,13210,13211,13212,13213,13214,13215,13216,13217,13218,\n13258,13197,13198,13199,13263,13192,13193,13256,13223,13224,13232,13233,13234,\n13235,13236,13237,13238,13239,13240,13241,13184,13185,13186,13187,13188,13242,\n13243,13244,13245,13246,13247,13200,13201,13202,13203,13204,8486,13248,13249,\n13194,13195,13196,13270,13253,13229,13230,13231,13275,13225,13226,13227,13228,\n13277,13264,13267,13251,13257,13276,13254,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,198,\n208,170,294,0,306,0,319,321,216,338,186,222,358,330,0,12896,12897,12898,12899,\n12900,12901,12902,12903,12904,12905,12906,12907,12908,12909,12910,12911,12912,\n12913,12914,12915,12916,12917,12918,12919,12920,12921,12922,12923,9424,9425,\n9426,9427,9428,9429,9430,9431,9432,9433,9434,9435,9436,9437,9438,9439,9440,\n9441,9442,9443,9444,9445,9446,9447,9448,9449,9312,9313,9314,9315,9316,9317,\n9318,9319,9320,9321,9322,9323,9324,9325,9326,189,8531,8532,188,190,8539,8540,\n8541,8542,230,273,240,295,305,307,312,320,322,248,339,223,254,359,331,\n329,12800,12801,12802,12803,12804,12805,12806,12807,12808,12809,12810,12811,\n12812,12813,12814,12815,12816,12817,12818,12819,12820,12821,12822,12823,12824,\n12825,12826,12827,9372,9373,9374,9375,9376,9377,9378,9379,9380,9381,9382,9383,\n9384,9385,9386,9387,9388,9389,9390,9391,9392,9393,9394,9395,9396,9397,9332,\n9333,9334,9335,9336,9337,9338,9339,9340,9341,9342,9343,9344,9345,9346,185,178,\n179,8308,8319,8321,8322,8323,8324,12353,12354,12355,12356,12357,12358,12359,\n12360,12361,12362,12363,12364,12365,12366,12367,12368,12369,12370,12371,12372,\n12373,12374,12375,12376,12377,12378,12379,12380,12381,12382,12383,12384,12385,\n12386,12387,12388,12389,12390,12391,12392,12393,12394,12395,12396,12397,12398,\n12399,12400,12401,12402,12403,12404,12405,12406,12407,12408,12409,12410,12411,\n12412,12413,12414,12415,12416,12417,12418,12419,12420,12421,12422,12423,12424,\n12425,12426,12427,12428,12429,12430,12431,12432,12433,12434,12435,0,0,0,0,0,0,\n0,0,0,0,0,12449,12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,\n12460,12461,12462,12463,12464,12465,12466,12467,12468,12469,12470,12471,12472,\n12473,12474,12475,12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,\n12486,12487,12488,12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,\n12499,12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,\n12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,12523,12524,\n12525,12526,12527,12528,12529,12530,12531,\n12532,12533,12534,0,0,0,0,0,0,0,0,1040,1041,1042,1043,1044,1045,1025,1046,\n1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,\n1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,1082,1083,1084,1085,\n1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,\n1101,1102,1103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,44032,44033,44036,44039,44040,44041,44042,44048,\n44049,44050,44051,44052,44053,44054,44055,44057,44058,44059,44060,44061,44064,\n44068,44076,44077,44079,44080,44081,44088,44089,44092,44096,44107,44109,44116,\n44120,44124,44144,44145,44148,44151,44152,44154,44160,44161,44163,44164,44165,\n44166,44169,44170,44171,44172,44176,44180,44188,44189,44191,44192,44193,44200,\n44201,44202,44204,44207,44208,44216,44217,44219,44220,44221,44225,44228,44232,\n44236,44245,44247,44256,44257,44260,44263,44264,44266,44268,44271,44272,44273,\n44275,44277,44278,44284,44285,44288,44292,44294,44300,44301,44303,44305,44312,\n44316,44320,44329,44332,44333,44340,44341,44344,44348,44356,44357,44359,44361,\n44368,44372,44376,44385,44387,44396,44397,44400,44403,44404,44405,44406,44411,\n44412,44413,44415,44417,44418,44424,44425,44428,44432,44444,44445,44452,44471,\n44480,44481,44484,44488,44496,44497,44499,44508,44512,44516,44536,44537,44540,\n44543,44544,44545,44552,44553,44555,44557,44564,44592,44593,44596,44599,44600,\n44602,44608,44609,44611,44613,44614,44618,44620,44621,44622,44624,44628,44630,\n44636,44637,44639,44640,44641,44645,44648,44649,44652,44656,44664,44665,44667,\n44668,44669,44676,44677,44684,44732,44733,44734,44736,44740,44748,44749,44751,\n44752,44753,44760,44761,44764,44776,44779,44781,44788,44792,44796,44807,44808,\n44813,44816,44844,44845,44848,44850,44852,44860,44861,44863,44865,44866,44867,\n44872,44873,44880,44892,44893,44900,44901,44921,44928,44932,44936,44944,44945,\n44949,44956,44984,44985,44988,44992,44999,45000,45001,45003,45005,45006,45012,\n45020,45032,45033,45040,45041,45044,45048,45056,45057,45060,45068,45072,45076,\n45084,45085,45096,45124,45125,45128,45130,45132,45134,45139,45140,45141,45143,\n45145,45149,45180,45181,45184,45188,45196,45197,45199,45201,45208,45209,45210,\n45212,45215,45216,45217,45218,45224,45225,45227,45228,45229,45230,45231,45233,\n45235,45236,45237,45240,45244,45252,45253,45255,45256,45257,45264,45265,45268,\n45272,45280,45285,45320,45321,45323,45324,45328,45330,45331,45336,45337,45339,\n45340,45341,45347,45348,45349,45352,45356,45364,45365,45367,45368,45369,45376,\n45377,45380,45384,45392,45393,45396,45397,45400,45404,45408,45432,45433,45436,\n45440,45442,45448,45449,45451,45453,45458,45459,45460,45464,45468,45480,45516,\n45520,45524,45532,45533,45535,45544,45545,45548,45552,\n45561,45563,45565,45572,45573,45576,45579,45580,45588,45589,45591,45593,45600,\n45620,45628,45656,45660,45664,45672,45673,45684,45685,45692,45700,45701,45705,\n45712,45713,45716,45720,45721,45722,45728,45729,45731,45733,45734,45738,45740,\n45744,45748,45768,45769,45772,45776,45778,45784,45785,45787,45789,45794,45796,\n45797,45798,45800,45803,45804,45805,45806,45807,45811,45812,45813,45815,45816,\n45817,45818,45819,45823,45824,45825,45828,45832,45840,45841,45843,45844,45845,\n45852,45908,45909,45910,45912,45915,45916,45918,45919,45924,45925,45927,45929,\n45931,45934,45936,45937,45940,45944,45952,45953,45955,45956,45957,45964,45968,\n45972,45984,45985,45992,45996,46020,46021,46024,46027,46028,46030,46032,46036,\n46037,46039,46041,46043,46045,46048,46052,46056,46076,46096,46104,46108,46112,\n46120,46121,46123,46132,46160,46161,46164,46168,46176,46177,46179,46181,46188,\n46208,46216,46237,46244,46248,46252,46261,46263,46265,46272,46276,46280,46288,\n46293,46300,46301,46304,46307,46308,46310,46316,46317,46319,46321,46328,46356,\n46357,46360,46363,46364,46372,46373,46375,46376,46377,46378,46384,46385,46388,\n46392,46400,46401,46403,46404,46405,46411,46412,46413,46416,46420,46428,46429,\n46431,46432,46433,46496,46497,46500,46504,46506,46507,46512,46513,46515,46516,\n46517,46523,46524,46525,46528,46532,46540,46541,46543,46544,46545,46552,46572,\n46608,46609,46612,46616,46629,46636,46644,46664,46692,46696,46748,46749,46752,\n46756,46763,46764,46769,46804,46832,46836,46840,46848,46849,46853,46888,46889,\n46892,46895,46896,46904,46905,46907,46916,46920,46924,\n46932,46933,46944,46948,46952,46960,46961,46963,46965,46972,46973,46976,46980,\n46988,46989,46991,46992,46993,46994,46998,46999,47000,47001,47004,47008,47016,\n47017,47019,47020,47021,47028,47029,47032,47047,47049,47084,47085,47088,47092,\n47100,47101,47103,47104,47105,47111,47112,47113,47116,47120,47128,47129,47131,\n47133,47140,47141,47144,47148,47156,47157,47159,47160,47161,47168,47172,47185,\n47187,47196,47197,47200,47204,47212,47213,47215,47217,47224,47228,47245,47272,\n47280,47284,47288,47296,47297,47299,47301,47308,47312,47316,47325,47327,47329,\n47336,47337,47340,47344,47352,47353,47355,47357,47364,47384,47392,47420,47421,\n47424,47428,47436,47439,47441,47448,47449,47452,47456,47464,47465,47467,47469,\n47476,47477,47480,47484,47492,47493,47495,47497,47498,47501,47502,47532,47533,\n47536,47540,47548,47549,47551,47553,47560,47561,47564,47566,47567,47568,47569,\n47570,47576,47577,47579,47581,47582,47585,47587,47588,47589,47592,47596,47604,\n47605,47607,47608,47609,47610,47616,47617,47624,47637,47672,47673,47676,47680,\n47682,47688,47689,47691,47693,47694,47699,47700,47701,47704,47708,47716,47717,\n47719,47720,47721,47728,47729,47732,47736,47747,47748,47749,47751,47756,47784,\n47785,47787,47788,47792,47794,47800,47801,47803,47805,47812,47816,47832,47833,\n47868,47872,47876,47885,47887,47889,47896,47900,47904,47913,47915,47924,47925,\n47926,47928,47931,47932,47933,47934,47940,47941,47943,47945,47949,47951,47952,\n47956,47960,47969,47971,47980,48008,48012,48016,48036,48040,48044,48052,48055,\n48064,48068,48072,48080,48083,48120,48121,48124,48127,\n48128,48130,48136,48137,48139,48140,48141,48143,48145,48148,48149,48150,48151,\n48152,48155,48156,48157,48158,48159,48164,48165,48167,48169,48173,48176,48177,\n48180,48184,48192,48193,48195,48196,48197,48201,48204,48205,48208,48221,48260,\n48261,48264,48267,48268,48270,48276,48277,48279,48281,48282,48288,48289,48292,\n48295,48296,48304,48305,48307,48308,48309,48316,48317,48320,48324,48333,48335,\n48336,48337,48341,48344,48348,48372,48373,48374,48376,48380,48388,48389,48391,\n48393,48400,48404,48420,48428,48448,48456,48457,48460,48464,48472,48473,48484,\n48488,48512,48513,48516,48519,48520,48521,48522,48528,48529,48531,48533,48537,\n48538,48540,48548,48560,48568,48596,48597,48600,48604,48617,48624,48628,48632,\n48640,48643,48645,48652,48653,48656,48660,48668,48669,48671,48708,48709,48712,\n48716,48718,48724,48725,48727,48729,48730,48731,48736,48737,48740,48744,48746,\n48752,48753,48755,48756,48757,48763,48764,48765,48768,48772,48780,48781,48783,\n48784,48785,48792,48793,48808,48848,48849,48852,48855,48856,48864,48867,48868,\n48869,48876,48897,48904,48905,48920,48921,48923,48924,48925,48960,48961,48964,\n48968,48976,48977,48981,49044,49072,49093,49100,49101,49104,49108,49116,49119,\n49121,49212,49233,49240,49244,49248,49256,49257,49296,49297,49300,49304,49312,\n49313,49315,49317,49324,49325,49327,49328,49331,49332,49333,49334,49340,49341,\n49343,49344,49345,49349,49352,49353,49356,49360,49368,49369,49371,49372,49373,\n49380,49381,49384,49388,49396,49397,49399,49401,49408,49412,49416,49424,49429,\n49436,49437,49438,49439,49440,49443,49444,49446,49447,\n49452,49453,49455,49456,49457,49462,49464,49465,49468,49472,49480,49481,49483,\n49484,49485,49492,49493,49496,49500,49508,49509,49511,49512,49513,49520,49524,\n49528,49541,49548,49549,49550,49552,49556,49558,49564,49565,49567,49569,49573,\n49576,49577,49580,49584,49597,49604,49608,49612,49620,49623,49624,49632,49636,\n49640,49648,49649,49651,49660,49661,49664,49668,49676,49677,49679,49681,49688,\n49689,49692,49695,49696,49704,49705,49707,49709,49711,49713,49714,49716,49736,\n49744,49745,49748,49752,49760,49765,49772,49773,49776,49780,49788,49789,49791,\n49793,49800,49801,49808,49816,49819,49821,49828,49829,49832,49836,49837,49844,\n49845,49847,49849,49884,49885,49888,49891,49892,49899,49900,49901,49903,49905,\n49910,49912,49913,49915,49916,49920,49928,49929,49932,49933,49939,49940,49941,\n49944,49948,49956,49957,49960,49961,49989,50024,50025,50028,50032,50034,50040,\n50041,50044,50045,50052,50056,50060,50112,50136,50137,50140,50143,50144,50146,\n50152,50153,50157,50164,50165,50168,50184,50192,50212,50220,50224,50228,50236,\n50237,50248,50276,50277,50280,50284,50292,50293,50297,50304,50324,50332,50360,\n50364,50409,50416,50417,50420,50424,50426,50431,50432,50433,50444,50448,50452,\n50460,50472,50473,50476,50480,50488,50489,50491,50493,50500,50501,50504,50505,\n50506,50508,50509,50510,50515,50516,50517,50519,50520,50521,50525,50526,50528,\n50529,50532,50536,50544,50545,50547,50548,50549,50556,50557,50560,50564,50567,\n50572,50573,50575,50577,50581,50583,50584,50588,50592,50601,50612,50613,50616,\n50617,50619,50620,50621,50622,50628,50629,50630,50631,\n50632,50633,50634,50636,50638,50640,50641,50644,50648,50656,50657,50659,50661,\n50668,50669,50670,50672,50676,50678,50679,50684,50685,50686,50687,50688,50689,\n50693,50694,50695,50696,50700,50704,50712,50713,50715,50716,50724,50725,50728,\n50732,50733,50734,50736,50739,50740,50741,50743,50745,50747,50752,50753,50756,\n50760,50768,50769,50771,50772,50773,50780,50781,50784,50796,50799,50801,50808,\n50809,50812,50816,50824,50825,50827,50829,50836,50837,50840,50844,50852,50853,\n50855,50857,50864,50865,50868,50872,50873,50874,50880,50881,50883,50885,50892,\n50893,50896,50900,50908,50909,50912,50913,50920,50921,50924,50928,50936,50937,\n50941,50948,50949,50952,50956,50964,50965,50967,50969,50976,50977,50980,50984,\n50992,50993,50995,50997,50999,51004,51005,51008,51012,51018,51020,51021,51023,\n51025,51026,51027,51028,51029,51030,51031,51032,51036,51040,51048,51051,51060,\n51061,51064,51068,51069,51070,51075,51076,51077,51079,51080,51081,51082,51086,\n51088,51089,51092,51094,51095,51096,51098,51104,51105,51107,51108,51109,51110,\n51116,51117,51120,51124,51132,51133,51135,51136,51137,51144,51145,51148,51150,\n51152,51160,51165,51172,51176,51180,51200,51201,51204,51208,51210,51216,51217,\n51219,51221,51222,51228,51229,51232,51236,51244,51245,51247,51249,51256,51260,\n51264,51272,51273,51276,51277,51284,51312,51313,51316,51320,51322,51328,51329,\n51331,51333,51334,51335,51339,51340,51341,51348,51357,51359,51361,51368,51388,\n51389,51396,51400,51404,51412,51413,51415,51417,51424,51425,51428,51445,51452,\n51453,51456,51460,51461,51462,51468,51469,51471,51473,\n51480,51500,51508,51536,51537,51540,51544,51552,51553,51555,51564,51568,51572,\n51580,51592,51593,51596,51600,51608,51609,51611,51613,51648,51649,51652,51655,\n51656,51658,51664,51665,51667,51669,51670,51673,51674,51676,51677,51680,51682,\n51684,51687,51692,51693,51695,51696,51697,51704,51705,51708,51712,51720,51721,\n51723,51724,51725,51732,51736,51753,51788,51789,51792,51796,51804,51805,51807,\n51808,51809,51816,51837,51844,51864,51900,51901,51904,51908,51916,51917,51919,\n51921,51923,51928,51929,51936,51948,51956,51976,51984,51988,51992,52000,52001,\n52033,52040,52041,52044,52048,52056,52057,52061,52068,52088,52089,52124,52152,\n52180,52196,52199,52201,52236,52237,52240,52244,52252,52253,52257,52258,52263,\n52264,52265,52268,52270,52272,52280,52281,52283,52284,52285,52286,52292,52293,\n52296,52300,52308,52309,52311,52312,52313,52320,52324,52326,52328,52336,52341,\n52376,52377,52380,52384,52392,52393,52395,52396,52397,52404,52405,52408,52412,\n52420,52421,52423,52425,52432,52436,52452,52460,52464,52481,52488,52489,52492,\n52496,52504,52505,52507,52509,52516,52520,52524,52537,52572,52576,52580,52588,\n52589,52591,52593,52600,52616,52628,52629,52632,52636,52644,52645,52647,52649,\n52656,52676,52684,52688,52712,52716,52720,52728,52729,52731,52733,52740,52744,\n52748,52756,52761,52768,52769,52772,52776,52784,52785,52787,52789,52824,52825,\n52828,52831,52832,52833,52840,52841,52843,52845,52852,52853,52856,52860,52868,\n52869,52871,52873,52880,52881,52884,52888,52896,52897,52899,52900,52901,52908,\n52909,52929,52964,52965,52968,52971,52972,52980,52981,\n52983,52984,52985,52992,52993,52996,53000,53008,53009,53011,53013,53020,53024,\n53028,53036,53037,53039,53040,53041,53048,53076,53077,53080,53084,53092,53093,\n53095,53097,53104,53105,53108,53112,53120,53125,53132,53153,53160,53168,53188,\n53216,53217,53220,53224,53232,53233,53235,53237,53244,53248,53252,53265,53272,\n53293,53300,53301,53304,53308,53316,53317,53319,53321,53328,53332,53336,53344,\n53356,53357,53360,53364,53372,53373,53377,53412,53413,53416,53420,53428,53429,\n53431,53433,53440,53441,53444,53448,53449,53456,53457,53459,53460,53461,53468,\n53469,53472,53476,53484,53485,53487,53488,53489,53496,53517,53552,53553,53556,\n53560,53562,53568,53569,53571,53572,53573,53580,53581,53584,53588,53596,53597,\n53599,53601,53608,53612,53628,53636,53640,53664,53665,53668,53672,53680,53681,\n53683,53685,53690,53692,53696,53720,53748,53752,53767,53769,53776,53804,53805,\n53808,53812,53820,53821,53823,53825,53832,53852,53860,53888,53889,53892,53896,\n53904,53905,53909,53916,53920,53924,53932,53937,53944,53945,53948,53951,53952,\n53954,53960,53961,53963,53972,53976,53980,53988,53989,54000,54001,54004,54008,\n54016,54017,54019,54021,54028,54029,54030,54032,54036,54038,54044,54045,54047,\n54048,54049,54053,54056,54057,54060,54064,54072,54073,54075,54076,54077,54084,\n54085,54140,54141,54144,54148,54156,54157,54159,54160,54161,54168,54169,54172,\n54176,54184,54185,54187,54189,54196,54200,54204,54212,54213,54216,54217,54224,\n54232,54241,54243,54252,54253,54256,54260,54268,54269,54271,54273,54280,54301,\n54336,54340,54364,54368,54372,54381,54383,54392,54393,\n54396,54399,54400,54402,54408,54409,54411,54413,54420,54441,54476,54480,54484,\n54492,54495,54504,54508,54512,54520,54523,54525,54532,54536,54540,54548,54549,\n54551,54588,54589,54592,54596,54604,54605,54607,54609,54616,54617,54620,54624,\n54629,54632,54633,54635,54637,54644,54645,54648,54652,54660,54661,54663,54664,\n54665,54672,54693,54728,54729,54732,54736,54738,54744,54745,54747,54749,54756,\n54757,54760,54764,54772,54773,54775,54777,54784,54785,54788,54792,54800,54801,\n54803,54804,54805,54812,54816,54820,54829,54840,54841,54844,54848,54853,54856,\n54857,54859,54861,54865,54868,54869,54872,54876,54887,54889,54896,54897,54900,\n54915,54917,54924,54925,54928,54932,54941,54943,54945,54952,54956,54960,54969,\n54971,54980,54981,54984,54988,54993,54996,54999,55001,55008,55012,55016,55024,\n55029,55036,55037,55040,55044,55057,55064,55065,55068,55072,55080,55081,55083,\n55085,55092,55093,55096,55100,55108,55111,55113,55120,55121,55124,55126,55127,\n55128,55129,55136,55137,55139,55141,55145,55148,55152,55156,55164,55165,55169,\n55176,55177,55180,55184,55192,55193,55195,55197,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20285,20339,20551,20729,21152,21487,21621,21733,\n22025,23233,23478,26247,26550,26551,26607,27468,29634,30146,31292,33499,33540,\n34903,34952,35382,36040,36303,36603,36838,39381,21051,21364,21508,24682,24932,\n27580,29647,33050,35258,35282,38307,20355,21002,22718,22904,23014,24178,24185,\n25031,25536,26438,26604,26751,28567,30286,30475,30965,31240,31487,31777,32925,\n33390,33393,35563,38291,20075,21917,26359,28212,30883,31469,33883,35088,34638,\n38824,21208,22350,22570,23884,24863,25022,25121,25954,26577,27204,28187,29976,\n30131,30435,30640,32058,37039,37969,37970,40853,21283,23724,30002,32987,37440,\n38296,21083,22536,23004,23713,23831,24247,24378,24394,24951,27743,30074,30086,\n31968,32115,32177,32652,33108,33313,34193,35137,35611,37628,38477,40007,20171,\n20215,20491,20977,22607,24887,24894,24936,25913,27114,28433,30117,30342,30422,\n31623,33445,33995,63744,37799,38283,21888,23458,22353,63745,31923,32697,37301,\n20520,21435,23621,24040,25298,25454,25818,25831,28192,28844,31067,36317,36382,\n63746,36989,37445,37624,20094,20214,20581,24062,24314,24838,26967,33137,34388,\n36423,37749,39467,20062,20625,26480,26688,20745,21133,21138,27298,30652,37392,\n40660,21163,24623,36850,20552,25001,25581,25802,26684,27268,28608,33160,35233,\n38548,22533,29309,29356,29956,32121,32365,32937,35211,35700,36963,40273,25225,\n27770,28500,32080,32570,35363,20860,24906,31645,35609,37463,37772,20140,20435,\n20510,20670,20742,21185,21197,21375,22384,22659,24218,24465,24950,25004,\n25806,25964,26223,26299,26356,26775,28039,28805,28913,29855,29861,29898,30169,\n30828,30956,31455,31478,32069,32147,32789,32831,33051,33686,35686,36629,36885,\n37857,38915,38968,39514,39912,20418,21843,22586,22865,23395,23622,24760,25106,\n26690,26800,26856,28330,30028,30328,30926,31293,31995,32363,32380,35336,35489,\n35903,38542,40388,21476,21481,21578,21617,22266,22993,23396,23611,24235,25335,\n25911,25925,25970,26272,26543,27073,27837,30204,30352,30590,31295,32660,32771,\n32929,33167,33510,33533,33776,34241,34865,34996,35493,63747,36764,37678,38599,\n39015,39640,40723,21741,26011,26354,26767,31296,35895,40288,22256,22372,23825,\n26118,26801,26829,28414,29736,34974,39908,27752,63748,39592,20379,20844,20849,\n21151,23380,24037,24656,24685,25329,25511,25915,29657,31354,34467,36002,38799,\n20018,23521,25096,26524,29916,31185,33747,35463,35506,36328,36942,37707,38982,\n24275,27112,34303,37101,63749,20896,23448,23532,24931,26874,27454,28748,29743,\n29912,31649,32592,33733,35264,36011,38364,39208,21038,24669,25324,36866,20362,\n20809,21281,22745,24291,26336,27960,28826,29378,29654,31568,33009,37979,21350,\n25499,32619,20054,20608,22602,22750,24618,24871,25296,27088,39745,23439,32024,\n32945,36703,20132,20689,21676,21932,23308,23968,24039,25898,25934,26657,27211,\n29409,30350,30703,32094,32761,33184,34126,34527,36611,36686,37066,39171,39509,\n39851,19992,20037,20061,20167,20465,20855,21246,21312,21475,21477,21646,22036,\n22389,22434,23495,23943,24272,25084,25304,25937,26552,26601,27083,27472,27590,\n27628,27714,28317,28792,29399,29590,29699,30655,30697,\n31350,32127,32777,33276,33285,33290,33503,34914,35635,36092,36544,36881,37041,\n37476,37558,39378,39493,40169,40407,40860,22283,23616,33738,38816,38827,40628,\n21531,31384,32676,35033,36557,37089,22528,23624,25496,31391,23470,24339,31353,\n31406,33422,36524,20518,21048,21240,21367,22280,25331,25458,27402,28099,30519,\n21413,29527,34152,36470,38357,26426,27331,28528,35437,36556,39243,63750,26231,\n27512,36020,39740,63751,21483,22317,22862,25542,27131,29674,30789,31418,31429,\n31998,33909,35215,36211,36917,38312,21243,22343,30023,31584,33740,37406,63752,\n27224,20811,21067,21127,25119,26840,26997,38553,20677,21156,21220,25027,26020,\n26681,27135,29822,31563,33465,33771,35250,35641,36817,39241,63753,20170,22935,\n25810,26129,27278,29748,31105,31165,33449,34942,34943,35167,63754,37670,20235,\n21450,24613,25201,27762,32026,32102,20120,20834,30684,32943,20225,20238,20854,\n20864,21980,22120,22331,22522,22524,22804,22855,22931,23492,23696,23822,24049,\n24190,24524,25216,26071,26083,26398,26399,26462,26827,26820,27231,27450,27683,\n27773,27778,28103,29592,29734,29738,29826,29859,30072,30079,30849,30959,31041,\n31047,31048,31098,31637,32000,32186,32648,32774,32813,32908,35352,35663,35912,\n36215,37665,37668,39138,39249,39438,39439,39525,40594,32202,20342,21513,25326,\n26708,37329,21931,20794,63755,63756,23068,25062,63757,25295,25343,63758,63759,\n63760,63761,63762,63763,37027,63764,63765,63766,63767,63768,35582,63769,63770,\n63771,63772,26262,63773,29014,63774,63775,38627,63776,25423,25466,21335,63777,\n26511,26976,28275,63778,30007,63779,63780,63781,32013,\n63782,63783,34930,22218,23064,63784,63785,63786,63787,63788,20035,63789,20839,\n22856,26608,32784,63790,22899,24180,25754,31178,24565,24684,25288,25467,23527,\n23511,21162,63791,22900,24361,24594,63792,63793,63794,29785,63795,63796,63797,\n63798,63799,63800,39377,63801,63802,63803,63804,63805,63806,63807,63808,63809,\n63810,63811,28611,63812,63813,33215,36786,24817,63814,63815,33126,63816,63817,\n23615,63818,63819,63820,63821,63822,63823,63824,63825,23273,35365,26491,32016,\n63826,63827,63828,63829,63830,63831,33021,63832,63833,23612,27877,21311,28346,\n22810,33590,20025,20150,20294,21934,22296,22727,24406,26039,26086,27264,27573,\n28237,30701,31471,31774,32222,34507,34962,37170,37723,25787,28606,29562,30136,\n36948,21846,22349,25018,25812,26311,28129,28251,28525,28601,30192,32835,33213,\n34113,35203,35527,35674,37663,27795,30035,31572,36367,36957,21776,22530,22616,\n24162,25095,25758,26848,30070,31958,34739,40680,20195,22408,22382,22823,23565,\n23729,24118,24453,25140,25825,29619,33274,34955,36024,38538,40667,23429,24503,\n24755,20498,20992,21040,22294,22581,22615,23566,23648,23798,23947,24230,24466,\n24764,25361,25481,25623,26691,26873,27330,28120,28193,28372,28644,29182,30428,\n30585,31153,31291,33796,35241,36077,36339,36424,36867,36884,36947,37117,37709,\n38518,38876,27602,28678,29272,29346,29544,30563,31167,31716,32411,35712,22697,\n24775,25958,26109,26302,27788,28958,29129,35930,38931,20077,31361,20189,20908,\n20941,21205,21516,24999,26481,26704,26847,27934,28540,30140,30643,31461,33012,\n33891,37509,20828,26007,26460,26515,30168,31431,33651,\n63834,35910,36887,38957,23663,33216,33434,36929,36975,37389,24471,23965,27225,\n29128,30331,31561,34276,35588,37159,39472,21895,25078,63835,30313,32645,34367,\n34746,35064,37007,63836,27931,28889,29662,32097,33853,63837,37226,39409,63838,\n20098,21365,27396,27410,28734,29211,34349,40478,21068,36771,23888,25829,25900,\n27414,28651,31811,32412,34253,35172,35261,25289,33240,34847,24266,26391,28010,\n29436,29701,29807,34690,37086,20358,23821,24480,33802,20919,25504,30053,20142,\n20486,20841,20937,26753,27153,31918,31921,31975,33391,35538,36635,37327,20406,\n20791,21237,21570,24300,24942,25150,26053,27354,28670,31018,34268,34851,38317,\n39522,39530,40599,40654,21147,26310,27511,28701,31019,36706,38722,24976,25088,\n25891,28451,29001,29833,32244,32879,34030,36646,36899,37706,20925,21015,21155,\n27916,28872,35010,24265,25986,27566,28610,31806,29557,20196,20278,22265,63839,\n23738,23994,24604,29618,31533,32666,32718,32838,36894,37428,38646,38728,38936,\n40801,20363,28583,31150,37300,38583,21214,63840,25736,25796,27347,28510,28696,\n29200,30439,32769,34310,34396,36335,36613,38706,39791,40442,40565,30860,31103,\n32160,33737,37636,40575,40595,35542,22751,24324,26407,28711,29903,31840,32894,\n20769,28712,29282,30922,36034,36058,36084,38647,20102,20698,23534,24278,26009,\n29134,30274,30637,32842,34044,36988,39719,40845,22744,23105,23650,27155,28122,\n28431,30267,32047,32311,34078,35128,37860,38475,21129,26066,26611,27060,27969,\n28316,28687,29705,29792,30041,30244,30827,35628,39006,20845,25134,38520,20374,\n20523,23833,28138,32184,36650,24459,24900,26647,63841,\n38534,21202,32907,20956,20940,26974,31260,32190,33777,38517,20442,21033,21400,\n21519,21774,23653,24743,26446,26792,28012,29313,29432,29702,29827,63842,30178,\n31852,32633,32696,33673,35023,35041,37324,37328,38626,39881,21533,28542,29136,\n29848,34298,36522,38563,40023,40607,26519,28107,29747,33256,38678,30764,31435,\n31520,31890,25705,29802,30194,30908,30952,39340,39764,40635,23518,24149,28448,\n33180,33707,37000,19975,21325,23081,24018,24398,24930,25405,26217,26364,28415,\n28459,28771,30622,33836,34067,34875,36627,39237,39995,21788,25273,26411,27819,\n33545,35178,38778,20129,22916,24536,24537,26395,32178,32596,33426,33579,33725,\n36638,37017,22475,22969,23186,23504,26151,26522,26757,27599,29028,32629,36023,\n36067,36993,39749,33032,35978,38476,39488,40613,23391,27667,29467,30450,30431,\n33804,20906,35219,20813,20885,21193,26825,27796,30468,30496,32191,32236,38754,\n40629,28357,34065,20901,21517,21629,26126,26269,26919,28319,30399,30609,33559,\n33986,34719,37225,37528,40180,34946,20398,20882,21215,22982,24125,24917,25720,\n25721,26286,26576,27169,27597,27611,29279,29281,29761,30520,30683,32791,33468,\n33541,35584,35624,35980,26408,27792,29287,30446,30566,31302,40361,27519,27794,\n22818,26406,33945,21359,22675,22937,24287,25551,26164,26483,28218,29483,31447,\n33495,37672,21209,24043,25006,25035,25098,25287,25771,26080,26969,27494,27595,\n28961,29687,30045,32326,33310,33538,34154,35491,36031,38695,40289,22696,40664,\n20497,21006,21563,21839,25991,27766,32010,32011,32862,34442,38272,38639,21247,\n27797,29289,21619,23194,23614,23883,24396,24494,26410,\n26806,26979,28220,28228,30473,31859,32654,34183,35598,36855,38753,40692,23735,\n24758,24845,25003,25935,26107,26108,27665,27887,29599,29641,32225,38292,23494,\n34588,35600,21085,21338,25293,25615,25778,26420,27192,27850,29632,29854,31636,\n31893,32283,33162,33334,34180,36843,38649,39361,20276,21322,21453,21467,25292,\n25644,25856,26001,27075,27886,28504,29677,30036,30242,30436,30460,30928,30971,\n31020,32070,33324,34784,36820,38930,39151,21187,25300,25765,28196,28497,30332,\n36299,37297,37474,39662,39747,20515,20621,22346,22952,23592,24135,24439,25151,\n25918,26041,26049,26121,26507,27036,28354,30917,32033,32938,33152,33323,33459,\n33953,34444,35370,35607,37030,38450,40848,20493,20467,63843,22521,24472,25308,\n25490,26479,28227,28953,30403,32972,32986,35060,35061,35097,36064,36649,37197,\n38506,20271,20336,24091,26575,26658,30333,30334,39748,24161,27146,29033,29140,\n30058,63844,32321,34115,34281,39132,20240,31567,32624,38309,20961,24070,26805,\n27710,27726,27867,29359,31684,33539,27861,29754,20731,21128,22721,25816,27287,\n29863,30294,30887,34327,38370,38713,63845,21342,24321,35722,36776,36783,37002,\n21029,30629,40009,40712,19993,20482,20853,23643,24183,26142,26170,26564,26821,\n28851,29953,30149,31177,31453,36647,39200,39432,20445,22561,22577,23542,26222,\n27493,27921,28282,28541,29668,29995,33769,35036,35091,35676,36628,20239,20693,\n21264,21340,23443,24489,26381,31119,33145,33583,34068,35079,35206,36665,36667,\n39333,39954,26412,20086,20472,22857,23553,23791,23792,25447,26834,28925,29090,\n29739,32299,34028,34562,36898,37586,40179,19981,20184,\n20463,20613,21078,21103,21542,21648,22496,22827,23142,23386,23413,23500,24220,\n63846,25206,25975,26023,28014,28325,29238,31526,31807,32566,33104,33105,33178,\n33344,33433,33705,35331,36000,36070,36091,36212,36282,37096,37340,38428,38468,\n39385,40167,21271,20998,21545,22132,22707,22868,22894,24575,24996,25198,26128,\n27774,28954,30406,31881,31966,32027,33452,36033,38640,63847,20315,24343,24447,\n25282,23849,26379,26842,30844,32323,40300,19989,20633,21269,21290,21329,22915,\n23138,24199,24754,24970,25161,25209,26000,26503,27047,27604,27606,27607,27608,\n27832,63848,29749,30202,30738,30865,31189,31192,31875,32203,32737,32933,33086,\n33218,33778,34586,35048,35513,35692,36027,37145,38750,39131,40763,22188,23338,\n24428,25996,27315,27567,27996,28657,28693,29277,29613,36007,36051,38971,24977,\n27703,32856,39425,20045,20107,20123,20181,20282,20284,20351,20447,20735,21490,\n21496,21766,21987,22235,22763,22882,23057,23531,23546,23556,24051,24107,24473,\n24605,25448,26012,26031,26614,26619,26797,27515,27801,27863,28195,28681,29509,\n30722,31038,31040,31072,31169,31721,32023,32114,32902,33293,33678,34001,34503,\n35039,35408,35422,35613,36060,36198,36781,37034,39164,39391,40605,21066,63849,\n26388,63850,20632,21034,23665,25955,27733,29642,29987,30109,31639,33948,37240,\n38704,20087,25746,27578,29022,34217,19977,63851,26441,26862,28183,33439,34072,\n34923,25591,28545,37394,39087,19978,20663,20687,20767,21830,21930,22039,23360,\n23577,23776,24120,24202,24224,24258,24819,26705,27233,28248,29245,29248,29376,\n30456,31077,31665,32724,35059,35316,35443,35937,36062,\n38684,22622,29885,36093,21959,63852,31329,32034,33394,29298,29983,29989,63853,\n31513,22661,22779,23996,24207,24246,24464,24661,25234,25471,25933,26257,26329,\n26360,26646,26866,29312,29790,31598,32110,32214,32626,32997,33298,34223,35199,\n35475,36893,37604,40653,40736,22805,22893,24109,24796,26132,26227,26512,27728,\n28101,28511,30707,30889,33990,37323,37675,20185,20682,20808,21892,23307,23459,\n25159,25982,26059,28210,29053,29697,29764,29831,29887,30316,31146,32218,32341,\n32680,33146,33203,33337,34330,34796,35445,36323,36984,37521,37925,39245,39854,\n21352,23633,26964,27844,27945,28203,33292,34203,35131,35373,35498,38634,40807,\n21089,26297,27570,32406,34814,36109,38275,38493,25885,28041,29166,63854,22478,\n22995,23468,24615,24826,25104,26143,26207,29481,29689,30427,30465,31596,32854,\n32882,33125,35488,37266,19990,21218,27506,27927,31237,31545,32048,63855,36016,\n21484,22063,22609,23477,23567,23569,24034,25152,25475,25620,26157,26803,27836,\n28040,28335,28703,28836,29138,29990,30095,30094,30233,31505,31712,31787,32032,\n32057,34092,34157,34311,35380,36877,36961,37045,37559,38902,39479,20439,23660,\n26463,28049,31903,32396,35606,36118,36895,23403,24061,25613,33984,36956,39137,\n29575,23435,24730,26494,28126,35359,35494,36865,38924,21047,63856,28753,30862,\n37782,34928,37335,20462,21463,22013,22234,22402,22781,23234,23432,23723,23744,\n24101,24833,25101,25163,25480,25628,25910,25976,27193,27530,27700,27929,28465,\n29159,29417,29560,29703,29874,30246,30561,31168,31319,31466,31929,32143,32172,\n32353,32670,33065,33585,33936,34010,34282,34966,35504,\n35728,36664,36930,36995,37228,37526,37561,38539,38567,38568,38614,38656,38920,\n39318,39635,39706,21460,22654,22809,23408,23487,28113,28506,29087,29729,29881,\n32901,33789,24033,24455,24490,24642,26092,26642,26991,27219,27529,27957,28147,\n29667,30462,30636,31565,32020,33059,33308,33600,34036,34147,35426,35524,37255,\n37662,38918,39348,25100,34899,36848,37477,23815,23847,23913,29791,33181,34664,\n28629,25342,32722,35126,35186,19998,20056,20711,21213,21319,25215,26119,32361,\n34821,38494,20365,21273,22070,22987,23204,23608,23630,23629,24066,24337,24643,\n26045,26159,26178,26558,26612,29468,30690,31034,32709,33940,33997,35222,35430,\n35433,35553,35925,35962,22516,23508,24335,24687,25325,26893,27542,28252,29060,\n31698,34645,35672,36606,39135,39166,20280,20353,20449,21627,23072,23480,24892,\n26032,26216,29180,30003,31070,32051,33102,33251,33688,34218,34254,34563,35338,\n36523,36763,63857,36805,22833,23460,23526,24713,23529,23563,24515,27777,63858,\n28145,28683,29978,33455,35574,20160,21313,63859,38617,27663,20126,20420,20818,\n21854,23077,23784,25105,29273,33469,33706,34558,34905,35357,38463,38597,39187,\n40201,40285,22538,23731,23997,24132,24801,24853,25569,27138,28197,37122,37716,\n38990,39952,40823,23433,23736,25353,26191,26696,30524,38593,38797,38996,39839,\n26017,35585,36555,38332,21813,23721,24022,24245,26263,30284,33780,38343,22739,\n25276,29390,40232,20208,22830,24591,26171,27523,31207,40230,21395,21696,22467,\n23830,24859,26326,28079,30861,33406,38552,38724,21380,25212,25494,28082,32266,\n33099,38989,27387,32588,40367,40474,20063,20539,20918,\n22812,24825,25590,26928,29242,32822,63860,37326,24369,63861,63862,32004,33509,\n33903,33979,34277,36493,63863,20335,63864,63865,22756,23363,24665,25562,25880,\n25965,26264,63866,26954,27171,27915,28673,29036,30162,30221,31155,31344,63867,\n32650,63868,35140,63869,35731,37312,38525,63870,39178,22276,24481,26044,28417,\n30208,31142,35486,39341,39770,40812,20740,25014,25233,27277,33222,20547,22576,\n24422,28937,35328,35578,23420,34326,20474,20796,22196,22852,25513,28153,23978,\n26989,20870,20104,20313,63871,63872,63873,22914,63874,63875,27487,27741,63876,\n29877,30998,63877,33287,33349,33593,36671,36701,63878,39192,63879,63880,63881,\n20134,63882,22495,24441,26131,63883,63884,30123,32377,35695,63885,36870,39515,\n22181,22567,23032,23071,23476,63886,24310,63887,63888,25424,25403,63889,26941,\n27783,27839,28046,28051,28149,28436,63890,28895,28982,29017,63891,29123,29141,\n63892,30799,30831,63893,31605,32227,63894,32303,63895,34893,36575,63896,63897,\n63898,37467,63899,40182,63900,63901,63902,24709,28037,63903,29105,63904,63905,\n38321,21421,63906,63907,63908,26579,63909,28814,28976,29744,33398,33490,63910,\n38331,39653,40573,26308,63911,29121,33865,63912,63913,22603,63914,63915,23992,\n24433,63916,26144,26254,27001,27054,27704,27891,28214,28481,28634,28699,28719,\n29008,29151,29552,63917,29787,63918,29908,30408,31310,32403,63919,63920,33521,\n35424,36814,63921,37704,63922,38681,63923,63924,20034,20522,63925,21000,21473,\n26355,27757,28618,29450,30591,31330,33454,34269,34306,63926,35028,35427,35709,\n35947,63927,37555,63928,38675,38928,20116,20237,20425,\n20658,21320,21566,21555,21978,22626,22714,22887,23067,23524,24735,63929,25034,\n25942,26111,26212,26791,27738,28595,28879,29100,29522,31613,34568,35492,39986,\n40711,23627,27779,29508,29577,37434,28331,29797,30239,31337,32277,34314,20800,\n22725,25793,29934,29973,30320,32705,37013,38605,39252,28198,29926,31401,31402,\n33253,34521,34680,35355,23113,23436,23451,26785,26880,28003,29609,29715,29740,\n30871,32233,32747,33048,33109,33694,35916,38446,38929,26352,24448,26106,26505,\n27754,29579,20525,23043,27498,30702,22806,23916,24013,29477,30031,63930,63931,\n20709,20985,22575,22829,22934,23002,23525,63932,63933,23970,25303,25622,25747,\n25854,63934,26332,63935,27208,63936,29183,29796,63937,31368,31407,32327,32350,\n32768,33136,63938,34799,35201,35616,36953,63939,36992,39250,24958,27442,28020,\n32287,35109,36785,20433,20653,20887,21191,22471,22665,23481,24248,24898,27029,\n28044,28263,28342,29076,29794,29992,29996,32883,33592,33993,36362,37780,37854,\n63940,20110,20305,20598,20778,21448,21451,21491,23431,23507,23588,24858,24962,\n26100,29275,29591,29760,30402,31056,31121,31161,32006,32701,33419,34261,34398,\n36802,36935,37109,37354,38533,38632,38633,21206,24423,26093,26161,26671,29020,\n31286,37057,38922,20113,63941,27218,27550,28560,29065,32792,33464,34131,36939,\n38549,38642,38907,34074,39729,20112,29066,38596,20803,21407,21729,22291,22290,\n22435,23195,23236,23491,24616,24895,25588,27781,27961,28274,28304,29232,29503,\n29783,33489,34945,36677,36960,63942,38498,39000,40219,26376,36234,37470,20301,\n20553,20702,21361,22285,22996,23041,23561,24944,26256,\n28205,29234,29771,32239,32963,33806,33894,34111,34655,34907,35096,35586,36949,\n38859,39759,20083,20369,20754,20842,63943,21807,21929,23418,23461,24188,24189,\n24254,24736,24799,24840,24841,25540,25912,26377,63944,26580,26586,63945,26977,\n26978,27833,27943,63946,28216,63947,28641,29494,29495,63948,29788,30001,63949,\n30290,63950,63951,32173,33278,33848,35029,35480,35547,35565,36400,36418,36938,\n36926,36986,37193,37321,37742,63952,63953,22537,63954,27603,32905,32946,63955,\n63956,20801,22891,23609,63957,63958,28516,29607,32996,36103,63959,37399,38287,\n63960,63961,63962,63963,32895,25102,28700,32104,34701,63964,22432,24681,24903,\n27575,35518,37504,38577,20057,21535,28139,34093,38512,38899,39150,25558,27875,\n37009,20957,25033,33210,40441,20381,20506,20736,23452,24847,25087,25836,26885,\n27589,30097,30691,32681,33380,34191,34811,34915,35516,35696,37291,20108,20197,\n20234,63965,63966,22839,23016,63967,24050,24347,24411,24609,63968,63969,63970,\n63971,29246,29669,63972,30064,30157,63973,31227,63974,32780,32819,32900,33505,\n33617,63975,63976,36029,36019,36999,63977,63978,39156,39180,63979,63980,28727,\n30410,32714,32716,32764,35610,20154,20161,20995,21360,63981,21693,22240,23035,\n23493,24341,24525,28270,63982,63983,32106,33589,63984,34451,35469,63985,38765,\n38775,63986,63987,19968,20314,20350,22777,26085,28322,36920,37808,39353,20219,\n22764,22922,23001,24641,63988,63989,31252,63990,33615,36035,20837,21316,63991,\n63992,63993,20173,21097,23381,33471,20180,21050,21672,22985,23039,23376,23383,\n23388,24675,24904,28363,28825,29038,29574,29943,30133,\n30913,32043,32773,33258,33576,34071,34249,35566,36039,38604,20316,21242,22204,\n26027,26152,28796,28856,29237,32189,33421,37196,38592,40306,23409,26855,27544,\n28538,30430,23697,26283,28507,31668,31786,34870,38620,19976,20183,21280,22580,\n22715,22767,22892,23559,24115,24196,24373,25484,26290,26454,27167,27299,27404,\n28479,29254,63994,29520,29835,31456,31911,33144,33247,33255,33674,33900,34083,\n34196,34255,35037,36115,37292,38263,38556,20877,21705,22312,23472,25165,26448,\n26685,26771,28221,28371,28797,32289,35009,36001,36617,40779,40782,29229,31631,\n35533,37658,20295,20302,20786,21632,22992,24213,25269,26485,26990,27159,27822,\n28186,29401,29482,30141,31672,32053,33511,33785,33879,34295,35419,36015,36487,\n36889,37048,38606,40799,21219,21514,23265,23490,25688,25973,28404,29380,63995,\n30340,31309,31515,31821,32318,32735,33659,35627,36042,36196,36321,36447,36842,\n36857,36969,37841,20291,20346,20659,20840,20856,21069,21098,22625,22652,22880,\n23560,23637,24283,24731,25136,26643,27583,27656,28593,29006,29728,30000,30008,\n30033,30322,31564,31627,31661,31686,32399,35438,36670,36681,37439,37523,37666,\n37931,38651,39002,39019,39198,20999,25130,25240,27993,30308,31434,31680,32118,\n21344,23742,24215,28472,28857,31896,38673,39822,40670,25509,25722,34678,19969,\n20117,20141,20572,20597,21576,22979,23450,24128,24237,24311,24449,24773,25402,\n25919,25972,26060,26230,26232,26622,26984,27273,27491,27712,28096,28136,28191,\n28254,28702,28833,29582,29693,30010,30555,30855,31118,31243,31357,31934,32142,\n33351,35330,35562,35998,37165,37194,37336,37478,37580,\n37664,38662,38742,38748,38914,40718,21046,21137,21884,22564,24093,24351,24716,\n25552,26799,28639,31085,31532,33229,34234,35069,35576,36420,37261,38500,38555,\n38717,38988,40778,20430,20806,20939,21161,22066,24340,24427,25514,25805,26089,\n26177,26362,26361,26397,26781,26839,27133,28437,28526,29031,29157,29226,29866,\n30522,31062,31066,31199,31264,31381,31895,31967,32068,32368,32903,34299,34468,\n35412,35519,36249,36481,36896,36973,37347,38459,38613,40165,26063,31751,36275,\n37827,23384,23562,21330,25305,29469,20519,23447,24478,24752,24939,26837,28121,\n29742,31278,32066,32156,32305,33131,36394,36405,37758,37912,20304,22352,24038,\n24231,25387,32618,20027,20303,20367,20570,23005,32964,21610,21608,22014,22863,\n23449,24030,24282,26205,26417,26609,26666,27880,27954,28234,28557,28855,29664,\n30087,31820,32002,32044,32162,33311,34523,35387,35461,36208,36490,36659,36913,\n37198,37202,37956,39376,31481,31909,20426,20737,20934,22472,23535,23803,26201,\n27197,27994,28310,28652,28940,30063,31459,34850,36897,36981,38603,39423,33537,\n20013,20210,34886,37325,21373,27355,26987,27713,33914,22686,24974,26366,25327,\n28893,29969,30151,32338,33976,35657,36104,20043,21482,21675,22320,22336,24535,\n25345,25351,25711,25903,26088,26234,26525,26547,27490,27744,27802,28460,30693,\n30757,31049,31063,32025,32930,33026,33267,33437,33463,34584,35468,63996,36100,\n36286,36978,30452,31257,31287,32340,32887,21767,21972,22645,25391,25634,26185,\n26187,26733,27035,27524,27941,28337,29645,29800,29857,30043,30137,30433,30494,\n30603,31206,32265,32285,33275,34095,34967,35386,36049,\n36587,36784,36914,37805,38499,38515,38663,20356,21489,23018,23241,24089,26702,\n29894,30142,31209,31378,33187,34541,36074,36300,36845,26015,26389,63997,22519,\n28503,32221,36655,37878,38598,24501,25074,28548,19988,20376,20511,21449,21983,\n23919,24046,27425,27492,30923,31642,63998,36425,36554,36974,25417,25662,30528,\n31364,37679,38015,40810,25776,28591,29158,29864,29914,31428,31762,32386,31922,\n32408,35738,36106,38013,39184,39244,21049,23519,25830,26413,32046,20717,21443,\n22649,24920,24921,25082,26028,31449,35730,35734,20489,20513,21109,21809,23100,\n24288,24432,24884,25950,26124,26166,26274,27085,28356,28466,29462,30241,31379,\n33081,33369,33750,33980,20661,22512,23488,23528,24425,25505,30758,32181,33756,\n34081,37319,37365,20874,26613,31574,36012,20932,22971,24765,34389,20508,63999,\n21076,23610,24957,25114,25299,25842,26021,28364,30240,33034,36448,38495,38587,\n20191,21315,21912,22825,24029,25797,27849,28154,29588,31359,33307,34214,36068,\n36368,36983,37351,38369,38433,38854,20984,21746,21894,24505,25764,28552,32180,\n36639,36685,37941,20681,23574,27838,28155,29979,30651,31805,31844,35449,35522,\n22558,22974,24086,25463,29266,30090,30571,35548,36028,36626,24307,26228,28152,\n32893,33729,35531,38737,39894,64000,21059,26367,28053,28399,32224,35558,36910,\n36958,39636,21021,21119,21736,24980,25220,25307,26786,26898,26970,27189,28818,\n28966,30813,30977,30990,31186,31245,32918,33400,33493,33609,34121,35970,36229,\n37218,37259,37294,20419,22225,29165,30679,34560,35320,23544,24534,26449,37032,\n21474,22618,23541,24740,24961,25696,32317,32880,34085,\n37507,25774,20652,23828,26368,22684,25277,25512,26894,27000,27166,28267,30394,\n31179,33467,33833,35535,36264,36861,37138,37195,37276,37648,37656,37786,38619,\n39478,39949,19985,30044,31069,31482,31569,31689,32302,33988,36441,36468,36600,\n36880,26149,26943,29763,20986,26414,40668,20805,24544,27798,34802,34909,34935,\n24756,33205,33795,36101,21462,21561,22068,23094,23601,28810,32736,32858,33030,\n33261,36259,37257,39519,40434,20596,20164,21408,24827,28204,23652,20360,20516,\n21988,23769,24159,24677,26772,27835,28100,29118,30164,30196,30305,31258,31305,\n32199,32251,32622,33268,34473,36636,38601,39347,40786,21063,21189,39149,35242,\n19971,26578,28422,20405,23522,26517,27784,28024,29723,30759,37341,37756,34756,\n31204,31281,24555,20182,21668,21822,22702,22949,24816,25171,25302,26422,26965,\n33333,38464,39345,39389,20524,21331,21828,22396,64001,25176,64002,25826,26219,\n26589,28609,28655,29730,29752,35351,37944,21585,22022,22374,24392,24986,27470,\n28760,28845,32187,35477,22890,33067,25506,30472,32829,36010,22612,25645,27067,\n23445,24081,28271,64003,34153,20812,21488,22826,24608,24907,27526,27760,27888,\n31518,32974,33492,36294,37040,39089,64004,25799,28580,25745,25860,20814,21520,\n22303,35342,24927,26742,64005,30171,31570,32113,36890,22534,27084,33151,35114,\n36864,38969,20600,22871,22956,25237,36879,39722,24925,29305,38358,22369,23110,\n24052,25226,25773,25850,26487,27874,27966,29228,29750,30772,32631,33453,36315,\n38935,21028,22338,26495,29256,29923,36009,36774,37393,38442,20843,21485,25420,\n20329,21764,24726,25943,27803,28031,29260,29437,31255,\n35207,35997,24429,28558,28921,33192,24846,20415,20559,25153,29255,31687,32232,\n32745,36941,38829,39449,36022,22378,24179,26544,33805,35413,21536,23318,24163,\n24290,24330,25987,32954,34109,38281,38491,20296,21253,21261,21263,21638,21754,\n22275,24067,24598,25243,25265,25429,64006,27873,28006,30129,30770,32990,33071,\n33502,33889,33970,34957,35090,36875,37610,39165,39825,24133,26292,26333,28689,\n29190,64007,20469,21117,24426,24915,26451,27161,28418,29922,31080,34920,35961,\n39111,39108,39491,21697,31263,26963,35575,35914,39080,39342,24444,25259,30130,\n30382,34987,36991,38466,21305,24380,24517,27852,29644,30050,30091,31558,33534,\n39325,20047,36924,19979,20309,21414,22799,24264,26160,27827,29781,33655,34662,\n36032,36944,38686,39957,22737,23416,34384,35604,40372,23506,24680,24717,26097,\n27735,28450,28579,28698,32597,32752,38289,38290,38480,38867,21106,36676,20989,\n21547,21688,21859,21898,27323,28085,32216,33382,37532,38519,40569,21512,21704,\n30418,34532,38308,38356,38492,20130,20233,23022,23270,24055,24658,25239,26477,\n26689,27782,28207,32568,32923,33322,64008,64009,38917,20133,20565,21683,22419,\n22874,23401,23475,25032,26999,28023,28707,34809,35299,35442,35559,36994,39405,\n39608,21182,26680,20502,24184,26447,33607,34892,20139,21521,22190,29670,37141,\n38911,39177,39255,39321,22099,22687,34395,35377,25010,27382,29563,36562,27463,\n38570,39511,22869,29184,36203,38761,20436,23796,24358,25080,26203,27883,28843,\n29572,29625,29694,30505,30541,32067,32098,32291,33335,34898,64010,36066,37449,\n39023,23377,31348,34880,38913,23244,20448,21332,22846,\n23805,25406,28025,29433,33029,33031,33698,37583,38960,20136,20804,21009,22411,\n24418,27842,28366,28677,28752,28847,29074,29673,29801,33610,34722,34913,36872,\n37026,37795,39336,20846,24407,24800,24935,26291,34137,36426,37295,38795,20046,\n20114,21628,22741,22778,22909,23733,24359,25142,25160,26122,26215,27627,28009,\n28111,28246,28408,28564,28640,28649,28765,29392,29733,29786,29920,30355,31068,\n31946,32286,32993,33446,33899,33983,34382,34399,34676,35703,35946,37804,38912,\n39013,24785,25110,37239,23130,26127,28151,28222,29759,39746,24573,24794,31503,\n21700,24344,27742,27859,27946,28888,32005,34425,35340,40251,21270,21644,23301,\n27194,28779,30069,31117,31166,33457,33775,35441,35649,36008,38772,64011,25844,\n25899,30906,30907,31339,20024,21914,22864,23462,24187,24739,25563,27489,26213,\n26707,28185,29029,29872,32008,36996,39529,39973,27963,28369,29502,35905,38346,\n20976,24140,24488,24653,24822,24880,24908,26179,26180,27045,27841,28255,28361,\n28514,29004,29852,30343,31681,31783,33618,34647,36945,38541,40643,21295,22238,\n24315,24458,24674,24724,25079,26214,26371,27292,28142,28590,28784,29546,32362,\n33214,33588,34516,35496,36036,21123,29554,23446,27243,37892,21742,22150,23389,\n25928,25989,26313,26783,28045,28102,29243,32948,37237,39501,20399,20505,21402,\n21518,21564,21897,21957,24127,24460,26429,29030,29661,36869,21211,21235,22628,\n22734,28932,29071,29179,34224,35347,26248,34216,21927,26244,29002,33841,21321,\n21913,27585,24409,24509,25582,26249,28999,35569,36637,40638,20241,25658,28875,\n30054,34407,24676,35662,40440,20807,20982,21256,27958,\n33016,40657,26133,27427,28824,30165,21507,23673,32007,35350,27424,27453,27462,\n21560,24688,27965,32725,33288,20694,20958,21916,22123,22221,23020,23305,24076,\n24985,24984,25137,26206,26342,29081,29113,29114,29351,31143,31232,32690,35440,\n"
  },
  {
    "path": "user.libc/src/locale/langinfo.c",
    "content": "#include <locale.h>\n#include <langinfo.h>\n#include \"locale_impl.h\"\n\nstatic const char c_time[] =\n\t\"Sun\\0\" \"Mon\\0\" \"Tue\\0\" \"Wed\\0\" \"Thu\\0\" \"Fri\\0\" \"Sat\\0\"\n\t\"Sunday\\0\" \"Monday\\0\" \"Tuesday\\0\" \"Wednesday\\0\"\n\t\"Thursday\\0\" \"Friday\\0\" \"Saturday\\0\"\n\t\"Jan\\0\" \"Feb\\0\" \"Mar\\0\" \"Apr\\0\" \"May\\0\" \"Jun\\0\"\n\t\"Jul\\0\" \"Aug\\0\" \"Sep\\0\" \"Oct\\0\" \"Nov\\0\" \"Dec\\0\"\n\t\"January\\0\"   \"February\\0\" \"March\\0\"    \"April\\0\"\n\t\"May\\0\"       \"June\\0\"     \"July\\0\"     \"August\\0\"\n\t\"September\\0\" \"October\\0\"  \"November\\0\" \"December\\0\"\n\t\"AM\\0\" \"PM\\0\"\n\t\"%a %b %e %T %Y\\0\"\n\t\"%m/%d/%y\\0\"\n\t\"%H:%M:%S\\0\"\n\t\"%I:%M:%S %p\\0\"\n\t\"\\0\"\n\t\"\\0\"\n\t\"%m/%d/%y\\0\"\n\t\"0123456789\\0\"\n\t\"%a %b %e %T %Y\\0\"\n\t\"%H:%M:%S\";\n\nstatic const char c_messages[] = \"^[yY]\\0\" \"^[nN]\\0\" \"yes\\0\" \"no\";\nstatic const char c_numeric[] = \".\\0\" \"\";\n\nchar *__nl_langinfo_l(nl_item item, locale_t loc)\n{\n\tint cat = item >> 16;\n\tint idx = item & 65535;\n\tconst char *str;\n\n\tif (item == CODESET) return loc->cat[LC_CTYPE] ? \"UTF-8\" : \"ASCII\";\n\n\t/* _NL_LOCALE_NAME extension */\n\tif (idx == 65535 && cat < LC_ALL)\n\t\treturn loc->cat[cat] ? (char *)loc->cat[cat]->name : \"C\";\n\t\n\tswitch (cat) {\n\tcase LC_NUMERIC:\n\t\tif (idx > 1) return \"\";\n\t\tstr = c_numeric;\n\t\tbreak;\n\tcase LC_TIME:\n\t\tif (idx > 0x31) return \"\";\n\t\tstr = c_time;\n\t\tbreak;\n\tcase LC_MONETARY:\n\t\tif (idx > 0) return \"\";\n\t\tstr = \"\";\n\t\tbreak;\n\tcase LC_MESSAGES:\n\t\tif (idx > 3) return \"\";\n\t\tstr = c_messages;\n\t\tbreak;\n\tdefault:\n\t\treturn \"\";\n\t}\n\n\tfor (; idx; idx--, str++) for (; *str; str++);\n\tif (cat != LC_NUMERIC && *str) str = LCTRANS(str, cat, loc);\n\treturn (char *)str;\n}\n\nchar *__nl_langinfo(nl_item item)\n{\n\treturn __nl_langinfo_l(item, CURRENT_LOCALE);\n}\n\nweak_alias(__nl_langinfo, nl_langinfo);\nweak_alias(__nl_langinfo_l, nl_langinfo_l);\n"
  },
  {
    "path": "user.libc/src/locale/legacychars.h",
    "content": "256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,\n275,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,\n296,297,298,299,302,303,304,305,308,309,310,311,312,313,314,315,316,317,318,\n321,322,323,324,325,326,327,328,330,331,332,333,336,337,338,339,340,341,342,\n343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,\n362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,\n381,382,402,416,417,431,432,536,537,538,539,710,711,728,729,731,732,733,768,\n769,771,777,803,890,900,901,902,904,905,906,908,910,911,912,913,914,915,916,\n917,918,919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,936,\n937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,\n956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,\n1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1038,1039,1040,\n1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,\n1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,\n1071,\n1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,\n1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,\n1102,1103,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1118,\n1119,1168,1169,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1467,1468,\n1469,1470,1471,1472,1473,1474,1475,1488,1489,1490,1491,1492,1493,1494,1495,\n1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,\n1511,1512,1513,1514,1520,1521,1522,1523,1524,1548,1563,1567,1569,1570,1571,\n1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,\n1587,1588,1589,1590,1591,1592,1593,1594,1600,1601,1602,1603,1604,1605,1606,\n1607,1608,1609,1610,1611,1612,1613,1614,1615,1616,1617,1618,1657,1662,1670,\n1672,1681,1688,1705,1711,1722,1726,1729,1746,3585,3586,3587,3588,3589,3590,\n3591,3592,3593,3594,3595,3596,3597,3598,3599,3600,3601,3602,3603,3604,3605,\n3606,3607,3608,3609,3610,3611,3612,3613,3614,3615,3616,3617,3618,3619,3620,\n3621,3622,3623,3624,3625,3626,3627,3628,3629,3630,3631,3632,3633,3634,3635,\n3636,3637,3638,3639,3640,3641,3642,3647,3648,3649,3650,3651,3652,3653,3654,\n3655,3656,3657,3658,3659,3660,3661,3662,3663,3664,3665,3666,3667,3668,3669,\n3670,3671,3672,3673,3674,3675,7682,7683,7690,7691,7710,7711,7744,7745,7766,\n7767,\n7776,7777,7786,7787,7808,7809,7810,7811,7812,7813,7922,7923,8204,8205,8206,\n8207,8211,8212,8213,8215,8216,8217,8218,8220,8221,8222,8224,8225,8226,8230,\n8240,8249,8250,8319,8359,8362,8363,8364,8367,8470,8482,8729,8730,8734,8745,\n8776,8801,8804,8805,8976,8992,8993,9472,9474,9484,9488,9492,9496,9500,9508,\n9516,9524,9532,9552,9553,9554,9555,9556,9557,9558,9559,9560,9561,9562,9563,\n9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,\n9579,9580,9600,9604,9608,9612,9616,9617,9618,9619,9632,\n"
  },
  {
    "path": "user.libc/src/locale/locale_map.c",
    "content": "#include <locale.h>\n#include <string.h>\n#include <sys/mman.h>\n#include <stdlib.h>\n#include \"locale_impl.h\"\n#include \"libc.h\"\n#include \"lock.h\"\n#include \"fork_impl.h\"\n\n#define malloc __libc_malloc\n#define calloc undef\n#define realloc undef\n#define free undef\n\nconst char *__lctrans_impl(const char *msg, const struct __locale_map *lm)\n{\n\tconst char *trans = 0;\n\tif (lm) trans = __mo_lookup(lm->map, lm->map_size, msg);\n\treturn trans ? trans : msg;\n}\n\nstatic const char envvars[][12] = {\n\t\"LC_CTYPE\",\n\t\"LC_NUMERIC\",\n\t\"LC_TIME\",\n\t\"LC_COLLATE\",\n\t\"LC_MONETARY\",\n\t\"LC_MESSAGES\",\n};\n\nvolatile int __locale_lock[1];\nvolatile int *const __locale_lockptr = __locale_lock;\n\nconst struct __locale_map *__get_locale(int cat, const char *val)\n{\n\tstatic void *volatile loc_head;\n\tconst struct __locale_map *p;\n\tstruct __locale_map *new = 0;\n\tconst char *path = 0, *z;\n\tchar buf[256];\n\tsize_t l, n;\n\n\tif (!*val) {\n\t\t(val = getenv(\"LC_ALL\")) && *val ||\n\t\t(val = getenv(envvars[cat])) && *val ||\n\t\t(val = getenv(\"LANG\")) && *val ||\n\t\t(val = \"C.UTF-8\");\n\t}\n\n\t/* Limit name length and forbid leading dot or any slashes. */\n\tfor (n=0; n<LOCALE_NAME_MAX && val[n] && val[n]!='/'; n++);\n\tif (val[0]=='.' || val[n]) val = \"C.UTF-8\";\n\tint builtin = (val[0]=='C' && !val[1])\n\t\t|| !strcmp(val, \"C.UTF-8\")\n\t\t|| !strcmp(val, \"POSIX\");\n\n\tif (builtin) {\n\t\tif (cat == LC_CTYPE && val[1]=='.')\n\t\t\treturn (void *)&__c_dot_utf8;\n\t\treturn 0;\n\t}\n\n\tfor (p=loc_head; p; p=p->next)\n\t\tif (!strcmp(val, p->name)) return p;\n\n\tif (!libc.secure) path = getenv(\"MUSL_LOCPATH\");\n\t/* FIXME: add a default path? */\n\n\tif (path) for (; *path; path=z+!!*z) {\n\t\tz = __strchrnul(path, ':');\n\t\tl = z - path;\n\t\tif (l >= sizeof buf - n - 2) continue;\n\t\tmemcpy(buf, path, l);\n\t\tbuf[l] = '/';\n\t\tmemcpy(buf+l+1, val, n);\n\t\tbuf[l+1+n] = 0;\n\t\tsize_t map_size;\n\t\tconst void *map = __map_file(buf, &map_size);\n\t\tif (map) {\n\t\t\tnew = malloc(sizeof *new);\n\t\t\tif (!new) {\n\t\t\t\t__munmap((void *)map, map_size);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tnew->map = map;\n\t\t\tnew->map_size = map_size;\n\t\t\tmemcpy(new->name, val, n);\n\t\t\tnew->name[n] = 0;\n\t\t\tnew->next = loc_head;\n\t\t\tloc_head = new;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t/* If no locale definition was found, make a locale map\n\t * object anyway to store the name, which is kept for the\n\t * sake of being able to do message translations at the\n\t * application level. */\n\tif (!new && (new = malloc(sizeof *new))) {\n\t\tnew->map = __c_dot_utf8.map;\n\t\tnew->map_size = __c_dot_utf8.map_size;\n\t\tmemcpy(new->name, val, n);\n\t\tnew->name[n] = 0;\n\t\tnew->next = loc_head;\n\t\tloc_head = new;\n\t}\n\n\t/* For LC_CTYPE, never return a null pointer unless the\n\t * requested name was \"C\" or \"POSIX\". */\n\tif (!new && cat == LC_CTYPE) new = (void *)&__c_dot_utf8;\n\n\treturn new;\n}\n"
  },
  {
    "path": "user.libc/src/locale/localeconv.c",
    "content": "#include <locale.h>\n#include <limits.h>\n\nstatic const struct lconv posix_lconv = {\n\t.decimal_point = \".\",\n\t.thousands_sep = \"\",\n\t.grouping = \"\",\n\t.int_curr_symbol = \"\",\n\t.currency_symbol = \"\",\n\t.mon_decimal_point = \"\",\n\t.mon_thousands_sep = \"\",\n\t.mon_grouping = \"\",\n\t.positive_sign = \"\",\n\t.negative_sign = \"\",\n\t.int_frac_digits = CHAR_MAX,\n\t.frac_digits = CHAR_MAX,\n\t.p_cs_precedes = CHAR_MAX,\n\t.p_sep_by_space = CHAR_MAX,\n\t.n_cs_precedes = CHAR_MAX,\n\t.n_sep_by_space = CHAR_MAX,\n\t.p_sign_posn = CHAR_MAX,\n\t.n_sign_posn = CHAR_MAX,\n\t.int_p_cs_precedes = CHAR_MAX,\n\t.int_p_sep_by_space = CHAR_MAX,\n\t.int_n_cs_precedes = CHAR_MAX,\n\t.int_n_sep_by_space = CHAR_MAX,\n\t.int_p_sign_posn = CHAR_MAX,\n\t.int_n_sign_posn = CHAR_MAX,\n};\n\nstruct lconv *localeconv(void)\n{\n\treturn (void *)&posix_lconv;\n}\n"
  },
  {
    "path": "user.libc/src/locale/newlocale.c",
    "content": "#include <stdlib.h>\n#include <string.h>\n#include <pthread.h>\n#include \"locale_impl.h\"\n#include \"lock.h\"\n\n#define malloc __libc_malloc\n#define calloc undef\n#define realloc undef\n#define free undef\n\nstatic int default_locale_init_done;\nstatic struct __locale_struct default_locale, default_ctype_locale;\n\nint __loc_is_allocated(locale_t loc)\n{\n\treturn loc && loc != C_LOCALE && loc != UTF8_LOCALE\n\t\t&& loc != &default_locale && loc != &default_ctype_locale;\n}\n\nstatic locale_t do_newlocale(int mask, const char *name, locale_t loc)\n{\n\tstruct __locale_struct tmp;\n\n\tfor (int i=0; i<LC_ALL; i++) {\n\t\ttmp.cat[i] = (!(mask & (1<<i)) && loc) ? loc->cat[i] :\n\t\t\t__get_locale(i, (mask & (1<<i)) ? name : \"\");\n\t\tif (tmp.cat[i] == LOC_MAP_FAILED)\n\t\t\treturn 0;\n\t}\n\n\t/* For locales with allocated storage, modify in-place. */\n\tif (__loc_is_allocated(loc)) {\n\t\t*loc = tmp;\n\t\treturn loc;\n\t}\n\n\t/* Otherwise, first see if we can use one of the builtin locales.\n\t * This makes the common usage case for newlocale, getting a C locale\n\t * with predictable behavior, very fast, and more importantly, fail-safe. */\n\tif (!memcmp(&tmp, C_LOCALE, sizeof tmp)) return C_LOCALE;\n\tif (!memcmp(&tmp, UTF8_LOCALE, sizeof tmp)) return UTF8_LOCALE;\n\n\t/* And provide builtins for the initial default locale, and a\n\t * variant of the C locale honoring the default locale's encoding. */\n\tif (!default_locale_init_done) {\n\t\tfor (int i=0; i<LC_ALL; i++)\n\t\t\tdefault_locale.cat[i] = __get_locale(i, \"\");\n\t\tdefault_ctype_locale.cat[LC_CTYPE] = default_locale.cat[LC_CTYPE];\n\t\tdefault_locale_init_done = 1;\n\t}\n\tif (!memcmp(&tmp, &default_locale, sizeof tmp)) return &default_locale;\n\tif (!memcmp(&tmp, &default_ctype_locale, sizeof tmp))\n\t\treturn &default_ctype_locale;\n\n\t/* If no builtin locale matched, attempt to allocate and copy. */\n\tif ((loc = malloc(sizeof *loc))) *loc = tmp;\n\n\treturn loc;\n}\n\nlocale_t __newlocale(int mask, const char *name, locale_t loc)\n{\n\tLOCK(__locale_lock);\n\tloc = do_newlocale(mask, name, loc);\n\tUNLOCK(__locale_lock);\n\treturn loc;\n}\n\nweak_alias(__newlocale, newlocale);\n"
  },
  {
    "path": "user.libc/src/locale/pleval.c",
    "content": "#include <stdlib.h>\n#include <ctype.h>\n#include \"pleval.h\"\n\n/*\ngrammar:\n\nStart = Expr ';'\nExpr  = Or | Or '?' Expr ':' Expr\nOr    = And | Or '||' And\nAnd   = Eq | And '&&' Eq\nEq    = Rel | Eq '==' Rel | Eq '!=' Rel\nRel   = Add | Rel '<=' Add | Rel '>=' Add | Rel '<' Add | Rel '>' Add\nAdd   = Mul | Add '+' Mul | Add '-' Mul\nMul   = Prim | Mul '*' Prim | Mul '/' Prim | Mul '%' Prim\nPrim  = '(' Expr ')' | '!' Prim | decimal | 'n'\n\ninternals:\n\nrecursive descent expression evaluator with stack depth limit.\nfor binary operators an operator-precedence parser is used.\neval* functions store the result of the parsed subexpression\nand return a pointer to the next non-space character.\n*/\n\nstruct st {\n\tunsigned long r;\n\tunsigned long n;\n\tint op;\n};\n\nstatic const char *skipspace(const char *s)\n{\n\twhile (isspace(*s)) s++;\n\treturn s;\n}\n\nstatic const char *evalexpr(struct st *st, const char *s, int d);\n\nstatic const char *evalprim(struct st *st, const char *s, int d)\n{\n\tchar *e;\n\tif (--d < 0) return \"\";\n\ts = skipspace(s);\n\tif (isdigit(*s)) {\n\t\tst->r = strtoul(s, &e, 10);\n\t\tif (e == s || st->r == -1) return \"\";\n\t\treturn skipspace(e);\n\t}\n\tif (*s == 'n') {\n\t\tst->r = st->n;\n\t\treturn skipspace(s+1);\n\t}\n\tif (*s == '(') {\n\t\ts = evalexpr(st, s+1, d);\n\t\tif (*s != ')') return \"\";\n\t\treturn skipspace(s+1);\n\t}\n\tif (*s == '!') {\n\t\ts = evalprim(st, s+1, d);\n\t\tst->r = !st->r;\n\t\treturn s;\n\t}\n\treturn \"\";\n}\n\nstatic int binop(struct st *st, int op, unsigned long left)\n{\n\tunsigned long a = left, b = st->r;\n\tswitch (op) {\n\tcase 0: st->r = a||b; return 0;\n\tcase 1: st->r = a&&b; return 0;\n\tcase 2: st->r = a==b; return 0;\n\tcase 3: st->r = a!=b; return 0;\n\tcase 4: st->r = a>=b; return 0;\n\tcase 5: st->r = a<=b; return 0;\n\tcase 6: st->r = a>b; return 0;\n\tcase 7: st->r = a<b; return 0;\n\tcase 8: st->r = a+b; return 0;\n\tcase 9: st->r = a-b; return 0;\n\tcase 10: st->r = a*b; return 0;\n\tcase 11: if (b) {st->r = a%b; return 0;} return 1;\n\tcase 12: if (b) {st->r = a/b; return 0;} return 1;\n\t}\n\treturn 1;\n}\n\nstatic const char *parseop(struct st *st, const char *s)\n{\n\tstatic const char opch[11] = \"|&=!><+-*%/\";\n\tstatic const char opch2[6] = \"|&====\";\n\tint i;\n\tfor (i=0; i<11; i++)\n\t\tif (*s == opch[i]) {\n\t\t\t/* note: >,< are accepted with or without = */\n\t\t\tif (i<6 && s[1] == opch2[i]) {\n\t\t\t\tst->op = i;\n\t\t\t\treturn s+2;\n\t\t\t}\n\t\t\tif (i>=4) {\n\t\t\t\tst->op = i+2;\n\t\t\t\treturn s+1;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\tst->op = 13;\n\treturn s;\n}\n\nstatic const char *evalbinop(struct st *st, const char *s, int minprec, int d)\n{\n\tstatic const char prec[14] = {1,2,3,3,4,4,4,4,5,5,6,6,6,0};\n\tunsigned long left;\n\tint op;\n\td--;\n\ts = evalprim(st, s, d);\n\ts = parseop(st, s);\n\tfor (;;) {\n\t\t/*\n\t\tst->r (left hand side value) and st->op are now set,\n\t\tget the right hand side or back out if op has low prec,\n\t\tif op was missing then prec[op]==0\n\t\t*/\n\t\top = st->op;\n\t\tif (prec[op] <= minprec)\n\t\t\treturn s;\n\t\tleft = st->r;\n\t\ts = evalbinop(st, s, prec[op], d);\n\t\tif (binop(st, op, left))\n\t\t\treturn \"\";\n\t}\n}\n\nstatic const char *evalexpr(struct st *st, const char *s, int d)\n{\n\tunsigned long a, b;\n\tif (--d < 0)\n\t\treturn \"\";\n\ts = evalbinop(st, s, 0, d);\n\tif (*s != '?')\n\t\treturn s;\n\ta = st->r;\n\ts = evalexpr(st, s+1, d);\n\tif (*s != ':')\n\t\treturn \"\";\n\tb = st->r;\n\ts = evalexpr(st, s+1, d);\n\tst->r = a ? b : st->r;\n\treturn s;\n}\n\nunsigned long __pleval(const char *s, unsigned long n)\n{\n\tstruct st st;\n\tst.n = n;\n\ts = evalexpr(&st, s, 100);\n\treturn *s == ';' ? st.r : -1;\n}\n"
  },
  {
    "path": "user.libc/src/locale/pleval.h",
    "content": "#ifndef PLEVAL_H\n#define PLEVAL_H\n\n#include <features.h>\n\nhidden unsigned long __pleval(const char *, unsigned long);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/locale/revjis.h",
    "content": "31,80,81,87,14,299,74,61,12,344,62,63,1280,1281,1282,1283,1284,1285,1286,1287,\n1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299,1300,1301,1302,\n1303,1312,1313,1314,1315,1316,1317,1318,1319,1320,1321,1322,1323,1324,1325,\n1326,1327,1328,1329,1330,1331,1332,1333,1334,1335,1542,1536,1537,1538,1539,\n1540,1541,1543,1544,1545,1546,1547,1548,1549,1550,1551,1552,1553,1554,1555,\n1556,1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567,1568,1584,1585,\n1586,1587,1588,1589,1591,1592,1593,1594,1595,1596,1597,1598,1599,1600,1601,\n1602,1603,1604,1605,1606,1607,1608,1609,1610,1611,1612,1613,1614,1615,1616,\n1590,29,28,33,37,38,39,40,342,343,36,35,338,75,76,263,77,337,266,267,265,268,\n300,301,302,318,303,319,281,282,60,324,326,70,315,297,298,288,287,328,329,71,\n327,325,321,65,320,68,69,322,323,285,286,283,284,316,317,1792,1803,1793,1804,\n1794,1805,1795,1806,1797,1808,1796,1807,1798,1819,1814,1809,1800,1821,1816,\n1811,1799,1815,1820,1810,1801,1817,1822,1812,1802,1818,1823,1813,258,257,260,\n259,262,261,256,93,90,92,91,349,89,88,73,72,341,340,339,0,1,2,22,24,25,26,49,\n50,51,52,53,54,55,56,57,58,264,269,43,44,32,\n768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,\n787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,\n806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,\n825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,\n844,845,846,847,848,849,850,10,11,20,21,1024,1025,1026,1027,1028,1029,1030,\n1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,\n1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,\n1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,\n1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,\n1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,\n1106,1107,1108,1109,5,27,18,19,3915,8793,6934,10843,7493,6671,7492,4379,10291,\n11294,12033,4110,4685,12034,7939,12577,5173,10521,7494,11549,10529,12035,8773,\n12036,5465,12037,4924,8719,6982,12038,12039,12040,9748,5174,9750,9538,5922,\n10770,18472,12041,7495,12042,4372,5444,5967,11080,13573,11343,9564,4868,5140,\n12043,12044,11546,11292,8263,12046,6741,9554,12049,4125,5950,5949,3909,11818,\n11817,6418,3840,12050,12051,12052,10771,12053,5969,3910,10833,5211,5212,5213,\n9025,11547,12054,12055,12056,7724,7193,7725,12061,12059,12060,5175,6402,4431,\n12058,12057,10504,6693,6692,8477,12062,10292,8006,23,12063,12065,8516,11584,\n3881,12064,4381,5411,8774,5710,12066,9731,4938,12067,3882,5951,4939,10329,\n10001,5176,4432,12102,9248,9803,12069,10011,11585,7692,6694,6742,4383,9008,\n8705,12073,3883,9026,7194,6419,11267,8493,4382,12072,11293,12068,12070,6477,\n12071,13315,12079,12082,12080,4385,10522,12074,12078,5970,6695,4869,12083,\n12075,11586,6743,12076,12081,12084,12077,5376,3884,5377,4384,13316,10840,\n10317,5971,7694,11542,10551,5655,8452,4419,7218,12088,12093,12091,12086,8462,\n12089,12092,12090,10556,12087,7693,10834,12094,12095,7171,12108,9775,10261,\n12103,10575,4373,12107,12101,12110,8241,5923,9787,16166,12109,9276,12098,5973,\n5972,12096,6969,12104,10574,8748,12100,5712,12097,12105,12099,11568,12106,\n11808,5445,5711,12111,12112,12116,3885,10543,12115,12114,12118,12117,9027,\n5713,12119,6948,8453,9028,5461,12120,5141,12121,12123,10772,5701,6672,10070,\n12122,6436,11298,12125,12290,12124,6435,7260,5656,12291,5422,12288,12289,9486,\n8283,5378,10796,12292,11548,12293,12296,12294,8237,12295,12297,12299,12298,\n10535,5142,12301,12302,4366,12300,6995,12305,12304,12303,12085,12306,7261,\n12307,11268,11064,12309,12308,12311,12310,12312,12313,3923,5908,5658,7195,\n8794,5379,8007,5974,6221,12315,11047,9253,6744,12314,12316,9277,4692,12317,\n9565,8211,12319,12320,9995,5975,11802,12321,5381,10523,8469,5456,\n9236,5714,12322,12323,9537,4158,12326,6492,12325,6437,12327,17741,12328,10784,\n12329,12330,12331,7496,6955,4870,12334,12332,11036,12333,10297,12335,12336,\n12337,9278,12341,12339,12340,12338,6466,12342,11081,11587,12343,7943,12344,\n7225,12345,8795,11550,9279,12580,12346,21252,5412,12347,10813,7239,8539,12349,\n9539,12350,12351,4621,12352,5382,9515,4185,7215,9984,12353,9280,7726,12354,\n10507,7993,4865,4872,12355,12357,5657,12356,11602,7240,10012,10539,12358,\n11351,12359,12360,9309,12361,7944,6493,5715,12362,6696,6222,9029,12364,8454,\n6478,12365,12366,8207,12363,12368,10773,6211,12367,5716,6461,9804,12371,12369,\n10330,7497,12378,4675,12372,12370,8238,12374,12373,4643,5695,12379,11532,\n12375,12380,12377,12376,11566,5976,4386,11603,7252,9271,6212,12545,12546,\n11588,11786,12548,5977,12547,4622,12549,10805,8987,11269,10552,12550,20276,\n9487,12551,4873,11026,7424,12552,10566,12556,7945,12553,5423,12554,4874,5645,\n12557,12558,12559,12560,6970,5978,11069,11079,9558,10576,12561,12562,12564,\n12566,12565,12567,4380,10795,6491,12568,8248,7425,5384,12569,10042,12570,\n12571,12572,12573,10243,5447,3908,9502,12574,7196,8008,12576,12575,7426,5952,\n12578,10013,12579,10043,8467,8525,5383,9549,8720,9805,10797,12581,8009,5652,\n12582,12583,4107,3924,4940,8455,5168,11344,12586,4374,12585,5385,12587,11088,\n12588,11569,5979,5909,12589,12591,12590,7742,4120,4157,12592,12593,5910,12594,\n5197,6673,12595,10835,6420,5177,11270,8239,10014,7004,7206,6983,\n6996,7253,10015,12598,4130,8240,5980,5924,5446,12602,8704,8541,5386,7427,\n12603,12601,4387,8517,6935,6698,4101,4687,6213,6697,12604,12605,5160,4645,\n6214,5159,9022,4100,9488,11037,6144,11352,9254,5981,5646,12614,5442,10793,\n10044,12613,4925,12608,12609,12611,12612,5178,7744,10508,12610,12606,5954,\n12607,11779,10577,9031,5953,6223,12615,9532,12619,7005,6997,12622,12620,11010,\n12617,12626,12621,12624,5925,11038,12625,12627,12629,6479,11809,12618,12616,\n12628,12623,12631,12802,12633,12637,12800,12634,12829,6472,4624,12632,12804,\n3925,12803,3844,10281,12801,12635,12630,12636,6439,12805,3926,12814,12806,\n12807,7428,10824,12812,12811,9230,12813,12810,4115,6421,7695,12808,9281,12809,\n3841,12819,11266,7430,12825,12824,12815,8482,12816,8526,12821,7429,12818,\n11075,5659,12822,12823,12820,12826,12817,12832,12837,12833,12828,12838,8208,\n12840,6145,12830,8796,12834,12827,4876,4941,4676,12835,12831,5717,12841,12839,\n8242,5161,5387,12836,5459,4131,12845,12843,13062,12848,12842,12846,12844,6699,\n12847,12850,12855,12853,12852,8721,4388,12849,12851,7431,4114,12854,4413,\n12865,7515,12861,12859,12860,12862,4124,8216,12856,12857,4697,12864,4942,\n12867,12863,12866,10509,9524,10007,12869,12868,4644,12870,12873,12872,12871,\n9752,12874,12875,12877,12876,12879,12882,12880,12878,12881,12883,12884,12885,\n12886,12887,12324,7003,6700,4434,3927,8739,12888,6403,3886,7741,12889,5926,\n6224,12891,12890,10559,12892,13056,12893,13057,13058,5718,4159,13059,13061,\n13060,\n13063,9273,13064,3860,6462,5660,8750,13065,13066,13068,13069,6467,5424,10774,\n13067,13070,6432,6146,13074,6404,8722,13071,9017,13075,7745,13073,13076,5662,\n13077,13078,6147,4639,13080,13081,13082,13079,13072,13083,13084,10819,7498,\n13086,13087,13085,13089,9751,3911,10293,13090,7516,6936,9788,4943,6474,10808,\n9489,5719,8494,13088,13091,8483,13092,13093,13095,9032,4877,21248,4160,10578,\n7499,9255,6469,13101,10524,11580,4435,13097,8217,13100,9282,9256,9283,10008,\n9004,6440,13096,4181,9237,13098,13094,7727,13102,7213,5388,13103,10567,8284,\n8997,13105,10798,13106,13111,10510,13110,13104,13107,13109,6405,10536,13112,\n8740,4436,7500,13114,13113,6215,13115,13117,13116,13119,13108,13121,13120,\n13118,6701,7728,8243,13122,7963,3916,9795,9018,13124,13123,13125,13126,13127,\n13128,10544,13129,4389,13130,11291,4623,12584,7207,8478,13131,11082,11027,\n13133,8518,9238,8479,10294,13134,13135,4186,6937,13136,3887,13137,13138,4161,\n4944,9535,10579,13142,8244,13141,5663,10810,13140,9284,13144,13143,13146,\n13145,4187,13147,7432,13149,8708,13148,10514,7254,9274,13312,6148,13313,9728,\n10045,11056,9732,13322,5143,11300,11022,13579,13314,13317,8484,10775,9257,\n13318,10820,6441,7433,13319,6703,6702,3864,5927,7946,3888,13323,13324,13321,\n4119,4878,13320,11044,10256,3847,3928,6704,3889,3842,13329,13327,11035,13330,\n13328,13326,7696,13325,10553,5955,13334,13335,7434,13331,11787,9771,13333,\n6406,13336,10295,13337,13332,11034,9789,13338,10257,13339,13343,\n13340,4390,13342,6938,13341,5720,13355,13348,13345,8771,13344,13346,13347,\n13349,13350,4945,13352,13351,13353,7501,13356,9019,4132,13354,13357,13358,\n13361,13359,13360,6705,13362,6149,13363,6745,8471,13364,13365,6713,6150,11057,\n5127,5928,13366,4663,13367,8472,13368,13570,13369,13370,13371,13373,13374,\n13375,8527,4102,6984,3873,8246,4879,6932,6151,9285,7168,4880,8775,9033,3863,\n5144,10580,6945,5169,8010,6939,11271,13376,5179,6442,4625,4162,7435,4391,\n13377,11301,7208,6979,13378,4946,9521,11016,13379,13380,10296,13382,4871,5462,\n13381,4881,7697,13386,6656,4392,13385,13383,13387,13384,9738,15148,7698,13388,\n11551,13389,13391,8797,13390,7938,6746,8495,6998,10324,8011,6956,13392,7436,\n13393,13394,3890,8473,7729,13395,9490,7437,7438,13396,8012,7439,13397,13398,\n11071,13399,5413,7169,13400,13401,6971,7691,9555,7731,10071,9729,5416,13402,\n5198,13403,5469,9518,4367,6706,13404,13569,13568,5468,13405,9239,8463,9258,\n6951,8247,11353,13571,13572,9525,6674,13574,13575,13576,4947,13577,13578,4363,\n8218,4931,13580,11015,8497,4664,13582,13584,4926,13581,13583,13586,13585,\n13587,13588,9500,5389,4420,13589,13594,13592,10582,10581,9286,13591,7219,\n13590,7761,13595,6473,13601,13602,13596,4626,13597,13606,13605,13604,13600,\n13599,13603,10583,13610,13607,13609,11345,13608,13598,7762,13611,6422,13612,\n13613,13616,13615,13614,9287,13593,13622,13618,13617,13619,13620,13623,11589,\n13624,13621,13625,4927,13626,13628,13627,13629,13630,8013,7170,\n7235,8258,6152,6423,6153,5199,13631,6424,5929,13632,11013,9762,13633,6154,\n4875,8710,5425,6707,10298,10016,13634,4948,13637,8960,13636,13635,13638,9034,\n7746,6708,7977,8498,5121,8961,13639,13640,7502,10776,13643,13642,13641,10332,\n13650,10809,13644,13646,10826,13645,13647,9991,13648,10525,13649,4882,10526,\n9742,13651,13652,6155,4883,13653,5911,11299,11272,4949,13655,8962,6156,7440,\n10046,7441,7255,9035,10584,9240,6157,10299,13656,9272,6433,5930,9036,3874,\n7245,6158,11302,13657,13658,9776,13659,11606,11788,13661,13660,4646,13824,\n13827,13828,13826,10271,7442,13830,13829,13825,13831,13832,13833,13836,13834,\n13835,13837,4163,9037,13838,5721,4437,9749,13839,9562,10554,13840,11789,13841,\n10527,13844,12032,12048,6927,9556,13845,5180,8963,3929,13846,10501,6159,8751,\n9038,11086,5912,5931,13847,13848,13854,6980,8964,5390,13849,10250,8741,13850,\n13851,5391,13852,13853,13855,9301,13856,13857,13858,13843,13842,13859,5664,\n10246,6443,10262,8965,10282,13860,7443,4133,13861,13862,11089,10047,13865,\n4188,7947,13864,13863,5665,8499,13869,13867,13866,11526,5956,7256,13868,9259,\n7197,9503,13872,13871,13870,13873,5957,13874,10331,7226,13875,10072,9504,8966,\n9231,13876,5130,7699,10251,4950,9733,13877,6709,10777,10778,4189,13882,8776,\n13879,4438,14092,13881,9743,13880,13878,6233,13884,13890,13896,13888,9275,\n13893,10300,13887,13892,11590,6710,8500,13885,5181,13895,7948,4164,13889,4439,\n13894,5392,13891,13897,13899,13909,13907,13904,13903,11607,\n13905,5393,6160,7257,13912,13898,13902,13886,4441,13906,13908,8752,6407,4375,\n13900,13911,13910,5394,8456,4677,5666,13901,13913,13916,14080,6940,14086,9039,\n13914,14084,4440,14082,14083,13917,14081,5958,11273,4884,4152,14085,9753,3852,\n10048,13883,14091,14095,11076,14088,9288,14093,7503,14094,9526,11814,14090,\n14096,6234,7978,3891,14089,14087,8249,13915,6675,8485,14108,8250,14103,14100,\n14101,6981,14104,14107,14102,7172,14105,14099,11099,11098,14109,14110,3892,\n14098,5457,3845,4885,14106,14114,14113,14118,14119,14117,14120,14112,14116,\n14121,14122,14111,6747,14115,8501,6161,14097,7700,14135,10568,14125,14126,\n14127,14134,14133,10844,4886,14131,5668,4627,14128,11543,14130,3893,14132,\n14123,14129,14136,5667,14124,11324,11274,14139,14143,8285,11608,14144,14141,\n14138,14137,14142,10511,9491,5669,14145,14140,14146,5722,4368,14154,4887,\n14152,14153,6408,14151,14149,14148,14155,14147,14157,4442,14159,14158,8967,\n14162,14160,14150,5723,14161,14165,14164,14166,14163,14167,14168,14169,10569,\n14171,14170,7198,7949,4421,4443,14172,3870,7979,14173,19234,14336,5696,14337,\n8014,14338,14339,5145,14340,14341,14342,8502,5932,11072,10779,7241,14343,8015,\n19740,10049,6985,6444,14344,8486,10502,8528,14347,14345,14348,14346,14349,\n10512,3862,10301,10050,14350,14353,7444,5146,14351,14358,7445,14352,9763,\n11325,14354,14355,14359,9289,14356,6162,7997,14373,10003,8529,10051,14604,\n10585,9040,10836,14362,4352,8777,14371,8723,14365,14372,14367,14374,14370,\n14369,9806,14363,\n4444,14361,5200,8530,14357,14360,6163,7994,7446,14368,9777,5201,4647,4678,\n7680,14376,14381,14377,5724,14382,6657,6216,7173,14364,6748,14379,6711,14380,\n3875,14375,8968,5202,5395,14378,3846,6434,7701,9041,10035,14384,8253,8457,\n6666,14385,14387,14383,10560,8988,8251,10586,6957,14399,14398,7767,5725,14392,\n7448,9543,9744,14390,8252,6999,14395,7447,14389,14394,9778,14388,5632,4668,\n14396,11530,6445,8724,14393,7995,6164,7747,4165,8219,14391,5156,5670,9006,\n14397,8254,14400,14402,8470,14408,14403,14405,10272,9042,14406,11275,11303,\n4888,3853,14404,14401,4951,4166,14407,11304,14411,8474,14418,14412,14409,\n14416,14386,14413,14417,10017,9290,14410,14414,5671,6480,7996,14422,9221,\n14419,10815,14420,14421,11053,7937,5697,14428,6676,14425,14424,9745,9492,9232,\n14426,14427,10318,9764,6658,8016,10799,4648,14596,14429,11305,14598,14594,\n14595,8255,14593,14366,14597,14592,14602,14603,9222,14605,6659,14600,5147,\n14606,14599,14610,14609,14608,14611,14613,7504,14612,14616,14614,14615,14415,\n14618,14617,14423,14619,14607,6712,14620,14621,14623,14622,14624,4445,6165,\n10587,7950,5933,14626,14629,10289,5182,14628,14627,9779,14630,5396,14632,\n14631,4889,6677,9527,5672,7763,14633,7951,9223,10302,14634,14635,14636,10519,\n13372,7973,10283,6455,10052,10018,9260,11552,14638,6959,14639,3861,5427,7980,\n10303,14640,6689,8742,6714,7702,14641,10588,4182,6715,14644,14642,14645,11544,\n14643,8026,14646,8465,14647,4953,14649,14648,14650,14651,4954,9563,\n8725,5195,6716,8256,7227,3855,14652,4353,14656,6166,14655,6410,7449,14654,\n7450,11039,6409,3894,7981,14661,7952,4134,7220,10821,6481,7451,7942,14660,\n14658,14659,8778,14853,14665,6749,6167,14663,14664,7703,14662,6670,14667,\n14666,14671,14672,14668,4609,14669,14670,10036,10304,5673,14673,7953,7452,\n8753,5414,14674,14678,4394,14675,14677,14676,7242,8743,3876,14679,14680,8969,\n11600,6690,10570,10780,14849,14682,14685,14684,14681,14848,9533,14683,14850,\n7243,14851,11306,9815,14852,14854,14855,14856,5417,4135,6168,14857,14858,7248,\n8257,12599,8221,8220,8503,6438,12113,5709,11276,10589,10333,14859,6482,8990,\n14860,11790,10781,8970,14861,4955,14862,14863,11065,11011,10837,10811,6660,\n14865,6986,10800,14867,14870,14869,4952,5183,14866,14868,14871,7768,11354,\n3880,6463,8475,6972,7506,14874,9261,14872,8458,14873,7505,11068,14875,14876,\n11335,14881,6169,9780,14878,9291,14653,14657,5166,9766,14880,7453,10019,14886,\n10073,14877,14883,14882,7982,10828,11570,10822,4395,6717,11815,14885,7764,\n14884,14879,5934,14891,14889,4396,14887,14893,14899,8487,10528,14901,10241,\n14900,9807,10782,4890,8022,7199,9010,11277,14896,14895,14897,14894,14902,\n14892,14890,14898,14888,8779,11095,6949,6483,6425,10830,4640,9005,9513,4136,\n8017,7955,5641,14904,6170,4699,14906,4691,14912,14909,8018,4650,6411,4649,\n6446,14907,5700,5674,9292,14905,3877,14908,14910,5420,5643,4891,5162,14913,\n6488,10832,6678,14914,10255,14926,4370,14915,14932,14916,11553,14923,\n9790,14931,14918,3859,14920,6171,14922,14921,14917,14928,7454,13132,5959,\n11355,14919,9043,4610,6412,14911,14927,4672,14925,14929,9293,4957,15121,11048,\n14934,4956,14941,10783,15104,15106,15110,14936,8713,9294,15114,14939,15111,\n15105,7704,15115,7954,15113,4892,11823,14933,15109,3895,14935,11033,14940,\n7681,8998,14930,15108,7769,15118,4688,5888,15120,14937,15119,15112,14938,\n15116,15117,15134,9517,15107,15130,15132,9015,11307,10325,15127,8489,15133,\n8222,15124,15137,15136,9550,15135,9545,15139,15126,5415,15129,7228,9791,15131,\n5418,15123,15125,15122,11791,4665,15128,15138,4628,6470,4156,15155,11792,\n15158,7705,15157,15156,15153,15141,15170,15140,15159,15151,15146,15143,15144,\n15152,21249,15149,6172,8999,8259,15147,15142,15145,11308,10825,15150,15160,\n15168,15161,15174,15172,15167,15166,9007,8260,15164,15162,15169,15175,10068,\n15181,15176,15179,15173,8787,10263,15163,15171,7455,11054,15191,15178,5889,\n4354,4670,15154,7456,15183,15190,7000,4689,8717,15180,15185,15189,5397,5163,\n15187,5120,9514,15186,15188,15182,15184,4671,8744,15195,15193,5960,15192,\n15360,14903,15194,15196,15197,15371,15367,14924,15366,15365,15362,15177,15364,\n15363,15369,11781,15372,5466,15368,15370,9990,15373,15377,15374,11346,15375,\n15165,15378,15379,4116,15381,5702,6912,5428,4355,11326,15383,15382,15385,5148,\n5429,4893,15388,15387,15389,4397,8726,15390,4894,15392,15391,15393,15394,\n15395,6718,7956,6400,10319,10561,11811,6740,6447,11601,15396,15397,6719,15398,\n15399,15401,15400,10807,\n7229,6987,6691,15402,15404,7682,15403,15405,15406,15407,15408,15409,15411,\n15410,15412,4356,8745,15413,6661,4651,15414,9249,13099,5122,15415,15416,10571,\n10823,9510,15417,10053,10074,11058,15418,15420,15419,15422,15421,15424,6720,\n11024,15425,15426,5123,15427,15429,15428,7748,10264,4137,10020,9044,7200,5184,\n10021,6925,15431,4895,4183,9553,15430,6173,8754,15432,15440,15433,8480,5185,\n15441,5703,5124,15439,15437,15434,11327,8991,9528,15435,15443,15442,5634,4364,\n6426,15436,15438,10806,8531,10838,15451,15452,4398,10503,11100,15616,6914,\n7457,15447,15453,4167,5398,15444,15449,8019,9808,10054,15446,10752,15448,\n15619,15617,15450,10753,9767,5186,9220,8780,15620,15618,8504,15445,4138,11309,\n15631,15630,8021,15627,11339,9493,15621,8996,4139,6174,15624,7174,15629,15628,\n15623,15626,4679,15625,9768,11533,7507,8020,15637,15635,10284,15632,15634,\n4121,6175,11793,4636,10305,11328,4611,7706,15636,15641,7458,11279,15638,15633,\n15639,11581,9298,9505,4629,4148,15645,15648,11554,11331,15655,15649,15646,\n11571,15652,7209,15654,15659,9296,15657,15651,8727,15658,15647,15653,15660,\n3931,15650,15661,7707,7230,10500,6413,15642,15656,9241,7957,4680,6448,7459,\n15644,7201,5675,15643,15665,7244,5913,15680,15674,5203,9262,15669,15678,3854,\n4113,4376,15671,8459,15662,15664,6176,15681,15676,15668,15675,11018,15673,\n15677,5935,7460,8728,15667,11278,15670,15663,9297,15666,15672,11824,6941,\n10845,15682,9997,15694,5914,7231,15684,11534,6177,15697,3917,15695,15683,\n15689,15691,11310,15686,9229,15688,15696,15690,11046,15685,6913,15709,4681,\n15687,15692,15693,8523,8505,15701,15707,15705,9224,15874,15702,15703,15679,\n5208,10265,6942,6230,11794,15699,15873,4168,8261,9816,4896,11609,11008,9009,\n15706,15708,8209,15872,15704,15698,4898,5704,15886,15881,8023,4674,7232,15890,\n15883,8971,15880,9016,15915,15877,15876,15885,15879,15878,15884,7936,15875,\n15887,15888,4897,15893,15892,15894,15897,9250,15891,15895,5698,8536,15889,\n9754,15896,15901,15899,15902,15905,15898,6217,9735,15640,11347,15900,15904,\n8532,15903,15882,20040,15908,15912,15910,15906,15907,15911,15909,10285,15917,\n15914,15913,15916,9523,15918,8788,8524,7940,15919,15921,15920,15700,15922,\n9542,15923,4399,9299,4612,5187,6973,6449,11782,7749,4169,15925,15924,15928,\n8729,15931,15926,15930,15929,9247,3896,11604,15933,4103,15935,15934,15932,\n15927,10754,15937,15936,4170,15939,10513,15938,11028,7462,8210,7461,11610,\n15945,8024,15941,15946,4171,15944,9792,15940,15943,7463,10032,15947,6960,8025,\n15950,15942,5638,15948,11311,15951,21253,7214,15952,15953,9741,15955,15956,\n9746,9300,15958,15960,11572,15957,15959,4172,15954,12858,15961,8262,6679,\n15963,15962,7683,12600,15964,16128,15949,15965,16129,9817,16130,16131,16132,\n16133,9021,16135,16134,16136,16137,6974,10306,11083,16138,16139,8245,6915,\n16140,16141,16142,10545,10022,16143,9782,8972,16144,4422,5196,11045,11029,\n4371,11795,10801,10505,7958,16145,9506,5890,16146,6451,16148,16147,16149,\n16150,16151,5149,16152,16153,\n5891,10023,16155,7508,16154,5399,16156,16158,16157,16159,5936,16160,5448,8223,\n6236,16162,16163,16161,6988,9511,5400,16165,8715,16164,11796,9793,16168,16170,\n16167,11059,16169,16171,11555,16175,16174,8789,9740,5892,16173,16172,11280,\n11281,16176,4173,6229,6721,16177,16178,16180,7202,16182,16181,16183,4652,\n16185,16184,16187,16186,5915,11527,5419,4357,5449,4928,11591,16189,16191,\n16192,4400,16188,6680,8992,16190,16195,6989,16193,5661,10024,16194,16221,\n16200,5916,5188,16197,11356,11535,8533,16199,16201,11573,5430,10075,9769,\n16202,16204,16207,16203,16206,5961,4140,16208,7759,16205,11579,16211,21251,\n16209,16212,16198,16210,6427,16213,16214,11357,16215,16216,16196,16217,4899,\n6916,16218,16219,16220,4122,16384,10266,16385,4867,16386,16387,16388,16390,\n16391,16389,10290,16393,16392,16395,16394,16396,16397,16399,16398,6232,16401,\n16400,4900,7730,9243,16402,7959,6681,4184,16403,11312,10562,16404,9251,11282,\n6178,7708,8746,12563,8973,4423,16405,16406,16411,16409,16408,14625,4613,16407,\n3897,9993,10025,11536,16412,16410,8763,7941,9994,10252,16414,11531,5676,16415,\n16413,10037,16416,16417,3898,7509,16422,16419,9548,16418,5125,16425,16420,\n16421,16424,16423,10244,8225,8224,5150,16426,16427,16428,16430,16429,4149,\n16438,10055,16432,16434,16436,7709,16437,16435,6943,16431,16433,10273,7464,\n16440,16439,16441,6917,6414,9302,16442,9002,16444,11520,16443,8264,16449,\n16451,16452,8755,16450,16447,16445,16446,16448,16455,16453,16454,16456,16458,\n16459,16460,16461,16457,\n16463,16462,16464,11556,16467,16465,16466,4929,11101,10537,16469,16468,16470,\n16471,16475,16472,16473,16474,16476,16477,16640,16641,16642,9998,9263,16643,\n9809,10259,16644,16645,9225,4614,6179,16646,16647,16648,6664,16650,16649,\n16651,16652,10056,16653,16654,21064,16655,16656,16657,6669,16658,9781,10814,\n4141,4150,16659,16661,16660,9295,7960,15384,16662,11040,16663,4901,10038,\n16664,16665,16666,11067,11060,8989,8265,16668,7233,7465,16671,16670,16669,\n10076,4902,5896,16677,16674,7710,11025,16673,16675,16676,16672,16678,16679,\n8974,4930,8772,16680,16681,16684,7750,9507,16685,10802,16682,16683,16688,\n16687,16686,16690,16689,16691,16693,16692,10540,7221,11557,16694,9494,16695,\n16696,16700,16698,16699,16697,16701,16702,16703,16704,11030,16705,11087,16706,\n8749,9801,5450,8730,16707,5401,7983,16708,6428,16709,16710,5893,6452,16712,\n9269,6453,5165,10755,9770,9270,6203,16714,7466,11537,6180,5894,9986,16716,\n16718,5962,16717,9045,16720,4630,16715,10057,4111,6475,11825,16719,16721,\n10538,7992,16723,16724,16722,4653,16730,16729,6918,16731,16726,16732,16727,\n10039,16725,16728,16897,16896,10816,16733,3914,16899,16898,7467,16900,8226,\n16902,16901,16903,16711,16713,16905,16904,6919,11592,6961,16906,5654,5151,\n5126,6722,11283,16912,16911,8227,16908,16910,7210,7711,16909,16907,9737,7468,\n10267,6454,9303,16913,16914,16936,5431,11804,8212,16915,4401,9046,10496,16916,\n5209,16917,16919,16920,9736,16921,16922,16923,5432,4402,9508,7175,6723,16924,\n7176,4393,10274,16925,\n10058,8228,16928,16929,9800,7712,16926,8768,16927,7469,3899,5128,16930,9047,\n16931,7974,11020,10242,16932,16933,8756,11558,16935,16934,6990,16937,3919,\n16940,16938,4403,5677,16939,6181,6225,10565,16941,10803,16943,7984,4142,4377,\n3851,16942,16944,16945,7510,16946,4654,16948,5705,5189,16949,5460,16950,8027,\n9516,7999,6484,16951,8769,8266,16953,16955,16952,16954,5633,16956,5637,5190,\n11313,16958,16959,4109,16962,4693,16961,16960,16964,16957,16965,11528,16966,\n16967,13139,16969,16968,16970,16971,11540,16972,20302,7470,16973,16974,7222,\n9495,16975,8711,16976,8731,16977,5380,12318,8764,6930,4903,16978,17153,16981,\n5191,16980,17155,16979,7471,16983,16984,9226,16985,4669,7737,10307,16987,8519,\n16982,16986,16988,6490,17157,10253,9989,9304,5433,17156,17154,10004,16989,\n8765,9306,9305,6485,17175,17159,17161,17164,17165,17162,17163,17160,17158,\n17152,10542,4404,17172,17169,17174,17173,9810,11014,6682,17167,17176,17171,\n17170,17166,17168,4904,8732,8028,9985,17181,9987,8000,17178,10030,17182,10546,\n8762,17177,17179,17180,17183,6947,9509,17188,17187,17184,11797,17193,17197,\n17194,17190,17191,17196,17185,12596,17192,17186,17195,17201,4905,17198,17199,\n17200,17203,17202,10069,17204,11611,10572,17209,17206,17205,7985,17208,17210,\n17207,17214,17211,17212,17189,17213,17215,17216,10533,17217,11073,5421,5640,\n17218,10515,7751,11023,17219,11538,9811,8229,9747,7212,3871,17224,17222,17220,\n4864,7472,17225,17223,17221,17229,17228,17227,17226,17230,17231,7961,17232,\n17234,\n17233,5937,8215,17236,9307,17235,17237,10516,8267,6182,17238,11559,17240,\n17241,17242,17243,6724,17244,5678,5193,5129,17408,11090,6183,17245,17411,\n11077,9755,10258,7234,17410,6962,6184,6725,5192,10517,17409,8230,10785,6486,\n6726,9020,17414,11582,6456,17415,7713,17417,7473,6415,17416,7177,5917,8231,\n17412,17418,17413,5679,17421,17425,5706,17420,17429,6185,11340,3867,17426,\n5194,17423,17424,9308,17422,17419,4615,8003,5895,17431,17428,17430,17427,5680,\n8466,17432,8269,17445,17441,17435,17439,7001,3900,17434,17442,17446,6186,\n11061,9013,17436,17444,17433,8733,17438,3868,11049,17437,5434,10059,8268,\n11567,7246,17485,17447,8029,17443,17448,17450,9048,17453,17449,10547,4906,\n11050,3901,17452,11612,17451,4174,9547,17454,17461,17455,17462,17458,9818,\n6953,17460,17457,17463,17456,7203,10756,7211,17459,17471,17467,17470,17468,\n17472,17466,17440,7986,10026,17469,17464,8192,5681,7178,7684,8213,17475,17477,\n17478,17474,17476,17465,17473,17481,17480,10841,5642,17479,17483,17482,17486,\n17488,6683,17484,17489,17490,17491,17497,9242,17493,17492,17494,17495,17496,\n17498,17499,4907,17500,17501,17664,17665,17666,17667,17668,17669,17671,17670,\n17672,17673,17674,17677,17675,17676,6464,5682,8757,10002,7247,9772,10060,\n17678,14156,17679,17681,11332,17680,17683,17682,11314,17684,10077,17685,17688,\n17687,17686,17689,5649,8193,5152,17693,17690,17691,17694,17695,17692,4104,\n4358,17697,17698,17699,11329,7179,17701,17700,7752,17702,17703,17704,4932,\n4908,17705,17706,10812,11330,\n11315,11798,6188,17709,6963,17708,17710,6920,8496,17711,6187,11062,17712,\n17713,17714,17715,17716,6921,11084,17718,8734,17717,17720,17719,17721,7962,\n17722,17723,10520,17724,8270,17725,17726,11613,17729,17728,17727,8975,17730,\n7685,17731,17732,11799,17733,17734,17736,17735,9988,9560,11805,9992,17738,\n7474,10249,17739,17737,4909,5939,6727,10061,5897,10786,17742,17740,6189,6190,\n3912,6471,9784,3902,17747,8735,9783,8506,17749,17745,17748,17743,17746,10757,\n5940,3932,17744,17751,17752,9496,5402,17925,9756,6728,5403,7975,11813,11021,\n17750,7987,5170,17753,17755,17754,17756,8709,9757,8976,17922,17921,17757,7732,\n10308,17924,17923,6191,11826,17940,17928,17929,6991,17927,6231,17926,17930,\n8977,10497,8194,8507,17934,17935,17931,17932,17933,6192,17941,17937,10309,\n10827,10247,17936,17939,17938,10787,17942,17943,8214,17944,17946,17950,17947,\n17945,9758,17948,17949,4369,17956,17951,17952,17953,8448,17955,17954,17957,\n17958,17959,7714,4424,17960,11574,6922,7180,6729,8758,17961,17962,4112,17963,\n17964,17965,17966,17967,5404,14601,17968,8004,17969,6954,17970,12047,17971,\n10557,4923,8195,7223,10320,7181,17972,6193,17973,10027,17987,17975,8488,9812,\n5918,17974,8196,17976,9049,17978,17977,17980,17979,17981,17983,17982,4910,\n17984,17985,17986,6416,11560,17988,7686,4175,17989,17990,17991,3921,17992,\n17993,10310,6950,17995,4616,3857,17994,17997,9773,7715,4405,10758,5692,5435,\n17996,4425,4866,4176,18001,11593,8508,10275,18013,4406,18011,18009,18000,\n17998,17999,\n6978,5451,8790,9520,4144,18003,18002,18008,18004,18007,11055,18006,4407,4700,\n18010,18012,5683,18178,18187,18188,3850,18195,3920,18186,18185,18180,18179,\n18177,18176,8770,8538,18182,18181,18184,8271,5684,4128,18183,6194,8272,18201,\n18202,4408,4365,18199,18189,18197,18204,18198,18196,18005,18194,18190,4911,\n18192,18203,18193,18205,18191,9819,11336,18200,18222,18214,7770,5157,5436,\n18209,4410,7475,18212,6457,9264,18217,10573,18208,4409,5941,10248,18218,18206,\n18215,18225,18210,18211,9497,18216,18213,10759,18219,3903,18207,18221,18220,\n9802,18227,18238,4701,18241,18223,18228,11341,18237,11316,11529,8791,4682,\n10321,18243,9472,3856,18236,18232,8273,18226,18234,18239,9739,3849,18231,\n18240,10327,18235,18230,7476,7182,6923,11063,10278,18246,18255,18233,4694,\n7511,18244,18249,8274,18245,18252,8766,18253,11317,18242,4631,18248,18251,\n11019,18254,18247,18250,10760,11776,18258,18265,18257,6946,18224,10541,11009,\n18264,18263,18259,18260,4117,18262,18256,9012,18261,3933,8449,10530,18266,\n18432,10040,18269,7477,6952,18434,5405,18435,10328,18268,18229,18267,11822,\n9473,10322,18442,18448,18449,18436,9813,18446,18438,18440,18450,18439,18443,\n4177,9540,18444,18447,18437,8197,18441,6662,7716,5647,11091,11096,7249,18454,\n18452,11821,18451,11348,18453,18455,18456,18459,18457,9474,18458,10028,18445,\n7250,18460,18465,8275,18464,18433,18466,8232,18461,18463,18462,15376,15361,\n18468,18467,11349,16667,18469,18470,18471,5942,5171,18473,12348,5204,11545,\n5458,18474,18475,8781,18476,\n9561,3865,4418,18481,18482,18477,6684,18478,9761,18479,18480,18490,18484,\n18487,18483,18485,18486,6967,18488,8736,5685,4641,18491,4638,18496,18492,\n18495,10009,18493,18494,10279,10041,18497,8540,18507,18503,4426,18501,10761,\n18502,18499,18500,18505,18508,18506,18504,18498,8759,18515,11017,18513,18514,\n18509,18511,18512,18510,8005,11800,18519,18520,18688,7689,18522,18525,18517,\n18516,18689,4411,18523,18690,18524,18521,8978,18518,9799,18694,11290,18693,\n18692,18701,18695,18703,11333,18706,18697,18698,18702,18705,18704,18696,18699,\n18716,18709,18707,18708,18713,18714,4617,5153,18712,18691,18711,18715,18710,\n18717,18719,18718,18721,18720,18489,18725,18722,18723,18724,18726,5707,18728,\n18727,7183,6195,15622,18729,7216,4632,18730,4145,7478,18731,6196,18732,3904,\n10268,18733,7753,18740,18737,8782,18738,18735,5437,18734,18741,5653,8509,\n18747,18743,8468,18742,18745,18736,18746,18748,10062,18744,18749,18751,5938,\n18739,3872,18750,6458,11605,18752,18753,8276,11521,18754,11284,18755,18756,\n10563,18757,6431,11522,18762,18763,7479,18761,11334,18758,18760,7964,7773,\n18759,18764,10498,18766,18765,4683,10762,18767,18779,18769,18770,18771,18772,\n18776,18777,18775,18773,18768,18774,18778,20246,4359,18781,5438,18780,18945,\n18944,18947,18946,18948,7184,18949,18950,18951,7965,11318,18952,10499,9765,\n18953,18954,5898,5131,18955,6730,9760,18956,4655,18957,18959,11350,18958,7717,\n18960,18961,18962,4912,18963,18964,18965,18966,4656,18967,18968,18969,4433,\n7687,18970,18971,18972,5919,9050,18973,\n5686,7733,18976,9475,18975,5648,18974,8534,5132,18977,18978,7480,5708,18979,\n10763,7998,5205,11092,8233,18980,7718,8783,7481,18981,18984,18985,6429,8481,\n18983,7482,10269,18982,6731,4146,18989,5687,6733,6732,11820,18988,18987,8198,\n5164,11810,4633,7483,18986,18991,18992,18990,5943,11295,6734,9734,18995,7967,\n8737,11285,18998,5963,7966,18994,18999,5964,18996,18997,18993,8001,9512,8718,\n4412,10063,5154,8979,19002,19000,8747,7968,4913,19001,7738,11561,11807,19003,\n19014,8980,19013,19010,19018,19011,19007,9051,19006,19004,11264,6735,19008,\n19005,19012,7251,5920,8537,10788,4153,3905,9476,19016,19015,9541,19020,19009,\n19019,19021,5899,19017,6197,6964,19022,11319,19025,19028,19026,10260,19023,\n5439,19027,19029,19033,19030,19032,19031,19034,6928,19036,19035,10311,19200,\n5688,19037,19201,19202,5155,17696,7512,19203,5965,19204,19205,6685,14637,\n19206,19207,7185,19208,19209,19210,19211,19212,8714,19213,19215,19214,9477,\n19216,10764,19217,19218,19219,19220,9529,7484,19221,6218,12045,19222,19223,\n10270,19224,19232,19225,19227,19226,19228,10789,19229,19230,19231,19233,4620,\n9030,10312,6465,6198,10286,4414,10029,19236,4914,7988,19235,19240,8792,11074,\n19238,19239,5133,19241,9794,8510,10064,9244,19237,10790,4427,19243,11783,8993,\n11812,6736,19242,8464,19259,8199,9559,10287,19246,6686,6737,7485,9796,5900,\n19245,19244,10313,6944,9265,19248,19249,6199,19247,19250,19251,19253,8450,\n19252,4933,19255,19254,19256,19258,19260,19261,7989,6958,19262,4657,\n19263,8277,19264,19265,10314,5134,19266,8981,4154,19267,6992,7765,8460,19270,\n19269,19268,19276,19274,19271,19273,19272,19275,5206,19279,7990,19280,5944,\n19277,19278,11784,8982,8200,19281,19284,19282,19283,11320,9478,19287,19285,\n19286,19288,19464,19291,19292,19290,19289,9052,19456,19460,19457,19293,19458,\n19459,19466,19461,7991,19463,19465,19462,19468,7186,19467,19469,19470,19473,\n19472,19471,19475,19474,11093,19477,19476,19478,19479,19481,19480,7719,19482,\n5452,19483,19485,19486,19487,19484,19488,6965,19489,5135,5650,5901,19490,9551,\n9245,19491,19494,6931,19493,19492,5689,19495,4658,19497,6459,19496,19505,\n19499,19501,10564,19498,19500,19504,19502,5136,19503,19506,9785,11575,7187,\n19507,11265,19509,19508,19512,11296,19511,4684,19510,19515,19514,19513,9233,\n19516,19517,19518,6219,5636,19519,19520,19521,7720,19522,6924,19523,19524,\n12544,12381,19525,17487,19526,8707,7690,9759,19527,10548,9011,6237,8712,4105,\n10839,7734,5693,5440,10549,19528,19530,19529,4415,9557,19531,9814,9234,19532,\n7217,19534,11041,19549,19536,19537,9000,8511,8278,9479,19535,5172,19544,19541,\n19716,9480,8767,19538,9053,9266,19539,19543,7743,9798,9003,7969,19542,8461,\n8451,19540,3848,11777,19545,8512,7188,7721,19547,19546,3918,19548,10254,19718,\n9530,7754,8760,5463,19717,11286,4126,10550,4416,19712,19713,19714,19715,9498,\n8706,3906,19719,19720,21250,8476,19721,4178,8235,5902,11321,19722,9227,8279,\n6966,19723,19726,7236,19724,8202,8201,3907,11562,19728,10065,19730,19729,\n19727,16963,4915,19533,19732,19731,19733,11287,9536,10765,19734,6968,19735,\n19736,19737,9216,3913,6200,11801,19741,5651,19738,19739,10323,4659,11288,5406,\n9267,19742,19743,19744,9217,19746,19745,9522,19747,7189,6975,9786,8784,6993,\n7755,19748,19749,7740,19750,19751,19752,11342,7190,19754,19753,6201,6226,6687,\n19757,7237,19756,19755,8520,5966,7970,9999,7192,19758,7486,19761,19759,19760,\n19763,19762,7513,19764,19765,19766,10031,6450,6976,19767,19768,11523,7204,\n11085,11563,19769,5441,19770,9218,19773,4695,7722,19771,19772,9023,10804,5467,\n19775,19776,19774,19778,9534,4642,19782,19779,19781,19777,20014,19780,11594,\n5945,19790,9235,19785,19788,19786,19791,19792,19784,19797,4179,19783,9996,\n19787,7487,6202,10791,5443,7205,9499,8204,19795,19789,19794,11042,8983,19796,\n19793,8203,19800,19799,19798,10766,7258,19801,10558,4147,10277,8785,5207,\n19803,6204,6667,19802,7756,7757,19968,19970,7514,19969,19971,5426,10276,6977,\n11778,19805,6487,11806,19973,19972,19974,19804,9544,9268,9014,19979,8738,\n19975,19976,5644,19978,5903,19977,7488,4696,19983,6430,8280,9001,4634,19981,\n19982,8994,19980,19984,19990,19993,19992,9228,19985,19986,19989,19991,5407,\n19994,19988,19987,19998,19999,20000,19997,19996,7489,9481,19995,20004,20002,\n20003,20001,8535,20005,20006,20008,4916,20007,11097,20019,20009,20012,20010,\n20011,20013,20015,20016,20017,20020,20018,20021,20023,20022,8984,11078,20024,\n8205,20025,10531,20026,4618,4123,4918,4917,20027,20028,20029,20030,20031,4919,\n4660,6205,10005,20033,20032,20034,4155,20037,20036,20035,20038,20041,3878,\n20039,20043,20042,20045,20044,20046,9485,20047,20048,20050,20049,10315,20051,\n20052,6468,20053,20054,10792,8234,3843,8490,20055,10316,20058,20056,6206,\n20057,5921,10532,20060,20224,20061,20225,4096,7735,7259,4920,20226,9797,20228,\n4097,20227,8995,11564,9482,20059,11525,5904,11322,5464,11539,5639,8513,17920,\n20229,4619,7758,4661,20231,20232,20230,5699,6460,7490,4098,11576,20234,19725,\n20233,20237,20235,20236,20238,20239,11595,20240,20241,7976,10010,7772,4934,\n11289,4428,7191,5946,20244,20243,6738,20245,20242,6663,20249,18700,12597,7766,\n20247,11524,9552,4106,8002,6933,10518,4127,11596,11338,20250,9252,7002,20251,\n20252,7723,20253,11597,20248,20255,20257,20256,20254,20258,20259,8281,4417,\n20260,11031,20261,20262,11785,14864,20263,20264,20265,20269,20266,20267,20268,\n20270,7971,11094,7972,20271,10066,20272,21042,11051,20273,20274,20275,4662,\n20277,7736,20278,5635,20279,20283,20281,20282,4690,20280,20284,20285,3879,\n20286,20287,7491,20288,5158,20291,20290,20289,19024,10555,20292,20293,20294,\n20295,20296,20297,4921,20298,20299,9730,20301,4378,20304,20303,4099,5408,\n10534,8985,6401,6207,7238,7739,20306,20305,11297,4935,10033,9531,7771,11565,\n5690,20309,20308,10794,9483,4143,20310,20307,10288,11337,20311,20312,20314,\n8521,4666,4667,20313,4936,5905,4937,9246,11583,5947,20315,20316,20317,20480,\n20482,20481,10326,20483,20484,20485,20486,20488,20487,20489,10067,17707,7688,\n5137,20490,\n20491,12555,15386,10034,3930,3866,6739,10767,7517,20492,11070,20493,11323,\n4129,6688,20494,4429,20495,20496,20498,20499,20501,20497,20500,4922,20502,\n20503,20504,20505,20506,20508,20507,20510,20513,20509,20511,20512,20514,5409,\n6994,20515,20516,6208,20517,4637,9774,20518,20519,8761,9546,20520,9820,8491,\n4151,5453,5454,8786,20525,5455,4430,20524,20522,20523,20521,20535,20526,20527,\n20528,20529,20531,20530,7224,20532,20534,5138,20533,8282,5906,20536,8492,\n20537,9484,20538,20543,20541,20540,20542,20539,20545,20544,20547,5410,20546,\n20548,20549,20551,20550,20552,20554,20553,6235,20555,20556,4635,20557,20558,\n7760,20559,20560,20561,20562,6209,20563,20564,20565,20566,20567,10000,20569,\n10245,20570,20568,20572,20571,20573,20736,20737,20738,20739,20740,20741,20742,\n20743,20744,20745,20746,20747,20748,20749,15380,20750,17239,5139,4608,6417,\n20752,20751,11012,20754,20755,20753,20756,10817,20757,5210,11780,20758,20760,\n3869,20761,10506,20759,20762,20763,20764,20765,20766,10829,6668,6489,8206,\n20767,20770,20768,20771,5968,20769,20772,20773,20774,20778,6665,8515,20779,\n20776,20775,20777,5694,20783,20782,20781,3858,20793,20789,20790,20786,20792,\n20788,4673,11819,20791,20787,20785,20784,20795,20798,20797,20796,10280,20794,\n3922,20799,20801,4686,20780,4118,20803,20802,20800,8716,10831,11577,20804,\n20805,20806,20807,20808,8986,20809,10006,20814,20810,20811,10768,11043,9519,\n20815,20816,9501,20813,20812,4361,20824,20823,4180,20821,20820,20818,4698,\n20817,6929,4360,6210,20827,20826,20825,\n20822,20828,20829,20996,20995,20997,4108,20992,20993,6227,11032,20994,10769,\n21002,20998,21003,21000,20999,5691,21004,21005,21006,21001,20819,21007,9024,\n21011,21012,21010,21009,21015,21008,21013,21014,21017,21016,21019,21020,21021,\n11816,21018,8522,6476,21022,21023,21024,21025,21026,5907,21027,21028,6926,\n21029,21030,21031,21032,21035,21033,11803,21034,11598,21036,11578,21037,9821,\n21038,21040,21041,21039,6220,11052,10818,13654,15423,10842,4362,21043,5167,\n21044,21045,21046,6228,21047,16179,11066,8514,21048,21050,21049,21051,21052,\n21053,21054,21055,21056,21057,21058,21059,21060,21061,21062,21063,9219,5948,\n21065,8236,21066,21067,10240,21068,21069,16918,19257,20300,21070,21071,21073,\n21074,21075,11599,21072,21076,21077,21079,21078,21081,21082,21080,11541,21083,\n21084,16947,21085,9,83,79,82,84,41,42,85,59,3,4,30,527,528,529,530,531,532,\n533,534,535,536,6,7,66,64,67,8,86,544,545,546,547,548,549,550,551,552,553,554,\n555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,45,46,15,17,13,\n576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,\n595,596,597,598,599,600,601,47,34,48,16,78,\n"
  },
  {
    "path": "user.libc/src/locale/setlocale.c",
    "content": "#include <locale.h>\n#include <stdlib.h>\n#include <string.h>\n#include \"locale_impl.h\"\n#include \"libc.h\"\n#include \"lock.h\"\n\nstatic char buf[LC_ALL*(LOCALE_NAME_MAX+1)];\n\nchar *setlocale(int cat, const char *name)\n{\n\tconst struct __locale_map *lm;\n\n\tif ((unsigned)cat > LC_ALL) return 0;\n\n\tLOCK(__locale_lock);\n\n\t/* For LC_ALL, setlocale is required to return a string which\n\t * encodes the current setting for all categories. The format of\n\t * this string is unspecified, and only the following code, which\n\t * performs both the serialization and deserialization, depends\n\t * on the format, so it can easily be changed if needed. */\n\tif (cat == LC_ALL) {\n\t\tint i;\n\t\tif (name) {\n\t\t\tstruct __locale_struct tmp_locale;\n\t\t\tchar part[LOCALE_NAME_MAX+1] = \"C.UTF-8\";\n\t\t\tconst char *p = name;\n\t\t\tfor (i=0; i<LC_ALL; i++) {\n\t\t\t\tconst char *z = __strchrnul(p, ';');\n\t\t\t\tif (z-p <= LOCALE_NAME_MAX) {\n\t\t\t\t\tmemcpy(part, p, z-p);\n\t\t\t\t\tpart[z-p] = 0;\n\t\t\t\t\tif (*z) p = z+1;\n\t\t\t\t}\n\t\t\t\tlm = __get_locale(i, part);\n\t\t\t\tif (lm == LOC_MAP_FAILED) {\n\t\t\t\t\tUNLOCK(__locale_lock);\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t\ttmp_locale.cat[i] = lm;\n\t\t\t}\n\t\t\tlibc.global_locale = tmp_locale;\n\t\t}\n\t\tchar *s = buf;\n\t\tconst char *part;\n\t\tint same = 0;\n\t\tfor (i=0; i<LC_ALL; i++) {\n\t\t\tconst struct __locale_map *lm =\n\t\t\t\tlibc.global_locale.cat[i];\n\t\t\tif (lm == libc.global_locale.cat[0]) same++;\n\t\t\tpart = lm ? lm->name : \"C\";\n\t\t\tsize_t l = strlen(part);\n\t\t\tmemcpy(s, part, l);\n\t\t\ts[l] = ';';\n\t\t\ts += l+1;\n\t\t}\n\t\t*--s = 0;\n\t\tUNLOCK(__locale_lock);\n\t\treturn same==LC_ALL ? (char *)part : buf;\n\t}\n\n\tif (name) {\n\t\tlm = __get_locale(cat, name);\n\t\tif (lm == LOC_MAP_FAILED) {\n\t\t\tUNLOCK(__locale_lock);\n\t\t\treturn 0;\n\t\t}\n\t\tlibc.global_locale.cat[cat] = lm;\n\t} else {\n\t\tlm = libc.global_locale.cat[cat];\n\t}\n\tchar *ret = lm ? (char *)lm->name : \"C\";\n\n\tUNLOCK(__locale_lock);\n\n\treturn ret;\n}\n"
  },
  {
    "path": "user.libc/src/locale/strcoll.c",
    "content": "#include <string.h>\n#include <locale.h>\n#include \"locale_impl.h\"\n\nint __strcoll_l(const char *l, const char *r, locale_t loc)\n{\n\treturn strcmp(l, r);\n}\n\nint strcoll(const char *l, const char *r)\n{\n\treturn __strcoll_l(l, r, CURRENT_LOCALE);\n}\n\nweak_alias(__strcoll_l, strcoll_l);\n"
  },
  {
    "path": "user.libc/src/locale/strfmon.c",
    "content": "#include <stdio.h>\n#include <ctype.h>\n#include <stdarg.h>\n#include <monetary.h>\n#include <errno.h>\n#include \"locale_impl.h\"\n\nstatic ssize_t vstrfmon_l(char *s, size_t n, locale_t loc, const char *fmt, va_list ap)\n{\n\tsize_t l;\n\tdouble x;\n\tint fill, nogrp, negpar, nosym, left, intl;\n\tint lp, rp, w, fw;\n\tchar *s0=s;\n\tfor (; n && *fmt; ) {\n\t\tif (*fmt != '%') {\n\t\tliteral:\n\t\t\t*s++ = *fmt++;\n\t\t\tn--;\n\t\t\tcontinue;\n\t\t}\n\t\tfmt++;\n\t\tif (*fmt == '%') goto literal;\n\n\t\tfill = ' ';\n\t\tnogrp = 0;\n\t\tnegpar = 0;\n\t\tnosym = 0;\n\t\tleft = 0;\n\t\tfor (; ; fmt++) {\n\t\t\tswitch (*fmt) {\n\t\t\tcase '=':\n\t\t\t\tfill = *++fmt;\n\t\t\t\tcontinue;\n\t\t\tcase '^':\n\t\t\t\tnogrp = 1;\n\t\t\t\tcontinue;\n\t\t\tcase '(':\n\t\t\t\tnegpar = 1;\n\t\t\tcase '+':\n\t\t\t\tcontinue;\n\t\t\tcase '!':\n\t\t\t\tnosym = 1;\n\t\t\t\tcontinue;\n\t\t\tcase '-':\n\t\t\t\tleft = 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tfor (fw=0; isdigit(*fmt); fmt++)\n\t\t\tfw = 10*fw + (*fmt-'0');\n\t\tlp = 0;\n\t\trp = 2;\n\t\tif (*fmt=='#') for (lp=0, fmt++; isdigit(*fmt); fmt++)\n\t\t\tlp = 10*lp + (*fmt-'0');\n\t\tif (*fmt=='.') for (rp=0, fmt++; isdigit(*fmt); fmt++)\n\t\t\trp = 10*rp + (*fmt-'0');\n\n\t\tintl = *fmt++ == 'i';\n\n\t\tw = lp + 1 + rp;\n\t\tif (!left && fw>w) w = fw;\n\n\t\tx = va_arg(ap, double);\n\t\tl = snprintf(s, n, \"%*.*f\", w, rp, x);\n\t\tif (l >= n) {\n\t\t\terrno = E2BIG;\n\t\t\treturn -1;\n\t\t}\n\t\ts += l;\n\t\tn -= l;\n\t}\n\treturn s-s0;\n}\n\nssize_t strfmon_l(char *restrict s, size_t n, locale_t loc, const char *restrict fmt, ...)\n{\n\tva_list ap;\n\tssize_t ret;\n\n\tva_start(ap, fmt);\n\tret = vstrfmon_l(s, n, loc, fmt, ap);\n\tva_end(ap);\n\n\treturn ret;\n}\n\n\nssize_t strfmon(char *restrict s, size_t n, const char *restrict fmt, ...)\n{\n\tva_list ap;\n\tssize_t ret;\n\n\tva_start(ap, fmt);\n\tret = vstrfmon_l(s, n, CURRENT_LOCALE, fmt, ap);\n\tva_end(ap);\n\n\treturn ret;\n}\n"
  },
  {
    "path": "user.libc/src/locale/strxfrm.c",
    "content": "#include <string.h>\n#include <locale.h>\n#include \"locale_impl.h\"\n\n/* collate only by code points */\nsize_t __strxfrm_l(char *restrict dest, const char *restrict src, size_t n, locale_t loc)\n{\n\tsize_t l = strlen(src);\n\tif (n > l) strcpy(dest, src);\n\treturn l;\n}\n\nsize_t strxfrm(char *restrict dest, const char *restrict src, size_t n)\n{\n\treturn __strxfrm_l(dest, src, n, CURRENT_LOCALE);\n}\n\nweak_alias(__strxfrm_l, strxfrm_l);\n"
  },
  {
    "path": "user.libc/src/locale/textdomain.c",
    "content": "#include <libintl.h>\n#include <string.h>\n#include <stdlib.h>\n#include <errno.h>\n#include <limits.h>\n\nstatic char *current_domain;\n\nchar *__gettextdomain()\n{\n\treturn current_domain ? current_domain : \"messages\";\n}\n\nchar *textdomain(const char *domainname)\n{\n\tif (!domainname) return __gettextdomain();\n\n\tsize_t domlen = strlen(domainname);\n\tif (domlen > NAME_MAX) {\n\t\terrno = EINVAL;\n\t\treturn 0;\n\t}\n\n\tif (!current_domain) {\n\t\tcurrent_domain = malloc(NAME_MAX+1);\n\t\tif (!current_domain) return 0;\n\t}\n\n\tmemcpy(current_domain, domainname, domlen+1);\n\n\treturn current_domain;\n}\n\nchar *gettext(const char *msgid)\n{\n\treturn dgettext(0, msgid);\n}\n\nchar *ngettext(const char *msgid1, const char *msgid2, unsigned long int n)\n{\n\treturn dngettext(0, msgid1, msgid2, n);\n}\n"
  },
  {
    "path": "user.libc/src/locale/uselocale.c",
    "content": "#include \"locale_impl.h\"\n#include \"pthread_impl.h\"\n#include \"libc.h\"\n\nlocale_t __uselocale(locale_t new)\n{\n\tpthread_t self = __pthread_self();\n\tlocale_t old = self->locale;\n\tlocale_t global = &libc.global_locale;\n\n\tif (new) self->locale = new == LC_GLOBAL_LOCALE ? global : new;\n\n\treturn old == global ? LC_GLOBAL_LOCALE : old;\n}\n\nweak_alias(__uselocale, uselocale);\n"
  },
  {
    "path": "user.libc/src/locale/wcscoll.c",
    "content": "#include <wchar.h>\n#include <locale.h>\n#include \"locale_impl.h\"\n\n/* FIXME: stub */\nint __wcscoll_l(const wchar_t *l, const wchar_t *r, locale_t locale)\n{\n\treturn wcscmp(l, r);\n}\n\nint wcscoll(const wchar_t *l, const wchar_t *r)\n{\n\treturn __wcscoll_l(l, r, CURRENT_LOCALE);\n}\n\nweak_alias(__wcscoll_l, wcscoll_l);\n"
  },
  {
    "path": "user.libc/src/locale/wcsxfrm.c",
    "content": "#include <wchar.h>\n#include <locale.h>\n#include \"locale_impl.h\"\n\n/* collate only by code points */\nsize_t __wcsxfrm_l(wchar_t *restrict dest, const wchar_t *restrict src, size_t n, locale_t loc)\n{\n\tsize_t l = wcslen(src);\n\tif (l < n) {\n\t\twmemcpy(dest, src, l+1);\n\t} else if (n) {\n\t\twmemcpy(dest, src, n-1);\n\t\tdest[n-1] = 0;\n\t}\n\treturn l;\n}\n\nsize_t wcsxfrm(wchar_t *restrict dest, const wchar_t *restrict src, size_t n)\n{\n\treturn __wcsxfrm_l(dest, src, n, CURRENT_LOCALE);\n}\n\nweak_alias(__wcsxfrm_l, wcsxfrm_l);\n"
  },
  {
    "path": "user.libc/src/malloc/calloc.c",
    "content": "#include <stdlib.h>\n#include <stdint.h>\n#include <string.h>\n#include <errno.h>\n#include \"dynlink.h\"\n\nstatic size_t mal0_clear(char *p, size_t n)\n{\n\tconst size_t pagesz = 4096; /* arbitrary */\n\tif (n < pagesz) return n;\n#ifdef __GNUC__\n\ttypedef uint64_t __attribute__((__may_alias__)) T;\n#else\n\ttypedef unsigned char T;\n#endif\n\tchar *pp = p + n;\n\tsize_t i = (uintptr_t)pp & (pagesz - 1);\n\tfor (;;) {\n\t\tpp = memset(pp - i, 0, i);\n\t\tif (pp - p < pagesz) return pp - p;\n\t\tfor (i = pagesz; i; i -= 2*sizeof(T), pp -= 2*sizeof(T))\n\t\t        if (((T *)pp)[-1] | ((T *)pp)[-2])\n\t\t\t\tbreak;\n\t}\n}\n\nstatic int allzerop(void *p)\n{\n\treturn 0;\n}\nweak_alias(allzerop, __malloc_allzerop);\n\nvoid *calloc(size_t m, size_t n)\n{\n\tif (n && m > (size_t)-1/n) {\n\t\terrno = ENOMEM;\n\t\treturn 0;\n\t}\n\tn *= m;\n\tvoid *p = malloc(n);\n\tif (!p || (!__malloc_replaced && __malloc_allzerop(p)))\n\t\treturn p;\n\tn = mal0_clear(p, n);\n\treturn memset(p, 0, n);\n}\n"
  },
  {
    "path": "user.libc/src/malloc/free.c",
    "content": "#include <stdlib.h>\n\nvoid free(void *p)\n{\n\treturn __libc_free(p);\n}\n"
  },
  {
    "path": "user.libc/src/malloc/libc_calloc.c",
    "content": "#define calloc __libc_calloc\n#define malloc __libc_malloc\n\n#include \"calloc.c\"\n"
  },
  {
    "path": "user.libc/src/malloc/lite_malloc.c",
    "content": "#include <stdlib.h>\n#include <stdint.h>\n#include <limits.h>\n#include <errno.h>\n#include <sys/mman.h>\n#include \"libc.h\"\n#include \"lock.h\"\n#include \"syscall.h\"\n#include \"fork_impl.h\"\n\n#define ALIGN 16\n\n/* This function returns true if the interval [old,new]\n * intersects the 'len'-sized interval below &libc.auxv\n * (interpreted as the main-thread stack) or below &b\n * (the current stack). It is used to defend against\n * buggy brk implementations that can cross the stack. */\n\nstatic int traverses_stack_p(uintptr_t old, uintptr_t new)\n{\n\tconst uintptr_t len = 8<<20;\n\tuintptr_t a, b;\n\n\tb = (uintptr_t)libc.auxv;\n\ta = b > len ? b-len : 0;\n\tif (new>a && old<b) return 1;\n\n\tb = (uintptr_t)&b;\n\ta = b > len ? b-len : 0;\n\tif (new>a && old<b) return 1;\n\n\treturn 0;\n}\n\nstatic volatile int lock[1];\nvolatile int *const __bump_lockptr = lock;\n\nstatic void *__simple_malloc(size_t n)\n{\n#if 0\n\tstatic uintptr_t brk, cur, end;\n\tstatic unsigned mmap_step;\n\tsize_t align=1;\n\tvoid *p;\n\n\tif (n > SIZE_MAX/2) {\n\t\terrno = ENOMEM;\n\t\treturn 0;\n\t}\n\n\tif (!n) n++;\n\twhile (align<n && align<ALIGN)\n\t\talign += align;\n\n\tLOCK(lock);\n\n\tcur += -cur & align-1;\n\n\tif (n > end-cur) {\n\t\tsize_t req = n - (end-cur) + PAGE_SIZE-1 & -PAGE_SIZE;\n\n\t\tif (!cur) {\n\t\t\t// brk = __syscall(SYS_brk, 0);\n\t\t\tbrk += -brk & PAGE_SIZE-1;\n\t\t\tcur = end = brk;\n\t\t}\n\n\t\tif (brk == end && req < SIZE_MAX-brk\n\t\t    && !traverses_stack_p(brk, brk+req)\n\t\t    && __syscall(SYS_brk, brk+req)==brk+req) {\n\t\t\tbrk = end += req;\n\t\t} else {\n\t\t\tint new_area = 0;\n\t\t\treq = n + PAGE_SIZE-1 & -PAGE_SIZE;\n\t\t\t/* Only make a new area rather than individual mmap\n\t\t\t * if wasted space would be over 1/8 of the map. */\n\t\t\tif (req-n > req/8) {\n\t\t\t\t/* Geometric area size growth up to 64 pages,\n\t\t\t\t * bounding waste by 1/8 of the area. */\n\t\t\t\tsize_t min = PAGE_SIZE<<(mmap_step/2);\n\t\t\t\tif (min-n > end-cur) {\n\t\t\t\t\tif (req < min) {\n\t\t\t\t\t\treq = min;\n\t\t\t\t\t\tif (mmap_step < 12)\n\t\t\t\t\t\t\tmmap_step++;\n\t\t\t\t\t}\n\t\t\t\t\tnew_area = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t\tvoid *mem = __mmap(0, req, PROT_READ|PROT_WRITE,\n\t\t\t\tMAP_PRIVATE|MAP_ANONYMOUS, -1, 0);\n\t\t\tif (mem == MAP_FAILED || !new_area) {\n\t\t\t\tUNLOCK(lock);\n\t\t\t\treturn mem==MAP_FAILED ? 0 : mem;\n\t\t\t}\n\t\t\tcur = (uintptr_t)mem;\n\t\t\tend = cur + req;\n\t\t}\n\t}\n\n\tp = (void *)cur;\n\tcur += n;\n\tUNLOCK(lock);\n\treturn p;\n#endif\n\treturn NULL;\n}\n\nweak_alias(__simple_malloc, __libc_malloc_impl);\n\nvoid *__libc_malloc(size_t n)\n{\n\treturn __libc_malloc_impl(n);\n}\n\nstatic void *default_malloc(size_t n)\n{\n\treturn __libc_malloc_impl(n);\n}\n\nweak_alias(default_malloc, malloc);\n"
  },
  {
    "path": "user.libc/src/malloc/mallocng/aligned_alloc.c",
    "content": "#include <stdlib.h>\n#include <errno.h>\n#include \"meta.h\"\n\nvoid *aligned_alloc(size_t align, size_t len)\n{\n\tif ((align & -align) != align) {\n\t\terrno = EINVAL;\n\t\treturn 0;\n\t}\n\n\tif (len > SIZE_MAX - align || align >= (1ULL<<31)*UNIT) {\n\t\terrno = ENOMEM;\n\t\treturn 0;\n\t}\n\n\tif (DISABLE_ALIGNED_ALLOC) {\n\t\terrno = ENOMEM;\n\t\treturn 0;\n\t}\n\n\tif (align <= UNIT) align = UNIT;\n\n\tunsigned char *p = malloc(len + align - UNIT);\n\tstruct meta *g = get_meta(p);\n\tint idx = get_slot_index(p);\n\tsize_t stride = get_stride(g);\n\tunsigned char *start = g->mem->storage + stride*idx;\n\tunsigned char *end = g->mem->storage + stride*(idx+1) - IB;\n\tsize_t adj = -(uintptr_t)p & (align-1);\n\n\tif (!adj) {\n\t\tset_size(p, end, len);\n\t\treturn p;\n\t}\n\tp += adj;\n\tuint32_t offset = (size_t)(p-g->mem->storage)/UNIT;\n\tif (offset <= 0xffff) {\n\t\t*(uint16_t *)(p-2) = offset;\n\t\tp[-4] = 0;\n\t} else {\n\t\t// use a 32-bit offset if 16-bit doesn't fit. for this,\n\t\t// 16-bit field must be zero, [-4] byte nonzero.\n\t\t*(uint16_t *)(p-2) = 0;\n\t\t*(uint32_t *)(p-8) = offset;\n\t\tp[-4] = 1;\n\t}\n\tp[-3] = idx;\n\tset_size(p, end, len);\n\t// store offset to aligned enframing. this facilitates cycling\n\t// offset and also iteration of heap for debugging/measurement.\n\t// for extreme overalignment it won't fit but these are classless\n\t// allocations anyway.\n\t*(uint16_t *)(start - 2) = (size_t)(p-start)/UNIT;\n\tstart[-3] = 7<<5;\n\treturn p;\n}\n"
  },
  {
    "path": "user.libc/src/malloc/mallocng/donate.c",
    "content": "#include <stdlib.h>\n#include <stdint.h>\n#include <limits.h>\n#include <string.h>\n#include <sys/mman.h>\n#include <errno.h>\n\n#include \"meta.h\"\n\nstatic void donate(unsigned char *base, size_t len)\n{\n\tuintptr_t a = (uintptr_t)base;\n\tuintptr_t b = a + len;\n\ta += -a & (UNIT-1);\n\tb -= b & (UNIT-1);\n\tmemset(base, 0, len);\n\tfor (int sc=47; sc>0 && b>a; sc-=4) {\n\t\tif (b-a < (size_classes[sc]+1)*UNIT) continue;\n\t\tstruct meta *m = alloc_meta();\n\t\tm->avail_mask = 0;\n\t\tm->freed_mask = 1;\n\t\tm->mem = (void *)a;\n\t\tm->mem->meta = m;\n\t\tm->last_idx = 0;\n\t\tm->freeable = 0;\n\t\tm->sizeclass = sc;\n\t\tm->maplen = 0;\n\t\t*((unsigned char *)m->mem+UNIT-4) = 0;\n\t\t*((unsigned char *)m->mem+UNIT-3) = 255;\n\t\tm->mem->storage[size_classes[sc]*UNIT-4] = 0;\n\t\tqueue(&ctx.active[sc], m);\n\t\ta += (size_classes[sc]+1)*UNIT;\n\t}\n}\n\nvoid __malloc_donate(char *start, char *end)\n{\n\tdonate((void *)start, end-start);\n}\n"
  },
  {
    "path": "user.libc/src/malloc/mallocng/free.c",
    "content": "#define _BSD_SOURCE\n#include <stdlib.h>\n#include <sys/mman.h>\n\n#include \"meta.h\"\n\nstruct mapinfo {\n\tvoid *base;\n\tsize_t len;\n};\n\nstatic struct mapinfo nontrivial_free(struct meta *, int);\n\nstatic struct mapinfo free_group(struct meta *g)\n{\n\tstruct mapinfo mi = { 0 };\n\tint sc = g->sizeclass;\n\tif (sc < 48) {\n\t\tctx.usage_by_class[sc] -= g->last_idx+1;\n\t}\n\tif (g->maplen) {\n\t\tstep_seq();\n\t\trecord_seq(sc);\n\t\tmi.base = g->mem;\n\t\tmi.len = g->maplen*4096UL;\n\t} else {\n\t\tvoid *p = g->mem;\n\t\tstruct meta *m = get_meta(p);\n\t\tint idx = get_slot_index(p);\n\t\tg->mem->meta = 0;\n\t\t// not checking size/reserved here; it's intentionally invalid\n\t\tmi = nontrivial_free(m, idx);\n\t}\n\tfree_meta(g);\n\treturn mi;\n}\n\nstatic int okay_to_free(struct meta *g)\n{\n\tint sc = g->sizeclass;\n\n\tif (!g->freeable) return 0;\n\n\t// always free individual mmaps not suitable for reuse\n\tif (sc >= 48 || get_stride(g) < UNIT*size_classes[sc])\n\t\treturn 1;\n\n\t// always free groups allocated inside another group's slot\n\t// since recreating them should not be expensive and they\n\t// might be blocking freeing of a much larger group.\n\tif (!g->maplen) return 1;\n\n\t// if there is another non-full group, free this one to\n\t// consolidate future allocations, reduce fragmentation.\n\tif (g->next != g) return 1;\n\n\t// free any group in a size class that's not bouncing\n\tif (!is_bouncing(sc)) return 1;\n\n\tsize_t cnt = g->last_idx+1;\n\tsize_t usage = ctx.usage_by_class[sc];\n\n\t// if usage is high enough that a larger count should be\n\t// used, free the low-count group so a new one will be made.\n\tif (9*cnt <= usage && cnt < 20)\n\t\treturn 1;\n\n\t// otherwise, keep the last group in a bouncing class.\n\treturn 0;\n}\n\nstatic struct mapinfo nontrivial_free(struct meta *g, int i)\n{\n\tuint32_t self = 1u<<i;\n\tint sc = g->sizeclass;\n\tuint32_t mask = g->freed_mask | g->avail_mask;\n\n\tif (mask+self == (2u<<g->last_idx)-1 && okay_to_free(g)) {\n\t\t// any multi-slot group is necessarily on an active list\n\t\t// here, but single-slot groups might or might not be.\n\t\tif (g->next) {\n\t\t\tassert(sc < 48);\n\t\t\tint activate_new = (ctx.active[sc]==g);\n\t\t\tdequeue(&ctx.active[sc], g);\n\t\t\tif (activate_new && ctx.active[sc])\n\t\t\t\tactivate_group(ctx.active[sc]);\n\t\t}\n\t\treturn free_group(g);\n\t} else if (!mask) {\n\t\tassert(sc < 48);\n\t\t// might still be active if there were no allocations\n\t\t// after last available slot was taken.\n\t\tif (ctx.active[sc] != g) {\n\t\t\tqueue(&ctx.active[sc], g);\n\t\t}\n\t}\n\ta_or(&g->freed_mask, self);\n\treturn (struct mapinfo){ 0 };\n}\n\nvoid free(void *p)\n{\n\tif (!p) return;\n\n\tstruct meta *g = get_meta(p);\n\tint idx = get_slot_index(p);\n\tsize_t stride = get_stride(g);\n\tunsigned char *start = g->mem->storage + stride*idx;\n\tunsigned char *end = start + stride - IB;\n\tget_nominal_size(p, end);\n\tuint32_t self = 1u<<idx, all = (2u<<g->last_idx)-1;\n\t((unsigned char *)p)[-3] = 255;\n\t// invalidate offset to group header, and cycle offset of\n\t// used region within slot if current offset is zero.\n\t*(uint16_t *)((char *)p-2) = 0;\n\n\t// release any whole pages contained in the slot to be freed\n\t// unless it's a single-slot group that will be unmapped.\n\tif (((uintptr_t)(start-1) ^ (uintptr_t)end) >= 2*PGSZ && g->last_idx) {\n\t\tunsigned char *base = start + (-(uintptr_t)start & (PGSZ-1));\n\t\tsize_t len = (end-base) & -PGSZ;\n\t\tif (len) madvise(base, len, MADV_FREE);\n\t}\n\n\t// atomic free without locking if this is neither first or last slot\n\tfor (;;) {\n\t\tuint32_t freed = g->freed_mask;\n\t\tuint32_t avail = g->avail_mask;\n\t\tuint32_t mask = freed | avail;\n\t\tassert(!(mask&self));\n\t\tif (!freed || mask+self==all) break;\n\t\tif (!MT)\n\t\t\tg->freed_mask = freed+self;\n\t\telse if (a_cas(&g->freed_mask, freed, freed+self)!=freed)\n\t\t\tcontinue;\n\t\treturn;\n\t}\n\n\twrlock();\n\tstruct mapinfo mi = nontrivial_free(g, idx);\n\tunlock();\n\tif (mi.len) munmap(mi.base, mi.len);\n}\n"
  },
  {
    "path": "user.libc/src/malloc/mallocng/glue.h",
    "content": "#ifndef MALLOC_GLUE_H\n#define MALLOC_GLUE_H\n\n#include <stdint.h>\n#include <sys/mman.h>\n#include <pthread.h>\n#include <unistd.h>\n#include <elf.h>\n#include <string.h>\n#include \"atomic.h\"\n#include \"syscall.h\"\n#include \"libc.h\"\n#include \"lock.h\"\n#include \"dynlink.h\"\n\n// use macros to appropriately namespace these.\n#define size_classes __malloc_size_classes\n#define ctx __malloc_context\n#define alloc_meta __malloc_alloc_meta\n#define is_allzero __malloc_allzerop\n#define dump_heap __dump_heap\n\n#define malloc __libc_malloc_impl\n#define realloc __libc_realloc\n#define free __libc_free\n\n#if USE_REAL_ASSERT\n#include <assert.h>\n#else\n#undef assert\n#define assert(x) do { if (!(x)) a_crash(); } while(0)\n#endif\n\nextern uintptr_t __brk(uintptr_t ptr);\n\n#define mmap __mmap\n#define madvise __madvise\n#define mremap __mremap\n\n#define DISABLE_ALIGNED_ALLOC (__malloc_replaced && !__aligned_alloc_replaced)\n\nstatic inline uint64_t get_random_secret()\n{\n\tuint64_t secret = (uintptr_t)&secret * 1103515245;\n\tfor (size_t i=0; libc.auxv[i]; i+=2)\n\t\tif (libc.auxv[i]==AT_RANDOM)\n\t\t\tmemcpy(&secret, (char *)libc.auxv[i+1]+8, sizeof secret);\n\treturn secret;\n}\n\n#ifndef PAGESIZE\n#define PAGESIZE PAGE_SIZE\n#endif\n\n#define MT (libc.need_locks)\n\n#define RDLOCK_IS_EXCLUSIVE 1\n\n__attribute__((__visibility__(\"hidden\")))\nextern int __malloc_lock[1];\n\n#define LOCK_OBJ_DEF \\\nint __malloc_lock[1]; \\\nvoid __malloc_atfork(int who) { malloc_atfork(who); }\n\nstatic inline void rdlock()\n{\n\tif (MT) LOCK(__malloc_lock);\n}\nstatic inline void wrlock()\n{\n\tif (MT) LOCK(__malloc_lock);\n}\nstatic inline void unlock()\n{\n\tUNLOCK(__malloc_lock);\n}\nstatic inline void upgradelock()\n{\n}\nstatic inline void resetlock()\n{\n\t__malloc_lock[0] = 0;\n}\n\nstatic inline void malloc_atfork(int who)\n{\n\tif (who<0) rdlock();\n\telse if (who>0) resetlock();\n\telse unlock();\n}\n\n#endif\n"
  },
  {
    "path": "user.libc/src/malloc/mallocng/malloc.c",
    "content": "#include <stdlib.h>\n#include <stdint.h>\n#include <limits.h>\n#include <string.h>\n#include <sys/mman.h>\n#include <errno.h>\n\n#include \"libc.h\"\n#include \"meta.h\"\n\nLOCK_OBJ_DEF;\n\nconst uint16_t size_classes[] = {\n\t1, 2, 3, 4, 5, 6, 7, 8,\n\t9, 10, 12, 15,\n\t18, 20, 25, 31,\n\t36, 42, 50, 63,\n\t72, 84, 102, 127,\n\t146, 170, 204, 255,\n\t292, 340, 409, 511,\n\t584, 682, 818, 1023,\n\t1169, 1364, 1637, 2047,\n\t2340, 2730, 3276, 4095,\n\t4680, 5460, 6552, 8191,\n};\n\nstatic const uint8_t small_cnt_tab[][3] = {\n\t{ 30, 30, 30 },\n\t{ 31, 15, 15 },\n\t{ 20, 10, 10 },\n\t{ 31, 15, 7 },\n\t{ 25, 12, 6 },\n\t{ 21, 10, 5 },\n\t{ 18, 8, 4 },\n\t{ 31, 15, 7 },\n\t{ 28, 14, 6 },\n};\n\nstatic const uint8_t med_cnt_tab[4] = { 28, 24, 20, 32 };\n\nstruct malloc_context ctx = { 0 };\n\nstruct meta *alloc_meta(void)\n{\n\tstruct meta *m;\n\tunsigned char *p;\n\tif (!ctx.init_done) {\n#ifndef PAGESIZE\n\t\tctx.pagesize = get_page_size();\n#endif\n\t\tctx.secret = get_random_secret();\n\t\tctx.init_done = 1;\n\t}\n\tsize_t pagesize = PGSZ;\n\tif (pagesize < 4096) pagesize = 4096;\n\tif ((m = dequeue_head(&ctx.free_meta_head))) return m;\n\tif (!ctx.avail_meta_count) {\n\t\tint need_unprotect = 1;\n\t\tif (!ctx.avail_meta_area_count && ctx.brk!=-1) {\n\t\t\tuintptr_t new = ctx.brk + pagesize;\n\t\t\tint need_guard = 0;\n\t\t\tif (!ctx.brk) {\n\t\t\t\tneed_guard = 1;\n\t\t\t\tctx.brk = __brk(0);\n\t\t\t\t// some ancient kernels returned _ebss\n\t\t\t\t// instead of next page as initial brk.\n\t\t\t\tctx.brk += -ctx.brk & (pagesize-1);\n\t\t\t\tnew = ctx.brk + 2*pagesize;\n\t\t\t}\n\t\t\tif (__brk(new) != new) {\n\t\t\t\tctx.brk = -1;\n\t\t\t} else {\n\t\t\t\tif (need_guard) mmap((void *)ctx.brk, pagesize,\n\t\t\t\t\tPROT_NONE, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);\n\t\t\t\tctx.brk = new;\n\t\t\t\tctx.avail_meta_areas = (void *)(new - pagesize);\n\t\t\t\tctx.avail_meta_area_count = pagesize>>12;\n\t\t\t\tneed_unprotect = 0;\n\t\t\t}\n\t\t}\n\t\tif (!ctx.avail_meta_area_count) {\n\t\t\tsize_t n = 2UL << ctx.meta_alloc_shift;\n\t\t\tp = mmap(0, n*pagesize, PROT_NONE,\n\t\t\t\tMAP_PRIVATE|MAP_ANON, -1, 0);\n\t\t\tif (p==MAP_FAILED) return 0;\n\t\t\tctx.avail_meta_areas = p + pagesize;\n\t\t\tctx.avail_meta_area_count = (n-1)*(pagesize>>12);\n\t\t\tctx.meta_alloc_shift++;\n\t\t}\n\t\tp = ctx.avail_meta_areas;\n\t\tif ((uintptr_t)p & (pagesize-1)) need_unprotect = 0;\n\t\tif (need_unprotect)\n\t\t\tif (mprotect(p, pagesize, PROT_READ|PROT_WRITE)\n\t\t\t    && errno != ENOSYS)\n\t\t\t\treturn 0;\n\t\tctx.avail_meta_area_count--;\n\t\tctx.avail_meta_areas = p + 4096;\n\t\tif (ctx.meta_area_tail) {\n\t\t\tctx.meta_area_tail->next = (void *)p;\n\t\t} else {\n\t\t\tctx.meta_area_head = (void *)p;\n\t\t}\n\t\tctx.meta_area_tail = (void *)p;\n\t\tctx.meta_area_tail->check = ctx.secret;\n\t\tctx.avail_meta_count = ctx.meta_area_tail->nslots\n\t\t\t= (4096-sizeof(struct meta_area))/sizeof *m;\n\t\tctx.avail_meta = ctx.meta_area_tail->slots;\n\t}\n\tctx.avail_meta_count--;\n\tm = ctx.avail_meta++;\n\tm->prev = m->next = 0;\n\treturn m;\n}\n\nstatic uint32_t try_avail(struct meta **pm)\n{\n\tstruct meta *m = *pm;\n\tuint32_t first;\n\tif (!m) return 0;\n\tuint32_t mask = m->avail_mask;\n\tif (!mask) {\n\t\tif (!m) return 0;\n\t\tif (!m->freed_mask) {\n\t\t\tdequeue(pm, m);\n\t\t\tm = *pm;\n\t\t\tif (!m) return 0;\n\t\t} else {\n\t\t\tm = m->next;\n\t\t\t*pm = m;\n\t\t}\n\n\t\tmask = m->freed_mask;\n\n\t\t// skip fully-free group unless it's the only one\n\t\t// or it's a permanently non-freeable group\n\t\tif (mask == (2u<<m->last_idx)-1 && m->freeable) {\n\t\t\tm = m->next;\n\t\t\t*pm = m;\n\t\t\tmask = m->freed_mask;\n\t\t}\n\n\t\t// activate more slots in a not-fully-active group\n\t\t// if needed, but only as a last resort. prefer using\n\t\t// any other group with free slots. this avoids\n\t\t// touching & dirtying as-yet-unused pages.\n\t\tif (!(mask & ((2u<<m->mem->active_idx)-1))) {\n\t\t\tif (m->next != m) {\n\t\t\t\tm = m->next;\n\t\t\t\t*pm = m;\n\t\t\t} else {\n\t\t\t\tint cnt = m->mem->active_idx + 2;\n\t\t\t\tint size = size_classes[m->sizeclass]*UNIT;\n\t\t\t\tint span = UNIT + size*cnt;\n\t\t\t\t// activate up to next 4k boundary\n\t\t\t\twhile ((span^(span+size-1)) < 4096) {\n\t\t\t\t\tcnt++;\n\t\t\t\t\tspan += size;\n\t\t\t\t}\n\t\t\t\tif (cnt > m->last_idx+1)\n\t\t\t\t\tcnt = m->last_idx+1;\n\t\t\t\tm->mem->active_idx = cnt-1;\n\t\t\t}\n\t\t}\n\t\tmask = activate_group(m);\n\t\tassert(mask);\n\t\tdecay_bounces(m->sizeclass);\n\t}\n\tfirst = mask&-mask;\n\tm->avail_mask = mask-first;\n\treturn first;\n}\n\nstatic int alloc_slot(int, size_t);\n\nstatic struct meta *alloc_group(int sc, size_t req)\n{\n\tsize_t size = UNIT*size_classes[sc];\n\tint i = 0, cnt;\n\tunsigned char *p;\n\tstruct meta *m = alloc_meta();\n\tif (!m) return 0;\n\tsize_t usage = ctx.usage_by_class[sc];\n\tsize_t pagesize = PGSZ;\n\tint active_idx;\n\tif (sc < 9) {\n\t\twhile (i<2 && 4*small_cnt_tab[sc][i] > usage)\n\t\t\ti++;\n\t\tcnt = small_cnt_tab[sc][i];\n\t} else {\n\t\t// lookup max number of slots fitting in power-of-two size\n\t\t// from a table, along with number of factors of two we\n\t\t// can divide out without a remainder or reaching 1.\n\t\tcnt = med_cnt_tab[sc&3];\n\n\t\t// reduce cnt to avoid excessive eagar allocation.\n\t\twhile (!(cnt&1) && 4*cnt > usage)\n\t\t\tcnt >>= 1;\n\n\t\t// data structures don't support groups whose slot offsets\n\t\t// in units don't fit in 16 bits.\n\t\twhile (size*cnt >= 65536*UNIT)\n\t\t\tcnt >>= 1;\n\t}\n\n\t// If we selected a count of 1 above but it's not sufficient to use\n\t// mmap, increase to 2. Then it might be; if not it will nest.\n\tif (cnt==1 && size*cnt+UNIT <= pagesize/2) cnt = 2;\n\n\t// All choices of size*cnt are \"just below\" a power of two, so anything\n\t// larger than half the page size should be allocated as whole pages.\n\tif (size*cnt+UNIT > pagesize/2) {\n\t\t// check/update bounce counter to start/increase retention\n\t\t// of freed maps, and inhibit use of low-count, odd-size\n\t\t// small mappings and single-slot groups if activated.\n\t\tint nosmall = is_bouncing(sc);\n\t\taccount_bounce(sc);\n\t\tstep_seq();\n\n\t\t// since the following count reduction opportunities have\n\t\t// an absolute memory usage cost, don't overdo them. count\n\t\t// coarse usage as part of usage.\n\t\tif (!(sc&1) && sc<32) usage += ctx.usage_by_class[sc+1];\n\n\t\t// try to drop to a lower count if the one found above\n\t\t// increases usage by more than 25%. these reduced counts\n\t\t// roughly fill an integral number of pages, just not a\n\t\t// power of two, limiting amount of unusable space.\n\t\tif (4*cnt > usage && !nosmall) {\n\t\t\tif (0);\n\t\t\telse if ((sc&3)==1 && size*cnt>8*pagesize) cnt = 2;\n\t\t\telse if ((sc&3)==2 && size*cnt>4*pagesize) cnt = 3;\n\t\t\telse if ((sc&3)==0 && size*cnt>8*pagesize) cnt = 3;\n\t\t\telse if ((sc&3)==0 && size*cnt>2*pagesize) cnt = 5;\n\t\t}\n\t\tsize_t needed = size*cnt + UNIT;\n\t\tneeded += -needed & (pagesize-1);\n\n\t\t// produce an individually-mmapped allocation if usage is low,\n\t\t// bounce counter hasn't triggered, and either it saves memory\n\t\t// or it avoids eagar slot allocation without wasting too much.\n\t\tif (!nosmall && cnt<=7) {\n\t\t\treq += IB + UNIT;\n\t\t\treq += -req & (pagesize-1);\n\t\t\tif (req<size+UNIT || (req>=4*pagesize && 2*cnt>usage)) {\n\t\t\t\tcnt = 1;\n\t\t\t\tneeded = req;\n\t\t\t}\n\t\t}\n\n\t\tp = mmap(0, needed, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);\n\t\tif (p==MAP_FAILED) {\n\t\t\tfree_meta(m);\n\t\t\treturn 0;\n\t\t}\n\t\tm->maplen = needed>>12;\n\t\tctx.mmap_counter++;\n\t\tactive_idx = (4096-UNIT)/size-1;\n\t\tif (active_idx > cnt-1) active_idx = cnt-1;\n\t\tif (active_idx < 0) active_idx = 0;\n\t} else {\n\t\tint j = size_to_class(UNIT+cnt*size-IB);\n\t\tint idx = alloc_slot(j, UNIT+cnt*size-IB);\n\t\tif (idx < 0) {\n\t\t\tfree_meta(m);\n\t\t\treturn 0;\n\t\t}\n\t\tstruct meta *g = ctx.active[j];\n\t\tp = enframe(g, idx, UNIT*size_classes[j]-IB, ctx.mmap_counter);\n\t\tm->maplen = 0;\n\t\tp[-3] = (p[-3]&31) | (6<<5);\n\t\tfor (int i=0; i<=cnt; i++)\n\t\t\tp[UNIT+i*size-4] = 0;\n\t\tactive_idx = cnt-1;\n\t}\n\tctx.usage_by_class[sc] += cnt;\n\tm->avail_mask = (2u<<active_idx)-1;\n\tm->freed_mask = (2u<<(cnt-1))-1 - m->avail_mask;\n\tm->mem = (void *)p;\n\tm->mem->meta = m;\n\tm->mem->active_idx = active_idx;\n\tm->last_idx = cnt-1;\n\tm->freeable = 1;\n\tm->sizeclass = sc;\n\treturn m;\n}\n\nstatic int alloc_slot(int sc, size_t req)\n{\n\tuint32_t first = try_avail(&ctx.active[sc]);\n\tif (first) return a_ctz_32(first);\n\n\tstruct meta *g = alloc_group(sc, req);\n\tif (!g) return -1;\n\n\tg->avail_mask--;\n\tqueue(&ctx.active[sc], g);\n\treturn 0;\n}\n\nvoid *malloc(size_t n)\n{\n\tif (size_overflows(n)) return 0;\n\tstruct meta *g;\n\tuint32_t mask, first;\n\tint sc;\n\tint idx;\n\tint ctr;\n\n\tif (n >= MMAP_THRESHOLD) {\n\t\tsize_t needed = n + IB + UNIT;\n\t\tvoid *p = mmap(0, needed, PROT_READ|PROT_WRITE,\n\t\t\tMAP_PRIVATE|MAP_ANON, -1, 0);\n\t\tif (p==MAP_FAILED) return 0;\n\t\twrlock();\n\t\tstep_seq();\n\t\tg = alloc_meta();\n\t\tif (!g) {\n\t\t\tunlock();\n\t\t\tmunmap(p, needed);\n\t\t\treturn 0;\n\t\t}\n\t\tg->mem = p;\n\t\tg->mem->meta = g;\n\t\tg->last_idx = 0;\n\t\tg->freeable = 1;\n\t\tg->sizeclass = 63;\n\t\tg->maplen = (needed+4095)/4096;\n\t\tg->avail_mask = g->freed_mask = 0;\n\t\t// use a global counter to cycle offset in\n\t\t// individually-mmapped allocations.\n\t\tctx.mmap_counter++;\n\t\tidx = 0;\n\t\tgoto success;\n\t}\n\n\tsc = size_to_class(n);\n\n\trdlock();\n\tg = ctx.active[sc];\n\n\t// use coarse size classes initially when there are not yet\n\t// any groups of desired size. this allows counts of 2 or 3\n\t// to be allocated at first rather than having to start with\n\t// 7 or 5, the min counts for even size classes.\n\tif (!g && sc>=4 && sc<32 && sc!=6 && !(sc&1) && !ctx.usage_by_class[sc]) {\n\t\tsize_t usage = ctx.usage_by_class[sc|1];\n\t\t// if a new group may be allocated, count it toward\n\t\t// usage in deciding if we can use coarse class.\n\t\tif (!ctx.active[sc|1] || (!ctx.active[sc|1]->avail_mask\n\t\t    && !ctx.active[sc|1]->freed_mask))\n\t\t\tusage += 3;\n\t\tif (usage <= 12)\n\t\t\tsc |= 1;\n\t\tg = ctx.active[sc];\n\t}\n\n\tfor (;;) {\n\t\tmask = g ? g->avail_mask : 0;\n\t\tfirst = mask&-mask;\n\t\tif (!first) break;\n\t\tif (RDLOCK_IS_EXCLUSIVE || !MT)\n\t\t\tg->avail_mask = mask-first;\n\t\telse if (a_cas(&g->avail_mask, mask, mask-first)!=mask)\n\t\t\tcontinue;\n\t\tidx = a_ctz_32(first);\n\t\tgoto success;\n\t}\n\tupgradelock();\n\n\tidx = alloc_slot(sc, n);\n\tif (idx < 0) {\n\t\tunlock();\n\t\treturn 0;\n\t}\n\tg = ctx.active[sc];\n\nsuccess:\n\tctr = ctx.mmap_counter;\n\tunlock();\n\treturn enframe(g, idx, n, ctr);\n}\n\nint is_allzero(void *p)\n{\n\tstruct meta *g = get_meta(p);\n\treturn g->sizeclass >= 48 ||\n\t\tget_stride(g) < UNIT*size_classes[g->sizeclass];\n}\n\nvoid *zalloc(size_t size)\n{\n\tvoid *mem = malloc(size);\n\tif (mem)\n\t\tmemset(mem, 0, size);\n\treturn mem;\n}\n"
  },
  {
    "path": "user.libc/src/malloc/mallocng/malloc_usable_size.c",
    "content": "#include <stdlib.h>\n#include \"meta.h\"\n\nsize_t malloc_usable_size(void *p)\n{\n\tif (!p) return 0;\n\tstruct meta *g = get_meta(p);\n\tint idx = get_slot_index(p);\n\tsize_t stride = get_stride(g);\n\tunsigned char *start = g->mem->storage + stride*idx;\n\tunsigned char *end = start + stride - IB;\n\treturn get_nominal_size(p, end);\n}\n"
  },
  {
    "path": "user.libc/src/malloc/mallocng/meta.h",
    "content": "#ifndef MALLOC_META_H\n#define MALLOC_META_H\n\n#include <stdint.h>\n#include <errno.h>\n#include <limits.h>\n#include \"glue.h\"\n\n__attribute__((__visibility__(\"hidden\")))\nextern const uint16_t size_classes[];\n\n#define MMAP_THRESHOLD 131052\n\n#define UNIT 16\n#define IB 4\n\nstruct group {\n\tstruct meta *meta;\n\tunsigned char active_idx:5;\n\tchar pad[UNIT - sizeof(struct meta *) - 1];\n\tunsigned char storage[];\n};\n\nstruct meta {\n\tstruct meta *prev, *next;\n\tstruct group *mem;\n\tvolatile int avail_mask, freed_mask;\n\tuintptr_t last_idx:5;\n\tuintptr_t freeable:1;\n\tuintptr_t sizeclass:6;\n\tuintptr_t maplen:8*sizeof(uintptr_t)-12;\n};\n\nstruct meta_area {\n\tuint64_t check;\n\tstruct meta_area *next;\n\tint nslots;\n\tstruct meta slots[];\n};\n\nstruct malloc_context {\n\tuint64_t secret;\n#ifndef PAGESIZE\n\tsize_t pagesize;\n#endif\n\tint init_done;\n\tunsigned mmap_counter;\n\tstruct meta *free_meta_head;\n\tstruct meta *avail_meta;\n\tsize_t avail_meta_count, avail_meta_area_count, meta_alloc_shift;\n\tstruct meta_area *meta_area_head, *meta_area_tail;\n\tunsigned char *avail_meta_areas;\n\tstruct meta *active[48];\n\tsize_t usage_by_class[48];\n\tuint8_t unmap_seq[32], bounces[32];\n\tuint8_t seq;\n\tuintptr_t brk;\n};\n\n__attribute__((__visibility__(\"hidden\")))\nextern struct malloc_context ctx;\n\n#ifdef PAGESIZE\n#define PGSZ PAGESIZE\n#else\n#define PGSZ ctx.pagesize\n#endif\n\n__attribute__((__visibility__(\"hidden\")))\nstruct meta *alloc_meta(void);\n\n__attribute__((__visibility__(\"hidden\")))\nint is_allzero(void *);\n\nstatic inline void queue(struct meta **phead, struct meta *m)\n{\n\tassert(!m->next);\n\tassert(!m->prev);\n\tif (*phead) {\n\t\tstruct meta *head = *phead;\n\t\tm->next = head;\n\t\tm->prev = head->prev;\n\t\tm->next->prev = m->prev->next = m;\n\t} else {\n\t\tm->prev = m->next = m;\n\t\t*phead = m;\n\t}\n}\n\nstatic inline void dequeue(struct meta **phead, struct meta *m)\n{\n\tif (m->next != m) {\n\t\tm->prev->next = m->next;\n\t\tm->next->prev = m->prev;\n\t\tif (*phead == m) *phead = m->next;\n\t} else {\n\t\t*phead = 0;\n\t}\n\tm->prev = m->next = 0;\n}\n\nstatic inline struct meta *dequeue_head(struct meta **phead)\n{\n\tstruct meta *m = *phead;\n\tif (m) dequeue(phead, m);\n\treturn m;\n}\n\nstatic inline void free_meta(struct meta *m)\n{\n\t*m = (struct meta){0};\n\tqueue(&ctx.free_meta_head, m);\n}\n\nstatic inline uint32_t activate_group(struct meta *m)\n{\n\tassert(!m->avail_mask);\n\tuint32_t mask, act = (2u<<m->mem->active_idx)-1;\n\tdo mask = m->freed_mask;\n\twhile (a_cas(&m->freed_mask, mask, mask&~act)!=mask);\n\treturn m->avail_mask = mask & act;\n}\n\nstatic inline int get_slot_index(const unsigned char *p)\n{\n\treturn p[-3] & 31;\n}\n\nstatic inline struct meta *get_meta(const unsigned char *p)\n{\n\tassert(!((uintptr_t)p & 15));\n\tint offset = *(const uint16_t *)(p - 2);\n\tint index = get_slot_index(p);\n\tif (p[-4]) {\n\t\tassert(!offset);\n\t\toffset = *(uint32_t *)(p - 8);\n\t\tassert(offset > 0xffff);\n\t}\n\tconst struct group *base = (const void *)(p - UNIT*offset - UNIT);\n\tconst struct meta *meta = base->meta;\n\tassert(meta->mem == base);\n\tassert(index <= meta->last_idx);\n\tassert(!(meta->avail_mask & (1u<<index)));\n\tassert(!(meta->freed_mask & (1u<<index)));\n\tconst struct meta_area *area = (void *)((uintptr_t)meta & -4096);\n\tassert(area->check == ctx.secret);\n\tif (meta->sizeclass < 48) {\n\t\tassert(offset >= size_classes[meta->sizeclass]*index);\n\t\tassert(offset < size_classes[meta->sizeclass]*(index+1));\n\t} else {\n\t\tassert(meta->sizeclass == 63);\n\t}\n\tif (meta->maplen) {\n\t\tassert(offset <= meta->maplen*4096UL/UNIT - 1);\n\t}\n\treturn (struct meta *)meta;\n}\n\nstatic inline size_t get_nominal_size(const unsigned char *p, const unsigned char *end)\n{\n\tsize_t reserved = p[-3] >> 5;\n\tif (reserved >= 5) {\n\t\tassert(reserved == 5);\n\t\treserved = *(const uint32_t *)(end-4);\n\t\tassert(reserved >= 5);\n\t\tassert(!end[-5]);\n\t}\n\tassert(reserved <= end-p);\n\tassert(!*(end-reserved));\n\t// also check the slot's overflow byte\n\tassert(!*end);\n\treturn end-reserved-p;\n}\n\nstatic inline size_t get_stride(const struct meta *g)\n{\n\tif (!g->last_idx && g->maplen) {\n\t\treturn g->maplen*4096UL - UNIT;\n\t} else {\n\t\treturn UNIT*size_classes[g->sizeclass];\n\t}\n}\n\nstatic inline void set_size(unsigned char *p, unsigned char *end, size_t n)\n{\n\tint reserved = end-p-n;\n\tif (reserved) end[-reserved] = 0;\n\tif (reserved >= 5) {\n\t\t*(uint32_t *)(end-4) = reserved;\n\t\tend[-5] = 0;\n\t\treserved = 5;\n\t}\n\tp[-3] = (p[-3]&31) + (reserved<<5);\n}\n\nstatic inline void *enframe(struct meta *g, int idx, size_t n, int ctr)\n{\n\tsize_t stride = get_stride(g);\n\tsize_t slack = (stride-IB-n)/UNIT;\n\tunsigned char *p = g->mem->storage + stride*idx;\n\tunsigned char *end = p+stride-IB;\n\t// cycle offset within slot to increase interval to address\n\t// reuse, facilitate trapping double-free.\n\tint off = (p[-3] ? *(uint16_t *)(p-2) + 1 : ctr) & 255;\n\tassert(!p[-4]);\n\tif (off > slack) {\n\t\tsize_t m = slack;\n\t\tm |= m>>1; m |= m>>2; m |= m>>4;\n\t\toff &= m;\n\t\tif (off > slack) off -= slack+1;\n\t\tassert(off <= slack);\n\t}\n\tif (off) {\n\t\t// store offset in unused header at offset zero\n\t\t// if enframing at non-zero offset.\n\t\t*(uint16_t *)(p-2) = off;\n\t\tp[-3] = 7<<5;\n\t\tp += UNIT*off;\n\t\t// for nonzero offset there is no permanent check\n\t\t// byte, so make one.\n\t\tp[-4] = 0;\n\t}\n\t*(uint16_t *)(p-2) = (size_t)(p-g->mem->storage)/UNIT;\n\tp[-3] = idx;\n\tset_size(p, end, n);\n\treturn p;\n}\n\nstatic inline int size_to_class(size_t n)\n{\n\tn = (n+IB-1)>>4;\n\tif (n<10) return n;\n\tn++;\n\tint i = (28-a_clz_32(n))*4 + 8;\n\tif (n>size_classes[i+1]) i+=2;\n\tif (n>size_classes[i]) i++;\n\treturn i;\n}\n\nstatic inline int size_overflows(size_t n)\n{\n\tif (n >= SIZE_MAX/2 - 4096) {\n\t\terrno = ENOMEM;\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nstatic inline void step_seq(void)\n{\n\tif (ctx.seq==255) {\n\t\tfor (int i=0; i<32; i++) ctx.unmap_seq[i] = 0;\n\t\tctx.seq = 1;\n\t} else {\n\t\tctx.seq++;\n\t}\n}\n\nstatic inline void record_seq(int sc)\n{\n\tif (sc-7U < 32) ctx.unmap_seq[sc-7] = ctx.seq;\n}\n\nstatic inline void account_bounce(int sc)\n{\n\tif (sc-7U < 32) {\n\t\tint seq = ctx.unmap_seq[sc-7];\n\t\tif (seq && ctx.seq-seq < 10) {\n\t\t\tif (ctx.bounces[sc-7]+1 < 100)\n\t\t\t\tctx.bounces[sc-7]++;\n\t\t\telse\n\t\t\t\tctx.bounces[sc-7] = 150;\n\t\t}\n\t}\n}\n\nstatic inline void decay_bounces(int sc)\n{\n\tif (sc-7U < 32 && ctx.bounces[sc-7])\n\t\tctx.bounces[sc-7]--;\n}\n\nstatic inline int is_bouncing(int sc)\n{\n\treturn (sc-7U < 32 && ctx.bounces[sc-7] >= 100);\n}\n\n#endif\n"
  },
  {
    "path": "user.libc/src/malloc/mallocng/realloc.c",
    "content": "#define _GNU_SOURCE\n#include <stdlib.h>\n#include <sys/mman.h>\n#include <string.h>\n#include \"meta.h\"\n\nvoid *realloc(void *p, size_t n)\n{\n\tif (!p) return malloc(n);\n\tif (size_overflows(n)) return 0;\n\n\tstruct meta *g = get_meta(p);\n\tint idx = get_slot_index(p);\n\tsize_t stride = get_stride(g);\n\tunsigned char *start = g->mem->storage + stride*idx;\n\tunsigned char *end = start + stride - IB;\n\tsize_t old_size = get_nominal_size(p, end);\n\tsize_t avail_size = end-(unsigned char *)p;\n\tvoid *new;\n\n\t// only resize in-place if size class matches\n\tif (n <= avail_size && n<MMAP_THRESHOLD\n\t    && size_to_class(n)+1 >= g->sizeclass) {\n\t\tset_size(p, end, n);\n\t\treturn p;\n\t}\n\n\t// use mremap if old and new size are both mmap-worthy\n\tif (g->sizeclass>=48 && n>=MMAP_THRESHOLD) {\n\t\tassert(g->sizeclass==63);\n\t\tsize_t base = (unsigned char *)p-start;\n\t\tsize_t needed = (n + base + UNIT + IB + 4095) & -4096;\n\t\tnew = g->maplen*4096UL == needed ? g->mem :\n\t\t\tmremap(g->mem, g->maplen*4096UL, needed, MREMAP_MAYMOVE);\n\t\tif (new!=MAP_FAILED) {\n\t\t\tg->mem = new;\n\t\t\tg->maplen = needed/4096;\n\t\t\tp = g->mem->storage + base;\n\t\t\tend = g->mem->storage + (needed - UNIT) - IB;\n\t\t\t*end = 0;\n\t\t\tset_size(p, end, n);\n\t\t\treturn p;\n\t\t}\n\t}\n\n\tnew = malloc(n);\n\tif (!new) return 0;\n\tmemcpy(new, p, n < old_size ? n : old_size);\n\tfree(p);\n\treturn new;\n}\n"
  },
  {
    "path": "user.libc/src/malloc/memalign.c",
    "content": "#define _BSD_SOURCE\n#include <stdlib.h>\n\nvoid *memalign(size_t align, size_t len)\n{\n\treturn aligned_alloc(align, len);\n}\n"
  },
  {
    "path": "user.libc/src/malloc/oldmalloc/aligned_alloc.c",
    "content": "#include <stdlib.h>\n#include <stdint.h>\n#include <errno.h>\n#include \"malloc_impl.h\"\n\nvoid *aligned_alloc(size_t align, size_t len)\n{\n\tunsigned char *mem, *new;\n\n\tif ((align & -align) != align) {\n\t\terrno = EINVAL;\n\t\treturn 0;\n\t}\n\n\tif (len > SIZE_MAX - align ||\n\t    (__malloc_replaced && !__aligned_alloc_replaced)) {\n\t\terrno = ENOMEM;\n\t\treturn 0;\n\t}\n\n\tif (align <= SIZE_ALIGN)\n\t\treturn malloc(len);\n\n\tif (!(mem = malloc(len + align-1)))\n\t\treturn 0;\n\n\tnew = (void *)((uintptr_t)mem + align-1 & -align);\n\tif (new == mem) return mem;\n\n\tstruct chunk *c = MEM_TO_CHUNK(mem);\n\tstruct chunk *n = MEM_TO_CHUNK(new);\n\n\tif (IS_MMAPPED(c)) {\n\t\t/* Apply difference between aligned and original\n\t\t * address to the \"extra\" field of mmapped chunk. */\n\t\tn->psize = c->psize + (new-mem);\n\t\tn->csize = c->csize - (new-mem);\n\t\treturn new;\n\t}\n\n\tstruct chunk *t = NEXT_CHUNK(c);\n\n\t/* Split the allocated chunk into two chunks. The aligned part\n\t * that will be used has the size in its footer reduced by the\n\t * difference between the aligned and original addresses, and\n\t * the resulting size copied to its header. A new header and\n\t * footer are written for the split-off part to be freed. */\n\tn->psize = c->csize = C_INUSE | (new-mem);\n\tn->csize = t->psize -= new-mem;\n\n\t__bin_chunk(c);\n\treturn new;\n}\n"
  },
  {
    "path": "user.libc/src/malloc/oldmalloc/malloc.c",
    "content": "#define _GNU_SOURCE\n#include <stdlib.h>\n#include <string.h>\n#include <limits.h>\n#include <stdint.h>\n#include <errno.h>\n#include <sys/mman.h>\n#include \"libc.h\"\n#include \"atomic.h\"\n#include \"pthread_impl.h\"\n#include \"malloc_impl.h\"\n#include \"fork_impl.h\"\n\n#define malloc __libc_malloc\n#define realloc __libc_realloc\n#define free __libc_free\n\n#if defined(__GNUC__) && defined(__PIC__)\n#define inline inline __attribute__((always_inline))\n#endif\n\nstatic struct {\n\tvolatile uint64_t binmap;\n\tstruct bin bins[64];\n\tvolatile int split_merge_lock[2];\n} mal;\n\n/* Synchronization tools */\n\nstatic inline void lock(volatile int *lk)\n{\n\tint need_locks = libc.need_locks;\n\tif (need_locks) {\n\t\twhile(a_swap(lk, 1)) __wait(lk, lk+1, 1, 1);\n\t\tif (need_locks < 0) libc.need_locks = 0;\n\t}\n}\n\nstatic inline void unlock(volatile int *lk)\n{\n\tif (lk[0]) {\n\t\ta_store(lk, 0);\n\t\tif (lk[1]) __wake(lk, 1, 1);\n\t}\n}\n\nstatic inline void lock_bin(int i)\n{\n\tlock(mal.bins[i].lock);\n\tif (!mal.bins[i].head)\n\t\tmal.bins[i].head = mal.bins[i].tail = BIN_TO_CHUNK(i);\n}\n\nstatic inline void unlock_bin(int i)\n{\n\tunlock(mal.bins[i].lock);\n}\n\nstatic int first_set(uint64_t x)\n{\n#if 1\n\treturn a_ctz_64(x);\n#else\n\tstatic const char debruijn64[64] = {\n\t\t0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,\n\t\t62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,\n\t\t63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,\n\t\t51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12\n\t};\n\tstatic const char debruijn32[32] = {\n\t\t0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,\n\t\t31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14\n\t};\n\tif (sizeof(long) < 8) {\n\t\tuint32_t y = x;\n\t\tif (!y) {\n\t\t\ty = x>>32;\n\t\t\treturn 32 + debruijn32[(y&-y)*0x076be629 >> 27];\n\t\t}\n\t\treturn debruijn32[(y&-y)*0x076be629 >> 27];\n\t}\n\treturn debruijn64[(x&-x)*0x022fdd63cc95386dull >> 58];\n#endif\n}\n\nstatic const unsigned char bin_tab[60] = {\n\t            32,33,34,35,36,36,37,37,38,38,39,39,\n\t40,40,40,40,41,41,41,41,42,42,42,42,43,43,43,43,\n\t44,44,44,44,44,44,44,44,45,45,45,45,45,45,45,45,\n\t46,46,46,46,46,46,46,46,47,47,47,47,47,47,47,47,\n};\n\nstatic int bin_index(size_t x)\n{\n\tx = x / SIZE_ALIGN - 1;\n\tif (x <= 32) return x;\n\tif (x < 512) return bin_tab[x/8-4];\n\tif (x > 0x1c00) return 63;\n\treturn bin_tab[x/128-4] + 16;\n}\n\nstatic int bin_index_up(size_t x)\n{\n\tx = x / SIZE_ALIGN - 1;\n\tif (x <= 32) return x;\n\tx--;\n\tif (x < 512) return bin_tab[x/8-4] + 1;\n\treturn bin_tab[x/128-4] + 17;\n}\n\n#if 0\nvoid __dump_heap(int x)\n{\n\tstruct chunk *c;\n\tint i;\n\tfor (c = (void *)mal.heap; CHUNK_SIZE(c); c = NEXT_CHUNK(c))\n\t\tfprintf(stderr, \"base %p size %zu (%d) flags %d/%d\\n\",\n\t\t\tc, CHUNK_SIZE(c), bin_index(CHUNK_SIZE(c)),\n\t\t\tc->csize & 15,\n\t\t\tNEXT_CHUNK(c)->psize & 15);\n\tfor (i=0; i<64; i++) {\n\t\tif (mal.bins[i].head != BIN_TO_CHUNK(i) && mal.bins[i].head) {\n\t\t\tfprintf(stderr, \"bin %d: %p\\n\", i, mal.bins[i].head);\n\t\t\tif (!(mal.binmap & 1ULL<<i))\n\t\t\t\tfprintf(stderr, \"missing from binmap!\\n\");\n\t\t} else if (mal.binmap & 1ULL<<i)\n\t\t\tfprintf(stderr, \"binmap wrongly contains %d!\\n\", i);\n\t}\n}\n#endif\n\n/* This function returns true if the interval [old,new]\n * intersects the 'len'-sized interval below &libc.auxv\n * (interpreted as the main-thread stack) or below &b\n * (the current stack). It is used to defend against\n * buggy brk implementations that can cross the stack. */\n\nstatic int traverses_stack_p(uintptr_t old, uintptr_t new)\n{\n\tconst uintptr_t len = 8<<20;\n\tuintptr_t a, b;\n\n\tb = (uintptr_t)libc.auxv;\n\ta = b > len ? b-len : 0;\n\tif (new>a && old<b) return 1;\n\n\tb = (uintptr_t)&b;\n\ta = b > len ? b-len : 0;\n\tif (new>a && old<b) return 1;\n\n\treturn 0;\n}\n\n/* Expand the heap in-place if brk can be used, or otherwise via mmap,\n * using an exponential lower bound on growth by mmap to make\n * fragmentation asymptotically irrelevant. The size argument is both\n * an input and an output, since the caller needs to know the size\n * allocated, which will be larger than requested due to page alignment\n * and mmap minimum size rules. The caller is responsible for locking\n * to prevent concurrent calls. */\n\nstatic void *__expand_heap(size_t *pn)\n{\n\tstatic uintptr_t brk;\n\tstatic unsigned mmap_step;\n\tsize_t n = *pn;\n\n\tif (n > SIZE_MAX/2 - PAGE_SIZE) {\n\t\terrno = ENOMEM;\n\t\treturn 0;\n\t}\n\tn += -n & PAGE_SIZE-1;\n\n\tif (!brk) {\n\t\tbrk = __syscall(SYS_brk, 0);\n\t\tbrk += -brk & PAGE_SIZE-1;\n\t}\n\n\tif (n < SIZE_MAX-brk && !traverses_stack_p(brk, brk+n)\n\t    && __syscall(SYS_brk, brk+n)==brk+n) {\n\t\t*pn = n;\n\t\tbrk += n;\n\t\treturn (void *)(brk-n);\n\t}\n\n\tsize_t min = (size_t)PAGE_SIZE << mmap_step/2;\n\tif (n < min) n = min;\n\tvoid *area = __mmap(0, n, PROT_READ|PROT_WRITE,\n\t\tMAP_PRIVATE|MAP_ANONYMOUS, -1, 0);\n\tif (area == MAP_FAILED) return 0;\n\t*pn = n;\n\tmmap_step++;\n\treturn area;\n}\n\nstatic struct chunk *expand_heap(size_t n)\n{\n\tstatic void *end;\n\tvoid *p;\n\tstruct chunk *w;\n\n\t/* The argument n already accounts for the caller's chunk\n\t * overhead needs, but if the heap can't be extended in-place,\n\t * we need room for an extra zero-sized sentinel chunk. */\n\tn += SIZE_ALIGN;\n\n\tp = __expand_heap(&n);\n\tif (!p) return 0;\n\n\t/* If not just expanding existing space, we need to make a\n\t * new sentinel chunk below the allocated space. */\n\tif (p != end) {\n\t\t/* Valid/safe because of the prologue increment. */\n\t\tn -= SIZE_ALIGN;\n\t\tp = (char *)p + SIZE_ALIGN;\n\t\tw = MEM_TO_CHUNK(p);\n\t\tw->psize = 0 | C_INUSE;\n\t}\n\n\t/* Record new heap end and fill in footer. */\n\tend = (char *)p + n;\n\tw = MEM_TO_CHUNK(end);\n\tw->psize = n | C_INUSE;\n\tw->csize = 0 | C_INUSE;\n\n\t/* Fill in header, which may be new or may be replacing a\n\t * zero-size sentinel header at the old end-of-heap. */\n\tw = MEM_TO_CHUNK(p);\n\tw->csize = n | C_INUSE;\n\n\treturn w;\n}\n\nstatic int adjust_size(size_t *n)\n{\n\t/* Result of pointer difference must fit in ptrdiff_t. */\n\tif (*n-1 > PTRDIFF_MAX - SIZE_ALIGN - PAGE_SIZE) {\n\t\tif (*n) {\n\t\t\terrno = ENOMEM;\n\t\t\treturn -1;\n\t\t} else {\n\t\t\t*n = SIZE_ALIGN;\n\t\t\treturn 0;\n\t\t}\n\t}\n\t*n = (*n + OVERHEAD + SIZE_ALIGN - 1) & SIZE_MASK;\n\treturn 0;\n}\n\nstatic void unbin(struct chunk *c, int i)\n{\n\tif (c->prev == c->next)\n\t\ta_and_64(&mal.binmap, ~(1ULL<<i));\n\tc->prev->next = c->next;\n\tc->next->prev = c->prev;\n\tc->csize |= C_INUSE;\n\tNEXT_CHUNK(c)->psize |= C_INUSE;\n}\n\nstatic void bin_chunk(struct chunk *self, int i)\n{\n\tself->next = BIN_TO_CHUNK(i);\n\tself->prev = mal.bins[i].tail;\n\tself->next->prev = self;\n\tself->prev->next = self;\n\tif (self->prev == BIN_TO_CHUNK(i))\n\t\ta_or_64(&mal.binmap, 1ULL<<i);\n}\n\nstatic void trim(struct chunk *self, size_t n)\n{\n\tsize_t n1 = CHUNK_SIZE(self);\n\tstruct chunk *next, *split;\n\n\tif (n >= n1 - DONTCARE) return;\n\n\tnext = NEXT_CHUNK(self);\n\tsplit = (void *)((char *)self + n);\n\n\tsplit->psize = n | C_INUSE;\n\tsplit->csize = n1-n;\n\tnext->psize = n1-n;\n\tself->csize = n | C_INUSE;\n\n\tint i = bin_index(n1-n);\n\tlock_bin(i);\n\n\tbin_chunk(split, i);\n\n\tunlock_bin(i);\n}\n\nvoid *malloc(size_t n)\n{\n\tstruct chunk *c;\n\tint i, j;\n\tuint64_t mask;\n\n\tif (adjust_size(&n) < 0) return 0;\n\n\tif (n > MMAP_THRESHOLD) {\n\t\tsize_t len = n + OVERHEAD + PAGE_SIZE - 1 & -PAGE_SIZE;\n\t\tchar *base = __mmap(0, len, PROT_READ|PROT_WRITE,\n\t\t\tMAP_PRIVATE|MAP_ANONYMOUS, -1, 0);\n\t\tif (base == (void *)-1) return 0;\n\t\tc = (void *)(base + SIZE_ALIGN - OVERHEAD);\n\t\tc->csize = len - (SIZE_ALIGN - OVERHEAD);\n\t\tc->psize = SIZE_ALIGN - OVERHEAD;\n\t\treturn CHUNK_TO_MEM(c);\n\t}\n\n\ti = bin_index_up(n);\n\tif (i<63 && (mal.binmap & (1ULL<<i))) {\n\t\tlock_bin(i);\n\t\tc = mal.bins[i].head;\n\t\tif (c != BIN_TO_CHUNK(i) && CHUNK_SIZE(c)-n <= DONTCARE) {\n\t\t\tunbin(c, i);\n\t\t\tunlock_bin(i);\n\t\t\treturn CHUNK_TO_MEM(c);\n\t\t}\n\t\tunlock_bin(i);\n\t}\n\tlock(mal.split_merge_lock);\n\tfor (mask = mal.binmap & -(1ULL<<i); mask; mask -= (mask&-mask)) {\n\t\tj = first_set(mask);\n\t\tlock_bin(j);\n\t\tc = mal.bins[j].head;\n\t\tif (c != BIN_TO_CHUNK(j)) {\n\t\t\tunbin(c, j);\n\t\t\tunlock_bin(j);\n\t\t\tbreak;\n\t\t}\n\t\tunlock_bin(j);\n\t}\n\tif (!mask) {\n\t\tc = expand_heap(n);\n\t\tif (!c) {\n\t\t\tunlock(mal.split_merge_lock);\n\t\t\treturn 0;\n\t\t}\n\t}\n\ttrim(c, n);\n\tunlock(mal.split_merge_lock);\n\treturn CHUNK_TO_MEM(c);\n}\n\nint __malloc_allzerop(void *p)\n{\n\treturn IS_MMAPPED(MEM_TO_CHUNK(p));\n}\n\nvoid *realloc(void *p, size_t n)\n{\n\tstruct chunk *self, *next;\n\tsize_t n0, n1;\n\tvoid *new;\n\n\tif (!p) return malloc(n);\n\n\tif (adjust_size(&n) < 0) return 0;\n\n\tself = MEM_TO_CHUNK(p);\n\tn1 = n0 = CHUNK_SIZE(self);\n\n\tif (n<=n0 && n0-n<=DONTCARE) return p;\n\n\tif (IS_MMAPPED(self)) {\n\t\tsize_t extra = self->psize;\n\t\tchar *base = (char *)self - extra;\n\t\tsize_t oldlen = n0 + extra;\n\t\tsize_t newlen = n + extra;\n\t\t/* Crash on realloc of freed chunk */\n\t\tif (extra & 1) a_crash();\n\t\tif (newlen < PAGE_SIZE && (new = malloc(n-OVERHEAD))) {\n\t\t\tn0 = n;\n\t\t\tgoto copy_free_ret;\n\t\t}\n\t\tnewlen = (newlen + PAGE_SIZE-1) & -PAGE_SIZE;\n\t\tif (oldlen == newlen) return p;\n\t\tbase = __mremap(base, oldlen, newlen, MREMAP_MAYMOVE);\n\t\tif (base == (void *)-1)\n\t\t\tgoto copy_realloc;\n\t\tself = (void *)(base + extra);\n\t\tself->csize = newlen - extra;\n\t\treturn CHUNK_TO_MEM(self);\n\t}\n\n\tnext = NEXT_CHUNK(self);\n\n\t/* Crash on corrupted footer (likely from buffer overflow) */\n\tif (next->psize != self->csize) a_crash();\n\n\tif (n < n0) {\n\t\tint i = bin_index_up(n);\n\t\tint j = bin_index(n0);\n\t\tif (i<j && (mal.binmap & (1ULL << i)))\n\t\t\tgoto copy_realloc;\n\t\tstruct chunk *split = (void *)((char *)self + n);\n\t\tself->csize = split->psize = n | C_INUSE;\n\t\tsplit->csize = next->psize = n0-n | C_INUSE;\n\t\t__bin_chunk(split);\n\t\treturn CHUNK_TO_MEM(self);\n\t}\n\n\tlock(mal.split_merge_lock);\n\n\tsize_t nsize = next->csize & C_INUSE ? 0 : CHUNK_SIZE(next);\n\tif (n0+nsize >= n) {\n\t\tint i = bin_index(nsize);\n\t\tlock_bin(i);\n\t\tif (!(next->csize & C_INUSE)) {\n\t\t\tunbin(next, i);\n\t\t\tunlock_bin(i);\n\t\t\tnext = NEXT_CHUNK(next);\n\t\t\tself->csize = next->psize = n0+nsize | C_INUSE;\n\t\t\ttrim(self, n);\n\t\t\tunlock(mal.split_merge_lock);\n\t\t\treturn CHUNK_TO_MEM(self);\n\t\t}\n\t\tunlock_bin(i);\n\t}\n\tunlock(mal.split_merge_lock);\n\ncopy_realloc:\n\t/* As a last resort, allocate a new chunk and copy to it. */\n\tnew = malloc(n-OVERHEAD);\n\tif (!new) return 0;\ncopy_free_ret:\n\tmemcpy(new, p, (n<n0 ? n : n0) - OVERHEAD);\n\tfree(CHUNK_TO_MEM(self));\n\treturn new;\n}\n\nvoid __bin_chunk(struct chunk *self)\n{\n\tstruct chunk *next = NEXT_CHUNK(self);\n\n\t/* Crash on corrupted footer (likely from buffer overflow) */\n\tif (next->psize != self->csize) a_crash();\n\n\tlock(mal.split_merge_lock);\n\n\tsize_t osize = CHUNK_SIZE(self), size = osize;\n\n\t/* Since we hold split_merge_lock, only transition from free to\n\t * in-use can race; in-use to free is impossible */\n\tsize_t psize = self->psize & C_INUSE ? 0 : CHUNK_PSIZE(self);\n\tsize_t nsize = next->csize & C_INUSE ? 0 : CHUNK_SIZE(next);\n\n\tif (psize) {\n\t\tint i = bin_index(psize);\n\t\tlock_bin(i);\n\t\tif (!(self->psize & C_INUSE)) {\n\t\t\tstruct chunk *prev = PREV_CHUNK(self);\n\t\t\tunbin(prev, i);\n\t\t\tself = prev;\n\t\t\tsize += psize;\n\t\t}\n\t\tunlock_bin(i);\n\t}\n\tif (nsize) {\n\t\tint i = bin_index(nsize);\n\t\tlock_bin(i);\n\t\tif (!(next->csize & C_INUSE)) {\n\t\t\tunbin(next, i);\n\t\t\tnext = NEXT_CHUNK(next);\n\t\t\tsize += nsize;\n\t\t}\n\t\tunlock_bin(i);\n\t}\n\n\tint i = bin_index(size);\n\tlock_bin(i);\n\n\tself->csize = size;\n\tnext->psize = size;\n\tbin_chunk(self, i);\n\tunlock(mal.split_merge_lock);\n\n\t/* Replace middle of large chunks with fresh zero pages */\n\tif (size > RECLAIM && (size^(size-osize)) > size-osize) {\n\t\tuintptr_t a = (uintptr_t)self + SIZE_ALIGN+PAGE_SIZE-1 & -PAGE_SIZE;\n\t\tuintptr_t b = (uintptr_t)next - SIZE_ALIGN & -PAGE_SIZE;\n#if 1\n\t\t__madvise((void *)a, b-a, MADV_DONTNEED);\n#else\n\t\t__mmap((void *)a, b-a, PROT_READ|PROT_WRITE,\n\t\t\tMAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0);\n#endif\n\t}\n\n\tunlock_bin(i);\n}\n\nstatic void unmap_chunk(struct chunk *self)\n{\n\tsize_t extra = self->psize;\n\tchar *base = (char *)self - extra;\n\tsize_t len = CHUNK_SIZE(self) + extra;\n\t/* Crash on double free */\n\tif (extra & 1) a_crash();\n\t__munmap(base, len);\n}\n\nvoid free(void *p)\n{\n\tif (!p) return;\n\n\tstruct chunk *self = MEM_TO_CHUNK(p);\n\n\tif (IS_MMAPPED(self))\n\t\tunmap_chunk(self);\n\telse\n\t\t__bin_chunk(self);\n}\n\nvoid __malloc_donate(char *start, char *end)\n{\n\tsize_t align_start_up = (SIZE_ALIGN-1) & (-(uintptr_t)start - OVERHEAD);\n\tsize_t align_end_down = (SIZE_ALIGN-1) & (uintptr_t)end;\n\n\t/* Getting past this condition ensures that the padding for alignment\n\t * and header overhead will not overflow and will leave a nonzero\n\t * multiple of SIZE_ALIGN bytes between start and end. */\n\tif (end - start <= OVERHEAD + align_start_up + align_end_down)\n\t\treturn;\n\tstart += align_start_up + OVERHEAD;\n\tend   -= align_end_down;\n\n\tstruct chunk *c = MEM_TO_CHUNK(start), *n = MEM_TO_CHUNK(end);\n\tc->psize = n->csize = C_INUSE;\n\tc->csize = n->psize = C_INUSE | (end-start);\n\t__bin_chunk(c);\n}\n\nvoid __malloc_atfork(int who)\n{\n\tif (who<0) {\n\t\tlock(mal.split_merge_lock);\n\t\tfor (int i=0; i<64; i++)\n\t\t\tlock(mal.bins[i].lock);\n\t} else if (!who) {\n\t\tfor (int i=0; i<64; i++)\n\t\t\tunlock(mal.bins[i].lock);\n\t\tunlock(mal.split_merge_lock);\n\t} else {\n\t\tfor (int i=0; i<64; i++)\n\t\t\tmal.bins[i].lock[0] = mal.bins[i].lock[1] = 0;\n\t\tmal.split_merge_lock[1] = 0;\n\t\tmal.split_merge_lock[0] = 0;\n\t}\n}\n"
  },
  {
    "path": "user.libc/src/malloc/oldmalloc/malloc_impl.h",
    "content": "#ifndef MALLOC_IMPL_H\n#define MALLOC_IMPL_H\n\n#include <sys/mman.h>\n#include \"dynlink.h\"\n\nstruct chunk {\n\tsize_t psize, csize;\n\tstruct chunk *next, *prev;\n};\n\nstruct bin {\n\tvolatile int lock[2];\n\tstruct chunk *head;\n\tstruct chunk *tail;\n};\n\n#define SIZE_ALIGN (4*sizeof(size_t))\n#define SIZE_MASK (-SIZE_ALIGN)\n#define OVERHEAD (2*sizeof(size_t))\n#define MMAP_THRESHOLD (0x1c00*SIZE_ALIGN)\n#define DONTCARE 16\n#define RECLAIM 163840\n\n#define CHUNK_SIZE(c) ((c)->csize & -2)\n#define CHUNK_PSIZE(c) ((c)->psize & -2)\n#define PREV_CHUNK(c) ((struct chunk *)((char *)(c) - CHUNK_PSIZE(c)))\n#define NEXT_CHUNK(c) ((struct chunk *)((char *)(c) + CHUNK_SIZE(c)))\n#define MEM_TO_CHUNK(p) (struct chunk *)((char *)(p) - OVERHEAD)\n#define CHUNK_TO_MEM(c) (void *)((char *)(c) + OVERHEAD)\n#define BIN_TO_CHUNK(i) (MEM_TO_CHUNK(&mal.bins[i].head))\n\n#define C_INUSE  ((size_t)1)\n\n#define IS_MMAPPED(c) !((c)->csize & (C_INUSE))\n\nhidden void __bin_chunk(struct chunk *);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/malloc/oldmalloc/malloc_usable_size.c",
    "content": "#include <malloc.h>\n#include \"malloc_impl.h\"\n \nhidden void *(*const __realloc_dep)(void *, size_t) = realloc;\n\nsize_t malloc_usable_size(void *p)\n{\n\treturn p ? CHUNK_SIZE(MEM_TO_CHUNK(p)) - OVERHEAD : 0;\n}\n"
  },
  {
    "path": "user.libc/src/malloc/posix_memalign.c",
    "content": "#include <stdlib.h>\n#include <errno.h>\n\nint posix_memalign(void **res, size_t align, size_t len)\n{\n\tif (align < sizeof(void *)) return EINVAL;\n\tvoid *mem = aligned_alloc(align, len);\n\tif (!mem) return errno;\n\t*res = mem;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/malloc/realloc.c",
    "content": "#include <stdlib.h>\n\nvoid *realloc(void *p, size_t n)\n{\n\treturn __libc_realloc(p, n);\n}\n"
  },
  {
    "path": "user.libc/src/malloc/reallocarray.c",
    "content": "#define _BSD_SOURCE\n#include <errno.h>\n#include <stdlib.h>\n\nvoid *reallocarray(void *ptr, size_t m, size_t n)\n{\n\tif (n && m > -1 / n) {\n\t\terrno = ENOMEM;\n\t\treturn 0;\n\t}\n\n\treturn realloc(ptr, m * n);\n}\n"
  },
  {
    "path": "user.libc/src/malloc/replaced.c",
    "content": "#include \"dynlink.h\"\n\nint __malloc_replaced;\nint __aligned_alloc_replaced;\n"
  },
  {
    "path": "user.libc/src/math/__cos.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/k_cos.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunSoft, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/*\n * __cos( x,  y )\n * kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164\n * Input x is assumed to be bounded by ~pi/4 in magnitude.\n * Input y is the tail of x.\n *\n * Algorithm\n *      1. Since cos(-x) = cos(x), we need only to consider positive x.\n *      2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0.\n *      3. cos(x) is approximated by a polynomial of degree 14 on\n *         [0,pi/4]\n *                                       4            14\n *              cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x\n *         where the remez error is\n *\n *      |              2     4     6     8     10    12     14 |     -58\n *      |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x  +C6*x  )| <= 2\n *      |                                                      |\n *\n *                     4     6     8     10    12     14\n *      4. let r = C1*x +C2*x +C3*x +C4*x +C5*x  +C6*x  , then\n *             cos(x) ~ 1 - x*x/2 + r\n *         since cos(x+y) ~ cos(x) - sin(x)*y\n *                        ~ cos(x) - x*y,\n *         a correction term is necessary in cos(x) and hence\n *              cos(x+y) = 1 - (x*x/2 - (r - x*y))\n *         For better accuracy, rearrange to\n *              cos(x+y) ~ w + (tmp + (r-x*y))\n *         where w = 1 - x*x/2 and tmp is a tiny correction term\n *         (1 - x*x/2 == w + tmp exactly in infinite precision).\n *         The exactness of w + tmp in infinite precision depends on w\n *         and tmp having the same precision as x.  If they have extra\n *         precision due to compiler bugs, then the extra precision is\n *         only good provided it is retained in all terms of the final\n *         expression for cos().  Retention happens in all cases tested\n *         under FreeBSD, so don't pessimize things by forcibly clipping\n *         any extra precision in w.\n */\n\n#include \"libm.h\"\n\nstatic const double\nC1  =  4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */\nC2  = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */\nC3  =  2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */\nC4  = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */\nC5  =  2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */\nC6  = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */\n\ndouble __cos(double x, double y)\n{\n\tdouble_t hz,z,r,w;\n\n\tz  = x*x;\n\tw  = z*z;\n\tr  = z*(C1+z*(C2+z*C3)) + w*w*(C4+z*(C5+z*C6));\n\thz = 0.5*z;\n\tw  = 1.0-hz;\n\treturn w + (((1.0-w)-hz) + (z*r-x*y));\n}\n"
  },
  {
    "path": "user.libc/src/math/__cosdf.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/k_cosf.c */\n/*\n * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.\n * Debugged and optimized by Bruce D. Evans.\n */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n\n#include \"libm.h\"\n\n/* |cos(x) - c(x)| < 2**-34.1 (~[-5.37e-11, 5.295e-11]). */\nstatic const double\nC0  = -0x1ffffffd0c5e81.0p-54, /* -0.499999997251031003120 */\nC1  =  0x155553e1053a42.0p-57, /*  0.0416666233237390631894 */\nC2  = -0x16c087e80f1e27.0p-62, /* -0.00138867637746099294692 */\nC3  =  0x199342e0ee5069.0p-68; /*  0.0000243904487962774090654 */\n\nfloat __cosdf(double x)\n{\n\tdouble_t r, w, z;\n\n\t/* Try to optimize for parallel evaluation as in __tandf.c. */\n\tz = x*x;\n\tw = z*z;\n\tr = C2+z*C3;\n\treturn ((1.0+z*C0) + w*C1) + (w*z)*r;\n}\n"
  },
  {
    "path": "user.libc/src/math/__cosl.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/ld80/k_cosl.c */\n/* origin: FreeBSD /usr/src/lib/msun/ld128/k_cosl.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.\n *\n * Developed at SunSoft, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n\n\n#include \"libm.h\"\n\n#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\n#if LDBL_MANT_DIG == 64\n/*\n * ld80 version of __cos.c.  See __cos.c for most comments.\n */\n/*\n * Domain [-0.7854, 0.7854], range ~[-2.43e-23, 2.425e-23]:\n * |cos(x) - c(x)| < 2**-75.1\n *\n * The coefficients of c(x) were generated by a pari-gp script using\n * a Remez algorithm that searches for the best higher coefficients\n * after rounding leading coefficients to a specified precision.\n *\n * Simpler methods like Chebyshev or basic Remez barely suffice for\n * cos() in 64-bit precision, because we want the coefficient of x^2\n * to be precisely -0.5 so that multiplying by it is exact, and plain\n * rounding of the coefficients of a good polynomial approximation only\n * gives this up to about 64-bit precision.  Plain rounding also gives\n * a mediocre approximation for the coefficient of x^4, but a rounding\n * error of 0.5 ulps for this coefficient would only contribute ~0.01\n * ulps to the final error, so this is unimportant.  Rounding errors in\n * higher coefficients are even less important.\n *\n * In fact, coefficients above the x^4 one only need to have 53-bit\n * precision, and this is more efficient.  We get this optimization\n * almost for free from the complications needed to search for the best\n * higher coefficients.\n */\nstatic const long double\nC1 =  0.0416666666666666666136L;        /*  0xaaaaaaaaaaaaaa9b.0p-68 */\nstatic const double\nC2 = -0.0013888888888888874,            /* -0x16c16c16c16c10.0p-62 */\nC3 =  0.000024801587301571716,          /*  0x1a01a01a018e22.0p-68 */\nC4 = -0.00000027557319215507120,        /* -0x127e4fb7602f22.0p-74 */\nC5 =  0.0000000020876754400407278,      /*  0x11eed8caaeccf1.0p-81 */\nC6 = -1.1470297442401303e-11,           /* -0x19393412bd1529.0p-89 */\nC7 =  4.7383039476436467e-14;           /*  0x1aac9d9af5c43e.0p-97 */\n#define POLY(z) (z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*C7)))))))\n#elif LDBL_MANT_DIG == 113\n/*\n * ld128 version of __cos.c.  See __cos.c for most comments.\n */\n/*\n * Domain [-0.7854, 0.7854], range ~[-1.80e-37, 1.79e-37]:\n * |cos(x) - c(x))| < 2**-122.0\n *\n * 113-bit precision requires more care than 64-bit precision, since\n * simple methods give a minimax polynomial with coefficient for x^2\n * that is 1 ulp below 0.5, but we want it to be precisely 0.5.  See\n * above for more details.\n */\nstatic const long double\nC1 =  0.04166666666666666666666666666666658424671L,\nC2 = -0.001388888888888888888888888888863490893732L,\nC3 =  0.00002480158730158730158730158600795304914210L,\nC4 = -0.2755731922398589065255474947078934284324e-6L,\nC5 =  0.2087675698786809897659225313136400793948e-8L,\nC6 = -0.1147074559772972315817149986812031204775e-10L,\nC7 =  0.4779477332386808976875457937252120293400e-13L;\nstatic const double\nC8 = -0.1561920696721507929516718307820958119868e-15,\nC9 =  0.4110317413744594971475941557607804508039e-18,\nC10 = -0.8896592467191938803288521958313920156409e-21,\nC11 =  0.1601061435794535138244346256065192782581e-23;\n#define POLY(z) (z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*(C7+ \\\n\tz*(C8+z*(C9+z*(C10+z*C11)))))))))))\n#endif\n\nlong double __cosl(long double x, long double y)\n{\n\tlong double hz,z,r,w;\n\n\tz  = x*x;\n\tr  = POLY(z);\n\thz = 0.5*z;\n\tw  = 1.0-hz;\n\treturn w + (((1.0-w)-hz) + (z*r-x*y));\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/__expo2.c",
    "content": "#include \"libm.h\"\n\n/* k is such that k*ln2 has minimal relative error and x - kln2 > log(DBL_MIN) */\nstatic const int k = 2043;\nstatic const double kln2 = 0x1.62066151add8bp+10;\n\n/* exp(x)/2 for x >= log(DBL_MAX), slightly better than 0.5*exp(x/2)*exp(x/2) */\ndouble __expo2(double x, double sign)\n{\n\tdouble scale;\n\n\t/* note that k is odd and scale*scale overflows */\n\tINSERT_WORDS(scale, (uint32_t)(0x3ff + k/2) << 20, 0);\n\t/* exp(x - k ln2) * 2**(k-1) */\n\t/* in directed rounding correct sign before rounding or overflow is important */\n\treturn exp(x - kln2) * (sign * scale) * scale;\n}\n"
  },
  {
    "path": "user.libc/src/math/__expo2f.c",
    "content": "#include \"libm.h\"\n\n/* k is such that k*ln2 has minimal relative error and x - kln2 > log(FLT_MIN) */\nstatic const int k = 235;\nstatic const float kln2 = 0x1.45c778p+7f;\n\n/* expf(x)/2 for x >= log(FLT_MAX), slightly better than 0.5f*expf(x/2)*expf(x/2) */\nfloat __expo2f(float x, float sign)\n{\n\tfloat scale;\n\n\t/* note that k is odd and scale*scale overflows */\n\tSET_FLOAT_WORD(scale, (uint32_t)(0x7f + k/2) << 23);\n\t/* exp(x - k ln2) * 2**(k-1) */\n\t/* in directed rounding correct sign before rounding or overflow is important */\n\treturn expf(x - kln2) * (sign * scale) * scale;\n}\n"
  },
  {
    "path": "user.libc/src/math/__fpclassify.c",
    "content": "#include <math.h>\n#include <stdint.h>\n\nint __fpclassify(double x)\n{\n\tunion {double f; uint64_t i;} u = {x};\n\tint e = u.i>>52 & 0x7ff;\n\tif (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;\n\tif (e==0x7ff) return u.i<<12 ? FP_NAN : FP_INFINITE;\n\treturn FP_NORMAL;\n}\n"
  },
  {
    "path": "user.libc/src/math/__fpclassifyf.c",
    "content": "#include <math.h>\n#include <stdint.h>\n\nint __fpclassifyf(float x)\n{\n\tunion {float f; uint32_t i;} u = {x};\n\tint e = u.i>>23 & 0xff;\n\tif (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;\n\tif (e==0xff) return u.i<<9 ? FP_NAN : FP_INFINITE;\n\treturn FP_NORMAL;\n}\n"
  },
  {
    "path": "user.libc/src/math/__fpclassifyl.c",
    "content": "#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nint __fpclassifyl(long double x)\n{\n\treturn __fpclassify(x);\n}\n#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384\nint __fpclassifyl(long double x)\n{\n\tunion ldshape u = {x};\n\tint e = u.i.se & 0x7fff;\n\tint msb = u.i.m>>63;\n\tif (!e && !msb)\n\t\treturn u.i.m ? FP_SUBNORMAL : FP_ZERO;\n\tif (e == 0x7fff) {\n\t\t/* The x86 variant of 80-bit extended precision only admits\n\t\t * one representation of each infinity, with the mantissa msb\n\t\t * necessarily set. The version with it clear is invalid/nan.\n\t\t * The m68k variant, however, allows either, and tooling uses\n\t\t * the version with it clear. */\n\t\tif (__BYTE_ORDER == __LITTLE_ENDIAN && !msb)\n\t\t\treturn FP_NAN;\n\t\treturn u.i.m << 1 ? FP_NAN : FP_INFINITE;\n\t}\n\tif (!msb)\n\t\treturn FP_NAN;\n\treturn FP_NORMAL;\n}\n#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384\nint __fpclassifyl(long double x)\n{\n\tunion ldshape u = {x};\n\tint e = u.i.se & 0x7fff;\n\tu.i.se = 0;\n\tif (!e)\n\t\treturn u.i2.lo | u.i2.hi ? FP_SUBNORMAL : FP_ZERO;\n\tif (e == 0x7fff)\n\t\treturn u.i2.lo | u.i2.hi ? FP_NAN : FP_INFINITE;\n\treturn FP_NORMAL;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/__invtrigl.c",
    "content": "#include <float.h>\n#include \"__invtrigl.h\"\n\n#if LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384\nstatic const long double\npS0 =  1.66666666666666666631e-01L,\npS1 = -4.16313987993683104320e-01L,\npS2 =  3.69068046323246813704e-01L,\npS3 = -1.36213932016738603108e-01L,\npS4 =  1.78324189708471965733e-02L,\npS5 = -2.19216428382605211588e-04L,\npS6 = -7.10526623669075243183e-06L,\nqS1 = -2.94788392796209867269e+00L,\nqS2 =  3.27309890266528636716e+00L,\nqS3 = -1.68285799854822427013e+00L,\nqS4 =  3.90699412641738801874e-01L,\nqS5 = -3.14365703596053263322e-02L;\n\nconst long double pio2_hi = 1.57079632679489661926L;\nconst long double pio2_lo = -2.50827880633416601173e-20L;\n\n/* used in asinl() and acosl() */\n/* R(x^2) is a rational approximation of (asin(x)-x)/x^3 with Remez algorithm */\nlong double __invtrigl_R(long double z)\n{\n\tlong double p, q;\n\tp = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*(pS5+z*pS6))))));\n\tq = 1.0+z*(qS1+z*(qS2+z*(qS3+z*(qS4+z*qS5))));\n\treturn p/q;\n}\n#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384\nstatic const long double\npS0 =  1.66666666666666666666666666666700314e-01L,\npS1 = -7.32816946414566252574527475428622708e-01L,\npS2 =  1.34215708714992334609030036562143589e+00L,\npS3 = -1.32483151677116409805070261790752040e+00L,\npS4 =  7.61206183613632558824485341162121989e-01L,\npS5 = -2.56165783329023486777386833928147375e-01L,\npS6 =  4.80718586374448793411019434585413855e-02L,\npS7 = -4.42523267167024279410230886239774718e-03L,\npS8 =  1.44551535183911458253205638280410064e-04L,\npS9 = -2.10558957916600254061591040482706179e-07L,\nqS1 = -4.84690167848739751544716485245697428e+00L,\nqS2 =  9.96619113536172610135016921140206980e+00L,\nqS3 = -1.13177895428973036660836798461641458e+01L,\nqS4 =  7.74004374389488266169304117714658761e+00L,\nqS5 = -3.25871986053534084709023539900339905e+00L,\nqS6 =  8.27830318881232209752469022352928864e-01L,\nqS7 = -1.18768052702942805423330715206348004e-01L,\nqS8 =  8.32600764660522313269101537926539470e-03L,\nqS9 = -1.99407384882605586705979504567947007e-04L;\n\nconst long double pio2_hi = 1.57079632679489661923132169163975140L;\nconst long double pio2_lo = 4.33590506506189051239852201302167613e-35L;\n\nlong double __invtrigl_R(long double z)\n{\n\tlong double p, q;\n\tp = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*(pS5+z*(pS6+z*(pS7+z*(pS8+z*pS9)))))))));\n\tq = 1.0+z*(qS1+z*(qS2+z*(qS3+z*(qS4+z*(qS5+z*(qS6+z*(qS7+z*(qS8+z*qS9))))))));\n\treturn p/q;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/__invtrigl.h",
    "content": "#include <features.h>\n\n/* shared by acosl, asinl and atan2l */\n#define pio2_hi __pio2_hi\n#define pio2_lo __pio2_lo\nhidden extern const long double pio2_hi, pio2_lo;\n\nhidden long double __invtrigl_R(long double z);\n"
  },
  {
    "path": "user.libc/src/math/__math_divzero.c",
    "content": "#include \"libm.h\"\n\ndouble __math_divzero(uint32_t sign)\n{\n\treturn fp_barrier(sign ? -1.0 : 1.0) / 0.0;\n}\n"
  },
  {
    "path": "user.libc/src/math/__math_divzerof.c",
    "content": "#include \"libm.h\"\n\nfloat __math_divzerof(uint32_t sign)\n{\n\treturn fp_barrierf(sign ? -1.0f : 1.0f) / 0.0f;\n}\n"
  },
  {
    "path": "user.libc/src/math/__math_invalid.c",
    "content": "#include \"libm.h\"\n\ndouble __math_invalid(double x)\n{\n\treturn (x - x) / (x - x);\n}\n"
  },
  {
    "path": "user.libc/src/math/__math_invalidf.c",
    "content": "#include \"libm.h\"\n\nfloat __math_invalidf(float x)\n{\n\treturn (x - x) / (x - x);\n}\n"
  },
  {
    "path": "user.libc/src/math/__math_invalidl.c",
    "content": "#include <float.h>\n#include \"libm.h\"\n\n#if LDBL_MANT_DIG != DBL_MANT_DIG\nlong double __math_invalidl(long double x)\n{\n\treturn (x - x) / (x - x);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/__math_oflow.c",
    "content": "#include \"libm.h\"\n\ndouble __math_oflow(uint32_t sign)\n{\n\treturn __math_xflow(sign, 0x1p769);\n}\n"
  },
  {
    "path": "user.libc/src/math/__math_oflowf.c",
    "content": "#include \"libm.h\"\n\nfloat __math_oflowf(uint32_t sign)\n{\n\treturn __math_xflowf(sign, 0x1p97f);\n}\n"
  },
  {
    "path": "user.libc/src/math/__math_uflow.c",
    "content": "#include \"libm.h\"\n\ndouble __math_uflow(uint32_t sign)\n{\n\treturn __math_xflow(sign, 0x1p-767);\n}\n"
  },
  {
    "path": "user.libc/src/math/__math_uflowf.c",
    "content": "#include \"libm.h\"\n\nfloat __math_uflowf(uint32_t sign)\n{\n\treturn __math_xflowf(sign, 0x1p-95f);\n}\n"
  },
  {
    "path": "user.libc/src/math/__math_xflow.c",
    "content": "#include \"libm.h\"\n\ndouble __math_xflow(uint32_t sign, double y)\n{\n\treturn eval_as_double(fp_barrier(sign ? -y : y) * y);\n}\n"
  },
  {
    "path": "user.libc/src/math/__math_xflowf.c",
    "content": "#include \"libm.h\"\n\nfloat __math_xflowf(uint32_t sign, float y)\n{\n\treturn eval_as_float(fp_barrierf(sign ? -y : y) * y);\n}\n"
  },
  {
    "path": "user.libc/src/math/__polevll.c",
    "content": "/* origin: OpenBSD /usr/src/lib/libm/src/polevll.c */\n/*\n * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n/*\n *      Evaluate polynomial\n *\n *\n * SYNOPSIS:\n *\n * int N;\n * long double x, y, coef[N+1], polevl[];\n *\n * y = polevll( x, coef, N );\n *\n *\n * DESCRIPTION:\n *\n * Evaluates polynomial of degree N:\n *\n *                     2          N\n * y  =  C  + C x + C x  +...+ C x\n *        0    1     2          N\n *\n * Coefficients are stored in reverse order:\n *\n * coef[0] = C  , ..., coef[N] = C  .\n *            N                   0\n *\n *  The function p1evll() assumes that coef[N] = 1.0 and is\n * omitted from the array.  Its calling arguments are\n * otherwise the same as polevll().\n *\n *\n * SPEED:\n *\n * In the interest of speed, there are no checks for out\n * of bounds arithmetic.  This routine is used by most of\n * the functions in the library.  Depending on available\n * equipment features, the user may wish to rewrite the\n * program in microcode or assembly language.\n *\n */\n\n#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\n#else\n/*\n * Polynomial evaluator:\n *  P[0] x^n  +  P[1] x^(n-1)  +  ...  +  P[n]\n */\nlong double __polevll(long double x, const long double *P, int n)\n{\n\tlong double y;\n\n\ty = *P++;\n\tdo {\n\t\ty = y * x + *P++;\n\t} while (--n);\n\n\treturn y;\n}\n\n/*\n * Polynomial evaluator:\n *  x^n  +  P[0] x^(n-1)  +  P[1] x^(n-2)  +  ...  +  P[n]\n */\nlong double __p1evll(long double x, const long double *P, int n)\n{\n\tlong double y;\n\n\tn -= 1;\n\ty = x + *P++;\n\tdo {\n\t\ty = y * x + *P++;\n\t} while (--n);\n\n\treturn y;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/__rem_pio2.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/e_rem_pio2.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunSoft, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n *\n * Optimized by Bruce D. Evans.\n */\n/* __rem_pio2(x,y)\n *\n * return the remainder of x rem pi/2 in y[0]+y[1]\n * use __rem_pio2_large() for large x\n */\n\n#include \"libm.h\"\n\n#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1\n#define EPS DBL_EPSILON\n#elif FLT_EVAL_METHOD==2\n#define EPS LDBL_EPSILON\n#endif\n\n/*\n * invpio2:  53 bits of 2/pi\n * pio2_1:   first  33 bit of pi/2\n * pio2_1t:  pi/2 - pio2_1\n * pio2_2:   second 33 bit of pi/2\n * pio2_2t:  pi/2 - (pio2_1+pio2_2)\n * pio2_3:   third  33 bit of pi/2\n * pio2_3t:  pi/2 - (pio2_1+pio2_2+pio2_3)\n */\nstatic const double\ntoint   = 1.5/EPS,\npio4    = 0x1.921fb54442d18p-1,\ninvpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */\npio2_1  = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */\npio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */\npio2_2  = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */\npio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */\npio2_3  = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */\npio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */\n\n/* caller must handle the case when reduction is not needed: |x| ~<= pi/4 */\nint __rem_pio2(double x, double *y)\n{\n\tunion {double f; uint64_t i;} u = {x};\n\tdouble_t z,w,t,r,fn;\n\tdouble tx[3],ty[2];\n\tuint32_t ix;\n\tint sign, n, ex, ey, i;\n\n\tsign = u.i>>63;\n\tix = u.i>>32 & 0x7fffffff;\n\tif (ix <= 0x400f6a7a) {  /* |x| ~<= 5pi/4 */\n\t\tif ((ix & 0xfffff) == 0x921fb)  /* |x| ~= pi/2 or 2pi/2 */\n\t\t\tgoto medium;  /* cancellation -- use medium case */\n\t\tif (ix <= 0x4002d97c) {  /* |x| ~<= 3pi/4 */\n\t\t\tif (!sign) {\n\t\t\t\tz = x - pio2_1;  /* one round good to 85 bits */\n\t\t\t\ty[0] = z - pio2_1t;\n\t\t\t\ty[1] = (z-y[0]) - pio2_1t;\n\t\t\t\treturn 1;\n\t\t\t} else {\n\t\t\t\tz = x + pio2_1;\n\t\t\t\ty[0] = z + pio2_1t;\n\t\t\t\ty[1] = (z-y[0]) + pio2_1t;\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t} else {\n\t\t\tif (!sign) {\n\t\t\t\tz = x - 2*pio2_1;\n\t\t\t\ty[0] = z - 2*pio2_1t;\n\t\t\t\ty[1] = (z-y[0]) - 2*pio2_1t;\n\t\t\t\treturn 2;\n\t\t\t} else {\n\t\t\t\tz = x + 2*pio2_1;\n\t\t\t\ty[0] = z + 2*pio2_1t;\n\t\t\t\ty[1] = (z-y[0]) + 2*pio2_1t;\n\t\t\t\treturn -2;\n\t\t\t}\n\t\t}\n\t}\n\tif (ix <= 0x401c463b) {  /* |x| ~<= 9pi/4 */\n\t\tif (ix <= 0x4015fdbc) {  /* |x| ~<= 7pi/4 */\n\t\t\tif (ix == 0x4012d97c)  /* |x| ~= 3pi/2 */\n\t\t\t\tgoto medium;\n\t\t\tif (!sign) {\n\t\t\t\tz = x - 3*pio2_1;\n\t\t\t\ty[0] = z - 3*pio2_1t;\n\t\t\t\ty[1] = (z-y[0]) - 3*pio2_1t;\n\t\t\t\treturn 3;\n\t\t\t} else {\n\t\t\t\tz = x + 3*pio2_1;\n\t\t\t\ty[0] = z + 3*pio2_1t;\n\t\t\t\ty[1] = (z-y[0]) + 3*pio2_1t;\n\t\t\t\treturn -3;\n\t\t\t}\n\t\t} else {\n\t\t\tif (ix == 0x401921fb)  /* |x| ~= 4pi/2 */\n\t\t\t\tgoto medium;\n\t\t\tif (!sign) {\n\t\t\t\tz = x - 4*pio2_1;\n\t\t\t\ty[0] = z - 4*pio2_1t;\n\t\t\t\ty[1] = (z-y[0]) - 4*pio2_1t;\n\t\t\t\treturn 4;\n\t\t\t} else {\n\t\t\t\tz = x + 4*pio2_1;\n\t\t\t\ty[0] = z + 4*pio2_1t;\n\t\t\t\ty[1] = (z-y[0]) + 4*pio2_1t;\n\t\t\t\treturn -4;\n\t\t\t}\n\t\t}\n\t}\n\tif (ix < 0x413921fb) {  /* |x| ~< 2^20*(pi/2), medium size */\nmedium:\n\t\t/* rint(x/(pi/2)) */\n\t\tfn = (double_t)x*invpio2 + toint - toint;\n\t\tn = (int32_t)fn;\n\t\tr = x - fn*pio2_1;\n\t\tw = fn*pio2_1t;  /* 1st round, good to 85 bits */\n\t\t/* Matters with directed rounding. */\n\t\tif (predict_false(r - w < -pio4)) {\n\t\t\tn--;\n\t\t\tfn--;\n\t\t\tr = x - fn*pio2_1;\n\t\t\tw = fn*pio2_1t;\n\t\t} else if (predict_false(r - w > pio4)) {\n\t\t\tn++;\n\t\t\tfn++;\n\t\t\tr = x - fn*pio2_1;\n\t\t\tw = fn*pio2_1t;\n\t\t}\n\t\ty[0] = r - w;\n\t\tu.f = y[0];\n\t\tey = u.i>>52 & 0x7ff;\n\t\tex = ix>>20;\n\t\tif (ex - ey > 16) { /* 2nd round, good to 118 bits */\n\t\t\tt = r;\n\t\t\tw = fn*pio2_2;\n\t\t\tr = t - w;\n\t\t\tw = fn*pio2_2t - ((t-r)-w);\n\t\t\ty[0] = r - w;\n\t\t\tu.f = y[0];\n\t\t\tey = u.i>>52 & 0x7ff;\n\t\t\tif (ex - ey > 49) {  /* 3rd round, good to 151 bits, covers all cases */\n\t\t\t\tt = r;\n\t\t\t\tw = fn*pio2_3;\n\t\t\t\tr = t - w;\n\t\t\t\tw = fn*pio2_3t - ((t-r)-w);\n\t\t\t\ty[0] = r - w;\n\t\t\t}\n\t\t}\n\t\ty[1] = (r - y[0]) - w;\n\t\treturn n;\n\t}\n\t/*\n\t * all other (large) arguments\n\t */\n\tif (ix >= 0x7ff00000) {  /* x is inf or NaN */\n\t\ty[0] = y[1] = x - x;\n\t\treturn 0;\n\t}\n\t/* set z = scalbn(|x|,-ilogb(x)+23) */\n\tu.f = x;\n\tu.i &= (uint64_t)-1>>12;\n\tu.i |= (uint64_t)(0x3ff + 23)<<52;\n\tz = u.f;\n\tfor (i=0; i < 2; i++) {\n\t\ttx[i] = (double)(int32_t)z;\n\t\tz     = (z-tx[i])*0x1p24;\n\t}\n\ttx[i] = z;\n\t/* skip zero terms, first term is non-zero */\n\twhile (tx[i] == 0.0)\n\t\ti--;\n\tn = __rem_pio2_large(tx,ty,(int)(ix>>20)-(0x3ff+23),i+1,1);\n\tif (sign) {\n\t\ty[0] = -ty[0];\n\t\ty[1] = -ty[1];\n\t\treturn -n;\n\t}\n\ty[0] = ty[0];\n\ty[1] = ty[1];\n\treturn n;\n}\n"
  },
  {
    "path": "user.libc/src/math/__rem_pio2_large.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/k_rem_pio2.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunSoft, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/*\n * __rem_pio2_large(x,y,e0,nx,prec)\n * double x[],y[]; int e0,nx,prec;\n *\n * __rem_pio2_large return the last three digits of N with\n *              y = x - N*pi/2\n * so that |y| < pi/2.\n *\n * The method is to compute the integer (mod 8) and fraction parts of\n * (2/pi)*x without doing the full multiplication. In general we\n * skip the part of the product that are known to be a huge integer (\n * more accurately, = 0 mod 8 ). Thus the number of operations are\n * independent of the exponent of the input.\n *\n * (2/pi) is represented by an array of 24-bit integers in ipio2[].\n *\n * Input parameters:\n *      x[]     The input value (must be positive) is broken into nx\n *              pieces of 24-bit integers in double precision format.\n *              x[i] will be the i-th 24 bit of x. The scaled exponent\n *              of x[0] is given in input parameter e0 (i.e., x[0]*2^e0\n *              match x's up to 24 bits.\n *\n *              Example of breaking a double positive z into x[0]+x[1]+x[2]:\n *                      e0 = ilogb(z)-23\n *                      z  = scalbn(z,-e0)\n *              for i = 0,1,2\n *                      x[i] = floor(z)\n *                      z    = (z-x[i])*2**24\n *\n *\n *      y[]     ouput result in an array of double precision numbers.\n *              The dimension of y[] is:\n *                      24-bit  precision       1\n *                      53-bit  precision       2\n *                      64-bit  precision       2\n *                      113-bit precision       3\n *              The actual value is the sum of them. Thus for 113-bit\n *              precison, one may have to do something like:\n *\n *              long double t,w,r_head, r_tail;\n *              t = (long double)y[2] + (long double)y[1];\n *              w = (long double)y[0];\n *              r_head = t+w;\n *              r_tail = w - (r_head - t);\n *\n *      e0      The exponent of x[0]. Must be <= 16360 or you need to\n *              expand the ipio2 table.\n *\n *      nx      dimension of x[]\n *\n *      prec    an integer indicating the precision:\n *                      0       24  bits (single)\n *                      1       53  bits (double)\n *                      2       64  bits (extended)\n *                      3       113 bits (quad)\n *\n * External function:\n *      double scalbn(), floor();\n *\n *\n * Here is the description of some local variables:\n *\n *      jk      jk+1 is the initial number of terms of ipio2[] needed\n *              in the computation. The minimum and recommended value\n *              for jk is 3,4,4,6 for single, double, extended, and quad.\n *              jk+1 must be 2 larger than you might expect so that our\n *              recomputation test works. (Up to 24 bits in the integer\n *              part (the 24 bits of it that we compute) and 23 bits in\n *              the fraction part may be lost to cancelation before we\n *              recompute.)\n *\n *      jz      local integer variable indicating the number of\n *              terms of ipio2[] used.\n *\n *      jx      nx - 1\n *\n *      jv      index for pointing to the suitable ipio2[] for the\n *              computation. In general, we want\n *                      ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8\n *              is an integer. Thus\n *                      e0-3-24*jv >= 0 or (e0-3)/24 >= jv\n *              Hence jv = max(0,(e0-3)/24).\n *\n *      jp      jp+1 is the number of terms in PIo2[] needed, jp = jk.\n *\n *      q[]     double array with integral value, representing the\n *              24-bits chunk of the product of x and 2/pi.\n *\n *      q0      the corresponding exponent of q[0]. Note that the\n *              exponent for q[i] would be q0-24*i.\n *\n *      PIo2[]  double precision array, obtained by cutting pi/2\n *              into 24 bits chunks.\n *\n *      f[]     ipio2[] in floating point\n *\n *      iq[]    integer array by breaking up q[] in 24-bits chunk.\n *\n *      fq[]    final product of x*(2/pi) in fq[0],..,fq[jk]\n *\n *      ih      integer. If >0 it indicates q[] is >= 0.5, hence\n *              it also indicates the *sign* of the result.\n *\n */\n/*\n * Constants:\n * The hexadecimal values are the intended ones for the following\n * constants. The decimal values may be used, provided that the\n * compiler will convert from decimal to binary accurately enough\n * to produce the hexadecimal values shown.\n */\n\n#include \"libm.h\"\n\nstatic const int init_jk[] = {3,4,4,6}; /* initial value for jk */\n\n/*\n * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi\n *\n *              integer array, contains the (24*i)-th to (24*i+23)-th\n *              bit of 2/pi after binary point. The corresponding\n *              floating value is\n *\n *                      ipio2[i] * 2^(-24(i+1)).\n *\n * NB: This table must have at least (e0-3)/24 + jk terms.\n *     For quad precision (e0 <= 16360, jk = 6), this is 686.\n */\nstatic const int32_t ipio2[] = {\n0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62,\n0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A,\n0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129,\n0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41,\n0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8,\n0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF,\n0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5,\n0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08,\n0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3,\n0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880,\n0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B,\n\n#if LDBL_MAX_EXP > 1024\n0x47C419, 0xC367CD, 0xDCE809, 0x2A8359, 0xC4768B, 0x961CA6,\n0xDDAF44, 0xD15719, 0x053EA5, 0xFF0705, 0x3F7E33, 0xE832C2,\n0xDE4F98, 0x327DBB, 0xC33D26, 0xEF6B1E, 0x5EF89F, 0x3A1F35,\n0xCAF27F, 0x1D87F1, 0x21907C, 0x7C246A, 0xFA6ED5, 0x772D30,\n0x433B15, 0xC614B5, 0x9D19C3, 0xC2C4AD, 0x414D2C, 0x5D000C,\n0x467D86, 0x2D71E3, 0x9AC69B, 0x006233, 0x7CD2B4, 0x97A7B4,\n0xD55537, 0xF63ED7, 0x1810A3, 0xFC764D, 0x2A9D64, 0xABD770,\n0xF87C63, 0x57B07A, 0xE71517, 0x5649C0, 0xD9D63B, 0x3884A7,\n0xCB2324, 0x778AD6, 0x23545A, 0xB91F00, 0x1B0AF1, 0xDFCE19,\n0xFF319F, 0x6A1E66, 0x615799, 0x47FBAC, 0xD87F7E, 0xB76522,\n0x89E832, 0x60BFE6, 0xCDC4EF, 0x09366C, 0xD43F5D, 0xD7DE16,\n0xDE3B58, 0x929BDE, 0x2822D2, 0xE88628, 0x4D58E2, 0x32CAC6,\n0x16E308, 0xCB7DE0, 0x50C017, 0xA71DF3, 0x5BE018, 0x34132E,\n0x621283, 0x014883, 0x5B8EF5, 0x7FB0AD, 0xF2E91E, 0x434A48,\n0xD36710, 0xD8DDAA, 0x425FAE, 0xCE616A, 0xA4280A, 0xB499D3,\n0xF2A606, 0x7F775C, 0x83C2A3, 0x883C61, 0x78738A, 0x5A8CAF,\n0xBDD76F, 0x63A62D, 0xCBBFF4, 0xEF818D, 0x67C126, 0x45CA55,\n0x36D9CA, 0xD2A828, 0x8D61C2, 0x77C912, 0x142604, 0x9B4612,\n0xC459C4, 0x44C5C8, 0x91B24D, 0xF31700, 0xAD43D4, 0xE54929,\n0x10D5FD, 0xFCBE00, 0xCC941E, 0xEECE70, 0xF53E13, 0x80F1EC,\n0xC3E7B3, 0x28F8C7, 0x940593, 0x3E71C1, 0xB3092E, 0xF3450B,\n0x9C1288, 0x7B20AB, 0x9FB52E, 0xC29247, 0x2F327B, 0x6D550C,\n0x90A772, 0x1FE76B, 0x96CB31, 0x4A1679, 0xE27941, 0x89DFF4,\n0x9794E8, 0x84E6E2, 0x973199, 0x6BED88, 0x365F5F, 0x0EFDBB,\n0xB49A48, 0x6CA467, 0x427271, 0x325D8D, 0xB8159F, 0x09E5BC,\n0x25318D, 0x3974F7, 0x1C0530, 0x010C0D, 0x68084B, 0x58EE2C,\n0x90AA47, 0x02E774, 0x24D6BD, 0xA67DF7, 0x72486E, 0xEF169F,\n0xA6948E, 0xF691B4, 0x5153D1, 0xF20ACF, 0x339820, 0x7E4BF5,\n0x6863B2, 0x5F3EDD, 0x035D40, 0x7F8985, 0x295255, 0xC06437,\n0x10D86D, 0x324832, 0x754C5B, 0xD4714E, 0x6E5445, 0xC1090B,\n0x69F52A, 0xD56614, 0x9D0727, 0x50045D, 0xDB3BB4, 0xC576EA,\n0x17F987, 0x7D6B49, 0xBA271D, 0x296996, 0xACCCC6, 0x5414AD,\n0x6AE290, 0x89D988, 0x50722C, 0xBEA404, 0x940777, 0x7030F3,\n0x27FC00, 0xA871EA, 0x49C266, 0x3DE064, 0x83DD97, 0x973FA3,\n0xFD9443, 0x8C860D, 0xDE4131, 0x9D3992, 0x8C70DD, 0xE7B717,\n0x3BDF08, 0x2B3715, 0xA0805C, 0x93805A, 0x921110, 0xD8E80F,\n0xAF806C, 0x4BFFDB, 0x0F9038, 0x761859, 0x15A562, 0xBBCB61,\n0xB989C7, 0xBD4010, 0x04F2D2, 0x277549, 0xF6B6EB, 0xBB22DB,\n0xAA140A, 0x2F2689, 0x768364, 0x333B09, 0x1A940E, 0xAA3A51,\n0xC2A31D, 0xAEEDAF, 0x12265C, 0x4DC26D, 0x9C7A2D, 0x9756C0,\n0x833F03, 0xF6F009, 0x8C402B, 0x99316D, 0x07B439, 0x15200C,\n0x5BC3D8, 0xC492F5, 0x4BADC6, 0xA5CA4E, 0xCD37A7, 0x36A9E6,\n0x9492AB, 0x6842DD, 0xDE6319, 0xEF8C76, 0x528B68, 0x37DBFC,\n0xABA1AE, 0x3115DF, 0xA1AE00, 0xDAFB0C, 0x664D64, 0xB705ED,\n0x306529, 0xBF5657, 0x3AFF47, 0xB9F96A, 0xF3BE75, 0xDF9328,\n0x3080AB, 0xF68C66, 0x15CB04, 0x0622FA, 0x1DE4D9, 0xA4B33D,\n0x8F1B57, 0x09CD36, 0xE9424E, 0xA4BE13, 0xB52333, 0x1AAAF0,\n0xA8654F, 0xA5C1D2, 0x0F3F0B, 0xCD785B, 0x76F923, 0x048B7B,\n0x721789, 0x53A6C6, 0xE26E6F, 0x00EBEF, 0x584A9B, 0xB7DAC4,\n0xBA66AA, 0xCFCF76, 0x1D02D1, 0x2DF1B1, 0xC1998C, 0x77ADC3,\n0xDA4886, 0xA05DF7, 0xF480C6, 0x2FF0AC, 0x9AECDD, 0xBC5C3F,\n0x6DDED0, 0x1FC790, 0xB6DB2A, 0x3A25A3, 0x9AAF00, 0x9353AD,\n0x0457B6, 0xB42D29, 0x7E804B, 0xA707DA, 0x0EAA76, 0xA1597B,\n0x2A1216, 0x2DB7DC, 0xFDE5FA, 0xFEDB89, 0xFDBE89, 0x6C76E4,\n0xFCA906, 0x70803E, 0x156E85, 0xFF87FD, 0x073E28, 0x336761,\n0x86182A, 0xEABD4D, 0xAFE7B3, 0x6E6D8F, 0x396795, 0x5BBF31,\n0x48D784, 0x16DF30, 0x432DC7, 0x356125, 0xCE70C9, 0xB8CB30,\n0xFD6CBF, 0xA200A4, 0xE46C05, 0xA0DD5A, 0x476F21, 0xD21262,\n0x845CB9, 0x496170, 0xE0566B, 0x015299, 0x375550, 0xB7D51E,\n0xC4F133, 0x5F6E13, 0xE4305D, 0xA92E85, 0xC3B21D, 0x3632A1,\n0xA4B708, 0xD4B1EA, 0x21F716, 0xE4698F, 0x77FF27, 0x80030C,\n0x2D408D, 0xA0CD4F, 0x99A520, 0xD3A2B3, 0x0A5D2F, 0x42F9B4,\n0xCBDA11, 0xD0BE7D, 0xC1DB9B, 0xBD17AB, 0x81A2CA, 0x5C6A08,\n0x17552E, 0x550027, 0xF0147F, 0x8607E1, 0x640B14, 0x8D4196,\n0xDEBE87, 0x2AFDDA, 0xB6256B, 0x34897B, 0xFEF305, 0x9EBFB9,\n0x4F6A68, 0xA82A4A, 0x5AC44F, 0xBCF82D, 0x985AD7, 0x95C7F4,\n0x8D4D0D, 0xA63A20, 0x5F57A4, 0xB13F14, 0x953880, 0x0120CC,\n0x86DD71, 0xB6DEC9, 0xF560BF, 0x11654D, 0x6B0701, 0xACB08C,\n0xD0C0B2, 0x485551, 0x0EFB1E, 0xC37295, 0x3B06A3, 0x3540C0,\n0x7BDC06, 0xCC45E0, 0xFA294E, 0xC8CAD6, 0x41F3E8, 0xDE647C,\n0xD8649B, 0x31BED9, 0xC397A4, 0xD45877, 0xC5E369, 0x13DAF0,\n0x3C3ABA, 0x461846, 0x5F7555, 0xF5BDD2, 0xC6926E, 0x5D2EAC,\n0xED440E, 0x423E1C, 0x87C461, 0xE9FD29, 0xF3D6E7, 0xCA7C22,\n0x35916F, 0xC5E008, 0x8DD7FF, 0xE26A6E, 0xC6FDB0, 0xC10893,\n0x745D7C, 0xB2AD6B, 0x9D6ECD, 0x7B723E, 0x6A11C6, 0xA9CFF7,\n0xDF7329, 0xBAC9B5, 0x5100B7, 0x0DB2E2, 0x24BA74, 0x607DE5,\n0x8AD874, 0x2C150D, 0x0C1881, 0x94667E, 0x162901, 0x767A9F,\n0xBEFDFD, 0xEF4556, 0x367ED9, 0x13D9EC, 0xB9BA8B, 0xFC97C4,\n0x27A831, 0xC36EF1, 0x36C594, 0x56A8D8, 0xB5A8B4, 0x0ECCCF,\n0x2D8912, 0x34576F, 0x89562C, 0xE3CE99, 0xB920D6, 0xAA5E6B,\n0x9C2A3E, 0xCC5F11, 0x4A0BFD, 0xFBF4E1, 0x6D3B8E, 0x2C86E2,\n0x84D4E9, 0xA9B4FC, 0xD1EEEF, 0xC9352E, 0x61392F, 0x442138,\n0xC8D91B, 0x0AFC81, 0x6A4AFB, 0xD81C2F, 0x84B453, 0x8C994E,\n0xCC2254, 0xDC552A, 0xD6C6C0, 0x96190B, 0xB8701A, 0x649569,\n0x605A26, 0xEE523F, 0x0F117F, 0x11B5F4, 0xF5CBFC, 0x2DBC34,\n0xEEBC34, 0xCC5DE8, 0x605EDD, 0x9B8E67, 0xEF3392, 0xB817C9,\n0x9B5861, 0xBC57E1, 0xC68351, 0x103ED8, 0x4871DD, 0xDD1C2D,\n0xA118AF, 0x462C21, 0xD7F359, 0x987AD9, 0xC0549E, 0xFA864F,\n0xFC0656, 0xAE79E5, 0x362289, 0x22AD38, 0xDC9367, 0xAAE855,\n0x382682, 0x9BE7CA, 0xA40D51, 0xB13399, 0x0ED7A9, 0x480569,\n0xF0B265, 0xA7887F, 0x974C88, 0x36D1F9, 0xB39221, 0x4A827B,\n0x21CF98, 0xDC9F40, 0x5547DC, 0x3A74E1, 0x42EB67, 0xDF9DFE,\n0x5FD45E, 0xA4677B, 0x7AACBA, 0xA2F655, 0x23882B, 0x55BA41,\n0x086E59, 0x862A21, 0x834739, 0xE6E389, 0xD49EE5, 0x40FB49,\n0xE956FF, 0xCA0F1C, 0x8A59C5, 0x2BFA94, 0xC5C1D3, 0xCFC50F,\n0xAE5ADB, 0x86C547, 0x624385, 0x3B8621, 0x94792C, 0x876110,\n0x7B4C2A, 0x1A2C80, 0x12BF43, 0x902688, 0x893C78, 0xE4C4A8,\n0x7BDBE5, 0xC23AC4, 0xEAF426, 0x8A67F7, 0xBF920D, 0x2BA365,\n0xB1933D, 0x0B7CBD, 0xDC51A4, 0x63DD27, 0xDDE169, 0x19949A,\n0x9529A8, 0x28CE68, 0xB4ED09, 0x209F44, 0xCA984E, 0x638270,\n0x237C7E, 0x32B90F, 0x8EF5A7, 0xE75614, 0x08F121, 0x2A9DB5,\n0x4D7E6F, 0x5119A5, 0xABF9B5, 0xD6DF82, 0x61DD96, 0x023616,\n0x9F3AC4, 0xA1A283, 0x6DED72, 0x7A8D39, 0xA9B882, 0x5C326B,\n0x5B2746, 0xED3400, 0x7700D2, 0x55F4FC, 0x4D5901, 0x8071E0,\n#endif\n};\n\nstatic const double PIo2[] = {\n  1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */\n  7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */\n  5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */\n  3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */\n  1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */\n  1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */\n  2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */\n  2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */\n};\n\nint __rem_pio2_large(double *x, double *y, int e0, int nx, int prec)\n{\n\tint32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;\n\tdouble z,fw,f[20],fq[20],q[20];\n\n\t/* initialize jk*/\n\tjk = init_jk[prec];\n\tjp = jk;\n\n\t/* determine jx,jv,q0, note that 3>q0 */\n\tjx = nx-1;\n\tjv = (e0-3)/24;  if(jv<0) jv=0;\n\tq0 = e0-24*(jv+1);\n\n\t/* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */\n\tj = jv-jx; m = jx+jk;\n\tfor (i=0; i<=m; i++,j++)\n\t\tf[i] = j<0 ? 0.0 : (double)ipio2[j];\n\n\t/* compute q[0],q[1],...q[jk] */\n\tfor (i=0; i<=jk; i++) {\n\t\tfor (j=0,fw=0.0; j<=jx; j++)\n\t\t\tfw += x[j]*f[jx+i-j];\n\t\tq[i] = fw;\n\t}\n\n\tjz = jk;\nrecompute:\n\t/* distill q[] into iq[] reversingly */\n\tfor (i=0,j=jz,z=q[jz]; j>0; i++,j--) {\n\t\tfw    = (double)(int32_t)(0x1p-24*z);\n\t\tiq[i] = (int32_t)(z - 0x1p24*fw);\n\t\tz     = q[j-1]+fw;\n\t}\n\n\t/* compute n */\n\tz  = scalbn(z,q0);       /* actual value of z */\n\tz -= 8.0*floor(z*0.125); /* trim off integer >= 8 */\n\tn  = (int32_t)z;\n\tz -= (double)n;\n\tih = 0;\n\tif (q0 > 0) {  /* need iq[jz-1] to determine n */\n\t\ti  = iq[jz-1]>>(24-q0); n += i;\n\t\tiq[jz-1] -= i<<(24-q0);\n\t\tih = iq[jz-1]>>(23-q0);\n\t}\n\telse if (q0 == 0) ih = iq[jz-1]>>23;\n\telse if (z >= 0.5) ih = 2;\n\n\tif (ih > 0) {  /* q > 0.5 */\n\t\tn += 1; carry = 0;\n\t\tfor (i=0; i<jz; i++) {  /* compute 1-q */\n\t\t\tj = iq[i];\n\t\t\tif (carry == 0) {\n\t\t\t\tif (j != 0) {\n\t\t\t\t\tcarry = 1;\n\t\t\t\t\tiq[i] = 0x1000000 - j;\n\t\t\t\t}\n\t\t\t} else\n\t\t\t\tiq[i] = 0xffffff - j;\n\t\t}\n\t\tif (q0 > 0) {  /* rare case: chance is 1 in 12 */\n\t\t\tswitch(q0) {\n\t\t\tcase 1:\n\t\t\t\tiq[jz-1] &= 0x7fffff; break;\n\t\t\tcase 2:\n\t\t\t\tiq[jz-1] &= 0x3fffff; break;\n\t\t\t}\n\t\t}\n\t\tif (ih == 2) {\n\t\t\tz = 1.0 - z;\n\t\t\tif (carry != 0)\n\t\t\t\tz -= scalbn(1.0,q0);\n\t\t}\n\t}\n\n\t/* check if recomputation is needed */\n\tif (z == 0.0) {\n\t\tj = 0;\n\t\tfor (i=jz-1; i>=jk; i--) j |= iq[i];\n\t\tif (j == 0) {  /* need recomputation */\n\t\t\tfor (k=1; iq[jk-k]==0; k++);  /* k = no. of terms needed */\n\n\t\t\tfor (i=jz+1; i<=jz+k; i++) {  /* add q[jz+1] to q[jz+k] */\n\t\t\t\tf[jx+i] = (double)ipio2[jv+i];\n\t\t\t\tfor (j=0,fw=0.0; j<=jx; j++)\n\t\t\t\t\tfw += x[j]*f[jx+i-j];\n\t\t\t\tq[i] = fw;\n\t\t\t}\n\t\t\tjz += k;\n\t\t\tgoto recompute;\n\t\t}\n\t}\n\n\t/* chop off zero terms */\n\tif (z == 0.0) {\n\t\tjz -= 1;\n\t\tq0 -= 24;\n\t\twhile (iq[jz] == 0) {\n\t\t\tjz--;\n\t\t\tq0 -= 24;\n\t\t}\n\t} else { /* break z into 24-bit if necessary */\n\t\tz = scalbn(z,-q0);\n\t\tif (z >= 0x1p24) {\n\t\t\tfw = (double)(int32_t)(0x1p-24*z);\n\t\t\tiq[jz] = (int32_t)(z - 0x1p24*fw);\n\t\t\tjz += 1;\n\t\t\tq0 += 24;\n\t\t\tiq[jz] = (int32_t)fw;\n\t\t} else\n\t\t\tiq[jz] = (int32_t)z;\n\t}\n\n\t/* convert integer \"bit\" chunk to floating-point value */\n\tfw = scalbn(1.0,q0);\n\tfor (i=jz; i>=0; i--) {\n\t\tq[i] = fw*(double)iq[i];\n\t\tfw *= 0x1p-24;\n\t}\n\n\t/* compute PIo2[0,...,jp]*q[jz,...,0] */\n\tfor(i=jz; i>=0; i--) {\n\t\tfor (fw=0.0,k=0; k<=jp && k<=jz-i; k++)\n\t\t\tfw += PIo2[k]*q[i+k];\n\t\tfq[jz-i] = fw;\n\t}\n\n\t/* compress fq[] into y[] */\n\tswitch(prec) {\n\tcase 0:\n\t\tfw = 0.0;\n\t\tfor (i=jz; i>=0; i--)\n\t\t\tfw += fq[i];\n\t\ty[0] = ih==0 ? fw : -fw;\n\t\tbreak;\n\tcase 1:\n\tcase 2:\n\t\tfw = 0.0;\n\t\tfor (i=jz; i>=0; i--)\n\t\t\tfw += fq[i];\n\t\t// TODO: drop excess precision here once double_t is used\n\t\tfw = (double)fw;\n\t\ty[0] = ih==0 ? fw : -fw;\n\t\tfw = fq[0]-fw;\n\t\tfor (i=1; i<=jz; i++)\n\t\t\tfw += fq[i];\n\t\ty[1] = ih==0 ? fw : -fw;\n\t\tbreak;\n\tcase 3:  /* painful */\n\t\tfor (i=jz; i>0; i--) {\n\t\t\tfw      = fq[i-1]+fq[i];\n\t\t\tfq[i]  += fq[i-1]-fw;\n\t\t\tfq[i-1] = fw;\n\t\t}\n\t\tfor (i=jz; i>1; i--) {\n\t\t\tfw      = fq[i-1]+fq[i];\n\t\t\tfq[i]  += fq[i-1]-fw;\n\t\t\tfq[i-1] = fw;\n\t\t}\n\t\tfor (fw=0.0,i=jz; i>=2; i--)\n\t\t\tfw += fq[i];\n\t\tif (ih==0) {\n\t\t\ty[0] =  fq[0]; y[1] =  fq[1]; y[2] =  fw;\n\t\t} else {\n\t\t\ty[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw;\n\t\t}\n\t}\n\treturn n&7;\n}\n"
  },
  {
    "path": "user.libc/src/math/__rem_pio2f.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/e_rem_pio2f.c */\n/*\n * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.\n * Debugged and optimized by Bruce D. Evans.\n */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/* __rem_pio2f(x,y)\n *\n * return the remainder of x rem pi/2 in *y\n * use double precision for everything except passing x\n * use __rem_pio2_large() for large x\n */\n\n#include \"libm.h\"\n\n#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1\n#define EPS DBL_EPSILON\n#elif FLT_EVAL_METHOD==2\n#define EPS LDBL_EPSILON\n#endif\n\n/*\n * invpio2:  53 bits of 2/pi\n * pio2_1:   first 25 bits of pi/2\n * pio2_1t:  pi/2 - pio2_1\n */\nstatic const double\ntoint   = 1.5/EPS,\npio4    = 0x1.921fb6p-1,\ninvpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */\npio2_1  = 1.57079631090164184570e+00, /* 0x3FF921FB, 0x50000000 */\npio2_1t = 1.58932547735281966916e-08; /* 0x3E5110b4, 0x611A6263 */\n\nint __rem_pio2f(float x, double *y)\n{\n\tunion {float f; uint32_t i;} u = {x};\n\tdouble tx[1],ty[1];\n\tdouble_t fn;\n\tuint32_t ix;\n\tint n, sign, e0;\n\n\tix = u.i & 0x7fffffff;\n\t/* 25+53 bit pi is good enough for medium size */\n\tif (ix < 0x4dc90fdb) {  /* |x| ~< 2^28*(pi/2), medium size */\n\t\t/* Use a specialized rint() to get fn. */\n\t\tfn = (double_t)x*invpio2 + toint - toint;\n\t\tn  = (int32_t)fn;\n\t\t*y = x - fn*pio2_1 - fn*pio2_1t;\n\t\t/* Matters with directed rounding. */\n\t\tif (predict_false(*y < -pio4)) {\n\t\t\tn--;\n\t\t\tfn--;\n\t\t\t*y = x - fn*pio2_1 - fn*pio2_1t;\n\t\t} else if (predict_false(*y > pio4)) {\n\t\t\tn++;\n\t\t\tfn++;\n\t\t\t*y = x - fn*pio2_1 - fn*pio2_1t;\n\t\t}\n\t\treturn n;\n\t}\n\tif(ix>=0x7f800000) {  /* x is inf or NaN */\n\t\t*y = x-x;\n\t\treturn 0;\n\t}\n\t/* scale x into [2^23, 2^24-1] */\n\tsign = u.i>>31;\n\te0 = (ix>>23) - (0x7f+23);  /* e0 = ilogb(|x|)-23, positive */\n\tu.i = ix - (e0<<23);\n\ttx[0] = u.f;\n\tn  =  __rem_pio2_large(tx,ty,e0,1,0);\n\tif (sign) {\n\t\t*y = -ty[0];\n\t\treturn -n;\n\t}\n\t*y = ty[0];\n\treturn n;\n}\n"
  },
  {
    "path": "user.libc/src/math/__rem_pio2l.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/ld80/e_rem_pio2.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.\n *\n * Developed at SunSoft, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n *\n * Optimized by Bruce D. Evans.\n */\n#include \"libm.h\"\n#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\n/* ld80 and ld128 version of __rem_pio2(x,y)\n *\n * return the remainder of x rem pi/2 in y[0]+y[1]\n * use __rem_pio2_large() for large x\n */\n\nstatic const long double toint = 1.5/LDBL_EPSILON;\n\n#if LDBL_MANT_DIG == 64\n/* u ~< 0x1p25*pi/2 */\n#define SMALL(u) (((u.i.se & 0x7fffU)<<16 | u.i.m>>48) < ((0x3fff + 25)<<16 | 0x921f>>1 | 0x8000))\n#define QUOBITS(x) ((uint32_t)(int32_t)x & 0x7fffffff)\n#define ROUND1 22\n#define ROUND2 61\n#define NX 3\n#define NY 2\n/*\n * invpio2:  64 bits of 2/pi\n * pio2_1:   first  39 bits of pi/2\n * pio2_1t:  pi/2 - pio2_1\n * pio2_2:   second 39 bits of pi/2\n * pio2_2t:  pi/2 - (pio2_1+pio2_2)\n * pio2_3:   third  39 bits of pi/2\n * pio2_3t:  pi/2 - (pio2_1+pio2_2+pio2_3)\n */\nstatic const double\npio2_1 =  1.57079632679597125389e+00, /* 0x3FF921FB, 0x54444000 */\npio2_2 = -1.07463465549783099519e-12, /* -0x12e7b967674000.0p-92 */\npio2_3 =  6.36831716351370313614e-25; /*  0x18a2e037074000.0p-133 */\nstatic const long double\npio4    =  0x1.921fb54442d1846ap-1L,\ninvpio2 =  6.36619772367581343076e-01L, /*  0xa2f9836e4e44152a.0p-64 */\npio2_1t = -1.07463465549719416346e-12L, /* -0x973dcb3b399d747f.0p-103 */\npio2_2t =  6.36831716351095013979e-25L, /*  0xc51701b839a25205.0p-144 */\npio2_3t = -2.75299651904407171810e-37L; /* -0xbb5bf6c7ddd660ce.0p-185 */\n#elif LDBL_MANT_DIG == 113\n/* u ~< 0x1p45*pi/2 */\n#define SMALL(u) (((u.i.se & 0x7fffU)<<16 | u.i.top) < ((0x3fff + 45)<<16 | 0x921f))\n#define QUOBITS(x) ((uint32_t)(int64_t)x & 0x7fffffff)\n#define ROUND1 51\n#define ROUND2 119\n#define NX 5\n#define NY 3\nstatic const long double\npio4    =  0x1.921fb54442d18469898cc51701b8p-1L,\ninvpio2 =  6.3661977236758134307553505349005747e-01L,\t/*  0x145f306dc9c882a53f84eafa3ea6a.0p-113 */\npio2_1  =  1.5707963267948966192292994253909555e+00L,\t/*  0x1921fb54442d18469800000000000.0p-112 */\npio2_1t =  2.0222662487959507323996846200947577e-21L,\t/*  0x13198a2e03707344a4093822299f3.0p-181 */\npio2_2  =  2.0222662487959507323994779168837751e-21L,\t/*  0x13198a2e03707344a400000000000.0p-181 */\npio2_2t =  2.0670321098263988236496903051604844e-43L,\t/*  0x127044533e63a0105df531d89cd91.0p-254 */\npio2_3  =  2.0670321098263988236499468110329591e-43L,\t/*  0x127044533e63a0105e00000000000.0p-254 */\npio2_3t = -2.5650587247459238361625433492959285e-65L;\t/* -0x159c4ec64ddaeb5f78671cbfb2210.0p-327 */\n#endif\n\nint __rem_pio2l(long double x, long double *y)\n{\n\tunion ldshape u,uz;\n\tlong double z,w,t,r,fn;\n\tdouble tx[NX],ty[NY];\n\tint ex,ey,n,i;\n\n\tu.f = x;\n\tex = u.i.se & 0x7fff;\n\tif (SMALL(u)) {\n\t\t/* rint(x/(pi/2)) */\n\t\tfn = x*invpio2 + toint - toint;\n\t\tn = QUOBITS(fn);\n\t\tr = x-fn*pio2_1;\n\t\tw = fn*pio2_1t;  /* 1st round good to 102/180 bits (ld80/ld128) */\n\t\t/* Matters with directed rounding. */\n\t\tif (predict_false(r - w < -pio4)) {\n\t\t\tn--;\n\t\t\tfn--;\n\t\t\tr = x - fn*pio2_1;\n\t\t\tw = fn*pio2_1t;\n\t\t} else if (predict_false(r - w > pio4)) {\n\t\t\tn++;\n\t\t\tfn++;\n\t\t\tr = x - fn*pio2_1;\n\t\t\tw = fn*pio2_1t;\n\t\t}\n\t\ty[0] = r-w;\n\t\tu.f = y[0];\n\t\tey = u.i.se & 0x7fff;\n\t\tif (ex - ey > ROUND1) {  /* 2nd iteration needed, good to 141/248 (ld80/ld128) */\n\t\t\tt = r;\n\t\t\tw = fn*pio2_2;\n\t\t\tr = t-w;\n\t\t\tw = fn*pio2_2t-((t-r)-w);\n\t\t\ty[0] = r-w;\n\t\t\tu.f = y[0];\n\t\t\tey = u.i.se & 0x7fff;\n\t\t\tif (ex - ey > ROUND2) {  /* 3rd iteration, good to 180/316 bits */\n\t\t\t\tt = r; /* will cover all possible cases (not verified for ld128) */\n\t\t\t\tw = fn*pio2_3;\n\t\t\t\tr = t-w;\n\t\t\t\tw = fn*pio2_3t-((t-r)-w);\n\t\t\t\ty[0] = r-w;\n\t\t\t}\n\t\t}\n\t\ty[1] = (r - y[0]) - w;\n\t\treturn n;\n\t}\n\t/*\n\t * all other (large) arguments\n\t */\n\tif (ex == 0x7fff) {                /* x is inf or NaN */\n\t\ty[0] = y[1] = x - x;\n\t\treturn 0;\n\t}\n\t/* set z = scalbn(|x|,-ilogb(x)+23) */\n\tuz.f = x;\n\tuz.i.se = 0x3fff + 23;\n\tz = uz.f;\n\tfor (i=0; i < NX - 1; i++) {\n\t\ttx[i] = (double)(int32_t)z;\n\t\tz     = (z-tx[i])*0x1p24;\n\t}\n\ttx[i] = z;\n\twhile (tx[i] == 0)\n\t\ti--;\n\tn = __rem_pio2_large(tx, ty, ex-0x3fff-23, i+1, NY);\n\tw = ty[1];\n\tif (NY == 3)\n\t\tw += ty[2];\n\tr = ty[0] + w;\n\t/* TODO: for ld128 this does not follow the recommendation of the\n\tcomments of __rem_pio2_large which seem wrong if |ty[0]| > |ty[1]+ty[2]| */\n\tw -= r - ty[0];\n\tif (u.i.se >> 15) {\n\t\ty[0] = -r;\n\t\ty[1] = -w;\n\t\treturn -n;\n\t}\n\ty[0] = r;\n\ty[1] = w;\n\treturn n;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/__signbit.c",
    "content": "#include \"libm.h\"\n\n// FIXME: macro in math.h\nint __signbit(double x)\n{\n\tunion {\n\t\tdouble d;\n\t\tuint64_t i;\n\t} y = { x };\n\treturn y.i>>63;\n}\n\n\n"
  },
  {
    "path": "user.libc/src/math/__signbitf.c",
    "content": "#include \"libm.h\"\n\n// FIXME: macro in math.h\nint __signbitf(float x)\n{\n\tunion {\n\t\tfloat f;\n\t\tuint32_t i;\n\t} y = { x };\n\treturn y.i>>31;\n}\n"
  },
  {
    "path": "user.libc/src/math/__signbitl.c",
    "content": "#include \"libm.h\"\n\n#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\nint __signbitl(long double x)\n{\n\tunion ldshape u = {x};\n\treturn u.i.se >> 15;\n}\n#elif LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nint __signbitl(long double x)\n{\n\treturn __signbit(x);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/__sin.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/k_sin.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunSoft, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/* __sin( x, y, iy)\n * kernel sin function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854\n * Input x is assumed to be bounded by ~pi/4 in magnitude.\n * Input y is the tail of x.\n * Input iy indicates whether y is 0. (if iy=0, y assume to be 0).\n *\n * Algorithm\n *      1. Since sin(-x) = -sin(x), we need only to consider positive x.\n *      2. Callers must return sin(-0) = -0 without calling here since our\n *         odd polynomial is not evaluated in a way that preserves -0.\n *         Callers may do the optimization sin(x) ~ x for tiny x.\n *      3. sin(x) is approximated by a polynomial of degree 13 on\n *         [0,pi/4]\n *                               3            13\n *              sin(x) ~ x + S1*x + ... + S6*x\n *         where\n *\n *      |sin(x)         2     4     6     8     10     12  |     -58\n *      |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x  +S6*x   )| <= 2\n *      |  x                                               |\n *\n *      4. sin(x+y) = sin(x) + sin'(x')*y\n *                  ~ sin(x) + (1-x*x/2)*y\n *         For better accuracy, let\n *                   3      2      2      2      2\n *              r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6))))\n *         then                   3    2\n *              sin(x) = x + (S1*x + (x *(r-y/2)+y))\n */\n\n#include \"libm.h\"\n\nstatic const double\nS1  = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */\nS2  =  8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */\nS3  = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */\nS4  =  2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */\nS5  = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */\nS6  =  1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */\n\ndouble __sin(double x, double y, int iy)\n{\n\tdouble_t z,r,v,w;\n\n\tz = x*x;\n\tw = z*z;\n\tr = S2 + z*(S3 + z*S4) + z*w*(S5 + z*S6);\n\tv = z*x;\n\tif (iy == 0)\n\t\treturn x + v*(S1 + z*r);\n\telse\n\t\treturn x - ((z*(0.5*y - v*r) - y) - v*S1);\n}\n"
  },
  {
    "path": "user.libc/src/math/__sindf.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/k_sinf.c */\n/*\n * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.\n * Optimized by Bruce D. Evans.\n */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n\n#include \"libm.h\"\n\n/* |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]). */\nstatic const double\nS1 = -0x15555554cbac77.0p-55, /* -0.166666666416265235595 */\nS2 =  0x111110896efbb2.0p-59, /*  0.0083333293858894631756 */\nS3 = -0x1a00f9e2cae774.0p-65, /* -0.000198393348360966317347 */\nS4 =  0x16cd878c3b46a7.0p-71; /*  0.0000027183114939898219064 */\n\nfloat __sindf(double x)\n{\n\tdouble_t r, s, w, z;\n\n\t/* Try to optimize for parallel evaluation as in __tandf.c. */\n\tz = x*x;\n\tw = z*z;\n\tr = S3 + z*S4;\n\ts = z*x;\n\treturn (x + s*(S1 + z*S2)) + s*w*r;\n}\n"
  },
  {
    "path": "user.libc/src/math/__sinl.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/ld80/k_sinl.c */\n/* origin: FreeBSD /usr/src/lib/msun/ld128/k_sinl.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.\n *\n * Developed at SunSoft, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n\n#include \"libm.h\"\n\n#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\n#if LDBL_MANT_DIG == 64\n/*\n * ld80 version of __sin.c.  See __sin.c for most comments.\n */\n/*\n * Domain [-0.7854, 0.7854], range ~[-1.89e-22, 1.915e-22]\n * |sin(x)/x - s(x)| < 2**-72.1\n *\n * See __cosl.c for more details about the polynomial.\n */\nstatic const long double\nS1 = -0.166666666666666666671L;   /* -0xaaaaaaaaaaaaaaab.0p-66 */\nstatic const double\nS2 =  0.0083333333333333332,      /*  0x11111111111111.0p-59 */\nS3 = -0.00019841269841269427,     /* -0x1a01a01a019f81.0p-65 */\nS4 =  0.0000027557319223597490,   /*  0x171de3a55560f7.0p-71 */\nS5 = -0.000000025052108218074604, /* -0x1ae64564f16cad.0p-78 */\nS6 =  1.6059006598854211e-10,     /*  0x161242b90243b5.0p-85 */\nS7 = -7.6429779983024564e-13,     /* -0x1ae42ebd1b2e00.0p-93 */\nS8 =  2.6174587166648325e-15;     /*  0x179372ea0b3f64.0p-101 */\n#define POLY(z) (S2+z*(S3+z*(S4+z*(S5+z*(S6+z*(S7+z*S8))))))\n#elif LDBL_MANT_DIG == 113\n/*\n * ld128 version of __sin.c.  See __sin.c for most comments.\n */\n/*\n * Domain [-0.7854, 0.7854], range ~[-1.53e-37, 1.659e-37]\n * |sin(x)/x - s(x)| < 2**-122.1\n *\n * See __cosl.c for more details about the polynomial.\n */\nstatic const long double\nS1 = -0.16666666666666666666666666666666666606732416116558L,\nS2 =  0.0083333333333333333333333333333331135404851288270047L,\nS3 = -0.00019841269841269841269841269839935785325638310428717L,\nS4 =  0.27557319223985890652557316053039946268333231205686e-5L,\nS5 = -0.25052108385441718775048214826384312253862930064745e-7L,\nS6 =  0.16059043836821614596571832194524392581082444805729e-9L,\nS7 = -0.76471637318198151807063387954939213287488216303768e-12L,\nS8 =  0.28114572543451292625024967174638477283187397621303e-14L;\nstatic const double\nS9  = -0.82206352458348947812512122163446202498005154296863e-17,\nS10 =  0.19572940011906109418080609928334380560135358385256e-19,\nS11 = -0.38680813379701966970673724299207480965452616911420e-22,\nS12 =  0.64038150078671872796678569586315881020659912139412e-25;\n#define POLY(z) (S2+z*(S3+z*(S4+z*(S5+z*(S6+z*(S7+z*(S8+ \\\n\tz*(S9+z*(S10+z*(S11+z*S12))))))))))\n#endif\n\nlong double __sinl(long double x, long double y, int iy)\n{\n\tlong double z,r,v;\n\n\tz = x*x;\n\tv = z*x;\n\tr = POLY(z);\n\tif (iy == 0)\n\t\treturn x+v*(S1+z*r);\n\treturn x-((z*(0.5*y-v*r)-y)-v*S1);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/__tan.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/k_tan.c */\n/*\n * ====================================================\n * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.\n *\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/* __tan( x, y, k )\n * kernel tan function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854\n * Input x is assumed to be bounded by ~pi/4 in magnitude.\n * Input y is the tail of x.\n * Input odd indicates whether tan (if odd = 0) or -1/tan (if odd = 1) is returned.\n *\n * Algorithm\n *      1. Since tan(-x) = -tan(x), we need only to consider positive x.\n *      2. Callers must return tan(-0) = -0 without calling here since our\n *         odd polynomial is not evaluated in a way that preserves -0.\n *         Callers may do the optimization tan(x) ~ x for tiny x.\n *      3. tan(x) is approximated by a odd polynomial of degree 27 on\n *         [0,0.67434]\n *                               3             27\n *              tan(x) ~ x + T1*x + ... + T13*x\n *         where\n *\n *              |tan(x)         2     4            26   |     -59.2\n *              |----- - (1+T1*x +T2*x +.... +T13*x    )| <= 2\n *              |  x                                    |\n *\n *         Note: tan(x+y) = tan(x) + tan'(x)*y\n *                        ~ tan(x) + (1+x*x)*y\n *         Therefore, for better accuracy in computing tan(x+y), let\n *                   3      2      2       2       2\n *              r = x *(T2+x *(T3+x *(...+x *(T12+x *T13))))\n *         then\n *                                  3    2\n *              tan(x+y) = x + (T1*x + (x *(r+y)+y))\n *\n *      4. For x in [0.67434,pi/4],  let y = pi/4 - x, then\n *              tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y))\n *                     = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y)))\n */\n\n#include \"libm.h\"\n\nstatic const double T[] = {\n             3.33333333333334091986e-01, /* 3FD55555, 55555563 */\n             1.33333333333201242699e-01, /* 3FC11111, 1110FE7A */\n             5.39682539762260521377e-02, /* 3FABA1BA, 1BB341FE */\n             2.18694882948595424599e-02, /* 3F9664F4, 8406D637 */\n             8.86323982359930005737e-03, /* 3F8226E3, E96E8493 */\n             3.59207910759131235356e-03, /* 3F6D6D22, C9560328 */\n             1.45620945432529025516e-03, /* 3F57DBC8, FEE08315 */\n             5.88041240820264096874e-04, /* 3F4344D8, F2F26501 */\n             2.46463134818469906812e-04, /* 3F3026F7, 1A8D1068 */\n             7.81794442939557092300e-05, /* 3F147E88, A03792A6 */\n             7.14072491382608190305e-05, /* 3F12B80F, 32F0A7E9 */\n            -1.85586374855275456654e-05, /* BEF375CB, DB605373 */\n             2.59073051863633712884e-05, /* 3EFB2A70, 74BF7AD4 */\n},\npio4 =       7.85398163397448278999e-01, /* 3FE921FB, 54442D18 */\npio4lo =     3.06161699786838301793e-17; /* 3C81A626, 33145C07 */\n\ndouble __tan(double x, double y, int odd)\n{\n\tdouble_t z, r, v, w, s, a;\n\tdouble w0, a0;\n\tuint32_t hx;\n\tint big, sign;\n\n\tGET_HIGH_WORD(hx,x);\n\tbig = (hx&0x7fffffff) >= 0x3FE59428; /* |x| >= 0.6744 */\n\tif (big) {\n\t\tsign = hx>>31;\n\t\tif (sign) {\n\t\t\tx = -x;\n\t\t\ty = -y;\n\t\t}\n\t\tx = (pio4 - x) + (pio4lo - y);\n\t\ty = 0.0;\n\t}\n\tz = x * x;\n\tw = z * z;\n\t/*\n\t * Break x^5*(T[1]+x^2*T[2]+...) into\n\t * x^5(T[1]+x^4*T[3]+...+x^20*T[11]) +\n\t * x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12]))\n\t */\n\tr = T[1] + w*(T[3] + w*(T[5] + w*(T[7] + w*(T[9] + w*T[11]))));\n\tv = z*(T[2] + w*(T[4] + w*(T[6] + w*(T[8] + w*(T[10] + w*T[12])))));\n\ts = z * x;\n\tr = y + z*(s*(r + v) + y) + s*T[0];\n\tw = x + r;\n\tif (big) {\n\t\ts = 1 - 2*odd;\n\t\tv = s - 2.0 * (x + (r - w*w/(w + s)));\n\t\treturn sign ? -v : v;\n\t}\n\tif (!odd)\n\t\treturn w;\n\t/* -1.0/(x+r) has up to 2ulp error, so compute it accurately */\n\tw0 = w;\n\tSET_LOW_WORD(w0, 0);\n\tv = r - (w0 - x);       /* w0+v = r+x */\n\ta0 = a = -1.0 / w;\n\tSET_LOW_WORD(a0, 0);\n\treturn a0 + a*(1.0 + a0*w0 + a0*v);\n}\n"
  },
  {
    "path": "user.libc/src/math/__tandf.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/k_tanf.c */\n/*\n * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.\n * Optimized by Bruce D. Evans.\n */\n/*\n * ====================================================\n * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.\n *\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n\n#include \"libm.h\"\n\n/* |tan(x)/x - t(x)| < 2**-25.5 (~[-2e-08, 2e-08]). */\nstatic const double T[] = {\n  0x15554d3418c99f.0p-54, /* 0.333331395030791399758 */\n  0x1112fd38999f72.0p-55, /* 0.133392002712976742718 */\n  0x1b54c91d865afe.0p-57, /* 0.0533812378445670393523 */\n  0x191df3908c33ce.0p-58, /* 0.0245283181166547278873 */\n  0x185dadfcecf44e.0p-61, /* 0.00297435743359967304927 */\n  0x1362b9bf971bcd.0p-59, /* 0.00946564784943673166728 */\n};\n\nfloat __tandf(double x, int odd)\n{\n\tdouble_t z,r,w,s,t,u;\n\n\tz = x*x;\n\t/*\n\t * Split up the polynomial into small independent terms to give\n\t * opportunities for parallel evaluation.  The chosen splitting is\n\t * micro-optimized for Athlons (XP, X64).  It costs 2 multiplications\n\t * relative to Horner's method on sequential machines.\n\t *\n\t * We add the small terms from lowest degree up for efficiency on\n\t * non-sequential machines (the lowest degree terms tend to be ready\n\t * earlier).  Apart from this, we don't care about order of\n\t * operations, and don't need to to care since we have precision to\n\t * spare.  However, the chosen splitting is good for accuracy too,\n\t * and would give results as accurate as Horner's method if the\n\t * small terms were added from highest degree down.\n\t */\n\tr = T[4] + z*T[5];\n\tt = T[2] + z*T[3];\n\tw = z*z;\n\ts = z*x;\n\tu = T[0] + z*T[1];\n\tr = (x + s*u) + (s*w)*(t + w*r);\n\treturn odd ? -1.0/r : r;\n}\n"
  },
  {
    "path": "user.libc/src/math/__tanl.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/ld80/k_tanl.c */\n/* origin: FreeBSD /usr/src/lib/msun/ld128/k_tanl.c */\n/*\n * ====================================================\n * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.\n * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.\n *\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n\n#include \"libm.h\"\n\n#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\n#if LDBL_MANT_DIG == 64\n/*\n * ld80 version of __tan.c.  See __tan.c for most comments.\n */\n/*\n * Domain [-0.67434, 0.67434], range ~[-2.25e-22, 1.921e-22]\n * |tan(x)/x - t(x)| < 2**-71.9\n *\n * See __cosl.c for more details about the polynomial.\n */\nstatic const long double\nT3 =  0.333333333333333333180L,         /*  0xaaaaaaaaaaaaaaa5.0p-65 */\nT5 =  0.133333333333333372290L,         /*  0x88888888888893c3.0p-66 */\nT7 =  0.0539682539682504975744L,        /*  0xdd0dd0dd0dc13ba2.0p-68 */\npio4   =  0.785398163397448309628L,     /*  0xc90fdaa22168c235.0p-64 */\npio4lo = -1.25413940316708300586e-20L;  /* -0xece675d1fc8f8cbb.0p-130 */\nstatic const double\nT9  =  0.021869488536312216,            /*  0x1664f4882cc1c2.0p-58 */\nT11 =  0.0088632355256619590,           /*  0x1226e355c17612.0p-59 */\nT13 =  0.0035921281113786528,           /*  0x1d6d3d185d7ff8.0p-61 */\nT15 =  0.0014558334756312418,           /*  0x17da354aa3f96b.0p-62 */\nT17 =  0.00059003538700862256,          /*  0x13559358685b83.0p-63 */\nT19 =  0.00023907843576635544,          /*  0x1f56242026b5be.0p-65 */\nT21 =  0.000097154625656538905,         /*  0x1977efc26806f4.0p-66 */\nT23 =  0.000038440165747303162,         /*  0x14275a09b3ceac.0p-67 */\nT25 =  0.000018082171885432524,         /*  0x12f5e563e5487e.0p-68 */\nT27 =  0.0000024196006108814377,        /*  0x144c0d80cc6896.0p-71 */\nT29 =  0.0000078293456938132840,        /*  0x106b59141a6cb3.0p-69 */\nT31 = -0.0000032609076735050182,        /* -0x1b5abef3ba4b59.0p-71 */\nT33 =  0.0000023261313142559411;        /*  0x13835436c0c87f.0p-71 */\n#define RPOLY(w) (T5 + w * (T9 + w * (T13 + w * (T17 + w * (T21 + \\\n\tw * (T25 + w * (T29 + w * T33)))))))\n#define VPOLY(w) (T7 + w * (T11 + w * (T15 + w * (T19 + w * (T23 + \\\n\tw * (T27 + w * T31))))))\n#elif LDBL_MANT_DIG == 113\n/*\n * ld128 version of __tan.c.  See __tan.c for most comments.\n */\n/*\n * Domain [-0.67434, 0.67434], range ~[-3.37e-36, 1.982e-37]\n * |tan(x)/x - t(x)| < 2**-117.8 (XXX should be ~1e-37)\n *\n * See __cosl.c for more details about the polynomial.\n */\nstatic const long double\nT3 = 0x1.5555555555555555555555555553p-2L,\nT5 = 0x1.1111111111111111111111111eb5p-3L,\nT7 = 0x1.ba1ba1ba1ba1ba1ba1ba1b694cd6p-5L,\nT9 = 0x1.664f4882c10f9f32d6bbe09d8bcdp-6L,\nT11 = 0x1.226e355e6c23c8f5b4f5762322eep-7L,\nT13 = 0x1.d6d3d0e157ddfb5fed8e84e27b37p-9L,\nT15 = 0x1.7da36452b75e2b5fce9ee7c2c92ep-10L,\nT17 = 0x1.355824803674477dfcf726649efep-11L,\nT19 = 0x1.f57d7734d1656e0aceb716f614c2p-13L,\nT21 = 0x1.967e18afcb180ed942dfdc518d6cp-14L,\nT23 = 0x1.497d8eea21e95bc7e2aa79b9f2cdp-15L,\nT25 = 0x1.0b132d39f055c81be49eff7afd50p-16L,\nT27 = 0x1.b0f72d33eff7bfa2fbc1059d90b6p-18L,\nT29 = 0x1.5ef2daf21d1113df38d0fbc00267p-19L,\nT31 = 0x1.1c77d6eac0234988cdaa04c96626p-20L,\nT33 = 0x1.cd2a5a292b180e0bdd701057dfe3p-22L,\nT35 = 0x1.75c7357d0298c01a31d0a6f7d518p-23L,\nT37 = 0x1.2f3190f4718a9a520f98f50081fcp-24L,\npio4 = 0x1.921fb54442d18469898cc51701b8p-1L,\npio4lo = 0x1.cd129024e088a67cc74020bbea60p-116L;\nstatic const double\nT39 =  0.000000028443389121318352,\t/*  0x1e8a7592977938.0p-78 */\nT41 =  0.000000011981013102001973,\t/*  0x19baa1b1223219.0p-79 */\nT43 =  0.0000000038303578044958070,\t/*  0x107385dfb24529.0p-80 */\nT45 =  0.0000000034664378216909893,\t/*  0x1dc6c702a05262.0p-81 */\nT47 = -0.0000000015090641701997785,\t/* -0x19ecef3569ebb6.0p-82 */\nT49 =  0.0000000029449552300483952,\t/*  0x194c0668da786a.0p-81 */\nT51 = -0.0000000022006995706097711,\t/* -0x12e763b8845268.0p-81 */\nT53 =  0.0000000015468200913196612,\t/*  0x1a92fc98c29554.0p-82 */\nT55 = -0.00000000061311613386849674,\t/* -0x151106cbc779a9.0p-83 */\nT57 =  1.4912469681508012e-10;\t\t/*  0x147edbdba6f43a.0p-85 */\n#define RPOLY(w) (T5 + w * (T9 + w * (T13 + w * (T17 + w * (T21 + \\\n\tw * (T25 + w * (T29 + w * (T33 + w * (T37 + w * (T41 + \\\n\tw * (T45 + w * (T49 + w * (T53 + w * T57)))))))))))))\n#define VPOLY(w) (T7 + w * (T11 + w * (T15 + w * (T19 + w * (T23 + \\\n\tw * (T27 + w * (T31 + w * (T35 + w * (T39 + w * (T43 + \\\n\tw * (T47 + w * (T51 + w * T55))))))))))))\n#endif\n\nlong double __tanl(long double x, long double y, int odd) {\n\tlong double z, r, v, w, s, a, t;\n\tint big, sign;\n\n\tbig = fabsl(x) >= 0.67434;\n\tif (big) {\n\t\tsign = 0;\n\t\tif (x < 0) {\n\t\t\tsign = 1;\n\t\t\tx = -x;\n\t\t\ty = -y;\n\t\t}\n\t\tx = (pio4 - x) + (pio4lo - y);\n\t\ty = 0.0;\n\t}\n\tz = x * x;\n\tw = z * z;\n\tr = RPOLY(w);\n\tv = z * VPOLY(w);\n\ts = z * x;\n\tr = y + z * (s * (r + v) + y) + T3 * s;\n\tw = x + r;\n\tif (big) {\n\t\ts = 1 - 2*odd;\n\t\tv = s - 2.0 * (x + (r - w * w / (w + s)));\n\t\treturn sign ? -v : v;\n\t}\n\tif (!odd)\n\t\treturn w;\n\t/*\n\t * if allow error up to 2 ulp, simply return\n\t * -1.0 / (x+r) here\n\t */\n\t/* compute -1.0 / (x+r) accurately */\n\tz = w;\n\tz = z + 0x1p32 - 0x1p32;\n\tv = r - (z - x);        /* z+v = r+x */\n\tt = a = -1.0 / w;       /* a = -1.0/w */\n\tt = t + 0x1p32 - 0x1p32;\n\ts = 1.0 + t * z;\n\treturn t + a * (s + t * v);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/aarch64/ceil.c",
    "content": "#include <math.h>\n\ndouble ceil(double x)\n{\n\t__asm__ (\"frintp %d0, %d1\" : \"=w\"(x) : \"w\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/ceilf.c",
    "content": "#include <math.h>\n\nfloat ceilf(float x)\n{\n\t__asm__ (\"frintp %s0, %s1\" : \"=w\"(x) : \"w\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/fabs.c",
    "content": "#include <math.h>\n\ndouble fabs(double x)\n{\n\t__asm__ (\"fabs %d0, %d1\" : \"=w\"(x) : \"w\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/fabsf.c",
    "content": "#include <math.h>\n\nfloat fabsf(float x)\n{\n\t__asm__ (\"fabs %s0, %s1\" : \"=w\"(x) : \"w\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/floor.c",
    "content": "#include <math.h>\n\ndouble floor(double x)\n{\n\t__asm__ (\"frintm %d0, %d1\" : \"=w\"(x) : \"w\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/floorf.c",
    "content": "#include <math.h>\n\nfloat floorf(float x)\n{\n\t__asm__ (\"frintm %s0, %s1\" : \"=w\"(x) : \"w\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/fma.c",
    "content": "#include <math.h>\n\ndouble fma(double x, double y, double z)\n{\n\t__asm__ (\"fmadd %d0, %d1, %d2, %d3\" : \"=w\"(x) : \"w\"(x), \"w\"(y), \"w\"(z));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/fmaf.c",
    "content": "#include <math.h>\n\nfloat fmaf(float x, float y, float z)\n{\n\t__asm__ (\"fmadd %s0, %s1, %s2, %s3\" : \"=w\"(x) : \"w\"(x), \"w\"(y), \"w\"(z));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/fmax.c",
    "content": "#include <math.h>\n\ndouble fmax(double x, double y)\n{\n\t__asm__ (\"fmaxnm %d0, %d1, %d2\" : \"=w\"(x) : \"w\"(x), \"w\"(y));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/fmaxf.c",
    "content": "#include <math.h>\n\nfloat fmaxf(float x, float y)\n{\n\t__asm__ (\"fmaxnm %s0, %s1, %s2\" : \"=w\"(x) : \"w\"(x), \"w\"(y));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/fmin.c",
    "content": "#include <math.h>\n\ndouble fmin(double x, double y)\n{\n\t__asm__ (\"fminnm %d0, %d1, %d2\" : \"=w\"(x) : \"w\"(x), \"w\"(y));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/fminf.c",
    "content": "#include <math.h>\n\nfloat fminf(float x, float y)\n{\n\t__asm__ (\"fminnm %s0, %s1, %s2\" : \"=w\"(x) : \"w\"(x), \"w\"(y));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/llrint.c",
    "content": "#include <math.h>\n\nlong long llrint(double x)\n{\n\tlong long n;\n\t__asm__ (\n\t\t\"frintx %d1, %d1\\n\"\n\t\t\"fcvtzs %x0, %d1\\n\" : \"=r\"(n), \"+w\"(x));\n\treturn n;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/llrintf.c",
    "content": "#include <math.h>\n\nlong long llrintf(float x)\n{\n\tlong long n;\n\t__asm__ (\n\t\t\"frintx %s1, %s1\\n\"\n\t\t\"fcvtzs %x0, %s1\\n\" : \"=r\"(n), \"+w\"(x));\n\treturn n;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/llround.c",
    "content": "#include <math.h>\n\nlong long llround(double x)\n{\n\tlong long n;\n\t__asm__ (\"fcvtas %x0, %d1\" : \"=r\"(n) : \"w\"(x));\n\treturn n;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/llroundf.c",
    "content": "#include <math.h>\n\nlong long llroundf(float x)\n{\n\tlong long n;\n\t__asm__ (\"fcvtas %x0, %s1\" : \"=r\"(n) : \"w\"(x));\n\treturn n;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/lrint.c",
    "content": "#include <math.h>\n\nlong lrint(double x)\n{\n\tlong n;\n\t__asm__ (\n\t\t\"frintx %d1, %d1\\n\"\n\t\t\"fcvtzs %x0, %d1\\n\" : \"=r\"(n), \"+w\"(x));\n\treturn n;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/lrintf.c",
    "content": "#include <math.h>\n\nlong lrintf(float x)\n{\n\tlong n;\n\t__asm__ (\n\t\t\"frintx %s1, %s1\\n\"\n\t\t\"fcvtzs %x0, %s1\\n\" : \"=r\"(n), \"+w\"(x));\n\treturn n;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/lround.c",
    "content": "#include <math.h>\n\nlong lround(double x)\n{\n\tlong n;\n\t__asm__ (\"fcvtas %x0, %d1\" : \"=r\"(n) : \"w\"(x));\n\treturn n;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/lroundf.c",
    "content": "#include <math.h>\n\nlong lroundf(float x)\n{\n\tlong n;\n\t__asm__ (\"fcvtas %x0, %s1\" : \"=r\"(n) : \"w\"(x));\n\treturn n;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/nearbyint.c",
    "content": "#include <math.h>\n\ndouble nearbyint(double x)\n{\n\t__asm__ (\"frinti %d0, %d1\" : \"=w\"(x) : \"w\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/nearbyintf.c",
    "content": "#include <math.h>\n\nfloat nearbyintf(float x)\n{\n\t__asm__ (\"frinti %s0, %s1\" : \"=w\"(x) : \"w\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/rint.c",
    "content": "#include <math.h>\n\ndouble rint(double x)\n{\n\t__asm__ (\"frintx %d0, %d1\" : \"=w\"(x) : \"w\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/rintf.c",
    "content": "#include <math.h>\n\nfloat rintf(float x)\n{\n\t__asm__ (\"frintx %s0, %s1\" : \"=w\"(x) : \"w\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/round.c",
    "content": "#include <math.h>\n\ndouble round(double x)\n{\n\t__asm__ (\"frinta %d0, %d1\" : \"=w\"(x) : \"w\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/roundf.c",
    "content": "#include <math.h>\n\nfloat roundf(float x)\n{\n\t__asm__ (\"frinta %s0, %s1\" : \"=w\"(x) : \"w\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/sqrt.c",
    "content": "#include <math.h>\n\ndouble sqrt(double x)\n{\n\t__asm__ (\"fsqrt %d0, %d1\" : \"=w\"(x) : \"w\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/sqrtf.c",
    "content": "#include <math.h>\n\nfloat sqrtf(float x)\n{\n\t__asm__ (\"fsqrt %s0, %s1\" : \"=w\"(x) : \"w\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/trunc.c",
    "content": "#include <math.h>\n\ndouble trunc(double x)\n{\n\t__asm__ (\"frintz %d0, %d1\" : \"=w\"(x) : \"w\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/aarch64/truncf.c",
    "content": "#include <math.h>\n\nfloat truncf(float x)\n{\n\t__asm__ (\"frintz %s0, %s1\" : \"=w\"(x) : \"w\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/acos.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/e_acos.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunSoft, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/* acos(x)\n * Method :\n *      acos(x)  = pi/2 - asin(x)\n *      acos(-x) = pi/2 + asin(x)\n * For |x|<=0.5\n *      acos(x) = pi/2 - (x + x*x^2*R(x^2))     (see asin.c)\n * For x>0.5\n *      acos(x) = pi/2 - (pi/2 - 2asin(sqrt((1-x)/2)))\n *              = 2asin(sqrt((1-x)/2))\n *              = 2s + 2s*z*R(z)        ...z=(1-x)/2, s=sqrt(z)\n *              = 2f + (2c + 2s*z*R(z))\n *     where f=hi part of s, and c = (z-f*f)/(s+f) is the correction term\n *     for f so that f+c ~ sqrt(z).\n * For x<-0.5\n *      acos(x) = pi - 2asin(sqrt((1-|x|)/2))\n *              = pi - 0.5*(s+s*z*R(z)), where z=(1-|x|)/2,s=sqrt(z)\n *\n * Special cases:\n *      if x is NaN, return x itself;\n *      if |x|>1, return NaN with invalid signal.\n *\n * Function needed: sqrt\n */\n\n#include \"libm.h\"\n\nstatic const double\npio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */\npio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */\npS0 =  1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */\npS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */\npS2 =  2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */\npS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */\npS4 =  7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */\npS5 =  3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */\nqS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */\nqS2 =  2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */\nqS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */\nqS4 =  7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */\n\nstatic double R(double z)\n{\n\tdouble_t p, q;\n\tp = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));\n\tq = 1.0+z*(qS1+z*(qS2+z*(qS3+z*qS4)));\n\treturn p/q;\n}\n\ndouble acos(double x)\n{\n\tdouble z,w,s,c,df;\n\tuint32_t hx,ix;\n\n\tGET_HIGH_WORD(hx, x);\n\tix = hx & 0x7fffffff;\n\t/* |x| >= 1 or nan */\n\tif (ix >= 0x3ff00000) {\n\t\tuint32_t lx;\n\n\t\tGET_LOW_WORD(lx,x);\n\t\tif ((ix-0x3ff00000 | lx) == 0) {\n\t\t\t/* acos(1)=0, acos(-1)=pi */\n\t\t\tif (hx >> 31)\n\t\t\t\treturn 2*pio2_hi + 0x1p-120f;\n\t\t\treturn 0;\n\t\t}\n\t\treturn 0/(x-x);\n\t}\n\t/* |x| < 0.5 */\n\tif (ix < 0x3fe00000) {\n\t\tif (ix <= 0x3c600000)  /* |x| < 2**-57 */\n\t\t\treturn pio2_hi + 0x1p-120f;\n\t\treturn pio2_hi - (x - (pio2_lo-x*R(x*x)));\n\t}\n\t/* x < -0.5 */\n\tif (hx >> 31) {\n\t\tz = (1.0+x)*0.5;\n\t\ts = sqrt(z);\n\t\tw = R(z)*s-pio2_lo;\n\t\treturn 2*(pio2_hi - (s+w));\n\t}\n\t/* x > 0.5 */\n\tz = (1.0-x)*0.5;\n\ts = sqrt(z);\n\tdf = s;\n\tSET_LOW_WORD(df,0);\n\tc = (z-df*df)/(s+df);\n\tw = R(z)*s+c;\n\treturn 2*(df+w);\n}\n"
  },
  {
    "path": "user.libc/src/math/acosf.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/e_acosf.c */\n/*\n * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.\n */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n\n#include \"libm.h\"\n\nstatic const float\npio2_hi = 1.5707962513e+00, /* 0x3fc90fda */\npio2_lo = 7.5497894159e-08, /* 0x33a22168 */\npS0 =  1.6666586697e-01,\npS1 = -4.2743422091e-02,\npS2 = -8.6563630030e-03,\nqS1 = -7.0662963390e-01;\n\nstatic float R(float z)\n{\n\tfloat_t p, q;\n\tp = z*(pS0+z*(pS1+z*pS2));\n\tq = 1.0f+z*qS1;\n\treturn p/q;\n}\n\nfloat acosf(float x)\n{\n\tfloat z,w,s,c,df;\n\tuint32_t hx,ix;\n\n\tGET_FLOAT_WORD(hx, x);\n\tix = hx & 0x7fffffff;\n\t/* |x| >= 1 or nan */\n\tif (ix >= 0x3f800000) {\n\t\tif (ix == 0x3f800000) {\n\t\t\tif (hx >> 31)\n\t\t\t\treturn 2*pio2_hi + 0x1p-120f;\n\t\t\treturn 0;\n\t\t}\n\t\treturn 0/(x-x);\n\t}\n\t/* |x| < 0.5 */\n\tif (ix < 0x3f000000) {\n\t\tif (ix <= 0x32800000) /* |x| < 2**-26 */\n\t\t\treturn pio2_hi + 0x1p-120f;\n\t\treturn pio2_hi - (x - (pio2_lo-x*R(x*x)));\n\t}\n\t/* x < -0.5 */\n\tif (hx >> 31) {\n\t\tz = (1+x)*0.5f;\n\t\ts = sqrtf(z);\n\t\tw = R(z)*s-pio2_lo;\n\t\treturn 2*(pio2_hi - (s+w));\n\t}\n\t/* x > 0.5 */\n\tz = (1-x)*0.5f;\n\ts = sqrtf(z);\n\tGET_FLOAT_WORD(hx,s);\n\tSET_FLOAT_WORD(df,hx&0xfffff000);\n\tc = (z-df*df)/(s+df);\n\tw = R(z)*s+c;\n\treturn 2*(df+w);\n}\n"
  },
  {
    "path": "user.libc/src/math/acosh.c",
    "content": "#include \"libm.h\"\n\n#if FLT_EVAL_METHOD==2\n#undef sqrt\n#define sqrt sqrtl\n#endif\n\n/* acosh(x) = log(x + sqrt(x*x-1)) */\ndouble acosh(double x)\n{\n\tunion {double f; uint64_t i;} u = {.f = x};\n\tunsigned e = u.i >> 52 & 0x7ff;\n\n\t/* x < 1 domain error is handled in the called functions */\n\n\tif (e < 0x3ff + 1)\n\t\t/* |x| < 2, up to 2ulp error in [1,1.125] */\n\t\treturn log1p(x-1 + sqrt((x-1)*(x-1)+2*(x-1)));\n\tif (e < 0x3ff + 26)\n\t\t/* |x| < 0x1p26 */\n\t\treturn log(2*x - 1/(x+sqrt(x*x-1)));\n\t/* |x| >= 0x1p26 or nan */\n\treturn log(x) + 0.693147180559945309417232121458176568;\n}\n"
  },
  {
    "path": "user.libc/src/math/acoshf.c",
    "content": "#include \"libm.h\"\n\n#if FLT_EVAL_METHOD==2\n#undef sqrtf\n#define sqrtf sqrtl\n#elif FLT_EVAL_METHOD==1\n#undef sqrtf\n#define sqrtf sqrt\n#endif\n\n/* acosh(x) = log(x + sqrt(x*x-1)) */\nfloat acoshf(float x)\n{\n\tunion {float f; uint32_t i;} u = {x};\n\tuint32_t a = u.i & 0x7fffffff;\n\n\tif (a < 0x3f800000+(1<<23))\n\t\t/* |x| < 2, invalid if x < 1 or nan */\n\t\t/* up to 2ulp error in [1,1.125] */\n\t\treturn log1pf(x-1 + sqrtf((x-1)*(x-1)+2*(x-1)));\n\tif (a < 0x3f800000+(12<<23))\n\t\t/* |x| < 0x1p12 */\n\t\treturn logf(2*x - 1/(x+sqrtf(x*x-1)));\n\t/* x >= 0x1p12 */\n\treturn logf(x) + 0.693147180559945309417232121458176568f;\n}\n"
  },
  {
    "path": "user.libc/src/math/acoshl.c",
    "content": "#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double acoshl(long double x)\n{\n\treturn acosh(x);\n}\n#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384\n/* acosh(x) = log(x + sqrt(x*x-1)) */\nlong double acoshl(long double x)\n{\n\tunion ldshape u = {x};\n\tint e = u.i.se & 0x7fff;\n\n\tif (e < 0x3fff + 1)\n\t\t/* |x| < 2, invalid if x < 1 or nan */\n\t\treturn log1pl(x-1 + sqrtl((x-1)*(x-1)+2*(x-1)));\n\tif (e < 0x3fff + 32)\n\t\t/* |x| < 0x1p32 */\n\t\treturn logl(2*x - 1/(x+sqrtl(x*x-1)));\n\treturn logl(x) + 0.693147180559945309417232121458176568L;\n}\n#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384\n// TODO: broken implementation to make things compile\nlong double acoshl(long double x)\n{\n\treturn acosh(x);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/acosl.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/e_acosl.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunSoft, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/*\n * See comments in acos.c.\n * Converted to long double by David Schultz <das@FreeBSD.ORG>.\n */\n\n#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double acosl(long double x)\n{\n\treturn acos(x);\n}\n#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\n#include \"__invtrigl.h\"\n#if LDBL_MANT_DIG == 64\n#define CLEARBOTTOM(u) (u.i.m &= -1ULL << 32)\n#elif LDBL_MANT_DIG == 113\n#define CLEARBOTTOM(u) (u.i.lo = 0)\n#endif\n\nlong double acosl(long double x)\n{\n\tunion ldshape u = {x};\n\tlong double z, s, c, f;\n\tuint16_t e = u.i.se & 0x7fff;\n\n\t/* |x| >= 1 or nan */\n\tif (e >= 0x3fff) {\n\t\tif (x == 1)\n\t\t\treturn 0;\n\t\tif (x == -1)\n\t\t\treturn 2*pio2_hi + 0x1p-120f;\n\t\treturn 0/(x-x);\n\t}\n\t/* |x| < 0.5 */\n\tif (e < 0x3fff - 1) {\n\t\tif (e < 0x3fff - LDBL_MANT_DIG - 1)\n\t\t\treturn pio2_hi + 0x1p-120f;\n\t\treturn pio2_hi - (__invtrigl_R(x*x)*x - pio2_lo + x);\n\t}\n\t/* x < -0.5 */\n\tif (u.i.se >> 15) {\n\t\tz = (1 + x)*0.5;\n\t\ts = sqrtl(z);\n\t\treturn 2*(pio2_hi - (__invtrigl_R(z)*s - pio2_lo + s));\n\t}\n\t/* x > 0.5 */\n\tz = (1 - x)*0.5;\n\ts = sqrtl(z);\n\tu.f = s;\n\tCLEARBOTTOM(u);\n\tf = u.f;\n\tc = (z - f*f)/(s + f);\n\treturn 2*(__invtrigl_R(z)*s + c + f);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/arm/fabs.c",
    "content": "#include <math.h>\n\n#if __ARM_PCS_VFP && __ARM_FP&8\n\ndouble fabs(double x)\n{\n\t__asm__ (\"vabs.f64 %P0, %P1\" : \"=w\"(x) : \"w\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../fabs.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/arm/fabsf.c",
    "content": "#include <math.h>\n\n#if __ARM_PCS_VFP && !BROKEN_VFP_ASM\n\nfloat fabsf(float x)\n{\n\t__asm__ (\"vabs.f32 %0, %1\" : \"=t\"(x) : \"t\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../fabsf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/arm/fma.c",
    "content": "#include <math.h>\n\n#if __ARM_FEATURE_FMA && __ARM_FP&8 && !__SOFTFP__\n\ndouble fma(double x, double y, double z)\n{\n\t__asm__ (\"vfma.f64 %P0, %P1, %P2\" : \"+w\"(z) : \"w\"(x), \"w\"(y));\n\treturn z;\n}\n\n#else\n\n#include \"../fma.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/arm/fmaf.c",
    "content": "#include <math.h>\n\n#if __ARM_FEATURE_FMA && __ARM_FP&4 && !__SOFTFP__ && !BROKEN_VFP_ASM\n\nfloat fmaf(float x, float y, float z)\n{\n\t__asm__ (\"vfma.f32 %0, %1, %2\" : \"+t\"(z) : \"t\"(x), \"t\"(y));\n\treturn z;\n}\n\n#else\n\n#include \"../fmaf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/arm/sqrt.c",
    "content": "#include <math.h>\n\n#if (__ARM_PCS_VFP || (__VFP_FP__ && !__SOFTFP__)) && (__ARM_FP&8)\n\ndouble sqrt(double x)\n{\n\t__asm__ (\"vsqrt.f64 %P0, %P1\" : \"=w\"(x) : \"w\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../sqrt.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/arm/sqrtf.c",
    "content": "#include <math.h>\n\n#if (__ARM_PCS_VFP || (__VFP_FP__ && !__SOFTFP__)) && !BROKEN_VFP_ASM\n\nfloat sqrtf(float x)\n{\n\t__asm__ (\"vsqrt.f32 %0, %1\" : \"=t\"(x) : \"t\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../sqrtf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/asin.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/e_asin.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunSoft, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/* asin(x)\n * Method :\n *      Since  asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ...\n *      we approximate asin(x) on [0,0.5] by\n *              asin(x) = x + x*x^2*R(x^2)\n *      where\n *              R(x^2) is a rational approximation of (asin(x)-x)/x^3\n *      and its remez error is bounded by\n *              |(asin(x)-x)/x^3 - R(x^2)| < 2^(-58.75)\n *\n *      For x in [0.5,1]\n *              asin(x) = pi/2-2*asin(sqrt((1-x)/2))\n *      Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2;\n *      then for x>0.98\n *              asin(x) = pi/2 - 2*(s+s*z*R(z))\n *                      = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo)\n *      For x<=0.98, let pio4_hi = pio2_hi/2, then\n *              f = hi part of s;\n *              c = sqrt(z) - f = (z-f*f)/(s+f)         ...f+c=sqrt(z)\n *      and\n *              asin(x) = pi/2 - 2*(s+s*z*R(z))\n *                      = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo)\n *                      = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c))\n *\n * Special cases:\n *      if x is NaN, return x itself;\n *      if |x|>1, return NaN with invalid signal.\n *\n */\n\n#include \"libm.h\"\n\nstatic const double\npio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */\npio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */\n/* coefficients for R(x^2) */\npS0 =  1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */\npS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */\npS2 =  2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */\npS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */\npS4 =  7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */\npS5 =  3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */\nqS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */\nqS2 =  2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */\nqS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */\nqS4 =  7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */\n\nstatic double R(double z)\n{\n\tdouble_t p, q;\n\tp = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));\n\tq = 1.0+z*(qS1+z*(qS2+z*(qS3+z*qS4)));\n\treturn p/q;\n}\n\ndouble asin(double x)\n{\n\tdouble z,r,s;\n\tuint32_t hx,ix;\n\n\tGET_HIGH_WORD(hx, x);\n\tix = hx & 0x7fffffff;\n\t/* |x| >= 1 or nan */\n\tif (ix >= 0x3ff00000) {\n\t\tuint32_t lx;\n\t\tGET_LOW_WORD(lx, x);\n\t\tif ((ix-0x3ff00000 | lx) == 0)\n\t\t\t/* asin(1) = +-pi/2 with inexact */\n\t\t\treturn x*pio2_hi + 0x1p-120f;\n\t\treturn 0/(x-x);\n\t}\n\t/* |x| < 0.5 */\n\tif (ix < 0x3fe00000) {\n\t\t/* if 0x1p-1022 <= |x| < 0x1p-26, avoid raising underflow */\n\t\tif (ix < 0x3e500000 && ix >= 0x00100000)\n\t\t\treturn x;\n\t\treturn x + x*R(x*x);\n\t}\n\t/* 1 > |x| >= 0.5 */\n\tz = (1 - fabs(x))*0.5;\n\ts = sqrt(z);\n\tr = R(z);\n\tif (ix >= 0x3fef3333) {  /* if |x| > 0.975 */\n\t\tx = pio2_hi-(2*(s+s*r)-pio2_lo);\n\t} else {\n\t\tdouble f,c;\n\t\t/* f+c = sqrt(z) */\n\t\tf = s;\n\t\tSET_LOW_WORD(f,0);\n\t\tc = (z-f*f)/(s+f);\n\t\tx = 0.5*pio2_hi - (2*s*r - (pio2_lo-2*c) - (0.5*pio2_hi-2*f));\n\t}\n\tif (hx >> 31)\n\t\treturn -x;\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/asinf.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/e_asinf.c */\n/*\n * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.\n */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n#include \"libm.h\"\n\nstatic const double\npio2 = 1.570796326794896558e+00;\n\nstatic const float\n/* coefficients for R(x^2) */\npS0 =  1.6666586697e-01,\npS1 = -4.2743422091e-02,\npS2 = -8.6563630030e-03,\nqS1 = -7.0662963390e-01;\n\nstatic float R(float z)\n{\n\tfloat_t p, q;\n\tp = z*(pS0+z*(pS1+z*pS2));\n\tq = 1.0f+z*qS1;\n\treturn p/q;\n}\n\nfloat asinf(float x)\n{\n\tdouble s;\n\tfloat z;\n\tuint32_t hx,ix;\n\n\tGET_FLOAT_WORD(hx, x);\n\tix = hx & 0x7fffffff;\n\tif (ix >= 0x3f800000) {  /* |x| >= 1 */\n\t\tif (ix == 0x3f800000)  /* |x| == 1 */\n\t\t\treturn x*pio2 + 0x1p-120f;  /* asin(+-1) = +-pi/2 with inexact */\n\t\treturn 0/(x-x);  /* asin(|x|>1) is NaN */\n\t}\n\tif (ix < 0x3f000000) {  /* |x| < 0.5 */\n\t\t/* if 0x1p-126 <= |x| < 0x1p-12, avoid raising underflow */\n\t\tif (ix < 0x39800000 && ix >= 0x00800000)\n\t\t\treturn x;\n\t\treturn x + x*R(x*x);\n\t}\n\t/* 1 > |x| >= 0.5 */\n\tz = (1 - fabsf(x))*0.5f;\n\ts = sqrt(z);\n\tx = pio2 - 2*(s+s*R(z));\n\tif (hx >> 31)\n\t\treturn -x;\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/asinh.c",
    "content": "#include \"libm.h\"\n\n/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */\ndouble asinh(double x)\n{\n\tunion {double f; uint64_t i;} u = {.f = x};\n\tunsigned e = u.i >> 52 & 0x7ff;\n\tunsigned s = u.i >> 63;\n\n\t/* |x| */\n\tu.i &= (uint64_t)-1/2;\n\tx = u.f;\n\n\tif (e >= 0x3ff + 26) {\n\t\t/* |x| >= 0x1p26 or inf or nan */\n\t\tx = log(x) + 0.693147180559945309417232121458176568;\n\t} else if (e >= 0x3ff + 1) {\n\t\t/* |x| >= 2 */\n\t\tx = log(2*x + 1/(sqrt(x*x+1)+x));\n\t} else if (e >= 0x3ff - 26) {\n\t\t/* |x| >= 0x1p-26, up to 1.6ulp error in [0.125,0.5] */\n\t\tx = log1p(x + x*x/(sqrt(x*x+1)+1));\n\t} else {\n\t\t/* |x| < 0x1p-26, raise inexact if x != 0 */\n\t\tFORCE_EVAL(x + 0x1p120f);\n\t}\n\treturn s ? -x : x;\n}\n"
  },
  {
    "path": "user.libc/src/math/asinhf.c",
    "content": "#include \"libm.h\"\n\n/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */\nfloat asinhf(float x)\n{\n\tunion {float f; uint32_t i;} u = {.f = x};\n\tuint32_t i = u.i & 0x7fffffff;\n\tunsigned s = u.i >> 31;\n\n\t/* |x| */\n\tu.i = i;\n\tx = u.f;\n\n\tif (i >= 0x3f800000 + (12<<23)) {\n\t\t/* |x| >= 0x1p12 or inf or nan */\n\t\tx = logf(x) + 0.693147180559945309417232121458176568f;\n\t} else if (i >= 0x3f800000 + (1<<23)) {\n\t\t/* |x| >= 2 */\n\t\tx = logf(2*x + 1/(sqrtf(x*x+1)+x));\n\t} else if (i >= 0x3f800000 - (12<<23)) {\n\t\t/* |x| >= 0x1p-12, up to 1.6ulp error in [0.125,0.5] */\n\t\tx = log1pf(x + x*x/(sqrtf(x*x+1)+1));\n\t} else {\n\t\t/* |x| < 0x1p-12, raise inexact if x!=0 */\n\t\tFORCE_EVAL(x + 0x1p120f);\n\t}\n\treturn s ? -x : x;\n}\n"
  },
  {
    "path": "user.libc/src/math/asinhl.c",
    "content": "#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double asinhl(long double x)\n{\n\treturn asinh(x);\n}\n#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384\n/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */\nlong double asinhl(long double x)\n{\n\tunion ldshape u = {x};\n\tunsigned e = u.i.se & 0x7fff;\n\tunsigned s = u.i.se >> 15;\n\n\t/* |x| */\n\tu.i.se = e;\n\tx = u.f;\n\n\tif (e >= 0x3fff + 32) {\n\t\t/* |x| >= 0x1p32 or inf or nan */\n\t\tx = logl(x) + 0.693147180559945309417232121458176568L;\n\t} else if (e >= 0x3fff + 1) {\n\t\t/* |x| >= 2 */\n\t\tx = logl(2*x + 1/(sqrtl(x*x+1)+x));\n\t} else if (e >= 0x3fff - 32) {\n\t\t/* |x| >= 0x1p-32 */\n\t\tx = log1pl(x + x*x/(sqrtl(x*x+1)+1));\n\t} else {\n\t\t/* |x| < 0x1p-32, raise inexact if x!=0 */\n\t\tFORCE_EVAL(x + 0x1p120f);\n\t}\n\treturn s ? -x : x;\n}\n#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384\n// TODO: broken implementation to make things compile\nlong double asinhl(long double x)\n{\n\treturn asinh(x);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/asinl.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/e_asinl.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunSoft, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/*\n * See comments in asin.c.\n * Converted to long double by David Schultz <das@FreeBSD.ORG>.\n */\n\n#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double asinl(long double x)\n{\n\treturn asin(x);\n}\n#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\n#include \"__invtrigl.h\"\n#if LDBL_MANT_DIG == 64\n#define CLOSETO1(u) (u.i.m>>56 >= 0xf7)\n#define CLEARBOTTOM(u) (u.i.m &= -1ULL << 32)\n#elif LDBL_MANT_DIG == 113\n#define CLOSETO1(u) (u.i.top >= 0xee00)\n#define CLEARBOTTOM(u) (u.i.lo = 0)\n#endif\n\nlong double asinl(long double x)\n{\n\tunion ldshape u = {x};\n\tlong double z, r, s;\n\tuint16_t e = u.i.se & 0x7fff;\n\tint sign = u.i.se >> 15;\n\n\tif (e >= 0x3fff) {   /* |x| >= 1 or nan */\n\t\t/* asin(+-1)=+-pi/2 with inexact */\n\t\tif (x == 1 || x == -1)\n\t\t\treturn x*pio2_hi + 0x1p-120f;\n\t\treturn 0/(x-x);\n\t}\n\tif (e < 0x3fff - 1) {  /* |x| < 0.5 */\n\t\tif (e < 0x3fff - (LDBL_MANT_DIG+1)/2) {\n\t\t\t/* return x with inexact if x!=0 */\n\t\t\tFORCE_EVAL(x + 0x1p120f);\n\t\t\treturn x;\n\t\t}\n\t\treturn x + x*__invtrigl_R(x*x);\n\t}\n\t/* 1 > |x| >= 0.5 */\n\tz = (1.0 - fabsl(x))*0.5;\n\ts = sqrtl(z);\n\tr = __invtrigl_R(z);\n\tif (CLOSETO1(u)) {\n\t\tx = pio2_hi - (2*(s+s*r)-pio2_lo);\n\t} else {\n\t\tlong double f, c;\n\t\tu.f = s;\n\t\tCLEARBOTTOM(u);\n\t\tf = u.f;\n\t\tc = (z - f*f)/(s + f);\n\t\tx = 0.5*pio2_hi-(2*s*r - (pio2_lo-2*c) - (0.5*pio2_hi-2*f));\n\t}\n\treturn sign ? -x : x;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/atan.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_atan.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/* atan(x)\n * Method\n *   1. Reduce x to positive by atan(x) = -atan(-x).\n *   2. According to the integer k=4t+0.25 chopped, t=x, the argument\n *      is further reduced to one of the following intervals and the\n *      arctangent of t is evaluated by the corresponding formula:\n *\n *      [0,7/16]      atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...)\n *      [7/16,11/16]  atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) )\n *      [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) )\n *      [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) )\n *      [39/16,INF]   atan(x) = atan(INF) + atan( -1/t )\n *\n * Constants:\n * The hexadecimal values are the intended ones for the following\n * constants. The decimal values may be used, provided that the\n * compiler will convert from decimal to binary accurately enough\n * to produce the hexadecimal values shown.\n */\n\n\n#include \"libm.h\"\n\nstatic const double atanhi[] = {\n  4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */\n  7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */\n  9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */\n  1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */\n};\n\nstatic const double atanlo[] = {\n  2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */\n  3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */\n  1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */\n  6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */\n};\n\nstatic const double aT[] = {\n  3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */\n -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */\n  1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */\n -1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */\n  9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */\n -7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */\n  6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */\n -5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */\n  4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */\n -3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */\n  1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */\n};\n\ndouble atan(double x)\n{\n\tdouble_t w,s1,s2,z;\n\tuint32_t ix,sign;\n\tint id;\n\n\tGET_HIGH_WORD(ix, x);\n\tsign = ix >> 31;\n\tix &= 0x7fffffff;\n\tif (ix >= 0x44100000) {   /* if |x| >= 2^66 */\n\t\tif (isnan(x))\n\t\t\treturn x;\n\t\tz = atanhi[3] + 0x1p-120f;\n\t\treturn sign ? -z : z;\n\t}\n\tif (ix < 0x3fdc0000) {    /* |x| < 0.4375 */\n\t\tif (ix < 0x3e400000) {  /* |x| < 2^-27 */\n\t\t\tif (ix < 0x00100000)\n\t\t\t\t/* raise underflow for subnormal x */\n\t\t\t\tFORCE_EVAL((float)x);\n\t\t\treturn x;\n\t\t}\n\t\tid = -1;\n\t} else {\n\t\tx = fabs(x);\n\t\tif (ix < 0x3ff30000) {  /* |x| < 1.1875 */\n\t\t\tif (ix < 0x3fe60000) {  /*  7/16 <= |x| < 11/16 */\n\t\t\t\tid = 0;\n\t\t\t\tx = (2.0*x-1.0)/(2.0+x);\n\t\t\t} else {                /* 11/16 <= |x| < 19/16 */\n\t\t\t\tid = 1;\n\t\t\t\tx = (x-1.0)/(x+1.0);\n\t\t\t}\n\t\t} else {\n\t\t\tif (ix < 0x40038000) {  /* |x| < 2.4375 */\n\t\t\t\tid = 2;\n\t\t\t\tx = (x-1.5)/(1.0+1.5*x);\n\t\t\t} else {                /* 2.4375 <= |x| < 2^66 */\n\t\t\t\tid = 3;\n\t\t\t\tx = -1.0/x;\n\t\t\t}\n\t\t}\n\t}\n\t/* end of argument reduction */\n\tz = x*x;\n\tw = z*z;\n\t/* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */\n\ts1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10])))));\n\ts2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9]))));\n\tif (id < 0)\n\t\treturn x - x*(s1+s2);\n\tz = atanhi[id] - (x*(s1+s2) - atanlo[id] - x);\n\treturn sign ? -z : z;\n}\n"
  },
  {
    "path": "user.libc/src/math/atan2.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/e_atan2.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunSoft, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n *\n */\n/* atan2(y,x)\n * Method :\n *      1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).\n *      2. Reduce x to positive by (if x and y are unexceptional):\n *              ARG (x+iy) = arctan(y/x)           ... if x > 0,\n *              ARG (x+iy) = pi - arctan[y/(-x)]   ... if x < 0,\n *\n * Special cases:\n *\n *      ATAN2((anything), NaN ) is NaN;\n *      ATAN2(NAN , (anything) ) is NaN;\n *      ATAN2(+-0, +(anything but NaN)) is +-0  ;\n *      ATAN2(+-0, -(anything but NaN)) is +-pi ;\n *      ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2;\n *      ATAN2(+-(anything but INF and NaN), +INF) is +-0 ;\n *      ATAN2(+-(anything but INF and NaN), -INF) is +-pi;\n *      ATAN2(+-INF,+INF ) is +-pi/4 ;\n *      ATAN2(+-INF,-INF ) is +-3pi/4;\n *      ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2;\n *\n * Constants:\n * The hexadecimal values are the intended ones for the following\n * constants. The decimal values may be used, provided that the\n * compiler will convert from decimal to binary accurately enough\n * to produce the hexadecimal values shown.\n */\n\n#include \"libm.h\"\n\nstatic const double\npi     = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */\npi_lo  = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */\n\ndouble atan2(double y, double x)\n{\n\tdouble z;\n\tuint32_t m,lx,ly,ix,iy;\n\n\tif (isnan(x) || isnan(y))\n\t\treturn x+y;\n\tEXTRACT_WORDS(ix, lx, x);\n\tEXTRACT_WORDS(iy, ly, y);\n\tif ((ix-0x3ff00000 | lx) == 0)  /* x = 1.0 */\n\t\treturn atan(y);\n\tm = ((iy>>31)&1) | ((ix>>30)&2);  /* 2*sign(x)+sign(y) */\n\tix = ix & 0x7fffffff;\n\tiy = iy & 0x7fffffff;\n\n\t/* when y = 0 */\n\tif ((iy|ly) == 0) {\n\t\tswitch(m) {\n\t\tcase 0:\n\t\tcase 1: return y;   /* atan(+-0,+anything)=+-0 */\n\t\tcase 2: return  pi; /* atan(+0,-anything) = pi */\n\t\tcase 3: return -pi; /* atan(-0,-anything) =-pi */\n\t\t}\n\t}\n\t/* when x = 0 */\n\tif ((ix|lx) == 0)\n\t\treturn m&1 ? -pi/2 : pi/2;\n\t/* when x is INF */\n\tif (ix == 0x7ff00000) {\n\t\tif (iy == 0x7ff00000) {\n\t\t\tswitch(m) {\n\t\t\tcase 0: return  pi/4;   /* atan(+INF,+INF) */\n\t\t\tcase 1: return -pi/4;   /* atan(-INF,+INF) */\n\t\t\tcase 2: return  3*pi/4; /* atan(+INF,-INF) */\n\t\t\tcase 3: return -3*pi/4; /* atan(-INF,-INF) */\n\t\t\t}\n\t\t} else {\n\t\t\tswitch(m) {\n\t\t\tcase 0: return  0.0; /* atan(+...,+INF) */\n\t\t\tcase 1: return -0.0; /* atan(-...,+INF) */\n\t\t\tcase 2: return  pi;  /* atan(+...,-INF) */\n\t\t\tcase 3: return -pi;  /* atan(-...,-INF) */\n\t\t\t}\n\t\t}\n\t}\n\t/* |y/x| > 0x1p64 */\n\tif (ix+(64<<20) < iy || iy == 0x7ff00000)\n\t\treturn m&1 ? -pi/2 : pi/2;\n\n\t/* z = atan(|y/x|) without spurious underflow */\n\tif ((m&2) && iy+(64<<20) < ix)  /* |y/x| < 0x1p-64, x<0 */\n\t\tz = 0;\n\telse\n\t\tz = atan(fabs(y/x));\n\tswitch (m) {\n\tcase 0: return z;              /* atan(+,+) */\n\tcase 1: return -z;             /* atan(-,+) */\n\tcase 2: return pi - (z-pi_lo); /* atan(+,-) */\n\tdefault: /* case 3 */\n\t\treturn (z-pi_lo) - pi; /* atan(-,-) */\n\t}\n}\n"
  },
  {
    "path": "user.libc/src/math/atan2f.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/e_atan2f.c */\n/*\n * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.\n */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n\n#include \"libm.h\"\n\nstatic const float\npi     = 3.1415927410e+00, /* 0x40490fdb */\npi_lo  = -8.7422776573e-08; /* 0xb3bbbd2e */\n\nfloat atan2f(float y, float x)\n{\n\tfloat z;\n\tuint32_t m,ix,iy;\n\n\tif (isnan(x) || isnan(y))\n\t\treturn x+y;\n\tGET_FLOAT_WORD(ix, x);\n\tGET_FLOAT_WORD(iy, y);\n\tif (ix == 0x3f800000)  /* x=1.0 */\n\t\treturn atanf(y);\n\tm = ((iy>>31)&1) | ((ix>>30)&2);  /* 2*sign(x)+sign(y) */\n\tix &= 0x7fffffff;\n\tiy &= 0x7fffffff;\n\n\t/* when y = 0 */\n\tif (iy == 0) {\n\t\tswitch (m) {\n\t\tcase 0:\n\t\tcase 1: return y;   /* atan(+-0,+anything)=+-0 */\n\t\tcase 2: return  pi; /* atan(+0,-anything) = pi */\n\t\tcase 3: return -pi; /* atan(-0,-anything) =-pi */\n\t\t}\n\t}\n\t/* when x = 0 */\n\tif (ix == 0)\n\t\treturn m&1 ? -pi/2 : pi/2;\n\t/* when x is INF */\n\tif (ix == 0x7f800000) {\n\t\tif (iy == 0x7f800000) {\n\t\t\tswitch (m) {\n\t\t\tcase 0: return  pi/4; /* atan(+INF,+INF) */\n\t\t\tcase 1: return -pi/4; /* atan(-INF,+INF) */\n\t\t\tcase 2: return 3*pi/4;  /*atan(+INF,-INF)*/\n\t\t\tcase 3: return -3*pi/4; /*atan(-INF,-INF)*/\n\t\t\t}\n\t\t} else {\n\t\t\tswitch (m) {\n\t\t\tcase 0: return  0.0f;    /* atan(+...,+INF) */\n\t\t\tcase 1: return -0.0f;    /* atan(-...,+INF) */\n\t\t\tcase 2: return  pi; /* atan(+...,-INF) */\n\t\t\tcase 3: return -pi; /* atan(-...,-INF) */\n\t\t\t}\n\t\t}\n\t}\n\t/* |y/x| > 0x1p26 */\n\tif (ix+(26<<23) < iy || iy == 0x7f800000)\n\t\treturn m&1 ? -pi/2 : pi/2;\n\n\t/* z = atan(|y/x|) with correct underflow */\n\tif ((m&2) && iy+(26<<23) < ix)  /*|y/x| < 0x1p-26, x < 0 */\n\t\tz = 0.0;\n\telse\n\t\tz = atanf(fabsf(y/x));\n\tswitch (m) {\n\tcase 0: return z;              /* atan(+,+) */\n\tcase 1: return -z;             /* atan(-,+) */\n\tcase 2: return pi - (z-pi_lo); /* atan(+,-) */\n\tdefault: /* case 3 */\n\t\treturn (z-pi_lo) - pi; /* atan(-,-) */\n\t}\n}\n"
  },
  {
    "path": "user.libc/src/math/atan2l.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/e_atan2l.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunSoft, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n *\n */\n/*\n * See comments in atan2.c.\n * Converted to long double by David Schultz <das@FreeBSD.ORG>.\n */\n\n#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double atan2l(long double y, long double x)\n{\n\treturn atan2(y, x);\n}\n#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\n#include \"__invtrigl.h\"\n\nlong double atan2l(long double y, long double x)\n{\n\tunion ldshape ux, uy;\n\tlong double z;\n\tint m, ex, ey;\n\n\tif (isnan(x) || isnan(y))\n\t\treturn x+y;\n\tif (x == 1)\n\t\treturn atanl(y);\n\tux.f = x;\n\tuy.f = y;\n\tex = ux.i.se & 0x7fff;\n\tey = uy.i.se & 0x7fff;\n\tm = 2*(ux.i.se>>15) | uy.i.se>>15;\n\tif (y == 0) {\n\t\tswitch(m) {\n\t\tcase 0:\n\t\tcase 1: return y;           /* atan(+-0,+anything)=+-0 */\n\t\tcase 2: return  2*pio2_hi;  /* atan(+0,-anything) = pi */\n\t\tcase 3: return -2*pio2_hi;  /* atan(-0,-anything) =-pi */\n\t\t}\n\t}\n\tif (x == 0)\n\t\treturn m&1 ? -pio2_hi : pio2_hi;\n\tif (ex == 0x7fff) {\n\t\tif (ey == 0x7fff) {\n\t\t\tswitch(m) {\n\t\t\tcase 0: return  pio2_hi/2;   /* atan(+INF,+INF) */\n\t\t\tcase 1: return -pio2_hi/2;   /* atan(-INF,+INF) */\n\t\t\tcase 2: return  1.5*pio2_hi; /* atan(+INF,-INF) */\n\t\t\tcase 3: return -1.5*pio2_hi; /* atan(-INF,-INF) */\n\t\t\t}\n\t\t} else {\n\t\t\tswitch(m) {\n\t\t\tcase 0: return  0.0;        /* atan(+...,+INF) */\n\t\t\tcase 1: return -0.0;        /* atan(-...,+INF) */\n\t\t\tcase 2: return  2*pio2_hi;  /* atan(+...,-INF) */\n\t\t\tcase 3: return -2*pio2_hi;  /* atan(-...,-INF) */\n\t\t\t}\n\t\t}\n\t}\n\tif (ex+120 < ey || ey == 0x7fff)\n\t\treturn m&1 ? -pio2_hi : pio2_hi;\n\t/* z = atan(|y/x|) without spurious underflow */\n\tif ((m&2) && ey+120 < ex)  /* |y/x| < 0x1p-120, x<0 */\n\t\tz = 0.0;\n\telse\n\t\tz = atanl(fabsl(y/x));\n\tswitch (m) {\n\tcase 0: return z;               /* atan(+,+) */\n\tcase 1: return -z;              /* atan(-,+) */\n\tcase 2: return 2*pio2_hi-(z-2*pio2_lo); /* atan(+,-) */\n\tdefault: /* case 3 */\n\t\treturn (z-2*pio2_lo)-2*pio2_hi; /* atan(-,-) */\n\t}\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/atanf.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_atanf.c */\n/*\n * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.\n */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n\n\n#include \"libm.h\"\n\nstatic const float atanhi[] = {\n  4.6364760399e-01, /* atan(0.5)hi 0x3eed6338 */\n  7.8539812565e-01, /* atan(1.0)hi 0x3f490fda */\n  9.8279368877e-01, /* atan(1.5)hi 0x3f7b985e */\n  1.5707962513e+00, /* atan(inf)hi 0x3fc90fda */\n};\n\nstatic const float atanlo[] = {\n  5.0121582440e-09, /* atan(0.5)lo 0x31ac3769 */\n  3.7748947079e-08, /* atan(1.0)lo 0x33222168 */\n  3.4473217170e-08, /* atan(1.5)lo 0x33140fb4 */\n  7.5497894159e-08, /* atan(inf)lo 0x33a22168 */\n};\n\nstatic const float aT[] = {\n  3.3333328366e-01,\n -1.9999158382e-01,\n  1.4253635705e-01,\n -1.0648017377e-01,\n  6.1687607318e-02,\n};\n\nfloat atanf(float x)\n{\n\tfloat_t w,s1,s2,z;\n\tuint32_t ix,sign;\n\tint id;\n\n\tGET_FLOAT_WORD(ix, x);\n\tsign = ix>>31;\n\tix &= 0x7fffffff;\n\tif (ix >= 0x4c800000) {  /* if |x| >= 2**26 */\n\t\tif (isnan(x))\n\t\t\treturn x;\n\t\tz = atanhi[3] + 0x1p-120f;\n\t\treturn sign ? -z : z;\n\t}\n\tif (ix < 0x3ee00000) {   /* |x| < 0.4375 */\n\t\tif (ix < 0x39800000) {  /* |x| < 2**-12 */\n\t\t\tif (ix < 0x00800000)\n\t\t\t\t/* raise underflow for subnormal x */\n\t\t\t\tFORCE_EVAL(x*x);\n\t\t\treturn x;\n\t\t}\n\t\tid = -1;\n\t} else {\n\t\tx = fabsf(x);\n\t\tif (ix < 0x3f980000) {  /* |x| < 1.1875 */\n\t\t\tif (ix < 0x3f300000) {  /*  7/16 <= |x| < 11/16 */\n\t\t\t\tid = 0;\n\t\t\t\tx = (2.0f*x - 1.0f)/(2.0f + x);\n\t\t\t} else {                /* 11/16 <= |x| < 19/16 */\n\t\t\t\tid = 1;\n\t\t\t\tx = (x - 1.0f)/(x + 1.0f);\n\t\t\t}\n\t\t} else {\n\t\t\tif (ix < 0x401c0000) {  /* |x| < 2.4375 */\n\t\t\t\tid = 2;\n\t\t\t\tx = (x - 1.5f)/(1.0f + 1.5f*x);\n\t\t\t} else {                /* 2.4375 <= |x| < 2**26 */\n\t\t\t\tid = 3;\n\t\t\t\tx = -1.0f/x;\n\t\t\t}\n\t\t}\n\t}\n\t/* end of argument reduction */\n\tz = x*x;\n\tw = z*z;\n\t/* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */\n\ts1 = z*(aT[0]+w*(aT[2]+w*aT[4]));\n\ts2 = w*(aT[1]+w*aT[3]);\n\tif (id < 0)\n\t\treturn x - x*(s1+s2);\n\tz = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);\n\treturn sign ? -z : z;\n}\n"
  },
  {
    "path": "user.libc/src/math/atanh.c",
    "content": "#include \"libm.h\"\n\n/* atanh(x) = log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2 ~= x + x^3/3 + o(x^5) */\ndouble atanh(double x)\n{\n\tunion {double f; uint64_t i;} u = {.f = x};\n\tunsigned e = u.i >> 52 & 0x7ff;\n\tunsigned s = u.i >> 63;\n\tdouble_t y;\n\n\t/* |x| */\n\tu.i &= (uint64_t)-1/2;\n\ty = u.f;\n\n\tif (e < 0x3ff - 1) {\n\t\tif (e < 0x3ff - 32) {\n\t\t\t/* handle underflow */\n\t\t\tif (e == 0)\n\t\t\t\tFORCE_EVAL((float)y);\n\t\t} else {\n\t\t\t/* |x| < 0.5, up to 1.7ulp error */\n\t\t\ty = 0.5*log1p(2*y + 2*y*y/(1-y));\n\t\t}\n\t} else {\n\t\t/* avoid overflow */\n\t\ty = 0.5*log1p(2*(y/(1-y)));\n\t}\n\treturn s ? -y : y;\n}\n"
  },
  {
    "path": "user.libc/src/math/atanhf.c",
    "content": "#include \"libm.h\"\n\n/* atanh(x) = log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2 ~= x + x^3/3 + o(x^5) */\nfloat atanhf(float x)\n{\n\tunion {float f; uint32_t i;} u = {.f = x};\n\tunsigned s = u.i >> 31;\n\tfloat_t y;\n\n\t/* |x| */\n\tu.i &= 0x7fffffff;\n\ty = u.f;\n\n\tif (u.i < 0x3f800000 - (1<<23)) {\n\t\tif (u.i < 0x3f800000 - (32<<23)) {\n\t\t\t/* handle underflow */\n\t\t\tif (u.i < (1<<23))\n\t\t\t\tFORCE_EVAL((float)(y*y));\n\t\t} else {\n\t\t\t/* |x| < 0.5, up to 1.7ulp error */\n\t\t\ty = 0.5f*log1pf(2*y + 2*y*y/(1-y));\n\t\t}\n\t} else {\n\t\t/* avoid overflow */\n\t\ty = 0.5f*log1pf(2*(y/(1-y)));\n\t}\n\treturn s ? -y : y;\n}\n"
  },
  {
    "path": "user.libc/src/math/atanhl.c",
    "content": "#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double atanhl(long double x)\n{\n\treturn atanh(x);\n}\n#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\n/* atanh(x) = log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2 ~= x + x^3/3 + o(x^5) */\nlong double atanhl(long double x)\n{\n\tunion ldshape u = {x};\n\tunsigned e = u.i.se & 0x7fff;\n\tunsigned s = u.i.se >> 15;\n\n\t/* |x| */\n\tu.i.se = e;\n\tx = u.f;\n\n\tif (e < 0x3ff - 1) {\n\t\tif (e < 0x3ff - LDBL_MANT_DIG/2) {\n\t\t\t/* handle underflow */\n\t\t\tif (e == 0)\n\t\t\t\tFORCE_EVAL((float)x);\n\t\t} else {\n\t\t\t/* |x| < 0.5, up to 1.7ulp error */\n\t\t\tx = 0.5*log1pl(2*x + 2*x*x/(1-x));\n\t\t}\n\t} else {\n\t\t/* avoid overflow */\n\t\tx = 0.5*log1pl(2*(x/(1-x)));\n\t}\n\treturn s ? -x : x;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/atanl.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_atanl.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/*\n * See comments in atan.c.\n * Converted to long double by David Schultz <das@FreeBSD.ORG>.\n */\n\n#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double atanl(long double x)\n{\n\treturn atan(x);\n}\n#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\n\n#if LDBL_MANT_DIG == 64\n#define EXPMAN(u) ((u.i.se & 0x7fff)<<8 | (u.i.m>>55 & 0xff))\n\nstatic const long double atanhi[] = {\n\t 4.63647609000806116202e-01L,\n\t 7.85398163397448309628e-01L,\n\t 9.82793723247329067960e-01L,\n\t 1.57079632679489661926e+00L,\n};\n\nstatic const long double atanlo[] = {\n\t 1.18469937025062860669e-20L,\n\t-1.25413940316708300586e-20L,\n\t 2.55232234165405176172e-20L,\n\t-2.50827880633416601173e-20L,\n};\n\nstatic const long double aT[] = {\n\t 3.33333333333333333017e-01L,\n\t-1.99999999999999632011e-01L,\n\t 1.42857142857046531280e-01L,\n\t-1.11111111100562372733e-01L,\n\t 9.09090902935647302252e-02L,\n\t-7.69230552476207730353e-02L,\n\t 6.66661718042406260546e-02L,\n\t-5.88158892835030888692e-02L,\n\t 5.25499891539726639379e-02L,\n\t-4.70119845393155721494e-02L,\n\t 4.03539201366454414072e-02L,\n\t-2.91303858419364158725e-02L,\n\t 1.24822046299269234080e-02L,\n};\n\nstatic long double T_even(long double x)\n{\n\treturn aT[0] + x * (aT[2] + x * (aT[4] + x * (aT[6] +\n\t\tx * (aT[8] + x * (aT[10] + x * aT[12])))));\n}\n\nstatic long double T_odd(long double x)\n{\n\treturn aT[1] + x * (aT[3] + x * (aT[5] + x * (aT[7] +\n\t\tx * (aT[9] + x * aT[11]))));\n}\n#elif LDBL_MANT_DIG == 113\n#define EXPMAN(u) ((u.i.se & 0x7fff)<<8 | u.i.top>>8)\n\nstatic const long double atanhi[] = {\n\t 4.63647609000806116214256231461214397e-01L,\n\t 7.85398163397448309615660845819875699e-01L,\n\t 9.82793723247329067985710611014666038e-01L,\n\t 1.57079632679489661923132169163975140e+00L,\n};\n\nstatic const long double atanlo[] = {\n\t 4.89509642257333492668618435220297706e-36L,\n\t 2.16795253253094525619926100651083806e-35L,\n\t-2.31288434538183565909319952098066272e-35L,\n\t 4.33590506506189051239852201302167613e-35L,\n};\n\nstatic const long double aT[] = {\n\t 3.33333333333333333333333333333333125e-01L,\n\t-1.99999999999999999999999999999180430e-01L,\n\t 1.42857142857142857142857142125269827e-01L,\n\t-1.11111111111111111111110834490810169e-01L,\n\t 9.09090909090909090908522355708623681e-02L,\n\t-7.69230769230769230696553844935357021e-02L,\n\t 6.66666666666666660390096773046256096e-02L,\n\t-5.88235294117646671706582985209643694e-02L,\n\t 5.26315789473666478515847092020327506e-02L,\n\t-4.76190476189855517021024424991436144e-02L,\n\t 4.34782608678695085948531993458097026e-02L,\n\t-3.99999999632663469330634215991142368e-02L,\n\t 3.70370363987423702891250829918659723e-02L,\n\t-3.44827496515048090726669907612335954e-02L,\n\t 3.22579620681420149871973710852268528e-02L,\n\t-3.03020767654269261041647570626778067e-02L,\n\t 2.85641979882534783223403715930946138e-02L,\n\t-2.69824879726738568189929461383741323e-02L,\n\t 2.54194698498808542954187110873675769e-02L,\n\t-2.35083879708189059926183138130183215e-02L,\n\t 2.04832358998165364349957325067131428e-02L,\n\t-1.54489555488544397858507248612362957e-02L,\n\t 8.64492360989278761493037861575248038e-03L,\n\t-2.58521121597609872727919154569765469e-03L,\n};\n\nstatic long double T_even(long double x)\n{\n\treturn (aT[0] + x * (aT[2] + x * (aT[4] + x * (aT[6] + x * (aT[8] +\n\t\tx * (aT[10] + x * (aT[12] + x * (aT[14] + x * (aT[16] +\n\t\tx * (aT[18] + x * (aT[20] + x * aT[22])))))))))));\n}\n\nstatic long double T_odd(long double x)\n{\n\treturn (aT[1] + x * (aT[3] + x * (aT[5] + x * (aT[7] + x * (aT[9] +\n\t\tx * (aT[11] + x * (aT[13] + x * (aT[15] + x * (aT[17] +\n\t\tx * (aT[19] + x * (aT[21] + x * aT[23])))))))))));\n}\n#endif\n\nlong double atanl(long double x)\n{\n\tunion ldshape u = {x};\n\tlong double w, s1, s2, z;\n\tint id;\n\tunsigned e = u.i.se & 0x7fff;\n\tunsigned sign = u.i.se >> 15;\n\tunsigned expman;\n\n\tif (e >= 0x3fff + LDBL_MANT_DIG + 1) { /* if |x| is large, atan(x)~=pi/2 */\n\t\tif (isnan(x))\n\t\t\treturn x;\n\t\treturn sign ? -atanhi[3] : atanhi[3];\n\t}\n\t/* Extract the exponent and the first few bits of the mantissa. */\n\texpman = EXPMAN(u);\n\tif (expman < ((0x3fff - 2) << 8) + 0xc0) {  /* |x| < 0.4375 */\n\t\tif (e < 0x3fff - (LDBL_MANT_DIG+1)/2) {   /* if |x| is small, atanl(x)~=x */\n\t\t\t/* raise underflow if subnormal */\n\t\t\tif (e == 0)\n\t\t\t\tFORCE_EVAL((float)x);\n\t\t\treturn x;\n\t\t}\n\t\tid = -1;\n\t} else {\n\t\tx = fabsl(x);\n\t\tif (expman < (0x3fff << 8) + 0x30) {  /* |x| < 1.1875 */\n\t\t\tif (expman < ((0x3fff - 1) << 8) + 0x60) { /*  7/16 <= |x| < 11/16 */\n\t\t\t\tid = 0;\n\t\t\t\tx = (2.0*x-1.0)/(2.0+x);\n\t\t\t} else {                                 /* 11/16 <= |x| < 19/16 */\n\t\t\t\tid = 1;\n\t\t\t\tx = (x-1.0)/(x+1.0);\n\t\t\t}\n\t\t} else {\n\t\t\tif (expman < ((0x3fff + 1) << 8) + 0x38) { /* |x| < 2.4375 */\n\t\t\t\tid = 2;\n\t\t\t\tx = (x-1.5)/(1.0+1.5*x);\n\t\t\t} else {                                 /* 2.4375 <= |x| */\n\t\t\t\tid = 3;\n\t\t\t\tx = -1.0/x;\n\t\t\t}\n\t\t}\n\t}\n\t/* end of argument reduction */\n\tz = x*x;\n\tw = z*z;\n\t/* break sum aT[i]z**(i+1) into odd and even poly */\n\ts1 = z*T_even(w);\n\ts2 = w*T_odd(w);\n\tif (id < 0)\n\t\treturn x - x*(s1+s2);\n\tz = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);\n\treturn sign ? -z : z;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/cbrt.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_cbrt.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n *\n * Optimized by Bruce D. Evans.\n */\n/* cbrt(x)\n * Return cube root of x\n */\n\n#include <math.h>\n#include <stdint.h>\n\nstatic const uint32_t\nB1 = 715094163, /* B1 = (1023-1023/3-0.03306235651)*2**20 */\nB2 = 696219795; /* B2 = (1023-1023/3-54/3-0.03306235651)*2**20 */\n\n/* |1/cbrt(x) - p(x)| < 2**-23.5 (~[-7.93e-8, 7.929e-8]). */\nstatic const double\nP0 =  1.87595182427177009643,  /* 0x3ffe03e6, 0x0f61e692 */\nP1 = -1.88497979543377169875,  /* 0xbffe28e0, 0x92f02420 */\nP2 =  1.621429720105354466140, /* 0x3ff9f160, 0x4a49d6c2 */\nP3 = -0.758397934778766047437, /* 0xbfe844cb, 0xbee751d9 */\nP4 =  0.145996192886612446982; /* 0x3fc2b000, 0xd4e4edd7 */\n\ndouble cbrt(double x)\n{\n\tunion {double f; uint64_t i;} u = {x};\n\tdouble_t r,s,t,w;\n\tuint32_t hx = u.i>>32 & 0x7fffffff;\n\n\tif (hx >= 0x7ff00000)  /* cbrt(NaN,INF) is itself */\n\t\treturn x+x;\n\n\t/*\n\t * Rough cbrt to 5 bits:\n\t *    cbrt(2**e*(1+m) ~= 2**(e/3)*(1+(e%3+m)/3)\n\t * where e is integral and >= 0, m is real and in [0, 1), and \"/\" and\n\t * \"%\" are integer division and modulus with rounding towards minus\n\t * infinity.  The RHS is always >= the LHS and has a maximum relative\n\t * error of about 1 in 16.  Adding a bias of -0.03306235651 to the\n\t * (e%3+m)/3 term reduces the error to about 1 in 32. With the IEEE\n\t * floating point representation, for finite positive normal values,\n\t * ordinary integer divison of the value in bits magically gives\n\t * almost exactly the RHS of the above provided we first subtract the\n\t * exponent bias (1023 for doubles) and later add it back.  We do the\n\t * subtraction virtually to keep e >= 0 so that ordinary integer\n\t * division rounds towards minus infinity; this is also efficient.\n\t */\n\tif (hx < 0x00100000) { /* zero or subnormal? */\n\t\tu.f = x*0x1p54;\n\t\thx = u.i>>32 & 0x7fffffff;\n\t\tif (hx == 0)\n\t\t\treturn x;  /* cbrt(0) is itself */\n\t\thx = hx/3 + B2;\n\t} else\n\t\thx = hx/3 + B1;\n\tu.i &= 1ULL<<63;\n\tu.i |= (uint64_t)hx << 32;\n\tt = u.f;\n\n\t/*\n\t * New cbrt to 23 bits:\n\t *    cbrt(x) = t*cbrt(x/t**3) ~= t*P(t**3/x)\n\t * where P(r) is a polynomial of degree 4 that approximates 1/cbrt(r)\n\t * to within 2**-23.5 when |r - 1| < 1/10.  The rough approximation\n\t * has produced t such than |t/cbrt(x) - 1| ~< 1/32, and cubing this\n\t * gives us bounds for r = t**3/x.\n\t *\n\t * Try to optimize for parallel evaluation as in __tanf.c.\n\t */\n\tr = (t*t)*(t/x);\n\tt = t*((P0+r*(P1+r*P2))+((r*r)*r)*(P3+r*P4));\n\n\t/*\n\t * Round t away from zero to 23 bits (sloppily except for ensuring that\n\t * the result is larger in magnitude than cbrt(x) but not much more than\n\t * 2 23-bit ulps larger).  With rounding towards zero, the error bound\n\t * would be ~5/6 instead of ~4/6.  With a maximum error of 2 23-bit ulps\n\t * in the rounded t, the infinite-precision error in the Newton\n\t * approximation barely affects third digit in the final error\n\t * 0.667; the error in the rounded t can be up to about 3 23-bit ulps\n\t * before the final error is larger than 0.667 ulps.\n\t */\n\tu.f = t;\n\tu.i = (u.i + 0x80000000) & 0xffffffffc0000000ULL;\n\tt = u.f;\n\n\t/* one step Newton iteration to 53 bits with error < 0.667 ulps */\n\ts = t*t;         /* t*t is exact */\n\tr = x/s;         /* error <= 0.5 ulps; |r| < |t| */\n\tw = t+t;         /* t+t is exact */\n\tr = (r-t)/(w+r); /* r-t is exact; w+r ~= 3*t */\n\tt = t+t*r;       /* error <= 0.5 + 0.5/3 + epsilon */\n\treturn t;\n}\n"
  },
  {
    "path": "user.libc/src/math/cbrtf.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_cbrtf.c */\n/*\n * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.\n * Debugged and optimized by Bruce D. Evans.\n */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/* cbrtf(x)\n * Return cube root of x\n */\n\n#include <math.h>\n#include <stdint.h>\n\nstatic const unsigned\nB1 = 709958130, /* B1 = (127-127.0/3-0.03306235651)*2**23 */\nB2 = 642849266; /* B2 = (127-127.0/3-24/3-0.03306235651)*2**23 */\n\nfloat cbrtf(float x)\n{\n\tdouble_t r,T;\n\tunion {float f; uint32_t i;} u = {x};\n\tuint32_t hx = u.i & 0x7fffffff;\n\n\tif (hx >= 0x7f800000)  /* cbrt(NaN,INF) is itself */\n\t\treturn x + x;\n\n\t/* rough cbrt to 5 bits */\n\tif (hx < 0x00800000) {  /* zero or subnormal? */\n\t\tif (hx == 0)\n\t\t\treturn x;  /* cbrt(+-0) is itself */\n\t\tu.f = x*0x1p24f;\n\t\thx = u.i & 0x7fffffff;\n\t\thx = hx/3 + B2;\n\t} else\n\t\thx = hx/3 + B1;\n\tu.i &= 0x80000000;\n\tu.i |= hx;\n\n\t/*\n\t * First step Newton iteration (solving t*t-x/t == 0) to 16 bits.  In\n\t * double precision so that its terms can be arranged for efficiency\n\t * without causing overflow or underflow.\n\t */\n\tT = u.f;\n\tr = T*T*T;\n\tT = T*((double_t)x+x+r)/(x+r+r);\n\n\t/*\n\t * Second step Newton iteration to 47 bits.  In double precision for\n\t * efficiency and accuracy.\n\t */\n\tr = T*T*T;\n\tT = T*((double_t)x+x+r)/(x+r+r);\n\n\t/* rounding to 24 bits is perfect in round-to-nearest mode */\n\treturn T;\n}\n"
  },
  {
    "path": "user.libc/src/math/cbrtl.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_cbrtl.c */\n/*-\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n * Copyright (c) 2009-2011, Bruce D. Evans, Steven G. Kargl, David Schultz.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n *\n * The argument reduction and testing for exceptional cases was\n * written by Steven G. Kargl with input from Bruce D. Evans\n * and David A. Schultz.\n */\n\n#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double cbrtl(long double x)\n{\n\treturn cbrt(x);\n}\n#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\nstatic const unsigned B1 = 709958130; /* B1 = (127-127.0/3-0.03306235651)*2**23 */\n\nlong double cbrtl(long double x)\n{\n\tunion ldshape u = {x}, v;\n\tunion {float f; uint32_t i;} uft;\n\tlong double r, s, t, w;\n\tdouble_t dr, dt, dx;\n\tfloat_t ft;\n\tint e = u.i.se & 0x7fff;\n\tint sign = u.i.se & 0x8000;\n\n\t/*\n\t * If x = +-Inf, then cbrt(x) = +-Inf.\n\t * If x = NaN, then cbrt(x) = NaN.\n\t */\n\tif (e == 0x7fff)\n\t\treturn x + x;\n\tif (e == 0) {\n\t\t/* Adjust subnormal numbers. */\n\t\tu.f *= 0x1p120;\n\t\te = u.i.se & 0x7fff;\n\t\t/* If x = +-0, then cbrt(x) = +-0. */\n\t\tif (e == 0)\n\t\t\treturn x;\n\t\te -= 120;\n\t}\n\te -= 0x3fff;\n\tu.i.se = 0x3fff;\n\tx = u.f;\n\tswitch (e % 3) {\n\tcase 1:\n\tcase -2:\n\t\tx *= 2;\n\t\te--;\n\t\tbreak;\n\tcase 2:\n\tcase -1:\n\t\tx *= 4;\n\t\te -= 2;\n\t\tbreak;\n\t}\n\tv.f = 1.0;\n\tv.i.se = sign | (0x3fff + e/3);\n\n\t/*\n\t * The following is the guts of s_cbrtf, with the handling of\n\t * special values removed and extra care for accuracy not taken,\n\t * but with most of the extra accuracy not discarded.\n\t */\n\n\t/* ~5-bit estimate: */\n\tuft.f = x;\n\tuft.i = (uft.i & 0x7fffffff)/3 + B1;\n\tft = uft.f;\n\n\t/* ~16-bit estimate: */\n\tdx = x;\n\tdt = ft;\n\tdr = dt * dt * dt;\n\tdt = dt * (dx + dx + dr) / (dx + dr + dr);\n\n\t/* ~47-bit estimate: */\n\tdr = dt * dt * dt;\n\tdt = dt * (dx + dx + dr) / (dx + dr + dr);\n\n#if LDBL_MANT_DIG == 64\n\t/*\n\t * dt is cbrtl(x) to ~47 bits (after x has been reduced to 1 <= x < 8).\n\t * Round it away from zero to 32 bits (32 so that t*t is exact, and\n\t * away from zero for technical reasons).\n\t */\n\tt = dt + (0x1.0p32L + 0x1.0p-31L) - 0x1.0p32;\n#elif LDBL_MANT_DIG == 113\n\t/*\n\t * Round dt away from zero to 47 bits.  Since we don't trust the 47,\n\t * add 2 47-bit ulps instead of 1 to round up.  Rounding is slow and\n\t * might be avoidable in this case, since on most machines dt will\n\t * have been evaluated in 53-bit precision and the technical reasons\n\t * for rounding up might not apply to either case in cbrtl() since\n\t * dt is much more accurate than needed.\n\t */\n\tt = dt + 0x2.0p-46 + 0x1.0p60L - 0x1.0p60;\n#endif\n\n\t/*\n\t * Final step Newton iteration to 64 or 113 bits with\n\t * error < 0.667 ulps\n\t */\n\ts = t*t;         /* t*t is exact */\n\tr = x/s;         /* error <= 0.5 ulps; |r| < |t| */\n\tw = t+t;         /* t+t is exact */\n\tr = (r-t)/(w+r); /* r-t is exact; w+r ~= 3*t */\n\tt = t+t*r;       /* error <= 0.5 + 0.5/3 + epsilon */\n\n\tt *= v.f;\n\treturn t;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/ceil.c",
    "content": "#include \"libm.h\"\n\n#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1\n#define EPS DBL_EPSILON\n#elif FLT_EVAL_METHOD==2\n#define EPS LDBL_EPSILON\n#endif\nstatic const double_t toint = 1/EPS;\n\ndouble ceil(double x)\n{\n\tunion {double f; uint64_t i;} u = {x};\n\tint e = u.i >> 52 & 0x7ff;\n\tdouble_t y;\n\n\tif (e >= 0x3ff+52 || x == 0)\n\t\treturn x;\n\t/* y = int(x) - x, where int(x) is an integer neighbor of x */\n\tif (u.i >> 63)\n\t\ty = x - toint + toint - x;\n\telse\n\t\ty = x + toint - toint - x;\n\t/* special case because of non-nearest rounding modes */\n\tif (e <= 0x3ff-1) {\n\t\tFORCE_EVAL(y);\n\t\treturn u.i >> 63 ? -0.0 : 1;\n\t}\n\tif (y < 0)\n\t\treturn x + y + 1;\n\treturn x + y;\n}\n"
  },
  {
    "path": "user.libc/src/math/ceilf.c",
    "content": "#include \"libm.h\"\n\nfloat ceilf(float x)\n{\n\tunion {float f; uint32_t i;} u = {x};\n\tint e = (int)(u.i >> 23 & 0xff) - 0x7f;\n\tuint32_t m;\n\n\tif (e >= 23)\n\t\treturn x;\n\tif (e >= 0) {\n\t\tm = 0x007fffff >> e;\n\t\tif ((u.i & m) == 0)\n\t\t\treturn x;\n\t\tFORCE_EVAL(x + 0x1p120f);\n\t\tif (u.i >> 31 == 0)\n\t\t\tu.i += m;\n\t\tu.i &= ~m;\n\t} else {\n\t\tFORCE_EVAL(x + 0x1p120f);\n\t\tif (u.i >> 31)\n\t\t\tu.f = -0.0;\n\t\telse if (u.i << 1)\n\t\t\tu.f = 1.0;\n\t}\n\treturn u.f;\n}\n"
  },
  {
    "path": "user.libc/src/math/ceill.c",
    "content": "#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double ceill(long double x)\n{\n\treturn ceil(x);\n}\n#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\n\nstatic const long double toint = 1/LDBL_EPSILON;\n\nlong double ceill(long double x)\n{\n\tunion ldshape u = {x};\n\tint e = u.i.se & 0x7fff;\n\tlong double y;\n\n\tif (e >= 0x3fff+LDBL_MANT_DIG-1 || x == 0)\n\t\treturn x;\n\t/* y = int(x) - x, where int(x) is an integer neighbor of x */\n\tif (u.i.se >> 15)\n\t\ty = x - toint + toint - x;\n\telse\n\t\ty = x + toint - toint - x;\n\t/* special case because of non-nearest rounding modes */\n\tif (e <= 0x3fff-1) {\n\t\tFORCE_EVAL(y);\n\t\treturn u.i.se >> 15 ? -0.0 : 1;\n\t}\n\tif (y < 0)\n\t\treturn x + y + 1;\n\treturn x + y;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/copysign.c",
    "content": "#include \"libm.h\"\n\ndouble copysign(double x, double y) {\n\tunion {double f; uint64_t i;} ux={x}, uy={y};\n\tux.i &= -1ULL/2;\n\tux.i |= uy.i & 1ULL<<63;\n\treturn ux.f;\n}\n"
  },
  {
    "path": "user.libc/src/math/copysignf.c",
    "content": "#include <math.h>\n#include <stdint.h>\n\nfloat copysignf(float x, float y)\n{\n\tunion {float f; uint32_t i;} ux={x}, uy={y};\n\tux.i &= 0x7fffffff;\n\tux.i |= uy.i & 0x80000000;\n\treturn ux.f;\n}\n"
  },
  {
    "path": "user.libc/src/math/copysignl.c",
    "content": "#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double copysignl(long double x, long double y)\n{\n\treturn copysign(x, y);\n}\n#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\nlong double copysignl(long double x, long double y)\n{\n\tunion ldshape ux = {x}, uy = {y};\n\tux.i.se &= 0x7fff;\n\tux.i.se |= uy.i.se & 0x8000;\n\treturn ux.f;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/cos.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_cos.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/* cos(x)\n * Return cosine function of x.\n *\n * kernel function:\n *      __sin           ... sine function on [-pi/4,pi/4]\n *      __cos           ... cosine function on [-pi/4,pi/4]\n *      __rem_pio2      ... argument reduction routine\n *\n * Method.\n *      Let S,C and T denote the sin, cos and tan respectively on\n *      [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2\n *      in [-pi/4 , +pi/4], and let n = k mod 4.\n *      We have\n *\n *          n        sin(x)      cos(x)        tan(x)\n *     ----------------------------------------------------------\n *          0          S           C             T\n *          1          C          -S            -1/T\n *          2         -S          -C             T\n *          3         -C           S            -1/T\n *     ----------------------------------------------------------\n *\n * Special cases:\n *      Let trig be any of sin, cos, or tan.\n *      trig(+-INF)  is NaN, with signals;\n *      trig(NaN)    is that NaN;\n *\n * Accuracy:\n *      TRIG(x) returns trig(x) nearly rounded\n */\n\n#include \"libm.h\"\n\ndouble cos(double x)\n{\n\tdouble y[2];\n\tuint32_t ix;\n\tunsigned n;\n\n\tGET_HIGH_WORD(ix, x);\n\tix &= 0x7fffffff;\n\n\t/* |x| ~< pi/4 */\n\tif (ix <= 0x3fe921fb) {\n\t\tif (ix < 0x3e46a09e) {  /* |x| < 2**-27 * sqrt(2) */\n\t\t\t/* raise inexact if x!=0 */\n\t\t\tFORCE_EVAL(x + 0x1p120f);\n\t\t\treturn 1.0;\n\t\t}\n\t\treturn __cos(x, 0);\n\t}\n\n\t/* cos(Inf or NaN) is NaN */\n\tif (ix >= 0x7ff00000)\n\t\treturn x-x;\n\n\t/* argument reduction */\n\tn = __rem_pio2(x, y);\n\tswitch (n&3) {\n\tcase 0: return  __cos(y[0], y[1]);\n\tcase 1: return -__sin(y[0], y[1], 1);\n\tcase 2: return -__cos(y[0], y[1]);\n\tdefault:\n\t\treturn  __sin(y[0], y[1], 1);\n\t}\n}\n"
  },
  {
    "path": "user.libc/src/math/cosf.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_cosf.c */\n/*\n * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.\n * Optimized by Bruce D. Evans.\n */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n\n#include \"libm.h\"\n\n/* Small multiples of pi/2 rounded to double precision. */\nstatic const double\nc1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */\nc2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */\nc3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */\nc4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */\n\nfloat cosf(float x)\n{\n\tdouble y;\n\tuint32_t ix;\n\tunsigned n, sign;\n\n\tGET_FLOAT_WORD(ix, x);\n\tsign = ix >> 31;\n\tix &= 0x7fffffff;\n\n\tif (ix <= 0x3f490fda) {  /* |x| ~<= pi/4 */\n\t\tif (ix < 0x39800000) {  /* |x| < 2**-12 */\n\t\t\t/* raise inexact if x != 0 */\n\t\t\tFORCE_EVAL(x + 0x1p120f);\n\t\t\treturn 1.0f;\n\t\t}\n\t\treturn __cosdf(x);\n\t}\n\tif (ix <= 0x407b53d1) {  /* |x| ~<= 5*pi/4 */\n\t\tif (ix > 0x4016cbe3)  /* |x|  ~> 3*pi/4 */\n\t\t\treturn -__cosdf(sign ? x+c2pio2 : x-c2pio2);\n\t\telse {\n\t\t\tif (sign)\n\t\t\t\treturn __sindf(x + c1pio2);\n\t\t\telse\n\t\t\t\treturn __sindf(c1pio2 - x);\n\t\t}\n\t}\n\tif (ix <= 0x40e231d5) {  /* |x| ~<= 9*pi/4 */\n\t\tif (ix > 0x40afeddf)  /* |x| ~> 7*pi/4 */\n\t\t\treturn __cosdf(sign ? x+c4pio2 : x-c4pio2);\n\t\telse {\n\t\t\tif (sign)\n\t\t\t\treturn __sindf(-x - c3pio2);\n\t\t\telse\n\t\t\t\treturn __sindf(x - c3pio2);\n\t\t}\n\t}\n\n\t/* cos(Inf or NaN) is NaN */\n\tif (ix >= 0x7f800000)\n\t\treturn x-x;\n\n\t/* general argument reduction needed */\n\tn = __rem_pio2f(x,&y);\n\tswitch (n&3) {\n\tcase 0: return  __cosdf(y);\n\tcase 1: return  __sindf(-y);\n\tcase 2: return -__cosdf(y);\n\tdefault:\n\t\treturn  __sindf(y);\n\t}\n}\n"
  },
  {
    "path": "user.libc/src/math/cosh.c",
    "content": "#include \"libm.h\"\n\n/* cosh(x) = (exp(x) + 1/exp(x))/2\n *         = 1 + 0.5*(exp(x)-1)*(exp(x)-1)/exp(x)\n *         = 1 + x*x/2 + o(x^4)\n */\ndouble cosh(double x)\n{\n\tunion {double f; uint64_t i;} u = {.f = x};\n\tuint32_t w;\n\tdouble t;\n\n\t/* |x| */\n\tu.i &= (uint64_t)-1/2;\n\tx = u.f;\n\tw = u.i >> 32;\n\n\t/* |x| < log(2) */\n\tif (w < 0x3fe62e42) {\n\t\tif (w < 0x3ff00000 - (26<<20)) {\n\t\t\t/* raise inexact if x!=0 */\n\t\t\tFORCE_EVAL(x + 0x1p120f);\n\t\t\treturn 1;\n\t\t}\n\t\tt = expm1(x);\n\t\treturn 1 + t*t/(2*(1+t));\n\t}\n\n\t/* |x| < log(DBL_MAX) */\n\tif (w < 0x40862e42) {\n\t\tt = exp(x);\n\t\t/* note: if x>log(0x1p26) then the 1/t is not needed */\n\t\treturn 0.5*(t + 1/t);\n\t}\n\n\t/* |x| > log(DBL_MAX) or nan */\n\t/* note: the result is stored to handle overflow */\n\tt = __expo2(x, 1.0);\n\treturn t;\n}\n"
  },
  {
    "path": "user.libc/src/math/coshf.c",
    "content": "#include \"libm.h\"\n\nfloat coshf(float x)\n{\n\tunion {float f; uint32_t i;} u = {.f = x};\n\tuint32_t w;\n\tfloat t;\n\n\t/* |x| */\n\tu.i &= 0x7fffffff;\n\tx = u.f;\n\tw = u.i;\n\n\t/* |x| < log(2) */\n\tif (w < 0x3f317217) {\n\t\tif (w < 0x3f800000 - (12<<23)) {\n\t\t\tFORCE_EVAL(x + 0x1p120f);\n\t\t\treturn 1;\n\t\t}\n\t\tt = expm1f(x);\n\t\treturn 1 + t*t/(2*(1+t));\n\t}\n\n\t/* |x| < log(FLT_MAX) */\n\tif (w < 0x42b17217) {\n\t\tt = expf(x);\n\t\treturn 0.5f*(t + 1/t);\n\t}\n\n\t/* |x| > log(FLT_MAX) or nan */\n\tt = __expo2f(x, 1.0f);\n\treturn t;\n}\n"
  },
  {
    "path": "user.libc/src/math/coshl.c",
    "content": "#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double coshl(long double x)\n{\n\treturn cosh(x);\n}\n#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384\nlong double coshl(long double x)\n{\n\tunion ldshape u = {x};\n\tunsigned ex = u.i.se & 0x7fff;\n\tuint32_t w;\n\tlong double t;\n\n\t/* |x| */\n\tu.i.se = ex;\n\tx = u.f;\n\tw = u.i.m >> 32;\n\n\t/* |x| < log(2) */\n\tif (ex < 0x3fff-1 || (ex == 0x3fff-1 && w < 0xb17217f7)) {\n\t\tif (ex < 0x3fff-32) {\n\t\t\tFORCE_EVAL(x + 0x1p120f);\n\t\t\treturn 1;\n\t\t}\n\t\tt = expm1l(x);\n\t\treturn 1 + t*t/(2*(1+t));\n\t}\n\n\t/* |x| < log(LDBL_MAX) */\n\tif (ex < 0x3fff+13 || (ex == 0x3fff+13 && w < 0xb17217f7)) {\n\t\tt = expl(x);\n\t\treturn 0.5*(t + 1/t);\n\t}\n\n\t/* |x| > log(LDBL_MAX) or nan */\n\tt = expl(0.5*x);\n\treturn 0.5*t*t;\n}\n#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384\n// TODO: broken implementation to make things compile\nlong double coshl(long double x)\n{\n\treturn cosh(x);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/cosl.c",
    "content": "#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double cosl(long double x) {\n\treturn cos(x);\n}\n#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\nlong double cosl(long double x)\n{\n\tunion ldshape u = {x};\n\tunsigned n;\n\tlong double y[2], hi, lo;\n\n\tu.i.se &= 0x7fff;\n\tif (u.i.se == 0x7fff)\n\t\treturn x - x;\n\tx = u.f;\n\tif (x < M_PI_4) {\n\t\tif (u.i.se < 0x3fff - LDBL_MANT_DIG)\n\t\t\t/* raise inexact if x!=0 */\n\t\t\treturn 1.0 + x;\n\t\treturn __cosl(x, 0);\n\t}\n\tn = __rem_pio2l(x, y);\n\thi = y[0];\n\tlo = y[1];\n\tswitch (n & 3) {\n\tcase 0:\n\t\treturn __cosl(hi, lo);\n\tcase 1:\n\t\treturn -__sinl(hi, lo, 1);\n\tcase 2:\n\t\treturn -__cosl(hi, lo);\n\tcase 3:\n\tdefault:\n\t\treturn __sinl(hi, lo, 1);\n\t}\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/erf.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_erf.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/* double erf(double x)\n * double erfc(double x)\n *                           x\n *                    2      |\\\n *     erf(x)  =  ---------  | exp(-t*t)dt\n *                 sqrt(pi) \\|\n *                           0\n *\n *     erfc(x) =  1-erf(x)\n *  Note that\n *              erf(-x) = -erf(x)\n *              erfc(-x) = 2 - erfc(x)\n *\n * Method:\n *      1. For |x| in [0, 0.84375]\n *          erf(x)  = x + x*R(x^2)\n *          erfc(x) = 1 - erf(x)           if x in [-.84375,0.25]\n *                  = 0.5 + ((0.5-x)-x*R)  if x in [0.25,0.84375]\n *         where R = P/Q where P is an odd poly of degree 8 and\n *         Q is an odd poly of degree 10.\n *                                               -57.90\n *                      | R - (erf(x)-x)/x | <= 2\n *\n *\n *         Remark. The formula is derived by noting\n *          erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....)\n *         and that\n *          2/sqrt(pi) = 1.128379167095512573896158903121545171688\n *         is close to one. The interval is chosen because the fix\n *         point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is\n *         near 0.6174), and by some experiment, 0.84375 is chosen to\n *         guarantee the error is less than one ulp for erf.\n *\n *      2. For |x| in [0.84375,1.25], let s = |x| - 1, and\n *         c = 0.84506291151 rounded to single (24 bits)\n *              erf(x)  = sign(x) * (c  + P1(s)/Q1(s))\n *              erfc(x) = (1-c)  - P1(s)/Q1(s) if x > 0\n *                        1+(c+P1(s)/Q1(s))    if x < 0\n *              |P1/Q1 - (erf(|x|)-c)| <= 2**-59.06\n *         Remark: here we use the taylor series expansion at x=1.\n *              erf(1+s) = erf(1) + s*Poly(s)\n *                       = 0.845.. + P1(s)/Q1(s)\n *         That is, we use rational approximation to approximate\n *                      erf(1+s) - (c = (single)0.84506291151)\n *         Note that |P1/Q1|< 0.078 for x in [0.84375,1.25]\n *         where\n *              P1(s) = degree 6 poly in s\n *              Q1(s) = degree 6 poly in s\n *\n *      3. For x in [1.25,1/0.35(~2.857143)],\n *              erfc(x) = (1/x)*exp(-x*x-0.5625+R1/S1)\n *              erf(x)  = 1 - erfc(x)\n *         where\n *              R1(z) = degree 7 poly in z, (z=1/x^2)\n *              S1(z) = degree 8 poly in z\n *\n *      4. For x in [1/0.35,28]\n *              erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0\n *                      = 2.0 - (1/x)*exp(-x*x-0.5625+R2/S2) if -6<x<0\n *                      = 2.0 - tiny            (if x <= -6)\n *              erf(x)  = sign(x)*(1.0 - erfc(x)) if x < 6, else\n *              erf(x)  = sign(x)*(1.0 - tiny)\n *         where\n *              R2(z) = degree 6 poly in z, (z=1/x^2)\n *              S2(z) = degree 7 poly in z\n *\n *      Note1:\n *         To compute exp(-x*x-0.5625+R/S), let s be a single\n *         precision number and s := x; then\n *              -x*x = -s*s + (s-x)*(s+x)\n *              exp(-x*x-0.5626+R/S) =\n *                      exp(-s*s-0.5625)*exp((s-x)*(s+x)+R/S);\n *      Note2:\n *         Here 4 and 5 make use of the asymptotic series\n *                        exp(-x*x)\n *              erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) )\n *                        x*sqrt(pi)\n *         We use rational approximation to approximate\n *              g(s)=f(1/x^2) = log(erfc(x)*x) - x*x + 0.5625\n *         Here is the error bound for R1/S1 and R2/S2\n *              |R1/S1 - f(x)|  < 2**(-62.57)\n *              |R2/S2 - f(x)|  < 2**(-61.52)\n *\n *      5. For inf > x >= 28\n *              erf(x)  = sign(x) *(1 - tiny)  (raise inexact)\n *              erfc(x) = tiny*tiny (raise underflow) if x > 0\n *                      = 2 - tiny if x<0\n *\n *      7. Special case:\n *              erf(0)  = 0, erf(inf)  = 1, erf(-inf) = -1,\n *              erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2,\n *              erfc/erf(NaN) is NaN\n */\n\n#include \"libm.h\"\n\nstatic const double\nerx  = 8.45062911510467529297e-01, /* 0x3FEB0AC1, 0x60000000 */\n/*\n * Coefficients for approximation to  erf on [0,0.84375]\n */\nefx8 =  1.02703333676410069053e+00, /* 0x3FF06EBA, 0x8214DB69 */\npp0  =  1.28379167095512558561e-01, /* 0x3FC06EBA, 0x8214DB68 */\npp1  = -3.25042107247001499370e-01, /* 0xBFD4CD7D, 0x691CB913 */\npp2  = -2.84817495755985104766e-02, /* 0xBF9D2A51, 0xDBD7194F */\npp3  = -5.77027029648944159157e-03, /* 0xBF77A291, 0x236668E4 */\npp4  = -2.37630166566501626084e-05, /* 0xBEF8EAD6, 0x120016AC */\nqq1  =  3.97917223959155352819e-01, /* 0x3FD97779, 0xCDDADC09 */\nqq2  =  6.50222499887672944485e-02, /* 0x3FB0A54C, 0x5536CEBA */\nqq3  =  5.08130628187576562776e-03, /* 0x3F74D022, 0xC4D36B0F */\nqq4  =  1.32494738004321644526e-04, /* 0x3F215DC9, 0x221C1A10 */\nqq5  = -3.96022827877536812320e-06, /* 0xBED09C43, 0x42A26120 */\n/*\n * Coefficients for approximation to  erf  in [0.84375,1.25]\n */\npa0  = -2.36211856075265944077e-03, /* 0xBF6359B8, 0xBEF77538 */\npa1  =  4.14856118683748331666e-01, /* 0x3FDA8D00, 0xAD92B34D */\npa2  = -3.72207876035701323847e-01, /* 0xBFD7D240, 0xFBB8C3F1 */\npa3  =  3.18346619901161753674e-01, /* 0x3FD45FCA, 0x805120E4 */\npa4  = -1.10894694282396677476e-01, /* 0xBFBC6398, 0x3D3E28EC */\npa5  =  3.54783043256182359371e-02, /* 0x3FA22A36, 0x599795EB */\npa6  = -2.16637559486879084300e-03, /* 0xBF61BF38, 0x0A96073F */\nqa1  =  1.06420880400844228286e-01, /* 0x3FBB3E66, 0x18EEE323 */\nqa2  =  5.40397917702171048937e-01, /* 0x3FE14AF0, 0x92EB6F33 */\nqa3  =  7.18286544141962662868e-02, /* 0x3FB2635C, 0xD99FE9A7 */\nqa4  =  1.26171219808761642112e-01, /* 0x3FC02660, 0xE763351F */\nqa5  =  1.36370839120290507362e-02, /* 0x3F8BEDC2, 0x6B51DD1C */\nqa6  =  1.19844998467991074170e-02, /* 0x3F888B54, 0x5735151D */\n/*\n * Coefficients for approximation to  erfc in [1.25,1/0.35]\n */\nra0  = -9.86494403484714822705e-03, /* 0xBF843412, 0x600D6435 */\nra1  = -6.93858572707181764372e-01, /* 0xBFE63416, 0xE4BA7360 */\nra2  = -1.05586262253232909814e+01, /* 0xC0251E04, 0x41B0E726 */\nra3  = -6.23753324503260060396e+01, /* 0xC04F300A, 0xE4CBA38D */\nra4  = -1.62396669462573470355e+02, /* 0xC0644CB1, 0x84282266 */\nra5  = -1.84605092906711035994e+02, /* 0xC067135C, 0xEBCCABB2 */\nra6  = -8.12874355063065934246e+01, /* 0xC0545265, 0x57E4D2F2 */\nra7  = -9.81432934416914548592e+00, /* 0xC023A0EF, 0xC69AC25C */\nsa1  =  1.96512716674392571292e+01, /* 0x4033A6B9, 0xBD707687 */\nsa2  =  1.37657754143519042600e+02, /* 0x4061350C, 0x526AE721 */\nsa3  =  4.34565877475229228821e+02, /* 0x407B290D, 0xD58A1A71 */\nsa4  =  6.45387271733267880336e+02, /* 0x40842B19, 0x21EC2868 */\nsa5  =  4.29008140027567833386e+02, /* 0x407AD021, 0x57700314 */\nsa6  =  1.08635005541779435134e+02, /* 0x405B28A3, 0xEE48AE2C */\nsa7  =  6.57024977031928170135e+00, /* 0x401A47EF, 0x8E484A93 */\nsa8  = -6.04244152148580987438e-02, /* 0xBFAEEFF2, 0xEE749A62 */\n/*\n * Coefficients for approximation to  erfc in [1/.35,28]\n */\nrb0  = -9.86494292470009928597e-03, /* 0xBF843412, 0x39E86F4A */\nrb1  = -7.99283237680523006574e-01, /* 0xBFE993BA, 0x70C285DE */\nrb2  = -1.77579549177547519889e+01, /* 0xC031C209, 0x555F995A */\nrb3  = -1.60636384855821916062e+02, /* 0xC064145D, 0x43C5ED98 */\nrb4  = -6.37566443368389627722e+02, /* 0xC083EC88, 0x1375F228 */\nrb5  = -1.02509513161107724954e+03, /* 0xC0900461, 0x6A2E5992 */\nrb6  = -4.83519191608651397019e+02, /* 0xC07E384E, 0x9BDC383F */\nsb1  =  3.03380607434824582924e+01, /* 0x403E568B, 0x261D5190 */\nsb2  =  3.25792512996573918826e+02, /* 0x40745CAE, 0x221B9F0A */\nsb3  =  1.53672958608443695994e+03, /* 0x409802EB, 0x189D5118 */\nsb4  =  3.19985821950859553908e+03, /* 0x40A8FFB7, 0x688C246A */\nsb5  =  2.55305040643316442583e+03, /* 0x40A3F219, 0xCEDF3BE6 */\nsb6  =  4.74528541206955367215e+02, /* 0x407DA874, 0xE79FE763 */\nsb7  = -2.24409524465858183362e+01; /* 0xC03670E2, 0x42712D62 */\n\nstatic double erfc1(double x)\n{\n\tdouble_t s,P,Q;\n\n\ts = fabs(x) - 1;\n\tP = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));\n\tQ = 1+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));\n\treturn 1 - erx - P/Q;\n}\n\nstatic double erfc2(uint32_t ix, double x)\n{\n\tdouble_t s,R,S;\n\tdouble z;\n\n\tif (ix < 0x3ff40000)  /* |x| < 1.25 */\n\t\treturn erfc1(x);\n\n\tx = fabs(x);\n\ts = 1/(x*x);\n\tif (ix < 0x4006db6d) {  /* |x| < 1/.35 ~ 2.85714 */\n\t\tR = ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(\n\t\t     ra5+s*(ra6+s*ra7))))));\n\t\tS = 1.0+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(\n\t\t     sa5+s*(sa6+s*(sa7+s*sa8)))))));\n\t} else {                /* |x| > 1/.35 */\n\t\tR = rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(\n\t\t     rb5+s*rb6)))));\n\t\tS = 1.0+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(\n\t\t     sb5+s*(sb6+s*sb7))))));\n\t}\n\tz = x;\n\tSET_LOW_WORD(z,0);\n\treturn exp(-z*z-0.5625)*exp((z-x)*(z+x)+R/S)/x;\n}\n\ndouble erf(double x)\n{\n\tdouble r,s,z,y;\n\tuint32_t ix;\n\tint sign;\n\n\tGET_HIGH_WORD(ix, x);\n\tsign = ix>>31;\n\tix &= 0x7fffffff;\n\tif (ix >= 0x7ff00000) {\n\t\t/* erf(nan)=nan, erf(+-inf)=+-1 */\n\t\treturn 1-2*sign + 1/x;\n\t}\n\tif (ix < 0x3feb0000) {  /* |x| < 0.84375 */\n\t\tif (ix < 0x3e300000) {  /* |x| < 2**-28 */\n\t\t\t/* avoid underflow */\n\t\t\treturn 0.125*(8*x + efx8*x);\n\t\t}\n\t\tz = x*x;\n\t\tr = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));\n\t\ts = 1.0+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));\n\t\ty = r/s;\n\t\treturn x + x*y;\n\t}\n\tif (ix < 0x40180000)  /* 0.84375 <= |x| < 6 */\n\t\ty = 1 - erfc2(ix,x);\n\telse\n\t\ty = 1 - 0x1p-1022;\n\treturn sign ? -y : y;\n}\n\ndouble erfc(double x)\n{\n\tdouble r,s,z,y;\n\tuint32_t ix;\n\tint sign;\n\n\tGET_HIGH_WORD(ix, x);\n\tsign = ix>>31;\n\tix &= 0x7fffffff;\n\tif (ix >= 0x7ff00000) {\n\t\t/* erfc(nan)=nan, erfc(+-inf)=0,2 */\n\t\treturn 2*sign + 1/x;\n\t}\n\tif (ix < 0x3feb0000) {  /* |x| < 0.84375 */\n\t\tif (ix < 0x3c700000)  /* |x| < 2**-56 */\n\t\t\treturn 1.0 - x;\n\t\tz = x*x;\n\t\tr = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));\n\t\ts = 1.0+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));\n\t\ty = r/s;\n\t\tif (sign || ix < 0x3fd00000) {  /* x < 1/4 */\n\t\t\treturn 1.0 - (x+x*y);\n\t\t}\n\t\treturn 0.5 - (x - 0.5 + x*y);\n\t}\n\tif (ix < 0x403c0000) {  /* 0.84375 <= |x| < 28 */\n\t\treturn sign ? 2 - erfc2(ix,x) : erfc2(ix,x);\n\t}\n\treturn sign ? 2 - 0x1p-1022 : 0x1p-1022*0x1p-1022;\n}\n"
  },
  {
    "path": "user.libc/src/math/erff.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_erff.c */\n/*\n * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.\n */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n\n#include \"libm.h\"\n\nstatic const float\nerx  =  8.4506291151e-01, /* 0x3f58560b */\n/*\n * Coefficients for approximation to  erf on [0,0.84375]\n */\nefx8 =  1.0270333290e+00, /* 0x3f8375d4 */\npp0  =  1.2837916613e-01, /* 0x3e0375d4 */\npp1  = -3.2504209876e-01, /* 0xbea66beb */\npp2  = -2.8481749818e-02, /* 0xbce9528f */\npp3  = -5.7702702470e-03, /* 0xbbbd1489 */\npp4  = -2.3763017452e-05, /* 0xb7c756b1 */\nqq1  =  3.9791721106e-01, /* 0x3ecbbbce */\nqq2  =  6.5022252500e-02, /* 0x3d852a63 */\nqq3  =  5.0813062117e-03, /* 0x3ba68116 */\nqq4  =  1.3249473704e-04, /* 0x390aee49 */\nqq5  = -3.9602282413e-06, /* 0xb684e21a */\n/*\n * Coefficients for approximation to  erf  in [0.84375,1.25]\n */\npa0  = -2.3621185683e-03, /* 0xbb1acdc6 */\npa1  =  4.1485610604e-01, /* 0x3ed46805 */\npa2  = -3.7220788002e-01, /* 0xbebe9208 */\npa3  =  3.1834661961e-01, /* 0x3ea2fe54 */\npa4  = -1.1089469492e-01, /* 0xbde31cc2 */\npa5  =  3.5478305072e-02, /* 0x3d1151b3 */\npa6  = -2.1663755178e-03, /* 0xbb0df9c0 */\nqa1  =  1.0642088205e-01, /* 0x3dd9f331 */\nqa2  =  5.4039794207e-01, /* 0x3f0a5785 */\nqa3  =  7.1828655899e-02, /* 0x3d931ae7 */\nqa4  =  1.2617121637e-01, /* 0x3e013307 */\nqa5  =  1.3637083583e-02, /* 0x3c5f6e13 */\nqa6  =  1.1984500103e-02, /* 0x3c445aa3 */\n/*\n * Coefficients for approximation to  erfc in [1.25,1/0.35]\n */\nra0  = -9.8649440333e-03, /* 0xbc21a093 */\nra1  = -6.9385856390e-01, /* 0xbf31a0b7 */\nra2  = -1.0558626175e+01, /* 0xc128f022 */\nra3  = -6.2375331879e+01, /* 0xc2798057 */\nra4  = -1.6239666748e+02, /* 0xc322658c */\nra5  = -1.8460508728e+02, /* 0xc3389ae7 */\nra6  = -8.1287437439e+01, /* 0xc2a2932b */\nra7  = -9.8143291473e+00, /* 0xc11d077e */\nsa1  =  1.9651271820e+01, /* 0x419d35ce */\nsa2  =  1.3765776062e+02, /* 0x4309a863 */\nsa3  =  4.3456588745e+02, /* 0x43d9486f */\nsa4  =  6.4538726807e+02, /* 0x442158c9 */\nsa5  =  4.2900814819e+02, /* 0x43d6810b */\nsa6  =  1.0863500214e+02, /* 0x42d9451f */\nsa7  =  6.5702495575e+00, /* 0x40d23f7c */\nsa8  = -6.0424413532e-02, /* 0xbd777f97 */\n/*\n * Coefficients for approximation to  erfc in [1/.35,28]\n */\nrb0  = -9.8649431020e-03, /* 0xbc21a092 */\nrb1  = -7.9928326607e-01, /* 0xbf4c9dd4 */\nrb2  = -1.7757955551e+01, /* 0xc18e104b */\nrb3  = -1.6063638306e+02, /* 0xc320a2ea */\nrb4  = -6.3756646729e+02, /* 0xc41f6441 */\nrb5  = -1.0250950928e+03, /* 0xc480230b */\nrb6  = -4.8351919556e+02, /* 0xc3f1c275 */\nsb1  =  3.0338060379e+01, /* 0x41f2b459 */\nsb2  =  3.2579251099e+02, /* 0x43a2e571 */\nsb3  =  1.5367296143e+03, /* 0x44c01759 */\nsb4  =  3.1998581543e+03, /* 0x4547fdbb */\nsb5  =  2.5530502930e+03, /* 0x451f90ce */\nsb6  =  4.7452853394e+02, /* 0x43ed43a7 */\nsb7  = -2.2440952301e+01; /* 0xc1b38712 */\n\nstatic float erfc1(float x)\n{\n\tfloat_t s,P,Q;\n\n\ts = fabsf(x) - 1;\n\tP = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));\n\tQ = 1+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));\n\treturn 1 - erx - P/Q;\n}\n\nstatic float erfc2(uint32_t ix, float x)\n{\n\tfloat_t s,R,S;\n\tfloat z;\n\n\tif (ix < 0x3fa00000)  /* |x| < 1.25 */\n\t\treturn erfc1(x);\n\n\tx = fabsf(x);\n\ts = 1/(x*x);\n\tif (ix < 0x4036db6d) {   /* |x| < 1/0.35 */\n\t\tR = ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(\n\t\t     ra5+s*(ra6+s*ra7))))));\n\t\tS = 1.0f+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(\n\t\t     sa5+s*(sa6+s*(sa7+s*sa8)))))));\n\t} else {                 /* |x| >= 1/0.35 */\n\t\tR = rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(\n\t\t     rb5+s*rb6)))));\n\t\tS = 1.0f+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(\n\t\t     sb5+s*(sb6+s*sb7))))));\n\t}\n\tGET_FLOAT_WORD(ix, x);\n\tSET_FLOAT_WORD(z, ix&0xffffe000);\n\treturn expf(-z*z - 0.5625f) * expf((z-x)*(z+x) + R/S)/x;\n}\n\nfloat erff(float x)\n{\n\tfloat r,s,z,y;\n\tuint32_t ix;\n\tint sign;\n\n\tGET_FLOAT_WORD(ix, x);\n\tsign = ix>>31;\n\tix &= 0x7fffffff;\n\tif (ix >= 0x7f800000) {\n\t\t/* erf(nan)=nan, erf(+-inf)=+-1 */\n\t\treturn 1-2*sign + 1/x;\n\t}\n\tif (ix < 0x3f580000) {  /* |x| < 0.84375 */\n\t\tif (ix < 0x31800000) {  /* |x| < 2**-28 */\n\t\t\t/*avoid underflow */\n\t\t\treturn 0.125f*(8*x + efx8*x);\n\t\t}\n\t\tz = x*x;\n\t\tr = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));\n\t\ts = 1+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));\n\t\ty = r/s;\n\t\treturn x + x*y;\n\t}\n\tif (ix < 0x40c00000)  /* |x| < 6 */\n\t\ty = 1 - erfc2(ix,x);\n\telse\n\t\ty = 1 - 0x1p-120f;\n\treturn sign ? -y : y;\n}\n\nfloat erfcf(float x)\n{\n\tfloat r,s,z,y;\n\tuint32_t ix;\n\tint sign;\n\n\tGET_FLOAT_WORD(ix, x);\n\tsign = ix>>31;\n\tix &= 0x7fffffff;\n\tif (ix >= 0x7f800000) {\n\t\t/* erfc(nan)=nan, erfc(+-inf)=0,2 */\n\t\treturn 2*sign + 1/x;\n\t}\n\n\tif (ix < 0x3f580000) {  /* |x| < 0.84375 */\n\t\tif (ix < 0x23800000)  /* |x| < 2**-56 */\n\t\t\treturn 1.0f - x;\n\t\tz = x*x;\n\t\tr = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));\n\t\ts = 1.0f+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));\n\t\ty = r/s;\n\t\tif (sign || ix < 0x3e800000)  /* x < 1/4 */\n\t\t\treturn 1.0f - (x+x*y);\n\t\treturn 0.5f - (x - 0.5f + x*y);\n\t}\n\tif (ix < 0x41e00000) {  /* |x| < 28 */\n\t\treturn sign ? 2 - erfc2(ix,x) : erfc2(ix,x);\n\t}\n\treturn sign ? 2 - 0x1p-120f : 0x1p-120f*0x1p-120f;\n}\n"
  },
  {
    "path": "user.libc/src/math/erfl.c",
    "content": "/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_erfl.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/*\n * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n/* double erf(double x)\n * double erfc(double x)\n *                           x\n *                    2      |\\\n *     erf(x)  =  ---------  | exp(-t*t)dt\n *                 sqrt(pi) \\|\n *                           0\n *\n *     erfc(x) =  1-erf(x)\n *  Note that\n *              erf(-x) = -erf(x)\n *              erfc(-x) = 2 - erfc(x)\n *\n * Method:\n *      1. For |x| in [0, 0.84375]\n *          erf(x)  = x + x*R(x^2)\n *          erfc(x) = 1 - erf(x)           if x in [-.84375,0.25]\n *                  = 0.5 + ((0.5-x)-x*R)  if x in [0.25,0.84375]\n *         Remark. The formula is derived by noting\n *          erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....)\n *         and that\n *          2/sqrt(pi) = 1.128379167095512573896158903121545171688\n *         is close to one. The interval is chosen because the fix\n *         point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is\n *         near 0.6174), and by some experiment, 0.84375 is chosen to\n *         guarantee the error is less than one ulp for erf.\n *\n *      2. For |x| in [0.84375,1.25], let s = |x| - 1, and\n *         c = 0.84506291151 rounded to single (24 bits)\n *      erf(x)  = sign(x) * (c  + P1(s)/Q1(s))\n *      erfc(x) = (1-c)  - P1(s)/Q1(s) if x > 0\n *                        1+(c+P1(s)/Q1(s))    if x < 0\n *         Remark: here we use the taylor series expansion at x=1.\n *              erf(1+s) = erf(1) + s*Poly(s)\n *                       = 0.845.. + P1(s)/Q1(s)\n *         Note that |P1/Q1|< 0.078 for x in [0.84375,1.25]\n *\n *      3. For x in [1.25,1/0.35(~2.857143)],\n *      erfc(x) = (1/x)*exp(-x*x-0.5625+R1(z)/S1(z))\n *              z=1/x^2\n *      erf(x)  = 1 - erfc(x)\n *\n *      4. For x in [1/0.35,107]\n *      erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0\n *                      = 2.0 - (1/x)*exp(-x*x-0.5625+R2(z)/S2(z))\n *                             if -6.666<x<0\n *                      = 2.0 - tiny            (if x <= -6.666)\n *              z=1/x^2\n *      erf(x)  = sign(x)*(1.0 - erfc(x)) if x < 6.666, else\n *      erf(x)  = sign(x)*(1.0 - tiny)\n *      Note1:\n *         To compute exp(-x*x-0.5625+R/S), let s be a single\n *         precision number and s := x; then\n *              -x*x = -s*s + (s-x)*(s+x)\n *              exp(-x*x-0.5626+R/S) =\n *                      exp(-s*s-0.5625)*exp((s-x)*(s+x)+R/S);\n *      Note2:\n *         Here 4 and 5 make use of the asymptotic series\n *                        exp(-x*x)\n *              erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) )\n *                        x*sqrt(pi)\n *\n *      5. For inf > x >= 107\n *      erf(x)  = sign(x) *(1 - tiny)  (raise inexact)\n *      erfc(x) = tiny*tiny (raise underflow) if x > 0\n *                      = 2 - tiny if x<0\n *\n *      7. Special case:\n *      erf(0)  = 0, erf(inf)  = 1, erf(-inf) = -1,\n *      erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2,\n *              erfc/erf(NaN) is NaN\n */\n\n\n#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double erfl(long double x)\n{\n\treturn erf(x);\n}\nlong double erfcl(long double x)\n{\n\treturn erfc(x);\n}\n#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384\nstatic const long double\nerx = 0.845062911510467529296875L,\n\n/*\n * Coefficients for approximation to  erf on [0,0.84375]\n */\n/* 8 * (2/sqrt(pi) - 1) */\nefx8 = 1.0270333367641005911692712249723613735048E0L,\npp[6] = {\n\t1.122751350964552113068262337278335028553E6L,\n\t-2.808533301997696164408397079650699163276E6L,\n\t-3.314325479115357458197119660818768924100E5L,\n\t-6.848684465326256109712135497895525446398E4L,\n\t-2.657817695110739185591505062971929859314E3L,\n\t-1.655310302737837556654146291646499062882E2L,\n},\nqq[6] = {\n\t8.745588372054466262548908189000448124232E6L,\n\t3.746038264792471129367533128637019611485E6L,\n\t7.066358783162407559861156173539693900031E5L,\n\t7.448928604824620999413120955705448117056E4L,\n\t4.511583986730994111992253980546131408924E3L,\n\t1.368902937933296323345610240009071254014E2L,\n\t/* 1.000000000000000000000000000000000000000E0 */\n},\n\n/*\n * Coefficients for approximation to  erf  in [0.84375,1.25]\n */\n/* erf(x+1) = 0.845062911510467529296875 + pa(x)/qa(x)\n   -0.15625 <= x <= +.25\n   Peak relative error 8.5e-22  */\npa[8] = {\n\t-1.076952146179812072156734957705102256059E0L,\n\t 1.884814957770385593365179835059971587220E2L,\n\t-5.339153975012804282890066622962070115606E1L,\n\t 4.435910679869176625928504532109635632618E1L,\n\t 1.683219516032328828278557309642929135179E1L,\n\t-2.360236618396952560064259585299045804293E0L,\n\t 1.852230047861891953244413872297940938041E0L,\n\t 9.394994446747752308256773044667843200719E-2L,\n},\nqa[7] =  {\n\t4.559263722294508998149925774781887811255E2L,\n\t3.289248982200800575749795055149780689738E2L,\n\t2.846070965875643009598627918383314457912E2L,\n\t1.398715859064535039433275722017479994465E2L,\n\t6.060190733759793706299079050985358190726E1L,\n\t2.078695677795422351040502569964299664233E1L,\n\t4.641271134150895940966798357442234498546E0L,\n\t/* 1.000000000000000000000000000000000000000E0 */\n},\n\n/*\n * Coefficients for approximation to  erfc in [1.25,1/0.35]\n */\n/* erfc(1/x) = x exp (-1/x^2 - 0.5625 + ra(x^2)/sa(x^2))\n   1/2.85711669921875 < 1/x < 1/1.25\n   Peak relative error 3.1e-21  */\nra[] = {\n\t1.363566591833846324191000679620738857234E-1L,\n\t1.018203167219873573808450274314658434507E1L,\n\t1.862359362334248675526472871224778045594E2L,\n\t1.411622588180721285284945138667933330348E3L,\n\t5.088538459741511988784440103218342840478E3L,\n\t8.928251553922176506858267311750789273656E3L,\n\t7.264436000148052545243018622742770549982E3L,\n\t2.387492459664548651671894725748959751119E3L,\n\t2.220916652813908085449221282808458466556E2L,\n},\nsa[] = {\n\t-1.382234625202480685182526402169222331847E1L,\n\t-3.315638835627950255832519203687435946482E2L,\n\t-2.949124863912936259747237164260785326692E3L,\n\t-1.246622099070875940506391433635999693661E4L,\n\t-2.673079795851665428695842853070996219632E4L,\n\t-2.880269786660559337358397106518918220991E4L,\n\t-1.450600228493968044773354186390390823713E4L,\n\t-2.874539731125893533960680525192064277816E3L,\n\t-1.402241261419067750237395034116942296027E2L,\n\t/* 1.000000000000000000000000000000000000000E0 */\n},\n\n/*\n * Coefficients for approximation to  erfc in [1/.35,107]\n */\n/* erfc(1/x) = x exp (-1/x^2 - 0.5625 + rb(x^2)/sb(x^2))\n   1/6.6666259765625 < 1/x < 1/2.85711669921875\n   Peak relative error 4.2e-22  */\nrb[] = {\n\t-4.869587348270494309550558460786501252369E-5L,\n\t-4.030199390527997378549161722412466959403E-3L,\n\t-9.434425866377037610206443566288917589122E-2L,\n\t-9.319032754357658601200655161585539404155E-1L,\n\t-4.273788174307459947350256581445442062291E0L,\n\t-8.842289940696150508373541814064198259278E0L,\n\t-7.069215249419887403187988144752613025255E0L,\n\t-1.401228723639514787920274427443330704764E0L,\n},\nsb[] = {\n\t4.936254964107175160157544545879293019085E-3L,\n\t1.583457624037795744377163924895349412015E-1L,\n\t1.850647991850328356622940552450636420484E0L,\n\t9.927611557279019463768050710008450625415E0L,\n\t2.531667257649436709617165336779212114570E1L,\n\t2.869752886406743386458304052862814690045E1L,\n\t1.182059497870819562441683560749192539345E1L,\n\t/* 1.000000000000000000000000000000000000000E0 */\n},\n/* erfc(1/x) = x exp (-1/x^2 - 0.5625 + rc(x^2)/sc(x^2))\n   1/107 <= 1/x <= 1/6.6666259765625\n   Peak relative error 1.1e-21  */\nrc[] = {\n\t-8.299617545269701963973537248996670806850E-5L,\n\t-6.243845685115818513578933902532056244108E-3L,\n\t-1.141667210620380223113693474478394397230E-1L,\n\t-7.521343797212024245375240432734425789409E-1L,\n\t-1.765321928311155824664963633786967602934E0L,\n\t-1.029403473103215800456761180695263439188E0L,\n},\nsc[] = {\n\t8.413244363014929493035952542677768808601E-3L,\n\t2.065114333816877479753334599639158060979E-1L,\n\t1.639064941530797583766364412782135680148E0L,\n\t4.936788463787115555582319302981666347450E0L,\n\t5.005177727208955487404729933261347679090E0L,\n\t/* 1.000000000000000000000000000000000000000E0 */\n};\n\nstatic long double erfc1(long double x)\n{\n\tlong double s,P,Q;\n\n\ts = fabsl(x) - 1;\n\tP = pa[0] + s * (pa[1] + s * (pa[2] +\n\t     s * (pa[3] + s * (pa[4] + s * (pa[5] + s * (pa[6] + s * pa[7]))))));\n\tQ = qa[0] + s * (qa[1] + s * (qa[2] +\n\t     s * (qa[3] + s * (qa[4] + s * (qa[5] + s * (qa[6] + s))))));\n\treturn 1 - erx - P / Q;\n}\n\nstatic long double erfc2(uint32_t ix, long double x)\n{\n\tunion ldshape u;\n\tlong double s,z,R,S;\n\n\tif (ix < 0x3fffa000)  /* 0.84375 <= |x| < 1.25 */\n\t\treturn erfc1(x);\n\n\tx = fabsl(x);\n\ts = 1 / (x * x);\n\tif (ix < 0x4000b6db) {  /* 1.25 <= |x| < 2.857 ~ 1/.35 */\n\t\tR = ra[0] + s * (ra[1] + s * (ra[2] + s * (ra[3] + s * (ra[4] +\n\t\t     s * (ra[5] + s * (ra[6] + s * (ra[7] + s * ra[8])))))));\n\t\tS = sa[0] + s * (sa[1] + s * (sa[2] + s * (sa[3] + s * (sa[4] +\n\t\t     s * (sa[5] + s * (sa[6] + s * (sa[7] + s * (sa[8] + s))))))));\n\t} else if (ix < 0x4001d555) {  /* 2.857 <= |x| < 6.6666259765625 */\n\t\tR = rb[0] + s * (rb[1] + s * (rb[2] + s * (rb[3] + s * (rb[4] +\n\t\t     s * (rb[5] + s * (rb[6] + s * rb[7]))))));\n\t\tS = sb[0] + s * (sb[1] + s * (sb[2] + s * (sb[3] + s * (sb[4] +\n\t\t     s * (sb[5] + s * (sb[6] + s))))));\n\t} else { /* 6.666 <= |x| < 107 (erfc only) */\n\t\tR = rc[0] + s * (rc[1] + s * (rc[2] + s * (rc[3] +\n\t\t     s * (rc[4] + s * rc[5]))));\n\t\tS = sc[0] + s * (sc[1] + s * (sc[2] + s * (sc[3] +\n\t\t     s * (sc[4] + s))));\n\t}\n\tu.f = x;\n\tu.i.m &= -1ULL << 40;\n\tz = u.f;\n\treturn expl(-z*z - 0.5625) * expl((z - x) * (z + x) + R / S) / x;\n}\n\nlong double erfl(long double x)\n{\n\tlong double r, s, z, y;\n\tunion ldshape u = {x};\n\tuint32_t ix = (u.i.se & 0x7fffU)<<16 | u.i.m>>48;\n\tint sign = u.i.se >> 15;\n\n\tif (ix >= 0x7fff0000)\n\t\t/* erf(nan)=nan, erf(+-inf)=+-1 */\n\t\treturn 1 - 2*sign + 1/x;\n\tif (ix < 0x3ffed800) {  /* |x| < 0.84375 */\n\t\tif (ix < 0x3fde8000) {  /* |x| < 2**-33 */\n\t\t\treturn 0.125 * (8 * x + efx8 * x);  /* avoid underflow */\n\t\t}\n\t\tz = x * x;\n\t\tr = pp[0] + z * (pp[1] +\n\t\t     z * (pp[2] + z * (pp[3] + z * (pp[4] + z * pp[5]))));\n\t\ts = qq[0] + z * (qq[1] +\n\t\t     z * (qq[2] + z * (qq[3] + z * (qq[4] + z * (qq[5] + z)))));\n\t\ty = r / s;\n\t\treturn x + x * y;\n\t}\n\tif (ix < 0x4001d555)  /* |x| < 6.6666259765625 */\n\t\ty = 1 - erfc2(ix,x);\n\telse\n\t\ty = 1 - 0x1p-16382L;\n\treturn sign ? -y : y;\n}\n\nlong double erfcl(long double x)\n{\n\tlong double r, s, z, y;\n\tunion ldshape u = {x};\n\tuint32_t ix = (u.i.se & 0x7fffU)<<16 | u.i.m>>48;\n\tint sign = u.i.se >> 15;\n\n\tif (ix >= 0x7fff0000)\n\t\t/* erfc(nan) = nan, erfc(+-inf) = 0,2 */\n\t\treturn 2*sign + 1/x;\n\tif (ix < 0x3ffed800) {  /* |x| < 0.84375 */\n\t\tif (ix < 0x3fbe0000)  /* |x| < 2**-65 */\n\t\t\treturn 1.0 - x;\n\t\tz = x * x;\n\t\tr = pp[0] + z * (pp[1] +\n\t\t     z * (pp[2] + z * (pp[3] + z * (pp[4] + z * pp[5]))));\n\t\ts = qq[0] + z * (qq[1] +\n\t\t     z * (qq[2] + z * (qq[3] + z * (qq[4] + z * (qq[5] + z)))));\n\t\ty = r / s;\n\t\tif (ix < 0x3ffd8000) /* x < 1/4 */\n\t\t\treturn 1.0 - (x + x * y);\n\t\treturn 0.5 - (x - 0.5 + x * y);\n\t}\n\tif (ix < 0x4005d600)  /* |x| < 107 */\n\t\treturn sign ? 2 - erfc2(ix,x) : erfc2(ix,x);\n\ty = 0x1p-16382L;\n\treturn sign ? 2 - y : y*y;\n}\n#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384\n// TODO: broken implementation to make things compile\nlong double erfl(long double x)\n{\n\treturn erf(x);\n}\nlong double erfcl(long double x)\n{\n\treturn erfc(x);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/exp.c",
    "content": "/*\n * Double-precision e^x function.\n *\n * Copyright (c) 2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n\n#include <math.h>\n#include <stdint.h>\n#include \"libm.h\"\n#include \"exp_data.h\"\n\n#define N (1 << EXP_TABLE_BITS)\n#define InvLn2N __exp_data.invln2N\n#define NegLn2hiN __exp_data.negln2hiN\n#define NegLn2loN __exp_data.negln2loN\n#define Shift __exp_data.shift\n#define T __exp_data.tab\n#define C2 __exp_data.poly[5 - EXP_POLY_ORDER]\n#define C3 __exp_data.poly[6 - EXP_POLY_ORDER]\n#define C4 __exp_data.poly[7 - EXP_POLY_ORDER]\n#define C5 __exp_data.poly[8 - EXP_POLY_ORDER]\n\n/* Handle cases that may overflow or underflow when computing the result that\n   is scale*(1+TMP) without intermediate rounding.  The bit representation of\n   scale is in SBITS, however it has a computed exponent that may have\n   overflown into the sign bit so that needs to be adjusted before using it as\n   a double.  (int32_t)KI is the k used in the argument reduction and exponent\n   adjustment of scale, positive k here means the result may overflow and\n   negative k means the result may underflow.  */\nstatic inline double specialcase(double_t tmp, uint64_t sbits, uint64_t ki)\n{\n\tdouble_t scale, y;\n\n\tif ((ki & 0x80000000) == 0) {\n\t\t/* k > 0, the exponent of scale might have overflowed by <= 460.  */\n\t\tsbits -= 1009ull << 52;\n\t\tscale = asdouble(sbits);\n\t\ty = 0x1p1009 * (scale + scale * tmp);\n\t\treturn eval_as_double(y);\n\t}\n\t/* k < 0, need special care in the subnormal range.  */\n\tsbits += 1022ull << 52;\n\tscale = asdouble(sbits);\n\ty = scale + scale * tmp;\n\tif (y < 1.0) {\n\t\t/* Round y to the right precision before scaling it into the subnormal\n\t\t range to avoid double rounding that can cause 0.5+E/2 ulp error where\n\t\t E is the worst-case ulp error outside the subnormal range.  So this\n\t\t is only useful if the goal is better than 1 ulp worst-case error.  */\n\t\tdouble_t hi, lo;\n\t\tlo = scale - y + scale * tmp;\n\t\thi = 1.0 + y;\n\t\tlo = 1.0 - hi + y + lo;\n\t\ty = eval_as_double(hi + lo) - 1.0;\n\t\t/* Avoid -0.0 with downward rounding.  */\n\t\tif (WANT_ROUNDING && y == 0.0)\n\t\t\ty = 0.0;\n\t\t/* The underflow exception needs to be signaled explicitly.  */\n\t\tfp_force_eval(fp_barrier(0x1p-1022) * 0x1p-1022);\n\t}\n\ty = 0x1p-1022 * y;\n\treturn eval_as_double(y);\n}\n\n/* Top 12 bits of a double (sign and exponent bits).  */\nstatic inline uint32_t top12(double x)\n{\n\treturn asuint64(x) >> 52;\n}\n\ndouble exp(double x)\n{\n\tuint32_t abstop;\n\tuint64_t ki, idx, top, sbits;\n\tdouble_t kd, z, r, r2, scale, tail, tmp;\n\n\tabstop = top12(x) & 0x7ff;\n\tif (predict_false(abstop - top12(0x1p-54) >= top12(512.0) - top12(0x1p-54))) {\n\t\tif (abstop - top12(0x1p-54) >= 0x80000000)\n\t\t\t/* Avoid spurious underflow for tiny x.  */\n\t\t\t/* Note: 0 is common input.  */\n\t\t\treturn WANT_ROUNDING ? 1.0 + x : 1.0;\n\t\tif (abstop >= top12(1024.0)) {\n\t\t\tif (asuint64(x) == asuint64(-INFINITY))\n\t\t\t\treturn 0.0;\n\t\t\tif (abstop >= top12(INFINITY))\n\t\t\t\treturn 1.0 + x;\n\t\t\tif (asuint64(x) >> 63)\n\t\t\t\treturn __math_uflow(0);\n\t\t\telse\n\t\t\t\treturn __math_oflow(0);\n\t\t}\n\t\t/* Large x is special cased below.  */\n\t\tabstop = 0;\n\t}\n\n\t/* exp(x) = 2^(k/N) * exp(r), with exp(r) in [2^(-1/2N),2^(1/2N)].  */\n\t/* x = ln2/N*k + r, with int k and r in [-ln2/2N, ln2/2N].  */\n\tz = InvLn2N * x;\n#if TOINT_INTRINSICS\n\tkd = roundtoint(z);\n\tki = converttoint(z);\n#elif EXP_USE_TOINT_NARROW\n\t/* z - kd is in [-0.5-2^-16, 0.5] in all rounding modes.  */\n\tkd = eval_as_double(z + Shift);\n\tki = asuint64(kd) >> 16;\n\tkd = (double_t)(int32_t)ki;\n#else\n\t/* z - kd is in [-1, 1] in non-nearest rounding modes.  */\n\tkd = eval_as_double(z + Shift);\n\tki = asuint64(kd);\n\tkd -= Shift;\n#endif\n\tr = x + kd * NegLn2hiN + kd * NegLn2loN;\n\t/* 2^(k/N) ~= scale * (1 + tail).  */\n\tidx = 2 * (ki % N);\n\ttop = ki << (52 - EXP_TABLE_BITS);\n\ttail = asdouble(T[idx]);\n\t/* This is only a valid scale when -1023*N < k < 1024*N.  */\n\tsbits = T[idx + 1] + top;\n\t/* exp(x) = 2^(k/N) * exp(r) ~= scale + scale * (tail + exp(r) - 1).  */\n\t/* Evaluation is optimized assuming superscalar pipelined execution.  */\n\tr2 = r * r;\n\t/* Without fma the worst case error is 0.25/N ulp larger.  */\n\t/* Worst case error is less than 0.5+1.11/N+(abs poly error * 2^53) ulp.  */\n\ttmp = tail + r + r2 * (C2 + r * C3) + r2 * r2 * (C4 + r * C5);\n\tif (predict_false(abstop == 0))\n\t\treturn specialcase(tmp, sbits, ki);\n\tscale = asdouble(sbits);\n\t/* Note: tmp == 0 or |tmp| > 2^-200 and scale > 2^-739, so there\n\t   is no spurious underflow here even without fma.  */\n\treturn eval_as_double(scale + scale * tmp);\n}\n"
  },
  {
    "path": "user.libc/src/math/exp10.c",
    "content": "#define _GNU_SOURCE\n#include <math.h>\n#include <stdint.h>\n\ndouble exp10(double x)\n{\n\tstatic const double p10[] = {\n\t\t1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10,\n\t\t1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1,\n\t\t1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,\n\t\t1e10, 1e11, 1e12, 1e13, 1e14, 1e15\n\t};\n\tdouble n, y = modf(x, &n);\n\tunion {double f; uint64_t i;} u = {n};\n\t/* fabs(n) < 16 without raising invalid on nan */\n\tif ((u.i>>52 & 0x7ff) < 0x3ff+4) {\n\t\tif (!y) return p10[(int)n+15];\n\t\ty = exp2(3.32192809488736234787031942948939 * y);\n\t\treturn y * p10[(int)n+15];\n\t}\n\treturn pow(10.0, x);\n}\n\nweak_alias(exp10, pow10);\n"
  },
  {
    "path": "user.libc/src/math/exp10f.c",
    "content": "#define _GNU_SOURCE\n#include <math.h>\n#include <stdint.h>\n\nfloat exp10f(float x)\n{\n\tstatic const float p10[] = {\n\t\t1e-7f, 1e-6f, 1e-5f, 1e-4f, 1e-3f, 1e-2f, 1e-1f,\n\t\t1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7\n\t};\n\tfloat n, y = modff(x, &n);\n\tunion {float f; uint32_t i;} u = {n};\n\t/* fabsf(n) < 8 without raising invalid on nan */\n\tif ((u.i>>23 & 0xff) < 0x7f+3) {\n\t\tif (!y) return p10[(int)n+7];\n\t\ty = exp2f(3.32192809488736234787031942948939f * y);\n\t\treturn y * p10[(int)n+7];\n\t}\n\treturn exp2(3.32192809488736234787031942948939 * x);\n}\n\nweak_alias(exp10f, pow10f);\n"
  },
  {
    "path": "user.libc/src/math/exp10l.c",
    "content": "#define _GNU_SOURCE\n#include <float.h>\n#include <math.h>\n#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double exp10l(long double x)\n{\n\treturn exp10(x);\n}\n#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\nlong double exp10l(long double x)\n{\n\tstatic const long double p10[] = {\n\t\t1e-15L, 1e-14L, 1e-13L, 1e-12L, 1e-11L, 1e-10L,\n\t\t1e-9L, 1e-8L, 1e-7L, 1e-6L, 1e-5L, 1e-4L, 1e-3L, 1e-2L, 1e-1L,\n\t\t1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,\n\t\t1e10, 1e11, 1e12, 1e13, 1e14, 1e15\n\t};\n\tlong double n, y = modfl(x, &n);\n\tunion ldshape u = {n};\n\t/* fabsl(n) < 16 without raising invalid on nan */\n\tif ((u.i.se & 0x7fff) < 0x3fff+4) {\n\t\tif (!y) return p10[(int)n+15];\n\t\ty = exp2l(3.32192809488736234787031942948939L * y);\n\t\treturn y * p10[(int)n+15];\n\t}\n\treturn powl(10.0, x);\n}\n#endif\n\nweak_alias(exp10l, pow10l);\n"
  },
  {
    "path": "user.libc/src/math/exp2.c",
    "content": "/*\n * Double-precision 2^x function.\n *\n * Copyright (c) 2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n\n#include <math.h>\n#include <stdint.h>\n#include \"libm.h\"\n#include \"exp_data.h\"\n\n#define N (1 << EXP_TABLE_BITS)\n#define Shift __exp_data.exp2_shift\n#define T __exp_data.tab\n#define C1 __exp_data.exp2_poly[0]\n#define C2 __exp_data.exp2_poly[1]\n#define C3 __exp_data.exp2_poly[2]\n#define C4 __exp_data.exp2_poly[3]\n#define C5 __exp_data.exp2_poly[4]\n\n/* Handle cases that may overflow or underflow when computing the result that\n   is scale*(1+TMP) without intermediate rounding.  The bit representation of\n   scale is in SBITS, however it has a computed exponent that may have\n   overflown into the sign bit so that needs to be adjusted before using it as\n   a double.  (int32_t)KI is the k used in the argument reduction and exponent\n   adjustment of scale, positive k here means the result may overflow and\n   negative k means the result may underflow.  */\nstatic inline double specialcase(double_t tmp, uint64_t sbits, uint64_t ki)\n{\n\tdouble_t scale, y;\n\n\tif ((ki & 0x80000000) == 0) {\n\t\t/* k > 0, the exponent of scale might have overflowed by 1.  */\n\t\tsbits -= 1ull << 52;\n\t\tscale = asdouble(sbits);\n\t\ty = 2 * (scale + scale * tmp);\n\t\treturn eval_as_double(y);\n\t}\n\t/* k < 0, need special care in the subnormal range.  */\n\tsbits += 1022ull << 52;\n\tscale = asdouble(sbits);\n\ty = scale + scale * tmp;\n\tif (y < 1.0) {\n\t\t/* Round y to the right precision before scaling it into the subnormal\n\t\t   range to avoid double rounding that can cause 0.5+E/2 ulp error where\n\t\t   E is the worst-case ulp error outside the subnormal range.  So this\n\t\t   is only useful if the goal is better than 1 ulp worst-case error.  */\n\t\tdouble_t hi, lo;\n\t\tlo = scale - y + scale * tmp;\n\t\thi = 1.0 + y;\n\t\tlo = 1.0 - hi + y + lo;\n\t\ty = eval_as_double(hi + lo) - 1.0;\n\t\t/* Avoid -0.0 with downward rounding.  */\n\t\tif (WANT_ROUNDING && y == 0.0)\n\t\t\ty = 0.0;\n\t\t/* The underflow exception needs to be signaled explicitly.  */\n\t\tfp_force_eval(fp_barrier(0x1p-1022) * 0x1p-1022);\n\t}\n\ty = 0x1p-1022 * y;\n\treturn eval_as_double(y);\n}\n\n/* Top 12 bits of a double (sign and exponent bits).  */\nstatic inline uint32_t top12(double x)\n{\n\treturn asuint64(x) >> 52;\n}\n\ndouble exp2(double x)\n{\n\tuint32_t abstop;\n\tuint64_t ki, idx, top, sbits;\n\tdouble_t kd, r, r2, scale, tail, tmp;\n\n\tabstop = top12(x) & 0x7ff;\n\tif (predict_false(abstop - top12(0x1p-54) >= top12(512.0) - top12(0x1p-54))) {\n\t\tif (abstop - top12(0x1p-54) >= 0x80000000)\n\t\t\t/* Avoid spurious underflow for tiny x.  */\n\t\t\t/* Note: 0 is common input.  */\n\t\t\treturn WANT_ROUNDING ? 1.0 + x : 1.0;\n\t\tif (abstop >= top12(1024.0)) {\n\t\t\tif (asuint64(x) == asuint64(-INFINITY))\n\t\t\t\treturn 0.0;\n\t\t\tif (abstop >= top12(INFINITY))\n\t\t\t\treturn 1.0 + x;\n\t\t\tif (!(asuint64(x) >> 63))\n\t\t\t\treturn __math_oflow(0);\n\t\t\telse if (asuint64(x) >= asuint64(-1075.0))\n\t\t\t\treturn __math_uflow(0);\n\t\t}\n\t\tif (2 * asuint64(x) > 2 * asuint64(928.0))\n\t\t\t/* Large x is special cased below.  */\n\t\t\tabstop = 0;\n\t}\n\n\t/* exp2(x) = 2^(k/N) * 2^r, with 2^r in [2^(-1/2N),2^(1/2N)].  */\n\t/* x = k/N + r, with int k and r in [-1/2N, 1/2N].  */\n\tkd = eval_as_double(x + Shift);\n\tki = asuint64(kd); /* k.  */\n\tkd -= Shift; /* k/N for int k.  */\n\tr = x - kd;\n\t/* 2^(k/N) ~= scale * (1 + tail).  */\n\tidx = 2 * (ki % N);\n\ttop = ki << (52 - EXP_TABLE_BITS);\n\ttail = asdouble(T[idx]);\n\t/* This is only a valid scale when -1023*N < k < 1024*N.  */\n\tsbits = T[idx + 1] + top;\n\t/* exp2(x) = 2^(k/N) * 2^r ~= scale + scale * (tail + 2^r - 1).  */\n\t/* Evaluation is optimized assuming superscalar pipelined execution.  */\n\tr2 = r * r;\n\t/* Without fma the worst case error is 0.5/N ulp larger.  */\n\t/* Worst case error is less than 0.5+0.86/N+(abs poly error * 2^53) ulp.  */\n\ttmp = tail + r * C1 + r2 * (C2 + r * C3) + r2 * r2 * (C4 + r * C5);\n\tif (predict_false(abstop == 0))\n\t\treturn specialcase(tmp, sbits, ki);\n\tscale = asdouble(sbits);\n\t/* Note: tmp == 0 or |tmp| > 2^-65 and scale > 2^-928, so there\n\t   is no spurious underflow here even without fma.  */\n\treturn eval_as_double(scale + scale * tmp);\n}\n"
  },
  {
    "path": "user.libc/src/math/exp2f.c",
    "content": "/*\n * Single-precision 2^x function.\n *\n * Copyright (c) 2017-2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n\n#include <math.h>\n#include <stdint.h>\n#include \"libm.h\"\n#include \"exp2f_data.h\"\n\n/*\nEXP2F_TABLE_BITS = 5\nEXP2F_POLY_ORDER = 3\n\nULP error: 0.502 (nearest rounding.)\nRelative error: 1.69 * 2^-34 in [-1/64, 1/64] (before rounding.)\nWrong count: 168353 (all nearest rounding wrong results with fma.)\nNon-nearest ULP error: 1 (rounded ULP error)\n*/\n\n#define N (1 << EXP2F_TABLE_BITS)\n#define T __exp2f_data.tab\n#define C __exp2f_data.poly\n#define SHIFT __exp2f_data.shift_scaled\n\nstatic inline uint32_t top12(float x)\n{\n\treturn asuint(x) >> 20;\n}\n\nfloat exp2f(float x)\n{\n\tuint32_t abstop;\n\tuint64_t ki, t;\n\tdouble_t kd, xd, z, r, r2, y, s;\n\n\txd = (double_t)x;\n\tabstop = top12(x) & 0x7ff;\n\tif (predict_false(abstop >= top12(128.0f))) {\n\t\t/* |x| >= 128 or x is nan.  */\n\t\tif (asuint(x) == asuint(-INFINITY))\n\t\t\treturn 0.0f;\n\t\tif (abstop >= top12(INFINITY))\n\t\t\treturn x + x;\n\t\tif (x > 0.0f)\n\t\t\treturn __math_oflowf(0);\n\t\tif (x <= -150.0f)\n\t\t\treturn __math_uflowf(0);\n\t}\n\n\t/* x = k/N + r with r in [-1/(2N), 1/(2N)] and int k.  */\n\tkd = eval_as_double(xd + SHIFT);\n\tki = asuint64(kd);\n\tkd -= SHIFT; /* k/N for int k.  */\n\tr = xd - kd;\n\n\t/* exp2(x) = 2^(k/N) * 2^r ~= s * (C0*r^3 + C1*r^2 + C2*r + 1) */\n\tt = T[ki % N];\n\tt += ki << (52 - EXP2F_TABLE_BITS);\n\ts = asdouble(t);\n\tz = C[0] * r + C[1];\n\tr2 = r * r;\n\ty = C[2] * r + 1;\n\ty = z * r2 + y;\n\ty = y * s;\n\treturn eval_as_float(y);\n}\n"
  },
  {
    "path": "user.libc/src/math/exp2f_data.c",
    "content": "/*\n * Shared data between expf, exp2f and powf.\n *\n * Copyright (c) 2017-2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n\n#include \"exp2f_data.h\"\n\n#define N (1 << EXP2F_TABLE_BITS)\n\nconst struct exp2f_data __exp2f_data = {\n  /* tab[i] = uint(2^(i/N)) - (i << 52-BITS)\n     used for computing 2^(k/N) for an int |k| < 150 N as\n     double(tab[k%N] + (k << 52-BITS)) */\n  .tab = {\n0x3ff0000000000000, 0x3fefd9b0d3158574, 0x3fefb5586cf9890f, 0x3fef9301d0125b51,\n0x3fef72b83c7d517b, 0x3fef54873168b9aa, 0x3fef387a6e756238, 0x3fef1e9df51fdee1,\n0x3fef06fe0a31b715, 0x3feef1a7373aa9cb, 0x3feedea64c123422, 0x3feece086061892d,\n0x3feebfdad5362a27, 0x3feeb42b569d4f82, 0x3feeab07dd485429, 0x3feea47eb03a5585,\n0x3feea09e667f3bcd, 0x3fee9f75e8ec5f74, 0x3feea11473eb0187, 0x3feea589994cce13,\n0x3feeace5422aa0db, 0x3feeb737b0cdc5e5, 0x3feec49182a3f090, 0x3feed503b23e255d,\n0x3feee89f995ad3ad, 0x3feeff76f2fb5e47, 0x3fef199bdd85529c, 0x3fef3720dcef9069,\n0x3fef5818dcfba487, 0x3fef7c97337b9b5f, 0x3fefa4afa2a490da, 0x3fefd0765b6e4540,\n  },\n  .shift_scaled = 0x1.8p+52 / N,\n  .poly = {\n  0x1.c6af84b912394p-5, 0x1.ebfce50fac4f3p-3, 0x1.62e42ff0c52d6p-1,\n  },\n  .shift = 0x1.8p+52,\n  .invln2_scaled = 0x1.71547652b82fep+0 * N,\n  .poly_scaled = {\n  0x1.c6af84b912394p-5/N/N/N, 0x1.ebfce50fac4f3p-3/N/N, 0x1.62e42ff0c52d6p-1/N,\n  },\n};\n"
  },
  {
    "path": "user.libc/src/math/exp2f_data.h",
    "content": "/*\n * Copyright (c) 2017-2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n#ifndef _EXP2F_DATA_H\n#define _EXP2F_DATA_H\n\n#include <features.h>\n#include <stdint.h>\n\n/* Shared between expf, exp2f and powf.  */\n#define EXP2F_TABLE_BITS 5\n#define EXP2F_POLY_ORDER 3\nextern hidden const struct exp2f_data {\n\tuint64_t tab[1 << EXP2F_TABLE_BITS];\n\tdouble shift_scaled;\n\tdouble poly[EXP2F_POLY_ORDER];\n\tdouble shift;\n\tdouble invln2_scaled;\n\tdouble poly_scaled[EXP2F_POLY_ORDER];\n} __exp2f_data;\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/exp2l.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/ld80/s_exp2l.c and /usr/src/lib/msun/ld128/s_exp2l.c */\n/*-\n * Copyright (c) 2005-2008 David Schultz <das@FreeBSD.ORG>\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double exp2l(long double x)\n{\n\treturn exp2(x);\n}\n#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384\n#define TBLBITS 7\n#define TBLSIZE (1 << TBLBITS)\n\nstatic const double\nredux = 0x1.8p63 / TBLSIZE,\nP1    = 0x1.62e42fefa39efp-1,\nP2    = 0x1.ebfbdff82c58fp-3,\nP3    = 0x1.c6b08d7049fap-5,\nP4    = 0x1.3b2ab6fba4da5p-7,\nP5    = 0x1.5d8804780a736p-10,\nP6    = 0x1.430918835e33dp-13;\n\nstatic const double tbl[TBLSIZE * 2] = {\n\t0x1.6a09e667f3bcdp-1,   -0x1.bdd3413b2648p-55,\n\t0x1.6c012750bdabfp-1,   -0x1.2895667ff0cp-57,\n\t0x1.6dfb23c651a2fp-1,   -0x1.bbe3a683c88p-58,\n\t0x1.6ff7df9519484p-1,   -0x1.83c0f25860fp-56,\n\t0x1.71f75e8ec5f74p-1,   -0x1.16e4786887bp-56,\n\t0x1.73f9a48a58174p-1,   -0x1.0a8d96c65d5p-55,\n\t0x1.75feb564267c9p-1,   -0x1.0245957316ep-55,\n\t0x1.780694fde5d3fp-1,    0x1.866b80a0216p-55,\n\t0x1.7a11473eb0187p-1,   -0x1.41577ee0499p-56,\n\t0x1.7c1ed0130c132p-1,    0x1.f124cd1164ep-55,\n\t0x1.7e2f336cf4e62p-1,    0x1.05d02ba157ap-57,\n\t0x1.80427543e1a12p-1,   -0x1.27c86626d97p-55,\n\t0x1.82589994cce13p-1,   -0x1.d4c1dd41533p-55,\n\t0x1.8471a4623c7adp-1,   -0x1.8d684a341cep-56,\n\t0x1.868d99b4492edp-1,   -0x1.fc6f89bd4f68p-55,\n\t0x1.88ac7d98a6699p-1,    0x1.994c2f37cb5p-55,\n\t0x1.8ace5422aa0dbp-1,    0x1.6e9f156864bp-55,\n\t0x1.8cf3216b5448cp-1,   -0x1.0d55e32e9e4p-57,\n\t0x1.8f1ae99157736p-1,    0x1.5cc13a2e397p-56,\n\t0x1.9145b0b91ffc6p-1,   -0x1.dd6792e5825p-55,\n\t0x1.93737b0cdc5e5p-1,   -0x1.75fc781b58p-58,\n\t0x1.95a44cbc8520fp-1,   -0x1.64b7c96a5fp-57,\n\t0x1.97d829fde4e5p-1,    -0x1.d185b7c1b86p-55,\n\t0x1.9a0f170ca07bap-1,   -0x1.173bd91cee6p-55,\n\t0x1.9c49182a3f09p-1,     0x1.c7c46b071f2p-57,\n\t0x1.9e86319e32323p-1,    0x1.824ca78e64cp-57,\n\t0x1.a0c667b5de565p-1,   -0x1.359495d1cd5p-55,\n\t0x1.a309bec4a2d33p-1,    0x1.6305c7ddc368p-55,\n\t0x1.a5503b23e255dp-1,   -0x1.d2f6edb8d42p-55,\n\t0x1.a799e1330b358p-1,    0x1.bcb7ecac564p-55,\n\t0x1.a9e6b5579fdbfp-1,    0x1.0fac90ef7fdp-55,\n\t0x1.ac36bbfd3f37ap-1,   -0x1.f9234cae76dp-56,\n\t0x1.ae89f995ad3adp-1,    0x1.7a1cd345dcc8p-55,\n\t0x1.b0e07298db666p-1,   -0x1.bdef54c80e4p-55,\n\t0x1.b33a2b84f15fbp-1,   -0x1.2805e3084d8p-58,\n\t0x1.b59728de5593ap-1,   -0x1.c71dfbbba6ep-55,\n\t0x1.b7f76f2fb5e47p-1,   -0x1.5584f7e54acp-57,\n\t0x1.ba5b030a1064ap-1,   -0x1.efcd30e5429p-55,\n\t0x1.bcc1e904bc1d2p-1,    0x1.23dd07a2d9fp-56,\n\t0x1.bf2c25bd71e09p-1,   -0x1.efdca3f6b9c8p-55,\n\t0x1.c199bdd85529cp-1,    0x1.11065895049p-56,\n\t0x1.c40ab5fffd07ap-1,    0x1.b4537e083c6p-55,\n\t0x1.c67f12e57d14bp-1,    0x1.2884dff483c8p-55,\n\t0x1.c8f6d9406e7b5p-1,    0x1.1acbc48805cp-57,\n\t0x1.cb720dcef9069p-1,    0x1.503cbd1e94ap-57,\n\t0x1.cdf0b555dc3fap-1,   -0x1.dd83b53829dp-56,\n\t0x1.d072d4a07897cp-1,   -0x1.cbc3743797a8p-55,\n\t0x1.d2f87080d89f2p-1,   -0x1.d487b719d858p-55,\n\t0x1.d5818dcfba487p-1,    0x1.2ed02d75b37p-56,\n\t0x1.d80e316c98398p-1,   -0x1.11ec18bedep-55,\n\t0x1.da9e603db3285p-1,    0x1.c2300696db5p-55,\n\t0x1.dd321f301b46p-1,     0x1.2da5778f019p-55,\n\t0x1.dfc97337b9b5fp-1,   -0x1.1a5cd4f184b8p-55,\n\t0x1.e264614f5a129p-1,   -0x1.7b627817a148p-55,\n\t0x1.e502ee78b3ff6p-1,    0x1.39e8980a9cdp-56,\n\t0x1.e7a51fbc74c83p-1,    0x1.2d522ca0c8ep-55,\n\t0x1.ea4afa2a490dap-1,   -0x1.e9c23179c288p-55,\n\t0x1.ecf482d8e67f1p-1,   -0x1.c93f3b411ad8p-55,\n\t0x1.efa1bee615a27p-1,    0x1.dc7f486a4b68p-55,\n\t0x1.f252b376bba97p-1,    0x1.3a1a5bf0d8e8p-55,\n\t0x1.f50765b6e454p-1,     0x1.9d3e12dd8a18p-55,\n\t0x1.f7bfdad9cbe14p-1,   -0x1.dbb12d00635p-55,\n\t0x1.fa7c1819e90d8p-1,    0x1.74853f3a593p-56,\n\t0x1.fd3c22b8f71f1p-1,    0x1.2eb74966578p-58,\n\t0x1p+0,                  0x0p+0,\n\t0x1.0163da9fb3335p+0,    0x1.b61299ab8cd8p-54,\n\t0x1.02c9a3e778061p+0,   -0x1.19083535b08p-56,\n\t0x1.04315e86e7f85p+0,   -0x1.0a31c1977c98p-54,\n\t0x1.059b0d3158574p+0,    0x1.d73e2a475b4p-55,\n\t0x1.0706b29ddf6dep+0,   -0x1.c91dfe2b13cp-55,\n\t0x1.0874518759bc8p+0,    0x1.186be4bb284p-57,\n\t0x1.09e3ecac6f383p+0,    0x1.14878183161p-54,\n\t0x1.0b5586cf9890fp+0,    0x1.8a62e4adc61p-54,\n\t0x1.0cc922b7247f7p+0,    0x1.01edc16e24f8p-54,\n\t0x1.0e3ec32d3d1a2p+0,    0x1.03a1727c58p-59,\n\t0x1.0fb66affed31bp+0,   -0x1.b9bedc44ebcp-57,\n\t0x1.11301d0125b51p+0,   -0x1.6c51039449bp-54,\n\t0x1.12abdc06c31ccp+0,   -0x1.1b514b36ca8p-58,\n\t0x1.1429aaea92dep+0,    -0x1.32fbf9af1368p-54,\n\t0x1.15a98c8a58e51p+0,    0x1.2406ab9eeabp-55,\n\t0x1.172b83c7d517bp+0,   -0x1.19041b9d78ap-55,\n\t0x1.18af9388c8deap+0,   -0x1.11023d1970f8p-54,\n\t0x1.1a35beb6fcb75p+0,    0x1.e5b4c7b4969p-55,\n\t0x1.1bbe084045cd4p+0,   -0x1.95386352ef6p-54,\n\t0x1.1d4873168b9aap+0,    0x1.e016e00a264p-54,\n\t0x1.1ed5022fcd91dp+0,   -0x1.1df98027bb78p-54,\n\t0x1.2063b88628cd6p+0,    0x1.dc775814a85p-55,\n\t0x1.21f49917ddc96p+0,    0x1.2a97e9494a6p-55,\n\t0x1.2387a6e756238p+0,    0x1.9b07eb6c7058p-54,\n\t0x1.251ce4fb2a63fp+0,    0x1.ac155bef4f5p-55,\n\t0x1.26b4565e27cddp+0,    0x1.2bd339940eap-55,\n\t0x1.284dfe1f56381p+0,   -0x1.a4c3a8c3f0d8p-54,\n\t0x1.29e9df51fdee1p+0,    0x1.612e8afad12p-55,\n\t0x1.2b87fd0dad99p+0,    -0x1.10adcd6382p-59,\n\t0x1.2d285a6e4030bp+0,    0x1.0024754db42p-54,\n\t0x1.2ecafa93e2f56p+0,    0x1.1ca0f45d524p-56,\n\t0x1.306fe0a31b715p+0,    0x1.6f46ad23183p-55,\n\t0x1.32170fc4cd831p+0,    0x1.a9ce78e1804p-55,\n\t0x1.33c08b26416ffp+0,    0x1.327218436598p-54,\n\t0x1.356c55f929ff1p+0,   -0x1.b5cee5c4e46p-55,\n\t0x1.371a7373aa9cbp+0,   -0x1.63aeabf42ebp-54,\n\t0x1.38cae6d05d866p+0,   -0x1.e958d3c99048p-54,\n\t0x1.3a7db34e59ff7p+0,   -0x1.5e436d661f6p-56,\n\t0x1.3c32dc313a8e5p+0,   -0x1.efff8375d2ap-54,\n\t0x1.3dea64c123422p+0,    0x1.ada0911f09fp-55,\n\t0x1.3fa4504ac801cp+0,   -0x1.7d023f956fap-54,\n\t0x1.4160a21f72e2ap+0,   -0x1.ef3691c309p-58,\n\t0x1.431f5d950a897p+0,   -0x1.1c7dde35f7ap-55,\n\t0x1.44e086061892dp+0,    0x1.89b7a04ef8p-59,\n\t0x1.46a41ed1d0057p+0,    0x1.c944bd1648a8p-54,\n\t0x1.486a2b5c13cdp+0,     0x1.3c1a3b69062p-56,\n\t0x1.4a32af0d7d3dep+0,    0x1.9cb62f3d1be8p-54,\n\t0x1.4bfdad5362a27p+0,    0x1.d4397afec42p-56,\n\t0x1.4dcb299fddd0dp+0,    0x1.8ecdbbc6a78p-54,\n\t0x1.4f9b2769d2ca7p+0,   -0x1.4b309d25958p-54,\n\t0x1.516daa2cf6642p+0,   -0x1.f768569bd94p-55,\n\t0x1.5342b569d4f82p+0,   -0x1.07abe1db13dp-55,\n\t0x1.551a4ca5d920fp+0,   -0x1.d689cefede6p-55,\n\t0x1.56f4736b527dap+0,    0x1.9bb2c011d938p-54,\n\t0x1.58d12d497c7fdp+0,    0x1.295e15b9a1ep-55,\n\t0x1.5ab07dd485429p+0,    0x1.6324c0546478p-54,\n\t0x1.5c9268a5946b7p+0,    0x1.c4b1b81698p-60,\n\t0x1.5e76f15ad2148p+0,    0x1.ba6f93080e68p-54,\n\t0x1.605e1b976dc09p+0,   -0x1.3e2429b56de8p-54,\n\t0x1.6247eb03a5585p+0,   -0x1.383c17e40b48p-54,\n\t0x1.6434634ccc32p+0,    -0x1.c483c759d89p-55,\n\t0x1.6623882552225p+0,   -0x1.bb60987591cp-54,\n\t0x1.68155d44ca973p+0,    0x1.038ae44f74p-57,\n};\n\n/*\n * exp2l(x): compute the base 2 exponential of x\n *\n * Accuracy: Peak error < 0.511 ulp.\n *\n * Method: (equally-spaced tables)\n *\n *   Reduce x:\n *     x = 2**k + y, for integer k and |y| <= 1/2.\n *     Thus we have exp2l(x) = 2**k * exp2(y).\n *\n *   Reduce y:\n *     y = i/TBLSIZE + z for integer i near y * TBLSIZE.\n *     Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z),\n *     with |z| <= 2**-(TBLBITS+1).\n *\n *   We compute exp2(i/TBLSIZE) via table lookup and exp2(z) via a\n *   degree-6 minimax polynomial with maximum error under 2**-69.\n *   The table entries each have 104 bits of accuracy, encoded as\n *   a pair of double precision values.\n */\nlong double exp2l(long double x)\n{\n\tunion ldshape u = {x};\n\tint e = u.i.se & 0x7fff;\n\tlong double r, z;\n\tuint32_t i0;\n\tunion {uint32_t u; int32_t i;} k;\n\n\t/* Filter out exceptional cases. */\n\tif (e >= 0x3fff + 13) {  /* |x| >= 8192 or x is NaN */\n\t\tif (u.i.se >= 0x3fff + 14 && u.i.se >> 15 == 0)\n\t\t\t/* overflow */\n\t\t\treturn x * 0x1p16383L;\n\t\tif (e == 0x7fff)  /* -inf or -nan */\n\t\t\treturn -1/x;\n\t\tif (x < -16382) {\n\t\t\tif (x <= -16446 || x - 0x1p63 + 0x1p63 != x)\n\t\t\t\t/* underflow */\n\t\t\t\tFORCE_EVAL((float)(-0x1p-149/x));\n\t\t\tif (x <= -16446)\n\t\t\t\treturn 0;\n\t\t}\n\t} else if (e < 0x3fff - 64) {\n\t\treturn 1 + x;\n\t}\n\n\t/*\n\t * Reduce x, computing z, i0, and k. The low bits of x + redux\n\t * contain the 16-bit integer part of the exponent (k) followed by\n\t * TBLBITS fractional bits (i0). We use bit tricks to extract these\n\t * as integers, then set z to the remainder.\n\t *\n\t * Example: Suppose x is 0xabc.123456p0 and TBLBITS is 8.\n\t * Then the low-order word of x + redux is 0x000abc12,\n\t * We split this into k = 0xabc and i0 = 0x12 (adjusted to\n\t * index into the table), then we compute z = 0x0.003456p0.\n\t */\n\tu.f = x + redux;\n\ti0 = u.i.m + TBLSIZE / 2;\n\tk.u = i0 / TBLSIZE * TBLSIZE;\n\tk.i /= TBLSIZE;\n\ti0 %= TBLSIZE;\n\tu.f -= redux;\n\tz = x - u.f;\n\n\t/* Compute r = exp2l(y) = exp2lt[i0] * p(z). */\n\tlong double t_hi = tbl[2*i0];\n\tlong double t_lo = tbl[2*i0 + 1];\n\t/* XXX This gives > 1 ulp errors outside of FE_TONEAREST mode */\n\tr = t_lo + (t_hi + t_lo) * z * (P1 + z * (P2 + z * (P3 + z * (P4\n\t     + z * (P5 + z * P6))))) + t_hi;\n\n\treturn scalbnl(r, k.i);\n}\n#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384\n#define TBLBITS 7\n#define TBLSIZE (1 << TBLBITS)\n\nstatic const long double\n    P1        = 0x1.62e42fefa39ef35793c7673007e6p-1L,\n    P2        = 0x1.ebfbdff82c58ea86f16b06ec9736p-3L,\n    P3        = 0x1.c6b08d704a0bf8b33a762bad3459p-5L,\n    P4        = 0x1.3b2ab6fba4e7729ccbbe0b4f3fc2p-7L,\n    P5        = 0x1.5d87fe78a67311071dee13fd11d9p-10L,\n    P6        = 0x1.430912f86c7876f4b663b23c5fe5p-13L;\n\nstatic const double\n    P7        = 0x1.ffcbfc588b041p-17,\n    P8        = 0x1.62c0223a5c7c7p-20,\n    P9        = 0x1.b52541ff59713p-24,\n    P10       = 0x1.e4cf56a391e22p-28,\n    redux     = 0x1.8p112 / TBLSIZE;\n\nstatic const long double tbl[TBLSIZE] = {\n\t0x1.6a09e667f3bcc908b2fb1366dfeap-1L,\n\t0x1.6c012750bdabeed76a99800f4edep-1L,\n\t0x1.6dfb23c651a2ef220e2cbe1bc0d4p-1L,\n\t0x1.6ff7df9519483cf87e1b4f3e1e98p-1L,\n\t0x1.71f75e8ec5f73dd2370f2ef0b148p-1L,\n\t0x1.73f9a48a58173bd5c9a4e68ab074p-1L,\n\t0x1.75feb564267c8bf6e9aa33a489a8p-1L,\n\t0x1.780694fde5d3f619ae02808592a4p-1L,\n\t0x1.7a11473eb0186d7d51023f6ccb1ap-1L,\n\t0x1.7c1ed0130c1327c49334459378dep-1L,\n\t0x1.7e2f336cf4e62105d02ba1579756p-1L,\n\t0x1.80427543e1a11b60de67649a3842p-1L,\n\t0x1.82589994cce128acf88afab34928p-1L,\n\t0x1.8471a4623c7acce52f6b97c6444cp-1L,\n\t0x1.868d99b4492ec80e41d90ac2556ap-1L,\n\t0x1.88ac7d98a669966530bcdf2d4cc0p-1L,\n\t0x1.8ace5422aa0db5ba7c55a192c648p-1L,\n\t0x1.8cf3216b5448bef2aa1cd161c57ap-1L,\n\t0x1.8f1ae991577362b982745c72eddap-1L,\n\t0x1.9145b0b91ffc588a61b469f6b6a0p-1L,\n\t0x1.93737b0cdc5e4f4501c3f2540ae8p-1L,\n\t0x1.95a44cbc8520ee9b483695a0e7fep-1L,\n\t0x1.97d829fde4e4f8b9e920f91e8eb6p-1L,\n\t0x1.9a0f170ca07b9ba3109b8c467844p-1L,\n\t0x1.9c49182a3f0901c7c46b071f28dep-1L,\n\t0x1.9e86319e323231824ca78e64c462p-1L,\n\t0x1.a0c667b5de564b29ada8b8cabbacp-1L,\n\t0x1.a309bec4a2d3358c171f770db1f4p-1L,\n\t0x1.a5503b23e255c8b424491caf88ccp-1L,\n\t0x1.a799e1330b3586f2dfb2b158f31ep-1L,\n\t0x1.a9e6b5579fdbf43eb243bdff53a2p-1L,\n\t0x1.ac36bbfd3f379c0db966a3126988p-1L,\n\t0x1.ae89f995ad3ad5e8734d17731c80p-1L,\n\t0x1.b0e07298db66590842acdfc6fb4ep-1L,\n\t0x1.b33a2b84f15faf6bfd0e7bd941b0p-1L,\n\t0x1.b59728de559398e3881111648738p-1L,\n\t0x1.b7f76f2fb5e46eaa7b081ab53ff6p-1L,\n\t0x1.ba5b030a10649840cb3c6af5b74cp-1L,\n\t0x1.bcc1e904bc1d2247ba0f45b3d06cp-1L,\n\t0x1.bf2c25bd71e088408d7025190cd0p-1L,\n\t0x1.c199bdd85529c2220cb12a0916bap-1L,\n\t0x1.c40ab5fffd07a6d14df820f17deap-1L,\n\t0x1.c67f12e57d14b4a2137fd20f2a26p-1L,\n\t0x1.c8f6d9406e7b511acbc48805c3f6p-1L,\n\t0x1.cb720dcef90691503cbd1e949d0ap-1L,\n\t0x1.cdf0b555dc3f9c44f8958fac4f12p-1L,\n\t0x1.d072d4a07897b8d0f22f21a13792p-1L,\n\t0x1.d2f87080d89f18ade123989ea50ep-1L,\n\t0x1.d5818dcfba48725da05aeb66dff8p-1L,\n\t0x1.d80e316c98397bb84f9d048807a0p-1L,\n\t0x1.da9e603db3285708c01a5b6d480cp-1L,\n\t0x1.dd321f301b4604b695de3c0630c0p-1L,\n\t0x1.dfc97337b9b5eb968cac39ed284cp-1L,\n\t0x1.e264614f5a128a12761fa17adc74p-1L,\n\t0x1.e502ee78b3ff6273d130153992d0p-1L,\n\t0x1.e7a51fbc74c834b548b2832378a4p-1L,\n\t0x1.ea4afa2a490d9858f73a18f5dab4p-1L,\n\t0x1.ecf482d8e67f08db0312fb949d50p-1L,\n\t0x1.efa1bee615a27771fd21a92dabb6p-1L,\n\t0x1.f252b376bba974e8696fc3638f24p-1L,\n\t0x1.f50765b6e4540674f84b762861a6p-1L,\n\t0x1.f7bfdad9cbe138913b4bfe72bd78p-1L,\n\t0x1.fa7c1819e90d82e90a7e74b26360p-1L,\n\t0x1.fd3c22b8f71f10975ba4b32bd006p-1L,\n\t0x1.0000000000000000000000000000p+0L,\n\t0x1.0163da9fb33356d84a66ae336e98p+0L,\n\t0x1.02c9a3e778060ee6f7caca4f7a18p+0L,\n\t0x1.04315e86e7f84bd738f9a20da442p+0L,\n\t0x1.059b0d31585743ae7c548eb68c6ap+0L,\n\t0x1.0706b29ddf6ddc6dc403a9d87b1ep+0L,\n\t0x1.0874518759bc808c35f25d942856p+0L,\n\t0x1.09e3ecac6f3834521e060c584d5cp+0L,\n\t0x1.0b5586cf9890f6298b92b7184200p+0L,\n\t0x1.0cc922b7247f7407b705b893dbdep+0L,\n\t0x1.0e3ec32d3d1a2020742e4f8af794p+0L,\n\t0x1.0fb66affed31af232091dd8a169ep+0L,\n\t0x1.11301d0125b50a4ebbf1aed9321cp+0L,\n\t0x1.12abdc06c31cbfb92bad324d6f84p+0L,\n\t0x1.1429aaea92ddfb34101943b2588ep+0L,\n\t0x1.15a98c8a58e512480d573dd562aep+0L,\n\t0x1.172b83c7d517adcdf7c8c50eb162p+0L,\n\t0x1.18af9388c8de9bbbf70b9a3c269cp+0L,\n\t0x1.1a35beb6fcb753cb698f692d2038p+0L,\n\t0x1.1bbe084045cd39ab1e72b442810ep+0L,\n\t0x1.1d4873168b9aa7805b8028990be8p+0L,\n\t0x1.1ed5022fcd91cb8819ff61121fbep+0L,\n\t0x1.2063b88628cd63b8eeb0295093f6p+0L,\n\t0x1.21f49917ddc962552fd29294bc20p+0L,\n\t0x1.2387a6e75623866c1fadb1c159c0p+0L,\n\t0x1.251ce4fb2a63f3582ab7de9e9562p+0L,\n\t0x1.26b4565e27cdd257a673281d3068p+0L,\n\t0x1.284dfe1f5638096cf15cf03c9fa0p+0L,\n\t0x1.29e9df51fdee12c25d15f5a25022p+0L,\n\t0x1.2b87fd0dad98ffddea46538fca24p+0L,\n\t0x1.2d285a6e4030b40091d536d0733ep+0L,\n\t0x1.2ecafa93e2f5611ca0f45d5239a4p+0L,\n\t0x1.306fe0a31b7152de8d5a463063bep+0L,\n\t0x1.32170fc4cd8313539cf1c3009330p+0L,\n\t0x1.33c08b26416ff4c9c8610d96680ep+0L,\n\t0x1.356c55f929ff0c94623476373be4p+0L,\n\t0x1.371a7373aa9caa7145502f45452ap+0L,\n\t0x1.38cae6d05d86585a9cb0d9bed530p+0L,\n\t0x1.3a7db34e59ff6ea1bc9299e0a1fep+0L,\n\t0x1.3c32dc313a8e484001f228b58cf0p+0L,\n\t0x1.3dea64c12342235b41223e13d7eep+0L,\n\t0x1.3fa4504ac801ba0bf701aa417b9cp+0L,\n\t0x1.4160a21f72e29f84325b8f3dbacap+0L,\n\t0x1.431f5d950a896dc704439410b628p+0L,\n\t0x1.44e086061892d03136f409df0724p+0L,\n\t0x1.46a41ed1d005772512f459229f0ap+0L,\n\t0x1.486a2b5c13cd013c1a3b69062f26p+0L,\n\t0x1.4a32af0d7d3de672d8bcf46f99b4p+0L,\n\t0x1.4bfdad5362a271d4397afec42e36p+0L,\n\t0x1.4dcb299fddd0d63b36ef1a9e19dep+0L,\n\t0x1.4f9b2769d2ca6ad33d8b69aa0b8cp+0L,\n\t0x1.516daa2cf6641c112f52c84d6066p+0L,\n\t0x1.5342b569d4f81df0a83c49d86bf4p+0L,\n\t0x1.551a4ca5d920ec52ec620243540cp+0L,\n\t0x1.56f4736b527da66ecb004764e61ep+0L,\n\t0x1.58d12d497c7fd252bc2b7343d554p+0L,\n\t0x1.5ab07dd48542958c93015191e9a8p+0L,\n\t0x1.5c9268a5946b701c4b1b81697ed4p+0L,\n\t0x1.5e76f15ad21486e9be4c20399d12p+0L,\n\t0x1.605e1b976dc08b076f592a487066p+0L,\n\t0x1.6247eb03a5584b1f0fa06fd2d9eap+0L,\n\t0x1.6434634ccc31fc76f8714c4ee122p+0L,\n\t0x1.66238825522249127d9e29b92ea2p+0L,\n\t0x1.68155d44ca973081c57227b9f69ep+0L,\n};\n\nstatic const float eps[TBLSIZE] = {\n\t-0x1.5c50p-101,\n\t-0x1.5d00p-106,\n\t 0x1.8e90p-102,\n\t-0x1.5340p-103,\n\t 0x1.1bd0p-102,\n\t-0x1.4600p-105,\n\t-0x1.7a40p-104,\n\t 0x1.d590p-102,\n\t-0x1.d590p-101,\n\t 0x1.b100p-103,\n\t-0x1.0d80p-105,\n\t 0x1.6b00p-103,\n\t-0x1.9f00p-105,\n\t 0x1.c400p-103,\n\t 0x1.e120p-103,\n\t-0x1.c100p-104,\n\t-0x1.9d20p-103,\n\t 0x1.a800p-108,\n\t 0x1.4c00p-106,\n\t-0x1.9500p-106,\n\t 0x1.6900p-105,\n\t-0x1.29d0p-100,\n\t 0x1.4c60p-103,\n\t 0x1.13a0p-102,\n\t-0x1.5b60p-103,\n\t-0x1.1c40p-103,\n\t 0x1.db80p-102,\n\t 0x1.91a0p-102,\n\t 0x1.dc00p-105,\n\t 0x1.44c0p-104,\n\t 0x1.9710p-102,\n\t 0x1.8760p-103,\n\t-0x1.a720p-103,\n\t 0x1.ed20p-103,\n\t-0x1.49c0p-102,\n\t-0x1.e000p-111,\n\t 0x1.86a0p-103,\n\t 0x1.2b40p-103,\n\t-0x1.b400p-108,\n\t 0x1.1280p-99,\n\t-0x1.02d8p-102,\n\t-0x1.e3d0p-103,\n\t-0x1.b080p-105,\n\t-0x1.f100p-107,\n\t-0x1.16c0p-105,\n\t-0x1.1190p-103,\n\t-0x1.a7d2p-100,\n\t 0x1.3450p-103,\n\t-0x1.67c0p-105,\n\t 0x1.4b80p-104,\n\t-0x1.c4e0p-103,\n\t 0x1.6000p-108,\n\t-0x1.3f60p-105,\n\t 0x1.93f0p-104,\n\t 0x1.5fe0p-105,\n\t 0x1.6f80p-107,\n\t-0x1.7600p-106,\n\t 0x1.21e0p-106,\n\t-0x1.3a40p-106,\n\t-0x1.40c0p-104,\n\t-0x1.9860p-105,\n\t-0x1.5d40p-108,\n\t-0x1.1d70p-106,\n\t 0x1.2760p-105,\n\t 0x0.0000p+0,\n\t 0x1.21e2p-104,\n\t-0x1.9520p-108,\n\t-0x1.5720p-106,\n\t-0x1.4810p-106,\n\t-0x1.be00p-109,\n\t 0x1.0080p-105,\n\t-0x1.5780p-108,\n\t-0x1.d460p-105,\n\t-0x1.6140p-105,\n\t 0x1.4630p-104,\n\t 0x1.ad50p-103,\n\t 0x1.82e0p-105,\n\t 0x1.1d3cp-101,\n\t 0x1.6100p-107,\n\t 0x1.ec30p-104,\n\t 0x1.f200p-108,\n\t 0x1.0b40p-103,\n\t 0x1.3660p-102,\n\t 0x1.d9d0p-103,\n\t-0x1.02d0p-102,\n\t 0x1.b070p-103,\n\t 0x1.b9c0p-104,\n\t-0x1.01c0p-103,\n\t-0x1.dfe0p-103,\n\t 0x1.1b60p-104,\n\t-0x1.ae94p-101,\n\t-0x1.3340p-104,\n\t 0x1.b3d8p-102,\n\t-0x1.6e40p-105,\n\t-0x1.3670p-103,\n\t 0x1.c140p-104,\n\t 0x1.1840p-101,\n\t 0x1.1ab0p-102,\n\t-0x1.a400p-104,\n\t 0x1.1f00p-104,\n\t-0x1.7180p-103,\n\t 0x1.4ce0p-102,\n\t 0x1.9200p-107,\n\t-0x1.54c0p-103,\n\t 0x1.1b80p-105,\n\t-0x1.1828p-101,\n\t 0x1.5720p-102,\n\t-0x1.a060p-100,\n\t 0x1.9160p-102,\n\t 0x1.a280p-104,\n\t 0x1.3400p-107,\n\t 0x1.2b20p-102,\n\t 0x1.7800p-108,\n\t 0x1.cfd0p-101,\n\t 0x1.2ef0p-102,\n\t-0x1.2760p-99,\n\t 0x1.b380p-104,\n\t 0x1.0048p-101,\n\t-0x1.60b0p-102,\n\t 0x1.a1ccp-100,\n\t-0x1.a640p-104,\n\t-0x1.08a0p-101,\n\t 0x1.7e60p-102,\n\t 0x1.22c0p-103,\n\t-0x1.7200p-106,\n\t 0x1.f0f0p-102,\n\t 0x1.eb4ep-99,\n\t 0x1.c6e0p-103,\n};\n\n/*\n * exp2l(x): compute the base 2 exponential of x\n *\n * Accuracy: Peak error < 0.502 ulp.\n *\n * Method: (accurate tables)\n *\n *   Reduce x:\n *     x = 2**k + y, for integer k and |y| <= 1/2.\n *     Thus we have exp2(x) = 2**k * exp2(y).\n *\n *   Reduce y:\n *     y = i/TBLSIZE + z - eps[i] for integer i near y * TBLSIZE.\n *     Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z - eps[i]),\n *     with |z - eps[i]| <= 2**-8 + 2**-98 for the table used.\n *\n *   We compute exp2(i/TBLSIZE) via table lookup and exp2(z - eps[i]) via\n *   a degree-10 minimax polynomial with maximum error under 2**-120.\n *   The values in exp2t[] and eps[] are chosen such that\n *   exp2t[i] = exp2(i/TBLSIZE + eps[i]), and eps[i] is a small offset such\n *   that exp2t[i] is accurate to 2**-122.\n *\n *   Note that the range of i is +-TBLSIZE/2, so we actually index the tables\n *   by i0 = i + TBLSIZE/2.\n *\n *   This method is due to Gal, with many details due to Gal and Bachelis:\n *\n *\tGal, S. and Bachelis, B.  An Accurate Elementary Mathematical Library\n *\tfor the IEEE Floating Point Standard.  TOMS 17(1), 26-46 (1991).\n */\nlong double\nexp2l(long double x)\n{\n\tunion ldshape u = {x};\n\tint e = u.i.se & 0x7fff;\n\tlong double r, z, t;\n\tuint32_t i0;\n\tunion {uint32_t u; int32_t i;} k;\n\n\t/* Filter out exceptional cases. */\n\tif (e >= 0x3fff + 14) {  /* |x| >= 16384 or x is NaN */\n\t\tif (u.i.se >= 0x3fff + 15 && u.i.se >> 15 == 0)\n\t\t\t/* overflow */\n\t\t\treturn x * 0x1p16383L;\n\t\tif (e == 0x7fff)  /* -inf or -nan */\n\t\t\treturn -1/x;\n\t\tif (x < -16382) {\n\t\t\tif (x <= -16495 || x - 0x1p112 + 0x1p112 != x)\n\t\t\t\t/* underflow */\n\t\t\t\tFORCE_EVAL((float)(-0x1p-149/x));\n\t\t\tif (x <= -16446)\n\t\t\t\treturn 0;\n\t\t}\n\t} else if (e < 0x3fff - 114) {\n\t\treturn 1 + x;\n\t}\n\n\t/*\n\t * Reduce x, computing z, i0, and k. The low bits of x + redux\n\t * contain the 16-bit integer part of the exponent (k) followed by\n\t * TBLBITS fractional bits (i0). We use bit tricks to extract these\n\t * as integers, then set z to the remainder.\n\t *\n\t * Example: Suppose x is 0xabc.123456p0 and TBLBITS is 8.\n\t * Then the low-order word of x + redux is 0x000abc12,\n\t * We split this into k = 0xabc and i0 = 0x12 (adjusted to\n\t * index into the table), then we compute z = 0x0.003456p0.\n\t */\n\tu.f = x + redux;\n\ti0 = u.i2.lo + TBLSIZE / 2;\n\tk.u = i0 / TBLSIZE * TBLSIZE;\n\tk.i /= TBLSIZE;\n\ti0 %= TBLSIZE;\n\tu.f -= redux;\n\tz = x - u.f;\n\n\t/* Compute r = exp2(y) = exp2t[i0] * p(z - eps[i]). */\n\tt = tbl[i0];\n\tz -= eps[i0];\n\tr = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * (P5 + z * (P6\n\t    + z * (P7 + z * (P8 + z * (P9 + z * P10)))))))));\n\n\treturn scalbnl(r, k.i);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/exp_data.c",
    "content": "/*\n * Shared data between exp, exp2 and pow.\n *\n * Copyright (c) 2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n\n#include \"exp_data.h\"\n\n#define N (1 << EXP_TABLE_BITS)\n\nconst struct exp_data __exp_data = {\n// N/ln2\n.invln2N = 0x1.71547652b82fep0 * N,\n// -ln2/N\n.negln2hiN = -0x1.62e42fefa0000p-8,\n.negln2loN = -0x1.cf79abc9e3b3ap-47,\n// Used for rounding when !TOINT_INTRINSICS\n#if EXP_USE_TOINT_NARROW\n.shift = 0x1800000000.8p0,\n#else\n.shift = 0x1.8p52,\n#endif\n// exp polynomial coefficients.\n.poly = {\n// abs error: 1.555*2^-66\n// ulp error: 0.509 (0.511 without fma)\n// if |x| < ln2/256+eps\n// abs error if |x| < ln2/256+0x1p-15: 1.09*2^-65\n// abs error if |x| < ln2/128: 1.7145*2^-56\n0x1.ffffffffffdbdp-2,\n0x1.555555555543cp-3,\n0x1.55555cf172b91p-5,\n0x1.1111167a4d017p-7,\n},\n.exp2_shift = 0x1.8p52 / N,\n// exp2 polynomial coefficients.\n.exp2_poly = {\n// abs error: 1.2195*2^-65\n// ulp error: 0.507 (0.511 without fma)\n// if |x| < 1/256\n// abs error if |x| < 1/128: 1.9941*2^-56\n0x1.62e42fefa39efp-1,\n0x1.ebfbdff82c424p-3,\n0x1.c6b08d70cf4b5p-5,\n0x1.3b2abd24650ccp-7,\n0x1.5d7e09b4e3a84p-10,\n},\n// 2^(k/N) ~= H[k]*(1 + T[k]) for int k in [0,N)\n// tab[2*k] = asuint64(T[k])\n// tab[2*k+1] = asuint64(H[k]) - (k << 52)/N\n.tab = {\n0x0, 0x3ff0000000000000,\n0x3c9b3b4f1a88bf6e, 0x3feff63da9fb3335,\n0xbc7160139cd8dc5d, 0x3fefec9a3e778061,\n0xbc905e7a108766d1, 0x3fefe315e86e7f85,\n0x3c8cd2523567f613, 0x3fefd9b0d3158574,\n0xbc8bce8023f98efa, 0x3fefd06b29ddf6de,\n0x3c60f74e61e6c861, 0x3fefc74518759bc8,\n0x3c90a3e45b33d399, 0x3fefbe3ecac6f383,\n0x3c979aa65d837b6d, 0x3fefb5586cf9890f,\n0x3c8eb51a92fdeffc, 0x3fefac922b7247f7,\n0x3c3ebe3d702f9cd1, 0x3fefa3ec32d3d1a2,\n0xbc6a033489906e0b, 0x3fef9b66affed31b,\n0xbc9556522a2fbd0e, 0x3fef9301d0125b51,\n0xbc5080ef8c4eea55, 0x3fef8abdc06c31cc,\n0xbc91c923b9d5f416, 0x3fef829aaea92de0,\n0x3c80d3e3e95c55af, 0x3fef7a98c8a58e51,\n0xbc801b15eaa59348, 0x3fef72b83c7d517b,\n0xbc8f1ff055de323d, 0x3fef6af9388c8dea,\n0x3c8b898c3f1353bf, 0x3fef635beb6fcb75,\n0xbc96d99c7611eb26, 0x3fef5be084045cd4,\n0x3c9aecf73e3a2f60, 0x3fef54873168b9aa,\n0xbc8fe782cb86389d, 0x3fef4d5022fcd91d,\n0x3c8a6f4144a6c38d, 0x3fef463b88628cd6,\n0x3c807a05b0e4047d, 0x3fef3f49917ddc96,\n0x3c968efde3a8a894, 0x3fef387a6e756238,\n0x3c875e18f274487d, 0x3fef31ce4fb2a63f,\n0x3c80472b981fe7f2, 0x3fef2b4565e27cdd,\n0xbc96b87b3f71085e, 0x3fef24dfe1f56381,\n0x3c82f7e16d09ab31, 0x3fef1e9df51fdee1,\n0xbc3d219b1a6fbffa, 0x3fef187fd0dad990,\n0x3c8b3782720c0ab4, 0x3fef1285a6e4030b,\n0x3c6e149289cecb8f, 0x3fef0cafa93e2f56,\n0x3c834d754db0abb6, 0x3fef06fe0a31b715,\n0x3c864201e2ac744c, 0x3fef0170fc4cd831,\n0x3c8fdd395dd3f84a, 0x3feefc08b26416ff,\n0xbc86a3803b8e5b04, 0x3feef6c55f929ff1,\n0xbc924aedcc4b5068, 0x3feef1a7373aa9cb,\n0xbc9907f81b512d8e, 0x3feeecae6d05d866,\n0xbc71d1e83e9436d2, 0x3feee7db34e59ff7,\n0xbc991919b3ce1b15, 0x3feee32dc313a8e5,\n0x3c859f48a72a4c6d, 0x3feedea64c123422,\n0xbc9312607a28698a, 0x3feeda4504ac801c,\n0xbc58a78f4817895b, 0x3feed60a21f72e2a,\n0xbc7c2c9b67499a1b, 0x3feed1f5d950a897,\n0x3c4363ed60c2ac11, 0x3feece086061892d,\n0x3c9666093b0664ef, 0x3feeca41ed1d0057,\n0x3c6ecce1daa10379, 0x3feec6a2b5c13cd0,\n0x3c93ff8e3f0f1230, 0x3feec32af0d7d3de,\n0x3c7690cebb7aafb0, 0x3feebfdad5362a27,\n0x3c931dbdeb54e077, 0x3feebcb299fddd0d,\n0xbc8f94340071a38e, 0x3feeb9b2769d2ca7,\n0xbc87deccdc93a349, 0x3feeb6daa2cf6642,\n0xbc78dec6bd0f385f, 0x3feeb42b569d4f82,\n0xbc861246ec7b5cf6, 0x3feeb1a4ca5d920f,\n0x3c93350518fdd78e, 0x3feeaf4736b527da,\n0x3c7b98b72f8a9b05, 0x3feead12d497c7fd,\n0x3c9063e1e21c5409, 0x3feeab07dd485429,\n0x3c34c7855019c6ea, 0x3feea9268a5946b7,\n0x3c9432e62b64c035, 0x3feea76f15ad2148,\n0xbc8ce44a6199769f, 0x3feea5e1b976dc09,\n0xbc8c33c53bef4da8, 0x3feea47eb03a5585,\n0xbc845378892be9ae, 0x3feea34634ccc320,\n0xbc93cedd78565858, 0x3feea23882552225,\n0x3c5710aa807e1964, 0x3feea155d44ca973,\n0xbc93b3efbf5e2228, 0x3feea09e667f3bcd,\n0xbc6a12ad8734b982, 0x3feea012750bdabf,\n0xbc6367efb86da9ee, 0x3fee9fb23c651a2f,\n0xbc80dc3d54e08851, 0x3fee9f7df9519484,\n0xbc781f647e5a3ecf, 0x3fee9f75e8ec5f74,\n0xbc86ee4ac08b7db0, 0x3fee9f9a48a58174,\n0xbc8619321e55e68a, 0x3fee9feb564267c9,\n0x3c909ccb5e09d4d3, 0x3feea0694fde5d3f,\n0xbc7b32dcb94da51d, 0x3feea11473eb0187,\n0x3c94ecfd5467c06b, 0x3feea1ed0130c132,\n0x3c65ebe1abd66c55, 0x3feea2f336cf4e62,\n0xbc88a1c52fb3cf42, 0x3feea427543e1a12,\n0xbc9369b6f13b3734, 0x3feea589994cce13,\n0xbc805e843a19ff1e, 0x3feea71a4623c7ad,\n0xbc94d450d872576e, 0x3feea8d99b4492ed,\n0x3c90ad675b0e8a00, 0x3feeaac7d98a6699,\n0x3c8db72fc1f0eab4, 0x3feeace5422aa0db,\n0xbc65b6609cc5e7ff, 0x3feeaf3216b5448c,\n0x3c7bf68359f35f44, 0x3feeb1ae99157736,\n0xbc93091fa71e3d83, 0x3feeb45b0b91ffc6,\n0xbc5da9b88b6c1e29, 0x3feeb737b0cdc5e5,\n0xbc6c23f97c90b959, 0x3feeba44cbc8520f,\n0xbc92434322f4f9aa, 0x3feebd829fde4e50,\n0xbc85ca6cd7668e4b, 0x3feec0f170ca07ba,\n0x3c71affc2b91ce27, 0x3feec49182a3f090,\n0x3c6dd235e10a73bb, 0x3feec86319e32323,\n0xbc87c50422622263, 0x3feecc667b5de565,\n0x3c8b1c86e3e231d5, 0x3feed09bec4a2d33,\n0xbc91bbd1d3bcbb15, 0x3feed503b23e255d,\n0x3c90cc319cee31d2, 0x3feed99e1330b358,\n0x3c8469846e735ab3, 0x3feede6b5579fdbf,\n0xbc82dfcd978e9db4, 0x3feee36bbfd3f37a,\n0x3c8c1a7792cb3387, 0x3feee89f995ad3ad,\n0xbc907b8f4ad1d9fa, 0x3feeee07298db666,\n0xbc55c3d956dcaeba, 0x3feef3a2b84f15fb,\n0xbc90a40e3da6f640, 0x3feef9728de5593a,\n0xbc68d6f438ad9334, 0x3feeff76f2fb5e47,\n0xbc91eee26b588a35, 0x3fef05b030a1064a,\n0x3c74ffd70a5fddcd, 0x3fef0c1e904bc1d2,\n0xbc91bdfbfa9298ac, 0x3fef12c25bd71e09,\n0x3c736eae30af0cb3, 0x3fef199bdd85529c,\n0x3c8ee3325c9ffd94, 0x3fef20ab5fffd07a,\n0x3c84e08fd10959ac, 0x3fef27f12e57d14b,\n0x3c63cdaf384e1a67, 0x3fef2f6d9406e7b5,\n0x3c676b2c6c921968, 0x3fef3720dcef9069,\n0xbc808a1883ccb5d2, 0x3fef3f0b555dc3fa,\n0xbc8fad5d3ffffa6f, 0x3fef472d4a07897c,\n0xbc900dae3875a949, 0x3fef4f87080d89f2,\n0x3c74a385a63d07a7, 0x3fef5818dcfba487,\n0xbc82919e2040220f, 0x3fef60e316c98398,\n0x3c8e5a50d5c192ac, 0x3fef69e603db3285,\n0x3c843a59ac016b4b, 0x3fef7321f301b460,\n0xbc82d52107b43e1f, 0x3fef7c97337b9b5f,\n0xbc892ab93b470dc9, 0x3fef864614f5a129,\n0x3c74b604603a88d3, 0x3fef902ee78b3ff6,\n0x3c83c5ec519d7271, 0x3fef9a51fbc74c83,\n0xbc8ff7128fd391f0, 0x3fefa4afa2a490da,\n0xbc8dae98e223747d, 0x3fefaf482d8e67f1,\n0x3c8ec3bc41aa2008, 0x3fefba1bee615a27,\n0x3c842b94c3a9eb32, 0x3fefc52b376bba97,\n0x3c8a64a931d185ee, 0x3fefd0765b6e4540,\n0xbc8e37bae43be3ed, 0x3fefdbfdad9cbe14,\n0x3c77893b4d91cd9d, 0x3fefe7c1819e90d8,\n0x3c5305c14160cc89, 0x3feff3c22b8f71f1,\n},\n};\n"
  },
  {
    "path": "user.libc/src/math/exp_data.h",
    "content": "/*\n * Copyright (c) 2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n#ifndef _EXP_DATA_H\n#define _EXP_DATA_H\n\n#include <features.h>\n#include <stdint.h>\n\n#define EXP_TABLE_BITS 7\n#define EXP_POLY_ORDER 5\n#define EXP_USE_TOINT_NARROW 0\n#define EXP2_POLY_ORDER 5\nextern hidden const struct exp_data {\n\tdouble invln2N;\n\tdouble shift;\n\tdouble negln2hiN;\n\tdouble negln2loN;\n\tdouble poly[4]; /* Last four coefficients.  */\n\tdouble exp2_shift;\n\tdouble exp2_poly[EXP2_POLY_ORDER];\n\tuint64_t tab[2*(1 << EXP_TABLE_BITS)];\n} __exp_data;\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/expf.c",
    "content": "/*\n * Single-precision e^x function.\n *\n * Copyright (c) 2017-2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n\n#include <math.h>\n#include <stdint.h>\n#include \"libm.h\"\n#include \"exp2f_data.h\"\n\n/*\nEXP2F_TABLE_BITS = 5\nEXP2F_POLY_ORDER = 3\n\nULP error: 0.502 (nearest rounding.)\nRelative error: 1.69 * 2^-34 in [-ln2/64, ln2/64] (before rounding.)\nWrong count: 170635 (all nearest rounding wrong results with fma.)\nNon-nearest ULP error: 1 (rounded ULP error)\n*/\n\n#define N (1 << EXP2F_TABLE_BITS)\n#define InvLn2N __exp2f_data.invln2_scaled\n#define T __exp2f_data.tab\n#define C __exp2f_data.poly_scaled\n\nstatic inline uint32_t top12(float x)\n{\n\treturn asuint(x) >> 20;\n}\n\nfloat expf(float x)\n{\n\tuint32_t abstop;\n\tuint64_t ki, t;\n\tdouble_t kd, xd, z, r, r2, y, s;\n\n\txd = (double_t)x;\n\tabstop = top12(x) & 0x7ff;\n\tif (predict_false(abstop >= top12(88.0f))) {\n\t\t/* |x| >= 88 or x is nan.  */\n\t\tif (asuint(x) == asuint(-INFINITY))\n\t\t\treturn 0.0f;\n\t\tif (abstop >= top12(INFINITY))\n\t\t\treturn x + x;\n\t\tif (x > 0x1.62e42ep6f) /* x > log(0x1p128) ~= 88.72 */\n\t\t\treturn __math_oflowf(0);\n\t\tif (x < -0x1.9fe368p6f) /* x < log(0x1p-150) ~= -103.97 */\n\t\t\treturn __math_uflowf(0);\n\t}\n\n\t/* x*N/Ln2 = k + r with r in [-1/2, 1/2] and int k.  */\n\tz = InvLn2N * xd;\n\n\t/* Round and convert z to int, the result is in [-150*N, 128*N] and\n\t   ideally ties-to-even rule is used, otherwise the magnitude of r\n\t   can be bigger which gives larger approximation error.  */\n#if TOINT_INTRINSICS\n\tkd = roundtoint(z);\n\tki = converttoint(z);\n#else\n# define SHIFT __exp2f_data.shift\n\tkd = eval_as_double(z + SHIFT);\n\tki = asuint64(kd);\n\tkd -= SHIFT;\n#endif\n\tr = z - kd;\n\n\t/* exp(x) = 2^(k/N) * 2^(r/N) ~= s * (C0*r^3 + C1*r^2 + C2*r + 1) */\n\tt = T[ki % N];\n\tt += ki << (52 - EXP2F_TABLE_BITS);\n\ts = asdouble(t);\n\tz = C[0] * r + C[1];\n\tr2 = r * r;\n\ty = C[2] * r + 1;\n\ty = z * r2 + y;\n\ty = y * s;\n\treturn eval_as_float(y);\n}\n"
  },
  {
    "path": "user.libc/src/math/expl.c",
    "content": "/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_expl.c */\n/*\n * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n/*\n *      Exponential function, long double precision\n *\n *\n * SYNOPSIS:\n *\n * long double x, y, expl();\n *\n * y = expl( x );\n *\n *\n * DESCRIPTION:\n *\n * Returns e (2.71828...) raised to the x power.\n *\n * Range reduction is accomplished by separating the argument\n * into an integer k and fraction f such that\n *\n *     x    k  f\n *    e  = 2  e.\n *\n * A Pade' form of degree 5/6 is used to approximate exp(f) - 1\n * in the basic range [-0.5 ln 2, 0.5 ln 2].\n *\n *\n * ACCURACY:\n *\n *                      Relative error:\n * arithmetic   domain     # trials      peak         rms\n *    IEEE      +-10000     50000       1.12e-19    2.81e-20\n *\n *\n * Error amplification in the exponential function can be\n * a serious matter.  The error propagation involves\n * exp( X(1+delta) ) = exp(X) ( 1 + X*delta + ... ),\n * which shows that a 1 lsb error in representing X produces\n * a relative error of X times 1 lsb in the function.\n * While the routine gives an accurate result for arguments\n * that are exactly represented by a long double precision\n * computer number, the result contains amplified roundoff\n * error for large arguments not exactly represented.\n *\n *\n * ERROR MESSAGES:\n *\n *   message         condition      value returned\n * exp underflow    x < MINLOG         0.0\n * exp overflow     x > MAXLOG         MAXNUM\n *\n */\n\n#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double expl(long double x)\n{\n\treturn exp(x);\n}\n#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384\n\nstatic const long double P[3] = {\n 1.2617719307481059087798E-4L,\n 3.0299440770744196129956E-2L,\n 9.9999999999999999991025E-1L,\n};\nstatic const long double Q[4] = {\n 3.0019850513866445504159E-6L,\n 2.5244834034968410419224E-3L,\n 2.2726554820815502876593E-1L,\n 2.0000000000000000000897E0L,\n};\nstatic const long double\nLN2HI = 6.9314575195312500000000E-1L,\nLN2LO = 1.4286068203094172321215E-6L,\nLOG2E = 1.4426950408889634073599E0L;\n\nlong double expl(long double x)\n{\n\tlong double px, xx;\n\tint k;\n\n\tif (isnan(x))\n\t\treturn x;\n\tif (x > 11356.5234062941439488L) /* x > ln(2^16384 - 0.5) */\n\t\treturn x * 0x1p16383L;\n\tif (x < -11399.4985314888605581L) /* x < ln(2^-16446) */\n\t\treturn -0x1p-16445L/x;\n\n\t/* Express e**x = e**f 2**k\n\t *   = e**(f + k ln(2))\n\t */\n\tpx = floorl(LOG2E * x + 0.5);\n\tk = px;\n\tx -= px * LN2HI;\n\tx -= px * LN2LO;\n\n\t/* rational approximation of the fractional part:\n\t * e**x =  1 + 2x P(x**2)/(Q(x**2) - x P(x**2))\n\t */\n\txx = x * x;\n\tpx = x * __polevll(xx, P, 2);\n\tx = px/(__polevll(xx, Q, 3) - px);\n\tx = 1.0 + 2.0 * x;\n\treturn scalbnl(x, k);\n}\n#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384\n// TODO: broken implementation to make things compile\nlong double expl(long double x)\n{\n\treturn exp(x);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/expm1.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_expm1.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/* expm1(x)\n * Returns exp(x)-1, the exponential of x minus 1.\n *\n * Method\n *   1. Argument reduction:\n *      Given x, find r and integer k such that\n *\n *               x = k*ln2 + r,  |r| <= 0.5*ln2 ~ 0.34658\n *\n *      Here a correction term c will be computed to compensate\n *      the error in r when rounded to a floating-point number.\n *\n *   2. Approximating expm1(r) by a special rational function on\n *      the interval [0,0.34658]:\n *      Since\n *          r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 - r^4/360 + ...\n *      we define R1(r*r) by\n *          r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 * R1(r*r)\n *      That is,\n *          R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r)\n *                   = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r))\n *                   = 1 - r^2/60 + r^4/2520 - r^6/100800 + ...\n *      We use a special Remez algorithm on [0,0.347] to generate\n *      a polynomial of degree 5 in r*r to approximate R1. The\n *      maximum error of this polynomial approximation is bounded\n *      by 2**-61. In other words,\n *          R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5\n *      where   Q1  =  -1.6666666666666567384E-2,\n *              Q2  =   3.9682539681370365873E-4,\n *              Q3  =  -9.9206344733435987357E-6,\n *              Q4  =   2.5051361420808517002E-7,\n *              Q5  =  -6.2843505682382617102E-9;\n *              z   =  r*r,\n *      with error bounded by\n *          |                  5           |     -61\n *          | 1.0+Q1*z+...+Q5*z   -  R1(z) | <= 2\n *          |                              |\n *\n *      expm1(r) = exp(r)-1 is then computed by the following\n *      specific way which minimize the accumulation rounding error:\n *                             2     3\n *                            r     r    [ 3 - (R1 + R1*r/2)  ]\n *            expm1(r) = r + --- + --- * [--------------------]\n *                            2     2    [ 6 - r*(3 - R1*r/2) ]\n *\n *      To compensate the error in the argument reduction, we use\n *              expm1(r+c) = expm1(r) + c + expm1(r)*c\n *                         ~ expm1(r) + c + r*c\n *      Thus c+r*c will be added in as the correction terms for\n *      expm1(r+c). Now rearrange the term to avoid optimization\n *      screw up:\n *                      (      2                                    2 )\n *                      ({  ( r    [ R1 -  (3 - R1*r/2) ]  )  }    r  )\n *       expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- )\n *                      ({  ( 2    [ 6 - r*(3 - R1*r/2) ]  )  }    2  )\n *                      (                                             )\n *\n *                 = r - E\n *   3. Scale back to obtain expm1(x):\n *      From step 1, we have\n *         expm1(x) = either 2^k*[expm1(r)+1] - 1\n *                  = or     2^k*[expm1(r) + (1-2^-k)]\n *   4. Implementation notes:\n *      (A). To save one multiplication, we scale the coefficient Qi\n *           to Qi*2^i, and replace z by (x^2)/2.\n *      (B). To achieve maximum accuracy, we compute expm1(x) by\n *        (i)   if x < -56*ln2, return -1.0, (raise inexact if x!=inf)\n *        (ii)  if k=0, return r-E\n *        (iii) if k=-1, return 0.5*(r-E)-0.5\n *        (iv)  if k=1 if r < -0.25, return 2*((r+0.5)- E)\n *                     else          return  1.0+2.0*(r-E);\n *        (v)   if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1)\n *        (vi)  if k <= 20, return 2^k((1-2^-k)-(E-r)), else\n *        (vii) return 2^k(1-((E+2^-k)-r))\n *\n * Special cases:\n *      expm1(INF) is INF, expm1(NaN) is NaN;\n *      expm1(-INF) is -1, and\n *      for finite argument, only expm1(0)=0 is exact.\n *\n * Accuracy:\n *      according to an error analysis, the error is always less than\n *      1 ulp (unit in the last place).\n *\n * Misc. info.\n *      For IEEE double\n *          if x >  7.09782712893383973096e+02 then expm1(x) overflow\n *\n * Constants:\n * The hexadecimal values are the intended ones for the following\n * constants. The decimal values may be used, provided that the\n * compiler will convert from decimal to binary accurately enough\n * to produce the hexadecimal values shown.\n */\n\n#include \"libm.h\"\n\nstatic const double\no_threshold = 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */\nln2_hi      = 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */\nln2_lo      = 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */\ninvln2      = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */\n/* Scaled Q's: Qn_here = 2**n * Qn_above, for R(2*z) where z = hxs = x*x/2: */\nQ1 = -3.33333333333331316428e-02, /* BFA11111 111110F4 */\nQ2 =  1.58730158725481460165e-03, /* 3F5A01A0 19FE5585 */\nQ3 = -7.93650757867487942473e-05, /* BF14CE19 9EAADBB7 */\nQ4 =  4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */\nQ5 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */\n\ndouble expm1(double x)\n{\n\tdouble_t y,hi,lo,c,t,e,hxs,hfx,r1,twopk;\n\tunion {double f; uint64_t i;} u = {x};\n\tuint32_t hx = u.i>>32 & 0x7fffffff;\n\tint k, sign = u.i>>63;\n\n\t/* filter out huge and non-finite argument */\n\tif (hx >= 0x4043687A) {  /* if |x|>=56*ln2 */\n\t\tif (isnan(x))\n\t\t\treturn x;\n\t\tif (sign)\n\t\t\treturn -1;\n\t\tif (x > o_threshold) {\n\t\t\tx *= 0x1p1023;\n\t\t\treturn x;\n\t\t}\n\t}\n\n\t/* argument reduction */\n\tif (hx > 0x3fd62e42) {  /* if  |x| > 0.5 ln2 */\n\t\tif (hx < 0x3FF0A2B2) {  /* and |x| < 1.5 ln2 */\n\t\t\tif (!sign) {\n\t\t\t\thi = x - ln2_hi;\n\t\t\t\tlo = ln2_lo;\n\t\t\t\tk =  1;\n\t\t\t} else {\n\t\t\t\thi = x + ln2_hi;\n\t\t\t\tlo = -ln2_lo;\n\t\t\t\tk = -1;\n\t\t\t}\n\t\t} else {\n\t\t\tk  = invln2*x + (sign ? -0.5 : 0.5);\n\t\t\tt  = k;\n\t\t\thi = x - t*ln2_hi;  /* t*ln2_hi is exact here */\n\t\t\tlo = t*ln2_lo;\n\t\t}\n\t\tx = hi-lo;\n\t\tc = (hi-x)-lo;\n\t} else if (hx < 0x3c900000) {  /* |x| < 2**-54, return x */\n\t\tif (hx < 0x00100000)\n\t\t\tFORCE_EVAL((float)x);\n\t\treturn x;\n\t} else\n\t\tk = 0;\n\n\t/* x is now in primary range */\n\thfx = 0.5*x;\n\thxs = x*hfx;\n\tr1 = 1.0+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5))));\n\tt  = 3.0-r1*hfx;\n\te  = hxs*((r1-t)/(6.0 - x*t));\n\tif (k == 0)   /* c is 0 */\n\t\treturn x - (x*e-hxs);\n\te  = x*(e-c) - c;\n\te -= hxs;\n\t/* exp(x) ~ 2^k (x_reduced - e + 1) */\n\tif (k == -1)\n\t\treturn 0.5*(x-e) - 0.5;\n\tif (k == 1) {\n\t\tif (x < -0.25)\n\t\t\treturn -2.0*(e-(x+0.5));\n\t\treturn 1.0+2.0*(x-e);\n\t}\n\tu.i = (uint64_t)(0x3ff + k)<<52;  /* 2^k */\n\ttwopk = u.f;\n\tif (k < 0 || k > 56) {  /* suffice to return exp(x)-1 */\n\t\ty = x - e + 1.0;\n\t\tif (k == 1024)\n\t\t\ty = y*2.0*0x1p1023;\n\t\telse\n\t\t\ty = y*twopk;\n\t\treturn y - 1.0;\n\t}\n\tu.i = (uint64_t)(0x3ff - k)<<52;  /* 2^-k */\n\tif (k < 20)\n\t\ty = (x-e+(1-u.f))*twopk;\n\telse\n\t\ty = (x-(e+u.f)+1)*twopk;\n\treturn y;\n}\n"
  },
  {
    "path": "user.libc/src/math/expm1f.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_expm1f.c */\n/*\n * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.\n */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n\n#include \"libm.h\"\n\nstatic const float\no_threshold = 8.8721679688e+01, /* 0x42b17180 */\nln2_hi      = 6.9313812256e-01, /* 0x3f317180 */\nln2_lo      = 9.0580006145e-06, /* 0x3717f7d1 */\ninvln2      = 1.4426950216e+00, /* 0x3fb8aa3b */\n/*\n * Domain [-0.34568, 0.34568], range ~[-6.694e-10, 6.696e-10]:\n * |6 / x * (1 + 2 * (1 / (exp(x) - 1) - 1 / x)) - q(x)| < 2**-30.04\n * Scaled coefficients: Qn_here = 2**n * Qn_for_q (see s_expm1.c):\n */\nQ1 = -3.3333212137e-2, /* -0x888868.0p-28 */\nQ2 =  1.5807170421e-3; /*  0xcf3010.0p-33 */\n\nfloat expm1f(float x)\n{\n\tfloat_t y,hi,lo,c,t,e,hxs,hfx,r1,twopk;\n\tunion {float f; uint32_t i;} u = {x};\n\tuint32_t hx = u.i & 0x7fffffff;\n\tint k, sign = u.i >> 31;\n\n\t/* filter out huge and non-finite argument */\n\tif (hx >= 0x4195b844) {  /* if |x|>=27*ln2 */\n\t\tif (hx > 0x7f800000)  /* NaN */\n\t\t\treturn x;\n\t\tif (sign)\n\t\t\treturn -1;\n\t\tif (x > o_threshold) {\n\t\t\tx *= 0x1p127f;\n\t\t\treturn x;\n\t\t}\n\t}\n\n\t/* argument reduction */\n\tif (hx > 0x3eb17218) {           /* if  |x| > 0.5 ln2 */\n\t\tif (hx < 0x3F851592) {       /* and |x| < 1.5 ln2 */\n\t\t\tif (!sign) {\n\t\t\t\thi = x - ln2_hi;\n\t\t\t\tlo = ln2_lo;\n\t\t\t\tk =  1;\n\t\t\t} else {\n\t\t\t\thi = x + ln2_hi;\n\t\t\t\tlo = -ln2_lo;\n\t\t\t\tk = -1;\n\t\t\t}\n\t\t} else {\n\t\t\tk  = invln2*x + (sign ? -0.5f : 0.5f);\n\t\t\tt  = k;\n\t\t\thi = x - t*ln2_hi;      /* t*ln2_hi is exact here */\n\t\t\tlo = t*ln2_lo;\n\t\t}\n\t\tx = hi-lo;\n\t\tc = (hi-x)-lo;\n\t} else if (hx < 0x33000000) {  /* when |x|<2**-25, return x */\n\t\tif (hx < 0x00800000)\n\t\t\tFORCE_EVAL(x*x);\n\t\treturn x;\n\t} else\n\t\tk = 0;\n\n\t/* x is now in primary range */\n\thfx = 0.5f*x;\n\thxs = x*hfx;\n\tr1 = 1.0f+hxs*(Q1+hxs*Q2);\n\tt  = 3.0f - r1*hfx;\n\te  = hxs*((r1-t)/(6.0f - x*t));\n\tif (k == 0)  /* c is 0 */\n\t\treturn x - (x*e-hxs);\n\te  = x*(e-c) - c;\n\te -= hxs;\n\t/* exp(x) ~ 2^k (x_reduced - e + 1) */\n\tif (k == -1)\n\t\treturn 0.5f*(x-e) - 0.5f;\n\tif (k == 1) {\n\t\tif (x < -0.25f)\n\t\t\treturn -2.0f*(e-(x+0.5f));\n\t\treturn 1.0f + 2.0f*(x-e);\n\t}\n\tu.i = (0x7f+k)<<23;  /* 2^k */\n\ttwopk = u.f;\n\tif (k < 0 || k > 56) {   /* suffice to return exp(x)-1 */\n\t\ty = x - e + 1.0f;\n\t\tif (k == 128)\n\t\t\ty = y*2.0f*0x1p127f;\n\t\telse\n\t\t\ty = y*twopk;\n\t\treturn y - 1.0f;\n\t}\n\tu.i = (0x7f-k)<<23;  /* 2^-k */\n\tif (k < 23)\n\t\ty = (x-e+(1-u.f))*twopk;\n\telse\n\t\ty = (x-(e+u.f)+1)*twopk;\n\treturn y;\n}\n"
  },
  {
    "path": "user.libc/src/math/expm1l.c",
    "content": "/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_expm1l.c */\n/*\n * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n/*\n *      Exponential function, minus 1\n *      Long double precision\n *\n *\n * SYNOPSIS:\n *\n * long double x, y, expm1l();\n *\n * y = expm1l( x );\n *\n *\n * DESCRIPTION:\n *\n * Returns e (2.71828...) raised to the x power, minus 1.\n *\n * Range reduction is accomplished by separating the argument\n * into an integer k and fraction f such that\n *\n *     x    k  f\n *    e  = 2  e.\n *\n * An expansion x + .5 x^2 + x^3 R(x) approximates exp(f) - 1\n * in the basic range [-0.5 ln 2, 0.5 ln 2].\n *\n *\n * ACCURACY:\n *\n *                      Relative error:\n * arithmetic   domain     # trials      peak         rms\n *    IEEE    -45,+maxarg   200,000     1.2e-19     2.5e-20\n */\n\n#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double expm1l(long double x)\n{\n\treturn expm1(x);\n}\n#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384\n\n/* exp(x) - 1 = x + 0.5 x^2 + x^3 P(x)/Q(x)\n   -.5 ln 2  <  x  <  .5 ln 2\n   Theoretical peak relative error = 3.4e-22  */\nstatic const long double\nP0 = -1.586135578666346600772998894928250240826E4L,\nP1 =  2.642771505685952966904660652518429479531E3L,\nP2 = -3.423199068835684263987132888286791620673E2L,\nP3 =  1.800826371455042224581246202420972737840E1L,\nP4 = -5.238523121205561042771939008061958820811E-1L,\nQ0 = -9.516813471998079611319047060563358064497E4L,\nQ1 =  3.964866271411091674556850458227710004570E4L,\nQ2 = -7.207678383830091850230366618190187434796E3L,\nQ3 =  7.206038318724600171970199625081491823079E2L,\nQ4 = -4.002027679107076077238836622982900945173E1L,\n/* Q5 = 1.000000000000000000000000000000000000000E0 */\n/* C1 + C2 = ln 2 */\nC1 = 6.93145751953125E-1L,\nC2 = 1.428606820309417232121458176568075500134E-6L,\n/* ln 2^-65 */\nminarg = -4.5054566736396445112120088E1L,\n/* ln 2^16384 */\nmaxarg = 1.1356523406294143949492E4L;\n\nlong double expm1l(long double x)\n{\n\tlong double px, qx, xx;\n\tint k;\n\n\tif (isnan(x))\n\t\treturn x;\n\tif (x > maxarg)\n\t\treturn x*0x1p16383L; /* overflow, unless x==inf */\n\tif (x == 0.0)\n\t\treturn x;\n\tif (x < minarg)\n\t\treturn -1.0;\n\n\txx = C1 + C2;\n\t/* Express x = ln 2 (k + remainder), remainder not exceeding 1/2. */\n\tpx = floorl(0.5 + x / xx);\n\tk = px;\n\t/* remainder times ln 2 */\n\tx -= px * C1;\n\tx -= px * C2;\n\n\t/* Approximate exp(remainder ln 2).*/\n\tpx = (((( P4 * x + P3) * x + P2) * x + P1) * x + P0) * x;\n\tqx = (((( x + Q4) * x + Q3) * x + Q2) * x + Q1) * x + Q0;\n\txx = x * x;\n\tqx = x + (0.5 * xx + xx * px / qx);\n\n\t/* exp(x) = exp(k ln 2) exp(remainder ln 2) = 2^k exp(remainder ln 2).\n\t We have qx = exp(remainder ln 2) - 1, so\n\t exp(x) - 1  =  2^k (qx + 1) - 1  =  2^k qx + 2^k - 1.  */\n\tpx = scalbnl(1.0, k);\n\tx = px * qx + (px - 1.0);\n\treturn x;\n}\n#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384\n// TODO: broken implementation to make things compile\nlong double expm1l(long double x)\n{\n\treturn expm1(x);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/fabs.c",
    "content": "#include <math.h>\n#include <stdint.h>\n\ndouble fabs(double x)\n{\n\tunion {double f; uint64_t i;} u = {x};\n\tu.i &= -1ULL/2;\n\treturn u.f;\n}\n"
  },
  {
    "path": "user.libc/src/math/fabsf.c",
    "content": "#include <math.h>\n#include <stdint.h>\n\nfloat fabsf(float x)\n{\n\tunion {float f; uint32_t i;} u = {x};\n\tu.i &= 0x7fffffff;\n\treturn u.f;\n}\n"
  },
  {
    "path": "user.libc/src/math/fabsl.c",
    "content": "#include \"libm.h\"\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double fabsl(long double x)\n{\n\treturn fabs(x);\n}\n#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\nlong double fabsl(long double x)\n{\n\tunion ldshape u = {x};\n\n\tu.i.se &= 0x7fff;\n\treturn u.f;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/fdim.c",
    "content": "#include <math.h>\n\ndouble fdim(double x, double y)\n{\n\tif (isnan(x))\n\t\treturn x;\n\tif (isnan(y))\n\t\treturn y;\n\treturn x > y ? x - y : 0;\n}\n"
  },
  {
    "path": "user.libc/src/math/fdimf.c",
    "content": "#include <math.h>\n\nfloat fdimf(float x, float y)\n{\n\tif (isnan(x))\n\t\treturn x;\n\tif (isnan(y))\n\t\treturn y;\n\treturn x > y ? x - y : 0;\n}\n"
  },
  {
    "path": "user.libc/src/math/fdiml.c",
    "content": "#include <math.h>\n#include <float.h>\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double fdiml(long double x, long double y)\n{\n\treturn fdim(x, y);\n}\n#else\nlong double fdiml(long double x, long double y)\n{\n\tif (isnan(x))\n\t\treturn x;\n\tif (isnan(y))\n\t\treturn y;\n\treturn x > y ? x - y : 0;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/finite.c",
    "content": "#define _GNU_SOURCE\n#include <math.h>\n\nint finite(double x)\n{\n\treturn isfinite(x);\n}\n"
  },
  {
    "path": "user.libc/src/math/finitef.c",
    "content": "#define _GNU_SOURCE\n#include <math.h>\n\nint finitef(float x)\n{\n\treturn isfinite(x);\n}\n"
  },
  {
    "path": "user.libc/src/math/floor.c",
    "content": "#include \"libm.h\"\n\n#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1\n#define EPS DBL_EPSILON\n#elif FLT_EVAL_METHOD==2\n#define EPS LDBL_EPSILON\n#endif\nstatic const double_t toint = 1/EPS;\n\ndouble floor(double x)\n{\n\tunion {double f; uint64_t i;} u = {x};\n\tint e = u.i >> 52 & 0x7ff;\n\tdouble_t y;\n\n\tif (e >= 0x3ff+52 || x == 0)\n\t\treturn x;\n\t/* y = int(x) - x, where int(x) is an integer neighbor of x */\n\tif (u.i >> 63)\n\t\ty = x - toint + toint - x;\n\telse\n\t\ty = x + toint - toint - x;\n\t/* special case because of non-nearest rounding modes */\n\tif (e <= 0x3ff-1) {\n\t\tFORCE_EVAL(y);\n\t\treturn u.i >> 63 ? -1 : 0;\n\t}\n\tif (y > 0)\n\t\treturn x + y - 1;\n\treturn x + y;\n}\n"
  },
  {
    "path": "user.libc/src/math/floorf.c",
    "content": "#include \"libm.h\"\n\nfloat floorf(float x)\n{\n\tunion {float f; uint32_t i;} u = {x};\n\tint e = (int)(u.i >> 23 & 0xff) - 0x7f;\n\tuint32_t m;\n\n\tif (e >= 23)\n\t\treturn x;\n\tif (e >= 0) {\n\t\tm = 0x007fffff >> e;\n\t\tif ((u.i & m) == 0)\n\t\t\treturn x;\n\t\tFORCE_EVAL(x + 0x1p120f);\n\t\tif (u.i >> 31)\n\t\t\tu.i += m;\n\t\tu.i &= ~m;\n\t} else {\n\t\tFORCE_EVAL(x + 0x1p120f);\n\t\tif (u.i >> 31 == 0)\n\t\t\tu.i = 0;\n\t\telse if (u.i << 1)\n\t\t\tu.f = -1.0;\n\t}\n\treturn u.f;\n}\n"
  },
  {
    "path": "user.libc/src/math/floorl.c",
    "content": "#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double floorl(long double x)\n{\n\treturn floor(x);\n}\n#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\n\nstatic const long double toint = 1/LDBL_EPSILON;\n\nlong double floorl(long double x)\n{\n\tunion ldshape u = {x};\n\tint e = u.i.se & 0x7fff;\n\tlong double y;\n\n\tif (e >= 0x3fff+LDBL_MANT_DIG-1 || x == 0)\n\t\treturn x;\n\t/* y = int(x) - x, where int(x) is an integer neighbor of x */\n\tif (u.i.se >> 15)\n\t\ty = x - toint + toint - x;\n\telse\n\t\ty = x + toint - toint - x;\n\t/* special case because of non-nearest rounding modes */\n\tif (e <= 0x3fff-1) {\n\t\tFORCE_EVAL(y);\n\t\treturn u.i.se >> 15 ? -1 : 0;\n\t}\n\tif (y > 0)\n\t\treturn x + y - 1;\n\treturn x + y;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/fma.c",
    "content": "#include <stdint.h>\n#include <float.h>\n#include <math.h>\n#include \"atomic.h\"\n\n#define ASUINT64(x) ((union {double f; uint64_t i;}){x}).i\n#define ZEROINFNAN (0x7ff-0x3ff-52-1)\n\nstruct num { uint64_t m; int e; int sign; };\n\nstatic struct num normalize(double x)\n{\n\tuint64_t ix = ASUINT64(x);\n\tint e = ix>>52;\n\tint sign = e & 0x800;\n\te &= 0x7ff;\n\tif (!e) {\n\t\tix = ASUINT64(x*0x1p63);\n\t\te = ix>>52 & 0x7ff;\n\t\te = e ? e-63 : 0x800;\n\t}\n\tix &= (1ull<<52)-1;\n\tix |= 1ull<<52;\n\tix <<= 1;\n\te -= 0x3ff + 52 + 1;\n\treturn (struct num){ix,e,sign};\n}\n\nstatic void mul(uint64_t *hi, uint64_t *lo, uint64_t x, uint64_t y)\n{\n\tuint64_t t1,t2,t3;\n\tuint64_t xlo = (uint32_t)x, xhi = x>>32;\n\tuint64_t ylo = (uint32_t)y, yhi = y>>32;\n\n\tt1 = xlo*ylo;\n\tt2 = xlo*yhi + xhi*ylo;\n\tt3 = xhi*yhi;\n\t*lo = t1 + (t2<<32);\n\t*hi = t3 + (t2>>32) + (t1 > *lo);\n}\n\ndouble fma(double x, double y, double z)\n{\n\t#pragma STDC FENV_ACCESS ON\n\n\t/* normalize so top 10bits and last bit are 0 */\n\tstruct num nx, ny, nz;\n\tnx = normalize(x);\n\tny = normalize(y);\n\tnz = normalize(z);\n\n\tif (nx.e >= ZEROINFNAN || ny.e >= ZEROINFNAN)\n\t\treturn x*y + z;\n\tif (nz.e >= ZEROINFNAN) {\n\t\tif (nz.e > ZEROINFNAN) /* z==0 */\n\t\t\treturn x*y + z;\n\t\treturn z;\n\t}\n\n\t/* mul: r = x*y */\n\tuint64_t rhi, rlo, zhi, zlo;\n\tmul(&rhi, &rlo, nx.m, ny.m);\n\t/* either top 20 or 21 bits of rhi and last 2 bits of rlo are 0 */\n\n\t/* align exponents */\n\tint e = nx.e + ny.e;\n\tint d = nz.e - e;\n\t/* shift bits z<<=kz, r>>=kr, so kz+kr == d, set e = e+kr (== ez-kz) */\n\tif (d > 0) {\n\t\tif (d < 64) {\n\t\t\tzlo = nz.m<<d;\n\t\t\tzhi = nz.m>>64-d;\n\t\t} else {\n\t\t\tzlo = 0;\n\t\t\tzhi = nz.m;\n\t\t\te = nz.e - 64;\n\t\t\td -= 64;\n\t\t\tif (d == 0) {\n\t\t\t} else if (d < 64) {\n\t\t\t\trlo = rhi<<64-d | rlo>>d | !!(rlo<<64-d);\n\t\t\t\trhi = rhi>>d;\n\t\t\t} else {\n\t\t\t\trlo = 1;\n\t\t\t\trhi = 0;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tzhi = 0;\n\t\td = -d;\n\t\tif (d == 0) {\n\t\t\tzlo = nz.m;\n\t\t} else if (d < 64) {\n\t\t\tzlo = nz.m>>d | !!(nz.m<<64-d);\n\t\t} else {\n\t\t\tzlo = 1;\n\t\t}\n\t}\n\n\t/* add */\n\tint sign = nx.sign^ny.sign;\n\tint samesign = !(sign^nz.sign);\n\tint nonzero = 1;\n\tif (samesign) {\n\t\t/* r += z */\n\t\trlo += zlo;\n\t\trhi += zhi + (rlo < zlo);\n\t} else {\n\t\t/* r -= z */\n\t\tuint64_t t = rlo;\n\t\trlo -= zlo;\n\t\trhi = rhi - zhi - (t < rlo);\n\t\tif (rhi>>63) {\n\t\t\trlo = -rlo;\n\t\t\trhi = -rhi-!!rlo;\n\t\t\tsign = !sign;\n\t\t}\n\t\tnonzero = !!rhi;\n\t}\n\n\t/* set rhi to top 63bit of the result (last bit is sticky) */\n\tif (nonzero) {\n\t\te += 64;\n\t\td = a_clz_64(rhi)-1;\n\t\t/* note: d > 0 */\n\t\trhi = rhi<<d | rlo>>64-d | !!(rlo<<d);\n\t} else if (rlo) {\n\t\td = a_clz_64(rlo)-1;\n\t\tif (d < 0)\n\t\t\trhi = rlo>>1 | (rlo&1);\n\t\telse\n\t\t\trhi = rlo<<d;\n\t} else {\n\t\t/* exact +-0 */\n\t\treturn x*y + z;\n\t}\n\te -= d;\n\n\t/* convert to double */\n\tint64_t i = rhi; /* i is in [1<<62,(1<<63)-1] */\n\tif (sign)\n\t\ti = -i;\n\tdouble r = i; /* |r| is in [0x1p62,0x1p63] */\n\n\tif (e < -1022-62) {\n\t\t/* result is subnormal before rounding */\n\t\tif (e == -1022-63) {\n\t\t\tdouble c = 0x1p63;\n\t\t\tif (sign)\n\t\t\t\tc = -c;\n\t\t\tif (r == c) {\n\t\t\t\t/* min normal after rounding, underflow depends\n\t\t\t\t   on arch behaviour which can be imitated by\n\t\t\t\t   a double to float conversion */\n\t\t\t\tfloat fltmin = 0x0.ffffff8p-63*FLT_MIN * r;\n\t\t\t\treturn DBL_MIN/FLT_MIN * fltmin;\n\t\t\t}\n\t\t\t/* one bit is lost when scaled, add another top bit to\n\t\t\t   only round once at conversion if it is inexact */\n\t\t\tif (rhi << 53) {\n\t\t\t\ti = rhi>>1 | (rhi&1) | 1ull<<62;\n\t\t\t\tif (sign)\n\t\t\t\t\ti = -i;\n\t\t\t\tr = i;\n\t\t\t\tr = 2*r - c; /* remove top bit */\n\n\t\t\t\t/* raise underflow portably, such that it\n\t\t\t\t   cannot be optimized away */\n\t\t\t\t{\n\t\t\t\t\tdouble_t tiny = DBL_MIN/FLT_MIN * r;\n\t\t\t\t\tr += (double)(tiny*tiny) * (r-r);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t/* only round once when scaled */\n\t\t\td = 10;\n\t\t\ti = ( rhi>>d | !!(rhi<<64-d) ) << d;\n\t\t\tif (sign)\n\t\t\t\ti = -i;\n\t\t\tr = i;\n\t\t}\n\t}\n\treturn scalbn(r, e);\n}\n"
  },
  {
    "path": "user.libc/src/math/fmaf.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_fmaf.c */\n/*-\n * Copyright (c) 2005-2011 David Schultz <das@FreeBSD.ORG>\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <fenv.h>\n#include <math.h>\n#include <stdint.h>\n\n/*\n * Fused multiply-add: Compute x * y + z with a single rounding error.\n *\n * A double has more than twice as much precision than a float, so\n * direct double-precision arithmetic suffices, except where double\n * rounding occurs.\n */\nfloat fmaf(float x, float y, float z)\n{\n\t#pragma STDC FENV_ACCESS ON\n\tdouble xy, result;\n\tunion {double f; uint64_t i;} u;\n\tint e;\n\n\txy = (double)x * y;\n\tresult = xy + z;\n\tu.f = result;\n\te = u.i>>52 & 0x7ff;\n\t/* Common case: The double precision result is fine. */\n\tif ((u.i & 0x1fffffff) != 0x10000000 || /* not a halfway case */\n\t\te == 0x7ff ||                   /* NaN */\n\t\t(result - xy == z && result - z == xy) || /* exact */\n\t\tfegetround() != FE_TONEAREST)       /* not round-to-nearest */\n\t{\n\t\t/*\n\t\tunderflow may not be raised correctly, example:\n\t\tfmaf(0x1p-120f, 0x1p-120f, 0x1p-149f)\n\t\t*/\n#if defined(FE_INEXACT) && defined(FE_UNDERFLOW)\n\t\tif (e < 0x3ff-126 && e >= 0x3ff-149 && fetestexcept(FE_INEXACT)) {\n\t\t\tfeclearexcept(FE_INEXACT);\n\t\t\t/* TODO: gcc and clang bug workaround */\n\t\t\tvolatile float vz = z;\n\t\t\tresult = xy + vz;\n\t\t\tif (fetestexcept(FE_INEXACT))\n\t\t\t\tferaiseexcept(FE_UNDERFLOW);\n\t\t\telse\n\t\t\t\tferaiseexcept(FE_INEXACT);\n\t\t}\n#endif\n\t\tz = result;\n\t\treturn z;\n\t}\n\n\t/*\n\t * If result is inexact, and exactly halfway between two float values,\n\t * we need to adjust the low-order bit in the direction of the error.\n\t */\n#ifdef FE_TOWARDZERO\n\tfesetround(FE_TOWARDZERO);\n#endif\n\tvolatile double vxy = xy;  /* XXX work around gcc CSE bug */\n\tdouble adjusted_result = vxy + z;\n\tfesetround(FE_TONEAREST);\n\tif (result == adjusted_result) {\n\t\tu.f = adjusted_result;\n\t\tu.i++;\n\t\tadjusted_result = u.f;\n\t}\n\tz = adjusted_result;\n\treturn z;\n}\n"
  },
  {
    "path": "user.libc/src/math/fmal.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_fmal.c */\n/*-\n * Copyright (c) 2005-2011 David Schultz <das@FreeBSD.ORG>\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n\n#include \"libm.h\"\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double fmal(long double x, long double y, long double z)\n{\n\treturn fma(x, y, z);\n}\n#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\n#include <fenv.h>\n#if LDBL_MANT_DIG == 64\n#define LASTBIT(u) (u.i.m & 1)\n#define SPLIT (0x1p32L + 1)\n#elif LDBL_MANT_DIG == 113\n#define LASTBIT(u) (u.i.lo & 1)\n#define SPLIT (0x1p57L + 1)\n#endif\n\n/*\n * A struct dd represents a floating-point number with twice the precision\n * of a long double.  We maintain the invariant that \"hi\" stores the high-order\n * bits of the result.\n */\nstruct dd {\n\tlong double hi;\n\tlong double lo;\n};\n\n/*\n * Compute a+b exactly, returning the exact result in a struct dd.  We assume\n * that both a and b are finite, but make no assumptions about their relative\n * magnitudes.\n */\nstatic inline struct dd dd_add(long double a, long double b)\n{\n\tstruct dd ret;\n\tlong double s;\n\n\tret.hi = a + b;\n\ts = ret.hi - a;\n\tret.lo = (a - (ret.hi - s)) + (b - s);\n\treturn (ret);\n}\n\n/*\n * Compute a+b, with a small tweak:  The least significant bit of the\n * result is adjusted into a sticky bit summarizing all the bits that\n * were lost to rounding.  This adjustment negates the effects of double\n * rounding when the result is added to another number with a higher\n * exponent.  For an explanation of round and sticky bits, see any reference\n * on FPU design, e.g.,\n *\n *     J. Coonen.  An Implementation Guide to a Proposed Standard for\n *     Floating-Point Arithmetic.  Computer, vol. 13, no. 1, Jan 1980.\n */\nstatic inline long double add_adjusted(long double a, long double b)\n{\n\tstruct dd sum;\n\tunion ldshape u;\n\n\tsum = dd_add(a, b);\n\tif (sum.lo != 0) {\n\t\tu.f = sum.hi;\n\t\tif (!LASTBIT(u))\n\t\t\tsum.hi = nextafterl(sum.hi, INFINITY * sum.lo);\n\t}\n\treturn (sum.hi);\n}\n\n/*\n * Compute ldexp(a+b, scale) with a single rounding error. It is assumed\n * that the result will be subnormal, and care is taken to ensure that\n * double rounding does not occur.\n */\nstatic inline long double add_and_denormalize(long double a, long double b, int scale)\n{\n\tstruct dd sum;\n\tint bits_lost;\n\tunion ldshape u;\n\n\tsum = dd_add(a, b);\n\n\t/*\n\t * If we are losing at least two bits of accuracy to denormalization,\n\t * then the first lost bit becomes a round bit, and we adjust the\n\t * lowest bit of sum.hi to make it a sticky bit summarizing all the\n\t * bits in sum.lo. With the sticky bit adjusted, the hardware will\n\t * break any ties in the correct direction.\n\t *\n\t * If we are losing only one bit to denormalization, however, we must\n\t * break the ties manually.\n\t */\n\tif (sum.lo != 0) {\n\t\tu.f = sum.hi;\n\t\tbits_lost = -u.i.se - scale + 1;\n\t\tif ((bits_lost != 1) ^ LASTBIT(u))\n\t\t\tsum.hi = nextafterl(sum.hi, INFINITY * sum.lo);\n\t}\n\treturn scalbnl(sum.hi, scale);\n}\n\n/*\n * Compute a*b exactly, returning the exact result in a struct dd.  We assume\n * that both a and b are normalized, so no underflow or overflow will occur.\n * The current rounding mode must be round-to-nearest.\n */\nstatic inline struct dd dd_mul(long double a, long double b)\n{\n\tstruct dd ret;\n\tlong double ha, hb, la, lb, p, q;\n\n\tp = a * SPLIT;\n\tha = a - p;\n\tha += p;\n\tla = a - ha;\n\n\tp = b * SPLIT;\n\thb = b - p;\n\thb += p;\n\tlb = b - hb;\n\n\tp = ha * hb;\n\tq = ha * lb + la * hb;\n\n\tret.hi = p + q;\n\tret.lo = p - ret.hi + q + la * lb;\n\treturn (ret);\n}\n\n/*\n * Fused multiply-add: Compute x * y + z with a single rounding error.\n *\n * We use scaling to avoid overflow/underflow, along with the\n * canonical precision-doubling technique adapted from:\n *\n *      Dekker, T.  A Floating-Point Technique for Extending the\n *      Available Precision.  Numer. Math. 18, 224-242 (1971).\n */\nlong double fmal(long double x, long double y, long double z)\n{\n\t#pragma STDC FENV_ACCESS ON\n\tlong double xs, ys, zs, adj;\n\tstruct dd xy, r;\n\tint oround;\n\tint ex, ey, ez;\n\tint spread;\n\n\t/*\n\t * Handle special cases. The order of operations and the particular\n\t * return values here are crucial in handling special cases involving\n\t * infinities, NaNs, overflows, and signed zeroes correctly.\n\t */\n\tif (!isfinite(x) || !isfinite(y))\n\t\treturn (x * y + z);\n\tif (!isfinite(z))\n\t\treturn (z);\n\tif (x == 0.0 || y == 0.0)\n\t\treturn (x * y + z);\n\tif (z == 0.0)\n\t\treturn (x * y);\n\n\txs = frexpl(x, &ex);\n\tys = frexpl(y, &ey);\n\tzs = frexpl(z, &ez);\n\toround = fegetround();\n\tspread = ex + ey - ez;\n\n\t/*\n\t * If x * y and z are many orders of magnitude apart, the scaling\n\t * will overflow, so we handle these cases specially.  Rounding\n\t * modes other than FE_TONEAREST are painful.\n\t */\n\tif (spread < -LDBL_MANT_DIG) {\n#ifdef FE_INEXACT\n\t\tferaiseexcept(FE_INEXACT);\n#endif\n#ifdef FE_UNDERFLOW\n\t\tif (!isnormal(z))\n\t\t\tferaiseexcept(FE_UNDERFLOW);\n#endif\n\t\tswitch (oround) {\n\t\tdefault: /* FE_TONEAREST */\n\t\t\treturn (z);\n#ifdef FE_TOWARDZERO\n\t\tcase FE_TOWARDZERO:\n\t\t\tif (x > 0.0 ^ y < 0.0 ^ z < 0.0)\n\t\t\t\treturn (z);\n\t\t\telse\n\t\t\t\treturn (nextafterl(z, 0));\n#endif\n#ifdef FE_DOWNWARD\n\t\tcase FE_DOWNWARD:\n\t\t\tif (x > 0.0 ^ y < 0.0)\n\t\t\t\treturn (z);\n\t\t\telse\n\t\t\t\treturn (nextafterl(z, -INFINITY));\n#endif\n#ifdef FE_UPWARD\n\t\tcase FE_UPWARD:\n\t\t\tif (x > 0.0 ^ y < 0.0)\n\t\t\t\treturn (nextafterl(z, INFINITY));\n\t\t\telse\n\t\t\t\treturn (z);\n#endif\n\t\t}\n\t}\n\tif (spread <= LDBL_MANT_DIG * 2)\n\t\tzs = scalbnl(zs, -spread);\n\telse\n\t\tzs = copysignl(LDBL_MIN, zs);\n\n\tfesetround(FE_TONEAREST);\n\n\t/*\n\t * Basic approach for round-to-nearest:\n\t *\n\t *     (xy.hi, xy.lo) = x * y           (exact)\n\t *     (r.hi, r.lo)   = xy.hi + z       (exact)\n\t *     adj = xy.lo + r.lo               (inexact; low bit is sticky)\n\t *     result = r.hi + adj              (correctly rounded)\n\t */\n\txy = dd_mul(xs, ys);\n\tr = dd_add(xy.hi, zs);\n\n\tspread = ex + ey;\n\n\tif (r.hi == 0.0) {\n\t\t/*\n\t\t * When the addends cancel to 0, ensure that the result has\n\t\t * the correct sign.\n\t\t */\n\t\tfesetround(oround);\n\t\tvolatile long double vzs = zs; /* XXX gcc CSE bug workaround */\n\t\treturn xy.hi + vzs + scalbnl(xy.lo, spread);\n\t}\n\n\tif (oround != FE_TONEAREST) {\n\t\t/*\n\t\t * There is no need to worry about double rounding in directed\n\t\t * rounding modes.\n\t\t * But underflow may not be raised correctly, example in downward rounding:\n\t\t * fmal(0x1.0000000001p-16000L, 0x1.0000000001p-400L, -0x1p-16440L)\n\t\t */\n\t\tlong double ret;\n#if defined(FE_INEXACT) && defined(FE_UNDERFLOW)\n\t\tint e = fetestexcept(FE_INEXACT);\n\t\tfeclearexcept(FE_INEXACT);\n#endif\n\t\tfesetround(oround);\n\t\tadj = r.lo + xy.lo;\n\t\tret = scalbnl(r.hi + adj, spread);\n#if defined(FE_INEXACT) && defined(FE_UNDERFLOW)\n\t\tif (ilogbl(ret) < -16382 && fetestexcept(FE_INEXACT))\n\t\t\tferaiseexcept(FE_UNDERFLOW);\n\t\telse if (e)\n\t\t\tferaiseexcept(FE_INEXACT);\n#endif\n\t\treturn ret;\n\t}\n\n\tadj = add_adjusted(r.lo, xy.lo);\n\tif (spread + ilogbl(r.hi) > -16383)\n\t\treturn scalbnl(r.hi + adj, spread);\n\telse\n\t\treturn add_and_denormalize(r.hi, adj, spread);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/fmax.c",
    "content": "#include <math.h>\n\ndouble fmax(double x, double y)\n{\n\tif (isnan(x))\n\t\treturn y;\n\tif (isnan(y))\n\t\treturn x;\n\t/* handle signed zeros, see C99 Annex F.9.9.2 */\n\tif (signbit(x) != signbit(y))\n\t\treturn signbit(x) ? y : x;\n\treturn x < y ? y : x;\n}\n"
  },
  {
    "path": "user.libc/src/math/fmaxf.c",
    "content": "#include <math.h>\n\nfloat fmaxf(float x, float y)\n{\n\tif (isnan(x))\n\t\treturn y;\n\tif (isnan(y))\n\t\treturn x;\n\t/* handle signed zeroes, see C99 Annex F.9.9.2 */\n\tif (signbit(x) != signbit(y))\n\t\treturn signbit(x) ? y : x;\n\treturn x < y ? y : x;\n}\n"
  },
  {
    "path": "user.libc/src/math/fmaxl.c",
    "content": "#include <math.h>\n#include <float.h>\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double fmaxl(long double x, long double y)\n{\n\treturn fmax(x, y);\n}\n#else\nlong double fmaxl(long double x, long double y)\n{\n\tif (isnan(x))\n\t\treturn y;\n\tif (isnan(y))\n\t\treturn x;\n\t/* handle signed zeros, see C99 Annex F.9.9.2 */\n\tif (signbit(x) != signbit(y))\n\t\treturn signbit(x) ? y : x;\n\treturn x < y ? y : x;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/fmin.c",
    "content": "#include <math.h>\n\ndouble fmin(double x, double y)\n{\n\tif (isnan(x))\n\t\treturn y;\n\tif (isnan(y))\n\t\treturn x;\n\t/* handle signed zeros, see C99 Annex F.9.9.2 */\n\tif (signbit(x) != signbit(y))\n\t\treturn signbit(x) ? x : y;\n\treturn x < y ? x : y;\n}\n"
  },
  {
    "path": "user.libc/src/math/fminf.c",
    "content": "#include <math.h>\n\nfloat fminf(float x, float y)\n{\n\tif (isnan(x))\n\t\treturn y;\n\tif (isnan(y))\n\t\treturn x;\n\t/* handle signed zeros, see C99 Annex F.9.9.2 */\n\tif (signbit(x) != signbit(y))\n\t\treturn signbit(x) ? x : y;\n\treturn x < y ? x : y;\n}\n"
  },
  {
    "path": "user.libc/src/math/fminl.c",
    "content": "#include <math.h>\n#include <float.h>\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double fminl(long double x, long double y)\n{\n\treturn fmin(x, y);\n}\n#else\nlong double fminl(long double x, long double y)\n{\n\tif (isnan(x))\n\t\treturn y;\n\tif (isnan(y))\n\t\treturn x;\n\t/* handle signed zeros, see C99 Annex F.9.9.2 */\n\tif (signbit(x) != signbit(y))\n\t\treturn signbit(x) ? x : y;\n\treturn x < y ? x : y;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/fmod.c",
    "content": "#include <math.h>\n#include <stdint.h>\n\ndouble fmod(double x, double y)\n{\n\tunion {double f; uint64_t i;} ux = {x}, uy = {y};\n\tint ex = ux.i>>52 & 0x7ff;\n\tint ey = uy.i>>52 & 0x7ff;\n\tint sx = ux.i>>63;\n\tuint64_t i;\n\n\t/* in the followings uxi should be ux.i, but then gcc wrongly adds */\n\t/* float load/store to inner loops ruining performance and code size */\n\tuint64_t uxi = ux.i;\n\n\tif (uy.i<<1 == 0 || isnan(y) || ex == 0x7ff)\n\t\treturn (x*y)/(x*y);\n\tif (uxi<<1 <= uy.i<<1) {\n\t\tif (uxi<<1 == uy.i<<1)\n\t\t\treturn 0*x;\n\t\treturn x;\n\t}\n\n\t/* normalize x and y */\n\tif (!ex) {\n\t\tfor (i = uxi<<12; i>>63 == 0; ex--, i <<= 1);\n\t\tuxi <<= -ex + 1;\n\t} else {\n\t\tuxi &= -1ULL >> 12;\n\t\tuxi |= 1ULL << 52;\n\t}\n\tif (!ey) {\n\t\tfor (i = uy.i<<12; i>>63 == 0; ey--, i <<= 1);\n\t\tuy.i <<= -ey + 1;\n\t} else {\n\t\tuy.i &= -1ULL >> 12;\n\t\tuy.i |= 1ULL << 52;\n\t}\n\n\t/* x mod y */\n\tfor (; ex > ey; ex--) {\n\t\ti = uxi - uy.i;\n\t\tif (i >> 63 == 0) {\n\t\t\tif (i == 0)\n\t\t\t\treturn 0*x;\n\t\t\tuxi = i;\n\t\t}\n\t\tuxi <<= 1;\n\t}\n\ti = uxi - uy.i;\n\tif (i >> 63 == 0) {\n\t\tif (i == 0)\n\t\t\treturn 0*x;\n\t\tuxi = i;\n\t}\n\tfor (; uxi>>52 == 0; uxi <<= 1, ex--);\n\n\t/* scale result */\n\tif (ex > 0) {\n\t\tuxi -= 1ULL << 52;\n\t\tuxi |= (uint64_t)ex << 52;\n\t} else {\n\t\tuxi >>= -ex + 1;\n\t}\n\tuxi |= (uint64_t)sx << 63;\n\tux.i = uxi;\n\treturn ux.f;\n}\n"
  },
  {
    "path": "user.libc/src/math/fmodf.c",
    "content": "#include <math.h>\n#include <stdint.h>\n\nfloat fmodf(float x, float y)\n{\n\tunion {float f; uint32_t i;} ux = {x}, uy = {y};\n\tint ex = ux.i>>23 & 0xff;\n\tint ey = uy.i>>23 & 0xff;\n\tuint32_t sx = ux.i & 0x80000000;\n\tuint32_t i;\n\tuint32_t uxi = ux.i;\n\n\tif (uy.i<<1 == 0 || isnan(y) || ex == 0xff)\n\t\treturn (x*y)/(x*y);\n\tif (uxi<<1 <= uy.i<<1) {\n\t\tif (uxi<<1 == uy.i<<1)\n\t\t\treturn 0*x;\n\t\treturn x;\n\t}\n\n\t/* normalize x and y */\n\tif (!ex) {\n\t\tfor (i = uxi<<9; i>>31 == 0; ex--, i <<= 1);\n\t\tuxi <<= -ex + 1;\n\t} else {\n\t\tuxi &= -1U >> 9;\n\t\tuxi |= 1U << 23;\n\t}\n\tif (!ey) {\n\t\tfor (i = uy.i<<9; i>>31 == 0; ey--, i <<= 1);\n\t\tuy.i <<= -ey + 1;\n\t} else {\n\t\tuy.i &= -1U >> 9;\n\t\tuy.i |= 1U << 23;\n\t}\n\n\t/* x mod y */\n\tfor (; ex > ey; ex--) {\n\t\ti = uxi - uy.i;\n\t\tif (i >> 31 == 0) {\n\t\t\tif (i == 0)\n\t\t\t\treturn 0*x;\n\t\t\tuxi = i;\n\t\t}\n\t\tuxi <<= 1;\n\t}\n\ti = uxi - uy.i;\n\tif (i >> 31 == 0) {\n\t\tif (i == 0)\n\t\t\treturn 0*x;\n\t\tuxi = i;\n\t}\n\tfor (; uxi>>23 == 0; uxi <<= 1, ex--);\n\n\t/* scale result up */\n\tif (ex > 0) {\n\t\tuxi -= 1U << 23;\n\t\tuxi |= (uint32_t)ex << 23;\n\t} else {\n\t\tuxi >>= -ex + 1;\n\t}\n\tuxi |= sx;\n\tux.i = uxi;\n\treturn ux.f;\n}\n"
  },
  {
    "path": "user.libc/src/math/fmodl.c",
    "content": "#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double fmodl(long double x, long double y)\n{\n\treturn fmod(x, y);\n}\n#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\nlong double fmodl(long double x, long double y)\n{\n\tunion ldshape ux = {x}, uy = {y};\n\tint ex = ux.i.se & 0x7fff;\n\tint ey = uy.i.se & 0x7fff;\n\tint sx = ux.i.se & 0x8000;\n\n\tif (y == 0 || isnan(y) || ex == 0x7fff)\n\t\treturn (x*y)/(x*y);\n\tux.i.se = ex;\n\tuy.i.se = ey;\n\tif (ux.f <= uy.f) {\n\t\tif (ux.f == uy.f)\n\t\t\treturn 0*x;\n\t\treturn x;\n\t}\n\n\t/* normalize x and y */\n\tif (!ex) {\n\t\tux.f *= 0x1p120f;\n\t\tex = ux.i.se - 120;\n\t}\n\tif (!ey) {\n\t\tuy.f *= 0x1p120f;\n\t\tey = uy.i.se - 120;\n\t}\n\n\t/* x mod y */\n#if LDBL_MANT_DIG == 64\n\tuint64_t i, mx, my;\n\tmx = ux.i.m;\n\tmy = uy.i.m;\n\tfor (; ex > ey; ex--) {\n\t\ti = mx - my;\n\t\tif (mx >= my) {\n\t\t\tif (i == 0)\n\t\t\t\treturn 0*x;\n\t\t\tmx = 2*i;\n\t\t} else if (2*mx < mx) {\n\t\t\tmx = 2*mx - my;\n\t\t} else {\n\t\t\tmx = 2*mx;\n\t\t}\n\t}\n\ti = mx - my;\n\tif (mx >= my) {\n\t\tif (i == 0)\n\t\t\treturn 0*x;\n\t\tmx = i;\n\t}\n\tfor (; mx >> 63 == 0; mx *= 2, ex--);\n\tux.i.m = mx;\n#elif LDBL_MANT_DIG == 113\n\tuint64_t hi, lo, xhi, xlo, yhi, ylo;\n\txhi = (ux.i2.hi & -1ULL>>16) | 1ULL<<48;\n\tyhi = (uy.i2.hi & -1ULL>>16) | 1ULL<<48;\n\txlo = ux.i2.lo;\n\tylo = uy.i2.lo;\n\tfor (; ex > ey; ex--) {\n\t\thi = xhi - yhi;\n\t\tlo = xlo - ylo;\n\t\tif (xlo < ylo)\n\t\t\thi -= 1;\n\t\tif (hi >> 63 == 0) {\n\t\t\tif ((hi|lo) == 0)\n\t\t\t\treturn 0*x;\n\t\t\txhi = 2*hi + (lo>>63);\n\t\t\txlo = 2*lo;\n\t\t} else {\n\t\t\txhi = 2*xhi + (xlo>>63);\n\t\t\txlo = 2*xlo;\n\t\t}\n\t}\n\thi = xhi - yhi;\n\tlo = xlo - ylo;\n\tif (xlo < ylo)\n\t\thi -= 1;\n\tif (hi >> 63 == 0) {\n\t\tif ((hi|lo) == 0)\n\t\t\treturn 0*x;\n\t\txhi = hi;\n\t\txlo = lo;\n\t}\n\tfor (; xhi >> 48 == 0; xhi = 2*xhi + (xlo>>63), xlo = 2*xlo, ex--);\n\tux.i2.hi = xhi;\n\tux.i2.lo = xlo;\n#endif\n\n\t/* scale result */\n\tif (ex <= 0) {\n\t\tux.i.se = (ex+120)|sx;\n\t\tux.f *= 0x1p-120f;\n\t} else\n\t\tux.i.se = ex|sx;\n\treturn ux.f;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/frexp.c",
    "content": "#include <math.h>\n#include <stdint.h>\n\ndouble frexp(double x, int *e)\n{\n\tunion { double d; uint64_t i; } y = { x };\n\tint ee = y.i>>52 & 0x7ff;\n\n\tif (!ee) {\n\t\tif (x) {\n\t\t\tx = frexp(x*0x1p64, e);\n\t\t\t*e -= 64;\n\t\t} else *e = 0;\n\t\treturn x;\n\t} else if (ee == 0x7ff) {\n\t\treturn x;\n\t}\n\n\t*e = ee - 0x3fe;\n\ty.i &= 0x800fffffffffffffull;\n\ty.i |= 0x3fe0000000000000ull;\n\treturn y.d;\n}\n"
  },
  {
    "path": "user.libc/src/math/frexpf.c",
    "content": "#include <math.h>\n#include <stdint.h>\n\nfloat frexpf(float x, int *e)\n{\n\tunion { float f; uint32_t i; } y = { x };\n\tint ee = y.i>>23 & 0xff;\n\n\tif (!ee) {\n\t\tif (x) {\n\t\t\tx = frexpf(x*0x1p64, e);\n\t\t\t*e -= 64;\n\t\t} else *e = 0;\n\t\treturn x;\n\t} else if (ee == 0xff) {\n\t\treturn x;\n\t}\n\n\t*e = ee - 0x7e;\n\ty.i &= 0x807ffffful;\n\ty.i |= 0x3f000000ul;\n\treturn y.f;\n}\n"
  },
  {
    "path": "user.libc/src/math/frexpl.c",
    "content": "#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double frexpl(long double x, int *e)\n{\n\treturn frexp(x, e);\n}\n#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\nlong double frexpl(long double x, int *e)\n{\n\tunion ldshape u = {x};\n\tint ee = u.i.se & 0x7fff;\n\n\tif (!ee) {\n\t\tif (x) {\n\t\t\tx = frexpl(x*0x1p120, e);\n\t\t\t*e -= 120;\n\t\t} else *e = 0;\n\t\treturn x;\n\t} else if (ee == 0x7fff) {\n\t\treturn x;\n\t}\n\n\t*e = ee - 0x3ffe;\n\tu.i.se &= 0x8000;\n\tu.i.se |= 0x3ffe;\n\treturn u.f;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/hypot.c",
    "content": "#include <math.h>\n#include <stdint.h>\n#include <float.h>\n\n#if FLT_EVAL_METHOD > 1U && LDBL_MANT_DIG == 64\n#define SPLIT (0x1p32 + 1)\n#else\n#define SPLIT (0x1p27 + 1)\n#endif\n\nstatic void sq(double_t *hi, double_t *lo, double x)\n{\n\tdouble_t xh, xl, xc;\n\n\txc = (double_t)x*SPLIT;\n\txh = x - xc + xc;\n\txl = x - xh;\n\t*hi = (double_t)x*x;\n\t*lo = xh*xh - *hi + 2*xh*xl + xl*xl;\n}\n\ndouble hypot(double x, double y)\n{\n\tunion {double f; uint64_t i;} ux = {x}, uy = {y}, ut;\n\tint ex, ey;\n\tdouble_t hx, lx, hy, ly, z;\n\n\t/* arrange |x| >= |y| */\n\tux.i &= -1ULL>>1;\n\tuy.i &= -1ULL>>1;\n\tif (ux.i < uy.i) {\n\t\tut = ux;\n\t\tux = uy;\n\t\tuy = ut;\n\t}\n\n\t/* special cases */\n\tex = ux.i>>52;\n\tey = uy.i>>52;\n\tx = ux.f;\n\ty = uy.f;\n\t/* note: hypot(inf,nan) == inf */\n\tif (ey == 0x7ff)\n\t\treturn y;\n\tif (ex == 0x7ff || uy.i == 0)\n\t\treturn x;\n\t/* note: hypot(x,y) ~= x + y*y/x/2 with inexact for small y/x */\n\t/* 64 difference is enough for ld80 double_t */\n\tif (ex - ey > 64)\n\t\treturn x + y;\n\n\t/* precise sqrt argument in nearest rounding mode without overflow */\n\t/* xh*xh must not overflow and xl*xl must not underflow in sq */\n\tz = 1;\n\tif (ex > 0x3ff+510) {\n\t\tz = 0x1p700;\n\t\tx *= 0x1p-700;\n\t\ty *= 0x1p-700;\n\t} else if (ey < 0x3ff-450) {\n\t\tz = 0x1p-700;\n\t\tx *= 0x1p700;\n\t\ty *= 0x1p700;\n\t}\n\tsq(&hx, &lx, x);\n\tsq(&hy, &ly, y);\n\treturn z*sqrt(ly+lx+hy+hx);\n}\n"
  },
  {
    "path": "user.libc/src/math/hypotf.c",
    "content": "#include <math.h>\n#include <stdint.h>\n\nfloat hypotf(float x, float y)\n{\n\tunion {float f; uint32_t i;} ux = {x}, uy = {y}, ut;\n\tfloat_t z;\n\n\tux.i &= -1U>>1;\n\tuy.i &= -1U>>1;\n\tif (ux.i < uy.i) {\n\t\tut = ux;\n\t\tux = uy;\n\t\tuy = ut;\n\t}\n\n\tx = ux.f;\n\ty = uy.f;\n\tif (uy.i == 0xff<<23)\n\t\treturn y;\n\tif (ux.i >= 0xff<<23 || uy.i == 0 || ux.i - uy.i >= 25<<23)\n\t\treturn x + y;\n\n\tz = 1;\n\tif (ux.i >= (0x7f+60)<<23) {\n\t\tz = 0x1p90f;\n\t\tx *= 0x1p-90f;\n\t\ty *= 0x1p-90f;\n\t} else if (uy.i < (0x7f-60)<<23) {\n\t\tz = 0x1p-90f;\n\t\tx *= 0x1p90f;\n\t\ty *= 0x1p90f;\n\t}\n\treturn z*sqrtf((double)x*x + (double)y*y);\n}\n"
  },
  {
    "path": "user.libc/src/math/hypotl.c",
    "content": "#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double hypotl(long double x, long double y)\n{\n\treturn hypot(x, y);\n}\n#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\n#if LDBL_MANT_DIG == 64\n#define SPLIT (0x1p32L+1)\n#elif LDBL_MANT_DIG == 113\n#define SPLIT (0x1p57L+1)\n#endif\n\nstatic void sq(long double *hi, long double *lo, long double x)\n{\n\tlong double xh, xl, xc;\n\txc = x*SPLIT;\n\txh = x - xc + xc;\n\txl = x - xh;\n\t*hi = x*x;\n\t*lo = xh*xh - *hi + 2*xh*xl + xl*xl;\n}\n\nlong double hypotl(long double x, long double y)\n{\n\tunion ldshape ux = {x}, uy = {y};\n\tint ex, ey;\n\tlong double hx, lx, hy, ly, z;\n\n\tux.i.se &= 0x7fff;\n\tuy.i.se &= 0x7fff;\n\tif (ux.i.se < uy.i.se) {\n\t\tex = uy.i.se;\n\t\tey = ux.i.se;\n\t\tx = uy.f;\n\t\ty = ux.f;\n\t} else {\n\t\tex = ux.i.se;\n\t\tey = uy.i.se;\n\t\tx = ux.f;\n\t\ty = uy.f;\n\t}\n\n\tif (ex == 0x7fff && isinf(y))\n\t\treturn y;\n\tif (ex == 0x7fff || y == 0)\n\t\treturn x;\n\tif (ex - ey > LDBL_MANT_DIG)\n\t\treturn x + y;\n\n\tz = 1;\n\tif (ex > 0x3fff+8000) {\n\t\tz = 0x1p10000L;\n\t\tx *= 0x1p-10000L;\n\t\ty *= 0x1p-10000L;\n\t} else if (ey < 0x3fff-8000) {\n\t\tz = 0x1p-10000L;\n\t\tx *= 0x1p10000L;\n\t\ty *= 0x1p10000L;\n\t}\n\tsq(&hx, &lx, x);\n\tsq(&hy, &ly, y);\n\treturn z*sqrtl(ly+lx+hy+hx);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/i386/fabs.c",
    "content": "#include <math.h>\n\ndouble fabs(double x)\n{\n\t__asm__ (\"fabs\" : \"+t\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/i386/fabsf.c",
    "content": "#include <math.h>\n\nfloat fabsf(float x)\n{\n\t__asm__ (\"fabs\" : \"+t\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/i386/fabsl.c",
    "content": "#include <math.h>\n\nlong double fabsl(long double x)\n{\n\t__asm__ (\"fabs\" : \"+t\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/i386/fmod.c",
    "content": "#include <math.h>\n\ndouble fmod(double x, double y)\n{\n\tunsigned short fpsr;\n\t// fprem does not introduce excess precision into x\n\tdo __asm__ (\"fprem; fnstsw %%ax\" : \"+t\"(x), \"=a\"(fpsr) : \"u\"(y));\n\twhile (fpsr & 0x400);\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/i386/fmodf.c",
    "content": "#include <math.h>\n\nfloat fmodf(float x, float y)\n{\n\tunsigned short fpsr;\n\t// fprem does not introduce excess precision into x\n\tdo __asm__ (\"fprem; fnstsw %%ax\" : \"+t\"(x), \"=a\"(fpsr) : \"u\"(y));\n\twhile (fpsr & 0x400);\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/i386/fmodl.c",
    "content": "#include <math.h>\n\nlong double fmodl(long double x, long double y)\n{\n\tunsigned short fpsr;\n\tdo __asm__ (\"fprem; fnstsw %%ax\" : \"+t\"(x), \"=a\"(fpsr) : \"u\"(y));\n\twhile (fpsr & 0x400);\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/i386/llrint.c",
    "content": "#include <math.h>\n\nlong long llrint(double x)\n{\n\tlong long r;\n\t__asm__ (\"fistpll %0\" : \"=m\"(r) : \"t\"(x) : \"st\");\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/src/math/i386/llrintf.c",
    "content": "#include <math.h>\n\nlong long llrintf(float x)\n{\n\tlong long r;\n\t__asm__ (\"fistpll %0\" : \"=m\"(r) : \"t\"(x) : \"st\");\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/src/math/i386/llrintl.c",
    "content": "#include <math.h>\n\nlong long llrintl(long double x)\n{\n\tlong long r;\n\t__asm__ (\"fistpll %0\" : \"=m\"(r) : \"t\"(x) : \"st\");\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/src/math/i386/lrint.c",
    "content": "#include <math.h>\n\nlong lrint(double x)\n{\n\tlong r;\n\t__asm__ (\"fistpl %0\" : \"=m\"(r) : \"t\"(x) : \"st\");\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/src/math/i386/lrintf.c",
    "content": "#include <math.h>\n\nlong lrintf(float x)\n{\n\tlong r;\n\t__asm__ (\"fistpl %0\" : \"=m\"(r) : \"t\"(x) : \"st\");\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/src/math/i386/lrintl.c",
    "content": "#include <math.h>\n\nlong lrintl(long double x)\n{\n\tlong r;\n\t__asm__ (\"fistpl %0\" : \"=m\"(r) : \"t\"(x) : \"st\");\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/src/math/i386/remainder.c",
    "content": "#include <math.h>\n\ndouble remainder(double x, double y)\n{\n\tunsigned short fpsr;\n\t// fprem1 does not introduce excess precision into x\n\tdo __asm__ (\"fprem1; fnstsw %%ax\" : \"+t\"(x), \"=a\"(fpsr) : \"u\"(y));\n\twhile (fpsr & 0x400);\n\treturn x;\n}\n\nweak_alias(remainder, drem);\n"
  },
  {
    "path": "user.libc/src/math/i386/remainderf.c",
    "content": "#include <math.h>\n\nfloat remainderf(float x, float y)\n{\n\tunsigned short fpsr;\n\t// fprem1 does not introduce excess precision into x\n\tdo __asm__ (\"fprem1; fnstsw %%ax\" : \"+t\"(x), \"=a\"(fpsr) : \"u\"(y));\n\twhile (fpsr & 0x400);\n\treturn x;\n}\n\nweak_alias(remainderf, dremf);\n"
  },
  {
    "path": "user.libc/src/math/i386/remainderl.c",
    "content": "#include <math.h>\n\nlong double remainderl(long double x, long double y)\n{\n\tunsigned short fpsr;\n\tdo __asm__ (\"fprem1; fnstsw %%ax\" : \"+t\"(x), \"=a\"(fpsr) : \"u\"(y));\n\twhile (fpsr & 0x400);\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/i386/rint.c",
    "content": "#include <math.h>\n\ndouble rint(double x)\n{\n\t__asm__ (\"frndint\" : \"+t\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/i386/rintf.c",
    "content": "#include <math.h>\n\nfloat rintf(float x)\n{\n\t__asm__ (\"frndint\" : \"+t\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/i386/rintl.c",
    "content": "#include <math.h>\n\nlong double rintl(long double x)\n{\n\t__asm__ (\"frndint\" : \"+t\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/i386/sqrt.c",
    "content": "#include \"libm.h\"\n\ndouble sqrt(double x)\n{\n\tunion ldshape ux;\n\tunsigned fpsr;\n\t__asm__ (\"fsqrt; fnstsw %%ax\": \"=t\"(ux.f), \"=a\"(fpsr) : \"0\"(x));\n\tif ((ux.i.m & 0x7ff) != 0x400)\n\t\treturn (double)ux.f;\n\t/* Rounding to double would have encountered an exact halfway case.\n\t   Adjust mantissa downwards if fsqrt rounded up, else upwards.\n\t   (result of fsqrt could not have been exact) */\n\tux.i.m ^= (fpsr & 0x200) + 0x300;\n\treturn (double)ux.f;\n}\n"
  },
  {
    "path": "user.libc/src/math/i386/sqrtf.c",
    "content": "#include <math.h>\n\nfloat sqrtf(float x)\n{\n\tlong double t;\n\t/* The long double result has sufficient precision so that\n\t * second rounding to float still keeps the returned value\n\t * correctly rounded, see Pierre Roux, \"Innocuous Double\n\t * Rounding of Basic Arithmetic Operations\". */\n\t__asm__ (\"fsqrt\" : \"=t\"(t) : \"0\"(x));\n\treturn (float)t;\n}\n"
  },
  {
    "path": "user.libc/src/math/i386/sqrtl.c",
    "content": "#include <math.h>\n\nlong double sqrtl(long double x)\n{\n\t__asm__ (\"fsqrt\" : \"+t\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/ilogb.c",
    "content": "#include <limits.h>\n#include \"libm.h\"\n\nint ilogb(double x)\n{\n\t#pragma STDC FENV_ACCESS ON\n\tunion {double f; uint64_t i;} u = {x};\n\tuint64_t i = u.i;\n\tint e = i>>52 & 0x7ff;\n\n\tif (!e) {\n\t\ti <<= 12;\n\t\tif (i == 0) {\n\t\t\tFORCE_EVAL(0/0.0f);\n\t\t\treturn FP_ILOGB0;\n\t\t}\n\t\t/* subnormal x */\n\t\tfor (e = -0x3ff; i>>63 == 0; e--, i<<=1);\n\t\treturn e;\n\t}\n\tif (e == 0x7ff) {\n\t\tFORCE_EVAL(0/0.0f);\n\t\treturn i<<12 ? FP_ILOGBNAN : INT_MAX;\n\t}\n\treturn e - 0x3ff;\n}\n"
  },
  {
    "path": "user.libc/src/math/ilogbf.c",
    "content": "#include <limits.h>\n#include \"libm.h\"\n\nint ilogbf(float x)\n{\n\t#pragma STDC FENV_ACCESS ON\n\tunion {float f; uint32_t i;} u = {x};\n\tuint32_t i = u.i;\n\tint e = i>>23 & 0xff;\n\n\tif (!e) {\n\t\ti <<= 9;\n\t\tif (i == 0) {\n\t\t\tFORCE_EVAL(0/0.0f);\n\t\t\treturn FP_ILOGB0;\n\t\t}\n\t\t/* subnormal x */\n\t\tfor (e = -0x7f; i>>31 == 0; e--, i<<=1);\n\t\treturn e;\n\t}\n\tif (e == 0xff) {\n\t\tFORCE_EVAL(0/0.0f);\n\t\treturn i<<9 ? FP_ILOGBNAN : INT_MAX;\n\t}\n\treturn e - 0x7f;\n}\n"
  },
  {
    "path": "user.libc/src/math/ilogbl.c",
    "content": "#include <limits.h>\n#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nint ilogbl(long double x)\n{\n\treturn ilogb(x);\n}\n#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384\nint ilogbl(long double x)\n{\n\t#pragma STDC FENV_ACCESS ON\n\tunion ldshape u = {x};\n\tuint64_t m = u.i.m;\n\tint e = u.i.se & 0x7fff;\n\n\tif (!e) {\n\t\tif (m == 0) {\n\t\t\tFORCE_EVAL(0/0.0f);\n\t\t\treturn FP_ILOGB0;\n\t\t}\n\t\t/* subnormal x */\n\t\tfor (e = -0x3fff+1; m>>63 == 0; e--, m<<=1);\n\t\treturn e;\n\t}\n\tif (e == 0x7fff) {\n\t\tFORCE_EVAL(0/0.0f);\n\t\treturn m<<1 ? FP_ILOGBNAN : INT_MAX;\n\t}\n\treturn e - 0x3fff;\n}\n#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384\nint ilogbl(long double x)\n{\n\t#pragma STDC FENV_ACCESS ON\n\tunion ldshape u = {x};\n\tint e = u.i.se & 0x7fff;\n\n\tif (!e) {\n\t\tif (x == 0) {\n\t\t\tFORCE_EVAL(0/0.0f);\n\t\t\treturn FP_ILOGB0;\n\t\t}\n\t\t/* subnormal x */\n\t\tx *= 0x1p120;\n\t\treturn ilogbl(x) - 120;\n\t}\n\tif (e == 0x7fff) {\n\t\tFORCE_EVAL(0/0.0f);\n\t\tu.i.se = 0;\n\t\treturn u.f ? FP_ILOGBNAN : INT_MAX;\n\t}\n\treturn e - 0x3fff;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/j0.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/e_j0.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunSoft, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/* j0(x), y0(x)\n * Bessel function of the first and second kinds of order zero.\n * Method -- j0(x):\n *      1. For tiny x, we use j0(x) = 1 - x^2/4 + x^4/64 - ...\n *      2. Reduce x to |x| since j0(x)=j0(-x),  and\n *         for x in (0,2)\n *              j0(x) = 1-z/4+ z^2*R0/S0,  where z = x*x;\n *         (precision:  |j0-1+z/4-z^2R0/S0 |<2**-63.67 )\n *         for x in (2,inf)\n *              j0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)-q0(x)*sin(x0))\n *         where x0 = x-pi/4. It is better to compute sin(x0),cos(x0)\n *         as follow:\n *              cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4)\n *                      = 1/sqrt(2) * (cos(x) + sin(x))\n *              sin(x0) = sin(x)cos(pi/4)-cos(x)sin(pi/4)\n *                      = 1/sqrt(2) * (sin(x) - cos(x))\n *         (To avoid cancellation, use\n *              sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))\n *          to compute the worse one.)\n *\n *      3 Special cases\n *              j0(nan)= nan\n *              j0(0) = 1\n *              j0(inf) = 0\n *\n * Method -- y0(x):\n *      1. For x<2.\n *         Since\n *              y0(x) = 2/pi*(j0(x)*(ln(x/2)+Euler) + x^2/4 - ...)\n *         therefore y0(x)-2/pi*j0(x)*ln(x) is an even function.\n *         We use the following function to approximate y0,\n *              y0(x) = U(z)/V(z) + (2/pi)*(j0(x)*ln(x)), z= x^2\n *         where\n *              U(z) = u00 + u01*z + ... + u06*z^6\n *              V(z) = 1  + v01*z + ... + v04*z^4\n *         with absolute approximation error bounded by 2**-72.\n *         Note: For tiny x, U/V = u0 and j0(x)~1, hence\n *              y0(tiny) = u0 + (2/pi)*ln(tiny), (choose tiny<2**-27)\n *      2. For x>=2.\n *              y0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)+q0(x)*sin(x0))\n *         where x0 = x-pi/4. It is better to compute sin(x0),cos(x0)\n *         by the method mentioned above.\n *      3. Special cases: y0(0)=-inf, y0(x<0)=NaN, y0(inf)=0.\n */\n\n#include \"libm.h\"\n\nstatic double pzero(double), qzero(double);\n\nstatic const double\ninvsqrtpi = 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */\ntpi       = 6.36619772367581382433e-01; /* 0x3FE45F30, 0x6DC9C883 */\n\n/* common method when |x|>=2 */\nstatic double common(uint32_t ix, double x, int y0)\n{\n\tdouble s,c,ss,cc,z;\n\n\t/*\n\t * j0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x-pi/4)-q0(x)*sin(x-pi/4))\n\t * y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x-pi/4)+q0(x)*cos(x-pi/4))\n\t *\n\t * sin(x-pi/4) = (sin(x) - cos(x))/sqrt(2)\n\t * cos(x-pi/4) = (sin(x) + cos(x))/sqrt(2)\n\t * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))\n\t */\n\ts = sin(x);\n\tc = cos(x);\n\tif (y0)\n\t\tc = -c;\n\tcc = s+c;\n\t/* avoid overflow in 2*x, big ulp error when x>=0x1p1023 */\n\tif (ix < 0x7fe00000) {\n\t\tss = s-c;\n\t\tz = -cos(2*x);\n\t\tif (s*c < 0)\n\t\t\tcc = z/ss;\n\t\telse\n\t\t\tss = z/cc;\n\t\tif (ix < 0x48000000) {\n\t\t\tif (y0)\n\t\t\t\tss = -ss;\n\t\t\tcc = pzero(x)*cc-qzero(x)*ss;\n\t\t}\n\t}\n\treturn invsqrtpi*cc/sqrt(x);\n}\n\n/* R0/S0 on [0, 2.00] */\nstatic const double\nR02 =  1.56249999999999947958e-02, /* 0x3F8FFFFF, 0xFFFFFFFD */\nR03 = -1.89979294238854721751e-04, /* 0xBF28E6A5, 0xB61AC6E9 */\nR04 =  1.82954049532700665670e-06, /* 0x3EBEB1D1, 0x0C503919 */\nR05 = -4.61832688532103189199e-09, /* 0xBE33D5E7, 0x73D63FCE */\nS01 =  1.56191029464890010492e-02, /* 0x3F8FFCE8, 0x82C8C2A4 */\nS02 =  1.16926784663337450260e-04, /* 0x3F1EA6D2, 0xDD57DBF4 */\nS03 =  5.13546550207318111446e-07, /* 0x3EA13B54, 0xCE84D5A9 */\nS04 =  1.16614003333790000205e-09; /* 0x3E1408BC, 0xF4745D8F */\n\ndouble j0(double x)\n{\n\tdouble z,r,s;\n\tuint32_t ix;\n\n\tGET_HIGH_WORD(ix, x);\n\tix &= 0x7fffffff;\n\n\t/* j0(+-inf)=0, j0(nan)=nan */\n\tif (ix >= 0x7ff00000)\n\t\treturn 1/(x*x);\n\tx = fabs(x);\n\n\tif (ix >= 0x40000000) {  /* |x| >= 2 */\n\t\t/* large ulp error near zeros: 2.4, 5.52, 8.6537,.. */\n\t\treturn common(ix,x,0);\n\t}\n\n\t/* 1 - x*x/4 + x*x*R(x^2)/S(x^2) */\n\tif (ix >= 0x3f200000) {  /* |x| >= 2**-13 */\n\t\t/* up to 4ulp error close to 2 */\n\t\tz = x*x;\n\t\tr = z*(R02+z*(R03+z*(R04+z*R05)));\n\t\ts = 1+z*(S01+z*(S02+z*(S03+z*S04)));\n\t\treturn (1+x/2)*(1-x/2) + z*(r/s);\n\t}\n\n\t/* 1 - x*x/4 */\n\t/* prevent underflow */\n\t/* inexact should be raised when x!=0, this is not done correctly */\n\tif (ix >= 0x38000000)  /* |x| >= 2**-127 */\n\t\tx = 0.25*x*x;\n\treturn 1 - x;\n}\n\nstatic const double\nu00  = -7.38042951086872317523e-02, /* 0xBFB2E4D6, 0x99CBD01F */\nu01  =  1.76666452509181115538e-01, /* 0x3FC69D01, 0x9DE9E3FC */\nu02  = -1.38185671945596898896e-02, /* 0xBF8C4CE8, 0xB16CFA97 */\nu03  =  3.47453432093683650238e-04, /* 0x3F36C54D, 0x20B29B6B */\nu04  = -3.81407053724364161125e-06, /* 0xBECFFEA7, 0x73D25CAD */\nu05  =  1.95590137035022920206e-08, /* 0x3E550057, 0x3B4EABD4 */\nu06  = -3.98205194132103398453e-11, /* 0xBDC5E43D, 0x693FB3C8 */\nv01  =  1.27304834834123699328e-02, /* 0x3F8A1270, 0x91C9C71A */\nv02  =  7.60068627350353253702e-05, /* 0x3F13ECBB, 0xF578C6C1 */\nv03  =  2.59150851840457805467e-07, /* 0x3E91642D, 0x7FF202FD */\nv04  =  4.41110311332675467403e-10; /* 0x3DFE5018, 0x3BD6D9EF */\n\ndouble y0(double x)\n{\n\tdouble z,u,v;\n\tuint32_t ix,lx;\n\n\tEXTRACT_WORDS(ix, lx, x);\n\n\t/* y0(nan)=nan, y0(<0)=nan, y0(0)=-inf, y0(inf)=0 */\n\tif ((ix<<1 | lx) == 0)\n\t\treturn -1/0.0;\n\tif (ix>>31)\n\t\treturn 0/0.0;\n\tif (ix >= 0x7ff00000)\n\t\treturn 1/x;\n\n\tif (ix >= 0x40000000) {  /* x >= 2 */\n\t\t/* large ulp errors near zeros: 3.958, 7.086,.. */\n\t\treturn common(ix,x,1);\n\t}\n\n\t/* U(x^2)/V(x^2) + (2/pi)*j0(x)*log(x) */\n\tif (ix >= 0x3e400000) {  /* x >= 2**-27 */\n\t\t/* large ulp error near the first zero, x ~= 0.89 */\n\t\tz = x*x;\n\t\tu = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06)))));\n\t\tv = 1.0+z*(v01+z*(v02+z*(v03+z*v04)));\n\t\treturn u/v + tpi*(j0(x)*log(x));\n\t}\n\treturn u00 + tpi*log(x);\n}\n\n/* The asymptotic expansions of pzero is\n *      1 - 9/128 s^2 + 11025/98304 s^4 - ...,  where s = 1/x.\n * For x >= 2, We approximate pzero by\n *      pzero(x) = 1 + (R/S)\n * where  R = pR0 + pR1*s^2 + pR2*s^4 + ... + pR5*s^10\n *        S = 1 + pS0*s^2 + ... + pS4*s^10\n * and\n *      | pzero(x)-1-R/S | <= 2  ** ( -60.26)\n */\nstatic const double pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */\n  0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */\n -7.03124999999900357484e-02, /* 0xBFB1FFFF, 0xFFFFFD32 */\n -8.08167041275349795626e+00, /* 0xC02029D0, 0xB44FA779 */\n -2.57063105679704847262e+02, /* 0xC0701102, 0x7B19E863 */\n -2.48521641009428822144e+03, /* 0xC0A36A6E, 0xCD4DCAFC */\n -5.25304380490729545272e+03, /* 0xC0B4850B, 0x36CC643D */\n};\nstatic const double pS8[5] = {\n  1.16534364619668181717e+02, /* 0x405D2233, 0x07A96751 */\n  3.83374475364121826715e+03, /* 0x40ADF37D, 0x50596938 */\n  4.05978572648472545552e+04, /* 0x40E3D2BB, 0x6EB6B05F */\n  1.16752972564375915681e+05, /* 0x40FC810F, 0x8F9FA9BD */\n  4.76277284146730962675e+04, /* 0x40E74177, 0x4F2C49DC */\n};\n\nstatic const double pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */\n -1.14125464691894502584e-11, /* 0xBDA918B1, 0x47E495CC */\n -7.03124940873599280078e-02, /* 0xBFB1FFFF, 0xE69AFBC6 */\n -4.15961064470587782438e+00, /* 0xC010A370, 0xF90C6BBF */\n -6.76747652265167261021e+01, /* 0xC050EB2F, 0x5A7D1783 */\n -3.31231299649172967747e+02, /* 0xC074B3B3, 0x6742CC63 */\n -3.46433388365604912451e+02, /* 0xC075A6EF, 0x28A38BD7 */\n};\nstatic const double pS5[5] = {\n  6.07539382692300335975e+01, /* 0x404E6081, 0x0C98C5DE */\n  1.05125230595704579173e+03, /* 0x40906D02, 0x5C7E2864 */\n  5.97897094333855784498e+03, /* 0x40B75AF8, 0x8FBE1D60 */\n  9.62544514357774460223e+03, /* 0x40C2CCB8, 0xFA76FA38 */\n  2.40605815922939109441e+03, /* 0x40A2CC1D, 0xC70BE864 */\n};\n\nstatic const double pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */\n -2.54704601771951915620e-09, /* 0xBE25E103, 0x6FE1AA86 */\n -7.03119616381481654654e-02, /* 0xBFB1FFF6, 0xF7C0E24B */\n -2.40903221549529611423e+00, /* 0xC00345B2, 0xAEA48074 */\n -2.19659774734883086467e+01, /* 0xC035F74A, 0x4CB94E14 */\n -5.80791704701737572236e+01, /* 0xC04D0A22, 0x420A1A45 */\n -3.14479470594888503854e+01, /* 0xC03F72AC, 0xA892D80F */\n};\nstatic const double pS3[5] = {\n  3.58560338055209726349e+01, /* 0x4041ED92, 0x84077DD3 */\n  3.61513983050303863820e+02, /* 0x40769839, 0x464A7C0E */\n  1.19360783792111533330e+03, /* 0x4092A66E, 0x6D1061D6 */\n  1.12799679856907414432e+03, /* 0x40919FFC, 0xB8C39B7E */\n  1.73580930813335754692e+02, /* 0x4065B296, 0xFC379081 */\n};\n\nstatic const double pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */\n -8.87534333032526411254e-08, /* 0xBE77D316, 0xE927026D */\n -7.03030995483624743247e-02, /* 0xBFB1FF62, 0x495E1E42 */\n -1.45073846780952986357e+00, /* 0xBFF73639, 0x8A24A843 */\n -7.63569613823527770791e+00, /* 0xC01E8AF3, 0xEDAFA7F3 */\n -1.11931668860356747786e+01, /* 0xC02662E6, 0xC5246303 */\n -3.23364579351335335033e+00, /* 0xC009DE81, 0xAF8FE70F */\n};\nstatic const double pS2[5] = {\n  2.22202997532088808441e+01, /* 0x40363865, 0x908B5959 */\n  1.36206794218215208048e+02, /* 0x4061069E, 0x0EE8878F */\n  2.70470278658083486789e+02, /* 0x4070E786, 0x42EA079B */\n  1.53875394208320329881e+02, /* 0x40633C03, 0x3AB6FAFF */\n  1.46576176948256193810e+01, /* 0x402D50B3, 0x44391809 */\n};\n\nstatic double pzero(double x)\n{\n\tconst double *p,*q;\n\tdouble_t z,r,s;\n\tuint32_t ix;\n\n\tGET_HIGH_WORD(ix, x);\n\tix &= 0x7fffffff;\n\tif      (ix >= 0x40200000){p = pR8; q = pS8;}\n\telse if (ix >= 0x40122E8B){p = pR5; q = pS5;}\n\telse if (ix >= 0x4006DB6D){p = pR3; q = pS3;}\n\telse /*ix >= 0x40000000*/ {p = pR2; q = pS2;}\n\tz = 1.0/(x*x);\n\tr = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));\n\ts = 1.0+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));\n\treturn 1.0 + r/s;\n}\n\n\n/* For x >= 8, the asymptotic expansions of qzero is\n *      -1/8 s + 75/1024 s^3 - ..., where s = 1/x.\n * We approximate pzero by\n *      qzero(x) = s*(-1.25 + (R/S))\n * where  R = qR0 + qR1*s^2 + qR2*s^4 + ... + qR5*s^10\n *        S = 1 + qS0*s^2 + ... + qS5*s^12\n * and\n *      | qzero(x)/s +1.25-R/S | <= 2  ** ( -61.22)\n */\nstatic const double qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */\n  0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */\n  7.32421874999935051953e-02, /* 0x3FB2BFFF, 0xFFFFFE2C */\n  1.17682064682252693899e+01, /* 0x40278952, 0x5BB334D6 */\n  5.57673380256401856059e+02, /* 0x40816D63, 0x15301825 */\n  8.85919720756468632317e+03, /* 0x40C14D99, 0x3E18F46D */\n  3.70146267776887834771e+04, /* 0x40E212D4, 0x0E901566 */\n};\nstatic const double qS8[6] = {\n  1.63776026895689824414e+02, /* 0x406478D5, 0x365B39BC */\n  8.09834494656449805916e+03, /* 0x40BFA258, 0x4E6B0563 */\n  1.42538291419120476348e+05, /* 0x41016652, 0x54D38C3F */\n  8.03309257119514397345e+05, /* 0x412883DA, 0x83A52B43 */\n  8.40501579819060512818e+05, /* 0x4129A66B, 0x28DE0B3D */\n -3.43899293537866615225e+05, /* 0xC114FD6D, 0x2C9530C5 */\n};\n\nstatic const double qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */\n  1.84085963594515531381e-11, /* 0x3DB43D8F, 0x29CC8CD9 */\n  7.32421766612684765896e-02, /* 0x3FB2BFFF, 0xD172B04C */\n  5.83563508962056953777e+00, /* 0x401757B0, 0xB9953DD3 */\n  1.35111577286449829671e+02, /* 0x4060E392, 0x0A8788E9 */\n  1.02724376596164097464e+03, /* 0x40900CF9, 0x9DC8C481 */\n  1.98997785864605384631e+03, /* 0x409F17E9, 0x53C6E3A6 */\n};\nstatic const double qS5[6] = {\n  8.27766102236537761883e+01, /* 0x4054B1B3, 0xFB5E1543 */\n  2.07781416421392987104e+03, /* 0x40A03BA0, 0xDA21C0CE */\n  1.88472887785718085070e+04, /* 0x40D267D2, 0x7B591E6D */\n  5.67511122894947329769e+04, /* 0x40EBB5E3, 0x97E02372 */\n  3.59767538425114471465e+04, /* 0x40E19118, 0x1F7A54A0 */\n -5.35434275601944773371e+03, /* 0xC0B4EA57, 0xBEDBC609 */\n};\n\nstatic const double qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */\n  4.37741014089738620906e-09, /* 0x3E32CD03, 0x6ADECB82 */\n  7.32411180042911447163e-02, /* 0x3FB2BFEE, 0x0E8D0842 */\n  3.34423137516170720929e+00, /* 0x400AC0FC, 0x61149CF5 */\n  4.26218440745412650017e+01, /* 0x40454F98, 0x962DAEDD */\n  1.70808091340565596283e+02, /* 0x406559DB, 0xE25EFD1F */\n  1.66733948696651168575e+02, /* 0x4064D77C, 0x81FA21E0 */\n};\nstatic const double qS3[6] = {\n  4.87588729724587182091e+01, /* 0x40486122, 0xBFE343A6 */\n  7.09689221056606015736e+02, /* 0x40862D83, 0x86544EB3 */\n  3.70414822620111362994e+03, /* 0x40ACF04B, 0xE44DFC63 */\n  6.46042516752568917582e+03, /* 0x40B93C6C, 0xD7C76A28 */\n  2.51633368920368957333e+03, /* 0x40A3A8AA, 0xD94FB1C0 */\n -1.49247451836156386662e+02, /* 0xC062A7EB, 0x201CF40F */\n};\n\nstatic const double qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */\n  1.50444444886983272379e-07, /* 0x3E84313B, 0x54F76BDB */\n  7.32234265963079278272e-02, /* 0x3FB2BEC5, 0x3E883E34 */\n  1.99819174093815998816e+00, /* 0x3FFFF897, 0xE727779C */\n  1.44956029347885735348e+01, /* 0x402CFDBF, 0xAAF96FE5 */\n  3.16662317504781540833e+01, /* 0x403FAA8E, 0x29FBDC4A */\n  1.62527075710929267416e+01, /* 0x403040B1, 0x71814BB4 */\n};\nstatic const double qS2[6] = {\n  3.03655848355219184498e+01, /* 0x403E5D96, 0xF7C07AED */\n  2.69348118608049844624e+02, /* 0x4070D591, 0xE4D14B40 */\n  8.44783757595320139444e+02, /* 0x408A6645, 0x22B3BF22 */\n  8.82935845112488550512e+02, /* 0x408B977C, 0x9C5CC214 */\n  2.12666388511798828631e+02, /* 0x406A9553, 0x0E001365 */\n -5.31095493882666946917e+00, /* 0xC0153E6A, 0xF8B32931 */\n};\n\nstatic double qzero(double x)\n{\n\tconst double *p,*q;\n\tdouble_t s,r,z;\n\tuint32_t ix;\n\n\tGET_HIGH_WORD(ix, x);\n\tix &= 0x7fffffff;\n\tif      (ix >= 0x40200000){p = qR8; q = qS8;}\n\telse if (ix >= 0x40122E8B){p = qR5; q = qS5;}\n\telse if (ix >= 0x4006DB6D){p = qR3; q = qS3;}\n\telse /*ix >= 0x40000000*/ {p = qR2; q = qS2;}\n\tz = 1.0/(x*x);\n\tr = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));\n\ts = 1.0+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));\n\treturn (-.125 + r/s)/x;\n}\n"
  },
  {
    "path": "user.libc/src/math/j0f.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/e_j0f.c */\n/*\n * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.\n */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n\n#define _GNU_SOURCE\n#include \"libm.h\"\n\nstatic float pzerof(float), qzerof(float);\n\nstatic const float\ninvsqrtpi = 5.6418961287e-01, /* 0x3f106ebb */\ntpi       = 6.3661974669e-01; /* 0x3f22f983 */\n\nstatic float common(uint32_t ix, float x, int y0)\n{\n\tfloat z,s,c,ss,cc;\n\t/*\n\t * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)\n\t * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)\n\t */\n\ts = sinf(x);\n\tc = cosf(x);\n\tif (y0)\n\t\tc = -c;\n\tcc = s+c;\n\tif (ix < 0x7f000000) {\n\t\tss = s-c;\n\t\tz = -cosf(2*x);\n\t\tif (s*c < 0)\n\t\t\tcc = z/ss;\n\t\telse\n\t\t\tss = z/cc;\n\t\tif (ix < 0x58800000) {\n\t\t\tif (y0)\n\t\t\t\tss = -ss;\n\t\t\tcc = pzerof(x)*cc-qzerof(x)*ss;\n\t\t}\n\t}\n\treturn invsqrtpi*cc/sqrtf(x);\n}\n\n/* R0/S0 on [0, 2.00] */\nstatic const float\nR02 =  1.5625000000e-02, /* 0x3c800000 */\nR03 = -1.8997929874e-04, /* 0xb947352e */\nR04 =  1.8295404516e-06, /* 0x35f58e88 */\nR05 = -4.6183270541e-09, /* 0xb19eaf3c */\nS01 =  1.5619102865e-02, /* 0x3c7fe744 */\nS02 =  1.1692678527e-04, /* 0x38f53697 */\nS03 =  5.1354652442e-07, /* 0x3509daa6 */\nS04 =  1.1661400734e-09; /* 0x30a045e8 */\n\nfloat j0f(float x)\n{\n\tfloat z,r,s;\n\tuint32_t ix;\n\n\tGET_FLOAT_WORD(ix, x);\n\tix &= 0x7fffffff;\n\tif (ix >= 0x7f800000)\n\t\treturn 1/(x*x);\n\tx = fabsf(x);\n\n\tif (ix >= 0x40000000) {  /* |x| >= 2 */\n\t\t/* large ulp error near zeros */\n\t\treturn common(ix, x, 0);\n\t}\n\tif (ix >= 0x3a000000) {  /* |x| >= 2**-11 */\n\t\t/* up to 4ulp error near 2 */\n\t\tz = x*x;\n\t\tr = z*(R02+z*(R03+z*(R04+z*R05)));\n\t\ts = 1+z*(S01+z*(S02+z*(S03+z*S04)));\n\t\treturn (1+x/2)*(1-x/2) + z*(r/s);\n\t}\n\tif (ix >= 0x21800000)  /* |x| >= 2**-60 */\n\t\tx = 0.25f*x*x;\n\treturn 1 - x;\n}\n\nstatic const float\nu00  = -7.3804296553e-02, /* 0xbd9726b5 */\nu01  =  1.7666645348e-01, /* 0x3e34e80d */\nu02  = -1.3818567619e-02, /* 0xbc626746 */\nu03  =  3.4745343146e-04, /* 0x39b62a69 */\nu04  = -3.8140706238e-06, /* 0xb67ff53c */\nu05  =  1.9559013964e-08, /* 0x32a802ba */\nu06  = -3.9820518410e-11, /* 0xae2f21eb */\nv01  =  1.2730483897e-02, /* 0x3c509385 */\nv02  =  7.6006865129e-05, /* 0x389f65e0 */\nv03  =  2.5915085189e-07, /* 0x348b216c */\nv04  =  4.4111031494e-10; /* 0x2ff280c2 */\n\nfloat y0f(float x)\n{\n\tfloat z,u,v;\n\tuint32_t ix;\n\n\tGET_FLOAT_WORD(ix, x);\n\tif ((ix & 0x7fffffff) == 0)\n\t\treturn -1/0.0f;\n\tif (ix>>31)\n\t\treturn 0/0.0f;\n\tif (ix >= 0x7f800000)\n\t\treturn 1/x;\n\tif (ix >= 0x40000000) {  /* |x| >= 2.0 */\n\t\t/* large ulp error near zeros */\n\t\treturn common(ix,x,1);\n\t}\n\tif (ix >= 0x39000000) {  /* x >= 2**-13 */\n\t\t/* large ulp error at x ~= 0.89 */\n\t\tz = x*x;\n\t\tu = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06)))));\n\t\tv = 1+z*(v01+z*(v02+z*(v03+z*v04)));\n\t\treturn u/v + tpi*(j0f(x)*logf(x));\n\t}\n\treturn u00 + tpi*logf(x);\n}\n\n/* The asymptotic expansions of pzero is\n *      1 - 9/128 s^2 + 11025/98304 s^4 - ...,  where s = 1/x.\n * For x >= 2, We approximate pzero by\n *      pzero(x) = 1 + (R/S)\n * where  R = pR0 + pR1*s^2 + pR2*s^4 + ... + pR5*s^10\n *        S = 1 + pS0*s^2 + ... + pS4*s^10\n * and\n *      | pzero(x)-1-R/S | <= 2  ** ( -60.26)\n */\nstatic const float pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */\n  0.0000000000e+00, /* 0x00000000 */\n -7.0312500000e-02, /* 0xbd900000 */\n -8.0816707611e+00, /* 0xc1014e86 */\n -2.5706311035e+02, /* 0xc3808814 */\n -2.4852163086e+03, /* 0xc51b5376 */\n -5.2530439453e+03, /* 0xc5a4285a */\n};\nstatic const float pS8[5] = {\n  1.1653436279e+02, /* 0x42e91198 */\n  3.8337448730e+03, /* 0x456f9beb */\n  4.0597855469e+04, /* 0x471e95db */\n  1.1675296875e+05, /* 0x47e4087c */\n  4.7627726562e+04, /* 0x473a0bba */\n};\nstatic const float pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */\n -1.1412546255e-11, /* 0xad48c58a */\n -7.0312492549e-02, /* 0xbd8fffff */\n -4.1596107483e+00, /* 0xc0851b88 */\n -6.7674766541e+01, /* 0xc287597b */\n -3.3123129272e+02, /* 0xc3a59d9b */\n -3.4643338013e+02, /* 0xc3ad3779 */\n};\nstatic const float pS5[5] = {\n  6.0753936768e+01, /* 0x42730408 */\n  1.0512523193e+03, /* 0x44836813 */\n  5.9789707031e+03, /* 0x45bad7c4 */\n  9.6254453125e+03, /* 0x461665c8 */\n  2.4060581055e+03, /* 0x451660ee */\n};\n\nstatic const float pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */\n -2.5470459075e-09, /* 0xb12f081b */\n -7.0311963558e-02, /* 0xbd8fffb8 */\n -2.4090321064e+00, /* 0xc01a2d95 */\n -2.1965976715e+01, /* 0xc1afba52 */\n -5.8079170227e+01, /* 0xc2685112 */\n -3.1447946548e+01, /* 0xc1fb9565 */\n};\nstatic const float pS3[5] = {\n  3.5856033325e+01, /* 0x420f6c94 */\n  3.6151397705e+02, /* 0x43b4c1ca */\n  1.1936077881e+03, /* 0x44953373 */\n  1.1279968262e+03, /* 0x448cffe6 */\n  1.7358093262e+02, /* 0x432d94b8 */\n};\n\nstatic const float pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */\n -8.8753431271e-08, /* 0xb3be98b7 */\n -7.0303097367e-02, /* 0xbd8ffb12 */\n -1.4507384300e+00, /* 0xbfb9b1cc */\n -7.6356959343e+00, /* 0xc0f4579f */\n -1.1193166733e+01, /* 0xc1331736 */\n -3.2336456776e+00, /* 0xc04ef40d */\n};\nstatic const float pS2[5] = {\n  2.2220300674e+01, /* 0x41b1c32d */\n  1.3620678711e+02, /* 0x430834f0 */\n  2.7047027588e+02, /* 0x43873c32 */\n  1.5387539673e+02, /* 0x4319e01a */\n  1.4657617569e+01, /* 0x416a859a */\n};\n\nstatic float pzerof(float x)\n{\n\tconst float *p,*q;\n\tfloat_t z,r,s;\n\tuint32_t ix;\n\n\tGET_FLOAT_WORD(ix, x);\n\tix &= 0x7fffffff;\n\tif      (ix >= 0x41000000){p = pR8; q = pS8;}\n\telse if (ix >= 0x409173eb){p = pR5; q = pS5;}\n\telse if (ix >= 0x4036d917){p = pR3; q = pS3;}\n\telse /*ix >= 0x40000000*/ {p = pR2; q = pS2;}\n\tz = 1.0f/(x*x);\n\tr = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));\n\ts = 1.0f+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));\n\treturn 1.0f + r/s;\n}\n\n\n/* For x >= 8, the asymptotic expansions of qzero is\n *      -1/8 s + 75/1024 s^3 - ..., where s = 1/x.\n * We approximate pzero by\n *      qzero(x) = s*(-1.25 + (R/S))\n * where  R = qR0 + qR1*s^2 + qR2*s^4 + ... + qR5*s^10\n *        S = 1 + qS0*s^2 + ... + qS5*s^12\n * and\n *      | qzero(x)/s +1.25-R/S | <= 2  ** ( -61.22)\n */\nstatic const float qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */\n  0.0000000000e+00, /* 0x00000000 */\n  7.3242187500e-02, /* 0x3d960000 */\n  1.1768206596e+01, /* 0x413c4a93 */\n  5.5767340088e+02, /* 0x440b6b19 */\n  8.8591972656e+03, /* 0x460a6cca */\n  3.7014625000e+04, /* 0x471096a0 */\n};\nstatic const float qS8[6] = {\n  1.6377603149e+02, /* 0x4323c6aa */\n  8.0983447266e+03, /* 0x45fd12c2 */\n  1.4253829688e+05, /* 0x480b3293 */\n  8.0330925000e+05, /* 0x49441ed4 */\n  8.4050156250e+05, /* 0x494d3359 */\n -3.4389928125e+05, /* 0xc8a7eb69 */\n};\n\nstatic const float qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */\n  1.8408595828e-11, /* 0x2da1ec79 */\n  7.3242180049e-02, /* 0x3d95ffff */\n  5.8356351852e+00, /* 0x40babd86 */\n  1.3511157227e+02, /* 0x43071c90 */\n  1.0272437744e+03, /* 0x448067cd */\n  1.9899779053e+03, /* 0x44f8bf4b */\n};\nstatic const float qS5[6] = {\n  8.2776611328e+01, /* 0x42a58da0 */\n  2.0778142090e+03, /* 0x4501dd07 */\n  1.8847289062e+04, /* 0x46933e94 */\n  5.6751113281e+04, /* 0x475daf1d */\n  3.5976753906e+04, /* 0x470c88c1 */\n -5.3543427734e+03, /* 0xc5a752be */\n};\n\nstatic const float qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */\n  4.3774099900e-09, /* 0x3196681b */\n  7.3241114616e-02, /* 0x3d95ff70 */\n  3.3442313671e+00, /* 0x405607e3 */\n  4.2621845245e+01, /* 0x422a7cc5 */\n  1.7080809021e+02, /* 0x432acedf */\n  1.6673394775e+02, /* 0x4326bbe4 */\n};\nstatic const float qS3[6] = {\n  4.8758872986e+01, /* 0x42430916 */\n  7.0968920898e+02, /* 0x44316c1c */\n  3.7041481934e+03, /* 0x4567825f */\n  6.4604252930e+03, /* 0x45c9e367 */\n  2.5163337402e+03, /* 0x451d4557 */\n -1.4924745178e+02, /* 0xc3153f59 */\n};\n\nstatic const float qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */\n  1.5044444979e-07, /* 0x342189db */\n  7.3223426938e-02, /* 0x3d95f62a */\n  1.9981917143e+00, /* 0x3fffc4bf */\n  1.4495602608e+01, /* 0x4167edfd */\n  3.1666231155e+01, /* 0x41fd5471 */\n  1.6252708435e+01, /* 0x4182058c */\n};\nstatic const float qS2[6] = {\n  3.0365585327e+01, /* 0x41f2ecb8 */\n  2.6934811401e+02, /* 0x4386ac8f */\n  8.4478375244e+02, /* 0x44533229 */\n  8.8293585205e+02, /* 0x445cbbe5 */\n  2.1266638184e+02, /* 0x4354aa98 */\n -5.3109550476e+00, /* 0xc0a9f358 */\n};\n\nstatic float qzerof(float x)\n{\n\tconst float *p,*q;\n\tfloat_t s,r,z;\n\tuint32_t ix;\n\n\tGET_FLOAT_WORD(ix, x);\n\tix &= 0x7fffffff;\n\tif      (ix >= 0x41000000){p = qR8; q = qS8;}\n\telse if (ix >= 0x409173eb){p = qR5; q = qS5;}\n\telse if (ix >= 0x4036d917){p = qR3; q = qS3;}\n\telse /*ix >= 0x40000000*/ {p = qR2; q = qS2;}\n\tz = 1.0f/(x*x);\n\tr = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));\n\ts = 1.0f+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));\n\treturn (-.125f + r/s)/x;\n}\n"
  },
  {
    "path": "user.libc/src/math/j1.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/e_j1.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunSoft, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/* j1(x), y1(x)\n * Bessel function of the first and second kinds of order zero.\n * Method -- j1(x):\n *      1. For tiny x, we use j1(x) = x/2 - x^3/16 + x^5/384 - ...\n *      2. Reduce x to |x| since j1(x)=-j1(-x),  and\n *         for x in (0,2)\n *              j1(x) = x/2 + x*z*R0/S0,  where z = x*x;\n *         (precision:  |j1/x - 1/2 - R0/S0 |<2**-61.51 )\n *         for x in (2,inf)\n *              j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x1)-q1(x)*sin(x1))\n *              y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1))\n *         where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1)\n *         as follow:\n *              cos(x1) =  cos(x)cos(3pi/4)+sin(x)sin(3pi/4)\n *                      =  1/sqrt(2) * (sin(x) - cos(x))\n *              sin(x1) =  sin(x)cos(3pi/4)-cos(x)sin(3pi/4)\n *                      = -1/sqrt(2) * (sin(x) + cos(x))\n *         (To avoid cancellation, use\n *              sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))\n *          to compute the worse one.)\n *\n *      3 Special cases\n *              j1(nan)= nan\n *              j1(0) = 0\n *              j1(inf) = 0\n *\n * Method -- y1(x):\n *      1. screen out x<=0 cases: y1(0)=-inf, y1(x<0)=NaN\n *      2. For x<2.\n *         Since\n *              y1(x) = 2/pi*(j1(x)*(ln(x/2)+Euler)-1/x-x/2+5/64*x^3-...)\n *         therefore y1(x)-2/pi*j1(x)*ln(x)-1/x is an odd function.\n *         We use the following function to approximate y1,\n *              y1(x) = x*U(z)/V(z) + (2/pi)*(j1(x)*ln(x)-1/x), z= x^2\n *         where for x in [0,2] (abs err less than 2**-65.89)\n *              U(z) = U0[0] + U0[1]*z + ... + U0[4]*z^4\n *              V(z) = 1  + v0[0]*z + ... + v0[4]*z^5\n *         Note: For tiny x, 1/x dominate y1 and hence\n *              y1(tiny) = -2/pi/tiny, (choose tiny<2**-54)\n *      3. For x>=2.\n *              y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1))\n *         where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1)\n *         by method mentioned above.\n */\n\n#include \"libm.h\"\n\nstatic double pone(double), qone(double);\n\nstatic const double\ninvsqrtpi = 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */\ntpi       = 6.36619772367581382433e-01; /* 0x3FE45F30, 0x6DC9C883 */\n\nstatic double common(uint32_t ix, double x, int y1, int sign)\n{\n\tdouble z,s,c,ss,cc;\n\n\t/*\n\t * j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x-3pi/4)-q1(x)*sin(x-3pi/4))\n\t * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x-3pi/4)+q1(x)*cos(x-3pi/4))\n\t *\n\t * sin(x-3pi/4) = -(sin(x) + cos(x))/sqrt(2)\n\t * cos(x-3pi/4) = (sin(x) - cos(x))/sqrt(2)\n\t * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))\n\t */\n\ts = sin(x);\n\tif (y1)\n\t\ts = -s;\n\tc = cos(x);\n\tcc = s-c;\n\tif (ix < 0x7fe00000) {\n\t\t/* avoid overflow in 2*x */\n\t\tss = -s-c;\n\t\tz = cos(2*x);\n\t\tif (s*c > 0)\n\t\t\tcc = z/ss;\n\t\telse\n\t\t\tss = z/cc;\n\t\tif (ix < 0x48000000) {\n\t\t\tif (y1)\n\t\t\t\tss = -ss;\n\t\t\tcc = pone(x)*cc-qone(x)*ss;\n\t\t}\n\t}\n\tif (sign)\n\t\tcc = -cc;\n\treturn invsqrtpi*cc/sqrt(x);\n}\n\n/* R0/S0 on [0,2] */\nstatic const double\nr00 = -6.25000000000000000000e-02, /* 0xBFB00000, 0x00000000 */\nr01 =  1.40705666955189706048e-03, /* 0x3F570D9F, 0x98472C61 */\nr02 = -1.59955631084035597520e-05, /* 0xBEF0C5C6, 0xBA169668 */\nr03 =  4.96727999609584448412e-08, /* 0x3E6AAAFA, 0x46CA0BD9 */\ns01 =  1.91537599538363460805e-02, /* 0x3F939D0B, 0x12637E53 */\ns02 =  1.85946785588630915560e-04, /* 0x3F285F56, 0xB9CDF664 */\ns03 =  1.17718464042623683263e-06, /* 0x3EB3BFF8, 0x333F8498 */\ns04 =  5.04636257076217042715e-09, /* 0x3E35AC88, 0xC97DFF2C */\ns05 =  1.23542274426137913908e-11; /* 0x3DAB2ACF, 0xCFB97ED8 */\n\ndouble j1(double x)\n{\n\tdouble z,r,s;\n\tuint32_t ix;\n\tint sign;\n\n\tGET_HIGH_WORD(ix, x);\n\tsign = ix>>31;\n\tix &= 0x7fffffff;\n\tif (ix >= 0x7ff00000)\n\t\treturn 1/(x*x);\n\tif (ix >= 0x40000000)  /* |x| >= 2 */\n\t\treturn common(ix, fabs(x), 0, sign);\n\tif (ix >= 0x38000000) {  /* |x| >= 2**-127 */\n\t\tz = x*x;\n\t\tr = z*(r00+z*(r01+z*(r02+z*r03)));\n\t\ts = 1+z*(s01+z*(s02+z*(s03+z*(s04+z*s05))));\n\t\tz = r/s;\n\t} else\n\t\t/* avoid underflow, raise inexact if x!=0 */\n\t\tz = x;\n\treturn (0.5 + z)*x;\n}\n\nstatic const double U0[5] = {\n -1.96057090646238940668e-01, /* 0xBFC91866, 0x143CBC8A */\n  5.04438716639811282616e-02, /* 0x3FA9D3C7, 0x76292CD1 */\n -1.91256895875763547298e-03, /* 0xBF5F55E5, 0x4844F50F */\n  2.35252600561610495928e-05, /* 0x3EF8AB03, 0x8FA6B88E */\n -9.19099158039878874504e-08, /* 0xBE78AC00, 0x569105B8 */\n};\nstatic const double V0[5] = {\n  1.99167318236649903973e-02, /* 0x3F94650D, 0x3F4DA9F0 */\n  2.02552581025135171496e-04, /* 0x3F2A8C89, 0x6C257764 */\n  1.35608801097516229404e-06, /* 0x3EB6C05A, 0x894E8CA6 */\n  6.22741452364621501295e-09, /* 0x3E3ABF1D, 0x5BA69A86 */\n  1.66559246207992079114e-11, /* 0x3DB25039, 0xDACA772A */\n};\n\ndouble y1(double x)\n{\n\tdouble z,u,v;\n\tuint32_t ix,lx;\n\n\tEXTRACT_WORDS(ix, lx, x);\n\t/* y1(nan)=nan, y1(<0)=nan, y1(0)=-inf, y1(inf)=0 */\n\tif ((ix<<1 | lx) == 0)\n\t\treturn -1/0.0;\n\tif (ix>>31)\n\t\treturn 0/0.0;\n\tif (ix >= 0x7ff00000)\n\t\treturn 1/x;\n\n\tif (ix >= 0x40000000)  /* x >= 2 */\n\t\treturn common(ix, x, 1, 0);\n\tif (ix < 0x3c900000)  /* x < 2**-54 */\n\t\treturn -tpi/x;\n\tz = x*x;\n\tu = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4])));\n\tv = 1+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4]))));\n\treturn x*(u/v) + tpi*(j1(x)*log(x)-1/x);\n}\n\n/* For x >= 8, the asymptotic expansions of pone is\n *      1 + 15/128 s^2 - 4725/2^15 s^4 - ...,   where s = 1/x.\n * We approximate pone by\n *      pone(x) = 1 + (R/S)\n * where  R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10\n *        S = 1 + ps0*s^2 + ... + ps4*s^10\n * and\n *      | pone(x)-1-R/S | <= 2  ** ( -60.06)\n */\n\nstatic const double pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */\n  0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */\n  1.17187499999988647970e-01, /* 0x3FBDFFFF, 0xFFFFFCCE */\n  1.32394806593073575129e+01, /* 0x402A7A9D, 0x357F7FCE */\n  4.12051854307378562225e+02, /* 0x4079C0D4, 0x652EA590 */\n  3.87474538913960532227e+03, /* 0x40AE457D, 0xA3A532CC */\n  7.91447954031891731574e+03, /* 0x40BEEA7A, 0xC32782DD */\n};\nstatic const double ps8[5] = {\n  1.14207370375678408436e+02, /* 0x405C8D45, 0x8E656CAC */\n  3.65093083420853463394e+03, /* 0x40AC85DC, 0x964D274F */\n  3.69562060269033463555e+04, /* 0x40E20B86, 0x97C5BB7F */\n  9.76027935934950801311e+04, /* 0x40F7D42C, 0xB28F17BB */\n  3.08042720627888811578e+04, /* 0x40DE1511, 0x697A0B2D */\n};\n\nstatic const double pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */\n  1.31990519556243522749e-11, /* 0x3DAD0667, 0xDAE1CA7D */\n  1.17187493190614097638e-01, /* 0x3FBDFFFF, 0xE2C10043 */\n  6.80275127868432871736e+00, /* 0x401B3604, 0x6E6315E3 */\n  1.08308182990189109773e+02, /* 0x405B13B9, 0x452602ED */\n  5.17636139533199752805e+02, /* 0x40802D16, 0xD052D649 */\n  5.28715201363337541807e+02, /* 0x408085B8, 0xBB7E0CB7 */\n};\nstatic const double ps5[5] = {\n  5.92805987221131331921e+01, /* 0x404DA3EA, 0xA8AF633D */\n  9.91401418733614377743e+02, /* 0x408EFB36, 0x1B066701 */\n  5.35326695291487976647e+03, /* 0x40B4E944, 0x5706B6FB */\n  7.84469031749551231769e+03, /* 0x40BEA4B0, 0xB8A5BB15 */\n  1.50404688810361062679e+03, /* 0x40978030, 0x036F5E51 */\n};\n\nstatic const double pr3[6] = {\n  3.02503916137373618024e-09, /* 0x3E29FC21, 0xA7AD9EDD */\n  1.17186865567253592491e-01, /* 0x3FBDFFF5, 0x5B21D17B */\n  3.93297750033315640650e+00, /* 0x400F76BC, 0xE85EAD8A */\n  3.51194035591636932736e+01, /* 0x40418F48, 0x9DA6D129 */\n  9.10550110750781271918e+01, /* 0x4056C385, 0x4D2C1837 */\n  4.85590685197364919645e+01, /* 0x4048478F, 0x8EA83EE5 */\n};\nstatic const double ps3[5] = {\n  3.47913095001251519989e+01, /* 0x40416549, 0xA134069C */\n  3.36762458747825746741e+02, /* 0x40750C33, 0x07F1A75F */\n  1.04687139975775130551e+03, /* 0x40905B7C, 0x5037D523 */\n  8.90811346398256432622e+02, /* 0x408BD67D, 0xA32E31E9 */\n  1.03787932439639277504e+02, /* 0x4059F26D, 0x7C2EED53 */\n};\n\nstatic const double pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */\n  1.07710830106873743082e-07, /* 0x3E7CE9D4, 0xF65544F4 */\n  1.17176219462683348094e-01, /* 0x3FBDFF42, 0xBE760D83 */\n  2.36851496667608785174e+00, /* 0x4002F2B7, 0xF98FAEC0 */\n  1.22426109148261232917e+01, /* 0x40287C37, 0x7F71A964 */\n  1.76939711271687727390e+01, /* 0x4031B1A8, 0x177F8EE2 */\n  5.07352312588818499250e+00, /* 0x40144B49, 0xA574C1FE */\n};\nstatic const double ps2[5] = {\n  2.14364859363821409488e+01, /* 0x40356FBD, 0x8AD5ECDC */\n  1.25290227168402751090e+02, /* 0x405F5293, 0x14F92CD5 */\n  2.32276469057162813669e+02, /* 0x406D08D8, 0xD5A2DBD9 */\n  1.17679373287147100768e+02, /* 0x405D6B7A, 0xDA1884A9 */\n  8.36463893371618283368e+00, /* 0x4020BAB1, 0xF44E5192 */\n};\n\nstatic double pone(double x)\n{\n\tconst double *p,*q;\n\tdouble_t z,r,s;\n\tuint32_t ix;\n\n\tGET_HIGH_WORD(ix, x);\n\tix &= 0x7fffffff;\n\tif      (ix >= 0x40200000){p = pr8; q = ps8;}\n\telse if (ix >= 0x40122E8B){p = pr5; q = ps5;}\n\telse if (ix >= 0x4006DB6D){p = pr3; q = ps3;}\n\telse /*ix >= 0x40000000*/ {p = pr2; q = ps2;}\n\tz = 1.0/(x*x);\n\tr = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));\n\ts = 1.0+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));\n\treturn 1.0+ r/s;\n}\n\n/* For x >= 8, the asymptotic expansions of qone is\n *      3/8 s - 105/1024 s^3 - ..., where s = 1/x.\n * We approximate pone by\n *      qone(x) = s*(0.375 + (R/S))\n * where  R = qr1*s^2 + qr2*s^4 + ... + qr5*s^10\n *        S = 1 + qs1*s^2 + ... + qs6*s^12\n * and\n *      | qone(x)/s -0.375-R/S | <= 2  ** ( -61.13)\n */\n\nstatic const double qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */\n  0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */\n -1.02539062499992714161e-01, /* 0xBFBA3FFF, 0xFFFFFDF3 */\n -1.62717534544589987888e+01, /* 0xC0304591, 0xA26779F7 */\n -7.59601722513950107896e+02, /* 0xC087BCD0, 0x53E4B576 */\n -1.18498066702429587167e+04, /* 0xC0C724E7, 0x40F87415 */\n -4.84385124285750353010e+04, /* 0xC0E7A6D0, 0x65D09C6A */\n};\nstatic const double qs8[6] = {\n  1.61395369700722909556e+02, /* 0x40642CA6, 0xDE5BCDE5 */\n  7.82538599923348465381e+03, /* 0x40BE9162, 0xD0D88419 */\n  1.33875336287249578163e+05, /* 0x4100579A, 0xB0B75E98 */\n  7.19657723683240939863e+05, /* 0x4125F653, 0x72869C19 */\n  6.66601232617776375264e+05, /* 0x412457D2, 0x7719AD5C */\n -2.94490264303834643215e+05, /* 0xC111F969, 0x0EA5AA18 */\n};\n\nstatic const double qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */\n -2.08979931141764104297e-11, /* 0xBDB6FA43, 0x1AA1A098 */\n -1.02539050241375426231e-01, /* 0xBFBA3FFF, 0xCB597FEF */\n -8.05644828123936029840e+00, /* 0xC0201CE6, 0xCA03AD4B */\n -1.83669607474888380239e+02, /* 0xC066F56D, 0x6CA7B9B0 */\n -1.37319376065508163265e+03, /* 0xC09574C6, 0x6931734F */\n -2.61244440453215656817e+03, /* 0xC0A468E3, 0x88FDA79D */\n};\nstatic const double qs5[6] = {\n  8.12765501384335777857e+01, /* 0x405451B2, 0xFF5A11B2 */\n  1.99179873460485964642e+03, /* 0x409F1F31, 0xE77BF839 */\n  1.74684851924908907677e+04, /* 0x40D10F1F, 0x0D64CE29 */\n  4.98514270910352279316e+04, /* 0x40E8576D, 0xAABAD197 */\n  2.79480751638918118260e+04, /* 0x40DB4B04, 0xCF7C364B */\n -4.71918354795128470869e+03, /* 0xC0B26F2E, 0xFCFFA004 */\n};\n\nstatic const double qr3[6] = {\n -5.07831226461766561369e-09, /* 0xBE35CFA9, 0xD38FC84F */\n -1.02537829820837089745e-01, /* 0xBFBA3FEB, 0x51AEED54 */\n -4.61011581139473403113e+00, /* 0xC01270C2, 0x3302D9FF */\n -5.78472216562783643212e+01, /* 0xC04CEC71, 0xC25D16DA */\n -2.28244540737631695038e+02, /* 0xC06C87D3, 0x4718D55F */\n -2.19210128478909325622e+02, /* 0xC06B66B9, 0x5F5C1BF6 */\n};\nstatic const double qs3[6] = {\n  4.76651550323729509273e+01, /* 0x4047D523, 0xCCD367E4 */\n  6.73865112676699709482e+02, /* 0x40850EEB, 0xC031EE3E */\n  3.38015286679526343505e+03, /* 0x40AA684E, 0x448E7C9A */\n  5.54772909720722782367e+03, /* 0x40B5ABBA, 0xA61D54A6 */\n  1.90311919338810798763e+03, /* 0x409DBC7A, 0x0DD4DF4B */\n -1.35201191444307340817e+02, /* 0xC060E670, 0x290A311F */\n};\n\nstatic const double qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */\n -1.78381727510958865572e-07, /* 0xBE87F126, 0x44C626D2 */\n -1.02517042607985553460e-01, /* 0xBFBA3E8E, 0x9148B010 */\n -2.75220568278187460720e+00, /* 0xC0060484, 0x69BB4EDA */\n -1.96636162643703720221e+01, /* 0xC033A9E2, 0xC168907F */\n -4.23253133372830490089e+01, /* 0xC04529A3, 0xDE104AAA */\n -2.13719211703704061733e+01, /* 0xC0355F36, 0x39CF6E52 */\n};\nstatic const double qs2[6] = {\n  2.95333629060523854548e+01, /* 0x403D888A, 0x78AE64FF */\n  2.52981549982190529136e+02, /* 0x406F9F68, 0xDB821CBA */\n  7.57502834868645436472e+02, /* 0x4087AC05, 0xCE49A0F7 */\n  7.39393205320467245656e+02, /* 0x40871B25, 0x48D4C029 */\n  1.55949003336666123687e+02, /* 0x40637E5E, 0x3C3ED8D4 */\n -4.95949898822628210127e+00, /* 0xC013D686, 0xE71BE86B */\n};\n\nstatic double qone(double x)\n{\n\tconst double *p,*q;\n\tdouble_t s,r,z;\n\tuint32_t ix;\n\n\tGET_HIGH_WORD(ix, x);\n\tix &= 0x7fffffff;\n\tif      (ix >= 0x40200000){p = qr8; q = qs8;}\n\telse if (ix >= 0x40122E8B){p = qr5; q = qs5;}\n\telse if (ix >= 0x4006DB6D){p = qr3; q = qs3;}\n\telse /*ix >= 0x40000000*/ {p = qr2; q = qs2;}\n\tz = 1.0/(x*x);\n\tr = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));\n\ts = 1.0+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));\n\treturn (.375 + r/s)/x;\n}\n"
  },
  {
    "path": "user.libc/src/math/j1f.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/e_j1f.c */\n/*\n * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.\n */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n\n#define _GNU_SOURCE\n#include \"libm.h\"\n\nstatic float ponef(float), qonef(float);\n\nstatic const float\ninvsqrtpi = 5.6418961287e-01, /* 0x3f106ebb */\ntpi       = 6.3661974669e-01; /* 0x3f22f983 */\n\nstatic float common(uint32_t ix, float x, int y1, int sign)\n{\n\tdouble z,s,c,ss,cc;\n\n\ts = sinf(x);\n\tif (y1)\n\t\ts = -s;\n\tc = cosf(x);\n\tcc = s-c;\n\tif (ix < 0x7f000000) {\n\t\tss = -s-c;\n\t\tz = cosf(2*x);\n\t\tif (s*c > 0)\n\t\t\tcc = z/ss;\n\t\telse\n\t\t\tss = z/cc;\n\t\tif (ix < 0x58800000) {\n\t\t\tif (y1)\n\t\t\t\tss = -ss;\n\t\t\tcc = ponef(x)*cc-qonef(x)*ss;\n\t\t}\n\t}\n\tif (sign)\n\t\tcc = -cc;\n\treturn invsqrtpi*cc/sqrtf(x);\n}\n\n/* R0/S0 on [0,2] */\nstatic const float\nr00 = -6.2500000000e-02, /* 0xbd800000 */\nr01 =  1.4070566976e-03, /* 0x3ab86cfd */\nr02 = -1.5995563444e-05, /* 0xb7862e36 */\nr03 =  4.9672799207e-08, /* 0x335557d2 */\ns01 =  1.9153760746e-02, /* 0x3c9ce859 */\ns02 =  1.8594678841e-04, /* 0x3942fab6 */\ns03 =  1.1771846857e-06, /* 0x359dffc2 */\ns04 =  5.0463624390e-09, /* 0x31ad6446 */\ns05 =  1.2354227016e-11; /* 0x2d59567e */\n\nfloat j1f(float x)\n{\n\tfloat z,r,s;\n\tuint32_t ix;\n\tint sign;\n\n\tGET_FLOAT_WORD(ix, x);\n\tsign = ix>>31;\n\tix &= 0x7fffffff;\n\tif (ix >= 0x7f800000)\n\t\treturn 1/(x*x);\n\tif (ix >= 0x40000000)  /* |x| >= 2 */\n\t\treturn common(ix, fabsf(x), 0, sign);\n\tif (ix >= 0x39000000) {  /* |x| >= 2**-13 */\n\t\tz = x*x;\n\t\tr = z*(r00+z*(r01+z*(r02+z*r03)));\n\t\ts = 1+z*(s01+z*(s02+z*(s03+z*(s04+z*s05))));\n\t\tz = 0.5f + r/s;\n\t} else\n\t\tz = 0.5f;\n\treturn z*x;\n}\n\nstatic const float U0[5] = {\n -1.9605709612e-01, /* 0xbe48c331 */\n  5.0443872809e-02, /* 0x3d4e9e3c */\n -1.9125689287e-03, /* 0xbafaaf2a */\n  2.3525259166e-05, /* 0x37c5581c */\n -9.1909917899e-08, /* 0xb3c56003 */\n};\nstatic const float V0[5] = {\n  1.9916731864e-02, /* 0x3ca3286a */\n  2.0255257550e-04, /* 0x3954644b */\n  1.3560879779e-06, /* 0x35b602d4 */\n  6.2274145840e-09, /* 0x31d5f8eb */\n  1.6655924903e-11, /* 0x2d9281cf */\n};\n\nfloat y1f(float x)\n{\n\tfloat z,u,v;\n\tuint32_t ix;\n\n\tGET_FLOAT_WORD(ix, x);\n\tif ((ix & 0x7fffffff) == 0)\n\t\treturn -1/0.0f;\n\tif (ix>>31)\n\t\treturn 0/0.0f;\n\tif (ix >= 0x7f800000)\n\t\treturn 1/x;\n\tif (ix >= 0x40000000)  /* |x| >= 2.0 */\n\t\treturn common(ix,x,1,0);\n\tif (ix < 0x33000000)  /* x < 2**-25 */\n\t\treturn -tpi/x;\n\tz = x*x;\n\tu = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4])));\n\tv = 1.0f+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4]))));\n\treturn x*(u/v) + tpi*(j1f(x)*logf(x)-1.0f/x);\n}\n\n/* For x >= 8, the asymptotic expansions of pone is\n *      1 + 15/128 s^2 - 4725/2^15 s^4 - ...,   where s = 1/x.\n * We approximate pone by\n *      pone(x) = 1 + (R/S)\n * where  R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10\n *        S = 1 + ps0*s^2 + ... + ps4*s^10\n * and\n *      | pone(x)-1-R/S | <= 2  ** ( -60.06)\n */\n\nstatic const float pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */\n  0.0000000000e+00, /* 0x00000000 */\n  1.1718750000e-01, /* 0x3df00000 */\n  1.3239480972e+01, /* 0x4153d4ea */\n  4.1205184937e+02, /* 0x43ce06a3 */\n  3.8747453613e+03, /* 0x45722bed */\n  7.9144794922e+03, /* 0x45f753d6 */\n};\nstatic const float ps8[5] = {\n  1.1420736694e+02, /* 0x42e46a2c */\n  3.6509309082e+03, /* 0x45642ee5 */\n  3.6956207031e+04, /* 0x47105c35 */\n  9.7602796875e+04, /* 0x47bea166 */\n  3.0804271484e+04, /* 0x46f0a88b */\n};\n\nstatic const float pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */\n  1.3199052094e-11, /* 0x2d68333f */\n  1.1718749255e-01, /* 0x3defffff */\n  6.8027510643e+00, /* 0x40d9b023 */\n  1.0830818176e+02, /* 0x42d89dca */\n  5.1763616943e+02, /* 0x440168b7 */\n  5.2871520996e+02, /* 0x44042dc6 */\n};\nstatic const float ps5[5] = {\n  5.9280597687e+01, /* 0x426d1f55 */\n  9.9140142822e+02, /* 0x4477d9b1 */\n  5.3532670898e+03, /* 0x45a74a23 */\n  7.8446904297e+03, /* 0x45f52586 */\n  1.5040468750e+03, /* 0x44bc0180 */\n};\n\nstatic const float pr3[6] = {\n  3.0250391081e-09, /* 0x314fe10d */\n  1.1718686670e-01, /* 0x3defffab */\n  3.9329774380e+00, /* 0x407bb5e7 */\n  3.5119403839e+01, /* 0x420c7a45 */\n  9.1055007935e+01, /* 0x42b61c2a */\n  4.8559066772e+01, /* 0x42423c7c */\n};\nstatic const float ps3[5] = {\n  3.4791309357e+01, /* 0x420b2a4d */\n  3.3676245117e+02, /* 0x43a86198 */\n  1.0468714600e+03, /* 0x4482dbe3 */\n  8.9081134033e+02, /* 0x445eb3ed */\n  1.0378793335e+02, /* 0x42cf936c */\n};\n\nstatic const float pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */\n  1.0771083225e-07, /* 0x33e74ea8 */\n  1.1717621982e-01, /* 0x3deffa16 */\n  2.3685150146e+00, /* 0x401795c0 */\n  1.2242610931e+01, /* 0x4143e1bc */\n  1.7693971634e+01, /* 0x418d8d41 */\n  5.0735230446e+00, /* 0x40a25a4d */\n};\nstatic const float ps2[5] = {\n  2.1436485291e+01, /* 0x41ab7dec */\n  1.2529022980e+02, /* 0x42fa9499 */\n  2.3227647400e+02, /* 0x436846c7 */\n  1.1767937469e+02, /* 0x42eb5bd7 */\n  8.3646392822e+00, /* 0x4105d590 */\n};\n\nstatic float ponef(float x)\n{\n\tconst float *p,*q;\n\tfloat_t z,r,s;\n\tuint32_t ix;\n\n\tGET_FLOAT_WORD(ix, x);\n\tix &= 0x7fffffff;\n\tif      (ix >= 0x41000000){p = pr8; q = ps8;}\n\telse if (ix >= 0x409173eb){p = pr5; q = ps5;}\n\telse if (ix >= 0x4036d917){p = pr3; q = ps3;}\n\telse /*ix >= 0x40000000*/ {p = pr2; q = ps2;}\n\tz = 1.0f/(x*x);\n\tr = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));\n\ts = 1.0f+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));\n\treturn 1.0f + r/s;\n}\n\n/* For x >= 8, the asymptotic expansions of qone is\n *      3/8 s - 105/1024 s^3 - ..., where s = 1/x.\n * We approximate pone by\n *      qone(x) = s*(0.375 + (R/S))\n * where  R = qr1*s^2 + qr2*s^4 + ... + qr5*s^10\n *        S = 1 + qs1*s^2 + ... + qs6*s^12\n * and\n *      | qone(x)/s -0.375-R/S | <= 2  ** ( -61.13)\n */\n\nstatic const float qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */\n  0.0000000000e+00, /* 0x00000000 */\n -1.0253906250e-01, /* 0xbdd20000 */\n -1.6271753311e+01, /* 0xc1822c8d */\n -7.5960174561e+02, /* 0xc43de683 */\n -1.1849806641e+04, /* 0xc639273a */\n -4.8438511719e+04, /* 0xc73d3683 */\n};\nstatic const float qs8[6] = {\n  1.6139537048e+02, /* 0x43216537 */\n  7.8253862305e+03, /* 0x45f48b17 */\n  1.3387534375e+05, /* 0x4802bcd6 */\n  7.1965775000e+05, /* 0x492fb29c */\n  6.6660125000e+05, /* 0x4922be94 */\n -2.9449025000e+05, /* 0xc88fcb48 */\n};\n\nstatic const float qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */\n -2.0897993405e-11, /* 0xadb7d219 */\n -1.0253904760e-01, /* 0xbdd1fffe */\n -8.0564479828e+00, /* 0xc100e736 */\n -1.8366960144e+02, /* 0xc337ab6b */\n -1.3731937256e+03, /* 0xc4aba633 */\n -2.6124443359e+03, /* 0xc523471c */\n};\nstatic const float qs5[6] = {\n  8.1276550293e+01, /* 0x42a28d98 */\n  1.9917987061e+03, /* 0x44f8f98f */\n  1.7468484375e+04, /* 0x468878f8 */\n  4.9851425781e+04, /* 0x4742bb6d */\n  2.7948074219e+04, /* 0x46da5826 */\n -4.7191835938e+03, /* 0xc5937978 */\n};\n\nstatic const float qr3[6] = {\n -5.0783124372e-09, /* 0xb1ae7d4f */\n -1.0253783315e-01, /* 0xbdd1ff5b */\n -4.6101160049e+00, /* 0xc0938612 */\n -5.7847221375e+01, /* 0xc267638e */\n -2.2824453735e+02, /* 0xc3643e9a */\n -2.1921012878e+02, /* 0xc35b35cb */\n};\nstatic const float qs3[6] = {\n  4.7665153503e+01, /* 0x423ea91e */\n  6.7386511230e+02, /* 0x4428775e */\n  3.3801528320e+03, /* 0x45534272 */\n  5.5477290039e+03, /* 0x45ad5dd5 */\n  1.9031191406e+03, /* 0x44ede3d0 */\n -1.3520118713e+02, /* 0xc3073381 */\n};\n\nstatic const float qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */\n -1.7838172539e-07, /* 0xb43f8932 */\n -1.0251704603e-01, /* 0xbdd1f475 */\n -2.7522056103e+00, /* 0xc0302423 */\n -1.9663616180e+01, /* 0xc19d4f16 */\n -4.2325313568e+01, /* 0xc2294d1f */\n -2.1371921539e+01, /* 0xc1aaf9b2 */\n};\nstatic const float qs2[6] = {\n  2.9533363342e+01, /* 0x41ec4454 */\n  2.5298155212e+02, /* 0x437cfb47 */\n  7.5750280762e+02, /* 0x443d602e */\n  7.3939318848e+02, /* 0x4438d92a */\n  1.5594900513e+02, /* 0x431bf2f2 */\n -4.9594988823e+00, /* 0xc09eb437 */\n};\n\nstatic float qonef(float x)\n{\n\tconst float *p,*q;\n\tfloat_t s,r,z;\n\tuint32_t ix;\n\n\tGET_FLOAT_WORD(ix, x);\n\tix &= 0x7fffffff;\n\tif      (ix >= 0x41000000){p = qr8; q = qs8;}\n\telse if (ix >= 0x409173eb){p = qr5; q = qs5;}\n\telse if (ix >= 0x4036d917){p = qr3; q = qs3;}\n\telse /*ix >= 0x40000000*/ {p = qr2; q = qs2;}\n\tz = 1.0f/(x*x);\n\tr = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));\n\ts = 1.0f+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));\n\treturn (.375f + r/s)/x;\n}\n"
  },
  {
    "path": "user.libc/src/math/jn.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/e_jn.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunSoft, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/*\n * jn(n, x), yn(n, x)\n * floating point Bessel's function of the 1st and 2nd kind\n * of order n\n *\n * Special cases:\n *      y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal;\n *      y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal.\n * Note 2. About jn(n,x), yn(n,x)\n *      For n=0, j0(x) is called,\n *      for n=1, j1(x) is called,\n *      for n<=x, forward recursion is used starting\n *      from values of j0(x) and j1(x).\n *      for n>x, a continued fraction approximation to\n *      j(n,x)/j(n-1,x) is evaluated and then backward\n *      recursion is used starting from a supposed value\n *      for j(n,x). The resulting value of j(0,x) is\n *      compared with the actual value to correct the\n *      supposed value of j(n,x).\n *\n *      yn(n,x) is similar in all respects, except\n *      that forward recursion is used for all\n *      values of n>1.\n */\n\n#include \"libm.h\"\n\nstatic const double invsqrtpi = 5.64189583547756279280e-01; /* 0x3FE20DD7, 0x50429B6D */\n\ndouble jn(int n, double x)\n{\n\tuint32_t ix, lx;\n\tint nm1, i, sign;\n\tdouble a, b, temp;\n\n\tEXTRACT_WORDS(ix, lx, x);\n\tsign = ix>>31;\n\tix &= 0x7fffffff;\n\n\tif ((ix | (lx|-lx)>>31) > 0x7ff00000) /* nan */\n\t\treturn x;\n\n\t/* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)\n\t * Thus, J(-n,x) = J(n,-x)\n\t */\n\t/* nm1 = |n|-1 is used instead of |n| to handle n==INT_MIN */\n\tif (n == 0)\n\t\treturn j0(x);\n\tif (n < 0) {\n\t\tnm1 = -(n+1);\n\t\tx = -x;\n\t\tsign ^= 1;\n\t} else\n\t\tnm1 = n-1;\n\tif (nm1 == 0)\n\t\treturn j1(x);\n\n\tsign &= n;  /* even n: 0, odd n: signbit(x) */\n\tx = fabs(x);\n\tif ((ix|lx) == 0 || ix == 0x7ff00000)  /* if x is 0 or inf */\n\t\tb = 0.0;\n\telse if (nm1 < x) {\n\t\t/* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */\n\t\tif (ix >= 0x52d00000) { /* x > 2**302 */\n\t\t\t/* (x >> n**2)\n\t\t\t *      Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)\n\t\t\t *      Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)\n\t\t\t *      Let s=sin(x), c=cos(x),\n\t\t\t *          xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then\n\t\t\t *\n\t\t\t *             n    sin(xn)*sqt2    cos(xn)*sqt2\n\t\t\t *          ----------------------------------\n\t\t\t *             0     s-c             c+s\n\t\t\t *             1    -s-c            -c+s\n\t\t\t *             2    -s+c            -c-s\n\t\t\t *             3     s+c             c-s\n\t\t\t */\n\t\t\tswitch(nm1&3) {\n\t\t\tcase 0: temp = -cos(x)+sin(x); break;\n\t\t\tcase 1: temp = -cos(x)-sin(x); break;\n\t\t\tcase 2: temp =  cos(x)-sin(x); break;\n\t\t\tdefault:\n\t\t\tcase 3: temp =  cos(x)+sin(x); break;\n\t\t\t}\n\t\t\tb = invsqrtpi*temp/sqrt(x);\n\t\t} else {\n\t\t\ta = j0(x);\n\t\t\tb = j1(x);\n\t\t\tfor (i=0; i<nm1; ) {\n\t\t\t\ti++;\n\t\t\t\ttemp = b;\n\t\t\t\tb = b*(2.0*i/x) - a; /* avoid underflow */\n\t\t\t\ta = temp;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif (ix < 0x3e100000) { /* x < 2**-29 */\n\t\t\t/* x is tiny, return the first Taylor expansion of J(n,x)\n\t\t\t * J(n,x) = 1/n!*(x/2)^n  - ...\n\t\t\t */\n\t\t\tif (nm1 > 32)  /* underflow */\n\t\t\t\tb = 0.0;\n\t\t\telse {\n\t\t\t\ttemp = x*0.5;\n\t\t\t\tb = temp;\n\t\t\t\ta = 1.0;\n\t\t\t\tfor (i=2; i<=nm1+1; i++) {\n\t\t\t\t\ta *= (double)i; /* a = n! */\n\t\t\t\t\tb *= temp;      /* b = (x/2)^n */\n\t\t\t\t}\n\t\t\t\tb = b/a;\n\t\t\t}\n\t\t} else {\n\t\t\t/* use backward recurrence */\n\t\t\t/*                      x      x^2      x^2\n\t\t\t *  J(n,x)/J(n-1,x) =  ----   ------   ------   .....\n\t\t\t *                      2n  - 2(n+1) - 2(n+2)\n\t\t\t *\n\t\t\t *                      1      1        1\n\t\t\t *  (for large x)   =  ----  ------   ------   .....\n\t\t\t *                      2n   2(n+1)   2(n+2)\n\t\t\t *                      -- - ------ - ------ -\n\t\t\t *                       x     x         x\n\t\t\t *\n\t\t\t * Let w = 2n/x and h=2/x, then the above quotient\n\t\t\t * is equal to the continued fraction:\n\t\t\t *                  1\n\t\t\t *      = -----------------------\n\t\t\t *                     1\n\t\t\t *         w - -----------------\n\t\t\t *                        1\n\t\t\t *              w+h - ---------\n\t\t\t *                     w+2h - ...\n\t\t\t *\n\t\t\t * To determine how many terms needed, let\n\t\t\t * Q(0) = w, Q(1) = w(w+h) - 1,\n\t\t\t * Q(k) = (w+k*h)*Q(k-1) - Q(k-2),\n\t\t\t * When Q(k) > 1e4      good for single\n\t\t\t * When Q(k) > 1e9      good for double\n\t\t\t * When Q(k) > 1e17     good for quadruple\n\t\t\t */\n\t\t\t/* determine k */\n\t\t\tdouble t,q0,q1,w,h,z,tmp,nf;\n\t\t\tint k;\n\n\t\t\tnf = nm1 + 1.0;\n\t\t\tw = 2*nf/x;\n\t\t\th = 2/x;\n\t\t\tz = w+h;\n\t\t\tq0 = w;\n\t\t\tq1 = w*z - 1.0;\n\t\t\tk = 1;\n\t\t\twhile (q1 < 1.0e9) {\n\t\t\t\tk += 1;\n\t\t\t\tz += h;\n\t\t\t\ttmp = z*q1 - q0;\n\t\t\t\tq0 = q1;\n\t\t\t\tq1 = tmp;\n\t\t\t}\n\t\t\tfor (t=0.0, i=k; i>=0; i--)\n\t\t\t\tt = 1/(2*(i+nf)/x - t);\n\t\t\ta = t;\n\t\t\tb = 1.0;\n\t\t\t/*  estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n)\n\t\t\t *  Hence, if n*(log(2n/x)) > ...\n\t\t\t *  single 8.8722839355e+01\n\t\t\t *  double 7.09782712893383973096e+02\n\t\t\t *  long double 1.1356523406294143949491931077970765006170e+04\n\t\t\t *  then recurrent value may overflow and the result is\n\t\t\t *  likely underflow to zero\n\t\t\t */\n\t\t\ttmp = nf*log(fabs(w));\n\t\t\tif (tmp < 7.09782712893383973096e+02) {\n\t\t\t\tfor (i=nm1; i>0; i--) {\n\t\t\t\t\ttemp = b;\n\t\t\t\t\tb = b*(2.0*i)/x - a;\n\t\t\t\t\ta = temp;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (i=nm1; i>0; i--) {\n\t\t\t\t\ttemp = b;\n\t\t\t\t\tb = b*(2.0*i)/x - a;\n\t\t\t\t\ta = temp;\n\t\t\t\t\t/* scale b to avoid spurious overflow */\n\t\t\t\t\tif (b > 0x1p500) {\n\t\t\t\t\t\ta /= b;\n\t\t\t\t\t\tt /= b;\n\t\t\t\t\t\tb  = 1.0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tz = j0(x);\n\t\t\tw = j1(x);\n\t\t\tif (fabs(z) >= fabs(w))\n\t\t\t\tb = t*z/b;\n\t\t\telse\n\t\t\t\tb = t*w/a;\n\t\t}\n\t}\n\treturn sign ? -b : b;\n}\n\n\ndouble yn(int n, double x)\n{\n\tuint32_t ix, lx, ib;\n\tint nm1, sign, i;\n\tdouble a, b, temp;\n\n\tEXTRACT_WORDS(ix, lx, x);\n\tsign = ix>>31;\n\tix &= 0x7fffffff;\n\n\tif ((ix | (lx|-lx)>>31) > 0x7ff00000) /* nan */\n\t\treturn x;\n\tif (sign && (ix|lx)!=0) /* x < 0 */\n\t\treturn 0/0.0;\n\tif (ix == 0x7ff00000)\n\t\treturn 0.0;\n\n\tif (n == 0)\n\t\treturn y0(x);\n\tif (n < 0) {\n\t\tnm1 = -(n+1);\n\t\tsign = n&1;\n\t} else {\n\t\tnm1 = n-1;\n\t\tsign = 0;\n\t}\n\tif (nm1 == 0)\n\t\treturn sign ? -y1(x) : y1(x);\n\n\tif (ix >= 0x52d00000) { /* x > 2**302 */\n\t\t/* (x >> n**2)\n\t\t *      Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)\n\t\t *      Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)\n\t\t *      Let s=sin(x), c=cos(x),\n\t\t *          xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then\n\t\t *\n\t\t *             n    sin(xn)*sqt2    cos(xn)*sqt2\n\t\t *          ----------------------------------\n\t\t *             0     s-c             c+s\n\t\t *             1    -s-c            -c+s\n\t\t *             2    -s+c            -c-s\n\t\t *             3     s+c             c-s\n\t\t */\n\t\tswitch(nm1&3) {\n\t\tcase 0: temp = -sin(x)-cos(x); break;\n\t\tcase 1: temp = -sin(x)+cos(x); break;\n\t\tcase 2: temp =  sin(x)+cos(x); break;\n\t\tdefault:\n\t\tcase 3: temp =  sin(x)-cos(x); break;\n\t\t}\n\t\tb = invsqrtpi*temp/sqrt(x);\n\t} else {\n\t\ta = y0(x);\n\t\tb = y1(x);\n\t\t/* quit if b is -inf */\n\t\tGET_HIGH_WORD(ib, b);\n\t\tfor (i=0; i<nm1 && ib!=0xfff00000; ){\n\t\t\ti++;\n\t\t\ttemp = b;\n\t\t\tb = (2.0*i/x)*b - a;\n\t\t\tGET_HIGH_WORD(ib, b);\n\t\t\ta = temp;\n\t\t}\n\t}\n\treturn sign ? -b : b;\n}\n"
  },
  {
    "path": "user.libc/src/math/jnf.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/e_jnf.c */\n/*\n * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.\n */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n\n#define _GNU_SOURCE\n#include \"libm.h\"\n\nfloat jnf(int n, float x)\n{\n\tuint32_t ix;\n\tint nm1, sign, i;\n\tfloat a, b, temp;\n\n\tGET_FLOAT_WORD(ix, x);\n\tsign = ix>>31;\n\tix &= 0x7fffffff;\n\tif (ix > 0x7f800000) /* nan */\n\t\treturn x;\n\n\t/* J(-n,x) = J(n,-x), use |n|-1 to avoid overflow in -n */\n\tif (n == 0)\n\t\treturn j0f(x);\n\tif (n < 0) {\n\t\tnm1 = -(n+1);\n\t\tx = -x;\n\t\tsign ^= 1;\n\t} else\n\t\tnm1 = n-1;\n\tif (nm1 == 0)\n\t\treturn j1f(x);\n\n\tsign &= n;  /* even n: 0, odd n: signbit(x) */\n\tx = fabsf(x);\n\tif (ix == 0 || ix == 0x7f800000)  /* if x is 0 or inf */\n\t\tb = 0.0f;\n\telse if (nm1 < x) {\n\t\t/* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */\n\t\ta = j0f(x);\n\t\tb = j1f(x);\n\t\tfor (i=0; i<nm1; ){\n\t\t\ti++;\n\t\t\ttemp = b;\n\t\t\tb = b*(2.0f*i/x) - a;\n\t\t\ta = temp;\n\t\t}\n\t} else {\n\t\tif (ix < 0x35800000) { /* x < 2**-20 */\n\t\t\t/* x is tiny, return the first Taylor expansion of J(n,x)\n\t\t\t * J(n,x) = 1/n!*(x/2)^n  - ...\n\t\t\t */\n\t\t\tif (nm1 > 8)  /* underflow */\n\t\t\t\tnm1 = 8;\n\t\t\ttemp = 0.5f * x;\n\t\t\tb = temp;\n\t\t\ta = 1.0f;\n\t\t\tfor (i=2; i<=nm1+1; i++) {\n\t\t\t\ta *= (float)i;    /* a = n! */\n\t\t\t\tb *= temp;        /* b = (x/2)^n */\n\t\t\t}\n\t\t\tb = b/a;\n\t\t} else {\n\t\t\t/* use backward recurrence */\n\t\t\t/*                      x      x^2      x^2\n\t\t\t *  J(n,x)/J(n-1,x) =  ----   ------   ------   .....\n\t\t\t *                      2n  - 2(n+1) - 2(n+2)\n\t\t\t *\n\t\t\t *                      1      1        1\n\t\t\t *  (for large x)   =  ----  ------   ------   .....\n\t\t\t *                      2n   2(n+1)   2(n+2)\n\t\t\t *                      -- - ------ - ------ -\n\t\t\t *                       x     x         x\n\t\t\t *\n\t\t\t * Let w = 2n/x and h=2/x, then the above quotient\n\t\t\t * is equal to the continued fraction:\n\t\t\t *                  1\n\t\t\t *      = -----------------------\n\t\t\t *                     1\n\t\t\t *         w - -----------------\n\t\t\t *                        1\n\t\t\t *              w+h - ---------\n\t\t\t *                     w+2h - ...\n\t\t\t *\n\t\t\t * To determine how many terms needed, let\n\t\t\t * Q(0) = w, Q(1) = w(w+h) - 1,\n\t\t\t * Q(k) = (w+k*h)*Q(k-1) - Q(k-2),\n\t\t\t * When Q(k) > 1e4      good for single\n\t\t\t * When Q(k) > 1e9      good for double\n\t\t\t * When Q(k) > 1e17     good for quadruple\n\t\t\t */\n\t\t\t/* determine k */\n\t\t\tfloat t,q0,q1,w,h,z,tmp,nf;\n\t\t\tint k;\n\n\t\t\tnf = nm1+1.0f;\n\t\t\tw = 2*nf/x;\n\t\t\th = 2/x;\n\t\t\tz = w+h;\n\t\t\tq0 = w;\n\t\t\tq1 = w*z - 1.0f;\n\t\t\tk = 1;\n\t\t\twhile (q1 < 1.0e4f) {\n\t\t\t\tk += 1;\n\t\t\t\tz += h;\n\t\t\t\ttmp = z*q1 - q0;\n\t\t\t\tq0 = q1;\n\t\t\t\tq1 = tmp;\n\t\t\t}\n\t\t\tfor (t=0.0f, i=k; i>=0; i--)\n\t\t\t\tt = 1.0f/(2*(i+nf)/x-t);\n\t\t\ta = t;\n\t\t\tb = 1.0f;\n\t\t\t/*  estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n)\n\t\t\t *  Hence, if n*(log(2n/x)) > ...\n\t\t\t *  single 8.8722839355e+01\n\t\t\t *  double 7.09782712893383973096e+02\n\t\t\t *  long double 1.1356523406294143949491931077970765006170e+04\n\t\t\t *  then recurrent value may overflow and the result is\n\t\t\t *  likely underflow to zero\n\t\t\t */\n\t\t\ttmp = nf*logf(fabsf(w));\n\t\t\tif (tmp < 88.721679688f) {\n\t\t\t\tfor (i=nm1; i>0; i--) {\n\t\t\t\t\ttemp = b;\n\t\t\t\t\tb = 2.0f*i*b/x - a;\n\t\t\t\t\ta = temp;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (i=nm1; i>0; i--){\n\t\t\t\t\ttemp = b;\n\t\t\t\t\tb = 2.0f*i*b/x - a;\n\t\t\t\t\ta = temp;\n\t\t\t\t\t/* scale b to avoid spurious overflow */\n\t\t\t\t\tif (b > 0x1p60f) {\n\t\t\t\t\t\ta /= b;\n\t\t\t\t\t\tt /= b;\n\t\t\t\t\t\tb = 1.0f;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tz = j0f(x);\n\t\t\tw = j1f(x);\n\t\t\tif (fabsf(z) >= fabsf(w))\n\t\t\t\tb = t*z/b;\n\t\t\telse\n\t\t\t\tb = t*w/a;\n\t\t}\n\t}\n\treturn sign ? -b : b;\n}\n\nfloat ynf(int n, float x)\n{\n\tuint32_t ix, ib;\n\tint nm1, sign, i;\n\tfloat a, b, temp;\n\n\tGET_FLOAT_WORD(ix, x);\n\tsign = ix>>31;\n\tix &= 0x7fffffff;\n\tif (ix > 0x7f800000) /* nan */\n\t\treturn x;\n\tif (sign && ix != 0) /* x < 0 */\n\t\treturn 0/0.0f;\n\tif (ix == 0x7f800000)\n\t\treturn 0.0f;\n\n\tif (n == 0)\n\t\treturn y0f(x);\n\tif (n < 0) {\n\t\tnm1 = -(n+1);\n\t\tsign = n&1;\n\t} else {\n\t\tnm1 = n-1;\n\t\tsign = 0;\n\t}\n\tif (nm1 == 0)\n\t\treturn sign ? -y1f(x) : y1f(x);\n\n\ta = y0f(x);\n\tb = y1f(x);\n\t/* quit if b is -inf */\n\tGET_FLOAT_WORD(ib,b);\n\tfor (i = 0; i < nm1 && ib != 0xff800000; ) {\n\t\ti++;\n\t\ttemp = b;\n\t\tb = (2.0f*i/x)*b - a;\n\t\tGET_FLOAT_WORD(ib, b);\n\t\ta = temp;\n\t}\n\treturn sign ? -b : b;\n}\n"
  },
  {
    "path": "user.libc/src/math/ldexp.c",
    "content": "#include <math.h>\n\ndouble ldexp(double x, int n)\n{\n\treturn scalbn(x, n);\n}\n"
  },
  {
    "path": "user.libc/src/math/ldexpf.c",
    "content": "#include <math.h>\n\nfloat ldexpf(float x, int n)\n{\n\treturn scalbnf(x, n);\n}\n"
  },
  {
    "path": "user.libc/src/math/ldexpl.c",
    "content": "#include <math.h>\n\nlong double ldexpl(long double x, int n)\n{\n\treturn scalbnl(x, n);\n}\n"
  },
  {
    "path": "user.libc/src/math/lgamma.c",
    "content": "#include <math.h>\n#include \"libm.h\"\n\ndouble lgamma(double x)\n{\n\treturn __lgamma_r(x, &__signgam);\n}\n"
  },
  {
    "path": "user.libc/src/math/lgamma_r.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/e_lgamma_r.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunSoft, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n *\n */\n/* lgamma_r(x, signgamp)\n * Reentrant version of the logarithm of the Gamma function\n * with user provide pointer for the sign of Gamma(x).\n *\n * Method:\n *   1. Argument Reduction for 0 < x <= 8\n *      Since gamma(1+s)=s*gamma(s), for x in [0,8], we may\n *      reduce x to a number in [1.5,2.5] by\n *              lgamma(1+s) = log(s) + lgamma(s)\n *      for example,\n *              lgamma(7.3) = log(6.3) + lgamma(6.3)\n *                          = log(6.3*5.3) + lgamma(5.3)\n *                          = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3)\n *   2. Polynomial approximation of lgamma around its\n *      minimun ymin=1.461632144968362245 to maintain monotonicity.\n *      On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use\n *              Let z = x-ymin;\n *              lgamma(x) = -1.214862905358496078218 + z^2*poly(z)\n *      where\n *              poly(z) is a 14 degree polynomial.\n *   2. Rational approximation in the primary interval [2,3]\n *      We use the following approximation:\n *              s = x-2.0;\n *              lgamma(x) = 0.5*s + s*P(s)/Q(s)\n *      with accuracy\n *              |P/Q - (lgamma(x)-0.5s)| < 2**-61.71\n *      Our algorithms are based on the following observation\n *\n *                             zeta(2)-1    2    zeta(3)-1    3\n * lgamma(2+s) = s*(1-Euler) + --------- * s  -  --------- * s  + ...\n *                                 2                 3\n *\n *      where Euler = 0.5771... is the Euler constant, which is very\n *      close to 0.5.\n *\n *   3. For x>=8, we have\n *      lgamma(x)~(x-0.5)log(x)-x+0.5*log(2pi)+1/(12x)-1/(360x**3)+....\n *      (better formula:\n *         lgamma(x)~(x-0.5)*(log(x)-1)-.5*(log(2pi)-1) + ...)\n *      Let z = 1/x, then we approximation\n *              f(z) = lgamma(x) - (x-0.5)(log(x)-1)\n *      by\n *                                  3       5             11\n *              w = w0 + w1*z + w2*z  + w3*z  + ... + w6*z\n *      where\n *              |w - f(z)| < 2**-58.74\n *\n *   4. For negative x, since (G is gamma function)\n *              -x*G(-x)*G(x) = pi/sin(pi*x),\n *      we have\n *              G(x) = pi/(sin(pi*x)*(-x)*G(-x))\n *      since G(-x) is positive, sign(G(x)) = sign(sin(pi*x)) for x<0\n *      Hence, for x<0, signgam = sign(sin(pi*x)) and\n *              lgamma(x) = log(|Gamma(x)|)\n *                        = log(pi/(|x*sin(pi*x)|)) - lgamma(-x);\n *      Note: one should avoid compute pi*(-x) directly in the\n *            computation of sin(pi*(-x)).\n *\n *   5. Special Cases\n *              lgamma(2+s) ~ s*(1-Euler) for tiny s\n *              lgamma(1) = lgamma(2) = 0\n *              lgamma(x) ~ -log(|x|) for tiny x\n *              lgamma(0) = lgamma(neg.integer) = inf and raise divide-by-zero\n *              lgamma(inf) = inf\n *              lgamma(-inf) = inf (bug for bug compatible with C99!?)\n *\n */\n\n#include \"libm.h\"\n\nstatic const double\npi  =  3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */\na0  =  7.72156649015328655494e-02, /* 0x3FB3C467, 0xE37DB0C8 */\na1  =  3.22467033424113591611e-01, /* 0x3FD4A34C, 0xC4A60FAD */\na2  =  6.73523010531292681824e-02, /* 0x3FB13E00, 0x1A5562A7 */\na3  =  2.05808084325167332806e-02, /* 0x3F951322, 0xAC92547B */\na4  =  7.38555086081402883957e-03, /* 0x3F7E404F, 0xB68FEFE8 */\na5  =  2.89051383673415629091e-03, /* 0x3F67ADD8, 0xCCB7926B */\na6  =  1.19270763183362067845e-03, /* 0x3F538A94, 0x116F3F5D */\na7  =  5.10069792153511336608e-04, /* 0x3F40B6C6, 0x89B99C00 */\na8  =  2.20862790713908385557e-04, /* 0x3F2CF2EC, 0xED10E54D */\na9  =  1.08011567247583939954e-04, /* 0x3F1C5088, 0x987DFB07 */\na10 =  2.52144565451257326939e-05, /* 0x3EFA7074, 0x428CFA52 */\na11 =  4.48640949618915160150e-05, /* 0x3F07858E, 0x90A45837 */\ntc  =  1.46163214496836224576e+00, /* 0x3FF762D8, 0x6356BE3F */\ntf  = -1.21486290535849611461e-01, /* 0xBFBF19B9, 0xBCC38A42 */\n/* tt = -(tail of tf) */\ntt  = -3.63867699703950536541e-18, /* 0xBC50C7CA, 0xA48A971F */\nt0  =  4.83836122723810047042e-01, /* 0x3FDEF72B, 0xC8EE38A2 */\nt1  = -1.47587722994593911752e-01, /* 0xBFC2E427, 0x8DC6C509 */\nt2  =  6.46249402391333854778e-02, /* 0x3FB08B42, 0x94D5419B */\nt3  = -3.27885410759859649565e-02, /* 0xBFA0C9A8, 0xDF35B713 */\nt4  =  1.79706750811820387126e-02, /* 0x3F9266E7, 0x970AF9EC */\nt5  = -1.03142241298341437450e-02, /* 0xBF851F9F, 0xBA91EC6A */\nt6  =  6.10053870246291332635e-03, /* 0x3F78FCE0, 0xE370E344 */\nt7  = -3.68452016781138256760e-03, /* 0xBF6E2EFF, 0xB3E914D7 */\nt8  =  2.25964780900612472250e-03, /* 0x3F6282D3, 0x2E15C915 */\nt9  = -1.40346469989232843813e-03, /* 0xBF56FE8E, 0xBF2D1AF1 */\nt10 =  8.81081882437654011382e-04, /* 0x3F4CDF0C, 0xEF61A8E9 */\nt11 = -5.38595305356740546715e-04, /* 0xBF41A610, 0x9C73E0EC */\nt12 =  3.15632070903625950361e-04, /* 0x3F34AF6D, 0x6C0EBBF7 */\nt13 = -3.12754168375120860518e-04, /* 0xBF347F24, 0xECC38C38 */\nt14 =  3.35529192635519073543e-04, /* 0x3F35FD3E, 0xE8C2D3F4 */\nu0  = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */\nu1  =  6.32827064025093366517e-01, /* 0x3FE4401E, 0x8B005DFF */\nu2  =  1.45492250137234768737e+00, /* 0x3FF7475C, 0xD119BD6F */\nu3  =  9.77717527963372745603e-01, /* 0x3FEF4976, 0x44EA8450 */\nu4  =  2.28963728064692451092e-01, /* 0x3FCD4EAE, 0xF6010924 */\nu5  =  1.33810918536787660377e-02, /* 0x3F8B678B, 0xBF2BAB09 */\nv1  =  2.45597793713041134822e+00, /* 0x4003A5D7, 0xC2BD619C */\nv2  =  2.12848976379893395361e+00, /* 0x40010725, 0xA42B18F5 */\nv3  =  7.69285150456672783825e-01, /* 0x3FE89DFB, 0xE45050AF */\nv4  =  1.04222645593369134254e-01, /* 0x3FBAAE55, 0xD6537C88 */\nv5  =  3.21709242282423911810e-03, /* 0x3F6A5ABB, 0x57D0CF61 */\ns0  = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */\ns1  =  2.14982415960608852501e-01, /* 0x3FCB848B, 0x36E20878 */\ns2  =  3.25778796408930981787e-01, /* 0x3FD4D98F, 0x4F139F59 */\ns3  =  1.46350472652464452805e-01, /* 0x3FC2BB9C, 0xBEE5F2F7 */\ns4  =  2.66422703033638609560e-02, /* 0x3F9B481C, 0x7E939961 */\ns5  =  1.84028451407337715652e-03, /* 0x3F5E26B6, 0x7368F239 */\ns6  =  3.19475326584100867617e-05, /* 0x3F00BFEC, 0xDD17E945 */\nr1  =  1.39200533467621045958e+00, /* 0x3FF645A7, 0x62C4AB74 */\nr2  =  7.21935547567138069525e-01, /* 0x3FE71A18, 0x93D3DCDC */\nr3  =  1.71933865632803078993e-01, /* 0x3FC601ED, 0xCCFBDF27 */\nr4  =  1.86459191715652901344e-02, /* 0x3F9317EA, 0x742ED475 */\nr5  =  7.77942496381893596434e-04, /* 0x3F497DDA, 0xCA41A95B */\nr6  =  7.32668430744625636189e-06, /* 0x3EDEBAF7, 0xA5B38140 */\nw0  =  4.18938533204672725052e-01, /* 0x3FDACFE3, 0x90C97D69 */\nw1  =  8.33333333333329678849e-02, /* 0x3FB55555, 0x5555553B */\nw2  = -2.77777777728775536470e-03, /* 0xBF66C16C, 0x16B02E5C */\nw3  =  7.93650558643019558500e-04, /* 0x3F4A019F, 0x98CF38B6 */\nw4  = -5.95187557450339963135e-04, /* 0xBF4380CB, 0x8C0FE741 */\nw5  =  8.36339918996282139126e-04, /* 0x3F4B67BA, 0x4CDAD5D1 */\nw6  = -1.63092934096575273989e-03; /* 0xBF5AB89D, 0x0B9E43E4 */\n\n/* sin(pi*x) assuming x > 2^-100, if sin(pi*x)==0 the sign is arbitrary */\nstatic double sin_pi(double x)\n{\n\tint n;\n\n\t/* spurious inexact if odd int */\n\tx = 2.0*(x*0.5 - floor(x*0.5));  /* x mod 2.0 */\n\n\tn = (int)(x*4.0);\n\tn = (n+1)/2;\n\tx -= n*0.5f;\n\tx *= pi;\n\n\tswitch (n) {\n\tdefault: /* case 4: */\n\tcase 0: return __sin(x, 0.0, 0);\n\tcase 1: return __cos(x, 0.0);\n\tcase 2: return __sin(-x, 0.0, 0);\n\tcase 3: return -__cos(x, 0.0);\n\t}\n}\n\ndouble __lgamma_r(double x, int *signgamp)\n{\n\tunion {double f; uint64_t i;} u = {x};\n\tdouble_t t,y,z,nadj,p,p1,p2,p3,q,r,w;\n\tuint32_t ix;\n\tint sign,i;\n\n\t/* purge off +-inf, NaN, +-0, tiny and negative arguments */\n\t*signgamp = 1;\n\tsign = u.i>>63;\n\tix = u.i>>32 & 0x7fffffff;\n\tif (ix >= 0x7ff00000)\n\t\treturn x*x;\n\tif (ix < (0x3ff-70)<<20) {  /* |x|<2**-70, return -log(|x|) */\n\t\tif(sign) {\n\t\t\tx = -x;\n\t\t\t*signgamp = -1;\n\t\t}\n\t\treturn -log(x);\n\t}\n\tif (sign) {\n\t\tx = -x;\n\t\tt = sin_pi(x);\n\t\tif (t == 0.0) /* -integer */\n\t\t\treturn 1.0/(x-x);\n\t\tif (t > 0.0)\n\t\t\t*signgamp = -1;\n\t\telse\n\t\t\tt = -t;\n\t\tnadj = log(pi/(t*x));\n\t}\n\n\t/* purge off 1 and 2 */\n\tif ((ix == 0x3ff00000 || ix == 0x40000000) && (uint32_t)u.i == 0)\n\t\tr = 0;\n\t/* for x < 2.0 */\n\telse if (ix < 0x40000000) {\n\t\tif (ix <= 0x3feccccc) {   /* lgamma(x) = lgamma(x+1)-log(x) */\n\t\t\tr = -log(x);\n\t\t\tif (ix >= 0x3FE76944) {\n\t\t\t\ty = 1.0 - x;\n\t\t\t\ti = 0;\n\t\t\t} else if (ix >= 0x3FCDA661) {\n\t\t\t\ty = x - (tc-1.0);\n\t\t\t\ti = 1;\n\t\t\t} else {\n\t\t\t\ty = x;\n\t\t\t\ti = 2;\n\t\t\t}\n\t\t} else {\n\t\t\tr = 0.0;\n\t\t\tif (ix >= 0x3FFBB4C3) {  /* [1.7316,2] */\n\t\t\t\ty = 2.0 - x;\n\t\t\t\ti = 0;\n\t\t\t} else if(ix >= 0x3FF3B4C4) {  /* [1.23,1.73] */\n\t\t\t\ty = x - tc;\n\t\t\t\ti = 1;\n\t\t\t} else {\n\t\t\t\ty = x - 1.0;\n\t\t\t\ti = 2;\n\t\t\t}\n\t\t}\n\t\tswitch (i) {\n\t\tcase 0:\n\t\t\tz = y*y;\n\t\t\tp1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10))));\n\t\t\tp2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11)))));\n\t\t\tp = y*p1+p2;\n\t\t\tr += (p-0.5*y);\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tz = y*y;\n\t\t\tw = z*y;\n\t\t\tp1 = t0+w*(t3+w*(t6+w*(t9 +w*t12)));    /* parallel comp */\n\t\t\tp2 = t1+w*(t4+w*(t7+w*(t10+w*t13)));\n\t\t\tp3 = t2+w*(t5+w*(t8+w*(t11+w*t14)));\n\t\t\tp = z*p1-(tt-w*(p2+y*p3));\n\t\t\tr += tf + p;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tp1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5)))));\n\t\t\tp2 = 1.0+y*(v1+y*(v2+y*(v3+y*(v4+y*v5))));\n\t\t\tr += -0.5*y + p1/p2;\n\t\t}\n\t} else if (ix < 0x40200000) {  /* x < 8.0 */\n\t\ti = (int)x;\n\t\ty = x - (double)i;\n\t\tp = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6))))));\n\t\tq = 1.0+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6)))));\n\t\tr = 0.5*y+p/q;\n\t\tz = 1.0;    /* lgamma(1+s) = log(s) + lgamma(s) */\n\t\tswitch (i) {\n\t\tcase 7: z *= y + 6.0;  /* FALLTHRU */\n\t\tcase 6: z *= y + 5.0;  /* FALLTHRU */\n\t\tcase 5: z *= y + 4.0;  /* FALLTHRU */\n\t\tcase 4: z *= y + 3.0;  /* FALLTHRU */\n\t\tcase 3: z *= y + 2.0;  /* FALLTHRU */\n\t\t\tr += log(z);\n\t\t\tbreak;\n\t\t}\n\t} else if (ix < 0x43900000) {  /* 8.0 <= x < 2**58 */\n\t\tt = log(x);\n\t\tz = 1.0/x;\n\t\ty = z*z;\n\t\tw = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6)))));\n\t\tr = (x-0.5)*(t-1.0)+w;\n\t} else                         /* 2**58 <= x <= inf */\n\t\tr =  x*(log(x)-1.0);\n\tif (sign)\n\t\tr = nadj - r;\n\treturn r;\n}\n\nweak_alias(__lgamma_r, lgamma_r);\n"
  },
  {
    "path": "user.libc/src/math/lgammaf.c",
    "content": "#include <math.h>\n#include \"libm.h\"\n\nfloat lgammaf(float x)\n{\n\treturn __lgammaf_r(x, &__signgam);\n}\n"
  },
  {
    "path": "user.libc/src/math/lgammaf_r.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/e_lgammaf_r.c */\n/*\n * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.\n */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n\n#include \"libm.h\"\n\nstatic const float\npi  =  3.1415927410e+00, /* 0x40490fdb */\na0  =  7.7215664089e-02, /* 0x3d9e233f */\na1  =  3.2246702909e-01, /* 0x3ea51a66 */\na2  =  6.7352302372e-02, /* 0x3d89f001 */\na3  =  2.0580807701e-02, /* 0x3ca89915 */\na4  =  7.3855509982e-03, /* 0x3bf2027e */\na5  =  2.8905137442e-03, /* 0x3b3d6ec6 */\na6  =  1.1927076848e-03, /* 0x3a9c54a1 */\na7  =  5.1006977446e-04, /* 0x3a05b634 */\na8  =  2.2086278477e-04, /* 0x39679767 */\na9  =  1.0801156895e-04, /* 0x38e28445 */\na10 =  2.5214456400e-05, /* 0x37d383a2 */\na11 =  4.4864096708e-05, /* 0x383c2c75 */\ntc  =  1.4616321325e+00, /* 0x3fbb16c3 */\ntf  = -1.2148628384e-01, /* 0xbdf8cdcd */\n/* tt = -(tail of tf) */\ntt  =  6.6971006518e-09, /* 0x31e61c52 */\nt0  =  4.8383611441e-01, /* 0x3ef7b95e */\nt1  = -1.4758771658e-01, /* 0xbe17213c */\nt2  =  6.4624942839e-02, /* 0x3d845a15 */\nt3  = -3.2788541168e-02, /* 0xbd064d47 */\nt4  =  1.7970675603e-02, /* 0x3c93373d */\nt5  = -1.0314224288e-02, /* 0xbc28fcfe */\nt6  =  6.1005386524e-03, /* 0x3bc7e707 */\nt7  = -3.6845202558e-03, /* 0xbb7177fe */\nt8  =  2.2596477065e-03, /* 0x3b141699 */\nt9  = -1.4034647029e-03, /* 0xbab7f476 */\nt10 =  8.8108185446e-04, /* 0x3a66f867 */\nt11 = -5.3859531181e-04, /* 0xba0d3085 */\nt12 =  3.1563205994e-04, /* 0x39a57b6b */\nt13 = -3.1275415677e-04, /* 0xb9a3f927 */\nt14 =  3.3552918467e-04, /* 0x39afe9f7 */\nu0  = -7.7215664089e-02, /* 0xbd9e233f */\nu1  =  6.3282704353e-01, /* 0x3f2200f4 */\nu2  =  1.4549225569e+00, /* 0x3fba3ae7 */\nu3  =  9.7771751881e-01, /* 0x3f7a4bb2 */\nu4  =  2.2896373272e-01, /* 0x3e6a7578 */\nu5  =  1.3381091878e-02, /* 0x3c5b3c5e */\nv1  =  2.4559779167e+00, /* 0x401d2ebe */\nv2  =  2.1284897327e+00, /* 0x4008392d */\nv3  =  7.6928514242e-01, /* 0x3f44efdf */\nv4  =  1.0422264785e-01, /* 0x3dd572af */\nv5  =  3.2170924824e-03, /* 0x3b52d5db */\ns0  = -7.7215664089e-02, /* 0xbd9e233f */\ns1  =  2.1498242021e-01, /* 0x3e5c245a */\ns2  =  3.2577878237e-01, /* 0x3ea6cc7a */\ns3  =  1.4635047317e-01, /* 0x3e15dce6 */\ns4  =  2.6642270386e-02, /* 0x3cda40e4 */\ns5  =  1.8402845599e-03, /* 0x3af135b4 */\ns6  =  3.1947532989e-05, /* 0x3805ff67 */\nr1  =  1.3920053244e+00, /* 0x3fb22d3b */\nr2  =  7.2193557024e-01, /* 0x3f38d0c5 */\nr3  =  1.7193385959e-01, /* 0x3e300f6e */\nr4  =  1.8645919859e-02, /* 0x3c98bf54 */\nr5  =  7.7794247773e-04, /* 0x3a4beed6 */\nr6  =  7.3266842264e-06, /* 0x36f5d7bd */\nw0  =  4.1893854737e-01, /* 0x3ed67f1d */\nw1  =  8.3333335817e-02, /* 0x3daaaaab */\nw2  = -2.7777778450e-03, /* 0xbb360b61 */\nw3  =  7.9365057172e-04, /* 0x3a500cfd */\nw4  = -5.9518753551e-04, /* 0xba1c065c */\nw5  =  8.3633989561e-04, /* 0x3a5b3dd2 */\nw6  = -1.6309292987e-03; /* 0xbad5c4e8 */\n\n/* sin(pi*x) assuming x > 2^-100, if sin(pi*x)==0 the sign is arbitrary */\nstatic float sin_pi(float x)\n{\n\tdouble_t y;\n\tint n;\n\n\t/* spurious inexact if odd int */\n\tx = 2*(x*0.5f - floorf(x*0.5f));  /* x mod 2.0 */\n\n\tn = (int)(x*4);\n\tn = (n+1)/2;\n\ty = x - n*0.5f;\n\ty *= 3.14159265358979323846;\n\tswitch (n) {\n\tdefault: /* case 4: */\n\tcase 0: return __sindf(y);\n\tcase 1: return __cosdf(y);\n\tcase 2: return __sindf(-y);\n\tcase 3: return -__cosdf(y);\n\t}\n}\n\nfloat __lgammaf_r(float x, int *signgamp)\n{\n\tunion {float f; uint32_t i;} u = {x};\n\tfloat t,y,z,nadj,p,p1,p2,p3,q,r,w;\n\tuint32_t ix;\n\tint i,sign;\n\n\t/* purge off +-inf, NaN, +-0, tiny and negative arguments */\n\t*signgamp = 1;\n\tsign = u.i>>31;\n\tix = u.i & 0x7fffffff;\n\tif (ix >= 0x7f800000)\n\t\treturn x*x;\n\tif (ix < 0x35000000) {  /* |x| < 2**-21, return -log(|x|) */\n\t\tif (sign) {\n\t\t\t*signgamp = -1;\n\t\t\tx = -x;\n\t\t}\n\t\treturn -logf(x);\n\t}\n\tif (sign) {\n\t\tx = -x;\n\t\tt = sin_pi(x);\n\t\tif (t == 0.0f) /* -integer */\n\t\t\treturn 1.0f/(x-x);\n\t\tif (t > 0.0f)\n\t\t\t*signgamp = -1;\n\t\telse\n\t\t\tt = -t;\n\t\tnadj = logf(pi/(t*x));\n\t}\n\n\t/* purge off 1 and 2 */\n\tif (ix == 0x3f800000 || ix == 0x40000000)\n\t\tr = 0;\n\t/* for x < 2.0 */\n\telse if (ix < 0x40000000) {\n\t\tif (ix <= 0x3f666666) {  /* lgamma(x) = lgamma(x+1)-log(x) */\n\t\t\tr = -logf(x);\n\t\t\tif (ix >= 0x3f3b4a20) {\n\t\t\t\ty = 1.0f - x;\n\t\t\t\ti = 0;\n\t\t\t} else if (ix >= 0x3e6d3308) {\n\t\t\t\ty = x - (tc-1.0f);\n\t\t\t\ti = 1;\n\t\t\t} else {\n\t\t\t\ty = x;\n\t\t\t\ti = 2;\n\t\t\t}\n\t\t} else {\n\t\t\tr = 0.0f;\n\t\t\tif (ix >= 0x3fdda618) {  /* [1.7316,2] */\n\t\t\t\ty = 2.0f - x;\n\t\t\t\ti = 0;\n\t\t\t} else if (ix >= 0x3F9da620) {  /* [1.23,1.73] */\n\t\t\t\ty = x - tc;\n\t\t\t\ti = 1;\n\t\t\t} else {\n\t\t\t\ty = x - 1.0f;\n\t\t\t\ti = 2;\n\t\t\t}\n\t\t}\n\t\tswitch(i) {\n\t\tcase 0:\n\t\t\tz = y*y;\n\t\t\tp1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10))));\n\t\t\tp2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11)))));\n\t\t\tp = y*p1+p2;\n\t\t\tr += p - 0.5f*y;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tz = y*y;\n\t\t\tw = z*y;\n\t\t\tp1 = t0+w*(t3+w*(t6+w*(t9 +w*t12)));    /* parallel comp */\n\t\t\tp2 = t1+w*(t4+w*(t7+w*(t10+w*t13)));\n\t\t\tp3 = t2+w*(t5+w*(t8+w*(t11+w*t14)));\n\t\t\tp = z*p1-(tt-w*(p2+y*p3));\n\t\t\tr += (tf + p);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tp1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5)))));\n\t\t\tp2 = 1.0f+y*(v1+y*(v2+y*(v3+y*(v4+y*v5))));\n\t\t\tr += -0.5f*y + p1/p2;\n\t\t}\n\t} else if (ix < 0x41000000) {  /* x < 8.0 */\n\t\ti = (int)x;\n\t\ty = x - (float)i;\n\t\tp = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6))))));\n\t\tq = 1.0f+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6)))));\n\t\tr = 0.5f*y+p/q;\n\t\tz = 1.0f;    /* lgamma(1+s) = log(s) + lgamma(s) */\n\t\tswitch (i) {\n\t\tcase 7: z *= y + 6.0f;  /* FALLTHRU */\n\t\tcase 6: z *= y + 5.0f;  /* FALLTHRU */\n\t\tcase 5: z *= y + 4.0f;  /* FALLTHRU */\n\t\tcase 4: z *= y + 3.0f;  /* FALLTHRU */\n\t\tcase 3: z *= y + 2.0f;  /* FALLTHRU */\n\t\t\tr += logf(z);\n\t\t\tbreak;\n\t\t}\n\t} else if (ix < 0x5c800000) {  /* 8.0 <= x < 2**58 */\n\t\tt = logf(x);\n\t\tz = 1.0f/x;\n\t\ty = z*z;\n\t\tw = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6)))));\n\t\tr = (x-0.5f)*(t-1.0f)+w;\n\t} else                         /* 2**58 <= x <= inf */\n\t\tr =  x*(logf(x)-1.0f);\n\tif (sign)\n\t\tr = nadj - r;\n\treturn r;\n}\n\nweak_alias(__lgammaf_r, lgammaf_r);\n"
  },
  {
    "path": "user.libc/src/math/lgammal.c",
    "content": "/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_lgammal.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/*\n * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n/* lgammal(x)\n * Reentrant version of the logarithm of the Gamma function\n * with user provide pointer for the sign of Gamma(x).\n *\n * Method:\n *   1. Argument Reduction for 0 < x <= 8\n *      Since gamma(1+s)=s*gamma(s), for x in [0,8], we may\n *      reduce x to a number in [1.5,2.5] by\n *              lgamma(1+s) = log(s) + lgamma(s)\n *      for example,\n *              lgamma(7.3) = log(6.3) + lgamma(6.3)\n *                          = log(6.3*5.3) + lgamma(5.3)\n *                          = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3)\n *   2. Polynomial approximation of lgamma around its\n *      minimun ymin=1.461632144968362245 to maintain monotonicity.\n *      On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use\n *              Let z = x-ymin;\n *              lgamma(x) = -1.214862905358496078218 + z^2*poly(z)\n *   2. Rational approximation in the primary interval [2,3]\n *      We use the following approximation:\n *              s = x-2.0;\n *              lgamma(x) = 0.5*s + s*P(s)/Q(s)\n *      Our algorithms are based on the following observation\n *\n *                             zeta(2)-1    2    zeta(3)-1    3\n * lgamma(2+s) = s*(1-Euler) + --------- * s  -  --------- * s  + ...\n *                                 2                 3\n *\n *      where Euler = 0.5771... is the Euler constant, which is very\n *      close to 0.5.\n *\n *   3. For x>=8, we have\n *      lgamma(x)~(x-0.5)log(x)-x+0.5*log(2pi)+1/(12x)-1/(360x**3)+....\n *      (better formula:\n *         lgamma(x)~(x-0.5)*(log(x)-1)-.5*(log(2pi)-1) + ...)\n *      Let z = 1/x, then we approximation\n *              f(z) = lgamma(x) - (x-0.5)(log(x)-1)\n *      by\n *                                  3       5             11\n *              w = w0 + w1*z + w2*z  + w3*z  + ... + w6*z\n *\n *   4. For negative x, since (G is gamma function)\n *              -x*G(-x)*G(x) = pi/sin(pi*x),\n *      we have\n *              G(x) = pi/(sin(pi*x)*(-x)*G(-x))\n *      since G(-x) is positive, sign(G(x)) = sign(sin(pi*x)) for x<0\n *      Hence, for x<0, signgam = sign(sin(pi*x)) and\n *              lgamma(x) = log(|Gamma(x)|)\n *                        = log(pi/(|x*sin(pi*x)|)) - lgamma(-x);\n *      Note: one should avoid compute pi*(-x) directly in the\n *            computation of sin(pi*(-x)).\n *\n *   5. Special Cases\n *              lgamma(2+s) ~ s*(1-Euler) for tiny s\n *              lgamma(1)=lgamma(2)=0\n *              lgamma(x) ~ -log(x) for tiny x\n *              lgamma(0) = lgamma(inf) = inf\n *              lgamma(-integer) = +-inf\n *\n */\n\n#define _GNU_SOURCE\n#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double __lgammal_r(long double x, int *sg)\n{\n\treturn __lgamma_r(x, sg);\n}\n#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384\nstatic const long double\npi = 3.14159265358979323846264L,\n\n/* lgam(1+x) = 0.5 x + x a(x)/b(x)\n    -0.268402099609375 <= x <= 0\n    peak relative error 6.6e-22 */\na0 = -6.343246574721079391729402781192128239938E2L,\na1 =  1.856560238672465796768677717168371401378E3L,\na2 =  2.404733102163746263689288466865843408429E3L,\na3 =  8.804188795790383497379532868917517596322E2L,\na4 =  1.135361354097447729740103745999661157426E2L,\na5 =  3.766956539107615557608581581190400021285E0L,\n\nb0 =  8.214973713960928795704317259806842490498E3L,\nb1 =  1.026343508841367384879065363925870888012E4L,\nb2 =  4.553337477045763320522762343132210919277E3L,\nb3 =  8.506975785032585797446253359230031874803E2L,\nb4 =  6.042447899703295436820744186992189445813E1L,\n/* b5 =  1.000000000000000000000000000000000000000E0 */\n\n\ntc =  1.4616321449683623412626595423257213284682E0L,\ntf = -1.2148629053584961146050602565082954242826E-1, /* double precision */\n/* tt = (tail of tf), i.e. tf + tt has extended precision. */\ntt = 3.3649914684731379602768989080467587736363E-18L,\n/* lgam ( 1.4616321449683623412626595423257213284682E0 ) =\n-1.2148629053584960809551455717769158215135617312999903886372437313313530E-1 */\n\n/* lgam (x + tc) = tf + tt + x g(x)/h(x)\n    -0.230003726999612341262659542325721328468 <= x\n       <= 0.2699962730003876587373404576742786715318\n     peak relative error 2.1e-21 */\ng0 = 3.645529916721223331888305293534095553827E-18L,\ng1 = 5.126654642791082497002594216163574795690E3L,\ng2 = 8.828603575854624811911631336122070070327E3L,\ng3 = 5.464186426932117031234820886525701595203E3L,\ng4 = 1.455427403530884193180776558102868592293E3L,\ng5 = 1.541735456969245924860307497029155838446E2L,\ng6 = 4.335498275274822298341872707453445815118E0L,\n\nh0 = 1.059584930106085509696730443974495979641E4L,\nh1 = 2.147921653490043010629481226937850618860E4L,\nh2 = 1.643014770044524804175197151958100656728E4L,\nh3 = 5.869021995186925517228323497501767586078E3L,\nh4 = 9.764244777714344488787381271643502742293E2L,\nh5 = 6.442485441570592541741092969581997002349E1L,\n/* h6 = 1.000000000000000000000000000000000000000E0 */\n\n\n/* lgam (x+1) = -0.5 x + x u(x)/v(x)\n    -0.100006103515625 <= x <= 0.231639862060546875\n    peak relative error 1.3e-21 */\nu0 = -8.886217500092090678492242071879342025627E1L,\nu1 =  6.840109978129177639438792958320783599310E2L,\nu2 =  2.042626104514127267855588786511809932433E3L,\nu3 =  1.911723903442667422201651063009856064275E3L,\nu4 =  7.447065275665887457628865263491667767695E2L,\nu5 =  1.132256494121790736268471016493103952637E2L,\nu6 =  4.484398885516614191003094714505960972894E0L,\n\nv0 =  1.150830924194461522996462401210374632929E3L,\nv1 =  3.399692260848747447377972081399737098610E3L,\nv2 =  3.786631705644460255229513563657226008015E3L,\nv3 =  1.966450123004478374557778781564114347876E3L,\nv4 =  4.741359068914069299837355438370682773122E2L,\nv5 =  4.508989649747184050907206782117647852364E1L,\n/* v6 =  1.000000000000000000000000000000000000000E0 */\n\n\n/* lgam (x+2) = .5 x + x s(x)/r(x)\n     0 <= x <= 1\n     peak relative error 7.2e-22 */\ns0 =  1.454726263410661942989109455292824853344E6L,\ns1 = -3.901428390086348447890408306153378922752E6L,\ns2 = -6.573568698209374121847873064292963089438E6L,\ns3 = -3.319055881485044417245964508099095984643E6L,\ns4 = -7.094891568758439227560184618114707107977E5L,\ns5 = -6.263426646464505837422314539808112478303E4L,\ns6 = -1.684926520999477529949915657519454051529E3L,\n\nr0 = -1.883978160734303518163008696712983134698E7L,\nr1 = -2.815206082812062064902202753264922306830E7L,\nr2 = -1.600245495251915899081846093343626358398E7L,\nr3 = -4.310526301881305003489257052083370058799E6L,\nr4 = -5.563807682263923279438235987186184968542E5L,\nr5 = -3.027734654434169996032905158145259713083E4L,\nr6 = -4.501995652861105629217250715790764371267E2L,\n/* r6 =  1.000000000000000000000000000000000000000E0 */\n\n\n/* lgam(x) = ( x - 0.5 ) * log(x) - x + LS2PI + 1/x w(1/x^2)\n    x >= 8\n    Peak relative error 1.51e-21\nw0 = LS2PI - 0.5 */\nw0 =  4.189385332046727417803e-1L,\nw1 =  8.333333333333331447505E-2L,\nw2 = -2.777777777750349603440E-3L,\nw3 =  7.936507795855070755671E-4L,\nw4 = -5.952345851765688514613E-4L,\nw5 =  8.412723297322498080632E-4L,\nw6 = -1.880801938119376907179E-3L,\nw7 =  4.885026142432270781165E-3L;\n\n/* sin(pi*x) assuming x > 2^-1000, if sin(pi*x)==0 the sign is arbitrary */\nstatic long double sin_pi(long double x)\n{\n\tint n;\n\n\t/* spurious inexact if odd int */\n\tx *= 0.5;\n\tx = 2.0*(x - floorl(x));  /* x mod 2.0 */\n\n\tn = (int)(x*4.0);\n\tn = (n+1)/2;\n\tx -= n*0.5f;\n\tx *= pi;\n\n\tswitch (n) {\n\tdefault: /* case 4: */\n\tcase 0: return __sinl(x, 0.0, 0);\n\tcase 1: return __cosl(x, 0.0);\n\tcase 2: return __sinl(-x, 0.0, 0);\n\tcase 3: return -__cosl(x, 0.0);\n\t}\n}\n\nlong double __lgammal_r(long double x, int *sg) {\n\tlong double t, y, z, nadj, p, p1, p2, q, r, w;\n\tunion ldshape u = {x};\n\tuint32_t ix = (u.i.se & 0x7fffU)<<16 | u.i.m>>48;\n\tint sign = u.i.se >> 15;\n\tint i;\n\n\t*sg = 1;\n\n\t/* purge off +-inf, NaN, +-0, tiny and negative arguments */\n\tif (ix >= 0x7fff0000)\n\t\treturn x * x;\n\tif (ix < 0x3fc08000) {  /* |x|<2**-63, return -log(|x|) */\n\t\tif (sign) {\n\t\t\t*sg = -1;\n\t\t\tx = -x;\n\t\t}\n\t\treturn -logl(x);\n\t}\n\tif (sign) {\n\t\tx = -x;\n\t\tt = sin_pi(x);\n\t\tif (t == 0.0)\n\t\t\treturn 1.0 / (x-x); /* -integer */\n\t\tif (t > 0.0)\n\t\t\t*sg = -1;\n\t\telse\n\t\t\tt = -t;\n\t\tnadj = logl(pi / (t * x));\n\t}\n\n\t/* purge off 1 and 2 (so the sign is ok with downward rounding) */\n\tif ((ix == 0x3fff8000 || ix == 0x40008000) && u.i.m == 0) {\n\t\tr = 0;\n\t} else if (ix < 0x40008000) {  /* x < 2.0 */\n\t\tif (ix <= 0x3ffee666) {  /* 8.99993896484375e-1 */\n\t\t\t/* lgamma(x) = lgamma(x+1) - log(x) */\n\t\t\tr = -logl(x);\n\t\t\tif (ix >= 0x3ffebb4a) {  /* 7.31597900390625e-1 */\n\t\t\t\ty = x - 1.0;\n\t\t\t\ti = 0;\n\t\t\t} else if (ix >= 0x3ffced33) {  /* 2.31639862060546875e-1 */\n\t\t\t\ty = x - (tc - 1.0);\n\t\t\t\ti = 1;\n\t\t\t} else { /* x < 0.23 */\n\t\t\t\ty = x;\n\t\t\t\ti = 2;\n\t\t\t}\n\t\t} else {\n\t\t\tr = 0.0;\n\t\t\tif (ix >= 0x3fffdda6) {  /* 1.73162841796875 */\n\t\t\t\t/* [1.7316,2] */\n\t\t\t\ty = x - 2.0;\n\t\t\t\ti = 0;\n\t\t\t} else if (ix >= 0x3fff9da6) {  /* 1.23162841796875 */\n\t\t\t\t/* [1.23,1.73] */\n\t\t\t\ty = x - tc;\n\t\t\t\ti = 1;\n\t\t\t} else {\n\t\t\t\t/* [0.9, 1.23] */\n\t\t\t\ty = x - 1.0;\n\t\t\t\ti = 2;\n\t\t\t}\n\t\t}\n\t\tswitch (i) {\n\t\tcase 0:\n\t\t\tp1 = a0 + y * (a1 + y * (a2 + y * (a3 + y * (a4 + y * a5))));\n\t\t\tp2 = b0 + y * (b1 + y * (b2 + y * (b3 + y * (b4 + y))));\n\t\t\tr += 0.5 * y + y * p1/p2;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tp1 = g0 + y * (g1 + y * (g2 + y * (g3 + y * (g4 + y * (g5 + y * g6)))));\n\t\t\tp2 = h0 + y * (h1 + y * (h2 + y * (h3 + y * (h4 + y * (h5 + y)))));\n\t\t\tp = tt + y * p1/p2;\n\t\t\tr += (tf + p);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tp1 = y * (u0 + y * (u1 + y * (u2 + y * (u3 + y * (u4 + y * (u5 + y * u6))))));\n\t\t\tp2 = v0 + y * (v1 + y * (v2 + y * (v3 + y * (v4 + y * (v5 + y)))));\n\t\t\tr += (-0.5 * y + p1 / p2);\n\t\t}\n\t} else if (ix < 0x40028000) {  /* 8.0 */\n\t\t/* x < 8.0 */\n\t\ti = (int)x;\n\t\ty = x - (double)i;\n\t\tp = y * (s0 + y * (s1 + y * (s2 + y * (s3 + y * (s4 + y * (s5 + y * s6))))));\n\t\tq = r0 + y * (r1 + y * (r2 + y * (r3 + y * (r4 + y * (r5 + y * (r6 + y))))));\n\t\tr = 0.5 * y + p / q;\n\t\tz = 1.0;\n\t\t/* lgamma(1+s) = log(s) + lgamma(s) */\n\t\tswitch (i) {\n\t\tcase 7:\n\t\t\tz *= (y + 6.0); /* FALLTHRU */\n\t\tcase 6:\n\t\t\tz *= (y + 5.0); /* FALLTHRU */\n\t\tcase 5:\n\t\t\tz *= (y + 4.0); /* FALLTHRU */\n\t\tcase 4:\n\t\t\tz *= (y + 3.0); /* FALLTHRU */\n\t\tcase 3:\n\t\t\tz *= (y + 2.0); /* FALLTHRU */\n\t\t\tr += logl(z);\n\t\t\tbreak;\n\t\t}\n\t} else if (ix < 0x40418000) {  /* 2^66 */\n\t\t/* 8.0 <= x < 2**66 */\n\t\tt = logl(x);\n\t\tz = 1.0 / x;\n\t\ty = z * z;\n\t\tw = w0 + z * (w1 + y * (w2 + y * (w3 + y * (w4 + y * (w5 + y * (w6 + y * w7))))));\n\t\tr = (x - 0.5) * (t - 1.0) + w;\n\t} else /* 2**66 <= x <= inf */\n\t\tr = x * (logl(x) - 1.0);\n\tif (sign)\n\t\tr = nadj - r;\n\treturn r;\n}\n#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384\n// TODO: broken implementation to make things compile\nlong double __lgammal_r(long double x, int *sg)\n{\n\treturn __lgamma_r(x, sg);\n}\n#endif\n\nlong double lgammal(long double x)\n{\n\treturn __lgammal_r(x, &__signgam);\n}\n\nweak_alias(__lgammal_r, lgammal_r);\n"
  },
  {
    "path": "user.libc/src/math/llrint.c",
    "content": "#include <math.h>\n\n/* uses LLONG_MAX > 2^53, see comments in lrint.c */\n\nlong long llrint(double x)\n{\n\treturn rint(x);\n}\n"
  },
  {
    "path": "user.libc/src/math/llrintf.c",
    "content": "#include <math.h>\n\n/* uses LLONG_MAX > 2^24, see comments in lrint.c */\n\nlong long llrintf(float x)\n{\n\treturn rintf(x);\n}\n"
  },
  {
    "path": "user.libc/src/math/llrintl.c",
    "content": "#include <limits.h>\n#include <fenv.h>\n#include \"libm.h\"\n\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong long llrintl(long double x)\n{\n\treturn llrint(x);\n}\n#elif defined(FE_INEXACT)\n/*\nsee comments in lrint.c\n\nNote that if LLONG_MAX == 0x7fffffffffffffff && LDBL_MANT_DIG == 64\nthen x == 2**63 - 0.5 is the only input that overflows and\nraises inexact (with tonearest or upward rounding mode)\n*/\nlong long llrintl(long double x)\n{\n\t#pragma STDC FENV_ACCESS ON\n\tint e;\n\n\te = fetestexcept(FE_INEXACT);\n\tx = rintl(x);\n\tif (!e && (x > LLONG_MAX || x < LLONG_MIN))\n\t\tfeclearexcept(FE_INEXACT);\n\t/* conversion */\n\treturn x;\n}\n#else\nlong long llrintl(long double x)\n{\n\treturn rintl(x);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/llround.c",
    "content": "#include <math.h>\n\nlong long llround(double x)\n{\n\treturn round(x);\n}\n"
  },
  {
    "path": "user.libc/src/math/llroundf.c",
    "content": "#include <math.h>\n\nlong long llroundf(float x)\n{\n\treturn roundf(x);\n}\n"
  },
  {
    "path": "user.libc/src/math/llroundl.c",
    "content": "#include <math.h>\n\nlong long llroundl(long double x)\n{\n\treturn roundl(x);\n}\n"
  },
  {
    "path": "user.libc/src/math/log.c",
    "content": "/*\n * Double-precision log(x) function.\n *\n * Copyright (c) 2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n\n#include <math.h>\n#include <stdint.h>\n#include \"libm.h\"\n#include \"log_data.h\"\n\n#define T __log_data.tab\n#define T2 __log_data.tab2\n#define B __log_data.poly1\n#define A __log_data.poly\n#define Ln2hi __log_data.ln2hi\n#define Ln2lo __log_data.ln2lo\n#define N (1 << LOG_TABLE_BITS)\n#define OFF 0x3fe6000000000000\n\n/* Top 16 bits of a double.  */\nstatic inline uint32_t top16(double x)\n{\n\treturn asuint64(x) >> 48;\n}\n\ndouble log(double x)\n{\n\tdouble_t w, z, r, r2, r3, y, invc, logc, kd, hi, lo;\n\tuint64_t ix, iz, tmp;\n\tuint32_t top;\n\tint k, i;\n\n\tix = asuint64(x);\n\ttop = top16(x);\n#define LO asuint64(1.0 - 0x1p-4)\n#define HI asuint64(1.0 + 0x1.09p-4)\n\tif (predict_false(ix - LO < HI - LO)) {\n\t\t/* Handle close to 1.0 inputs separately.  */\n\t\t/* Fix sign of zero with downward rounding when x==1.  */\n\t\tif (WANT_ROUNDING && predict_false(ix == asuint64(1.0)))\n\t\t\treturn 0;\n\t\tr = x - 1.0;\n\t\tr2 = r * r;\n\t\tr3 = r * r2;\n\t\ty = r3 *\n\t\t    (B[1] + r * B[2] + r2 * B[3] +\n\t\t     r3 * (B[4] + r * B[5] + r2 * B[6] +\n\t\t\t   r3 * (B[7] + r * B[8] + r2 * B[9] + r3 * B[10])));\n\t\t/* Worst-case error is around 0.507 ULP.  */\n\t\tw = r * 0x1p27;\n\t\tdouble_t rhi = r + w - w;\n\t\tdouble_t rlo = r - rhi;\n\t\tw = rhi * rhi * B[0]; /* B[0] == -0.5.  */\n\t\thi = r + w;\n\t\tlo = r - hi + w;\n\t\tlo += B[0] * rlo * (rhi + r);\n\t\ty += lo;\n\t\ty += hi;\n\t\treturn eval_as_double(y);\n\t}\n\tif (predict_false(top - 0x0010 >= 0x7ff0 - 0x0010)) {\n\t\t/* x < 0x1p-1022 or inf or nan.  */\n\t\tif (ix * 2 == 0)\n\t\t\treturn __math_divzero(1);\n\t\tif (ix == asuint64(INFINITY)) /* log(inf) == inf.  */\n\t\t\treturn x;\n\t\tif ((top & 0x8000) || (top & 0x7ff0) == 0x7ff0)\n\t\t\treturn __math_invalid(x);\n\t\t/* x is subnormal, normalize it.  */\n\t\tix = asuint64(x * 0x1p52);\n\t\tix -= 52ULL << 52;\n\t}\n\n\t/* x = 2^k z; where z is in range [OFF,2*OFF) and exact.\n\t   The range is split into N subintervals.\n\t   The ith subinterval contains z and c is near its center.  */\n\ttmp = ix - OFF;\n\ti = (tmp >> (52 - LOG_TABLE_BITS)) % N;\n\tk = (int64_t)tmp >> 52; /* arithmetic shift */\n\tiz = ix - (tmp & 0xfffULL << 52);\n\tinvc = T[i].invc;\n\tlogc = T[i].logc;\n\tz = asdouble(iz);\n\n\t/* log(x) = log1p(z/c-1) + log(c) + k*Ln2.  */\n\t/* r ~= z/c - 1, |r| < 1/(2*N).  */\n#if __FP_FAST_FMA\n\t/* rounding error: 0x1p-55/N.  */\n\tr = __builtin_fma(z, invc, -1.0);\n#else\n\t/* rounding error: 0x1p-55/N + 0x1p-66.  */\n\tr = (z - T2[i].chi - T2[i].clo) * invc;\n#endif\n\tkd = (double_t)k;\n\n\t/* hi + lo = r + log(c) + k*Ln2.  */\n\tw = kd * Ln2hi + logc;\n\thi = w + r;\n\tlo = w - hi + r + kd * Ln2lo;\n\n\t/* log(x) = lo + (log1p(r) - r) + hi.  */\n\tr2 = r * r; /* rounding error: 0x1p-54/N^2.  */\n\t/* Worst case error if |y| > 0x1p-5:\n\t   0.5 + 4.13/N + abs-poly-error*2^57 ULP (+ 0.002 ULP without fma)\n\t   Worst case error if |y| > 0x1p-4:\n\t   0.5 + 2.06/N + abs-poly-error*2^56 ULP (+ 0.001 ULP without fma).  */\n\ty = lo + r2 * A[0] +\n\t    r * r2 * (A[1] + r * A[2] + r2 * (A[3] + r * A[4])) + hi;\n\treturn eval_as_double(y);\n}\n"
  },
  {
    "path": "user.libc/src/math/log10.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/e_log10.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunSoft, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/*\n * Return the base 10 logarithm of x.  See log.c for most comments.\n *\n * Reduce x to 2^k (1+f) and calculate r = log(1+f) - f + f*f/2\n * as in log.c, then combine and scale in extra precision:\n *    log10(x) = (f - f*f/2 + r)/log(10) + k*log10(2)\n */\n\n#include <math.h>\n#include <stdint.h>\n\nstatic const double\nivln10hi  = 4.34294481878168880939e-01, /* 0x3fdbcb7b, 0x15200000 */\nivln10lo  = 2.50829467116452752298e-11, /* 0x3dbb9438, 0xca9aadd5 */\nlog10_2hi = 3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */\nlog10_2lo = 3.69423907715893078616e-13, /* 0x3D59FEF3, 0x11F12B36 */\nLg1 = 6.666666666666735130e-01,  /* 3FE55555 55555593 */\nLg2 = 3.999999999940941908e-01,  /* 3FD99999 9997FA04 */\nLg3 = 2.857142874366239149e-01,  /* 3FD24924 94229359 */\nLg4 = 2.222219843214978396e-01,  /* 3FCC71C5 1D8E78AF */\nLg5 = 1.818357216161805012e-01,  /* 3FC74664 96CB03DE */\nLg6 = 1.531383769920937332e-01,  /* 3FC39A09 D078C69F */\nLg7 = 1.479819860511658591e-01;  /* 3FC2F112 DF3E5244 */\n\ndouble log10(double x)\n{\n\tunion {double f; uint64_t i;} u = {x};\n\tdouble_t hfsq,f,s,z,R,w,t1,t2,dk,y,hi,lo,val_hi,val_lo;\n\tuint32_t hx;\n\tint k;\n\n\thx = u.i>>32;\n\tk = 0;\n\tif (hx < 0x00100000 || hx>>31) {\n\t\tif (u.i<<1 == 0)\n\t\t\treturn -1/(x*x);  /* log(+-0)=-inf */\n\t\tif (hx>>31)\n\t\t\treturn (x-x)/0.0; /* log(-#) = NaN */\n\t\t/* subnormal number, scale x up */\n\t\tk -= 54;\n\t\tx *= 0x1p54;\n\t\tu.f = x;\n\t\thx = u.i>>32;\n\t} else if (hx >= 0x7ff00000) {\n\t\treturn x;\n\t} else if (hx == 0x3ff00000 && u.i<<32 == 0)\n\t\treturn 0;\n\n\t/* reduce x into [sqrt(2)/2, sqrt(2)] */\n\thx += 0x3ff00000 - 0x3fe6a09e;\n\tk += (int)(hx>>20) - 0x3ff;\n\thx = (hx&0x000fffff) + 0x3fe6a09e;\n\tu.i = (uint64_t)hx<<32 | (u.i&0xffffffff);\n\tx = u.f;\n\n\tf = x - 1.0;\n\thfsq = 0.5*f*f;\n\ts = f/(2.0+f);\n\tz = s*s;\n\tw = z*z;\n\tt1 = w*(Lg2+w*(Lg4+w*Lg6));\n\tt2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));\n\tR = t2 + t1;\n\n\t/* See log2.c for details. */\n\t/* hi+lo = f - hfsq + s*(hfsq+R) ~ log(1+f) */\n\thi = f - hfsq;\n\tu.f = hi;\n\tu.i &= (uint64_t)-1<<32;\n\thi = u.f;\n\tlo = f - hi - hfsq + s*(hfsq+R);\n\n\t/* val_hi+val_lo ~ log10(1+f) + k*log10(2) */\n\tval_hi = hi*ivln10hi;\n\tdk = k;\n\ty = dk*log10_2hi;\n\tval_lo = dk*log10_2lo + (lo+hi)*ivln10lo + lo*ivln10hi;\n\n\t/*\n\t * Extra precision in for adding y is not strictly needed\n\t * since there is no very large cancellation near x = sqrt(2) or\n\t * x = 1/sqrt(2), but we do it anyway since it costs little on CPUs\n\t * with some parallelism and it reduces the error for many args.\n\t */\n\tw = y + val_hi;\n\tval_lo += (y - w) + val_hi;\n\tval_hi = w;\n\n\treturn val_lo + val_hi;\n}\n"
  },
  {
    "path": "user.libc/src/math/log10f.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/e_log10f.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/*\n * See comments in log10.c.\n */\n\n#include <math.h>\n#include <stdint.h>\n\nstatic const float\nivln10hi  =  4.3432617188e-01, /* 0x3ede6000 */\nivln10lo  = -3.1689971365e-05, /* 0xb804ead9 */\nlog10_2hi =  3.0102920532e-01, /* 0x3e9a2080 */\nlog10_2lo =  7.9034151668e-07, /* 0x355427db */\n/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */\nLg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */\nLg2 = 0xccce13.0p-25, /* 0.40000972152 */\nLg3 = 0x91e9ee.0p-25, /* 0.28498786688 */\nLg4 = 0xf89e26.0p-26; /* 0.24279078841 */\n\nfloat log10f(float x)\n{\n\tunion {float f; uint32_t i;} u = {x};\n\tfloat_t hfsq,f,s,z,R,w,t1,t2,dk,hi,lo;\n\tuint32_t ix;\n\tint k;\n\n\tix = u.i;\n\tk = 0;\n\tif (ix < 0x00800000 || ix>>31) {  /* x < 2**-126  */\n\t\tif (ix<<1 == 0)\n\t\t\treturn -1/(x*x);  /* log(+-0)=-inf */\n\t\tif (ix>>31)\n\t\t\treturn (x-x)/0.0f; /* log(-#) = NaN */\n\t\t/* subnormal number, scale up x */\n\t\tk -= 25;\n\t\tx *= 0x1p25f;\n\t\tu.f = x;\n\t\tix = u.i;\n\t} else if (ix >= 0x7f800000) {\n\t\treturn x;\n\t} else if (ix == 0x3f800000)\n\t\treturn 0;\n\n\t/* reduce x into [sqrt(2)/2, sqrt(2)] */\n\tix += 0x3f800000 - 0x3f3504f3;\n\tk += (int)(ix>>23) - 0x7f;\n\tix = (ix&0x007fffff) + 0x3f3504f3;\n\tu.i = ix;\n\tx = u.f;\n\n\tf = x - 1.0f;\n\ts = f/(2.0f + f);\n\tz = s*s;\n\tw = z*z;\n\tt1= w*(Lg2+w*Lg4);\n\tt2= z*(Lg1+w*Lg3);\n\tR = t2 + t1;\n\thfsq = 0.5f*f*f;\n\n\thi = f - hfsq;\n\tu.f = hi;\n\tu.i &= 0xfffff000;\n\thi = u.f;\n\tlo = f - hi - hfsq + s*(hfsq+R);\n\tdk = k;\n\treturn dk*log10_2lo + (lo+hi)*ivln10lo + lo*ivln10hi + hi*ivln10hi + dk*log10_2hi;\n}\n"
  },
  {
    "path": "user.libc/src/math/log10l.c",
    "content": "/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_log10l.c */\n/*\n * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n/*\n *      Common logarithm, long double precision\n *\n *\n * SYNOPSIS:\n *\n * long double x, y, log10l();\n *\n * y = log10l( x );\n *\n *\n * DESCRIPTION:\n *\n * Returns the base 10 logarithm of x.\n *\n * The argument is separated into its exponent and fractional\n * parts.  If the exponent is between -1 and +1, the logarithm\n * of the fraction is approximated by\n *\n *     log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x).\n *\n * Otherwise, setting  z = 2(x-1)/x+1),\n *\n *     log(x) = z + z**3 P(z)/Q(z).\n *\n *\n * ACCURACY:\n *\n *                      Relative error:\n * arithmetic   domain     # trials      peak         rms\n *    IEEE      0.5, 2.0     30000      9.0e-20     2.6e-20\n *    IEEE     exp(+-10000)  30000      6.0e-20     2.3e-20\n *\n * In the tests over the interval exp(+-10000), the logarithms\n * of the random arguments were uniformly distributed over\n * [-10000, +10000].\n *\n * ERROR MESSAGES:\n *\n * log singularity:  x = 0; returns MINLOG\n * log domain:       x < 0; returns MINLOG\n */\n\n#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double log10l(long double x)\n{\n\treturn log10(x);\n}\n#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384\n/* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x)\n * 1/sqrt(2) <= x < sqrt(2)\n * Theoretical peak relative error = 6.2e-22\n */\nstatic const long double P[] = {\n 4.9962495940332550844739E-1L,\n 1.0767376367209449010438E1L,\n 7.7671073698359539859595E1L,\n 2.5620629828144409632571E2L,\n 4.2401812743503691187826E2L,\n 3.4258224542413922935104E2L,\n 1.0747524399916215149070E2L,\n};\nstatic const long double Q[] = {\n/* 1.0000000000000000000000E0,*/\n 2.3479774160285863271658E1L,\n 1.9444210022760132894510E2L,\n 7.7952888181207260646090E2L,\n 1.6911722418503949084863E3L,\n 2.0307734695595183428202E3L,\n 1.2695660352705325274404E3L,\n 3.2242573199748645407652E2L,\n};\n\n/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),\n * where z = 2(x-1)/(x+1)\n * 1/sqrt(2) <= x < sqrt(2)\n * Theoretical peak relative error = 6.16e-22\n */\nstatic const long double R[4] = {\n 1.9757429581415468984296E-3L,\n-7.1990767473014147232598E-1L,\n 1.0777257190312272158094E1L,\n-3.5717684488096787370998E1L,\n};\nstatic const long double S[4] = {\n/* 1.00000000000000000000E0L,*/\n-2.6201045551331104417768E1L,\n 1.9361891836232102174846E2L,\n-4.2861221385716144629696E2L,\n};\n/* log10(2) */\n#define L102A 0.3125L\n#define L102B -1.1470004336018804786261e-2L\n/* log10(e) */\n#define L10EA 0.5L\n#define L10EB -6.5705518096748172348871e-2L\n\n#define SQRTH 0.70710678118654752440L\n\nlong double log10l(long double x)\n{\n\tlong double y, z;\n\tint e;\n\n\tif (isnan(x))\n\t\treturn x;\n\tif(x <= 0.0) {\n\t\tif(x == 0.0)\n\t\t\treturn -1.0 / (x*x);\n\t\treturn (x - x) / 0.0;\n\t}\n\tif (x == INFINITY)\n\t\treturn INFINITY;\n\t/* separate mantissa from exponent */\n\t/* Note, frexp is used so that denormal numbers\n\t * will be handled properly.\n\t */\n\tx = frexpl(x, &e);\n\n\t/* logarithm using log(x) = z + z**3 P(z)/Q(z),\n\t * where z = 2(x-1)/x+1)\n\t */\n\tif (e > 2 || e < -2) {\n\t\tif (x < SQRTH) {  /* 2(2x-1)/(2x+1) */\n\t\t\te -= 1;\n\t\t\tz = x - 0.5;\n\t\t\ty = 0.5 * z + 0.5;\n\t\t} else {  /*  2 (x-1)/(x+1)   */\n\t\t\tz = x - 0.5;\n\t\t\tz -= 0.5;\n\t\t\ty = 0.5 * x  + 0.5;\n\t\t}\n\t\tx = z / y;\n\t\tz = x*x;\n\t\ty = x * (z * __polevll(z, R, 3) / __p1evll(z, S, 3));\n\t\tgoto done;\n\t}\n\n\t/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */\n\tif (x < SQRTH) {\n\t\te -= 1;\n\t\tx = 2.0*x - 1.0;\n\t} else {\n\t\tx = x - 1.0;\n\t}\n\tz = x*x;\n\ty = x * (z * __polevll(x, P, 6) / __p1evll(x, Q, 7));\n\ty = y - 0.5*z;\n\ndone:\n\t/* Multiply log of fraction by log10(e)\n\t * and base 2 exponent by log10(2).\n\t *\n\t * ***CAUTION***\n\t *\n\t * This sequence of operations is critical and it may\n\t * be horribly defeated by some compiler optimizers.\n\t */\n\tz = y * (L10EB);\n\tz += x * (L10EB);\n\tz += e * (L102B);\n\tz += y * (L10EA);\n\tz += x * (L10EA);\n\tz += e * (L102A);\n\treturn z;\n}\n#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384\n// TODO: broken implementation to make things compile\nlong double log10l(long double x)\n{\n\treturn log10(x);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/log1p.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_log1p.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/* double log1p(double x)\n * Return the natural logarithm of 1+x.\n *\n * Method :\n *   1. Argument Reduction: find k and f such that\n *                      1+x = 2^k * (1+f),\n *         where  sqrt(2)/2 < 1+f < sqrt(2) .\n *\n *      Note. If k=0, then f=x is exact. However, if k!=0, then f\n *      may not be representable exactly. In that case, a correction\n *      term is need. Let u=1+x rounded. Let c = (1+x)-u, then\n *      log(1+x) - log(u) ~ c/u. Thus, we proceed to compute log(u),\n *      and add back the correction term c/u.\n *      (Note: when x > 2**53, one can simply return log(x))\n *\n *   2. Approximation of log(1+f): See log.c\n *\n *   3. Finally, log1p(x) = k*ln2 + log(1+f) + c/u. See log.c\n *\n * Special cases:\n *      log1p(x) is NaN with signal if x < -1 (including -INF) ;\n *      log1p(+INF) is +INF; log1p(-1) is -INF with signal;\n *      log1p(NaN) is that NaN with no signal.\n *\n * Accuracy:\n *      according to an error analysis, the error is always less than\n *      1 ulp (unit in the last place).\n *\n * Constants:\n * The hexadecimal values are the intended ones for the following\n * constants. The decimal values may be used, provided that the\n * compiler will convert from decimal to binary accurately enough\n * to produce the hexadecimal values shown.\n *\n * Note: Assuming log() return accurate answer, the following\n *       algorithm can be used to compute log1p(x) to within a few ULP:\n *\n *              u = 1+x;\n *              if(u==1.0) return x ; else\n *                         return log(u)*(x/(u-1.0));\n *\n *       See HP-15C Advanced Functions Handbook, p.193.\n */\n\n#include \"libm.h\"\n\nstatic const double\nln2_hi = 6.93147180369123816490e-01,  /* 3fe62e42 fee00000 */\nln2_lo = 1.90821492927058770002e-10,  /* 3dea39ef 35793c76 */\nLg1 = 6.666666666666735130e-01,  /* 3FE55555 55555593 */\nLg2 = 3.999999999940941908e-01,  /* 3FD99999 9997FA04 */\nLg3 = 2.857142874366239149e-01,  /* 3FD24924 94229359 */\nLg4 = 2.222219843214978396e-01,  /* 3FCC71C5 1D8E78AF */\nLg5 = 1.818357216161805012e-01,  /* 3FC74664 96CB03DE */\nLg6 = 1.531383769920937332e-01,  /* 3FC39A09 D078C69F */\nLg7 = 1.479819860511658591e-01;  /* 3FC2F112 DF3E5244 */\n\ndouble log1p(double x)\n{\n\tunion {double f; uint64_t i;} u = {x};\n\tdouble_t hfsq,f,c,s,z,R,w,t1,t2,dk;\n\tuint32_t hx,hu;\n\tint k;\n\n\thx = u.i>>32;\n\tk = 1;\n\tif (hx < 0x3fda827a || hx>>31) {  /* 1+x < sqrt(2)+ */\n\t\tif (hx >= 0xbff00000) {  /* x <= -1.0 */\n\t\t\tif (x == -1)\n\t\t\t\treturn x/0.0; /* log1p(-1) = -inf */\n\t\t\treturn (x-x)/0.0;     /* log1p(x<-1) = NaN */\n\t\t}\n\t\tif (hx<<1 < 0x3ca00000<<1) {  /* |x| < 2**-53 */\n\t\t\t/* underflow if subnormal */\n\t\t\tif ((hx&0x7ff00000) == 0)\n\t\t\t\tFORCE_EVAL((float)x);\n\t\t\treturn x;\n\t\t}\n\t\tif (hx <= 0xbfd2bec4) {  /* sqrt(2)/2- <= 1+x < sqrt(2)+ */\n\t\t\tk = 0;\n\t\t\tc = 0;\n\t\t\tf = x;\n\t\t}\n\t} else if (hx >= 0x7ff00000)\n\t\treturn x;\n\tif (k) {\n\t\tu.f = 1 + x;\n\t\thu = u.i>>32;\n\t\thu += 0x3ff00000 - 0x3fe6a09e;\n\t\tk = (int)(hu>>20) - 0x3ff;\n\t\t/* correction term ~ log(1+x)-log(u), avoid underflow in c/u */\n\t\tif (k < 54) {\n\t\t\tc = k >= 2 ? 1-(u.f-x) : x-(u.f-1);\n\t\t\tc /= u.f;\n\t\t} else\n\t\t\tc = 0;\n\t\t/* reduce u into [sqrt(2)/2, sqrt(2)] */\n\t\thu = (hu&0x000fffff) + 0x3fe6a09e;\n\t\tu.i = (uint64_t)hu<<32 | (u.i&0xffffffff);\n\t\tf = u.f - 1;\n\t}\n\thfsq = 0.5*f*f;\n\ts = f/(2.0+f);\n\tz = s*s;\n\tw = z*z;\n\tt1 = w*(Lg2+w*(Lg4+w*Lg6));\n\tt2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));\n\tR = t2 + t1;\n\tdk = k;\n\treturn s*(hfsq+R) + (dk*ln2_lo+c) - hfsq + f + dk*ln2_hi;\n}\n"
  },
  {
    "path": "user.libc/src/math/log1pf.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_log1pf.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n\n#include \"libm.h\"\n\nstatic const float\nln2_hi = 6.9313812256e-01, /* 0x3f317180 */\nln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */\n/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */\nLg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */\nLg2 = 0xccce13.0p-25, /* 0.40000972152 */\nLg3 = 0x91e9ee.0p-25, /* 0.28498786688 */\nLg4 = 0xf89e26.0p-26; /* 0.24279078841 */\n\nfloat log1pf(float x)\n{\n\tunion {float f; uint32_t i;} u = {x};\n\tfloat_t hfsq,f,c,s,z,R,w,t1,t2,dk;\n\tuint32_t ix,iu;\n\tint k;\n\n\tix = u.i;\n\tk = 1;\n\tif (ix < 0x3ed413d0 || ix>>31) {  /* 1+x < sqrt(2)+  */\n\t\tif (ix >= 0xbf800000) {  /* x <= -1.0 */\n\t\t\tif (x == -1)\n\t\t\t\treturn x/0.0f; /* log1p(-1)=+inf */\n\t\t\treturn (x-x)/0.0f;     /* log1p(x<-1)=NaN */\n\t\t}\n\t\tif (ix<<1 < 0x33800000<<1) {   /* |x| < 2**-24 */\n\t\t\t/* underflow if subnormal */\n\t\t\tif ((ix&0x7f800000) == 0)\n\t\t\t\tFORCE_EVAL(x*x);\n\t\t\treturn x;\n\t\t}\n\t\tif (ix <= 0xbe95f619) { /* sqrt(2)/2- <= 1+x < sqrt(2)+ */\n\t\t\tk = 0;\n\t\t\tc = 0;\n\t\t\tf = x;\n\t\t}\n\t} else if (ix >= 0x7f800000)\n\t\treturn x;\n\tif (k) {\n\t\tu.f = 1 + x;\n\t\tiu = u.i;\n\t\tiu += 0x3f800000 - 0x3f3504f3;\n\t\tk = (int)(iu>>23) - 0x7f;\n\t\t/* correction term ~ log(1+x)-log(u), avoid underflow in c/u */\n\t\tif (k < 25) {\n\t\t\tc = k >= 2 ? 1-(u.f-x) : x-(u.f-1);\n\t\t\tc /= u.f;\n\t\t} else\n\t\t\tc = 0;\n\t\t/* reduce u into [sqrt(2)/2, sqrt(2)] */\n\t\tiu = (iu&0x007fffff) + 0x3f3504f3;\n\t\tu.i = iu;\n\t\tf = u.f - 1;\n\t}\n\ts = f/(2.0f + f);\n\tz = s*s;\n\tw = z*z;\n\tt1= w*(Lg2+w*Lg4);\n\tt2= z*(Lg1+w*Lg3);\n\tR = t2 + t1;\n\thfsq = 0.5f*f*f;\n\tdk = k;\n\treturn s*(hfsq+R) + (dk*ln2_lo+c) - hfsq + f + dk*ln2_hi;\n}\n"
  },
  {
    "path": "user.libc/src/math/log1pl.c",
    "content": "/* origin: OpenBSD /usr/src/lib/libm/src/ld80/s_log1pl.c */\n/*\n * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n/*\n *      Relative error logarithm\n *      Natural logarithm of 1+x, long double precision\n *\n *\n * SYNOPSIS:\n *\n * long double x, y, log1pl();\n *\n * y = log1pl( x );\n *\n *\n * DESCRIPTION:\n *\n * Returns the base e (2.718...) logarithm of 1+x.\n *\n * The argument 1+x is separated into its exponent and fractional\n * parts.  If the exponent is between -1 and +1, the logarithm\n * of the fraction is approximated by\n *\n *     log(1+x) = x - 0.5 x^2 + x^3 P(x)/Q(x).\n *\n * Otherwise, setting  z = 2(x-1)/x+1),\n *\n *     log(x) = z + z^3 P(z)/Q(z).\n *\n *\n * ACCURACY:\n *\n *                      Relative error:\n * arithmetic   domain     # trials      peak         rms\n *    IEEE     -1.0, 9.0    100000      8.2e-20    2.5e-20\n */\n\n#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double log1pl(long double x)\n{\n\treturn log1p(x);\n}\n#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384\n/* Coefficients for log(1+x) = x - x^2 / 2 + x^3 P(x)/Q(x)\n * 1/sqrt(2) <= x < sqrt(2)\n * Theoretical peak relative error = 2.32e-20\n */\nstatic const long double P[] = {\n 4.5270000862445199635215E-5L,\n 4.9854102823193375972212E-1L,\n 6.5787325942061044846969E0L,\n 2.9911919328553073277375E1L,\n 6.0949667980987787057556E1L,\n 5.7112963590585538103336E1L,\n 2.0039553499201281259648E1L,\n};\nstatic const long double Q[] = {\n/* 1.0000000000000000000000E0,*/\n 1.5062909083469192043167E1L,\n 8.3047565967967209469434E1L,\n 2.2176239823732856465394E2L,\n 3.0909872225312059774938E2L,\n 2.1642788614495947685003E2L,\n 6.0118660497603843919306E1L,\n};\n\n/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),\n * where z = 2(x-1)/(x+1)\n * 1/sqrt(2) <= x < sqrt(2)\n * Theoretical peak relative error = 6.16e-22\n */\nstatic const long double R[4] = {\n 1.9757429581415468984296E-3L,\n-7.1990767473014147232598E-1L,\n 1.0777257190312272158094E1L,\n-3.5717684488096787370998E1L,\n};\nstatic const long double S[4] = {\n/* 1.00000000000000000000E0L,*/\n-2.6201045551331104417768E1L,\n 1.9361891836232102174846E2L,\n-4.2861221385716144629696E2L,\n};\nstatic const long double C1 = 6.9314575195312500000000E-1L;\nstatic const long double C2 = 1.4286068203094172321215E-6L;\n\n#define SQRTH 0.70710678118654752440L\n\nlong double log1pl(long double xm1)\n{\n\tlong double x, y, z;\n\tint e;\n\n\tif (isnan(xm1))\n\t\treturn xm1;\n\tif (xm1 == INFINITY)\n\t\treturn xm1;\n\tif (xm1 == 0.0)\n\t\treturn xm1;\n\n\tx = xm1 + 1.0;\n\n\t/* Test for domain errors.  */\n\tif (x <= 0.0) {\n\t\tif (x == 0.0)\n\t\t\treturn -1/(x*x); /* -inf with divbyzero */\n\t\treturn 0/0.0f; /* nan with invalid */\n\t}\n\n\t/* Separate mantissa from exponent.\n\t   Use frexp so that denormal numbers will be handled properly.  */\n\tx = frexpl(x, &e);\n\n\t/* logarithm using log(x) = z + z^3 P(z)/Q(z),\n\t   where z = 2(x-1)/x+1)  */\n\tif (e > 2 || e < -2) {\n\t\tif (x < SQRTH) { /* 2(2x-1)/(2x+1) */\n\t\t\te -= 1;\n\t\t\tz = x - 0.5;\n\t\t\ty = 0.5 * z + 0.5;\n\t\t} else { /*  2 (x-1)/(x+1)   */\n\t\t\tz = x - 0.5;\n\t\t\tz -= 0.5;\n\t\t\ty = 0.5 * x  + 0.5;\n\t\t}\n\t\tx = z / y;\n\t\tz = x*x;\n\t\tz = x * (z * __polevll(z, R, 3) / __p1evll(z, S, 3));\n\t\tz = z + e * C2;\n\t\tz = z + x;\n\t\tz = z + e * C1;\n\t\treturn z;\n\t}\n\n\t/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */\n\tif (x < SQRTH) {\n\t\te -= 1;\n\t\tif (e != 0)\n\t\t\tx = 2.0 * x - 1.0;\n\t\telse\n\t\t\tx = xm1;\n\t} else {\n\t\tif (e != 0)\n\t\t\tx = x - 1.0;\n\t\telse\n\t\t\tx = xm1;\n\t}\n\tz = x*x;\n\ty = x * (z * __polevll(x, P, 6) / __p1evll(x, Q, 6));\n\ty = y + e * C2;\n\tz = y - 0.5 * z;\n\tz = z + x;\n\tz = z + e * C1;\n\treturn z;\n}\n#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384\n// TODO: broken implementation to make things compile\nlong double log1pl(long double x)\n{\n\treturn log1p(x);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/log2.c",
    "content": "/*\n * Double-precision log2(x) function.\n *\n * Copyright (c) 2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n\n#include <math.h>\n#include <stdint.h>\n#include \"libm.h\"\n#include \"log2_data.h\"\n\n#define T __log2_data.tab\n#define T2 __log2_data.tab2\n#define B __log2_data.poly1\n#define A __log2_data.poly\n#define InvLn2hi __log2_data.invln2hi\n#define InvLn2lo __log2_data.invln2lo\n#define N (1 << LOG2_TABLE_BITS)\n#define OFF 0x3fe6000000000000\n\n/* Top 16 bits of a double.  */\nstatic inline uint32_t top16(double x)\n{\n\treturn asuint64(x) >> 48;\n}\n\ndouble log2(double x)\n{\n\tdouble_t z, r, r2, r4, y, invc, logc, kd, hi, lo, t1, t2, t3, p;\n\tuint64_t ix, iz, tmp;\n\tuint32_t top;\n\tint k, i;\n\n\tix = asuint64(x);\n\ttop = top16(x);\n#define LO asuint64(1.0 - 0x1.5b51p-5)\n#define HI asuint64(1.0 + 0x1.6ab2p-5)\n\tif (predict_false(ix - LO < HI - LO)) {\n\t\t/* Handle close to 1.0 inputs separately.  */\n\t\t/* Fix sign of zero with downward rounding when x==1.  */\n\t\tif (WANT_ROUNDING && predict_false(ix == asuint64(1.0)))\n\t\t\treturn 0;\n\t\tr = x - 1.0;\n#if __FP_FAST_FMA\n\t\thi = r * InvLn2hi;\n\t\tlo = r * InvLn2lo + __builtin_fma(r, InvLn2hi, -hi);\n#else\n\t\tdouble_t rhi, rlo;\n\t\trhi = asdouble(asuint64(r) & -1ULL << 32);\n\t\trlo = r - rhi;\n\t\thi = rhi * InvLn2hi;\n\t\tlo = rlo * InvLn2hi + r * InvLn2lo;\n#endif\n\t\tr2 = r * r; /* rounding error: 0x1p-62.  */\n\t\tr4 = r2 * r2;\n\t\t/* Worst-case error is less than 0.54 ULP (0.55 ULP without fma).  */\n\t\tp = r2 * (B[0] + r * B[1]);\n\t\ty = hi + p;\n\t\tlo += hi - y + p;\n\t\tlo += r4 * (B[2] + r * B[3] + r2 * (B[4] + r * B[5]) +\n\t\t\t    r4 * (B[6] + r * B[7] + r2 * (B[8] + r * B[9])));\n\t\ty += lo;\n\t\treturn eval_as_double(y);\n\t}\n\tif (predict_false(top - 0x0010 >= 0x7ff0 - 0x0010)) {\n\t\t/* x < 0x1p-1022 or inf or nan.  */\n\t\tif (ix * 2 == 0)\n\t\t\treturn __math_divzero(1);\n\t\tif (ix == asuint64(INFINITY)) /* log(inf) == inf.  */\n\t\t\treturn x;\n\t\tif ((top & 0x8000) || (top & 0x7ff0) == 0x7ff0)\n\t\t\treturn __math_invalid(x);\n\t\t/* x is subnormal, normalize it.  */\n\t\tix = asuint64(x * 0x1p52);\n\t\tix -= 52ULL << 52;\n\t}\n\n\t/* x = 2^k z; where z is in range [OFF,2*OFF) and exact.\n\t   The range is split into N subintervals.\n\t   The ith subinterval contains z and c is near its center.  */\n\ttmp = ix - OFF;\n\ti = (tmp >> (52 - LOG2_TABLE_BITS)) % N;\n\tk = (int64_t)tmp >> 52; /* arithmetic shift */\n\tiz = ix - (tmp & 0xfffULL << 52);\n\tinvc = T[i].invc;\n\tlogc = T[i].logc;\n\tz = asdouble(iz);\n\tkd = (double_t)k;\n\n\t/* log2(x) = log2(z/c) + log2(c) + k.  */\n\t/* r ~= z/c - 1, |r| < 1/(2*N).  */\n#if __FP_FAST_FMA\n\t/* rounding error: 0x1p-55/N.  */\n\tr = __builtin_fma(z, invc, -1.0);\n\tt1 = r * InvLn2hi;\n\tt2 = r * InvLn2lo + __builtin_fma(r, InvLn2hi, -t1);\n#else\n\tdouble_t rhi, rlo;\n\t/* rounding error: 0x1p-55/N + 0x1p-65.  */\n\tr = (z - T2[i].chi - T2[i].clo) * invc;\n\trhi = asdouble(asuint64(r) & -1ULL << 32);\n\trlo = r - rhi;\n\tt1 = rhi * InvLn2hi;\n\tt2 = rlo * InvLn2hi + r * InvLn2lo;\n#endif\n\n\t/* hi + lo = r/ln2 + log2(c) + k.  */\n\tt3 = kd + logc;\n\thi = t3 + t1;\n\tlo = t3 - hi + t1 + t2;\n\n\t/* log2(r+1) = r/ln2 + r^2*poly(r).  */\n\t/* Evaluation is optimized assuming superscalar pipelined execution.  */\n\tr2 = r * r; /* rounding error: 0x1p-54/N^2.  */\n\tr4 = r2 * r2;\n\t/* Worst-case error if |y| > 0x1p-4: 0.547 ULP (0.550 ULP without fma).\n\t   ~ 0.5 + 2/N/ln2 + abs-poly-error*0x1p56 ULP (+ 0.003 ULP without fma).  */\n\tp = A[0] + r * A[1] + r2 * (A[2] + r * A[3]) + r4 * (A[4] + r * A[5]);\n\ty = lo + r2 * p + hi;\n\treturn eval_as_double(y);\n}\n"
  },
  {
    "path": "user.libc/src/math/log2_data.c",
    "content": "/*\n * Data for log2.\n *\n * Copyright (c) 2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n\n#include \"log2_data.h\"\n\n#define N (1 << LOG2_TABLE_BITS)\n\nconst struct log2_data __log2_data = {\n// First coefficient: 0x1.71547652b82fe1777d0ffda0d24p0\n.invln2hi = 0x1.7154765200000p+0,\n.invln2lo = 0x1.705fc2eefa200p-33,\n.poly1 = {\n// relative error: 0x1.2fad8188p-63\n// in -0x1.5b51p-5 0x1.6ab2p-5\n-0x1.71547652b82fep-1,\n0x1.ec709dc3a03f7p-2,\n-0x1.71547652b7c3fp-2,\n0x1.2776c50f05be4p-2,\n-0x1.ec709dd768fe5p-3,\n0x1.a61761ec4e736p-3,\n-0x1.7153fbc64a79bp-3,\n0x1.484d154f01b4ap-3,\n-0x1.289e4a72c383cp-3,\n0x1.0b32f285aee66p-3,\n},\n.poly = {\n// relative error: 0x1.a72c2bf8p-58\n// abs error: 0x1.67a552c8p-66\n// in -0x1.f45p-8 0x1.f45p-8\n-0x1.71547652b8339p-1,\n0x1.ec709dc3a04bep-2,\n-0x1.7154764702ffbp-2,\n0x1.2776c50034c48p-2,\n-0x1.ec7b328ea92bcp-3,\n0x1.a6225e117f92ep-3,\n},\n/* Algorithm:\n\n\tx = 2^k z\n\tlog2(x) = k + log2(c) + log2(z/c)\n\tlog2(z/c) = poly(z/c - 1)\n\nwhere z is in [1.6p-1; 1.6p0] which is split into N subintervals and z falls\ninto the ith one, then table entries are computed as\n\n\ttab[i].invc = 1/c\n\ttab[i].logc = (double)log2(c)\n\ttab2[i].chi = (double)c\n\ttab2[i].clo = (double)(c - (double)c)\n\nwhere c is near the center of the subinterval and is chosen by trying +-2^29\nfloating point invc candidates around 1/center and selecting one for which\n\n\t1) the rounding error in 0x1.8p10 + logc is 0,\n\t2) the rounding error in z - chi - clo is < 0x1p-64 and\n\t3) the rounding error in (double)log2(c) is minimized (< 0x1p-68).\n\nNote: 1) ensures that k + logc can be computed without rounding error, 2)\nensures that z/c - 1 can be computed as (z - chi - clo)*invc with close to a\nsingle rounding error when there is no fast fma for z*invc - 1, 3) ensures\nthat logc + poly(z/c - 1) has small error, however near x == 1 when\n|log2(x)| < 0x1p-4, this is not enough so that is special cased.  */\n.tab = {\n{0x1.724286bb1acf8p+0, -0x1.1095feecdb000p-1},\n{0x1.6e1f766d2cca1p+0, -0x1.08494bd76d000p-1},\n{0x1.6a13d0e30d48ap+0, -0x1.00143aee8f800p-1},\n{0x1.661ec32d06c85p+0, -0x1.efec5360b4000p-2},\n{0x1.623fa951198f8p+0, -0x1.dfdd91ab7e000p-2},\n{0x1.5e75ba4cf026cp+0, -0x1.cffae0cc79000p-2},\n{0x1.5ac055a214fb8p+0, -0x1.c043811fda000p-2},\n{0x1.571ed0f166e1ep+0, -0x1.b0b67323ae000p-2},\n{0x1.53909590bf835p+0, -0x1.a152f5a2db000p-2},\n{0x1.5014fed61adddp+0, -0x1.9217f5af86000p-2},\n{0x1.4cab88e487bd0p+0, -0x1.8304db0719000p-2},\n{0x1.49539b4334feep+0, -0x1.74189f9a9e000p-2},\n{0x1.460cbdfafd569p+0, -0x1.6552bb5199000p-2},\n{0x1.42d664ee4b953p+0, -0x1.56b23a29b1000p-2},\n{0x1.3fb01111dd8a6p+0, -0x1.483650f5fa000p-2},\n{0x1.3c995b70c5836p+0, -0x1.39de937f6a000p-2},\n{0x1.3991c4ab6fd4ap+0, -0x1.2baa1538d6000p-2},\n{0x1.3698e0ce099b5p+0, -0x1.1d98340ca4000p-2},\n{0x1.33ae48213e7b2p+0, -0x1.0fa853a40e000p-2},\n{0x1.30d191985bdb1p+0, -0x1.01d9c32e73000p-2},\n{0x1.2e025cab271d7p+0, -0x1.e857da2fa6000p-3},\n{0x1.2b404cf13cd82p+0, -0x1.cd3c8633d8000p-3},\n{0x1.288b02c7ccb50p+0, -0x1.b26034c14a000p-3},\n{0x1.25e2263944de5p+0, -0x1.97c1c2f4fe000p-3},\n{0x1.234563d8615b1p+0, -0x1.7d6023f800000p-3},\n{0x1.20b46e33eaf38p+0, -0x1.633a71a05e000p-3},\n{0x1.1e2eefdcda3ddp+0, -0x1.494f5e9570000p-3},\n{0x1.1bb4a580b3930p+0, -0x1.2f9e424e0a000p-3},\n{0x1.19453847f2200p+0, -0x1.162595afdc000p-3},\n{0x1.16e06c0d5d73cp+0, -0x1.f9c9a75bd8000p-4},\n{0x1.1485f47b7e4c2p+0, -0x1.c7b575bf9c000p-4},\n{0x1.12358ad0085d1p+0, -0x1.960c60ff48000p-4},\n{0x1.0fef00f532227p+0, -0x1.64ce247b60000p-4},\n{0x1.0db2077d03a8fp+0, -0x1.33f78b2014000p-4},\n{0x1.0b7e6d65980d9p+0, -0x1.0387d1a42c000p-4},\n{0x1.0953efe7b408dp+0, -0x1.a6f9208b50000p-5},\n{0x1.07325cac53b83p+0, -0x1.47a954f770000p-5},\n{0x1.05197e40d1b5cp+0, -0x1.d23a8c50c0000p-6},\n{0x1.03091c1208ea2p+0, -0x1.16a2629780000p-6},\n{0x1.0101025b37e21p+0, -0x1.720f8d8e80000p-8},\n{0x1.fc07ef9caa76bp-1, 0x1.6fe53b1500000p-7},\n{0x1.f4465d3f6f184p-1, 0x1.11ccce10f8000p-5},\n{0x1.ecc079f84107fp-1, 0x1.c4dfc8c8b8000p-5},\n{0x1.e573a99975ae8p-1, 0x1.3aa321e574000p-4},\n{0x1.de5d6f0bd3de6p-1, 0x1.918a0d08b8000p-4},\n{0x1.d77b681ff38b3p-1, 0x1.e72e9da044000p-4},\n{0x1.d0cb5724de943p-1, 0x1.1dcd2507f6000p-3},\n{0x1.ca4b2dc0e7563p-1, 0x1.476ab03dea000p-3},\n{0x1.c3f8ee8d6cb51p-1, 0x1.7074377e22000p-3},\n{0x1.bdd2b4f020c4cp-1, 0x1.98ede8ba94000p-3},\n{0x1.b7d6c006015cap-1, 0x1.c0db86ad2e000p-3},\n{0x1.b20366e2e338fp-1, 0x1.e840aafcee000p-3},\n{0x1.ac57026295039p-1, 0x1.0790ab4678000p-2},\n{0x1.a6d01bc2731ddp-1, 0x1.1ac056801c000p-2},\n{0x1.a16d3bc3ff18bp-1, 0x1.2db11d4fee000p-2},\n{0x1.9c2d14967feadp-1, 0x1.406464ec58000p-2},\n{0x1.970e4f47c9902p-1, 0x1.52dbe093af000p-2},\n{0x1.920fb3982bcf2p-1, 0x1.651902050d000p-2},\n{0x1.8d30187f759f1p-1, 0x1.771d2cdeaf000p-2},\n{0x1.886e5ebb9f66dp-1, 0x1.88e9c857d9000p-2},\n{0x1.83c97b658b994p-1, 0x1.9a80155e16000p-2},\n{0x1.7f405ffc61022p-1, 0x1.abe186ed3d000p-2},\n{0x1.7ad22181415cap-1, 0x1.bd0f2aea0e000p-2},\n{0x1.767dcf99eff8cp-1, 0x1.ce0a43dbf4000p-2},\n},\n#if !__FP_FAST_FMA\n.tab2 = {\n{0x1.6200012b90a8ep-1, 0x1.904ab0644b605p-55},\n{0x1.66000045734a6p-1, 0x1.1ff9bea62f7a9p-57},\n{0x1.69fffc325f2c5p-1, 0x1.27ecfcb3c90bap-55},\n{0x1.6e00038b95a04p-1, 0x1.8ff8856739326p-55},\n{0x1.71fffe09994e3p-1, 0x1.afd40275f82b1p-55},\n{0x1.7600015590e1p-1, -0x1.2fd75b4238341p-56},\n{0x1.7a00012655bd5p-1, 0x1.808e67c242b76p-56},\n{0x1.7e0003259e9a6p-1, -0x1.208e426f622b7p-57},\n{0x1.81fffedb4b2d2p-1, -0x1.402461ea5c92fp-55},\n{0x1.860002dfafcc3p-1, 0x1.df7f4a2f29a1fp-57},\n{0x1.89ffff78c6b5p-1, -0x1.e0453094995fdp-55},\n{0x1.8e00039671566p-1, -0x1.a04f3bec77b45p-55},\n{0x1.91fffe2bf1745p-1, -0x1.7fa34400e203cp-56},\n{0x1.95fffcc5c9fd1p-1, -0x1.6ff8005a0695dp-56},\n{0x1.9a0003bba4767p-1, 0x1.0f8c4c4ec7e03p-56},\n{0x1.9dfffe7b92da5p-1, 0x1.e7fd9478c4602p-55},\n{0x1.a1fffd72efdafp-1, -0x1.a0c554dcdae7ep-57},\n{0x1.a5fffde04ff95p-1, 0x1.67da98ce9b26bp-55},\n{0x1.a9fffca5e8d2bp-1, -0x1.284c9b54c13dep-55},\n{0x1.adfffddad03eap-1, 0x1.812c8ea602e3cp-58},\n{0x1.b1ffff10d3d4dp-1, -0x1.efaddad27789cp-55},\n{0x1.b5fffce21165ap-1, 0x1.3cb1719c61237p-58},\n{0x1.b9fffd950e674p-1, 0x1.3f7d94194cep-56},\n{0x1.be000139ca8afp-1, 0x1.50ac4215d9bcp-56},\n{0x1.c20005b46df99p-1, 0x1.beea653e9c1c9p-57},\n{0x1.c600040b9f7aep-1, -0x1.c079f274a70d6p-56},\n{0x1.ca0006255fd8ap-1, -0x1.a0b4076e84c1fp-56},\n{0x1.cdfffd94c095dp-1, 0x1.8f933f99ab5d7p-55},\n{0x1.d1ffff975d6cfp-1, -0x1.82c08665fe1bep-58},\n{0x1.d5fffa2561c93p-1, -0x1.b04289bd295f3p-56},\n{0x1.d9fff9d228b0cp-1, 0x1.70251340fa236p-55},\n{0x1.de00065bc7e16p-1, -0x1.5011e16a4d80cp-56},\n{0x1.e200002f64791p-1, 0x1.9802f09ef62ep-55},\n{0x1.e600057d7a6d8p-1, -0x1.e0b75580cf7fap-56},\n{0x1.ea00027edc00cp-1, -0x1.c848309459811p-55},\n{0x1.ee0006cf5cb7cp-1, -0x1.f8027951576f4p-55},\n{0x1.f2000782b7dccp-1, -0x1.f81d97274538fp-55},\n{0x1.f6000260c450ap-1, -0x1.071002727ffdcp-59},\n{0x1.f9fffe88cd533p-1, -0x1.81bdce1fda8bp-58},\n{0x1.fdfffd50f8689p-1, 0x1.7f91acb918e6ep-55},\n{0x1.0200004292367p+0, 0x1.b7ff365324681p-54},\n{0x1.05fffe3e3d668p+0, 0x1.6fa08ddae957bp-55},\n{0x1.0a0000a85a757p+0, -0x1.7e2de80d3fb91p-58},\n{0x1.0e0001a5f3fccp+0, -0x1.1823305c5f014p-54},\n{0x1.11ffff8afbaf5p+0, -0x1.bfabb6680bac2p-55},\n{0x1.15fffe54d91adp+0, -0x1.d7f121737e7efp-54},\n{0x1.1a00011ac36e1p+0, 0x1.c000a0516f5ffp-54},\n{0x1.1e00019c84248p+0, -0x1.082fbe4da5dap-54},\n{0x1.220000ffe5e6ep+0, -0x1.8fdd04c9cfb43p-55},\n{0x1.26000269fd891p+0, 0x1.cfe2a7994d182p-55},\n{0x1.2a00029a6e6dap+0, -0x1.00273715e8bc5p-56},\n{0x1.2dfffe0293e39p+0, 0x1.b7c39dab2a6f9p-54},\n{0x1.31ffff7dcf082p+0, 0x1.df1336edc5254p-56},\n{0x1.35ffff05a8b6p+0, -0x1.e03564ccd31ebp-54},\n{0x1.3a0002e0eaeccp+0, 0x1.5f0e74bd3a477p-56},\n{0x1.3e000043bb236p+0, 0x1.c7dcb149d8833p-54},\n{0x1.4200002d187ffp+0, 0x1.e08afcf2d3d28p-56},\n{0x1.460000d387cb1p+0, 0x1.20837856599a6p-55},\n{0x1.4a00004569f89p+0, -0x1.9fa5c904fbcd2p-55},\n{0x1.4e000043543f3p+0, -0x1.81125ed175329p-56},\n{0x1.51fffcc027f0fp+0, 0x1.883d8847754dcp-54},\n{0x1.55ffffd87b36fp+0, -0x1.709e731d02807p-55},\n{0x1.59ffff21df7bap+0, 0x1.7f79f68727b02p-55},\n{0x1.5dfffebfc3481p+0, -0x1.180902e30e93ep-54},\n},\n#endif\n};\n"
  },
  {
    "path": "user.libc/src/math/log2_data.h",
    "content": "/*\n * Copyright (c) 2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n#ifndef _LOG2_DATA_H\n#define _LOG2_DATA_H\n\n#include <features.h>\n\n#define LOG2_TABLE_BITS 6\n#define LOG2_POLY_ORDER 7\n#define LOG2_POLY1_ORDER 11\nextern hidden const struct log2_data {\n\tdouble invln2hi;\n\tdouble invln2lo;\n\tdouble poly[LOG2_POLY_ORDER - 1];\n\tdouble poly1[LOG2_POLY1_ORDER - 1];\n\tstruct {\n\t\tdouble invc, logc;\n\t} tab[1 << LOG2_TABLE_BITS];\n#if !__FP_FAST_FMA\n\tstruct {\n\t\tdouble chi, clo;\n\t} tab2[1 << LOG2_TABLE_BITS];\n#endif\n} __log2_data;\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/log2f.c",
    "content": "/*\n * Single-precision log2 function.\n *\n * Copyright (c) 2017-2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n\n#include <math.h>\n#include <stdint.h>\n#include \"libm.h\"\n#include \"log2f_data.h\"\n\n/*\nLOG2F_TABLE_BITS = 4\nLOG2F_POLY_ORDER = 4\n\nULP error: 0.752 (nearest rounding.)\nRelative error: 1.9 * 2^-26 (before rounding.)\n*/\n\n#define N (1 << LOG2F_TABLE_BITS)\n#define T __log2f_data.tab\n#define A __log2f_data.poly\n#define OFF 0x3f330000\n\nfloat log2f(float x)\n{\n\tdouble_t z, r, r2, p, y, y0, invc, logc;\n\tuint32_t ix, iz, top, tmp;\n\tint k, i;\n\n\tix = asuint(x);\n\t/* Fix sign of zero with downward rounding when x==1.  */\n\tif (WANT_ROUNDING && predict_false(ix == 0x3f800000))\n\t\treturn 0;\n\tif (predict_false(ix - 0x00800000 >= 0x7f800000 - 0x00800000)) {\n\t\t/* x < 0x1p-126 or inf or nan.  */\n\t\tif (ix * 2 == 0)\n\t\t\treturn __math_divzerof(1);\n\t\tif (ix == 0x7f800000) /* log2(inf) == inf.  */\n\t\t\treturn x;\n\t\tif ((ix & 0x80000000) || ix * 2 >= 0xff000000)\n\t\t\treturn __math_invalidf(x);\n\t\t/* x is subnormal, normalize it.  */\n\t\tix = asuint(x * 0x1p23f);\n\t\tix -= 23 << 23;\n\t}\n\n\t/* x = 2^k z; where z is in range [OFF,2*OFF] and exact.\n\t   The range is split into N subintervals.\n\t   The ith subinterval contains z and c is near its center.  */\n\ttmp = ix - OFF;\n\ti = (tmp >> (23 - LOG2F_TABLE_BITS)) % N;\n\ttop = tmp & 0xff800000;\n\tiz = ix - top;\n\tk = (int32_t)tmp >> 23; /* arithmetic shift */\n\tinvc = T[i].invc;\n\tlogc = T[i].logc;\n\tz = (double_t)asfloat(iz);\n\n\t/* log2(x) = log1p(z/c-1)/ln2 + log2(c) + k */\n\tr = z * invc - 1;\n\ty0 = logc + (double_t)k;\n\n\t/* Pipelined polynomial evaluation to approximate log1p(r)/ln2.  */\n\tr2 = r * r;\n\ty = A[1] * r + A[2];\n\ty = A[0] * r2 + y;\n\tp = A[3] * r + y0;\n\ty = y * r2 + p;\n\treturn eval_as_float(y);\n}\n"
  },
  {
    "path": "user.libc/src/math/log2f_data.c",
    "content": "/*\n * Data definition for log2f.\n *\n * Copyright (c) 2017-2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n\n#include \"log2f_data.h\"\n\nconst struct log2f_data __log2f_data = {\n  .tab = {\n  { 0x1.661ec79f8f3bep+0, -0x1.efec65b963019p-2 },\n  { 0x1.571ed4aaf883dp+0, -0x1.b0b6832d4fca4p-2 },\n  { 0x1.49539f0f010bp+0, -0x1.7418b0a1fb77bp-2 },\n  { 0x1.3c995b0b80385p+0, -0x1.39de91a6dcf7bp-2 },\n  { 0x1.30d190c8864a5p+0, -0x1.01d9bf3f2b631p-2 },\n  { 0x1.25e227b0b8eap+0, -0x1.97c1d1b3b7afp-3 },\n  { 0x1.1bb4a4a1a343fp+0, -0x1.2f9e393af3c9fp-3 },\n  { 0x1.12358f08ae5bap+0, -0x1.960cbbf788d5cp-4 },\n  { 0x1.0953f419900a7p+0, -0x1.a6f9db6475fcep-5 },\n  { 0x1p+0, 0x0p+0 },\n  { 0x1.e608cfd9a47acp-1, 0x1.338ca9f24f53dp-4 },\n  { 0x1.ca4b31f026aap-1, 0x1.476a9543891bap-3 },\n  { 0x1.b2036576afce6p-1, 0x1.e840b4ac4e4d2p-3 },\n  { 0x1.9c2d163a1aa2dp-1, 0x1.40645f0c6651cp-2 },\n  { 0x1.886e6037841edp-1, 0x1.88e9c2c1b9ff8p-2 },\n  { 0x1.767dcf5534862p-1, 0x1.ce0a44eb17bccp-2 },\n  },\n  .poly = {\n  -0x1.712b6f70a7e4dp-2, 0x1.ecabf496832ep-2, -0x1.715479ffae3dep-1,\n  0x1.715475f35c8b8p0,\n  }\n};\n"
  },
  {
    "path": "user.libc/src/math/log2f_data.h",
    "content": "/*\n * Copyright (c) 2017-2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n#ifndef _LOG2F_DATA_H\n#define _LOG2F_DATA_H\n\n#include <features.h>\n\n#define LOG2F_TABLE_BITS 4\n#define LOG2F_POLY_ORDER 4\nextern hidden const struct log2f_data {\n\tstruct {\n\t\tdouble invc, logc;\n\t} tab[1 << LOG2F_TABLE_BITS];\n\tdouble poly[LOG2F_POLY_ORDER];\n} __log2f_data;\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/log2l.c",
    "content": "/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_log2l.c */\n/*\n * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n/*\n *      Base 2 logarithm, long double precision\n *\n *\n * SYNOPSIS:\n *\n * long double x, y, log2l();\n *\n * y = log2l( x );\n *\n *\n * DESCRIPTION:\n *\n * Returns the base 2 logarithm of x.\n *\n * The argument is separated into its exponent and fractional\n * parts.  If the exponent is between -1 and +1, the (natural)\n * logarithm of the fraction is approximated by\n *\n *     log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x).\n *\n * Otherwise, setting  z = 2(x-1)/x+1),\n *\n *     log(x) = z + z**3 P(z)/Q(z).\n *\n *\n * ACCURACY:\n *\n *                      Relative error:\n * arithmetic   domain     # trials      peak         rms\n *    IEEE      0.5, 2.0     30000      9.8e-20     2.7e-20\n *    IEEE     exp(+-10000)  70000      5.4e-20     2.3e-20\n *\n * In the tests over the interval exp(+-10000), the logarithms\n * of the random arguments were uniformly distributed over\n * [-10000, +10000].\n */\n\n#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double log2l(long double x)\n{\n\treturn log2(x);\n}\n#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384\n/* Coefficients for ln(1+x) = x - x**2/2 + x**3 P(x)/Q(x)\n * 1/sqrt(2) <= x < sqrt(2)\n * Theoretical peak relative error = 6.2e-22\n */\nstatic const long double P[] = {\n 4.9962495940332550844739E-1L,\n 1.0767376367209449010438E1L,\n 7.7671073698359539859595E1L,\n 2.5620629828144409632571E2L,\n 4.2401812743503691187826E2L,\n 3.4258224542413922935104E2L,\n 1.0747524399916215149070E2L,\n};\nstatic const long double Q[] = {\n/* 1.0000000000000000000000E0,*/\n 2.3479774160285863271658E1L,\n 1.9444210022760132894510E2L,\n 7.7952888181207260646090E2L,\n 1.6911722418503949084863E3L,\n 2.0307734695595183428202E3L,\n 1.2695660352705325274404E3L,\n 3.2242573199748645407652E2L,\n};\n\n/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),\n * where z = 2(x-1)/(x+1)\n * 1/sqrt(2) <= x < sqrt(2)\n * Theoretical peak relative error = 6.16e-22\n */\nstatic const long double R[4] = {\n 1.9757429581415468984296E-3L,\n-7.1990767473014147232598E-1L,\n 1.0777257190312272158094E1L,\n-3.5717684488096787370998E1L,\n};\nstatic const long double S[4] = {\n/* 1.00000000000000000000E0L,*/\n-2.6201045551331104417768E1L,\n 1.9361891836232102174846E2L,\n-4.2861221385716144629696E2L,\n};\n/* log2(e) - 1 */\n#define LOG2EA 4.4269504088896340735992e-1L\n\n#define SQRTH 0.70710678118654752440L\n\nlong double log2l(long double x)\n{\n\tlong double y, z;\n\tint e;\n\n\tif (isnan(x))\n\t\treturn x;\n\tif (x == INFINITY)\n\t\treturn x;\n\tif (x <= 0.0) {\n\t\tif (x == 0.0)\n\t\t\treturn -1/(x*x); /* -inf with divbyzero */\n\t\treturn 0/0.0f; /* nan with invalid */\n\t}\n\n\t/* separate mantissa from exponent */\n\t/* Note, frexp is used so that denormal numbers\n\t * will be handled properly.\n\t */\n\tx = frexpl(x, &e);\n\n\t/* logarithm using log(x) = z + z**3 P(z)/Q(z),\n\t * where z = 2(x-1)/x+1)\n\t */\n\tif (e > 2 || e < -2) {\n\t\tif (x < SQRTH) {  /* 2(2x-1)/(2x+1) */\n\t\t\te -= 1;\n\t\t\tz = x - 0.5;\n\t\t\ty = 0.5 * z + 0.5;\n\t\t} else {  /*  2 (x-1)/(x+1)   */\n\t\t\tz = x - 0.5;\n\t\t\tz -= 0.5;\n\t\t\ty = 0.5 * x + 0.5;\n\t\t}\n\t\tx = z / y;\n\t\tz = x*x;\n\t\ty = x * (z * __polevll(z, R, 3) / __p1evll(z, S, 3));\n\t\tgoto done;\n\t}\n\n\t/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */\n\tif (x < SQRTH) {\n\t\te -= 1;\n\t\tx = 2.0*x - 1.0;\n\t} else {\n\t\tx = x - 1.0;\n\t}\n\tz = x*x;\n\ty = x * (z * __polevll(x, P, 6) / __p1evll(x, Q, 7));\n\ty = y - 0.5*z;\n\ndone:\n\t/* Multiply log of fraction by log2(e)\n\t * and base 2 exponent by 1\n\t *\n\t * ***CAUTION***\n\t *\n\t * This sequence of operations is critical and it may\n\t * be horribly defeated by some compiler optimizers.\n\t */\n\tz = y * LOG2EA;\n\tz += x * LOG2EA;\n\tz += y;\n\tz += x;\n\tz += e;\n\treturn z;\n}\n#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384\n// TODO: broken implementation to make things compile\nlong double log2l(long double x)\n{\n\treturn log2(x);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/log_data.c",
    "content": "/*\n * Data for log.\n *\n * Copyright (c) 2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n\n#include \"log_data.h\"\n\n#define N (1 << LOG_TABLE_BITS)\n\nconst struct log_data __log_data = {\n.ln2hi = 0x1.62e42fefa3800p-1,\n.ln2lo = 0x1.ef35793c76730p-45,\n.poly1 = {\n// relative error: 0x1.c04d76cp-63\n// in -0x1p-4 0x1.09p-4 (|log(1+x)| > 0x1p-4 outside the interval)\n-0x1p-1,\n0x1.5555555555577p-2,\n-0x1.ffffffffffdcbp-3,\n0x1.999999995dd0cp-3,\n-0x1.55555556745a7p-3,\n0x1.24924a344de3p-3,\n-0x1.fffffa4423d65p-4,\n0x1.c7184282ad6cap-4,\n-0x1.999eb43b068ffp-4,\n0x1.78182f7afd085p-4,\n-0x1.5521375d145cdp-4,\n},\n.poly = {\n// relative error: 0x1.926199e8p-56\n// abs error: 0x1.882ff33p-65\n// in -0x1.fp-9 0x1.fp-9\n-0x1.0000000000001p-1,\n0x1.555555551305bp-2,\n-0x1.fffffffeb459p-3,\n0x1.999b324f10111p-3,\n-0x1.55575e506c89fp-3,\n},\n/* Algorithm:\n\n\tx = 2^k z\n\tlog(x) = k ln2 + log(c) + log(z/c)\n\tlog(z/c) = poly(z/c - 1)\n\nwhere z is in [1.6p-1; 1.6p0] which is split into N subintervals and z falls\ninto the ith one, then table entries are computed as\n\n\ttab[i].invc = 1/c\n\ttab[i].logc = (double)log(c)\n\ttab2[i].chi = (double)c\n\ttab2[i].clo = (double)(c - (double)c)\n\nwhere c is near the center of the subinterval and is chosen by trying +-2^29\nfloating point invc candidates around 1/center and selecting one for which\n\n\t1) the rounding error in 0x1.8p9 + logc is 0,\n\t2) the rounding error in z - chi - clo is < 0x1p-66 and\n\t3) the rounding error in (double)log(c) is minimized (< 0x1p-66).\n\nNote: 1) ensures that k*ln2hi + logc can be computed without rounding error,\n2) ensures that z/c - 1 can be computed as (z - chi - clo)*invc with close to\na single rounding error when there is no fast fma for z*invc - 1, 3) ensures\nthat logc + poly(z/c - 1) has small error, however near x == 1 when\n|log(x)| < 0x1p-4, this is not enough so that is special cased.  */\n.tab = {\n{0x1.734f0c3e0de9fp+0, -0x1.7cc7f79e69000p-2},\n{0x1.713786a2ce91fp+0, -0x1.76feec20d0000p-2},\n{0x1.6f26008fab5a0p+0, -0x1.713e31351e000p-2},\n{0x1.6d1a61f138c7dp+0, -0x1.6b85b38287800p-2},\n{0x1.6b1490bc5b4d1p+0, -0x1.65d5590807800p-2},\n{0x1.69147332f0cbap+0, -0x1.602d076180000p-2},\n{0x1.6719f18224223p+0, -0x1.5a8ca86909000p-2},\n{0x1.6524f99a51ed9p+0, -0x1.54f4356035000p-2},\n{0x1.63356aa8f24c4p+0, -0x1.4f637c36b4000p-2},\n{0x1.614b36b9ddc14p+0, -0x1.49da7fda85000p-2},\n{0x1.5f66452c65c4cp+0, -0x1.445923989a800p-2},\n{0x1.5d867b5912c4fp+0, -0x1.3edf439b0b800p-2},\n{0x1.5babccb5b90dep+0, -0x1.396ce448f7000p-2},\n{0x1.59d61f2d91a78p+0, -0x1.3401e17bda000p-2},\n{0x1.5805612465687p+0, -0x1.2e9e2ef468000p-2},\n{0x1.56397cee76bd3p+0, -0x1.2941b3830e000p-2},\n{0x1.54725e2a77f93p+0, -0x1.23ec58cda8800p-2},\n{0x1.52aff42064583p+0, -0x1.1e9e129279000p-2},\n{0x1.50f22dbb2bddfp+0, -0x1.1956d2b48f800p-2},\n{0x1.4f38f4734ded7p+0, -0x1.141679ab9f800p-2},\n{0x1.4d843cfde2840p+0, -0x1.0edd094ef9800p-2},\n{0x1.4bd3ec078a3c8p+0, -0x1.09aa518db1000p-2},\n{0x1.4a27fc3e0258ap+0, -0x1.047e65263b800p-2},\n{0x1.4880524d48434p+0, -0x1.feb224586f000p-3},\n{0x1.46dce1b192d0bp+0, -0x1.f474a7517b000p-3},\n{0x1.453d9d3391854p+0, -0x1.ea4443d103000p-3},\n{0x1.43a2744b4845ap+0, -0x1.e020d44e9b000p-3},\n{0x1.420b54115f8fbp+0, -0x1.d60a22977f000p-3},\n{0x1.40782da3ef4b1p+0, -0x1.cc00104959000p-3},\n{0x1.3ee8f5d57fe8fp+0, -0x1.c202956891000p-3},\n{0x1.3d5d9a00b4ce9p+0, -0x1.b81178d811000p-3},\n{0x1.3bd60c010c12bp+0, -0x1.ae2c9ccd3d000p-3},\n{0x1.3a5242b75dab8p+0, -0x1.a45402e129000p-3},\n{0x1.38d22cd9fd002p+0, -0x1.9a877681df000p-3},\n{0x1.3755bc5847a1cp+0, -0x1.90c6d69483000p-3},\n{0x1.35dce49ad36e2p+0, -0x1.87120a645c000p-3},\n{0x1.34679984dd440p+0, -0x1.7d68fb4143000p-3},\n{0x1.32f5cceffcb24p+0, -0x1.73cb83c627000p-3},\n{0x1.3187775a10d49p+0, -0x1.6a39a9b376000p-3},\n{0x1.301c8373e3990p+0, -0x1.60b3154b7a000p-3},\n{0x1.2eb4ebb95f841p+0, -0x1.5737d76243000p-3},\n{0x1.2d50a0219a9d1p+0, -0x1.4dc7b8fc23000p-3},\n{0x1.2bef9a8b7fd2ap+0, -0x1.4462c51d20000p-3},\n{0x1.2a91c7a0c1babp+0, -0x1.3b08abc830000p-3},\n{0x1.293726014b530p+0, -0x1.31b996b490000p-3},\n{0x1.27dfa5757a1f5p+0, -0x1.2875490a44000p-3},\n{0x1.268b39b1d3bbfp+0, -0x1.1f3b9f879a000p-3},\n{0x1.2539d838ff5bdp+0, -0x1.160c8252ca000p-3},\n{0x1.23eb7aac9083bp+0, -0x1.0ce7f57f72000p-3},\n{0x1.22a012ba940b6p+0, -0x1.03cdc49fea000p-3},\n{0x1.2157996cc4132p+0, -0x1.f57bdbc4b8000p-4},\n{0x1.201201dd2fc9bp+0, -0x1.e370896404000p-4},\n{0x1.1ecf4494d480bp+0, -0x1.d17983ef94000p-4},\n{0x1.1d8f5528f6569p+0, -0x1.bf9674ed8a000p-4},\n{0x1.1c52311577e7cp+0, -0x1.adc79202f6000p-4},\n{0x1.1b17c74cb26e9p+0, -0x1.9c0c3e7288000p-4},\n{0x1.19e010c2c1ab6p+0, -0x1.8a646b372c000p-4},\n{0x1.18ab07bb670bdp+0, -0x1.78d01b3ac0000p-4},\n{0x1.1778a25efbcb6p+0, -0x1.674f145380000p-4},\n{0x1.1648d354c31dap+0, -0x1.55e0e6d878000p-4},\n{0x1.151b990275fddp+0, -0x1.4485cdea1e000p-4},\n{0x1.13f0ea432d24cp+0, -0x1.333d94d6aa000p-4},\n{0x1.12c8b7210f9dap+0, -0x1.22079f8c56000p-4},\n{0x1.11a3028ecb531p+0, -0x1.10e4698622000p-4},\n{0x1.107fbda8434afp+0, -0x1.ffa6c6ad20000p-5},\n{0x1.0f5ee0f4e6bb3p+0, -0x1.dda8d4a774000p-5},\n{0x1.0e4065d2a9fcep+0, -0x1.bbcece4850000p-5},\n{0x1.0d244632ca521p+0, -0x1.9a1894012c000p-5},\n{0x1.0c0a77ce2981ap+0, -0x1.788583302c000p-5},\n{0x1.0af2f83c636d1p+0, -0x1.5715e67d68000p-5},\n{0x1.09ddb98a01339p+0, -0x1.35c8a49658000p-5},\n{0x1.08cabaf52e7dfp+0, -0x1.149e364154000p-5},\n{0x1.07b9f2f4e28fbp+0, -0x1.e72c082eb8000p-6},\n{0x1.06ab58c358f19p+0, -0x1.a55f152528000p-6},\n{0x1.059eea5ecf92cp+0, -0x1.63d62cf818000p-6},\n{0x1.04949cdd12c90p+0, -0x1.228fb8caa0000p-6},\n{0x1.038c6c6f0ada9p+0, -0x1.c317b20f90000p-7},\n{0x1.02865137932a9p+0, -0x1.419355daa0000p-7},\n{0x1.0182427ea7348p+0, -0x1.81203c2ec0000p-8},\n{0x1.008040614b195p+0, -0x1.0040979240000p-9},\n{0x1.fe01ff726fa1ap-1, 0x1.feff384900000p-9},\n{0x1.fa11cc261ea74p-1, 0x1.7dc41353d0000p-7},\n{0x1.f6310b081992ep-1, 0x1.3cea3c4c28000p-6},\n{0x1.f25f63ceeadcdp-1, 0x1.b9fc114890000p-6},\n{0x1.ee9c8039113e7p-1, 0x1.1b0d8ce110000p-5},\n{0x1.eae8078cbb1abp-1, 0x1.58a5bd001c000p-5},\n{0x1.e741aa29d0c9bp-1, 0x1.95c8340d88000p-5},\n{0x1.e3a91830a99b5p-1, 0x1.d276aef578000p-5},\n{0x1.e01e009609a56p-1, 0x1.07598e598c000p-4},\n{0x1.dca01e577bb98p-1, 0x1.253f5e30d2000p-4},\n{0x1.d92f20b7c9103p-1, 0x1.42edd8b380000p-4},\n{0x1.d5cac66fb5ccep-1, 0x1.606598757c000p-4},\n{0x1.d272caa5ede9dp-1, 0x1.7da76356a0000p-4},\n{0x1.cf26e3e6b2ccdp-1, 0x1.9ab434e1c6000p-4},\n{0x1.cbe6da2a77902p-1, 0x1.b78c7bb0d6000p-4},\n{0x1.c8b266d37086dp-1, 0x1.d431332e72000p-4},\n{0x1.c5894bd5d5804p-1, 0x1.f0a3171de6000p-4},\n{0x1.c26b533bb9f8cp-1, 0x1.067152b914000p-3},\n{0x1.bf583eeece73fp-1, 0x1.147858292b000p-3},\n{0x1.bc4fd75db96c1p-1, 0x1.2266ecdca3000p-3},\n{0x1.b951e0c864a28p-1, 0x1.303d7a6c55000p-3},\n{0x1.b65e2c5ef3e2cp-1, 0x1.3dfc33c331000p-3},\n{0x1.b374867c9888bp-1, 0x1.4ba366b7a8000p-3},\n{0x1.b094b211d304ap-1, 0x1.5933928d1f000p-3},\n{0x1.adbe885f2ef7ep-1, 0x1.66acd2418f000p-3},\n{0x1.aaf1d31603da2p-1, 0x1.740f8ec669000p-3},\n{0x1.a82e63fd358a7p-1, 0x1.815c0f51af000p-3},\n{0x1.a5740ef09738bp-1, 0x1.8e92954f68000p-3},\n{0x1.a2c2a90ab4b27p-1, 0x1.9bb3602f84000p-3},\n{0x1.a01a01393f2d1p-1, 0x1.a8bed1c2c0000p-3},\n{0x1.9d79f24db3c1bp-1, 0x1.b5b515c01d000p-3},\n{0x1.9ae2505c7b190p-1, 0x1.c2967ccbcc000p-3},\n{0x1.9852ef297ce2fp-1, 0x1.cf635d5486000p-3},\n{0x1.95cbaeea44b75p-1, 0x1.dc1bd3446c000p-3},\n{0x1.934c69de74838p-1, 0x1.e8c01b8cfe000p-3},\n{0x1.90d4f2f6752e6p-1, 0x1.f5509c0179000p-3},\n{0x1.8e6528effd79dp-1, 0x1.00e6c121fb800p-2},\n{0x1.8bfce9fcc007cp-1, 0x1.071b80e93d000p-2},\n{0x1.899c0dabec30ep-1, 0x1.0d46b9e867000p-2},\n{0x1.87427aa2317fbp-1, 0x1.13687334bd000p-2},\n{0x1.84f00acb39a08p-1, 0x1.1980d67234800p-2},\n{0x1.82a49e8653e55p-1, 0x1.1f8ffe0cc8000p-2},\n{0x1.8060195f40260p-1, 0x1.2595fd7636800p-2},\n{0x1.7e22563e0a329p-1, 0x1.2b9300914a800p-2},\n{0x1.7beb377dcb5adp-1, 0x1.3187210436000p-2},\n{0x1.79baa679725c2p-1, 0x1.377266dec1800p-2},\n{0x1.77907f2170657p-1, 0x1.3d54ffbaf3000p-2},\n{0x1.756cadbd6130cp-1, 0x1.432eee32fe000p-2},\n},\n#if !__FP_FAST_FMA\n.tab2 = {\n{0x1.61000014fb66bp-1, 0x1.e026c91425b3cp-56},\n{0x1.63000034db495p-1, 0x1.dbfea48005d41p-55},\n{0x1.650000d94d478p-1, 0x1.e7fa786d6a5b7p-55},\n{0x1.67000074e6fadp-1, 0x1.1fcea6b54254cp-57},\n{0x1.68ffffedf0faep-1, -0x1.c7e274c590efdp-56},\n{0x1.6b0000763c5bcp-1, -0x1.ac16848dcda01p-55},\n{0x1.6d0001e5cc1f6p-1, 0x1.33f1c9d499311p-55},\n{0x1.6efffeb05f63ep-1, -0x1.e80041ae22d53p-56},\n{0x1.710000e86978p-1, 0x1.bff6671097952p-56},\n{0x1.72ffffc67e912p-1, 0x1.c00e226bd8724p-55},\n{0x1.74fffdf81116ap-1, -0x1.e02916ef101d2p-57},\n{0x1.770000f679c9p-1, -0x1.7fc71cd549c74p-57},\n{0x1.78ffffa7ec835p-1, 0x1.1bec19ef50483p-55},\n{0x1.7affffe20c2e6p-1, -0x1.07e1729cc6465p-56},\n{0x1.7cfffed3fc9p-1, -0x1.08072087b8b1cp-55},\n{0x1.7efffe9261a76p-1, 0x1.dc0286d9df9aep-55},\n{0x1.81000049ca3e8p-1, 0x1.97fd251e54c33p-55},\n{0x1.8300017932c8fp-1, -0x1.afee9b630f381p-55},\n{0x1.850000633739cp-1, 0x1.9bfbf6b6535bcp-55},\n{0x1.87000204289c6p-1, -0x1.bbf65f3117b75p-55},\n{0x1.88fffebf57904p-1, -0x1.9006ea23dcb57p-55},\n{0x1.8b00022bc04dfp-1, -0x1.d00df38e04b0ap-56},\n{0x1.8cfffe50c1b8ap-1, -0x1.8007146ff9f05p-55},\n{0x1.8effffc918e43p-1, 0x1.3817bd07a7038p-55},\n{0x1.910001efa5fc7p-1, 0x1.93e9176dfb403p-55},\n{0x1.9300013467bb9p-1, 0x1.f804e4b980276p-56},\n{0x1.94fffe6ee076fp-1, -0x1.f7ef0d9ff622ep-55},\n{0x1.96fffde3c12d1p-1, -0x1.082aa962638bap-56},\n{0x1.98ffff4458a0dp-1, -0x1.7801b9164a8efp-55},\n{0x1.9afffdd982e3ep-1, -0x1.740e08a5a9337p-55},\n{0x1.9cfffed49fb66p-1, 0x1.fce08c19bep-60},\n{0x1.9f00020f19c51p-1, -0x1.a3faa27885b0ap-55},\n{0x1.a10001145b006p-1, 0x1.4ff489958da56p-56},\n{0x1.a300007bbf6fap-1, 0x1.cbeab8a2b6d18p-55},\n{0x1.a500010971d79p-1, 0x1.8fecadd78793p-55},\n{0x1.a70001df52e48p-1, -0x1.f41763dd8abdbp-55},\n{0x1.a90001c593352p-1, -0x1.ebf0284c27612p-55},\n{0x1.ab0002a4f3e4bp-1, -0x1.9fd043cff3f5fp-57},\n{0x1.acfffd7ae1ed1p-1, -0x1.23ee7129070b4p-55},\n{0x1.aefffee510478p-1, 0x1.a063ee00edea3p-57},\n{0x1.b0fffdb650d5bp-1, 0x1.a06c8381f0ab9p-58},\n{0x1.b2ffffeaaca57p-1, -0x1.9011e74233c1dp-56},\n{0x1.b4fffd995badcp-1, -0x1.9ff1068862a9fp-56},\n{0x1.b7000249e659cp-1, 0x1.aff45d0864f3ep-55},\n{0x1.b8ffff987164p-1, 0x1.cfe7796c2c3f9p-56},\n{0x1.bafffd204cb4fp-1, -0x1.3ff27eef22bc4p-57},\n{0x1.bcfffd2415c45p-1, -0x1.cffb7ee3bea21p-57},\n{0x1.beffff86309dfp-1, -0x1.14103972e0b5cp-55},\n{0x1.c0fffe1b57653p-1, 0x1.bc16494b76a19p-55},\n{0x1.c2ffff1fa57e3p-1, -0x1.4feef8d30c6edp-57},\n{0x1.c4fffdcbfe424p-1, -0x1.43f68bcec4775p-55},\n{0x1.c6fffed54b9f7p-1, 0x1.47ea3f053e0ecp-55},\n{0x1.c8fffeb998fd5p-1, 0x1.383068df992f1p-56},\n{0x1.cb0002125219ap-1, -0x1.8fd8e64180e04p-57},\n{0x1.ccfffdd94469cp-1, 0x1.e7ebe1cc7ea72p-55},\n{0x1.cefffeafdc476p-1, 0x1.ebe39ad9f88fep-55},\n{0x1.d1000169af82bp-1, 0x1.57d91a8b95a71p-56},\n{0x1.d30000d0ff71dp-1, 0x1.9c1906970c7dap-55},\n{0x1.d4fffea790fc4p-1, -0x1.80e37c558fe0cp-58},\n{0x1.d70002edc87e5p-1, -0x1.f80d64dc10f44p-56},\n{0x1.d900021dc82aap-1, -0x1.47c8f94fd5c5cp-56},\n{0x1.dafffd86b0283p-1, 0x1.c7f1dc521617ep-55},\n{0x1.dd000296c4739p-1, 0x1.8019eb2ffb153p-55},\n{0x1.defffe54490f5p-1, 0x1.e00d2c652cc89p-57},\n{0x1.e0fffcdabf694p-1, -0x1.f8340202d69d2p-56},\n{0x1.e2fffdb52c8ddp-1, 0x1.b00c1ca1b0864p-56},\n{0x1.e4ffff24216efp-1, 0x1.2ffa8b094ab51p-56},\n{0x1.e6fffe88a5e11p-1, -0x1.7f673b1efbe59p-58},\n{0x1.e9000119eff0dp-1, -0x1.4808d5e0bc801p-55},\n{0x1.eafffdfa51744p-1, 0x1.80006d54320b5p-56},\n{0x1.ed0001a127fa1p-1, -0x1.002f860565c92p-58},\n{0x1.ef00007babcc4p-1, -0x1.540445d35e611p-55},\n{0x1.f0ffff57a8d02p-1, -0x1.ffb3139ef9105p-59},\n{0x1.f30001ee58ac7p-1, 0x1.a81acf2731155p-55},\n{0x1.f4ffff5823494p-1, 0x1.a3f41d4d7c743p-55},\n{0x1.f6ffffca94c6bp-1, -0x1.202f41c987875p-57},\n{0x1.f8fffe1f9c441p-1, 0x1.77dd1f477e74bp-56},\n{0x1.fafffd2e0e37ep-1, -0x1.f01199a7ca331p-57},\n{0x1.fd0001c77e49ep-1, 0x1.181ee4bceacb1p-56},\n{0x1.feffff7e0c331p-1, -0x1.e05370170875ap-57},\n{0x1.00ffff465606ep+0, -0x1.a7ead491c0adap-55},\n{0x1.02ffff3867a58p+0, -0x1.77f69c3fcb2ep-54},\n{0x1.04ffffdfc0d17p+0, 0x1.7bffe34cb945bp-54},\n{0x1.0700003cd4d82p+0, 0x1.20083c0e456cbp-55},\n{0x1.08ffff9f2cbe8p+0, -0x1.dffdfbe37751ap-57},\n{0x1.0b000010cda65p+0, -0x1.13f7faee626ebp-54},\n{0x1.0d00001a4d338p+0, 0x1.07dfa79489ff7p-55},\n{0x1.0effffadafdfdp+0, -0x1.7040570d66bcp-56},\n{0x1.110000bbafd96p+0, 0x1.e80d4846d0b62p-55},\n{0x1.12ffffae5f45dp+0, 0x1.dbffa64fd36efp-54},\n{0x1.150000dd59ad9p+0, 0x1.a0077701250aep-54},\n{0x1.170000f21559ap+0, 0x1.dfdf9e2e3deeep-55},\n{0x1.18ffffc275426p+0, 0x1.10030dc3b7273p-54},\n{0x1.1b000123d3c59p+0, 0x1.97f7980030188p-54},\n{0x1.1cffff8299eb7p+0, -0x1.5f932ab9f8c67p-57},\n{0x1.1effff48ad4p+0, 0x1.37fbf9da75bebp-54},\n{0x1.210000c8b86a4p+0, 0x1.f806b91fd5b22p-54},\n{0x1.2300003854303p+0, 0x1.3ffc2eb9fbf33p-54},\n{0x1.24fffffbcf684p+0, 0x1.601e77e2e2e72p-56},\n{0x1.26ffff52921d9p+0, 0x1.ffcbb767f0c61p-56},\n{0x1.2900014933a3cp+0, -0x1.202ca3c02412bp-56},\n{0x1.2b00014556313p+0, -0x1.2808233f21f02p-54},\n{0x1.2cfffebfe523bp+0, -0x1.8ff7e384fdcf2p-55},\n{0x1.2f0000bb8ad96p+0, -0x1.5ff51503041c5p-55},\n{0x1.30ffffb7ae2afp+0, -0x1.10071885e289dp-55},\n{0x1.32ffffeac5f7fp+0, -0x1.1ff5d3fb7b715p-54},\n{0x1.350000ca66756p+0, 0x1.57f82228b82bdp-54},\n{0x1.3700011fbf721p+0, 0x1.000bac40dd5ccp-55},\n{0x1.38ffff9592fb9p+0, -0x1.43f9d2db2a751p-54},\n{0x1.3b00004ddd242p+0, 0x1.57f6b707638e1p-55},\n{0x1.3cffff5b2c957p+0, 0x1.a023a10bf1231p-56},\n{0x1.3efffeab0b418p+0, 0x1.87f6d66b152bp-54},\n{0x1.410001532aff4p+0, 0x1.7f8375f198524p-57},\n{0x1.4300017478b29p+0, 0x1.301e672dc5143p-55},\n{0x1.44fffe795b463p+0, 0x1.9ff69b8b2895ap-55},\n{0x1.46fffe80475ep+0, -0x1.5c0b19bc2f254p-54},\n{0x1.48fffef6fc1e7p+0, 0x1.b4009f23a2a72p-54},\n{0x1.4afffe5bea704p+0, -0x1.4ffb7bf0d7d45p-54},\n{0x1.4d000171027dep+0, -0x1.9c06471dc6a3dp-54},\n{0x1.4f0000ff03ee2p+0, 0x1.77f890b85531cp-54},\n{0x1.5100012dc4bd1p+0, 0x1.004657166a436p-57},\n{0x1.530001605277ap+0, -0x1.6bfcece233209p-54},\n{0x1.54fffecdb704cp+0, -0x1.902720505a1d7p-55},\n{0x1.56fffef5f54a9p+0, 0x1.bbfe60ec96412p-54},\n{0x1.5900017e61012p+0, 0x1.87ec581afef9p-55},\n{0x1.5b00003c93e92p+0, -0x1.f41080abf0ccp-54},\n{0x1.5d0001d4919bcp+0, -0x1.8812afb254729p-54},\n{0x1.5efffe7b87a89p+0, -0x1.47eb780ed6904p-54},\n},\n#endif\n};\n"
  },
  {
    "path": "user.libc/src/math/log_data.h",
    "content": "/*\n * Copyright (c) 2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n#ifndef _LOG_DATA_H\n#define _LOG_DATA_H\n\n#include <features.h>\n\n#define LOG_TABLE_BITS 7\n#define LOG_POLY_ORDER 6\n#define LOG_POLY1_ORDER 12\nextern hidden const struct log_data {\n\tdouble ln2hi;\n\tdouble ln2lo;\n\tdouble poly[LOG_POLY_ORDER - 1]; /* First coefficient is 1.  */\n\tdouble poly1[LOG_POLY1_ORDER - 1];\n\tstruct {\n\t\tdouble invc, logc;\n\t} tab[1 << LOG_TABLE_BITS];\n#if !__FP_FAST_FMA\n\tstruct {\n\t\tdouble chi, clo;\n\t} tab2[1 << LOG_TABLE_BITS];\n#endif\n} __log_data;\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/logb.c",
    "content": "#include <math.h>\n\n/*\nspecial cases:\n\tlogb(+-0) = -inf, and raise divbyzero\n\tlogb(+-inf) = +inf\n\tlogb(nan) = nan\n*/\n\ndouble logb(double x)\n{\n\tif (!isfinite(x))\n\t\treturn x * x;\n\tif (x == 0)\n\t\treturn -1/(x*x);\n\treturn ilogb(x);\n}\n"
  },
  {
    "path": "user.libc/src/math/logbf.c",
    "content": "#include <math.h>\n\nfloat logbf(float x)\n{\n\tif (!isfinite(x))\n\t\treturn x * x;\n\tif (x == 0)\n\t\treturn -1/(x*x);\n\treturn ilogbf(x);\n}\n"
  },
  {
    "path": "user.libc/src/math/logbl.c",
    "content": "#include <math.h>\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double logbl(long double x)\n{\n\treturn logb(x);\n}\n#else\nlong double logbl(long double x)\n{\n\tif (!isfinite(x))\n\t\treturn x * x;\n\tif (x == 0)\n\t\treturn -1/(x*x);\n\treturn ilogbl(x);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/logf.c",
    "content": "/*\n * Single-precision log function.\n *\n * Copyright (c) 2017-2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n\n#include <math.h>\n#include <stdint.h>\n#include \"libm.h\"\n#include \"logf_data.h\"\n\n/*\nLOGF_TABLE_BITS = 4\nLOGF_POLY_ORDER = 4\n\nULP error: 0.818 (nearest rounding.)\nRelative error: 1.957 * 2^-26 (before rounding.)\n*/\n\n#define T __logf_data.tab\n#define A __logf_data.poly\n#define Ln2 __logf_data.ln2\n#define N (1 << LOGF_TABLE_BITS)\n#define OFF 0x3f330000\n\nfloat logf(float x)\n{\n\tdouble_t z, r, r2, y, y0, invc, logc;\n\tuint32_t ix, iz, tmp;\n\tint k, i;\n\n\tix = asuint(x);\n\t/* Fix sign of zero with downward rounding when x==1.  */\n\tif (WANT_ROUNDING && predict_false(ix == 0x3f800000))\n\t\treturn 0;\n\tif (predict_false(ix - 0x00800000 >= 0x7f800000 - 0x00800000)) {\n\t\t/* x < 0x1p-126 or inf or nan.  */\n\t\tif (ix * 2 == 0)\n\t\t\treturn __math_divzerof(1);\n\t\tif (ix == 0x7f800000) /* log(inf) == inf.  */\n\t\t\treturn x;\n\t\tif ((ix & 0x80000000) || ix * 2 >= 0xff000000)\n\t\t\treturn __math_invalidf(x);\n\t\t/* x is subnormal, normalize it.  */\n\t\tix = asuint(x * 0x1p23f);\n\t\tix -= 23 << 23;\n\t}\n\n\t/* x = 2^k z; where z is in range [OFF,2*OFF] and exact.\n\t   The range is split into N subintervals.\n\t   The ith subinterval contains z and c is near its center.  */\n\ttmp = ix - OFF;\n\ti = (tmp >> (23 - LOGF_TABLE_BITS)) % N;\n\tk = (int32_t)tmp >> 23; /* arithmetic shift */\n\tiz = ix - (tmp & 0x1ff << 23);\n\tinvc = T[i].invc;\n\tlogc = T[i].logc;\n\tz = (double_t)asfloat(iz);\n\n\t/* log(x) = log1p(z/c-1) + log(c) + k*Ln2 */\n\tr = z * invc - 1;\n\ty0 = logc + (double_t)k * Ln2;\n\n\t/* Pipelined polynomial evaluation to approximate log1p(r).  */\n\tr2 = r * r;\n\ty = A[1] * r + A[2];\n\ty = A[0] * r2 + y;\n\ty = y * r2 + (y0 + r);\n\treturn eval_as_float(y);\n}\n"
  },
  {
    "path": "user.libc/src/math/logf_data.c",
    "content": "/*\n * Data definition for logf.\n *\n * Copyright (c) 2017-2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n\n#include \"logf_data.h\"\n\nconst struct logf_data __logf_data = {\n  .tab = {\n  { 0x1.661ec79f8f3bep+0, -0x1.57bf7808caadep-2 },\n  { 0x1.571ed4aaf883dp+0, -0x1.2bef0a7c06ddbp-2 },\n  { 0x1.49539f0f010bp+0, -0x1.01eae7f513a67p-2 },\n  { 0x1.3c995b0b80385p+0, -0x1.b31d8a68224e9p-3 },\n  { 0x1.30d190c8864a5p+0, -0x1.6574f0ac07758p-3 },\n  { 0x1.25e227b0b8eap+0, -0x1.1aa2bc79c81p-3 },\n  { 0x1.1bb4a4a1a343fp+0, -0x1.a4e76ce8c0e5ep-4 },\n  { 0x1.12358f08ae5bap+0, -0x1.1973c5a611cccp-4 },\n  { 0x1.0953f419900a7p+0, -0x1.252f438e10c1ep-5 },\n  { 0x1p+0, 0x0p+0 },\n  { 0x1.e608cfd9a47acp-1, 0x1.aa5aa5df25984p-5 },\n  { 0x1.ca4b31f026aap-1, 0x1.c5e53aa362eb4p-4 },\n  { 0x1.b2036576afce6p-1, 0x1.526e57720db08p-3 },\n  { 0x1.9c2d163a1aa2dp-1, 0x1.bc2860d22477p-3 },\n  { 0x1.886e6037841edp-1, 0x1.1058bc8a07ee1p-2 },\n  { 0x1.767dcf5534862p-1, 0x1.4043057b6ee09p-2 },\n  },\n  .ln2 = 0x1.62e42fefa39efp-1,\n  .poly = {\n  -0x1.00ea348b88334p-2, 0x1.5575b0be00b6ap-2, -0x1.ffffef20a4123p-2,\n  }\n};\n"
  },
  {
    "path": "user.libc/src/math/logf_data.h",
    "content": "/*\n * Copyright (c) 2017-2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n#ifndef _LOGF_DATA_H\n#define _LOGF_DATA_H\n\n#include <features.h>\n\n#define LOGF_TABLE_BITS 4\n#define LOGF_POLY_ORDER 4\nextern hidden const struct logf_data {\n\tstruct {\n\t\tdouble invc, logc;\n\t} tab[1 << LOGF_TABLE_BITS];\n\tdouble ln2;\n\tdouble poly[LOGF_POLY_ORDER - 1]; /* First order coefficient is 1.  */\n} __logf_data;\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/logl.c",
    "content": "/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_logl.c */\n/*\n * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n/*\n *      Natural logarithm, long double precision\n *\n *\n * SYNOPSIS:\n *\n * long double x, y, logl();\n *\n * y = logl( x );\n *\n *\n * DESCRIPTION:\n *\n * Returns the base e (2.718...) logarithm of x.\n *\n * The argument is separated into its exponent and fractional\n * parts.  If the exponent is between -1 and +1, the logarithm\n * of the fraction is approximated by\n *\n *     log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x).\n *\n * Otherwise, setting  z = 2(x-1)/(x+1),\n *\n *     log(x) = log(1+z/2) - log(1-z/2) = z + z**3 P(z)/Q(z).\n *\n *\n * ACCURACY:\n *\n *                      Relative error:\n * arithmetic   domain     # trials      peak         rms\n *    IEEE      0.5, 2.0    150000      8.71e-20    2.75e-20\n *    IEEE     exp(+-10000) 100000      5.39e-20    2.34e-20\n *\n * In the tests over the interval exp(+-10000), the logarithms\n * of the random arguments were uniformly distributed over\n * [-10000, +10000].\n */\n\n#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double logl(long double x)\n{\n\treturn log(x);\n}\n#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384\n/* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x)\n * 1/sqrt(2) <= x < sqrt(2)\n * Theoretical peak relative error = 2.32e-20\n */\nstatic const long double P[] = {\n 4.5270000862445199635215E-5L,\n 4.9854102823193375972212E-1L,\n 6.5787325942061044846969E0L,\n 2.9911919328553073277375E1L,\n 6.0949667980987787057556E1L,\n 5.7112963590585538103336E1L,\n 2.0039553499201281259648E1L,\n};\nstatic const long double Q[] = {\n/* 1.0000000000000000000000E0,*/\n 1.5062909083469192043167E1L,\n 8.3047565967967209469434E1L,\n 2.2176239823732856465394E2L,\n 3.0909872225312059774938E2L,\n 2.1642788614495947685003E2L,\n 6.0118660497603843919306E1L,\n};\n\n/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),\n * where z = 2(x-1)/(x+1)\n * 1/sqrt(2) <= x < sqrt(2)\n * Theoretical peak relative error = 6.16e-22\n */\nstatic const long double R[4] = {\n 1.9757429581415468984296E-3L,\n-7.1990767473014147232598E-1L,\n 1.0777257190312272158094E1L,\n-3.5717684488096787370998E1L,\n};\nstatic const long double S[4] = {\n/* 1.00000000000000000000E0L,*/\n-2.6201045551331104417768E1L,\n 1.9361891836232102174846E2L,\n-4.2861221385716144629696E2L,\n};\nstatic const long double C1 = 6.9314575195312500000000E-1L;\nstatic const long double C2 = 1.4286068203094172321215E-6L;\n\n#define SQRTH 0.70710678118654752440L\n\nlong double logl(long double x)\n{\n\tlong double y, z;\n\tint e;\n\n\tif (isnan(x))\n\t\treturn x;\n\tif (x == INFINITY)\n\t\treturn x;\n\tif (x <= 0.0) {\n\t\tif (x == 0.0)\n\t\t\treturn -1/(x*x); /* -inf with divbyzero */\n\t\treturn 0/0.0f; /* nan with invalid */\n\t}\n\n\t/* separate mantissa from exponent */\n\t/* Note, frexp is used so that denormal numbers\n\t * will be handled properly.\n\t */\n\tx = frexpl(x, &e);\n\n\t/* logarithm using log(x) = z + z**3 P(z)/Q(z),\n\t * where z = 2(x-1)/(x+1)\n\t */\n\tif (e > 2 || e < -2) {\n\t\tif (x < SQRTH) {  /* 2(2x-1)/(2x+1) */\n\t\t\te -= 1;\n\t\t\tz = x - 0.5;\n\t\t\ty = 0.5 * z + 0.5;\n\t\t} else {  /*  2 (x-1)/(x+1)   */\n\t\t\tz = x - 0.5;\n\t\t\tz -= 0.5;\n\t\t\ty = 0.5 * x  + 0.5;\n\t\t}\n\t\tx = z / y;\n\t\tz = x*x;\n\t\tz = x * (z * __polevll(z, R, 3) / __p1evll(z, S, 3));\n\t\tz = z + e * C2;\n\t\tz = z + x;\n\t\tz = z + e * C1;\n\t\treturn z;\n\t}\n\n\t/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */\n\tif (x < SQRTH) {\n\t\te -= 1;\n\t\tx = 2.0*x - 1.0;\n\t} else {\n\t\tx = x - 1.0;\n\t}\n\tz = x*x;\n\ty = x * (z * __polevll(x, P, 6) / __p1evll(x, Q, 6));\n\ty = y + e * C2;\n\tz = y - 0.5*z;\n\t/* Note, the sum of above terms does not exceed x/4,\n\t * so it contributes at most about 1/4 lsb to the error.\n\t */\n\tz = z + x;\n\tz = z + e * C1; /* This sum has an error of 1/2 lsb. */\n\treturn z;\n}\n#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384\n// TODO: broken implementation to make things compile\nlong double logl(long double x)\n{\n\treturn log(x);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/lrint.c",
    "content": "#include <limits.h>\n#include <fenv.h>\n#include <math.h>\n#include \"libm.h\"\n\n/*\nIf the result cannot be represented (overflow, nan), then\nlrint raises the invalid exception.\n\nOtherwise if the input was not an integer then the inexact\nexception is raised.\n\nC99 is a bit vague about whether inexact exception is\nallowed to be raised when invalid is raised.\n(F.9 explicitly allows spurious inexact exceptions, F.9.6.5\ndoes not make it clear if that rule applies to lrint, but\nIEEE 754r 7.8 seems to forbid spurious inexact exception in\nthe ineger conversion functions)\n\nSo we try to make sure that no spurious inexact exception is\nraised in case of an overflow.\n\nIf the bit size of long > precision of double, then there\ncannot be inexact rounding in case the result overflows,\notherwise LONG_MAX and LONG_MIN can be represented exactly\nas a double.\n*/\n\n#if LONG_MAX < 1U<<53 && defined(FE_INEXACT)\n#include <float.h>\n#include <stdint.h>\n#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1\n#define EPS DBL_EPSILON\n#elif FLT_EVAL_METHOD==2\n#define EPS LDBL_EPSILON\n#endif\n#ifdef __GNUC__\n/* avoid stack frame in lrint */\n__attribute__((noinline))\n#endif\nstatic long lrint_slow(double x)\n{\n\t#pragma STDC FENV_ACCESS ON\n\tint e;\n\n\te = fetestexcept(FE_INEXACT);\n\tx = rint(x);\n\tif (!e && (x > LONG_MAX || x < LONG_MIN))\n\t\tfeclearexcept(FE_INEXACT);\n\t/* conversion */\n\treturn x;\n}\n\nlong lrint(double x)\n{\n\tuint32_t abstop = asuint64(x)>>32 & 0x7fffffff;\n\tuint64_t sign = asuint64(x) & (1ULL << 63);\n\n\tif (abstop < 0x41dfffff) {\n\t\t/* |x| < 0x7ffffc00, no overflow */\n\t\tdouble_t toint = asdouble(asuint64(1/EPS) | sign);\n\t\tdouble_t y = x + toint - toint;\n\t\treturn (long)y;\n\t}\n\treturn lrint_slow(x);\n}\n#else\nlong lrint(double x)\n{\n\treturn rint(x);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/lrintf.c",
    "content": "#include <math.h>\n\n/* uses LONG_MAX > 2^24, see comments in lrint.c */\n\nlong lrintf(float x)\n{\n\treturn rintf(x);\n}\n"
  },
  {
    "path": "user.libc/src/math/lrintl.c",
    "content": "#include <limits.h>\n#include <fenv.h>\n#include \"libm.h\"\n\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong lrintl(long double x)\n{\n\treturn lrint(x);\n}\n#elif defined(FE_INEXACT)\n/*\nsee comments in lrint.c\n\nNote that if LONG_MAX == 0x7fffffffffffffff && LDBL_MANT_DIG == 64\nthen x == 2**63 - 0.5 is the only input that overflows and\nraises inexact (with tonearest or upward rounding mode)\n*/\nlong lrintl(long double x)\n{\n\t#pragma STDC FENV_ACCESS ON\n\tint e;\n\n\te = fetestexcept(FE_INEXACT);\n\tx = rintl(x);\n\tif (!e && (x > LONG_MAX || x < LONG_MIN))\n\t\tfeclearexcept(FE_INEXACT);\n\t/* conversion */\n\treturn x;\n}\n#else\nlong lrintl(long double x)\n{\n\treturn rintl(x);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/lround.c",
    "content": "#include <math.h>\n\nlong lround(double x)\n{\n\treturn round(x);\n}\n"
  },
  {
    "path": "user.libc/src/math/lroundf.c",
    "content": "#include <math.h>\n\nlong lroundf(float x)\n{\n\treturn roundf(x);\n}\n"
  },
  {
    "path": "user.libc/src/math/lroundl.c",
    "content": "#include <math.h>\n\nlong lroundl(long double x)\n{\n\treturn roundl(x);\n}\n"
  },
  {
    "path": "user.libc/src/math/m68k/sqrtl.c",
    "content": "#include <math.h>\n\n#if __HAVE_68881__\n\nlong double sqrtl(long double x)\n{\n\t__asm__ (\"fsqrt.x %1,%0\" : \"=f\"(x) : \"fm\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../sqrtl.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/mips/fabs.c",
    "content": "#if !defined(__mips_soft_float) && defined(__mips_abs2008)\n\n#include <math.h>\n\ndouble fabs(double x)\n{\n\tdouble r;\n\t__asm__(\"abs.d %0,%1\" : \"=f\"(r) : \"f\"(x));\n\treturn r;\n}\n\n#else\n\n#include \"../fabs.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/mips/fabsf.c",
    "content": "#if !defined(__mips_soft_float) && defined(__mips_abs2008)\n\n#include <math.h>\n\nfloat fabsf(float x)\n{\n\tfloat r;\n\t__asm__(\"abs.s %0,%1\" : \"=f\"(r) : \"f\"(x));\n\treturn r;\n}\n\n#else\n\n#include \"../fabsf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/mips/sqrt.c",
    "content": "#if !defined(__mips_soft_float) && __mips >= 3\n\n#include <math.h>\n\ndouble sqrt(double x)\n{\n\tdouble r;\n\t__asm__(\"sqrt.d %0,%1\" : \"=f\"(r) : \"f\"(x));\n\treturn r;\n}\n\n#else\n\n#include \"../sqrt.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/mips/sqrtf.c",
    "content": "#if !defined(__mips_soft_float) && __mips >= 2\n\n#include <math.h>\n\nfloat sqrtf(float x)\n{\n\tfloat r;\n\t__asm__(\"sqrt.s %0,%1\" : \"=f\"(r) : \"f\"(x));\n\treturn r;\n}\n\n#else\n\n#include \"../sqrtf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/modf.c",
    "content": "#include \"libm.h\"\n\ndouble modf(double x, double *iptr)\n{\n\tunion {double f; uint64_t i;} u = {x};\n\tuint64_t mask;\n\tint e = (int)(u.i>>52 & 0x7ff) - 0x3ff;\n\n\t/* no fractional part */\n\tif (e >= 52) {\n\t\t*iptr = x;\n\t\tif (e == 0x400 && u.i<<12 != 0) /* nan */\n\t\t\treturn x;\n\t\tu.i &= 1ULL<<63;\n\t\treturn u.f;\n\t}\n\n\t/* no integral part*/\n\tif (e < 0) {\n\t\tu.i &= 1ULL<<63;\n\t\t*iptr = u.f;\n\t\treturn x;\n\t}\n\n\tmask = -1ULL>>12>>e;\n\tif ((u.i & mask) == 0) {\n\t\t*iptr = x;\n\t\tu.i &= 1ULL<<63;\n\t\treturn u.f;\n\t}\n\tu.i &= ~mask;\n\t*iptr = u.f;\n\treturn x - u.f;\n}\n"
  },
  {
    "path": "user.libc/src/math/modff.c",
    "content": "#include \"libm.h\"\n\nfloat modff(float x, float *iptr)\n{\n\tunion {float f; uint32_t i;} u = {x};\n\tuint32_t mask;\n\tint e = (int)(u.i>>23 & 0xff) - 0x7f;\n\n\t/* no fractional part */\n\tif (e >= 23) {\n\t\t*iptr = x;\n\t\tif (e == 0x80 && u.i<<9 != 0) { /* nan */\n\t\t\treturn x;\n\t\t}\n\t\tu.i &= 0x80000000;\n\t\treturn u.f;\n\t}\n\t/* no integral part */\n\tif (e < 0) {\n\t\tu.i &= 0x80000000;\n\t\t*iptr = u.f;\n\t\treturn x;\n\t}\n\n\tmask = 0x007fffff>>e;\n\tif ((u.i & mask) == 0) {\n\t\t*iptr = x;\n\t\tu.i &= 0x80000000;\n\t\treturn u.f;\n\t}\n\tu.i &= ~mask;\n\t*iptr = u.f;\n\treturn x - u.f;\n}\n"
  },
  {
    "path": "user.libc/src/math/modfl.c",
    "content": "#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double modfl(long double x, long double *iptr)\n{\n\tdouble d;\n\tlong double r;\n\n\tr = modf(x, &d);\n\t*iptr = d;\n\treturn r;\n}\n#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\n\nstatic const long double toint = 1/LDBL_EPSILON;\n\nlong double modfl(long double x, long double *iptr)\n{\n\tunion ldshape u = {x};\n\tint e = (u.i.se & 0x7fff) - 0x3fff;\n\tint s = u.i.se >> 15;\n\tlong double absx;\n\tlong double y;\n\n\t/* no fractional part */\n\tif (e >= LDBL_MANT_DIG-1) {\n\t\t*iptr = x;\n\t\tif (isnan(x))\n\t\t\treturn x;\n\t\treturn s ? -0.0 : 0.0;\n\t}\n\n\t/* no integral part*/\n\tif (e < 0) {\n\t\t*iptr = s ? -0.0 : 0.0;\n\t\treturn x;\n\t}\n\n\t/* raises spurious inexact */\n\tabsx = s ? -x : x;\n\ty = absx + toint - toint - absx;\n\tif (y == 0) {\n\t\t*iptr = x;\n\t\treturn s ? -0.0 : 0.0;\n\t}\n\tif (y > 0)\n\t\ty -= 1;\n\tif (s)\n\t\ty = -y;\n\t*iptr = x + y;\n\treturn -y;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/nan.c",
    "content": "#include <math.h>\n\ndouble nan(const char *s)\n{\n\treturn NAN;\n}\n"
  },
  {
    "path": "user.libc/src/math/nanf.c",
    "content": "#include <math.h>\n\nfloat nanf(const char *s)\n{\n\treturn NAN;\n}\n"
  },
  {
    "path": "user.libc/src/math/nanl.c",
    "content": "#include <math.h>\n\nlong double nanl(const char *s)\n{\n\treturn NAN;\n}\n"
  },
  {
    "path": "user.libc/src/math/nearbyint.c",
    "content": "#include <fenv.h>\n#include <math.h>\n\n/* nearbyint is the same as rint, but it must not raise the inexact exception */\n\ndouble nearbyint(double x)\n{\n#ifdef FE_INEXACT\n\t#pragma STDC FENV_ACCESS ON\n\tint e;\n\n\te = fetestexcept(FE_INEXACT);\n#endif\n\tx = rint(x);\n#ifdef FE_INEXACT\n\tif (!e)\n\t\tfeclearexcept(FE_INEXACT);\n#endif\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/nearbyintf.c",
    "content": "#include <fenv.h>\n#include <math.h>\n\nfloat nearbyintf(float x)\n{\n#ifdef FE_INEXACT\n\t#pragma STDC FENV_ACCESS ON\n\tint e;\n\n\te = fetestexcept(FE_INEXACT);\n#endif\n\tx = rintf(x);\n#ifdef FE_INEXACT\n\tif (!e)\n\t\tfeclearexcept(FE_INEXACT);\n#endif\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/nearbyintl.c",
    "content": "#include <math.h>\n#include <float.h>\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double nearbyintl(long double x)\n{\n\treturn nearbyint(x);\n}\n#else\n#include <fenv.h>\nlong double nearbyintl(long double x)\n{\n#ifdef FE_INEXACT\n\t#pragma STDC FENV_ACCESS ON\n\tint e;\n\n\te = fetestexcept(FE_INEXACT);\n#endif\n\tx = rintl(x);\n#ifdef FE_INEXACT\n\tif (!e)\n\t\tfeclearexcept(FE_INEXACT);\n#endif\n\treturn x;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/nextafter.c",
    "content": "#include \"libm.h\"\n\ndouble nextafter(double x, double y)\n{\n\tunion {double f; uint64_t i;} ux={x}, uy={y};\n\tuint64_t ax, ay;\n\tint e;\n\n\tif (isnan(x) || isnan(y))\n\t\treturn x + y;\n\tif (ux.i == uy.i)\n\t\treturn y;\n\tax = ux.i & -1ULL/2;\n\tay = uy.i & -1ULL/2;\n\tif (ax == 0) {\n\t\tif (ay == 0)\n\t\t\treturn y;\n\t\tux.i = (uy.i & 1ULL<<63) | 1;\n\t} else if (ax > ay || ((ux.i ^ uy.i) & 1ULL<<63))\n\t\tux.i--;\n\telse\n\t\tux.i++;\n\te = ux.i >> 52 & 0x7ff;\n\t/* raise overflow if ux.f is infinite and x is finite */\n\tif (e == 0x7ff)\n\t\tFORCE_EVAL(x+x);\n\t/* raise underflow if ux.f is subnormal or zero */\n\tif (e == 0)\n\t\tFORCE_EVAL(x*x + ux.f*ux.f);\n\treturn ux.f;\n}\n"
  },
  {
    "path": "user.libc/src/math/nextafterf.c",
    "content": "#include \"libm.h\"\n\nfloat nextafterf(float x, float y)\n{\n\tunion {float f; uint32_t i;} ux={x}, uy={y};\n\tuint32_t ax, ay, e;\n\n\tif (isnan(x) || isnan(y))\n\t\treturn x + y;\n\tif (ux.i == uy.i)\n\t\treturn y;\n\tax = ux.i & 0x7fffffff;\n\tay = uy.i & 0x7fffffff;\n\tif (ax == 0) {\n\t\tif (ay == 0)\n\t\t\treturn y;\n\t\tux.i = (uy.i & 0x80000000) | 1;\n\t} else if (ax > ay || ((ux.i ^ uy.i) & 0x80000000))\n\t\tux.i--;\n\telse\n\t\tux.i++;\n\te = ux.i & 0x7f800000;\n\t/* raise overflow if ux.f is infinite and x is finite */\n\tif (e == 0x7f800000)\n\t\tFORCE_EVAL(x+x);\n\t/* raise underflow if ux.f is subnormal or zero */\n\tif (e == 0)\n\t\tFORCE_EVAL(x*x + ux.f*ux.f);\n\treturn ux.f;\n}\n"
  },
  {
    "path": "user.libc/src/math/nextafterl.c",
    "content": "#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double nextafterl(long double x, long double y)\n{\n\treturn nextafter(x, y);\n}\n#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384\nlong double nextafterl(long double x, long double y)\n{\n\tunion ldshape ux, uy;\n\n\tif (isnan(x) || isnan(y))\n\t\treturn x + y;\n\tif (x == y)\n\t\treturn y;\n\tux.f = x;\n\tif (x == 0) {\n\t\tuy.f = y;\n\t\tux.i.m = 1;\n\t\tux.i.se = uy.i.se & 0x8000;\n\t} else if ((x < y) == !(ux.i.se & 0x8000)) {\n\t\tux.i.m++;\n\t\tif (ux.i.m << 1 == 0) {\n\t\t\tux.i.m = 1ULL << 63;\n\t\t\tux.i.se++;\n\t\t}\n\t} else {\n\t\tif (ux.i.m << 1 == 0) {\n\t\t\tux.i.se--;\n\t\t\tif (ux.i.se)\n\t\t\t\tux.i.m = 0;\n\t\t}\n\t\tux.i.m--;\n\t}\n\t/* raise overflow if ux is infinite and x is finite */\n\tif ((ux.i.se & 0x7fff) == 0x7fff)\n\t\treturn x + x;\n\t/* raise underflow if ux is subnormal or zero */\n\tif ((ux.i.se & 0x7fff) == 0)\n\t\tFORCE_EVAL(x*x + ux.f*ux.f);\n\treturn ux.f;\n}\n#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384\nlong double nextafterl(long double x, long double y)\n{\n\tunion ldshape ux, uy;\n\n\tif (isnan(x) || isnan(y))\n\t\treturn x + y;\n\tif (x == y)\n\t\treturn y;\n\tux.f = x;\n\tif (x == 0) {\n\t\tuy.f = y;\n\t\tux.i.lo = 1;\n\t\tux.i.se = uy.i.se & 0x8000;\n\t} else if ((x < y) == !(ux.i.se & 0x8000)) {\n\t\tux.i2.lo++;\n\t\tif (ux.i2.lo == 0)\n\t\t\tux.i2.hi++;\n\t} else {\n\t\tif (ux.i2.lo == 0)\n\t\t\tux.i2.hi--;\n\t\tux.i2.lo--;\n\t}\n\t/* raise overflow if ux is infinite and x is finite */\n\tif ((ux.i.se & 0x7fff) == 0x7fff)\n\t\treturn x + x;\n\t/* raise underflow if ux is subnormal or zero */\n\tif ((ux.i.se & 0x7fff) == 0)\n\t\tFORCE_EVAL(x*x + ux.f*ux.f);\n\treturn ux.f;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/nexttoward.c",
    "content": "#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\ndouble nexttoward(double x, long double y)\n{\n\treturn nextafter(x, y);\n}\n#else\ndouble nexttoward(double x, long double y)\n{\n\tunion {double f; uint64_t i;} ux = {x};\n\tint e;\n\n\tif (isnan(x) || isnan(y))\n\t\treturn x + y;\n\tif (x == y)\n\t\treturn y;\n\tif (x == 0) {\n\t\tux.i = 1;\n\t\tif (signbit(y))\n\t\t\tux.i |= 1ULL<<63;\n\t} else if (x < y) {\n\t\tif (signbit(x))\n\t\t\tux.i--;\n\t\telse\n\t\t\tux.i++;\n\t} else {\n\t\tif (signbit(x))\n\t\t\tux.i++;\n\t\telse\n\t\t\tux.i--;\n\t}\n\te = ux.i>>52 & 0x7ff;\n\t/* raise overflow if ux.f is infinite and x is finite */\n\tif (e == 0x7ff)\n\t\tFORCE_EVAL(x+x);\n\t/* raise underflow if ux.f is subnormal or zero */\n\tif (e == 0)\n\t\tFORCE_EVAL(x*x + ux.f*ux.f);\n\treturn ux.f;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/nexttowardf.c",
    "content": "#include \"libm.h\"\n\nfloat nexttowardf(float x, long double y)\n{\n\tunion {float f; uint32_t i;} ux = {x};\n\tuint32_t e;\n\n\tif (isnan(x) || isnan(y))\n\t\treturn x + y;\n\tif (x == y)\n\t\treturn y;\n\tif (x == 0) {\n\t\tux.i = 1;\n\t\tif (signbit(y))\n\t\t\tux.i |= 0x80000000;\n\t} else if (x < y) {\n\t\tif (signbit(x))\n\t\t\tux.i--;\n\t\telse\n\t\t\tux.i++;\n\t} else {\n\t\tif (signbit(x))\n\t\t\tux.i++;\n\t\telse\n\t\t\tux.i--;\n\t}\n\te = ux.i & 0x7f800000;\n\t/* raise overflow if ux.f is infinite and x is finite */\n\tif (e == 0x7f800000)\n\t\tFORCE_EVAL(x+x);\n\t/* raise underflow if ux.f is subnormal or zero */\n\tif (e == 0)\n\t\tFORCE_EVAL(x*x + ux.f*ux.f);\n\treturn ux.f;\n}\n"
  },
  {
    "path": "user.libc/src/math/nexttowardl.c",
    "content": "#include <math.h>\n\nlong double nexttowardl(long double x, long double y)\n{\n\treturn nextafterl(x, y);\n}\n"
  },
  {
    "path": "user.libc/src/math/pow.c",
    "content": "/*\n * Double-precision x^y function.\n *\n * Copyright (c) 2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n\n#include <math.h>\n#include <stdint.h>\n#include \"libm.h\"\n#include \"exp_data.h\"\n#include \"pow_data.h\"\n\n/*\nWorst-case error: 0.54 ULP (~= ulperr_exp + 1024*Ln2*relerr_log*2^53)\nrelerr_log: 1.3 * 2^-68 (Relative error of log, 1.5 * 2^-68 without fma)\nulperr_exp: 0.509 ULP (ULP error of exp, 0.511 ULP without fma)\n*/\n\n#define T __pow_log_data.tab\n#define A __pow_log_data.poly\n#define Ln2hi __pow_log_data.ln2hi\n#define Ln2lo __pow_log_data.ln2lo\n#define N (1 << POW_LOG_TABLE_BITS)\n#define OFF 0x3fe6955500000000\n\n/* Top 12 bits of a double (sign and exponent bits).  */\nstatic inline uint32_t top12(double x)\n{\n\treturn asuint64(x) >> 52;\n}\n\n/* Compute y+TAIL = log(x) where the rounded result is y and TAIL has about\n   additional 15 bits precision.  IX is the bit representation of x, but\n   normalized in the subnormal range using the sign bit for the exponent.  */\nstatic inline double_t log_inline(uint64_t ix, double_t *tail)\n{\n\t/* double_t for better performance on targets with FLT_EVAL_METHOD==2.  */\n\tdouble_t z, r, y, invc, logc, logctail, kd, hi, t1, t2, lo, lo1, lo2, p;\n\tuint64_t iz, tmp;\n\tint k, i;\n\n\t/* x = 2^k z; where z is in range [OFF,2*OFF) and exact.\n\t   The range is split into N subintervals.\n\t   The ith subinterval contains z and c is near its center.  */\n\ttmp = ix - OFF;\n\ti = (tmp >> (52 - POW_LOG_TABLE_BITS)) % N;\n\tk = (int64_t)tmp >> 52; /* arithmetic shift */\n\tiz = ix - (tmp & 0xfffULL << 52);\n\tz = asdouble(iz);\n\tkd = (double_t)k;\n\n\t/* log(x) = k*Ln2 + log(c) + log1p(z/c-1).  */\n\tinvc = T[i].invc;\n\tlogc = T[i].logc;\n\tlogctail = T[i].logctail;\n\n\t/* Note: 1/c is j/N or j/N/2 where j is an integer in [N,2N) and\n     |z/c - 1| < 1/N, so r = z/c - 1 is exactly representible.  */\n#if __FP_FAST_FMA\n\tr = __builtin_fma(z, invc, -1.0);\n#else\n\t/* Split z such that rhi, rlo and rhi*rhi are exact and |rlo| <= |r|.  */\n\tdouble_t zhi = asdouble((iz + (1ULL << 31)) & (-1ULL << 32));\n\tdouble_t zlo = z - zhi;\n\tdouble_t rhi = zhi * invc - 1.0;\n\tdouble_t rlo = zlo * invc;\n\tr = rhi + rlo;\n#endif\n\n\t/* k*Ln2 + log(c) + r.  */\n\tt1 = kd * Ln2hi + logc;\n\tt2 = t1 + r;\n\tlo1 = kd * Ln2lo + logctail;\n\tlo2 = t1 - t2 + r;\n\n\t/* Evaluation is optimized assuming superscalar pipelined execution.  */\n\tdouble_t ar, ar2, ar3, lo3, lo4;\n\tar = A[0] * r; /* A[0] = -0.5.  */\n\tar2 = r * ar;\n\tar3 = r * ar2;\n\t/* k*Ln2 + log(c) + r + A[0]*r*r.  */\n#if __FP_FAST_FMA\n\thi = t2 + ar2;\n\tlo3 = __builtin_fma(ar, r, -ar2);\n\tlo4 = t2 - hi + ar2;\n#else\n\tdouble_t arhi = A[0] * rhi;\n\tdouble_t arhi2 = rhi * arhi;\n\thi = t2 + arhi2;\n\tlo3 = rlo * (ar + arhi);\n\tlo4 = t2 - hi + arhi2;\n#endif\n\t/* p = log1p(r) - r - A[0]*r*r.  */\n\tp = (ar3 * (A[1] + r * A[2] +\n\t\t    ar2 * (A[3] + r * A[4] + ar2 * (A[5] + r * A[6]))));\n\tlo = lo1 + lo2 + lo3 + lo4 + p;\n\ty = hi + lo;\n\t*tail = hi - y + lo;\n\treturn y;\n}\n\n#undef N\n#undef T\n#define N (1 << EXP_TABLE_BITS)\n#define InvLn2N __exp_data.invln2N\n#define NegLn2hiN __exp_data.negln2hiN\n#define NegLn2loN __exp_data.negln2loN\n#define Shift __exp_data.shift\n#define T __exp_data.tab\n#define C2 __exp_data.poly[5 - EXP_POLY_ORDER]\n#define C3 __exp_data.poly[6 - EXP_POLY_ORDER]\n#define C4 __exp_data.poly[7 - EXP_POLY_ORDER]\n#define C5 __exp_data.poly[8 - EXP_POLY_ORDER]\n#define C6 __exp_data.poly[9 - EXP_POLY_ORDER]\n\n/* Handle cases that may overflow or underflow when computing the result that\n   is scale*(1+TMP) without intermediate rounding.  The bit representation of\n   scale is in SBITS, however it has a computed exponent that may have\n   overflown into the sign bit so that needs to be adjusted before using it as\n   a double.  (int32_t)KI is the k used in the argument reduction and exponent\n   adjustment of scale, positive k here means the result may overflow and\n   negative k means the result may underflow.  */\nstatic inline double specialcase(double_t tmp, uint64_t sbits, uint64_t ki)\n{\n\tdouble_t scale, y;\n\n\tif ((ki & 0x80000000) == 0) {\n\t\t/* k > 0, the exponent of scale might have overflowed by <= 460.  */\n\t\tsbits -= 1009ull << 52;\n\t\tscale = asdouble(sbits);\n\t\ty = 0x1p1009 * (scale + scale * tmp);\n\t\treturn eval_as_double(y);\n\t}\n\t/* k < 0, need special care in the subnormal range.  */\n\tsbits += 1022ull << 52;\n\t/* Note: sbits is signed scale.  */\n\tscale = asdouble(sbits);\n\ty = scale + scale * tmp;\n\tif (fabs(y) < 1.0) {\n\t\t/* Round y to the right precision before scaling it into the subnormal\n\t\t   range to avoid double rounding that can cause 0.5+E/2 ulp error where\n\t\t   E is the worst-case ulp error outside the subnormal range.  So this\n\t\t   is only useful if the goal is better than 1 ulp worst-case error.  */\n\t\tdouble_t hi, lo, one = 1.0;\n\t\tif (y < 0.0)\n\t\t\tone = -1.0;\n\t\tlo = scale - y + scale * tmp;\n\t\thi = one + y;\n\t\tlo = one - hi + y + lo;\n\t\ty = eval_as_double(hi + lo) - one;\n\t\t/* Fix the sign of 0.  */\n\t\tif (y == 0.0)\n\t\t\ty = asdouble(sbits & 0x8000000000000000);\n\t\t/* The underflow exception needs to be signaled explicitly.  */\n\t\tfp_force_eval(fp_barrier(0x1p-1022) * 0x1p-1022);\n\t}\n\ty = 0x1p-1022 * y;\n\treturn eval_as_double(y);\n}\n\n#define SIGN_BIAS (0x800 << EXP_TABLE_BITS)\n\n/* Computes sign*exp(x+xtail) where |xtail| < 2^-8/N and |xtail| <= |x|.\n   The sign_bias argument is SIGN_BIAS or 0 and sets the sign to -1 or 1.  */\nstatic inline double exp_inline(double_t x, double_t xtail, uint32_t sign_bias)\n{\n\tuint32_t abstop;\n\tuint64_t ki, idx, top, sbits;\n\t/* double_t for better performance on targets with FLT_EVAL_METHOD==2.  */\n\tdouble_t kd, z, r, r2, scale, tail, tmp;\n\n\tabstop = top12(x) & 0x7ff;\n\tif (predict_false(abstop - top12(0x1p-54) >=\n\t\t\t  top12(512.0) - top12(0x1p-54))) {\n\t\tif (abstop - top12(0x1p-54) >= 0x80000000) {\n\t\t\t/* Avoid spurious underflow for tiny x.  */\n\t\t\t/* Note: 0 is common input.  */\n\t\t\tdouble_t one = WANT_ROUNDING ? 1.0 + x : 1.0;\n\t\t\treturn sign_bias ? -one : one;\n\t\t}\n\t\tif (abstop >= top12(1024.0)) {\n\t\t\t/* Note: inf and nan are already handled.  */\n\t\t\tif (asuint64(x) >> 63)\n\t\t\t\treturn __math_uflow(sign_bias);\n\t\t\telse\n\t\t\t\treturn __math_oflow(sign_bias);\n\t\t}\n\t\t/* Large x is special cased below.  */\n\t\tabstop = 0;\n\t}\n\n\t/* exp(x) = 2^(k/N) * exp(r), with exp(r) in [2^(-1/2N),2^(1/2N)].  */\n\t/* x = ln2/N*k + r, with int k and r in [-ln2/2N, ln2/2N].  */\n\tz = InvLn2N * x;\n#if TOINT_INTRINSICS\n\tkd = roundtoint(z);\n\tki = converttoint(z);\n#elif EXP_USE_TOINT_NARROW\n\t/* z - kd is in [-0.5-2^-16, 0.5] in all rounding modes.  */\n\tkd = eval_as_double(z + Shift);\n\tki = asuint64(kd) >> 16;\n\tkd = (double_t)(int32_t)ki;\n#else\n\t/* z - kd is in [-1, 1] in non-nearest rounding modes.  */\n\tkd = eval_as_double(z + Shift);\n\tki = asuint64(kd);\n\tkd -= Shift;\n#endif\n\tr = x + kd * NegLn2hiN + kd * NegLn2loN;\n\t/* The code assumes 2^-200 < |xtail| < 2^-8/N.  */\n\tr += xtail;\n\t/* 2^(k/N) ~= scale * (1 + tail).  */\n\tidx = 2 * (ki % N);\n\ttop = (ki + sign_bias) << (52 - EXP_TABLE_BITS);\n\ttail = asdouble(T[idx]);\n\t/* This is only a valid scale when -1023*N < k < 1024*N.  */\n\tsbits = T[idx + 1] + top;\n\t/* exp(x) = 2^(k/N) * exp(r) ~= scale + scale * (tail + exp(r) - 1).  */\n\t/* Evaluation is optimized assuming superscalar pipelined execution.  */\n\tr2 = r * r;\n\t/* Without fma the worst case error is 0.25/N ulp larger.  */\n\t/* Worst case error is less than 0.5+1.11/N+(abs poly error * 2^53) ulp.  */\n\ttmp = tail + r + r2 * (C2 + r * C3) + r2 * r2 * (C4 + r * C5);\n\tif (predict_false(abstop == 0))\n\t\treturn specialcase(tmp, sbits, ki);\n\tscale = asdouble(sbits);\n\t/* Note: tmp == 0 or |tmp| > 2^-200 and scale > 2^-739, so there\n\t   is no spurious underflow here even without fma.  */\n\treturn eval_as_double(scale + scale * tmp);\n}\n\n/* Returns 0 if not int, 1 if odd int, 2 if even int.  The argument is\n   the bit representation of a non-zero finite floating-point value.  */\nstatic inline int checkint(uint64_t iy)\n{\n\tint e = iy >> 52 & 0x7ff;\n\tif (e < 0x3ff)\n\t\treturn 0;\n\tif (e > 0x3ff + 52)\n\t\treturn 2;\n\tif (iy & ((1ULL << (0x3ff + 52 - e)) - 1))\n\t\treturn 0;\n\tif (iy & (1ULL << (0x3ff + 52 - e)))\n\t\treturn 1;\n\treturn 2;\n}\n\n/* Returns 1 if input is the bit representation of 0, infinity or nan.  */\nstatic inline int zeroinfnan(uint64_t i)\n{\n\treturn 2 * i - 1 >= 2 * asuint64(INFINITY) - 1;\n}\n\ndouble pow(double x, double y)\n{\n\tuint32_t sign_bias = 0;\n\tuint64_t ix, iy;\n\tuint32_t topx, topy;\n\n\tix = asuint64(x);\n\tiy = asuint64(y);\n\ttopx = top12(x);\n\ttopy = top12(y);\n\tif (predict_false(topx - 0x001 >= 0x7ff - 0x001 ||\n\t\t\t  (topy & 0x7ff) - 0x3be >= 0x43e - 0x3be)) {\n\t\t/* Note: if |y| > 1075 * ln2 * 2^53 ~= 0x1.749p62 then pow(x,y) = inf/0\n\t\t   and if |y| < 2^-54 / 1075 ~= 0x1.e7b6p-65 then pow(x,y) = +-1.  */\n\t\t/* Special cases: (x < 0x1p-126 or inf or nan) or\n\t\t   (|y| < 0x1p-65 or |y| >= 0x1p63 or nan).  */\n\t\tif (predict_false(zeroinfnan(iy))) {\n\t\t\tif (2 * iy == 0)\n\t\t\t\treturn issignaling_inline(x) ? x + y : 1.0;\n\t\t\tif (ix == asuint64(1.0))\n\t\t\t\treturn issignaling_inline(y) ? x + y : 1.0;\n\t\t\tif (2 * ix > 2 * asuint64(INFINITY) ||\n\t\t\t    2 * iy > 2 * asuint64(INFINITY))\n\t\t\t\treturn x + y;\n\t\t\tif (2 * ix == 2 * asuint64(1.0))\n\t\t\t\treturn 1.0;\n\t\t\tif ((2 * ix < 2 * asuint64(1.0)) == !(iy >> 63))\n\t\t\t\treturn 0.0; /* |x|<1 && y==inf or |x|>1 && y==-inf.  */\n\t\t\treturn y * y;\n\t\t}\n\t\tif (predict_false(zeroinfnan(ix))) {\n\t\t\tdouble_t x2 = x * x;\n\t\t\tif (ix >> 63 && checkint(iy) == 1)\n\t\t\t\tx2 = -x2;\n\t\t\t/* Without the barrier some versions of clang hoist the 1/x2 and\n\t\t\t   thus division by zero exception can be signaled spuriously.  */\n\t\t\treturn iy >> 63 ? fp_barrier(1 / x2) : x2;\n\t\t}\n\t\t/* Here x and y are non-zero finite.  */\n\t\tif (ix >> 63) {\n\t\t\t/* Finite x < 0.  */\n\t\t\tint yint = checkint(iy);\n\t\t\tif (yint == 0)\n\t\t\t\treturn __math_invalid(x);\n\t\t\tif (yint == 1)\n\t\t\t\tsign_bias = SIGN_BIAS;\n\t\t\tix &= 0x7fffffffffffffff;\n\t\t\ttopx &= 0x7ff;\n\t\t}\n\t\tif ((topy & 0x7ff) - 0x3be >= 0x43e - 0x3be) {\n\t\t\t/* Note: sign_bias == 0 here because y is not odd.  */\n\t\t\tif (ix == asuint64(1.0))\n\t\t\t\treturn 1.0;\n\t\t\tif ((topy & 0x7ff) < 0x3be) {\n\t\t\t\t/* |y| < 2^-65, x^y ~= 1 + y*log(x).  */\n\t\t\t\tif (WANT_ROUNDING)\n\t\t\t\t\treturn ix > asuint64(1.0) ? 1.0 + y :\n\t\t\t\t\t\t\t\t    1.0 - y;\n\t\t\t\telse\n\t\t\t\t\treturn 1.0;\n\t\t\t}\n\t\t\treturn (ix > asuint64(1.0)) == (topy < 0x800) ?\n\t\t\t\t       __math_oflow(0) :\n\t\t\t\t       __math_uflow(0);\n\t\t}\n\t\tif (topx == 0) {\n\t\t\t/* Normalize subnormal x so exponent becomes negative.  */\n\t\t\tix = asuint64(x * 0x1p52);\n\t\t\tix &= 0x7fffffffffffffff;\n\t\t\tix -= 52ULL << 52;\n\t\t}\n\t}\n\n\tdouble_t lo;\n\tdouble_t hi = log_inline(ix, &lo);\n\tdouble_t ehi, elo;\n#if __FP_FAST_FMA\n\tehi = y * hi;\n\telo = y * lo + __builtin_fma(y, hi, -ehi);\n#else\n\tdouble_t yhi = asdouble(iy & -1ULL << 27);\n\tdouble_t ylo = y - yhi;\n\tdouble_t lhi = asdouble(asuint64(hi) & -1ULL << 27);\n\tdouble_t llo = hi - lhi + lo;\n\tehi = yhi * lhi;\n\telo = ylo * lhi + y * llo; /* |elo| < |ehi| * 2^-25.  */\n#endif\n\treturn exp_inline(ehi, elo, sign_bias);\n}\n"
  },
  {
    "path": "user.libc/src/math/pow_data.c",
    "content": "/*\n * Data for the log part of pow.\n *\n * Copyright (c) 2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n\n#include \"pow_data.h\"\n\n#define N (1 << POW_LOG_TABLE_BITS)\n\nconst struct pow_log_data __pow_log_data = {\n.ln2hi = 0x1.62e42fefa3800p-1,\n.ln2lo = 0x1.ef35793c76730p-45,\n.poly = {\n// relative error: 0x1.11922ap-70\n// in -0x1.6bp-8 0x1.6bp-8\n// Coefficients are scaled to match the scaling during evaluation.\n-0x1p-1,\n0x1.555555555556p-2 * -2,\n-0x1.0000000000006p-2 * -2,\n0x1.999999959554ep-3 * 4,\n-0x1.555555529a47ap-3 * 4,\n0x1.2495b9b4845e9p-3 * -8,\n-0x1.0002b8b263fc3p-3 * -8,\n},\n/* Algorithm:\n\n\tx = 2^k z\n\tlog(x) = k ln2 + log(c) + log(z/c)\n\tlog(z/c) = poly(z/c - 1)\n\nwhere z is in [0x1.69555p-1; 0x1.69555p0] which is split into N subintervals\nand z falls into the ith one, then table entries are computed as\n\n\ttab[i].invc = 1/c\n\ttab[i].logc = round(0x1p43*log(c))/0x1p43\n\ttab[i].logctail = (double)(log(c) - logc)\n\nwhere c is chosen near the center of the subinterval such that 1/c has only a\nfew precision bits so z/c - 1 is exactly representible as double:\n\n\t1/c = center < 1 ? round(N/center)/N : round(2*N/center)/N/2\n\nNote: |z/c - 1| < 1/N for the chosen c, |log(c) - logc - logctail| < 0x1p-97,\nthe last few bits of logc are rounded away so k*ln2hi + logc has no rounding\nerror and the interval for z is selected such that near x == 1, where log(x)\nis tiny, large cancellation error is avoided in logc + poly(z/c - 1).  */\n.tab = {\n#define A(a, b, c) {a, 0, b, c},\nA(0x1.6a00000000000p+0, -0x1.62c82f2b9c800p-2, 0x1.ab42428375680p-48)\nA(0x1.6800000000000p+0, -0x1.5d1bdbf580800p-2, -0x1.ca508d8e0f720p-46)\nA(0x1.6600000000000p+0, -0x1.5767717455800p-2, -0x1.362a4d5b6506dp-45)\nA(0x1.6400000000000p+0, -0x1.51aad872df800p-2, -0x1.684e49eb067d5p-49)\nA(0x1.6200000000000p+0, -0x1.4be5f95777800p-2, -0x1.41b6993293ee0p-47)\nA(0x1.6000000000000p+0, -0x1.4618bc21c6000p-2, 0x1.3d82f484c84ccp-46)\nA(0x1.5e00000000000p+0, -0x1.404308686a800p-2, 0x1.c42f3ed820b3ap-50)\nA(0x1.5c00000000000p+0, -0x1.3a64c55694800p-2, 0x1.0b1c686519460p-45)\nA(0x1.5a00000000000p+0, -0x1.347dd9a988000p-2, 0x1.5594dd4c58092p-45)\nA(0x1.5800000000000p+0, -0x1.2e8e2bae12000p-2, 0x1.67b1e99b72bd8p-45)\nA(0x1.5600000000000p+0, -0x1.2895a13de8800p-2, 0x1.5ca14b6cfb03fp-46)\nA(0x1.5600000000000p+0, -0x1.2895a13de8800p-2, 0x1.5ca14b6cfb03fp-46)\nA(0x1.5400000000000p+0, -0x1.22941fbcf7800p-2, -0x1.65a242853da76p-46)\nA(0x1.5200000000000p+0, -0x1.1c898c1699800p-2, -0x1.fafbc68e75404p-46)\nA(0x1.5000000000000p+0, -0x1.1675cababa800p-2, 0x1.f1fc63382a8f0p-46)\nA(0x1.4e00000000000p+0, -0x1.1058bf9ae4800p-2, -0x1.6a8c4fd055a66p-45)\nA(0x1.4c00000000000p+0, -0x1.0a324e2739000p-2, -0x1.c6bee7ef4030ep-47)\nA(0x1.4a00000000000p+0, -0x1.0402594b4d000p-2, -0x1.036b89ef42d7fp-48)\nA(0x1.4a00000000000p+0, -0x1.0402594b4d000p-2, -0x1.036b89ef42d7fp-48)\nA(0x1.4800000000000p+0, -0x1.fb9186d5e4000p-3, 0x1.d572aab993c87p-47)\nA(0x1.4600000000000p+0, -0x1.ef0adcbdc6000p-3, 0x1.b26b79c86af24p-45)\nA(0x1.4400000000000p+0, -0x1.e27076e2af000p-3, -0x1.72f4f543fff10p-46)\nA(0x1.4200000000000p+0, -0x1.d5c216b4fc000p-3, 0x1.1ba91bbca681bp-45)\nA(0x1.4000000000000p+0, -0x1.c8ff7c79aa000p-3, 0x1.7794f689f8434p-45)\nA(0x1.4000000000000p+0, -0x1.c8ff7c79aa000p-3, 0x1.7794f689f8434p-45)\nA(0x1.3e00000000000p+0, -0x1.bc286742d9000p-3, 0x1.94eb0318bb78fp-46)\nA(0x1.3c00000000000p+0, -0x1.af3c94e80c000p-3, 0x1.a4e633fcd9066p-52)\nA(0x1.3a00000000000p+0, -0x1.a23bc1fe2b000p-3, -0x1.58c64dc46c1eap-45)\nA(0x1.3a00000000000p+0, -0x1.a23bc1fe2b000p-3, -0x1.58c64dc46c1eap-45)\nA(0x1.3800000000000p+0, -0x1.9525a9cf45000p-3, -0x1.ad1d904c1d4e3p-45)\nA(0x1.3600000000000p+0, -0x1.87fa06520d000p-3, 0x1.bbdbf7fdbfa09p-45)\nA(0x1.3400000000000p+0, -0x1.7ab890210e000p-3, 0x1.bdb9072534a58p-45)\nA(0x1.3400000000000p+0, -0x1.7ab890210e000p-3, 0x1.bdb9072534a58p-45)\nA(0x1.3200000000000p+0, -0x1.6d60fe719d000p-3, -0x1.0e46aa3b2e266p-46)\nA(0x1.3000000000000p+0, -0x1.5ff3070a79000p-3, -0x1.e9e439f105039p-46)\nA(0x1.3000000000000p+0, -0x1.5ff3070a79000p-3, -0x1.e9e439f105039p-46)\nA(0x1.2e00000000000p+0, -0x1.526e5e3a1b000p-3, -0x1.0de8b90075b8fp-45)\nA(0x1.2c00000000000p+0, -0x1.44d2b6ccb8000p-3, 0x1.70cc16135783cp-46)\nA(0x1.2c00000000000p+0, -0x1.44d2b6ccb8000p-3, 0x1.70cc16135783cp-46)\nA(0x1.2a00000000000p+0, -0x1.371fc201e9000p-3, 0x1.178864d27543ap-48)\nA(0x1.2800000000000p+0, -0x1.29552f81ff000p-3, -0x1.48d301771c408p-45)\nA(0x1.2600000000000p+0, -0x1.1b72ad52f6000p-3, -0x1.e80a41811a396p-45)\nA(0x1.2600000000000p+0, -0x1.1b72ad52f6000p-3, -0x1.e80a41811a396p-45)\nA(0x1.2400000000000p+0, -0x1.0d77e7cd09000p-3, 0x1.a699688e85bf4p-47)\nA(0x1.2400000000000p+0, -0x1.0d77e7cd09000p-3, 0x1.a699688e85bf4p-47)\nA(0x1.2200000000000p+0, -0x1.fec9131dbe000p-4, -0x1.575545ca333f2p-45)\nA(0x1.2000000000000p+0, -0x1.e27076e2b0000p-4, 0x1.a342c2af0003cp-45)\nA(0x1.2000000000000p+0, -0x1.e27076e2b0000p-4, 0x1.a342c2af0003cp-45)\nA(0x1.1e00000000000p+0, -0x1.c5e548f5bc000p-4, -0x1.d0c57585fbe06p-46)\nA(0x1.1c00000000000p+0, -0x1.a926d3a4ae000p-4, 0x1.53935e85baac8p-45)\nA(0x1.1c00000000000p+0, -0x1.a926d3a4ae000p-4, 0x1.53935e85baac8p-45)\nA(0x1.1a00000000000p+0, -0x1.8c345d631a000p-4, 0x1.37c294d2f5668p-46)\nA(0x1.1a00000000000p+0, -0x1.8c345d631a000p-4, 0x1.37c294d2f5668p-46)\nA(0x1.1800000000000p+0, -0x1.6f0d28ae56000p-4, -0x1.69737c93373dap-45)\nA(0x1.1600000000000p+0, -0x1.51b073f062000p-4, 0x1.f025b61c65e57p-46)\nA(0x1.1600000000000p+0, -0x1.51b073f062000p-4, 0x1.f025b61c65e57p-46)\nA(0x1.1400000000000p+0, -0x1.341d7961be000p-4, 0x1.c5edaccf913dfp-45)\nA(0x1.1400000000000p+0, -0x1.341d7961be000p-4, 0x1.c5edaccf913dfp-45)\nA(0x1.1200000000000p+0, -0x1.16536eea38000p-4, 0x1.47c5e768fa309p-46)\nA(0x1.1000000000000p+0, -0x1.f0a30c0118000p-5, 0x1.d599e83368e91p-45)\nA(0x1.1000000000000p+0, -0x1.f0a30c0118000p-5, 0x1.d599e83368e91p-45)\nA(0x1.0e00000000000p+0, -0x1.b42dd71198000p-5, 0x1.c827ae5d6704cp-46)\nA(0x1.0e00000000000p+0, -0x1.b42dd71198000p-5, 0x1.c827ae5d6704cp-46)\nA(0x1.0c00000000000p+0, -0x1.77458f632c000p-5, -0x1.cfc4634f2a1eep-45)\nA(0x1.0c00000000000p+0, -0x1.77458f632c000p-5, -0x1.cfc4634f2a1eep-45)\nA(0x1.0a00000000000p+0, -0x1.39e87b9fec000p-5, 0x1.502b7f526feaap-48)\nA(0x1.0a00000000000p+0, -0x1.39e87b9fec000p-5, 0x1.502b7f526feaap-48)\nA(0x1.0800000000000p+0, -0x1.f829b0e780000p-6, -0x1.980267c7e09e4p-45)\nA(0x1.0800000000000p+0, -0x1.f829b0e780000p-6, -0x1.980267c7e09e4p-45)\nA(0x1.0600000000000p+0, -0x1.7b91b07d58000p-6, -0x1.88d5493faa639p-45)\nA(0x1.0400000000000p+0, -0x1.fc0a8b0fc0000p-7, -0x1.f1e7cf6d3a69cp-50)\nA(0x1.0400000000000p+0, -0x1.fc0a8b0fc0000p-7, -0x1.f1e7cf6d3a69cp-50)\nA(0x1.0200000000000p+0, -0x1.fe02a6b100000p-8, -0x1.9e23f0dda40e4p-46)\nA(0x1.0200000000000p+0, -0x1.fe02a6b100000p-8, -0x1.9e23f0dda40e4p-46)\nA(0x1.0000000000000p+0, 0x0.0000000000000p+0, 0x0.0000000000000p+0)\nA(0x1.0000000000000p+0, 0x0.0000000000000p+0, 0x0.0000000000000p+0)\nA(0x1.fc00000000000p-1, 0x1.0101575890000p-7, -0x1.0c76b999d2be8p-46)\nA(0x1.f800000000000p-1, 0x1.0205658938000p-6, -0x1.3dc5b06e2f7d2p-45)\nA(0x1.f400000000000p-1, 0x1.8492528c90000p-6, -0x1.aa0ba325a0c34p-45)\nA(0x1.f000000000000p-1, 0x1.0415d89e74000p-5, 0x1.111c05cf1d753p-47)\nA(0x1.ec00000000000p-1, 0x1.466aed42e0000p-5, -0x1.c167375bdfd28p-45)\nA(0x1.e800000000000p-1, 0x1.894aa149fc000p-5, -0x1.97995d05a267dp-46)\nA(0x1.e400000000000p-1, 0x1.ccb73cdddc000p-5, -0x1.a68f247d82807p-46)\nA(0x1.e200000000000p-1, 0x1.eea31c006c000p-5, -0x1.e113e4fc93b7bp-47)\nA(0x1.de00000000000p-1, 0x1.1973bd1466000p-4, -0x1.5325d560d9e9bp-45)\nA(0x1.da00000000000p-1, 0x1.3bdf5a7d1e000p-4, 0x1.cc85ea5db4ed7p-45)\nA(0x1.d600000000000p-1, 0x1.5e95a4d97a000p-4, -0x1.c69063c5d1d1ep-45)\nA(0x1.d400000000000p-1, 0x1.700d30aeac000p-4, 0x1.c1e8da99ded32p-49)\nA(0x1.d000000000000p-1, 0x1.9335e5d594000p-4, 0x1.3115c3abd47dap-45)\nA(0x1.cc00000000000p-1, 0x1.b6ac88dad6000p-4, -0x1.390802bf768e5p-46)\nA(0x1.ca00000000000p-1, 0x1.c885801bc4000p-4, 0x1.646d1c65aacd3p-45)\nA(0x1.c600000000000p-1, 0x1.ec739830a2000p-4, -0x1.dc068afe645e0p-45)\nA(0x1.c400000000000p-1, 0x1.fe89139dbe000p-4, -0x1.534d64fa10afdp-45)\nA(0x1.c000000000000p-1, 0x1.1178e8227e000p-3, 0x1.1ef78ce2d07f2p-45)\nA(0x1.be00000000000p-1, 0x1.1aa2b7e23f000p-3, 0x1.ca78e44389934p-45)\nA(0x1.ba00000000000p-1, 0x1.2d1610c868000p-3, 0x1.39d6ccb81b4a1p-47)\nA(0x1.b800000000000p-1, 0x1.365fcb0159000p-3, 0x1.62fa8234b7289p-51)\nA(0x1.b400000000000p-1, 0x1.4913d8333b000p-3, 0x1.5837954fdb678p-45)\nA(0x1.b200000000000p-1, 0x1.527e5e4a1b000p-3, 0x1.633e8e5697dc7p-45)\nA(0x1.ae00000000000p-1, 0x1.6574ebe8c1000p-3, 0x1.9cf8b2c3c2e78p-46)\nA(0x1.ac00000000000p-1, 0x1.6f0128b757000p-3, -0x1.5118de59c21e1p-45)\nA(0x1.aa00000000000p-1, 0x1.7898d85445000p-3, -0x1.c661070914305p-46)\nA(0x1.a600000000000p-1, 0x1.8beafeb390000p-3, -0x1.73d54aae92cd1p-47)\nA(0x1.a400000000000p-1, 0x1.95a5adcf70000p-3, 0x1.7f22858a0ff6fp-47)\nA(0x1.a000000000000p-1, 0x1.a93ed3c8ae000p-3, -0x1.8724350562169p-45)\nA(0x1.9e00000000000p-1, 0x1.b31d8575bd000p-3, -0x1.c358d4eace1aap-47)\nA(0x1.9c00000000000p-1, 0x1.bd087383be000p-3, -0x1.d4bc4595412b6p-45)\nA(0x1.9a00000000000p-1, 0x1.c6ffbc6f01000p-3, -0x1.1ec72c5962bd2p-48)\nA(0x1.9600000000000p-1, 0x1.db13db0d49000p-3, -0x1.aff2af715b035p-45)\nA(0x1.9400000000000p-1, 0x1.e530effe71000p-3, 0x1.212276041f430p-51)\nA(0x1.9200000000000p-1, 0x1.ef5ade4dd0000p-3, -0x1.a211565bb8e11p-51)\nA(0x1.9000000000000p-1, 0x1.f991c6cb3b000p-3, 0x1.bcbecca0cdf30p-46)\nA(0x1.8c00000000000p-1, 0x1.07138604d5800p-2, 0x1.89cdb16ed4e91p-48)\nA(0x1.8a00000000000p-1, 0x1.0c42d67616000p-2, 0x1.7188b163ceae9p-45)\nA(0x1.8800000000000p-1, 0x1.1178e8227e800p-2, -0x1.c210e63a5f01cp-45)\nA(0x1.8600000000000p-1, 0x1.16b5ccbacf800p-2, 0x1.b9acdf7a51681p-45)\nA(0x1.8400000000000p-1, 0x1.1bf99635a6800p-2, 0x1.ca6ed5147bdb7p-45)\nA(0x1.8200000000000p-1, 0x1.214456d0eb800p-2, 0x1.a87deba46baeap-47)\nA(0x1.7e00000000000p-1, 0x1.2bef07cdc9000p-2, 0x1.a9cfa4a5004f4p-45)\nA(0x1.7c00000000000p-1, 0x1.314f1e1d36000p-2, -0x1.8e27ad3213cb8p-45)\nA(0x1.7a00000000000p-1, 0x1.36b6776be1000p-2, 0x1.16ecdb0f177c8p-46)\nA(0x1.7800000000000p-1, 0x1.3c25277333000p-2, 0x1.83b54b606bd5cp-46)\nA(0x1.7600000000000p-1, 0x1.419b423d5e800p-2, 0x1.8e436ec90e09dp-47)\nA(0x1.7400000000000p-1, 0x1.4718dc271c800p-2, -0x1.f27ce0967d675p-45)\nA(0x1.7200000000000p-1, 0x1.4c9e09e173000p-2, -0x1.e20891b0ad8a4p-45)\nA(0x1.7000000000000p-1, 0x1.522ae0738a000p-2, 0x1.ebe708164c759p-45)\nA(0x1.6e00000000000p-1, 0x1.57bf753c8d000p-2, 0x1.fadedee5d40efp-46)\nA(0x1.6c00000000000p-1, 0x1.5d5bddf596000p-2, -0x1.a0b2a08a465dcp-47)\n},\n};\n"
  },
  {
    "path": "user.libc/src/math/pow_data.h",
    "content": "/*\n * Copyright (c) 2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n#ifndef _POW_DATA_H\n#define _POW_DATA_H\n\n#include <features.h>\n\n#define POW_LOG_TABLE_BITS 7\n#define POW_LOG_POLY_ORDER 8\nextern hidden const struct pow_log_data {\n\tdouble ln2hi;\n\tdouble ln2lo;\n\tdouble poly[POW_LOG_POLY_ORDER - 1]; /* First coefficient is 1.  */\n\t/* Note: the pad field is unused, but allows slightly faster indexing.  */\n\tstruct {\n\t\tdouble invc, pad, logc, logctail;\n\t} tab[1 << POW_LOG_TABLE_BITS];\n} __pow_log_data;\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/powerpc/fabs.c",
    "content": "#include <math.h>\n\n#if defined(_SOFT_FLOAT) || defined(BROKEN_PPC_D_ASM)\n\n#include \"../fabs.c\"\n\n#else\n\ndouble fabs(double x)\n{\n\t__asm__ (\"fabs %0, %1\" : \"=d\"(x) : \"d\"(x));\n\treturn x;\n}\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/powerpc/fabsf.c",
    "content": "#include <math.h>\n\n#ifdef _SOFT_FLOAT\n\n#include \"../fabsf.c\"\n\n#else\n\nfloat fabsf(float x)\n{\n\t__asm__ (\"fabs %0, %1\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/powerpc/fma.c",
    "content": "#include <math.h>\n\n#if defined(_SOFT_FLOAT) || defined(BROKEN_PPC_D_ASM)\n\n#include \"../fma.c\"\n\n#else\n\ndouble fma(double x, double y, double z)\n{\n\t__asm__(\"fmadd %0, %1, %2, %3\" : \"=d\"(x) : \"d\"(x), \"d\"(y), \"d\"(z));\n\treturn x;\n}\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/powerpc/fmaf.c",
    "content": "#include <math.h>\n\n#ifdef _SOFT_FLOAT\n\n#include \"../fmaf.c\"\n\n#else\n\nfloat fmaf(float x, float y, float z)\n{\n\t__asm__(\"fmadds %0, %1, %2, %3\" : \"=f\"(x) : \"f\"(x), \"f\"(y), \"f\"(z));\n\treturn x;\n}\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/powerpc/sqrt.c",
    "content": "#include <math.h>\n\n#if !defined _SOFT_FLOAT && defined _ARCH_PPCSQ\n\ndouble sqrt(double x)\n{\n\t__asm__ (\"fsqrt %0, %1\\n\" : \"=d\" (x) : \"d\" (x));\n\treturn x;\n}\n\n#else\n\n#include \"../sqrt.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/powerpc/sqrtf.c",
    "content": "#include <math.h>\n\n#if !defined _SOFT_FLOAT && defined _ARCH_PPCSQ\n\nfloat sqrtf(float x)\n{\n\t__asm__ (\"fsqrts %0, %1\\n\" : \"=f\" (x) : \"f\" (x));\n\treturn x;\n}\n\n#else\n\n#include \"../sqrtf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/powerpc64/ceil.c",
    "content": "#include <math.h>\n\n#ifdef _ARCH_PWR5X\n\ndouble ceil(double x)\n{\n\t__asm__ (\"frip %0, %1\" : \"=d\"(x) : \"d\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../ceil.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/powerpc64/ceilf.c",
    "content": "#include <math.h>\n\n#ifdef _ARCH_PWR5X\n\nfloat ceilf(float x)\n{\n\t__asm__ (\"frip %0, %1\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../ceilf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/powerpc64/fabs.c",
    "content": "#include <math.h>\n\ndouble fabs(double x)\n{\n\t__asm__ (\"fabs %0, %1\" : \"=d\"(x) : \"d\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/powerpc64/fabsf.c",
    "content": "#include <math.h>\n\nfloat fabsf(float x)\n{\n\t__asm__ (\"fabs %0, %1\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/powerpc64/floor.c",
    "content": "#include <math.h>\n\n#ifdef _ARCH_PWR5X\n\ndouble floor(double x)\n{\n\t__asm__ (\"frim %0, %1\" : \"=d\"(x) : \"d\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../floor.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/powerpc64/floorf.c",
    "content": "#include <math.h>\n\n#ifdef _ARCH_PWR5X\n\nfloat floorf(float x)\n{\n\t__asm__ (\"frim %0, %1\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../floorf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/powerpc64/fma.c",
    "content": "#include <math.h>\n\ndouble fma(double x, double y, double z)\n{\n\t__asm__ (\"fmadd %0, %1, %2, %3\" : \"=d\"(x) : \"d\"(x), \"d\"(y), \"d\"(z));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/powerpc64/fmaf.c",
    "content": "#include <math.h>\n\nfloat fmaf(float x, float y, float z)\n{\n\t__asm__ (\"fmadds %0, %1, %2, %3\" : \"=f\"(x) : \"f\"(x), \"f\"(y), \"f\"(z));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/powerpc64/fmax.c",
    "content": "#include <math.h>\n\n#ifdef __VSX__\n\ndouble fmax(double x, double y)\n{\n\t__asm__ (\"xsmaxdp %x0, %x1, %x2\" : \"=ws\"(x) : \"ws\"(x), \"ws\"(y));\n\treturn x;\n}\n\n#else\n\n#include \"../fmax.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/powerpc64/fmaxf.c",
    "content": "#include <math.h>\n\n#ifdef __VSX__\n\nfloat fmaxf(float x, float y)\n{\n\t__asm__ (\"xsmaxdp %x0, %x1, %x2\" : \"=ww\"(x) : \"ww\"(x), \"ww\"(y));\n\treturn x;\n}\n\n#else\n\n#include \"../fmaxf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/powerpc64/fmin.c",
    "content": "#include <math.h>\n\n#ifdef __VSX__\n\ndouble fmin(double x, double y)\n{\n\t__asm__ (\"xsmindp %x0, %x1, %x2\" : \"=ws\"(x) : \"ws\"(x), \"ws\"(y));\n\treturn x;\n}\n\n#else\n\n#include \"../fmin.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/powerpc64/fminf.c",
    "content": "#include <math.h>\n\n#ifdef __VSX__\n\nfloat fminf(float x, float y)\n{\n\t__asm__ (\"xsmindp %x0, %x1, %x2\" : \"=ww\"(x) : \"ww\"(x), \"ww\"(y));\n\treturn x;\n}\n\n#else\n\n#include \"../fminf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/powerpc64/lrint.c",
    "content": "#include <math.h>\n\n#ifdef _ARCH_PWR5X\n\nlong lrint(double x)\n{\n\tlong n;\n\t__asm__ (\"fctid %0, %1\" : \"=d\"(n) : \"d\"(x));\n\treturn n;\n}\n\n#else\n\n#include \"../lrint.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/powerpc64/lrintf.c",
    "content": "#include <math.h>\n\n#ifdef _ARCH_PWR5X\n\nlong lrintf(float x)\n{\n\tlong n;\n\t__asm__ (\"fctid %0, %1\" : \"=d\"(n) : \"f\"(x));\n\treturn n;\n}\n\n#else\n\n#include \"../lrintf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/powerpc64/lround.c",
    "content": "#include <math.h>\n\n#ifdef __VSX__\n\nlong lround(double x)\n{\n\tlong n;\n\t__asm__ (\n\t\t\"xsrdpi %1, %1\\n\"\n\t\t\"fctid %0, %1\\n\" : \"=d\"(n), \"+d\"(x));\n\treturn n;\n}\n\n#else\n\n#include \"../lround.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/powerpc64/lroundf.c",
    "content": "#include <math.h>\n\n#ifdef __VSX__\n\nlong lroundf(float x)\n{\n\tlong n;\n\t__asm__ (\n\t\t\"xsrdpi %1, %1\\n\"\n\t\t\"fctid %0, %1\\n\" : \"=d\"(n), \"+f\"(x));\n\treturn n;\n}\n\n#else\n\n#include \"../lroundf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/powerpc64/round.c",
    "content": "#include <math.h>\n\n#ifdef _ARCH_PWR5X\n\ndouble round(double x)\n{\n\t__asm__ (\"frin %0, %1\" : \"=d\"(x) : \"d\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../round.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/powerpc64/roundf.c",
    "content": "#include <math.h>\n\n#ifdef _ARCH_PWR5X\n\nfloat roundf(float x)\n{\n\t__asm__ (\"frin %0, %1\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../roundf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/powerpc64/sqrt.c",
    "content": "#include <math.h>\n\ndouble sqrt(double x)\n{\n\t__asm__ (\"fsqrt %0, %1\" : \"=d\"(x) : \"d\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/powerpc64/sqrtf.c",
    "content": "#include <math.h>\n\nfloat sqrtf(float x)\n{\n\t__asm__ (\"fsqrts %0, %1\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/powerpc64/trunc.c",
    "content": "#include <math.h>\n\n#ifdef _ARCH_PWR5X\n\ndouble trunc(double x)\n{\n\t__asm__ (\"friz %0, %1\" : \"=d\"(x) : \"d\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../trunc.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/powerpc64/truncf.c",
    "content": "#include <math.h>\n\n#ifdef _ARCH_PWR5X\n\nfloat truncf(float x)\n{\n\t__asm__ (\"friz %0, %1\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../truncf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/powf.c",
    "content": "/*\n * Copyright (c) 2017-2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n\n#include <math.h>\n#include <stdint.h>\n#include \"libm.h\"\n#include \"exp2f_data.h\"\n#include \"powf_data.h\"\n\n/*\nPOWF_LOG2_POLY_ORDER = 5\nEXP2F_TABLE_BITS = 5\n\nULP error: 0.82 (~ 0.5 + relerr*2^24)\nrelerr: 1.27 * 2^-26 (Relative error ~= 128*Ln2*relerr_log2 + relerr_exp2)\nrelerr_log2: 1.83 * 2^-33 (Relative error of logx.)\nrelerr_exp2: 1.69 * 2^-34 (Relative error of exp2(ylogx).)\n*/\n\n#define N (1 << POWF_LOG2_TABLE_BITS)\n#define T __powf_log2_data.tab\n#define A __powf_log2_data.poly\n#define OFF 0x3f330000\n\n/* Subnormal input is normalized so ix has negative biased exponent.\n   Output is multiplied by N (POWF_SCALE) if TOINT_INTRINICS is set.  */\nstatic inline double_t log2_inline(uint32_t ix)\n{\n\tdouble_t z, r, r2, r4, p, q, y, y0, invc, logc;\n\tuint32_t iz, top, tmp;\n\tint k, i;\n\n\t/* x = 2^k z; where z is in range [OFF,2*OFF] and exact.\n\t   The range is split into N subintervals.\n\t   The ith subinterval contains z and c is near its center.  */\n\ttmp = ix - OFF;\n\ti = (tmp >> (23 - POWF_LOG2_TABLE_BITS)) % N;\n\ttop = tmp & 0xff800000;\n\tiz = ix - top;\n\tk = (int32_t)top >> (23 - POWF_SCALE_BITS); /* arithmetic shift */\n\tinvc = T[i].invc;\n\tlogc = T[i].logc;\n\tz = (double_t)asfloat(iz);\n\n\t/* log2(x) = log1p(z/c-1)/ln2 + log2(c) + k */\n\tr = z * invc - 1;\n\ty0 = logc + (double_t)k;\n\n\t/* Pipelined polynomial evaluation to approximate log1p(r)/ln2.  */\n\tr2 = r * r;\n\ty = A[0] * r + A[1];\n\tp = A[2] * r + A[3];\n\tr4 = r2 * r2;\n\tq = A[4] * r + y0;\n\tq = p * r2 + q;\n\ty = y * r4 + q;\n\treturn y;\n}\n\n#undef N\n#undef T\n#define N (1 << EXP2F_TABLE_BITS)\n#define T __exp2f_data.tab\n#define SIGN_BIAS (1 << (EXP2F_TABLE_BITS + 11))\n\n/* The output of log2 and thus the input of exp2 is either scaled by N\n   (in case of fast toint intrinsics) or not.  The unscaled xd must be\n   in [-1021,1023], sign_bias sets the sign of the result.  */\nstatic inline float exp2_inline(double_t xd, uint32_t sign_bias)\n{\n\tuint64_t ki, ski, t;\n\tdouble_t kd, z, r, r2, y, s;\n\n#if TOINT_INTRINSICS\n#define C __exp2f_data.poly_scaled\n\t/* N*x = k + r with r in [-1/2, 1/2] */\n\tkd = roundtoint(xd); /* k */\n\tki = converttoint(xd);\n#else\n#define C __exp2f_data.poly\n#define SHIFT __exp2f_data.shift_scaled\n\t/* x = k/N + r with r in [-1/(2N), 1/(2N)] */\n\tkd = eval_as_double(xd + SHIFT);\n\tki = asuint64(kd);\n\tkd -= SHIFT; /* k/N */\n#endif\n\tr = xd - kd;\n\n\t/* exp2(x) = 2^(k/N) * 2^r ~= s * (C0*r^3 + C1*r^2 + C2*r + 1) */\n\tt = T[ki % N];\n\tski = ki + sign_bias;\n\tt += ski << (52 - EXP2F_TABLE_BITS);\n\ts = asdouble(t);\n\tz = C[0] * r + C[1];\n\tr2 = r * r;\n\ty = C[2] * r + 1;\n\ty = z * r2 + y;\n\ty = y * s;\n\treturn eval_as_float(y);\n}\n\n/* Returns 0 if not int, 1 if odd int, 2 if even int.  The argument is\n   the bit representation of a non-zero finite floating-point value.  */\nstatic inline int checkint(uint32_t iy)\n{\n\tint e = iy >> 23 & 0xff;\n\tif (e < 0x7f)\n\t\treturn 0;\n\tif (e > 0x7f + 23)\n\t\treturn 2;\n\tif (iy & ((1 << (0x7f + 23 - e)) - 1))\n\t\treturn 0;\n\tif (iy & (1 << (0x7f + 23 - e)))\n\t\treturn 1;\n\treturn 2;\n}\n\nstatic inline int zeroinfnan(uint32_t ix)\n{\n\treturn 2 * ix - 1 >= 2u * 0x7f800000 - 1;\n}\n\nfloat powf(float x, float y)\n{\n\tuint32_t sign_bias = 0;\n\tuint32_t ix, iy;\n\n\tix = asuint(x);\n\tiy = asuint(y);\n\tif (predict_false(ix - 0x00800000 >= 0x7f800000 - 0x00800000 ||\n\t\t\t  zeroinfnan(iy))) {\n\t\t/* Either (x < 0x1p-126 or inf or nan) or (y is 0 or inf or nan).  */\n\t\tif (predict_false(zeroinfnan(iy))) {\n\t\t\tif (2 * iy == 0)\n\t\t\t\treturn issignalingf_inline(x) ? x + y : 1.0f;\n\t\t\tif (ix == 0x3f800000)\n\t\t\t\treturn issignalingf_inline(y) ? x + y : 1.0f;\n\t\t\tif (2 * ix > 2u * 0x7f800000 ||\n\t\t\t    2 * iy > 2u * 0x7f800000)\n\t\t\t\treturn x + y;\n\t\t\tif (2 * ix == 2 * 0x3f800000)\n\t\t\t\treturn 1.0f;\n\t\t\tif ((2 * ix < 2 * 0x3f800000) == !(iy & 0x80000000))\n\t\t\t\treturn 0.0f; /* |x|<1 && y==inf or |x|>1 && y==-inf.  */\n\t\t\treturn y * y;\n\t\t}\n\t\tif (predict_false(zeroinfnan(ix))) {\n\t\t\tfloat_t x2 = x * x;\n\t\t\tif (ix & 0x80000000 && checkint(iy) == 1)\n\t\t\t\tx2 = -x2;\n\t\t\t/* Without the barrier some versions of clang hoist the 1/x2 and\n\t\t\t   thus division by zero exception can be signaled spuriously.  */\n\t\t\treturn iy & 0x80000000 ? fp_barrierf(1 / x2) : x2;\n\t\t}\n\t\t/* x and y are non-zero finite.  */\n\t\tif (ix & 0x80000000) {\n\t\t\t/* Finite x < 0.  */\n\t\t\tint yint = checkint(iy);\n\t\t\tif (yint == 0)\n\t\t\t\treturn __math_invalidf(x);\n\t\t\tif (yint == 1)\n\t\t\t\tsign_bias = SIGN_BIAS;\n\t\t\tix &= 0x7fffffff;\n\t\t}\n\t\tif (ix < 0x00800000) {\n\t\t\t/* Normalize subnormal x so exponent becomes negative.  */\n\t\t\tix = asuint(x * 0x1p23f);\n\t\t\tix &= 0x7fffffff;\n\t\t\tix -= 23 << 23;\n\t\t}\n\t}\n\tdouble_t logx = log2_inline(ix);\n\tdouble_t ylogx = y * logx; /* cannot overflow, y is single prec.  */\n\tif (predict_false((asuint64(ylogx) >> 47 & 0xffff) >=\n\t\t\t  asuint64(126.0 * POWF_SCALE) >> 47)) {\n\t\t/* |y*log(x)| >= 126.  */\n\t\tif (ylogx > 0x1.fffffffd1d571p+6 * POWF_SCALE)\n\t\t\treturn __math_oflowf(sign_bias);\n\t\tif (ylogx <= -150.0 * POWF_SCALE)\n\t\t\treturn __math_uflowf(sign_bias);\n\t}\n\treturn exp2_inline(ylogx, sign_bias);\n}\n"
  },
  {
    "path": "user.libc/src/math/powf_data.c",
    "content": "/*\n * Data definition for powf.\n *\n * Copyright (c) 2017-2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n\n#include \"powf_data.h\"\n\nconst struct powf_log2_data __powf_log2_data = {\n  .tab = {\n  { 0x1.661ec79f8f3bep+0, -0x1.efec65b963019p-2 * POWF_SCALE },\n  { 0x1.571ed4aaf883dp+0, -0x1.b0b6832d4fca4p-2 * POWF_SCALE },\n  { 0x1.49539f0f010bp+0, -0x1.7418b0a1fb77bp-2 * POWF_SCALE },\n  { 0x1.3c995b0b80385p+0, -0x1.39de91a6dcf7bp-2 * POWF_SCALE },\n  { 0x1.30d190c8864a5p+0, -0x1.01d9bf3f2b631p-2 * POWF_SCALE },\n  { 0x1.25e227b0b8eap+0, -0x1.97c1d1b3b7afp-3 * POWF_SCALE },\n  { 0x1.1bb4a4a1a343fp+0, -0x1.2f9e393af3c9fp-3 * POWF_SCALE },\n  { 0x1.12358f08ae5bap+0, -0x1.960cbbf788d5cp-4 * POWF_SCALE },\n  { 0x1.0953f419900a7p+0, -0x1.a6f9db6475fcep-5 * POWF_SCALE },\n  { 0x1p+0, 0x0p+0 * POWF_SCALE },\n  { 0x1.e608cfd9a47acp-1, 0x1.338ca9f24f53dp-4 * POWF_SCALE },\n  { 0x1.ca4b31f026aap-1, 0x1.476a9543891bap-3 * POWF_SCALE },\n  { 0x1.b2036576afce6p-1, 0x1.e840b4ac4e4d2p-3 * POWF_SCALE },\n  { 0x1.9c2d163a1aa2dp-1, 0x1.40645f0c6651cp-2 * POWF_SCALE },\n  { 0x1.886e6037841edp-1, 0x1.88e9c2c1b9ff8p-2 * POWF_SCALE },\n  { 0x1.767dcf5534862p-1, 0x1.ce0a44eb17bccp-2 * POWF_SCALE },\n  },\n  .poly = {\n  0x1.27616c9496e0bp-2 * POWF_SCALE, -0x1.71969a075c67ap-2 * POWF_SCALE,\n  0x1.ec70a6ca7baddp-2 * POWF_SCALE, -0x1.7154748bef6c8p-1 * POWF_SCALE,\n  0x1.71547652ab82bp0 * POWF_SCALE,\n  }\n};\n"
  },
  {
    "path": "user.libc/src/math/powf_data.h",
    "content": "/*\n * Copyright (c) 2017-2018, Arm Limited.\n * SPDX-License-Identifier: MIT\n */\n#ifndef _POWF_DATA_H\n#define _POWF_DATA_H\n\n#include \"libm.h\"\n#include \"exp2f_data.h\"\n\n#define POWF_LOG2_TABLE_BITS 4\n#define POWF_LOG2_POLY_ORDER 5\n#if TOINT_INTRINSICS\n#define POWF_SCALE_BITS EXP2F_TABLE_BITS\n#else\n#define POWF_SCALE_BITS 0\n#endif\n#define POWF_SCALE ((double)(1 << POWF_SCALE_BITS))\nextern hidden const struct powf_log2_data {\n\tstruct {\n\t\tdouble invc, logc;\n\t} tab[1 << POWF_LOG2_TABLE_BITS];\n\tdouble poly[POWF_LOG2_POLY_ORDER];\n} __powf_log2_data;\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/powl.c",
    "content": "/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_powl.c */\n/*\n * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n/*                                                      powl.c\n *\n *      Power function, long double precision\n *\n *\n * SYNOPSIS:\n *\n * long double x, y, z, powl();\n *\n * z = powl( x, y );\n *\n *\n * DESCRIPTION:\n *\n * Computes x raised to the yth power.  Analytically,\n *\n *      x**y  =  exp( y log(x) ).\n *\n * Following Cody and Waite, this program uses a lookup table\n * of 2**-i/32 and pseudo extended precision arithmetic to\n * obtain several extra bits of accuracy in both the logarithm\n * and the exponential.\n *\n *\n * ACCURACY:\n *\n * The relative error of pow(x,y) can be estimated\n * by   y dl ln(2),   where dl is the absolute error of\n * the internally computed base 2 logarithm.  At the ends\n * of the approximation interval the logarithm equal 1/32\n * and its relative error is about 1 lsb = 1.1e-19.  Hence\n * the predicted relative error in the result is 2.3e-21 y .\n *\n *                      Relative error:\n * arithmetic   domain     # trials      peak         rms\n *\n *    IEEE     +-1000       40000      2.8e-18      3.7e-19\n * .001 < x < 1000, with log(x) uniformly distributed.\n * -1000 < y < 1000, y uniformly distributed.\n *\n *    IEEE     0,8700       60000      6.5e-18      1.0e-18\n * 0.99 < x < 1.01, 0 < y < 8700, uniformly distributed.\n *\n *\n * ERROR MESSAGES:\n *\n *   message         condition      value returned\n * pow overflow     x**y > MAXNUM      INFINITY\n * pow underflow   x**y < 1/MAXNUM       0.0\n * pow domain      x<0 and y noninteger  0.0\n *\n */\n\n#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double powl(long double x, long double y)\n{\n\treturn pow(x, y);\n}\n#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384\n\n/* Table size */\n#define NXT 32\n\n/* log(1+x) =  x - .5x^2 + x^3 *  P(z)/Q(z)\n * on the domain  2^(-1/32) - 1  <=  x  <=  2^(1/32) - 1\n */\nstatic const long double P[] = {\n 8.3319510773868690346226E-4L,\n 4.9000050881978028599627E-1L,\n 1.7500123722550302671919E0L,\n 1.4000100839971580279335E0L,\n};\nstatic const long double Q[] = {\n/* 1.0000000000000000000000E0L,*/\n 5.2500282295834889175431E0L,\n 8.4000598057587009834666E0L,\n 4.2000302519914740834728E0L,\n};\n/* A[i] = 2^(-i/32), rounded to IEEE long double precision.\n * If i is even, A[i] + B[i/2] gives additional accuracy.\n */\nstatic const long double A[33] = {\n 1.0000000000000000000000E0L,\n 9.7857206208770013448287E-1L,\n 9.5760328069857364691013E-1L,\n 9.3708381705514995065011E-1L,\n 9.1700404320467123175367E-1L,\n 8.9735453750155359320742E-1L,\n 8.7812608018664974155474E-1L,\n 8.5930964906123895780165E-1L,\n 8.4089641525371454301892E-1L,\n 8.2287773907698242225554E-1L,\n 8.0524516597462715409607E-1L,\n 7.8799042255394324325455E-1L,\n 7.7110541270397041179298E-1L,\n 7.5458221379671136985669E-1L,\n 7.3841307296974965571198E-1L,\n 7.2259040348852331001267E-1L,\n 7.0710678118654752438189E-1L,\n 6.9195494098191597746178E-1L,\n 6.7712777346844636413344E-1L,\n 6.6261832157987064729696E-1L,\n 6.4841977732550483296079E-1L,\n 6.3452547859586661129850E-1L,\n 6.2092890603674202431705E-1L,\n 6.0762367999023443907803E-1L,\n 5.9460355750136053334378E-1L,\n 5.8186242938878875689693E-1L,\n 5.6939431737834582684856E-1L,\n 5.5719337129794626814472E-1L,\n 5.4525386633262882960438E-1L,\n 5.3357020033841180906486E-1L,\n 5.2213689121370692017331E-1L,\n 5.1094857432705833910408E-1L,\n 5.0000000000000000000000E-1L,\n};\nstatic const long double B[17] = {\n 0.0000000000000000000000E0L,\n 2.6176170809902549338711E-20L,\n-1.0126791927256478897086E-20L,\n 1.3438228172316276937655E-21L,\n 1.2207982955417546912101E-20L,\n-6.3084814358060867200133E-21L,\n 1.3164426894366316434230E-20L,\n-1.8527916071632873716786E-20L,\n 1.8950325588932570796551E-20L,\n 1.5564775779538780478155E-20L,\n 6.0859793637556860974380E-21L,\n-2.0208749253662532228949E-20L,\n 1.4966292219224761844552E-20L,\n 3.3540909728056476875639E-21L,\n-8.6987564101742849540743E-22L,\n-1.2327176863327626135542E-20L,\n 0.0000000000000000000000E0L,\n};\n\n/* 2^x = 1 + x P(x),\n * on the interval -1/32 <= x <= 0\n */\nstatic const long double R[] = {\n 1.5089970579127659901157E-5L,\n 1.5402715328927013076125E-4L,\n 1.3333556028915671091390E-3L,\n 9.6181291046036762031786E-3L,\n 5.5504108664798463044015E-2L,\n 2.4022650695910062854352E-1L,\n 6.9314718055994530931447E-1L,\n};\n\n#define MEXP (NXT*16384.0L)\n/* The following if denormal numbers are supported, else -MEXP: */\n#define MNEXP (-NXT*(16384.0L+64.0L))\n/* log2(e) - 1 */\n#define LOG2EA 0.44269504088896340735992L\n\n#define F W\n#define Fa Wa\n#define Fb Wb\n#define G W\n#define Ga Wa\n#define Gb u\n#define H W\n#define Ha Wb\n#define Hb Wb\n\nstatic const long double MAXLOGL = 1.1356523406294143949492E4L;\nstatic const long double MINLOGL = -1.13994985314888605586758E4L;\nstatic const long double LOGE2L = 6.9314718055994530941723E-1L;\nstatic const long double huge = 0x1p10000L;\n/* XXX Prevent gcc from erroneously constant folding this. */\nstatic const volatile long double twom10000 = 0x1p-10000L;\n\nstatic long double reducl(long double);\nstatic long double powil(long double, int);\n\nlong double powl(long double x, long double y)\n{\n\t/* double F, Fa, Fb, G, Ga, Gb, H, Ha, Hb */\n\tint i, nflg, iyflg, yoddint;\n\tlong e;\n\tvolatile long double z=0;\n\tlong double w=0, W=0, Wa=0, Wb=0, ya=0, yb=0, u=0;\n\n\t/* make sure no invalid exception is raised by nan comparision */\n\tif (isnan(x)) {\n\t\tif (!isnan(y) && y == 0.0)\n\t\t\treturn 1.0;\n\t\treturn x;\n\t}\n\tif (isnan(y)) {\n\t\tif (x == 1.0)\n\t\t\treturn 1.0;\n\t\treturn y;\n\t}\n\tif (x == 1.0)\n\t\treturn 1.0; /* 1**y = 1, even if y is nan */\n\tif (x == -1.0 && !isfinite(y))\n\t\treturn 1.0; /* -1**inf = 1 */\n\tif (y == 0.0)\n\t\treturn 1.0; /* x**0 = 1, even if x is nan */\n\tif (y == 1.0)\n\t\treturn x;\n\tif (y >= LDBL_MAX) {\n\t\tif (x > 1.0 || x < -1.0)\n\t\t\treturn INFINITY;\n\t\tif (x != 0.0)\n\t\t\treturn 0.0;\n\t}\n\tif (y <= -LDBL_MAX) {\n\t\tif (x > 1.0 || x < -1.0)\n\t\t\treturn 0.0;\n\t\tif (x != 0.0 || y == -INFINITY)\n\t\t\treturn INFINITY;\n\t}\n\tif (x >= LDBL_MAX) {\n\t\tif (y > 0.0)\n\t\t\treturn INFINITY;\n\t\treturn 0.0;\n\t}\n\n\tw = floorl(y);\n\n\t/* Set iyflg to 1 if y is an integer. */\n\tiyflg = 0;\n\tif (w == y)\n\t\tiyflg = 1;\n\n\t/* Test for odd integer y. */\n\tyoddint = 0;\n\tif (iyflg) {\n\t\tya = fabsl(y);\n\t\tya = floorl(0.5 * ya);\n\t\tyb = 0.5 * fabsl(w);\n\t\tif( ya != yb )\n\t\t\tyoddint = 1;\n\t}\n\n\tif (x <= -LDBL_MAX) {\n\t\tif (y > 0.0) {\n\t\t\tif (yoddint)\n\t\t\t\treturn -INFINITY;\n\t\t\treturn INFINITY;\n\t\t}\n\t\tif (y < 0.0) {\n\t\t\tif (yoddint)\n\t\t\t\treturn -0.0;\n\t\t\treturn 0.0;\n\t\t}\n\t}\n\tnflg = 0; /* (x<0)**(odd int) */\n\tif (x <= 0.0) {\n\t\tif (x == 0.0) {\n\t\t\tif (y < 0.0) {\n\t\t\t\tif (signbit(x) && yoddint)\n\t\t\t\t\t/* (-0.0)**(-odd int) = -inf, divbyzero */\n\t\t\t\t\treturn -1.0/0.0;\n\t\t\t\t/* (+-0.0)**(negative) = inf, divbyzero */\n\t\t\t\treturn 1.0/0.0;\n\t\t\t}\n\t\t\tif (signbit(x) && yoddint)\n\t\t\t\treturn -0.0;\n\t\t\treturn 0.0;\n\t\t}\n\t\tif (iyflg == 0)\n\t\t\treturn (x - x) / (x - x); /* (x<0)**(non-int) is NaN */\n\t\t/* (x<0)**(integer) */\n\t\tif (yoddint)\n\t\t\tnflg = 1; /* negate result */\n\t\tx = -x;\n\t}\n\t/* (+integer)**(integer)  */\n\tif (iyflg && floorl(x) == x && fabsl(y) < 32768.0) {\n\t\tw = powil(x, (int)y);\n\t\treturn nflg ? -w : w;\n\t}\n\n\t/* separate significand from exponent */\n\tx = frexpl(x, &i);\n\te = i;\n\n\t/* find significand in antilog table A[] */\n\ti = 1;\n\tif (x <= A[17])\n\t\ti = 17;\n\tif (x <= A[i+8])\n\t\ti += 8;\n\tif (x <= A[i+4])\n\t\ti += 4;\n\tif (x <= A[i+2])\n\t\ti += 2;\n\tif (x >= A[1])\n\t\ti = -1;\n\ti += 1;\n\n\t/* Find (x - A[i])/A[i]\n\t * in order to compute log(x/A[i]):\n\t *\n\t * log(x) = log( a x/a ) = log(a) + log(x/a)\n\t *\n\t * log(x/a) = log(1+v),  v = x/a - 1 = (x-a)/a\n\t */\n\tx -= A[i];\n\tx -= B[i/2];\n\tx /= A[i];\n\n\t/* rational approximation for log(1+v):\n\t *\n\t * log(1+v)  =  v  -  v**2/2  +  v**3 P(v) / Q(v)\n\t */\n\tz = x*x;\n\tw = x * (z * __polevll(x, P, 3) / __p1evll(x, Q, 3));\n\tw = w - 0.5*z;\n\n\t/* Convert to base 2 logarithm:\n\t * multiply by log2(e) = 1 + LOG2EA\n\t */\n\tz = LOG2EA * w;\n\tz += w;\n\tz += LOG2EA * x;\n\tz += x;\n\n\t/* Compute exponent term of the base 2 logarithm. */\n\tw = -i;\n\tw /= NXT;\n\tw += e;\n\t/* Now base 2 log of x is w + z. */\n\n\t/* Multiply base 2 log by y, in extended precision. */\n\n\t/* separate y into large part ya\n\t * and small part yb less than 1/NXT\n\t */\n\tya = reducl(y);\n\tyb = y - ya;\n\n\t/* (w+z)(ya+yb)\n\t * = w*ya + w*yb + z*y\n\t */\n\tF = z * y  +  w * yb;\n\tFa = reducl(F);\n\tFb = F - Fa;\n\n\tG = Fa + w * ya;\n\tGa = reducl(G);\n\tGb = G - Ga;\n\n\tH = Fb + Gb;\n\tHa = reducl(H);\n\tw = (Ga + Ha) * NXT;\n\n\t/* Test the power of 2 for overflow */\n\tif (w > MEXP)\n\t\treturn huge * huge;  /* overflow */\n\tif (w < MNEXP)\n\t\treturn twom10000 * twom10000;  /* underflow */\n\n\te = w;\n\tHb = H - Ha;\n\n\tif (Hb > 0.0) {\n\t\te += 1;\n\t\tHb -= 1.0/NXT;  /*0.0625L;*/\n\t}\n\n\t/* Now the product y * log2(x)  =  Hb + e/NXT.\n\t *\n\t * Compute base 2 exponential of Hb,\n\t * where -0.0625 <= Hb <= 0.\n\t */\n\tz = Hb * __polevll(Hb, R, 6);  /*  z = 2**Hb - 1  */\n\n\t/* Express e/NXT as an integer plus a negative number of (1/NXT)ths.\n\t * Find lookup table entry for the fractional power of 2.\n\t */\n\tif (e < 0)\n\t\ti = 0;\n\telse\n\t\ti = 1;\n\ti = e/NXT + i;\n\te = NXT*i - e;\n\tw = A[e];\n\tz = w * z;  /*  2**-e * ( 1 + (2**Hb-1) )  */\n\tz = z + w;\n\tz = scalbnl(z, i);  /* multiply by integer power of 2 */\n\n\tif (nflg)\n\t\tz = -z;\n\treturn z;\n}\n\n\n/* Find a multiple of 1/NXT that is within 1/NXT of x. */\nstatic long double reducl(long double x)\n{\n\tlong double t;\n\n\tt = x * NXT;\n\tt = floorl(t);\n\tt = t / NXT;\n\treturn t;\n}\n\n/*\n *      Positive real raised to integer power, long double precision\n *\n *\n * SYNOPSIS:\n *\n * long double x, y, powil();\n * int n;\n *\n * y = powil( x, n );\n *\n *\n * DESCRIPTION:\n *\n * Returns argument x>0 raised to the nth power.\n * The routine efficiently decomposes n as a sum of powers of\n * two. The desired power is a product of two-to-the-kth\n * powers of x.  Thus to compute the 32767 power of x requires\n * 28 multiplications instead of 32767 multiplications.\n *\n *\n * ACCURACY:\n *\n *                      Relative error:\n * arithmetic   x domain   n domain  # trials      peak         rms\n *    IEEE     .001,1000  -1022,1023  50000       4.3e-17     7.8e-18\n *    IEEE        1,2     -1022,1023  20000       3.9e-17     7.6e-18\n *    IEEE     .99,1.01     0,8700    10000       3.6e-16     7.2e-17\n *\n * Returns MAXNUM on overflow, zero on underflow.\n */\n\nstatic long double powil(long double x, int nn)\n{\n\tlong double ww, y;\n\tlong double s;\n\tint n, e, sign, lx;\n\n\tif (nn == 0)\n\t\treturn 1.0;\n\n\tif (nn < 0) {\n\t\tsign = -1;\n\t\tn = -nn;\n\t} else {\n\t\tsign = 1;\n\t\tn = nn;\n\t}\n\n\t/* Overflow detection */\n\n\t/* Calculate approximate logarithm of answer */\n\ts = x;\n\ts = frexpl( s, &lx);\n\te = (lx - 1)*n;\n\tif ((e == 0) || (e > 64) || (e < -64)) {\n\t\ts = (s - 7.0710678118654752e-1L) / (s +  7.0710678118654752e-1L);\n\t\ts = (2.9142135623730950L * s - 0.5 + lx) * nn * LOGE2L;\n\t} else {\n\t\ts = LOGE2L * e;\n\t}\n\n\tif (s > MAXLOGL)\n\t\treturn huge * huge;  /* overflow */\n\n\tif (s < MINLOGL)\n\t\treturn twom10000 * twom10000;  /* underflow */\n\t/* Handle tiny denormal answer, but with less accuracy\n\t * since roundoff error in 1.0/x will be amplified.\n\t * The precise demarcation should be the gradual underflow threshold.\n\t */\n\tif (s < -MAXLOGL+2.0) {\n\t\tx = 1.0/x;\n\t\tsign = -sign;\n\t}\n\n\t/* First bit of the power */\n\tif (n & 1)\n\t\ty = x;\n\telse\n\t\ty = 1.0;\n\n\tww = x;\n\tn >>= 1;\n\twhile (n) {\n\t\tww = ww * ww;   /* arg to the 2-to-the-kth power */\n\t\tif (n & 1)     /* if that bit is set, then include in product */\n\t\t\ty *= ww;\n\t\tn >>= 1;\n\t}\n\n\tif (sign < 0)\n\t\ty = 1.0/y;\n\treturn y;\n}\n#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384\n// TODO: broken implementation to make things compile\nlong double powl(long double x, long double y)\n{\n\treturn pow(x, y);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/remainder.c",
    "content": "#include <math.h>\n\ndouble remainder(double x, double y)\n{\n\tint q;\n\treturn remquo(x, y, &q);\n}\n\nweak_alias(remainder, drem);\n"
  },
  {
    "path": "user.libc/src/math/remainderf.c",
    "content": "#include <math.h>\n\nfloat remainderf(float x, float y)\n{\n\tint q;\n\treturn remquof(x, y, &q);\n}\n\nweak_alias(remainderf, dremf);\n"
  },
  {
    "path": "user.libc/src/math/remainderl.c",
    "content": "#include <math.h>\n#include <float.h>\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double remainderl(long double x, long double y)\n{\n\treturn remainder(x, y);\n}\n#else\nlong double remainderl(long double x, long double y)\n{\n\tint q;\n\treturn remquol(x, y, &q);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/remquo.c",
    "content": "#include <math.h>\n#include <stdint.h>\n\ndouble remquo(double x, double y, int *quo)\n{\n\tunion {double f; uint64_t i;} ux = {x}, uy = {y};\n\tint ex = ux.i>>52 & 0x7ff;\n\tint ey = uy.i>>52 & 0x7ff;\n\tint sx = ux.i>>63;\n\tint sy = uy.i>>63;\n\tuint32_t q;\n\tuint64_t i;\n\tuint64_t uxi = ux.i;\n\n\t*quo = 0;\n\tif (uy.i<<1 == 0 || isnan(y) || ex == 0x7ff)\n\t\treturn (x*y)/(x*y);\n\tif (ux.i<<1 == 0)\n\t\treturn x;\n\n\t/* normalize x and y */\n\tif (!ex) {\n\t\tfor (i = uxi<<12; i>>63 == 0; ex--, i <<= 1);\n\t\tuxi <<= -ex + 1;\n\t} else {\n\t\tuxi &= -1ULL >> 12;\n\t\tuxi |= 1ULL << 52;\n\t}\n\tif (!ey) {\n\t\tfor (i = uy.i<<12; i>>63 == 0; ey--, i <<= 1);\n\t\tuy.i <<= -ey + 1;\n\t} else {\n\t\tuy.i &= -1ULL >> 12;\n\t\tuy.i |= 1ULL << 52;\n\t}\n\n\tq = 0;\n\tif (ex < ey) {\n\t\tif (ex+1 == ey)\n\t\t\tgoto end;\n\t\treturn x;\n\t}\n\n\t/* x mod y */\n\tfor (; ex > ey; ex--) {\n\t\ti = uxi - uy.i;\n\t\tif (i >> 63 == 0) {\n\t\t\tuxi = i;\n\t\t\tq++;\n\t\t}\n\t\tuxi <<= 1;\n\t\tq <<= 1;\n\t}\n\ti = uxi - uy.i;\n\tif (i >> 63 == 0) {\n\t\tuxi = i;\n\t\tq++;\n\t}\n\tif (uxi == 0)\n\t\tex = -60;\n\telse\n\t\tfor (; uxi>>52 == 0; uxi <<= 1, ex--);\nend:\n\t/* scale result and decide between |x| and |x|-|y| */\n\tif (ex > 0) {\n\t\tuxi -= 1ULL << 52;\n\t\tuxi |= (uint64_t)ex << 52;\n\t} else {\n\t\tuxi >>= -ex + 1;\n\t}\n\tux.i = uxi;\n\tx = ux.f;\n\tif (sy)\n\t\ty = -y;\n\tif (ex == ey || (ex+1 == ey && (2*x > y || (2*x == y && q%2)))) {\n\t\tx -= y;\n\t\tq++;\n\t}\n\tq &= 0x7fffffff;\n\t*quo = sx^sy ? -(int)q : (int)q;\n\treturn sx ? -x : x;\n}\n"
  },
  {
    "path": "user.libc/src/math/remquof.c",
    "content": "#include <math.h>\n#include <stdint.h>\n\nfloat remquof(float x, float y, int *quo)\n{\n\tunion {float f; uint32_t i;} ux = {x}, uy = {y};\n\tint ex = ux.i>>23 & 0xff;\n\tint ey = uy.i>>23 & 0xff;\n\tint sx = ux.i>>31;\n\tint sy = uy.i>>31;\n\tuint32_t q;\n\tuint32_t i;\n\tuint32_t uxi = ux.i;\n\n\t*quo = 0;\n\tif (uy.i<<1 == 0 || isnan(y) || ex == 0xff)\n\t\treturn (x*y)/(x*y);\n\tif (ux.i<<1 == 0)\n\t\treturn x;\n\n\t/* normalize x and y */\n\tif (!ex) {\n\t\tfor (i = uxi<<9; i>>31 == 0; ex--, i <<= 1);\n\t\tuxi <<= -ex + 1;\n\t} else {\n\t\tuxi &= -1U >> 9;\n\t\tuxi |= 1U << 23;\n\t}\n\tif (!ey) {\n\t\tfor (i = uy.i<<9; i>>31 == 0; ey--, i <<= 1);\n\t\tuy.i <<= -ey + 1;\n\t} else {\n\t\tuy.i &= -1U >> 9;\n\t\tuy.i |= 1U << 23;\n\t}\n\n\tq = 0;\n\tif (ex < ey) {\n\t\tif (ex+1 == ey)\n\t\t\tgoto end;\n\t\treturn x;\n\t}\n\n\t/* x mod y */\n\tfor (; ex > ey; ex--) {\n\t\ti = uxi - uy.i;\n\t\tif (i >> 31 == 0) {\n\t\t\tuxi = i;\n\t\t\tq++;\n\t\t}\n\t\tuxi <<= 1;\n\t\tq <<= 1;\n\t}\n\ti = uxi - uy.i;\n\tif (i >> 31 == 0) {\n\t\tuxi = i;\n\t\tq++;\n\t}\n\tif (uxi == 0)\n\t\tex = -30;\n\telse\n\t\tfor (; uxi>>23 == 0; uxi <<= 1, ex--);\nend:\n\t/* scale result and decide between |x| and |x|-|y| */\n\tif (ex > 0) {\n\t\tuxi -= 1U << 23;\n\t\tuxi |= (uint32_t)ex << 23;\n\t} else {\n\t\tuxi >>= -ex + 1;\n\t}\n\tux.i = uxi;\n\tx = ux.f;\n\tif (sy)\n\t\ty = -y;\n\tif (ex == ey || (ex+1 == ey && (2*x > y || (2*x == y && q%2)))) {\n\t\tx -= y;\n\t\tq++;\n\t}\n\tq &= 0x7fffffff;\n\t*quo = sx^sy ? -(int)q : (int)q;\n\treturn sx ? -x : x;\n}\n"
  },
  {
    "path": "user.libc/src/math/remquol.c",
    "content": "#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double remquol(long double x, long double y, int *quo)\n{\n\treturn remquo(x, y, quo);\n}\n#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\nlong double remquol(long double x, long double y, int *quo)\n{\n\tunion ldshape ux = {x}, uy = {y};\n\tint ex = ux.i.se & 0x7fff;\n\tint ey = uy.i.se & 0x7fff;\n\tint sx = ux.i.se >> 15;\n\tint sy = uy.i.se >> 15;\n\tuint32_t q;\n\n\t*quo = 0;\n\tif (y == 0 || isnan(y) || ex == 0x7fff)\n\t\treturn (x*y)/(x*y);\n\tif (x == 0)\n\t\treturn x;\n\n\t/* normalize x and y */\n\tif (!ex) {\n\t\tux.i.se = ex;\n\t\tux.f *= 0x1p120f;\n\t\tex = ux.i.se - 120;\n\t}\n\tif (!ey) {\n\t\tuy.i.se = ey;\n\t\tuy.f *= 0x1p120f;\n\t\tey = uy.i.se - 120;\n\t}\n\n\tq = 0;\n\tif (ex >= ey) {\n\t\t/* x mod y */\n#if LDBL_MANT_DIG == 64\n\t\tuint64_t i, mx, my;\n\t\tmx = ux.i.m;\n\t\tmy = uy.i.m;\n\t\tfor (; ex > ey; ex--) {\n\t\t\ti = mx - my;\n\t\t\tif (mx >= my) {\n\t\t\t\tmx = 2*i;\n\t\t\t\tq++;\n\t\t\t\tq <<= 1;\n\t\t\t} else if (2*mx < mx) {\n\t\t\t\tmx = 2*mx - my;\n\t\t\t\tq <<= 1;\n\t\t\t\tq++;\n\t\t\t} else {\n\t\t\t\tmx = 2*mx;\n\t\t\t\tq <<= 1;\n\t\t\t}\n\t\t}\n\t\ti = mx - my;\n\t\tif (mx >= my) {\n\t\t\tmx = i;\n\t\t\tq++;\n\t\t}\n\t\tif (mx == 0)\n\t\t\tex = -120;\n\t\telse\n\t\t\tfor (; mx >> 63 == 0; mx *= 2, ex--);\n\t\tux.i.m = mx;\n#elif LDBL_MANT_DIG == 113\n\t\tuint64_t hi, lo, xhi, xlo, yhi, ylo;\n\t\txhi = (ux.i2.hi & -1ULL>>16) | 1ULL<<48;\n\t\tyhi = (uy.i2.hi & -1ULL>>16) | 1ULL<<48;\n\t\txlo = ux.i2.lo;\n\t\tylo = ux.i2.lo;\n\t\tfor (; ex > ey; ex--) {\n\t\t\thi = xhi - yhi;\n\t\t\tlo = xlo - ylo;\n\t\t\tif (xlo < ylo)\n\t\t\t\thi -= 1;\n\t\t\tif (hi >> 63 == 0) {\n\t\t\t\txhi = 2*hi + (lo>>63);\n\t\t\t\txlo = 2*lo;\n\t\t\t\tq++;\n\t\t\t} else {\n\t\t\t\txhi = 2*xhi + (xlo>>63);\n\t\t\t\txlo = 2*xlo;\n\t\t\t}\n\t\t\tq <<= 1;\n\t\t}\n\t\thi = xhi - yhi;\n\t\tlo = xlo - ylo;\n\t\tif (xlo < ylo)\n\t\t\thi -= 1;\n\t\tif (hi >> 63 == 0) {\n\t\t\txhi = hi;\n\t\t\txlo = lo;\n\t\t\tq++;\n\t\t}\n\t\tif ((xhi|xlo) == 0)\n\t\t\tex = -120;\n\t\telse\n\t\t\tfor (; xhi >> 48 == 0; xhi = 2*xhi + (xlo>>63), xlo = 2*xlo, ex--);\n\t\tux.i2.hi = xhi;\n\t\tux.i2.lo = xlo;\n#endif\n\t}\n\n\t/* scale result and decide between |x| and |x|-|y| */\n\tif (ex <= 0) {\n\t\tux.i.se = ex + 120;\n\t\tux.f *= 0x1p-120f;\n\t} else\n\t\tux.i.se = ex;\n\tx = ux.f;\n\tif (sy)\n\t\ty = -y;\n\tif (ex == ey || (ex+1 == ey && (2*x > y || (2*x == y && q%2)))) {\n\t\tx -= y;\n\t\tq++;\n\t}\n\tq &= 0x7fffffff;\n\t*quo = sx^sy ? -(int)q : (int)q;\n\treturn sx ? -x : x;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/rint.c",
    "content": "#include <float.h>\n#include <math.h>\n#include <stdint.h>\n\n#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1\n#define EPS DBL_EPSILON\n#elif FLT_EVAL_METHOD==2\n#define EPS LDBL_EPSILON\n#endif\nstatic const double_t toint = 1/EPS;\n\ndouble rint(double x)\n{\n\tunion {double f; uint64_t i;} u = {x};\n\tint e = u.i>>52 & 0x7ff;\n\tint s = u.i>>63;\n\tdouble_t y;\n\n\tif (e >= 0x3ff+52)\n\t\treturn x;\n\tif (s)\n\t\ty = x - toint + toint;\n\telse\n\t\ty = x + toint - toint;\n\tif (y == 0)\n\t\treturn s ? -0.0 : 0;\n\treturn y;\n}\n"
  },
  {
    "path": "user.libc/src/math/rintf.c",
    "content": "#include <float.h>\n#include <math.h>\n#include <stdint.h>\n\n#if FLT_EVAL_METHOD==0\n#define EPS FLT_EPSILON\n#elif FLT_EVAL_METHOD==1\n#define EPS DBL_EPSILON\n#elif FLT_EVAL_METHOD==2\n#define EPS LDBL_EPSILON\n#endif\nstatic const float_t toint = 1/EPS;\n\nfloat rintf(float x)\n{\n\tunion {float f; uint32_t i;} u = {x};\n\tint e = u.i>>23 & 0xff;\n\tint s = u.i>>31;\n\tfloat_t y;\n\n\tif (e >= 0x7f+23)\n\t\treturn x;\n\tif (s)\n\t\ty = x - toint + toint;\n\telse\n\t\ty = x + toint - toint;\n\tif (y == 0)\n\t\treturn s ? -0.0f : 0.0f;\n\treturn y;\n}\n"
  },
  {
    "path": "user.libc/src/math/rintl.c",
    "content": "#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double rintl(long double x)\n{\n\treturn rint(x);\n}\n#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\n\nstatic const long double toint = 1/LDBL_EPSILON;\n\nlong double rintl(long double x)\n{\n\tunion ldshape u = {x};\n\tint e = u.i.se & 0x7fff;\n\tint s = u.i.se >> 15;\n\tlong double y;\n\n\tif (e >= 0x3fff+LDBL_MANT_DIG-1)\n\t\treturn x;\n\tif (s)\n\t\ty = x - toint + toint;\n\telse\n\t\ty = x + toint - toint;\n\tif (y == 0)\n\t\treturn 0*x;\n\treturn y;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/riscv64/copysign.c",
    "content": "#include <math.h>\n\n#if __riscv_flen >= 64\n\ndouble copysign(double x, double y)\n{\n\t__asm__ (\"fsgnj.d %0, %1, %2\" : \"=f\"(x) : \"f\"(x), \"f\"(y));\n\treturn x;\n}\n\n#else\n\n#include \"../copysign.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/riscv64/copysignf.c",
    "content": "#include <math.h>\n\n#if __riscv_flen >= 32\n\nfloat copysignf(float x, float y)\n{\n\t__asm__ (\"fsgnj.s %0, %1, %2\" : \"=f\"(x) : \"f\"(x), \"f\"(y));\n\treturn x;\n}\n\n#else\n\n#include \"../copysignf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/riscv64/fabs.c",
    "content": "#include <math.h>\n\n#if __riscv_flen >= 64\n\ndouble fabs(double x)\n{\n\t__asm__ (\"fabs.d %0, %1\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../fabs.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/riscv64/fabsf.c",
    "content": "#include <math.h>\n\n#if __riscv_flen >= 32\n\nfloat fabsf(float x)\n{\n\t__asm__ (\"fabs.s %0, %1\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../fabsf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/riscv64/fma.c",
    "content": "#include <math.h>\n\n#if __riscv_flen >= 64\n\ndouble fma(double x, double y, double z)\n{\n\t__asm__ (\"fmadd.d %0, %1, %2, %3\" : \"=f\"(x) : \"f\"(x), \"f\"(y), \"f\"(z));\n\treturn x;\n}\n\n#else\n\n#include \"../fma.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/riscv64/fmaf.c",
    "content": "#include <math.h>\n\n#if __riscv_flen >= 32\n\nfloat fmaf(float x, float y, float z)\n{\n\t__asm__ (\"fmadd.s %0, %1, %2, %3\" : \"=f\"(x) : \"f\"(x), \"f\"(y), \"f\"(z));\n\treturn x;\n}\n\n#else\n\n#include \"../fmaf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/riscv64/fmax.c",
    "content": "#include <math.h>\n\n#if __riscv_flen >= 64\n\ndouble fmax(double x, double y)\n{\n\t__asm__ (\"fmax.d %0, %1, %2\" : \"=f\"(x) : \"f\"(x), \"f\"(y));\n\treturn x;\n}\n\n#else\n\n#include \"../fmax.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/riscv64/fmaxf.c",
    "content": "#include <math.h>\n\n#if __riscv_flen >= 32\n\nfloat fmaxf(float x, float y)\n{\n\t__asm__ (\"fmax.s %0, %1, %2\" : \"=f\"(x) : \"f\"(x), \"f\"(y));\n\treturn x;\n}\n\n#else\n\n#include \"../fmaxf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/riscv64/fmin.c",
    "content": "#include <math.h>\n\n#if __riscv_flen >= 64\n\ndouble fmin(double x, double y)\n{\n\t__asm__ (\"fmin.d %0, %1, %2\" : \"=f\"(x) : \"f\"(x), \"f\"(y));\n\treturn x;\n}\n\n#else\n\n#include \"../fmin.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/riscv64/fminf.c",
    "content": "#include <math.h>\n\n#if __riscv_flen >= 32\n\nfloat fminf(float x, float y)\n{\n\t__asm__ (\"fmin.s %0, %1, %2\" : \"=f\"(x) : \"f\"(x), \"f\"(y));\n\treturn x;\n}\n\n#else\n\n#include \"../fminf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/riscv64/sqrt.c",
    "content": "#include <math.h>\n\n#if __riscv_flen >= 64\n\ndouble sqrt(double x)\n{\n\t__asm__ (\"fsqrt.d %0, %1\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../sqrt.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/riscv64/sqrtf.c",
    "content": "#include <math.h>\n\n#if __riscv_flen >= 32\n\nfloat sqrtf(float x)\n{\n\t__asm__ (\"fsqrt.s %0, %1\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../sqrtf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/round.c",
    "content": "#include \"libm.h\"\n\n#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1\n#define EPS DBL_EPSILON\n#elif FLT_EVAL_METHOD==2\n#define EPS LDBL_EPSILON\n#endif\nstatic const double_t toint = 1/EPS;\n\ndouble round(double x)\n{\n\tunion {double f; uint64_t i;} u = {x};\n\tint e = u.i >> 52 & 0x7ff;\n\tdouble_t y;\n\n\tif (e >= 0x3ff+52)\n\t\treturn x;\n\tif (u.i >> 63)\n\t\tx = -x;\n\tif (e < 0x3ff-1) {\n\t\t/* raise inexact if x!=0 */\n\t\tFORCE_EVAL(x + toint);\n\t\treturn 0*u.f;\n\t}\n\ty = x + toint - toint - x;\n\tif (y > 0.5)\n\t\ty = y + x - 1;\n\telse if (y <= -0.5)\n\t\ty = y + x + 1;\n\telse\n\t\ty = y + x;\n\tif (u.i >> 63)\n\t\ty = -y;\n\treturn y;\n}\n"
  },
  {
    "path": "user.libc/src/math/roundf.c",
    "content": "#include \"libm.h\"\n\n#if FLT_EVAL_METHOD==0\n#define EPS FLT_EPSILON\n#elif FLT_EVAL_METHOD==1\n#define EPS DBL_EPSILON\n#elif FLT_EVAL_METHOD==2\n#define EPS LDBL_EPSILON\n#endif\nstatic const float_t toint = 1/EPS;\n\nfloat roundf(float x)\n{\n\tunion {float f; uint32_t i;} u = {x};\n\tint e = u.i >> 23 & 0xff;\n\tfloat_t y;\n\n\tif (e >= 0x7f+23)\n\t\treturn x;\n\tif (u.i >> 31)\n\t\tx = -x;\n\tif (e < 0x7f-1) {\n\t\tFORCE_EVAL(x + toint);\n\t\treturn 0*u.f;\n\t}\n\ty = x + toint - toint - x;\n\tif (y > 0.5f)\n\t\ty = y + x - 1;\n\telse if (y <= -0.5f)\n\t\ty = y + x + 1;\n\telse\n\t\ty = y + x;\n\tif (u.i >> 31)\n\t\ty = -y;\n\treturn y;\n}\n"
  },
  {
    "path": "user.libc/src/math/roundl.c",
    "content": "#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double roundl(long double x)\n{\n\treturn round(x);\n}\n#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\n\nstatic const long double toint = 1/LDBL_EPSILON;\n\nlong double roundl(long double x)\n{\n\tunion ldshape u = {x};\n\tint e = u.i.se & 0x7fff;\n\tlong double y;\n\n\tif (e >= 0x3fff+LDBL_MANT_DIG-1)\n\t\treturn x;\n\tif (u.i.se >> 15)\n\t\tx = -x;\n\tif (e < 0x3fff-1) {\n\t\tFORCE_EVAL(x + toint);\n\t\treturn 0*u.f;\n\t}\n\ty = x + toint - toint - x;\n\tif (y > 0.5)\n\t\ty = y + x - 1;\n\telse if (y <= -0.5)\n\t\ty = y + x + 1;\n\telse\n\t\ty = y + x;\n\tif (u.i.se >> 15)\n\t\ty = -y;\n\treturn y;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/s390x/ceil.c",
    "content": "#include <math.h>\n\n#if defined(__HTM__) || __ARCH__ >= 9\n\ndouble ceil(double x)\n{\n\t__asm__ (\"fidbra %0, 6, %1, 4\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../ceil.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/s390x/ceilf.c",
    "content": "#include <math.h>\n\n#if defined(__HTM__) || __ARCH__ >= 9\n\nfloat ceilf(float x)\n{\n\t__asm__ (\"fiebra %0, 6, %1, 4\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../ceilf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/s390x/ceill.c",
    "content": "#include <math.h>\n\n#if defined(__HTM__) || __ARCH__ >= 9\n\nlong double ceill(long double x)\n{\n\t__asm__ (\"fixbra %0, 6, %1, 4\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../ceill.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/s390x/fabs.c",
    "content": "#include <math.h>\n\n#if defined(__HTM__) || __ARCH__ >= 9\n\ndouble fabs(double x)\n{\n\t__asm__ (\"lpdbr %0, %1\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../fabs.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/s390x/fabsf.c",
    "content": "#include <math.h>\n\n#if defined(__HTM__) || __ARCH__ >= 9\n\nfloat fabsf(float x)\n{\n\t__asm__ (\"lpebr %0, %1\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../fabsf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/s390x/fabsl.c",
    "content": "#include <math.h>\n\n#if defined(__HTM__) || __ARCH__ >= 9\n\nlong double fabsl(long double x)\n{\n\t__asm__ (\"lpxbr %0, %1\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../fabsl.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/s390x/floor.c",
    "content": "#include <math.h>\n\n#if defined(__HTM__) || __ARCH__ >= 9\n\ndouble floor(double x)\n{\n\t__asm__ (\"fidbra %0, 7, %1, 4\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../floor.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/s390x/floorf.c",
    "content": "#include <math.h>\n\n#if defined(__HTM__) || __ARCH__ >= 9\n\nfloat floorf(float x)\n{\n\t__asm__ (\"fiebra %0, 7, %1, 4\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../floorf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/s390x/floorl.c",
    "content": "#include <math.h>\n\n#if defined(__HTM__) || __ARCH__ >= 9\n\nlong double floorl(long double x)\n{\n\t__asm__ (\"fixbra %0, 7, %1, 4\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../floorl.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/s390x/fma.c",
    "content": "#include <math.h>\n\ndouble fma(double x, double y, double z)\n{\n\t__asm__ (\"madbr %0, %1, %2\" : \"+f\"(z) : \"f\"(x), \"f\"(y));\n\treturn z;\n}\n"
  },
  {
    "path": "user.libc/src/math/s390x/fmaf.c",
    "content": "#include <math.h>\n\nfloat fmaf(float x, float y, float z)\n{\n\t__asm__ (\"maebr %0, %1, %2\" : \"+f\"(z) : \"f\"(x), \"f\"(y));\n\treturn z;\n}\n"
  },
  {
    "path": "user.libc/src/math/s390x/nearbyint.c",
    "content": "#include <math.h>\n\n#if defined(__HTM__) || __ARCH__ >= 9\n\ndouble nearbyint(double x)\n{\n\t__asm__ (\"fidbra %0, 0, %1, 4\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../nearbyint.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/s390x/nearbyintf.c",
    "content": "#include <math.h>\n\n#if defined(__HTM__) || __ARCH__ >= 9\n\nfloat nearbyintf(float x)\n{\n\t__asm__ (\"fiebra %0, 0, %1, 4\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../nearbyintf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/s390x/nearbyintl.c",
    "content": "#include <math.h>\n\n#if defined(__HTM__) || __ARCH__ >= 9\n\nlong double nearbyintl(long double x)\n{\n\t__asm__ (\"fixbra %0, 0, %1, 4\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../nearbyintl.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/s390x/rint.c",
    "content": "#include <math.h>\n\n#if defined(__HTM__) || __ARCH__ >= 9\n\ndouble rint(double x)\n{\n\t__asm__ (\"fidbr %0, 0, %1\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../rint.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/s390x/rintf.c",
    "content": "#include <math.h>\n\n#if defined(__HTM__) || __ARCH__ >= 9\n\nfloat rintf(float x)\n{\n\t__asm__ (\"fiebr %0, 0, %1\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../rintf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/s390x/rintl.c",
    "content": "#include <math.h>\n\n#if defined(__HTM__) || __ARCH__ >= 9\n\nlong double rintl(long double x)\n{\n\t__asm__ (\"fixbr %0, 0, %1\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../rintl.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/s390x/round.c",
    "content": "#include <math.h>\n\n#if defined(__HTM__) || __ARCH__ >= 9\n\ndouble round(double x)\n{\n\t__asm__ (\"fidbra %0, 1, %1, 4\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../round.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/s390x/roundf.c",
    "content": "#include <math.h>\n\n#if defined(__HTM__) || __ARCH__ >= 9\n\nfloat roundf(float x)\n{\n\t__asm__ (\"fiebra %0, 1, %1, 4\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../roundf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/s390x/roundl.c",
    "content": "#include <math.h>\n\n#if defined(__HTM__) || __ARCH__ >= 9\n\nlong double roundl(long double x)\n{\n\t__asm__ (\"fixbra %0, 1, %1, 4\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../roundl.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/s390x/sqrt.c",
    "content": "#include <math.h>\n\n#if defined(__HTM__) || __ARCH__ >= 9\n\ndouble sqrt(double x)\n{\n\t__asm__ (\"sqdbr %0, %1\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../sqrt.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/s390x/sqrtf.c",
    "content": "#include <math.h>\n\n#if defined(__HTM__) || __ARCH__ >= 9\n\nfloat sqrtf(float x)\n{\n\t__asm__ (\"sqebr %0, %1\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../sqrtf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/s390x/sqrtl.c",
    "content": "#include <math.h>\n\n#if defined(__HTM__) || __ARCH__ >= 9\n\nlong double sqrtl(long double x)\n{\n\t__asm__ (\"sqxbr %0, %1\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../sqrtl.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/s390x/trunc.c",
    "content": "#include <math.h>\n\n#if defined(__HTM__) || __ARCH__ >= 9\n\ndouble trunc(double x)\n{\n\t__asm__ (\"fidbra %0, 5, %1, 4\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../trunc.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/s390x/truncf.c",
    "content": "#include <math.h>\n\n#if defined(__HTM__) || __ARCH__ >= 9\n\nfloat truncf(float x)\n{\n\t__asm__ (\"fiebra %0, 5, %1, 4\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../truncf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/s390x/truncl.c",
    "content": "#include <math.h>\n\n#if defined(__HTM__) || __ARCH__ >= 9\n\nlong double truncl(long double x)\n{\n\t__asm__ (\"fixbra %0, 5, %1, 4\" : \"=f\"(x) : \"f\"(x));\n\treturn x;\n}\n\n#else\n\n#include \"../truncl.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/scalb.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/e_scalb.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunSoft, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/*\n * scalb(x, fn) is provide for\n * passing various standard test suite. One\n * should use scalbn() instead.\n */\n\n#define _GNU_SOURCE\n#include <math.h>\n\ndouble scalb(double x, double fn)\n{\n\tif (isnan(x) || isnan(fn))\n\t\treturn x*fn;\n\tif (!isfinite(fn)) {\n\t\tif (fn > 0.0)\n\t\t\treturn x*fn;\n\t\telse\n\t\t\treturn x/(-fn);\n\t}\n\tif (rint(fn) != fn) return (fn-fn)/(fn-fn);\n\tif ( fn > 65000.0) return scalbn(x, 65000);\n\tif (-fn > 65000.0) return scalbn(x,-65000);\n\treturn scalbn(x,(int)fn);\n}\n"
  },
  {
    "path": "user.libc/src/math/scalbf.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/e_scalbf.c */\n/*\n * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.\n */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n\n#define _GNU_SOURCE\n#include <math.h>\n\nfloat scalbf(float x, float fn)\n{\n\tif (isnan(x) || isnan(fn)) return x*fn;\n\tif (!isfinite(fn)) {\n\t\tif (fn > 0.0f)\n\t\t\treturn x*fn;\n\t\telse\n\t\t\treturn x/(-fn);\n\t}\n\tif (rintf(fn) != fn) return (fn-fn)/(fn-fn);\n\tif ( fn > 65000.0f) return scalbnf(x, 65000);\n\tif (-fn > 65000.0f) return scalbnf(x,-65000);\n\treturn scalbnf(x,(int)fn);\n}\n"
  },
  {
    "path": "user.libc/src/math/scalbln.c",
    "content": "#include <limits.h>\n#include <math.h>\n\ndouble scalbln(double x, long n)\n{\n\tif (n > INT_MAX)\n\t\tn = INT_MAX;\n\telse if (n < INT_MIN)\n\t\tn = INT_MIN;\n\treturn scalbn(x, n);\n}\n"
  },
  {
    "path": "user.libc/src/math/scalblnf.c",
    "content": "#include <limits.h>\n#include <math.h>\n\nfloat scalblnf(float x, long n)\n{\n\tif (n > INT_MAX)\n\t\tn = INT_MAX;\n\telse if (n < INT_MIN)\n\t\tn = INT_MIN;\n\treturn scalbnf(x, n);\n}\n"
  },
  {
    "path": "user.libc/src/math/scalblnl.c",
    "content": "#include <limits.h>\n#include <math.h>\n#include <float.h>\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double scalblnl(long double x, long n)\n{\n\treturn scalbln(x, n);\n}\n#else\nlong double scalblnl(long double x, long n)\n{\n\tif (n > INT_MAX)\n\t\tn = INT_MAX;\n\telse if (n < INT_MIN)\n\t\tn = INT_MIN;\n\treturn scalbnl(x, n);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/scalbn.c",
    "content": "#include <math.h>\n#include <stdint.h>\n\ndouble scalbn(double x, int n)\n{\n\tunion {double f; uint64_t i;} u;\n\tdouble_t y = x;\n\n\tif (n > 1023) {\n\t\ty *= 0x1p1023;\n\t\tn -= 1023;\n\t\tif (n > 1023) {\n\t\t\ty *= 0x1p1023;\n\t\t\tn -= 1023;\n\t\t\tif (n > 1023)\n\t\t\t\tn = 1023;\n\t\t}\n\t} else if (n < -1022) {\n\t\t/* make sure final n < -53 to avoid double\n\t\t   rounding in the subnormal range */\n\t\ty *= 0x1p-1022 * 0x1p53;\n\t\tn += 1022 - 53;\n\t\tif (n < -1022) {\n\t\t\ty *= 0x1p-1022 * 0x1p53;\n\t\t\tn += 1022 - 53;\n\t\t\tif (n < -1022)\n\t\t\t\tn = -1022;\n\t\t}\n\t}\n\tu.i = (uint64_t)(0x3ff+n)<<52;\n\tx = y * u.f;\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/scalbnf.c",
    "content": "#include <math.h>\n#include <stdint.h>\n\nfloat scalbnf(float x, int n)\n{\n\tunion {float f; uint32_t i;} u;\n\tfloat_t y = x;\n\n\tif (n > 127) {\n\t\ty *= 0x1p127f;\n\t\tn -= 127;\n\t\tif (n > 127) {\n\t\t\ty *= 0x1p127f;\n\t\t\tn -= 127;\n\t\t\tif (n > 127)\n\t\t\t\tn = 127;\n\t\t}\n\t} else if (n < -126) {\n\t\ty *= 0x1p-126f * 0x1p24f;\n\t\tn += 126 - 24;\n\t\tif (n < -126) {\n\t\t\ty *= 0x1p-126f * 0x1p24f;\n\t\t\tn += 126 - 24;\n\t\t\tif (n < -126)\n\t\t\t\tn = -126;\n\t\t}\n\t}\n\tu.i = (uint32_t)(0x7f+n)<<23;\n\tx = y * u.f;\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/scalbnl.c",
    "content": "#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double scalbnl(long double x, int n)\n{\n\treturn scalbn(x, n);\n}\n#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\nlong double scalbnl(long double x, int n)\n{\n\tunion ldshape u;\n\n\tif (n > 16383) {\n\t\tx *= 0x1p16383L;\n\t\tn -= 16383;\n\t\tif (n > 16383) {\n\t\t\tx *= 0x1p16383L;\n\t\t\tn -= 16383;\n\t\t\tif (n > 16383)\n\t\t\t\tn = 16383;\n\t\t}\n\t} else if (n < -16382) {\n\t\tx *= 0x1p-16382L * 0x1p113L;\n\t\tn += 16382 - 113;\n\t\tif (n < -16382) {\n\t\t\tx *= 0x1p-16382L * 0x1p113L;\n\t\t\tn += 16382 - 113;\n\t\t\tif (n < -16382)\n\t\t\t\tn = -16382;\n\t\t}\n\t}\n\tu.f = 1.0;\n\tu.i.se = 0x3fff + n;\n\treturn x * u.f;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/signgam.c",
    "content": "#include <math.h>\n#include \"libm.h\"\n\nint __signgam = 0;\n\nweak_alias(__signgam, signgam);\n"
  },
  {
    "path": "user.libc/src/math/significand.c",
    "content": "#define _GNU_SOURCE\n#include <math.h>\n\ndouble significand(double x)\n{\n\treturn scalbn(x, -ilogb(x));\n}\n"
  },
  {
    "path": "user.libc/src/math/significandf.c",
    "content": "#define _GNU_SOURCE\n#include <math.h>\n\nfloat significandf(float x)\n{\n\treturn scalbnf(x, -ilogbf(x));\n}\n"
  },
  {
    "path": "user.libc/src/math/sin.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_sin.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/* sin(x)\n * Return sine function of x.\n *\n * kernel function:\n *      __sin            ... sine function on [-pi/4,pi/4]\n *      __cos            ... cose function on [-pi/4,pi/4]\n *      __rem_pio2       ... argument reduction routine\n *\n * Method.\n *      Let S,C and T denote the sin, cos and tan respectively on\n *      [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2\n *      in [-pi/4 , +pi/4], and let n = k mod 4.\n *      We have\n *\n *          n        sin(x)      cos(x)        tan(x)\n *     ----------------------------------------------------------\n *          0          S           C             T\n *          1          C          -S            -1/T\n *          2         -S          -C             T\n *          3         -C           S            -1/T\n *     ----------------------------------------------------------\n *\n * Special cases:\n *      Let trig be any of sin, cos, or tan.\n *      trig(+-INF)  is NaN, with signals;\n *      trig(NaN)    is that NaN;\n *\n * Accuracy:\n *      TRIG(x) returns trig(x) nearly rounded\n */\n\n#include \"libm.h\"\n\ndouble sin(double x)\n{\n\tdouble y[2];\n\tuint32_t ix;\n\tunsigned n;\n\n\t/* High word of x. */\n\tGET_HIGH_WORD(ix, x);\n\tix &= 0x7fffffff;\n\n\t/* |x| ~< pi/4 */\n\tif (ix <= 0x3fe921fb) {\n\t\tif (ix < 0x3e500000) {  /* |x| < 2**-26 */\n\t\t\t/* raise inexact if x != 0 and underflow if subnormal*/\n\t\t\tFORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f);\n\t\t\treturn x;\n\t\t}\n\t\treturn __sin(x, 0.0, 0);\n\t}\n\n\t/* sin(Inf or NaN) is NaN */\n\tif (ix >= 0x7ff00000)\n\t\treturn x - x;\n\n\t/* argument reduction needed */\n\tn = __rem_pio2(x, y);\n\tswitch (n&3) {\n\tcase 0: return  __sin(y[0], y[1], 1);\n\tcase 1: return  __cos(y[0], y[1]);\n\tcase 2: return -__sin(y[0], y[1], 1);\n\tdefault:\n\t\treturn -__cos(y[0], y[1]);\n\t}\n}\n"
  },
  {
    "path": "user.libc/src/math/sincos.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_sin.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n\n#define _GNU_SOURCE\n#include \"libm.h\"\n\nvoid sincos(double x, double *sin, double *cos)\n{\n\tdouble y[2], s, c;\n\tuint32_t ix;\n\tunsigned n;\n\n\tGET_HIGH_WORD(ix, x);\n\tix &= 0x7fffffff;\n\n\t/* |x| ~< pi/4 */\n\tif (ix <= 0x3fe921fb) {\n\t\t/* if |x| < 2**-27 * sqrt(2) */\n\t\tif (ix < 0x3e46a09e) {\n\t\t\t/* raise inexact if x!=0 and underflow if subnormal */\n\t\t\tFORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f);\n\t\t\t*sin = x;\n\t\t\t*cos = 1.0;\n\t\t\treturn;\n\t\t}\n\t\t*sin = __sin(x, 0.0, 0);\n\t\t*cos = __cos(x, 0.0);\n\t\treturn;\n\t}\n\n\t/* sincos(Inf or NaN) is NaN */\n\tif (ix >= 0x7ff00000) {\n\t\t*sin = *cos = x - x;\n\t\treturn;\n\t}\n\n\t/* argument reduction needed */\n\tn = __rem_pio2(x, y);\n\ts = __sin(y[0], y[1], 1);\n\tc = __cos(y[0], y[1]);\n\tswitch (n&3) {\n\tcase 0:\n\t\t*sin = s;\n\t\t*cos = c;\n\t\tbreak;\n\tcase 1:\n\t\t*sin = c;\n\t\t*cos = -s;\n\t\tbreak;\n\tcase 2:\n\t\t*sin = -s;\n\t\t*cos = -c;\n\t\tbreak;\n\tcase 3:\n\tdefault:\n\t\t*sin = -c;\n\t\t*cos = s;\n\t\tbreak;\n\t}\n}\n"
  },
  {
    "path": "user.libc/src/math/sincosf.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_sinf.c */\n/*\n * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.\n * Optimized by Bruce D. Evans.\n */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n\n#define _GNU_SOURCE\n#include \"libm.h\"\n\n/* Small multiples of pi/2 rounded to double precision. */\nstatic const double\ns1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */\ns2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */\ns3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */\ns4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */\n\nvoid sincosf(float x, float *sin, float *cos)\n{\n\tdouble y;\n\tfloat_t s, c;\n\tuint32_t ix;\n\tunsigned n, sign;\n\n\tGET_FLOAT_WORD(ix, x);\n\tsign = ix >> 31;\n\tix &= 0x7fffffff;\n\n\t/* |x| ~<= pi/4 */\n\tif (ix <= 0x3f490fda) {\n\t\t/* |x| < 2**-12 */\n\t\tif (ix < 0x39800000) {\n\t\t\t/* raise inexact if x!=0 and underflow if subnormal */\n\t\t\tFORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f);\n\t\t\t*sin = x;\n\t\t\t*cos = 1.0f;\n\t\t\treturn;\n\t\t}\n\t\t*sin = __sindf(x);\n\t\t*cos = __cosdf(x);\n\t\treturn;\n\t}\n\n\t/* |x| ~<= 5*pi/4 */\n\tif (ix <= 0x407b53d1) {\n\t\tif (ix <= 0x4016cbe3) {  /* |x| ~<= 3pi/4 */\n\t\t\tif (sign) {\n\t\t\t\t*sin = -__cosdf(x + s1pio2);\n\t\t\t\t*cos = __sindf(x + s1pio2);\n\t\t\t} else {\n\t\t\t\t*sin = __cosdf(s1pio2 - x);\n\t\t\t\t*cos = __sindf(s1pio2 - x);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\t/* -sin(x+c) is not correct if x+c could be 0: -0 vs +0 */\n\t\t*sin = -__sindf(sign ? x + s2pio2 : x - s2pio2);\n\t\t*cos = -__cosdf(sign ? x + s2pio2 : x - s2pio2);\n\t\treturn;\n\t}\n\n\t/* |x| ~<= 9*pi/4 */\n\tif (ix <= 0x40e231d5) {\n\t\tif (ix <= 0x40afeddf) {  /* |x| ~<= 7*pi/4 */\n\t\t\tif (sign) {\n\t\t\t\t*sin = __cosdf(x + s3pio2);\n\t\t\t\t*cos = -__sindf(x + s3pio2);\n\t\t\t} else {\n\t\t\t\t*sin = -__cosdf(x - s3pio2);\n\t\t\t\t*cos = __sindf(x - s3pio2);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\t*sin = __sindf(sign ? x + s4pio2 : x - s4pio2);\n\t\t*cos = __cosdf(sign ? x + s4pio2 : x - s4pio2);\n\t\treturn;\n\t}\n\n\t/* sin(Inf or NaN) is NaN */\n\tif (ix >= 0x7f800000) {\n\t\t*sin = *cos = x - x;\n\t\treturn;\n\t}\n\n\t/* general argument reduction needed */\n\tn = __rem_pio2f(x, &y);\n\ts = __sindf(y);\n\tc = __cosdf(y);\n\tswitch (n&3) {\n\tcase 0:\n\t\t*sin = s;\n\t\t*cos = c;\n\t\tbreak;\n\tcase 1:\n\t\t*sin = c;\n\t\t*cos = -s;\n\t\tbreak;\n\tcase 2:\n\t\t*sin = -s;\n\t\t*cos = -c;\n\t\tbreak;\n\tcase 3:\n\tdefault:\n\t\t*sin = -c;\n\t\t*cos = s;\n\t\tbreak;\n\t}\n}\n"
  },
  {
    "path": "user.libc/src/math/sincosl.c",
    "content": "#define _GNU_SOURCE\n#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nvoid sincosl(long double x, long double *sin, long double *cos)\n{\n\tdouble sind, cosd;\n\tsincos(x, &sind, &cosd);\n\t*sin = sind;\n\t*cos = cosd;\n}\n#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\nvoid sincosl(long double x, long double *sin, long double *cos)\n{\n\tunion ldshape u = {x};\n\tunsigned n;\n\tlong double y[2], s, c;\n\n\tu.i.se &= 0x7fff;\n\tif (u.i.se == 0x7fff) {\n\t\t*sin = *cos = x - x;\n\t\treturn;\n\t}\n\tif (u.f < M_PI_4) {\n\t\tif (u.i.se < 0x3fff - LDBL_MANT_DIG) {\n\t\t\t/* raise underflow if subnormal */\n\t\t\tif (u.i.se == 0) FORCE_EVAL(x*0x1p-120f);\n\t\t\t*sin = x;\n\t\t\t/* raise inexact if x!=0 */\n\t\t\t*cos = 1.0 + x;\n\t\t\treturn;\n\t\t}\n\t\t*sin = __sinl(x, 0, 0);\n\t\t*cos = __cosl(x, 0);\n\t\treturn;\n\t}\n\tn = __rem_pio2l(x, y);\n\ts = __sinl(y[0], y[1], 1);\n\tc = __cosl(y[0], y[1]);\n\tswitch (n & 3) {\n\tcase 0:\n\t\t*sin = s;\n\t\t*cos = c;\n\t\tbreak;\n\tcase 1:\n\t\t*sin = c;\n\t\t*cos = -s;\n\t\tbreak;\n\tcase 2:\n\t\t*sin = -s;\n\t\t*cos = -c;\n\t\tbreak;\n\tcase 3:\n\tdefault:\n\t\t*sin = -c;\n\t\t*cos = s;\n\t\tbreak;\n\t}\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/sinf.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_sinf.c */\n/*\n * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.\n * Optimized by Bruce D. Evans.\n */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n\n#include \"libm.h\"\n\n/* Small multiples of pi/2 rounded to double precision. */\nstatic const double\ns1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */\ns2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */\ns3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */\ns4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */\n\nfloat sinf(float x)\n{\n\tdouble y;\n\tuint32_t ix;\n\tint n, sign;\n\n\tGET_FLOAT_WORD(ix, x);\n\tsign = ix >> 31;\n\tix &= 0x7fffffff;\n\n\tif (ix <= 0x3f490fda) {  /* |x| ~<= pi/4 */\n\t\tif (ix < 0x39800000) {  /* |x| < 2**-12 */\n\t\t\t/* raise inexact if x!=0 and underflow if subnormal */\n\t\t\tFORCE_EVAL(ix < 0x00800000 ? x/0x1p120f : x+0x1p120f);\n\t\t\treturn x;\n\t\t}\n\t\treturn __sindf(x);\n\t}\n\tif (ix <= 0x407b53d1) {  /* |x| ~<= 5*pi/4 */\n\t\tif (ix <= 0x4016cbe3) {  /* |x| ~<= 3pi/4 */\n\t\t\tif (sign)\n\t\t\t\treturn -__cosdf(x + s1pio2);\n\t\t\telse\n\t\t\t\treturn __cosdf(x - s1pio2);\n\t\t}\n\t\treturn __sindf(sign ? -(x + s2pio2) : -(x - s2pio2));\n\t}\n\tif (ix <= 0x40e231d5) {  /* |x| ~<= 9*pi/4 */\n\t\tif (ix <= 0x40afeddf) {  /* |x| ~<= 7*pi/4 */\n\t\t\tif (sign)\n\t\t\t\treturn __cosdf(x + s3pio2);\n\t\t\telse\n\t\t\t\treturn -__cosdf(x - s3pio2);\n\t\t}\n\t\treturn __sindf(sign ? x + s4pio2 : x - s4pio2);\n\t}\n\n\t/* sin(Inf or NaN) is NaN */\n\tif (ix >= 0x7f800000)\n\t\treturn x - x;\n\n\t/* general argument reduction needed */\n\tn = __rem_pio2f(x, &y);\n\tswitch (n&3) {\n\tcase 0: return  __sindf(y);\n\tcase 1: return  __cosdf(y);\n\tcase 2: return  __sindf(-y);\n\tdefault:\n\t\treturn -__cosdf(y);\n\t}\n}\n"
  },
  {
    "path": "user.libc/src/math/sinh.c",
    "content": "#include \"libm.h\"\n\n/* sinh(x) = (exp(x) - 1/exp(x))/2\n *         = (exp(x)-1 + (exp(x)-1)/exp(x))/2\n *         = x + x^3/6 + o(x^5)\n */\ndouble sinh(double x)\n{\n\tunion {double f; uint64_t i;} u = {.f = x};\n\tuint32_t w;\n\tdouble t, h, absx;\n\n\th = 0.5;\n\tif (u.i >> 63)\n\t\th = -h;\n\t/* |x| */\n\tu.i &= (uint64_t)-1/2;\n\tabsx = u.f;\n\tw = u.i >> 32;\n\n\t/* |x| < log(DBL_MAX) */\n\tif (w < 0x40862e42) {\n\t\tt = expm1(absx);\n\t\tif (w < 0x3ff00000) {\n\t\t\tif (w < 0x3ff00000 - (26<<20))\n\t\t\t\t/* note: inexact and underflow are raised by expm1 */\n\t\t\t\t/* note: this branch avoids spurious underflow */\n\t\t\t\treturn x;\n\t\t\treturn h*(2*t - t*t/(t+1));\n\t\t}\n\t\t/* note: |x|>log(0x1p26)+eps could be just h*exp(x) */\n\t\treturn h*(t + t/(t+1));\n\t}\n\n\t/* |x| > log(DBL_MAX) or nan */\n\t/* note: the result is stored to handle overflow */\n\tt = __expo2(absx, 2*h);\n\treturn t;\n}\n"
  },
  {
    "path": "user.libc/src/math/sinhf.c",
    "content": "#include \"libm.h\"\n\nfloat sinhf(float x)\n{\n\tunion {float f; uint32_t i;} u = {.f = x};\n\tuint32_t w;\n\tfloat t, h, absx;\n\n\th = 0.5;\n\tif (u.i >> 31)\n\t\th = -h;\n\t/* |x| */\n\tu.i &= 0x7fffffff;\n\tabsx = u.f;\n\tw = u.i;\n\n\t/* |x| < log(FLT_MAX) */\n\tif (w < 0x42b17217) {\n\t\tt = expm1f(absx);\n\t\tif (w < 0x3f800000) {\n\t\t\tif (w < 0x3f800000 - (12<<23))\n\t\t\t\treturn x;\n\t\t\treturn h*(2*t - t*t/(t+1));\n\t\t}\n\t\treturn h*(t + t/(t+1));\n\t}\n\n\t/* |x| > logf(FLT_MAX) or nan */\n\tt = __expo2f(absx, 2*h);\n\treturn t;\n}\n"
  },
  {
    "path": "user.libc/src/math/sinhl.c",
    "content": "#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double sinhl(long double x)\n{\n\treturn sinh(x);\n}\n#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384\nlong double sinhl(long double x)\n{\n\tunion ldshape u = {x};\n\tunsigned ex = u.i.se & 0x7fff;\n\tlong double h, t, absx;\n\n\th = 0.5;\n\tif (u.i.se & 0x8000)\n\t\th = -h;\n\t/* |x| */\n\tu.i.se = ex;\n\tabsx = u.f;\n\n\t/* |x| < log(LDBL_MAX) */\n\tif (ex < 0x3fff+13 || (ex == 0x3fff+13 && u.i.m>>32 < 0xb17217f7)) {\n\t\tt = expm1l(absx);\n\t\tif (ex < 0x3fff) {\n\t\t\tif (ex < 0x3fff-32)\n\t\t\t\treturn x;\n\t\t\treturn h*(2*t - t*t/(1+t));\n\t\t}\n\t\treturn h*(t + t/(t+1));\n\t}\n\n\t/* |x| > log(LDBL_MAX) or nan */\n\tt = expl(0.5*absx);\n\treturn h*t*t;\n}\n#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384\n// TODO: broken implementation to make things compile\nlong double sinhl(long double x)\n{\n\treturn sinh(x);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/sinl.c",
    "content": "#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double sinl(long double x)\n{\n\treturn sin(x);\n}\n#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\nlong double sinl(long double x)\n{\n\tunion ldshape u = {x};\n\tunsigned n;\n\tlong double y[2], hi, lo;\n\n\tu.i.se &= 0x7fff;\n\tif (u.i.se == 0x7fff)\n\t\treturn x - x;\n\tif (u.f < M_PI_4) {\n\t\tif (u.i.se < 0x3fff - LDBL_MANT_DIG/2) {\n\t\t\t/* raise inexact if x!=0 and underflow if subnormal */\n\t\t\tFORCE_EVAL(u.i.se == 0 ? x*0x1p-120f : x+0x1p120f);\n\t\t\treturn x;\n\t\t}\n\t\treturn __sinl(x, 0.0, 0);\n\t}\n\tn = __rem_pio2l(x, y);\n\thi = y[0];\n\tlo = y[1];\n\tswitch (n & 3) {\n\tcase 0:\n\t\treturn __sinl(hi, lo, 1);\n\tcase 1:\n\t\treturn __cosl(hi, lo);\n\tcase 2:\n\t\treturn -__sinl(hi, lo, 1);\n\tcase 3:\n\tdefault:\n\t\treturn -__cosl(hi, lo);\n\t}\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/sqrt.c",
    "content": "#include <stdint.h>\n#include <math.h>\n#include \"libm.h\"\n#include \"sqrt_data.h\"\n\n#define FENV_SUPPORT 1\n\n/* returns a*b*2^-32 - e, with error 0 <= e < 1.  */\nstatic inline uint32_t mul32(uint32_t a, uint32_t b)\n{\n\treturn (uint64_t)a*b >> 32;\n}\n\n/* returns a*b*2^-64 - e, with error 0 <= e < 3.  */\nstatic inline uint64_t mul64(uint64_t a, uint64_t b)\n{\n\tuint64_t ahi = a>>32;\n\tuint64_t alo = a&0xffffffff;\n\tuint64_t bhi = b>>32;\n\tuint64_t blo = b&0xffffffff;\n\treturn ahi*bhi + (ahi*blo >> 32) + (alo*bhi >> 32);\n}\n\ndouble sqrt(double x)\n{\n\tuint64_t ix, top, m;\n\n\t/* special case handling.  */\n\tix = asuint64(x);\n\ttop = ix >> 52;\n\tif (predict_false(top - 0x001 >= 0x7ff - 0x001)) {\n\t\t/* x < 0x1p-1022 or inf or nan.  */\n\t\tif (ix * 2 == 0)\n\t\t\treturn x;\n\t\tif (ix == 0x7ff0000000000000)\n\t\t\treturn x;\n\t\tif (ix > 0x7ff0000000000000)\n\t\t\treturn __math_invalid(x);\n\t\t/* x is subnormal, normalize it.  */\n\t\tix = asuint64(x * 0x1p52);\n\t\ttop = ix >> 52;\n\t\ttop -= 52;\n\t}\n\n\t/* argument reduction:\n\t   x = 4^e m; with integer e, and m in [1, 4)\n\t   m: fixed point representation [2.62]\n\t   2^e is the exponent part of the result.  */\n\tint even = top & 1;\n\tm = (ix << 11) | 0x8000000000000000;\n\tif (even) m >>= 1;\n\ttop = (top + 0x3ff) >> 1;\n\n\t/* approximate r ~ 1/sqrt(m) and s ~ sqrt(m) when m in [1,4)\n\n\t   initial estimate:\n\t   7bit table lookup (1bit exponent and 6bit significand).\n\n\t   iterative approximation:\n\t   using 2 goldschmidt iterations with 32bit int arithmetics\n\t   and a final iteration with 64bit int arithmetics.\n\n\t   details:\n\n\t   the relative error (e = r0 sqrt(m)-1) of a linear estimate\n\t   (r0 = a m + b) is |e| < 0.085955 ~ 0x1.6p-4 at best,\n\t   a table lookup is faster and needs one less iteration\n\t   6 bit lookup table (128b) gives |e| < 0x1.f9p-8\n\t   7 bit lookup table (256b) gives |e| < 0x1.fdp-9\n\t   for single and double prec 6bit is enough but for quad\n\t   prec 7bit is needed (or modified iterations). to avoid\n\t   one more iteration >=13bit table would be needed (16k).\n\n\t   a newton-raphson iteration for r is\n\t     w = r*r\n\t     u = 3 - m*w\n\t     r = r*u/2\n\t   can use a goldschmidt iteration for s at the end or\n\t     s = m*r\n\n\t   first goldschmidt iteration is\n\t     s = m*r\n\t     u = 3 - s*r\n\t     r = r*u/2\n\t     s = s*u/2\n\t   next goldschmidt iteration is\n\t     u = 3 - s*r\n\t     r = r*u/2\n\t     s = s*u/2\n\t   and at the end r is not computed only s.\n\n\t   they use the same amount of operations and converge at the\n\t   same quadratic rate, i.e. if\n\t     r1 sqrt(m) - 1 = e, then\n\t     r2 sqrt(m) - 1 = -3/2 e^2 - 1/2 e^3\n\t   the advantage of goldschmidt is that the mul for s and r\n\t   are independent (computed in parallel), however it is not\n\t   \"self synchronizing\": it only uses the input m in the\n\t   first iteration so rounding errors accumulate. at the end\n\t   or when switching to larger precision arithmetics rounding\n\t   errors dominate so the first iteration should be used.\n\n\t   the fixed point representations are\n\t     m: 2.30 r: 0.32, s: 2.30, d: 2.30, u: 2.30, three: 2.30\n\t   and after switching to 64 bit\n\t     m: 2.62 r: 0.64, s: 2.62, d: 2.62, u: 2.62, three: 2.62  */\n\n\tstatic const uint64_t three = 0xc0000000;\n\tuint64_t r, s, d, u, i;\n\n\ti = (ix >> 46) % 128;\n\tr = (uint32_t)__rsqrt_tab[i] << 16;\n\t/* |r sqrt(m) - 1| < 0x1.fdp-9 */\n\ts = mul32(m>>32, r);\n\t/* |s/sqrt(m) - 1| < 0x1.fdp-9 */\n\td = mul32(s, r);\n\tu = three - d;\n\tr = mul32(r, u) << 1;\n\t/* |r sqrt(m) - 1| < 0x1.7bp-16 */\n\ts = mul32(s, u) << 1;\n\t/* |s/sqrt(m) - 1| < 0x1.7bp-16 */\n\td = mul32(s, r);\n\tu = three - d;\n\tr = mul32(r, u) << 1;\n\t/* |r sqrt(m) - 1| < 0x1.3704p-29 (measured worst-case) */\n\tr = r << 32;\n\ts = mul64(m, r);\n\td = mul64(s, r);\n\tu = (three<<32) - d;\n\ts = mul64(s, u);  /* repr: 3.61 */\n\t/* -0x1p-57 < s - sqrt(m) < 0x1.8001p-61 */\n\ts = (s - 2) >> 9; /* repr: 12.52 */\n\t/* -0x1.09p-52 < s - sqrt(m) < -0x1.fffcp-63 */\n\n\t/* s < sqrt(m) < s + 0x1.09p-52,\n\t   compute nearest rounded result:\n\t   the nearest result to 52 bits is either s or s+0x1p-52,\n\t   we can decide by comparing (2^52 s + 0.5)^2 to 2^104 m.  */\n\tuint64_t d0, d1, d2;\n\tdouble y, t;\n\td0 = (m << 42) - s*s;\n\td1 = s - d0;\n\td2 = d1 + s + 1;\n\ts += d1 >> 63;\n\ts &= 0x000fffffffffffff;\n\ts |= top << 52;\n\ty = asdouble(s);\n\tif (FENV_SUPPORT) {\n\t\t/* handle rounding modes and inexact exception:\n\t\t   only (s+1)^2 == 2^42 m case is exact otherwise\n\t\t   add a tiny value to cause the fenv effects.  */\n\t\tuint64_t tiny = predict_false(d2==0) ? 0 : 0x0010000000000000;\n\t\ttiny |= (d1^d2) & 0x8000000000000000;\n\t\tt = asdouble(tiny);\n\t\ty = eval_as_double(y + t);\n\t}\n\treturn y;\n}\n"
  },
  {
    "path": "user.libc/src/math/sqrt_data.c",
    "content": "#include \"sqrt_data.h\"\nconst uint16_t __rsqrt_tab[128] = {\n0xb451,0xb2f0,0xb196,0xb044,0xaef9,0xadb6,0xac79,0xab43,\n0xaa14,0xa8eb,0xa7c8,0xa6aa,0xa592,0xa480,0xa373,0xa26b,\n0xa168,0xa06a,0x9f70,0x9e7b,0x9d8a,0x9c9d,0x9bb5,0x9ad1,\n0x99f0,0x9913,0x983a,0x9765,0x9693,0x95c4,0x94f8,0x9430,\n0x936b,0x92a9,0x91ea,0x912e,0x9075,0x8fbe,0x8f0a,0x8e59,\n0x8daa,0x8cfe,0x8c54,0x8bac,0x8b07,0x8a64,0x89c4,0x8925,\n0x8889,0x87ee,0x8756,0x86c0,0x862b,0x8599,0x8508,0x8479,\n0x83ec,0x8361,0x82d8,0x8250,0x81c9,0x8145,0x80c2,0x8040,\n0xff02,0xfd0e,0xfb25,0xf947,0xf773,0xf5aa,0xf3ea,0xf234,\n0xf087,0xeee3,0xed47,0xebb3,0xea27,0xe8a3,0xe727,0xe5b2,\n0xe443,0xe2dc,0xe17a,0xe020,0xdecb,0xdd7d,0xdc34,0xdaf1,\n0xd9b3,0xd87b,0xd748,0xd61a,0xd4f1,0xd3cd,0xd2ad,0xd192,\n0xd07b,0xcf69,0xce5b,0xcd51,0xcc4a,0xcb48,0xca4a,0xc94f,\n0xc858,0xc764,0xc674,0xc587,0xc49d,0xc3b7,0xc2d4,0xc1f4,\n0xc116,0xc03c,0xbf65,0xbe90,0xbdbe,0xbcef,0xbc23,0xbb59,\n0xba91,0xb9cc,0xb90a,0xb84a,0xb78c,0xb6d0,0xb617,0xb560,\n};\n"
  },
  {
    "path": "user.libc/src/math/sqrt_data.h",
    "content": "#ifndef _SQRT_DATA_H\n#define _SQRT_DATA_H\n\n#include <features.h>\n#include <stdint.h>\n\n/* if x in [1,2): i = (int)(64*x);\n   if x in [2,4): i = (int)(32*x-64);\n   __rsqrt_tab[i]*2^-16 is estimating 1/sqrt(x) with small relative error:\n   |__rsqrt_tab[i]*0x1p-16*sqrt(x) - 1| < -0x1.fdp-9 < 2^-8 */\nextern hidden const uint16_t __rsqrt_tab[128];\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/sqrtf.c",
    "content": "#include <stdint.h>\n#include <math.h>\n#include \"libm.h\"\n#include \"sqrt_data.h\"\n\n#define FENV_SUPPORT 1\n\nstatic inline uint32_t mul32(uint32_t a, uint32_t b)\n{\n\treturn (uint64_t)a*b >> 32;\n}\n\n/* see sqrt.c for more detailed comments.  */\n\nfloat sqrtf(float x)\n{\n\tuint32_t ix, m, m1, m0, even, ey;\n\n\tix = asuint(x);\n\tif (predict_false(ix - 0x00800000 >= 0x7f800000 - 0x00800000)) {\n\t\t/* x < 0x1p-126 or inf or nan.  */\n\t\tif (ix * 2 == 0)\n\t\t\treturn x;\n\t\tif (ix == 0x7f800000)\n\t\t\treturn x;\n\t\tif (ix > 0x7f800000)\n\t\t\treturn __math_invalidf(x);\n\t\t/* x is subnormal, normalize it.  */\n\t\tix = asuint(x * 0x1p23f);\n\t\tix -= 23 << 23;\n\t}\n\n\t/* x = 4^e m; with int e and m in [1, 4).  */\n\teven = ix & 0x00800000;\n\tm1 = (ix << 8) | 0x80000000;\n\tm0 = (ix << 7) & 0x7fffffff;\n\tm = even ? m0 : m1;\n\n\t/* 2^e is the exponent part of the return value.  */\n\tey = ix >> 1;\n\tey += 0x3f800000 >> 1;\n\tey &= 0x7f800000;\n\n\t/* compute r ~ 1/sqrt(m), s ~ sqrt(m) with 2 goldschmidt iterations.  */\n\tstatic const uint32_t three = 0xc0000000;\n\tuint32_t r, s, d, u, i;\n\ti = (ix >> 17) % 128;\n\tr = (uint32_t)__rsqrt_tab[i] << 16;\n\t/* |r*sqrt(m) - 1| < 0x1p-8 */\n\ts = mul32(m, r);\n\t/* |s/sqrt(m) - 1| < 0x1p-8 */\n\td = mul32(s, r);\n\tu = three - d;\n\tr = mul32(r, u) << 1;\n\t/* |r*sqrt(m) - 1| < 0x1.7bp-16 */\n\ts = mul32(s, u) << 1;\n\t/* |s/sqrt(m) - 1| < 0x1.7bp-16 */\n\td = mul32(s, r);\n\tu = three - d;\n\ts = mul32(s, u);\n\t/* -0x1.03p-28 < s/sqrt(m) - 1 < 0x1.fp-31 */\n\ts = (s - 1)>>6;\n\t/* s < sqrt(m) < s + 0x1.08p-23 */\n\n\t/* compute nearest rounded result.  */\n\tuint32_t d0, d1, d2;\n\tfloat y, t;\n\td0 = (m << 16) - s*s;\n\td1 = s - d0;\n\td2 = d1 + s + 1;\n\ts += d1 >> 31;\n\ts &= 0x007fffff;\n\ts |= ey;\n\ty = asfloat(s);\n\tif (FENV_SUPPORT) {\n\t\t/* handle rounding and inexact exception. */\n\t\tuint32_t tiny = predict_false(d2==0) ? 0 : 0x01000000;\n\t\ttiny |= (d1^d2) & 0x80000000;\n\t\tt = asfloat(tiny);\n\t\ty = eval_as_float(y + t);\n\t}\n\treturn y;\n}\n"
  },
  {
    "path": "user.libc/src/math/sqrtl.c",
    "content": "#include <stdint.h>\n#include <math.h>\n#include <float.h>\n#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double sqrtl(long double x)\n{\n\treturn sqrt(x);\n}\n#elif (LDBL_MANT_DIG == 113 || LDBL_MANT_DIG == 64) && LDBL_MAX_EXP == 16384\n#include \"sqrt_data.h\"\n\n#define FENV_SUPPORT 1\n\ntypedef struct {\n\tuint64_t hi;\n\tuint64_t lo;\n} u128;\n\n/* top: 16 bit sign+exponent, x: significand.  */\nstatic inline long double mkldbl(uint64_t top, u128 x)\n{\n\tunion ldshape u;\n#if LDBL_MANT_DIG == 113\n\tu.i2.hi = x.hi;\n\tu.i2.lo = x.lo;\n\tu.i2.hi &= 0x0000ffffffffffff;\n\tu.i2.hi |= top << 48;\n#elif LDBL_MANT_DIG == 64\n\tu.i.se = top;\n\tu.i.m = x.lo;\n\t/* force the top bit on non-zero (and non-subnormal) results.  */\n\tif (top & 0x7fff)\n\t\tu.i.m |= 0x8000000000000000;\n#endif\n\treturn u.f;\n}\n\n/* return: top 16 bit is sign+exp and following bits are the significand.  */\nstatic inline u128 asu128(long double x)\n{\n\tunion ldshape u = {.f=x};\n\tu128 r;\n#if LDBL_MANT_DIG == 113\n\tr.hi = u.i2.hi;\n\tr.lo = u.i2.lo;\n#elif LDBL_MANT_DIG == 64\n\tr.lo = u.i.m<<49;\n\t/* ignore the top bit: pseudo numbers are not handled. */\n\tr.hi = u.i.m>>15;\n\tr.hi &= 0x0000ffffffffffff;\n\tr.hi |= (uint64_t)u.i.se << 48;\n#endif\n\treturn r;\n}\n\n/* returns a*b*2^-32 - e, with error 0 <= e < 1.  */\nstatic inline uint32_t mul32(uint32_t a, uint32_t b)\n{\n\treturn (uint64_t)a*b >> 32;\n}\n\n/* returns a*b*2^-64 - e, with error 0 <= e < 3.  */\nstatic inline uint64_t mul64(uint64_t a, uint64_t b)\n{\n\tuint64_t ahi = a>>32;\n\tuint64_t alo = a&0xffffffff;\n\tuint64_t bhi = b>>32;\n\tuint64_t blo = b&0xffffffff;\n\treturn ahi*bhi + (ahi*blo >> 32) + (alo*bhi >> 32);\n}\n\nstatic inline u128 add64(u128 a, uint64_t b)\n{\n\tu128 r;\n\tr.lo = a.lo + b;\n\tr.hi = a.hi;\n\tif (r.lo < a.lo)\n\t\tr.hi++;\n\treturn r;\n}\n\nstatic inline u128 add128(u128 a, u128 b)\n{\n\tu128 r;\n\tr.lo = a.lo + b.lo;\n\tr.hi = a.hi + b.hi;\n\tif (r.lo < a.lo)\n\t\tr.hi++;\n\treturn r;\n}\n\nstatic inline u128 sub64(u128 a, uint64_t b)\n{\n\tu128 r;\n\tr.lo = a.lo - b;\n\tr.hi = a.hi;\n\tif (a.lo < b)\n\t\tr.hi--;\n\treturn r;\n}\n\nstatic inline u128 sub128(u128 a, u128 b)\n{\n\tu128 r;\n\tr.lo = a.lo - b.lo;\n\tr.hi = a.hi - b.hi;\n\tif (a.lo < b.lo)\n\t\tr.hi--;\n\treturn r;\n}\n\n/* a<<n, 0 <= n <= 127 */\nstatic inline u128 lsh(u128 a, int n)\n{\n\tif (n == 0)\n\t\treturn a;\n\tif (n >= 64) {\n\t\ta.hi = a.lo<<(n-64);\n\t\ta.lo = 0;\n\t} else {\n\t\ta.hi = (a.hi<<n) | (a.lo>>(64-n));\n\t\ta.lo = a.lo<<n;\n\t}\n\treturn a;\n}\n\n/* a>>n, 0 <= n <= 127 */\nstatic inline u128 rsh(u128 a, int n)\n{\n\tif (n == 0)\n\t\treturn a;\n\tif (n >= 64) {\n\t\ta.lo = a.hi>>(n-64);\n\t\ta.hi = 0;\n\t} else {\n\t\ta.lo = (a.lo>>n) | (a.hi<<(64-n));\n\t\ta.hi = a.hi>>n;\n\t}\n\treturn a;\n}\n\n/* returns a*b exactly.  */\nstatic inline u128 mul64_128(uint64_t a, uint64_t b)\n{\n\tu128 r;\n\tuint64_t ahi = a>>32;\n\tuint64_t alo = a&0xffffffff;\n\tuint64_t bhi = b>>32;\n\tuint64_t blo = b&0xffffffff;\n\tuint64_t lo1 = ((ahi*blo)&0xffffffff) + ((alo*bhi)&0xffffffff) + (alo*blo>>32);\n\tuint64_t lo2 = (alo*blo)&0xffffffff;\n\tr.hi = ahi*bhi + (ahi*blo>>32) + (alo*bhi>>32) + (lo1>>32);\n\tr.lo = (lo1<<32) + lo2;\n\treturn r;\n}\n\n/* returns a*b*2^-128 - e, with error 0 <= e < 7.  */\nstatic inline u128 mul128(u128 a, u128 b)\n{\n\tu128 hi = mul64_128(a.hi, b.hi);\n\tuint64_t m1 = mul64(a.hi, b.lo);\n\tuint64_t m2 = mul64(a.lo, b.hi);\n\treturn add64(add64(hi, m1), m2);\n}\n\n/* returns a*b % 2^128.  */\nstatic inline u128 mul128_tail(u128 a, u128 b)\n{\n\tu128 lo = mul64_128(a.lo, b.lo);\n\tlo.hi += a.hi*b.lo + a.lo*b.hi;\n\treturn lo;\n}\n\n\n/* see sqrt.c for detailed comments.  */\n\nlong double sqrtl(long double x)\n{\n\tu128 ix, ml;\n\tuint64_t top;\n\n\tix = asu128(x);\n\ttop = ix.hi >> 48;\n\tif (predict_false(top - 0x0001 >= 0x7fff - 0x0001)) {\n\t\t/* x < 0x1p-16382 or inf or nan.  */\n\t\tif (2*ix.hi == 0 && ix.lo == 0)\n\t\t\treturn x;\n\t\tif (ix.hi == 0x7fff000000000000 && ix.lo == 0)\n\t\t\treturn x;\n\t\tif (top >= 0x7fff)\n\t\t\treturn __math_invalidl(x);\n\t\t/* x is subnormal, normalize it.  */\n\t\tix = asu128(x * 0x1p112);\n\t\ttop = ix.hi >> 48;\n\t\ttop -= 112;\n\t}\n\n\t/* x = 4^e m; with int e and m in [1, 4) */\n\tint even = top & 1;\n\tml = lsh(ix, 15);\n\tml.hi |= 0x8000000000000000;\n\tif (even) ml = rsh(ml, 1);\n\ttop = (top + 0x3fff) >> 1;\n\n\t/* r ~ 1/sqrt(m) */\n\tstatic const uint64_t three = 0xc0000000;\n\tuint64_t r, s, d, u, i;\n\ti = (ix.hi >> 42) % 128;\n\tr = (uint32_t)__rsqrt_tab[i] << 16;\n\t/* |r sqrt(m) - 1| < 0x1p-8 */\n\ts = mul32(ml.hi>>32, r);\n\td = mul32(s, r);\n\tu = three - d;\n\tr = mul32(u, r) << 1;\n\t/* |r sqrt(m) - 1| < 0x1.7bp-16, switch to 64bit */\n\tr = r<<32;\n\ts = mul64(ml.hi, r);\n\td = mul64(s, r);\n\tu = (three<<32) - d;\n\tr = mul64(u, r) << 1;\n\t/* |r sqrt(m) - 1| < 0x1.a5p-31 */\n\ts = mul64(u, s) << 1;\n\td = mul64(s, r);\n\tu = (three<<32) - d;\n\tr = mul64(u, r) << 1;\n\t/* |r sqrt(m) - 1| < 0x1.c001p-59, switch to 128bit */\n\n\tstatic const u128 threel = {.hi=0xc0000000<<32, .lo=0};\n\tu128 rl, sl, dl, ul;\n\trl.hi = r;\n\trl.lo = 0;\n\tsl = mul128(ml, rl);\n\tdl = mul128(sl, rl);\n\tul = sub128(threel, dl);\n\tsl = mul128(ul, sl); /* repr: 3.125 */\n\t/* -0x1p-116 < s - sqrt(m) < 0x3.8001p-125 */\n\tsl = rsh(sub64(sl, 4), 125-(LDBL_MANT_DIG-1));\n\t/* s < sqrt(m) < s + 1 ULP + tiny */\n\n\tlong double y;\n\tu128 d2, d1, d0;\n\td0 = sub128(lsh(ml, 2*(LDBL_MANT_DIG-1)-126), mul128_tail(sl,sl));\n\td1 = sub128(sl, d0);\n\td2 = add128(add64(sl, 1), d1);\n\tsl = add64(sl, d1.hi >> 63);\n\ty = mkldbl(top, sl);\n\tif (FENV_SUPPORT) {\n\t\t/* handle rounding modes and inexact exception.  */\n\t\ttop = predict_false((d2.hi|d2.lo)==0) ? 0 : 1;\n\t\ttop |= ((d1.hi^d2.hi)&0x8000000000000000) >> 48;\n\t\ty += mkldbl(top, (u128){0});\n\t}\n\treturn y;\n}\n#else\n#error unsupported long double format\n#endif\n"
  },
  {
    "path": "user.libc/src/math/tan.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_tan.c */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n/* tan(x)\n * Return tangent function of x.\n *\n * kernel function:\n *      __tan           ... tangent function on [-pi/4,pi/4]\n *      __rem_pio2      ... argument reduction routine\n *\n * Method.\n *      Let S,C and T denote the sin, cos and tan respectively on\n *      [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2\n *      in [-pi/4 , +pi/4], and let n = k mod 4.\n *      We have\n *\n *          n        sin(x)      cos(x)        tan(x)\n *     ----------------------------------------------------------\n *          0          S           C             T\n *          1          C          -S            -1/T\n *          2         -S          -C             T\n *          3         -C           S            -1/T\n *     ----------------------------------------------------------\n *\n * Special cases:\n *      Let trig be any of sin, cos, or tan.\n *      trig(+-INF)  is NaN, with signals;\n *      trig(NaN)    is that NaN;\n *\n * Accuracy:\n *      TRIG(x) returns trig(x) nearly rounded\n */\n\n#include \"libm.h\"\n\ndouble tan(double x)\n{\n\tdouble y[2];\n\tuint32_t ix;\n\tunsigned n;\n\n\tGET_HIGH_WORD(ix, x);\n\tix &= 0x7fffffff;\n\n\t/* |x| ~< pi/4 */\n\tif (ix <= 0x3fe921fb) {\n\t\tif (ix < 0x3e400000) { /* |x| < 2**-27 */\n\t\t\t/* raise inexact if x!=0 and underflow if subnormal */\n\t\t\tFORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f);\n\t\t\treturn x;\n\t\t}\n\t\treturn __tan(x, 0.0, 0);\n\t}\n\n\t/* tan(Inf or NaN) is NaN */\n\tif (ix >= 0x7ff00000)\n\t\treturn x - x;\n\n\t/* argument reduction */\n\tn = __rem_pio2(x, y);\n\treturn __tan(y[0], y[1], n&1);\n}\n"
  },
  {
    "path": "user.libc/src/math/tanf.c",
    "content": "/* origin: FreeBSD /usr/src/lib/msun/src/s_tanf.c */\n/*\n * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.\n * Optimized by Bruce D. Evans.\n */\n/*\n * ====================================================\n * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n *\n * Developed at SunPro, a Sun Microsystems, Inc. business.\n * Permission to use, copy, modify, and distribute this\n * software is freely granted, provided that this notice\n * is preserved.\n * ====================================================\n */\n\n#include \"libm.h\"\n\n/* Small multiples of pi/2 rounded to double precision. */\nstatic const double\nt1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */\nt2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */\nt3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */\nt4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */\n\nfloat tanf(float x)\n{\n\tdouble y;\n\tuint32_t ix;\n\tunsigned n, sign;\n\n\tGET_FLOAT_WORD(ix, x);\n\tsign = ix >> 31;\n\tix &= 0x7fffffff;\n\n\tif (ix <= 0x3f490fda) {  /* |x| ~<= pi/4 */\n\t\tif (ix < 0x39800000) {  /* |x| < 2**-12 */\n\t\t\t/* raise inexact if x!=0 and underflow if subnormal */\n\t\t\tFORCE_EVAL(ix < 0x00800000 ? x/0x1p120f : x+0x1p120f);\n\t\t\treturn x;\n\t\t}\n\t\treturn __tandf(x, 0);\n\t}\n\tif (ix <= 0x407b53d1) {  /* |x| ~<= 5*pi/4 */\n\t\tif (ix <= 0x4016cbe3)  /* |x| ~<= 3pi/4 */\n\t\t\treturn __tandf((sign ? x+t1pio2 : x-t1pio2), 1);\n\t\telse\n\t\t\treturn __tandf((sign ? x+t2pio2 : x-t2pio2), 0);\n\t}\n\tif (ix <= 0x40e231d5) {  /* |x| ~<= 9*pi/4 */\n\t\tif (ix <= 0x40afeddf)  /* |x| ~<= 7*pi/4 */\n\t\t\treturn __tandf((sign ? x+t3pio2 : x-t3pio2), 1);\n\t\telse\n\t\t\treturn __tandf((sign ? x+t4pio2 : x-t4pio2), 0);\n\t}\n\n\t/* tan(Inf or NaN) is NaN */\n\tif (ix >= 0x7f800000)\n\t\treturn x - x;\n\n\t/* argument reduction */\n\tn = __rem_pio2f(x, &y);\n\treturn __tandf(y, n&1);\n}\n"
  },
  {
    "path": "user.libc/src/math/tanh.c",
    "content": "#include \"libm.h\"\n\n/* tanh(x) = (exp(x) - exp(-x))/(exp(x) + exp(-x))\n *         = (exp(2*x) - 1)/(exp(2*x) - 1 + 2)\n *         = (1 - exp(-2*x))/(exp(-2*x) - 1 + 2)\n */\ndouble tanh(double x)\n{\n\tunion {double f; uint64_t i;} u = {.f = x};\n\tuint32_t w;\n\tint sign;\n\tdouble_t t;\n\n\t/* x = |x| */\n\tsign = u.i >> 63;\n\tu.i &= (uint64_t)-1/2;\n\tx = u.f;\n\tw = u.i >> 32;\n\n\tif (w > 0x3fe193ea) {\n\t\t/* |x| > log(3)/2 ~= 0.5493 or nan */\n\t\tif (w > 0x40340000) {\n\t\t\t/* |x| > 20 or nan */\n\t\t\t/* note: this branch avoids raising overflow */\n\t\t\tt = 1 - 0/x;\n\t\t} else {\n\t\t\tt = expm1(2*x);\n\t\t\tt = 1 - 2/(t+2);\n\t\t}\n\t} else if (w > 0x3fd058ae) {\n\t\t/* |x| > log(5/3)/2 ~= 0.2554 */\n\t\tt = expm1(2*x);\n\t\tt = t/(t+2);\n\t} else if (w >= 0x00100000) {\n\t\t/* |x| >= 0x1p-1022, up to 2ulp error in [0.1,0.2554] */\n\t\tt = expm1(-2*x);\n\t\tt = -t/(t+2);\n\t} else {\n\t\t/* |x| is subnormal */\n\t\t/* note: the branch above would not raise underflow in [0x1p-1023,0x1p-1022) */\n\t\tFORCE_EVAL((float)x);\n\t\tt = x;\n\t}\n\treturn sign ? -t : t;\n}\n"
  },
  {
    "path": "user.libc/src/math/tanhf.c",
    "content": "#include \"libm.h\"\n\nfloat tanhf(float x)\n{\n\tunion {float f; uint32_t i;} u = {.f = x};\n\tuint32_t w;\n\tint sign;\n\tfloat t;\n\n\t/* x = |x| */\n\tsign = u.i >> 31;\n\tu.i &= 0x7fffffff;\n\tx = u.f;\n\tw = u.i;\n\n\tif (w > 0x3f0c9f54) {\n\t\t/* |x| > log(3)/2 ~= 0.5493 or nan */\n\t\tif (w > 0x41200000) {\n\t\t\t/* |x| > 10 */\n\t\t\tt = 1 + 0/x;\n\t\t} else {\n\t\t\tt = expm1f(2*x);\n\t\t\tt = 1 - 2/(t+2);\n\t\t}\n\t} else if (w > 0x3e82c578) {\n\t\t/* |x| > log(5/3)/2 ~= 0.2554 */\n\t\tt = expm1f(2*x);\n\t\tt = t/(t+2);\n\t} else if (w >= 0x00800000) {\n\t\t/* |x| >= 0x1p-126 */\n\t\tt = expm1f(-2*x);\n\t\tt = -t/(t+2);\n\t} else {\n\t\t/* |x| is subnormal */\n\t\tFORCE_EVAL(x*x);\n\t\tt = x;\n\t}\n\treturn sign ? -t : t;\n}\n"
  },
  {
    "path": "user.libc/src/math/tanhl.c",
    "content": "#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double tanhl(long double x)\n{\n\treturn tanh(x);\n}\n#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384\nlong double tanhl(long double x)\n{\n\tunion ldshape u = {x};\n\tunsigned ex = u.i.se & 0x7fff;\n\tunsigned sign = u.i.se & 0x8000;\n\tuint32_t w;\n\tlong double t;\n\n\t/* x = |x| */\n\tu.i.se = ex;\n\tx = u.f;\n\tw = u.i.m >> 32;\n\n\tif (ex > 0x3ffe || (ex == 0x3ffe && w > 0x8c9f53d5)) {\n\t\t/* |x| > log(3)/2 ~= 0.5493 or nan */\n\t\tif (ex >= 0x3fff+5) {\n\t\t\t/* |x| >= 32 */\n\t\t\tt = 1 + 0/(x + 0x1p-120f);\n\t\t} else {\n\t\t\tt = expm1l(2*x);\n\t\t\tt = 1 - 2/(t+2);\n\t\t}\n\t} else if (ex > 0x3ffd || (ex == 0x3ffd && w > 0x82c577d4)) {\n\t\t/* |x| > log(5/3)/2 ~= 0.2554 */\n\t\tt = expm1l(2*x);\n\t\tt = t/(t+2);\n\t} else {\n\t\t/* |x| is small */\n\t\tt = expm1l(-2*x);\n\t\tt = -t/(t+2);\n\t}\n\treturn sign ? -t : t;\n}\n#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384\n// TODO: broken implementation to make things compile\nlong double tanhl(long double x)\n{\n\treturn tanh(x);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/tanl.c",
    "content": "#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double tanl(long double x)\n{\n\treturn tan(x);\n}\n#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\nlong double tanl(long double x)\n{\n\tunion ldshape u = {x};\n\tlong double y[2];\n\tunsigned n;\n\n\tu.i.se &= 0x7fff;\n\tif (u.i.se == 0x7fff)\n\t\treturn x - x;\n\tif (u.f < M_PI_4) {\n\t\tif (u.i.se < 0x3fff - LDBL_MANT_DIG/2) {\n\t\t\t/* raise inexact if x!=0 and underflow if subnormal */\n\t\t\tFORCE_EVAL(u.i.se == 0 ? x*0x1p-120f : x+0x1p120f);\n\t\t\treturn x;\n\t\t}\n\t\treturn __tanl(x, 0, 0);\n\t}\n\tn = __rem_pio2l(x, y);\n\treturn __tanl(y[0], y[1], n&1);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/tgamma.c",
    "content": "/*\n\"A Precision Approximation of the Gamma Function\" - Cornelius Lanczos (1964)\n\"Lanczos Implementation of the Gamma Function\" - Paul Godfrey (2001)\n\"An Analysis of the Lanczos Gamma Approximation\" - Glendon Ralph Pugh (2004)\n\napproximation method:\n\n                        (x - 0.5)         S(x)\nGamma(x) = (x + g - 0.5)         *  ----------------\n                                    exp(x + g - 0.5)\n\nwith\n                 a1      a2      a3            aN\nS(x) ~= [ a0 + ----- + ----- + ----- + ... + ----- ]\n               x + 1   x + 2   x + 3         x + N\n\nwith a0, a1, a2, a3,.. aN constants which depend on g.\n\nfor x < 0 the following reflection formula is used:\n\nGamma(x)*Gamma(-x) = -pi/(x sin(pi x))\n\nmost ideas and constants are from boost and python\n*/\n#include \"libm.h\"\n\nstatic const double pi = 3.141592653589793238462643383279502884;\n\n/* sin(pi x) with x > 0x1p-100, if sin(pi*x)==0 the sign is arbitrary */\nstatic double sinpi(double x)\n{\n\tint n;\n\n\t/* argument reduction: x = |x| mod 2 */\n\t/* spurious inexact when x is odd int */\n\tx = x * 0.5;\n\tx = 2 * (x - floor(x));\n\n\t/* reduce x into [-.25,.25] */\n\tn = 4 * x;\n\tn = (n+1)/2;\n\tx -= n * 0.5;\n\n\tx *= pi;\n\tswitch (n) {\n\tdefault: /* case 4 */\n\tcase 0:\n\t\treturn __sin(x, 0, 0);\n\tcase 1:\n\t\treturn __cos(x, 0);\n\tcase 2:\n\t\treturn __sin(-x, 0, 0);\n\tcase 3:\n\t\treturn -__cos(x, 0);\n\t}\n}\n\n#define N 12\n//static const double g = 6.024680040776729583740234375;\nstatic const double gmhalf = 5.524680040776729583740234375;\nstatic const double Snum[N+1] = {\n\t23531376880.410759688572007674451636754734846804940,\n\t42919803642.649098768957899047001988850926355848959,\n\t35711959237.355668049440185451547166705960488635843,\n\t17921034426.037209699919755754458931112671403265390,\n\t6039542586.3520280050642916443072979210699388420708,\n\t1439720407.3117216736632230727949123939715485786772,\n\t248874557.86205415651146038641322942321632125127801,\n\t31426415.585400194380614231628318205362874684987640,\n\t2876370.6289353724412254090516208496135991145378768,\n\t186056.26539522349504029498971604569928220784236328,\n\t8071.6720023658162106380029022722506138218516325024,\n\t210.82427775157934587250973392071336271166969580291,\n\t2.5066282746310002701649081771338373386264310793408,\n};\nstatic const double Sden[N+1] = {\n\t0, 39916800, 120543840, 150917976, 105258076, 45995730, 13339535,\n\t2637558, 357423, 32670, 1925, 66, 1,\n};\n/* n! for small integer n */\nstatic const double fact[] = {\n\t1, 1, 2, 6, 24, 120, 720, 5040.0, 40320.0, 362880.0, 3628800.0, 39916800.0,\n\t479001600.0, 6227020800.0, 87178291200.0, 1307674368000.0, 20922789888000.0,\n\t355687428096000.0, 6402373705728000.0, 121645100408832000.0,\n\t2432902008176640000.0, 51090942171709440000.0, 1124000727777607680000.0,\n};\n\n/* S(x) rational function for positive x */\nstatic double S(double x)\n{\n\tdouble_t num = 0, den = 0;\n\tint i;\n\n\t/* to avoid overflow handle large x differently */\n\tif (x < 8)\n\t\tfor (i = N; i >= 0; i--) {\n\t\t\tnum = num * x + Snum[i];\n\t\t\tden = den * x + Sden[i];\n\t\t}\n\telse\n\t\tfor (i = 0; i <= N; i++) {\n\t\t\tnum = num / x + Snum[i];\n\t\t\tden = den / x + Sden[i];\n\t\t}\n\treturn num/den;\n}\n\ndouble tgamma(double x)\n{\n\tunion {double f; uint64_t i;} u = {x};\n\tdouble absx, y;\n\tdouble_t dy, z, r;\n\tuint32_t ix = u.i>>32 & 0x7fffffff;\n\tint sign = u.i>>63;\n\n\t/* special cases */\n\tif (ix >= 0x7ff00000)\n\t\t/* tgamma(nan)=nan, tgamma(inf)=inf, tgamma(-inf)=nan with invalid */\n\t\treturn x + INFINITY;\n\tif (ix < (0x3ff-54)<<20)\n\t\t/* |x| < 2^-54: tgamma(x) ~ 1/x, +-0 raises div-by-zero */\n\t\treturn 1/x;\n\n\t/* integer arguments */\n\t/* raise inexact when non-integer */\n\tif (x == floor(x)) {\n\t\tif (sign)\n\t\t\treturn 0/0.0;\n\t\tif (x <= sizeof fact/sizeof *fact)\n\t\t\treturn fact[(int)x - 1];\n\t}\n\n\t/* x >= 172: tgamma(x)=inf with overflow */\n\t/* x =< -184: tgamma(x)=+-0 with underflow */\n\tif (ix >= 0x40670000) { /* |x| >= 184 */\n\t\tif (sign) {\n\t\t\tFORCE_EVAL((float)(0x1p-126/x));\n\t\t\tif (floor(x) * 0.5 == floor(x * 0.5))\n\t\t\t\treturn 0;\n\t\t\treturn -0.0;\n\t\t}\n\t\tx *= 0x1p1023;\n\t\treturn x;\n\t}\n\n\tabsx = sign ? -x : x;\n\n\t/* handle the error of x + g - 0.5 */\n\ty = absx + gmhalf;\n\tif (absx > gmhalf) {\n\t\tdy = y - absx;\n\t\tdy -= gmhalf;\n\t} else {\n\t\tdy = y - gmhalf;\n\t\tdy -= absx;\n\t}\n\n\tz = absx - 0.5;\n\tr = S(absx) * exp(-y);\n\tif (x < 0) {\n\t\t/* reflection formula for negative x */\n\t\t/* sinpi(absx) is not 0, integers are already handled */\n\t\tr = -pi / (sinpi(absx) * absx * r);\n\t\tdy = -dy;\n\t\tz = -z;\n\t}\n\tr += dy * (gmhalf+0.5) * r / y;\n\tz = pow(y, 0.5*z);\n\ty = r * z * z;\n\treturn y;\n}\n\n#if 0\ndouble __lgamma_r(double x, int *sign)\n{\n\tdouble r, absx;\n\n\t*sign = 1;\n\n\t/* special cases */\n\tif (!isfinite(x))\n\t\t/* lgamma(nan)=nan, lgamma(+-inf)=inf */\n\t\treturn x*x;\n\n\t/* integer arguments */\n\tif (x == floor(x) && x <= 2) {\n\t\t/* n <= 0: lgamma(n)=inf with divbyzero */\n\t\t/* n == 1,2: lgamma(n)=0 */\n\t\tif (x <= 0)\n\t\t\treturn 1/0.0;\n\t\treturn 0;\n\t}\n\n\tabsx = fabs(x);\n\n\t/* lgamma(x) ~ -log(|x|) for tiny |x| */\n\tif (absx < 0x1p-54) {\n\t\t*sign = 1 - 2*!!signbit(x);\n\t\treturn -log(absx);\n\t}\n\n\t/* use tgamma for smaller |x| */\n\tif (absx < 128) {\n\t\tx = tgamma(x);\n\t\t*sign = 1 - 2*!!signbit(x);\n\t\treturn log(fabs(x));\n\t}\n\n\t/* second term (log(S)-g) could be more precise here.. */\n\t/* or with stirling: (|x|-0.5)*(log(|x|)-1) + poly(1/|x|) */\n\tr = (absx-0.5)*(log(absx+gmhalf)-1) + (log(S(absx)) - (gmhalf+0.5));\n\tif (x < 0) {\n\t\t/* reflection formula for negative x */\n\t\tx = sinpi(absx);\n\t\t*sign = 2*!!signbit(x) - 1;\n\t\tr = log(pi/(fabs(x)*absx)) - r;\n\t}\n\treturn r;\n}\n\nweak_alias(__lgamma_r, lgamma_r);\n#endif\n"
  },
  {
    "path": "user.libc/src/math/tgammaf.c",
    "content": "#include <math.h>\n\nfloat tgammaf(float x)\n{\n\treturn tgamma(x);\n}\n"
  },
  {
    "path": "user.libc/src/math/tgammal.c",
    "content": "/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_tgammal.c */\n/*\n * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n/*\n *      Gamma function\n *\n *\n * SYNOPSIS:\n *\n * long double x, y, tgammal();\n *\n * y = tgammal( x );\n *\n *\n * DESCRIPTION:\n *\n * Returns gamma function of the argument.  The result is\n * correctly signed.\n *\n * Arguments |x| <= 13 are reduced by recurrence and the function\n * approximated by a rational function of degree 7/8 in the\n * interval (2,3).  Large arguments are handled by Stirling's\n * formula. Large negative arguments are made positive using\n * a reflection formula.\n *\n *\n * ACCURACY:\n *\n *                      Relative error:\n * arithmetic   domain     # trials      peak         rms\n *    IEEE     -40,+40      10000       3.6e-19     7.9e-20\n *    IEEE    -1755,+1755   10000       4.8e-18     6.5e-19\n *\n * Accuracy for large arguments is dominated by error in powl().\n *\n */\n\n#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double tgammal(long double x)\n{\n\treturn tgamma(x);\n}\n#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384\n/*\ntgamma(x+2) = tgamma(x+2) P(x)/Q(x)\n0 <= x <= 1\nRelative error\nn=7, d=8\nPeak error =  1.83e-20\nRelative error spread =  8.4e-23\n*/\nstatic const long double P[8] = {\n 4.212760487471622013093E-5L,\n 4.542931960608009155600E-4L,\n 4.092666828394035500949E-3L,\n 2.385363243461108252554E-2L,\n 1.113062816019361559013E-1L,\n 3.629515436640239168939E-1L,\n 8.378004301573126728826E-1L,\n 1.000000000000000000009E0L,\n};\nstatic const long double Q[9] = {\n-1.397148517476170440917E-5L,\n 2.346584059160635244282E-4L,\n-1.237799246653152231188E-3L,\n-7.955933682494738320586E-4L,\n 2.773706565840072979165E-2L,\n-4.633887671244534213831E-2L,\n-2.243510905670329164562E-1L,\n 4.150160950588455434583E-1L,\n 9.999999999999999999908E-1L,\n};\n\n/*\nstatic const long double P[] = {\n-3.01525602666895735709e0L,\n-3.25157411956062339893e1L,\n-2.92929976820724030353e2L,\n-1.70730828800510297666e3L,\n-7.96667499622741999770e3L,\n-2.59780216007146401957e4L,\n-5.99650230220855581642e4L,\n-7.15743521530849602425e4L\n};\nstatic const long double Q[] = {\n 1.00000000000000000000e0L,\n-1.67955233807178858919e1L,\n 8.85946791747759881659e1L,\n 5.69440799097468430177e1L,\n-1.98526250512761318471e3L,\n 3.31667508019495079814e3L,\n 1.60577839621734713377e4L,\n-2.97045081369399940529e4L,\n-7.15743521530849602412e4L\n};\n*/\n#define MAXGAML 1755.455L\n/*static const long double LOGPI = 1.14472988584940017414L;*/\n\n/* Stirling's formula for the gamma function\ntgamma(x) = sqrt(2 pi) x^(x-.5) exp(-x) (1 + 1/x P(1/x))\nz(x) = x\n13 <= x <= 1024\nRelative error\nn=8, d=0\nPeak error =  9.44e-21\nRelative error spread =  8.8e-4\n*/\nstatic const long double STIR[9] = {\n 7.147391378143610789273E-4L,\n-2.363848809501759061727E-5L,\n-5.950237554056330156018E-4L,\n 6.989332260623193171870E-5L,\n 7.840334842744753003862E-4L,\n-2.294719747873185405699E-4L,\n-2.681327161876304418288E-3L,\n 3.472222222230075327854E-3L,\n 8.333333333333331800504E-2L,\n};\n\n#define MAXSTIR 1024.0L\nstatic const long double SQTPI = 2.50662827463100050242E0L;\n\n/* 1/tgamma(x) = z P(z)\n * z(x) = 1/x\n * 0 < x < 0.03125\n * Peak relative error 4.2e-23\n */\nstatic const long double S[9] = {\n-1.193945051381510095614E-3L,\n 7.220599478036909672331E-3L,\n-9.622023360406271645744E-3L,\n-4.219773360705915470089E-2L,\n 1.665386113720805206758E-1L,\n-4.200263503403344054473E-2L,\n-6.558780715202540684668E-1L,\n 5.772156649015328608253E-1L,\n 1.000000000000000000000E0L,\n};\n\n/* 1/tgamma(-x) = z P(z)\n * z(x) = 1/x\n * 0 < x < 0.03125\n * Peak relative error 5.16e-23\n * Relative error spread =  2.5e-24\n */\nstatic const long double SN[9] = {\n 1.133374167243894382010E-3L,\n 7.220837261893170325704E-3L,\n 9.621911155035976733706E-3L,\n-4.219773343731191721664E-2L,\n-1.665386113944413519335E-1L,\n-4.200263503402112910504E-2L,\n 6.558780715202536547116E-1L,\n 5.772156649015328608727E-1L,\n-1.000000000000000000000E0L,\n};\n\nstatic const long double PIL = 3.1415926535897932384626L;\n\n/* Gamma function computed by Stirling's formula.\n */\nstatic long double stirf(long double x)\n{\n\tlong double y, w, v;\n\n\tw = 1.0/x;\n\t/* For large x, use rational coefficients from the analytical expansion.  */\n\tif (x > 1024.0)\n\t\tw = (((((6.97281375836585777429E-5L * w\n\t\t + 7.84039221720066627474E-4L) * w\n\t\t - 2.29472093621399176955E-4L) * w\n\t\t - 2.68132716049382716049E-3L) * w\n\t\t + 3.47222222222222222222E-3L) * w\n\t\t + 8.33333333333333333333E-2L) * w\n\t\t + 1.0;\n\telse\n\t\tw = 1.0 + w * __polevll(w, STIR, 8);\n\ty = expl(x);\n\tif (x > MAXSTIR) { /* Avoid overflow in pow() */\n\t\tv = powl(x, 0.5L * x - 0.25L);\n\t\ty = v * (v / y);\n\t} else {\n\t\ty = powl(x, x - 0.5L) / y;\n\t}\n\ty = SQTPI * y * w;\n\treturn y;\n}\n\nlong double tgammal(long double x)\n{\n\tlong double p, q, z;\n\n\tif (!isfinite(x))\n\t\treturn x + INFINITY;\n\n\tq = fabsl(x);\n\tif (q > 13.0) {\n\t\tif (x < 0.0) {\n\t\t\tp = floorl(q);\n\t\t\tz = q - p;\n\t\t\tif (z == 0)\n\t\t\t\treturn 0 / z;\n\t\t\tif (q > MAXGAML) {\n\t\t\t\tz = 0;\n\t\t\t} else {\n\t\t\t\tif (z > 0.5) {\n\t\t\t\t\tp += 1.0;\n\t\t\t\t\tz = q - p;\n\t\t\t\t}\n\t\t\t\tz = q * sinl(PIL * z);\n\t\t\t\tz = fabsl(z) * stirf(q);\n\t\t\t\tz = PIL/z;\n\t\t\t}\n\t\t\tif (0.5 * p == floorl(q * 0.5))\n\t\t\t\tz = -z;\n\t\t} else if (x > MAXGAML) {\n\t\t\tz = x * 0x1p16383L;\n\t\t} else {\n\t\t\tz = stirf(x);\n\t\t}\n\t\treturn z;\n\t}\n\n\tz = 1.0;\n\twhile (x >= 3.0) {\n\t\tx -= 1.0;\n\t\tz *= x;\n\t}\n\twhile (x < -0.03125L) {\n\t\tz /= x;\n\t\tx += 1.0;\n\t}\n\tif (x <= 0.03125L)\n\t\tgoto small;\n\twhile (x < 2.0) {\n\t\tz /= x;\n\t\tx += 1.0;\n\t}\n\tif (x == 2.0)\n\t\treturn z;\n\n\tx -= 2.0;\n\tp = __polevll(x, P, 7);\n\tq = __polevll(x, Q, 8);\n\tz = z * p / q;\n\treturn z;\n\nsmall:\n\t/* z==1 if x was originally +-0 */\n\tif (x == 0 && z != 1)\n\t\treturn x / x;\n\tif (x < 0.0) {\n\t\tx = -x;\n\t\tq = z / (x * __polevll(x, SN, 8));\n\t} else\n\t\tq = z / (x * __polevll(x, S, 8));\n\treturn q;\n}\n#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384\n// TODO: broken implementation to make things compile\nlong double tgammal(long double x)\n{\n\treturn tgamma(x);\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/trunc.c",
    "content": "#include \"libm.h\"\n\ndouble trunc(double x)\n{\n\tunion {double f; uint64_t i;} u = {x};\n\tint e = (int)(u.i >> 52 & 0x7ff) - 0x3ff + 12;\n\tuint64_t m;\n\n\tif (e >= 52 + 12)\n\t\treturn x;\n\tif (e < 12)\n\t\te = 1;\n\tm = -1ULL >> e;\n\tif ((u.i & m) == 0)\n\t\treturn x;\n\tFORCE_EVAL(x + 0x1p120f);\n\tu.i &= ~m;\n\treturn u.f;\n}\n"
  },
  {
    "path": "user.libc/src/math/truncf.c",
    "content": "#include \"libm.h\"\n\nfloat truncf(float x)\n{\n\tunion {float f; uint32_t i;} u = {x};\n\tint e = (int)(u.i >> 23 & 0xff) - 0x7f + 9;\n\tuint32_t m;\n\n\tif (e >= 23 + 9)\n\t\treturn x;\n\tif (e < 9)\n\t\te = 1;\n\tm = -1U >> e;\n\tif ((u.i & m) == 0)\n\t\treturn x;\n\tFORCE_EVAL(x + 0x1p120f);\n\tu.i &= ~m;\n\treturn u.f;\n}\n"
  },
  {
    "path": "user.libc/src/math/truncl.c",
    "content": "#include \"libm.h\"\n\n#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024\nlong double truncl(long double x)\n{\n\treturn trunc(x);\n}\n#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384\n\nstatic const long double toint = 1/LDBL_EPSILON;\n\nlong double truncl(long double x)\n{\n\tunion ldshape u = {x};\n\tint e = u.i.se & 0x7fff;\n\tint s = u.i.se >> 15;\n\tlong double y;\n\n\tif (e >= 0x3fff+LDBL_MANT_DIG-1)\n\t\treturn x;\n\tif (e <= 0x3fff-1) {\n\t\tFORCE_EVAL(x + 0x1p120f);\n\t\treturn x*0;\n\t}\n\t/* y = int(|x|) - |x|, where int(|x|) is an integer neighbor of |x| */\n\tif (s)\n\t\tx = -x;\n\ty = x + toint - toint - x;\n\tif (y > 0)\n\t\ty -= 1;\n\tx += y;\n\treturn s ? -x : x;\n}\n#endif\n"
  },
  {
    "path": "user.libc/src/math/x32/fma.c",
    "content": "#include <math.h>\n\n#if __FMA__\n\ndouble fma(double x, double y, double z)\n{\n\t__asm__ (\"vfmadd132sd %1, %2, %0\" : \"+x\" (x) : \"x\" (y), \"x\" (z));\n\treturn x;\n}\n\n#elif __FMA4__\n\ndouble fma(double x, double y, double z)\n{\n\t__asm__ (\"vfmaddsd %3, %2, %1, %0\" : \"=x\" (x) : \"x\" (x), \"x\" (y), \"x\" (z));\n\treturn x;\n}\n\n#else\n\n#include \"../fma.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/x32/fmaf.c",
    "content": "#include <math.h>\n\n#if __FMA__\n\nfloat fmaf(float x, float y, float z)\n{\n\t__asm__ (\"vfmadd132ss %1, %2, %0\" : \"+x\" (x) : \"x\" (y), \"x\" (z));\n\treturn x;\n}\n\n#elif __FMA4__\n\nfloat fmaf(float x, float y, float z)\n{\n\t__asm__ (\"vfmaddss %3, %2, %1, %0\" : \"=x\" (x) : \"x\" (x), \"x\" (y), \"x\" (z));\n\treturn x;\n}\n\n#else\n\n#include \"../fmaf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/x86_64/fabs.c",
    "content": "#include <math.h>\n\ndouble fabs(double x)\n{\n\tdouble t;\n\t__asm__ (\"pcmpeqd %0, %0\" : \"=x\"(t));          // t = ~0\n\t__asm__ (\"psrlq   $1, %0\" : \"+x\"(t));          // t >>= 1\n\t__asm__ (\"andps   %1, %0\" : \"+x\"(x) : \"x\"(t)); // x &= t\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/x86_64/fabsf.c",
    "content": "#include <math.h>\n\nfloat fabsf(float x)\n{\n\tfloat t;\n\t__asm__ (\"pcmpeqd %0, %0\" : \"=x\"(t));          // t = ~0\n\t__asm__ (\"psrld   $1, %0\" : \"+x\"(t));          // t >>= 1\n\t__asm__ (\"andps   %1, %0\" : \"+x\"(x) : \"x\"(t)); // x &= t\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/x86_64/fabsl.c",
    "content": "#include <math.h>\n\nlong double fabsl(long double x)\n{\n\t__asm__ (\"fabs\" : \"+t\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/x86_64/fma.c",
    "content": "#include <math.h>\n\n#if __FMA__\n\ndouble fma(double x, double y, double z)\n{\n\t__asm__ (\"vfmadd132sd %1, %2, %0\" : \"+x\" (x) : \"x\" (y), \"x\" (z));\n\treturn x;\n}\n\n#elif __FMA4__\n\ndouble fma(double x, double y, double z)\n{\n\t__asm__ (\"vfmaddsd %3, %2, %1, %0\" : \"=x\" (x) : \"x\" (x), \"x\" (y), \"x\" (z));\n\treturn x;\n}\n\n#else\n\n#include \"../fma.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/x86_64/fmaf.c",
    "content": "#include <math.h>\n\n#if __FMA__\n\nfloat fmaf(float x, float y, float z)\n{\n\t__asm__ (\"vfmadd132ss %1, %2, %0\" : \"+x\" (x) : \"x\" (y), \"x\" (z));\n\treturn x;\n}\n\n#elif __FMA4__\n\nfloat fmaf(float x, float y, float z)\n{\n\t__asm__ (\"vfmaddss %3, %2, %1, %0\" : \"=x\" (x) : \"x\" (x), \"x\" (y), \"x\" (z));\n\treturn x;\n}\n\n#else\n\n#include \"../fmaf.c\"\n\n#endif\n"
  },
  {
    "path": "user.libc/src/math/x86_64/fmodl.c",
    "content": "#include <math.h>\n\nlong double fmodl(long double x, long double y)\n{\n\tunsigned short fpsr;\n\tdo __asm__ (\"fprem; fnstsw %%ax\" : \"+t\"(x), \"=a\"(fpsr) : \"u\"(y));\n\twhile (fpsr & 0x400);\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/x86_64/llrint.c",
    "content": "#include <math.h>\n\nlong long llrint(double x)\n{\n\tlong long r;\n\t__asm__ (\"cvtsd2si %1, %0\" : \"=r\"(r) : \"x\"(x));\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/src/math/x86_64/llrintf.c",
    "content": "#include <math.h>\n\nlong long llrintf(float x)\n{\n\tlong long r;\n\t__asm__ (\"cvtss2si %1, %0\" : \"=r\"(r) : \"x\"(x));\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/src/math/x86_64/llrintl.c",
    "content": "#include <math.h>\n\nlong long llrintl(long double x)\n{\n\tlong long r;\n\t__asm__ (\"fistpll %0\" : \"=m\"(r) : \"t\"(x) : \"st\");\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/src/math/x86_64/lrint.c",
    "content": "#include <math.h>\n\nlong lrint(double x)\n{\n\tlong r;\n\t__asm__ (\"cvtsd2si %1, %0\" : \"=r\"(r) : \"x\"(x));\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/src/math/x86_64/lrintf.c",
    "content": "#include <math.h>\n\nlong lrintf(float x)\n{\n\tlong r;\n\t__asm__ (\"cvtss2si %1, %0\" : \"=r\"(r) : \"x\"(x));\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/src/math/x86_64/lrintl.c",
    "content": "#include <math.h>\n\nlong lrintl(long double x)\n{\n\tlong r;\n\t__asm__ (\"fistpll %0\" : \"=m\"(r) : \"t\"(x) : \"st\");\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/src/math/x86_64/remainderl.c",
    "content": "#include <math.h>\n\nlong double remainderl(long double x, long double y)\n{\n\tunsigned short fpsr;\n\tdo __asm__ (\"fprem1; fnstsw %%ax\" : \"+t\"(x), \"=a\"(fpsr) : \"u\"(y));\n\twhile (fpsr & 0x400);\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/x86_64/remquol.c",
    "content": "#include <math.h>\n\nlong double remquol(long double x, long double y, int *quo)\n{\n\tsigned char *cx = (void *)&x, *cy = (void *)&y;\n\t/* By ensuring that addresses of x and y cannot be discarded,\n\t * this empty asm guides GCC into representing extraction of\n\t * their sign bits as memory loads rather than making x and y\n\t * not-address-taken internally and using bitfield operations,\n\t * which in the end wouldn't work out, as extraction from FPU\n\t * registers needs to go through memory anyway. This way GCC\n\t * should manage to use incoming stack slots without spills. */\n\t__asm__ (\"\" :: \"X\"(cx), \"X\"(cy));\n\n\tlong double t = x;\n\tunsigned fpsr;\n\tdo __asm__ (\"fprem1; fnstsw %%ax\" : \"+t\"(t), \"=a\"(fpsr) : \"u\"(y));\n\twhile (fpsr & 0x400);\n\t/* C0, C1, C3 flags in x87 status word carry low bits of quotient:\n\t * 15 14 13 12 11 10  9  8\n\t *  . C3  .  .  . C2 C1 C0\n\t *  . b1  .  .  .  0 b0 b2 */\n\tunsigned char i = fpsr >> 8;\n\ti = i>>4 | i<<4;\n\t/* i[5:2] is now {b0 b2 ? b1}. Retrieve {0 b2 b1 b0} via\n\t * in-register table lookup. */\n\tunsigned qbits = 0x7575313164642020 >> (i & 60);\n\tqbits &= 7;\n\n\t*quo = (cx[9]^cy[9]) < 0 ? -qbits : qbits;\n\treturn t;\n}\n"
  },
  {
    "path": "user.libc/src/math/x86_64/rintl.c",
    "content": "#include <math.h>\n\nlong double rintl(long double x)\n{\n\t__asm__ (\"frndint\" : \"+t\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/x86_64/sqrt.c",
    "content": "#include <math.h>\n\ndouble sqrt(double x)\n{\n\t__asm__ (\"sqrtsd %1, %0\" : \"=x\"(x) : \"x\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/x86_64/sqrtf.c",
    "content": "#include <math.h>\n\nfloat sqrtf(float x)\n{\n\t__asm__ (\"sqrtss %1, %0\" : \"=x\"(x) : \"x\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/math/x86_64/sqrtl.c",
    "content": "#include <math.h>\n\nlong double sqrtl(long double x)\n{\n\t__asm__ (\"fsqrt\" : \"+t\"(x));\n\treturn x;\n}\n"
  },
  {
    "path": "user.libc/src/minos/aarch64/aarch64_kobject.c",
    "content": "#include <stdlib.h>\n#include <stdint.h>\n\n#include \"stdio_impl.h\"\n#include \"aarch64_svc.h\"\n\nint kobject_close(int handle)\n{\n\treturn syscall(SYS_kobject_close, handle);\n}\n\nint kobject_create(int type, unsigned long data)\n{\n\treturn syscall(SYS_kobject_create, type, data);\n}\n\n/*\n * <  0 : failed\n * >= 0 : the token or other things for read/write\n */\nlong kobject_read(int handle, void *data, size_t data_size,\n\t\tsize_t *actual_data, void *extra, size_t extra_size,\n\t\tsize_t *actual_extra, uint32_t timeout)\n{\n\tstruct aarch64_svc_res res;\n\tlong ret;\n\n\taarch64_svc_call((unsigned long)handle, (unsigned long)data,\n\t\t\t(unsigned long)data_size, (unsigned long)extra,\n\t\t\t(unsigned long)extra_size, (unsigned long)timeout, 0,\n\t\t\tSYS_kobject_recv, &res);\n\n\tret = (long)res.a0;\n\n\tif (actual_data)\n\t\t*actual_data = (size_t)res.a1;\n\tif (actual_extra)\n\t\t*actual_extra = (size_t)res.a2;\n\n\treturn ret;\n}\n\nlong kobject_write(int handle, void *data, size_t data_size,\n\t\tvoid *extra, size_t extra_size, uint32_t timeout)\n{\n\treturn syscall(SYS_kobject_send, handle, data, data_size,\n\t\t\textra, extra_size, timeout);\n\n}\n\nint kobject_reply(int handle, long token, long err_code, int fd, int right)\n{\n\treturn syscall(SYS_kobject_reply, handle, token, err_code, fd, right);\n}\n\nint kobject_reply_errcode(int handle, long token, long err_code)\n{\n\treturn kobject_reply(handle, token, err_code, -1, 0);\n}\n\nint kobject_mmap(int handle, void **addr, size_t *msize)\n{\n\tstruct aarch64_svc_res res;\n\tint ret;\n\n\taarch64_svc_call((unsigned long)handle, 0, 0, 0, 0,\n\t\t\t0, 0, SYS_kobject_mmap, &res);\n\tret = (long)res.a0;\n\tif (addr)\n\t\t*addr = (void *)res.a1;\n\tif (msize)\n\t\t*msize = (size_t)res.a2;\n\n\treturn ret;\n}\n\nint kobject_munmap(int handle)\n{\n\treturn syscall(SYS_kobject_munmap, handle);\n}\n\nlong kobject_ctl(int handle, int action, unsigned long data)\n{\n\treturn syscall(SYS_kobject_ctl, handle, action, data);\n}\n\nint kobject_open(int handle)\n{\n\treturn syscall(SYS_kobject_open, handle);\n}\n"
  },
  {
    "path": "user.libc/src/minos/aarch64/aarch64_svc.S",
    "content": "/*\n * Copyright (c) 2021 Min Le (lemin9538@163.com)\n */\n\n\t.global aarch64_svc_call\n\n#include \"asm.inc\"\n\nfunc aarch64_svc_call\n\tmov\tx8, x7\n\tsvc\t#0\n\tldr\tx4, [sp]\n\tstp\tx0, x1, [x4, #0]\n\tstp\tx2, x3, [x4, #16]\n\tret\nendfunc aarch64_svc_call\n"
  },
  {
    "path": "user.libc/src/minos/aarch64/aarch64_svc.h",
    "content": "#ifndef __LIBC_AARCH64_SVC_H__\n#define __LIBC_AARCH64_SVC_H__\n\nstruct aarch64_svc_res {\n\tunsigned long a0;\n\tunsigned long a1;\n\tunsigned long a2;\n\tunsigned long a3;\n};\n\nvoid aarch64_svc_call(unsigned long a0, unsigned long a1, unsigned long a2,\n\t\tunsigned long a3, unsigned long a4, unsigned long a5,\n\t\tunsigned long a6, unsigned long svc_num_a7,\n\t\tstruct aarch64_svc_res *res);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/minos/brk.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n */\n\n#include <stdlib.h>\n#include <stdint.h>\n\n#include \"stdio_impl.h\"\n#include <sys/epoll.h>\n#include <minos/kobject.h>\n#include <minos/proto.h>\n\nuintptr_t __brk(uintptr_t ptr)\n{\n\tstruct proto proto;\n\n\tproto.proto_id = PROTO_BRK;\n\tproto.brk.addr = (void *)ptr;\n\n\treturn (uintptr_t)__syscall_ret(kobject_write(0, &proto,\n\t\t\tsizeof(struct proto), NULL, 0, -1));\n}\n"
  },
  {
    "path": "user.libc/src/minos/device.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n */\n\n#include <stdlib.h>\n#include <stdint.h>\n#include <string.h>\n\n#include \"stdio_impl.h\"\n#include \"libc.h\"\n#include <minos/proto.h>\n#include <minos/kobject.h>\n#include <minos/types.h>\n\nstatic int __request_device_resource(int id, const char *comp, int index)\n{\n\tstruct proto proto;\n\n\tif (libc.chiyou_handle <= 0)\n\t\treturn -EPERM;\n\n\tif (strlen(comp) >= FILENAME_MAX)\n\t\treturn -ENAMETOOLONG;\n\n\tproto.proto_id = id;\n\tproto.devinfo.key = 0;\n\tproto.devinfo.index = index;\n\n\treturn kobject_write(libc.chiyou_handle, &proto,\n\t\t\tsizeof(struct proto), (void *)comp, strlen(comp), -1);\n}\n\nint request_irq_by_handle(int handle)\n{\n\treturn kobject_open(handle);\n}\n\nint request_consequent_pma(size_t memsize, int right)\n{\n\treturn kobject_create_consequent_pma(memsize, right);\n}\n\nvoid *request_mmio_by_handle(int handle)\n{\n\tvoid *base;\n\n\tif (kobject_open(handle) < 0)\n\t\treturn (void *)-1;\n\n\tif (kobject_mmap(handle, &base, NULL))\n\t\t\treturn (void *)-1;\n\n\treturn base;\n}\n\nint get_device_mmio_handle(const char *comp, int index)\n{\n\treturn __request_device_resource(PROTO_GET_MMIO, comp, index);\n}\n\nint get_device_irq_handle(const char *comp, int index)\n{\n\treturn __request_device_resource(PROTO_GET_IRQ, comp, index);\n}\n"
  },
  {
    "path": "user.libc/src/minos/grant.c",
    "content": "#include <stdlib.h>\n#include <stdint.h>\n\n#include \"stdio_impl.h\"\n\nint grant(int proc, int handle, int right)\n{\n\treturn syscall(SYS_grant, proc, handle, right);\n}\n"
  },
  {
    "path": "user.libc/src/minos/kobject.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n */\n\n#include <stdlib.h>\n#include <stdint.h>\n\n#include \"stdio_impl.h\"\n#include <sys/epoll.h>\n#include <minos/kobject.h>\n#include <minos/types.h>\n\nint kobject_create_endpoint(size_t shmem_size)\n{\n\treturn kobject_create(KOBJ_TYPE_ENDPOINT, shmem_size);\n}\n\nint kobject_create_socket(size_t shmem_size)\n{\n\treturn kobject_create(KOBJ_TYPE_SOCKET, shmem_size);\n}\n\nint kobject_create_port(void)\n{\n\treturn kobject_create(KOBJ_TYPE_PORT, 0);\n}\n\nint kobject_create_notify(void)\n{\n\treturn kobject_create(KOBJ_TYPE_NOTIFY, 0);\n}\n\nstatic int __kobject_create_pma(size_t memsize, int consequent, int right)\n{\n\tstruct pma_create_arg args;\n\n\targs.size = memsize;\n\targs.right = right;\n\targs.consequent = consequent;\n\targs.type = PMA_TYPE_NORMAL;\n\targs.start = 0;\n\n\treturn kobject_create(KOBJ_TYPE_PMA, (unsigned long)&args);\n}\n\nint kobject_create_pma(size_t memsize, int right)\n{\n\treturn __kobject_create_pma(memsize, 0, right);\n}\n\nint kobject_create_consequent_pma(size_t memsize, int right)\n{\n\treturn __kobject_create_pma(memsize, 1, right);\n}\n"
  },
  {
    "path": "user.libc/src/minos/map.c",
    "content": "#include <stdlib.h>\n#include <stdint.h>\n\n#include \"stdio_impl.h\"\n\nint sys_map(int proc, int pma, unsigned long base, size_t size, int right)\n{\n\treturn syscall(SYS_map, proc, pma, base, size, right);\n}\n\nint sys_unmap(int proc, int pma, unsigned long base, size_t size)\n{\n\treturn syscall(SYS_unmap, proc, pma, base, size);\n}\n\nunsigned long sys_mtrans(unsigned long virt)\n{\n\treturn syscall(SYS_mtrans, virt);\n}\n"
  },
  {
    "path": "user.libc/src/minos/poll.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n */\n\n#include <stdlib.h>\n#include <stdint.h>\n\n#include \"stdio_impl.h\"\n#include <sys/epoll.h>\n#include <minos/kobject.h>\n\nint epoll_wait(int epfd, struct epoll_event *events,\n                      int maxevents, int timeout)\n{\n\tsize_t e, d;\n\tssize_t size;\n\tint ret;\n\n\t/*\n\t * currently only support EPOLLIN event\n\t */\n\tif ((events == NULL) || (maxevents <= 0))\n\t\treturn -EINVAL;\n\n\tsize = maxevents * sizeof(struct epoll_event);\n\tret = kobject_read(epfd, events, size, &d, NULL, 0, &e, timeout);\n\tif (ret < 0)\n\t\treturn ret;\n\telse if (d == 0)\n\t\treturn -EAGAIN;\n\n\treturn (d / sizeof(struct epoll_event));\n}\n\nint epoll_pwait(int epfd, struct epoll_event *events, int maxevents,\n\t\tint timeout, const sigset_t *sig)\n{\n\treturn -ENOSYS;\n}\n\nint epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)\n{\n\tif (!event)\n\t\treturn -EINVAL;\n\n\tif ((op != EPOLL_CTL_ADD) && (op != EPOLL_CTL_DEL) && (op != EPOLL_CTL_MOD))\n\t\treturn -EINVAL;\n\n\top += KOBJ_POLLHUB_OP_BASE;\n\tevent->data.fd = fd;\n\n\treturn kobject_ctl(epfd, op, (unsigned long)event);\n}\n\nint epoll_create(int size)\n{\n\treturn kobject_create(KOBJ_TYPE_POLLHUB, 0);\n}\n\nint epoll_create1(int flags)\n{\n\treturn epoll_create(0);\n}\n"
  },
  {
    "path": "user.libc/src/minos/procinfo.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n */\n\n#include <stdlib.h>\n#include <stdint.h>\n\n#include \"stdio_impl.h\"\n#include <sys/epoll.h>\n#include <minos/kobject.h>\n#include <minos/proto.h>\n\nint sys_proccnt(void)\n{\n\tstruct proto proto = {\n\t\t.proto_id = PROTO_PROCCNT,\n\t};\n\n\treturn sys_send_proto(0, &proto);\n}\n\nint sys_procinfo_handle(void)\n{\n\tstruct proto proto = {\n\t\t.proto_id = PROTO_PROCINFO,\n\t};\n\n\treturn sys_send_proto(0, &proto);\n}\n\nint sys_taskstat_handle(void)\n{\n\tstruct proto proto = {\n\t\t.proto_id = PROTO_TASKSTAT,\n\t};\n\n\treturn sys_send_proto(0, &proto);\n}\n"
  },
  {
    "path": "user.libc/src/minos/proto.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n */\n\n#include <stdlib.h>\n#include <stdint.h>\n\n#include \"stdio_impl.h\"\n#include \"pthread_impl.h\"\n#include <sys/epoll.h>\n\n#include <minos/proto.h>\n#include <minos/kobject.h>\n\n#define MODE_ANY 0\n#define MODE_STRING 1\n#define MODE_EQUAL 2\n\nstatic int __read_proto(int handle, struct proto *proto, char *extra,\n\t\tsize_t size, uint32_t timeout, int mode)\n{\n\tsize_t dsize, esize;\n\tlong token;\n\tint success;\n\n\ttoken = kobject_read(handle, proto, sizeof(struct proto),\n\t\t\t&dsize, extra, size, &esize, timeout);\n\tif (token < 0)\n\t\treturn (int)token;\n\n\tswitch (mode) {\n\tcase MODE_STRING:\n\t\tsuccess = (esize < size);\n\t\tbreak;\n\tcase MODE_EQUAL:\n\t\tsuccess = (esize == size);\n\t\tbreak;\n\tdefault:\n\t\tsuccess = (esize <= size);\n\t\tbreak;\n\t}\n\n\tif (!success) {\n\t\tkobject_reply(handle, token, -EINVAL, 0, 0);\n\t\treturn -EINVAL;\n\t}\n\n\tproto->token = token;\n\tif (mode == MODE_STRING)\n\t\textra[esize] = 0;\n\n\treturn 0;\n}\n\nint sys_read_proto_with_string(int handle, struct proto *proto,\n\t\tchar *extra, size_t size, uint32_t timeout)\n{\n\treturn __read_proto(handle, proto, extra, size, timeout, MODE_STRING);\n}\n\nint sys_read_proto(int handle, struct proto *proto,\n\t\tchar *extra, size_t size, uint32_t timeout)\n{\n\treturn __read_proto(handle, proto, extra, size, timeout, MODE_ANY);\n}\n\nstatic inline long __send_proto(int handle, struct proto *proto,\n\t\tvoid *data, size_t datasz, uint32_t timeout)\n{\n\treturn kobject_write(handle, proto, PROTO_SIZE,\n\t\t\tdata, datasz, timeout);\n}\n\nlong sys_send_proto(int handle, struct proto *proto)\n{\n\treturn __send_proto(handle, proto, NULL, 0, -1);\n}\n\nlong sys_send_proto_nonblock(int handle, struct proto *proto)\n{\n\treturn __send_proto(handle, proto, NULL, 0, 0);\n}\n\nlong sys_send_proto_timeout(int handle, struct proto *proto, uint32_t to)\n{\n\treturn __send_proto(handle, proto, NULL, 0, to);\n}\n\nlong sys_send_proto_with_data(int handle, struct proto *proto,\n\t\tvoid *data, size_t dsz, uint32_t to)\n{\n\treturn __send_proto(handle, proto, data, dsz, to);\n}\n\nvoid i_am_ok(void)\n{\n\tstruct proto proto;\n\n\tproto.proto_id = PROTO_IAMOK;\n\tkobject_write(self_handle(), &proto, PROTO_SIZE, NULL, 0, -1);\n}\n"
  },
  {
    "path": "user.libc/src/minos/service.c",
    "content": "#include <stdlib.h>\n#include <stdint.h>\n#include <string.h>\n\n#include \"stdio_impl.h\"\n#include <minos/kobject.h>\n#include <minos/proto.h>\n#include \"libc.h\"\n\nint register_service(const char *src, const char *target, int type, int flags)\n{\n\tchar string[FILENAME_MAX];\n\tstruct proto proto;\n\tchar *buf = string;\n\tint len, handle;\n\n\tlen = strlen(src) + strlen(target) + 2;\n\tif (len >= FILENAME_MAX)\n\t\treturn -ENAMETOOLONG;\n\n\tstrcpy(buf, src);\n\tbuf += strlen(src) + 1;\n\tstrcpy(buf, target);\n\n\tproto.proto_id = PROTO_REGISTER_SERVICE;\n\tproto.register_service.type = type;\n\tproto.register_service.flags = flags;\n\tproto.register_service.source_off = 0;\n\tproto.register_service.target_off = strlen(src) + 1;\n\n\thandle = kobject_write(libc.rootfs_handle, &proto,\n\t\t\tsizeof(struct proto), string, len, -1);\n\n\treturn handle;\n}\n\nint unregister_service(int fd)\n{\n\treturn kobject_close(fd);\n}\n"
  },
  {
    "path": "user.libc/src/minos/sys.c",
    "content": "/*\n * Copyright (c) 2020 - 2021 Min Le (lemin9538@163.com)\n */\n\n#include <stdlib.h>\n#include \"libc.h\"\n\nvoid libc_set_rootfs_handle(int handle)\n{\n\tlibc.rootfs_handle = handle;\n}\n"
  },
  {
    "path": "user.libc/src/minos/thread.c",
    "content": "#include <stdlib.h>\n#include <stdint.h>\n\n#include \"stdio_impl.h\"\n#include <minos/kobject.h>\n\nint create_thread(int (*fn)(void *), void *stack, int prio, int aff,\n\t\tint flags, void *tls, void *pdata)\n{\n#if 0\n\tstruct thread_create_arg args;\n\tint handle;\n\n\targs.fn = fn;\n\targs.user_sp = stack;\n\targs.prio = prio;\n\targs.aff = aff;\n\targs.flags = flags;\n\targs.pdata = pdata;\n\targs.tls = tls;\n\n\thandle = kobject_create(NULL, KOBJ_TYPE_THREAD,\n\t\t\tKOBJ_RIGHT_CTL | KOBJ_RIGHT_READ,\n\t\t\tKOBJ_RIGHT_CTL | KOBJ_RIGHT_READ,\n\t\t\t(unsigned long)&args);\n\tif (handle < 0)\n\t\treturn handle;\n\n\tkobject_ctl(handle, KOBJ_THREAD_OP_WAKEUP, 0);\n\n\treturn handle;\n#endif\n\treturn 0;\n}\n\n"
  },
  {
    "path": "user.libc/src/minos/yield.c",
    "content": "#include <stdlib.h>\n#include <stdint.h>\n\n#include \"stdio_impl.h\"\n\nvoid yield(void)\n{\n\tsyscall(SYS_yield);\n}\n"
  },
  {
    "path": "user.libc/src/misc/a64l.c",
    "content": "#include <stdlib.h>\n#include <string.h>\n#include <stdint.h>\n\nstatic const char digits[] =\n\t\"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n\nlong a64l(const char *s)\n{\n\tint e;\n\tuint32_t x = 0;\n\tfor (e=0; e<36 && *s; e+=6, s++) {\n\t\tconst char *d = strchr(digits, *s);\n\t\tif (!d) break;\n\t\tx |= (uint32_t)(d-digits)<<e;\n\t}\n\treturn (int32_t)x;\n}\n\nchar *l64a(long x0)\n{\n\tstatic char s[7];\n\tchar *p;\n\tuint32_t x = x0;\n\tfor (p=s; x; p++, x>>=6)\n\t\t*p = digits[x&63];\n\t*p = 0;\n\treturn s;\n}\n"
  },
  {
    "path": "user.libc/src/misc/basename.c",
    "content": "#include <string.h>\n#include <libgen.h>\n\nchar *basename(char *s)\n{\n\tsize_t i;\n\tif (!s || !*s) return \".\";\n\ti = strlen(s)-1;\n\tfor (; i&&s[i]=='/'; i--) s[i] = 0;\n\tfor (; i&&s[i-1]!='/'; i--);\n\treturn s+i;\n}\n\nweak_alias(basename, __xpg_basename);\n"
  },
  {
    "path": "user.libc/src/misc/dirname.c",
    "content": "#include <string.h>\n#include <libgen.h>\n\nchar *dirname(char *s)\n{\n\tsize_t i;\n\tif (!s || !*s) return \".\";\n\ti = strlen(s)-1;\n\tfor (; s[i]=='/'; i--) if (!i) return \"/\";\n\tfor (; s[i]!='/'; i--) if (!i) return \".\";\n\tfor (; s[i]=='/'; i--) if (!i) return \"/\";\n\ts[i+1] = 0;\n\treturn s;\n}\n"
  },
  {
    "path": "user.libc/src/misc/ffs.c",
    "content": "#include <strings.h>\n#include \"atomic.h\"\n\nint ffs(int i)\n{\n\treturn i ? a_ctz_l(i)+1 : 0;\n}\n"
  },
  {
    "path": "user.libc/src/misc/ffsl.c",
    "content": "#include <strings.h>\n#include \"atomic.h\"\n\nint ffsl(long i)\n{\n\treturn i ? a_ctz_l(i)+1 : 0;\n}\n"
  },
  {
    "path": "user.libc/src/misc/ffsll.c",
    "content": "#include <strings.h>\n#include \"atomic.h\"\n\nint ffsll(long long i)\n{\n\treturn i ? a_ctz_64(i)+1 : 0;\n}\n"
  },
  {
    "path": "user.libc/src/misc/fmtmsg.c",
    "content": "/* Public domain fmtmsg()\n * Written by Isaac Dunham, 2014\n */\n#include <fmtmsg.h>\n#include <fcntl.h>\n#include <unistd.h>\n#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n#include <pthread.h>\n\n/*\n * If lstr is the first part of bstr, check that the next char in bstr\n * is either \\0 or :\n */\nstatic int _strcolcmp(const char *lstr, const char *bstr)\n{\n\tsize_t i = 0;\n\twhile (lstr[i] && bstr[i] && (bstr[i] == lstr[i])) i++;\n\tif ( lstr[i] || (bstr[i] && bstr[i] != ':')) return 1;\n\treturn 0;\n}\n\nint fmtmsg(long classification, const char *label, int severity,\n           const char *text, const char *action, const char *tag)\n{\n\tint ret = 0, i, consolefd, verb = 0;\n\tchar *errstring = MM_NULLSEV, *cmsg = getenv(\"MSGVERB\");\n\tchar *const msgs[] = {\n\t\t\"label\", \"severity\", \"text\", \"action\", \"tag\", NULL\n\t};\n\tint cs;\n\n\tpthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);\n\n\tif (severity == MM_HALT) errstring = \"HALT: \";\n\telse if (severity == MM_ERROR) errstring = \"ERROR: \";\n\telse if (severity == MM_WARNING) errstring = \"WARNING: \";\n\telse if (severity == MM_INFO) errstring = \"INFO: \";\n\n\tif (classification & MM_CONSOLE) {\n\t\tconsolefd = open(\"/dev/console\", O_WRONLY);\n\t\tif (consolefd < 0) {\n\t\t\tret = MM_NOCON;\n\t\t} else {\n\t\t\tif (dprintf(consolefd, \"%s%s%s%s%s%s%s%s\\n\",\n\t\t\t            label?label:\"\", label?\": \":\"\",\n\t\t\t            severity?errstring:\"\", text?text:\"\",\n\t\t\t            action?\"\\nTO FIX: \":\"\",\n\t\t\t            action?action:\"\", action?\" \":\"\",\n\t\t\t            tag?tag:\"\" )<1)\n\t\t\t\tret = MM_NOCON;\n\t\t\tclose(consolefd);\n\t\t}\n\t}\n\n\tif (classification & MM_PRINT) {\n\t\twhile (cmsg && cmsg[0]) {\n\t\t\tfor(i=0; msgs[i]; i++) {\n\t\t\t\tif (!_strcolcmp(msgs[i], cmsg)) break;\n\t\t\t}\n\t\t\tif (msgs[i] == NULL) {\n\t\t\t\t//ignore MSGVERB-unrecognized component\n\t\t\t\tverb = 0xFF;\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tverb |= (1 << i);\n\t\t\t\tcmsg = strchr(cmsg, ':');\n\t\t\t\tif (cmsg) cmsg++;\n\t\t\t}\n\t\t}\n\t\tif (!verb) verb = 0xFF;\n\t\tif (dprintf(2, \"%s%s%s%s%s%s%s%s\\n\",\n\t\t            (verb&1 && label) ? label : \"\",\n\t\t            (verb&1 && label) ? \": \" : \"\",\n\t\t            (verb&2 && severity) ? errstring : \"\",\n\t\t            (verb&4 && text) ? text : \"\",\n\t\t            (verb&8 && action) ? \"\\nTO FIX: \" : \"\",\n\t\t            (verb&8 && action) ? action : \"\",\n\t\t            (verb&8 && action) ? \" \" : \"\",\n\t\t            (verb&16 && tag) ? tag : \"\" ) < 1)\n\t\t\tret |= MM_NOMSG;\n\t}\n\tif ((ret & (MM_NOCON|MM_NOMSG)) == (MM_NOCON|MM_NOMSG))\n\t\tret = MM_NOTOK;\n\n\tpthread_setcancelstate(cs, 0);\n\n\treturn ret;\n}\n"
  },
  {
    "path": "user.libc/src/misc/forkpty.c",
    "content": "#include <pty.h>\n#include <utmp.h>\n#include <unistd.h>\n#include <errno.h>\n#include <fcntl.h>\n#include <sys/wait.h>\n#include <pthread.h>\n\nint forkpty(int *pm, char *name, const struct termios *tio, const struct winsize *ws)\n{\n\tint m, s, ec=0, p[2], cs;\n\tpid_t pid=-1;\n\tsigset_t set, oldset;\n\n\tif (openpty(&m, &s, name, tio, ws) < 0) return -1;\n\n\tsigfillset(&set);\n\tpthread_sigmask(SIG_BLOCK, &set, &oldset);\n\tpthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);\n\n\tif (pipe2(p, O_CLOEXEC)) {\n\t\tclose(s);\n\t\tgoto out;\n\t}\n\n\tpid = fork();\n\tif (!pid) {\n\t\tclose(m);\n\t\tclose(p[0]);\n\t\tif (login_tty(s)) {\n\t\t\twrite(p[1], &errno, sizeof errno);\n\t\t\t_exit(127);\n\t\t}\n\t\tclose(p[1]);\n\t\tpthread_setcancelstate(cs, 0);\n\t\tpthread_sigmask(SIG_SETMASK, &oldset, 0);\n\t\treturn 0;\n\t}\n\tclose(s);\n\tclose(p[1]);\n\tif (read(p[0], &ec, sizeof ec) > 0) {\n\t\tint status;\n\t\twaitpid(pid, &status, 0);\n\t\tpid = -1;\n\t\terrno = ec;\n\t}\n\tclose(p[0]);\n\nout:\n\tif (pid > 0) *pm = m;\n\telse close(m);\n\n\tpthread_setcancelstate(cs, 0);\n\tpthread_sigmask(SIG_SETMASK, &oldset, 0);\n\n\treturn pid;\n}\n"
  },
  {
    "path": "user.libc/src/misc/get_current_dir_name.c",
    "content": "#define _GNU_SOURCE\n#include <stdlib.h>\n#include <string.h>\n#include <limits.h>\n#include <unistd.h>\n#include <sys/stat.h>\n\nchar *get_current_dir_name(void) {\n\tstruct stat a, b;\n\tchar *res = getenv(\"PWD\");\n\tif (res && *res && !stat(res, &a) && !stat(\".\", &b)\n\t    && (a.st_dev == b.st_dev) && (a.st_ino == b.st_ino))\n\t\treturn strdup(res);\n\treturn getcwd(0, 0);\n}\n"
  },
  {
    "path": "user.libc/src/misc/getauxval.c",
    "content": "#include <sys/auxv.h>\n#include <errno.h>\n#include \"libc.h\"\n\nunsigned long __getauxval(unsigned long item)\n{\n\tsize_t *auxv = libc.auxv;\n\tif (item == AT_SECURE) return libc.secure;\n\tfor (; *auxv; auxv+=2)\n\t\tif (*auxv==item) return auxv[1];\n\terrno = ENOENT;\n\treturn 0;\n}\n\nweak_alias(__getauxval, getauxval);\n"
  },
  {
    "path": "user.libc/src/misc/getdomainname.c",
    "content": "#define _GNU_SOURCE\n#include <unistd.h>\n#include <sys/utsname.h>\n#include <string.h>\n#include <errno.h>\n\nint getdomainname(char *name, size_t len)\n{\n\tstruct utsname temp;\n\tuname(&temp);\n\tif (!len || strlen(temp.domainname) >= len) {\n\t\terrno = EINVAL;\n\t\treturn -1;\n\t}\n\tstrcpy(name, temp.domainname);\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/misc/getentropy.c",
    "content": "#define _BSD_SOURCE\n#include <unistd.h>\n#include <sys/random.h>\n#include <pthread.h>\n#include <errno.h>\n\nint getentropy(void *buffer, size_t len)\n{\n\tint cs, ret = 0;\n\tchar *pos = buffer;\n\n\tif (len > 256) {\n\t\terrno = EIO;\n\t\treturn -1;\n\t}\n\n\tpthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);\n\n\twhile (len) {\n\t\tret = getrandom(pos, len, 0);\n\t\tif (ret < 0) {\n\t\t\tif (errno == EINTR) continue;\n\t\t\telse break;\n\t\t}\n\t\tpos += ret;\n\t\tlen -= ret;\n\t\tret = 0;\n\t}\n\n\tpthread_setcancelstate(cs, 0);\n\n\treturn ret;\n}\n"
  },
  {
    "path": "user.libc/src/misc/gethostid.c",
    "content": "#include <unistd.h>\n\nlong gethostid()\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/misc/getopt.c",
    "content": "#define _BSD_SOURCE\n#include <unistd.h>\n#include <wchar.h>\n#include <string.h>\n#include <limits.h>\n#include <stdlib.h>\n#include \"locale_impl.h\"\n#include \"stdio_impl.h\"\n\nchar *optarg;\nint optind=1, opterr=1, optopt, __optpos, __optreset=0;\n\n#define optpos __optpos\nweak_alias(__optreset, optreset);\n\nvoid __getopt_msg(const char *a, const char *b, const char *c, size_t l)\n{\n\tFILE *f = stderr;\n\tb = __lctrans_cur(b);\n\tFLOCK(f);\n\tfputs(a, f)>=0\n\t&& fwrite(b, strlen(b), 1, f)\n\t&& fwrite(c, 1, l, f)==l\n\t&& putc('\\n', f);\n\tFUNLOCK(f);\n}\n\nint getopt(int argc, char * const argv[], const char *optstring)\n{\n\tint i;\n\twchar_t c, d;\n\tint k, l;\n\tchar *optchar;\n\n\tif (!optind || __optreset) {\n\t\t__optreset = 0;\n\t\t__optpos = 0;\n\t\toptind = 1;\n\t}\n\n\tif (optind >= argc || !argv[optind])\n\t\treturn -1;\n\n\tif (argv[optind][0] != '-') {\n\t\tif (optstring[0] == '-') {\n\t\t\toptarg = argv[optind++];\n\t\t\treturn 1;\n\t\t}\n\t\treturn -1;\n\t}\n\n\tif (!argv[optind][1])\n\t\treturn -1;\n\n\tif (argv[optind][1] == '-' && !argv[optind][2])\n\t\treturn optind++, -1;\n\n\tif (!optpos) optpos++;\n\tif ((k = mbtowc(&c, argv[optind]+optpos, MB_LEN_MAX)) < 0) {\n\t\tk = 1;\n\t\tc = 0xfffd; /* replacement char */\n\t}\n\toptchar = argv[optind]+optpos;\n\toptpos += k;\n\n\tif (!argv[optind][optpos]) {\n\t\toptind++;\n\t\toptpos = 0;\n\t}\n\n\tif (optstring[0] == '-' || optstring[0] == '+')\n\t\toptstring++;\n\n\ti = 0;\n\td = 0;\n\tdo {\n\t\tl = mbtowc(&d, optstring+i, MB_LEN_MAX);\n\t\tif (l>0) i+=l; else i++;\n\t} while (l && d != c);\n\n\tif (d != c || c == ':') {\n\t\toptopt = c;\n\t\tif (optstring[0] != ':' && opterr)\n\t\t\t__getopt_msg(argv[0], \": unrecognized option: \", optchar, k);\n\t\treturn '?';\n\t}\n\tif (optstring[i] == ':') {\n\t\toptarg = 0;\n\t\tif (optstring[i+1] != ':' || optpos) {\n\t\t\toptarg = argv[optind++] + optpos;\n\t\t\toptpos = 0;\n\t\t}\n\t\tif (optind > argc) {\n\t\t\toptopt = c;\n\t\t\tif (optstring[0] == ':') return ':';\n\t\t\tif (opterr) __getopt_msg(argv[0],\n\t\t\t\t\": option requires an argument: \",\n\t\t\t\toptchar, k);\n\t\t\treturn '?';\n\t\t}\n\t}\n\treturn c;\n}\n\nweak_alias(getopt, __posix_getopt);\n"
  },
  {
    "path": "user.libc/src/misc/getopt_long.c",
    "content": "#define _GNU_SOURCE\n#include <stddef.h>\n#include <stdlib.h>\n#include <limits.h>\n#include <getopt.h>\n#include <stdio.h>\n#include <string.h>\n#include \"stdio_impl.h\"\n\nextern int __optpos, __optreset;\n\nstatic void permute(char *const *argv, int dest, int src)\n{\n\tchar **av = (char **)argv;\n\tchar *tmp = av[src];\n\tint i;\n\tfor (i=src; i>dest; i--)\n\t\tav[i] = av[i-1];\n\tav[dest] = tmp;\n}\n\nstatic int __getopt_long_core(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly);\n\nstatic int __getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly)\n{\n\tint ret, skipped, resumed;\n\tif (!optind || __optreset) {\n\t\t__optreset = 0;\n\t\t__optpos = 0;\n\t\toptind = 1;\n\t}\n\tif (optind >= argc || !argv[optind]) return -1;\n\tskipped = optind;\n\tif (optstring[0] != '+' && optstring[0] != '-') {\n\t\tint i;\n\t\tfor (i=optind; ; i++) {\n\t\t\tif (i >= argc || !argv[i]) return -1;\n\t\t\tif (argv[i][0] == '-' && argv[i][1]) break;\n\t\t}\n\t\toptind = i;\n\t}\n\tresumed = optind;\n\tret = __getopt_long_core(argc, argv, optstring, longopts, idx, longonly);\n\tif (resumed > skipped) {\n\t\tint i, cnt = optind-resumed;\n\t\tfor (i=0; i<cnt; i++)\n\t\t\tpermute(argv, skipped, optind-1);\n\t\toptind = skipped + cnt;\n\t}\n\treturn ret;\n}\n\nstatic int __getopt_long_core(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly)\n{\n\toptarg = 0;\n\tif (longopts && argv[optind][0] == '-' &&\n\t\t((longonly && argv[optind][1] && argv[optind][1] != '-') ||\n\t\t (argv[optind][1] == '-' && argv[optind][2])))\n\t{\n\t\tint colon = optstring[optstring[0]=='+'||optstring[0]=='-']==':';\n\t\tint i, cnt, match;\n\t\tchar *arg, *opt, *start = argv[optind]+1;\n\t\tfor (cnt=i=0; longopts[i].name; i++) {\n\t\t\tconst char *name = longopts[i].name;\n\t\t\topt = start;\n\t\t\tif (*opt == '-') opt++;\n\t\t\twhile (*opt && *opt != '=' && *opt == *name)\n\t\t\t\tname++, opt++;\n\t\t\tif (*opt && *opt != '=') continue;\n\t\t\targ = opt;\n\t\t\tmatch = i;\n\t\t\tif (!*name) {\n\t\t\t\tcnt = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcnt++;\n\t\t}\n\t\tif (cnt==1 && longonly && arg-start == mblen(start, MB_LEN_MAX)) {\n\t\t\tint l = arg-start;\n\t\t\tfor (i=0; optstring[i]; i++) {\n\t\t\t\tint j;\n\t\t\t\tfor (j=0; j<l && start[j]==optstring[i+j]; j++);\n\t\t\t\tif (j==l) {\n\t\t\t\t\tcnt++;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (cnt==1) {\n\t\t\ti = match;\n\t\t\topt = arg;\n\t\t\toptind++;\n\t\t\tif (*opt == '=') {\n\t\t\t\tif (!longopts[i].has_arg) {\n\t\t\t\t\toptopt = longopts[i].val;\n\t\t\t\t\tif (colon || !opterr)\n\t\t\t\t\t\treturn '?';\n\t\t\t\t\t__getopt_msg(argv[0],\n\t\t\t\t\t\t\": option does not take an argument: \",\n\t\t\t\t\t\tlongopts[i].name,\n\t\t\t\t\t\tstrlen(longopts[i].name));\n\t\t\t\t\treturn '?';\n\t\t\t\t}\n\t\t\t\toptarg = opt+1;\n\t\t\t} else if (longopts[i].has_arg == required_argument) {\n\t\t\t\tif (!(optarg = argv[optind])) {\n\t\t\t\t\toptopt = longopts[i].val;\n\t\t\t\t\tif (colon) return ':';\n\t\t\t\t\tif (!opterr) return '?';\n\t\t\t\t\t__getopt_msg(argv[0],\n\t\t\t\t\t\t\": option requires an argument: \",\n\t\t\t\t\t\tlongopts[i].name,\n\t\t\t\t\t\tstrlen(longopts[i].name));\n\t\t\t\t\treturn '?';\n\t\t\t\t}\n\t\t\t\toptind++;\n\t\t\t}\n\t\t\tif (idx) *idx = i;\n\t\t\tif (longopts[i].flag) {\n\t\t\t\t*longopts[i].flag = longopts[i].val;\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\treturn longopts[i].val;\n\t\t}\n\t\tif (argv[optind][1] == '-') {\n\t\t\toptopt = 0;\n\t\t\tif (!colon && opterr)\n\t\t\t\t__getopt_msg(argv[0], cnt ?\n\t\t\t\t\t\": option is ambiguous: \" :\n\t\t\t\t\t\": unrecognized option: \",\n\t\t\t\t\targv[optind]+2,\n\t\t\t\t\tstrlen(argv[optind]+2));\n\t\t\toptind++;\n\t\t\treturn '?';\n\t\t}\n\t}\n\treturn getopt(argc, argv, optstring);\n}\n\nint getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx)\n{\n\treturn __getopt_long(argc, argv, optstring, longopts, idx, 0);\n}\n\nint getopt_long_only(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx)\n{\n\treturn __getopt_long(argc, argv, optstring, longopts, idx, 1);\n}\n"
  },
  {
    "path": "user.libc/src/misc/getsubopt.c",
    "content": "#include <stdlib.h>\n#include <string.h>\n\nint getsubopt(char **opt, char *const *keys, char **val)\n{\n\tchar *s = *opt;\n\tint i;\n\n\t*val = NULL;\n\t*opt = strchr(s, ',');\n\tif (*opt) *(*opt)++ = 0;\n\telse *opt = s + strlen(s);\n\n\tfor (i=0; keys[i]; i++) {\n\t\tsize_t l = strlen(keys[i]);\n\t\tif (strncmp(keys[i], s, l)) continue;\n\t\tif (s[l] == '=')\n\t\t\t*val = s + l + 1;\n\t\telse if (s[l]) continue;\n\t\treturn i;\n\t}\n\treturn -1;\n}\n"
  },
  {
    "path": "user.libc/src/misc/initgroups.c",
    "content": "#define _GNU_SOURCE\n#include <grp.h>\n#include <limits.h>\n\nint initgroups(const char *user, gid_t gid)\n{\n\tgid_t groups[NGROUPS_MAX];\n\tint count = NGROUPS_MAX;\n\tif (getgrouplist(user, gid, groups, &count) < 0) return -1;\n\treturn setgroups(count, groups);\n}\n"
  },
  {
    "path": "user.libc/src/misc/issetugid.c",
    "content": "#define _BSD_SOURCE\n#include <unistd.h>\n#include \"libc.h\"\n\nint issetugid(void)\n{\n\treturn libc.secure;\n}\n"
  },
  {
    "path": "user.libc/src/misc/lockf.c",
    "content": "#include <unistd.h>\n#include <fcntl.h>\n#include <errno.h>\n\nint lockf(int fd, int op, off_t size)\n{\n\tstruct flock l = {\n\t\t.l_type = F_WRLCK,\n\t\t.l_whence = SEEK_CUR,\n\t\t.l_len = size,\n\t};\n\tswitch (op) {\n\tcase F_TEST:\n\t\tl.l_type = F_RDLCK;\n\t\tif (fcntl(fd, F_GETLK, &l) < 0)\n\t\t\treturn -1;\n\t\tif (l.l_type == F_UNLCK || l.l_pid == getpid())\n\t\t\treturn 0;\n\t\terrno = EACCES;\n\t\treturn -1;\n\tcase F_ULOCK:\n\t\tl.l_type = F_UNLCK;\n\tcase F_TLOCK:\n\t\treturn fcntl(fd, F_SETLK, &l);\n\tcase F_LOCK:\n\t\treturn fcntl(fd, F_SETLKW, &l);\n\t}\n\terrno = EINVAL;\n\treturn -1;\n}\n\nweak_alias(lockf, lockf64);\n"
  },
  {
    "path": "user.libc/src/misc/login_tty.c",
    "content": "#include <utmp.h>\n#include <sys/ioctl.h>\n#include <unistd.h>\n\nint login_tty(int fd)\n{\n\tsetsid();\n\tif (ioctl(fd, TIOCSCTTY, (char *)0)) return -1;\n\tdup2(fd, 0);\n\tdup2(fd, 1);\n\tdup2(fd, 2);\n\tif (fd>2) close(fd);\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/misc/mntent.c",
    "content": "#include <stdio.h>\n#include <string.h>\n#include <mntent.h>\n#include <errno.h>\n\nstatic char *internal_buf;\nstatic size_t internal_bufsize;\n\n#define SENTINEL (char *)&internal_buf\n\nFILE *setmntent(const char *name, const char *mode)\n{\n\treturn fopen(name, mode);\n}\n\nint endmntent(FILE *f)\n{\n\tif (f) fclose(f);\n\treturn 1;\n}\n\nstruct mntent *getmntent_r(FILE *f, struct mntent *mnt, char *linebuf, int buflen)\n{\n\tint cnt, n[8], use_internal = (linebuf == SENTINEL);\n\n\tmnt->mnt_freq = 0;\n\tmnt->mnt_passno = 0;\n\n\tdo {\n\t\tif (use_internal) {\n\t\t\tgetline(&internal_buf, &internal_bufsize, f);\n\t\t\tlinebuf = internal_buf;\n\t\t} else {\n\t\t\tfgets(linebuf, buflen, f);\n\t\t}\n\t\tif (feof(f) || ferror(f)) return 0;\n\t\tif (!strchr(linebuf, '\\n')) {\n\t\t\tfscanf(f, \"%*[^\\n]%*[\\n]\");\n\t\t\terrno = ERANGE;\n\t\t\treturn 0;\n\t\t}\n\t\tcnt = sscanf(linebuf, \" %n%*s%n %n%*s%n %n%*s%n %n%*s%n %d %d\",\n\t\t\tn, n+1, n+2, n+3, n+4, n+5, n+6, n+7,\n\t\t\t&mnt->mnt_freq, &mnt->mnt_passno);\n\t} while (cnt < 2 || linebuf[n[0]] == '#');\n\n\tlinebuf[n[1]] = 0;\n\tlinebuf[n[3]] = 0;\n\tlinebuf[n[5]] = 0;\n\tlinebuf[n[7]] = 0;\n\n\tmnt->mnt_fsname = linebuf+n[0];\n\tmnt->mnt_dir = linebuf+n[2];\n\tmnt->mnt_type = linebuf+n[4];\n\tmnt->mnt_opts = linebuf+n[6];\n\n\treturn mnt;\n}\n\nstruct mntent *getmntent(FILE *f)\n{\n\tstatic struct mntent mnt;\n\treturn getmntent_r(f, &mnt, SENTINEL, 0);\n}\n\nint addmntent(FILE *f, const struct mntent *mnt)\n{\n\tif (fseek(f, 0, SEEK_END)) return 1;\n\treturn fprintf(f, \"%s\\t%s\\t%s\\t%s\\t%d\\t%d\\n\",\n\t\tmnt->mnt_fsname, mnt->mnt_dir, mnt->mnt_type, mnt->mnt_opts,\n\t\tmnt->mnt_freq, mnt->mnt_passno) < 0;\n}\n\nchar *hasmntopt(const struct mntent *mnt, const char *opt)\n{\n\treturn strstr(mnt->mnt_opts, opt);\n}\n"
  },
  {
    "path": "user.libc/src/misc/nftw.c",
    "content": "#include <ftw.h>\n#include <dirent.h>\n#include <fcntl.h>\n#include <sys/stat.h>\n#include <errno.h>\n#include <unistd.h>\n#include <string.h>\n#include <limits.h>\n#include <pthread.h>\n\nstruct history\n{\n\tstruct history *chain;\n\tdev_t dev;\n\tino_t ino;\n\tint level;\n\tint base;\n};\n\n#undef dirfd\n#define dirfd(d) (*(int *)d)\n\nstatic int do_nftw(char *path, int (*fn)(const char *, const struct stat *, int, struct FTW *), int fd_limit, int flags, struct history *h)\n{\n\tsize_t l = strlen(path), j = l && path[l-1]=='/' ? l-1 : l;\n\tstruct stat st;\n\tstruct history new;\n\tint type;\n\tint r;\n\tint dfd;\n\tint err;\n\tstruct FTW lev;\n\n\tif ((flags & FTW_PHYS) ? lstat(path, &st) : stat(path, &st) < 0) {\n\t\tif (!(flags & FTW_PHYS) && errno==ENOENT && !lstat(path, &st))\n\t\t\ttype = FTW_SLN;\n\t\telse if (errno != EACCES) return -1;\n\t\telse type = FTW_NS;\n\t} else if (S_ISDIR(st.st_mode)) {\n\t\tif (flags & FTW_DEPTH) type = FTW_DP;\n\t\telse type = FTW_D;\n\t} else if (S_ISLNK(st.st_mode)) {\n\t\tif (flags & FTW_PHYS) type = FTW_SL;\n\t\telse type = FTW_SLN;\n\t} else {\n\t\ttype = FTW_F;\n\t}\n\n\tif ((flags & FTW_MOUNT) && h && st.st_dev != h->dev)\n\t\treturn 0;\n\t\n\tnew.chain = h;\n\tnew.dev = st.st_dev;\n\tnew.ino = st.st_ino;\n\tnew.level = h ? h->level+1 : 0;\n\tnew.base = j+1;\n\t\n\tlev.level = new.level;\n\tif (h) {\n\t\tlev.base = h->base;\n\t} else {\n\t\tsize_t k;\n\t\tfor (k=j; k && path[k]=='/'; k--);\n\t\tfor (; k && path[k-1]!='/'; k--);\n\t\tlev.base = k;\n\t}\n\n\tif (type == FTW_D || type == FTW_DP) {\n\t\tdfd = open(path, O_RDONLY);\n\t\terr = errno;\n\t\tif (dfd < 0 && err == EACCES) type = FTW_DNR;\n\t\tif (!fd_limit) close(dfd);\n\t}\n\n\tif (!(flags & FTW_DEPTH) && (r=fn(path, &st, type, &lev)))\n\t\treturn r;\n\n\tfor (; h; h = h->chain)\n\t\tif (h->dev == st.st_dev && h->ino == st.st_ino)\n\t\t\treturn 0;\n\n\tif ((type == FTW_D || type == FTW_DP) && fd_limit) {\n\t\tif (dfd < 0) {\n\t\t\terrno = err;\n\t\t\treturn -1;\n\t\t}\n\t\tDIR *d = fdopendir(dfd);\n\t\tif (d) {\n\t\t\tstruct dirent *de;\n\t\t\twhile ((de = readdir(d))) {\n\t\t\t\tif (de->d_name[0] == '.'\n\t\t\t\t && (!de->d_name[1]\n\t\t\t\t  || (de->d_name[1]=='.'\n\t\t\t\t   && !de->d_name[2]))) continue;\n\t\t\t\tif (strlen(de->d_name) >= PATH_MAX-l) {\n\t\t\t\t\terrno = ENAMETOOLONG;\n\t\t\t\t\tclosedir(d);\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t\tpath[j]='/';\n\t\t\t\tstrcpy(path+j+1, de->d_name);\n\t\t\t\tif ((r=do_nftw(path, fn, fd_limit-1, flags, &new))) {\n\t\t\t\t\tclosedir(d);\n\t\t\t\t\treturn r;\n\t\t\t\t}\n\t\t\t}\n\t\t\tclosedir(d);\n\t\t} else {\n\t\t\tclose(dfd);\n\t\t\treturn -1;\n\t\t}\n\t}\n\n\tpath[l] = 0;\n\tif ((flags & FTW_DEPTH) && (r=fn(path, &st, type, &lev)))\n\t\treturn r;\n\n\treturn 0;\n}\n\nint nftw(const char *path, int (*fn)(const char *, const struct stat *, int, struct FTW *), int fd_limit, int flags)\n{\n\tint r, cs;\n\tsize_t l;\n\tchar pathbuf[PATH_MAX+1];\n\n\tif (fd_limit <= 0) return 0;\n\n\tl = strlen(path);\n\tif (l > PATH_MAX) {\n\t\terrno = ENAMETOOLONG;\n\t\treturn -1;\n\t}\n\tmemcpy(pathbuf, path, l+1);\n\t\n\tpthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);\n\tr = do_nftw(pathbuf, fn, fd_limit, flags, NULL);\n\tpthread_setcancelstate(cs, 0);\n\treturn r;\n}\n\nweak_alias(nftw, nftw64);\n"
  },
  {
    "path": "user.libc/src/misc/openpty.c",
    "content": "#include <stdlib.h>\n#include <fcntl.h>\n#include <unistd.h>\n#include <pty.h>\n#include <stdio.h>\n#include <pthread.h>\n\n/* Nonstandard, but vastly superior to the standard functions */\n\nint openpty(int *pm, int *ps, char *name, const struct termios *tio, const struct winsize *ws)\n{\n\tint m, s, n=0, cs;\n\tchar buf[20];\n\n\tm = open(\"/dev/ptmx\", O_RDWR|O_NOCTTY);\n\tif (m < 0) return -1;\n\n\tpthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);\n\n\tif (ioctl(m, TIOCSPTLCK, &n) || ioctl (m, TIOCGPTN, &n))\n\t\tgoto fail;\n\n\tif (!name) name = buf;\n\tsnprintf(name, sizeof buf, \"/dev/pts/%d\", n);\n\tif ((s = open(name, O_RDWR|O_NOCTTY)) < 0)\n\t\tgoto fail;\n\n\tif (tio) tcsetattr(s, TCSANOW, tio);\n\tif (ws) ioctl(s, TIOCSWINSZ, ws);\n\n\t*pm = m;\n\t*ps = s;\n\n\tpthread_setcancelstate(cs, 0);\n\treturn 0;\nfail:\n\tclose(m);\n\tpthread_setcancelstate(cs, 0);\n\treturn -1;\n}\n"
  },
  {
    "path": "user.libc/src/misc/ptsname.c",
    "content": "#include <stdlib.h>\n#include <errno.h>\n\nchar *ptsname(int fd)\n{\n\tstatic char buf[9 + sizeof(int)*3 + 1];\n\tint err = __ptsname_r(fd, buf, sizeof buf);\n\tif (err) {\n\t\terrno = err;\n\t\treturn 0;\n\t}\n\treturn buf;\n}\n"
  },
  {
    "path": "user.libc/src/misc/realpath.c",
    "content": "#include <stdlib.h>\n#include <limits.h>\n#include <errno.h>\n#include <unistd.h>\n#include <string.h>\n\nstatic size_t slash_len(const char *s)\n{\n\tconst char *s0 = s;\n\twhile (*s == '/') s++;\n\treturn s-s0;\n}\n\nchar *realpath(const char *restrict filename, char *restrict resolved)\n{\n\tchar stack[PATH_MAX+1];\n\tchar output[PATH_MAX];\n\tsize_t p, q, l, l0, cnt=0, nup=0;\n\tint check_dir=0;\n\n\tif (!filename) {\n\t\terrno = EINVAL;\n\t\treturn 0;\n\t}\n\tl = strnlen(filename, sizeof stack);\n\tif (!l) {\n\t\terrno = ENOENT;\n\t\treturn 0;\n\t}\n\tif (l >= PATH_MAX) goto toolong;\n\tp = sizeof stack - l - 1;\n\tq = 0;\n\tmemcpy(stack+p, filename, l+1);\n\n\t/* Main loop. Each iteration pops the next part from stack of\n\t * remaining path components and consumes any slashes that follow.\n\t * If not a link, it's moved to output; if a link, contents are\n\t * pushed to the stack. */\nrestart:\n\tfor (; ; p+=slash_len(stack+p)) {\n\t\t/* If stack starts with /, the whole component is / or //\n\t\t * and the output state must be reset. */\n\t\tif (stack[p] == '/') {\n\t\t\tcheck_dir=0;\n\t\t\tnup=0;\n\t\t\tq=0;\n\t\t\toutput[q++] = '/';\n\t\t\tp++;\n\t\t\t/* Initial // is special. */\n\t\t\tif (stack[p] == '/' && stack[p+1] != '/')\n\t\t\t\toutput[q++] = '/';\n\t\t\tcontinue;\n\t\t}\n\n\t\tchar *z = __strchrnul(stack+p, '/');\n\t\tl0 = l = z-(stack+p);\n\n\t\tif (!l && !check_dir) break;\n\n\t\t/* Skip any . component but preserve check_dir status. */\n\t\tif (l==1 && stack[p]=='.') {\n\t\t\tp += l;\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* Copy next component onto output at least temporarily, to\n\t\t * call readlink, but wait to advance output position until\n\t\t * determining it's not a link. */\n\t\tif (q && output[q-1] != '/') {\n\t\t\tif (!p) goto toolong;\n\t\t\tstack[--p] = '/';\n\t\t\tl++;\n\t\t}\n\t\tif (q+l >= PATH_MAX) goto toolong;\n\t\tmemcpy(output+q, stack+p, l);\n\t\toutput[q+l] = 0;\n\t\tp += l;\n\n\t\tint up = 0;\n\t\tif (l0==2 && stack[p-2]=='.' && stack[p-1]=='.') {\n\t\t\tup = 1;\n\t\t\t/* Any non-.. path components we could cancel start\n\t\t\t * after nup repetitions of the 3-byte string \"../\";\n\t\t\t * if there are none, accumulate .. components to\n\t\t\t * later apply to cwd, if needed. */\n\t\t\tif (q <= 3*nup) {\n\t\t\t\tnup++;\n\t\t\t\tq += l;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t/* When previous components are already known to be\n\t\t\t * directories, processing .. can skip readlink. */\n\t\t\tif (!check_dir) goto skip_readlink;\n\t\t}\n\t\tssize_t k = readlink(output, stack, p);\n\t\tif (k==p) goto toolong;\n\t\tif (!k) {\n\t\t\terrno = ENOENT;\n\t\t\treturn 0;\n\t\t}\n\t\tif (k<0) {\n\t\t\tif (errno != EINVAL) return 0;\nskip_readlink:\n\t\t\tcheck_dir = 0;\n\t\t\tif (up) {\n\t\t\t\twhile(q && output[q-1]!='/') q--;\n\t\t\t\tif (q>1 && (q>2 || output[0]!='/')) q--;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (l0) q += l;\n\t\t\tcheck_dir = stack[p];\n\t\t\tcontinue;\n\t\t}\n\t\tif (++cnt == SYMLOOP_MAX) {\n\t\t\terrno = ELOOP;\n\t\t\treturn 0;\n\t\t}\n\n\t\t/* If link contents end in /, strip any slashes already on\n\t\t * stack to avoid /->// or //->/// or spurious toolong. */\n\t\tif (stack[k-1]=='/') while (stack[p]=='/') p++;\n\t\tp -= k;\n\t\tmemmove(stack+p, stack, k);\n\n\t\t/* Skip the stack advancement in case we have a new\n\t\t * absolute base path. */\n\t\tgoto restart;\n\t}\n\n \toutput[q] = 0;\n\n\tif (output[0] != '/') {\n\t\tif (!getcwd(stack, sizeof stack)) return 0;\n\t\tl = strlen(stack);\n\t\t/* Cancel any initial .. components. */\n\t\tp = 0;\n\t\twhile (nup--) {\n\t\t\twhile(l>1 && stack[l-1]!='/') l--;\n\t\t\tif (l>1) l--;\n\t\t\tp += 2;\n\t\t\tif (p<q) p++;\n\t\t}\n\t\tif (q-p && stack[l-1]!='/') stack[l++] = '/';\n\t\tif (l + (q-p) + 1 >= PATH_MAX) goto toolong;\n\t\tmemmove(output + l, output + p, q - p + 1);\n\t\tmemcpy(output, stack, l);\n\t\tq = l + q-p;\n\t}\n\n\tif (resolved) return memcpy(resolved, output, q+1);\n\telse return strdup(output);\n\ntoolong:\n\terrno = ENAMETOOLONG;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/misc/syscall.c",
    "content": "#define _BSD_SOURCE\n#include <unistd.h>\n#include \"syscall.h\"\n#include <stdarg.h>\n\n#undef syscall\n\nlong syscall(long n, ...)\n{\n\tva_list ap;\n\tsyscall_arg_t a,b,c,d,e,f;\n\tva_start(ap, n);\n\ta=va_arg(ap, syscall_arg_t);\n\tb=va_arg(ap, syscall_arg_t);\n\tc=va_arg(ap, syscall_arg_t);\n\td=va_arg(ap, syscall_arg_t);\n\te=va_arg(ap, syscall_arg_t);\n\tf=va_arg(ap, syscall_arg_t);\n\tva_end(ap);\n\treturn __syscall_ret(__syscall(n,a,b,c,d,e,f));\n}\n"
  },
  {
    "path": "user.libc/src/misc/syslog.c",
    "content": "#include <stdarg.h>\n#include <sys/socket.h>\n#include <stdio.h>\n#include <unistd.h>\n#include <syslog.h>\n#include <time.h>\n#include <signal.h>\n#include <string.h>\n#include <pthread.h>\n#include <errno.h>\n#include <fcntl.h>\n#include \"lock.h\"\n#include \"fork_impl.h\"\n\nstatic volatile int lock[1];\nstatic char log_ident[32];\nstatic int log_opt;\nstatic int log_facility = LOG_USER;\nstatic int log_mask = 0xff;\nstatic int log_fd = -1;\nvolatile int *const __syslog_lockptr = lock;\n\nint setlogmask(int maskpri)\n{\n\tLOCK(lock);\n\tint ret = log_mask;\n\tif (maskpri) log_mask = maskpri;\n\tUNLOCK(lock);\n\treturn ret;\n}\n\nstatic const struct {\n\tshort sun_family;\n\tchar sun_path[9];\n} log_addr = {\n\tAF_UNIX,\n\t\"/dev/log\"\n};\n\nvoid closelog(void)\n{\n\tint cs;\n\tpthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);\n\tLOCK(lock);\n\tclose(log_fd);\n\tlog_fd = -1;\n\tUNLOCK(lock);\n\tpthread_setcancelstate(cs, 0);\n}\n\nstatic void __openlog()\n{\n\tlog_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);\n\tif (log_fd >= 0) connect(log_fd, (void *)&log_addr, sizeof log_addr);\n}\n\nvoid openlog(const char *ident, int opt, int facility)\n{\n\tint cs;\n\tpthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);\n\tLOCK(lock);\n\n\tif (ident) {\n\t\tsize_t n = strnlen(ident, sizeof log_ident - 1);\n\t\tmemcpy(log_ident, ident, n);\n\t\tlog_ident[n] = 0;\n\t} else {\n\t\tlog_ident[0] = 0;\n\t}\n\tlog_opt = opt;\n\tlog_facility = facility;\n\n\tif ((opt & LOG_NDELAY) && log_fd<0) __openlog();\n\n\tUNLOCK(lock);\n\tpthread_setcancelstate(cs, 0);\n}\n\nstatic int is_lost_conn(int e)\n{\n\treturn e==ECONNREFUSED || e==ECONNRESET || e==ENOTCONN || e==EPIPE;\n}\n\nstatic void _vsyslog(int priority, const char *message, va_list ap)\n{\n\tchar timebuf[16];\n\ttime_t now;\n\tstruct tm tm;\n\tchar buf[1024];\n\tint errno_save = errno;\n\tint pid;\n\tint l, l2;\n\tint hlen;\n\tint fd;\n\n\tif (log_fd < 0) __openlog();\n\n\tif (!(priority & LOG_FACMASK)) priority |= log_facility;\n\n\tnow = time(NULL);\n\tgmtime_r(&now, &tm);\n\tstrftime(timebuf, sizeof timebuf, \"%b %e %T\", &tm);\n\n\tpid = (log_opt & LOG_PID) ? getpid() : 0;\n\tl = snprintf(buf, sizeof buf, \"<%d>%s %n%s%s%.0d%s: \",\n\t\tpriority, timebuf, &hlen, log_ident, \"[\"+!pid, pid, \"]\"+!pid);\n\terrno = errno_save;\n\tl2 = vsnprintf(buf+l, sizeof buf - l, message, ap);\n\tif (l2 >= 0) {\n\t\tif (l2 >= sizeof buf - l) l = sizeof buf - 1;\n\t\telse l += l2;\n\t\tif (buf[l-1] != '\\n') buf[l++] = '\\n';\n\t\tif (send(log_fd, buf, l, 0) < 0 && (!is_lost_conn(errno)\n\t\t    || connect(log_fd, (void *)&log_addr, sizeof log_addr) < 0\n\t\t    || send(log_fd, buf, l, 0) < 0)\n\t\t    && (log_opt & LOG_CONS)) {\n\t\t\tfd = open(\"/dev/console\", O_WRONLY|O_NOCTTY|O_CLOEXEC);\n\t\t\tif (fd >= 0) {\n\t\t\t\tdprintf(fd, \"%.*s\", l-hlen, buf+hlen);\n\t\t\t\tclose(fd);\n\t\t\t}\n\t\t}\n\t\tif (log_opt & LOG_PERROR) dprintf(2, \"%.*s\", l-hlen, buf+hlen);\n\t}\n}\n\nstatic void __vsyslog(int priority, const char *message, va_list ap)\n{\n\tint cs;\n\tif (!(log_mask & LOG_MASK(priority&7)) || (priority&~0x3ff)) return;\n\tpthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);\n\tLOCK(lock);\n\t_vsyslog(priority, message, ap);\n\tUNLOCK(lock);\n\tpthread_setcancelstate(cs, 0);\n}\n\nvoid syslog(int priority, const char *message, ...)\n{\n\tva_list ap;\n\tva_start(ap, message);\n\t__vsyslog(priority, message, ap);\n\tva_end(ap);\n}\n\nweak_alias(__vsyslog, vsyslog);\n"
  },
  {
    "path": "user.libc/src/misc/wordexp.c",
    "content": "#include <wordexp.h>\n#include <unistd.h>\n#include <stdio.h>\n#include <string.h>\n#include <limits.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <sys/wait.h>\n#include <signal.h>\n#include <errno.h>\n#include <fcntl.h>\n#include \"pthread_impl.h\"\n\nstatic void reap(pid_t pid)\n{\n\tint status;\n\twhile (waitpid(pid, &status, 0) < 0 && errno == EINTR);\n}\n\nstatic char *getword(FILE *f)\n{\n\tchar *s = 0;\n\treturn getdelim(&s, (size_t [1]){0}, 0, f) < 0 ? 0 : s;\n}\n\nstatic int do_wordexp(const char *s, wordexp_t *we, int flags)\n{\n\tsize_t i, l;\n\tint sq=0, dq=0;\n\tsize_t np=0;\n\tchar *w, **tmp;\n\tchar *redir = (flags & WRDE_SHOWERR) ? \"\" : \"2>/dev/null\";\n\tint err = 0;\n\tFILE *f;\n\tsize_t wc = 0;\n\tchar **wv = 0;\n\tint p[2];\n\tpid_t pid;\n\tsigset_t set;\n\n\tif (flags & WRDE_REUSE) wordfree(we);\n\n\tif (flags & WRDE_NOCMD) for (i=0; s[i]; i++) switch (s[i]) {\n\tcase '\\\\':\n\t\tif (!sq && !s[++i]) return WRDE_SYNTAX;\n\t\tbreak;\n\tcase '\\'':\n\t\tif (!dq) sq^=1;\n\t\tbreak;\n\tcase '\"':\n\t\tif (!sq) dq^=1;\n\t\tbreak;\n\tcase '(':\n\t\tif (np) {\n\t\t\tnp++;\n\t\t\tbreak;\n\t\t}\n\tcase ')':\n\t\tif (np) {\n\t\t\tnp--;\n\t\t\tbreak;\n\t\t}\n\tcase '\\n':\n\tcase '|':\n\tcase '&':\n\tcase ';':\n\tcase '<':\n\tcase '>':\n\tcase '{':\n\tcase '}':\n\t\tif (!(sq|dq|np)) return WRDE_BADCHAR;\n\t\tbreak;\n\tcase '$':\n\t\tif (sq) break;\n\t\tif (s[i+1]=='(' && s[i+2]=='(') {\n\t\t\ti += 2;\n\t\t\tnp += 2;\n\t\t\tbreak;\n\t\t} else if (s[i+1] != '(') break;\n\tcase '`':\n\t\tif (sq) break;\n\t\treturn WRDE_CMDSUB;\n\t}\n\n\tif (flags & WRDE_APPEND) {\n\t\twc = we->we_wordc;\n\t\twv = we->we_wordv;\n\t}\n\n\ti = wc;\n\tif (flags & WRDE_DOOFFS) {\n\t\tif (we->we_offs > SIZE_MAX/sizeof(void *)/4)\n\t\t\tgoto nospace;\n\t\ti += we->we_offs;\n\t} else {\n\t\twe->we_offs = 0;\n\t}\n\n\tif (pipe2(p, O_CLOEXEC) < 0) goto nospace;\n\t__block_all_sigs(&set);\n\tpid = fork();\n\t__restore_sigs(&set);\n\tif (pid < 0) {\n\t\tclose(p[0]);\n\t\tclose(p[1]);\n\t\tgoto nospace;\n\t}\n\tif (!pid) {\n\t\tif (p[1] == 1) fcntl(1, F_SETFD, 0);\n\t\telse dup2(p[1], 1);\n\t\texecl(\"/bin/sh\", \"sh\", \"-c\",\n\t\t\t\"eval \\\"printf %s\\\\\\\\\\\\\\\\0 x $1 $2\\\"\",\n\t\t\t\"sh\", s, redir, (char *)0);\n\t\t_exit(1);\n\t}\n\tclose(p[1]);\n\t\n\tf = fdopen(p[0], \"r\");\n\tif (!f) {\n\t\tclose(p[0]);\n\t\tkill(pid, SIGKILL);\n\t\treap(pid);\n\t\tgoto nospace;\n\t}\n\n\tl = wv ? i+1 : 0;\n\n\tfree(getword(f));\n\tif (feof(f)) {\n\t\tfclose(f);\n\t\treap(pid);\n\t\treturn WRDE_SYNTAX;\n\t}\n\n\twhile ((w = getword(f))) {\n\t\tif (i+1 >= l) {\n\t\t\tl += l/2+10;\n\t\t\ttmp = realloc(wv, l*sizeof(char *));\n\t\t\tif (!tmp) break;\n\t\t\twv = tmp;\n\t\t}\n\t\twv[i++] = w;\n\t\twv[i] = 0;\n\t}\n\tif (!feof(f)) err = WRDE_NOSPACE;\n\n\tfclose(f);\n\treap(pid);\n\n\tif (!wv) wv = calloc(i+1, sizeof *wv);\n\n\twe->we_wordv = wv;\n\twe->we_wordc = i;\n\n\tif (flags & WRDE_DOOFFS) {\n\t\tif (wv) for (i=we->we_offs; i; i--)\n\t\t\twe->we_wordv[i-1] = 0;\n\t\twe->we_wordc -= we->we_offs;\n\t}\n\treturn err;\n\nnospace:\n\tif (!(flags & WRDE_APPEND)) {\n\t\twe->we_wordc = 0;\n\t\twe->we_wordv = 0;\n\t}\n\treturn WRDE_NOSPACE;\n}\n\nint wordexp(const char *restrict s, wordexp_t *restrict we, int flags)\n{\n\tint r, cs;\n\tpthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);\n\tr = do_wordexp(s, we, flags);\n\tpthread_setcancelstate(cs, 0);\n\treturn r;\n}\n\nvoid wordfree(wordexp_t *we)\n{\n\tsize_t i;\n\tif (!we->we_wordv) return;\n\tfor (i=0; i<we->we_wordc; i++) free(we->we_wordv[we->we_offs+i]);\n\tfree(we->we_wordv);\n\twe->we_wordv = 0;\n\twe->we_wordc = 0;\n}\n"
  },
  {
    "path": "user.libc/src/mman/madvise.c",
    "content": "#include <sys/mman.h>\n#include \"syscall.h\"\n\nint __madvise(void *addr, size_t len, int advice)\n{\n\t/*\n\t * TBD.\n\t */\n\treturn 0;\n}\n\nweak_alias(__madvise, madvise);\n"
  },
  {
    "path": "user.libc/src/mman/mmap.c",
    "content": "#include <unistd.h>\n#include <sys/mman.h>\n#include <errno.h>\n#include <stdint.h>\n#include <limits.h>\n#include \"syscall.h\"\n#include \"pthread_impl.h\"\n\n#include <minos/proto.h>\n#include <minos/kobject.h>\n\nstatic void dummy(void) { }\nweak_alias(dummy, __vm_wait);\n\n#define UNIT SYSCALL_MMAP2_UNIT\n#define OFF_MASK ((-0x2000ULL << (8*sizeof(syscall_arg_t)-1)) | (UNIT-1))\n\nvoid *__mmap(void *start, size_t len, int prot, int flags, int fd, off_t off)\n{\n\tstruct proto proto;\n\tlong ret;\n\n\tproto.proto_id = PROTO_MMAP;\n\tproto.mmap.addr = start;\n\tproto.mmap.len = len;\n\tproto.mmap.prot = prot;\n\tproto.mmap.flags = flags;\n\tproto.mmap.fd = fd;\n\tproto.mmap.offset = off;\n\n\tif (off & OFF_MASK) {\n\t\terrno = EINVAL;\n\t\treturn MAP_FAILED;\n\t}\n\tif (len >= PTRDIFF_MAX) {\n\t\terrno = ENOMEM;\n\t\treturn MAP_FAILED;\n\t}\n\tif (flags & MAP_FIXED) {\n\t\t__vm_wait();\n\t}\n\n\tret = kobject_write(self_handle(), &proto, sizeof(struct proto), NULL, 0, -1);\n\n\t/* Fixup incorrect EPERM from kernel. */\n\tif (ret == -EPERM && !start && (flags&MAP_ANON) && !(flags&MAP_FIXED))\n\t\tret = -ENOMEM;\n\n\treturn (void *)__syscall_ret(ret);\n}\n\nweak_alias(__mmap, mmap);\n\nweak_alias(mmap, mmap64);\n"
  },
  {
    "path": "user.libc/src/mman/mprotect.c",
    "content": "#include <sys/mman.h>\n#include \"libc.h\"\n#include \"syscall.h\"\n#include \"pthread_impl.h\"\n\n#include <minos/proto.h>\n#include <minos/kobject.h>\n\nint __mprotect(void *addr, size_t len, int prot)\n{\n\tstruct proto proto;\n\tsize_t start, end;\n\n\tstart = (size_t)addr & -PAGE_SIZE;\n\tend = (size_t)((char *)addr + len + PAGE_SIZE-1) & -PAGE_SIZE;\n\tproto.proto_id = PROTO_MPROTECT;\n\tproto.mprotect.addr = (void *)start;\n\tproto.mprotect.len = end - start;\n\tproto.mprotect.prot = prot;\n\n\treturn kobject_write(self_handle(), &proto,\n\t\t\tsizeof(struct proto), NULL, 0, -1);\n}\n\nweak_alias(__mprotect, mprotect);\n"
  },
  {
    "path": "user.libc/src/mman/munmap.c",
    "content": "#include <sys/mman.h>\n#include \"syscall.h\"\n\n#include <minos/proto.h>\n#include <minos/kobject.h>\n\n#include \"pthread_impl.h\"\n\nstatic void dummy(void) { }\nweak_alias(dummy, __vm_wait);\n\nint __munmap(void *start, size_t len)\n{\n\tstruct proto proto;\n\n\tproto.proto_id = PROTO_MUNMAP;\n\tproto.munmap.start = start;\n\tproto.munmap.len = len;\n\t__vm_wait();\n\n\treturn __syscall_ret(kobject_write(self_handle(), &proto,\n\t\t\t\tsizeof(struct proto), NULL, 0, -1));\n}\n\nweak_alias(__munmap, munmap);\n"
  },
  {
    "path": "user.libc/src/mman/posix_madvise.c",
    "content": "#define _GNU_SOURCE\n#include <sys/mman.h>\n#include \"syscall.h\"\n\nint posix_madvise(void *addr, size_t len, int advice)\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/multibyte/btowc.c",
    "content": "#include <stdio.h>\n#include <wchar.h>\n#include <stdlib.h>\n#include \"internal.h\"\n\nwint_t btowc(int c)\n{\n\tint b = (unsigned char)c;\n\treturn b<128U ? b : (MB_CUR_MAX==1 && c!=EOF) ? CODEUNIT(c) : WEOF;\n}\n"
  },
  {
    "path": "user.libc/src/multibyte/c16rtomb.c",
    "content": "#include <uchar.h>\n#include <errno.h>\n#include <wchar.h>\n\nsize_t c16rtomb(char *restrict s, char16_t c16, mbstate_t *restrict ps)\n{\n\tstatic unsigned internal_state;\n\tif (!ps) ps = (void *)&internal_state;\n\tunsigned *x = (unsigned *)ps;\n\twchar_t wc;\n\n\tif (!s) {\n\t\tif (*x) goto ilseq;\n\t\treturn 1;\n\t}\n\n\tif (!*x && c16 - 0xd800u < 0x400) {\n\t\t*x = c16 - 0xd7c0 << 10;\n\t\treturn 0;\n\t}\n\n\tif (*x) {\n\t\tif (c16 - 0xdc00u >= 0x400) goto ilseq;\n\t\telse wc = *x + c16 - 0xdc00;\n\t\t*x = 0;\n\t} else {\n\t\twc = c16;\n\t}\n\treturn wcrtomb(s, wc, 0);\n\nilseq:\n\t*x = 0;\n\terrno = EILSEQ;\n\treturn -1;\n}\n"
  },
  {
    "path": "user.libc/src/multibyte/c32rtomb.c",
    "content": "#include <uchar.h>\n#include <wchar.h>\n\nsize_t c32rtomb(char *restrict s, char32_t c32, mbstate_t *restrict ps)\n{\n\treturn wcrtomb(s, c32, ps);\n}\n"
  },
  {
    "path": "user.libc/src/multibyte/internal.c",
    "content": "#include \"internal.h\"\n\n#define C(x) ( x<2 ? -1 : ( R(0x80,0xc0) | x ) )\n#define D(x) C((x+16))\n#define E(x) ( ( x==0 ? R(0xa0,0xc0) : \\\n                 x==0xd ? R(0x80,0xa0) : \\\n                 R(0x80,0xc0) ) \\\n             | ( R(0x80,0xc0) >> 6 ) \\\n             | x )\n#define F(x) ( ( x>=5 ? 0 : \\\n                 x==0 ? R(0x90,0xc0) : \\\n                 x==4 ? R(0x80,0x90) : \\\n                 R(0x80,0xc0) ) \\\n             | ( R(0x80,0xc0) >> 6 ) \\\n             | ( R(0x80,0xc0) >> 12 ) \\\n             | x )\n\nconst uint32_t bittab[] = {\n\t              C(0x2),C(0x3),C(0x4),C(0x5),C(0x6),C(0x7),\n\tC(0x8),C(0x9),C(0xa),C(0xb),C(0xc),C(0xd),C(0xe),C(0xf),\n\tD(0x0),D(0x1),D(0x2),D(0x3),D(0x4),D(0x5),D(0x6),D(0x7),\n\tD(0x8),D(0x9),D(0xa),D(0xb),D(0xc),D(0xd),D(0xe),D(0xf),\n\tE(0x0),E(0x1),E(0x2),E(0x3),E(0x4),E(0x5),E(0x6),E(0x7),\n\tE(0x8),E(0x9),E(0xa),E(0xb),E(0xc),E(0xd),E(0xe),E(0xf),\n\tF(0x0),F(0x1),F(0x2),F(0x3),F(0x4)\n};\n"
  },
  {
    "path": "user.libc/src/multibyte/internal.h",
    "content": "#define bittab __fsmu8\n\n#include <stdint.h>\n#include <features.h>\n\nextern hidden const uint32_t bittab[];\n\n/* Upper 6 state bits are a negative integer offset to bound-check next byte */\n/*    equivalent to: ( (b-0x80) | (b+offset) ) & ~0x3f      */\n#define OOB(c,b) (((((b)>>3)-0x10)|(((b)>>3)+((int32_t)(c)>>26))) & ~7)\n\n/* Interval [a,b). Either a must be 80 or b must be c0, lower 3 bits clear. */\n#define R(a,b) ((uint32_t)((a==0x80 ? 0x40u-b : 0u-a) << 23))\n#define FAILSTATE R(0x80,0x80)\n\n#define SA 0xc2u\n#define SB 0xf4u\n\n/* Arbitrary encoding for representing code units instead of characters. */\n#define CODEUNIT(c) (0xdfff & (signed char)(c))\n#define IS_CODEUNIT(c) ((unsigned)(c)-0xdf80 < 0x80)\n\n/* Get inline definition of MB_CUR_MAX. */\n#include \"locale_impl.h\"\n"
  },
  {
    "path": "user.libc/src/multibyte/mblen.c",
    "content": "#include <stdlib.h>\n\nint mblen(const char *s, size_t n)\n{\n\treturn mbtowc(0, s, n);\n}\n"
  },
  {
    "path": "user.libc/src/multibyte/mbrlen.c",
    "content": "#include <wchar.h>\n\nsize_t mbrlen(const char *restrict s, size_t n, mbstate_t *restrict st)\n{\n\tstatic unsigned internal;\n\treturn mbrtowc(0, s, n, st ? st : (mbstate_t *)&internal);\n}\n"
  },
  {
    "path": "user.libc/src/multibyte/mbrtoc16.c",
    "content": "#include <uchar.h>\n#include <wchar.h>\n\nsize_t mbrtoc16(char16_t *restrict pc16, const char *restrict s, size_t n, mbstate_t *restrict ps)\n{\n\tstatic unsigned internal_state;\n\tif (!ps) ps = (void *)&internal_state;\n\tunsigned *pending = (unsigned *)ps;\n\n\tif (!s) return mbrtoc16(0, \"\", 1, ps);\n\n\t/* mbrtowc states for partial UTF-8 characters have the high bit set;\n\t * we use nonzero states without high bit for pending surrogates. */\n\tif ((int)*pending > 0) {\n \t\tif (pc16) *pc16 = *pending;\n\t\t*pending = 0;\n\t\treturn -3;\n\t}\n\n\twchar_t wc;\n\tsize_t ret = mbrtowc(&wc, s, n, ps);\n\tif (ret <= 4) {\n\t\tif (wc >= 0x10000) {\n\t\t\t*pending = (wc & 0x3ff) + 0xdc00;\n\t\t\twc = 0xd7c0 + (wc >> 10);\n\t\t}\n\t\tif (pc16) *pc16 = wc;\n\t}\n\treturn ret;\n}\n"
  },
  {
    "path": "user.libc/src/multibyte/mbrtoc32.c",
    "content": "#include <uchar.h>\n#include <wchar.h>\n\nsize_t mbrtoc32(char32_t *restrict pc32, const char *restrict s, size_t n, mbstate_t *restrict ps)\n{\n\tstatic unsigned internal_state;\n\tif (!ps) ps = (void *)&internal_state;\n\tif (!s) return mbrtoc32(0, \"\", 1, ps);\n\twchar_t wc;\n\tsize_t ret = mbrtowc(&wc, s, n, ps);\n\tif (ret <= 4 && pc32) *pc32 = wc;\n\treturn ret;\n}\n"
  },
  {
    "path": "user.libc/src/multibyte/mbrtowc.c",
    "content": "#include <stdlib.h>\n#include <wchar.h>\n#include <errno.h>\n#include \"internal.h\"\n\nsize_t mbrtowc(wchar_t *restrict wc, const char *restrict src, size_t n, mbstate_t *restrict st)\n{\n\tstatic unsigned internal_state;\n\tunsigned c;\n\tconst unsigned char *s = (const void *)src;\n\tconst unsigned N = n;\n\twchar_t dummy;\n\n\tif (!st) st = (void *)&internal_state;\n\tc = *(unsigned *)st;\n\t\n\tif (!s) {\n\t\tif (c) goto ilseq;\n\t\treturn 0;\n\t} else if (!wc) wc = &dummy;\n\n\tif (!n) return -2;\n\tif (!c) {\n\t\tif (*s < 0x80) return !!(*wc = *s);\n\t\tif (MB_CUR_MAX==1) return (*wc = CODEUNIT(*s)), 1;\n\t\tif (*s-SA > SB-SA) goto ilseq;\n\t\tc = bittab[*s++-SA]; n--;\n\t}\n\n\tif (n) {\n\t\tif (OOB(c,*s)) goto ilseq;\nloop:\n\t\tc = c<<6 | *s++-0x80; n--;\n\t\tif (!(c&(1U<<31))) {\n\t\t\t*(unsigned *)st = 0;\n\t\t\t*wc = c;\n\t\t\treturn N-n;\n\t\t}\n\t\tif (n) {\n\t\t\tif (*s-0x80u >= 0x40) goto ilseq;\n\t\t\tgoto loop;\n\t\t}\n\t}\n\n\t*(unsigned *)st = c;\n\treturn -2;\nilseq:\n\t*(unsigned *)st = 0;\n\terrno = EILSEQ;\n\treturn -1;\n}\n"
  },
  {
    "path": "user.libc/src/multibyte/mbsinit.c",
    "content": "#include <wchar.h>\n\nint mbsinit(const mbstate_t *st)\n{\n\treturn !st || !*(unsigned *)st;\n}\n"
  },
  {
    "path": "user.libc/src/multibyte/mbsnrtowcs.c",
    "content": "#include <wchar.h>\n\nsize_t mbsnrtowcs(wchar_t *restrict wcs, const char **restrict src, size_t n, size_t wn, mbstate_t *restrict st)\n{\n\tsize_t l, cnt=0, n2;\n\twchar_t *ws, wbuf[256];\n\tconst char *s = *src;\n\tconst char *tmp_s;\n\n\tif (!wcs) ws = wbuf, wn = sizeof wbuf / sizeof *wbuf;\n\telse ws = wcs;\n\n\t/* making sure output buffer size is at most n/4 will ensure\n\t * that mbsrtowcs never reads more than n input bytes. thus\n\t * we can use mbsrtowcs as long as it's practical.. */\n\n\twhile ( s && wn && ( (n2=n/4)>=wn || n2>32 ) ) {\n\t\tif (n2>=wn) n2=wn;\n\t\ttmp_s = s;\n\t\tl = mbsrtowcs(ws, &s, n2, st);\n\t\tif (!(l+1)) {\n\t\t\tcnt = l;\n\t\t\twn = 0;\n\t\t\tbreak;\n\t\t}\n\t\tif (ws != wbuf) {\n\t\t\tws += l;\n\t\t\twn -= l;\n\t\t}\n\t\tn = s ? n - (s - tmp_s) : 0;\n\t\tcnt += l;\n\t}\n\tif (s) while (wn && n) {\n\t\tl = mbrtowc(ws, s, n, st);\n\t\tif (l+2<=2) {\n\t\t\tif (!(l+1)) {\n\t\t\t\tcnt = l;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!l) {\n\t\t\t\ts = 0;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t/* have to roll back partial character */\n\t\t\t*(unsigned *)st = 0;\n\t\t\tbreak;\n\t\t}\n\t\ts += l; n -= l;\n\t\t/* safe - this loop runs fewer than sizeof(wbuf)/8 times */\n\t\tws++; wn--;\n\t\tcnt++;\n\t}\n\tif (wcs) *src = s;\n\treturn cnt;\n}\n"
  },
  {
    "path": "user.libc/src/multibyte/mbsrtowcs.c",
    "content": "#include <stdint.h>\n#include <wchar.h>\n#include <errno.h>\n#include <string.h>\n#include <stdlib.h>\n#include \"internal.h\"\n\nsize_t mbsrtowcs(wchar_t *restrict ws, const char **restrict src, size_t wn, mbstate_t *restrict st)\n{\n\tconst unsigned char *s = (const void *)*src;\n\tsize_t wn0 = wn;\n\tunsigned c = 0;\n\n\tif (st && (c = *(unsigned *)st)) {\n\t\tif (ws) {\n\t\t\t*(unsigned *)st = 0;\n\t\t\tgoto resume;\n\t\t} else {\n\t\t\tgoto resume0;\n\t\t}\n\t}\n\n\tif (MB_CUR_MAX==1) {\n\t\tif (!ws) return strlen((const char *)s);\n\t\tfor (;;) {\n\t\t\tif (!wn) {\n\t\t\t\t*src = (const void *)s;\n\t\t\t\treturn wn0;\n\t\t\t}\n\t\t\tif (!*s) break;\n\t\t\tc = *s++;\n\t\t\t*ws++ = CODEUNIT(c);\n\t\t\twn--;\n\t\t}\n\t\t*ws = 0;\n\t\t*src = 0;\n\t\treturn wn0-wn;\n\t}\n\n\tif (!ws) for (;;) {\n#ifdef __GNUC__\n\t\ttypedef uint32_t __attribute__((__may_alias__)) w32;\n\t\tif (*s-1u < 0x7f && (uintptr_t)s%4 == 0) {\n\t\t\twhile (!(( *(w32*)s | *(w32*)s-0x01010101) & 0x80808080)) {\n\t\t\t\ts += 4;\n\t\t\t\twn -= 4;\n\t\t\t}\n\t\t}\n#endif\n\t\tif (*s-1u < 0x7f) {\n\t\t\ts++;\n\t\t\twn--;\n\t\t\tcontinue;\n\t\t}\n\t\tif (*s-SA > SB-SA) break;\n\t\tc = bittab[*s++-SA];\nresume0:\n\t\tif (OOB(c,*s)) { s--; break; }\n\t\ts++;\n\t\tif (c&(1U<<25)) {\n\t\t\tif (*s-0x80u >= 0x40) { s-=2; break; }\n\t\t\ts++;\n\t\t\tif (c&(1U<<19)) {\n\t\t\t\tif (*s-0x80u >= 0x40) { s-=3; break; }\n\t\t\t\ts++;\n\t\t\t}\n\t\t}\n\t\twn--;\n\t\tc = 0;\n\t} else for (;;) {\n\t\tif (!wn) {\n\t\t\t*src = (const void *)s;\n\t\t\treturn wn0;\n\t\t}\n#ifdef __GNUC__\n\t\ttypedef uint32_t __attribute__((__may_alias__)) w32;\n\t\tif (*s-1u < 0x7f && (uintptr_t)s%4 == 0) {\n\t\t\twhile (wn>=5 && !(( *(w32*)s | *(w32*)s-0x01010101) & 0x80808080)) {\n\t\t\t\t*ws++ = *s++;\n\t\t\t\t*ws++ = *s++;\n\t\t\t\t*ws++ = *s++;\n\t\t\t\t*ws++ = *s++;\n\t\t\t\twn -= 4;\n\t\t\t}\n\t\t}\n#endif\n\t\tif (*s-1u < 0x7f) {\n\t\t\t*ws++ = *s++;\n\t\t\twn--;\n\t\t\tcontinue;\n\t\t}\n\t\tif (*s-SA > SB-SA) break;\n\t\tc = bittab[*s++-SA];\nresume:\n\t\tif (OOB(c,*s)) { s--; break; }\n\t\tc = (c<<6) | *s++-0x80;\n\t\tif (c&(1U<<31)) {\n\t\t\tif (*s-0x80u >= 0x40) { s-=2; break; }\n\t\t\tc = (c<<6) | *s++-0x80;\n\t\t\tif (c&(1U<<31)) {\n\t\t\t\tif (*s-0x80u >= 0x40) { s-=3; break; }\n\t\t\t\tc = (c<<6) | *s++-0x80;\n\t\t\t}\n\t\t}\n\t\t*ws++ = c;\n\t\twn--;\n\t\tc = 0;\n\t}\n\n\tif (!c && !*s) {\n\t\tif (ws) {\n\t\t\t*ws = 0;\n\t\t\t*src = 0;\n\t\t}\n\t\treturn wn0-wn;\n\t}\n\terrno = EILSEQ;\n\tif (ws) *src = (const void *)s;\n\treturn -1;\n}\n"
  },
  {
    "path": "user.libc/src/multibyte/mbstowcs.c",
    "content": "#include <stdlib.h>\n#include <wchar.h>\n\nsize_t mbstowcs(wchar_t *restrict ws, const char *restrict s, size_t wn)\n{\n\treturn mbsrtowcs(ws, (void*)&s, wn, 0);\n}\n"
  },
  {
    "path": "user.libc/src/multibyte/mbtowc.c",
    "content": "#include <stdlib.h>\n#include <wchar.h>\n#include <errno.h>\n#include \"internal.h\"\n\nint mbtowc(wchar_t *restrict wc, const char *restrict src, size_t n)\n{\n\tunsigned c;\n\tconst unsigned char *s = (const void *)src;\n\twchar_t dummy;\n\n\tif (!s) return 0;\n\tif (!n) goto ilseq;\n\tif (!wc) wc = &dummy;\n\n\tif (*s < 0x80) return !!(*wc = *s);\n\tif (MB_CUR_MAX==1) return (*wc = CODEUNIT(*s)), 1;\n\tif (*s-SA > SB-SA) goto ilseq;\n\tc = bittab[*s++-SA];\n\n\t/* Avoid excessive checks against n: If shifting the state n-1\n\t * times does not clear the high bit, then the value of n is\n\t * insufficient to read a character */\n\tif (n<4 && ((c<<(6*n-6)) & (1U<<31))) goto ilseq;\n\n\tif (OOB(c,*s)) goto ilseq;\n\tc = c<<6 | *s++-0x80;\n\tif (!(c&(1U<<31))) {\n\t\t*wc = c;\n\t\treturn 2;\n\t}\n\n\tif (*s-0x80u >= 0x40) goto ilseq;\n\tc = c<<6 | *s++-0x80;\n\tif (!(c&(1U<<31))) {\n\t\t*wc = c;\n\t\treturn 3;\n\t}\n\n\tif (*s-0x80u >= 0x40) goto ilseq;\n\t*wc = c<<6 | *s++-0x80;\n\treturn 4;\n\nilseq:\n\terrno = EILSEQ;\n\treturn -1;\n}\n"
  },
  {
    "path": "user.libc/src/multibyte/wcrtomb.c",
    "content": "#include <stdlib.h>\n#include <wchar.h>\n#include <errno.h>\n#include \"internal.h\"\n\nsize_t wcrtomb(char *restrict s, wchar_t wc, mbstate_t *restrict st)\n{\n\tif (!s) return 1;\n\tif ((unsigned)wc < 0x80) {\n\t\t*s = wc;\n\t\treturn 1;\n\t} else if (MB_CUR_MAX == 1) {\n\t\tif (!IS_CODEUNIT(wc)) {\n\t\t\terrno = EILSEQ;\n\t\t\treturn -1;\n\t\t}\n\t\t*s = wc;\n\t\treturn 1;\n\t} else if ((unsigned)wc < 0x800) {\n\t\t*s++ = 0xc0 | (wc>>6);\n\t\t*s = 0x80 | (wc&0x3f);\n\t\treturn 2;\n\t} else if ((unsigned)wc < 0xd800 || (unsigned)wc-0xe000 < 0x2000) {\n\t\t*s++ = 0xe0 | (wc>>12);\n\t\t*s++ = 0x80 | ((wc>>6)&0x3f);\n\t\t*s = 0x80 | (wc&0x3f);\n\t\treturn 3;\n\t} else if ((unsigned)wc-0x10000 < 0x100000) {\n\t\t*s++ = 0xf0 | (wc>>18);\n\t\t*s++ = 0x80 | ((wc>>12)&0x3f);\n\t\t*s++ = 0x80 | ((wc>>6)&0x3f);\n\t\t*s = 0x80 | (wc&0x3f);\n\t\treturn 4;\n\t}\n\terrno = EILSEQ;\n\treturn -1;\n}\n"
  },
  {
    "path": "user.libc/src/multibyte/wcsnrtombs.c",
    "content": "#include <wchar.h>\n#include <limits.h>\n#include <string.h>\n\nsize_t wcsnrtombs(char *restrict dst, const wchar_t **restrict wcs, size_t wn, size_t n, mbstate_t *restrict st)\n{\n\tconst wchar_t *ws = *wcs;\n\tsize_t cnt = 0;\n\tif (!dst) n=0;\n\twhile (ws && wn) {\n\t\tchar tmp[MB_LEN_MAX];\n\t\tsize_t l = wcrtomb(n<MB_LEN_MAX ? tmp : dst, *ws, 0);\n\t\tif (l==-1) {\n\t\t\tcnt = -1;\n\t\t\tbreak;\n\t\t}\n\t\tif (dst) {\n\t\t\tif (n<MB_LEN_MAX) {\n\t\t\t\tif (l>n) break;\n\t\t\t\tmemcpy(dst, tmp, l);\n\t\t\t}\n\t\t\tdst += l;\n\t\t\tn -= l;\n\t\t}\n\t\tif (!*ws) {\n\t\t\tws = 0;\n\t\t\tbreak;\n\t\t}\n\t\tws++;\n\t\twn--;\n\t\tcnt += l;\n\t}\n\tif (dst) *wcs = ws;\n\treturn cnt;\n}\n"
  },
  {
    "path": "user.libc/src/multibyte/wcsrtombs.c",
    "content": "#include <wchar.h>\n\nsize_t wcsrtombs(char *restrict s, const wchar_t **restrict ws, size_t n, mbstate_t *restrict st)\n{\n\tconst wchar_t *ws2;\n\tchar buf[4];\n\tsize_t N = n, l;\n\tif (!s) {\n\t\tfor (n=0, ws2=*ws; *ws2; ws2++) {\n\t\t\tif (*ws2 >= 0x80u) {\n\t\t\t\tl = wcrtomb(buf, *ws2, 0);\n\t\t\t\tif (!(l+1)) return -1;\n\t\t\t\tn += l;\n\t\t\t} else n++;\n\t\t}\n\t\treturn n;\n\t}\n\twhile (n>=4) {\n\t\tif (**ws-1u >= 0x7fu) {\n\t\t\tif (!**ws) {\n\t\t\t\t*s = 0;\n\t\t\t\t*ws = 0;\n\t\t\t\treturn N-n;\n\t\t\t}\n\t\t\tl = wcrtomb(s, **ws, 0);\n\t\t\tif (!(l+1)) return -1;\n\t\t\ts += l;\n\t\t\tn -= l;\n\t\t} else {\n\t\t\t*s++ = **ws;\n\t\t\tn--;\n\t\t}\n\t\t(*ws)++;\n\t}\n\twhile (n) {\n\t\tif (**ws-1u >= 0x7fu) {\n\t\t\tif (!**ws) {\n\t\t\t\t*s = 0;\n\t\t\t\t*ws = 0;\n\t\t\t\treturn N-n;\n\t\t\t}\n\t\t\tl = wcrtomb(buf, **ws, 0);\n\t\t\tif (!(l+1)) return -1;\n\t\t\tif (l>n) return N-n;\n\t\t\twcrtomb(s, **ws, 0);\n\t\t\ts += l;\n\t\t\tn -= l;\n\t\t} else {\n\t\t\t*s++ = **ws;\n\t\t\tn--;\n\t\t}\n\t\t(*ws)++;\n\t}\n\treturn N;\n}\n"
  },
  {
    "path": "user.libc/src/multibyte/wcstombs.c",
    "content": "#include <stdlib.h>\n#include <wchar.h>\n\nsize_t wcstombs(char *restrict s, const wchar_t *restrict ws, size_t n)\n{\n\treturn wcsrtombs(s, &(const wchar_t *){ws}, n, 0);\n}\n"
  },
  {
    "path": "user.libc/src/multibyte/wctob.c",
    "content": "#include <wchar.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include \"internal.h\"\n\nint wctob(wint_t c)\n{\n\tif (c < 128U) return c;\n\tif (MB_CUR_MAX==1 && IS_CODEUNIT(c)) return (unsigned char)c;\n\treturn EOF;\n}\n"
  },
  {
    "path": "user.libc/src/multibyte/wctomb.c",
    "content": "#include <stdlib.h>\n#include <wchar.h>\n\nint wctomb(char *s, wchar_t wc)\n{\n\tif (!s) return 0;\n\treturn wcrtomb(s, wc, 0);\n}\n"
  },
  {
    "path": "user.libc/src/passwd/fgetgrent.c",
    "content": "#define _GNU_SOURCE\n#include \"pwf.h\"\n\nstruct group *fgetgrent(FILE *f)\n{\n\tstatic char *line, **mem;\n\tstatic struct group gr;\n\tstruct group *res;\n\tsize_t size=0, nmem=0;\n\t__getgrent_a(f, &gr, &line, &size, &mem, &nmem, &res);\n\treturn res;\n}\n"
  },
  {
    "path": "user.libc/src/passwd/fgetpwent.c",
    "content": "#define _GNU_SOURCE\n#include \"pwf.h\"\n\nstruct passwd *fgetpwent(FILE *f)\n{\n\tstatic char *line;\n\tstatic struct passwd pw;\n\tsize_t size=0;\n\tstruct passwd *res;\n\t__getpwent_a(f, &pw, &line, &size, &res);\n\treturn res;\n}\n"
  },
  {
    "path": "user.libc/src/passwd/fgetspent.c",
    "content": "#include \"pwf.h\"\n#include <pthread.h>\n\nstruct spwd *fgetspent(FILE *f)\n{\n\tstatic char *line;\n\tstatic struct spwd sp;\n\tsize_t size = 0;\n\tstruct spwd *res = 0;\n\tint cs;\n\tpthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);\n\tif (getline(&line, &size, f) >= 0 && __parsespent(line, &sp) >= 0) res = &sp;\n\tpthread_setcancelstate(cs, 0);\n\treturn res;\n}\n"
  },
  {
    "path": "user.libc/src/passwd/getgr_a.c",
    "content": "#include <pthread.h>\n#include <byteswap.h>\n#include <string.h>\n#include <unistd.h>\n#include \"pwf.h\"\n#include \"nscd.h\"\n\nstatic char *itoa(char *p, uint32_t x)\n{\n\t// number of digits in a uint32_t + NUL\n\tp += 11;\n\t*--p = 0;\n\tdo {\n\t\t*--p = '0' + x % 10;\n\t\tx /= 10;\n\t} while (x);\n\treturn p;\n}\n\nint __getgr_a(const char *name, gid_t gid, struct group *gr, char **buf, size_t *size, char ***mem, size_t *nmem, struct group **res)\n{\n\tFILE *f;\n\tint rv = 0;\n\tint cs;\n\n\t*res = 0;\n\n\tpthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);\n\tf = fopen(\"/etc/group\", \"rbe\");\n\tif (!f) {\n\t\trv = errno;\n\t\tgoto done;\n\t}\n\n\twhile (!(rv = __getgrent_a(f, gr, buf, size, mem, nmem, res)) && *res) {\n\t\tif (name && !strcmp(name, (*res)->gr_name)\n\t\t|| !name && (*res)->gr_gid == gid) {\n\t\t\tbreak;\n\t\t}\n\t}\n\tfclose(f);\n\n\tif (!*res && (rv == 0 || rv == ENOENT || rv == ENOTDIR)) {\n\t\tint32_t req = name ? GETGRBYNAME : GETGRBYGID;\n\t\tint32_t i;\n\t\tconst char *key;\n\t\tint32_t groupbuf[GR_LEN] = {0};\n\t\tsize_t len = 0;\n\t\tsize_t grlist_len = 0;\n\t\tchar gidbuf[11] = {0};\n\t\tint swap = 0;\n\t\tchar *ptr;\n\n\t\tif (name) {\n\t\t\tkey = name;\n\t\t} else {\n\t\t\tif (gid < 0 || gid > UINT32_MAX) {\n\t\t\t\trv = 0;\n\t\t\t\tgoto done;\n\t\t\t}\n\t\t\tkey = itoa(gidbuf, gid);\n\t\t}\n\n\t\tf = __nscd_query(req, key, groupbuf, sizeof groupbuf, &swap);\n\t\tif (!f) { rv = errno; goto done; }\n\n\t\tif (!groupbuf[GRFOUND]) { rv = 0; goto cleanup_f; }\n\n\t\tif (!groupbuf[GRNAMELEN] || !groupbuf[GRPASSWDLEN]) {\n\t\t\trv = EIO;\n\t\t\tgoto cleanup_f;\n\t\t}\n\n\t\tif (groupbuf[GRNAMELEN] > SIZE_MAX - groupbuf[GRPASSWDLEN]) {\n\t\t\trv = ENOMEM;\n\t\t\tgoto cleanup_f;\n\t\t}\n\t\tlen = groupbuf[GRNAMELEN] + groupbuf[GRPASSWDLEN];\n\n\t\tfor (i = 0; i < groupbuf[GRMEMCNT]; i++) {\n\t\t\tuint32_t name_len;\n\t\t\tif (fread(&name_len, sizeof name_len, 1, f) < 1) {\n\t\t\t\trv = ferror(f) ? errno : EIO;\n\t\t\t\tgoto cleanup_f;\n\t\t\t}\n\t\t\tif (swap) {\n\t\t\t\tname_len = bswap_32(name_len);\n\t\t\t}\n\t\t\tif (name_len > SIZE_MAX - grlist_len\n\t\t\t|| name_len > SIZE_MAX - len) {\n\t\t\t\trv = ENOMEM;\n\t\t\t\tgoto cleanup_f;\n\t\t\t}\n\t\t\tlen += name_len;\n\t\t\tgrlist_len += name_len;\n\t\t}\n\n\t\tif (len > *size || !*buf) {\n\t\t\tchar *tmp = realloc(*buf, len);\n\t\t\tif (!tmp) {\n\t\t\t\trv = errno;\n\t\t\t\tgoto cleanup_f;\n\t\t\t}\n\t\t\t*buf = tmp;\n\t\t\t*size = len;\n\t\t}\n\n\t\tif (!fread(*buf, len, 1, f)) {\n\t\t\trv = ferror(f) ? errno : EIO;\n\t\t\tgoto cleanup_f;\n\t\t}\n\n\t\tif (groupbuf[GRMEMCNT] + 1 > *nmem) {\n\t\t\tif (groupbuf[GRMEMCNT] + 1 > SIZE_MAX/sizeof(char*)) {\n\t\t\t\trv = ENOMEM;\n\t\t\t\tgoto cleanup_f;\n\t\t\t}\n\t\t\tchar **tmp = realloc(*mem, (groupbuf[GRMEMCNT]+1)*sizeof(char*));\n\t\t\tif (!tmp) {\n\t\t\t\trv = errno;\n\t\t\t\tgoto cleanup_f;\n\t\t\t}\n\t\t\t*mem = tmp;\n\t\t\t*nmem = groupbuf[GRMEMCNT] + 1;\n\t\t}\n\n\t\tif (groupbuf[GRMEMCNT]) {\n\t\t\tmem[0][0] = *buf + groupbuf[GRNAMELEN] + groupbuf[GRPASSWDLEN];\n\t\t\tfor (ptr = mem[0][0], i = 0; ptr != mem[0][0]+grlist_len; ptr++)\n\t\t\t\tif (!*ptr) mem[0][++i] = ptr+1;\n\t\t\tmem[0][i] = 0;\n\n\t\t\tif (i != groupbuf[GRMEMCNT]) {\n\t\t\t\trv = EIO;\n\t\t\t\tgoto cleanup_f;\n\t\t\t}\n\t\t} else {\n\t\t\tmem[0][0] = 0;\n\t\t}\n\n\t\tgr->gr_name = *buf;\n\t\tgr->gr_passwd = gr->gr_name + groupbuf[GRNAMELEN];\n\t\tgr->gr_gid = groupbuf[GRGID];\n\t\tgr->gr_mem = *mem;\n\n\t\tif (gr->gr_passwd[-1]\n\t\t|| gr->gr_passwd[groupbuf[GRPASSWDLEN]-1]) {\n\t\t\trv = EIO;\n\t\t\tgoto cleanup_f;\n\t\t}\n\n\t\tif (name && strcmp(name, gr->gr_name)\n\t\t|| !name && gid != gr->gr_gid) {\n\t\t\trv = EIO;\n\t\t\tgoto cleanup_f;\n\t\t}\n\n\t\t*res = gr;\n\ncleanup_f:\n\t\tfclose(f);\n\t\tgoto done;\n\t}\n\ndone:\n\tpthread_setcancelstate(cs, 0);\n\tif (rv) errno = rv;\n\treturn rv;\n}\n"
  },
  {
    "path": "user.libc/src/passwd/getgr_r.c",
    "content": "#include \"pwf.h\"\n#include <pthread.h>\n\n#define FIX(x) (gr->gr_##x = gr->gr_##x-line+buf)\n\nstatic int getgr_r(const char *name, gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)\n{\n\tchar *line = 0;\n\tsize_t len = 0;\n\tchar **mem = 0;\n\tsize_t nmem = 0;\n\tint rv = 0;\n\tsize_t i;\n\tint cs;\n\n\tpthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);\n\n\trv = __getgr_a(name, gid, gr, &line, &len, &mem, &nmem, res);\n\tif (*res && size < len + (nmem+1)*sizeof(char *) + 32) {\n\t\t*res = 0;\n\t\trv = ERANGE;\n\t}\n\tif (*res) {\n\t\tbuf += (16-(uintptr_t)buf)%16;\n\t\tgr->gr_mem = (void *)buf;\n\t\tbuf += (nmem+1)*sizeof(char *);\n\t\tmemcpy(buf, line, len);\n\t\tFIX(name);\n\t\tFIX(passwd);\n\t\tfor (i=0; mem[i]; i++)\n\t\t\tgr->gr_mem[i] = mem[i]-line+buf;\n\t\tgr->gr_mem[i] = 0;\n\t}\n \tfree(mem);\n \tfree(line);\n\tpthread_setcancelstate(cs, 0);\n\tif (rv) errno = rv;\n\treturn rv;\n}\n\nint getgrnam_r(const char *name, struct group *gr, char *buf, size_t size, struct group **res)\n{\n\treturn getgr_r(name, 0, gr, buf, size, res);\n}\n\nint getgrgid_r(gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)\n{\n\treturn getgr_r(0, gid, gr, buf, size, res);\n}\n"
  },
  {
    "path": "user.libc/src/passwd/getgrent.c",
    "content": "#include \"pwf.h\"\n\nstatic FILE *f;\nstatic char *line, **mem;\nstatic struct group gr;\n\nvoid setgrent()\n{\n\tif (f) fclose(f);\n\tf = 0;\n}\n\nweak_alias(setgrent, endgrent);\n\nstruct group *getgrent()\n{\n\tstruct group *res;\n\tsize_t size=0, nmem=0;\n\tif (!f) f = fopen(\"/etc/group\", \"rbe\");\n\tif (!f) return 0;\n\t__getgrent_a(f, &gr, &line, &size, &mem, &nmem, &res);\n\treturn res;\n}\n\nstruct group *getgrgid(gid_t gid)\n{\n\tstruct group *res;\n\tsize_t size=0, nmem=0;\n\t__getgr_a(0, gid, &gr, &line, &size, &mem, &nmem, &res);\n\treturn res;\n}\n\nstruct group *getgrnam(const char *name)\n{\n\tstruct group *res;\n\tsize_t size=0, nmem=0;\n\t__getgr_a(name, 0, &gr, &line, &size, &mem, &nmem, &res);\n\treturn res;\n}\n"
  },
  {
    "path": "user.libc/src/passwd/getgrent_a.c",
    "content": "#include \"pwf.h\"\n#include <pthread.h>\n\nstatic unsigned atou(char **s)\n{\n\tunsigned x;\n\tfor (x=0; **s-'0'<10U; ++*s) x=10*x+(**s-'0');\n\treturn x;\n}\n\nint __getgrent_a(FILE *f, struct group *gr, char **line, size_t *size, char ***mem, size_t *nmem, struct group **res)\n{\n\tssize_t l;\n\tchar *s, *mems;\n\tsize_t i;\n\tint rv = 0;\n\tint cs;\n\tpthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);\n\tfor (;;) {\n\t\tif ((l=getline(line, size, f)) < 0) {\n\t\t\trv = ferror(f) ? errno : 0;\n\t\t\tfree(*line);\n\t\t\t*line = 0;\n\t\t\tgr = 0;\n\t\t\tgoto end;\n\t\t}\n\t\tline[0][l-1] = 0;\n\n\t\ts = line[0];\n\t\tgr->gr_name = s++;\n\t\tif (!(s = strchr(s, ':'))) continue;\n\n\t\t*s++ = 0; gr->gr_passwd = s;\n\t\tif (!(s = strchr(s, ':'))) continue;\n\n\t\t*s++ = 0; gr->gr_gid = atou(&s);\n\t\tif (*s != ':') continue;\n\n\t\t*s++ = 0; mems = s;\n\t\tbreak;\n\t}\n\n\tfor (*nmem=!!*s; *s; s++)\n\t\tif (*s==',') ++*nmem;\n\tfree(*mem);\n\t*mem = calloc(sizeof(char *), *nmem+1);\n\tif (!*mem) {\n\t\trv = errno;\n\t\tfree(*line);\n\t\t*line = 0;\n\t\tgr = 0;\n\t\tgoto end;\n\t}\n\tif (*mems) {\n\t\tmem[0][0] = mems;\n\t\tfor (s=mems, i=0; *s; s++)\n\t\t\tif (*s==',') *s++ = 0, mem[0][++i] = s;\n\t\tmem[0][++i] = 0;\n\t} else {\n\t\tmem[0][0] = 0;\n\t}\n\tgr->gr_mem = *mem;\nend:\n\tpthread_setcancelstate(cs, 0);\n\t*res = gr;\n\tif(rv) errno = rv;\n\treturn rv;\n}\n"
  },
  {
    "path": "user.libc/src/passwd/getgrouplist.c",
    "content": "#define _GNU_SOURCE\n#include \"pwf.h\"\n#include <grp.h>\n#include <string.h>\n#include <limits.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <byteswap.h>\n#include <errno.h>\n#include \"nscd.h\"\n\nint getgrouplist(const char *user, gid_t gid, gid_t *groups, int *ngroups)\n{\n\tint rv, nlim, ret = -1;\n\tssize_t i, n = 1;\n\tstruct group gr;\n\tstruct group *res;\n\tFILE *f;\n\tint swap = 0;\n\tint32_t resp[INITGR_LEN];\n\tuint32_t *nscdbuf = 0;\n\tchar *buf = 0;\n\tchar **mem = 0;\n\tsize_t nmem = 0;\n\tsize_t size;\n\tnlim = *ngroups;\n\tif (nlim >= 1) *groups++ = gid;\n\n\tf = __nscd_query(GETINITGR, user, resp, sizeof resp, &swap);\n\tif (!f) goto cleanup;\n\tif (resp[INITGRFOUND]) {\n\t\tnscdbuf = calloc(resp[INITGRNGRPS], sizeof(uint32_t));\n\t\tif (!nscdbuf) goto cleanup;\n\t\tsize_t nbytes = sizeof(*nscdbuf)*resp[INITGRNGRPS];\n\t\tif (nbytes && !fread(nscdbuf, nbytes, 1, f)) {\n\t\t\tif (!ferror(f)) errno = EIO;\n\t\t\tgoto cleanup;\n\t\t}\n\t\tif (swap) {\n\t\t\tfor (i = 0; i < resp[INITGRNGRPS]; i++)\n\t\t\t\tnscdbuf[i] = bswap_32(nscdbuf[i]);\n\t\t}\n\t}\n\tfclose(f);\n\n\tf = fopen(\"/etc/group\", \"rbe\");\n\tif (!f && errno != ENOENT && errno != ENOTDIR)\n\t\tgoto cleanup;\n\n\tif (f) {\n\t\twhile (!(rv = __getgrent_a(f, &gr, &buf, &size, &mem, &nmem, &res)) && res) {\n\t\t\tif (nscdbuf)\n\t\t\t\tfor (i=0; i < resp[INITGRNGRPS]; i++) {\n\t\t\t\t\tif (nscdbuf[i] == gr.gr_gid) nscdbuf[i] = gid;\n\t\t\t\t}\n\t\t\tfor (i=0; gr.gr_mem[i] && strcmp(user, gr.gr_mem[i]); i++);\n\t\t\tif (!gr.gr_mem[i]) continue;\n\t\t\tif (++n <= nlim) *groups++ = gr.gr_gid;\n\t\t}\n\t\tif (rv) {\n\t\t\terrno = rv;\n\t\t\tgoto cleanup;\n\t\t}\n\t}\n\tif (nscdbuf) {\n\t\tfor(i=0; i < resp[INITGRNGRPS]; i++) {\n\t\t\tif (nscdbuf[i] != gid)\n\t\t\t\tif(++n <= nlim) *groups++ = nscdbuf[i];\n\t\t}\n\t}\n\n\tret = n > nlim ? -1 : n;\n\t*ngroups = n;\n\ncleanup:\n\tif (f) fclose(f);\n\tfree(nscdbuf);\n\tfree(buf);\n\tfree(mem);\n\treturn ret;\n}\n"
  },
  {
    "path": "user.libc/src/passwd/getpw_a.c",
    "content": "#include <pthread.h>\n#include <byteswap.h>\n#include <string.h>\n#include <unistd.h>\n#include \"pwf.h\"\n#include \"nscd.h\"\n\nstatic char *itoa(char *p, uint32_t x)\n{\n\t// number of digits in a uint32_t + NUL\n\tp += 11;\n\t*--p = 0;\n\tdo {\n\t\t*--p = '0' + x % 10;\n\t\tx /= 10;\n\t} while (x);\n\treturn p;\n}\n\nint __getpw_a(const char *name, uid_t uid, struct passwd *pw, char **buf, size_t *size, struct passwd **res)\n{\n\tFILE *f;\n\tint cs;\n\tint rv = 0;\n\n\t*res = 0;\n\n\tpthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);\n\n\tf = fopen(\"/etc/passwd\", \"rbe\");\n\tif (!f) {\n\t\trv = errno;\n\t\tgoto done;\n\t}\n\n\twhile (!(rv = __getpwent_a(f, pw, buf, size, res)) && *res) {\n\t\tif (name && !strcmp(name, (*res)->pw_name)\n\t\t|| !name && (*res)->pw_uid == uid)\n\t\t\tbreak;\n\t}\n\tfclose(f);\n\n\tif (!*res && (rv == 0 || rv == ENOENT || rv == ENOTDIR)) {\n\t\tint32_t req = name ? GETPWBYNAME : GETPWBYUID;\n\t\tconst char *key;\n\t\tint32_t passwdbuf[PW_LEN] = {0};\n\t\tsize_t len = 0;\n\t\tchar uidbuf[11] = {0};\n\n\t\tif (name) {\n\t\t\tkey = name;\n\t\t} else {\n\t\t\t/* uid outside of this range can't be queried with the\n\t\t\t * nscd interface, but might happen if uid_t ever\n\t\t\t * happens to be a larger type (this is not true as of\n\t\t\t * now)\n\t\t\t */\n\t\t\tif(uid < 0 || uid > UINT32_MAX) {\n\t\t\t\trv = 0;\n\t\t\t\tgoto done;\n\t\t\t}\n\t\t\tkey = itoa(uidbuf, uid);\n\t\t}\n\n\t\tf = __nscd_query(req, key, passwdbuf, sizeof passwdbuf, (int[]){0});\n\t\tif (!f) { rv = errno; goto done; }\n\n\t\tif(!passwdbuf[PWFOUND]) { rv = 0; goto cleanup_f; }\n\n\t\t/* A zero length response from nscd is invalid. We ignore\n\t\t * invalid responses and just report an error, rather than\n\t\t * trying to do something with them.\n\t\t */\n\t\tif (!passwdbuf[PWNAMELEN] || !passwdbuf[PWPASSWDLEN]\n\t\t|| !passwdbuf[PWGECOSLEN] || !passwdbuf[PWDIRLEN]\n\t\t|| !passwdbuf[PWSHELLLEN]) {\n\t\t\trv = EIO;\n\t\t\tgoto cleanup_f;\n\t\t}\n\n\t\tif ((passwdbuf[PWNAMELEN]|passwdbuf[PWPASSWDLEN]\n\t\t     |passwdbuf[PWGECOSLEN]|passwdbuf[PWDIRLEN]\n\t\t     |passwdbuf[PWSHELLLEN]) >= SIZE_MAX/8) {\n\t\t\trv = ENOMEM;\n\t\t\tgoto cleanup_f;\n\t\t}\n\n\t\tlen = passwdbuf[PWNAMELEN] + passwdbuf[PWPASSWDLEN]\n\t\t    + passwdbuf[PWGECOSLEN] + passwdbuf[PWDIRLEN]\n\t\t    + passwdbuf[PWSHELLLEN];\n\n\t\tif (len > *size || !*buf) {\n\t\t\tchar *tmp = realloc(*buf, len);\n\t\t\tif (!tmp) {\n\t\t\t\trv = errno;\n\t\t\t\tgoto cleanup_f;\n\t\t\t}\n\t\t\t*buf = tmp;\n\t\t\t*size = len;\n\t\t}\n\n\t\tif (!fread(*buf, len, 1, f)) {\n\t\t\trv = ferror(f) ? errno : EIO;\n\t\t\tgoto cleanup_f;\n\t\t}\n\n\t\tpw->pw_name = *buf;\n\t\tpw->pw_passwd = pw->pw_name + passwdbuf[PWNAMELEN];\n\t\tpw->pw_gecos = pw->pw_passwd + passwdbuf[PWPASSWDLEN];\n\t\tpw->pw_dir = pw->pw_gecos + passwdbuf[PWGECOSLEN];\n\t\tpw->pw_shell = pw->pw_dir + passwdbuf[PWDIRLEN];\n\t\tpw->pw_uid = passwdbuf[PWUID];\n\t\tpw->pw_gid = passwdbuf[PWGID];\n\n\t\t/* Don't assume that nscd made sure to null terminate strings.\n\t\t * It's supposed to, but malicious nscd should be ignored\n\t\t * rather than causing a crash.\n\t\t */\n\t\tif (pw->pw_passwd[-1] || pw->pw_gecos[-1] || pw->pw_dir[-1]\n\t\t|| pw->pw_shell[passwdbuf[PWSHELLLEN]-1]) {\n\t\t\trv = EIO;\n\t\t\tgoto cleanup_f;\n\t\t}\n\n\t\tif (name && strcmp(name, pw->pw_name)\n\t\t|| !name && uid != pw->pw_uid) {\n\t\t\trv = EIO;\n\t\t\tgoto cleanup_f;\n\t\t}\n\n\n\t\t*res = pw;\ncleanup_f:\n\t\tfclose(f);\n\t\tgoto done;\n\t}\n\ndone:\n\tpthread_setcancelstate(cs, 0);\n\tif (rv) errno = rv;\n\treturn rv;\n}\n"
  },
  {
    "path": "user.libc/src/passwd/getpw_r.c",
    "content": "#include \"pwf.h\"\n#include <pthread.h>\n\n#define FIX(x) (pw->pw_##x = pw->pw_##x-line+buf)\n\nstatic int getpw_r(const char *name, uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)\n{\n\tchar *line = 0;\n\tsize_t len = 0;\n\tint rv = 0;\n\tint cs;\n\n\tpthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);\n\n\trv = __getpw_a(name, uid, pw, &line, &len, res);\n\tif (*res && size < len) {\n\t\t*res = 0;\n\t\trv = ERANGE;\n\t}\n\tif (*res) {\n\t\tmemcpy(buf, line, len);\n\t\tFIX(name);\n\t\tFIX(passwd);\n\t\tFIX(gecos);\n\t\tFIX(dir);\n\t\tFIX(shell);\n\t}\n \tfree(line);\n\tpthread_setcancelstate(cs, 0);\n\tif (rv) errno = rv;\n\treturn rv;\n}\n\nint getpwnam_r(const char *name, struct passwd *pw, char *buf, size_t size, struct passwd **res)\n{\n\treturn getpw_r(name, 0, pw, buf, size, res);\n}\n\nint getpwuid_r(uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)\n{\n\treturn getpw_r(0, uid, pw, buf, size, res);\n}\n"
  },
  {
    "path": "user.libc/src/passwd/getpwent.c",
    "content": "#include \"pwf.h\"\n\nstatic FILE *f;\nstatic char *line;\nstatic struct passwd pw;\nstatic size_t size;\n\nvoid setpwent()\n{\n\tif (f) fclose(f);\n\tf = 0;\n}\n\nweak_alias(setpwent, endpwent);\n\nstruct passwd *getpwent()\n{\n\tstruct passwd *res;\n\tif (!f) f = fopen(\"/etc/passwd\", \"rbe\");\n\tif (!f) return 0;\n\t__getpwent_a(f, &pw, &line, &size, &res);\n\treturn res;\n}\n\nstruct passwd *getpwuid(uid_t uid)\n{\n\tstruct passwd *res;\n\t__getpw_a(0, uid, &pw, &line, &size, &res);\n\treturn res;\n}\n\nstruct passwd *getpwnam(const char *name)\n{\n\tstruct passwd *res;\n\t__getpw_a(name, 0, &pw, &line, &size, &res);\n\treturn res;\n}\n"
  },
  {
    "path": "user.libc/src/passwd/getpwent_a.c",
    "content": "#include \"pwf.h\"\n#include <pthread.h>\n\nstatic unsigned atou(char **s)\n{\n\tunsigned x;\n\tfor (x=0; **s-'0'<10U; ++*s) x=10*x+(**s-'0');\n\treturn x;\n}\n\nint __getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *size, struct passwd **res)\n{\n\tssize_t l;\n\tchar *s;\n\tint rv = 0;\n\tint cs;\n\tpthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);\n\tfor (;;) {\n\t\tif ((l=getline(line, size, f)) < 0) {\n\t\t\trv = ferror(f) ? errno : 0;\n\t\t\tfree(*line);\n\t\t\t*line = 0;\n\t\t\tpw = 0;\n\t\t\tbreak;\n\t\t}\n\t\tline[0][l-1] = 0;\n\n\t\ts = line[0];\n\t\tpw->pw_name = s++;\n\t\tif (!(s = strchr(s, ':'))) continue;\n\n\t\t*s++ = 0; pw->pw_passwd = s;\n\t\tif (!(s = strchr(s, ':'))) continue;\n\n\t\t*s++ = 0; pw->pw_uid = atou(&s);\n\t\tif (*s != ':') continue;\n\n\t\t*s++ = 0; pw->pw_gid = atou(&s);\n\t\tif (*s != ':') continue;\n\n\t\t*s++ = 0; pw->pw_gecos = s;\n\t\tif (!(s = strchr(s, ':'))) continue;\n\n\t\t*s++ = 0; pw->pw_dir = s;\n\t\tif (!(s = strchr(s, ':'))) continue;\n\n\t\t*s++ = 0; pw->pw_shell = s;\n\t\tbreak;\n\t}\n\tpthread_setcancelstate(cs, 0);\n\t*res = pw;\n\tif (rv) errno = rv;\n\treturn rv;\n}\n"
  },
  {
    "path": "user.libc/src/passwd/getspent.c",
    "content": "#include \"pwf.h\"\n\nvoid setspent()\n{\n}\n\nvoid endspent()\n{\n}\n\nstruct spwd *getspent()\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/passwd/getspnam.c",
    "content": "#include \"pwf.h\"\n\n#define LINE_LIM 256\n\nstruct spwd *getspnam(const char *name)\n{\n\tstatic struct spwd sp;\n\tstatic char *line;\n\tstruct spwd *res;\n\tint e;\n\tint orig_errno = errno;\n\n\tif (!line) line = malloc(LINE_LIM);\n\tif (!line) return 0;\n\te = getspnam_r(name, &sp, line, LINE_LIM, &res);\n\terrno = e ? e : orig_errno;\n\treturn res;\n}\n"
  },
  {
    "path": "user.libc/src/passwd/getspnam_r.c",
    "content": "#include <fcntl.h>\n#include <unistd.h>\n#include <sys/stat.h>\n#include <ctype.h>\n#include <pthread.h>\n#include \"pwf.h\"\n\n/* This implementation support Openwall-style TCB passwords in place of\n * traditional shadow, if the appropriate directories and files exist.\n * Thus, it is careful to avoid following symlinks or blocking on fifos\n * which a malicious user might create in place of his or her TCB shadow\n * file. It also avoids any allocation to prevent memory-exhaustion\n * attacks via huge TCB shadow files. */\n\nstatic long xatol(char **s)\n{\n\tlong x;\n\tif (**s == ':' || **s == '\\n') return -1;\n\tfor (x=0; **s-'0'<10U; ++*s) x=10*x+(**s-'0');\n\treturn x;\n}\n\nint __parsespent(char *s, struct spwd *sp)\n{\n\tsp->sp_namp = s;\n\tif (!(s = strchr(s, ':'))) return -1;\n\t*s = 0;\n\n\tsp->sp_pwdp = ++s;\n\tif (!(s = strchr(s, ':'))) return -1;\n\t*s = 0;\n\n\ts++; sp->sp_lstchg = xatol(&s);\n\tif (*s != ':') return -1;\n\n\ts++; sp->sp_min = xatol(&s);\n\tif (*s != ':') return -1;\n\n\ts++; sp->sp_max = xatol(&s);\n\tif (*s != ':') return -1;\n\n\ts++; sp->sp_warn = xatol(&s);\n\tif (*s != ':') return -1;\n\n\ts++; sp->sp_inact = xatol(&s);\n\tif (*s != ':') return -1;\n\n\ts++; sp->sp_expire = xatol(&s);\n\tif (*s != ':') return -1;\n\n\ts++; sp->sp_flag = xatol(&s);\n\tif (*s != '\\n') return -1;\n\treturn 0;\n}\n\nstatic void cleanup(void *p)\n{\n\tfclose(p);\n}\n\nint getspnam_r(const char *name, struct spwd *sp, char *buf, size_t size, struct spwd **res)\n{\n\tchar path[20+NAME_MAX];\n\tFILE *f = 0;\n\tint rv = 0;\n\tint fd;\n\tsize_t k, l = strlen(name);\n\tint skip = 0;\n\tint cs;\n\tint orig_errno = errno;\n\n\t*res = 0;\n\n\t/* Disallow potentially-malicious user names */\n\tif (*name=='.' || strchr(name, '/') || !l)\n\t\treturn errno = EINVAL;\n\n\t/* Buffer size must at least be able to hold name, plus some.. */\n\tif (size < l+100)\n\t\treturn errno = ERANGE;\n\n\t/* Protect against truncation */\n\tif (snprintf(path, sizeof path, \"/etc/tcb/%s/shadow\", name) >= sizeof path)\n\t\treturn errno = EINVAL;\n\n\tfd = open(path, O_RDONLY|O_NOFOLLOW|O_NONBLOCK|O_CLOEXEC);\n\tif (fd >= 0) {\n\t\tstruct stat st = { 0 };\n\t\terrno = EINVAL;\n\t\tif (fstat(fd, &st) || !S_ISREG(st.st_mode) || !(f = fdopen(fd, \"rb\"))) {\n\t\t\tpthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);\n\t\t\tclose(fd);\n\t\t\tpthread_setcancelstate(cs, 0);\n\t\t\treturn errno;\n\t\t}\n\t} else {\n\t\tif (errno != ENOENT && errno != ENOTDIR)\n\t\t\treturn errno;\n\t\tf = fopen(\"/etc/shadow\", \"rbe\");\n\t\tif (!f) {\n\t\t\tif (errno != ENOENT && errno != ENOTDIR)\n\t\t\t\treturn errno;\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\tpthread_cleanup_push(cleanup, f);\n\twhile (fgets(buf, size, f) && (k=strlen(buf))>0) {\n\t\tif (skip || strncmp(name, buf, l) || buf[l]!=':') {\n\t\t\tskip = buf[k-1] != '\\n';\n\t\t\tcontinue;\n\t\t}\n\t\tif (buf[k-1] != '\\n') {\n\t\t\trv = ERANGE;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (__parsespent(buf, sp) < 0) continue;\n\t\t*res = sp;\n\t\tbreak;\n\t}\n\tpthread_cleanup_pop(1);\n\terrno = rv ? rv : orig_errno;\n\treturn rv;\n}\n"
  },
  {
    "path": "user.libc/src/passwd/lckpwdf.c",
    "content": "#include <shadow.h>\n\nint lckpwdf()\n{\n\treturn 0;\n}\n\nint ulckpwdf()\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/passwd/nscd.h",
    "content": "#ifndef NSCD_H\n#define NSCD_H\n\n#include <stdint.h>\n\n#define NSCDVERSION 2\n#define GETPWBYNAME 0\n#define GETPWBYUID 1\n#define GETGRBYNAME 2\n#define GETGRBYGID 3\n#define GETINITGR 15\n\n#define REQVERSION 0\n#define REQTYPE 1\n#define REQKEYLEN 2\n#define REQ_LEN 3\n\n#define PWVERSION 0\n#define PWFOUND 1\n#define PWNAMELEN 2\n#define PWPASSWDLEN 3\n#define PWUID 4\n#define PWGID 5\n#define PWGECOSLEN 6\n#define PWDIRLEN 7\n#define PWSHELLLEN 8\n#define PW_LEN 9\n\n#define GRVERSION 0\n#define GRFOUND 1\n#define GRNAMELEN 2\n#define GRPASSWDLEN 3\n#define GRGID 4\n#define GRMEMCNT 5\n#define GR_LEN 6\n\n#define INITGRVERSION 0\n#define INITGRFOUND 1\n#define INITGRNGRPS 2\n#define INITGR_LEN 3\n\nhidden FILE *__nscd_query(int32_t req, const char *key, int32_t *buf, size_t len, int *swap);\n\n#endif\n"
  },
  {
    "path": "user.libc/src/passwd/nscd_query.c",
    "content": "#include <sys/socket.h>\n#include <byteswap.h>\n#include <unistd.h>\n#include <stdio.h>\n#include <string.h>\n#include <errno.h>\n#include <limits.h>\n#include \"nscd.h\"\n\nstatic const struct {\n\tshort sun_family;\n\tchar sun_path[21];\n} addr = {\n\tAF_UNIX,\n\t\"/var/run/nscd/socket\"\n};\n\nFILE *__nscd_query(int32_t req, const char *key, int32_t *buf, size_t len, int *swap)\n{\n\tsize_t i;\n\tint fd;\n\tFILE *f = 0;\n\tint32_t req_buf[REQ_LEN] = {\n\t\tNSCDVERSION,\n\t\treq,\n\t\tstrnlen(key,LOGIN_NAME_MAX)+1\n\t};\n\tstruct msghdr msg = {\n\t\t.msg_iov = (struct iovec[]){\n\t\t\t{&req_buf, sizeof(req_buf)},\n\t\t\t{(char*)key, strlen(key)+1}\n\t\t},\n\t\t.msg_iovlen = 2\n\t};\n\tint errno_save = errno;\n\n\t*swap = 0;\nretry:\n\tmemset(buf, 0, len);\n\tbuf[0] = NSCDVERSION;\n\n\tfd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);\n\tif (fd < 0) return NULL;\n\n\tif(!(f = fdopen(fd, \"r\"))) {\n\t\tclose(fd);\n\t\treturn 0;\n\t}\n\n\tif (req_buf[2] > LOGIN_NAME_MAX)\n\t\treturn f;\n\n\tif (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {\n\t\t/* If there isn't a running nscd we simulate a \"not found\"\n\t\t * result and the caller is responsible for calling\n\t\t * fclose on the (unconnected) socket. The value of\n\t\t * errno must be left unchanged in this case.  */\n\t\tif (errno == EACCES || errno == ECONNREFUSED || errno == ENOENT) {\n\t\t\terrno = errno_save;\n\t\t\treturn f;\n\t\t}\n\t\tgoto error;\n\t}\n\n\tif (sendmsg(fd, &msg, MSG_NOSIGNAL) < 0)\n\t\tgoto error;\n\n\tif (!fread(buf, len, 1, f)) {\n\t\t/* If the VERSION entry mismatches nscd will disconnect. The\n\t\t * most likely cause is that the endianness mismatched. So, we\n\t\t * byteswap and try once more. (if we already swapped, just\n\t\t * fail out)\n\t\t */\n\t\tif (ferror(f)) goto error;\n\t\tif (!*swap) {\n\t\t\tfclose(f);\n\t\t\tfor (i = 0; i < sizeof(req_buf)/sizeof(req_buf[0]); i++) {\n\t\t\t\treq_buf[i] = bswap_32(req_buf[i]);\n\t\t\t}\n\t\t\t*swap = 1;\n\t\t\tgoto retry;\n\t\t} else {\n\t\t\terrno = EIO;\n\t\t\tgoto error;\n\t\t}\n\t}\n\n\tif (*swap) {\n\t\tfor (i = 0; i < len/sizeof(buf[0]); i++) {\n\t\t\tbuf[i] = bswap_32(buf[i]);\n\t\t}\n\t}\n\n\t/* The first entry in every nscd response is the version number. This\n\t * really shouldn't happen, and is evidence of some form of malformed\n\t * response.\n\t */\n\tif(buf[0] != NSCDVERSION) {\n\t\terrno = EIO;\n\t\tgoto error;\n\t}\n\n\treturn f;\nerror:\n\tfclose(f);\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/passwd/putgrent.c",
    "content": "#define _GNU_SOURCE\n#include <grp.h>\n#include <stdio.h>\n\nint putgrent(const struct group *gr, FILE *f)\n{\n\tint r;\n\tsize_t i;\n\tflockfile(f);\n\tif ((r = fprintf(f, \"%s:%s:%u:\", gr->gr_name, gr->gr_passwd, gr->gr_gid))<0) goto done;\n\tif (gr->gr_mem) for (i=0; gr->gr_mem[i]; i++)\n\t\tif ((r = fprintf(f, \"%s%s\", i?\",\":\"\", gr->gr_mem[i]))<0) goto done;\n\tr = fputc('\\n', f);\ndone:\n\tfunlockfile(f);\n\treturn r<0 ? -1 : 0;\n}\n"
  },
  {
    "path": "user.libc/src/passwd/putpwent.c",
    "content": "#define _GNU_SOURCE\n#include <pwd.h>\n#include <stdio.h>\n\nint putpwent(const struct passwd *pw, FILE *f)\n{\n\treturn fprintf(f, \"%s:%s:%u:%u:%s:%s:%s\\n\",\n\t\tpw->pw_name, pw->pw_passwd, pw->pw_uid, pw->pw_gid,\n\t\tpw->pw_gecos, pw->pw_dir, pw->pw_shell)<0 ? -1 : 0;\n}\n"
  },
  {
    "path": "user.libc/src/passwd/putspent.c",
    "content": "#include <shadow.h>\n#include <stdio.h>\n\n#define NUM(n) ((n) == -1 ? 0 : -1), ((n) == -1 ? 0 : (n))\n#define STR(s) ((s) ? (s) : \"\")\n\nint putspent(const struct spwd *sp, FILE *f)\n{\n\treturn fprintf(f, \"%s:%s:%.*ld:%.*ld:%.*ld:%.*ld:%.*ld:%.*ld:%.*lu\\n\",\n\t\tSTR(sp->sp_namp), STR(sp->sp_pwdp), NUM(sp->sp_lstchg),\n\t\tNUM(sp->sp_min), NUM(sp->sp_max), NUM(sp->sp_warn),\n\t\tNUM(sp->sp_inact), NUM(sp->sp_expire), NUM(sp->sp_flag)) < 0 ? -1 : 0;\n}\n"
  },
  {
    "path": "user.libc/src/passwd/pwf.h",
    "content": "#include <pwd.h>\n#include <grp.h>\n#include <shadow.h>\n#include <stdio.h>\n#include <errno.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n#include <limits.h>\n\nhidden int __getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *size, struct passwd **res);\nhidden int __getpw_a(const char *name, uid_t uid, struct passwd *pw, char **buf, size_t *size, struct passwd **res);\nhidden int __getgrent_a(FILE *f, struct group *gr, char **line, size_t *size, char ***mem, size_t *nmem, struct group **res);\nhidden int __getgr_a(const char *name, gid_t gid, struct group *gr, char **buf, size_t *size, char ***mem, size_t *nmem, struct group **res);\nhidden int __parsespent(char *s, struct spwd *sp);\n"
  },
  {
    "path": "user.libc/src/prng/__rand48_step.c",
    "content": "#include <stdint.h>\n#include \"rand48.h\"\n\nuint64_t __rand48_step(unsigned short *xi, unsigned short *lc)\n{\n\tuint64_t a, x;\n\tx = xi[0] | xi[1]+0U<<16 | xi[2]+0ULL<<32;\n\ta = lc[0] | lc[1]+0U<<16 | lc[2]+0ULL<<32;\n\tx = a*x + lc[3];\n\txi[0] = x;\n\txi[1] = x>>16;\n\txi[2] = x>>32;\n\treturn x & 0xffffffffffffull;\n}\n"
  },
  {
    "path": "user.libc/src/prng/__seed48.c",
    "content": "#include \"rand48.h\"\n\nunsigned short __seed48[7] = { 0, 0, 0, 0xe66d, 0xdeec, 0x5, 0xb };\n"
  },
  {
    "path": "user.libc/src/prng/drand48.c",
    "content": "#include <stdlib.h>\n#include <inttypes.h>\n#include \"rand48.h\"\n\ndouble erand48(unsigned short s[3])\n{\n\tunion {\n\t\tuint64_t u;\n\t\tdouble f;\n\t} x = { 0x3ff0000000000000ULL | __rand48_step(s, __seed48+3)<<4 };\n\treturn x.f - 1.0;\n}\n\ndouble drand48(void)\n{\n\treturn erand48(__seed48);\n}\n"
  },
  {
    "path": "user.libc/src/prng/lcong48.c",
    "content": "#include <stdlib.h>\n#include <string.h>\n#include \"rand48.h\"\n\nvoid lcong48(unsigned short p[7])\n{\n\tmemcpy(__seed48, p, sizeof __seed48);\n}\n"
  },
  {
    "path": "user.libc/src/prng/lrand48.c",
    "content": "#include <stdlib.h>\n#include <inttypes.h>\n#include \"rand48.h\"\n\nlong nrand48(unsigned short s[3])\n{\n\treturn __rand48_step(s, __seed48+3) >> 17;\n}\n\nlong lrand48(void)\n{\n\treturn nrand48(__seed48);\n}\n"
  },
  {
    "path": "user.libc/src/prng/mrand48.c",
    "content": "#include <stdlib.h>\n#include <inttypes.h>\n#include \"rand48.h\"\n\nlong jrand48(unsigned short s[3])\n{\n\treturn (int32_t)(__rand48_step(s, __seed48+3) >> 16);\n}\n\nlong mrand48(void)\n{\n\treturn jrand48(__seed48);\n}\n"
  },
  {
    "path": "user.libc/src/prng/rand.c",
    "content": "#include <stdlib.h>\n#include <stdint.h>\n\nstatic uint64_t seed;\n\nvoid srand(unsigned s)\n{\n\tseed = s-1;\n}\n\nint rand(void)\n{\n\tseed = 6364136223846793005ULL*seed + 1;\n\treturn seed>>33;\n}\n"
  },
  {
    "path": "user.libc/src/prng/rand48.h",
    "content": "#include <stdint.h>\n#include <features.h>\n\nhidden uint64_t __rand48_step(unsigned short *xi, unsigned short *lc);\nextern hidden unsigned short __seed48[7];\n"
  },
  {
    "path": "user.libc/src/prng/rand_r.c",
    "content": "#include <stdlib.h>\n\nstatic unsigned temper(unsigned x)\n{\n\tx ^= x>>11;\n\tx ^= x<<7 & 0x9D2C5680;\n\tx ^= x<<15 & 0xEFC60000;\n\tx ^= x>>18;\n\treturn x;\n}\n\nint rand_r(unsigned *seed)\n{\n\treturn temper(*seed = *seed * 1103515245 + 12345)/2;\n}\n"
  },
  {
    "path": "user.libc/src/prng/random.c",
    "content": "#include <stdlib.h>\n#include <stdint.h>\n#include \"lock.h\"\n#include \"fork_impl.h\"\n\n/*\nthis code uses the same lagged fibonacci generator as the\noriginal bsd random implementation except for the seeding\nwhich was broken in the original\n*/\n\nstatic uint32_t init[] = {\n0x00000000,0x5851f42d,0xc0b18ccf,0xcbb5f646,\n0xc7033129,0x30705b04,0x20fd5db4,0x9a8b7f78,\n0x502959d8,0xab894868,0x6c0356a7,0x88cdb7ff,\n0xb477d43f,0x70a3a52b,0xa8e4baf1,0xfd8341fc,\n0x8ae16fd9,0x742d2f7a,0x0d1f0796,0x76035e09,\n0x40f7702c,0x6fa72ca5,0xaaa84157,0x58a0df74,\n0xc74a0364,0xae533cc4,0x04185faf,0x6de3b115,\n0x0cab8628,0xf043bfa4,0x398150e9,0x37521657};\n\nstatic int n = 31;\nstatic int i = 3;\nstatic int j = 0;\nstatic uint32_t *x = init+1;\nstatic volatile int lock[1];\nvolatile int *const __random_lockptr = lock;\n\nstatic uint32_t lcg31(uint32_t x) {\n\treturn (1103515245*x + 12345) & 0x7fffffff;\n}\n\nstatic uint64_t lcg64(uint64_t x) {\n\treturn 6364136223846793005ull*x + 1;\n}\n\nstatic void *savestate() {\n\tx[-1] = (n<<16)|(i<<8)|j;\n\treturn x-1;\n}\n\nstatic void loadstate(uint32_t *state) {\n\tx = state+1;\n\tn = x[-1]>>16;\n\ti = (x[-1]>>8)&0xff;\n\tj = x[-1]&0xff;\n}\n\nstatic void __srandom(unsigned seed) {\n\tint k;\n\tuint64_t s = seed;\n\n\tif (n == 0) {\n\t\tx[0] = s;\n\t\treturn;\n\t}\n\ti = n == 31 || n == 7 ? 3 : 1;\n\tj = 0;\n\tfor (k = 0; k < n; k++) {\n\t\ts = lcg64(s);\n\t\tx[k] = s>>32;\n\t}\n\t/* make sure x contains at least one odd number */\n\tx[0] |= 1;\n}\n\nvoid srandom(unsigned seed) {\n\tLOCK(lock);\n\t__srandom(seed);\n\tUNLOCK(lock);\n}\n\nchar *initstate(unsigned seed, char *state, size_t size) {\n\tvoid *old;\n\n\tif (size < 8)\n\t\treturn 0;\n\tLOCK(lock);\n\told = savestate();\n\tif (size < 32)\n\t\tn = 0;\n\telse if (size < 64)\n\t\tn = 7;\n\telse if (size < 128)\n\t\tn = 15;\n\telse if (size < 256)\n\t\tn = 31;\n\telse\n\t\tn = 63;\n\tx = (uint32_t*)state + 1;\n\t__srandom(seed);\n\tsavestate();\n\tUNLOCK(lock);\n\treturn old;\n}\n\nchar *setstate(char *state) {\n\tvoid *old;\n\n\tLOCK(lock);\n\told = savestate();\n\tloadstate((uint32_t*)state);\n\tUNLOCK(lock);\n\treturn old;\n}\n\nlong random(void) {\n\tlong k;\n\n\tLOCK(lock);\n\tif (n == 0) {\n\t\tk = x[0] = lcg31(x[0]);\n\t\tgoto end;\n\t}\n\tx[i] += x[j];\n\tk = x[i]>>1;\n\tif (++i == n)\n\t\ti = 0;\n\tif (++j == n)\n\t\tj = 0;\nend:\n\tUNLOCK(lock);\n\treturn k;\n}\n"
  },
  {
    "path": "user.libc/src/prng/seed48.c",
    "content": "#include <stdlib.h>\n#include <string.h>\n#include \"rand48.h\"\n\nunsigned short *seed48(unsigned short *s)\n{\n\tstatic unsigned short p[3];\n\tmemcpy(p, __seed48, sizeof p);\n\tmemcpy(__seed48, s, sizeof p);\n\treturn p;\n}\n"
  },
  {
    "path": "user.libc/src/prng/srand48.c",
    "content": "#include <stdlib.h>\n\nvoid srand48(long seed)\n{\n\tseed48((unsigned short [3]){ 0x330e, seed, seed>>16 });\n}\n"
  },
  {
    "path": "user.libc/src/process/execv.c",
    "content": "#include <unistd.h>\n#include <string.h>\n#include <errno.h>\n#include <stdio.h>\n#include <stdlib.h>\n\n#include <minos/kobject.h>\n#include <minos/proto.h>\n#include <minos/types.h>\n\n#include \"pthread_impl.h\"\n\nstatic int setup_argv(struct execv_extra *extra, char *const argv[])\n{\n\tint left = PAGE_SIZE - sizeof(struct execv_extra);\n\tint offset = 0, len, i;\n\tchar *arg, *buf = extra->buf;\n\n\tif (argv == NULL)\n\t\treturn 0;\n\n\tfor (i = 0; i < 32; i++) {\n\t\targ = argv[i];\n\t\tif (arg == NULL)\n\t\t\tbreak;\n\n\t\tlen = strlen(arg) + 1;\n\t\tif (len > left)\n\t\t\treturn -EINVAL;\n\n\t\textra->argv[i] = offset;\n\t\tstrncpy(buf, arg, len);\n\t\toffset += len;\n\t\tleft -= len; \n\t}\n\n\textra->argc = i;\n\treturn 0;\n}\n\nint execv(const char *path, char *const argv[])\n{\n\tstruct execv_extra *extra;\n\tstruct proto proto;\n\tint ret = 0;\n\n\tif (strlen(path) >= FILENAME_MAX)\n\t\treturn -ENAMETOOLONG;\n\n\textra = malloc(PAGE_SIZE);\n\tif (!extra)\n\t\treturn -ENOMEM;\n\n\t/*\n\t * copy the filename and the additional info to the\n\t * buf, then send to the server.\n\t */\n\tmemset((char *)extra, 0, PAGE_SIZE);\n\tif (setup_argv(extra, argv)) {\n\t\tret = -EINVAL;\n\t\tgoto out;\n\t}\n\tstrcpy(extra->path, path);\n\n\tproto.proto_id = PROTO_EXECV;\n\tret = kobject_write(self_handle(), &proto, PROTO_SIZE,\n\t\t\textra, PAGE_SIZE, -1);\nout:\n\tfree(extra);\n\treturn ret;\n}\n"
  },
  {
    "path": "user.libc/src/process/wait.c",
    "content": "#include <sys/wait.h>\n\npid_t wait(int *status)\n{\n\treturn waitpid((pid_t)-1, status, 0);\n}\n"
  },
  {
    "path": "user.libc/src/process/waitid.c",
    "content": "#include <sys/wait.h>\n#include \"syscall.h\"\n\nint waitid(idtype_t type, id_t id, siginfo_t *info, int options)\n{\n\t// return syscall_cp(SYS_waitid, type, id, info, options, 0);\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/process/waitpid.c",
    "content": "#include <sys/wait.h>\n#include \"syscall.h\"\n\n#include <minos/proto.h>\n\npid_t waitpid(pid_t pid, int *status, int options)\n{\n\tstruct proto proto;\n\tlong ret;\n\n\tproto.proto_id = PROTO_WAITPID;\n\tproto.waitpid.pid = pid;\n\tproto.waitpid.options = options;\n\n\tret = sys_send_proto(0, &proto);\n\tif (status)\n\t\t*status = ret & 0xffff;\n\n\treturn (pid_t)(ret >> 16);\n}\n"
  },
  {
    "path": "user.libc/src/regex/fnmatch.c",
    "content": "/*\n * An implementation of what I call the \"Sea of Stars\" algorithm for\n * POSIX fnmatch(). The basic idea is that we factor the pattern into\n * a head component (which we match first and can reject without ever\n * measuring the length of the string), an optional tail component\n * (which only exists if the pattern contains at least one star), and\n * an optional \"sea of stars\", a set of star-separated components\n * between the head and tail. After the head and tail matches have\n * been removed from the input string, the components in the \"sea of\n * stars\" are matched sequentially by searching for their first\n * occurrence past the end of the previous match.\n *\n * - Rich Felker, April 2012\n */\n\n#include <string.h>\n#include <fnmatch.h>\n#include <stdlib.h>\n#include <wchar.h>\n#include <wctype.h>\n#include \"locale_impl.h\"\n\n#define END 0\n#define UNMATCHABLE -2\n#define BRACKET -3\n#define QUESTION -4\n#define STAR -5\n\nstatic int str_next(const char *str, size_t n, size_t *step)\n{\n\tif (!n) {\n\t\t*step = 0;\n\t\treturn 0;\n\t}\n\tif (str[0] >= 128U) {\n\t\twchar_t wc;\n\t\tint k = mbtowc(&wc, str, n);\n\t\tif (k<0) {\n\t\t\t*step = 1;\n\t\t\treturn -1;\n\t\t}\n\t\t*step = k;\n\t\treturn wc;\n\t}\n\t*step = 1;\n\treturn str[0];\n}\n\nstatic int pat_next(const char *pat, size_t m, size_t *step, int flags)\n{\n\tint esc = 0;\n\tif (!m || !*pat) {\n\t\t*step = 0;\n\t\treturn END;\n\t}\n\t*step = 1;\n\tif (pat[0]=='\\\\' && pat[1] && !(flags & FNM_NOESCAPE)) {\n\t\t*step = 2;\n\t\tpat++;\n\t\tesc = 1;\n\t\tgoto escaped;\n\t}\n\tif (pat[0]=='[') {\n\t\tsize_t k = 1;\n\t\tif (k<m) if (pat[k] == '^' || pat[k] == '!') k++;\n\t\tif (k<m) if (pat[k] == ']') k++;\n\t\tfor (; k<m && pat[k] && pat[k]!=']'; k++) {\n\t\t\tif (k+1<m && pat[k+1] && pat[k]=='[' && (pat[k+1]==':' || pat[k+1]=='.' || pat[k+1]=='=')) {\n\t\t\t\tint z = pat[k+1];\n\t\t\t\tk+=2;\n\t\t\t\tif (k<m && pat[k]) k++;\n\t\t\t\twhile (k<m && pat[k] && (pat[k-1]!=z || pat[k]!=']')) k++;\n\t\t\t\tif (k==m || !pat[k]) break;\n\t\t\t}\n\t\t}\n\t\tif (k==m || !pat[k]) {\n\t\t\t*step = 1;\n\t\t\treturn '[';\n\t\t}\n\t\t*step = k+1;\n\t\treturn BRACKET;\n\t}\n\tif (pat[0] == '*')\n\t\treturn STAR;\n\tif (pat[0] == '?')\n\t\treturn QUESTION;\nescaped:\n\tif (pat[0] >= 128U) {\n\t\twchar_t wc;\n\t\tint k = mbtowc(&wc, pat, m);\n\t\tif (k<0) {\n\t\t\t*step = 0;\n\t\t\treturn UNMATCHABLE;\n\t\t}\n\t\t*step = k + esc;\n\t\treturn wc;\n\t}\n\treturn pat[0];\n}\n\nstatic int casefold(int k)\n{\n\tint c = towupper(k);\n\treturn c == k ? towlower(k) : c;\n}\n\nstatic int match_bracket(const char *p, int k, int kfold)\n{\n\twchar_t wc;\n\tint inv = 0;\n\tp++;\n\tif (*p=='^' || *p=='!') {\n\t\tinv = 1;\n\t\tp++;\n\t}\n\tif (*p==']') {\n\t\tif (k==']') return !inv;\n\t\tp++;\n\t} else if (*p=='-') {\n\t\tif (k=='-') return !inv;\n\t\tp++;\n\t}\n\twc = p[-1];\n\tfor (; *p != ']'; p++) {\n\t\tif (p[0]=='-' && p[1]!=']') {\n\t\t\twchar_t wc2;\n\t\t\tint l = mbtowc(&wc2, p+1, 4);\n\t\t\tif (l < 0) return 0;\n\t\t\tif (wc <= wc2)\n\t\t\t\tif ((unsigned)k-wc <= wc2-wc ||\n\t\t\t\t    (unsigned)kfold-wc <= wc2-wc)\n\t\t\t\t\treturn !inv;\n\t\t\tp += l-1;\n\t\t\tcontinue;\n\t\t}\n\t\tif (p[0]=='[' && (p[1]==':' || p[1]=='.' || p[1]=='=')) {\n\t\t\tconst char *p0 = p+2;\n\t\t\tint z = p[1];\n\t\t\tp+=3;\n\t\t\twhile (p[-1]!=z || p[0]!=']') p++;\n\t\t\tif (z == ':' && p-1-p0 < 16) {\n\t\t\t\tchar buf[16];\n\t\t\t\tmemcpy(buf, p0, p-1-p0);\n\t\t\t\tbuf[p-1-p0] = 0;\n\t\t\t\tif (iswctype(k, wctype(buf)) ||\n\t\t\t\t    iswctype(kfold, wctype(buf)))\n\t\t\t\t\treturn !inv;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (*p < 128U) {\n\t\t\twc = (unsigned char)*p;\n\t\t} else {\n\t\t\tint l = mbtowc(&wc, p, 4);\n\t\t\tif (l < 0) return 0;\n\t\t\tp += l-1;\n\t\t}\n\t\tif (wc==k || wc==kfold) return !inv;\n\t}\n\treturn inv;\n}\n\nstatic int fnmatch_internal(const char *pat, size_t m, const char *str, size_t n, int flags)\n{\n\tconst char *p, *ptail, *endpat;\n\tconst char *s, *stail, *endstr;\n\tsize_t pinc, sinc, tailcnt=0;\n\tint c, k, kfold;\n\n\tif (flags & FNM_PERIOD) {\n\t\tif (*str == '.' && *pat != '.')\n\t\t\treturn FNM_NOMATCH;\n\t}\n\tfor (;;) {\n\t\tswitch ((c = pat_next(pat, m, &pinc, flags))) {\n\t\tcase UNMATCHABLE:\n\t\t\treturn FNM_NOMATCH;\n\t\tcase STAR:\n\t\t\tpat++;\n\t\t\tm--;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tk = str_next(str, n, &sinc);\n\t\t\tif (k <= 0)\n\t\t\t\treturn (c==END) ? 0 : FNM_NOMATCH;\n\t\t\tstr += sinc;\n\t\t\tn -= sinc;\n\t\t\tkfold = flags & FNM_CASEFOLD ? casefold(k) : k;\n\t\t\tif (c == BRACKET) {\n\t\t\t\tif (!match_bracket(pat, k, kfold))\n\t\t\t\t\treturn FNM_NOMATCH;\n\t\t\t} else if (c != QUESTION && k != c && kfold != c) {\n\t\t\t\treturn FNM_NOMATCH;\n\t\t\t}\n\t\t\tpat+=pinc;\n\t\t\tm-=pinc;\n\t\t\tcontinue;\n\t\t}\n\t\tbreak;\n\t}\n\n\t/* Compute real pat length if it was initially unknown/-1 */\n\tm = strnlen(pat, m);\n\tendpat = pat + m;\n\n\t/* Find the last * in pat and count chars needed after it */\n\tfor (p=ptail=pat; p<endpat; p+=pinc) {\n\t\tswitch (pat_next(p, endpat-p, &pinc, flags)) {\n\t\tcase UNMATCHABLE:\n\t\t\treturn FNM_NOMATCH;\n\t\tcase STAR:\n\t\t\ttailcnt=0;\n\t\t\tptail = p+1;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\ttailcnt++;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t/* Past this point we need not check for UNMATCHABLE in pat,\n\t * because all of pat has already been parsed once. */\n\n\t/* Compute real str length if it was initially unknown/-1 */\n\tn = strnlen(str, n);\n\tendstr = str + n;\n\tif (n < tailcnt) return FNM_NOMATCH;\n\n\t/* Find the final tailcnt chars of str, accounting for UTF-8.\n\t * On illegal sequences we may get it wrong, but in that case\n\t * we necessarily have a matching failure anyway. */\n\tfor (s=endstr; s>str && tailcnt; tailcnt--) {\n\t\tif (s[-1] < 128U || MB_CUR_MAX==1) s--;\n\t\telse while ((unsigned char)*--s-0x80U<0x40 && s>str);\n\t}\n\tif (tailcnt) return FNM_NOMATCH;\n\tstail = s;\n\n\t/* Check that the pat and str tails match */\n\tp = ptail;\n\tfor (;;) {\n\t\tc = pat_next(p, endpat-p, &pinc, flags);\n\t\tp += pinc;\n\t\tif ((k = str_next(s, endstr-s, &sinc)) <= 0) {\n\t\t\tif (c != END) return FNM_NOMATCH;\n\t\t\tbreak;\n\t\t}\n\t\ts += sinc;\n\t\tkfold = flags & FNM_CASEFOLD ? casefold(k) : k;\n\t\tif (c == BRACKET) {\n\t\t\tif (!match_bracket(p-pinc, k, kfold))\n\t\t\t\treturn FNM_NOMATCH;\n\t\t} else if (c != QUESTION && k != c && kfold != c) {\n\t\t\treturn FNM_NOMATCH;\n\t\t}\n\t}\n\n\t/* We're all done with the tails now, so throw them out */\n\tendstr = stail;\n\tendpat = ptail;\n\n\t/* Match pattern components until there are none left */\n\twhile (pat<endpat) {\n\t\tp = pat;\n\t\ts = str;\n\t\tfor (;;) {\n\t\t\tc = pat_next(p, endpat-p, &pinc, flags);\n\t\t\tp += pinc;\n\t\t\t/* Encountering * completes/commits a component */\n\t\t\tif (c == STAR) {\n\t\t\t\tpat = p;\n\t\t\t\tstr = s;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tk = str_next(s, endstr-s, &sinc);\n\t\t\tif (!k)\n\t\t\t\treturn FNM_NOMATCH;\n\t\t\tkfold = flags & FNM_CASEFOLD ? casefold(k) : k;\n\t\t\tif (c == BRACKET) {\n\t\t\t\tif (!match_bracket(p-pinc, k, kfold))\n\t\t\t\t\tbreak;\n\t\t\t} else if (c != QUESTION && k != c && kfold != c) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\ts += sinc;\n\t\t}\n\t\tif (c == STAR) continue;\n\t\t/* If we failed, advance str, by 1 char if it's a valid\n\t\t * char, or past all invalid bytes otherwise. */\n\t\tk = str_next(str, endstr-str, &sinc);\n\t\tif (k > 0) str += sinc;\n\t\telse for (str++; str_next(str, endstr-str, &sinc)<0; str++);\n\t}\n\n\treturn 0;\n}\n\nint fnmatch(const char *pat, const char *str, int flags)\n{\n\tconst char *s, *p;\n\tsize_t inc;\n\tint c;\n\tif (flags & FNM_PATHNAME) for (;;) {\n\t\tfor (s=str; *s && *s!='/'; s++);\n\t\tfor (p=pat; (c=pat_next(p, -1, &inc, flags))!=END && c!='/'; p+=inc);\n\t\tif (c!=*s && (!*s || !(flags & FNM_LEADING_DIR)))\n\t\t\treturn FNM_NOMATCH;\n\t\tif (fnmatch_internal(pat, p-pat, str, s-str, flags))\n\t\t\treturn FNM_NOMATCH;\n\t\tif (!c) return 0;\n\t\tstr = s+1;\n\t\tpat = p+inc;\n\t} else if (flags & FNM_LEADING_DIR) {\n\t\tfor (s=str; *s; s++) {\n\t\t\tif (*s != '/') continue;\n\t\t\tif (!fnmatch_internal(pat, -1, str, s-str, flags))\n\t\t\t\treturn 0;\n\t\t}\n\t}\n\treturn fnmatch_internal(pat, -1, str, -1, flags);\n}\n"
  },
  {
    "path": "user.libc/src/regex/glob.c",
    "content": "#define _BSD_SOURCE\n#include <glob.h>\n#include <fnmatch.h>\n#include <sys/stat.h>\n#include <dirent.h>\n#include <limits.h>\n#include <string.h>\n#include <stdlib.h>\n#include <errno.h>\n#include <stddef.h>\n#include <unistd.h>\n#include <pwd.h>\n\nstruct match\n{\n\tstruct match *next;\n\tchar name[];\n};\n\nstatic int append(struct match **tail, const char *name, size_t len, int mark)\n{\n\tstruct match *new = malloc(sizeof(struct match) + len + 2);\n\tif (!new) return -1;\n\t(*tail)->next = new;\n\tnew->next = NULL;\n\tmemcpy(new->name, name, len+1);\n\tif (mark && len && name[len-1]!='/') {\n\t\tnew->name[len] = '/';\n\t\tnew->name[len+1] = 0;\n\t}\n\t*tail = new;\n\treturn 0;\n}\n\nstatic int do_glob(char *buf, size_t pos, int type, char *pat, int flags, int (*errfunc)(const char *path, int err), struct match **tail)\n{\n\t/* If GLOB_MARK is unused, we don't care about type. */\n\tif (!type && !(flags & GLOB_MARK)) type = DT_REG;\n\n\t/* Special-case the remaining pattern being all slashes, in\n\t * which case we can use caller-passed type if it's a dir. */\n\tif (*pat && type!=DT_DIR) type = 0;\n\twhile (pos+1 < PATH_MAX && *pat=='/') buf[pos++] = *pat++;\n\n\t/* Consume maximal [escaped-]literal prefix of pattern, copying\n\t * and un-escaping it to the running buffer as we go. */\n\tptrdiff_t i=0, j=0;\n\tint in_bracket = 0, overflow = 0;\n\tfor (; pat[i]!='*' && pat[i]!='?' && (!in_bracket || pat[i]!=']'); i++) {\n\t\tif (!pat[i]) {\n\t\t\tif (overflow) return 0;\n\t\t\tpat += i;\n\t\t\tpos += j;\n\t\t\ti = j = 0;\n\t\t\tbreak;\n\t\t} else if (pat[i] == '[') {\n\t\t\tin_bracket = 1;\n\t\t} else if (pat[i] == '\\\\' && !(flags & GLOB_NOESCAPE)) {\n\t\t\t/* Backslashes inside a bracket are (at least by\n\t\t\t * our interpretation) non-special, so if next\n\t\t\t * char is ']' we have a complete expression. */\n\t\t\tif (in_bracket && pat[i+1]==']') break;\n\t\t\t/* Unpaired final backslash never matches. */\n\t\t\tif (!pat[i+1]) return 0;\n\t\t\ti++;\n\t\t}\n\t\tif (pat[i] == '/') {\n\t\t\tif (overflow) return 0;\n\t\t\tin_bracket = 0;\n\t\t\tpat += i+1;\n\t\t\ti = -1;\n\t\t\tpos += j+1;\n\t\t\tj = -1;\n\t\t}\n\t\t/* Only store a character if it fits in the buffer, but if\n\t\t * a potential bracket expression is open, the overflow\n\t\t * must be remembered and handled later only if the bracket\n\t\t * is unterminated (and thereby a literal), so as not to\n\t\t * disallow long bracket expressions with short matches. */\n\t\tif (pos+(j+1) < PATH_MAX) {\n\t\t\tbuf[pos+j++] = pat[i];\n\t\t} else if (in_bracket) {\n\t\t\toverflow = 1;\n\t\t} else {\n\t\t\treturn 0;\n\t\t}\n\t\t/* If we consume any new components, the caller-passed type\n\t\t * or dummy type from above is no longer valid. */\n\t\ttype = 0;\n\t}\n\tbuf[pos] = 0;\n\tif (!*pat) {\n\t\t/* If we consumed any components above, or if GLOB_MARK is\n\t\t * requested and we don't yet know if the match is a dir,\n\t\t * we must confirm the file exists and/or determine its type.\n\t\t *\n\t\t * If marking dirs, symlink type is inconclusive; we need the\n\t\t * type for the symlink target, and therefore must try stat\n\t\t * first unless type is known not to be a symlink. Otherwise,\n\t\t * or if that fails, use lstat for determining existence to\n\t\t * avoid false negatives in the case of broken symlinks. */\n\t\tstruct stat st;\n\t\tif ((flags & GLOB_MARK) && (!type||type==DT_LNK) && !stat(buf, &st)) {\n\t\t\tif (S_ISDIR(st.st_mode)) type = DT_DIR;\n\t\t\telse type = DT_REG;\n\t\t}\n\t\tif (!type && lstat(buf, &st)) {\n\t\t\tif (errno!=ENOENT && (errfunc(buf, errno) || (flags & GLOB_ERR)))\n\t\t\t\treturn GLOB_ABORTED;\n\t\t\treturn 0;\n\t\t}\n\t\tif (append(tail, buf, pos, (flags & GLOB_MARK) && type==DT_DIR))\n\t\t\treturn GLOB_NOSPACE;\n\t\treturn 0;\n\t}\n\tchar *p2 = strchr(pat, '/'), saved_sep = '/';\n\t/* Check if the '/' was escaped and, if so, remove the escape char\n\t * so that it will not be unpaired when passed to fnmatch. */\n\tif (p2 && !(flags & GLOB_NOESCAPE)) {\n\t\tchar *p;\n\t\tfor (p=p2; p>pat && p[-1]=='\\\\'; p--);\n\t\tif ((p2-p)%2) {\n\t\t\tp2--;\n\t\t\tsaved_sep = '\\\\';\n\t\t}\n\t}\n\tDIR *dir = opendir(pos ? buf : \".\");\n\tif (!dir) {\n\t\tif (errfunc(buf, errno) || (flags & GLOB_ERR))\n\t\t\treturn GLOB_ABORTED;\n\t\treturn 0;\n\t}\n\tint old_errno = errno;\n\tstruct dirent *de;\n\twhile (errno=0, de=readdir(dir)) {\n\t\t/* Quickly skip non-directories when there's pattern left. */\n\t\tif (p2 && de->d_type && de->d_type!=DT_DIR && de->d_type!=DT_LNK)\n\t\t\tcontinue;\n\n\t\tsize_t l = strlen(de->d_name);\n\t\tif (l >= PATH_MAX-pos) continue;\n\n\t\tif (p2) *p2 = 0;\n\n\t\tint fnm_flags= ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)\n\t\t\t| ((!(flags & GLOB_PERIOD)) ? FNM_PERIOD : 0);\n\n\t\tif (fnmatch(pat, de->d_name, fnm_flags))\n\t\t\tcontinue;\n\n\t\t/* With GLOB_PERIOD, don't allow matching . or .. unless\n\t\t * fnmatch would match them with FNM_PERIOD rules in effect. */\n\t\tif (p2 && (flags & GLOB_PERIOD) && de->d_name[0]=='.'\n\t\t    && (!de->d_name[1] || de->d_name[1]=='.' && !de->d_name[2])\n\t\t    && fnmatch(pat, de->d_name, fnm_flags | FNM_PERIOD))\n\t\t\tcontinue;\n\n\t\tmemcpy(buf+pos, de->d_name, l+1);\n\t\tif (p2) *p2 = saved_sep;\n\t\tint r = do_glob(buf, pos+l, de->d_type, p2 ? p2 : \"\", flags, errfunc, tail);\n\t\tif (r) {\n\t\t\tclosedir(dir);\n\t\t\treturn r;\n\t\t}\n\t}\n\tint readerr = errno;\n\tif (p2) *p2 = saved_sep;\n\tclosedir(dir);\n\tif (readerr && (errfunc(buf, errno) || (flags & GLOB_ERR)))\n\t\treturn GLOB_ABORTED;\n\terrno = old_errno;\n\treturn 0;\n}\n\nstatic int ignore_err(const char *path, int err)\n{\n\treturn 0;\n}\n\nstatic void freelist(struct match *head)\n{\n\tstruct match *match, *next;\n\tfor (match=head->next; match; match=next) {\n\t\tnext = match->next;\n\t\tfree(match);\n\t}\n}\n\nstatic int sort(const void *a, const void *b)\n{\n\treturn strcmp(*(const char **)a, *(const char **)b);\n}\n\nstatic int expand_tilde(char **pat, char *buf, size_t *pos)\n{\n\tchar *p = *pat + 1;\n\tsize_t i = 0;\n\n\tchar delim, *name_end = __strchrnul(p, '/');\n\tif ((delim = *name_end)) *name_end++ = 0;\n\t*pat = name_end;\n\n\tchar *home = *p ? NULL : getenv(\"HOME\");\n\tif (!home) {\n\t\tstruct passwd pw, *res;\n\t\tswitch (*p ? getpwnam_r(p, &pw, buf, PATH_MAX, &res)\n\t\t\t   : getpwuid_r(getuid(), &pw, buf, PATH_MAX, &res)) {\n\t\tcase ENOMEM:\n\t\t\treturn GLOB_NOSPACE;\n\t\tcase 0:\n\t\t\tif (!res)\n\t\tdefault:\n\t\t\t\treturn GLOB_NOMATCH;\n\t\t}\n\t\thome = pw.pw_dir;\n\t}\n\twhile (i < PATH_MAX - 2 && *home)\n\t\tbuf[i++] = *home++;\n\tif (*home)\n\t\treturn GLOB_NOMATCH;\n\tif ((buf[i] = delim))\n\t\tbuf[++i] = 0;\n\t*pos = i;\n\treturn 0;\n}\n\nint glob(const char *restrict pat, int flags, int (*errfunc)(const char *path, int err), glob_t *restrict g)\n{\n\tstruct match head = { .next = NULL }, *tail = &head;\n\tsize_t cnt, i;\n\tsize_t offs = (flags & GLOB_DOOFFS) ? g->gl_offs : 0;\n\tint error = 0;\n\tchar buf[PATH_MAX];\n\t\n\tif (!errfunc) errfunc = ignore_err;\n\n\tif (!(flags & GLOB_APPEND)) {\n\t\tg->gl_offs = offs;\n\t\tg->gl_pathc = 0;\n\t\tg->gl_pathv = NULL;\n\t}\n\n\tif (*pat) {\n\t\tchar *p = strdup(pat);\n\t\tif (!p) return GLOB_NOSPACE;\n\t\tbuf[0] = 0;\n\t\tsize_t pos = 0;\n\t\tchar *s = p;\n\t\tif ((flags & (GLOB_TILDE | GLOB_TILDE_CHECK)) && *p == '~')\n\t\t\terror = expand_tilde(&s, buf, &pos);\n\t\tif (!error)\n\t\t\terror = do_glob(buf, pos, 0, s, flags, errfunc, &tail);\n\t\tfree(p);\n\t}\n\n\tif (error == GLOB_NOSPACE) {\n\t\tfreelist(&head);\n\t\treturn error;\n\t}\n\t\n\tfor (cnt=0, tail=head.next; tail; tail=tail->next, cnt++);\n\tif (!cnt) {\n\t\tif (flags & GLOB_NOCHECK) {\n\t\t\ttail = &head;\n\t\t\tif (append(&tail, pat, strlen(pat), 0))\n\t\t\t\treturn GLOB_NOSPACE;\n\t\t\tcnt++;\n\t\t} else\n\t\t\treturn GLOB_NOMATCH;\n\t}\n\n\tif (flags & GLOB_APPEND) {\n\t\tchar **pathv = realloc(g->gl_pathv, (offs + g->gl_pathc + cnt + 1) * sizeof(char *));\n\t\tif (!pathv) {\n\t\t\tfreelist(&head);\n\t\t\treturn GLOB_NOSPACE;\n\t\t}\n\t\tg->gl_pathv = pathv;\n\t\toffs += g->gl_pathc;\n\t} else {\n\t\tg->gl_pathv = malloc((offs + cnt + 1) * sizeof(char *));\n\t\tif (!g->gl_pathv) {\n\t\t\tfreelist(&head);\n\t\t\treturn GLOB_NOSPACE;\n\t\t}\n\t\tfor (i=0; i<offs; i++)\n\t\t\tg->gl_pathv[i] = NULL;\n\t}\n\tfor (i=0, tail=head.next; i<cnt; tail=tail->next, i++)\n\t\tg->gl_pathv[offs + i] = tail->name;\n\tg->gl_pathv[offs + i] = NULL;\n\tg->gl_pathc += cnt;\n\n\tif (!(flags & GLOB_NOSORT))\n\t\tqsort(g->gl_pathv+offs, cnt, sizeof(char *), sort);\n\t\n\treturn error;\n}\n\nvoid globfree(glob_t *g)\n{\n\tsize_t i;\n\tfor (i=0; i<g->gl_pathc; i++)\n\t\tfree(g->gl_pathv[g->gl_offs + i] - offsetof(struct match, name));\n\tfree(g->gl_pathv);\n\tg->gl_pathc = 0;\n\tg->gl_pathv = NULL;\n}\n\nweak_alias(glob, glob64);\nweak_alias(globfree, globfree64);\n"
  },
  {
    "path": "user.libc/src/regex/regcomp.c",
    "content": "/*\n  regcomp.c - TRE POSIX compatible regex compilation functions.\n\n  Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>\n  All rights reserved.\n\n  Redistribution and use in source and binary forms, with or without\n  modification, are permitted provided that the following conditions\n  are met:\n\n    1. Redistributions of source code must retain the above copyright\n       notice, this list of conditions and the following disclaimer.\n\n    2. Redistributions in binary form must reproduce the above copyright\n       notice, this list of conditions and the following disclaimer in the\n       documentation and/or other materials provided with the distribution.\n\n  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS\n  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT\n  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n*/\n\n#include <string.h>\n#include <stdlib.h>\n#include <regex.h>\n#include <limits.h>\n#include <stdint.h>\n#include <ctype.h>\n\n#include \"tre.h\"\n\n#include <assert.h>\n\n/***********************************************************************\n from tre-compile.h\n***********************************************************************/\n\ntypedef struct {\n  int position;\n  int code_min;\n  int code_max;\n  int *tags;\n  int assertions;\n  tre_ctype_t class;\n  tre_ctype_t *neg_classes;\n  int backref;\n} tre_pos_and_tags_t;\n\n\n/***********************************************************************\n from tre-ast.c and tre-ast.h\n***********************************************************************/\n\n/* The different AST node types. */\ntypedef enum {\n  LITERAL,\n  CATENATION,\n  ITERATION,\n  UNION\n} tre_ast_type_t;\n\n/* Special subtypes of TRE_LITERAL. */\n#define EMPTY\t  -1   /* Empty leaf (denotes empty string). */\n#define ASSERTION -2   /* Assertion leaf. */\n#define TAG\t  -3   /* Tag leaf. */\n#define BACKREF\t  -4   /* Back reference leaf. */\n\n#define IS_SPECIAL(x)\t((x)->code_min < 0)\n#define IS_EMPTY(x)\t((x)->code_min == EMPTY)\n#define IS_ASSERTION(x) ((x)->code_min == ASSERTION)\n#define IS_TAG(x)\t((x)->code_min == TAG)\n#define IS_BACKREF(x)\t((x)->code_min == BACKREF)\n\n\n/* A generic AST node.  All AST nodes consist of this node on the top\n   level with `obj' pointing to the actual content. */\ntypedef struct {\n  tre_ast_type_t type;   /* Type of the node. */\n  void *obj;             /* Pointer to actual node. */\n  int nullable;\n  int submatch_id;\n  int num_submatches;\n  int num_tags;\n  tre_pos_and_tags_t *firstpos;\n  tre_pos_and_tags_t *lastpos;\n} tre_ast_node_t;\n\n\n/* A \"literal\" node.  These are created for assertions, back references,\n   tags, matching parameter settings, and all expressions that match one\n   character. */\ntypedef struct {\n  long code_min;\n  long code_max;\n  int position;\n  tre_ctype_t class;\n  tre_ctype_t *neg_classes;\n} tre_literal_t;\n\n/* A \"catenation\" node.\t These are created when two regexps are concatenated.\n   If there are more than one subexpressions in sequence, the `left' part\n   holds all but the last, and `right' part holds the last subexpression\n   (catenation is left associative). */\ntypedef struct {\n  tre_ast_node_t *left;\n  tre_ast_node_t *right;\n} tre_catenation_t;\n\n/* An \"iteration\" node.\t These are created for the \"*\", \"+\", \"?\", and \"{m,n}\"\n   operators. */\ntypedef struct {\n  /* Subexpression to match. */\n  tre_ast_node_t *arg;\n  /* Minimum number of consecutive matches. */\n  int min;\n  /* Maximum number of consecutive matches. */\n  int max;\n  /* If 0, match as many characters as possible, if 1 match as few as\n     possible.\tNote that this does not always mean the same thing as\n     matching as many/few repetitions as possible. */\n  unsigned int minimal:1;\n} tre_iteration_t;\n\n/* An \"union\" node.  These are created for the \"|\" operator. */\ntypedef struct {\n  tre_ast_node_t *left;\n  tre_ast_node_t *right;\n} tre_union_t;\n\n\nstatic tre_ast_node_t *\ntre_ast_new_node(tre_mem_t mem, int type, void *obj)\n{\n\ttre_ast_node_t *node = tre_mem_calloc(mem, sizeof *node);\n\tif (!node || !obj)\n\t\treturn 0;\n\tnode->obj = obj;\n\tnode->type = type;\n\tnode->nullable = -1;\n\tnode->submatch_id = -1;\n\treturn node;\n}\n\nstatic tre_ast_node_t *\ntre_ast_new_literal(tre_mem_t mem, int code_min, int code_max, int position)\n{\n\ttre_ast_node_t *node;\n\ttre_literal_t *lit;\n\n\tlit = tre_mem_calloc(mem, sizeof *lit);\n\tnode = tre_ast_new_node(mem, LITERAL, lit);\n\tif (!node)\n\t\treturn 0;\n\tlit->code_min = code_min;\n\tlit->code_max = code_max;\n\tlit->position = position;\n\treturn node;\n}\n\nstatic tre_ast_node_t *\ntre_ast_new_iter(tre_mem_t mem, tre_ast_node_t *arg, int min, int max, int minimal)\n{\n\ttre_ast_node_t *node;\n\ttre_iteration_t *iter;\n\n\titer = tre_mem_calloc(mem, sizeof *iter);\n\tnode = tre_ast_new_node(mem, ITERATION, iter);\n\tif (!node)\n\t\treturn 0;\n\titer->arg = arg;\n\titer->min = min;\n\titer->max = max;\n\titer->minimal = minimal;\n\tnode->num_submatches = arg->num_submatches;\n\treturn node;\n}\n\nstatic tre_ast_node_t *\ntre_ast_new_union(tre_mem_t mem, tre_ast_node_t *left, tre_ast_node_t *right)\n{\n\ttre_ast_node_t *node;\n\ttre_union_t *un;\n\n\tif (!left)\n\t\treturn right;\n\tun = tre_mem_calloc(mem, sizeof *un);\n\tnode = tre_ast_new_node(mem, UNION, un);\n\tif (!node || !right)\n\t\treturn 0;\n\tun->left = left;\n\tun->right = right;\n\tnode->num_submatches = left->num_submatches + right->num_submatches;\n\treturn node;\n}\n\nstatic tre_ast_node_t *\ntre_ast_new_catenation(tre_mem_t mem, tre_ast_node_t *left, tre_ast_node_t *right)\n{\n\ttre_ast_node_t *node;\n\ttre_catenation_t *cat;\n\n\tif (!left)\n\t\treturn right;\n\tcat = tre_mem_calloc(mem, sizeof *cat);\n\tnode = tre_ast_new_node(mem, CATENATION, cat);\n\tif (!node)\n\t\treturn 0;\n\tcat->left = left;\n\tcat->right = right;\n\tnode->num_submatches = left->num_submatches + right->num_submatches;\n\treturn node;\n}\n\n\n/***********************************************************************\n from tre-stack.c and tre-stack.h\n***********************************************************************/\n\ntypedef struct tre_stack_rec tre_stack_t;\n\n/* Creates a new stack object.\t`size' is initial size in bytes, `max_size'\n   is maximum size, and `increment' specifies how much more space will be\n   allocated with realloc() if all space gets used up.\tReturns the stack\n   object or NULL if out of memory. */\nstatic tre_stack_t *\ntre_stack_new(int size, int max_size, int increment);\n\n/* Frees the stack object. */\nstatic void\ntre_stack_destroy(tre_stack_t *s);\n\n/* Returns the current number of objects in the stack. */\nstatic int\ntre_stack_num_objects(tre_stack_t *s);\n\n/* Each tre_stack_push_*(tre_stack_t *s, <type> value) function pushes\n   `value' on top of stack `s'.  Returns REG_ESPACE if out of memory.\n   This tries to realloc() more space before failing if maximum size\n   has not yet been reached.  Returns REG_OK if successful. */\n#define declare_pushf(typetag, type)\t\t\t\t\t      \\\n  static reg_errcode_t tre_stack_push_ ## typetag(tre_stack_t *s, type value)\n\ndeclare_pushf(voidptr, void *);\ndeclare_pushf(int, int);\n\n/* Each tre_stack_pop_*(tre_stack_t *s) function pops the topmost\n   element off of stack `s' and returns it.  The stack must not be\n   empty. */\n#define declare_popf(typetag, type)\t\t  \\\n  static type tre_stack_pop_ ## typetag(tre_stack_t *s)\n\ndeclare_popf(voidptr, void *);\ndeclare_popf(int, int);\n\n/* Just to save some typing. */\n#define STACK_PUSH(s, typetag, value)\t\t\t\t\t      \\\n  do\t\t\t\t\t\t\t\t\t      \\\n    {\t\t\t\t\t\t\t\t\t      \\\n      status = tre_stack_push_ ## typetag(s, value);\t\t\t      \\\n    }\t\t\t\t\t\t\t\t\t      \\\n  while (/*CONSTCOND*/0)\n\n#define STACK_PUSHX(s, typetag, value)\t\t\t\t\t      \\\n  {\t\t\t\t\t\t\t\t\t      \\\n    status = tre_stack_push_ ## typetag(s, value);\t\t\t      \\\n    if (status != REG_OK)\t\t\t\t\t\t      \\\n      break;\t\t\t\t\t\t\t\t      \\\n  }\n\n#define STACK_PUSHR(s, typetag, value)\t\t\t\t\t      \\\n  {\t\t\t\t\t\t\t\t\t      \\\n    reg_errcode_t _status;\t\t\t\t\t\t      \\\n    _status = tre_stack_push_ ## typetag(s, value);\t\t\t      \\\n    if (_status != REG_OK)\t\t\t\t\t\t      \\\n      return _status;\t\t\t\t\t\t\t      \\\n  }\n\nunion tre_stack_item {\n  void *voidptr_value;\n  int int_value;\n};\n\nstruct tre_stack_rec {\n  int size;\n  int max_size;\n  int increment;\n  int ptr;\n  union tre_stack_item *stack;\n};\n\n\nstatic tre_stack_t *\ntre_stack_new(int size, int max_size, int increment)\n{\n  tre_stack_t *s;\n\n  s = xmalloc(sizeof(*s));\n  if (s != NULL)\n    {\n      s->stack = xmalloc(sizeof(*s->stack) * size);\n      if (s->stack == NULL)\n\t{\n\t  xfree(s);\n\t  return NULL;\n\t}\n      s->size = size;\n      s->max_size = max_size;\n      s->increment = increment;\n      s->ptr = 0;\n    }\n  return s;\n}\n\nstatic void\ntre_stack_destroy(tre_stack_t *s)\n{\n  xfree(s->stack);\n  xfree(s);\n}\n\nstatic int\ntre_stack_num_objects(tre_stack_t *s)\n{\n  return s->ptr;\n}\n\nstatic reg_errcode_t\ntre_stack_push(tre_stack_t *s, union tre_stack_item value)\n{\n  if (s->ptr < s->size)\n    {\n      s->stack[s->ptr] = value;\n      s->ptr++;\n    }\n  else\n    {\n      if (s->size >= s->max_size)\n\t{\n\t  return REG_ESPACE;\n\t}\n      else\n\t{\n\t  union tre_stack_item *new_buffer;\n\t  int new_size;\n\t  new_size = s->size + s->increment;\n\t  if (new_size > s->max_size)\n\t    new_size = s->max_size;\n\t  new_buffer = xrealloc(s->stack, sizeof(*new_buffer) * new_size);\n\t  if (new_buffer == NULL)\n\t    {\n\t      return REG_ESPACE;\n\t    }\n\t  assert(new_size > s->size);\n\t  s->size = new_size;\n\t  s->stack = new_buffer;\n\t  tre_stack_push(s, value);\n\t}\n    }\n  return REG_OK;\n}\n\n#define define_pushf(typetag, type)  \\\n  declare_pushf(typetag, type) {     \\\n    union tre_stack_item item;\t     \\\n    item.typetag ## _value = value;  \\\n    return tre_stack_push(s, item);  \\\n}\n\ndefine_pushf(int, int)\ndefine_pushf(voidptr, void *)\n\n#define define_popf(typetag, type)\t\t    \\\n  declare_popf(typetag, type) {\t\t\t    \\\n    return s->stack[--s->ptr].typetag ## _value;    \\\n  }\n\ndefine_popf(int, int)\ndefine_popf(voidptr, void *)\n\n\n/***********************************************************************\n from tre-parse.c and tre-parse.h\n***********************************************************************/\n\n/* Parse context. */\ntypedef struct {\n\t/* Memory allocator. The AST is allocated using this. */\n\ttre_mem_t mem;\n\t/* Stack used for keeping track of regexp syntax. */\n\ttre_stack_t *stack;\n\t/* The parsed node after a parse function returns. */\n\ttre_ast_node_t *n;\n\t/* Position in the regexp pattern after a parse function returns. */\n\tconst char *s;\n\t/* The first character of the last subexpression parsed. */\n\tconst char *start;\n\t/* Current submatch ID. */\n\tint submatch_id;\n\t/* Current position (number of literal). */\n\tint position;\n\t/* The highest back reference or -1 if none seen so far. */\n\tint max_backref;\n\t/* Compilation flags. */\n\tint cflags;\n} tre_parse_ctx_t;\n\n/* Some macros for expanding \\w, \\s, etc. */\nstatic const struct {\n\tchar c;\n\tconst char *expansion;\n} tre_macros[] = {\n\t{'t', \"\\t\"}, {'n', \"\\n\"}, {'r', \"\\r\"},\n\t{'f', \"\\f\"}, {'a', \"\\a\"}, {'e', \"\\033\"},\n\t{'w', \"[[:alnum:]_]\"}, {'W', \"[^[:alnum:]_]\"}, {'s', \"[[:space:]]\"},\n\t{'S', \"[^[:space:]]\"}, {'d', \"[[:digit:]]\"}, {'D', \"[^[:digit:]]\"},\n\t{ 0, 0 }\n};\n\n/* Expands a macro delimited by `regex' and `regex_end' to `buf', which\n   must have at least `len' items.  Sets buf[0] to zero if the there\n   is no match in `tre_macros'. */\nstatic const char *tre_expand_macro(const char *s)\n{\n\tint i;\n\tfor (i = 0; tre_macros[i].c && tre_macros[i].c != *s; i++);\n\treturn tre_macros[i].expansion;\n}\n\nstatic int\ntre_compare_lit(const void *a, const void *b)\n{\n\tconst tre_literal_t *const *la = a;\n\tconst tre_literal_t *const *lb = b;\n\t/* assumes the range of valid code_min is < INT_MAX */\n\treturn la[0]->code_min - lb[0]->code_min;\n}\n\nstruct literals {\n\ttre_mem_t mem;\n\ttre_literal_t **a;\n\tint len;\n\tint cap;\n};\n\nstatic tre_literal_t *tre_new_lit(struct literals *p)\n{\n\ttre_literal_t **a;\n\tif (p->len >= p->cap) {\n\t\tif (p->cap >= 1<<15)\n\t\t\treturn 0;\n\t\tp->cap *= 2;\n\t\ta = xrealloc(p->a, p->cap * sizeof *p->a);\n\t\tif (!a)\n\t\t\treturn 0;\n\t\tp->a = a;\n\t}\n\ta = p->a + p->len++;\n\t*a = tre_mem_calloc(p->mem, sizeof **a);\n\treturn *a;\n}\n\nstatic int add_icase_literals(struct literals *ls, int min, int max)\n{\n\ttre_literal_t *lit;\n\tint b, e, c;\n\tfor (c=min; c<=max; ) {\n\t\t/* assumes islower(c) and isupper(c) are exclusive\n\t\t   and toupper(c)!=c if islower(c).\n\t\t   multiple opposite case characters are not supported */\n\t\tif (tre_islower(c)) {\n\t\t\tb = e = tre_toupper(c);\n\t\t\tfor (c++, e++; c<=max; c++, e++)\n\t\t\t\tif (tre_toupper(c) != e) break;\n\t\t} else if (tre_isupper(c)) {\n\t\t\tb = e = tre_tolower(c);\n\t\t\tfor (c++, e++; c<=max; c++, e++)\n\t\t\t\tif (tre_tolower(c) != e) break;\n\t\t} else {\n\t\t\tc++;\n\t\t\tcontinue;\n\t\t}\n\t\tlit = tre_new_lit(ls);\n\t\tif (!lit)\n\t\t\treturn -1;\n\t\tlit->code_min = b;\n\t\tlit->code_max = e-1;\n\t\tlit->position = -1;\n\t}\n\treturn 0;\n}\n\n\n/* Maximum number of character classes in a negated bracket expression. */\n#define MAX_NEG_CLASSES 64\n\nstruct neg {\n\tint negate;\n\tint len;\n\ttre_ctype_t a[MAX_NEG_CLASSES];\n};\n\n// TODO: parse bracket into a set of non-overlapping [lo,hi] ranges\n\n/*\nbracket grammar:\nBracket  =  '[' List ']'  |  '[^' List ']'\nList     =  Term  |  List Term\nTerm     =  Char  |  Range  |  Chclass  |  Eqclass\nRange    =  Char '-' Char  |  Char '-' '-'\nChar     =  Coll  |  coll_single\nMeta     =  ']'  |  '-'\nColl     =  '[.' coll_single '.]'  |  '[.' coll_multi '.]'  |  '[.' Meta '.]'\nEqclass  =  '[=' coll_single '=]'  |  '[=' coll_multi '=]'\nChclass  =  '[:' class ':]'\n\ncoll_single is a single char collating element but it can be\n '-' only at the beginning or end of a List and\n ']' only at the beginning of a List and\n '^' anywhere except after the openning '['\n*/\n\nstatic reg_errcode_t parse_bracket_terms(tre_parse_ctx_t *ctx, const char *s, struct literals *ls, struct neg *neg)\n{\n\tconst char *start = s;\n\ttre_ctype_t class;\n\tint min, max;\n\twchar_t wc;\n\tint len;\n\n\tfor (;;) {\n\t\tclass = 0;\n\t\tlen = mbtowc(&wc, s, -1);\n\t\tif (len <= 0)\n\t\t\treturn *s ? REG_BADPAT : REG_EBRACK;\n\t\tif (*s == ']' && s != start) {\n\t\t\tctx->s = s+1;\n\t\t\treturn REG_OK;\n\t\t}\n\t\tif (*s == '-' && s != start && s[1] != ']' &&\n\t\t    /* extension: [a-z--@] is accepted as [a-z]|[--@] */\n\t\t    (s[1] != '-' || s[2] == ']'))\n\t\t\treturn REG_ERANGE;\n\t\tif (*s == '[' && (s[1] == '.' || s[1] == '='))\n\t\t\t/* collating symbols and equivalence classes are not supported */\n\t\t\treturn REG_ECOLLATE;\n\t\tif (*s == '[' && s[1] == ':') {\n\t\t\tchar tmp[CHARCLASS_NAME_MAX+1];\n\t\t\ts += 2;\n\t\t\tfor (len=0; len < CHARCLASS_NAME_MAX && s[len]; len++) {\n\t\t\t\tif (s[len] == ':') {\n\t\t\t\t\tmemcpy(tmp, s, len);\n\t\t\t\t\ttmp[len] = 0;\n\t\t\t\t\tclass = tre_ctype(tmp);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!class || s[len+1] != ']')\n\t\t\t\treturn REG_ECTYPE;\n\t\t\tmin = 0;\n\t\t\tmax = TRE_CHAR_MAX;\n\t\t\ts += len+2;\n\t\t} else {\n\t\t\tmin = max = wc;\n\t\t\ts += len;\n\t\t\tif (*s == '-' && s[1] != ']') {\n\t\t\t\ts++;\n\t\t\t\tlen = mbtowc(&wc, s, -1);\n\t\t\t\tmax = wc;\n\t\t\t\t/* XXX - Should use collation order instead of\n\t\t\t\t   encoding values in character ranges. */\n\t\t\t\tif (len <= 0 || min > max)\n\t\t\t\t\treturn REG_ERANGE;\n\t\t\t\ts += len;\n\t\t\t}\n\t\t}\n\n\t\tif (class && neg->negate) {\n\t\t\tif (neg->len >= MAX_NEG_CLASSES)\n\t\t\t\treturn REG_ESPACE;\n\t\t\tneg->a[neg->len++] = class;\n\t\t} else  {\n\t\t\ttre_literal_t *lit = tre_new_lit(ls);\n\t\t\tif (!lit)\n\t\t\t\treturn REG_ESPACE;\n\t\t\tlit->code_min = min;\n\t\t\tlit->code_max = max;\n\t\t\tlit->class = class;\n\t\t\tlit->position = -1;\n\n\t\t\t/* Add opposite-case codepoints if REG_ICASE is present.\n\t\t\t   It seems that POSIX requires that bracket negation\n\t\t\t   should happen before case-folding, but most practical\n\t\t\t   implementations do it the other way around. Changing\n\t\t\t   the order would need efficient representation of\n\t\t\t   case-fold ranges and bracket range sets even with\n\t\t\t   simple patterns so this is ok for now. */\n\t\t\tif (ctx->cflags & REG_ICASE && !class)\n\t\t\t\tif (add_icase_literals(ls, min, max))\n\t\t\t\t\treturn REG_ESPACE;\n\t\t}\n\t}\n}\n\nstatic reg_errcode_t parse_bracket(tre_parse_ctx_t *ctx, const char *s)\n{\n\tint i, max, min, negmax, negmin;\n\ttre_ast_node_t *node = 0, *n;\n\ttre_ctype_t *nc = 0;\n\ttre_literal_t *lit;\n\tstruct literals ls;\n\tstruct neg neg;\n\treg_errcode_t err;\n\n\tls.mem = ctx->mem;\n\tls.len = 0;\n\tls.cap = 32;\n\tls.a = xmalloc(ls.cap * sizeof *ls.a);\n\tif (!ls.a)\n\t\treturn REG_ESPACE;\n\tneg.len = 0;\n\tneg.negate = *s == '^';\n\tif (neg.negate)\n\t\ts++;\n\n\terr = parse_bracket_terms(ctx, s, &ls, &neg);\n\tif (err != REG_OK)\n\t\tgoto parse_bracket_done;\n\n\tif (neg.negate) {\n\t\t/*\n\t\t * With REG_NEWLINE, POSIX requires that newlines are not matched by\n\t\t * any form of a non-matching list.\n\t\t */\n\t\tif (ctx->cflags & REG_NEWLINE) {\n\t\t\tlit = tre_new_lit(&ls);\n\t\t\tif (!lit) {\n\t\t\t\terr = REG_ESPACE;\n\t\t\t\tgoto parse_bracket_done;\n\t\t\t}\n\t\t\tlit->code_min = '\\n';\n\t\t\tlit->code_max = '\\n';\n\t\t\tlit->position = -1;\n\t\t}\n\t\t/* Sort the array if we need to negate it. */\n\t\tqsort(ls.a, ls.len, sizeof *ls.a, tre_compare_lit);\n\t\t/* extra lit for the last negated range */\n\t\tlit = tre_new_lit(&ls);\n\t\tif (!lit) {\n\t\t\terr = REG_ESPACE;\n\t\t\tgoto parse_bracket_done;\n\t\t}\n\t\tlit->code_min = TRE_CHAR_MAX+1;\n\t\tlit->code_max = TRE_CHAR_MAX+1;\n\t\tlit->position = -1;\n\t\t/* negated classes */\n\t\tif (neg.len) {\n\t\t\tnc = tre_mem_alloc(ctx->mem, (neg.len+1)*sizeof *neg.a);\n\t\t\tif (!nc) {\n\t\t\t\terr = REG_ESPACE;\n\t\t\t\tgoto parse_bracket_done;\n\t\t\t}\n\t\t\tmemcpy(nc, neg.a, neg.len*sizeof *neg.a);\n\t\t\tnc[neg.len] = 0;\n\t\t}\n\t}\n\n\t/* Build a union of the items in the array, negated if necessary. */\n\tnegmax = negmin = 0;\n\tfor (i = 0; i < ls.len; i++) {\n\t\tlit = ls.a[i];\n\t\tmin = lit->code_min;\n\t\tmax = lit->code_max;\n\t\tif (neg.negate) {\n\t\t\tif (min <= negmin) {\n\t\t\t\t/* Overlap. */\n\t\t\t\tnegmin = MAX(max + 1, negmin);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tnegmax = min - 1;\n\t\t\tlit->code_min = negmin;\n\t\t\tlit->code_max = negmax;\n\t\t\tnegmin = max + 1;\n\t\t}\n\t\tlit->position = ctx->position;\n\t\tlit->neg_classes = nc;\n\t\tn = tre_ast_new_node(ctx->mem, LITERAL, lit);\n\t\tnode = tre_ast_new_union(ctx->mem, node, n);\n\t\tif (!node) {\n\t\t\terr = REG_ESPACE;\n\t\t\tbreak;\n\t\t}\n\t}\n\nparse_bracket_done:\n\txfree(ls.a);\n\tctx->position++;\n\tctx->n = node;\n\treturn err;\n}\n\nstatic const char *parse_dup_count(const char *s, int *n)\n{\n\t*n = -1;\n\tif (!isdigit(*s))\n\t\treturn s;\n\t*n = 0;\n\tfor (;;) {\n\t\t*n = 10 * *n + (*s - '0');\n\t\ts++;\n\t\tif (!isdigit(*s) || *n > RE_DUP_MAX)\n\t\t\tbreak;\n\t}\n\treturn s;\n}\n\nstatic const char *parse_dup(const char *s, int ere, int *pmin, int *pmax)\n{\n\tint min, max;\n\n\ts = parse_dup_count(s, &min);\n\tif (*s == ',')\n\t\ts = parse_dup_count(s+1, &max);\n\telse\n\t\tmax = min;\n\n\tif (\n\t\t(max < min && max >= 0) ||\n\t\tmax > RE_DUP_MAX ||\n\t\tmin > RE_DUP_MAX ||\n\t\tmin < 0 ||\n\t\t(!ere && *s++ != '\\\\') ||\n\t\t*s++ != '}'\n\t)\n\t\treturn 0;\n\t*pmin = min;\n\t*pmax = max;\n\treturn s;\n}\n\nstatic int hexval(unsigned c)\n{\n\tif (c-'0'<10) return c-'0';\n\tc |= 32;\n\tif (c-'a'<6) return c-'a'+10;\n\treturn -1;\n}\n\nstatic reg_errcode_t marksub(tre_parse_ctx_t *ctx, tre_ast_node_t *node, int subid)\n{\n\tif (node->submatch_id >= 0) {\n\t\ttre_ast_node_t *n = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);\n\t\tif (!n)\n\t\t\treturn REG_ESPACE;\n\t\tn = tre_ast_new_catenation(ctx->mem, n, node);\n\t\tif (!n)\n\t\t\treturn REG_ESPACE;\n\t\tn->num_submatches = node->num_submatches;\n\t\tnode = n;\n\t}\n\tnode->submatch_id = subid;\n\tnode->num_submatches++;\n\tctx->n = node;\n\treturn REG_OK;\n}\n\n/*\nBRE grammar:\nRegex  =  Branch  |  '^'  |  '$'  |  '^$'  |  '^' Branch  |  Branch '$'  |  '^' Branch '$'\nBranch =  Atom  |  Branch Atom\nAtom   =  char  |  quoted_char  |  '.'  |  Bracket  |  Atom Dup  |  '\\(' Branch '\\)'  |  back_ref\nDup    =  '*'  |  '\\{' Count '\\}'  |  '\\{' Count ',\\}'  |  '\\{' Count ',' Count '\\}'\n\n(leading ^ and trailing $ in a sub expr may be an anchor or literal as well)\n\nERE grammar:\nRegex  =  Branch  |  Regex '|' Branch\nBranch =  Atom  |  Branch Atom\nAtom   =  char  |  quoted_char  |  '.'  |  Bracket  |  Atom Dup  |  '(' Regex ')'  |  '^'  |  '$'\nDup    =  '*'  |  '+'  |  '?'  |  '{' Count '}'  |  '{' Count ',}'  |  '{' Count ',' Count '}'\n\n(a*+?, ^*, $+, \\X, {, (|a) are unspecified)\n*/\n\nstatic reg_errcode_t parse_atom(tre_parse_ctx_t *ctx, const char *s)\n{\n\tint len, ere = ctx->cflags & REG_EXTENDED;\n\tconst char *p;\n\ttre_ast_node_t *node;\n\twchar_t wc;\n\tswitch (*s) {\n\tcase '[':\n\t\treturn parse_bracket(ctx, s+1);\n\tcase '\\\\':\n\t\tp = tre_expand_macro(s+1);\n\t\tif (p) {\n\t\t\t/* assume \\X expansion is a single atom */\n\t\t\treg_errcode_t err = parse_atom(ctx, p);\n\t\t\tctx->s = s+2;\n\t\t\treturn err;\n\t\t}\n\t\t/* extensions: \\b, \\B, \\<, \\>, \\xHH \\x{HHHH} */\n\t\tswitch (*++s) {\n\t\tcase 0:\n\t\t\treturn REG_EESCAPE;\n\t\tcase 'b':\n\t\t\tnode = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_WB, -1);\n\t\t\tbreak;\n\t\tcase 'B':\n\t\t\tnode = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_WB_NEG, -1);\n\t\t\tbreak;\n\t\tcase '<':\n\t\t\tnode = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_BOW, -1);\n\t\t\tbreak;\n\t\tcase '>':\n\t\t\tnode = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_EOW, -1);\n\t\t\tbreak;\n\t\tcase 'x':\n\t\t\ts++;\n\t\t\tint i, v = 0, c;\n\t\t\tlen = 2;\n\t\t\tif (*s == '{') {\n\t\t\t\tlen = 8;\n\t\t\t\ts++;\n\t\t\t}\n\t\t\tfor (i=0; i<len && v<0x110000; i++) {\n\t\t\t\tc = hexval(s[i]);\n\t\t\t\tif (c < 0) break;\n\t\t\t\tv = 16*v + c;\n\t\t\t}\n\t\t\ts += i;\n\t\t\tif (len == 8) {\n\t\t\t\tif (*s != '}')\n\t\t\t\t\treturn REG_EBRACE;\n\t\t\t\ts++;\n\t\t\t}\n\t\t\tnode = tre_ast_new_literal(ctx->mem, v, v, ctx->position++);\n\t\t\ts--;\n\t\t\tbreak;\n\t\tcase '{':\n\t\tcase '+':\n\t\tcase '?':\n\t\t\t/* extension: treat \\+, \\? as repetitions in BRE */\n\t\t\t/* reject repetitions after empty expression in BRE */\n\t\t\tif (!ere)\n\t\t\t\treturn REG_BADRPT;\n\t\tcase '|':\n\t\t\t/* extension: treat \\| as alternation in BRE */\n\t\t\tif (!ere) {\n\t\t\t\tnode = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);\n\t\t\t\ts--;\n\t\t\t\tgoto end;\n\t\t\t}\n\t\t\t/* fallthrough */\n\t\tdefault:\n\t\t\tif (!ere && (unsigned)*s-'1' < 9) {\n\t\t\t\t/* back reference */\n\t\t\t\tint val = *s - '0';\n\t\t\t\tnode = tre_ast_new_literal(ctx->mem, BACKREF, val, ctx->position++);\n\t\t\t\tctx->max_backref = MAX(val, ctx->max_backref);\n\t\t\t} else {\n\t\t\t\t/* extension: accept unknown escaped char\n\t\t\t\t   as a literal */\n\t\t\t\tgoto parse_literal;\n\t\t\t}\n\t\t}\n\t\ts++;\n\t\tbreak;\n\tcase '.':\n\t\tif (ctx->cflags & REG_NEWLINE) {\n\t\t\ttre_ast_node_t *tmp1, *tmp2;\n\t\t\ttmp1 = tre_ast_new_literal(ctx->mem, 0, '\\n'-1, ctx->position++);\n\t\t\ttmp2 = tre_ast_new_literal(ctx->mem, '\\n'+1, TRE_CHAR_MAX, ctx->position++);\n\t\t\tif (tmp1 && tmp2)\n\t\t\t\tnode = tre_ast_new_union(ctx->mem, tmp1, tmp2);\n\t\t\telse\n\t\t\t\tnode = 0;\n\t\t} else {\n\t\t\tnode = tre_ast_new_literal(ctx->mem, 0, TRE_CHAR_MAX, ctx->position++);\n\t\t}\n\t\ts++;\n\t\tbreak;\n\tcase '^':\n\t\t/* '^' has a special meaning everywhere in EREs, and at beginning of BRE. */\n\t\tif (!ere && s != ctx->start)\n\t\t\tgoto parse_literal;\n\t\tnode = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_BOL, -1);\n\t\ts++;\n\t\tbreak;\n\tcase '$':\n\t\t/* '$' is special everywhere in EREs, and at the end of a BRE subexpression. */\n\t\tif (!ere && s[1] && (s[1]!='\\\\'|| (s[2]!=')' && s[2]!='|')))\n\t\t\tgoto parse_literal;\n\t\tnode = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_EOL, -1);\n\t\ts++;\n\t\tbreak;\n\tcase '*':\n\tcase '{':\n\tcase '+':\n\tcase '?':\n\t\t/* reject repetitions after empty expression in ERE */\n\t\tif (ere)\n\t\t\treturn REG_BADRPT;\n\tcase '|':\n\t\tif (!ere)\n\t\t\tgoto parse_literal;\n\tcase 0:\n\t\tnode = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);\n\t\tbreak;\n\tdefault:\nparse_literal:\n\t\tlen = mbtowc(&wc, s, -1);\n\t\tif (len < 0)\n\t\t\treturn REG_BADPAT;\n\t\tif (ctx->cflags & REG_ICASE && (tre_isupper(wc) || tre_islower(wc))) {\n\t\t\ttre_ast_node_t *tmp1, *tmp2;\n\t\t\t/* multiple opposite case characters are not supported */\n\t\t\ttmp1 = tre_ast_new_literal(ctx->mem, tre_toupper(wc), tre_toupper(wc), ctx->position);\n\t\t\ttmp2 = tre_ast_new_literal(ctx->mem, tre_tolower(wc), tre_tolower(wc), ctx->position);\n\t\t\tif (tmp1 && tmp2)\n\t\t\t\tnode = tre_ast_new_union(ctx->mem, tmp1, tmp2);\n\t\t\telse\n\t\t\t\tnode = 0;\n\t\t} else {\n\t\t\tnode = tre_ast_new_literal(ctx->mem, wc, wc, ctx->position);\n\t\t}\n\t\tctx->position++;\n\t\ts += len;\n\t\tbreak;\n\t}\nend:\n\tif (!node)\n\t\treturn REG_ESPACE;\n\tctx->n = node;\n\tctx->s = s;\n\treturn REG_OK;\n}\n\n#define PUSHPTR(err, s, v) do { \\\n\tif ((err = tre_stack_push_voidptr(s, v)) != REG_OK) \\\n\t\treturn err; \\\n} while(0)\n\n#define PUSHINT(err, s, v) do { \\\n\tif ((err = tre_stack_push_int(s, v)) != REG_OK) \\\n\t\treturn err; \\\n} while(0)\n\nstatic reg_errcode_t tre_parse(tre_parse_ctx_t *ctx)\n{\n\ttre_ast_node_t *nbranch=0, *nunion=0;\n\tint ere = ctx->cflags & REG_EXTENDED;\n\tconst char *s = ctx->start;\n\tint subid = 0;\n\tint depth = 0;\n\treg_errcode_t err;\n\ttre_stack_t *stack = ctx->stack;\n\n\tPUSHINT(err, stack, subid++);\n\tfor (;;) {\n\t\tif ((!ere && *s == '\\\\' && s[1] == '(') ||\n\t\t    (ere && *s == '(')) {\n\t\t\tPUSHPTR(err, stack, nunion);\n\t\t\tPUSHPTR(err, stack, nbranch);\n\t\t\tPUSHINT(err, stack, subid++);\n\t\t\ts++;\n\t\t\tif (!ere)\n\t\t\t\ts++;\n\t\t\tdepth++;\n\t\t\tnbranch = nunion = 0;\n\t\t\tctx->start = s;\n\t\t\tcontinue;\n\t\t}\n\t\tif ((!ere && *s == '\\\\' && s[1] == ')') ||\n\t\t    (ere && *s == ')' && depth)) {\n\t\t\tctx->n = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);\n\t\t\tif (!ctx->n)\n\t\t\t\treturn REG_ESPACE;\n\t\t} else {\n\t\t\terr = parse_atom(ctx, s);\n\t\t\tif (err != REG_OK)\n\t\t\t\treturn err;\n\t\t\ts = ctx->s;\n\t\t}\n\n\tparse_iter:\n\t\tfor (;;) {\n\t\t\tint min, max;\n\n\t\t\tif (*s!='\\\\' && *s!='*') {\n\t\t\t\tif (!ere)\n\t\t\t\t\tbreak;\n\t\t\t\tif (*s!='+' && *s!='?' && *s!='{')\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (*s=='\\\\' && ere)\n\t\t\t\tbreak;\n\t\t\t/* extension: treat \\+, \\? as repetitions in BRE */\n\t\t\tif (*s=='\\\\' && s[1]!='+' && s[1]!='?' && s[1]!='{')\n\t\t\t\tbreak;\n\t\t\tif (*s=='\\\\')\n\t\t\t\ts++;\n\n\t\t\t/* handle ^* at the start of a BRE. */\n\t\t\tif (!ere && s==ctx->start+1 && s[-1]=='^')\n\t\t\t\tbreak;\n\n\t\t\t/* extension: multiple consecutive *+?{,} is unspecified,\n\t\t\t   but (a+)+ has to be supported so accepting a++ makes\n\t\t\t   sense, note however that the RE_DUP_MAX limit can be\n\t\t\t   circumvented: (a{255}){255} uses a lot of memory.. */\n\t\t\tif (*s=='{') {\n\t\t\t\ts = parse_dup(s+1, ere, &min, &max);\n\t\t\t\tif (!s)\n\t\t\t\t\treturn REG_BADBR;\n\t\t\t} else {\n\t\t\t\tmin=0;\n\t\t\t\tmax=-1;\n\t\t\t\tif (*s == '+')\n\t\t\t\t\tmin = 1;\n\t\t\t\tif (*s == '?')\n\t\t\t\t\tmax = 1;\n\t\t\t\ts++;\n\t\t\t}\n\t\t\tif (max == 0)\n\t\t\t\tctx->n = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);\n\t\t\telse\n\t\t\t\tctx->n = tre_ast_new_iter(ctx->mem, ctx->n, min, max, 0);\n\t\t\tif (!ctx->n)\n\t\t\t\treturn REG_ESPACE;\n\t\t}\n\n\t\tnbranch = tre_ast_new_catenation(ctx->mem, nbranch, ctx->n);\n\t\tif ((ere && *s == '|') ||\n\t\t    (ere && *s == ')' && depth) ||\n\t\t    (!ere && *s == '\\\\' && s[1] == ')') ||\n\t\t    /* extension: treat \\| as alternation in BRE */\n\t\t    (!ere && *s == '\\\\' && s[1] == '|') ||\n\t\t    !*s) {\n\t\t\t/* extension: empty branch is unspecified (), (|a), (a|)\n\t\t\t   here they are not rejected but match on empty string */\n\t\t\tint c = *s;\n\t\t\tnunion = tre_ast_new_union(ctx->mem, nunion, nbranch);\n\t\t\tnbranch = 0;\n\n\t\t\tif (c == '\\\\' && s[1] == '|') {\n\t\t\t\ts+=2;\n\t\t\t\tctx->start = s;\n\t\t\t} else if (c == '|') {\n\t\t\t\ts++;\n\t\t\t\tctx->start = s;\n\t\t\t} else {\n\t\t\t\tif (c == '\\\\') {\n\t\t\t\t\tif (!depth) return REG_EPAREN;\n\t\t\t\t\ts+=2;\n\t\t\t\t} else if (c == ')')\n\t\t\t\t\ts++;\n\t\t\t\tdepth--;\n\t\t\t\terr = marksub(ctx, nunion, tre_stack_pop_int(stack));\n\t\t\t\tif (err != REG_OK)\n\t\t\t\t\treturn err;\n\t\t\t\tif (!c && depth<0) {\n\t\t\t\t\tctx->submatch_id = subid;\n\t\t\t\t\treturn REG_OK;\n\t\t\t\t}\n\t\t\t\tif (!c || depth<0)\n\t\t\t\t\treturn REG_EPAREN;\n\t\t\t\tnbranch = tre_stack_pop_voidptr(stack);\n\t\t\t\tnunion = tre_stack_pop_voidptr(stack);\n\t\t\t\tgoto parse_iter;\n\t\t\t}\n\t\t}\n\t}\n}\n\n\n/***********************************************************************\n from tre-compile.c\n***********************************************************************/\n\n\n/*\n  TODO:\n   - Fix tre_ast_to_tnfa() to recurse using a stack instead of recursive\n     function calls.\n*/\n\n/*\n  Algorithms to setup tags so that submatch addressing can be done.\n*/\n\n\n/* Inserts a catenation node to the root of the tree given in `node'.\n   As the left child a new tag with number `tag_id' to `node' is added,\n   and the right child is the old root. */\nstatic reg_errcode_t\ntre_add_tag_left(tre_mem_t mem, tre_ast_node_t *node, int tag_id)\n{\n  tre_catenation_t *c;\n\n  c = tre_mem_alloc(mem, sizeof(*c));\n  if (c == NULL)\n    return REG_ESPACE;\n  c->left = tre_ast_new_literal(mem, TAG, tag_id, -1);\n  if (c->left == NULL)\n    return REG_ESPACE;\n  c->right = tre_mem_alloc(mem, sizeof(tre_ast_node_t));\n  if (c->right == NULL)\n    return REG_ESPACE;\n\n  c->right->obj = node->obj;\n  c->right->type = node->type;\n  c->right->nullable = -1;\n  c->right->submatch_id = -1;\n  c->right->firstpos = NULL;\n  c->right->lastpos = NULL;\n  c->right->num_tags = 0;\n  c->right->num_submatches = 0;\n  node->obj = c;\n  node->type = CATENATION;\n  return REG_OK;\n}\n\n/* Inserts a catenation node to the root of the tree given in `node'.\n   As the right child a new tag with number `tag_id' to `node' is added,\n   and the left child is the old root. */\nstatic reg_errcode_t\ntre_add_tag_right(tre_mem_t mem, tre_ast_node_t *node, int tag_id)\n{\n  tre_catenation_t *c;\n\n  c = tre_mem_alloc(mem, sizeof(*c));\n  if (c == NULL)\n    return REG_ESPACE;\n  c->right = tre_ast_new_literal(mem, TAG, tag_id, -1);\n  if (c->right == NULL)\n    return REG_ESPACE;\n  c->left = tre_mem_alloc(mem, sizeof(tre_ast_node_t));\n  if (c->left == NULL)\n    return REG_ESPACE;\n\n  c->left->obj = node->obj;\n  c->left->type = node->type;\n  c->left->nullable = -1;\n  c->left->submatch_id = -1;\n  c->left->firstpos = NULL;\n  c->left->lastpos = NULL;\n  c->left->num_tags = 0;\n  c->left->num_submatches = 0;\n  node->obj = c;\n  node->type = CATENATION;\n  return REG_OK;\n}\n\ntypedef enum {\n  ADDTAGS_RECURSE,\n  ADDTAGS_AFTER_ITERATION,\n  ADDTAGS_AFTER_UNION_LEFT,\n  ADDTAGS_AFTER_UNION_RIGHT,\n  ADDTAGS_AFTER_CAT_LEFT,\n  ADDTAGS_AFTER_CAT_RIGHT,\n  ADDTAGS_SET_SUBMATCH_END\n} tre_addtags_symbol_t;\n\n\ntypedef struct {\n  int tag;\n  int next_tag;\n} tre_tag_states_t;\n\n\n/* Go through `regset' and set submatch data for submatches that are\n   using this tag. */\nstatic void\ntre_purge_regset(int *regset, tre_tnfa_t *tnfa, int tag)\n{\n  int i;\n\n  for (i = 0; regset[i] >= 0; i++)\n    {\n      int id = regset[i] / 2;\n      int start = !(regset[i] % 2);\n      if (start)\n\ttnfa->submatch_data[id].so_tag = tag;\n      else\n\ttnfa->submatch_data[id].eo_tag = tag;\n    }\n  regset[0] = -1;\n}\n\n\n/* Adds tags to appropriate locations in the parse tree in `tree', so that\n   subexpressions marked for submatch addressing can be traced. */\nstatic reg_errcode_t\ntre_add_tags(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *tree,\n\t     tre_tnfa_t *tnfa)\n{\n  reg_errcode_t status = REG_OK;\n  tre_addtags_symbol_t symbol;\n  tre_ast_node_t *node = tree; /* Tree node we are currently looking at. */\n  int bottom = tre_stack_num_objects(stack);\n  /* True for first pass (counting number of needed tags) */\n  int first_pass = (mem == NULL || tnfa == NULL);\n  int *regset, *orig_regset;\n  int num_tags = 0; /* Total number of tags. */\n  int num_minimals = 0;\t /* Number of special minimal tags. */\n  int tag = 0;\t    /* The tag that is to be added next. */\n  int next_tag = 1; /* Next tag to use after this one. */\n  int *parents;\t    /* Stack of submatches the current submatch is\n\t\t       contained in. */\n  int minimal_tag = -1; /* Tag that marks the beginning of a minimal match. */\n  tre_tag_states_t *saved_states;\n\n  tre_tag_direction_t direction = TRE_TAG_MINIMIZE;\n  if (!first_pass)\n    {\n      tnfa->end_tag = 0;\n      tnfa->minimal_tags[0] = -1;\n    }\n\n  regset = xmalloc(sizeof(*regset) * ((tnfa->num_submatches + 1) * 2));\n  if (regset == NULL)\n    return REG_ESPACE;\n  regset[0] = -1;\n  orig_regset = regset;\n\n  parents = xmalloc(sizeof(*parents) * (tnfa->num_submatches + 1));\n  if (parents == NULL)\n    {\n      xfree(regset);\n      return REG_ESPACE;\n    }\n  parents[0] = -1;\n\n  saved_states = xmalloc(sizeof(*saved_states) * (tnfa->num_submatches + 1));\n  if (saved_states == NULL)\n    {\n      xfree(regset);\n      xfree(parents);\n      return REG_ESPACE;\n    }\n  else\n    {\n      unsigned int i;\n      for (i = 0; i <= tnfa->num_submatches; i++)\n\tsaved_states[i].tag = -1;\n    }\n\n  STACK_PUSH(stack, voidptr, node);\n  STACK_PUSH(stack, int, ADDTAGS_RECURSE);\n\n  while (tre_stack_num_objects(stack) > bottom)\n    {\n      if (status != REG_OK)\n\tbreak;\n\n      symbol = (tre_addtags_symbol_t)tre_stack_pop_int(stack);\n      switch (symbol)\n\t{\n\n\tcase ADDTAGS_SET_SUBMATCH_END:\n\t  {\n\t    int id = tre_stack_pop_int(stack);\n\t    int i;\n\n\t    /* Add end of this submatch to regset. */\n\t    for (i = 0; regset[i] >= 0; i++);\n\t    regset[i] = id * 2 + 1;\n\t    regset[i + 1] = -1;\n\n\t    /* Pop this submatch from the parents stack. */\n\t    for (i = 0; parents[i] >= 0; i++);\n\t    parents[i - 1] = -1;\n\t    break;\n\t  }\n\n\tcase ADDTAGS_RECURSE:\n\t  node = tre_stack_pop_voidptr(stack);\n\n\t  if (node->submatch_id >= 0)\n\t    {\n\t      int id = node->submatch_id;\n\t      int i;\n\n\n\t      /* Add start of this submatch to regset. */\n\t      for (i = 0; regset[i] >= 0; i++);\n\t      regset[i] = id * 2;\n\t      regset[i + 1] = -1;\n\n\t      if (!first_pass)\n\t\t{\n\t\t  for (i = 0; parents[i] >= 0; i++);\n\t\t  tnfa->submatch_data[id].parents = NULL;\n\t\t  if (i > 0)\n\t\t    {\n\t\t      int *p = xmalloc(sizeof(*p) * (i + 1));\n\t\t      if (p == NULL)\n\t\t\t{\n\t\t\t  status = REG_ESPACE;\n\t\t\t  break;\n\t\t\t}\n\t\t      assert(tnfa->submatch_data[id].parents == NULL);\n\t\t      tnfa->submatch_data[id].parents = p;\n\t\t      for (i = 0; parents[i] >= 0; i++)\n\t\t\tp[i] = parents[i];\n\t\t      p[i] = -1;\n\t\t    }\n\t\t}\n\n\t      /* Add end of this submatch to regset after processing this\n\t\t node. */\n\t      STACK_PUSHX(stack, int, node->submatch_id);\n\t      STACK_PUSHX(stack, int, ADDTAGS_SET_SUBMATCH_END);\n\t    }\n\n\t  switch (node->type)\n\t    {\n\t    case LITERAL:\n\t      {\n\t\ttre_literal_t *lit = node->obj;\n\n\t\tif (!IS_SPECIAL(lit) || IS_BACKREF(lit))\n\t\t  {\n\t\t    int i;\n\t\t    if (regset[0] >= 0)\n\t\t      {\n\t\t\t/* Regset is not empty, so add a tag before the\n\t\t\t   literal or backref. */\n\t\t\tif (!first_pass)\n\t\t\t  {\n\t\t\t    status = tre_add_tag_left(mem, node, tag);\n\t\t\t    tnfa->tag_directions[tag] = direction;\n\t\t\t    if (minimal_tag >= 0)\n\t\t\t      {\n\t\t\t\tfor (i = 0; tnfa->minimal_tags[i] >= 0; i++);\n\t\t\t\ttnfa->minimal_tags[i] = tag;\n\t\t\t\ttnfa->minimal_tags[i + 1] = minimal_tag;\n\t\t\t\ttnfa->minimal_tags[i + 2] = -1;\n\t\t\t\tminimal_tag = -1;\n\t\t\t\tnum_minimals++;\n\t\t\t      }\n\t\t\t    tre_purge_regset(regset, tnfa, tag);\n\t\t\t  }\n\t\t\telse\n\t\t\t  {\n\t\t\t    node->num_tags = 1;\n\t\t\t  }\n\n\t\t\tregset[0] = -1;\n\t\t\ttag = next_tag;\n\t\t\tnum_tags++;\n\t\t\tnext_tag++;\n\t\t      }\n\t\t  }\n\t\telse\n\t\t  {\n\t\t    assert(!IS_TAG(lit));\n\t\t  }\n\t\tbreak;\n\t      }\n\t    case CATENATION:\n\t      {\n\t\ttre_catenation_t *cat = node->obj;\n\t\ttre_ast_node_t *left = cat->left;\n\t\ttre_ast_node_t *right = cat->right;\n\t\tint reserved_tag = -1;\n\n\n\t\t/* After processing right child. */\n\t\tSTACK_PUSHX(stack, voidptr, node);\n\t\tSTACK_PUSHX(stack, int, ADDTAGS_AFTER_CAT_RIGHT);\n\n\t\t/* Process right child. */\n\t\tSTACK_PUSHX(stack, voidptr, right);\n\t\tSTACK_PUSHX(stack, int, ADDTAGS_RECURSE);\n\n\t\t/* After processing left child. */\n\t\tSTACK_PUSHX(stack, int, next_tag + left->num_tags);\n\t\tif (left->num_tags > 0 && right->num_tags > 0)\n\t\t  {\n\t\t    /* Reserve the next tag to the right child. */\n\t\t    reserved_tag = next_tag;\n\t\t    next_tag++;\n\t\t  }\n\t\tSTACK_PUSHX(stack, int, reserved_tag);\n\t\tSTACK_PUSHX(stack, int, ADDTAGS_AFTER_CAT_LEFT);\n\n\t\t/* Process left child. */\n\t\tSTACK_PUSHX(stack, voidptr, left);\n\t\tSTACK_PUSHX(stack, int, ADDTAGS_RECURSE);\n\n\t\t}\n\t      break;\n\t    case ITERATION:\n\t      {\n\t\ttre_iteration_t *iter = node->obj;\n\n\t\tif (first_pass)\n\t\t  {\n\t\t    STACK_PUSHX(stack, int, regset[0] >= 0 || iter->minimal);\n\t\t  }\n\t\telse\n\t\t  {\n\t\t    STACK_PUSHX(stack, int, tag);\n\t\t    STACK_PUSHX(stack, int, iter->minimal);\n\t\t  }\n\t\tSTACK_PUSHX(stack, voidptr, node);\n\t\tSTACK_PUSHX(stack, int, ADDTAGS_AFTER_ITERATION);\n\n\t\tSTACK_PUSHX(stack, voidptr, iter->arg);\n\t\tSTACK_PUSHX(stack, int, ADDTAGS_RECURSE);\n\n\t\t/* Regset is not empty, so add a tag here. */\n\t\tif (regset[0] >= 0 || iter->minimal)\n\t\t  {\n\t\t    if (!first_pass)\n\t\t      {\n\t\t\tint i;\n\t\t\tstatus = tre_add_tag_left(mem, node, tag);\n\t\t\tif (iter->minimal)\n\t\t\t  tnfa->tag_directions[tag] = TRE_TAG_MAXIMIZE;\n\t\t\telse\n\t\t\t  tnfa->tag_directions[tag] = direction;\n\t\t\tif (minimal_tag >= 0)\n\t\t\t  {\n\t\t\t    for (i = 0; tnfa->minimal_tags[i] >= 0; i++);\n\t\t\t    tnfa->minimal_tags[i] = tag;\n\t\t\t    tnfa->minimal_tags[i + 1] = minimal_tag;\n\t\t\t    tnfa->minimal_tags[i + 2] = -1;\n\t\t\t    minimal_tag = -1;\n\t\t\t    num_minimals++;\n\t\t\t  }\n\t\t\ttre_purge_regset(regset, tnfa, tag);\n\t\t      }\n\n\t\t    regset[0] = -1;\n\t\t    tag = next_tag;\n\t\t    num_tags++;\n\t\t    next_tag++;\n\t\t  }\n\t\tdirection = TRE_TAG_MINIMIZE;\n\t      }\n\t      break;\n\t    case UNION:\n\t      {\n\t\ttre_union_t *uni = node->obj;\n\t\ttre_ast_node_t *left = uni->left;\n\t\ttre_ast_node_t *right = uni->right;\n\t\tint left_tag;\n\t\tint right_tag;\n\n\t\tif (regset[0] >= 0)\n\t\t  {\n\t\t    left_tag = next_tag;\n\t\t    right_tag = next_tag + 1;\n\t\t  }\n\t\telse\n\t\t  {\n\t\t    left_tag = tag;\n\t\t    right_tag = next_tag;\n\t\t  }\n\n\t\t/* After processing right child. */\n\t\tSTACK_PUSHX(stack, int, right_tag);\n\t\tSTACK_PUSHX(stack, int, left_tag);\n\t\tSTACK_PUSHX(stack, voidptr, regset);\n\t\tSTACK_PUSHX(stack, int, regset[0] >= 0);\n\t\tSTACK_PUSHX(stack, voidptr, node);\n\t\tSTACK_PUSHX(stack, voidptr, right);\n\t\tSTACK_PUSHX(stack, voidptr, left);\n\t\tSTACK_PUSHX(stack, int, ADDTAGS_AFTER_UNION_RIGHT);\n\n\t\t/* Process right child. */\n\t\tSTACK_PUSHX(stack, voidptr, right);\n\t\tSTACK_PUSHX(stack, int, ADDTAGS_RECURSE);\n\n\t\t/* After processing left child. */\n\t\tSTACK_PUSHX(stack, int, ADDTAGS_AFTER_UNION_LEFT);\n\n\t\t/* Process left child. */\n\t\tSTACK_PUSHX(stack, voidptr, left);\n\t\tSTACK_PUSHX(stack, int, ADDTAGS_RECURSE);\n\n\t\t/* Regset is not empty, so add a tag here. */\n\t\tif (regset[0] >= 0)\n\t\t  {\n\t\t    if (!first_pass)\n\t\t      {\n\t\t\tint i;\n\t\t\tstatus = tre_add_tag_left(mem, node, tag);\n\t\t\ttnfa->tag_directions[tag] = direction;\n\t\t\tif (minimal_tag >= 0)\n\t\t\t  {\n\t\t\t    for (i = 0; tnfa->minimal_tags[i] >= 0; i++);\n\t\t\t    tnfa->minimal_tags[i] = tag;\n\t\t\t    tnfa->minimal_tags[i + 1] = minimal_tag;\n\t\t\t    tnfa->minimal_tags[i + 2] = -1;\n\t\t\t    minimal_tag = -1;\n\t\t\t    num_minimals++;\n\t\t\t  }\n\t\t\ttre_purge_regset(regset, tnfa, tag);\n\t\t      }\n\n\t\t    regset[0] = -1;\n\t\t    tag = next_tag;\n\t\t    num_tags++;\n\t\t    next_tag++;\n\t\t  }\n\n\t\tif (node->num_submatches > 0)\n\t\t  {\n\t\t    /* The next two tags are reserved for markers. */\n\t\t    next_tag++;\n\t\t    tag = next_tag;\n\t\t    next_tag++;\n\t\t  }\n\n\t\tbreak;\n\t      }\n\t    }\n\n\t  if (node->submatch_id >= 0)\n\t    {\n\t      int i;\n\t      /* Push this submatch on the parents stack. */\n\t      for (i = 0; parents[i] >= 0; i++);\n\t      parents[i] = node->submatch_id;\n\t      parents[i + 1] = -1;\n\t    }\n\n\t  break; /* end case: ADDTAGS_RECURSE */\n\n\tcase ADDTAGS_AFTER_ITERATION:\n\t  {\n\t    int minimal = 0;\n\t    int enter_tag;\n\t    node = tre_stack_pop_voidptr(stack);\n\t    if (first_pass)\n\t      {\n\t\tnode->num_tags = ((tre_iteration_t *)node->obj)->arg->num_tags\n\t\t  + tre_stack_pop_int(stack);\n\t\tminimal_tag = -1;\n\t      }\n\t    else\n\t      {\n\t\tminimal = tre_stack_pop_int(stack);\n\t\tenter_tag = tre_stack_pop_int(stack);\n\t\tif (minimal)\n\t\t  minimal_tag = enter_tag;\n\t      }\n\n\t    if (!first_pass)\n\t      {\n\t\tif (minimal)\n\t\t  direction = TRE_TAG_MINIMIZE;\n\t\telse\n\t\t  direction = TRE_TAG_MAXIMIZE;\n\t      }\n\t    break;\n\t  }\n\n\tcase ADDTAGS_AFTER_CAT_LEFT:\n\t  {\n\t    int new_tag = tre_stack_pop_int(stack);\n\t    next_tag = tre_stack_pop_int(stack);\n\t    if (new_tag >= 0)\n\t      {\n\t\ttag = new_tag;\n\t      }\n\t    break;\n\t  }\n\n\tcase ADDTAGS_AFTER_CAT_RIGHT:\n\t  node = tre_stack_pop_voidptr(stack);\n\t  if (first_pass)\n\t    node->num_tags = ((tre_catenation_t *)node->obj)->left->num_tags\n\t      + ((tre_catenation_t *)node->obj)->right->num_tags;\n\t  break;\n\n\tcase ADDTAGS_AFTER_UNION_LEFT:\n\t  /* Lift the bottom of the `regset' array so that when processing\n\t     the right operand the items currently in the array are\n\t     invisible.\t The original bottom was saved at ADDTAGS_UNION and\n\t     will be restored at ADDTAGS_AFTER_UNION_RIGHT below. */\n\t  while (*regset >= 0)\n\t    regset++;\n\t  break;\n\n\tcase ADDTAGS_AFTER_UNION_RIGHT:\n\t  {\n\t    int added_tags, tag_left, tag_right;\n\t    tre_ast_node_t *left = tre_stack_pop_voidptr(stack);\n\t    tre_ast_node_t *right = tre_stack_pop_voidptr(stack);\n\t    node = tre_stack_pop_voidptr(stack);\n\t    added_tags = tre_stack_pop_int(stack);\n\t    if (first_pass)\n\t      {\n\t\tnode->num_tags = ((tre_union_t *)node->obj)->left->num_tags\n\t\t  + ((tre_union_t *)node->obj)->right->num_tags + added_tags\n\t\t  + ((node->num_submatches > 0) ? 2 : 0);\n\t      }\n\t    regset = tre_stack_pop_voidptr(stack);\n\t    tag_left = tre_stack_pop_int(stack);\n\t    tag_right = tre_stack_pop_int(stack);\n\n\t    /* Add tags after both children, the left child gets a smaller\n\t       tag than the right child.  This guarantees that we prefer\n\t       the left child over the right child. */\n\t    /* XXX - This is not always necessary (if the children have\n\t       tags which must be seen for every match of that child). */\n\t    /* XXX - Check if this is the only place where tre_add_tag_right\n\t       is used.\t If so, use tre_add_tag_left (putting the tag before\n\t       the child as opposed after the child) and throw away\n\t       tre_add_tag_right. */\n\t    if (node->num_submatches > 0)\n\t      {\n\t\tif (!first_pass)\n\t\t  {\n\t\t    status = tre_add_tag_right(mem, left, tag_left);\n\t\t    tnfa->tag_directions[tag_left] = TRE_TAG_MAXIMIZE;\n\t\t    if (status == REG_OK)\n\t\t      status = tre_add_tag_right(mem, right, tag_right);\n\t\t    tnfa->tag_directions[tag_right] = TRE_TAG_MAXIMIZE;\n\t\t  }\n\t\tnum_tags += 2;\n\t      }\n\t    direction = TRE_TAG_MAXIMIZE;\n\t    break;\n\t  }\n\n\tdefault:\n\t  assert(0);\n\t  break;\n\n\t} /* end switch(symbol) */\n    } /* end while(tre_stack_num_objects(stack) > bottom) */\n\n  if (!first_pass)\n    tre_purge_regset(regset, tnfa, tag);\n\n  if (!first_pass && minimal_tag >= 0)\n    {\n      int i;\n      for (i = 0; tnfa->minimal_tags[i] >= 0; i++);\n      tnfa->minimal_tags[i] = tag;\n      tnfa->minimal_tags[i + 1] = minimal_tag;\n      tnfa->minimal_tags[i + 2] = -1;\n      minimal_tag = -1;\n      num_minimals++;\n    }\n\n  assert(tree->num_tags == num_tags);\n  tnfa->end_tag = num_tags;\n  tnfa->num_tags = num_tags;\n  tnfa->num_minimals = num_minimals;\n  xfree(orig_regset);\n  xfree(parents);\n  xfree(saved_states);\n  return status;\n}\n\n\n\n/*\n  AST to TNFA compilation routines.\n*/\n\ntypedef enum {\n  COPY_RECURSE,\n  COPY_SET_RESULT_PTR\n} tre_copyast_symbol_t;\n\n/* Flags for tre_copy_ast(). */\n#define COPY_REMOVE_TAGS\t 1\n#define COPY_MAXIMIZE_FIRST_TAG\t 2\n\nstatic reg_errcode_t\ntre_copy_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,\n\t     int flags, int *pos_add, tre_tag_direction_t *tag_directions,\n\t     tre_ast_node_t **copy, int *max_pos)\n{\n  reg_errcode_t status = REG_OK;\n  int bottom = tre_stack_num_objects(stack);\n  int num_copied = 0;\n  int first_tag = 1;\n  tre_ast_node_t **result = copy;\n  tre_copyast_symbol_t symbol;\n\n  STACK_PUSH(stack, voidptr, ast);\n  STACK_PUSH(stack, int, COPY_RECURSE);\n\n  while (status == REG_OK && tre_stack_num_objects(stack) > bottom)\n    {\n      tre_ast_node_t *node;\n      if (status != REG_OK)\n\tbreak;\n\n      symbol = (tre_copyast_symbol_t)tre_stack_pop_int(stack);\n      switch (symbol)\n\t{\n\tcase COPY_SET_RESULT_PTR:\n\t  result = tre_stack_pop_voidptr(stack);\n\t  break;\n\tcase COPY_RECURSE:\n\t  node = tre_stack_pop_voidptr(stack);\n\t  switch (node->type)\n\t    {\n\t    case LITERAL:\n\t      {\n\t\ttre_literal_t *lit = node->obj;\n\t\tint pos = lit->position;\n\t\tint min = lit->code_min;\n\t\tint max = lit->code_max;\n\t\tif (!IS_SPECIAL(lit) || IS_BACKREF(lit))\n\t\t  {\n\t\t    /* XXX - e.g. [ab] has only one position but two\n\t\t       nodes, so we are creating holes in the state space\n\t\t       here.  Not fatal, just wastes memory. */\n\t\t    pos += *pos_add;\n\t\t    num_copied++;\n\t\t  }\n\t\telse if (IS_TAG(lit) && (flags & COPY_REMOVE_TAGS))\n\t\t  {\n\t\t    /* Change this tag to empty. */\n\t\t    min = EMPTY;\n\t\t    max = pos = -1;\n\t\t  }\n\t\telse if (IS_TAG(lit) && (flags & COPY_MAXIMIZE_FIRST_TAG)\n\t\t\t && first_tag)\n\t\t  {\n\t\t    /* Maximize the first tag. */\n\t\t    tag_directions[max] = TRE_TAG_MAXIMIZE;\n\t\t    first_tag = 0;\n\t\t  }\n\t\t*result = tre_ast_new_literal(mem, min, max, pos);\n\t\tif (*result == NULL)\n\t\t  status = REG_ESPACE;\n\t\telse {\n\t\t  tre_literal_t *p = (*result)->obj;\n\t\t  p->class = lit->class;\n\t\t  p->neg_classes = lit->neg_classes;\n\t\t}\n\n\t\tif (pos > *max_pos)\n\t\t  *max_pos = pos;\n\t\tbreak;\n\t      }\n\t    case UNION:\n\t      {\n\t\ttre_union_t *uni = node->obj;\n\t\ttre_union_t *tmp;\n\t\t*result = tre_ast_new_union(mem, uni->left, uni->right);\n\t\tif (*result == NULL)\n\t\t  {\n\t\t    status = REG_ESPACE;\n\t\t    break;\n\t\t  }\n\t\ttmp = (*result)->obj;\n\t\tresult = &tmp->left;\n\t\tSTACK_PUSHX(stack, voidptr, uni->right);\n\t\tSTACK_PUSHX(stack, int, COPY_RECURSE);\n\t\tSTACK_PUSHX(stack, voidptr, &tmp->right);\n\t\tSTACK_PUSHX(stack, int, COPY_SET_RESULT_PTR);\n\t\tSTACK_PUSHX(stack, voidptr, uni->left);\n\t\tSTACK_PUSHX(stack, int, COPY_RECURSE);\n\t\tbreak;\n\t      }\n\t    case CATENATION:\n\t      {\n\t\ttre_catenation_t *cat = node->obj;\n\t\ttre_catenation_t *tmp;\n\t\t*result = tre_ast_new_catenation(mem, cat->left, cat->right);\n\t\tif (*result == NULL)\n\t\t  {\n\t\t    status = REG_ESPACE;\n\t\t    break;\n\t\t  }\n\t\ttmp = (*result)->obj;\n\t\ttmp->left = NULL;\n\t\ttmp->right = NULL;\n\t\tresult = &tmp->left;\n\n\t\tSTACK_PUSHX(stack, voidptr, cat->right);\n\t\tSTACK_PUSHX(stack, int, COPY_RECURSE);\n\t\tSTACK_PUSHX(stack, voidptr, &tmp->right);\n\t\tSTACK_PUSHX(stack, int, COPY_SET_RESULT_PTR);\n\t\tSTACK_PUSHX(stack, voidptr, cat->left);\n\t\tSTACK_PUSHX(stack, int, COPY_RECURSE);\n\t\tbreak;\n\t      }\n\t    case ITERATION:\n\t      {\n\t\ttre_iteration_t *iter = node->obj;\n\t\tSTACK_PUSHX(stack, voidptr, iter->arg);\n\t\tSTACK_PUSHX(stack, int, COPY_RECURSE);\n\t\t*result = tre_ast_new_iter(mem, iter->arg, iter->min,\n\t\t\t\t\t   iter->max, iter->minimal);\n\t\tif (*result == NULL)\n\t\t  {\n\t\t    status = REG_ESPACE;\n\t\t    break;\n\t\t  }\n\t\titer = (*result)->obj;\n\t\tresult = &iter->arg;\n\t\tbreak;\n\t      }\n\t    default:\n\t      assert(0);\n\t      break;\n\t    }\n\t  break;\n\t}\n    }\n  *pos_add += num_copied;\n  return status;\n}\n\ntypedef enum {\n  EXPAND_RECURSE,\n  EXPAND_AFTER_ITER\n} tre_expand_ast_symbol_t;\n\n/* Expands each iteration node that has a finite nonzero minimum or maximum\n   iteration count to a catenated sequence of copies of the node. */\nstatic reg_errcode_t\ntre_expand_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,\n\t       int *position, tre_tag_direction_t *tag_directions)\n{\n  reg_errcode_t status = REG_OK;\n  int bottom = tre_stack_num_objects(stack);\n  int pos_add = 0;\n  int pos_add_total = 0;\n  int max_pos = 0;\n  int iter_depth = 0;\n\n  STACK_PUSHR(stack, voidptr, ast);\n  STACK_PUSHR(stack, int, EXPAND_RECURSE);\n  while (status == REG_OK && tre_stack_num_objects(stack) > bottom)\n    {\n      tre_ast_node_t *node;\n      tre_expand_ast_symbol_t symbol;\n\n      if (status != REG_OK)\n\tbreak;\n\n      symbol = (tre_expand_ast_symbol_t)tre_stack_pop_int(stack);\n      node = tre_stack_pop_voidptr(stack);\n      switch (symbol)\n\t{\n\tcase EXPAND_RECURSE:\n\t  switch (node->type)\n\t    {\n\t    case LITERAL:\n\t      {\n\t\ttre_literal_t *lit= node->obj;\n\t\tif (!IS_SPECIAL(lit) || IS_BACKREF(lit))\n\t\t  {\n\t\t    lit->position += pos_add;\n\t\t    if (lit->position > max_pos)\n\t\t      max_pos = lit->position;\n\t\t  }\n\t\tbreak;\n\t      }\n\t    case UNION:\n\t      {\n\t\ttre_union_t *uni = node->obj;\n\t\tSTACK_PUSHX(stack, voidptr, uni->right);\n\t\tSTACK_PUSHX(stack, int, EXPAND_RECURSE);\n\t\tSTACK_PUSHX(stack, voidptr, uni->left);\n\t\tSTACK_PUSHX(stack, int, EXPAND_RECURSE);\n\t\tbreak;\n\t      }\n\t    case CATENATION:\n\t      {\n\t\ttre_catenation_t *cat = node->obj;\n\t\tSTACK_PUSHX(stack, voidptr, cat->right);\n\t\tSTACK_PUSHX(stack, int, EXPAND_RECURSE);\n\t\tSTACK_PUSHX(stack, voidptr, cat->left);\n\t\tSTACK_PUSHX(stack, int, EXPAND_RECURSE);\n\t\tbreak;\n\t      }\n\t    case ITERATION:\n\t      {\n\t\ttre_iteration_t *iter = node->obj;\n\t\tSTACK_PUSHX(stack, int, pos_add);\n\t\tSTACK_PUSHX(stack, voidptr, node);\n\t\tSTACK_PUSHX(stack, int, EXPAND_AFTER_ITER);\n\t\tSTACK_PUSHX(stack, voidptr, iter->arg);\n\t\tSTACK_PUSHX(stack, int, EXPAND_RECURSE);\n\t\t/* If we are going to expand this node at EXPAND_AFTER_ITER\n\t\t   then don't increase the `pos' fields of the nodes now, it\n\t\t   will get done when expanding. */\n\t\tif (iter->min > 1 || iter->max > 1)\n\t\t  pos_add = 0;\n\t\titer_depth++;\n\t\tbreak;\n\t      }\n\t    default:\n\t      assert(0);\n\t      break;\n\t    }\n\t  break;\n\tcase EXPAND_AFTER_ITER:\n\t  {\n\t    tre_iteration_t *iter = node->obj;\n\t    int pos_add_last;\n\t    pos_add = tre_stack_pop_int(stack);\n\t    pos_add_last = pos_add;\n\t    if (iter->min > 1 || iter->max > 1)\n\t      {\n\t\ttre_ast_node_t *seq1 = NULL, *seq2 = NULL;\n\t\tint j;\n\t\tint pos_add_save = pos_add;\n\n\t\t/* Create a catenated sequence of copies of the node. */\n\t\tfor (j = 0; j < iter->min; j++)\n\t\t  {\n\t\t    tre_ast_node_t *copy;\n\t\t    /* Remove tags from all but the last copy. */\n\t\t    int flags = ((j + 1 < iter->min)\n\t\t\t\t ? COPY_REMOVE_TAGS\n\t\t\t\t : COPY_MAXIMIZE_FIRST_TAG);\n\t\t    pos_add_save = pos_add;\n\t\t    status = tre_copy_ast(mem, stack, iter->arg, flags,\n\t\t\t\t\t  &pos_add, tag_directions, &copy,\n\t\t\t\t\t  &max_pos);\n\t\t    if (status != REG_OK)\n\t\t      return status;\n\t\t    if (seq1 != NULL)\n\t\t      seq1 = tre_ast_new_catenation(mem, seq1, copy);\n\t\t    else\n\t\t      seq1 = copy;\n\t\t    if (seq1 == NULL)\n\t\t      return REG_ESPACE;\n\t\t  }\n\n\t\tif (iter->max == -1)\n\t\t  {\n\t\t    /* No upper limit. */\n\t\t    pos_add_save = pos_add;\n\t\t    status = tre_copy_ast(mem, stack, iter->arg, 0,\n\t\t\t\t\t  &pos_add, NULL, &seq2, &max_pos);\n\t\t    if (status != REG_OK)\n\t\t      return status;\n\t\t    seq2 = tre_ast_new_iter(mem, seq2, 0, -1, 0);\n\t\t    if (seq2 == NULL)\n\t\t      return REG_ESPACE;\n\t\t  }\n\t\telse\n\t\t  {\n\t\t    for (j = iter->min; j < iter->max; j++)\n\t\t      {\n\t\t\ttre_ast_node_t *tmp, *copy;\n\t\t\tpos_add_save = pos_add;\n\t\t\tstatus = tre_copy_ast(mem, stack, iter->arg, 0,\n\t\t\t\t\t      &pos_add, NULL, &copy, &max_pos);\n\t\t\tif (status != REG_OK)\n\t\t\t  return status;\n\t\t\tif (seq2 != NULL)\n\t\t\t  seq2 = tre_ast_new_catenation(mem, copy, seq2);\n\t\t\telse\n\t\t\t  seq2 = copy;\n\t\t\tif (seq2 == NULL)\n\t\t\t  return REG_ESPACE;\n\t\t\ttmp = tre_ast_new_literal(mem, EMPTY, -1, -1);\n\t\t\tif (tmp == NULL)\n\t\t\t  return REG_ESPACE;\n\t\t\tseq2 = tre_ast_new_union(mem, tmp, seq2);\n\t\t\tif (seq2 == NULL)\n\t\t\t  return REG_ESPACE;\n\t\t      }\n\t\t  }\n\n\t\tpos_add = pos_add_save;\n\t\tif (seq1 == NULL)\n\t\t  seq1 = seq2;\n\t\telse if (seq2 != NULL)\n\t\t  seq1 = tre_ast_new_catenation(mem, seq1, seq2);\n\t\tif (seq1 == NULL)\n\t\t  return REG_ESPACE;\n\t\tnode->obj = seq1->obj;\n\t\tnode->type = seq1->type;\n\t      }\n\n\t    iter_depth--;\n\t    pos_add_total += pos_add - pos_add_last;\n\t    if (iter_depth == 0)\n\t      pos_add = pos_add_total;\n\n\t    break;\n\t  }\n\tdefault:\n\t  assert(0);\n\t  break;\n\t}\n    }\n\n  *position += pos_add_total;\n\n  /* `max_pos' should never be larger than `*position' if the above\n     code works, but just an extra safeguard let's make sure\n     `*position' is set large enough so enough memory will be\n     allocated for the transition table. */\n  if (max_pos > *position)\n    *position = max_pos;\n\n  return status;\n}\n\nstatic tre_pos_and_tags_t *\ntre_set_empty(tre_mem_t mem)\n{\n  tre_pos_and_tags_t *new_set;\n\n  new_set = tre_mem_calloc(mem, sizeof(*new_set));\n  if (new_set == NULL)\n    return NULL;\n\n  new_set[0].position = -1;\n  new_set[0].code_min = -1;\n  new_set[0].code_max = -1;\n\n  return new_set;\n}\n\nstatic tre_pos_and_tags_t *\ntre_set_one(tre_mem_t mem, int position, int code_min, int code_max,\n\t    tre_ctype_t class, tre_ctype_t *neg_classes, int backref)\n{\n  tre_pos_and_tags_t *new_set;\n\n  new_set = tre_mem_calloc(mem, sizeof(*new_set) * 2);\n  if (new_set == NULL)\n    return NULL;\n\n  new_set[0].position = position;\n  new_set[0].code_min = code_min;\n  new_set[0].code_max = code_max;\n  new_set[0].class = class;\n  new_set[0].neg_classes = neg_classes;\n  new_set[0].backref = backref;\n  new_set[1].position = -1;\n  new_set[1].code_min = -1;\n  new_set[1].code_max = -1;\n\n  return new_set;\n}\n\nstatic tre_pos_and_tags_t *\ntre_set_union(tre_mem_t mem, tre_pos_and_tags_t *set1, tre_pos_and_tags_t *set2,\n\t      int *tags, int assertions)\n{\n  int s1, s2, i, j;\n  tre_pos_and_tags_t *new_set;\n  int *new_tags;\n  int num_tags;\n\n  for (num_tags = 0; tags != NULL && tags[num_tags] >= 0; num_tags++);\n  for (s1 = 0; set1[s1].position >= 0; s1++);\n  for (s2 = 0; set2[s2].position >= 0; s2++);\n  new_set = tre_mem_calloc(mem, sizeof(*new_set) * (s1 + s2 + 1));\n  if (!new_set )\n    return NULL;\n\n  for (s1 = 0; set1[s1].position >= 0; s1++)\n    {\n      new_set[s1].position = set1[s1].position;\n      new_set[s1].code_min = set1[s1].code_min;\n      new_set[s1].code_max = set1[s1].code_max;\n      new_set[s1].assertions = set1[s1].assertions | assertions;\n      new_set[s1].class = set1[s1].class;\n      new_set[s1].neg_classes = set1[s1].neg_classes;\n      new_set[s1].backref = set1[s1].backref;\n      if (set1[s1].tags == NULL && tags == NULL)\n\tnew_set[s1].tags = NULL;\n      else\n\t{\n\t  for (i = 0; set1[s1].tags != NULL && set1[s1].tags[i] >= 0; i++);\n\t  new_tags = tre_mem_alloc(mem, (sizeof(*new_tags)\n\t\t\t\t\t * (i + num_tags + 1)));\n\t  if (new_tags == NULL)\n\t    return NULL;\n\t  for (j = 0; j < i; j++)\n\t    new_tags[j] = set1[s1].tags[j];\n\t  for (i = 0; i < num_tags; i++)\n\t    new_tags[j + i] = tags[i];\n\t  new_tags[j + i] = -1;\n\t  new_set[s1].tags = new_tags;\n\t}\n    }\n\n  for (s2 = 0; set2[s2].position >= 0; s2++)\n    {\n      new_set[s1 + s2].position = set2[s2].position;\n      new_set[s1 + s2].code_min = set2[s2].code_min;\n      new_set[s1 + s2].code_max = set2[s2].code_max;\n      /* XXX - why not | assertions here as well? */\n      new_set[s1 + s2].assertions = set2[s2].assertions;\n      new_set[s1 + s2].class = set2[s2].class;\n      new_set[s1 + s2].neg_classes = set2[s2].neg_classes;\n      new_set[s1 + s2].backref = set2[s2].backref;\n      if (set2[s2].tags == NULL)\n\tnew_set[s1 + s2].tags = NULL;\n      else\n\t{\n\t  for (i = 0; set2[s2].tags[i] >= 0; i++);\n\t  new_tags = tre_mem_alloc(mem, sizeof(*new_tags) * (i + 1));\n\t  if (new_tags == NULL)\n\t    return NULL;\n\t  for (j = 0; j < i; j++)\n\t    new_tags[j] = set2[s2].tags[j];\n\t  new_tags[j] = -1;\n\t  new_set[s1 + s2].tags = new_tags;\n\t}\n    }\n  new_set[s1 + s2].position = -1;\n  return new_set;\n}\n\n/* Finds the empty path through `node' which is the one that should be\n   taken according to POSIX.2 rules, and adds the tags on that path to\n   `tags'.   `tags' may be NULL.  If `num_tags_seen' is not NULL, it is\n   set to the number of tags seen on the path. */\nstatic reg_errcode_t\ntre_match_empty(tre_stack_t *stack, tre_ast_node_t *node, int *tags,\n\t\tint *assertions, int *num_tags_seen)\n{\n  tre_literal_t *lit;\n  tre_union_t *uni;\n  tre_catenation_t *cat;\n  tre_iteration_t *iter;\n  int i;\n  int bottom = tre_stack_num_objects(stack);\n  reg_errcode_t status = REG_OK;\n  if (num_tags_seen)\n    *num_tags_seen = 0;\n\n  status = tre_stack_push_voidptr(stack, node);\n\n  /* Walk through the tree recursively. */\n  while (status == REG_OK && tre_stack_num_objects(stack) > bottom)\n    {\n      node = tre_stack_pop_voidptr(stack);\n\n      switch (node->type)\n\t{\n\tcase LITERAL:\n\t  lit = (tre_literal_t *)node->obj;\n\t  switch (lit->code_min)\n\t    {\n\t    case TAG:\n\t      if (lit->code_max >= 0)\n\t\t{\n\t\t  if (tags != NULL)\n\t\t    {\n\t\t      /* Add the tag to `tags'. */\n\t\t      for (i = 0; tags[i] >= 0; i++)\n\t\t\tif (tags[i] == lit->code_max)\n\t\t\t  break;\n\t\t      if (tags[i] < 0)\n\t\t\t{\n\t\t\t  tags[i] = lit->code_max;\n\t\t\t  tags[i + 1] = -1;\n\t\t\t}\n\t\t    }\n\t\t  if (num_tags_seen)\n\t\t    (*num_tags_seen)++;\n\t\t}\n\t      break;\n\t    case ASSERTION:\n\t      assert(lit->code_max >= 1\n\t\t     || lit->code_max <= ASSERT_LAST);\n\t      if (assertions != NULL)\n\t\t*assertions |= lit->code_max;\n\t      break;\n\t    case EMPTY:\n\t      break;\n\t    default:\n\t      assert(0);\n\t      break;\n\t    }\n\t  break;\n\n\tcase UNION:\n\t  /* Subexpressions starting earlier take priority over ones\n\t     starting later, so we prefer the left subexpression over the\n\t     right subexpression. */\n\t  uni = (tre_union_t *)node->obj;\n\t  if (uni->left->nullable)\n\t    STACK_PUSHX(stack, voidptr, uni->left)\n\t  else if (uni->right->nullable)\n\t    STACK_PUSHX(stack, voidptr, uni->right)\n\t  else\n\t    assert(0);\n\t  break;\n\n\tcase CATENATION:\n\t  /* The path must go through both children. */\n\t  cat = (tre_catenation_t *)node->obj;\n\t  assert(cat->left->nullable);\n\t  assert(cat->right->nullable);\n\t  STACK_PUSHX(stack, voidptr, cat->left);\n\t  STACK_PUSHX(stack, voidptr, cat->right);\n\t  break;\n\n\tcase ITERATION:\n\t  /* A match with an empty string is preferred over no match at\n\t     all, so we go through the argument if possible. */\n\t  iter = (tre_iteration_t *)node->obj;\n\t  if (iter->arg->nullable)\n\t    STACK_PUSHX(stack, voidptr, iter->arg);\n\t  break;\n\n\tdefault:\n\t  assert(0);\n\t  break;\n\t}\n    }\n\n  return status;\n}\n\n\ntypedef enum {\n  NFL_RECURSE,\n  NFL_POST_UNION,\n  NFL_POST_CATENATION,\n  NFL_POST_ITERATION\n} tre_nfl_stack_symbol_t;\n\n\n/* Computes and fills in the fields `nullable', `firstpos', and `lastpos' for\n   the nodes of the AST `tree'. */\nstatic reg_errcode_t\ntre_compute_nfl(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *tree)\n{\n  int bottom = tre_stack_num_objects(stack);\n\n  STACK_PUSHR(stack, voidptr, tree);\n  STACK_PUSHR(stack, int, NFL_RECURSE);\n\n  while (tre_stack_num_objects(stack) > bottom)\n    {\n      tre_nfl_stack_symbol_t symbol;\n      tre_ast_node_t *node;\n\n      symbol = (tre_nfl_stack_symbol_t)tre_stack_pop_int(stack);\n      node = tre_stack_pop_voidptr(stack);\n      switch (symbol)\n\t{\n\tcase NFL_RECURSE:\n\t  switch (node->type)\n\t    {\n\t    case LITERAL:\n\t      {\n\t\ttre_literal_t *lit = (tre_literal_t *)node->obj;\n\t\tif (IS_BACKREF(lit))\n\t\t  {\n\t\t    /* Back references: nullable = false, firstpos = {i},\n\t\t       lastpos = {i}. */\n\t\t    node->nullable = 0;\n\t\t    node->firstpos = tre_set_one(mem, lit->position, 0,\n\t\t\t\t\t     TRE_CHAR_MAX, 0, NULL, -1);\n\t\t    if (!node->firstpos)\n\t\t      return REG_ESPACE;\n\t\t    node->lastpos = tre_set_one(mem, lit->position, 0,\n\t\t\t\t\t\tTRE_CHAR_MAX, 0, NULL,\n\t\t\t\t\t\t(int)lit->code_max);\n\t\t    if (!node->lastpos)\n\t\t      return REG_ESPACE;\n\t\t  }\n\t\telse if (lit->code_min < 0)\n\t\t  {\n\t\t    /* Tags, empty strings, params, and zero width assertions:\n\t\t       nullable = true, firstpos = {}, and lastpos = {}. */\n\t\t    node->nullable = 1;\n\t\t    node->firstpos = tre_set_empty(mem);\n\t\t    if (!node->firstpos)\n\t\t      return REG_ESPACE;\n\t\t    node->lastpos = tre_set_empty(mem);\n\t\t    if (!node->lastpos)\n\t\t      return REG_ESPACE;\n\t\t  }\n\t\telse\n\t\t  {\n\t\t    /* Literal at position i: nullable = false, firstpos = {i},\n\t\t       lastpos = {i}. */\n\t\t    node->nullable = 0;\n\t\t    node->firstpos =\n\t\t      tre_set_one(mem, lit->position, (int)lit->code_min,\n\t\t\t\t  (int)lit->code_max, 0, NULL, -1);\n\t\t    if (!node->firstpos)\n\t\t      return REG_ESPACE;\n\t\t    node->lastpos = tre_set_one(mem, lit->position,\n\t\t\t\t\t\t(int)lit->code_min,\n\t\t\t\t\t\t(int)lit->code_max,\n\t\t\t\t\t\tlit->class, lit->neg_classes,\n\t\t\t\t\t\t-1);\n\t\t    if (!node->lastpos)\n\t\t      return REG_ESPACE;\n\t\t  }\n\t\tbreak;\n\t      }\n\n\t    case UNION:\n\t      /* Compute the attributes for the two subtrees, and after that\n\t\t for this node. */\n\t      STACK_PUSHR(stack, voidptr, node);\n\t      STACK_PUSHR(stack, int, NFL_POST_UNION);\n\t      STACK_PUSHR(stack, voidptr, ((tre_union_t *)node->obj)->right);\n\t      STACK_PUSHR(stack, int, NFL_RECURSE);\n\t      STACK_PUSHR(stack, voidptr, ((tre_union_t *)node->obj)->left);\n\t      STACK_PUSHR(stack, int, NFL_RECURSE);\n\t      break;\n\n\t    case CATENATION:\n\t      /* Compute the attributes for the two subtrees, and after that\n\t\t for this node. */\n\t      STACK_PUSHR(stack, voidptr, node);\n\t      STACK_PUSHR(stack, int, NFL_POST_CATENATION);\n\t      STACK_PUSHR(stack, voidptr, ((tre_catenation_t *)node->obj)->right);\n\t      STACK_PUSHR(stack, int, NFL_RECURSE);\n\t      STACK_PUSHR(stack, voidptr, ((tre_catenation_t *)node->obj)->left);\n\t      STACK_PUSHR(stack, int, NFL_RECURSE);\n\t      break;\n\n\t    case ITERATION:\n\t      /* Compute the attributes for the subtree, and after that for\n\t\t this node. */\n\t      STACK_PUSHR(stack, voidptr, node);\n\t      STACK_PUSHR(stack, int, NFL_POST_ITERATION);\n\t      STACK_PUSHR(stack, voidptr, ((tre_iteration_t *)node->obj)->arg);\n\t      STACK_PUSHR(stack, int, NFL_RECURSE);\n\t      break;\n\t    }\n\t  break; /* end case: NFL_RECURSE */\n\n\tcase NFL_POST_UNION:\n\t  {\n\t    tre_union_t *uni = (tre_union_t *)node->obj;\n\t    node->nullable = uni->left->nullable || uni->right->nullable;\n\t    node->firstpos = tre_set_union(mem, uni->left->firstpos,\n\t\t\t\t\t   uni->right->firstpos, NULL, 0);\n\t    if (!node->firstpos)\n\t      return REG_ESPACE;\n\t    node->lastpos = tre_set_union(mem, uni->left->lastpos,\n\t\t\t\t\t  uni->right->lastpos, NULL, 0);\n\t    if (!node->lastpos)\n\t      return REG_ESPACE;\n\t    break;\n\t  }\n\n\tcase NFL_POST_ITERATION:\n\t  {\n\t    tre_iteration_t *iter = (tre_iteration_t *)node->obj;\n\n\t    if (iter->min == 0 || iter->arg->nullable)\n\t      node->nullable = 1;\n\t    else\n\t      node->nullable = 0;\n\t    node->firstpos = iter->arg->firstpos;\n\t    node->lastpos = iter->arg->lastpos;\n\t    break;\n\t  }\n\n\tcase NFL_POST_CATENATION:\n\t  {\n\t    int num_tags, *tags, assertions;\n\t    reg_errcode_t status;\n\t    tre_catenation_t *cat = node->obj;\n\t    node->nullable = cat->left->nullable && cat->right->nullable;\n\n\t    /* Compute firstpos. */\n\t    if (cat->left->nullable)\n\t      {\n\t\t/* The left side matches the empty string.  Make a first pass\n\t\t   with tre_match_empty() to get the number of tags and\n\t\t   parameters. */\n\t\tstatus = tre_match_empty(stack, cat->left,\n\t\t\t\t\t NULL, NULL, &num_tags);\n\t\tif (status != REG_OK)\n\t\t  return status;\n\t\t/* Allocate arrays for the tags and parameters. */\n\t\ttags = xmalloc(sizeof(*tags) * (num_tags + 1));\n\t\tif (!tags)\n\t\t  return REG_ESPACE;\n\t\ttags[0] = -1;\n\t\tassertions = 0;\n\t\t/* Second pass with tre_mach_empty() to get the list of\n\t\t   tags and parameters. */\n\t\tstatus = tre_match_empty(stack, cat->left, tags,\n\t\t\t\t\t &assertions, NULL);\n\t\tif (status != REG_OK)\n\t\t  {\n\t\t    xfree(tags);\n\t\t    return status;\n\t\t  }\n\t\tnode->firstpos =\n\t\t  tre_set_union(mem, cat->right->firstpos, cat->left->firstpos,\n\t\t\t\ttags, assertions);\n\t\txfree(tags);\n\t\tif (!node->firstpos)\n\t\t  return REG_ESPACE;\n\t      }\n\t    else\n\t      {\n\t\tnode->firstpos = cat->left->firstpos;\n\t      }\n\n\t    /* Compute lastpos. */\n\t    if (cat->right->nullable)\n\t      {\n\t\t/* The right side matches the empty string.  Make a first pass\n\t\t   with tre_match_empty() to get the number of tags and\n\t\t   parameters. */\n\t\tstatus = tre_match_empty(stack, cat->right,\n\t\t\t\t\t NULL, NULL, &num_tags);\n\t\tif (status != REG_OK)\n\t\t  return status;\n\t\t/* Allocate arrays for the tags and parameters. */\n\t\ttags = xmalloc(sizeof(int) * (num_tags + 1));\n\t\tif (!tags)\n\t\t  return REG_ESPACE;\n\t\ttags[0] = -1;\n\t\tassertions = 0;\n\t\t/* Second pass with tre_mach_empty() to get the list of\n\t\t   tags and parameters. */\n\t\tstatus = tre_match_empty(stack, cat->right, tags,\n\t\t\t\t\t &assertions, NULL);\n\t\tif (status != REG_OK)\n\t\t  {\n\t\t    xfree(tags);\n\t\t    return status;\n\t\t  }\n\t\tnode->lastpos =\n\t\t  tre_set_union(mem, cat->left->lastpos, cat->right->lastpos,\n\t\t\t\ttags, assertions);\n\t\txfree(tags);\n\t\tif (!node->lastpos)\n\t\t  return REG_ESPACE;\n\t      }\n\t    else\n\t      {\n\t\tnode->lastpos = cat->right->lastpos;\n\t      }\n\t    break;\n\t  }\n\n\tdefault:\n\t  assert(0);\n\t  break;\n\t}\n    }\n\n  return REG_OK;\n}\n\n\n/* Adds a transition from each position in `p1' to each position in `p2'. */\nstatic reg_errcode_t\ntre_make_trans(tre_pos_and_tags_t *p1, tre_pos_and_tags_t *p2,\n\t       tre_tnfa_transition_t *transitions,\n\t       int *counts, int *offs)\n{\n  tre_pos_and_tags_t *orig_p2 = p2;\n  tre_tnfa_transition_t *trans;\n  int i, j, k, l, dup, prev_p2_pos;\n\n  if (transitions != NULL)\n    while (p1->position >= 0)\n      {\n\tp2 = orig_p2;\n\tprev_p2_pos = -1;\n\twhile (p2->position >= 0)\n\t  {\n\t    /* Optimization: if this position was already handled, skip it. */\n\t    if (p2->position == prev_p2_pos)\n\t      {\n\t\tp2++;\n\t\tcontinue;\n\t      }\n\t    prev_p2_pos = p2->position;\n\t    /* Set `trans' to point to the next unused transition from\n\t       position `p1->position'. */\n\t    trans = transitions + offs[p1->position];\n\t    while (trans->state != NULL)\n\t      {\n#if 0\n\t\t/* If we find a previous transition from `p1->position' to\n\t\t   `p2->position', it is overwritten.  This can happen only\n\t\t   if there are nested loops in the regexp, like in \"((a)*)*\".\n\t\t   In POSIX.2 repetition using the outer loop is always\n\t\t   preferred over using the inner loop.\t Therefore the\n\t\t   transition for the inner loop is useless and can be thrown\n\t\t   away. */\n\t\t/* XXX - The same position is used for all nodes in a bracket\n\t\t   expression, so this optimization cannot be used (it will\n\t\t   break bracket expressions) unless I figure out a way to\n\t\t   detect it here. */\n\t\tif (trans->state_id == p2->position)\n\t\t  {\n\t\t    break;\n\t\t  }\n#endif\n\t\ttrans++;\n\t      }\n\n\t    if (trans->state == NULL)\n\t      (trans + 1)->state = NULL;\n\t    /* Use the character ranges, assertions, etc. from `p1' for\n\t       the transition from `p1' to `p2'. */\n\t    trans->code_min = p1->code_min;\n\t    trans->code_max = p1->code_max;\n\t    trans->state = transitions + offs[p2->position];\n\t    trans->state_id = p2->position;\n\t    trans->assertions = p1->assertions | p2->assertions\n\t      | (p1->class ? ASSERT_CHAR_CLASS : 0)\n\t      | (p1->neg_classes != NULL ? ASSERT_CHAR_CLASS_NEG : 0);\n\t    if (p1->backref >= 0)\n\t      {\n\t\tassert((trans->assertions & ASSERT_CHAR_CLASS) == 0);\n\t\tassert(p2->backref < 0);\n\t\ttrans->u.backref = p1->backref;\n\t\ttrans->assertions |= ASSERT_BACKREF;\n\t      }\n\t    else\n\t      trans->u.class = p1->class;\n\t    if (p1->neg_classes != NULL)\n\t      {\n\t\tfor (i = 0; p1->neg_classes[i] != (tre_ctype_t)0; i++);\n\t\ttrans->neg_classes =\n\t\t  xmalloc(sizeof(*trans->neg_classes) * (i + 1));\n\t\tif (trans->neg_classes == NULL)\n\t\t  return REG_ESPACE;\n\t\tfor (i = 0; p1->neg_classes[i] != (tre_ctype_t)0; i++)\n\t\t  trans->neg_classes[i] = p1->neg_classes[i];\n\t\ttrans->neg_classes[i] = (tre_ctype_t)0;\n\t      }\n\t    else\n\t      trans->neg_classes = NULL;\n\n\t    /* Find out how many tags this transition has. */\n\t    i = 0;\n\t    if (p1->tags != NULL)\n\t      while(p1->tags[i] >= 0)\n\t\ti++;\n\t    j = 0;\n\t    if (p2->tags != NULL)\n\t      while(p2->tags[j] >= 0)\n\t\tj++;\n\n\t    /* If we are overwriting a transition, free the old tag array. */\n\t    if (trans->tags != NULL)\n\t      xfree(trans->tags);\n\t    trans->tags = NULL;\n\n\t    /* If there were any tags, allocate an array and fill it. */\n\t    if (i + j > 0)\n\t      {\n\t\ttrans->tags = xmalloc(sizeof(*trans->tags) * (i + j + 1));\n\t\tif (!trans->tags)\n\t\t  return REG_ESPACE;\n\t\ti = 0;\n\t\tif (p1->tags != NULL)\n\t\t  while(p1->tags[i] >= 0)\n\t\t    {\n\t\t      trans->tags[i] = p1->tags[i];\n\t\t      i++;\n\t\t    }\n\t\tl = i;\n\t\tj = 0;\n\t\tif (p2->tags != NULL)\n\t\t  while (p2->tags[j] >= 0)\n\t\t    {\n\t\t      /* Don't add duplicates. */\n\t\t      dup = 0;\n\t\t      for (k = 0; k < i; k++)\n\t\t\tif (trans->tags[k] == p2->tags[j])\n\t\t\t  {\n\t\t\t    dup = 1;\n\t\t\t    break;\n\t\t\t  }\n\t\t      if (!dup)\n\t\t\ttrans->tags[l++] = p2->tags[j];\n\t\t      j++;\n\t\t    }\n\t\ttrans->tags[l] = -1;\n\t      }\n\n\t    p2++;\n\t  }\n\tp1++;\n      }\n  else\n    /* Compute a maximum limit for the number of transitions leaving\n       from each state. */\n    while (p1->position >= 0)\n      {\n\tp2 = orig_p2;\n\twhile (p2->position >= 0)\n\t  {\n\t    counts[p1->position]++;\n\t    p2++;\n\t  }\n\tp1++;\n      }\n  return REG_OK;\n}\n\n/* Converts the syntax tree to a TNFA.\tAll the transitions in the TNFA are\n   labelled with one character range (there are no transitions on empty\n   strings).  The TNFA takes O(n^2) space in the worst case, `n' is size of\n   the regexp. */\nstatic reg_errcode_t\ntre_ast_to_tnfa(tre_ast_node_t *node, tre_tnfa_transition_t *transitions,\n\t\tint *counts, int *offs)\n{\n  tre_union_t *uni;\n  tre_catenation_t *cat;\n  tre_iteration_t *iter;\n  reg_errcode_t errcode = REG_OK;\n\n  /* XXX - recurse using a stack!. */\n  switch (node->type)\n    {\n    case LITERAL:\n      break;\n    case UNION:\n      uni = (tre_union_t *)node->obj;\n      errcode = tre_ast_to_tnfa(uni->left, transitions, counts, offs);\n      if (errcode != REG_OK)\n\treturn errcode;\n      errcode = tre_ast_to_tnfa(uni->right, transitions, counts, offs);\n      break;\n\n    case CATENATION:\n      cat = (tre_catenation_t *)node->obj;\n      /* Add a transition from each position in cat->left->lastpos\n\t to each position in cat->right->firstpos. */\n      errcode = tre_make_trans(cat->left->lastpos, cat->right->firstpos,\n\t\t\t       transitions, counts, offs);\n      if (errcode != REG_OK)\n\treturn errcode;\n      errcode = tre_ast_to_tnfa(cat->left, transitions, counts, offs);\n      if (errcode != REG_OK)\n\treturn errcode;\n      errcode = tre_ast_to_tnfa(cat->right, transitions, counts, offs);\n      break;\n\n    case ITERATION:\n      iter = (tre_iteration_t *)node->obj;\n      assert(iter->max == -1 || iter->max == 1);\n\n      if (iter->max == -1)\n\t{\n\t  assert(iter->min == 0 || iter->min == 1);\n\t  /* Add a transition from each last position in the iterated\n\t     expression to each first position. */\n\t  errcode = tre_make_trans(iter->arg->lastpos, iter->arg->firstpos,\n\t\t\t\t   transitions, counts, offs);\n\t  if (errcode != REG_OK)\n\t    return errcode;\n\t}\n      errcode = tre_ast_to_tnfa(iter->arg, transitions, counts, offs);\n      break;\n    }\n  return errcode;\n}\n\n\n#define ERROR_EXIT(err)\t\t  \\\n  do\t\t\t\t  \\\n    {\t\t\t\t  \\\n      errcode = err;\t\t  \\\n      if (/*CONSTCOND*/1)\t  \\\n      \tgoto error_exit;\t  \\\n    }\t\t\t\t  \\\n while (/*CONSTCOND*/0)\n\n\nint\nregcomp(regex_t *restrict preg, const char *restrict regex, int cflags)\n{\n  tre_stack_t *stack;\n  tre_ast_node_t *tree, *tmp_ast_l, *tmp_ast_r;\n  tre_pos_and_tags_t *p;\n  int *counts = NULL, *offs = NULL;\n  int i, add = 0;\n  tre_tnfa_transition_t *transitions, *initial;\n  tre_tnfa_t *tnfa = NULL;\n  tre_submatch_data_t *submatch_data;\n  tre_tag_direction_t *tag_directions = NULL;\n  reg_errcode_t errcode;\n  tre_mem_t mem;\n\n  /* Parse context. */\n  tre_parse_ctx_t parse_ctx;\n\n  /* Allocate a stack used throughout the compilation process for various\n     purposes. */\n  stack = tre_stack_new(512, 1024000, 128);\n  if (!stack)\n    return REG_ESPACE;\n  /* Allocate a fast memory allocator. */\n  mem = tre_mem_new();\n  if (!mem)\n    {\n      tre_stack_destroy(stack);\n      return REG_ESPACE;\n    }\n\n  /* Parse the regexp. */\n  memset(&parse_ctx, 0, sizeof(parse_ctx));\n  parse_ctx.mem = mem;\n  parse_ctx.stack = stack;\n  parse_ctx.start = regex;\n  parse_ctx.cflags = cflags;\n  parse_ctx.max_backref = -1;\n  errcode = tre_parse(&parse_ctx);\n  if (errcode != REG_OK)\n    ERROR_EXIT(errcode);\n  preg->re_nsub = parse_ctx.submatch_id - 1;\n  tree = parse_ctx.n;\n\n#ifdef TRE_DEBUG\n  tre_ast_print(tree);\n#endif /* TRE_DEBUG */\n\n  /* Referring to nonexistent subexpressions is illegal. */\n  if (parse_ctx.max_backref > (int)preg->re_nsub)\n    ERROR_EXIT(REG_ESUBREG);\n\n  /* Allocate the TNFA struct. */\n  tnfa = xcalloc(1, sizeof(tre_tnfa_t));\n  if (tnfa == NULL)\n    ERROR_EXIT(REG_ESPACE);\n  tnfa->have_backrefs = parse_ctx.max_backref >= 0;\n  tnfa->have_approx = 0;\n  tnfa->num_submatches = parse_ctx.submatch_id;\n\n  /* Set up tags for submatch addressing.  If REG_NOSUB is set and the\n     regexp does not have back references, this can be skipped. */\n  if (tnfa->have_backrefs || !(cflags & REG_NOSUB))\n    {\n\n      /* Figure out how many tags we will need. */\n      errcode = tre_add_tags(NULL, stack, tree, tnfa);\n      if (errcode != REG_OK)\n\tERROR_EXIT(errcode);\n\n      if (tnfa->num_tags > 0)\n\t{\n\t  tag_directions = xmalloc(sizeof(*tag_directions)\n\t\t\t\t   * (tnfa->num_tags + 1));\n\t  if (tag_directions == NULL)\n\t    ERROR_EXIT(REG_ESPACE);\n\t  tnfa->tag_directions = tag_directions;\n\t  memset(tag_directions, -1,\n\t\t sizeof(*tag_directions) * (tnfa->num_tags + 1));\n\t}\n      tnfa->minimal_tags = xcalloc((unsigned)tnfa->num_tags * 2 + 1,\n\t\t\t\t   sizeof(*tnfa->minimal_tags));\n      if (tnfa->minimal_tags == NULL)\n\tERROR_EXIT(REG_ESPACE);\n\n      submatch_data = xcalloc((unsigned)parse_ctx.submatch_id,\n\t\t\t      sizeof(*submatch_data));\n      if (submatch_data == NULL)\n\tERROR_EXIT(REG_ESPACE);\n      tnfa->submatch_data = submatch_data;\n\n      errcode = tre_add_tags(mem, stack, tree, tnfa);\n      if (errcode != REG_OK)\n\tERROR_EXIT(errcode);\n\n    }\n\n  /* Expand iteration nodes. */\n  errcode = tre_expand_ast(mem, stack, tree, &parse_ctx.position,\n\t\t\t   tag_directions);\n  if (errcode != REG_OK)\n    ERROR_EXIT(errcode);\n\n  /* Add a dummy node for the final state.\n     XXX - For certain patterns this dummy node can be optimized away,\n\t   for example \"a*\" or \"ab*\".\tFigure out a simple way to detect\n\t   this possibility. */\n  tmp_ast_l = tree;\n  tmp_ast_r = tre_ast_new_literal(mem, 0, 0, parse_ctx.position++);\n  if (tmp_ast_r == NULL)\n    ERROR_EXIT(REG_ESPACE);\n\n  tree = tre_ast_new_catenation(mem, tmp_ast_l, tmp_ast_r);\n  if (tree == NULL)\n    ERROR_EXIT(REG_ESPACE);\n\n  errcode = tre_compute_nfl(mem, stack, tree);\n  if (errcode != REG_OK)\n    ERROR_EXIT(errcode);\n\n  counts = xmalloc(sizeof(int) * parse_ctx.position);\n  if (counts == NULL)\n    ERROR_EXIT(REG_ESPACE);\n\n  offs = xmalloc(sizeof(int) * parse_ctx.position);\n  if (offs == NULL)\n    ERROR_EXIT(REG_ESPACE);\n\n  for (i = 0; i < parse_ctx.position; i++)\n    counts[i] = 0;\n  tre_ast_to_tnfa(tree, NULL, counts, NULL);\n\n  add = 0;\n  for (i = 0; i < parse_ctx.position; i++)\n    {\n      offs[i] = add;\n      add += counts[i] + 1;\n      counts[i] = 0;\n    }\n  transitions = xcalloc((unsigned)add + 1, sizeof(*transitions));\n  if (transitions == NULL)\n    ERROR_EXIT(REG_ESPACE);\n  tnfa->transitions = transitions;\n  tnfa->num_transitions = add;\n\n  errcode = tre_ast_to_tnfa(tree, transitions, counts, offs);\n  if (errcode != REG_OK)\n    ERROR_EXIT(errcode);\n\n  tnfa->firstpos_chars = NULL;\n\n  p = tree->firstpos;\n  i = 0;\n  while (p->position >= 0)\n    {\n      i++;\n      p++;\n    }\n\n  initial = xcalloc((unsigned)i + 1, sizeof(tre_tnfa_transition_t));\n  if (initial == NULL)\n    ERROR_EXIT(REG_ESPACE);\n  tnfa->initial = initial;\n\n  i = 0;\n  for (p = tree->firstpos; p->position >= 0; p++)\n    {\n      initial[i].state = transitions + offs[p->position];\n      initial[i].state_id = p->position;\n      initial[i].tags = NULL;\n      /* Copy the arrays p->tags, and p->params, they are allocated\n\t from a tre_mem object. */\n      if (p->tags)\n\t{\n\t  int j;\n\t  for (j = 0; p->tags[j] >= 0; j++);\n\t  initial[i].tags = xmalloc(sizeof(*p->tags) * (j + 1));\n\t  if (!initial[i].tags)\n\t    ERROR_EXIT(REG_ESPACE);\n\t  memcpy(initial[i].tags, p->tags, sizeof(*p->tags) * (j + 1));\n\t}\n      initial[i].assertions = p->assertions;\n      i++;\n    }\n  initial[i].state = NULL;\n\n  tnfa->num_transitions = add;\n  tnfa->final = transitions + offs[tree->lastpos[0].position];\n  tnfa->num_states = parse_ctx.position;\n  tnfa->cflags = cflags;\n\n  tre_mem_destroy(mem);\n  tre_stack_destroy(stack);\n  xfree(counts);\n  xfree(offs);\n\n  preg->TRE_REGEX_T_FIELD = (void *)tnfa;\n  return REG_OK;\n\n error_exit:\n  /* Free everything that was allocated and return the error code. */\n  tre_mem_destroy(mem);\n  if (stack != NULL)\n    tre_stack_destroy(stack);\n  if (counts != NULL)\n    xfree(counts);\n  if (offs != NULL)\n    xfree(offs);\n  preg->TRE_REGEX_T_FIELD = (void *)tnfa;\n  regfree(preg);\n  return errcode;\n}\n\n\n\n\nvoid\nregfree(regex_t *preg)\n{\n  tre_tnfa_t *tnfa;\n  unsigned int i;\n  tre_tnfa_transition_t *trans;\n\n  tnfa = (void *)preg->TRE_REGEX_T_FIELD;\n  if (!tnfa)\n    return;\n\n  for (i = 0; i < tnfa->num_transitions; i++)\n    if (tnfa->transitions[i].state)\n      {\n\tif (tnfa->transitions[i].tags)\n\t  xfree(tnfa->transitions[i].tags);\n\tif (tnfa->transitions[i].neg_classes)\n\t  xfree(tnfa->transitions[i].neg_classes);\n      }\n  if (tnfa->transitions)\n    xfree(tnfa->transitions);\n\n  if (tnfa->initial)\n    {\n      for (trans = tnfa->initial; trans->state; trans++)\n\t{\n\t  if (trans->tags)\n\t    xfree(trans->tags);\n\t}\n      xfree(tnfa->initial);\n    }\n\n  if (tnfa->submatch_data)\n    {\n      for (i = 0; i < tnfa->num_submatches; i++)\n\tif (tnfa->submatch_data[i].parents)\n\t  xfree(tnfa->submatch_data[i].parents);\n      xfree(tnfa->submatch_data);\n    }\n\n  if (tnfa->tag_directions)\n    xfree(tnfa->tag_directions);\n  if (tnfa->firstpos_chars)\n    xfree(tnfa->firstpos_chars);\n  if (tnfa->minimal_tags)\n    xfree(tnfa->minimal_tags);\n  xfree(tnfa);\n}\n"
  },
  {
    "path": "user.libc/src/regex/regerror.c",
    "content": "#include <string.h>\n#include <regex.h>\n#include <stdio.h>\n#include \"locale_impl.h\"\n\n/* Error message strings for error codes listed in `regex.h'.  This list\n   needs to be in sync with the codes listed there, naturally. */\n\n/* Converted to single string by Rich Felker to remove the need for\n * data relocations at runtime, 27 Feb 2006. */\n\nstatic const char messages[] = {\n  \"No error\\0\"\n  \"No match\\0\"\n  \"Invalid regexp\\0\"\n  \"Unknown collating element\\0\"\n  \"Unknown character class name\\0\"\n  \"Trailing backslash\\0\"\n  \"Invalid back reference\\0\"\n  \"Missing ']'\\0\"\n  \"Missing ')'\\0\"\n  \"Missing '}'\\0\"\n  \"Invalid contents of {}\\0\"\n  \"Invalid character range\\0\"\n  \"Out of memory\\0\"\n  \"Repetition not preceded by valid expression\\0\"\n  \"\\0Unknown error\"\n};\n\nsize_t regerror(int e, const regex_t *restrict preg, char *restrict buf, size_t size)\n{\n\tconst char *s;\n\tfor (s=messages; e && *s; e--, s+=strlen(s)+1);\n\tif (!*s) s++;\n\ts = LCTRANS_CUR(s);\n\treturn 1+snprintf(buf, size, \"%s\", s);\n}\n"
  },
  {
    "path": "user.libc/src/regex/regexec.c",
    "content": "/*\n  regexec.c - TRE POSIX compatible matching functions (and more).\n\n  Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>\n  All rights reserved.\n\n  Redistribution and use in source and binary forms, with or without\n  modification, are permitted provided that the following conditions\n  are met:\n\n    1. Redistributions of source code must retain the above copyright\n       notice, this list of conditions and the following disclaimer.\n\n    2. Redistributions in binary form must reproduce the above copyright\n       notice, this list of conditions and the following disclaimer in the\n       documentation and/or other materials provided with the distribution.\n\n  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS\n  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT\n  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n*/\n\n#include <stdlib.h>\n#include <string.h>\n#include <wchar.h>\n#include <wctype.h>\n#include <limits.h>\n#include <stdint.h>\n\n#include <regex.h>\n\n#include \"tre.h\"\n\n#include <assert.h>\n\nstatic void\ntre_fill_pmatch(size_t nmatch, regmatch_t pmatch[], int cflags,\n\t\tconst tre_tnfa_t *tnfa, regoff_t *tags, regoff_t match_eo);\n\n/***********************************************************************\n from tre-match-utils.h\n***********************************************************************/\n\n#define GET_NEXT_WCHAR() do {                                                 \\\n    prev_c = next_c; pos += pos_add_next;                                     \\\n    if ((pos_add_next = mbtowc(&next_c, str_byte, MB_LEN_MAX)) <= 0) {        \\\n        if (pos_add_next < 0) { ret = REG_NOMATCH; goto error_exit; }         \\\n        else pos_add_next++;                                                  \\\n    }                                                                         \\\n    str_byte += pos_add_next;                                                 \\\n  } while (0)\n\n#define IS_WORD_CHAR(c)\t ((c) == L'_' || tre_isalnum(c))\n\n#define CHECK_ASSERTIONS(assertions)\t\t\t\t\t      \\\n  (((assertions & ASSERT_AT_BOL)\t\t\t\t\t      \\\n    && (pos > 0 || reg_notbol)\t\t\t\t\t\t      \\\n    && (prev_c != L'\\n' || !reg_newline))\t\t\t\t      \\\n   || ((assertions & ASSERT_AT_EOL)\t\t\t\t\t      \\\n       && (next_c != L'\\0' || reg_noteol)\t\t\t\t      \\\n       && (next_c != L'\\n' || !reg_newline))\t\t\t\t      \\\n   || ((assertions & ASSERT_AT_BOW)\t\t\t\t\t      \\\n       && (IS_WORD_CHAR(prev_c) || !IS_WORD_CHAR(next_c)))\t              \\\n   || ((assertions & ASSERT_AT_EOW)\t\t\t\t\t      \\\n       && (!IS_WORD_CHAR(prev_c) || IS_WORD_CHAR(next_c)))\t\t      \\\n   || ((assertions & ASSERT_AT_WB)\t\t\t\t\t      \\\n       && (pos != 0 && next_c != L'\\0'\t\t\t\t\t      \\\n\t   && IS_WORD_CHAR(prev_c) == IS_WORD_CHAR(next_c)))\t\t      \\\n   || ((assertions & ASSERT_AT_WB_NEG)\t\t\t\t\t      \\\n       && (pos == 0 || next_c == L'\\0'\t\t\t\t\t      \\\n\t   || IS_WORD_CHAR(prev_c) != IS_WORD_CHAR(next_c))))\n\n#define CHECK_CHAR_CLASSES(trans_i, tnfa, eflags)                             \\\n  (((trans_i->assertions & ASSERT_CHAR_CLASS)                                 \\\n       && !(tnfa->cflags & REG_ICASE)                                         \\\n       && !tre_isctype((tre_cint_t)prev_c, trans_i->u.class))                 \\\n    || ((trans_i->assertions & ASSERT_CHAR_CLASS)                             \\\n        && (tnfa->cflags & REG_ICASE)                                         \\\n        && !tre_isctype(tre_tolower((tre_cint_t)prev_c),trans_i->u.class)     \\\n\t&& !tre_isctype(tre_toupper((tre_cint_t)prev_c),trans_i->u.class))    \\\n    || ((trans_i->assertions & ASSERT_CHAR_CLASS_NEG)                         \\\n        && tre_neg_char_classes_match(trans_i->neg_classes,(tre_cint_t)prev_c,\\\n                                      tnfa->cflags & REG_ICASE)))\n\n\n\n\n/* Returns 1 if `t1' wins `t2', 0 otherwise. */\nstatic int\ntre_tag_order(int num_tags, tre_tag_direction_t *tag_directions,\n\t      regoff_t *t1, regoff_t *t2)\n{\n  int i;\n  for (i = 0; i < num_tags; i++)\n    {\n      if (tag_directions[i] == TRE_TAG_MINIMIZE)\n\t{\n\t  if (t1[i] < t2[i])\n\t    return 1;\n\t  if (t1[i] > t2[i])\n\t    return 0;\n\t}\n      else\n\t{\n\t  if (t1[i] > t2[i])\n\t    return 1;\n\t  if (t1[i] < t2[i])\n\t    return 0;\n\t}\n    }\n  /*  assert(0);*/\n  return 0;\n}\n\nstatic int\ntre_neg_char_classes_match(tre_ctype_t *classes, tre_cint_t wc, int icase)\n{\n  while (*classes != (tre_ctype_t)0)\n    if ((!icase && tre_isctype(wc, *classes))\n\t|| (icase && (tre_isctype(tre_toupper(wc), *classes)\n\t\t      || tre_isctype(tre_tolower(wc), *classes))))\n      return 1; /* Match. */\n    else\n      classes++;\n  return 0; /* No match. */\n}\n\n\n/***********************************************************************\n from tre-match-parallel.c\n***********************************************************************/\n\n/*\n  This algorithm searches for matches basically by reading characters\n  in the searched string one by one, starting at the beginning.\t All\n  matching paths in the TNFA are traversed in parallel.\t When two or\n  more paths reach the same state, exactly one is chosen according to\n  tag ordering rules; if returning submatches is not required it does\n  not matter which path is chosen.\n\n  The worst case time required for finding the leftmost and longest\n  match, or determining that there is no match, is always linearly\n  dependent on the length of the text being searched.\n\n  This algorithm cannot handle TNFAs with back referencing nodes.\n  See `tre-match-backtrack.c'.\n*/\n\ntypedef struct {\n  tre_tnfa_transition_t *state;\n  regoff_t *tags;\n} tre_tnfa_reach_t;\n\ntypedef struct {\n  regoff_t pos;\n  regoff_t **tags;\n} tre_reach_pos_t;\n\n\nstatic reg_errcode_t\ntre_tnfa_run_parallel(const tre_tnfa_t *tnfa, const void *string,\n\t\t      regoff_t *match_tags, int eflags,\n\t\t      regoff_t *match_end_ofs)\n{\n  /* State variables required by GET_NEXT_WCHAR. */\n  tre_char_t prev_c = 0, next_c = 0;\n  const char *str_byte = string;\n  regoff_t pos = -1;\n  regoff_t pos_add_next = 1;\n#ifdef TRE_MBSTATE\n  mbstate_t mbstate;\n#endif /* TRE_MBSTATE */\n  int reg_notbol = eflags & REG_NOTBOL;\n  int reg_noteol = eflags & REG_NOTEOL;\n  int reg_newline = tnfa->cflags & REG_NEWLINE;\n  reg_errcode_t ret;\n\n  char *buf;\n  tre_tnfa_transition_t *trans_i;\n  tre_tnfa_reach_t *reach, *reach_next, *reach_i, *reach_next_i;\n  tre_reach_pos_t *reach_pos;\n  int *tag_i;\n  int num_tags, i;\n\n  regoff_t match_eo = -1;\t   /* end offset of match (-1 if no match found yet) */\n  int new_match = 0;\n  regoff_t *tmp_tags = NULL;\n  regoff_t *tmp_iptr;\n\n#ifdef TRE_MBSTATE\n  memset(&mbstate, '\\0', sizeof(mbstate));\n#endif /* TRE_MBSTATE */\n\n  if (!match_tags)\n    num_tags = 0;\n  else\n    num_tags = tnfa->num_tags;\n\n  /* Allocate memory for temporary data required for matching.\tThis needs to\n     be done for every matching operation to be thread safe.  This allocates\n     everything in a single large block with calloc(). */\n  {\n    size_t tbytes, rbytes, pbytes, xbytes, total_bytes;\n    char *tmp_buf;\n\n    /* Ensure that tbytes and xbytes*num_states cannot overflow, and that\n     * they don't contribute more than 1/8 of SIZE_MAX to total_bytes. */\n    if (num_tags > SIZE_MAX/(8 * sizeof(regoff_t) * tnfa->num_states))\n      return REG_ESPACE;\n\n    /* Likewise check rbytes. */\n    if (tnfa->num_states+1 > SIZE_MAX/(8 * sizeof(*reach_next)))\n      return REG_ESPACE;\n\n    /* Likewise check pbytes. */\n    if (tnfa->num_states > SIZE_MAX/(8 * sizeof(*reach_pos)))\n      return REG_ESPACE;\n\n    /* Compute the length of the block we need. */\n    tbytes = sizeof(*tmp_tags) * num_tags;\n    rbytes = sizeof(*reach_next) * (tnfa->num_states + 1);\n    pbytes = sizeof(*reach_pos) * tnfa->num_states;\n    xbytes = sizeof(regoff_t) * num_tags;\n    total_bytes =\n      (sizeof(long) - 1) * 4 /* for alignment paddings */\n      + (rbytes + xbytes * tnfa->num_states) * 2 + tbytes + pbytes;\n\n    /* Allocate the memory. */\n    buf = calloc(total_bytes, 1);\n    if (buf == NULL)\n      return REG_ESPACE;\n\n    /* Get the various pointers within tmp_buf (properly aligned). */\n    tmp_tags = (void *)buf;\n    tmp_buf = buf + tbytes;\n    tmp_buf += ALIGN(tmp_buf, long);\n    reach_next = (void *)tmp_buf;\n    tmp_buf += rbytes;\n    tmp_buf += ALIGN(tmp_buf, long);\n    reach = (void *)tmp_buf;\n    tmp_buf += rbytes;\n    tmp_buf += ALIGN(tmp_buf, long);\n    reach_pos = (void *)tmp_buf;\n    tmp_buf += pbytes;\n    tmp_buf += ALIGN(tmp_buf, long);\n    for (i = 0; i < tnfa->num_states; i++)\n      {\n\treach[i].tags = (void *)tmp_buf;\n\ttmp_buf += xbytes;\n\treach_next[i].tags = (void *)tmp_buf;\n\ttmp_buf += xbytes;\n      }\n  }\n\n  for (i = 0; i < tnfa->num_states; i++)\n    reach_pos[i].pos = -1;\n\n  GET_NEXT_WCHAR();\n  pos = 0;\n\n  reach_next_i = reach_next;\n  while (1)\n    {\n      /* If no match found yet, add the initial states to `reach_next'. */\n      if (match_eo < 0)\n\t{\n\t  trans_i = tnfa->initial;\n\t  while (trans_i->state != NULL)\n\t    {\n\t      if (reach_pos[trans_i->state_id].pos < pos)\n\t\t{\n\t\t  if (trans_i->assertions\n\t\t      && CHECK_ASSERTIONS(trans_i->assertions))\n\t\t    {\n\t\t      trans_i++;\n\t\t      continue;\n\t\t    }\n\n\t\t  reach_next_i->state = trans_i->state;\n\t\t  for (i = 0; i < num_tags; i++)\n\t\t    reach_next_i->tags[i] = -1;\n\t\t  tag_i = trans_i->tags;\n\t\t  if (tag_i)\n\t\t    while (*tag_i >= 0)\n\t\t      {\n\t\t\tif (*tag_i < num_tags)\n\t\t\t  reach_next_i->tags[*tag_i] = pos;\n\t\t\ttag_i++;\n\t\t      }\n\t\t  if (reach_next_i->state == tnfa->final)\n\t\t    {\n\t\t      match_eo = pos;\n\t\t      new_match = 1;\n\t\t      for (i = 0; i < num_tags; i++)\n\t\t\tmatch_tags[i] = reach_next_i->tags[i];\n\t\t    }\n\t\t  reach_pos[trans_i->state_id].pos = pos;\n\t\t  reach_pos[trans_i->state_id].tags = &reach_next_i->tags;\n\t\t  reach_next_i++;\n\t\t}\n\t      trans_i++;\n\t    }\n\t  reach_next_i->state = NULL;\n\t}\n      else\n\t{\n\t  if (num_tags == 0 || reach_next_i == reach_next)\n\t    /* We have found a match. */\n\t    break;\n\t}\n\n      /* Check for end of string. */\n      if (!next_c) break;\n\n      GET_NEXT_WCHAR();\n\n      /* Swap `reach' and `reach_next'. */\n      reach_i = reach;\n      reach = reach_next;\n      reach_next = reach_i;\n\n      /* For each state in `reach', weed out states that don't fulfill the\n\t minimal matching conditions. */\n      if (tnfa->num_minimals && new_match)\n\t{\n\t  new_match = 0;\n\t  reach_next_i = reach_next;\n\t  for (reach_i = reach; reach_i->state; reach_i++)\n\t    {\n\t      int skip = 0;\n\t      for (i = 0; tnfa->minimal_tags[i] >= 0; i += 2)\n\t\t{\n\t\t  int end = tnfa->minimal_tags[i];\n\t\t  int start = tnfa->minimal_tags[i + 1];\n\t\t  if (end >= num_tags)\n\t\t    {\n\t\t      skip = 1;\n\t\t      break;\n\t\t    }\n\t\t  else if (reach_i->tags[start] == match_tags[start]\n\t\t\t   && reach_i->tags[end] < match_tags[end])\n\t\t    {\n\t\t      skip = 1;\n\t\t      break;\n\t\t    }\n\t\t}\n\t      if (!skip)\n\t\t{\n\t\t  reach_next_i->state = reach_i->state;\n\t\t  tmp_iptr = reach_next_i->tags;\n\t\t  reach_next_i->tags = reach_i->tags;\n\t\t  reach_i->tags = tmp_iptr;\n\t\t  reach_next_i++;\n\t\t}\n\t    }\n\t  reach_next_i->state = NULL;\n\n\t  /* Swap `reach' and `reach_next'. */\n\t  reach_i = reach;\n\t  reach = reach_next;\n\t  reach_next = reach_i;\n\t}\n\n      /* For each state in `reach' see if there is a transition leaving with\n\t the current input symbol to a state not yet in `reach_next', and\n\t add the destination states to `reach_next'. */\n      reach_next_i = reach_next;\n      for (reach_i = reach; reach_i->state; reach_i++)\n\t{\n\t  for (trans_i = reach_i->state; trans_i->state; trans_i++)\n\t    {\n\t      /* Does this transition match the input symbol? */\n\t      if (trans_i->code_min <= (tre_cint_t)prev_c &&\n\t\t  trans_i->code_max >= (tre_cint_t)prev_c)\n\t\t{\n\t\t  if (trans_i->assertions\n\t\t      && (CHECK_ASSERTIONS(trans_i->assertions)\n\t\t\t  || CHECK_CHAR_CLASSES(trans_i, tnfa, eflags)))\n\t\t    {\n\t\t      continue;\n\t\t    }\n\n\t\t  /* Compute the tags after this transition. */\n\t\t  for (i = 0; i < num_tags; i++)\n\t\t    tmp_tags[i] = reach_i->tags[i];\n\t\t  tag_i = trans_i->tags;\n\t\t  if (tag_i != NULL)\n\t\t    while (*tag_i >= 0)\n\t\t      {\n\t\t\tif (*tag_i < num_tags)\n\t\t\t  tmp_tags[*tag_i] = pos;\n\t\t\ttag_i++;\n\t\t      }\n\n\t\t  if (reach_pos[trans_i->state_id].pos < pos)\n\t\t    {\n\t\t      /* Found an unvisited node. */\n\t\t      reach_next_i->state = trans_i->state;\n\t\t      tmp_iptr = reach_next_i->tags;\n\t\t      reach_next_i->tags = tmp_tags;\n\t\t      tmp_tags = tmp_iptr;\n\t\t      reach_pos[trans_i->state_id].pos = pos;\n\t\t      reach_pos[trans_i->state_id].tags = &reach_next_i->tags;\n\n\t\t      if (reach_next_i->state == tnfa->final\n\t\t\t  && (match_eo == -1\n\t\t\t      || (num_tags > 0\n\t\t\t\t  && reach_next_i->tags[0] <= match_tags[0])))\n\t\t\t{\n\t\t\t  match_eo = pos;\n\t\t\t  new_match = 1;\n\t\t\t  for (i = 0; i < num_tags; i++)\n\t\t\t    match_tags[i] = reach_next_i->tags[i];\n\t\t\t}\n\t\t      reach_next_i++;\n\n\t\t    }\n\t\t  else\n\t\t    {\n\t\t      assert(reach_pos[trans_i->state_id].pos == pos);\n\t\t      /* Another path has also reached this state.  We choose\n\t\t\t the winner by examining the tag values for both\n\t\t\t paths. */\n\t\t      if (tre_tag_order(num_tags, tnfa->tag_directions,\n\t\t\t\t\ttmp_tags,\n\t\t\t\t\t*reach_pos[trans_i->state_id].tags))\n\t\t\t{\n\t\t\t  /* The new path wins. */\n\t\t\t  tmp_iptr = *reach_pos[trans_i->state_id].tags;\n\t\t\t  *reach_pos[trans_i->state_id].tags = tmp_tags;\n\t\t\t  if (trans_i->state == tnfa->final)\n\t\t\t    {\n\t\t\t      match_eo = pos;\n\t\t\t      new_match = 1;\n\t\t\t      for (i = 0; i < num_tags; i++)\n\t\t\t\tmatch_tags[i] = tmp_tags[i];\n\t\t\t    }\n\t\t\t  tmp_tags = tmp_iptr;\n\t\t\t}\n\t\t    }\n\t\t}\n\t    }\n\t}\n      reach_next_i->state = NULL;\n    }\n\n  *match_end_ofs = match_eo;\n  ret = match_eo >= 0 ? REG_OK : REG_NOMATCH;\nerror_exit:\n  xfree(buf);\n  return ret;\n}\n\n\n\n/***********************************************************************\n from tre-match-backtrack.c\n***********************************************************************/\n\n/*\n  This matcher is for regexps that use back referencing.  Regexp matching\n  with back referencing is an NP-complete problem on the number of back\n  references.  The easiest way to match them is to use a backtracking\n  routine which basically goes through all possible paths in the TNFA\n  and chooses the one which results in the best (leftmost and longest)\n  match.  This can be spectacularly expensive and may run out of stack\n  space, but there really is no better known generic algorithm.\t Quoting\n  Henry Spencer from comp.compilers:\n  <URL: http://compilers.iecc.com/comparch/article/93-03-102>\n\n    POSIX.2 REs require longest match, which is really exciting to\n    implement since the obsolete (\"basic\") variant also includes\n    \\<digit>.  I haven't found a better way of tackling this than doing\n    a preliminary match using a DFA (or simulation) on a modified RE\n    that just replicates subREs for \\<digit>, and then doing a\n    backtracking match to determine whether the subRE matches were\n    right.  This can be rather slow, but I console myself with the\n    thought that people who use \\<digit> deserve very slow execution.\n    (Pun unintentional but very appropriate.)\n\n*/\n\ntypedef struct {\n  regoff_t pos;\n  const char *str_byte;\n  tre_tnfa_transition_t *state;\n  int state_id;\n  int next_c;\n  regoff_t *tags;\n#ifdef TRE_MBSTATE\n  mbstate_t mbstate;\n#endif /* TRE_MBSTATE */\n} tre_backtrack_item_t;\n\ntypedef struct tre_backtrack_struct {\n  tre_backtrack_item_t item;\n  struct tre_backtrack_struct *prev;\n  struct tre_backtrack_struct *next;\n} *tre_backtrack_t;\n\n#ifdef TRE_MBSTATE\n#define BT_STACK_MBSTATE_IN  stack->item.mbstate = (mbstate)\n#define BT_STACK_MBSTATE_OUT (mbstate) = stack->item.mbstate\n#else /* !TRE_MBSTATE */\n#define BT_STACK_MBSTATE_IN\n#define BT_STACK_MBSTATE_OUT\n#endif /* !TRE_MBSTATE */\n\n#define tre_bt_mem_new\t\t  tre_mem_new\n#define tre_bt_mem_alloc\t  tre_mem_alloc\n#define tre_bt_mem_destroy\t  tre_mem_destroy\n\n\n#define BT_STACK_PUSH(_pos, _str_byte, _str_wide, _state, _state_id, _next_c, _tags, _mbstate) \\\n  do\t\t\t\t\t\t\t\t\t      \\\n    {\t\t\t\t\t\t\t\t\t      \\\n      int i;\t\t\t\t\t\t\t\t      \\\n      if (!stack->next)\t\t\t\t\t\t\t      \\\n\t{\t\t\t\t\t\t\t\t      \\\n\t  tre_backtrack_t s;\t\t\t\t\t\t      \\\n\t  s = tre_bt_mem_alloc(mem, sizeof(*s));\t\t\t      \\\n\t  if (!s)\t\t\t\t\t\t\t      \\\n\t    {\t\t\t\t\t\t\t\t      \\\n\t      tre_bt_mem_destroy(mem);\t\t\t\t\t      \\\n\t      if (tags)\t\t\t\t\t\t\t      \\\n\t\txfree(tags);\t\t\t\t\t\t      \\\n\t      if (pmatch)\t\t\t\t\t\t      \\\n\t\txfree(pmatch);\t\t\t\t\t\t      \\\n\t      if (states_seen)\t\t\t\t\t\t      \\\n\t\txfree(states_seen);\t\t\t\t\t      \\\n\t      return REG_ESPACE;\t\t\t\t\t      \\\n\t    }\t\t\t\t\t\t\t\t      \\\n\t  s->prev = stack;\t\t\t\t\t\t      \\\n\t  s->next = NULL;\t\t\t\t\t\t      \\\n\t  s->item.tags = tre_bt_mem_alloc(mem,\t\t\t\t      \\\n\t\t\t\t\t  sizeof(*tags) * tnfa->num_tags);    \\\n\t  if (!s->item.tags)\t\t\t\t\t\t      \\\n\t    {\t\t\t\t\t\t\t\t      \\\n\t      tre_bt_mem_destroy(mem);\t\t\t\t\t      \\\n\t      if (tags)\t\t\t\t\t\t\t      \\\n\t\txfree(tags);\t\t\t\t\t\t      \\\n\t      if (pmatch)\t\t\t\t\t\t      \\\n\t\txfree(pmatch);\t\t\t\t\t\t      \\\n\t      if (states_seen)\t\t\t\t\t\t      \\\n\t\txfree(states_seen);\t\t\t\t\t      \\\n\t      return REG_ESPACE;\t\t\t\t\t      \\\n\t    }\t\t\t\t\t\t\t\t      \\\n\t  stack->next = s;\t\t\t\t\t\t      \\\n\t  stack = s;\t\t\t\t\t\t\t      \\\n\t}\t\t\t\t\t\t\t\t      \\\n      else\t\t\t\t\t\t\t\t      \\\n\tstack = stack->next;\t\t\t\t\t\t      \\\n      stack->item.pos = (_pos);\t\t\t\t\t\t      \\\n      stack->item.str_byte = (_str_byte);\t\t\t\t      \\\n      stack->item.state = (_state);\t\t\t\t\t      \\\n      stack->item.state_id = (_state_id);\t\t\t\t      \\\n      stack->item.next_c = (_next_c);\t\t\t\t\t      \\\n      for (i = 0; i < tnfa->num_tags; i++)\t\t\t\t      \\\n\tstack->item.tags[i] = (_tags)[i];\t\t\t\t      \\\n      BT_STACK_MBSTATE_IN;\t\t\t\t\t\t      \\\n    }\t\t\t\t\t\t\t\t\t      \\\n  while (0)\n\n#define BT_STACK_POP()\t\t\t\t\t\t\t      \\\n  do\t\t\t\t\t\t\t\t\t      \\\n    {\t\t\t\t\t\t\t\t\t      \\\n      int i;\t\t\t\t\t\t\t\t      \\\n      assert(stack->prev);\t\t\t\t\t\t      \\\n      pos = stack->item.pos;\t\t\t\t\t\t      \\\n      str_byte = stack->item.str_byte;\t\t\t\t\t      \\\n      state = stack->item.state;\t\t\t\t\t      \\\n      next_c = stack->item.next_c;\t\t\t\t\t      \\\n      for (i = 0; i < tnfa->num_tags; i++)\t\t\t\t      \\\n\ttags[i] = stack->item.tags[i];\t\t\t\t\t      \\\n      BT_STACK_MBSTATE_OUT;\t\t\t\t\t\t      \\\n      stack = stack->prev;\t\t\t\t\t\t      \\\n    }\t\t\t\t\t\t\t\t\t      \\\n  while (0)\n\n#undef MIN\n#define MIN(a, b) ((a) <= (b) ? (a) : (b))\n\nstatic reg_errcode_t\ntre_tnfa_run_backtrack(const tre_tnfa_t *tnfa, const void *string,\n\t\t       regoff_t *match_tags, int eflags, regoff_t *match_end_ofs)\n{\n  /* State variables required by GET_NEXT_WCHAR. */\n  tre_char_t prev_c = 0, next_c = 0;\n  const char *str_byte = string;\n  regoff_t pos = 0;\n  regoff_t pos_add_next = 1;\n#ifdef TRE_MBSTATE\n  mbstate_t mbstate;\n#endif /* TRE_MBSTATE */\n  int reg_notbol = eflags & REG_NOTBOL;\n  int reg_noteol = eflags & REG_NOTEOL;\n  int reg_newline = tnfa->cflags & REG_NEWLINE;\n\n  /* These are used to remember the necessary values of the above\n     variables to return to the position where the current search\n     started from. */\n  int next_c_start;\n  const char *str_byte_start;\n  regoff_t pos_start = -1;\n#ifdef TRE_MBSTATE\n  mbstate_t mbstate_start;\n#endif /* TRE_MBSTATE */\n\n  /* End offset of best match so far, or -1 if no match found yet. */\n  regoff_t match_eo = -1;\n  /* Tag arrays. */\n  int *next_tags;\n  regoff_t *tags = NULL;\n  /* Current TNFA state. */\n  tre_tnfa_transition_t *state;\n  int *states_seen = NULL;\n\n  /* Memory allocator to for allocating the backtracking stack. */\n  tre_mem_t mem = tre_bt_mem_new();\n\n  /* The backtracking stack. */\n  tre_backtrack_t stack;\n\n  tre_tnfa_transition_t *trans_i;\n  regmatch_t *pmatch = NULL;\n  int ret;\n\n#ifdef TRE_MBSTATE\n  memset(&mbstate, '\\0', sizeof(mbstate));\n#endif /* TRE_MBSTATE */\n\n  if (!mem)\n    return REG_ESPACE;\n  stack = tre_bt_mem_alloc(mem, sizeof(*stack));\n  if (!stack)\n    {\n      ret = REG_ESPACE;\n      goto error_exit;\n    }\n  stack->prev = NULL;\n  stack->next = NULL;\n\n  if (tnfa->num_tags)\n    {\n      tags = xmalloc(sizeof(*tags) * tnfa->num_tags);\n      if (!tags)\n\t{\n\t  ret = REG_ESPACE;\n\t  goto error_exit;\n\t}\n    }\n  if (tnfa->num_submatches)\n    {\n      pmatch = xmalloc(sizeof(*pmatch) * tnfa->num_submatches);\n      if (!pmatch)\n\t{\n\t  ret = REG_ESPACE;\n\t  goto error_exit;\n\t}\n    }\n  if (tnfa->num_states)\n    {\n      states_seen = xmalloc(sizeof(*states_seen) * tnfa->num_states);\n      if (!states_seen)\n\t{\n\t  ret = REG_ESPACE;\n\t  goto error_exit;\n\t}\n    }\n\n retry:\n  {\n    int i;\n    for (i = 0; i < tnfa->num_tags; i++)\n      {\n\ttags[i] = -1;\n\tif (match_tags)\n\t  match_tags[i] = -1;\n      }\n    for (i = 0; i < tnfa->num_states; i++)\n      states_seen[i] = 0;\n  }\n\n  state = NULL;\n  pos = pos_start;\n  GET_NEXT_WCHAR();\n  pos_start = pos;\n  next_c_start = next_c;\n  str_byte_start = str_byte;\n#ifdef TRE_MBSTATE\n  mbstate_start = mbstate;\n#endif /* TRE_MBSTATE */\n\n  /* Handle initial states. */\n  next_tags = NULL;\n  for (trans_i = tnfa->initial; trans_i->state; trans_i++)\n    {\n      if (trans_i->assertions && CHECK_ASSERTIONS(trans_i->assertions))\n\t{\n\t  continue;\n\t}\n      if (state == NULL)\n\t{\n\t  /* Start from this state. */\n\t  state = trans_i->state;\n\t  next_tags = trans_i->tags;\n\t}\n      else\n\t{\n\t  /* Backtrack to this state. */\n\t  BT_STACK_PUSH(pos, str_byte, 0, trans_i->state,\n\t\t\ttrans_i->state_id, next_c, tags, mbstate);\n\t  {\n\t    int *tmp = trans_i->tags;\n\t    if (tmp)\n\t      while (*tmp >= 0)\n\t\tstack->item.tags[*tmp++] = pos;\n\t  }\n\t}\n    }\n\n  if (next_tags)\n    for (; *next_tags >= 0; next_tags++)\n      tags[*next_tags] = pos;\n\n\n  if (state == NULL)\n    goto backtrack;\n\n  while (1)\n    {\n      tre_tnfa_transition_t *next_state;\n      int empty_br_match;\n\n      if (state == tnfa->final)\n\t{\n\t  if (match_eo < pos\n\t      || (match_eo == pos\n\t\t  && match_tags\n\t\t  && tre_tag_order(tnfa->num_tags, tnfa->tag_directions,\n\t\t\t\t   tags, match_tags)))\n\t    {\n\t      int i;\n\t      /* This match wins the previous match. */\n\t      match_eo = pos;\n\t      if (match_tags)\n\t\tfor (i = 0; i < tnfa->num_tags; i++)\n\t\t  match_tags[i] = tags[i];\n\t    }\n\t  /* Our TNFAs never have transitions leaving from the final state,\n\t     so we jump right to backtracking. */\n\t  goto backtrack;\n\t}\n\n      /* Go to the next character in the input string. */\n      empty_br_match = 0;\n      trans_i = state;\n      if (trans_i->state && trans_i->assertions & ASSERT_BACKREF)\n\t{\n\t  /* This is a back reference state.  All transitions leaving from\n\t     this state have the same back reference \"assertion\".  Instead\n\t     of reading the next character, we match the back reference. */\n\t  regoff_t so, eo;\n\t  int bt = trans_i->u.backref;\n\t  regoff_t bt_len;\n\t  int result;\n\n\t  /* Get the substring we need to match against.  Remember to\n\t     turn off REG_NOSUB temporarily. */\n\t  tre_fill_pmatch(bt + 1, pmatch, tnfa->cflags & ~REG_NOSUB,\n\t\t\t  tnfa, tags, pos);\n\t  so = pmatch[bt].rm_so;\n\t  eo = pmatch[bt].rm_eo;\n\t  bt_len = eo - so;\n\n\t  result = strncmp((const char*)string + so, str_byte - 1,\n\t\t\t\t (size_t)bt_len);\n\n\t  if (result == 0)\n\t    {\n\t      /* Back reference matched.  Check for infinite loop. */\n\t      if (bt_len == 0)\n\t\tempty_br_match = 1;\n\t      if (empty_br_match && states_seen[trans_i->state_id])\n\t\t{\n\t\t  goto backtrack;\n\t\t}\n\n\t      states_seen[trans_i->state_id] = empty_br_match;\n\n\t      /* Advance in input string and resync `prev_c', `next_c'\n\t\t and pos. */\n\t      str_byte += bt_len - 1;\n\t      pos += bt_len - 1;\n\t      GET_NEXT_WCHAR();\n\t    }\n\t  else\n\t    {\n\t      goto backtrack;\n\t    }\n\t}\n      else\n\t{\n\t  /* Check for end of string. */\n\t  if (next_c == L'\\0')\n\t\tgoto backtrack;\n\n\t  /* Read the next character. */\n\t  GET_NEXT_WCHAR();\n\t}\n\n      next_state = NULL;\n      for (trans_i = state; trans_i->state; trans_i++)\n\t{\n\t  if (trans_i->code_min <= (tre_cint_t)prev_c\n\t      && trans_i->code_max >= (tre_cint_t)prev_c)\n\t    {\n\t      if (trans_i->assertions\n\t\t  && (CHECK_ASSERTIONS(trans_i->assertions)\n\t\t      || CHECK_CHAR_CLASSES(trans_i, tnfa, eflags)))\n\t\t{\n\t\t  continue;\n\t\t}\n\n\t      if (next_state == NULL)\n\t\t{\n\t\t  /* First matching transition. */\n\t\t  next_state = trans_i->state;\n\t\t  next_tags = trans_i->tags;\n\t\t}\n\t      else\n\t\t{\n\t\t  /* Second matching transition.  We may need to backtrack here\n\t\t     to take this transition instead of the first one, so we\n\t\t     push this transition in the backtracking stack so we can\n\t\t     jump back here if needed. */\n\t\t  BT_STACK_PUSH(pos, str_byte, 0, trans_i->state,\n\t\t\t\ttrans_i->state_id, next_c, tags, mbstate);\n\t\t  {\n\t\t    int *tmp;\n\t\t    for (tmp = trans_i->tags; tmp && *tmp >= 0; tmp++)\n\t\t      stack->item.tags[*tmp] = pos;\n\t\t  }\n#if 0 /* XXX - it's important not to look at all transitions here to keep\n\t the stack small! */\n\t\t  break;\n#endif\n\t\t}\n\t    }\n\t}\n\n      if (next_state != NULL)\n\t{\n\t  /* Matching transitions were found.  Take the first one. */\n\t  state = next_state;\n\n\t  /* Update the tag values. */\n\t  if (next_tags)\n\t    while (*next_tags >= 0)\n\t      tags[*next_tags++] = pos;\n\t}\n      else\n\t{\n\tbacktrack:\n\t  /* A matching transition was not found.  Try to backtrack. */\n\t  if (stack->prev)\n\t    {\n\t      if (stack->item.state->assertions & ASSERT_BACKREF)\n\t\t{\n\t\t  states_seen[stack->item.state_id] = 0;\n\t\t}\n\n\t      BT_STACK_POP();\n\t    }\n\t  else if (match_eo < 0)\n\t    {\n\t      /* Try starting from a later position in the input string. */\n\t      /* Check for end of string. */\n\t      if (next_c == L'\\0')\n\t\t    {\n\t\t      break;\n\t\t    }\n\t      next_c = next_c_start;\n#ifdef TRE_MBSTATE\n\t      mbstate = mbstate_start;\n#endif /* TRE_MBSTATE */\n\t      str_byte = str_byte_start;\n\t      goto retry;\n\t    }\n\t  else\n\t    {\n\t      break;\n\t    }\n\t}\n    }\n\n  ret = match_eo >= 0 ? REG_OK : REG_NOMATCH;\n  *match_end_ofs = match_eo;\n\n error_exit:\n  tre_bt_mem_destroy(mem);\n#ifndef TRE_USE_ALLOCA\n  if (tags)\n    xfree(tags);\n  if (pmatch)\n    xfree(pmatch);\n  if (states_seen)\n    xfree(states_seen);\n#endif /* !TRE_USE_ALLOCA */\n\n  return ret;\n}\n\n/***********************************************************************\n from regexec.c\n***********************************************************************/\n\n/* Fills the POSIX.2 regmatch_t array according to the TNFA tag and match\n   endpoint values. */\nstatic void\ntre_fill_pmatch(size_t nmatch, regmatch_t pmatch[], int cflags,\n\t\tconst tre_tnfa_t *tnfa, regoff_t *tags, regoff_t match_eo)\n{\n  tre_submatch_data_t *submatch_data;\n  unsigned int i, j;\n  int *parents;\n\n  i = 0;\n  if (match_eo >= 0 && !(cflags & REG_NOSUB))\n    {\n      /* Construct submatch offsets from the tags. */\n      submatch_data = tnfa->submatch_data;\n      while (i < tnfa->num_submatches && i < nmatch)\n\t{\n\t  if (submatch_data[i].so_tag == tnfa->end_tag)\n\t    pmatch[i].rm_so = match_eo;\n\t  else\n\t    pmatch[i].rm_so = tags[submatch_data[i].so_tag];\n\n\t  if (submatch_data[i].eo_tag == tnfa->end_tag)\n\t    pmatch[i].rm_eo = match_eo;\n\t  else\n\t    pmatch[i].rm_eo = tags[submatch_data[i].eo_tag];\n\n\t  /* If either of the endpoints were not used, this submatch\n\t     was not part of the match. */\n\t  if (pmatch[i].rm_so == -1 || pmatch[i].rm_eo == -1)\n\t    pmatch[i].rm_so = pmatch[i].rm_eo = -1;\n\n\t  i++;\n\t}\n      /* Reset all submatches that are not within all of their parent\n\t submatches. */\n      i = 0;\n      while (i < tnfa->num_submatches && i < nmatch)\n\t{\n\t  if (pmatch[i].rm_eo == -1)\n\t    assert(pmatch[i].rm_so == -1);\n\t  assert(pmatch[i].rm_so <= pmatch[i].rm_eo);\n\n\t  parents = submatch_data[i].parents;\n\t  if (parents != NULL)\n\t    for (j = 0; parents[j] >= 0; j++)\n\t      {\n\t\tif (pmatch[i].rm_so < pmatch[parents[j]].rm_so\n\t\t    || pmatch[i].rm_eo > pmatch[parents[j]].rm_eo)\n\t\t  pmatch[i].rm_so = pmatch[i].rm_eo = -1;\n\t      }\n\t  i++;\n\t}\n    }\n\n  while (i < nmatch)\n    {\n      pmatch[i].rm_so = -1;\n      pmatch[i].rm_eo = -1;\n      i++;\n    }\n}\n\n\n/*\n  Wrapper functions for POSIX compatible regexp matching.\n*/\n\nint\nregexec(const regex_t *restrict preg, const char *restrict string,\n\t  size_t nmatch, regmatch_t pmatch[restrict], int eflags)\n{\n  tre_tnfa_t *tnfa = (void *)preg->TRE_REGEX_T_FIELD;\n  reg_errcode_t status;\n  regoff_t *tags = NULL, eo;\n  if (tnfa->cflags & REG_NOSUB) nmatch = 0;\n  if (tnfa->num_tags > 0 && nmatch > 0)\n    {\n      tags = xmalloc(sizeof(*tags) * tnfa->num_tags);\n      if (tags == NULL)\n\treturn REG_ESPACE;\n    }\n\n  /* Dispatch to the appropriate matcher. */\n  if (tnfa->have_backrefs)\n    {\n      /* The regex has back references, use the backtracking matcher. */\n      status = tre_tnfa_run_backtrack(tnfa, string, tags, eflags, &eo);\n    }\n  else\n    {\n      /* Exact matching, no back references, use the parallel matcher. */\n      status = tre_tnfa_run_parallel(tnfa, string, tags, eflags, &eo);\n    }\n\n  if (status == REG_OK)\n    /* A match was found, so fill the submatch registers. */\n    tre_fill_pmatch(nmatch, pmatch, tnfa->cflags, tnfa, tags, eo);\n  if (tags)\n    xfree(tags);\n  return status;\n}\n"
  },
  {
    "path": "user.libc/src/regex/tre-mem.c",
    "content": "/*\n  tre-mem.c - TRE memory allocator\n\n  Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>\n  All rights reserved.\n\n  Redistribution and use in source and binary forms, with or without\n  modification, are permitted provided that the following conditions\n  are met:\n\n    1. Redistributions of source code must retain the above copyright\n       notice, this list of conditions and the following disclaimer.\n\n    2. Redistributions in binary form must reproduce the above copyright\n       notice, this list of conditions and the following disclaimer in the\n       documentation and/or other materials provided with the distribution.\n\n  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS\n  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT\n  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n*/\n\n/*\n  This memory allocator is for allocating small memory blocks efficiently\n  in terms of memory overhead and execution speed.  The allocated blocks\n  cannot be freed individually, only all at once.  There can be multiple\n  allocators, though.\n*/\n\n#include <stdlib.h>\n#include <string.h>\n\n#include \"tre.h\"\n\n/*\n  This memory allocator is for allocating small memory blocks efficiently\n  in terms of memory overhead and execution speed.  The allocated blocks\n  cannot be freed individually, only all at once.  There can be multiple\n  allocators, though.\n*/\n\n/* Returns a new memory allocator or NULL if out of memory. */\ntre_mem_t\ntre_mem_new_impl(int provided, void *provided_block)\n{\n  tre_mem_t mem;\n  if (provided)\n    {\n      mem = provided_block;\n      memset(mem, 0, sizeof(*mem));\n    }\n  else\n    mem = xcalloc(1, sizeof(*mem));\n  if (mem == NULL)\n    return NULL;\n  return mem;\n}\n\n\n/* Frees the memory allocator and all memory allocated with it. */\nvoid\ntre_mem_destroy(tre_mem_t mem)\n{\n  tre_list_t *tmp, *l = mem->blocks;\n\n  while (l != NULL)\n    {\n      xfree(l->data);\n      tmp = l->next;\n      xfree(l);\n      l = tmp;\n    }\n  xfree(mem);\n}\n\n\n/* Allocates a block of `size' bytes from `mem'.  Returns a pointer to the\n   allocated block or NULL if an underlying malloc() failed. */\nvoid *\ntre_mem_alloc_impl(tre_mem_t mem, int provided, void *provided_block,\n\t\t   int zero, size_t size)\n{\n  void *ptr;\n\n  if (mem->failed)\n    {\n      return NULL;\n    }\n\n  if (mem->n < size)\n    {\n      /* We need more memory than is available in the current block.\n\t Allocate a new block. */\n      tre_list_t *l;\n      if (provided)\n\t{\n\t  if (provided_block == NULL)\n\t    {\n\t      mem->failed = 1;\n\t      return NULL;\n\t    }\n\t  mem->ptr = provided_block;\n\t  mem->n = TRE_MEM_BLOCK_SIZE;\n\t}\n      else\n\t{\n\t  int block_size;\n\t  if (size * 8 > TRE_MEM_BLOCK_SIZE)\n\t    block_size = size * 8;\n\t  else\n\t    block_size = TRE_MEM_BLOCK_SIZE;\n\t  l = xmalloc(sizeof(*l));\n\t  if (l == NULL)\n\t    {\n\t      mem->failed = 1;\n\t      return NULL;\n\t    }\n\t  l->data = xmalloc(block_size);\n\t  if (l->data == NULL)\n\t    {\n\t      xfree(l);\n\t      mem->failed = 1;\n\t      return NULL;\n\t    }\n\t  l->next = NULL;\n\t  if (mem->current != NULL)\n\t    mem->current->next = l;\n\t  if (mem->blocks == NULL)\n\t    mem->blocks = l;\n\t  mem->current = l;\n\t  mem->ptr = l->data;\n\t  mem->n = block_size;\n\t}\n    }\n\n  /* Make sure the next pointer will be aligned. */\n  size += ALIGN(mem->ptr + size, long);\n\n  /* Allocate from current block. */\n  ptr = mem->ptr;\n  mem->ptr += size;\n  mem->n -= size;\n\n  /* Set to zero if needed. */\n  if (zero)\n    memset(ptr, 0, size);\n\n  return ptr;\n}\n"
  },
  {
    "path": "user.libc/src/regex/tre.h",
    "content": "/*\n  tre-internal.h - TRE internal definitions\n\n  Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>\n  All rights reserved.\n\n  Redistribution and use in source and binary forms, with or without\n  modification, are permitted provided that the following conditions\n  are met:\n\n    1. Redistributions of source code must retain the above copyright\n       notice, this list of conditions and the following disclaimer.\n\n    2. Redistributions in binary form must reproduce the above copyright\n       notice, this list of conditions and the following disclaimer in the\n       documentation and/or other materials provided with the distribution.\n\n  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS\n  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT\n  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n*/\n\n#include <regex.h>\n#include <wchar.h>\n#include <wctype.h>\n\n#undef  TRE_MBSTATE\n\n#define NDEBUG\n\n#define TRE_REGEX_T_FIELD __opaque\ntypedef int reg_errcode_t;\n\ntypedef wchar_t tre_char_t;\n\n#define DPRINT(msg) do { } while(0)\n\n#define elementsof(x)\t( sizeof(x) / sizeof(x[0]) )\n\n#define tre_mbrtowc(pwc, s, n, ps) (mbtowc((pwc), (s), (n)))\n\n/* Wide characters. */\ntypedef wint_t tre_cint_t;\n#define TRE_CHAR_MAX 0x10ffff\n\n#define tre_isalnum iswalnum\n#define tre_isalpha iswalpha\n#define tre_isblank iswblank\n#define tre_iscntrl iswcntrl\n#define tre_isdigit iswdigit\n#define tre_isgraph iswgraph\n#define tre_islower iswlower\n#define tre_isprint iswprint\n#define tre_ispunct iswpunct\n#define tre_isspace iswspace\n#define tre_isupper iswupper\n#define tre_isxdigit iswxdigit\n\n#define tre_tolower towlower\n#define tre_toupper towupper\n#define tre_strlen  wcslen\n\n/* Use system provided iswctype() and wctype(). */\ntypedef wctype_t tre_ctype_t;\n#define tre_isctype iswctype\n#define tre_ctype   wctype\n\n/* Returns number of bytes to add to (char *)ptr to make it\n   properly aligned for the type. */\n#define ALIGN(ptr, type) \\\n  ((((long)ptr) % sizeof(type)) \\\n   ? (sizeof(type) - (((long)ptr) % sizeof(type))) \\\n   : 0)\n\n#undef MAX\n#undef MIN\n#define MAX(a, b) (((a) >= (b)) ? (a) : (b))\n#define MIN(a, b) (((a) <= (b)) ? (a) : (b))\n\n/* TNFA transition type. A TNFA state is an array of transitions,\n   the terminator is a transition with NULL `state'. */\ntypedef struct tnfa_transition tre_tnfa_transition_t;\n\nstruct tnfa_transition {\n  /* Range of accepted characters. */\n  tre_cint_t code_min;\n  tre_cint_t code_max;\n  /* Pointer to the destination state. */\n  tre_tnfa_transition_t *state;\n  /* ID number of the destination state. */\n  int state_id;\n  /* -1 terminated array of tags (or NULL). */\n  int *tags;\n  /* Assertion bitmap. */\n  int assertions;\n  /* Assertion parameters. */\n  union {\n    /* Character class assertion. */\n    tre_ctype_t class;\n    /* Back reference assertion. */\n    int backref;\n  } u;\n  /* Negative character class assertions. */\n  tre_ctype_t *neg_classes;\n};\n\n\n/* Assertions. */\n#define ASSERT_AT_BOL\t\t  1   /* Beginning of line. */\n#define ASSERT_AT_EOL\t\t  2   /* End of line. */\n#define ASSERT_CHAR_CLASS\t  4   /* Character class in `class'. */\n#define ASSERT_CHAR_CLASS_NEG\t  8   /* Character classes in `neg_classes'. */\n#define ASSERT_AT_BOW\t\t 16   /* Beginning of word. */\n#define ASSERT_AT_EOW\t\t 32   /* End of word. */\n#define ASSERT_AT_WB\t\t 64   /* Word boundary. */\n#define ASSERT_AT_WB_NEG\t128   /* Not a word boundary. */\n#define ASSERT_BACKREF\t\t256   /* A back reference in `backref'. */\n#define ASSERT_LAST\t\t256\n\n/* Tag directions. */\ntypedef enum {\n  TRE_TAG_MINIMIZE = 0,\n  TRE_TAG_MAXIMIZE = 1\n} tre_tag_direction_t;\n\n/* Instructions to compute submatch register values from tag values\n   after a successful match.  */\nstruct tre_submatch_data {\n  /* Tag that gives the value for rm_so (submatch start offset). */\n  int so_tag;\n  /* Tag that gives the value for rm_eo (submatch end offset). */\n  int eo_tag;\n  /* List of submatches this submatch is contained in. */\n  int *parents;\n};\n\ntypedef struct tre_submatch_data tre_submatch_data_t;\n\n\n/* TNFA definition. */\ntypedef struct tnfa tre_tnfa_t;\n\nstruct tnfa {\n  tre_tnfa_transition_t *transitions;\n  unsigned int num_transitions;\n  tre_tnfa_transition_t *initial;\n  tre_tnfa_transition_t *final;\n  tre_submatch_data_t *submatch_data;\n  char *firstpos_chars;\n  int first_char;\n  unsigned int num_submatches;\n  tre_tag_direction_t *tag_directions;\n  int *minimal_tags;\n  int num_tags;\n  int num_minimals;\n  int end_tag;\n  int num_states;\n  int cflags;\n  int have_backrefs;\n  int have_approx;\n};\n\n/* from tre-mem.h: */\n\n#define TRE_MEM_BLOCK_SIZE 1024\n\ntypedef struct tre_list {\n  void *data;\n  struct tre_list *next;\n} tre_list_t;\n\ntypedef struct tre_mem_struct {\n  tre_list_t *blocks;\n  tre_list_t *current;\n  char *ptr;\n  size_t n;\n  int failed;\n  void **provided;\n} *tre_mem_t;\n\n#define tre_mem_new_impl   __tre_mem_new_impl\n#define tre_mem_alloc_impl __tre_mem_alloc_impl\n#define tre_mem_destroy    __tre_mem_destroy\n\nhidden tre_mem_t tre_mem_new_impl(int provided, void *provided_block);\nhidden void *tre_mem_alloc_impl(tre_mem_t mem, int provided, void *provided_block,\n                                int zero, size_t size);\n\n/* Returns a new memory allocator or NULL if out of memory. */\n#define tre_mem_new()  tre_mem_new_impl(0, NULL)\n\n/* Allocates a block of `size' bytes from `mem'.  Returns a pointer to the\n   allocated block or NULL if an underlying malloc() failed. */\n#define tre_mem_alloc(mem, size) tre_mem_alloc_impl(mem, 0, NULL, 0, size)\n\n/* Allocates a block of `size' bytes from `mem'.  Returns a pointer to the\n   allocated block or NULL if an underlying malloc() failed.  The memory\n   is set to zero. */\n#define tre_mem_calloc(mem, size) tre_mem_alloc_impl(mem, 0, NULL, 1, size)\n\n#ifdef TRE_USE_ALLOCA\n/* alloca() versions.  Like above, but memory is allocated with alloca()\n   instead of malloc(). */\n\n#define tre_mem_newa() \\\n  tre_mem_new_impl(1, alloca(sizeof(struct tre_mem_struct)))\n\n#define tre_mem_alloca(mem, size)\t\t\t\t\t      \\\n  ((mem)->n >= (size)\t\t\t\t\t\t\t      \\\n   ? tre_mem_alloc_impl((mem), 1, NULL, 0, (size))\t\t\t      \\\n   : tre_mem_alloc_impl((mem), 1, alloca(TRE_MEM_BLOCK_SIZE), 0, (size)))\n#endif /* TRE_USE_ALLOCA */\n\n\n/* Frees the memory allocator and all memory allocated with it. */\nhidden void tre_mem_destroy(tre_mem_t mem);\n\n#define xmalloc malloc\n#define xcalloc calloc\n#define xfree free\n#define xrealloc realloc\n\n"
  },
  {
    "path": "user.libc/src/search/hsearch.c",
    "content": "#define _GNU_SOURCE\n#include <stdlib.h>\n#include <string.h>\n#include <search.h>\n\n/*\nopen addressing hash table with 2^n table size\nquadratic probing is used in case of hash collision\ntab indices and hash are size_t\nafter resize fails with ENOMEM the state of tab is still usable\n\nwith the posix api items cannot be iterated and length cannot be queried\n*/\n\n#define MINSIZE 8\n#define MAXSIZE ((size_t)-1/2 + 1)\n\nstruct __tab {\n\tENTRY *entries;\n\tsize_t mask;\n\tsize_t used;\n};\n\nstatic struct hsearch_data htab;\n\nstatic int __hcreate_r(size_t, struct hsearch_data *);\nstatic void __hdestroy_r(struct hsearch_data *);\nstatic int __hsearch_r(ENTRY, ACTION, ENTRY **, struct hsearch_data *);\n\nstatic size_t keyhash(char *k)\n{\n\tunsigned char *p = (void *)k;\n\tsize_t h = 0;\n\n\twhile (*p)\n\t\th = 31*h + *p++;\n\treturn h;\n}\n\nstatic int resize(size_t nel, struct hsearch_data *htab)\n{\n\tsize_t newsize;\n\tsize_t i, j;\n\tENTRY *e, *newe;\n\tENTRY *oldtab = htab->__tab->entries;\n\tENTRY *oldend = htab->__tab->entries + htab->__tab->mask + 1;\n\n\tif (nel > MAXSIZE)\n\t\tnel = MAXSIZE;\n\tfor (newsize = MINSIZE; newsize < nel; newsize *= 2);\n\thtab->__tab->entries = calloc(newsize, sizeof *htab->__tab->entries);\n\tif (!htab->__tab->entries) {\n\t\thtab->__tab->entries = oldtab;\n\t\treturn 0;\n\t}\n\thtab->__tab->mask = newsize - 1;\n\tif (!oldtab)\n\t\treturn 1;\n\tfor (e = oldtab; e < oldend; e++)\n\t\tif (e->key) {\n\t\t\tfor (i=keyhash(e->key),j=1; ; i+=j++) {\n\t\t\t\tnewe = htab->__tab->entries + (i & htab->__tab->mask);\n\t\t\t\tif (!newe->key)\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t*newe = *e;\n\t\t}\n\tfree(oldtab);\n\treturn 1;\n}\n\nint hcreate(size_t nel)\n{\n\treturn __hcreate_r(nel, &htab);\n}\n\nvoid hdestroy(void)\n{\n\t__hdestroy_r(&htab);\n}\n\nstatic ENTRY *lookup(char *key, size_t hash, struct hsearch_data *htab)\n{\n\tsize_t i, j;\n\tENTRY *e;\n\n\tfor (i=hash,j=1; ; i+=j++) {\n\t\te = htab->__tab->entries + (i & htab->__tab->mask);\n\t\tif (!e->key || strcmp(e->key, key) == 0)\n\t\t\tbreak;\n\t}\n\treturn e;\n}\n\nENTRY *hsearch(ENTRY item, ACTION action)\n{\n\tENTRY *e;\n\n\t__hsearch_r(item, action, &e, &htab);\n\treturn e;\n}\n\nstatic int __hcreate_r(size_t nel, struct hsearch_data *htab)\n{\n\tint r;\n\n\thtab->__tab = calloc(1, sizeof *htab->__tab);\n\tif (!htab->__tab)\n\t\treturn 0;\n\tr = resize(nel, htab);\n\tif (r == 0) {\n\t\tfree(htab->__tab);\n\t\thtab->__tab = 0;\n\t}\n\treturn r;\n}\nweak_alias(__hcreate_r, hcreate_r);\n\nstatic void __hdestroy_r(struct hsearch_data *htab)\n{\n\tif (htab->__tab) free(htab->__tab->entries);\n\tfree(htab->__tab);\n\thtab->__tab = 0;\n}\nweak_alias(__hdestroy_r, hdestroy_r);\n\nstatic int __hsearch_r(ENTRY item, ACTION action, ENTRY **retval, struct hsearch_data *htab)\n{\n\tsize_t hash = keyhash(item.key);\n\tENTRY *e = lookup(item.key, hash, htab);\n\n\tif (e->key) {\n\t\t*retval = e;\n\t\treturn 1;\n\t}\n\tif (action == FIND) {\n\t\t*retval = 0;\n\t\treturn 0;\n\t}\n\t*e = item;\n\tif (++htab->__tab->used > htab->__tab->mask - htab->__tab->mask/4) {\n\t\tif (!resize(2*htab->__tab->used, htab)) {\n\t\t\thtab->__tab->used--;\n\t\t\te->key = 0;\n\t\t\t*retval = 0;\n\t\t\treturn 0;\n\t\t}\n\t\te = lookup(item.key, hash, htab);\n\t}\n\t*retval = e;\n\treturn 1;\n}\nweak_alias(__hsearch_r, hsearch_r);\n"
  },
  {
    "path": "user.libc/src/search/insque.c",
    "content": "#include <search.h>\n\nstruct node {\n\tstruct node *next;\n\tstruct node *prev;\n};\n\nvoid insque(void *element, void *pred)\n{\n\tstruct node *e = element;\n\tstruct node *p = pred;\n\n\tif (!p) {\n\t\te->next = e->prev = 0;\n\t\treturn;\n\t}\n\te->next = p->next;\n\te->prev = p;\n\tp->next = e;\n\tif (e->next)\n\t\te->next->prev = e;\n}\n\nvoid remque(void *element)\n{\n\tstruct node *e = element;\n\n\tif (e->next)\n\t\te->next->prev = e->prev;\n\tif (e->prev)\n\t\te->prev->next = e->next;\n}\n"
  },
  {
    "path": "user.libc/src/search/lsearch.c",
    "content": "#include <search.h>\n#include <string.h>\n\nvoid *lsearch(const void *key, void *base, size_t *nelp, size_t width,\n\tint (*compar)(const void *, const void *))\n{\n\tchar (*p)[width] = base;\n\tsize_t n = *nelp;\n\tsize_t i;\n\n\tfor (i = 0; i < n; i++)\n\t\tif (compar(key, p[i]) == 0)\n\t\t\treturn p[i];\n\t*nelp = n+1;\n\treturn memcpy(p[n], key, width);\n}\n\nvoid *lfind(const void *key, const void *base, size_t *nelp,\n\tsize_t width, int (*compar)(const void *, const void *))\n{\n\tchar (*p)[width] = (void *)base;\n\tsize_t n = *nelp;\n\tsize_t i;\n\n\tfor (i = 0; i < n; i++)\n\t\tif (compar(key, p[i]) == 0)\n\t\t\treturn p[i];\n\treturn 0;\n}\n\n\n"
  },
  {
    "path": "user.libc/src/search/tdelete.c",
    "content": "#include <stdlib.h>\n#include <search.h>\n#include \"tsearch.h\"\n\nvoid *tdelete(const void *restrict key, void **restrict rootp,\n\tint(*cmp)(const void *, const void *))\n{\n\tif (!rootp)\n\t\treturn 0;\n\n\tvoid **a[MAXH+1];\n\tstruct node *n = *rootp;\n\tstruct node *parent;\n\tstruct node *child;\n\tint i=0;\n\t/* *a[0] is an arbitrary non-null pointer that is returned when\n\t   the root node is deleted.  */\n\ta[i++] = rootp;\n\ta[i++] = rootp;\n\tfor (;;) {\n\t\tif (!n)\n\t\t\treturn 0;\n\t\tint c = cmp(key, n->key);\n\t\tif (!c)\n\t\t\tbreak;\n\t\ta[i++] = &n->a[c>0];\n\t\tn = n->a[c>0];\n\t}\n\tparent = *a[i-2];\n\tif (n->a[0]) {\n\t\t/* free the preceding node instead of the deleted one.  */\n\t\tstruct node *deleted = n;\n\t\ta[i++] = &n->a[0];\n\t\tn = n->a[0];\n\t\twhile (n->a[1]) {\n\t\t\ta[i++] = &n->a[1];\n\t\t\tn = n->a[1];\n\t\t}\n\t\tdeleted->key = n->key;\n\t\tchild = n->a[0];\n\t} else {\n\t\tchild = n->a[1];\n\t}\n\t/* freed node has at most one child, move it up and rebalance.  */\n\tfree(n);\n\t*a[--i] = child;\n\twhile (--i && __tsearch_balance(a[i]));\n\treturn parent;\n}\n"
  },
  {
    "path": "user.libc/src/search/tdestroy.c",
    "content": "#define _GNU_SOURCE\n#include <stdlib.h>\n#include <search.h>\n#include \"tsearch.h\"\n\nvoid tdestroy(void *root, void (*freekey)(void *))\n{\n\tstruct node *r = root;\n\n\tif (r == 0)\n\t\treturn;\n\ttdestroy(r->a[0], freekey);\n\ttdestroy(r->a[1], freekey);\n\tif (freekey) freekey((void *)r->key);\n\tfree(r);\n}\n"
  },
  {
    "path": "user.libc/src/search/tfind.c",
    "content": "#include <search.h>\n#include \"tsearch.h\"\n\nvoid *tfind(const void *key, void *const *rootp,\n\tint(*cmp)(const void *, const void *))\n{\n\tif (!rootp)\n\t\treturn 0;\n\n\tstruct node *n = *rootp;\n\tfor (;;) {\n\t\tif (!n)\n\t\t\tbreak;\n\t\tint c = cmp(key, n->key);\n\t\tif (!c)\n\t\t\tbreak;\n\t\tn = n->a[c>0];\n\t}\n\treturn n;\n}\n"
  },
  {
    "path": "user.libc/src/search/tsearch.c",
    "content": "#include <stdlib.h>\n#include <search.h>\n#include \"tsearch.h\"\n\nstatic inline int height(struct node *n) { return n ? n->h : 0; }\n\nstatic int rot(void **p, struct node *x, int dir /* deeper side */)\n{\n\tstruct node *y = x->a[dir];\n\tstruct node *z = y->a[!dir];\n\tint hx = x->h;\n\tint hz = height(z);\n\tif (hz > height(y->a[dir])) {\n\t\t/*\n\t\t *   x\n\t\t *  / \\ dir          z\n\t\t * A   y            / \\\n\t\t *    / \\   -->    x   y\n\t\t *   z   D        /|   |\\\n\t\t *  / \\          A B   C D\n\t\t * B   C\n\t\t */\n\t\tx->a[dir] = z->a[!dir];\n\t\ty->a[!dir] = z->a[dir];\n\t\tz->a[!dir] = x;\n\t\tz->a[dir] = y;\n\t\tx->h = hz;\n\t\ty->h = hz;\n\t\tz->h = hz+1;\n\t} else {\n\t\t/*\n\t\t *   x               y\n\t\t *  / \\             / \\\n\t\t * A   y    -->    x   D\n\t\t *    / \\         / \\\n\t\t *   z   D       A   z\n\t\t */\n\t\tx->a[dir] = z;\n\t\ty->a[!dir] = x;\n\t\tx->h = hz+1;\n\t\ty->h = hz+2;\n\t\tz = y;\n\t}\n\t*p = z;\n\treturn z->h - hx;\n}\n\n/* balance *p, return 0 if height is unchanged.  */\nint __tsearch_balance(void **p)\n{\n\tstruct node *n = *p;\n\tint h0 = height(n->a[0]);\n\tint h1 = height(n->a[1]);\n\tif (h0 - h1 + 1u < 3u) {\n\t\tint old = n->h;\n\t\tn->h = h0<h1 ? h1+1 : h0+1;\n\t\treturn n->h - old;\n\t}\n\treturn rot(p, n, h0<h1);\n}\n\nvoid *tsearch(const void *key, void **rootp,\n\tint (*cmp)(const void *, const void *))\n{\n\tif (!rootp)\n\t\treturn 0;\n\n\tvoid **a[MAXH];\n\tstruct node *n = *rootp;\n\tstruct node *r;\n\tint i=0;\n\ta[i++] = rootp;\n\tfor (;;) {\n\t\tif (!n)\n\t\t\tbreak;\n\t\tint c = cmp(key, n->key);\n\t\tif (!c)\n\t\t\treturn n;\n\t\ta[i++] = &n->a[c>0];\n\t\tn = n->a[c>0];\n\t}\n\tr = malloc(sizeof *r);\n\tif (!r)\n\t\treturn 0;\n\tr->key = key;\n\tr->a[0] = r->a[1] = 0;\n\tr->h = 1;\n\t/* insert new node, rebalance ancestors.  */\n\t*a[--i] = r;\n\twhile (i && __tsearch_balance(a[--i]));\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/src/search/tsearch.h",
    "content": "#include <search.h>\n#include <features.h>\n\n/* AVL tree height < 1.44*log2(nodes+2)-0.3, MAXH is a safe upper bound.  */\n#define MAXH (sizeof(void*)*8*3/2)\n\nstruct node {\n\tconst void *key;\n\tvoid *a[2];\n\tint h;\n};\n\nhidden int __tsearch_balance(void **);\n"
  },
  {
    "path": "user.libc/src/search/twalk.c",
    "content": "#include <search.h>\n#include \"tsearch.h\"\n\nstatic void walk(const struct node *r, void (*action)(const void *, VISIT, int), int d)\n{\n\tif (!r)\n\t\treturn;\n\tif (r->h == 1)\n\t\taction(r, leaf, d);\n\telse {\n\t\taction(r, preorder, d);\n\t\twalk(r->a[0], action, d+1);\n\t\taction(r, postorder, d);\n\t\twalk(r->a[1], action, d+1);\n\t\taction(r, endorder, d);\n\t}\n}\n\nvoid twalk(const void *root, void (*action)(const void *, VISIT, int))\n{\n\twalk(root, action, 0);\n}\n"
  },
  {
    "path": "user.libc/src/setjmp/longjmp.c",
    "content": ""
  },
  {
    "path": "user.libc/src/setjmp/setjmp.c",
    "content": ""
  },
  {
    "path": "user.libc/src/stdio/__fclose_ca.c",
    "content": "#include \"stdio_impl.h\"\n\nint __fclose_ca(FILE *f)\n{\n\treturn f->close(f);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/__fdopen.c",
    "content": "#include \"stdio_impl.h\"\n#include <stdlib.h>\n#include <sys/ioctl.h>\n#include <fcntl.h>\n#include <errno.h>\n#include <string.h>\n#include \"libc.h\"\n\n#include <minos/kobject.h>\n#include <minos/proto.h>\n\nFILE *__fdopen(int fd, int flags)\n{\n\tFILE *f;\n\tstruct winsize wsz;\n\n\t/* Allocate FILE+buffer or fail */\n\tif (!(f=malloc(sizeof *f + UNGET))) return 0;\n\n\t/* Zero-fill only the struct, not the buffer */\n\tmemset(f, 0, sizeof *f);\n\n#if 0\n\t/* Apply close-on-exec flag */\n\tif (strchr(mode, 'e')) __syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC);\n#endif\n\n\tif (kobject_mmap(fd, &f->buf, NULL)) {\n\t\tfree(f);\n\t\treturn 0;\n\t}\n\n\tf->flags = flags;\n\tf->fd = fd;\n\tf->buf_size = BUFSIZ;\n\n\t/* Activate line buffered mode for terminals */\n\tf->lbf = EOF;\n\n#if 0\n\t/* Is this file is a tty device ? */\n\tif (!(f->flags & F_NOWR) && !__syscall(SYS_ioctl, fd, TIOCGWINSZ, &wsz))\n\t\tf->lbf = '\\n';\n#endif\n\n\t/* Initialize op ptrs. No problem if some are unneeded. */\n\tf->read = __stdio_read;\n\tf->write = __stdio_write;\n\tf->seek = __stdio_seek;\n\tf->close = __stdio_close;\n\n\tif (!libc.threaded) f->lock = -1;\n\n\t/* Add new FILE to open file list */\n\treturn __ofl_add(f);\n}\n\nFILE *fdopen(int fd, const char *mode)\n{\n\t/* Check for valid initial mode character */\n\tif (!strchr(\"rwa\", *mode)) {\n\t\terrno = EINVAL;\n\t\treturn 0;\n\t}\n\n\treturn __fdopen(fd, __fmodeflags(mode));\n}\n"
  },
  {
    "path": "user.libc/src/stdio/__fmodeflags.c",
    "content": "#include <fcntl.h>\n#include <string.h>\n\nint __fmodeflags(const char *mode)\n{\n\tint flags;\n\tif (strchr(mode, '+')) flags = O_RDWR;\n\telse if (*mode == 'r') flags = O_RDONLY;\n\telse flags = O_WRONLY;\n\tif (strchr(mode, 'x')) flags |= O_EXCL;\n\tif (strchr(mode, 'e')) flags |= O_CLOEXEC;\n\tif (*mode != 'r') flags |= O_CREAT;\n\tif (*mode == 'w') flags |= O_TRUNC;\n\tif (*mode == 'a') flags |= O_APPEND;\n\treturn flags;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/__fopen_rb_ca.c",
    "content": "#include \"stdio_impl.h\"\n#include <fcntl.h>\n#include <string.h>\n\nFILE *__fopen_rb_ca(const char *filename, FILE *f, unsigned char *buf, size_t len)\n{\n\tmemset(f, 0, sizeof *f);\n\n\tf->fd = sys_open(filename, O_RDONLY|O_CLOEXEC);\n\tif (f->fd < 0) return 0;\n\n#if 0\n\t__syscall(SYS_fcntl, f->fd, F_SETFD, FD_CLOEXEC);\n#endif\n\n\tf->flags = F_NOWR | F_PERM;\n\tf->buf = buf + UNGET;\n\tf->buf_size = len - UNGET;\n\tf->read = __stdio_read;\n\tf->seek = __stdio_seek;\n\tf->close = __stdio_close;\n\tf->lock = -1;\n\n\treturn f;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/__lockfile.c",
    "content": "#include \"stdio_impl.h\"\n#include \"pthread_impl.h\"\n\nint __lockfile(FILE *f)\n{\n\tint owner = f->lock, tid = __pthread_self()->tid;\n\tif ((owner & ~MAYBE_WAITERS) == tid)\n\t\treturn 0;\n\towner = a_cas(&f->lock, 0, tid);\n\tif (!owner) return 1;\n\twhile ((owner = a_cas(&f->lock, 0, tid|MAYBE_WAITERS))) {\n\t\tif ((owner & MAYBE_WAITERS) ||\n\t\t    a_cas(&f->lock, owner, owner|MAYBE_WAITERS)==owner)\n\t\t\t__futexwait(&f->lock, owner|MAYBE_WAITERS, 1);\n\t}\n\treturn 1;\n}\n\nvoid __unlockfile(FILE *f)\n{\n\tif (a_swap(&f->lock, 0) & MAYBE_WAITERS)\n\t\t__wake(&f->lock, 1, 1);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/__overflow.c",
    "content": "#include \"stdio_impl.h\"\n\nint __overflow(FILE *f, int _c)\n{\n\tunsigned char c = _c;\n\tif (!f->wend && __towrite(f)) return EOF;\n\tif (f->wpos != f->wend && c != f->lbf) return *f->wpos++ = c;\n\tif (f->write(f, &c, 1)!=1) return EOF;\n\treturn c;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/__stdio_close.c",
    "content": "#include \"stdio_impl.h\"\n#include \"aio_impl.h\"\n\n#include <minos/kobject.h>\n\nint __stdio_close(FILE *f)\n{\n\treturn kobject_close(f->fd);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/__stdio_exit.c",
    "content": "#include \"stdio_impl.h\"\n\nstatic FILE *volatile dummy_file = 0;\nweak_alias(dummy_file, __stdin_used);\nweak_alias(dummy_file, __stdout_used);\nweak_alias(dummy_file, __stderr_used);\n\nstatic void close_file(FILE *f)\n{\n\tif (!f) return;\n\tFFINALLOCK(f);\n\tif (f->wpos != f->wbase) f->write(f, 0, 0);\n\tif (f->rpos != f->rend) f->seek(f, f->rpos-f->rend, SEEK_CUR);\n}\n\nvoid __stdio_exit(void)\n{\n\tFILE *f;\n\tfor (f=*__ofl_lock(); f; f=f->next) close_file(f);\n\tclose_file(__stdin_used);\n\tclose_file(__stdout_used);\n\tclose_file(__stderr_used);\n}\n\nweak_alias(__stdio_exit, __stdio_exit_needed);\n"
  },
  {
    "path": "user.libc/src/stdio/__stdio_read.c",
    "content": "#include \"stdio_impl.h\"\n#include <sys/uio.h>\n#include <string.h>\n\n#include <minos/proto.h>\n#include <minos/kobject.h>\n\nsize_t __stdio_read(FILE *f, unsigned char *buf, size_t len)\n{\n\t/*\n\t * read BUF_SIZE from the file, then copy to the buffer\n\t */\n\tstruct proto proto;\n\tsize_t copy, rem, total = 0;\n\tlong cnt;\n\n\tmemset(&proto, 0, sizeof(struct proto));\n\tproto.proto_id = PROTO_READ;\n\tproto.read.len = f->buf_size;\n\n\tdo {\n\t\tcnt = kobject_write(f->fd, &proto,\n\t\t\t\tsizeof(struct proto), NULL, 0, -1);\n\t\tif (cnt <= 0) {\n\t\t\t/*\n\t\t\t * mark as end of file if needed.\n\t\t\t */\n\t\t\tf->flags |= cnt ? F_ERR : F_EOF;\n\t\t\tif ((f->flags & F_EOF) && total < len)\n\t\t\t\tbuf[total] = EOF;\n\t\t\treturn 0;\n\t\t}\n\n\t\tcopy = cnt > len ? len : cnt;\n\t\tmemcpy(buf, f->buf, copy);\n\t\tbuf += copy;\n\t\tlen -= copy;\n\t\ttotal += copy;\n\t\trem = cnt - copy;\n\t} while (len > 0);\n\n\tif (rem != 0) {\n\t\tf->rpos = f->buf + rem;\n\t\tf->rend = f->buf + cnt;\n\t}\n\n\treturn total;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/__stdio_seek.c",
    "content": "#include \"stdio_impl.h\"\n#include <unistd.h>\n\n#include <minos/proto.h>\n#include <minos/kobject.h>\n\noff_t __lseek(int fd, off_t off, int whence)\n{\n\tstruct proto proto;\n\n\tif (fd <= 3)\n\t\treturn 0;\n\n\tproto.proto_id = PROTO_LSEEK;\n\tproto.lseek.off = off;\n\tproto.lseek.whence = whence;\n\n\treturn kobject_write(fd, &proto, sizeof(struct proto), NULL, 0, -1);\n}\n\noff_t __stdio_seek(FILE *f, off_t off, int whence)\n{\n\treturn __lseek(f->fd, off, whence);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/__stdio_write.c",
    "content": "#include \"stdio_impl.h\"\n#include <string.h>\n\n#include <minos/proto.h>\n#include <minos/kobject.h>\n\nsize_t __stdio_write(FILE *f, const unsigned char *buf, size_t len)\n{\n\tsize_t rem = len + (f->wpos - f->wbase);\n\tsize_t buf_rem = f->wend - f->wpos;\n\tsize_t cnt, copy, write_size;\n\tunsigned char *wbuf = f->wpos;\n\tstruct proto proto;\n\tsize_t total = rem;\n\n\tproto.proto_id = PROTO_WRITE;\n\tcopy = buf_rem > len ? len : buf_rem;\n\twrite_size = (f->wpos - f->wbase) + copy;\n\n\tdo {\n\t\tif (copy != 0)\n\t\t\tmemcpy(wbuf, buf, copy);\n\n\t\tproto.write.len = write_size;\n\t\tproto.write.offset = wbuf - f->buf;\n\t\tcnt = kobject_write(f->fd, &proto, sizeof(struct proto),\n\t\t\t\tNULL, 0, -1);\n\t\tif (cnt < 0) {\n\t\t\tf->wpos = f->wbase = f->wend = 0;\n\t\t\tf->flags |= F_ERR;\n\t\t\treturn 0;\n\t\t}\n\n\t\ttotal -= write_size;\n\t\twbuf = f->buf;\n\t\tbuf += copy;\n\n\t\tcopy = total > f->buf_size ? f->buf_size : total;\n\t\twrite_size = copy;\n\t} while (total > 0);\n\n\tf->wend = f->buf + f->buf_size;\n\tf->wpos = f->wbase = f->buf;\n\n\treturn rem;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/__stdout_write.c",
    "content": "#include \"stdio_impl.h\"\n#include <sys/ioctl.h>\n\nsize_t __stdout_write(FILE *f, const unsigned char *buf, size_t len)\n{\n       size_t rem = len + (f->wpos - f->wbase);\n       ssize_t cnt = 0;\n\n       if (f->wpos - f->wbase > 0) {\n               cnt = syscall(SYS_kobject_send, f->fd, f->wbase,\n                               f->wpos - f->wbase, NULL, 0, 0);\n               if (cnt < 0) {\n                       f->wpos = f->wbase = f->wend = 0;\n                       f->flags |= F_ERR;\n                       return 0;\n               }\n       }\n\n       if (len > 0) {\n               cnt = syscall(SYS_kobject_send, f->fd, buf, len, NULL, 0, 0, 0);\n               if (cnt < 0) {\n                       f->wpos = f->wbase = f->wend = 0;\n                       f->flags |= F_ERR;\n                       return 0;\n               }\n       }\n\n       f->wend = f->buf + f->buf_size;\n       f->wpos = f->wbase = f->buf;\n\n       return rem;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/__toread.c",
    "content": "#include <stdio_impl.h>\n\nint __toread(FILE *f)\n{\n\tf->mode |= f->mode-1;\n\tif (f->wpos != f->wbase) f->write(f, 0, 0);\n\tf->wpos = f->wbase = f->wend = 0;\n\tif (f->flags & F_NORD) {\n\t\tf->flags |= F_ERR;\n\t\treturn EOF;\n\t}\n\tf->rpos = f->rend = f->buf + f->buf_size;\n\treturn (f->flags & F_EOF) ? EOF : 0;\n}\n\nhidden void __toread_needs_stdio_exit()\n{\n\t__stdio_exit_needed();\n}\n"
  },
  {
    "path": "user.libc/src/stdio/__towrite.c",
    "content": "#include \"stdio_impl.h\"\n\nint __towrite(FILE *f)\n{\n\tf->mode |= f->mode-1;\n\tif (f->flags & F_NOWR) {\n\t\tf->flags |= F_ERR;\n\t\treturn EOF;\n\t}\n\t/* Clear read buffer (easier than summoning nasal demons) */\n\tf->rpos = f->rend = 0;\n\n\t/* Activate write through the buffer. */\n\tf->wpos = f->wbase = f->buf;\n\tf->wend = f->buf + f->buf_size;\n\n\treturn 0;\n}\n\nhidden void __towrite_needs_stdio_exit()\n{\n\t__stdio_exit_needed();\n}\n"
  },
  {
    "path": "user.libc/src/stdio/__uflow.c",
    "content": "#include \"stdio_impl.h\"\n\n/* This function assumes it will never be called if there is already\n * data buffered for reading. */\n\nint __uflow(FILE *f)\n{\n\tunsigned char c;\n\tif (!__toread(f) && f->read(f, &c, 1)==1) return c;\n\treturn EOF;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/asprintf.c",
    "content": "#define _GNU_SOURCE\n#include <stdio.h>\n#include <stdarg.h>\n\nint asprintf(char **s, const char *fmt, ...)\n{\n\tint ret;\n\tva_list ap;\n\tva_start(ap, fmt);\n\tret = vasprintf(s, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/clearerr.c",
    "content": "#include \"stdio_impl.h\"\n\nvoid clearerr(FILE *f)\n{\n\tFLOCK(f);\n\tf->flags &= ~(F_EOF|F_ERR);\n\tFUNLOCK(f);\n}\n\nweak_alias(clearerr, clearerr_unlocked);\n"
  },
  {
    "path": "user.libc/src/stdio/dprintf.c",
    "content": "#include <stdio.h>\n#include <stdarg.h>\n\nint dprintf(int fd, const char *restrict fmt, ...)\n{\n\tint ret;\n\tva_list ap;\n\tva_start(ap, fmt);\n\tret = vdprintf(fd, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/ext.c",
    "content": "#define _GNU_SOURCE\n#include \"stdio_impl.h\"\n#include <stdio_ext.h>\n\nvoid _flushlbf(void)\n{\n\tfflush(0);\n}\n\nint __fsetlocking(FILE *f, int type)\n{\n\treturn 0;\n}\n\nint __fwriting(FILE *f)\n{\n\treturn (f->flags & F_NORD) || f->wend;\n}\n\nint __freading(FILE *f)\n{\n\treturn (f->flags & F_NOWR) || f->rend;\n}\n\nint __freadable(FILE *f)\n{\n\treturn !(f->flags & F_NORD);\n}\n\nint __fwritable(FILE *f)\n{\n\treturn !(f->flags & F_NOWR);\n}\n\nint __flbf(FILE *f)\n{\n\treturn f->lbf >= 0;\n}\n\nsize_t __fbufsize(FILE *f)\n{\n\treturn f->buf_size;\n}\n\nsize_t __fpending(FILE *f)\n{\n\treturn f->wend ? f->wpos - f->wbase : 0;\n}\n\nint __fpurge(FILE *f)\n{\n\tf->wpos = f->wbase = f->wend = 0;\n\tf->rpos = f->rend = 0;\n\treturn 0;\n}\n\nweak_alias(__fpurge, fpurge);\n"
  },
  {
    "path": "user.libc/src/stdio/ext2.c",
    "content": "#include \"stdio_impl.h\"\n#include <stdio_ext.h>\n\nsize_t __freadahead(FILE *f)\n{\n\treturn f->rend ? f->rend - f->rpos : 0;\n}\n\nconst char *__freadptr(FILE *f, size_t *sizep)\n{\n\tif (f->rpos == f->rend) return 0;\n\t*sizep = f->rend - f->rpos;\n\treturn (const char *)f->rpos;\n}\n\nvoid __freadptrinc(FILE *f, size_t inc)\n{\n\tf->rpos += inc;\n}\n\nvoid __fseterr(FILE *f)\n{\n\tf->flags |= F_ERR;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/fclose.c",
    "content": "#include \"stdio_impl.h\"\n#include <stdlib.h>\n\nstatic void dummy(FILE *f) { }\nweak_alias(dummy, __unlist_locked_file);\n\nstatic int __fclose(FILE *f, int del)\n{\n\tint r;\n\t\n\tFLOCK(f);\n\tr = fflush(f);\n\tr |= f->close(f);\n\tFUNLOCK(f);\n\n\t/* Past this point, f is closed and any further explict access\n\t * to it is undefined. However, it still exists as an entry in\n\t * the open file list and possibly in the thread's locked files\n\t * list, if it was closed while explicitly locked. Functions\n\t * which process these lists must tolerate dead FILE objects\n\t * (which necessarily have inactive buffer pointers) without\n\t * producing any side effects. */\n\n\tif (f->flags & F_PERM) return r;\n\n\t/*\n\t * delete it from the open file list. TBD\n\t */\n\t__unlist_locked_file(f);\n\tif (del)\n\t\t__ofl_del(f);\n\n\tfree(f->getln_buf);\n\tfree(f);\n\n\treturn r;\n}\n\nint fclose(FILE *f)\n{\n\treturn __fclose(f, 1);\n}\n\nint fclose_fd(int fd)\n{\n\tFILE *file = __ofl_del_fd(fd);\n\tif (!file)\n\t\treturn -ENOENT;\n\n\treturn __fclose(file, 0);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/feof.c",
    "content": "#include \"stdio_impl.h\"\n\n#undef feof\n\nint feof(FILE *f)\n{\n\tFLOCK(f);\n\tint ret = !!(f->flags & F_EOF);\n\tFUNLOCK(f);\n\treturn ret;\n}\n\nweak_alias(feof, feof_unlocked);\nweak_alias(feof, _IO_feof_unlocked);\n"
  },
  {
    "path": "user.libc/src/stdio/ferror.c",
    "content": "#include \"stdio_impl.h\"\n\n#undef ferror\n\nint ferror(FILE *f)\n{\n\tFLOCK(f);\n\tint ret = !!(f->flags & F_ERR);\n\tFUNLOCK(f);\n\treturn ret;\n}\n\nweak_alias(ferror, ferror_unlocked);\nweak_alias(ferror, _IO_ferror_unlocked);\n"
  },
  {
    "path": "user.libc/src/stdio/fflush.c",
    "content": "#include \"stdio_impl.h\"\n\n/* stdout.c will override this if linked */\nstatic FILE *volatile dummy = 0;\nweak_alias(dummy, __stdout_used);\nweak_alias(dummy, __stderr_used);\n\nint fflush(FILE *f)\n{\n\tif (!f) {\n\t\tint r = 0;\n\t\tif (__stdout_used) r |= fflush(__stdout_used);\n\t\tif (__stderr_used) r |= fflush(__stderr_used);\n\n\t\tfor (f=*__ofl_lock(); f; f=f->next) {\n\t\t\tFLOCK(f);\n\t\t\tif (f->wpos != f->wbase) r |= fflush(f);\n\t\t\tFUNLOCK(f);\n\t\t}\n\t\t__ofl_unlock();\n\n\t\treturn r;\n\t}\n\n\tFLOCK(f);\n\n\t/* If writing, flush output */\n\tif (f->wpos != f->wbase) {\n\t\tf->write(f, 0, 0);\n\t\tif (!f->wpos) {\n\t\t\tFUNLOCK(f);\n\t\t\treturn EOF;\n\t\t}\n\t}\n\n\t/* If reading, sync position, per POSIX */\n\tif (f->rpos != f->rend) f->seek(f, f->rpos-f->rend, SEEK_CUR);\n\n\t/* Clear read and write modes */\n\tf->wpos = f->wbase = f->wend = 0;\n\tf->rpos = f->rend = 0;\n\n\tFUNLOCK(f);\n\treturn 0;\n}\n\nweak_alias(fflush, fflush_unlocked);\n"
  },
  {
    "path": "user.libc/src/stdio/fgetc.c",
    "content": "#include <stdio.h>\n#include \"getc.h\"\n\nint fgetc(FILE *f)\n{\n\treturn do_getc(f);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/fgetln.c",
    "content": "#define _GNU_SOURCE\n#include \"stdio_impl.h\"\n#include <string.h>\n\n#include \"libc.h\"\n\nchar *fgetln(FILE *f, size_t *plen)\n{\n\tchar *ret = 0, *z;\n\tssize_t l;\n\n\tFLOCK(f);\n\tungetc(getc_unlocked(f), f);\n\tif (f->rend && (z=memchr(f->rpos, '\\n', f->rend - f->rpos))) {\n\t\tret = (char *)f->rpos;\n\t\t*plen = ++z - ret;\n\t\tf->rpos = (void *)z;\n\t} else if ((l = getline(&f->getln_buf, (size_t[]){0}, f)) > 0) {\n\t\t*plen = l;\n\t\tret = f->getln_buf;\n\t}\n\tFUNLOCK(f);\n\treturn ret;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/fgetpos.c",
    "content": "#include \"stdio_impl.h\"\n\nint fgetpos(FILE *restrict f, fpos_t *restrict pos)\n{\n\toff_t off = __ftello(f);\n\tif (off < 0) return -1;\n\t*(long long *)pos = off;\n\treturn 0;\n}\n\nweak_alias(fgetpos, fgetpos64);\n"
  },
  {
    "path": "user.libc/src/stdio/fgets.c",
    "content": "#include \"stdio_impl.h\"\n#include <string.h>\n\n#define MIN(a,b) ((a)<(b) ? (a) : (b))\n\nchar *fgets(char *restrict s, int n, FILE *restrict f)\n{\n\tchar *p = s;\n\tunsigned char *z;\n\tsize_t k;\n\tint c;\n\n\tFLOCK(f);\n\n\tif (n--<=1) {\n\t\tf->mode |= f->mode-1;\n\t\tFUNLOCK(f);\n\t\tif (n) return 0;\n\t\t*s = 0;\n\t\treturn s;\n\t}\n\n\twhile (n) {\n\t\tif (f->rpos != f->rend) {\n\t\t\tz = memchr(f->rpos, '\\n', f->rend - f->rpos);\n\t\t\tk = z ? z - f->rpos + 1 : f->rend - f->rpos;\n\t\t\tk = MIN(k, n);\n\t\t\tmemcpy(p, f->rpos, k);\n\t\t\tf->rpos += k;\n\t\t\tp += k;\n\t\t\tn -= k;\n\t\t\tif (z || !n) break;\n\t\t}\n\t\tif ((c = getc_unlocked(f)) < 0) {\n\t\t\tif (p==s || !feof(f)) s = 0;\n\t\t\tbreak;\n\t\t}\n\t\tn--;\n\t\tif ((*p++ = c) == '\\n') break;\n\t}\n\tif (s) *p = 0;\n\n\tFUNLOCK(f);\n\n\treturn s;\n}\n\nweak_alias(fgets, fgets_unlocked);\n"
  },
  {
    "path": "user.libc/src/stdio/fgetwc.c",
    "content": "#include \"stdio_impl.h\"\n#include \"locale_impl.h\"\n#include <wchar.h>\n#include <errno.h>\n\nstatic wint_t __fgetwc_unlocked_internal(FILE *f)\n{\n\twchar_t wc;\n\tint c;\n\tsize_t l;\n\n\t/* Convert character from buffer if possible */\n\tif (f->rpos != f->rend) {\n\t\tl = mbtowc(&wc, (void *)f->rpos, f->rend - f->rpos);\n\t\tif (l+1 >= 1) {\n\t\t\tf->rpos += l + !l; /* l==0 means 1 byte, null */\n\t\t\treturn wc;\n\t\t}\n\t}\n\n\t/* Convert character byte-by-byte */\n\tmbstate_t st = { 0 };\n\tunsigned char b;\n\tint first = 1;\n\tdo {\n\t\tb = c = getc_unlocked(f);\n\t\tif (c < 0) {\n\t\t\tif (!first) {\n\t\t\t\tf->flags |= F_ERR;\n\t\t\t\terrno = EILSEQ;\n\t\t\t}\n\t\t\treturn WEOF;\n\t\t}\n\t\tl = mbrtowc(&wc, (void *)&b, 1, &st);\n\t\tif (l == -1) {\n\t\t\tif (!first) {\n\t\t\t\tf->flags |= F_ERR;\n\t\t\t\tungetc(b, f);\n\t\t\t}\n\t\t\treturn WEOF;\n\t\t}\n\t\tfirst = 0;\n\t} while (l == -2);\n\n\treturn wc;\n}\n\nwint_t __fgetwc_unlocked(FILE *f)\n{\n\tlocale_t *ploc = &CURRENT_LOCALE, loc = *ploc;\n\tif (f->mode <= 0) fwide(f, 1);\n\t*ploc = f->locale;\n\twchar_t wc = __fgetwc_unlocked_internal(f);\n\t*ploc = loc;\n\treturn wc;\n}\n\nwint_t fgetwc(FILE *f)\n{\n\twint_t c;\n\tFLOCK(f);\n\tc = __fgetwc_unlocked(f);\n\tFUNLOCK(f);\n\treturn c;\n}\n\nweak_alias(__fgetwc_unlocked, fgetwc_unlocked);\nweak_alias(__fgetwc_unlocked, getwc_unlocked);\n"
  },
  {
    "path": "user.libc/src/stdio/fgetws.c",
    "content": "#include \"stdio_impl.h\"\n#include <wchar.h>\n#include <errno.h>\n\nwint_t __fgetwc_unlocked(FILE *);\n\nwchar_t *fgetws(wchar_t *restrict s, int n, FILE *restrict f)\n{\n\twchar_t *p = s;\n\n\tif (!n--) return s;\n\n\tFLOCK(f);\n\n\t/* Setup a dummy errno so we can detect EILSEQ. This is\n\t * the only way to catch encoding errors in the form of a\n\t * partial character just before EOF. */\n\terrno = EAGAIN;\n\tfor (; n; n--) {\n\t\twint_t c = __fgetwc_unlocked(f);\n\t\tif (c == WEOF) break;\n\t\t*p++ = c;\n\t\tif (c == '\\n') break;\n\t}\n\t*p = 0;\n\tif (ferror(f) || errno==EILSEQ) p = s;\n\n\tFUNLOCK(f);\n\n\treturn (p == s) ? NULL : s;\n}\n\nweak_alias(fgetws, fgetws_unlocked);\n"
  },
  {
    "path": "user.libc/src/stdio/fileno.c",
    "content": "#include \"stdio_impl.h\"\n#include <errno.h>\n\nint fileno(FILE *f)\n{\n\tFLOCK(f);\n\tint fd = f->fd;\n\tFUNLOCK(f);\n\tif (fd < 0) {\n\t\terrno = EBADF;\n\t\treturn -1;\n\t}\n\treturn fd;\n}\n\nweak_alias(fileno, fileno_unlocked);\n"
  },
  {
    "path": "user.libc/src/stdio/flockfile.c",
    "content": "#include \"stdio_impl.h\"\n#include \"pthread_impl.h\"\n\nvoid flockfile(FILE *f)\n{\n\tif (!ftrylockfile(f)) return;\n\t__lockfile(f);\n\t__register_locked_file(f, __pthread_self());\n}\n"
  },
  {
    "path": "user.libc/src/stdio/fmemopen.c",
    "content": "#include \"stdio_impl.h\"\n#include <errno.h>\n#include <string.h>\n#include <stdlib.h>\n#include <stddef.h>\n#include <inttypes.h>\n#include \"libc.h\"\n\nstruct cookie {\n\tsize_t pos, len, size;\n\tunsigned char *buf;\n\tint mode;\n};\n\nstruct mem_FILE {\n\tFILE f;\n\tstruct cookie c;\n\tunsigned char buf[UNGET+BUFSIZ], buf2[];\n};\n\nstatic off_t mseek(FILE *f, off_t off, int whence)\n{\n\tssize_t base;\n\tstruct cookie *c = f->cookie;\n\tif (whence>2U) {\nfail:\n\t\terrno = EINVAL;\n\t\treturn -1;\n\t}\n\tbase = (size_t [3]){0, c->pos, c->len}[whence];\n\tif (off < -base || off > (ssize_t)c->size-base) goto fail;\n\treturn c->pos = base+off;\n}\n\nstatic size_t mread(FILE *f, unsigned char *buf, size_t len)\n{\n\tstruct cookie *c = f->cookie;\n\tsize_t rem = c->len - c->pos;\n\tif (c->pos > c->len) rem = 0;\n\tif (len > rem) {\n\t\tlen = rem;\n\t\tf->flags |= F_EOF;\n\t}\n\tmemcpy(buf, c->buf+c->pos, len);\n\tc->pos += len;\n\trem -= len;\n\tif (rem > f->buf_size) rem = f->buf_size;\n\tf->rpos = f->buf;\n\tf->rend = f->buf + rem;\n\tmemcpy(f->rpos, c->buf+c->pos, rem);\n\tc->pos += rem;\n\treturn len;\n}\n\nstatic size_t mwrite(FILE *f, const unsigned char *buf, size_t len)\n{\n\tstruct cookie *c = f->cookie;\n\tsize_t rem;\n\tsize_t len2 = f->wpos - f->wbase;\n\tif (len2) {\n\t\tf->wpos = f->wbase;\n\t\tif (mwrite(f, f->wpos, len2) < len2) return 0;\n\t}\n\tif (c->mode == 'a') c->pos = c->len;\n\trem = c->size - c->pos;\n\tif (len > rem) len = rem;\n\tmemcpy(c->buf+c->pos, buf, len);\n\tc->pos += len;\n\tif (c->pos > c->len) {\n\t\tc->len = c->pos;\n\t\tif (c->len < c->size) c->buf[c->len] = 0;\n\t\telse if ((f->flags&F_NORD) && c->size) c->buf[c->size-1] = 0;\n\t}\n\treturn len;\n}\n\nstatic int mclose(FILE *m)\n{\n\treturn 0;\n}\n\nFILE *fmemopen(void *restrict buf, size_t size, const char *restrict mode)\n{\n\tstruct mem_FILE *f;\n\tint plus = !!strchr(mode, '+');\n\t\n\tif (!strchr(\"rwa\", *mode)) {\n\t\terrno = EINVAL;\n\t\treturn 0;\n\t}\n\n\tif (!buf && size > PTRDIFF_MAX) {\n\t\terrno = ENOMEM;\n\t\treturn 0;\n\t}\n\n\tf = malloc(sizeof *f + (buf?0:size));\n\tif (!f) return 0;\n\tmemset(f, 0, offsetof(struct mem_FILE, buf));\n\tf->f.cookie = &f->c;\n\tf->f.fd = -1;\n\tf->f.lbf = EOF;\n\tf->f.buf = f->buf + UNGET;\n\tf->f.buf_size = sizeof f->buf - UNGET;\n\tif (!buf) {\n\t\tbuf = f->buf2;\n\t\tmemset(buf, 0, size);\n\t}\n\n\tf->c.buf = buf;\n\tf->c.size = size;\n\tf->c.mode = *mode;\n\t\n\tif (!plus) f->f.flags = (*mode == 'r') ? F_NOWR : F_NORD;\n\tif (*mode == 'r') f->c.len = size;\n\telse if (*mode == 'a') f->c.len = f->c.pos = strnlen(buf, size);\n\telse if (plus) *f->c.buf = 0;\n\n\tf->f.read = mread;\n\tf->f.write = mwrite;\n\tf->f.seek = mseek;\n\tf->f.close = mclose;\n\n\tif (!libc.threaded) f->f.lock = -1;\n\n\treturn __ofl_add(&f->f);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/fopen.c",
    "content": "#include \"stdio_impl.h\"\n#include <fcntl.h>\n#include <string.h>\n#include <errno.h>\n#include <ctype.h>\n\n#include \"libc.h\"\n\n#include <minos/kobject.h>\n#include <minos/proto.h>\n\n#define FILE_PATH_MIN 4\n\nint __sys_open(const char *restrict filename, int flags, int mode)\n{\n\tint len = strlen(filename);\n\tstruct proto proto;\n\n\tif ((len >= FILENAME_MAX) || (filename[0] != '/'))\n\t\treturn -EINVAL;\n\n\tif (libc.rootfs_handle <= 0)\n\t\treturn -ENOENT;\n\n\tproto.proto_id = PROTO_OPEN;\n\tproto.open.flags = flags;\n\tproto.open.mode = mode;\n\n\treturn kobject_write(libc.rootfs_handle, &proto, sizeof(struct proto),\n\t\t\t(char *)filename, len, 5000);\n}\n\nFILE *fopen(const char *restrict filename, const char *restrict mode)\n{\n\tFILE *f;\n\tint fd;\n\tint flags;\n\n\t/* Check for valid initial mode character */\n\tif (!strchr(\"rwa\", *mode)) {\n\t\terrno = EINVAL;\n\t\treturn 0;\n\t}\n\n\t/* Compute the flags to pass to open() */\n\tflags = __fmodeflags(mode);\n\n\tfd = __sys_open(filename, flags, 0);\n\tif (fd < 0)\n\t\treturn 0;\n\n#if 0\n\tif (flags & O_CLOEXEC)\n\t\t__syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC);\n#endif\n\n\tf = __fdopen(fd, flags);\n\tif (f)\n\t\treturn f;\n\n\tkobject_close(fd);\n\n\treturn 0;\n}\n\nweak_alias(fopen, fopen64);\n"
  },
  {
    "path": "user.libc/src/stdio/fopencookie.c",
    "content": "#define _GNU_SOURCE\n#include \"stdio_impl.h\"\n#include <stdlib.h>\n#include <sys/ioctl.h>\n#include <fcntl.h>\n#include <errno.h>\n#include <string.h>\n\nstruct fcookie {\n\tvoid *cookie;\n\tcookie_io_functions_t iofuncs;\n};\n\nstruct cookie_FILE {\n\tFILE f;\n\tstruct fcookie fc;\n\tunsigned char buf[UNGET+BUFSIZ];\n};\n\nstatic size_t cookieread(FILE *f, unsigned char *buf, size_t len)\n{\n\tstruct fcookie *fc = f->cookie;\n\tssize_t ret = -1;\n\tsize_t remain = len, readlen = 0;\n\tsize_t len2 = len - !!f->buf_size;\n\n\tif (!fc->iofuncs.read) goto bail;\n\n\tif (len2) {\n\t\tret = fc->iofuncs.read(fc->cookie, (char *) buf, len2);\n\t\tif (ret <= 0) goto bail;\n\n\t\treadlen += ret;\n\t\tremain -= ret;\n\t}\n\n\tif (!f->buf_size || remain > !!f->buf_size) return readlen;\n\n\tf->rpos = f->buf;\n\tret = fc->iofuncs.read(fc->cookie, (char *) f->rpos, f->buf_size);\n\tif (ret <= 0) goto bail;\n\tf->rend = f->rpos + ret;\n\n\tbuf[readlen++] = *f->rpos++;\n\n\treturn readlen;\n\nbail:\n\tf->flags |= ret == 0 ? F_EOF : F_ERR;\n\tf->rpos = f->rend = f->buf;\n\treturn readlen;\n}\n\nstatic size_t cookiewrite(FILE *f, const unsigned char *buf, size_t len)\n{\n\tstruct fcookie *fc = f->cookie;\n\tssize_t ret;\n\tsize_t len2 = f->wpos - f->wbase;\n\tif (!fc->iofuncs.write) return len;\n\tif (len2) {\n\t\tf->wpos = f->wbase;\n\t\tif (cookiewrite(f, f->wpos, len2) < len2) return 0;\n\t}\n\tret = fc->iofuncs.write(fc->cookie, (const char *) buf, len);\n\tif (ret < 0) {\n\t\tf->wpos = f->wbase = f->wend = 0;\n\t\tf->flags |= F_ERR;\n\t\treturn 0;\n\t}\n\treturn ret;\n}\n\nstatic off_t cookieseek(FILE *f, off_t off, int whence)\n{\n\tstruct fcookie *fc = f->cookie;\n\tint res;\n\tif (whence > 2U) {\n\t\terrno = EINVAL;\n\t\treturn -1;\n\t}\n\tif (!fc->iofuncs.seek) {\n\t\terrno = ENOTSUP;\n\t\treturn -1;\n\t}\n\tres = fc->iofuncs.seek(fc->cookie, &off, whence);\n\tif (res < 0)\n\t\treturn res;\n\treturn off;\n}\n\nstatic int cookieclose(FILE *f)\n{\n\tstruct fcookie *fc = f->cookie;\n\tif (fc->iofuncs.close) return fc->iofuncs.close(fc->cookie);\n\treturn 0;\n}\n\nFILE *fopencookie(void *cookie, const char *mode, cookie_io_functions_t iofuncs)\n{\n\tstruct cookie_FILE *f;\n\n\t/* Check for valid initial mode character */\n\tif (!strchr(\"rwa\", *mode)) {\n\t\terrno = EINVAL;\n\t\treturn 0;\n\t}\n\n\t/* Allocate FILE+fcookie+buffer or fail */\n\tif (!(f=malloc(sizeof *f))) return 0;\n\n\t/* Zero-fill only the struct, not the buffer */\n\tmemset(&f->f, 0, sizeof f->f);\n\n\t/* Impose mode restrictions */\n\tif (!strchr(mode, '+')) f->f.flags = (*mode == 'r') ? F_NOWR : F_NORD;\n\n\t/* Set up our fcookie */\n\tf->fc.cookie = cookie;\n\tf->fc.iofuncs = iofuncs;\n\n\tf->f.fd = -1;\n\tf->f.cookie = &f->fc;\n\tf->f.buf = f->buf + UNGET;\n\tf->f.buf_size = sizeof f->buf - UNGET;\n\tf->f.lbf = EOF;\n\n\t/* Initialize op ptrs. No problem if some are unneeded. */\n\tf->f.read = cookieread;\n\tf->f.write = cookiewrite;\n\tf->f.seek = cookieseek;\n\tf->f.close = cookieclose;\n\n\t/* Add new FILE to open file list */\n\treturn __ofl_add(&f->f);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/fprintf.c",
    "content": "#include <stdio.h>\n#include <stdarg.h>\n\nint fprintf(FILE *restrict f, const char *restrict fmt, ...)\n{\n\tint ret;\n\tva_list ap;\n\tva_start(ap, fmt);\n\tret = vfprintf(f, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/fputc.c",
    "content": "#include <stdio.h>\n#include \"putc.h\"\n\nint fputc(int c, FILE *f)\n{\n\treturn do_putc(c, f);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/fputs.c",
    "content": "#include \"stdio_impl.h\"\n#include <string.h>\n\nint fputs(const char *restrict s, FILE *restrict f)\n{\n\tsize_t l = strlen(s);\n\treturn (fwrite(s, 1, l, f)==l) - 1;\n}\n\nweak_alias(fputs, fputs_unlocked);\n"
  },
  {
    "path": "user.libc/src/stdio/fputwc.c",
    "content": "#include \"stdio_impl.h\"\n#include \"locale_impl.h\"\n#include <wchar.h>\n#include <limits.h>\n#include <ctype.h>\n\nwint_t __fputwc_unlocked(wchar_t c, FILE *f)\n{\n\tchar mbc[MB_LEN_MAX];\n\tint l;\n\tlocale_t *ploc = &CURRENT_LOCALE, loc = *ploc;\n\n\tif (f->mode <= 0) fwide(f, 1);\n\t*ploc = f->locale;\n\n\tif (isascii(c)) {\n\t\tc = putc_unlocked(c, f);\n\t} else if (f->wpos + MB_LEN_MAX < f->wend) {\n\t\tl = wctomb((void *)f->wpos, c);\n\t\tif (l < 0) c = WEOF;\n\t\telse f->wpos += l;\n\t} else {\n\t\tl = wctomb(mbc, c);\n\t\tif (l < 0 || __fwritex((void *)mbc, l, f) < l) c = WEOF;\n\t}\n\tif (c==WEOF) f->flags |= F_ERR;\n\t*ploc = loc;\n\treturn c;\n}\n\nwint_t fputwc(wchar_t c, FILE *f)\n{\n\tFLOCK(f);\n\tc = __fputwc_unlocked(c, f);\n\tFUNLOCK(f);\n\treturn c;\n}\n\nweak_alias(__fputwc_unlocked, fputwc_unlocked);\nweak_alias(__fputwc_unlocked, putwc_unlocked);\n"
  },
  {
    "path": "user.libc/src/stdio/fputws.c",
    "content": "#include \"stdio_impl.h\"\n#include \"locale_impl.h\"\n#include <wchar.h>\n\nint fputws(const wchar_t *restrict ws, FILE *restrict f)\n{\n\tunsigned char buf[BUFSIZ];\n\tsize_t l=0;\n\tlocale_t *ploc = &CURRENT_LOCALE, loc = *ploc;\n\n\tFLOCK(f);\n\n\tfwide(f, 1);\n\t*ploc = f->locale;\n\n\twhile (ws && (l = wcsrtombs((void *)buf, (void*)&ws, sizeof buf, 0))+1 > 1)\n\t\tif (__fwritex(buf, l, f) < l) {\n\t\t\tFUNLOCK(f);\n\t\t\t*ploc = loc;\n\t\t\treturn -1;\n\t\t}\n\n\tFUNLOCK(f);\n\n\t*ploc = loc;\n\treturn l; /* 0 or -1 */\n}\n\nweak_alias(fputws, fputws_unlocked);\n"
  },
  {
    "path": "user.libc/src/stdio/fread.c",
    "content": "#include \"stdio_impl.h\"\n#include <string.h>\n\n#define MIN(a,b) ((a)<(b) ? (a) : (b))\n\nsize_t fread(void *restrict destv, size_t size, size_t nmemb, FILE *restrict f)\n{\n\tunsigned char *dest = destv;\n\tsize_t len = size*nmemb, l = len, k;\n\tif (!size) nmemb = 0;\n\n\tFLOCK(f);\n\n\tf->mode |= f->mode-1;\n\n\tif (f->rpos != f->rend) {\n\t\t/* First exhaust the buffer. */\n\t\tk = MIN(f->rend - f->rpos, l);\n\t\tmemcpy(dest, f->rpos, k);\n\t\tf->rpos += k;\n\t\tdest += k;\n\t\tl -= k;\n\t}\n\t\n\t/* Read the remainder directly */\n\tfor (; l; l-=k, dest+=k) {\n\t\tk = __toread(f) ? 0 : f->read(f, dest, l);\n\t\tif (!k) {\n\t\t\tFUNLOCK(f);\n\t\t\treturn (len-l)/size;\n\t\t} else if (f->flags & F_STREAM) {\n\t\t\tl -= k;\n\t\t\tFUNLOCK(f);\n\t\t\treturn (len-l)/size;\n\t\t}\n\t}\n\n\tFUNLOCK(f);\n\treturn nmemb;\n}\n\nweak_alias(fread, fread_unlocked);\n"
  },
  {
    "path": "user.libc/src/stdio/freopen.c",
    "content": "#include \"stdio_impl.h\"\n#include <fcntl.h>\n#include <unistd.h>\n\n/* The basic idea of this implementation is to open a new FILE,\n * hack the necessary parts of the new FILE into the old one, then\n * close the new FILE. */\n\n/* Locking IS necessary because another thread may provably hold the\n * lock, via flockfile or otherwise, when freopen is called, and in that\n * case, freopen cannot act until the lock is released. */\n\nFILE *freopen(const char *restrict filename, const char *restrict mode, FILE *restrict f)\n{\n\tint fl = __fmodeflags(mode);\n\tFILE *f2;\n\n\tFLOCK(f);\n\n\tfflush(f);\n\n\tif (!filename) {\n#if 0\n\t\tif (fl&O_CLOEXEC)\n\t\t\t__syscall(SYS_fcntl, f->fd, F_SETFD, FD_CLOEXEC);\n\t\tfl &= ~(O_CREAT|O_EXCL|O_CLOEXEC);\n\t\tif (syscall(SYS_fcntl, f->fd, F_SETFL, fl) < 0)\n\t\t\tgoto fail;\n#endif\n\t} else {\n\t\tf2 = fopen(filename, mode);\n\t\tif (!f2) goto fail;\n\t\tif (f2->fd == f->fd) f2->fd = -1; /* avoid closing in fclose */\n\t\telse if (__dup3(f2->fd, f->fd, fl&O_CLOEXEC)<0) goto fail2;\n\n\t\tf->flags = (f->flags & F_PERM) | f2->flags;\n\t\tf->read = f2->read;\n\t\tf->write = f2->write;\n\t\tf->seek = f2->seek;\n\t\tf->close = f2->close;\n\n\t\tfclose(f2);\n\t}\n\n\tFUNLOCK(f);\n\treturn f;\n\nfail2:\n\tfclose(f2);\nfail:\n\tfclose(f);\n\treturn NULL;\n}\n\nweak_alias(freopen, freopen64);\n"
  },
  {
    "path": "user.libc/src/stdio/fscanf.c",
    "content": "#include <stdio.h>\n#include <stdarg.h>\n\nint fscanf(FILE *restrict f, const char *restrict fmt, ...)\n{\n\tint ret;\n\tva_list ap;\n\tva_start(ap, fmt);\n\tret = vfscanf(f, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n\nweak_alias(fscanf, __isoc99_fscanf);\n"
  },
  {
    "path": "user.libc/src/stdio/fseek.c",
    "content": "#include \"stdio_impl.h\"\n\nint __fseeko_unlocked(FILE *f, off_t off, int whence)\n{\n\t/* Adjust relative offset for unread data in buffer, if any. */\n\tif (whence == SEEK_CUR && f->rend) off -= f->rend - f->rpos;\n\n\t/* Flush write buffer, and report error on failure. */\n\tif (f->wpos != f->wbase) {\n\t\tf->write(f, 0, 0);\n\t\tif (!f->wpos) return -1;\n\t}\n\n\t/* Leave writing mode */\n\tf->wpos = f->wbase = f->wend = 0;\n\n\t/* Perform the underlying seek. */\n\tif (f->seek(f, off, whence) < 0) return -1;\n\n\t/* If seek succeeded, file is seekable and we discard read buffer. */\n\tf->rpos = f->rend = 0;\n\tf->flags &= ~F_EOF;\n\t\n\treturn 0;\n}\n\nint __fseeko(FILE *f, off_t off, int whence)\n{\n\tint result;\n\tFLOCK(f);\n\tresult = __fseeko_unlocked(f, off, whence);\n\tFUNLOCK(f);\n\treturn result;\n}\n\nint fseek(FILE *f, long off, int whence)\n{\n\treturn __fseeko(f, off, whence);\n}\n\nweak_alias(__fseeko, fseeko);\n\nweak_alias(fseeko, fseeko64);\n"
  },
  {
    "path": "user.libc/src/stdio/fsetpos.c",
    "content": "#include \"stdio_impl.h\"\n\nint fsetpos(FILE *f, const fpos_t *pos)\n{\n\treturn __fseeko(f, *(const long long *)pos, SEEK_SET);\n}\n\nweak_alias(fsetpos, fsetpos64);\n"
  },
  {
    "path": "user.libc/src/stdio/ftell.c",
    "content": "#include \"stdio_impl.h\"\n#include <limits.h>\n#include <errno.h>\n\noff_t __ftello_unlocked(FILE *f)\n{\n\toff_t pos = f->seek(f, 0,\n\t\t(f->flags & F_APP) && f->wpos != f->wbase\n\t\t? SEEK_END : SEEK_CUR);\n\tif (pos < 0) return pos;\n\n\t/* Adjust for data in buffer. */\n\tif (f->rend)\n\t\tpos += f->rpos - f->rend;\n\telse if (f->wbase)\n\t\tpos += f->wpos - f->wbase;\n\treturn pos;\n}\n\noff_t __ftello(FILE *f)\n{\n\toff_t pos;\n\tFLOCK(f);\n\tpos = __ftello_unlocked(f);\n\tFUNLOCK(f);\n\treturn pos;\n}\n\nlong ftell(FILE *f)\n{\n\toff_t pos = __ftello(f);\n\tif (pos > LONG_MAX) {\n\t\terrno = EOVERFLOW;\n\t\treturn -1;\n\t}\n\treturn pos;\n}\n\nweak_alias(__ftello, ftello);\n\nweak_alias(ftello, ftello64);\n"
  },
  {
    "path": "user.libc/src/stdio/ftrylockfile.c",
    "content": "#include \"stdio_impl.h\"\n#include \"pthread_impl.h\"\n#include <limits.h>\n\nvoid __do_orphaned_stdio_locks()\n{\n\tFILE *f;\n\tfor (f=__pthread_self()->stdio_locks; f; f=f->next_locked)\n\t\ta_store(&f->lock, 0x40000000);\n}\n\nvoid __unlist_locked_file(FILE *f)\n{\n\tif (f->lockcount) {\n\t\tif (f->next_locked) f->next_locked->prev_locked = f->prev_locked;\n\t\tif (f->prev_locked) f->prev_locked->next_locked = f->next_locked;\n\t\telse __pthread_self()->stdio_locks = f->next_locked;\n\t}\n}\n\nvoid __register_locked_file(FILE *f, pthread_t self)\n{\n\tf->lockcount = 1;\n\tf->prev_locked = 0;\n\tf->next_locked = self->stdio_locks;\n\tif (f->next_locked) f->next_locked->prev_locked = f;\n\tself->stdio_locks = f;\n}\n\nint ftrylockfile(FILE *f)\n{\n\tpthread_t self = __pthread_self();\n\tint tid = self->tid;\n\tint owner = f->lock;\n\tif ((owner & ~MAYBE_WAITERS) == tid) {\n\t\tif (f->lockcount == LONG_MAX)\n\t\t\treturn -1;\n\t\tf->lockcount++;\n\t\treturn 0;\n\t}\n\tif (owner < 0) f->lock = owner = 0;\n\tif (owner || a_cas(&f->lock, 0, tid))\n\t\treturn -1;\n\t__register_locked_file(f, self);\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/funlockfile.c",
    "content": "#include \"stdio_impl.h\"\n#include \"pthread_impl.h\"\n\nvoid funlockfile(FILE *f)\n{\n\tif (f->lockcount == 1) {\n\t\t__unlist_locked_file(f);\n\t\tf->lockcount = 0;\n\t\t__unlockfile(f);\n\t} else {\n\t\tf->lockcount--;\n\t}\n}\n"
  },
  {
    "path": "user.libc/src/stdio/fwide.c",
    "content": "#include <wchar.h>\n#include \"stdio_impl.h\"\n#include \"locale_impl.h\"\n\nint fwide(FILE *f, int mode)\n{\n\tFLOCK(f);\n\tif (mode) {\n\t\tif (!f->locale) f->locale = MB_CUR_MAX==1\n\t\t\t? C_LOCALE : UTF8_LOCALE;\n\t\tif (!f->mode) f->mode = mode>0 ? 1 : -1;\n\t}\n\tmode = f->mode;\n\tFUNLOCK(f);\n\treturn mode;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/fwprintf.c",
    "content": "#include <stdio.h>\n#include <stdarg.h>\n#include <wchar.h>\n\nint fwprintf(FILE *restrict f, const wchar_t *restrict fmt, ...)\n{\n\tint ret;\n\tva_list ap;\n\tva_start(ap, fmt);\n\tret = vfwprintf(f, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/fwrite.c",
    "content": "#include \"stdio_impl.h\"\n#include <string.h>\n\nsize_t __fwritex(const unsigned char *restrict s, size_t l, FILE *restrict f)\n{\n\tsize_t i=0;\n\n\tif (!f->wend && __towrite(f)) return 0;\n\n\tif (l > f->wend - f->wpos) return f->write(f, s, l);\n\n\tif (f->lbf >= 0) {\n\t\t/* Match /^(.*\\n|)/ */\n\t\tfor (i=l; i && s[i-1] != '\\n'; i--);\n\t\tif (i) {\n\t\t\tsize_t n = f->write(f, s, i);\n\t\t\tif (n < i) return n;\n\t\t\ts += i;\n\t\t\tl -= i;\n\t\t}\n\t}\n\n\tmemcpy(f->wpos, s, l);\n\tf->wpos += l;\n\treturn l+i;\n}\n\nsize_t fwrite(const void *restrict src, size_t size, size_t nmemb, FILE *restrict f)\n{\n\tsize_t k, l = size*nmemb;\n\tif (!size) nmemb = 0;\n\tFLOCK(f);\n\tk = __fwritex(src, l, f);\n\tFUNLOCK(f);\n\treturn k==l ? nmemb : k/size;\n}\n\nweak_alias(fwrite, fwrite_unlocked);\n"
  },
  {
    "path": "user.libc/src/stdio/fwscanf.c",
    "content": "#include <stdio.h>\n#include <stdarg.h>\n#include <wchar.h>\n\nint fwscanf(FILE *restrict f, const wchar_t *restrict fmt, ...)\n{\n\tint ret;\n\tva_list ap;\n\tva_start(ap, fmt);\n\tret = vfwscanf(f, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n\nweak_alias(fwscanf,__isoc99_fwscanf);\n"
  },
  {
    "path": "user.libc/src/stdio/getc.c",
    "content": "#include <stdio.h>\n#include \"getc.h\"\n\nint getc(FILE *f)\n{\n\treturn do_getc(f);\n}\n\nweak_alias(getc, _IO_getc);\n"
  },
  {
    "path": "user.libc/src/stdio/getc.h",
    "content": "#include \"stdio_impl.h\"\n#include \"pthread_impl.h\"\n\n#ifdef __GNUC__\n__attribute__((__noinline__))\n#endif\nstatic int locking_getc(FILE *f)\n{\n\tif (a_cas(&f->lock, 0, MAYBE_WAITERS-1)) __lockfile(f);\n\tint c = getc_unlocked(f);\n\tif (a_swap(&f->lock, 0) & MAYBE_WAITERS)\n\t\t__wake(&f->lock, 1, 1);\n\treturn c;\n}\n\nstatic inline int do_getc(FILE *f)\n{\n\tint l = f->lock;\n\tif (l < 0 || l && (l & ~MAYBE_WAITERS) == __pthread_self()->tid)\n\t\treturn getc_unlocked(f);\n\treturn locking_getc(f);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/getc_unlocked.c",
    "content": "#include \"stdio_impl.h\"\n\nint (getc_unlocked)(FILE *f)\n{\n\treturn getc_unlocked(f);\n}\n\nweak_alias (getc_unlocked, fgetc_unlocked);\nweak_alias (getc_unlocked, _IO_getc_unlocked);\n"
  },
  {
    "path": "user.libc/src/stdio/getchar.c",
    "content": "#include <stdio.h>\n#include \"getc.h\"\n\nint getchar(void)\n{\n\treturn do_getc(stdin);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/getchar_unlocked.c",
    "content": "#include \"stdio_impl.h\"\n\nint getchar_unlocked(void)\n{\n\treturn getc_unlocked(stdin);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/getdelim.c",
    "content": "#include \"stdio_impl.h\"\n#include <string.h>\n#include <stdlib.h>\n#include <inttypes.h>\n#include <errno.h>\n\nssize_t getdelim(char **restrict s, size_t *restrict n, int delim, FILE *restrict f)\n{\n\tchar *tmp;\n\tunsigned char *z;\n\tsize_t k;\n\tsize_t i=0;\n\tint c;\n\n\tFLOCK(f);\n\n\tif (!n || !s) {\n\t\tf->mode |= f->mode-1;\n\t\tf->flags |= F_ERR;\n\t\tFUNLOCK(f);\n\t\terrno = EINVAL;\n\t\treturn -1;\n\t}\n\n\tif (!*s) *n=0;\n\n\tfor (;;) {\n\t\tif (f->rpos != f->rend) {\n\t\t\tz = memchr(f->rpos, delim, f->rend - f->rpos);\n\t\t\tk = z ? z - f->rpos + 1 : f->rend - f->rpos;\n\t\t} else {\n\t\t\tz = 0;\n\t\t\tk = 0;\n\t\t}\n\t\tif (i+k >= *n) {\n\t\t\tsize_t m = i+k+2;\n\t\t\tif (!z && m < SIZE_MAX/4) m += m/2;\n\t\t\ttmp = realloc(*s, m);\n\t\t\tif (!tmp) {\n\t\t\t\tm = i+k+2;\n\t\t\t\ttmp = realloc(*s, m);\n\t\t\t\tif (!tmp) {\n\t\t\t\t\t/* Copy as much as fits and ensure no\n\t\t\t\t\t * pushback remains in the FILE buf. */\n\t\t\t\t\tk = *n-i;\n\t\t\t\t\tmemcpy(*s+i, f->rpos, k);\n\t\t\t\t\tf->rpos += k;\n\t\t\t\t\tf->mode |= f->mode-1;\n\t\t\t\t\tf->flags |= F_ERR;\n\t\t\t\t\tFUNLOCK(f);\n\t\t\t\t\terrno = ENOMEM;\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t}\n\t\t\t*s = tmp;\n\t\t\t*n = m;\n\t\t}\n\t\tmemcpy(*s+i, f->rpos, k);\n\t\tf->rpos += k;\n\t\ti += k;\n\t\tif (z) break;\n\t\tif ((c = getc_unlocked(f)) == EOF) {\n\t\t\tif (!i || !feof(f)) {\n\t\t\t\tFUNLOCK(f);\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\t/* If the byte read by getc won't fit without growing the\n\t\t * output buffer, push it back for next iteration. */\n\t\tif (i+1 >= *n) *--f->rpos = c;\n\t\telse if (((*s)[i++] = c) == delim) break;\n\t}\n\t(*s)[i] = 0;\n\n\tFUNLOCK(f);\n\n\treturn i;\n}\n\nweak_alias(getdelim, __getdelim);\n"
  },
  {
    "path": "user.libc/src/stdio/getline.c",
    "content": "#include <stdio.h>\n\nssize_t getline(char **restrict s, size_t *restrict n, FILE *restrict f)\n{\n\treturn getdelim(s, n, '\\n', f);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/gets.c",
    "content": "#include \"stdio_impl.h\"\n#include <limits.h>\n#include <string.h>\n\nchar *gets(char *s)\n{\n\tsize_t i=0;\n\tint c;\n\tFLOCK(stdin);\n\twhile ((c=getc_unlocked(stdin)) != EOF && c != '\\n') s[i++] = c;\n\ts[i] = 0;\n\tif (c != '\\n' && (!feof(stdin) || !i)) s = 0;\n\tFUNLOCK(stdin);\n\treturn s;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/getw.c",
    "content": "#define _GNU_SOURCE\n#include <stdio.h>\n\nint getw(FILE *f)\n{\n\tint x;\n\treturn fread(&x, sizeof x, 1, f) ? x : EOF;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/getwc.c",
    "content": "#include \"stdio_impl.h\"\n#include <wchar.h>\n\nwint_t getwc(FILE *f)\n{\n\treturn fgetwc(f);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/getwchar.c",
    "content": "#include \"stdio_impl.h\"\n#include <wchar.h>\n\nwint_t getwchar(void)\n{\n\treturn fgetwc(stdin);\n}\n\nweak_alias(getwchar, getwchar_unlocked);\n"
  },
  {
    "path": "user.libc/src/stdio/ofl.c",
    "content": "#include \"stdio_impl.h\"\n#include \"lock.h\"\n#include \"fork_impl.h\"\n\nstatic FILE *ofl_head;\nstatic volatile int ofl_lock[1];\nvolatile int *const __stdio_ofl_lockptr = ofl_lock;\n\nFILE **__ofl_lock()\n{\n\tLOCK(ofl_lock);\n\treturn &ofl_head;\n}\n\nvoid __ofl_unlock()\n{\n\tUNLOCK(ofl_lock);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/ofl_add.c",
    "content": "#include \"stdio_impl.h\"\n\nFILE *__ofl_add(FILE *f)\n{\n\tFILE **head = __ofl_lock();\n\tf->next = *head;\n\tif (*head) (*head)->prev = f;\n\t*head = f;\n\t__ofl_unlock();\n\treturn f;\n}\n\nstatic FILE *__ofl_do_get_file(FILE *head, int fd)\n{\n\twhile (head) {\n\t\tif (head->fd == fd)\n\t\t\treturn head;\n\t\thead = head->next;\n\t}\n\n\treturn NULL;\n}\n\nFILE *__ofl_get_file(int fd)\n{\n\tFILE *file = NULL;\n\tFILE **head = __ofl_lock();\n\n\t/*\n\t * for performance reason, will change to rb-tree\n\t * later.\n\t */\n\tfile = __ofl_do_get_file(*head, fd);\n\t__ofl_unlock();\n\n\treturn file;\n}\n\nFILE *__ofl_del_fd(int fd)\n{\n\tFILE *f = NULL;\n\tFILE **head = __ofl_lock();\n\n\tf = __ofl_do_get_file(*head, fd);\n\tif (!f)\n\t\tgoto out;\n\n\tif (f->prev) f->prev->next = f->next;\n\tif (f->next) f->next->prev = f->prev;\n\tif (*head == f) *head = f->next;\nout:\n\t__ofl_unlock();\n\n\treturn f;\n}\n\nvoid *__ofl_del(FILE *f)\n{\n\tFILE **head = __ofl_lock();\n\tif (f->prev) f->prev->next = f->next;\n\tif (f->next) f->next->prev = f->prev;\n\tif (*head == f) *head = f->next;\n\t__ofl_unlock();\n}\n"
  },
  {
    "path": "user.libc/src/stdio/open_memstream.c",
    "content": "#include \"stdio_impl.h\"\n#include <errno.h>\n#include <limits.h>\n#include <string.h>\n#include <stdlib.h>\n#include \"libc.h\"\n\nstruct cookie {\n\tchar **bufp;\n\tsize_t *sizep;\n\tsize_t pos;\n\tchar *buf;\n\tsize_t len;\n\tsize_t space;\n};\n\nstruct ms_FILE {\n\tFILE f;\n\tstruct cookie c;\n\tunsigned char buf[BUFSIZ];\n};\n\nstatic off_t ms_seek(FILE *f, off_t off, int whence)\n{\n\tssize_t base;\n\tstruct cookie *c = f->cookie;\n\tif (whence>2U) {\nfail:\n\t\terrno = EINVAL;\n\t\treturn -1;\n\t}\n\tbase = (size_t [3]){0, c->pos, c->len}[whence];\n\tif (off < -base || off > SSIZE_MAX-base) goto fail;\n\treturn c->pos = base+off;\n}\n\nstatic size_t ms_write(FILE *f, const unsigned char *buf, size_t len)\n{\n\tstruct cookie *c = f->cookie;\n\tsize_t len2 = f->wpos - f->wbase;\n\tchar *newbuf;\n\tif (len2) {\n\t\tf->wpos = f->wbase;\n\t\tif (ms_write(f, f->wbase, len2) < len2) return 0;\n\t}\n\tif (len + c->pos >= c->space) {\n\t\tlen2 = 2*c->space+1 | c->pos+len+1;\n\t\tnewbuf = realloc(c->buf, len2);\n\t\tif (!newbuf) return 0;\n\t\t*c->bufp = c->buf = newbuf;\n\t\tmemset(c->buf + c->space, 0, len2 - c->space);\n\t\tc->space = len2;\n\t}\n\tmemcpy(c->buf+c->pos, buf, len);\n\tc->pos += len;\n\tif (c->pos >= c->len) c->len = c->pos;\n\t*c->sizep = c->pos;\n\treturn len;\n}\n\nstatic int ms_close(FILE *f)\n{\n\treturn 0;\n}\n\nFILE *open_memstream(char **bufp, size_t *sizep)\n{\n\tstruct ms_FILE *f;\n\tchar *buf;\n\n\tif (!(f=malloc(sizeof *f))) return 0;\n\tif (!(buf=malloc(sizeof *buf))) {\n\t\tfree(f);\n\t\treturn 0;\n\t}\n\tmemset(&f->f, 0, sizeof f->f);\n\tmemset(&f->c, 0, sizeof f->c);\n\tf->f.cookie = &f->c;\n\n\tf->c.bufp = bufp;\n\tf->c.sizep = sizep;\n\tf->c.pos = f->c.len = f->c.space = *sizep = 0;\n\tf->c.buf = *bufp = buf;\n\t*buf = 0;\n\n\tf->f.flags = F_NORD;\n\tf->f.fd = -1;\n\tf->f.buf = f->buf;\n\tf->f.buf_size = sizeof f->buf;\n\tf->f.lbf = EOF;\n\tf->f.write = ms_write;\n\tf->f.seek = ms_seek;\n\tf->f.close = ms_close;\n\tf->f.mode = -1;\n\n\tif (!libc.threaded) f->f.lock = -1;\n\n\treturn __ofl_add(&f->f);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/open_wmemstream.c",
    "content": "#include \"stdio_impl.h\"\n#include <wchar.h>\n#include <errno.h>\n#include <limits.h>\n#include <string.h>\n#include <stdlib.h>\n#include \"libc.h\"\n\nstruct cookie {\n\twchar_t **bufp;\n\tsize_t *sizep;\n\tsize_t pos;\n\twchar_t *buf;\n\tsize_t len;\n\tsize_t space;\n\tmbstate_t mbs;\n};\n\nstruct wms_FILE {\n\tFILE f;\n\tstruct cookie c;\n\tunsigned char buf[1];\n};\n\nstatic off_t wms_seek(FILE *f, off_t off, int whence)\n{\n\tssize_t base;\n\tstruct cookie *c = f->cookie;\n\tif (whence>2U) {\nfail:\n\t\terrno = EINVAL;\n\t\treturn -1;\n\t}\n\tbase = (size_t [3]){0, c->pos, c->len}[whence];\n\tif (off < -base || off > SSIZE_MAX/4-base) goto fail;\n\tmemset(&c->mbs, 0, sizeof c->mbs);\n\treturn c->pos = base+off;\n}\n\nstatic size_t wms_write(FILE *f, const unsigned char *buf, size_t len)\n{\n\tstruct cookie *c = f->cookie;\n\tsize_t len2;\n\twchar_t *newbuf;\n\tif (len + c->pos >= c->space) {\n\t\tlen2 = 2*c->space+1 | c->pos+len+1;\n\t\tif (len2 > SSIZE_MAX/4) return 0;\n\t\tnewbuf = realloc(c->buf, len2*4);\n\t\tif (!newbuf) return 0;\n\t\t*c->bufp = c->buf = newbuf;\n\t\tmemset(c->buf + c->space, 0, 4*(len2 - c->space));\n\t\tc->space = len2;\n\t}\n\t\n\tlen2 = mbsnrtowcs(c->buf+c->pos, (void *)&buf, len, c->space-c->pos, &c->mbs);\n\tif (len2 == -1) return 0;\n\tc->pos += len2;\n\tif (c->pos >= c->len) c->len = c->pos;\n\t*c->sizep = c->pos;\n\treturn len;\n}\n\nstatic int wms_close(FILE *f)\n{\n\treturn 0;\n}\n\nFILE *open_wmemstream(wchar_t **bufp, size_t *sizep)\n{\n\tstruct wms_FILE *f;\n\twchar_t *buf;\n\n\tif (!(f=malloc(sizeof *f))) return 0;\n\tif (!(buf=malloc(sizeof *buf))) {\n\t\tfree(f);\n\t\treturn 0;\n\t}\n\tmemset(&f->f, 0, sizeof f->f);\n\tmemset(&f->c, 0, sizeof f->c);\n\tf->f.cookie = &f->c;\n\n\tf->c.bufp = bufp;\n\tf->c.sizep = sizep;\n\tf->c.pos = f->c.len = f->c.space = *sizep = 0;\n\tf->c.buf = *bufp = buf;\n\t*buf = 0;\n\n\tf->f.flags = F_NORD;\n\tf->f.fd = -1;\n\tf->f.buf = f->buf;\n\tf->f.buf_size = 0;\n\tf->f.lbf = EOF;\n\tf->f.write = wms_write;\n\tf->f.seek = wms_seek;\n\tf->f.close = wms_close;\n\n\tif (!libc.threaded) f->f.lock = -1;\n\n\tfwide(&f->f, 1);\n\n\treturn __ofl_add(&f->f);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/perror.c",
    "content": "#include <stdio.h>\n#include <string.h>\n#include <errno.h>\n#include \"stdio_impl.h\"\n\nvoid perror(const char *msg)\n{\n\tFILE *f = stderr;\n\tchar *errstr = strerror(errno);\n\n\tFLOCK(f);\n\n\t/* Save stderr's orientation and encoding rule, since perror is not\n\t * permitted to change them. */\n\tvoid *old_locale = f->locale;\n\tint old_mode = f->mode;\n\t\n\tif (msg && *msg) {\n\t\tfwrite(msg, strlen(msg), 1, f);\n\t\tfputc(':', f);\n\t\tfputc(' ', f);\n\t}\n\tfwrite(errstr, strlen(errstr), 1, f);\n\tfputc('\\n', f);\n\n\tf->mode = old_mode;\n\tf->locale = old_locale;\n\n\tFUNLOCK(f);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/popen.c",
    "content": "#include <fcntl.h>\n#include <unistd.h>\n#include <errno.h>\n#include <string.h>\n#include <spawn.h>\n#include \"stdio_impl.h\"\n#include \"syscall.h\"\n\nextern char **__environ;\n\nFILE *popen(const char *cmd, const char *mode)\n{\n#if 0\n\tint p[2], op, e;\n\tpid_t pid;\n\tFILE *f;\n\tposix_spawn_file_actions_t fa;\n\n\tif (*mode == 'r') {\n\t\top = 0;\n\t} else if (*mode == 'w') {\n\t\top = 1;\n\t} else {\n\t\terrno = EINVAL;\n\t\treturn 0;\n\t}\n\t\n\tif (pipe2(p, O_CLOEXEC)) return NULL;\n\tf = fdopen(p[op], mode);\n\tif (!f) {\n\t\t__syscall(SYS_close, p[0]);\n\t\t__syscall(SYS_close, p[1]);\n\t\treturn NULL;\n\t}\n\tFLOCK(f);\n\n\t/* If the child's end of the pipe happens to already be on the final\n\t * fd number to which it will be assigned (either 0 or 1), it must\n\t * be moved to a different fd. Otherwise, there is no safe way to\n\t * remove the close-on-exec flag in the child without also creating\n\t * a file descriptor leak race condition in the parent. */\n\tif (p[1-op] == 1-op) {\n\t\tint tmp = fcntl(1-op, F_DUPFD_CLOEXEC, 0);\n\t\tif (tmp < 0) {\n\t\t\te = errno;\n\t\t\tgoto fail;\n\t\t}\n\t\t__syscall(SYS_close, p[1-op]);\n\t\tp[1-op] = tmp;\n\t}\n\n\te = ENOMEM;\n\tif (!posix_spawn_file_actions_init(&fa)) {\n\t\tif (!posix_spawn_file_actions_adddup2(&fa, p[1-op], 1-op)) {\n\t\t\tif (!(e = posix_spawn(&pid, \"/bin/sh\", &fa, 0,\n\t\t\t    (char *[]){ \"sh\", \"-c\", (char *)cmd, 0 }, __environ))) {\n\t\t\t\tposix_spawn_file_actions_destroy(&fa);\n\t\t\t\tf->pipe_pid = pid;\n\t\t\t\tif (!strchr(mode, 'e'))\n\t\t\t\t\tfcntl(p[op], F_SETFD, 0);\n\t\t\t\t__syscall(SYS_close, p[1-op]);\n\t\t\t\tFUNLOCK(f);\n\t\t\t\treturn f;\n\t\t\t}\n\t\t}\n\t\tposix_spawn_file_actions_destroy(&fa);\n\t}\nfail:\n\tfclose(f);\n\t__syscall(SYS_close, p[1-op]);\n\n\terrno = e;\n#endif\n\treturn NULL;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/printf.c",
    "content": "#include <stdio.h>\n#include <stdarg.h>\n\nint printf(const char *restrict fmt, ...)\n{\n\tint ret;\n\tva_list ap;\n\tva_start(ap, fmt);\n\tret = vfprintf(stdout, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/putc.c",
    "content": "#include <stdio.h>\n#include \"putc.h\"\n\nint putc(int c, FILE *f)\n{\n\treturn do_putc(c, f);\n}\n\nweak_alias(putc, _IO_putc);\n"
  },
  {
    "path": "user.libc/src/stdio/putc.h",
    "content": "#include \"stdio_impl.h\"\n#include \"pthread_impl.h\"\n\n#ifdef __GNUC__\n__attribute__((__noinline__))\n#endif\nstatic int locking_putc(int c, FILE *f)\n{\n\tif (a_cas(&f->lock, 0, MAYBE_WAITERS-1)) __lockfile(f);\n\tc = putc_unlocked(c, f);\n\tif (a_swap(&f->lock, 0) & MAYBE_WAITERS)\n\t\t__wake(&f->lock, 1, 1);\n\treturn c;\n}\n\nstatic inline int do_putc(int c, FILE *f)\n{\n\tint l = f->lock;\n\tif (l < 0 || l && (l & ~MAYBE_WAITERS) == __pthread_self()->tid)\n\t\treturn putc_unlocked(c, f);\n\treturn locking_putc(c, f);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/putc_unlocked.c",
    "content": "#include \"stdio_impl.h\"\n\nint (putc_unlocked)(int c, FILE *f)\n{\n\treturn putc_unlocked(c, f);\n}\n\nweak_alias(putc_unlocked, fputc_unlocked);\nweak_alias(putc_unlocked, _IO_putc_unlocked);\n"
  },
  {
    "path": "user.libc/src/stdio/putchar.c",
    "content": "#include <stdio.h>\n#include \"putc.h\"\n\nint putchar(int c)\n{\n\treturn do_putc(c, stdout);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/putchar_unlocked.c",
    "content": "#include \"stdio_impl.h\"\n\nint putchar_unlocked(int c)\n{\n\treturn putc_unlocked(c, stdout);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/puts.c",
    "content": "#include \"stdio_impl.h\"\n\nint puts(const char *s)\n{\n\tint r;\n\tFLOCK(stdout);\n\tr = -(fputs(s, stdout) < 0 || putc_unlocked('\\n', stdout) < 0);\n\tFUNLOCK(stdout);\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/putw.c",
    "content": "#define _GNU_SOURCE\n#include <stdio.h>\n\nint putw(int x, FILE *f)\n{\n\treturn (int)fwrite(&x, sizeof x, 1, f)-1;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/putwc.c",
    "content": "#include \"stdio_impl.h\"\n#include <wchar.h>\n\nwint_t putwc(wchar_t c, FILE *f)\n{\n\treturn fputwc(c, f);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/putwchar.c",
    "content": "#include \"stdio_impl.h\"\n#include <wchar.h>\n\nwint_t putwchar(wchar_t c)\n{\n\treturn fputwc(c, stdout);\n}\n\nweak_alias(putwchar, putwchar_unlocked);\n"
  },
  {
    "path": "user.libc/src/stdio/rewind.c",
    "content": "#include \"stdio_impl.h\"\n\nvoid rewind(FILE *f)\n{\n\tFLOCK(f);\n\t__fseeko_unlocked(f, 0, SEEK_SET);\n\tf->flags &= ~F_ERR;\n\tFUNLOCK(f);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/scanf.c",
    "content": "#include <stdio.h>\n#include <stdarg.h>\n\nint scanf(const char *restrict fmt, ...)\n{\n\tint ret;\n\tva_list ap;\n\tva_start(ap, fmt);\n\tret = vscanf(fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n\nweak_alias(scanf,__isoc99_scanf);\n"
  },
  {
    "path": "user.libc/src/stdio/setbuf.c",
    "content": "#include <stdio.h>\n\nvoid setbuf(FILE *restrict f, char *restrict buf)\n{\n\tsetvbuf(f, buf, buf ? _IOFBF : _IONBF, BUFSIZ);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/setbuffer.c",
    "content": "#define _GNU_SOURCE\n#include <stdio.h>\n\nvoid setbuffer(FILE *f, char *buf, size_t size)\n{\n\tsetvbuf(f, buf, buf ? _IOFBF : _IONBF, size);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/setlinebuf.c",
    "content": "#define _GNU_SOURCE\n#include <stdio.h>\n\nvoid setlinebuf(FILE *f)\n{\n\tsetvbuf(f, 0, _IOLBF, 0);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/setvbuf.c",
    "content": "#include \"stdio_impl.h\"\n\n/* The behavior of this function is undefined except when it is the first\n * operation on the stream, so the presence or absence of locking is not\n * observable in a program whose behavior is defined. Thus no locking is\n * performed here. No allocation of buffers is performed, but a buffer\n * provided by the caller is used as long as it is suitably sized. */\n\nint setvbuf(FILE *restrict f, char *restrict buf, int type, size_t size)\n{\n\tf->lbf = EOF;\n\n\tif (type == _IONBF) {\n\t\tf->buf_size = 0;\n\t} else if (type == _IOLBF || type == _IOFBF) {\n\t\tif (buf && size >= UNGET) {\n\t\t\tf->buf = (void *)(buf + UNGET);\n\t\t\tf->buf_size = size - UNGET;\n\t\t}\n\t\tif (type == _IOLBF && f->buf_size)\n\t\t\tf->lbf = '\\n';\n\t} else {\n\t\treturn -1;\n\t}\n\n\tf->flags |= F_SVB;\n\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/snprintf.c",
    "content": "#include <stdio.h>\n#include <stdarg.h>\n\nint snprintf(char *restrict s, size_t n, const char *restrict fmt, ...)\n{\n\tint ret;\n\tva_list ap;\n\tva_start(ap, fmt);\n\tret = vsnprintf(s, n, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n\n"
  },
  {
    "path": "user.libc/src/stdio/sprintf.c",
    "content": "#include <stdio.h>\n#include <stdarg.h>\n\nint sprintf(char *restrict s, const char *restrict fmt, ...)\n{\n\tint ret;\n\tva_list ap;\n\tva_start(ap, fmt);\n\tret = vsprintf(s, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/sscanf.c",
    "content": "#include <stdio.h>\n#include <stdarg.h>\n\nint sscanf(const char *restrict s, const char *restrict fmt, ...)\n{\n\tint ret;\n\tva_list ap;\n\tva_start(ap, fmt);\n\tret = vsscanf(s, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n\nweak_alias(sscanf,__isoc99_sscanf);\n"
  },
  {
    "path": "user.libc/src/stdio/stderr.c",
    "content": "#include \"stdio_impl.h\"\n\n#undef stderr\n\nstatic size_t __stderr_write(FILE *f, const unsigned char *buf, size_t len)\n{\n\treturn __stdout_write(f, buf, len);\n}\n\nstatic off_t __stderr_seek(FILE *f, off_t off, int whence)\n{\n\treturn 0;\n}\n\nstatic int __stderr_close(FILE *f)\n{\n\treturn __stdio_close(f);\n}\n\nhidden FILE __stderr_FILE = {\n\t.buf = NULL,\n\t.buf_size = 0,\n\t.fd = 3,\n\t.flags = F_PERM | F_NORD,\n\t.lbf = -1,\n\t.write = __stderr_write,\n\t.seek = __stderr_seek,\n\t.close = __stderr_close,\n\t.lock = -1,\n};\nFILE *const stderr = &__stderr_FILE;\nFILE *volatile __stderr_used = &__stderr_FILE;\n"
  },
  {
    "path": "user.libc/src/stdio/stdin.c",
    "content": "#include \"stdio_impl.h\"\n\n#undef stdin\n#include <minos/kobject.h>\n\nextern hidden int __stdio_close(FILE *f);\n\nstatic size_t __stdin_read(FILE *f, unsigned char *buf, size_t len)\n{\n\tsize_t read_size;\n\tlong ret;\n\n\tret = kobject_read(f->fd, buf, len, &read_size, NULL, 0, NULL, 0);\n\tif (ret < 0) {\n\t\tf->flags |= F_ERR;\n\t\treturn 0;\n\t}\n\n\treturn read_size;\n}\n\nstatic off_t __stdin_seek(FILE *f, off_t off, int whence)\n{\n\treturn 0;\n}\n\nstatic int __stdin_close(FILE *f)\n{\n\treturn __stdio_close(f);\n}\n\nhidden FILE __stdin_FILE = {\n\t.buf = NULL,\n\t.buf_size = 0,\n\t.fd = 1,\n\t.flags = F_PERM | F_NOWR | F_STREAM,\n\t.read = __stdin_read,\n\t.seek = __stdin_seek,\n\t.close = __stdin_close,\n\t.lock = -1,\n};\nFILE *const stdin = &__stdin_FILE;\nFILE *volatile __stdin_used = &__stdin_FILE;\n"
  },
  {
    "path": "user.libc/src/stdio/stdout.c",
    "content": "#include \"stdio_impl.h\"\n\n#undef stdout\n\nstatic unsigned char buf[BUFSIZ+UNGET];\nhidden FILE __stdout_FILE = {\n\t.buf = buf+UNGET,\n\t.buf_size = sizeof buf-UNGET,\n\t.fd = 2,\n\t.flags = F_PERM | F_NORD,\n\t.lbf = '\\n',\n\t.write = __stdout_write,\n\t.seek = __stdio_seek,\n\t.close = __stdio_close,\n\t.lock = -1,\n};\nFILE *const stdout = &__stdout_FILE;\nFILE *volatile __stdout_used = &__stdout_FILE;\n"
  },
  {
    "path": "user.libc/src/stdio/swprintf.c",
    "content": "#include <stdarg.h>\n#include <wchar.h>\n\nint swprintf(wchar_t *restrict s, size_t n, const wchar_t *restrict fmt, ...)\n{\n\tint ret;\n\tva_list ap;\n\tva_start(ap, fmt);\n\tret = vswprintf(s, n, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n\n"
  },
  {
    "path": "user.libc/src/stdio/swscanf.c",
    "content": "#include <stdarg.h>\n#include <wchar.h>\n\nint swscanf(const wchar_t *restrict s, const wchar_t *restrict fmt, ...)\n{\n\tint ret;\n\tva_list ap;\n\tva_start(ap, fmt);\n\tret = vswscanf(s, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n\nweak_alias(swscanf,__isoc99_swscanf);\n"
  },
  {
    "path": "user.libc/src/stdio/ungetc.c",
    "content": "#include \"stdio_impl.h\"\n\nint ungetc(int c, FILE *f)\n{\n\tif (c == EOF) return c;\n\n\tFLOCK(f);\n\n\tif (!f->rpos) __toread(f);\n\tif (!f->rpos || f->rpos <= f->buf - UNGET) {\n\t\tFUNLOCK(f);\n\t\treturn EOF;\n\t}\n\n\t*--f->rpos = c;\n\tf->flags &= ~F_EOF;\n\n\tFUNLOCK(f);\n\treturn (unsigned char)c;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/ungetwc.c",
    "content": "#include \"stdio_impl.h\"\n#include \"locale_impl.h\"\n#include <wchar.h>\n#include <limits.h>\n#include <ctype.h>\n#include <string.h>\n\nwint_t ungetwc(wint_t c, FILE *f)\n{\n\tunsigned char mbc[MB_LEN_MAX];\n\tint l;\n\tlocale_t *ploc = &CURRENT_LOCALE, loc = *ploc;\n\n\tFLOCK(f);\n\n\tif (f->mode <= 0) fwide(f, 1);\n\t*ploc = f->locale;\n\n\tif (!f->rpos) __toread(f);\n\tif (!f->rpos || c == WEOF || (l = wcrtomb((void *)mbc, c, 0)) < 0 ||\n\t    f->rpos < f->buf - UNGET + l) {\n\t\tFUNLOCK(f);\n\t\t*ploc = loc;\n\t\treturn WEOF;\n\t}\n\n\tif (isascii(c)) *--f->rpos = c;\n\telse memcpy(f->rpos -= l, mbc, l);\n\n\tf->flags &= ~F_EOF;\n\n\tFUNLOCK(f);\n\t*ploc = loc;\n\treturn c;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/vasprintf.c",
    "content": "#define _GNU_SOURCE\n#include <stdio.h>\n#include <stdarg.h>\n#include <stdlib.h>\n\nint vasprintf(char **s, const char *fmt, va_list ap)\n{\n\tva_list ap2;\n\tva_copy(ap2, ap);\n\tint l = vsnprintf(0, 0, fmt, ap2);\n\tva_end(ap2);\n\n\tif (l<0 || !(*s=malloc(l+1U))) return -1;\n\treturn vsnprintf(*s, l+1U, fmt, ap);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/vdprintf.c",
    "content": "#include \"stdio_impl.h\"\n\nint vdprintf(int fd, const char *restrict fmt, va_list ap)\n{\n\tFILE f = {\n\t\t.fd = fd, .lbf = EOF, .write = __stdio_write,\n\t\t.buf = (void *)fmt, .buf_size = 0,\n\t\t.lock = -1\n\t};\n\treturn vfprintf(&f, fmt, ap);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/vfprintf.c",
    "content": "#include \"stdio_impl.h\"\n#include <errno.h>\n#include <ctype.h>\n#include <limits.h>\n#include <string.h>\n#include <stdarg.h>\n#include <stddef.h>\n#include <stdlib.h>\n#include <wchar.h>\n#include <inttypes.h>\n#include <math.h>\n#include <float.h>\n\n/* Some useful macros */\n\n#define MAX(a,b) ((a)>(b) ? (a) : (b))\n#define MIN(a,b) ((a)<(b) ? (a) : (b))\n\n/* Convenient bit representation for modifier flags, which all fall\n * within 31 codepoints of the space character. */\n\n#define ALT_FORM   (1U<<'#'-' ')\n#define ZERO_PAD   (1U<<'0'-' ')\n#define LEFT_ADJ   (1U<<'-'-' ')\n#define PAD_POS    (1U<<' '-' ')\n#define MARK_POS   (1U<<'+'-' ')\n#define GROUPED    (1U<<'\\''-' ')\n\n#define FLAGMASK (ALT_FORM|ZERO_PAD|LEFT_ADJ|PAD_POS|MARK_POS|GROUPED)\n\n/* State machine to accept length modifiers + conversion specifiers.\n * Result is 0 on failure, or an argument type to pop on success. */\n\nenum {\n\tBARE, LPRE, LLPRE, HPRE, HHPRE, BIGLPRE,\n\tZTPRE, JPRE,\n\tSTOP,\n\tPTR, INT, UINT, ULLONG,\n\tLONG, ULONG,\n\tSHORT, USHORT, CHAR, UCHAR,\n\tLLONG, SIZET, IMAX, UMAX, PDIFF, UIPTR,\n\tDBL, LDBL,\n\tNOARG,\n\tMAXSTATE\n};\n\n#define S(x) [(x)-'A']\n\nstatic const unsigned char states[]['z'-'A'+1] = {\n\t{ /* 0: bare types */\n\t\tS('d') = INT, S('i') = INT,\n\t\tS('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT,\n\t\tS('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,\n\t\tS('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,\n\t\tS('c') = CHAR, S('C') = INT,\n\t\tS('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR,\n\t\tS('m') = NOARG,\n\t\tS('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,\n\t\tS('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE,\n\t}, { /* 1: l-prefixed */\n\t\tS('d') = LONG, S('i') = LONG,\n\t\tS('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG,\n\t\tS('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,\n\t\tS('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,\n\t\tS('c') = INT, S('s') = PTR, S('n') = PTR,\n\t\tS('l') = LLPRE,\n\t}, { /* 2: ll-prefixed */\n\t\tS('d') = LLONG, S('i') = LLONG,\n\t\tS('o') = ULLONG, S('u') = ULLONG,\n\t\tS('x') = ULLONG, S('X') = ULLONG,\n\t\tS('n') = PTR,\n\t}, { /* 3: h-prefixed */\n\t\tS('d') = SHORT, S('i') = SHORT,\n\t\tS('o') = USHORT, S('u') = USHORT,\n\t\tS('x') = USHORT, S('X') = USHORT,\n\t\tS('n') = PTR,\n\t\tS('h') = HHPRE,\n\t}, { /* 4: hh-prefixed */\n\t\tS('d') = CHAR, S('i') = CHAR,\n\t\tS('o') = UCHAR, S('u') = UCHAR,\n\t\tS('x') = UCHAR, S('X') = UCHAR,\n\t\tS('n') = PTR,\n\t}, { /* 5: L-prefixed */\n\t\tS('e') = LDBL, S('f') = LDBL, S('g') = LDBL, S('a') = LDBL,\n\t\tS('E') = LDBL, S('F') = LDBL, S('G') = LDBL, S('A') = LDBL,\n\t\tS('n') = PTR,\n\t}, { /* 6: z- or t-prefixed (assumed to be same size) */\n\t\tS('d') = PDIFF, S('i') = PDIFF,\n\t\tS('o') = SIZET, S('u') = SIZET,\n\t\tS('x') = SIZET, S('X') = SIZET,\n\t\tS('n') = PTR,\n\t}, { /* 7: j-prefixed */\n\t\tS('d') = IMAX, S('i') = IMAX,\n\t\tS('o') = UMAX, S('u') = UMAX,\n\t\tS('x') = UMAX, S('X') = UMAX,\n\t\tS('n') = PTR,\n\t}\n};\n\n#define OOB(x) ((unsigned)(x)-'A' > 'z'-'A')\n\nunion arg\n{\n\tuintmax_t i;\n\tlong double f;\n\tvoid *p;\n};\n\nstatic void pop_arg(union arg *arg, int type, va_list *ap)\n{\n\tswitch (type) {\n\t       case PTR:\targ->p = va_arg(*ap, void *);\n\tbreak; case INT:\targ->i = va_arg(*ap, int);\n\tbreak; case UINT:\targ->i = va_arg(*ap, unsigned int);\n\tbreak; case LONG:\targ->i = va_arg(*ap, long);\n\tbreak; case ULONG:\targ->i = va_arg(*ap, unsigned long);\n\tbreak; case ULLONG:\targ->i = va_arg(*ap, unsigned long long);\n\tbreak; case SHORT:\targ->i = (short)va_arg(*ap, int);\n\tbreak; case USHORT:\targ->i = (unsigned short)va_arg(*ap, int);\n\tbreak; case CHAR:\targ->i = (signed char)va_arg(*ap, int);\n\tbreak; case UCHAR:\targ->i = (unsigned char)va_arg(*ap, int);\n\tbreak; case LLONG:\targ->i = va_arg(*ap, long long);\n\tbreak; case SIZET:\targ->i = va_arg(*ap, size_t);\n\tbreak; case IMAX:\targ->i = va_arg(*ap, intmax_t);\n\tbreak; case UMAX:\targ->i = va_arg(*ap, uintmax_t);\n\tbreak; case PDIFF:\targ->i = va_arg(*ap, ptrdiff_t);\n\tbreak; case UIPTR:\targ->i = (uintptr_t)va_arg(*ap, void *);\n\tbreak; case DBL:\targ->f = va_arg(*ap, double);\n\tbreak; case LDBL:\targ->f = va_arg(*ap, long double);\n\t}\n}\n\nstatic void out(FILE *f, const char *s, size_t l)\n{\n\tif (!(f->flags & F_ERR)) __fwritex((void *)s, l, f);\n}\n\nstatic void pad(FILE *f, char c, int w, int l, int fl)\n{\n\tchar pad[256];\n\tif (fl & (LEFT_ADJ | ZERO_PAD) || l >= w) return;\n\tl = w - l;\n\tmemset(pad, c, l>sizeof pad ? sizeof pad : l);\n\tfor (; l >= sizeof pad; l -= sizeof pad)\n\t\tout(f, pad, sizeof pad);\n\tout(f, pad, l);\n}\n\nstatic const char xdigits[16] = {\n\t\"0123456789ABCDEF\"\n};\n\nstatic char *fmt_x(uintmax_t x, char *s, int lower)\n{\n\tfor (; x; x>>=4) *--s = xdigits[(x&15)]|lower;\n\treturn s;\n}\n\nstatic char *fmt_o(uintmax_t x, char *s)\n{\n\tfor (; x; x>>=3) *--s = '0' + (x&7);\n\treturn s;\n}\n\nstatic char *fmt_u(uintmax_t x, char *s)\n{\n\tunsigned long y;\n\tfor (   ; x>ULONG_MAX; x/=10) *--s = '0' + x%10;\n\tfor (y=x;           y; y/=10) *--s = '0' + y%10;\n\treturn s;\n}\n\n/* Do not override this check. The floating point printing code below\n * depends on the float.h constants being right. If they are wrong, it\n * may overflow the stack. */\n#if LDBL_MANT_DIG == 53\ntypedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double)];\n#endif\n\nstatic int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t)\n{\n\tuint32_t big[(LDBL_MANT_DIG+28)/29 + 1          // mantissa expansion\n\t\t+ (LDBL_MAX_EXP+LDBL_MANT_DIG+28+8)/9]; // exponent expansion\n\tuint32_t *a, *d, *r, *z;\n\tint e2=0, e, i, j, l;\n\tchar buf[9+LDBL_MANT_DIG/4], *s;\n\tconst char *prefix=\"-0X+0X 0X-0x+0x 0x\";\n\tint pl;\n\tchar ebuf0[3*sizeof(int)], *ebuf=&ebuf0[3*sizeof(int)], *estr;\n\n\tpl=1;\n\tif (signbit(y)) {\n\t\ty=-y;\n\t} else if (fl & MARK_POS) {\n\t\tprefix+=3;\n\t} else if (fl & PAD_POS) {\n\t\tprefix+=6;\n\t} else prefix++, pl=0;\n\n\tif (!isfinite(y)) {\n\t\tchar *s = (t&32)?\"inf\":\"INF\";\n\t\tif (y!=y) s=(t&32)?\"nan\":\"NAN\";\n\t\tpad(f, ' ', w, 3+pl, fl&~ZERO_PAD);\n\t\tout(f, prefix, pl);\n\t\tout(f, s, 3);\n\t\tpad(f, ' ', w, 3+pl, fl^LEFT_ADJ);\n\t\treturn MAX(w, 3+pl);\n\t}\n\n\ty = frexpl(y, &e2) * 2;\n\tif (y) e2--;\n\n\tif ((t|32)=='a') {\n\t\tlong double round = 8.0;\n\t\tint re;\n\n\t\tif (t&32) prefix += 9;\n\t\tpl += 2;\n\n\t\tif (p<0 || p>=LDBL_MANT_DIG/4-1) re=0;\n\t\telse re=LDBL_MANT_DIG/4-1-p;\n\n\t\tif (re) {\n\t\t\tround *= 1<<(LDBL_MANT_DIG%4);\n\t\t\twhile (re--) round*=16;\n\t\t\tif (*prefix=='-') {\n\t\t\t\ty=-y;\n\t\t\t\ty-=round;\n\t\t\t\ty+=round;\n\t\t\t\ty=-y;\n\t\t\t} else {\n\t\t\t\ty+=round;\n\t\t\t\ty-=round;\n\t\t\t}\n\t\t}\n\n\t\testr=fmt_u(e2<0 ? -e2 : e2, ebuf);\n\t\tif (estr==ebuf) *--estr='0';\n\t\t*--estr = (e2<0 ? '-' : '+');\n\t\t*--estr = t+('p'-'a');\n\n\t\ts=buf;\n\t\tdo {\n\t\t\tint x=y;\n\t\t\t*s++=xdigits[x]|(t&32);\n\t\t\ty=16*(y-x);\n\t\t\tif (s-buf==1 && (y||p>0||(fl&ALT_FORM))) *s++='.';\n\t\t} while (y);\n\n\t\tif (p > INT_MAX-2-(ebuf-estr)-pl)\n\t\t\treturn -1;\n\t\tif (p && s-buf-2 < p)\n\t\t\tl = (p+2) + (ebuf-estr);\n\t\telse\n\t\t\tl = (s-buf) + (ebuf-estr);\n\n\t\tpad(f, ' ', w, pl+l, fl);\n\t\tout(f, prefix, pl);\n\t\tpad(f, '0', w, pl+l, fl^ZERO_PAD);\n\t\tout(f, buf, s-buf);\n\t\tpad(f, '0', l-(ebuf-estr)-(s-buf), 0, 0);\n\t\tout(f, estr, ebuf-estr);\n\t\tpad(f, ' ', w, pl+l, fl^LEFT_ADJ);\n\t\treturn MAX(w, pl+l);\n\t}\n\tif (p<0) p=6;\n\n\tif (y) y *= 0x1p28, e2-=28;\n\n\tif (e2<0) a=r=z=big;\n\telse a=r=z=big+sizeof(big)/sizeof(*big) - LDBL_MANT_DIG - 1;\n\n\tdo {\n\t\t*z = y;\n\t\ty = 1000000000*(y-*z++);\n\t} while (y);\n\n\twhile (e2>0) {\n\t\tuint32_t carry=0;\n\t\tint sh=MIN(29,e2);\n\t\tfor (d=z-1; d>=a; d--) {\n\t\t\tuint64_t x = ((uint64_t)*d<<sh)+carry;\n\t\t\t*d = x % 1000000000;\n\t\t\tcarry = x / 1000000000;\n\t\t}\n\t\tif (carry) *--a = carry;\n\t\twhile (z>a && !z[-1]) z--;\n\t\te2-=sh;\n\t}\n\twhile (e2<0) {\n\t\tuint32_t carry=0, *b;\n\t\tint sh=MIN(9,-e2), need=1+(p+LDBL_MANT_DIG/3U+8)/9;\n\t\tfor (d=a; d<z; d++) {\n\t\t\tuint32_t rm = *d & (1<<sh)-1;\n\t\t\t*d = (*d>>sh) + carry;\n\t\t\tcarry = (1000000000>>sh) * rm;\n\t\t}\n\t\tif (!*a) a++;\n\t\tif (carry) *z++ = carry;\n\t\t/* Avoid (slow!) computation past requested precision */\n\t\tb = (t|32)=='f' ? r : a;\n\t\tif (z-b > need) z = b+need;\n\t\te2+=sh;\n\t}\n\n\tif (a<z) for (i=10, e=9*(r-a); *a>=i; i*=10, e++);\n\telse e=0;\n\n\t/* Perform rounding: j is precision after the radix (possibly neg) */\n\tj = p - ((t|32)!='f')*e - ((t|32)=='g' && p);\n\tif (j < 9*(z-r-1)) {\n\t\tuint32_t x;\n\t\t/* We avoid C's broken division of negative numbers */\n\t\td = r + 1 + ((j+9*LDBL_MAX_EXP)/9 - LDBL_MAX_EXP);\n\t\tj += 9*LDBL_MAX_EXP;\n\t\tj %= 9;\n\t\tfor (i=10, j++; j<9; i*=10, j++);\n\t\tx = *d % i;\n\t\t/* Are there any significant digits past j? */\n\t\tif (x || d+1!=z) {\n\t\t\tlong double round = 2/LDBL_EPSILON;\n\t\t\tlong double small;\n\t\t\tif ((*d/i & 1) || (i==1000000000 && d>a && (d[-1]&1)))\n\t\t\t\tround += 2;\n\t\t\tif (x<i/2) small=0x0.8p0;\n\t\t\telse if (x==i/2 && d+1==z) small=0x1.0p0;\n\t\t\telse small=0x1.8p0;\n\t\t\tif (pl && *prefix=='-') round*=-1, small*=-1;\n\t\t\t*d -= x;\n\t\t\t/* Decide whether to round by probing round+small */\n\t\t\tif (round+small != round) {\n\t\t\t\t*d = *d + i;\n\t\t\t\twhile (*d > 999999999) {\n\t\t\t\t\t*d--=0;\n\t\t\t\t\tif (d<a) *--a=0;\n\t\t\t\t\t(*d)++;\n\t\t\t\t}\n\t\t\t\tfor (i=10, e=9*(r-a); *a>=i; i*=10, e++);\n\t\t\t}\n\t\t}\n\t\tif (z>d+1) z=d+1;\n\t}\n\tfor (; z>a && !z[-1]; z--);\n\t\n\tif ((t|32)=='g') {\n\t\tif (!p) p++;\n\t\tif (p>e && e>=-4) {\n\t\t\tt--;\n\t\t\tp-=e+1;\n\t\t} else {\n\t\t\tt-=2;\n\t\t\tp--;\n\t\t}\n\t\tif (!(fl&ALT_FORM)) {\n\t\t\t/* Count trailing zeros in last place */\n\t\t\tif (z>a && z[-1]) for (i=10, j=0; z[-1]%i==0; i*=10, j++);\n\t\t\telse j=9;\n\t\t\tif ((t|32)=='f')\n\t\t\t\tp = MIN(p,MAX(0,9*(z-r-1)-j));\n\t\t\telse\n\t\t\t\tp = MIN(p,MAX(0,9*(z-r-1)+e-j));\n\t\t}\n\t}\n\tif (p > INT_MAX-1-(p || (fl&ALT_FORM)))\n\t\treturn -1;\n\tl = 1 + p + (p || (fl&ALT_FORM));\n\tif ((t|32)=='f') {\n\t\tif (e > INT_MAX-l) return -1;\n\t\tif (e>0) l+=e;\n\t} else {\n\t\testr=fmt_u(e<0 ? -e : e, ebuf);\n\t\twhile(ebuf-estr<2) *--estr='0';\n\t\t*--estr = (e<0 ? '-' : '+');\n\t\t*--estr = t;\n\t\tif (ebuf-estr > INT_MAX-l) return -1;\n\t\tl += ebuf-estr;\n\t}\n\n\tif (l > INT_MAX-pl) return -1;\n\tpad(f, ' ', w, pl+l, fl);\n\tout(f, prefix, pl);\n\tpad(f, '0', w, pl+l, fl^ZERO_PAD);\n\n\tif ((t|32)=='f') {\n\t\tif (a>r) a=r;\n\t\tfor (d=a; d<=r; d++) {\n\t\t\tchar *s = fmt_u(*d, buf+9);\n\t\t\tif (d!=a) while (s>buf) *--s='0';\n\t\t\telse if (s==buf+9) *--s='0';\n\t\t\tout(f, s, buf+9-s);\n\t\t}\n\t\tif (p || (fl&ALT_FORM)) out(f, \".\", 1);\n\t\tfor (; d<z && p>0; d++, p-=9) {\n\t\t\tchar *s = fmt_u(*d, buf+9);\n\t\t\twhile (s>buf) *--s='0';\n\t\t\tout(f, s, MIN(9,p));\n\t\t}\n\t\tpad(f, '0', p+9, 9, 0);\n\t} else {\n\t\tif (z<=a) z=a+1;\n\t\tfor (d=a; d<z && p>=0; d++) {\n\t\t\tchar *s = fmt_u(*d, buf+9);\n\t\t\tif (s==buf+9) *--s='0';\n\t\t\tif (d!=a) while (s>buf) *--s='0';\n\t\t\telse {\n\t\t\t\tout(f, s++, 1);\n\t\t\t\tif (p>0||(fl&ALT_FORM)) out(f, \".\", 1);\n\t\t\t}\n\t\t\tout(f, s, MIN(buf+9-s, p));\n\t\t\tp -= buf+9-s;\n\t\t}\n\t\tpad(f, '0', p+18, 18, 0);\n\t\tout(f, estr, ebuf-estr);\n\t}\n\n\tpad(f, ' ', w, pl+l, fl^LEFT_ADJ);\n\n\treturn MAX(w, pl+l);\n}\n\nstatic int getint(char **s) {\n\tint i;\n\tfor (i=0; isdigit(**s); (*s)++) {\n\t\tif (i > INT_MAX/10U || **s-'0' > INT_MAX-10*i) i = -1;\n\t\telse i = 10*i + (**s-'0');\n\t}\n\treturn i;\n}\n\nstatic int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, int *nl_type)\n{\n\tchar *a, *z, *s=(char *)fmt;\n\tunsigned l10n=0, fl;\n\tint w, p, xp;\n\tunion arg arg;\n\tint argpos;\n\tunsigned st, ps;\n\tint cnt=0, l=0;\n\tsize_t i;\n\tchar buf[sizeof(uintmax_t)*3+3+LDBL_MANT_DIG/4];\n\tconst char *prefix;\n\tint t, pl;\n\twchar_t wc[2], *ws;\n\tchar mb[4];\n\n\tfor (;;) {\n\t\t/* This error is only specified for snprintf, but since it's\n\t\t * unspecified for other forms, do the same. Stop immediately\n\t\t * on overflow; otherwise %n could produce wrong results. */\n\t\tif (l > INT_MAX - cnt) goto overflow;\n\n\t\t/* Update output count, end loop when fmt is exhausted */\n\t\tcnt += l;\n\t\tif (!*s) break;\n\n\t\t/* Handle literal text and %% format specifiers */\n\t\tfor (a=s; *s && *s!='%'; s++);\n\t\tfor (z=s; s[0]=='%' && s[1]=='%'; z++, s+=2);\n\t\tif (z-a > INT_MAX-cnt) goto overflow;\n\t\tl = z-a;\n\t\tif (f) out(f, a, l);\n\t\tif (l) continue;\n\n\t\tif (isdigit(s[1]) && s[2]=='$') {\n\t\t\tl10n=1;\n\t\t\targpos = s[1]-'0';\n\t\t\ts+=3;\n\t\t} else {\n\t\t\targpos = -1;\n\t\t\ts++;\n\t\t}\n\n\t\t/* Read modifier flags */\n\t\tfor (fl=0; (unsigned)*s-' '<32 && (FLAGMASK&(1U<<*s-' ')); s++)\n\t\t\tfl |= 1U<<*s-' ';\n\n\t\t/* Read field width */\n\t\tif (*s=='*') {\n\t\t\tif (isdigit(s[1]) && s[2]=='$') {\n\t\t\t\tl10n=1;\n\t\t\t\tnl_type[s[1]-'0'] = INT;\n\t\t\t\tw = nl_arg[s[1]-'0'].i;\n\t\t\t\ts+=3;\n\t\t\t} else if (!l10n) {\n\t\t\t\tw = f ? va_arg(*ap, int) : 0;\n\t\t\t\ts++;\n\t\t\t} else goto inval;\n\t\t\tif (w<0) fl|=LEFT_ADJ, w=-w;\n\t\t} else if ((w=getint(&s))<0) goto overflow;\n\n\t\t/* Read precision */\n\t\tif (*s=='.' && s[1]=='*') {\n\t\t\tif (isdigit(s[2]) && s[3]=='$') {\n\t\t\t\tnl_type[s[2]-'0'] = INT;\n\t\t\t\tp = nl_arg[s[2]-'0'].i;\n\t\t\t\ts+=4;\n\t\t\t} else if (!l10n) {\n\t\t\t\tp = f ? va_arg(*ap, int) : 0;\n\t\t\t\ts+=2;\n\t\t\t} else goto inval;\n\t\t\txp = (p>=0);\n\t\t} else if (*s=='.') {\n\t\t\ts++;\n\t\t\tp = getint(&s);\n\t\t\txp = 1;\n\t\t} else {\n\t\t\tp = -1;\n\t\t\txp = 0;\n\t\t}\n\n\t\t/* Format specifier state machine */\n\t\tst=0;\n\t\tdo {\n\t\t\tif (OOB(*s)) goto inval;\n\t\t\tps=st;\n\t\t\tst=states[st]S(*s++);\n\t\t} while (st-1<STOP);\n\t\tif (!st) goto inval;\n\n\t\t/* Check validity of argument type (nl/normal) */\n\t\tif (st==NOARG) {\n\t\t\tif (argpos>=0) goto inval;\n\t\t} else {\n\t\t\tif (argpos>=0) nl_type[argpos]=st, arg=nl_arg[argpos];\n\t\t\telse if (f) pop_arg(&arg, st, ap);\n\t\t\telse return 0;\n\t\t}\n\n\t\tif (!f) continue;\n\n\t\tz = buf + sizeof(buf);\n\t\tprefix = \"-+   0X0x\";\n\t\tpl = 0;\n\t\tt = s[-1];\n\n\t\t/* Transform ls,lc -> S,C */\n\t\tif (ps && (t&15)==3) t&=~32;\n\n\t\t/* - and 0 flags are mutually exclusive */\n\t\tif (fl & LEFT_ADJ) fl &= ~ZERO_PAD;\n\n\t\tswitch(t) {\n\t\tcase 'n':\n\t\t\tswitch(ps) {\n\t\t\tcase BARE: *(int *)arg.p = cnt; break;\n\t\t\tcase LPRE: *(long *)arg.p = cnt; break;\n\t\t\tcase LLPRE: *(long long *)arg.p = cnt; break;\n\t\t\tcase HPRE: *(unsigned short *)arg.p = cnt; break;\n\t\t\tcase HHPRE: *(unsigned char *)arg.p = cnt; break;\n\t\t\tcase ZTPRE: *(size_t *)arg.p = cnt; break;\n\t\t\tcase JPRE: *(uintmax_t *)arg.p = cnt; break;\n\t\t\t}\n\t\t\tcontinue;\n\t\tcase 'p':\n\t\t\tp = MAX(p, 2*sizeof(void*));\n\t\t\tt = 'x';\n\t\t\tfl |= ALT_FORM;\n\t\tcase 'x': case 'X':\n\t\t\ta = fmt_x(arg.i, z, t&32);\n\t\t\tif (arg.i && (fl & ALT_FORM)) prefix+=(t>>4), pl=2;\n\t\t\tif (0) {\n\t\tcase 'o':\n\t\t\ta = fmt_o(arg.i, z);\n\t\t\tif ((fl&ALT_FORM) && p<z-a+1) p=z-a+1;\n\t\t\t} if (0) {\n\t\tcase 'd': case 'i':\n\t\t\tpl=1;\n\t\t\tif (arg.i>INTMAX_MAX) {\n\t\t\t\targ.i=-arg.i;\n\t\t\t} else if (fl & MARK_POS) {\n\t\t\t\tprefix++;\n\t\t\t} else if (fl & PAD_POS) {\n\t\t\t\tprefix+=2;\n\t\t\t} else pl=0;\n\t\tcase 'u':\n\t\t\ta = fmt_u(arg.i, z);\n\t\t\t}\n\t\t\tif (xp && p<0) goto overflow;\n\t\t\tif (xp) fl &= ~ZERO_PAD;\n\t\t\tif (!arg.i && !p) {\n\t\t\t\ta=z;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tp = MAX(p, z-a + !arg.i);\n\t\t\tbreak;\n\t\tcase 'c':\n\t\t\t*(a=z-(p=1))=arg.i;\n\t\t\tfl &= ~ZERO_PAD;\n\t\t\tbreak;\n\t\tcase 'm':\n\t\t\tif (1) a = strerror(errno); else\n\t\tcase 's':\n\t\t\ta = arg.p ? arg.p : \"(null)\";\n\t\t\tz = a + strnlen(a, p<0 ? INT_MAX : p);\n\t\t\tif (p<0 && *z) goto overflow;\n\t\t\tp = z-a;\n\t\t\tfl &= ~ZERO_PAD;\n\t\t\tbreak;\n\t\tcase 'C':\n\t\t\twc[0] = arg.i;\n\t\t\twc[1] = 0;\n\t\t\targ.p = wc;\n\t\t\tp = -1;\n\t\tcase 'S':\n\t\t\tws = arg.p;\n\t\t\tfor (i=l=0; i<p && *ws && (l=wctomb(mb, *ws++))>=0 && l<=p-i; i+=l);\n\t\t\tif (l<0) return -1;\n\t\t\tif (i > INT_MAX) goto overflow;\n\t\t\tp = i;\n\t\t\tpad(f, ' ', w, p, fl);\n\t\t\tws = arg.p;\n\t\t\tfor (i=0; i<0U+p && *ws && i+(l=wctomb(mb, *ws++))<=p; i+=l)\n\t\t\t\tout(f, mb, l);\n\t\t\tpad(f, ' ', w, p, fl^LEFT_ADJ);\n\t\t\tl = w>p ? w : p;\n\t\t\tcontinue;\n\t\tcase 'e': case 'f': case 'g': case 'a':\n\t\tcase 'E': case 'F': case 'G': case 'A':\n\t\t\tif (xp && p<0) goto overflow;\n\t\t\tl = fmt_fp(f, arg.f, w, p, fl, t);\n\t\t\tif (l<0) goto overflow;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (p < z-a) p = z-a;\n\t\tif (p > INT_MAX-pl) goto overflow;\n\t\tif (w < pl+p) w = pl+p;\n\t\tif (w > INT_MAX-cnt) goto overflow;\n\n\t\tpad(f, ' ', w, pl+p, fl);\n\t\tout(f, prefix, pl);\n\t\tpad(f, '0', w, pl+p, fl^ZERO_PAD);\n\t\tpad(f, '0', p, z-a, 0);\n\t\tout(f, a, z-a);\n\t\tpad(f, ' ', w, pl+p, fl^LEFT_ADJ);\n\n\t\tl = w;\n\t}\n\n\tif (f) return cnt;\n\tif (!l10n) return 0;\n\n\tfor (i=1; i<=NL_ARGMAX && nl_type[i]; i++)\n\t\tpop_arg(nl_arg+i, nl_type[i], ap);\n\tfor (; i<=NL_ARGMAX && !nl_type[i]; i++);\n\tif (i<=NL_ARGMAX) goto inval;\n\treturn 1;\n\ninval:\n\terrno = EINVAL;\n\treturn -1;\noverflow:\n\terrno = EOVERFLOW;\n\treturn -1;\n}\n\nint vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap)\n{\n\tva_list ap2;\n\tint nl_type[NL_ARGMAX+1] = {0};\n\tunion arg nl_arg[NL_ARGMAX+1];\n\tunsigned char internal_buf[80], *saved_buf = 0;\n\tint olderr;\n\tint ret;\n\n\t/* the copy allows passing va_list* even if va_list is an array */\n\tva_copy(ap2, ap);\n\tif (printf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) {\n\t\tva_end(ap2);\n\t\treturn -1;\n\t}\n\n\tFLOCK(f);\n\tolderr = f->flags & F_ERR;\n\tif (f->mode < 1) f->flags &= ~F_ERR;\n\tif (!f->buf_size) {\n\t\tsaved_buf = f->buf;\n\t\tf->buf = internal_buf;\n\t\tf->buf_size = sizeof internal_buf;\n\t\tf->wpos = f->wbase = f->wend = 0;\n\t}\n\tif (!f->wend && __towrite(f)) ret = -1;\n\telse ret = printf_core(f, fmt, &ap2, nl_arg, nl_type);\n\tif (saved_buf) {\n\t\tf->write(f, 0, 0);\n\t\tif (!f->wpos) ret = -1;\n\t\tf->buf = saved_buf;\n\t\tf->buf_size = 0;\n\t\tf->wpos = f->wbase = f->wend = 0;\n\t}\n\tif (f->flags & F_ERR) ret = -1;\n\tf->flags |= olderr;\n\tFUNLOCK(f);\n\tva_end(ap2);\n\treturn ret;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/vfscanf.c",
    "content": "#include <stdlib.h>\n#include <stdarg.h>\n#include <ctype.h>\n#include <wchar.h>\n#include <wctype.h>\n#include <limits.h>\n#include <string.h>\n#include <stdint.h>\n\n#include \"stdio_impl.h\"\n#include \"shgetc.h\"\n#include \"intscan.h\"\n#include \"floatscan.h\"\n\n#define SIZE_hh -2\n#define SIZE_h  -1\n#define SIZE_def 0\n#define SIZE_l   1\n#define SIZE_L   2\n#define SIZE_ll  3\n\nstatic void store_int(void *dest, int size, unsigned long long i)\n{\n\tif (!dest) return;\n\tswitch (size) {\n\tcase SIZE_hh:\n\t\t*(char *)dest = i;\n\t\tbreak;\n\tcase SIZE_h:\n\t\t*(short *)dest = i;\n\t\tbreak;\n\tcase SIZE_def:\n\t\t*(int *)dest = i;\n\t\tbreak;\n\tcase SIZE_l:\n\t\t*(long *)dest = i;\n\t\tbreak;\n\tcase SIZE_ll:\n\t\t*(long long *)dest = i;\n\t\tbreak;\n\t}\n}\n\nstatic void *arg_n(va_list ap, unsigned int n)\n{\n\tvoid *p;\n\tunsigned int i;\n\tva_list ap2;\n\tva_copy(ap2, ap);\n\tfor (i=n; i>1; i--) va_arg(ap2, void *);\n\tp = va_arg(ap2, void *);\n\tva_end(ap2);\n\treturn p;\n}\n\nint vfscanf(FILE *restrict f, const char *restrict fmt, va_list ap)\n{\n\tint width;\n\tint size;\n\tint alloc = 0;\n\tint base;\n\tconst unsigned char *p;\n\tint c, t;\n\tchar *s;\n\twchar_t *wcs;\n\tmbstate_t st;\n\tvoid *dest=NULL;\n\tint invert;\n\tint matches=0;\n\tunsigned long long x;\n\tlong double y;\n\toff_t pos = 0;\n\tunsigned char scanset[257];\n\tsize_t i, k;\n\twchar_t wc;\n\n\tFLOCK(f);\n\n\tif (!f->rpos) __toread(f);\n\tif (!f->rpos) goto input_fail;\n\n\tfor (p=(const unsigned char *)fmt; *p; p++) {\n\n\t\talloc = 0;\n\n\t\tif (isspace(*p)) {\n\t\t\twhile (isspace(p[1])) p++;\n\t\t\tshlim(f, 0);\n\t\t\twhile (isspace(shgetc(f)));\n\t\t\tshunget(f);\n\t\t\tpos += shcnt(f);\n\t\t\tcontinue;\n\t\t}\n\t\tif (*p != '%' || p[1] == '%') {\n\t\t\tshlim(f, 0);\n\t\t\tif (*p == '%') {\n\t\t\t\tp++;\n\t\t\t\twhile (isspace((c=shgetc(f))));\n\t\t\t} else {\n\t\t\t\tc = shgetc(f);\n\t\t\t}\n\t\t\tif (c!=*p) {\n\t\t\t\tshunget(f);\n\t\t\t\tif (c<0) goto input_fail;\n\t\t\t\tgoto match_fail;\n\t\t\t}\n\t\t\tpos += shcnt(f);\n\t\t\tcontinue;\n\t\t}\n\n\t\tp++;\n\t\tif (*p=='*') {\n\t\t\tdest = 0; p++;\n\t\t} else if (isdigit(*p) && p[1]=='$') {\n\t\t\tdest = arg_n(ap, *p-'0'); p+=2;\n\t\t} else {\n\t\t\tdest = va_arg(ap, void *);\n\t\t}\n\n\t\tfor (width=0; isdigit(*p); p++) {\n\t\t\twidth = 10*width + *p - '0';\n\t\t}\n\n\t\tif (*p=='m') {\n\t\t\twcs = 0;\n\t\t\ts = 0;\n\t\t\talloc = !!dest;\n\t\t\tp++;\n\t\t} else {\n\t\t\talloc = 0;\n\t\t}\n\n\t\tsize = SIZE_def;\n\t\tswitch (*p++) {\n\t\tcase 'h':\n\t\t\tif (*p == 'h') p++, size = SIZE_hh;\n\t\t\telse size = SIZE_h;\n\t\t\tbreak;\n\t\tcase 'l':\n\t\t\tif (*p == 'l') p++, size = SIZE_ll;\n\t\t\telse size = SIZE_l;\n\t\t\tbreak;\n\t\tcase 'j':\n\t\t\tsize = SIZE_ll;\n\t\t\tbreak;\n\t\tcase 'z':\n\t\tcase 't':\n\t\t\tsize = SIZE_l;\n\t\t\tbreak;\n\t\tcase 'L':\n\t\t\tsize = SIZE_L;\n\t\t\tbreak;\n\t\tcase 'd': case 'i': case 'o': case 'u': case 'x':\n\t\tcase 'a': case 'e': case 'f': case 'g':\n\t\tcase 'A': case 'E': case 'F': case 'G': case 'X':\n\t\tcase 's': case 'c': case '[':\n\t\tcase 'S': case 'C':\n\t\tcase 'p': case 'n':\n\t\t\tp--;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tgoto fmt_fail;\n\t\t}\n\n\t\tt = *p;\n\n\t\t/* C or S */\n\t\tif ((t&0x2f) == 3) {\n\t\t\tt |= 32;\n\t\t\tsize = SIZE_l;\n\t\t}\n\n\t\tswitch (t) {\n\t\tcase 'c':\n\t\t\tif (width < 1) width = 1;\n\t\tcase '[':\n\t\t\tbreak;\n\t\tcase 'n':\n\t\t\tstore_int(dest, size, pos);\n\t\t\t/* do not increment match count, etc! */\n\t\t\tcontinue;\n\t\tdefault:\n\t\t\tshlim(f, 0);\n\t\t\twhile (isspace(shgetc(f)));\n\t\t\tshunget(f);\n\t\t\tpos += shcnt(f);\n\t\t}\n\n\t\tshlim(f, width);\n\t\tif (shgetc(f) < 0) goto input_fail;\n\t\tshunget(f);\n\n\t\tswitch (t) {\n\t\tcase 's':\n\t\tcase 'c':\n\t\tcase '[':\n\t\t\tif (t == 'c' || t == 's') {\n\t\t\t\tmemset(scanset, -1, sizeof scanset);\n\t\t\t\tscanset[0] = 0;\n\t\t\t\tif (t == 's') {\n\t\t\t\t\tscanset[1+'\\t'] = 0;\n\t\t\t\t\tscanset[1+'\\n'] = 0;\n\t\t\t\t\tscanset[1+'\\v'] = 0;\n\t\t\t\t\tscanset[1+'\\f'] = 0;\n\t\t\t\t\tscanset[1+'\\r'] = 0;\n\t\t\t\t\tscanset[1+' '] = 0;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (*++p == '^') p++, invert = 1;\n\t\t\t\telse invert = 0;\n\t\t\t\tmemset(scanset, invert, sizeof scanset);\n\t\t\t\tscanset[0] = 0;\n\t\t\t\tif (*p == '-') p++, scanset[1+'-'] = 1-invert;\n\t\t\t\telse if (*p == ']') p++, scanset[1+']'] = 1-invert;\n\t\t\t\tfor (; *p != ']'; p++) {\n\t\t\t\t\tif (!*p) goto fmt_fail;\n\t\t\t\t\tif (*p=='-' && p[1] && p[1] != ']')\n\t\t\t\t\t\tfor (c=p++[-1]; c<*p; c++)\n\t\t\t\t\t\t\tscanset[1+c] = 1-invert;\n\t\t\t\t\tscanset[1+*p] = 1-invert;\n\t\t\t\t}\n\t\t\t}\n\t\t\twcs = 0;\n\t\t\ts = 0;\n\t\t\ti = 0;\n\t\t\tk = t=='c' ? width+1U : 31;\n\t\t\tif (size == SIZE_l) {\n\t\t\t\tif (alloc) {\n\t\t\t\t\twcs = malloc(k*sizeof(wchar_t));\n\t\t\t\t\tif (!wcs) goto alloc_fail;\n\t\t\t\t} else {\n\t\t\t\t\twcs = dest;\n\t\t\t\t}\n\t\t\t\tst = (mbstate_t){0};\n\t\t\t\twhile (scanset[(c=shgetc(f))+1]) {\n\t\t\t\t\tswitch (mbrtowc(&wc, &(char){c}, 1, &st)) {\n\t\t\t\t\tcase -1:\n\t\t\t\t\t\tgoto input_fail;\n\t\t\t\t\tcase -2:\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (wcs) wcs[i++] = wc;\n\t\t\t\t\tif (alloc && i==k) {\n\t\t\t\t\t\tk+=k+1;\n\t\t\t\t\t\twchar_t *tmp = realloc(wcs, k*sizeof(wchar_t));\n\t\t\t\t\t\tif (!tmp) goto alloc_fail;\n\t\t\t\t\t\twcs = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!mbsinit(&st)) goto input_fail;\n\t\t\t} else if (alloc) {\n\t\t\t\ts = malloc(k);\n\t\t\t\tif (!s) goto alloc_fail;\n\t\t\t\twhile (scanset[(c=shgetc(f))+1]) {\n\t\t\t\t\ts[i++] = c;\n\t\t\t\t\tif (i==k) {\n\t\t\t\t\t\tk+=k+1;\n\t\t\t\t\t\tchar *tmp = realloc(s, k);\n\t\t\t\t\t\tif (!tmp) goto alloc_fail;\n\t\t\t\t\t\ts = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if ((s = dest)) {\n\t\t\t\twhile (scanset[(c=shgetc(f))+1])\n\t\t\t\t\ts[i++] = c;\n\t\t\t} else {\n\t\t\t\twhile (scanset[(c=shgetc(f))+1]);\n\t\t\t}\n\t\t\tshunget(f);\n\t\t\tif (!shcnt(f)) goto match_fail;\n\t\t\tif (t == 'c' && shcnt(f) != width) goto match_fail;\n\t\t\tif (alloc) {\n\t\t\t\tif (size == SIZE_l) *(wchar_t **)dest = wcs;\n\t\t\t\telse *(char **)dest = s;\n\t\t\t}\n\t\t\tif (t != 'c') {\n\t\t\t\tif (wcs) wcs[i] = 0;\n\t\t\t\tif (s) s[i] = 0;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'p':\n\t\tcase 'X':\n\t\tcase 'x':\n\t\t\tbase = 16;\n\t\t\tgoto int_common;\n\t\tcase 'o':\n\t\t\tbase = 8;\n\t\t\tgoto int_common;\n\t\tcase 'd':\n\t\tcase 'u':\n\t\t\tbase = 10;\n\t\t\tgoto int_common;\n\t\tcase 'i':\n\t\t\tbase = 0;\n\t\tint_common:\n\t\t\tx = __intscan(f, base, 0, ULLONG_MAX);\n\t\t\tif (!shcnt(f)) goto match_fail;\n\t\t\tif (t=='p' && dest) *(void **)dest = (void *)(uintptr_t)x;\n\t\t\telse store_int(dest, size, x);\n\t\t\tbreak;\n\t\tcase 'a': case 'A':\n\t\tcase 'e': case 'E':\n\t\tcase 'f': case 'F':\n\t\tcase 'g': case 'G':\n\t\t\ty = __floatscan(f, size, 0);\n\t\t\tif (!shcnt(f)) goto match_fail;\n\t\t\tif (dest) switch (size) {\n\t\t\tcase SIZE_def:\n\t\t\t\t*(float *)dest = y;\n\t\t\t\tbreak;\n\t\t\tcase SIZE_l:\n\t\t\t\t*(double *)dest = y;\n\t\t\t\tbreak;\n\t\t\tcase SIZE_L:\n\t\t\t\t*(long double *)dest = y;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tpos += shcnt(f);\n\t\tif (dest) matches++;\n\t}\n\tif (0) {\nfmt_fail:\nalloc_fail:\ninput_fail:\n\t\tif (!matches) matches--;\nmatch_fail:\n\t\tif (alloc) {\n\t\t\tfree(s);\n\t\t\tfree(wcs);\n\t\t}\n\t}\n\tFUNLOCK(f);\n\treturn matches;\n}\n\nweak_alias(vfscanf,__isoc99_vfscanf);\n"
  },
  {
    "path": "user.libc/src/stdio/vfwprintf.c",
    "content": "#include \"stdio_impl.h\"\n#include <errno.h>\n#include <ctype.h>\n#include <limits.h>\n#include <string.h>\n#include <stdarg.h>\n#include <stddef.h>\n#include <stdlib.h>\n#include <wchar.h>\n#include <inttypes.h>\n\n/* Convenient bit representation for modifier flags, which all fall\n * within 31 codepoints of the space character. */\n\n#define ALT_FORM   (1U<<'#'-' ')\n#define ZERO_PAD   (1U<<'0'-' ')\n#define LEFT_ADJ   (1U<<'-'-' ')\n#define PAD_POS    (1U<<' '-' ')\n#define MARK_POS   (1U<<'+'-' ')\n#define GROUPED    (1U<<'\\''-' ')\n\n#define FLAGMASK (ALT_FORM|ZERO_PAD|LEFT_ADJ|PAD_POS|MARK_POS|GROUPED)\n\n/* State machine to accept length modifiers + conversion specifiers.\n * Result is 0 on failure, or an argument type to pop on success. */\n\nenum {\n\tBARE, LPRE, LLPRE, HPRE, HHPRE, BIGLPRE,\n\tZTPRE, JPRE,\n\tSTOP,\n\tPTR, INT, UINT, ULLONG,\n\tLONG, ULONG,\n\tSHORT, USHORT, CHAR, UCHAR,\n\tLLONG, SIZET, IMAX, UMAX, PDIFF, UIPTR,\n\tDBL, LDBL,\n\tNOARG,\n\tMAXSTATE\n};\n\n#define S(x) [(x)-'A']\n\nstatic const unsigned char states[]['z'-'A'+1] = {\n\t{ /* 0: bare types */\n\t\tS('d') = INT, S('i') = INT,\n\t\tS('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT,\n\t\tS('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,\n\t\tS('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,\n\t\tS('c') = CHAR, S('C') = INT,\n\t\tS('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR,\n\t\tS('m') = NOARG,\n\t\tS('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,\n\t\tS('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE,\n\t}, { /* 1: l-prefixed */\n\t\tS('d') = LONG, S('i') = LONG,\n\t\tS('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG,\n\t\tS('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,\n\t\tS('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,\n\t\tS('c') = INT, S('s') = PTR, S('n') = PTR,\n\t\tS('l') = LLPRE,\n\t}, { /* 2: ll-prefixed */\n\t\tS('d') = LLONG, S('i') = LLONG,\n\t\tS('o') = ULLONG, S('u') = ULLONG,\n\t\tS('x') = ULLONG, S('X') = ULLONG,\n\t\tS('n') = PTR,\n\t}, { /* 3: h-prefixed */\n\t\tS('d') = SHORT, S('i') = SHORT,\n\t\tS('o') = USHORT, S('u') = USHORT,\n\t\tS('x') = USHORT, S('X') = USHORT,\n\t\tS('n') = PTR,\n\t\tS('h') = HHPRE,\n\t}, { /* 4: hh-prefixed */\n\t\tS('d') = CHAR, S('i') = CHAR,\n\t\tS('o') = UCHAR, S('u') = UCHAR,\n\t\tS('x') = UCHAR, S('X') = UCHAR,\n\t\tS('n') = PTR,\n\t}, { /* 5: L-prefixed */\n\t\tS('e') = LDBL, S('f') = LDBL, S('g') = LDBL, S('a') = LDBL,\n\t\tS('E') = LDBL, S('F') = LDBL, S('G') = LDBL, S('A') = LDBL,\n\t\tS('n') = PTR,\n\t}, { /* 6: z- or t-prefixed (assumed to be same size) */\n\t\tS('d') = PDIFF, S('i') = PDIFF,\n\t\tS('o') = SIZET, S('u') = SIZET,\n\t\tS('x') = SIZET, S('X') = SIZET,\n\t\tS('n') = PTR,\n\t}, { /* 7: j-prefixed */\n\t\tS('d') = IMAX, S('i') = IMAX,\n\t\tS('o') = UMAX, S('u') = UMAX,\n\t\tS('x') = UMAX, S('X') = UMAX,\n\t\tS('n') = PTR,\n\t}\n};\n\n#define OOB(x) ((unsigned)(x)-'A' > 'z'-'A')\n\nunion arg\n{\n\tuintmax_t i;\n\tlong double f;\n\tvoid *p;\n};\n\nstatic void pop_arg(union arg *arg, int type, va_list *ap)\n{\n\tswitch (type) {\n\t       case PTR:\targ->p = va_arg(*ap, void *);\n\tbreak; case INT:\targ->i = va_arg(*ap, int);\n\tbreak; case UINT:\targ->i = va_arg(*ap, unsigned int);\n\tbreak; case LONG:\targ->i = va_arg(*ap, long);\n\tbreak; case ULONG:\targ->i = va_arg(*ap, unsigned long);\n\tbreak; case ULLONG:\targ->i = va_arg(*ap, unsigned long long);\n\tbreak; case SHORT:\targ->i = (short)va_arg(*ap, int);\n\tbreak; case USHORT:\targ->i = (unsigned short)va_arg(*ap, int);\n\tbreak; case CHAR:\targ->i = (signed char)va_arg(*ap, int);\n\tbreak; case UCHAR:\targ->i = (unsigned char)va_arg(*ap, int);\n\tbreak; case LLONG:\targ->i = va_arg(*ap, long long);\n\tbreak; case SIZET:\targ->i = va_arg(*ap, size_t);\n\tbreak; case IMAX:\targ->i = va_arg(*ap, intmax_t);\n\tbreak; case UMAX:\targ->i = va_arg(*ap, uintmax_t);\n\tbreak; case PDIFF:\targ->i = va_arg(*ap, ptrdiff_t);\n\tbreak; case UIPTR:\targ->i = (uintptr_t)va_arg(*ap, void *);\n\tbreak; case DBL:\targ->f = va_arg(*ap, double);\n\tbreak; case LDBL:\targ->f = va_arg(*ap, long double);\n\t}\n}\n\nstatic void out(FILE *f, const wchar_t *s, size_t l)\n{\n\twhile (l-- && !(f->flags & F_ERR)) fputwc(*s++, f);\n}\n\nstatic int getint(wchar_t **s) {\n\tint i;\n\tfor (i=0; iswdigit(**s); (*s)++) {\n\t\tif (i > INT_MAX/10U || **s-'0' > INT_MAX-10*i) i = -1;\n\t\telse i = 10*i + (**s-'0');\n\t}\n\treturn i;\n}\n\nstatic const char sizeprefix['y'-'a'] = {\n['a'-'a']='L', ['e'-'a']='L', ['f'-'a']='L', ['g'-'a']='L',\n['d'-'a']='j', ['i'-'a']='j', ['o'-'a']='j', ['u'-'a']='j', ['x'-'a']='j',\n['p'-'a']='j'\n};\n\nstatic int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_arg, int *nl_type)\n{\n\twchar_t *a, *z, *s=(wchar_t *)fmt;\n\tunsigned l10n=0, fl;\n\tint w, p, xp;\n\tunion arg arg;\n\tint argpos;\n\tunsigned st, ps;\n\tint cnt=0, l=0;\n\tint i;\n\tint t;\n\tchar *bs;\n\tchar charfmt[16];\n\twchar_t wc;\n\n\tfor (;;) {\n\t\t/* This error is only specified for snprintf, but since it's\n\t\t * unspecified for other forms, do the same. Stop immediately\n\t\t * on overflow; otherwise %n could produce wrong results. */\n\t\tif (l > INT_MAX - cnt) goto overflow;\n\n\t\t/* Update output count, end loop when fmt is exhausted */\n\t\tcnt += l;\n\t\tif (!*s) break;\n\n\t\t/* Handle literal text and %% format specifiers */\n\t\tfor (a=s; *s && *s!='%'; s++);\n\t\tfor (z=s; s[0]=='%' && s[1]=='%'; z++, s+=2);\n\t\tif (z-a > INT_MAX-cnt) goto overflow;\n\t\tl = z-a;\n\t\tif (f) out(f, a, l);\n\t\tif (l) continue;\n\n\t\tif (iswdigit(s[1]) && s[2]=='$') {\n\t\t\tl10n=1;\n\t\t\targpos = s[1]-'0';\n\t\t\ts+=3;\n\t\t} else {\n\t\t\targpos = -1;\n\t\t\ts++;\n\t\t}\n\n\t\t/* Read modifier flags */\n\t\tfor (fl=0; (unsigned)*s-' '<32 && (FLAGMASK&(1U<<*s-' ')); s++)\n\t\t\tfl |= 1U<<*s-' ';\n\n\t\t/* Read field width */\n\t\tif (*s=='*') {\n\t\t\tif (iswdigit(s[1]) && s[2]=='$') {\n\t\t\t\tl10n=1;\n\t\t\t\tnl_type[s[1]-'0'] = INT;\n\t\t\t\tw = nl_arg[s[1]-'0'].i;\n\t\t\t\ts+=3;\n\t\t\t} else if (!l10n) {\n\t\t\t\tw = f ? va_arg(*ap, int) : 0;\n\t\t\t\ts++;\n\t\t\t} else goto inval;\n\t\t\tif (w<0) fl|=LEFT_ADJ, w=-w;\n\t\t} else if ((w=getint(&s))<0) goto overflow;\n\n\t\t/* Read precision */\n\t\tif (*s=='.' && s[1]=='*') {\n\t\t\tif (isdigit(s[2]) && s[3]=='$') {\n\t\t\t\tnl_type[s[2]-'0'] = INT;\n\t\t\t\tp = nl_arg[s[2]-'0'].i;\n\t\t\t\ts+=4;\n\t\t\t} else if (!l10n) {\n\t\t\t\tp = f ? va_arg(*ap, int) : 0;\n\t\t\t\ts+=2;\n\t\t\t} else goto inval;\n\t\t\txp = (p>=0);\n\t\t} else if (*s=='.') {\n\t\t\ts++;\n\t\t\tp = getint(&s);\n\t\t\txp = 1;\n\t\t} else {\n\t\t\tp = -1;\n\t\t\txp = 0;\n\t\t}\n\n\t\t/* Format specifier state machine */\n\t\tst=0;\n\t\tdo {\n\t\t\tif (OOB(*s)) goto inval;\n\t\t\tps=st;\n\t\t\tst=states[st]S(*s++);\n\t\t} while (st-1<STOP);\n\t\tif (!st) goto inval;\n\n\t\t/* Check validity of argument type (nl/normal) */\n\t\tif (st==NOARG) {\n\t\t\tif (argpos>=0) goto inval;\n\t\t} else {\n\t\t\tif (argpos>=0) nl_type[argpos]=st, arg=nl_arg[argpos];\n\t\t\telse if (f) pop_arg(&arg, st, ap);\n\t\t\telse return 0;\n\t\t}\n\n\t\tif (!f) continue;\n\t\tt = s[-1];\n\t\tif (ps && (t&15)==3) t&=~32;\n\n\t\tswitch (t) {\n\t\tcase 'n':\n\t\t\tswitch(ps) {\n\t\t\tcase BARE: *(int *)arg.p = cnt; break;\n\t\t\tcase LPRE: *(long *)arg.p = cnt; break;\n\t\t\tcase LLPRE: *(long long *)arg.p = cnt; break;\n\t\t\tcase HPRE: *(unsigned short *)arg.p = cnt; break;\n\t\t\tcase HHPRE: *(unsigned char *)arg.p = cnt; break;\n\t\t\tcase ZTPRE: *(size_t *)arg.p = cnt; break;\n\t\t\tcase JPRE: *(uintmax_t *)arg.p = cnt; break;\n\t\t\t}\n\t\t\tcontinue;\n\t\tcase 'c':\n\t\t\tif (w<1) w=1;\n\t\t\tif (w>1 && !(fl&LEFT_ADJ)) fprintf(f, \"%*s\", w-1, \"\");\n\t\t\tfputwc(btowc(arg.i), f);\n\t\t\tif (w>1 && (fl&LEFT_ADJ)) fprintf(f, \"%*s\", w-1, \"\");\n\t\t\tl = w;\n\t\t\tcontinue;\n\t\tcase 'C':\n\t\t\tfputwc(arg.i, f);\n\t\t\tl = 1;\n\t\t\tcontinue;\n\t\tcase 'S':\n\t\t\ta = arg.p;\n\t\t\tz = a + wcsnlen(a, p<0 ? INT_MAX : p);\n\t\t\tif (p<0 && *z) goto overflow;\n\t\t\tp = z-a;\n\t\t\tif (w<p) w=p;\n\t\t\tif (!(fl&LEFT_ADJ)) fprintf(f, \"%*s\", w-p, \"\");\n\t\t\tout(f, a, p);\n\t\t\tif ((fl&LEFT_ADJ)) fprintf(f, \"%*s\", w-p, \"\");\n\t\t\tl=w;\n\t\t\tcontinue;\n\t\tcase 'm':\n\t\t\targ.p = strerror(errno);\n\t\tcase 's':\n\t\t\tif (!arg.p) arg.p = \"(null)\";\n\t\t\tbs = arg.p;\n\t\t\tfor (i=l=0; l<(p<0?INT_MAX:p) && (i=mbtowc(&wc, bs, MB_LEN_MAX))>0; bs+=i, l++);\n\t\t\tif (i<0) return -1;\n\t\t\tif (p<0 && *bs) goto overflow;\n\t\t\tp=l;\n\t\t\tif (w<p) w=p;\n\t\t\tif (!(fl&LEFT_ADJ)) fprintf(f, \"%*s\", w-p, \"\");\n\t\t\tbs = arg.p;\n\t\t\twhile (l--) {\n\t\t\t\ti=mbtowc(&wc, bs, MB_LEN_MAX);\n\t\t\t\tbs+=i;\n\t\t\t\tfputwc(wc, f);\n\t\t\t}\n\t\t\tif ((fl&LEFT_ADJ)) fprintf(f, \"%*s\", w-p, \"\");\n\t\t\tl=w;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (xp && p<0) goto overflow;\n\t\tsnprintf(charfmt, sizeof charfmt, \"%%%s%s%s%s%s*.*%c%c\",\n\t\t\t\"#\"+!(fl & ALT_FORM),\n\t\t\t\"+\"+!(fl & MARK_POS),\n\t\t\t\"-\"+!(fl & LEFT_ADJ),\n\t\t\t\" \"+!(fl & PAD_POS),\n\t\t\t\"0\"+!(fl & ZERO_PAD),\n\t\t\tsizeprefix[(t|32)-'a'], t);\n\n\t\tswitch (t|32) {\n\t\tcase 'a': case 'e': case 'f': case 'g':\n\t\t\tl = fprintf(f, charfmt, w, p, arg.f);\n\t\t\tbreak;\n\t\tcase 'd': case 'i': case 'o': case 'u': case 'x': case 'p':\n\t\t\tl = fprintf(f, charfmt, w, p, arg.i);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (f) return cnt;\n\tif (!l10n) return 0;\n\n\tfor (i=1; i<=NL_ARGMAX && nl_type[i]; i++)\n\t\tpop_arg(nl_arg+i, nl_type[i], ap);\n\tfor (; i<=NL_ARGMAX && !nl_type[i]; i++);\n\tif (i<=NL_ARGMAX) return -1;\n\treturn 1;\n\ninval:\n\terrno = EINVAL;\n\treturn -1;\noverflow:\n\terrno = EOVERFLOW;\n\treturn -1;\n}\n\nint vfwprintf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap)\n{\n\tva_list ap2;\n\tint nl_type[NL_ARGMAX] = {0};\n\tunion arg nl_arg[NL_ARGMAX];\n\tint olderr;\n\tint ret;\n\n\t/* the copy allows passing va_list* even if va_list is an array */\n\tva_copy(ap2, ap);\n\tif (wprintf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) {\n\t\tva_end(ap2);\n\t\treturn -1;\n\t}\n\n\tFLOCK(f);\n\tfwide(f, 1);\n\tolderr = f->flags & F_ERR;\n\tf->flags &= ~F_ERR;\n\tret = wprintf_core(f, fmt, &ap2, nl_arg, nl_type);\n\tif (f->flags & F_ERR) ret = -1;\n\tf->flags |= olderr;\n\tFUNLOCK(f);\n\tva_end(ap2);\n\treturn ret;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/vfwscanf.c",
    "content": "#include <stdio.h>\n#include <stdlib.h>\n#include <stdarg.h>\n#include <ctype.h>\n#include <wchar.h>\n#include <wctype.h>\n#include <limits.h>\n#include <string.h>\n\n#include \"stdio_impl.h\"\n#include \"shgetc.h\"\n#include \"intscan.h\"\n#include \"floatscan.h\"\n\n#define SIZE_hh -2\n#define SIZE_h  -1\n#define SIZE_def 0\n#define SIZE_l   1\n#define SIZE_L   2\n#define SIZE_ll  3\n\nstatic void store_int(void *dest, int size, unsigned long long i)\n{\n\tif (!dest) return;\n\tswitch (size) {\n\tcase SIZE_hh:\n\t\t*(char *)dest = i;\n\t\tbreak;\n\tcase SIZE_h:\n\t\t*(short *)dest = i;\n\t\tbreak;\n\tcase SIZE_def:\n\t\t*(int *)dest = i;\n\t\tbreak;\n\tcase SIZE_l:\n\t\t*(long *)dest = i;\n\t\tbreak;\n\tcase SIZE_ll:\n\t\t*(long long *)dest = i;\n\t\tbreak;\n\t}\n}\n\nstatic void *arg_n(va_list ap, unsigned int n)\n{\n\tvoid *p;\n\tunsigned int i;\n\tva_list ap2;\n\tva_copy(ap2, ap);\n\tfor (i=n; i>1; i--) va_arg(ap2, void *);\n\tp = va_arg(ap2, void *);\n\tva_end(ap2);\n\treturn p;\n}\n\nstatic int in_set(const wchar_t *set, int c)\n{\n\tint j;\n\tconst wchar_t *p = set;\n\tif (*p == '-') {\n\t\tif (c=='-') return 1;\n\t\tp++;\n\t} else if (*p == ']') {\n\t\tif (c==']') return 1;\n\t\tp++;\n\t}\n\tfor (; *p && *p != ']'; p++) {\n\t\tif (*p=='-' && p[1] && p[1] != ']')\n\t\t\tfor (j=p++[-1]; j<*p; j++)\n\t\t\t\tif (c==j) return 1;\n\t\tif (c==*p) return 1;\n\t}\n\treturn 0;\n}\n\n#if 1\n#undef getwc\n#define getwc(f) \\\n\t((f)->rpos != (f)->rend && *(f)->rpos < 128 ? *(f)->rpos++ : (getwc)(f))\n\n#undef ungetwc\n#define ungetwc(c,f) \\\n\t((f)->rend && (c)<128U ? *--(f)->rpos : ungetwc((c),(f)))\n#endif\n\nint vfwscanf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap)\n{\n\tint width;\n\tint size;\n\tint alloc;\n\tconst wchar_t *p;\n\tint c, t;\n\tchar *s;\n\twchar_t *wcs;\n\tvoid *dest=NULL;\n\tint invert;\n\tint matches=0;\n\toff_t pos = 0, cnt;\n\tstatic const char size_pfx[][3] = { \"hh\", \"h\", \"\", \"l\", \"L\", \"ll\" };\n\tchar tmp[3*sizeof(int)+10];\n\tconst wchar_t *set;\n\tsize_t i, k;\n\n\tFLOCK(f);\n\n\tfwide(f, 1);\n\n\tfor (p=fmt; *p; p++) {\n\n\t\talloc = 0;\n\n\t\tif (iswspace(*p)) {\n\t\t\twhile (iswspace(p[1])) p++;\n\t\t\twhile (iswspace((c=getwc(f)))) pos++;\n\t\t\tungetwc(c, f);\n\t\t\tcontinue;\n\t\t}\n\t\tif (*p != '%' || p[1] == '%') {\n\t\t\tif (*p == '%') {\n\t\t\t\tp++;\n\t\t\t\twhile (iswspace((c=getwc(f)))) pos++;\n\t\t\t} else {\n\t\t\t\tc = getwc(f);\n\t\t\t}\n\t\t\tif (c!=*p) {\n\t\t\t\tungetwc(c, f);\n\t\t\t\tif (c<0) goto input_fail;\n\t\t\t\tgoto match_fail;\n\t\t\t}\n\t\t\tpos++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tp++;\n\t\tif (*p=='*') {\n\t\t\tdest = 0; p++;\n\t\t} else if (iswdigit(*p) && p[1]=='$') {\n\t\t\tdest = arg_n(ap, *p-'0'); p+=2;\n\t\t} else {\n\t\t\tdest = va_arg(ap, void *);\n\t\t}\n\n\t\tfor (width=0; iswdigit(*p); p++) {\n\t\t\twidth = 10*width + *p - '0';\n\t\t}\n\n\t\tif (*p=='m') {\n\t\t\twcs = 0;\n\t\t\ts = 0;\n\t\t\talloc = !!dest;\n\t\t\tp++;\n\t\t} else {\n\t\t\talloc = 0;\n\t\t}\n\n\t\tsize = SIZE_def;\n\t\tswitch (*p++) {\n\t\tcase 'h':\n\t\t\tif (*p == 'h') p++, size = SIZE_hh;\n\t\t\telse size = SIZE_h;\n\t\t\tbreak;\n\t\tcase 'l':\n\t\t\tif (*p == 'l') p++, size = SIZE_ll;\n\t\t\telse size = SIZE_l;\n\t\t\tbreak;\n\t\tcase 'j':\n\t\t\tsize = SIZE_ll;\n\t\t\tbreak;\n\t\tcase 'z':\n\t\tcase 't':\n\t\t\tsize = SIZE_l;\n\t\t\tbreak;\n\t\tcase 'L':\n\t\t\tsize = SIZE_L;\n\t\t\tbreak;\n\t\tcase 'd': case 'i': case 'o': case 'u': case 'x':\n\t\tcase 'a': case 'e': case 'f': case 'g':\n\t\tcase 'A': case 'E': case 'F': case 'G': case 'X':\n\t\tcase 's': case 'c': case '[':\n\t\tcase 'S': case 'C':\n\t\tcase 'p': case 'n':\n\t\t\tp--;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tgoto fmt_fail;\n\t\t}\n\n\t\tt = *p;\n\n\t\t/* Transform S,C -> ls,lc */\n\t\tif ((t&0x2f)==3) {\n\t\t\tsize = SIZE_l;\n\t\t\tt |= 32;\n\t\t}\n\n\t\tif (t != 'n') {\n\t\t\tif (t != '[' && (t|32) != 'c')\n\t\t\t\twhile (iswspace((c=getwc(f)))) pos++;\n\t\t\telse\n\t\t\t\tc=getwc(f);\n\t\t\tif (c < 0) goto input_fail;\n\t\t\tungetwc(c, f);\n\t\t}\n\n\t\tswitch (t) {\n\t\tcase 'n':\n\t\t\tstore_int(dest, size, pos);\n\t\t\t/* do not increment match count, etc! */\n\t\t\tcontinue;\n\n\t\tcase 's':\n\t\tcase 'c':\n\t\tcase '[':\n\t\t\tif (t == 'c') {\n\t\t\t\tif (width<1) width = 1;\n\t\t\t\tinvert = 1;\n\t\t\t\tset = L\"\";\n\t\t\t} else if (t == 's') {\n\t\t\t\tinvert = 1;\n\t\t\t\tstatic const wchar_t spaces[] = {\n\t\t\t\t\t' ', '\\t', '\\n', '\\r', 11, 12,  0x0085,\n\t\t\t\t\t0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005,\n\t\t\t\t\t0x2006, 0x2008, 0x2009, 0x200a,\n\t\t\t\t\t0x2028, 0x2029, 0x205f, 0x3000, 0 };\n\t\t\t\tset = spaces;\n\t\t\t} else {\n\t\t\t\tif (*++p == '^') p++, invert = 1;\n\t\t\t\telse invert = 0;\n\t\t\t\tset = p;\n\t\t\t\tif (*p==']') p++;\n\t\t\t\twhile (*p!=']') {\n\t\t\t\t\tif (!*p) goto fmt_fail;\n\t\t\t\t\tp++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ts = (size == SIZE_def) ? dest : 0;\n\t\t\twcs = (size == SIZE_l) ? dest : 0;\n\n\t\t\tint gotmatch = 0;\n\n\t\t\tif (width < 1) width = -1;\n\n\t\t\ti = 0;\n\t\t\tif (alloc) {\n\t\t\t\tk = t=='c' ? width+1U : 31;\n\t\t\t\tif (size == SIZE_l) {\n\t\t\t\t\twcs = malloc(k*sizeof(wchar_t));\n\t\t\t\t\tif (!wcs) goto alloc_fail;\n\t\t\t\t} else {\n\t\t\t\t\ts = malloc(k);\n\t\t\t\t\tif (!s) goto alloc_fail;\n\t\t\t\t}\n\t\t\t}\n\t\t\twhile (width) {\n\t\t\t\tif ((c=getwc(f))<0) break;\n\t\t\t\tif (in_set(set, c) == invert)\n\t\t\t\t\tbreak;\n\t\t\t\tif (wcs) {\n\t\t\t\t\twcs[i++] = c;\n\t\t\t\t\tif (alloc && i==k) {\n\t\t\t\t\t\tk += k+1;\n\t\t\t\t\t\twchar_t *tmp = realloc(wcs, k*sizeof(wchar_t));\n\t\t\t\t\t\tif (!tmp) goto alloc_fail;\n\t\t\t\t\t\twcs = tmp;\n\t\t\t\t\t}\n\t\t\t\t} else if (size != SIZE_l) {\n\t\t\t\t\tint l = wctomb(s?s+i:tmp, c);\n\t\t\t\t\tif (l<0) goto input_fail;\n\t\t\t\t\ti += l;\n\t\t\t\t\tif (alloc && i > k-4) {\n\t\t\t\t\t\tk += k+1;\n\t\t\t\t\t\tchar *tmp = realloc(s, k);\n\t\t\t\t\t\tif (!tmp) goto alloc_fail;\n\t\t\t\t\t\ts = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tpos++;\n\t\t\t\twidth-=(width>0);\n\t\t\t\tgotmatch=1;\n\t\t\t}\n\t\t\tif (width) {\n\t\t\t\tungetwc(c, f);\n\t\t\t\tif (t == 'c' || !gotmatch) goto match_fail;\n\t\t\t}\n\n\t\t\tif (alloc) {\n\t\t\t\tif (size == SIZE_l) *(wchar_t **)dest = wcs;\n\t\t\t\telse *(char **)dest = s;\n\t\t\t}\n\t\t\tif (t != 'c') {\n\t\t\t\tif (wcs) wcs[i] = 0;\n\t\t\t\tif (s) s[i] = 0;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase 'd': case 'i': case 'o': case 'u': case 'x':\n\t\tcase 'a': case 'e': case 'f': case 'g':\n\t\tcase 'A': case 'E': case 'F': case 'G': case 'X':\n\t\tcase 'p':\n\t\t\tif (width < 1) width = 0;\n\t\t\tsnprintf(tmp, sizeof tmp, \"%.*s%.0d%s%c%%lln\",\n\t\t\t\t1+!dest, \"%*\", width, size_pfx[size+2], t);\n\t\t\tcnt = 0;\n\t\t\tif (fscanf(f, tmp, dest?dest:&cnt, &cnt) == -1)\n\t\t\t\tgoto input_fail;\n\t\t\telse if (!cnt)\n\t\t\t\tgoto match_fail;\n\t\t\tpos += cnt;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tgoto fmt_fail;\n\t\t}\n\n\t\tif (dest) matches++;\n\t}\n\tif (0) {\nfmt_fail:\nalloc_fail:\ninput_fail:\n\t\tif (!matches) matches--;\nmatch_fail:\n\t\tif (alloc) {\n\t\t\tfree(s);\n\t\t\tfree(wcs);\n\t\t}\n\t}\n\tFUNLOCK(f);\n\treturn matches;\n}\n\nweak_alias(vfwscanf,__isoc99_vfwscanf);\n"
  },
  {
    "path": "user.libc/src/stdio/vprintf.c",
    "content": "#include <stdio.h>\n\nint vprintf(const char *restrict fmt, va_list ap)\n{\n\treturn vfprintf(stdout, fmt, ap);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/vscanf.c",
    "content": "#include <stdio.h>\n#include <stdarg.h>\n\nint vscanf(const char *restrict fmt, va_list ap)\n{\n\treturn vfscanf(stdin, fmt, ap);\n}\n\nweak_alias(vscanf,__isoc99_vscanf);\n"
  },
  {
    "path": "user.libc/src/stdio/vsnprintf.c",
    "content": "#include \"stdio_impl.h\"\n#include <limits.h>\n#include <string.h>\n#include <errno.h>\n#include <stdint.h>\n\nstruct cookie {\n\tchar *s;\n\tsize_t n;\n};\n\n#define MIN(a, b) ((a) < (b) ? (a) : (b))\n\nstatic size_t sn_write(FILE *f, const unsigned char *s, size_t l)\n{\n\tstruct cookie *c = f->cookie;\n\tsize_t k = MIN(c->n, f->wpos - f->wbase);\n\tif (k) {\n\t\tmemcpy(c->s, f->wbase, k);\n\t\tc->s += k;\n\t\tc->n -= k;\n\t}\n\tk = MIN(c->n, l);\n\tif (k) {\n\t\tmemcpy(c->s, s, k);\n\t\tc->s += k;\n\t\tc->n -= k;\n\t}\n\t*c->s = 0;\n\tf->wpos = f->wbase = f->buf;\n\t/* pretend to succeed, even if we discarded extra data */\n\treturn l;\n}\n\nint vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap)\n{\n\tunsigned char buf[1];\n\tchar dummy[1];\n\tstruct cookie c = { .s = n ? s : dummy, .n = n ? n-1 : 0 };\n\tFILE f = {\n\t\t.lbf = EOF,\n\t\t.write = sn_write,\n\t\t.lock = -1,\n\t\t.buf = buf,\n\t\t.cookie = &c,\n\t};\n\n\tif (n > INT_MAX) {\n\t\terrno = EOVERFLOW;\n\t\treturn -1;\n\t}\n\n\t*c.s = 0;\n\treturn vfprintf(&f, fmt, ap);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/vsprintf.c",
    "content": "#include <stdio.h>\n#include <limits.h>\n\nint vsprintf(char *restrict s, const char *restrict fmt, va_list ap)\n{\n\treturn vsnprintf(s, INT_MAX, fmt, ap);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/vsscanf.c",
    "content": "#include \"stdio_impl.h\"\n#include <string.h>\n\nstatic size_t string_read(FILE *f, unsigned char *buf, size_t len)\n{\n\tchar *src = f->cookie;\n\tsize_t k = len+256;\n\tchar *end = memchr(src, 0, k);\n\tif (end) k = end-src;\n\tif (k < len) len = k;\n\tmemcpy(buf, src, len);\n\tf->rpos = (void *)(src+len);\n\tf->rend = (void *)(src+k);\n\tf->cookie = src+k;\n\treturn len;\n}\n\nint vsscanf(const char *restrict s, const char *restrict fmt, va_list ap)\n{\n\tFILE f = {\n\t\t.buf = (void *)s, .cookie = (void *)s,\n\t\t.read = string_read, .lock = -1\n\t};\n\treturn vfscanf(&f, fmt, ap);\n}\n\nweak_alias(vsscanf,__isoc99_vsscanf);\n"
  },
  {
    "path": "user.libc/src/stdio/vswprintf.c",
    "content": "#include \"stdio_impl.h\"\n#include <limits.h>\n#include <errno.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <wchar.h>\n\nstruct cookie {\n\twchar_t *ws;\n\tsize_t l;\n};\n\nstatic size_t sw_write(FILE *f, const unsigned char *s, size_t l)\n{\n\tsize_t l0 = l;\n\tint i = 0;\n\tstruct cookie *c = f->cookie;\n\tif (s!=f->wbase && sw_write(f, f->wbase, f->wpos-f->wbase)==-1)\n\t\treturn -1;\n\twhile (c->l && l && (i=mbtowc(c->ws, (void *)s, l))>=0) {\n\t\ts+=i;\n\t\tl-=i;\n\t\tc->l--;\n\t\tc->ws++;\n\t}\n\t*c->ws = 0;\n\tif (i < 0) {\n\t\tf->wpos = f->wbase = f->wend = 0;\n\t\tf->flags |= F_ERR;\n\t\treturn i;\n\t}\n\tf->wend = f->buf + f->buf_size;\n\tf->wpos = f->wbase = f->buf;\n\treturn l0;\n}\n\nint vswprintf(wchar_t *restrict s, size_t n, const wchar_t *restrict fmt, va_list ap)\n{\n\tint r;\n\tunsigned char buf[256];\n\tstruct cookie c = { s, n-1 };\n\tFILE f = {\n\t\t.lbf = EOF,\n\t\t.write = sw_write,\n\t\t.lock = -1,\n\t\t.buf = buf,\n\t\t.buf_size = sizeof buf,\n\t\t.cookie = &c,\n\t};\n\n\tif (!n) {\n\t\treturn -1;\n\t} else if (n > INT_MAX) {\n\t\terrno = EOVERFLOW;\n\t\treturn -1;\n\t}\n\tr = vfwprintf(&f, fmt, ap);\n\tsw_write(&f, 0, 0);\n\treturn r>=n ? -1 : r;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/vswscanf.c",
    "content": "#include \"stdio_impl.h\"\n#include <wchar.h>\n\nstatic size_t wstring_read(FILE *f, unsigned char *buf, size_t len)\n{\n\tconst wchar_t *src = f->cookie;\n\tsize_t k;\n\n\tif (!src) return 0;\n\n\tk = wcsrtombs((void *)f->buf, &src, f->buf_size, 0);\n\tif (k==(size_t)-1) {\n\t\tf->rpos = f->rend = 0;\n\t\treturn 0;\n\t}\n\n\tf->rpos = f->buf;\n\tf->rend = f->buf + k;\n\tf->cookie = (void *)src;\n\n\tif (!len || !k) return 0;\n\n\t*buf = *f->rpos++;\n\treturn 1;\n}\n\nint vswscanf(const wchar_t *restrict s, const wchar_t *restrict fmt, va_list ap)\n{\n\tunsigned char buf[256];\n\tFILE f = {\n\t\t.buf = buf, .buf_size = sizeof buf,\n\t\t.cookie = (void *)s,\n\t\t.read = wstring_read, .lock = -1\n\t};\n\treturn vfwscanf(&f, fmt, ap);\n}\n\nweak_alias(vswscanf,__isoc99_vswscanf);\n"
  },
  {
    "path": "user.libc/src/stdio/vwprintf.c",
    "content": "#include <stdio.h>\n#include <wchar.h>\n\nint vwprintf(const wchar_t *restrict fmt, va_list ap)\n{\n\treturn vfwprintf(stdout, fmt, ap);\n}\n"
  },
  {
    "path": "user.libc/src/stdio/vwscanf.c",
    "content": "#include <stdio.h>\n#include <stdarg.h>\n#include <wchar.h>\n\nint vwscanf(const wchar_t *restrict fmt, va_list ap)\n{\n\treturn vfwscanf(stdin, fmt, ap);\n}\n\nweak_alias(vwscanf,__isoc99_vwscanf);\n"
  },
  {
    "path": "user.libc/src/stdio/wprintf.c",
    "content": "#include <stdio.h>\n#include <stdarg.h>\n#include <wchar.h>\n\nint wprintf(const wchar_t *restrict fmt, ...)\n{\n\tint ret;\n\tva_list ap;\n\tva_start(ap, fmt);\n\tret = vwprintf(fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n"
  },
  {
    "path": "user.libc/src/stdio/wscanf.c",
    "content": "#include <stdio.h>\n#include <stdarg.h>\n#include <wchar.h>\n\nint wscanf(const wchar_t *restrict fmt, ...)\n{\n\tint ret;\n\tva_list ap;\n\tva_start(ap, fmt);\n\tret = vwscanf(fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n\nweak_alias(wscanf,__isoc99_wscanf);\n"
  },
  {
    "path": "user.libc/src/stdlib/abs.c",
    "content": "#include <stdlib.h>\n\nint abs(int a)\n{\n\treturn a>0 ? a : -a;\n}\n"
  },
  {
    "path": "user.libc/src/stdlib/atof.c",
    "content": "#include <stdlib.h>\n\ndouble atof(const char *s)\n{\n\treturn strtod(s, 0);\n}\n"
  },
  {
    "path": "user.libc/src/stdlib/atoi.c",
    "content": "#include <stdlib.h>\n#include <ctype.h>\n\nint atoi(const char *s)\n{\n\tint n=0, neg=0;\n\twhile (isspace(*s)) s++;\n\tswitch (*s) {\n\tcase '-': neg=1;\n\tcase '+': s++;\n\t}\n\t/* Compute n as a negative number to avoid overflow on INT_MIN */\n\twhile (isdigit(*s))\n\t\tn = 10*n - (*s++ - '0');\n\treturn neg ? n : -n;\n}\n"
  },
  {
    "path": "user.libc/src/stdlib/atol.c",
    "content": "#include <stdlib.h>\n#include <ctype.h>\n\nlong atol(const char *s)\n{\n\tlong n=0;\n\tint neg=0;\n\twhile (isspace(*s)) s++;\n\tswitch (*s) {\n\tcase '-': neg=1;\n\tcase '+': s++;\n\t}\n\t/* Compute n as a negative number to avoid overflow on LONG_MIN */\n\twhile (isdigit(*s))\n\t\tn = 10*n - (*s++ - '0');\n\treturn neg ? n : -n;\n}\n"
  },
  {
    "path": "user.libc/src/stdlib/atoll.c",
    "content": "#include <stdlib.h>\n#include <ctype.h>\n\nlong long atoll(const char *s)\n{\n\tlong long n=0;\n\tint neg=0;\n\twhile (isspace(*s)) s++;\n\tswitch (*s) {\n\tcase '-': neg=1;\n\tcase '+': s++;\n\t}\n\t/* Compute n as a negative number to avoid overflow on LLONG_MIN */\n\twhile (isdigit(*s))\n\t\tn = 10*n - (*s++ - '0');\n\treturn neg ? n : -n;\n}\n"
  },
  {
    "path": "user.libc/src/stdlib/bsearch.c",
    "content": "#include <stdlib.h>\n\nvoid *bsearch(const void *key, const void *base, size_t nel, size_t width, int (*cmp)(const void *, const void *))\n{\n\tvoid *try;\n\tint sign;\n\twhile (nel > 0) {\n\t\ttry = (char *)base + width*(nel/2);\n\t\tsign = cmp(key, try);\n\t\tif (sign < 0) {\n\t\t\tnel /= 2;\n\t\t} else if (sign > 0) {\n\t\t\tbase = (char *)try + width;\n\t\t\tnel -= nel/2+1;\n\t\t} else {\n\t\t\treturn try;\n\t\t}\n\t}\n\treturn NULL;\n}\n"
  },
  {
    "path": "user.libc/src/stdlib/div.c",
    "content": "#include <stdlib.h>\n\ndiv_t div(int num, int den)\n{\n\treturn (div_t){ num/den, num%den };\n}\n"
  },
  {
    "path": "user.libc/src/stdlib/ecvt.c",
    "content": "#define _GNU_SOURCE\n#include <stdlib.h>\n#include <stdio.h>\n\nchar *ecvt(double x, int n, int *dp, int *sign)\n{\n\tstatic char buf[16];\n\tchar tmp[32];\n\tint i, j;\n\n\tif (n-1U > 15) n = 15;\n\tsprintf(tmp, \"%.*e\", n-1, x);\n\ti = *sign = (tmp[0]=='-');\n\tfor (j=0; tmp[i]!='e'; j+=(tmp[i++]!='.'))\n\t\tbuf[j] = tmp[i];\n\tbuf[j] = 0;\n\t*dp = atoi(tmp+i+1)+1;\n\n\treturn buf;\n}\n"
  },
  {
    "path": "user.libc/src/stdlib/fcvt.c",
    "content": "#define _GNU_SOURCE\n#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n\nchar *fcvt(double x, int n, int *dp, int *sign)\n{\n\tchar tmp[1500];\n\tint i, lz;\n\n\tif (n > 1400U) n = 1400;\n\tsprintf(tmp, \"%.*f\", n, x);\n\ti = (tmp[0] == '-');\n\tif (tmp[i] == '0') lz = strspn(tmp+i+2, \"0\");\n\telse lz = -(int)strcspn(tmp+i, \".\");\n\n\tif (n<=lz) {\n\t\t*sign = i;\n\t\t*dp = 1;\n\t\tif (n>14U) n = 14;\n\t\treturn \"000000000000000\"+14-n;\n\t}\n\n\treturn ecvt(x, n-lz, dp, sign);\n}\n"
  },
  {
    "path": "user.libc/src/stdlib/gcvt.c",
    "content": "#define _GNU_SOURCE\n#include <stdlib.h>\n#include <stdio.h>\n\nchar *gcvt(double x, int n, char *b)\n{\n\tsprintf(b, \"%.*g\", n, x);\n\treturn b;\n}\n"
  },
  {
    "path": "user.libc/src/stdlib/imaxabs.c",
    "content": "#include <inttypes.h>\n\nintmax_t imaxabs(intmax_t a)\n{\n\treturn a>0 ? a : -a;\n}\n"
  },
  {
    "path": "user.libc/src/stdlib/imaxdiv.c",
    "content": "#include <inttypes.h>\n\nimaxdiv_t imaxdiv(intmax_t num, intmax_t den)\n{\n\treturn (imaxdiv_t){ num/den, num%den };\n}\n"
  },
  {
    "path": "user.libc/src/stdlib/labs.c",
    "content": "#include <stdlib.h>\n\nlong labs(long a)\n{\n\treturn a>0 ? a : -a;\n}\n"
  },
  {
    "path": "user.libc/src/stdlib/ldiv.c",
    "content": "#include <stdlib.h>\n\nldiv_t ldiv(long num, long den)\n{\n\treturn (ldiv_t){ num/den, num%den };\n}\n"
  },
  {
    "path": "user.libc/src/stdlib/llabs.c",
    "content": "#include <stdlib.h>\n\nlong long llabs(long long a)\n{\n\treturn a>0 ? a : -a;\n}\n"
  },
  {
    "path": "user.libc/src/stdlib/lldiv.c",
    "content": "#include <stdlib.h>\n\nlldiv_t lldiv(long long num, long long den)\n{\n\treturn (lldiv_t){ num/den, num%den };\n}\n"
  },
  {
    "path": "user.libc/src/stdlib/qsort.c",
    "content": "/* Copyright (C) 2011 by Valentin Ochs\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* Minor changes by Rich Felker for integration in musl, 2011-04-27. */\n\n/* Smoothsort, an adaptive variant of Heapsort.  Memory usage: O(1).\n   Run time: Worst case O(n log n), close to O(n) in the mostly-sorted case. */\n\n#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include \"atomic.h\"\n#define ntz(x) a_ctz_l((x))\n\ntypedef int (*cmpfun)(const void *, const void *);\n\nstatic inline int pntz(size_t p[2]) {\n\tint r = ntz(p[0] - 1);\n\tif(r != 0 || (r = 8*sizeof(size_t) + ntz(p[1])) != 8*sizeof(size_t)) {\n\t\treturn r;\n\t}\n\treturn 0;\n}\n\nstatic void cycle(size_t width, unsigned char* ar[], int n)\n{\n\tunsigned char tmp[256];\n\tsize_t l;\n\tint i;\n\n\tif(n < 2) {\n\t\treturn;\n\t}\n\n\tar[n] = tmp;\n\twhile(width) {\n\t\tl = sizeof(tmp) < width ? sizeof(tmp) : width;\n\t\tmemcpy(ar[n], ar[0], l);\n\t\tfor(i = 0; i < n; i++) {\n\t\t\tmemcpy(ar[i], ar[i + 1], l);\n\t\t\tar[i] += l;\n\t\t}\n\t\twidth -= l;\n\t}\n}\n\n/* shl() and shr() need n > 0 */\nstatic inline void shl(size_t p[2], int n)\n{\n\tif(n >= 8 * sizeof(size_t)) {\n\t\tn -= 8 * sizeof(size_t);\n\t\tp[1] = p[0];\n\t\tp[0] = 0;\n\t}\n\tp[1] <<= n;\n\tp[1] |= p[0] >> (sizeof(size_t) * 8 - n);\n\tp[0] <<= n;\n}\n\nstatic inline void shr(size_t p[2], int n)\n{\n\tif(n >= 8 * sizeof(size_t)) {\n\t\tn -= 8 * sizeof(size_t);\n\t\tp[0] = p[1];\n\t\tp[1] = 0;\n\t}\n\tp[0] >>= n;\n\tp[0] |= p[1] << (sizeof(size_t) * 8 - n);\n\tp[1] >>= n;\n}\n\nstatic void sift(unsigned char *head, size_t width, cmpfun cmp, int pshift, size_t lp[])\n{\n\tunsigned char *rt, *lf;\n\tunsigned char *ar[14 * sizeof(size_t) + 1];\n\tint i = 1;\n\n\tar[0] = head;\n\twhile(pshift > 1) {\n\t\trt = head - width;\n\t\tlf = head - width - lp[pshift - 2];\n\n\t\tif((*cmp)(ar[0], lf) >= 0 && (*cmp)(ar[0], rt) >= 0) {\n\t\t\tbreak;\n\t\t}\n\t\tif((*cmp)(lf, rt) >= 0) {\n\t\t\tar[i++] = lf;\n\t\t\thead = lf;\n\t\t\tpshift -= 1;\n\t\t} else {\n\t\t\tar[i++] = rt;\n\t\t\thead = rt;\n\t\t\tpshift -= 2;\n\t\t}\n\t}\n\tcycle(width, ar, i);\n}\n\nstatic void trinkle(unsigned char *head, size_t width, cmpfun cmp, size_t pp[2], int pshift, int trusty, size_t lp[])\n{\n\tunsigned char *stepson,\n\t              *rt, *lf;\n\tsize_t p[2];\n\tunsigned char *ar[14 * sizeof(size_t) + 1];\n\tint i = 1;\n\tint trail;\n\n\tp[0] = pp[0];\n\tp[1] = pp[1];\n\n\tar[0] = head;\n\twhile(p[0] != 1 || p[1] != 0) {\n\t\tstepson = head - lp[pshift];\n\t\tif((*cmp)(stepson, ar[0]) <= 0) {\n\t\t\tbreak;\n\t\t}\n\t\tif(!trusty && pshift > 1) {\n\t\t\trt = head - width;\n\t\t\tlf = head - width - lp[pshift - 2];\n\t\t\tif((*cmp)(rt, stepson) >= 0 || (*cmp)(lf, stepson) >= 0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tar[i++] = stepson;\n\t\thead = stepson;\n\t\ttrail = pntz(p);\n\t\tshr(p, trail);\n\t\tpshift += trail;\n\t\ttrusty = 0;\n\t}\n\tif(!trusty) {\n\t\tcycle(width, ar, i);\n\t\tsift(head, width, cmp, pshift, lp);\n\t}\n}\n\nvoid qsort(void *base, size_t nel, size_t width, cmpfun cmp)\n{\n\tsize_t lp[12*sizeof(size_t)];\n\tsize_t i, size = width * nel;\n\tunsigned char *head, *high;\n\tsize_t p[2] = {1, 0};\n\tint pshift = 1;\n\tint trail;\n\n\tif (!size) return;\n\n\thead = base;\n\thigh = head + size - width;\n\n\t/* Precompute Leonardo numbers, scaled by element width */\n\tfor(lp[0]=lp[1]=width, i=2; (lp[i]=lp[i-2]+lp[i-1]+width) < size; i++);\n\n\twhile(head < high) {\n\t\tif((p[0] & 3) == 3) {\n\t\t\tsift(head, width, cmp, pshift, lp);\n\t\t\tshr(p, 2);\n\t\t\tpshift += 2;\n\t\t} else {\n\t\t\tif(lp[pshift - 1] >= high - head) {\n\t\t\t\ttrinkle(head, width, cmp, p, pshift, 0, lp);\n\t\t\t} else {\n\t\t\t\tsift(head, width, cmp, pshift, lp);\n\t\t\t}\n\t\t\t\n\t\t\tif(pshift == 1) {\n\t\t\t\tshl(p, 1);\n\t\t\t\tpshift = 0;\n\t\t\t} else {\n\t\t\t\tshl(p, pshift - 1);\n\t\t\t\tpshift = 1;\n\t\t\t}\n\t\t}\n\t\t\n\t\tp[0] |= 1;\n\t\thead += width;\n\t}\n\n\ttrinkle(head, width, cmp, p, pshift, 0, lp);\n\n\twhile(pshift != 1 || p[0] != 1 || p[1] != 0) {\n\t\tif(pshift <= 1) {\n\t\t\ttrail = pntz(p);\n\t\t\tshr(p, trail);\n\t\t\tpshift += trail;\n\t\t} else {\n\t\t\tshl(p, 2);\n\t\t\tpshift -= 2;\n\t\t\tp[0] ^= 7;\n\t\t\tshr(p, 1);\n\t\t\ttrinkle(head - lp[pshift] - width, width, cmp, p, pshift + 1, 1, lp);\n\t\t\tshl(p, 1);\n\t\t\tp[0] |= 1;\n\t\t\ttrinkle(head - width, width, cmp, p, pshift, 1, lp);\n\t\t}\n\t\thead -= width;\n\t}\n}\n"
  },
  {
    "path": "user.libc/src/stdlib/strtod.c",
    "content": "#include <stdlib.h>\n#include \"shgetc.h\"\n#include \"floatscan.h\"\n#include \"stdio_impl.h\"\n\nstatic long double strtox(const char *s, char **p, int prec)\n{\n\tFILE f;\n\tsh_fromstring(&f, s);\n\tshlim(&f, 0);\n\tlong double y = __floatscan(&f, prec, 1);\n\toff_t cnt = shcnt(&f);\n\tif (p) *p = cnt ? (char *)s + cnt : (char *)s;\n\treturn y;\n}\n\nfloat strtof(const char *restrict s, char **restrict p)\n{\n\treturn strtox(s, p, 0);\n}\n\ndouble strtod(const char *restrict s, char **restrict p)\n{\n\treturn strtox(s, p, 1);\n}\n\nlong double strtold(const char *restrict s, char **restrict p)\n{\n\treturn strtox(s, p, 2);\n}\n\nweak_alias(strtof, strtof_l);\nweak_alias(strtod, strtod_l);\nweak_alias(strtold, strtold_l);\nweak_alias(strtof, __strtof_l);\nweak_alias(strtod, __strtod_l);\nweak_alias(strtold, __strtold_l);\n"
  },
  {
    "path": "user.libc/src/stdlib/strtol.c",
    "content": "#include \"stdio_impl.h\"\n#include \"intscan.h\"\n#include \"shgetc.h\"\n#include <inttypes.h>\n#include <limits.h>\n#include <ctype.h>\n\nstatic unsigned long long strtox(const char *s, char **p, int base, unsigned long long lim)\n{\n\tFILE f;\n\tsh_fromstring(&f, s);\n\tshlim(&f, 0);\n\tunsigned long long y = __intscan(&f, base, 1, lim);\n\tif (p) {\n\t\tsize_t cnt = shcnt(&f);\n\t\t*p = (char *)s + cnt;\n\t}\n\treturn y;\n}\n\nunsigned long long strtoull(const char *restrict s, char **restrict p, int base)\n{\n\treturn strtox(s, p, base, ULLONG_MAX);\n}\n\nlong long strtoll(const char *restrict s, char **restrict p, int base)\n{\n\treturn strtox(s, p, base, LLONG_MIN);\n}\n\nunsigned long strtoul(const char *restrict s, char **restrict p, int base)\n{\n\treturn strtox(s, p, base, ULONG_MAX);\n}\n\nlong strtol(const char *restrict s, char **restrict p, int base)\n{\n\treturn strtox(s, p, base, 0UL+LONG_MIN);\n}\n\nintmax_t strtoimax(const char *restrict s, char **restrict p, int base)\n{\n\treturn strtoll(s, p, base);\n}\n\nuintmax_t strtoumax(const char *restrict s, char **restrict p, int base)\n{\n\treturn strtoull(s, p, base);\n}\n\nweak_alias(strtol, __strtol_internal);\nweak_alias(strtoul, __strtoul_internal);\nweak_alias(strtoll, __strtoll_internal);\nweak_alias(strtoull, __strtoull_internal);\nweak_alias(strtoimax, __strtoimax_internal);\nweak_alias(strtoumax, __strtoumax_internal);\n"
  },
  {
    "path": "user.libc/src/stdlib/wcstod.c",
    "content": "#include \"shgetc.h\"\n#include \"floatscan.h\"\n#include \"stdio_impl.h\"\n#include <wchar.h>\n#include <wctype.h>\n\n/* This read function heavily cheats. It knows:\n *  (1) len will always be 1\n *  (2) non-ascii characters don't matter */\n\nstatic size_t do_read(FILE *f, unsigned char *buf, size_t len)\n{\n\tsize_t i;\n\tconst wchar_t *wcs = f->cookie;\n\n\tif (!wcs[0]) wcs=L\"@\";\n\tfor (i=0; i<f->buf_size && wcs[i]; i++)\n\t\tf->buf[i] = wcs[i] < 128 ? wcs[i] : '@';\n\tf->rpos = f->buf;\n\tf->rend = f->buf + i;\n\tf->cookie = (void *)(wcs+i);\n\n\tif (i && len) {\n\t\t*buf = *f->rpos++;\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nstatic long double wcstox(const wchar_t *s, wchar_t **p, int prec)\n{\n\twchar_t *t = (wchar_t *)s;\n\tunsigned char buf[64];\n\tFILE f = {0};\n\tf.flags = 0;\n\tf.rpos = f.rend = f.buf = buf + 4;\n\tf.buf_size = sizeof buf - 4;\n\tf.lock = -1;\n\tf.read = do_read;\n\twhile (iswspace(*t)) t++;\n\tf.cookie = (void *)t;\n\tshlim(&f, 0);\n\tlong double y = __floatscan(&f, prec, 1);\n\tif (p) {\n\t\tsize_t cnt = shcnt(&f);\n\t\t*p = cnt ? t + cnt : (wchar_t *)s;\n\t}\n\treturn y;\n}\n\nfloat wcstof(const wchar_t *restrict s, wchar_t **restrict p)\n{\n\treturn wcstox(s, p, 0);\n}\n\ndouble wcstod(const wchar_t *restrict s, wchar_t **restrict p)\n{\n\treturn wcstox(s, p, 1);\n}\n\nlong double wcstold(const wchar_t *restrict s, wchar_t **restrict p)\n{\n\treturn wcstox(s, p, 2);\n}\n"
  },
  {
    "path": "user.libc/src/stdlib/wcstol.c",
    "content": "#include \"stdio_impl.h\"\n#include \"intscan.h\"\n#include \"shgetc.h\"\n#include <inttypes.h>\n#include <limits.h>\n#include <wctype.h>\n#include <wchar.h>\n\n/* This read function heavily cheats. It knows:\n *  (1) len will always be 1\n *  (2) non-ascii characters don't matter */\n\nstatic size_t do_read(FILE *f, unsigned char *buf, size_t len)\n{\n\tsize_t i;\n\tconst wchar_t *wcs = f->cookie;\n\n\tif (!wcs[0]) wcs=L\"@\";\n\tfor (i=0; i<f->buf_size && wcs[i]; i++)\n\t\tf->buf[i] = wcs[i] < 128 ? wcs[i] : '@';\n\tf->rpos = f->buf;\n\tf->rend = f->buf + i;\n\tf->cookie = (void *)(wcs+i);\n\n\tif (i && len) {\n\t\t*buf = *f->rpos++;\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nstatic unsigned long long wcstox(const wchar_t *s, wchar_t **p, int base, unsigned long long lim)\n{\n\twchar_t *t = (wchar_t *)s;\n\tunsigned char buf[64];\n\tFILE f = {0};\n\tf.flags = 0;\n\tf.rpos = f.rend = f.buf = buf + 4;\n\tf.buf_size = sizeof buf - 4;\n\tf.lock = -1;\n\tf.read = do_read;\n\twhile (iswspace(*t)) t++;\n\tf.cookie = (void *)t;\n\tshlim(&f, 0);\n\tunsigned long long y = __intscan(&f, base, 1, lim);\n\tif (p) {\n\t\tsize_t cnt = shcnt(&f);\n\t\t*p = cnt ? t + cnt : (wchar_t *)s;\n\t}\n\treturn y;\n}\n\nunsigned long long wcstoull(const wchar_t *restrict s, wchar_t **restrict p, int base)\n{\n\treturn wcstox(s, p, base, ULLONG_MAX);\n}\n\nlong long wcstoll(const wchar_t *restrict s, wchar_t **restrict p, int base)\n{\n\treturn wcstox(s, p, base, LLONG_MIN);\n}\n\nunsigned long wcstoul(const wchar_t *restrict s, wchar_t **restrict p, int base)\n{\n\treturn wcstox(s, p, base, ULONG_MAX);\n}\n\nlong wcstol(const wchar_t *restrict s, wchar_t **restrict p, int base)\n{\n\treturn wcstox(s, p, base, 0UL+LONG_MIN);\n}\n\nintmax_t wcstoimax(const wchar_t *restrict s, wchar_t **restrict p, int base)\n{\n\treturn wcstoll(s, p, base);\n}\n\nuintmax_t wcstoumax(const wchar_t *restrict s, wchar_t **restrict p, int base)\n{\n\treturn wcstoull(s, p, base);\n}\n"
  },
  {
    "path": "user.libc/src/string/bcmp.c",
    "content": "#define _BSD_SOURCE\n#include <string.h>\n#include <strings.h>\n\nint bcmp(const void *s1, const void *s2, size_t n)\n{\n\treturn memcmp(s1, s2, n);\n}\n"
  },
  {
    "path": "user.libc/src/string/bcopy.c",
    "content": "#define _BSD_SOURCE\n#include <string.h>\n#include <strings.h>\n\nvoid bcopy(const void *s1, void *s2, size_t n)\n{\n\tmemmove(s2, s1, n);\n}\n"
  },
  {
    "path": "user.libc/src/string/bzero.c",
    "content": "#define _BSD_SOURCE\n#include <string.h>\n#include <strings.h>\n\nvoid bzero(void *s, size_t n)\n{\n\tmemset(s, 0, n);\n}\n"
  },
  {
    "path": "user.libc/src/string/explicit_bzero.c",
    "content": "#define _BSD_SOURCE\n#include <string.h>\n\nvoid explicit_bzero(void *d, size_t n)\n{\n\td = memset(d, 0, n);\n\t__asm__ __volatile__ (\"\" : : \"r\"(d) : \"memory\");\n}\n"
  },
  {
    "path": "user.libc/src/string/index.c",
    "content": "#define _BSD_SOURCE\n#include <string.h>\n#include <strings.h>\n\nchar *index(const char *s, int c)\n{\n\treturn strchr(s, c);\n}\n"
  },
  {
    "path": "user.libc/src/string/memccpy.c",
    "content": "#include <string.h>\n#include <stdint.h>\n#include <limits.h>\n\n#define ALIGN (sizeof(size_t)-1)\n#define ONES ((size_t)-1/UCHAR_MAX)\n#define HIGHS (ONES * (UCHAR_MAX/2+1))\n#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)\n\nvoid *memccpy(void *restrict dest, const void *restrict src, int c, size_t n)\n{\n\tunsigned char *d = dest;\n\tconst unsigned char *s = src;\n\n\tc = (unsigned char)c;\n#ifdef __GNUC__\n\ttypedef size_t __attribute__((__may_alias__)) word;\n\tword *wd;\n\tconst word *ws;\n\tif (((uintptr_t)s & ALIGN) == ((uintptr_t)d & ALIGN)) {\n\t\tfor (; ((uintptr_t)s & ALIGN) && n && (*d=*s)!=c; n--, s++, d++);\n\t\tif ((uintptr_t)s & ALIGN) goto tail;\n\t\tsize_t k = ONES * c;\n\t\twd=(void *)d; ws=(const void *)s;\n\t\tfor (; n>=sizeof(size_t) && !HASZERO(*ws^k);\n\t\t       n-=sizeof(size_t), ws++, wd++) *wd = *ws;\n\t\td=(void *)wd; s=(const void *)ws;\n\t}\n#endif\n\tfor (; n && (*d=*s)!=c; n--, s++, d++);\ntail:\n\tif (n) return d+1;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/string/memchr.c",
    "content": "#include <string.h>\n#include <stdint.h>\n#include <limits.h>\n\n#define SS (sizeof(size_t))\n#define ALIGN (sizeof(size_t)-1)\n#define ONES ((size_t)-1/UCHAR_MAX)\n#define HIGHS (ONES * (UCHAR_MAX/2+1))\n#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)\n\nvoid *memchr(const void *src, int c, size_t n)\n{\n\tconst unsigned char *s = src;\n\tc = (unsigned char)c;\n#ifdef __GNUC__\n\tfor (; ((uintptr_t)s & ALIGN) && n && *s != c; s++, n--);\n\tif (n && *s != c) {\n\t\ttypedef size_t __attribute__((__may_alias__)) word;\n\t\tconst word *w;\n\t\tsize_t k = ONES * c;\n\t\tfor (w = (const void *)s; n>=SS && !HASZERO(*w^k); w++, n-=SS);\n\t\ts = (const void *)w;\n\t}\n#endif\n\tfor (; n && *s != c; s++, n--);\n\treturn n ? (void *)s : 0;\n}\n"
  },
  {
    "path": "user.libc/src/string/memcmp.c",
    "content": "#include <string.h>\n\nint memcmp(const void *vl, const void *vr, size_t n)\n{\n\tconst unsigned char *l=vl, *r=vr;\n\tfor (; n && *l == *r; n--, l++, r++);\n\treturn n ? *l-*r : 0;\n}\n"
  },
  {
    "path": "user.libc/src/string/memcpy.c",
    "content": "#include <string.h>\n#include <stdint.h>\n#include <endian.h>\n\nvoid *memcpy(void *restrict dest, const void *restrict src, size_t n)\n{\n\tunsigned char *d = dest;\n\tconst unsigned char *s = src;\n\n#ifdef __GNUC__\n\n#if __BYTE_ORDER == __LITTLE_ENDIAN\n#define LS >>\n#define RS <<\n#else\n#define LS <<\n#define RS >>\n#endif\n\n\ttypedef uint32_t __attribute__((__may_alias__)) u32;\n\tuint32_t w, x;\n\n\tfor (; (uintptr_t)s % 4 && n; n--) *d++ = *s++;\n\n\tif ((uintptr_t)d % 4 == 0) {\n\t\tfor (; n>=16; s+=16, d+=16, n-=16) {\n\t\t\t*(u32 *)(d+0) = *(u32 *)(s+0);\n\t\t\t*(u32 *)(d+4) = *(u32 *)(s+4);\n\t\t\t*(u32 *)(d+8) = *(u32 *)(s+8);\n\t\t\t*(u32 *)(d+12) = *(u32 *)(s+12);\n\t\t}\n\t\tif (n&8) {\n\t\t\t*(u32 *)(d+0) = *(u32 *)(s+0);\n\t\t\t*(u32 *)(d+4) = *(u32 *)(s+4);\n\t\t\td += 8; s += 8;\n\t\t}\n\t\tif (n&4) {\n\t\t\t*(u32 *)(d+0) = *(u32 *)(s+0);\n\t\t\td += 4; s += 4;\n\t\t}\n\t\tif (n&2) {\n\t\t\t*d++ = *s++; *d++ = *s++;\n\t\t}\n\t\tif (n&1) {\n\t\t\t*d = *s;\n\t\t}\n\t\treturn dest;\n\t}\n\n\tif (n >= 32) switch ((uintptr_t)d % 4) {\n\tcase 1:\n\t\tw = *(u32 *)s;\n\t\t*d++ = *s++;\n\t\t*d++ = *s++;\n\t\t*d++ = *s++;\n\t\tn -= 3;\n\t\tfor (; n>=17; s+=16, d+=16, n-=16) {\n\t\t\tx = *(u32 *)(s+1);\n\t\t\t*(u32 *)(d+0) = (w LS 24) | (x RS 8);\n\t\t\tw = *(u32 *)(s+5);\n\t\t\t*(u32 *)(d+4) = (x LS 24) | (w RS 8);\n\t\t\tx = *(u32 *)(s+9);\n\t\t\t*(u32 *)(d+8) = (w LS 24) | (x RS 8);\n\t\t\tw = *(u32 *)(s+13);\n\t\t\t*(u32 *)(d+12) = (x LS 24) | (w RS 8);\n\t\t}\n\t\tbreak;\n\tcase 2:\n\t\tw = *(u32 *)s;\n\t\t*d++ = *s++;\n\t\t*d++ = *s++;\n\t\tn -= 2;\n\t\tfor (; n>=18; s+=16, d+=16, n-=16) {\n\t\t\tx = *(u32 *)(s+2);\n\t\t\t*(u32 *)(d+0) = (w LS 16) | (x RS 16);\n\t\t\tw = *(u32 *)(s+6);\n\t\t\t*(u32 *)(d+4) = (x LS 16) | (w RS 16);\n\t\t\tx = *(u32 *)(s+10);\n\t\t\t*(u32 *)(d+8) = (w LS 16) | (x RS 16);\n\t\t\tw = *(u32 *)(s+14);\n\t\t\t*(u32 *)(d+12) = (x LS 16) | (w RS 16);\n\t\t}\n\t\tbreak;\n\tcase 3:\n\t\tw = *(u32 *)s;\n\t\t*d++ = *s++;\n\t\tn -= 1;\n\t\tfor (; n>=19; s+=16, d+=16, n-=16) {\n\t\t\tx = *(u32 *)(s+3);\n\t\t\t*(u32 *)(d+0) = (w LS 8) | (x RS 24);\n\t\t\tw = *(u32 *)(s+7);\n\t\t\t*(u32 *)(d+4) = (x LS 8) | (w RS 24);\n\t\t\tx = *(u32 *)(s+11);\n\t\t\t*(u32 *)(d+8) = (w LS 8) | (x RS 24);\n\t\t\tw = *(u32 *)(s+15);\n\t\t\t*(u32 *)(d+12) = (x LS 8) | (w RS 24);\n\t\t}\n\t\tbreak;\n\t}\n\tif (n&16) {\n\t\t*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;\n\t\t*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;\n\t\t*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;\n\t\t*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;\n\t}\n\tif (n&8) {\n\t\t*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;\n\t\t*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;\n\t}\n\tif (n&4) {\n\t\t*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;\n\t}\n\tif (n&2) {\n\t\t*d++ = *s++; *d++ = *s++;\n\t}\n\tif (n&1) {\n\t\t*d = *s;\n\t}\n\treturn dest;\n#endif\n\n\tfor (; n; n--) *d++ = *s++;\n\treturn dest;\n}\n"
  },
  {
    "path": "user.libc/src/string/memmem.c",
    "content": "#define _GNU_SOURCE\n#include <string.h>\n#include <stdint.h>\n\nstatic char *twobyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)\n{\n\tuint16_t nw = n[0]<<8 | n[1], hw = h[0]<<8 | h[1];\n\tfor (h+=2, k-=2; k; k--, hw = hw<<8 | *h++)\n\t\tif (hw == nw) return (char *)h-2;\n\treturn hw == nw ? (char *)h-2 : 0;\n}\n\nstatic char *threebyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)\n{\n\tuint32_t nw = (uint32_t)n[0]<<24 | n[1]<<16 | n[2]<<8;\n\tuint32_t hw = (uint32_t)h[0]<<24 | h[1]<<16 | h[2]<<8;\n\tfor (h+=3, k-=3; k; k--, hw = (hw|*h++)<<8)\n\t\tif (hw == nw) return (char *)h-3;\n\treturn hw == nw ? (char *)h-3 : 0;\n}\n\nstatic char *fourbyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)\n{\n\tuint32_t nw = (uint32_t)n[0]<<24 | n[1]<<16 | n[2]<<8 | n[3];\n\tuint32_t hw = (uint32_t)h[0]<<24 | h[1]<<16 | h[2]<<8 | h[3];\n\tfor (h+=4, k-=4; k; k--, hw = hw<<8 | *h++)\n\t\tif (hw == nw) return (char *)h-4;\n\treturn hw == nw ? (char *)h-4 : 0;\n}\n\n#define MAX(a,b) ((a)>(b)?(a):(b))\n#define MIN(a,b) ((a)<(b)?(a):(b))\n\n#define BITOP(a,b,op) \\\n ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))\n\nstatic char *twoway_memmem(const unsigned char *h, const unsigned char *z, const unsigned char *n, size_t l)\n{\n\tsize_t i, ip, jp, k, p, ms, p0, mem, mem0;\n\tsize_t byteset[32 / sizeof(size_t)] = { 0 };\n\tsize_t shift[256];\n\n\t/* Computing length of needle and fill shift table */\n\tfor (i=0; i<l; i++)\n\t\tBITOP(byteset, n[i], |=), shift[n[i]] = i+1;\n\n\t/* Compute maximal suffix */\n\tip = -1; jp = 0; k = p = 1;\n\twhile (jp+k<l) {\n\t\tif (n[ip+k] == n[jp+k]) {\n\t\t\tif (k == p) {\n\t\t\t\tjp += p;\n\t\t\t\tk = 1;\n\t\t\t} else k++;\n\t\t} else if (n[ip+k] > n[jp+k]) {\n\t\t\tjp += k;\n\t\t\tk = 1;\n\t\t\tp = jp - ip;\n\t\t} else {\n\t\t\tip = jp++;\n\t\t\tk = p = 1;\n\t\t}\n\t}\n\tms = ip;\n\tp0 = p;\n\n\t/* And with the opposite comparison */\n\tip = -1; jp = 0; k = p = 1;\n\twhile (jp+k<l) {\n\t\tif (n[ip+k] == n[jp+k]) {\n\t\t\tif (k == p) {\n\t\t\t\tjp += p;\n\t\t\t\tk = 1;\n\t\t\t} else k++;\n\t\t} else if (n[ip+k] < n[jp+k]) {\n\t\t\tjp += k;\n\t\t\tk = 1;\n\t\t\tp = jp - ip;\n\t\t} else {\n\t\t\tip = jp++;\n\t\t\tk = p = 1;\n\t\t}\n\t}\n\tif (ip+1 > ms+1) ms = ip;\n\telse p = p0;\n\n\t/* Periodic needle? */\n\tif (memcmp(n, n+p, ms+1)) {\n\t\tmem0 = 0;\n\t\tp = MAX(ms, l-ms-1) + 1;\n\t} else mem0 = l-p;\n\tmem = 0;\n\n\t/* Search loop */\n\tfor (;;) {\n\t\t/* If remainder of haystack is shorter than needle, done */\n\t\tif (z-h < l) return 0;\n\n\t\t/* Check last byte first; advance by shift on mismatch */\n\t\tif (BITOP(byteset, h[l-1], &)) {\n\t\t\tk = l-shift[h[l-1]];\n\t\t\tif (k) {\n\t\t\t\tif (k < mem) k = mem;\n\t\t\t\th += k;\n\t\t\t\tmem = 0;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t} else {\n\t\t\th += l;\n\t\t\tmem = 0;\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* Compare right half */\n\t\tfor (k=MAX(ms+1,mem); k<l && n[k] == h[k]; k++);\n\t\tif (k < l) {\n\t\t\th += k-ms;\n\t\t\tmem = 0;\n\t\t\tcontinue;\n\t\t}\n\t\t/* Compare left half */\n\t\tfor (k=ms+1; k>mem && n[k-1] == h[k-1]; k--);\n\t\tif (k <= mem) return (char *)h;\n\t\th += p;\n\t\tmem = mem0;\n\t}\n}\n\nvoid *memmem(const void *h0, size_t k, const void *n0, size_t l)\n{\n\tconst unsigned char *h = h0, *n = n0;\n\n\t/* Return immediately on empty needle */\n\tif (!l) return (void *)h;\n\n\t/* Return immediately when needle is longer than haystack */\n\tif (k<l) return 0;\n\n\t/* Use faster algorithms for short needles */\n\th = memchr(h0, *n, k);\n\tif (!h || l==1) return (void *)h;\n\tk -= h - (const unsigned char *)h0;\n\tif (k<l) return 0;\n\tif (l==2) return twobyte_memmem(h, k, n);\n\tif (l==3) return threebyte_memmem(h, k, n);\n\tif (l==4) return fourbyte_memmem(h, k, n);\n\n\treturn twoway_memmem(h, h+k, n, l);\n}\n"
  },
  {
    "path": "user.libc/src/string/memmove.c",
    "content": "#include <string.h>\n#include <stdint.h>\n\n#ifdef __GNUC__\ntypedef __attribute__((__may_alias__)) size_t WT;\n#define WS (sizeof(WT))\n#endif\n\nvoid *memmove(void *dest, const void *src, size_t n)\n{\n\tchar *d = dest;\n\tconst char *s = src;\n\n\tif (d==s) return d;\n\tif ((uintptr_t)s-(uintptr_t)d-n <= -2*n) return memcpy(d, s, n);\n\n\tif (d<s) {\n#ifdef __GNUC__\n\t\tif ((uintptr_t)s % WS == (uintptr_t)d % WS) {\n\t\t\twhile ((uintptr_t)d % WS) {\n\t\t\t\tif (!n--) return dest;\n\t\t\t\t*d++ = *s++;\n\t\t\t}\n\t\t\tfor (; n>=WS; n-=WS, d+=WS, s+=WS) *(WT *)d = *(WT *)s;\n\t\t}\n#endif\n\t\tfor (; n; n--) *d++ = *s++;\n\t} else {\n#ifdef __GNUC__\n\t\tif ((uintptr_t)s % WS == (uintptr_t)d % WS) {\n\t\t\twhile ((uintptr_t)(d+n) % WS) {\n\t\t\t\tif (!n--) return dest;\n\t\t\t\td[n] = s[n];\n\t\t\t}\n\t\t\twhile (n>=WS) n-=WS, *(WT *)(d+n) = *(WT *)(s+n);\n\t\t}\n#endif\n\t\twhile (n) n--, d[n] = s[n];\n\t}\n\n\treturn dest;\n}\n"
  },
  {
    "path": "user.libc/src/string/mempcpy.c",
    "content": "#define _GNU_SOURCE\n#include <string.h>\n\nvoid *mempcpy(void *dest, const void *src, size_t n)\n{\n\treturn (char *)memcpy(dest, src, n) + n;\n}\n"
  },
  {
    "path": "user.libc/src/string/memrchr.c",
    "content": "#include <string.h>\n\nvoid *__memrchr(const void *m, int c, size_t n)\n{\n\tconst unsigned char *s = m;\n\tc = (unsigned char)c;\n\twhile (n--) if (s[n]==c) return (void *)(s+n);\n\treturn 0;\n}\n\nweak_alias(__memrchr, memrchr);\n"
  },
  {
    "path": "user.libc/src/string/memset.c",
    "content": "#include <string.h>\n#include <stdint.h>\n\nvoid *memset(void *dest, int c, size_t n)\n{\n\tunsigned char *s = dest;\n\tsize_t k;\n\n\t/* Fill head and tail with minimal branching. Each\n\t * conditional ensures that all the subsequently used\n\t * offsets are well-defined and in the dest region. */\n\n\tif (!n) return dest;\n\ts[0] = c;\n\ts[n-1] = c;\n\tif (n <= 2) return dest;\n\ts[1] = c;\n\ts[2] = c;\n\ts[n-2] = c;\n\ts[n-3] = c;\n\tif (n <= 6) return dest;\n\ts[3] = c;\n\ts[n-4] = c;\n\tif (n <= 8) return dest;\n\n\t/* Advance pointer to align it at a 4-byte boundary,\n\t * and truncate n to a multiple of 4. The previous code\n\t * already took care of any head/tail that get cut off\n\t * by the alignment. */\n\n\tk = -(uintptr_t)s & 3;\n\ts += k;\n\tn -= k;\n\tn &= -4;\n\n#ifdef __GNUC__\n\ttypedef uint32_t __attribute__((__may_alias__)) u32;\n\ttypedef uint64_t __attribute__((__may_alias__)) u64;\n\n\tu32 c32 = ((u32)-1)/255 * (unsigned char)c;\n\n\t/* In preparation to copy 32 bytes at a time, aligned on\n\t * an 8-byte bounary, fill head/tail up to 28 bytes each.\n\t * As in the initial byte-based head/tail fill, each\n\t * conditional below ensures that the subsequent offsets\n\t * are valid (e.g. !(n<=24) implies n>=28). */\n\n\t*(u32 *)(s+0) = c32;\n\t*(u32 *)(s+n-4) = c32;\n\tif (n <= 8) return dest;\n\t*(u32 *)(s+4) = c32;\n\t*(u32 *)(s+8) = c32;\n\t*(u32 *)(s+n-12) = c32;\n\t*(u32 *)(s+n-8) = c32;\n\tif (n <= 24) return dest;\n\t*(u32 *)(s+12) = c32;\n\t*(u32 *)(s+16) = c32;\n\t*(u32 *)(s+20) = c32;\n\t*(u32 *)(s+24) = c32;\n\t*(u32 *)(s+n-28) = c32;\n\t*(u32 *)(s+n-24) = c32;\n\t*(u32 *)(s+n-20) = c32;\n\t*(u32 *)(s+n-16) = c32;\n\n\t/* Align to a multiple of 8 so we can fill 64 bits at a time,\n\t * and avoid writing the same bytes twice as much as is\n\t * practical without introducing additional branching. */\n\n\tk = 24 + ((uintptr_t)s & 4);\n\ts += k;\n\tn -= k;\n\n\t/* If this loop is reached, 28 tail bytes have already been\n\t * filled, so any remainder when n drops below 32 can be\n\t * safely ignored. */\n\n\tu64 c64 = c32 | ((u64)c32 << 32);\n\tfor (; n >= 32; n-=32, s+=32) {\n\t\t*(u64 *)(s+0) = c64;\n\t\t*(u64 *)(s+8) = c64;\n\t\t*(u64 *)(s+16) = c64;\n\t\t*(u64 *)(s+24) = c64;\n\t}\n#else\n\t/* Pure C fallback with no aliasing violations. */\n\tfor (; n; n--, s++) *s = c;\n#endif\n\n\treturn dest;\n}\n"
  },
  {
    "path": "user.libc/src/string/rindex.c",
    "content": "#define _BSD_SOURCE\n#include <string.h>\n#include <strings.h>\n\nchar *rindex(const char *s, int c)\n{\n\treturn strrchr(s, c);\n}\n"
  },
  {
    "path": "user.libc/src/string/stpcpy.c",
    "content": "#include <string.h>\n#include <stdint.h>\n#include <limits.h>\n\n#define ALIGN (sizeof(size_t))\n#define ONES ((size_t)-1/UCHAR_MAX)\n#define HIGHS (ONES * (UCHAR_MAX/2+1))\n#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)\n\nchar *__stpcpy(char *restrict d, const char *restrict s)\n{\n#ifdef __GNUC__\n\ttypedef size_t __attribute__((__may_alias__)) word;\n\tword *wd;\n\tconst word *ws;\n\tif ((uintptr_t)s % ALIGN == (uintptr_t)d % ALIGN) {\n\t\tfor (; (uintptr_t)s % ALIGN; s++, d++)\n\t\t\tif (!(*d=*s)) return d;\n\t\twd=(void *)d; ws=(const void *)s;\n\t\tfor (; !HASZERO(*ws); *wd++ = *ws++);\n\t\td=(void *)wd; s=(const void *)ws;\n\t}\n#endif\n\tfor (; (*d=*s); s++, d++);\n\n\treturn d;\n}\n\nweak_alias(__stpcpy, stpcpy);\n"
  },
  {
    "path": "user.libc/src/string/stpncpy.c",
    "content": "#include <string.h>\n#include <stdint.h>\n#include <limits.h>\n\n#define ALIGN (sizeof(size_t)-1)\n#define ONES ((size_t)-1/UCHAR_MAX)\n#define HIGHS (ONES * (UCHAR_MAX/2+1))\n#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)\n\nchar *__stpncpy(char *restrict d, const char *restrict s, size_t n)\n{\n#ifdef __GNUC__\n\ttypedef size_t __attribute__((__may_alias__)) word;\n\tword *wd;\n\tconst word *ws;\n\tif (((uintptr_t)s & ALIGN) == ((uintptr_t)d & ALIGN)) {\n\t\tfor (; ((uintptr_t)s & ALIGN) && n && (*d=*s); n--, s++, d++);\n\t\tif (!n || !*s) goto tail;\n\t\twd=(void *)d; ws=(const void *)s;\n\t\tfor (; n>=sizeof(size_t) && !HASZERO(*ws);\n\t\t       n-=sizeof(size_t), ws++, wd++) *wd = *ws;\n\t\td=(void *)wd; s=(const void *)ws;\n\t}\n#endif\n\tfor (; n && (*d=*s); n--, s++, d++);\ntail:\n\tmemset(d, 0, n);\n\treturn d;\n}\n\nweak_alias(__stpncpy, stpncpy);\n\n"
  },
  {
    "path": "user.libc/src/string/strcasecmp.c",
    "content": "#include <strings.h>\n#include <ctype.h>\n\nint strcasecmp(const char *_l, const char *_r)\n{\n\tconst unsigned char *l=(void *)_l, *r=(void *)_r;\n\tfor (; *l && *r && (*l == *r || tolower(*l) == tolower(*r)); l++, r++);\n\treturn tolower(*l) - tolower(*r);\n}\n\nint __strcasecmp_l(const char *l, const char *r, locale_t loc)\n{\n\treturn strcasecmp(l, r);\n}\n\nweak_alias(__strcasecmp_l, strcasecmp_l);\n"
  },
  {
    "path": "user.libc/src/string/strcasestr.c",
    "content": "#define _GNU_SOURCE\n#include <string.h>\n\nchar *strcasestr(const char *h, const char *n)\n{\n\tsize_t l = strlen(n);\n\tfor (; *h; h++) if (!strncasecmp(h, n, l)) return (char *)h;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/string/strcat.c",
    "content": "#include <string.h>\n\nchar *strcat(char *restrict dest, const char *restrict src)\n{\n\tstrcpy(dest + strlen(dest), src);\n\treturn dest;\n}\n"
  },
  {
    "path": "user.libc/src/string/strchr.c",
    "content": "#include <string.h>\n\nchar *strchr(const char *s, int c)\n{\n\tchar *r = __strchrnul(s, c);\n\treturn *(unsigned char *)r == (unsigned char)c ? r : 0;\n}\n"
  },
  {
    "path": "user.libc/src/string/strchrnul.c",
    "content": "#include <string.h>\n#include <stdint.h>\n#include <limits.h>\n\n#define ALIGN (sizeof(size_t))\n#define ONES ((size_t)-1/UCHAR_MAX)\n#define HIGHS (ONES * (UCHAR_MAX/2+1))\n#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)\n\nchar *__strchrnul(const char *s, int c)\n{\n\tc = (unsigned char)c;\n\tif (!c) return (char *)s + strlen(s);\n\n#ifdef __GNUC__\n\ttypedef size_t __attribute__((__may_alias__)) word;\n\tconst word *w;\n\tfor (; (uintptr_t)s % ALIGN; s++)\n\t\tif (!*s || *(unsigned char *)s == c) return (char *)s;\n\tsize_t k = ONES * c;\n\tfor (w = (void *)s; !HASZERO(*w) && !HASZERO(*w^k); w++);\n\ts = (void *)w;\n#endif\n\tfor (; *s && *(unsigned char *)s != c; s++);\n\treturn (char *)s;\n}\n\nweak_alias(__strchrnul, strchrnul);\n"
  },
  {
    "path": "user.libc/src/string/strcmp.c",
    "content": "#include <string.h>\n\nint strcmp(const char *l, const char *r)\n{\n\tfor (; *l==*r && *l; l++, r++);\n\treturn *(unsigned char *)l - *(unsigned char *)r;\n}\n"
  },
  {
    "path": "user.libc/src/string/strcpy.c",
    "content": "#include <string.h>\n\nchar *strcpy(char *restrict dest, const char *restrict src)\n{\n\t__stpcpy(dest, src);\n\treturn dest;\n}\n"
  },
  {
    "path": "user.libc/src/string/strcspn.c",
    "content": "#include <string.h>\n\n#define BITOP(a,b,op) \\\n ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))\n\nsize_t strcspn(const char *s, const char *c)\n{\n\tconst char *a = s;\n\tsize_t byteset[32/sizeof(size_t)];\n\n\tif (!c[0] || !c[1]) return __strchrnul(s, *c)-a;\n\n\tmemset(byteset, 0, sizeof byteset);\n\tfor (; *c && BITOP(byteset, *(unsigned char *)c, |=); c++);\n\tfor (; *s && !BITOP(byteset, *(unsigned char *)s, &); s++);\n\treturn s-a;\n}\n"
  },
  {
    "path": "user.libc/src/string/strdup.c",
    "content": "#include <stdlib.h>\n#include <string.h>\n\nchar *strdup(const char *s)\n{\n\tsize_t l = strlen(s);\n\tchar *d = malloc(l+1);\n\tif (!d) return NULL;\n\treturn memcpy(d, s, l+1);\n}\n"
  },
  {
    "path": "user.libc/src/string/strerror_r.c",
    "content": "#include <string.h>\n#include <errno.h>\n\nint strerror_r(int err, char *buf, size_t buflen)\n{\n\tchar *msg = strerror(err);\n\tsize_t l = strlen(msg);\n\tif (l >= buflen) {\n\t\tif (buflen) {\n\t\t\tmemcpy(buf, msg, buflen-1);\n\t\t\tbuf[buflen-1] = 0;\n\t\t}\n\t\treturn ERANGE;\n\t}\n\tmemcpy(buf, msg, l+1);\n\treturn 0;\n}\n\nweak_alias(strerror_r, __xpg_strerror_r);\n"
  },
  {
    "path": "user.libc/src/string/strlcat.c",
    "content": "#define _BSD_SOURCE\n#include <string.h>\n\nsize_t strlcat(char *d, const char *s, size_t n)\n{\n\tsize_t l = strnlen(d, n);\n\tif (l == n) return l + strlen(s);\n\treturn l + strlcpy(d+l, s, n-l);\n}\n"
  },
  {
    "path": "user.libc/src/string/strlcpy.c",
    "content": "#define _BSD_SOURCE\n#include <string.h>\n#include <stdint.h>\n#include <limits.h>\n\n#define ALIGN (sizeof(size_t)-1)\n#define ONES ((size_t)-1/UCHAR_MAX)\n#define HIGHS (ONES * (UCHAR_MAX/2+1))\n#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)\n\nsize_t strlcpy(char *d, const char *s, size_t n)\n{\n\tchar *d0 = d;\n\tsize_t *wd;\n\n\tif (!n--) goto finish;\n#ifdef __GNUC__\n\ttypedef size_t __attribute__((__may_alias__)) word;\n\tconst word *ws;\n\tif (((uintptr_t)s & ALIGN) == ((uintptr_t)d & ALIGN)) {\n\t\tfor (; ((uintptr_t)s & ALIGN) && n && (*d=*s); n--, s++, d++);\n\t\tif (n && *s) {\n\t\t\twd=(void *)d; ws=(const void *)s;\n\t\t\tfor (; n>=sizeof(size_t) && !HASZERO(*ws);\n\t\t\t       n-=sizeof(size_t), ws++, wd++) *wd = *ws;\n\t\t\td=(void *)wd; s=(const void *)ws;\n\t\t}\n\t}\n#endif\n\tfor (; n && (*d=*s); n--, s++, d++);\n\t*d = 0;\nfinish:\n\treturn d-d0 + strlen(s);\n}\n"
  },
  {
    "path": "user.libc/src/string/strlen.c",
    "content": "#include <string.h>\n#include <stdint.h>\n#include <limits.h>\n\n#define ALIGN (sizeof(size_t))\n#define ONES ((size_t)-1/UCHAR_MAX)\n#define HIGHS (ONES * (UCHAR_MAX/2+1))\n#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)\n\nsize_t strlen(const char *s)\n{\n\tconst char *a = s;\n#ifdef __GNUC__\n\ttypedef size_t __attribute__((__may_alias__)) word;\n\tconst word *w;\n\tfor (; (uintptr_t)s % ALIGN; s++) if (!*s) return s-a;\n\tfor (w = (const void *)s; !HASZERO(*w); w++);\n\ts = (const void *)w;\n#endif\n\tfor (; *s; s++);\n\treturn s-a;\n}\n"
  },
  {
    "path": "user.libc/src/string/strncasecmp.c",
    "content": "#include <strings.h>\n#include <ctype.h>\n\nint strncasecmp(const char *_l, const char *_r, size_t n)\n{\n\tconst unsigned char *l=(void *)_l, *r=(void *)_r;\n\tif (!n--) return 0;\n\tfor (; *l && *r && n && (*l == *r || tolower(*l) == tolower(*r)); l++, r++, n--);\n\treturn tolower(*l) - tolower(*r);\n}\n\nint __strncasecmp_l(const char *l, const char *r, size_t n, locale_t loc)\n{\n\treturn strncasecmp(l, r, n);\n}\n\nweak_alias(__strncasecmp_l, strncasecmp_l);\n"
  },
  {
    "path": "user.libc/src/string/strncat.c",
    "content": "#include <string.h>\n\nchar *strncat(char *restrict d, const char *restrict s, size_t n)\n{\n\tchar *a = d;\n\td += strlen(d);\n\twhile (n && *s) n--, *d++ = *s++;\n\t*d++ = 0;\n\treturn a;\n}\n"
  },
  {
    "path": "user.libc/src/string/strncmp.c",
    "content": "#include <string.h>\n\nint strncmp(const char *_l, const char *_r, size_t n)\n{\n\tconst unsigned char *l=(void *)_l, *r=(void *)_r;\n\tif (!n--) return 0;\n\tfor (; *l && *r && n && *l == *r ; l++, r++, n--);\n\treturn *l - *r;\n}\n"
  },
  {
    "path": "user.libc/src/string/strncpy.c",
    "content": "#include <string.h>\n\nchar *strncpy(char *restrict d, const char *restrict s, size_t n)\n{\n\t__stpncpy(d, s, n);\n\treturn d;\n}\n"
  },
  {
    "path": "user.libc/src/string/strndup.c",
    "content": "#include <stdlib.h>\n#include <string.h>\n\nchar *strndup(const char *s, size_t n)\n{\n\tsize_t l = strnlen(s, n);\n\tchar *d = malloc(l+1);\n\tif (!d) return NULL;\n\tmemcpy(d, s, l);\n\td[l] = 0;\n\treturn d;\n}\n"
  },
  {
    "path": "user.libc/src/string/strnlen.c",
    "content": "#include <string.h>\n\nsize_t strnlen(const char *s, size_t n)\n{\n\tconst char *p = memchr(s, 0, n);\n\treturn p ? p-s : n;\n}\n"
  },
  {
    "path": "user.libc/src/string/strpbrk.c",
    "content": "#include <string.h>\n\nchar *strpbrk(const char *s, const char *b)\n{\n\ts += strcspn(s, b);\n\treturn *s ? (char *)s : 0;\n}\n"
  },
  {
    "path": "user.libc/src/string/strrchr.c",
    "content": "#include <string.h>\n\nchar *strrchr(const char *s, int c)\n{\n\treturn __memrchr(s, c, strlen(s) + 1);\n}\n"
  },
  {
    "path": "user.libc/src/string/strsep.c",
    "content": "#define _GNU_SOURCE\n#include <string.h>\n\nchar *strsep(char **str, const char *sep)\n{\n\tchar *s = *str, *end;\n\tif (!s) return NULL;\n\tend = s + strcspn(s, sep);\n\tif (*end) *end++ = 0;\n\telse end = 0;\n\t*str = end;\n\treturn s;\n}\n"
  },
  {
    "path": "user.libc/src/string/strsignal.c",
    "content": "#include <signal.h>\n#include <string.h>\n#include \"locale_impl.h\"\n\n#if (SIGHUP == 1) && (SIGINT == 2) && (SIGQUIT == 3) && (SIGILL == 4) \\\n && (SIGTRAP == 5) && (SIGABRT == 6) && (SIGBUS == 7) && (SIGFPE == 8) \\\n && (SIGKILL == 9) && (SIGUSR1 == 10) && (SIGSEGV == 11) && (SIGUSR2 == 12) \\\n && (SIGPIPE == 13) && (SIGALRM == 14) && (SIGTERM == 15) && (SIGSTKFLT == 16) \\\n && (SIGCHLD == 17) && (SIGCONT == 18) && (SIGSTOP == 19) && (SIGTSTP == 20) \\\n && (SIGTTIN == 21) && (SIGTTOU == 22) && (SIGURG == 23) && (SIGXCPU == 24) \\\n && (SIGXFSZ == 25) && (SIGVTALRM == 26) && (SIGPROF == 27) && (SIGWINCH == 28) \\\n && (SIGPOLL == 29) && (SIGPWR == 30) && (SIGSYS == 31)\n\n#define sigmap(x) x\n\n#else\n\nstatic const char map[] = {\n\t[SIGHUP]    = 1,\n\t[SIGINT]    = 2,\n\t[SIGQUIT]   = 3,\n\t[SIGILL]    = 4,\n\t[SIGTRAP]   = 5,\n\t[SIGABRT]   = 6,\n\t[SIGBUS]    = 7,\n\t[SIGFPE]    = 8,\n\t[SIGKILL]   = 9,\n\t[SIGUSR1]   = 10,\n\t[SIGSEGV]   = 11,\n\t[SIGUSR2]   = 12,\n\t[SIGPIPE]   = 13,\n\t[SIGALRM]   = 14,\n\t[SIGTERM]   = 15,\n#if defined(SIGSTKFLT)\n\t[SIGSTKFLT] = 16,\n#elif defined(SIGEMT)\n\t[SIGEMT]    = 16,\n#endif\n\t[SIGCHLD]   = 17,\n\t[SIGCONT]   = 18,\n\t[SIGSTOP]   = 19,\n\t[SIGTSTP]   = 20,\n\t[SIGTTIN]   = 21,\n\t[SIGTTOU]   = 22,\n\t[SIGURG]    = 23,\n\t[SIGXCPU]   = 24,\n\t[SIGXFSZ]   = 25,\n\t[SIGVTALRM] = 26,\n\t[SIGPROF]   = 27,\n\t[SIGWINCH]  = 28,\n\t[SIGPOLL]   = 29,\n\t[SIGPWR]    = 30,\n\t[SIGSYS]    = 31\n};\n\n#define sigmap(x) ((x) >= sizeof map ? (x) : map[(x)])\n\n#endif\n\nstatic const char strings[] =\n\t\"Unknown signal\\0\"\n\t\"Hangup\\0\"\n\t\"Interrupt\\0\"\n\t\"Quit\\0\"\n\t\"Illegal instruction\\0\"\n\t\"Trace/breakpoint trap\\0\"\n\t\"Aborted\\0\"\n\t\"Bus error\\0\"\n\t\"Arithmetic exception\\0\"\n\t\"Killed\\0\"\n\t\"User defined signal 1\\0\"\n\t\"Segmentation fault\\0\"\n\t\"User defined signal 2\\0\"\n\t\"Broken pipe\\0\"\n\t\"Alarm clock\\0\"\n\t\"Terminated\\0\"\n#if defined(SIGSTKFLT)\n\t\"Stack fault\\0\"\n#elif defined(SIGEMT)\n\t\"Emulator trap\\0\"\n#else\n\t\"Unknown signal\\0\"\n#endif\n\t\"Child process status\\0\"\n\t\"Continued\\0\"\n\t\"Stopped (signal)\\0\"\n\t\"Stopped\\0\"\n\t\"Stopped (tty input)\\0\"\n\t\"Stopped (tty output)\\0\"\n\t\"Urgent I/O condition\\0\"\n\t\"CPU time limit exceeded\\0\"\n\t\"File size limit exceeded\\0\"\n\t\"Virtual timer expired\\0\"\n\t\"Profiling timer expired\\0\"\n\t\"Window changed\\0\"\n\t\"I/O possible\\0\"\n\t\"Power failure\\0\"\n\t\"Bad system call\\0\"\n\t\"RT32\"\n\t\"\\0RT33\\0RT34\\0RT35\\0RT36\\0RT37\\0RT38\\0RT39\\0RT40\"\n\t\"\\0RT41\\0RT42\\0RT43\\0RT44\\0RT45\\0RT46\\0RT47\\0RT48\"\n\t\"\\0RT49\\0RT50\\0RT51\\0RT52\\0RT53\\0RT54\\0RT55\\0RT56\"\n\t\"\\0RT57\\0RT58\\0RT59\\0RT60\\0RT61\\0RT62\\0RT63\\0RT64\"\n#if _NSIG > 65\n\t\"\\0RT65\\0RT66\\0RT67\\0RT68\\0RT69\\0RT70\\0RT71\\0RT72\"\n\t\"\\0RT73\\0RT74\\0RT75\\0RT76\\0RT77\\0RT78\\0RT79\\0RT80\"\n\t\"\\0RT81\\0RT82\\0RT83\\0RT84\\0RT85\\0RT86\\0RT87\\0RT88\"\n\t\"\\0RT89\\0RT90\\0RT91\\0RT92\\0RT93\\0RT94\\0RT95\\0RT96\"\n\t\"\\0RT97\\0RT98\\0RT99\\0RT100\\0RT101\\0RT102\\0RT103\\0RT104\"\n\t\"\\0RT105\\0RT106\\0RT107\\0RT108\\0RT109\\0RT110\\0RT111\\0RT112\"\n\t\"\\0RT113\\0RT114\\0RT115\\0RT116\\0RT117\\0RT118\\0RT119\\0RT120\"\n\t\"\\0RT121\\0RT122\\0RT123\\0RT124\\0RT125\\0RT126\\0RT127\\0RT128\"\n#endif\n\t\"\";\n\nchar *strsignal(int signum)\n{\n\tconst char *s = strings;\n\n\tsignum = sigmap(signum);\n\tif (signum - 1U >= _NSIG-1) signum = 0;\n\n\tfor (; signum--; s++) for (; *s; s++);\n\n\treturn (char *)LCTRANS_CUR(s);\n}\n"
  },
  {
    "path": "user.libc/src/string/strspn.c",
    "content": "#include <string.h>\n\n#define BITOP(a,b,op) \\\n ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))\n\nsize_t strspn(const char *s, const char *c)\n{\n\tconst char *a = s;\n\tsize_t byteset[32/sizeof(size_t)] = { 0 };\n\n\tif (!c[0]) return 0;\n\tif (!c[1]) {\n\t\tfor (; *s == *c; s++);\n\t\treturn s-a;\n\t}\n\n\tfor (; *c && BITOP(byteset, *(unsigned char *)c, |=); c++);\n\tfor (; *s && BITOP(byteset, *(unsigned char *)s, &); s++);\n\treturn s-a;\n}\n"
  },
  {
    "path": "user.libc/src/string/strstr.c",
    "content": "#include <string.h>\n#include <stdint.h>\n\nstatic char *twobyte_strstr(const unsigned char *h, const unsigned char *n)\n{\n\tuint16_t nw = n[0]<<8 | n[1], hw = h[0]<<8 | h[1];\n\tfor (h++; *h && hw != nw; hw = hw<<8 | *++h);\n\treturn *h ? (char *)h-1 : 0;\n}\n\nstatic char *threebyte_strstr(const unsigned char *h, const unsigned char *n)\n{\n\tuint32_t nw = (uint32_t)n[0]<<24 | n[1]<<16 | n[2]<<8;\n\tuint32_t hw = (uint32_t)h[0]<<24 | h[1]<<16 | h[2]<<8;\n\tfor (h+=2; *h && hw != nw; hw = (hw|*++h)<<8);\n\treturn *h ? (char *)h-2 : 0;\n}\n\nstatic char *fourbyte_strstr(const unsigned char *h, const unsigned char *n)\n{\n\tuint32_t nw = (uint32_t)n[0]<<24 | n[1]<<16 | n[2]<<8 | n[3];\n\tuint32_t hw = (uint32_t)h[0]<<24 | h[1]<<16 | h[2]<<8 | h[3];\n\tfor (h+=3; *h && hw != nw; hw = hw<<8 | *++h);\n\treturn *h ? (char *)h-3 : 0;\n}\n\n#define MAX(a,b) ((a)>(b)?(a):(b))\n#define MIN(a,b) ((a)<(b)?(a):(b))\n\n#define BITOP(a,b,op) \\\n ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))\n\nstatic char *twoway_strstr(const unsigned char *h, const unsigned char *n)\n{\n\tconst unsigned char *z;\n\tsize_t l, ip, jp, k, p, ms, p0, mem, mem0;\n\tsize_t byteset[32 / sizeof(size_t)] = { 0 };\n\tsize_t shift[256];\n\n\t/* Computing length of needle and fill shift table */\n\tfor (l=0; n[l] && h[l]; l++)\n\t\tBITOP(byteset, n[l], |=), shift[n[l]] = l+1;\n\tif (n[l]) return 0; /* hit the end of h */\n\n\t/* Compute maximal suffix */\n\tip = -1; jp = 0; k = p = 1;\n\twhile (jp+k<l) {\n\t\tif (n[ip+k] == n[jp+k]) {\n\t\t\tif (k == p) {\n\t\t\t\tjp += p;\n\t\t\t\tk = 1;\n\t\t\t} else k++;\n\t\t} else if (n[ip+k] > n[jp+k]) {\n\t\t\tjp += k;\n\t\t\tk = 1;\n\t\t\tp = jp - ip;\n\t\t} else {\n\t\t\tip = jp++;\n\t\t\tk = p = 1;\n\t\t}\n\t}\n\tms = ip;\n\tp0 = p;\n\n\t/* And with the opposite comparison */\n\tip = -1; jp = 0; k = p = 1;\n\twhile (jp+k<l) {\n\t\tif (n[ip+k] == n[jp+k]) {\n\t\t\tif (k == p) {\n\t\t\t\tjp += p;\n\t\t\t\tk = 1;\n\t\t\t} else k++;\n\t\t} else if (n[ip+k] < n[jp+k]) {\n\t\t\tjp += k;\n\t\t\tk = 1;\n\t\t\tp = jp - ip;\n\t\t} else {\n\t\t\tip = jp++;\n\t\t\tk = p = 1;\n\t\t}\n\t}\n\tif (ip+1 > ms+1) ms = ip;\n\telse p = p0;\n\n\t/* Periodic needle? */\n\tif (memcmp(n, n+p, ms+1)) {\n\t\tmem0 = 0;\n\t\tp = MAX(ms, l-ms-1) + 1;\n\t} else mem0 = l-p;\n\tmem = 0;\n\n\t/* Initialize incremental end-of-haystack pointer */\n\tz = h;\n\n\t/* Search loop */\n\tfor (;;) {\n\t\t/* Update incremental end-of-haystack pointer */\n\t\tif (z-h < l) {\n\t\t\t/* Fast estimate for MAX(l,63) */\n\t\t\tsize_t grow = l | 63;\n\t\t\tconst unsigned char *z2 = memchr(z, 0, grow);\n\t\t\tif (z2) {\n\t\t\t\tz = z2;\n\t\t\t\tif (z-h < l) return 0;\n\t\t\t} else z += grow;\n\t\t}\n\n\t\t/* Check last byte first; advance by shift on mismatch */\n\t\tif (BITOP(byteset, h[l-1], &)) {\n\t\t\tk = l-shift[h[l-1]];\n\t\t\tif (k) {\n\t\t\t\tif (k < mem) k = mem;\n\t\t\t\th += k;\n\t\t\t\tmem = 0;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t} else {\n\t\t\th += l;\n\t\t\tmem = 0;\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* Compare right half */\n\t\tfor (k=MAX(ms+1,mem); n[k] && n[k] == h[k]; k++);\n\t\tif (n[k]) {\n\t\t\th += k-ms;\n\t\t\tmem = 0;\n\t\t\tcontinue;\n\t\t}\n\t\t/* Compare left half */\n\t\tfor (k=ms+1; k>mem && n[k-1] == h[k-1]; k--);\n\t\tif (k <= mem) return (char *)h;\n\t\th += p;\n\t\tmem = mem0;\n\t}\n}\n\nchar *strstr(const char *h, const char *n)\n{\n\t/* Return immediately on empty needle */\n\tif (!n[0]) return (char *)h;\n\n\t/* Use faster algorithms for short needles */\n\th = strchr(h, *n);\n\tif (!h || !n[1]) return (char *)h;\n\tif (!h[1]) return 0;\n\tif (!n[2]) return twobyte_strstr((void *)h, (void *)n);\n\tif (!h[2]) return 0;\n\tif (!n[3]) return threebyte_strstr((void *)h, (void *)n);\n\tif (!h[3]) return 0;\n\tif (!n[4]) return fourbyte_strstr((void *)h, (void *)n);\n\n\treturn twoway_strstr((void *)h, (void *)n);\n}\n"
  },
  {
    "path": "user.libc/src/string/strtok.c",
    "content": "#include <string.h>\n\nchar *strtok(char *restrict s, const char *restrict sep)\n{\n\tstatic char *p;\n\tif (!s && !(s = p)) return NULL;\n\ts += strspn(s, sep);\n\tif (!*s) return p = 0;\n\tp = s + strcspn(s, sep);\n\tif (*p) *p++ = 0;\n\telse p = 0;\n\treturn s;\n}\n"
  },
  {
    "path": "user.libc/src/string/strtok_r.c",
    "content": "#include <string.h>\n\nchar *strtok_r(char *restrict s, const char *restrict sep, char **restrict p)\n{\n\tif (!s && !(s = *p)) return NULL;\n\ts += strspn(s, sep);\n\tif (!*s) return *p = 0;\n\t*p = s + strcspn(s, sep);\n\tif (**p) *(*p)++ = 0;\n\telse *p = 0;\n\treturn s;\n}\n"
  },
  {
    "path": "user.libc/src/string/strverscmp.c",
    "content": "#define _GNU_SOURCE\n#include <ctype.h>\n#include <string.h>\n\nint strverscmp(const char *l0, const char *r0)\n{\n\tconst unsigned char *l = (const void *)l0;\n\tconst unsigned char *r = (const void *)r0;\n\tsize_t i, dp, j;\n\tint z = 1;\n\n\t/* Find maximal matching prefix and track its maximal digit\n\t * suffix and whether those digits are all zeros. */\n\tfor (dp=i=0; l[i]==r[i]; i++) {\n\t\tint c = l[i];\n\t\tif (!c) return 0;\n\t\tif (!isdigit(c)) dp=i+1, z=1;\n\t\telse if (c!='0') z=0;\n\t}\n\n\tif (l[dp]!='0' && r[dp]!='0') {\n\t\t/* If we're not looking at a digit sequence that began\n\t\t * with a zero, longest digit string is greater. */\n\t\tfor (j=i; isdigit(l[j]); j++)\n\t\t\tif (!isdigit(r[j])) return 1;\n\t\tif (isdigit(r[j])) return -1;\n\t} else if (z && dp<i && (isdigit(l[i]) || isdigit(r[i]))) {\n\t\t/* Otherwise, if common prefix of digit sequence is\n\t\t * all zeros, digits order less than non-digits. */\n\t\treturn (unsigned char)(l[i]-'0') - (unsigned char)(r[i]-'0');\n\t}\n\n\treturn l[i] - r[i];\n}\n"
  },
  {
    "path": "user.libc/src/string/swab.c",
    "content": "#include <unistd.h>\n\nvoid swab(const void *restrict _src, void *restrict _dest, ssize_t n)\n{\n\tconst char *src = _src;\n\tchar *dest = _dest;\n\tfor (; n>1; n-=2) {\n\t\tdest[0] = src[1];\n\t\tdest[1] = src[0];\n\t\tdest += 2;\n\t\tsrc += 2;\n\t}\n}\n"
  },
  {
    "path": "user.libc/src/string/wcpcpy.c",
    "content": "#include <wchar.h>\n\nwchar_t *wcpcpy(wchar_t *restrict d, const wchar_t *restrict s)\n{\n\treturn wcscpy(d, s) + wcslen(s);\n}\n"
  },
  {
    "path": "user.libc/src/string/wcpncpy.c",
    "content": "#include <wchar.h>\n\nwchar_t *wcpncpy(wchar_t *restrict d, const wchar_t *restrict s, size_t n)\n{\n\treturn wcsncpy(d, s, n) + wcsnlen(s, n);\n}\n"
  },
  {
    "path": "user.libc/src/string/wcscasecmp.c",
    "content": "#include <wchar.h>\n#include <wctype.h>\n\nint wcscasecmp(const wchar_t *l, const wchar_t *r)\n{\n\treturn wcsncasecmp(l, r, -1);\n}\n"
  },
  {
    "path": "user.libc/src/string/wcscasecmp_l.c",
    "content": "#include <wchar.h>\n\nint wcscasecmp_l(const wchar_t *l, const wchar_t *r, locale_t locale)\n{\n\treturn wcscasecmp(l, r);\n}\n"
  },
  {
    "path": "user.libc/src/string/wcscat.c",
    "content": "#include <wchar.h>\n\nwchar_t *wcscat(wchar_t *restrict dest, const wchar_t *restrict src)\n{\n\twcscpy(dest + wcslen(dest), src);\n\treturn dest;\n}\n"
  },
  {
    "path": "user.libc/src/string/wcschr.c",
    "content": "#include <wchar.h>\n\nwchar_t *wcschr(const wchar_t *s, wchar_t c)\n{\n\tif (!c) return (wchar_t *)s + wcslen(s);\n\tfor (; *s && *s != c; s++);\n\treturn *s ? (wchar_t *)s : 0;\n}\n"
  },
  {
    "path": "user.libc/src/string/wcscmp.c",
    "content": "#include <wchar.h>\n\nint wcscmp(const wchar_t *l, const wchar_t *r)\n{\n\tfor (; *l==*r && *l && *r; l++, r++);\n\treturn *l - *r;\n}\n"
  },
  {
    "path": "user.libc/src/string/wcscpy.c",
    "content": "#include <wchar.h>\n\nwchar_t *wcscpy(wchar_t *restrict d, const wchar_t *restrict s)\n{\n\twchar_t *a = d;\n\twhile ((*d++ = *s++));\n\treturn a;\n}\n"
  },
  {
    "path": "user.libc/src/string/wcscspn.c",
    "content": "#include <wchar.h>\n\nsize_t wcscspn(const wchar_t *s, const wchar_t *c)\n{\n\tconst wchar_t *a;\n\tif (!c[0]) return wcslen(s);\n\tif (!c[1]) return (s=wcschr(a=s, *c)) ? s-a : wcslen(a);\n\tfor (a=s; *s && !wcschr(c, *s); s++);\n\treturn s-a;\n}\n"
  },
  {
    "path": "user.libc/src/string/wcsdup.c",
    "content": "#include <stdlib.h>\n#include <wchar.h>\n\nwchar_t *wcsdup(const wchar_t *s)\n{\n\tsize_t l = wcslen(s);\n\twchar_t *d = malloc((l+1)*sizeof(wchar_t));\n\tif (!d) return NULL;\n\treturn wmemcpy(d, s, l+1);\n}\n"
  },
  {
    "path": "user.libc/src/string/wcslen.c",
    "content": "#include <wchar.h>\n\nsize_t wcslen(const wchar_t *s)\n{\n\tconst wchar_t *a;\n\tfor (a=s; *s; s++);\n\treturn s-a;\n}\n"
  },
  {
    "path": "user.libc/src/string/wcsncasecmp.c",
    "content": "#include <wchar.h>\n#include <wctype.h>\n\nint wcsncasecmp(const wchar_t *l, const wchar_t *r, size_t n)\n{\n\tif (!n--) return 0;\n\tfor (; *l && *r && n && (*l == *r || towlower(*l) == towlower(*r)); l++, r++, n--);\n\treturn towlower(*l) - towlower(*r);\n}\n"
  },
  {
    "path": "user.libc/src/string/wcsncasecmp_l.c",
    "content": "#include <wchar.h>\n\nint wcsncasecmp_l(const wchar_t *l, const wchar_t *r, size_t n, locale_t locale)\n{\n\treturn wcsncasecmp(l, r, n);\n}\n"
  },
  {
    "path": "user.libc/src/string/wcsncat.c",
    "content": "#include <wchar.h>\n\nwchar_t *wcsncat(wchar_t *restrict d, const wchar_t *restrict s, size_t n)\n{\n\twchar_t *a = d;\n\td += wcslen(d);\n\twhile (n && *s) n--, *d++ = *s++;\n\t*d++ = 0;\n\treturn a;\n}\n"
  },
  {
    "path": "user.libc/src/string/wcsncmp.c",
    "content": "#include <wchar.h>\n\nint wcsncmp(const wchar_t *l, const wchar_t *r, size_t n)\n{\n\tfor (; n && *l==*r && *l && *r; n--, l++, r++);\n\treturn n ? *l - *r : 0;\n}\n"
  },
  {
    "path": "user.libc/src/string/wcsncpy.c",
    "content": "#include <wchar.h>\n\nwchar_t *wcsncpy(wchar_t *restrict d, const wchar_t *restrict s, size_t n)\n{\n\twchar_t *a = d;\n\twhile (n && *s) n--, *d++ = *s++;\n\twmemset(d, 0, n);\n\treturn a;\n}\n"
  },
  {
    "path": "user.libc/src/string/wcsnlen.c",
    "content": "#include <wchar.h>\n\nsize_t wcsnlen(const wchar_t *s, size_t n)\n{\n\tconst wchar_t *z = wmemchr(s, 0, n);\n\tif (z) n = z-s;\n\treturn n;\n}\n"
  },
  {
    "path": "user.libc/src/string/wcspbrk.c",
    "content": "#include <wchar.h>\n\nwchar_t *wcspbrk(const wchar_t *s, const wchar_t *b)\n{\n\ts += wcscspn(s, b);\n\treturn *s ? (wchar_t *)s : NULL;\n}\n"
  },
  {
    "path": "user.libc/src/string/wcsrchr.c",
    "content": "#include <wchar.h>\n\nwchar_t *wcsrchr(const wchar_t *s, wchar_t c)\n{\n\tconst wchar_t *p;\n\tfor (p=s+wcslen(s); p>=s && *p!=c; p--);\n\treturn p>=s ? (wchar_t *)p : 0;\n}\n"
  },
  {
    "path": "user.libc/src/string/wcsspn.c",
    "content": "#include <wchar.h>\n\nsize_t wcsspn(const wchar_t *s, const wchar_t *c)\n{\n\tconst wchar_t *a;\n\tfor (a=s; *s && wcschr(c, *s); s++);\n\treturn s-a;\n}\n"
  },
  {
    "path": "user.libc/src/string/wcsstr.c",
    "content": "#include <wchar.h>\n\n#define MAX(a,b) ((a)>(b)?(a):(b))\n#define MIN(a,b) ((a)<(b)?(a):(b))\n\nstatic wchar_t *twoway_wcsstr(const wchar_t *h, const wchar_t *n)\n{\n\tconst wchar_t *z;\n\tsize_t l, ip, jp, k, p, ms, p0, mem, mem0;\n\n\t/* Computing length of needle */\n\tfor (l=0; n[l] && h[l]; l++);\n\tif (n[l]) return 0; /* hit the end of h */\n\n\t/* Compute maximal suffix */\n\tip = -1; jp = 0; k = p = 1;\n\twhile (jp+k<l) {\n\t\tif (n[ip+k] == n[jp+k]) {\n\t\t\tif (k == p) {\n\t\t\t\tjp += p;\n\t\t\t\tk = 1;\n\t\t\t} else k++;\n\t\t} else if (n[ip+k] > n[jp+k]) {\n\t\t\tjp += k;\n\t\t\tk = 1;\n\t\t\tp = jp - ip;\n\t\t} else {\n\t\t\tip = jp++;\n\t\t\tk = p = 1;\n\t\t}\n\t}\n\tms = ip;\n\tp0 = p;\n\n\t/* And with the opposite comparison */\n\tip = -1; jp = 0; k = p = 1;\n\twhile (jp+k<l) {\n\t\tif (n[ip+k] == n[jp+k]) {\n\t\t\tif (k == p) {\n\t\t\t\tjp += p;\n\t\t\t\tk = 1;\n\t\t\t} else k++;\n\t\t} else if (n[ip+k] < n[jp+k]) {\n\t\t\tjp += k;\n\t\t\tk = 1;\n\t\t\tp = jp - ip;\n\t\t} else {\n\t\t\tip = jp++;\n\t\t\tk = p = 1;\n\t\t}\n\t}\n\tif (ip+1 > ms+1) ms = ip;\n\telse p = p0;\n\n\t/* Periodic needle? */\n\tif (wmemcmp(n, n+p, ms+1)) {\n\t\tmem0 = 0;\n\t\tp = MAX(ms, l-ms-1) + 1;\n\t} else mem0 = l-p;\n\tmem = 0;\n\n\t/* Initialize incremental end-of-haystack pointer */\n\tz = h;\n\n\t/* Search loop */\n\tfor (;;) {\n\t\t/* Update incremental end-of-haystack pointer */\n\t\tif (z-h < l) {\n\t\t\t/* Fast estimate for MIN(l,63) */\n\t\t\tsize_t grow = l | 63;\n\t\t\tconst wchar_t *z2 = wmemchr(z, 0, grow);\n\t\t\tif (z2) {\n\t\t\t\tz = z2;\n\t\t\t\tif (z-h < l) return 0;\n\t\t\t} else z += grow;\n\t\t}\n\n\t\t/* Compare right half */\n\t\tfor (k=MAX(ms+1,mem); n[k] && n[k] == h[k]; k++);\n\t\tif (n[k]) {\n\t\t\th += k-ms;\n\t\t\tmem = 0;\n\t\t\tcontinue;\n\t\t}\n\t\t/* Compare left half */\n\t\tfor (k=ms+1; k>mem && n[k-1] == h[k-1]; k--);\n\t\tif (k <= mem) return (wchar_t *)h;\n\t\th += p;\n\t\tmem = mem0;\n\t}\n}\n\nwchar_t *wcsstr(const wchar_t *restrict h, const wchar_t *restrict n)\n{\n\t/* Return immediately on empty needle or haystack */\n\tif (!n[0]) return (wchar_t *)h;\n\tif (!h[0]) return 0;\n\n\t/* Use faster algorithms for short needles */\n\th = wcschr(h, *n);\n\tif (!h || !n[1]) return (wchar_t *)h;\n\tif (!h[1]) return 0;\n\n\treturn twoway_wcsstr(h, n);\n}\n"
  },
  {
    "path": "user.libc/src/string/wcstok.c",
    "content": "#include <wchar.h>\n\nwchar_t *wcstok(wchar_t *restrict s, const wchar_t *restrict sep, wchar_t **restrict p)\n{\n\tif (!s && !(s = *p)) return NULL;\n\ts += wcsspn(s, sep);\n\tif (!*s) return *p = 0;\n\t*p = s + wcscspn(s, sep);\n\tif (**p) *(*p)++ = 0;\n\telse *p = 0;\n\treturn s;\n}\n"
  },
  {
    "path": "user.libc/src/string/wcswcs.c",
    "content": "#include <wchar.h>\n\nwchar_t *wcswcs(const wchar_t *haystack, const wchar_t *needle)\n{\n\treturn wcsstr(haystack, needle);\n}\n"
  },
  {
    "path": "user.libc/src/string/wmemchr.c",
    "content": "#include <wchar.h>\n\nwchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n)\n{\n\tfor (; n && *s != c; n--, s++);\n\treturn n ? (wchar_t *)s : 0;\n}\n"
  },
  {
    "path": "user.libc/src/string/wmemcmp.c",
    "content": "#include <wchar.h>\n\nint wmemcmp(const wchar_t *l, const wchar_t *r, size_t n)\n{\n\tfor (; n && *l==*r; n--, l++, r++);\n\treturn n ? *l-*r : 0;\n}\n"
  },
  {
    "path": "user.libc/src/string/wmemcpy.c",
    "content": "#include <wchar.h>\n\nwchar_t *wmemcpy(wchar_t *restrict d, const wchar_t *restrict s, size_t n)\n{\n\twchar_t *a = d;\n\twhile (n--) *d++ = *s++;\n\treturn a;\n}\n"
  },
  {
    "path": "user.libc/src/string/wmemmove.c",
    "content": "#include <wchar.h>\n#include <stdint.h>\n\nwchar_t *wmemmove(wchar_t *d, const wchar_t *s, size_t n)\n{\n\twchar_t *d0 = d;\n\tif (d == s) return d;\n\tif ((uintptr_t)d-(uintptr_t)s < n * sizeof *d)\n\t\twhile (n--) d[n] = s[n];\n\telse\n\t\twhile (n--) *d++ = *s++;\n\treturn d0;\n}\n"
  },
  {
    "path": "user.libc/src/string/wmemset.c",
    "content": "#include <wchar.h>\n\nwchar_t *wmemset(wchar_t *d, wchar_t c, size_t n)\n{\n\twchar_t *ret = d;\n\twhile (n--) *d++ = c;\n\treturn ret;\n}\n"
  },
  {
    "path": "user.libc/src/temp/__randname.c",
    "content": "#include <time.h>\n#include <stdint.h>\n\n/* This assumes that a check for the\n   template size has already been made */\nchar *__randname(char *template)\n{\n\tint i;\n\tstruct timespec ts;\n\tunsigned long r;\n\n\t__clock_gettime(CLOCK_REALTIME, &ts);\n\tr = ts.tv_nsec*65537 ^ (uintptr_t)&ts / 16 + (uintptr_t)template;\n\tfor (i=0; i<6; i++, r>>=5)\n\t\ttemplate[i] = 'A'+(r&15)+(r&16)*2;\n\n\treturn template;\n}\n"
  },
  {
    "path": "user.libc/src/temp/mkdtemp.c",
    "content": "#include <string.h>\n#include <stdlib.h>\n#include <errno.h>\n#include <sys/stat.h>\n\nchar *mkdtemp(char *template)\n{\n\tsize_t l = strlen(template);\n\tint retries = 100;\n\n\tif (l<6 || memcmp(template+l-6, \"XXXXXX\", 6)) {\n\t\terrno = EINVAL;\n\t\treturn 0;\n\t}\n\n\tdo {\n\t\t__randname(template+l-6);\n\t\tif (!mkdir(template, 0700)) return template;\n\t} while (--retries && errno == EEXIST);\n\n\tmemcpy(template+l-6, \"XXXXXX\", 6);\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/temp/mkostemp.c",
    "content": "#define _BSD_SOURCE\n#include <stdlib.h>\n\nint mkostemp(char *template, int flags)\n{\n\treturn __mkostemps(template, 0, flags);\n}\n\nweak_alias(mkostemp, mkostemp64);\n"
  },
  {
    "path": "user.libc/src/temp/mkostemps.c",
    "content": "#define _BSD_SOURCE\n#include <stdlib.h>\n#include <string.h>\n#include <fcntl.h>\n#include <unistd.h>\n#include <errno.h>\n\nint __mkostemps(char *template, int len, int flags)\n{\n\tsize_t l = strlen(template);\n\tif (l<6 || len>l-6 || memcmp(template+l-len-6, \"XXXXXX\", 6)) {\n\t\terrno = EINVAL;\n\t\treturn -1;\n\t}\n\n\tflags -= flags & O_ACCMODE;\n\tint fd, retries = 100;\n\tdo {\n\t\t__randname(template+l-len-6);\n\t\tif ((fd = open(template, flags | O_RDWR | O_CREAT | O_EXCL, 0600))>=0)\n\t\t\treturn fd;\n\t} while (--retries && errno == EEXIST);\n\n\tmemcpy(template+l-len-6, \"XXXXXX\", 6);\n\treturn -1;\n}\n\nweak_alias(__mkostemps, mkostemps);\nweak_alias(__mkostemps, mkostemps64);\n"
  },
  {
    "path": "user.libc/src/temp/mkstemp.c",
    "content": "#include <stdlib.h>\n\nint mkstemp(char *template)\n{\n\treturn __mkostemps(template, 0, 0);\n}\n\nweak_alias(mkstemp, mkstemp64);\n"
  },
  {
    "path": "user.libc/src/temp/mkstemps.c",
    "content": "#define _BSD_SOURCE\n#include <stdlib.h>\n\nint mkstemps(char *template, int len)\n{\n\treturn __mkostemps(template, len, 0);\n}\n\nweak_alias(mkstemps, mkstemps64);\n"
  },
  {
    "path": "user.libc/src/temp/mktemp.c",
    "content": "#define _GNU_SOURCE\n#include <string.h>\n#include <stdlib.h>\n#include <errno.h>\n#include <sys/stat.h>\n\nchar *mktemp(char *template)\n{\n\tsize_t l = strlen(template);\n\tint retries = 100;\n\tstruct stat st;\n\n\tif (l < 6 || memcmp(template+l-6, \"XXXXXX\", 6)) {\n\t\terrno = EINVAL;\n\t\t*template = 0;\n\t\treturn template;\n\t}\n\n\tdo {\n\t\t__randname(template+l-6);\n\t\tif (stat(template, &st)) {\n\t\t\tif (errno != ENOENT) *template = 0;\n\t\t\treturn template;\n\t\t}\n\t} while (--retries);\n\n\t*template = 0;\n\terrno = EEXIST;\n\treturn template;\n}\n"
  },
  {
    "path": "user.libc/src/termios/cfgetospeed.c",
    "content": "#define _BSD_SOURCE\n#include <termios.h>\n#include <sys/ioctl.h>\n\nspeed_t cfgetospeed(const struct termios *tio)\n{\n\treturn tio->c_cflag & CBAUD;\n}\n\nspeed_t cfgetispeed(const struct termios *tio)\n{\n\treturn cfgetospeed(tio);\n}\n"
  },
  {
    "path": "user.libc/src/termios/cfmakeraw.c",
    "content": "#define _GNU_SOURCE\n#include <termios.h>\n\nvoid cfmakeraw(struct termios *t)\n{\n\tt->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);\n\tt->c_oflag &= ~OPOST;\n\tt->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);\n\tt->c_cflag &= ~(CSIZE|PARENB);\n\tt->c_cflag |= CS8;\n\tt->c_cc[VMIN] = 1;\n\tt->c_cc[VTIME] = 0;\n}\n"
  },
  {
    "path": "user.libc/src/termios/cfsetospeed.c",
    "content": "#define _BSD_SOURCE\n#include <termios.h>\n#include <sys/ioctl.h>\n#include <errno.h>\n\nint cfsetospeed(struct termios *tio, speed_t speed)\n{\n\tif (speed & ~CBAUD) {\n\t\terrno = EINVAL;\n\t\treturn -1;\n\t}\n\ttio->c_cflag &= ~CBAUD;\n\ttio->c_cflag |= speed;\n\treturn 0;\n}\n\nint cfsetispeed(struct termios *tio, speed_t speed)\n{\n\treturn speed ? cfsetospeed(tio, speed) : 0;\n}\n\nweak_alias(cfsetospeed, cfsetspeed);\n"
  },
  {
    "path": "user.libc/src/termios/tcdrain.c",
    "content": "#include <termios.h>\n#include <sys/ioctl.h>\n#include \"syscall.h\"\n\nint tcdrain(int fd)\n{\n#if 0\n\treturn syscall_cp(SYS_ioctl, fd, TCSBRK, 1);\n#endif\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/termios/tcflow.c",
    "content": "#include <termios.h>\n#include <sys/ioctl.h>\n\nint tcflow(int fd, int action)\n{\n\treturn ioctl(fd, TCXONC, action);\n}\n"
  },
  {
    "path": "user.libc/src/termios/tcflush.c",
    "content": "#include <termios.h>\n#include <sys/ioctl.h>\n\nint tcflush(int fd, int queue)\n{\n\treturn ioctl(fd, TCFLSH, queue);\n}\n"
  },
  {
    "path": "user.libc/src/termios/tcgetattr.c",
    "content": "#include <termios.h>\n#include <sys/ioctl.h>\n\nint tcgetattr(int fd, struct termios *tio)\n{\n\tif (ioctl(fd, TCGETS, tio))\n\t\treturn -1;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/termios/tcgetsid.c",
    "content": "#include <termios.h>\n#include <sys/ioctl.h>\n\npid_t tcgetsid(int fd)\n{\n\tint sid;\n\tif (ioctl(fd, TIOCGSID, &sid) < 0)\n\t\treturn -1;\n\treturn sid;\n}\n"
  },
  {
    "path": "user.libc/src/termios/tcgetwinsize.c",
    "content": "#include <termios.h>\n#include <sys/ioctl.h>\n#include \"syscall.h\"\n\nint tcgetwinsize(int fd, struct winsize *wsz)\n{\n#if 0\n\treturn syscall(SYS_ioctl, fd, TIOCGWINSZ, wsz);\n#endif\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/termios/tcsendbreak.c",
    "content": "#include <termios.h>\n#include <sys/ioctl.h>\n\nint tcsendbreak(int fd, int dur)\n{\n\t/* nonzero duration is implementation-defined, so ignore it */\n\treturn ioctl(fd, TCSBRK, 0);\n}\n"
  },
  {
    "path": "user.libc/src/termios/tcsetattr.c",
    "content": "#include <termios.h>\n#include <sys/ioctl.h>\n#include <errno.h>\n\nint tcsetattr(int fd, int act, const struct termios *tio)\n{\n\tif (act < 0 || act > 2) {\n\t\terrno = EINVAL;\n\t\treturn -1;\n\t}\n\treturn ioctl(fd, TCSETS+act, tio);\n}\n"
  },
  {
    "path": "user.libc/src/termios/tcsetwinsize.c",
    "content": "#include <termios.h>\n#include <sys/ioctl.h>\n#include \"syscall.h\"\n\nint tcsetwinsize(int fd, const struct winsize *wsz)\n{\n#if 0\n\treturn syscall(SYS_ioctl, fd, TIOCSWINSZ, wsz);\n#endif\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/__lock.c",
    "content": "#include \"pthread_impl.h\"\n\n/* This lock primitive combines a flag (in the sign bit) and a\n * congestion count (= threads inside the critical section, CS) in a\n * single int that is accessed through atomic operations. The states\n * of the int for value x are:\n *\n * x == 0: unlocked and no thread inside the critical section\n *\n * x < 0: locked with a congestion of x-INT_MIN, including the thread\n * that holds the lock\n *\n * x > 0: unlocked with a congestion of x\n *\n * or in an equivalent formulation x is the congestion count or'ed\n * with INT_MIN as a lock flag.\n */\n\nvoid __lock(volatile int *l)\n{\n\tint need_locks = libc.need_locks;\n\tif (!need_locks) return;\n\t/* fast path: INT_MIN for the lock, +1 for the congestion */\n\tint current = a_cas(l, 0, INT_MIN + 1);\n\tif (need_locks < 0) libc.need_locks = 0;\n\tif (!current) return;\n\t/* A first spin loop, for medium congestion. */\n\tfor (unsigned i = 0; i < 10; ++i) {\n\t\tif (current < 0) current -= INT_MIN + 1;\n\t\t// assertion: current >= 0\n\t\tint val = a_cas(l, current, INT_MIN + (current + 1));\n\t\tif (val == current) return;\n\t\tcurrent = val;\n\t}\n\t// Spinning failed, so mark ourselves as being inside the CS.\n\tcurrent = a_fetch_add(l, 1) + 1;\n\t/* The main lock acquisition loop for heavy congestion. The only\n\t * change to the value performed inside that loop is a successful\n\t * lock via the CAS that acquires the lock. */\n\tfor (;;) {\n\t\t/* We can only go into wait, if we know that somebody holds the\n\t\t * lock and will eventually wake us up, again. */\n\t\tif (current < 0) {\n\t\t\t__futexwait(l, current, 1);\n\t\t\tcurrent -= INT_MIN + 1;\n\t\t}\n\t\t/* assertion: current > 0, the count includes us already. */\n\t\tint val = a_cas(l, current, INT_MIN + current);\n\t\tif (val == current) return;\n\t\tcurrent = val;\n\t}\n}\n\nvoid __unlock(volatile int *l)\n{\n\t/* Check l[0] to see if we are multi-threaded. */\n\tif (l[0] < 0) {\n\t\tif (a_fetch_add(l, -(INT_MIN + 1)) != (INT_MIN + 1)) {\n\t\t\t__wake(l, 1, 1);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "user.libc/src/thread/__set_thread_area.c",
    "content": "#include \"pthread_impl.h\"\n\nint __set_thread_area(void *p)\n{\n#ifdef SYS_set_thread_area\n\treturn __syscall(SYS_set_thread_area, p);\n#else\n\treturn -ENOSYS;\n#endif\n}\n"
  },
  {
    "path": "user.libc/src/thread/__syscall_cp.c",
    "content": "#include \"pthread_impl.h\"\n#include \"syscall.h\"\n\nhidden long __syscall_cp_c();\n\nstatic long sccp(syscall_arg_t nr,\n                 syscall_arg_t u, syscall_arg_t v, syscall_arg_t w,\n                 syscall_arg_t x, syscall_arg_t y, syscall_arg_t z)\n{\n\treturn __syscall(nr, u, v, w, x, y, z);\n}\n\nweak_alias(sccp, __syscall_cp_c);\n\nlong (__syscall_cp)(syscall_arg_t nr,\n                    syscall_arg_t u, syscall_arg_t v, syscall_arg_t w,\n                    syscall_arg_t x, syscall_arg_t y, syscall_arg_t z)\n{\n\treturn __syscall_cp_c(nr, u, v, w, x, y, z);\n}\n"
  },
  {
    "path": "user.libc/src/thread/__timedwait.c",
    "content": "#include <pthread.h>\n#include <time.h>\n#include <errno.h>\n#include \"futex.h\"\n#include \"syscall.h\"\n#include \"pthread_impl.h\"\n\n#define IS32BIT(x) !((x)+0x80000000ULL>>32)\n#define CLAMP(x) (int)(IS32BIT(x) ? (x) : 0x7fffffffU+((0ULL+(x))>>63))\n\nstatic int __futex4_cp(volatile void *addr, int op, int val, const struct timespec *to)\n{\n\tint r;\n#ifdef SYS_futex_time64\n\ttime_t s = to ? to->tv_sec : 0;\n\tlong ns = to ? to->tv_nsec : 0;\n\tr = -ENOSYS;\n\tif (SYS_futex == SYS_futex_time64 || !IS32BIT(s))\n\t\tr = __syscall_cp(SYS_futex_time64, addr, op, val,\n\t\t\tto ? ((long long[]){s, ns}) : 0);\n\tif (SYS_futex == SYS_futex_time64 || r!=-ENOSYS) return r;\n\tto = to ? (void *)(long[]){CLAMP(s), ns} : 0;\n#endif\n\tr = __syscall_cp(SYS_futex, addr, op, val, to);\n\tif (r != -ENOSYS) return r;\n\treturn __syscall_cp(SYS_futex, addr, op & ~FUTEX_PRIVATE, val, to);\n}\n\nstatic volatile int dummy = 0;\nweak_alias(dummy, __eintr_valid_flag);\n\nint __timedwait_cp(volatile int *addr, int val,\n\tclockid_t clk, const struct timespec *at, int priv)\n{\n\tint r;\n\tstruct timespec to, *top=0;\n\n\tif (priv) priv = FUTEX_PRIVATE;\n\n\tif (at) {\n\t\tif (at->tv_nsec >= 1000000000UL) return EINVAL;\n\t\tif (__clock_gettime(clk, &to)) return EINVAL;\n\t\tto.tv_sec = at->tv_sec - to.tv_sec;\n\t\tif ((to.tv_nsec = at->tv_nsec - to.tv_nsec) < 0) {\n\t\t\tto.tv_sec--;\n\t\t\tto.tv_nsec += 1000000000;\n\t\t}\n\t\tif (to.tv_sec < 0) return ETIMEDOUT;\n\t\ttop = &to;\n\t}\n\n\tr = -__futex4_cp(addr, FUTEX_WAIT|priv, val, top);\n\tif (r != EINTR && r != ETIMEDOUT && r != ECANCELED) r = 0;\n\t/* Mitigate bug in old kernels wrongly reporting EINTR for non-\n\t * interrupting (SA_RESTART) signal handlers. This is only practical\n\t * when NO interrupting signal handlers have been installed, and\n\t * works by sigaction tracking whether that's the case. */\n\tif (r == EINTR && !__eintr_valid_flag) r = 0;\n\n\treturn r;\n}\n\nint __timedwait(volatile int *addr, int val,\n\tclockid_t clk, const struct timespec *at, int priv)\n{\n\tint cs, r;\n\t__pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);\n\tr = __timedwait_cp(addr, val, clk, at, priv);\n\t__pthread_setcancelstate(cs, 0);\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/src/thread/__tls_get_addr.c",
    "content": "#include \"pthread_impl.h\"\n\nvoid *__tls_get_addr(tls_mod_off_t *v)\n{\n\tpthread_t self = __pthread_self();\n\treturn (void *)(self->dtv[v[0]] + v[1]);\n}\n"
  },
  {
    "path": "user.libc/src/thread/__unmapself.c",
    "content": "#include \"pthread_impl.h\"\n#include \"atomic.h\"\n#include \"syscall.h\"\n/* cheat and reuse CRTJMP macro from dynlink code */\n#include \"dynlink.h\"\n\nstatic void *unmap_base;\nstatic size_t unmap_size;\nstatic char shared_stack[256];\n\nstatic void do_unmap()\n{\n\t__syscall(SYS_munmap, unmap_base, unmap_size);\n\t__syscall(SYS_exit);\n}\n\nvoid __unmapself(void *base, size_t size)\n{\n\tchar *stack = shared_stack + sizeof shared_stack;\n\tstack -= (uintptr_t)stack % 16;\n\tunmap_base = base;\n\tunmap_size = size;\n\tCRTJMP(do_unmap, stack);\n}\n"
  },
  {
    "path": "user.libc/src/thread/__wait.c",
    "content": "#include \"pthread_impl.h\"\n\nvoid __wait(volatile int *addr, volatile int *waiters, int val, int priv)\n{\n\tint spins=100;\n\tif (priv) priv = FUTEX_PRIVATE;\n\twhile (spins-- && (!waiters || !*waiters)) {\n\t\tif (*addr==val) a_spin();\n\t\telse return;\n\t}\n\tif (waiters) a_inc(waiters);\n\twhile (*addr==val) {\n\t\t__syscall(SYS_futex, addr, FUTEX_WAIT|priv, val, 0) != -ENOSYS\n\t\t|| __syscall(SYS_futex, addr, FUTEX_WAIT, val, 0);\n\t}\n\tif (waiters) a_dec(waiters);\n}\n"
  },
  {
    "path": "user.libc/src/thread/aarch64/__set_thread_area.S",
    "content": ".global __set_thread_area\n.hidden __set_thread_area\n.type   __set_thread_area,@function\n__set_thread_area:\n\tmsr tpidr_el0,x0\n\tmov w0,#0\n\tret\n"
  },
  {
    "path": "user.libc/src/thread/aarch64/__unmapself.S",
    "content": ".global __unmapself\n.type   __unmapself,%function\n__unmapself:\n\tmov x8,#215 // SYS_munmap\n\tsvc 0\n\tmov x8,#93 // SYS_exit\n\tsvc 0\n"
  },
  {
    "path": "user.libc/src/thread/aarch64/clone.S",
    "content": "// __clone(func, stack, flags, arg, ptid, tls, ctid)\n//         x0,   x1,    w2,    x3,  x4,   x5,  x6\n\n// syscall(SYS_clone, flags, stack, ptid, tls, ctid)\n//         x8,        x0,    x1,    x2,   x3,  x4\n\n.global __clone\n.hidden __clone\n.type   __clone,%function\n__clone:\n        // align stack and save func,arg\n        and x1,x1,#-16\n        stp x0,x3,[x1,#-16]!\n\n        // syscall\n        uxtw x0,w2\n        mov x2,x4\n        mov x3,x5\n        mov x4,x6\n        mov x8,#20 // SYS_clone\n        svc #0\n\n        cbz x0,1f\n        // parent\n        ret\n        // child\n1:      ldp x1,x0,[sp],#16\n        blr x1\n        mov x8,#18 // SYS_exit\n        svc #0\n"
  },
  {
    "path": "user.libc/src/thread/aarch64/syscall_cp.S",
    "content": "// __syscall_cp_asm(&self->cancel, nr, u, v, w, x, y, z)\n//                  x0             x1  x2 x3 x4 x5 x6 x7\n\n// syscall(nr, u, v, w, x, y, z)\n//         x8  x0 x1 x2 x3 x4 x5\n\n.global __cp_begin\n.hidden __cp_begin\n.global __cp_end\n.hidden __cp_end\n.global __cp_cancel\n.hidden __cp_cancel\n.hidden __cancel\n.global __syscall_cp_asm\n.hidden __syscall_cp_asm\n.type __syscall_cp_asm,%function\n__syscall_cp_asm:\n__cp_begin:\n\tldr w0,[x0]\n\tcbnz w0,__cp_cancel\n\tmov x8,x1\n\tmov x0,x2\n\tmov x1,x3\n\tmov x2,x4\n\tmov x3,x5\n\tmov x4,x6\n\tmov x5,x7\n\tsvc 0\n__cp_end:\n\tret\n__cp_cancel:\n\tb __cancel\n"
  },
  {
    "path": "user.libc/src/thread/arm/__set_thread_area.c",
    "content": "#include <stdint.h>\n#include <elf.h>\n#include \"pthread_impl.h\"\n#include \"libc.h\"\n\n#define HWCAP_TLS (1 << 15)\n\nextern hidden const unsigned char\n\t__a_barrier_oldkuser[], __a_barrier_v6[], __a_barrier_v7[],\n\t__a_cas_v6[], __a_cas_v7[],\n\t__a_gettp_cp15[];\n\n#define __a_barrier_kuser 0xffff0fa0\n#define __a_barrier_oldkuser (uintptr_t)__a_barrier_oldkuser\n#define __a_barrier_v6 (uintptr_t)__a_barrier_v6\n#define __a_barrier_v7 (uintptr_t)__a_barrier_v7\n\n#define __a_cas_kuser 0xffff0fc0\n#define __a_cas_v6 (uintptr_t)__a_cas_v6\n#define __a_cas_v7 (uintptr_t)__a_cas_v7\n\n#define __a_gettp_kuser 0xffff0fe0\n#define __a_gettp_cp15 (uintptr_t)__a_gettp_cp15\n\nextern hidden uintptr_t __a_barrier_ptr, __a_cas_ptr, __a_gettp_ptr;\n\nint __set_thread_area(void *p)\n{\n#if !__ARM_ARCH_7A__ && !__ARM_ARCH_7R__ && __ARM_ARCH < 7\n\tif (__hwcap & HWCAP_TLS) {\n\t\tsize_t *aux;\n\t\t__a_cas_ptr = __a_cas_v7;\n\t\t__a_barrier_ptr = __a_barrier_v7;\n\t\tfor (aux=libc.auxv; *aux; aux+=2) {\n\t\t\tif (*aux != AT_PLATFORM) continue;\n\t\t\tconst char *s = (void *)aux[1];\n\t\t\tif (s[0]!='v' || s[1]!='6' || s[2]-'0'<10u) break;\n\t\t\t__a_cas_ptr = __a_cas_v6;\n\t\t\t__a_barrier_ptr = __a_barrier_v6;\n\t\t\tbreak;\n\t\t}\n\t} else {\n\t\tint ver = *(int *)0xffff0ffc;\n\t\t__a_gettp_ptr = __a_gettp_kuser;\n\t\t__a_cas_ptr = __a_cas_kuser;\n\t\t__a_barrier_ptr = __a_barrier_kuser;\n\t\tif (ver < 2) a_crash();\n\t\tif (ver < 3) __a_barrier_ptr = __a_barrier_oldkuser;\n\t}\n#endif\n\treturn __syscall(0xf0005, p);\n}\n"
  },
  {
    "path": "user.libc/src/thread/call_once.c",
    "content": "#include <threads.h>\n#include <pthread.h>\n\nvoid call_once(once_flag *flag, void (*func)(void))\n{\n\t__pthread_once(flag, func);\n}\n"
  },
  {
    "path": "user.libc/src/thread/clone.c",
    "content": "#include <errno.h>\n#include \"pthread_impl.h\"\n\nint __clone(int (*func)(void *), void *stack, int flags, void *arg, ...)\n{\n\treturn -ENOSYS;\n}\n"
  },
  {
    "path": "user.libc/src/thread/cnd_broadcast.c",
    "content": "#include <threads.h>\n#include <pthread.h>\n\nint cnd_broadcast(cnd_t *c)\n{\n\t/* This internal function never fails, and always returns zero,\n\t * which matches the value thrd_success is defined with. */\n\treturn __private_cond_signal((pthread_cond_t *)c, -1);\n}\n"
  },
  {
    "path": "user.libc/src/thread/cnd_destroy.c",
    "content": "#include <threads.h>\n\nvoid cnd_destroy(cnd_t *c)\n{\n\t/* For private cv this is a no-op */\n}\n"
  },
  {
    "path": "user.libc/src/thread/cnd_init.c",
    "content": "#include <threads.h>\n\nint cnd_init(cnd_t *c)\n{\n\t*c = (cnd_t){ 0 };\n\treturn thrd_success;\n}\n"
  },
  {
    "path": "user.libc/src/thread/cnd_signal.c",
    "content": "#include <threads.h>\n#include <pthread.h>\n\nint cnd_signal(cnd_t *c)\n{\n\t/* This internal function never fails, and always returns zero,\n\t * which matches the value thrd_success is defined with. */\n\treturn __private_cond_signal((pthread_cond_t *)c, 1);\n}\n"
  },
  {
    "path": "user.libc/src/thread/cnd_timedwait.c",
    "content": "#include <threads.h>\n#include <pthread.h>\n#include <errno.h>\n\nint cnd_timedwait(cnd_t *restrict c, mtx_t *restrict m, const struct timespec *restrict ts)\n{\n\tint ret = __pthread_cond_timedwait((pthread_cond_t *)c, (pthread_mutex_t *)m, ts);\n\tswitch (ret) {\n\t/* May also return EINVAL or EPERM. */\n\tdefault:        return thrd_error;\n\tcase 0:         return thrd_success;\n\tcase ETIMEDOUT: return thrd_timedout;\n\t}\n}\n"
  },
  {
    "path": "user.libc/src/thread/cnd_wait.c",
    "content": "#include <threads.h>\n\nint cnd_wait(cnd_t *c, mtx_t *m)\n{\n\t/* Calling cnd_timedwait with a null pointer is an extension.\n\t * It is convenient here to avoid duplication of the logic\n\t * for return values. */\n\treturn cnd_timedwait(c, m, 0);\n}\n"
  },
  {
    "path": "user.libc/src/thread/default_attr.c",
    "content": "#include \"pthread_impl.h\"\n\nunsigned __default_stacksize = DEFAULT_STACK_SIZE;\nunsigned __default_guardsize = DEFAULT_GUARD_SIZE;\n"
  },
  {
    "path": "user.libc/src/thread/lock_ptc.c",
    "content": "#include <pthread.h>\n\nstatic pthread_rwlock_t lock = PTHREAD_RWLOCK_INITIALIZER;\n\nvoid __inhibit_ptc()\n{\n\tpthread_rwlock_wrlock(&lock);\n}\n\nvoid __acquire_ptc()\n{\n\tpthread_rwlock_rdlock(&lock);\n}\n\nvoid __release_ptc()\n{\n\tpthread_rwlock_unlock(&lock);\n}\n"
  },
  {
    "path": "user.libc/src/thread/mtx_destroy.c",
    "content": "#include <threads.h>\n\nvoid mtx_destroy(mtx_t *mtx)\n{\n}\n"
  },
  {
    "path": "user.libc/src/thread/mtx_init.c",
    "content": "#include \"pthread_impl.h\"\n#include <threads.h>\n\nint mtx_init(mtx_t *m, int type)\n{\n\t*m = (mtx_t){\n\t\t._m_type = ((type&mtx_recursive) ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL),\n\t};\n\treturn thrd_success;\n}\n"
  },
  {
    "path": "user.libc/src/thread/mtx_lock.c",
    "content": "#include \"pthread_impl.h\"\n#include <threads.h>\n\nint mtx_lock(mtx_t *m)\n{\n\tif (m->_m_type == PTHREAD_MUTEX_NORMAL && !a_cas(&m->_m_lock, 0, EBUSY))\n\t\treturn thrd_success;\n\t/* Calling mtx_timedlock with a null pointer is an extension.\n\t * It is convenient, here to avoid duplication of the logic\n\t * for return values. */\n\treturn mtx_timedlock(m, 0);\n}\n"
  },
  {
    "path": "user.libc/src/thread/mtx_timedlock.c",
    "content": "#include <threads.h>\n#include <pthread.h>\n#include <errno.h>\n\nint mtx_timedlock(mtx_t *restrict m, const struct timespec *restrict ts)\n{\n\tint ret = __pthread_mutex_timedlock((pthread_mutex_t *)m, ts);\n\tswitch (ret) {\n\tdefault:        return thrd_error;\n\tcase 0:         return thrd_success;\n\tcase ETIMEDOUT: return thrd_timedout;\n\t}\n}\n"
  },
  {
    "path": "user.libc/src/thread/mtx_trylock.c",
    "content": "#include \"pthread_impl.h\"\n#include <threads.h>\n\nint mtx_trylock(mtx_t *m)\n{\n\tif (m->_m_type == PTHREAD_MUTEX_NORMAL)\n\t\treturn (a_cas(&m->_m_lock, 0, EBUSY) & EBUSY) ? thrd_busy : thrd_success;\n\n\tint ret = __pthread_mutex_trylock((pthread_mutex_t *)m);\n\tswitch (ret) {\n\tdefault:    return thrd_error;\n\tcase 0:     return thrd_success;\n\tcase EBUSY: return thrd_busy;\n\t}\n}\n"
  },
  {
    "path": "user.libc/src/thread/mtx_unlock.c",
    "content": "#include <threads.h>\n#include <pthread.h>\n\nint mtx_unlock(mtx_t *mtx)\n{\n\t/* The only cases where pthread_mutex_unlock can return an\n\t * error are undefined behavior for C11 mtx_unlock, so we can\n\t * assume it does not return an error and simply tail call. */\n\treturn __pthread_mutex_unlock((pthread_mutex_t *)mtx);\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_atfork.c",
    "content": "#include <pthread.h>\n#include \"libc.h\"\n#include \"lock.h\"\n\nstatic struct atfork_funcs {\n\tvoid (*prepare)(void);\n\tvoid (*parent)(void);\n\tvoid (*child)(void);\n\tstruct atfork_funcs *prev, *next;\n} *funcs;\n\nstatic volatile int lock[1];\n\nvoid __fork_handler(int who)\n{\n\tstruct atfork_funcs *p;\n\tif (!funcs) return;\n\tif (who < 0) {\n\t\tLOCK(lock);\n\t\tfor (p=funcs; p; p = p->next) {\n\t\t\tif (p->prepare) p->prepare();\n\t\t\tfuncs = p;\n\t\t}\n\t} else {\n\t\tfor (p=funcs; p; p = p->prev) {\n\t\t\tif (!who && p->parent) p->parent();\n\t\t\telse if (who && p->child) p->child();\n\t\t\tfuncs = p;\n\t\t}\n\t\tUNLOCK(lock);\n\t}\n}\n\nint pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void))\n{\n\tstruct atfork_funcs *new = malloc(sizeof *new);\n\tif (!new) return -1;\n\n\tLOCK(lock);\n\tnew->next = funcs;\n\tnew->prev = 0;\n\tnew->prepare = prepare;\n\tnew->parent = parent;\n\tnew->child = child;\n\tif (funcs) funcs->prev = new;\n\tfuncs = new;\n\tUNLOCK(lock);\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_attr_destroy.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_attr_destroy(pthread_attr_t *a)\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_attr_get.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_attr_getdetachstate(const pthread_attr_t *a, int *state)\n{\n\t*state = a->_a_detach;\n\treturn 0;\n}\nint pthread_attr_getguardsize(const pthread_attr_t *restrict a, size_t *restrict size)\n{\n\t*size = a->_a_guardsize;\n\treturn 0;\n}\n\nint pthread_attr_getinheritsched(const pthread_attr_t *restrict a, int *restrict inherit)\n{\n\t*inherit = a->_a_sched;\n\treturn 0;\n}\n\nint pthread_attr_getschedparam(const pthread_attr_t *restrict a, struct sched_param *restrict param)\n{\n\tparam->sched_priority = a->_a_prio;\n\treturn 0;\n}\n\nint pthread_attr_getschedpolicy(const pthread_attr_t *restrict a, int *restrict policy)\n{\n\t*policy = a->_a_policy;\n\treturn 0;\n}\n\nint pthread_attr_getscope(const pthread_attr_t *restrict a, int *restrict scope)\n{\n\t*scope = PTHREAD_SCOPE_SYSTEM;\n\treturn 0;\n}\n\nint pthread_attr_getstack(const pthread_attr_t *restrict a, void **restrict addr, size_t *restrict size)\n{\n\tif (!a->_a_stackaddr)\n\t\treturn EINVAL;\n\t*size = a->_a_stacksize;\n\t*addr = (void *)(a->_a_stackaddr - *size);\n\treturn 0;\n}\n\nint pthread_attr_getstacksize(const pthread_attr_t *restrict a, size_t *restrict size)\n{\n\t*size = a->_a_stacksize;\n\treturn 0;\n}\n\nint pthread_barrierattr_getpshared(const pthread_barrierattr_t *restrict a, int *restrict pshared)\n{\n\t*pshared = !!a->__attr;\n\treturn 0;\n}\n\nint pthread_condattr_getclock(const pthread_condattr_t *restrict a, clockid_t *restrict clk)\n{\n\t*clk = a->__attr & 0x7fffffff;\n\treturn 0;\n}\n\nint pthread_condattr_getpshared(const pthread_condattr_t *restrict a, int *restrict pshared)\n{\n\t*pshared = a->__attr>>31;\n\treturn 0;\n}\n\nint pthread_mutexattr_getprotocol(const pthread_mutexattr_t *restrict a, int *restrict protocol)\n{\n\t*protocol = a->__attr / 8U % 2;\n\treturn 0;\n}\nint pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict a, int *restrict pshared)\n{\n\t*pshared = a->__attr / 128U % 2;\n\treturn 0;\n}\n\nint pthread_mutexattr_getrobust(const pthread_mutexattr_t *restrict a, int *restrict robust)\n{\n\t*robust = a->__attr / 4U % 2;\n\treturn 0;\n}\n\nint pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict a, int *restrict type)\n{\n\t*type = a->__attr & 3;\n\treturn 0;\n}\n\nint pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *restrict a, int *restrict pshared)\n{\n\t*pshared = a->__attr[0];\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_attr_init.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_attr_init(pthread_attr_t *a)\n{\n\t*a = (pthread_attr_t){0};\n\t__acquire_ptc();\n\ta->_a_stacksize = __default_stacksize;\n\ta->_a_guardsize = __default_guardsize;\n\t__release_ptc();\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_attr_setdetachstate.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_attr_setdetachstate(pthread_attr_t *a, int state)\n{\n\tif (state > 1U) return EINVAL;\n\ta->_a_detach = state;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_attr_setguardsize.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_attr_setguardsize(pthread_attr_t *a, size_t size)\n{\n\tif (size > SIZE_MAX/8) return EINVAL;\n\ta->_a_guardsize = size;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_attr_setinheritsched.c",
    "content": "#include \"pthread_impl.h\"\n#include \"syscall.h\"\n\nint pthread_attr_setinheritsched(pthread_attr_t *a, int inherit)\n{\n\tif (inherit > 1U) return EINVAL;\n\ta->_a_sched = inherit;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_attr_setschedparam.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_attr_setschedparam(pthread_attr_t *restrict a, const struct sched_param *restrict param)\n{\n\ta->_a_prio = param->sched_priority;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_attr_setschedpolicy.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_attr_setschedpolicy(pthread_attr_t *a, int policy)\n{\n\ta->_a_policy = policy;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_attr_setscope.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_attr_setscope(pthread_attr_t *a, int scope)\n{\n\tswitch (scope) {\n\tcase PTHREAD_SCOPE_SYSTEM:\n\t\treturn 0;\n\tcase PTHREAD_SCOPE_PROCESS:\n\t\treturn ENOTSUP;\n\tdefault:\n\t\treturn EINVAL;\n\t}\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_attr_setstack.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_attr_setstack(pthread_attr_t *a, void *addr, size_t size)\n{\n\tif (size-PTHREAD_STACK_MIN > SIZE_MAX/4) return EINVAL;\n\ta->_a_stackaddr = (size_t)addr + size;\n\ta->_a_stacksize = size;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_attr_setstacksize.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_attr_setstacksize(pthread_attr_t *a, size_t size)\n{\n\tif (size-PTHREAD_STACK_MIN > SIZE_MAX/4) return EINVAL;\n\ta->_a_stackaddr = 0;\n\ta->_a_stacksize = size;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_barrier_destroy.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_barrier_destroy(pthread_barrier_t *b)\n{\n\tif (b->_b_limit < 0) {\n\t\tif (b->_b_lock) {\n\t\t\tint v;\n\t\t\ta_or(&b->_b_lock, INT_MIN);\n\t\t\twhile ((v = b->_b_lock) & INT_MAX)\n\t\t\t\t__wait(&b->_b_lock, 0, v, 0);\n\t\t}\n\t\t__vm_wait();\n\t}\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_barrier_init.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_barrier_init(pthread_barrier_t *restrict b, const pthread_barrierattr_t *restrict a, unsigned count)\n{\n\tif (count-1 > INT_MAX-1) return EINVAL;\n\t*b = (pthread_barrier_t){ ._b_limit = count-1 | (a?a->__attr:0) };\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_barrier_wait.c",
    "content": "#include \"pthread_impl.h\"\n\nstatic int pshared_barrier_wait(pthread_barrier_t *b)\n{\n\tint limit = (b->_b_limit & INT_MAX) + 1;\n\tint ret = 0;\n\tint v, w;\n\n\tif (limit==1) return PTHREAD_BARRIER_SERIAL_THREAD;\n\n\twhile ((v=a_cas(&b->_b_lock, 0, limit)))\n\t\t__wait(&b->_b_lock, &b->_b_waiters, v, 0);\n\n\t/* Wait for <limit> threads to get to the barrier */\n\tif (++b->_b_count == limit) {\n\t\ta_store(&b->_b_count, 0);\n\t\tret = PTHREAD_BARRIER_SERIAL_THREAD;\n\t\tif (b->_b_waiters2) __wake(&b->_b_count, -1, 0);\n\t} else {\n\t\ta_store(&b->_b_lock, 0);\n\t\tif (b->_b_waiters) __wake(&b->_b_lock, 1, 0);\n\t\twhile ((v=b->_b_count)>0)\n\t\t\t__wait(&b->_b_count, &b->_b_waiters2, v, 0);\n\t}\n\n\t__vm_lock();\n\n\t/* Ensure all threads have a vm lock before proceeding */\n\tif (a_fetch_add(&b->_b_count, -1)==1-limit) {\n\t\ta_store(&b->_b_count, 0);\n\t\tif (b->_b_waiters2) __wake(&b->_b_count, -1, 0);\n\t} else {\n\t\twhile ((v=b->_b_count))\n\t\t\t__wait(&b->_b_count, &b->_b_waiters2, v, 0);\n\t}\n\t\n\t/* Perform a recursive unlock suitable for self-sync'd destruction */\n\tdo {\n\t\tv = b->_b_lock;\n\t\tw = b->_b_waiters;\n\t} while (a_cas(&b->_b_lock, v, v==INT_MIN+1 ? 0 : v-1) != v);\n\n\t/* Wake a thread waiting to reuse or destroy the barrier */\n\tif (v==INT_MIN+1 || (v==1 && w))\n\t\t__wake(&b->_b_lock, 1, 0);\n\n\t__vm_unlock();\n\n\treturn ret;\n}\n\nstruct instance\n{\n\tvolatile int count;\n\tvolatile int last;\n\tvolatile int waiters;\n\tvolatile int finished;\n};\n\nint pthread_barrier_wait(pthread_barrier_t *b)\n{\n\tint limit = b->_b_limit;\n\tstruct instance *inst;\n\n\t/* Trivial case: count was set at 1 */\n\tif (!limit) return PTHREAD_BARRIER_SERIAL_THREAD;\n\n\t/* Process-shared barriers require a separate, inefficient wait */\n\tif (limit < 0) return pshared_barrier_wait(b);\n\n\t/* Otherwise we need a lock on the barrier object */\n\twhile (a_swap(&b->_b_lock, 1))\n\t\t__wait(&b->_b_lock, &b->_b_waiters, 1, 1);\n\tinst = b->_b_inst;\n\n\t/* First thread to enter the barrier becomes the \"instance owner\" */\n\tif (!inst) {\n\t\tstruct instance new_inst = { 0 };\n\t\tint spins = 200;\n\t\tb->_b_inst = inst = &new_inst;\n\t\ta_store(&b->_b_lock, 0);\n\t\tif (b->_b_waiters) __wake(&b->_b_lock, 1, 1);\n\t\twhile (spins-- && !inst->finished)\n\t\t\ta_spin();\n\t\ta_inc(&inst->finished);\n\t\twhile (inst->finished == 1)\n\t\t\t__syscall(SYS_futex,&inst->finished,FUTEX_WAIT|FUTEX_PRIVATE,1,0) != -ENOSYS\n\t\t\t|| __syscall(SYS_futex,&inst->finished,FUTEX_WAIT,1,0);\n\t\treturn PTHREAD_BARRIER_SERIAL_THREAD;\n\t}\n\n\t/* Last thread to enter the barrier wakes all non-instance-owners */\n\tif (++inst->count == limit) {\n\t\tb->_b_inst = 0;\n\t\ta_store(&b->_b_lock, 0);\n\t\tif (b->_b_waiters) __wake(&b->_b_lock, 1, 1);\n\t\ta_store(&inst->last, 1);\n\t\tif (inst->waiters)\n\t\t\t__wake(&inst->last, -1, 1);\n\t} else {\n\t\ta_store(&b->_b_lock, 0);\n\t\tif (b->_b_waiters) __wake(&b->_b_lock, 1, 1);\n\t\t__wait(&inst->last, &inst->waiters, 0, 1);\n\t}\n\n\t/* Last thread to exit the barrier wakes the instance owner */\n\tif (a_fetch_add(&inst->count,-1)==1 && a_fetch_add(&inst->finished,1))\n\t\t__wake(&inst->finished, 1, 1);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_barrierattr_destroy.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_barrierattr_destroy(pthread_barrierattr_t *a)\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_barrierattr_init.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_barrierattr_init(pthread_barrierattr_t *a)\n{\n\t*a = (pthread_barrierattr_t){0};\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_barrierattr_setpshared.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_barrierattr_setpshared(pthread_barrierattr_t *a, int pshared)\n{\n\tif (pshared > 1U) return EINVAL;\n\ta->__attr = pshared ? INT_MIN : 0;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_cancel.c",
    "content": "#define _GNU_SOURCE\n#include <string.h>\n#include \"pthread_impl.h\"\n#include \"syscall.h\"\n\nhidden long __cancel(), __syscall_cp_asm(), __syscall_cp_c();\n\nlong __cancel()\n{\n\tpthread_t self = __pthread_self();\n\tif (self->canceldisable == PTHREAD_CANCEL_ENABLE || self->cancelasync)\n\t\tpthread_exit(PTHREAD_CANCELED);\n\tself->canceldisable = PTHREAD_CANCEL_DISABLE;\n\treturn -ECANCELED;\n}\n\nlong __syscall_cp_asm(volatile void *, syscall_arg_t,\n                      syscall_arg_t, syscall_arg_t, syscall_arg_t,\n                      syscall_arg_t, syscall_arg_t, syscall_arg_t);\n\nlong __syscall_cp_c(syscall_arg_t nr,\n                    syscall_arg_t u, syscall_arg_t v, syscall_arg_t w,\n                    syscall_arg_t x, syscall_arg_t y, syscall_arg_t z)\n{\n\tpthread_t self;\n\tlong r;\n\tint st;\n#if 0\n\tif ((st=(self=__pthread_self())->canceldisable)\n\t    && (st==PTHREAD_CANCEL_DISABLE || nr==SYS_close))\n\t\treturn __syscall(nr, u, v, w, x, y, z);\n\n\tr = __syscall_cp_asm(&self->cancel, nr, u, v, w, x, y, z);\n\tif (r==-EINTR && nr!=SYS_close && self->cancel &&\n\t    self->canceldisable != PTHREAD_CANCEL_DISABLE)\n\t\tr = __cancel();\n#endif\n\treturn r;\n}\n\nstatic void _sigaddset(sigset_t *set, int sig)\n{\n\tunsigned s = sig-1;\n\tset->__bits[s/8/sizeof *set->__bits] |= 1UL<<(s&8*sizeof *set->__bits-1);\n}\n\nextern hidden const char __cp_begin[1], __cp_end[1], __cp_cancel[1];\n\n#if 0\nstatic void cancel_handler(int sig, siginfo_t *si, void *ctx)\n{\n\tpthread_t self = __pthread_self();\n\tucontext_t *uc = ctx;\n\tuintptr_t pc = uc->uc_mcontext.MC_PC;\n\n\ta_barrier();\n\tif (!self->cancel || self->canceldisable == PTHREAD_CANCEL_DISABLE) return;\n\n\t_sigaddset(&uc->uc_sigmask, SIGCANCEL);\n\n\tif (self->cancelasync || pc >= (uintptr_t)__cp_begin && pc < (uintptr_t)__cp_end) {\n\t\tuc->uc_mcontext.MC_PC = (uintptr_t)__cp_cancel;\n#ifdef CANCEL_GOT\n\t\tuc->uc_mcontext.MC_GOT = CANCEL_GOT;\n#endif\n\t\treturn;\n\t}\n\n\t__syscall(SYS_tkill, self->tid, SIGCANCEL);\n}\n#endif\n\nvoid __testcancel()\n{\n\tpthread_t self = __pthread_self();\n\tif (self->cancel && !self->canceldisable)\n\t\t__cancel();\n}\n\nstatic void init_cancellation()\n{\n\n}\n\nint pthread_cancel(pthread_t t)\n{\n\tstatic int init;\n\tif (!init) {\n\t\tinit_cancellation();\n\t\tinit = 1;\n\t}\n\ta_store(&t->cancel, 1);\n\tif (t == pthread_self()) {\n\t\tif (t->canceldisable == PTHREAD_CANCEL_ENABLE && t->cancelasync)\n\t\t\tpthread_exit(PTHREAD_CANCELED);\n\t\treturn 0;\n\t}\n\treturn pthread_kill(t, SIGCANCEL);\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_cleanup_push.c",
    "content": "#include \"pthread_impl.h\"\n\nstatic void dummy(struct __ptcb *cb)\n{\n}\nweak_alias(dummy, __do_cleanup_push);\nweak_alias(dummy, __do_cleanup_pop);\n\nvoid _pthread_cleanup_push(struct __ptcb *cb, void (*f)(void *), void *x)\n{\n\tcb->__f = f;\n\tcb->__x = x;\n\t__do_cleanup_push(cb);\n}\n\nvoid _pthread_cleanup_pop(struct __ptcb *cb, int run)\n{\n\t__do_cleanup_pop(cb);\n\tif (run) cb->__f(cb->__x);\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_cond_broadcast.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_cond_broadcast(pthread_cond_t *c)\n{\n\tif (!c->_c_shared) return __private_cond_signal(c, -1);\n\tif (!c->_c_waiters) return 0;\n\ta_inc(&c->_c_seq);\n\t__wake(&c->_c_seq, -1, 0);\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_cond_destroy.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_cond_destroy(pthread_cond_t *c)\n{\n\tif (c->_c_shared && c->_c_waiters) {\n\t\tint cnt;\n\t\ta_or(&c->_c_waiters, 0x80000000);\n\t\ta_inc(&c->_c_seq);\n\t\t__wake(&c->_c_seq, -1, 0);\n\t\twhile ((cnt = c->_c_waiters) & 0x7fffffff)\n\t\t\t__wait(&c->_c_waiters, 0, cnt, 0);\n\t}\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_cond_init.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_cond_init(pthread_cond_t *restrict c, const pthread_condattr_t *restrict a)\n{\n\t*c = (pthread_cond_t){0};\n\tif (a) {\n\t\tc->_c_clock = a->__attr & 0x7fffffff;\n\t\tif (a->__attr>>31) c->_c_shared = (void *)-1;\n\t}\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_cond_signal.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_cond_signal(pthread_cond_t *c)\n{\n\tif (!c->_c_shared) return __private_cond_signal(c, 1);\n\tif (!c->_c_waiters) return 0;\n\ta_inc(&c->_c_seq);\n\t__wake(&c->_c_seq, 1, 0);\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_cond_timedwait.c",
    "content": "#include \"pthread_impl.h\"\n\n/*\n * struct waiter\n *\n * Waiter objects have automatic storage on the waiting thread, and\n * are used in building a linked list representing waiters currently\n * waiting on the condition variable or a group of waiters woken\n * together by a broadcast or signal; in the case of signal, this is a\n * degenerate list of one member.\n *\n * Waiter lists attached to the condition variable itself are\n * protected by the lock on the cv. Detached waiter lists are never\n * modified again, but can only be traversed in reverse order, and are\n * protected by the \"barrier\" locks in each node, which are unlocked\n * in turn to control wake order.\n *\n * Since process-shared cond var semantics do not necessarily allow\n * one thread to see another's automatic storage (they may be in\n * different processes), the waiter list is not used for the\n * process-shared case, but the structure is still used to store data\n * needed by the cancellation cleanup handler.\n */\n\nstruct waiter {\n\tstruct waiter *prev, *next;\n\tvolatile int state, barrier;\n\tvolatile int *notify;\n};\n\n/* Self-synchronized-destruction-safe lock functions */\n\nstatic inline void lock(volatile int *l)\n{\n\tif (a_cas(l, 0, 1)) {\n\t\ta_cas(l, 1, 2);\n\t\tdo __wait(l, 0, 2, 1);\n\t\twhile (a_cas(l, 0, 2));\n\t}\n}\n\nstatic inline void unlock(volatile int *l)\n{\n\tif (a_swap(l, 0)==2)\n\t\t__wake(l, 1, 1);\n}\n\nstatic inline void unlock_requeue(volatile int *l, volatile int *r, int w)\n{\n\ta_store(l, 0);\n\tif (w) __wake(l, 1, 1);\n\telse __syscall(SYS_futex, l, FUTEX_REQUEUE|FUTEX_PRIVATE, 0, 1, r) != -ENOSYS\n\t\t|| __syscall(SYS_futex, l, FUTEX_REQUEUE, 0, 1, r);\n}\n\nenum {\n\tWAITING,\n\tSIGNALED,\n\tLEAVING,\n};\n\nint __pthread_cond_timedwait(pthread_cond_t *restrict c, pthread_mutex_t *restrict m, const struct timespec *restrict ts)\n{\n\tstruct waiter node = { 0 };\n\tint e, seq, clock = c->_c_clock, cs, shared=0, oldstate, tmp;\n\tvolatile int *fut;\n\n\tif ((m->_m_type&15) && (m->_m_lock&INT_MAX) != __pthread_self()->tid)\n\t\treturn EPERM;\n\n\tif (ts && ts->tv_nsec >= 1000000000UL)\n\t\treturn EINVAL;\n\n\t__pthread_testcancel();\n\n\tif (c->_c_shared) {\n\t\tshared = 1;\n\t\tfut = &c->_c_seq;\n\t\tseq = c->_c_seq;\n\t\ta_inc(&c->_c_waiters);\n\t} else {\n\t\tlock(&c->_c_lock);\n\n\t\tseq = node.barrier = 2;\n\t\tfut = &node.barrier;\n\t\tnode.state = WAITING;\n\t\tnode.next = c->_c_head;\n\t\tc->_c_head = &node;\n\t\tif (!c->_c_tail) c->_c_tail = &node;\n\t\telse node.next->prev = &node;\n\n\t\tunlock(&c->_c_lock);\n\t}\n\n\t__pthread_mutex_unlock(m);\n\n\t__pthread_setcancelstate(PTHREAD_CANCEL_MASKED, &cs);\n\tif (cs == PTHREAD_CANCEL_DISABLE) __pthread_setcancelstate(cs, 0);\n\n\tdo e = __timedwait_cp(fut, seq, clock, ts, !shared);\n\twhile (*fut==seq && (!e || e==EINTR));\n\tif (e == EINTR) e = 0;\n\n\tif (shared) {\n\t\t/* Suppress cancellation if a signal was potentially\n\t\t * consumed; this is a legitimate form of spurious\n\t\t * wake even if not. */\n\t\tif (e == ECANCELED && c->_c_seq != seq) e = 0;\n\t\tif (a_fetch_add(&c->_c_waiters, -1) == -0x7fffffff)\n\t\t\t__wake(&c->_c_waiters, 1, 0);\n\t\toldstate = WAITING;\n\t\tgoto relock;\n\t}\n\n\toldstate = a_cas(&node.state, WAITING, LEAVING);\n\n\tif (oldstate == WAITING) {\n\t\t/* Access to cv object is valid because this waiter was not\n\t\t * yet signaled and a new signal/broadcast cannot return\n\t\t * after seeing a LEAVING waiter without getting notified\n\t\t * via the futex notify below. */\n\n\t\tlock(&c->_c_lock);\n\t\t\n\t\tif (c->_c_head == &node) c->_c_head = node.next;\n\t\telse if (node.prev) node.prev->next = node.next;\n\t\tif (c->_c_tail == &node) c->_c_tail = node.prev;\n\t\telse if (node.next) node.next->prev = node.prev;\n\t\t\n\t\tunlock(&c->_c_lock);\n\n\t\tif (node.notify) {\n\t\t\tif (a_fetch_add(node.notify, -1)==1)\n\t\t\t\t__wake(node.notify, 1, 1);\n\t\t}\n\t} else {\n\t\t/* Lock barrier first to control wake order. */\n\t\tlock(&node.barrier);\n\t}\n\nrelock:\n\t/* Errors locking the mutex override any existing error or\n\t * cancellation, since the caller must see them to know the\n\t * state of the mutex. */\n\tif ((tmp = pthread_mutex_lock(m))) e = tmp;\n\n\tif (oldstate == WAITING) goto done;\n\n\tif (!node.next && !(m->_m_type & 8))\n\t\ta_inc(&m->_m_waiters);\n\n\t/* Unlock the barrier that's holding back the next waiter, and\n\t * either wake it or requeue it to the mutex. */\n\tif (node.prev) {\n\t\tint val = m->_m_lock;\n\t\tif (val>0) a_cas(&m->_m_lock, val, val|0x80000000);\n\t\tunlock_requeue(&node.prev->barrier, &m->_m_lock, m->_m_type & (8|128));\n\t} else if (!(m->_m_type & 8)) {\n\t\ta_dec(&m->_m_waiters);\t\t\n\t}\n\n\t/* Since a signal was consumed, cancellation is not permitted. */\n\tif (e == ECANCELED) e = 0;\n\ndone:\n\t__pthread_setcancelstate(cs, 0);\n\n\tif (e == ECANCELED) {\n\t\t__pthread_testcancel();\n\t\t__pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);\n\t}\n\n\treturn e;\n}\n\nint __private_cond_signal(pthread_cond_t *c, int n)\n{\n\tstruct waiter *p, *first=0;\n\tvolatile int ref = 0;\n\tint cur;\n\n\tlock(&c->_c_lock);\n\tfor (p=c->_c_tail; n && p; p=p->prev) {\n\t\tif (a_cas(&p->state, WAITING, SIGNALED) != WAITING) {\n\t\t\tref++;\n\t\t\tp->notify = &ref;\n\t\t} else {\n\t\t\tn--;\n\t\t\tif (!first) first=p;\n\t\t}\n\t}\n\t/* Split the list, leaving any remainder on the cv. */\n\tif (p) {\n\t\tif (p->next) p->next->prev = 0;\n\t\tp->next = 0;\n\t} else {\n\t\tc->_c_head = 0;\n\t}\n\tc->_c_tail = p;\n\tunlock(&c->_c_lock);\n\n\t/* Wait for any waiters in the LEAVING state to remove\n\t * themselves from the list before returning or allowing\n\t * signaled threads to proceed. */\n\twhile ((cur = ref)) __wait(&ref, 0, cur, 1);\n\n\t/* Allow first signaled waiter, if any, to proceed. */\n\tif (first) unlock(&first->barrier);\n\n\treturn 0;\n}\n\nweak_alias(__pthread_cond_timedwait, pthread_cond_timedwait);\n"
  },
  {
    "path": "user.libc/src/thread/pthread_cond_wait.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_cond_wait(pthread_cond_t *restrict c, pthread_mutex_t *restrict m)\n{\n\treturn pthread_cond_timedwait(c, m, 0);\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_condattr_destroy.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_condattr_destroy(pthread_condattr_t *a)\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_condattr_init.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_condattr_init(pthread_condattr_t *a)\n{\n\t*a = (pthread_condattr_t){0};\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_condattr_setclock.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_condattr_setclock(pthread_condattr_t *a, clockid_t clk)\n{\n\tif (clk < 0 || clk-2U < 2) return EINVAL;\n\ta->__attr &= 0x80000000;\n\ta->__attr |= clk;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_condattr_setpshared.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_condattr_setpshared(pthread_condattr_t *a, int pshared)\n{\n\tif (pshared > 1U) return EINVAL;\n\ta->__attr &= 0x7fffffff;\n\ta->__attr |= (unsigned)pshared<<31;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_create.c",
    "content": "#define _GNU_SOURCE\n#include \"pthread_impl.h\"\n#include \"stdio_impl.h\"\n#include \"libc.h\"\n#include \"lock.h\"\n#include <sys/mman.h>\n#include <string.h>\n#include <stddef.h>\n\nstatic void dummy_0()\n{\n}\nweak_alias(dummy_0, __acquire_ptc);\nweak_alias(dummy_0, __release_ptc);\nweak_alias(dummy_0, __pthread_tsd_run_dtors);\nweak_alias(dummy_0, __do_orphaned_stdio_locks);\nweak_alias(dummy_0, __dl_thread_cleanup);\nweak_alias(dummy_0, __membarrier_init);\n\nstatic int tl_lock_count;\nstatic int tl_lock_waiters;\n\nvoid __tl_lock(void)\n{\n\tint tid = __pthread_self()->tid;\n\tint val = __thread_list_lock;\n\tif (val == tid) {\n\t\ttl_lock_count++;\n\t\treturn;\n\t}\n\twhile ((val = a_cas(&__thread_list_lock, 0, tid)))\n\t\t__wait(&__thread_list_lock, &tl_lock_waiters, val, 0);\n}\n\nvoid __tl_unlock(void)\n{\n\tif (tl_lock_count) {\n\t\ttl_lock_count--;\n\t\treturn;\n\t}\n\ta_store(&__thread_list_lock, 0);\n\tif (tl_lock_waiters) __wake(&__thread_list_lock, 1, 0);\n}\n\nvoid __tl_sync(pthread_t td)\n{\n\ta_barrier();\n\tint val = __thread_list_lock;\n\tif (!val) return;\n\t__wait(&__thread_list_lock, &tl_lock_waiters, val, 0);\n\tif (tl_lock_waiters) __wake(&__thread_list_lock, 1, 0);\n}\n\n_Noreturn void __pthread_exit(void *result)\n{\n\tpthread_t self = __pthread_self();\n\n\tself->canceldisable = 1;\n\tself->cancelasync = 0;\n\tself->result = result;\n\n\twhile (self->cancelbuf) {\n\t\tvoid (*f)(void *) = self->cancelbuf->__f;\n\t\tvoid *x = self->cancelbuf->__x;\n\t\tself->cancelbuf = self->cancelbuf->__next;\n\t\tf(x);\n\t}\n\n\t__pthread_tsd_run_dtors();\n\n\t/* This atomic potentially competes with a concurrent pthread_detach\n\t * call; the loser is responsible for freeing thread resources. */\n\tint state = a_cas(&self->detach_state, DT_JOINABLE, DT_EXITING);\n\n\tif (state==DT_DETACHED && self->map_base) {\n\t\t/* Since __unmapself bypasses the normal munmap code path,\n\t\t * explicitly wait for vmlock holders first. This must be\n\t\t * done before any locks are taken, to avoid lock ordering\n\t\t * issues that could lead to deadlock. */\n\t\t__vm_wait();\n\t}\n\n\t/* Access to target the exiting thread with syscalls that use\n\t * its kernel tid is controlled by killlock. For detached threads,\n\t * any use past this point would have undefined behavior, but for\n\t * joinable threads it's a valid usage that must be handled.\n\t * Signals must be blocked since pthread_kill must be AS-safe. */\n\tLOCK(self->killlock);\n\n\t/* The thread list lock must be AS-safe, and thus depends on\n\t * application signals being blocked above. */\n\t__tl_lock();\n\n\t/* If this is the only thread in the list, don't proceed with\n\t * termination of the thread, but restore the previous lock and\n\t * signal state to prepare for exit to call atexit handlers. */\n\tif (self->next == self) {\n\t\t__tl_unlock();\n\t\tUNLOCK(self->killlock);\n\t\tself->detach_state = state;\n\t\texit(0);\n\t}\n\n\t/* At this point we are committed to thread termination. */\n\n\t/* Process robust list in userspace to handle non-pshared mutexes\n\t * and the detached thread case where the robust list head will\n\t * be invalid when the kernel would process it. */\n\t__vm_lock();\n\tvolatile void *volatile *rp;\n\twhile ((rp=self->robust_list.head) && rp != &self->robust_list.head) {\n\t\tpthread_mutex_t *m = (void *)((char *)rp\n\t\t\t- offsetof(pthread_mutex_t, _m_next));\n\t\tint waiters = m->_m_waiters;\n\t\tint priv = (m->_m_type & 128) ^ 128;\n\t\tself->robust_list.pending = rp;\n\t\tself->robust_list.head = *rp;\n\t\tint cont = a_swap(&m->_m_lock, 0x40000000);\n\t\tself->robust_list.pending = 0;\n\t\tif (cont < 0 || waiters)\n\t\t\t__wake(&m->_m_lock, 1, priv);\n\t}\n\t__vm_unlock();\n\n\t__do_orphaned_stdio_locks();\n\t__dl_thread_cleanup();\n\n\t/* Last, unlink thread from the list. This change will not be visible\n\t * until the lock is released, which only happens after SYS_exit\n\t * has been called, via the exit futex address pointing at the lock.\n\t * This needs to happen after any possible calls to LOCK() that might\n\t * skip locking if process appears single-threaded. */\n\tif (!--libc.threads_minus_1) libc.need_locks = -1;\n\tself->next->prev = self->prev;\n\tself->prev->next = self->next;\n\tself->prev = self->next = self;\n\n\tif (state==DT_DETACHED && self->map_base) {\n\t\t/* Robust list will no longer be valid, and was already\n\t\t * processed above, so unregister it with the kernel. */\n#if 0\n\t\t if (self->robust_list.off)\n\t\t\t__syscall(SYS_set_robust_list, 0, 3*sizeof(long));\n#endif\n\n\t\t/* The following call unmaps the thread's stack mapping\n\t\t * and then exits without touching the stack. */\n\t\t__unmapself(self->map_base, self->map_size);\n\t}\n\n\t/* Wake any joiner. */\n\ta_store(&self->detach_state, DT_EXITED);\n\t__wake(&self->detach_state, 1, 1);\n\n\t/* After the kernel thread exits, its tid may be reused. Clear it\n\t * to prevent inadvertent use and inform functions that would use\n\t * it that it's no longer available. */\n\tself->tid = 0;\n\n\t__tl_unlock();\n\tUNLOCK(self->killlock);\n\n\t__syscall(SYS_exit, 0);\n}\n\nvoid __do_cleanup_push(struct __ptcb *cb)\n{\n\tstruct pthread *self = __pthread_self();\n\tcb->__next = self->cancelbuf;\n\tself->cancelbuf = cb;\n}\n\nvoid __do_cleanup_pop(struct __ptcb *cb)\n{\n\t__pthread_self()->cancelbuf = cb->__next;\n}\n\nstruct start_args {\n\tvoid *(*start_func)(void *);\n\tvoid *start_arg;\n\tvolatile int control;\n\tunsigned long sig_mask[_NSIG/8/sizeof(long)];\n};\n\nstatic int start(void *p)\n{\n\tstruct start_args *args = p;\n\tint state = args->control;\n\tif (state) {\n\t\tif (a_cas(&args->control, 1, 2)==1)\n\t\t\t__wait(&args->control, 0, 2, 1);\n\t\tif (args->control) {\n\t\t\t// __syscall(SYS_set_tid_address, &args->control);\n\t\t\t// for (;;) __syscall(SYS_exit, 0);\n\t\t}\n\t}\n\t// __syscall(SYS_rt_sigprocmask, SIG_SETMASK, &args->sig_mask, 0, _NSIG/8);\n\t__pthread_exit(args->start_func(args->start_arg));\n\treturn 0;\n}\n\nstatic int start_c11(void *p)\n{\n\tstruct start_args *args = p;\n\tint (*start)(void*) = (int(*)(void*)) args->start_func;\n\t__pthread_exit((void *)(uintptr_t)start(args->start_arg));\n\treturn 0;\n}\n\n#define ROUND(x) (((x)+PAGE_SIZE-1)&-PAGE_SIZE)\n\n/* pthread_key_create.c overrides this */\nstatic volatile size_t dummy = 0;\nweak_alias(dummy, __pthread_tsd_size);\nstatic void *dummy_tsd[1] = { 0 };\nweak_alias(dummy_tsd, __pthread_tsd_main);\n\nstatic FILE *volatile dummy_file = 0;\nweak_alias(dummy_file, __stdin_used);\nweak_alias(dummy_file, __stdout_used);\nweak_alias(dummy_file, __stderr_used);\n\nstatic void init_file_lock(FILE *f)\n{\n\tif (f && f->lock<0) f->lock = 0;\n}\n\nint __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attrp, void *(*entry)(void *), void *restrict arg)\n{\n\tint ret, c11 = (attrp == __ATTRP_C11_THREAD);\n\tsize_t size, guard;\n\tstruct pthread *self, *new;\n\tunsigned char *map = 0, *stack = 0, *tsd = 0, *stack_limit;\n\tunsigned flags = 0;\n\tpthread_attr_t attr = { 0 };\n\n\tif (!libc.can_do_threads) return ENOSYS;\n\tself = __pthread_self();\n\tif (!libc.threaded) {\n\t\tfor (FILE *f=*__ofl_lock(); f; f=f->next)\n\t\t\tinit_file_lock(f);\n\t\t__ofl_unlock();\n\t\tinit_file_lock(__stdin_used);\n\t\tinit_file_lock(__stdout_used);\n\t\tinit_file_lock(__stderr_used);\n\t\tself->tsd = (void **)__pthread_tsd_main;\n\t\t__membarrier_init();\n\t\tlibc.threaded = 1;\n\t}\n\tif (attrp && !c11) attr = *attrp;\n\n\t__acquire_ptc();\n\tif (!attrp || c11) {\n\t\tattr._a_stacksize = __default_stacksize;\n\t\tattr._a_guardsize = __default_guardsize;\n\t}\n\n\tif (attr._a_stackaddr) {\n\t\tsize_t need = libc.tls_size + __pthread_tsd_size;\n\t\tsize = attr._a_stacksize;\n\t\tstack = (void *)(attr._a_stackaddr & -16);\n\t\tstack_limit = (void *)(attr._a_stackaddr - size);\n\t\t/* Use application-provided stack for TLS only when\n\t\t * it does not take more than ~12% or 2k of the\n\t\t * application's stack space. */\n\t\tif (need < size/8 && need < 2048) {\n\t\t\ttsd = stack - __pthread_tsd_size;\n\t\t\tstack = tsd - libc.tls_size;\n\t\t\tmemset(stack, 0, need);\n\t\t} else {\n\t\t\tsize = ROUND(need);\n\t\t}\n\t\tguard = 0;\n\t} else {\n\t\tguard = ROUND(attr._a_guardsize);\n\t\tsize = guard + ROUND(attr._a_stacksize\n\t\t\t+ libc.tls_size +  __pthread_tsd_size);\n\t}\n\n\tif (!tsd) {\n\t\tif (guard) {\n\t\t\tmap = __mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANON, -1, 0);\n\t\t\tif (map == MAP_FAILED) goto fail;\n\t\t\tif (__mprotect(map+guard, size-guard, PROT_READ|PROT_WRITE)\n\t\t\t    && errno != ENOSYS) {\n\t\t\t\t__munmap(map, size);\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t} else {\n\t\t\tmap = __mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);\n\t\t\tif (map == MAP_FAILED) goto fail;\n\t\t}\n\t\ttsd = map + size - __pthread_tsd_size;\n\t\tif (!stack) {\n\t\t\tstack = tsd - libc.tls_size;\n\t\t\tstack_limit = map + guard;\n\t\t}\n\t}\n\n\tnew = __copy_tls(tsd - libc.tls_size);\n\tnew->map_base = map;\n\tnew->map_size = size;\n\tnew->stack = stack;\n\tnew->stack_size = stack - stack_limit;\n\tnew->guard_size = guard;\n\tnew->self = new;\n\tnew->tsd = (void *)tsd;\n\tnew->locale = &libc.global_locale;\n\tif (attr._a_detach) {\n\t\tnew->detach_state = DT_DETACHED;\n\t} else {\n\t\tnew->detach_state = DT_JOINABLE;\n\t}\n\tnew->robust_list.head = &new->robust_list.head;\n\tnew->canary = self->canary;\n\tnew->sysinfo = self->sysinfo;\n\n\t/* Setup argument structure for the new thread on its stack.\n\t * It's safe to access from the caller only until the thread\n\t * list is unlocked. */\n\tstack -= (uintptr_t)stack % sizeof(uintptr_t);\n\tstack -= sizeof(struct start_args);\n\tstruct start_args *args = (void *)stack;\n\targs->start_func = entry;\n\targs->start_arg = arg;\n\targs->control = attr._a_sched ? 1 : 0;\n\n\t__tl_lock();\n\tif (!libc.threads_minus_1++) libc.need_locks = 1;\n\tret = __clone((c11 ? start_c11 : start), stack, flags, args, &new->tid, TP_ADJ(new), &__thread_list_lock);\n\n\t/* All clone failures translate to EAGAIN. If explicit scheduling\n\t * was requested, attempt it before unlocking the thread list so\n\t * that the failed thread is never exposed and so that we can\n\t * clean up all transient resource usage before returning. */\n\tif (ret < 0) {\n\t\tret = -EAGAIN;\n\t}\n#if 0\n\telse if (attr._a_sched) {\n\t\tret = __syscall(SYS_sched_setscheduler,\n\t\t\tnew->tid, attr._a_policy, &attr._a_prio);\n\t\tif (a_swap(&args->control, ret ? 3 : 0)==2)\n\t\t\t__wake(&args->control, 1, 1);\n\t\tif (ret)\n\t\t\t__wait(&args->control, 0, 3, 0);\n\t}\n#endif\n\n\tif (ret >= 0) {\n\t\tnew->next = self->next;\n\t\tnew->prev = self;\n\t\tnew->next->prev = new;\n\t\tnew->prev->next = new;\n\t} else {\n\t\tif (!--libc.threads_minus_1) libc.need_locks = 0;\n\t}\n\t__tl_unlock();\n\t__release_ptc();\n\n\tif (ret < 0) {\n\t\tif (map) __munmap(map, size);\n\t\treturn -ret;\n\t}\n\n\t*res = new;\n\treturn 0;\nfail:\n\t__release_ptc();\n\treturn EAGAIN;\n}\n\nweak_alias(__pthread_exit, pthread_exit);\nweak_alias(__pthread_create, pthread_create);\n"
  },
  {
    "path": "user.libc/src/thread/pthread_detach.c",
    "content": "#include \"pthread_impl.h\"\n#include <threads.h>\n\nstatic int __pthread_detach(pthread_t t)\n{\n\t/* If the cas fails, detach state is either already-detached\n\t * or exiting/exited, and pthread_join will trap or cleanup. */\n\tif (a_cas(&t->detach_state, DT_JOINABLE, DT_DETACHED) != DT_JOINABLE)\n\t\treturn __pthread_join(t, 0);\n\treturn 0;\n}\n\nweak_alias(__pthread_detach, pthread_detach);\nweak_alias(__pthread_detach, thrd_detach);\n"
  },
  {
    "path": "user.libc/src/thread/pthread_equal.c",
    "content": "#include <pthread.h>\n#include <threads.h>\n\nstatic int __pthread_equal(pthread_t a, pthread_t b)\n{\n\treturn a==b;\n}\n\nweak_alias(__pthread_equal, pthread_equal);\nweak_alias(__pthread_equal, thrd_equal);\n"
  },
  {
    "path": "user.libc/src/thread/pthread_getattr_np.c",
    "content": "#define _GNU_SOURCE\n#include \"pthread_impl.h\"\n#include \"libc.h\"\n#include <sys/mman.h>\n\nint pthread_getattr_np(pthread_t t, pthread_attr_t *a)\n{\n\t*a = (pthread_attr_t){0};\n\ta->_a_detach = t->detach_state>=DT_DETACHED;\n\ta->_a_guardsize = t->guard_size;\n\tif (t->stack) {\n\t\ta->_a_stackaddr = (uintptr_t)t->stack;\n\t\ta->_a_stacksize = t->stack_size;\n\t} else {\n\t\tchar *p = (void *)libc.auxv;\n\t\tsize_t l = PAGE_SIZE;\n\t\tp += -(uintptr_t)p & PAGE_SIZE-1;\n\t\ta->_a_stackaddr = (uintptr_t)p;\n\t\twhile (mremap(p-l-PAGE_SIZE, PAGE_SIZE, 2*PAGE_SIZE, 0)==MAP_FAILED && errno==ENOMEM)\n\t\t\tl += PAGE_SIZE;\n\t\ta->_a_stacksize = l;\n\t}\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_getconcurrency.c",
    "content": "#include <pthread.h>\n\nint pthread_getconcurrency()\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_getcpuclockid.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_getcpuclockid(pthread_t t, clockid_t *clockid)\n{\n\t*clockid = (-t->tid-1)*8U + 6;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_getschedparam.c",
    "content": "#include \"pthread_impl.h\"\n#include \"lock.h\"\n\nint pthread_getschedparam(pthread_t t, int *restrict policy, struct sched_param *restrict param)\n{\n#if 0\n\tint r;\n\tsigset_t set;\n\t__block_app_sigs(&set);\n\tLOCK(t->killlock);\n\tif (!t->tid) {\n\t\tr = ESRCH;\n\t} else {\n\t\tr = -__syscall(SYS_sched_getparam, t->tid, param);\n\t\tif (!r) {\n\t\t\t*policy = __syscall(SYS_sched_getscheduler, t->tid);\n\t\t}\n\t}\n\tUNLOCK(t->killlock);\n\t__restore_sigs(&set);\n\treturn r;\n#endif\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_getspecific.c",
    "content": "#include \"pthread_impl.h\"\n#include <threads.h>\n\nstatic void *__pthread_getspecific(pthread_key_t k)\n{\n\tstruct pthread *self = __pthread_self();\n\treturn self->tsd[k];\n}\n\nweak_alias(__pthread_getspecific, pthread_getspecific);\nweak_alias(__pthread_getspecific, tss_get);\n"
  },
  {
    "path": "user.libc/src/thread/pthread_join.c",
    "content": "#define _GNU_SOURCE\n#include \"pthread_impl.h\"\n#include <sys/mman.h>\n\nstatic void dummy1(pthread_t t)\n{\n}\nweak_alias(dummy1, __tl_sync);\n\nstatic int __pthread_timedjoin_np(pthread_t t, void **res, const struct timespec *at)\n{\n\tint state, cs, r = 0;\n\t__pthread_testcancel();\n\t__pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);\n\tif (cs == PTHREAD_CANCEL_ENABLE) __pthread_setcancelstate(cs, 0);\n\twhile ((state = t->detach_state) && r != ETIMEDOUT && r != EINVAL) {\n\t\tif (state >= DT_DETACHED) a_crash();\n\t\tr = __timedwait_cp(&t->detach_state, state, CLOCK_REALTIME, at, 1);\n\t}\n\t__pthread_setcancelstate(cs, 0);\n\tif (r == ETIMEDOUT || r == EINVAL) return r;\n\t__tl_sync(t);\n\tif (res) *res = t->result;\n\tif (t->map_base) __munmap(t->map_base, t->map_size);\n\treturn 0;\n}\n\nint __pthread_join(pthread_t t, void **res)\n{\n\treturn __pthread_timedjoin_np(t, res, 0);\n}\n\nstatic int __pthread_tryjoin_np(pthread_t t, void **res)\n{\n\treturn t->detach_state==DT_JOINABLE ? EBUSY : __pthread_join(t, res);\n}\n\nweak_alias(__pthread_tryjoin_np, pthread_tryjoin_np);\nweak_alias(__pthread_timedjoin_np, pthread_timedjoin_np);\nweak_alias(__pthread_join, pthread_join);\n"
  },
  {
    "path": "user.libc/src/thread/pthread_key_create.c",
    "content": "#include \"pthread_impl.h\"\n\nvolatile size_t __pthread_tsd_size = sizeof(void *) * PTHREAD_KEYS_MAX;\nvoid *__pthread_tsd_main[PTHREAD_KEYS_MAX] = { 0 };\n\nstatic void (*keys[PTHREAD_KEYS_MAX])(void *);\n\nstatic pthread_rwlock_t key_lock = PTHREAD_RWLOCK_INITIALIZER;\n\nstatic pthread_key_t next_key;\n\nstatic void nodtor(void *dummy)\n{\n}\n\nstatic void dummy_0(void)\n{\n}\n\nweak_alias(dummy_0, __tl_lock);\nweak_alias(dummy_0, __tl_unlock);\n\nint __pthread_key_create(pthread_key_t *k, void (*dtor)(void *))\n{\n\tpthread_t self = __pthread_self();\n\n\t/* This can only happen in the main thread before\n\t * pthread_create has been called. */\n\tif (!self->tsd) self->tsd = __pthread_tsd_main;\n\n\t/* Purely a sentinel value since null means slot is free. */\n\tif (!dtor) dtor = nodtor;\n\n\t__pthread_rwlock_wrlock(&key_lock);\n\tpthread_key_t j = next_key;\n\tdo {\n\t\tif (!keys[j]) {\n\t\t\tkeys[next_key = *k = j] = dtor;\n\t\t\t__pthread_rwlock_unlock(&key_lock);\n\t\t\treturn 0;\n\t\t}\n\t} while ((j=(j+1)%PTHREAD_KEYS_MAX) != next_key);\n\n\t__pthread_rwlock_unlock(&key_lock);\n\treturn EAGAIN;\n}\n\nint __pthread_key_delete(pthread_key_t k)\n{\n\tsigset_t set;\n\tpthread_t self = __pthread_self(), td=self;\n\n\t__block_app_sigs(&set);\n\t__pthread_rwlock_wrlock(&key_lock);\n\n\t__tl_lock();\n\tdo td->tsd[k] = 0;\n\twhile ((td=td->next)!=self);\n\t__tl_unlock();\n\n\tkeys[k] = 0;\n\n\t__pthread_rwlock_unlock(&key_lock);\n\t__restore_sigs(&set);\n\n\treturn 0;\n}\n\nvoid __pthread_tsd_run_dtors()\n{\n\tpthread_t self = __pthread_self();\n\tint i, j;\n\tfor (j=0; self->tsd_used && j<PTHREAD_DESTRUCTOR_ITERATIONS; j++) {\n\t\t__pthread_rwlock_rdlock(&key_lock);\n\t\tself->tsd_used = 0;\n\t\tfor (i=0; i<PTHREAD_KEYS_MAX; i++) {\n\t\t\tvoid *val = self->tsd[i];\n\t\t\tvoid (*dtor)(void *) = keys[i];\n\t\t\tself->tsd[i] = 0;\n\t\t\tif (val && dtor && dtor != nodtor) {\n\t\t\t\t__pthread_rwlock_unlock(&key_lock);\n\t\t\t\tdtor(val);\n\t\t\t\t__pthread_rwlock_rdlock(&key_lock);\n\t\t\t}\n\t\t}\n\t\t__pthread_rwlock_unlock(&key_lock);\n\t}\n}\n\nweak_alias(__pthread_key_create, pthread_key_create);\nweak_alias(__pthread_key_delete, pthread_key_delete);\n"
  },
  {
    "path": "user.libc/src/thread/pthread_kill.c",
    "content": "#include \"pthread_impl.h\"\n#include \"lock.h\"\n\nint pthread_kill(pthread_t t, int sig)\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_mutex_consistent.c",
    "content": "#include \"pthread_impl.h\"\n#include \"atomic.h\"\n\nint pthread_mutex_consistent(pthread_mutex_t *m)\n{\n\tint old = m->_m_lock;\n\tint own = old & 0x3fffffff;\n\tif (!(m->_m_type & 4) || !own || !(old & 0x40000000))\n\t\treturn EINVAL;\n\tif (own != __pthread_self()->tid)\n\t\treturn EPERM;\n\ta_and(&m->_m_lock, ~0x40000000);\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_mutex_destroy.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_mutex_destroy(pthread_mutex_t *mutex)\n{\n\t/* If the mutex being destroyed is process-shared and has nontrivial\n\t * type (tracking ownership), it might be in the pending slot of a\n\t * robust_list; wait for quiescence. */\n\tif (mutex->_m_type > 128) __vm_wait();\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_mutex_getprioceiling.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_mutex_getprioceiling(const pthread_mutex_t *restrict m, int *restrict ceiling)\n{\n\treturn EINVAL;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_mutex_init.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_mutex_init(pthread_mutex_t *restrict m, const pthread_mutexattr_t *restrict a)\n{\n\t*m = (pthread_mutex_t){0};\n\tif (a) m->_m_type = a->__attr;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_mutex_lock.c",
    "content": "#include \"pthread_impl.h\"\n\nint __pthread_mutex_lock(pthread_mutex_t *m)\n{\n\tif ((m->_m_type&15) == PTHREAD_MUTEX_NORMAL\n\t    && !a_cas(&m->_m_lock, 0, EBUSY))\n\t\treturn 0;\n\n\treturn __pthread_mutex_timedlock(m, 0);\n}\n\nweak_alias(__pthread_mutex_lock, pthread_mutex_lock);\n"
  },
  {
    "path": "user.libc/src/thread/pthread_mutex_setprioceiling.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_mutex_setprioceiling(pthread_mutex_t *restrict m, int ceiling, int *restrict old)\n{\n\treturn EINVAL;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_mutex_timedlock.c",
    "content": "#include \"pthread_impl.h\"\n\n#define IS32BIT(x) !((x)+0x80000000ULL>>32)\n#define CLAMP(x) (int)(IS32BIT(x) ? (x) : 0x7fffffffU+((0ULL+(x))>>63))\n\nstatic int __futex4(volatile void *addr, int op, int val, const struct timespec *to)\n{\n#ifdef SYS_futex_time64\n\ttime_t s = to ? to->tv_sec : 0;\n\tlong ns = to ? to->tv_nsec : 0;\n\tint r = -ENOSYS;\n\tif (SYS_futex == SYS_futex_time64 || !IS32BIT(s))\n\t\tr = __syscall(SYS_futex_time64, addr, op, val,\n\t\t\tto ? ((long long[]){s, ns}) : 0);\n\tif (SYS_futex == SYS_futex_time64 || r!=-ENOSYS) return r;\n\tto = to ? (void *)(long[]){CLAMP(s), ns} : 0;\n#endif\n\treturn __syscall(SYS_futex, addr, op, val, to);\n}\n\nstatic int pthread_mutex_timedlock_pi(pthread_mutex_t *restrict m, const struct timespec *restrict at)\n{\n\tint type = m->_m_type;\n\tint priv = (type & 128) ^ 128;\n\tpthread_t self = __pthread_self();\n\tint e;\n\n\tif (!priv) self->robust_list.pending = &m->_m_next;\n\n\tdo e = -__futex4(&m->_m_lock, FUTEX_LOCK_PI|priv, 0, at);\n\twhile (e==EINTR);\n\tif (e) self->robust_list.pending = 0;\n\n\tswitch (e) {\n\tcase 0:\n\t\t/* Catch spurious success for non-robust mutexes. */\n\t\tif (!(type&4) && ((m->_m_lock & 0x40000000) || m->_m_waiters)) {\n\t\t\ta_store(&m->_m_waiters, -1);\n\t\t\t__syscall(SYS_futex, &m->_m_lock, FUTEX_UNLOCK_PI|priv);\n\t\t\tself->robust_list.pending = 0;\n\t\t\tbreak;\n\t\t}\n\t\t/* Signal to trylock that we already have the lock. */\n\t\tm->_m_count = -1;\n\t\treturn __pthread_mutex_trylock(m);\n\tcase ETIMEDOUT:\n\t\treturn e;\n\tcase EDEADLK:\n\t\tif ((type&3) == PTHREAD_MUTEX_ERRORCHECK) return e;\n\t}\n\tdo e = __timedwait(&(int){0}, 0, CLOCK_REALTIME, at, 1);\n\twhile (e != ETIMEDOUT);\n\treturn e;\n}\n\nint __pthread_mutex_timedlock(pthread_mutex_t *restrict m, const struct timespec *restrict at)\n{\n\tif ((m->_m_type&15) == PTHREAD_MUTEX_NORMAL\n\t    && !a_cas(&m->_m_lock, 0, EBUSY))\n\t\treturn 0;\n\n\tint type = m->_m_type;\n\tint r, t, priv = (type & 128) ^ 128;\n\n\tr = __pthread_mutex_trylock(m);\n\tif (r != EBUSY) return r;\n\n\tif (type&8) return pthread_mutex_timedlock_pi(m, at);\n\t\n\tint spins = 100;\n\twhile (spins-- && m->_m_lock && !m->_m_waiters) a_spin();\n\n\twhile ((r=__pthread_mutex_trylock(m)) == EBUSY) {\n\t\tr = m->_m_lock;\n\t\tint own = r & 0x3fffffff;\n\t\tif (!own && (!r || (type&4)))\n\t\t\tcontinue;\n\t\tif ((type&3) == PTHREAD_MUTEX_ERRORCHECK\n\t\t    && own == __pthread_self()->tid)\n\t\t\treturn EDEADLK;\n\n\t\ta_inc(&m->_m_waiters);\n\t\tt = r | 0x80000000;\n\t\ta_cas(&m->_m_lock, r, t);\n\t\tr = __timedwait(&m->_m_lock, t, CLOCK_REALTIME, at, priv);\n\t\ta_dec(&m->_m_waiters);\n\t\tif (r && r != EINTR) break;\n\t}\n\treturn r;\n}\n\nweak_alias(__pthread_mutex_timedlock, pthread_mutex_timedlock);\n"
  },
  {
    "path": "user.libc/src/thread/pthread_mutex_trylock.c",
    "content": "#include \"pthread_impl.h\"\n\nint __pthread_mutex_trylock_owner(pthread_mutex_t *m)\n{\n\tint old, own;\n\tint type = m->_m_type;\n\tpthread_t self = __pthread_self();\n\tint tid = self->tid;\n\n\told = m->_m_lock;\n\town = old & 0x3fffffff;\n\tif (own == tid) {\n\t\tif ((type&8) && m->_m_count<0) {\n\t\t\told &= 0x40000000;\n\t\t\tm->_m_count = 0;\n\t\t\tgoto success;\n\t\t}\n\t\tif ((type&3) == PTHREAD_MUTEX_RECURSIVE) {\n\t\t\tif ((unsigned)m->_m_count >= INT_MAX) return EAGAIN;\n\t\t\tm->_m_count++;\n\t\t\treturn 0;\n\t\t}\n\t}\n\tif (own == 0x3fffffff) return ENOTRECOVERABLE;\n\tif (own || (old && !(type & 4))) return EBUSY;\n\n\tif (type & 128) {\n\t\tif (!self->robust_list.off) {\n\t\t\tself->robust_list.off = (char*)&m->_m_lock-(char *)&m->_m_next;\n//\t\t\t__syscall(SYS_set_robust_list, &self->robust_list, 3*sizeof(long));\n\t\t}\n\t\tif (m->_m_waiters) tid |= 0x80000000;\n\t\tself->robust_list.pending = &m->_m_next;\n\t}\n\ttid |= old & 0x40000000;\n\n\tif (a_cas(&m->_m_lock, old, tid) != old) {\n\t\tself->robust_list.pending = 0;\n\t\tif ((type&12)==12 && m->_m_waiters) return ENOTRECOVERABLE;\n\t\treturn EBUSY;\n\t}\n\nsuccess:\n\tif ((type&8) && m->_m_waiters) {\n\t\tint priv = (type & 128) ^ 128;\n\t\t__syscall(SYS_futex, &m->_m_lock, FUTEX_UNLOCK_PI|priv);\n\t\tself->robust_list.pending = 0;\n\t\treturn (type&4) ? ENOTRECOVERABLE : EBUSY;\n\t}\n\n\tvolatile void *next = self->robust_list.head;\n\tm->_m_next = next;\n\tm->_m_prev = &self->robust_list.head;\n\tif (next != &self->robust_list.head) *(volatile void *volatile *)\n\t\t((char *)next - sizeof(void *)) = &m->_m_next;\n\tself->robust_list.head = &m->_m_next;\n\tself->robust_list.pending = 0;\n\n\tif (old) {\n\t\tm->_m_count = 0;\n\t\treturn EOWNERDEAD;\n\t}\n\n\treturn 0;\n}\n\nint __pthread_mutex_trylock(pthread_mutex_t *m)\n{\n\tif ((m->_m_type&15) == PTHREAD_MUTEX_NORMAL)\n\t\treturn a_cas(&m->_m_lock, 0, EBUSY) & EBUSY;\n\treturn __pthread_mutex_trylock_owner(m);\n}\n\nweak_alias(__pthread_mutex_trylock, pthread_mutex_trylock);\n"
  },
  {
    "path": "user.libc/src/thread/pthread_mutex_unlock.c",
    "content": "#include \"pthread_impl.h\"\n\nint __pthread_mutex_unlock(pthread_mutex_t *m)\n{\n\tpthread_t self;\n\tint waiters = m->_m_waiters;\n\tint cont;\n\tint type = m->_m_type & 15;\n\tint priv = (m->_m_type & 128) ^ 128;\n\tint new = 0;\n\tint old;\n\n\tif (type != PTHREAD_MUTEX_NORMAL) {\n\t\tself = __pthread_self();\n\t\told = m->_m_lock;\n\t\tint own = old & 0x3fffffff;\n\t\tif (own != self->tid)\n\t\t\treturn EPERM;\n\t\tif ((type&3) == PTHREAD_MUTEX_RECURSIVE && m->_m_count)\n\t\t\treturn m->_m_count--, 0;\n\t\tif ((type&4) && (old&0x40000000))\n\t\t\tnew = 0x7fffffff;\n\t\tif (!priv) {\n\t\t\tself->robust_list.pending = &m->_m_next;\n\t\t\t__vm_lock();\n\t\t}\n\t\tvolatile void *prev = m->_m_prev;\n\t\tvolatile void *next = m->_m_next;\n\t\t*(volatile void *volatile *)prev = next;\n\t\tif (next != &self->robust_list.head) *(volatile void *volatile *)\n\t\t\t((char *)next - sizeof(void *)) = prev;\n\t}\n\tif (type&8) {\n\t\tif (old<0 || a_cas(&m->_m_lock, old, new)!=old) {\n\t\t\tif (new) a_store(&m->_m_waiters, -1);\n\t\t\t__syscall(SYS_futex, &m->_m_lock, FUTEX_UNLOCK_PI|priv);\n\t\t}\n\t\tcont = 0;\n\t\twaiters = 0;\n\t} else {\n\t\tcont = a_swap(&m->_m_lock, new);\n\t}\n\tif (type != PTHREAD_MUTEX_NORMAL && !priv) {\n\t\tself->robust_list.pending = 0;\n\t\t__vm_unlock();\n\t}\n\tif (waiters || cont<0)\n\t\t__wake(&m->_m_lock, 1, priv);\n\treturn 0;\n}\n\nweak_alias(__pthread_mutex_unlock, pthread_mutex_unlock);\n"
  },
  {
    "path": "user.libc/src/thread/pthread_mutexattr_destroy.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_mutexattr_destroy(pthread_mutexattr_t *a)\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_mutexattr_init.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_mutexattr_init(pthread_mutexattr_t *a)\n{\n\t*a = (pthread_mutexattr_t){0};\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_mutexattr_setprotocol.c",
    "content": "#include \"pthread_impl.h\"\n#include \"syscall.h\"\n\nstatic volatile int check_pi_result = -1;\n\nint pthread_mutexattr_setprotocol(pthread_mutexattr_t *a, int protocol)\n{\n\tint r;\n\tswitch (protocol) {\n\tcase PTHREAD_PRIO_NONE:\n\t\ta->__attr &= ~8;\n\t\treturn 0;\n\tcase PTHREAD_PRIO_INHERIT:\n\t\tr = check_pi_result;\n\t\tif (r < 0) {\n\t\t\tvolatile int lk = 0;\n\t\t\tr = -__syscall(SYS_futex, &lk, FUTEX_LOCK_PI, 0, 0);\n\t\t\ta_store(&check_pi_result, r);\n\t\t}\n\t\tif (r) return r;\n\t\ta->__attr |= 8;\n\t\treturn 0;\n\tcase PTHREAD_PRIO_PROTECT:\n\t\treturn ENOTSUP;\n\tdefault:\n\t\treturn EINVAL;\n\t}\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_mutexattr_setpshared.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_mutexattr_setpshared(pthread_mutexattr_t *a, int pshared)\n{\n\tif (pshared > 1U) return EINVAL;\n\ta->__attr &= ~128U;\n\ta->__attr |= pshared<<7;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_mutexattr_setrobust.c",
    "content": "#include \"pthread_impl.h\"\n#include \"syscall.h\"\n\nstatic volatile int check_robust_result = -1;\n\nint pthread_mutexattr_setrobust(pthread_mutexattr_t *a, int robust)\n{\n\tif (robust > 1U) return EINVAL;\n\tif (robust) {\n\t\tint r = check_robust_result;\n\t\tif (r < 0) {\n\t\t\tvoid *p;\n\t\t\tsize_t l;\n//\t\t\tr = -__syscall(SYS_get_robust_list, 0, &p, &l);\n\t\t\ta_store(&check_robust_result, r);\n\t\t}\n\t\tif (r) return r;\n\t\ta->__attr |= 4;\n\t\treturn 0;\n\t}\n\ta->__attr &= ~4;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_mutexattr_settype.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_mutexattr_settype(pthread_mutexattr_t *a, int type)\n{\n\tif ((unsigned)type > 2) return EINVAL;\n\ta->__attr = (a->__attr & ~3) | type;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_once.c",
    "content": "#include \"pthread_impl.h\"\n\nstatic void undo(void *control)\n{\n\t/* Wake all waiters, since the waiter status is lost when\n\t * resetting control to the initial state. */\n\tif (a_swap(control, 0) == 3)\n\t\t__wake(control, -1, 1);\n}\n\nhidden int __pthread_once_full(pthread_once_t *control, void (*init)(void))\n{\n\t/* Try to enter initializing state. Four possibilities:\n\t *  0 - we're the first or the other cancelled; run init\n\t *  1 - another thread is running init; wait\n\t *  2 - another thread finished running init; just return\n\t *  3 - another thread is running init, waiters present; wait */\n\n\tfor (;;) switch (a_cas(control, 0, 1)) {\n\tcase 0:\n\t\tpthread_cleanup_push(undo, control);\n\t\tinit();\n\t\tpthread_cleanup_pop(0);\n\n\t\tif (a_swap(control, 2) == 3)\n\t\t\t__wake(control, -1, 1);\n\t\treturn 0;\n\tcase 1:\n\t\t/* If this fails, so will __wait. */\n\t\ta_cas(control, 1, 3);\n\tcase 3:\n\t\t__wait(control, 0, 3, 1);\n\t\tcontinue;\n\tcase 2:\n\t\treturn 0;\n\t}\n}\n\nint __pthread_once(pthread_once_t *control, void (*init)(void))\n{\n\t/* Return immediately if init finished before, but ensure that\n\t * effects of the init routine are visible to the caller. */\n\tif (*(volatile int *)control == 2) {\n\t\ta_barrier();\n\t\treturn 0;\n\t}\n\treturn __pthread_once_full(control, init);\n}\n\nweak_alias(__pthread_once, pthread_once);\n"
  },
  {
    "path": "user.libc/src/thread/pthread_rwlock_destroy.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_rwlock_destroy(pthread_rwlock_t *rw)\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_rwlock_init.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_rwlock_init(pthread_rwlock_t *restrict rw, const pthread_rwlockattr_t *restrict a)\n{\n\t*rw = (pthread_rwlock_t){0};\n\tif (a) rw->_rw_shared = a->__attr[0]*128;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_rwlock_rdlock.c",
    "content": "#include \"pthread_impl.h\"\n\nint __pthread_rwlock_rdlock(pthread_rwlock_t *rw)\n{\n\treturn __pthread_rwlock_timedrdlock(rw, 0);\n}\n\nweak_alias(__pthread_rwlock_rdlock, pthread_rwlock_rdlock);\n"
  },
  {
    "path": "user.libc/src/thread/pthread_rwlock_timedrdlock.c",
    "content": "#include \"pthread_impl.h\"\n\nint __pthread_rwlock_timedrdlock(pthread_rwlock_t *restrict rw, const struct timespec *restrict at)\n{\n\tint r, t;\n\n\tr = pthread_rwlock_tryrdlock(rw);\n\tif (r != EBUSY) return r;\n\t\n\tint spins = 100;\n\twhile (spins-- && rw->_rw_lock && !rw->_rw_waiters) a_spin();\n\n\twhile ((r=__pthread_rwlock_tryrdlock(rw))==EBUSY) {\n\t\tif (!(r=rw->_rw_lock) || (r&0x7fffffff)!=0x7fffffff) continue;\n\t\tt = r | 0x80000000;\n\t\ta_inc(&rw->_rw_waiters);\n\t\ta_cas(&rw->_rw_lock, r, t);\n\t\tr = __timedwait(&rw->_rw_lock, t, CLOCK_REALTIME, at, rw->_rw_shared^128);\n\t\ta_dec(&rw->_rw_waiters);\n\t\tif (r && r != EINTR) return r;\n\t}\n\treturn r;\n}\n\nweak_alias(__pthread_rwlock_timedrdlock, pthread_rwlock_timedrdlock);\n"
  },
  {
    "path": "user.libc/src/thread/pthread_rwlock_timedwrlock.c",
    "content": "#include \"pthread_impl.h\"\n\nint __pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict rw, const struct timespec *restrict at)\n{\n\tint r, t;\n\t\n\tr = pthread_rwlock_trywrlock(rw);\n\tif (r != EBUSY) return r;\n\t\n\tint spins = 100;\n\twhile (spins-- && rw->_rw_lock && !rw->_rw_waiters) a_spin();\n\n\twhile ((r=__pthread_rwlock_trywrlock(rw))==EBUSY) {\n\t\tif (!(r=rw->_rw_lock)) continue;\n\t\tt = r | 0x80000000;\n\t\ta_inc(&rw->_rw_waiters);\n\t\ta_cas(&rw->_rw_lock, r, t);\n\t\tr = __timedwait(&rw->_rw_lock, t, CLOCK_REALTIME, at, rw->_rw_shared^128);\n\t\ta_dec(&rw->_rw_waiters);\n\t\tif (r && r != EINTR) return r;\n\t}\n\treturn r;\n}\n\nweak_alias(__pthread_rwlock_timedwrlock, pthread_rwlock_timedwrlock);\n"
  },
  {
    "path": "user.libc/src/thread/pthread_rwlock_tryrdlock.c",
    "content": "#include \"pthread_impl.h\"\n\nint __pthread_rwlock_tryrdlock(pthread_rwlock_t *rw)\n{\n\tint val, cnt;\n\tdo {\n\t\tval = rw->_rw_lock;\n\t\tcnt = val & 0x7fffffff;\n\t\tif (cnt == 0x7fffffff) return EBUSY;\n\t\tif (cnt == 0x7ffffffe) return EAGAIN;\n\t} while (a_cas(&rw->_rw_lock, val, val+1) != val);\n\treturn 0;\n}\n\nweak_alias(__pthread_rwlock_tryrdlock, pthread_rwlock_tryrdlock);\n"
  },
  {
    "path": "user.libc/src/thread/pthread_rwlock_trywrlock.c",
    "content": "#include \"pthread_impl.h\"\n\nint __pthread_rwlock_trywrlock(pthread_rwlock_t *rw)\n{\n\tif (a_cas(&rw->_rw_lock, 0, 0x7fffffff)) return EBUSY;\n\treturn 0;\n}\n\nweak_alias(__pthread_rwlock_trywrlock, pthread_rwlock_trywrlock);\n"
  },
  {
    "path": "user.libc/src/thread/pthread_rwlock_unlock.c",
    "content": "#include \"pthread_impl.h\"\n\nint __pthread_rwlock_unlock(pthread_rwlock_t *rw)\n{\n\tint val, cnt, waiters, new, priv = rw->_rw_shared^128;\n\n\tdo {\n\t\tval = rw->_rw_lock;\n\t\tcnt = val & 0x7fffffff;\n\t\twaiters = rw->_rw_waiters;\n\t\tnew = (cnt == 0x7fffffff || cnt == 1) ? 0 : val-1;\n\t} while (a_cas(&rw->_rw_lock, val, new) != val);\n\n\tif (!new && (waiters || val<0))\n\t\t__wake(&rw->_rw_lock, cnt, priv);\n\n\treturn 0;\n}\n\nweak_alias(__pthread_rwlock_unlock, pthread_rwlock_unlock);\n"
  },
  {
    "path": "user.libc/src/thread/pthread_rwlock_wrlock.c",
    "content": "#include \"pthread_impl.h\"\n\nint __pthread_rwlock_wrlock(pthread_rwlock_t *rw)\n{\n\treturn __pthread_rwlock_timedwrlock(rw, 0);\n}\n\nweak_alias(__pthread_rwlock_wrlock, pthread_rwlock_wrlock);\n"
  },
  {
    "path": "user.libc/src/thread/pthread_rwlockattr_destroy.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_rwlockattr_destroy(pthread_rwlockattr_t *a)\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_rwlockattr_init.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_rwlockattr_init(pthread_rwlockattr_t *a)\n{\n\t*a = (pthread_rwlockattr_t){0};\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_rwlockattr_setpshared.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_rwlockattr_setpshared(pthread_rwlockattr_t *a, int pshared)\n{\n\tif (pshared > 1U) return EINVAL;\n\ta->__attr[0] = pshared;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_self.c",
    "content": "#include \"pthread_impl.h\"\n#include <threads.h>\n\nstatic pthread_t __pthread_self_internal()\n{\n\treturn __pthread_self();\n}\n\nweak_alias(__pthread_self_internal, pthread_self);\nweak_alias(__pthread_self_internal, thrd_current);\n"
  },
  {
    "path": "user.libc/src/thread/pthread_setattr_default_np.c",
    "content": "#define _GNU_SOURCE\n#include \"pthread_impl.h\"\n#include <string.h>\n\n#define MIN(a,b) ((a)<(b) ? (a) : (b))\n#define MAX(a,b) ((a)>(b) ? (a) : (b))\n\nint pthread_setattr_default_np(const pthread_attr_t *attrp)\n{\n\t/* Reject anything in the attr object other than stack/guard size. */\n\tpthread_attr_t tmp = *attrp, zero = { 0 };\n\ttmp._a_stacksize = 0;\n\ttmp._a_guardsize = 0;\n\tif (memcmp(&tmp, &zero, sizeof tmp))\n\t\treturn EINVAL;\n\n\tunsigned stack = MIN(attrp->_a_stacksize, DEFAULT_STACK_MAX);\n\tunsigned guard = MIN(attrp->_a_guardsize, DEFAULT_GUARD_MAX);\n\n\t__inhibit_ptc();\n\t__default_stacksize = MAX(__default_stacksize, stack);\n\t__default_guardsize = MAX(__default_guardsize, guard);\n\t__release_ptc();\n\n\treturn 0;\n}\n\nint pthread_getattr_default_np(pthread_attr_t *attrp)\n{\n\t__acquire_ptc();\n\t*attrp = (pthread_attr_t) {\n\t\t._a_stacksize = __default_stacksize,\n\t\t._a_guardsize = __default_guardsize,\n\t};\n\t__release_ptc();\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_setcancelstate.c",
    "content": "#include \"pthread_impl.h\"\n\nint __pthread_setcancelstate(int new, int *old)\n{\n\tif (new > 2U) return EINVAL;\n\tstruct pthread *self = __pthread_self();\n\tif (old) *old = self->canceldisable;\n\tself->canceldisable = new;\n\treturn 0;\n}\n\nweak_alias(__pthread_setcancelstate, pthread_setcancelstate);\n"
  },
  {
    "path": "user.libc/src/thread/pthread_setcanceltype.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_setcanceltype(int new, int *old)\n{\n\tstruct pthread *self = __pthread_self();\n\tif (new > 1U) return EINVAL;\n\tif (old) *old = self->cancelasync;\n\tself->cancelasync = new;\n\tif (new) pthread_testcancel();\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_setconcurrency.c",
    "content": "#include <pthread.h>\n#include <errno.h>\n\nint pthread_setconcurrency(int val)\n{\n\tif (val < 0) return EINVAL;\n\tif (val > 0) return EAGAIN;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_setname_np.c",
    "content": "#define _GNU_SOURCE\n#include <fcntl.h>\n#include <string.h>\n#include <unistd.h>\n#include <sys/prctl.h>\n\n#include \"pthread_impl.h\"\n\nint pthread_setname_np(pthread_t thread, const char *name)\n{\n\tint fd, cs, status = 0;\n\tchar f[sizeof \"/proc/self/task//comm\" + 3*sizeof(int)];\n\tsize_t len;\n\n\tif ((len = strnlen(name, 16)) > 15) return ERANGE;\n\n\tif (thread == pthread_self())\n\t\treturn prctl(PR_SET_NAME, (unsigned long)name, 0UL, 0UL, 0UL) ? errno : 0;\n\n\tsnprintf(f, sizeof f, \"/proc/self/task/%d/comm\", thread->tid);\n\tpthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);\n\tif ((fd = open(f, O_WRONLY)) < 0 || write(fd, name, len) < 0) status = errno;\n\tif (fd >= 0) close(fd);\n\tpthread_setcancelstate(cs, 0);\n\treturn status;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_setschedparam.c",
    "content": "#include \"pthread_impl.h\"\n#include \"lock.h\"\n\nint pthread_setschedparam(pthread_t t, int policy, const struct sched_param *param)\n{\n\tint r;\n\tsigset_t set;\n\t__block_app_sigs(&set);\n\tLOCK(t->killlock);\n//\tr = !t->tid ? ESRCH : -__syscall(SYS_sched_setscheduler, t->tid, policy, param);\n\tUNLOCK(t->killlock);\n\t__restore_sigs(&set);\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_setschedprio.c",
    "content": "#include \"pthread_impl.h\"\n#include \"lock.h\"\n\nint pthread_setschedprio(pthread_t t, int prio)\n{\n\tint r;\n\tsigset_t set;\n\t__block_app_sigs(&set);\n\tLOCK(t->killlock);\n//\tr = !t->tid ? ESRCH : -__syscall(SYS_sched_setparam, t->tid, &prio);\n\tUNLOCK(t->killlock);\n\t__restore_sigs(&set);\n\treturn r;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_setspecific.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_setspecific(pthread_key_t k, const void *x)\n{\n\tstruct pthread *self = __pthread_self();\n\t/* Avoid unnecessary COW */\n\tif (self->tsd[k] != x) {\n\t\tself->tsd[k] = (void *)x;\n\t\tself->tsd_used = 1;\n\t}\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_sigmask.c",
    "content": "#include <signal.h>\n#include <errno.h>\n#include \"syscall.h\"\n\nint pthread_sigmask(int how, const sigset_t *restrict set, sigset_t *restrict old)\n{\n#if 0\n\tint ret;\n\tif (set && (unsigned)how - SIG_BLOCK > 2U) return EINVAL;\n\tret = -__syscall(SYS_rt_sigprocmask, how, set, old, _NSIG/8);\n\tif (!ret && old) {\n\t\tif (sizeof old->__bits[0] == 8) {\n\t\t\told->__bits[0] &= ~0x380000000ULL;\n\t\t} else {\n\t\t\told->__bits[0] &= ~0x80000000UL;\n\t\t\told->__bits[1] &= ~0x3UL;\n\t\t}\n\t}\n\treturn ret;\n#endif\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_spin_destroy.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_spin_destroy(pthread_spinlock_t *s)\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_spin_init.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_spin_init(pthread_spinlock_t *s, int shared)\n{\n\treturn *s = 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_spin_lock.c",
    "content": "#include \"pthread_impl.h\"\n#include <errno.h>\n\nint pthread_spin_lock(pthread_spinlock_t *s)\n{\n\twhile (*(volatile int *)s || a_cas(s, 0, EBUSY)) a_spin();\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_spin_trylock.c",
    "content": "#include \"pthread_impl.h\"\n#include <errno.h>\n\nint pthread_spin_trylock(pthread_spinlock_t *s)\n{\n\treturn a_cas(s, 0, EBUSY);\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_spin_unlock.c",
    "content": "#include \"pthread_impl.h\"\n\nint pthread_spin_unlock(pthread_spinlock_t *s)\n{\n\ta_store(s, 0);\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/pthread_testcancel.c",
    "content": "#include \"pthread_impl.h\"\n\nstatic void dummy()\n{\n}\n\nweak_alias(dummy, __testcancel);\n\nvoid __pthread_testcancel()\n{\n\t__testcancel();\n}\n\nweak_alias(__pthread_testcancel, pthread_testcancel);\n"
  },
  {
    "path": "user.libc/src/thread/sem_destroy.c",
    "content": "#include <semaphore.h>\n\nint sem_destroy(sem_t *sem)\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/sem_getvalue.c",
    "content": "#include <semaphore.h>\n\nint sem_getvalue(sem_t *restrict sem, int *restrict valp)\n{\n\tint val = sem->__val[0];\n\t*valp = val < 0 ? 0 : val;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/sem_init.c",
    "content": "#include <semaphore.h>\n#include <limits.h>\n#include <errno.h>\n\nint sem_init(sem_t *sem, int pshared, unsigned value)\n{\n\tif (value > SEM_VALUE_MAX) {\n\t\terrno = EINVAL;\n\t\treturn -1;\n\t}\n\tsem->__val[0] = value;\n\tsem->__val[1] = 0;\n\tsem->__val[2] = pshared ? 0 : 128;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/sem_open.c",
    "content": "#include <semaphore.h>\n#include <sys/mman.h>\n#include <limits.h>\n#include <fcntl.h>\n#include <unistd.h>\n#include <string.h>\n#include <stdarg.h>\n#include <errno.h>\n#include <time.h>\n#include <stdio.h>\n#include <sys/stat.h>\n#include <stdlib.h>\n#include <pthread.h>\n#include \"lock.h\"\n#include \"fork_impl.h\"\n\n#define malloc __libc_malloc\n#define calloc __libc_calloc\n#define realloc undef\n#define free undef\n\nstatic struct {\n\tino_t ino;\n\tsem_t *sem;\n\tint refcnt;\n} *semtab;\nstatic volatile int lock[1];\nvolatile int *const __sem_open_lockptr = lock;\n\n#define FLAGS (O_RDWR|O_NOFOLLOW|O_CLOEXEC|O_NONBLOCK)\n\nsem_t *sem_open(const char *name, int flags, ...)\n{\n\tva_list ap;\n\tmode_t mode;\n\tunsigned value;\n\tint fd, i, e, slot, first=1, cnt, cs;\n\tsem_t newsem;\n\tvoid *map;\n\tchar tmp[64];\n\tstruct timespec ts;\n\tstruct stat st;\n\tchar buf[NAME_MAX+10];\n\n\tif (!(name = __shm_mapname(name, buf)))\n\t\treturn SEM_FAILED;\n\n\tLOCK(lock);\n\t/* Allocate table if we don't have one yet */\n\tif (!semtab && !(semtab = calloc(sizeof *semtab, SEM_NSEMS_MAX))) {\n\t\tUNLOCK(lock);\n\t\treturn SEM_FAILED;\n\t}\n\n\t/* Reserve a slot in case this semaphore is not mapped yet;\n\t * this is necessary because there is no way to handle\n\t * failures after creation of the file. */\n\tslot = -1;\n\tfor (cnt=i=0; i<SEM_NSEMS_MAX; i++) {\n\t\tcnt += semtab[i].refcnt;\n\t\tif (!semtab[i].sem && slot < 0) slot = i;\n\t}\n\t/* Avoid possibility of overflow later */\n\tif (cnt == INT_MAX || slot < 0) {\n\t\terrno = EMFILE;\n\t\tUNLOCK(lock);\n\t\treturn SEM_FAILED;\n\t}\n\t/* Dummy pointer to make a reservation */\n\tsemtab[slot].sem = (sem_t *)-1;\n\tUNLOCK(lock);\n\n\tflags &= (O_CREAT|O_EXCL);\n\n\tpthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);\n\n\t/* Early failure check for exclusive open; otherwise the case\n\t * where the semaphore already exists is expensive. */\n\tif (flags == (O_CREAT|O_EXCL) && access(name, F_OK) == 0) {\n\t\terrno = EEXIST;\n\t\tgoto fail;\n\t}\n\n\tfor (;;) {\n\t\t/* If exclusive mode is not requested, try opening an\n\t\t * existing file first and fall back to creation. */\n\t\tif (flags != (O_CREAT|O_EXCL)) {\n\t\t\tfd = open(name, FLAGS);\n\t\t\tif (fd >= 0) {\n\t\t\t\tif (fstat(fd, &st) < 0 ||\n\t\t\t\t    (map = mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) {\n\t\t\t\t\tclose(fd);\n\t\t\t\t\tgoto fail;\n\t\t\t\t}\n\t\t\t\tclose(fd);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (errno != ENOENT)\n\t\t\t\tgoto fail;\n\t\t}\n\t\tif (!(flags & O_CREAT))\n\t\t\tgoto fail;\n\t\tif (first) {\n\t\t\tfirst = 0;\n\t\t\tva_start(ap, flags);\n\t\t\tmode = va_arg(ap, mode_t) & 0666;\n\t\t\tvalue = va_arg(ap, unsigned);\n\t\t\tva_end(ap);\n\t\t\tif (value > SEM_VALUE_MAX) {\n\t\t\t\terrno = EINVAL;\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tsem_init(&newsem, 1, value);\n\t\t}\n\t\t/* Create a temp file with the new semaphore contents\n\t\t * and attempt to atomically link it as the new name */\n\t\tclock_gettime(CLOCK_REALTIME, &ts);\n\t\tsnprintf(tmp, sizeof(tmp), \"/dev/shm/tmp-%d\", (int)ts.tv_nsec);\n\t\tfd = open(tmp, O_CREAT|O_EXCL|FLAGS, mode);\n\t\tif (fd < 0) {\n\t\t\tif (errno == EEXIST) continue;\n\t\t\tgoto fail;\n\t\t}\n\t\tif (write(fd, &newsem, sizeof newsem) != sizeof newsem || fstat(fd, &st) < 0 ||\n\t\t    (map = mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) {\n\t\t\tclose(fd);\n\t\t\tunlink(tmp);\n\t\t\tgoto fail;\n\t\t}\n\t\tclose(fd);\n\t\te = link(tmp, name) ? errno : 0;\n\t\tunlink(tmp);\n\t\tif (!e) break;\n\t\tmunmap(map, sizeof(sem_t));\n\t\t/* Failure is only fatal when doing an exclusive open;\n\t\t * otherwise, next iteration will try to open the\n\t\t * existing file. */\n\t\tif (e != EEXIST || flags == (O_CREAT|O_EXCL))\n\t\t\tgoto fail;\n\t}\n\n\t/* See if the newly mapped semaphore is already mapped. If\n\t * so, unmap the new mapping and use the existing one. Otherwise,\n\t * add it to the table of mapped semaphores. */\n\tLOCK(lock);\n\tfor (i=0; i<SEM_NSEMS_MAX && semtab[i].ino != st.st_ino; i++);\n\tif (i<SEM_NSEMS_MAX) {\n\t\tmunmap(map, sizeof(sem_t));\n\t\tsemtab[slot].sem = 0;\n\t\tslot = i;\n\t\tmap = semtab[i].sem;\n\t}\n\tsemtab[slot].refcnt++;\n\tsemtab[slot].sem = map;\n\tsemtab[slot].ino = st.st_ino;\n\tUNLOCK(lock);\n\tpthread_setcancelstate(cs, 0);\n\treturn map;\n\nfail:\n\tpthread_setcancelstate(cs, 0);\n\tLOCK(lock);\n\tsemtab[slot].sem = 0;\n\tUNLOCK(lock);\n\treturn SEM_FAILED;\n}\n\nint sem_close(sem_t *sem)\n{\n\tint i;\n\tLOCK(lock);\n\tfor (i=0; i<SEM_NSEMS_MAX && semtab[i].sem != sem; i++);\n\tif (--semtab[i].refcnt) {\n\t\tUNLOCK(lock);\n\t\treturn 0;\n\t}\n\tsemtab[i].sem = 0;\n\tsemtab[i].ino = 0;\n\tUNLOCK(lock);\n\tmunmap(sem, sizeof *sem);\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/sem_post.c",
    "content": "#include <semaphore.h>\n#include \"pthread_impl.h\"\n\nint sem_post(sem_t *sem)\n{\n\tint val, waiters, priv = sem->__val[2];\n\tdo {\n\t\tval = sem->__val[0];\n\t\twaiters = sem->__val[1];\n\t\tif (val == SEM_VALUE_MAX) {\n\t\t\terrno = EOVERFLOW;\n\t\t\treturn -1;\n\t\t}\n\t} while (a_cas(sem->__val, val, val+1+(val<0)) != val);\n\tif (val<0 || waiters) __wake(sem->__val, 1, priv);\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/sem_timedwait.c",
    "content": "#include <semaphore.h>\n#include \"pthread_impl.h\"\n\nstatic void cleanup(void *p)\n{\n\ta_dec(p);\n}\n\nint sem_timedwait(sem_t *restrict sem, const struct timespec *restrict at)\n{\n\tpthread_testcancel();\n\n\tif (!sem_trywait(sem)) return 0;\n\n\tint spins = 100;\n\twhile (spins-- && sem->__val[0] <= 0 && !sem->__val[1]) a_spin();\n\n\twhile (sem_trywait(sem)) {\n\t\tint r;\n\t\ta_inc(sem->__val+1);\n\t\ta_cas(sem->__val, 0, -1);\n\t\tpthread_cleanup_push(cleanup, (void *)(sem->__val+1));\n\t\tr = __timedwait_cp(sem->__val, -1, CLOCK_REALTIME, at, sem->__val[2]);\n\t\tpthread_cleanup_pop(1);\n\t\tif (r) {\n\t\t\terrno = r;\n\t\t\treturn -1;\n\t\t}\n\t}\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/sem_trywait.c",
    "content": "#include <semaphore.h>\n#include \"pthread_impl.h\"\n\nint sem_trywait(sem_t *sem)\n{\n\tint val;\n\twhile ((val=sem->__val[0]) > 0) {\n\t\tint new = val-1-(val==1 && sem->__val[1]);\n\t\tif (a_cas(sem->__val, val, new)==val) return 0;\n\t}\n\terrno = EAGAIN;\n\treturn -1;\n}\n"
  },
  {
    "path": "user.libc/src/thread/sem_unlink.c",
    "content": "#include <semaphore.h>\n#include <sys/mman.h>\n\nint sem_unlink(const char *name)\n{\n\treturn shm_unlink(name);\n}\n"
  },
  {
    "path": "user.libc/src/thread/sem_wait.c",
    "content": "#include <semaphore.h>\n\nint sem_wait(sem_t *sem)\n{\n\treturn sem_timedwait(sem, 0);\n}\n"
  },
  {
    "path": "user.libc/src/thread/sh/__set_thread_area.c",
    "content": "#include \"pthread_impl.h\"\n#include \"libc.h\"\n#include <elf.h>\n\n/* Also perform sh-specific init */\n\n#define CPU_HAS_LLSC 0x0040\n#define CPU_HAS_CAS_L 0x0400\n\nextern hidden const char __sh_cas_gusa[], __sh_cas_llsc[], __sh_cas_imask[], __sh_cas_cas_l[];\n\nhidden const void *__sh_cas_ptr;\n\nhidden unsigned __sh_nommu;\n\nint __set_thread_area(void *p)\n{\n\tsize_t *aux;\n\t__asm__ __volatile__ ( \"ldc %0, gbr\" : : \"r\"(p) : \"memory\" );\n#ifndef __SH4A__\n\t__sh_cas_ptr = __sh_cas_gusa;\n#if !defined(__SH3__) && !defined(__SH4__)\n\tfor (aux=libc.auxv; *aux; aux+=2) {\n\t\tif (*aux != AT_PLATFORM) continue;\n\t\tconst char *s = (void *)aux[1];\n\t\tif (s[0]!='s' || s[1]!='h' || s[2]!='2' || s[3]-'0'<10u) break;\n\t\t__sh_cas_ptr = __sh_cas_imask;\n\t\t__sh_nommu = 1;\n\t}\n#endif\n\tif (__hwcap & CPU_HAS_CAS_L)\n\t\t__sh_cas_ptr = __sh_cas_cas_l;\n\telse if (__hwcap & CPU_HAS_LLSC)\n\t\t__sh_cas_ptr = __sh_cas_llsc;\n#endif\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/thread/sh/__unmapself.c",
    "content": "#include \"pthread_impl.h\"\n\nhidden void __unmapself_sh_mmu(void *, size_t);\nhidden void __unmapself_sh_nommu(void *, size_t);\n\n#if !defined(__SH3__) && !defined(__SH4__)\n#define __unmapself __unmapself_sh_nommu\n#include \"dynlink.h\"\n#undef CRTJMP\n#define CRTJMP(pc,sp) __asm__ __volatile__( \\\n\t\"mov.l @%0+,r0 ; mov.l @%0,r12 ; jmp @r0 ; mov %1,r15\" \\\n\t: : \"r\"(pc), \"r\"(sp) : \"r0\", \"memory\" )\n#include \"../__unmapself.c\"\n#undef __unmapself\nextern hidden unsigned __sh_nommu;\n#else\n#define __sh_nommu 0\n#endif\n\nvoid __unmapself(void *base, size_t size)\n{\n\tif (__sh_nommu) __unmapself_sh_nommu(base, size);\n\telse __unmapself_sh_mmu(base, size);\n}\n"
  },
  {
    "path": "user.libc/src/thread/synccall.c",
    "content": "#include \"pthread_impl.h\"\n#include <semaphore.h>\n#include <string.h>\n\nstatic void dummy_0(void)\n{\n}\n\nweak_alias(dummy_0, __tl_lock);\nweak_alias(dummy_0, __tl_unlock);\n\nstatic int target_tid;\nstatic void (*callback)(void *), *context;\nstatic sem_t target_sem, caller_sem;\n\nstatic void dummy(void *p)\n{\n}\n\nstatic void handler(int sig)\n{\n\tif (__pthread_self()->tid != target_tid) return;\n\n\tint old_errno = errno;\n\n\t/* Inform caller we have received signal and wait for\n\t * the caller to let us make the callback. */\n\tsem_post(&caller_sem);\n\tsem_wait(&target_sem);\n\n\tcallback(context);\n\n\t/* Inform caller we've complered the callback and wait\n\t * for the caller to release us to return. */\n\tsem_post(&caller_sem);\n\tsem_wait(&target_sem);\n\n\t/* Inform caller we are returning and state is destroyable. */\n\tsem_post(&caller_sem);\n\n\terrno = old_errno;\n}\n\nvoid __synccall(void (*func)(void *), void *ctx)\n{\n\tsigset_t oldmask;\n\tint cs, i, r;\n\tstruct sigaction sa = { .sa_flags = SA_RESTART, .sa_handler = handler };\n\tpthread_t self = __pthread_self(), td;\n\tint count = 0;\n\n\t/* Blocking signals in two steps, first only app-level signals\n\t * before taking the lock, then all signals after taking the lock,\n\t * is necessary to achieve AS-safety. Blocking them all first would\n\t * deadlock if multiple threads called __synccall. Waiting to block\n\t * any until after the lock would allow re-entry in the same thread\n\t * with the lock already held. */\n\t__block_app_sigs(&oldmask);\n\t__tl_lock();\n\t__block_all_sigs(0);\n\tpthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);\n\n\tsem_init(&target_sem, 0, 0);\n\tsem_init(&caller_sem, 0, 0);\n\n\t// if (!libc.threads_minus_1 || __syscall(SYS_gettid) != self->tid)\n\t// \tgoto single_threaded;\n\n\tcallback = func;\n\tcontext = ctx;\n\n\t/* Block even implementation-internal signals, so that nothing\n\t * interrupts the SIGSYNCCALL handlers. The main possible source\n\t * of trouble is asynchronous cancellation. */\n\tmemset(&sa.sa_mask, -1, sizeof sa.sa_mask);\n\t__libc_sigaction(SIGSYNCCALL, &sa, 0);\n\n\n\tfor (td=self->next; td!=self; td=td->next) {\n\t\ttarget_tid = td->tid;\n\t\t// while ((r = -__syscall(SYS_tkill, td->tid, SIGSYNCCALL)) == EAGAIN);\n\t\tif (r) {\n\t\t\t/* If we failed to signal any thread, nop out the\n\t\t\t * callback to abort the synccall and just release\n\t\t\t * any threads already caught. */\n\t\t\tcallback = func = dummy;\n\t\t\tbreak;\n\t\t}\n\t\tsem_wait(&caller_sem);\n\t\tcount++;\n\t}\n\ttarget_tid = 0;\n\n\t/* Serialize execution of callback in caught threads, or just\n\t * release them all if synccall is being aborted. */\n\tfor (i=0; i<count; i++) {\n\t\tsem_post(&target_sem);\n\t\tsem_wait(&caller_sem);\n\t}\n\n\tsa.sa_handler = SIG_IGN;\n\t__libc_sigaction(SIGSYNCCALL, &sa, 0);\n\nsingle_threaded:\n\tfunc(ctx);\n\n\t/* Only release the caught threads once all threads, including the\n\t * caller, have returned from the callback function. */\n\tfor (i=0; i<count; i++)\n\t\tsem_post(&target_sem);\n\tfor (i=0; i<count; i++)\n\t\tsem_wait(&caller_sem);\n\n\tsem_destroy(&caller_sem);\n\tsem_destroy(&target_sem);\n\n\tpthread_setcancelstate(cs, 0);\n\t__tl_unlock();\n\t__restore_sigs(&oldmask);\n}\n"
  },
  {
    "path": "user.libc/src/thread/syscall_cp.c",
    "content": ""
  },
  {
    "path": "user.libc/src/thread/thrd_create.c",
    "content": "#include \"pthread_impl.h\"\n#include <threads.h>\n\nint thrd_create(thrd_t *thr, thrd_start_t func, void *arg)\n{\n\tint ret = __pthread_create(thr, __ATTRP_C11_THREAD, (void *(*)(void *))func, arg);\n\tswitch (ret) {\n\tcase 0:      return thrd_success;\n\tcase EAGAIN: return thrd_nomem;\n\tdefault:     return thrd_error;\n\t}\n}\n"
  },
  {
    "path": "user.libc/src/thread/thrd_exit.c",
    "content": "#include <threads.h>\n#include <pthread.h>\n#include <stdint.h>\n\n_Noreturn void thrd_exit(int result)\n{\n\t__pthread_exit((void*)(intptr_t)result);\n}\n"
  },
  {
    "path": "user.libc/src/thread/thrd_join.c",
    "content": "#include <stdint.h>\n#include <threads.h>\n#include <pthread.h>\n\nint thrd_join(thrd_t t, int *res)\n{\n        void *pthread_res;\n        __pthread_join(t, &pthread_res);\n        if (res) *res = (int)(intptr_t)pthread_res;\n        return thrd_success;\n}\n"
  },
  {
    "path": "user.libc/src/thread/thrd_sleep.c",
    "content": "#include <threads.h>\n#include <time.h>\n#include <errno.h>\n#include \"syscall.h\"\n\nint thrd_sleep(const struct timespec *req, struct timespec *rem)\n{\n\tint ret = -__clock_nanosleep(CLOCK_REALTIME, 0, req, rem);\n\tswitch (ret) {\n\tcase 0:      return 0;\n\tcase -EINTR: return -1; /* value specified by C11 */\n\tdefault:     return -2;\n\t}\n}\n"
  },
  {
    "path": "user.libc/src/thread/thrd_yield.c",
    "content": "#include <threads.h>\n#include \"syscall.h\"\n\nvoid thrd_yield()\n{\n//\t__syscall(SYS_sched_yield);\n}\n"
  },
  {
    "path": "user.libc/src/thread/tls.c",
    "content": ""
  },
  {
    "path": "user.libc/src/thread/tss_create.c",
    "content": "#include <threads.h>\n#include <pthread.h>\n\nint tss_create(tss_t *tss, tss_dtor_t dtor)\n{\n\t/* Different error returns are possible. C glues them together into\n\t * just failure notification. Can't be optimized to a tail call,\n\t * unless thrd_error equals EAGAIN. */\n\treturn __pthread_key_create(tss, dtor) ? thrd_error : thrd_success;\n}\n"
  },
  {
    "path": "user.libc/src/thread/tss_delete.c",
    "content": "#include <threads.h>\n#include <pthread.h>\n\nvoid tss_delete(tss_t key)\n{\n\t__pthread_key_delete(key);\n}\n"
  },
  {
    "path": "user.libc/src/thread/tss_set.c",
    "content": "#include \"pthread_impl.h\"\n#include <threads.h>\n\nint tss_set(tss_t k, void *x)\n{\n\tstruct pthread *self = __pthread_self();\n\t/* Avoid unnecessary COW */\n\tif (self->tsd[k] != x) {\n\t\tself->tsd[k] = x;\n\t\tself->tsd_used = 1;\n\t}\n\treturn thrd_success;\n}\n"
  },
  {
    "path": "user.libc/src/thread/vmlock.c",
    "content": "#include \"pthread_impl.h\"\n#include \"fork_impl.h\"\n\nstatic volatile int vmlock[2];\nvolatile int *const __vmlock_lockptr = vmlock;\n\nvoid __vm_wait()\n{\n\tint tmp;\n\twhile ((tmp=vmlock[0]))\n\t\t__wait(vmlock, vmlock+1, tmp, 1);\n}\n\nvoid __vm_lock()\n{\n\ta_inc(vmlock);\n}\n\nvoid __vm_unlock()\n{\n\tif (a_fetch_add(vmlock, -1)==1 && vmlock[1])\n\t\t__wake(vmlock, -1, 1);\n}\n"
  },
  {
    "path": "user.libc/src/time/__month_to_secs.c",
    "content": "int __month_to_secs(int month, int is_leap)\n{\n\tstatic const int secs_through_month[] = {\n\t\t0, 31*86400, 59*86400, 90*86400,\n\t\t120*86400, 151*86400, 181*86400, 212*86400,\n\t\t243*86400, 273*86400, 304*86400, 334*86400 };\n\tint t = secs_through_month[month];\n\tif (is_leap && month >= 2) t+=86400;\n\treturn t;\n}\n"
  },
  {
    "path": "user.libc/src/time/__secs_to_tm.c",
    "content": "#include \"time_impl.h\"\n#include <limits.h>\n\n/* 2000-03-01 (mod 400 year, immediately after feb29 */\n#define LEAPOCH (946684800LL + 86400*(31+29))\n\n#define DAYS_PER_400Y (365*400 + 97)\n#define DAYS_PER_100Y (365*100 + 24)\n#define DAYS_PER_4Y   (365*4   + 1)\n\nint __secs_to_tm(long long t, struct tm *tm)\n{\n\tlong long days, secs, years;\n\tint remdays, remsecs, remyears;\n\tint qc_cycles, c_cycles, q_cycles;\n\tint months;\n\tint wday, yday, leap;\n\tstatic const char days_in_month[] = {31,30,31,30,31,31,30,31,30,31,31,29};\n\n\t/* Reject time_t values whose year would overflow int */\n\tif (t < INT_MIN * 31622400LL || t > INT_MAX * 31622400LL)\n\t\treturn -1;\n\n\tsecs = t - LEAPOCH;\n\tdays = secs / 86400;\n\tremsecs = secs % 86400;\n\tif (remsecs < 0) {\n\t\tremsecs += 86400;\n\t\tdays--;\n\t}\n\n\twday = (3+days)%7;\n\tif (wday < 0) wday += 7;\n\n\tqc_cycles = days / DAYS_PER_400Y;\n\tremdays = days % DAYS_PER_400Y;\n\tif (remdays < 0) {\n\t\tremdays += DAYS_PER_400Y;\n\t\tqc_cycles--;\n\t}\n\n\tc_cycles = remdays / DAYS_PER_100Y;\n\tif (c_cycles == 4) c_cycles--;\n\tremdays -= c_cycles * DAYS_PER_100Y;\n\n\tq_cycles = remdays / DAYS_PER_4Y;\n\tif (q_cycles == 25) q_cycles--;\n\tremdays -= q_cycles * DAYS_PER_4Y;\n\n\tremyears = remdays / 365;\n\tif (remyears == 4) remyears--;\n\tremdays -= remyears * 365;\n\n\tleap = !remyears && (q_cycles || !c_cycles);\n\tyday = remdays + 31 + 28 + leap;\n\tif (yday >= 365+leap) yday -= 365+leap;\n\n\tyears = remyears + 4*q_cycles + 100*c_cycles + 400LL*qc_cycles;\n\n\tfor (months=0; days_in_month[months] <= remdays; months++)\n\t\tremdays -= days_in_month[months];\n\n\tif (months >= 10) {\n\t\tmonths -= 12;\n\t\tyears++;\n\t}\n\n\tif (years+100 > INT_MAX || years+100 < INT_MIN)\n\t\treturn -1;\n\n\ttm->tm_year = years + 100;\n\ttm->tm_mon = months + 2;\n\ttm->tm_mday = remdays + 1;\n\ttm->tm_wday = wday;\n\ttm->tm_yday = yday;\n\n\ttm->tm_hour = remsecs / 3600;\n\ttm->tm_min = remsecs / 60 % 60;\n\ttm->tm_sec = remsecs % 60;\n\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/time/__tm_to_secs.c",
    "content": "#include \"time_impl.h\"\n\nlong long __tm_to_secs(const struct tm *tm)\n{\n\tint is_leap;\n\tlong long year = tm->tm_year;\n\tint month = tm->tm_mon;\n\tif (month >= 12 || month < 0) {\n\t\tint adj = month / 12;\n\t\tmonth %= 12;\n\t\tif (month < 0) {\n\t\t\tadj--;\n\t\t\tmonth += 12;\n\t\t}\n\t\tyear += adj;\n\t}\n\tlong long t = __year_to_secs(year, &is_leap);\n\tt += __month_to_secs(month, is_leap);\n\tt += 86400LL * (tm->tm_mday-1);\n\tt += 3600LL * tm->tm_hour;\n\tt += 60LL * tm->tm_min;\n\tt += tm->tm_sec;\n\treturn t;\n}\n"
  },
  {
    "path": "user.libc/src/time/__year_to_secs.c",
    "content": "long long __year_to_secs(long long year, int *is_leap)\n{\n\tif (year-2ULL <= 136) {\n\t\tint y = year;\n\t\tint leaps = (y-68)>>2;\n\t\tif (!((y-68)&3)) {\n\t\t\tleaps--;\n\t\t\tif (is_leap) *is_leap = 1;\n\t\t} else if (is_leap) *is_leap = 0;\n\t\treturn 31536000*(y-70) + 86400*leaps;\n\t}\n\n\tint cycles, centuries, leaps, rem;\n\n\tif (!is_leap) is_leap = &(int){0};\n\tcycles = (year-100) / 400;\n\trem = (year-100) % 400;\n\tif (rem < 0) {\n\t\tcycles--;\n\t\trem += 400;\n\t}\n\tif (!rem) {\n\t\t*is_leap = 1;\n\t\tcenturies = 0;\n\t\tleaps = 0;\n\t} else {\n\t\tif (rem >= 200) {\n\t\t\tif (rem >= 300) centuries = 3, rem -= 300;\n\t\t\telse centuries = 2, rem -= 200;\n\t\t} else {\n\t\t\tif (rem >= 100) centuries = 1, rem -= 100;\n\t\t\telse centuries = 0;\n\t\t}\n\t\tif (!rem) {\n\t\t\t*is_leap = 0;\n\t\t\tleaps = 0;\n\t\t} else {\n\t\t\tleaps = rem / 4U;\n\t\t\trem %= 4U;\n\t\t\t*is_leap = !rem;\n\t\t}\n\t}\n\n\tleaps += 97*cycles + 24*centuries - *is_leap;\n\n\treturn (year-100) * 31536000LL + leaps * 86400LL + 946684800 + 86400;\n}\n"
  },
  {
    "path": "user.libc/src/time/asctime.c",
    "content": "#include <time.h>\n\nchar *asctime(const struct tm *tm)\n{\n\tstatic char buf[26];\n\treturn __asctime_r(tm, buf);\n}\n"
  },
  {
    "path": "user.libc/src/time/asctime_r.c",
    "content": "#include <time.h>\n#include <stdio.h>\n#include <langinfo.h>\n#include \"locale_impl.h\"\n#include \"atomic.h\"\n\nchar *__asctime_r(const struct tm *restrict tm, char *restrict buf)\n{\n\tif (snprintf(buf, 26, \"%.3s %.3s%3d %.2d:%.2d:%.2d %d\\n\",\n\t\t__nl_langinfo_l(ABDAY_1+tm->tm_wday, C_LOCALE),\n\t\t__nl_langinfo_l(ABMON_1+tm->tm_mon, C_LOCALE),\n\t\ttm->tm_mday, tm->tm_hour,\n\t\ttm->tm_min, tm->tm_sec,\n\t\t1900 + tm->tm_year) >= 26)\n\t{\n\t\t/* ISO C requires us to use the above format string,\n\t\t * even if it will not fit in the buffer. Thus asctime_r\n\t\t * is _supposed_ to crash if the fields in tm are too large.\n\t\t * We follow this behavior and crash \"gracefully\" to warn\n\t\t * application developers that they may not be so lucky\n\t\t * on other implementations (e.g. stack smashing..).\n\t\t */\n\t\ta_crash();\n\t}\n\treturn buf;\n}\n\nweak_alias(__asctime_r, asctime_r);\n"
  },
  {
    "path": "user.libc/src/time/clock.c",
    "content": "#include <time.h>\n#include <limits.h>\n\nclock_t clock()\n{\n\tstruct timespec ts;\n\n\tif (__clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts))\n\t\treturn -1;\n\n\tif (ts.tv_sec > LONG_MAX/1000000\n\t || ts.tv_nsec/1000 > LONG_MAX-1000000*ts.tv_sec)\n\t\treturn -1;\n\n\treturn ts.tv_sec*1000000 + ts.tv_nsec/1000;\n}\n"
  },
  {
    "path": "user.libc/src/time/clock_getres.c",
    "content": "#include <time.h>\n#include \"syscall.h\"\n\nint clock_getres(clockid_t clk, struct timespec *ts)\n{\n#if 0\n#ifdef SYS_clock_getres_time64\n\t/* On a 32-bit arch, use the old syscall if it exists. */\n\tif (SYS_clock_getres != SYS_clock_getres_time64) {\n\t\tlong ts32[2];\n\t\tint r = __syscall(SYS_clock_getres, clk, ts32);\n\t\tif (!r && ts) {\n\t\t\tts->tv_sec = ts32[0];\n\t\t\tts->tv_nsec = ts32[1];\n\t\t}\n\t\treturn __syscall_ret(r);\n\t}\n#endif\n\t/* If reaching this point, it's a 64-bit arch or time64-only\n\t * 32-bit arch and we can get result directly into timespec. */\n\treturn syscall(SYS_clock_getres, clk, ts);\n#endif\n}\n"
  },
  {
    "path": "user.libc/src/time/clock_gettime.c",
    "content": "#include <time.h>\n#include <errno.h>\n#include <stdint.h>\n#include \"syscall.h\"\n#include \"atomic.h\"\n\nint __clock_gettime(clockid_t clk, struct timespec *ts)\n{\n\treturn __syscall_ret(__syscall(SYS_clock_gettime, clk, ts));\n}\n\nweak_alias(__clock_gettime, clock_gettime);\n"
  },
  {
    "path": "user.libc/src/time/clock_nanosleep.c",
    "content": "#include <time.h>\n#include <errno.h>\n#include \"syscall.h\"\n\n#define IS32BIT(x) !((x)+0x80000000ULL>>32)\n#define CLAMP(x) (int)(IS32BIT(x) ? (x) : 0x7fffffffU+((0ULL+(x))>>63))\n\nint __clock_nanosleep(clockid_t clk, int flags, const struct timespec *req, struct timespec *rem)\n{\n\ttime_t s = req->tv_sec;\n\tlong ns = req->tv_nsec;\n\tint r = -ENOSYS;\n\n\tif (clk == CLOCK_THREAD_CPUTIME_ID)\n\t\treturn EINVAL;\n\n\tr = __syscall_cp(SYS_clock_nanosleep, clk, flags, s, ns, rem);\n\n\treturn -r;\n}\n\nweak_alias(__clock_nanosleep, clock_nanosleep);\n"
  },
  {
    "path": "user.libc/src/time/clock_settime.c",
    "content": "#include <time.h>\n#include <errno.h>\n#include \"syscall.h\"\n\n#define IS32BIT(x) !((x)+0x80000000ULL>>32)\n\nint clock_settime(clockid_t clk, const struct timespec *ts)\n{\n#if 0\n#ifdef SYS_clock_settime64\n\ttime_t s = ts->tv_sec;\n\tlong ns = ts->tv_nsec;\n\tint r = -ENOSYS;\n\tif (SYS_clock_settime == SYS_clock_settime64 || !IS32BIT(s))\n\t\tr = __syscall(SYS_clock_settime64, clk,\n\t\t\t((long long[]){s, ns}));\n\tif (SYS_clock_settime == SYS_clock_settime64 || r!=-ENOSYS)\n\t\treturn __syscall_ret(r);\n\tif (!IS32BIT(s))\n\t\treturn __syscall_ret(-ENOTSUP);\n\treturn syscall(SYS_clock_settime, clk, ((long[]){s, ns}));\n#else\n\treturn syscall(SYS_clock_settime, clk, ts);\n#endif\n#endif\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/time/ctime.c",
    "content": "#include <time.h>\n\nchar *ctime(const time_t *t)\n{\n\tstruct tm *tm = localtime(t);\n\tif (!tm) return 0;\n\treturn asctime(tm);\n}\n"
  },
  {
    "path": "user.libc/src/time/ctime_r.c",
    "content": "#include <time.h>\n\nchar *ctime_r(const time_t *t, char *buf)\n{\n\tstruct tm tm, *tm_p = localtime_r(t, &tm);\n\treturn tm_p ? asctime_r(tm_p, buf) : 0;\n}\n"
  },
  {
    "path": "user.libc/src/time/difftime.c",
    "content": "#include <time.h>\n\ndouble difftime(time_t t1, time_t t0)\n{\n\treturn t1-t0;\n}\n"
  },
  {
    "path": "user.libc/src/time/ftime.c",
    "content": "#include <sys/timeb.h>\n#include <time.h>\n\nint ftime(struct timeb *tp)\n{\n\tstruct timespec ts;\n\tclock_gettime(CLOCK_REALTIME, &ts);\n\ttp->time = ts.tv_sec;\n\ttp->millitm = ts.tv_nsec / 1000000;\n\ttp->timezone = tp->dstflag = 0;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/time/getdate.c",
    "content": "#include <time.h>\n#include <pthread.h>\n#include <errno.h>\n#include <stdio.h>\n#include <stdlib.h>\n\nint getdate_err;\n\nstruct tm *getdate(const char *s)\n{\n\tstatic struct tm tmbuf;\n\tstruct tm *ret = 0;\n\tchar *datemsk = getenv(\"DATEMSK\");\n\tFILE *f = 0;\n\tchar fmt[100], *p;\n\tint cs;\n\n\tpthread_setcancelstate(PTHREAD_CANCEL_DEFERRED, &cs);\n\n\tif (!datemsk) {\n\t\tgetdate_err = 1;\n\t\tgoto out;\n\t}\n\n\tf = fopen(datemsk, \"rbe\");\n\tif (!f) {\n\t\tif (errno == ENOMEM) getdate_err = 6;\n\t\telse getdate_err = 2;\n\t\tgoto out;\n\t}\n\n\twhile (fgets(fmt, sizeof fmt, f)) {\n\t\tp = strptime(s, fmt, &tmbuf);\n\t\tif (p && !*p) {\n\t\t\tret = &tmbuf;\n\t\t\tgoto out;\n\t\t}\n\t}\n\n\tif (ferror(f)) getdate_err = 5;\n\telse getdate_err = 7;\nout:\n\tif (f) fclose(f);\n\tpthread_setcancelstate(cs, 0);\n\treturn ret;\n}\n"
  },
  {
    "path": "user.libc/src/time/gettimeofday.c",
    "content": "#include <time.h>\n#include <sys/time.h>\n#include \"syscall.h\"\n\nint gettimeofday(struct timeval *restrict tv, void *restrict tz)\n{\n\tstruct timespec ts;\n\tif (!tv) return 0;\n\tclock_gettime(CLOCK_REALTIME, &ts);\n\ttv->tv_sec = ts.tv_sec;\n\ttv->tv_usec = (int)ts.tv_nsec / 1000;\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/time/gmtime.c",
    "content": "#include \"time_impl.h\"\n#include <errno.h>\n\nstruct tm *gmtime(const time_t *t)\n{\n\tstatic struct tm tm;\n\treturn __gmtime_r(t, &tm);\n}\n"
  },
  {
    "path": "user.libc/src/time/gmtime_r.c",
    "content": "#include \"time_impl.h\"\n#include <errno.h>\n\nstruct tm *__gmtime_r(const time_t *restrict t, struct tm *restrict tm)\n{\n\tif (__secs_to_tm(*t, tm) < 0) {\n\t\terrno = EOVERFLOW;\n\t\treturn 0;\n\t}\n\ttm->tm_isdst = 0;\n\ttm->__tm_gmtoff = 0;\n\ttm->__tm_zone = __utc;\n\treturn tm;\n}\n\nweak_alias(__gmtime_r, gmtime_r);\n"
  },
  {
    "path": "user.libc/src/time/localtime.c",
    "content": "#include \"time_impl.h\"\n\nstruct tm *localtime(const time_t *t)\n{\n\tstatic struct tm tm;\n\treturn __localtime_r(t, &tm);\n}\n"
  },
  {
    "path": "user.libc/src/time/localtime_r.c",
    "content": "#include \"time_impl.h\"\n#include <errno.h>\n#include <limits.h>\n\nstruct tm *__localtime_r(const time_t *restrict t, struct tm *restrict tm)\n{\n\t/* Reject time_t values whose year would overflow int because\n\t * __secs_to_zone cannot safely handle them. */\n\tif (*t < INT_MIN * 31622400LL || *t > INT_MAX * 31622400LL) {\n\t\terrno = EOVERFLOW;\n\t\treturn 0;\n\t}\n\t__secs_to_zone(*t, 0, &tm->tm_isdst, &tm->__tm_gmtoff, 0, &tm->__tm_zone);\n\tif (__secs_to_tm((long long)*t + tm->__tm_gmtoff, tm) < 0) {\n\t\terrno = EOVERFLOW;\n\t\treturn 0;\n\t}\n\treturn tm;\n}\n\nweak_alias(__localtime_r, localtime_r);\n"
  },
  {
    "path": "user.libc/src/time/mktime.c",
    "content": "#include \"time_impl.h\"\n#include <errno.h>\n\ntime_t mktime(struct tm *tm)\n{\n\tstruct tm new;\n\tlong opp;\n\tlong long t = __tm_to_secs(tm);\n\n\t__secs_to_zone(t, 1, &new.tm_isdst, &new.__tm_gmtoff, &opp, &new.__tm_zone);\n\n\tif (tm->tm_isdst>=0 && new.tm_isdst!=tm->tm_isdst)\n\t\tt -= opp - new.__tm_gmtoff;\n\n\tt -= new.__tm_gmtoff;\n\tif ((time_t)t != t) goto error;\n\n\t__secs_to_zone(t, 0, &new.tm_isdst, &new.__tm_gmtoff, &opp, &new.__tm_zone);\n\n\tif (__secs_to_tm(t + new.__tm_gmtoff, &new) < 0) goto error;\n\n\t*tm = new;\n\treturn t;\n\nerror:\n\terrno = EOVERFLOW;\n\treturn -1;\n}\n"
  },
  {
    "path": "user.libc/src/time/nanosleep.c",
    "content": "#include <time.h>\n#include \"syscall.h\"\n\nint nanosleep(const struct timespec *req, struct timespec *rem)\n{\n\treturn __syscall_ret(-__clock_nanosleep(CLOCK_REALTIME, 0, req, rem));\n}\n"
  },
  {
    "path": "user.libc/src/time/strptime.c",
    "content": "#include <stdlib.h>\n#include <langinfo.h>\n#include <time.h>\n#include <ctype.h>\n#include <stddef.h>\n#include <string.h>\n#include <strings.h>\n\nchar *strptime(const char *restrict s, const char *restrict f, struct tm *restrict tm)\n{\n\tint i, w, neg, adj, min, range, *dest, dummy;\n\tconst char *ex;\n\tsize_t len;\n\tint want_century = 0, century = 0, relyear = 0;\n\twhile (*f) {\n\t\tif (*f != '%') {\n\t\t\tif (isspace(*f)) for (; *s && isspace(*s); s++);\n\t\t\telse if (*s != *f) return 0;\n\t\t\telse s++;\n\t\t\tf++;\n\t\t\tcontinue;\n\t\t}\n\t\tf++;\n\t\tif (*f == '+') f++;\n\t\tif (isdigit(*f)) {\n\t\t\tchar *new_f;\n\t\t\tw=strtoul(f, &new_f, 10);\n\t\t\tf = new_f;\n\t\t} else {\n\t\t\tw=-1;\n\t\t}\n\t\tadj=0;\n\t\tswitch (*f++) {\n\t\tcase 'a': case 'A':\n\t\t\tdest = &tm->tm_wday;\n\t\t\tmin = ABDAY_1;\n\t\t\trange = 7;\n\t\t\tgoto symbolic_range;\n\t\tcase 'b': case 'B': case 'h':\n\t\t\tdest = &tm->tm_mon;\n\t\t\tmin = ABMON_1;\n\t\t\trange = 12;\n\t\t\tgoto symbolic_range;\n\t\tcase 'c':\n\t\t\ts = strptime(s, nl_langinfo(D_T_FMT), tm);\n\t\t\tif (!s) return 0;\n\t\t\tbreak;\n\t\tcase 'C':\n\t\t\tdest = &century;\n\t\t\tif (w<0) w=2;\n\t\t\twant_century |= 2;\n\t\t\tgoto numeric_digits;\n\t\tcase 'd': case 'e':\n\t\t\tdest = &tm->tm_mday;\n\t\t\tmin = 1;\n\t\t\trange = 31;\n\t\t\tgoto numeric_range;\n\t\tcase 'D':\n\t\t\ts = strptime(s, \"%m/%d/%y\", tm);\n\t\t\tif (!s) return 0;\n\t\t\tbreak;\n\t\tcase 'H':\n\t\t\tdest = &tm->tm_hour;\n\t\t\tmin = 0;\n\t\t\trange = 24;\n\t\t\tgoto numeric_range;\n\t\tcase 'I':\n\t\t\tdest = &tm->tm_hour;\n\t\t\tmin = 1;\n\t\t\trange = 12;\n\t\t\tgoto numeric_range;\n\t\tcase 'j':\n\t\t\tdest = &tm->tm_yday;\n\t\t\tmin = 1;\n\t\t\trange = 366;\n\t\t\tadj = 1;\n\t\t\tgoto numeric_range;\n\t\tcase 'm':\n\t\t\tdest = &tm->tm_mon;\n\t\t\tmin = 1;\n\t\t\trange = 12;\n\t\t\tadj = 1;\n\t\t\tgoto numeric_range;\n\t\tcase 'M':\n\t\t\tdest = &tm->tm_min;\n\t\t\tmin = 0;\n\t\t\trange = 60;\n\t\t\tgoto numeric_range;\n\t\tcase 'n': case 't':\n\t\t\tfor (; *s && isspace(*s); s++);\n\t\t\tbreak;\n\t\tcase 'p':\n\t\t\tex = nl_langinfo(AM_STR);\n\t\t\tlen = strlen(ex);\n\t\t\tif (!strncasecmp(s, ex, len)) {\n\t\t\t\ttm->tm_hour %= 12;\n\t\t\t\ts += len;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tex = nl_langinfo(PM_STR);\n\t\t\tlen = strlen(ex);\n\t\t\tif (!strncasecmp(s, ex, len)) {\n\t\t\t\ttm->tm_hour %= 12;\n\t\t\t\ttm->tm_hour += 12;\n\t\t\t\ts += len;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn 0;\n\t\tcase 'r':\n\t\t\ts = strptime(s, nl_langinfo(T_FMT_AMPM), tm);\n\t\t\tif (!s) return 0;\n\t\t\tbreak;\n\t\tcase 'R':\n\t\t\ts = strptime(s, \"%H:%M\", tm);\n\t\t\tif (!s) return 0;\n\t\t\tbreak;\n\t\tcase 'S':\n\t\t\tdest = &tm->tm_sec;\n\t\t\tmin = 0;\n\t\t\trange = 61;\n\t\t\tgoto numeric_range;\n\t\tcase 'T':\n\t\t\ts = strptime(s, \"%H:%M:%S\", tm);\n\t\t\tif (!s) return 0;\n\t\t\tbreak;\n\t\tcase 'U':\n\t\tcase 'W':\n\t\t\t/* Throw away result, for now. (FIXME?) */\n\t\t\tdest = &dummy;\n\t\t\tmin = 0;\n\t\t\trange = 54;\n\t\t\tgoto numeric_range;\n\t\tcase 'w':\n\t\t\tdest = &tm->tm_wday;\n\t\t\tmin = 0;\n\t\t\trange = 7;\n\t\t\tgoto numeric_range;\n\t\tcase 'x':\n\t\t\ts = strptime(s, nl_langinfo(D_FMT), tm);\n\t\t\tif (!s) return 0;\n\t\t\tbreak;\n\t\tcase 'X':\n\t\t\ts = strptime(s, nl_langinfo(T_FMT), tm);\n\t\t\tif (!s) return 0;\n\t\t\tbreak;\n\t\tcase 'y':\n\t\t\tdest = &relyear;\n\t\t\tw = 2;\n\t\t\twant_century |= 1;\n\t\t\tgoto numeric_digits;\n\t\tcase 'Y':\n\t\t\tdest = &tm->tm_year;\n\t\t\tif (w<0) w=4;\n\t\t\tadj = 1900;\n\t\t\twant_century = 0;\n\t\t\tgoto numeric_digits;\n\t\tcase '%':\n\t\t\tif (*s++ != '%') return 0;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn 0;\n\t\tnumeric_range:\n\t\t\tif (!isdigit(*s)) return 0;\n\t\t\t*dest = 0;\n\t\t\tfor (i=1; i<=min+range && isdigit(*s); i*=10)\n\t\t\t\t*dest = *dest * 10 + *s++ - '0';\n\t\t\tif (*dest - min >= (unsigned)range) return 0;\n\t\t\t*dest -= adj;\n\t\t\tswitch((char *)dest - (char *)tm) {\n\t\t\tcase offsetof(struct tm, tm_yday):\n\t\t\t\t;\n\t\t\t}\n\t\t\tgoto update;\n\t\tnumeric_digits:\n\t\t\tneg = 0;\n\t\t\tif (*s == '+') s++;\n\t\t\telse if (*s == '-') neg=1, s++;\n\t\t\tif (!isdigit(*s)) return 0;\n\t\t\tfor (*dest=i=0; i<w && isdigit(*s); i++)\n\t\t\t\t*dest = *dest * 10 + *s++ - '0';\n\t\t\tif (neg) *dest = -*dest;\n\t\t\t*dest -= adj;\n\t\t\tgoto update;\n\t\tsymbolic_range:\n\t\t\tfor (i=2*range-1; i>=0; i--) {\n\t\t\t\tex = nl_langinfo(min+i);\n\t\t\t\tlen = strlen(ex);\n\t\t\t\tif (strncasecmp(s, ex, len)) continue;\n\t\t\t\ts += len;\n\t\t\t\t*dest = i % range;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (i<0) return 0;\n\t\t\tgoto update;\n\t\tupdate:\n\t\t\t//FIXME\n\t\t\t;\n\t\t}\n\t}\n\tif (want_century) {\n\t\ttm->tm_year = relyear;\n\t\tif (want_century & 2) tm->tm_year += century * 100 - 1900;\n\t\telse if (tm->tm_year <= 68) tm->tm_year += 100;\n\t}\n\treturn (char *)s;\n}\n"
  },
  {
    "path": "user.libc/src/time/time.c",
    "content": "#include <time.h>\n#include \"syscall.h\"\n\ntime_t time(time_t *t)\n{\n\tstruct timespec ts;\n\t__clock_gettime(CLOCK_REALTIME, &ts);\n\tif (t) *t = ts.tv_sec;\n\treturn ts.tv_sec;\n}\n"
  },
  {
    "path": "user.libc/src/time/time_impl.h",
    "content": "#include <time.h>\n\nhidden int __days_in_month(int, int);\nhidden int __month_to_secs(int, int);\nhidden long long __year_to_secs(long long, int *);\nhidden long long __tm_to_secs(const struct tm *);\nhidden const char *__tm_to_tzname(const struct tm *);\nhidden int __secs_to_tm(long long, struct tm *);\nhidden void __secs_to_zone(long long, int, int *, long *, long *, const char **);\nhidden const char *__strftime_fmt_1(char (*)[100], size_t *, int, const struct tm *, locale_t, int);\nextern hidden const char __utc[];\n"
  },
  {
    "path": "user.libc/src/time/timegm.c",
    "content": "#define _GNU_SOURCE\n#include \"time_impl.h\"\n#include <errno.h>\n\ntime_t timegm(struct tm *tm)\n{\n\tstruct tm new;\n\tlong long t = __tm_to_secs(tm);\n\tif (__secs_to_tm(t, &new) < 0) {\n\t\terrno = EOVERFLOW;\n\t\treturn -1;\n\t}\n\t*tm = new;\n\ttm->tm_isdst = 0;\n\ttm->__tm_gmtoff = 0;\n\ttm->__tm_zone = __utc;\n\treturn t;\n}\n"
  },
  {
    "path": "user.libc/src/time/times.c",
    "content": "#include <sys/times.h>\n#include \"syscall.h\"\n\nclock_t times(struct tms *tms)\n{\n#if 0\n\treturn __syscall(SYS_times, tms);\n#endif\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libc/src/time/timespec_get.c",
    "content": "#include <time.h>\n\n/* There is no other implemented value than TIME_UTC; all other values\n * are considered erroneous. */\nint timespec_get(struct timespec * ts, int base)\n{\n\tif (base != TIME_UTC) return 0;\n\tint ret = __clock_gettime(CLOCK_REALTIME, ts);\n\treturn ret < 0 ? 0 : base;\n}\n"
  },
  {
    "path": "user.libc/src/time/utime.c",
    "content": "#include <utime.h>\n#include <sys/stat.h>\n#include <time.h>\n#include <fcntl.h>\n\nint utime(const char *path, const struct utimbuf *times)\n{\n\treturn utimensat(AT_FDCWD, path, times ? ((struct timespec [2]){\n\t\t{ .tv_sec = times->actime }, { .tv_sec = times->modtime }})\n\t\t: 0, 0);\n}\n"
  },
  {
    "path": "user.libc/src/time/wcsftime.c",
    "content": "#include <wchar.h>\n#include <time.h>\n#include <locale.h>\n#include \"locale_impl.h\"\n#include \"time_impl.h\"\n\nsize_t __wcsftime_l(wchar_t *restrict s, size_t n, const wchar_t *restrict f, const struct tm *restrict tm, locale_t loc)\n{\n\tsize_t l, k;\n\tchar buf[100];\n\twchar_t wbuf[100];\n\twchar_t *p;\n\tconst char *t_mb;\n\tconst wchar_t *t;\n\tint pad, plus;\n\tunsigned long width;\n\tfor (l=0; l<n; f++) {\n\t\tif (!*f) {\n\t\t\ts[l] = 0;\n\t\t\treturn l;\n\t\t}\n\t\tif (*f != '%') {\n\t\t\ts[l++] = *f;\n\t\t\tcontinue;\n\t\t}\n\t\tf++;\n\t\tpad = 0;\n\t\tif (*f == '-' || *f == '_' || *f == '0') pad = *f++;\n\t\tif ((plus = (*f == '+'))) f++;\n\t\twidth = wcstoul(f, &p, 10);\n\t\tif (*p == 'C' || *p == 'F' || *p == 'G' || *p == 'Y') {\n\t\t\tif (!width && p!=f) width = 1;\n\t\t} else {\n\t\t\twidth = 0;\n\t\t}\n\t\tf = p;\n\t\tif (*f == 'E' || *f == 'O') f++;\n\t\tt_mb = __strftime_fmt_1(&buf, &k, *f, tm, loc, pad);\n\t\tif (!t_mb) break;\n\t\tk = mbstowcs(wbuf, t_mb, sizeof wbuf / sizeof *wbuf);\n\t\tif (k == (size_t)-1) return 0;\n\t\tt = wbuf;\n\t\tif (width) {\n\t\t\tfor (; *t=='+' || *t=='-' || (*t=='0'&&t[1]); t++, k--);\n\t\t\twidth--;\n\t\t\tif (plus && tm->tm_year >= 10000-1900)\n\t\t\t\ts[l++] = '+';\n\t\t\telse if (tm->tm_year < -1900)\n\t\t\t\ts[l++] = '-';\n\t\t\telse\n\t\t\t\twidth++;\n\t\t\tfor (; width > k && l < n; width--)\n\t\t\t\ts[l++] = '0';\n\t\t}\n\t\tif (k >= n-l) k = n-l;\n\t\twmemcpy(s+l, t, k);\n\t\tl += k;\n\t}\n\tif (n) {\n\t\tif (l==n) l=n-1;\n\t\ts[l] = 0;\n\t}\n\treturn 0;\n}\n\nsize_t wcsftime(wchar_t *restrict wcs, size_t n, const wchar_t *restrict f, const struct tm *restrict tm)\n{\n\treturn __wcsftime_l(wcs, n, f, tm, CURRENT_LOCALE);\n}\n\nweak_alias(__wcsftime_l, wcsftime_l);\n"
  },
  {
    "path": "user.libc/src/unistd/aarch64/__unistd.c",
    "content": "#include <unistd.h>\n\npid_t __getpid(void)\n{\n\tunsigned long v;\n\t__asm__ volatile (\"mrs %0, tpidrro_el0\" : \"=r\" (v));\n\treturn (pid_t)(v >> 32);\n}\n\nint __gettid(void)\n{\n\tunsigned long v;\n\t__asm__ volatile (\"mrs %0, tpidrro_el0\" : \"=r\" (v));\n\treturn (int)(v & 0xffffffff);\n}\n"
  },
  {
    "path": "user.libc/src/unistd/access.c",
    "content": "#include <unistd.h>\n#include <fcntl.h>\n#include \"syscall.h\"\n#include <string.h>\n\n#include <minos/proto.h>\n#include <minos/kobject.h>\n#include \"libc.h\"\n\nint access(const char *filename, int amode)\n{\n\tstruct proto proto;\n\n\tif (strcmp(\".\", filename) == 0)\n\t\treturn -EINVAL;\n\tif (strcmp(\"..\", filename) == 0)\n\t\treturn -EINVAL;\n\tif (filename[strlen(filename) - 1] == '/')\n\t\treturn -EINVAL;\n\n\t/*\n\t * currently only support Absolute path, TBD\n\t */\n\tif (filename[0] != '/')\n\t\treturn -EINVAL;\n\n\tproto.proto_id = PROTO_ACCESS;\n\tproto.access.amode = amode;\n\n\treturn sys_send_proto_with_data(libc.rootfs_handle,\n\t\t\t&proto, (void *)filename, strlen(filename), -1);\n}\n"
  },
  {
    "path": "user.libc/src/unistd/chdir.c",
    "content": "#include <unistd.h>\n#include <dirent.h>\n#include <errno.h>\n#include <limits.h>\n#include <string.h>\n#include \"syscall.h\"\n\nstatic char __cwd[PATH_MAX];\nDIR *__cdir = NULL;\n\nchar *getcwd(char *buf, size_t size)\n{\n        char tmp[buf ? 1 : PATH_MAX];\n\n        if (!buf) {\n                buf = tmp;\n                size = sizeof tmp;\n        } else if (!size) {\n                errno = EINVAL;\n                return 0;\n        }\n\n\tstrcpy(buf, __cwd);\n\n        return buf == tmp ? strdup(buf) : buf;\n}\n\nDIR *getcdir(void)\n{\n\tif (__cdir == NULL)\n\t\t__cdir = opendir(__cwd);\n\treturn __cdir;\n}\n\nint chdir(const char *path)\n{\n\tDIR *new;\n\n\tif ((strcmp(path, __cwd) == 0) && (__cdir != NULL))\n\t\treturn 0;\n\n\tnew = opendir(path);\n\tif (!new)\n\t\treturn -ENOENT;\n\n\tstrcpy(__cwd, path);\n\tif (__cdir)\n\t\tclosedir(__cdir);\n\t__cdir = new;\n\n\treturn 0;\n}\n\nhidden void __cwd_init(void)\n{\n\tstrcpy(__cwd, \"/\");\n}\n"
  },
  {
    "path": "user.libc/src/unistd/close.c",
    "content": "#include <unistd.h>\n#include <errno.h>\n#include \"syscall.h\"\n#include \"stdio_impl.h\"\n\nint close(int fd)\n{\n\treturn fclose_fd(fd);\n}\n"
  },
  {
    "path": "user.libc/src/unistd/getpid.c",
    "content": "#include <unistd.h>\n\nstatic pid_t __getpid_dummy(void)\n{\n\treturn 0;\n}\n\nweak_alias(__getpid_dummy, __getpid);\n\npid_t getpid(void)\n{\n        return __getpid();\n}\n"
  },
  {
    "path": "user.libc/src/unistd/gettid.c",
    "content": "#include <unistd.h>\n\nstatic int __gettid_dummy(void)\n{\n\treturn 0;\n}\n\nweak_alias(__gettid_dummy, __gettid);\n\nint gettid(void)\n{\n        return __gettid();\n}\n"
  },
  {
    "path": "user.libc/src/unistd/read.c",
    "content": "#include <unistd.h>\n#include \"syscall.h\"\n#include <string.h>\n#include \"stdio_impl.h\"\n\n#include <minos/proto.h>\n#include <minos/kobject.h>\n\nssize_t read(int fd, void *buf, size_t count)\n{\n\tFILE *file;\n\n\tfile = __ofl_get_file(fd);\n\tif (!file)\n\t\treturn -ENOENT;\n\n\treturn fread(buf, count, 1, file);\n}\n"
  },
  {
    "path": "user.libc/src/unistd/write.c",
    "content": "#include <stdio.h>\n#include <unistd.h>\n#include \"syscall.h\"\n#include \"stdio_impl.h\"\n\nssize_t write(int fd, const void *buf, size_t count)\n{\n\tFILE *file;\n\n\tfile = __ofl_get_file(fd);\n\tif (!file)\n\t\treturn -ENOENT;\n\n\treturn fwrite(buf, count, 1, file);\n}\n"
  },
  {
    "path": "user.libc/stat/stat.c",
    "content": "#include <stdlib.h>\n#include <stdint.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <unistd.h>\n\n#include \"stdio_impl.h\"\n#include <minos/kobject.h>\n#include <minos/proto.h>\n\nint fstatat(int dirfd, const char *pathname, struct stat *statbuf, int flags)\n{\n\treturn -EOPNOTSUPP;\n}\n\nint fstat(int fd, struct stat *statbuf)\n{\n\tstruct proto proto;\n\tint handle;\n\tint ret;\n\n\tif (fd <= 0)\n\t\treturn -EINVAL;\n\n\tproto.proto_id = PROTO_STAT;\n\thandle = sys_send_proto(fd, &proto);\n\tif (handle <= 0)\n\t\treturn handle;\n\n\tret = kobject_read_simple(handle, statbuf, sizeof(struct stat), 0);\n\tkobject_close(handle);\n\n\treturn ret;\n}\n\nint stat(const char *pathname, struct stat *statbuf)\n{\n\treturn -EOPNOTSUPP;\n}\n\nint lstat(const char *pathname, struct stat *statbuf)\n{\n\treturn stat(pathname, statbuf);\n}\n"
  },
  {
    "path": "user.libc/tools/add-cfi.common.awk",
    "content": "function hex2int(str,   i) {\n  str = tolower(str)\n\n  for (i = 1; i <= 16; i++) {\n    char = substr(\"0123456789abcdef\", i, 1)\n    lookup[char] = i-1\n  }\n\n  result = 0\n  for (i = 1; i <= length(str); i++) {\n    result = result * 16\n    char   = substr(str, i, 1)\n    result = result + lookup[char]\n  }\n  return result\n}\n\nfunction parse_const(str) {\n  sign = sub(/^-/, \"\", str)\n  hex  = sub(/^0x/, \"\", str)\n  if (hex)\n    n = hex2int(str)\n  else\n    n = str+0\n  return sign ? -n : n\n}\n"
  },
  {
    "path": "user.libc/tools/add-cfi.i386.awk",
    "content": "# Insert GAS CFI directives (\"control frame information\") into x86-32 asm input\n#\n# CFI directives tell the assembler how to generate \"stack frame\" debug info\n# This information can tell a debugger (like gdb) how to find the current stack\n#   frame at any point in the program code, and how to find the values which\n#   various registers had at higher points in the call stack\n# With this information, the debugger can show a backtrace, and you can move up\n#   and down the call stack and examine the values of local variables\n\nBEGIN {\n  # don't put CFI data in the .eh_frame ELF section (which we don't keep)\n  print \".cfi_sections .debug_frame\"\n\n  # only emit CFI directives inside a function\n  in_function = 0\n\n  # emit .loc directives with line numbers from original source\n  printf \".file 1 \\\"%s\\\"\\n\", ARGV[1]\n  line_number = 0\n\n  # used to detect \"call label; label:\" trick\n  called = \"\"\n}\n\nfunction get_const1() {\n  # for instructions with 2 operands, get 1st operand (assuming it is constant)\n  match($0, /-?(0x[0-9a-fA-F]+|[0-9]+),/)\n  return parse_const(substr($0, RSTART, RLENGTH-1))\n}\n\nfunction canonicalize_reg(register) {\n  if (match(register, /^e/))\n    return register\n  else if (match(register, /[hl]$/)) # AH, AL, BH, BL, etc\n    return \"e\" substr(register, 1, 1) \"x\"\n  else # AX, BX, CX, etc\n    return \"e\" register\n}\nfunction get_reg() {\n  # only use if you already know there is 1 and only 1 register\n  match($0, /%e?([abcd][hlx]|si|di|bp)/)\n  return canonicalize_reg(substr($0, RSTART+1, RLENGTH-1))\n}\nfunction get_reg1() {\n  # for instructions with 2 operands, get 1st operand (assuming it is register)\n  match($0, /%e?([abcd][hlx]|si|di|bp),/)\n  return canonicalize_reg(substr($0, RSTART+1, RLENGTH-2))\n}\nfunction get_reg2() {\n  # for instructions with 2 operands, get 2nd operand (assuming it is register)\n  match($0, /,%e?([abcd][hlx]|si|di|bp)/)\n  return canonicalize_reg(substr($0, RSTART+2, RLENGTH-2))\n}\n\nfunction adjust_sp_offset(delta) {\n  if (in_function)\n    printf \".cfi_adjust_cfa_offset %d\\n\", delta\n}\n\n{\n  line_number = line_number + 1\n\n  # clean the input up before doing anything else\n  # delete comments\n  gsub(/(#|\\/\\/).*/, \"\")\n\n  # canonicalize whitespace\n  gsub(/[ \\t]+/, \" \") # mawk doesn't understand \\s\n  gsub(/ *, */, \",\")\n  gsub(/ *: */, \": \")\n  gsub(/ $/, \"\")\n  gsub(/^ /, \"\")\n}\n\n# check for assembler directives which we care about\n/^\\.(section|data|text)/ {\n  # a .cfi_startproc/.cfi_endproc pair should be within the same section\n  # otherwise, clang will choke when generating ELF output\n  if (in_function) {\n    print \".cfi_endproc\"\n    in_function = 0\n  }\n}\n/^\\.type [a-zA-Z0-9_]+,@function/ {\n  functions[substr($2, 1, length($2)-10)] = 1\n}\n# not interested in assembler directives beyond this, just pass them through\n/^\\./ {\n  print\n  next\n}\n\n/^[a-zA-Z0-9_]+:/ {\n  label = substr($1, 1, length($1)-1) # drop trailing :\n\n  if (called == label) {\n    # note adjustment of stack pointer from \"call label; label:\"\n    adjust_sp_offset(4)\n  }\n\n  if (functions[label]) {\n    if (in_function)\n      print \".cfi_endproc\"\n\n    in_function = 1\n    print \".cfi_startproc\"\n\n    for (register in saved)\n      delete saved[register]\n    for (register in dirty)\n      delete dirty[register]\n  }\n\n  # an instruction may follow on the same line, so continue processing\n}\n\n/^$/ { next }\n\n{\n  called = \"\"\n  printf \".loc 1 %d\\n\", line_number\n  print\n}\n\n# KEEPING UP WITH THE STACK POINTER\n# We do NOT attempt to understand foolish and ridiculous tricks like stashing\n#   the stack pointer and then using %esp as a scratch register, or bitshifting\n#   it or taking its square root or anything stupid like that.\n# %esp should only be adjusted by pushing/popping or adding/subtracting constants\n#\n/pushl?/ {\n  if (match($0, / %(ax|bx|cx|dx|di|si|bp|sp)/))\n    adjust_sp_offset(2)\n  else\n    adjust_sp_offset(4)\n}\n/popl?/ {\n  if (match($0, / %(ax|bx|cx|dx|di|si|bp|sp)/))\n    adjust_sp_offset(-2)\n  else\n    adjust_sp_offset(-4)\n}\n/addl? \\$-?(0x[0-9a-fA-F]+|[0-9]+),%esp/ { adjust_sp_offset(-get_const1()) }\n/subl? \\$-?(0x[0-9a-fA-F]+|[0-9]+),%esp/ { adjust_sp_offset(get_const1()) }\n\n/call/ {\n  if (match($0, /call [0-9]+f/)) # \"forward\" label\n    called = substr($0, RSTART+5, RLENGTH-6)\n  else if (match($0, /call [0-9a-zA-Z_]+/))\n    called = substr($0, RSTART+5, RLENGTH-5)\n}\n\n# TRACKING REGISTER VALUES FROM THE PREVIOUS STACK FRAME\n#\n/pushl? %e(ax|bx|cx|dx|si|di|bp)/ { # don't match \"push (%reg)\"\n  # if a register is being pushed, and its value has not changed since the\n  #   beginning of this function, the pushed value can be used when printing\n  #   local variables at the next level up the stack\n  # emit '.cfi_rel_offset' for that\n\n  if (in_function) {\n    register = get_reg()\n    if (!saved[register] && !dirty[register]) {\n      printf \".cfi_rel_offset %s,0\\n\", register\n      saved[register] = 1\n    }\n  }\n}\n\n/movl? %e(ax|bx|cx|dx|si|di|bp),-?(0x[0-9a-fA-F]+|[0-9]+)?\\(%esp\\)/ {\n  if (in_function) {\n    register = get_reg()\n    if (match($0, /-?(0x[0-9a-fA-F]+|[0-9]+)\\(%esp\\)/)) {\n      offset = parse_const(substr($0, RSTART, RLENGTH-6))\n    } else {\n      offset = 0\n    }\n    if (!saved[register] && !dirty[register]) {\n      printf \".cfi_rel_offset %s,%d\\n\", register, offset\n      saved[register] = 1\n    }\n  }\n}\n\n# IF REGISTER VALUES ARE UNCEREMONIOUSLY TRASHED\n# ...then we want to know about it.\n#\nfunction trashed(register) {\n  if (in_function && !saved[register] && !dirty[register]) {\n    printf \".cfi_undefined %s\\n\", register\n  }\n  dirty[register] = 1\n}\n# this does NOT exhaustively check for all possible instructions which could\n# overwrite a register value inherited from the caller (just the common ones)\n/mov.*,%e?([abcd][hlx]|si|di|bp)$/  { trashed(get_reg2()) }\n/(add|addl|sub|subl|and|or|xor|lea|sal|sar|shl|shr).*,%e?([abcd][hlx]|si|di|bp)$/ {\n  trashed(get_reg2())\n}\n/^i?mul [^,]*$/                      { trashed(\"eax\"); trashed(\"edx\") }\n/^i?mul.*,%e?([abcd][hlx]|si|di|bp)$/ { trashed(get_reg2()) }\n/^i?div/                             { trashed(\"eax\"); trashed(\"edx\") }\n/(dec|inc|not|neg|pop) %e?([abcd][hlx]|si|di|bp)/  { trashed(get_reg()) }\n/cpuid/ { trashed(\"eax\"); trashed(\"ebx\"); trashed(\"ecx\"); trashed(\"edx\") }\n\nEND {\n  if (in_function)\n    print \".cfi_endproc\"\n}\n"
  },
  {
    "path": "user.libc/tools/add-cfi.x86_64.awk",
    "content": "# Insert GAS CFI directives (\"control frame information\") into x86-64 asm input\n\nBEGIN {\n  # don't put CFI data in the .eh_frame ELF section (which we don't keep)\n  print \".cfi_sections .debug_frame\"\n\n  # only emit CFI directives inside a function\n  in_function = 0\n\n  # emit .loc directives with line numbers from original source\n  printf \".file 1 \\\"%s\\\"\\n\", ARGV[1]\n  line_number = 0\n\n  # used to detect \"call label; label:\" trick\n  called = \"\"\n}\n\nfunction get_const1() {\n  # for instructions with 2 operands, get 1st operand (assuming it is constant)\n  match($0, /-?(0x[0-9a-fA-F]+|[0-9]+),/)\n  return parse_const(substr($0, RSTART, RLENGTH-1))\n}\n\nfunction canonicalize_reg(register) {\n  if (match(register, /^r/))\n    return register\n  else if (match(register, /^e/))\n    return \"r\" substr(register, 2, length(register)-1)\n  else if (match(register, /[hl]$/)) # AH, AL, BH, BL, etc\n    return \"r\" substr(register, 1, 1) \"x\"\n  else # AX, BX, CX, etc\n    return \"r\" register\n}\nfunction get_reg() {\n  # only use if you already know there is 1 and only 1 register\n  match($0, /%[er]?([abcd][xlh]|si|di|bp|8|9|10|11|12|13|14|15)/)\n  return canonicalize_reg(substr($0, RSTART+1, RLENGTH-1))\n}\nfunction get_reg1() {\n  # for instructions with 2 operands, get 1st operand (assuming it is register)\n  match($0, /%[er]?([abcd][xlh]|si|di|bp|8|9|10|11|12|13|14|15),/)\n  return canonicalize_reg(substr($0, RSTART+1, RLENGTH-2))\n}\nfunction get_reg2() {\n  # for instructions with 2 operands, get 2nd operand (assuming it is register)\n  match($0, /,%[er]?([abcd][xlh]|si|di|bp|8|9|10|11|12|13|14|15)/)\n  return canonicalize_reg(substr($0, RSTART+2, RLENGTH-2))\n}\n\nfunction adjust_sp_offset(delta) {\n  if (in_function)\n    printf \".cfi_adjust_cfa_offset %d\\n\", delta\n}\n\n{\n  line_number = line_number + 1\n\n  # clean the input up before doing anything else\n  # delete comments\n  gsub(/(#|\\/\\/).*/, \"\")\n\n  # canonicalize whitespace\n  gsub(/[ \\t]+/, \" \") # mawk doesn't understand \\s\n  gsub(/ *, */, \",\")\n  gsub(/ *: */, \": \")\n  gsub(/ $/, \"\")\n  gsub(/^ /, \"\")\n}\n\n# check for assembler directives which we care about\n/^\\.(section|data|text)/ {\n  # a .cfi_startproc/.cfi_endproc pair should be within the same section\n  # otherwise, clang will choke when generating ELF output\n  if (in_function) {\n    print \".cfi_endproc\"\n    in_function = 0\n  }\n}\n/^\\.type [a-zA-Z0-9_]+,@function/ {\n  functions[substr($2, 1, length($2)-10)] = 1\n}\n# not interested in assembler directives beyond this, just pass them through\n/^\\./ {\n  print\n  next\n}\n\n/^[a-zA-Z0-9_]+:/ {\n  label = substr($1, 1, length($1)-1) # drop trailing :\n\n  if (called == label) {\n    # note adjustment of stack pointer from \"call label; label:\"\n    adjust_sp_offset(8)\n  }\n\n  if (functions[label]) {\n    if (in_function)\n      print \".cfi_endproc\"\n\n    in_function = 1\n    print \".cfi_startproc\"\n\n    for (register in saved)\n      delete saved[register]\n    for (register in dirty)\n      delete dirty[register]\n  }\n\n  # an instruction may follow on the same line, so continue processing\n}\n\n/^$/ { next }\n\n{\n  called = \"\"\n  printf \".loc 1 %d\\n\", line_number\n  print\n}\n\n# KEEPING UP WITH THE STACK POINTER\n# %rsp should only be adjusted by pushing/popping or adding/subtracting constants\n#\n/pushl?/ {\n  adjust_sp_offset(8)\n}\n/popl?/ {\n  adjust_sp_offset(-8)\n}\n/addl? \\$-?(0x[0-9a-fA-F]+|[0-9]+),%rsp/ { adjust_sp_offset(-get_const1()) }\n/subl? \\$-?(0x[0-9a-fA-F]+|[0-9]+),%rsp/ { adjust_sp_offset(get_const1()) }\n\n/call/ {\n  if (match($0, /call [0-9]+f/)) # \"forward\" label\n    called = substr($0, RSTART+5, RLENGTH-6)\n  else if (match($0, /call [0-9a-zA-Z_]+/))\n    called = substr($0, RSTART+5, RLENGTH-5)\n}\n\n# TRACKING REGISTER VALUES FROM THE PREVIOUS STACK FRAME\n#\n/pushl? %r(ax|bx|cx|dx|si|di|bp|8|9|10|11|12|13|14|15)/ { # don't match \"push (%reg)\"\n  # if a register is being pushed, and its value has not changed since the\n  #   beginning of this function, the pushed value can be used when printing\n  #   local variables at the next level up the stack\n  # emit '.cfi_rel_offset' for that\n\n  if (in_function) {\n    register = get_reg()\n    if (!saved[register] && !dirty[register]) {\n      printf \".cfi_rel_offset %s,0\\n\", register\n      saved[register] = 1\n    }\n  }\n}\n\n/movl? %r(ax|bx|cx|dx|si|di|bp|8|9|10|11|12|13|14|15),-?(0x[0-9a-fA-F]+|[0-9]+)?\\(%rsp\\)/ {\n  if (in_function) {\n    register = get_reg()\n    if (match($0, /-?(0x[0-9a-fA-F]+|[0-9]+)\\(%rsp\\)/)) {\n      offset = parse_const(substr($0, RSTART, RLENGTH-6))\n    } else {\n      offset = 0\n    }\n    if (!saved[register] && !dirty[register]) {\n      printf \".cfi_rel_offset %s,%d\\n\", register, offset\n      saved[register] = 1\n    }\n  }\n}\n\n# IF REGISTER VALUES ARE UNCEREMONIOUSLY TRASHED\n# ...then we want to know about it.\n#\nfunction trashed(register) {\n  if (in_function && !saved[register] && !dirty[register]) {\n    printf \".cfi_undefined %s\\n\", register\n  }\n  dirty[register] = 1\n}\n# this does NOT exhaustively check for all possible instructions which could\n# overwrite a register value inherited from the caller (just the common ones)\n/mov.*,%[er]?([abcd][xlh]|si|di|bp|8|9|10|11|12|13|14|15)$/ { trashed(get_reg2()) }\n/(add|addl|sub|subl|and|or|xor|lea|sal|sar|shl|shr).*,%[er]?([abcd][xlh]|si|di|bp|8|9|10|11|12|13|14|15)$/ {\n  trashed(get_reg2())\n}\n/^i?mul [^,]*$/ { trashed(\"rax\"); trashed(\"rdx\") }\n/^i?mul.*,%[er]?([abcd][xlh]|si|di|bp|8|9|10|11|12|13|14|15)$/ { trashed(get_reg2()) }\n/^i?div/ { trashed(\"rax\"); trashed(\"rdx\") }\n\n/(dec|inc|not|neg|pop) %[er]?([abcd][xlh]|si|di|bp|8|9|10|11|12|13|14|15)/  { trashed(get_reg()) }\n/cpuid/ { trashed(\"rax\"); trashed(\"rbx\"); trashed(\"rcx\"); trashed(\"rdx\") }\n\nEND {\n  if (in_function)\n    print \".cfi_endproc\"\n}\n"
  },
  {
    "path": "user.libc/tools/install.sh",
    "content": "#!/bin/sh\n#\n# This is an actually-safe install command which installs the new\n# file atomically in the new location, rather than overwriting\n# existing files.\n#\n\nusage() {\nprintf \"usage: %s [-D] [-l] [-m mode] src dest\\n\" \"$0\" 1>&2\nexit 1\n}\n\nmkdirp=\nsymlink=\nmode=755\n\nwhile getopts Dlm: name ; do\ncase \"$name\" in\nD) mkdirp=yes ;;\nl) symlink=yes ;;\nm) mode=$OPTARG ;;\n?) usage ;;\nesac\ndone\nshift $(($OPTIND - 1))\n\ntest \"$#\" -eq 2 || usage\nsrc=$1\ndst=$2\ntmp=\"$dst.tmp.$$\"\n\ncase \"$dst\" in\n*/) printf \"%s: %s ends in /\\n\", \"$0\" \"$dst\" 1>&2 ; exit 1 ;;\nesac\n\nset -C\nset -e\n\nif test \"$mkdirp\" ; then\numask 022\ncase \"$2\" in\n*/*) mkdir -p \"${dst%/*}\" ;;\nesac\nfi\n\ntrap 'rm -f \"$tmp\"' EXIT INT QUIT TERM HUP\n\numask 077\n\nif test \"$symlink\" ; then\nln -s \"$1\" \"$tmp\"\nelse\ncat < \"$1\" > \"$tmp\"\nchmod \"$mode\" \"$tmp\"\nfi\n\nmv -f \"$tmp\" \"$2\"\ntest -d \"$2\" && {\nrm -f \"$2/$tmp\"\nprintf \"%s: %s is a directory\\n\" \"$0\" \"$dst\" 1>&2\nexit 1\n}\n\nexit 0\n"
  },
  {
    "path": "user.libc/tools/ld.musl-clang.in",
    "content": "#!/bin/sh\ncc=\"@CC@\"\nlibc_lib=\"@LIBDIR@\"\nldso=\"@LDSO@\"\ncleared=\nshared=\nuserlinkdir=\nuserlink=\n\nfor x ; do\n    test \"$cleared\" || set -- ; cleared=1\n\n    case \"$x\" in\n        -L-user-start)\n            userlinkdir=1\n            ;;\n        -L-user-end)\n            userlinkdir=\n            ;;\n        -L*)\n            test \"$userlinkdir\" && set -- \"$@\" \"$x\"\n            ;;\n        -l-user-start)\n            userlink=1\n            ;;\n        -l-user-end)\n            userlink=\n            ;;\n        crtbegin*.o|crtend*.o)\n            set -- \"$@\" $($cc -print-file-name=$x)\n            ;;\n        -lgcc|-lgcc_eh)\n            file=lib${x#-l}.a\n            set -- \"$@\" $($cc -print-file-name=$file)\n            ;;\n        -l*)\n            test \"$userlink\" && set -- \"$@\" \"$x\"\n            ;;\n        -shared)\n            shared=1\n            set -- \"$@\" -shared\n            ;;\n        -sysroot=*|--sysroot=*)\n            ;;\n        *)\n            set -- \"$@\" \"$x\"\n            ;;\n    esac\ndone\n\nexec $($cc -print-prog-name=ld) -nostdlib \"$@\" -lc -dynamic-linker \"$ldso\"\n"
  },
  {
    "path": "user.libc/tools/mkalltypes.sed",
    "content": "/^TYPEDEF/s/TYPEDEF \\(.*\\) \\([^ ]*\\);$/#if defined(__NEED_\\2) \\&\\& !defined(__DEFINED_\\2)\\\ntypedef \\1 \\2;\\\n#define __DEFINED_\\2\\\n#endif\\\n/\n/^STRUCT/s/STRUCT * \\([^ ]*\\) \\(.*\\);$/#if defined(__NEED_struct_\\1) \\&\\& !defined(__DEFINED_struct_\\1)\\\nstruct \\1 \\2;\\\n#define __DEFINED_struct_\\1\\\n#endif\\\n/\n/^UNION/s/UNION * \\([^ ]*\\) \\(.*\\);$/#if defined(__NEED_union_\\1) \\&\\& !defined(__DEFINED_union_\\1)\\\nunion \\1 \\2;\\\n#define __DEFINED_union_\\1\\\n#endif\\\n/\n"
  },
  {
    "path": "user.libc/tools/musl-clang.in",
    "content": "#!/bin/sh\ncc=\"@CC@\"\nlibc=\"@PREFIX@\"\nlibc_inc=\"@INCDIR@\"\nlibc_lib=\"@LIBDIR@\"\nthisdir=\"`cd \"$(dirname \"$0\")\"; pwd`\"\n\n# prevent clang from running the linker (and erroring) on no input.\nsflags=\neflags=\nfor x ; do\n    case \"$x\" in\n        -l*) input=1 ;;\n        *) input= ;;\n    esac\n    if test \"$input\" ; then\n        sflags=\"-l-user-start\"\n        eflags=\"-l-user-end\"\n        break\n    fi\ndone\n\nexec $cc \\\n    -B\"$thisdir\" \\\n    -fuse-ld=musl-clang \\\n    -static-libgcc \\\n    -nostdinc \\\n    --sysroot \"$libc\" \\\n    -isystem \"$libc_inc\" \\\n    -L-user-start \\\n    $sflags \\\n    \"$@\" \\\n    $eflags \\\n    -L\"$libc_lib\" \\\n    -L-user-end\n"
  },
  {
    "path": "user.libc/tools/musl-gcc.specs.sh",
    "content": "incdir=$1\nlibdir=$2\nldso=$3\ncat <<EOF\n%rename cpp_options old_cpp_options\n\n*cpp_options:\n-nostdinc -isystem $incdir -isystem include%s %(old_cpp_options)\n\n*cc1:\n%(cc1_cpu) -nostdinc -isystem $incdir -isystem include%s\n\n*link_libgcc:\n-L$libdir -L .%s\n\n*libgcc:\nlibgcc.a%s %:if-exists(libgcc_eh.a%s)\n\n*startfile:\n%{!shared: $libdir/Scrt1.o} $libdir/crti.o crtbeginS.o%s\n\n*endfile:\ncrtendS.o%s $libdir/crtn.o\n\n*link:\n-dynamic-linker $ldso -nostdlib %{shared:-shared} %{static:-static} %{rdynamic:-export-dynamic}\n\n*esp_link:\n\n\n*esp_options:\n\n\n*esp_cpp_options:\n\n\nEOF\n"
  },
  {
    "path": "user.libc/tools/version.sh",
    "content": "#!/bin/sh\n\nif test -d .git ; then\nif type git >/dev/null 2>&1 ; then\ngit describe --tags --match 'v[0-9]*' 2>/dev/null \\\n| sed -e 's/^v//' -e 's/-/-git-/'\nelse\nsed 's/$/-git/' < VERSION\nfi\nelse\ncat VERSION\nfi\n"
  },
  {
    "path": "user.libs/libfdt/Makefile",
    "content": "TARGET\t\t= libfdt.a\nLIB_CFLAGS\t= -I./include\n\nSRC_C\t:= $(wildcard src/*.c)\n\nINSTALL_HEADERS = $(wildcard include/libfdt/*.h)\n\ninclude $(projtree)/scripts/lib_build.mk\n"
  },
  {
    "path": "user.libs/libfdt/include/libfdt/fdt.h",
    "content": "#ifndef FDT_H\n#define FDT_H\n/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2006 David Gibson, IBM Corporation.\n * Copyright 2012 Kim Phillips, Freescale Semiconductor.\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifndef __ASSEMBLY__\n\nstruct fdt_header {\n\tfdt32_t magic;\t\t\t /* magic word FDT_MAGIC */\n\tfdt32_t totalsize;\t\t /* total size of DT block */\n\tfdt32_t off_dt_struct;\t\t /* offset to structure */\n\tfdt32_t off_dt_strings;\t\t /* offset to strings */\n\tfdt32_t off_mem_rsvmap;\t\t /* offset to memory reserve map */\n\tfdt32_t version;\t\t /* format version */\n\tfdt32_t last_comp_version;\t /* last compatible version */\n\n\t/* version 2 fields below */\n\tfdt32_t boot_cpuid_phys;\t /* Which physical CPU id we're\n\t\t\t\t\t    booting on */\n\t/* version 3 fields below */\n\tfdt32_t size_dt_strings;\t /* size of the strings block */\n\n\t/* version 17 fields below */\n\tfdt32_t size_dt_struct;\t\t /* size of the structure block */\n};\n\nstruct fdt_reserve_entry {\n\tfdt64_t address;\n\tfdt64_t size;\n};\n\nstruct fdt_node_header {\n\tfdt32_t tag;\n\tchar name[0];\n};\n\nstruct fdt_property {\n\tfdt32_t tag;\n\tfdt32_t len;\n\tfdt32_t nameoff;\n\tchar data[0];\n};\n\n#endif /* !__ASSEMBLY */\n\n#define FDT_MAGIC\t0xd00dfeed\t/* 4: version, 4: total size */\n#define FDT_TAGSIZE\tsizeof(fdt32_t)\n\n#define FDT_BEGIN_NODE\t0x1\t\t/* Start node: full name */\n#define FDT_END_NODE\t0x2\t\t/* End node */\n#define FDT_PROP\t0x3\t\t/* Property: name off,\n\t\t\t\t\t   size, content */\n#define FDT_NOP\t\t0x4\t\t/* nop */\n#define FDT_END\t\t0x9\n\n#define FDT_V1_SIZE\t(7*sizeof(fdt32_t))\n#define FDT_V2_SIZE\t(FDT_V1_SIZE + sizeof(fdt32_t))\n#define FDT_V3_SIZE\t(FDT_V2_SIZE + sizeof(fdt32_t))\n#define FDT_V16_SIZE\tFDT_V3_SIZE\n#define FDT_V17_SIZE\t(FDT_V16_SIZE + sizeof(fdt32_t))\n\n#endif /* FDT_H */\n"
  },
  {
    "path": "user.libs/libfdt/include/libfdt/libfdt.h",
    "content": "#ifndef LIBFDT_H\n#define LIBFDT_H\n/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2006 David Gibson, IBM Corporation.\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include <libfdt/libfdt_env.h>\n#include <libfdt/fdt.h>\n\n#define FDT_FIRST_SUPPORTED_VERSION\t0x02\n#define FDT_LAST_SUPPORTED_VERSION\t0x11\n\n/* Error codes: informative error codes */\n#define FDT_ERR_NOTFOUND\t1\n\t/* FDT_ERR_NOTFOUND: The requested node or property does not exist */\n#define FDT_ERR_EXISTS\t\t2\n\t/* FDT_ERR_EXISTS: Attempted to create a node or property which\n\t * already exists */\n#define FDT_ERR_NOSPACE\t\t3\n\t/* FDT_ERR_NOSPACE: Operation needed to expand the device\n\t * tree, but its buffer did not have sufficient space to\n\t * contain the expanded tree. Use fdt_open_into() to move the\n\t * device tree to a buffer with more space. */\n\n/* Error codes: codes for bad parameters */\n#define FDT_ERR_BADOFFSET\t4\n\t/* FDT_ERR_BADOFFSET: Function was passed a structure block\n\t * offset which is out-of-bounds, or which points to an\n\t * unsuitable part of the structure for the operation. */\n#define FDT_ERR_BADPATH\t\t5\n\t/* FDT_ERR_BADPATH: Function was passed a badly formatted path\n\t * (e.g. missing a leading / for a function which requires an\n\t * absolute path) */\n#define FDT_ERR_BADPHANDLE\t6\n\t/* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle.\n\t * This can be caused either by an invalid phandle property\n\t * length, or the phandle value was either 0 or -1, which are\n\t * not permitted. */\n#define FDT_ERR_BADSTATE\t7\n\t/* FDT_ERR_BADSTATE: Function was passed an incomplete device\n\t * tree created by the sequential-write functions, which is\n\t * not sufficiently complete for the requested operation. */\n\n/* Error codes: codes for bad device tree blobs */\n#define FDT_ERR_TRUNCATED\t8\n\t/* FDT_ERR_TRUNCATED: FDT or a sub-block is improperly\n\t * terminated (overflows, goes outside allowed bounds, or\n\t * isn't properly terminated).  */\n#define FDT_ERR_BADMAGIC\t9\n\t/* FDT_ERR_BADMAGIC: Given \"device tree\" appears not to be a\n\t * device tree at all - it is missing the flattened device\n\t * tree magic number. */\n#define FDT_ERR_BADVERSION\t10\n\t/* FDT_ERR_BADVERSION: Given device tree has a version which\n\t * can't be handled by the requested operation.  For\n\t * read-write functions, this may mean that fdt_open_into() is\n\t * required to convert the tree to the expected version. */\n#define FDT_ERR_BADSTRUCTURE\t11\n\t/* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt\n\t * structure block or other serious error (e.g. misnested\n\t * nodes, or subnodes preceding properties). */\n#define FDT_ERR_BADLAYOUT\t12\n\t/* FDT_ERR_BADLAYOUT: For read-write functions, the given\n\t * device tree has it's sub-blocks in an order that the\n\t * function can't handle (memory reserve map, then structure,\n\t * then strings).  Use fdt_open_into() to reorganize the tree\n\t * into a form suitable for the read-write operations. */\n\n/* \"Can't happen\" error indicating a bug in libfdt */\n#define FDT_ERR_INTERNAL\t13\n\t/* FDT_ERR_INTERNAL: libfdt has failed an internal assertion.\n\t * Should never be returned, if it is, it indicates a bug in\n\t * libfdt itself. */\n\n/* Errors in device tree content */\n#define FDT_ERR_BADNCELLS\t14\n\t/* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells\n\t * or similar property with a bad format or value */\n\n#define FDT_ERR_BADVALUE\t15\n\t/* FDT_ERR_BADVALUE: Device tree has a property with an unexpected\n\t * value. For example: a property expected to contain a string list\n\t * is not NUL-terminated within the length of its value. */\n\n#define FDT_ERR_BADOVERLAY\t16\n\t/* FDT_ERR_BADOVERLAY: The device tree overlay, while\n\t * correctly structured, cannot be applied due to some\n\t * unexpected or missing value, property or node. */\n\n#define FDT_ERR_NOPHANDLES\t17\n\t/* FDT_ERR_NOPHANDLES: The device tree doesn't have any\n\t * phandle available anymore without causing an overflow */\n\n#define FDT_ERR_MAX\t\t17\n\n/**********************************************************************/\n/* Low-level functions (you probably don't need these)                */\n/**********************************************************************/\n\n#ifndef SWIG /* This function is not useful in Python */\nconst void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen);\n#endif\nstatic inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)\n{\n\treturn (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen);\n}\n\nuint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);\n\n/*\n * Alignment helpers:\n *     These helpers access words from a device tree blob.  They're\n *     built to work even with unaligned pointers on platforms (ike\n *     ARM) that don't like unaligned loads and stores\n */\n\nstatic inline uint32_t fdt32_ld(const fdt32_t *p)\n{\n\tfdt32_t v;\n\n\tmemcpy(&v, p, sizeof(v));\n\treturn fdt32_to_cpu(v);\n}\n\nstatic inline uint64_t fdt64_ld(const fdt64_t *p)\n{\n\tfdt64_t v;\n\n\tmemcpy(&v, p, sizeof(v));\n\treturn fdt64_to_cpu(v);\n}\n\n/**********************************************************************/\n/* Traversal functions                                                */\n/**********************************************************************/\n\nint fdt_next_node(const void *fdt, int offset, int *depth);\n\n/**\n * fdt_first_subnode() - get offset of first direct subnode\n *\n * @fdt:\tFDT blob\n * @offset:\tOffset of node to check\n * @return offset of first subnode, or -FDT_ERR_NOTFOUND if there is none\n */\nint fdt_first_subnode(const void *fdt, int offset);\n\n/**\n * fdt_next_subnode() - get offset of next direct subnode\n *\n * After first calling fdt_first_subnode(), call this function repeatedly to\n * get direct subnodes of a parent node.\n *\n * @fdt:\tFDT blob\n * @offset:\tOffset of previous subnode\n * @return offset of next subnode, or -FDT_ERR_NOTFOUND if there are no more\n * subnodes\n */\nint fdt_next_subnode(const void *fdt, int offset);\n\n/**\n * fdt_for_each_subnode - iterate over all subnodes of a parent\n *\n * @node:\tchild node (int, lvalue)\n * @fdt:\tFDT blob (const void *)\n * @parent:\tparent node (int)\n *\n * This is actually a wrapper around a for loop and would be used like so:\n *\n *\tfdt_for_each_subnode(node, fdt, parent) {\n *\t\tUse node\n *\t\t...\n *\t}\n *\n *\tif ((node < 0) && (node != -FDT_ERR_NOT_FOUND)) {\n *\t\tError handling\n *\t}\n *\n * Note that this is implemented as a macro and @node is used as\n * iterator in the loop. The parent variable be constant or even a\n * literal.\n *\n */\n#define fdt_for_each_subnode(node, fdt, parent)\t\t\\\n\tfor (node = fdt_first_subnode(fdt, parent);\t\\\n\t     node >= 0;\t\t\t\t\t\\\n\t     node = fdt_next_subnode(fdt, node))\n\n/**********************************************************************/\n/* General functions                                                  */\n/**********************************************************************/\n#define fdt_get_header(fdt, field) \\\n\t(fdt32_ld(&((const struct fdt_header *)(fdt))->field))\n#define fdt_magic(fdt)\t\t\t(fdt_get_header(fdt, magic))\n#define fdt_totalsize(fdt)\t\t(fdt_get_header(fdt, totalsize))\n#define fdt_off_dt_struct(fdt)\t\t(fdt_get_header(fdt, off_dt_struct))\n#define fdt_off_dt_strings(fdt)\t\t(fdt_get_header(fdt, off_dt_strings))\n#define fdt_off_mem_rsvmap(fdt)\t\t(fdt_get_header(fdt, off_mem_rsvmap))\n#define fdt_version(fdt)\t\t(fdt_get_header(fdt, version))\n#define fdt_last_comp_version(fdt)\t(fdt_get_header(fdt, last_comp_version))\n#define fdt_boot_cpuid_phys(fdt)\t(fdt_get_header(fdt, boot_cpuid_phys))\n#define fdt_size_dt_strings(fdt)\t(fdt_get_header(fdt, size_dt_strings))\n#define fdt_size_dt_struct(fdt)\t\t(fdt_get_header(fdt, size_dt_struct))\n\n#define fdt_set_hdr_(name) \\\n\tstatic inline void fdt_set_##name(void *fdt, uint32_t val) \\\n\t{ \\\n\t\tstruct fdt_header *fdth = (struct fdt_header *)fdt; \\\n\t\tfdth->name = cpu_to_fdt32(val); \\\n\t}\nfdt_set_hdr_(magic);\nfdt_set_hdr_(totalsize);\nfdt_set_hdr_(off_dt_struct);\nfdt_set_hdr_(off_dt_strings);\nfdt_set_hdr_(off_mem_rsvmap);\nfdt_set_hdr_(version);\nfdt_set_hdr_(last_comp_version);\nfdt_set_hdr_(boot_cpuid_phys);\nfdt_set_hdr_(size_dt_strings);\nfdt_set_hdr_(size_dt_struct);\n#undef fdt_set_hdr_\n\n/**\n * fdt_header_size - return the size of the tree's header\n * @fdt: pointer to a flattened device tree\n */\nsize_t fdt_header_size_(uint32_t version);\nstatic inline size_t fdt_header_size(const void *fdt)\n{\n\treturn fdt_header_size_(fdt_version(fdt));\n}\n\n/**\n * fdt_check_header - sanity check a device tree header\n\n * @fdt: pointer to data which might be a flattened device tree\n *\n * fdt_check_header() checks that the given buffer contains what\n * appears to be a flattened device tree, and that the header contains\n * valid information (to the extent that can be determined from the\n * header alone).\n *\n * returns:\n *     0, if the buffer appears to contain a valid device tree\n *     -FDT_ERR_BADMAGIC,\n *     -FDT_ERR_BADVERSION,\n *     -FDT_ERR_BADSTATE,\n *     -FDT_ERR_TRUNCATED, standard meanings, as above\n */\nint fdt_check_header(const void *fdt);\n\n/**\n * fdt_move - move a device tree around in memory\n * @fdt: pointer to the device tree to move\n * @buf: pointer to memory where the device is to be moved\n * @bufsize: size of the memory space at buf\n *\n * fdt_move() relocates, if possible, the device tree blob located at\n * fdt to the buffer at buf of size bufsize.  The buffer may overlap\n * with the existing device tree blob at fdt.  Therefore,\n *     fdt_move(fdt, fdt, fdt_totalsize(fdt))\n * should always succeed.\n *\n * returns:\n *     0, on success\n *     -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree\n *     -FDT_ERR_BADMAGIC,\n *     -FDT_ERR_BADVERSION,\n *     -FDT_ERR_BADSTATE, standard meanings\n */\nint fdt_move(const void *fdt, void *buf, int bufsize);\n\n/**********************************************************************/\n/* Read-only functions                                                */\n/**********************************************************************/\n\nint fdt_check_full(const void *fdt, size_t bufsize);\n\n/**\n * fdt_get_string - retrieve a string from the strings block of a device tree\n * @fdt: pointer to the device tree blob\n * @stroffset: offset of the string within the strings block (native endian)\n * @lenp: optional pointer to return the string's length\n *\n * fdt_get_string() retrieves a pointer to a single string from the\n * strings block of the device tree blob at fdt, and optionally also\n * returns the string's length in *lenp.\n *\n * returns:\n *     a pointer to the string, on success\n *     NULL, if stroffset is out of bounds, or doesn't point to a valid string\n */\nconst char *fdt_get_string(const void *fdt, int stroffset, int *lenp);\n\n/**\n * fdt_string - retrieve a string from the strings block of a device tree\n * @fdt: pointer to the device tree blob\n * @stroffset: offset of the string within the strings block (native endian)\n *\n * fdt_string() retrieves a pointer to a single string from the\n * strings block of the device tree blob at fdt.\n *\n * returns:\n *     a pointer to the string, on success\n *     NULL, if stroffset is out of bounds, or doesn't point to a valid string\n */\nconst char *fdt_string(const void *fdt, int stroffset);\n\n/**\n * fdt_get_max_phandle - retrieves the highest phandle in a tree\n * @fdt: pointer to the device tree blob\n *\n * fdt_get_max_phandle retrieves the highest phandle in the given\n * device tree. This will ignore badly formatted phandles, or phandles\n * with a value of 0 or -1.\n *\n * returns:\n *      the highest phandle on success\n *      0, if no phandle was found in the device tree\n *      -1, if an error occurred\n */\nuint32_t fdt_get_max_phandle(const void *fdt);\n\n/**\n * fdt_num_mem_rsv - retrieve the number of memory reserve map entries\n * @fdt: pointer to the device tree blob\n *\n * Returns the number of entries in the device tree blob's memory\n * reservation map.  This does not include the terminating 0,0 entry\n * or any other (0,0) entries reserved for expansion.\n *\n * returns:\n *     the number of entries\n */\nint fdt_num_mem_rsv(const void *fdt);\n\n/**\n * fdt_get_mem_rsv - retrieve one memory reserve map entry\n * @fdt: pointer to the device tree blob\n * @address, @size: pointers to 64-bit variables\n *\n * On success, *address and *size will contain the address and size of\n * the n-th reserve map entry from the device tree blob, in\n * native-endian format.\n *\n * returns:\n *     0, on success\n *     -FDT_ERR_BADMAGIC,\n *     -FDT_ERR_BADVERSION,\n *     -FDT_ERR_BADSTATE, standard meanings\n */\nint fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);\n\n/**\n * fdt_subnode_offset_namelen - find a subnode based on substring\n * @fdt: pointer to the device tree blob\n * @parentoffset: structure block offset of a node\n * @name: name of the subnode to locate\n * @namelen: number of characters of name to consider\n *\n * Identical to fdt_subnode_offset(), but only examine the first\n * namelen characters of name for matching the subnode name.  This is\n * useful for finding subnodes based on a portion of a larger string,\n * such as a full path.\n */\n#ifndef SWIG /* Not available in Python */\nint fdt_subnode_offset_namelen(const void *fdt, int parentoffset,\n\t\t\t       const char *name, int namelen);\n#endif\n/**\n * fdt_subnode_offset - find a subnode of a given node\n * @fdt: pointer to the device tree blob\n * @parentoffset: structure block offset of a node\n * @name: name of the subnode to locate\n *\n * fdt_subnode_offset() finds a subnode of the node at structure block\n * offset parentoffset with the given name.  name may include a unit\n * address, in which case fdt_subnode_offset() will find the subnode\n * with that unit address, or the unit address may be omitted, in\n * which case fdt_subnode_offset() will find an arbitrary subnode\n * whose name excluding unit address matches the given name.\n *\n * returns:\n *\tstructure block offset of the requested subnode (>=0), on success\n *\t-FDT_ERR_NOTFOUND, if the requested subnode does not exist\n *\t-FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE\n *\t\ttag\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings.\n */\nint fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);\n\n/**\n * fdt_path_offset_namelen - find a tree node by its full path\n * @fdt: pointer to the device tree blob\n * @path: full path of the node to locate\n * @namelen: number of characters of path to consider\n *\n * Identical to fdt_path_offset(), but only consider the first namelen\n * characters of path as the path name.\n */\n#ifndef SWIG /* Not available in Python */\nint fdt_path_offset_namelen(const void *fdt, const char *path, int namelen);\n#endif\n\n/**\n * fdt_path_offset - find a tree node by its full path\n * @fdt: pointer to the device tree blob\n * @path: full path of the node to locate\n *\n * fdt_path_offset() finds a node of a given path in the device tree.\n * Each path component may omit the unit address portion, but the\n * results of this are undefined if any such path component is\n * ambiguous (that is if there are multiple nodes at the relevant\n * level matching the given component, differentiated only by unit\n * address).\n *\n * returns:\n *\tstructure block offset of the node with the requested path (>=0), on\n *\t\tsuccess\n *\t-FDT_ERR_BADPATH, given path does not begin with '/' or is invalid\n *\t-FDT_ERR_NOTFOUND, if the requested node does not exist\n *      -FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings.\n */\nint fdt_path_offset(const void *fdt, const char *path);\n\n/**\n * fdt_get_name - retrieve the name of a given node\n * @fdt: pointer to the device tree blob\n * @nodeoffset: structure block offset of the starting node\n * @lenp: pointer to an integer variable (will be overwritten) or NULL\n *\n * fdt_get_name() retrieves the name (including unit address) of the\n * device tree node at structure block offset nodeoffset.  If lenp is\n * non-NULL, the length of this name is also returned, in the integer\n * pointed to by lenp.\n *\n * returns:\n *\tpointer to the node's name, on success\n *\t\tIf lenp is non-NULL, *lenp contains the length of that name\n *\t\t\t(>=0)\n *\tNULL, on error\n *\t\tif lenp is non-NULL *lenp contains an error code (<0):\n *\t\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE\n *\t\t\ttag\n *\t\t-FDT_ERR_BADMAGIC,\n *\t\t-FDT_ERR_BADVERSION,\n *\t\t-FDT_ERR_BADSTATE, standard meanings\n */\nconst char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);\n\n/**\n * fdt_first_property_offset - find the offset of a node's first property\n * @fdt: pointer to the device tree blob\n * @nodeoffset: structure block offset of a node\n *\n * fdt_first_property_offset() finds the first property of the node at\n * the given structure block offset.\n *\n * returns:\n *\tstructure block offset of the property (>=0), on success\n *\t-FDT_ERR_NOTFOUND, if the requested node has no properties\n *\t-FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_BEGIN_NODE tag\n *      -FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings.\n */\nint fdt_first_property_offset(const void *fdt, int nodeoffset);\n\n/**\n * fdt_next_property_offset - step through a node's properties\n * @fdt: pointer to the device tree blob\n * @offset: structure block offset of a property\n *\n * fdt_next_property_offset() finds the property immediately after the\n * one at the given structure block offset.  This will be a property\n * of the same node as the given property.\n *\n * returns:\n *\tstructure block offset of the next property (>=0), on success\n *\t-FDT_ERR_NOTFOUND, if the given property is the last in its node\n *\t-FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_PROP tag\n *      -FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings.\n */\nint fdt_next_property_offset(const void *fdt, int offset);\n\n/**\n * fdt_for_each_property_offset - iterate over all properties of a node\n *\n * @property_offset:\tproperty offset (int, lvalue)\n * @fdt:\t\tFDT blob (const void *)\n * @node:\t\tnode offset (int)\n *\n * This is actually a wrapper around a for loop and would be used like so:\n *\n *\tfdt_for_each_property_offset(property, fdt, node) {\n *\t\tUse property\n *\t\t...\n *\t}\n *\n *\tif ((property < 0) && (property != -FDT_ERR_NOT_FOUND)) {\n *\t\tError handling\n *\t}\n *\n * Note that this is implemented as a macro and property is used as\n * iterator in the loop. The node variable can be constant or even a\n * literal.\n */\n#define fdt_for_each_property_offset(property, fdt, node)\t\\\n\tfor (property = fdt_first_property_offset(fdt, node);\t\\\n\t     property >= 0;\t\t\t\t\t\\\n\t     property = fdt_next_property_offset(fdt, property))\n\n/**\n * fdt_get_property_by_offset - retrieve the property at a given offset\n * @fdt: pointer to the device tree blob\n * @offset: offset of the property to retrieve\n * @lenp: pointer to an integer variable (will be overwritten) or NULL\n *\n * fdt_get_property_by_offset() retrieves a pointer to the\n * fdt_property structure within the device tree blob at the given\n * offset.  If lenp is non-NULL, the length of the property value is\n * also returned, in the integer pointed to by lenp.\n *\n * Note that this code only works on device tree versions >= 16. fdt_getprop()\n * works on all versions.\n *\n * returns:\n *\tpointer to the structure representing the property\n *\t\tif lenp is non-NULL, *lenp contains the length of the property\n *\t\tvalue (>=0)\n *\tNULL, on error\n *\t\tif lenp is non-NULL, *lenp contains an error code (<0):\n *\t\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag\n *\t\t-FDT_ERR_BADMAGIC,\n *\t\t-FDT_ERR_BADVERSION,\n *\t\t-FDT_ERR_BADSTATE,\n *\t\t-FDT_ERR_BADSTRUCTURE,\n *\t\t-FDT_ERR_TRUNCATED, standard meanings\n */\nconst struct fdt_property *fdt_get_property_by_offset(const void *fdt,\n\t\t\t\t\t\t      int offset,\n\t\t\t\t\t\t      int *lenp);\n\n/**\n * fdt_get_property_namelen - find a property based on substring\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to find\n * @name: name of the property to find\n * @namelen: number of characters of name to consider\n * @lenp: pointer to an integer variable (will be overwritten) or NULL\n *\n * Identical to fdt_get_property(), but only examine the first namelen\n * characters of name for matching the property name.\n */\n#ifndef SWIG /* Not available in Python */\nconst struct fdt_property *fdt_get_property_namelen(const void *fdt,\n\t\t\t\t\t\t    int nodeoffset,\n\t\t\t\t\t\t    const char *name,\n\t\t\t\t\t\t    int namelen, int *lenp);\n#endif\n\n/**\n * fdt_get_property - find a given property in a given node\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to find\n * @name: name of the property to find\n * @lenp: pointer to an integer variable (will be overwritten) or NULL\n *\n * fdt_get_property() retrieves a pointer to the fdt_property\n * structure within the device tree blob corresponding to the property\n * named 'name' of the node at offset nodeoffset.  If lenp is\n * non-NULL, the length of the property value is also returned, in the\n * integer pointed to by lenp.\n *\n * returns:\n *\tpointer to the structure representing the property\n *\t\tif lenp is non-NULL, *lenp contains the length of the property\n *\t\tvalue (>=0)\n *\tNULL, on error\n *\t\tif lenp is non-NULL, *lenp contains an error code (<0):\n *\t\t-FDT_ERR_NOTFOUND, node does not have named property\n *\t\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE\n *\t\t\ttag\n *\t\t-FDT_ERR_BADMAGIC,\n *\t\t-FDT_ERR_BADVERSION,\n *\t\t-FDT_ERR_BADSTATE,\n *\t\t-FDT_ERR_BADSTRUCTURE,\n *\t\t-FDT_ERR_TRUNCATED, standard meanings\n */\nconst struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset,\n\t\t\t\t\t    const char *name, int *lenp);\nstatic inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,\n\t\t\t\t\t\t      const char *name,\n\t\t\t\t\t\t      int *lenp)\n{\n\treturn (struct fdt_property *)(uintptr_t)\n\t\tfdt_get_property(fdt, nodeoffset, name, lenp);\n}\n\n/**\n * fdt_getprop_by_offset - retrieve the value of a property at a given offset\n * @fdt: pointer to the device tree blob\n * @ffset: offset of the property to read\n * @namep: pointer to a string variable (will be overwritten) or NULL\n * @lenp: pointer to an integer variable (will be overwritten) or NULL\n *\n * fdt_getprop_by_offset() retrieves a pointer to the value of the\n * property at structure block offset 'offset' (this will be a pointer\n * to within the device blob itself, not a copy of the value).  If\n * lenp is non-NULL, the length of the property value is also\n * returned, in the integer pointed to by lenp.  If namep is non-NULL,\n * the property's namne will also be returned in the char * pointed to\n * by namep (this will be a pointer to within the device tree's string\n * block, not a new copy of the name).\n *\n * returns:\n *\tpointer to the property's value\n *\t\tif lenp is non-NULL, *lenp contains the length of the property\n *\t\tvalue (>=0)\n *\t\tif namep is non-NULL *namep contiains a pointer to the property\n *\t\tname.\n *\tNULL, on error\n *\t\tif lenp is non-NULL, *lenp contains an error code (<0):\n *\t\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag\n *\t\t-FDT_ERR_BADMAGIC,\n *\t\t-FDT_ERR_BADVERSION,\n *\t\t-FDT_ERR_BADSTATE,\n *\t\t-FDT_ERR_BADSTRUCTURE,\n *\t\t-FDT_ERR_TRUNCATED, standard meanings\n */\n#ifndef SWIG /* This function is not useful in Python */\nconst void *fdt_getprop_by_offset(const void *fdt, int offset,\n\t\t\t\t  const char **namep, int *lenp);\n#endif\n\n/**\n * fdt_getprop_namelen - get property value based on substring\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to find\n * @name: name of the property to find\n * @namelen: number of characters of name to consider\n * @lenp: pointer to an integer variable (will be overwritten) or NULL\n *\n * Identical to fdt_getprop(), but only examine the first namelen\n * characters of name for matching the property name.\n */\n#ifndef SWIG /* Not available in Python */\nconst void *fdt_getprop_namelen(const void *fdt, int nodeoffset,\n\t\t\t\tconst char *name, int namelen, int *lenp);\nstatic inline void *fdt_getprop_namelen_w(void *fdt, int nodeoffset,\n\t\t\t\t\t  const char *name, int namelen,\n\t\t\t\t\t  int *lenp)\n{\n\treturn (void *)(uintptr_t)fdt_getprop_namelen(fdt, nodeoffset, name,\n\t\t\t\t\t\t      namelen, lenp);\n}\n#endif\n\n/**\n * fdt_getprop - retrieve the value of a given property\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to find\n * @name: name of the property to find\n * @lenp: pointer to an integer variable (will be overwritten) or NULL\n *\n * fdt_getprop() retrieves a pointer to the value of the property\n * named 'name' of the node at offset nodeoffset (this will be a\n * pointer to within the device blob itself, not a copy of the value).\n * If lenp is non-NULL, the length of the property value is also\n * returned, in the integer pointed to by lenp.\n *\n * returns:\n *\tpointer to the property's value\n *\t\tif lenp is non-NULL, *lenp contains the length of the property\n *\t\tvalue (>=0)\n *\tNULL, on error\n *\t\tif lenp is non-NULL, *lenp contains an error code (<0):\n *\t\t-FDT_ERR_NOTFOUND, node does not have named property\n *\t\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE\n *\t\t\ttag\n *\t\t-FDT_ERR_BADMAGIC,\n *\t\t-FDT_ERR_BADVERSION,\n *\t\t-FDT_ERR_BADSTATE,\n *\t\t-FDT_ERR_BADSTRUCTURE,\n *\t\t-FDT_ERR_TRUNCATED, standard meanings\n */\nconst void *fdt_getprop(const void *fdt, int nodeoffset,\n\t\t\tconst char *name, int *lenp);\nstatic inline void *fdt_getprop_w(void *fdt, int nodeoffset,\n\t\t\t\t  const char *name, int *lenp)\n{\n\treturn (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp);\n}\n\n/**\n * fdt_get_phandle - retrieve the phandle of a given node\n * @fdt: pointer to the device tree blob\n * @nodeoffset: structure block offset of the node\n *\n * fdt_get_phandle() retrieves the phandle of the device tree node at\n * structure block offset nodeoffset.\n *\n * returns:\n *\tthe phandle of the node at nodeoffset, on success (!= 0, != -1)\n *\t0, if the node has no phandle, or another error occurs\n */\nuint32_t fdt_get_phandle(const void *fdt, int nodeoffset);\n\n/**\n * fdt_get_alias_namelen - get alias based on substring\n * @fdt: pointer to the device tree blob\n * @name: name of the alias th look up\n * @namelen: number of characters of name to consider\n *\n * Identical to fdt_get_alias(), but only examine the first namelen\n * characters of name for matching the alias name.\n */\n#ifndef SWIG /* Not available in Python */\nconst char *fdt_get_alias_namelen(const void *fdt,\n\t\t\t\t  const char *name, int namelen);\n#endif\n\n/**\n * fdt_get_alias - retrieve the path referenced by a given alias\n * @fdt: pointer to the device tree blob\n * @name: name of the alias th look up\n *\n * fdt_get_alias() retrieves the value of a given alias.  That is, the\n * value of the property named 'name' in the node /aliases.\n *\n * returns:\n *\ta pointer to the expansion of the alias named 'name', if it exists\n *\tNULL, if the given alias or the /aliases node does not exist\n */\nconst char *fdt_get_alias(const void *fdt, const char *name);\n\n/**\n * fdt_get_path - determine the full path of a node\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose path to find\n * @buf: character buffer to contain the returned path (will be overwritten)\n * @buflen: size of the character buffer at buf\n *\n * fdt_get_path() computes the full path of the node at offset\n * nodeoffset, and records that path in the buffer at buf.\n *\n * NOTE: This function is expensive, as it must scan the device tree\n * structure from the start to nodeoffset.\n *\n * returns:\n *\t0, on success\n *\t\tbuf contains the absolute path of the node at\n *\t\tnodeoffset, as a NUL-terminated string.\n *\t-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag\n *\t-FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1)\n *\t\tcharacters and will not fit in the given buffer.\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE, standard meanings\n */\nint fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen);\n\n/**\n * fdt_supernode_atdepth_offset - find a specific ancestor of a node\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose parent to find\n * @supernodedepth: depth of the ancestor to find\n * @nodedepth: pointer to an integer variable (will be overwritten) or NULL\n *\n * fdt_supernode_atdepth_offset() finds an ancestor of the given node\n * at a specific depth from the root (where the root itself has depth\n * 0, its immediate subnodes depth 1 and so forth).  So\n *\tfdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL);\n * will always return 0, the offset of the root node.  If the node at\n * nodeoffset has depth D, then:\n *\tfdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL);\n * will return nodeoffset itself.\n *\n * NOTE: This function is expensive, as it must scan the device tree\n * structure from the start to nodeoffset.\n *\n * returns:\n *\tstructure block offset of the node at node offset's ancestor\n *\t\tof depth supernodedepth (>=0), on success\n *\t-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag\n *\t-FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of\n *\t\tnodeoffset\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE, standard meanings\n */\nint fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,\n\t\t\t\t int supernodedepth, int *nodedepth);\n\n/**\n * fdt_node_depth - find the depth of a given node\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose parent to find\n *\n * fdt_node_depth() finds the depth of a given node.  The root node\n * has depth 0, its immediate subnodes depth 1 and so forth.\n *\n * NOTE: This function is expensive, as it must scan the device tree\n * structure from the start to nodeoffset.\n *\n * returns:\n *\tdepth of the node at nodeoffset (>=0), on success\n *\t-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE, standard meanings\n */\nint fdt_node_depth(const void *fdt, int nodeoffset);\n\n/**\n * fdt_parent_offset - find the parent of a given node\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose parent to find\n *\n * fdt_parent_offset() locates the parent node of a given node (that\n * is, it finds the offset of the node which contains the node at\n * nodeoffset as a subnode).\n *\n * NOTE: This function is expensive, as it must scan the device tree\n * structure from the start to nodeoffset, *twice*.\n *\n * returns:\n *\tstructure block offset of the parent of the node at nodeoffset\n *\t\t(>=0), on success\n *\t-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE, standard meanings\n */\nint fdt_parent_offset(const void *fdt, int nodeoffset);\n\n/**\n * fdt_node_offset_by_prop_value - find nodes with a given property value\n * @fdt: pointer to the device tree blob\n * @startoffset: only find nodes after this offset\n * @propname: property name to check\n * @propval: property value to search for\n * @proplen: length of the value in propval\n *\n * fdt_node_offset_by_prop_value() returns the offset of the first\n * node after startoffset, which has a property named propname whose\n * value is of length proplen and has value equal to propval; or if\n * startoffset is -1, the very first such node in the tree.\n *\n * To iterate through all nodes matching the criterion, the following\n * idiom can be used:\n *\toffset = fdt_node_offset_by_prop_value(fdt, -1, propname,\n *\t\t\t\t\t       propval, proplen);\n *\twhile (offset != -FDT_ERR_NOTFOUND) {\n *\t\t// other code here\n *\t\toffset = fdt_node_offset_by_prop_value(fdt, offset, propname,\n *\t\t\t\t\t\t       propval, proplen);\n *\t}\n *\n * Note the -1 in the first call to the function, if 0 is used here\n * instead, the function will never locate the root node, even if it\n * matches the criterion.\n *\n * returns:\n *\tstructure block offset of the located node (>= 0, >startoffset),\n *\t\t on success\n *\t-FDT_ERR_NOTFOUND, no node matching the criterion exists in the\n *\t\ttree after startoffset\n *\t-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE, standard meanings\n */\nint fdt_node_offset_by_prop_value(const void *fdt, int startoffset,\n\t\t\t\t  const char *propname,\n\t\t\t\t  const void *propval, int proplen);\n\n/**\n * fdt_node_offset_by_phandle - find the node with a given phandle\n * @fdt: pointer to the device tree blob\n * @phandle: phandle value\n *\n * fdt_node_offset_by_phandle() returns the offset of the node\n * which has the given phandle value.  If there is more than one node\n * in the tree with the given phandle (an invalid tree), results are\n * undefined.\n *\n * returns:\n *\tstructure block offset of the located node (>= 0), on success\n *\t-FDT_ERR_NOTFOUND, no node with that phandle exists\n *\t-FDT_ERR_BADPHANDLE, given phandle value was invalid (0 or -1)\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE, standard meanings\n */\nint fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);\n\n/**\n * fdt_node_check_compatible: check a node's compatible property\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of a tree node\n * @compatible: string to match against\n *\n *\n * fdt_node_check_compatible() returns 0 if the given node contains a\n * 'compatible' property with the given string as one of its elements,\n * it returns non-zero otherwise, or on error.\n *\n * returns:\n *\t0, if the node has a 'compatible' property listing the given string\n *\t1, if the node has a 'compatible' property, but it does not list\n *\t\tthe given string\n *\t-FDT_ERR_NOTFOUND, if the given node has no 'compatible' property\n *\t-FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE, standard meanings\n */\nint fdt_node_check_compatible(const void *fdt, int nodeoffset,\n\t\t\t      const char *compatible);\n\n/**\n * fdt_node_offset_by_compatible - find nodes with a given 'compatible' value\n * @fdt: pointer to the device tree blob\n * @startoffset: only find nodes after this offset\n * @compatible: 'compatible' string to match against\n *\n * fdt_node_offset_by_compatible() returns the offset of the first\n * node after startoffset, which has a 'compatible' property which\n * lists the given compatible string; or if startoffset is -1, the\n * very first such node in the tree.\n *\n * To iterate through all nodes matching the criterion, the following\n * idiom can be used:\n *\toffset = fdt_node_offset_by_compatible(fdt, -1, compatible);\n *\twhile (offset != -FDT_ERR_NOTFOUND) {\n *\t\t// other code here\n *\t\toffset = fdt_node_offset_by_compatible(fdt, offset, compatible);\n *\t}\n *\n * Note the -1 in the first call to the function, if 0 is used here\n * instead, the function will never locate the root node, even if it\n * matches the criterion.\n *\n * returns:\n *\tstructure block offset of the located node (>= 0, >startoffset),\n *\t\t on success\n *\t-FDT_ERR_NOTFOUND, no node matching the criterion exists in the\n *\t\ttree after startoffset\n *\t-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE, standard meanings\n */\nint fdt_node_offset_by_compatible(const void *fdt, int startoffset,\n\t\t\t\t  const char *compatible);\n\n/**\n * fdt_stringlist_contains - check a string list property for a string\n * @strlist: Property containing a list of strings to check\n * @listlen: Length of property\n * @str: String to search for\n *\n * This is a utility function provided for convenience. The list contains\n * one or more strings, each terminated by \\0, as is found in a device tree\n * \"compatible\" property.\n *\n * @return: 1 if the string is found in the list, 0 not found, or invalid list\n */\nint fdt_stringlist_contains(const char *strlist, int listlen, const char *str);\n\n/**\n * fdt_stringlist_count - count the number of strings in a string list\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of a tree node\n * @property: name of the property containing the string list\n * @return:\n *   the number of strings in the given property\n *   -FDT_ERR_BADVALUE if the property value is not NUL-terminated\n *   -FDT_ERR_NOTFOUND if the property does not exist\n */\nint fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property);\n\n/**\n * fdt_stringlist_search - find a string in a string list and return its index\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of a tree node\n * @property: name of the property containing the string list\n * @string: string to look up in the string list\n *\n * Note that it is possible for this function to succeed on property values\n * that are not NUL-terminated. That's because the function will stop after\n * finding the first occurrence of @string. This can for example happen with\n * small-valued cell properties, such as #address-cells, when searching for\n * the empty string.\n *\n * @return:\n *   the index of the string in the list of strings\n *   -FDT_ERR_BADVALUE if the property value is not NUL-terminated\n *   -FDT_ERR_NOTFOUND if the property does not exist or does not contain\n *                     the given string\n */\nint fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property,\n\t\t\t  const char *string);\n\n/**\n * fdt_stringlist_get() - obtain the string at a given index in a string list\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of a tree node\n * @property: name of the property containing the string list\n * @index: index of the string to return\n * @lenp: return location for the string length or an error code on failure\n *\n * Note that this will successfully extract strings from properties with\n * non-NUL-terminated values. For example on small-valued cell properties\n * this function will return the empty string.\n *\n * If non-NULL, the length of the string (on success) or a negative error-code\n * (on failure) will be stored in the integer pointer to by lenp.\n *\n * @return:\n *   A pointer to the string at the given index in the string list or NULL on\n *   failure. On success the length of the string will be stored in the memory\n *   location pointed to by the lenp parameter, if non-NULL. On failure one of\n *   the following negative error codes will be returned in the lenp parameter\n *   (if non-NULL):\n *     -FDT_ERR_BADVALUE if the property value is not NUL-terminated\n *     -FDT_ERR_NOTFOUND if the property does not exist\n */\nconst char *fdt_stringlist_get(const void *fdt, int nodeoffset,\n\t\t\t       const char *property, int index,\n\t\t\t       int *lenp);\n\n/**********************************************************************/\n/* Read-only functions (addressing related)                           */\n/**********************************************************************/\n\n/**\n * FDT_MAX_NCELLS - maximum value for #address-cells and #size-cells\n *\n * This is the maximum value for #address-cells, #size-cells and\n * similar properties that will be processed by libfdt.  IEE1275\n * requires that OF implementations handle values up to 4.\n * Implementations may support larger values, but in practice higher\n * values aren't used.\n */\n#define FDT_MAX_NCELLS\t\t4\n\n/**\n * fdt_address_cells - retrieve address size for a bus represented in the tree\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node to find the address size for\n *\n * When the node has a valid #address-cells property, returns its value.\n *\n * returns:\n *\t0 <= n < FDT_MAX_NCELLS, on success\n *      2, if the node has no #address-cells property\n *      -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid\n *\t\t#address-cells property\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nint fdt_address_cells(const void *fdt, int nodeoffset);\n\n/**\n * fdt_size_cells - retrieve address range size for a bus represented in the\n *                  tree\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node to find the address range size for\n *\n * When the node has a valid #size-cells property, returns its value.\n *\n * returns:\n *\t0 <= n < FDT_MAX_NCELLS, on success\n *      2, if the node has no #size-cells property\n *      -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid\n *\t\t#size-cells property\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nint fdt_size_cells(const void *fdt, int nodeoffset);\n\n\n/**********************************************************************/\n/* Write-in-place functions                                           */\n/**********************************************************************/\n\n/**\n * fdt_setprop_inplace_namelen_partial - change a property's value,\n *                                       but not its size\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n * @namelen: number of characters of name to consider\n * @idx: index of the property to change in the array\n * @val: pointer to data to replace the property value with\n * @len: length of the property value\n *\n * Identical to fdt_setprop_inplace(), but modifies the given property\n * starting from the given index, and using only the first characters\n * of the name. It is useful when you want to manipulate only one value of\n * an array and you have a string that doesn't end with \\0.\n */\n#ifndef SWIG /* Not available in Python */\nint fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset,\n\t\t\t\t\tconst char *name, int namelen,\n\t\t\t\t\tuint32_t idx, const void *val,\n\t\t\t\t\tint len);\n#endif\n\n/**\n * fdt_setprop_inplace - change a property's value, but not its size\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n * @val: pointer to data to replace the property value with\n * @len: length of the property value\n *\n * fdt_setprop_inplace() replaces the value of a given property with\n * the data in val, of length len.  This function cannot change the\n * size of a property, and so will only work if len is equal to the\n * current length of the property.\n *\n * This function will alter only the bytes in the blob which contain\n * the given property value, and will not alter or move any other part\n * of the tree.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, if len is not equal to the property's current length\n *\t-FDT_ERR_NOTFOUND, node does not have the named property\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\n#ifndef SWIG /* Not available in Python */\nint fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,\n\t\t\tconst void *val, int len);\n#endif\n\n/**\n * fdt_setprop_inplace_u32 - change the value of a 32-bit integer property\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n * @val: 32-bit integer value to replace the property with\n *\n * fdt_setprop_inplace_u32() replaces the value of a given property\n * with the 32-bit integer value in val, converting val to big-endian\n * if necessary.  This function cannot change the size of a property,\n * and so will only work if the property already exists and has length\n * 4.\n *\n * This function will alter only the bytes in the blob which contain\n * the given property value, and will not alter or move any other part\n * of the tree.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, if the property's length is not equal to 4\n *\t-FDT_ERR_NOTFOUND, node does not have the named property\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nstatic inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset,\n\t\t\t\t\t  const char *name, uint32_t val)\n{\n\tfdt32_t tmp = cpu_to_fdt32(val);\n\treturn fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp));\n}\n\n/**\n * fdt_setprop_inplace_u64 - change the value of a 64-bit integer property\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n * @val: 64-bit integer value to replace the property with\n *\n * fdt_setprop_inplace_u64() replaces the value of a given property\n * with the 64-bit integer value in val, converting val to big-endian\n * if necessary.  This function cannot change the size of a property,\n * and so will only work if the property already exists and has length\n * 8.\n *\n * This function will alter only the bytes in the blob which contain\n * the given property value, and will not alter or move any other part\n * of the tree.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, if the property's length is not equal to 8\n *\t-FDT_ERR_NOTFOUND, node does not have the named property\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nstatic inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset,\n\t\t\t\t\t  const char *name, uint64_t val)\n{\n\tfdt64_t tmp = cpu_to_fdt64(val);\n\treturn fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp));\n}\n\n/**\n * fdt_setprop_inplace_cell - change the value of a single-cell property\n *\n * This is an alternative name for fdt_setprop_inplace_u32()\n */\nstatic inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,\n\t\t\t\t\t   const char *name, uint32_t val)\n{\n\treturn fdt_setprop_inplace_u32(fdt, nodeoffset, name, val);\n}\n\n/**\n * fdt_nop_property - replace a property with nop tags\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to nop\n * @name: name of the property to nop\n *\n * fdt_nop_property() will replace a given property's representation\n * in the blob with FDT_NOP tags, effectively removing it from the\n * tree.\n *\n * This function will alter only the bytes in the blob which contain\n * the property, and will not alter or move any other part of the\n * tree.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOTFOUND, node does not have the named property\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nint fdt_nop_property(void *fdt, int nodeoffset, const char *name);\n\n/**\n * fdt_nop_node - replace a node (subtree) with nop tags\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node to nop\n *\n * fdt_nop_node() will replace a given node's representation in the\n * blob, including all its subnodes, if any, with FDT_NOP tags,\n * effectively removing it from the tree.\n *\n * This function will alter only the bytes in the blob which contain\n * the node and its properties and subnodes, and will not alter or\n * move any other part of the tree.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nint fdt_nop_node(void *fdt, int nodeoffset);\n\n/**********************************************************************/\n/* Sequential write functions                                         */\n/**********************************************************************/\n\nint fdt_create(void *buf, int bufsize);\nint fdt_resize(void *fdt, void *buf, int bufsize);\nint fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);\nint fdt_finish_reservemap(void *fdt);\nint fdt_begin_node(void *fdt, const char *name);\nint fdt_property(void *fdt, const char *name, const void *val, int len);\nstatic inline int fdt_property_u32(void *fdt, const char *name, uint32_t val)\n{\n\tfdt32_t tmp = cpu_to_fdt32(val);\n\treturn fdt_property(fdt, name, &tmp, sizeof(tmp));\n}\nstatic inline int fdt_property_u64(void *fdt, const char *name, uint64_t val)\n{\n\tfdt64_t tmp = cpu_to_fdt64(val);\n\treturn fdt_property(fdt, name, &tmp, sizeof(tmp));\n}\n\n#ifndef SWIG /* Not available in Python */\nstatic inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)\n{\n\treturn fdt_property_u32(fdt, name, val);\n}\n#endif\n\n/**\n * fdt_property_placeholder - add a new property and return a ptr to its value\n *\n * @fdt: pointer to the device tree blob\n * @name: name of property to add\n * @len: length of property value in bytes\n * @valp: returns a pointer to where where the value should be placed\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_NOSPACE, standard meanings\n */\nint fdt_property_placeholder(void *fdt, const char *name, int len, void **valp);\n\n#define fdt_property_string(fdt, name, str) \\\n\tfdt_property(fdt, name, str, strlen(str)+1)\nint fdt_end_node(void *fdt);\nint fdt_finish(void *fdt);\n\n/**********************************************************************/\n/* Read-write functions                                               */\n/**********************************************************************/\n\nint fdt_create_empty_tree(void *buf, int bufsize);\nint fdt_open_into(const void *fdt, void *buf, int bufsize);\nint fdt_pack(void *fdt);\n\n/**\n * fdt_add_mem_rsv - add one memory reserve map entry\n * @fdt: pointer to the device tree blob\n * @address, @size: 64-bit values (native endian)\n *\n * Adds a reserve map entry to the given blob reserving a region at\n * address address of length size.\n *\n * This function will insert data into the reserve map and will\n * therefore change the indexes of some entries in the table.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there is insufficient free space in the blob to\n *\t\tcontain the new reservation entry\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nint fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);\n\n/**\n * fdt_del_mem_rsv - remove a memory reserve map entry\n * @fdt: pointer to the device tree blob\n * @n: entry to remove\n *\n * fdt_del_mem_rsv() removes the n-th memory reserve map entry from\n * the blob.\n *\n * This function will delete data from the reservation table and will\n * therefore change the indexes of some entries in the table.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOTFOUND, there is no entry of the given index (i.e. there\n *\t\tare less than n+1 reserve map entries)\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nint fdt_del_mem_rsv(void *fdt, int n);\n\n/**\n * fdt_set_name - change the name of a given node\n * @fdt: pointer to the device tree blob\n * @nodeoffset: structure block offset of a node\n * @name: name to give the node\n *\n * fdt_set_name() replaces the name (including unit address, if any)\n * of the given node with the given string.  NOTE: this function can't\n * efficiently check if the new name is unique amongst the given\n * node's siblings; results are undefined if this function is invoked\n * with a name equal to one of the given node's siblings.\n *\n * This function may insert or delete data from the blob, and will\n * therefore change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there is insufficient free space in the blob\n *\t\tto contain the new name\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE, standard meanings\n */\nint fdt_set_name(void *fdt, int nodeoffset, const char *name);\n\n/**\n * fdt_setprop - create or change a property\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n * @val: pointer to data to set the property value to\n * @len: length of the property value\n *\n * fdt_setprop() sets the value of the named property in the given\n * node to the given value and length, creating the property if it\n * does not already exist.\n *\n * This function may insert or delete data from the blob, and will\n * therefore change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there is insufficient free space in the blob to\n *\t\tcontain the new property value\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nint fdt_setprop(void *fdt, int nodeoffset, const char *name,\n\t\tconst void *val, int len);\n\n/**\n * fdt_setprop_placeholder - allocate space for a property\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n * @len: length of the property value\n * @prop_data: return pointer to property data\n *\n * fdt_setprop_placeholer() allocates the named property in the given node.\n * If the property exists it is resized. In either case a pointer to the\n * property data is returned.\n *\n * This function may insert or delete data from the blob, and will\n * therefore change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there is insufficient free space in the blob to\n *\t\tcontain the new property value\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nint fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,\n\t\t\t    int len, void **prop_data);\n\n/**\n * fdt_setprop_u32 - set a property to a 32-bit integer\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n * @val: 32-bit integer value for the property (native endian)\n *\n * fdt_setprop_u32() sets the value of the named property in the given\n * node to the given 32-bit integer value (converting to big-endian if\n * necessary), or creates a new property with that value if it does\n * not already exist.\n *\n * This function may insert or delete data from the blob, and will\n * therefore change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there is insufficient free space in the blob to\n *\t\tcontain the new property value\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nstatic inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name,\n\t\t\t\t  uint32_t val)\n{\n\tfdt32_t tmp = cpu_to_fdt32(val);\n\treturn fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));\n}\n\n/**\n * fdt_setprop_u64 - set a property to a 64-bit integer\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n * @val: 64-bit integer value for the property (native endian)\n *\n * fdt_setprop_u64() sets the value of the named property in the given\n * node to the given 64-bit integer value (converting to big-endian if\n * necessary), or creates a new property with that value if it does\n * not already exist.\n *\n * This function may insert or delete data from the blob, and will\n * therefore change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there is insufficient free space in the blob to\n *\t\tcontain the new property value\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nstatic inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name,\n\t\t\t\t  uint64_t val)\n{\n\tfdt64_t tmp = cpu_to_fdt64(val);\n\treturn fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));\n}\n\n/**\n * fdt_setprop_cell - set a property to a single cell value\n *\n * This is an alternative name for fdt_setprop_u32()\n */\nstatic inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,\n\t\t\t\t   uint32_t val)\n{\n\treturn fdt_setprop_u32(fdt, nodeoffset, name, val);\n}\n\n/**\n * fdt_setprop_string - set a property to a string value\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n * @str: string value for the property\n *\n * fdt_setprop_string() sets the value of the named property in the\n * given node to the given string value (using the length of the\n * string to determine the new length of the property), or creates a\n * new property with that value if it does not already exist.\n *\n * This function may insert or delete data from the blob, and will\n * therefore change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there is insufficient free space in the blob to\n *\t\tcontain the new property value\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\n#define fdt_setprop_string(fdt, nodeoffset, name, str) \\\n\tfdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)\n\n\n/**\n * fdt_setprop_empty - set a property to an empty value\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n *\n * fdt_setprop_empty() sets the value of the named property in the\n * given node to an empty (zero length) value, or creates a new empty\n * property if it does not already exist.\n *\n * This function may insert or delete data from the blob, and will\n * therefore change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there is insufficient free space in the blob to\n *\t\tcontain the new property value\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\n#define fdt_setprop_empty(fdt, nodeoffset, name) \\\n\tfdt_setprop((fdt), (nodeoffset), (name), NULL, 0)\n\n/**\n * fdt_appendprop - append to or create a property\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to append to\n * @val: pointer to data to append to the property value\n * @len: length of the data to append to the property value\n *\n * fdt_appendprop() appends the value to the named property in the\n * given node, creating the property if it does not already exist.\n *\n * This function may insert data into the blob, and will therefore\n * change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there is insufficient free space in the blob to\n *\t\tcontain the new property value\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nint fdt_appendprop(void *fdt, int nodeoffset, const char *name,\n\t\t   const void *val, int len);\n\n/**\n * fdt_appendprop_u32 - append a 32-bit integer value to a property\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n * @val: 32-bit integer value to append to the property (native endian)\n *\n * fdt_appendprop_u32() appends the given 32-bit integer value\n * (converting to big-endian if necessary) to the value of the named\n * property in the given node, or creates a new property with that\n * value if it does not already exist.\n *\n * This function may insert data into the blob, and will therefore\n * change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there is insufficient free space in the blob to\n *\t\tcontain the new property value\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nstatic inline int fdt_appendprop_u32(void *fdt, int nodeoffset,\n\t\t\t\t     const char *name, uint32_t val)\n{\n\tfdt32_t tmp = cpu_to_fdt32(val);\n\treturn fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));\n}\n\n/**\n * fdt_appendprop_u64 - append a 64-bit integer value to a property\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n * @val: 64-bit integer value to append to the property (native endian)\n *\n * fdt_appendprop_u64() appends the given 64-bit integer value\n * (converting to big-endian if necessary) to the value of the named\n * property in the given node, or creates a new property with that\n * value if it does not already exist.\n *\n * This function may insert data into the blob, and will therefore\n * change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there is insufficient free space in the blob to\n *\t\tcontain the new property value\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nstatic inline int fdt_appendprop_u64(void *fdt, int nodeoffset,\n\t\t\t\t     const char *name, uint64_t val)\n{\n\tfdt64_t tmp = cpu_to_fdt64(val);\n\treturn fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));\n}\n\n/**\n * fdt_appendprop_cell - append a single cell value to a property\n *\n * This is an alternative name for fdt_appendprop_u32()\n */\nstatic inline int fdt_appendprop_cell(void *fdt, int nodeoffset,\n\t\t\t\t      const char *name, uint32_t val)\n{\n\treturn fdt_appendprop_u32(fdt, nodeoffset, name, val);\n}\n\n/**\n * fdt_appendprop_string - append a string to a property\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to change\n * @name: name of the property to change\n * @str: string value to append to the property\n *\n * fdt_appendprop_string() appends the given string to the value of\n * the named property in the given node, or creates a new property\n * with that value if it does not already exist.\n *\n * This function may insert data into the blob, and will therefore\n * change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there is insufficient free space in the blob to\n *\t\tcontain the new property value\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\n#define fdt_appendprop_string(fdt, nodeoffset, name, str) \\\n\tfdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)\n\n/**\n * fdt_delprop - delete a property\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node whose property to nop\n * @name: name of the property to nop\n *\n * fdt_del_property() will delete the given property.\n *\n * This function will delete data from the blob, and will therefore\n * change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOTFOUND, node does not have the named property\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nint fdt_delprop(void *fdt, int nodeoffset, const char *name);\n\n/**\n * fdt_add_subnode_namelen - creates a new node based on substring\n * @fdt: pointer to the device tree blob\n * @parentoffset: structure block offset of a node\n * @name: name of the subnode to locate\n * @namelen: number of characters of name to consider\n *\n * Identical to fdt_add_subnode(), but use only the first namelen\n * characters of name as the name of the new node.  This is useful for\n * creating subnodes based on a portion of a larger string, such as a\n * full path.\n */\n#ifndef SWIG /* Not available in Python */\nint fdt_add_subnode_namelen(void *fdt, int parentoffset,\n\t\t\t    const char *name, int namelen);\n#endif\n\n/**\n * fdt_add_subnode - creates a new node\n * @fdt: pointer to the device tree blob\n * @parentoffset: structure block offset of a node\n * @name: name of the subnode to locate\n *\n * fdt_add_subnode() creates a new node as a subnode of the node at\n * structure block offset parentoffset, with the given name (which\n * should include the unit address, if any).\n *\n * This function will insert data into the blob, and will therefore\n * change the offsets of some existing nodes.\n\n * returns:\n *\tstructure block offset of the created nodeequested subnode (>=0), on\n *\t\tsuccess\n *\t-FDT_ERR_NOTFOUND, if the requested subnode does not exist\n *\t-FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE\n *\t\ttag\n *\t-FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of\n *\t\tthe given name\n *\t-FDT_ERR_NOSPACE, if there is insufficient free space in the\n *\t\tblob to contain the new node\n *\t-FDT_ERR_NOSPACE\n *\t-FDT_ERR_BADLAYOUT\n *      -FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings.\n */\nint fdt_add_subnode(void *fdt, int parentoffset, const char *name);\n\n/**\n * fdt_del_node - delete a node (subtree)\n * @fdt: pointer to the device tree blob\n * @nodeoffset: offset of the node to nop\n *\n * fdt_del_node() will remove the given node, including all its\n * subnodes if any, from the blob.\n *\n * This function will delete data from the blob, and will therefore\n * change the offsets of some existing nodes.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nint fdt_del_node(void *fdt, int nodeoffset);\n\n/**\n * fdt_overlay_apply - Applies a DT overlay on a base DT\n * @fdt: pointer to the base device tree blob\n * @fdto: pointer to the device tree overlay blob\n *\n * fdt_overlay_apply() will apply the given device tree overlay on the\n * given base device tree.\n *\n * Expect the base device tree to be modified, even if the function\n * returns an error.\n *\n * returns:\n *\t0, on success\n *\t-FDT_ERR_NOSPACE, there's not enough space in the base device tree\n *\t-FDT_ERR_NOTFOUND, the overlay points to some inexistant nodes or\n *\t\tproperties in the base DT\n *\t-FDT_ERR_BADPHANDLE,\n *\t-FDT_ERR_BADOVERLAY,\n *\t-FDT_ERR_NOPHANDLES,\n *\t-FDT_ERR_INTERNAL,\n *\t-FDT_ERR_BADLAYOUT,\n *\t-FDT_ERR_BADMAGIC,\n *\t-FDT_ERR_BADOFFSET,\n *\t-FDT_ERR_BADPATH,\n *\t-FDT_ERR_BADVERSION,\n *\t-FDT_ERR_BADSTRUCTURE,\n *\t-FDT_ERR_BADSTATE,\n *\t-FDT_ERR_TRUNCATED, standard meanings\n */\nint fdt_overlay_apply(void *fdt, void *fdto);\n\n/**********************************************************************/\n/* Debugging / informational functions                                */\n/**********************************************************************/\n\nconst char *fdt_strerror(int errval);\n\nstatic inline uint64_t fdt32_to_cpu64(fdt32_t high, fdt32_t low)\n{\n\treturn ((uint64_t)fdt32_to_cpu(high) << 32) | fdt32_to_cpu(low);\n}\n\n#endif /* LIBFDT_H */\n"
  },
  {
    "path": "user.libs/libfdt/include/libfdt/libfdt_env.h",
    "content": "#ifndef LIBFDT_ENV_H\n#define LIBFDT_ENV_H\n/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2006 David Gibson, IBM Corporation.\n * Copyright 2012 Kim Phillips, Freescale Semiconductor.\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include <string.h>\n#include <inttypes.h>\n#include <limits.h>\n#include <stdlib.h>\n\n#ifdef __CHECKER__\n#define FDT_FORCE __attribute__((force))\n#define FDT_BITWISE __attribute__((bitwise))\n#else\n#define FDT_FORCE\n#define FDT_BITWISE\n#endif\n\ntypedef uint16_t FDT_BITWISE fdt16_t;\ntypedef uint32_t FDT_BITWISE fdt32_t;\ntypedef uint64_t FDT_BITWISE fdt64_t;\n\n#define EXTRACT_BYTE(x, n)\t((unsigned long long)((uint8_t *)&x)[n])\n#define CPU_TO_FDT16(x) ((EXTRACT_BYTE(x, 0) << 8) | EXTRACT_BYTE(x, 1))\n#define CPU_TO_FDT32(x) ((EXTRACT_BYTE(x, 0) << 24) | (EXTRACT_BYTE(x, 1) << 16) | \\\n\t\t\t (EXTRACT_BYTE(x, 2) << 8) | EXTRACT_BYTE(x, 3))\n#define CPU_TO_FDT64(x) ((EXTRACT_BYTE(x, 0) << 56) | (EXTRACT_BYTE(x, 1) << 48) | \\\n\t\t\t (EXTRACT_BYTE(x, 2) << 40) | (EXTRACT_BYTE(x, 3) << 32) | \\\n\t\t\t (EXTRACT_BYTE(x, 4) << 24) | (EXTRACT_BYTE(x, 5) << 16) | \\\n\t\t\t (EXTRACT_BYTE(x, 6) << 8) | EXTRACT_BYTE(x, 7))\n\nstatic inline uint16_t fdt16_to_cpu(fdt16_t x)\n{\n\treturn (FDT_FORCE uint16_t)CPU_TO_FDT16(x);\n}\nstatic inline fdt16_t cpu_to_fdt16(uint16_t x)\n{\n\treturn (FDT_FORCE fdt16_t)CPU_TO_FDT16(x);\n}\n\nstatic inline uint32_t fdt32_to_cpu(fdt32_t x)\n{\n\treturn (FDT_FORCE uint32_t)CPU_TO_FDT32(x);\n}\nstatic inline fdt32_t cpu_to_fdt32(uint32_t x)\n{\n\treturn (FDT_FORCE fdt32_t)CPU_TO_FDT32(x);\n}\n\nstatic inline uint64_t fdt64_to_cpu(fdt64_t x)\n{\n\treturn (FDT_FORCE uint64_t)CPU_TO_FDT64(x);\n}\nstatic inline fdt64_t cpu_to_fdt64(uint64_t x)\n{\n\treturn (FDT_FORCE fdt64_t)CPU_TO_FDT64(x);\n}\n#undef CPU_TO_FDT64\n#undef CPU_TO_FDT32\n#undef CPU_TO_FDT16\n#undef EXTRACT_BYTE\n\n#ifdef __APPLE__\n#include <AvailabilityMacros.h>\n\n/* strnlen() is not available on Mac OS < 10.7 */\n# if !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED < \\\n                                         MAC_OS_X_VERSION_10_7)\n\n#define strnlen fdt_strnlen\n\n/*\n * fdt_strnlen: returns the length of a string or max_count - which ever is\n * smallest.\n * Input 1 string: the string whose size is to be determined\n * Input 2 max_count: the maximum value returned by this function\n * Output: length of the string or max_count (the smallest of the two)\n */\nstatic inline size_t fdt_strnlen(const char *string, size_t max_count)\n{\n    const char *p = memchr(string, 0, max_count);\n    return p ? p - string : max_count;\n}\n\n#endif /* !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED <\n          MAC_OS_X_VERSION_10_7) */\n\n#endif /* __APPLE__ */\n\n#endif /* LIBFDT_ENV_H */\n"
  },
  {
    "path": "user.libs/libfdt/src/fdt.c",
    "content": "/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2006 David Gibson, IBM Corporation.\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n#include <libfdt/libfdt_env.h>\n\n#include <libfdt/fdt.h>\n#include <libfdt/libfdt.h>\n\n#include \"libfdt_internal.h\"\n\n/*\n * Minimal sanity check for a read-only tree. fdt_ro_probe_() checks\n * that the given buffer contains what appears to be a flattened\n * device tree with sane information in its header.\n */\nint fdt_ro_probe_(const void *fdt)\n{\n\tif (fdt_magic(fdt) == FDT_MAGIC) {\n\t\t/* Complete tree */\n\t\tif (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)\n\t\t\treturn -FDT_ERR_BADVERSION;\n\t\tif (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)\n\t\t\treturn -FDT_ERR_BADVERSION;\n\t} else if (fdt_magic(fdt) == FDT_SW_MAGIC) {\n\t\t/* Unfinished sequential-write blob */\n\t\tif (fdt_size_dt_struct(fdt) == 0)\n\t\t\treturn -FDT_ERR_BADSTATE;\n\t} else {\n\t\treturn -FDT_ERR_BADMAGIC;\n\t}\n\n\treturn 0;\n}\n\nstatic int check_off_(uint32_t hdrsize, uint32_t totalsize, uint32_t off)\n{\n\treturn (off >= hdrsize) && (off <= totalsize);\n}\n\nstatic int check_block_(uint32_t hdrsize, uint32_t totalsize,\n\t\t\tuint32_t base, uint32_t size)\n{\n\tif (!check_off_(hdrsize, totalsize, base))\n\t\treturn 0; /* block start out of bounds */\n\tif ((base + size) < base)\n\t\treturn 0; /* overflow */\n\tif (!check_off_(hdrsize, totalsize, base + size))\n\t\treturn 0; /* block end out of bounds */\n\treturn 1;\n}\n\nsize_t fdt_header_size_(uint32_t version)\n{\n\tif (version <= 1)\n\t\treturn FDT_V1_SIZE;\n\telse if (version <= 2)\n\t\treturn FDT_V2_SIZE;\n\telse if (version <= 3)\n\t\treturn FDT_V3_SIZE;\n\telse if (version <= 16)\n\t\treturn FDT_V16_SIZE;\n\telse\n\t\treturn FDT_V17_SIZE;\n}\n\nint fdt_check_header(const void *fdt)\n{\n\tsize_t hdrsize;\n\n\tif (fdt_magic(fdt) != FDT_MAGIC)\n\t\treturn -FDT_ERR_BADMAGIC;\n\thdrsize = fdt_header_size(fdt);\n\tif ((fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)\n\t    || (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION))\n\t\treturn -FDT_ERR_BADVERSION;\n\tif (fdt_version(fdt) < fdt_last_comp_version(fdt))\n\t\treturn -FDT_ERR_BADVERSION;\n\n\tif ((fdt_totalsize(fdt) < hdrsize)\n\t    || (fdt_totalsize(fdt) > INT_MAX))\n\t\treturn -FDT_ERR_TRUNCATED;\n\n\t/* Bounds check memrsv block */\n\tif (!check_off_(hdrsize, fdt_totalsize(fdt), fdt_off_mem_rsvmap(fdt)))\n\t\treturn -FDT_ERR_TRUNCATED;\n\n\t/* Bounds check structure block */\n\tif (fdt_version(fdt) < 17) {\n\t\tif (!check_off_(hdrsize, fdt_totalsize(fdt),\n\t\t\t\tfdt_off_dt_struct(fdt)))\n\t\t\treturn -FDT_ERR_TRUNCATED;\n\t} else {\n\t\tif (!check_block_(hdrsize, fdt_totalsize(fdt),\n\t\t\t\t  fdt_off_dt_struct(fdt),\n\t\t\t\t  fdt_size_dt_struct(fdt)))\n\t\t\treturn -FDT_ERR_TRUNCATED;\n\t}\n\n\t/* Bounds check strings block */\n\tif (!check_block_(hdrsize, fdt_totalsize(fdt),\n\t\t\t  fdt_off_dt_strings(fdt), fdt_size_dt_strings(fdt)))\n\t\treturn -FDT_ERR_TRUNCATED;\n\n\treturn 0;\n}\n\nconst void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)\n{\n\tunsigned absoffset = offset + fdt_off_dt_struct(fdt);\n\n\tif ((absoffset < offset)\n\t    || ((absoffset + len) < absoffset)\n\t    || (absoffset + len) > fdt_totalsize(fdt))\n\t\treturn NULL;\n\n\tif (fdt_version(fdt) >= 0x11)\n\t\tif (((offset + len) < offset)\n\t\t    || ((offset + len) > fdt_size_dt_struct(fdt)))\n\t\t\treturn NULL;\n\n\treturn fdt_offset_ptr_(fdt, offset);\n}\n\nuint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)\n{\n\tconst fdt32_t *tagp, *lenp;\n\tuint32_t tag;\n\tint offset = startoffset;\n\tconst char *p;\n\n\t*nextoffset = -FDT_ERR_TRUNCATED;\n\ttagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);\n\tif (!tagp)\n\t\treturn FDT_END; /* premature end */\n\ttag = fdt32_to_cpu(*tagp);\n\toffset += FDT_TAGSIZE;\n\n\t*nextoffset = -FDT_ERR_BADSTRUCTURE;\n\tswitch (tag) {\n\tcase FDT_BEGIN_NODE:\n\t\t/* skip name */\n\t\tdo {\n\t\t\tp = fdt_offset_ptr(fdt, offset++, 1);\n\t\t} while (p && (*p != '\\0'));\n\t\tif (!p)\n\t\t\treturn FDT_END; /* premature end */\n\t\tbreak;\n\n\tcase FDT_PROP:\n\t\tlenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));\n\t\tif (!lenp)\n\t\t\treturn FDT_END; /* premature end */\n\t\t/* skip-name offset, length and value */\n\t\toffset += sizeof(struct fdt_property) - FDT_TAGSIZE\n\t\t\t+ fdt32_to_cpu(*lenp);\n\t\tif (fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 &&\n\t\t    ((offset - fdt32_to_cpu(*lenp)) % 8) != 0)\n\t\t\toffset += 4;\n\t\tbreak;\n\n\tcase FDT_END:\n\tcase FDT_END_NODE:\n\tcase FDT_NOP:\n\t\tbreak;\n\n\tdefault:\n\t\treturn FDT_END;\n\t}\n\n\tif (!fdt_offset_ptr(fdt, startoffset, offset - startoffset))\n\t\treturn FDT_END; /* premature end */\n\n\t*nextoffset = FDT_TAGALIGN(offset);\n\treturn tag;\n}\n\nint fdt_check_node_offset_(const void *fdt, int offset)\n{\n\tif ((offset < 0) || (offset % FDT_TAGSIZE)\n\t    || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))\n\t\treturn -FDT_ERR_BADOFFSET;\n\n\treturn offset;\n}\n\nint fdt_check_prop_offset_(const void *fdt, int offset)\n{\n\tif ((offset < 0) || (offset % FDT_TAGSIZE)\n\t    || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP))\n\t\treturn -FDT_ERR_BADOFFSET;\n\n\treturn offset;\n}\n\nint fdt_next_node(const void *fdt, int offset, int *depth)\n{\n\tint nextoffset = 0;\n\tuint32_t tag;\n\n\tif (offset >= 0)\n\t\tif ((nextoffset = fdt_check_node_offset_(fdt, offset)) < 0)\n\t\t\treturn nextoffset;\n\n\tdo {\n\t\toffset = nextoffset;\n\t\ttag = fdt_next_tag(fdt, offset, &nextoffset);\n\n\t\tswitch (tag) {\n\t\tcase FDT_PROP:\n\t\tcase FDT_NOP:\n\t\t\tbreak;\n\n\t\tcase FDT_BEGIN_NODE:\n\t\t\tif (depth)\n\t\t\t\t(*depth)++;\n\t\t\tbreak;\n\n\t\tcase FDT_END_NODE:\n\t\t\tif (depth && ((--(*depth)) < 0))\n\t\t\t\treturn nextoffset;\n\t\t\tbreak;\n\n\t\tcase FDT_END:\n\t\t\tif ((nextoffset >= 0)\n\t\t\t    || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth))\n\t\t\t\treturn -FDT_ERR_NOTFOUND;\n\t\t\telse\n\t\t\t\treturn nextoffset;\n\t\t}\n\t} while (tag != FDT_BEGIN_NODE);\n\n\treturn offset;\n}\n\nint fdt_first_subnode(const void *fdt, int offset)\n{\n\tint depth = 0;\n\n\toffset = fdt_next_node(fdt, offset, &depth);\n\tif (offset < 0 || depth != 1)\n\t\treturn -FDT_ERR_NOTFOUND;\n\n\treturn offset;\n}\n\nint fdt_next_subnode(const void *fdt, int offset)\n{\n\tint depth = 1;\n\n\t/*\n\t * With respect to the parent, the depth of the next subnode will be\n\t * the same as the last.\n\t */\n\tdo {\n\t\toffset = fdt_next_node(fdt, offset, &depth);\n\t\tif (offset < 0 || depth < 1)\n\t\t\treturn -FDT_ERR_NOTFOUND;\n\t} while (depth > 1);\n\n\treturn offset;\n}\n\nconst char *fdt_find_string_(const char *strtab, int tabsize, const char *s)\n{\n\tint len = strlen(s) + 1;\n\tconst char *last = strtab + tabsize - len;\n\tconst char *p;\n\n\tfor (p = strtab; p <= last; p++)\n\t\tif (memcmp(p, s, len) == 0)\n\t\t\treturn p;\n\treturn NULL;\n}\n\nint fdt_move(const void *fdt, void *buf, int bufsize)\n{\n\tFDT_RO_PROBE(fdt);\n\n\tif (fdt_totalsize(fdt) > bufsize)\n\t\treturn -FDT_ERR_NOSPACE;\n\n\tmemmove(buf, fdt, fdt_totalsize(fdt));\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libs/libfdt/src/fdt_addresses.c",
    "content": "/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2014 David Gibson <david@gibson.dropbear.id.au>\n * Copyright (C) 2018 embedded brains GmbH\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n#include <libfdt/libfdt_env.h>\n\n#include <libfdt/fdt.h>\n#include <libfdt/libfdt.h>\n\n#include \"libfdt_internal.h\"\n\nstatic int fdt_cells(const void *fdt, int nodeoffset, const char *name)\n{\n\tconst fdt32_t *c;\n\tint val;\n\tint len;\n\n\tc = fdt_getprop(fdt, nodeoffset, name, &len);\n\tif (!c)\n\t\treturn 2;\n\n\tif (len != sizeof(*c))\n\t\treturn -FDT_ERR_BADNCELLS;\n\n\tval = fdt32_to_cpu(*c);\n\tif ((val <= 0) || (val > FDT_MAX_NCELLS))\n\t\treturn -FDT_ERR_BADNCELLS;\n\n\treturn val;\n}\n\nint fdt_address_cells(const void *fdt, int nodeoffset)\n{\n\treturn fdt_cells(fdt, nodeoffset, \"#address-cells\");\n}\n\nint fdt_size_cells(const void *fdt, int nodeoffset)\n{\n\treturn fdt_cells(fdt, nodeoffset, \"#size-cells\");\n}\n"
  },
  {
    "path": "user.libs/libfdt/src/fdt_empty_tree.c",
    "content": "/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2012 David Gibson, IBM Corporation.\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n#include <libfdt/libfdt_env.h>\n\n#include <libfdt/fdt.h>\n#include <libfdt/libfdt.h>\n\n#include \"libfdt_internal.h\"\n\nint fdt_create_empty_tree(void *buf, int bufsize)\n{\n\tint err;\n\n\terr = fdt_create(buf, bufsize);\n\tif (err)\n\t\treturn err;\n\n\terr = fdt_finish_reservemap(buf);\n\tif (err)\n\t\treturn err;\n\n\terr = fdt_begin_node(buf, \"\");\n\tif (err)\n\t\treturn err;\n\n\terr =  fdt_end_node(buf);\n\tif (err)\n\t\treturn err;\n\n\terr = fdt_finish(buf);\n\tif (err)\n\t\treturn err;\n\n\treturn fdt_open_into(buf, buf, bufsize);\n}\n"
  },
  {
    "path": "user.libs/libfdt/src/fdt_overlay.c",
    "content": "/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2016 Free Electrons\n * Copyright (C) 2016 NextThing Co.\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n#include <libfdt/libfdt_env.h>\n\n#include <libfdt/fdt.h>\n#include <libfdt/libfdt.h>\n\n#include \"libfdt_internal.h\"\n\n/**\n * overlay_get_target_phandle - retrieves the target phandle of a fragment\n * @fdto: pointer to the device tree overlay blob\n * @fragment: node offset of the fragment in the overlay\n *\n * overlay_get_target_phandle() retrieves the target phandle of an\n * overlay fragment when that fragment uses a phandle (target\n * property) instead of a path (target-path property).\n *\n * returns:\n *      the phandle pointed by the target property\n *      0, if the phandle was not found\n *\t-1, if the phandle was malformed\n */\nstatic uint32_t overlay_get_target_phandle(const void *fdto, int fragment)\n{\n\tconst fdt32_t *val;\n\tint len;\n\n\tval = fdt_getprop(fdto, fragment, \"target\", &len);\n\tif (!val)\n\t\treturn 0;\n\n\tif ((len != sizeof(*val)) || (fdt32_to_cpu(*val) == (uint32_t)-1))\n\t\treturn (uint32_t)-1;\n\n\treturn fdt32_to_cpu(*val);\n}\n\n/**\n * overlay_get_target - retrieves the offset of a fragment's target\n * @fdt: Base device tree blob\n * @fdto: Device tree overlay blob\n * @fragment: node offset of the fragment in the overlay\n * @pathp: pointer which receives the path of the target (or NULL)\n *\n * overlay_get_target() retrieves the target offset in the base\n * device tree of a fragment, no matter how the actual targetting is\n * done (through a phandle or a path)\n *\n * returns:\n *      the targetted node offset in the base device tree\n *      Negative error code on error\n */\nstatic int overlay_get_target(const void *fdt, const void *fdto,\n\t\t\t      int fragment, char const **pathp)\n{\n\tuint32_t phandle;\n\tconst char *path = NULL;\n\tint path_len = 0, ret;\n\n\t/* Try first to do a phandle based lookup */\n\tphandle = overlay_get_target_phandle(fdto, fragment);\n\tif (phandle == (uint32_t)-1)\n\t\treturn -FDT_ERR_BADPHANDLE;\n\n\t/* no phandle, try path */\n\tif (!phandle) {\n\t\t/* And then a path based lookup */\n\t\tpath = fdt_getprop(fdto, fragment, \"target-path\", &path_len);\n\t\tif (path)\n\t\t\tret = fdt_path_offset(fdt, path);\n\t\telse\n\t\t\tret = path_len;\n\t} else\n\t\tret = fdt_node_offset_by_phandle(fdt, phandle);\n\n\t/*\n\t* If we haven't found either a target or a\n\t* target-path property in a node that contains a\n\t* __overlay__ subnode (we wouldn't be called\n\t* otherwise), consider it a improperly written\n\t* overlay\n\t*/\n\tif (ret < 0 && path_len == -FDT_ERR_NOTFOUND)\n\t\tret = -FDT_ERR_BADOVERLAY;\n\n\t/* return on error */\n\tif (ret < 0)\n\t\treturn ret;\n\n\t/* return pointer to path (if available) */\n\tif (pathp)\n\t\t*pathp = path ? path : NULL;\n\n\treturn ret;\n}\n\n/**\n * overlay_phandle_add_offset - Increases a phandle by an offset\n * @fdt: Base device tree blob\n * @node: Device tree overlay blob\n * @name: Name of the property to modify (phandle or linux,phandle)\n * @delta: offset to apply\n *\n * overlay_phandle_add_offset() increments a node phandle by a given\n * offset.\n *\n * returns:\n *      0 on success.\n *      Negative error code on error\n */\nstatic int overlay_phandle_add_offset(void *fdt, int node,\n\t\t\t\t      const char *name, uint32_t delta)\n{\n\tconst fdt32_t *val;\n\tuint32_t adj_val;\n\tint len;\n\n\tval = fdt_getprop(fdt, node, name, &len);\n\tif (!val)\n\t\treturn len;\n\n\tif (len != sizeof(*val))\n\t\treturn -FDT_ERR_BADPHANDLE;\n\n\tadj_val = fdt32_to_cpu(*val);\n\tif ((adj_val + delta) < adj_val)\n\t\treturn -FDT_ERR_NOPHANDLES;\n\n\tadj_val += delta;\n\tif (adj_val == (uint32_t)-1)\n\t\treturn -FDT_ERR_NOPHANDLES;\n\n\treturn fdt_setprop_inplace_u32(fdt, node, name, adj_val);\n}\n\n/**\n * overlay_adjust_node_phandles - Offsets the phandles of a node\n * @fdto: Device tree overlay blob\n * @node: Offset of the node we want to adjust\n * @delta: Offset to shift the phandles of\n *\n * overlay_adjust_node_phandles() adds a constant to all the phandles\n * of a given node. This is mainly use as part of the overlay\n * application process, when we want to update all the overlay\n * phandles to not conflict with the overlays of the base device tree.\n *\n * returns:\n *      0 on success\n *      Negative error code on failure\n */\nstatic int overlay_adjust_node_phandles(void *fdto, int node,\n\t\t\t\t\tuint32_t delta)\n{\n\tint child;\n\tint ret;\n\n\tret = overlay_phandle_add_offset(fdto, node, \"phandle\", delta);\n\tif (ret && ret != -FDT_ERR_NOTFOUND)\n\t\treturn ret;\n\n\tret = overlay_phandle_add_offset(fdto, node, \"linux,phandle\", delta);\n\tif (ret && ret != -FDT_ERR_NOTFOUND)\n\t\treturn ret;\n\n\tfdt_for_each_subnode(child, fdto, node) {\n\t\tret = overlay_adjust_node_phandles(fdto, child, delta);\n\t\tif (ret)\n\t\t\treturn ret;\n\t}\n\n\treturn 0;\n}\n\n/**\n * overlay_adjust_local_phandles - Adjust the phandles of a whole overlay\n * @fdto: Device tree overlay blob\n * @delta: Offset to shift the phandles of\n *\n * overlay_adjust_local_phandles() adds a constant to all the\n * phandles of an overlay. This is mainly use as part of the overlay\n * application process, when we want to update all the overlay\n * phandles to not conflict with the overlays of the base device tree.\n *\n * returns:\n *      0 on success\n *      Negative error code on failure\n */\nstatic int overlay_adjust_local_phandles(void *fdto, uint32_t delta)\n{\n\t/*\n\t * Start adjusting the phandles from the overlay root\n\t */\n\treturn overlay_adjust_node_phandles(fdto, 0, delta);\n}\n\n/**\n * overlay_update_local_node_references - Adjust the overlay references\n * @fdto: Device tree overlay blob\n * @tree_node: Node offset of the node to operate on\n * @fixup_node: Node offset of the matching local fixups node\n * @delta: Offset to shift the phandles of\n *\n * overlay_update_local_nodes_references() update the phandles\n * pointing to a node within the device tree overlay by adding a\n * constant delta.\n *\n * This is mainly used as part of a device tree application process,\n * where you want the device tree overlays phandles to not conflict\n * with the ones from the base device tree before merging them.\n *\n * returns:\n *      0 on success\n *      Negative error code on failure\n */\nstatic int overlay_update_local_node_references(void *fdto,\n\t\t\t\t\t\tint tree_node,\n\t\t\t\t\t\tint fixup_node,\n\t\t\t\t\t\tuint32_t delta)\n{\n\tint fixup_prop;\n\tint fixup_child;\n\tint ret;\n\n\tfdt_for_each_property_offset(fixup_prop, fdto, fixup_node) {\n\t\tconst fdt32_t *fixup_val;\n\t\tconst char *tree_val;\n\t\tconst char *name;\n\t\tint fixup_len;\n\t\tint tree_len;\n\t\tint i;\n\n\t\tfixup_val = fdt_getprop_by_offset(fdto, fixup_prop,\n\t\t\t\t\t\t  &name, &fixup_len);\n\t\tif (!fixup_val)\n\t\t\treturn fixup_len;\n\n\t\tif (fixup_len % sizeof(uint32_t))\n\t\t\treturn -FDT_ERR_BADOVERLAY;\n\n\t\ttree_val = fdt_getprop(fdto, tree_node, name, &tree_len);\n\t\tif (!tree_val) {\n\t\t\tif (tree_len == -FDT_ERR_NOTFOUND)\n\t\t\t\treturn -FDT_ERR_BADOVERLAY;\n\n\t\t\treturn tree_len;\n\t\t}\n\n\t\tfor (i = 0; i < (fixup_len / sizeof(uint32_t)); i++) {\n\t\t\tfdt32_t adj_val;\n\t\t\tuint32_t poffset;\n\n\t\t\tpoffset = fdt32_to_cpu(fixup_val[i]);\n\n\t\t\t/*\n\t\t\t * phandles to fixup can be unaligned.\n\t\t\t *\n\t\t\t * Use a memcpy for the architectures that do\n\t\t\t * not support unaligned accesses.\n\t\t\t */\n\t\t\tmemcpy(&adj_val, tree_val + poffset, sizeof(adj_val));\n\n\t\t\tadj_val = cpu_to_fdt32(fdt32_to_cpu(adj_val) + delta);\n\n\t\t\tret = fdt_setprop_inplace_namelen_partial(fdto,\n\t\t\t\t\t\t\t\t  tree_node,\n\t\t\t\t\t\t\t\t  name,\n\t\t\t\t\t\t\t\t  strlen(name),\n\t\t\t\t\t\t\t\t  poffset,\n\t\t\t\t\t\t\t\t  &adj_val,\n\t\t\t\t\t\t\t\t  sizeof(adj_val));\n\t\t\tif (ret == -FDT_ERR_NOSPACE)\n\t\t\t\treturn -FDT_ERR_BADOVERLAY;\n\n\t\t\tif (ret)\n\t\t\t\treturn ret;\n\t\t}\n\t}\n\n\tfdt_for_each_subnode(fixup_child, fdto, fixup_node) {\n\t\tconst char *fixup_child_name = fdt_get_name(fdto, fixup_child,\n\t\t\t\t\t\t\t    NULL);\n\t\tint tree_child;\n\n\t\ttree_child = fdt_subnode_offset(fdto, tree_node,\n\t\t\t\t\t\tfixup_child_name);\n\t\tif (tree_child == -FDT_ERR_NOTFOUND)\n\t\t\treturn -FDT_ERR_BADOVERLAY;\n\t\tif (tree_child < 0)\n\t\t\treturn tree_child;\n\n\t\tret = overlay_update_local_node_references(fdto,\n\t\t\t\t\t\t\t   tree_child,\n\t\t\t\t\t\t\t   fixup_child,\n\t\t\t\t\t\t\t   delta);\n\t\tif (ret)\n\t\t\treturn ret;\n\t}\n\n\treturn 0;\n}\n\n/**\n * overlay_update_local_references - Adjust the overlay references\n * @fdto: Device tree overlay blob\n * @delta: Offset to shift the phandles of\n *\n * overlay_update_local_references() update all the phandles pointing\n * to a node within the device tree overlay by adding a constant\n * delta to not conflict with the base overlay.\n *\n * This is mainly used as part of a device tree application process,\n * where you want the device tree overlays phandles to not conflict\n * with the ones from the base device tree before merging them.\n *\n * returns:\n *      0 on success\n *      Negative error code on failure\n */\nstatic int overlay_update_local_references(void *fdto, uint32_t delta)\n{\n\tint fixups;\n\n\tfixups = fdt_path_offset(fdto, \"/__local_fixups__\");\n\tif (fixups < 0) {\n\t\t/* There's no local phandles to adjust, bail out */\n\t\tif (fixups == -FDT_ERR_NOTFOUND)\n\t\t\treturn 0;\n\n\t\treturn fixups;\n\t}\n\n\t/*\n\t * Update our local references from the root of the tree\n\t */\n\treturn overlay_update_local_node_references(fdto, 0, fixups,\n\t\t\t\t\t\t    delta);\n}\n\n/**\n * overlay_fixup_one_phandle - Set an overlay phandle to the base one\n * @fdt: Base Device Tree blob\n * @fdto: Device tree overlay blob\n * @symbols_off: Node offset of the symbols node in the base device tree\n * @path: Path to a node holding a phandle in the overlay\n * @path_len: number of path characters to consider\n * @name: Name of the property holding the phandle reference in the overlay\n * @name_len: number of name characters to consider\n * @poffset: Offset within the overlay property where the phandle is stored\n * @label: Label of the node referenced by the phandle\n *\n * overlay_fixup_one_phandle() resolves an overlay phandle pointing to\n * a node in the base device tree.\n *\n * This is part of the device tree overlay application process, when\n * you want all the phandles in the overlay to point to the actual\n * base dt nodes.\n *\n * returns:\n *      0 on success\n *      Negative error code on failure\n */\nstatic int overlay_fixup_one_phandle(void *fdt, void *fdto,\n\t\t\t\t     int symbols_off,\n\t\t\t\t     const char *path, uint32_t path_len,\n\t\t\t\t     const char *name, uint32_t name_len,\n\t\t\t\t     int poffset, const char *label)\n{\n\tconst char *symbol_path;\n\tuint32_t phandle;\n\tfdt32_t phandle_prop;\n\tint symbol_off, fixup_off;\n\tint prop_len;\n\n\tif (symbols_off < 0)\n\t\treturn symbols_off;\n\n\tsymbol_path = fdt_getprop(fdt, symbols_off, label,\n\t\t\t\t  &prop_len);\n\tif (!symbol_path)\n\t\treturn prop_len;\n\n\tsymbol_off = fdt_path_offset(fdt, symbol_path);\n\tif (symbol_off < 0)\n\t\treturn symbol_off;\n\n\tphandle = fdt_get_phandle(fdt, symbol_off);\n\tif (!phandle)\n\t\treturn -FDT_ERR_NOTFOUND;\n\n\tfixup_off = fdt_path_offset_namelen(fdto, path, path_len);\n\tif (fixup_off == -FDT_ERR_NOTFOUND)\n\t\treturn -FDT_ERR_BADOVERLAY;\n\tif (fixup_off < 0)\n\t\treturn fixup_off;\n\n\tphandle_prop = cpu_to_fdt32(phandle);\n\treturn fdt_setprop_inplace_namelen_partial(fdto, fixup_off,\n\t\t\t\t\t\t   name, name_len, poffset,\n\t\t\t\t\t\t   &phandle_prop,\n\t\t\t\t\t\t   sizeof(phandle_prop));\n};\n\n/**\n * overlay_fixup_phandle - Set an overlay phandle to the base one\n * @fdt: Base Device Tree blob\n * @fdto: Device tree overlay blob\n * @symbols_off: Node offset of the symbols node in the base device tree\n * @property: Property offset in the overlay holding the list of fixups\n *\n * overlay_fixup_phandle() resolves all the overlay phandles pointed\n * to in a __fixups__ property, and updates them to match the phandles\n * in use in the base device tree.\n *\n * This is part of the device tree overlay application process, when\n * you want all the phandles in the overlay to point to the actual\n * base dt nodes.\n *\n * returns:\n *      0 on success\n *      Negative error code on failure\n */\nstatic int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off,\n\t\t\t\t int property)\n{\n\tconst char *value;\n\tconst char *label;\n\tint len;\n\n\tvalue = fdt_getprop_by_offset(fdto, property,\n\t\t\t\t      &label, &len);\n\tif (!value) {\n\t\tif (len == -FDT_ERR_NOTFOUND)\n\t\t\treturn -FDT_ERR_INTERNAL;\n\n\t\treturn len;\n\t}\n\n\tdo {\n\t\tconst char *path, *name, *fixup_end;\n\t\tconst char *fixup_str = value;\n\t\tuint32_t path_len, name_len;\n\t\tuint32_t fixup_len;\n\t\tchar *sep, *endptr;\n\t\tint poffset, ret;\n\n\t\tfixup_end = memchr(value, '\\0', len);\n\t\tif (!fixup_end)\n\t\t\treturn -FDT_ERR_BADOVERLAY;\n\t\tfixup_len = fixup_end - fixup_str;\n\n\t\tlen -= fixup_len + 1;\n\t\tvalue += fixup_len + 1;\n\n\t\tpath = fixup_str;\n\t\tsep = memchr(fixup_str, ':', fixup_len);\n\t\tif (!sep || *sep != ':')\n\t\t\treturn -FDT_ERR_BADOVERLAY;\n\n\t\tpath_len = sep - path;\n\t\tif (path_len == (fixup_len - 1))\n\t\t\treturn -FDT_ERR_BADOVERLAY;\n\n\t\tfixup_len -= path_len + 1;\n\t\tname = sep + 1;\n\t\tsep = memchr(name, ':', fixup_len);\n\t\tif (!sep || *sep != ':')\n\t\t\treturn -FDT_ERR_BADOVERLAY;\n\n\t\tname_len = sep - name;\n\t\tif (!name_len)\n\t\t\treturn -FDT_ERR_BADOVERLAY;\n\n\t\tpoffset = strtoul(sep + 1, &endptr, 10);\n\t\tif ((*endptr != '\\0') || (endptr <= (sep + 1)))\n\t\t\treturn -FDT_ERR_BADOVERLAY;\n\n\t\tret = overlay_fixup_one_phandle(fdt, fdto, symbols_off,\n\t\t\t\t\t\tpath, path_len, name, name_len,\n\t\t\t\t\t\tpoffset, label);\n\t\tif (ret)\n\t\t\treturn ret;\n\t} while (len > 0);\n\n\treturn 0;\n}\n\n/**\n * overlay_fixup_phandles - Resolve the overlay phandles to the base\n *                          device tree\n * @fdt: Base Device Tree blob\n * @fdto: Device tree overlay blob\n *\n * overlay_fixup_phandles() resolves all the overlay phandles pointing\n * to nodes in the base device tree.\n *\n * This is one of the steps of the device tree overlay application\n * process, when you want all the phandles in the overlay to point to\n * the actual base dt nodes.\n *\n * returns:\n *      0 on success\n *      Negative error code on failure\n */\nstatic int overlay_fixup_phandles(void *fdt, void *fdto)\n{\n\tint fixups_off, symbols_off;\n\tint property;\n\n\t/* We can have overlays without any fixups */\n\tfixups_off = fdt_path_offset(fdto, \"/__fixups__\");\n\tif (fixups_off == -FDT_ERR_NOTFOUND)\n\t\treturn 0; /* nothing to do */\n\tif (fixups_off < 0)\n\t\treturn fixups_off;\n\n\t/* And base DTs without symbols */\n\tsymbols_off = fdt_path_offset(fdt, \"/__symbols__\");\n\tif ((symbols_off < 0 && (symbols_off != -FDT_ERR_NOTFOUND)))\n\t\treturn symbols_off;\n\n\tfdt_for_each_property_offset(property, fdto, fixups_off) {\n\t\tint ret;\n\n\t\tret = overlay_fixup_phandle(fdt, fdto, symbols_off, property);\n\t\tif (ret)\n\t\t\treturn ret;\n\t}\n\n\treturn 0;\n}\n\n/**\n * overlay_apply_node - Merges a node into the base device tree\n * @fdt: Base Device Tree blob\n * @target: Node offset in the base device tree to apply the fragment to\n * @fdto: Device tree overlay blob\n * @node: Node offset in the overlay holding the changes to merge\n *\n * overlay_apply_node() merges a node into a target base device tree\n * node pointed.\n *\n * This is part of the final step in the device tree overlay\n * application process, when all the phandles have been adjusted and\n * resolved and you just have to merge overlay into the base device\n * tree.\n *\n * returns:\n *      0 on success\n *      Negative error code on failure\n */\nstatic int overlay_apply_node(void *fdt, int target,\n\t\t\t      void *fdto, int node)\n{\n\tint property;\n\tint subnode;\n\n\tfdt_for_each_property_offset(property, fdto, node) {\n\t\tconst char *name;\n\t\tconst void *prop;\n\t\tint prop_len;\n\t\tint ret;\n\n\t\tprop = fdt_getprop_by_offset(fdto, property, &name,\n\t\t\t\t\t     &prop_len);\n\t\tif (prop_len == -FDT_ERR_NOTFOUND)\n\t\t\treturn -FDT_ERR_INTERNAL;\n\t\tif (prop_len < 0)\n\t\t\treturn prop_len;\n\n\t\tret = fdt_setprop(fdt, target, name, prop, prop_len);\n\t\tif (ret)\n\t\t\treturn ret;\n\t}\n\n\tfdt_for_each_subnode(subnode, fdto, node) {\n\t\tconst char *name = fdt_get_name(fdto, subnode, NULL);\n\t\tint nnode;\n\t\tint ret;\n\n\t\tnnode = fdt_add_subnode(fdt, target, name);\n\t\tif (nnode == -FDT_ERR_EXISTS) {\n\t\t\tnnode = fdt_subnode_offset(fdt, target, name);\n\t\t\tif (nnode == -FDT_ERR_NOTFOUND)\n\t\t\t\treturn -FDT_ERR_INTERNAL;\n\t\t}\n\n\t\tif (nnode < 0)\n\t\t\treturn nnode;\n\n\t\tret = overlay_apply_node(fdt, nnode, fdto, subnode);\n\t\tif (ret)\n\t\t\treturn ret;\n\t}\n\n\treturn 0;\n}\n\n/**\n * overlay_merge - Merge an overlay into its base device tree\n * @fdt: Base Device Tree blob\n * @fdto: Device tree overlay blob\n *\n * overlay_merge() merges an overlay into its base device tree.\n *\n * This is the next to last step in the device tree overlay application\n * process, when all the phandles have been adjusted and resolved and\n * you just have to merge overlay into the base device tree.\n *\n * returns:\n *      0 on success\n *      Negative error code on failure\n */\nstatic int overlay_merge(void *fdt, void *fdto)\n{\n\tint fragment;\n\n\tfdt_for_each_subnode(fragment, fdto, 0) {\n\t\tint overlay;\n\t\tint target;\n\t\tint ret;\n\n\t\t/*\n\t\t * Each fragments will have an __overlay__ node. If\n\t\t * they don't, it's not supposed to be merged\n\t\t */\n\t\toverlay = fdt_subnode_offset(fdto, fragment, \"__overlay__\");\n\t\tif (overlay == -FDT_ERR_NOTFOUND)\n\t\t\tcontinue;\n\n\t\tif (overlay < 0)\n\t\t\treturn overlay;\n\n\t\ttarget = overlay_get_target(fdt, fdto, fragment, NULL);\n\t\tif (target < 0)\n\t\t\treturn target;\n\n\t\tret = overlay_apply_node(fdt, target, fdto, overlay);\n\t\tif (ret)\n\t\t\treturn ret;\n\t}\n\n\treturn 0;\n}\n\nstatic int get_path_len(const void *fdt, int nodeoffset)\n{\n\tint len = 0, namelen;\n\tconst char *name;\n\n\tFDT_RO_PROBE(fdt);\n\n\tfor (;;) {\n\t\tname = fdt_get_name(fdt, nodeoffset, &namelen);\n\t\tif (!name)\n\t\t\treturn namelen;\n\n\t\t/* root? we're done */\n\t\tif (namelen == 0)\n\t\t\tbreak;\n\n\t\tnodeoffset = fdt_parent_offset(fdt, nodeoffset);\n\t\tif (nodeoffset < 0)\n\t\t\treturn nodeoffset;\n\t\tlen += namelen + 1;\n\t}\n\n\t/* in case of root pretend it's \"/\" */\n\tif (len == 0)\n\t\tlen++;\n\treturn len;\n}\n\n/**\n * overlay_symbol_update - Update the symbols of base tree after a merge\n * @fdt: Base Device Tree blob\n * @fdto: Device tree overlay blob\n *\n * overlay_symbol_update() updates the symbols of the base tree with the\n * symbols of the applied overlay\n *\n * This is the last step in the device tree overlay application\n * process, allowing the reference of overlay symbols by subsequent\n * overlay operations.\n *\n * returns:\n *      0 on success\n *      Negative error code on failure\n */\nstatic int overlay_symbol_update(void *fdt, void *fdto)\n{\n\tint root_sym, ov_sym, prop, path_len, fragment, target;\n\tint len, frag_name_len, ret, rel_path_len;\n\tconst char *s, *e;\n\tconst char *path;\n\tconst char *name;\n\tconst char *frag_name;\n\tconst char *rel_path;\n\tconst char *target_path;\n\tchar *buf;\n\tvoid *p;\n\n\tov_sym = fdt_subnode_offset(fdto, 0, \"__symbols__\");\n\n\t/* if no overlay symbols exist no problem */\n\tif (ov_sym < 0)\n\t\treturn 0;\n\n\troot_sym = fdt_subnode_offset(fdt, 0, \"__symbols__\");\n\n\t/* it no root symbols exist we should create them */\n\tif (root_sym == -FDT_ERR_NOTFOUND)\n\t\troot_sym = fdt_add_subnode(fdt, 0, \"__symbols__\");\n\n\t/* any error is fatal now */\n\tif (root_sym < 0)\n\t\treturn root_sym;\n\n\t/* iterate over each overlay symbol */\n\tfdt_for_each_property_offset(prop, fdto, ov_sym) {\n\t\tpath = fdt_getprop_by_offset(fdto, prop, &name, &path_len);\n\t\tif (!path)\n\t\t\treturn path_len;\n\n\t\t/* verify it's a string property (terminated by a single \\0) */\n\t\tif (path_len < 1 || memchr(path, '\\0', path_len) != &path[path_len - 1])\n\t\t\treturn -FDT_ERR_BADVALUE;\n\n\t\t/* keep end marker to avoid strlen() */\n\t\te = path + path_len;\n\n\t\t/* format: /<fragment-name>/__overlay__/<relative-subnode-path> */\n\n\t\tif (*path != '/')\n\t\t\treturn -FDT_ERR_BADVALUE;\n\n\t\t/* get fragment name first */\n\t\ts = strchr(path + 1, '/');\n\t\tif (!s)\n\t\t\treturn -FDT_ERR_BADOVERLAY;\n\n\t\tfrag_name = path + 1;\n\t\tfrag_name_len = s - path - 1;\n\n\t\t/* verify format; safe since \"s\" lies in \\0 terminated prop */\n\t\tlen = sizeof(\"/__overlay__/\") - 1;\n\t\tif ((e - s) < len || memcmp(s, \"/__overlay__/\", len))\n\t\t\treturn -FDT_ERR_BADOVERLAY;\n\n\t\trel_path = s + len;\n\t\trel_path_len = e - rel_path;\n\n\t\t/* find the fragment index in which the symbol lies */\n\t\tret = fdt_subnode_offset_namelen(fdto, 0, frag_name,\n\t\t\t\t\t       frag_name_len);\n\t\t/* not found? */\n\t\tif (ret < 0)\n\t\t\treturn -FDT_ERR_BADOVERLAY;\n\t\tfragment = ret;\n\n\t\t/* an __overlay__ subnode must exist */\n\t\tret = fdt_subnode_offset(fdto, fragment, \"__overlay__\");\n\t\tif (ret < 0)\n\t\t\treturn -FDT_ERR_BADOVERLAY;\n\n\t\t/* get the target of the fragment */\n\t\tret = overlay_get_target(fdt, fdto, fragment, &target_path);\n\t\tif (ret < 0)\n\t\t\treturn ret;\n\t\ttarget = ret;\n\n\t\t/* if we have a target path use */\n\t\tif (!target_path) {\n\t\t\tret = get_path_len(fdt, target);\n\t\t\tif (ret < 0)\n\t\t\t\treturn ret;\n\t\t\tlen = ret;\n\t\t} else {\n\t\t\tlen = strlen(target_path);\n\t\t}\n\n\t\tret = fdt_setprop_placeholder(fdt, root_sym, name,\n\t\t\t\tlen + (len > 1) + rel_path_len + 1, &p);\n\t\tif (ret < 0)\n\t\t\treturn ret;\n\n\t\tif (!target_path) {\n\t\t\t/* again in case setprop_placeholder changed it */\n\t\t\tret = overlay_get_target(fdt, fdto, fragment, &target_path);\n\t\t\tif (ret < 0)\n\t\t\t\treturn ret;\n\t\t\ttarget = ret;\n\t\t}\n\n\t\tbuf = p;\n\t\tif (len > 1) { /* target is not root */\n\t\t\tif (!target_path) {\n\t\t\t\tret = fdt_get_path(fdt, target, buf, len + 1);\n\t\t\t\tif (ret < 0)\n\t\t\t\t\treturn ret;\n\t\t\t} else\n\t\t\t\tmemcpy(buf, target_path, len + 1);\n\n\t\t} else\n\t\t\tlen--;\n\n\t\tbuf[len] = '/';\n\t\tmemcpy(buf + len + 1, rel_path, rel_path_len);\n\t\tbuf[len + 1 + rel_path_len] = '\\0';\n\t}\n\n\treturn 0;\n}\n\nint fdt_overlay_apply(void *fdt, void *fdto)\n{\n\tuint32_t delta = fdt_get_max_phandle(fdt);\n\tint ret;\n\n\tFDT_RO_PROBE(fdt);\n\tFDT_RO_PROBE(fdto);\n\n\tret = overlay_adjust_local_phandles(fdto, delta);\n\tif (ret)\n\t\tgoto err;\n\n\tret = overlay_update_local_references(fdto, delta);\n\tif (ret)\n\t\tgoto err;\n\n\tret = overlay_fixup_phandles(fdt, fdto);\n\tif (ret)\n\t\tgoto err;\n\n\tret = overlay_merge(fdt, fdto);\n\tif (ret)\n\t\tgoto err;\n\n\tret = overlay_symbol_update(fdt, fdto);\n\tif (ret)\n\t\tgoto err;\n\n\t/*\n\t * The overlay has been damaged, erase its magic.\n\t */\n\tfdt_set_magic(fdto, ~0);\n\n\treturn 0;\n\nerr:\n\t/*\n\t * The overlay might have been damaged, erase its magic.\n\t */\n\tfdt_set_magic(fdto, ~0);\n\n\t/*\n\t * The base device tree might have been damaged, erase its\n\t * magic.\n\t */\n\tfdt_set_magic(fdt, ~0);\n\n\treturn ret;\n}\n"
  },
  {
    "path": "user.libs/libfdt/src/fdt_ro.c",
    "content": "/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2006 David Gibson, IBM Corporation.\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n#include <libfdt/libfdt_env.h>\n\n#include <libfdt/fdt.h>\n#include <libfdt/libfdt.h>\n\n#include \"libfdt_internal.h\"\n\nstatic int fdt_nodename_eq_(const void *fdt, int offset,\n\t\t\t    const char *s, int len)\n{\n\tint olen;\n\tconst char *p = fdt_get_name(fdt, offset, &olen);\n\n\tif (!p || olen < len)\n\t\t/* short match */\n\t\treturn 0;\n\n\tif (memcmp(p, s, len) != 0)\n\t\treturn 0;\n\n\tif (p[len] == '\\0')\n\t\treturn 1;\n\telse if (!memchr(s, '@', len) && (p[len] == '@'))\n\t\treturn 1;\n\telse\n\t\treturn 0;\n}\n\nconst char *fdt_get_string(const void *fdt, int stroffset, int *lenp)\n{\n\tuint32_t absoffset = stroffset + fdt_off_dt_strings(fdt);\n\tsize_t len;\n\tint err;\n\tconst char *s, *n;\n\n\terr = fdt_ro_probe_(fdt);\n\tif (err != 0)\n\t\tgoto fail;\n\n\terr = -FDT_ERR_BADOFFSET;\n\tif (absoffset >= fdt_totalsize(fdt))\n\t\tgoto fail;\n\tlen = fdt_totalsize(fdt) - absoffset;\n\n\tif (fdt_magic(fdt) == FDT_MAGIC) {\n\t\tif (stroffset < 0)\n\t\t\tgoto fail;\n\t\tif (fdt_version(fdt) >= 17) {\n\t\t\tif (stroffset >= fdt_size_dt_strings(fdt))\n\t\t\t\tgoto fail;\n\t\t\tif ((fdt_size_dt_strings(fdt) - stroffset) < len)\n\t\t\t\tlen = fdt_size_dt_strings(fdt) - stroffset;\n\t\t}\n\t} else if (fdt_magic(fdt) == FDT_SW_MAGIC) {\n\t\tif ((stroffset >= 0)\n\t\t    || (stroffset < -fdt_size_dt_strings(fdt)))\n\t\t\tgoto fail;\n\t\tif ((-stroffset) < len)\n\t\t\tlen = -stroffset;\n\t} else {\n\t\terr = -FDT_ERR_INTERNAL;\n\t\tgoto fail;\n\t}\n\n\ts = (const char *)fdt + absoffset;\n\tn = memchr(s, '\\0', len);\n\tif (!n) {\n\t\t/* missing terminating NULL */\n\t\terr = -FDT_ERR_TRUNCATED;\n\t\tgoto fail;\n\t}\n\n\tif (lenp)\n\t\t*lenp = n - s;\n\treturn s;\n\nfail:\n\tif (lenp)\n\t\t*lenp = err;\n\treturn NULL;\n}\n\nconst char *fdt_string(const void *fdt, int stroffset)\n{\n\treturn fdt_get_string(fdt, stroffset, NULL);\n}\n\nstatic int fdt_string_eq_(const void *fdt, int stroffset,\n\t\t\t  const char *s, int len)\n{\n\tint slen;\n\tconst char *p = fdt_get_string(fdt, stroffset, &slen);\n\n\treturn p && (slen == len) && (memcmp(p, s, len) == 0);\n}\n\nuint32_t fdt_get_max_phandle(const void *fdt)\n{\n\tuint32_t max_phandle = 0;\n\tint offset;\n\n\tfor (offset = fdt_next_node(fdt, -1, NULL);;\n\t     offset = fdt_next_node(fdt, offset, NULL)) {\n\t\tuint32_t phandle;\n\n\t\tif (offset == -FDT_ERR_NOTFOUND)\n\t\t\treturn max_phandle;\n\n\t\tif (offset < 0)\n\t\t\treturn (uint32_t)-1;\n\n\t\tphandle = fdt_get_phandle(fdt, offset);\n\t\tif (phandle == (uint32_t)-1)\n\t\t\tcontinue;\n\n\t\tif (phandle > max_phandle)\n\t\t\tmax_phandle = phandle;\n\t}\n\n\treturn 0;\n}\n\nstatic const struct fdt_reserve_entry *fdt_mem_rsv(const void *fdt, int n)\n{\n\tint offset = n * sizeof(struct fdt_reserve_entry);\n\tint absoffset = fdt_off_mem_rsvmap(fdt) + offset;\n\n\tif (absoffset < fdt_off_mem_rsvmap(fdt))\n\t\treturn NULL;\n\tif (absoffset > fdt_totalsize(fdt) - sizeof(struct fdt_reserve_entry))\n\t\treturn NULL;\n\treturn fdt_mem_rsv_(fdt, n);\n}\n\nint fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)\n{\n\tconst struct fdt_reserve_entry *re;\n\n\tFDT_RO_PROBE(fdt);\n\tre = fdt_mem_rsv(fdt, n);\n\tif (!re)\n\t\treturn -FDT_ERR_BADOFFSET;\n\n\t*address = fdt64_ld(&re->address);\n\t*size = fdt64_ld(&re->size);\n\treturn 0;\n}\n\nint fdt_num_mem_rsv(const void *fdt)\n{\n\tint i;\n\tconst struct fdt_reserve_entry *re;\n\n\tfor (i = 0; (re = fdt_mem_rsv(fdt, i)) != NULL; i++) {\n\t\tif (fdt64_ld(&re->size) == 0)\n\t\t\treturn i;\n\t}\n\treturn -FDT_ERR_TRUNCATED;\n}\n\nstatic int nextprop_(const void *fdt, int offset)\n{\n\tuint32_t tag;\n\tint nextoffset;\n\n\tdo {\n\t\ttag = fdt_next_tag(fdt, offset, &nextoffset);\n\n\t\tswitch (tag) {\n\t\tcase FDT_END:\n\t\t\tif (nextoffset >= 0)\n\t\t\t\treturn -FDT_ERR_BADSTRUCTURE;\n\t\t\telse\n\t\t\t\treturn nextoffset;\n\n\t\tcase FDT_PROP:\n\t\t\treturn offset;\n\t\t}\n\t\toffset = nextoffset;\n\t} while (tag == FDT_NOP);\n\n\treturn -FDT_ERR_NOTFOUND;\n}\n\nint fdt_subnode_offset_namelen(const void *fdt, int offset,\n\t\t\t       const char *name, int namelen)\n{\n\tint depth;\n\n\tFDT_RO_PROBE(fdt);\n\n\tfor (depth = 0;\n\t     (offset >= 0) && (depth >= 0);\n\t     offset = fdt_next_node(fdt, offset, &depth))\n\t\tif ((depth == 1)\n\t\t    && fdt_nodename_eq_(fdt, offset, name, namelen))\n\t\t\treturn offset;\n\n\tif (depth < 0)\n\t\treturn -FDT_ERR_NOTFOUND;\n\treturn offset; /* error */\n}\n\nint fdt_subnode_offset(const void *fdt, int parentoffset,\n\t\t       const char *name)\n{\n\treturn fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name));\n}\n\nint fdt_path_offset_namelen(const void *fdt, const char *path, int namelen)\n{\n\tconst char *end = path + namelen;\n\tconst char *p = path;\n\tint offset = 0;\n\n\tFDT_RO_PROBE(fdt);\n\n\t/* see if we have an alias */\n\tif (*path != '/') {\n\t\tconst char *q = memchr(path, '/', end - p);\n\n\t\tif (!q)\n\t\t\tq = end;\n\n\t\tp = fdt_get_alias_namelen(fdt, p, q - p);\n\t\tif (!p)\n\t\t\treturn -FDT_ERR_BADPATH;\n\t\toffset = fdt_path_offset(fdt, p);\n\n\t\tp = q;\n\t}\n\n\twhile (p < end) {\n\t\tconst char *q;\n\n\t\twhile (*p == '/') {\n\t\t\tp++;\n\t\t\tif (p == end)\n\t\t\t\treturn offset;\n\t\t}\n\t\tq = memchr(p, '/', end - p);\n\t\tif (! q)\n\t\t\tq = end;\n\n\t\toffset = fdt_subnode_offset_namelen(fdt, offset, p, q-p);\n\t\tif (offset < 0)\n\t\t\treturn offset;\n\n\t\tp = q;\n\t}\n\n\treturn offset;\n}\n\nint fdt_path_offset(const void *fdt, const char *path)\n{\n\treturn fdt_path_offset_namelen(fdt, path, strlen(path));\n}\n\nconst char *fdt_get_name(const void *fdt, int nodeoffset, int *len)\n{\n\tconst struct fdt_node_header *nh = fdt_offset_ptr_(fdt, nodeoffset);\n\tconst char *nameptr;\n\tint err;\n\n\tif (((err = fdt_ro_probe_(fdt)) != 0)\n\t    || ((err = fdt_check_node_offset_(fdt, nodeoffset)) < 0))\n\t\t\tgoto fail;\n\n\tnameptr = nh->name;\n\n\tif (fdt_version(fdt) < 0x10) {\n\t\t/*\n\t\t * For old FDT versions, match the naming conventions of V16:\n\t\t * give only the leaf name (after all /). The actual tree\n\t\t * contents are loosely checked.\n\t\t */\n\t\tconst char *leaf;\n\t\tleaf = strrchr(nameptr, '/');\n\t\tif (leaf == NULL) {\n\t\t\terr = -FDT_ERR_BADSTRUCTURE;\n\t\t\tgoto fail;\n\t\t}\n\t\tnameptr = leaf+1;\n\t}\n\n\tif (len)\n\t\t*len = strlen(nameptr);\n\n\treturn nameptr;\n\n fail:\n\tif (len)\n\t\t*len = err;\n\treturn NULL;\n}\n\nint fdt_first_property_offset(const void *fdt, int nodeoffset)\n{\n\tint offset;\n\n\tif ((offset = fdt_check_node_offset_(fdt, nodeoffset)) < 0)\n\t\treturn offset;\n\n\treturn nextprop_(fdt, offset);\n}\n\nint fdt_next_property_offset(const void *fdt, int offset)\n{\n\tif ((offset = fdt_check_prop_offset_(fdt, offset)) < 0)\n\t\treturn offset;\n\n\treturn nextprop_(fdt, offset);\n}\n\nstatic const struct fdt_property *fdt_get_property_by_offset_(const void *fdt,\n\t\t\t\t\t\t              int offset,\n\t\t\t\t\t\t              int *lenp)\n{\n\tint err;\n\tconst struct fdt_property *prop;\n\n\tif ((err = fdt_check_prop_offset_(fdt, offset)) < 0) {\n\t\tif (lenp)\n\t\t\t*lenp = err;\n\t\treturn NULL;\n\t}\n\n\tprop = fdt_offset_ptr_(fdt, offset);\n\n\tif (lenp)\n\t\t*lenp = fdt32_ld(&prop->len);\n\n\treturn prop;\n}\n\nconst struct fdt_property *fdt_get_property_by_offset(const void *fdt,\n\t\t\t\t\t\t      int offset,\n\t\t\t\t\t\t      int *lenp)\n{\n\t/* Prior to version 16, properties may need realignment\n\t * and this API does not work. fdt_getprop_*() will, however. */\n\n\tif (fdt_version(fdt) < 0x10) {\n\t\tif (lenp)\n\t\t\t*lenp = -FDT_ERR_BADVERSION;\n\t\treturn NULL;\n\t}\n\n\treturn fdt_get_property_by_offset_(fdt, offset, lenp);\n}\n\nstatic const struct fdt_property *fdt_get_property_namelen_(const void *fdt,\n\t\t\t\t\t\t            int offset,\n\t\t\t\t\t\t            const char *name,\n\t\t\t\t\t\t            int namelen,\n\t\t\t\t\t\t\t    int *lenp,\n\t\t\t\t\t\t\t    int *poffset)\n{\n\tfor (offset = fdt_first_property_offset(fdt, offset);\n\t     (offset >= 0);\n\t     (offset = fdt_next_property_offset(fdt, offset))) {\n\t\tconst struct fdt_property *prop;\n\n\t\tif (!(prop = fdt_get_property_by_offset_(fdt, offset, lenp))) {\n\t\t\toffset = -FDT_ERR_INTERNAL;\n\t\t\tbreak;\n\t\t}\n\t\tif (fdt_string_eq_(fdt, fdt32_ld(&prop->nameoff),\n\t\t\t\t   name, namelen)) {\n\t\t\tif (poffset)\n\t\t\t\t*poffset = offset;\n\t\t\treturn prop;\n\t\t}\n\t}\n\n\tif (lenp)\n\t\t*lenp = offset;\n\treturn NULL;\n}\n\n\nconst struct fdt_property *fdt_get_property_namelen(const void *fdt,\n\t\t\t\t\t\t    int offset,\n\t\t\t\t\t\t    const char *name,\n\t\t\t\t\t\t    int namelen, int *lenp)\n{\n\t/* Prior to version 16, properties may need realignment\n\t * and this API does not work. fdt_getprop_*() will, however. */\n\tif (fdt_version(fdt) < 0x10) {\n\t\tif (lenp)\n\t\t\t*lenp = -FDT_ERR_BADVERSION;\n\t\treturn NULL;\n\t}\n\n\treturn fdt_get_property_namelen_(fdt, offset, name, namelen, lenp,\n\t\t\t\t\t NULL);\n}\n\n\nconst struct fdt_property *fdt_get_property(const void *fdt,\n\t\t\t\t\t    int nodeoffset,\n\t\t\t\t\t    const char *name, int *lenp)\n{\n\treturn fdt_get_property_namelen(fdt, nodeoffset, name,\n\t\t\t\t\tstrlen(name), lenp);\n}\n\nconst void *fdt_getprop_namelen(const void *fdt, int nodeoffset,\n\t\t\t\tconst char *name, int namelen, int *lenp)\n{\n\tint poffset;\n\tconst struct fdt_property *prop;\n\n\tprop = fdt_get_property_namelen_(fdt, nodeoffset, name, namelen, lenp,\n\t\t\t\t\t &poffset);\n\tif (!prop)\n\t\treturn NULL;\n\n\t/* Handle realignment */\n\tif (fdt_version(fdt) < 0x10 && (poffset + sizeof(*prop)) % 8 &&\n\t    fdt32_ld(&prop->len) >= 8)\n\t\treturn prop->data + 4;\n\treturn prop->data;\n}\n\nconst void *fdt_getprop_by_offset(const void *fdt, int offset,\n\t\t\t\t  const char **namep, int *lenp)\n{\n\tconst struct fdt_property *prop;\n\n\tprop = fdt_get_property_by_offset_(fdt, offset, lenp);\n\tif (!prop)\n\t\treturn NULL;\n\tif (namep) {\n\t\tconst char *name;\n\t\tint namelen;\n\t\tname = fdt_get_string(fdt, fdt32_ld(&prop->nameoff),\n\t\t\t\t      &namelen);\n\t\tif (!name) {\n\t\t\tif (lenp)\n\t\t\t\t*lenp = namelen;\n\t\t\treturn NULL;\n\t\t}\n\t\t*namep = name;\n\t}\n\n\t/* Handle realignment */\n\tif (fdt_version(fdt) < 0x10 && (offset + sizeof(*prop)) % 8 &&\n\t    fdt32_ld(&prop->len) >= 8)\n\t\treturn prop->data + 4;\n\treturn prop->data;\n}\n\nconst void *fdt_getprop(const void *fdt, int nodeoffset,\n\t\t\tconst char *name, int *lenp)\n{\n\treturn fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), lenp);\n}\n\nuint32_t fdt_get_phandle(const void *fdt, int nodeoffset)\n{\n\tconst fdt32_t *php;\n\tint len;\n\n\t/* FIXME: This is a bit sub-optimal, since we potentially scan\n\t * over all the properties twice. */\n\tphp = fdt_getprop(fdt, nodeoffset, \"phandle\", &len);\n\tif (!php || (len != sizeof(*php))) {\n\t\tphp = fdt_getprop(fdt, nodeoffset, \"linux,phandle\", &len);\n\t\tif (!php || (len != sizeof(*php)))\n\t\t\treturn 0;\n\t}\n\n\treturn fdt32_ld(php);\n}\n\nconst char *fdt_get_alias_namelen(const void *fdt,\n\t\t\t\t  const char *name, int namelen)\n{\n\tint aliasoffset;\n\n\taliasoffset = fdt_path_offset(fdt, \"/aliases\");\n\tif (aliasoffset < 0)\n\t\treturn NULL;\n\n\treturn fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL);\n}\n\nconst char *fdt_get_alias(const void *fdt, const char *name)\n{\n\treturn fdt_get_alias_namelen(fdt, name, strlen(name));\n}\n\nint fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)\n{\n\tint pdepth = 0, p = 0;\n\tint offset, depth, namelen;\n\tconst char *name;\n\n\tFDT_RO_PROBE(fdt);\n\n\tif (buflen < 2)\n\t\treturn -FDT_ERR_NOSPACE;\n\n\tfor (offset = 0, depth = 0;\n\t     (offset >= 0) && (offset <= nodeoffset);\n\t     offset = fdt_next_node(fdt, offset, &depth)) {\n\t\twhile (pdepth > depth) {\n\t\t\tdo {\n\t\t\t\tp--;\n\t\t\t} while (buf[p-1] != '/');\n\t\t\tpdepth--;\n\t\t}\n\n\t\tif (pdepth >= depth) {\n\t\t\tname = fdt_get_name(fdt, offset, &namelen);\n\t\t\tif (!name)\n\t\t\t\treturn namelen;\n\t\t\tif ((p + namelen + 1) <= buflen) {\n\t\t\t\tmemcpy(buf + p, name, namelen);\n\t\t\t\tp += namelen;\n\t\t\t\tbuf[p++] = '/';\n\t\t\t\tpdepth++;\n\t\t\t}\n\t\t}\n\n\t\tif (offset == nodeoffset) {\n\t\t\tif (pdepth < (depth + 1))\n\t\t\t\treturn -FDT_ERR_NOSPACE;\n\n\t\t\tif (p > 1) /* special case so that root path is \"/\", not \"\" */\n\t\t\t\tp--;\n\t\t\tbuf[p] = '\\0';\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\tif ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))\n\t\treturn -FDT_ERR_BADOFFSET;\n\telse if (offset == -FDT_ERR_BADOFFSET)\n\t\treturn -FDT_ERR_BADSTRUCTURE;\n\n\treturn offset; /* error from fdt_next_node() */\n}\n\nint fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,\n\t\t\t\t int supernodedepth, int *nodedepth)\n{\n\tint offset, depth;\n\tint supernodeoffset = -FDT_ERR_INTERNAL;\n\n\tFDT_RO_PROBE(fdt);\n\n\tif (supernodedepth < 0)\n\t\treturn -FDT_ERR_NOTFOUND;\n\n\tfor (offset = 0, depth = 0;\n\t     (offset >= 0) && (offset <= nodeoffset);\n\t     offset = fdt_next_node(fdt, offset, &depth)) {\n\t\tif (depth == supernodedepth)\n\t\t\tsupernodeoffset = offset;\n\n\t\tif (offset == nodeoffset) {\n\t\t\tif (nodedepth)\n\t\t\t\t*nodedepth = depth;\n\n\t\t\tif (supernodedepth > depth)\n\t\t\t\treturn -FDT_ERR_NOTFOUND;\n\t\t\telse\n\t\t\t\treturn supernodeoffset;\n\t\t}\n\t}\n\n\tif ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))\n\t\treturn -FDT_ERR_BADOFFSET;\n\telse if (offset == -FDT_ERR_BADOFFSET)\n\t\treturn -FDT_ERR_BADSTRUCTURE;\n\n\treturn offset; /* error from fdt_next_node() */\n}\n\nint fdt_node_depth(const void *fdt, int nodeoffset)\n{\n\tint nodedepth;\n\tint err;\n\n\terr = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);\n\tif (err)\n\t\treturn (err < 0) ? err : -FDT_ERR_INTERNAL;\n\treturn nodedepth;\n}\n\nint fdt_parent_offset(const void *fdt, int nodeoffset)\n{\n\tint nodedepth = fdt_node_depth(fdt, nodeoffset);\n\n\tif (nodedepth < 0)\n\t\treturn nodedepth;\n\treturn fdt_supernode_atdepth_offset(fdt, nodeoffset,\n\t\t\t\t\t    nodedepth - 1, NULL);\n}\n\nint fdt_node_offset_by_prop_value(const void *fdt, int startoffset,\n\t\t\t\t  const char *propname,\n\t\t\t\t  const void *propval, int proplen)\n{\n\tint offset;\n\tconst void *val;\n\tint len;\n\n\tFDT_RO_PROBE(fdt);\n\n\t/* FIXME: The algorithm here is pretty horrible: we scan each\n\t * property of a node in fdt_getprop(), then if that didn't\n\t * find what we want, we scan over them again making our way\n\t * to the next node.  Still it's the easiest to implement\n\t * approach; performance can come later. */\n\tfor (offset = fdt_next_node(fdt, startoffset, NULL);\n\t     offset >= 0;\n\t     offset = fdt_next_node(fdt, offset, NULL)) {\n\t\tval = fdt_getprop(fdt, offset, propname, &len);\n\t\tif (val && (len == proplen)\n\t\t    && (memcmp(val, propval, len) == 0))\n\t\t\treturn offset;\n\t}\n\n\treturn offset; /* error from fdt_next_node() */\n}\n\nint fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)\n{\n\tint offset;\n\n\tif ((phandle == 0) || (phandle == -1))\n\t\treturn -FDT_ERR_BADPHANDLE;\n\n\tFDT_RO_PROBE(fdt);\n\n\t/* FIXME: The algorithm here is pretty horrible: we\n\t * potentially scan each property of a node in\n\t * fdt_get_phandle(), then if that didn't find what\n\t * we want, we scan over them again making our way to the next\n\t * node.  Still it's the easiest to implement approach;\n\t * performance can come later. */\n\tfor (offset = fdt_next_node(fdt, -1, NULL);\n\t     offset >= 0;\n\t     offset = fdt_next_node(fdt, offset, NULL)) {\n\t\tif (fdt_get_phandle(fdt, offset) == phandle)\n\t\t\treturn offset;\n\t}\n\n\treturn offset; /* error from fdt_next_node() */\n}\n\nint fdt_stringlist_contains(const char *strlist, int listlen, const char *str)\n{\n\tint len = strlen(str);\n\tconst char *p;\n\n\twhile (listlen >= len) {\n\t\tif (memcmp(str, strlist, len+1) == 0)\n\t\t\treturn 1;\n\t\tp = memchr(strlist, '\\0', listlen);\n\t\tif (!p)\n\t\t\treturn 0; /* malformed strlist.. */\n\t\tlistlen -= (p-strlist) + 1;\n\t\tstrlist = p + 1;\n\t}\n\treturn 0;\n}\n\nint fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property)\n{\n\tconst char *list, *end;\n\tint length, count = 0;\n\n\tlist = fdt_getprop(fdt, nodeoffset, property, &length);\n\tif (!list)\n\t\treturn length;\n\n\tend = list + length;\n\n\twhile (list < end) {\n\t\tlength = strnlen(list, end - list) + 1;\n\n\t\t/* Abort if the last string isn't properly NUL-terminated. */\n\t\tif (list + length > end)\n\t\t\treturn -FDT_ERR_BADVALUE;\n\n\t\tlist += length;\n\t\tcount++;\n\t}\n\n\treturn count;\n}\n\nint fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property,\n\t\t\t  const char *string)\n{\n\tint length, len, idx = 0;\n\tconst char *list, *end;\n\n\tlist = fdt_getprop(fdt, nodeoffset, property, &length);\n\tif (!list)\n\t\treturn length;\n\n\tlen = strlen(string) + 1;\n\tend = list + length;\n\n\twhile (list < end) {\n\t\tlength = strnlen(list, end - list) + 1;\n\n\t\t/* Abort if the last string isn't properly NUL-terminated. */\n\t\tif (list + length > end)\n\t\t\treturn -FDT_ERR_BADVALUE;\n\n\t\tif (length == len && memcmp(list, string, length) == 0)\n\t\t\treturn idx;\n\n\t\tlist += length;\n\t\tidx++;\n\t}\n\n\treturn -FDT_ERR_NOTFOUND;\n}\n\nconst char *fdt_stringlist_get(const void *fdt, int nodeoffset,\n\t\t\t       const char *property, int idx,\n\t\t\t       int *lenp)\n{\n\tconst char *list, *end;\n\tint length;\n\n\tlist = fdt_getprop(fdt, nodeoffset, property, &length);\n\tif (!list) {\n\t\tif (lenp)\n\t\t\t*lenp = length;\n\n\t\treturn NULL;\n\t}\n\n\tend = list + length;\n\n\twhile (list < end) {\n\t\tlength = strnlen(list, end - list) + 1;\n\n\t\t/* Abort if the last string isn't properly NUL-terminated. */\n\t\tif (list + length > end) {\n\t\t\tif (lenp)\n\t\t\t\t*lenp = -FDT_ERR_BADVALUE;\n\n\t\t\treturn NULL;\n\t\t}\n\n\t\tif (idx == 0) {\n\t\t\tif (lenp)\n\t\t\t\t*lenp = length - 1;\n\n\t\t\treturn list;\n\t\t}\n\n\t\tlist += length;\n\t\tidx--;\n\t}\n\n\tif (lenp)\n\t\t*lenp = -FDT_ERR_NOTFOUND;\n\n\treturn NULL;\n}\n\nint fdt_node_check_compatible(const void *fdt, int nodeoffset,\n\t\t\t      const char *compatible)\n{\n\tconst void *prop;\n\tint len;\n\n\tprop = fdt_getprop(fdt, nodeoffset, \"compatible\", &len);\n\tif (!prop)\n\t\treturn len;\n\n\treturn !fdt_stringlist_contains(prop, len, compatible);\n}\n\nint fdt_node_offset_by_compatible(const void *fdt, int startoffset,\n\t\t\t\t  const char *compatible)\n{\n\tint offset, err;\n\n\tFDT_RO_PROBE(fdt);\n\n\t/* FIXME: The algorithm here is pretty horrible: we scan each\n\t * property of a node in fdt_node_check_compatible(), then if\n\t * that didn't find what we want, we scan over them again\n\t * making our way to the next node.  Still it's the easiest to\n\t * implement approach; performance can come later. */\n\tfor (offset = fdt_next_node(fdt, startoffset, NULL);\n\t     offset >= 0;\n\t     offset = fdt_next_node(fdt, offset, NULL)) {\n\t\terr = fdt_node_check_compatible(fdt, offset, compatible);\n\t\tif ((err < 0) && (err != -FDT_ERR_NOTFOUND))\n\t\t\treturn err;\n\t\telse if (err == 0)\n\t\t\treturn offset;\n\t}\n\n\treturn offset; /* error from fdt_next_node() */\n}\n\nint fdt_check_full(const void *fdt, size_t bufsize)\n{\n\tint err;\n\tint num_memrsv;\n\tint offset, nextoffset = 0;\n\tuint32_t tag;\n\tunsigned depth = 0;\n\tconst void *prop;\n\tconst char *propname;\n\n\tif (bufsize < FDT_V1_SIZE)\n\t\treturn -FDT_ERR_TRUNCATED;\n\terr = fdt_check_header(fdt);\n\tif (err != 0)\n\t\treturn err;\n\tif (bufsize < fdt_totalsize(fdt))\n\t\treturn -FDT_ERR_TRUNCATED;\n\n\tnum_memrsv = fdt_num_mem_rsv(fdt);\n\tif (num_memrsv < 0)\n\t\treturn num_memrsv;\n\n\twhile (1) {\n\t\toffset = nextoffset;\n\t\ttag = fdt_next_tag(fdt, offset, &nextoffset);\n\n\t\tif (nextoffset < 0)\n\t\t\treturn nextoffset;\n\n\t\tswitch (tag) {\n\t\tcase FDT_NOP:\n\t\t\tbreak;\n\n\t\tcase FDT_END:\n\t\t\tif (depth != 0)\n\t\t\t\treturn -FDT_ERR_BADSTRUCTURE;\n\t\t\treturn 0;\n\n\t\tcase FDT_BEGIN_NODE:\n\t\t\tdepth++;\n\t\t\tif (depth > INT_MAX)\n\t\t\t\treturn -FDT_ERR_BADSTRUCTURE;\n\t\t\tbreak;\n\n\t\tcase FDT_END_NODE:\n\t\t\tif (depth == 0)\n\t\t\t\treturn -FDT_ERR_BADSTRUCTURE;\n\t\t\tdepth--;\n\t\t\tbreak;\n\n\t\tcase FDT_PROP:\n\t\t\tprop = fdt_getprop_by_offset(fdt, offset, &propname,\n\t\t\t\t\t\t     &err);\n\t\t\tif (!prop)\n\t\t\t\treturn err;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\treturn -FDT_ERR_INTERNAL;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "user.libs/libfdt/src/fdt_rw.c",
    "content": "/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2006 David Gibson, IBM Corporation.\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n#include <libfdt/libfdt_env.h>\n\n#include <libfdt/fdt.h>\n#include <libfdt/libfdt.h>\n\n#include \"libfdt_internal.h\"\n\nstatic int fdt_blocks_misordered_(const void *fdt,\n\t\t\t\t  int mem_rsv_size, int struct_size)\n{\n\treturn (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8))\n\t\t|| (fdt_off_dt_struct(fdt) <\n\t\t    (fdt_off_mem_rsvmap(fdt) + mem_rsv_size))\n\t\t|| (fdt_off_dt_strings(fdt) <\n\t\t    (fdt_off_dt_struct(fdt) + struct_size))\n\t\t|| (fdt_totalsize(fdt) <\n\t\t    (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));\n}\n\nstatic int fdt_rw_probe_(void *fdt)\n{\n\tFDT_RO_PROBE(fdt);\n\n\tif (fdt_version(fdt) < 17)\n\t\treturn -FDT_ERR_BADVERSION;\n\tif (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry),\n\t\t\t\t   fdt_size_dt_struct(fdt)))\n\t\treturn -FDT_ERR_BADLAYOUT;\n\tif (fdt_version(fdt) > 17)\n\t\tfdt_set_version(fdt, 17);\n\n\treturn 0;\n}\n\n#define FDT_RW_PROBE(fdt) \\\n\t{ \\\n\t\tint err_; \\\n\t\tif ((err_ = fdt_rw_probe_(fdt)) != 0) \\\n\t\t\treturn err_; \\\n\t}\n\nstatic inline int fdt_data_size_(void *fdt)\n{\n\treturn fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);\n}\n\nstatic int fdt_splice_(void *fdt, void *splicepoint, int oldlen, int newlen)\n{\n\tchar *p = splicepoint;\n\tchar *end = (char *)fdt + fdt_data_size_(fdt);\n\n\tif (((p + oldlen) < p) || ((p + oldlen) > end))\n\t\treturn -FDT_ERR_BADOFFSET;\n\tif ((p < (char *)fdt) || ((end - oldlen + newlen) < (char *)fdt))\n\t\treturn -FDT_ERR_BADOFFSET;\n\tif ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt)))\n\t\treturn -FDT_ERR_NOSPACE;\n\tmemmove(p + newlen, p + oldlen, end - p - oldlen);\n\treturn 0;\n}\n\nstatic int fdt_splice_mem_rsv_(void *fdt, struct fdt_reserve_entry *p,\n\t\t\t       int oldn, int newn)\n{\n\tint delta = (newn - oldn) * sizeof(*p);\n\tint err;\n\terr = fdt_splice_(fdt, p, oldn * sizeof(*p), newn * sizeof(*p));\n\tif (err)\n\t\treturn err;\n\tfdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta);\n\tfdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);\n\treturn 0;\n}\n\nstatic int fdt_splice_struct_(void *fdt, void *p,\n\t\t\t      int oldlen, int newlen)\n{\n\tint delta = newlen - oldlen;\n\tint err;\n\n\tif ((err = fdt_splice_(fdt, p, oldlen, newlen)))\n\t\treturn err;\n\n\tfdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta);\n\tfdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);\n\treturn 0;\n}\n\nstatic int fdt_splice_string_(void *fdt, int newlen)\n{\n\tvoid *p = (char *)fdt\n\t\t+ fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);\n\tint err;\n\n\tif ((err = fdt_splice_(fdt, p, 0, newlen)))\n\t\treturn err;\n\n\tfdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen);\n\treturn 0;\n}\n\nstatic int fdt_find_add_string_(void *fdt, const char *s)\n{\n\tchar *strtab = (char *)fdt + fdt_off_dt_strings(fdt);\n\tconst char *p;\n\tchar *new;\n\tint len = strlen(s) + 1;\n\tint err;\n\n\tp = fdt_find_string_(strtab, fdt_size_dt_strings(fdt), s);\n\tif (p)\n\t\t/* found it */\n\t\treturn (p - strtab);\n\n\tnew = strtab + fdt_size_dt_strings(fdt);\n\terr = fdt_splice_string_(fdt, len);\n\tif (err)\n\t\treturn err;\n\n\tmemcpy(new, s, len);\n\treturn (new - strtab);\n}\n\nint fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)\n{\n\tstruct fdt_reserve_entry *re;\n\tint err;\n\n\tFDT_RW_PROBE(fdt);\n\n\tre = fdt_mem_rsv_w_(fdt, fdt_num_mem_rsv(fdt));\n\terr = fdt_splice_mem_rsv_(fdt, re, 0, 1);\n\tif (err)\n\t\treturn err;\n\n\tre->address = cpu_to_fdt64(address);\n\tre->size = cpu_to_fdt64(size);\n\treturn 0;\n}\n\nint fdt_del_mem_rsv(void *fdt, int n)\n{\n\tstruct fdt_reserve_entry *re = fdt_mem_rsv_w_(fdt, n);\n\n\tFDT_RW_PROBE(fdt);\n\n\tif (n >= fdt_num_mem_rsv(fdt))\n\t\treturn -FDT_ERR_NOTFOUND;\n\n\treturn fdt_splice_mem_rsv_(fdt, re, 1, 0);\n}\n\nstatic int fdt_resize_property_(void *fdt, int nodeoffset, const char *name,\n\t\t\t\tint len, struct fdt_property **prop)\n{\n\tint oldlen;\n\tint err;\n\n\t*prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);\n\tif (!*prop)\n\t\treturn oldlen;\n\n\tif ((err = fdt_splice_struct_(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),\n\t\t\t\t      FDT_TAGALIGN(len))))\n\t\treturn err;\n\n\t(*prop)->len = cpu_to_fdt32(len);\n\treturn 0;\n}\n\nstatic int fdt_add_property_(void *fdt, int nodeoffset, const char *name,\n\t\t\t     int len, struct fdt_property **prop)\n{\n\tint proplen;\n\tint nextoffset;\n\tint namestroff;\n\tint err;\n\n\tif ((nextoffset = fdt_check_node_offset_(fdt, nodeoffset)) < 0)\n\t\treturn nextoffset;\n\n\tnamestroff = fdt_find_add_string_(fdt, name);\n\tif (namestroff < 0)\n\t\treturn namestroff;\n\n\t*prop = fdt_offset_ptr_w_(fdt, nextoffset);\n\tproplen = sizeof(**prop) + FDT_TAGALIGN(len);\n\n\terr = fdt_splice_struct_(fdt, *prop, 0, proplen);\n\tif (err)\n\t\treturn err;\n\n\t(*prop)->tag = cpu_to_fdt32(FDT_PROP);\n\t(*prop)->nameoff = cpu_to_fdt32(namestroff);\n\t(*prop)->len = cpu_to_fdt32(len);\n\treturn 0;\n}\n\nint fdt_set_name(void *fdt, int nodeoffset, const char *name)\n{\n\tchar *namep;\n\tint oldlen, newlen;\n\tint err;\n\n\tFDT_RW_PROBE(fdt);\n\n\tnamep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen);\n\tif (!namep)\n\t\treturn oldlen;\n\n\tnewlen = strlen(name);\n\n\terr = fdt_splice_struct_(fdt, namep, FDT_TAGALIGN(oldlen+1),\n\t\t\t\t FDT_TAGALIGN(newlen+1));\n\tif (err)\n\t\treturn err;\n\n\tmemcpy(namep, name, newlen+1);\n\treturn 0;\n}\n\nint fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,\n\t\t\t    int len, void **prop_data)\n{\n\tstruct fdt_property *prop;\n\tint err;\n\n\tFDT_RW_PROBE(fdt);\n\n\terr = fdt_resize_property_(fdt, nodeoffset, name, len, &prop);\n\tif (err == -FDT_ERR_NOTFOUND)\n\t\terr = fdt_add_property_(fdt, nodeoffset, name, len, &prop);\n\tif (err)\n\t\treturn err;\n\n\t*prop_data = prop->data;\n\treturn 0;\n}\n\nint fdt_setprop(void *fdt, int nodeoffset, const char *name,\n\t\tconst void *val, int len)\n{\n\tvoid *prop_data;\n\tint err;\n\n\terr = fdt_setprop_placeholder(fdt, nodeoffset, name, len, &prop_data);\n\tif (err)\n\t\treturn err;\n\n\tif (len)\n\t\tmemcpy(prop_data, val, len);\n\treturn 0;\n}\n\nint fdt_appendprop(void *fdt, int nodeoffset, const char *name,\n\t\t   const void *val, int len)\n{\n\tstruct fdt_property *prop;\n\tint err, oldlen, newlen;\n\n\tFDT_RW_PROBE(fdt);\n\n\tprop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);\n\tif (prop) {\n\t\tnewlen = len + oldlen;\n\t\terr = fdt_splice_struct_(fdt, prop->data,\n\t\t\t\t\t FDT_TAGALIGN(oldlen),\n\t\t\t\t\t FDT_TAGALIGN(newlen));\n\t\tif (err)\n\t\t\treturn err;\n\t\tprop->len = cpu_to_fdt32(newlen);\n\t\tmemcpy(prop->data + oldlen, val, len);\n\t} else {\n\t\terr = fdt_add_property_(fdt, nodeoffset, name, len, &prop);\n\t\tif (err)\n\t\t\treturn err;\n\t\tmemcpy(prop->data, val, len);\n\t}\n\treturn 0;\n}\n\nint fdt_delprop(void *fdt, int nodeoffset, const char *name)\n{\n\tstruct fdt_property *prop;\n\tint len, proplen;\n\n\tFDT_RW_PROBE(fdt);\n\n\tprop = fdt_get_property_w(fdt, nodeoffset, name, &len);\n\tif (!prop)\n\t\treturn len;\n\n\tproplen = sizeof(*prop) + FDT_TAGALIGN(len);\n\treturn fdt_splice_struct_(fdt, prop, proplen, 0);\n}\n\nint fdt_add_subnode_namelen(void *fdt, int parentoffset,\n\t\t\t    const char *name, int namelen)\n{\n\tstruct fdt_node_header *nh;\n\tint offset, nextoffset;\n\tint nodelen;\n\tint err;\n\tuint32_t tag;\n\tfdt32_t *endtag;\n\n\tFDT_RW_PROBE(fdt);\n\n\toffset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);\n\tif (offset >= 0)\n\t\treturn -FDT_ERR_EXISTS;\n\telse if (offset != -FDT_ERR_NOTFOUND)\n\t\treturn offset;\n\n\t/* Try to place the new node after the parent's properties */\n\tfdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */\n\tdo {\n\t\toffset = nextoffset;\n\t\ttag = fdt_next_tag(fdt, offset, &nextoffset);\n\t} while ((tag == FDT_PROP) || (tag == FDT_NOP));\n\n\tnh = fdt_offset_ptr_w_(fdt, offset);\n\tnodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE;\n\n\terr = fdt_splice_struct_(fdt, nh, 0, nodelen);\n\tif (err)\n\t\treturn err;\n\n\tnh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);\n\tmemset(nh->name, 0, FDT_TAGALIGN(namelen+1));\n\tmemcpy(nh->name, name, namelen);\n\tendtag = (fdt32_t *)((char *)nh + nodelen - FDT_TAGSIZE);\n\t*endtag = cpu_to_fdt32(FDT_END_NODE);\n\n\treturn offset;\n}\n\nint fdt_add_subnode(void *fdt, int parentoffset, const char *name)\n{\n\treturn fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name));\n}\n\nint fdt_del_node(void *fdt, int nodeoffset)\n{\n\tint endoffset;\n\n\tFDT_RW_PROBE(fdt);\n\n\tendoffset = fdt_node_end_offset_(fdt, nodeoffset);\n\tif (endoffset < 0)\n\t\treturn endoffset;\n\n\treturn fdt_splice_struct_(fdt, fdt_offset_ptr_w_(fdt, nodeoffset),\n\t\t\t\t  endoffset - nodeoffset, 0);\n}\n\nstatic void fdt_packblocks_(const char *old, char *new,\n\t\t\t    int mem_rsv_size, int struct_size)\n{\n\tint mem_rsv_off, struct_off, strings_off;\n\n\tmem_rsv_off = FDT_ALIGN(sizeof(struct fdt_header), 8);\n\tstruct_off = mem_rsv_off + mem_rsv_size;\n\tstrings_off = struct_off + struct_size;\n\n\tmemmove(new + mem_rsv_off, old + fdt_off_mem_rsvmap(old), mem_rsv_size);\n\tfdt_set_off_mem_rsvmap(new, mem_rsv_off);\n\n\tmemmove(new + struct_off, old + fdt_off_dt_struct(old), struct_size);\n\tfdt_set_off_dt_struct(new, struct_off);\n\tfdt_set_size_dt_struct(new, struct_size);\n\n\tmemmove(new + strings_off, old + fdt_off_dt_strings(old),\n\t\tfdt_size_dt_strings(old));\n\tfdt_set_off_dt_strings(new, strings_off);\n\tfdt_set_size_dt_strings(new, fdt_size_dt_strings(old));\n}\n\nint fdt_open_into(const void *fdt, void *buf, int bufsize)\n{\n\tint err;\n\tint mem_rsv_size, struct_size;\n\tint newsize;\n\tconst char *fdtstart = fdt;\n\tconst char *fdtend = fdtstart + fdt_totalsize(fdt);\n\tchar *tmp;\n\n\tFDT_RO_PROBE(fdt);\n\n\tmem_rsv_size = (fdt_num_mem_rsv(fdt)+1)\n\t\t* sizeof(struct fdt_reserve_entry);\n\n\tif (fdt_version(fdt) >= 17) {\n\t\tstruct_size = fdt_size_dt_struct(fdt);\n\t} else {\n\t\tstruct_size = 0;\n\t\twhile (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)\n\t\t\t;\n\t\tif (struct_size < 0)\n\t\t\treturn struct_size;\n\t}\n\n\tif (!fdt_blocks_misordered_(fdt, mem_rsv_size, struct_size)) {\n\t\t/* no further work necessary */\n\t\terr = fdt_move(fdt, buf, bufsize);\n\t\tif (err)\n\t\t\treturn err;\n\t\tfdt_set_version(buf, 17);\n\t\tfdt_set_size_dt_struct(buf, struct_size);\n\t\tfdt_set_totalsize(buf, bufsize);\n\t\treturn 0;\n\t}\n\n\t/* Need to reorder */\n\tnewsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size\n\t\t+ struct_size + fdt_size_dt_strings(fdt);\n\n\tif (bufsize < newsize)\n\t\treturn -FDT_ERR_NOSPACE;\n\n\t/* First attempt to build converted tree at beginning of buffer */\n\ttmp = buf;\n\t/* But if that overlaps with the old tree... */\n\tif (((tmp + newsize) > fdtstart) && (tmp < fdtend)) {\n\t\t/* Try right after the old tree instead */\n\t\ttmp = (char *)(uintptr_t)fdtend;\n\t\tif ((tmp + newsize) > ((char *)buf + bufsize))\n\t\t\treturn -FDT_ERR_NOSPACE;\n\t}\n\n\tfdt_packblocks_(fdt, tmp, mem_rsv_size, struct_size);\n\tmemmove(buf, tmp, newsize);\n\n\tfdt_set_magic(buf, FDT_MAGIC);\n\tfdt_set_totalsize(buf, bufsize);\n\tfdt_set_version(buf, 17);\n\tfdt_set_last_comp_version(buf, 16);\n\tfdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt));\n\n\treturn 0;\n}\n\nint fdt_pack(void *fdt)\n{\n\tint mem_rsv_size;\n\n\tFDT_RW_PROBE(fdt);\n\n\tmem_rsv_size = (fdt_num_mem_rsv(fdt)+1)\n\t\t* sizeof(struct fdt_reserve_entry);\n\tfdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));\n\tfdt_set_totalsize(fdt, fdt_data_size_(fdt));\n\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libs/libfdt/src/fdt_strerror.c",
    "content": "/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2006 David Gibson, IBM Corporation.\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n#include <libfdt/libfdt_env.h>\n\n#include <libfdt/fdt.h>\n#include <libfdt/libfdt.h>\n\n#include \"libfdt_internal.h\"\n\nstruct fdt_errtabent {\n\tconst char *str;\n};\n\n#define FDT_ERRTABENT(val) \\\n\t[(val)] = { .str = #val, }\n\nstatic struct fdt_errtabent fdt_errtable[] = {\n\tFDT_ERRTABENT(FDT_ERR_NOTFOUND),\n\tFDT_ERRTABENT(FDT_ERR_EXISTS),\n\tFDT_ERRTABENT(FDT_ERR_NOSPACE),\n\n\tFDT_ERRTABENT(FDT_ERR_BADOFFSET),\n\tFDT_ERRTABENT(FDT_ERR_BADPATH),\n\tFDT_ERRTABENT(FDT_ERR_BADPHANDLE),\n\tFDT_ERRTABENT(FDT_ERR_BADSTATE),\n\n\tFDT_ERRTABENT(FDT_ERR_TRUNCATED),\n\tFDT_ERRTABENT(FDT_ERR_BADMAGIC),\n\tFDT_ERRTABENT(FDT_ERR_BADVERSION),\n\tFDT_ERRTABENT(FDT_ERR_BADSTRUCTURE),\n\tFDT_ERRTABENT(FDT_ERR_BADLAYOUT),\n\tFDT_ERRTABENT(FDT_ERR_INTERNAL),\n\tFDT_ERRTABENT(FDT_ERR_BADNCELLS),\n\tFDT_ERRTABENT(FDT_ERR_BADVALUE),\n\tFDT_ERRTABENT(FDT_ERR_BADOVERLAY),\n\tFDT_ERRTABENT(FDT_ERR_NOPHANDLES),\n};\n#define FDT_ERRTABSIZE\t(sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))\n\nconst char *fdt_strerror(int errval)\n{\n\tif (errval > 0)\n\t\treturn \"<valid offset/length>\";\n\telse if (errval == 0)\n\t\treturn \"<no error>\";\n\telse if (errval > -FDT_ERRTABSIZE) {\n\t\tconst char *s = fdt_errtable[-errval].str;\n\n\t\tif (s)\n\t\t\treturn s;\n\t}\n\n\treturn \"<unknown error>\";\n}\n"
  },
  {
    "path": "user.libs/libfdt/src/fdt_sw.c",
    "content": "/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2006 David Gibson, IBM Corporation.\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n#include <libfdt/libfdt_env.h>\n\n#include <libfdt/fdt.h>\n#include <libfdt/libfdt.h>\n\n#include \"libfdt_internal.h\"\n\nstatic int fdt_sw_probe_(void *fdt)\n{\n\tif (fdt_magic(fdt) == FDT_MAGIC)\n\t\treturn -FDT_ERR_BADSTATE;\n\telse if (fdt_magic(fdt) != FDT_SW_MAGIC)\n\t\treturn -FDT_ERR_BADMAGIC;\n\treturn 0;\n}\n\n#define FDT_SW_PROBE(fdt) \\\n\t{ \\\n\t\tint err; \\\n\t\tif ((err = fdt_sw_probe_(fdt)) != 0) \\\n\t\t\treturn err; \\\n\t}\n\n/* 'memrsv' state:\tInitial state after fdt_create()\n *\n * Allowed functions:\n *\tfdt_add_reservmap_entry()\n *\tfdt_finish_reservemap()\t\t[moves to 'struct' state]\n */\nstatic int fdt_sw_probe_memrsv_(void *fdt)\n{\n\tint err = fdt_sw_probe_(fdt);\n\tif (err)\n\t\treturn err;\n\n\tif (fdt_off_dt_strings(fdt) != 0)\n\t\treturn -FDT_ERR_BADSTATE;\n\treturn 0;\n}\n\n#define FDT_SW_PROBE_MEMRSV(fdt) \\\n\t{ \\\n\t\tint err; \\\n\t\tif ((err = fdt_sw_probe_memrsv_(fdt)) != 0) \\\n\t\t\treturn err; \\\n\t}\n\n/* 'struct' state:\tEnter this state after fdt_finish_reservemap()\n *\n * Allowed functions:\n *\tfdt_begin_node()\n *\tfdt_end_node()\n *\tfdt_property*()\n *\tfdt_finish()\t\t\t[moves to 'complete' state]\n */\nstatic int fdt_sw_probe_struct_(void *fdt)\n{\n\tint err = fdt_sw_probe_(fdt);\n\tif (err)\n\t\treturn err;\n\n\tif (fdt_off_dt_strings(fdt) != fdt_totalsize(fdt))\n\t\treturn -FDT_ERR_BADSTATE;\n\treturn 0;\n}\n\n#define FDT_SW_PROBE_STRUCT(fdt) \\\n\t{ \\\n\t\tint err; \\\n\t\tif ((err = fdt_sw_probe_struct_(fdt)) != 0) \\\n\t\t\treturn err; \\\n\t}\n\n/* 'complete' state:\tEnter this state after fdt_finish()\n *\n * Allowed functions: none\n */\n\nstatic void *fdt_grab_space_(void *fdt, size_t len)\n{\n\tint offset = fdt_size_dt_struct(fdt);\n\tint spaceleft;\n\n\tspaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt)\n\t\t- fdt_size_dt_strings(fdt);\n\n\tif ((offset + len < offset) || (offset + len > spaceleft))\n\t\treturn NULL;\n\n\tfdt_set_size_dt_struct(fdt, offset + len);\n\treturn fdt_offset_ptr_w_(fdt, offset);\n}\n\nint fdt_create(void *buf, int bufsize)\n{\n\tconst size_t hdrsize = FDT_ALIGN(sizeof(struct fdt_header),\n\t\t\t\t\t sizeof(struct fdt_reserve_entry));\n\tvoid *fdt = buf;\n\n\tif (bufsize < hdrsize)\n\t\treturn -FDT_ERR_NOSPACE;\n\n\tmemset(buf, 0, bufsize);\n\n\tfdt_set_magic(fdt, FDT_SW_MAGIC);\n\tfdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION);\n\tfdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION);\n\tfdt_set_totalsize(fdt,  bufsize);\n\n\tfdt_set_off_mem_rsvmap(fdt, hdrsize);\n\tfdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt));\n\tfdt_set_off_dt_strings(fdt, 0);\n\n\treturn 0;\n}\n\nint fdt_resize(void *fdt, void *buf, int bufsize)\n{\n\tsize_t headsize, tailsize;\n\tchar *oldtail, *newtail;\n\n\tFDT_SW_PROBE(fdt);\n\n\theadsize = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);\n\ttailsize = fdt_size_dt_strings(fdt);\n\n\tif ((headsize + tailsize) > fdt_totalsize(fdt))\n\t\treturn -FDT_ERR_INTERNAL;\n\n\tif ((headsize + tailsize) > bufsize)\n\t\treturn -FDT_ERR_NOSPACE;\n\n\toldtail = (char *)fdt + fdt_totalsize(fdt) - tailsize;\n\tnewtail = (char *)buf + bufsize - tailsize;\n\n\t/* Two cases to avoid clobbering data if the old and new\n\t * buffers partially overlap */\n\tif (buf <= fdt) {\n\t\tmemmove(buf, fdt, headsize);\n\t\tmemmove(newtail, oldtail, tailsize);\n\t} else {\n\t\tmemmove(newtail, oldtail, tailsize);\n\t\tmemmove(buf, fdt, headsize);\n\t}\n\n\tfdt_set_totalsize(buf, bufsize);\n\tif (fdt_off_dt_strings(buf))\n\t\tfdt_set_off_dt_strings(buf, bufsize);\n\n\treturn 0;\n}\n\nint fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)\n{\n\tstruct fdt_reserve_entry *re;\n\tint offset;\n\n\tFDT_SW_PROBE_MEMRSV(fdt);\n\n\toffset = fdt_off_dt_struct(fdt);\n\tif ((offset + sizeof(*re)) > fdt_totalsize(fdt))\n\t\treturn -FDT_ERR_NOSPACE;\n\n\tre = (struct fdt_reserve_entry *)((char *)fdt + offset);\n\tre->address = cpu_to_fdt64(addr);\n\tre->size = cpu_to_fdt64(size);\n\n\tfdt_set_off_dt_struct(fdt, offset + sizeof(*re));\n\n\treturn 0;\n}\n\nint fdt_finish_reservemap(void *fdt)\n{\n\tint err = fdt_add_reservemap_entry(fdt, 0, 0);\n\n\tif (err)\n\t\treturn err;\n\n\tfdt_set_off_dt_strings(fdt, fdt_totalsize(fdt));\n\treturn 0;\n}\n\nint fdt_begin_node(void *fdt, const char *name)\n{\n\tstruct fdt_node_header *nh;\n\tint namelen;\n\n\tFDT_SW_PROBE_STRUCT(fdt);\n\n\tnamelen = strlen(name) + 1;\n\tnh = fdt_grab_space_(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen));\n\tif (! nh)\n\t\treturn -FDT_ERR_NOSPACE;\n\n\tnh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);\n\tmemcpy(nh->name, name, namelen);\n\treturn 0;\n}\n\nint fdt_end_node(void *fdt)\n{\n\tfdt32_t *en;\n\n\tFDT_SW_PROBE_STRUCT(fdt);\n\n\ten = fdt_grab_space_(fdt, FDT_TAGSIZE);\n\tif (! en)\n\t\treturn -FDT_ERR_NOSPACE;\n\n\t*en = cpu_to_fdt32(FDT_END_NODE);\n\treturn 0;\n}\n\nstatic int fdt_find_add_string_(void *fdt, const char *s)\n{\n\tchar *strtab = (char *)fdt + fdt_totalsize(fdt);\n\tconst char *p;\n\tint strtabsize = fdt_size_dt_strings(fdt);\n\tint len = strlen(s) + 1;\n\tint struct_top, offset;\n\n\tp = fdt_find_string_(strtab - strtabsize, strtabsize, s);\n\tif (p)\n\t\treturn p - strtab;\n\n\t/* Add it */\n\toffset = -strtabsize - len;\n\tstruct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);\n\tif (fdt_totalsize(fdt) + offset < struct_top)\n\t\treturn 0; /* no more room :( */\n\n\tmemcpy(strtab + offset, s, len);\n\tfdt_set_size_dt_strings(fdt, strtabsize + len);\n\treturn offset;\n}\n\nint fdt_property_placeholder(void *fdt, const char *name, int len, void **valp)\n{\n\tstruct fdt_property *prop;\n\tint nameoff;\n\n\tFDT_SW_PROBE_STRUCT(fdt);\n\n\tnameoff = fdt_find_add_string_(fdt, name);\n\tif (nameoff == 0)\n\t\treturn -FDT_ERR_NOSPACE;\n\n\tprop = fdt_grab_space_(fdt, sizeof(*prop) + FDT_TAGALIGN(len));\n\tif (! prop)\n\t\treturn -FDT_ERR_NOSPACE;\n\n\tprop->tag = cpu_to_fdt32(FDT_PROP);\n\tprop->nameoff = cpu_to_fdt32(nameoff);\n\tprop->len = cpu_to_fdt32(len);\n\t*valp = prop->data;\n\treturn 0;\n}\n\nint fdt_property(void *fdt, const char *name, const void *val, int len)\n{\n\tvoid *ptr;\n\tint ret;\n\n\tret = fdt_property_placeholder(fdt, name, len, &ptr);\n\tif (ret)\n\t\treturn ret;\n\tmemcpy(ptr, val, len);\n\treturn 0;\n}\n\nint fdt_finish(void *fdt)\n{\n\tchar *p = (char *)fdt;\n\tfdt32_t *end;\n\tint oldstroffset, newstroffset;\n\tuint32_t tag;\n\tint offset, nextoffset;\n\n\tFDT_SW_PROBE_STRUCT(fdt);\n\n\t/* Add terminator */\n\tend = fdt_grab_space_(fdt, sizeof(*end));\n\tif (! end)\n\t\treturn -FDT_ERR_NOSPACE;\n\t*end = cpu_to_fdt32(FDT_END);\n\n\t/* Relocate the string table */\n\toldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt);\n\tnewstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);\n\tmemmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt));\n\tfdt_set_off_dt_strings(fdt, newstroffset);\n\n\t/* Walk the structure, correcting string offsets */\n\toffset = 0;\n\twhile ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {\n\t\tif (tag == FDT_PROP) {\n\t\t\tstruct fdt_property *prop =\n\t\t\t\tfdt_offset_ptr_w_(fdt, offset);\n\t\t\tint nameoff;\n\n\t\t\tnameoff = fdt32_to_cpu(prop->nameoff);\n\t\t\tnameoff += fdt_size_dt_strings(fdt);\n\t\t\tprop->nameoff = cpu_to_fdt32(nameoff);\n\t\t}\n\t\toffset = nextoffset;\n\t}\n\tif (nextoffset < 0)\n\t\treturn nextoffset;\n\n\t/* Finally, adjust the header */\n\tfdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt));\n\tfdt_set_magic(fdt, FDT_MAGIC);\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libs/libfdt/src/fdt_wip.c",
    "content": "/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2006 David Gibson, IBM Corporation.\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include <libfdt/libfdt_env.h>\n\n#include <libfdt/fdt.h>\n#include <libfdt/libfdt.h>\n\n#include \"libfdt_internal.h\"\n\nint fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset,\n\t\t\t\t\tconst char *name, int namelen,\n\t\t\t\t\tuint32_t idx, const void *val,\n\t\t\t\t\tint len)\n{\n\tvoid *propval;\n\tint proplen;\n\n\tpropval = fdt_getprop_namelen_w(fdt, nodeoffset, name, namelen,\n\t\t\t\t\t&proplen);\n\tif (!propval)\n\t\treturn proplen;\n\n\tif (proplen < (len + idx))\n\t\treturn -FDT_ERR_NOSPACE;\n\n\tmemcpy((char *)propval + idx, val, len);\n\treturn 0;\n}\n\nint fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,\n\t\t\tconst void *val, int len)\n{\n\tconst void *propval;\n\tint proplen;\n\n\tpropval = fdt_getprop(fdt, nodeoffset, name, &proplen);\n\tif (!propval)\n\t\treturn proplen;\n\n\tif (proplen != len)\n\t\treturn -FDT_ERR_NOSPACE;\n\n\treturn fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name,\n\t\t\t\t\t\t   strlen(name), 0,\n\t\t\t\t\t\t   val, len);\n}\n\nstatic void fdt_nop_region_(void *start, int len)\n{\n\tfdt32_t *p;\n\n\tfor (p = start; (char *)p < ((char *)start + len); p++)\n\t\t*p = cpu_to_fdt32(FDT_NOP);\n}\n\nint fdt_nop_property(void *fdt, int nodeoffset, const char *name)\n{\n\tstruct fdt_property *prop;\n\tint len;\n\n\tprop = fdt_get_property_w(fdt, nodeoffset, name, &len);\n\tif (!prop)\n\t\treturn len;\n\n\tfdt_nop_region_(prop, len + sizeof(*prop));\n\n\treturn 0;\n}\n\nint fdt_node_end_offset_(void *fdt, int offset)\n{\n\tint depth = 0;\n\n\twhile ((offset >= 0) && (depth >= 0))\n\t\toffset = fdt_next_node(fdt, offset, &depth);\n\n\treturn offset;\n}\n\nint fdt_nop_node(void *fdt, int nodeoffset)\n{\n\tint endoffset;\n\n\tendoffset = fdt_node_end_offset_(fdt, nodeoffset);\n\tif (endoffset < 0)\n\t\treturn endoffset;\n\n\tfdt_nop_region_(fdt_offset_ptr_w(fdt, nodeoffset, 0),\n\t\t\tendoffset - nodeoffset);\n\treturn 0;\n}\n"
  },
  {
    "path": "user.libs/libfdt/src/libfdt_internal.h",
    "content": "#ifndef LIBFDT_INTERNAL_H\n#define LIBFDT_INTERNAL_H\n/*\n * libfdt - Flat Device Tree manipulation\n * Copyright (C) 2006 David Gibson, IBM Corporation.\n *\n * libfdt is dual licensed: you can use it either under the terms of\n * the GPL, or the BSD license, at your option.\n *\n *  a) This library is free software; you can redistribute it and/or\n *     modify it under the terms of the GNU General Public License as\n *     published by the Free Software Foundation; either version 2 of the\n *     License, or (at your option) any later version.\n *\n *     This library is distributed in the hope that it will be useful,\n *     but WITHOUT ANY WARRANTY; without even the implied warranty of\n *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *     GNU General Public License for more details.\n *\n *     You should have received a copy of the GNU General Public\n *     License along with this library; if not, write to the Free\n *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\n *     MA 02110-1301 USA\n *\n * Alternatively,\n *\n *  b) Redistribution and use in source and binary forms, with or\n *     without modification, are permitted provided that the following\n *     conditions are met:\n *\n *     1. Redistributions of source code must retain the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer.\n *     2. Redistributions in binary form must reproduce the above\n *        copyright notice, this list of conditions and the following\n *        disclaimer in the documentation and/or other materials\n *        provided with the distribution.\n *\n *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n *     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n#include <libfdt/fdt.h>\n\n#define FDT_ALIGN(x, a)\t\t(((x) + (a) - 1) & ~((a) - 1))\n#define FDT_TAGALIGN(x)\t\t(FDT_ALIGN((x), FDT_TAGSIZE))\n\nint fdt_ro_probe_(const void *fdt);\n#define FDT_RO_PROBE(fdt)\t\t\t\\\n\t{ \\\n\t\tint err_; \\\n\t\tif ((err_ = fdt_ro_probe_(fdt)) != 0)\t\\\n\t\t\treturn err_; \\\n\t}\n\nint fdt_check_node_offset_(const void *fdt, int offset);\nint fdt_check_prop_offset_(const void *fdt, int offset);\nconst char *fdt_find_string_(const char *strtab, int tabsize, const char *s);\nint fdt_node_end_offset_(void *fdt, int nodeoffset);\n\nstatic inline const void *fdt_offset_ptr_(const void *fdt, int offset)\n{\n\treturn (const char *)fdt + fdt_off_dt_struct(fdt) + offset;\n}\n\nstatic inline void *fdt_offset_ptr_w_(void *fdt, int offset)\n{\n\treturn (void *)(uintptr_t)fdt_offset_ptr_(fdt, offset);\n}\n\nstatic inline const struct fdt_reserve_entry *fdt_mem_rsv_(const void *fdt, int n)\n{\n\tconst struct fdt_reserve_entry *rsv_table =\n\t\t(const struct fdt_reserve_entry *)\n\t\t((const char *)fdt + fdt_off_mem_rsvmap(fdt));\n\n\treturn rsv_table + n;\n}\nstatic inline struct fdt_reserve_entry *fdt_mem_rsv_w_(void *fdt, int n)\n{\n\treturn (void *)(uintptr_t)fdt_mem_rsv_(fdt, n);\n}\n\n#define FDT_SW_MAGIC\t\t(~FDT_MAGIC)\n\n#endif /* LIBFDT_INTERNAL_H */\n"
  },
  {
    "path": "user.libs/liblwext4/Makefile",
    "content": "TARGET\t\t= liblwext4.a\nLIB_CFLAGS\t= -I./include/lwext4 -DCONFIG_USE_DEFAULT_CFG -DCONFIG_USE_USER_MALLOC\n\nSRC_C\t= $(wildcard src/*.c)\nSRC_C\t+= ext4_server.c ext4_mem.c\n\nINSTALL_HEADERS := include/lwext4/ext4_blkdev.h\n\ninclude $(projtree)/scripts/lib_build.mk\n"
  },
  {
    "path": "user.libs/liblwext4/ext4_mem.c",
    "content": "/*\n * Copyright (c) 2021 Min Le (lemin9538@163.com)\n */\n\n#include <stdio.h>\n#include <unistd.h>\n#include <inttypes.h>\n#include <stdlib.h>\n#include <string.h>\n#include <errno.h>\n\n#include <minos/debug.h>\n#include <minos/types.h>\n\nvoid *ext4_user_malloc(size_t size)\n{\n\tvoid *mem;\n\n\tmem = malloc(size);\n\tif (mem)\n\t\tmemset(mem, 0, size);\n\n\treturn mem;\n}\n\nvoid *ext4_user_calloc(size_t numb, size_t size)\n{\n\treturn ext4_user_malloc(numb * size);\n}\n\nvoid ext4_user_free(void *mem)\n{\n\tfree(mem);\n}\n\nvoid *ext4_realloc(void *ptr, size_t size)\n{\n\tpr_err(\"ext4_realloc do not implement\\n\");\n\n\treturn NULL;\n}\n\nvoid *ext4_user_alloc_bcache(size_t size)\n{\n\tvoid *mem;\n\n\tmem = memalign(PAGE_SIZE, PAGE_BALIGN(size));\n\tif (mem)\n\t\tmemset(mem, 0, sizeof(unsigned long));\n\n\treturn mem;\n}\n"
  },
  {
    "path": "user.libs/liblwext4/ext4_server.c",
    "content": "/*\n * Copyright (c) 2021 Min Le (lemin9538@163.com)\n */\n\n#include <stdio.h>\n#include <unistd.h>\n#include <inttypes.h>\n#include <stdlib.h>\n#include <string.h>\n#include <errno.h>\n#include <dirent.h>\n#include <sys/mman.h>\n#include <sys/epoll.h>\n\n#include <minos/kobject.h>\n#include <minos/debug.h>\n#include <minos/proto.h>\n#include <minos/service.h>\n#include <minos/types.h>\n\n#include <ext4.h>\n#include <ext4_mbr.h>\n\n#define EXT4_MAX_PARTITION 4\n#define VFS_MAX_EVENTS 16\n\nstruct lwext4_file {\n\tint handle;\n\tuint8_t root;\n\tuint8_t dir;\n\tchar *sbuf;\n\tsize_t sbuf_size;\n\tchar *buf[0];\n};\n\n/*\n * only support one partition now.\n */\nstruct ext4_server {\n\tint epfd;\n\tstruct lwext4_file root_file;\n\tchar buf[PAGE_SIZE];\n\tstruct ext4_blockdev bdev;\n};\n\n#define LWEXT4_FILE(lwf) (struct ext4_file *)((lwf)->buf)\n#define LWEXT4_DIR(lwf) (struct ext4_dir *)((lwf)->buf)\n\nstatic int ext4_server_listen(struct ext4_server *vs, struct lwext4_file *file)\n{\n\tstruct epoll_event event;\n\tint ret;\n\n\tevent.events = EPOLLIN | EPOLLWCLOSE;\n\tevent.data.ptr = file;\n\tret = epoll_ctl(vs->epfd, EPOLL_CTL_ADD, file->handle, &event);\n\tif (ret)\n\t\tpr_err(\"add file to vfs server failed\\n\");\n\n\treturn 0;\n}\n\nstatic int ext4_server_unlisten(struct ext4_server *vs, struct lwext4_file *file)\n{\n\tstruct epoll_event event;\n\tint ret;\n\n\tevent.events = EPOLLIN | EPOLLWCLOSE;\n\tret = epoll_ctl(vs->epfd, EPOLL_CTL_DEL, file->handle, &event);\n\tif (ret)\n\t\tpr_err(\"unlisten ext4 file failed\\n\");\n\n\treturn ret;\n}\n\nstatic struct lwext4_file *create_new_lwext4_file(int dir)\n{\n\tstruct lwext4_file *file;\n\tint handle;\n\tvoid *addr;\n\tint size;\n\n\thandle = kobject_create_endpoint(PAGE_SIZE);\n\tif (handle <= 0)\n\t\treturn NULL;\n\n\tif (kobject_mmap(handle, &addr, NULL)) {\n\t\tkobject_close(handle);\n\t\treturn NULL;\n\t}\n\n\tsize = sizeof(struct lwext4_file);\n\tif (dir)\n\t\tsize += sizeof(struct ext4_dir);\n\telse\n\t\tsize += sizeof(struct ext4_file);\n\n\tfile = zalloc(size);\n\tif (!file)\n\t\treturn NULL;\n\n\tfile->handle = handle;\n\tfile->sbuf = addr;\n\tfile->sbuf_size = PAGE_SIZE;\n\tfile->dir = !!dir;\n\n\treturn file;\n}\n\nstatic void release_file(struct lwext4_file *file)\n{\n\tif (!file)\n\t\treturn;\n\n\tkobject_munmap(file->handle);\n\tkobject_close(file->handle);\n\tfree(file);\n}\n\nstatic int __handle_vfs_open_request(struct ext4_server *vs, struct lwext4_file *file,\n\t\tstruct proto *proto, struct lwext4_file **new)\n{\n\tint dir = !!(proto->open.flags & O_DIRECTORY);\n\tstruct lwext4_file *new_file;\n\tint ret;\n\n\tif (!file->dir)\n\t\treturn -ENOTDIR;\n\n\tnew_file = create_new_lwext4_file(dir);\n\tif (!new_file)\n\t\treturn -ENOMEM;\n\n\t/*\n\t * open the root directory\n\t */\n\tif (vs->buf[0] == 0)\n\t\tstrcpy(vs->buf, \"/\");\n\n\tif (dir)\n\t\tret = ext4_dir_open(LWEXT4_DIR(new_file), vs->buf);\n\telse\n\t\tret = ext4_fopen(LWEXT4_FILE(new_file), vs->buf, \"r\");\n\tif (ret) {\n\t\tpr_err(\"open %s failed\\n\", vs->buf);\n\t\trelease_file(new_file);\n\t\treturn -ENOENT;\n\t}\n\n\tret = ext4_server_listen(vs, new_file);\n\tif (ret) {\n\t\tpr_err(\"add new file failed %s\\n\", __func__);\n\t\trelease_file(new_file);\n\t\treturn ret;\n\t}\n\n\t*new = new_file;\n\n\treturn 0;\n}\n\nstatic int handle_vfs_open_request(struct ext4_server *vs,\n\t\t\tstruct lwext4_file *parent, struct proto *proto)\n{\n\tstruct lwext4_file *file;\n\tint ret;\n\n\tret = __handle_vfs_open_request(vs, parent, proto, &file);\n\tif (ret) {\n\t\tkobject_reply_errcode(parent->handle, proto->token, ret);\n\t\treturn ret;\n\t}\n\n\tkobject_reply_handle(parent->handle, proto->token,\n\t\t\tfile->handle, KR_WM | KR_C);\n\n\treturn 0;\n}\n\nstatic int handle_vfs_write_request(struct ext4_server *vs,\n\t\tstruct lwext4_file *file, struct proto *proto)\n{\n\treturn 0;\n}\n\nstatic int handle_vfs_read_request(struct ext4_server *vs,\n\t\tstruct lwext4_file *file, struct proto *proto)\n{\n\tsize_t ret_size;\n\tint ret;\n\n\tif (proto->read.len > PAGE_SIZE) {\n\t\tret_size = -E2BIG;\n\t\tgoto out;\n\t}\n\n\tret = ext4_fread(LWEXT4_FILE(file), file->sbuf,\n\t\t\tproto->read.len, &ret_size);\n\tif (ret)\n\t\tpr_err(\"read file failed\\n\");\nout:\n\tkobject_reply_errcode(file->handle, proto->token, ret_size);\n\treturn 0;\n}\n\nstatic int handle_vfs_lseek_request(struct ext4_server *vs,\n\t\tstruct lwext4_file *file, struct proto *proto)\n{\n\tint ret;\n\n\tif (file->dir)\n\t\tret = ext4_dir_seek(LWEXT4_DIR(file), proto->lseek.off, proto->lseek.whence);\n\telse\n\t\tret = ext4_fseek(LWEXT4_FILE(file), proto->lseek.off, proto->lseek.whence);\n\n\tkobject_reply_errcode(file->handle, proto->token, ret);\n\n\treturn 0;\n}\n\nstatic char dt_types[EXT4_DE_MAX] = {\n\tDT_UNKNOWN,\n\tDT_REG,\n\tDT_DIR,\n\tDT_CHR,\n\tDT_BLK,\n\tDT_FIFO,\n\tDT_SOCK,\n\tDT_LNK\n};\n\nstatic inline unsigned char ext4_file_type(int dtype)\n{\n\tif (dtype >= EXT4_DE_MAX)\n\t\treturn DT_UNKNOWN;\n\telse\n\t\treturn dt_types[dtype];\n}\n\nstatic int handle_vfs_getdent_request(struct ext4_server *vs,\n\t\tstruct lwext4_file *file, struct proto *proto)\n{\n\tconst ext4_direntry *d;\n\tstruct dirent *de;\n\tchar *tmp = file->sbuf;\n\tint idx = 0, len;\n\tint size_left = PAGE_SIZE;\n\n\tif (!file->dir) {\n\t\tpr_err(\"file is not a directory\\n\");\n\t\tkobject_reply_errcode(file->handle, proto->token, -ENOTDIR);\n\t\treturn -ENOTDIR;\n\t}\n\n\twhile ((d = ext4_dir_entry_next(LWEXT4_DIR(file))) != NULL) {\n\t\tidx++;\n\t\tlen = DIRENT_SIZE(d->name_length + 1);\n\t\tif (size_left < len)\n\t\t\tbreak;\n\n\t\tde = (struct dirent *)tmp;\n\t\tde->d_ino = d->inode;\n\t\tde->d_off = d->inode;\n\t\tde->d_reclen = len;\n\t\tde->d_type = ext4_file_type(d->inode_type);\n\t\tmemcpy(de->d_name, d->name, d->name_length);\n\t\tde->d_name[d->name_length] = 0;\n\n\t\ttmp += len;\n\t\tsize_left -= len;\n\t}\n\n\tkobject_reply_errcode(file->handle, proto->token, PAGE_SIZE - size_left);\n\n\treturn 0;\n}\n\nstatic int handle_vfs_close_request(struct ext4_server *vs, struct lwext4_file *file)\n{\n\text4_server_unlisten(vs, file);\n\tif (file->dir)\n\t\text4_dir_close(LWEXT4_DIR(file));\n\telse\n\t\text4_fclose(LWEXT4_FILE(file));\n\n\trelease_file(file);\n\n\treturn 0;\n}\n\nstatic int handle_vfs_access_request(struct ext4_server *vs,\n\t\tstruct lwext4_file *file, struct proto *proto)\n{\n\treturn 0;\n}\n\nstatic int handle_vfs_in_request(struct ext4_server *vs, struct lwext4_file *file)\n{\n\tstruct proto proto;\n\tint ret;\n\n\tret = sys_read_proto_with_string(file->handle, &proto, vs->buf, PAGE_SIZE, 0);\n\tif (ret)\n\t\treturn ret;\n\n\tswitch (proto.proto_id) {\n\tcase PROTO_OPEN:\n\t\tret = handle_vfs_open_request(vs, file, &proto);\n\t\tbreak;\n\tcase PROTO_READ:\n\t\tret = handle_vfs_read_request(vs, file, &proto);\n\t\tbreak;\n\tcase PROTO_WRITE:\n\t\tret = handle_vfs_write_request(vs, file, &proto);\n\t\tbreak;\n\tcase PROTO_GETDENTS:\n\t\tret = handle_vfs_getdent_request(vs, file, &proto);\n\t\tbreak;\n\tcase PROTO_LSEEK:\n\t\tret = handle_vfs_lseek_request(vs, file, &proto);\n\t\tbreak;\n\tcase PROTO_ACCESS:\n\t\tret = handle_vfs_access_request(vs, file, &proto);\n\t\tkobject_reply_errcode(file->handle, proto.token, ret);\n\t\tbreak;\n\tdefault:\n\t\tret = -ENOSYS;\n\t\tpr_err(\"unsupport vfs proto %d\\n\", proto.proto_id);\n\t\tkobject_reply_errcode(file->handle, proto.token, ret);\n\t\tbreak;\n\t}\n\n#if 0\n\tif (ret)\n\t\tdump_proto(&proto);\n#endif\n\n\treturn ret;\n}\n\nstatic int handle_vfs_server_event(struct ext4_server *vs, struct epoll_event *event)\n{\n\tstruct lwext4_file *file = event->data.ptr;\n\n\tif (!file)\n\t\treturn -ENOENT;\n\n\tif ((event->events != EPOLLIN) && (event->events != EPOLLWCLOSE))\n\t\treturn -EPROTO;\n\n\tif (event->events == EPOLLWCLOSE)\n\t\treturn handle_vfs_close_request(vs, file);\n\telse\n\t\treturn handle_vfs_in_request(vs, file);\n}\n\nstatic int run_ext4_server(struct ext4_server *vs)\n{\n\tstruct epoll_event events[VFS_MAX_EVENTS];\n\tstruct lwext4_file *efile = &vs->root_file;\n\tint epfd, rfd;\n\tint cnt, i;\n\n\t/*\n\t * only support one partition now.\n\t */\n\trfd = register_service(\"/\", \"c\", SRV_PORT, 0);\n\tif (rfd <= 0) {\n\t\tpr_err(\"create service for virtio-block ext4 server failed\\n\");\n\t\treturn -ENOMEM;\n\t}\n\n\tepfd = epoll_create(0);\n\tif (epfd <= 0) {\n\t\tpr_err(\"create epoll handle for vfs server failed\\n\");\n\t\tunregister_service(rfd);\n\t\treturn epfd;\n\t}\n\n\tvs->epfd = epfd;\n\tpr_info(\"ext4 server epfd:%d root_fd:%d\\n\", epfd, rfd);\n\n\t/*\n\t * listen on the root file.\n\t */\n\tmemset(efile, 0, sizeof(struct lwext4_file));\n\tefile->handle = rfd;\n\tefile->root = 1;\n\tefile->dir = 1;\n\text4_server_listen(vs, efile);\n\n\ti_am_ok();\n\tpr_info(\"ext4 server start, waitting for request...\\n\");\n\n\tfor (; ;) {\n\t\tcnt = epoll_wait(vs->epfd, events, VFS_MAX_EVENTS, -1);\n\t\tif (cnt <= 0)\n\t\t\tcontinue;\n\n\t\tfor (i = 0; i < cnt; i++)\n\t\t\thandle_vfs_server_event(vs, &events[i]);\n\t}\n\n\treturn -1;\n}\n\nint run_ext4_file_server(struct ext4_blockdev *bdev)\n{\n\tstruct ext4_mbr_bdevs bdevs;\n\tint r, i, cnt = 0;\n\tstruct ext4_blockdev *ext4_blkdev = NULL;\n\tstruct ext4_server *vs;\n\n\tvs = malloc(sizeof(struct ext4_server));\n\tif (!vs)\n\t\treturn -ENOMEM;\n\n\text4_dmask_set(DEBUG_ALL);\n\n\tr = ext4_mbr_scan(bdev, &bdevs);\n\tif (r) {\n\t\tpr_err(\"ext4 mbr scan failed\\n\");\n\t\treturn -ENODEV;\n\t}\n\n\tpr_info(\"ext4_mbr_scan:\\n\");\n\n\tfor (i = 0; i < 4; i++) {\n\t\tpr_info(\"mbr_entry %d:\\n\", i);\n\t\tif (!bdevs.partitions[i].bdif) {\n\t\t\tpr_info(\"\\tempty/unknown\\n\");\n\t\t\tcontinue;\n\t\t}\n\t\t\n\t\tpr_info(\"\\toffeset: 0x%\"PRIx64\", %\"PRIu64\"MB\\n\",\n\t\t\t\tbdevs.partitions[i].part_offset,\n\t\t\t\tbdevs.partitions[i].part_offset / (1024 * 1024));\n\t\tpr_info(\"\\tsize:    0x%\"PRIx64\", %\"PRIu64\"MB\\n\",\n\t\t\t\tbdevs.partitions[i].part_size,\n\t\t\t\tbdevs.partitions[i].part_size / (1024 * 1024));\n\n\t\tif (ext4_blkdev == NULL)\n\t\t\text4_blkdev = &bdevs.partitions[i];\n\t\telse if (bdevs.partitions[i].part_size > ext4_blkdev->part_size)\n\t\t\text4_blkdev = &bdevs.partitions[i];\n\t\tcnt++;\n\t}\n\n\tif (cnt == 0 || ext4_blkdev == NULL) {\n\t\tpr_err(\"no ext4 partition found\\n\");\n\t\treturn -ENODEV;\n\t}\n\n\tif (cnt > 1)\n\t\tpr_warn(\"only one partition will support\\n\");\n\n\tmemcpy(&vs->bdev, ext4_blkdev, sizeof(struct ext4_blockdev));\n\tr = ext4_device_register(&vs->bdev, \"vd0\");\n\tif (r) {\n\t\tpr_err(\"register ext4 partition fail\\n\");\n\t\texit(r);\n\t}\n\n\tr = ext4_mount(\"vd0\", \"/\", 0);\n\tif (r) {\n\t\tpr_err(\"mount ext4 partition fail\\n\");\n\t\texit(r);\n\t}\n\n\treturn run_ext4_server(vs);\n}\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4.h",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4.h\n * @brief Ext4 high level operations (files, directories, mount points...).\n *        Client has to include only this file.\n */\n\n#ifndef EXT4_H_\n#define EXT4_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n#include <stddef.h>\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_errno.h>\n#include <ext4_oflags.h>\n#include <ext4_debug.h>\n\n#include <ext4_blockdev.h>\n\n/********************************OS LOCK INFERFACE***************************/\n\n/**@brief   OS dependent lock interface.*/\nstruct ext4_lock {\n\n    /**@brief   Lock access to mount point.*/\n    void (*lock)(void);\n\n    /**@brief   Unlock access to mount point.*/\n    void (*unlock)(void);\n};\n\n/********************************FILE DESCRIPTOR*****************************/\n\n/**@brief   File descriptor. */\ntypedef struct ext4_file {\n\n    /**@brief   Mount point handle.*/\n    struct ext4_mountpoint *mp;\n\n    /**@brief   File inode id.*/\n    uint32_t inode;\n\n    /**@brief   Open flags.*/\n    uint32_t flags;\n\n    /**@brief   File size.*/\n    uint64_t fsize;\n\n    /**@brief   Actual file position.*/\n    uint64_t fpos;\n} ext4_file;\n\n/*****************************DIRECTORY DESCRIPTOR***************************/\n\n/**@brief   Directory entry descriptor. */\ntypedef struct ext4_direntry {\n    uint32_t inode;\n    uint16_t entry_length;\n    uint8_t name_length;\n    uint8_t inode_type;\n    uint8_t name[255];\n} ext4_direntry;\n\n/**@brief   Directory descriptor. */\ntypedef struct ext4_dir {\n    /**@brief   File descriptor.*/\n    ext4_file f;\n    /**@brief   Current directory entry.*/\n    ext4_direntry de;\n    /**@brief   Next entry offset.*/\n    uint64_t next_off;\n} ext4_dir;\n\n/********************************MOUNT OPERATIONS****************************/\n\n/**@brief   Register block device.\n *\n * @param   bd Block device.\n * @param   dev_name Block device name.\n *\n * @return  Standard error code.*/\nint ext4_device_register(struct ext4_blockdev *bd,\n             const char *dev_name);\n\n/**@brief   Un-register block device.\n *\n * @param   dev_name Block device name.\n *\n * @return  Standard error code.*/\nint ext4_device_unregister(const char *dev_name);\n\n/**@brief   Un-register all block devices.\n *\n * @return  Standard error code.*/\nint ext4_device_unregister_all(void);\n\n/**@brief   Mount a block device with EXT4 partition to the mount point.\n *\n * @param   dev_name Block device name (@ref ext4_device_register).\n * @param   mount_point Mount point, for example:\n *          -   /\n *          -   /my_partition/\n *          -   /my_second_partition/\n * @param   read_only mount as read-only mode.\n *\n * @return Standard error code */\nint ext4_mount(const char *dev_name,\n           const char *mount_point,\n           bool read_only);\n\n/**@brief   Umount operation.\n *\n * @param   mount_pount Mount point.\n *\n * @return  Standard error code */\nint ext4_umount(const char *mount_point);\n\n/**@brief   Starts journaling. Journaling start/stop functions are transparent\n *          and might be used on filesystems without journaling support.\n * @warning Usage:\n *              ext4_mount(\"sda1\", \"/\");\n *              ext4_journal_start(\"/\");\n *\n *              //File operations here...\n *\n *              ext4_journal_stop(\"/\");\n *              ext4_umount(\"/\");\n * @param   mount_pount Mount point.\n *\n * @return  Standard error code. */\nint ext4_journal_start(const char *mount_point);\n\n/**@brief   Stops journaling. Journaling start/stop functions are transparent\n *          and might be used on filesystems without journaling support.\n *\n * @param   mount_pount Mount point name.\n *\n * @return  Standard error code. */\nint ext4_journal_stop(const char *mount_point);\n\n/**@brief   Journal recovery.\n * @warning Must be called after @ref ext4_mount.\n *\n * @param   mount_pount Mount point.\n *\n * @return Standard error code. */\nint ext4_recover(const char *mount_point);\n\n/**@brief   Some of the filesystem stats. */\nstruct ext4_mount_stats {\n    uint32_t inodes_count;\n    uint32_t free_inodes_count;\n    uint64_t blocks_count;\n    uint64_t free_blocks_count;\n\n    uint32_t block_size;\n    uint32_t block_group_count;\n    uint32_t blocks_per_group;\n    uint32_t inodes_per_group;\n\n    char volume_name[16];\n};\n\n/**@brief   Get file mount point stats.\n *\n * @param   mount_pount Mount point.\n * @param   stats Filesystem stats.\n *\n * @return Standard error code. */\nint ext4_mount_point_stats(const char *mount_point,\n               struct ext4_mount_stats *stats);\n\n/**@brief   Setup OS lock routines.\n *\n * @param   mount_pount Mount point.\n * @param   locks  Lock and unlock functions\n *\n * @return Standard error code. */\nint ext4_mount_setup_locks(const char *mount_point,\n               const struct ext4_lock *locks);\n\n/**@brief   Acquire the filesystem superblock pointer of a mp.\n *\n * @param   mount_pount Mount point.\n * @param   sb Superblock handle\n *\n * @return Standard error code. */\nint ext4_get_sblock(const char *mount_point, struct ext4_sblock **sb);\n\n/**@brief   Enable/disable write back cache mode.\n * @warning Default model of cache is write trough. It means that when You do:\n *\n *          ext4_fopen(...);\n *          ext4_fwrite(...);\n *                           < --- data is flushed to physical drive\n *\n *          When you do:\n *          ext4_cache_write_back(..., 1);\n *          ext4_fopen(...);\n *          ext4_fwrite(...);\n *                           < --- data is NOT flushed to physical drive\n *          ext4_cache_write_back(..., 0);\n *                           < --- when write back mode is disabled all\n *                                 cache data will be flushed\n * To enable write back mode permanently just call this function\n * once after ext4_mount (and disable before ext4_umount).\n *\n * Some of the function use write back cache mode internally.\n * If you enable write back mode twice you have to disable it twice\n * to flush all data:\n *\n *      ext4_cache_write_back(..., 1);\n *      ext4_cache_write_back(..., 1);\n *\n *      ext4_cache_write_back(..., 0);\n *      ext4_cache_write_back(..., 0);\n *\n * Write back mode is useful when you want to create a lot of empty\n * files/directories.\n *\n * @param   mount_pount Mount point.\n * @param   on Enable/disable cache writeback mode.\n *\n * @return Standard error code. */\nint ext4_cache_write_back(const char *path, bool on);\n\n\n/**@brief   Force cache flush.\n *\n * @param   mount_pount Mount point.\n *\n * @return  Standard error code. */\nint ext4_cache_flush(const char *path);\n\n/********************************FILE OPERATIONS*****************************/\n\n/**@brief   Remove file by path.\n *\n * @param   path Path to file.\n *\n * @return  Standard error code. */\nint ext4_fremove(const char *path);\n\n/**@brief   Create a hardlink for a file.\n *\n * @param   path Path to file.\n * @param   hardlink_path Path of hardlink.\n *\n * @return  Standard error code. */\nint ext4_flink(const char *path, const char *hardlink_path);\n\n/**@brief Rename file.\n * @param path Source.\n * @param new_path Destination.\n * @return  Standard error code. */\nint ext4_frename(const char *path, const char *new_path);\n\n/**@brief   File open function.\n *\n * @param   file  File handle.\n * @param   path  File path, has to start from mount point:/my_partition/file.\n * @param   flags File open flags.\n *  |---------------------------------------------------------------|\n *  |   r or rb                 O_RDONLY                            |\n *  |---------------------------------------------------------------|\n *  |   w or wb                 O_WRONLY|O_CREAT|O_TRUNC            |\n *  |---------------------------------------------------------------|\n *  |   a or ab                 O_WRONLY|O_CREAT|O_APPEND           |\n *  |---------------------------------------------------------------|\n *  |   r+ or rb+ or r+b        O_RDWR                              |\n *  |---------------------------------------------------------------|\n *  |   w+ or wb+ or w+b        O_RDWR|O_CREAT|O_TRUNC              |\n *  |---------------------------------------------------------------|\n *  |   a+ or ab+ or a+b        O_RDWR|O_CREAT|O_APPEND             |\n *  |---------------------------------------------------------------|\n *\n * @return  Standard error code.*/\nint ext4_fopen(ext4_file *file, const char *path, const char *flags);\n\n/**@brief   Alternate file open function.\n *\n * @param   file  File handle.\n * @param   path  File path, has to start from mount point:/my_partition/file.\n * @param   flags File open flags.\n *\n * @return  Standard error code.*/\nint ext4_fopen2(ext4_file *file, const char *path, int flags);\n\n/**@brief   File close function.\n *\n * @param   file File handle.\n *\n * @return  Standard error code.*/\nint ext4_fclose(ext4_file *file);\n\n\n/**@brief   File truncate function.\n *\n * @param   file File handle.\n * @param   size New file size.\n *\n * @return  Standard error code.*/\nint ext4_ftruncate(ext4_file *file, uint64_t size);\n\n/**@brief   Read data from file.\n *\n * @param   file File handle.\n * @param   buf  Output buffer.\n * @param   size Bytes to read.\n * @param   rcnt Bytes read (NULL allowed).\n *\n * @return  Standard error code.*/\nint ext4_fread(ext4_file *file, void *buf, size_t size, size_t *rcnt);\n\n/**@brief   Write data to file.\n *\n * @param   file File handle.\n * @param   buf  Data to write\n * @param   size Write length..\n * @param   wcnt Bytes written (NULL allowed).\n *\n * @return  Standard error code.*/\nint ext4_fwrite(ext4_file *file, const void *buf, size_t size, size_t *wcnt);\n\n/**@brief   File seek operation.\n *\n * @param   file File handle.\n * @param   offset Offset to seek.\n * @param   origin Seek type:\n *              @ref SEEK_SET\n *              @ref SEEK_CUR\n *              @ref SEEK_END\n *\n * @return  Standard error code.*/\nint ext4_fseek(ext4_file *file, int64_t offset, uint32_t origin);\n\n/**@brief   Get file position.\n *\n * @param   file File handle.\n *\n * @return  Actual file position */\nuint64_t ext4_ftell(ext4_file *file);\n\n/**@brief   Get file size.\n *\n * @param   file File handle.\n *\n * @return  File size. */\nuint64_t ext4_fsize(ext4_file *file);\n\n\n/**@brief Get inode of file/directory/link.\n *\n * @param path    Parh to file/dir/link.\n * @param ret_ino Inode number.\n * @param inode   Inode internals.\n *\n * @return  Standard error code.*/\nint ext4_raw_inode_fill(const char *path, uint32_t *ret_ino,\n            struct ext4_inode *inode);\n\n/**@brief Check if inode exists.\n *\n * @param path    Parh to file/dir/link.\n * @param type    Inode type.\n *                @ref EXT4_DIRENTRY_UNKNOWN\n *                @ref EXT4_DE_REG_FILE\n *                @ref EXT4_DE_DIR\n *                @ref EXT4_DE_CHRDEV\n *                @ref EXT4_DE_BLKDEV\n *                @ref EXT4_DE_FIFO\n *                @ref EXT4_DE_SOCK\n *                @ref EXT4_DE_SYMLINK\n *\n * @return  Standard error code.*/\nint ext4_inode_exist(const char *path, int type);\n\n/**@brief Change file/directory/link mode bits.\n *\n * @param path Path to file/dir/link.\n * @param mode New mode bits (for example 0777).\n *\n * @return  Standard error code.*/\nint ext4_mode_set(const char *path, uint32_t mode);\n\n\n/**@brief Get file/directory/link mode bits.\n *\n * @param path Path to file/dir/link.\n * @param mode New mode bits (for example 0777).\n *\n * @return  Standard error code.*/\nint ext4_mode_get(const char *path, uint32_t *mode);\n\n/**@brief Change file owner and group.\n *\n * @param path Path to file/dir/link.\n * @param uid  User id.\n * @param gid  Group id.\n *\n * @return  Standard error code.*/\nint ext4_owner_set(const char *path, uint32_t uid, uint32_t gid);\n\n/**@brief Get file/directory/link owner and group.\n *\n * @param path Path to file/dir/link.\n * @param uid  User id.\n * @param gid  Group id.\n *\n * @return  Standard error code.*/\nint ext4_owner_get(const char *path, uint32_t *uid, uint32_t *gid);\n\n/**@brief Set file/directory/link access time.\n *\n * @param path  Path to file/dir/link.\n * @param atime Access timestamp.\n *\n * @return  Standard error code.*/\nint ext4_atime_set(const char *path, uint32_t atime);\n\n/**@brief Set file/directory/link modify time.\n *\n * @param path  Path to file/dir/link.\n * @param mtime Modify timestamp.\n *\n * @return  Standard error code.*/\nint ext4_mtime_set(const char *path, uint32_t mtime);\n\n/**@brief Set file/directory/link change time.\n *\n * @param path  Path to file/dir/link.\n * @param ctime Change timestamp.\n *\n * @return  Standard error code.*/\nint ext4_ctime_set(const char *path, uint32_t ctime);\n\n/**@brief Get file/directory/link access time.\n *\n * @param path  Path to file/dir/link.\n * @param atime Access timestamp.\n *\n * @return  Standard error code.*/\nint ext4_atime_get(const char *path, uint32_t *atime);\n\n/**@brief Get file/directory/link modify time.\n *\n * @param path  Path to file/dir/link.\n * @param mtime Modify timestamp.\n *\n * @return  Standard error code.*/\nint ext4_mtime_get(const char *path, uint32_t *mtime);\n\n/**@brief Get file/directory/link change time.\n *\n * @param path  Pathto file/dir/link.\n * @param ctime Change timestamp.\n *\n * @return  standard error code*/\nint ext4_ctime_get(const char *path, uint32_t *ctime);\n\n/**@brief Create symbolic link.\n *\n * @param target Destination entry path.\n * @param path   Source entry path.\n *\n * @return  Standard error code.*/\nint ext4_fsymlink(const char *target, const char *path);\n\n/**@brief Create special file.\n * @param path     Path to new special file.\n * @param filetype Filetype of the new special file.\n *             (that must not be regular file, directory, or unknown type)\n * @param dev      If filetype is char device or block device,\n *             the device number will become the payload in the inode.\n * @return  Standard error code.*/\nint ext4_mknod(const char *path, int filetype, uint32_t dev);\n\n/**@brief Read symbolic link payload.\n *\n * @param path    Path to symlink.\n * @param buf     Output buffer.\n * @param bufsize Output buffer max size.\n * @param rcnt    Bytes read.\n *\n * @return  Standard error code.*/\nint ext4_readlink(const char *path, char *buf, size_t bufsize, size_t *rcnt);\n\n/**@brief Set extended attribute.\n *\n * @param path      Path to file/directory\n * @param name      Name of the entry to add.\n * @param name_len  Length of @name in bytes.\n * @param data      Data of the entry to add.\n * @param data_size Size of data to add.\n *\n * @return  Standard error code.*/\nint ext4_setxattr(const char *path, const char *name, size_t name_len,\n          const void *data, size_t data_size);\n\n/**@brief Get extended attribute.\n *\n * @param path      Path to file/directory.\n * @param name      Name of the entry to get.\n * @param name_len  Length of @name in bytes.\n * @param data      Data of the entry to get.\n * @param data_size Size of data to get.\n *\n * @return  Standard error code.*/\nint ext4_getxattr(const char *path, const char *name, size_t name_len,\n          void *buf, size_t buf_size, size_t *data_size);\n\n/**@brief List extended attributes.\n *\n * @param path     Path to file/directory.\n * @param list     List to hold the name of entries.\n * @param size     Size of @list in bytes.\n * @param ret_size Used bytes of @list.\n *\n * @return  Standard error code.*/\nint ext4_listxattr(const char *path, char *list, size_t size, size_t *ret_size);\n\n/**@brief Remove extended attribute.\n *\n * @param path     Path to file/directory.\n * @param name     Name of the entry to remove.\n * @param name_len Length of @name in bytes.\n *\n * @return  Standard error code.*/\nint ext4_removexattr(const char *path, const char *name, size_t name_len);\n\n\n/*********************************DIRECTORY OPERATION***********************/\n\n/**@brief   Recursive directory remove.\n *\n * @param   path Directory path to remove\n *\n * @return  Standard error code.*/\nint ext4_dir_rm(const char *path);\n\n/**@brief Rename/move directory.\n *\n * @param path     Source path.\n * @param new_path Destination path.\n *\n * @return  Standard error code. */\nint ext4_dir_mv(const char *path, const char *new_path);\n\n/**@brief   Create new directory.\n *\n * @param   path Directory name.\n *\n * @return  Standard error code.*/\nint ext4_dir_mk(const char *path);\n\n/**@brief   Directory open.\n *\n * @param   dir  Directory handle.\n * @param   path Directory path.\n *\n * @return  Standard error code.*/\nint ext4_dir_open(ext4_dir *dir, const char *path);\n\n/**@brief   Directory close.\n *\n * @param   dir directory handle.\n *\n * @return  Standard error code.*/\nint ext4_dir_close(ext4_dir *dir);\n\n/**@brief   Return next directory entry.\n *\n * @param   dir Directory handle.\n *\n * @return  Directory entry id (NULL if no entry)*/\nconst ext4_direntry *ext4_dir_entry_next(ext4_dir *dir);\n\n/**@brief   Rewine directory entry offset.\n *\n * @param   dir Directory handle.*/\nvoid ext4_dir_entry_rewind(ext4_dir *dir);\n\nint ext4_dir_seek(ext4_dir *dir, int64_t offset, uint32_t origin);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EXT4_H_ */\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_balloc.h",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n *\n * HelenOS:\n * Copyright (c) 2012 Martin Sucha\n * Copyright (c) 2012 Frantisek Princ\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_balloc.h\n * @brief Physical block allocator.\n */\n\n#ifndef EXT4_BALLOC_H_\n#define EXT4_BALLOC_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n\n#include <ext4_fs.h>\n\n#include <stdint.h>\n#include <stdbool.h>\n\n/**@brief Compute number of block group from block address.\n * @param sb superblock pointer.\n * @param baddr Absolute address of block.\n * @return Block group index\n */\nuint32_t ext4_balloc_get_bgid_of_block(struct ext4_sblock *s,\n                       ext4_fsblk_t baddr);\n\n/**@brief Compute the starting block address of a block group\n * @param sb   superblock pointer.\n * @param bgid block group index\n * @return Block address\n */\next4_fsblk_t ext4_balloc_get_block_of_bgid(struct ext4_sblock *s,\n                       uint32_t bgid);\n\n/**@brief Calculate and set checksum of block bitmap.\n * @param sb superblock pointer.\n * @param bg block group\n * @param bitmap bitmap buffer\n */\nvoid ext4_balloc_set_bitmap_csum(struct ext4_sblock *sb,\n                 struct ext4_bgroup *bg,\n                 void *bitmap);\n\n/**@brief   Free block from inode.\n * @param   inode_ref inode reference\n * @param   baddr block address\n * @return  standard error code*/\nint ext4_balloc_free_block(struct ext4_inode_ref *inode_ref,\n               ext4_fsblk_t baddr);\n\n/**@brief   Free blocks from inode.\n * @param   inode_ref inode reference\n * @param   first block address\n * @param   count block count\n * @return  standard error code*/\nint ext4_balloc_free_blocks(struct ext4_inode_ref *inode_ref,\n                ext4_fsblk_t first, uint32_t count);\n\n/**@brief   Allocate block procedure.\n * @param   inode_ref inode reference\n * @param   goal\n * @param   baddr allocated block address\n * @return  standard error code*/\nint ext4_balloc_alloc_block(struct ext4_inode_ref *inode_ref,\n                ext4_fsblk_t goal,\n                ext4_fsblk_t *baddr);\n\n/**@brief   Try allocate selected block.\n * @param   inode_ref inode reference\n * @param   baddr block address to allocate\n * @param   free if baddr is not allocated\n * @return  standard error code*/\nint ext4_balloc_try_alloc_block(struct ext4_inode_ref *inode_ref,\n                ext4_fsblk_t baddr, bool *free);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EXT4_BALLOC_H_ */\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_bcache.h",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_bcache.h\n * @brief Block cache allocator.\n */\n\n#ifndef EXT4_BCACHE_H_\n#define EXT4_BCACHE_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <ext4_config.h>\n\n#include <stdint.h>\n#include <stdbool.h>\n#include <misc/tree.h>\n#include <misc/queue.h>\n\n#define EXT4_BLOCK_ZERO()   \\\n    {.lb_id = 0, .data = 0}\n\n/**@brief   Single block descriptor*/\nstruct ext4_block {\n    /**@brief   Logical block ID*/\n    uint64_t lb_id;\n\n    /**@brief   Buffer */\n    struct ext4_buf *buf;\n\n    /**@brief   Data buffer.*/\n    uint8_t *data;\n};\n\nstruct ext4_bcache;\n\n/**@brief   Single block descriptor*/\nstruct ext4_buf {\n    /**@brief   Flags*/\n    int flags;\n\n    /**@brief   Logical block address*/\n    uint64_t lba;\n\n    /**@brief   Data buffer.*/\n    uint8_t *data;\n\n    /**@brief   LRU priority. (unused) */\n    uint32_t lru_prio;\n\n    /**@brief   LRU id.*/\n    uint32_t lru_id;\n\n    /**@brief   Reference count table*/\n    uint32_t refctr;\n\n    /**@brief   The block cache this buffer belongs to. */\n    struct ext4_bcache *bc;\n\n    /**@brief   Whether or not buffer is on dirty list.*/\n    bool on_dirty_list;\n\n    /**@brief   LBA tree node*/\n    RB_ENTRY(ext4_buf) lba_node;\n\n    /**@brief   LRU tree node*/\n    RB_ENTRY(ext4_buf) lru_node;\n\n    /**@brief   Dirty list node*/\n    SLIST_ENTRY(ext4_buf) dirty_node;\n\n    /**@brief   Callback routine after a disk-write operation.\n     * @param   bc block cache descriptor\n     * @param   buf buffer descriptor\n     * @param   standard error code returned by bdev->bwrite()\n     * @param   arg argument passed to this routine*/\n    void (*end_write)(struct ext4_bcache *bc,\n              struct ext4_buf *buf,\n              int res,\n              void *arg);\n\n    /**@brief   argument passed to end_write() callback.*/\n    void *end_write_arg;\n};\n\n/**@brief   Block cache descriptor*/\nstruct ext4_bcache {\n\n    /**@brief   Item count in block cache*/\n    uint32_t cnt;\n\n    /**@brief   Item size in block cache*/\n    uint32_t itemsize;\n\n    /**@brief   Last recently used counter*/\n    uint32_t lru_ctr;\n\n    /**@brief   Currently referenced datablocks*/\n    uint32_t ref_blocks;\n\n    /**@brief   Maximum referenced datablocks*/\n    uint32_t max_ref_blocks;\n\n    /**@brief   The blockdev binded to this block cache*/\n    struct ext4_blockdev *bdev;\n\n    /**@brief   The cache should not be shaked */\n    bool dont_shake;\n\n    /**@brief   A tree holding all bufs*/\n    RB_HEAD(ext4_buf_lba, ext4_buf) lba_root;\n\n    /**@brief   A tree holding unreferenced bufs*/\n    RB_HEAD(ext4_buf_lru, ext4_buf) lru_root;\n\n    /**@brief   A singly-linked list holding dirty buffers*/\n    SLIST_HEAD(ext4_buf_dirty, ext4_buf) dirty_list;\n};\n\n/**@brief buffer state bits\n *\n *  - BCâ™¡UPTODATE: Buffer contains valid data.\n *  - BC_DIRTY: Buffer is dirty.\n *  - BC_FLUSH: Buffer will be immediately flushed,\n *              when no one references it.\n *  - BC_TMP: Buffer will be dropped once its refctr\n *            reaches zero.\n */\nenum bcache_state_bits {\n    BC_UPTODATE,\n    BC_DIRTY,\n    BC_FLUSH,\n    BC_TMP\n};\n\n#define ext4_bcache_set_flag(buf, b)    \\\n    (buf)->flags |= 1 << (b)\n\n#define ext4_bcache_clear_flag(buf, b)    \\\n    (buf)->flags &= ~(1 << (b))\n\n#define ext4_bcache_test_flag(buf, b)    \\\n    (((buf)->flags & (1 << (b))) >> (b))\n\nstatic inline void ext4_bcache_set_dirty(struct ext4_buf *buf) {\n    ext4_bcache_set_flag(buf, BC_UPTODATE);\n    ext4_bcache_set_flag(buf, BC_DIRTY);\n}\n\nstatic inline void ext4_bcache_clear_dirty(struct ext4_buf *buf) {\n    ext4_bcache_clear_flag(buf, BC_UPTODATE);\n    ext4_bcache_clear_flag(buf, BC_DIRTY);\n}\n\n/**@brief   Increment reference counter of buf by 1.*/\n#define ext4_bcache_inc_ref(buf) ((buf)->refctr++)\n\n/**@brief   Decrement reference counter of buf by 1.*/\n#define ext4_bcache_dec_ref(buf) ((buf)->refctr--)\n\n/**@brief   Insert buffer to dirty cache list\n * @param   bc block cache descriptor\n * @param   buf buffer descriptor */\nstatic inline void\next4_bcache_insert_dirty_node(struct ext4_bcache *bc, struct ext4_buf *buf) {\n    if (!buf->on_dirty_list) {\n        SLIST_INSERT_HEAD(&bc->dirty_list, buf, dirty_node);\n        buf->on_dirty_list = true;\n    }\n}\n\n/**@brief   Remove buffer to dirty cache list\n * @param   bc block cache descriptor\n * @param   buf buffer descriptor */\nstatic inline void\next4_bcache_remove_dirty_node(struct ext4_bcache *bc, struct ext4_buf *buf) {\n    if (buf->on_dirty_list) {\n        SLIST_REMOVE(&bc->dirty_list, buf, ext4_buf, dirty_node);\n        buf->on_dirty_list = false;\n    }\n}\n\n\n/**@brief   Dynamic initialization of block cache.\n * @param   bc block cache descriptor\n * @param   cnt items count in block cache\n * @param   itemsize single item size (in bytes)\n * @return  standard error code*/\nint ext4_bcache_init_dynamic(struct ext4_bcache *bc, uint32_t cnt,\n                 uint32_t itemsize);\n\n/**@brief   Do cleanup works on block cache.\n * @param   bc block cache descriptor.*/\nvoid ext4_bcache_cleanup(struct ext4_bcache *bc);\n\n/**@brief   Dynamic de-initialization of block cache.\n * @param   bc block cache descriptor\n * @return  standard error code*/\nint ext4_bcache_fini_dynamic(struct ext4_bcache *bc);\n\n/**@brief   Get a buffer with the lowest LRU counter in bcache.\n * @param   bc block cache descriptor\n * @return  buffer with the lowest LRU counter*/\nstruct ext4_buf *ext4_buf_lowest_lru(struct ext4_bcache *bc);\n\n/**@brief   Drop unreferenced buffer from bcache.\n * @param   bc block cache descriptor\n * @param   buf buffer*/\nvoid ext4_bcache_drop_buf(struct ext4_bcache *bc, struct ext4_buf *buf);\n\n/**@brief   Invalidate a buffer.\n * @param   bc block cache descriptor\n * @param   buf buffer*/\nvoid ext4_bcache_invalidate_buf(struct ext4_bcache *bc,\n                struct ext4_buf *buf);\n\n/**@brief   Invalidate a range of buffers.\n * @param   bc block cache descriptor\n * @param   from starting lba\n * @param   cnt block counts\n * @param   buf buffer*/\nvoid ext4_bcache_invalidate_lba(struct ext4_bcache *bc,\n                uint64_t from,\n                uint32_t cnt);\n\n/**@brief   Find existing buffer from block cache memory.\n *          Unreferenced block allocation is based on LRU\n *          (Last Recently Used) algorithm.\n * @param   bc block cache descriptor\n * @param   b block to alloc\n * @param   lba logical block address\n * @return  block cache buffer */\nstruct ext4_buf *\next4_bcache_find_get(struct ext4_bcache *bc, struct ext4_block *b,\n             uint64_t lba);\n\n/**@brief   Allocate block from block cache memory.\n *          Unreferenced block allocation is based on LRU\n *          (Last Recently Used) algorithm.\n * @param   bc block cache descriptor\n * @param   b block to alloc\n * @param   is_new block is new (needs to be read)\n * @return  standard error code*/\nint ext4_bcache_alloc(struct ext4_bcache *bc, struct ext4_block *b,\n              bool *is_new);\n\n/**@brief   Free block from cache memory (decrement reference counter).\n * @param   bc block cache descriptor\n * @param   b block to free\n * @return  standard error code*/\nint ext4_bcache_free(struct ext4_bcache *bc, struct ext4_block *b);\n\n/**@brief   Return a full status of block cache.\n * @param   bc block cache descriptor\n * @return  full status*/\nbool ext4_bcache_is_full(struct ext4_bcache *bc);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EXT4_BCACHE_H_ */\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_bitmap.h",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_bitmap.h\n * @brief Block/inode bitmap allocator.\n */\n\n#ifndef EXT4_BITMAP_H_\n#define EXT4_BITMAP_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <ext4_config.h>\n\n#include <stdint.h>\n#include <stdbool.h>\n\n/**@brief   Set bitmap bit.\n * @param   bmap bitmap\n * @param   bit bit to set*/\nstatic inline void ext4_bmap_bit_set(uint8_t *bmap, uint32_t bit)\n{\n    *(bmap + (bit >> 3)) |= (1 << (bit & 7));\n}\n\n/**@brief   Clear bitmap bit.\n * @param   bmap bitmap buffer\n * @param   bit bit to clear*/\nstatic inline void ext4_bmap_bit_clr(uint8_t *bmap, uint32_t bit)\n{\n    *(bmap + (bit >> 3)) &= ~(1 << (bit & 7));\n}\n\n/**@brief   Check if the bitmap bit is set.\n * @param   bmap bitmap buffer\n * @param   bit bit to check*/\nstatic inline bool ext4_bmap_is_bit_set(uint8_t *bmap, uint32_t bit)\n{\n    return (*(bmap + (bit >> 3)) & (1 << (bit & 7)));\n}\n\n/**@brief   Check if the bitmap bit is clear.\n * @param   bmap bitmap buffer\n * @param   bit bit to check*/\nstatic inline bool ext4_bmap_is_bit_clr(uint8_t *bmap, uint32_t bit)\n{\n    return !ext4_bmap_is_bit_set(bmap, bit);\n}\n\n/**@brief   Free range of bits in bitmap.\n * @param   bmap bitmap buffer\n * @param   sbit start bit\n * @param   bcnt bit count*/\nvoid ext4_bmap_bits_free(uint8_t *bmap, uint32_t sbit, uint32_t bcnt);\n\n/**@brief   Find first clear bit in bitmap.\n * @param   sbit start bit of search\n * @param   ebit end bit of search\n * @param   bit_id output parameter (first free bit)\n * @return  standard error code*/\nint ext4_bmap_bit_find_clr(uint8_t *bmap, uint32_t sbit, uint32_t ebit,\n               uint32_t *bit_id);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EXT4_BITMAP_H_ */\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_blkdev.h",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_blockdev.h\n * @brief Block device module.\n */\n\n#ifndef EXT4_BLKDEV_H_\n#define EXT4_BLKDEV_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdbool.h>\n#include <stdint.h>\n\nstruct ext4_blockdev;\n\nstruct ext4_blockdev_iface {\n    /**@brief   Open device function\n     * @param   bdev block device.*/\n    int (*open)(struct ext4_blockdev *bdev);\n\n    /**@brief   Block read function.\n     * @param   bdev block device\n     * @param   buf output buffer\n     * @param   blk_id block id\n     * @param   blk_cnt block count*/\n    int (*bread)(struct ext4_blockdev *bdev, void *buf, uint64_t blk_id,\n             uint32_t blk_cnt);\n\n    /**@brief   Block write function.\n     * @param   buf input buffer\n     * @param   blk_id block id\n     * @param   blk_cnt block count*/\n    int (*bwrite)(struct ext4_blockdev *bdev, const void *buf,\n              uint64_t blk_id, uint32_t blk_cnt);\n\n    /**@brief   Close device function.\n     * @param   bdev block device.*/\n    int (*close)(struct ext4_blockdev *bdev);\n\n    /**@brief   Lock block device. Required in multi partition mode\n     *          operations. Not mandatory field.\n     * @param   bdev block device.*/\n    int (*lock)(struct ext4_blockdev *bdev);\n\n    /**@brief   Unlock block device. Required in multi partition mode\n     *          operations. Not mandatory field.\n     * @param   bdev block device.*/\n    int (*unlock)(struct ext4_blockdev *bdev);\n\n    /**@brief   Block size (bytes): physical*/\n    uint32_t ph_bsize;\n\n    /**@brief   Block count: physical*/\n    uint64_t ph_bcnt;\n\n    /**@brief   Block size buffer: physical*/\n    uint8_t *ph_bbuf;\n\n    /**@brief   Reference counter to block device interface*/\n    uint32_t ph_refctr;\n\n    /**@brief   Physical read counter*/\n    uint32_t bread_ctr;\n\n    /**@brief   Physical write counter*/\n    uint32_t bwrite_ctr;\n\n    /**@brief   User data pointer*/\n    void* p_user;\n};\n\n/**@brief   Definition of the simple block device.*/\nstruct ext4_blockdev {\n    /**@brief Block device interface*/\n    struct ext4_blockdev_iface *bdif;\n\n    /**@brief Offset in bdif. For multi partition mode.*/\n    uint64_t part_offset;\n\n    /**@brief Part size in bdif. For multi partition mode.*/\n    uint64_t part_size;\n\n    /**@brief   Block cache.*/\n    struct ext4_bcache *bc;\n\n    /**@brief   Block size (bytes) logical*/\n    uint32_t lg_bsize;\n\n    /**@brief   Block count: logical*/\n    uint64_t lg_bcnt;\n\n    /**@brief   Cache write back mode reference counter*/\n    uint32_t cache_write_back;\n\n    /**@brief   The filesystem this block device belongs to. */\n    struct ext4_fs *fs;\n\n    void *journal;\n};\n\n/**@brief   Static initialization of the block device.*/\n#define EXT4_BLOCKDEV_STATIC_INSTANCE(__name, __bsize, __bcnt, __open, __bread,\\\n                      __bwrite, __close, __lock, __unlock)     \\\n    static uint8_t __name##_ph_bbuf[(__bsize)];                            \\\n    static struct ext4_blockdev_iface __name##_iface = {                   \\\n        .open = __open,                                                \\\n        .bread = __bread,                                              \\\n        .bwrite = __bwrite,                                            \\\n        .close = __close,                                              \\\n        .lock = __lock,                                                \\\n        .unlock = __unlock,                                            \\\n        .ph_bsize = __bsize,                                           \\\n        .ph_bcnt = __bcnt,                                             \\\n        .ph_bbuf = __name##_ph_bbuf,                                   \\\n    };                                     \\\n    static struct ext4_blockdev __name = {                                 \\\n        .bdif = &__name##_iface,                                       \\\n        .part_offset = 0,                                              \\\n        .part_size =  (__bcnt) * (__bsize),                            \\\n    }\n\nint run_ext4_file_server(struct ext4_blockdev *bdev);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EXT4_BLOCKDEV_H_ */\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_block_group.h",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n *\n *\n * HelenOS:\n * Copyright (c) 2012 Martin Sucha\n * Copyright (c) 2012 Frantisek Princ\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_block_group.h\n * @brief Block group function set.\n */\n\n#ifndef EXT4_BLOCK_GROUP_H_\n#define EXT4_BLOCK_GROUP_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_super.h>\n\n#include <stdint.h>\n#include <stdbool.h>\n\n/**@brief Get address of block with data block bitmap.\n * @param bg pointer to block group\n * @param s pointer to superblock\n * @return Address of block with block bitmap\n */\nstatic inline uint64_t ext4_bg_get_block_bitmap(struct ext4_bgroup *bg,\n                        struct ext4_sblock *s)\n{\n    uint64_t v = to_le32(bg->block_bitmap_lo);\n\n    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)\n        v |= (uint64_t)to_le32(bg->block_bitmap_hi) << 32;\n\n    return v;\n}\n\n/**@brief Set address of block with data block bitmap.\n * @param bg pointer to block group\n * @param s pointer to superblock\n * @param blk block to set\n * @return Address of block with block bitmap\n */\nstatic inline void ext4_bg_set_block_bitmap(struct ext4_bgroup *bg,\n                        struct ext4_sblock *s, uint64_t blk)\n{\n\n    bg->block_bitmap_lo = to_le32((uint32_t)blk);\n    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)\n        bg->block_bitmap_hi = to_le32(blk >> 32);\n\n}\n\n/**@brief Get address of block with i-node bitmap.\n * @param bg Pointer to block group\n * @param s Pointer to superblock\n * @return Address of block with i-node bitmap\n */\nstatic inline uint64_t ext4_bg_get_inode_bitmap(struct ext4_bgroup *bg,\n                        struct ext4_sblock *s)\n{\n\n    uint64_t v = to_le32(bg->inode_bitmap_lo);\n\n    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)\n        v |= (uint64_t)to_le32(bg->inode_bitmap_hi) << 32;\n\n    return v;\n}\n\n/**@brief Set address of block with i-node bitmap.\n * @param bg Pointer to block group\n * @param s Pointer to superblock\n * @param blk block to set\n * @return Address of block with i-node bitmap\n */\nstatic inline void ext4_bg_set_inode_bitmap(struct ext4_bgroup *bg,\n                        struct ext4_sblock *s, uint64_t blk)\n{\n    bg->inode_bitmap_lo = to_le32((uint32_t)blk);\n    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)\n        bg->inode_bitmap_hi = to_le32(blk >> 32);\n\n}\n\n\n/**@brief Get address of the first block of the i-node table.\n * @param bg Pointer to block group\n * @param s Pointer to superblock\n * @return Address of first block of i-node table\n */\nstatic inline uint64_t\next4_bg_get_inode_table_first_block(struct ext4_bgroup *bg,\n                    struct ext4_sblock *s)\n{\n    uint64_t v = to_le32(bg->inode_table_first_block_lo);\n\n    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)\n        v |= (uint64_t)to_le32(bg->inode_table_first_block_hi) << 32;\n\n    return v;\n}\n\n/**@brief Set address of the first block of the i-node table.\n * @param bg Pointer to block group\n * @param s Pointer to superblock\n * @param blk block to set\n * @return Address of first block of i-node table\n */\nstatic inline void\next4_bg_set_inode_table_first_block(struct ext4_bgroup *bg,\n                    struct ext4_sblock *s, uint64_t blk)\n{\n    bg->inode_table_first_block_lo = to_le32((uint32_t)blk);\n    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)\n        bg->inode_table_first_block_hi = to_le32(blk >> 32);\n}\n\n/**@brief Get number of free blocks in block group.\n * @param bg Pointer to block group\n * @param sb Pointer to superblock\n * @return Number of free blocks in block group\n */\nstatic inline uint32_t ext4_bg_get_free_blocks_count(struct ext4_bgroup *bg,\n                             struct ext4_sblock *s)\n{\n    uint32_t v = to_le16(bg->free_blocks_count_lo);\n\n    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)\n        v |= (uint32_t)to_le16(bg->free_blocks_count_hi) << 16;\n\n    return v;\n}\n\n/**@brief Set number of free blocks in block group.\n * @param bg Pointer to block group\n * @param s Pointer to superblock\n * @param cnt Number of free blocks in block group\n */\nstatic inline void ext4_bg_set_free_blocks_count(struct ext4_bgroup *bg,\n                         struct ext4_sblock *s,\n                         uint32_t cnt)\n{\n    bg->free_blocks_count_lo = to_le16((cnt << 16) >> 16);\n    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)\n        bg->free_blocks_count_hi = to_le16(cnt >> 16);\n}\n\n/**@brief Get number of free i-nodes in block group.\n * @param bg Pointer to block group\n * @param s Pointer to superblock\n * @return Number of free i-nodes in block group\n */\nstatic inline uint32_t ext4_bg_get_free_inodes_count(struct ext4_bgroup *bg,\n                             struct ext4_sblock *s)\n{\n    uint32_t v = to_le16(bg->free_inodes_count_lo);\n\n    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)\n        v |= (uint32_t)to_le16(bg->free_inodes_count_hi) << 16;\n\n    return v;\n}\n\n/**@brief Set number of free i-nodes in block group.\n * @param bg Pointer to block group\n * @param s Pointer to superblock\n * @param cnt Number of free i-nodes in block group\n */\nstatic inline void ext4_bg_set_free_inodes_count(struct ext4_bgroup *bg,\n                         struct ext4_sblock *s,\n                         uint32_t cnt)\n{\n    bg->free_inodes_count_lo = to_le16((cnt << 16) >> 16);\n    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)\n        bg->free_inodes_count_hi = to_le16(cnt >> 16);\n}\n\n/**@brief Get number of used directories in block group.\n * @param bg Pointer to block group\n * @param s Pointer to superblock\n * @return Number of used directories in block group\n */\nstatic inline uint32_t ext4_bg_get_used_dirs_count(struct ext4_bgroup *bg,\n                           struct ext4_sblock *s)\n{\n    uint32_t v = to_le16(bg->used_dirs_count_lo);\n\n    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)\n        v |= (uint32_t)to_le16(bg->used_dirs_count_hi) << 16;\n\n    return v;\n}\n\n/**@brief Set number of used directories in block group.\n * @param bg Pointer to block group\n * @param s Pointer to superblock\n * @param cnt Number of used directories in block group\n */\nstatic inline void ext4_bg_set_used_dirs_count(struct ext4_bgroup *bg,\n                           struct ext4_sblock *s,\n                           uint32_t cnt)\n{\n    bg->used_dirs_count_lo = to_le16((cnt << 16) >> 16);\n    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)\n        bg->used_dirs_count_hi = to_le16(cnt >> 16);\n}\n\n/**@brief Get number of unused i-nodes.\n * @param bg Pointer to block group\n * @param s Pointer to superblock\n * @return Number of unused i-nodes\n */\nstatic inline uint32_t ext4_bg_get_itable_unused(struct ext4_bgroup *bg,\n                         struct ext4_sblock *s)\n{\n\n    uint32_t v = to_le16(bg->itable_unused_lo);\n\n    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)\n        v |= (uint32_t)to_le16(bg->itable_unused_hi) << 16;\n\n    return v;\n}\n\n/**@brief Set number of unused i-nodes.\n * @param bg Pointer to block group\n * @param s Pointer to superblock\n * @param cnt Number of unused i-nodes\n */\nstatic inline void ext4_bg_set_itable_unused(struct ext4_bgroup *bg,\n                         struct ext4_sblock *s,\n                         uint32_t cnt)\n{\n    bg->itable_unused_lo = to_le16((cnt << 16) >> 16);\n    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)\n        bg->itable_unused_hi = to_le16(cnt >> 16);\n}\n\n/**@brief  Set checksum of block group.\n * @param bg Pointer to block group\n * @param crc Cheksum of block group\n */\nstatic inline void ext4_bg_set_checksum(struct ext4_bgroup *bg, uint16_t crc)\n{\n    bg->checksum = to_le16(crc);\n}\n\n/**@brief Check if block group has a flag.\n * @param bg Pointer to block group\n * @param flag Flag to be checked\n * @return True if flag is set to 1\n */\nstatic inline bool ext4_bg_has_flag(struct ext4_bgroup *bg, uint32_t f)\n{\n    return to_le16(bg->flags) & f;\n}\n\n/**@brief Set flag of block group.\n * @param bg Pointer to block group\n * @param flag Flag to be set\n */\nstatic inline void ext4_bg_set_flag(struct ext4_bgroup *bg, uint32_t f)\n{\n    uint16_t flags = to_le16(bg->flags);\n    flags |= f;\n    bg->flags = to_le16(flags);\n}\n\n/**@brief Clear flag of block group.\n * @param bg Pointer to block group\n * @param flag Flag to be cleared\n */\nstatic inline void ext4_bg_clear_flag(struct ext4_bgroup *bg, uint32_t f)\n{\n    uint16_t flags = to_le16(bg->flags);\n    flags &= ~f;\n    bg->flags = to_le16(flags);\n}\n\n/**@brief Calculate CRC16 of the block group.\n * @param crc Init value\n * @param buffer Input buffer\n * @param len Sizeof input buffer\n * @return Computed CRC16*/\nuint16_t ext4_bg_crc16(uint16_t crc, const uint8_t *buffer, size_t len);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EXT4_BLOCK_GROUP_H_ */\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_blockdev.h",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_blockdev.h\n * @brief Block device module.\n */\n\n#ifndef EXT4_BLOCKDEV_H_\n#define EXT4_BLOCKDEV_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <ext4_config.h>\n#include <ext4_bcache.h>\n#include <ext4_blkdev.h>\n\n#include <stdbool.h>\n#include <stdint.h>\n\n/**@brief   Block device initialization.\n * @param   bdev block device descriptor\n * @param   bg_bsize logical block size\n * @param   bdev block device descriptor\n * @return  standard error code*/\nint ext4_block_init(struct ext4_blockdev *bdev);\n\n/**@brief   Binds a bcache to block device.\n * @param   bdev block device descriptor\n * @param   bc block cache descriptor\n * @return  standard error code*/\nint ext4_block_bind_bcache(struct ext4_blockdev *bdev, struct ext4_bcache *bc);\n\n/**@brief   Close block device\n * @param   bdev block device descriptor\n * @return  standard error code*/\nint ext4_block_fini(struct ext4_blockdev *bdev);\n\n/**@brief   Flush data in given buffer to disk.\n * @param   bdev block device descriptor\n * @param   buf buffer\n * @return  standard error code*/\nint ext4_block_flush_buf(struct ext4_blockdev *bdev, struct ext4_buf *buf);\n\n/**@brief   Flush data in buffer of given lba to disk,\n *          if that buffer exists in block cache.\n * @param   bdev block device descriptor\n * @param   lba logical block address\n * @return  standard error code*/\nint ext4_block_flush_lba(struct ext4_blockdev *bdev, uint64_t lba);\n\n/**@brief   Set logical block size in block device.\n * @param   bdev block device descriptor\n * @param   lb_size logical block size (in bytes)\n * @return  standard error code*/\nvoid ext4_block_set_lb_size(struct ext4_blockdev *bdev, uint32_t lb_bsize);\n\n/**@brief   Block get function (through cache, don't read).\n * @param   bdev block device descriptor\n * @param   b block descriptor\n * @param   lba logical block address\n * @return  standard error code*/\nint ext4_block_get_noread(struct ext4_blockdev *bdev, struct ext4_block *b,\n              uint64_t lba);\n\n/**@brief   Block get function (through cache).\n * @param   bdev block device descriptor\n * @param   b block descriptor\n * @param   lba logical block address\n * @return  standard error code*/\nint ext4_block_get(struct ext4_blockdev *bdev, struct ext4_block *b,\n           uint64_t lba);\n\n/**@brief   Block set procedure (through cache).\n * @param   bdev block device descriptor\n * @param   b block descriptor\n * @return  standard error code*/\nint ext4_block_set(struct ext4_blockdev *bdev, struct ext4_block *b);\n\n/**@brief   Block read procedure (without cache)\n * @param   bdev block device descriptor\n * @param   buf output buffer\n * @param   lba logical block address\n * @return  standard error code*/\nint ext4_blocks_get_direct(struct ext4_blockdev *bdev, void *buf, uint64_t lba,\n               uint32_t cnt);\n\n/**@brief   Block write procedure (without cache)\n * @param   bdev block device descriptor\n * @param   buf output buffer\n * @param   lba logical block address\n * @return  standard error code*/\nint ext4_blocks_set_direct(struct ext4_blockdev *bdev, const void *buf,\n               uint64_t lba, uint32_t cnt);\n\n/**@brief   Write to block device (by direct address).\n * @param   bdev block device descriptor\n * @param   off byte offset in block device\n * @param   buf input buffer\n * @param   len length of the write buffer\n * @return  standard error code*/\nint ext4_block_writebytes(struct ext4_blockdev *bdev, uint64_t off,\n              const void *buf, uint32_t len);\n\n/**@brief   Read freom block device (by direct address).\n * @param   bdev block device descriptor\n * @param   off byte offset in block device\n * @param   buf input buffer\n * @param   len length of the write buffer\n * @return  standard error code*/\nint ext4_block_readbytes(struct ext4_blockdev *bdev, uint64_t off, void *buf,\n             uint32_t len);\n\n/**@brief   Flush all dirty buffers to disk\n * @param   bdev block device descriptor\n * @return  standard error code*/\nint ext4_block_cache_flush(struct ext4_blockdev *bdev);\n\n/**@brief   Enable/disable write back cache mode\n * @param   bdev block device descriptor\n * @param   on_off\n *              !0 - ENABLE\n *               0 - DISABLE (all delayed cache buffers will be flushed)\n * @return  standard error code*/\nint ext4_block_cache_write_back(struct ext4_blockdev *bdev, uint8_t on_off);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EXT4_BLOCKDEV_H_ */\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_config.h",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_config.h\n * @brief Configuration file.\n */\n\n#ifndef EXT4_CONFIG_H_\n#define EXT4_CONFIG_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#if !CONFIG_USE_DEFAULT_CFG\n#include \"generated/ext4_config.h\"\n#endif\n\n/*****************************************************************************/\n\n#define F_SET_EXT2 2\n#define F_SET_EXT3 3\n#define F_SET_EXT4 4\n\n#ifndef CONFIG_EXT_FEATURE_SET_LVL\n#define CONFIG_EXT_FEATURE_SET_LVL F_SET_EXT4\n#endif\n\n/*****************************************************************************/\n\n#if CONFIG_EXT_FEATURE_SET_LVL == F_SET_EXT2\n/*Superblock features flag EXT2*/\n#define CONFIG_SUPPORTED_FCOM EXT2_SUPPORTED_FCOM\n#define CONFIG_SUPPORTED_FINCOM (EXT2_SUPPORTED_FINCOM | EXT_FINCOM_IGNORED)\n#define CONFIG_SUPPORTED_FRO_COM EXT2_SUPPORTED_FRO_COM\n\n#elif CONFIG_EXT_FEATURE_SET_LVL == F_SET_EXT3\n/*Superblock features flag EXT3*/\n#define CONFIG_SUPPORTED_FCOM EXT3_SUPPORTED_FCOM\n#define CONFIG_SUPPORTED_FINCOM (EXT3_SUPPORTED_FINCOM | EXT_FINCOM_IGNORED)\n#define CONFIG_SUPPORTED_FRO_COM EXT3_SUPPORTED_FRO_COM\n#elif CONFIG_EXT_FEATURE_SET_LVL == F_SET_EXT4\n/*Superblock features flag EXT4*/\n#define CONFIG_SUPPORTED_FCOM EXT4_SUPPORTED_FCOM\n#define CONFIG_SUPPORTED_FINCOM (EXT4_SUPPORTED_FINCOM | EXT_FINCOM_IGNORED)\n#define CONFIG_SUPPORTED_FRO_COM EXT4_SUPPORTED_FRO_COM\n#else\n#define \"Unsupported CONFIG_EXT_FEATURE_SET_LVL\"\n#endif\n\n#define CONFIG_DIR_INDEX_ENABLE (CONFIG_SUPPORTED_FCOM & EXT4_FCOM_DIR_INDEX)\n#define CONFIG_EXTENT_ENABLE (CONFIG_SUPPORTED_FINCOM & EXT4_FINCOM_EXTENTS)\n#define CONFIG_META_CSUM_ENABLE (CONFIG_SUPPORTED_FRO_COM & EXT4_FRO_COM_METADATA_CSUM)\n\n/*****************************************************************************/\n\n/**@brief  Enable/disable journaling*/\n#ifndef CONFIG_JOURNALING_ENABLE\n#define CONFIG_JOURNALING_ENABLE 1\n#endif\n\n/**@brief  Enable/disable xattr*/\n#ifndef CONFIG_XATTR_ENABLE\n#define CONFIG_XATTR_ENABLE 1\n#endif\n\n/**@brief  Enable/disable extents*/\n#ifndef CONFIG_EXTENTS_ENABLE\n#define CONFIG_EXTENTS_ENABLE 1\n#endif\n\n/**@brief   Include error codes from ext4_errno or standard library.*/\n#ifndef CONFIG_HAVE_OWN_ERRNO\n#define CONFIG_HAVE_OWN_ERRNO 0\n#endif\n\n/**@brief   Debug printf enable (stdout)*/\n#ifndef CONFIG_DEBUG_PRINTF\n#define CONFIG_DEBUG_PRINTF 1\n#endif\n\n/**@brief   Assert printf enable (stdout)*/\n#ifndef CONFIG_DEBUG_ASSERT\n#define CONFIG_DEBUG_ASSERT 1\n#endif\n\n/**@brief   Include assert codes from ext4_debug or standard library.*/\n#ifndef CONFIG_HAVE_OWN_ASSERT\n#define CONFIG_HAVE_OWN_ASSERT 1\n#endif\n\n/**@brief   Statistics of block device*/\n#ifndef CONFIG_BLOCK_DEV_ENABLE_STATS\n#define CONFIG_BLOCK_DEV_ENABLE_STATS 1\n#endif\n\n/**@brief   Cache size of block device.*/\n#ifndef CONFIG_BLOCK_DEV_CACHE_SIZE\n#define CONFIG_BLOCK_DEV_CACHE_SIZE 8\n#endif\n\n\n/**@brief   Maximum block device name*/\n#ifndef CONFIG_EXT4_MAX_BLOCKDEV_NAME\n#define CONFIG_EXT4_MAX_BLOCKDEV_NAME 32\n#endif\n\n\n/**@brief   Maximum block device count*/\n#ifndef CONFIG_EXT4_BLOCKDEVS_COUNT\n#define CONFIG_EXT4_BLOCKDEVS_COUNT 2\n#endif\n\n/**@brief   Maximum mountpoint name*/\n#ifndef CONFIG_EXT4_MAX_MP_NAME\n#define CONFIG_EXT4_MAX_MP_NAME 32\n#endif\n\n/**@brief   Maximum mountpoint count*/\n#ifndef CONFIG_EXT4_MOUNTPOINTS_COUNT\n#define CONFIG_EXT4_MOUNTPOINTS_COUNT 2\n#endif\n\n/**@brief   Include open flags from ext4_errno or standard library.*/\n#ifndef CONFIG_HAVE_OWN_OFLAGS\n#define CONFIG_HAVE_OWN_OFLAGS 1\n#endif\n\n/**@brief Maximum single truncate size. Transactions must be limited to reduce\n *        number of allocetions for single transaction*/\n#ifndef CONFIG_MAX_TRUNCATE_SIZE\n#define CONFIG_MAX_TRUNCATE_SIZE (16ul * 1024ul * 1024ul)\n#endif\n\n\n/**@brief Unaligned access switch on/off*/\n#ifndef CONFIG_UNALIGNED_ACCESS\n#define CONFIG_UNALIGNED_ACCESS 0\n#endif\n\n/**@brief Switches use of malloc/free functions family\n *        from standard library to user provided*/\n#ifndef CONFIG_USE_USER_MALLOC\n#define CONFIG_USE_USER_MALLOC 0\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EXT4_CONFIG_H_ */\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_crc32.h",
    "content": "/*\n * Copyright (c) 2014 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * All rights reserved.\n *\n * Based on FreeBSD.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_crc32.h\n * @brief Crc32c routine. Taken from FreeBSD kernel.\n */\n\n#ifndef LWEXT4_EXT4_CRC32C_H_\n#define LWEXT4_EXT4_CRC32C_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <ext4_config.h>\n\n#include <stdint.h>\n\n/**@brief   CRC32 algorithm.\n * @param   crc input feed\n * @param   buf input buffer\n * @param   size input buffer length (bytes)\n * @return  updated crc32 value*/\nuint32_t ext4_crc32(uint32_t crc, const void *buf, uint32_t size);\n\n/**@brief   CRC32C algorithm.\n * @param   crc input feed\n * @param   buf input buffer\n * @param   length input buffer length (bytes)\n * @return  updated crc32c value*/\nuint32_t ext4_crc32c(uint32_t crc, const void *buf, uint32_t size);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* LWEXT4_EXT4_CRC32C_H_ */\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_debug.h",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_debug.c\n * @brief Debug printf and assert macros.\n */\n\n#ifndef EXT4_DEBUG_H_\n#define EXT4_DEBUG_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <ext4_config.h>\n#include <ext4_errno.h>\n\n#if !CONFIG_HAVE_OWN_ASSERT\n#include <assert.h>\n#endif\n\n#include <stdint.h>\n#include <inttypes.h>\n\n#ifndef PRIu64\n#define PRIu64 \"llu\"\n#endif\n\n#ifndef PRId64\n#define PRId64 \"lld\"\n#endif\n\n\n#define DEBUG_BALLOC (1ul << 0)\n#define DEBUG_BCACHE (1ul << 1)\n#define DEBUG_BITMAP (1ul << 2)\n#define DEBUG_BLOCK_GROUP (1ul << 3)\n#define DEBUG_BLOCKDEV (1ul << 4)\n#define DEBUG_DIR_IDX (1ul << 5)\n#define DEBUG_DIR (1ul << 6)\n#define DEBUG_EXTENT (1ul << 7)\n#define DEBUG_FS (1ul << 8)\n#define DEBUG_HASH (1ul << 9)\n#define DEBUG_IALLOC (1ul << 10)\n#define DEBUG_INODE (1ul << 11)\n#define DEBUG_SUPER (1ul << 12)\n#define DEBUG_XATTR (1ul << 13)\n#define DEBUG_MKFS (1ul << 14)\n#define DEBUG_EXT4 (1ul << 15)\n#define DEBUG_JBD (1ul << 16)\n#define DEBUG_MBR (1ul << 17)\n\n#define DEBUG_NOPREFIX (1ul << 31)\n#define DEBUG_ALL (0xFFFFFFFF)\n\nstatic inline const char *ext4_dmask_id2str(uint32_t m)\n{\n    switch(m) {\n    case DEBUG_BALLOC:\n        return \"ext4_balloc: \";\n    case DEBUG_BCACHE:\n        return \"ext4_bcache: \";\n    case DEBUG_BITMAP:\n        return \"ext4_bitmap: \";\n    case DEBUG_BLOCK_GROUP:\n        return \"ext4_block_group: \";\n    case DEBUG_BLOCKDEV:\n        return \"ext4_blockdev: \";\n    case DEBUG_DIR_IDX:\n        return \"ext4_dir_idx: \";\n    case DEBUG_DIR:\n        return \"ext4_dir: \";\n    case DEBUG_EXTENT:\n        return \"ext4_extent: \";\n    case DEBUG_FS:\n        return \"ext4_fs: \";\n    case DEBUG_HASH:\n        return \"ext4_hash: \";\n    case DEBUG_IALLOC:\n        return \"ext4_ialloc: \";\n    case DEBUG_INODE:\n        return \"ext4_inode: \";\n    case DEBUG_SUPER:\n        return \"ext4_super: \";\n    case DEBUG_XATTR:\n        return \"ext4_xattr: \";\n    case DEBUG_MKFS:\n        return \"ext4_mkfs: \";\n    case DEBUG_JBD:\n        return \"ext4_jbd: \";\n    case DEBUG_MBR:\n        return \"ext4_mbr: \";\n    case DEBUG_EXT4:\n        return \"ext4: \";\n    }\n    return \"\";\n}\n#define DBG_NONE  \"\"\n#define DBG_INFO  \"[info]  \"\n#define DBG_WARN  \"[warn]  \"\n#define DBG_ERROR \"[error] \"\n\n/**@brief   Global mask debug set.\n * @brief   m new debug mask.*/\nvoid ext4_dmask_set(uint32_t m);\n\n/**@brief   Global mask debug clear.\n * @brief   m new debug mask.*/\nvoid ext4_dmask_clr(uint32_t m);\n\n/**@brief   Global debug mask get.\n * @return  debug mask*/\nuint32_t ext4_dmask_get(void);\n\n#if CONFIG_DEBUG_PRINTF\n#include <stdio.h>\n\n/**@brief   Debug printf.*/\n#define ext4_dbg(m, ...)                                                       \\\n    do {                                                                   \\\n        if ((m) & ext4_dmask_get()) {                                  \\\n            if (!((m) & DEBUG_NOPREFIX)) {                         \\\n                printf(\"%s\", ext4_dmask_id2str(m));            \\\n                printf(\"l: %d   \", __LINE__);                  \\\n            }                                                      \\\n            printf(__VA_ARGS__);                                   \\\n/*fflush(stdout);*/ \\\n        }                                                              \\\n    } while (0)\n#else\n#define ext4_dbg(m, ...) do { } while (0)\n#endif\n\n#if CONFIG_DEBUG_ASSERT\n/**@brief   Debug assertion.*/\n#if CONFIG_HAVE_OWN_ASSERT\n#include <stdio.h>\n\n#define ext4_assert(_v)                                                        \\\n    do {                                                                   \\\n        if (!(_v)) {                                                   \\\n            printf(\"assertion failed:\\nfile: %s\\nline: %d\\n\",      \\\n                   __FILE__, __LINE__);                            \\\n                   while (1)                       \\\n                       ;                       \\\n        }                                                              \\\n    } while (0)\n#else\n#define ext4_assert(_v) assert(_v)\n#endif\n#else\n#define ext4_assert(_v) ((void)(_v))\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EXT4_DEBUG_H_ */\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_dir.h",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n *\n *\n * HelenOS:\n * Copyright (c) 2012 Martin Sucha\n * Copyright (c) 2012 Frantisek Princ\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_dir.h\n * @brief Directory handle procedures.\n */\n\n#ifndef EXT4_DIR_H_\n#define EXT4_DIR_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_misc.h>\n#include <ext4_blockdev.h>\n#include <ext4_super.h>\n\n#include <stdint.h>\n\nstruct ext4_dir_iter {\n    struct ext4_inode_ref *inode_ref;\n    struct ext4_block curr_blk;\n    uint64_t curr_off;\n    struct ext4_dir_en *curr;\n};\n\nstruct ext4_dir_search_result {\n    struct ext4_block block;\n    struct ext4_dir_en *dentry;\n};\n\n\n/**@brief Get i-node number from directory entry.\n * @param de Directory entry\n * @return I-node number\n */\nstatic inline uint32_t\next4_dir_en_get_inode(struct ext4_dir_en *de)\n{\n    return to_le32(de->inode);\n}\n\n/**@brief Set i-node number to directory entry.\n * @param de Directory entry\n * @param inode I-node number\n */\nstatic inline void\next4_dir_en_set_inode(struct ext4_dir_en *de, uint32_t inode)\n{\n    de->inode = to_le32(inode);\n}\n\n/**@brief Set i-node number to directory entry. (For HTree root)\n * @param de Directory entry\n * @param inode I-node number\n */\nstatic inline void\next4_dx_dot_en_set_inode(struct ext4_dir_idx_dot_en *de, uint32_t inode)\n{\n    de->inode = to_le32(inode);\n}\n\n/**@brief Get directory entry length.\n * @param de Directory entry\n * @return Entry length\n */\nstatic inline uint16_t ext4_dir_en_get_entry_len(struct ext4_dir_en *de)\n{\n    return to_le16(de->entry_len);\n}\n\n/**@brief Set directory entry length.\n * @param de     Directory entry\n * @param length Entry length\n */\nstatic inline void ext4_dir_en_set_entry_len(struct ext4_dir_en *de, uint16_t l)\n{\n    de->entry_len = to_le16(l);\n}\n\n/**@brief Get directory entry name length.\n * @param sb Superblock\n * @param de Directory entry\n * @return Entry name length\n */\nstatic inline uint16_t ext4_dir_en_get_name_len(struct ext4_sblock *sb,\n                        struct ext4_dir_en *de)\n{\n    uint16_t v = de->name_len;\n\n    if ((ext4_get32(sb, rev_level) == 0) &&\n        (ext4_get32(sb, minor_rev_level) < 5))\n        v |= ((uint16_t)de->in.name_length_high) << 8;\n\n    return v;\n}\n\n/**@brief Set directory entry name length.\n * @param sb     Superblock\n * @param de     Directory entry\n * @param length Entry name length\n */\nstatic inline void ext4_dir_en_set_name_len(struct ext4_sblock *sb,\n                        struct ext4_dir_en *de,\n                        uint16_t len)\n{\n    de->name_len = (len << 8) >> 8;\n\n    if ((ext4_get32(sb, rev_level) == 0) &&\n        (ext4_get32(sb, minor_rev_level) < 5))\n        de->in.name_length_high = len >> 8;\n}\n\n/**@brief Get i-node type of directory entry.\n * @param sb Superblock\n * @param de Directory entry\n * @return I-node type (file, dir, etc.)\n */\nstatic inline uint8_t ext4_dir_en_get_inode_type(struct ext4_sblock *sb,\n                         struct ext4_dir_en *de)\n{\n    if ((ext4_get32(sb, rev_level) > 0) ||\n        (ext4_get32(sb, minor_rev_level) >= 5))\n        return de->in.inode_type;\n\n    return EXT4_DE_UNKNOWN;\n}\n/**@brief Set i-node type of directory entry.\n * @param sb   Superblock\n * @param de   Directory entry\n * @param type I-node type (file, dir, etc.)\n */\n\nstatic inline void ext4_dir_en_set_inode_type(struct ext4_sblock *sb,\n                          struct ext4_dir_en *de, uint8_t t)\n{\n    if ((ext4_get32(sb, rev_level) > 0) ||\n        (ext4_get32(sb, minor_rev_level) >= 5))\n        de->in.inode_type = t;\n}\n\n/**@brief Verify checksum of a linear directory leaf block\n * @param inode_ref Directory i-node\n * @param dirent    Linear directory leaf block\n * @return true means the block passed checksum verification\n */\nbool ext4_dir_csum_verify(struct ext4_inode_ref *inode_ref,\n              struct ext4_dir_en *dirent);\n\n/**@brief Initialize directory iterator.\n * Set position to the first valid entry from the required position.\n * @param it        Pointer to iterator to be initialized\n * @param inode_ref Directory i-node\n * @param pos       Position to start reading entries from\n * @return Error code\n */\nint ext4_dir_iterator_init(struct ext4_dir_iter *it,\n               struct ext4_inode_ref *inode_ref, uint64_t pos);\n\n/**@brief Jump to the next valid entry\n * @param it Initialized iterator\n * @return Error code\n */\nint ext4_dir_iterator_next(struct ext4_dir_iter *it);\n\n/**@brief Uninitialize directory iterator.\n *        Release all allocated structures.\n * @param it Iterator to be finished\n * @return Error code\n */\nint ext4_dir_iterator_fini(struct ext4_dir_iter *it);\n\n/**@brief Write directory entry to concrete data block.\n * @param sb        Superblock\n * @param en     Pointer to entry to be written\n * @param entry_len Length of new entry\n * @param child     Child i-node to be written to new entry\n * @param name      Name of the new entry\n * @param name_len  Length of entry name\n */\nvoid ext4_dir_write_entry(struct ext4_sblock *sb, struct ext4_dir_en *en,\n              uint16_t entry_len, struct ext4_inode_ref *child,\n              const char *name, size_t name_len);\n\n/**@brief Add new entry to the directory.\n * @param parent Directory i-node\n * @param name   Name of new entry\n * @param child  I-node to be referenced from new entry\n * @return Error code\n */\nint ext4_dir_add_entry(struct ext4_inode_ref *parent, const char *name,\n               uint32_t name_len, struct ext4_inode_ref *child);\n\n/**@brief Find directory entry with passed name.\n * @param result Result structure to be returned if entry found\n * @param parent Directory i-node\n * @param name   Name of entry to be found\n * @param name_len  Name length\n * @return Error code\n */\nint ext4_dir_find_entry(struct ext4_dir_search_result *result,\n            struct ext4_inode_ref *parent, const char *name,\n            uint32_t name_len);\n\n/**@brief Remove directory entry.\n * @param parent Directory i-node\n * @param name   Name of the entry to be removed\n * @param name_len  Name length\n * @return Error code\n */\nint ext4_dir_remove_entry(struct ext4_inode_ref *parent, const char *name,\n              uint32_t name_len);\n\n/**@brief Try to insert entry to concrete data block.\n * @param sb           Superblock\n * @param inode_ref    Directory i-node\n * @param dst_blk      Block to try to insert entry to\n * @param child        Child i-node to be inserted by new entry\n * @param name         Name of the new entry\n * @param name_len     Length of the new entry name\n * @return Error code\n */\nint ext4_dir_try_insert_entry(struct ext4_sblock *sb,\n                  struct ext4_inode_ref *inode_ref,\n                  struct ext4_block *dst_blk,\n                  struct ext4_inode_ref *child, const char *name,\n                  uint32_t name_len);\n\n/**@brief Try to find entry in block by name.\n * @param block     Block containing entries\n * @param sb        Superblock\n * @param name_len  Length of entry name\n * @param name      Name of entry to be found\n * @param res_entry Output pointer to found entry, NULL if not found\n * @return Error code\n */\nint ext4_dir_find_in_block(struct ext4_block *block, struct ext4_sblock *sb,\n               size_t name_len, const char *name,\n               struct ext4_dir_en **res_entry);\n\n/**@brief Simple function to release allocated data from result.\n * @param parent Parent inode\n * @param result Search result to destroy\n * @return Error code\n *\n */\nint ext4_dir_destroy_result(struct ext4_inode_ref *parent,\n                struct ext4_dir_search_result *result);\n\nvoid ext4_dir_set_csum(struct ext4_inode_ref *inode_ref,\n               struct ext4_dir_en *dirent);\n\n\nvoid ext4_dir_init_entry_tail(struct ext4_dir_entry_tail *t);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EXT4_DIR_H_ */\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_dir_idx.h",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n *\n *\n * HelenOS:\n * Copyright (c) 2012 Martin Sucha\n * Copyright (c) 2012 Frantisek Princ\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_dir_idx.h\n * @brief Directory indexing procedures.\n */\n\n#ifndef EXT4_DIR_IDX_H_\n#define EXT4_DIR_IDX_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n\n#include <ext4_fs.h>\n#include <ext4_dir.h>\n\n#include <stdint.h>\n#include <stdbool.h>\n\nstruct ext4_dir_idx_block {\n    struct ext4_block b;\n    struct ext4_dir_idx_entry *entries;\n    struct ext4_dir_idx_entry *position;\n};\n\n#define EXT4_DIR_DX_INIT_BCNT 2\n\n\n/**@brief Initialize index structure of new directory.\n * @param dir Pointer to directory i-node\n * @param dir Pointer to parent directory i-node\n * @return Error code\n */\nint ext4_dir_dx_init(struct ext4_inode_ref *dir,\n             struct ext4_inode_ref *parent);\n\n/**@brief Try to find directory entry using directory index.\n * @param result    Output value - if entry will be found,\n *                  than will be passed through this parameter\n * @param inode_ref Directory i-node\n * @param name_len  Length of name to be found\n * @param name      Name to be found\n * @return Error code\n */\nint ext4_dir_dx_find_entry(struct ext4_dir_search_result *result,\n               struct ext4_inode_ref *inode_ref, size_t name_len,\n               const char *name);\n\n/**@brief Add new entry to indexed directory\n * @param parent Directory i-node\n * @param child  I-node to be referenced from directory entry\n * @param name   Name of new directory entry\n * @return Error code\n */\nint ext4_dir_dx_add_entry(struct ext4_inode_ref *parent,\n              struct ext4_inode_ref *child, const char *name, uint32_t name_len);\n\n/**@brief Add new entry to indexed directory\n * @param dir           Directory i-node\n * @param parent_inode  parent inode index\n * @return Error code\n */\nint ext4_dir_dx_reset_parent_inode(struct ext4_inode_ref *dir,\n                                   uint32_t parent_inode);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EXT4_DIR_IDX_H_ */\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_errno.h",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_errno.h\n * @brief Error codes.\n */\n#ifndef EXT4_ERRNO_H_\n#define EXT4_ERRNO_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <ext4_config.h>\n\n#if !CONFIG_HAVE_OWN_ERRNO\n#include <errno.h>\n#else\n#define EPERM 1      /* Operation not permitted */\n#define ENOENT 2     /* No such file or directory */\n#define EIO 5        /* I/O error */\n#define ENXIO 6      /* No such device or address */\n#define E2BIG 7      /* Argument list too long */\n#define ENOMEM 12    /* Out of memory */\n#define EACCES 13    /* Permission denied */\n#define EFAULT 14    /* Bad address */\n#define EEXIST 17    /* File exists */\n#define ENODEV 19    /* No such device */\n#define ENOTDIR 20   /* Not a directory */\n#define EISDIR 21    /* Is a directory */\n#define EINVAL 22    /* Invalid argument */\n#define EFBIG 27     /* File too large */\n#define ENOSPC 28    /* No space left on device */\n#define EROFS 30     /* Read-only file system */\n#define EMLINK 31    /* Too many links */\n#define ERANGE 34    /* Math result not representable */\n#define ENOTEMPTY 39 /* Directory not empty */\n#define ENODATA 61   /* No data available */\n#define ENOTSUP 95   /* Not supported */\n#endif\n\n#ifndef ENODATA\n #ifdef ENOATTR\n #define ENODATA ENOATTR\n #else\n #define ENODATA 61\n #endif\n#endif\n\n#ifndef ENOTSUP\n#define ENOTSUP 95\n#endif\n\n#ifndef EOK\n#define EOK 0\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EXT4_ERRNO_H_ */\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_extent.h",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n *\n * HelenOS:\n * Copyright (c) 2012 Martin Sucha\n * Copyright (c) 2012 Frantisek Princ\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_extent.h\n * @brief More complex filesystem functions.\n */\n#ifndef EXT4_EXTENT_H_\n#define EXT4_EXTENT_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_inode.h>\n\nvoid ext4_extent_tree_init(struct ext4_inode_ref *inode_ref);\n\n\nint ext4_extent_get_blocks(struct ext4_inode_ref *inode_ref, ext4_lblk_t iblock,\n               uint32_t max_blocks, ext4_fsblk_t *result, bool create,\n               uint32_t *blocks_count);\n\n\n/**@brief Release all data blocks starting from specified logical block.\n * @param inode_ref   I-node to release blocks from\n * @param iblock_from First logical block to release\n * @return Error code */\nint ext4_extent_remove_space(struct ext4_inode_ref *inode_ref, ext4_lblk_t from,\n                 ext4_lblk_t to);\n\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EXT4_EXTENT_H_ */\n/**\n* @}\n*/\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_fs.h",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n *\n *\n * HelenOS:\n * Copyright (c) 2012 Martin Sucha\n * Copyright (c) 2012 Frantisek Princ\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_fs.c\n * @brief More complex filesystem functions.\n */\n\n#ifndef EXT4_FS_H_\n#define EXT4_FS_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_misc.h>\n\n#include <stdint.h>\n#include <stdbool.h>\n\nstruct ext4_fs {\n    bool read_only;\n\n    struct ext4_blockdev *bdev;\n    struct ext4_sblock sb;\n\n    uint64_t inode_block_limits[4];\n    uint64_t inode_blocks_per_level[4];\n\n    uint32_t last_inode_bg_id;\n\n    struct jbd_fs *jbd_fs;\n    struct jbd_journal *jbd_journal;\n    struct jbd_trans *curr_trans;\n};\n\nstruct ext4_block_group_ref {\n    struct ext4_block block;\n    struct ext4_bgroup *block_group;\n    struct ext4_fs *fs;\n    uint32_t index;\n    bool dirty;\n};\n\nstruct ext4_inode_ref {\n    struct ext4_block block;\n    struct ext4_inode *inode;\n    struct ext4_fs *fs;\n    uint32_t index;\n    bool dirty;\n};\n\n\n/**@brief Convert block address to relative index in block group.\n * @param sb Superblock pointer\n * @param baddr Block number to convert\n * @return Relative number of block\n */\nstatic inline uint32_t ext4_fs_addr_to_idx_bg(struct ext4_sblock *s,\n                             ext4_fsblk_t baddr)\n{\n    if (ext4_get32(s, first_data_block) && baddr)\n        baddr--;\n\n    return baddr % ext4_get32(s, blocks_per_group);\n}\n\n/**@brief Convert relative block address in group to absolute address.\n * @param s Superblock pointer\n * @param index Relative block address\n * @param bgid Block group\n * @return Absolute block address\n */\nstatic inline ext4_fsblk_t ext4_fs_bg_idx_to_addr(struct ext4_sblock *s,\n                             uint32_t index,\n                             uint32_t bgid)\n{\n    if (ext4_get32(s, first_data_block))\n        index++;\n\n    return ext4_get32(s, blocks_per_group) * bgid + index;\n}\n\n/**@brief TODO: */\nstatic inline ext4_fsblk_t ext4_fs_first_bg_block_no(struct ext4_sblock *s,\n                         uint32_t bgid)\n{\n    return (uint64_t)bgid * ext4_get32(s, blocks_per_group) +\n           ext4_get32(s, first_data_block);\n}\n\n/**@brief Initialize filesystem and read all needed data.\n * @param fs Filesystem instance to be initialized\n * @param bdev Identifier if device with the filesystem\n * @param read_only Mark the filesystem as read-only.\n * @return Error code\n */\nint ext4_fs_init(struct ext4_fs *fs, struct ext4_blockdev *bdev,\n         bool read_only);\n\n/**@brief Destroy filesystem instance (used by unmount operation).\n * @param fs Filesystem to be destroyed\n * @return Error code\n */\nint ext4_fs_fini(struct ext4_fs *fs);\n\n/**@brief Check filesystem's features, if supported by this driver\n * Function can return EOK and set read_only flag. It mean's that\n * there are some not-supported features, that can cause problems\n * during some write operations.\n * @param fs        Filesystem to be checked\n * @param read_only Flag if filesystem should be mounted only for reading\n * @return Error code\n */\nint ext4_fs_check_features(struct ext4_fs *fs, bool *read_only);\n\n/**@brief Get reference to block group specified by index.\n * @param fs   Filesystem to find block group on\n * @param bgid Index of block group to load\n * @param ref  Output pointer for reference\n * @return Error code\n */\nint ext4_fs_get_block_group_ref(struct ext4_fs *fs, uint32_t bgid,\n                struct ext4_block_group_ref *ref);\n\n/**@brief Put reference to block group.\n * @param ref Pointer for reference to be put back\n * @return Error code\n */\nint ext4_fs_put_block_group_ref(struct ext4_block_group_ref *ref);\n\n/**@brief Get reference to i-node specified by index.\n * @param fs    Filesystem to find i-node on\n * @param index Index of i-node to load\n * @param ref   Output pointer for reference\n * @return Error code\n */\nint ext4_fs_get_inode_ref(struct ext4_fs *fs, uint32_t index,\n              struct ext4_inode_ref *ref);\n\n/**@brief Reset blocks field of i-node.\n * @param fs        Filesystem to reset blocks field of i-inode on\n * @param inode_ref ref Pointer for inode to be operated on\n */\nvoid ext4_fs_inode_blocks_init(struct ext4_fs *fs,\n                   struct ext4_inode_ref *inode_ref);\n\n/**@brief Put reference to i-node.\n * @param ref Pointer for reference to be put back\n * @return Error code\n */\nint ext4_fs_put_inode_ref(struct ext4_inode_ref *ref);\n\n/**@brief Convert filetype to inode mode.\n * @param filetype\n * @return inode mode\n */\nuint32_t ext4_fs_correspond_inode_mode(int filetype);\n\n/**@brief Allocate new i-node in the filesystem.\n * @param fs        Filesystem to allocated i-node on\n * @param inode_ref Output pointer to return reference to allocated i-node\n * @param filetype  File type of newly created i-node\n * @return Error code\n */\nint ext4_fs_alloc_inode(struct ext4_fs *fs, struct ext4_inode_ref *inode_ref,\n            int filetype);\n\n/**@brief Release i-node and mark it as free.\n * @param inode_ref I-node to be released\n * @return Error code\n */\nint ext4_fs_free_inode(struct ext4_inode_ref *inode_ref);\n\n/**@brief Truncate i-node data blocks.\n * @param inode_ref I-node to be truncated\n * @param new_size  New size of inode (must be < current size)\n * @return Error code\n */\nint ext4_fs_truncate_inode(struct ext4_inode_ref *inode_ref, uint64_t new_size);\n\n/**@brief Compute 'goal' for inode index\n * @param inode_ref Reference to inode, to allocate block for\n * @return goal\n */\next4_fsblk_t ext4_fs_inode_to_goal_block(struct ext4_inode_ref *inode_ref);\n\n/**@brief Compute 'goal' for allocation algorithm (For blockmap).\n * @param inode_ref Reference to inode, to allocate block for\n * @param goal\n * @return error code\n */\nint ext4_fs_indirect_find_goal(struct ext4_inode_ref *inode_ref,\n                ext4_fsblk_t *goal);\n\n/**@brief Get physical block address by logical index of the block.\n * @param inode_ref I-node to read block address from\n * @param iblock            Logical index of block\n * @param fblock            Output pointer for return physical\n *                          block address\n * @param support_unwritten Indicate whether unwritten block range\n *                          is supported under the current context\n * @return Error code\n */\nint ext4_fs_get_inode_dblk_idx(struct ext4_inode_ref *inode_ref,\n                 ext4_lblk_t iblock, ext4_fsblk_t *fblock,\n                 bool support_unwritten);\n\n/**@brief Initialize a part of unwritten range of the inode.\n * @param inode_ref I-node to proceed on.\n * @param iblock    Logical index of block\n * @param fblock    Output pointer for return physical block address\n * @return Error code\n */\nint ext4_fs_init_inode_dblk_idx(struct ext4_inode_ref *inode_ref,\n                  ext4_lblk_t iblock, ext4_fsblk_t *fblock);\n\n/**@brief Append following logical block to the i-node.\n * @param inode_ref I-node to append block to\n * @param fblock    Output physical block address of newly allocated block\n * @param iblock    Output logical number of newly allocated block\n * @return Error code\n */\nint ext4_fs_append_inode_dblk(struct ext4_inode_ref *inode_ref,\n                  ext4_fsblk_t *fblock, ext4_lblk_t *iblock);\n\n/**@brief   Increment inode link count.\n * @param   inode none handle\n */\nvoid ext4_fs_inode_links_count_inc(struct ext4_inode_ref *inode_ref);\n\n/**@brief   Decrement inode link count.\n * @param   inode none handle\n */\nvoid ext4_fs_inode_links_count_dec(struct ext4_inode_ref *inode_ref);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EXT4_FS_H_ */\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_hash.h",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_hash.h\n * @brief Directory indexing hash functions.\n */\n\n#ifndef EXT4_HASH_H_\n#define EXT4_HASH_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <ext4_config.h>\n\n#include <stdint.h>\n\nstruct ext4_hash_info {\n    uint32_t hash;\n    uint32_t minor_hash;\n    uint32_t hash_version;\n    const uint32_t *seed;\n};\n\n\n/**@brief   Directory entry name hash function.\n * @param   name entry name\n * @param   len entry name length\n * @param   hash_seed (from superblock)\n * @param   hash version (from superblock)\n * @param   hash_minor output value\n * @param   hash_major output value\n * @return  standard error code*/\nint ext2_htree_hash(const char *name, int len, const uint32_t *hash_seed,\n            int hash_version, uint32_t *hash_major,\n            uint32_t *hash_minor);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EXT4_HASH_H_ */\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_ialloc.h",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n *\n *\n * HelenOS:\n * Copyright (c) 2012 Martin Sucha\n * Copyright (c) 2012 Frantisek Princ\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_ialloc.c\n * @brief Inode allocation procedures.\n */\n\n#ifndef EXT4_IALLOC_H_\n#define EXT4_IALLOC_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n\n/**@brief Calculate and set checksum of inode bitmap.\n * @param sb superblock pointer.\n * @param bg block group\n * @param bitmap bitmap buffer\n */\nvoid ext4_ialloc_set_bitmap_csum(struct ext4_sblock *sb, struct ext4_bgroup *bg,\n                 void *bitmap);\n\n/**@brief Free i-node number and modify filesystem data structers.\n * @param fs     Filesystem, where the i-node is located\n * @param index  Index of i-node to be release\n * @param is_dir Flag us for information whether i-node is directory or not\n */\nint ext4_ialloc_free_inode(struct ext4_fs *fs, uint32_t index, bool is_dir);\n\n/**@brief I-node allocation algorithm.\n * This is more simple algorithm, than Orlov allocator used\n * in the Linux kernel.\n * @param fs     Filesystem to allocate i-node on\n * @param index  Output value - allocated i-node number\n * @param is_dir Flag if allocated i-node will be file or directory\n * @return Error code\n */\nint ext4_ialloc_alloc_inode(struct ext4_fs *fs, uint32_t *index, bool is_dir);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EXT4_IALLOC_H_ */\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_inode.h",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n *\n *\n * HelenOS:\n * Copyright (c) 2012 Martin Sucha\n * Copyright (c) 2012 Frantisek Princ\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_inode.h\n * @brief Inode handle functions\n */\n\n#ifndef EXT4_INODE_H_\n#define EXT4_INODE_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n\n#include <stdint.h>\n\n/**@brief Get mode of the i-node.\n * @param sb    Superblock\n * @param inode I-node to load mode from\n * @return Mode of the i-node\n */\nuint32_t ext4_inode_get_mode(struct ext4_sblock *sb, struct ext4_inode *inode);\n\n/**@brief Set mode of the i-node.\n * @param sb    Superblock\n * @param inode I-node to set mode to\n * @param mode  Mode to set to i-node\n */\nvoid ext4_inode_set_mode(struct ext4_sblock *sb, struct ext4_inode *inode,\n             uint32_t mode);\n\n/**@brief Get ID of the i-node owner (user id).\n * @param inode I-node to load uid from\n * @return User ID of the i-node owner\n */\nuint32_t ext4_inode_get_uid(struct ext4_inode *inode);\n\n/**@brief Set ID of the i-node owner.\n * @param inode I-node to set uid to\n * @param uid   ID of the i-node owner\n */\nvoid ext4_inode_set_uid(struct ext4_inode *inode, uint32_t uid);\n\n/**@brief Get real i-node size.\n * @param sb    Superblock\n * @param inode I-node to load size from\n * @return Real size of i-node\n */\nuint64_t ext4_inode_get_size(struct ext4_sblock *sb, struct ext4_inode *inode);\n\n/**@brief Set real i-node size.\n * @param inode I-node to set size to\n * @param size  Size of the i-node\n */\nvoid ext4_inode_set_size(struct ext4_inode *inode, uint64_t size);\n\n/**@brief Get time, when i-node was last accessed.\n * @param inode I-node\n * @return Time of the last access (POSIX)\n */\nuint32_t ext4_inode_get_access_time(struct ext4_inode *inode);\n\n/**@brief Set time, when i-node was last accessed.\n * @param inode I-node\n * @param time  Time of the last access (POSIX)\n */\nvoid ext4_inode_set_access_time(struct ext4_inode *inode, uint32_t time);\n\n/**@brief Get time, when i-node was last changed.\n * @param inode I-node\n * @return Time of the last change (POSIX)\n */\nuint32_t ext4_inode_get_change_inode_time(struct ext4_inode *inode);\n\n/**@brief Set time, when i-node was last changed.\n * @param inode I-node\n * @param time  Time of the last change (POSIX)\n */\nvoid ext4_inode_set_change_inode_time(struct ext4_inode *inode, uint32_t time);\n\n/**@brief Get time, when i-node content was last modified.\n * @param inode I-node\n * @return Time of the last content modification (POSIX)\n */\nuint32_t ext4_inode_get_modif_time(struct ext4_inode *inode);\n\n/**@brief Set time, when i-node content was last modified.\n * @param inode I-node\n * @param time  Time of the last content modification (POSIX)\n */\nvoid ext4_inode_set_modif_time(struct ext4_inode *inode, uint32_t time);\n\n/**@brief Get time, when i-node was deleted.\n * @param inode I-node\n * @return Time of the delete action (POSIX)\n */\nuint32_t ext4_inode_get_del_time(struct ext4_inode *inode);\n\n/**@brief Set time, when i-node was deleted.\n * @param inode I-node\n * @param time  Time of the delete action (POSIX)\n */\nvoid ext4_inode_set_del_time(struct ext4_inode *inode, uint32_t time);\n\n/**@brief Get ID of the i-node owner's group.\n * @param inode I-node to load gid from\n * @return Group ID of the i-node owner\n */\nuint32_t ext4_inode_get_gid(struct ext4_inode *inode);\n\n/**@brief Set ID to the i-node owner's group.\n * @param inode I-node to set gid to\n * @param gid   Group ID of the i-node owner\n */\nvoid ext4_inode_set_gid(struct ext4_inode *inode, uint32_t gid);\n\n/**@brief Get number of links to i-node.\n * @param inode I-node to load number of links from\n * @return Number of links to i-node\n */\nuint16_t ext4_inode_get_links_cnt(struct ext4_inode *inode);\n\n/**@brief Set number of links to i-node.\n * @param inode I-node to set number of links to\n * @param count Number of links to i-node\n */\nvoid ext4_inode_set_links_cnt(struct ext4_inode *inode, uint16_t cnt);\n\n/**@brief Get number of 512-bytes blocks used for i-node.\n * @param sb    Superblock\n * @param inode I-node\n * @return Number of 512-bytes blocks\n */\nuint64_t ext4_inode_get_blocks_count(struct ext4_sblock *sb,\n                     struct ext4_inode *inode);\n\n/**@brief Set number of 512-bytes blocks used for i-node.\n * @param sb    Superblock\n * @param inode I-node\n * @param count Number of 512-bytes blocks\n * @return Error code\n */\nint ext4_inode_set_blocks_count(struct ext4_sblock *sb,\n                struct ext4_inode *inode, uint64_t cnt);\n\n/**@brief Get flags (features) of i-node.\n * @param inode I-node to get flags from\n * @return Flags (bitmap)\n */\nuint32_t ext4_inode_get_flags(struct ext4_inode *inode);\n\n/**@brief Set flags (features) of i-node.\n * @param inode I-node to set flags to\n * @param flags Flags to set to i-node\n */\nvoid ext4_inode_set_flags(struct ext4_inode *inode, uint32_t flags);\n\n/**@brief Get file generation (used by NFS).\n * @param inode I-node\n * @return File generation\n */\nuint32_t ext4_inode_get_generation(struct ext4_inode *inode);\n\n/**@brief Set file generation (used by NFS).\n * @param inode      I-node\n * @param generation File generation\n */\nvoid ext4_inode_set_generation(struct ext4_inode *inode, uint32_t gen);\n\n/**@brief Get extra I-node size field.\n * @param sb         Superblock\n * @param inode      I-node\n * @return extra I-node size\n */\nuint16_t ext4_inode_get_extra_isize(struct ext4_sblock *sb,\n                    struct ext4_inode *inode);\n\n/**@brief Set extra I-node size field.\n * @param sb         Superblock\n * @param inode      I-node\n * @param size       extra I-node size\n */\nvoid ext4_inode_set_extra_isize(struct ext4_sblock *sb,\n                struct ext4_inode *inode,\n                uint16_t size);\n\n/**@brief Get address of block, where are extended attributes located.\n * @param inode I-node\n * @param sb    Superblock\n * @return Block address\n */\nuint64_t ext4_inode_get_file_acl(struct ext4_inode *inode,\n                 struct ext4_sblock *sb);\n\n/**@brief Set address of block, where are extended attributes located.\n * @param inode    I-node\n * @param sb       Superblock\n * @param file_acl Block address\n */\nvoid ext4_inode_set_file_acl(struct ext4_inode *inode, struct ext4_sblock *sb,\n                 uint64_t acl);\n\n/**@brief Get block address of specified direct block.\n * @param inode I-node to load block from\n * @param idx   Index of logical block\n * @return Physical block address\n */\nuint32_t ext4_inode_get_direct_block(struct ext4_inode *inode, uint32_t idx);\n\n/**@brief Set block address of specified direct block.\n * @param inode  I-node to set block address to\n * @param idx    Index of logical block\n * @param fblock Physical block address\n */\nvoid ext4_inode_set_direct_block(struct ext4_inode *inode, uint32_t idx,\n                 uint32_t block);\n\n/**@brief Get block address of specified indirect block.\n * @param inode I-node to get block address from\n * @param idx   Index of indirect block\n * @return Physical block address\n */\nuint32_t ext4_inode_get_indirect_block(struct ext4_inode *inode, uint32_t idx);\n\n/**@brief Set block address of specified indirect block.\n * @param inode  I-node to set block address to\n * @param idx    Index of indirect block\n * @param fblock Physical block address\n */\nvoid ext4_inode_set_indirect_block(struct ext4_inode *inode, uint32_t idx,\n                   uint32_t block);\n\n/**@brief Get device number\n * @param inode  I-node to get device number from\n * @return Device number\n */\nuint32_t ext4_inode_get_dev(struct ext4_inode *inode);\n\n/**@brief Set device number\n * @param inode  I-node to set device number to\n * @param dev    Device number\n */\nvoid ext4_inode_set_dev(struct ext4_inode *inode, uint32_t dev);\n\n/**@brief return the type of i-node\n * @param sb    Superblock\n * @param inode I-node to return the type of\n * @return Result of check operation\n */\nuint32_t ext4_inode_type(struct ext4_sblock *sb, struct ext4_inode *inode);\n\n/**@brief Check if i-node has specified type.\n * @param sb    Superblock\n * @param inode I-node to check type of\n * @param type  Type to check\n * @return Result of check operation\n */\nbool ext4_inode_is_type(struct ext4_sblock *sb, struct ext4_inode *inode,\n            uint32_t type);\n\n/**@brief Check if i-node has specified flag.\n * @param inode I-node to check flags of\n * @param flag  Flag to check\n * @return Result of check operation\n */\nbool ext4_inode_has_flag(struct ext4_inode *inode, uint32_t f);\n\n/**@brief Remove specified flag from i-node.\n * @param inode      I-node to clear flag on\n * @param clear_flag Flag to be cleared\n */\nvoid ext4_inode_clear_flag(struct ext4_inode *inode, uint32_t f);\n\n/**@brief Set specified flag to i-node.\n * @param inode    I-node to set flag on\n * @param set_flag Flag to be set\n */\nvoid ext4_inode_set_flag(struct ext4_inode *inode, uint32_t f);\n\n/**@brief Get inode checksum(crc32)\n * @param sb    Superblock\n * @param inode I-node to get checksum value from\n */\nuint32_t\next4_inode_get_csum(struct ext4_sblock *sb, struct ext4_inode *inode);\n\n/**@brief Get inode checksum(crc32)\n * @param sb    Superblock\n * @param inode I-node to get checksum value from\n */\nvoid\next4_inode_set_csum(struct ext4_sblock *sb, struct ext4_inode *inode,\n            uint32_t checksum);\n\n/**@brief Check if i-node can be truncated.\n * @param sb    Superblock\n * @param inode I-node to check\n * @return Result of the check operation\n */\nbool ext4_inode_can_truncate(struct ext4_sblock *sb, struct ext4_inode *inode);\n\n/**@brief Get extent header from the root of the extent tree.\n * @param inode I-node to get extent header from\n * @return Pointer to extent header of the root node\n */\nstruct ext4_extent_header *\next4_inode_get_extent_header(struct ext4_inode *inode);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EXT4_INODE_H_ */\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_journal.h",
    "content": "/*\n * Copyright (c) 2015 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * Copyright (c) 2015 Kaho Ng (ngkaho1234@gmail.com)\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_journal.h\n * @brief Journal handle functions\n */\n\n#ifndef EXT4_JOURNAL_H_\n#define EXT4_JOURNAL_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <misc/queue.h>\n#include <misc/tree.h>\n\nstruct jbd_fs {\n    struct ext4_blockdev *bdev;\n    struct ext4_inode_ref inode_ref;\n    struct jbd_sb sb;\n\n    bool dirty;\n};\n\nstruct jbd_buf {\n    uint32_t jbd_lba;\n    struct ext4_block block;\n    struct jbd_trans *trans;\n    struct jbd_block_rec *block_rec;\n    TAILQ_ENTRY(jbd_buf) buf_node;\n    TAILQ_ENTRY(jbd_buf) dirty_buf_node;\n};\n\nstruct jbd_revoke_rec {\n    ext4_fsblk_t lba;\n    RB_ENTRY(jbd_revoke_rec) revoke_node;\n};\n\nstruct jbd_block_rec {\n    ext4_fsblk_t lba;\n    struct jbd_trans *trans;\n    RB_ENTRY(jbd_block_rec) block_rec_node;\n    LIST_ENTRY(jbd_block_rec) tbrec_node;\n    TAILQ_HEAD(jbd_buf_dirty, jbd_buf) dirty_buf_queue;\n};\n\nstruct jbd_trans {\n    uint32_t trans_id;\n\n    uint32_t start_iblock;\n    int alloc_blocks;\n    int data_cnt;\n    uint32_t data_csum;\n    int written_cnt;\n    int error;\n\n    struct jbd_journal *journal;\n\n    TAILQ_HEAD(jbd_trans_buf, jbd_buf) buf_queue;\n    RB_HEAD(jbd_revoke_tree, jbd_revoke_rec) revoke_root;\n    LIST_HEAD(jbd_trans_block_rec, jbd_block_rec) tbrec_list;\n    TAILQ_ENTRY(jbd_trans) trans_node;\n};\n\nstruct jbd_journal {\n    uint32_t first;\n    uint32_t start;\n    uint32_t last;\n    uint32_t trans_id;\n    uint32_t alloc_trans_id;\n\n    uint32_t block_size;\n\n    TAILQ_HEAD(jbd_cp_queue, jbd_trans) cp_queue;\n    RB_HEAD(jbd_block, jbd_block_rec) block_rec_root;\n\n    struct jbd_fs *jbd_fs;\n};\n\nint jbd_get_fs(struct ext4_fs *fs,\n           struct jbd_fs *jbd_fs);\nint jbd_put_fs(struct jbd_fs *jbd_fs);\nint jbd_inode_bmap(struct jbd_fs *jbd_fs,\n           ext4_lblk_t iblock,\n           ext4_fsblk_t *fblock);\nint jbd_recover(struct jbd_fs *jbd_fs);\nint jbd_journal_start(struct jbd_fs *jbd_fs,\n              struct jbd_journal *journal);\nint jbd_journal_stop(struct jbd_journal *journal);\nstruct jbd_trans *\njbd_journal_new_trans(struct jbd_journal *journal);\nint jbd_trans_set_block_dirty(struct jbd_trans *trans,\n                  struct ext4_block *block);\nint jbd_trans_revoke_block(struct jbd_trans *trans,\n               ext4_fsblk_t lba);\nint jbd_trans_try_revoke_block(struct jbd_trans *trans,\n                   ext4_fsblk_t lba);\nvoid jbd_journal_free_trans(struct jbd_journal *journal,\n                struct jbd_trans *trans,\n                bool abort);\nint jbd_journal_commit_trans(struct jbd_journal *journal,\n                 struct jbd_trans *trans);\nvoid\njbd_journal_purge_cp_trans(struct jbd_journal *journal,\n               bool flush,\n               bool once);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EXT4_JOURNAL_H_ */\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_mbr.h",
    "content": "/*\n * Copyright (c) 2015 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_mbr.h\n * @brief Master boot record parser\n */\n\n#ifndef EXT4_MBR_H_\n#define EXT4_MBR_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <ext4_config.h>\n#include <ext4_blockdev.h>\n\n/**@brief Master boot record block devices descriptor*/\nstruct ext4_mbr_bdevs {\n    struct ext4_blockdev partitions[4];\n};\n\nint ext4_mbr_scan(struct ext4_blockdev *parent, struct ext4_mbr_bdevs *bdevs);\n\n/**@brief Master boot record partitions*/\nstruct ext4_mbr_parts {\n\n    /**@brief Percentage division tab:\n     *  - {50, 20, 10, 20}\n     * Sum of all 4 elements must be <= 100*/\n    uint8_t division[4];\n};\n\nint ext4_mbr_write(struct ext4_blockdev *parent, struct ext4_mbr_parts *parts, uint32_t disk_id);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EXT4_MBR_H_ */\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_misc.h",
    "content": "/*\n * Copyright (c) 2015 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * Copyright (c) 2015 Kaho Ng (ngkaho1234@gmail.com)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_misc.h\n * @brief Miscellaneous helpers.\n */\n\n#ifndef EXT4_MISC_H_\n#define EXT4_MISC_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n\n/**************************************************************/\n\n#define EXT4_DIV_ROUND_UP(x, y) (((x) + (y) - 1)/(y))\n#define EXT4_ALIGN(x, y) ((y) * EXT4_DIV_ROUND_UP((x), (y)))\n\n/****************************Endian conversion*****************/\n\nstatic inline uint64_t reorder64(uint64_t n)\n{\n    return  ((n & 0xff) << 56) |\n        ((n & 0xff00) << 40) |\n        ((n & 0xff0000) << 24) |\n        ((n & 0xff000000LL) << 8) |\n        ((n & 0xff00000000LL) >> 8) |\n        ((n & 0xff0000000000LL) >> 24) |\n        ((n & 0xff000000000000LL) >> 40) |\n        ((n & 0xff00000000000000LL) >> 56);\n}\n\nstatic inline uint32_t reorder32(uint32_t n)\n{\n    return  ((n & 0xff) << 24) |\n        ((n & 0xff00) << 8) |\n        ((n & 0xff0000) >> 8) |\n        ((n & 0xff000000) >> 24);\n}\n\nstatic inline uint16_t reorder16(uint16_t n)\n{\n    return  ((n & 0xff) << 8) |\n        ((n & 0xff00) >> 8);\n}\n\n#ifdef CONFIG_BIG_ENDIAN\n#define to_le64(_n) reorder64(_n)\n#define to_le32(_n) reorder32(_n)\n#define to_le16(_n) reorder16(_n)\n\n#define to_be64(_n) _n\n#define to_be32(_n) _n\n#define to_be16(_n) _n\n\n#else\n#define to_le64(_n) _n\n#define to_le32(_n) _n\n#define to_le16(_n) _n\n\n#define to_be64(_n) reorder64(_n)\n#define to_be32(_n) reorder32(_n)\n#define to_be16(_n) reorder16(_n)\n#endif\n\n/****************************Access macros to ext4 structures*****************/\n\n#define ext4_get32(s, f) to_le32((s)->f)\n#define ext4_get16(s, f) to_le16((s)->f)\n#define ext4_get8(s, f) (s)->f\n\n#define ext4_set32(s, f, v)                                                    \\\n    do {                                                                   \\\n        (s)->f = to_le32(v);                                           \\\n    } while (0)\n#define ext4_set16(s, f, v)                                                    \\\n    do {                                                                   \\\n        (s)->f = to_le16(v);                                           \\\n    } while (0)\n#define ext4_set8                                                              \\\n    (s, f, v) do { (s)->f = (v); }                                         \\\n    while (0)\n\n/****************************Access macros to jbd2 structures*****************/\n\n#define jbd_get32(s, f) to_be32((s)->f)\n#define jbd_get16(s, f) to_be16((s)->f)\n#define jbd_get8(s, f) (s)->f\n\n#define jbd_set32(s, f, v)                                                    \\\n    do {                                                                   \\\n        (s)->f = to_be32(v);                                           \\\n    } while (0)\n#define jbd_set16(s, f, v)                                                    \\\n    do {                                                                   \\\n        (s)->f = to_be16(v);                                           \\\n    } while (0)\n#define jbd_set8                                                              \\\n    (s, f, v) do { (s)->f = (v); }                                         \\\n    while (0)\n\n#ifdef __GNUC__\n #ifndef __unused\n #define __unused __attribute__ ((__unused__))\n #endif\n#else\n #define __unused\n#endif\n\n#ifndef offsetof\n#define offsetof(type, field)       \\\n    ((size_t)(&(((type *)0)->field)))\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EXT4_MISC_H_ */\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_mkfs.h",
    "content": "/*\n * Copyright (c) 2015 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_mkfs.h\n * @brief\n */\n\n#ifndef EXT4_MKFS_H_\n#define EXT4_MKFS_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n\n#include <ext4_blockdev.h>\n#include <ext4_fs.h>\n\n#include <stdbool.h>\n#include <stdint.h>\n\nstruct ext4_mkfs_info {\n    uint64_t len;\n    uint32_t block_size;\n    uint32_t blocks_per_group;\n    uint32_t inodes_per_group;\n    uint32_t inode_size;\n    uint32_t inodes;\n    uint32_t journal_blocks;\n    uint32_t feat_ro_compat;\n    uint32_t feat_compat;\n    uint32_t feat_incompat;\n    uint32_t bg_desc_reserve_blocks;\n    uint16_t dsc_size;\n    uint8_t uuid[UUID_SIZE];\n    bool journal;\n    const char *label;\n};\n\n\nint ext4_mkfs_read_info(struct ext4_blockdev *bd, struct ext4_mkfs_info *info);\n\nint ext4_mkfs(struct ext4_fs *fs, struct ext4_blockdev *bd,\n          struct ext4_mkfs_info *info, int fs_type);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EXT4_MKFS_H_ */\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_oflags.h",
    "content": "/*\n * Copyright (c) 2015 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * Copyright (c) 2015 Kaho Ng (ngkaho1234@gmail.com)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_oflags.h\n * @brief File opening & seeking flags.\n */\n#ifndef EXT4_OFLAGS_H_\n#define EXT4_OFLAGS_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/********************************FILE OPEN FLAGS*****************************/\n\n#if CONFIG_HAVE_OWN_OFLAGS\n\n #ifndef O_RDONLY\n #define O_RDONLY 00\n #endif\n\n #ifndef O_WRONLY\n #define O_WRONLY 01\n #endif\n\n #ifndef O_RDWR\n #define O_RDWR 02\n #endif\n\n #ifndef O_CREAT\n #define O_CREAT 0100\n #endif\n\n #ifndef O_EXCL\n #define O_EXCL 0200\n #endif\n\n #ifndef O_TRUNC\n #define O_TRUNC 01000\n #endif\n\n #ifndef O_APPEND\n #define O_APPEND 02000\n #endif\n\n/********************************FILE SEEK FLAGS*****************************/\n\n #ifndef SEEK_SET\n #define SEEK_SET 0\n #endif\n\n #ifndef SEEK_CUR\n #define SEEK_CUR 1\n #endif\n\n #ifndef SEEK_END\n #define SEEK_END 2\n #endif\n\n#else\n #include <unistd.h>\n #include <fcntl.h>\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EXT4_OFLAGS_H_ */\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_super.h",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n *\n *\n * HelenOS:\n * Copyright (c) 2012 Martin Sucha\n * Copyright (c) 2012 Frantisek Princ\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_super.c\n * @brief Superblock operations.\n */\n\n#ifndef EXT4_SUPER_H_\n#define EXT4_SUPER_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_misc.h>\n\n/**@brief   Blocks count get stored in superblock.\n * @param   s superblock descriptor\n * @return  count of blocks*/\nstatic inline uint64_t ext4_sb_get_blocks_cnt(struct ext4_sblock *s)\n{\n    return ((uint64_t)to_le32(s->blocks_count_hi) << 32) |\n           to_le32(s->blocks_count_lo);\n}\n\n/**@brief   Blocks count set  in superblock.\n * @param   s superblock descriptor\n * @return  count of blocks*/\nstatic inline void ext4_sb_set_blocks_cnt(struct ext4_sblock *s, uint64_t cnt)\n{\n    s->blocks_count_lo = to_le32((cnt << 32) >> 32);\n    s->blocks_count_hi = to_le32(cnt >> 32);\n}\n\n/**@brief   Free blocks count get stored in superblock.\n * @param   s superblock descriptor\n * @return  free blocks*/\nstatic inline uint64_t ext4_sb_get_free_blocks_cnt(struct ext4_sblock *s)\n{\n    return ((uint64_t)to_le32(s->free_blocks_count_hi) << 32) |\n           to_le32(s->free_blocks_count_lo);\n}\n\n/**@brief   Free blocks count set.\n * @param   s superblock descriptor\n * @param   cnt new value of free blocks*/\nstatic inline void ext4_sb_set_free_blocks_cnt(struct ext4_sblock *s,\n                           uint64_t cnt)\n{\n    s->free_blocks_count_lo = to_le32((cnt << 32) >> 32);\n    s->free_blocks_count_hi = to_le32(cnt >> 32);\n}\n\n/**@brief   Block size get from superblock.\n * @param   s superblock descriptor\n * @return  block size in bytes*/\nstatic inline uint32_t ext4_sb_get_block_size(struct ext4_sblock *s)\n{\n    return 1024 << to_le32(s->log_block_size);\n}\n\n/**@brief   Block group descriptor size.\n * @param   s superblock descriptor\n * @return  block group descriptor size in bytes*/\nstatic inline uint16_t ext4_sb_get_desc_size(struct ext4_sblock *s)\n{\n    uint16_t size = to_le16(s->desc_size);\n\n    return size < EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE\n           ? EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE\n           : size;\n}\n\n/*************************Flags and features*********************************/\n\n/**@brief   Support check of flag.\n * @param   s superblock descriptor\n * @param   v flag to check\n * @return  true if flag is supported*/\nstatic inline bool ext4_sb_check_flag(struct ext4_sblock *s, uint32_t v)\n{\n    return to_le32(s->flags) & v;\n}\n\n/**@brief   Support check of feature compatible.\n * @param   s superblock descriptor\n * @param   v feature to check\n * @return  true if feature is supported*/\nstatic inline bool ext4_sb_feature_com(struct ext4_sblock *s, uint32_t v)\n{\n    return to_le32(s->features_compatible) & v;\n}\n\n/**@brief   Support check of feature incompatible.\n * @param   s superblock descriptor\n * @param   v feature to check\n * @return  true if feature is supported*/\nstatic inline bool ext4_sb_feature_incom(struct ext4_sblock *s, uint32_t v)\n{\n    return to_le32(s->features_incompatible) & v;\n}\n\n/**@brief   Support check of read only flag.\n * @param   s superblock descriptor\n * @param   v flag to check\n * @return  true if flag is supported*/\nstatic inline bool ext4_sb_feature_ro_com(struct ext4_sblock *s, uint32_t v)\n{\n    return to_le32(s->features_read_only) & v;\n}\n\n/**@brief   Block group to flex group.\n * @param   s superblock descriptor\n * @param   block_group block group\n * @return  flex group id*/\nstatic inline uint32_t ext4_sb_bg_to_flex(struct ext4_sblock *s,\n                      uint32_t block_group)\n{\n    return block_group >> to_le32(s->log_groups_per_flex);\n}\n\n/**@brief   Flex block group size.\n * @param   s superblock descriptor\n * @return  flex bg size*/\nstatic inline uint32_t ext4_sb_flex_bg_size(struct ext4_sblock *s)\n{\n    return 1 << to_le32(s->log_groups_per_flex);\n}\n\n/**@brief   Return first meta block group id.\n * @param   s superblock descriptor\n * @return  first meta_bg id */\nstatic inline uint32_t ext4_sb_first_meta_bg(struct ext4_sblock *s)\n{\n    return to_le32(s->first_meta_bg);\n}\n\n/**************************More complex functions****************************/\n\n/**@brief   Returns a block group count.\n * @param   s superblock descriptor\n * @return  count of block groups*/\nuint32_t ext4_block_group_cnt(struct ext4_sblock *s);\n\n/**@brief   Returns block count in block group\n *          (last block group may have less blocks)\n * @param   s superblock descriptor\n * @param   bgid block group id\n * @return  blocks count*/\nuint32_t ext4_blocks_in_group_cnt(struct ext4_sblock *s, uint32_t bgid);\n\n/**@brief   Returns inodes count in block group\n *          (last block group may have less inodes)\n * @param   s superblock descriptor\n * @param   bgid block group id\n * @return  inodes count*/\nuint32_t ext4_inodes_in_group_cnt(struct ext4_sblock *s, uint32_t bgid);\n\n/***************************Read/write/check superblock**********************/\n\n/**@brief   Superblock write.\n * @param   bdev block device descriptor.\n * @param   s superblock descriptor\n * @return  Standard error code */\nint ext4_sb_write(struct ext4_blockdev *bdev, struct ext4_sblock *s);\n\n/**@brief   Superblock read.\n * @param   bdev block device descriptor.\n * @param   s superblock descriptor\n * @return  Standard error code */\nint ext4_sb_read(struct ext4_blockdev *bdev, struct ext4_sblock *s);\n\n/**@brief   Superblock simple validation.\n * @param   s superblock descriptor\n * @return  true if OK*/\nbool ext4_sb_check(struct ext4_sblock *s);\n\n/**@brief   Superblock presence in block group.\n * @param   s superblock descriptor\n * @param   block_group block group id\n * @return  true if block group has superblock*/\nbool ext4_sb_is_super_in_bg(struct ext4_sblock *s, uint32_t block_group);\n\n/**@brief   TODO:*/\nbool ext4_sb_sparse(uint32_t group);\n\n/**@brief   TODO:*/\nuint32_t ext4_bg_num_gdb(struct ext4_sblock *s, uint32_t group);\n\n/**@brief   TODO:*/\nuint32_t ext4_num_base_meta_clusters(struct ext4_sblock *s,\n                     uint32_t block_group);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EXT4_SUPER_H_ */\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_trans.h",
    "content": "/*\n * Copyright (c) 2015 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * Copyright (c) 2015 Kaho Ng (ngkaho1234@gmail.com)\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_trans.h\n * @brief Transaction handle functions\n */\n\n#ifndef EXT4_TRANS_H\n#define EXT4_TRANS_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n\n\n/**@brief   Mark a buffer dirty and add it to the current transaction.\n * @param   buf buffer\n * @return  standard error code*/\nint ext4_trans_set_block_dirty(struct ext4_buf *buf);\n\n/**@brief   Block get function (through cache, don't read).\n *          jbd_trans_get_access would be called in order to\n *          get write access to the buffer.\n * @param   bdev block device descriptor\n * @param   b block descriptor\n * @param   lba logical block address\n * @return  standard error code*/\nint ext4_trans_block_get_noread(struct ext4_blockdev *bdev,\n              struct ext4_block *b,\n              uint64_t lba);\n\n/**@brief   Block get function (through cache).\n *          jbd_trans_get_access would be called in order to\n *          get write access to the buffer.\n * @param   bdev block device descriptor\n * @param   b block descriptor\n * @param   lba logical block address\n * @return  standard error code*/\nint ext4_trans_block_get(struct ext4_blockdev *bdev,\n           struct ext4_block *b,\n           uint64_t lba);\n\n/**@brief  Try to add block to be revoked to the current transaction.\n * @param  bdev block device descriptor\n * @param  lba logical block address\n * @return standard error code*/\nint ext4_trans_try_revoke_block(struct ext4_blockdev *bdev,\n                   uint64_t lba);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EXT4_TRANS_H */\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_types.h",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n *\n *\n * HelenOS:\n * Copyright (c) 2012 Martin Sucha\n * Copyright (c) 2012 Frantisek Princ\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_types.h\n * @brief Ext4 data structure definitions.\n */\n\n#ifndef EXT4_TYPES_H_\n#define EXT4_TYPES_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <ext4_config.h>\n#include <ext4_blockdev.h>\n#include <misc/tree.h>\n\n#include <stddef.h>\n#include <stdint.h>\n\n/*\n * Types of blocks.\n */\ntypedef uint32_t ext4_lblk_t;\ntypedef uint64_t ext4_fsblk_t;\n\n\n#define EXT4_CHECKSUM_CRC32C 1\n\n#define UUID_SIZE 16\n\n#pragma pack(push, 1)\n\n/*\n * Structure of the super block\n */\nstruct ext4_sblock {\n    uint32_t inodes_count;         /* I-nodes count */\n    uint32_t blocks_count_lo;     /* Blocks count */\n    uint32_t reserved_blocks_count_lo; /* Reserved blocks count */\n    uint32_t free_blocks_count_lo;     /* Free blocks count */\n    uint32_t free_inodes_count; /* Free inodes count */\n    uint32_t first_data_block;   /* First Data Block */\n    uint32_t log_block_size;       /* Block size */\n    uint32_t log_cluster_size;   /* Obsoleted fragment size */\n    uint32_t blocks_per_group;   /* Number of blocks per group */\n    uint32_t frags_per_group;     /* Obsoleted fragments per group */\n    uint32_t inodes_per_group;   /* Number of inodes per group */\n    uint32_t mount_time;           /* Mount time */\n    uint32_t write_time;           /* Write time */\n    uint16_t mount_count;          /* Mount count */\n    uint16_t max_mount_count;     /* Maximal mount count */\n    uint16_t magic;            /* Magic signature */\n    uint16_t state;            /* File system state */\n    uint16_t errors;           /* Behavior when detecting errors */\n    uint16_t minor_rev_level;     /* Minor revision level */\n    uint32_t last_check_time;     /* Time of last check */\n    uint32_t check_interval;       /* Maximum time between checks */\n    uint32_t creator_os;           /* Creator OS */\n    uint32_t rev_level;        /* Revision level */\n    uint16_t def_resuid;           /* Default uid for reserved blocks */\n    uint16_t def_resgid;           /* Default gid for reserved blocks */\n\n    /* Fields for EXT4_DYNAMIC_REV superblocks only. */\n    uint32_t first_inode;    /* First non-reserved inode */\n    uint16_t inode_size;      /* Size of inode structure */\n    uint16_t block_group_index;   /* Block group index of this superblock */\n    uint32_t features_compatible; /* Compatible feature set */\n    uint32_t features_incompatible;  /* Incompatible feature set */\n    uint32_t features_read_only;     /* Readonly-compatible feature set */\n    uint8_t uuid[UUID_SIZE];         /* 128-bit uuid for volume */\n    char volume_name[16];        /* Volume name */\n    char last_mounted[64];       /* Directory where last mounted */\n    uint32_t algorithm_usage_bitmap; /* For compression */\n\n    /*\n     * Performance hints. Directory preallocation should only\n     * happen if the EXT4_FEATURE_COMPAT_DIR_PREALLOC flag is on.\n     */\n    uint8_t s_prealloc_blocks; /* Number of blocks to try to preallocate */\n    uint8_t s_prealloc_dir_blocks;  /* Number to preallocate for dirs */\n    uint16_t s_reserved_gdt_blocks; /* Per group desc for online growth */\n\n    /*\n     * Journaling support valid if EXT4_FEATURE_COMPAT_HAS_JOURNAL set.\n     */\n    uint8_t journal_uuid[UUID_SIZE];      /* UUID of journal superblock */\n    uint32_t journal_inode_number; /* Inode number of journal file */\n    uint32_t journal_dev;     /* Device number of journal file */\n    uint32_t last_orphan;     /* Head of list of inodes to delete */\n    uint32_t hash_seed[4];   /* HTREE hash seed */\n    uint8_t default_hash_version;  /* Default hash version to use */\n    uint8_t journal_backup_type;\n    uint16_t desc_size;   /* Size of group descriptor */\n    uint32_t default_mount_opts; /* Default mount options */\n    uint32_t first_meta_bg;      /* First metablock block group */\n    uint32_t mkfs_time;   /* When the filesystem was created */\n    uint32_t journal_blocks[17]; /* Backup of the journal inode */\n\n    /* 64bit support valid if EXT4_FEATURE_COMPAT_64BIT */\n    uint32_t blocks_count_hi;     /* Blocks count */\n    uint32_t reserved_blocks_count_hi; /* Reserved blocks count */\n    uint32_t free_blocks_count_hi;     /* Free blocks count */\n    uint16_t min_extra_isize;    /* All inodes have at least # bytes */\n    uint16_t want_extra_isize;   /* New inodes should reserve # bytes */\n    uint32_t flags;          /* Miscellaneous flags */\n    uint16_t raid_stride;   /* RAID stride */\n    uint16_t mmp_interval;       /* # seconds to wait in MMP checking */\n    uint64_t mmp_block;   /* Block for multi-mount protection */\n    uint32_t raid_stripe_width;  /* Blocks on all data disks (N * stride) */\n    uint8_t log_groups_per_flex; /* FLEX_BG group size */\n    uint8_t checksum_type;\n    uint16_t reserved_pad;\n    uint64_t kbytes_written; /* Number of lifetime kilobytes written */\n    uint32_t snapshot_inum;  /* I-node number of active snapshot */\n    uint32_t snapshot_id;    /* Sequential ID of active snapshot */\n    uint64_t\n        snapshot_r_blocks_count; /* Reserved blocks for active snapshot's\n                    future use */\n    uint32_t\n        snapshot_list; /* I-node number of the head of the on-disk snapshot\n                  list */\n    uint32_t error_count;    /* Number of file system errors */\n    uint32_t first_error_time;    /* First time an error happened */\n    uint32_t first_error_ino;     /* I-node involved in first error */\n    uint64_t first_error_block;   /* Block involved of first error */\n    uint8_t first_error_func[32]; /* Function where the error happened */\n    uint32_t first_error_line;    /* Line number where error happened */\n    uint32_t last_error_time;     /* Most recent time of an error */\n    uint32_t last_error_ino;      /* I-node involved in last error */\n    uint32_t last_error_line;     /* Line number where error happened */\n    uint64_t last_error_block;    /* Block involved of last error */\n    uint8_t last_error_func[32];  /* Function where the error happened */\n    uint8_t mount_opts[64];\n    uint32_t usr_quota_inum;    /* inode for tracking user quota */\n    uint32_t grp_quota_inum;    /* inode for tracking group quota */\n    uint32_t overhead_clusters; /* overhead blocks/clusters in fs */\n    uint32_t backup_bgs[2]; /* groups with sparse_super2 SBs */\n    uint8_t  encrypt_algos[4];  /* Encryption algorithms in use  */\n    uint8_t  encrypt_pw_salt[16];   /* Salt used for string2key algorithm */\n    uint32_t lpf_ino;       /* Location of the lost+found inode */\n    uint32_t padding[100];  /* Padding to the end of the block */\n    uint32_t checksum;      /* crc32c(superblock) */\n};\n\n#pragma pack(pop)\n\n#define EXT4_SUPERBLOCK_MAGIC 0xEF53\n#define EXT4_SUPERBLOCK_SIZE 1024\n#define EXT4_SUPERBLOCK_OFFSET 1024\n\n#define EXT4_SUPERBLOCK_OS_LINUX 0\n#define EXT4_SUPERBLOCK_OS_HURD 1\n\n/*\n * Misc. filesystem flags\n */\n#define EXT4_SUPERBLOCK_FLAGS_SIGNED_HASH 0x0001\n#define EXT4_SUPERBLOCK_FLAGS_UNSIGNED_HASH 0x0002\n#define EXT4_SUPERBLOCK_FLAGS_TEST_FILESYS 0x0004\n/*\n * Filesystem states\n */\n#define EXT4_SUPERBLOCK_STATE_VALID_FS 0x0001  /* Unmounted cleanly */\n#define EXT4_SUPERBLOCK_STATE_ERROR_FS 0x0002  /* Errors detected */\n#define EXT4_SUPERBLOCK_STATE_ORPHAN_FS 0x0004 /* Orphans being recovered */\n\n/*\n * Behaviour when errors detected\n */\n#define EXT4_SUPERBLOCK_ERRORS_CONTINUE 1 /* Continue execution */\n#define EXT4_SUPERBLOCK_ERRORS_RO 2       /* Remount fs read-only */\n#define EXT4_SUPERBLOCK_ERRORS_PANIC 3    /* Panic */\n#define EXT4_SUPERBLOCK_ERRORS_DEFAULT EXT4_ERRORS_CONTINUE\n\n/*\n * Compatible features\n */\n#define EXT4_FCOM_DIR_PREALLOC 0x0001\n#define EXT4_FCOM_IMAGIC_INODES 0x0002\n#define EXT4_FCOM_HAS_JOURNAL 0x0004\n#define EXT4_FCOM_EXT_ATTR 0x0008\n#define EXT4_FCOM_RESIZE_INODE 0x0010\n#define EXT4_FCOM_DIR_INDEX 0x0020\n\n/*\n * Read-only compatible features\n */\n#define EXT4_FRO_COM_SPARSE_SUPER 0x0001\n#define EXT4_FRO_COM_LARGE_FILE 0x0002\n#define EXT4_FRO_COM_BTREE_DIR 0x0004\n#define EXT4_FRO_COM_HUGE_FILE 0x0008\n#define EXT4_FRO_COM_GDT_CSUM 0x0010\n#define EXT4_FRO_COM_DIR_NLINK 0x0020\n#define EXT4_FRO_COM_EXTRA_ISIZE 0x0040\n#define EXT4_FRO_COM_QUOTA 0x0100\n#define EXT4_FRO_COM_BIGALLOC 0x0200\n#define EXT4_FRO_COM_METADATA_CSUM 0x0400\n\n/*\n * Incompatible features\n */\n#define EXT4_FINCOM_COMPRESSION 0x0001\n#define EXT4_FINCOM_FILETYPE 0x0002\n#define EXT4_FINCOM_RECOVER 0x0004     /* Needs recovery */\n#define EXT4_FINCOM_JOURNAL_DEV 0x0008 /* Journal device */\n#define EXT4_FINCOM_META_BG 0x0010\n#define EXT4_FINCOM_EXTENTS 0x0040 /* extents support */\n#define EXT4_FINCOM_64BIT 0x0080\n#define EXT4_FINCOM_MMP 0x0100\n#define EXT4_FINCOM_FLEX_BG 0x0200\n#define EXT4_FINCOM_EA_INODE 0x0400  /* EA in inode */\n#define EXT4_FINCOM_DIRDATA 0x1000    /* data in dirent */\n#define EXT4_FINCOM_BG_USE_META_CSUM 0x2000 /* use crc32c for bg */\n#define EXT4_FINCOM_LARGEDIR 0x4000  /* >2GB or 3-lvl htree */\n#define EXT4_FINCOM_INLINE_DATA 0x8000      /* data in inode */\n\n/*\n * EXT2 supported feature set\n */\n#define EXT2_SUPPORTED_FCOM 0x0000\n\n#define EXT2_SUPPORTED_FINCOM                                   \\\n    (EXT4_FINCOM_FILETYPE | EXT4_FINCOM_META_BG)\n\n#define EXT2_SUPPORTED_FRO_COM                                  \\\n    (EXT4_FRO_COM_SPARSE_SUPER |                            \\\n     EXT4_FRO_COM_LARGE_FILE)\n\n/*\n * EXT3 supported feature set\n */\n#define EXT3_SUPPORTED_FCOM (EXT4_FCOM_DIR_INDEX)\n\n#define EXT3_SUPPORTED_FINCOM                                 \\\n    (EXT4_FINCOM_FILETYPE | EXT4_FINCOM_META_BG)\n\n#define EXT3_SUPPORTED_FRO_COM                                \\\n    (EXT4_FRO_COM_SPARSE_SUPER | EXT4_FRO_COM_LARGE_FILE)\n\n/*\n * EXT4 supported feature set\n */\n#define EXT4_SUPPORTED_FCOM (EXT4_FCOM_DIR_INDEX)\n\n#define EXT4_SUPPORTED_FINCOM                              \\\n    (EXT4_FINCOM_FILETYPE | EXT4_FINCOM_META_BG |      \\\n     EXT4_FINCOM_EXTENTS | EXT4_FINCOM_FLEX_BG |       \\\n     EXT4_FINCOM_64BIT)\n\n#define EXT4_SUPPORTED_FRO_COM                             \\\n    (EXT4_FRO_COM_SPARSE_SUPER |                       \\\n     EXT4_FRO_COM_METADATA_CSUM |                      \\\n     EXT4_FRO_COM_LARGE_FILE | EXT4_FRO_COM_GDT_CSUM | \\\n     EXT4_FRO_COM_DIR_NLINK |                          \\\n     EXT4_FRO_COM_EXTRA_ISIZE | EXT4_FRO_COM_HUGE_FILE)\n\n/*Ignored features:\n * RECOVER - journaling in lwext4 is not supported\n *           (probably won't be ever...)\n * MMP - multi-mout protection (impossible scenario)\n * */\n#define EXT_FINCOM_IGNORED                                 \\\n    EXT4_FINCOM_RECOVER | EXT4_FINCOM_MMP\n\n#if 0\n/*TODO: Features incompatible to implement*/\n#define EXT4_SUPPORTED_FINCOM\n                     (EXT4_FINCOM_INLINE_DATA)\n\n/*TODO: Features read only to implement*/\n#define EXT4_SUPPORTED_FRO_COM\n                     EXT4_FRO_COM_BIGALLOC |\\\n                     EXT4_FRO_COM_QUOTA)\n#endif\n\n\n/* Inode table/bitmap not in use */\n#define EXT4_BLOCK_GROUP_INODE_UNINIT 0x0001\n/* Block bitmap not in use */\n#define EXT4_BLOCK_GROUP_BLOCK_UNINIT 0x0002\n/* On-disk itable initialized to zero */\n#define EXT4_BLOCK_GROUP_ITABLE_ZEROED 0x0004\n\n/*\n * Structure of a blocks group descriptor\n */\nstruct ext4_bgroup {\n    uint32_t block_bitmap_lo;       /* Blocks bitmap block */\n    uint32_t inode_bitmap_lo;       /* Inodes bitmap block */\n    uint32_t inode_table_first_block_lo; /* Inodes table block */\n    uint16_t free_blocks_count_lo;       /* Free blocks count */\n    uint16_t free_inodes_count_lo;       /* Free inodes count */\n    uint16_t used_dirs_count_lo;     /* Directories count */\n    uint16_t flags;            /* EXT4_BG_flags (INODE_UNINIT, etc) */\n    uint32_t exclude_bitmap_lo;    /* Exclude bitmap for snapshots */\n    uint16_t block_bitmap_csum_lo; /* crc32c(s_uuid+grp_num+bbitmap) LE */\n    uint16_t inode_bitmap_csum_lo; /* crc32c(s_uuid+grp_num+ibitmap) LE */\n    uint16_t itable_unused_lo;     /* Unused inodes count */\n    uint16_t checksum;       /* crc16(sb_uuid+group+desc) */\n\n    uint32_t block_bitmap_hi;       /* Blocks bitmap block MSB */\n    uint32_t inode_bitmap_hi;       /* I-nodes bitmap block MSB */\n    uint32_t inode_table_first_block_hi; /* I-nodes table block MSB */\n    uint16_t free_blocks_count_hi;       /* Free blocks count MSB */\n    uint16_t free_inodes_count_hi;       /* Free i-nodes count MSB */\n    uint16_t used_dirs_count_hi;     /* Directories count MSB */\n    uint16_t itable_unused_hi;     /* Unused inodes count MSB */\n    uint32_t exclude_bitmap_hi;   /* Exclude bitmap block MSB */\n    uint16_t block_bitmap_csum_hi; /* crc32c(s_uuid+grp_num+bbitmap) BE */\n    uint16_t inode_bitmap_csum_hi; /* crc32c(s_uuid+grp_num+ibitmap) BE */\n    uint32_t reserved;       /* Padding */\n};\n\n\n#define EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE 32\n#define EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE 64\n\n#define EXT4_MIN_BLOCK_SIZE 1024  /* 1 KiB */\n#define EXT4_MAX_BLOCK_SIZE 65536 /* 64 KiB */\n#define EXT4_REV0_INODE_SIZE 128\n\n#define EXT4_INODE_BLOCK_SIZE 512\n\n#define EXT4_INODE_DIRECT_BLOCK_COUNT 12\n#define EXT4_INODE_INDIRECT_BLOCK EXT4_INODE_DIRECT_BLOCK_COUNT\n#define EXT4_INODE_DOUBLE_INDIRECT_BLOCK (EXT4_INODE_INDIRECT_BLOCK + 1)\n#define EXT4_INODE_TRIPPLE_INDIRECT_BLOCK (EXT4_INODE_DOUBLE_INDIRECT_BLOCK + 1)\n#define EXT4_INODE_BLOCKS (EXT4_INODE_TRIPPLE_INDIRECT_BLOCK + 1)\n#define EXT4_INODE_INDIRECT_BLOCK_COUNT                                        \\\n    (EXT4_INODE_BLOCKS - EXT4_INODE_DIRECT_BLOCK_COUNT)\n\n#pragma pack(push, 1)\n\n/*\n * Structure of an inode on the disk\n */\nstruct ext4_inode {\n    uint16_t mode;          /* File mode */\n    uint16_t uid;           /* Low 16 bits of owner uid */\n    uint32_t size_lo;      /* Size in bytes */\n    uint32_t access_time;       /* Access time */\n    uint32_t change_inode_time; /* I-node change time */\n    uint32_t modification_time; /* Modification time */\n    uint32_t deletion_time;     /* Deletion time */\n    uint16_t gid;           /* Low 16 bits of group id */\n    uint16_t links_count;       /* Links count */\n    uint32_t blocks_count_lo;   /* Blocks count */\n    uint32_t flags;         /* File flags */\n    uint32_t unused_osd1;       /* OS dependent - not used in HelenOS */\n    uint32_t blocks[EXT4_INODE_BLOCKS]; /* Pointers to blocks */\n    uint32_t generation;            /* File version (for NFS) */\n    uint32_t file_acl_lo;           /* File ACL */\n    uint32_t size_hi;\n    uint32_t obso_faddr; /* Obsoleted fragment address */\n\n    union {\n        struct {\n            uint16_t blocks_high;\n            uint16_t file_acl_high;\n            uint16_t uid_high;\n            uint16_t gid_high;\n            uint16_t checksum_lo; /* crc32c(uuid+inum+inode) LE */\n            uint16_t reserved2;\n        } linux2;\n        struct {\n            uint16_t reserved1;\n            uint16_t mode_high;\n            uint16_t uid_high;\n            uint16_t gid_high;\n            uint32_t author;\n        } hurd2;\n    } osd2;\n\n    uint16_t extra_isize;\n    uint16_t checksum_hi;   /* crc32c(uuid+inum+inode) BE */\n    uint32_t ctime_extra; /* Extra change time (nsec << 2 | epoch) */\n    uint32_t mtime_extra; /* Extra Modification time (nsec << 2 | epoch) */\n    uint32_t atime_extra; /* Extra Access time (nsec << 2 | epoch) */\n    uint32_t crtime;      /* File creation time */\n    uint32_t\n        crtime_extra;    /* Extra file creation time (nsec << 2 | epoch) */\n    uint32_t version_hi; /* High 32 bits for 64-bit version */\n};\n\n#pragma pack(pop)\n\n#define EXT4_INODE_MODE_FIFO 0x1000\n#define EXT4_INODE_MODE_CHARDEV 0x2000\n#define EXT4_INODE_MODE_DIRECTORY 0x4000\n#define EXT4_INODE_MODE_BLOCKDEV 0x6000\n#define EXT4_INODE_MODE_FILE 0x8000\n#define EXT4_INODE_MODE_SOFTLINK 0xA000\n#define EXT4_INODE_MODE_SOCKET 0xC000\n#define EXT4_INODE_MODE_TYPE_MASK 0xF000\n\n/*\n * Inode flags\n */\n#define EXT4_INODE_FLAG_SECRM 0x00000001     /* Secure deletion */\n#define EXT4_INODE_FLAG_UNRM 0x00000002      /* Undelete */\n#define EXT4_INODE_FLAG_COMPR 0x00000004     /* Compress file */\n#define EXT4_INODE_FLAG_SYNC 0x00000008      /* Synchronous updates */\n#define EXT4_INODE_FLAG_IMMUTABLE 0x00000010 /* Immutable file */\n#define EXT4_INODE_FLAG_APPEND 0x00000020  /* writes to file may only append */\n#define EXT4_INODE_FLAG_NODUMP 0x00000040  /* do not dump file */\n#define EXT4_INODE_FLAG_NOATIME 0x00000080 /* do not update atime */\n\n/* Compression flags */\n#define EXT4_INODE_FLAG_DIRTY 0x00000100\n#define EXT4_INODE_FLAG_COMPRBLK                                               \\\n    0x00000200             /* One or more compressed clusters */\n#define EXT4_INODE_FLAG_NOCOMPR 0x00000400 /* Don't compress */\n#define EXT4_INODE_FLAG_ECOMPR 0x00000800  /* Compression error */\n\n#define EXT4_INODE_FLAG_INDEX 0x00001000  /* hash-indexed directory */\n#define EXT4_INODE_FLAG_IMAGIC 0x00002000 /* AFS directory */\n#define EXT4_INODE_FLAG_JOURNAL_DATA                                           \\\n    0x00004000            /* File data should be journaled */\n#define EXT4_INODE_FLAG_NOTAIL 0x00008000 /* File tail should not be merged */\n#define EXT4_INODE_FLAG_DIRSYNC                                                \\\n    0x00010000 /* Dirsync behaviour (directories only) */\n#define EXT4_INODE_FLAG_TOPDIR 0x00020000    /* Top of directory hierarchies */\n#define EXT4_INODE_FLAG_HUGE_FILE 0x00040000 /* Set to each huge file */\n#define EXT4_INODE_FLAG_EXTENTS 0x00080000   /* Inode uses extents */\n#define EXT4_INODE_FLAG_EA_INODE 0x00200000  /* Inode used for large EA */\n#define EXT4_INODE_FLAG_EOFBLOCKS 0x00400000 /* Blocks allocated beyond EOF */\n#define EXT4_INODE_FLAG_RESERVED 0x80000000  /* reserved for ext4 lib */\n\n#define EXT4_INODE_ROOT_INDEX 2\n\n\n#define EXT4_DIRECTORY_FILENAME_LEN 255\n\n/**@brief   Directory entry types. */\nenum {\n\tEXT4_DE_UNKNOWN = 0,\n\tEXT4_DE_REG_FILE,\n\tEXT4_DE_DIR,\n\tEXT4_DE_CHRDEV,\n\tEXT4_DE_BLKDEV,\n\tEXT4_DE_FIFO,\n\tEXT4_DE_SOCK,\n\tEXT4_DE_SYMLINK,\n\tEXT4_DE_MAX,\n};\n\n#define EXT4_DIRENTRY_DIR_CSUM 0xDE\n\n#pragma pack(push, 1)\n\nunion ext4_dir_en_internal {\n    uint8_t name_length_high; /* Higher 8 bits of name length */\n    uint8_t inode_type;       /* Type of referenced inode (in rev >= 0.5) */\n};\n\n/**\n * Linked list directory entry structure\n */\nstruct ext4_dir_en {\n    uint32_t inode; /* I-node for the entry */\n    uint16_t entry_len; /* Distance to the next directory entry */\n    uint8_t name_len;   /* Lower 8 bits of name length */\n\n    union ext4_dir_en_internal in;\n    uint8_t name[]; /* Entry name */\n};\n\n/* Structures for indexed directory */\n\nstruct ext4_dir_idx_climit {\n    uint16_t limit;\n    uint16_t count;\n};\n\nstruct ext4_dir_idx_dot_en {\n    uint32_t inode;\n    uint16_t entry_length;\n    uint8_t name_length;\n    uint8_t inode_type;\n    uint8_t name[4];\n};\n\nstruct ext4_dir_idx_rinfo {\n    uint32_t reserved_zero;\n    uint8_t hash_version;\n    uint8_t info_length;\n    uint8_t indirect_levels;\n    uint8_t unused_flags;\n};\n\nstruct ext4_dir_idx_entry {\n    uint32_t hash;\n    uint32_t block;\n};\n\nstruct ext4_dir_idx_root {\n    struct ext4_dir_idx_dot_en dots[2];\n    struct ext4_dir_idx_rinfo info;\n    struct ext4_dir_idx_entry en[];\n};\n\nstruct ext4_fake_dir_entry {\n    uint32_t inode;\n    uint16_t entry_length;\n    uint8_t name_length;\n    uint8_t inode_type;\n};\n\nstruct ext4_dir_idx_node {\n    struct ext4_fake_dir_entry fake;\n    struct ext4_dir_idx_entry entries[];\n};\n\n/*\n * This goes at the end of each htree block.\n */\nstruct ext4_dir_idx_tail {\n    uint32_t reserved;\n    uint32_t checksum;  /* crc32c(uuid+inum+dirblock) */\n};\n\n/*\n * This is a bogus directory entry at the end of each leaf block that\n * records checksums.\n */\nstruct ext4_dir_entry_tail {\n    uint32_t reserved_zero1;    /* Pretend to be unused */\n    uint16_t rec_len;       /* 12 */\n    uint8_t reserved_zero2; /* Zero name length */\n    uint8_t reserved_ft;    /* 0xDE, fake file type */\n    uint32_t checksum;      /* crc32c(uuid+inum+dirblock) */\n};\n\n#pragma pack(pop)\n\n#define EXT4_DIRENT_TAIL(block, blocksize) \\\n    ((struct ext4_dir_entry_tail *)(((char *)(block)) + ((blocksize) - \\\n                    sizeof(struct ext4_dir_entry_tail))))\n\n#define EXT4_ERR_BAD_DX_DIR (-25000)\n\n#define EXT4_LINK_MAX 65000\n\n#define EXT4_BAD_INO 1\n#define EXT4_ROOT_INO 2\n#define EXT4_BOOT_LOADER_INO 5\n#define EXT4_UNDEL_DIR_INO 6\n#define EXT4_RESIZE_INO 7\n#define EXT4_JOURNAL_INO 8\n\n#define EXT4_GOOD_OLD_FIRST_INO 11\n#define EXT_MAX_BLOCKS (ext4_lblk_t) (-1)\n#define IN_RANGE(b, first, len) ((b) >= (first) && (b) <= (first) + (len) - 1)\n\n\n/******************************************************************************/\n\n/* EXT3 HTree directory indexing */\n#define EXT2_HTREE_LEGACY 0\n#define EXT2_HTREE_HALF_MD4 1\n#define EXT2_HTREE_TEA 2\n#define EXT2_HTREE_LEGACY_UNSIGNED 3\n#define EXT2_HTREE_HALF_MD4_UNSIGNED 4\n#define EXT2_HTREE_TEA_UNSIGNED 5\n\n#define EXT2_HTREE_EOF 0x7FFFFFFFUL\n\n#define EXT4_GOOD_OLD_INODE_SIZE    128\n\n/*****************************************************************************/\n\n/*\n * JBD stores integers in big endian.\n */\n\n#define JBD_MAGIC_NUMBER 0xc03b3998U /* The first 4 bytes of /dev/random! */\n\n/*\n * Descriptor block types:\n */\n\n#define JBD_DESCRIPTOR_BLOCK    1\n#define JBD_COMMIT_BLOCK    2\n#define JBD_SUPERBLOCK      3\n#define JBD_SUPERBLOCK_V2   4\n#define JBD_REVOKE_BLOCK    5\n\n#pragma pack(push, 1)\n\n/*\n * Standard header for all descriptor blocks:\n */\nstruct jbd_bhdr {\n    uint32_t        magic;\n    uint32_t        blocktype;\n    uint32_t        sequence;\n};\n\n#pragma pack(pop)\n\n/*\n * Checksum types.\n */\n#define JBD_CRC32_CHKSUM   1\n#define JBD_MD5_CHKSUM     2\n#define JBD_SHA1_CHKSUM    3\n#define JBD_CRC32C_CHKSUM  4\n\n#define JBD_CRC32_CHKSUM_SIZE 4\n\n#define JBD_CHECKSUM_BYTES (32 / sizeof(uint32_t))\n\n#pragma pack(push, 1)\n\n/*\n * Commit block header for storing transactional checksums:\n *\n * NOTE: If FEATURE_COMPAT_CHECKSUM (checksum v1) is set, the h_chksum*\n * fields are used to store a checksum of the descriptor and data blocks.\n *\n * If FEATURE_INCOMPAT_CSUM_V2 (checksum v2) is set, then the h_chksum\n * field is used to store crc32c(uuid+commit_block).  Each journal metadata\n * block gets its own checksum, and data block checksums are stored in\n * journal_block_tag (in the descriptor).  The other h_chksum* fields are\n * not used.\n *\n * If FEATURE_INCOMPAT_CSUM_V3 is set, the descriptor block uses\n * journal_block_tag3_t to store a full 32-bit checksum.  Everything else\n * is the same as v2.\n *\n * Checksum v1, v2, and v3 are mutually exclusive features.\n */\n\nstruct jbd_commit_header {\n    struct jbd_bhdr header;\n    uint8_t chksum_type;\n    uint8_t chksum_size;\n    uint8_t padding[2];\n    uint32_t        chksum[JBD_CHECKSUM_BYTES];\n    uint64_t        commit_sec;\n    uint32_t        commit_nsec;\n};\n\n/*\n * The block tag: used to describe a single buffer in the journal\n */\nstruct jbd_block_tag3 {\n    uint32_t        blocknr;    /* The on-disk block number */\n    uint32_t        flags;  /* See below */\n    uint32_t        blocknr_high; /* most-significant high 32bits. */\n    uint32_t        checksum;   /* crc32c(uuid+seq+block) */\n};\n\nstruct jbd_block_tag {\n    uint32_t        blocknr;    /* The on-disk block number */\n    uint16_t        checksum;   /* truncated crc32c(uuid+seq+block) */\n    uint16_t        flags;  /* See below */\n    uint32_t        blocknr_high; /* most-significant high 32bits. */\n};\n\n#pragma pack(pop)\n\n/* Definitions for the journal tag flags word: */\n#define JBD_FLAG_ESCAPE     1   /* on-disk block is escaped */\n#define JBD_FLAG_SAME_UUID  2   /* block has same uuid as previous */\n#define JBD_FLAG_DELETED    4   /* block deleted by this transaction */\n#define JBD_FLAG_LAST_TAG   8   /* last tag in this descriptor block */\n\n#pragma pack(push, 1)\n\n/* Tail of descriptor block, for checksumming */\nstruct jbd_block_tail {\n    uint32_t    checksum;\n};\n\n/*\n * The revoke descriptor: used on disk to describe a series of blocks to\n * be revoked from the log\n */\nstruct jbd_revoke_header {\n    struct jbd_bhdr  header;\n    uint32_t     count; /* Count of bytes used in the block */\n};\n\n/* Tail of revoke block, for checksumming */\nstruct jbd_revoke_tail {\n    uint32_t        checksum;\n};\n\n#pragma pack(pop)\n\n#define JBD_USERS_MAX 48\n#define JBD_USERS_SIZE (UUID_SIZE * JBD_USERS_MAX)\n\n#pragma pack(push, 1)\n\n/*\n * The journal superblock.  All fields are in big-endian byte order.\n */\nstruct jbd_sb {\n/* 0x0000 */\n    struct jbd_bhdr header;\n\n/* 0x000C */\n    /* Static information describing the journal */\n    uint32_t    blocksize;      /* journal device blocksize */\n    uint32_t    maxlen;     /* total blocks in journal file */\n    uint32_t    first;      /* first block of log information */\n\n/* 0x0018 */\n    /* Dynamic information describing the current state of the log */\n    uint32_t    sequence;       /* first commit ID expected in log */\n    uint32_t    start;      /* blocknr of start of log */\n\n/* 0x0020 */\n    /* Error value, as set by journal_abort(). */\n    int32_t     error_val;\n\n/* 0x0024 */\n    /* Remaining fields are only valid in a version-2 superblock */\n    uint32_t    feature_compat;     /* compatible feature set */\n    uint32_t    feature_incompat;   /* incompatible feature set */\n    uint32_t    feature_ro_compat;  /* readonly-compatible feature set */\n/* 0x0030 */\n    uint8_t     uuid[UUID_SIZE];        /* 128-bit uuid for journal */\n\n/* 0x0040 */\n    uint32_t    nr_users;       /* Nr of filesystems sharing log */\n\n    uint32_t    dynsuper;       /* Blocknr of dynamic superblock copy*/\n\n/* 0x0048 */\n    uint32_t    max_transaction;    /* Limit of journal blocks per trans.*/\n    uint32_t    max_trandata;   /* Limit of data blocks per trans. */\n\n/* 0x0050 */\n    uint8_t     checksum_type;  /* checksum type */\n    uint8_t     padding2[3];\n    uint32_t    padding[42];\n    uint32_t    checksum;       /* crc32c(superblock) */\n\n/* 0x0100 */\n    uint8_t     users[JBD_USERS_SIZE];      /* ids of all fs'es sharing the log */\n\n/* 0x0400 */\n};\n\n#pragma pack(pop)\n\n#define JBD_SUPERBLOCK_SIZE sizeof(struct jbd_sb)\n\n#define JBD_HAS_COMPAT_FEATURE(jsb,mask)                    \\\n    ((jsb)->header.blocktype >= to_be32(2) &&               \\\n     ((jsb)->feature_compat & to_be32((mask))))\n#define JBD_HAS_RO_COMPAT_FEATURE(jsb,mask)             \\\n    ((jsb)->header.blocktype >= to_be32(2) &&               \\\n     ((jsb)->feature_ro_compat & to_be32((mask))))\n#define JBD_HAS_INCOMPAT_FEATURE(jsb,mask)              \\\n    ((jsb)->header.blocktype >= to_be32(2) &&               \\\n     ((jsb)->feature_incompat & to_be32((mask))))\n\n#define JBD_FEATURE_COMPAT_CHECKSUM 0x00000001\n\n#define JBD_FEATURE_INCOMPAT_REVOKE     0x00000001\n#define JBD_FEATURE_INCOMPAT_64BIT      0x00000002\n#define JBD_FEATURE_INCOMPAT_ASYNC_COMMIT   0x00000004\n#define JBD_FEATURE_INCOMPAT_CSUM_V2        0x00000008\n#define JBD_FEATURE_INCOMPAT_CSUM_V3        0x00000010\n\n/* Features known to this kernel version: */\n#define JBD_KNOWN_COMPAT_FEATURES   0\n#define JBD_KNOWN_ROCOMPAT_FEATURES 0\n#define JBD_KNOWN_INCOMPAT_FEATURES (JBD_FEATURE_INCOMPAT_REVOKE|\\\n                     JBD_FEATURE_INCOMPAT_ASYNC_COMMIT|\\\n                     JBD_FEATURE_INCOMPAT_64BIT|\\\n                     JBD_FEATURE_INCOMPAT_CSUM_V2|\\\n                     JBD_FEATURE_INCOMPAT_CSUM_V3)\n\n/*****************************************************************************/\n\n#define EXT4_CRC32_INIT (0xFFFFFFFFUL)\n\n/*****************************************************************************/\n\n#ifdef __cplusplus\n}\n#endif\n\n\n#if CONFIG_USE_USER_MALLOC\n\nextern void *ext4_user_malloc(size_t size);\nextern void *ext4_user_calloc(size_t numb, size_t size);\nextern void *ext4_user_free(void *mem);\nextern void *ext4_user_realloc(void *ptr, size_t size);\nextern void *ext4_user_alloc_bcache(size_t size);\n\n#define ext4_malloc  ext4_user_malloc\n#define ext4_calloc  ext4_user_calloc\n#define ext4_realloc ext4_user_realloc\n#define ext4_free    ext4_user_free\n#define ext4_alloc_bcache ext4_user_alloc_bcache\n\n#else\n\n#define ext4_malloc  malloc\n#define ext4_calloc  calloc\n#define ext4_realloc realloc\n#define ext4_free    free\n#define ext4_alloc_bcache malloc\n\n#endif\n\n\n#endif /* EXT4_TYPES_H_ */\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/ext4_xattr.h",
    "content": "/*\n * Copyright (c) 2015 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * Copyright (c) 2015 Kaho Ng (ngkaho1234@gmail.com)\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_xattr.h\n * @brief Extended Attribute manipulation.\n */\n\n#ifndef EXT4_XATTR_H_\n#define EXT4_XATTR_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_inode.h>\n\nstruct ext4_xattr_info {\n    uint8_t name_index;\n    const char *name;\n    size_t name_len;\n    const void *value;\n    size_t value_len;\n};\n\nstruct ext4_xattr_list_entry {\n    uint8_t name_index;\n    char *name;\n    size_t name_len;\n    struct ext4_xattr_list_entry *next;\n};\n\nstruct ext4_xattr_search {\n    /* The first entry in the buffer */\n    struct ext4_xattr_entry *first;\n\n    /* The address of the buffer */\n    void *base;\n\n    /* The first inaccessible address */\n    void *end;\n\n    /* The current entry pointer */\n    struct ext4_xattr_entry *here;\n\n    /* Entry not found */\n    bool not_found;\n};\n\nconst char *ext4_extract_xattr_name(const char *full_name, size_t full_name_len,\n                    uint8_t *name_index, size_t *name_len,\n                    bool *found);\n\nconst char *ext4_get_xattr_name_prefix(uint8_t name_index,\n                       size_t *ret_prefix_len);\n\nint ext4_xattr_list(struct ext4_inode_ref *inode_ref,\n            struct ext4_xattr_list_entry *list, size_t *list_len);\n\nint ext4_xattr_get(struct ext4_inode_ref *inode_ref, uint8_t name_index,\n           const char *name, size_t name_len, void *buf, size_t buf_len,\n           size_t *data_len);\n\nint ext4_xattr_remove(struct ext4_inode_ref *inode_ref, uint8_t name_index,\n              const char *name, size_t name_len);\n\nint ext4_xattr_set(struct ext4_inode_ref *inode_ref, uint8_t name_index,\n           const char *name, size_t name_len, const void *value,\n           size_t value_len);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/misc/queue.h",
    "content": "/*-\n * Copyright (c) 1991, 1993\n *  The Regents of the University of California.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 4. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *  @(#)queue.h 8.5 (Berkeley) 8/20/94\n * $FreeBSD$\n */\n\n#ifndef _SYS_QUEUE_H_\n#define _SYS_QUEUE_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"../ext4_config.h\"\n\n/*\n * This file defines four types of data structures: singly-linked lists,\n * singly-linked tail queues, lists and tail queues.\n *\n * A singly-linked list is headed by a single forward pointer. The elements\n * are singly linked for minimum space and pointer manipulation overhead at\n * the expense of O(n) removal for arbitrary elements. New elements can be\n * added to the list after an existing element or at the head of the list.\n * Elements being removed from the head of the list should use the explicit\n * macro for this purpose for optimum efficiency. A singly-linked list may\n * only be traversed in the forward direction.  Singly-linked lists are ideal\n * for applications with large datasets and few or no removals or for\n * implementing a LIFO queue.\n *\n * A singly-linked tail queue is headed by a pair of pointers, one to the\n * head of the list and the other to the tail of the list. The elements are\n * singly linked for minimum space and pointer manipulation overhead at the\n * expense of O(n) removal for arbitrary elements. New elements can be added\n * to the list after an existing element, at the head of the list, or at the\n * end of the list. Elements being removed from the head of the tail queue\n * should use the explicit macro for this purpose for optimum efficiency.\n * A singly-linked tail queue may only be traversed in the forward direction.\n * Singly-linked tail queues are ideal for applications with large datasets\n * and few or no removals or for implementing a FIFO queue.\n *\n * A list is headed by a single forward pointer (or an array of forward\n * pointers for a hash table header). The elements are doubly linked\n * so that an arbitrary element can be removed without a need to\n * traverse the list. New elements can be added to the list before\n * or after an existing element or at the head of the list. A list\n * may be traversed in either direction.\n *\n * A tail queue is headed by a pair of pointers, one to the head of the\n * list and the other to the tail of the list. The elements are doubly\n * linked so that an arbitrary element can be removed without a need to\n * traverse the list. New elements can be added to the list before or\n * after an existing element, at the head of the list, or at the end of\n * the list. A tail queue may be traversed in either direction.\n *\n * For details on the use of these macros, see the queue(3) manual page.\n *\n *\n *              SLIST   LIST    STAILQ  TAILQ\n * _HEAD            +   +   +   +\n * _HEAD_INITIALIZER        +   +   +   +\n * _ENTRY           +   +   +   +\n * _INIT            +   +   +   +\n * _EMPTY           +   +   +   +\n * _FIRST           +   +   +   +\n * _NEXT            +   +   +   +\n * _PREV            -   +   -   +\n * _LAST            -   -   +   +\n * _FOREACH         +   +   +   +\n * _FOREACH_FROM        +   +   +   +\n * _FOREACH_SAFE        +   +   +   +\n * _FOREACH_FROM_SAFE       +   +   +   +\n * _FOREACH_REVERSE     -   -   -   +\n * _FOREACH_REVERSE_FROM    -   -   -   +\n * _FOREACH_REVERSE_SAFE    -   -   -   +\n * _FOREACH_REVERSE_FROM_SAFE   -   -   -   +\n * _INSERT_HEAD         +   +   +   +\n * _INSERT_BEFORE       -   +   -   +\n * _INSERT_AFTER        +   +   +   +\n * _INSERT_TAIL         -   -   +   +\n * _CONCAT          -   -   +   +\n * _REMOVE_AFTER        +   -   +   -\n * _REMOVE_HEAD         +   -   +   -\n * _REMOVE          +   +   +   +\n * _SWAP            +   +   +   +\n *\n */\n#ifdef QUEUE_MACRO_DEBUG\n/* Store the last 2 places the queue element or head was altered */\nstruct qm_trace {\n    unsigned long    lastline;\n    unsigned long    prevline;\n    const char  *lastfile;\n    const char  *prevfile;\n};\n\n#define TRACEBUF    struct qm_trace trace;\n#define TRACEBUF_INITIALIZER    { __LINE__, 0, __FILE__, NULL } ,\n#define TRASHIT(x)  do {(x) = (void *)-1;} while (0)\n#define QMD_SAVELINK(name, link)    void **name = (void *)&(link)\n\n#define QMD_TRACE_HEAD(head) do {                   \\\n    (head)->trace.prevline = (head)->trace.lastline;        \\\n    (head)->trace.prevfile = (head)->trace.lastfile;        \\\n    (head)->trace.lastline = __LINE__;              \\\n    (head)->trace.lastfile = __FILE__;              \\\n} while (0)\n\n#define QMD_TRACE_ELEM(elem) do {                   \\\n    (elem)->trace.prevline = (elem)->trace.lastline;        \\\n    (elem)->trace.prevfile = (elem)->trace.lastfile;        \\\n    (elem)->trace.lastline = __LINE__;              \\\n    (elem)->trace.lastfile = __FILE__;              \\\n} while (0)\n\n#else\n#define QMD_TRACE_ELEM(elem)\n#define QMD_TRACE_HEAD(head)\n#define QMD_SAVELINK(name, link)\n#define TRACEBUF\n#define TRACEBUF_INITIALIZER\n#define TRASHIT(x)\n#endif  /* QUEUE_MACRO_DEBUG */\n\n/*\n * Singly-linked List declarations.\n */\n#define SLIST_HEAD(name, type)                      \\\nstruct name {                               \\\n    struct type *slh_first; /* first element */         \\\n}\n\n#define SLIST_HEAD_INITIALIZER(head)                    \\\n    { NULL }\n\n#define SLIST_ENTRY(type)                       \\\nstruct {                                \\\n    struct type *sle_next;  /* next element */          \\\n}\n\n/*\n * Singly-linked List functions.\n */\n#define SLIST_EMPTY(head)   ((head)->slh_first == NULL)\n\n#define SLIST_FIRST(head)   ((head)->slh_first)\n\n#define SLIST_FOREACH(var, head, field)                 \\\n    for ((var) = SLIST_FIRST((head));               \\\n        (var);                          \\\n        (var) = SLIST_NEXT((var), field))\n\n#define SLIST_FOREACH_FROM(var, head, field)                \\\n    for ((var) = ((var) ? (var) : SLIST_FIRST((head)));     \\\n        (var);                          \\\n        (var) = SLIST_NEXT((var), field))\n\n#define SLIST_FOREACH_SAFE(var, head, field, tvar)          \\\n    for ((var) = SLIST_FIRST((head));               \\\n        (var) && ((tvar) = SLIST_NEXT((var), field), 1);        \\\n        (var) = (tvar))\n\n#define SLIST_FOREACH_FROM_SAFE(var, head, field, tvar)         \\\n    for ((var) = ((var) ? (var) : SLIST_FIRST((head)));     \\\n        (var) && ((tvar) = SLIST_NEXT((var), field), 1);        \\\n        (var) = (tvar))\n\n#define SLIST_FOREACH_PREVPTR(var, varp, head, field)           \\\n    for ((varp) = &SLIST_FIRST((head));             \\\n        ((var) = *(varp)) != NULL;                  \\\n        (varp) = &SLIST_NEXT((var), field))\n\n#define SLIST_INIT(head) do {                       \\\n    SLIST_FIRST((head)) = NULL;                 \\\n} while (0)\n\n#define SLIST_INSERT_AFTER(slistelm, elm, field) do {           \\\n    SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field);   \\\n    SLIST_NEXT((slistelm), field) = (elm);              \\\n} while (0)\n\n#define SLIST_INSERT_HEAD(head, elm, field) do {            \\\n    SLIST_NEXT((elm), field) = SLIST_FIRST((head));         \\\n    SLIST_FIRST((head)) = (elm);                    \\\n} while (0)\n\n#define SLIST_NEXT(elm, field)  ((elm)->field.sle_next)\n\n#define SLIST_REMOVE(head, elm, type, field) do {           \\\n    QMD_SAVELINK(oldnext, (elm)->field.sle_next);           \\\n    if (SLIST_FIRST((head)) == (elm)) {             \\\n        SLIST_REMOVE_HEAD((head), field);           \\\n    }                               \\\n    else {                              \\\n        struct type *curelm = SLIST_FIRST((head));      \\\n        while (SLIST_NEXT(curelm, field) != (elm))      \\\n            curelm = SLIST_NEXT(curelm, field);     \\\n        SLIST_REMOVE_AFTER(curelm, field);          \\\n    }                               \\\n    TRASHIT(*oldnext);                      \\\n} while (0)\n\n#define SLIST_REMOVE_AFTER(elm, field) do {             \\\n    SLIST_NEXT(elm, field) =                    \\\n        SLIST_NEXT(SLIST_NEXT(elm, field), field);          \\\n} while (0)\n\n#define SLIST_REMOVE_HEAD(head, field) do {             \\\n    SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field);   \\\n} while (0)\n\n#define SLIST_SWAP(head1, head2, type) do {             \\\n    struct type *swap_first = SLIST_FIRST(head1);           \\\n    SLIST_FIRST(head1) = SLIST_FIRST(head2);            \\\n    SLIST_FIRST(head2) = swap_first;                \\\n} while (0)\n\n/*\n * Singly-linked Tail queue declarations.\n */\n#define STAILQ_HEAD(name, type)                     \\\nstruct name {                               \\\n    struct type *stqh_first;/* first element */         \\\n    struct type **stqh_last;/* addr of last next element */     \\\n}\n\n#define STAILQ_HEAD_INITIALIZER(head)                   \\\n    { NULL, &(head).stqh_first }\n\n#define STAILQ_ENTRY(type)                      \\\nstruct {                                \\\n    struct type *stqe_next; /* next element */          \\\n}\n\n/*\n * Singly-linked Tail queue functions.\n */\n#define STAILQ_CONCAT(head1, head2) do {                \\\n    if (!STAILQ_EMPTY((head2))) {                   \\\n        *(head1)->stqh_last = (head2)->stqh_first;      \\\n        (head1)->stqh_last = (head2)->stqh_last;        \\\n        STAILQ_INIT((head2));                   \\\n    }                               \\\n} while (0)\n\n#define STAILQ_EMPTY(head)  ((head)->stqh_first == NULL)\n\n#define STAILQ_FIRST(head)  ((head)->stqh_first)\n\n#define STAILQ_FOREACH(var, head, field)                \\\n    for((var) = STAILQ_FIRST((head));               \\\n       (var);                           \\\n       (var) = STAILQ_NEXT((var), field))\n\n#define STAILQ_FOREACH_FROM(var, head, field)               \\\n    for ((var) = ((var) ? (var) : STAILQ_FIRST((head)));        \\\n       (var);                           \\\n       (var) = STAILQ_NEXT((var), field))\n\n#define STAILQ_FOREACH_SAFE(var, head, field, tvar)         \\\n    for ((var) = STAILQ_FIRST((head));              \\\n        (var) && ((tvar) = STAILQ_NEXT((var), field), 1);       \\\n        (var) = (tvar))\n\n#define STAILQ_FOREACH_FROM_SAFE(var, head, field, tvar)        \\\n    for ((var) = ((var) ? (var) : STAILQ_FIRST((head)));        \\\n        (var) && ((tvar) = STAILQ_NEXT((var), field), 1);       \\\n        (var) = (tvar))\n\n#define STAILQ_INIT(head) do {                      \\\n    STAILQ_FIRST((head)) = NULL;                    \\\n    (head)->stqh_last = &STAILQ_FIRST((head));          \\\n} while (0)\n\n#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {       \\\n    if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\\\n        (head)->stqh_last = &STAILQ_NEXT((elm), field);     \\\n    STAILQ_NEXT((tqelm), field) = (elm);                \\\n} while (0)\n\n#define STAILQ_INSERT_HEAD(head, elm, field) do {           \\\n    if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \\\n        (head)->stqh_last = &STAILQ_NEXT((elm), field);     \\\n    STAILQ_FIRST((head)) = (elm);                   \\\n} while (0)\n\n#define STAILQ_INSERT_TAIL(head, elm, field) do {           \\\n    STAILQ_NEXT((elm), field) = NULL;               \\\n    *(head)->stqh_last = (elm);                 \\\n    (head)->stqh_last = &STAILQ_NEXT((elm), field);         \\\n} while (0)\n\n#define STAILQ_LAST(head, type, field)                  \\\n    (STAILQ_EMPTY((head)) ? NULL :                  \\\n        __containerof((head)->stqh_last, struct type, field.stqe_next))\n\n#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)\n\n#define STAILQ_REMOVE(head, elm, type, field) do {          \\\n    QMD_SAVELINK(oldnext, (elm)->field.stqe_next);          \\\n    if (STAILQ_FIRST((head)) == (elm)) {                \\\n        STAILQ_REMOVE_HEAD((head), field);          \\\n    }                               \\\n    else {                              \\\n        struct type *curelm = STAILQ_FIRST((head));     \\\n        while (STAILQ_NEXT(curelm, field) != (elm))     \\\n            curelm = STAILQ_NEXT(curelm, field);        \\\n        STAILQ_REMOVE_AFTER(head, curelm, field);       \\\n    }                               \\\n    TRASHIT(*oldnext);                      \\\n} while (0)\n\n#define STAILQ_REMOVE_AFTER(head, elm, field) do {          \\\n    if ((STAILQ_NEXT(elm, field) =                  \\\n         STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL)  \\\n        (head)->stqh_last = &STAILQ_NEXT((elm), field);     \\\n} while (0)\n\n#define STAILQ_REMOVE_HEAD(head, field) do {                \\\n    if ((STAILQ_FIRST((head)) =                 \\\n         STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)     \\\n        (head)->stqh_last = &STAILQ_FIRST((head));      \\\n} while (0)\n\n#define STAILQ_SWAP(head1, head2, type) do {                \\\n    struct type *swap_first = STAILQ_FIRST(head1);          \\\n    struct type **swap_last = (head1)->stqh_last;           \\\n    STAILQ_FIRST(head1) = STAILQ_FIRST(head2);          \\\n    (head1)->stqh_last = (head2)->stqh_last;            \\\n    STAILQ_FIRST(head2) = swap_first;               \\\n    (head2)->stqh_last = swap_last;                 \\\n    if (STAILQ_EMPTY(head1))                    \\\n        (head1)->stqh_last = &STAILQ_FIRST(head1);      \\\n    if (STAILQ_EMPTY(head2))                    \\\n        (head2)->stqh_last = &STAILQ_FIRST(head2);      \\\n} while (0)\n\n\n/*\n * List declarations.\n */\n#define LIST_HEAD(name, type)                       \\\nstruct name {                               \\\n    struct type *lh_first;  /* first element */         \\\n}\n\n#define LIST_HEAD_INITIALIZER(head)                 \\\n    { NULL }\n\n#define LIST_ENTRY(type)                        \\\nstruct {                                \\\n    struct type *le_next;   /* next element */          \\\n    struct type **le_prev;  /* address of previous next element */  \\\n}\n\n/*\n * List functions.\n */\n\n#if (defined(_KERNEL) && defined(INVARIANTS))\n#define QMD_LIST_CHECK_HEAD(head, field) do {               \\\n    if (LIST_FIRST((head)) != NULL &&               \\\n        LIST_FIRST((head))->field.le_prev !=            \\\n         &LIST_FIRST((head)))                   \\\n        panic(\"Bad list head %p first->prev != head\", (head));  \\\n} while (0)\n\n#define QMD_LIST_CHECK_NEXT(elm, field) do {                \\\n    if (LIST_NEXT((elm), field) != NULL &&              \\\n        LIST_NEXT((elm), field)->field.le_prev !=           \\\n         &((elm)->field.le_next))                   \\\n            panic(\"Bad link elm %p next->prev != elm\", (elm));  \\\n} while (0)\n\n#define QMD_LIST_CHECK_PREV(elm, field) do {                \\\n    if (*(elm)->field.le_prev != (elm))             \\\n        panic(\"Bad link elm %p prev->next != elm\", (elm));  \\\n} while (0)\n#else\n#define QMD_LIST_CHECK_HEAD(head, field)\n#define QMD_LIST_CHECK_NEXT(elm, field)\n#define QMD_LIST_CHECK_PREV(elm, field)\n#endif /* (_KERNEL && INVARIANTS) */\n\n#define LIST_EMPTY(head)    ((head)->lh_first == NULL)\n\n#define LIST_FIRST(head)    ((head)->lh_first)\n\n#define LIST_FOREACH(var, head, field)                  \\\n    for ((var) = LIST_FIRST((head));                \\\n        (var);                          \\\n        (var) = LIST_NEXT((var), field))\n\n#define LIST_FOREACH_FROM(var, head, field)             \\\n    for ((var) = ((var) ? (var) : LIST_FIRST((head)));      \\\n        (var);                          \\\n        (var) = LIST_NEXT((var), field))\n\n#define LIST_FOREACH_SAFE(var, head, field, tvar)           \\\n    for ((var) = LIST_FIRST((head));                \\\n        (var) && ((tvar) = LIST_NEXT((var), field), 1);     \\\n        (var) = (tvar))\n\n#define LIST_FOREACH_FROM_SAFE(var, head, field, tvar)          \\\n    for ((var) = ((var) ? (var) : LIST_FIRST((head)));      \\\n        (var) && ((tvar) = LIST_NEXT((var), field), 1);     \\\n        (var) = (tvar))\n\n#define LIST_INIT(head) do {                        \\\n    LIST_FIRST((head)) = NULL;                  \\\n} while (0)\n\n#define LIST_INSERT_AFTER(listelm, elm, field) do {         \\\n    QMD_LIST_CHECK_NEXT(listelm, field);                \\\n    if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\\\n        LIST_NEXT((listelm), field)->field.le_prev =        \\\n            &LIST_NEXT((elm), field);               \\\n    LIST_NEXT((listelm), field) = (elm);                \\\n    (elm)->field.le_prev = &LIST_NEXT((listelm), field);        \\\n} while (0)\n\n#define LIST_INSERT_BEFORE(listelm, elm, field) do {            \\\n    QMD_LIST_CHECK_PREV(listelm, field);                \\\n    (elm)->field.le_prev = (listelm)->field.le_prev;        \\\n    LIST_NEXT((elm), field) = (listelm);                \\\n    *(listelm)->field.le_prev = (elm);              \\\n    (listelm)->field.le_prev = &LIST_NEXT((elm), field);        \\\n} while (0)\n\n#define LIST_INSERT_HEAD(head, elm, field) do {             \\\n    QMD_LIST_CHECK_HEAD((head), field);             \\\n    if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \\\n        LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\\\n    LIST_FIRST((head)) = (elm);                 \\\n    (elm)->field.le_prev = &LIST_FIRST((head));         \\\n} while (0)\n\n#define LIST_NEXT(elm, field)   ((elm)->field.le_next)\n\n#define LIST_PREV(elm, head, type, field)               \\\n    ((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL :       \\\n        __containerof((elm)->field.le_prev, struct type, field.le_next))\n\n#define LIST_REMOVE(elm, field) do {                    \\\n    QMD_SAVELINK(oldnext, (elm)->field.le_next);            \\\n    QMD_SAVELINK(oldprev, (elm)->field.le_prev);            \\\n    QMD_LIST_CHECK_NEXT(elm, field);                \\\n    QMD_LIST_CHECK_PREV(elm, field);                \\\n    if (LIST_NEXT((elm), field) != NULL)                \\\n        LIST_NEXT((elm), field)->field.le_prev =        \\\n            (elm)->field.le_prev;               \\\n    *(elm)->field.le_prev = LIST_NEXT((elm), field);        \\\n    TRASHIT(*oldnext);                      \\\n    TRASHIT(*oldprev);                      \\\n} while (0)\n\n#define LIST_SWAP(head1, head2, type, field) do {           \\\n    struct type *swap_tmp = LIST_FIRST((head1));            \\\n    LIST_FIRST((head1)) = LIST_FIRST((head2));          \\\n    LIST_FIRST((head2)) = swap_tmp;                 \\\n    if ((swap_tmp = LIST_FIRST((head1))) != NULL)           \\\n        swap_tmp->field.le_prev = &LIST_FIRST((head1));     \\\n    if ((swap_tmp = LIST_FIRST((head2))) != NULL)           \\\n        swap_tmp->field.le_prev = &LIST_FIRST((head2));     \\\n} while (0)\n\n/*\n * Tail queue declarations.\n */\n#define TAILQ_HEAD(name, type)                      \\\nstruct name {                               \\\n    struct type *tqh_first; /* first element */         \\\n    struct type **tqh_last; /* addr of last next element */     \\\n    TRACEBUF                            \\\n}\n\n#define TAILQ_HEAD_INITIALIZER(head)                    \\\n    { NULL, &(head).tqh_first, TRACEBUF_INITIALIZER }\n\n#define TAILQ_ENTRY(type)                       \\\nstruct {                                \\\n    struct type *tqe_next;  /* next element */          \\\n    struct type **tqe_prev; /* address of previous next element */  \\\n    TRACEBUF                            \\\n}\n\n/*\n * Tail queue functions.\n */\n#if (defined(_KERNEL) && defined(INVARIANTS))\n#define QMD_TAILQ_CHECK_HEAD(head, field) do {              \\\n    if (!TAILQ_EMPTY(head) &&                   \\\n        TAILQ_FIRST((head))->field.tqe_prev !=          \\\n         &TAILQ_FIRST((head)))                  \\\n        panic(\"Bad tailq head %p first->prev != head\", (head)); \\\n} while (0)\n\n#define QMD_TAILQ_CHECK_TAIL(head, field) do {              \\\n    if (*(head)->tqh_last != NULL)                  \\\n            panic(\"Bad tailq NEXT(%p->tqh_last) != NULL\", (head));  \\\n} while (0)\n\n#define QMD_TAILQ_CHECK_NEXT(elm, field) do {               \\\n    if (TAILQ_NEXT((elm), field) != NULL &&             \\\n        TAILQ_NEXT((elm), field)->field.tqe_prev !=         \\\n         &((elm)->field.tqe_next))                  \\\n        panic(\"Bad link elm %p next->prev != elm\", (elm));  \\\n} while (0)\n\n#define QMD_TAILQ_CHECK_PREV(elm, field) do {               \\\n    if (*(elm)->field.tqe_prev != (elm))                \\\n        panic(\"Bad link elm %p prev->next != elm\", (elm));  \\\n} while (0)\n#else\n#define QMD_TAILQ_CHECK_HEAD(head, field)\n#define QMD_TAILQ_CHECK_TAIL(head, headname)\n#define QMD_TAILQ_CHECK_NEXT(elm, field)\n#define QMD_TAILQ_CHECK_PREV(elm, field)\n#endif /* (_KERNEL && INVARIANTS) */\n\n#define TAILQ_CONCAT(head1, head2, field) do {              \\\n    if (!TAILQ_EMPTY(head2)) {                  \\\n        *(head1)->tqh_last = (head2)->tqh_first;        \\\n        (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \\\n        (head1)->tqh_last = (head2)->tqh_last;          \\\n        TAILQ_INIT((head2));                    \\\n        QMD_TRACE_HEAD(head1);                  \\\n        QMD_TRACE_HEAD(head2);                  \\\n    }                               \\\n} while (0)\n\n#define TAILQ_EMPTY(head)   ((head)->tqh_first == NULL)\n\n#define TAILQ_FIRST(head)   ((head)->tqh_first)\n\n#define TAILQ_FOREACH(var, head, field)                 \\\n    for ((var) = TAILQ_FIRST((head));               \\\n        (var);                          \\\n        (var) = TAILQ_NEXT((var), field))\n\n#define TAILQ_FOREACH_FROM(var, head, field)                \\\n    for ((var) = ((var) ? (var) : TAILQ_FIRST((head)));     \\\n        (var);                          \\\n        (var) = TAILQ_NEXT((var), field))\n\n#define TAILQ_FOREACH_SAFE(var, head, field, tvar)          \\\n    for ((var) = TAILQ_FIRST((head));               \\\n        (var) && ((tvar) = TAILQ_NEXT((var), field), 1);        \\\n        (var) = (tvar))\n\n#define TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar)         \\\n    for ((var) = ((var) ? (var) : TAILQ_FIRST((head)));     \\\n        (var) && ((tvar) = TAILQ_NEXT((var), field), 1);        \\\n        (var) = (tvar))\n\n#define TAILQ_FOREACH_REVERSE(var, head, headname, field)       \\\n    for ((var) = TAILQ_LAST((head), headname);          \\\n        (var);                          \\\n        (var) = TAILQ_PREV((var), headname, field))\n\n#define TAILQ_FOREACH_REVERSE_FROM(var, head, headname, field)      \\\n    for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname));    \\\n        (var);                          \\\n        (var) = TAILQ_PREV((var), headname, field))\n\n#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)    \\\n    for ((var) = TAILQ_LAST((head), headname);          \\\n        (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1);  \\\n        (var) = (tvar))\n\n#define TAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar) \\\n    for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname));    \\\n        (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1);  \\\n        (var) = (tvar))\n\n#define TAILQ_INIT(head) do {                       \\\n    TAILQ_FIRST((head)) = NULL;                 \\\n    (head)->tqh_last = &TAILQ_FIRST((head));            \\\n    QMD_TRACE_HEAD(head);                       \\\n} while (0)\n\n#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {      \\\n    QMD_TAILQ_CHECK_NEXT(listelm, field);               \\\n    if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\\\n        TAILQ_NEXT((elm), field)->field.tqe_prev =      \\\n            &TAILQ_NEXT((elm), field);              \\\n    else {                              \\\n        (head)->tqh_last = &TAILQ_NEXT((elm), field);       \\\n        QMD_TRACE_HEAD(head);                   \\\n    }                               \\\n    TAILQ_NEXT((listelm), field) = (elm);               \\\n    (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field);      \\\n    QMD_TRACE_ELEM(&(elm)->field);                  \\\n    QMD_TRACE_ELEM(&(listelm)->field);              \\\n} while (0)\n\n#define TAILQ_INSERT_BEFORE(listelm, elm, field) do {           \\\n    QMD_TAILQ_CHECK_PREV(listelm, field);               \\\n    (elm)->field.tqe_prev = (listelm)->field.tqe_prev;      \\\n    TAILQ_NEXT((elm), field) = (listelm);               \\\n    *(listelm)->field.tqe_prev = (elm);             \\\n    (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field);      \\\n    QMD_TRACE_ELEM(&(elm)->field);                  \\\n    QMD_TRACE_ELEM(&(listelm)->field);              \\\n} while (0)\n\n#define TAILQ_INSERT_HEAD(head, elm, field) do {            \\\n    QMD_TAILQ_CHECK_HEAD(head, field);              \\\n    if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)   \\\n        TAILQ_FIRST((head))->field.tqe_prev =           \\\n            &TAILQ_NEXT((elm), field);              \\\n    else                                \\\n        (head)->tqh_last = &TAILQ_NEXT((elm), field);       \\\n    TAILQ_FIRST((head)) = (elm);                    \\\n    (elm)->field.tqe_prev = &TAILQ_FIRST((head));           \\\n    QMD_TRACE_HEAD(head);                       \\\n    QMD_TRACE_ELEM(&(elm)->field);                  \\\n} while (0)\n\n#define TAILQ_INSERT_TAIL(head, elm, field) do {            \\\n    QMD_TAILQ_CHECK_TAIL(head, field);              \\\n    TAILQ_NEXT((elm), field) = NULL;                \\\n    (elm)->field.tqe_prev = (head)->tqh_last;           \\\n    *(head)->tqh_last = (elm);                  \\\n    (head)->tqh_last = &TAILQ_NEXT((elm), field);           \\\n    QMD_TRACE_HEAD(head);                       \\\n    QMD_TRACE_ELEM(&(elm)->field);                  \\\n} while (0)\n\n#define TAILQ_LAST(head, headname)                  \\\n    (*(((struct headname *)((head)->tqh_last))->tqh_last))\n\n#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)\n\n#define TAILQ_PREV(elm, headname, field)                \\\n    (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))\n\n#define TAILQ_REMOVE(head, elm, field) do {             \\\n    QMD_SAVELINK(oldnext, (elm)->field.tqe_next);           \\\n    QMD_SAVELINK(oldprev, (elm)->field.tqe_prev);           \\\n    QMD_TAILQ_CHECK_NEXT(elm, field);               \\\n    QMD_TAILQ_CHECK_PREV(elm, field);               \\\n    if ((TAILQ_NEXT((elm), field)) != NULL)             \\\n        TAILQ_NEXT((elm), field)->field.tqe_prev =      \\\n            (elm)->field.tqe_prev;              \\\n    else {                              \\\n        (head)->tqh_last = (elm)->field.tqe_prev;       \\\n        QMD_TRACE_HEAD(head);                   \\\n    }                               \\\n    *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);      \\\n    TRASHIT(*oldnext);                      \\\n    TRASHIT(*oldprev);                      \\\n    QMD_TRACE_ELEM(&(elm)->field);                  \\\n} while (0)\n\n#define TAILQ_SWAP(head1, head2, type, field) do {          \\\n    struct type *swap_first = (head1)->tqh_first;           \\\n    struct type **swap_last = (head1)->tqh_last;            \\\n    (head1)->tqh_first = (head2)->tqh_first;            \\\n    (head1)->tqh_last = (head2)->tqh_last;              \\\n    (head2)->tqh_first = swap_first;                \\\n    (head2)->tqh_last = swap_last;                  \\\n    if ((swap_first = (head1)->tqh_first) != NULL)          \\\n        swap_first->field.tqe_prev = &(head1)->tqh_first;   \\\n    else                                \\\n        (head1)->tqh_last = &(head1)->tqh_first;        \\\n    if ((swap_first = (head2)->tqh_first) != NULL)          \\\n        swap_first->field.tqe_prev = &(head2)->tqh_first;   \\\n    else                                \\\n        (head2)->tqh_last = &(head2)->tqh_first;        \\\n} while (0)\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* !_SYS_QUEUE_H_ */\n"
  },
  {
    "path": "user.libs/liblwext4/include/lwext4/misc/tree.h",
    "content": "/*  $NetBSD: tree.h,v 1.8 2004/03/28 19:38:30 provos Exp $  */\n/*  $OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $    */\n/* $FreeBSD$ */\n\n/*-\n * Copyright 2002 Niels Provos <provos@citi.umich.edu>\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifndef _SYS_TREE_H_\n#define _SYS_TREE_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"../ext4_config.h\"\n\n/*\n * This file defines data structures for different types of trees:\n * splay trees and red-black trees.\n *\n * A splay tree is a self-organizing data structure.  Every operation\n * on the tree causes a splay to happen.  The splay moves the requested\n * node to the root of the tree and partly rebalances it.\n *\n * This has the benefit that request locality causes faster lookups as\n * the requested nodes move to the top of the tree.  On the other hand,\n * every lookup causes memory writes.\n *\n * The Balance Theorem bounds the total access time for m operations\n * and n inserts on an initially empty tree as O((m + n)lg n).  The\n * amortized cost for a sequence of m accesses to a splay tree is O(lg n);\n *\n * A red-black tree is a binary search tree with the node color as an\n * extra attribute.  It fulfills a set of conditions:\n *  - every search path from the root to a leaf consists of the\n *    same number of black nodes,\n *  - each red node (except for the root) has a black parent,\n *  - each leaf node is black.\n *\n * Every operation on a red-black tree is bounded as O(lg n).\n * The maximum height of a red-black tree is 2lg (n+1).\n */\n\n#define SPLAY_HEAD(name, type)                      \\\nstruct name {                               \\\n    struct type *sph_root; /* root of the tree */           \\\n}\n\n#define SPLAY_INITIALIZER(root)                     \\\n    { NULL }\n\n#define SPLAY_INIT(root) do {                       \\\n    (root)->sph_root = NULL;                    \\\n} while (/*CONSTCOND*/ 0)\n\n#define SPLAY_ENTRY(type)                       \\\nstruct {                                \\\n    struct type *spe_left; /* left element */           \\\n    struct type *spe_right; /* right element */         \\\n}\n\n#define SPLAY_LEFT(elm, field)      (elm)->field.spe_left\n#define SPLAY_RIGHT(elm, field)     (elm)->field.spe_right\n#define SPLAY_ROOT(head)        (head)->sph_root\n#define SPLAY_EMPTY(head)       (SPLAY_ROOT(head) == NULL)\n\n/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */\n#define SPLAY_ROTATE_RIGHT(head, tmp, field) do {           \\\n    SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field);  \\\n    SPLAY_RIGHT(tmp, field) = (head)->sph_root;         \\\n    (head)->sph_root = tmp;                     \\\n} while (/*CONSTCOND*/ 0)\n\n#define SPLAY_ROTATE_LEFT(head, tmp, field) do {            \\\n    SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field);  \\\n    SPLAY_LEFT(tmp, field) = (head)->sph_root;          \\\n    (head)->sph_root = tmp;                     \\\n} while (/*CONSTCOND*/ 0)\n\n#define SPLAY_LINKLEFT(head, tmp, field) do {               \\\n    SPLAY_LEFT(tmp, field) = (head)->sph_root;          \\\n    tmp = (head)->sph_root;                     \\\n    (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);     \\\n} while (/*CONSTCOND*/ 0)\n\n#define SPLAY_LINKRIGHT(head, tmp, field) do {              \\\n    SPLAY_RIGHT(tmp, field) = (head)->sph_root;         \\\n    tmp = (head)->sph_root;                     \\\n    (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);    \\\n} while (/*CONSTCOND*/ 0)\n\n#define SPLAY_ASSEMBLE(head, node, left, right, field) do {     \\\n    SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \\\n    SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\\\n    SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \\\n    SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \\\n} while (/*CONSTCOND*/ 0)\n\n/* Generates prototypes and inline functions */\n\n#define SPLAY_PROTOTYPE(name, type, field, cmp)             \\\nvoid name##_SPLAY(struct name *, struct type *);            \\\nvoid name##_SPLAY_MINMAX(struct name *, int);               \\\nstruct type *name##_SPLAY_INSERT(struct name *, struct type *);     \\\nstruct type *name##_SPLAY_REMOVE(struct name *, struct type *);     \\\n                                    \\\n/* Finds the node with the same key as elm */               \\\nstatic __inline struct type *                       \\\nname##_SPLAY_FIND(struct name *head, struct type *elm)          \\\n{                                   \\\n    if (SPLAY_EMPTY(head))                      \\\n        return(NULL);                       \\\n    name##_SPLAY(head, elm);                    \\\n    if ((cmp)(elm, (head)->sph_root) == 0)              \\\n        return (head->sph_root);                \\\n    return (NULL);                          \\\n}                                   \\\n                                    \\\nstatic __inline struct type *                       \\\nname##_SPLAY_NEXT(struct name *head, struct type *elm)          \\\n{                                   \\\n    name##_SPLAY(head, elm);                    \\\n    if (SPLAY_RIGHT(elm, field) != NULL) {              \\\n        elm = SPLAY_RIGHT(elm, field);              \\\n        while (SPLAY_LEFT(elm, field) != NULL) {        \\\n            elm = SPLAY_LEFT(elm, field);           \\\n        }                           \\\n    } else                              \\\n        elm = NULL;                     \\\n    return (elm);                           \\\n}                                   \\\n                                    \\\nstatic __inline struct type *                       \\\nname##_SPLAY_MIN_MAX(struct name *head, int val)            \\\n{                                   \\\n    name##_SPLAY_MINMAX(head, val);                 \\\n        return (SPLAY_ROOT(head));                  \\\n}\n\n/* Main splay operation.\n * Moves node close to the key of elm to top\n */\n#define SPLAY_GENERATE(name, type, field, cmp)              \\\nstruct type *                               \\\nname##_SPLAY_INSERT(struct name *head, struct type *elm)        \\\n{                                   \\\n    if (SPLAY_EMPTY(head)) {                        \\\n        SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL;    \\\n    } else {                                \\\n        int __comp;                         \\\n        name##_SPLAY(head, elm);                    \\\n        __comp = (cmp)(elm, (head)->sph_root);          \\\n        if(__comp < 0) {                        \\\n            SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\\\n            SPLAY_RIGHT(elm, field) = (head)->sph_root;     \\\n            SPLAY_LEFT((head)->sph_root, field) = NULL;     \\\n        } else if (__comp > 0) {                    \\\n            SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\\\n            SPLAY_LEFT(elm, field) = (head)->sph_root;      \\\n            SPLAY_RIGHT((head)->sph_root, field) = NULL;    \\\n        } else                          \\\n            return ((head)->sph_root);              \\\n    }                                   \\\n    (head)->sph_root = (elm);                       \\\n    return (NULL);                          \\\n}                                   \\\n                                    \\\nstruct type *                               \\\nname##_SPLAY_REMOVE(struct name *head, struct type *elm)        \\\n{                                   \\\n    struct type *__tmp;                     \\\n    if (SPLAY_EMPTY(head))                      \\\n        return (NULL);                      \\\n    name##_SPLAY(head, elm);                    \\\n    if ((cmp)(elm, (head)->sph_root) == 0) {            \\\n        if (SPLAY_LEFT((head)->sph_root, field) == NULL) {  \\\n            (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\\\n        } else {                        \\\n            __tmp = SPLAY_RIGHT((head)->sph_root, field);   \\\n            (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\\\n            name##_SPLAY(head, elm);            \\\n            SPLAY_RIGHT((head)->sph_root, field) = __tmp;   \\\n        }                           \\\n        return (elm);                       \\\n    }                               \\\n    return (NULL);                          \\\n}                                   \\\n                                    \\\nvoid                                    \\\nname##_SPLAY(struct name *head, struct type *elm)           \\\n{                                   \\\n    struct type __node, *__left, *__right, *__tmp;          \\\n    int __comp;                         \\\n\\\n    SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\\\n    __left = __right = &__node;                 \\\n\\\n    while ((__comp = (cmp)(elm, (head)->sph_root)) != 0) {      \\\n        if (__comp < 0) {                   \\\n            __tmp = SPLAY_LEFT((head)->sph_root, field);    \\\n            if (__tmp == NULL)              \\\n                break;                  \\\n            if ((cmp)(elm, __tmp) < 0){         \\\n                SPLAY_ROTATE_RIGHT(head, __tmp, field); \\\n                if (SPLAY_LEFT((head)->sph_root, field) == NULL)\\\n                    break;              \\\n            }                       \\\n            SPLAY_LINKLEFT(head, __right, field);       \\\n        } else if (__comp > 0) {                \\\n            __tmp = SPLAY_RIGHT((head)->sph_root, field);   \\\n            if (__tmp == NULL)              \\\n                break;                  \\\n            if ((cmp)(elm, __tmp) > 0){         \\\n                SPLAY_ROTATE_LEFT(head, __tmp, field);  \\\n                if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\\\n                    break;              \\\n            }                       \\\n            SPLAY_LINKRIGHT(head, __left, field);       \\\n        }                           \\\n    }                               \\\n    SPLAY_ASSEMBLE(head, &__node, __left, __right, field);      \\\n}                                   \\\n                                    \\\n/* Splay with either the minimum or the maximum element         \\\n * Used to find minimum or maximum element in tree.         \\\n */                                 \\\nvoid name##_SPLAY_MINMAX(struct name *head, int __comp) \\\n{                                   \\\n    struct type __node, *__left, *__right, *__tmp;          \\\n\\\n    SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\\\n    __left = __right = &__node;                 \\\n\\\n    while (1) {                         \\\n        if (__comp < 0) {                   \\\n            __tmp = SPLAY_LEFT((head)->sph_root, field);    \\\n            if (__tmp == NULL)              \\\n                break;                  \\\n            if (__comp < 0){                \\\n                SPLAY_ROTATE_RIGHT(head, __tmp, field); \\\n                if (SPLAY_LEFT((head)->sph_root, field) == NULL)\\\n                    break;              \\\n            }                       \\\n            SPLAY_LINKLEFT(head, __right, field);       \\\n        } else if (__comp > 0) {                \\\n            __tmp = SPLAY_RIGHT((head)->sph_root, field);   \\\n            if (__tmp == NULL)              \\\n                break;                  \\\n            if (__comp > 0) {               \\\n                SPLAY_ROTATE_LEFT(head, __tmp, field);  \\\n                if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\\\n                    break;              \\\n            }                       \\\n            SPLAY_LINKRIGHT(head, __left, field);       \\\n        }                           \\\n    }                               \\\n    SPLAY_ASSEMBLE(head, &__node, __left, __right, field);      \\\n}\n\n#define SPLAY_NEGINF    -1\n#define SPLAY_INF   1\n\n#define SPLAY_INSERT(name, x, y)    name##_SPLAY_INSERT(x, y)\n#define SPLAY_REMOVE(name, x, y)    name##_SPLAY_REMOVE(x, y)\n#define SPLAY_FIND(name, x, y)      name##_SPLAY_FIND(x, y)\n#define SPLAY_NEXT(name, x, y)      name##_SPLAY_NEXT(x, y)\n#define SPLAY_MIN(name, x)      (SPLAY_EMPTY(x) ? NULL  \\\n                    : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))\n#define SPLAY_MAX(name, x)      (SPLAY_EMPTY(x) ? NULL  \\\n                    : name##_SPLAY_MIN_MAX(x, SPLAY_INF))\n\n#define SPLAY_FOREACH(x, name, head)                    \\\n    for ((x) = SPLAY_MIN(name, head);               \\\n         (x) != NULL;                       \\\n         (x) = SPLAY_NEXT(name, head, x))\n\n/* Macros that define a red-black tree */\n#define RB_HEAD(name, type)                     \\\nstruct name {                               \\\n    struct type *rbh_root; /* root of the tree */           \\\n}\n\n#define RB_INITIALIZER(root)                        \\\n    { NULL }\n\n#define RB_INIT(root) do {                      \\\n    (root)->rbh_root = NULL;                    \\\n} while (/*CONSTCOND*/ 0)\n\n#define RB_BLACK    0\n#define RB_RED      1\n#define RB_ENTRY(type)                          \\\nstruct {                                \\\n    struct type *rbe_left;      /* left element */      \\\n    struct type *rbe_right;     /* right element */     \\\n    struct type *rbe_parent;    /* parent element */        \\\n    int rbe_color;          /* node color */        \\\n}\n\n#define RB_LEFT(elm, field)     (elm)->field.rbe_left\n#define RB_RIGHT(elm, field)        (elm)->field.rbe_right\n#define RB_PARENT(elm, field)       (elm)->field.rbe_parent\n#define RB_COLOR(elm, field)        (elm)->field.rbe_color\n#define RB_ROOT(head)           (head)->rbh_root\n#define RB_EMPTY(head)          (RB_ROOT(head) == NULL)\n\n#define RB_SET(elm, parent, field) do {                 \\\n    RB_PARENT(elm, field) = parent;                 \\\n    RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL;      \\\n    RB_COLOR(elm, field) = RB_RED;                  \\\n} while (/*CONSTCOND*/ 0)\n\n#define RB_SET_BLACKRED(black, red, field) do {             \\\n    RB_COLOR(black, field) = RB_BLACK;              \\\n    RB_COLOR(red, field) = RB_RED;                  \\\n} while (/*CONSTCOND*/ 0)\n\n#ifndef RB_AUGMENT\n#define RB_AUGMENT(x)   do {} while (0)\n#endif\n\n#define RB_ROTATE_LEFT(head, elm, tmp, field) do {          \\\n    (tmp) = RB_RIGHT(elm, field);                   \\\n    if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { \\\n        RB_PARENT(RB_LEFT(tmp, field), field) = (elm);      \\\n    }                               \\\n    RB_AUGMENT(elm);                        \\\n    if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) {  \\\n        if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \\\n            RB_LEFT(RB_PARENT(elm, field), field) = (tmp);  \\\n        else                            \\\n            RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \\\n    } else                              \\\n        (head)->rbh_root = (tmp);               \\\n    RB_LEFT(tmp, field) = (elm);                    \\\n    RB_PARENT(elm, field) = (tmp);                  \\\n    RB_AUGMENT(tmp);                        \\\n    if ((RB_PARENT(tmp, field)))                    \\\n        RB_AUGMENT(RB_PARENT(tmp, field));          \\\n} while (/*CONSTCOND*/ 0)\n\n#define RB_ROTATE_RIGHT(head, elm, tmp, field) do {         \\\n    (tmp) = RB_LEFT(elm, field);                    \\\n    if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { \\\n        RB_PARENT(RB_RIGHT(tmp, field), field) = (elm);     \\\n    }                               \\\n    RB_AUGMENT(elm);                        \\\n    if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) {  \\\n        if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \\\n            RB_LEFT(RB_PARENT(elm, field), field) = (tmp);  \\\n        else                            \\\n            RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \\\n    } else                              \\\n        (head)->rbh_root = (tmp);               \\\n    RB_RIGHT(tmp, field) = (elm);                   \\\n    RB_PARENT(elm, field) = (tmp);                  \\\n    RB_AUGMENT(tmp);                        \\\n    if ((RB_PARENT(tmp, field)))                    \\\n        RB_AUGMENT(RB_PARENT(tmp, field));          \\\n} while (/*CONSTCOND*/ 0)\n\n/* Generates prototypes and inline functions */\n#define RB_PROTOTYPE(name, type, field, cmp)                \\\n    RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)\n#define RB_PROTOTYPE_STATIC(name, type, field, cmp)         \\\n    RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __unused static)\n#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr)     \\\n    RB_PROTOTYPE_INSERT_COLOR(name, type, attr);            \\\n    RB_PROTOTYPE_REMOVE_COLOR(name, type, attr);            \\\n    RB_PROTOTYPE_INSERT(name, type, attr);              \\\n    RB_PROTOTYPE_REMOVE(name, type, attr);              \\\n    RB_PROTOTYPE_FIND(name, type, attr);                \\\n    RB_PROTOTYPE_NFIND(name, type, attr);               \\\n    RB_PROTOTYPE_NEXT(name, type, attr);                \\\n    RB_PROTOTYPE_PREV(name, type, attr);                \\\n    RB_PROTOTYPE_MINMAX(name, type, attr);\n#define RB_PROTOTYPE_INSERT_COLOR(name, type, attr)         \\\n    attr void name##_RB_INSERT_COLOR(struct name *, struct type *)\n#define RB_PROTOTYPE_REMOVE_COLOR(name, type, attr)         \\\n    attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *)\n#define RB_PROTOTYPE_REMOVE(name, type, attr)               \\\n    attr struct type *name##_RB_REMOVE(struct name *, struct type *)\n#define RB_PROTOTYPE_INSERT(name, type, attr)               \\\n    attr struct type *name##_RB_INSERT(struct name *, struct type *)\n#define RB_PROTOTYPE_FIND(name, type, attr)             \\\n    attr struct type *name##_RB_FIND(struct name *, struct type *)\n#define RB_PROTOTYPE_NFIND(name, type, attr)                \\\n    attr struct type *name##_RB_NFIND(struct name *, struct type *)\n#define RB_PROTOTYPE_NEXT(name, type, attr)             \\\n    attr struct type *name##_RB_NEXT(struct type *)\n#define RB_PROTOTYPE_PREV(name, type, attr)             \\\n    attr struct type *name##_RB_PREV(struct type *)\n#define RB_PROTOTYPE_MINMAX(name, type, attr)               \\\n    attr struct type *name##_RB_MINMAX(struct name *, int)\n\n/* Main rb operation.\n * Moves node close to the key of elm to top\n */\n#define RB_GENERATE(name, type, field, cmp)             \\\n    RB_GENERATE_INTERNAL(name, type, field, cmp,)\n#define RB_GENERATE_STATIC(name, type, field, cmp)          \\\n    RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static)\n#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr)      \\\n    RB_GENERATE_INSERT_COLOR(name, type, field, attr)       \\\n    RB_GENERATE_REMOVE_COLOR(name, type, field, attr)       \\\n    RB_GENERATE_INSERT(name, type, field, cmp, attr)        \\\n    RB_GENERATE_REMOVE(name, type, field, attr)         \\\n    RB_GENERATE_FIND(name, type, field, cmp, attr)          \\\n    RB_GENERATE_NFIND(name, type, field, cmp, attr)         \\\n    RB_GENERATE_NEXT(name, type, field, attr)           \\\n    RB_GENERATE_PREV(name, type, field, attr)           \\\n    RB_GENERATE_MINMAX(name, type, field, attr)\n\n#define RB_GENERATE_INSERT_COLOR(name, type, field, attr)       \\\nattr void                               \\\nname##_RB_INSERT_COLOR(struct name *head, struct type *elm)     \\\n{                                   \\\n    struct type *parent, *gparent, *tmp;                \\\n    while ((parent = RB_PARENT(elm, field)) != NULL &&      \\\n        RB_COLOR(parent, field) == RB_RED) {            \\\n        gparent = RB_PARENT(parent, field);         \\\n        if (parent == RB_LEFT(gparent, field)) {        \\\n            tmp = RB_RIGHT(gparent, field);         \\\n            if (tmp && RB_COLOR(tmp, field) == RB_RED) {    \\\n                RB_COLOR(tmp, field) = RB_BLACK;    \\\n                RB_SET_BLACKRED(parent, gparent, field);\\\n                elm = gparent;              \\\n                continue;               \\\n            }                       \\\n            if (RB_RIGHT(parent, field) == elm) {       \\\n                RB_ROTATE_LEFT(head, parent, tmp, field);\\\n                tmp = parent;               \\\n                parent = elm;               \\\n                elm = tmp;              \\\n            }                       \\\n            RB_SET_BLACKRED(parent, gparent, field);    \\\n            RB_ROTATE_RIGHT(head, gparent, tmp, field); \\\n        } else {                        \\\n            tmp = RB_LEFT(gparent, field);          \\\n            if (tmp && RB_COLOR(tmp, field) == RB_RED) {    \\\n                RB_COLOR(tmp, field) = RB_BLACK;    \\\n                RB_SET_BLACKRED(parent, gparent, field);\\\n                elm = gparent;              \\\n                continue;               \\\n            }                       \\\n            if (RB_LEFT(parent, field) == elm) {        \\\n                RB_ROTATE_RIGHT(head, parent, tmp, field);\\\n                tmp = parent;               \\\n                parent = elm;               \\\n                elm = tmp;              \\\n            }                       \\\n            RB_SET_BLACKRED(parent, gparent, field);    \\\n            RB_ROTATE_LEFT(head, gparent, tmp, field);  \\\n        }                           \\\n    }                               \\\n    RB_COLOR(head->rbh_root, field) = RB_BLACK;         \\\n}\n\n#define RB_GENERATE_REMOVE_COLOR(name, type, field, attr)       \\\nattr void                               \\\nname##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \\\n{                                   \\\n    struct type *tmp;                       \\\n    while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \\\n        elm != RB_ROOT(head)) {                 \\\n        if (RB_LEFT(parent, field) == elm) {            \\\n            tmp = RB_RIGHT(parent, field);          \\\n            if (RB_COLOR(tmp, field) == RB_RED) {       \\\n                RB_SET_BLACKRED(tmp, parent, field);    \\\n                RB_ROTATE_LEFT(head, parent, tmp, field);\\\n                tmp = RB_RIGHT(parent, field);      \\\n            }                       \\\n            if ((RB_LEFT(tmp, field) == NULL ||     \\\n                RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\\\n                (RB_RIGHT(tmp, field) == NULL ||        \\\n                RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\\\n                RB_COLOR(tmp, field) = RB_RED;      \\\n                elm = parent;               \\\n                parent = RB_PARENT(elm, field);     \\\n            } else {                    \\\n                if (RB_RIGHT(tmp, field) == NULL || \\\n                    RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\\\n                    struct type *oleft;     \\\n                    if ((oleft = RB_LEFT(tmp, field)) \\\n                        != NULL)            \\\n                        RB_COLOR(oleft, field) = RB_BLACK;\\\n                    RB_COLOR(tmp, field) = RB_RED;  \\\n                    RB_ROTATE_RIGHT(head, tmp, oleft, field);\\\n                    tmp = RB_RIGHT(parent, field);  \\\n                }                   \\\n                RB_COLOR(tmp, field) = RB_COLOR(parent, field);\\\n                RB_COLOR(parent, field) = RB_BLACK; \\\n                if (RB_RIGHT(tmp, field))       \\\n                    RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\\\n                RB_ROTATE_LEFT(head, parent, tmp, field);\\\n                elm = RB_ROOT(head);            \\\n                break;                  \\\n            }                       \\\n        } else {                        \\\n            tmp = RB_LEFT(parent, field);           \\\n            if (RB_COLOR(tmp, field) == RB_RED) {       \\\n                RB_SET_BLACKRED(tmp, parent, field);    \\\n                RB_ROTATE_RIGHT(head, parent, tmp, field);\\\n                tmp = RB_LEFT(parent, field);       \\\n            }                       \\\n            if ((RB_LEFT(tmp, field) == NULL ||     \\\n                RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\\\n                (RB_RIGHT(tmp, field) == NULL ||        \\\n                RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\\\n                RB_COLOR(tmp, field) = RB_RED;      \\\n                elm = parent;               \\\n                parent = RB_PARENT(elm, field);     \\\n            } else {                    \\\n                if (RB_LEFT(tmp, field) == NULL ||  \\\n                    RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\\\n                    struct type *oright;        \\\n                    if ((oright = RB_RIGHT(tmp, field)) \\\n                        != NULL)            \\\n                        RB_COLOR(oright, field) = RB_BLACK;\\\n                    RB_COLOR(tmp, field) = RB_RED;  \\\n                    RB_ROTATE_LEFT(head, tmp, oright, field);\\\n                    tmp = RB_LEFT(parent, field);   \\\n                }                   \\\n                RB_COLOR(tmp, field) = RB_COLOR(parent, field);\\\n                RB_COLOR(parent, field) = RB_BLACK; \\\n                if (RB_LEFT(tmp, field))        \\\n                    RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\\\n                RB_ROTATE_RIGHT(head, parent, tmp, field);\\\n                elm = RB_ROOT(head);            \\\n                break;                  \\\n            }                       \\\n        }                           \\\n    }                               \\\n    if (elm)                            \\\n        RB_COLOR(elm, field) = RB_BLACK;            \\\n}\n\n#define RB_GENERATE_REMOVE(name, type, field, attr)         \\\nattr struct type *                          \\\nname##_RB_REMOVE(struct name *head, struct type *elm)           \\\n{                                   \\\n    struct type *child, *parent, *old = elm;            \\\n    int color;                          \\\n    if (RB_LEFT(elm, field) == NULL)                \\\n        child = RB_RIGHT(elm, field);               \\\n    else if (RB_RIGHT(elm, field) == NULL)              \\\n        child = RB_LEFT(elm, field);                \\\n    else {                              \\\n        struct type *left;                  \\\n        elm = RB_RIGHT(elm, field);             \\\n        while ((left = RB_LEFT(elm, field)) != NULL)        \\\n            elm = left;                 \\\n        child = RB_RIGHT(elm, field);               \\\n        parent = RB_PARENT(elm, field);             \\\n        color = RB_COLOR(elm, field);               \\\n        if (child)                      \\\n            RB_PARENT(child, field) = parent;       \\\n        if (parent) {                       \\\n            if (RB_LEFT(parent, field) == elm)      \\\n                RB_LEFT(parent, field) = child;     \\\n            else                        \\\n                RB_RIGHT(parent, field) = child;    \\\n            RB_AUGMENT(parent);             \\\n        } else                          \\\n            RB_ROOT(head) = child;              \\\n        if (RB_PARENT(elm, field) == old)           \\\n            parent = elm;                   \\\n        (elm)->field = (old)->field;                \\\n        if (RB_PARENT(old, field)) {                \\\n            if (RB_LEFT(RB_PARENT(old, field), field) == old)\\\n                RB_LEFT(RB_PARENT(old, field), field) = elm;\\\n            else                        \\\n                RB_RIGHT(RB_PARENT(old, field), field) = elm;\\\n            RB_AUGMENT(RB_PARENT(old, field));      \\\n        } else                          \\\n            RB_ROOT(head) = elm;                \\\n        RB_PARENT(RB_LEFT(old, field), field) = elm;        \\\n        if (RB_RIGHT(old, field))               \\\n            RB_PARENT(RB_RIGHT(old, field), field) = elm;   \\\n        if (parent) {                       \\\n            left = parent;                  \\\n            do {                        \\\n                RB_AUGMENT(left);           \\\n            } while ((left = RB_PARENT(left, field)) != NULL); \\\n        }                           \\\n        goto color;                     \\\n    }                               \\\n    parent = RB_PARENT(elm, field);                 \\\n    color = RB_COLOR(elm, field);                   \\\n    if (child)                          \\\n        RB_PARENT(child, field) = parent;           \\\n    if (parent) {                           \\\n        if (RB_LEFT(parent, field) == elm)          \\\n            RB_LEFT(parent, field) = child;         \\\n        else                            \\\n            RB_RIGHT(parent, field) = child;        \\\n        RB_AUGMENT(parent);                 \\\n    } else                              \\\n        RB_ROOT(head) = child;                  \\\ncolor:                                  \\\n    if (color == RB_BLACK)                      \\\n        name##_RB_REMOVE_COLOR(head, parent, child);        \\\n    return (old);                           \\\n}                                   \\\n\n#define RB_GENERATE_INSERT(name, type, field, cmp, attr)        \\\n/* Inserts a node into the RB tree */                   \\\nattr struct type *                          \\\nname##_RB_INSERT(struct name *head, struct type *elm)           \\\n{                                   \\\n    struct type *tmp;                       \\\n    struct type *parent = NULL;                 \\\n    int comp = 0;                           \\\n    tmp = RB_ROOT(head);                        \\\n    while (tmp) {                           \\\n        parent = tmp;                       \\\n        comp = (cmp)(elm, parent);              \\\n        if (comp < 0)                       \\\n            tmp = RB_LEFT(tmp, field);          \\\n        else if (comp > 0)                  \\\n            tmp = RB_RIGHT(tmp, field);         \\\n        else                            \\\n            return (tmp);                   \\\n    }                               \\\n    RB_SET(elm, parent, field);                 \\\n    if (parent != NULL) {                       \\\n        if (comp < 0)                       \\\n            RB_LEFT(parent, field) = elm;           \\\n        else                            \\\n            RB_RIGHT(parent, field) = elm;          \\\n        RB_AUGMENT(parent);                 \\\n    } else                              \\\n        RB_ROOT(head) = elm;                    \\\n    name##_RB_INSERT_COLOR(head, elm);              \\\n    return (NULL);                          \\\n}\n\n#define RB_GENERATE_FIND(name, type, field, cmp, attr)          \\\n/* Finds the node with the same key as elm */               \\\nattr struct type *                          \\\nname##_RB_FIND(struct name *head, struct type *elm)         \\\n{                                   \\\n    struct type *tmp = RB_ROOT(head);               \\\n    int comp;                           \\\n    while (tmp) {                           \\\n        comp = cmp(elm, tmp);                   \\\n        if (comp < 0)                       \\\n            tmp = RB_LEFT(tmp, field);          \\\n        else if (comp > 0)                  \\\n            tmp = RB_RIGHT(tmp, field);         \\\n        else                            \\\n            return (tmp);                   \\\n    }                               \\\n    return (NULL);                          \\\n}\n\n#define RB_GENERATE_NFIND(name, type, field, cmp, attr)         \\\n/* Finds the first node greater than or equal to the search key */  \\\nattr struct type *                          \\\nname##_RB_NFIND(struct name *head, struct type *elm)            \\\n{                                   \\\n    struct type *tmp = RB_ROOT(head);               \\\n    struct type *res = NULL;                    \\\n    int comp;                           \\\n    while (tmp) {                           \\\n        comp = cmp(elm, tmp);                   \\\n        if (comp < 0) {                     \\\n            res = tmp;                  \\\n            tmp = RB_LEFT(tmp, field);          \\\n        }                           \\\n        else if (comp > 0)                  \\\n            tmp = RB_RIGHT(tmp, field);         \\\n        else                            \\\n            return (tmp);                   \\\n    }                               \\\n    return (res);                           \\\n}\n\n#define RB_GENERATE_NEXT(name, type, field, attr)           \\\n/* ARGSUSED */                              \\\nattr struct type *                          \\\nname##_RB_NEXT(struct type *elm)                    \\\n{                                   \\\n    if (RB_RIGHT(elm, field)) {                 \\\n        elm = RB_RIGHT(elm, field);             \\\n        while (RB_LEFT(elm, field))             \\\n            elm = RB_LEFT(elm, field);          \\\n    } else {                            \\\n        if (RB_PARENT(elm, field) &&                \\\n            (elm == RB_LEFT(RB_PARENT(elm, field), field))) \\\n            elm = RB_PARENT(elm, field);            \\\n        else {                          \\\n            while (RB_PARENT(elm, field) &&         \\\n                (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\\\n                elm = RB_PARENT(elm, field);        \\\n            elm = RB_PARENT(elm, field);            \\\n        }                           \\\n    }                               \\\n    return (elm);                           \\\n}\n\n#define RB_GENERATE_PREV(name, type, field, attr)           \\\n/* ARGSUSED */                              \\\nattr struct type *                          \\\nname##_RB_PREV(struct type *elm)                    \\\n{                                   \\\n    if (RB_LEFT(elm, field)) {                  \\\n        elm = RB_LEFT(elm, field);              \\\n        while (RB_RIGHT(elm, field))                \\\n            elm = RB_RIGHT(elm, field);         \\\n    } else {                            \\\n        if (RB_PARENT(elm, field) &&                \\\n            (elm == RB_RIGHT(RB_PARENT(elm, field), field)))    \\\n            elm = RB_PARENT(elm, field);            \\\n        else {                          \\\n            while (RB_PARENT(elm, field) &&         \\\n                (elm == RB_LEFT(RB_PARENT(elm, field), field)))\\\n                elm = RB_PARENT(elm, field);        \\\n            elm = RB_PARENT(elm, field);            \\\n        }                           \\\n    }                               \\\n    return (elm);                           \\\n}\n\n#define RB_GENERATE_MINMAX(name, type, field, attr)         \\\nattr struct type *                          \\\nname##_RB_MINMAX(struct name *head, int val)                \\\n{                                   \\\n    struct type *tmp = RB_ROOT(head);               \\\n    struct type *parent = NULL;                 \\\n    while (tmp) {                           \\\n        parent = tmp;                       \\\n        if (val < 0)                        \\\n            tmp = RB_LEFT(tmp, field);          \\\n        else                            \\\n            tmp = RB_RIGHT(tmp, field);         \\\n    }                               \\\n    return (parent);                        \\\n}\n\n#define RB_NEGINF   -1\n#define RB_INF  1\n\n#define RB_INSERT(name, x, y)   name##_RB_INSERT(x, y)\n#define RB_REMOVE(name, x, y)   name##_RB_REMOVE(x, y)\n#define RB_FIND(name, x, y) name##_RB_FIND(x, y)\n#define RB_NFIND(name, x, y)    name##_RB_NFIND(x, y)\n#define RB_NEXT(name, x, y) name##_RB_NEXT(y)\n#define RB_PREV(name, x, y) name##_RB_PREV(y)\n#define RB_MIN(name, x)     name##_RB_MINMAX(x, RB_NEGINF)\n#define RB_MAX(name, x)     name##_RB_MINMAX(x, RB_INF)\n\n#define RB_FOREACH(x, name, head)                   \\\n    for ((x) = RB_MIN(name, head);                  \\\n         (x) != NULL;                       \\\n         (x) = name##_RB_NEXT(x))\n\n#define RB_FOREACH_FROM(x, name, y)                 \\\n    for ((x) = (y);                         \\\n        ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL);    \\\n         (x) = (y))\n\n#define RB_FOREACH_SAFE(x, name, head, y)               \\\n    for ((x) = RB_MIN(name, head);                  \\\n        ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL);    \\\n         (x) = (y))\n\n#define RB_FOREACH_REVERSE(x, name, head)               \\\n    for ((x) = RB_MAX(name, head);                  \\\n         (x) != NULL;                       \\\n         (x) = name##_RB_PREV(x))\n\n#define RB_FOREACH_REVERSE_FROM(x, name, y)             \\\n    for ((x) = (y);                         \\\n        ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL);    \\\n         (x) = (y))\n\n#define RB_FOREACH_REVERSE_SAFE(x, name, head, y)           \\\n    for ((x) = RB_MAX(name, head);                  \\\n        ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL);    \\\n         (x) = (y))\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif  /* _SYS_TREE_H_ */\n"
  },
  {
    "path": "user.libs/liblwext4/src/ext4.c",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4.h\n * @brief Ext4 high level operations (file, directory, mountpoints...)\n */\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_misc.h>\n#include <ext4_errno.h>\n#include <ext4_oflags.h>\n#include <ext4_debug.h>\n\n#include <ext4.h>\n#include <ext4_trans.h>\n#include <ext4_blockdev.h>\n#include <ext4_fs.h>\n#include <ext4_dir.h>\n#include <ext4_inode.h>\n#include <ext4_super.h>\n#include <ext4_block_group.h>\n#include <ext4_dir_idx.h>\n#include <ext4_xattr.h>\n#include <ext4_journal.h>\n\n\n#include <stdlib.h>\n#include <string.h>\n\n/**@brief   Mount point OS dependent lock*/\n#define EXT4_MP_LOCK(_m)                                                       \\\n    do {                                                                   \\\n        if ((_m)->os_locks)                                            \\\n            (_m)->os_locks->lock();                                \\\n    } while (0)\n\n/**@brief   Mount point OS dependent unlock*/\n#define EXT4_MP_UNLOCK(_m)                                                     \\\n    do {                                                                   \\\n        if ((_m)->os_locks)                                            \\\n            (_m)->os_locks->unlock();                              \\\n    } while (0)\n\n/**@brief   Mount point descriptor.*/\nstruct ext4_mountpoint {\n\n    /**@brief   Mount done flag.*/\n    bool mounted;\n\n    /**@brief   Mount point name (@ref ext4_mount)*/\n    char name[CONFIG_EXT4_MAX_MP_NAME + 1];\n\n    /**@brief   OS dependent lock/unlock functions.*/\n    const struct ext4_lock *os_locks;\n\n    /**@brief   Ext4 filesystem internals.*/\n    struct ext4_fs fs;\n\n    /**@brief   JBD fs.*/\n    struct jbd_fs jbd_fs;\n\n    /**@brief   Journal.*/\n    struct jbd_journal jbd_journal;\n\n    /**@brief   Block cache.*/\n    struct ext4_bcache bc;\n};\n\n/**@brief   Block devices descriptor.*/\nstruct ext4_block_devices {\n\n    /**@brief   Block device name.*/\n    char name[CONFIG_EXT4_MAX_BLOCKDEV_NAME + 1];\n\n    /**@brief   Block device handle.*/\n    struct ext4_blockdev *bd;\n};\n\n/**@brief   Block devices.*/\nstatic struct ext4_block_devices s_bdevices[CONFIG_EXT4_BLOCKDEVS_COUNT];\n\n/**@brief   Mountpoints.*/\nstatic struct ext4_mountpoint s_mp[CONFIG_EXT4_MOUNTPOINTS_COUNT];\n\nint ext4_device_register(struct ext4_blockdev *bd,\n             const char *dev_name)\n{\n    ext4_assert(bd && dev_name);\n\n    if (strlen(dev_name) > CONFIG_EXT4_MAX_BLOCKDEV_NAME)\n        return EINVAL;\n\n    for (size_t i = 0; i < CONFIG_EXT4_BLOCKDEVS_COUNT; ++i) {\n        if (!strcmp(s_bdevices[i].name, dev_name))\n            return EEXIST;\n    }\n\n    for (size_t i = 0; i < CONFIG_EXT4_BLOCKDEVS_COUNT; ++i) {\n        if (!s_bdevices[i].bd) {\n            strcpy(s_bdevices[i].name, dev_name);\n            s_bdevices[i].bd = bd;\n            return EOK;\n        }\n    }\n\n    return ENOSPC;\n}\n\nint ext4_device_unregister(const char *dev_name)\n{\n    ext4_assert(dev_name);\n\n    for (size_t i = 0; i < CONFIG_EXT4_BLOCKDEVS_COUNT; ++i) {\n        if (strcmp(s_bdevices[i].name, dev_name))\n            continue;\n\n        memset(&s_bdevices[i], 0, sizeof(s_bdevices[i]));\n    }\n\n    return ENOENT;\n}\n\nint ext4_device_unregister_all(void)\n{\n    memset(s_bdevices, 0, sizeof(s_bdevices));\n\n    return EOK;\n}\n\n/****************************************************************************/\n\nstatic bool ext4_is_dots(const uint8_t *name, size_t name_size)\n{\n    if ((name_size == 1) && (name[0] == '.'))\n        return true;\n\n    if ((name_size == 2) && (name[0] == '.') && (name[1] == '.'))\n        return true;\n\n    return false;\n}\n\nstatic int ext4_has_children(bool *has_children, struct ext4_inode_ref *enode)\n{\n    struct ext4_sblock *sb = &enode->fs->sb;\n\n    /* Check if node is directory */\n    if (!ext4_inode_is_type(sb, enode->inode, EXT4_INODE_MODE_DIRECTORY)) {\n        *has_children = false;\n        return EOK;\n    }\n\n    struct ext4_dir_iter it;\n    int rc = ext4_dir_iterator_init(&it, enode, 0);\n    if (rc != EOK)\n        return rc;\n\n    /* Find a non-empty directory entry */\n    bool found = false;\n    while (it.curr != NULL) {\n        if (ext4_dir_en_get_inode(it.curr) != 0) {\n            uint16_t nsize;\n            nsize = ext4_dir_en_get_name_len(sb, it.curr);\n            if (!ext4_is_dots(it.curr->name, nsize)) {\n                found = true;\n                break;\n            }\n        }\n\n        rc = ext4_dir_iterator_next(&it);\n        if (rc != EOK) {\n            ext4_dir_iterator_fini(&it);\n            return rc;\n        }\n    }\n\n    rc = ext4_dir_iterator_fini(&it);\n    if (rc != EOK)\n        return rc;\n\n    *has_children = found;\n\n    return EOK;\n}\n\nstatic int ext4_link(struct ext4_mountpoint *mp, struct ext4_inode_ref *parent,\n             struct ext4_inode_ref *ch, const char *n,\n             uint32_t len, bool rename)\n{\n    /* Check maximum name length */\n    if (len > EXT4_DIRECTORY_FILENAME_LEN)\n        return EINVAL;\n\n    /* Add entry to parent directory */\n    int r = ext4_dir_add_entry(parent, n, len, ch);\n    if (r != EOK)\n        return r;\n\n    /* Fill new dir -> add '.' and '..' entries.\n     * Also newly allocated inode should have 0 link count.\n     */\n\n    bool is_dir = ext4_inode_is_type(&mp->fs.sb, ch->inode,\n                   EXT4_INODE_MODE_DIRECTORY);\n    if (is_dir && !rename) {\n\n#if CONFIG_DIR_INDEX_ENABLE\n        /* Initialize directory index if supported */\n        if (ext4_sb_feature_com(&mp->fs.sb, EXT4_FCOM_DIR_INDEX)) {\n            r = ext4_dir_dx_init(ch, parent);\n            if (r != EOK)\n                return r;\n\n            ext4_inode_set_flag(ch->inode, EXT4_INODE_FLAG_INDEX);\n            ch->dirty = true;\n        } else\n#endif\n        {\n            r = ext4_dir_add_entry(ch, \".\", strlen(\".\"), ch);\n            if (r != EOK) {\n                ext4_dir_remove_entry(parent, n, strlen(n));\n                return r;\n            }\n\n            r = ext4_dir_add_entry(ch, \"..\", strlen(\"..\"), parent);\n            if (r != EOK) {\n                ext4_dir_remove_entry(parent, n, strlen(n));\n                ext4_dir_remove_entry(ch, \".\", strlen(\".\"));\n                return r;\n            }\n        }\n\n        /*New empty directory. Two links (. and ..) */\n        ext4_inode_set_links_cnt(ch->inode, 2);\n        ext4_fs_inode_links_count_inc(parent);\n        ch->dirty = true;\n        parent->dirty = true;\n        return r;\n    }\n    /*\n     * In case we want to rename a directory,\n     * we reset the original '..' pointer.\n     */\n    if (is_dir) {\n        bool idx;\n        idx = ext4_inode_has_flag(ch->inode, EXT4_INODE_FLAG_INDEX);\n        struct ext4_dir_search_result res;\n        if (!idx) {\n            r = ext4_dir_find_entry(&res, ch, \"..\", strlen(\"..\"));\n            if (r != EOK)\n                return EIO;\n\n            ext4_dir_en_set_inode(res.dentry, parent->index);\n            ext4_trans_set_block_dirty(res.block.buf);\n            r = ext4_dir_destroy_result(ch, &res);\n            if (r != EOK)\n                return r;\n\n        } else {\n#if CONFIG_DIR_INDEX_ENABLE\n            r = ext4_dir_dx_reset_parent_inode(ch, parent->index);\n            if (r != EOK)\n                return r;\n\n#endif\n        }\n\n        ext4_fs_inode_links_count_inc(parent);\n        parent->dirty = true;\n    }\n    if (!rename) {\n        ext4_fs_inode_links_count_inc(ch);\n        ch->dirty = true;\n    }\n\n    return r;\n}\n\nstatic int ext4_unlink(struct ext4_mountpoint *mp,\n               struct ext4_inode_ref *parent,\n               struct ext4_inode_ref *child, const char *name,\n               uint32_t name_len)\n{\n    bool has_children;\n    int rc = ext4_has_children(&has_children, child);\n    if (rc != EOK)\n        return rc;\n\n    /* Cannot unlink non-empty node */\n    if (has_children)\n        return ENOTEMPTY;\n\n    /* Remove entry from parent directory */\n    rc = ext4_dir_remove_entry(parent, name, name_len);\n    if (rc != EOK)\n        return rc;\n\n    bool is_dir = ext4_inode_is_type(&mp->fs.sb, child->inode,\n                     EXT4_INODE_MODE_DIRECTORY);\n\n    /* If directory - handle links from parent */\n    if (is_dir) {\n        ext4_fs_inode_links_count_dec(parent);\n        parent->dirty = true;\n    }\n\n    /*\n     * TODO: Update timestamps of the parent\n     * (when we have wall-clock time).\n     *\n     * ext4_inode_set_change_inode_time(parent->inode, (uint32_t) now);\n     * ext4_inode_set_modification_time(parent->inode, (uint32_t) now);\n     * parent->dirty = true;\n     */\n\n    /*\n     * TODO: Update timestamp for inode.\n     *\n     * ext4_inode_set_change_inode_time(child->inode,\n     *     (uint32_t) now);\n     */\n    if (ext4_inode_get_links_cnt(child->inode)) {\n        ext4_fs_inode_links_count_dec(child);\n        child->dirty = true;\n    }\n\n    return EOK;\n}\n\n/****************************************************************************/\n\nint ext4_mount(const char *dev_name, const char *mount_point,\n           bool read_only)\n{\n    int r;\n    uint32_t bsize;\n    struct ext4_bcache *bc;\n    struct ext4_blockdev *bd = 0;\n    struct ext4_mountpoint *mp = 0;\n\n    ext4_assert(mount_point && dev_name);\n\n    size_t mp_len = strlen(mount_point);\n\n    if (mp_len > CONFIG_EXT4_MAX_MP_NAME)\n        return EINVAL;\n\n    if (mount_point[mp_len - 1] != '/')\n        return ENOTSUP;\n\n    for (size_t i = 0; i < CONFIG_EXT4_BLOCKDEVS_COUNT; ++i) {\n        if (!strcmp(dev_name, s_bdevices[i].name)) {\n            bd = s_bdevices[i].bd;\n            break;\n        }\n    }\n\n    if (!bd)\n        return ENODEV;\n\n    for (size_t i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {\n        if (!s_mp[i].mounted) {\n            strcpy(s_mp[i].name, mount_point);\n            s_mp[i].mounted = 1;\n            mp = &s_mp[i];\n            break;\n        }\n\n        if (!strcmp(s_mp[i].name, mount_point))\n            return EOK;\n    }\n\n    if (!mp)\n        return ENOMEM;\n\n    r = ext4_block_init(bd);\n    if (r != EOK)\n        return r;\n\n    r = ext4_fs_init(&mp->fs, bd, read_only);\n    if (r != EOK) {\n        ext4_block_fini(bd);\n        return r;\n    }\n\n    bsize = ext4_sb_get_block_size(&mp->fs.sb);\n    ext4_block_set_lb_size(bd, bsize);\n    bc = &mp->bc;\n\n    r = ext4_bcache_init_dynamic(bc, CONFIG_BLOCK_DEV_CACHE_SIZE, bsize);\n    if (r != EOK) {\n        ext4_block_fini(bd);\n        return r;\n    }\n\n    if (bsize != bc->itemsize)\n        return ENOTSUP;\n\n    /*Bind block cache to block device*/\n    r = ext4_block_bind_bcache(bd, bc);\n    if (r != EOK) {\n        ext4_bcache_cleanup(bc);\n        ext4_block_fini(bd);\n        ext4_bcache_fini_dynamic(bc);\n        return r;\n    }\n\n    bd->fs = &mp->fs;\n    return r;\n}\n\n\nint ext4_umount(const char *mount_point)\n{\n    int i;\n    int r;\n    struct ext4_mountpoint *mp = 0;\n\n    for (i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {\n        if (!strcmp(s_mp[i].name, mount_point)) {\n            mp = &s_mp[i];\n            break;\n        }\n    }\n\n    if (!mp)\n        return ENODEV;\n\n    r = ext4_fs_fini(&mp->fs);\n    if (r != EOK)\n        goto Finish;\n\n    mp->mounted = 0;\n\n    ext4_bcache_cleanup(mp->fs.bdev->bc);\n    ext4_bcache_fini_dynamic(mp->fs.bdev->bc);\n\n    r = ext4_block_fini(mp->fs.bdev);\nFinish:\n    mp->fs.bdev->fs = NULL;\n    return r;\n}\n\nstatic struct ext4_mountpoint *ext4_get_mount(const char *path)\n{\n    for (size_t i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {\n\n        if (!s_mp[i].mounted)\n            continue;\n\n        if (!strncmp(s_mp[i].name, path, strlen(s_mp[i].name)))\n            return &s_mp[i];\n    }\n\n    return NULL;\n}\n\n__unused\nstatic int __ext4_journal_start(const char *mount_point)\n{\n    int r = EOK;\n    struct ext4_mountpoint *mp = ext4_get_mount(mount_point);\n\n    if (!mp)\n        return ENOENT;\n\n    if (mp->fs.read_only)\n        return EOK;\n\n    if (ext4_sb_feature_com(&mp->fs.sb,\n                EXT4_FCOM_HAS_JOURNAL)) {\n        r = jbd_get_fs(&mp->fs, &mp->jbd_fs);\n        if (r != EOK)\n            goto Finish;\n\n        r = jbd_journal_start(&mp->jbd_fs, &mp->jbd_journal);\n        if (r != EOK) {\n            mp->jbd_fs.dirty = false;\n            jbd_put_fs(&mp->jbd_fs);\n            goto Finish;\n        }\n        mp->fs.jbd_fs = &mp->jbd_fs;\n        mp->fs.jbd_journal = &mp->jbd_journal;\n    }\nFinish:\n    return r;\n}\n\n__unused\nstatic int __ext4_journal_stop(const char *mount_point)\n{\n    int r = EOK;\n    struct ext4_mountpoint *mp = ext4_get_mount(mount_point);\n\n    if (!mp)\n        return ENOENT;\n\n    if (mp->fs.read_only)\n        return EOK;\n\n    if (ext4_sb_feature_com(&mp->fs.sb,\n                EXT4_FCOM_HAS_JOURNAL)) {\n        r = jbd_journal_stop(&mp->jbd_journal);\n        if (r != EOK) {\n            mp->jbd_fs.dirty = false;\n            jbd_put_fs(&mp->jbd_fs);\n            mp->fs.jbd_journal = NULL;\n            mp->fs.jbd_fs = NULL;\n            goto Finish;\n        }\n\n        r = jbd_put_fs(&mp->jbd_fs);\n        if (r != EOK) {\n            mp->fs.jbd_journal = NULL;\n            mp->fs.jbd_fs = NULL;\n            goto Finish;\n        }\n\n        mp->fs.jbd_journal = NULL;\n        mp->fs.jbd_fs = NULL;\n    }\nFinish:\n    return r;\n}\n\n__unused\nstatic int __ext4_recover(const char *mount_point)\n{\n    struct ext4_mountpoint *mp = ext4_get_mount(mount_point);\n    int r = ENOTSUP;\n\n    if (!mp)\n        return ENOENT;\n\n    EXT4_MP_LOCK(mp);\n    if (ext4_sb_feature_com(&mp->fs.sb, EXT4_FCOM_HAS_JOURNAL)) {\n        struct jbd_fs *jbd_fs = ext4_calloc(1, sizeof(struct jbd_fs));\n        if (!jbd_fs) {\n             r = ENOMEM;\n             goto Finish;\n        }\n\n        r = jbd_get_fs(&mp->fs, jbd_fs);\n        if (r != EOK) {\n            ext4_free(jbd_fs);\n            goto Finish;\n        }\n\n        r = jbd_recover(jbd_fs);\n        jbd_put_fs(jbd_fs);\n        ext4_free(jbd_fs);\n    }\n    if (r == EOK && !mp->fs.read_only) {\n        uint32_t bgid;\n        uint64_t free_blocks_count = 0;\n        uint32_t free_inodes_count = 0;\n        struct ext4_block_group_ref bg_ref;\n\n        /* Update superblock's stats */\n        for (bgid = 0;bgid < ext4_block_group_cnt(&mp->fs.sb);bgid++) {\n            r = ext4_fs_get_block_group_ref(&mp->fs, bgid, &bg_ref);\n            if (r != EOK)\n                goto Finish;\n\n            free_blocks_count +=\n                ext4_bg_get_free_blocks_count(bg_ref.block_group,\n                        &mp->fs.sb);\n            free_inodes_count +=\n                ext4_bg_get_free_inodes_count(bg_ref.block_group,\n                        &mp->fs.sb);\n\n            ext4_fs_put_block_group_ref(&bg_ref);\n        }\n        ext4_sb_set_free_blocks_cnt(&mp->fs.sb, free_blocks_count);\n        ext4_set32(&mp->fs.sb, free_inodes_count, free_inodes_count);\n        /* We don't need to save the superblock stats immediately. */\n    }\n\nFinish:\n    EXT4_MP_UNLOCK(mp);\n    return r;\n}\n\n__unused\nstatic int __ext4_trans_start(struct ext4_mountpoint *mp)\n{\n    int r = EOK;\n\n    if (mp->fs.jbd_journal && !mp->fs.curr_trans) {\n        struct jbd_journal *journal = mp->fs.jbd_journal;\n        struct jbd_trans *trans;\n        trans = jbd_journal_new_trans(journal);\n        if (!trans) {\n            r = ENOMEM;\n            goto Finish;\n        }\n        mp->fs.curr_trans = trans;\n    }\nFinish:\n    return r;\n}\n\n__unused\nstatic int __ext4_trans_stop(struct ext4_mountpoint *mp)\n{\n    int r = EOK;\n\n    if (mp->fs.jbd_journal && mp->fs.curr_trans) {\n        struct jbd_journal *journal = mp->fs.jbd_journal;\n        struct jbd_trans *trans = mp->fs.curr_trans;\n        r = jbd_journal_commit_trans(journal, trans);\n        mp->fs.curr_trans = NULL;\n    }\n    return r;\n}\n\n__unused\nstatic void __ext4_trans_abort(struct ext4_mountpoint *mp)\n{\n    if (mp->fs.jbd_journal && mp->fs.curr_trans) {\n        struct jbd_journal *journal = mp->fs.jbd_journal;\n        struct jbd_trans *trans = mp->fs.curr_trans;\n        jbd_journal_free_trans(journal, trans, true);\n        mp->fs.curr_trans = NULL;\n    }\n}\n\nint ext4_journal_start(const char *mount_point __unused)\n{\n    int r = EOK;\n#if CONFIG_JOURNALING_ENABLE\n    r = __ext4_journal_start(mount_point);\n#endif\n    return r;\n}\n\nint ext4_journal_stop(const char *mount_point __unused)\n{\n    int r = EOK;\n#if CONFIG_JOURNALING_ENABLE\n    r = __ext4_journal_stop(mount_point);\n#endif\n    return r;\n}\n\nint ext4_recover(const char *mount_point __unused)\n{\n    int r = EOK;\n#if CONFIG_JOURNALING_ENABLE\n    r = __ext4_recover(mount_point);\n#endif\n    return r;\n}\n\nstatic int ext4_trans_start(struct ext4_mountpoint *mp __unused)\n{\n    int r = EOK;\n#if CONFIG_JOURNALING_ENABLE\n    r = __ext4_trans_start(mp);\n#endif\n    return r;\n}\n\nstatic int ext4_trans_stop(struct ext4_mountpoint *mp __unused)\n{\n    int r = EOK;\n#if CONFIG_JOURNALING_ENABLE\n    r = __ext4_trans_stop(mp);\n#endif\n    return r;\n}\n\nstatic void ext4_trans_abort(struct ext4_mountpoint *mp __unused)\n{\n#if CONFIG_JOURNALING_ENABLE\n    __ext4_trans_abort(mp);\n#endif\n}\n\n\nint ext4_mount_point_stats(const char *mount_point,\n               struct ext4_mount_stats *stats)\n{\n    struct ext4_mountpoint *mp = ext4_get_mount(mount_point);\n\n    if (!mp)\n        return ENOENT;\n\n    EXT4_MP_LOCK(mp);\n    stats->inodes_count = ext4_get32(&mp->fs.sb, inodes_count);\n    stats->free_inodes_count = ext4_get32(&mp->fs.sb, free_inodes_count);\n    stats->blocks_count = ext4_sb_get_blocks_cnt(&mp->fs.sb);\n    stats->free_blocks_count = ext4_sb_get_free_blocks_cnt(&mp->fs.sb);\n    stats->block_size = ext4_sb_get_block_size(&mp->fs.sb);\n\n    stats->block_group_count = ext4_block_group_cnt(&mp->fs.sb);\n    stats->blocks_per_group = ext4_get32(&mp->fs.sb, blocks_per_group);\n    stats->inodes_per_group = ext4_get32(&mp->fs.sb, inodes_per_group);\n\n    memcpy(stats->volume_name, mp->fs.sb.volume_name, 16);\n    EXT4_MP_UNLOCK(mp);\n\n    return EOK;\n}\n\nint ext4_mount_setup_locks(const char *mount_point,\n               const struct ext4_lock *locks)\n{\n    uint32_t i;\n    struct ext4_mountpoint *mp = 0;\n\n    for (i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {\n        if (!strcmp(s_mp[i].name, mount_point)) {\n            mp = &s_mp[i];\n            break;\n        }\n    }\n    if (!mp)\n        return ENOENT;\n\n    mp->os_locks = locks;\n    return EOK;\n}\n\n/********************************FILE OPERATIONS*****************************/\n\nstatic int ext4_path_check(const char *path, bool *is_goal)\n{\n    int i;\n\n    for (i = 0; i < EXT4_DIRECTORY_FILENAME_LEN; ++i) {\n\n        if (path[i] == '/') {\n            *is_goal = false;\n            return i;\n        }\n\n        if (path[i] == 0) {\n            *is_goal = true;\n            return i;\n        }\n    }\n\n    return 0;\n}\n\nstatic bool ext4_parse_flags(const char *flags, uint32_t *file_flags)\n{\n    if (!flags)\n        return false;\n\n    if (!strcmp(flags, \"r\") || !strcmp(flags, \"rb\")) {\n        *file_flags = O_RDONLY;\n        return true;\n    }\n\n    if (!strcmp(flags, \"w\") || !strcmp(flags, \"wb\")) {\n        *file_flags = O_WRONLY | O_CREAT | O_TRUNC;\n        return true;\n    }\n\n    if (!strcmp(flags, \"a\") || !strcmp(flags, \"ab\")) {\n        *file_flags = O_WRONLY | O_CREAT | O_APPEND;\n        return true;\n    }\n\n    if (!strcmp(flags, \"r+\") || !strcmp(flags, \"rb+\") ||\n        !strcmp(flags, \"r+b\")) {\n        *file_flags = O_RDWR;\n        return true;\n    }\n\n    if (!strcmp(flags, \"w+\") || !strcmp(flags, \"wb+\") ||\n        !strcmp(flags, \"w+b\")) {\n        *file_flags = O_RDWR | O_CREAT | O_TRUNC;\n        return true;\n    }\n\n    if (!strcmp(flags, \"a+\") || !strcmp(flags, \"ab+\") ||\n        !strcmp(flags, \"a+b\")) {\n        *file_flags = O_RDWR | O_CREAT | O_APPEND;\n        return true;\n    }\n\n    return false;\n}\n\nstatic int ext4_trunc_inode(struct ext4_mountpoint *mp,\n                uint32_t index, uint64_t new_size)\n{\n    int r = EOK;\n    struct ext4_fs *const fs = &mp->fs;\n    struct ext4_inode_ref inode_ref;\n    uint64_t inode_size;\n    bool has_trans = mp->fs.jbd_journal && mp->fs.curr_trans;\n    r = ext4_fs_get_inode_ref(fs, index, &inode_ref);\n    if (r != EOK)\n        return r;\n\n    inode_size = ext4_inode_get_size(&fs->sb, inode_ref.inode);\n    ext4_fs_put_inode_ref(&inode_ref);\n    if (has_trans)\n        ext4_trans_stop(mp);\n\n    while (inode_size > new_size + CONFIG_MAX_TRUNCATE_SIZE) {\n\n        inode_size -= CONFIG_MAX_TRUNCATE_SIZE;\n\n        ext4_trans_start(mp);\n        r = ext4_fs_get_inode_ref(fs, index, &inode_ref);\n        if (r != EOK) {\n            ext4_trans_abort(mp);\n            break;\n        }\n        r = ext4_fs_truncate_inode(&inode_ref, inode_size);\n        if (r != EOK)\n            ext4_fs_put_inode_ref(&inode_ref);\n        else\n            r = ext4_fs_put_inode_ref(&inode_ref);\n\n        if (r != EOK) {\n            ext4_trans_abort(mp);\n            goto Finish;\n        } else\n            ext4_trans_stop(mp);\n    }\n\n    if (inode_size > new_size) {\n\n        inode_size = new_size;\n\n        ext4_trans_start(mp);\n        r = ext4_fs_get_inode_ref(fs, index, &inode_ref);\n        if (r != EOK) {\n            ext4_trans_abort(mp);\n            goto Finish;\n        }\n        r = ext4_fs_truncate_inode(&inode_ref, inode_size);\n        if (r != EOK)\n            ext4_fs_put_inode_ref(&inode_ref);\n        else\n            r = ext4_fs_put_inode_ref(&inode_ref);\n\n        if (r != EOK)\n            ext4_trans_abort(mp);\n        else\n            ext4_trans_stop(mp);\n\n    }\n\nFinish:\n\n    if (has_trans)\n        ext4_trans_start(mp);\n\n    return r;\n}\n\nstatic int ext4_trunc_dir(struct ext4_mountpoint *mp,\n              struct ext4_inode_ref *parent,\n              struct ext4_inode_ref *dir)\n{\n    int r = EOK;\n    bool is_dir = ext4_inode_is_type(&mp->fs.sb, dir->inode,\n            EXT4_INODE_MODE_DIRECTORY);\n    uint32_t block_size = ext4_sb_get_block_size(&mp->fs.sb);\n    if (!is_dir)\n        return EINVAL;\n\n#if CONFIG_DIR_INDEX_ENABLE\n    /* Initialize directory index if supported */\n    if (ext4_sb_feature_com(&mp->fs.sb, EXT4_FCOM_DIR_INDEX)) {\n        r = ext4_dir_dx_init(dir, parent);\n        if (r != EOK)\n            return r;\n\n        r = ext4_trunc_inode(mp, dir->index,\n                     EXT4_DIR_DX_INIT_BCNT * block_size);\n        if (r != EOK)\n            return r;\n    } else\n#endif\n    {\n        r = ext4_trunc_inode(mp, dir->index, block_size);\n        if (r != EOK)\n            return r;\n    }\n\n    return ext4_fs_truncate_inode(dir, 0);\n}\n\n/*\n * NOTICE: if filetype is equal to EXT4_DIRENTRY_UNKNOWN,\n * any filetype of the target dir entry will be accepted.\n */\nstatic int ext4_generic_open2(ext4_file *f, const char *path, int flags,\n                  int ftype, uint32_t *parent_inode,\n                  uint32_t *name_off)\n{\n    bool is_goal = false;\n    uint32_t imode = EXT4_INODE_MODE_DIRECTORY;\n    uint32_t next_inode;\n\n    int r;\n    int len;\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n    struct ext4_dir_search_result result;\n    struct ext4_inode_ref ref;\n\n    f->mp = 0;\n\n    if (!mp)\n        return ENOENT;\n\n    struct ext4_fs *const fs = &mp->fs;\n    struct ext4_sblock *const sb = &mp->fs.sb;\n\n    if (fs->read_only && flags & O_CREAT)\n        return EROFS;\n\n    f->flags = flags;\n\n    /*Skip mount point*/\n    path += strlen(mp->name);\n\n    if (name_off)\n        *name_off = strlen(mp->name);\n\n    /*Load root*/\n    r = ext4_fs_get_inode_ref(fs, EXT4_INODE_ROOT_INDEX, &ref);\n    if (r != EOK)\n        return r;\n\n    if (parent_inode)\n        *parent_inode = ref.index;\n\n    len = ext4_path_check(path, &is_goal);\n    while (1) {\n\n        len = ext4_path_check(path, &is_goal);\n        if (!len) {\n            /*If root open was request.*/\n            if (ftype == EXT4_DE_DIR || ftype == EXT4_DE_UNKNOWN)\n                if (is_goal)\n                    break;\n\n            r = ENOENT;\n            break;\n        }\n\n        r = ext4_dir_find_entry(&result, &ref, path, len);\n        if (r != EOK) {\n\n            /*Destroy last result*/\n            ext4_dir_destroy_result(&ref, &result);\n            if (r != ENOENT)\n                break;\n\n            if (!(f->flags & O_CREAT))\n                break;\n\n            /*O_CREAT allows create new entry*/\n            struct ext4_inode_ref child_ref;\n            r = ext4_fs_alloc_inode(fs, &child_ref,\n                    is_goal ? ftype : EXT4_DE_DIR);\n\n            if (r != EOK)\n                break;\n\n            ext4_fs_inode_blocks_init(fs, &child_ref);\n\n            /*Link with root dir.*/\n            r = ext4_link(mp, &ref, &child_ref, path, len, false);\n            if (r != EOK) {\n                /*Fail. Free new inode.*/\n                ext4_fs_free_inode(&child_ref);\n                /*We do not want to write new inode.\n                  But block has to be released.*/\n                child_ref.dirty = false;\n                ext4_fs_put_inode_ref(&child_ref);\n                break;\n            }\n\n            ext4_fs_put_inode_ref(&child_ref);\n            continue;\n        }\n\n        if (parent_inode)\n            *parent_inode = ref.index;\n\n        next_inode = ext4_dir_en_get_inode(result.dentry);\n        if (ext4_sb_feature_incom(sb, EXT4_FINCOM_FILETYPE)) {\n            uint8_t t;\n            t = ext4_dir_en_get_inode_type(sb, result.dentry);\n            imode = ext4_fs_correspond_inode_mode(t);\n        } else {\n            struct ext4_inode_ref child_ref;\n            r = ext4_fs_get_inode_ref(fs, next_inode, &child_ref);\n            if (r != EOK)\n                break;\n\n            imode = ext4_inode_type(sb, child_ref.inode);\n            ext4_fs_put_inode_ref(&child_ref);\n        }\n\n        r = ext4_dir_destroy_result(&ref, &result);\n        if (r != EOK)\n            break;\n\n        /*If expected file error*/\n        if (imode != EXT4_INODE_MODE_DIRECTORY && !is_goal) {\n            r = ENOENT;\n            break;\n        }\n        if (ftype != EXT4_DE_UNKNOWN) {\n            bool df = imode != ext4_fs_correspond_inode_mode(ftype);\n            if (df && is_goal) {\n                r = ENOENT;\n                break;\n            }\n        }\n\n        r = ext4_fs_put_inode_ref(&ref);\n        if (r != EOK)\n            break;\n\n        r = ext4_fs_get_inode_ref(fs, next_inode, &ref);\n        if (r != EOK)\n            break;\n\n        if (is_goal)\n            break;\n\n        path += len + 1;\n\n        if (name_off)\n            *name_off += len + 1;\n    }\n\n    if (r != EOK) {\n        ext4_fs_put_inode_ref(&ref);\n        return r;\n    }\n\n    if (is_goal) {\n\n        if ((f->flags & O_TRUNC) && (imode == EXT4_INODE_MODE_FILE)) {\n            r = ext4_trunc_inode(mp, ref.index, 0);\n            if (r != EOK) {\n                ext4_fs_put_inode_ref(&ref);\n                return r;\n            }\n        }\n\n        f->mp = mp;\n        f->fsize = ext4_inode_get_size(sb, ref.inode);\n        f->inode = ref.index;\n        f->fpos = 0;\n\n        if (f->flags & O_APPEND)\n            f->fpos = f->fsize;\n    }\n\n    return ext4_fs_put_inode_ref(&ref);\n}\n\n/****************************************************************************/\n\nstatic int ext4_generic_open(ext4_file *f, const char *path, const char *flags,\n                 bool file_expect, uint32_t *parent_inode,\n                 uint32_t *name_off)\n{\n    uint32_t iflags;\n    int filetype;\n    int r;\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n\n    if (ext4_parse_flags(flags, &iflags) == false)\n        return EINVAL;\n\n    if (file_expect == true)\n        filetype = EXT4_DE_REG_FILE;\n    else\n        filetype = EXT4_DE_DIR;\n\n    if (iflags & O_CREAT)\n        ext4_trans_start(mp);\n\n    r = ext4_generic_open2(f, path, iflags, filetype, parent_inode,\n                name_off);\n\n    if (iflags & O_CREAT) {\n        if (r == EOK)\n            ext4_trans_stop(mp);\n        else\n            ext4_trans_abort(mp);\n    }\n\n    return r;\n}\n\nstatic int ext4_create_hardlink(const char *path,\n        struct ext4_inode_ref *child_ref, bool rename)\n{\n    bool is_goal = false;\n    uint32_t inode_mode = EXT4_INODE_MODE_DIRECTORY;\n    uint32_t next_inode;\n\n    int r;\n    int len;\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n    struct ext4_dir_search_result result;\n    struct ext4_inode_ref ref;\n\n    if (!mp)\n        return ENOENT;\n\n    struct ext4_fs *const fs = &mp->fs;\n    struct ext4_sblock *const sb = &mp->fs.sb;\n\n    /*Skip mount point*/\n    path += strlen(mp->name);\n\n    /*Load root*/\n    r = ext4_fs_get_inode_ref(fs, EXT4_INODE_ROOT_INDEX, &ref);\n    if (r != EOK)\n        return r;\n\n    len = ext4_path_check(path, &is_goal);\n    while (1) {\n\n        len = ext4_path_check(path, &is_goal);\n        if (!len) {\n            /*If root open was request.*/\n            r = is_goal ? EINVAL : ENOENT;\n            break;\n        }\n\n        r = ext4_dir_find_entry(&result, &ref, path, len);\n        if (r != EOK) {\n\n            /*Destroy last result*/\n            ext4_dir_destroy_result(&ref, &result);\n\n            if (r != ENOENT || !is_goal)\n                break;\n\n            /*Link with root dir.*/\n            r = ext4_link(mp, &ref, child_ref, path, len, rename);\n            break;\n        } else if (r == EOK && is_goal) {\n            /*Destroy last result*/\n            ext4_dir_destroy_result(&ref, &result);\n            r = EEXIST;\n            break;\n        }\n\n        next_inode = result.dentry->inode;\n        if (ext4_sb_feature_incom(sb, EXT4_FINCOM_FILETYPE)) {\n            uint8_t t;\n            t = ext4_dir_en_get_inode_type(sb, result.dentry);\n            inode_mode = ext4_fs_correspond_inode_mode(t);\n        } else {\n            struct ext4_inode_ref child_ref;\n            r = ext4_fs_get_inode_ref(fs, next_inode, &child_ref);\n            if (r != EOK)\n                break;\n\n            inode_mode = ext4_inode_type(sb, child_ref.inode);\n            ext4_fs_put_inode_ref(&child_ref);\n        }\n\n        r = ext4_dir_destroy_result(&ref, &result);\n        if (r != EOK)\n            break;\n\n        if (inode_mode != EXT4_INODE_MODE_DIRECTORY) {\n            r = is_goal ? EEXIST : ENOENT;\n            break;\n        }\n\n        r = ext4_fs_put_inode_ref(&ref);\n        if (r != EOK)\n            break;\n\n        r = ext4_fs_get_inode_ref(fs, next_inode, &ref);\n        if (r != EOK)\n            break;\n\n        if (is_goal)\n            break;\n\n        path += len + 1;\n    };\n\n    if (r != EOK) {\n        ext4_fs_put_inode_ref(&ref);\n        return r;\n    }\n\n    r = ext4_fs_put_inode_ref(&ref);\n    return r;\n}\n\nstatic int ext4_remove_orig_reference(const char *path, uint32_t name_off,\n                      struct ext4_inode_ref *parent_ref,\n                      struct ext4_inode_ref *child_ref)\n{\n    bool is_goal;\n    int r;\n    int len;\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n\n    if (!mp)\n        return ENOENT;\n\n    /*Set path*/\n    path += name_off;\n\n    len = ext4_path_check(path, &is_goal);\n\n    /* Remove entry from parent directory */\n    r = ext4_dir_remove_entry(parent_ref, path, len);\n    if (r != EOK)\n        goto Finish;\n\n    if (ext4_inode_is_type(&mp->fs.sb, child_ref->inode,\n                   EXT4_INODE_MODE_DIRECTORY)) {\n        ext4_fs_inode_links_count_dec(parent_ref);\n        parent_ref->dirty = true;\n    }\nFinish:\n    return r;\n}\n\nint ext4_flink(const char *path, const char *hardlink_path)\n{\n    int r;\n    ext4_file f;\n    uint32_t name_off;\n    bool child_loaded = false;\n    uint32_t parent_inode, child_inode;\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n    struct ext4_mountpoint *target_mp = ext4_get_mount(hardlink_path);\n    struct ext4_inode_ref child_ref;\n\n    if (!mp)\n        return ENOENT;\n\n    if (mp->fs.read_only)\n        return EROFS;\n\n    /* Will that happen? Anyway return EINVAL for such case. */\n    if (mp != target_mp)\n        return EINVAL;\n\n    EXT4_MP_LOCK(mp);\n    r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN,\n                   &parent_inode, &name_off);\n    if (r != EOK) {\n        EXT4_MP_UNLOCK(mp);\n        return r;\n    }\n\n    child_inode = f.inode;\n    ext4_fclose(&f);\n    ext4_trans_start(mp);\n\n    /*We have file to unlink. Load it.*/\n    r = ext4_fs_get_inode_ref(&mp->fs, child_inode, &child_ref);\n    if (r != EOK)\n        goto Finish;\n\n    child_loaded = true;\n\n    /* Creating hardlink for directory is not allowed. */\n    if (ext4_inode_is_type(&mp->fs.sb, child_ref.inode,\n                   EXT4_INODE_MODE_DIRECTORY)) {\n        r = EINVAL;\n        goto Finish;\n    }\n\n    r = ext4_create_hardlink(hardlink_path, &child_ref, false);\n\nFinish:\n    if (child_loaded)\n        ext4_fs_put_inode_ref(&child_ref);\n\n    if (r != EOK)\n        ext4_trans_abort(mp);\n    else\n        ext4_trans_stop(mp);\n\n    EXT4_MP_UNLOCK(mp);\n    return r;\n\n}\n\nint ext4_frename(const char *path, const char *new_path)\n{\n    int r;\n    ext4_file f;\n    uint32_t name_off;\n    bool parent_loaded = false, child_loaded = false;\n    uint32_t parent_inode, child_inode;\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n    struct ext4_inode_ref child_ref, parent_ref;\n\n    if (!mp)\n        return ENOENT;\n\n    if (mp->fs.read_only)\n        return EROFS;\n\n    EXT4_MP_LOCK(mp);\n\n    r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN,\n                &parent_inode, &name_off);\n    if (r != EOK) {\n        EXT4_MP_UNLOCK(mp);\n        return r;\n    }\n\n    child_inode = f.inode;\n    ext4_fclose(&f);\n    ext4_trans_start(mp);\n\n    /*Load parent*/\n    r = ext4_fs_get_inode_ref(&mp->fs, parent_inode, &parent_ref);\n    if (r != EOK)\n        goto Finish;\n\n    parent_loaded = true;\n\n    /*We have file to unlink. Load it.*/\n    r = ext4_fs_get_inode_ref(&mp->fs, child_inode, &child_ref);\n    if (r != EOK)\n        goto Finish;\n\n    child_loaded = true;\n\n    r = ext4_create_hardlink(new_path, &child_ref, true);\n    if (r != EOK)\n        goto Finish;\n\n    r = ext4_remove_orig_reference(path, name_off, &parent_ref, &child_ref);\n    if (r != EOK)\n        goto Finish;\n\nFinish:\n    if (parent_loaded)\n        ext4_fs_put_inode_ref(&parent_ref);\n\n    if (child_loaded)\n        ext4_fs_put_inode_ref(&child_ref);\n\n    if (r != EOK)\n        ext4_trans_abort(mp);\n    else\n        ext4_trans_stop(mp);\n\n    EXT4_MP_UNLOCK(mp);\n    return r;\n\n}\n\n/****************************************************************************/\n\nint ext4_get_sblock(const char *mount_point, struct ext4_sblock **sb)\n{\n    struct ext4_mountpoint *mp = ext4_get_mount(mount_point);\n\n    if (!mp)\n        return ENOENT;\n\n    *sb = &mp->fs.sb;\n    return EOK;\n}\n\nint ext4_cache_write_back(const char *path, bool on)\n{\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n    int ret;\n\n    if (!mp)\n        return ENOENT;\n\n    EXT4_MP_LOCK(mp);\n    ret = ext4_block_cache_write_back(mp->fs.bdev, on);\n    EXT4_MP_UNLOCK(mp);\n    return ret;\n}\n\nint ext4_cache_flush(const char *path)\n{\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n    int ret;\n\n    if (!mp)\n        return ENOENT;\n\n    EXT4_MP_LOCK(mp);\n    ret = ext4_block_cache_flush(mp->fs.bdev);\n    EXT4_MP_UNLOCK(mp);\n    return ret;\n}\n\nint ext4_fremove(const char *path)\n{\n    ext4_file f;\n    uint32_t parent_inode;\n    uint32_t child_inode;\n    uint32_t name_off;\n    bool is_goal;\n    int r;\n    int len;\n    struct ext4_inode_ref child;\n    struct ext4_inode_ref parent;\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n\n    if (!mp)\n        return ENOENT;\n\n    if (mp->fs.read_only)\n        return EROFS;\n\n    EXT4_MP_LOCK(mp);\n    r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN,\n                   &parent_inode, &name_off);\n    if (r != EOK) {\n        EXT4_MP_UNLOCK(mp);\n        return r;\n    }\n\n    child_inode = f.inode;\n    ext4_fclose(&f);\n    ext4_trans_start(mp);\n\n    /*Load parent*/\n    r = ext4_fs_get_inode_ref(&mp->fs, parent_inode, &parent);\n    if (r != EOK) {\n        ext4_trans_abort(mp);\n        EXT4_MP_UNLOCK(mp);\n        return r;\n    }\n\n    /*We have file to delete. Load it.*/\n    r = ext4_fs_get_inode_ref(&mp->fs, child_inode, &child);\n    if (r != EOK) {\n        ext4_fs_put_inode_ref(&parent);\n        ext4_trans_abort(mp);\n        EXT4_MP_UNLOCK(mp);\n        return r;\n    }\n    /* We do not allow opening files here. */\n    if (ext4_inode_type(&mp->fs.sb, child.inode) ==\n        EXT4_INODE_MODE_DIRECTORY) {\n        ext4_fs_put_inode_ref(&parent);\n        ext4_fs_put_inode_ref(&child);\n        ext4_trans_abort(mp);\n        EXT4_MP_UNLOCK(mp);\n        return r;\n    }\n\n    /*Link count will be zero, the inode should be freed. */\n    if (ext4_inode_get_links_cnt(child.inode) == 1) {\n        ext4_block_cache_write_back(mp->fs.bdev, 1);\n        r = ext4_trunc_inode(mp, child.index, 0);\n        if (r != EOK) {\n            ext4_fs_put_inode_ref(&parent);\n            ext4_fs_put_inode_ref(&child);\n            ext4_trans_abort(mp);\n            EXT4_MP_UNLOCK(mp);\n            return r;\n        }\n        ext4_block_cache_write_back(mp->fs.bdev, 0);\n    }\n\n    /*Set path*/\n    path += name_off;\n\n    len = ext4_path_check(path, &is_goal);\n\n    /*Unlink from parent*/\n    r = ext4_unlink(mp, &parent, &child, path, len);\n    if (r != EOK)\n        goto Finish;\n\n    /*Link count is zero, the inode should be freed. */\n    if (!ext4_inode_get_links_cnt(child.inode)) {\n        ext4_inode_set_del_time(child.inode, -1L);\n\n        r = ext4_fs_free_inode(&child);\n        if (r != EOK)\n            goto Finish;\n    }\n\nFinish:\n    ext4_fs_put_inode_ref(&child);\n    ext4_fs_put_inode_ref(&parent);\n\n    if (r != EOK)\n        ext4_trans_abort(mp);\n    else\n        ext4_trans_stop(mp);\n\n    EXT4_MP_UNLOCK(mp);\n    return r;\n}\n\nint ext4_fopen(ext4_file *file, const char *path, const char *flags)\n{\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n    int r;\n\n    if (!mp)\n        return ENOENT;\n\n    EXT4_MP_LOCK(mp);\n\n    ext4_block_cache_write_back(mp->fs.bdev, 1);\n    r = ext4_generic_open(file, path, flags, true, 0, 0);\n    ext4_block_cache_write_back(mp->fs.bdev, 0);\n\n    EXT4_MP_UNLOCK(mp);\n    return r;\n}\n\nint ext4_fopen2(ext4_file *file, const char *path, int flags)\n{\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n    int r;\n    int filetype;\n\n    if (!mp)\n        return ENOENT;\n\n    filetype = EXT4_DE_REG_FILE;\n    EXT4_MP_LOCK(mp);\n    ext4_block_cache_write_back(mp->fs.bdev, 1);\n\n    if (flags & O_CREAT)\n        ext4_trans_start(mp);\n\n    r = ext4_generic_open2(file, path, flags, filetype, NULL, NULL);\n\n    if (flags & O_CREAT) {\n        if (r == EOK)\n            ext4_trans_stop(mp);\n        else\n            ext4_trans_abort(mp);\n    }\n\n    ext4_block_cache_write_back(mp->fs.bdev, 0);\n    EXT4_MP_UNLOCK(mp);\n\n    return r;\n}\n\nint ext4_fclose(ext4_file *file)\n{\n    ext4_assert(file && file->mp);\n\n    file->mp = 0;\n    file->flags = 0;\n    file->inode = 0;\n    file->fpos = file->fsize = 0;\n\n    return EOK;\n}\n\nstatic int ext4_ftruncate_no_lock(ext4_file *file, uint64_t size)\n{\n    struct ext4_inode_ref ref;\n    int r;\n\n\n    r = ext4_fs_get_inode_ref(&file->mp->fs, file->inode, &ref);\n    if (r != EOK) {\n        EXT4_MP_UNLOCK(file->mp);\n        return r;\n    }\n\n    /*Sync file size*/\n    file->fsize = ext4_inode_get_size(&file->mp->fs.sb, ref.inode);\n    if (file->fsize <= size) {\n        r = EOK;\n        goto Finish;\n    }\n\n    /*Start write back cache mode.*/\n    r = ext4_block_cache_write_back(file->mp->fs.bdev, 1);\n    if (r != EOK)\n        goto Finish;\n\n    r = ext4_trunc_inode(file->mp, ref.index, size);\n    if (r != EOK)\n        goto Finish;\n\n    file->fsize = size;\n    if (file->fpos > size)\n        file->fpos = size;\n\n    /*Stop write back cache mode*/\n    ext4_block_cache_write_back(file->mp->fs.bdev, 0);\n\n    if (r != EOK)\n        goto Finish;\n\nFinish:\n    ext4_fs_put_inode_ref(&ref);\n    return r;\n\n}\n\nint ext4_ftruncate(ext4_file *f, uint64_t size)\n{\n    int r;\n    ext4_assert(f && f->mp);\n\n    if (f->mp->fs.read_only)\n        return EROFS;\n\n    if (f->flags & O_RDONLY)\n        return EPERM;\n\n    EXT4_MP_LOCK(f->mp);\n\n    ext4_trans_start(f->mp);\n    r = ext4_ftruncate_no_lock(f, size);\n    if (r != EOK)\n        ext4_trans_abort(f->mp);\n    else\n        ext4_trans_stop(f->mp);\n\n    EXT4_MP_UNLOCK(f->mp);\n    return r;\n}\n\nint ext4_fread(ext4_file *file, void *buf, size_t size, size_t *rcnt)\n{\n    uint32_t unalg;\n    uint32_t iblock_idx;\n    uint32_t iblock_last;\n    uint32_t block_size;\n\n    ext4_fsblk_t fblock;\n    ext4_fsblk_t fblock_start;\n    uint32_t fblock_count;\n\n    uint8_t *u8_buf = buf;\n    int r;\n    struct ext4_inode_ref ref;\n\n    ext4_assert(file && file->mp);\n\n    if (file->flags & O_WRONLY)\n        return EPERM;\n\n    if (!size)\n        return EOK;\n\n    EXT4_MP_LOCK(file->mp);\n\n    struct ext4_fs *const fs = &file->mp->fs;\n    struct ext4_sblock *const sb = &file->mp->fs.sb;\n\n    if (rcnt)\n        *rcnt = 0;\n\n    r = ext4_fs_get_inode_ref(fs, file->inode, &ref);\n    if (r != EOK) {\n        EXT4_MP_UNLOCK(file->mp);\n        return r;\n    }\n\n    /*Sync file size*/\n    file->fsize = ext4_inode_get_size(sb, ref.inode);\n\n    block_size = ext4_sb_get_block_size(sb);\n    size = ((uint64_t)size > (file->fsize - file->fpos))\n        ? ((size_t)(file->fsize - file->fpos)) : size;\n\n    iblock_idx = (uint32_t)((file->fpos) / block_size);\n    iblock_last = (uint32_t)((file->fpos + size) / block_size);\n    unalg = (file->fpos) % block_size;\n\n    /*If the size of symlink is smaller than 60 bytes*/\n    bool softlink;\n    softlink = ext4_inode_is_type(sb, ref.inode, EXT4_INODE_MODE_SOFTLINK);\n    if (softlink && file->fsize < sizeof(ref.inode->blocks)\n             && !ext4_inode_get_blocks_count(sb, ref.inode)) {\n\n        char *content = (char *)ref.inode->blocks;\n        if (file->fpos < file->fsize) {\n            size_t len = size;\n            if (unalg + size > (uint32_t)file->fsize)\n                len = (uint32_t)file->fsize - unalg;\n            memcpy(buf, content + unalg, len);\n            if (rcnt)\n                *rcnt = len;\n\n        }\n\n        r = EOK;\n        goto Finish;\n    }\n\n    if (unalg) {\n        size_t len =  size;\n        if (size > (block_size - unalg))\n            len = block_size - unalg;\n\n        r = ext4_fs_get_inode_dblk_idx(&ref, iblock_idx, &fblock, true);\n        if (r != EOK)\n            goto Finish;\n\n        /* Do we get an unwritten range? */\n        if (fblock != 0) {\n            uint64_t off = fblock * block_size + unalg;\n            r = ext4_block_readbytes(file->mp->fs.bdev, off, u8_buf, len);\n            if (r != EOK)\n                goto Finish;\n\n        } else {\n            /* Yes, we do. */\n            memset(u8_buf, 0, len);\n        }\n\n        u8_buf += len;\n        size -= len;\n        file->fpos += len;\n\n        if (rcnt)\n            *rcnt += len;\n\n        iblock_idx++;\n    }\n\n    fblock_start = 0;\n    fblock_count = 0;\n    while (size >= block_size) {\n        while (iblock_idx < iblock_last) {\n            r = ext4_fs_get_inode_dblk_idx(&ref, iblock_idx,\n                               &fblock, true);\n            if (r != EOK)\n                goto Finish;\n\n            iblock_idx++;\n\n            if (!fblock_start)\n                fblock_start = fblock;\n\n            if ((fblock_start + fblock_count) != fblock)\n                break;\n\n            fblock_count++;\n        }\n\n        r = ext4_blocks_get_direct(file->mp->fs.bdev, u8_buf, fblock_start,\n                       fblock_count);\n        if (r != EOK)\n            goto Finish;\n\n        size -= block_size * fblock_count;\n        u8_buf += block_size * fblock_count;\n        file->fpos += block_size * fblock_count;\n\n        if (rcnt)\n            *rcnt += block_size * fblock_count;\n\n        fblock_start = fblock;\n        fblock_count = 1;\n    }\n\n    if (size) {\n        uint64_t off;\n        r = ext4_fs_get_inode_dblk_idx(&ref, iblock_idx, &fblock, true);\n        if (r != EOK)\n            goto Finish;\n\n        off = fblock * block_size;\n        r = ext4_block_readbytes(file->mp->fs.bdev, off, u8_buf, size);\n        if (r != EOK)\n            goto Finish;\n\n        file->fpos += size;\n\n        if (rcnt)\n            *rcnt += size;\n    }\n\nFinish:\n    ext4_fs_put_inode_ref(&ref);\n    EXT4_MP_UNLOCK(file->mp);\n    return r;\n}\n\nint ext4_fwrite(ext4_file *file, const void *buf, size_t size, size_t *wcnt)\n{\n    uint32_t unalg;\n    uint32_t iblk_idx;\n    uint32_t iblock_last;\n    uint32_t ifile_blocks;\n    uint32_t block_size;\n\n    uint32_t fblock_count;\n    ext4_fsblk_t fblk;\n    ext4_fsblk_t fblock_start;\n\n    struct ext4_inode_ref ref;\n    const uint8_t *u8_buf = buf;\n    int r, rr = EOK;\n\n    ext4_assert(file && file->mp);\n\n    if (file->mp->fs.read_only)\n        return EROFS;\n\n    if (file->flags & O_RDONLY)\n        return EPERM;\n\n    if (!size)\n        return EOK;\n\n    EXT4_MP_LOCK(file->mp);\n    ext4_trans_start(file->mp);\n\n    struct ext4_fs *const fs = &file->mp->fs;\n    struct ext4_sblock *const sb = &file->mp->fs.sb;\n\n    if (wcnt)\n        *wcnt = 0;\n\n    r = ext4_fs_get_inode_ref(fs, file->inode, &ref);\n    if (r != EOK) {\n        ext4_trans_abort(file->mp);\n        EXT4_MP_UNLOCK(file->mp);\n        return r;\n    }\n\n    /*Sync file size*/\n    file->fsize = ext4_inode_get_size(sb, ref.inode);\n    block_size = ext4_sb_get_block_size(sb);\n\n    iblock_last = (uint32_t)((file->fpos + size) / block_size);\n    iblk_idx = (uint32_t)(file->fpos / block_size);\n    ifile_blocks = (uint32_t)((file->fsize + block_size - 1) / block_size);\n\n    unalg = (file->fpos) % block_size;\n\n    if (unalg) {\n        size_t len =  size;\n        uint64_t off;\n        if (size > (block_size - unalg))\n            len = block_size - unalg;\n\n        r = ext4_fs_init_inode_dblk_idx(&ref, iblk_idx, &fblk);\n        if (r != EOK)\n            goto Finish;\n\n        off = fblk * block_size + unalg;\n        r = ext4_block_writebytes(file->mp->fs.bdev, off, u8_buf, len);\n        if (r != EOK)\n            goto Finish;\n\n        u8_buf += len;\n        size -= len;\n        file->fpos += len;\n\n        if (wcnt)\n            *wcnt += len;\n\n        iblk_idx++;\n    }\n\n    /*Start write back cache mode.*/\n    r = ext4_block_cache_write_back(file->mp->fs.bdev, 1);\n    if (r != EOK)\n        goto Finish;\n\n    fblock_start = 0;\n    fblock_count = 0;\n    while (size >= block_size) {\n\n        while (iblk_idx < iblock_last) {\n            if (iblk_idx < ifile_blocks) {\n                r = ext4_fs_init_inode_dblk_idx(&ref, iblk_idx,\n                                &fblk);\n                if (r != EOK)\n                    goto Finish;\n            } else {\n                rr = ext4_fs_append_inode_dblk(&ref, &fblk,\n                                   &iblk_idx);\n                if (rr != EOK) {\n                    /* Unable to append more blocks. But\n                     * some block might be allocated already\n                     * */\n                    break;\n                }\n            }\n\n            iblk_idx++;\n\n            if (!fblock_start) {\n                fblock_start = fblk;\n            }\n\n            if ((fblock_start + fblock_count) != fblk)\n                break;\n\n            fblock_count++;\n        }\n\n        r = ext4_blocks_set_direct(file->mp->fs.bdev, u8_buf, fblock_start,\n                       fblock_count);\n        if (r != EOK)\n            break;\n\n        size -= block_size * fblock_count;\n        u8_buf += block_size * fblock_count;\n        file->fpos += block_size * fblock_count;\n\n        if (wcnt)\n            *wcnt += block_size * fblock_count;\n\n        fblock_start = fblk;\n        fblock_count = 1;\n\n        if (rr != EOK) {\n            /*ext4_fs_append_inode_block has failed and no\n             * more blocks might be written. But node size\n             * should be updated.*/\n            r = rr;\n            goto out_fsize;\n        }\n    }\n\n    /*Stop write back cache mode*/\n    ext4_block_cache_write_back(file->mp->fs.bdev, 0);\n\n    if (r != EOK)\n        goto Finish;\n\n    if (size) {\n        uint64_t off;\n        if (iblk_idx < ifile_blocks) {\n            r = ext4_fs_init_inode_dblk_idx(&ref, iblk_idx, &fblk);\n            if (r != EOK)\n                goto Finish;\n        } else {\n            r = ext4_fs_append_inode_dblk(&ref, &fblk, &iblk_idx);\n            if (r != EOK)\n                /*Node size sholud be updated.*/\n                goto out_fsize;\n        }\n\n        off = fblk * block_size;\n        r = ext4_block_writebytes(file->mp->fs.bdev, off, u8_buf, size);\n        if (r != EOK)\n            goto Finish;\n\n        file->fpos += size;\n\n        if (wcnt)\n            *wcnt += size;\n    }\n\nout_fsize:\n    if (file->fpos > file->fsize) {\n        file->fsize = file->fpos;\n        ext4_inode_set_size(ref.inode, file->fsize);\n        ref.dirty = true;\n    }\n\nFinish:\n    r = ext4_fs_put_inode_ref(&ref);\n\n    if (r != EOK)\n        ext4_trans_abort(file->mp);\n    else\n        ext4_trans_stop(file->mp);\n\n    EXT4_MP_UNLOCK(file->mp);\n    return r;\n}\n\nint ext4_fseek(ext4_file *file, int64_t offset, uint32_t origin)\n{\n    switch (origin) {\n    case SEEK_SET:\n        if (offset < 0 || (uint64_t)offset > file->fsize)\n            return EINVAL;\n\n        file->fpos = offset;\n        return EOK;\n    case SEEK_CUR:\n        if ((offset < 0 && (uint64_t)(-offset) > file->fpos) ||\n            (offset > 0 &&\n             (uint64_t)offset > (file->fsize - file->fpos)))\n            return EINVAL;\n\n        file->fpos += offset;\n        return EOK;\n    case SEEK_END:\n        if (offset < 0 || (uint64_t)offset > file->fsize)\n            return EINVAL;\n\n        file->fpos = file->fsize - offset;\n        return EOK;\n    }\n    return EINVAL;\n}\n\nuint64_t ext4_ftell(ext4_file *file)\n{\n    return file->fpos;\n}\n\nuint64_t ext4_fsize(ext4_file *file)\n{\n    return file->fsize;\n}\n\n\nstatic int ext4_trans_get_inode_ref(const char *path,\n                    struct ext4_mountpoint *mp,\n                    struct ext4_inode_ref *inode_ref)\n{\n    int r;\n    ext4_file f;\n\n    r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN, NULL, NULL);\n    if (r != EOK)\n        return r;\n\n    ext4_trans_start(mp);\n\n    r = ext4_fs_get_inode_ref(&mp->fs, f.inode, inode_ref);\n    if (r != EOK) {\n        ext4_trans_abort(mp);\n        return r;\n    }\n\n    return r;\n}\n\nstatic int ext4_trans_put_inode_ref(struct ext4_mountpoint *mp,\n                    struct ext4_inode_ref *inode_ref)\n{\n    int r;\n\n    r = ext4_fs_put_inode_ref(inode_ref);\n    if (r != EOK)\n        ext4_trans_abort(mp);\n    else\n        ext4_trans_stop(mp);\n\n    return r;\n}\n\n\nint ext4_raw_inode_fill(const char *path, uint32_t *ret_ino,\n            struct ext4_inode *inode)\n{\n    int r;\n    ext4_file f;\n    struct ext4_inode_ref inode_ref;\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n\n    if (!mp)\n        return ENOENT;\n\n    EXT4_MP_LOCK(mp);\n\n    r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN, NULL, NULL);\n    if (r != EOK) {\n        EXT4_MP_UNLOCK(mp);\n        return r;\n    }\n\n    /*Load parent*/\n    r = ext4_fs_get_inode_ref(&mp->fs, f.inode, &inode_ref);\n    if (r != EOK) {\n        EXT4_MP_UNLOCK(mp);\n        return r;\n    }\n\n    if (ret_ino)\n        *ret_ino = f.inode;\n\n    memcpy(inode, inode_ref.inode, sizeof(struct ext4_inode));\n    ext4_fs_put_inode_ref(&inode_ref);\n    EXT4_MP_UNLOCK(mp);\n\n    return r;\n}\n\nint ext4_inode_exist(const char *path, int type)\n{\n    int r;\n    ext4_file f;\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n\n    if (!mp)\n        return ENOENT;\n\n    EXT4_MP_LOCK(mp);\n    r = ext4_generic_open2(&f, path, O_RDONLY, type, NULL, NULL);\n    EXT4_MP_UNLOCK(mp);\n\n    return r;\n}\n\nint ext4_mode_set(const char *path, uint32_t mode)\n{\n    int r;\n    uint32_t orig_mode;\n    struct ext4_inode_ref inode_ref;\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n\n    if (!mp)\n        return ENOENT;\n\n    if (mp->fs.read_only)\n        return EROFS;\n\n    EXT4_MP_LOCK(mp);\n\n    r = ext4_trans_get_inode_ref(path, mp, &inode_ref);\n    if (r != EOK)\n        goto Finish;\n\n    orig_mode = ext4_inode_get_mode(&mp->fs.sb, inode_ref.inode);\n    orig_mode &= ~0xFFF;\n    orig_mode |= mode & 0xFFF;\n    ext4_inode_set_mode(&mp->fs.sb, inode_ref.inode, orig_mode);\n\n    inode_ref.dirty = true;\n    r = ext4_trans_put_inode_ref(mp, &inode_ref);\n\n    Finish:\n    EXT4_MP_UNLOCK(mp);\n\n    return r;\n}\n\nint ext4_owner_set(const char *path, uint32_t uid, uint32_t gid)\n{\n    int r;\n    struct ext4_inode_ref inode_ref;\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n\n    if (!mp)\n        return ENOENT;\n\n    if (mp->fs.read_only)\n        return EROFS;\n\n    EXT4_MP_LOCK(mp);\n\n    r = ext4_trans_get_inode_ref(path, mp, &inode_ref);\n    if (r != EOK)\n        goto Finish;\n\n    ext4_inode_set_uid(inode_ref.inode, uid);\n    ext4_inode_set_gid(inode_ref.inode, gid);\n\n    inode_ref.dirty = true;\n    r = ext4_trans_put_inode_ref(mp, &inode_ref);\n\n    Finish:\n    EXT4_MP_UNLOCK(mp);\n\n    return r;\n}\n\nint ext4_mode_get(const char *path, uint32_t *mode)\n{\n    struct ext4_inode_ref inode_ref;\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n    ext4_file f;\n    int r;\n\n    if (!mp)\n        return ENOENT;\n\n    EXT4_MP_LOCK(mp);\n\n    r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN, NULL, NULL);\n    if (r != EOK)\n        goto Finish;\n\n    r = ext4_fs_get_inode_ref(&mp->fs, f.inode, &inode_ref);\n    if (r != EOK)\n        goto Finish;\n\n    *mode = ext4_inode_get_mode(&mp->fs.sb, inode_ref.inode);\n    r = ext4_fs_put_inode_ref(&inode_ref);\n\n    Finish:\n    EXT4_MP_UNLOCK(mp);\n\n    return r;\n}\n\nint ext4_owner_get(const char *path, uint32_t *uid, uint32_t *gid)\n{\n    struct ext4_inode_ref inode_ref;\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n    ext4_file f;\n    int r;\n\n    if (!mp)\n        return ENOENT;\n\n    EXT4_MP_LOCK(mp);\n\n    r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN, NULL, NULL);\n    if (r != EOK)\n        goto Finish;\n\n    r = ext4_fs_get_inode_ref(&mp->fs, f.inode, &inode_ref);\n    if (r != EOK)\n        goto Finish;\n\n    *uid = ext4_inode_get_uid(inode_ref.inode);\n    *gid = ext4_inode_get_gid(inode_ref.inode);\n    r = ext4_fs_put_inode_ref(&inode_ref);\n\n    Finish:\n    EXT4_MP_UNLOCK(mp);\n\n    return r;\n}\n\nint ext4_atime_set(const char *path, uint32_t atime)\n{\n    struct ext4_inode_ref inode_ref;\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n    int r;\n\n    if (!mp)\n        return ENOENT;\n\n    if (mp->fs.read_only)\n        return EROFS;\n\n    EXT4_MP_LOCK(mp);\n\n    r = ext4_trans_get_inode_ref(path, mp, &inode_ref);\n    if (r != EOK)\n        goto Finish;\n\n    ext4_inode_set_access_time(inode_ref.inode, atime);\n    inode_ref.dirty = true;\n    r = ext4_trans_put_inode_ref(mp, &inode_ref);\n\n    Finish:\n    EXT4_MP_UNLOCK(mp);\n\n    return r;\n}\n\nint ext4_mtime_set(const char *path, uint32_t mtime)\n{\n    struct ext4_inode_ref inode_ref;\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n    int r;\n\n    if (!mp)\n        return ENOENT;\n\n    if (mp->fs.read_only)\n        return EROFS;\n\n    EXT4_MP_LOCK(mp);\n\n    r = ext4_trans_get_inode_ref(path, mp, &inode_ref);\n    if (r != EOK)\n        goto Finish;\n\n    ext4_inode_set_modif_time(inode_ref.inode, mtime);\n    inode_ref.dirty = true;\n    r = ext4_trans_put_inode_ref(mp, &inode_ref);\n\n    Finish:\n    EXT4_MP_UNLOCK(mp);\n\n    return r;\n}\n\nint ext4_ctime_set(const char *path, uint32_t ctime)\n{\n    struct ext4_inode_ref inode_ref;\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n    int r;\n\n    if (!mp)\n        return ENOENT;\n\n    if (mp->fs.read_only)\n        return EROFS;\n\n    EXT4_MP_LOCK(mp);\n\n    r = ext4_trans_get_inode_ref(path, mp, &inode_ref);\n    if (r != EOK)\n        goto Finish;\n\n    ext4_inode_set_change_inode_time(inode_ref.inode, ctime);\n    inode_ref.dirty = true;\n    r = ext4_trans_put_inode_ref(mp, &inode_ref);\n\n    Finish:\n    EXT4_MP_UNLOCK(mp);\n\n    return r;\n}\n\nint ext4_atime_get(const char *path, uint32_t *atime)\n{\n    struct ext4_inode_ref inode_ref;\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n    ext4_file f;\n    int r;\n\n    if (!mp)\n        return ENOENT;\n\n    EXT4_MP_LOCK(mp);\n\n    r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN, NULL, NULL);\n    if (r != EOK)\n        goto Finish;\n\n    r = ext4_fs_get_inode_ref(&mp->fs, f.inode, &inode_ref);\n    if (r != EOK)\n        goto Finish;\n\n    *atime = ext4_inode_get_access_time(inode_ref.inode);\n    r = ext4_fs_put_inode_ref(&inode_ref);\n\n    Finish:\n    EXT4_MP_UNLOCK(mp);\n\n    return r;\n}\n\nint ext4_mtime_get(const char *path, uint32_t *mtime)\n{\n    struct ext4_inode_ref inode_ref;\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n    ext4_file f;\n    int r;\n\n    if (!mp)\n        return ENOENT;\n\n    EXT4_MP_LOCK(mp);\n\n    r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN, NULL, NULL);\n    if (r != EOK)\n        goto Finish;\n\n    r = ext4_fs_get_inode_ref(&mp->fs, f.inode, &inode_ref);\n    if (r != EOK)\n        goto Finish;\n\n    *mtime = ext4_inode_get_modif_time(inode_ref.inode);\n    r = ext4_fs_put_inode_ref(&inode_ref);\n\n    Finish:\n    EXT4_MP_UNLOCK(mp);\n\n    return r;\n}\n\nint ext4_ctime_get(const char *path, uint32_t *ctime)\n{\n    struct ext4_inode_ref inode_ref;\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n    ext4_file f;\n    int r;\n\n    if (!mp)\n        return ENOENT;\n\n    EXT4_MP_LOCK(mp);\n\n    r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN, NULL, NULL);\n    if (r != EOK)\n        goto Finish;\n\n    r = ext4_fs_get_inode_ref(&mp->fs, f.inode, &inode_ref);\n    if (r != EOK)\n        goto Finish;\n\n    *ctime = ext4_inode_get_change_inode_time(inode_ref.inode);\n    r = ext4_fs_put_inode_ref(&inode_ref);\n\n    Finish:\n    EXT4_MP_UNLOCK(mp);\n\n    return r;\n}\n\nstatic int ext4_fsymlink_set(ext4_file *f, const void *buf, uint32_t size)\n{\n    struct ext4_inode_ref ref;\n    uint32_t sblock;\n    ext4_fsblk_t fblock;\n    uint32_t block_size;\n    int r;\n\n    ext4_assert(f && f->mp);\n\n    if (!size)\n        return EOK;\n\n    r = ext4_fs_get_inode_ref(&f->mp->fs, f->inode, &ref);\n    if (r != EOK)\n        return r;\n\n    /*Sync file size*/\n    block_size = ext4_sb_get_block_size(&f->mp->fs.sb);\n    if (size > block_size) {\n        r = EINVAL;\n        goto Finish;\n    }\n    r = ext4_ftruncate_no_lock(f, 0);\n    if (r != EOK)\n        goto Finish;\n\n    /*Start write back cache mode.*/\n    r = ext4_block_cache_write_back(f->mp->fs.bdev, 1);\n    if (r != EOK)\n        goto Finish;\n\n    /*If the size of symlink is smaller than 60 bytes*/\n    if (size < sizeof(ref.inode->blocks)) {\n        memset(ref.inode->blocks, 0, sizeof(ref.inode->blocks));\n        memcpy(ref.inode->blocks, buf, size);\n        ext4_inode_clear_flag(ref.inode, EXT4_INODE_FLAG_EXTENTS);\n    } else {\n        uint64_t off;\n        ext4_fs_inode_blocks_init(&f->mp->fs, &ref);\n        r = ext4_fs_append_inode_dblk(&ref, &fblock, &sblock);\n        if (r != EOK)\n            goto Finish;\n\n        off = fblock * block_size;\n        r = ext4_block_writebytes(f->mp->fs.bdev, off, buf, size);\n        if (r != EOK)\n            goto Finish;\n    }\n\n    /*Stop write back cache mode*/\n    ext4_block_cache_write_back(f->mp->fs.bdev, 0);\n\n    if (r != EOK)\n        goto Finish;\n\n    ext4_inode_set_size(ref.inode, size);\n    ref.dirty = true;\n\n    f->fsize = size;\n    if (f->fpos > size)\n        f->fpos = size;\n\nFinish:\n    ext4_fs_put_inode_ref(&ref);\n    return r;\n}\n\nint ext4_fsymlink(const char *target, const char *path)\n{\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n    int r;\n    ext4_file f;\n    int filetype;\n\n    if (!mp)\n        return ENOENT;\n\n    if (mp->fs.read_only)\n        return EROFS;\n\n    filetype = EXT4_DE_SYMLINK;\n\n    EXT4_MP_LOCK(mp);\n    ext4_block_cache_write_back(mp->fs.bdev, 1);\n    ext4_trans_start(mp);\n\n    r = ext4_generic_open2(&f, path, O_RDWR | O_CREAT, filetype, NULL, NULL);\n    if (r == EOK)\n        r = ext4_fsymlink_set(&f, target, strlen(target));\n    else\n        goto Finish;\n\n    ext4_fclose(&f);\n\nFinish:\n    if (r != EOK)\n        ext4_trans_abort(mp);\n    else\n        ext4_trans_stop(mp);\n\n    ext4_block_cache_write_back(mp->fs.bdev, 0);\n    EXT4_MP_UNLOCK(mp);\n    return r;\n}\n\nint ext4_readlink(const char *path, char *buf, size_t bufsize, size_t *rcnt)\n{\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n    int r;\n    ext4_file f;\n    int filetype;\n\n    if (!mp)\n        return ENOENT;\n\n    if (!buf)\n        return EINVAL;\n\n    filetype = EXT4_DE_SYMLINK;\n\n    EXT4_MP_LOCK(mp);\n    ext4_block_cache_write_back(mp->fs.bdev, 1);\n    r = ext4_generic_open2(&f, path, O_RDONLY, filetype, NULL, NULL);\n    if (r == EOK)\n        r = ext4_fread(&f, buf, bufsize, rcnt);\n    else\n        goto Finish;\n\n    ext4_fclose(&f);\n\nFinish:\n    ext4_block_cache_write_back(mp->fs.bdev, 0);\n    EXT4_MP_UNLOCK(mp);\n    return r;\n}\n\nstatic int ext4_mknod_set(ext4_file *f, uint32_t dev)\n{\n    struct ext4_inode_ref ref;\n    int r;\n\n    ext4_assert(f && f->mp);\n\n    r = ext4_fs_get_inode_ref(&f->mp->fs, f->inode, &ref);\n    if (r != EOK)\n        return r;\n\n    ext4_inode_set_dev(ref.inode, dev);\n\n    ext4_inode_set_size(ref.inode, 0);\n    ref.dirty = true;\n\n    f->fsize = 0;\n    f->fpos = 0;\n\n    r = ext4_fs_put_inode_ref(&ref);\n    return r;\n}\n\nint ext4_mknod(const char *path, int filetype, uint32_t dev)\n{\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n    int r;\n    ext4_file f;\n\n    if (!mp)\n        return ENOENT;\n\n    if (mp->fs.read_only)\n        return EROFS;\n\n    /*\n     * The filetype shouldn't be normal file, directory or\n     * unknown.\n     */\n    if (filetype == EXT4_DE_UNKNOWN ||\n        filetype == EXT4_DE_REG_FILE ||\n        filetype == EXT4_DE_DIR ||\n        filetype == EXT4_DE_SYMLINK)\n        return EINVAL;\n\n    /*\n     * Nor should it be any bogus value.\n     */\n    if (filetype != EXT4_DE_CHRDEV &&\n        filetype != EXT4_DE_BLKDEV &&\n        filetype != EXT4_DE_FIFO &&\n        filetype != EXT4_DE_SOCK)\n        return EINVAL;\n\n    EXT4_MP_LOCK(mp);\n    ext4_block_cache_write_back(mp->fs.bdev, 1);\n    ext4_trans_start(mp);\n\n    r = ext4_generic_open2(&f, path, O_RDWR | O_CREAT, filetype, NULL, NULL);\n    if (r == EOK) {\n        if (filetype == EXT4_DE_CHRDEV ||\n            filetype == EXT4_DE_BLKDEV)\n            r = ext4_mknod_set(&f, dev);\n    } else {\n        goto Finish;\n    }\n\n    ext4_fclose(&f);\n\nFinish:\n    if (r != EOK)\n        ext4_trans_abort(mp);\n    else\n        ext4_trans_stop(mp);\n\n    ext4_block_cache_write_back(mp->fs.bdev, 0);\n    EXT4_MP_UNLOCK(mp);\n    return r;\n}\n\nint ext4_setxattr(const char *path, const char *name, size_t name_len,\n          const void *data, size_t data_size)\n{\n    bool found;\n    int r = EOK;\n    ext4_file f;\n    uint32_t inode;\n    uint8_t name_index;\n    const char *dissected_name = NULL;\n    size_t dissected_len = 0;\n    struct ext4_inode_ref inode_ref;\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n    if (!mp)\n        return ENOENT;\n\n    if (mp->fs.read_only)\n        return EROFS;\n\n    dissected_name = ext4_extract_xattr_name(name, name_len,\n                &name_index, &dissected_len,\n                &found);\n    if (!found)\n        return EINVAL;\n\n    EXT4_MP_LOCK(mp);\n    r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN, NULL, NULL);\n    if (r != EOK) {\n        EXT4_MP_UNLOCK(mp);\n        return r;\n    }\n\n    inode = f.inode;\n    ext4_fclose(&f);\n    ext4_trans_start(mp);\n\n    r = ext4_fs_get_inode_ref(&mp->fs, inode, &inode_ref);\n    if (r != EOK)\n        goto Finish;\n\n    r = ext4_xattr_set(&inode_ref, name_index, dissected_name,\n            dissected_len, data, data_size);\n\n    ext4_fs_put_inode_ref(&inode_ref);\nFinish:\n    if (r != EOK)\n        ext4_trans_abort(mp);\n    else\n        ext4_trans_stop(mp);\n\n    EXT4_MP_UNLOCK(mp);\n    return r;\n}\n\nint ext4_getxattr(const char *path, const char *name, size_t name_len,\n          void *buf, size_t buf_size, size_t *data_size)\n{\n    bool found;\n    int r = EOK;\n    ext4_file f;\n    uint32_t inode;\n    uint8_t name_index;\n    const char *dissected_name = NULL;\n    size_t dissected_len = 0;\n    struct ext4_inode_ref inode_ref;\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n    if (!mp)\n        return ENOENT;\n\n    dissected_name = ext4_extract_xattr_name(name, name_len,\n                &name_index, &dissected_len,\n                &found);\n    if (!found)\n        return EINVAL;\n\n    EXT4_MP_LOCK(mp);\n    r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN, NULL, NULL);\n    if (r != EOK)\n        goto Finish;\n\n    inode = f.inode;\n    ext4_fclose(&f);\n\n    r = ext4_fs_get_inode_ref(&mp->fs, inode, &inode_ref);\n    if (r != EOK)\n        goto Finish;\n\n    r = ext4_xattr_get(&inode_ref, name_index, dissected_name,\n                dissected_len, buf, buf_size, data_size);\n\n    ext4_fs_put_inode_ref(&inode_ref);\nFinish:\n    EXT4_MP_UNLOCK(mp);\n    return r;\n}\n\nint ext4_listxattr(const char *path, char *list, size_t size, size_t *ret_size)\n{\n    int r = EOK;\n    ext4_file f;\n    uint32_t inode;\n    size_t list_len, list_size = 0;\n    struct ext4_inode_ref inode_ref;\n    struct ext4_xattr_list_entry *xattr_list = NULL,\n                     *entry = NULL;\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n    if (!mp)\n        return ENOENT;\n\n    EXT4_MP_LOCK(mp);\n    r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN, NULL, NULL);\n    if (r != EOK)\n        goto Finish;\n    inode = f.inode;\n    ext4_fclose(&f);\n\n    r = ext4_fs_get_inode_ref(&mp->fs, inode, &inode_ref);\n    if (r != EOK)\n        goto Finish;\n\n    r = ext4_xattr_list(&inode_ref, NULL, &list_len);\n    if (r == EOK && list_len) {\n        xattr_list = ext4_malloc(list_len);\n        if (!xattr_list) {\n            ext4_fs_put_inode_ref(&inode_ref);\n            r = ENOMEM;\n            goto Finish;\n        }\n        entry = xattr_list;\n        r = ext4_xattr_list(&inode_ref, entry, &list_len);\n        if (r != EOK) {\n            ext4_fs_put_inode_ref(&inode_ref);\n            goto Finish;\n        }\n\n        for (;entry;entry = entry->next) {\n            size_t prefix_len;\n            const char *prefix =\n                ext4_get_xattr_name_prefix(entry->name_index,\n                               &prefix_len);\n            if (size) {\n                if (prefix_len + entry->name_len + 1 > size) {\n                    ext4_fs_put_inode_ref(&inode_ref);\n                    r = ERANGE;\n                    goto Finish;\n                }\n            }\n\n            if (list && size) {\n                memcpy(list, prefix, prefix_len);\n                list += prefix_len;\n                memcpy(list, entry->name,\n                    entry->name_len);\n                list[entry->name_len] = 0;\n                list += entry->name_len + 1;\n\n                size -= prefix_len + entry->name_len + 1;\n            }\n\n            list_size += prefix_len + entry->name_len + 1;\n        }\n        if (ret_size)\n            *ret_size = list_size;\n\n    }\n    ext4_fs_put_inode_ref(&inode_ref);\nFinish:\n    EXT4_MP_UNLOCK(mp);\n    if (xattr_list)\n        ext4_free(xattr_list);\n\n    return r;\n\n}\n\nint ext4_removexattr(const char *path, const char *name, size_t name_len)\n{\n    bool found;\n    int r = EOK;\n    ext4_file f;\n    uint32_t inode;\n    uint8_t name_index;\n    const char *dissected_name = NULL;\n    size_t dissected_len = 0;\n    struct ext4_inode_ref inode_ref;\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n    if (!mp)\n        return ENOENT;\n\n    if (mp->fs.read_only)\n        return EROFS;\n\n    dissected_name = ext4_extract_xattr_name(name, name_len,\n                        &name_index, &dissected_len,\n                        &found);\n    if (!found)\n        return EINVAL;\n\n    EXT4_MP_LOCK(mp);\n    r = ext4_generic_open2(&f, path, O_RDONLY, EXT4_DE_UNKNOWN, NULL, NULL);\n    if (r != EOK) {\n        EXT4_MP_LOCK(mp);\n        return r;\n    }\n\n    inode = f.inode;\n    ext4_fclose(&f);\n    ext4_trans_start(mp);\n\n    r = ext4_fs_get_inode_ref(&mp->fs, inode, &inode_ref);\n    if (r != EOK)\n        goto Finish;\n\n    r = ext4_xattr_remove(&inode_ref, name_index, dissected_name,\n                  dissected_len);\n\n    ext4_fs_put_inode_ref(&inode_ref);\nFinish:\n    if (r != EOK)\n        ext4_trans_abort(mp);\n    else\n        ext4_trans_stop(mp);\n\n    EXT4_MP_UNLOCK(mp);\n    return r;\n\n}\n\n/*********************************DIRECTORY OPERATION************************/\n\nint ext4_dir_rm(const char *path)\n{\n    int r;\n    int len;\n    ext4_file f;\n\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n    struct ext4_inode_ref act;\n    struct ext4_inode_ref child;\n    struct ext4_dir_iter it;\n\n    uint32_t name_off;\n    uint32_t inode_up;\n    uint32_t inode_current;\n    uint32_t depth = 1;\n\n    bool has_children;\n    bool is_goal;\n    bool dir_end;\n\n    if (!mp)\n        return ENOENT;\n\n    if (mp->fs.read_only)\n        return EROFS;\n\n    EXT4_MP_LOCK(mp);\n\n    struct ext4_fs *const fs = &mp->fs;\n\n    /*Check if exist.*/\n    r = ext4_generic_open(&f, path, \"r\", false, &inode_up, &name_off);\n    if (r != EOK) {\n        EXT4_MP_UNLOCK(mp);\n        return r;\n    }\n\n    path += name_off;\n    len = ext4_path_check(path, &is_goal);\n    inode_current = f.inode;\n\n    ext4_block_cache_write_back(mp->fs.bdev, 1);\n\n    do {\n\n        uint64_t act_curr_pos = 0;\n        has_children = false;\n        dir_end = false;\n\n        while (r == EOK && !has_children && !dir_end) {\n\n            /*Load directory node.*/\n            r = ext4_fs_get_inode_ref(fs, inode_current, &act);\n            if (r != EOK) {\n                break;\n            }\n\n            /*Initialize iterator.*/\n            r = ext4_dir_iterator_init(&it, &act, act_curr_pos);\n            if (r != EOK) {\n                ext4_fs_put_inode_ref(&act);\n                break;\n            }\n\n            if (!it.curr) {\n                dir_end = true;\n                goto End;\n            }\n\n            ext4_trans_start(mp);\n\n            /*Get up directory inode when \"..\" entry*/\n            if ((it.curr->name_len == 2) &&\n                ext4_is_dots(it.curr->name, it.curr->name_len)) {\n                inode_up = ext4_dir_en_get_inode(it.curr);\n            }\n\n            /*If directory or file entry,  but not \".\" \"..\" entry*/\n            if (!ext4_is_dots(it.curr->name, it.curr->name_len)) {\n\n                /*Get child inode reference do unlink\n                 * directory/file.*/\n                uint32_t cinode;\n                uint32_t inode_type;\n                cinode = ext4_dir_en_get_inode(it.curr);\n                r = ext4_fs_get_inode_ref(fs, cinode, &child);\n                if (r != EOK)\n                    goto End;\n\n                /*If directory with no leaf children*/\n                r = ext4_has_children(&has_children, &child);\n                if (r != EOK) {\n                    ext4_fs_put_inode_ref(&child);\n                    goto End;\n                }\n\n                if (has_children) {\n                    /*Has directory children. Go into this\n                     * directory.*/\n                    inode_up = inode_current;\n                    inode_current = cinode;\n                    depth++;\n                    ext4_fs_put_inode_ref(&child);\n                    goto End;\n                }\n                inode_type = ext4_inode_type(&mp->fs.sb,\n                        child.inode);\n\n                /* Truncate */\n                if (inode_type != EXT4_INODE_MODE_DIRECTORY)\n                    r = ext4_trunc_inode(mp, child.index, 0);\n                else\n                    r = ext4_trunc_dir(mp, &act, &child);\n\n                if (r != EOK) {\n                    ext4_fs_put_inode_ref(&child);\n                    goto End;\n                }\n\n                /*No children in child directory or file. Just\n                 * unlink.*/\n                r = ext4_unlink(f.mp, &act, &child,\n                        (char *)it.curr->name,\n                        it.curr->name_len);\n                if (r != EOK) {\n                    ext4_fs_put_inode_ref(&child);\n                    goto End;\n                }\n\n                ext4_inode_set_del_time(child.inode, -1L);\n                ext4_inode_set_links_cnt(child.inode, 0);\n                child.dirty = true;\n\n                r = ext4_fs_free_inode(&child);\n                if (r != EOK) {\n                    ext4_fs_put_inode_ref(&child);\n                    goto End;\n                }\n\n                r = ext4_fs_put_inode_ref(&child);\n                if (r != EOK)\n                    goto End;\n\n            }\n\n            r = ext4_dir_iterator_next(&it);\n            if (r != EOK)\n                goto End;\n\n            act_curr_pos = it.curr_off;\nEnd:\n            ext4_dir_iterator_fini(&it);\n            if (r == EOK)\n                r = ext4_fs_put_inode_ref(&act);\n            else\n                ext4_fs_put_inode_ref(&act);\n\n            if (r != EOK)\n                ext4_trans_abort(mp);\n            else\n                ext4_trans_stop(mp);\n        }\n\n        if (dir_end) {\n            /*Directory iterator reached last entry*/\n            depth--;\n            if (depth)\n                inode_current = inode_up;\n\n        }\n\n        if (r != EOK)\n            break;\n\n    } while (depth);\n\n    /*Last unlink*/\n    if (r == EOK && !depth) {\n        /*Load parent.*/\n        struct ext4_inode_ref parent;\n        r = ext4_fs_get_inode_ref(&f.mp->fs, inode_up,\n                &parent);\n        if (r != EOK)\n            goto Finish;\n        r = ext4_fs_get_inode_ref(&f.mp->fs, inode_current,\n                &act);\n        if (r != EOK) {\n            ext4_fs_put_inode_ref(&act);\n            goto Finish;\n        }\n\n        ext4_trans_start(mp);\n\n        /* In this place all directories should be\n         * unlinked.\n         * Last unlink from root of current directory*/\n        r = ext4_unlink(f.mp, &parent, &act,\n                (char *)path, len);\n        if (r != EOK) {\n            ext4_fs_put_inode_ref(&parent);\n            ext4_fs_put_inode_ref(&act);\n            goto Finish;\n        }\n\n        if (ext4_inode_get_links_cnt(act.inode) == 2) {\n            ext4_inode_set_del_time(act.inode, -1L);\n            ext4_inode_set_links_cnt(act.inode, 0);\n            act.dirty = true;\n            /*Truncate*/\n            r = ext4_trunc_dir(mp, &parent, &act);\n            if (r != EOK) {\n                ext4_fs_put_inode_ref(&parent);\n                ext4_fs_put_inode_ref(&act);\n                goto Finish;\n            }\n\n            r = ext4_fs_free_inode(&act);\n            if (r != EOK) {\n                ext4_fs_put_inode_ref(&parent);\n                ext4_fs_put_inode_ref(&act);\n                goto Finish;\n            }\n        }\n\n        r = ext4_fs_put_inode_ref(&parent);\n        if (r != EOK)\n            goto Finish;\n\n        r = ext4_fs_put_inode_ref(&act);\n    Finish:\n        if (r != EOK)\n            ext4_trans_abort(mp);\n        else\n            ext4_trans_stop(mp);\n    }\n\n    ext4_block_cache_write_back(mp->fs.bdev, 0);\n    EXT4_MP_UNLOCK(mp);\n\n    return r;\n}\n\nint ext4_dir_mv(const char *path, const char *new_path)\n{\n    return ext4_frename(path, new_path);\n}\n\nint ext4_dir_mk(const char *path)\n{\n    int r;\n    ext4_file f;\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n\n    if (!mp)\n        return ENOENT;\n\n    if (mp->fs.read_only)\n        return EROFS;\n\n    EXT4_MP_LOCK(mp);\n\n    /*Check if exist.*/\n    r = ext4_generic_open(&f, path, \"r\", false, 0, 0);\n    if (r == EOK)\n        goto Finish;\n\n    /*Create new directory.*/\n    r = ext4_generic_open(&f, path, \"w\", false, 0, 0);\n\nFinish:\n    EXT4_MP_UNLOCK(mp);\n    return r;\n}\n\nint ext4_dir_open(ext4_dir *dir, const char *path)\n{\n    struct ext4_mountpoint *mp = ext4_get_mount(path);\n    int r;\n\n    if (!mp)\n        return ENOENT;\n\n    EXT4_MP_LOCK(mp);\n    r = ext4_generic_open(&dir->f, path, \"r\", false, 0, 0);\n    dir->next_off = 0;\n    EXT4_MP_UNLOCK(mp);\n    return r;\n}\n\nint ext4_dir_close(ext4_dir *dir)\n{\n    return ext4_fclose(&dir->f);\n}\n\nconst ext4_direntry *ext4_dir_entry_next(ext4_dir *dir)\n{\n#define EXT4_DIR_ENTRY_OFFSET_TERM (uint64_t)(-1)\n\n    int r;\n    uint16_t name_length;\n    ext4_direntry *de = 0;\n    struct ext4_inode_ref dir_inode;\n    struct ext4_dir_iter it;\n\n    EXT4_MP_LOCK(dir->f.mp);\n\n    if (dir->next_off == EXT4_DIR_ENTRY_OFFSET_TERM) {\n        EXT4_MP_UNLOCK(dir->f.mp);\n        return 0;\n    }\n\n    r = ext4_fs_get_inode_ref(&dir->f.mp->fs, dir->f.inode, &dir_inode);\n    if (r != EOK) {\n        goto Finish;\n    }\n\n    r = ext4_dir_iterator_init(&it, &dir_inode, dir->next_off);\n    if (r != EOK) {\n        ext4_fs_put_inode_ref(&dir_inode);\n        goto Finish;\n    }\n\n    memset(&dir->de.name, 0, sizeof(dir->de.name));\n    name_length = ext4_dir_en_get_name_len(&dir->f.mp->fs.sb,\n                           it.curr);\n    memcpy(&dir->de.name, it.curr->name, name_length);\n\n    /* Directly copying the content isn't safe for Big-endian targets*/\n    dir->de.inode = ext4_dir_en_get_inode(it.curr);\n    dir->de.entry_length = ext4_dir_en_get_entry_len(it.curr);\n    dir->de.name_length = name_length;\n    dir->de.inode_type = ext4_dir_en_get_inode_type(&dir->f.mp->fs.sb,\n                              it.curr);\n\n    de = &dir->de;\n\n    ext4_dir_iterator_next(&it);\n\n    dir->next_off = it.curr ? it.curr_off : EXT4_DIR_ENTRY_OFFSET_TERM;\n\n    ext4_dir_iterator_fini(&it);\n    ext4_fs_put_inode_ref(&dir_inode);\n\nFinish:\n    EXT4_MP_UNLOCK(dir->f.mp);\n    return de;\n}\n\nvoid ext4_dir_entry_rewind(ext4_dir *dir)\n{\n    dir->next_off = 0;\n}\n\nint ext4_dir_seek(ext4_dir *dir, int64_t offset, uint32_t origin)\n{\n\t/*\n\t * TO BE DONE\n\t */\n    switch (origin) {\n    case SEEK_SET:\n\tdir->next_off = offset;\n        return EOK;\n    case SEEK_CUR:\n\tdir->next_off += offset;\n        return EOK;\n    case SEEK_END:\n\tdir->next_off = EXT4_DIR_ENTRY_OFFSET_TERM;\n        return EOK;\n    }\n    return EINVAL;\n}\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/src/ext4_balloc.c",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n *\n * HelenOS:\n * Copyright (c) 2012 Martin Sucha\n * Copyright (c) 2012 Frantisek Princ\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_balloc.c\n * @brief Physical block allocator.\n */\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_misc.h>\n#include <ext4_errno.h>\n#include <ext4_debug.h>\n\n#include <ext4_trans.h>\n#include <ext4_balloc.h>\n#include <ext4_super.h>\n#include <ext4_crc32.h>\n#include <ext4_block_group.h>\n#include <ext4_fs.h>\n#include <ext4_bitmap.h>\n#include <ext4_inode.h>\n\n/**@brief Compute number of block group from block address.\n * @param sb superblock pointer.\n * @param baddr Absolute address of block.\n * @return Block group index\n */\nuint32_t ext4_balloc_get_bgid_of_block(struct ext4_sblock *s,\n                       uint64_t baddr)\n{\n    if (ext4_get32(s, first_data_block) && baddr)\n        baddr--;\n\n    return (uint32_t)(baddr / ext4_get32(s, blocks_per_group));\n}\n\n/**@brief Compute the starting block address of a block group\n * @param sb   superblock pointer.\n * @param bgid block group index\n * @return Block address\n */\nuint64_t ext4_balloc_get_block_of_bgid(struct ext4_sblock *s,\n                       uint32_t bgid)\n{\n    uint64_t baddr = 0;\n    if (ext4_get32(s, first_data_block))\n        baddr++;\n\n    baddr += bgid * ext4_get32(s, blocks_per_group);\n    return baddr;\n}\n\n#if CONFIG_META_CSUM_ENABLE\nstatic uint32_t ext4_balloc_bitmap_csum(struct ext4_sblock *sb,\n                    void *bitmap)\n{\n    uint32_t checksum = 0;\n    if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) {\n        uint32_t blocks_per_group = ext4_get32(sb, blocks_per_group);\n\n        /* First calculate crc32 checksum against fs uuid */\n        checksum = ext4_crc32c(EXT4_CRC32_INIT, sb->uuid,\n                sizeof(sb->uuid));\n        /* Then calculate crc32 checksum against block_group_desc */\n        checksum = ext4_crc32c(checksum, bitmap, blocks_per_group / 8);\n    }\n    return checksum;\n}\n#else\n#define ext4_balloc_bitmap_csum(...) 0\n#endif\n\nvoid ext4_balloc_set_bitmap_csum(struct ext4_sblock *sb,\n                 struct ext4_bgroup *bg,\n                 void *bitmap __unused)\n{\n    int desc_size = ext4_sb_get_desc_size(sb);\n    uint32_t checksum = ext4_balloc_bitmap_csum(sb, bitmap);\n    uint16_t lo_checksum = to_le16(checksum & 0xFFFF),\n         hi_checksum = to_le16(checksum >> 16);\n\n    if (!ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM))\n        return;\n\n    /* See if we need to assign a 32bit checksum */\n    bg->block_bitmap_csum_lo = lo_checksum;\n    if (desc_size == EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE)\n        bg->block_bitmap_csum_hi = hi_checksum;\n\n}\n\n#if CONFIG_META_CSUM_ENABLE\nstatic bool\next4_balloc_verify_bitmap_csum(struct ext4_sblock *sb,\n                   struct ext4_bgroup *bg,\n                   void *bitmap __unused)\n{\n    int desc_size = ext4_sb_get_desc_size(sb);\n    uint32_t checksum = ext4_balloc_bitmap_csum(sb, bitmap);\n    uint16_t lo_checksum = to_le16(checksum & 0xFFFF),\n         hi_checksum = to_le16(checksum >> 16);\n\n    if (!ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM))\n        return true;\n\n    if (bg->block_bitmap_csum_lo != lo_checksum)\n        return false;\n\n    if (desc_size == EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE)\n        if (bg->block_bitmap_csum_hi != hi_checksum)\n            return false;\n\n    return true;\n}\n#else\n#define ext4_balloc_verify_bitmap_csum(...) true\n#endif\n\nint ext4_balloc_free_block(struct ext4_inode_ref *inode_ref, ext4_fsblk_t baddr)\n{\n    struct ext4_fs *fs = inode_ref->fs;\n    struct ext4_sblock *sb = &fs->sb;\n\n    uint32_t bg_id = ext4_balloc_get_bgid_of_block(sb, baddr);\n    uint32_t index_in_group = ext4_fs_addr_to_idx_bg(sb, baddr);\n\n    /* Load block group reference */\n    struct ext4_block_group_ref bg_ref;\n    int rc = ext4_fs_get_block_group_ref(fs, bg_id, &bg_ref);\n    if (rc != EOK)\n        return rc;\n\n    struct ext4_bgroup *bg = bg_ref.block_group;\n\n    /* Load block with bitmap */\n    ext4_fsblk_t bitmap_block_addr =\n        ext4_bg_get_block_bitmap(bg, sb);\n\n    struct ext4_block bitmap_block;\n\n    rc = ext4_trans_block_get(fs->bdev, &bitmap_block, bitmap_block_addr);\n    if (rc != EOK) {\n        ext4_fs_put_block_group_ref(&bg_ref);\n        return rc;\n    }\n\n    if (!ext4_balloc_verify_bitmap_csum(sb, bg, bitmap_block.data)) {\n        ext4_dbg(DEBUG_BALLOC,\n            DBG_WARN \"Bitmap checksum failed.\"\n            \"Group: %\" PRIu32\"\\n\",\n            bg_ref.index);\n    }\n\n    /* Modify bitmap */\n    ext4_bmap_bit_clr(bitmap_block.data, index_in_group);\n    ext4_balloc_set_bitmap_csum(sb, bg, bitmap_block.data);\n    ext4_trans_set_block_dirty(bitmap_block.buf);\n\n    /* Release block with bitmap */\n    rc = ext4_block_set(fs->bdev, &bitmap_block);\n    if (rc != EOK) {\n        /* Error in saving bitmap */\n        ext4_fs_put_block_group_ref(&bg_ref);\n        return rc;\n    }\n\n    uint32_t block_size = ext4_sb_get_block_size(sb);\n\n    /* Update superblock free blocks count */\n    uint64_t sb_free_blocks = ext4_sb_get_free_blocks_cnt(sb);\n    sb_free_blocks++;\n    ext4_sb_set_free_blocks_cnt(sb, sb_free_blocks);\n\n    /* Update inode blocks count */\n    uint64_t ino_blocks = ext4_inode_get_blocks_count(sb, inode_ref->inode);\n    ino_blocks -= block_size / EXT4_INODE_BLOCK_SIZE;\n    ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks);\n    inode_ref->dirty = true;\n\n    /* Update block group free blocks count */\n    uint32_t free_blocks = ext4_bg_get_free_blocks_count(bg, sb);\n    free_blocks++;\n    ext4_bg_set_free_blocks_count(bg, sb, free_blocks);\n\n    bg_ref.dirty = true;\n\n    rc = ext4_trans_try_revoke_block(fs->bdev, baddr);\n    if (rc != EOK) {\n        bg_ref.dirty = false;\n        ext4_fs_put_block_group_ref(&bg_ref);\n        return rc;\n    }\n    ext4_bcache_invalidate_lba(fs->bdev->bc, baddr, 1);\n    /* Release block group reference */\n    rc = ext4_fs_put_block_group_ref(&bg_ref);\n\n    return rc;\n}\n\nint ext4_balloc_free_blocks(struct ext4_inode_ref *inode_ref,\n                ext4_fsblk_t first, uint32_t count)\n{\n    int rc = EOK;\n    uint32_t blk_cnt = count;\n    ext4_fsblk_t start_block = first;\n    struct ext4_fs *fs = inode_ref->fs;\n    struct ext4_sblock *sb = &fs->sb;\n\n    /* Compute indexes */\n    uint32_t bg_first = ext4_balloc_get_bgid_of_block(sb, first);\n\n    /* Compute indexes */\n    uint32_t bg_last = ext4_balloc_get_bgid_of_block(sb, first + count - 1);\n\n    if (!ext4_sb_feature_incom(sb, EXT4_FINCOM_FLEX_BG)) {\n        /*It is not possible without flex_bg that blocks are continuous\n         * and and last block belongs to other bg.*/\n        if (bg_last != bg_first) {\n            ext4_dbg(DEBUG_BALLOC, DBG_WARN \"FLEX_BG: disabled & \"\n                \"bg_last: %\"PRIu32\" bg_first: %\"PRIu32\"\\n\",\n                bg_last, bg_first);\n        }\n    }\n\n    /* Load block group reference */\n    struct ext4_block_group_ref bg_ref;\n    while (bg_first <= bg_last) {\n\n        rc = ext4_fs_get_block_group_ref(fs, bg_first, &bg_ref);\n        if (rc != EOK)\n            return rc;\n\n        struct ext4_bgroup *bg = bg_ref.block_group;\n\n        uint32_t idx_in_bg_first;\n        idx_in_bg_first = ext4_fs_addr_to_idx_bg(sb, first);\n\n        /* Load block with bitmap */\n        ext4_fsblk_t bitmap_blk = ext4_bg_get_block_bitmap(bg, sb);\n\n        struct ext4_block blk;\n        rc = ext4_trans_block_get(fs->bdev, &blk, bitmap_blk);\n        if (rc != EOK) {\n            ext4_fs_put_block_group_ref(&bg_ref);\n            return rc;\n        }\n\n        if (!ext4_balloc_verify_bitmap_csum(sb, bg, blk.data)) {\n            ext4_dbg(DEBUG_BALLOC,\n                DBG_WARN \"Bitmap checksum failed.\"\n                \"Group: %\" PRIu32\"\\n\",\n                bg_ref.index);\n        }\n        uint32_t free_cnt;\n        free_cnt = ext4_sb_get_block_size(sb) * 8 - idx_in_bg_first;\n\n        /*If last block, free only count blocks*/\n        free_cnt = count > free_cnt ? free_cnt : count;\n\n        /* Modify bitmap */\n        ext4_bmap_bits_free(blk.data, idx_in_bg_first, free_cnt);\n        ext4_balloc_set_bitmap_csum(sb, bg, blk.data);\n        ext4_trans_set_block_dirty(blk.buf);\n\n        count -= free_cnt;\n        first += free_cnt;\n\n        /* Release block with bitmap */\n        rc = ext4_block_set(fs->bdev, &blk);\n        if (rc != EOK) {\n            ext4_fs_put_block_group_ref(&bg_ref);\n            return rc;\n        }\n\n        uint32_t block_size = ext4_sb_get_block_size(sb);\n\n        /* Update superblock free blocks count */\n        uint64_t sb_free_blocks = ext4_sb_get_free_blocks_cnt(sb);\n        sb_free_blocks += free_cnt;\n        ext4_sb_set_free_blocks_cnt(sb, sb_free_blocks);\n\n        /* Update inode blocks count */\n        uint64_t ino_blocks;\n        ino_blocks = ext4_inode_get_blocks_count(sb, inode_ref->inode);\n        ino_blocks -= free_cnt * (block_size / EXT4_INODE_BLOCK_SIZE);\n        ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks);\n        inode_ref->dirty = true;\n\n        /* Update block group free blocks count */\n        uint32_t free_blocks;\n        free_blocks = ext4_bg_get_free_blocks_count(bg, sb);\n        free_blocks += free_cnt;\n        ext4_bg_set_free_blocks_count(bg, sb, free_blocks);\n        bg_ref.dirty = true;\n\n        /* Release block group reference */\n        rc = ext4_fs_put_block_group_ref(&bg_ref);\n        if (rc != EOK)\n            break;\n\n        bg_first++;\n    }\n\n    uint32_t i;\n    for (i = 0;i < blk_cnt;i++) {\n        rc = ext4_trans_try_revoke_block(fs->bdev, start_block + i);\n        if (rc != EOK)\n            return rc;\n\n    }\n\n    ext4_bcache_invalidate_lba(fs->bdev->bc, start_block, blk_cnt);\n    /*All blocks should be released*/\n    ext4_assert(count == 0);\n\n    return rc;\n}\n\nint ext4_balloc_alloc_block(struct ext4_inode_ref *inode_ref,\n                ext4_fsblk_t goal,\n                ext4_fsblk_t *fblock)\n{\n    ext4_fsblk_t alloc = 0;\n    ext4_fsblk_t bmp_blk_adr;\n    uint32_t rel_blk_idx = 0;\n    uint64_t free_blocks;\n    int r;\n    struct ext4_sblock *sb = &inode_ref->fs->sb;\n\n    /* Load block group number for goal and relative index */\n    uint32_t bg_id = ext4_balloc_get_bgid_of_block(sb, goal);\n    uint32_t idx_in_bg = ext4_fs_addr_to_idx_bg(sb, goal);\n\n    struct ext4_block b;\n    struct ext4_block_group_ref bg_ref;\n\n    /* Load block group reference */\n    r = ext4_fs_get_block_group_ref(inode_ref->fs, bg_id, &bg_ref);\n    if (r != EOK)\n        return r;\n\n    struct ext4_bgroup *bg = bg_ref.block_group;\n\n    free_blocks = ext4_bg_get_free_blocks_count(bg_ref.block_group, sb);\n    if (free_blocks == 0) {\n        /* This group has no free blocks */\n        goto goal_failed;\n    }\n\n    /* Compute indexes */\n    ext4_fsblk_t first_in_bg;\n    first_in_bg = ext4_balloc_get_block_of_bgid(sb, bg_ref.index);\n\n    uint32_t first_in_bg_index;\n    first_in_bg_index = ext4_fs_addr_to_idx_bg(sb, first_in_bg);\n\n    if (idx_in_bg < first_in_bg_index)\n        idx_in_bg = first_in_bg_index;\n\n    /* Load block with bitmap */\n    bmp_blk_adr = ext4_bg_get_block_bitmap(bg_ref.block_group, sb);\n\n    r = ext4_trans_block_get(inode_ref->fs->bdev, &b, bmp_blk_adr);\n    if (r != EOK) {\n        ext4_fs_put_block_group_ref(&bg_ref);\n        return r;\n    }\n\n    if (!ext4_balloc_verify_bitmap_csum(sb, bg, b.data)) {\n        ext4_dbg(DEBUG_BALLOC,\n            DBG_WARN \"Bitmap checksum failed.\"\n            \"Group: %\" PRIu32\"\\n\",\n            bg_ref.index);\n    }\n\n    /* Check if goal is free */\n    if (ext4_bmap_is_bit_clr(b.data, idx_in_bg)) {\n        ext4_bmap_bit_set(b.data, idx_in_bg);\n        ext4_balloc_set_bitmap_csum(sb, bg_ref.block_group,\n                        b.data);\n        ext4_trans_set_block_dirty(b.buf);\n        r = ext4_block_set(inode_ref->fs->bdev, &b);\n        if (r != EOK) {\n            ext4_fs_put_block_group_ref(&bg_ref);\n            return r;\n        }\n\n        alloc = ext4_fs_bg_idx_to_addr(sb, idx_in_bg, bg_id);\n        goto success;\n    }\n\n    uint32_t blk_in_bg = ext4_blocks_in_group_cnt(sb, bg_id);\n\n    uint32_t end_idx = (idx_in_bg + 63) & ~63;\n    if (end_idx > blk_in_bg)\n        end_idx = blk_in_bg;\n\n    /* Try to find free block near to goal */\n    uint32_t tmp_idx;\n    for (tmp_idx = idx_in_bg + 1; tmp_idx < end_idx; ++tmp_idx) {\n        if (ext4_bmap_is_bit_clr(b.data, tmp_idx)) {\n            ext4_bmap_bit_set(b.data, tmp_idx);\n\n            ext4_balloc_set_bitmap_csum(sb, bg, b.data);\n            ext4_trans_set_block_dirty(b.buf);\n            r = ext4_block_set(inode_ref->fs->bdev, &b);\n            if (r != EOK)\n                return r;\n\n            alloc = ext4_fs_bg_idx_to_addr(sb, tmp_idx, bg_id);\n            goto success;\n        }\n    }\n\n    /* Find free bit in bitmap */\n    r = ext4_bmap_bit_find_clr(b.data, idx_in_bg, blk_in_bg, &rel_blk_idx);\n    if (r == EOK) {\n        ext4_bmap_bit_set(b.data, rel_blk_idx);\n        ext4_balloc_set_bitmap_csum(sb, bg_ref.block_group, b.data);\n        ext4_trans_set_block_dirty(b.buf);\n        r = ext4_block_set(inode_ref->fs->bdev, &b);\n        if (r != EOK)\n            return r;\n\n        alloc = ext4_fs_bg_idx_to_addr(sb, rel_blk_idx, bg_id);\n        goto success;\n    }\n\n    /* No free block found yet */\n    r = ext4_block_set(inode_ref->fs->bdev, &b);\n    if (r != EOK) {\n        ext4_fs_put_block_group_ref(&bg_ref);\n        return r;\n    }\n\ngoal_failed:\n\n    r = ext4_fs_put_block_group_ref(&bg_ref);\n    if (r != EOK)\n        return r;\n\n    /* Try other block groups */\n    uint32_t block_group_count = ext4_block_group_cnt(sb);\n    uint32_t bgid = (bg_id + 1) % block_group_count;\n    uint32_t count = block_group_count;\n\n    while (count > 0) {\n        r = ext4_fs_get_block_group_ref(inode_ref->fs, bgid, &bg_ref);\n        if (r != EOK)\n            return r;\n\n        struct ext4_bgroup *bg = bg_ref.block_group;\n        free_blocks = ext4_bg_get_free_blocks_count(bg, sb);\n        if (free_blocks == 0) {\n            /* This group has no free blocks */\n            goto next_group;\n        }\n\n        /* Load block with bitmap */\n        bmp_blk_adr = ext4_bg_get_block_bitmap(bg, sb);\n        r = ext4_trans_block_get(inode_ref->fs->bdev, &b, bmp_blk_adr);\n        if (r != EOK) {\n            ext4_fs_put_block_group_ref(&bg_ref);\n            return r;\n        }\n\n        if (!ext4_balloc_verify_bitmap_csum(sb, bg, b.data)) {\n            ext4_dbg(DEBUG_BALLOC,\n                DBG_WARN \"Bitmap checksum failed.\"\n                \"Group: %\" PRIu32\"\\n\",\n                bg_ref.index);\n        }\n\n        /* Compute indexes */\n        first_in_bg = ext4_balloc_get_block_of_bgid(sb, bgid);\n        idx_in_bg = ext4_fs_addr_to_idx_bg(sb, first_in_bg);\n        blk_in_bg = ext4_blocks_in_group_cnt(sb, bgid);\n        first_in_bg_index = ext4_fs_addr_to_idx_bg(sb, first_in_bg);\n\n        if (idx_in_bg < first_in_bg_index)\n            idx_in_bg = first_in_bg_index;\n\n        r = ext4_bmap_bit_find_clr(b.data, idx_in_bg, blk_in_bg,\n                &rel_blk_idx);\n        if (r == EOK) {\n            ext4_bmap_bit_set(b.data, rel_blk_idx);\n            ext4_balloc_set_bitmap_csum(sb, bg, b.data);\n            ext4_trans_set_block_dirty(b.buf);\n            r = ext4_block_set(inode_ref->fs->bdev, &b);\n            if (r != EOK) {\n                ext4_fs_put_block_group_ref(&bg_ref);\n                return r;\n            }\n\n            alloc = ext4_fs_bg_idx_to_addr(sb, rel_blk_idx, bgid);\n            goto success;\n        }\n\n        r = ext4_block_set(inode_ref->fs->bdev, &b);\n        if (r != EOK) {\n            ext4_fs_put_block_group_ref(&bg_ref);\n            return r;\n        }\n\n    next_group:\n        r = ext4_fs_put_block_group_ref(&bg_ref);\n        if (r != EOK) {\n            return r;\n        }\n\n        /* Goto next group */\n        bgid = (bgid + 1) % block_group_count;\n        count--;\n    }\n\n    return ENOSPC;\n\nsuccess:\n    /* Empty command - because of syntax */\n    ;\n\n    uint32_t block_size = ext4_sb_get_block_size(sb);\n\n    /* Update superblock free blocks count */\n    uint64_t sb_free_blocks = ext4_sb_get_free_blocks_cnt(sb);\n    sb_free_blocks--;\n    ext4_sb_set_free_blocks_cnt(sb, sb_free_blocks);\n\n    /* Update inode blocks (different block size!) count */\n    uint64_t ino_blocks = ext4_inode_get_blocks_count(sb, inode_ref->inode);\n    ino_blocks += block_size / EXT4_INODE_BLOCK_SIZE;\n    ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks);\n    inode_ref->dirty = true;\n\n    /* Update block group free blocks count */\n\n    uint32_t fb_cnt = ext4_bg_get_free_blocks_count(bg_ref.block_group, sb);\n    fb_cnt--;\n    ext4_bg_set_free_blocks_count(bg_ref.block_group, sb, fb_cnt);\n\n    bg_ref.dirty = true;\n    r = ext4_fs_put_block_group_ref(&bg_ref);\n\n    *fblock = alloc;\n    return r;\n}\n\nint ext4_balloc_try_alloc_block(struct ext4_inode_ref *inode_ref,\n                ext4_fsblk_t baddr, bool *free)\n{\n    int rc;\n\n    struct ext4_fs *fs = inode_ref->fs;\n    struct ext4_sblock *sb = &fs->sb;\n\n    /* Compute indexes */\n    uint32_t block_group = ext4_balloc_get_bgid_of_block(sb, baddr);\n    uint32_t index_in_group = ext4_fs_addr_to_idx_bg(sb, baddr);\n\n    /* Load block group reference */\n    struct ext4_block_group_ref bg_ref;\n    rc = ext4_fs_get_block_group_ref(fs, block_group, &bg_ref);\n    if (rc != EOK)\n        return rc;\n\n    /* Load block with bitmap */\n    ext4_fsblk_t bmp_blk_addr;\n    bmp_blk_addr = ext4_bg_get_block_bitmap(bg_ref.block_group, sb);\n\n    struct ext4_block b;\n    rc = ext4_trans_block_get(fs->bdev, &b, bmp_blk_addr);\n    if (rc != EOK) {\n        ext4_fs_put_block_group_ref(&bg_ref);\n        return rc;\n    }\n\n    if (!ext4_balloc_verify_bitmap_csum(sb, bg_ref.block_group, b.data)) {\n        ext4_dbg(DEBUG_BALLOC,\n            DBG_WARN \"Bitmap checksum failed.\"\n            \"Group: %\" PRIu32\"\\n\",\n            bg_ref.index);\n    }\n\n    /* Check if block is free */\n    *free = ext4_bmap_is_bit_clr(b.data, index_in_group);\n\n    /* Allocate block if possible */\n    if (*free) {\n        ext4_bmap_bit_set(b.data, index_in_group);\n        ext4_balloc_set_bitmap_csum(sb, bg_ref.block_group, b.data);\n        ext4_trans_set_block_dirty(b.buf);\n    }\n\n    /* Release block with bitmap */\n    rc = ext4_block_set(fs->bdev, &b);\n    if (rc != EOK) {\n        /* Error in saving bitmap */\n        ext4_fs_put_block_group_ref(&bg_ref);\n        return rc;\n    }\n\n    /* If block is not free, return */\n    if (!(*free))\n        goto terminate;\n\n    uint32_t block_size = ext4_sb_get_block_size(sb);\n\n    /* Update superblock free blocks count */\n    uint64_t sb_free_blocks = ext4_sb_get_free_blocks_cnt(sb);\n    sb_free_blocks--;\n    ext4_sb_set_free_blocks_cnt(sb, sb_free_blocks);\n\n    /* Update inode blocks count */\n    uint64_t ino_blocks = ext4_inode_get_blocks_count(sb, inode_ref->inode);\n    ino_blocks += block_size / EXT4_INODE_BLOCK_SIZE;\n    ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks);\n    inode_ref->dirty = true;\n\n    /* Update block group free blocks count */\n    uint32_t fb_cnt = ext4_bg_get_free_blocks_count(bg_ref.block_group, sb);\n    fb_cnt--;\n    ext4_bg_set_free_blocks_count(bg_ref.block_group, sb, fb_cnt);\n\n    bg_ref.dirty = true;\n\nterminate:\n    return ext4_fs_put_block_group_ref(&bg_ref);\n}\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/src/ext4_bcache.c",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_bcache.c\n * @brief Block cache allocator.\n */\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_bcache.h>\n#include <ext4_blockdev.h>\n#include <ext4_debug.h>\n#include <ext4_errno.h>\n\n#include <string.h>\n#include <stdlib.h>\n\nstatic int ext4_bcache_lba_compare(struct ext4_buf *a, struct ext4_buf *b)\n{\n     if (a->lba > b->lba)\n         return 1;\n     else if (a->lba < b->lba)\n         return -1;\n     return 0;\n}\n\nstatic int ext4_bcache_lru_compare(struct ext4_buf *a, struct ext4_buf *b)\n{\n    if (a->lru_id > b->lru_id)\n        return 1;\n    else if (a->lru_id < b->lru_id)\n        return -1;\n    return 0;\n}\n\nRB_GENERATE_INTERNAL(ext4_buf_lba, ext4_buf, lba_node,\n             ext4_bcache_lba_compare, static inline)\nRB_GENERATE_INTERNAL(ext4_buf_lru, ext4_buf, lru_node,\n             ext4_bcache_lru_compare, static inline)\n\nint ext4_bcache_init_dynamic(struct ext4_bcache *bc, uint32_t cnt,\n                 uint32_t itemsize)\n{\n    ext4_assert(bc && cnt && itemsize);\n\n    memset(bc, 0, sizeof(struct ext4_bcache));\n\n    bc->cnt = cnt;\n    bc->itemsize = itemsize;\n    bc->ref_blocks = 0;\n    bc->max_ref_blocks = 0;\n\n    return EOK;\n}\n\nvoid ext4_bcache_cleanup(struct ext4_bcache *bc)\n{\n    struct ext4_buf *buf, *tmp;\n    RB_FOREACH_SAFE(buf, ext4_buf_lba, &bc->lba_root, tmp) {\n        ext4_block_flush_buf(bc->bdev, buf);\n        ext4_bcache_drop_buf(bc, buf);\n    }\n}\n\nint ext4_bcache_fini_dynamic(struct ext4_bcache *bc)\n{\n    memset(bc, 0, sizeof(struct ext4_bcache));\n    return EOK;\n}\n\n/**@brief:\n *\n *  This is ext4_bcache, the module handling basic buffer-cache stuff.\n *\n *  Buffers in a bcache are sorted by their LBA and stored in a\n *  RB-Tree(lba_root).\n *\n *  Bcache also maintains another RB-Tree(lru_root) right now, where\n *  buffers are sorted by their LRU id.\n *\n *  A singly-linked list is used to track those dirty buffers which are\n *  ready to be flushed. (Those buffers which are dirty but also referenced\n *  are not considered ready to be flushed.)\n *\n *  When a buffer is not referenced, it will be stored in both lba_root\n *  and lru_root, while it will only be stored in lba_root when it is\n *  referenced.\n */\n\nstatic struct ext4_buf *\next4_buf_alloc(struct ext4_bcache *bc, uint64_t lba)\n{\n    void *data;\n    struct ext4_buf *buf;\n    data = ext4_alloc_bcache(bc->itemsize);\n    if (!data)\n        return NULL;\n\n    buf = ext4_calloc(1, sizeof(struct ext4_buf));\n    if (!buf) {\n        ext4_free(data);\n        return NULL;\n    }\n\n    buf->lba = lba;\n    buf->data = data;\n    buf->bc = bc;\n    return buf;\n}\n\nstatic void ext4_buf_free(struct ext4_buf *buf)\n{\n    ext4_free(buf->data);\n    ext4_free(buf);\n}\n\nstatic struct ext4_buf *\next4_buf_lookup(struct ext4_bcache *bc, uint64_t lba)\n{\n    struct ext4_buf tmp = {\n        .lba = lba\n    };\n\n    return RB_FIND(ext4_buf_lba, &bc->lba_root, &tmp);\n}\n\nstruct ext4_buf *ext4_buf_lowest_lru(struct ext4_bcache *bc)\n{\n    return RB_MIN(ext4_buf_lru, &bc->lru_root);\n}\n\nvoid ext4_bcache_drop_buf(struct ext4_bcache *bc, struct ext4_buf *buf)\n{\n    /* Warn on dropping any referenced buffers.*/\n    if (buf->refctr) {\n        ext4_dbg(DEBUG_BCACHE, DBG_WARN \"Buffer is still referenced. \"\n                \"lba: %\" PRIu64 \", refctr: %\" PRIu32 \"\\n\",\n                buf->lba, buf->refctr);\n    } else\n        RB_REMOVE(ext4_buf_lru, &bc->lru_root, buf);\n\n    RB_REMOVE(ext4_buf_lba, &bc->lba_root, buf);\n\n    /*Forcibly drop dirty buffer.*/\n    if (ext4_bcache_test_flag(buf, BC_DIRTY))\n        ext4_bcache_remove_dirty_node(bc, buf);\n\n    ext4_buf_free(buf);\n    bc->ref_blocks--;\n}\n\nvoid ext4_bcache_invalidate_buf(struct ext4_bcache *bc,\n                struct ext4_buf *buf)\n{\n    buf->end_write = NULL;\n    buf->end_write_arg = NULL;\n\n    /* Clear both dirty and up-to-date flags. */\n    if (ext4_bcache_test_flag(buf, BC_DIRTY))\n        ext4_bcache_remove_dirty_node(bc, buf);\n\n    ext4_bcache_clear_dirty(buf);\n}\n\nvoid ext4_bcache_invalidate_lba(struct ext4_bcache *bc,\n                uint64_t from,\n                uint32_t cnt)\n{\n    uint64_t end = from + cnt - 1;\n    struct ext4_buf *tmp = ext4_buf_lookup(bc, from), *buf;\n    RB_FOREACH_FROM(buf, ext4_buf_lba, tmp) {\n        if (buf->lba > end)\n            break;\n\n        ext4_bcache_invalidate_buf(bc, buf);\n    }\n}\n\nstruct ext4_buf *\next4_bcache_find_get(struct ext4_bcache *bc, struct ext4_block *b,\n             uint64_t lba)\n{\n    struct ext4_buf *buf = ext4_buf_lookup(bc, lba);\n    if (buf) {\n        /* If buffer is not referenced. */\n        if (!buf->refctr) {\n            /* Assign new value to LRU id and increment LRU counter\n             * by 1*/\n            buf->lru_id = ++bc->lru_ctr;\n            RB_REMOVE(ext4_buf_lru, &bc->lru_root, buf);\n            if (ext4_bcache_test_flag(buf, BC_DIRTY))\n                ext4_bcache_remove_dirty_node(bc, buf);\n\n        }\n\n        ext4_bcache_inc_ref(buf);\n\n        b->lb_id = lba;\n        b->buf = buf;\n        b->data = buf->data;\n    }\n    return buf;\n}\n\nint ext4_bcache_alloc(struct ext4_bcache *bc, struct ext4_block *b,\n              bool *is_new)\n{\n    /* Try to search the buffer with exaxt LBA. */\n    struct ext4_buf *buf = ext4_bcache_find_get(bc, b, b->lb_id);\n    if (buf) {\n        *is_new = false;\n        return EOK;\n    }\n\n    /* We need to allocate one buffer.*/\n    buf = ext4_buf_alloc(bc, b->lb_id);\n    if (!buf)\n        return ENOMEM;\n\n    RB_INSERT(ext4_buf_lba, &bc->lba_root, buf);\n    /* One more buffer in bcache now. :-) */\n    bc->ref_blocks++;\n\n    /*Calc ref blocks max depth*/\n    if (bc->max_ref_blocks < bc->ref_blocks)\n        bc->max_ref_blocks = bc->ref_blocks;\n\n\n    ext4_bcache_inc_ref(buf);\n    /* Assign new value to LRU id and increment LRU counter\n     * by 1*/\n    buf->lru_id = ++bc->lru_ctr;\n\n    b->buf = buf;\n    b->data = buf->data;\n\n    *is_new = true;\n    return EOK;\n}\n\nint ext4_bcache_free(struct ext4_bcache *bc, struct ext4_block *b)\n{\n    struct ext4_buf *buf = b->buf;\n\n    ext4_assert(bc && b);\n\n    /*Check if valid.*/\n    ext4_assert(b->lb_id);\n\n    /*Block should have a valid pointer to ext4_buf.*/\n    ext4_assert(buf);\n\n    /*Check if someone don't try free unreferenced block cache.*/\n    ext4_assert(buf->refctr);\n\n    /*Just decrease reference counter*/\n    ext4_bcache_dec_ref(buf);\n\n    /* We are the last one touching this buffer, do the cleanups. */\n    if (!buf->refctr) {\n        RB_INSERT(ext4_buf_lru, &bc->lru_root, buf);\n        /* This buffer is ready to be flushed. */\n        if (ext4_bcache_test_flag(buf, BC_DIRTY) &&\n            ext4_bcache_test_flag(buf, BC_UPTODATE)) {\n            if (bc->bdev->cache_write_back &&\n                !ext4_bcache_test_flag(buf, BC_FLUSH) &&\n                !ext4_bcache_test_flag(buf, BC_TMP))\n                ext4_bcache_insert_dirty_node(bc, buf);\n            else {\n                ext4_block_flush_buf(bc->bdev, buf);\n                ext4_bcache_clear_flag(buf, BC_FLUSH);\n            }\n        }\n\n        /* The buffer is invalidated...drop it. */\n        if (!ext4_bcache_test_flag(buf, BC_UPTODATE) ||\n            ext4_bcache_test_flag(buf, BC_TMP))\n            ext4_bcache_drop_buf(bc, buf);\n\n    }\n\n    b->lb_id = 0;\n    b->data = 0;\n\n    return EOK;\n}\n\nbool ext4_bcache_is_full(struct ext4_bcache *bc)\n{\n    return (bc->cnt <= bc->ref_blocks);\n}\n\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/src/ext4_bitmap.c",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_bitmap.c\n * @brief Block/inode bitmap allocator.\n */\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_misc.h>\n#include <ext4_errno.h>\n#include <ext4_debug.h>\n\n#include <ext4_bitmap.h>\n\nvoid ext4_bmap_bits_free(uint8_t *bmap, uint32_t sbit, uint32_t bcnt)\n{\n    uint32_t i = sbit;\n\n    while (i & 7) {\n\n        if (!bcnt)\n            return;\n\n        ext4_bmap_bit_clr(bmap, i);\n\n        bcnt--;\n        i++;\n    }\n    sbit = i;\n    bmap += (sbit >> 3);\n\n#if CONFIG_UNALIGNED_ACCESS\n    while (bcnt >= 32) {\n        *(uint32_t *)bmap = 0;\n        bmap += 4;\n        bcnt -= 32;\n        sbit += 32;\n    }\n\n    while (bcnt >= 16) {\n        *(uint16_t *)bmap = 0;\n        bmap += 2;\n        bcnt -= 16;\n        sbit += 16;\n    }\n#endif\n\n    while (bcnt >= 8) {\n        *bmap = 0;\n        bmap += 1;\n        bcnt -= 8;\n        sbit += 8;\n    }\n\n    for (i = 0; i < bcnt; ++i) {\n        ext4_bmap_bit_clr(bmap, i);\n    }\n}\n\nint ext4_bmap_bit_find_clr(uint8_t *bmap, uint32_t sbit, uint32_t ebit,\n               uint32_t *bit_id)\n{\n    uint32_t i;\n    uint32_t bcnt = ebit - sbit;\n\n    i = sbit;\n\n    while (i & 7) {\n\n        if (!bcnt)\n            return ENOSPC;\n\n        if (ext4_bmap_is_bit_clr(bmap, i)) {\n            *bit_id = sbit;\n            return EOK;\n        }\n\n        i++;\n        bcnt--;\n    }\n\n    sbit = i;\n    bmap += (sbit >> 3);\n\n#if CONFIG_UNALIGNED_ACCESS\n    while (bcnt >= 32) {\n        if (*(uint32_t *)bmap != 0xFFFFFFFF)\n            goto finish_it;\n\n        bmap += 4;\n        bcnt -= 32;\n        sbit += 32;\n    }\n\n    while (bcnt >= 16) {\n        if (*(uint16_t *)bmap != 0xFFFF)\n            goto finish_it;\n\n        bmap += 2;\n        bcnt -= 16;\n        sbit += 16;\n    }\nfinish_it:\n#endif\n    while (bcnt >= 8) {\n        if (*bmap != 0xFF) {\n            for (i = 0; i < 8; ++i) {\n                if (ext4_bmap_is_bit_clr(bmap, i)) {\n                    *bit_id = sbit + i;\n                    return EOK;\n                }\n            }\n        }\n\n        bmap += 1;\n        bcnt -= 8;\n        sbit += 8;\n    }\n\n    for (i = 0; i < bcnt; ++i) {\n        if (ext4_bmap_is_bit_clr(bmap, i)) {\n            *bit_id = sbit + i;\n            return EOK;\n        }\n    }\n\n    return ENOSPC;\n}\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/src/ext4_block_group.c",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n *\n *\n * HelenOS:\n * Copyright (c) 2012 Martin Sucha\n * Copyright (c) 2012 Frantisek Princ\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_block_group.c\n * @brief Block group function set.\n */\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_misc.h>\n#include <ext4_errno.h>\n#include <ext4_debug.h>\n\n#include <ext4_block_group.h>\n\n/**@brief CRC-16 look up table*/\nstatic uint16_t const crc16_tab[256] = {\n    0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 0xC601,\n    0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, 0xCC01, 0x0CC0,\n    0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0x0A00, 0xCAC1, 0xCB81,\n    0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, 0xD801, 0x18C0, 0x1980, 0xD941,\n    0x1B00, 0xDBC1, 0xDA81, 0x1A40, 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01,\n    0x1DC0, 0x1C80, 0xDC41, 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0,\n    0x1680, 0xD641, 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081,\n    0x1040, 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,\n    0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, 0x3C00,\n    0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 0xFA01, 0x3AC0,\n    0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, 0x2800, 0xE8C1, 0xE981,\n    0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 0xEE01, 0x2EC0, 0x2F80, 0xEF41,\n    0x2D00, 0xEDC1, 0xEC81, 0x2C40, 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700,\n    0xE7C1, 0xE681, 0x2640, 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0,\n    0x2080, 0xE041, 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281,\n    0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,\n    0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 0xAA01,\n    0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, 0x7800, 0xB8C1,\n    0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 0xBE01, 0x7EC0, 0x7F80,\n    0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 0xB401, 0x74C0, 0x7580, 0xB541,\n    0x7700, 0xB7C1, 0xB681, 0x7640, 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101,\n    0x71C0, 0x7080, 0xB041, 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0,\n    0x5280, 0x9241, 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481,\n    0x5440, 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,\n    0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, 0x8801,\n    0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 0x4E00, 0x8EC1,\n    0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 0x4400, 0x84C1, 0x8581,\n    0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 0x8201, 0x42C0, 0x4380, 0x8341,\n    0x4100, 0x81C1, 0x8081, 0x4040};\n\nuint16_t ext4_bg_crc16(uint16_t crc, const uint8_t *buffer, size_t len)\n{\n    while (len--)\n\n        crc = (((crc >> 8) & 0xffU) ^\n               crc16_tab[(crc ^ *buffer++) & 0xffU]) &\n              0x0000ffffU;\n    return crc;\n}\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/src/ext4_blockdev.c",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_blockdev.c\n * @brief Block device module.\n */\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_misc.h>\n#include <ext4_errno.h>\n#include <ext4_debug.h>\n\n#include <ext4_blockdev.h>\n#include <ext4_fs.h>\n#include <ext4_journal.h>\n\n#include <string.h>\n#include <stdlib.h>\n\nstatic void ext4_bdif_lock(struct ext4_blockdev *bdev)\n{\n    if (!bdev->bdif->lock)\n        return;\n\n    int r = bdev->bdif->lock(bdev);\n    ext4_assert(r == EOK);\n}\n\nstatic void ext4_bdif_unlock(struct ext4_blockdev *bdev)\n{\n    if (!bdev->bdif->unlock)\n        return;\n\n    int r = bdev->bdif->unlock(bdev);\n    ext4_assert(r == EOK);\n}\n\nstatic int ext4_bdif_bread(struct ext4_blockdev *bdev, void *buf,\n               uint64_t blk_id, uint32_t blk_cnt)\n{\n    ext4_bdif_lock(bdev);\n    int r = bdev->bdif->bread(bdev, buf, blk_id, blk_cnt);\n    bdev->bdif->bread_ctr++;\n    ext4_bdif_unlock(bdev);\n    return r;\n}\n\nstatic int ext4_bdif_bwrite(struct ext4_blockdev *bdev, const void *buf,\n                uint64_t blk_id, uint32_t blk_cnt)\n{\n    ext4_bdif_lock(bdev);\n    int r = bdev->bdif->bwrite(bdev, buf, blk_id, blk_cnt);\n    bdev->bdif->bwrite_ctr++;\n    ext4_bdif_unlock(bdev);\n    return r;\n}\n\nint ext4_block_init(struct ext4_blockdev *bdev)\n{\n    int rc;\n    ext4_assert(bdev);\n    ext4_assert(bdev->bdif);\n    ext4_assert(bdev->bdif->open &&\n           bdev->bdif->close &&\n           bdev->bdif->bread &&\n           bdev->bdif->bwrite);\n\n    if (bdev->bdif->ph_refctr) {\n        bdev->bdif->ph_refctr++;\n        return EOK;\n    }\n\n    /*Low level block init*/\n    rc = bdev->bdif->open(bdev);\n    if (rc != EOK)\n        return rc;\n\n    bdev->bdif->ph_refctr = 1;\n    return EOK;\n}\n\nint ext4_block_bind_bcache(struct ext4_blockdev *bdev, struct ext4_bcache *bc)\n{\n    ext4_assert(bdev && bc);\n    bdev->bc = bc;\n    bc->bdev = bdev;\n    return EOK;\n}\n\nvoid ext4_block_set_lb_size(struct ext4_blockdev *bdev, uint32_t lb_bsize)\n{\n    /*Logical block size has to be multiply of physical */\n    ext4_assert(!(lb_bsize % bdev->bdif->ph_bsize));\n\n    bdev->lg_bsize = lb_bsize;\n    bdev->lg_bcnt = bdev->part_size / lb_bsize;\n}\n\nint ext4_block_fini(struct ext4_blockdev *bdev)\n{\n    ext4_assert(bdev);\n\n    if (!bdev->bdif->ph_refctr)\n        return EOK;\n\n    bdev->bdif->ph_refctr--;\n    if (bdev->bdif->ph_refctr)\n        return EOK;\n\n    /*Low level block fini*/\n    return bdev->bdif->close(bdev);\n}\n\nint ext4_block_flush_buf(struct ext4_blockdev *bdev, struct ext4_buf *buf)\n{\n    int r;\n    struct ext4_bcache *bc = bdev->bc;\n\n    if (ext4_bcache_test_flag(buf, BC_DIRTY) &&\n        ext4_bcache_test_flag(buf, BC_UPTODATE)) {\n        r = ext4_blocks_set_direct(bdev, buf->data, buf->lba, 1);\n        if (r) {\n            if (buf->end_write) {\n                bc->dont_shake = true;\n                buf->end_write(bc, buf, r, buf->end_write_arg);\n                bc->dont_shake = false;\n            }\n\n            return r;\n        }\n\n        ext4_bcache_remove_dirty_node(bc, buf);\n        ext4_bcache_clear_flag(buf, BC_DIRTY);\n        if (buf->end_write) {\n            bc->dont_shake = true;\n            buf->end_write(bc, buf, r, buf->end_write_arg);\n            bc->dont_shake = false;\n        }\n    }\n    return EOK;\n}\n\nint ext4_block_flush_lba(struct ext4_blockdev *bdev, uint64_t lba)\n{\n    int r = EOK;\n    struct ext4_buf *buf;\n    struct ext4_block b;\n    buf = ext4_bcache_find_get(bdev->bc, &b, lba);\n    if (buf) {\n        r = ext4_block_flush_buf(bdev, buf);\n        ext4_bcache_free(bdev->bc, &b);\n    }\n    return r;\n}\n\nint ext4_block_cache_shake(struct ext4_blockdev *bdev)\n{\n    int r = EOK;\n    struct ext4_buf *buf;\n    if (bdev->bc->dont_shake)\n        return EOK;\n\n    bdev->bc->dont_shake = true;\n\n    while (!RB_EMPTY(&bdev->bc->lru_root) &&\n        ext4_bcache_is_full(bdev->bc)) {\n\n        buf = ext4_buf_lowest_lru(bdev->bc);\n        ext4_assert(buf);\n        if (ext4_bcache_test_flag(buf, BC_DIRTY)) {\n            r = ext4_block_flush_buf(bdev, buf);\n            if (r != EOK)\n                break;\n\n        }\n\n        ext4_bcache_drop_buf(bdev->bc, buf);\n    }\n    bdev->bc->dont_shake = false;\n    return r;\n}\n\nint ext4_block_get_noread(struct ext4_blockdev *bdev, struct ext4_block *b,\n              uint64_t lba)\n{\n    bool is_new;\n    int r;\n\n    ext4_assert(bdev && b);\n\n    if (!bdev->bdif->ph_refctr)\n        return EIO;\n\n    if (!(lba < bdev->lg_bcnt))\n        return ENXIO;\n\n    b->lb_id = lba;\n\n    /*If cache is full we have to (flush and) drop it anyway :(*/\n    r = ext4_block_cache_shake(bdev);\n    if (r != EOK)\n        return r;\n\n    r = ext4_bcache_alloc(bdev->bc, b, &is_new);\n    if (r != EOK)\n        return r;\n\n    if (!b->data)\n        return ENOMEM;\n\n    return EOK;\n}\n\nint ext4_block_get(struct ext4_blockdev *bdev, struct ext4_block *b,\n           uint64_t lba)\n{\n    int r = ext4_block_get_noread(bdev, b, lba);\n    if (r != EOK)\n        return r;\n\n    if (ext4_bcache_test_flag(b->buf, BC_UPTODATE)) {\n        /* Data in the cache is up-to-date.\n         * Reading from physical device is not required */\n        return EOK;\n    }\n\n    r = ext4_blocks_get_direct(bdev, b->data, lba, 1);\n    if (r != EOK) {\n        ext4_bcache_free(bdev->bc, b);\n        b->lb_id = 0;\n        return r;\n    }\n\n    /* Mark buffer up-to-date, since\n     * fresh data is read from physical device just now. */\n    ext4_bcache_set_flag(b->buf, BC_UPTODATE);\n    return EOK;\n}\n\nint ext4_block_set(struct ext4_blockdev *bdev, struct ext4_block *b)\n{\n    ext4_assert(bdev && b);\n    ext4_assert(b->buf);\n\n    if (!bdev->bdif->ph_refctr)\n        return EIO;\n\n    return ext4_bcache_free(bdev->bc, b);\n}\n\nint ext4_blocks_get_direct(struct ext4_blockdev *bdev, void *buf, uint64_t lba,\n               uint32_t cnt)\n{\n    uint64_t pba;\n    uint32_t pb_cnt;\n\n    ext4_assert(bdev && buf);\n\n    pba = (lba * bdev->lg_bsize + bdev->part_offset) / bdev->bdif->ph_bsize;\n    pb_cnt = bdev->lg_bsize / bdev->bdif->ph_bsize;\n\n    return ext4_bdif_bread(bdev, buf, pba, pb_cnt * cnt);\n}\n\nint ext4_blocks_set_direct(struct ext4_blockdev *bdev, const void *buf,\n               uint64_t lba, uint32_t cnt)\n{\n    uint64_t pba;\n    uint32_t pb_cnt;\n\n    ext4_assert(bdev && buf);\n\n    pba = (lba * bdev->lg_bsize + bdev->part_offset) / bdev->bdif->ph_bsize;\n    pb_cnt = bdev->lg_bsize / bdev->bdif->ph_bsize;\n\n    return ext4_bdif_bwrite(bdev, buf, pba, pb_cnt * cnt);\n}\n\nint ext4_block_writebytes(struct ext4_blockdev *bdev, uint64_t off,\n              const void *buf, uint32_t len)\n{\n    uint64_t block_idx;\n    uint32_t blen;\n    uint32_t unalg;\n    int r = EOK;\n\n    const uint8_t *p = (void *)buf;\n\n    ext4_assert(bdev && buf);\n\n    if (!bdev->bdif->ph_refctr)\n        return EIO;\n\n    if (off + len > bdev->part_size)\n        return EINVAL; /*Ups. Out of range operation*/\n\n    block_idx = ((off + bdev->part_offset) / bdev->bdif->ph_bsize);\n\n    /*OK lets deal with the first possible unaligned block*/\n    unalg = (off & (bdev->bdif->ph_bsize - 1));\n    if (unalg) {\n\n        uint32_t wlen = (bdev->bdif->ph_bsize - unalg) > len\n                    ? len\n                    : (bdev->bdif->ph_bsize - unalg);\n\n        r = ext4_bdif_bread(bdev, bdev->bdif->ph_bbuf, block_idx, 1);\n        if (r != EOK)\n            return r;\n\n        memcpy(bdev->bdif->ph_bbuf + unalg, p, wlen);\n        r = ext4_bdif_bwrite(bdev, bdev->bdif->ph_bbuf, block_idx, 1);\n        if (r != EOK)\n            return r;\n\n        p += wlen;\n        len -= wlen;\n        block_idx++;\n    }\n\n    /*Aligned data*/\n    blen = len / bdev->bdif->ph_bsize;\n    if (blen != 0) {\n        r = ext4_bdif_bwrite(bdev, p, block_idx, blen);\n        if (r != EOK)\n            return r;\n\n        p += bdev->bdif->ph_bsize * blen;\n        len -= bdev->bdif->ph_bsize * blen;\n\n        block_idx += blen;\n    }\n\n    /*Rest of the data*/\n    if (len) {\n        r = ext4_bdif_bread(bdev, bdev->bdif->ph_bbuf, block_idx, 1);\n        if (r != EOK)\n            return r;\n\n        memcpy(bdev->bdif->ph_bbuf, p, len);\n        r = ext4_bdif_bwrite(bdev, bdev->bdif->ph_bbuf, block_idx, 1);\n        if (r != EOK)\n            return r;\n    }\n\n    return r;\n}\n\nint ext4_block_readbytes(struct ext4_blockdev *bdev, uint64_t off, void *buf,\n             uint32_t len)\n{\n    uint64_t block_idx;\n    uint32_t blen;\n    uint32_t unalg;\n    int r = EOK;\n\n    uint8_t *p = (void *)buf;\n\n    ext4_assert(bdev && buf);\n\n    if (!bdev->bdif->ph_refctr)\n        return EIO;\n\n    if (off + len > bdev->part_size)\n        return EINVAL; /*Ups. Out of range operation*/\n\n    block_idx = ((off + bdev->part_offset) / bdev->bdif->ph_bsize);\n\n    /*OK lets deal with the first possible unaligned block*/\n    unalg = (off & (bdev->bdif->ph_bsize - 1));\n    if (unalg) {\n\n        uint32_t rlen = (bdev->bdif->ph_bsize - unalg) > len\n                    ? len\n                    : (bdev->bdif->ph_bsize - unalg);\n\n        r = ext4_bdif_bread(bdev, bdev->bdif->ph_bbuf, block_idx, 1);\n        if (r != EOK)\n            return r;\n\n        memcpy(p, bdev->bdif->ph_bbuf + unalg, rlen);\n\n        p += rlen;\n        len -= rlen;\n        block_idx++;\n    }\n\n    /*Aligned data*/\n    blen = len / bdev->bdif->ph_bsize;\n\n    if (blen != 0) {\n        r = ext4_bdif_bread(bdev, p, block_idx, blen);\n        if (r != EOK)\n            return r;\n\n        p += bdev->bdif->ph_bsize * blen;\n        len -= bdev->bdif->ph_bsize * blen;\n\n        block_idx += blen;\n    }\n\n    /*Rest of the data*/\n    if (len) {\n        r = ext4_bdif_bread(bdev, bdev->bdif->ph_bbuf, block_idx, 1);\n        if (r != EOK)\n            return r;\n\n        memcpy(p, bdev->bdif->ph_bbuf, len);\n    }\n\n    return r;\n}\n\nint ext4_block_cache_flush(struct ext4_blockdev *bdev)\n{\n    while (!SLIST_EMPTY(&bdev->bc->dirty_list)) {\n        int r;\n        struct ext4_buf *buf = SLIST_FIRST(&bdev->bc->dirty_list);\n        ext4_assert(buf);\n        r = ext4_block_flush_buf(bdev, buf);\n        if (r != EOK)\n            return r;\n\n    }\n    return EOK;\n}\n\nint ext4_block_cache_write_back(struct ext4_blockdev *bdev, uint8_t on_off)\n{\n    if (on_off)\n        bdev->cache_write_back++;\n\n    if (!on_off && bdev->cache_write_back)\n        bdev->cache_write_back--;\n\n    if (bdev->cache_write_back)\n        return EOK;\n\n    /*Flush data in all delayed cache blocks*/\n    return ext4_block_cache_flush(bdev);\n}\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/src/ext4_crc32.c",
    "content": "/*\n * Copyright (c) 2014 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * All rights reserved.\n *\n * Based on FreeBSD.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_crc32c.c\n * @brief Crc32c routine. Taken from FreeBSD kernel.\n */\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_misc.h>\n#include <ext4_errno.h>\n#include <ext4_debug.h>\n\n#include \"ext4_crc32.h\"\n\nstatic const uint32_t crc32_tab[] = {\n    0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,\n    0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,\n    0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,\n    0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,\n    0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,\n    0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,\n    0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,\n    0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,\n    0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,\n    0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,\n    0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,\n    0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,\n    0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,\n    0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,\n    0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,\n    0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,\n    0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,\n    0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,\n    0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,\n    0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,\n    0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,\n    0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,\n    0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,\n    0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,\n    0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,\n    0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,\n    0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,\n    0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,\n    0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,\n    0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,\n    0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,\n    0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,\n    0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,\n    0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,\n    0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,\n    0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,\n    0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,\n    0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,\n    0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,\n    0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,\n    0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,\n    0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,\n    0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d\n};\n\n/* */\n/* CRC LOOKUP TABLE */\n/* ================ */\n/* The following CRC lookup table was generated automagically */\n/* by the Rocksoft^tm Model CRC Algorithm Table Generation */\n/* Program V1.0 using the following model parameters: */\n/* */\n/* Width : 4 bytes. */\n/* Poly : 0x1EDC6F41L */\n/* Reverse : TRUE. */\n/* */\n/* For more information on the Rocksoft^tm Model CRC Algorithm, */\n/* see the document titled \"A Painless Guide to CRC Error */\n/* Detection Algorithms\" by Ross Williams */\n/* (ross@guest.adelaide.edu.au.). This document is likely to be */\n/* in the FTP archive \"ftp.adelaide.edu.au/pub/rocksoft\". */\n/* */\nstatic const uint32_t crc32c_tab[256] = {\n    0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, 0xC79A971FL,\n    0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, 0x8AD958CFL, 0x78B2DBCCL,\n    0x6BE22838L, 0x9989AB3BL, 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L,\n    0x5E133C24L, 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,\n    0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, 0x9A879FA0L,\n    0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, 0x5D1D08BFL, 0xAF768BBCL,\n    0xBC267848L, 0x4E4DFB4BL, 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L,\n    0x33ED7D2AL, 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,\n    0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, 0x6DFE410EL,\n    0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, 0x30E349B1L, 0xC288CAB2L,\n    0xD1D83946L, 0x23B3BA45L, 0xF779DEAEL, 0x05125DADL, 0x1642AE59L,\n    0xE4292D5AL, 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,\n    0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, 0x417B1DBCL,\n    0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, 0x86E18AA3L, 0x748A09A0L,\n    0x67DAFA54L, 0x95B17957L, 0xCBA24573L, 0x39C9C670L, 0x2A993584L,\n    0xD8F2B687L, 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,\n    0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, 0x96BF4DCCL,\n    0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, 0xDBFC821CL, 0x2997011FL,\n    0x3AC7F2EBL, 0xC8AC71E8L, 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L,\n    0x0F36E6F7L, 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,\n    0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, 0xEB1FCBADL,\n    0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, 0x2C855CB2L, 0xDEEEDFB1L,\n    0xCDBE2C45L, 0x3FD5AF46L, 0x7198540DL, 0x83F3D70EL, 0x90A324FAL,\n    0x62C8A7F9L, 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,\n    0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, 0x3CDB9BDDL,\n    0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, 0x82F63B78L, 0x709DB87BL,\n    0x63CD4B8FL, 0x91A6C88CL, 0x456CAC67L, 0xB7072F64L, 0xA457DC90L,\n    0x563C5F93L, 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,\n    0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, 0x92A8FC17L,\n    0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, 0x55326B08L, 0xA759E80BL,\n    0xB4091BFFL, 0x466298FCL, 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL,\n    0x0B21572CL, 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,\n    0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, 0x65D122B9L,\n    0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, 0x2892ED69L, 0xDAF96E6AL,\n    0xC9A99D9EL, 0x3BC21E9DL, 0xEF087A76L, 0x1D63F975L, 0x0E330A81L,\n    0xFC588982L, 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,\n    0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, 0x38CC2A06L,\n    0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, 0xFF56BD19L, 0x0D3D3E1AL,\n    0x1E6DCDEEL, 0xEC064EEDL, 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L,\n    0xD0DDD530L, 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,\n    0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, 0x8ECEE914L,\n    0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, 0xD3D3E1ABL, 0x21B862A8L,\n    0x32E8915CL, 0xC083125FL, 0x144976B4L, 0xE622F5B7L, 0xF5720643L,\n    0x07198540L, 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,\n    0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, 0xE330A81AL,\n    0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, 0x24AA3F05L, 0xD6C1BC06L,\n    0xC5914FF2L, 0x37FACCF1L, 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L,\n    0x7AB90321L, 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,\n    0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, 0x34F4F86AL,\n    0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, 0x79B737BAL, 0x8BDCB4B9L,\n    0x988C474DL, 0x6AE7C44EL, 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L,\n    0xAD7D5351L};\n\nstatic inline uint32_t crc32(uint32_t crc, const void *buf, uint32_t size,\n                 const uint32_t *tab)\n{\n    const uint8_t *p = (const uint8_t *)buf;\n\n    while (size--)\n        crc = tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);\n\n    return (crc);\n}\n\nuint32_t ext4_crc32(uint32_t crc, const void *buf, uint32_t size)\n{\n    return crc32(crc, buf, size, crc32_tab);\n}\n\nuint32_t ext4_crc32c(uint32_t crc, const void *buf, uint32_t size)\n{\n    return crc32(crc, buf, size, crc32c_tab);\n}\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/src/ext4_debug.c",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_debug.c\n * @brief Debug printf and assert macros.\n */\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_misc.h>\n#include <ext4_errno.h>\n#include <ext4_debug.h>\n\n#include <stdarg.h>\n\nstatic uint32_t debug_mask;\n\nvoid ext4_dmask_set(uint32_t m)\n{\n    debug_mask |= m;\n}\n\nvoid ext4_dmask_clr(uint32_t m)\n{\n    debug_mask &= ~m;\n}\n\nuint32_t ext4_dmask_get(void)\n{\n    return debug_mask;\n}\n\n\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/src/ext4_dir.c",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n *\n *\n * HelenOS:\n * Copyright (c) 2012 Martin Sucha\n * Copyright (c) 2012 Frantisek Princ\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_dir.h\n * @brief Directory handle procedures.\n */\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_misc.h>\n#include <ext4_errno.h>\n#include <ext4_debug.h>\n\n#include <ext4_trans.h>\n#include <ext4_dir.h>\n#include <ext4_dir_idx.h>\n#include <ext4_crc32.h>\n#include <ext4_inode.h>\n#include <ext4_fs.h>\n\n#include <string.h>\n\n/****************************************************************************/\n\n/* Walk through a dirent block to find a checksum \"dirent\" at the tail */\nstatic struct ext4_dir_entry_tail *\next4_dir_get_tail(struct ext4_inode_ref *inode_ref,\n        struct ext4_dir_en *de)\n{\n    struct ext4_dir_entry_tail *t;\n    struct ext4_sblock *sb = &inode_ref->fs->sb;\n\n    t = EXT4_DIRENT_TAIL(de, ext4_sb_get_block_size(sb));\n\n    if (t->reserved_zero1 || t->reserved_zero2)\n        return NULL;\n    if (to_le16(t->rec_len) != sizeof(struct ext4_dir_entry_tail))\n        return NULL;\n    if (t->reserved_ft != EXT4_DIRENTRY_DIR_CSUM)\n        return NULL;\n\n    return t;\n}\n\n#if CONFIG_META_CSUM_ENABLE\nstatic uint32_t ext4_dir_csum(struct ext4_inode_ref *inode_ref,\n                  struct ext4_dir_en *dirent, int size)\n{\n    uint32_t csum;\n    struct ext4_sblock *sb = &inode_ref->fs->sb;\n    uint32_t ino_index = to_le32(inode_ref->index);\n    uint32_t ino_gen = to_le32(ext4_inode_get_generation(inode_ref->inode));\n\n    /* First calculate crc32 checksum against fs uuid */\n    csum = ext4_crc32c(EXT4_CRC32_INIT, sb->uuid, sizeof(sb->uuid));\n    /* Then calculate crc32 checksum against inode number\n     * and inode generation */\n    csum = ext4_crc32c(csum, &ino_index, sizeof(ino_index));\n    csum = ext4_crc32c(csum, &ino_gen, sizeof(ino_gen));\n    /* Finally calculate crc32 checksum against directory entries */\n    csum = ext4_crc32c(csum, dirent, size);\n    return csum;\n}\n#else\n#define ext4_dir_csum(...) 0\n#endif\n\nbool ext4_dir_csum_verify(struct ext4_inode_ref *inode_ref,\n                  struct ext4_dir_en *dirent)\n{\n#ifdef CONFIG_META_CSUM_ENABLE\n    struct ext4_dir_entry_tail *t;\n    struct ext4_sblock *sb = &inode_ref->fs->sb;\n\n    /* Compute the checksum only if the filesystem supports it */\n    if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) {\n        t = ext4_dir_get_tail(inode_ref, dirent);\n        if (!t) {\n            /* There is no space to hold the checksum */\n            return false;\n        }\n\n        ptrdiff_t __unused diff = (char *)t - (char *)dirent;\n        uint32_t csum = ext4_dir_csum(inode_ref, dirent, diff);\n        if (t->checksum != to_le32(csum))\n            return false;\n\n    }\n#endif\n    return true;\n}\n\nvoid ext4_dir_init_entry_tail(struct ext4_dir_entry_tail *t)\n{\n    memset(t, 0, sizeof(struct ext4_dir_entry_tail));\n    t->rec_len = to_le16(sizeof(struct ext4_dir_entry_tail));\n    t->reserved_ft = EXT4_DIRENTRY_DIR_CSUM;\n}\n\nvoid ext4_dir_set_csum(struct ext4_inode_ref *inode_ref,\n               struct ext4_dir_en *dirent)\n{\n    struct ext4_dir_entry_tail *t;\n    struct ext4_sblock *sb = &inode_ref->fs->sb;\n\n    /* Compute the checksum only if the filesystem supports it */\n    if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) {\n        t = ext4_dir_get_tail(inode_ref, dirent);\n        if (!t) {\n            /* There is no space to hold the checksum */\n            return;\n        }\n\n        ptrdiff_t __unused diff = (char *)t - (char *)dirent;\n        uint32_t csum = ext4_dir_csum(inode_ref, dirent, diff);\n        t->checksum = to_le32(csum);\n    }\n}\n\n/**@brief Do some checks before returning iterator.\n * @param it Iterator to be checked\n * @param block_size Size of data block\n * @return Error code\n */\nstatic int ext4_dir_iterator_set(struct ext4_dir_iter *it,\n                 uint32_t block_size)\n{\n    uint32_t off_in_block = it->curr_off % block_size;\n    struct ext4_sblock *sb = &it->inode_ref->fs->sb;\n\n    it->curr = NULL;\n\n    /* Ensure proper alignment */\n    if ((off_in_block % 4) != 0)\n        return EIO;\n\n    /* Ensure that the core of the entry does not overflow the block */\n    if (off_in_block > block_size - 8)\n        return EIO;\n\n    struct ext4_dir_en *en;\n    en = (void *)(it->curr_blk.data + off_in_block);\n\n    /* Ensure that the whole entry does not overflow the block */\n    uint16_t length = ext4_dir_en_get_entry_len(en);\n    if (off_in_block + length > block_size)\n        return EIO;\n\n    /* Ensure the name length is not too large */\n    if (ext4_dir_en_get_name_len(sb, en) > length - 8)\n        return EIO;\n\n    /* Everything OK - \"publish\" the entry */\n    it->curr = en;\n    return EOK;\n}\n\n/**@brief Seek to next valid directory entry.\n *        Here can be jumped to the next data block.\n * @param it  Initialized iterator\n * @param pos Position of the next entry\n * @return Error code\n */\nstatic int ext4_dir_iterator_seek(struct ext4_dir_iter *it, uint64_t pos)\n{\n    struct ext4_sblock *sb = &it->inode_ref->fs->sb;\n    struct ext4_inode *inode = it->inode_ref->inode;\n    struct ext4_blockdev *bdev = it->inode_ref->fs->bdev;\n    uint64_t size = ext4_inode_get_size(sb, inode);\n    int r;\n\n    /* The iterator is not valid until we seek to the desired position */\n    it->curr = NULL;\n\n    /* Are we at the end? */\n    if (pos >= size) {\n        if (it->curr_blk.lb_id) {\n\n            r = ext4_block_set(bdev, &it->curr_blk);\n            it->curr_blk.lb_id = 0;\n            if (r != EOK)\n                return r;\n        }\n\n        it->curr_off = pos;\n        return EOK;\n    }\n\n    /* Compute next block address */\n    uint32_t block_size = ext4_sb_get_block_size(sb);\n    uint64_t current_blk_idx = it->curr_off / block_size;\n    uint32_t next_blk_idx = (uint32_t)(pos / block_size);\n\n    /*\n     * If we don't have a block or are moving across block boundary,\n     * we need to get another block\n     */\n    if ((it->curr_blk.lb_id == 0) ||\n        (current_blk_idx != next_blk_idx)) {\n        if (it->curr_blk.lb_id) {\n            r = ext4_block_set(bdev, &it->curr_blk);\n            it->curr_blk.lb_id = 0;\n\n            if (r != EOK)\n                return r;\n        }\n\n        ext4_fsblk_t next_blk;\n        r = ext4_fs_get_inode_dblk_idx(it->inode_ref, next_blk_idx,\n                           &next_blk, false);\n        if (r != EOK)\n            return r;\n\n        r = ext4_trans_block_get(bdev, &it->curr_blk, next_blk);\n        if (r != EOK) {\n            it->curr_blk.lb_id = 0;\n            return r;\n        }\n    }\n\n    it->curr_off = pos;\n    return ext4_dir_iterator_set(it, block_size);\n}\n\nint ext4_dir_iterator_init(struct ext4_dir_iter *it,\n               struct ext4_inode_ref *inode_ref, uint64_t pos)\n{\n    it->inode_ref = inode_ref;\n    it->curr = 0;\n    it->curr_off = 0;\n    it->curr_blk.lb_id = 0;\n\n    return ext4_dir_iterator_seek(it, pos);\n}\n\nint ext4_dir_iterator_next(struct ext4_dir_iter *it)\n{\n    int r = EOK;\n    uint16_t skip;\n\n    while (r == EOK) {\n        skip = ext4_dir_en_get_entry_len(it->curr);\n        r = ext4_dir_iterator_seek(it, it->curr_off + skip);\n\n        if (!it->curr)\n            break;\n        /*Skip NULL referenced entry*/\n        if (ext4_dir_en_get_inode(it->curr) != 0)\n            break;\n    }\n\n    return r;\n}\n\nint ext4_dir_iterator_fini(struct ext4_dir_iter *it)\n{\n    it->curr = 0;\n\n    if (it->curr_blk.lb_id)\n        return ext4_block_set(it->inode_ref->fs->bdev, &it->curr_blk);\n\n    return EOK;\n}\n\nvoid ext4_dir_write_entry(struct ext4_sblock *sb, struct ext4_dir_en *en,\n              uint16_t entry_len, struct ext4_inode_ref *child,\n              const char *name, size_t name_len)\n{\n    /* Check maximum entry length */\n    ext4_assert(entry_len <= ext4_sb_get_block_size(sb));\n\n    /* Set type of entry */\n    switch (ext4_inode_type(sb, child->inode)) {\n    case EXT4_INODE_MODE_DIRECTORY:\n        ext4_dir_en_set_inode_type(sb, en, EXT4_DE_DIR);\n        break;\n    case EXT4_INODE_MODE_FILE:\n        ext4_dir_en_set_inode_type(sb, en, EXT4_DE_REG_FILE);\n        break;\n    case EXT4_INODE_MODE_SOFTLINK:\n        ext4_dir_en_set_inode_type(sb, en, EXT4_DE_SYMLINK);\n        break;\n    case EXT4_INODE_MODE_CHARDEV:\n        ext4_dir_en_set_inode_type(sb, en, EXT4_DE_CHRDEV);\n        break;\n    case EXT4_INODE_MODE_BLOCKDEV:\n        ext4_dir_en_set_inode_type(sb, en, EXT4_DE_BLKDEV);\n        break;\n    case EXT4_INODE_MODE_FIFO:\n        ext4_dir_en_set_inode_type(sb, en, EXT4_DE_FIFO);\n        break;\n    case EXT4_INODE_MODE_SOCKET:\n        ext4_dir_en_set_inode_type(sb, en, EXT4_DE_SOCK);\n        break;\n    default:\n        /* FIXME: unsupported filetype */\n        ext4_dir_en_set_inode_type(sb, en, EXT4_DE_UNKNOWN);\n    }\n\n    /* Set basic attributes */\n    ext4_dir_en_set_inode(en, child->index);\n    ext4_dir_en_set_entry_len(en, entry_len);\n    ext4_dir_en_set_name_len(sb, en, (uint16_t)name_len);\n\n    /* Write name */\n    memcpy(en->name, name, name_len);\n}\n\nint ext4_dir_add_entry(struct ext4_inode_ref *parent, const char *name,\n               uint32_t name_len, struct ext4_inode_ref *child)\n{\n    int r;\n    struct ext4_fs *fs = parent->fs;\n    struct ext4_sblock *sb = &parent->fs->sb;\n\n#if CONFIG_DIR_INDEX_ENABLE\n    /* Index adding (if allowed) */\n    if ((ext4_sb_feature_com(sb, EXT4_FCOM_DIR_INDEX)) &&\n        (ext4_inode_has_flag(parent->inode, EXT4_INODE_FLAG_INDEX))) {\n        r = ext4_dir_dx_add_entry(parent, child, name, name_len);\n\n        /* Check if index is not corrupted */\n        if (r != EXT4_ERR_BAD_DX_DIR) {\n            if (r != EOK)\n                return r;\n\n            return EOK;\n        }\n\n        /* Needed to clear dir index flag if corrupted */\n        ext4_inode_clear_flag(parent->inode, EXT4_INODE_FLAG_INDEX);\n        parent->dirty = true;\n    }\n#endif\n\n    /* Linear algorithm */\n    uint32_t iblock = 0;\n    ext4_fsblk_t fblock = 0;\n    uint32_t block_size = ext4_sb_get_block_size(sb);\n    uint64_t inode_size = ext4_inode_get_size(sb, parent->inode);\n    uint32_t total_blocks = (uint32_t)(inode_size / block_size);\n\n    /* Find block, where is space for new entry and try to add */\n    bool success = false;\n    for (iblock = 0; iblock < total_blocks; ++iblock) {\n        r = ext4_fs_get_inode_dblk_idx(parent, iblock, &fblock, false);\n        if (r != EOK)\n            return r;\n\n        struct ext4_block block;\n        r = ext4_trans_block_get(fs->bdev, &block, fblock);\n        if (r != EOK)\n            return r;\n\n        if (!ext4_dir_csum_verify(parent, (void *)block.data)) {\n            ext4_dbg(DEBUG_DIR,\n                 DBG_WARN \"Leaf block checksum failed.\"\n                 \"Inode: %\" PRIu32\", \"\n                 \"Block: %\" PRIu32\"\\n\",\n                 parent->index,\n                 iblock);\n        }\n\n        /* If adding is successful, function can finish */\n        r = ext4_dir_try_insert_entry(sb, parent, &block, child,\n                        name, name_len);\n        if (r == EOK)\n            success = true;\n\n        r = ext4_block_set(fs->bdev, &block);\n        if (r != EOK)\n            return r;\n\n        if (success)\n            return EOK;\n    }\n\n    /* No free block found - needed to allocate next data block */\n\n    iblock = 0;\n    fblock = 0;\n    r = ext4_fs_append_inode_dblk(parent, &fblock, &iblock);\n    if (r != EOK)\n        return r;\n\n    /* Load new block */\n    struct ext4_block b;\n\n    r = ext4_trans_block_get_noread(fs->bdev, &b, fblock);\n    if (r != EOK)\n        return r;\n\n    /* Fill block with zeroes */\n    memset(b.data, 0, block_size);\n    struct ext4_dir_en *blk_en = (void *)b.data;\n\n    /* Save new block */\n    if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) {\n        uint16_t el = block_size - sizeof(struct ext4_dir_entry_tail);\n        ext4_dir_write_entry(sb, blk_en, el, child, name, name_len);\n        ext4_dir_init_entry_tail(EXT4_DIRENT_TAIL(b.data, block_size));\n    } else {\n        ext4_dir_write_entry(sb, blk_en, block_size, child, name,\n                name_len);\n    }\n\n    ext4_dir_set_csum(parent, (void *)b.data);\n    ext4_trans_set_block_dirty(b.buf);\n    r = ext4_block_set(fs->bdev, &b);\n\n    return r;\n}\n\nint ext4_dir_find_entry(struct ext4_dir_search_result *result,\n            struct ext4_inode_ref *parent, const char *name,\n            uint32_t name_len)\n{\n    int r;\n    struct ext4_sblock *sb = &parent->fs->sb;\n\n    /* Entry clear */\n    result->block.lb_id = 0;\n    result->dentry = NULL;\n\n#if CONFIG_DIR_INDEX_ENABLE\n    /* Index search */\n    if ((ext4_sb_feature_com(sb, EXT4_FCOM_DIR_INDEX)) &&\n        (ext4_inode_has_flag(parent->inode, EXT4_INODE_FLAG_INDEX))) {\n        r = ext4_dir_dx_find_entry(result, parent, name_len, name);\n        /* Check if index is not corrupted */\n        if (r != EXT4_ERR_BAD_DX_DIR) {\n            if (r != EOK)\n                return r;\n\n            return EOK;\n        }\n\n        /* Needed to clear dir index flag if corrupted */\n        ext4_inode_clear_flag(parent->inode, EXT4_INODE_FLAG_INDEX);\n        parent->dirty = true;\n    }\n#endif\n\n    /* Linear algorithm */\n\n    uint32_t iblock;\n    ext4_fsblk_t fblock;\n    uint32_t block_size = ext4_sb_get_block_size(sb);\n    uint64_t inode_size = ext4_inode_get_size(sb, parent->inode);\n    uint32_t total_blocks = (uint32_t)(inode_size / block_size);\n\n    /* Walk through all data blocks */\n    for (iblock = 0; iblock < total_blocks; ++iblock) {\n        /* Load block address */\n        r = ext4_fs_get_inode_dblk_idx(parent, iblock, &fblock, false);\n        if (r != EOK)\n            return r;\n\n        /* Load data block */\n        struct ext4_block b;\n        r = ext4_trans_block_get(parent->fs->bdev, &b, fblock);\n        if (r != EOK)\n            return r;\n\n        if (!ext4_dir_csum_verify(parent, (void *)b.data)) {\n            ext4_dbg(DEBUG_DIR,\n                 DBG_WARN \"Leaf block checksum failed.\"\n                 \"Inode: %\" PRIu32\", \"\n                 \"Block: %\" PRIu32\"\\n\",\n                 parent->index,\n                 iblock);\n        }\n\n        /* Try to find entry in block */\n        struct ext4_dir_en *res_entry;\n        r = ext4_dir_find_in_block(&b, sb, name_len, name, &res_entry);\n        if (r == EOK) {\n            result->block = b;\n            result->dentry = res_entry;\n            return EOK;\n        }\n\n        /* Entry not found - put block and continue to the next block */\n\n        r = ext4_block_set(parent->fs->bdev, &b);\n        if (r != EOK)\n            return r;\n    }\n\n    return ENOENT;\n}\n\nint ext4_dir_remove_entry(struct ext4_inode_ref *parent, const char *name,\n              uint32_t name_len)\n{\n    struct ext4_sblock *sb = &parent->fs->sb;\n    /* Check if removing from directory */\n    if (!ext4_inode_is_type(sb, parent->inode, EXT4_INODE_MODE_DIRECTORY))\n        return ENOTDIR;\n\n    /* Try to find entry */\n    struct ext4_dir_search_result result;\n    int rc = ext4_dir_find_entry(&result, parent, name, name_len);\n    if (rc != EOK)\n        return rc;\n\n    /* Invalidate entry */\n    ext4_dir_en_set_inode(result.dentry, 0);\n\n    /* Store entry position in block */\n    uint32_t pos = (uint8_t *)result.dentry - result.block.data;\n\n    /*\n     * If entry is not the first in block, it must be merged\n     * with previous entry\n     */\n    if (pos != 0) {\n        uint32_t offset = 0;\n\n        /* Start from the first entry in block */\n        struct ext4_dir_en *tmp_de =(void *)result.block.data;\n        uint16_t de_len = ext4_dir_en_get_entry_len(tmp_de);\n\n        /* Find direct predecessor of removed entry */\n        while ((offset + de_len) < pos) {\n            offset += ext4_dir_en_get_entry_len(tmp_de);\n            tmp_de = (void *)(result.block.data + offset);\n            de_len = ext4_dir_en_get_entry_len(tmp_de);\n        }\n\n        ext4_assert(de_len + offset == pos);\n\n        /* Add to removed entry length to predecessor's length */\n        uint16_t del_len;\n        del_len = ext4_dir_en_get_entry_len(result.dentry);\n        ext4_dir_en_set_entry_len(tmp_de, de_len + del_len);\n    }\n\n    ext4_dir_set_csum(parent,\n            (struct ext4_dir_en *)result.block.data);\n    ext4_trans_set_block_dirty(result.block.buf);\n\n    return ext4_dir_destroy_result(parent, &result);\n}\n\nint ext4_dir_try_insert_entry(struct ext4_sblock *sb,\n                  struct ext4_inode_ref *inode_ref,\n                  struct ext4_block *dst_blk,\n                  struct ext4_inode_ref *child, const char *name,\n                  uint32_t name_len)\n{\n    /* Compute required length entry and align it to 4 bytes */\n    uint32_t block_size = ext4_sb_get_block_size(sb);\n    uint16_t required_len = sizeof(struct ext4_fake_dir_entry) + name_len;\n\n    if ((required_len % 4) != 0)\n        required_len += 4 - (required_len % 4);\n\n    /* Initialize pointers, stop means to upper bound */\n    struct ext4_dir_en *start = (void *)dst_blk->data;\n    struct ext4_dir_en *stop = (void *)(dst_blk->data + block_size);\n\n    /*\n     * Walk through the block and check for invalid entries\n     * or entries with free space for new entry\n     */\n    while (start < stop) {\n        uint32_t inode = ext4_dir_en_get_inode(start);\n        uint16_t rec_len = ext4_dir_en_get_entry_len(start);\n        uint8_t itype = ext4_dir_en_get_inode_type(sb, start);\n\n        /* If invalid and large enough entry, use it */\n        if ((inode == 0) && (itype != EXT4_DIRENTRY_DIR_CSUM) &&\n            (rec_len >= required_len)) {\n            ext4_dir_write_entry(sb, start, rec_len, child, name,\n                         name_len);\n            ext4_dir_set_csum(inode_ref, (void *)dst_blk->data);\n            ext4_trans_set_block_dirty(dst_blk->buf);\n\n            return EOK;\n        }\n\n        /* Valid entry, try to split it */\n        if (inode != 0) {\n            uint16_t used_len;\n            used_len = ext4_dir_en_get_name_len(sb, start);\n\n            uint16_t sz;\n            sz = sizeof(struct ext4_fake_dir_entry) + used_len;\n\n            if ((used_len % 4) != 0)\n                sz += 4 - (used_len % 4);\n\n            uint16_t free_space = rec_len - sz;\n\n            /* There is free space for new entry */\n            if (free_space >= required_len) {\n                /* Cut tail of current entry */\n                struct ext4_dir_en * new_entry;\n                new_entry = (void *)((uint8_t *)start + sz);\n                ext4_dir_en_set_entry_len(start, sz);\n                ext4_dir_write_entry(sb, new_entry, free_space,\n                             child, name, name_len);\n\n                ext4_dir_set_csum(inode_ref,\n                          (void *)dst_blk->data);\n                ext4_trans_set_block_dirty(dst_blk->buf);\n                return EOK;\n            }\n        }\n\n        /* Jump to the next entry */\n        start = (void *)((uint8_t *)start + rec_len);\n    }\n\n    /* No free space found for new entry */\n    return ENOSPC;\n}\n\nint ext4_dir_find_in_block(struct ext4_block *block, struct ext4_sblock *sb,\n               size_t name_len, const char *name,\n               struct ext4_dir_en **res_entry)\n{\n    /* Start from the first entry in block */\n    struct ext4_dir_en *de = (struct ext4_dir_en *)block->data;\n\n    /* Set upper bound for cycling */\n    uint8_t *addr_limit = block->data + ext4_sb_get_block_size(sb);\n\n    /* Walk through the block and check entries */\n    while ((uint8_t *)de < addr_limit) {\n        /* Termination condition */\n        if ((uint8_t *)de + name_len > addr_limit)\n            break;\n\n        /* Valid entry - check it */\n        if (ext4_dir_en_get_inode(de) != 0) {\n            /* For more efficient compare only lengths firstly*/\n            uint16_t el = ext4_dir_en_get_name_len(sb, de);\n            if (el == name_len) {\n                /* Compare names */\n                if (memcmp(name, de->name, name_len) == 0) {\n                    *res_entry = de;\n                    return EOK;\n                }\n            }\n        }\n\n        uint16_t de_len = ext4_dir_en_get_entry_len(de);\n\n        /* Corrupted entry */\n        if (de_len == 0)\n            return EINVAL;\n\n        /* Jump to next entry */\n        de = (struct ext4_dir_en *)((uint8_t *)de + de_len);\n    }\n\n    /* Entry not found */\n    return ENOENT;\n}\n\nint ext4_dir_destroy_result(struct ext4_inode_ref *parent,\n                struct ext4_dir_search_result *result)\n{\n    if (result->block.lb_id)\n        return ext4_block_set(parent->fs->bdev, &result->block);\n\n    return EOK;\n}\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/src/ext4_dir_idx.c",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_dir_idx.c\n * @brief Directory indexing procedures.\n */\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_misc.h>\n#include <ext4_errno.h>\n#include <ext4_debug.h>\n\n#include <ext4_trans.h>\n#include <ext4_dir_idx.h>\n#include <ext4_dir.h>\n#include <ext4_blockdev.h>\n#include <ext4_fs.h>\n#include <ext4_super.h>\n#include <ext4_inode.h>\n#include <ext4_crc32.h>\n#include <ext4_hash.h>\n\n#include <string.h>\n#include <stdlib.h>\n\n/**@brief Get hash version used in directory index.\n * @param root_info Pointer to root info structure of index\n * @return Hash algorithm version\n */\nstatic inline uint8_t\next4_dir_dx_rinfo_get_hash_version(struct ext4_dir_idx_rinfo *ri)\n{\n    return ri->hash_version;\n}\n\n/**@brief Set hash version, that will be used in directory index.\n * @param root_info Pointer to root info structure of index\n * @param v Hash algorithm version\n */\nstatic inline void\next4_dir_dx_rinfo_set_hash_version(struct ext4_dir_idx_rinfo *ri, uint8_t v)\n{\n    ri->hash_version = v;\n}\n\n/**@brief Get length of root_info structure in bytes.\n * @param root_info Pointer to root info structure of index\n * @return Length of the structure\n */\nstatic inline uint8_t\next4_dir_dx_rinfo_get_info_length(struct ext4_dir_idx_rinfo *ri)\n{\n    return ri->info_length;\n}\n\n/**@brief Set length of root_info structure in bytes.\n * @param root_info   Pointer to root info structure of index\n * @param info_length Length of the structure\n */\nstatic inline void\next4_dir_dx_root_info_set_info_length(struct ext4_dir_idx_rinfo *ri,\n                      uint8_t len)\n{\n    ri->info_length = len;\n}\n\n/**@brief Get number of indirect levels of HTree.\n * @param root_info Pointer to root info structure of index\n * @return Height of HTree (actually only 0 or 1)\n */\nstatic inline uint8_t\next4_dir_dx_rinfo_get_indirect_levels(struct ext4_dir_idx_rinfo *ri)\n{\n    return ri->indirect_levels;\n}\n\n/**@brief Set number of indirect levels of HTree.\n * @param root_info Pointer to root info structure of index\n * @param lvl Height of HTree (actually only 0 or 1)\n */\nstatic inline void\next4_dir_dx_rinfo_set_indirect_levels(struct ext4_dir_idx_rinfo *ri, uint8_t l)\n{\n    ri->indirect_levels = l;\n}\n\n/**@brief Get maximum number of index node entries.\n * @param climit Pointer to counlimit structure\n * @return Maximum of entries in node\n */\nstatic inline uint16_t\next4_dir_dx_climit_get_limit(struct ext4_dir_idx_climit *climit)\n{\n    return to_le16(climit->limit);\n}\n\n/**@brief Set maximum number of index node entries.\n * @param climit Pointer to counlimit structure\n * @param limit Maximum of entries in node\n */\nstatic inline void\next4_dir_dx_climit_set_limit(struct ext4_dir_idx_climit *climit, uint16_t limit)\n{\n    climit->limit = to_le16(limit);\n}\n\n/**@brief Get current number of index node entries.\n * @param climit Pointer to counlimit structure\n * @return Number of entries in node\n */\nstatic inline uint16_t\next4_dir_dx_climit_get_count(struct ext4_dir_idx_climit *climit)\n{\n    return to_le16(climit->count);\n}\n\n/**@brief Set current number of index node entries.\n * @param climit Pointer to counlimit structure\n * @param count Number of entries in node\n */\nstatic inline void\next4_dir_dx_climit_set_count(struct ext4_dir_idx_climit *climit, uint16_t count)\n{\n    climit->count = to_le16(count);\n}\n\n/**@brief Get hash value of index entry.\n * @param entry Pointer to index entry\n * @return Hash value\n */\nstatic inline uint32_t\next4_dir_dx_entry_get_hash(struct ext4_dir_idx_entry *entry)\n{\n    return to_le32(entry->hash);\n}\n\n/**@brief Set hash value of index entry.\n * @param entry Pointer to index entry\n * @param hash  Hash value\n */\nstatic inline void\next4_dir_dx_entry_set_hash(struct ext4_dir_idx_entry *entry, uint32_t hash)\n{\n    entry->hash = to_le32(hash);\n}\n\n/**@brief Get block address where child node is located.\n * @param entry Pointer to index entry\n * @return Block address of child node\n */\nstatic inline uint32_t\next4_dir_dx_entry_get_block(struct ext4_dir_idx_entry *entry)\n{\n    return to_le32(entry->block);\n}\n\n/**@brief Set block address where child node is located.\n * @param entry Pointer to index entry\n * @param block Block address of child node\n */\nstatic inline void\next4_dir_dx_entry_set_block(struct ext4_dir_idx_entry *entry, uint32_t block)\n{\n    entry->block = to_le32(block);\n}\n\n/**@brief Sort entry item.*/\nstruct ext4_dx_sort_entry {\n    uint32_t hash;\n    uint32_t rec_len;\n    void *dentry;\n};\n\nstatic int ext4_dir_dx_hash_string(struct ext4_hash_info *hinfo, int len,\n                   const char *name)\n{\n    return ext2_htree_hash(name, len, hinfo->seed, hinfo->hash_version,\n                   &hinfo->hash, &hinfo->minor_hash);\n}\n\n#if CONFIG_META_CSUM_ENABLE\nstatic uint32_t ext4_dir_dx_checksum(struct ext4_inode_ref *inode_ref, void *de,\n                     int count_offset, int count,\n                     struct ext4_dir_idx_tail *t)\n{\n    uint32_t orig_cum, csum = 0;\n    struct ext4_sblock *sb = &inode_ref->fs->sb;\n    int sz;\n\n    /* Compute the checksum only if the filesystem supports it */\n    if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) {\n        uint32_t ino_index = to_le32(inode_ref->index);\n        uint32_t ino_gen;\n        ino_gen = to_le32(ext4_inode_get_generation(inode_ref->inode));\n\n        sz = count_offset + (count * sizeof(struct ext4_dir_idx_tail));\n        orig_cum = t->checksum;\n        t->checksum = 0;\n        /* First calculate crc32 checksum against fs uuid */\n        csum = ext4_crc32c(EXT4_CRC32_INIT, sb->uuid, sizeof(sb->uuid));\n        /* Then calculate crc32 checksum against inode number\n         * and inode generation */\n        csum = ext4_crc32c(csum, &ino_index, sizeof(ino_index));\n        csum = ext4_crc32c(csum, &ino_gen, sizeof(ino_gen));\n        /* After that calculate crc32 checksum against all the dx_entry */\n        csum = ext4_crc32c(csum, de, sz);\n        /* Finally calculate crc32 checksum for dx_tail */\n        csum = ext4_crc32c(csum, t, sizeof(struct ext4_dir_idx_tail));\n        t->checksum = orig_cum;\n    }\n    return csum;\n}\n\nstatic struct ext4_dir_idx_climit *\next4_dir_dx_get_climit(struct ext4_inode_ref *inode_ref,\n               struct ext4_dir_en *dirent, int *offset)\n{\n    struct ext4_dir_en *dp;\n    struct ext4_dir_idx_root *root;\n    struct ext4_sblock *sb = &inode_ref->fs->sb;\n    uint32_t block_size = ext4_sb_get_block_size(sb);\n    uint16_t entry_len = ext4_dir_en_get_entry_len(dirent);\n    int count_offset;\n\n\n    if (entry_len == 12) {\n        root = (struct ext4_dir_idx_root *)dirent;\n        dp = (struct ext4_dir_en *)&root->dots[1];\n        if (ext4_dir_en_get_entry_len(dp) != (block_size - 12))\n            return NULL;\n        if (root->info.reserved_zero)\n            return NULL;\n        if (root->info.info_length != sizeof(struct ext4_dir_idx_rinfo))\n            return NULL;\n        count_offset = 32;\n    } else if (entry_len == block_size) {\n        count_offset = 8;\n    } else {\n        return NULL;\n    }\n\n    if (offset)\n        *offset = count_offset;\n    return (struct ext4_dir_idx_climit *)(((char *)dirent) + count_offset);\n}\n\n/*\n * BIG FAT NOTES:\n *       Currently we do not verify the checksum of HTree node.\n */\nstatic bool ext4_dir_dx_csum_verify(struct ext4_inode_ref *inode_ref,\n                    struct ext4_dir_en *de)\n{\n    struct ext4_sblock *sb = &inode_ref->fs->sb;\n    uint32_t block_size = ext4_sb_get_block_size(sb);\n    int coff, limit, cnt;\n\n    if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) {\n        struct ext4_dir_idx_climit *climit;\n        climit = ext4_dir_dx_get_climit(inode_ref, de, &coff);\n        if (!climit) {\n            /* Directory seems corrupted. */\n            return true;\n        }\n        struct ext4_dir_idx_tail *t;\n        limit = ext4_dir_dx_climit_get_limit(climit);\n        cnt = ext4_dir_dx_climit_get_count(climit);\n        if (coff + (limit * sizeof(struct ext4_dir_idx_entry)) >\n            (block_size - sizeof(struct ext4_dir_idx_tail))) {\n            /* There is no space to hold the checksum */\n            return true;\n        }\n        t = (void *)(((struct ext4_dir_idx_entry *)climit) + limit);\n\n        uint32_t c;\n        c = to_le32(ext4_dir_dx_checksum(inode_ref, de, coff, cnt, t));\n        if (t->checksum != c)\n            return false;\n    }\n    return true;\n}\n\n\nstatic void ext4_dir_set_dx_csum(struct ext4_inode_ref *inode_ref,\n                 struct ext4_dir_en *dirent)\n{\n    int coff, limit, count;\n    struct ext4_sblock *sb = &inode_ref->fs->sb;\n    uint32_t block_size = ext4_sb_get_block_size(sb);\n\n    if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) {\n        struct ext4_dir_idx_climit *climit;\n        climit = ext4_dir_dx_get_climit(inode_ref, dirent, &coff);\n        if (!climit) {\n            /* Directory seems corrupted. */\n            return;\n        }\n        struct ext4_dir_idx_tail *t;\n        limit = ext4_dir_dx_climit_get_limit(climit);\n        count = ext4_dir_dx_climit_get_count(climit);\n        if (coff + (limit * sizeof(struct ext4_dir_idx_entry)) >\n           (block_size - sizeof(struct ext4_dir_idx_tail))) {\n            /* There is no space to hold the checksum */\n            return;\n        }\n\n        t = (void *)(((struct ext4_dir_idx_entry *)climit) + limit);\n        t->checksum = to_le32(ext4_dir_dx_checksum(inode_ref, dirent,\n                    coff, count, t));\n    }\n}\n#else\n#define ext4_dir_dx_csum_verify(...) true\n#define ext4_dir_set_dx_csum(...)\n#endif\n\n/****************************************************************************/\n\nint ext4_dir_dx_init(struct ext4_inode_ref *dir, struct ext4_inode_ref *parent)\n{\n    /* Load block 0, where will be index root located */\n    ext4_fsblk_t fblock;\n    uint32_t iblock = 0;\n    bool need_append =\n        (ext4_inode_get_size(&dir->fs->sb, dir->inode)\n            < EXT4_DIR_DX_INIT_BCNT)\n        ? true : false;\n    struct ext4_sblock *sb = &dir->fs->sb;\n    uint32_t block_size = ext4_sb_get_block_size(&dir->fs->sb);\n    struct ext4_block block;\n\n    int rc;\n\n    if (!need_append)\n        rc = ext4_fs_init_inode_dblk_idx(dir, iblock, &fblock);\n    else\n        rc = ext4_fs_append_inode_dblk(dir, &fblock, &iblock);\n\n    if (rc != EOK)\n        return rc;\n\n    rc = ext4_trans_block_get_noread(dir->fs->bdev, &block, fblock);\n    if (rc != EOK)\n        return rc;\n\n    /* Initialize pointers to data structures */\n    struct ext4_dir_idx_root *root = (void *)block.data;\n    struct ext4_dir_idx_rinfo *info = &(root->info);\n\n    memset(root, 0, sizeof(struct ext4_dir_idx_root));\n    struct ext4_dir_en *de;\n\n    /* Initialize dot entries */\n    de = (struct ext4_dir_en *)root->dots;\n    ext4_dir_write_entry(sb, de, 12, dir, \".\", strlen(\".\"));\n\n    de = (struct ext4_dir_en *)(root->dots + 1);\n    uint16_t elen = block_size - 12;\n    ext4_dir_write_entry(sb, de, elen, parent, \"..\", strlen(\"..\"));\n\n    /* Initialize root info structure */\n    uint8_t hash_version = ext4_get8(&dir->fs->sb, default_hash_version);\n\n    ext4_dir_dx_rinfo_set_hash_version(info, hash_version);\n    ext4_dir_dx_rinfo_set_indirect_levels(info, 0);\n    ext4_dir_dx_root_info_set_info_length(info, 8);\n\n    /* Set limit and current number of entries */\n    struct ext4_dir_idx_climit *climit;\n    climit = (struct ext4_dir_idx_climit *)&root->en;\n\n    ext4_dir_dx_climit_set_count(climit, 1);\n\n    uint32_t entry_space;\n    entry_space = block_size - 2 * sizeof(struct ext4_dir_idx_dot_en) -\n            sizeof(struct ext4_dir_idx_rinfo);\n\n    if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM))\n        entry_space -= sizeof(struct ext4_dir_idx_tail);\n\n    uint16_t root_limit = entry_space / sizeof(struct ext4_dir_idx_entry);\n    ext4_dir_dx_climit_set_limit(climit, root_limit);\n\n    /* Append new block, where will be new entries inserted in the future */\n    iblock++;\n    if (!need_append)\n        rc = ext4_fs_init_inode_dblk_idx(dir, iblock, &fblock);\n    else\n        rc = ext4_fs_append_inode_dblk(dir, &fblock, &iblock);\n\n    if (rc != EOK) {\n        ext4_block_set(dir->fs->bdev, &block);\n        return rc;\n    }\n\n    struct ext4_block new_block;\n    rc = ext4_trans_block_get_noread(dir->fs->bdev, &new_block, fblock);\n    if (rc != EOK) {\n        ext4_block_set(dir->fs->bdev, &block);\n        return rc;\n    }\n\n    /* Fill the whole block with empty entry */\n    struct ext4_dir_en *be = (void *)new_block.data;\n\n    if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) {\n        uint16_t len = block_size - sizeof(struct ext4_dir_entry_tail);\n        ext4_dir_en_set_entry_len(be, len);\n        ext4_dir_en_set_name_len(sb, be, 0);\n        ext4_dir_en_set_inode_type(sb, be, EXT4_DE_UNKNOWN);\n        ext4_dir_init_entry_tail(EXT4_DIRENT_TAIL(be, block_size));\n        ext4_dir_set_csum(dir, be);\n    } else {\n        ext4_dir_en_set_entry_len(be, block_size);\n    }\n\n    ext4_dir_en_set_inode(be, 0);\n\n    ext4_trans_set_block_dirty(new_block.buf);\n    rc = ext4_block_set(dir->fs->bdev, &new_block);\n    if (rc != EOK) {\n        ext4_block_set(dir->fs->bdev, &block);\n        return rc;\n    }\n\n    /* Connect new block to the only entry in index */\n    struct ext4_dir_idx_entry *entry = root->en;\n    ext4_dir_dx_entry_set_block(entry, iblock);\n\n    ext4_dir_set_dx_csum(dir, (struct ext4_dir_en *)block.data);\n    ext4_trans_set_block_dirty(block.buf);\n\n    return ext4_block_set(dir->fs->bdev, &block);\n}\n\n/**@brief Initialize hash info structure necessary for index operations.\n * @param hinfo      Pointer to hinfo to be initialized\n * @param root_block Root block (number 0) of index\n * @param sb         Pointer to superblock\n * @param name_len   Length of name to be computed hash value from\n * @param name       Name to be computed hash value from\n * @return Standard error code\n */\nstatic int ext4_dir_hinfo_init(struct ext4_hash_info *hinfo,\n                   struct ext4_block *root_block,\n                   struct ext4_sblock *sb, size_t name_len,\n                   const char *name)\n{\n    struct ext4_dir_idx_root *root;\n\n    root = (struct ext4_dir_idx_root *)root_block->data;\n    if ((root->info.hash_version != EXT2_HTREE_LEGACY) &&\n        (root->info.hash_version != EXT2_HTREE_HALF_MD4) &&\n        (root->info.hash_version != EXT2_HTREE_TEA))\n        return EXT4_ERR_BAD_DX_DIR;\n\n    /* Check unused flags */\n    if (root->info.unused_flags != 0)\n        return EXT4_ERR_BAD_DX_DIR;\n\n    /* Check indirect levels */\n    if (root->info.indirect_levels > 1)\n        return EXT4_ERR_BAD_DX_DIR;\n\n    /* Check if node limit is correct */\n    uint32_t block_size = ext4_sb_get_block_size(sb);\n    uint32_t entry_space = block_size;\n    entry_space -= 2 * sizeof(struct ext4_dir_idx_dot_en);\n    entry_space -= sizeof(struct ext4_dir_idx_rinfo);\n    if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM))\n        entry_space -= sizeof(struct ext4_dir_idx_tail);\n    entry_space = entry_space / sizeof(struct ext4_dir_idx_entry);\n\n    struct ext4_dir_idx_climit *climit = (void *)&root->en;\n    uint16_t limit = ext4_dir_dx_climit_get_limit(climit);\n    if (limit != entry_space)\n        return EXT4_ERR_BAD_DX_DIR;\n\n    /* Check hash version and modify if necessary */\n    hinfo->hash_version = ext4_dir_dx_rinfo_get_hash_version(&root->info);\n    if ((hinfo->hash_version <= EXT2_HTREE_TEA) &&\n        (ext4_sb_check_flag(sb, EXT4_SUPERBLOCK_FLAGS_UNSIGNED_HASH))) {\n        /* Use unsigned hash */\n        hinfo->hash_version += 3;\n    }\n\n    /* Load hash seed from superblock */\n    hinfo->seed = ext4_get8(sb, hash_seed);\n\n    /* Compute hash value of name */\n    if (name)\n        return ext4_dir_dx_hash_string(hinfo, name_len, name);\n\n    return EOK;\n}\n\n/**@brief Walk through index tree and load leaf with corresponding hash value.\n * @param hinfo      Initialized hash info structure\n * @param inode_ref  Current i-node\n * @param root_block Root block (iblock 0), where is root node located\n * @param dx_block   Pointer to leaf node in dx_blocks array\n * @param dx_blocks  Array with the whole path from root to leaf\n * @return Standard error code\n */\nstatic int ext4_dir_dx_get_leaf(struct ext4_hash_info *hinfo,\n                struct ext4_inode_ref *inode_ref,\n                struct ext4_block *root_block,\n                struct ext4_dir_idx_block **dx_block,\n                struct ext4_dir_idx_block *dx_blocks)\n{\n    struct ext4_dir_idx_root *root;\n    struct ext4_dir_idx_entry *entries;\n    struct ext4_dir_idx_entry *p;\n    struct ext4_dir_idx_entry *q;\n    struct ext4_dir_idx_entry *m;\n    struct ext4_dir_idx_entry *at;\n    ext4_fsblk_t fblk;\n    uint32_t block_size;\n    uint16_t limit;\n    uint16_t entry_space;\n    uint8_t ind_level;\n    int r;\n\n    struct ext4_dir_idx_block *tmp_dx_blk = dx_blocks;\n    struct ext4_block *tmp_blk = root_block;\n    struct ext4_sblock *sb = &inode_ref->fs->sb;\n\n    block_size = ext4_sb_get_block_size(sb);\n    root = (struct ext4_dir_idx_root *)root_block->data;\n    entries = (struct ext4_dir_idx_entry *)&root->en;\n    limit = ext4_dir_dx_climit_get_limit((void *)entries);\n    ind_level = ext4_dir_dx_rinfo_get_indirect_levels(&root->info);\n\n    /* Walk through the index tree */\n    while (true) {\n        uint16_t cnt = ext4_dir_dx_climit_get_count((void *)entries);\n        if ((cnt == 0) || (cnt > limit))\n            return EXT4_ERR_BAD_DX_DIR;\n\n        /* Do binary search in every node */\n        p = entries + 1;\n        q = entries + cnt - 1;\n\n        while (p <= q) {\n            m = p + (q - p) / 2;\n            if (ext4_dir_dx_entry_get_hash(m) > hinfo->hash)\n                q = m - 1;\n            else\n                p = m + 1;\n        }\n\n        at = p - 1;\n\n        /* Write results */\n        memcpy(&tmp_dx_blk->b, tmp_blk, sizeof(struct ext4_block));\n        tmp_dx_blk->entries = entries;\n        tmp_dx_blk->position = at;\n\n        /* Is algorithm in the leaf? */\n        if (ind_level == 0) {\n            *dx_block = tmp_dx_blk;\n            return EOK;\n        }\n\n        /* Goto child node */\n        uint32_t n_blk = ext4_dir_dx_entry_get_block(at);\n\n        ind_level--;\n\n        r = ext4_fs_get_inode_dblk_idx(inode_ref, n_blk, &fblk, false);\n        if (r != EOK)\n            return r;\n\n        r = ext4_trans_block_get(inode_ref->fs->bdev, tmp_blk, fblk);\n        if (r != EOK)\n            return r;\n\n        entries = ((struct ext4_dir_idx_node *)tmp_blk->data)->entries;\n        limit = ext4_dir_dx_climit_get_limit((void *)entries);\n\n        entry_space = block_size - sizeof(struct ext4_fake_dir_entry);\n        if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM))\n            entry_space -= sizeof(struct ext4_dir_idx_tail);\n\n        entry_space = entry_space / sizeof(struct ext4_dir_idx_entry);\n\n        if (limit != entry_space) {\n            ext4_block_set(inode_ref->fs->bdev, tmp_blk);\n            return EXT4_ERR_BAD_DX_DIR;\n        }\n\n        if (!ext4_dir_dx_csum_verify(inode_ref, (void *)tmp_blk->data)) {\n            ext4_dbg(DEBUG_DIR_IDX,\n                    DBG_WARN \"HTree checksum failed.\"\n                    \"Inode: %\" PRIu32\", \"\n                    \"Block: %\" PRIu32\"\\n\",\n                    inode_ref->index,\n                    n_blk);\n        }\n\n        ++tmp_dx_blk;\n    }\n\n    /* Unreachable */\n    return EOK;\n}\n\n/**@brief Check if the the next block would be checked during entry search.\n * @param inode_ref Directory i-node\n * @param hash      Hash value to check\n * @param dx_block  Current block\n * @param dx_blocks Array with path from root to leaf node\n * @return Standard Error code\n */\nstatic int ext4_dir_dx_next_block(struct ext4_inode_ref *inode_ref,\n                  uint32_t hash,\n                  struct ext4_dir_idx_block *dx_block,\n                  struct ext4_dir_idx_block *dx_blocks)\n{\n    int r;\n    uint32_t num_handles = 0;\n    ext4_fsblk_t blk_adr;\n    struct ext4_dir_idx_block *p = dx_block;\n\n    /* Try to find data block with next bunch of entries */\n    while (true) {\n        uint16_t cnt = ext4_dir_dx_climit_get_count((void *)p->entries);\n\n        p->position++;\n        if (p->position < p->entries + cnt)\n            break;\n\n        if (p == dx_blocks)\n            return EOK;\n\n        num_handles++;\n        p--;\n    }\n\n    /* Check hash collision (if not occurred - no next block cannot be\n     * used)*/\n    uint32_t current_hash = ext4_dir_dx_entry_get_hash(p->position);\n    if ((hash & 1) == 0) {\n        if ((current_hash & ~1) != hash)\n            return 0;\n    }\n\n    /* Fill new path */\n    while (num_handles--) {\n        uint32_t blk = ext4_dir_dx_entry_get_block(p->position);\n        r = ext4_fs_get_inode_dblk_idx(inode_ref, blk, &blk_adr, false);\n        if (r != EOK)\n            return r;\n\n        struct ext4_block b;\n        r = ext4_trans_block_get(inode_ref->fs->bdev, &b, blk_adr);\n        if (r != EOK)\n            return r;\n\n        if (!ext4_dir_dx_csum_verify(inode_ref, (void *)b.data)) {\n            ext4_dbg(DEBUG_DIR_IDX,\n                    DBG_WARN \"HTree checksum failed.\"\n                    \"Inode: %\" PRIu32\", \"\n                    \"Block: %\" PRIu32\"\\n\",\n                    inode_ref->index,\n                    blk);\n        }\n\n        p++;\n\n        /* Don't forget to put old block (prevent memory leak) */\n        r = ext4_block_set(inode_ref->fs->bdev, &p->b);\n        if (r != EOK)\n            return r;\n\n        memcpy(&p->b, &b, sizeof(b));\n        p->entries = ((struct ext4_dir_idx_node *)b.data)->entries;\n        p->position = p->entries;\n    }\n\n    return ENOENT;\n}\n\nint ext4_dir_dx_find_entry(struct ext4_dir_search_result *result,\n               struct ext4_inode_ref *inode_ref, size_t name_len,\n               const char *name)\n{\n    /* Load direct block 0 (index root) */\n    ext4_fsblk_t root_block_addr;\n    int rc2;\n    int rc;\n    rc = ext4_fs_get_inode_dblk_idx(inode_ref,  0, &root_block_addr, false);\n    if (rc != EOK)\n        return rc;\n\n    struct ext4_fs *fs = inode_ref->fs;\n\n    struct ext4_block root_block;\n    rc = ext4_trans_block_get(fs->bdev, &root_block, root_block_addr);\n    if (rc != EOK)\n        return rc;\n\n    if (!ext4_dir_dx_csum_verify(inode_ref, (void *)root_block.data)) {\n        ext4_dbg(DEBUG_DIR_IDX,\n             DBG_WARN \"HTree root checksum failed.\"\n             \"Inode: %\" PRIu32\", \"\n             \"Block: %\" PRIu32\"\\n\",\n             inode_ref->index,\n             (uint32_t)0);\n    }\n\n    /* Initialize hash info (compute hash value) */\n    struct ext4_hash_info hinfo;\n    rc = ext4_dir_hinfo_init(&hinfo, &root_block, &fs->sb, name_len, name);\n    if (rc != EOK) {\n        ext4_block_set(fs->bdev, &root_block);\n        return EXT4_ERR_BAD_DX_DIR;\n    }\n\n    /*\n     * Hardcoded number 2 means maximum height of index tree,\n     * specified in the Linux driver.\n     */\n    struct ext4_dir_idx_block dx_blocks[2];\n    struct ext4_dir_idx_block *dx_block;\n    struct ext4_dir_idx_block *tmp;\n\n    rc = ext4_dir_dx_get_leaf(&hinfo, inode_ref, &root_block, &dx_block,\n                  dx_blocks);\n    if (rc != EOK) {\n        ext4_block_set(fs->bdev, &root_block);\n        return EXT4_ERR_BAD_DX_DIR;\n    }\n\n    do {\n        /* Load leaf block */\n        uint32_t leaf_blk_idx;\n        ext4_fsblk_t leaf_block_addr;\n        struct ext4_block b;\n\n        leaf_blk_idx = ext4_dir_dx_entry_get_block(dx_block->position);\n        rc = ext4_fs_get_inode_dblk_idx(inode_ref, leaf_blk_idx,\n                        &leaf_block_addr, false);\n        if (rc != EOK)\n            goto cleanup;\n\n        rc = ext4_trans_block_get(fs->bdev, &b, leaf_block_addr);\n        if (rc != EOK)\n            goto cleanup;\n\n        if (!ext4_dir_csum_verify(inode_ref, (void *)b.data)) {\n            ext4_dbg(DEBUG_DIR_IDX,\n                 DBG_WARN \"HTree leaf block checksum failed.\"\n                 \"Inode: %\" PRIu32\", \"\n                 \"Block: %\" PRIu32\"\\n\",\n                 inode_ref->index,\n                 leaf_blk_idx);\n        }\n\n        /* Linear search inside block */\n        struct ext4_dir_en *de;\n        rc = ext4_dir_find_in_block(&b, &fs->sb, name_len, name, &de);\n\n        /* Found => return it */\n        if (rc == EOK) {\n            result->block = b;\n            result->dentry = de;\n            goto cleanup;\n        }\n\n        /* Not found, leave untouched */\n        rc2 = ext4_block_set(fs->bdev, &b);\n        if (rc2 != EOK)\n            goto cleanup;\n\n        if (rc != ENOENT)\n            goto cleanup;\n\n        /* check if the next block could be checked */\n        rc = ext4_dir_dx_next_block(inode_ref, hinfo.hash, dx_block,\n                        &dx_blocks[0]);\n        if (rc < 0)\n            goto cleanup;\n    } while (rc == ENOENT);\n\n    /* Entry not found */\n    rc = ENOENT;\n\ncleanup:\n    /* The whole path must be released (preventing memory leak) */\n    tmp = dx_blocks;\n\n    while (tmp <= dx_block) {\n        rc2 = ext4_block_set(fs->bdev, &tmp->b);\n        if (rc == EOK && rc2 != EOK)\n            rc = rc2;\n        ++tmp;\n    }\n\n    return rc;\n}\n\n/**@brief  Compare function used to pass in quicksort implementation.\n *         It can compare two entries by hash value.\n * @param arg1  First entry\n * @param arg2  Second entry\n * @param dummy Unused parameter, can be NULL\n *\n * @return Classic compare result\n *         (0: equal, -1: arg1 < arg2, 1: arg1 > arg2)\n */\nstatic int ext4_dir_dx_entry_comparator(const void *arg1, const void *arg2)\n{\n    struct ext4_dx_sort_entry *entry1 = (void *)arg1;\n    struct ext4_dx_sort_entry *entry2 = (void *)arg2;\n\n    if (entry1->hash == entry2->hash)\n        return 0;\n\n    if (entry1->hash < entry2->hash)\n        return -1;\n    else\n        return 1;\n}\n\n/**@brief  Insert new index entry to block.\n *         Note that space for new entry must be checked by caller.\n * @param inode_ref   Directory i-node\n * @param index_block Block where to insert new entry\n * @param hash        Hash value covered by child node\n * @param iblock      Logical number of child block\n *\n */\nstatic void\next4_dir_dx_insert_entry(struct ext4_inode_ref *inode_ref __unused,\n             struct ext4_dir_idx_block *index_block,\n             uint32_t hash, uint32_t iblock)\n{\n    struct ext4_dir_idx_entry *old_index_entry = index_block->position;\n    struct ext4_dir_idx_entry *new_index_entry = old_index_entry + 1;\n    struct ext4_dir_idx_climit *climit = (void *)index_block->entries;\n    struct ext4_dir_idx_entry *start_index = index_block->entries;\n    uint32_t count = ext4_dir_dx_climit_get_count(climit);\n\n    size_t bytes;\n    bytes = (uint8_t *)(start_index + count) - (uint8_t *)(new_index_entry);\n\n    memmove(new_index_entry + 1, new_index_entry, bytes);\n\n    ext4_dir_dx_entry_set_block(new_index_entry, iblock);\n    ext4_dir_dx_entry_set_hash(new_index_entry, hash);\n    ext4_dir_dx_climit_set_count(climit, count + 1);\n    ext4_dir_set_dx_csum(inode_ref, (void *)index_block->b.data);\n    ext4_trans_set_block_dirty(index_block->b.buf);\n}\n\n/**@brief Split directory entries to two parts preventing node overflow.\n * @param inode_ref      Directory i-node\n * @param hinfo          Hash info\n * @param old_data_block Block with data to be split\n * @param index_block    Block where index entries are located\n * @param new_data_block Output value for newly allocated data block\n */\nstatic int ext4_dir_dx_split_data(struct ext4_inode_ref *inode_ref,\n                  struct ext4_hash_info *hinfo,\n                  struct ext4_block *old_data_block,\n                  struct ext4_dir_idx_block *index_block,\n                  struct ext4_block *new_data_block)\n{\n    int rc = EOK;\n    struct ext4_sblock *sb = &inode_ref->fs->sb;\n    uint32_t block_size = ext4_sb_get_block_size(&inode_ref->fs->sb);\n\n    /* Allocate buffer for directory entries */\n    uint8_t *entry_buffer = ext4_malloc(block_size);\n    if (entry_buffer == NULL)\n        return ENOMEM;\n\n    /* dot entry has the smallest size available */\n    uint32_t max_ecnt = block_size / sizeof(struct ext4_dir_idx_dot_en);\n\n    /* Allocate sort entry */\n    struct ext4_dx_sort_entry *sort;\n\n    sort = ext4_malloc(max_ecnt * sizeof(struct ext4_dx_sort_entry));\n    if (sort == NULL) {\n        ext4_free(entry_buffer);\n        return ENOMEM;\n    }\n\n    uint32_t idx = 0;\n    uint32_t real_size = 0;\n\n    /* Initialize hinfo */\n    struct ext4_hash_info hinfo_tmp;\n    memcpy(&hinfo_tmp, hinfo, sizeof(struct ext4_hash_info));\n\n    /* Load all valid entries to the buffer */\n    struct ext4_dir_en *de = (void *)old_data_block->data;\n    uint8_t *entry_buffer_ptr = entry_buffer;\n    while ((void *)de < (void *)(old_data_block->data + block_size)) {\n        /* Read only valid entries */\n        if (ext4_dir_en_get_inode(de) && de->name_len) {\n            uint16_t len = ext4_dir_en_get_name_len(sb, de);\n            rc = ext4_dir_dx_hash_string(&hinfo_tmp, len,\n                             (char *)de->name);\n            if (rc != EOK) {\n                ext4_free(sort);\n                ext4_free(entry_buffer);\n                return rc;\n            }\n\n            uint32_t rec_len = 8 + len;\n            if ((rec_len % 4) != 0)\n                rec_len += 4 - (rec_len % 4);\n\n            memcpy(entry_buffer_ptr, de, rec_len);\n\n            sort[idx].dentry = entry_buffer_ptr;\n            sort[idx].rec_len = rec_len;\n            sort[idx].hash = hinfo_tmp.hash;\n\n            entry_buffer_ptr += rec_len;\n            real_size += rec_len;\n            idx++;\n        }\n\n        size_t elen = ext4_dir_en_get_entry_len(de);\n        de = (void *)((uint8_t *)de + elen);\n    }\n\n    qsort(sort, idx, sizeof(struct ext4_dx_sort_entry),\n          ext4_dir_dx_entry_comparator);\n\n    /* Allocate new block for store the second part of entries */\n    ext4_fsblk_t new_fblock;\n    uint32_t new_iblock;\n    rc = ext4_fs_append_inode_dblk(inode_ref, &new_fblock, &new_iblock);\n    if (rc != EOK) {\n        ext4_free(sort);\n        ext4_free(entry_buffer);\n        return rc;\n    }\n\n    /* Load new block */\n    struct ext4_block new_data_block_tmp;\n    rc = ext4_trans_block_get_noread(inode_ref->fs->bdev, &new_data_block_tmp,\n                   new_fblock);\n    if (rc != EOK) {\n        ext4_free(sort);\n        ext4_free(entry_buffer);\n        return rc;\n    }\n\n    /*\n     * Distribute entries to two blocks (by size)\n     * - compute the half\n     */\n    uint32_t new_hash = 0;\n    uint32_t current_size = 0;\n    uint32_t mid = 0;\n    uint32_t i;\n    for (i = 0; i < idx; ++i) {\n        if ((current_size + sort[i].rec_len) > (block_size / 2)) {\n            new_hash = sort[i].hash;\n            mid = i;\n            break;\n        }\n\n        current_size += sort[i].rec_len;\n    }\n\n    /* Check hash collision */\n    uint32_t continued = 0;\n    if (new_hash == sort[mid - 1].hash)\n        continued = 1;\n\n    uint32_t off = 0;\n    void *ptr;\n    if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM))\n        block_size -= sizeof(struct ext4_dir_entry_tail);\n\n    /* First part - to the old block */\n    for (i = 0; i < mid; ++i) {\n        ptr = old_data_block->data + off;\n        memcpy(ptr, sort[i].dentry, sort[i].rec_len);\n\n        struct ext4_dir_en *t = ptr;\n        if (i < (mid - 1))\n            ext4_dir_en_set_entry_len(t, sort[i].rec_len);\n        else\n            ext4_dir_en_set_entry_len(t, block_size - off);\n\n        off += sort[i].rec_len;\n    }\n\n    /* Second part - to the new block */\n    off = 0;\n    for (i = mid; i < idx; ++i) {\n        ptr = new_data_block_tmp.data + off;\n        memcpy(ptr, sort[i].dentry, sort[i].rec_len);\n\n        struct ext4_dir_en *t = ptr;\n        if (i < (idx - 1))\n            ext4_dir_en_set_entry_len(t, sort[i].rec_len);\n        else\n            ext4_dir_en_set_entry_len(t, block_size - off);\n\n        off += sort[i].rec_len;\n    }\n\n    block_size = ext4_sb_get_block_size(&inode_ref->fs->sb);\n\n    /* Do some steps to finish operation */\n    sb = &inode_ref->fs->sb;\n    if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) {\n        struct ext4_dir_entry_tail *t;\n\n        t = EXT4_DIRENT_TAIL(old_data_block->data, block_size);\n        ext4_dir_init_entry_tail(t);\n        t = EXT4_DIRENT_TAIL(new_data_block_tmp.data, block_size);\n        ext4_dir_init_entry_tail(t);\n    }\n    ext4_dir_set_csum(inode_ref, (void *)old_data_block->data);\n    ext4_dir_set_csum(inode_ref, (void *)new_data_block_tmp.data);\n    ext4_trans_set_block_dirty(old_data_block->buf);\n    ext4_trans_set_block_dirty(new_data_block_tmp.buf);\n\n    ext4_free(sort);\n    ext4_free(entry_buffer);\n\n    ext4_dir_dx_insert_entry(inode_ref, index_block, new_hash + continued,\n                new_iblock);\n\n    *new_data_block = new_data_block_tmp;\n    return EOK;\n}\n\n/**@brief  Split index node and maybe some parent nodes in the tree hierarchy.\n * @param inode_ref Directory i-node\n * @param dx_blocks Array with path from root to leaf node\n * @param dx_block  Leaf block to be split if needed\n * @return Error code\n */\nstatic int\next4_dir_dx_split_index(struct ext4_inode_ref *ino_ref,\n            struct ext4_dir_idx_block *dx_blks,\n            struct ext4_dir_idx_block *dxb,\n            struct ext4_dir_idx_block **new_dx_block)\n{\n    struct ext4_sblock *sb = &ino_ref->fs->sb;\n    struct ext4_dir_idx_entry *e;\n    int r;\n\n    uint32_t block_size = ext4_sb_get_block_size(&ino_ref->fs->sb);\n    uint32_t entry_space = block_size - sizeof(struct ext4_fake_dir_entry);\n    uint32_t node_limit =  entry_space / sizeof(struct ext4_dir_idx_entry);\n\n    bool meta_csum = ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM);\n\n    if (dxb == dx_blks)\n        e = ((struct ext4_dir_idx_root *)dxb->b.data)->en;\n    else\n        e = ((struct ext4_dir_idx_node *)dxb->b.data)->entries;\n\n    struct ext4_dir_idx_climit *climit = (struct ext4_dir_idx_climit *)e;\n\n    uint16_t leaf_limit = ext4_dir_dx_climit_get_limit(climit);\n    uint16_t leaf_count = ext4_dir_dx_climit_get_count(climit);\n\n    /* Check if is necessary to split index block */\n    if (leaf_limit == leaf_count) {\n        struct ext4_dir_idx_entry *ren;\n        ptrdiff_t levels = dxb - dx_blks;\n\n        ren = ((struct ext4_dir_idx_root *)dx_blks[0].b.data)->en;\n        struct ext4_dir_idx_climit *rclimit = (void *)ren;\n        uint16_t root_limit = ext4_dir_dx_climit_get_limit(rclimit);\n        uint16_t root_count = ext4_dir_dx_climit_get_count(rclimit);\n\n\n        /* Linux limitation */\n        if ((levels > 0) && (root_limit == root_count))\n            return ENOSPC;\n\n        /* Add new block to directory */\n        ext4_fsblk_t new_fblk;\n        uint32_t new_iblk;\n        r = ext4_fs_append_inode_dblk(ino_ref, &new_fblk, &new_iblk);\n        if (r != EOK)\n            return r;\n\n        /* load new block */\n        struct ext4_block b;\n        r = ext4_trans_block_get_noread(ino_ref->fs->bdev, &b, new_fblk);\n        if (r != EOK)\n            return r;\n\n        struct ext4_dir_idx_node *new_node = (void *)b.data;\n        struct ext4_dir_idx_entry *new_en = new_node->entries;\n\n        memset(&new_node->fake, 0, sizeof(struct ext4_fake_dir_entry));\n        new_node->fake.entry_length = block_size;\n\n        /* Split leaf node */\n        if (levels > 0) {\n            uint32_t count_left = leaf_count / 2;\n            uint32_t count_right = leaf_count - count_left;\n            uint32_t hash_right;\n            size_t sz;\n\n            struct ext4_dir_idx_climit *left_climit;\n            struct ext4_dir_idx_climit *right_climit;\n\n            hash_right = ext4_dir_dx_entry_get_hash(e + count_left);\n            /* Copy data to new node */\n            sz = count_right * sizeof(struct ext4_dir_idx_entry);\n            memcpy(new_en, e + count_left, sz);\n\n            /* Initialize new node */\n            left_climit = (struct ext4_dir_idx_climit *)e;\n            right_climit = (struct ext4_dir_idx_climit *)new_en;\n\n            ext4_dir_dx_climit_set_count(left_climit, count_left);\n            ext4_dir_dx_climit_set_count(right_climit, count_right);\n\n            if (meta_csum)\n                entry_space -= sizeof(struct ext4_dir_idx_tail);\n\n            ext4_dir_dx_climit_set_limit(right_climit, node_limit);\n\n            /* Which index block is target for new entry */\n            uint32_t position_index =\n                (dxb->position - dxb->entries);\n            if (position_index >= count_left) {\n                ext4_dir_set_dx_csum(\n                        ino_ref,\n                        (struct ext4_dir_en *)\n                        dxb->b.data);\n                ext4_trans_set_block_dirty(dxb->b.buf);\n\n                struct ext4_block block_tmp = dxb->b;\n\n                dxb->b = b;\n\n                dxb->position =\n                    new_en + position_index - count_left;\n                dxb->entries = new_en;\n\n                b = block_tmp;\n            }\n\n            /* Finally insert new entry */\n            ext4_dir_dx_insert_entry(ino_ref, dx_blks, hash_right,\n                         new_iblk);\n            ext4_dir_set_dx_csum(ino_ref, (void*)dx_blks[0].b.data);\n            ext4_dir_set_dx_csum(ino_ref, (void*)dx_blks[1].b.data);\n            ext4_trans_set_block_dirty(dx_blks[0].b.buf);\n            ext4_trans_set_block_dirty(dx_blks[1].b.buf);\n\n            ext4_dir_set_dx_csum(ino_ref, (void *)b.data);\n            ext4_trans_set_block_dirty(b.buf);\n            return ext4_block_set(ino_ref->fs->bdev, &b);\n        } else {\n            size_t sz;\n            /* Copy data from root to child block */\n            sz = leaf_count * sizeof(struct ext4_dir_idx_entry);\n            memcpy(new_en, e, sz);\n\n            struct ext4_dir_idx_climit *new_climit = (void*)new_en;\n            if (meta_csum)\n                entry_space -= sizeof(struct ext4_dir_idx_tail);\n\n            ext4_dir_dx_climit_set_limit(new_climit, node_limit);\n\n            /* Set values in root node */\n            struct ext4_dir_idx_climit *new_root_climit = (void *)e;\n\n            ext4_dir_dx_climit_set_count(new_root_climit, 1);\n            ext4_dir_dx_entry_set_block(e, new_iblk);\n\n            struct ext4_dir_idx_root *r = (void *)dx_blks[0].b.data;\n            r->info.indirect_levels = 1;\n\n            /* Add new entry to the path */\n            dxb = dx_blks + 1;\n            dxb->position = dx_blks->position - e + new_en;\n            dxb->entries = new_en;\n            dxb->b = b;\n            *new_dx_block = dxb;\n\n            ext4_dir_set_dx_csum(ino_ref, (void*)dx_blks[0].b.data);\n            ext4_dir_set_dx_csum(ino_ref, (void*)dx_blks[1].b.data);\n            ext4_trans_set_block_dirty(dx_blks[0].b.buf);\n            ext4_trans_set_block_dirty(dx_blks[1].b.buf);\n        }\n    }\n\n    return EOK;\n}\n\nint ext4_dir_dx_add_entry(struct ext4_inode_ref *parent,\n              struct ext4_inode_ref *child, const char *name, uint32_t name_len)\n{\n    int rc2 = EOK;\n    int r;\n    /* Get direct block 0 (index root) */\n    ext4_fsblk_t rblock_addr;\n    r =  ext4_fs_get_inode_dblk_idx(parent, 0, &rblock_addr, false);\n    if (r != EOK)\n        return r;\n\n    struct ext4_fs *fs = parent->fs;\n    struct ext4_block root_blk;\n\n    r = ext4_trans_block_get(fs->bdev, &root_blk, rblock_addr);\n    if (r != EOK)\n        return r;\n\n    if (!ext4_dir_dx_csum_verify(parent, (void*)root_blk.data)) {\n        ext4_dbg(DEBUG_DIR_IDX,\n             DBG_WARN \"HTree root checksum failed.\"\n             \"Inode: %\" PRIu32\", \"\n             \"Block: %\" PRIu32\"\\n\",\n             parent->index,\n             (uint32_t)0);\n    }\n\n    /* Initialize hinfo structure (mainly compute hash) */\n    struct ext4_hash_info hinfo;\n    r = ext4_dir_hinfo_init(&hinfo, &root_blk, &fs->sb, name_len, name);\n    if (r != EOK) {\n        ext4_block_set(fs->bdev, &root_blk);\n        return EXT4_ERR_BAD_DX_DIR;\n    }\n\n    /*\n     * Hardcoded number 2 means maximum height of index\n     * tree defined in Linux.\n     */\n    struct ext4_dir_idx_block dx_blks[2];\n    struct ext4_dir_idx_block *dx_blk;\n    struct ext4_dir_idx_block *dx_it;\n\n    r = ext4_dir_dx_get_leaf(&hinfo, parent, &root_blk, &dx_blk, dx_blks);\n    if (r != EOK) {\n        r = EXT4_ERR_BAD_DX_DIR;\n        goto release_index;\n    }\n\n    /* Try to insert to existing data block */\n    uint32_t leaf_block_idx = ext4_dir_dx_entry_get_block(dx_blk->position);\n    ext4_fsblk_t leaf_block_addr;\n    r = ext4_fs_get_inode_dblk_idx(parent, leaf_block_idx,\n                        &leaf_block_addr, false);\n    if (r != EOK)\n        goto release_index;\n\n    /*\n     * Check if there is needed to split index node\n     * (and recursively also parent nodes)\n     */\n    r = ext4_dir_dx_split_index(parent, dx_blks, dx_blk, &dx_blk);\n    if (r != EOK)\n        goto release_target_index;\n\n    struct ext4_block target_block;\n    r = ext4_trans_block_get(fs->bdev, &target_block, leaf_block_addr);\n    if (r != EOK)\n        goto release_index;\n\n    if (!ext4_dir_csum_verify(parent,(void *)target_block.data)) {\n        ext4_dbg(DEBUG_DIR_IDX,\n                DBG_WARN \"HTree leaf block checksum failed.\"\n                \"Inode: %\" PRIu32\", \"\n                \"Block: %\" PRIu32\"\\n\",\n                parent->index,\n                leaf_block_idx);\n    }\n\n    /* Check if insert operation passed */\n    r = ext4_dir_try_insert_entry(&fs->sb, parent, &target_block, child,\n                    name, name_len);\n    if (r == EOK)\n        goto release_target_index;\n\n    /* Split entries to two blocks (includes sorting by hash value) */\n    struct ext4_block new_block;\n    r = ext4_dir_dx_split_data(parent, &hinfo, &target_block, dx_blk,\n                    &new_block);\n    if (r != EOK) {\n        rc2 = r;\n        goto release_target_index;\n    }\n\n    /* Where to save new entry */\n    uint32_t blk_hash = ext4_dir_dx_entry_get_hash(dx_blk->position + 1);\n    if (hinfo.hash >= blk_hash)\n        r = ext4_dir_try_insert_entry(&fs->sb, parent, &new_block,\n                        child, name, name_len);\n    else\n        r = ext4_dir_try_insert_entry(&fs->sb, parent, &target_block,\n                        child, name, name_len);\n\n    /* Cleanup */\n    r = ext4_block_set(fs->bdev, &new_block);\n    if (r != EOK)\n        return r;\n\n/* Cleanup operations */\n\nrelease_target_index:\n    rc2 = r;\n\n    r = ext4_block_set(fs->bdev, &target_block);\n    if (r != EOK)\n        return r;\n\nrelease_index:\n    if (r != EOK)\n        rc2 = r;\n\n    dx_it = dx_blks;\n\n    while (dx_it <= dx_blk) {\n        r = ext4_block_set(fs->bdev, &dx_it->b);\n        if (r != EOK)\n            return r;\n\n        dx_it++;\n    }\n\n    return rc2;\n}\n\nint ext4_dir_dx_reset_parent_inode(struct ext4_inode_ref *dir,\n                                   uint32_t parent_inode)\n{\n    /* Load block 0, where will be index root located */\n    ext4_fsblk_t fblock;\n    int rc = ext4_fs_get_inode_dblk_idx(dir, 0, &fblock, false);\n    if (rc != EOK)\n        return rc;\n\n    struct ext4_block block;\n    rc = ext4_trans_block_get(dir->fs->bdev, &block, fblock);\n    if (rc != EOK)\n        return rc;\n\n    if (!ext4_dir_dx_csum_verify(dir, (void *)block.data)) {\n        ext4_dbg(DEBUG_DIR_IDX,\n             DBG_WARN \"HTree root checksum failed.\"\n             \"Inode: %\" PRIu32\", \"\n             \"Block: %\" PRIu32\"\\n\",\n             dir->index,\n             (uint32_t)0);\n    }\n\n    /* Initialize pointers to data structures */\n    struct ext4_dir_idx_root *root = (void *)block.data;\n\n    /* Fill the inode field with a new parent ino. */\n    ext4_dx_dot_en_set_inode(&root->dots[1], parent_inode);\n\n    ext4_dir_set_dx_csum(dir, (void *)block.data);\n    ext4_trans_set_block_dirty(block.buf);\n\n    return ext4_block_set(dir->fs->bdev, &block);\n}\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/src/ext4_extent.c",
    "content": "/*\n * Copyright (c) 2017 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * Copyright (c) 2017 Kaho Ng (ngkaho1234@gmail.com)\n *\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; either version 2\n * of the License, or (at your option) any later version.\n */\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_misc.h>\n#include <ext4_errno.h>\n#include <ext4_debug.h>\n\n#include <ext4_blockdev.h>\n#include <ext4_trans.h>\n#include <ext4_fs.h>\n#include <ext4_super.h>\n#include <ext4_crc32.h>\n#include <ext4_balloc.h>\n#include <ext4_extent.h>\n\n#include <stdlib.h>\n#include <string.h>\n#include <inttypes.h>\n#include <stddef.h>\n\n#if CONFIG_EXTENTS_ENABLE\n/*\n * used by extent splitting.\n */\n#define EXT4_EXT_MARK_UNWRIT1 0x02 /* mark first half unwritten */\n#define EXT4_EXT_MARK_UNWRIT2 0x04 /* mark second half unwritten */\n#define EXT4_EXT_DATA_VALID1 0x08  /* first half contains valid data */\n#define EXT4_EXT_DATA_VALID2 0x10  /* second half contains valid data */\n#define EXT4_EXT_NO_COMBINE 0x20   /* do not combine two extents */\n\n#define EXT4_EXT_UNWRITTEN_MASK (1L << 15)\n\n#define EXT4_EXT_MAX_LEN_WRITTEN (1L << 15)\n#define EXT4_EXT_MAX_LEN_UNWRITTEN \\\n    (EXT4_EXT_MAX_LEN_WRITTEN - 1)\n\n#define EXT4_EXT_GET_LEN(ex) to_le16((ex)->block_count)\n#define EXT4_EXT_GET_LEN_UNWRITTEN(ex) \\\n    (EXT4_EXT_GET_LEN(ex) & ~(EXT4_EXT_UNWRITTEN_MASK))\n#define EXT4_EXT_SET_LEN(ex, count) \\\n    ((ex)->block_count = to_le16(count))\n\n#define EXT4_EXT_IS_UNWRITTEN(ex) \\\n    (EXT4_EXT_GET_LEN(ex) > EXT4_EXT_MAX_LEN_WRITTEN)\n#define EXT4_EXT_SET_UNWRITTEN(ex) \\\n    ((ex)->block_count |= to_le16(EXT4_EXT_UNWRITTEN_MASK))\n#define EXT4_EXT_SET_WRITTEN(ex) \\\n    ((ex)->block_count &= ~(to_le16(EXT4_EXT_UNWRITTEN_MASK)))\n\n/*\n * Array of ext4_ext_path contains path to some extent.\n * Creation/lookup routines use it for traversal/splitting/etc.\n * Truncate uses it to simulate recursive walking.\n */\nstruct ext4_extent_path {\n    ext4_fsblk_t p_block;\n    struct ext4_block block;\n    int32_t depth;\n    int32_t maxdepth;\n    struct ext4_extent_header *header;\n    struct ext4_extent_index *index;\n    struct ext4_extent *extent;\n};\n\n\n#pragma pack(push, 1)\n\n/*\n * This is the extent tail on-disk structure.\n * All other extent structures are 12 bytes long.  It turns out that\n * block_size % 12 >= 4 for at least all powers of 2 greater than 512, which\n * covers all valid ext4 block sizes.  Therefore, this tail structure can be\n * crammed into the end of the block without having to rebalance the tree.\n */\nstruct ext4_extent_tail\n{\n    uint32_t et_checksum; /* crc32c(uuid+inum+extent_block) */\n};\n\n/*\n * This is the extent on-disk structure.\n * It's used at the bottom of the tree.\n */\nstruct ext4_extent {\n    uint32_t first_block; /* First logical block extent covers */\n    uint16_t block_count; /* Number of blocks covered by extent */\n    uint16_t start_hi;    /* High 16 bits of physical block */\n    uint32_t start_lo;    /* Low 32 bits of physical block */\n};\n\n/*\n * This is index on-disk structure.\n * It's used at all the levels except the bottom.\n */\nstruct ext4_extent_index {\n    uint32_t first_block; /* Index covers logical blocks from 'block' */\n\n    /**\n     * Pointer to the physical block of the next\n     * level. leaf or next index could be there\n     * high 16 bits of physical block\n     */\n    uint32_t leaf_lo;\n    uint16_t leaf_hi;\n    uint16_t padding;\n};\n\n/*\n * Each block (leaves and indexes), even inode-stored has header.\n */\nstruct ext4_extent_header {\n    uint16_t magic;\n    uint16_t entries_count;     /* Number of valid entries */\n    uint16_t max_entries_count; /* Capacity of store in entries */\n    uint16_t depth;             /* Has tree real underlying blocks? */\n    uint32_t generation;    /* generation of the tree */\n};\n\n#pragma pack(pop)\n\n\n#define EXT4_EXTENT_MAGIC 0xF30A\n\n#define EXT4_EXTENT_FIRST(header)                                              \\\n    ((struct ext4_extent *)(((char *)(header)) +                           \\\n                sizeof(struct ext4_extent_header)))\n\n#define EXT4_EXTENT_FIRST_INDEX(header)                                        \\\n    ((struct ext4_extent_index *)(((char *)(header)) +                     \\\n                      sizeof(struct ext4_extent_header)))\n\n/*\n * EXT_INIT_MAX_LEN is the maximum number of blocks we can have in an\n * initialized extent. This is 2^15 and not (2^16 - 1), since we use the\n * MSB of ee_len field in the extent datastructure to signify if this\n * particular extent is an initialized extent or an uninitialized (i.e.\n * preallocated).\n * EXT_UNINIT_MAX_LEN is the maximum number of blocks we can have in an\n * uninitialized extent.\n * If ee_len is <= 0x8000, it is an initialized extent. Otherwise, it is an\n * uninitialized one. In other words, if MSB of ee_len is set, it is an\n * uninitialized extent with only one special scenario when ee_len = 0x8000.\n * In this case we can not have an uninitialized extent of zero length and\n * thus we make it as a special case of initialized extent with 0x8000 length.\n * This way we get better extent-to-group alignment for initialized extents.\n * Hence, the maximum number of blocks we can have in an *initialized*\n * extent is 2^15 (32768) and in an *uninitialized* extent is 2^15-1 (32767).\n */\n#define EXT_INIT_MAX_LEN (1L << 15)\n#define EXT_UNWRITTEN_MAX_LEN (EXT_INIT_MAX_LEN - 1)\n\n#define EXT_EXTENT_SIZE sizeof(struct ext4_extent)\n#define EXT_INDEX_SIZE sizeof(struct ext4_extent_idx)\n\n#define EXT_FIRST_EXTENT(__hdr__)                                              \\\n    ((struct ext4_extent *)(((char *)(__hdr__)) +                          \\\n                sizeof(struct ext4_extent_header)))\n#define EXT_FIRST_INDEX(__hdr__)                                               \\\n    ((struct ext4_extent_index *)(((char *)(__hdr__)) +                    \\\n                    sizeof(struct ext4_extent_header)))\n#define EXT_HAS_FREE_INDEX(__path__)                                           \\\n    (to_le16((__path__)->header->entries_count) <                                \\\n                    to_le16((__path__)->header->max_entries_count))\n#define EXT_LAST_EXTENT(__hdr__)                                               \\\n    (EXT_FIRST_EXTENT((__hdr__)) + to_le16((__hdr__)->entries_count) - 1)\n#define EXT_LAST_INDEX(__hdr__)                                                \\\n    (EXT_FIRST_INDEX((__hdr__)) + to_le16((__hdr__)->entries_count) - 1)\n#define EXT_MAX_EXTENT(__hdr__)                                                \\\n    (EXT_FIRST_EXTENT((__hdr__)) + to_le16((__hdr__)->max_entries_count) - 1)\n#define EXT_MAX_INDEX(__hdr__)                                                 \\\n    (EXT_FIRST_INDEX((__hdr__)) + to_le16((__hdr__)->max_entries_count) - 1)\n\n#define EXT4_EXTENT_TAIL_OFFSET(hdr)                                           \\\n    (sizeof(struct ext4_extent_header) +                                   \\\n     (sizeof(struct ext4_extent) * to_le16((hdr)->max_entries_count)))\n\n\n/**@brief Get logical number of the block covered by extent.\n * @param extent Extent to load number from\n * @return Logical number of the first block covered by extent */\nstatic inline uint32_t ext4_extent_get_first_block(struct ext4_extent *extent)\n{\n    return to_le32(extent->first_block);\n}\n\n/**@brief Set logical number of the first block covered by extent.\n * @param extent Extent to set number to\n * @param iblock Logical number of the first block covered by extent */\nstatic inline void ext4_extent_set_first_block(struct ext4_extent *extent,\n        uint32_t iblock)\n{\n    extent->first_block = to_le32(iblock);\n}\n\n/**@brief Get number of blocks covered by extent.\n * @param extent Extent to load count from\n * @return Number of blocks covered by extent */\nstatic inline uint16_t ext4_extent_get_block_count(struct ext4_extent *extent)\n{\n    if (EXT4_EXT_IS_UNWRITTEN(extent))\n        return EXT4_EXT_GET_LEN_UNWRITTEN(extent);\n    else\n        return EXT4_EXT_GET_LEN(extent);\n}\n/**@brief Set number of blocks covered by extent.\n * @param extent Extent to load count from\n * @param count  Number of blocks covered by extent\n * @param unwritten Whether the extent is unwritten or not */\nstatic inline void ext4_extent_set_block_count(struct ext4_extent *extent,\n                           uint16_t count, bool unwritten)\n{\n    EXT4_EXT_SET_LEN(extent, count);\n    if (unwritten)\n        EXT4_EXT_SET_UNWRITTEN(extent);\n}\n\n/**@brief Get physical number of the first block covered by extent.\n * @param extent Extent to load number\n * @return Physical number of the first block covered by extent */\nstatic inline uint64_t ext4_extent_get_start(struct ext4_extent *extent)\n{\n    return ((uint64_t)to_le16(extent->start_hi)) << 32 |\n           ((uint64_t)to_le32(extent->start_lo));\n}\n\n\n/**@brief Set physical number of the first block covered by extent.\n * @param extent Extent to load number\n * @param fblock Physical number of the first block covered by extent */\nstatic inline void ext4_extent_set_start(struct ext4_extent *extent, uint64_t fblock)\n{\n    extent->start_lo = to_le32((fblock << 32) >> 32);\n    extent->start_hi = to_le16((uint16_t)(fblock >> 32));\n}\n\n\n/**@brief Get logical number of the block covered by extent index.\n * @param index Extent index to load number from\n * @return Logical number of the first block covered by extent index */\nstatic inline uint32_t\next4_extent_index_get_first_block(struct ext4_extent_index *index)\n{\n    return to_le32(index->first_block);\n}\n\n/**@brief Set logical number of the block covered by extent index.\n * @param index  Extent index to set number to\n * @param iblock Logical number of the first block covered by extent index */\nstatic inline void\next4_extent_index_set_first_block(struct ext4_extent_index *index,\n                  uint32_t iblock)\n{\n    index->first_block = to_le32(iblock);\n}\n\n/**@brief Get physical number of block where the child node is located.\n * @param index Extent index to load number from\n * @return Physical number of the block with child node */\nstatic inline uint64_t\next4_extent_index_get_leaf(struct ext4_extent_index *index)\n{\n    return ((uint64_t)to_le16(index->leaf_hi)) << 32 |\n           ((uint64_t)to_le32(index->leaf_lo));\n}\n\n/**@brief Set physical number of block where the child node is located.\n * @param index  Extent index to set number to\n * @param fblock Ohysical number of the block with child node */\nstatic inline void ext4_extent_index_set_leaf(struct ext4_extent_index *index,\n                          uint64_t fblock)\n{\n    index->leaf_lo = to_le32((fblock << 32) >> 32);\n    index->leaf_hi = to_le16((uint16_t)(fblock >> 32));\n}\n\n/**@brief Get magic value from extent header.\n * @param header Extent header to load value from\n * @return Magic value of extent header */\nstatic inline uint16_t\next4_extent_header_get_magic(struct ext4_extent_header *header)\n{\n    return to_le16(header->magic);\n}\n\n/**@brief Set magic value to extent header.\n * @param header Extent header to set value to\n * @param magic  Magic value of extent header */\nstatic inline void ext4_extent_header_set_magic(struct ext4_extent_header *header,\n                        uint16_t magic)\n{\n    header->magic = to_le16(magic);\n}\n\n/**@brief Get number of entries from extent header\n * @param header Extent header to get value from\n * @return Number of entries covered by extent header */\nstatic inline uint16_t\next4_extent_header_get_entries_count(struct ext4_extent_header *header)\n{\n    return to_le16(header->entries_count);\n}\n\n/**@brief Set number of entries to extent header\n * @param header Extent header to set value to\n * @param count  Number of entries covered by extent header */\nstatic inline void\next4_extent_header_set_entries_count(struct ext4_extent_header *header,\n                     uint16_t count)\n{\n    header->entries_count = to_le16(count);\n}\n\n/**@brief Get maximum number of entries from extent header\n * @param header Extent header to get value from\n * @return Maximum number of entries covered by extent header */\nstatic inline uint16_t\next4_extent_header_get_max_entries_count(struct ext4_extent_header *header)\n{\n    return to_le16(header->max_entries_count);\n}\n\n/**@brief Set maximum number of entries to extent header\n * @param header    Extent header to set value to\n * @param max_count Maximum number of entries covered by extent header */\nstatic inline void\next4_extent_header_set_max_entries_count(struct ext4_extent_header *header,\n                          uint16_t max_count)\n{\n    header->max_entries_count = to_le16(max_count);\n}\n\n/**@brief Get depth of extent subtree.\n * @param header Extent header to get value from\n * @return Depth of extent subtree */\nstatic inline uint16_t\next4_extent_header_get_depth(struct ext4_extent_header *header)\n{\n    return to_le16(header->depth);\n}\n\n/**@brief Set depth of extent subtree.\n * @param header Extent header to set value to\n * @param depth  Depth of extent subtree */\nstatic inline void\next4_extent_header_set_depth(struct ext4_extent_header *header, uint16_t depth)\n{\n    header->depth = to_le16(depth);\n}\n\n/**@brief Get generation from extent header\n * @param header Extent header to get value from\n * @return Generation */\nstatic inline uint32_t\next4_extent_header_get_generation(struct ext4_extent_header *header)\n{\n    return to_le32(header->generation);\n}\n\n/**@brief Set generation to extent header\n * @param header     Extent header to set value to\n * @param generation Generation */\nstatic inline void\next4_extent_header_set_generation(struct ext4_extent_header *header,\n                       uint32_t generation)\n{\n    header->generation = to_le32(generation);\n}\n\nvoid ext4_extent_tree_init(struct ext4_inode_ref *inode_ref)\n{\n    /* Initialize extent root header */\n    struct ext4_extent_header *header =\n            ext4_inode_get_extent_header(inode_ref->inode);\n    ext4_extent_header_set_depth(header, 0);\n    ext4_extent_header_set_entries_count(header, 0);\n    ext4_extent_header_set_generation(header, 0);\n    ext4_extent_header_set_magic(header, EXT4_EXTENT_MAGIC);\n\n    uint16_t max_entries = (EXT4_INODE_BLOCKS * sizeof(uint32_t) -\n            sizeof(struct ext4_extent_header)) /\n                    sizeof(struct ext4_extent);\n\n    ext4_extent_header_set_max_entries_count(header, max_entries);\n    inode_ref->dirty  = true;\n}\n\n\nstatic struct ext4_extent_tail *\nfind_ext4_extent_tail(struct ext4_extent_header *eh)\n{\n    return (struct ext4_extent_tail *)(((char *)eh) +\n                       EXT4_EXTENT_TAIL_OFFSET(eh));\n}\n\nstatic struct ext4_extent_header *ext_inode_hdr(struct ext4_inode *inode)\n{\n    return (struct ext4_extent_header *)inode->blocks;\n}\n\nstatic struct ext4_extent_header *ext_block_hdr(struct ext4_block *block)\n{\n    return (struct ext4_extent_header *)block->data;\n}\n\nstatic uint16_t ext_depth(struct ext4_inode *inode)\n{\n    return to_le16(ext_inode_hdr(inode)->depth);\n}\n\nstatic uint16_t ext4_ext_get_actual_len(struct ext4_extent *ext)\n{\n    return (to_le16(ext->block_count) <= EXT_INIT_MAX_LEN\n            ? to_le16(ext->block_count)\n            : (to_le16(ext->block_count) - EXT_INIT_MAX_LEN));\n}\n\nstatic void ext4_ext_mark_initialized(struct ext4_extent *ext)\n{\n    ext->block_count = to_le16(ext4_ext_get_actual_len(ext));\n}\n\nstatic void ext4_ext_mark_unwritten(struct ext4_extent *ext)\n{\n    ext->block_count |= to_le16(EXT_INIT_MAX_LEN);\n}\n\nstatic int ext4_ext_is_unwritten(struct ext4_extent *ext)\n{\n    /* Extent with ee_len of 0x8000 is treated as an initialized extent */\n    return (to_le16(ext->block_count) > EXT_INIT_MAX_LEN);\n}\n\n/*\n * ext4_ext_pblock:\n * combine low and high parts of physical block number into ext4_fsblk_t\n */\nstatic ext4_fsblk_t ext4_ext_pblock(struct ext4_extent *ex)\n{\n    ext4_fsblk_t block;\n\n    block = to_le32(ex->start_lo);\n    block |= ((ext4_fsblk_t)to_le16(ex->start_hi) << 31) << 1;\n    return block;\n}\n\n/*\n * ext4_idx_pblock:\n * combine low and high parts of a leaf physical block number into ext4_fsblk_t\n */\nstatic ext4_fsblk_t ext4_idx_pblock(struct ext4_extent_index *ix)\n{\n    ext4_fsblk_t block;\n\n    block = to_le32(ix->leaf_lo);\n    block |= ((ext4_fsblk_t)to_le16(ix->leaf_hi) << 31) << 1;\n    return block;\n}\n\n/*\n * ext4_ext_store_pblock:\n * stores a large physical block number into an extent struct,\n * breaking it into parts\n */\nstatic void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb)\n{\n    ex->start_lo = to_le32((uint32_t)(pb & 0xffffffff));\n    ex->start_hi = to_le16((uint16_t)((pb >> 32)) & 0xffff);\n}\n\n/*\n * ext4_idx_store_pblock:\n * stores a large physical block number into an index struct,\n * breaking it into parts\n */\nstatic void ext4_idx_store_pblock(struct ext4_extent_index *ix, ext4_fsblk_t pb)\n{\n    ix->leaf_lo = to_le32((uint32_t)(pb & 0xffffffff));\n    ix->leaf_hi = to_le16((uint16_t)((pb >> 32)) & 0xffff);\n}\n\nstatic int ext4_allocate_single_block(struct ext4_inode_ref *inode_ref,\n                      ext4_fsblk_t goal, ext4_fsblk_t *blockp)\n{\n    return ext4_balloc_alloc_block(inode_ref, goal, blockp);\n}\n\nstatic ext4_fsblk_t ext4_new_meta_blocks(struct ext4_inode_ref *inode_ref,\n                     ext4_fsblk_t goal,\n                     uint32_t flags __unused,\n                     uint32_t *count, int *errp)\n{\n    ext4_fsblk_t block = 0;\n\n    *errp = ext4_allocate_single_block(inode_ref, goal, &block);\n    if (count)\n        *count = 1;\n    return block;\n}\n\nstatic void ext4_ext_free_blocks(struct ext4_inode_ref *inode_ref,\n                 ext4_fsblk_t block, uint32_t count,\n                 uint32_t flags __unused)\n{\n    ext4_balloc_free_blocks(inode_ref, block, count);\n}\n\nstatic uint16_t ext4_ext_space_block(struct ext4_inode_ref *inode_ref)\n{\n    uint16_t size;\n    uint32_t block_size = ext4_sb_get_block_size(&inode_ref->fs->sb);\n\n    size = (block_size - sizeof(struct ext4_extent_header)) /\n           sizeof(struct ext4_extent);\n#ifdef AGGRESSIVE_TEST\n    if (size > 6)\n        size = 6;\n#endif\n    return size;\n}\n\nstatic uint16_t ext4_ext_space_block_idx(struct ext4_inode_ref *inode_ref)\n{\n    uint16_t size;\n    uint32_t block_size = ext4_sb_get_block_size(&inode_ref->fs->sb);\n\n    size = (block_size - sizeof(struct ext4_extent_header)) /\n           sizeof(struct ext4_extent_index);\n#ifdef AGGRESSIVE_TEST\n    if (size > 5)\n        size = 5;\n#endif\n    return size;\n}\n\nstatic uint16_t ext4_ext_space_root(struct ext4_inode_ref *inode_ref)\n{\n    uint16_t size;\n\n    size = sizeof(inode_ref->inode->blocks);\n    size -= sizeof(struct ext4_extent_header);\n    size /= sizeof(struct ext4_extent);\n#ifdef AGGRESSIVE_TEST\n    if (size > 3)\n        size = 3;\n#endif\n    return size;\n}\n\nstatic uint16_t ext4_ext_space_root_idx(struct ext4_inode_ref *inode_ref)\n{\n    uint16_t size;\n\n    size = sizeof(inode_ref->inode->blocks);\n    size -= sizeof(struct ext4_extent_header);\n    size /= sizeof(struct ext4_extent_index);\n#ifdef AGGRESSIVE_TEST\n    if (size > 4)\n        size = 4;\n#endif\n    return size;\n}\n\nstatic uint16_t ext4_ext_max_entries(struct ext4_inode_ref *inode_ref,\n                     uint32_t depth)\n{\n    uint16_t max;\n\n    if (depth == ext_depth(inode_ref->inode)) {\n        if (depth == 0)\n            max = ext4_ext_space_root(inode_ref);\n        else\n            max = ext4_ext_space_root_idx(inode_ref);\n    } else {\n        if (depth == 0)\n            max = ext4_ext_space_block(inode_ref);\n        else\n            max = ext4_ext_space_block_idx(inode_ref);\n    }\n\n    return max;\n}\n\nstatic ext4_fsblk_t ext4_ext_find_goal(struct ext4_inode_ref *inode_ref,\n                       struct ext4_extent_path *path,\n                       ext4_lblk_t block)\n{\n    if (path) {\n        uint32_t depth = path->depth;\n        struct ext4_extent *ex;\n\n        /*\n         * Try to predict block placement assuming that we are\n         * filling in a file which will eventually be\n         * non-sparse --- i.e., in the case of libbfd writing\n         * an ELF object sections out-of-order but in a way\n         * the eventually results in a contiguous object or\n         * executable file, or some database extending a table\n         * space file.  However, this is actually somewhat\n         * non-ideal if we are writing a sparse file such as\n         * qemu or KVM writing a raw image file that is going\n         * to stay fairly sparse, since it will end up\n         * fragmenting the file system's free space.  Maybe we\n         * should have some hueristics or some way to allow\n         * userspace to pass a hint to file system,\n         * especially if the latter case turns out to be\n         * common.\n         */\n        ex = path[depth].extent;\n        if (ex) {\n            ext4_fsblk_t ext_pblk = ext4_ext_pblock(ex);\n            ext4_lblk_t ext_block = to_le32(ex->first_block);\n\n            if (block > ext_block)\n                return ext_pblk + (block - ext_block);\n            else\n                return ext_pblk - (ext_block - block);\n        }\n\n        /* it looks like index is empty;\n         * try to find starting block from index itself */\n        if (path[depth].block.lb_id)\n            return path[depth].block.lb_id;\n    }\n\n    /* OK. use inode's group */\n    return ext4_fs_inode_to_goal_block(inode_ref);\n}\n\n/*\n * Allocation for a meta data block\n */\nstatic ext4_fsblk_t ext4_ext_new_meta_block(struct ext4_inode_ref *inode_ref,\n                        struct ext4_extent_path *path,\n                        struct ext4_extent *ex, int *err,\n                        uint32_t flags)\n{\n    ext4_fsblk_t goal, newblock;\n\n    goal = ext4_ext_find_goal(inode_ref, path, to_le32(ex->first_block));\n    newblock = ext4_new_meta_blocks(inode_ref, goal, flags, NULL, err);\n    return newblock;\n}\n\n#if CONFIG_META_CSUM_ENABLE\nstatic uint32_t ext4_ext_block_csum(struct ext4_inode_ref *inode_ref,\n                    struct ext4_extent_header *eh)\n{\n    uint32_t checksum = 0;\n    struct ext4_sblock *sb = &inode_ref->fs->sb;\n\n    if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) {\n        uint32_t ino_index = to_le32(inode_ref->index);\n        uint32_t ino_gen =\n            to_le32(ext4_inode_get_generation(inode_ref->inode));\n        /* First calculate crc32 checksum against fs uuid */\n        checksum =\n            ext4_crc32c(EXT4_CRC32_INIT, sb->uuid, sizeof(sb->uuid));\n        /* Then calculate crc32 checksum against inode number\n         * and inode generation */\n        checksum = ext4_crc32c(checksum, &ino_index, sizeof(ino_index));\n        checksum = ext4_crc32c(checksum, &ino_gen, sizeof(ino_gen));\n        /* Finally calculate crc32 checksum against\n         * the entire extent block up to the checksum field */\n        checksum =\n            ext4_crc32c(checksum, eh, EXT4_EXTENT_TAIL_OFFSET(eh));\n    }\n    return checksum;\n}\n#else\n#define ext4_ext_block_csum(...) 0\n#endif\n\nstatic void\next4_extent_block_csum_set(struct ext4_inode_ref *inode_ref __unused,\n               struct ext4_extent_header *eh)\n{\n    struct ext4_extent_tail *tail;\n\n    tail = find_ext4_extent_tail(eh);\n    tail->et_checksum = to_le32(ext4_ext_block_csum(inode_ref, eh));\n}\n\nstatic int ext4_ext_dirty(struct ext4_inode_ref *inode_ref,\n              struct ext4_extent_path *path)\n{\n    if (path->block.lb_id)\n        ext4_trans_set_block_dirty(path->block.buf);\n    else\n        inode_ref->dirty = true;\n\n    return EOK;\n}\n\nstatic void ext4_ext_drop_refs(struct ext4_inode_ref *inode_ref,\n                   struct ext4_extent_path *path, bool keep_other)\n{\n    int32_t depth, i;\n\n    if (!path)\n        return;\n    if (keep_other)\n        depth = 0;\n    else\n        depth = path->depth;\n\n    for (i = 0; i <= depth; i++, path++) {\n        if (path->block.lb_id) {\n            if (ext4_bcache_test_flag(path->block.buf, BC_DIRTY))\n                ext4_extent_block_csum_set(inode_ref,\n                               path->header);\n\n            ext4_block_set(inode_ref->fs->bdev, &path->block);\n        }\n    }\n}\n\n/*\n * Check that whether the basic information inside the extent header\n * is correct or not.\n */\nstatic int ext4_ext_check(struct ext4_inode_ref *inode_ref,\n              struct ext4_extent_header *eh, uint16_t depth,\n              ext4_fsblk_t pblk __unused)\n{\n    struct ext4_extent_tail *tail;\n    struct ext4_sblock *sb = &inode_ref->fs->sb;\n    const char *error_msg;\n    (void)error_msg;\n\n    if (to_le16(eh->magic) != EXT4_EXTENT_MAGIC) {\n        error_msg = \"invalid magic\";\n        goto corrupted;\n    }\n    if (to_le16(eh->depth) != depth) {\n        error_msg = \"unexpected eh_depth\";\n        goto corrupted;\n    }\n    if (eh->max_entries_count == 0) {\n        error_msg = \"invalid eh_max\";\n        goto corrupted;\n    }\n    if (to_le16(eh->entries_count) > to_le16(eh->max_entries_count)) {\n        error_msg = \"invalid eh_entries\";\n        goto corrupted;\n    }\n\n    tail = find_ext4_extent_tail(eh);\n    if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) {\n        if (tail->et_checksum !=\n            to_le32(ext4_ext_block_csum(inode_ref, eh))) {\n            ext4_dbg(DEBUG_EXTENT,\n                 DBG_WARN \"Extent block checksum failed.\"\n                      \"Blocknr: %\" PRIu64 \"\\n\",\n                 pblk);\n        }\n    }\n\n    return EOK;\n\ncorrupted:\n    ext4_dbg(DEBUG_EXTENT, \"Bad extents B+ tree block: %s. \"\n                   \"Blocknr: %\" PRId64 \"\\n\",\n         error_msg, pblk);\n    return EIO;\n}\n\nstatic int read_extent_tree_block(struct ext4_inode_ref *inode_ref,\n                  ext4_fsblk_t pblk, int32_t depth,\n                  struct ext4_block *bh,\n                  uint32_t flags __unused)\n{\n    int err;\n\n    err = ext4_trans_block_get(inode_ref->fs->bdev, bh, pblk);\n    if (err != EOK)\n        goto errout;\n\n    err = ext4_ext_check(inode_ref, ext_block_hdr(bh), depth, pblk);\n    if (err != EOK)\n        goto errout;\n\n    return EOK;\nerrout:\n    if (bh->lb_id)\n        ext4_block_set(inode_ref->fs->bdev, bh);\n\n    return err;\n}\n\n/*\n * ext4_ext_binsearch_idx:\n * binary search for the closest index of the given block\n * the header must be checked before calling this\n */\nstatic void ext4_ext_binsearch_idx(struct ext4_extent_path *path,\n                   ext4_lblk_t block)\n{\n    struct ext4_extent_header *eh = path->header;\n    struct ext4_extent_index *r, *l, *m;\n\n    l = EXT_FIRST_INDEX(eh) + 1;\n    r = EXT_LAST_INDEX(eh);\n    while (l <= r) {\n        m = l + (r - l) / 2;\n        if (block < to_le32(m->first_block))\n            r = m - 1;\n        else\n            l = m + 1;\n    }\n\n    path->index = l - 1;\n}\n\n/*\n * ext4_ext_binsearch:\n * binary search for closest extent of the given block\n * the header must be checked before calling this\n */\nstatic void ext4_ext_binsearch(struct ext4_extent_path *path, ext4_lblk_t block)\n{\n    struct ext4_extent_header *eh = path->header;\n    struct ext4_extent *r, *l, *m;\n\n    if (eh->entries_count == 0) {\n        /*\n         * this leaf is empty:\n         * we get such a leaf in split/add case\n         */\n        return;\n    }\n\n    l = EXT_FIRST_EXTENT(eh) + 1;\n    r = EXT_LAST_EXTENT(eh);\n\n    while (l <= r) {\n        m = l + (r - l) / 2;\n        if (block < to_le32(m->first_block))\n            r = m - 1;\n        else\n            l = m + 1;\n    }\n\n    path->extent = l - 1;\n}\n\nstatic int ext4_find_extent(struct ext4_inode_ref *inode_ref, ext4_lblk_t block,\n                struct ext4_extent_path **orig_path, uint32_t flags)\n{\n    struct ext4_extent_header *eh;\n    struct ext4_block bh = EXT4_BLOCK_ZERO();\n    ext4_fsblk_t buf_block = 0;\n    struct ext4_extent_path *path = *orig_path;\n    int32_t depth, ppos = 0;\n    int32_t i;\n    int ret;\n\n    eh = ext_inode_hdr(inode_ref->inode);\n    depth = ext_depth(inode_ref->inode);\n\n    if (path) {\n        ext4_ext_drop_refs(inode_ref, path, 0);\n        if (depth > path[0].maxdepth) {\n            ext4_free(path);\n            *orig_path = path = NULL;\n        }\n    }\n    if (!path) {\n        int32_t path_depth = depth + 1;\n        /* account possible depth increase */\n        path = ext4_calloc(1, sizeof(struct ext4_extent_path) *\n                     (path_depth + 1));\n        if (!path)\n            return ENOMEM;\n        path[0].maxdepth = path_depth;\n    }\n    path[0].header = eh;\n    path[0].block = bh;\n\n    i = depth;\n    /* walk through the tree */\n    while (i) {\n        ext4_ext_binsearch_idx(path + ppos, block);\n        path[ppos].p_block = ext4_idx_pblock(path[ppos].index);\n        path[ppos].depth = i;\n        path[ppos].extent = NULL;\n        buf_block = path[ppos].p_block;\n\n        i--;\n        ppos++;\n        if (!path[ppos].block.lb_id ||\n            path[ppos].block.lb_id != buf_block) {\n            ret = read_extent_tree_block(inode_ref, buf_block, i,\n                             &bh, flags);\n            if (ret != EOK) {\n                goto err;\n            }\n            if (ppos > depth) {\n                ext4_block_set(inode_ref->fs->bdev, &bh);\n                ret = EIO;\n                goto err;\n            }\n\n            eh = ext_block_hdr(&bh);\n            path[ppos].block = bh;\n            path[ppos].header = eh;\n        }\n    }\n\n    path[ppos].depth = i;\n    path[ppos].extent = NULL;\n    path[ppos].index = NULL;\n\n    /* find extent */\n    ext4_ext_binsearch(path + ppos, block);\n    /* if not an empty leaf */\n    if (path[ppos].extent)\n        path[ppos].p_block = ext4_ext_pblock(path[ppos].extent);\n\n    *orig_path = path;\n\n    ret = EOK;\n    return ret;\n\nerr:\n    ext4_ext_drop_refs(inode_ref, path, 0);\n    ext4_free(path);\n    if (orig_path)\n        *orig_path = NULL;\n    return ret;\n}\n\nstatic void ext4_ext_init_header(struct ext4_inode_ref *inode_ref,\n                 struct ext4_extent_header *eh, int32_t depth)\n{\n    eh->entries_count = 0;\n    eh->max_entries_count = to_le16(ext4_ext_max_entries(inode_ref, depth));\n    eh->magic = to_le16(EXT4_EXTENT_MAGIC);\n    eh->depth = depth;\n}\n\nstatic int ext4_ext_insert_index(struct ext4_inode_ref *inode_ref,\n                 struct ext4_extent_path *path, int at,\n                 ext4_lblk_t insert_index,\n                 ext4_fsblk_t insert_block, bool set_to_ix)\n{\n    struct ext4_extent_index *ix;\n    struct ext4_extent_path *curp = path + at;\n    int len, err;\n    struct ext4_extent_header *eh;\n\n    if (curp->index && insert_index == to_le32(curp->index->first_block))\n        return EIO;\n\n    if (to_le16(curp->header->entries_count) ==\n        to_le16(curp->header->max_entries_count))\n        return EIO;\n\n    eh = curp->header;\n    if (curp->index == NULL) {\n        ix = EXT_FIRST_INDEX(eh);\n        curp->index = ix;\n    } else if (insert_index > to_le32(curp->index->first_block)) {\n        /* insert after */\n        ix = curp->index + 1;\n    } else {\n        /* insert before */\n        ix = curp->index;\n    }\n\n    if (ix > EXT_MAX_INDEX(eh))\n        return EIO;\n\n    len = EXT_LAST_INDEX(eh) - ix + 1;\n    ext4_assert(len >= 0);\n    if (len > 0)\n        memmove(ix + 1, ix, len * sizeof(struct ext4_extent_index));\n\n    ix->first_block = to_le32(insert_index);\n    ext4_idx_store_pblock(ix, insert_block);\n    eh->entries_count = to_le16(to_le16(eh->entries_count) + 1);\n\n    if (ix > EXT_LAST_INDEX(eh)) {\n        err = EIO;\n        goto out;\n    }\n\n    err = ext4_ext_dirty(inode_ref, curp);\n\nout:\n    if (err == EOK && set_to_ix) {\n        curp->index = ix;\n        curp->p_block = ext4_idx_pblock(ix);\n    }\n    return err;\n}\n\nstatic int ext4_ext_split_node(struct ext4_inode_ref *inode_ref,\n                   struct ext4_extent_path *path, int at,\n                   struct ext4_extent *newext,\n                   struct ext4_extent_path *npath,\n                   bool *ins_right_leaf)\n{\n    int i, npath_at, ret;\n    ext4_lblk_t insert_index;\n    ext4_fsblk_t newblock = 0;\n    int depth = ext_depth(inode_ref->inode);\n    npath_at = depth - at;\n\n    ext4_assert(at > 0);\n\n    if (path[depth].extent != EXT_MAX_EXTENT(path[depth].header))\n        insert_index = path[depth].extent[1].first_block;\n    else\n        insert_index = newext->first_block;\n\n    for (i = depth; i >= at; i--, npath_at--) {\n        struct ext4_block bh = EXT4_BLOCK_ZERO();\n\n        /* FIXME: currently we split at the point after the current\n         * extent. */\n        newblock =\n            ext4_ext_new_meta_block(inode_ref, path, newext, &ret, 0);\n        if (ret != EOK)\n            goto cleanup;\n\n        /*  For write access.*/\n        ret = ext4_trans_block_get_noread(inode_ref->fs->bdev, &bh,\n                          newblock);\n        if (ret != EOK)\n            goto cleanup;\n\n        if (i == depth) {\n            /* start copy from next extent */\n            int m = EXT_MAX_EXTENT(path[i].header) - path[i].extent;\n            struct ext4_extent_header *neh;\n            struct ext4_extent *ex;\n            neh = ext_block_hdr(&bh);\n            ex = EXT_FIRST_EXTENT(neh);\n            ext4_ext_init_header(inode_ref, neh, 0);\n            if (m) {\n                memmove(ex, path[i].extent + 1,\n                    sizeof(struct ext4_extent) * m);\n                neh->entries_count =\n                    to_le16(to_le16(neh->entries_count) + m);\n                path[i].header->entries_count = to_le16(\n                    to_le16(path[i].header->entries_count) - m);\n                ret = ext4_ext_dirty(inode_ref, path + i);\n                if (ret != EOK)\n                    goto cleanup;\n\n                npath[npath_at].p_block = ext4_ext_pblock(ex);\n                npath[npath_at].extent = ex;\n            } else {\n                npath[npath_at].p_block = 0;\n                npath[npath_at].extent = NULL;\n            }\n\n            npath[npath_at].depth = to_le16(neh->depth);\n            npath[npath_at].maxdepth = 0;\n            npath[npath_at].index = NULL;\n            npath[npath_at].header = neh;\n            npath[npath_at].block = bh;\n\n            ext4_trans_set_block_dirty(bh.buf);\n        } else {\n            int m = EXT_MAX_INDEX(path[i].header) - path[i].index;\n            struct ext4_extent_header *neh;\n            struct ext4_extent_index *ix;\n            neh = ext_block_hdr(&bh);\n            ix = EXT_FIRST_INDEX(neh);\n            ext4_ext_init_header(inode_ref, neh, depth - i);\n            ix->first_block = to_le32(insert_index);\n            ext4_idx_store_pblock(ix,\n                          npath[npath_at + 1].block.lb_id);\n            neh->entries_count = to_le16(1);\n            if (m) {\n                memmove(ix + 1, path[i].index + 1,\n                    sizeof(struct ext4_extent) * m);\n                neh->entries_count =\n                    to_le16(to_le16(neh->entries_count) + m);\n                path[i].header->entries_count = to_le16(\n                    to_le16(path[i].header->entries_count) - m);\n                ret = ext4_ext_dirty(inode_ref, path + i);\n                if (ret != EOK)\n                    goto cleanup;\n            }\n\n            npath[npath_at].p_block = ext4_idx_pblock(ix);\n            npath[npath_at].depth = to_le16(neh->depth);\n            npath[npath_at].maxdepth = 0;\n            npath[npath_at].extent = NULL;\n            npath[npath_at].index = ix;\n            npath[npath_at].header = neh;\n            npath[npath_at].block = bh;\n\n            ext4_trans_set_block_dirty(bh.buf);\n        }\n    }\n    newblock = 0;\n\n    /*\n     * If newext->first_block can be included into the\n     * right sub-tree.\n     */\n    if (to_le32(newext->first_block) < insert_index)\n        *ins_right_leaf = false;\n    else\n        *ins_right_leaf = true;\n\n    ret = ext4_ext_insert_index(inode_ref, path, at - 1, insert_index,\n                    npath[0].block.lb_id, *ins_right_leaf);\n\ncleanup:\n    if (ret != EOK) {\n        if (newblock)\n            ext4_ext_free_blocks(inode_ref, newblock, 1, 0);\n\n        npath_at = depth - at;\n        while (npath_at >= 0) {\n            if (npath[npath_at].block.lb_id) {\n                newblock = npath[npath_at].block.lb_id;\n                ext4_block_set(inode_ref->fs->bdev,\n                           &npath[npath_at].block);\n                ext4_ext_free_blocks(inode_ref, newblock, 1, 0);\n                memset(&npath[npath_at].block, 0,\n                       sizeof(struct ext4_block));\n            }\n            npath_at--;\n        }\n    }\n    return ret;\n}\n\n/*\n * ext4_ext_correct_indexes:\n * if leaf gets modified and modified extent is first in the leaf,\n * then we have to correct all indexes above.\n */\nstatic int ext4_ext_correct_indexes(struct ext4_inode_ref *inode_ref,\n                    struct ext4_extent_path *path)\n{\n    struct ext4_extent_header *eh;\n    int32_t depth = ext_depth(inode_ref->inode);\n    struct ext4_extent *ex;\n    uint32_t border;\n    int32_t k;\n    int err = EOK;\n\n    eh = path[depth].header;\n    ex = path[depth].extent;\n\n    if (ex == NULL || eh == NULL)\n        return EIO;\n\n    if (depth == 0) {\n        /* there is no tree at all */\n        return EOK;\n    }\n\n    if (ex != EXT_FIRST_EXTENT(eh)) {\n        /* we correct tree if first leaf got modified only */\n        return EOK;\n    }\n\n    k = depth - 1;\n    border = path[depth].extent->first_block;\n    path[k].index->first_block = border;\n    err = ext4_ext_dirty(inode_ref, path + k);\n    if (err != EOK)\n        return err;\n\n    while (k--) {\n        /* change all left-side indexes */\n        if (path[k + 1].index != EXT_FIRST_INDEX(path[k + 1].header))\n            break;\n        path[k].index->first_block = border;\n        err = ext4_ext_dirty(inode_ref, path + k);\n        if (err != EOK)\n            break;\n    }\n\n    return err;\n}\n\nstatic inline bool ext4_ext_can_prepend(struct ext4_extent *ex1,\n                    struct ext4_extent *ex2)\n{\n    if (ext4_ext_pblock(ex2) + ext4_ext_get_actual_len(ex2) !=\n        ext4_ext_pblock(ex1))\n        return 0;\n\n#ifdef AGGRESSIVE_TEST\n    if (ext4_ext_get_actual_len(ex1) + ext4_ext_get_actual_len(ex2) > 4)\n        return 0;\n#else\n    if (ext4_ext_is_unwritten(ex1)) {\n        if (ext4_ext_get_actual_len(ex1) +\n            ext4_ext_get_actual_len(ex2) >\n            EXT_UNWRITTEN_MAX_LEN)\n            return 0;\n    } else if (ext4_ext_get_actual_len(ex1) + ext4_ext_get_actual_len(ex2) >\n           EXT_INIT_MAX_LEN)\n        return 0;\n#endif\n\n    if (to_le32(ex2->first_block) + ext4_ext_get_actual_len(ex2) !=\n        to_le32(ex1->first_block))\n        return 0;\n\n    return 1;\n}\n\nstatic inline bool ext4_ext_can_append(struct ext4_extent *ex1,\n                       struct ext4_extent *ex2)\n{\n    if (ext4_ext_pblock(ex1) + ext4_ext_get_actual_len(ex1) !=\n        ext4_ext_pblock(ex2))\n        return 0;\n\n#ifdef AGGRESSIVE_TEST\n    if (ext4_ext_get_actual_len(ex1) + ext4_ext_get_actual_len(ex2) > 4)\n        return 0;\n#else\n    if (ext4_ext_is_unwritten(ex1)) {\n        if (ext4_ext_get_actual_len(ex1) +\n            ext4_ext_get_actual_len(ex2) >\n            EXT_UNWRITTEN_MAX_LEN)\n            return 0;\n    } else if (ext4_ext_get_actual_len(ex1) + ext4_ext_get_actual_len(ex2) >\n           EXT_INIT_MAX_LEN)\n        return 0;\n#endif\n\n    if (to_le32(ex1->first_block) + ext4_ext_get_actual_len(ex1) !=\n        to_le32(ex2->first_block))\n        return 0;\n\n    return 1;\n}\n\nstatic int ext4_ext_insert_leaf(struct ext4_inode_ref *inode_ref,\n                struct ext4_extent_path *path, int at,\n                struct ext4_extent *newext, int flags,\n                bool *need_split)\n{\n    struct ext4_extent_path *curp = path + at;\n    struct ext4_extent *ex = curp->extent;\n    int len, err, unwritten;\n    struct ext4_extent_header *eh;\n\n    *need_split = false;\n\n    if (curp->extent &&\n        to_le32(newext->first_block) == to_le32(curp->extent->first_block))\n        return EIO;\n\n    if (!(flags & EXT4_EXT_NO_COMBINE)) {\n        if (curp->extent && ext4_ext_can_append(curp->extent, newext)) {\n            unwritten = ext4_ext_is_unwritten(curp->extent);\n            curp->extent->block_count =\n                to_le16(ext4_ext_get_actual_len(curp->extent) +\n                    ext4_ext_get_actual_len(newext));\n            if (unwritten)\n                ext4_ext_mark_unwritten(curp->extent);\n\n            err = ext4_ext_dirty(inode_ref, curp);\n            goto out;\n        }\n\n        if (curp->extent &&\n            ext4_ext_can_prepend(curp->extent, newext)) {\n            unwritten = ext4_ext_is_unwritten(curp->extent);\n            curp->extent->first_block = newext->first_block;\n            curp->extent->block_count =\n                to_le16(ext4_ext_get_actual_len(curp->extent) +\n                    ext4_ext_get_actual_len(newext));\n            if (unwritten)\n                ext4_ext_mark_unwritten(curp->extent);\n\n            err = ext4_ext_dirty(inode_ref, curp);\n            goto out;\n        }\n    }\n\n    if (to_le16(curp->header->entries_count) ==\n        to_le16(curp->header->max_entries_count)) {\n        err = EIO;\n        *need_split = true;\n        goto out;\n    } else {\n        eh = curp->header;\n        if (curp->extent == NULL) {\n            ex = EXT_FIRST_EXTENT(eh);\n            curp->extent = ex;\n        } else if (to_le32(newext->first_block) >\n               to_le32(curp->extent->first_block)) {\n            /* insert after */\n            ex = curp->extent + 1;\n        } else {\n            /* insert before */\n            ex = curp->extent;\n        }\n    }\n\n    len = EXT_LAST_EXTENT(eh) - ex + 1;\n    ext4_assert(len >= 0);\n    if (len > 0)\n        memmove(ex + 1, ex, len * sizeof(struct ext4_extent));\n\n    if (ex > EXT_MAX_EXTENT(eh)) {\n        err = EIO;\n        goto out;\n    }\n\n    ex->first_block = newext->first_block;\n    ex->block_count = newext->block_count;\n    ext4_ext_store_pblock(ex, ext4_ext_pblock(newext));\n    eh->entries_count = to_le16(to_le16(eh->entries_count) + 1);\n\n    if (ex > EXT_LAST_EXTENT(eh)) {\n        err = EIO;\n        goto out;\n    }\n\n    err = ext4_ext_correct_indexes(inode_ref, path);\n    if (err != EOK)\n        goto out;\n    err = ext4_ext_dirty(inode_ref, curp);\n\nout:\n    if (err == EOK) {\n        curp->extent = ex;\n        curp->p_block = ext4_ext_pblock(ex);\n    }\n\n    return err;\n}\n\n/*\n * ext4_ext_grow_indepth:\n * implements tree growing procedure:\n * - allocates new block\n * - moves top-level data (index block or leaf) into the new block\n * - initializes new top-level, creating index that points to the\n *   just created block\n */\nstatic int ext4_ext_grow_indepth(struct ext4_inode_ref *inode_ref,\n                 uint32_t flags)\n{\n    struct ext4_extent_header *neh;\n    struct ext4_block bh = EXT4_BLOCK_ZERO();\n    ext4_fsblk_t newblock, goal = 0;\n    int err = EOK;\n\n    /* Try to prepend new index to old one */\n    if (ext_depth(inode_ref->inode))\n        goal = ext4_idx_pblock(\n            EXT_FIRST_INDEX(ext_inode_hdr(inode_ref->inode)));\n    else\n        goal = ext4_fs_inode_to_goal_block(inode_ref);\n\n    newblock = ext4_new_meta_blocks(inode_ref, goal, flags, NULL, &err);\n    if (newblock == 0)\n        return err;\n\n    /* # */\n    err = ext4_trans_block_get_noread(inode_ref->fs->bdev, &bh, newblock);\n    if (err != EOK) {\n        ext4_ext_free_blocks(inode_ref, newblock, 1, 0);\n        return err;\n    }\n\n    /* move top-level index/leaf into new block */\n    memmove(bh.data, inode_ref->inode->blocks,\n        sizeof(inode_ref->inode->blocks));\n\n    /* set size of new block */\n    neh = ext_block_hdr(&bh);\n    /* old root could have indexes or leaves\n     * so calculate e_max right way */\n    if (ext_depth(inode_ref->inode))\n        neh->max_entries_count =\n            to_le16(ext4_ext_space_block_idx(inode_ref));\n    else\n        neh->max_entries_count =\n            to_le16(ext4_ext_space_block(inode_ref));\n\n    neh->magic = to_le16(EXT4_EXTENT_MAGIC);\n    ext4_extent_block_csum_set(inode_ref, neh);\n\n    /* Update top-level index: num,max,pointer */\n    neh = ext_inode_hdr(inode_ref->inode);\n    neh->entries_count = to_le16(1);\n    ext4_idx_store_pblock(EXT_FIRST_INDEX(neh), newblock);\n    if (neh->depth == 0) {\n        /* Root extent block becomes index block */\n        neh->max_entries_count =\n            to_le16(ext4_ext_space_root_idx(inode_ref));\n        EXT_FIRST_INDEX(neh)\n            ->first_block = EXT_FIRST_EXTENT(neh)->first_block;\n    }\n    neh->depth = to_le16(to_le16(neh->depth) + 1);\n\n    ext4_trans_set_block_dirty(bh.buf);\n    inode_ref->dirty = true;\n    ext4_block_set(inode_ref->fs->bdev, &bh);\n\n    return err;\n}\n\nstatic inline void ext4_ext_replace_path(struct ext4_inode_ref *inode_ref,\n                     struct ext4_extent_path *path,\n                     struct ext4_extent_path *newpath,\n                     int at)\n{\n    ext4_ext_drop_refs(inode_ref, path + at, 1);\n    path[at] = *newpath;\n    memset(newpath, 0, sizeof(struct ext4_extent_path));\n}\n\nint ext4_ext_insert_extent(struct ext4_inode_ref *inode_ref,\n               struct ext4_extent_path **ppath,\n               struct ext4_extent *newext, int flags)\n{\n    int depth, level = 0, ret = 0;\n    struct ext4_extent_path *path = *ppath;\n    struct ext4_extent_path *npath = NULL;\n    bool ins_right_leaf = false;\n    bool need_split;\n\nagain:\n    depth = ext_depth(inode_ref->inode);\n    ret = ext4_ext_insert_leaf(inode_ref, path, depth, newext, flags,\n                   &need_split);\n    if (ret == EIO && need_split == true) {\n        int i;\n        for (i = depth, level = 0; i >= 0; i--, level++)\n            if (EXT_HAS_FREE_INDEX(path + i))\n                break;\n\n        /* Do we need to grow the tree? */\n        if (i < 0) {\n            ret = ext4_ext_grow_indepth(inode_ref, 0);\n            if (ret != EOK)\n                goto out;\n\n            ret = ext4_find_extent(\n                inode_ref, to_le32(newext->first_block), ppath, 0);\n            if (ret != EOK)\n                goto out;\n\n            path = *ppath;\n            /*\n             * After growing the tree, there should be free space in\n             * the only child node of the root.\n             */\n            level--;\n            depth++;\n        }\n\n        i = depth - (level - 1);\n        /* We split from leaf to the i-th node */\n        if (level > 0) {\n            npath = ext4_calloc(1, sizeof(struct ext4_extent_path) *\n                          (level));\n            if (!npath) {\n                ret = ENOMEM;\n                goto out;\n            }\n            ret = ext4_ext_split_node(inode_ref, path, i, newext,\n                          npath, &ins_right_leaf);\n            if (ret != EOK)\n                goto out;\n\n            while (--level >= 0) {\n                if (ins_right_leaf)\n                    ext4_ext_replace_path(inode_ref, path,\n                                  &npath[level],\n                                  i + level);\n                else if (npath[level].block.lb_id)\n                    ext4_ext_drop_refs(inode_ref,\n                               npath + level, 1);\n            }\n        }\n        goto again;\n    }\n\nout:\n    if (ret != EOK) {\n        if (path)\n            ext4_ext_drop_refs(inode_ref, path, 0);\n\n        while (--level >= 0 && npath) {\n            if (npath[level].block.lb_id) {\n                ext4_fsblk_t block = npath[level].block.lb_id;\n                ext4_ext_free_blocks(inode_ref, block, 1, 0);\n                ext4_ext_drop_refs(inode_ref, npath + level, 1);\n            }\n        }\n    }\n    if (npath)\n        ext4_free(npath);\n\n    return ret;\n}\n\nstatic void ext4_ext_remove_blocks(struct ext4_inode_ref *inode_ref,\n                   struct ext4_extent *ex, ext4_lblk_t from,\n                   ext4_lblk_t to)\n{\n    ext4_lblk_t len = to - from + 1;\n    ext4_lblk_t num;\n    ext4_fsblk_t start;\n    num = from - to_le32(ex->first_block);\n    start = ext4_ext_pblock(ex) + num;\n    ext4_dbg(DEBUG_EXTENT,\n         \"Freeing %\" PRIu32 \" at %\" PRIu64 \", %\" PRIu32 \"\\n\", from,\n         start, len);\n\n    ext4_ext_free_blocks(inode_ref, start, len, 0);\n}\n\nstatic int ext4_ext_remove_idx(struct ext4_inode_ref *inode_ref,\n                   struct ext4_extent_path *path, int32_t depth)\n{\n    int err = EOK;\n    int32_t i = depth;\n    ext4_fsblk_t leaf;\n\n    /* free index block */\n    leaf = ext4_idx_pblock(path[i].index);\n\n    if (path[i].index != EXT_LAST_INDEX(path[i].header)) {\n        ptrdiff_t len = EXT_LAST_INDEX(path[i].header) - path[i].index;\n        memmove(path[i].index, path[i].index + 1,\n            len * sizeof(struct ext4_extent_index));\n    }\n\n    path[i].header->entries_count =\n        to_le16(to_le16(path[i].header->entries_count) - 1);\n    err = ext4_ext_dirty(inode_ref, path + i);\n    if (err != EOK)\n        return err;\n\n    ext4_dbg(DEBUG_EXTENT, \"IDX: Freeing %\" PRIu32 \" at %\" PRIu64 \", %d\\n\",\n         to_le32(path[i].index->first_block), leaf, 1);\n    ext4_ext_free_blocks(inode_ref, leaf, 1, 0);\n\n    /*\n     * We may need to correct the paths after the first extents/indexes in\n     * a node being modified.\n     *\n     * We do not need to consider whether there's any extents presenting or\n     * not, as garbage will be cleared soon.\n     */\n    while (i > 0) {\n        if (path[i].index != EXT_FIRST_INDEX(path[i].header))\n            break;\n\n        path[i - 1].index->first_block = path[i].index->first_block;\n        err = ext4_ext_dirty(inode_ref, path + i - 1);\n        if (err != EOK)\n            break;\n\n        i--;\n    }\n    return err;\n}\n\nstatic int ext4_ext_remove_leaf(struct ext4_inode_ref *inode_ref,\n                struct ext4_extent_path *path, ext4_lblk_t from,\n                ext4_lblk_t to)\n{\n\n    int32_t depth = ext_depth(inode_ref->inode);\n    struct ext4_extent *ex = path[depth].extent;\n    struct ext4_extent *start_ex, *ex2 = NULL;\n    struct ext4_extent_header *eh = path[depth].header;\n    int32_t len;\n    int err = EOK;\n    uint16_t new_entries;\n\n    start_ex = ex;\n    new_entries = to_le16(eh->entries_count);\n    while (ex <= EXT_LAST_EXTENT(path[depth].header) &&\n           to_le32(ex->first_block) <= to) {\n        int32_t new_len = 0;\n        int unwritten;\n        ext4_lblk_t start, new_start;\n        ext4_fsblk_t newblock;\n        new_start = start = to_le32(ex->first_block);\n        len = ext4_ext_get_actual_len(ex);\n        newblock = ext4_ext_pblock(ex);\n        /*\n         * The 1st case:\n         *   The position that we start truncation is inside the range of an\n         *   extent. Here we should calculate the new length of that extent and\n         *   may start the removal from the next extent.\n         */\n        if (start < from) {\n            len -= from - start;\n            new_len = from - start;\n            start = from;\n            start_ex++;\n        } else {\n            /*\n             * The second case:\n             *   The last block to be truncated is inside the range of an\n             *   extent. We need to calculate the new length and the new\n             *   start of the extent.\n             */\n            if (start + len - 1 > to) {\n                new_len = start + len - 1 - to;\n                len -= new_len;\n                new_start = to + 1;\n                newblock += to + 1 - start;\n                ex2 = ex;\n            }\n        }\n\n        ext4_ext_remove_blocks(inode_ref, ex, start, start + len - 1);\n        /*\n         * Set the first block of the extent if it is presented.\n         */\n        ex->first_block = to_le32(new_start);\n\n        /*\n         * If the new length of the current extent we are working on is\n         * zero, remove it.\n         */\n        if (!new_len)\n            new_entries--;\n        else {\n            unwritten = ext4_ext_is_unwritten(ex);\n            ex->block_count = to_le16(new_len);\n            ext4_ext_store_pblock(ex, newblock);\n            if (unwritten)\n                ext4_ext_mark_unwritten(ex);\n        }\n\n        ex += 1;\n    }\n\n    if (ex2 == NULL)\n        ex2 = ex;\n\n    /*\n     * Move any remaining extents to the starting position of the node.\n     */\n    if (ex2 <= EXT_LAST_EXTENT(eh))\n        memmove(start_ex, ex2, (EXT_LAST_EXTENT(eh) - ex2 + 1) *\n                       sizeof(struct ext4_extent));\n\n    eh->entries_count = to_le16(new_entries);\n    ext4_ext_dirty(inode_ref, path + depth);\n\n    /*\n     * If the extent pointer is pointed to the first extent of the node, and\n     * there's still extents presenting, we may need to correct the indexes\n     * of the paths.\n     */\n    if (path[depth].extent == EXT_FIRST_EXTENT(eh) && eh->entries_count) {\n        err = ext4_ext_correct_indexes(inode_ref, path);\n        if (err != EOK)\n            return err;\n    }\n\n    /* if this leaf is free, then we should\n     * remove it from index block above */\n    if (eh->entries_count == 0 && path[depth].block.lb_id)\n        err = ext4_ext_remove_idx(inode_ref, path, depth - 1);\n    else if (depth > 0)\n        path[depth - 1].index++;\n\n    return err;\n}\n\n/*\n * Check if there's more to remove at a specific level.\n */\nstatic bool ext4_ext_more_to_rm(struct ext4_extent_path *path, ext4_lblk_t to)\n{\n    if (!to_le16(path->header->entries_count))\n        return false;\n\n    if (path->index > EXT_LAST_INDEX(path->header))\n        return false;\n\n    if (to_le32(path->index->first_block) > to)\n        return false;\n\n    return true;\n}\n\nint ext4_extent_remove_space(struct ext4_inode_ref *inode_ref, ext4_lblk_t from,\n                 ext4_lblk_t to)\n{\n    struct ext4_extent_path *path = NULL;\n    int ret = EOK;\n    int32_t depth = ext_depth(inode_ref->inode);\n    int32_t i;\n\n    ret = ext4_find_extent(inode_ref, from, &path, 0);\n    if (ret != EOK)\n        goto out;\n\n    if (!path[depth].extent) {\n        ret = EOK;\n        goto out;\n    }\n\n    bool in_range = IN_RANGE(from, to_le32(path[depth].extent->first_block),\n                 ext4_ext_get_actual_len(path[depth].extent));\n\n    if (!in_range) {\n        ret = EOK;\n        goto out;\n    }\n\n    /* If we do remove_space inside the range of an extent */\n    if ((to_le32(path[depth].extent->first_block) < from) &&\n        (to < to_le32(path[depth].extent->first_block) +\n              ext4_ext_get_actual_len(path[depth].extent) - 1)) {\n\n        struct ext4_extent *ex = path[depth].extent, newex;\n        int unwritten = ext4_ext_is_unwritten(ex);\n        ext4_lblk_t ee_block = to_le32(ex->first_block);\n        int32_t len = ext4_ext_get_actual_len(ex);\n        ext4_fsblk_t newblock = to + 1 - ee_block + ext4_ext_pblock(ex);\n\n        ex->block_count = to_le16(from - ee_block);\n        if (unwritten)\n            ext4_ext_mark_unwritten(ex);\n\n        ext4_ext_dirty(inode_ref, path + depth);\n\n        newex.first_block = to_le32(to + 1);\n        newex.block_count = to_le16(ee_block + len - 1 - to);\n        ext4_ext_store_pblock(&newex, newblock);\n        if (unwritten)\n            ext4_ext_mark_unwritten(&newex);\n\n        ret = ext4_ext_insert_extent(inode_ref, &path, &newex, 0);\n        goto out;\n    }\n\n    i = depth;\n    while (i >= 0) {\n        if (i == depth) {\n            struct ext4_extent_header *eh;\n            struct ext4_extent *first_ex, *last_ex;\n            ext4_lblk_t leaf_from, leaf_to;\n            eh = path[i].header;\n            ext4_assert(to_le16(eh->entries_count) > 0);\n            first_ex = EXT_FIRST_EXTENT(eh);\n            last_ex = EXT_LAST_EXTENT(eh);\n            leaf_from = to_le32(first_ex->first_block);\n            leaf_to = to_le32(last_ex->first_block) +\n                  ext4_ext_get_actual_len(last_ex) - 1;\n            if (leaf_from < from)\n                leaf_from = from;\n\n            if (leaf_to > to)\n                leaf_to = to;\n\n            ext4_ext_remove_leaf(inode_ref, path, leaf_from,\n                         leaf_to);\n            ext4_ext_drop_refs(inode_ref, path + i, 0);\n            i--;\n            continue;\n        }\n\n        struct ext4_extent_header *eh;\n        eh = path[i].header;\n        if (ext4_ext_more_to_rm(path + i, to)) {\n            struct ext4_block bh = EXT4_BLOCK_ZERO();\n            if (path[i + 1].block.lb_id)\n                ext4_ext_drop_refs(inode_ref, path + i + 1, 0);\n\n            ret = read_extent_tree_block(\n                inode_ref, ext4_idx_pblock(path[i].index),\n                depth - i - 1, &bh, 0);\n            if (ret != EOK)\n                goto out;\n\n            path[i].p_block = ext4_idx_pblock(path[i].index);\n            path[i + 1].block = bh;\n            path[i + 1].header = ext_block_hdr(&bh);\n            path[i + 1].depth = depth - i - 1;\n            if (i + 1 == depth)\n                path[i + 1].extent =\n                    EXT_FIRST_EXTENT(path[i + 1].header);\n            else\n                path[i + 1].index =\n                    EXT_FIRST_INDEX(path[i + 1].header);\n\n            i++;\n        } else {\n            if (i > 0) {\n                /*\n                 * Garbage entries will finally be cleared here.\n                 */\n                if (!eh->entries_count)\n                    ret = ext4_ext_remove_idx(inode_ref,\n                                  path, i - 1);\n                else\n                    path[i - 1].index++;\n            }\n\n            if (i)\n                ext4_block_set(inode_ref->fs->bdev,\n                           &path[i].block);\n\n            i--;\n        }\n    }\n\n    /* TODO: flexible tree reduction should be here */\n    if (path->header->entries_count == 0) {\n        /*\n         * truncate to zero freed all the tree,\n         * so we need to correct eh_depth\n         */\n        ext_inode_hdr(inode_ref->inode)->depth = 0;\n        ext_inode_hdr(inode_ref->inode)->max_entries_count =\n            to_le16(ext4_ext_space_root(inode_ref));\n        ret = ext4_ext_dirty(inode_ref, path);\n    }\n\nout:\n    ext4_ext_drop_refs(inode_ref, path, 0);\n    ext4_free(path);\n    path = NULL;\n    return ret;\n}\n\nstatic int ext4_ext_split_extent_at(struct ext4_inode_ref *inode_ref,\n                    struct ext4_extent_path **ppath,\n                    ext4_lblk_t split, uint32_t split_flag)\n{\n    struct ext4_extent *ex, newex;\n    ext4_fsblk_t newblock;\n    ext4_lblk_t ee_block;\n    int32_t ee_len;\n    int32_t depth = ext_depth(inode_ref->inode);\n    int err = EOK;\n\n    ex = (*ppath)[depth].extent;\n    ee_block = to_le32(ex->first_block);\n    ee_len = ext4_ext_get_actual_len(ex);\n    newblock = split - ee_block + ext4_ext_pblock(ex);\n\n    if (split == ee_block) {\n        /*\n         * case b: block @split is the block that the extent begins with\n         * then we just change the state of the extent, and splitting\n         * is not needed.\n         */\n        if (split_flag & EXT4_EXT_MARK_UNWRIT2)\n            ext4_ext_mark_unwritten(ex);\n        else\n            ext4_ext_mark_initialized(ex);\n\n        err = ext4_ext_dirty(inode_ref, *ppath + depth);\n        goto out;\n    }\n\n    ex->block_count = to_le16(split - ee_block);\n    if (split_flag & EXT4_EXT_MARK_UNWRIT1)\n        ext4_ext_mark_unwritten(ex);\n\n    err = ext4_ext_dirty(inode_ref, *ppath + depth);\n    if (err != EOK)\n        goto out;\n\n    newex.first_block = to_le32(split);\n    newex.block_count = to_le16(ee_len - (split - ee_block));\n    ext4_ext_store_pblock(&newex, newblock);\n    if (split_flag & EXT4_EXT_MARK_UNWRIT2)\n        ext4_ext_mark_unwritten(&newex);\n    err = ext4_ext_insert_extent(inode_ref, ppath, &newex,\n                     EXT4_EXT_NO_COMBINE);\n    if (err != EOK)\n        goto restore_extent_len;\n\nout:\n    return err;\nrestore_extent_len:\n    ex->block_count = to_le16(ee_len);\n    err = ext4_ext_dirty(inode_ref, *ppath + depth);\n    return err;\n}\n\nstatic int ext4_ext_convert_to_initialized(struct ext4_inode_ref *inode_ref,\n                       struct ext4_extent_path **ppath,\n                       ext4_lblk_t split, uint32_t blocks)\n{\n    int32_t depth = ext_depth(inode_ref->inode), err = EOK;\n    struct ext4_extent *ex = (*ppath)[depth].extent;\n\n    ext4_assert(to_le32(ex->first_block) <= split);\n\n    if (split + blocks ==\n        to_le32(ex->first_block) + ext4_ext_get_actual_len(ex)) {\n        /* split and initialize right part */\n        err = ext4_ext_split_extent_at(inode_ref, ppath, split,\n                           EXT4_EXT_MARK_UNWRIT1);\n    } else if (to_le32(ex->first_block) == split) {\n        /* split and initialize left part */\n        err = ext4_ext_split_extent_at(inode_ref, ppath, split + blocks,\n                           EXT4_EXT_MARK_UNWRIT2);\n    } else {\n        /* split 1 extent to 3 and initialize the 2nd */\n        err = ext4_ext_split_extent_at(inode_ref, ppath, split + blocks,\n                           EXT4_EXT_MARK_UNWRIT1 |\n                           EXT4_EXT_MARK_UNWRIT2);\n        if (err == EOK) {\n            err = ext4_ext_split_extent_at(inode_ref, ppath, split,\n                               EXT4_EXT_MARK_UNWRIT1);\n        }\n    }\n\n    return err;\n}\n\nstatic ext4_lblk_t ext4_ext_next_allocated_block(struct ext4_extent_path *path)\n{\n    int32_t depth;\n\n    depth = path->depth;\n\n    if (depth == 0 && path->extent == NULL)\n        return EXT_MAX_BLOCKS;\n\n    while (depth >= 0) {\n        if (depth == path->depth) {\n            /* leaf */\n            if (path[depth].extent &&\n                path[depth].extent !=\n                EXT_LAST_EXTENT(path[depth].header))\n                return to_le32(\n                    path[depth].extent[1].first_block);\n        } else {\n            /* index */\n            if (path[depth].index !=\n                EXT_LAST_INDEX(path[depth].header))\n                return to_le32(\n                    path[depth].index[1].first_block);\n        }\n        depth--;\n    }\n\n    return EXT_MAX_BLOCKS;\n}\n\nstatic int ext4_ext_zero_unwritten_range(struct ext4_inode_ref *inode_ref,\n                     ext4_fsblk_t block,\n                     uint32_t blocks_count)\n{\n    int err = EOK;\n    uint32_t i;\n    uint32_t block_size = ext4_sb_get_block_size(&inode_ref->fs->sb);\n    for (i = 0; i < blocks_count; i++) {\n        struct ext4_block bh = EXT4_BLOCK_ZERO();\n        err = ext4_trans_block_get_noread(inode_ref->fs->bdev, &bh,\n                          block + i);\n        if (err != EOK)\n            break;\n\n        memset(bh.data, 0, block_size);\n        ext4_trans_set_block_dirty(bh.buf);\n        err = ext4_block_set(inode_ref->fs->bdev, &bh);\n        if (err != EOK)\n            break;\n    }\n    return err;\n}\n\n__unused static void print_path(struct ext4_extent_path *path)\n{\n    int32_t i = path->depth;\n    while (i >= 0) {\n\n        ptrdiff_t a =\n            (path->extent)\n            ? (path->extent - EXT_FIRST_EXTENT(path->header))\n            : 0;\n        ptrdiff_t b =\n            (path->index)\n            ? (path->index - EXT_FIRST_INDEX(path->header))\n            : 0;\n\n        (void)a;\n        (void)b;\n        ext4_dbg(DEBUG_EXTENT,\n             \"depth %\" PRId32 \", p_block: %\" PRIu64 \",\"\n             \"p_ext offset: %td, p_idx offset: %td\\n\",\n             i, path->p_block, a, b);\n        i--;\n        path++;\n    }\n}\n\nint ext4_extent_get_blocks(struct ext4_inode_ref *inode_ref, ext4_lblk_t iblock,\n               uint32_t max_blocks, ext4_fsblk_t *result,\n               bool create, uint32_t *blocks_count)\n{\n    struct ext4_extent_path *path = NULL;\n    struct ext4_extent newex, *ex;\n    ext4_fsblk_t goal;\n    int err = EOK;\n    int32_t depth;\n    uint32_t allocated = 0;\n    ext4_lblk_t next;\n    ext4_fsblk_t newblock;\n\n    if (result)\n        *result = 0;\n\n    if (blocks_count)\n        *blocks_count = 0;\n\n    /* find extent for this block */\n    err = ext4_find_extent(inode_ref, iblock, &path, 0);\n    if (err != EOK) {\n        path = NULL;\n        goto out2;\n    }\n\n    depth = ext_depth(inode_ref->inode);\n\n    /*\n     * consistent leaf must not be empty\n     * this situations is possible, though, _during_ tree modification\n     * this is why assert can't be put in ext4_ext_find_extent()\n     */\n    ex = path[depth].extent;\n    if (ex) {\n        ext4_lblk_t ee_block = to_le32(ex->first_block);\n        ext4_fsblk_t ee_start = ext4_ext_pblock(ex);\n        uint16_t ee_len = ext4_ext_get_actual_len(ex);\n        /* if found exent covers block, simple return it */\n        if (IN_RANGE(iblock, ee_block, ee_len)) {\n            /* number of remain blocks in the extent */\n            allocated = ee_len - (iblock - ee_block);\n\n            if (!ext4_ext_is_unwritten(ex)) {\n                newblock = iblock - ee_block + ee_start;\n                goto out;\n            }\n\n            if (!create) {\n                newblock = 0;\n                goto out;\n            }\n\n            uint32_t zero_range;\n            zero_range = allocated;\n            if (zero_range > max_blocks)\n                zero_range = max_blocks;\n\n            newblock = iblock - ee_block + ee_start;\n            err = ext4_ext_zero_unwritten_range(inode_ref, newblock,\n                                zero_range);\n            if (err != EOK)\n                goto out2;\n\n            err = ext4_ext_convert_to_initialized(\n                inode_ref, &path, iblock, zero_range);\n            if (err != EOK)\n                goto out2;\n\n            goto out;\n        }\n    }\n\n    /*\n     * requested block isn't allocated yet\n     * we couldn't try to create block if create flag is zero\n     */\n    if (!create) {\n        goto out2;\n    }\n\n    /* find next allocated block so that we know how many\n     * blocks we can allocate without ovelapping next extent */\n    next = ext4_ext_next_allocated_block(path);\n    allocated = next - iblock;\n    if (allocated > max_blocks)\n        allocated = max_blocks;\n\n    /* allocate new block */\n    goal = ext4_ext_find_goal(inode_ref, path, iblock);\n    newblock = ext4_new_meta_blocks(inode_ref, goal, 0, &allocated, &err);\n    if (!newblock)\n        goto out2;\n\n    /* try to insert new extent into found leaf and return */\n    newex.first_block = to_le32(iblock);\n    ext4_ext_store_pblock(&newex, newblock);\n    newex.block_count = to_le16(allocated);\n    err = ext4_ext_insert_extent(inode_ref, &path, &newex, 0);\n    if (err != EOK) {\n        /* free data blocks we just allocated */\n        ext4_ext_free_blocks(inode_ref, ext4_ext_pblock(&newex),\n                     to_le16(newex.block_count), 0);\n        goto out2;\n    }\n\n    /* previous routine could use block we allocated */\n    newblock = ext4_ext_pblock(&newex);\n\nout:\n    if (allocated > max_blocks)\n        allocated = max_blocks;\n\n    if (result)\n        *result = newblock;\n\n    if (blocks_count)\n        *blocks_count = allocated;\n\nout2:\n    if (path) {\n        ext4_ext_drop_refs(inode_ref, path, 0);\n        ext4_free(path);\n    }\n\n    return err;\n}\n#endif\n"
  },
  {
    "path": "user.libs/liblwext4/src/ext4_fs.c",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n *\n *\n * HelenOS:\n * Copyright (c) 2012 Martin Sucha\n * Copyright (c) 2012 Frantisek Princ\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_fs.c\n * @brief More complex filesystem functions.\n */\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_misc.h>\n#include <ext4_errno.h>\n#include <ext4_debug.h>\n\n#include <ext4_trans.h>\n#include <ext4_fs.h>\n#include <ext4_blockdev.h>\n#include <ext4_super.h>\n#include <ext4_crc32.h>\n#include <ext4_block_group.h>\n#include <ext4_balloc.h>\n#include <ext4_bitmap.h>\n#include <ext4_inode.h>\n#include <ext4_ialloc.h>\n#include <ext4_extent.h>\n\n#include <string.h>\n\nint ext4_fs_init(struct ext4_fs *fs, struct ext4_blockdev *bdev,\n         bool read_only)\n{\n    int r, i;\n    uint16_t tmp;\n    uint32_t bsize;\n\n    ext4_assert(fs && bdev);\n\n    fs->bdev = bdev;\n\n    fs->read_only = read_only;\n\n    r = ext4_sb_read(fs->bdev, &fs->sb);\n    if (r != EOK)\n        return r;\n\n    if (!ext4_sb_check(&fs->sb))\n        return ENOTSUP;\n\n    bsize = ext4_sb_get_block_size(&fs->sb);\n    if (bsize > EXT4_MAX_BLOCK_SIZE)\n        return ENXIO;\n\n    r = ext4_fs_check_features(fs, &read_only);\n    if (r != EOK)\n        return r;\n\n    if (read_only)\n        fs->read_only = read_only;\n\n    /* Compute limits for indirect block levels */\n    uint32_t blocks_id = bsize / sizeof(uint32_t);\n\n    fs->inode_block_limits[0] = EXT4_INODE_DIRECT_BLOCK_COUNT;\n    fs->inode_blocks_per_level[0] = 1;\n\n    for (i = 1; i < 4; i++) {\n        fs->inode_blocks_per_level[i] =\n            fs->inode_blocks_per_level[i - 1] * blocks_id;\n        fs->inode_block_limits[i] = fs->inode_block_limits[i - 1] +\n                        fs->inode_blocks_per_level[i];\n    }\n\n    /*Validate FS*/\n    tmp = ext4_get16(&fs->sb, state);\n    if (tmp & EXT4_SUPERBLOCK_STATE_ERROR_FS)\n        ext4_dbg(DEBUG_FS, DBG_WARN\n                \"last umount error: superblock fs_error flag\\n\");\n\n\n    if (!fs->read_only) {\n        /* Mark system as mounted */\n        ext4_set16(&fs->sb, state, EXT4_SUPERBLOCK_STATE_ERROR_FS);\n        r = ext4_sb_write(fs->bdev, &fs->sb);\n        if (r != EOK)\n            return r;\n\n        /*Update mount count*/\n        ext4_set16(&fs->sb, mount_count, ext4_get16(&fs->sb, mount_count) + 1);\n    }\n\n    return r;\n}\n\nint ext4_fs_fini(struct ext4_fs *fs)\n{\n    ext4_assert(fs);\n\n    /*Set superblock state*/\n    ext4_set16(&fs->sb, state, EXT4_SUPERBLOCK_STATE_VALID_FS);\n\n    if (!fs->read_only)\n        return ext4_sb_write(fs->bdev, &fs->sb);\n\n    return EOK;\n}\n\nstatic void ext4_fs_debug_features_inc(uint32_t features_incompatible)\n{\n    if (features_incompatible & EXT4_FINCOM_COMPRESSION)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"compression\\n\");\n    if (features_incompatible & EXT4_FINCOM_FILETYPE)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"filetype\\n\");\n    if (features_incompatible & EXT4_FINCOM_RECOVER)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"recover\\n\");\n    if (features_incompatible & EXT4_FINCOM_JOURNAL_DEV)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"journal_dev\\n\");\n    if (features_incompatible & EXT4_FINCOM_META_BG)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"meta_bg\\n\");\n    if (features_incompatible & EXT4_FINCOM_EXTENTS)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"extents\\n\");\n    if (features_incompatible & EXT4_FINCOM_64BIT)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"64bit\\n\");\n    if (features_incompatible & EXT4_FINCOM_MMP)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"mnp\\n\");\n    if (features_incompatible & EXT4_FINCOM_FLEX_BG)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"flex_bg\\n\");\n    if (features_incompatible & EXT4_FINCOM_EA_INODE)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"ea_inode\\n\");\n    if (features_incompatible & EXT4_FINCOM_DIRDATA)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"dirdata\\n\");\n    if (features_incompatible & EXT4_FINCOM_BG_USE_META_CSUM)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"meta_csum\\n\");\n    if (features_incompatible & EXT4_FINCOM_LARGEDIR)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"largedir\\n\");\n    if (features_incompatible & EXT4_FINCOM_INLINE_DATA)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"inline_data\\n\");\n}\nstatic void ext4_fs_debug_features_comp(uint32_t features_compatible)\n{\n    if (features_compatible & EXT4_FCOM_DIR_PREALLOC)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"dir_prealloc\\n\");\n    if (features_compatible & EXT4_FCOM_IMAGIC_INODES)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"imagic_inodes\\n\");\n    if (features_compatible & EXT4_FCOM_HAS_JOURNAL)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"has_journal\\n\");\n    if (features_compatible & EXT4_FCOM_EXT_ATTR)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"ext_attr\\n\");\n    if (features_compatible & EXT4_FCOM_RESIZE_INODE)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"resize_inode\\n\");\n    if (features_compatible & EXT4_FCOM_DIR_INDEX)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"dir_index\\n\");\n}\n\nstatic void ext4_fs_debug_features_ro(uint32_t features_ro)\n{\n    if (features_ro & EXT4_FRO_COM_SPARSE_SUPER)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"sparse_super\\n\");\n    if (features_ro & EXT4_FRO_COM_LARGE_FILE)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"large_file\\n\");\n    if (features_ro & EXT4_FRO_COM_BTREE_DIR)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"btree_dir\\n\");\n    if (features_ro & EXT4_FRO_COM_HUGE_FILE)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"huge_file\\n\");\n    if (features_ro & EXT4_FRO_COM_GDT_CSUM)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"gtd_csum\\n\");\n    if (features_ro & EXT4_FRO_COM_DIR_NLINK)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"dir_nlink\\n\");\n    if (features_ro & EXT4_FRO_COM_EXTRA_ISIZE)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"extra_isize\\n\");\n    if (features_ro & EXT4_FRO_COM_QUOTA)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"quota\\n\");\n    if (features_ro & EXT4_FRO_COM_BIGALLOC)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"bigalloc\\n\");\n    if (features_ro & EXT4_FRO_COM_METADATA_CSUM)\n        ext4_dbg(DEBUG_FS, DBG_NONE \"metadata_csum\\n\");\n}\n\nint ext4_fs_check_features(struct ext4_fs *fs, bool *read_only)\n{\n    ext4_assert(fs && read_only);\n    uint32_t v;\n    if (ext4_get32(&fs->sb, rev_level) == 0) {\n        *read_only = false;\n        return EOK;\n    }\n\n    ext4_dbg(DEBUG_FS, DBG_INFO \"sblock features_incompatible:\\n\");\n    ext4_fs_debug_features_inc(ext4_get32(&fs->sb, features_incompatible));\n\n    ext4_dbg(DEBUG_FS, DBG_INFO \"sblock features_compatible:\\n\");\n    ext4_fs_debug_features_comp(ext4_get32(&fs->sb, features_compatible));\n\n    ext4_dbg(DEBUG_FS, DBG_INFO \"sblock features_read_only:\\n\");\n    ext4_fs_debug_features_ro(ext4_get32(&fs->sb, features_read_only));\n\n    /*Check features_incompatible*/\n    v = (ext4_get32(&fs->sb, features_incompatible) &\n         (~CONFIG_SUPPORTED_FINCOM));\n    if (v) {\n        ext4_dbg(DEBUG_FS, DBG_ERROR\n                \"sblock has unsupported features incompatible:\\n\");\n        ext4_fs_debug_features_inc(v);\n        return ENOTSUP;\n    }\n\n    /*Check features_read_only*/\n    v = ext4_get32(&fs->sb, features_read_only);\n    v &= ~CONFIG_SUPPORTED_FRO_COM;\n    if (v) {\n        ext4_dbg(DEBUG_FS, DBG_WARN\n            \"sblock has unsupported features read only:\\n\");\n        ext4_fs_debug_features_ro(v);\n        *read_only = true;\n        return EOK;\n    }\n    *read_only = false;\n\n    return EOK;\n}\n\n/**@brief Determine whether the block is inside the group.\n * @param baddr   block address\n * @param bgid    block group id\n * @return Error code\n */\nstatic bool ext4_block_in_group(struct ext4_sblock *s, ext4_fsblk_t baddr,\n                    uint32_t bgid)\n{\n    uint32_t actual_bgid;\n    actual_bgid = ext4_balloc_get_bgid_of_block(s, baddr);\n    if (actual_bgid == bgid)\n        return true;\n    return false;\n}\n\n/**@brief   To avoid calling the atomic setbit hundreds or thousands of times, we only\n *          need to use it within a single byte (to ensure we get endianness right).\n *          We can use memset for the rest of the bitmap as there are no other users.\n */\nstatic void ext4_fs_mark_bitmap_end(int start_bit, int end_bit, void *bitmap)\n{\n    int i;\n\n    if (start_bit >= end_bit)\n        return;\n\n    for (i = start_bit; (unsigned)i < ((start_bit + 7) & ~7UL); i++)\n        ext4_bmap_bit_set(bitmap, i);\n\n    if (i < end_bit)\n        memset((char *)bitmap + (i >> 3), 0xff, (end_bit - i) >> 3);\n}\n\n/**@brief Initialize block bitmap in block group.\n * @param bg_ref Reference to block group\n * @return Error code\n */\nstatic int ext4_fs_init_block_bitmap(struct ext4_block_group_ref *bg_ref)\n{\n    struct ext4_sblock *sb = &bg_ref->fs->sb;\n    struct ext4_bgroup *bg = bg_ref->block_group;\n    int rc;\n\n    uint32_t bit, bit_max;\n    uint32_t group_blocks;\n    uint16_t inode_size = ext4_get16(sb, inode_size);\n    uint32_t block_size = ext4_sb_get_block_size(sb);\n    uint32_t inodes_per_group = ext4_get32(sb, inodes_per_group);\n\n    ext4_fsblk_t i;\n    ext4_fsblk_t bmp_blk = ext4_bg_get_block_bitmap(bg, sb);\n    ext4_fsblk_t bmp_inode = ext4_bg_get_inode_bitmap(bg, sb);\n    ext4_fsblk_t inode_table = ext4_bg_get_inode_table_first_block(bg, sb);\n    ext4_fsblk_t first_bg = ext4_balloc_get_block_of_bgid(sb, bg_ref->index);\n\n    uint32_t dsc_per_block =  block_size / ext4_sb_get_desc_size(sb);\n\n    bool flex_bg = ext4_sb_feature_incom(sb, EXT4_FINCOM_FLEX_BG);\n    bool meta_bg = ext4_sb_feature_incom(sb, EXT4_FINCOM_META_BG);\n\n    uint32_t inode_table_bcnt = inodes_per_group * inode_size / block_size;\n\n    struct ext4_block block_bitmap;\n    rc = ext4_trans_block_get_noread(bg_ref->fs->bdev, &block_bitmap, bmp_blk);\n    if (rc != EOK)\n        return rc;\n\n    memset(block_bitmap.data, 0, block_size);\n    bit_max = ext4_sb_is_super_in_bg(sb, bg_ref->index);\n\n    uint32_t count = ext4_sb_first_meta_bg(sb) * dsc_per_block;\n    if (!meta_bg || bg_ref->index < count) {\n        if (bit_max) {\n            bit_max += ext4_bg_num_gdb(sb, bg_ref->index);\n            bit_max += ext4_get16(sb, s_reserved_gdt_blocks);\n        }\n    } else { /* For META_BG_BLOCK_GROUPS */\n        bit_max += ext4_bg_num_gdb(sb, bg_ref->index);\n    }\n    for (bit = 0; bit < bit_max; bit++)\n        ext4_bmap_bit_set(block_bitmap.data, bit);\n\n    if (bg_ref->index == ext4_block_group_cnt(sb) - 1) {\n        /*\n         * Even though mke2fs always initialize first and last group\n         * if some other tool enabled the EXT4_BG_BLOCK_UNINIT we need\n         * to make sure we calculate the right free blocks\n         */\n\n        group_blocks = (uint32_t)(ext4_sb_get_blocks_cnt(sb) -\n                      ext4_get32(sb, first_data_block) -\n                      ext4_get32(sb, blocks_per_group) *\n                      (ext4_block_group_cnt(sb) - 1));\n    } else {\n        group_blocks = ext4_get32(sb, blocks_per_group);\n    }\n\n    bool in_bg;\n    in_bg = ext4_block_in_group(sb, bmp_blk, bg_ref->index);\n    if (!flex_bg || in_bg)\n        ext4_bmap_bit_set(block_bitmap.data,\n                  (uint32_t)(bmp_blk - first_bg));\n\n    in_bg = ext4_block_in_group(sb, bmp_inode, bg_ref->index);\n    if (!flex_bg || in_bg) {\n        ext4_bmap_bit_set(block_bitmap.data,\n                  (uint32_t)(bmp_inode - first_bg));\n    }\n    \n    for (i = inode_table; i < inode_table + inode_table_bcnt; i++) {\n        in_bg = ext4_block_in_group(sb, i, bg_ref->index);\n        if (!flex_bg || in_bg)\n            ext4_bmap_bit_set(block_bitmap.data,\n                      (uint32_t)(i - first_bg));\n    }\n        /*\n         * Also if the number of blocks within the group is\n         * less than the blocksize * 8 ( which is the size\n         * of bitmap ), set rest of the block bitmap to 1\n         */\n        ext4_fs_mark_bitmap_end(group_blocks, block_size * 8, block_bitmap.data);\n    ext4_trans_set_block_dirty(block_bitmap.buf);\n\n    ext4_balloc_set_bitmap_csum(sb, bg_ref->block_group, block_bitmap.data);\n    bg_ref->dirty = true;\n\n    /* Save bitmap */\n    return ext4_block_set(bg_ref->fs->bdev, &block_bitmap);\n}\n\n/**@brief Initialize i-node bitmap in block group.\n * @param bg_ref Reference to block group\n * @return Error code\n */\nstatic int ext4_fs_init_inode_bitmap(struct ext4_block_group_ref *bg_ref)\n{\n    int rc;\n    struct ext4_sblock *sb = &bg_ref->fs->sb;\n    struct ext4_bgroup *bg = bg_ref->block_group;\n\n    /* Load bitmap */\n    ext4_fsblk_t bitmap_block_addr = ext4_bg_get_inode_bitmap(bg, sb);\n\n    struct ext4_block b;\n    rc = ext4_trans_block_get_noread(bg_ref->fs->bdev, &b, bitmap_block_addr);\n    if (rc != EOK)\n        return rc;\n\n    /* Initialize all bitmap bits to zero */\n    uint32_t block_size = ext4_sb_get_block_size(sb);\n    uint32_t inodes_per_group = ext4_get32(sb, inodes_per_group);\n\n    memset(b.data, 0, (inodes_per_group + 7) / 8);\n\n    uint32_t start_bit = inodes_per_group;\n    uint32_t end_bit = block_size * 8;\n\n    uint32_t i;\n    for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++)\n        ext4_bmap_bit_set(b.data, i);\n\n    if (i < end_bit)\n        memset(b.data + (i >> 3), 0xff, (end_bit - i) >> 3);\n\n    ext4_trans_set_block_dirty(b.buf);\n\n    ext4_ialloc_set_bitmap_csum(sb, bg, b.data);\n    bg_ref->dirty = true;\n\n    /* Save bitmap */\n    return ext4_block_set(bg_ref->fs->bdev, &b);\n}\n\n/**@brief Initialize i-node table in block group.\n * @param bg_ref Reference to block group\n * @return Error code\n */\nstatic int ext4_fs_init_inode_table(struct ext4_block_group_ref *bg_ref)\n{\n    struct ext4_sblock *sb = &bg_ref->fs->sb;\n    struct ext4_bgroup *bg = bg_ref->block_group;\n\n    uint32_t inode_size = ext4_get16(sb, inode_size);\n    uint32_t block_size = ext4_sb_get_block_size(sb);\n    uint32_t inodes_per_block = block_size / inode_size;\n    uint32_t inodes_in_group = ext4_inodes_in_group_cnt(sb, bg_ref->index);\n    uint32_t table_blocks = inodes_in_group / inodes_per_block;\n    ext4_fsblk_t fblock;\n\n    if (inodes_in_group % inodes_per_block)\n        table_blocks++;\n\n    /* Compute initialization bounds */\n    ext4_fsblk_t first_block = ext4_bg_get_inode_table_first_block(bg, sb);\n\n    ext4_fsblk_t last_block = first_block + table_blocks - 1;\n\n    /* Initialization of all itable blocks */\n    for (fblock = first_block; fblock <= last_block; ++fblock) {\n        struct ext4_block b;\n        int rc = ext4_trans_block_get_noread(bg_ref->fs->bdev, &b, fblock);\n        if (rc != EOK)\n            return rc;\n\n        memset(b.data, 0, block_size);\n        ext4_trans_set_block_dirty(b.buf);\n\n        rc = ext4_block_set(bg_ref->fs->bdev, &b);\n        if (rc != EOK)\n            return rc;\n    }\n\n    return EOK;\n}\n\nstatic ext4_fsblk_t ext4_fs_get_descriptor_block(struct ext4_sblock *s,\n                         uint32_t bgid,\n                         uint32_t dsc_per_block)\n{\n    uint32_t first_meta_bg, dsc_id;\n    int has_super = 0;\n    dsc_id = bgid / dsc_per_block;\n    first_meta_bg = ext4_sb_first_meta_bg(s);\n\n    bool meta_bg = ext4_sb_feature_incom(s, EXT4_FINCOM_META_BG);\n\n    if (!meta_bg || dsc_id < first_meta_bg)\n        return ext4_get32(s, first_data_block) + dsc_id + 1;\n\n    if (ext4_sb_is_super_in_bg(s, bgid))\n        has_super = 1;\n\n    return (has_super + ext4_fs_first_bg_block_no(s, bgid));\n}\n\n/**@brief  Compute checksum of block group descriptor.\n * @param sb   Superblock\n * @param bgid Index of block group in the filesystem\n * @param bg   Block group to compute checksum for\n * @return Checksum value\n */\nstatic uint16_t ext4_fs_bg_checksum(struct ext4_sblock *sb, uint32_t bgid,\n                    struct ext4_bgroup *bg)\n{\n    /* If checksum not supported, 0 will be returned */\n    uint16_t crc = 0;\n#if CONFIG_META_CSUM_ENABLE\n    /* Compute the checksum only if the filesystem supports it */\n    if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) {\n        /* Use metadata_csum algorithm instead */\n        uint32_t le32_bgid = to_le32(bgid);\n        uint32_t orig_checksum, checksum;\n\n        /* Preparation: temporarily set bg checksum to 0 */\n        orig_checksum = bg->checksum;\n        bg->checksum = 0;\n\n        /* First calculate crc32 checksum against fs uuid */\n        checksum = ext4_crc32c(EXT4_CRC32_INIT, sb->uuid,\n                sizeof(sb->uuid));\n        /* Then calculate crc32 checksum against bgid */\n        checksum = ext4_crc32c(checksum, &le32_bgid, sizeof(bgid));\n        /* Finally calculate crc32 checksum against block_group_desc */\n        checksum = ext4_crc32c(checksum, bg, ext4_sb_get_desc_size(sb));\n        bg->checksum = orig_checksum;\n\n        crc = checksum & 0xFFFF;\n        return crc;\n    }\n#endif\n    if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_GDT_CSUM)) {\n        uint8_t *base = (uint8_t *)bg;\n        uint8_t *checksum = (uint8_t *)&bg->checksum;\n\n        uint32_t offset = (uint32_t)(checksum - base);\n\n        /* Convert block group index to little endian */\n        uint32_t group = to_le32(bgid);\n\n        /* Initialization */\n        crc = ext4_bg_crc16(~0, sb->uuid, sizeof(sb->uuid));\n\n        /* Include index of block group */\n        crc = ext4_bg_crc16(crc, (uint8_t *)&group, sizeof(group));\n\n        /* Compute crc from the first part (stop before checksum field)\n         */\n        crc = ext4_bg_crc16(crc, (uint8_t *)bg, offset);\n\n        /* Skip checksum */\n        offset += sizeof(bg->checksum);\n\n        /* Checksum of the rest of block group descriptor */\n        if ((ext4_sb_feature_incom(sb, EXT4_FINCOM_64BIT)) &&\n            (offset < ext4_sb_get_desc_size(sb))) {\n\n            const uint8_t *start = ((uint8_t *)bg) + offset;\n            size_t len = ext4_sb_get_desc_size(sb) - offset;\n            crc = ext4_bg_crc16(crc, start, len);\n        }\n    }\n    return crc;\n}\n\n#if CONFIG_META_CSUM_ENABLE\nstatic bool ext4_fs_verify_bg_csum(struct ext4_sblock *sb,\n                   uint32_t bgid,\n                   struct ext4_bgroup *bg)\n{\n    if (!ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM))\n        return true;\n\n    return ext4_fs_bg_checksum(sb, bgid, bg) == to_le16(bg->checksum);\n}\n#else\n#define ext4_fs_verify_bg_csum(...) true\n#endif\n\nint ext4_fs_get_block_group_ref(struct ext4_fs *fs, uint32_t bgid,\n                struct ext4_block_group_ref *ref)\n{\n    /* Compute number of descriptors, that fits in one data block */\n    uint32_t block_size = ext4_sb_get_block_size(&fs->sb);\n    uint32_t dsc_cnt = block_size / ext4_sb_get_desc_size(&fs->sb);\n\n    /* Block group descriptor table starts at the next block after\n     * superblock */\n    uint64_t block_id = ext4_fs_get_descriptor_block(&fs->sb, bgid, dsc_cnt);\n\n    uint32_t offset = (bgid % dsc_cnt) * ext4_sb_get_desc_size(&fs->sb);\n\n    int rc = ext4_trans_block_get(fs->bdev, &ref->block, block_id);\n    if (rc != EOK)\n        return rc;\n\n    ref->block_group = (void *)(ref->block.data + offset);\n    ref->fs = fs;\n    ref->index = bgid;\n    ref->dirty = false;\n    struct ext4_bgroup *bg = ref->block_group;\n\n    if (!ext4_fs_verify_bg_csum(&fs->sb, bgid, bg)) {\n        ext4_dbg(DEBUG_FS,\n             DBG_WARN \"Block group descriptor checksum failed.\"\n             \"Block group index: %\" PRIu32\"\\n\",\n             bgid);\n    }\n\n    if (ext4_bg_has_flag(bg, EXT4_BLOCK_GROUP_BLOCK_UNINIT)) {\n        rc = ext4_fs_init_block_bitmap(ref);\n        if (rc != EOK) {\n            ext4_block_set(fs->bdev, &ref->block);\n            return rc;\n        }\n        ext4_bg_clear_flag(bg, EXT4_BLOCK_GROUP_BLOCK_UNINIT);\n        ref->dirty = true;\n    }\n\n    if (ext4_bg_has_flag(bg, EXT4_BLOCK_GROUP_INODE_UNINIT)) {\n        rc = ext4_fs_init_inode_bitmap(ref);\n        if (rc != EOK) {\n            ext4_block_set(ref->fs->bdev, &ref->block);\n            return rc;\n        }\n\n        ext4_bg_clear_flag(bg, EXT4_BLOCK_GROUP_INODE_UNINIT);\n\n        if (!ext4_bg_has_flag(bg, EXT4_BLOCK_GROUP_ITABLE_ZEROED)) {\n            rc = ext4_fs_init_inode_table(ref);\n            if (rc != EOK) {\n                ext4_block_set(fs->bdev, &ref->block);\n                return rc;\n            }\n\n            ext4_bg_set_flag(bg, EXT4_BLOCK_GROUP_ITABLE_ZEROED);\n        }\n\n        ref->dirty = true;\n    }\n\n    return EOK;\n}\n\nint ext4_fs_put_block_group_ref(struct ext4_block_group_ref *ref)\n{\n    /* Check if reference modified */\n    if (ref->dirty) {\n        /* Compute new checksum of block group */\n        uint16_t cs;\n        cs = ext4_fs_bg_checksum(&ref->fs->sb, ref->index,\n                     ref->block_group);\n        ref->block_group->checksum = to_le16(cs);\n\n        /* Mark block dirty for writing changes to physical device */\n        ext4_trans_set_block_dirty(ref->block.buf);\n    }\n\n    /* Put back block, that contains block group descriptor */\n    return ext4_block_set(ref->fs->bdev, &ref->block);\n}\n\n#if CONFIG_META_CSUM_ENABLE\nstatic uint32_t ext4_fs_inode_checksum(struct ext4_inode_ref *inode_ref)\n{\n    uint32_t checksum = 0;\n    struct ext4_sblock *sb = &inode_ref->fs->sb;\n    uint16_t inode_size = ext4_get16(sb, inode_size);\n\n    if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) {\n        uint32_t orig_checksum;\n\n        uint32_t ino_index = to_le32(inode_ref->index);\n        uint32_t ino_gen =\n            to_le32(ext4_inode_get_generation(inode_ref->inode));\n\n        /* Preparation: temporarily set bg checksum to 0 */\n        orig_checksum = ext4_inode_get_csum(sb, inode_ref->inode);\n        ext4_inode_set_csum(sb, inode_ref->inode, 0);\n\n        /* First calculate crc32 checksum against fs uuid */\n        checksum = ext4_crc32c(EXT4_CRC32_INIT, sb->uuid,\n                       sizeof(sb->uuid));\n        /* Then calculate crc32 checksum against inode number\n         * and inode generation */\n        checksum = ext4_crc32c(checksum, &ino_index, sizeof(ino_index));\n        checksum = ext4_crc32c(checksum, &ino_gen, sizeof(ino_gen));\n        /* Finally calculate crc32 checksum against\n         * the entire inode */\n        checksum = ext4_crc32c(checksum, inode_ref->inode, inode_size);\n        ext4_inode_set_csum(sb, inode_ref->inode, orig_checksum);\n\n        /* If inode size is not large enough to hold the\n         * upper 16bit of the checksum */\n        if (inode_size == EXT4_GOOD_OLD_INODE_SIZE)\n            checksum &= 0xFFFF;\n\n    }\n    return checksum;\n}\n#else\n#define ext4_fs_inode_checksum(...) 0\n#endif\n\nstatic void ext4_fs_set_inode_checksum(struct ext4_inode_ref *inode_ref)\n{\n    struct ext4_sblock *sb = &inode_ref->fs->sb;\n    if (!ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM))\n        return;\n\n    uint32_t csum = ext4_fs_inode_checksum(inode_ref);\n    ext4_inode_set_csum(sb, inode_ref->inode, csum);\n}\n\n#if CONFIG_META_CSUM_ENABLE\nstatic bool ext4_fs_verify_inode_csum(struct ext4_inode_ref *inode_ref)\n{\n    struct ext4_sblock *sb = &inode_ref->fs->sb;\n    if (!ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM))\n        return true;\n\n    return ext4_inode_get_csum(sb, inode_ref->inode) ==\n        ext4_fs_inode_checksum(inode_ref);\n}\n#else\n#define ext4_fs_verify_inode_csum(...) true\n#endif\n\nstatic int\n__ext4_fs_get_inode_ref(struct ext4_fs *fs, uint32_t index,\n            struct ext4_inode_ref *ref,\n            bool initialized)\n{\n    /* Compute number of i-nodes, that fits in one data block */\n    uint32_t inodes_per_group = ext4_get32(&fs->sb, inodes_per_group);\n\n    /*\n     * Inode numbers are 1-based, but it is simpler to work with 0-based\n     * when computing indices\n     */\n    index -= 1;\n    uint32_t block_group = index / inodes_per_group;\n    uint32_t offset_in_group = index % inodes_per_group;\n\n    /* Load block group, where i-node is located */\n    struct ext4_block_group_ref bg_ref;\n\n    int rc = ext4_fs_get_block_group_ref(fs, block_group, &bg_ref);\n    if (rc != EOK) {\n        return rc;\n    }\n\n    /* Load block address, where i-node table is located */\n    ext4_fsblk_t inode_table_start =\n        ext4_bg_get_inode_table_first_block(bg_ref.block_group, &fs->sb);\n\n    /* Put back block group reference (not needed more) */\n    rc = ext4_fs_put_block_group_ref(&bg_ref);\n    if (rc != EOK) {\n        return rc;\n    }\n\n    /* Compute position of i-node in the block group */\n    uint16_t inode_size = ext4_get16(&fs->sb, inode_size);\n    uint32_t block_size = ext4_sb_get_block_size(&fs->sb);\n    uint32_t byte_offset_in_group = offset_in_group * inode_size;\n\n    /* Compute block address */\n    ext4_fsblk_t block_id =\n        inode_table_start + (byte_offset_in_group / block_size);\n\n    rc = ext4_trans_block_get(fs->bdev, &ref->block, block_id);\n    if (rc != EOK) {\n        return rc;\n    }\n\n    /* Compute position of i-node in the data block */\n    uint32_t offset_in_block = byte_offset_in_group % block_size;\n    ref->inode = (struct ext4_inode *)(ref->block.data + offset_in_block);\n\n    /* We need to store the original value of index in the reference */\n    ref->index = index + 1;\n    ref->fs = fs;\n    ref->dirty = false;\n\n    if (initialized && !ext4_fs_verify_inode_csum(ref)) {\n        ext4_dbg(DEBUG_FS,\n            DBG_WARN \"Inode checksum failed.\"\n            \"Inode: %\" PRIu32\"\\n\",\n            ref->index);\n    }\n\n    return EOK;\n}\n\nint ext4_fs_get_inode_ref(struct ext4_fs *fs, uint32_t index,\n              struct ext4_inode_ref *ref)\n{\n    return __ext4_fs_get_inode_ref(fs, index, ref, true);\n}\n\nint ext4_fs_put_inode_ref(struct ext4_inode_ref *ref)\n{\n    /* Check if reference modified */\n    if (ref->dirty) {\n        /* Mark block dirty for writing changes to physical device */\n        ext4_fs_set_inode_checksum(ref);\n        ext4_trans_set_block_dirty(ref->block.buf);\n    }\n\n    /* Put back block, that contains i-node */\n    return ext4_block_set(ref->fs->bdev, &ref->block);\n}\n\nvoid ext4_fs_inode_blocks_init(struct ext4_fs *fs,\n                   struct ext4_inode_ref *inode_ref)\n{\n    struct ext4_inode *inode = inode_ref->inode;\n\n    /* Reset blocks array. For inode which is not directory or file, just\n     * fill in blocks with 0 */\n    switch (ext4_inode_type(&fs->sb, inode_ref->inode)) {\n    case EXT4_INODE_MODE_FILE:\n    case EXT4_INODE_MODE_DIRECTORY:\n        break;\n    default:\n        return;\n    }\n\n#if CONFIG_EXTENT_ENABLE\n    /* Initialize extents if needed */\n    if (ext4_sb_feature_incom(&fs->sb, EXT4_FINCOM_EXTENTS)) {\n        ext4_inode_set_flag(inode, EXT4_INODE_FLAG_EXTENTS);\n\n        /* Initialize extent root header */\n        ext4_extent_tree_init(inode_ref);\n    }\n\n    inode_ref->dirty = true;\n#endif\n}\n\nuint32_t ext4_fs_correspond_inode_mode(int filetype)\n{\n    switch (filetype) {\n    case EXT4_DE_DIR:\n        return EXT4_INODE_MODE_DIRECTORY;\n    case EXT4_DE_REG_FILE:\n        return EXT4_INODE_MODE_FILE;\n    case EXT4_DE_SYMLINK:\n        return EXT4_INODE_MODE_SOFTLINK;\n    case EXT4_DE_CHRDEV:\n        return EXT4_INODE_MODE_CHARDEV;\n    case EXT4_DE_BLKDEV:\n        return EXT4_INODE_MODE_BLOCKDEV;\n    case EXT4_DE_FIFO:\n        return EXT4_INODE_MODE_FIFO;\n    case EXT4_DE_SOCK:\n        return EXT4_INODE_MODE_SOCKET;\n    }\n    /* FIXME: unsupported filetype */\n    return EXT4_INODE_MODE_FILE;\n}\n\nint ext4_fs_alloc_inode(struct ext4_fs *fs, struct ext4_inode_ref *inode_ref,\n            int filetype)\n{\n    /* Check if newly allocated i-node will be a directory */\n    bool is_dir;\n    uint16_t inode_size = ext4_get16(&fs->sb, inode_size);\n\n    is_dir = (filetype == EXT4_DE_DIR);\n\n    /* Allocate inode by allocation algorithm */\n    uint32_t index;\n    int rc = ext4_ialloc_alloc_inode(fs, &index, is_dir);\n    if (rc != EOK)\n        return rc;\n\n    /* Load i-node from on-disk i-node table */\n    rc = __ext4_fs_get_inode_ref(fs, index, inode_ref, false);\n    if (rc != EOK) {\n        ext4_ialloc_free_inode(fs, index, is_dir);\n        return rc;\n    }\n\n    /* Initialize i-node */\n    struct ext4_inode *inode = inode_ref->inode;\n\n    memset(inode, 0, inode_size);\n\n    uint32_t mode;\n    if (is_dir) {\n        /*\n         * Default directory permissions to be compatible with other\n         * systems\n         * 0777 (octal) == rwxrwxrwx\n         */\n\n        mode = 0777;\n        mode |= EXT4_INODE_MODE_DIRECTORY;\n    } else if (filetype == EXT4_DE_SYMLINK) {\n        /*\n         * Default symbolic link permissions to be compatible with other systems\n         * 0777 (octal) == rwxrwxrwx\n         */\n\n        mode = 0777;\n        mode |= EXT4_INODE_MODE_SOFTLINK;\n    } else {\n        /*\n         * Default file permissions to be compatible with other systems\n         * 0666 (octal) == rw-rw-rw-\n         */\n\n        mode = 0666;\n        mode |= ext4_fs_correspond_inode_mode(filetype);\n    }\n    ext4_inode_set_mode(&fs->sb, inode, mode);\n\n    ext4_inode_set_links_cnt(inode, 0);\n    ext4_inode_set_uid(inode, 0);\n    ext4_inode_set_gid(inode, 0);\n    ext4_inode_set_size(inode, 0);\n    ext4_inode_set_access_time(inode, 0);\n    ext4_inode_set_change_inode_time(inode, 0);\n    ext4_inode_set_modif_time(inode, 0);\n    ext4_inode_set_del_time(inode, 0);\n    ext4_inode_set_blocks_count(&fs->sb, inode, 0);\n    ext4_inode_set_flags(inode, 0);\n    ext4_inode_set_generation(inode, 0);\n    if (inode_size > EXT4_GOOD_OLD_INODE_SIZE) {\n        uint16_t size = ext4_get16(&fs->sb, want_extra_isize);\n        ext4_inode_set_extra_isize(&fs->sb, inode, size);\n    }\n\n    memset(inode->blocks, 0, sizeof(inode->blocks));\n    inode_ref->dirty = true;\n\n    return EOK;\n}\n\nint ext4_fs_free_inode(struct ext4_inode_ref *inode_ref)\n{\n    struct ext4_fs *fs = inode_ref->fs;\n    uint32_t offset;\n    uint32_t suboff;\n    int rc;\n#if CONFIG_EXTENT_ENABLE\n    /* For extents must be data block destroyed by other way */\n    if ((ext4_sb_feature_incom(&fs->sb, EXT4_FINCOM_EXTENTS)) &&\n        (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {\n        /* Data structures are released during truncate operation... */\n        goto finish;\n    }\n#endif\n    /* Release all indirect (no data) blocks */\n\n    /* 1) Single indirect */\n    ext4_fsblk_t fblock = ext4_inode_get_indirect_block(inode_ref->inode, 0);\n    if (fblock != 0) {\n        int rc = ext4_balloc_free_block(inode_ref, fblock);\n        if (rc != EOK)\n            return rc;\n\n        ext4_inode_set_indirect_block(inode_ref->inode, 0, 0);\n    }\n\n    uint32_t block_size = ext4_sb_get_block_size(&fs->sb);\n    uint32_t count = block_size / sizeof(uint32_t);\n\n    struct ext4_block block;\n\n    /* 2) Double indirect */\n    fblock = ext4_inode_get_indirect_block(inode_ref->inode, 1);\n    if (fblock != 0) {\n        int rc = ext4_trans_block_get(fs->bdev, &block, fblock);\n        if (rc != EOK)\n            return rc;\n\n        ext4_fsblk_t ind_block;\n        for (offset = 0; offset < count; ++offset) {\n            ind_block = to_le32(((uint32_t *)block.data)[offset]);\n\n            if (ind_block == 0)\n                continue;\n            rc = ext4_balloc_free_block(inode_ref, ind_block);\n            if (rc != EOK) {\n                ext4_block_set(fs->bdev, &block);\n                return rc;\n            }\n\n        }\n\n        ext4_block_set(fs->bdev, &block);\n        rc = ext4_balloc_free_block(inode_ref, fblock);\n        if (rc != EOK)\n            return rc;\n\n        ext4_inode_set_indirect_block(inode_ref->inode, 1, 0);\n    }\n\n    /* 3) Tripple indirect */\n    struct ext4_block subblock;\n    fblock = ext4_inode_get_indirect_block(inode_ref->inode, 2);\n    if (fblock == 0)\n        goto finish;\n    rc = ext4_trans_block_get(fs->bdev, &block, fblock);\n    if (rc != EOK)\n        return rc;\n\n    ext4_fsblk_t ind_block;\n    for (offset = 0; offset < count; ++offset) {\n        ind_block = to_le32(((uint32_t *)block.data)[offset]);\n\n        if (ind_block == 0)\n            continue;\n        rc = ext4_trans_block_get(fs->bdev, &subblock,\n                ind_block);\n        if (rc != EOK) {\n            ext4_block_set(fs->bdev, &block);\n            return rc;\n        }\n\n        ext4_fsblk_t ind_subblk;\n        for (suboff = 0; suboff < count; ++suboff) {\n            ind_subblk = to_le32(((uint32_t *)subblock.data)[suboff]);\n\n            if (ind_subblk == 0)\n                continue;\n            rc = ext4_balloc_free_block(inode_ref, ind_subblk);\n            if (rc != EOK) {\n                ext4_block_set(fs->bdev, &subblock);\n                ext4_block_set(fs->bdev, &block);\n                return rc;\n            }\n\n        }\n\n        ext4_block_set(fs->bdev, &subblock);\n\n        rc = ext4_balloc_free_block(inode_ref,\n                ind_block);\n        if (rc != EOK) {\n            ext4_block_set(fs->bdev, &block);\n            return rc;\n        }\n\n    }\n\n    ext4_block_set(fs->bdev, &block);\n    rc = ext4_balloc_free_block(inode_ref, fblock);\n    if (rc != EOK)\n        return rc;\n\n    ext4_inode_set_indirect_block(inode_ref->inode, 2, 0);\nfinish:\n    /* Mark inode dirty for writing to the physical device */\n    inode_ref->dirty = true;\n\n    /* Free block with extended attributes if present */\n    ext4_fsblk_t xattr_block =\n        ext4_inode_get_file_acl(inode_ref->inode, &fs->sb);\n    if (xattr_block) {\n        int rc = ext4_balloc_free_block(inode_ref, xattr_block);\n        if (rc != EOK)\n            return rc;\n\n        ext4_inode_set_file_acl(inode_ref->inode, &fs->sb, 0);\n    }\n\n    /* Free inode by allocator */\n    if (ext4_inode_is_type(&fs->sb, inode_ref->inode,\n                   EXT4_INODE_MODE_DIRECTORY))\n        rc = ext4_ialloc_free_inode(fs, inode_ref->index, true);\n    else\n        rc = ext4_ialloc_free_inode(fs, inode_ref->index, false);\n\n    return rc;\n}\n\n\n/**@brief Release data block from i-node\n * @param inode_ref I-node to release block from\n * @param iblock    Logical block to be released\n * @return Error code\n */\nstatic int ext4_fs_release_inode_block(struct ext4_inode_ref *inode_ref,\n                ext4_lblk_t iblock)\n{\n    ext4_fsblk_t fblock;\n\n    struct ext4_fs *fs = inode_ref->fs;\n\n    /* Extents are handled otherwise = there is not support in this function\n     */\n    ext4_assert(!(\n        ext4_sb_feature_incom(&fs->sb, EXT4_FINCOM_EXTENTS) &&\n        (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))));\n\n    struct ext4_inode *inode = inode_ref->inode;\n\n    /* Handle simple case when we are dealing with direct reference */\n    if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {\n        fblock = ext4_inode_get_direct_block(inode, iblock);\n\n        /* Sparse file */\n        if (fblock == 0)\n            return EOK;\n\n        ext4_inode_set_direct_block(inode, iblock, 0);\n        return ext4_balloc_free_block(inode_ref, fblock);\n    }\n\n    /* Determine the indirection level needed to get the desired block */\n    unsigned int level = 0;\n    unsigned int i;\n    for (i = 1; i < 4; i++) {\n        if (iblock < fs->inode_block_limits[i]) {\n            level = i;\n            break;\n        }\n    }\n\n    if (level == 0)\n        return EIO;\n\n    /* Compute offsets for the topmost level */\n    uint32_t block_offset_in_level =\n        (uint32_t)(iblock - fs->inode_block_limits[level - 1]);\n    ext4_fsblk_t current_block =\n        ext4_inode_get_indirect_block(inode, level - 1);\n    uint32_t offset_in_block =\n        (uint32_t)(block_offset_in_level / fs->inode_blocks_per_level[level - 1]);\n\n    /*\n     * Navigate through other levels, until we find the block number\n     * or find null reference meaning we are dealing with sparse file\n     */\n    struct ext4_block block;\n\n    while (level > 0) {\n\n        /* Sparse check */\n        if (current_block == 0)\n            return EOK;\n\n        int rc = ext4_trans_block_get(fs->bdev, &block, current_block);\n        if (rc != EOK)\n            return rc;\n\n        current_block =\n            to_le32(((uint32_t *)block.data)[offset_in_block]);\n\n        /* Set zero if physical data block address found */\n        if (level == 1) {\n            ((uint32_t *)block.data)[offset_in_block] = to_le32(0);\n            ext4_trans_set_block_dirty(block.buf);\n        }\n\n        rc = ext4_block_set(fs->bdev, &block);\n        if (rc != EOK)\n            return rc;\n\n        level--;\n\n        /*\n         * If we are on the last level, break here as\n         * there is no next level to visit\n         */\n        if (level == 0)\n            break;\n\n        /* Visit the next level */\n        block_offset_in_level %= fs->inode_blocks_per_level[level];\n        offset_in_block = (uint32_t)(block_offset_in_level /\n                  fs->inode_blocks_per_level[level - 1]);\n    }\n\n    fblock = current_block;\n    if (fblock == 0)\n        return EOK;\n\n    /* Physical block is not referenced, it can be released */\n    return ext4_balloc_free_block(inode_ref, fblock);\n}\n\nint ext4_fs_truncate_inode(struct ext4_inode_ref *inode_ref, uint64_t new_size)\n{\n    struct ext4_sblock *sb = &inode_ref->fs->sb;\n    uint32_t i;\n    int r;\n    bool v;\n\n    /* Check flags, if i-node can be truncated */\n    if (!ext4_inode_can_truncate(sb, inode_ref->inode))\n        return EINVAL;\n\n    /* If sizes are equal, nothing has to be done. */\n    uint64_t old_size = ext4_inode_get_size(sb, inode_ref->inode);\n    if (old_size == new_size)\n        return EOK;\n\n    /* It's not supported to make the larger file by truncate operation */\n    if (old_size < new_size)\n        return EINVAL;\n\n    /* For symbolic link which is small enough */\n    v = ext4_inode_is_type(sb, inode_ref->inode, EXT4_INODE_MODE_SOFTLINK);\n    if (v && old_size < sizeof(inode_ref->inode->blocks) &&\n        !ext4_inode_get_blocks_count(sb, inode_ref->inode)) {\n        char *content = (char *)inode_ref->inode->blocks + new_size;\n        memset(content, 0,\n               sizeof(inode_ref->inode->blocks) - (uint32_t)new_size);\n        ext4_inode_set_size(inode_ref->inode, new_size);\n        inode_ref->dirty = true;\n\n        return EOK;\n    }\n\n    i = ext4_inode_type(sb, inode_ref->inode);\n    if (i == EXT4_INODE_MODE_CHARDEV ||\n        i == EXT4_INODE_MODE_BLOCKDEV ||\n        i == EXT4_INODE_MODE_SOCKET) {\n        inode_ref->inode->blocks[0] = 0;\n        inode_ref->inode->blocks[1] = 0;\n\n        inode_ref->dirty = true;\n        return EOK;\n    }\n\n    /* Compute how many blocks will be released */\n    uint32_t block_size = ext4_sb_get_block_size(sb);\n    uint32_t new_blocks_cnt = (uint32_t)((new_size + block_size - 1) / block_size);\n    uint32_t old_blocks_cnt = (uint32_t)((old_size + block_size - 1) / block_size);\n    uint32_t diff_blocks_cnt = old_blocks_cnt - new_blocks_cnt;\n#if CONFIG_EXTENT_ENABLE\n    if ((ext4_sb_feature_incom(sb, EXT4_FINCOM_EXTENTS)) &&\n        (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {\n\n        /* Extents require special operation */\n        if (diff_blocks_cnt) {\n            r = ext4_extent_remove_space(inode_ref, new_blocks_cnt,\n                             EXT_MAX_BLOCKS);\n            if (r != EOK)\n                return r;\n\n        }\n    } else\n#endif\n    {\n        /* Release data blocks from the end of file */\n\n        /* Starting from 1 because of logical blocks are numbered from 0\n         */\n        for (i = 0; i < diff_blocks_cnt; ++i) {\n            r = ext4_fs_release_inode_block(inode_ref,\n                            new_blocks_cnt + i);\n            if (r != EOK)\n                return r;\n        }\n    }\n\n    /* Update i-node */\n    ext4_inode_set_size(inode_ref->inode, new_size);\n    inode_ref->dirty = true;\n\n    return EOK;\n}\n\n/**@brief Compute 'goal' for inode index\n * @param inode_ref Reference to inode, to allocate block for\n * @return goal\n */\next4_fsblk_t ext4_fs_inode_to_goal_block(struct ext4_inode_ref *inode_ref)\n{\n    uint32_t grp_inodes = ext4_get32(&inode_ref->fs->sb, inodes_per_group);\n    return (inode_ref->index - 1) / grp_inodes;\n}\n\n/**@brief Compute 'goal' for allocation algorithm (For blockmap).\n * @param inode_ref Reference to inode, to allocate block for\n * @param goal\n * @return error code\n */\nint ext4_fs_indirect_find_goal(struct ext4_inode_ref *inode_ref,\n                   ext4_fsblk_t *goal)\n{\n    int r;\n    struct ext4_sblock *sb = &inode_ref->fs->sb;\n    *goal = 0;\n\n    uint64_t inode_size = ext4_inode_get_size(sb, inode_ref->inode);\n    uint32_t block_size = ext4_sb_get_block_size(sb);\n    uint32_t iblock_cnt = (uint32_t)(inode_size / block_size);\n\n    if (inode_size % block_size != 0)\n        iblock_cnt++;\n\n    /* If inode has some blocks, get last block address + 1 */\n    if (iblock_cnt > 0) {\n        r = ext4_fs_get_inode_dblk_idx(inode_ref, iblock_cnt - 1,\n                           goal, false);\n        if (r != EOK)\n            return r;\n\n        if (*goal != 0) {\n            (*goal)++;\n            return r;\n        }\n\n        /* If goal == 0, sparse file -> continue */\n    }\n\n    /* Identify block group of inode */\n\n    uint32_t inodes_per_bg = ext4_get32(sb, inodes_per_group);\n    uint32_t block_group = (inode_ref->index - 1) / inodes_per_bg;\n    block_size = ext4_sb_get_block_size(sb);\n\n    /* Load block group reference */\n    struct ext4_block_group_ref bg_ref;\n    r = ext4_fs_get_block_group_ref(inode_ref->fs, block_group, &bg_ref);\n    if (r != EOK)\n        return r;\n\n    struct ext4_bgroup *bg = bg_ref.block_group;\n\n    /* Compute indexes */\n    uint32_t bg_count = ext4_block_group_cnt(sb);\n    ext4_fsblk_t itab_first_block = ext4_bg_get_inode_table_first_block(bg, sb);\n    uint16_t itab_item_size = ext4_get16(sb, inode_size);\n    uint32_t itab_bytes;\n\n    /* Check for last block group */\n    if (block_group < bg_count - 1) {\n        itab_bytes = inodes_per_bg * itab_item_size;\n    } else {\n        /* Last block group could be smaller */\n        uint32_t inodes_cnt = ext4_get32(sb, inodes_count);\n\n        itab_bytes = (inodes_cnt - ((bg_count - 1) * inodes_per_bg));\n        itab_bytes *= itab_item_size;\n    }\n\n    ext4_fsblk_t inode_table_blocks = itab_bytes / block_size;\n\n    if (itab_bytes % block_size)\n        inode_table_blocks++;\n\n    *goal = itab_first_block + inode_table_blocks;\n\n    return ext4_fs_put_block_group_ref(&bg_ref);\n}\n\nstatic int ext4_fs_get_inode_dblk_idx_internal(struct ext4_inode_ref *inode_ref,\n                       ext4_lblk_t iblock, ext4_fsblk_t *fblock,\n                       bool extent_create,\n                       bool support_unwritten __unused)\n{\n    struct ext4_fs *fs = inode_ref->fs;\n\n    /* For empty file is situation simple */\n    if (ext4_inode_get_size(&fs->sb, inode_ref->inode) == 0) {\n        *fblock = 0;\n        return EOK;\n    }\n\n    ext4_fsblk_t current_block;\n\n    (void)extent_create;\n#if CONFIG_EXTENT_ENABLE\n    /* Handle i-node using extents */\n    if ((ext4_sb_feature_incom(&fs->sb, EXT4_FINCOM_EXTENTS)) &&\n        (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {\n\n        ext4_fsblk_t current_fsblk;\n        int rc = ext4_extent_get_blocks(inode_ref, iblock, 1,\n                &current_fsblk, extent_create, NULL);\n        if (rc != EOK)\n            return rc;\n\n        current_block = current_fsblk;\n        *fblock = current_block;\n\n        ext4_assert(*fblock || support_unwritten);\n        return EOK;\n    }\n#endif\n\n    struct ext4_inode *inode = inode_ref->inode;\n\n    /* Direct block are read directly from array in i-node structure */\n    if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {\n        current_block =\n            ext4_inode_get_direct_block(inode, (uint32_t)iblock);\n        *fblock = current_block;\n        return EOK;\n    }\n\n    /* Determine indirection level of the target block */\n    unsigned int l = 0;\n    unsigned int i;\n    for (i = 1; i < 4; i++) {\n        if (iblock < fs->inode_block_limits[i]) {\n            l = i;\n            break;\n        }\n    }\n\n    if (l == 0)\n        return EIO;\n\n    /* Compute offsets for the topmost level */\n    uint32_t blk_off_in_lvl = (uint32_t)(iblock - fs->inode_block_limits[l - 1]);\n    current_block = ext4_inode_get_indirect_block(inode, l - 1);\n    uint32_t off_in_blk = (uint32_t)(blk_off_in_lvl / fs->inode_blocks_per_level[l - 1]);\n\n    /* Sparse file */\n    if (current_block == 0) {\n        *fblock = 0;\n        return EOK;\n    }\n\n    struct ext4_block block;\n\n    /*\n     * Navigate through other levels, until we find the block number\n     * or find null reference meaning we are dealing with sparse file\n     */\n    while (l > 0) {\n        /* Load indirect block */\n        int rc = ext4_trans_block_get(fs->bdev, &block, current_block);\n        if (rc != EOK)\n            return rc;\n\n        /* Read block address from indirect block */\n        current_block =\n            to_le32(((uint32_t *)block.data)[off_in_blk]);\n\n        /* Put back indirect block untouched */\n        rc = ext4_block_set(fs->bdev, &block);\n        if (rc != EOK)\n            return rc;\n\n        /* Check for sparse file */\n        if (current_block == 0) {\n            *fblock = 0;\n            return EOK;\n        }\n\n        /* Jump to the next level */\n        l--;\n\n        /* Termination condition - we have address of data block loaded\n         */\n        if (l == 0)\n            break;\n\n        /* Visit the next level */\n        blk_off_in_lvl %= fs->inode_blocks_per_level[l];\n        off_in_blk = (uint32_t)(blk_off_in_lvl / fs->inode_blocks_per_level[l - 1]);\n    }\n\n    *fblock = current_block;\n\n    return EOK;\n}\n\n\nint ext4_fs_get_inode_dblk_idx(struct ext4_inode_ref *inode_ref,\n                   ext4_lblk_t iblock, ext4_fsblk_t *fblock,\n                   bool support_unwritten)\n{\n    return ext4_fs_get_inode_dblk_idx_internal(inode_ref, iblock, fblock,\n                           false, support_unwritten);\n}\n\nint ext4_fs_init_inode_dblk_idx(struct ext4_inode_ref *inode_ref,\n                ext4_lblk_t iblock, ext4_fsblk_t *fblock)\n{\n    return ext4_fs_get_inode_dblk_idx_internal(inode_ref, iblock, fblock,\n                           true, true);\n}\n\nstatic int ext4_fs_set_inode_data_block_index(struct ext4_inode_ref *inode_ref,\n                       ext4_lblk_t iblock, ext4_fsblk_t fblock)\n{\n    struct ext4_fs *fs = inode_ref->fs;\n\n#if CONFIG_EXTENT_ENABLE\n    /* Handle inode using extents */\n    if ((ext4_sb_feature_incom(&fs->sb, EXT4_FINCOM_EXTENTS)) &&\n        (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {\n        /* Not reachable */\n        return ENOTSUP;\n    }\n#endif\n\n    /* Handle simple case when we are dealing with direct reference */\n    if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {\n        ext4_inode_set_direct_block(inode_ref->inode, (uint32_t)iblock,\n                        (uint32_t)fblock);\n        inode_ref->dirty = true;\n\n        return EOK;\n    }\n\n    /* Determine the indirection level needed to get the desired block */\n    unsigned int l = 0;\n    unsigned int i;\n    for (i = 1; i < 4; i++) {\n        if (iblock < fs->inode_block_limits[i]) {\n            l = i;\n            break;\n        }\n    }\n\n    if (l == 0)\n        return EIO;\n\n    uint32_t block_size = ext4_sb_get_block_size(&fs->sb);\n\n    /* Compute offsets for the topmost level */\n    uint32_t blk_off_in_lvl = (uint32_t)(iblock - fs->inode_block_limits[l - 1]);\n    ext4_fsblk_t current_block =\n            ext4_inode_get_indirect_block(inode_ref->inode, l - 1);\n    uint32_t off_in_blk = (uint32_t)(blk_off_in_lvl / fs->inode_blocks_per_level[l - 1]);\n\n    ext4_fsblk_t new_blk;\n\n    struct ext4_block block;\n    struct ext4_block new_block;\n\n    /* Is needed to allocate indirect block on the i-node level */\n    if (current_block == 0) {\n        /* Allocate new indirect block */\n        ext4_fsblk_t goal;\n        int rc = ext4_fs_indirect_find_goal(inode_ref, &goal);\n        if (rc != EOK)\n            return rc;\n\n        rc = ext4_balloc_alloc_block(inode_ref, goal, &new_blk);\n        if (rc != EOK)\n            return rc;\n\n        /* Update i-node */\n        ext4_inode_set_indirect_block(inode_ref->inode, l - 1,\n                (uint32_t)new_blk);\n        inode_ref->dirty = true;\n\n        /* Load newly allocated block */\n        rc = ext4_trans_block_get_noread(fs->bdev, &new_block, new_blk);\n        if (rc != EOK) {\n            ext4_balloc_free_block(inode_ref, new_blk);\n            return rc;\n        }\n\n        /* Initialize new block */\n        memset(new_block.data, 0, block_size);\n        ext4_trans_set_block_dirty(new_block.buf);\n\n        /* Put back the allocated block */\n        rc = ext4_block_set(fs->bdev, &new_block);\n        if (rc != EOK)\n            return rc;\n\n        current_block = new_blk;\n    }\n\n    /*\n     * Navigate through other levels, until we find the block number\n     * or find null reference meaning we are dealing with sparse file\n     */\n    while (l > 0) {\n        int rc = ext4_trans_block_get(fs->bdev, &block, current_block);\n        if (rc != EOK)\n            return rc;\n\n        current_block = to_le32(((uint32_t *)block.data)[off_in_blk]);\n        if ((l > 1) && (current_block == 0)) {\n            ext4_fsblk_t goal;\n            rc = ext4_fs_indirect_find_goal(inode_ref, &goal);\n            if (rc != EOK) {\n                ext4_block_set(fs->bdev, &block);\n                return rc;\n            }\n\n            /* Allocate new block */\n            rc =\n                ext4_balloc_alloc_block(inode_ref, goal, &new_blk);\n            if (rc != EOK) {\n                ext4_block_set(fs->bdev, &block);\n                return rc;\n            }\n\n            /* Load newly allocated block */\n            rc = ext4_trans_block_get_noread(fs->bdev, &new_block,\n                        new_blk);\n\n            if (rc != EOK) {\n                ext4_block_set(fs->bdev, &block);\n                return rc;\n            }\n\n            /* Initialize allocated block */\n            memset(new_block.data, 0, block_size);\n            ext4_trans_set_block_dirty(new_block.buf);\n\n            rc = ext4_block_set(fs->bdev, &new_block);\n            if (rc != EOK) {\n                ext4_block_set(fs->bdev, &block);\n                return rc;\n            }\n\n            /* Write block address to the parent */\n            uint32_t * p = (uint32_t * )block.data;\n            p[off_in_blk] = to_le32((uint32_t)new_blk);\n            ext4_trans_set_block_dirty(block.buf);\n            current_block = new_blk;\n        }\n\n        /* Will be finished, write the fblock address */\n        if (l == 1) {\n            uint32_t * p = (uint32_t * )block.data;\n            p[off_in_blk] = to_le32((uint32_t)fblock);\n            ext4_trans_set_block_dirty(block.buf);\n        }\n\n        rc = ext4_block_set(fs->bdev, &block);\n        if (rc != EOK)\n            return rc;\n\n        l--;\n\n        /*\n         * If we are on the last level, break here as\n         * there is no next level to visit\n         */\n        if (l == 0)\n            break;\n\n        /* Visit the next level */\n        blk_off_in_lvl %= fs->inode_blocks_per_level[l];\n        off_in_blk = (uint32_t)(blk_off_in_lvl / fs->inode_blocks_per_level[l - 1]);\n    }\n\n    return EOK;\n}\n\n\nint ext4_fs_append_inode_dblk(struct ext4_inode_ref *inode_ref,\n                  ext4_fsblk_t *fblock, ext4_lblk_t *iblock)\n{\n#if CONFIG_EXTENT_ENABLE\n    /* Handle extents separately */\n    if ((ext4_sb_feature_incom(&inode_ref->fs->sb, EXT4_FINCOM_EXTENTS)) &&\n        (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {\n        int rc;\n        ext4_fsblk_t current_fsblk;\n        struct ext4_sblock *sb = &inode_ref->fs->sb;\n        uint64_t inode_size = ext4_inode_get_size(sb, inode_ref->inode);\n        uint32_t block_size = ext4_sb_get_block_size(sb);\n        *iblock = (uint32_t)((inode_size + block_size - 1) / block_size);\n\n        rc = ext4_extent_get_blocks(inode_ref, *iblock, 1,\n                        &current_fsblk, true, NULL);\n        if (rc != EOK)\n            return rc;\n\n        *fblock = current_fsblk;\n        ext4_assert(*fblock);\n\n        ext4_inode_set_size(inode_ref->inode, inode_size + block_size);\n        inode_ref->dirty = true;\n\n\n        return rc;\n    }\n#endif\n    struct ext4_sblock *sb = &inode_ref->fs->sb;\n\n    /* Compute next block index and allocate data block */\n    uint64_t inode_size = ext4_inode_get_size(sb, inode_ref->inode);\n    uint32_t block_size = ext4_sb_get_block_size(sb);\n\n    /* Align size i-node size */\n    if ((inode_size % block_size) != 0)\n        inode_size += block_size - (inode_size % block_size);\n\n    /* Logical blocks are numbered from 0 */\n    uint32_t new_block_idx = (uint32_t)(inode_size / block_size);\n\n    /* Allocate new physical block */\n    ext4_fsblk_t goal, phys_block;\n    int rc = ext4_fs_indirect_find_goal(inode_ref, &goal);\n    if (rc != EOK)\n        return rc;\n\n    rc = ext4_balloc_alloc_block(inode_ref, goal, &phys_block);\n    if (rc != EOK)\n        return rc;\n\n    /* Add physical block address to the i-node */\n    rc = ext4_fs_set_inode_data_block_index(inode_ref, new_block_idx,\n                        phys_block);\n    if (rc != EOK) {\n        ext4_balloc_free_block(inode_ref, phys_block);\n        return rc;\n    }\n\n    /* Update i-node */\n    ext4_inode_set_size(inode_ref->inode, inode_size + block_size);\n    inode_ref->dirty = true;\n\n    *fblock = phys_block;\n    *iblock = new_block_idx;\n\n    return EOK;\n}\n\nvoid ext4_fs_inode_links_count_inc(struct ext4_inode_ref *inode_ref)\n{\n    uint16_t link;\n    bool is_dx;\n    link = ext4_inode_get_links_cnt(inode_ref->inode);\n    link++;\n    ext4_inode_set_links_cnt(inode_ref->inode, link);\n\n    is_dx = ext4_sb_feature_com(&inode_ref->fs->sb, EXT4_FCOM_DIR_INDEX) &&\n        ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_INDEX);\n\n    if (is_dx && link > 1) {\n        if (link >= EXT4_LINK_MAX || link == 2) {\n            ext4_inode_set_links_cnt(inode_ref->inode, 1);\n\n            uint32_t v;\n            v = ext4_get32(&inode_ref->fs->sb, features_read_only);\n            v |= EXT4_FRO_COM_DIR_NLINK;\n            ext4_set32(&inode_ref->fs->sb, features_read_only, v);\n        }\n    }\n}\n\nvoid ext4_fs_inode_links_count_dec(struct ext4_inode_ref *inode_ref)\n{\n    uint16_t links = ext4_inode_get_links_cnt(inode_ref->inode);\n    if (!ext4_inode_is_type(&inode_ref->fs->sb, inode_ref->inode,\n                EXT4_INODE_MODE_DIRECTORY)) {\n        if (links > 0)\n            ext4_inode_set_links_cnt(inode_ref->inode, links - 1);\n        return;\n    }\n\n    if (links > 2)\n        ext4_inode_set_links_cnt(inode_ref->inode, links - 1);\n}\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/src/ext4_hash.c",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n *\n * FreeBSD:\n * Copyright (c) 2010, 2013 Zheng Liu <lz@freebsd.org>\n * Copyright (c) 2012, Vyacheslav Matyushin\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n */\n\n/*\n * The following notice applies to the code in ext2_half_md4():\n *\n * Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved.\n *\n * License to copy and use this software is granted provided that it\n * is identified as the \"RSA Data Security, Inc. MD4 Message-Digest\n * Algorithm\" in all material mentioning or referencing this software\n * or this function.\n *\n * License is also granted to make and use derivative works provided\n * that such works are identified as \"derived from the RSA Data\n * Security, Inc. MD4 Message-Digest Algorithm\" in all material\n * mentioning or referencing the derived work.\n *\n * RSA Data Security, Inc. makes no representations concerning either\n * the merchantability of this software or the suitability of this\n * software for any particular purpose. It is provided \"as is\"\n * without express or implied warranty of any kind.\n *\n * These notices must be retained in any copies of any part of this\n * documentation and/or software.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_hash.c\n * @brief Directory indexing hash functions.\n */\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_misc.h>\n#include <ext4_errno.h>\n#include <ext4_debug.h>\n\n#include <string.h>\n\n/* F, G, and H are MD4 functions */\n#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))\n#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))\n#define H(x, y, z) ((x) ^ (y) ^ (z))\n\n/* ROTATE_LEFT rotates x left n bits */\n#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))\n\n/*\n * FF, GG, and HH are transformations for rounds 1, 2, and 3.\n * Rotation is separated from addition to prevent recomputation.\n */\n#define FF(a, b, c, d, x, s)                                                   \\\n    {                                                                      \\\n        (a) += F((b), (c), (d)) + (x);                                 \\\n        (a) = ROTATE_LEFT((a), (s));                                   \\\n    \\\n}\n\n#define GG(a, b, c, d, x, s)                                                   \\\n    {                                                                      \\\n        (a) += G((b), (c), (d)) + (x) + (uint32_t)0x5A827999;          \\\n        (a) = ROTATE_LEFT((a), (s));                                   \\\n    \\\n}\n\n#define HH(a, b, c, d, x, s)                                                   \\\n    {                                                                      \\\n        (a) += H((b), (c), (d)) + (x) + (uint32_t)0x6ED9EBA1;          \\\n        (a) = ROTATE_LEFT((a), (s));                                   \\\n    \\\n}\n\n/*\n * MD4 basic transformation.  It transforms state based on block.\n *\n * This is a half md4 algorithm since Linux uses this algorithm for dir\n * index.  This function is derived from the RSA Data Security, Inc. MD4\n * Message-Digest Algorithm and was modified as necessary.\n *\n * The return value of this function is uint32_t in Linux, but actually we don't\n * need to check this value, so in our version this function doesn't return any\n * value.\n */\nstatic void ext2_half_md4(uint32_t hash[4], uint32_t data[8])\n{\n    uint32_t a = hash[0], b = hash[1], c = hash[2], d = hash[3];\n\n    /* Round 1 */\n    FF(a, b, c, d, data[0], 3);\n    FF(d, a, b, c, data[1], 7);\n    FF(c, d, a, b, data[2], 11);\n    FF(b, c, d, a, data[3], 19);\n    FF(a, b, c, d, data[4], 3);\n    FF(d, a, b, c, data[5], 7);\n    FF(c, d, a, b, data[6], 11);\n    FF(b, c, d, a, data[7], 19);\n\n    /* Round 2 */\n    GG(a, b, c, d, data[1], 3);\n    GG(d, a, b, c, data[3], 5);\n    GG(c, d, a, b, data[5], 9);\n    GG(b, c, d, a, data[7], 13);\n    GG(a, b, c, d, data[0], 3);\n    GG(d, a, b, c, data[2], 5);\n    GG(c, d, a, b, data[4], 9);\n    GG(b, c, d, a, data[6], 13);\n\n    /* Round 3 */\n    HH(a, b, c, d, data[3], 3);\n    HH(d, a, b, c, data[7], 9);\n    HH(c, d, a, b, data[2], 11);\n    HH(b, c, d, a, data[6], 15);\n    HH(a, b, c, d, data[1], 3);\n    HH(d, a, b, c, data[5], 9);\n    HH(c, d, a, b, data[0], 11);\n    HH(b, c, d, a, data[4], 15);\n\n    hash[0] += a;\n    hash[1] += b;\n    hash[2] += c;\n    hash[3] += d;\n}\n\n/*\n * Tiny Encryption Algorithm.\n */\nstatic void ext2_tea(uint32_t hash[4], uint32_t data[8])\n{\n    uint32_t tea_delta = 0x9E3779B9;\n    uint32_t sum;\n    uint32_t x = hash[0], y = hash[1];\n    int n = 16;\n    int i = 1;\n\n    while (n-- > 0) {\n        sum = i * tea_delta;\n        x += ((y << 4) + data[0]) ^ (y + sum) ^ ((y >> 5) + data[1]);\n        y += ((x << 4) + data[2]) ^ (x + sum) ^ ((x >> 5) + data[3]);\n        i++;\n    }\n\n    hash[0] += x;\n    hash[1] += y;\n}\n\nstatic uint32_t ext2_legacy_hash(const char *name, int len, int unsigned_char)\n{\n    uint32_t h0, h1 = 0x12A3FE2D, h2 = 0x37ABE8F9;\n    uint32_t multi = 0x6D22F5;\n    const unsigned char *uname = (const unsigned char *)name;\n    const signed char *sname = (const signed char *)name;\n    int val, i;\n\n    for (i = 0; i < len; i++) {\n        if (unsigned_char)\n            val = (unsigned int)*uname++;\n        else\n            val = (int)*sname++;\n\n        h0 = h2 + (h1 ^ (val * multi));\n        if (h0 & 0x80000000)\n            h0 -= 0x7FFFFFFF;\n        h2 = h1;\n        h1 = h0;\n    }\n\n    return (h1 << 1);\n}\n\nstatic void ext2_prep_hashbuf(const char *src, uint32_t slen, uint32_t *dst,\n                  int dlen, int unsigned_char)\n{\n    uint32_t padding = slen | (slen << 8) | (slen << 16) | (slen << 24);\n    uint32_t buf_val;\n    int len, i;\n    int buf_byte;\n    const unsigned char *ubuf = (const unsigned char *)src;\n    const signed char *sbuf = (const signed char *)src;\n\n    if (slen > (uint32_t)dlen)\n        len = dlen;\n    else\n        len = slen;\n\n    buf_val = padding;\n\n    for (i = 0; i < len; i++) {\n        if (unsigned_char)\n            buf_byte = (unsigned int)ubuf[i];\n        else\n            buf_byte = (int)sbuf[i];\n\n        if ((i % 4) == 0)\n            buf_val = padding;\n\n        buf_val <<= 8;\n        buf_val += buf_byte;\n\n        if ((i % 4) == 3) {\n            *dst++ = buf_val;\n            dlen -= sizeof(uint32_t);\n            buf_val = padding;\n        }\n    }\n\n    dlen -= sizeof(uint32_t);\n    if (dlen >= 0)\n        *dst++ = buf_val;\n\n    dlen -= sizeof(uint32_t);\n    while (dlen >= 0) {\n        *dst++ = padding;\n        dlen -= sizeof(uint32_t);\n    }\n}\n\nint ext2_htree_hash(const char *name, int len, const uint32_t *hash_seed,\n            int hash_version, uint32_t *hash_major,\n            uint32_t *hash_minor)\n{\n    uint32_t hash[4];\n    uint32_t data[8];\n    uint32_t major = 0, minor = 0;\n    int unsigned_char = 0;\n\n    if (!name || !hash_major)\n        return (-1);\n\n    if (len < 1 || len > 255)\n        goto error;\n\n    hash[0] = 0x67452301;\n    hash[1] = 0xEFCDAB89;\n    hash[2] = 0x98BADCFE;\n    hash[3] = 0x10325476;\n\n    if (hash_seed)\n        memcpy(hash, hash_seed, sizeof(hash));\n\n    switch (hash_version) {\n    case EXT2_HTREE_TEA_UNSIGNED:\n        unsigned_char = 1;\n        /* FALLTHRU */\n    case EXT2_HTREE_TEA:\n        while (len > 0) {\n            ext2_prep_hashbuf(name, len, data, 16, unsigned_char);\n            ext2_tea(hash, data);\n            len -= 16;\n            name += 16;\n        }\n        major = hash[0];\n        minor = hash[1];\n        break;\n    case EXT2_HTREE_LEGACY_UNSIGNED:\n        unsigned_char = 1;\n        /* FALLTHRU */\n    case EXT2_HTREE_LEGACY:\n        major = ext2_legacy_hash(name, len, unsigned_char);\n        break;\n    case EXT2_HTREE_HALF_MD4_UNSIGNED:\n        unsigned_char = 1;\n        /* FALLTHRU */\n    case EXT2_HTREE_HALF_MD4:\n        while (len > 0) {\n            ext2_prep_hashbuf(name, len, data, 32, unsigned_char);\n            ext2_half_md4(hash, data);\n            len -= 32;\n            name += 32;\n        }\n        major = hash[1];\n        minor = hash[2];\n        break;\n    default:\n        goto error;\n    }\n\n    major &= ~1;\n    if (major == (EXT2_HTREE_EOF << 1))\n        major = (EXT2_HTREE_EOF - 1) << 1;\n    *hash_major = major;\n    if (hash_minor)\n        *hash_minor = minor;\n\n    return EOK;\n\nerror:\n    *hash_major = 0;\n    if (hash_minor)\n        *hash_minor = 0;\n    return ENOTSUP;\n}\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/src/ext4_ialloc.c",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n *\n *\n * HelenOS:\n * Copyright (c) 2012 Martin Sucha\n * Copyright (c) 2012 Frantisek Princ\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_ialloc.c\n * @brief Inode allocation procedures.\n */\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_misc.h>\n#include <ext4_errno.h>\n#include <ext4_debug.h>\n\n#include <ext4_trans.h>\n#include <ext4_ialloc.h>\n#include <ext4_super.h>\n#include <ext4_crc32.h>\n#include <ext4_fs.h>\n#include <ext4_blockdev.h>\n#include <ext4_block_group.h>\n#include <ext4_bitmap.h>\n\n/**@brief  Convert i-node number to relative index in block group.\n * @param sb    Superblock\n * @param inode I-node number to be converted\n * @return Index of the i-node in the block group\n */\nstatic uint32_t ext4_ialloc_inode_to_bgidx(struct ext4_sblock *sb,\n                       uint32_t inode)\n{\n    uint32_t inodes_per_group = ext4_get32(sb, inodes_per_group);\n    return (inode - 1) % inodes_per_group;\n}\n\n/**@brief Convert relative index of i-node to absolute i-node number.\n * @param sb    Superblock\n * @param index Index to be converted\n * @return Absolute number of the i-node\n *\n */\nstatic uint32_t ext4_ialloc_bgidx_to_inode(struct ext4_sblock *sb,\n                       uint32_t index, uint32_t bgid)\n{\n    uint32_t inodes_per_group = ext4_get32(sb, inodes_per_group);\n    return bgid * inodes_per_group + (index + 1);\n}\n\n/**@brief Compute block group number from the i-node number.\n * @param sb    Superblock\n * @param inode I-node number to be found the block group for\n * @return Block group number computed from i-node number\n */\nstatic uint32_t ext4_ialloc_get_bgid_of_inode(struct ext4_sblock *sb,\n                          uint32_t inode)\n{\n    uint32_t inodes_per_group = ext4_get32(sb, inodes_per_group);\n    return (inode - 1) / inodes_per_group;\n}\n\n#if CONFIG_META_CSUM_ENABLE\nstatic uint32_t ext4_ialloc_bitmap_csum(struct ext4_sblock *sb, void *bitmap)\n{\n    uint32_t csum = 0;\n    if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) {\n        uint32_t inodes_per_group =\n            ext4_get32(sb, inodes_per_group);\n\n        /* First calculate crc32 checksum against fs uuid */\n        csum = ext4_crc32c(EXT4_CRC32_INIT, sb->uuid, sizeof(sb->uuid));\n        /* Then calculate crc32 checksum against inode bitmap */\n        csum = ext4_crc32c(csum, bitmap, (inodes_per_group + 7) / 8);\n    }\n    return csum;\n}\n#else\n#define ext4_ialloc_bitmap_csum(...) 0\n#endif\n\nvoid ext4_ialloc_set_bitmap_csum(struct ext4_sblock *sb, struct ext4_bgroup *bg,\n                 void *bitmap __unused)\n{\n    int desc_size = ext4_sb_get_desc_size(sb);\n    uint32_t csum = ext4_ialloc_bitmap_csum(sb, bitmap);\n    uint16_t lo_csum = to_le16(csum & 0xFFFF),\n         hi_csum = to_le16(csum >> 16);\n\n    if (!ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM))\n        return;\n\n    /* See if we need to assign a 32bit checksum */\n    bg->inode_bitmap_csum_lo = lo_csum;\n    if (desc_size == EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE)\n        bg->inode_bitmap_csum_hi = hi_csum;\n\n}\n\n#if CONFIG_META_CSUM_ENABLE\nstatic bool\next4_ialloc_verify_bitmap_csum(struct ext4_sblock *sb, struct ext4_bgroup *bg,\n                   void *bitmap __unused)\n{\n\n    int desc_size = ext4_sb_get_desc_size(sb);\n    uint32_t csum = ext4_ialloc_bitmap_csum(sb, bitmap);\n    uint16_t lo_csum = to_le16(csum & 0xFFFF),\n         hi_csum = to_le16(csum >> 16);\n\n    if (!ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM))\n        return true;\n\n    if (bg->inode_bitmap_csum_lo != lo_csum)\n        return false;\n\n    if (desc_size == EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE)\n        if (bg->inode_bitmap_csum_hi != hi_csum)\n            return false;\n\n    return true;\n}\n#else\n#define ext4_ialloc_verify_bitmap_csum(...) true\n#endif\n\nint ext4_ialloc_free_inode(struct ext4_fs *fs, uint32_t index, bool is_dir)\n{\n    struct ext4_sblock *sb = &fs->sb;\n\n    /* Compute index of block group and load it */\n    uint32_t block_group = ext4_ialloc_get_bgid_of_inode(sb, index);\n\n    struct ext4_block_group_ref bg_ref;\n    int rc = ext4_fs_get_block_group_ref(fs, block_group, &bg_ref);\n    if (rc != EOK)\n        return rc;\n\n    struct ext4_bgroup *bg = bg_ref.block_group;\n\n    /* Load i-node bitmap */\n    ext4_fsblk_t bitmap_block_addr =\n        ext4_bg_get_inode_bitmap(bg, sb);\n\n    struct ext4_block b;\n    rc = ext4_trans_block_get(fs->bdev, &b, bitmap_block_addr);\n    if (rc != EOK)\n        return rc;\n\n    if (!ext4_ialloc_verify_bitmap_csum(sb, bg, b.data)) {\n        ext4_dbg(DEBUG_IALLOC,\n            DBG_WARN \"Bitmap checksum failed.\"\n            \"Group: %\" PRIu32\"\\n\",\n            bg_ref.index);\n    }\n\n    /* Free i-node in the bitmap */\n    uint32_t index_in_group = ext4_ialloc_inode_to_bgidx(sb, index);\n    ext4_bmap_bit_clr(b.data, index_in_group);\n    ext4_ialloc_set_bitmap_csum(sb, bg, b.data);\n    ext4_trans_set_block_dirty(b.buf);\n\n    /* Put back the block with bitmap */\n    rc = ext4_block_set(fs->bdev, &b);\n    if (rc != EOK) {\n        /* Error in saving bitmap */\n        ext4_fs_put_block_group_ref(&bg_ref);\n        return rc;\n    }\n\n    /* If released i-node is a directory, decrement used directories count\n     */\n    if (is_dir) {\n        uint32_t bg_used_dirs = ext4_bg_get_used_dirs_count(bg, sb);\n        bg_used_dirs--;\n        ext4_bg_set_used_dirs_count(bg, sb, bg_used_dirs);\n    }\n\n    /* Update block group free inodes count */\n    uint32_t free_inodes = ext4_bg_get_free_inodes_count(bg, sb);\n    free_inodes++;\n    ext4_bg_set_free_inodes_count(bg, sb, free_inodes);\n\n    bg_ref.dirty = true;\n\n    /* Put back the modified block group */\n    rc = ext4_fs_put_block_group_ref(&bg_ref);\n    if (rc != EOK)\n        return rc;\n\n    /* Update superblock free inodes count */\n    ext4_set32(sb, free_inodes_count,\n           ext4_get32(sb, free_inodes_count) + 1);\n\n    return EOK;\n}\n\nint ext4_ialloc_alloc_inode(struct ext4_fs *fs, uint32_t *idx, bool is_dir)\n{\n    struct ext4_sblock *sb = &fs->sb;\n\n    uint32_t bgid = fs->last_inode_bg_id;\n    uint32_t bg_count = ext4_block_group_cnt(sb);\n    uint32_t sb_free_inodes = ext4_get32(sb, free_inodes_count);\n    bool rewind = false;\n\n    /* Try to find free i-node in all block groups */\n    while (bgid <= bg_count) {\n\n        if (bgid == bg_count) {\n            if (rewind)\n                break;\n            bg_count = fs->last_inode_bg_id;\n            bgid = 0;\n            rewind = true;\n            continue;\n        }\n\n        /* Load block group to check */\n        struct ext4_block_group_ref bg_ref;\n        int rc = ext4_fs_get_block_group_ref(fs, bgid, &bg_ref);\n        if (rc != EOK)\n            return rc;\n\n        struct ext4_bgroup *bg = bg_ref.block_group;\n\n        /* Read necessary values for algorithm */\n        uint32_t free_inodes = ext4_bg_get_free_inodes_count(bg, sb);\n        uint32_t used_dirs = ext4_bg_get_used_dirs_count(bg, sb);\n\n        /* Check if this block group is good candidate for allocation */\n        if (free_inodes > 0) {\n            /* Load block with bitmap */\n            ext4_fsblk_t bmp_blk_add = ext4_bg_get_inode_bitmap(bg, sb);\n\n            struct ext4_block b;\n            rc = ext4_trans_block_get(fs->bdev, &b, bmp_blk_add);\n            if (rc != EOK) {\n                ext4_fs_put_block_group_ref(&bg_ref);\n                return rc;\n            }\n\n            if (!ext4_ialloc_verify_bitmap_csum(sb, bg, b.data)) {\n                ext4_dbg(DEBUG_IALLOC,\n                    DBG_WARN \"Bitmap checksum failed.\"\n                    \"Group: %\" PRIu32\"\\n\",\n                    bg_ref.index);\n            }\n\n            /* Try to allocate i-node in the bitmap */\n            uint32_t inodes_in_bg;\n            uint32_t idx_in_bg;\n\n            inodes_in_bg = ext4_inodes_in_group_cnt(sb, bgid);\n            rc = ext4_bmap_bit_find_clr(b.data, 0, inodes_in_bg,\n                            &idx_in_bg);\n            /* Block group has not any free i-node */\n            if (rc == ENOSPC) {\n                rc = ext4_block_set(fs->bdev, &b);\n                if (rc != EOK) {\n                    ext4_fs_put_block_group_ref(&bg_ref);\n                    return rc;\n                }\n\n                rc = ext4_fs_put_block_group_ref(&bg_ref);\n                if (rc != EOK)\n                    return rc;\n\n                continue;\n            }\n\n            ext4_bmap_bit_set(b.data, idx_in_bg);\n\n            /* Free i-node found, save the bitmap */\n            ext4_ialloc_set_bitmap_csum(sb,bg,\n                            b.data);\n            ext4_trans_set_block_dirty(b.buf);\n\n            ext4_block_set(fs->bdev, &b);\n            if (rc != EOK) {\n                ext4_fs_put_block_group_ref(&bg_ref);\n                return rc;\n            }\n\n            /* Modify filesystem counters */\n            free_inodes--;\n            ext4_bg_set_free_inodes_count(bg, sb, free_inodes);\n\n            /* Increment used directories counter */\n            if (is_dir) {\n                used_dirs++;\n                ext4_bg_set_used_dirs_count(bg, sb, used_dirs);\n            }\n\n            /* Decrease unused inodes count */\n            uint32_t unused =\n                ext4_bg_get_itable_unused(bg, sb);\n\n            uint32_t free = inodes_in_bg - unused;\n\n            if (idx_in_bg >= free) {\n                unused = inodes_in_bg - (idx_in_bg + 1);\n                ext4_bg_set_itable_unused(bg, sb, unused);\n            }\n\n            /* Save modified block group */\n            bg_ref.dirty = true;\n\n            rc = ext4_fs_put_block_group_ref(&bg_ref);\n            if (rc != EOK)\n                return rc;\n\n            /* Update superblock */\n            sb_free_inodes--;\n            ext4_set32(sb, free_inodes_count, sb_free_inodes);\n\n            /* Compute the absolute i-nodex number */\n            *idx = ext4_ialloc_bgidx_to_inode(sb, idx_in_bg, bgid);\n\n            fs->last_inode_bg_id = bgid;\n\n            return EOK;\n        }\n\n        /* Block group not modified, put it and jump to the next block\n         * group */\n        ext4_fs_put_block_group_ref(&bg_ref);\n        if (rc != EOK)\n            return rc;\n\n        ++bgid;\n    }\n\n    return ENOSPC;\n}\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/src/ext4_inode.c",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n *\n *\n * HelenOS:\n * Copyright (c) 2012 Martin Sucha\n * Copyright (c) 2012 Frantisek Princ\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_inode.c\n * @brief Inode handle functions\n */\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_misc.h>\n#include <ext4_errno.h>\n#include <ext4_debug.h>\n\n#include <ext4_inode.h>\n#include <ext4_super.h>\n\n/**@brief  Compute number of bits for block count.\n * @param block_size Filesystem block_size\n * @return Number of bits\n */\nstatic uint32_t ext4_inode_block_bits_count(uint32_t block_size)\n{\n    uint32_t bits = 8;\n    uint32_t size = block_size;\n\n    do {\n        bits++;\n        size = size >> 1;\n    } while (size > 256);\n\n    return bits;\n}\n\nuint32_t ext4_inode_get_mode(struct ext4_sblock *sb, struct ext4_inode *inode)\n{\n    uint32_t v = to_le16(inode->mode);\n\n    if (ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_HURD) {\n        v |= ((uint32_t)to_le16(inode->osd2.hurd2.mode_high)) << 16;\n    }\n\n    return v;\n}\n\nvoid ext4_inode_set_mode(struct ext4_sblock *sb, struct ext4_inode *inode,\n             uint32_t mode)\n{\n    inode->mode = to_le16((mode << 16) >> 16);\n\n    if (ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_HURD)\n        inode->osd2.hurd2.mode_high = to_le16(mode >> 16);\n}\n\nuint32_t ext4_inode_get_uid(struct ext4_inode *inode)\n{\n    return to_le32(inode->uid);\n}\n\nvoid ext4_inode_set_uid(struct ext4_inode *inode, uint32_t uid)\n{\n    inode->uid = to_le32(uid);\n}\n\nuint64_t ext4_inode_get_size(struct ext4_sblock *sb, struct ext4_inode *inode)\n{\n    uint64_t v = to_le32(inode->size_lo);\n\n    if ((ext4_get32(sb, rev_level) > 0) &&\n        (ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_FILE)))\n        v |= ((uint64_t)to_le32(inode->size_hi)) << 32;\n\n    return v;\n}\n\nvoid ext4_inode_set_size(struct ext4_inode *inode, uint64_t size)\n{\n    inode->size_lo = to_le32((size << 32) >> 32);\n    inode->size_hi = to_le32(size >> 32);\n}\n\nuint32_t ext4_inode_get_csum(struct ext4_sblock *sb, struct ext4_inode *inode)\n{\n    uint16_t inode_size = ext4_get16(sb, inode_size);\n    uint32_t v = to_le16(inode->osd2.linux2.checksum_lo);\n\n    if (inode_size > EXT4_GOOD_OLD_INODE_SIZE)\n        v |= ((uint32_t)to_le16(inode->checksum_hi)) << 16;\n\n    return v;\n}\n\nvoid ext4_inode_set_csum(struct ext4_sblock *sb, struct ext4_inode *inode,\n            uint32_t checksum)\n{\n    uint16_t inode_size = ext4_get16(sb, inode_size);\n    inode->osd2.linux2.checksum_lo =\n        to_le16((checksum << 16) >> 16);\n\n    if (inode_size > EXT4_GOOD_OLD_INODE_SIZE)\n        inode->checksum_hi = to_le16(checksum >> 16);\n\n}\n\nuint32_t ext4_inode_get_access_time(struct ext4_inode *inode)\n{\n    return to_le32(inode->access_time);\n}\nvoid ext4_inode_set_access_time(struct ext4_inode *inode, uint32_t time)\n{\n    inode->access_time = to_le32(time);\n}\n\nuint32_t ext4_inode_get_change_inode_time(struct ext4_inode *inode)\n{\n    return to_le32(inode->change_inode_time);\n}\nvoid ext4_inode_set_change_inode_time(struct ext4_inode *inode, uint32_t time)\n{\n    inode->change_inode_time = to_le32(time);\n}\n\nuint32_t ext4_inode_get_modif_time(struct ext4_inode *inode)\n{\n    return to_le32(inode->modification_time);\n}\n\nvoid ext4_inode_set_modif_time(struct ext4_inode *inode, uint32_t time)\n{\n    inode->modification_time = to_le32(time);\n}\n\nuint32_t ext4_inode_get_del_time(struct ext4_inode *inode)\n{\n    return to_le32(inode->deletion_time);\n}\n\nvoid ext4_inode_set_del_time(struct ext4_inode *inode, uint32_t time)\n{\n    inode->deletion_time = to_le32(time);\n}\n\nuint32_t ext4_inode_get_gid(struct ext4_inode *inode)\n{\n    return to_le32(inode->gid);\n}\nvoid ext4_inode_set_gid(struct ext4_inode *inode, uint32_t gid)\n{\n    inode->gid = to_le32(gid);\n}\n\nuint16_t ext4_inode_get_links_cnt(struct ext4_inode *inode)\n{\n    return to_le16(inode->links_count);\n}\nvoid ext4_inode_set_links_cnt(struct ext4_inode *inode, uint16_t cnt)\n{\n    inode->links_count = to_le16(cnt);\n}\n\nuint64_t ext4_inode_get_blocks_count(struct ext4_sblock *sb,\n                     struct ext4_inode *inode)\n{\n    uint64_t cnt = to_le32(inode->blocks_count_lo);\n\n    if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_HUGE_FILE)) {\n\n        /* 48-bit field */\n        cnt |= (uint64_t)to_le16(inode->osd2.linux2.blocks_high) << 32;\n\n        if (ext4_inode_has_flag(inode, EXT4_INODE_FLAG_HUGE_FILE)) {\n\n            uint32_t block_count = ext4_sb_get_block_size(sb);\n            uint32_t b = ext4_inode_block_bits_count(block_count);\n            return cnt << (b - 9);\n        }\n    }\n\n    return cnt;\n}\n\nint ext4_inode_set_blocks_count(struct ext4_sblock *sb,\n                struct ext4_inode *inode, uint64_t count)\n{\n    /* 32-bit maximum */\n    uint64_t max = 0;\n    max = ~max >> 32;\n\n    if (count <= max) {\n        inode->blocks_count_lo = to_le32((uint32_t)count);\n        inode->osd2.linux2.blocks_high = 0;\n        ext4_inode_clear_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);\n\n        return EOK;\n    }\n\n    /* Check if there can be used huge files (many blocks) */\n    if (!ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_HUGE_FILE))\n        return EINVAL;\n\n    /* 48-bit maximum */\n    max = 0;\n    max = ~max >> 16;\n\n    if (count <= max) {\n        inode->blocks_count_lo = to_le32((uint32_t)count);\n        inode->osd2.linux2.blocks_high = to_le16((uint16_t)(count >> 32));\n        ext4_inode_clear_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);\n    } else {\n        uint32_t block_count = ext4_sb_get_block_size(sb);\n        uint32_t block_bits =ext4_inode_block_bits_count(block_count);\n\n        ext4_inode_set_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);\n        count = count >> (block_bits - 9);\n        inode->blocks_count_lo = to_le32((uint32_t)count);\n        inode->osd2.linux2.blocks_high = to_le16((uint16_t)(count >> 32));\n    }\n\n    return EOK;\n}\n\nuint32_t ext4_inode_get_flags(struct ext4_inode *inode)\n{\n    return to_le32(inode->flags);\n}\nvoid ext4_inode_set_flags(struct ext4_inode *inode, uint32_t flags)\n{\n    inode->flags = to_le32(flags);\n}\n\nuint32_t ext4_inode_get_generation(struct ext4_inode *inode)\n{\n    return to_le32(inode->generation);\n}\nvoid ext4_inode_set_generation(struct ext4_inode *inode, uint32_t gen)\n{\n    inode->generation = to_le32(gen);\n}\n\nuint16_t ext4_inode_get_extra_isize(struct ext4_sblock *sb,\n                    struct ext4_inode *inode)\n{\n    uint16_t inode_size = ext4_get16(sb, inode_size);\n    if (inode_size > EXT4_GOOD_OLD_INODE_SIZE)\n        return to_le16(inode->extra_isize);\n    else\n        return 0;\n}\n\nvoid ext4_inode_set_extra_isize(struct ext4_sblock *sb,\n                struct ext4_inode *inode,\n                uint16_t size)\n{\n    uint16_t inode_size = ext4_get16(sb, inode_size);\n    if (inode_size > EXT4_GOOD_OLD_INODE_SIZE)\n        inode->extra_isize = to_le16(size);\n}\n\nuint64_t ext4_inode_get_file_acl(struct ext4_inode *inode,\n                 struct ext4_sblock *sb)\n{\n    uint64_t v = to_le32(inode->file_acl_lo);\n\n    if (ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_LINUX)\n        v |= (uint32_t)to_le16(inode->osd2.linux2.file_acl_high) << 16;\n\n    return v;\n}\n\nvoid ext4_inode_set_file_acl(struct ext4_inode *inode, struct ext4_sblock *sb,\n                 uint64_t acl)\n{\n    inode->file_acl_lo = to_le32((acl << 32) >> 32);\n\n    if (ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_LINUX)\n        inode->osd2.linux2.file_acl_high = to_le16((uint16_t)(acl >> 32));\n}\n\nuint32_t ext4_inode_get_direct_block(struct ext4_inode *inode, uint32_t idx)\n{\n    return to_le32(inode->blocks[idx]);\n}\nvoid ext4_inode_set_direct_block(struct ext4_inode *inode, uint32_t idx,\n                 uint32_t block)\n{\n    inode->blocks[idx] = to_le32(block);\n}\n\nuint32_t ext4_inode_get_indirect_block(struct ext4_inode *inode, uint32_t idx)\n{\n    return to_le32(inode->blocks[idx + EXT4_INODE_INDIRECT_BLOCK]);\n}\n\nvoid ext4_inode_set_indirect_block(struct ext4_inode *inode, uint32_t idx,\n                   uint32_t block)\n{\n    inode->blocks[idx + EXT4_INODE_INDIRECT_BLOCK] = to_le32(block);\n}\n\nuint32_t ext4_inode_get_dev(struct ext4_inode *inode)\n{\n    uint32_t dev_0, dev_1;\n    dev_0 = ext4_inode_get_direct_block(inode, 0);\n    dev_1 = ext4_inode_get_direct_block(inode, 1);\n\n    if (dev_0)\n        return dev_0;\n    else\n        return dev_1;\n}\n\nvoid ext4_inode_set_dev(struct ext4_inode *inode, uint32_t dev)\n{\n    if (dev & ~0xFFFF)\n        ext4_inode_set_direct_block(inode, 1, dev);\n    else\n        ext4_inode_set_direct_block(inode, 0, dev);\n}\n\nuint32_t ext4_inode_type(struct ext4_sblock *sb, struct ext4_inode *inode)\n{\n    return (ext4_inode_get_mode(sb, inode) & EXT4_INODE_MODE_TYPE_MASK);\n}\n\nbool ext4_inode_is_type(struct ext4_sblock *sb, struct ext4_inode *inode,\n            uint32_t type)\n{\n    return ext4_inode_type(sb, inode) == type;\n}\n\nbool ext4_inode_has_flag(struct ext4_inode *inode, uint32_t f)\n{\n    return ext4_inode_get_flags(inode) & f;\n}\n\nvoid ext4_inode_clear_flag(struct ext4_inode *inode, uint32_t f)\n{\n    uint32_t flags = ext4_inode_get_flags(inode);\n    flags = flags & (~f);\n    ext4_inode_set_flags(inode, flags);\n}\n\nvoid ext4_inode_set_flag(struct ext4_inode *inode, uint32_t f)\n{\n    uint32_t flags = ext4_inode_get_flags(inode);\n    flags = flags | f;\n    ext4_inode_set_flags(inode, flags);\n}\n\nbool ext4_inode_can_truncate(struct ext4_sblock *sb, struct ext4_inode *inode)\n{\n    if ((ext4_inode_has_flag(inode, EXT4_INODE_FLAG_APPEND)) ||\n        (ext4_inode_has_flag(inode, EXT4_INODE_FLAG_IMMUTABLE)))\n        return false;\n\n    if ((ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_FILE)) ||\n        (ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_DIRECTORY)) ||\n        (ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_SOFTLINK)))\n        return true;\n\n    return false;\n}\n\nstruct ext4_extent_header *\next4_inode_get_extent_header(struct ext4_inode *inode)\n{\n    return (struct ext4_extent_header *)inode->blocks;\n}\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/src/ext4_journal.c",
    "content": "/*\n * Copyright (c) 2015 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * Copyright (c) 2015 Kaho Ng (ngkaho1234@gmail.com)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_journal.c\n * @brief Journal handle functions\n */\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_misc.h>\n#include <ext4_errno.h>\n#include <ext4_debug.h>\n\n#include <ext4_fs.h>\n#include <ext4_super.h>\n#include <ext4_journal.h>\n#include <ext4_blockdev.h>\n#include <ext4_crc32.h>\n#include <ext4_journal.h>\n\n#include <string.h>\n#include <stdlib.h>\n\n/**@brief  Revoke entry during journal replay.*/\nstruct revoke_entry {\n    /**@brief  Block number not to be replayed.*/\n    ext4_fsblk_t block;\n\n    /**@brief  For any transaction id smaller\n     *         than trans_id, records of @block\n     *         in those transactions should not\n     *         be replayed.*/\n    uint32_t trans_id;\n\n    /**@brief  Revoke tree node.*/\n    RB_ENTRY(revoke_entry) revoke_node;\n};\n\n/**@brief  Valid journal replay information.*/\nstruct recover_info {\n    /**@brief  Starting transaction id.*/\n    uint32_t start_trans_id;\n\n    /**@brief  Ending transaction id.*/\n    uint32_t last_trans_id;\n\n    /**@brief  Used as internal argument.*/\n    uint32_t this_trans_id;\n\n    /**@brief  No of transactions went through.*/\n    uint32_t trans_cnt;\n\n    /**@brief  RB-Tree storing revoke entries.*/\n    RB_HEAD(jbd_revoke, revoke_entry) revoke_root;\n};\n\n/**@brief  Journal replay internal arguments.*/\nstruct replay_arg {\n    /**@brief  Journal replay information.*/\n    struct recover_info *info;\n\n    /**@brief  Current block we are on.*/\n    uint32_t *this_block;\n\n    /**@brief  Current trans_id we are on.*/\n    uint32_t this_trans_id;\n};\n\n/* Make sure we wrap around the log correctly! */\n#define wrap(sb, var)                       \\\ndo {                                    \\\n    if (var >= jbd_get32((sb), maxlen))                 \\\n        var -= (jbd_get32((sb), maxlen) - jbd_get32((sb), first));  \\\n} while (0)\n\nstatic inline int32_t\ntrans_id_diff(uint32_t x, uint32_t y)\n{\n    int32_t diff = x - y;\n    return diff;\n}\n\nstatic int\njbd_revoke_entry_cmp(struct revoke_entry *a, struct revoke_entry *b)\n{\n    if (a->block > b->block)\n        return 1;\n    else if (a->block < b->block)\n        return -1;\n    return 0;\n}\n\nstatic int\njbd_block_rec_cmp(struct jbd_block_rec *a, struct jbd_block_rec *b)\n{\n    if (a->lba > b->lba)\n        return 1;\n    else if (a->lba < b->lba)\n        return -1;\n    return 0;\n}\n\nstatic int\njbd_revoke_rec_cmp(struct jbd_revoke_rec *a, struct jbd_revoke_rec *b)\n{\n    if (a->lba > b->lba)\n        return 1;\n    else if (a->lba < b->lba)\n        return -1;\n    return 0;\n}\n\nRB_GENERATE_INTERNAL(jbd_revoke, revoke_entry, revoke_node,\n             jbd_revoke_entry_cmp, static inline)\nRB_GENERATE_INTERNAL(jbd_block, jbd_block_rec, block_rec_node,\n             jbd_block_rec_cmp, static inline)\nRB_GENERATE_INTERNAL(jbd_revoke_tree, jbd_revoke_rec, revoke_node,\n             jbd_revoke_rec_cmp, static inline)\n\n#define jbd_alloc_revoke_entry() ext4_calloc(1, sizeof(struct revoke_entry))\n#define jbd_free_revoke_entry(addr) ext4_free(addr)\n\nstatic int jbd_has_csum(struct jbd_sb *jbd_sb)\n{\n    if (JBD_HAS_INCOMPAT_FEATURE(jbd_sb, JBD_FEATURE_INCOMPAT_CSUM_V2))\n        return 2;\n\n    if (JBD_HAS_INCOMPAT_FEATURE(jbd_sb, JBD_FEATURE_INCOMPAT_CSUM_V3))\n        return 3;\n\n    return 0;\n}\n\n#if CONFIG_META_CSUM_ENABLE\nstatic uint32_t jbd_sb_csum(struct jbd_sb *jbd_sb)\n{\n    uint32_t checksum = 0;\n\n    if (jbd_has_csum(jbd_sb)) {\n        uint32_t orig_checksum = jbd_sb->checksum;\n        jbd_set32(jbd_sb, checksum, 0);\n        /* Calculate crc32c checksum against tho whole superblock */\n        checksum = ext4_crc32c(EXT4_CRC32_INIT, jbd_sb,\n                JBD_SUPERBLOCK_SIZE);\n        jbd_sb->checksum = orig_checksum;\n    }\n    return checksum;\n}\n#else\n#define jbd_sb_csum(...) 0\n#endif\n\nstatic void jbd_sb_csum_set(struct jbd_sb *jbd_sb)\n{\n    if (!jbd_has_csum(jbd_sb))\n        return;\n\n    jbd_set32(jbd_sb, checksum, jbd_sb_csum(jbd_sb));\n}\n\n#if CONFIG_META_CSUM_ENABLE\nstatic bool\njbd_verify_sb_csum(struct jbd_sb *jbd_sb)\n{\n    if (!jbd_has_csum(jbd_sb))\n        return true;\n\n    return jbd_sb_csum(jbd_sb) == jbd_get32(jbd_sb, checksum);\n}\n#else\n#define jbd_verify_sb_csum(...) true\n#endif\n\n#if CONFIG_META_CSUM_ENABLE\nstatic uint32_t jbd_meta_csum(struct jbd_fs *jbd_fs,\n                  struct jbd_bhdr *bhdr)\n{\n    uint32_t checksum = 0;\n\n    if (jbd_has_csum(&jbd_fs->sb)) {\n        uint32_t block_size = jbd_get32(&jbd_fs->sb, blocksize);\n        struct jbd_block_tail *tail =\n            (struct jbd_block_tail *)((char *)bhdr + block_size -\n                sizeof(struct jbd_block_tail));\n        uint32_t orig_checksum = tail->checksum;\n        tail->checksum = 0;\n\n        /* First calculate crc32c checksum against fs uuid */\n        checksum = ext4_crc32c(EXT4_CRC32_INIT, jbd_fs->sb.uuid,\n                       sizeof(jbd_fs->sb.uuid));\n        /* Calculate crc32c checksum against tho whole block */\n        checksum = ext4_crc32c(checksum, bhdr,\n                block_size);\n        tail->checksum = orig_checksum;\n    }\n    return checksum;\n}\n#else\n#define jbd_meta_csum(...) 0\n#endif\n\nstatic void jbd_meta_csum_set(struct jbd_fs *jbd_fs,\n                  struct jbd_bhdr *bhdr)\n{\n    uint32_t block_size = jbd_get32(&jbd_fs->sb, blocksize);\n    struct jbd_block_tail *tail = (struct jbd_block_tail *)\n                ((char *)bhdr + block_size -\n                sizeof(struct jbd_block_tail));\n    if (!jbd_has_csum(&jbd_fs->sb))\n        return;\n\n    tail->checksum = to_be32(jbd_meta_csum(jbd_fs, bhdr));\n}\n\n#if CONFIG_META_CSUM_ENABLE\nstatic bool\njbd_verify_meta_csum(struct jbd_fs *jbd_fs,\n             struct jbd_bhdr *bhdr)\n{\n    uint32_t block_size = jbd_get32(&jbd_fs->sb, blocksize);\n    struct jbd_block_tail *tail = (struct jbd_block_tail *)\n                ((char *)bhdr + block_size -\n                sizeof(struct jbd_block_tail));\n    if (!jbd_has_csum(&jbd_fs->sb))\n        return true;\n\n    return jbd_meta_csum(jbd_fs, bhdr) == to_be32(tail->checksum);\n}\n#else\n#define jbd_verify_meta_csum(...) true\n#endif\n\n#if CONFIG_META_CSUM_ENABLE\nstatic uint32_t jbd_commit_csum(struct jbd_fs *jbd_fs,\n                  struct jbd_commit_header *header)\n{\n    uint32_t checksum = 0;\n\n    if (jbd_has_csum(&jbd_fs->sb)) {\n        uint8_t orig_checksum_type = header->chksum_type,\n             orig_checksum_size = header->chksum_size;\n        uint32_t orig_checksum = header->chksum[0];\n        uint32_t block_size = jbd_get32(&jbd_fs->sb, blocksize);\n        header->chksum_type = 0;\n        header->chksum_size = 0;\n        header->chksum[0] = 0;\n\n        /* First calculate crc32c checksum against fs uuid */\n        checksum = ext4_crc32c(EXT4_CRC32_INIT, jbd_fs->sb.uuid,\n                       sizeof(jbd_fs->sb.uuid));\n        /* Calculate crc32c checksum against tho whole block */\n        checksum = ext4_crc32c(checksum, header,\n                block_size);\n\n        header->chksum_type = orig_checksum_type;\n        header->chksum_size = orig_checksum_size;\n        header->chksum[0] = orig_checksum;\n    }\n    return checksum;\n}\n#else\n#define jbd_commit_csum(...) 0\n#endif\n\nstatic void jbd_commit_csum_set(struct jbd_fs *jbd_fs,\n                  struct jbd_commit_header *header)\n{\n    if (!jbd_has_csum(&jbd_fs->sb))\n        return;\n\n    header->chksum_type = 0;\n    header->chksum_size = 0;\n    header->chksum[0] = jbd_commit_csum(jbd_fs, header);\n}\n\n#if CONFIG_META_CSUM_ENABLE\nstatic bool jbd_verify_commit_csum(struct jbd_fs *jbd_fs,\n                   struct jbd_commit_header *header)\n{\n    if (!jbd_has_csum(&jbd_fs->sb))\n        return true;\n\n    return header->chksum[0] == to_be32(jbd_commit_csum(jbd_fs,\n                        header));\n}\n#else\n#define jbd_verify_commit_csum(...) true\n#endif\n\n#if CONFIG_META_CSUM_ENABLE\n/*\n * NOTE: We only make use of @csum parameter when\n *       JBD_FEATURE_COMPAT_CHECKSUM is enabled.\n */\nstatic uint32_t jbd_block_csum(struct jbd_fs *jbd_fs, const void *buf,\n                   uint32_t csum,\n                   uint32_t sequence)\n{\n    uint32_t checksum = 0;\n\n    if (jbd_has_csum(&jbd_fs->sb)) {\n        uint32_t block_size = jbd_get32(&jbd_fs->sb, blocksize);\n        /* First calculate crc32c checksum against fs uuid */\n        checksum = ext4_crc32c(EXT4_CRC32_INIT, jbd_fs->sb.uuid,\n                       sizeof(jbd_fs->sb.uuid));\n        /* Then calculate crc32c checksum against sequence no. */\n        checksum = ext4_crc32c(checksum, &sequence,\n                sizeof(uint32_t));\n        /* Calculate crc32c checksum against tho whole block */\n        checksum = ext4_crc32c(checksum, buf,\n                block_size);\n    } else if (JBD_HAS_INCOMPAT_FEATURE(&jbd_fs->sb,\n                     JBD_FEATURE_COMPAT_CHECKSUM)) {\n        uint32_t block_size = jbd_get32(&jbd_fs->sb, blocksize);\n        /* Calculate crc32c checksum against tho whole block */\n        checksum = ext4_crc32(csum, buf,\n                block_size);\n    }\n    return checksum;\n}\n#else\n#define jbd_block_csum(...) 0\n#endif\n\nstatic void jbd_block_tag_csum_set(struct jbd_fs *jbd_fs, void *__tag,\n                   uint32_t checksum)\n{\n    int ver = jbd_has_csum(&jbd_fs->sb);\n    if (!ver)\n        return;\n\n    if (ver == 2) {\n        struct jbd_block_tag *tag = __tag;\n        tag->checksum = (uint16_t)to_be32(checksum);\n    } else {\n        struct jbd_block_tag3 *tag = __tag;\n        tag->checksum = to_be32(checksum);\n    }\n}\n\n/**@brief  Write jbd superblock to disk.\n * @param  jbd_fs jbd filesystem\n * @param  s jbd superblock\n * @return standard error code*/\nstatic int jbd_sb_write(struct jbd_fs *jbd_fs, struct jbd_sb *s)\n{\n    int rc;\n    struct ext4_fs *fs = jbd_fs->inode_ref.fs;\n    uint64_t offset;\n    ext4_fsblk_t fblock;\n    rc = jbd_inode_bmap(jbd_fs, 0, &fblock);\n    if (rc != EOK)\n        return rc;\n\n    jbd_sb_csum_set(s);\n    offset = fblock * ext4_sb_get_block_size(&fs->sb);\n    return ext4_block_writebytes(fs->bdev, offset, s,\n                     EXT4_SUPERBLOCK_SIZE);\n}\n\n/**@brief  Read jbd superblock from disk.\n * @param  jbd_fs jbd filesystem\n * @param  s jbd superblock\n * @return standard error code*/\nstatic int jbd_sb_read(struct jbd_fs *jbd_fs, struct jbd_sb *s)\n{\n    int rc;\n    struct ext4_fs *fs = jbd_fs->inode_ref.fs;\n    uint64_t offset;\n    ext4_fsblk_t fblock;\n    rc = jbd_inode_bmap(jbd_fs, 0, &fblock);\n    if (rc != EOK)\n        return rc;\n\n    offset = fblock * ext4_sb_get_block_size(&fs->sb);\n    return ext4_block_readbytes(fs->bdev, offset, s,\n                    EXT4_SUPERBLOCK_SIZE);\n}\n\n/**@brief  Verify jbd superblock.\n * @param  sb jbd superblock\n * @return true if jbd superblock is valid */\nstatic bool jbd_verify_sb(struct jbd_sb *sb)\n{\n    struct jbd_bhdr *header = &sb->header;\n    if (jbd_get32(header, magic) != JBD_MAGIC_NUMBER)\n        return false;\n\n    if (jbd_get32(header, blocktype) != JBD_SUPERBLOCK &&\n        jbd_get32(header, blocktype) != JBD_SUPERBLOCK_V2)\n        return false;\n\n    return jbd_verify_sb_csum(sb);\n}\n\n/**@brief  Write back dirty jbd superblock to disk.\n * @param  jbd_fs jbd filesystem\n * @return standard error code*/\nstatic int jbd_write_sb(struct jbd_fs *jbd_fs)\n{\n    int rc = EOK;\n    if (jbd_fs->dirty) {\n        rc = jbd_sb_write(jbd_fs, &jbd_fs->sb);\n        if (rc != EOK)\n            return rc;\n\n        jbd_fs->dirty = false;\n    }\n    return rc;\n}\n\n/**@brief  Get reference to jbd filesystem.\n * @param  fs Filesystem to load journal of\n * @param  jbd_fs jbd filesystem\n * @return standard error code*/\nint jbd_get_fs(struct ext4_fs *fs,\n           struct jbd_fs *jbd_fs)\n{\n    int rc;\n    uint32_t journal_ino;\n\n    memset(jbd_fs, 0, sizeof(struct jbd_fs));\n    /* See if there is journal inode on this filesystem.*/\n    /* FIXME: detection on existance ofbkejournal bdev is\n     *        missing.*/\n    journal_ino = ext4_get32(&fs->sb, journal_inode_number);\n\n    rc = ext4_fs_get_inode_ref(fs,\n                   journal_ino,\n                   &jbd_fs->inode_ref);\n    if (rc != EOK)\n        return rc;\n\n    rc = jbd_sb_read(jbd_fs, &jbd_fs->sb);\n    if (rc != EOK)\n        goto Error;\n\n    if (!jbd_verify_sb(&jbd_fs->sb)) {\n        rc = EIO;\n        goto Error;\n    }\n\n    if (rc == EOK)\n        jbd_fs->bdev = fs->bdev;\n\n    return rc;\nError:\n    ext4_fs_put_inode_ref(&jbd_fs->inode_ref);\n    memset(jbd_fs, 0, sizeof(struct jbd_fs));\n\n    return rc;\n}\n\n/**@brief  Put reference of jbd filesystem.\n * @param  jbd_fs jbd filesystem\n * @return standard error code*/\nint jbd_put_fs(struct jbd_fs *jbd_fs)\n{\n    int rc = EOK;\n    rc = jbd_write_sb(jbd_fs);\n\n    ext4_fs_put_inode_ref(&jbd_fs->inode_ref);\n    return rc;\n}\n\n/**@brief  Data block lookup helper.\n * @param  jbd_fs jbd filesystem\n * @param  iblock block index\n * @param  fblock logical block address\n * @return standard error code*/\nint jbd_inode_bmap(struct jbd_fs *jbd_fs,\n           ext4_lblk_t iblock,\n           ext4_fsblk_t *fblock)\n{\n    int rc = ext4_fs_get_inode_dblk_idx(\n            &jbd_fs->inode_ref,\n            iblock,\n            fblock,\n            false);\n    return rc;\n}\n\n/**@brief   jbd block get function (through cache).\n * @param   jbd_fs jbd filesystem\n * @param   block block descriptor\n * @param   fblock jbd logical block address\n * @return  standard error code*/\nstatic int jbd_block_get(struct jbd_fs *jbd_fs,\n          struct ext4_block *block,\n          ext4_fsblk_t fblock)\n{\n    /* TODO: journal device. */\n    int rc;\n    struct ext4_blockdev *bdev = jbd_fs->bdev;\n    ext4_lblk_t iblock = (ext4_lblk_t)fblock;\n\n    /* Lookup the logical block address of\n     * fblock.*/\n    rc = jbd_inode_bmap(jbd_fs, iblock,\n                &fblock);\n    if (rc != EOK)\n        return rc;\n\n    rc = ext4_block_get(bdev, block, fblock);\n\n    /* If succeeded, mark buffer as BC_FLUSH to indicate\n     * that data should be written to disk immediately.*/\n    if (rc == EOK) {\n        ext4_bcache_set_flag(block->buf, BC_FLUSH);\n        /* As we don't want to occupy too much space\n         * in block cache, we set this buffer BC_TMP.*/\n        ext4_bcache_set_flag(block->buf, BC_TMP);\n    }\n\n    return rc;\n}\n\n/**@brief   jbd block get function (through cache, don't read).\n * @param   jbd_fs jbd filesystem\n * @param   block block descriptor\n * @param   fblock jbd logical block address\n * @return  standard error code*/\nstatic int jbd_block_get_noread(struct jbd_fs *jbd_fs,\n             struct ext4_block *block,\n             ext4_fsblk_t fblock)\n{\n    /* TODO: journal device. */\n    int rc;\n    struct ext4_blockdev *bdev = jbd_fs->bdev;\n    ext4_lblk_t iblock = (ext4_lblk_t)fblock;\n    rc = jbd_inode_bmap(jbd_fs, iblock,\n                &fblock);\n    if (rc != EOK)\n        return rc;\n\n    rc = ext4_block_get_noread(bdev, block, fblock);\n    if (rc == EOK)\n        ext4_bcache_set_flag(block->buf, BC_FLUSH);\n\n    return rc;\n}\n\n/**@brief   jbd block set procedure (through cache).\n * @param   jbd_fs jbd filesystem\n * @param   block block descriptor\n * @return  standard error code*/\nstatic int jbd_block_set(struct jbd_fs *jbd_fs,\n          struct ext4_block *block)\n{\n    struct ext4_blockdev *bdev = jbd_fs->bdev;\n    return ext4_block_set(bdev, block);\n}\n\n/**@brief  helper functions to calculate\n *         block tag size, not including UUID part.\n * @param  jbd_fs jbd filesystem\n * @return tag size in bytes*/\nstatic int jbd_tag_bytes(struct jbd_fs *jbd_fs)\n{\n    int size;\n\n    /* It is very easy to deal with the case which\n     * JBD_FEATURE_INCOMPAT_CSUM_V3 is enabled.*/\n    if (JBD_HAS_INCOMPAT_FEATURE(&jbd_fs->sb,\n                     JBD_FEATURE_INCOMPAT_CSUM_V3))\n        return sizeof(struct jbd_block_tag3);\n\n    size = sizeof(struct jbd_block_tag);\n\n    /* If JBD_FEATURE_INCOMPAT_CSUM_V2 is enabled,\n     * add 2 bytes to size.*/\n    if (JBD_HAS_INCOMPAT_FEATURE(&jbd_fs->sb,\n                     JBD_FEATURE_INCOMPAT_CSUM_V2))\n        size += sizeof(uint16_t);\n\n    if (JBD_HAS_INCOMPAT_FEATURE(&jbd_fs->sb,\n                     JBD_FEATURE_INCOMPAT_64BIT))\n        return size;\n\n    /* If block number is 4 bytes in size,\n     * minus 4 bytes from size */\n    return size - sizeof(uint32_t);\n}\n\n/**@brief  Tag information. */\nstruct tag_info {\n    /**@brief  Tag size in bytes, including UUID part.*/\n    int tag_bytes;\n\n    /**@brief  block number stored in this tag.*/\n    ext4_fsblk_t block;\n\n    /**@brief  Is the first 4 bytes of block equals to\n     *     JBD_MAGIC_NUMBER? */\n    bool is_escape;\n\n    /**@brief  whether UUID part exists or not.*/\n    bool uuid_exist;\n\n    /**@brief  UUID content if UUID part exists.*/\n    uint8_t uuid[UUID_SIZE];\n\n    /**@brief  Is this the last tag? */\n    bool last_tag;\n\n    /**@brief  crc32c checksum. */\n    uint32_t checksum;\n};\n\n/**@brief  Extract information from a block tag.\n * @param  __tag pointer to the block tag\n * @param  tag_bytes block tag size of this jbd filesystem\n * @param  remaining size in buffer containing the block tag\n * @param  tag_info information of this tag.\n * @return  EOK when succeed, otherwise return EINVAL.*/\nstatic int\njbd_extract_block_tag(struct jbd_fs *jbd_fs,\n              void *__tag,\n              int tag_bytes,\n              int32_t remain_buf_size,\n              struct tag_info *tag_info)\n{\n    char *uuid_start;\n    tag_info->tag_bytes = tag_bytes;\n    tag_info->uuid_exist = false;\n    tag_info->last_tag = false;\n    tag_info->is_escape = false;\n\n    /* See whether it is possible to hold a valid block tag.*/\n    if (remain_buf_size - tag_bytes < 0)\n        return EINVAL;\n\n    if (JBD_HAS_INCOMPAT_FEATURE(&jbd_fs->sb,\n                     JBD_FEATURE_INCOMPAT_CSUM_V3)) {\n        struct jbd_block_tag3 *tag = __tag;\n        tag_info->block = jbd_get32(tag, blocknr);\n        if (JBD_HAS_INCOMPAT_FEATURE(&jbd_fs->sb,\n                         JBD_FEATURE_INCOMPAT_64BIT))\n             tag_info->block |=\n                 (uint64_t)jbd_get32(tag, blocknr_high) << 32;\n\n        if (jbd_get32(tag, flags) & JBD_FLAG_ESCAPE)\n            tag_info->is_escape = true;\n\n        if (!(jbd_get32(tag, flags) & JBD_FLAG_SAME_UUID)) {\n            /* See whether it is possible to hold UUID part.*/\n            if (remain_buf_size - tag_bytes < UUID_SIZE)\n                return EINVAL;\n\n            uuid_start = (char *)tag + tag_bytes;\n            tag_info->uuid_exist = true;\n            tag_info->tag_bytes += UUID_SIZE;\n            memcpy(tag_info->uuid, uuid_start, UUID_SIZE);\n        }\n\n        if (jbd_get32(tag, flags) & JBD_FLAG_LAST_TAG)\n            tag_info->last_tag = true;\n\n    } else {\n        struct jbd_block_tag *tag = __tag;\n        tag_info->block = jbd_get32(tag, blocknr);\n        if (JBD_HAS_INCOMPAT_FEATURE(&jbd_fs->sb,\n                         JBD_FEATURE_INCOMPAT_64BIT))\n             tag_info->block |=\n                 (uint64_t)jbd_get32(tag, blocknr_high) << 32;\n\n        if (jbd_get16(tag, flags) & JBD_FLAG_ESCAPE)\n            tag_info->is_escape = true;\n\n        if (!(jbd_get16(tag, flags) & JBD_FLAG_SAME_UUID)) {\n            /* See whether it is possible to hold UUID part.*/\n            if (remain_buf_size - tag_bytes < UUID_SIZE)\n                return EINVAL;\n\n            uuid_start = (char *)tag + tag_bytes;\n            tag_info->uuid_exist = true;\n            tag_info->tag_bytes += UUID_SIZE;\n            memcpy(tag_info->uuid, uuid_start, UUID_SIZE);\n        }\n\n        if (jbd_get16(tag, flags) & JBD_FLAG_LAST_TAG)\n            tag_info->last_tag = true;\n\n    }\n    return EOK;\n}\n\n/**@brief  Write information to a block tag.\n * @param  __tag pointer to the block tag\n * @param  remaining size in buffer containing the block tag\n * @param  tag_info information of this tag.\n * @return  EOK when succeed, otherwise return EINVAL.*/\nstatic int\njbd_write_block_tag(struct jbd_fs *jbd_fs,\n            void *__tag,\n            int32_t remain_buf_size,\n            struct tag_info *tag_info)\n{\n    char *uuid_start;\n    int tag_bytes = jbd_tag_bytes(jbd_fs);\n\n    tag_info->tag_bytes = tag_bytes;\n\n    /* See whether it is possible to hold a valid block tag.*/\n    if (remain_buf_size - tag_bytes < 0)\n        return EINVAL;\n\n    if (JBD_HAS_INCOMPAT_FEATURE(&jbd_fs->sb,\n                     JBD_FEATURE_INCOMPAT_CSUM_V3)) {\n        struct jbd_block_tag3 *tag = __tag;\n        memset(tag, 0, sizeof(struct jbd_block_tag3));\n        jbd_set32(tag, blocknr, (uint32_t)tag_info->block);\n        if (JBD_HAS_INCOMPAT_FEATURE(&jbd_fs->sb,\n                         JBD_FEATURE_INCOMPAT_64BIT))\n            jbd_set32(tag, blocknr_high, tag_info->block >> 32);\n\n        if (tag_info->uuid_exist) {\n            /* See whether it is possible to hold UUID part.*/\n            if (remain_buf_size - tag_bytes < UUID_SIZE)\n                return EINVAL;\n\n            uuid_start = (char *)tag + tag_bytes;\n            tag_info->tag_bytes += UUID_SIZE;\n            memcpy(uuid_start, tag_info->uuid, UUID_SIZE);\n        } else\n            jbd_set32(tag, flags,\n                  jbd_get32(tag, flags) | JBD_FLAG_SAME_UUID);\n\n        jbd_block_tag_csum_set(jbd_fs, __tag, tag_info->checksum);\n\n        if (tag_info->last_tag)\n            jbd_set32(tag, flags,\n                  jbd_get32(tag, flags) | JBD_FLAG_LAST_TAG);\n\n        if (tag_info->is_escape)\n            jbd_set32(tag, flags,\n                  jbd_get32(tag, flags) | JBD_FLAG_ESCAPE);\n\n    } else {\n        struct jbd_block_tag *tag = __tag;\n        memset(tag, 0, sizeof(struct jbd_block_tag));\n        jbd_set32(tag, blocknr, (uint32_t)tag_info->block);\n        if (JBD_HAS_INCOMPAT_FEATURE(&jbd_fs->sb,\n                         JBD_FEATURE_INCOMPAT_64BIT))\n            jbd_set32(tag, blocknr_high, tag_info->block >> 32);\n\n        if (tag_info->uuid_exist) {\n            /* See whether it is possible to hold UUID part.*/\n            if (remain_buf_size - tag_bytes < UUID_SIZE)\n                return EINVAL;\n\n            uuid_start = (char *)tag + tag_bytes;\n            tag_info->tag_bytes += UUID_SIZE;\n            memcpy(uuid_start, tag_info->uuid, UUID_SIZE);\n        } else\n            jbd_set16(tag, flags,\n                  jbd_get16(tag, flags) | JBD_FLAG_SAME_UUID);\n\n        jbd_block_tag_csum_set(jbd_fs, __tag, tag_info->checksum);\n\n        if (tag_info->last_tag)\n            jbd_set16(tag, flags,\n                  jbd_get16(tag, flags) | JBD_FLAG_LAST_TAG);\n\n\n        if (tag_info->is_escape)\n            jbd_set16(tag, flags,\n                  jbd_get16(tag, flags) | JBD_FLAG_ESCAPE);\n\n    }\n    return EOK;\n}\n\n/**@brief  Iterate all block tags in a block.\n * @param  jbd_fs jbd filesystem\n * @param  __tag_start pointer to the block\n * @param  tag_tbl_size size of the block\n * @param  func callback routine to indicate that\n *         a block tag is found\n * @param  arg additional argument to be passed to func */\nstatic void\njbd_iterate_block_table(struct jbd_fs *jbd_fs,\n            void *__tag_start,\n            int32_t tag_tbl_size,\n            void (*func)(struct jbd_fs * jbd_fs,\n                     struct tag_info *tag_info,\n                     void *arg),\n            void *arg)\n{\n    char *tag_start, *tag_ptr;\n    int tag_bytes = jbd_tag_bytes(jbd_fs);\n    tag_start = __tag_start;\n    tag_ptr = tag_start;\n\n    /* Cut off the size of block tail storing checksum. */\n    if (JBD_HAS_INCOMPAT_FEATURE(&jbd_fs->sb,\n                     JBD_FEATURE_INCOMPAT_CSUM_V2) ||\n        JBD_HAS_INCOMPAT_FEATURE(&jbd_fs->sb,\n                     JBD_FEATURE_INCOMPAT_CSUM_V3))\n        tag_tbl_size -= sizeof(struct jbd_block_tail);\n\n    while (tag_tbl_size) {\n        struct tag_info tag_info;\n        int rc = jbd_extract_block_tag(jbd_fs,\n                      tag_ptr,\n                      tag_bytes,\n                      tag_tbl_size,\n                      &tag_info);\n        if (rc != EOK)\n            break;\n\n        if (func)\n            func(jbd_fs, &tag_info, arg);\n\n        /* Stop the iteration when we reach the last tag. */\n        if (tag_info.last_tag)\n            break;\n\n        tag_ptr += tag_info.tag_bytes;\n        tag_tbl_size -= tag_info.tag_bytes;\n    }\n}\n\nstatic void jbd_display_block_tags(struct jbd_fs *jbd_fs,\n                   struct tag_info *tag_info,\n                   void *arg)\n{\n    uint32_t *iblock = arg;\n    ext4_dbg(DEBUG_JBD, \"Block in block_tag: %\" PRIu64 \"\\n\", tag_info->block);\n    (*iblock)++;\n    wrap(&jbd_fs->sb, *iblock);\n    (void)jbd_fs;\n    return;\n}\n\nstatic struct revoke_entry *\njbd_revoke_entry_lookup(struct recover_info *info, ext4_fsblk_t block)\n{\n    struct revoke_entry tmp = {\n        .block = block\n    };\n\n    return RB_FIND(jbd_revoke, &info->revoke_root, &tmp);\n}\n\n/**@brief  Replay a block in a transaction.\n * @param  jbd_fs jbd filesystem\n * @param  tag_info tag_info of the logged block.*/\nstatic void jbd_replay_block_tags(struct jbd_fs *jbd_fs,\n                  struct tag_info *tag_info,\n                  void *__arg)\n{\n    int r;\n    struct replay_arg *arg = __arg;\n    struct recover_info *info = arg->info;\n    uint32_t *this_block = arg->this_block;\n    struct revoke_entry *revoke_entry;\n    struct ext4_block journal_block, ext4_block;\n    struct ext4_fs *fs = jbd_fs->inode_ref.fs;\n\n    (*this_block)++;\n    wrap(&jbd_fs->sb, *this_block);\n\n    /* We replay this block only if the current transaction id\n     * is equal or greater than that in revoke entry.*/\n    revoke_entry = jbd_revoke_entry_lookup(info, tag_info->block);\n    if (revoke_entry &&\n        trans_id_diff(arg->this_trans_id, revoke_entry->trans_id) <= 0)\n        return;\n\n    ext4_dbg(DEBUG_JBD,\n         \"Replaying block in block_tag: %\" PRIu64 \"\\n\",\n         tag_info->block);\n\n    r = jbd_block_get(jbd_fs, &journal_block, *this_block);\n    if (r != EOK)\n        return;\n\n    /* We need special treatment for ext4 superblock. */\n    if (tag_info->block) {\n        r = ext4_block_get_noread(fs->bdev, &ext4_block, tag_info->block);\n        if (r != EOK) {\n            jbd_block_set(jbd_fs, &journal_block);\n            return;\n        }\n\n        memcpy(ext4_block.data,\n            journal_block.data,\n            jbd_get32(&jbd_fs->sb, blocksize));\n\n        if (tag_info->is_escape)\n            ((struct jbd_bhdr *)ext4_block.data)->magic =\n                    to_be32(JBD_MAGIC_NUMBER);\n\n        ext4_bcache_set_dirty(ext4_block.buf);\n        ext4_block_set(fs->bdev, &ext4_block);\n    } else {\n        uint16_t mount_count, state;\n        mount_count = ext4_get16(&fs->sb, mount_count);\n        state = ext4_get16(&fs->sb, state);\n\n        memcpy(&fs->sb,\n            journal_block.data + EXT4_SUPERBLOCK_OFFSET,\n            EXT4_SUPERBLOCK_SIZE);\n\n        /* Mark system as mounted */\n        ext4_set16(&fs->sb, state, state);\n        r = ext4_sb_write(fs->bdev, &fs->sb);\n        if (r != EOK)\n            return;\n\n        /*Update mount count*/\n        ext4_set16(&fs->sb, mount_count, mount_count);\n    }\n\n    jbd_block_set(jbd_fs, &journal_block);\n\n    return;\n}\n\n/**@brief  Add block address to revoke tree, along with\n *         its transaction id.\n * @param  info  journal replay info\n * @param  block  block address to be replayed.*/\nstatic void jbd_add_revoke_block_tags(struct recover_info *info,\n                      ext4_fsblk_t block)\n{\n    struct revoke_entry *revoke_entry;\n\n    ext4_dbg(DEBUG_JBD, \"Add block %\" PRIu64 \" to revoke tree\\n\", block);\n    /* If the revoke entry with respect to the block address\n     * exists already, update its transaction id.*/\n    revoke_entry = jbd_revoke_entry_lookup(info, block);\n    if (revoke_entry) {\n        revoke_entry->trans_id = info->this_trans_id;\n        return;\n    }\n\n    revoke_entry = jbd_alloc_revoke_entry();\n    ext4_assert(revoke_entry);\n    revoke_entry->block = block;\n    revoke_entry->trans_id = info->this_trans_id;\n    RB_INSERT(jbd_revoke, &info->revoke_root, revoke_entry);\n\n    return;\n}\n\nstatic void jbd_destroy_revoke_tree(struct recover_info *info)\n{\n    while (!RB_EMPTY(&info->revoke_root)) {\n        struct revoke_entry *revoke_entry =\n            RB_MIN(jbd_revoke, &info->revoke_root);\n        ext4_assert(revoke_entry);\n        RB_REMOVE(jbd_revoke, &info->revoke_root, revoke_entry);\n        jbd_free_revoke_entry(revoke_entry);\n    }\n}\n\n\n#define ACTION_SCAN 0\n#define ACTION_REVOKE 1\n#define ACTION_RECOVER 2\n\n/**@brief  Add entries in a revoke block to revoke tree.\n * @param  jbd_fs jbd filesystem\n * @param  header revoke block header\n * @param  recover_info  journal replay info*/\nstatic void jbd_build_revoke_tree(struct jbd_fs *jbd_fs,\n                  struct jbd_bhdr *header,\n                  struct recover_info *info)\n{\n    char *blocks_entry;\n    struct jbd_revoke_header *revoke_hdr =\n        (struct jbd_revoke_header *)header;\n    uint32_t i, nr_entries, record_len = 4;\n\n    /* If we are working on a 64bit jbd filesystem, */\n    if (JBD_HAS_INCOMPAT_FEATURE(&jbd_fs->sb,\n                     JBD_FEATURE_INCOMPAT_64BIT))\n        record_len = 8;\n\n    nr_entries = (jbd_get32(revoke_hdr, count) -\n            sizeof(struct jbd_revoke_header)) /\n            record_len;\n\n    blocks_entry = (char *)(revoke_hdr + 1);\n\n    for (i = 0;i < nr_entries;i++) {\n        if (record_len == 8) {\n            uint64_t *blocks =\n                (uint64_t *)blocks_entry;\n            jbd_add_revoke_block_tags(info, to_be64(*blocks));\n        } else {\n            uint32_t *blocks =\n                (uint32_t *)blocks_entry;\n            jbd_add_revoke_block_tags(info, to_be32(*blocks));\n        }\n        blocks_entry += record_len;\n    }\n}\n\nstatic void jbd_debug_descriptor_block(struct jbd_fs *jbd_fs,\n                       struct jbd_bhdr *header,\n                       uint32_t *iblock)\n{\n    jbd_iterate_block_table(jbd_fs,\n                header + 1,\n                jbd_get32(&jbd_fs->sb, blocksize) -\n                    sizeof(struct jbd_bhdr),\n                jbd_display_block_tags,\n                iblock);\n}\n\nstatic void jbd_replay_descriptor_block(struct jbd_fs *jbd_fs,\n                    struct jbd_bhdr *header,\n                    struct replay_arg *arg)\n{\n    jbd_iterate_block_table(jbd_fs,\n                header + 1,\n                jbd_get32(&jbd_fs->sb, blocksize) -\n                    sizeof(struct jbd_bhdr),\n                jbd_replay_block_tags,\n                arg);\n}\n\n/**@brief  The core routine of journal replay.\n * @param  jbd_fs jbd filesystem\n * @param  recover_info  journal replay info\n * @param  action action needed to be taken\n * @return standard error code*/\nstatic int jbd_iterate_log(struct jbd_fs *jbd_fs,\n               struct recover_info *info,\n               int action)\n{\n    int r = EOK;\n    bool log_end = false;\n    struct jbd_sb *sb = &jbd_fs->sb;\n    uint32_t start_trans_id, this_trans_id;\n    uint32_t start_block, this_block;\n\n    /* We start iterating valid blocks in the whole journal.*/\n    start_trans_id = this_trans_id = jbd_get32(sb, sequence);\n    start_block = this_block = jbd_get32(sb, start);\n    if (action == ACTION_SCAN)\n        info->trans_cnt = 0;\n    else if (!info->trans_cnt)\n        log_end = true;\n\n    ext4_dbg(DEBUG_JBD, \"Start of journal at trans id: %\" PRIu32 \"\\n\",\n                start_trans_id);\n\n    while (!log_end) {\n        struct ext4_block block;\n        struct jbd_bhdr *header;\n        /* If we are not scanning for the last\n         * valid transaction in the journal,\n         * we will stop when we reach the end of\n         * the journal.*/\n        if (action != ACTION_SCAN)\n            if (trans_id_diff(this_trans_id, info->last_trans_id) > 0) {\n                log_end = true;\n                continue;\n            }\n\n        r = jbd_block_get(jbd_fs, &block, this_block);\n        if (r != EOK)\n            break;\n\n        header = (struct jbd_bhdr *)block.data;\n        /* This block does not have a valid magic number,\n         * so we have reached the end of the journal.*/\n        if (jbd_get32(header, magic) != JBD_MAGIC_NUMBER) {\n            jbd_block_set(jbd_fs, &block);\n            log_end = true;\n            continue;\n        }\n\n        /* If the transaction id we found is not expected,\n         * we may have reached the end of the journal.\n         *\n         * If we are not scanning the journal, something\n         * bad might have taken place. :-( */\n        if (jbd_get32(header, sequence) != this_trans_id) {\n            if (action != ACTION_SCAN)\n                r = EIO;\n\n            jbd_block_set(jbd_fs, &block);\n            log_end = true;\n            continue;\n        }\n\n        switch (jbd_get32(header, blocktype)) {\n        case JBD_DESCRIPTOR_BLOCK:\n            if (!jbd_verify_meta_csum(jbd_fs, header)) {\n                ext4_dbg(DEBUG_JBD,\n                    DBG_WARN \"Descriptor block checksum failed.\"\n                        \"Journal block: %\" PRIu32\"\\n\",\n                        this_block);\n                log_end = true;\n                break;\n            }\n            ext4_dbg(DEBUG_JBD, \"Descriptor block: %\" PRIu32\", \"\n                        \"trans_id: %\" PRIu32\"\\n\",\n                        this_block, this_trans_id);\n            if (action == ACTION_RECOVER) {\n                struct replay_arg replay_arg;\n                replay_arg.info = info;\n                replay_arg.this_block = &this_block;\n                replay_arg.this_trans_id = this_trans_id;\n\n                jbd_replay_descriptor_block(jbd_fs,\n                        header, &replay_arg);\n            } else\n                jbd_debug_descriptor_block(jbd_fs,\n                        header, &this_block);\n\n            break;\n        case JBD_COMMIT_BLOCK:\n            if (!jbd_verify_commit_csum(jbd_fs,\n                    (struct jbd_commit_header *)header)) {\n                ext4_dbg(DEBUG_JBD,\n                    DBG_WARN \"Commit block checksum failed.\"\n                        \"Journal block: %\" PRIu32\"\\n\",\n                        this_block);\n                log_end = true;\n                break;\n            }\n            ext4_dbg(DEBUG_JBD, \"Commit block: %\" PRIu32\", \"\n                        \"trans_id: %\" PRIu32\"\\n\",\n                        this_block, this_trans_id);\n            /*\n             * This is the end of a transaction,\n             * we may now proceed to the next transaction.\n             */\n            this_trans_id++;\n            if (action == ACTION_SCAN)\n                info->trans_cnt++;\n            break;\n        case JBD_REVOKE_BLOCK:\n            if (!jbd_verify_meta_csum(jbd_fs, header)) {\n                ext4_dbg(DEBUG_JBD,\n                    DBG_WARN \"Revoke block checksum failed.\"\n                        \"Journal block: %\" PRIu32\"\\n\",\n                        this_block);\n                log_end = true;\n                break;\n            }\n            ext4_dbg(DEBUG_JBD, \"Revoke block: %\" PRIu32\", \"\n                        \"trans_id: %\" PRIu32\"\\n\",\n                        this_block, this_trans_id);\n            if (action == ACTION_REVOKE) {\n                info->this_trans_id = this_trans_id;\n                jbd_build_revoke_tree(jbd_fs,\n                        header, info);\n            }\n            break;\n        default:\n            log_end = true;\n            break;\n        }\n        jbd_block_set(jbd_fs, &block);\n        this_block++;\n        wrap(sb, this_block);\n        if (this_block == start_block)\n            log_end = true;\n\n    }\n    ext4_dbg(DEBUG_JBD, \"End of journal.\\n\");\n    if (r == EOK && action == ACTION_SCAN) {\n        /* We have finished scanning the journal. */\n        info->start_trans_id = start_trans_id;\n        if (trans_id_diff(this_trans_id, start_trans_id) > 0)\n            info->last_trans_id = this_trans_id - 1;\n        else\n            info->last_trans_id = this_trans_id;\n    }\n\n    return r;\n}\n\n/**@brief  Replay journal.\n * @param  jbd_fs jbd filesystem\n * @return standard error code*/\nint jbd_recover(struct jbd_fs *jbd_fs)\n{\n    int r;\n    struct recover_info info;\n    struct jbd_sb *sb = &jbd_fs->sb;\n    if (!sb->start)\n        return EOK;\n\n    RB_INIT(&info.revoke_root);\n\n    r = jbd_iterate_log(jbd_fs, &info, ACTION_SCAN);\n    if (r != EOK)\n        return r;\n\n    r = jbd_iterate_log(jbd_fs, &info, ACTION_REVOKE);\n    if (r != EOK)\n        return r;\n\n    r = jbd_iterate_log(jbd_fs, &info, ACTION_RECOVER);\n    if (r == EOK) {\n        /* If we successfully replay the journal,\n         * clear EXT4_FINCOM_RECOVER flag on the\n         * ext4 superblock, and set the start of\n         * journal to 0.*/\n        uint32_t features_incompatible =\n            ext4_get32(&jbd_fs->inode_ref.fs->sb,\n                   features_incompatible);\n        jbd_set32(&jbd_fs->sb, start, 0);\n        jbd_set32(&jbd_fs->sb, sequence, info.last_trans_id);\n        features_incompatible &= ~EXT4_FINCOM_RECOVER;\n        ext4_set32(&jbd_fs->inode_ref.fs->sb,\n               features_incompatible,\n               features_incompatible);\n        jbd_fs->dirty = true;\n        r = ext4_sb_write(jbd_fs->bdev,\n                  &jbd_fs->inode_ref.fs->sb);\n    }\n    jbd_destroy_revoke_tree(&info);\n    return r;\n}\n\nstatic void jbd_journal_write_sb(struct jbd_journal *journal)\n{\n    struct jbd_fs *jbd_fs = journal->jbd_fs;\n    jbd_set32(&jbd_fs->sb, start, journal->start);\n    jbd_set32(&jbd_fs->sb, sequence, journal->trans_id);\n    jbd_fs->dirty = true;\n}\n\n/**@brief  Start accessing the journal.\n * @param  jbd_fs jbd filesystem\n * @param  journal current journal session\n * @return standard error code*/\nint jbd_journal_start(struct jbd_fs *jbd_fs,\n              struct jbd_journal *journal)\n{\n    int r;\n    uint32_t features_incompatible =\n            ext4_get32(&jbd_fs->inode_ref.fs->sb,\n                   features_incompatible);\n    features_incompatible |= EXT4_FINCOM_RECOVER;\n    ext4_set32(&jbd_fs->inode_ref.fs->sb,\n            features_incompatible,\n            features_incompatible);\n    r = ext4_sb_write(jbd_fs->bdev,\n            &jbd_fs->inode_ref.fs->sb);\n    if (r != EOK)\n        return r;\n\n    journal->first = jbd_get32(&jbd_fs->sb, first);\n    journal->start = journal->first;\n    journal->last = journal->first;\n    /*\n     * To invalidate any stale records we need to start from\n     * the checkpoint transaction ID of the previous journalling session\n     * plus 1.\n     */\n    journal->trans_id = jbd_get32(&jbd_fs->sb, sequence) + 1;\n    journal->alloc_trans_id = journal->trans_id;\n\n    journal->block_size = jbd_get32(&jbd_fs->sb, blocksize);\n\n    TAILQ_INIT(&journal->cp_queue);\n    RB_INIT(&journal->block_rec_root);\n    journal->jbd_fs = jbd_fs;\n    jbd_journal_write_sb(journal);\n    r = jbd_write_sb(jbd_fs);\n    if (r != EOK)\n        return r;\n\n    jbd_fs->bdev->journal = journal;\n    return EOK;\n}\n\nstatic void jbd_trans_end_write(struct ext4_bcache *bc __unused,\n              struct ext4_buf *buf __unused,\n              int res,\n              void *arg);\n\n/*\n * This routine is only suitable to committed transactions. */\nstatic void jbd_journal_flush_trans(struct jbd_trans *trans)\n{\n    struct jbd_buf *jbd_buf, *tmp;\n    struct jbd_journal *journal = trans->journal;\n    struct ext4_fs *fs = journal->jbd_fs->inode_ref.fs;\n    void *tmp_data = ext4_alloc_bcache(journal->block_size);\n    ext4_assert(tmp_data);\n\n    TAILQ_FOREACH_SAFE(jbd_buf, &trans->buf_queue, buf_node,\n            tmp) {\n        struct ext4_buf *buf;\n        struct ext4_block block;\n        /* The buffer is not yet flushed. */\n        buf = ext4_bcache_find_get(fs->bdev->bc, &block,\n                       jbd_buf->block_rec->lba);\n        if (!(buf && ext4_bcache_test_flag(buf, BC_UPTODATE) &&\n              jbd_buf->block_rec->trans == trans)) {\n            int r;\n            struct ext4_block jbd_block = EXT4_BLOCK_ZERO();\n            r = jbd_block_get(journal->jbd_fs,\n                        &jbd_block,\n                        jbd_buf->jbd_lba);\n            ext4_assert(r == EOK);\n            memcpy(tmp_data, jbd_block.data,\n                    journal->block_size);\n            ext4_block_set(fs->bdev, &jbd_block);\n            r = ext4_blocks_set_direct(fs->bdev, tmp_data,\n                    jbd_buf->block_rec->lba, 1);\n            jbd_trans_end_write(fs->bdev->bc, buf, r, jbd_buf);\n        } else\n            ext4_block_flush_buf(fs->bdev, buf);\n\n        if (buf)\n            ext4_block_set(fs->bdev, &block);\n    }\n\n    ext4_free(tmp_data);\n}\n\nstatic void\njbd_journal_skip_pure_revoke(struct jbd_journal *journal,\n                 struct jbd_trans *trans)\n{\n    journal->start = trans->start_iblock +\n        trans->alloc_blocks;\n    wrap(&journal->jbd_fs->sb, journal->start);\n    journal->trans_id = trans->trans_id + 1;\n    jbd_journal_free_trans(journal,\n            trans, false);\n    jbd_journal_write_sb(journal);\n}\n\nvoid\njbd_journal_purge_cp_trans(struct jbd_journal *journal,\n               bool flush,\n               bool once)\n{\n    struct jbd_trans *trans;\n    while ((trans = TAILQ_FIRST(&journal->cp_queue))) {\n        if (!trans->data_cnt) {\n            TAILQ_REMOVE(&journal->cp_queue,\n                    trans,\n                    trans_node);\n            jbd_journal_skip_pure_revoke(journal, trans);\n        } else {\n            if (trans->data_cnt ==\n                    trans->written_cnt) {\n                journal->start =\n                    trans->start_iblock +\n                    trans->alloc_blocks;\n                wrap(&journal->jbd_fs->sb,\n                        journal->start);\n                journal->trans_id =\n                    trans->trans_id + 1;\n                TAILQ_REMOVE(&journal->cp_queue,\n                        trans,\n                        trans_node);\n                jbd_journal_free_trans(journal,\n                        trans,\n                        false);\n                jbd_journal_write_sb(journal);\n            } else if (!flush) {\n                journal->start =\n                    trans->start_iblock;\n                wrap(&journal->jbd_fs->sb,\n                        journal->start);\n                journal->trans_id =\n                    trans->trans_id;\n                jbd_journal_write_sb(journal);\n                break;\n            } else\n                jbd_journal_flush_trans(trans);\n        }\n        if (once)\n            break;\n    }\n}\n\n/**@brief  Stop accessing the journal.\n * @param  journal current journal session\n * @return standard error code*/\nint jbd_journal_stop(struct jbd_journal *journal)\n{\n    int r;\n    struct jbd_fs *jbd_fs = journal->jbd_fs;\n    uint32_t features_incompatible;\n\n    /* Make sure that journalled content have reached\n     * the disk.*/\n    jbd_journal_purge_cp_trans(journal, true, false);\n\n    /* There should be no block record in this journal\n     * session. */\n    if (!RB_EMPTY(&journal->block_rec_root))\n        ext4_dbg(DEBUG_JBD,\n             DBG_WARN \"There are still block records \"\n                  \"in this journal session!\\n\");\n\n    features_incompatible =\n        ext4_get32(&jbd_fs->inode_ref.fs->sb,\n               features_incompatible);\n    features_incompatible &= ~EXT4_FINCOM_RECOVER;\n    ext4_set32(&jbd_fs->inode_ref.fs->sb,\n            features_incompatible,\n            features_incompatible);\n    r = ext4_sb_write(jbd_fs->bdev,\n            &jbd_fs->inode_ref.fs->sb);\n    if (r != EOK)\n        return r;\n\n    journal->start = 0;\n    journal->trans_id = 0;\n    jbd_journal_write_sb(journal);\n    return jbd_write_sb(journal->jbd_fs);\n}\n\n/**@brief  Allocate a block in the journal.\n * @param  journal current journal session\n * @param  trans transaction\n * @return allocated block address*/\nstatic uint32_t jbd_journal_alloc_block(struct jbd_journal *journal,\n                    struct jbd_trans *trans)\n{\n    uint32_t start_block;\n\n    start_block = journal->last++;\n    trans->alloc_blocks++;\n    wrap(&journal->jbd_fs->sb, journal->last);\n\n    /* If there is no space left, flush just one journalled\n     * transaction.*/\n    if (journal->last == journal->start) {\n        jbd_journal_purge_cp_trans(journal, true, true);\n        ext4_assert(journal->last != journal->start);\n    }\n\n    return start_block;\n}\n\nstatic struct jbd_block_rec *\njbd_trans_block_rec_lookup(struct jbd_journal *journal,\n               ext4_fsblk_t lba)\n{\n    struct jbd_block_rec tmp = {\n        .lba = lba\n    };\n\n    return RB_FIND(jbd_block,\n               &journal->block_rec_root,\n               &tmp);\n}\n\nstatic void\njbd_trans_change_ownership(struct jbd_block_rec *block_rec,\n               struct jbd_trans *new_trans)\n{\n    LIST_REMOVE(block_rec, tbrec_node);\n    if (new_trans) {\n        /* Now this block record belongs to this transaction. */\n        LIST_INSERT_HEAD(&new_trans->tbrec_list, block_rec, tbrec_node);\n    }\n    block_rec->trans = new_trans;\n}\n\nstatic inline struct jbd_block_rec *\njbd_trans_insert_block_rec(struct jbd_trans *trans,\n               ext4_fsblk_t lba)\n{\n    struct jbd_block_rec *block_rec;\n    block_rec = jbd_trans_block_rec_lookup(trans->journal, lba);\n    if (block_rec) {\n        jbd_trans_change_ownership(block_rec, trans);\n        return block_rec;\n    }\n    block_rec = ext4_calloc(1, sizeof(struct jbd_block_rec));\n    if (!block_rec)\n        return NULL;\n\n    block_rec->lba = lba;\n    block_rec->trans = trans;\n    TAILQ_INIT(&block_rec->dirty_buf_queue);\n    LIST_INSERT_HEAD(&trans->tbrec_list, block_rec, tbrec_node);\n    RB_INSERT(jbd_block, &trans->journal->block_rec_root, block_rec);\n    return block_rec;\n}\n\n/*\n * This routine will do the dirty works.\n */\nstatic void\njbd_trans_finish_callback(struct jbd_journal *journal,\n              const struct jbd_trans *trans,\n              struct jbd_block_rec *block_rec,\n              bool abort,\n              bool revoke)\n{\n    struct ext4_fs *fs = journal->jbd_fs->inode_ref.fs;\n    if (block_rec->trans != trans)\n        return;\n\n    if (!abort) {\n        struct jbd_buf *jbd_buf, *tmp;\n        TAILQ_FOREACH_SAFE(jbd_buf,\n                &block_rec->dirty_buf_queue,\n                dirty_buf_node,\n                tmp) {\n            jbd_trans_end_write(fs->bdev->bc,\n                    NULL,\n                    EOK,\n                    jbd_buf);\n        }\n    } else {\n        /*\n         * We have to roll back data if the block is going to be\n         * aborted.\n         */\n        struct jbd_buf *jbd_buf;\n        struct ext4_block jbd_block = EXT4_BLOCK_ZERO(),\n                  block = EXT4_BLOCK_ZERO();\n        jbd_buf = TAILQ_LAST(&block_rec->dirty_buf_queue,\n                jbd_buf_dirty);\n        if (jbd_buf) {\n            if (!revoke) {\n                int r;\n                r = ext4_block_get_noread(fs->bdev,\n                            &block,\n                            block_rec->lba);\n                ext4_assert(r == EOK);\n                r = jbd_block_get(journal->jbd_fs,\n                            &jbd_block,\n                            jbd_buf->jbd_lba);\n                ext4_assert(r == EOK);\n                memcpy(block.data, jbd_block.data,\n                        journal->block_size);\n\n                jbd_trans_change_ownership(block_rec,\n                        jbd_buf->trans);\n\n                block.buf->end_write = jbd_trans_end_write;\n                block.buf->end_write_arg = jbd_buf;\n\n                ext4_bcache_set_flag(jbd_block.buf, BC_TMP);\n                ext4_bcache_set_dirty(block.buf);\n\n                ext4_block_set(fs->bdev, &jbd_block);\n                ext4_block_set(fs->bdev, &block);\n                return;\n            } else {\n                /* The revoked buffer is yet written. */\n                jbd_trans_change_ownership(block_rec,\n                        jbd_buf->trans);\n            }\n        }\n    }\n}\n\nstatic inline void\njbd_trans_remove_block_rec(struct jbd_journal *journal,\n               struct jbd_block_rec *block_rec,\n               struct jbd_trans *trans)\n{\n    /* If this block record doesn't belong to this transaction,\n     * give up.*/\n    if (block_rec->trans == trans) {\n        LIST_REMOVE(block_rec, tbrec_node);\n        RB_REMOVE(jbd_block,\n                &journal->block_rec_root,\n                block_rec);\n        ext4_free(block_rec);\n    }\n}\n\n/**@brief  Add block to a transaction and mark it dirty.\n * @param  trans transaction\n * @param  block block descriptor\n * @return standard error code*/\nint jbd_trans_set_block_dirty(struct jbd_trans *trans,\n                  struct ext4_block *block)\n{\n    struct jbd_buf *jbd_buf;\n    struct jbd_revoke_rec *rec, tmp_rec = {\n        .lba = block->lb_id\n    };\n    struct jbd_block_rec *block_rec;\n\n    if (block->buf->end_write == jbd_trans_end_write) {\n        jbd_buf = block->buf->end_write_arg;\n        if (jbd_buf && jbd_buf->trans == trans)\n            return EOK;\n    }\n    jbd_buf = ext4_calloc(1, sizeof(struct jbd_buf));\n    if (!jbd_buf)\n        return ENOMEM;\n\n    if ((block_rec = jbd_trans_insert_block_rec(trans,\n                    block->lb_id)) == NULL) {\n        ext4_free(jbd_buf);\n        return ENOMEM;\n    }\n\n    TAILQ_INSERT_TAIL(&block_rec->dirty_buf_queue,\n            jbd_buf,\n            dirty_buf_node);\n\n    jbd_buf->block_rec = block_rec;\n    jbd_buf->trans = trans;\n    jbd_buf->block = *block;\n    ext4_bcache_inc_ref(block->buf);\n\n    /* If the content reach the disk, notify us\n     * so that we may do a checkpoint. */\n    block->buf->end_write = jbd_trans_end_write;\n    block->buf->end_write_arg = jbd_buf;\n\n    trans->data_cnt++;\n    TAILQ_INSERT_HEAD(&trans->buf_queue, jbd_buf, buf_node);\n\n    ext4_bcache_set_dirty(block->buf);\n    rec = RB_FIND(jbd_revoke_tree,\n            &trans->revoke_root,\n            &tmp_rec);\n    if (rec) {\n        RB_REMOVE(jbd_revoke_tree, &trans->revoke_root,\n              rec);\n        ext4_free(rec);\n    }\n\n    return EOK;\n}\n\n/**@brief  Add block to be revoked to a transaction\n * @param  trans transaction\n * @param  lba logical block address\n * @return standard error code*/\nint jbd_trans_revoke_block(struct jbd_trans *trans,\n               ext4_fsblk_t lba)\n{\n    struct jbd_revoke_rec tmp_rec = {\n        .lba = lba\n    }, *rec;\n    rec = RB_FIND(jbd_revoke_tree,\n              &trans->revoke_root,\n              &tmp_rec);\n    if (rec)\n        return EOK;\n\n    rec = ext4_calloc(1, sizeof(struct jbd_revoke_rec));\n    if (!rec)\n        return ENOMEM;\n\n    rec->lba = lba;\n    RB_INSERT(jbd_revoke_tree, &trans->revoke_root, rec);\n    return EOK;\n}\n\n/**@brief  Try to add block to be revoked to a transaction.\n *         If @lba still remains in an transaction on checkpoint\n *         queue, add @lba as a revoked block to the transaction.\n * @param  trans transaction\n * @param  lba logical block address\n * @return standard error code*/\nint jbd_trans_try_revoke_block(struct jbd_trans *trans,\n                   ext4_fsblk_t lba)\n{\n    struct jbd_journal *journal = trans->journal;\n    struct jbd_block_rec *block_rec =\n        jbd_trans_block_rec_lookup(journal, lba);\n\n    if (block_rec) {\n        if (block_rec->trans == trans) {\n            struct jbd_buf *jbd_buf =\n                TAILQ_LAST(&block_rec->dirty_buf_queue,\n                    jbd_buf_dirty);\n            /* If there are still unwritten buffers. */\n            if (TAILQ_FIRST(&block_rec->dirty_buf_queue) !=\n                jbd_buf)\n                jbd_trans_revoke_block(trans, lba);\n\n        } else\n            jbd_trans_revoke_block(trans, lba);\n    }\n\n    return EOK;\n}\n\n/**@brief  Free a transaction\n * @param  journal current journal session\n * @param  trans transaction\n * @param  abort discard all the modifications on the block?\n * @return standard error code*/\nvoid jbd_journal_free_trans(struct jbd_journal *journal,\n                struct jbd_trans *trans,\n                bool abort)\n{\n    struct jbd_buf *jbd_buf, *tmp;\n    struct jbd_revoke_rec *rec, *tmp2;\n    struct jbd_block_rec *block_rec, *tmp3;\n    struct ext4_fs *fs = journal->jbd_fs->inode_ref.fs;\n    TAILQ_FOREACH_SAFE(jbd_buf, &trans->buf_queue, buf_node,\n              tmp) {\n        block_rec = jbd_buf->block_rec;\n        if (abort) {\n            jbd_buf->block.buf->end_write = NULL;\n            jbd_buf->block.buf->end_write_arg = NULL;\n            ext4_bcache_clear_dirty(jbd_buf->block.buf);\n            ext4_block_set(fs->bdev, &jbd_buf->block);\n        }\n\n        TAILQ_REMOVE(&jbd_buf->block_rec->dirty_buf_queue,\n            jbd_buf,\n            dirty_buf_node);\n        jbd_trans_finish_callback(journal,\n                trans,\n                block_rec,\n                abort,\n                false);\n        TAILQ_REMOVE(&trans->buf_queue, jbd_buf, buf_node);\n        ext4_free(jbd_buf);\n    }\n    RB_FOREACH_SAFE(rec, jbd_revoke_tree, &trans->revoke_root,\n              tmp2) {\n        RB_REMOVE(jbd_revoke_tree, &trans->revoke_root, rec);\n        ext4_free(rec);\n    }\n    LIST_FOREACH_SAFE(block_rec, &trans->tbrec_list, tbrec_node,\n              tmp3) {\n        jbd_trans_remove_block_rec(journal, block_rec, trans);\n    }\n\n    ext4_free(trans);\n}\n\n/**@brief  Write commit block for a transaction\n * @param  trans transaction\n * @return standard error code*/\nstatic int jbd_trans_write_commit_block(struct jbd_trans *trans)\n{\n    int rc;\n    struct ext4_block block;\n    struct jbd_commit_header *header;\n    uint32_t commit_iblock;\n    struct jbd_journal *journal = trans->journal;\n\n    commit_iblock = jbd_journal_alloc_block(journal, trans);\n\n    rc = jbd_block_get_noread(journal->jbd_fs, &block, commit_iblock);\n    if (rc != EOK)\n        return rc;\n\n    header = (struct jbd_commit_header *)block.data;\n    jbd_set32(&header->header, magic, JBD_MAGIC_NUMBER);\n    jbd_set32(&header->header, blocktype, JBD_COMMIT_BLOCK);\n    jbd_set32(&header->header, sequence, trans->trans_id);\n\n    if (JBD_HAS_INCOMPAT_FEATURE(&journal->jbd_fs->sb,\n                JBD_FEATURE_COMPAT_CHECKSUM)) {\n        header->chksum_type = JBD_CRC32_CHKSUM;\n        header->chksum_size = JBD_CRC32_CHKSUM_SIZE;\n        jbd_set32(header, chksum[0], trans->data_csum);\n    }\n    jbd_commit_csum_set(journal->jbd_fs, header);\n    ext4_bcache_set_dirty(block.buf);\n    ext4_bcache_set_flag(block.buf, BC_TMP);\n    rc = jbd_block_set(journal->jbd_fs, &block);\n    return rc;\n}\n\n/**@brief  Write descriptor block for a transaction\n * @param  journal current journal session\n * @param  trans transaction\n * @return standard error code*/\nstatic int jbd_journal_prepare(struct jbd_journal *journal,\n                   struct jbd_trans *trans)\n{\n    int rc = EOK, i = 0;\n    struct ext4_block desc_block = EXT4_BLOCK_ZERO(),\n              data_block = EXT4_BLOCK_ZERO();\n    int32_t tag_tbl_size = 0;\n    uint32_t desc_iblock = 0;\n    uint32_t data_iblock = 0;\n    char *tag_start = NULL, *tag_ptr = NULL;\n    struct jbd_buf *jbd_buf, *tmp;\n    struct ext4_fs *fs = journal->jbd_fs->inode_ref.fs;\n    uint32_t checksum = EXT4_CRC32_INIT;\n    struct jbd_bhdr *bhdr = NULL;\n    void *data;\n\n    /* Try to remove any non-dirty buffers from the tail of\n     * buf_queue. */\n    TAILQ_FOREACH_REVERSE_SAFE(jbd_buf, &trans->buf_queue,\n            jbd_trans_buf, buf_node, tmp) {\n        struct jbd_revoke_rec tmp_rec = {\n            .lba = jbd_buf->block_rec->lba\n        };\n        /* We stop the iteration when we find a dirty buffer. */\n        if (ext4_bcache_test_flag(jbd_buf->block.buf,\n                    BC_DIRTY))\n            break;\n\n        TAILQ_REMOVE(&jbd_buf->block_rec->dirty_buf_queue,\n            jbd_buf,\n            dirty_buf_node);\n\n        jbd_buf->block.buf->end_write = NULL;\n        jbd_buf->block.buf->end_write_arg = NULL;\n        jbd_trans_finish_callback(journal,\n                trans,\n                jbd_buf->block_rec,\n                true,\n                RB_FIND(jbd_revoke_tree,\n                    &trans->revoke_root,\n                    &tmp_rec));\n        jbd_trans_remove_block_rec(journal,\n                    jbd_buf->block_rec, trans);\n        trans->data_cnt--;\n\n        ext4_block_set(fs->bdev, &jbd_buf->block);\n        TAILQ_REMOVE(&trans->buf_queue, jbd_buf, buf_node);\n        ext4_free(jbd_buf);\n    }\n\n    TAILQ_FOREACH_SAFE(jbd_buf, &trans->buf_queue, buf_node, tmp) {\n        struct tag_info tag_info;\n        bool uuid_exist = false;\n        bool is_escape = false;\n        struct jbd_revoke_rec tmp_rec = {\n            .lba = jbd_buf->block_rec->lba\n        };\n        if (!ext4_bcache_test_flag(jbd_buf->block.buf,\n                       BC_DIRTY)) {\n            TAILQ_REMOVE(&jbd_buf->block_rec->dirty_buf_queue,\n                    jbd_buf,\n                    dirty_buf_node);\n\n            jbd_buf->block.buf->end_write = NULL;\n            jbd_buf->block.buf->end_write_arg = NULL;\n\n            /* The buffer has not been modified, just release\n             * that jbd_buf. */\n            jbd_trans_finish_callback(journal,\n                    trans,\n                    jbd_buf->block_rec,\n                    true,\n                    RB_FIND(jbd_revoke_tree,\n                        &trans->revoke_root,\n                        &tmp_rec));\n            jbd_trans_remove_block_rec(journal,\n                    jbd_buf->block_rec, trans);\n            trans->data_cnt--;\n\n            ext4_block_set(fs->bdev, &jbd_buf->block);\n            TAILQ_REMOVE(&trans->buf_queue, jbd_buf, buf_node);\n            ext4_free(jbd_buf);\n            continue;\n        }\n        checksum = jbd_block_csum(journal->jbd_fs,\n                      jbd_buf->block.data,\n                      checksum,\n                      trans->trans_id);\n        if (((struct jbd_bhdr *)jbd_buf->block.data)->magic ==\n                to_be32(JBD_MAGIC_NUMBER))\n            is_escape = true;\n\nagain:\n        if (!desc_iblock) {\n            desc_iblock = jbd_journal_alloc_block(journal, trans);\n            rc = jbd_block_get_noread(journal->jbd_fs, &desc_block, desc_iblock);\n            if (rc != EOK)\n                break;\n\n            bhdr = (struct jbd_bhdr *)desc_block.data;\n            jbd_set32(bhdr, magic, JBD_MAGIC_NUMBER);\n            jbd_set32(bhdr, blocktype, JBD_DESCRIPTOR_BLOCK);\n            jbd_set32(bhdr, sequence, trans->trans_id);\n\n            tag_start = (char *)(bhdr + 1);\n            tag_ptr = tag_start;\n            uuid_exist = true;\n            tag_tbl_size = journal->block_size -\n                sizeof(struct jbd_bhdr);\n\n            if (jbd_has_csum(&journal->jbd_fs->sb))\n                tag_tbl_size -= sizeof(struct jbd_block_tail);\n\n            if (!trans->start_iblock)\n                trans->start_iblock = desc_iblock;\n\n            ext4_bcache_set_dirty(desc_block.buf);\n            ext4_bcache_set_flag(desc_block.buf, BC_TMP);\n        }\n        tag_info.block = jbd_buf->block.lb_id;\n        tag_info.uuid_exist = uuid_exist;\n        tag_info.is_escape = is_escape;\n        if (i == trans->data_cnt - 1)\n            tag_info.last_tag = true;\n        else\n            tag_info.last_tag = false;\n\n        tag_info.checksum = checksum;\n\n        if (uuid_exist)\n            memcpy(tag_info.uuid, journal->jbd_fs->sb.uuid,\n                    UUID_SIZE);\n\n        rc = jbd_write_block_tag(journal->jbd_fs,\n                tag_ptr,\n                tag_tbl_size,\n                &tag_info);\n        if (rc != EOK) {\n            jbd_meta_csum_set(journal->jbd_fs, bhdr);\n            desc_iblock = 0;\n            rc = jbd_block_set(journal->jbd_fs, &desc_block);\n            if (rc != EOK)\n                break;\n\n            goto again;\n        }\n\n        data_iblock = jbd_journal_alloc_block(journal, trans);\n        rc = jbd_block_get_noread(journal->jbd_fs, &data_block, data_iblock);\n        if (rc != EOK) {\n            desc_iblock = 0;\n            ext4_bcache_clear_dirty(desc_block.buf);\n            jbd_block_set(journal->jbd_fs, &desc_block);\n            break;\n        }\n\n        data = data_block.data;\n        memcpy(data, jbd_buf->block.data,\n            journal->block_size);\n        if (is_escape)\n            ((struct jbd_bhdr *)data)->magic = 0;\n\n        ext4_bcache_set_dirty(data_block.buf);\n        ext4_bcache_set_flag(data_block.buf, BC_TMP);\n        rc = jbd_block_set(journal->jbd_fs, &data_block);\n        if (rc != EOK) {\n            desc_iblock = 0;\n            ext4_bcache_clear_dirty(desc_block.buf);\n            jbd_block_set(journal->jbd_fs, &desc_block);\n            break;\n        }\n        jbd_buf->jbd_lba = data_iblock;\n\n        tag_ptr += tag_info.tag_bytes;\n        tag_tbl_size -= tag_info.tag_bytes;\n\n        i++;\n    }\n    if (rc == EOK && desc_iblock) {\n        jbd_meta_csum_set(journal->jbd_fs,\n                (struct jbd_bhdr *)bhdr);\n        trans->data_csum = checksum;\n        rc = jbd_block_set(journal->jbd_fs, &desc_block);\n    }\n\n    return rc;\n}\n\n/**@brief  Write revoke block for a transaction\n * @param  journal current journal session\n * @param  trans transaction\n * @return standard error code*/\nstatic int\njbd_journal_prepare_revoke(struct jbd_journal *journal,\n               struct jbd_trans *trans)\n{\n    int rc = EOK, i = 0;\n    struct ext4_block desc_block = EXT4_BLOCK_ZERO();\n    int32_t tag_tbl_size = 0;\n    uint32_t desc_iblock = 0;\n    char *blocks_entry = NULL;\n    struct jbd_revoke_rec *rec, *tmp;\n    struct jbd_revoke_header *header = NULL;\n    int32_t record_len = 4;\n    struct jbd_bhdr *bhdr = NULL;\n\n    if (JBD_HAS_INCOMPAT_FEATURE(&journal->jbd_fs->sb,\n                     JBD_FEATURE_INCOMPAT_64BIT))\n        record_len = 8;\n\n    RB_FOREACH_SAFE(rec, jbd_revoke_tree, &trans->revoke_root,\n              tmp) {\nagain:\n        if (!desc_iblock) {\n            desc_iblock = jbd_journal_alloc_block(journal, trans);\n            rc = jbd_block_get_noread(journal->jbd_fs, &desc_block,\n                          desc_iblock);\n            if (rc != EOK)\n                break;\n\n            bhdr = (struct jbd_bhdr *)desc_block.data;\n            jbd_set32(bhdr, magic, JBD_MAGIC_NUMBER);\n            jbd_set32(bhdr, blocktype, JBD_REVOKE_BLOCK);\n            jbd_set32(bhdr, sequence, trans->trans_id);\n\n            header = (struct jbd_revoke_header *)bhdr;\n            blocks_entry = (char *)(header + 1);\n            tag_tbl_size = journal->block_size -\n                sizeof(struct jbd_revoke_header);\n\n            if (jbd_has_csum(&journal->jbd_fs->sb))\n                tag_tbl_size -= sizeof(struct jbd_block_tail);\n\n            if (!trans->start_iblock)\n                trans->start_iblock = desc_iblock;\n\n            ext4_bcache_set_dirty(desc_block.buf);\n            ext4_bcache_set_flag(desc_block.buf, BC_TMP);\n        }\n\n        if (tag_tbl_size < record_len) {\n            jbd_set32(header, count,\n                  journal->block_size - tag_tbl_size);\n            jbd_meta_csum_set(journal->jbd_fs, bhdr);\n            bhdr = NULL;\n            desc_iblock = 0;\n            header = NULL;\n            rc = jbd_block_set(journal->jbd_fs, &desc_block);\n            if (rc != EOK)\n                break;\n\n            goto again;\n        }\n        if (record_len == 8) {\n            uint64_t *blocks =\n                (uint64_t *)blocks_entry;\n            *blocks = to_be64(rec->lba);\n        } else {\n            uint32_t *blocks =\n                (uint32_t *)blocks_entry;\n            *blocks = to_be32((uint32_t)rec->lba);\n        }\n        blocks_entry += record_len;\n        tag_tbl_size -= record_len;\n\n        i++;\n    }\n    if (rc == EOK && desc_iblock) {\n        if (header != NULL)\n            jbd_set32(header, count,\n                  journal->block_size - tag_tbl_size);\n\n        jbd_meta_csum_set(journal->jbd_fs, bhdr);\n        rc = jbd_block_set(journal->jbd_fs, &desc_block);\n    }\n\n    return rc;\n}\n\n/**@brief  Put references of block descriptors in a transaction.\n * @param  journal current journal session\n * @param  trans transaction*/\nvoid jbd_journal_cp_trans(struct jbd_journal *journal, struct jbd_trans *trans)\n{\n    struct jbd_buf *jbd_buf, *tmp;\n    struct ext4_fs *fs = journal->jbd_fs->inode_ref.fs;\n    TAILQ_FOREACH_SAFE(jbd_buf, &trans->buf_queue, buf_node,\n            tmp) {\n        struct ext4_block block = jbd_buf->block;\n        ext4_block_set(fs->bdev, &block);\n    }\n}\n\n/**@brief  Update the start block of the journal when\n *         all the contents in a transaction reach the disk.*/\nstatic void jbd_trans_end_write(struct ext4_bcache *bc __unused,\n              struct ext4_buf *buf,\n              int res,\n              void *arg)\n{\n    struct jbd_buf *jbd_buf = arg;\n    struct jbd_trans *trans = jbd_buf->trans;\n    struct jbd_block_rec *block_rec = jbd_buf->block_rec;\n    struct jbd_journal *journal = trans->journal;\n    bool first_in_queue =\n        trans == TAILQ_FIRST(&journal->cp_queue);\n    if (res != EOK)\n        trans->error = res;\n\n    TAILQ_REMOVE(&trans->buf_queue, jbd_buf, buf_node);\n    TAILQ_REMOVE(&block_rec->dirty_buf_queue,\n            jbd_buf,\n            dirty_buf_node);\n\n    jbd_trans_finish_callback(journal,\n            trans,\n            jbd_buf->block_rec,\n            false,\n            false);\n    if (block_rec->trans == trans && buf) {\n        /* Clear the end_write and end_write_arg fields. */\n        buf->end_write = NULL;\n        buf->end_write_arg = NULL;\n    }\n\n    ext4_free(jbd_buf);\n\n    trans->written_cnt++;\n    if (trans->written_cnt == trans->data_cnt) {\n        /* If it is the first transaction on checkpoint queue,\n         * we will shift the start of the journal to the next\n         * transaction, and remove subsequent written\n         * transactions from checkpoint queue until we find\n         * an unwritten one. */\n        if (first_in_queue) {\n            journal->start = trans->start_iblock +\n                trans->alloc_blocks;\n            wrap(&journal->jbd_fs->sb, journal->start);\n            journal->trans_id = trans->trans_id + 1;\n            TAILQ_REMOVE(&journal->cp_queue, trans, trans_node);\n            jbd_journal_free_trans(journal, trans, false);\n\n            jbd_journal_purge_cp_trans(journal, false, false);\n            jbd_journal_write_sb(journal);\n            jbd_write_sb(journal->jbd_fs);\n        }\n    }\n}\n\n/**@brief  Commit a transaction to the journal immediately.\n * @param  journal current journal session\n * @param  trans transaction\n * @return standard error code*/\nstatic int __jbd_journal_commit_trans(struct jbd_journal *journal,\n                      struct jbd_trans *trans)\n{\n    int rc = EOK;\n    uint32_t last = journal->last;\n    struct jbd_revoke_rec *rec, *tmp;\n\n    trans->trans_id = journal->alloc_trans_id;\n    rc = jbd_journal_prepare(journal, trans);\n    if (rc != EOK)\n        goto Finish;\n\n    rc = jbd_journal_prepare_revoke(journal, trans);\n    if (rc != EOK)\n        goto Finish;\n\n    if (TAILQ_EMPTY(&trans->buf_queue) &&\n        RB_EMPTY(&trans->revoke_root)) {\n        /* Since there are no entries in both buffer list\n         * and revoke entry list, we do not consider trans as\n         * complete transaction and just return EOK.*/\n        jbd_journal_free_trans(journal, trans, false);\n        goto Finish;\n    }\n\n    rc = jbd_trans_write_commit_block(trans);\n    if (rc != EOK)\n        goto Finish;\n\n    journal->alloc_trans_id++;\n\n    /* Complete the checkpoint of buffers which are revoked. */\n    RB_FOREACH_SAFE(rec, jbd_revoke_tree, &trans->revoke_root,\n            tmp) {\n        struct jbd_block_rec *block_rec =\n            jbd_trans_block_rec_lookup(journal, rec->lba);\n        struct jbd_buf *jbd_buf = NULL;\n        if (block_rec)\n            jbd_buf = TAILQ_LAST(&block_rec->dirty_buf_queue,\n                    jbd_buf_dirty);\n        if (jbd_buf) {\n            struct ext4_buf *buf;\n            struct ext4_block block = EXT4_BLOCK_ZERO();\n            /*\n             * We do this to reset the ext4_buf::end_write and\n             * ext4_buf::end_write_arg fields so that the checkpoint\n             * callback won't be triggered again.\n             */\n            buf = ext4_bcache_find_get(journal->jbd_fs->bdev->bc,\n                    &block,\n                    jbd_buf->block_rec->lba);\n            jbd_trans_end_write(journal->jbd_fs->bdev->bc,\n                    buf,\n                    EOK,\n                    jbd_buf);\n            if (buf)\n                ext4_block_set(journal->jbd_fs->bdev, &block);\n        }\n    }\n\n    if (TAILQ_EMPTY(&journal->cp_queue)) {\n        /*\n         * This transaction is going to be the first object in the\n         * checkpoint queue.\n         * When the first transaction in checkpoint queue is completely\n         * written to disk, we shift the tail of the log to right.\n         */\n        if (trans->data_cnt) {\n            journal->start = trans->start_iblock;\n            wrap(&journal->jbd_fs->sb, journal->start);\n            journal->trans_id = trans->trans_id;\n            jbd_journal_write_sb(journal);\n            jbd_write_sb(journal->jbd_fs);\n            TAILQ_INSERT_TAIL(&journal->cp_queue, trans,\n                    trans_node);\n            jbd_journal_cp_trans(journal, trans);\n        } else {\n            journal->start = trans->start_iblock +\n                trans->alloc_blocks;\n            wrap(&journal->jbd_fs->sb, journal->start);\n            journal->trans_id = trans->trans_id + 1;\n            jbd_journal_write_sb(journal);\n            jbd_journal_free_trans(journal, trans, false);\n        }\n    } else {\n        /* No need to do anything to the JBD superblock. */\n        TAILQ_INSERT_TAIL(&journal->cp_queue, trans,\n                trans_node);\n        if (trans->data_cnt)\n            jbd_journal_cp_trans(journal, trans);\n    }\nFinish:\n    if (rc != EOK && rc != ENOSPC) {\n        journal->last = last;\n        jbd_journal_free_trans(journal, trans, true);\n    }\n    return rc;\n}\n\n/**@brief  Allocate a new transaction\n * @param  journal current journal session\n * @return transaction allocated*/\nstruct jbd_trans *\njbd_journal_new_trans(struct jbd_journal *journal)\n{\n    struct jbd_trans *trans = NULL;\n    trans = ext4_calloc(1, sizeof(struct jbd_trans));\n    if (!trans)\n        return NULL;\n\n    /* We will assign a trans_id to this transaction,\n     * once it has been committed.*/\n    trans->journal = journal;\n    trans->data_csum = EXT4_CRC32_INIT;\n    trans->error = EOK;\n    TAILQ_INIT(&trans->buf_queue);\n    return trans;\n}\n\n/**@brief  Commit a transaction to the journal immediately.\n * @param  journal current journal session\n * @param  trans transaction\n * @return standard error code*/\nint jbd_journal_commit_trans(struct jbd_journal *journal,\n                 struct jbd_trans *trans)\n{\n    int r = EOK;\n    r = __jbd_journal_commit_trans(journal, trans);\n    return r;\n}\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/src/ext4_mbr.c",
    "content": "/*\n * Copyright (c) 2015 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_mbr.c\n * @brief Master boot record parser\n */\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_misc.h>\n#include <ext4_errno.h>\n#include <ext4_debug.h>\n\n#include <ext4_mbr.h>\n\n#include <inttypes.h>\n#include <string.h>\n\n#define MBR_SIGNATURE 0xAA55\n\n#pragma pack(push, 1)\n\nstruct ext4_part_entry {\n    uint8_t status;\n    uint8_t chs1[3];\n    uint8_t type;\n    uint8_t chs2[3];\n    uint32_t first_lba;\n    uint32_t sectors;\n};\n\nstruct ext4_mbr {\n    uint8_t bootstrap[442];\n    uint32_t disk_id;\n    struct ext4_part_entry part_entry[4];\n    uint16_t signature;\n};\n\n#pragma pack(pop)\n\nint ext4_mbr_scan(struct ext4_blockdev *parent, struct ext4_mbr_bdevs *bdevs)\n{\n    int r;\n    size_t i;\n\n    ext4_dbg(DEBUG_MBR, DBG_INFO \"ext4_mbr_scan\\n\");\n    memset(bdevs, 0, sizeof(struct ext4_mbr_bdevs));\n    r = ext4_block_init(parent);\n    if (r != EOK)\n        return r;\n\n    r = ext4_block_readbytes(parent, 0, parent->bdif->ph_bbuf, 512);\n    if (r != EOK) {\n        goto blockdev_fini;\n    }\n\n    const struct ext4_mbr *mbr = (void *)parent->bdif->ph_bbuf;\n\n    if (to_le16(mbr->signature) != MBR_SIGNATURE) {\n        ext4_dbg(DEBUG_MBR, DBG_ERROR \"ext4_mbr_scan: unknown \"\n             \"signature: 0x%x\\n\", to_le16(mbr->signature));\n        r = ENOENT;\n        goto blockdev_fini;\n    }\n\n    /*Show bootstrap code*/\n    ext4_dbg(DEBUG_MBR, \"mbr_part: bootstrap:\");\n    for (i = 0; i < sizeof(mbr->bootstrap); ++i) {\n        if (!(i & 0xF))\n                ext4_dbg(DEBUG_MBR | DEBUG_NOPREFIX, \"\\n\");\n        ext4_dbg(DEBUG_MBR | DEBUG_NOPREFIX, \"%02x, \", mbr->bootstrap[i]);\n    }\n\n    ext4_dbg(DEBUG_MBR | DEBUG_NOPREFIX, \"\\n\\n\");\n    for (i = 0; i < 4; ++i) {\n        const struct ext4_part_entry *pe = &mbr->part_entry[i];\n        ext4_dbg(DEBUG_MBR, \"mbr_part: %d\\n\", (int)i);\n        ext4_dbg(DEBUG_MBR, \"\\tstatus: 0x%x\\n\", pe->status);\n        ext4_dbg(DEBUG_MBR, \"\\ttype 0x%x:\\n\", pe->type);\n        ext4_dbg(DEBUG_MBR, \"\\tfirst_lba: 0x%\"PRIx32\"\\n\", pe->first_lba);\n        ext4_dbg(DEBUG_MBR, \"\\tsectors: 0x%\"PRIx32\"\\n\", pe->sectors);\n\n        if (!pe->sectors)\n            continue; /*Empty entry*/\n\n        if (pe->type != 0x83)\n            continue; /*Unsupported entry. 0x83 - linux native*/\n\n        bdevs->partitions[i].bdif = parent->bdif;\n        bdevs->partitions[i].part_offset =\n            (uint64_t)pe->first_lba * 512;\n        bdevs->partitions[i].part_size =\n            (uint64_t)pe->sectors * 512;\n    }\n\n    blockdev_fini:\n    ext4_block_fini(parent);\n    return r;\n}\n\nint ext4_mbr_write(struct ext4_blockdev *parent, struct ext4_mbr_parts *parts, uint32_t disk_id)\n{\n    int r;\n    uint64_t disk_size;\n    uint32_t division_sum = parts->division[0] + parts->division[1] +\n                parts->division[2] + parts->division[3];\n\n    if (division_sum > 100)\n        return EINVAL;\n\n    ext4_dbg(DEBUG_MBR, DBG_INFO \"ext4_mbr_write\\n\");\n    r = ext4_block_init(parent);\n    if (r != EOK)\n        return r;\n\n    disk_size = parent->part_size;\n\n    /*Calculate CHS*/\n    uint32_t k = 16;\n    while ((k < 256) && ((disk_size / k / 63) > 1024))\n        k *= 2;\n\n    if (k == 256)\n        --k;\n\n    const uint32_t cyl_size = 63 * k;\n    const uint32_t cyl_count = disk_size / cyl_size;\n\n    struct ext4_mbr *mbr = (void *)parent->bdif->ph_bbuf;\n    memset(mbr, 0, sizeof(struct ext4_mbr));\n\n    mbr->disk_id = disk_id;\n\n    uint32_t cyl_it = 0;\n    for (int i = 0; i < 4; ++i) {\n        uint32_t cyl_part = cyl_count * parts->division[i] / 100;\n        if (!cyl_part)\n            continue;\n\n        uint32_t part_start = cyl_it * cyl_size;\n        uint32_t part_size = cyl_part * cyl_size;\n\n        if (i == 0) {\n            part_start += 63;\n            part_size -= 63 * parent->bdif->ph_bsize;\n        }\n\n        uint32_t cyl_end = cyl_part + cyl_it - 1;\n\n        mbr->part_entry[i].status = 0;\n        mbr->part_entry[i].chs1[0] = i ? 0 : 1;;\n        mbr->part_entry[i].chs1[1] = (cyl_it >> 2) + 1;\n        mbr->part_entry[i].chs1[2] = cyl_it;\n        mbr->part_entry[i].type = 0x83;\n        mbr->part_entry[i].chs2[0] = k - 1;\n        mbr->part_entry[i].chs2[1] = (cyl_end >> 2) + 63;\n        mbr->part_entry[i].chs2[2] = cyl_end;\n\n        mbr->part_entry[i].first_lba = part_start;\n        mbr->part_entry[i].sectors = part_size / parent->bdif->ph_bsize;\n\n        cyl_it += cyl_part;\n    }\n\n    mbr->signature = MBR_SIGNATURE;\n    r = ext4_block_writebytes(parent, 0, parent->bdif->ph_bbuf, 512);\n    if (r != EOK)\n        goto blockdev_fini;\n\n\n    blockdev_fini:\n    ext4_block_fini(parent);\n    return r;\n}\n\n/**\n * @}\n */\n\n"
  },
  {
    "path": "user.libs/liblwext4/src/ext4_mkfs.c",
    "content": "/*\n * Copyright (c) 2015 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_mkfs.c\n * @brief\n */\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_misc.h>\n#include <ext4_errno.h>\n#include <ext4_debug.h>\n\n#include <ext4_super.h>\n#include <ext4_block_group.h>\n#include <ext4_dir.h>\n#include <ext4_dir_idx.h>\n#include <ext4_fs.h>\n#include <ext4_inode.h>\n#include <ext4_ialloc.h>\n#include <ext4_mkfs.h>\n\n#include <inttypes.h>\n#include <string.h>\n#include <stdlib.h>\n\nstruct fs_aux_info {\n    struct ext4_sblock *sb;\n    uint8_t *bg_desc_blk;\n    struct xattr_list_element *xattrs;\n    uint32_t first_data_block;\n    uint64_t len_blocks;\n    uint32_t inode_table_blocks;\n    uint32_t groups;\n    uint32_t bg_desc_blocks;\n    uint32_t default_i_flags;\n    uint32_t blocks_per_ind;\n    uint32_t blocks_per_dind;\n    uint32_t blocks_per_tind;\n};\n\nstatic inline int log_2(int j)\n{\n    int i;\n\n    for (i = 0; j > 0; i++)\n        j >>= 1;\n\n    return i - 1;\n}\n\nstatic int sb2info(struct ext4_sblock *sb, struct ext4_mkfs_info *info)\n{\n        if (to_le16(sb->magic) != EXT4_SUPERBLOCK_MAGIC)\n                return EINVAL;\n\n    info->block_size = 1024 << to_le32(sb->log_block_size);\n    info->blocks_per_group = to_le32(sb->blocks_per_group);\n    info->inodes_per_group = to_le32(sb->inodes_per_group);\n    info->inode_size = to_le16(sb->inode_size);\n    info->inodes = to_le32(sb->inodes_count);\n    info->feat_ro_compat = to_le32(sb->features_read_only);\n    info->feat_compat = to_le32(sb->features_compatible);\n    info->feat_incompat = to_le32(sb->features_incompatible);\n    info->bg_desc_reserve_blocks = to_le16(sb->s_reserved_gdt_blocks);\n    info->label = sb->volume_name;\n    info->len = (uint64_t)info->block_size * ext4_sb_get_blocks_cnt(sb);\n    info->dsc_size = to_le16(sb->desc_size);\n    memcpy(info->uuid, sb->uuid, UUID_SIZE);\n\n    return EOK;\n}\n\nstatic uint32_t compute_blocks_per_group(struct ext4_mkfs_info *info)\n{\n    return info->block_size * 8;\n}\n\nstatic uint32_t compute_inodes(struct ext4_mkfs_info *info)\n{\n    return (uint32_t)EXT4_DIV_ROUND_UP(info->len, info->block_size) / 4;\n}\n\nstatic uint32_t compute_inodes_per_group(struct ext4_mkfs_info *info)\n{\n    uint32_t blocks = (uint32_t)EXT4_DIV_ROUND_UP(info->len, info->block_size);\n    uint32_t block_groups = EXT4_DIV_ROUND_UP(blocks, info->blocks_per_group);\n    uint32_t inodes = EXT4_DIV_ROUND_UP(info->inodes, block_groups);\n    inodes = EXT4_ALIGN(inodes, (info->block_size / info->inode_size));\n\n    /* After properly rounding up the number of inodes/group,\n     * make sure to update the total inodes field in the info struct.\n     */\n    info->inodes = inodes * block_groups;\n\n    return inodes;\n}\n\n\nstatic uint32_t compute_journal_blocks(struct ext4_mkfs_info *info)\n{\n    uint32_t journal_blocks = (uint32_t)EXT4_DIV_ROUND_UP(info->len,\n                         info->block_size) / 64;\n    if (journal_blocks < 1024)\n        journal_blocks = 1024;\n    if (journal_blocks > 32768)\n        journal_blocks = 32768;\n    return journal_blocks;\n}\n\nstatic bool has_superblock(struct ext4_mkfs_info *info, uint32_t bgid)\n{\n    if (!(info->feat_ro_compat & EXT4_FRO_COM_SPARSE_SUPER))\n        return true;\n\n    return ext4_sb_sparse(bgid);\n}\n\nstatic int create_fs_aux_info(struct fs_aux_info *aux_info,\n                  struct ext4_mkfs_info *info)\n{\n    aux_info->first_data_block = (info->block_size > 1024) ? 0 : 1;\n    aux_info->len_blocks = info->len / info->block_size;\n    aux_info->inode_table_blocks = EXT4_DIV_ROUND_UP(info->inodes_per_group *\n            info->inode_size, info->block_size);\n    aux_info->groups = (uint32_t)EXT4_DIV_ROUND_UP(aux_info->len_blocks -\n            aux_info->first_data_block, info->blocks_per_group);\n    aux_info->blocks_per_ind = info->block_size / sizeof(uint32_t);\n    aux_info->blocks_per_dind =\n            aux_info->blocks_per_ind * aux_info->blocks_per_ind;\n    aux_info->blocks_per_tind =\n            aux_info->blocks_per_dind * aux_info->blocks_per_dind;\n\n    aux_info->bg_desc_blocks =\n        EXT4_DIV_ROUND_UP(aux_info->groups * info->dsc_size,\n            info->block_size);\n\n    aux_info->default_i_flags = EXT4_INODE_FLAG_NOATIME;\n\n    uint32_t last_group_size = aux_info->len_blocks % info->blocks_per_group;\n    uint32_t last_header_size = 2 + aux_info->inode_table_blocks;\n    if (has_superblock(info, aux_info->groups - 1))\n        last_header_size += 1 + aux_info->bg_desc_blocks +\n            info->bg_desc_reserve_blocks;\n\n    if (last_group_size > 0 && last_group_size < last_header_size) {\n        aux_info->groups--;\n        aux_info->len_blocks -= last_group_size;\n    }\n\n    aux_info->sb = ext4_calloc(1, EXT4_SUPERBLOCK_SIZE);\n    if (!aux_info->sb)\n        return ENOMEM;\n\n    aux_info->bg_desc_blk = ext4_calloc(1, info->block_size);\n    if (!aux_info->bg_desc_blk)\n        return ENOMEM;\n\n    aux_info->xattrs = NULL;\n\n\n    ext4_dbg(DEBUG_MKFS, DBG_INFO \"create_fs_aux_info\\n\");\n    ext4_dbg(DEBUG_MKFS, DBG_NONE \"first_data_block: %\"PRIu32\"\\n\",\n            aux_info->first_data_block);\n    ext4_dbg(DEBUG_MKFS, DBG_NONE \"len_blocks: %\"PRIu64\"\\n\",\n            aux_info->len_blocks);\n    ext4_dbg(DEBUG_MKFS, DBG_NONE \"inode_table_blocks: %\"PRIu32\"\\n\",\n            aux_info->inode_table_blocks);\n    ext4_dbg(DEBUG_MKFS, DBG_NONE \"groups: %\"PRIu32\"\\n\",\n            aux_info->groups);\n    ext4_dbg(DEBUG_MKFS, DBG_NONE \"bg_desc_blocks: %\"PRIu32\"\\n\",\n            aux_info->bg_desc_blocks);\n    ext4_dbg(DEBUG_MKFS, DBG_NONE \"default_i_flags: %\"PRIu32\"\\n\",\n            aux_info->default_i_flags);\n    ext4_dbg(DEBUG_MKFS, DBG_NONE \"blocks_per_ind: %\"PRIu32\"\\n\",\n            aux_info->blocks_per_ind);\n    ext4_dbg(DEBUG_MKFS, DBG_NONE \"blocks_per_dind: %\"PRIu32\"\\n\",\n            aux_info->blocks_per_dind);\n    ext4_dbg(DEBUG_MKFS, DBG_NONE \"blocks_per_tind: %\"PRIu32\"\\n\",\n            aux_info->blocks_per_tind);\n\n    return EOK;\n}\n\nstatic void release_fs_aux_info(struct fs_aux_info *aux_info)\n{\n    if (aux_info->sb)\n        ext4_free(aux_info->sb);\n    if (aux_info->bg_desc_blk)\n        ext4_free(aux_info->bg_desc_blk);\n}\n\n\n/* Fill in the superblock memory buffer based on the filesystem parameters */\nstatic void fill_sb(struct fs_aux_info *aux_info, struct ext4_mkfs_info *info)\n{\n    struct ext4_sblock *sb = aux_info->sb;\n\n    sb->inodes_count = to_le32(info->inodes_per_group * aux_info->groups);\n\n    ext4_sb_set_blocks_cnt(sb, aux_info->len_blocks);\n    ext4_sb_set_free_blocks_cnt(sb, aux_info->len_blocks);\n    sb->free_inodes_count = to_le32(info->inodes_per_group * aux_info->groups);\n\n    sb->reserved_blocks_count_lo = to_le32(0);\n    sb->first_data_block = to_le32(aux_info->first_data_block);\n    sb->log_block_size = to_le32(log_2(info->block_size / 1024));\n    sb->log_cluster_size = to_le32(log_2(info->block_size / 1024));\n    sb->blocks_per_group = to_le32(info->blocks_per_group);\n    sb->frags_per_group = to_le32(info->blocks_per_group);\n    sb->inodes_per_group = to_le32(info->inodes_per_group);\n    sb->mount_time = to_le32(0);\n    sb->write_time = to_le32(0);\n    sb->mount_count = to_le16(0);\n    sb->max_mount_count = to_le16(0xFFFF);\n    sb->magic = to_le16(EXT4_SUPERBLOCK_MAGIC);\n    sb->state = to_le16(EXT4_SUPERBLOCK_STATE_VALID_FS);\n    sb->errors = to_le16(EXT4_SUPERBLOCK_ERRORS_RO);\n    sb->minor_rev_level = to_le16(0);\n    sb->last_check_time = to_le32(0);\n    sb->check_interval = to_le32(0);\n    sb->creator_os = to_le32(EXT4_SUPERBLOCK_OS_LINUX);\n    sb->rev_level = to_le32(1);\n    sb->def_resuid = to_le16(0);\n    sb->def_resgid = to_le16(0);\n\n    sb->first_inode = to_le32(EXT4_GOOD_OLD_FIRST_INO);\n    sb->inode_size = to_le16(info->inode_size);\n    sb->block_group_index = to_le16(0);\n\n    sb->features_compatible = to_le32(info->feat_compat);\n    sb->features_incompatible = to_le32(info->feat_incompat);\n    sb->features_read_only = to_le32(info->feat_ro_compat);\n\n    memcpy(sb->uuid, info->uuid, UUID_SIZE);\n\n    memset(sb->volume_name, 0, sizeof(sb->volume_name));\n    strncpy(sb->volume_name, info->label, sizeof(sb->volume_name));\n    memset(sb->last_mounted, 0, sizeof(sb->last_mounted));\n\n    sb->algorithm_usage_bitmap = to_le32(0);\n    sb->s_prealloc_blocks = 0;\n    sb->s_prealloc_dir_blocks = 0;\n    sb->s_reserved_gdt_blocks = to_le16(info->bg_desc_reserve_blocks);\n\n    if (info->feat_compat & EXT4_FCOM_HAS_JOURNAL)\n        sb->journal_inode_number = to_le32(EXT4_JOURNAL_INO);\n\n    sb->journal_backup_type = 1;\n    sb->journal_dev = to_le32(0);\n    sb->last_orphan = to_le32(0);\n    sb->hash_seed[0] = to_le32(0x11111111);\n    sb->hash_seed[1] = to_le32(0x22222222);\n    sb->hash_seed[2] = to_le32(0x33333333);\n    sb->hash_seed[3] = to_le32(0x44444444);\n    sb->default_hash_version = EXT2_HTREE_HALF_MD4;\n    sb->checksum_type = 1;\n    sb->desc_size = to_le16(info->dsc_size);\n    sb->default_mount_opts = to_le32(0);\n    sb->first_meta_bg = to_le32(0);\n    sb->mkfs_time = to_le32(0);\n\n    sb->reserved_blocks_count_hi = to_le32(0);\n    sb->min_extra_isize = to_le32(sizeof(struct ext4_inode) -\n        EXT4_GOOD_OLD_INODE_SIZE);\n    sb->want_extra_isize = to_le32(sizeof(struct ext4_inode) -\n        EXT4_GOOD_OLD_INODE_SIZE);\n    sb->flags = to_le32(EXT4_SUPERBLOCK_FLAGS_SIGNED_HASH);\n}\n\n\nstatic int write_bgroup_block(struct ext4_blockdev *bd,\n                  struct fs_aux_info *aux_info,\n                  struct ext4_mkfs_info *info,\n                  uint32_t blk)\n{\n    int r = EOK;\n    uint32_t j;\n    struct ext4_block b;\n\n    uint32_t block_size = ext4_sb_get_block_size(aux_info->sb);\n\n    for (j = 0; j < aux_info->groups; j++) {\n        uint64_t bg_start_block = aux_info->first_data_block +\n                      j * info->blocks_per_group;\n        uint32_t blk_off = 0;\n\n        blk_off += aux_info->bg_desc_blocks;\n        if (has_superblock(info, j)) {\n            bg_start_block++;\n            blk_off += info->bg_desc_reserve_blocks;\n        }\n\n        uint64_t dsc_blk = bg_start_block + blk;\n\n        r = ext4_block_get_noread(bd, &b, dsc_blk);\n        if (r != EOK)\n            return r;\n\n        memcpy(b.data, aux_info->bg_desc_blk, block_size);\n\n        ext4_bcache_set_dirty(b.buf);\n        r = ext4_block_set(bd, &b);\n        if (r != EOK)\n            return r;\n    }\n\n    return r;\n}\n\nstatic int write_bgroups(struct ext4_blockdev *bd, struct fs_aux_info *aux_info,\n             struct ext4_mkfs_info *info)\n{\n    int r = EOK;\n\n    struct ext4_block b;\n    struct ext4_bgroup *bg_desc;\n\n    uint32_t i;\n    uint32_t bg_free_blk = 0;\n    uint64_t sb_free_blk = 0;\n    uint32_t block_size = ext4_sb_get_block_size(aux_info->sb);\n    uint32_t dsc_size = ext4_sb_get_desc_size(aux_info->sb);\n    uint32_t dsc_per_block = block_size / dsc_size;\n    uint32_t k = 0;\n\n    for (i = 0; i < aux_info->groups; i++) {\n        uint64_t bg_start_block = aux_info->first_data_block +\n            aux_info->first_data_block + i * info->blocks_per_group;\n        uint32_t blk_off = 0;\n\n        bg_desc = (void *)(aux_info->bg_desc_blk + k * dsc_size);\n        bg_free_blk = info->blocks_per_group -\n                aux_info->inode_table_blocks;\n\n        bg_free_blk -= 2;\n        blk_off += aux_info->bg_desc_blocks;\n\n        if (i == (aux_info->groups - 1))\n            bg_free_blk -= aux_info->first_data_block;\n\n        if (has_superblock(info, i)) {\n            bg_start_block++;\n            blk_off += info->bg_desc_reserve_blocks;\n            bg_free_blk -= info->bg_desc_reserve_blocks + 1;\n            bg_free_blk -= aux_info->bg_desc_blocks;\n        }\n\n        ext4_bg_set_block_bitmap(bg_desc, aux_info->sb,\n                     bg_start_block + blk_off + 1);\n\n        ext4_bg_set_inode_bitmap(bg_desc, aux_info->sb,\n                     bg_start_block + blk_off + 2);\n\n        ext4_bg_set_inode_table_first_block(bg_desc,\n                        aux_info->sb,\n                        bg_start_block + blk_off + 3);\n\n        ext4_bg_set_free_blocks_count(bg_desc, aux_info->sb,\n                          bg_free_blk);\n\n        ext4_bg_set_free_inodes_count(bg_desc,\n                aux_info->sb, to_le32(aux_info->sb->inodes_per_group));\n\n        ext4_bg_set_used_dirs_count(bg_desc, aux_info->sb, 0);\n\n        ext4_bg_set_flag(bg_desc,\n                 EXT4_BLOCK_GROUP_BLOCK_UNINIT |\n                 EXT4_BLOCK_GROUP_INODE_UNINIT);\n\n        sb_free_blk += bg_free_blk;\n\n        r = ext4_block_get_noread(bd, &b, bg_start_block + blk_off + 1);\n        if (r != EOK)\n            return r;\n        memset(b.data, 0, block_size);\n        ext4_bcache_set_dirty(b.buf);\n        r = ext4_block_set(bd, &b);\n        if (r != EOK)\n            return r;\n        r = ext4_block_get_noread(bd, &b, bg_start_block + blk_off + 2);\n        if (r != EOK)\n            return r;\n        memset(b.data, 0, block_size);\n        ext4_bcache_set_dirty(b.buf);\n        r = ext4_block_set(bd, &b);\n        if (r != EOK)\n            return r;\n\n        if (++k != dsc_per_block)\n            continue;\n\n        k = 0;\n        r = write_bgroup_block(bd, aux_info, info, i / dsc_per_block);\n        if (r != EOK)\n            return r;\n\n    }\n\n    r = write_bgroup_block(bd, aux_info, info, i / dsc_per_block);\n    if (r != EOK)\n        return r;\n\n    ext4_sb_set_free_blocks_cnt(aux_info->sb, sb_free_blk);\n    return r;\n}\n\nstatic int write_sblocks(struct ext4_blockdev *bd, struct fs_aux_info *aux_info,\n              struct ext4_mkfs_info *info)\n{\n    uint64_t offset;\n    uint32_t i;\n    int r;\n\n    /* write out the backup superblocks */\n    for (i = 1; i < aux_info->groups; i++) {\n        if (has_superblock(info, i)) {\n            offset = info->block_size * (aux_info->first_data_block\n                + i * info->blocks_per_group);\n\n            aux_info->sb->block_group_index = to_le16(i);\n            r = ext4_block_writebytes(bd, offset, aux_info->sb,\n                          EXT4_SUPERBLOCK_SIZE);\n            if (r != EOK)\n                return r;\n        }\n    }\n\n    /* write out the primary superblock */\n    aux_info->sb->block_group_index = to_le16(0);\n    return ext4_block_writebytes(bd, 1024, aux_info->sb,\n            EXT4_SUPERBLOCK_SIZE);\n}\n\n\nint ext4_mkfs_read_info(struct ext4_blockdev *bd, struct ext4_mkfs_info *info)\n{\n    int r;\n    struct ext4_sblock *sb = NULL;\n    r = ext4_block_init(bd);\n    if (r != EOK)\n        return r;\n\n    sb = ext4_malloc(EXT4_SUPERBLOCK_SIZE);\n    if (!sb)\n        goto Finish;\n\n\n    r = ext4_sb_read(bd, sb);\n    if (r != EOK)\n        goto Finish;\n\n    r = sb2info(sb, info);\n\nFinish:\n    if (sb)\n        ext4_free(sb);\n    ext4_block_fini(bd);\n    return r;\n}\n\nstatic int mkfs_init(struct ext4_blockdev *bd, struct ext4_mkfs_info *info)\n{\n    int r;\n    struct fs_aux_info aux_info;\n    memset(&aux_info, 0, sizeof(struct fs_aux_info));\n\n    r = create_fs_aux_info(&aux_info, info);\n    if (r != EOK)\n        goto Finish;\n\n    fill_sb(&aux_info, info);\n\n    r = write_bgroups(bd, &aux_info, info);\n    if (r != EOK)\n        goto Finish;\n\n    r = write_sblocks(bd, &aux_info, info);\n    if (r != EOK)\n        goto Finish;\n\n    Finish:\n    release_fs_aux_info(&aux_info);\n    return r;\n}\n\nstatic int init_bgs(struct ext4_fs *fs)\n{\n    int r = EOK;\n    struct ext4_block_group_ref ref;\n    uint32_t i;\n    uint32_t bg_count = ext4_block_group_cnt(&fs->sb);\n    for (i = 0; i < bg_count; ++i) {\n        r = ext4_fs_get_block_group_ref(fs, i, &ref);\n        if (r != EOK)\n            break;\n\n        r = ext4_fs_put_block_group_ref(&ref);\n        if (r != EOK)\n            break;\n    }\n    return r;\n}\n\nstatic int alloc_inodes(struct ext4_fs *fs)\n{\n    int r = EOK;\n    int i;\n    struct ext4_inode_ref inode_ref;\n    for (i = 1; i < 12; ++i) {\n        int filetype = EXT4_DE_REG_FILE;\n\n        switch (i) {\n        case EXT4_ROOT_INO:\n        case EXT4_GOOD_OLD_FIRST_INO:\n            filetype = EXT4_DE_DIR;\n            break;\n        default:\n            break;\n        }\n\n        r = ext4_fs_alloc_inode(fs, &inode_ref, filetype);\n        if (r != EOK)\n            return r;\n\n        ext4_inode_set_mode(&fs->sb, inode_ref.inode, 0);\n\n        switch (i) {\n        case EXT4_ROOT_INO:\n        case EXT4_JOURNAL_INO:\n            ext4_fs_inode_blocks_init(fs, &inode_ref);\n            break;\n        }\n\n        ext4_fs_put_inode_ref(&inode_ref);\n    }\n\n    return r;\n}\n\nstatic int create_dirs(struct ext4_fs *fs)\n{\n    int r = EOK;\n    struct ext4_inode_ref root;\n    struct ext4_inode_ref child;\n\n    r = ext4_fs_get_inode_ref(fs, EXT4_ROOT_INO, &root);\n    if (r != EOK)\n        return r;\n\n    r = ext4_fs_get_inode_ref(fs, EXT4_GOOD_OLD_FIRST_INO, &child);\n    if (r != EOK)\n        return r;\n\n    ext4_inode_set_mode(&fs->sb, child.inode,\n            EXT4_INODE_MODE_DIRECTORY | 0777);\n\n    ext4_inode_set_mode(&fs->sb, root.inode,\n            EXT4_INODE_MODE_DIRECTORY | 0777);\n\n#if CONFIG_DIR_INDEX_ENABLE\n    /* Initialize directory index if supported */\n    if (ext4_sb_feature_com(&fs->sb, EXT4_FCOM_DIR_INDEX)) {\n        r = ext4_dir_dx_init(&root, &root);\n        if (r != EOK)\n            return r;\n\n        r = ext4_dir_dx_init(&child, &root);\n        if (r != EOK)\n            return r;\n\n        ext4_inode_set_flag(root.inode, EXT4_INODE_FLAG_INDEX);\n        ext4_inode_set_flag(child.inode, EXT4_INODE_FLAG_INDEX);\n    } else\n#endif\n    {\n        r = ext4_dir_add_entry(&root, \".\", strlen(\".\"), &root);\n        if (r != EOK)\n            return r;\n\n        r = ext4_dir_add_entry(&root, \"..\", strlen(\"..\"), &root);\n        if (r != EOK)\n            return r;\n\n        r = ext4_dir_add_entry(&child, \".\", strlen(\".\"), &child);\n        if (r != EOK)\n            return r;\n\n        r = ext4_dir_add_entry(&child, \"..\", strlen(\"..\"), &root);\n        if (r != EOK)\n            return r;\n    }\n\n    r = ext4_dir_add_entry(&root, \"lost+found\", strlen(\"lost+found\"), &child);\n    if (r != EOK)\n        return r;\n\n    ext4_inode_set_links_cnt(root.inode, 3);\n    ext4_inode_set_links_cnt(child.inode, 2);\n\n    child.dirty = true;\n    root.dirty = true;\n    ext4_fs_put_inode_ref(&child);\n    ext4_fs_put_inode_ref(&root);\n    return r;\n}\n\nstatic int create_journal_inode(struct ext4_fs *fs,\n                struct ext4_mkfs_info *info)\n{\n    int ret;\n    struct ext4_inode_ref inode_ref;\n    uint64_t blocks_count;\n\n    if (!info->journal)\n        return EOK;\n\n    ret = ext4_fs_get_inode_ref(fs, EXT4_JOURNAL_INO, &inode_ref);\n    if (ret != EOK)\n        return ret;\n\n    struct ext4_inode *inode = inode_ref.inode;\n\n    ext4_inode_set_mode(&fs->sb, inode, EXT4_INODE_MODE_FILE | 0600);\n    ext4_inode_set_links_cnt(inode, 1);\n\n    blocks_count = ext4_inode_get_blocks_count(&fs->sb, inode);\n\n    while (blocks_count++ < info->journal_blocks)\n    {\n        ext4_fsblk_t fblock;\n        ext4_lblk_t iblock;\n        struct ext4_block blk;\n\n        ret = ext4_fs_append_inode_dblk(&inode_ref, &fblock, &iblock);\n        if (ret != EOK)\n            goto Finish;\n\n        if (iblock != 0)\n            continue;\n\n        ret = ext4_block_get(fs->bdev, &blk, fblock);\n        if (ret != EOK)\n            goto Finish;\n\n\n        struct jbd_sb * jbd_sb = (struct jbd_sb * )blk.data;\n        memset(jbd_sb, 0, sizeof(struct jbd_sb));\n\n        jbd_sb->header.magic = to_be32(JBD_MAGIC_NUMBER);\n        jbd_sb->header.blocktype = to_be32(JBD_SUPERBLOCK_V2);\n        jbd_sb->blocksize = to_be32(info->block_size);\n        jbd_sb->maxlen = to_be32(info->journal_blocks);\n        jbd_sb->nr_users = to_be32(1);\n        jbd_sb->first = to_be32(1);\n        jbd_sb->sequence = to_be32(1);\n\n        ext4_bcache_set_dirty(blk.buf);\n        ret = ext4_block_set(fs->bdev, &blk);\n        if (ret != EOK)\n            goto Finish;\n    }\n\n    memcpy(fs->sb.journal_blocks, inode->blocks, sizeof(inode->blocks));\n\n    Finish:\n    ext4_fs_put_inode_ref(&inode_ref);\n\n    return ret;\n}\n\nint ext4_mkfs(struct ext4_fs *fs, struct ext4_blockdev *bd,\n          struct ext4_mkfs_info *info, int fs_type)\n{\n    int r;\n\n    r = ext4_block_init(bd);\n    if (r != EOK)\n        return r;\n\n    bd->fs = fs;\n\n    if (info->len == 0)\n        info->len = bd->part_size;\n\n    if (info->block_size == 0)\n        info->block_size = 4096; /*Set block size to default value*/\n\n    /* Round down the filesystem length to be a multiple of the block size */\n    info->len &= ~((uint64_t)info->block_size - 1);\n\n    if (info->journal_blocks == 0)\n        info->journal_blocks = compute_journal_blocks(info);\n\n    if (info->blocks_per_group == 0)\n        info->blocks_per_group = compute_blocks_per_group(info);\n\n    if (info->inodes == 0)\n        info->inodes = compute_inodes(info);\n\n    if (info->inode_size == 0)\n        info->inode_size = 256;\n\n    if (info->label == NULL)\n        info->label = \"\";\n\n    info->inodes_per_group = compute_inodes_per_group(info);\n\n    switch (fs_type) {\n    case F_SET_EXT2:\n        info->feat_compat = EXT2_SUPPORTED_FCOM;\n        info->feat_ro_compat = EXT2_SUPPORTED_FRO_COM;\n        info->feat_incompat = EXT2_SUPPORTED_FINCOM;\n        break;\n    case F_SET_EXT3:\n        info->feat_compat = EXT3_SUPPORTED_FCOM;\n        info->feat_ro_compat = EXT3_SUPPORTED_FRO_COM;\n        info->feat_incompat = EXT3_SUPPORTED_FINCOM;\n        break;\n    case F_SET_EXT4:\n        info->feat_compat = EXT4_SUPPORTED_FCOM;\n        info->feat_ro_compat = EXT4_SUPPORTED_FRO_COM;\n        info->feat_incompat = EXT4_SUPPORTED_FINCOM;\n        break;\n    }\n\n    /*TODO: handle this features some day...*/\n    info->feat_incompat &= ~EXT4_FINCOM_META_BG;\n    info->feat_incompat &= ~EXT4_FINCOM_FLEX_BG;\n    info->feat_incompat &= ~EXT4_FINCOM_64BIT;\n\n    info->feat_ro_compat &= ~EXT4_FRO_COM_METADATA_CSUM;\n    info->feat_ro_compat &= ~EXT4_FRO_COM_GDT_CSUM;\n    info->feat_ro_compat &= ~EXT4_FRO_COM_DIR_NLINK;\n    info->feat_ro_compat &= ~EXT4_FRO_COM_EXTRA_ISIZE;\n    info->feat_ro_compat &= ~EXT4_FRO_COM_HUGE_FILE;\n\n    if (info->journal)\n        info->feat_compat |= EXT4_FCOM_HAS_JOURNAL;\n\n    if (info->dsc_size == 0) {\n\n        if (info->feat_incompat & EXT4_FINCOM_64BIT)\n            info->dsc_size = EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE;\n        else\n            info->dsc_size = EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE;\n    }\n\n    info->bg_desc_reserve_blocks = 0;\n\n    ext4_dbg(DEBUG_MKFS, DBG_INFO \"Creating filesystem with parameters:\\n\");\n    ext4_dbg(DEBUG_MKFS, DBG_NONE \"Size: %\"PRIu64\"\\n\", info->len);\n    ext4_dbg(DEBUG_MKFS, DBG_NONE \"Block size: %\"PRIu32\"\\n\",\n            info->block_size);\n    ext4_dbg(DEBUG_MKFS, DBG_NONE \"Blocks per group: %\"PRIu32\"\\n\",\n            info->blocks_per_group);\n    ext4_dbg(DEBUG_MKFS, DBG_NONE \"Inodes per group: %\"PRIu32\"\\n\",\n            info->inodes_per_group);\n    ext4_dbg(DEBUG_MKFS, DBG_NONE \"Inode size: %\"PRIu32\"\\n\",\n            info->inode_size);\n    ext4_dbg(DEBUG_MKFS, DBG_NONE \"Inodes: %\"PRIu32\"\\n\", info->inodes);\n    ext4_dbg(DEBUG_MKFS, DBG_NONE \"Journal blocks: %\"PRIu32\"\\n\",\n            info->journal_blocks);\n    ext4_dbg(DEBUG_MKFS, DBG_NONE \"Features ro_compat: 0x%x\\n\",\n            info->feat_ro_compat);\n    ext4_dbg(DEBUG_MKFS, DBG_NONE \"Features compat: 0x%x\\n\",\n            info->feat_compat);\n    ext4_dbg(DEBUG_MKFS, DBG_NONE \"Features incompat: 0x%x\\n\",\n            info->feat_incompat);\n    ext4_dbg(DEBUG_MKFS, DBG_NONE \"BG desc reserve: %\"PRIu32\"\\n\",\n            info->bg_desc_reserve_blocks);\n    ext4_dbg(DEBUG_MKFS, DBG_NONE \"Descriptor size: %\"PRIu16\"\\n\",\n            info->dsc_size);\n    ext4_dbg(DEBUG_MKFS, DBG_NONE \"journal: %s\\n\",\n            info->journal ? \"yes\" : \"no\");\n    ext4_dbg(DEBUG_MKFS, DBG_NONE \"Label: %s\\n\", info->label);\n\n    struct ext4_bcache bc;\n\n    memset(&bc, 0, sizeof(struct ext4_bcache));\n    ext4_block_set_lb_size(bd, info->block_size);\n\n    r = ext4_bcache_init_dynamic(&bc, CONFIG_BLOCK_DEV_CACHE_SIZE,\n                      info->block_size);\n    if (r != EOK)\n        goto block_fini;\n\n    /*Bind block cache to block device*/\n    r = ext4_block_bind_bcache(bd, &bc);\n    if (r != EOK)\n        goto cache_fini;\n\n    r = ext4_block_cache_write_back(bd, 1);\n    if (r != EOK)\n        goto cache_fini;\n\n    r = mkfs_init(bd, info);\n    if (r != EOK)\n        goto cache_fini;\n\n    r = ext4_fs_init(fs, bd, false);\n    if (r != EOK)\n        goto cache_fini;\n\n    r = init_bgs(fs);\n    if (r != EOK)\n        goto fs_fini;\n\n    r = alloc_inodes(fs);\n    if (r != EOK)\n        goto fs_fini;\n\n    r = create_dirs(fs);\n    if (r != EOK)\n        goto fs_fini;\n\n    r = create_journal_inode(fs, info);\n    if (r != EOK)\n        goto fs_fini;\n\n    fs_fini:\n    ext4_fs_fini(fs);\n\n    cache_fini:\n    ext4_block_cache_write_back(bd, 0);\n    ext4_bcache_fini_dynamic(&bc);\n\n    block_fini:\n    ext4_block_fini(bd);\n\n    return r;\n}\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/src/ext4_super.c",
    "content": "/*\n * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n *\n *\n * HelenOS:\n * Copyright (c) 2012 Martin Sucha\n * Copyright (c) 2012 Frantisek Princ\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_super.h\n * @brief Superblock operations.\n */\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_misc.h>\n#include <ext4_errno.h>\n#include <ext4_debug.h>\n\n#include <ext4_super.h>\n#include <ext4_crc32.h>\n\nuint32_t ext4_block_group_cnt(struct ext4_sblock *s)\n{\n    uint64_t blocks_count = ext4_sb_get_blocks_cnt(s);\n    uint32_t blocks_per_group = ext4_get32(s, blocks_per_group);\n\n    uint32_t block_groups_count = (uint32_t)(blocks_count / blocks_per_group);\n\n    if (blocks_count % blocks_per_group)\n        block_groups_count++;\n\n    return block_groups_count;\n}\n\nuint32_t ext4_blocks_in_group_cnt(struct ext4_sblock *s, uint32_t bgid)\n{\n    uint32_t block_group_count = ext4_block_group_cnt(s);\n    uint32_t blocks_per_group = ext4_get32(s, blocks_per_group);\n    uint64_t total_blocks = ext4_sb_get_blocks_cnt(s);\n\n    if (bgid < block_group_count - 1)\n        return blocks_per_group;\n\n    return (uint32_t)(total_blocks - ((block_group_count - 1) * blocks_per_group));\n}\n\nuint32_t ext4_inodes_in_group_cnt(struct ext4_sblock *s, uint32_t bgid)\n{\n    uint32_t block_group_count = ext4_block_group_cnt(s);\n    uint32_t inodes_per_group = ext4_get32(s, inodes_per_group);\n    uint32_t total_inodes = ext4_get32(s, inodes_count);\n\n    if (bgid < block_group_count - 1)\n        return inodes_per_group;\n\n    return (total_inodes - ((block_group_count - 1) * inodes_per_group));\n}\n\n#if CONFIG_META_CSUM_ENABLE\nstatic uint32_t ext4_sb_csum(struct ext4_sblock *s)\n{\n\n    return ext4_crc32c(EXT4_CRC32_INIT, s,\n            offsetof(struct ext4_sblock, checksum));\n}\n#else\n#define ext4_sb_csum(...) 0\n#endif\n\nstatic bool ext4_sb_verify_csum(struct ext4_sblock *s)\n{\n    if (!ext4_sb_feature_ro_com(s, EXT4_FRO_COM_METADATA_CSUM))\n        return true;\n\n    if (s->checksum_type != to_le32(EXT4_CHECKSUM_CRC32C))\n        return false;\n\n    return s->checksum == to_le32(ext4_sb_csum(s));\n}\n\nstatic void ext4_sb_set_csum(struct ext4_sblock *s)\n{\n    if (!ext4_sb_feature_ro_com(s, EXT4_FRO_COM_METADATA_CSUM))\n        return;\n\n    s->checksum = to_le32(ext4_sb_csum(s));\n}\n\nint ext4_sb_write(struct ext4_blockdev *bdev, struct ext4_sblock *s)\n{\n    ext4_sb_set_csum(s);\n    return ext4_block_writebytes(bdev, EXT4_SUPERBLOCK_OFFSET, s,\n                     EXT4_SUPERBLOCK_SIZE);\n}\n\nint ext4_sb_read(struct ext4_blockdev *bdev, struct ext4_sblock *s)\n{\n    return ext4_block_readbytes(bdev, EXT4_SUPERBLOCK_OFFSET, s,\n                    EXT4_SUPERBLOCK_SIZE);\n}\n\nbool ext4_sb_check(struct ext4_sblock *s)\n{\n    if (ext4_get16(s, magic) != EXT4_SUPERBLOCK_MAGIC)\n        return false;\n\n    if (ext4_get32(s, inodes_count) == 0)\n        return false;\n\n    if (ext4_sb_get_blocks_cnt(s) == 0)\n        return false;\n\n    if (ext4_get32(s, blocks_per_group) == 0)\n        return false;\n\n    if (ext4_get32(s, inodes_per_group) == 0)\n        return false;\n\n    if (ext4_get16(s, inode_size) < 128)\n        return false;\n\n    if (ext4_get32(s, first_inode) < 11)\n        return false;\n\n    if (ext4_sb_get_desc_size(s) < EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)\n        return false;\n\n    if (ext4_sb_get_desc_size(s) > EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE)\n        return false;\n\n    if (!ext4_sb_verify_csum(s))\n        return false;\n\n    return true;\n}\n\nstatic inline int is_power_of(uint32_t a, uint32_t b)\n{\n    while (1) {\n        if (a < b)\n            return 0;\n        if (a == b)\n            return 1;\n        if ((a % b) != 0)\n            return 0;\n        a = a / b;\n    }\n}\n\nbool ext4_sb_sparse(uint32_t group)\n{\n    if (group <= 1)\n        return 1;\n\n    if (!(group & 1))\n        return 0;\n\n    return (is_power_of(group, 7) || is_power_of(group, 5) ||\n        is_power_of(group, 3));\n}\n\nbool ext4_sb_is_super_in_bg(struct ext4_sblock *s, uint32_t group)\n{\n    if (ext4_sb_feature_ro_com(s, EXT4_FRO_COM_SPARSE_SUPER) &&\n        !ext4_sb_sparse(group))\n        return false;\n    return true;\n}\n\nstatic uint32_t ext4_bg_num_gdb_meta(struct ext4_sblock *s, uint32_t group)\n{\n    uint32_t dsc_per_block =\n        ext4_sb_get_block_size(s) / ext4_sb_get_desc_size(s);\n\n    uint32_t metagroup = group / dsc_per_block;\n    uint32_t first = metagroup * dsc_per_block;\n    uint32_t last = first + dsc_per_block - 1;\n\n    if (group == first || group == first + 1 || group == last)\n        return 1;\n    return 0;\n}\n\nstatic uint32_t ext4_bg_num_gdb_nometa(struct ext4_sblock *s, uint32_t group)\n{\n    if (!ext4_sb_is_super_in_bg(s, group))\n        return 0;\n    uint32_t dsc_per_block =\n        ext4_sb_get_block_size(s) / ext4_sb_get_desc_size(s);\n\n    uint32_t db_count =\n        (ext4_block_group_cnt(s) + dsc_per_block - 1) / dsc_per_block;\n\n    if (ext4_sb_feature_incom(s, EXT4_FINCOM_META_BG))\n        return ext4_sb_first_meta_bg(s);\n\n    return db_count;\n}\n\nuint32_t ext4_bg_num_gdb(struct ext4_sblock *s, uint32_t group)\n{\n    uint32_t dsc_per_block =\n        ext4_sb_get_block_size(s) / ext4_sb_get_desc_size(s);\n    uint32_t first_meta_bg = ext4_sb_first_meta_bg(s);\n    uint32_t metagroup = group / dsc_per_block;\n\n    if (!ext4_sb_feature_incom(s,EXT4_FINCOM_META_BG) ||\n        metagroup < first_meta_bg)\n        return ext4_bg_num_gdb_nometa(s, group);\n\n    return ext4_bg_num_gdb_meta(s, group);\n}\n\nuint32_t ext4_num_base_meta_clusters(struct ext4_sblock *s,\n                     uint32_t block_group)\n{\n    uint32_t num;\n    uint32_t dsc_per_block =\n        ext4_sb_get_block_size(s) / ext4_sb_get_desc_size(s);\n\n    num = ext4_sb_is_super_in_bg(s, block_group);\n\n    if (!ext4_sb_feature_incom(s, EXT4_FINCOM_META_BG) ||\n        block_group < ext4_sb_first_meta_bg(s) * dsc_per_block) {\n        if (num) {\n            num += ext4_bg_num_gdb(s, block_group);\n            num += ext4_get16(s, s_reserved_gdt_blocks);\n        }\n    } else {\n        num += ext4_bg_num_gdb(s, block_group);\n    }\n\n    uint32_t clustersize = 1024 << ext4_get32(s, log_cluster_size);\n    uint32_t cluster_ratio = clustersize / ext4_sb_get_block_size(s);\n    uint32_t v =\n        (num + cluster_ratio - 1) >> ext4_get32(s, log_cluster_size);\n\n    return v;\n}\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/src/ext4_trans.c",
    "content": "/*\n * Copyright (c) 2015 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * Copyright (c) 2015 Kaho Ng (ngkaho1234@gmail.com)\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * - Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * - Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n * - The name of the author may not be used to endorse or promote products\n *   derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_trans.c\n * @brief Ext4 transaction buffer operations.\n */\n\n#include <ext4_config.h>\n#include <ext4_types.h>\n#include <ext4_misc.h>\n#include <ext4_errno.h>\n#include <ext4_debug.h>\n\n#include <ext4_fs.h>\n#include <ext4_journal.h>\n\nint ext4_trans_set_block_dirty(struct ext4_buf *buf)\n{\n    int r = EOK;\n#if CONFIG_JOURNALING_ENABLE\n    struct ext4_fs *fs = buf->bc->bdev->fs;\n    struct ext4_block block = {\n        .lb_id = buf->lba,\n        .data = buf->data,\n        .buf = buf\n    };\n\n    if (fs->jbd_journal && fs->curr_trans) {\n        struct jbd_trans *trans = fs->curr_trans;\n        return jbd_trans_set_block_dirty(trans, &block);\n    }\n#endif\n    ext4_bcache_set_dirty(buf);\n    return r;\n}\n\nint ext4_trans_block_get_noread(struct ext4_blockdev *bdev,\n              struct ext4_block *b,\n              uint64_t lba)\n{\n    int r = ext4_block_get_noread(bdev, b, lba);\n    if (r != EOK)\n        return r;\n\n    return r;\n}\n\nint ext4_trans_block_get(struct ext4_blockdev *bdev,\n           struct ext4_block *b,\n           uint64_t lba)\n{\n    int r = ext4_block_get(bdev, b, lba);\n    if (r != EOK)\n        return r;\n\n    return r;\n}\n\nint ext4_trans_try_revoke_block(struct ext4_blockdev *bdev __unused,\n                    uint64_t lba __unused)\n{\n    int r = EOK;\n#if CONFIG_JOURNALING_ENABLE\n    struct ext4_fs *fs = bdev->fs;\n    if (fs->jbd_journal && fs->curr_trans) {\n        struct jbd_trans *trans = fs->curr_trans;\n        r = jbd_trans_try_revoke_block(trans, lba);\n    } else if (fs->jbd_journal) {\n        r = ext4_block_flush_lba(fs->bdev, lba);\n    }\n#endif\n    return r;\n}\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/liblwext4/src/ext4_xattr.c",
    "content": "/*\n * Copyright (c) 2017 Grzegorz Kostka (kostka.grzegorz@gmail.com)\n * Copyright (c) 2017 Kaho Ng (ngkaho1234@gmail.com)\n *\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; either version 2\n * of the License, or (at your option) any later version.\n */\n\n/** @addtogroup lwext4\n * @{\n */\n/**\n * @file  ext4_xattr.c\n * @brief Extended Attribute manipulation.\n */\n\n#include <ext4_config.h>\n#include <ext4_debug.h>\n#include <ext4_errno.h>\n#include <ext4_misc.h>\n#include <ext4_types.h>\n\n#include <ext4_balloc.h>\n#include <ext4_block_group.h>\n#include <ext4_blockdev.h>\n#include <ext4_crc32.h>\n#include <ext4_fs.h>\n#include <ext4_inode.h>\n#include <ext4_super.h>\n#include <ext4_trans.h>\n#include <ext4_xattr.h>\n\n#include <stdlib.h>\n#include <string.h>\n\n#if CONFIG_XATTR_ENABLE\n\n/**\n * @file  ext4_xattr.c\n * @brief Extended Attribute Manipulation\n */\n\n/* Extended Attribute(EA) */\n\n/* Magic value in attribute blocks */\n#define EXT4_XATTR_MAGIC        0xEA020000\n\n/* Maximum number of references to one attribute block */\n#define EXT4_XATTR_REFCOUNT_MAX     1024\n\n/* Name indexes */\n#define EXT4_XATTR_INDEX_USER           1\n#define EXT4_XATTR_INDEX_POSIX_ACL_ACCESS   2\n#define EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT  3\n#define EXT4_XATTR_INDEX_TRUSTED        4\n#define EXT4_XATTR_INDEX_LUSTRE         5\n#define EXT4_XATTR_INDEX_SECURITY           6\n#define EXT4_XATTR_INDEX_SYSTEM         7\n#define EXT4_XATTR_INDEX_RICHACL        8\n#define EXT4_XATTR_INDEX_ENCRYPTION     9\n\n#define EXT4_XATTR_PAD_BITS 2\n#define EXT4_XATTR_PAD (1 << EXT4_XATTR_PAD_BITS)\n#define EXT4_XATTR_ROUND (EXT4_XATTR_PAD - 1)\n#define EXT4_XATTR_LEN(name_len)                                               \\\n    (((name_len) + EXT4_XATTR_ROUND + sizeof(struct ext4_xattr_entry)) &   \\\n     ~EXT4_XATTR_ROUND)\n#define EXT4_XATTR_NEXT(entry)                                                 \\\n    ((struct ext4_xattr_entry *)((char *)(entry) +                         \\\n                     EXT4_XATTR_LEN((entry)->e_name_len)))\n#define EXT4_XATTR_SIZE(size) (((size) + EXT4_XATTR_ROUND) & ~EXT4_XATTR_ROUND)\n#define EXT4_XATTR_NAME(entry) ((char *)((entry) + 1))\n\n#define EXT4_XATTR_IHDR(sb, raw_inode)                                         \\\n    ((struct ext4_xattr_ibody_header *)((char *)raw_inode +                \\\n                        EXT4_GOOD_OLD_INODE_SIZE +         \\\n                        ext4_inode_get_extra_isize(        \\\n                        sb, raw_inode)))\n#define EXT4_XATTR_IFIRST(hdr) ((struct ext4_xattr_entry *)((hdr) + 1))\n\n#define EXT4_XATTR_BHDR(block) ((struct ext4_xattr_header *)((block)->data))\n#define EXT4_XATTR_ENTRY(ptr) ((struct ext4_xattr_entry *)(ptr))\n#define EXT4_XATTR_BFIRST(block) EXT4_XATTR_ENTRY(EXT4_XATTR_BHDR(block) + 1)\n#define EXT4_XATTR_IS_LAST_ENTRY(entry) (*(uint32_t *)(entry) == 0)\n\n#define EXT4_ZERO_XATTR_VALUE ((void *)-1)\n\n#pragma pack(push, 1)\n\nstruct ext4_xattr_header {\n    uint32_t h_magic;   /* magic number for identification */\n    uint32_t h_refcount;    /* reference count */\n    uint32_t h_blocks;  /* number of disk blocks used */\n    uint32_t h_hash;        /* hash value of all attributes */\n    uint32_t h_checksum;    /* crc32c(uuid+id+xattrblock) */\n                /* id = inum if refcount=1, blknum otherwise */\n    uint32_t h_reserved[3]; /* zero right now */\n};\n\nstruct ext4_xattr_ibody_header {\n    uint32_t h_magic;   /* magic number for identification */\n};\n\nstruct ext4_xattr_entry {\n    uint8_t e_name_len; /* length of name */\n    uint8_t e_name_index;   /* attribute name index */\n    uint16_t e_value_offs;  /* offset in disk block of value */\n    uint32_t e_value_block; /* disk block attribute is stored on (n/i) */\n    uint32_t e_value_size;  /* size of attribute value */\n    uint32_t e_hash;        /* hash value of name and value */\n};\n\n#pragma pack(pop)\n\n\n#define NAME_HASH_SHIFT 5\n#define VALUE_HASH_SHIFT 16\n\nstatic inline void ext4_xattr_compute_hash(struct ext4_xattr_header *header,\n                       struct ext4_xattr_entry *entry)\n{\n    uint32_t hash = 0;\n    char *name = EXT4_XATTR_NAME(entry);\n    int n;\n\n    for (n = 0; n < entry->e_name_len; n++) {\n        hash = (hash << NAME_HASH_SHIFT) ^\n               (hash >> (8 * sizeof(hash) - NAME_HASH_SHIFT)) ^ *name++;\n    }\n\n    if (entry->e_value_block == 0 && entry->e_value_size != 0) {\n        uint32_t *value =\n            (uint32_t *)((char *)header + to_le16(entry->e_value_offs));\n        for (n = (to_le32(entry->e_value_size) + EXT4_XATTR_ROUND) >>\n             EXT4_XATTR_PAD_BITS;\n             n; n--) {\n            hash = (hash << VALUE_HASH_SHIFT) ^\n                   (hash >> (8 * sizeof(hash) - VALUE_HASH_SHIFT)) ^\n                   to_le32(*value++);\n        }\n    }\n    entry->e_hash = to_le32(hash);\n}\n\n#define BLOCK_HASH_SHIFT 16\n\n/*\n * ext4_xattr_rehash()\n *\n * Re-compute the extended attribute hash value after an entry has changed.\n */\nstatic void ext4_xattr_rehash(struct ext4_xattr_header *header,\n                  struct ext4_xattr_entry *entry)\n{\n    struct ext4_xattr_entry *here;\n    uint32_t hash = 0;\n\n    ext4_xattr_compute_hash(header, entry);\n    here = EXT4_XATTR_ENTRY(header + 1);\n    while (!EXT4_XATTR_IS_LAST_ENTRY(here)) {\n        if (!here->e_hash) {\n            /* Block is not shared if an entry's hash value == 0 */\n            hash = 0;\n            break;\n        }\n        hash = (hash << BLOCK_HASH_SHIFT) ^\n               (hash >> (8 * sizeof(hash) - BLOCK_HASH_SHIFT)) ^\n               to_le32(here->e_hash);\n        here = EXT4_XATTR_NEXT(here);\n    }\n    header->h_hash = to_le32(hash);\n}\n\n#if CONFIG_META_CSUM_ENABLE\nstatic uint32_t ext4_xattr_block_checksum(struct ext4_inode_ref *inode_ref,\n                      ext4_fsblk_t blocknr,\n                      struct ext4_xattr_header *header)\n{\n    uint32_t checksum = 0;\n    uint64_t le64_blocknr = blocknr;\n    struct ext4_sblock *sb = &inode_ref->fs->sb;\n\n    if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) {\n        uint32_t orig_checksum;\n\n        /* Preparation: temporarily set bg checksum to 0 */\n        orig_checksum = header->h_checksum;\n        header->h_checksum = 0;\n        /* First calculate crc32 checksum against fs uuid */\n        checksum =\n            ext4_crc32c(EXT4_CRC32_INIT, sb->uuid, sizeof(sb->uuid));\n        /* Then calculate crc32 checksum block number */\n        checksum =\n            ext4_crc32c(checksum, &le64_blocknr, sizeof(le64_blocknr));\n        /* Finally calculate crc32 checksum against\n         * the entire xattr block */\n        checksum =\n            ext4_crc32c(checksum, header, ext4_sb_get_block_size(sb));\n        header->h_checksum = orig_checksum;\n    }\n    return checksum;\n}\n#else\n#define ext4_xattr_block_checksum(...) 0\n#endif\n\nstatic void ext4_xattr_set_block_checksum(struct ext4_inode_ref *inode_ref,\n                      ext4_fsblk_t blocknr __unused,\n                      struct ext4_xattr_header *header)\n{\n    struct ext4_sblock *sb = &inode_ref->fs->sb;\n    if (!ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM))\n        return;\n\n    header->h_checksum =\n        ext4_xattr_block_checksum(inode_ref, blocknr, header);\n}\n\nstruct xattr_prefix {\n    const char *prefix;\n    uint8_t name_index;\n};\n\nstatic const struct xattr_prefix prefix_tbl[] = {\n    {\"user.\", EXT4_XATTR_INDEX_USER},\n    {\"system.posix_acl_access\", EXT4_XATTR_INDEX_POSIX_ACL_ACCESS},\n    {\"system.posix_acl_default\", EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT},\n    {\"trusted.\", EXT4_XATTR_INDEX_TRUSTED},\n    {\"security.\", EXT4_XATTR_INDEX_SECURITY},\n    {\"system.\", EXT4_XATTR_INDEX_SYSTEM},\n    {\"system.richacl\", EXT4_XATTR_INDEX_RICHACL},\n    {NULL, 0},\n};\n\nconst char *ext4_extract_xattr_name(const char *full_name, size_t full_name_len,\n                    uint8_t *name_index, size_t *name_len,\n                    bool *found)\n{\n    int i;\n    ext4_assert(name_index);\n    ext4_assert(found);\n\n    *found = false;\n\n    if (!full_name_len) {\n        if (name_len)\n            *name_len = 0;\n\n        return NULL;\n    }\n\n    for (i = 0; prefix_tbl[i].prefix; i++) {\n        size_t prefix_len = strlen(prefix_tbl[i].prefix);\n        if (full_name_len >= prefix_len &&\n            !memcmp(full_name, prefix_tbl[i].prefix, prefix_len)) {\n            bool require_name =\n                prefix_tbl[i].prefix[prefix_len - 1] == '.';\n            *name_index = prefix_tbl[i].name_index;\n            if (name_len)\n                *name_len = full_name_len - prefix_len;\n\n            if (!(full_name_len - prefix_len) && require_name)\n                return NULL;\n\n            *found = true;\n            if (require_name)\n                return full_name + prefix_len;\n\n            return NULL;\n        }\n    }\n    if (name_len)\n        *name_len = 0;\n\n    return NULL;\n}\n\nconst char *ext4_get_xattr_name_prefix(uint8_t name_index,\n                       size_t *ret_prefix_len)\n{\n    int i;\n\n    for (i = 0; prefix_tbl[i].prefix; i++) {\n        size_t prefix_len = strlen(prefix_tbl[i].prefix);\n        if (prefix_tbl[i].name_index == name_index) {\n            if (ret_prefix_len)\n                *ret_prefix_len = prefix_len;\n\n            return prefix_tbl[i].prefix;\n        }\n    }\n    if (ret_prefix_len)\n        *ret_prefix_len = 0;\n\n    return NULL;\n}\n\nstatic const char ext4_xattr_empty_value;\n\n/**\n * @brief Insert/Remove/Modify the given entry\n *\n * @param i The information of the given EA entry\n * @param s Search context block\n * @param dry_run Do not modify the content of the buffer\n *\n * @return Return EOK when finished, ENOSPC when there is no enough space\n */\nstatic int ext4_xattr_set_entry(struct ext4_xattr_info *i,\n                struct ext4_xattr_search *s, bool dry_run)\n{\n    struct ext4_xattr_entry *last;\n    size_t free, min_offs = (char *)s->end - (char *)s->base,\n             name_len = i->name_len;\n\n    /*\n     * If the entry is going to be removed but not found, return 0 to\n     * indicate success.\n     */\n    if (!i->value && s->not_found)\n        return EOK;\n\n    /* Compute min_offs and last. */\n    last = s->first;\n    for (; !EXT4_XATTR_IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) {\n        if (last->e_value_size) {\n            size_t offs = to_le16(last->e_value_offs);\n            if (offs < min_offs)\n                min_offs = offs;\n        }\n    }\n\n    /* Calculate free space in the block. */\n    free = min_offs - ((char *)last - (char *)s->base) - sizeof(uint32_t);\n    if (!s->not_found)\n        free += EXT4_XATTR_SIZE(s->here->e_value_size) +\n            EXT4_XATTR_LEN(s->here->e_name_len);\n\n    if (i->value) {\n        /* See whether there is enough space to hold new entry */\n        if (free <\n            EXT4_XATTR_SIZE(i->value_len) + EXT4_XATTR_LEN(name_len))\n            return ENOSPC;\n    }\n\n    /* Return EOK now if we do not intend to modify the content. */\n    if (dry_run)\n        return EOK;\n\n    /* First remove the old entry's data part */\n    if (!s->not_found) {\n        size_t value_offs = to_le16(s->here->e_value_offs);\n        void *value = (char *)s->base + value_offs;\n        void *first_value = (char *)s->base + min_offs;\n        size_t value_size =\n            EXT4_XATTR_SIZE(to_le32(s->here->e_value_size));\n\n        if (value_offs) {\n            /* Remove the data part. */\n            memmove((char *)first_value + value_size, first_value,\n                (char *)value - (char *)first_value);\n\n            /* Zero the gap created */\n            memset(first_value, 0, value_size);\n\n            /*\n             * Calculate the new min_offs after removal of the old\n             * entry's data part\n             */\n            min_offs += value_size;\n        }\n\n        /*\n         * Adjust the value offset of entries which has value offset\n         * prior to the s->here. The offset of these entries won't be\n         * shifted if the size of the entry we removed is zero.\n         */\n        for (last = s->first; !EXT4_XATTR_IS_LAST_ENTRY(last);\n             last = EXT4_XATTR_NEXT(last)) {\n            size_t offs = to_le16(last->e_value_offs);\n\n            /* For zero-value-length entry, offs will be zero. */\n            if (offs < value_offs)\n                last->e_value_offs = to_le16(offs + value_size);\n        }\n    }\n\n    /* If caller wants us to insert... */\n    if (i->value) {\n        size_t value_offs;\n        if (i->value_len)\n            value_offs = min_offs - EXT4_XATTR_SIZE(i->value_len);\n        else\n            value_offs = 0;\n\n        if (!s->not_found) {\n            struct ext4_xattr_entry *here = s->here;\n\n            /* Reuse the current entry we have got */\n            here->e_value_offs = to_le16(value_offs);\n            here->e_value_size = to_le32(i->value_len);\n        } else {\n            /* Insert a new entry */\n            last->e_name_len = (uint8_t)name_len;\n            last->e_name_index = i->name_index;\n            last->e_value_offs = to_le16(value_offs);\n            last->e_value_block = 0;\n            last->e_value_size = to_le32(i->value_len);\n            memcpy(EXT4_XATTR_NAME(last), i->name, name_len);\n\n            /* Set valid last entry indicator */\n            *(uint32_t *)EXT4_XATTR_NEXT(last) = 0;\n\n            s->here = last;\n        }\n\n        /* Insert the value's part */\n        if (value_offs) {\n            memcpy((char *)s->base + value_offs, i->value,\n                   i->value_len);\n\n            /* Clear the padding bytes if there is */\n            if (EXT4_XATTR_SIZE(i->value_len) != i->value_len)\n                memset((char *)s->base + value_offs +\n                       i->value_len,\n                       0, EXT4_XATTR_SIZE(i->value_len) -\n                          i->value_len);\n        }\n    } else {\n        size_t shift_offs;\n\n        /* Remove the whole entry */\n        shift_offs = (char *)EXT4_XATTR_NEXT(s->here) - (char *)s->here;\n        memmove(s->here, EXT4_XATTR_NEXT(s->here),\n            (char *)last + sizeof(uint32_t) -\n                (char *)EXT4_XATTR_NEXT(s->here));\n\n        /* Zero the gap created */\n        memset((char *)last - shift_offs + sizeof(uint32_t), 0,\n               shift_offs);\n\n        s->here = NULL;\n    }\n\n    return EOK;\n}\n\nstatic inline bool ext4_xattr_is_empty(struct ext4_xattr_search *s)\n{\n    if (!EXT4_XATTR_IS_LAST_ENTRY(s->first))\n        return false;\n\n    return true;\n}\n\n/**\n * @brief Find the entry according to given information\n *\n * @param i The information of the EA entry to be found,\n *      including name_index, name and the length of name\n * @param s Search context block\n */\nstatic void ext4_xattr_find_entry(struct ext4_xattr_info *i,\n                  struct ext4_xattr_search *s)\n{\n    struct ext4_xattr_entry *entry = NULL;\n\n    s->not_found = true;\n    s->here = NULL;\n\n    /*\n     * Find the wanted EA entry by simply comparing the namespace,\n     * name and the length of name.\n     */\n    for (entry = s->first; !EXT4_XATTR_IS_LAST_ENTRY(entry);\n         entry = EXT4_XATTR_NEXT(entry)) {\n        size_t name_len = entry->e_name_len;\n        const char *name = EXT4_XATTR_NAME(entry);\n        if (name_len == i->name_len &&\n            entry->e_name_index == i->name_index &&\n            !memcmp(name, i->name, name_len)) {\n            s->here = entry;\n            s->not_found = false;\n            i->value_len = to_le32(entry->e_value_size);\n            if (i->value_len)\n                i->value = (char *)s->base +\n                       to_le16(entry->e_value_offs);\n            else\n                i->value = NULL;\n\n            return;\n        }\n    }\n}\n\n/**\n * @brief Check whether the xattr block's content is valid\n *\n * @param inode_ref Inode reference\n * @param block     The block buffer to be validated\n *\n * @return true if @block is valid, false otherwise.\n */\nstatic bool ext4_xattr_is_block_valid(struct ext4_inode_ref *inode_ref,\n                      struct ext4_block *block)\n{\n\n    void *base = block->data,\n         *end = block->data + ext4_sb_get_block_size(&inode_ref->fs->sb);\n    size_t min_offs = (char *)end - (char *)base;\n    struct ext4_xattr_header *header = EXT4_XATTR_BHDR(block);\n    struct ext4_xattr_entry *entry = EXT4_XATTR_BFIRST(block);\n\n    /*\n     * Check whether the magic number in the header is correct.\n     */\n    if (header->h_magic != to_le32(EXT4_XATTR_MAGIC))\n        return false;\n\n    /*\n     * The in-kernel filesystem driver only supports 1 block currently.\n     */\n    if (header->h_blocks != to_le32(1))\n        return false;\n\n    /*\n     * Check if those entries are maliciously corrupted to inflict harm\n     * upon us.\n     */\n    for (; !EXT4_XATTR_IS_LAST_ENTRY(entry);\n         entry = EXT4_XATTR_NEXT(entry)) {\n        if (!to_le32(entry->e_value_size) &&\n            to_le16(entry->e_value_offs))\n            return false;\n\n        if ((char *)base + to_le16(entry->e_value_offs) +\n            to_le32(entry->e_value_size) >\n            (char *)end)\n            return false;\n\n        /*\n         * The name length field should also be correct,\n         * also there should be an 4-byte zero entry at the\n         * end.\n         */\n        if ((char *)EXT4_XATTR_NEXT(entry) + sizeof(uint32_t) >\n            (char *)end)\n            return false;\n\n        if (to_le32(entry->e_value_size)) {\n            size_t offs = to_le16(entry->e_value_offs);\n            if (offs < min_offs)\n                min_offs = offs;\n        }\n    }\n    /*\n     * Entry field and data field do not override each other.\n     */\n    if ((char *)base + min_offs < (char *)entry + sizeof(uint32_t))\n        return false;\n\n    return true;\n}\n\n/**\n * @brief Check whether the inode buffer's content is valid\n *\n * @param inode_ref Inode reference\n *\n * @return true if the inode buffer is valid, false otherwise.\n */\nstatic bool ext4_xattr_is_ibody_valid(struct ext4_inode_ref *inode_ref)\n{\n    size_t min_offs;\n    void *base, *end;\n    struct ext4_fs *fs = inode_ref->fs;\n    struct ext4_xattr_ibody_header *iheader;\n    struct ext4_xattr_entry *entry;\n    size_t inode_size = ext4_get16(&fs->sb, inode_size);\n\n    iheader = EXT4_XATTR_IHDR(&fs->sb, inode_ref->inode);\n    entry = EXT4_XATTR_IFIRST(iheader);\n    base = iheader;\n    end = (char *)inode_ref->inode + inode_size;\n    min_offs = (char *)end - (char *)base;\n\n    /*\n     * Check whether the magic number in the header is correct.\n     */\n    if (iheader->h_magic != to_le32(EXT4_XATTR_MAGIC))\n        return false;\n\n    /*\n     * Check if those entries are maliciously corrupted to inflict harm\n     * upon us.\n     */\n    for (; !EXT4_XATTR_IS_LAST_ENTRY(entry);\n         entry = EXT4_XATTR_NEXT(entry)) {\n        if (!to_le32(entry->e_value_size) &&\n            to_le16(entry->e_value_offs))\n            return false;\n\n        if ((char *)base + to_le16(entry->e_value_offs) +\n            to_le32(entry->e_value_size) >\n            (char *)end)\n            return false;\n\n        /*\n         * The name length field should also be correct,\n         * also there should be an 4-byte zero entry at the\n         * end.\n         */\n        if ((char *)EXT4_XATTR_NEXT(entry) + sizeof(uint32_t) >\n            (char *)end)\n            return false;\n\n        if (to_le32(entry->e_value_size)) {\n            size_t offs = to_le16(entry->e_value_offs);\n            if (offs < min_offs)\n                min_offs = offs;\n        }\n    }\n    /*\n     * Entry field and data field do not override each other.\n     */\n    if ((char *)base + min_offs < (char *)entry + sizeof(uint32_t))\n        return false;\n\n    return true;\n}\n\n/**\n * @brief An EA entry finder for inode buffer\n */\nstruct ext4_xattr_finder {\n    /**\n     * @brief The information of the EA entry to be find\n     */\n    struct ext4_xattr_info i;\n\n    /**\n     * @brief Search context block of the current search\n     */\n    struct ext4_xattr_search s;\n\n    /**\n     * @brief Inode reference to the corresponding inode\n     */\n    struct ext4_inode_ref *inode_ref;\n};\n\nstatic void ext4_xattr_ibody_initialize(struct ext4_inode_ref *inode_ref)\n{\n    struct ext4_xattr_ibody_header *header;\n    struct ext4_fs *fs = inode_ref->fs;\n    size_t extra_isize =\n        ext4_inode_get_extra_isize(&fs->sb, inode_ref->inode);\n    size_t inode_size = ext4_get16(&fs->sb, inode_size);\n    if (!extra_isize)\n        return;\n\n    header = EXT4_XATTR_IHDR(&fs->sb, inode_ref->inode);\n    memset(header, 0, inode_size - EXT4_GOOD_OLD_INODE_SIZE - extra_isize);\n    header->h_magic = to_le32(EXT4_XATTR_MAGIC);\n    inode_ref->dirty = true;\n}\n\n/**\n * @brief Initialize a given xattr block\n *\n * @param inode_ref Inode reference\n * @param block xattr block buffer\n */\nstatic void ext4_xattr_block_initialize(struct ext4_inode_ref *inode_ref,\n                    struct ext4_block *block)\n{\n    struct ext4_xattr_header *header;\n    struct ext4_fs *fs = inode_ref->fs;\n\n    memset(block->data, 0, ext4_sb_get_block_size(&fs->sb));\n\n    header = EXT4_XATTR_BHDR(block);\n    header->h_magic = to_le32(EXT4_XATTR_MAGIC);\n    header->h_refcount = to_le32(1);\n    header->h_blocks = to_le32(1);\n\n    ext4_trans_set_block_dirty(block->buf);\n}\n\nstatic void ext4_xattr_block_init_search(struct ext4_inode_ref *inode_ref,\n                     struct ext4_xattr_search *s,\n                     struct ext4_block *block)\n{\n    s->base = block->data;\n    s->end = block->data + ext4_sb_get_block_size(&inode_ref->fs->sb);\n    s->first = EXT4_XATTR_BFIRST(block);\n    s->here = NULL;\n    s->not_found = true;\n}\n\n/**\n * @brief Find an EA entry inside a xattr block\n *\n * @param inode_ref Inode reference\n * @param finder    The caller-provided finder block with\n *          information filled\n * @param block     The block buffer to be looked into\n *\n * @return Return EOK no matter the entry is found or not.\n *     If the IO operation or the buffer validation failed,\n *     return other value.\n */\nstatic int ext4_xattr_block_find_entry(struct ext4_inode_ref *inode_ref,\n                       struct ext4_xattr_finder *finder,\n                       struct ext4_block *block)\n{\n    int ret = EOK;\n\n    /* Initialize the caller-given finder */\n    finder->inode_ref = inode_ref;\n    memset(&finder->s, 0, sizeof(finder->s));\n\n    if (ret != EOK)\n        return ret;\n\n    /* Check the validity of the buffer */\n    if (!ext4_xattr_is_block_valid(inode_ref, block))\n        return EIO;\n\n    ext4_xattr_block_init_search(inode_ref, &finder->s, block);\n    ext4_xattr_find_entry(&finder->i, &finder->s);\n    return EOK;\n}\n\n/**\n * @brief Find an EA entry inside an inode's extra space\n *\n * @param inode_ref Inode reference\n * @param finder    The caller-provided finder block with\n *          information filled\n *\n * @return Return EOK no matter the entry is found or not.\n *     If the IO operation or the buffer validation failed,\n *     return other value.\n */\nstatic int ext4_xattr_ibody_find_entry(struct ext4_inode_ref *inode_ref,\n                       struct ext4_xattr_finder *finder)\n{\n    struct ext4_fs *fs = inode_ref->fs;\n    struct ext4_xattr_ibody_header *iheader;\n    size_t extra_isize =\n        ext4_inode_get_extra_isize(&fs->sb, inode_ref->inode);\n    size_t inode_size = ext4_get16(&fs->sb, inode_size);\n\n    /* Initialize the caller-given finder */\n    finder->inode_ref = inode_ref;\n    memset(&finder->s, 0, sizeof(finder->s));\n\n    /*\n     * If there is no extra inode space\n     * set ext4_xattr_ibody_finder::s::not_found to true and return EOK\n     */\n    if (!extra_isize) {\n        finder->s.not_found = true;\n        return EOK;\n    }\n\n    /* Check the validity of the buffer */\n    if (!ext4_xattr_is_ibody_valid(inode_ref))\n        return EIO;\n\n    iheader = EXT4_XATTR_IHDR(&fs->sb, inode_ref->inode);\n    finder->s.base = EXT4_XATTR_IFIRST(iheader);\n    finder->s.end = (char *)inode_ref->inode + inode_size;\n    finder->s.first = EXT4_XATTR_IFIRST(iheader);\n    ext4_xattr_find_entry(&finder->i, &finder->s);\n    return EOK;\n}\n\n/**\n * @brief Try to allocate a block holding EA entries.\n *\n * @param inode_ref Inode reference\n *\n * @return Error code\n */\nstatic int ext4_xattr_try_alloc_block(struct ext4_inode_ref *inode_ref)\n{\n    int ret = EOK;\n\n    ext4_fsblk_t xattr_block = 0;\n    xattr_block =\n        ext4_inode_get_file_acl(inode_ref->inode, &inode_ref->fs->sb);\n\n    /*\n     * Only allocate a xattr block when there is no xattr block\n     * used by the inode.\n     */\n    if (!xattr_block) {\n        ext4_fsblk_t goal = ext4_fs_inode_to_goal_block(inode_ref);\n\n        ret = ext4_balloc_alloc_block(inode_ref, goal, &xattr_block);\n        if (ret != EOK)\n            goto Finish;\n\n        ext4_inode_set_file_acl(inode_ref->inode, &inode_ref->fs->sb,\n                    xattr_block);\n    }\n\nFinish:\n    return ret;\n}\n\n/**\n * @brief Try to free a block holding EA entries.\n *\n * @param inode_ref Inode reference\n *\n * @return Error code\n */\nstatic void ext4_xattr_try_free_block(struct ext4_inode_ref *inode_ref)\n{\n    ext4_fsblk_t xattr_block;\n    xattr_block =\n        ext4_inode_get_file_acl(inode_ref->inode, &inode_ref->fs->sb);\n    /*\n     * Free the xattr block used by the inode when there is one.\n     */\n    if (xattr_block) {\n        ext4_inode_set_file_acl(inode_ref->inode, &inode_ref->fs->sb,\n                    0);\n        ext4_balloc_free_block(inode_ref, xattr_block);\n        inode_ref->dirty = true;\n    }\n}\n\n/**\n * @brief Put a list of EA entries into a caller-provided buffer\n *    In order to make sure that @list buffer can fit in the data,\n *    the routine should be called twice.\n *\n * @param inode_ref Inode reference\n * @param list A caller-provided buffer to hold a list of EA entries.\n *         If list == NULL, list_len will contain the size of\n *         the buffer required to hold these entries\n * @param list_len The length of the data written to @list\n * @return Error code\n */\nint ext4_xattr_list(struct ext4_inode_ref *inode_ref,\n            struct ext4_xattr_list_entry *list, size_t *list_len)\n{\n    int ret = EOK;\n    size_t buf_len = 0;\n    struct ext4_fs *fs = inode_ref->fs;\n    struct ext4_xattr_ibody_header *iheader;\n    size_t extra_isize =\n        ext4_inode_get_extra_isize(&fs->sb, inode_ref->inode);\n    struct ext4_block block;\n    bool block_loaded = false;\n    ext4_fsblk_t xattr_block = 0;\n    struct ext4_xattr_entry *entry;\n    struct ext4_xattr_list_entry *list_prev = NULL;\n    xattr_block = ext4_inode_get_file_acl(inode_ref->inode, &fs->sb);\n\n    /*\n     * If there is extra inode space and the xattr buffer in the\n     * inode is valid.\n     */\n    if (extra_isize && ext4_xattr_is_ibody_valid(inode_ref)) {\n        iheader = EXT4_XATTR_IHDR(&fs->sb, inode_ref->inode);\n        entry = EXT4_XATTR_IFIRST(iheader);\n\n        /*\n         * The format of the list should be like this:\n         *\n         * name_len indicates the length in bytes of the name\n         * of the EA entry. The string is null-terminated.\n         *\n         * list->name => (char *)(list + 1);\n         * list->next => (void *)((char *)(list + 1) + name_len + 1);\n         */\n        for (; !EXT4_XATTR_IS_LAST_ENTRY(entry);\n             entry = EXT4_XATTR_NEXT(entry)) {\n            size_t name_len = entry->e_name_len;\n            if (list) {\n                list->name_index = entry->e_name_index;\n                list->name_len = name_len;\n                list->name = (char *)(list + 1);\n                memcpy(list->name, EXT4_XATTR_NAME(entry),\n                       list->name_len);\n\n                if (list_prev)\n                    list_prev->next = list;\n\n                list_prev = list;\n                list = (struct ext4_xattr_list_entry\n                        *)(list->name + name_len + 1);\n            }\n\n            /*\n             * Size calculation by pointer arithmetics.\n             */\n            buf_len +=\n                (char *)((struct ext4_xattr_list_entry *)0 + 1) +\n                name_len + 1 -\n                (char *)(struct ext4_xattr_list_entry *)0;\n        }\n    }\n\n    /*\n     * If there is a xattr block used by the inode\n     */\n    if (xattr_block) {\n        ret = ext4_trans_block_get(fs->bdev, &block, xattr_block);\n        if (ret != EOK)\n            goto out;\n\n        block_loaded = true;\n\n        /*\n         * As we don't allow the content in the block being invalid,\n         * bail out.\n         */\n        if (!ext4_xattr_is_block_valid(inode_ref, &block)) {\n            ret = EIO;\n            goto out;\n        }\n\n        entry = EXT4_XATTR_BFIRST(&block);\n\n        /*\n         * The format of the list should be like this:\n         *\n         * name_len indicates the length in bytes of the name\n         * of the EA entry. The string is null-terminated.\n         *\n         * list->name => (char *)(list + 1);\n         * list->next => (void *)((char *)(list + 1) + name_len + 1);\n         *\n         * Same as above actually.\n         */\n        for (; !EXT4_XATTR_IS_LAST_ENTRY(entry);\n             entry = EXT4_XATTR_NEXT(entry)) {\n            size_t name_len = entry->e_name_len;\n            if (list) {\n                list->name_index = entry->e_name_index;\n                list->name_len = name_len;\n                list->name = (char *)(list + 1);\n                memcpy(list->name, EXT4_XATTR_NAME(entry),\n                       list->name_len);\n\n                if (list_prev)\n                    list_prev->next = list;\n\n                list_prev = list;\n                list = (struct ext4_xattr_list_entry\n                        *)(list->name + name_len + 1);\n            }\n\n            /*\n             * Size calculation by pointer arithmetics.\n             */\n            buf_len +=\n                (char *)((struct ext4_xattr_list_entry *)0 + 1) +\n                name_len + 1 -\n                (char *)(struct ext4_xattr_list_entry *)0;\n        }\n    }\n    if (list_prev)\n        list_prev->next = NULL;\nout:\n    if (ret == EOK && list_len)\n        *list_len = buf_len;\n\n    if (block_loaded)\n        ext4_block_set(fs->bdev, &block);\n\n    return ret;\n}\n\n/**\n * @brief Query EA entry's value with given name-index and name\n *\n * @param inode_ref Inode reference\n * @param name_index Name-index\n * @param name Name of the EA entry to be queried\n * @param name_len Length of name in bytes\n * @param buf Output buffer to hold content\n * @param buf_len Output buffer's length\n * @param data_len The length of data of the EA entry found\n *\n * @return Error code\n */\nint ext4_xattr_get(struct ext4_inode_ref *inode_ref, uint8_t name_index,\n           const char *name, size_t name_len, void *buf, size_t buf_len,\n           size_t *data_len)\n{\n    int ret = EOK;\n    struct ext4_xattr_finder ibody_finder;\n    struct ext4_xattr_finder block_finder;\n    struct ext4_xattr_info i;\n    size_t value_len = 0;\n    size_t value_offs = 0;\n    struct ext4_fs *fs = inode_ref->fs;\n    ext4_fsblk_t xattr_block;\n    xattr_block = ext4_inode_get_file_acl(inode_ref->inode, &fs->sb);\n\n    i.name_index = name_index;\n    i.name = name;\n    i.name_len = name_len;\n    i.value = 0;\n    i.value_len = 0;\n    if (data_len)\n        *data_len = 0;\n\n    ibody_finder.i = i;\n    ret = ext4_xattr_ibody_find_entry(inode_ref, &ibody_finder);\n    if (ret != EOK)\n        goto out;\n\n    if (!ibody_finder.s.not_found) {\n        value_len = to_le32(ibody_finder.s.here->e_value_size);\n        value_offs = to_le32(ibody_finder.s.here->e_value_offs);\n        if (buf_len && buf) {\n            void *data_loc =\n                (char *)ibody_finder.s.base + value_offs;\n            memcpy(buf, data_loc,\n                   (buf_len < value_len) ? buf_len : value_len);\n        }\n    } else {\n        struct ext4_block block;\n\n        /* Return ENODATA if there is no EA block */\n        if (!xattr_block) {\n            ret = ENODATA;\n            goto out;\n        }\n\n        block_finder.i = i;\n        ret = ext4_trans_block_get(fs->bdev, &block, xattr_block);\n        if (ret != EOK)\n            goto out;\n\n        ret = ext4_xattr_block_find_entry(inode_ref, &block_finder,\n                          &block);\n        if (ret != EOK) {\n            ext4_block_set(fs->bdev, &block);\n            goto out;\n        }\n\n        /* Return ENODATA if entry is not found */\n        if (block_finder.s.not_found) {\n            ext4_block_set(fs->bdev, &block);\n            ret = ENODATA;\n            goto out;\n        }\n\n        value_len = to_le32(block_finder.s.here->e_value_size);\n        value_offs = to_le32(block_finder.s.here->e_value_offs);\n        if (buf_len && buf) {\n            void *data_loc =\n                (char *)block_finder.s.base + value_offs;\n            memcpy(buf, data_loc,\n                   (buf_len < value_len) ? buf_len : value_len);\n        }\n\n        /*\n         * Free the xattr block buffer returned by\n         * ext4_xattr_block_find_entry.\n         */\n        ext4_block_set(fs->bdev, &block);\n    }\n\nout:\n    if (ret == EOK && data_len)\n        *data_len = value_len;\n\n    return ret;\n}\n\n/**\n * @brief Try to copy the content of an xattr block to a newly-allocated\n *    block. If the operation fails, the block buffer provided by\n *    caller will be freed\n *\n * @param inode_ref Inode reference\n * @param block The block buffer reference\n * @param new_block The newly-allocated block buffer reference\n * @param orig_block The block number of @block\n * @param allocated a new block is allocated\n *\n * @return Error code\n */\nstatic int ext4_xattr_copy_new_block(struct ext4_inode_ref *inode_ref,\n                     struct ext4_block *block,\n                     struct ext4_block *new_block,\n                     ext4_fsblk_t *orig_block, bool *allocated)\n{\n    int ret = EOK;\n    ext4_fsblk_t xattr_block = 0;\n    struct ext4_xattr_header *header;\n    struct ext4_fs *fs = inode_ref->fs;\n    header = EXT4_XATTR_BHDR(block);\n\n    if (orig_block)\n        *orig_block = block->lb_id;\n\n    if (allocated)\n        *allocated = false;\n\n    /* Only do copy when a block is referenced by more than one inode. */\n    if (to_le32(header->h_refcount) > 1) {\n        ext4_fsblk_t goal = ext4_fs_inode_to_goal_block(inode_ref);\n\n        /* Allocate a new block to be used by this inode */\n        ret = ext4_balloc_alloc_block(inode_ref, goal, &xattr_block);\n        if (ret != EOK)\n            goto out;\n\n        ret = ext4_trans_block_get(fs->bdev, new_block, xattr_block);\n        if (ret != EOK)\n            goto out;\n\n        /* Copy the content of the whole block */\n        memcpy(new_block->data, block->data,\n               ext4_sb_get_block_size(&inode_ref->fs->sb));\n\n        /*\n         * Decrement the reference count of the original xattr block\n         * by one\n         */\n        header->h_refcount = to_le32(to_le32(header->h_refcount) - 1);\n        ext4_trans_set_block_dirty(block->buf);\n        ext4_trans_set_block_dirty(new_block->buf);\n\n        header = EXT4_XATTR_BHDR(new_block);\n        header->h_refcount = to_le32(1);\n\n        if (allocated)\n            *allocated = true;\n    }\nout:\n    if (xattr_block) {\n        if (ret != EOK)\n            ext4_balloc_free_block(inode_ref, xattr_block);\n        else {\n            /*\n             * Modify the in-inode pointer to point to the new xattr block\n             */\n            ext4_inode_set_file_acl(inode_ref->inode, &fs->sb, xattr_block);\n            inode_ref->dirty = true;\n        }\n    }\n\n    return ret;\n}\n\n/**\n * @brief Given an EA entry's name, remove the EA entry\n *\n * @param inode_ref Inode reference\n * @param name_index Name-index\n * @param name Name of the EA entry to be removed\n * @param name_len Length of name in bytes\n *\n * @return Error code\n */\nint ext4_xattr_remove(struct ext4_inode_ref *inode_ref, uint8_t name_index,\n              const char *name, size_t name_len)\n{\n    int ret = EOK;\n    struct ext4_block block;\n    struct ext4_xattr_finder ibody_finder;\n    struct ext4_xattr_finder block_finder;\n    bool use_block = false;\n    bool block_loaded = false;\n    struct ext4_xattr_info i;\n    struct ext4_fs *fs = inode_ref->fs;\n    ext4_fsblk_t xattr_block;\n\n    xattr_block = ext4_inode_get_file_acl(inode_ref->inode, &fs->sb);\n\n    i.name_index = name_index;\n    i.name = name;\n    i.name_len = name_len;\n    i.value = NULL;\n    i.value_len = 0;\n\n    ibody_finder.i = i;\n    block_finder.i = i;\n\n    ret = ext4_xattr_ibody_find_entry(inode_ref, &ibody_finder);\n    if (ret != EOK)\n        goto out;\n\n    if (ibody_finder.s.not_found && xattr_block) {\n        ret = ext4_trans_block_get(fs->bdev, &block, xattr_block);\n        if (ret != EOK)\n            goto out;\n\n        block_loaded = true;\n        block_finder.i = i;\n        ret = ext4_xattr_block_find_entry(inode_ref, &block_finder,\n                          &block);\n        if (ret != EOK)\n            goto out;\n\n        /* Return ENODATA if entry is not found */\n        if (block_finder.s.not_found) {\n            ret = ENODATA;\n            goto out;\n        }\n        use_block = true;\n    }\n\n    if (use_block) {\n        bool allocated = false;\n        struct ext4_block new_block;\n\n        /*\n         * There will be no effect when the xattr block is only referenced\n         * once.\n         */\n        ret = ext4_xattr_copy_new_block(inode_ref, &block, &new_block,\n                        &xattr_block, &allocated);\n        if (ret != EOK)\n            goto out;\n\n        if (!allocated) {\n            /* Prevent double-freeing */\n            block_loaded = false;\n            new_block = block;\n        }\n\n        ret = ext4_xattr_block_find_entry(inode_ref, &block_finder,\n                          &new_block);\n        if (ret != EOK)\n            goto out;\n\n        /* Now remove the entry */\n        ext4_xattr_set_entry(&i, &block_finder.s, false);\n\n        if (ext4_xattr_is_empty(&block_finder.s)) {\n            ext4_block_set(fs->bdev, &new_block);\n            ext4_xattr_try_free_block(inode_ref);\n        } else {\n            struct ext4_xattr_header *header =\n                EXT4_XATTR_BHDR(&new_block);\n            header = EXT4_XATTR_BHDR(&new_block);\n            ext4_assert(block_finder.s.first);\n            ext4_xattr_rehash(header, block_finder.s.first);\n            ext4_xattr_set_block_checksum(inode_ref,\n                              block.lb_id,\n                              header);\n\n            ext4_trans_set_block_dirty(new_block.buf);\n            ext4_block_set(fs->bdev, &new_block);\n        }\n\n    } else {\n        /* Now remove the entry */\n        ext4_xattr_set_entry(&i, &block_finder.s, false);\n        inode_ref->dirty = true;\n    }\nout:\n    if (block_loaded)\n        ext4_block_set(fs->bdev, &block);\n\n    return ret;\n}\n\n/**\n * @brief Insert/overwrite an EA entry into/in a xattr block\n *\n * @param inode_ref Inode reference\n * @param i The information of the given EA entry\n *\n * @return Error code\n */\nstatic int ext4_xattr_block_set(struct ext4_inode_ref *inode_ref,\n                struct ext4_xattr_info *i,\n                bool no_insert)\n{\n    int ret = EOK;\n    bool allocated = false;\n    struct ext4_fs *fs = inode_ref->fs;\n    struct ext4_block block, new_block;\n    ext4_fsblk_t orig_xattr_block;\n\n    orig_xattr_block = ext4_inode_get_file_acl(inode_ref->inode, &fs->sb);\n\n    ext4_assert(i->value);\n    if (!orig_xattr_block) {\n        struct ext4_xattr_search s;\n        struct ext4_xattr_header *header;\n\n        /* If insertion of new entry is not allowed... */\n        if (no_insert) {\n            ret = ENODATA;\n            goto out;\n        }\n\n        ret = ext4_xattr_try_alloc_block(inode_ref);\n        if (ret != EOK)\n            goto out;\n\n        orig_xattr_block =\n            ext4_inode_get_file_acl(inode_ref->inode, &fs->sb);\n        ret = ext4_trans_block_get(fs->bdev, &block, orig_xattr_block);\n        if (ret != EOK) {\n            ext4_xattr_try_free_block(inode_ref);\n            goto out;\n        }\n\n        ext4_xattr_block_initialize(inode_ref, &block);\n        ext4_xattr_block_init_search(inode_ref, &s, &block);\n\n        ret = ext4_xattr_set_entry(i, &s, false);\n        if (ret == EOK) {\n            header = EXT4_XATTR_BHDR(&block);\n\n            ext4_assert(s.here);\n            ext4_assert(s.first);\n            ext4_xattr_compute_hash(header, s.here);\n            ext4_xattr_rehash(header, s.first);\n            ext4_xattr_set_block_checksum(inode_ref,\n                              block.lb_id,\n                              header);\n            ext4_trans_set_block_dirty(block.buf);\n        }\n        ext4_block_set(fs->bdev, &block);\n        if (ret != EOK)\n            ext4_xattr_try_free_block(inode_ref);\n\n    } else {\n        struct ext4_xattr_finder finder;\n        struct ext4_xattr_header *header;\n        finder.i = *i;\n        ret = ext4_trans_block_get(fs->bdev, &block, orig_xattr_block);\n        if (ret != EOK)\n            goto out;\n\n        header = EXT4_XATTR_BHDR(&block);\n\n        /*\n         * Consider the following case when insertion of new\n         * entry is not allowed\n         */\n        if (to_le32(header->h_refcount) > 1 && no_insert) {\n            /*\n             * There are other people referencing the\n             * same xattr block\n             */\n            ret = ext4_xattr_block_find_entry(inode_ref, &finder, &block);\n            if (ret != EOK) {\n                ext4_block_set(fs->bdev, &block);\n                goto out;\n            }\n            if (finder.s.not_found) {\n                ext4_block_set(fs->bdev, &block);\n                ret = ENODATA;\n                goto out;\n            }\n        }\n\n        /*\n         * There will be no effect when the xattr block is only referenced\n         * once.\n         */\n        ret = ext4_xattr_copy_new_block(inode_ref, &block, &new_block,\n                        &orig_xattr_block, &allocated);\n        if (ret != EOK) {\n            ext4_block_set(fs->bdev, &block);\n            goto out;\n        }\n\n        if (allocated) {\n            ext4_block_set(fs->bdev, &block);\n            new_block = block;\n        }\n\n        ret = ext4_xattr_block_find_entry(inode_ref, &finder, &block);\n        if (ret != EOK) {\n            ext4_block_set(fs->bdev, &block);\n            goto out;\n        }\n\n        ret = ext4_xattr_set_entry(i, &finder.s, false);\n        if (ret == EOK) {\n            header = EXT4_XATTR_BHDR(&block);\n\n            ext4_assert(finder.s.here);\n            ext4_assert(finder.s.first);\n            ext4_xattr_compute_hash(header, finder.s.here);\n            ext4_xattr_rehash(header, finder.s.first);\n            ext4_xattr_set_block_checksum(inode_ref,\n                              block.lb_id,\n                              header);\n            ext4_trans_set_block_dirty(block.buf);\n        }\n        ext4_block_set(fs->bdev, &block);\n    }\nout:\n    return ret;\n}\n\n/**\n * @brief Remove an EA entry from a xattr block\n *\n * @param inode_ref Inode reference\n * @param i The information of the given EA entry\n *\n * @return Error code\n */\nstatic int ext4_xattr_block_remove(struct ext4_inode_ref *inode_ref,\n                   struct ext4_xattr_info *i)\n{\n    int ret = EOK;\n    bool allocated = false;\n    const void *value = i->value;\n    struct ext4_fs *fs = inode_ref->fs;\n    struct ext4_xattr_finder finder;\n    struct ext4_block block, new_block;\n    struct ext4_xattr_header *header;\n    ext4_fsblk_t orig_xattr_block;\n    orig_xattr_block = ext4_inode_get_file_acl(inode_ref->inode, &fs->sb);\n\n    ext4_assert(orig_xattr_block);\n    ret = ext4_trans_block_get(fs->bdev, &block, orig_xattr_block);\n    if (ret != EOK)\n        goto out;\n\n    /*\n     * There will be no effect when the xattr block is only referenced\n     * once.\n     */\n    ret = ext4_xattr_copy_new_block(inode_ref, &block, &new_block,\n                    &orig_xattr_block, &allocated);\n    if (ret != EOK) {\n        ext4_block_set(fs->bdev, &block);\n        goto out;\n    }\n\n    if (allocated) {\n        ext4_block_set(fs->bdev, &block);\n        block = new_block;\n    }\n\n    ext4_xattr_block_find_entry(inode_ref, &finder, &block);\n\n    if (!finder.s.not_found) {\n        i->value = NULL;\n        ret = ext4_xattr_set_entry(i, &finder.s, false);\n        i->value = value;\n\n        header = EXT4_XATTR_BHDR(&block);\n        ext4_assert(finder.s.first);\n        ext4_xattr_rehash(header, finder.s.first);\n        ext4_xattr_set_block_checksum(inode_ref,\n                          block.lb_id,\n                          header);\n        ext4_trans_set_block_dirty(block.buf);\n    }\n\n    ext4_block_set(fs->bdev, &block);\nout:\n    return ret;\n}\n\n/**\n * @brief Insert an EA entry into a given inode reference\n *\n * @param inode_ref Inode reference\n * @param name_index Name-index\n * @param name Name of the EA entry to be inserted\n * @param name_len Length of name in bytes\n * @param value Input buffer to hold content\n * @param value_len Length of input content\n *\n * @return Error code\n */\nint ext4_xattr_set(struct ext4_inode_ref *inode_ref, uint8_t name_index,\n           const char *name, size_t name_len, const void *value,\n           size_t value_len)\n{\n    int ret = EOK;\n    struct ext4_fs *fs = inode_ref->fs;\n    struct ext4_xattr_finder ibody_finder;\n    struct ext4_xattr_info i;\n    bool block_found = false;\n    ext4_fsblk_t orig_xattr_block;\n    size_t extra_isize =\n        ext4_inode_get_extra_isize(&fs->sb, inode_ref->inode);\n\n    i.name_index = name_index;\n    i.name = name;\n    i.name_len = name_len;\n    i.value = (value_len) ? value : &ext4_xattr_empty_value;\n    i.value_len = value_len;\n\n    ibody_finder.i = i;\n\n    orig_xattr_block = ext4_inode_get_file_acl(inode_ref->inode, &fs->sb);\n\n    /*\n     * Even if entry is not found, search context block inside the\n     * finder is still valid and can be used to insert entry.\n     */\n    ret = ext4_xattr_ibody_find_entry(inode_ref, &ibody_finder);\n    if (ret != EOK) {\n        ext4_xattr_ibody_initialize(inode_ref);\n        ext4_xattr_ibody_find_entry(inode_ref, &ibody_finder);\n    }\n\n    if (ibody_finder.s.not_found) {\n        if (orig_xattr_block) {\n            block_found = true;\n            ret = ext4_xattr_block_set(inode_ref, &i, true);\n            if (ret == ENOSPC)\n                goto try_insert;\n            else if (ret == ENODATA)\n                goto try_insert;\n            else if (ret != EOK)\n                goto out;\n\n        } else\n            goto try_insert;\n\n    } else {\n    try_insert:\n        /* Only try to set entry in ibody if inode is sufficiently large */\n        if (extra_isize)\n            ret = ext4_xattr_set_entry(&i, &ibody_finder.s, false);\n        else\n            ret = ENOSPC;\n\n        if (ret == ENOSPC) {\n            if (!block_found) {\n                ret = ext4_xattr_block_set(inode_ref, &i, false);\n                ibody_finder.i.value = NULL;\n                ext4_xattr_set_entry(&ibody_finder.i,\n                             &ibody_finder.s, false);\n                inode_ref->dirty = true;\n            }\n\n        } else if (ret == EOK) {\n            if (block_found)\n                ret = ext4_xattr_block_remove(inode_ref, &i);\n\n            inode_ref->dirty = true;\n        }\n    }\n\nout:\n    return ret;\n}\n\n#endif\n\n/**\n * @}\n */\n"
  },
  {
    "path": "user.libs/libmisc/Makefile",
    "content": "TARGET\t\t= libmisc.a\nLIB_CFLAGS\t= -I./include\n\nSRC_C\t= $(wildcard *.c)\n\nINSTALL_HEADERS = include/misc.h\n\ninclude $(projtree)/scripts/lib_build.mk\n"
  },
  {
    "path": "user.libs/libmisc/include/misc.h",
    "content": "#ifndef __MINOS_MISC_H__\n#define __MINOS_MISC_H__\n\nint get_irq_handles(int argc, char **argv, int *handles, int cnt);\nint get_mmio_handles(int argc, char **argv, int *handles, int cnt);\nint get_dma_handles(int argc, char **argv, int *handles, int cnt);\nint get_handles(int argc, char **argv, int *handles, int cnt);\n\n#endif\n"
  },
  {
    "path": "user.libs/libmisc/misc.c",
    "content": "/*\n * SPDX-License-Identifier: GPL-2.0\n *\n * Copyright (C) 2020 Min Le (lemin9538@gmail.com)\n */\n\n#include <stdlib.h>\n#include <string.h>\n#include <errno.h>\n#include <inttypes.h>\n#include <ctype.h>\n\nstatic int __get_resource_handles(char *compare, char *string,\n\t\tint *handles, int cnt)\n{\n\tint len = strlen(compare);\n\tchar *tmp = string;\n\tchar *str;\n\tint num = 0;\n\n\tif (strncmp(tmp, compare, len) != 0)\n\t\treturn -EINVAL;\n\n\ttmp += len;\n\twhile ((str = strsep(&tmp, \",\")) != NULL) {\n\t\tif ((*str == 0) || (!isdigit(*str)))\n\t\t\tcontinue;\n\n\t\thandles[num++] = atoi(str);\n\t\tif (num >= cnt)\n\t\t\tbreak;\n\t}\n\n\treturn num;\n}\n\nstatic int get_resource_handles(int argc, char **argv, char *comp,\n\t\tint *handles, int cnt)\n{\n\tint i;\n\n\tif (cnt <= 0)\n\t\treturn -EINVAL;\n\n\tfor (i = 0; i < argc; i++) {\n\t\tif (argv[i] == NULL)\n\t\t\tbreak;\n\n\t\tif (__get_resource_handles(comp, argv[i], handles, cnt) == cnt)\n\t\t\treturn cnt;\n\t}\n\n\treturn -ENOENT;\n}\n\nint get_irq_handles(int argc, char **argv, int *handles, int cnt)\n{\n\treturn get_resource_handles(argc, argv, \"irq@\", handles, cnt);\n}\n\nint get_mmio_handles(int argc, char **argv, int *handles, int cnt)\n{\n\treturn get_resource_handles(argc, argv, \"mmio@\", handles, cnt);\n}\n\nint get_dma_handles(int argc, char **argv, int *handles, int cnt)\n{\n\treturn get_resource_handles(argc, argv, \"dma@\", handles, cnt);\n}\n\nint get_handles(int argc, char **argv, int *handles, int cnt)\n{\n\treturn get_resource_handles(argc, argv, \"handle@\", handles, cnt);\n}\n"
  },
  {
    "path": "user.sbin/chiyou/Makefile",
    "content": "TARGET \t\t= chiyou.srv\n\nAPP_LINK_LIBS\t= fdt misc\n\nSRC_C\t:= $(wildcard *.c)\n\nAPP_INSTALL_DIR = ramdisk\n\nTEXT_START := 0xc000000\n\ninclude $(projtree)/scripts/app_build.mk\n"
  },
  {
    "path": "user.sbin/chiyou/chiyou.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <misc.h>\n#include <errno.h>\n#include <minos/kobject.h>\n#include <minos/proto.h>\n#include <minos/types.h>\n#include <minos/debug.h>\n\n#include \"of.h\"\n\n#define BUF_SIZE 256\n\nenum {\n\tRES_TYPE_MMIO,\n\tRES_TYPE_IRQ,\n\tRES_TYPE_GPIO,\n\tRES_TYPE_DMA_CHANNEL,\n\tRES_TYPE_IOMMU_SID,\n\tRES_TYPE_MAX,\n};\n\nstruct resource {\n\tuint8_t type;\n\tuint8_t index;\n\tint handle;\n\tunsigned long base;\n\tunsigned long end;\n\tstruct list_head list;\n};\n\nstatic int pmem_handle;\nstatic int chiyou_handle;\n\nstatic void *dtb_base;\nstatic char buf[BUF_SIZE];\n\nstatic int create_mmio_handle(unsigned long base, unsigned long size)\n{\n\tstruct pma_create_arg args;\n\n\tsize = PAGE_BALIGN(size);\n\targs.size = size;\n\targs.type = PMA_TYPE_MMIO;\n\targs.start = base;\n\targs.right = KOBJ_RIGHT_RW;\n\n\treturn kobject_create(KOBJ_TYPE_PMA, (unsigned long)&args);\n}\n\nstatic int create_irq_handle(uint32_t irq, unsigned long flags)\n{\n\treturn kobject_create(KOBJ_TYPE_IRQ, irq);\n}\n\nstatic int get_device_node(const char *name,\n\t\tuint32_t key, struct device_node **dnode)\n{\n\tstruct device_node *__dnode;\n\tchar *comp[2] = {buf, NULL};\n\n\t__dnode = of_find_node_by_compatible(of_root_node, comp);\n\tif (!__dnode) {\n\t\tpr_err(\"can not find device [%s]\\n\", buf);\n\t\treturn -ENOENT;\n\t}\n\t\n\t// if (__dnode->key != key)\n\t//\treturn -EACCES;\n\n\t*dnode = __dnode;\n\n\treturn 0;\n}\n\nstatic int handle_get_mmio(struct device_node *dnode, int index)\n{\n\tstruct resource *res;\n\tuint64_t addr, size;\n\tint ret, handle;\n\n\tlist_for_each_entry(res, &dnode->resource_list, list) {\n\t\tif (res->type != RES_TYPE_MMIO)\n\t\t\tcontinue;\n\n\t\tif (res->index == index)\n\t\t\treturn res->handle;\n\t}\n\n\t/*\n\t * get the mmio range from the dtb.\n\t */\n\tret = of_translate_address_index(dnode, &addr, &size, index);\n\tif (ret)\n\t\treturn ret;\n\n\thandle = create_mmio_handle(addr, size);\n\tif (handle <= 0)\n\t\treturn -ENOMEM;\n\n\tres = zalloc(sizeof(struct resource));\n\tif (!res) {\n\t\tkobject_close(handle);\n\t\treturn -ENOMEM;\n\t}\n\n\tres->type = RES_TYPE_MMIO;\n\tres->base = addr;\n\tres->end = addr + size;\n\tres->handle = handle;\n\tres->index = index;\n\tlist_add_tail(&dnode->resource_list, &res->list);\n\n\treturn handle;\n}\n\nstatic int handle_get_irq(struct device_node *dnode, int index)\n{\n\tstruct resource *res;\n\tunsigned long flags;\n\tuint32_t irq;\n\tint ret, handle;\n\n\tlist_for_each_entry(res, &dnode->resource_list, list) {\n\t\tif (res->type != RES_TYPE_IRQ)\n\t\t\tcontinue;\n\n\t\tif (res->index == index)\n\t\t\treturn res->handle;\n\t}\n\n\tret = of_get_device_irq_index(dnode, &irq, &flags, index);\n\tif (ret)\n\t\treturn ret;\n\n\thandle = create_irq_handle(irq, flags);\n\tif (handle <= 0)\n\t\treturn -ENOENT;\n\n\tres = zalloc(sizeof(struct resource));\n\tif (!res) {\n\t\tkobject_close(handle);\n\t\treturn -ENOMEM;\n\t}\n\n\tres->type = RES_TYPE_IRQ;\n\tres->base = irq;\n\tres->end = irq;\n\tres->handle = handle;\n\tres->index = index;\n\tlist_add_tail(&dnode->resource_list, &res->list);\n\n\treturn handle;\n}\n\nstatic int handle_get_dma_channel(struct device_node *dnode, int index)\n{\n\treturn 0;\n}\n\nstatic int handle_get_iommu_sid(struct device_node *dnode, int index)\n{\n\treturn 0;\n}\n\nstatic int do_handle_chiyou_event(struct proto *proto, char *buf, int *right)\n{\n\tstruct proto_devinfo *dinfo = &proto->devinfo;\n\tstruct device_node *dnode;\n\tlong ret;\n\n\tret = get_device_node(buf, dinfo->key, &dnode);\n\tif (ret)\n\t\treturn ret;\n\n\tswitch (proto->proto_id) {\n\tcase PROTO_GET_MMIO:\n\t\tret = handle_get_mmio(dnode, dinfo->index);\n\t\t*right = KR_RWCM;\n\t\tbreak;\n\tcase PROTO_GET_IRQ:\n\t\tret = handle_get_irq(dnode, dinfo->index);\n\t\t*right = KR_RW;\n\t\tbreak;\n\tcase PROTO_GET_DMA_CHANEL:\n\t\tret = handle_get_dma_channel(dnode, dinfo->index);\n\t\t*right = KR_RW;\n\t\tbreak;\n\tcase PROTO_GET_IOMMU_SID:\n\t\tret = handle_get_iommu_sid(dnode, dinfo->index);\n\t\t*right = KR_RW;\n\t\tbreak;\n\tdefault:\n\t\tret = -ENOSYS;\n\t\tpr_err(\"unknow chiyou event %d\\n\", proto->proto_id);\n\t\tbreak;\n\t}\n\n\treturn ret;\n}\n\nstatic int handle_chiyou_event(int loop)\n{\n\tstruct proto proto;\n\tint ret, right;\n\n\tfor (;;) {\n\t\tret = sys_read_proto_with_string(chiyou_handle,\n\t\t\t\t&proto, buf, BUF_SIZE, -1);\n\t\tif (ret) {\n\t\t\tpr_err(\"read proto fail %d\\n\", ret);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (proto.proto_id == PROTO_ROOTFS_READY) {\n\t\t\tkobject_reply_errcode(chiyou_handle, proto.token, 0);\n\t\t\tif (!loop) {\n\t\t\t\tpr_info(\"rootfs is ready, exit chiyou event loop\\n\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\tret = do_handle_chiyou_event(&proto, buf, &right);\n\t\t\tif (ret <= 0) {\n\t\t\t\tpr_err(\"handle chiyou event fail %d %s %d %d\\n\",\n\t\t\t\t\t\tret, buf, proto.proto_id,\n\t\t\t\t\t\tproto.devinfo.index);\n\t\t\t}\n\n\t\t\tkobject_reply_handle(chiyou_handle, proto.token, ret, right);\n\t\t}\n\t}\n\n\treturn 0;\n}\n\nint main(int argc, char **argv)\n{\n\tint ret, handles[2];\n\n\tret = get_handles(argc, argv, handles, 2);\n\tif (ret != 2) {\n\t\tpr_err(\"get handles from argv fail\\n\");\n\t\texit(-ENOENT);\n\t}\n\n\tchiyou_handle = handles[0];\n\tpmem_handle = handles[1];\n\n\tif (chiyou_handle <= 0 || pmem_handle <= 0) {\n\t\tpr_err(\"invalid handle for chiyou %d %d\\n\",\n\t\t\t\t\tchiyou_handle, pmem_handle);\n\t\texit(-EINVAL);\n\t}\n\n\tif (kobject_mmap(pmem_handle, &dtb_base, NULL)) {\n\t\tpr_err(\"mmap dtb address fail\\n\");\n\t\texit(-ENOMEM);\n\t}\n\n\tif (of_init(dtb_base))\n\t\texit(-EIO);\n\n\t/*\n\t * since the rootfs may not ready now, and the rootfs driver\n\t * will also get the information from the chiyou service. need\n\t * wait here, and get the ready signal from rootfs, then loading\n\t * the drivers from the rootfs.\n\t */\n\tret = handle_chiyou_event(0);\n\tif (ret)\n\t\texit(ret);\n\n\t/*\n\t * then try to load all the request driver for each\n\t * device.\n\t */\n\t// load_drivers();\n\n\thandle_chiyou_event(1);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "user.sbin/chiyou/of.c",
    "content": "/*\n * Copyright (C) 2020 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdio.h>\n#include <string.h>\n#include <inttypes.h>\n#include <errno.h>\n#include <sys/param.h>\n#include <minos/debug.h>\n#include <minos/compiler.h>\n\n#include <libfdt/libfdt.h>\n#include \"of.h\"\n\nvoid *dtb_address;\nstruct device_node *of_root_node;\n\nint fdt_n_size_cells(void *dtb, int node)\n{\n\tfdt32_t *v;\n\tint parent, child = node;\n\n\tparent = fdt_parent_offset(dtb, child);\n\n\tdo {\n\t\tif (parent >= 0)\n\t\t\tchild = parent;\n\t\tv = (fdt32_t *)fdt_getprop(dtb, child, \"#size-cells\", NULL);\n\t\tif (v)\n\t\t\treturn fdt32_to_cpu(*v);\n\n\t\tparent = fdt_parent_offset(dtb, child);\n\t} while (parent >= 0);\n\n\treturn 2;\n}\n\nint fdt_n_addr_cells(void *dtb, int node)\n{\n\tfdt32_t *v;\n\tint parent, child = node;\n\n\tparent = fdt_parent_offset(dtb, child);\n\n\tdo {\n\t\tif (parent >= 0)\n\t\t\tchild = parent;\n\t\tv = (fdt32_t *)fdt_getprop(dtb, child, \"#address-cells\", NULL);\n\t\tif (v)\n\t\t\treturn fdt32_to_cpu(*v);\n\n\t\tparent = fdt_parent_offset(dtb, child);\n\t} while (parent >= 0);\n\n\treturn 2;\n}\n\nstatic inline void *__of_getprop(void *dtb, int node,\n\t\tchar *attr, int *len)\n{\n\tconst void *data;\n\n\tif (!dtb || node <= 0 || !attr)\n\t\treturn NULL;\n\n\tdata = fdt_getprop(dtb, node, attr, len);\n\tif (!data || (*len <= 0))\n\t\treturn NULL;\n\n\treturn (void *)data;\n}\n\nvoid *of_getprop(struct device_node *node, char *attr, int *len)\n{\n\treturn __of_getprop(node->data, node->offset, attr, len);\n}\n\nstatic int __of_get_node_by_name(void *data, int pnode,\n\t\tchar *str, int deepth)\n{\n\tconst char *name;\n\tint node = -1, child, len;\n\n\tif (deepth >= 10)\n\t\treturn -ENOENT;\n\n\tfdt_for_each_subnode(node, data, pnode) {\n\t\tif (NULL == (name = fdt_get_name(data, node, &len)))\n\t\t\tcontinue;\n\t\tif (len < 0)\n\t\t\tcontinue;\n\n\t\tif (strncmp(name, str, strlen(str)) == 0)\n\t\t\treturn node;\n\t\telse {\n\t\t\tchild = __of_get_node_by_name(data, node,\n\t\t\t\t\tstr, deepth + 1);\n\t\t\tif (child > 0)\n\t\t\t\treturn child;\n\t\t}\n\t}\n\n\treturn -ENOENT;\n}\n\nint of_get_node_by_name(void *data, int pnode, char *str)\n{\n\tif (!data || (pnode < 0) || !str)\n\t\treturn -EINVAL;\n\n\treturn __of_get_node_by_name(data, pnode, str, 0);\n}\n\nconst char *__of_get_compatible(void *dtb, int node)\n{\n\tconst void *data;\n\tint len;\n\n\tdata = fdt_getprop(dtb, node, \"compatible\", &len);\n\tif (!data || len == 0)\n\t\treturn NULL;\n\n\treturn (const char *)data;\n}\n\nint __of_get_bool(void *dtb, int node, char *attr)\n{\n\tint len;\n\tconst struct fdt_property *prop;\n\n\tprop = fdt_get_property(dtb, node, attr, &len);\n\treturn (prop != NULL);\n}\n\nint of_get_bool(struct device_node *node, char *attr)\n{\n\treturn __of_get_bool(node->data, node->offset, attr);\n}\n\nint __of_get_string(void *dtb, int node, char *attr, char *str, int len)\n{\n\tchar *s;\n\tint length;\n\n\tmemset(str, 0, len);\n\ts = (char *)__of_getprop(dtb, node, attr, &length);\n\tif (!s || !str || (length == 0))\n\t\treturn -EINVAL;\n\n\tlength = MIN(len - 1, length);\n\tstrncpy(str, s, length);\n\n\treturn length;\n}\n\nchar *of_get_cmdline(void *dtb)\n{\n\tint node, len;\n\tconst void *data = NULL;\n\n\tnode = fdt_path_offset(dtb, \"/chosen\");\n\tif (node <= 0)\n\t\treturn NULL;\n\n\tdata = fdt_getprop(dtb, node, \"bootargs\", &len);\n\treturn (char *)data;\n}\n\nint __of_get_u16_array(void *dtb, int node, char *attr,\n\t\tuint16_t *array, int len)\n{\n\tfdt16_t *val;\n\tint length, i;\n\n\tmemset(array, 0, sizeof(uint16_t) * len);\n\tval = (fdt16_t *)__of_getprop(dtb, node, attr, &length);\n\tif (!val)\n\t\treturn -EINVAL;\n\n\tif ((length % sizeof(uint16_t)) != 0) {\n\t\tpr_err(\"node is not a u32 array %d\\n\", length);\n\t\treturn -EINVAL;\n\t}\n\n\tlength = length / sizeof(fdt16_t);\n\tlength = MIN(len, length);\n\n\tfor (i = 0; i < length; i++)\n\t\t*array++ = fdt16_to_cpu(val[i]);\n\n\treturn length;\n}\n\nint __of_get_u32_array(void *dtb, int node, char *attr,\n\t\tuint32_t *array, int len)\n{\n\tfdt32_t *val;\n\tint length, i;\n\n\tmemset(array, 0, sizeof(uint32_t) * len);\n\tval = (fdt32_t *)__of_getprop(dtb, node, attr, &length);\n\tif (!val)\n\t\treturn -EINVAL;\n\n\tif ((length % sizeof(fdt32_t)) != 0) {\n\t\tpr_err(\"node is not a u32 array %d\\n\", length);\n\t\treturn -EINVAL;\n\t}\n\n\tlength = length / sizeof(fdt32_t);\n\tlength = MIN(len, length);\n\n\tfor (i = 0; i < length; i++)\n\t\t*array++ = fdt32_to_cpu(val[i]);\n\n\treturn length;\n}\n\nint __of_get_u64_array(void *dtb, int node, char *attr,\n\t\tuint64_t *array, int len)\n{\n\tfdt64_t *val;\n\tint length, i;\n\n\tmemset(array, 0, sizeof(uint64_t) * len);\n\tval = (fdt64_t *)__of_getprop(dtb, node, attr, &length);\n\tif (!val) {\n\t\tpr_err(\"can not get %s\\n\", attr);\n\t\treturn -EINVAL;\n\t}\n\n\tif ((length % sizeof(fdt64_t)) != 0) {\n\t\tpr_err(\"node is not a u64 array %d\\n\", length);\n\t\treturn -EINVAL;\n\t}\n\n\tlength = length / sizeof(uint64_t);\n\tlength = MIN(len, length);\n\n\tfor (i = 0; i < length; i++)\n\t\t*array++ = fdt64_to_cpu(val[i]);\n\n\treturn length;\n}\n\nstatic inline struct device_node *alloc_device_node(void)\n{\n\tstruct device_node *node;\n\n\tnode = zalloc(sizeof(struct device_node));\n\tif (!node) {\n\t\tpr_warn(\"%s no enough memory\\n\", __func__);\n\t\treturn NULL;\n\t}\n\n\tinit_list(&node->resource_list);\n\n\treturn node;\n}\n\nstatic int of_parse_dt_class(struct device_node *node)\n{\n\tint ret;\n\tchar type[64];\n\n\tret = __of_get_string(node->data, node->offset,\n\t\t\t\"device_type\", type, 64);\n\tif (ret > 0) {\n\t\tif (strcmp(type, \"cpu\") == 0)\n\t\t\tnode->class = DT_CLASS_CPU;\n\t\telse if (strcmp(type, \"memory\") == 0)\n\t\t\tnode->class = DT_CLASS_MEMORY;\n\t\telse if (strcmp(type, \"pci\") == 0)\n\t\t\tnode->class = DT_CLASS_PCI_BUS;\n\t\telse if (strcmp(type, \"virtual_machine\") == 0)\n\t\t\tnode->class = DT_CLASS_VM;\n\t\telse if (strcmp(type, \"vmbox\") == 0)\n\t\t\tnode->class = DT_CLASS_VMBOX;\n\t\telse\n\t\t\tnode->class = DT_CLASS_OTHER;\n\t} else {\n\t\tret = __of_get_bool(node->data, node->offset,\n\t\t\t\t\"interrupt-controller\");\n\t\tif (ret) {\n\t\t\tnode->class = DT_CLASS_IRQCHIP;\n\t\t\treturn 0;\n\t\t}\n\n\t\tif (strcmp(node->name, \"timer\") == 0) {\n\t\t\tnode->class = DT_CLASS_TIMER;\n\t\t\treturn 0;\n\t\t}\n\n\t\tif (!fdt_node_check_compatible(node->data,\n\t\t\t\tnode->offset, \"simple-bus\")) {\n\t\t\tnode->class = DT_CLASS_SIMPLE_BUS;\n\t\t\treturn 0;\n\t\t}\n\n\t\tret = __of_get_bool(node->data, node->offset,\n\t\t\t\t\"virtual_device\");\n\t\tif (ret) {\n\t\t\tnode->class = DT_CLASS_VDEV;\n\t\t\treturn 0;\n\t\t}\n\n\t\tswitch (node->parent->class) {\n\t\tcase DT_CLASS_IRQCHIP:\n\t\tcase DT_CLASS_CPU:\n\t\tcase DT_CLASS_PDEV:\n\t\tcase DT_CLASS_VDEV:\n\t\t\tnode->class = node->parent->class;\n\t\t\treturn 0;\n\t\tdefault:\n\t\t\tbreak;;\n\t\t}\n\n\t\tif (node->compatible)\n\t\t\tnode->class = DT_CLASS_PDEV;\n\t\telse\n\t\t\tnode->class = DT_CLASS_OTHER;\n\t}\n\n\treturn 0;\n}\n\nint of_device_match(struct device_node *node, char **comp)\n{\n\tif (!node || !comp)\n\t\treturn -EINVAL;\n\n\twhile (*comp != NULL) {\n\t\tif (!fdt_node_check_compatible(node->data,\n\t\t\t\tnode->offset, *comp))\n\t\t\treturn 1;\n\n\t\tcomp++;\n\t}\n\n\treturn 0;\n}\n\nstatic int __of_parse_device_node(struct device_node *root,\n\t\tstruct device_node *pnode)\n{\n\tint child, index = 0;\n\tstruct device_node *node, *prev;\n\tvoid *data = pnode->data;\n\n\tif (!pnode)\n\t\treturn -EINVAL;\n\n\tfdt_for_each_subnode(child, data, pnode->offset) {\n\t\tnode = alloc_device_node();\n\t\tif (!node)\n\t\t\treturn -ENOMEM;\n\n\t\tnode->name = fdt_get_name(data, child, NULL);\n\t\tnode->compatible = __of_get_compatible(data, child);\n\t\tnode->offset = child;\n\t\tnode->data = data;\n\t\tnode->parent = pnode;\n\t\tnode->flags |= DEVICE_NODE_F_OF;\n\n\t\t/* udpate the child and the sibling */\n\t\tif (index == 0) {\n\t\t\tpnode->child = node;\n\t\t\tindex = 1;\n\t\t} else {\n\t\t\tprev->sibling = node;\n\t\t}\n\n\t\tprev = node;\n\t\tnode->next = root->next;\n\t\troot->next = node;\n\t\tof_parse_dt_class(node);\n\t\t__of_parse_device_node(root, node);\n\t}\n\n\treturn 0;\n}\n\n/* must pass a root device node to this function */\nstatic void *__iterate_device_node(struct device_node *node,\n\t\tof_iterate_fn func, void *arg, int loop)\n{\n\tstruct device_node *child, *sibling, *n;\n\n\tif (!node)\n\t\treturn NULL;\n\n\tchild = node->child;\n\tn = func(node, arg);\n\tif (n && !loop)\n\t\treturn n;\n\n\twhile (child) {\n\t\tsibling = child->sibling;\n\t\tn = __iterate_device_node(child, func, arg, loop);\n\t\tif (n && !loop)\n\t\t\treturn n;\n\t\tchild = sibling;\n\t}\n\n\treturn NULL;\n}\n\nvoid *of_iterate_all_node_loop(struct device_node *node,\n\t\tof_iterate_fn func, void *arg)\n{\n\treturn __iterate_device_node(node, func, arg, 1);\n}\n\nvoid *of_iterate_all_node(struct device_node *node,\n\t\tof_iterate_fn func, void *arg)\n{\n\treturn __iterate_device_node(node, func, arg, 0);\n}\n\nstatic void *find_node_by_compatible(struct device_node *node, void *comp)\n{\n\tchar **str = (char **)comp;\n\n\tif (of_device_match(node, str))\n\t\treturn node;\n\n\treturn NULL;\n}\n\nstatic void *find_node_by_name(struct device_node *node, void *name)\n{\n\tif (node->name && !(strcmp(node->name, (char *)name)))\n\t\treturn node;\n\n\treturn NULL;\n}\n\nstruct device_node *\nof_find_node_by_compatible(struct device_node *root, char **comp)\n{\n\treturn (struct device_node *)__iterate_device_node(root,\n\t\t\tfind_node_by_compatible, (void *)comp, 0);\n}\n\nstruct device_node *\nof_find_node_by_name(struct device_node *root, char *name)\n{\n\treturn (struct device_node *)__iterate_device_node(root,\n\t\t\tfind_node_by_name, (void *)name, 0);\n}\n\nint of_n_addr_cells(struct device_node *node)\n{\n\tfdt32_t *ip;\n\n\tdo {\n\t\tip = (fdt32_t *)fdt_getprop(node->data, node->offset,\n\t\t\t\t\"#address-cells\", NULL);\n\t\tif (ip)\n\t\t\treturn fdt32_to_cpu(*ip);\n\n\t\tif (node->parent)\n\t\t\tnode = node->parent;\n\t} while (node);\n\n\treturn 2;\n}\n\nint of_n_size_cells(struct device_node *node)\n{\n\tfdt32_t *ip;\n\n\tdo {\n\t\tip = (fdt32_t *)fdt_getprop(node->data, node->offset,\n\t\t\t\t\"#size-cells\", NULL);\n\t\tif (ip)\n\t\t\treturn fdt32_to_cpu(*ip);\n\n\t\tif (node->parent)\n\t\t\tnode = node->parent;\n\t} while (node);\n\n\treturn 1;\n}\n\nint of_get_phandle(struct device_node *node)\n{\n\tconst struct fdt_property *prop;\n\tint len;\n\n\tprop = fdt_get_property(node->data, node->offset,\n\t\t\t\"interrupt-parent\", &len);\n\tif (!prop)\n\t\treturn -1;\n\n\treturn fdt32_to_cpu(*(fdt32_t *)prop->data);\n}\n\nint of_n_interrupt_cells(struct device_node *node)\n{\n\tint ret, len;\n\tuint32_t ni = 0;\n\tstruct device_node *parent = node;\n\tuint32_t phandle;\n\tint offset;\n\tconst struct fdt_property *prop;\n\n\twhile (parent) {\n\t\tprop = fdt_get_property(parent->data, parent->offset,\n\t\t\t\t\"interrupt-parent\", &len);\n\t\tif (!prop || !prop->data)\n\t\t\tgoto repeat;\n\n\t\tphandle = fdt32_to_cpu(*(fdt32_t *)prop->data);\n\t\toffset = fdt_node_offset_by_phandle(parent->data, phandle);\n\t\tif (offset <= 0)\n\t\t\treturn 0;\n\n\t\tret = __of_get_u32_array(parent->data, offset,\n\t\t\t\t\"#interrupt-cells\", &ni, 1);\n\t\tif (ret == 1)\n\t\t\treturn ni;\nrepeat:\n\t\tparent = parent->parent;\n\t}\n\n\treturn 0;\n}\n\nint of_n_addr_count(struct device_node *node)\n{\n\tint na, ns;\n\tint len;\n\tconst void *prop;\n\n\tna = fdt_n_addr_cells(node->data, node->offset);\n\tns = fdt_n_size_cells(node->data, node->offset);\n\n\tprop = fdt_getprop(node->data, node->offset, \"reg\", &len);\n\tif (!prop)\n\t\treturn 0;\n\n\tlen = len / ((na + ns) * sizeof(fdt32_t));\n\treturn len;\n}\n\nint of_data(void *data)\n{\n\treturn !fdt_check_header(data);\n}\n\nstatic inline uint64_t of_read_number(const fdt32_t *cell, int size)\n{\n\tuint64_t r = 0;\n\twhile (size--) {\n\t\tr = (r << 32) | fdt32_to_cpu(*cell);\n\t\tcell++;\n\t}\n\treturn r;\n}\n\nstatic inline int of_check_counts(int na, int ns)\n{\n\treturn ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && (ns) > 0);\n}\n\n/* Callbacks for bus specific translators */\nstruct of_bus {\n\tconst char *name;\n\tconst char *addresses;\n\tvoid (*count_cells)(void *blob, int parentoffset,\n\t\t\tint *addrc, int *sizec);\n\tuint64_t (*map)(uint32_t *addr, const uint32_t *range,\n\t\t\tint na, int ns, int pna);\n\tint (*translate)(uint32_t *addr, uint64_t offset, int na);\n};\n\n/* Default translator (generic bus) */\nstatic void of_bus_default_count_cells(void *blob,\n\t\tint parentoffset, int *addrc, int *sizec)\n{\n\tconst fdt32_t *prop;\n\n\tif (addrc) {\n\t\tprop = fdt_getprop(blob, parentoffset, \"#address-cells\", NULL);\n\t\tif (prop)\n\t\t\t*addrc = fdt32_to_cpu(*prop);\n\t\telse\n\t\t\t*addrc = 2;\n\t}\n\n\tif (sizec) {\n\t\tprop = fdt_getprop(blob, parentoffset, \"#size-cells\", NULL);\n\t\tif (prop)\n\t\t\t*sizec = fdt32_to_cpu(*prop);\n\t\telse\n\t\t\t*sizec = 1;\n\t}\n}\n\nstatic uint64_t of_bus_default_map(fdt32_t *addr,\n\t\tconst fdt32_t *range,\n\t\tint na, int ns, int pna)\n{\n\tuint64_t cp, s, da;\n\n\tcp = of_read_number(range, na);\n\ts  = of_read_number(range + na + pna, ns);\n\tda = of_read_number(addr, na);\n\n\tpr_debug(\"OF: default map, cp=0x%p, s=0x%p, da=0x%p\\n\", cp, s, da);\n\n\tif (da < cp || da >= (cp + s))\n\t\treturn OF_BAD_ADDR;\n\treturn da - cp;\n}\n\nstatic int of_bus_default_translate(uint32_t *addr, uint64_t offset, int na)\n{\n\tuint64_t a = of_read_number(addr, na);\n\tmemset(addr, 0, na * 4);\n\ta += offset;\n\tif (na > 1) {\n\t\taddr[na - 2] = a >> 32;\n\t\taddr[na - 2] = cpu_to_fdt32(addr[na - 2]);\n\t}\n\taddr[na - 1] = a & 0xffffffffu;\n\taddr[na - 1] = cpu_to_fdt32(addr[na - 1]);\n\n\treturn 0;\n}\n\n/* Array of bus specific translators */\nstatic struct of_bus of_busses[] = {\n\t/* Default */\n\t{\n\t\t.name = \"default\",\n\t\t.addresses = \"reg\",\n\t\t.count_cells = of_bus_default_count_cells,\n\t\t.map = of_bus_default_map,\n\t\t.translate = of_bus_default_translate,\n\t},\n};\n\nstatic int of_translate_one(void * blob, int parent, struct of_bus *bus,\n\t\t\t    struct of_bus *pbus, uint32_t *addr,\n\t\t\t    int na, int ns, int pna, const char *rprop)\n{\n\tconst uint32_t *ranges;\n\tint rlen;\n\tint rone;\n\tuint64_t offset = OF_BAD_ADDR;\n\n\t/* Normally, an absence of a \"ranges\" property means we are\n\t * crossing a non-translatable boundary, and thus the addresses\n\t * below the current not cannot be converted to CPU physical ones.\n\t * Unfortunately, while this is very clear in the spec, it's not\n\t * what Apple understood, and they do have things like /uni-n or\n\t * /ht nodes with no \"ranges\" property and a lot of perfectly\n\t * useable mapped devices below them. Thus we treat the absence of\n\t * \"ranges\" as equivalent to an empty \"ranges\" property which means\n\t * a 1:1 translation at that level. It's up to the caller not to try\n\t * to translate addresses that aren't supposed to be translated in\n\t * the first place. --BenH.\n\t */\n\tranges = (uint32_t *)fdt_getprop(blob, parent, rprop, &rlen);\n\tif (ranges == NULL || rlen == 0) {\n\t\toffset = of_read_number(addr, na);\n\t\tmemset(addr, 0, pna * 4);\n\t\tpr_debug(\"OF: no ranges, 1:1 translation\\n\");\n\t\tgoto finish;\n\t}\n\n\tpr_debug(\"OF: walking ranges...\\n\");\n\n\t/* Now walk through the ranges */\n\trlen /= 4;\n\trone = na + pna + ns;\n\tfor (; rlen >= rone; rlen -= rone, ranges += rone) {\n\t\toffset = bus->map(addr, ranges, na, ns, pna);\n\t\tif (offset != OF_BAD_ADDR)\n\t\t\tbreak;\n\t}\n\tif (offset == OF_BAD_ADDR) {\n\t\tpr_debug(\"OF: not found !\\n\");\n\t\treturn 1;\n\t}\n\tmemcpy(addr, ranges + na, 4 * pna);\n\n finish:\n\t/* Translate it into parent bus space */\n\treturn pbus->translate(addr, offset, pna);\n}\n\n/*\n * Translate an address from the device-tree into a CPU physical address,\n * this walks up the tree and applies the various bus mappings on the\n * way.\n *\n * Note: We consider that crossing any level with #size-cells == 0 to mean\n * that translation is impossible (that is we are not dealing with a value\n * that can be mapped to a cpu physical address). This is not really specified\n * that way, but this is traditionally the way IBM at least do things\n */\nstatic uint64_t __of_translate_address(struct device_node *node,\n\t\tconst fdt32_t *in_addr, const char *prop)\n{\n\tint node_offset;\n\tstruct device_node *parent;\n\tfdt32_t addr[OF_MAX_ADDR_CELLS];\n\tint na, ns, pna, pns;\n\tstruct of_bus *bus, *pbus;\n\tuint64_t result = OF_BAD_ADDR;\n\tvoid *data;\n\n\tpr_debug(\"OF: ** translation for device %s **\\n\", node->name);\n\n\t/* Get parent & match bus type */\n\tparent = node->parent;\n\tdata = node->data;\n\tif (parent == NULL)\n\t\tgoto bail;\n\tbus = &of_busses[0];\n\n\t/* Cound address cells & copy address locally */\n\tbus->count_cells(data, parent->offset, &na, &ns);\n\tif (!of_check_counts(na, ns)) {\n\t\tpr_warn(\"%s: Bad cell count for %s\\n\", __func__, parent->name);\n\t\tgoto bail;\n\t}\n\tmemcpy(addr, in_addr, na * 4);\n\n\tpr_debug(\"OF: bus is %s (na=%d, ns=%d) on %s\\n\",\n\t\t\tbus->name, na, ns, parent->name);\n\n\t/* Translate */\n\tfor (;;) {\n\t\t/* Switch to parent bus */\n\t\tnode_offset = parent->offset;\n\t\tparent = parent->parent;\n\n\t\t/* If root, we have finished */\n\t\tif (!parent || (parent->offset < 0)) {\n\t\t\tpr_debug(\"OF: reached root node\\n\");\n\t\t\tresult = of_read_number(addr, na);\n\t\t\tbreak;\n\t\t}\n\n\t\t/* Get new parent bus and counts */\n\t\tpbus = &of_busses[0];\n\t\tpbus->count_cells(data, parent->offset, &pna, &pns);\n\t\tif (!of_check_counts(pna, pns)) {\n\t\t\tpr_err(\"%s: Bad cell count for %s\\n\",\n\t\t\t\t\t__func__, parent->name);\n\t\t\tbreak;\n\t\t}\n\n\t\tpr_debug(\"OF: parent bus is %s (na=%d, ns=%d) on %s\\n\",\n\t\t\t\tpbus->name, pna, pns, parent->name);\n\n\t\t/* Apply bus translation */\n\t\tif (of_translate_one(data, node_offset, bus, pbus,\n\t\t\t\t\taddr, na, ns, pna, \"ranges\"))\n\t\t\tbreak;\n\n\t\t/* Complete the move up one level */\n\t\tna = pna;\n\t\tns = pns;\n\t\tbus = pbus;\n\t}\n bail:\n\n\treturn result;\n}\n\nint of_translate_address_index(struct device_node *np,\n\t\tuint64_t *address, uint64_t *size, int index)\n{\n\tconst fdt32_t *reg;\n\tint na, ns, node, len = 0;\n\tvoid *data;\n\n\tif (!np || !np->data || (np->offset <=0))\n\t\treturn -EINVAL;\n\n\tdata = np->data;\n\tnode = np->offset;\n\tna = fdt_n_addr_cells(np->data, np->offset);\n\tif (na < 1) {\n\t\tpr_debug(\"bad #address-cells %s\\n\", np->name);\n\t\treturn -EINVAL;\n\t}\n\n\tns = fdt_n_size_cells(np->data, np->offset);\n\tif (ns < 0) {\n\t\tpr_debug(\"bad #size-cells %s\\n\", np->name);\n\t\treturn -EINVAL;\n\t}\n\n\treg = fdt_getprop(data, node, \"reg\", &len);\n\tif (!reg || (len <= (index * 4) *(na + ns))) {\n\t\tpr_debug(\"index out of range\\n\");\n\t\treturn -ENOENT;\n\t}\n\n\treg += index * (na + ns);\n\n\tif (ns) {\n\t\t*address = __of_translate_address(np, reg, \"ranges\");\n\t\tif (*address == OF_BAD_ADDR)\n\t\t\treturn -EINVAL;\n\n\t\tif (ns == 2)\n\t\t\t*size = fdt32_to_cpu64(reg[na], reg[na + 1]);\n\t\telse\n\t\t\t*size = fdt32_to_cpu(reg[na]);\n\t} else {\n\t\t*address = of_read_number(reg, na);\n\t\t*size = 0;\n\t}\n\n\treturn 0;\n}\n\nint of_translate_address(struct device_node *node,\n\t\tuint64_t *address, uint64_t *size)\n{\n\treturn of_translate_address_index(node, address, size, 0);\n}\n\nstatic int gic_xlate_irq(struct device_node *node,\n\t\tuint32_t *intspec, unsigned int intsize,\n\t\tuint32_t *hwirq, unsigned long *type)\n{\n\tif (intsize != 3)\n\t\treturn -EINVAL;\n\n\tif (intspec[0] == 0)\n\t\t*hwirq = intspec[1] + 32;\n\telse if (intspec[0] == 1) {\n\t\tif (intspec[1] >= 16)\n\t\t\treturn -EINVAL;\n\t\t*hwirq = intspec[1] + 16;\n\t} else\n\t\treturn -EINVAL;\n\n\t*type = intspec[2];\n\treturn 0;\n}\n\nint of_get_device_irq_index(struct device_node *node, uint32_t *irq,\n\t\tunsigned long *flags, int index)\n{\n\tint irq_cells, len, i;\n\tof32_t *value;\n\tuint32_t irqv[4];\n\n\tif (!node)\n\t\treturn -EINVAL;\n\n\tvalue = (of32_t *)of_getprop(node, \"interrupts\", &len);\n\tif (!value || (len < sizeof(of32_t)))\n\t\treturn -ENOENT;\n\n\tirq_cells = of_n_interrupt_cells(node);\n\tif (irq_cells == 0) {\n\t\tpr_err(\"bad irqcells - %s\\n\", node->name);\n\t\treturn -ENOENT;\n\t}\n\n\tpr_debug(\"interrupt-cells %d\\n\", irq_cells);\n\n\tlen = len / sizeof(of32_t);\n\tif (index >= len)\n\t\treturn -ENOENT;\n\n\tvalue += (index * irq_cells);\n\tfor (i = 0; i < irq_cells; i++)\n\t\tirqv[i] = of32_to_cpu(*value++);\n\n\treturn gic_xlate_irq(node, irqv, irq_cells, irq, flags);\n}\n\nvoid of_release_all_node(struct device_node *node)\n{\n\tstruct device_node *tmp = node;\n\tstruct device_node *tmp2;\n\n\tif (!device_node_is_root(node))\n\t\treturn;\n\n\tdo {\n\t\ttmp2 = tmp->next;\n\t\tfree(tmp);\n\t\ttmp = tmp2;\n\t} while (tmp);\n}\n\nvoid of_parse_device_tree(void)\n{\n\tvoid *data = dtb_address;\n\n\tof_root_node = alloc_device_node();\n\tif (!of_root_node)\n\t\treturn;\n\n\tof_root_node->data = data;\n\tof_root_node->name = \"root node\";\n\tof_root_node->offset = 0;\n\tof_root_node->parent = NULL;\n\tof_root_node->sibling = NULL;\n\tof_root_node->next = NULL;\n\tof_root_node->class = DT_CLASS_OTHER;\n\tof_root_node->compatible = fdt_getprop(data, 0, \"compatible\", NULL);\n\tof_root_node->flags = DEVICE_NODE_F_OF | DEVICE_NODE_F_ROOT;\n\n\t/*\n\t * now parse all the node and convert them to the\n\t * device node struct for the hypervisor and vm0 use\n\t */\n\t__of_parse_device_node(of_root_node, of_root_node);\n}\n\nstatic inline void *of_get_chosen_prop(const char *name, int len)\n{\n\tint node, length;\n\tvoid *d;\n\n\tnode = fdt_path_offset(dtb_address, \"/chosen\");\n\tif (node <= 0)\n\t\treturn NULL;\n\n\td = (void *)fdt_getprop(dtb_address, node, name, &length);\n\tif (!d || (length < len))\n\t\treturn NULL;\n\n\treturn d;\n}\n\nint of_get_console_name(char **name)\n{\n\tvoid *dtb = dtb_address;\n\tint node,  len;\n\tconst void *data = NULL;\n\n\tnode = fdt_path_offset(dtb, \"/chosen\");\n\tif (node <= 0)\n\t\treturn -ENOENT;\n\n\tdata = fdt_getprop(dtb, node, \"minos,stdout\", &len);\n\tif (!data || (len == 0))\n\t\treturn -ENOENT;\n\n\t*name = (char *)data;\n\treturn 0;\n}\n\nstatic int __used of_get_chosen_prop64(const char *name, uint64_t *value)\n{\n\tfdt64_t *data = of_get_chosen_prop(name, sizeof(uint64_t));\n\tif (!data)\n\t\treturn -ENOENT;\n\n\t*value = fdt64_to_cpu(*data);\n\treturn 0;\n}\n\nint of_init(void *dtb)\n{\n\tdtb_address = dtb;\n\tif (!dtb || fdt_check_header(dtb_address)) {\n\t\tpr_err(\"bad device tree address: %p\\n\", dtb_address);\n\t\treturn -EFAULT;\n\t}\n\n\tof_parse_device_tree();\t\n\n\treturn 0;\n}\n"
  },
  {
    "path": "user.sbin/chiyou/of.h",
    "content": "#ifndef __MINOS_SYS_OF_H__\n#define __MINOS_SYS_OF_H__\n\n#include <libfdt/libfdt.h>\n#include <minos/list.h>\n\ntypedef enum __device_class {\n\tDT_CLASS_CPU = 0,\n\tDT_CLASS_MEMORY,\n\tDT_CLASS_IRQCHIP,\n\tDT_CLASS_TIMER,\n\tDT_CLASS_SIMPLE_BUS,\n\tDT_CLASS_PCI_BUS,\n\tDT_CLASS_VDEV,\n\tDT_CLASS_PDEV,\n\tDT_CLASS_VM,\n\tDT_CLASS_VMBOX,\n\tDT_CLASS_VIRQCHIP,\n\tDT_CLASS_OTHER,\n} device_class_t;\n\n#define DEVICE_NODE_F_ROOT\t\t(1 << 0)\n#define DEVICE_NODE_F_OF\t\t(1 << 1)\n\n/*\n * data       - the data for all device such as dtb or acpi\n * offset     - node offset\n * name       - the name of the device node\n * compatible - the compatible used to match device\n * parent     - the parent node of device_node\n * child      - child nodes of the device_node\n * sibling    - brother of the device node\n */\nstruct device_node {\n\tvoid *data;\n\tint offset;\n\tconst char *name;\n\tconst char *compatible;\n\tstruct device_node *parent;\n\tstruct device_node *child;\n\tstruct device_node *sibling;\n\tstruct device_node *next;\n\tdevice_class_t class;\n\tunsigned long flags;\n\tuint32_t key;\n\tstruct list_head resource_list;\n};\n\n#define devnode_name(node)\tnode->name\n\n\ntypedef fdt16_t of16_t;\ntypedef fdt32_t of32_t;\ntypedef fdt64_t of64_t;\n\n#define MAX_DTB_SIZE\t(MEM_BLOCK_SIZE)\n\n#define OF_MAX_ADDR_CELLS\t4\n#define OF_BAD_ADDR\t\t((uint64_t)-1)\n\ntypedef void * (*of_iterate_fn)(struct device_node *, void *arg);\n\nextern struct device_node *of_root_node;\nextern void *dtb_address;\n\n#define of_node_for_each_child(node, child)\t\\\n\tfor (child = node->child; child != NULL; child = child->sibling)\n\nstatic fdt32_t inline cpu_to_of32(uint32_t v)\n{\n\treturn cpu_to_fdt32(v);\n}\n\nstatic uint32_t inline of16_to_cpu(of16_t v)\n{\n\treturn fdt32_to_cpu((fdt16_t)v);\n}\n\nstatic uint32_t inline of32_to_cpu(of32_t v)\n{\n\treturn fdt32_to_cpu((fdt32_t)v);\n}\n\nstatic uint64_t inline of32_to_cpu64(of32_t high, of32_t low)\n{\n\treturn ((uint64_t)fdt32_to_cpu((fdt32_t)high) << 32) |\n\t\tfdt32_to_cpu((fdt32_t)low);\n}\n\nint __of_get_u64_array(void *, int, char *, uint64_t *, int);\nint __of_get_u32_array(void *, int, char *, uint32_t *, int);\nint __of_get_u16_array(void *, int, char *, uint16_t *, int);\nint __of_get_string(void *, int, char *, char *, int);\nint __of_get_bool(void *dtb, int node, char *attr);\nchar *of_get_cmdline(void *dtb);\n\nint of_get_bool(struct device_node *node, char *attr);\nvoid *of_getprop(struct device_node *node, char *attr, int *len);\nint of_get_node_by_name(void *data, int pnode, char *str);\nconst char *__of_get_compatible(void *dtb, int node);\nint of_device_match(struct device_node *node, char **comp);\n\nvoid *of_iterate_all_node_loop(struct device_node *node,\n\t\tof_iterate_fn func, void *arg);\nvoid *of_iterate_all_node(struct device_node *node,\n\t\tof_iterate_fn func, void *arg);\n\nstruct device_node * of_find_node_by_compatible(struct device_node *root, char **comp);\n\nint of_n_addr_cells(struct device_node *node);\nint of_n_size_cells(struct device_node *node);\nint of_n_interrupt_cells(struct device_node *node);\nint of_n_addr_count(struct device_node *node);\nint of_data(void *data);\n\nint of_translate_address_index(struct device_node *node,\n\t\tuint64_t *address, uint64_t *size, int index);\nint of_translate_address(struct device_node *node,\n\t\tuint64_t *address, uint64_t *size);\n\nvoid of_parse_device_tree(void);\nvoid of_release_all_node(struct device_node *node);\nvoid *of_device_node_match(struct device_node *node, void *s, void *e);\nint of_get_phandle(struct device_node *node);\n\nstruct device_node *\nof_find_node_by_name(struct device_node *root, char *name);\n\nint fdt_n_size_cells(void *dtb, int node);\nint fdt_n_addr_cells(void *dtb, int node);\n\nstatic inline int of_get_u64_array(struct device_node *node,\n\t\tchar *attr, uint64_t *array, int len)\n{\n\tif (!node || !attr || !array)\n\t\treturn -EINVAL;\n\n\treturn __of_get_u64_array(node->data, node->offset,\n\t\t\tattr, array, len);\n}\n\nstatic inline int of_get_u32_array(struct device_node *node,\n\t\tchar *attr, uint32_t *array, int len)\n{\n\tif (!node || !attr || !array)\n\t\treturn -EINVAL;\n\n\treturn __of_get_u32_array(node->data, node->offset,\n\t\t\tattr, array, len);\n}\n\nstatic inline int of_get_u16_array(struct device_node *node,\n\t\tchar *attr, uint16_t *array, int len)\n{\n\tif (!node || !attr || !array)\n\t\treturn -EINVAL;\n\n\treturn __of_get_u16_array(node->data, node->offset,\n\t\t\tattr, array, len);\n}\n\nstatic inline int of_get_string(struct device_node *node,\n\t\tchar *attr, char *str, int len)\n{\n\tif (!node || !attr || !str)\n\t\treturn -EINVAL;\n\n\treturn __of_get_string(node->data, node->offset,\n\t\t\tattr, str, len);\n}\n\nstatic int inline device_node_is_root(struct device_node *node)\n{\n\treturn (node->parent == NULL);\n}\n\nstatic int inline translate_device_address_index(struct device_node *node,\n\t\tuint64_t *base, uint64_t *size, int index)\n{\n\tif (node->flags & DEVICE_NODE_F_OF)\n\t\treturn of_translate_address_index(node, base, size, index);\n\n\treturn -EINVAL;\n}\n\nstatic inline int translate_device_address(struct device_node *node,\n\t\tuint64_t *base, uint64_t *size)\n{\n\treturn translate_device_address_index(node, base, size, 0);\n}\n\nint of_get_device_irq_index(struct device_node *node, uint32_t *irq,\n\t\tunsigned long *flags, int index);\n\nint of_init(void *base);\n\n#endif\n"
  },
  {
    "path": "user.sbin/fuxi/Makefile",
    "content": "TARGET \t\t:= fuxi.srv\n\nSRC_C\t\t:= fuxi.c\n\nAPP_LINK_LIBS\t= misc\n\nAPP_INSTALL_DIR = ramdisk\n\nTEXT_START := 0x800000\n\ninclude $(projtree)/scripts/app_build.mk\n"
  },
  {
    "path": "user.sbin/fuxi/fuxi.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdlib.h>\n#include <stdint.h>\n#include <sys/types.h>\n#include <sys/dir.h>\n#include <sys/epoll.h>\n#include <errno.h>\n#include <string.h>\n#include <limits.h>\n\n#include <minos/list.h>\n#include <minos/proto.h>\n#include <minos/kobject.h>\n#include <minos/debug.h>\n#include <minos/types.h>\n#include <minos/service.h>\n#include <misc.h>\n\n#define VNODENAME_MAX 64\n#define VNODE_MAX 128\n#define VREQ_MAX 256\n#define MAX_EVENTS 10\n\nstruct vnode {\n\tint type;\n\tint open_cnt;\n\tint handle;\t\t\t// for service node.\n\tint d_ino;\n\tchar name[VNODENAME_MAX];\n\tstruct list_head child;\n\tstruct list_head list;\n};\n\nstruct vreq {\n\tint handle;\t\t\t// for ipc between two process.\n\tint right;\n\tstruct vnode *node;\n\tstruct vreq *next;\n\tstruct list_head *pdata;\n\tvoid *buf;\n};\n\nstatic struct vnode vnodes[VNODE_MAX];\nstatic LIST_HEAD(node_list);\n\nstatic struct vreq vreqs[VREQ_MAX];\nstatic struct vreq *vreq_head = NULL;\n\nstatic struct vnode root_vnode;\nstatic int epfd;\n\nstatic char string_buffer[PATH_MAX];\nstatic char filename[PATH_MAX];\n\nstatic void fuxi_info(char *str)\n{\n\tkobject_write(2, str, strlen(str), NULL, 0, 0);\n}\n\nstatic struct vreq *alloc_vreq(void)\n{\n\tstruct vreq *vreq;\n\n\tif (vreq_head == NULL)\n\t\treturn NULL;\n\n\tvreq = vreq_head;\n\tvreq_head = vreq->next;\n\tvreq->next = NULL;\n\n\treturn vreq;\n}\n\nstatic void release_vreq(struct vreq *vreq)\n{\n\tvreq->next = vreq_head;\n\tvreq_head = vreq;\n}\n\nstatic void vreqs_init(void)\n{\n\tstruct vreq *vreq;\n\tint i;\n\n\tfor (i = 0; i < VREQ_MAX; i++) {\n\t\tvreq = &vreqs[i];\n\t\tvreq->next = vreq_head;\n\t\tvreq_head = vreq;\n\t}\n}\n\nstatic int epoll_new_vreq(struct vreq *vreq)\n{\n\tstruct epoll_event event;\n\n\tevent.events = EPOLLIN;\n\tevent.data.ptr = vreq;\n\n\treturn epoll_ctl(epfd, EPOLL_CTL_ADD, vreq->handle, &event);\n}\n\nstatic struct vnode *alloc_node(void)\n{\n\tstruct vnode *node;\n\n\tif (is_list_empty(&node_list))\n\t\treturn NULL;\n\n\tnode = list_first_entry(&node_list, struct vnode, list);\n\tlist_del(&node->list);\n\n\treturn node;\n}\n\nstatic void release_node(struct vnode *node)\n{\n\tlist_del(&node->list);\n\tlist_add(&node_list, &node->list);\n}\n\nstatic int handle_close_event(struct epoll_event *event)\n{\n\tstruct vreq *vreq = (struct vreq *)event->data.ptr;\n\tstruct vnode *node = vreq->node;\n\n\tif (node->handle)\n\t\tkobject_close(node->handle);\n\n\trelease_node(node);\n\trelease_vreq(vreq);\n\n\treturn 0;\n}\n\nstatic struct vreq *create_new_vreq(struct vnode *node)\n{\n\tstruct vreq *vreq;\n\tint ret;\n\n\tvreq = alloc_vreq();\n\tif (!vreq)\n\t\treturn NULL;\n\n\t/*\n\t * create a normal endpoint which allow two process\n\t * to IPC with each other.\n\t */\n\tvreq->handle = kobject_create_endpoint(PAGE_SIZE);\n\tif (vreq->handle <= 0)\n\t\tgoto err_create_endpoint;\n\n\tif (kobject_mmap(vreq->handle, &vreq->buf, NULL))\n\t\tgoto err_open_endpoint;\n\n\tret = epoll_new_vreq(vreq);\n\tif (ret)\n\t\tgoto err_open_endpoint;\n\n\t/*\n\t * pointed to the first member in the node.\n\t */\n\tvreq->node = node;\n\tvreq->pdata = node->child.next;\n\n\treturn vreq;\n\nerr_open_endpoint:\n\tkobject_close(vreq->handle);\nerr_create_endpoint:\n\trelease_vreq(vreq);\n\treturn NULL;\n}\n\nstatic int open_remote_node(struct vnode *node,\n\t\t\tstruct proto *proto, char *name)\n{\n\treturn kobject_write(node->handle, proto,\n\t\t\tsizeof(struct proto), name, strlen(name), 5000);\n}\n\nstatic struct vnode *find_node(struct vnode *parent, char *name)\n{\n\tstruct vnode *node;\n\n\tlist_for_each_entry(node, &parent->child, list) {\n\t\tif (strcmp(name, node->name) == 0)\n\t\t\treturn node;\n\t}\n\n\treturn NULL;\n}\n\nstatic int check_string(char *buf, int offset, int size)\n{\n\twhile (offset < size) {\n\t\tif (buf[offset] == '\\0')\n\t\t\treturn 1;\n\t\toffset++;\n\t}\n\n\treturn 0;\n}\n\nstatic struct vnode *find_dir_node(struct vnode *root, char *buf)\n{\n\tstruct vnode *cur = root;\n\tchar *pathrem = buf, *end;\n\n\tfor (;;) {\n\t\twhile (*pathrem == '/')\n\t\t\tpathrem++;\n\n\t\tif (cur->type != SRV_DIR)\n\t\t\tbreak;\n\n\t\t/*\n\t\t * open a directory of the SNS, SNS only provide two file type\n\t\t * one is directory, other is service.\n\t\t */\n\t\tif (*pathrem == '\\0')\n\t\t\treturn cur;\n\n\t\tend = strchrnul(pathrem, '/');\n\t\tif (end - pathrem >= PATH_MAX)\n\t\t\tbreak;\n\n\t\tstrlcpy(filename, pathrem, end - pathrem + 1);\n\t\tpathrem = end;\n\n\t\tcur = find_node(cur, filename);\n\t\tif (!cur)\n\t\t\tbreak;\n\t}\n\n\treturn NULL;\n}\n\nstatic int create_service_kobject(struct vnode *node, struct proto *proto)\n{\n\tint handle;\n\n\tswitch (proto->register_service.type) {\n\tcase SRV_PORT:\n\t\thandle = kobject_create_port();\n\t\tbreak;\n\tcase SRV_NOTIFY:\n\t\thandle = kobject_create_notify();\n\t\tbreak;\n\tdefault:\n\t\thandle = -1;\n\t\tbreak;\n\t}\n\n\tif (handle <= 0)\n\t\treturn handle;\n\n\tnode->handle = handle;\n\tnode->open_cnt = 0;\n\n\treturn 0;\n}\n\nstatic struct vnode *__handle_register_service_request(struct vreq *vreq,\n\t\tstruct proto *proto, char *buf)\n{\n\tchar *source = buf + proto->register_service.source_off;\n\tchar *target = buf + proto->register_service.target_off;\n\tstruct vnode *parent = vreq->node;\n\tstruct vnode *node;\n\n\tif (parent->d_ino != -1)\n\t\treturn NULL;\n\n\tif (!check_string(buf, proto->register_service.source_off, PATH_MAX))\n\t\treturn NULL;\n\n\tif (!check_string(buf, proto->register_service.target_off, PATH_MAX))\n\t\treturn NULL;\n\n\tif (strlen(target) >= VNODENAME_MAX)\n\t\treturn NULL;\n\n\tparent = find_dir_node(parent, source);\n\tif (!parent)\n\t\treturn NULL;\n\n\tnode = alloc_node();\n\tif (!node)\n\t\treturn NULL;\n\n\tstrcpy(node->name, target);\n\tnode->type = proto->register_service.type;\n\n\tif (node->type == SRV_DIR) {\n\t\tnode->handle = -1;\n\t\tinit_list(&node->child);\n\t\tlist_add_tail(&parent->child, &node->list);\n\t} else {\n\t\tif (create_service_kobject(node, proto)) {\n\t\t\trelease_node(node);\n\t\t\tnode = NULL;\n\t\t} else {\n\t\t\tlist_add_tail(&parent->child, &node->list);\n\t\t}\n\t}\n\n\treturn node;\n}\n\nstatic void handle_register_service_request(struct vreq *vreq, struct proto *proto, char *buf)\n{\n\tstruct vnode *node;\n\n\tnode = __handle_register_service_request(vreq, proto, buf);\n\tif (!node) {\n\t\tkobject_reply_errcode(vreq->handle, proto->token, -EINVAL);\n\t\treturn;\n\t}\n\n\tswitch (node->type) {\n\tcase SRV_PORT:\n\t\tkobject_reply_handle(vreq->handle, proto->token, node->handle, KR_R);\n\t\tbreak;\n\tcase SRV_NOTIFY:\n\t\tkobject_reply_handle(vreq->handle, proto->token, node->handle, KR_W);\n\t\tbreak;\n\tdefault:\n\t\tkobject_reply_errcode(vreq->handle, proto->token, -EINVAL);\n\t\tbreak;\n\t}\n}\n\nstatic int __handle_open_request(struct vreq *vreq, struct proto *proto, char *buf, int *type)\n{\n\tstruct vnode *cur = vreq->node, *next;\n\tstruct vreq *new_vreq;\n\tchar *pathrem = buf, *end;\n\tint handle = -EINVAL;\n\n\tfor (;;) {\n\t\twhile (*pathrem == '/')\n\t\t\tpathrem++;\n\n\t\t/*\n\t\t * open a directory of the SNS, SNS only provide two file type\n\t\t * one is directory, other is service.\n\t\t */\n\t\tif (*pathrem == '\\0') {\n\t\t\tif (cur->type == SRV_NOTIFY) {\n\t\t\t\tif (!(proto->open.flags & O_DIRECTORY)) {\n\t\t\t\t\t*type = SRV_NOTIFY;\n\t\t\t\t\treturn cur->handle;\n\t\t\t\t} else {\n\t\t\t\t\treturn -ENOENT;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!(proto->open.flags & O_DIRECTORY) && (cur->type != SRV_DIR))\n\t\t\t\treturn -ENOENT;\n\n\t\t\t/*\n\t\t\t * open a directly, create a new endpoint for the request.\n\t\t\t */\n\t\t\tnew_vreq = create_new_vreq(cur);\n\t\t\tif (new_vreq != NULL) {\n\t\t\t\t*type = SRV_DIR;\n\t\t\t\thandle = new_vreq->handle;\n\t\t\t}\n\n\t\t\treturn handle;\n\t\t}\n\n\t\tif (cur->type != SRV_DIR)\n\t\t\treturn -ENOENT;\n\n\t\tend = strchrnul(pathrem, '/');\n\t\tif (end - pathrem >= PATH_MAX)\n\t\t\treturn -ENAMETOOLONG;\n\n\t\tstrlcpy(filename, pathrem, end - pathrem + 1);\n\t\tpathrem = end;\n\n\t\tnext = find_node(cur, filename);\n\t\tif (!next)\n\t\t\treturn -ENOENT;\n\n\t\t/*\n\t\t * if this node is a service node, open it with remote call.\n\t\t */\n\t\tif ((next->type == SRV_PORT)) {\n\t\t\t*type = SRV_REMOTE;\n\t\t\treturn open_remote_node(next, proto, pathrem);\n\t\t}\n\t}\n\n\treturn -ENOENT;\n}\n\nstatic void handle_open_request(struct vreq *vreq, struct proto *proto, char *buf)\n{\n\tint type = 0;\n\tint handle;\n\tint right;\n\n\thandle = __handle_open_request(vreq, proto, buf, &type);\n\tif (handle <= 0) {\n\t\tright = 0;\n\t\tfuxi_info(\"open file failed\\n\");\n\t} else {\n\t\tif (type == SRV_DIR)\n\t\t\tright = KR_WM;\n\t\telse if (type == SRV_PORT)\n\t\t\tright = KR_W;\n\t\telse if (type == SRV_NOTIFY)\n\t\t\tright = KR_R;\n\t\telse\n\t\t\tright = 0;\n\t}\n\n\t/*\n\t * close the handle if this handle is a remote handle. the\n\t * rights has been passed to the target process.\n\t */\n\tkobject_reply_handle(vreq->handle, proto->token, handle, right);\n\tif (handle > 0 && type == SRV_REMOTE)\n\t\tkobject_close(handle);\n}\n\nstatic void handle_getdent_request(struct vreq *vreq, struct proto *proto, char *buf)\n{\n\tstruct vnode *node = vreq->node;\n\tunsigned char *tmp = vreq->buf;\n\tstruct dirent *de;\n\tint ret = 0, len;\n\tstruct vnode *next;\n\tint size_left = PAGE_SIZE;\n\n\tif (node->type != SRV_DIR) {\n\t\tret = -EBADF;\n\t\tgoto out;\n\t}\n\n\tif (vreq->pdata == NULL) {\n\t\tret = -EPERM;\n\t\tgoto out;\n\t}\n\n\tfor (;;) {\n\t\tif (vreq->pdata == &vreq->node->child)\n\t\t\tbreak;\n\n\t\tnext = list_entry(vreq->pdata, struct vnode, list);\n\t\tif (next == NULL)\n\t\t\tbreak;\n\n\t\tlen = DIRENT_SIZE(strlen(next->name) + 1);\n\t\tif (size_left < len)\n\t\t\tbreak;\n\n\t\tde = (struct dirent *)tmp;\n\t\tde->d_ino = node->d_ino;\n\t\tde->d_off = node->d_ino;\n\t\tde->d_reclen = len;\n\t\tde->d_type = DT_SRV;\n\t\tstrcpy(de->d_name, next->name);\n\n\t\ttmp += len;\n\t\tsize_left -= len;\n\t\tvreq->pdata = vreq->pdata->next;\n\t}\n\n\tret = PAGE_SIZE - size_left;\nout:\n\tkobject_reply(vreq->handle, proto->token, ret, 0, 0);\n}\n\nstatic int handle_remote_access(struct vnode *node, struct proto *proto, char *buf)\n{\n\tstruct proto rproto;\n\n\trproto.proto_id = PROTO_ACCESS;\n\trproto.access.amode = proto->access.amode;\n\n\treturn sys_send_proto_with_data(node->handle,\n\t\t\t&rproto, buf, strlen(buf), 2000);\n}\n\nstatic int __handle_access_request(struct vreq *vreq, struct proto *proto, char *buf)\n{\n\tstruct vnode *cur = vreq->node, *next;\n\tint amode = proto->access.amode;\n\tchar *pathrem = buf, *end;\n\n\tfor (;;) {\n\t\twhile (*pathrem == '/')\n\t\t\tpathrem++;\n\n\t\t/*\n\t\t * open a directory of the fuxi, fuxi only provide two file type\n\t\t * one is directory, other is service.\n\t\t */\n\t\tif (*pathrem == '\\0') {\n\t\t\tif (cur->type == SRV_NOTIFY)\n\t\t\t\treturn ((amode & R_OK) == amode);\n\t\t\telse if (cur->type == SRV_PORT)\n\t\t\t\treturn ((amode & W_OK) == amode);\n\t\t\telse\n\t\t\t\treturn -EPERM;\n\t\t}\n\n\t\tif (cur->type != SRV_DIR)\n\t\t\treturn -ENOENT;\n\n\t\tend = strchrnul(pathrem, '/');\n\t\tif (end - pathrem >= PATH_MAX)\n\t\t\treturn -ENAMETOOLONG;\n\n\t\tstrlcpy(filename, pathrem, end - pathrem + 1);\n\t\tpathrem = end;\n\n\t\tnext = find_node(cur, filename);\n\t\tif (!next)\n\t\t\treturn -ENOENT;\n\n\t\t/*\n\t\t * if this node is a service node, open it with remote call.\n\t\t */\n\t\tif ((next->type == SRV_PORT))\n\t\t\treturn handle_remote_access(next, proto, pathrem);\n\t}\n\n\treturn -ENOENT;\n}\n\nstatic void handle_access_request(struct vreq *vreq,\n\t\tstruct proto *proto, char *path)\n{\n\tint ret = __handle_access_request(vreq, proto, path);\n\tkobject_reply_errcode(vreq->handle, proto->token, ret);\n}\n\nstatic void handle_lseek_request(struct vreq *vreq,\n\t\tstruct proto *proto, char *sbuf)\n{\n\tstruct vnode *node = vreq->node;\n\tint ret = -EPERM;\n\n\t/*\n\t * TBD\n\t */\n\tif (node->type == SRV_DIR) {\n\t\tvreq->pdata = node->child.next;\n\t\tret = 0;\n\t}\n\n\tkobject_reply_errcode(vreq->handle, proto->token, ret);\n}\n\nstatic int handle_event(struct epoll_event *event)\n{\n\tstruct vreq *vreq = (struct vreq *)event->data.ptr;\n\tstruct proto proto;\n\tint ret;\n\n\tret = sys_read_proto_with_string(vreq->handle, &proto,\n\t\t\tstring_buffer, PATH_MAX, 0);\n\tif (ret)\n\t\treturn ret;\n\n\tif ((vreq->buf == NULL) && (proto.proto_id == PROTO_GETDENTS)) {\n\t\tkobject_reply_errcode(vreq->handle, proto.token, -EPERM);\n\t\treturn -EPERM;\n\t}\n\n\tswitch (proto.proto_id) {\n\tcase PROTO_OPEN:\n\t\thandle_open_request(vreq, &proto, string_buffer);\n\t\tbreak;\n\tcase PROTO_ACCESS:\n\t\thandle_access_request(vreq, &proto, string_buffer);\n\t\tbreak;\n\tcase PROTO_GETDENTS:\n\t\thandle_getdent_request(vreq, &proto, string_buffer);\n\t\tbreak;\n\tcase PROTO_REGISTER_SERVICE:\n\t\thandle_register_service_request(vreq, &proto, string_buffer);\n\t\tbreak;\n\tcase PROTO_LSEEK:\n\t\thandle_lseek_request(vreq, &proto, string_buffer);\n\t\tbreak;\n\tcase PROTO_READ:\n\tcase PROTO_WRITE:\n\tcase PROTO_IOCTL:\n\tdefault:\n\t\tkobject_reply_errcode(vreq->handle, proto.token, -EPERM);\n\t\tbreak;\n\t};\n\n\treturn ret;\n}\n\nstatic int fuxi_loop(int handle)\n{\n\tstruct epoll_event events[MAX_EVENTS];\n\tstruct epoll_event *event = &events[0];\n\tstruct vreq *vreq;\n\tint ret, i;\n\n\tepfd = epoll_create(MAX_EVENTS);\n\tif (epfd <= 0)\n\t\texit(-ENOSPC);\n\n\tvreq = alloc_vreq();\n\tvreq->handle = handle;\n\tvreq->node = &root_vnode;\n\tvreq->pdata = NULL;\n\tvreq->buf = NULL;\n\n\tevent->data.ptr = vreq;\n\tevent->events = EPOLLIN;\n\tret = epoll_ctl(epfd, EPOLL_CTL_ADD, vreq->handle, event);\n\tif (ret)\n\t\texit(ret);\n\n\t/*\n\t * inform the root service, that we are ok.\n\t */\n\ti_am_ok();\n\n\tfuxi_info(\"fuxi: waitting request\\n\");\n\n\tfor (;;) {\n\t\tret = epoll_wait(epfd, events, MAX_EVENTS, -1);\n\t\tif (ret <= 0) {\n\t\t\tfuxi_info(\"vfs epoll failed\\n\");\n\t\t\tcontinue;\n\t\t}\n\n\t\t// fuxi_info(\"fuxi: receive service request\\n\");\n\n\t\tfor (i = 0; i < ret; i++) {\n\t\t\tswitch (events[i].events) {\n\t\t\tcase EPOLLIN:\n\t\t\t\thandle_event(&events[i]);\n\t\t\t\tbreak;\n\t\t\tcase EPOLLWCLOSE:\n\t\t\t\thandle_close_event(&events[i]);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn -1;\n}\n\nstatic void root_vnode_init(void)\n{\n\tstrcpy(root_vnode.name, \"/\");\n\troot_vnode.type = SRV_DIR;\n\troot_vnode.d_ino = -1;\n\tinit_list(&root_vnode.child);\n}\n\nstatic void vnodes_init(void)\n{\n\tint i;\n\n\tmemset(vnodes, 0, VNODE_MAX * sizeof(struct vnode));\n\tfor (i = 0; i < VNODE_MAX; i++) {\n\t\tvnodes[i].d_ino = i;\n\t\tlist_add_tail(&node_list, &vnodes[i].list);\n\t}\n\n\troot_vnode_init();\n}\n\n/*\n * 0 - root service\n * 1 - stdin\n * 2 - stdout\n * 3 - stderr\n */\nint main(int argc, char **argv)\n{\n\tint handle;\n\n\tfuxi_info(\"\\n\\nFuXi service start...\\n\\n\");\n\n\tif (get_handles(argc, argv, &handle, 1) != 1) {\n\t\tpr_err(\"get fuxi handle fail\\n\");\n\t\treturn -ENOENT;\n\t}\n\n\tpr_info(\"fuxi handle %d\\n\", handle);\n\n\tvnodes_init();\n\tvreqs_init();\n\n\texit(fuxi_loop(handle));\n}\n"
  },
  {
    "path": "user.sbin/nvwa/Makefile",
    "content": "TARGET := nvwa.srv\n\nAPP_LINK_LIBS\t= misc\n\nSRC_C := nvwa.c elf_std.c\nAPP_INSTALL_DIR := ramdisk\n\nTEXT_START := 0x4000000\n\ninclude $(projtree)/scripts/app_build.mk\n"
  },
  {
    "path": "user.sbin/nvwa/elf.h",
    "content": "#ifndef __PANGU_ELF_H__\n#define __PANGU_ELF_H__\n\n#include <minos/types.h>\n\ntypedef uint8_t     Elf_Byte;\n\ntypedef uint32_t    Elf32_Addr;    /* Unsigned program address */\ntypedef uint32_t    Elf32_Off;     /* Unsigned file offset */\ntypedef int32_t     Elf32_Sword;   /* Signed large integer */\ntypedef uint32_t    Elf32_Word;    /* Unsigned large integer */\ntypedef uint16_t    Elf32_Half;    /* Unsigned medium integer */\n\ntypedef uint64_t    Elf64_Addr;\ntypedef uint64_t    Elf64_Off;\ntypedef int32_t     Elf64_Shalf;\n\n#ifdef __alpha__\ntypedef int64_t     Elf64_Sword;\ntypedef uint64_t    Elf64_Word;\n#else\ntypedef int32_t     Elf64_Sword;\ntypedef uint32_t    Elf64_Word;\n#endif\n\ntypedef int64_t     Elf64_Sxword;\ntypedef uint64_t    Elf64_Xword;\n\ntypedef uint32_t    Elf64_Half;\ntypedef uint16_t    Elf64_Quarter;\n\n#if defined(__i386__)\n#define EM_THIS EM_386\n#define EL_ARCH_USES_REL\n#elif defined(__amd64__)\n#define EM_THIS EM_AMD64\n#define EL_ARCH_USES_RELA\n#elif defined(__arm__)\n#define EM_THIS EM_ARM\n#elif defined(__aarch64__)\n#define EM_THIS EM_AARCH64\n#define EL_ARCH_USES_RELA\n#define EL_ARCH_USES_REL\n#else\n#error specify your ELF architecture\n#endif\n\n#if defined(__LP64__) || defined(__LLP64__)\n#define ELFSIZE 64\n#else\n#define ELFSIZE 32\n#endif\n\n#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__\n#define ELFDATATHIS ELFDATA2LSB\n#else\n#define ELFDATATHIS ELFDATA2MSB\n#endif\n\n#define EI_MAG0        0        /* file ID */\n#define EI_MAG1        1        /* file ID */\n#define EI_MAG2        2        /* file ID */\n#define EI_MAG3        3        /* file ID */\n#define EI_CLASS       4        /* file class */\n#define EI_DATA        5        /* data encoding */\n#define EI_VERSION     6        /* ELF header version */\n#define EI_OSABI       7        /* OS/ABI ID */\n#define EI_ABIVERSION  8        /* ABI version */\n#define EI_PAD         9        /* start of pad bytes */\n#define EI_NIDENT     16        /* Size of e_ident[] */\n\n/* e_ident[] magic number */\n#define    ELFMAG0        0x7f       /* e_ident[EI_MAG0] */\n#define    ELFMAG1        'E'        /* e_ident[EI_MAG1] */\n#define    ELFMAG2        'L'        /* e_ident[EI_MAG2] */\n#define    ELFMAG3        'F'        /* e_ident[EI_MAG3] */\n#define    ELFMAG        \"\\177ELF\"   /* magic */\n#define    SELFMAG        4          /* size of magic */\n\n/* e_ident[] file class */\n#define    ELFCLASSNONE    0        /* invalid */\n#define    ELFCLASS32    1          /* 32-bit objs */\n#define    ELFCLASS64    2          /* 64-bit objs */\n#define    ELFCLASSNUM    3         /* number of classes */\n\n/* e_ident[] data encoding */\n#define ELFDATANONE    0            /* invalid */\n#define ELFDATA2LSB    1            /* Little-Endian */\n#define ELFDATA2MSB    2            /* Big-Endian */\n#define ELFDATANUM     3            /* number of data encode defines */\n\n/* e_ident[] Operating System/ABI */\n#define ELFOSABI_SYSV        0    /* UNIX System V ABI */\n#define ELFOSABI_HPUX        1    /* HP-UX operating system */\n#define ELFOSABI_NETBSD      2    /* NetBSD */\n#define ELFOSABI_LINUX       3    /* GNU/Linux */\n#define ELFOSABI_HURD        4    /* GNU/Hurd */\n#define ELFOSABI_86OPEN      5    /* 86Open common IA32 ABI */\n#define ELFOSABI_SOLARIS     6    /* Solaris */\n#define ELFOSABI_MONTEREY    7    /* Monterey */\n#define ELFOSABI_IRIX        8    /* IRIX */\n#define ELFOSABI_FREEBSD     9    /* FreeBSD */\n#define ELFOSABI_TRU64       10   /* TRU64 UNIX */\n#define ELFOSABI_MODESTO     11   /* Novell Modesto */\n#define ELFOSABI_OPENBSD     12   /* OpenBSD */\n#define ELFOSABI_ARM         97   /* ARM */\n#define ELFOSABI_STANDALONE  255  /* Standalone (embedded) application */\n\n/* e_ident */\n#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \\\n                      (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \\\n                      (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \\\n                      (ehdr).e_ident[EI_MAG3] == ELFMAG3)\n\n/* ELF Header */\ntypedef struct {\n    unsigned char    e_ident[EI_NIDENT];     /* ELF Identification */\n    Elf32_Half       e_type;                 /* object file type */\n    Elf32_Half       e_machine;              /* machine */\n    Elf32_Word       e_version;              /* object file version */\n    Elf32_Addr       e_entry;                /* virtual entry point */\n    Elf32_Off        e_phoff;                /* program header table offset */\n    Elf32_Off        e_shoff;                /* section header table offset */\n    Elf32_Word       e_flags;                /* processor-specific flags */\n    Elf32_Half       e_ehsize;               /* ELF header size */\n    Elf32_Half       e_phentsize;            /* program header entry size */\n    Elf32_Half       e_phnum;                /* number of program header entries */\n    Elf32_Half       e_shentsize;            /* section header entry size */\n    Elf32_Half       e_shnum;                /* number of section header entries */\n    Elf32_Half       e_shstrndx;             /* section header table's \"section\n                                                header string table\" entry offset */\n} Elf32_Ehdr;\n\ntypedef struct {\n    unsigned char    e_ident[EI_NIDENT];    /* Id bytes */\n    Elf64_Quarter    e_type;                /* file type */\n    Elf64_Quarter    e_machine;             /* machine type */\n    Elf64_Half       e_version;             /* version number */\n    Elf64_Addr       e_entry;               /* entry point */\n    Elf64_Off        e_phoff;               /* Program hdr offset */\n    Elf64_Off        e_shoff;               /* Section hdr offset */\n    Elf64_Half       e_flags;               /* Processor flags */\n    Elf64_Quarter    e_ehsize;              /* sizeof ehdr */\n    Elf64_Quarter    e_phentsize;           /* Program header entry size */\n    Elf64_Quarter    e_phnum;               /* Number of program headers */\n    Elf64_Quarter    e_shentsize;           /* Section header entry size */\n    Elf64_Quarter    e_shnum;               /* Number of section headers */\n    Elf64_Quarter    e_shstrndx;            /* String table index */\n} Elf64_Ehdr;\n\n/* e_type */\n#define ET_NONE        0        /* No file type */\n#define ET_REL         1        /* relocatable file */\n#define ET_EXEC        2        /* executable file */\n#define ET_DYN         3        /* shared object file */\n#define ET_CORE        4        /* core file */\n#define ET_NUM         5        /* number of types */\n#define ET_LOPROC      0xff00   /* reserved range for processor */\n#define ET_HIPROC      0xffff   /*  specific e_type */\n\n/* e_machine */\n#define EM_NONE        0        /* No Machine */\n#define EM_M32         1        /* AT&T WE 32100 */\n#define EM_SPARC       2        /* SPARC */\n#define EM_386         3        /* Intel 80386 */\n#define EM_68K         4        /* Motorola 68000 */\n#define EM_88K         5        /* Motorola 88000 */\n#define EM_486         6        /* Intel 80486 - unused? */\n#define EM_860         7        /* Intel 80860 */\n#define EM_MIPS        8        /* MIPS R3000 Big-Endian only */\n/*\n * Don't know if EM_MIPS_RS4_BE,\n * EM_SPARC64, EM_PARISC,\n * or EM_PPC are ABI compliant\n */\n#define EM_MIPS_RS4_BE 10        /* MIPS R4000 Big-Endian */\n#define EM_SPARC64     11        /* SPARC v9 64-bit unofficial */\n#define EM_PARISC      15        /* HPPA */\n#define EM_SPARC32PLUS 18        /* Enhanced instruction set SPARC */\n#define EM_PPC         20        /* PowerPC */\n#define EM_ARM         40        /* ARM AArch32 */\n#define EM_ALPHA       41        /* DEC ALPHA */\n#define EM_SH          42        /* Hitachi/Renesas Super-H */\n#define EM_SPARCV9     43        /* SPARC version 9 */\n#define EM_IA_64       50        /* Intel IA-64 Processor */\n#define EM_AMD64       62        /* AMD64 architecture */\n#define EM_VAX         75        /* DEC VAX */\n#define EM_AARCH64     183       /* ARM AArch64 */\n\n/* Non-standard */\n#define EM_ALPHA_EXP   0x9026        /* DEC ALPHA */\n\n\n/* Version */\n#define EV_NONE        0        /* Invalid */\n#define EV_CURRENT     1        /* Current */\n#define EV_NUM         2        /* number of versions */\n\n/* Section Header */\ntypedef struct {\n    Elf32_Word    sh_name;      /* name - index into section header\n                                 * string table section */\n    Elf32_Word    sh_type;      /* type */\n    Elf32_Word    sh_flags;     /* flags */\n    Elf32_Addr    sh_addr;      /* address */\n    Elf32_Off     sh_offset;    /* file offset */\n    Elf32_Word    sh_size;      /* section size */\n    Elf32_Word    sh_link;      /* section header table index link */\n    Elf32_Word    sh_info;      /* extra information */\n    Elf32_Word    sh_addralign; /* address alignment */\n    Elf32_Word    sh_entsize;   /* section entry size */\n} Elf32_Shdr;\n\ntypedef struct {\n    Elf64_Half    sh_name;       /* section name */\n    Elf64_Half    sh_type;       /* section type */\n    Elf64_Xword   sh_flags;      /* section flags */\n    Elf64_Addr    sh_addr;       /* virtual address */\n    Elf64_Off     sh_offset;     /* file offset */\n    Elf64_Xword   sh_size;       /* section size */\n    Elf64_Half    sh_link;       /* link to another */\n    Elf64_Half    sh_info;       /* misc info */\n    Elf64_Xword   sh_addralign;  /* memory alignment */\n    Elf64_Xword   sh_entsize;    /* table entry size */\n} Elf64_Shdr;\n\n/* Special Section Indexes */\n#define SHN_UNDEF     0             /* undefined */\n#define SHN_LORESERVE 0xff00        /* lower bounds of reserved indexes */\n#define SHN_LOPROC    0xff00        /* reserved range for processor */\n#define SHN_HIPROC    0xff1f        /*   specific section indexes */\n#define SHN_ABS       0xfff1        /* absolute value */\n#define SHN_COMMON    0xfff2        /* common symbol */\n#define SHN_HIRESERVE 0xffff        /* upper bounds of reserved indexes */\n\n/* sh_type */\n#define SHT_NULL     0        /* inactive */\n#define SHT_PROGBITS 1        /* program defined information */\n#define SHT_SYMTAB   2        /* symbol table section */\n#define SHT_STRTAB   3        /* string table section */\n#define SHT_RELA     4        /* relocation section with addends*/\n#define SHT_HASH     5        /* symbol hash table section */\n#define SHT_DYNAMIC  6        /* dynamic section */\n#define SHT_NOTE     7        /* note section */\n#define SHT_NOBITS   8        /* no space section */\n#define SHT_REL      9        /* relation section without addends */\n#define SHT_SHLIB    10       /* reserved - purpose unknown */\n#define SHT_DYNSYM   11       /* dynamic symbol table section */\n#define SHT_NUM      12       /* number of section types */\n#define SHT_LOPROC   0x70000000    /* reserved range for processor */\n#define SHT_HIPROC   0x7fffffff    /*  specific section header types */\n#define SHT_LOUSER   0x80000000    /* reserved range for application */\n#define SHT_HIUSER   0xffffffff    /*  specific indexes */\n\n/* Section names */\n#define ELF_BSS         \".bss\"        /* uninitialized data */\n#define ELF_DATA        \".data\"       /* initialized data */\n#define ELF_DEBUG       \".debug\"      /* debug */\n#define ELF_DYNAMIC     \".dynamic\"    /* dynamic linking information */\n#define ELF_DYNSTR      \".dynstr\"     /* dynamic string table */\n#define ELF_DYNSYM      \".dynsym\"     /* dynamic symbol table */\n#define ELF_FINI        \".fini\"       /* termination code */\n#define ELF_GOT         \".got\"        /* global offset table */\n#define ELF_HASH        \".hash\"       /* symbol hash table */\n#define ELF_INIT        \".init\"       /* initialization code */\n#define ELF_REL_DATA    \".rel.data\"   /* relocation data */\n#define ELF_REL_FINI    \".rel.fini\"   /* relocation termination code */\n#define ELF_REL_INIT    \".rel.init\"   /* relocation initialization code */\n#define ELF_REL_DYN     \".rel.dyn\"    /* relocation dynamic link info */\n#define ELF_REL_RODATA  \".rel.rodata\" /* relocation read-only data */\n#define ELF_REL_TEXT    \".rel.text\"   /* relocation code */\n#define ELF_RODATA      \".rodata\"     /* read-only data */\n#define ELF_SHSTRTAB    \".shstrtab\"   /* section header string table */\n#define ELF_STRTAB      \".strtab\"     /* string table */\n#define ELF_SYMTAB      \".symtab\"     /* symbol table */\n#define ELF_TEXT        \".text\"       /* code */\n\n\n/* Section Attribute Flags - sh_flags */\n#define SHF_WRITE        0x1           /* Writable */\n#define SHF_ALLOC        0x2           /* occupies memory */\n#define SHF_EXECINSTR    0x4           /* executable */\n#define SHF_TLS          0x400         /* thread local storage */\n#define SHF_MASKPROC     0xf0000000    /* reserved bits for processor\n                                        *  specific section attributes */\n\n/* Symbol Table Entry */\ntypedef struct elf32_sym {\n    Elf32_Word    st_name;     /* name - index into string table */\n    Elf32_Addr    st_value;    /* symbol value */\n    Elf32_Word    st_size;     /* symbol size */\n    unsigned char st_info;     /* type and binding */\n    unsigned char st_other;    /* 0 - no defined meaning */\n    Elf32_Half    st_shndx;    /* section header index */\n} Elf32_Sym;\n\ntypedef struct {\n    Elf64_Half    st_name;    /* Symbol name index in str table */\n    Elf_Byte      st_info;    /* type / binding attrs */\n    Elf_Byte      st_other;   /* unused */\n    Elf64_Quarter st_shndx;   /* section index of symbol */\n    Elf64_Xword   st_value;   /* value of symbol */\n    Elf64_Xword   st_size;    /* size of symbol */\n} Elf64_Sym;\n\n/* Symbol table index */\n#define STN_UNDEF    0        /* undefined */\n\n/* Extract symbol info - st_info */\n#define ELF32_ST_BIND(x)    ((x) >> 4)\n#define ELF32_ST_TYPE(x)    (((unsigned int) x) & 0xf)\n#define ELF32_ST_INFO(b,t)  (((b) << 4) + ((t) & 0xf))\n\n#define ELF64_ST_BIND(x)    ((x) >> 4)\n#define ELF64_ST_TYPE(x)    (((unsigned int) x) & 0xf)\n#define ELF64_ST_INFO(b,t)  (((b) << 4) + ((t) & 0xf))\n\n/* Symbol Binding - ELF32_ST_BIND - st_info */\n#define STB_LOCAL    0        /* Local symbol */\n#define STB_GLOBAL   1        /* Global symbol */\n#define STB_WEAK     2        /* like global - lower precedence */\n#define STB_NUM      3        /* number of symbol bindings */\n#define STB_LOPROC  13        /* reserved range for processor */\n#define STB_HIPROC  15        /*  specific symbol bindings */\n\n/* Symbol type - ELF32_ST_TYPE - st_info */\n#define STT_NOTYPE    0        /* not specified */\n#define STT_OBJECT    1        /* data object */\n#define STT_FUNC      2        /* function */\n#define STT_SECTION   3        /* section */\n#define STT_FILE      4        /* file */\n#define STT_TLS       6        /* thread local storage */\n#define STT_LOPROC    13       /* reserved range for processor */\n#define STT_HIPROC    15       /*  specific symbol types */\n\n/* Relocation entry with implicit addend */\ntypedef struct {\n    Elf32_Addr    r_offset;    /* offset of relocation */\n    Elf32_Word    r_info;      /* symbol table index and type */\n} Elf32_Rel;\n\n/* Relocation entry with explicit addend */\ntypedef struct {\n    Elf32_Addr    r_offset;    /* offset of relocation */\n    Elf32_Word    r_info;      /* symbol table index and type */\n    Elf32_Sword   r_addend;\n} Elf32_Rela;\n\n/* Extract relocation info - r_info */\n#define ELF32_R_SYM(i)         ((i) >> 8)\n#define ELF32_R_TYPE(i)        ((unsigned char) (i))\n#define ELF32_R_INFO(s,t)      (((s) << 8) + (unsigned char)(t))\n\ntypedef struct {\n    Elf64_Xword    r_offset;    /* where to do it */\n    Elf64_Xword    r_info;      /* index & type of relocation */\n} Elf64_Rel;\n\ntypedef struct {\n    Elf64_Xword    r_offset;    /* where to do it */\n    Elf64_Xword    r_info;      /* index & type of relocation */\n    Elf64_Sxword    r_addend;   /* adjustment value */\n} Elf64_Rela;\n\n#define    ELF64_R_SYM(info)    ((info) >> 32)\n#define    ELF64_R_TYPE(info)   ((info) & 0xFFFFFFFF)\n#define    ELF64_R_INFO(s,t)    (((s) << 32) + (__uint32_t)(t))\n\n#if defined(__mips64__) && defined(__MIPSEL__)\n/*\n * The 64-bit MIPS ELF ABI uses a slightly different relocation format\n * than the regular ELF ABI: the r_info field is split into several\n * pieces (see gnu/usr.bin/binutils/include/elf/mips.h for details).\n */\n#undef    ELF64_R_SYM\n#undef    ELF64_R_TYPE\n#undef    ELF64_R_INFO\n#define   ELF64_R_TYPE(info)   (swap32((info) >> 32))\n#define   ELF64_R_SYM(info)    ((info) & 0xFFFFFFFF)\n#define   ELF64_R_INFO(s,t)    (((__uint64_t)swap32(t) << 32) + (__uint32_t)(s))\n#endif /* __mips64__ && __MIPSEL__ */\n\n/* Program Header */\ntypedef struct {\n    Elf32_Word    p_type;     /* segment type */\n    Elf32_Off     p_offset;   /* segment offset */\n    Elf32_Addr    p_vaddr;    /* virtual address of segment */\n    Elf32_Addr    p_paddr;    /* physical address - ignored? */\n    Elf32_Word    p_filesz;   /* number of bytes in file for seg. */\n    Elf32_Word    p_memsz;    /* number of bytes in mem. for seg. */\n    Elf32_Word    p_flags;    /* flags */\n    Elf32_Word    p_align;    /* memory alignment */\n} Elf32_Phdr;\n\ntypedef struct {\n    Elf64_Half    p_type;     /* entry type */\n    Elf64_Half    p_flags;    /* flags */\n    Elf64_Off     p_offset;   /* offset */\n    Elf64_Addr    p_vaddr;    /* virtual address */\n    Elf64_Addr    p_paddr;    /* physical address */\n    Elf64_Xword   p_filesz;   /* file size */\n    Elf64_Xword   p_memsz;    /* memory size */\n    Elf64_Xword   p_align;    /* memory & file alignment */\n} Elf64_Phdr;\n\n/* Segment types - p_type */\n#define PT_NULL        0          /* unused */\n#define PT_LOAD        1          /* loadable segment */\n#define PT_DYNAMIC     2          /* dynamic linking section */\n#define PT_INTERP      3          /* the RTLD */\n#define PT_NOTE        4          /* auxiliary information */\n#define PT_SHLIB       5          /* reserved - purpose undefined */\n#define PT_PHDR        6          /* program header */\n#define PT_TLS         7          /* thread local storage */\n#define PT_LOOS        0x60000000 /* reserved range for OS */\n#define PT_HIOS        0x6fffffff /*  specific segment types */\n#define PT_LOPROC      0x70000000 /* reserved range for processor */\n#define PT_HIPROC      0x7fffffff /*  specific segment types */\n\n#define PT_OPENBSD_RANDOMIZE 0x65a3dbe6 /* fill with random data */\n#define PT_GANDR_KERNEL      0x67646b6c /* gdkl */\n\n\n/* Segment flags - p_flags */\n#define PF_X        0x1        /* Executable */\n#define PF_W        0x2        /* Writable */\n#define PF_R        0x4        /* Readable */\n#define PF_MASKPROC 0xf0000000    /* reserved bits for processor */\n                    /*  specific segment flags */\n\n/* Dynamic structure */\ntypedef struct {\n    Elf32_Sword    d_tag;    /* controls meaning of d_val */\n    union {\n        Elf32_Word d_val;    /* Multiple meanings - see d_tag */\n        Elf32_Addr d_ptr;    /* program virtual address */\n    } d_un;\n} Elf32_Dyn;\n\ntypedef struct {\n    Elf64_Xword     d_tag;   /* controls meaning of d_val */\n    union {\n        Elf64_Addr  d_ptr;\n        Elf64_Xword d_val;\n    } d_un;\n} Elf64_Dyn;\n\n/* Dynamic Array Tags - d_tag */\n#define DT_NULL        0        /* marks end of _DYNAMIC array */\n#define DT_NEEDED      1        /* string table offset of needed lib */\n#define DT_PLTRELSZ    2        /* size of relocation entries in PLT */\n#define DT_PLTGOT      3        /* address PLT/GOT */\n#define DT_HASH        4        /* address of symbol hash table */\n#define DT_STRTAB      5        /* address of string table */\n#define DT_SYMTAB      6        /* address of symbol table */\n#define DT_RELA        7        /* address of relocation table */\n#define DT_RELASZ      8        /* size of relocation table */\n#define DT_RELAENT     9        /* size of relocation entry */\n#define DT_STRSZ      10        /* size of string table */\n#define DT_SYMENT     11        /* size of symbol table entry */\n#define DT_INIT       12        /* address of initialization func. */\n#define DT_FINI       13        /* address of termination function */\n#define DT_SONAME     14        /* string table offset of shared obj */\n#define DT_RPATH      15        /* string table offset of library\n                                 * search path */\n#define DT_SYMBOLIC   16        /* start sym search in shared obj. */\n#define DT_REL        17        /* address of rel. tbl. w addends */\n#define DT_RELSZ      18        /* size of DT_REL relocation table */\n#define DT_RELENT     19        /* size of DT_REL relocation entry */\n#define DT_PLTREL     20        /* PLT referenced relocation entry */\n#define DT_DEBUG      21        /* bugger */\n#define DT_TEXTREL    22        /* Allow rel. mod. to unwritable seg */\n#define DT_JMPREL     23        /* add. of PLT's relocation entries */\n#define DT_BIND_NOW   24        /* Bind now regardless of env setting */\n#define DT_LOOS       0x6000000d    /* reserved range for OS */\n#define DT_HIOS       0x6ffff000    /*  specific dynamic array tags */\n#define DT_LOPROC     0x70000000    /* reserved range for processor */\n#define DT_HIPROC     0x7fffffff    /*  specific dynamic array tags */\n\n/* some other useful tags */\n#define DT_RELACOUNT  0x6ffffff9    /* if present, number of RELATIVE */\n#define DT_RELCOUNT   0x6ffffffa    /* relocs, which must come first */\n#define DT_FLAGS_1    0x6ffffffb\n\n/* Dynamic Flags - DT_FLAGS_1 .dynamic entry */\n#define DF_1_NOW       0x00000001\n#define DF_1_GLOBAL    0x00000002\n#define DF_1_GROUP     0x00000004\n#define DF_1_NODELETE  0x00000008\n#define DF_1_LOADFLTR  0x00000010\n#define DF_1_INITFIRST 0x00000020\n#define DF_1_NOOPEN    0x00000040\n#define DF_1_ORIGIN    0x00000080\n#define DF_1_DIRECT    0x00000100\n#define DF_1_TRANS     0x00000200\n#define DF_1_INTERPOSE 0x00000400\n#define DF_1_NODEFLIB  0x00000800\n#define DF_1_NODUMP    0x00001000\n#define DF_1_CONLFAT   0x00002000\n\n/* ld.so: number of low tags that are used saved internally (0 .. DT_NUM-1) */\n#define DT_NUM        (DT_JMPREL+1)\n\n/*\n * Note Definitions\n */\ntypedef struct {\n    Elf32_Word namesz;\n    Elf32_Word descsz;\n    Elf32_Word type;\n} Elf32_Note;\n\ntypedef struct {\n    Elf64_Half namesz;\n    Elf64_Half descsz;\n    Elf64_Half type;\n} Elf64_Note;\n\ntypedef struct {\n\tuint64_t a_type;              /* Entry type */\n\tuint64_t a_val;\n} Elf64_auxv_t;\n\n#define ELFSIZE\t64\n\n#if defined(ELFSIZE) && (ELFSIZE == 32)\n#define Elf_Ehdr    Elf32_Ehdr\n#define Elf_Phdr    Elf32_Phdr\n#define Elf_Shdr    Elf32_Shdr\n#define Elf_Sym     Elf32_Sym\n#define Elf_Rel     Elf32_Rel\n#define Elf_RelA    Elf32_Rela\n#define Elf_Dyn     Elf32_Dyn\n#define Elf_Half    Elf32_Half\n#define Elf_Word    Elf32_Word\n#define Elf_Sword   Elf32_Sword\n#define Elf_Addr    Elf32_Addr\n#define Elf_Off     Elf32_Off\n#define Elf_Nhdr    Elf32_Nhdr\n#define Elf_Note    Elf32_Note\n\n#define ELF_R_SYM   ELF32_R_SYM\n#define ELF_R_TYPE  ELF32_R_TYPE\n#define ELF_R_INFO  ELF32_R_INFO\n#define ELFCLASS    ELFCLASS32\n\n#define ELF_ST_BIND ELF32_ST_BIND\n#define ELF_ST_TYPE ELF32_ST_TYPE\n#define ELF_ST_INFO ELF32_ST_INFO\n\n#elif defined(ELFSIZE) && (ELFSIZE == 64)\n\n#define Elf_Ehdr    Elf64_Ehdr\n#define Elf_Phdr    Elf64_Phdr\n#define Elf_Shdr    Elf64_Shdr\n#define Elf_Sym     Elf64_Sym\n#define Elf_Rel     Elf64_Rel\n#define Elf_RelA    Elf64_Rela\n#define Elf_Dyn     Elf64_Dyn\n#define Elf_Half    Elf64_Half\n#define Elf_Word    Elf64_Word\n#define Elf_Sword   Elf64_Sword\n#define Elf_Addr    Elf64_Addr\n#define Elf_Off     Elf64_Off\n#define Elf_Nhdr    Elf64_Nhdr\n#define Elf_Note    Elf64_Note\n\n#define ELF_R_SYM   ELF64_R_SYM\n#define ELF_R_TYPE  ELF64_R_TYPE\n#define ELF_R_INFO  ELF64_R_INFO\n#define ELFCLASS    ELFCLASS64\n\n#define ELF_ST_BIND ELF64_ST_BIND\n#define ELF_ST_TYPE ELF64_ST_TYPE\n#define ELF_ST_INFO ELF64_ST_INFO\n\n#endif\n\n/* Symbolic values for the entries in the auxiliary table\n   put on the initial stack */\n#define AT_NULL   0     /* end of vector */\n#define AT_IGNORE 1     /* entry should be ignored */\n#define AT_EXECFD 2     /* file descriptor of program */\n#define AT_PHDR   3     /* program headers for program */\n#define AT_PHENT  4     /* size of program header entry */\n#define AT_PHNUM  5     /* number of program headers */\n#define AT_PAGESZ 6     /* system page size */\n#define AT_BASE   7     /* base address of interpreter */\n#define AT_FLAGS  8     /* flags */\n#define AT_ENTRY  9     /* entry point of program */\n#define AT_NOTELF 10    /* program is not ELF */\n#define AT_UID    11    /* real uid */\n#define AT_EUID   12    /* effective uid */\n#define AT_GID    13    /* real gid */\n#define AT_EGID   14    /* effective gid */\n#define AT_PLATFORM 15  /* string identifying CPU for optimizations */\n#define AT_HWCAP  16    /* arch dependent hints at CPU capabilities */\n#define AT_CLKTCK 17    /* frequency at which times() increments */\n/* AT_* values 18 through 22 are reserved */\n#define AT_SECURE 23   /* secure mode boolean */\n#define AT_BASE_PLATFORM 24     /* string identifying real platform, may\n                                 * differ from AT_PLATFORM. */\n#define AT_RANDOM 25    /* address of 16 random bytes */\n#define AT_HWCAP2 26    /* extension of AT_HWCAP */\n\n#define AT_EXECFN  31   /* filename of program */\n\n/* dedicated for minos */\n#define AT_ROOTFS_HANDLE 61\n\nstruct elf_ctx {\n\tElf_Addr base_load_vbase;\n\tElf_Addr base_load_vend;\n\tElf_Addr memsz;\n\tElf_Addr align;\n\tElf_Ehdr ehdr;\n\tElf_Off  dynoff;\n\tElf_Addr dynsize;\n};\n\nenum {\n\tEL_OK         = 0,\n\tEL_EIO,\n    \tEL_ENOMEM,\n    \tEL_NOTELF,\n    \tEL_WRONGBITS,\n    \tEL_WRONGENDIAN,\n    \tEL_WRONGARCH,\n    \tEL_WRONGOS,\n    \tEL_NOTEXEC,\n    \tEL_NODYN,\n    \tEL_BADREL,\n};\n\n#define EL_PHOFF(ctx, num) (((ctx)->ehdr.e_phoff + (num) * (ctx)->ehdr.e_phentsize))\n#define EL_SHOFF(ctx, num) (((ctx)->ehdr.e_shoff + (num) * (ctx)->ehdr.e_shentsize))\n\n#endif\n"
  },
  {
    "path": "user.sbin/nvwa/elf_std.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <errno.h>\n#include <minos/types.h>\n#include <minos/debug.h>\n\n#include \"elf.h\"\n\nstatic int elf_file_read(FILE *file, void *buf, size_t size, off_t offset)\n{\n\tint ret;\n\n\tret = fseek(file, offset, SEEK_SET);\n\tif (ret < 0)\n\t\treturn ret;\n\n\tif (fread(buf, 1, size, file) != size) {\n\t\tpr_err(\"read elf file 0x%lx\\n fail\\n\", offset);\n\t\treturn -EIO;\n\t}\n\n\treturn 0;\n}\n\nstatic int elf_findphdr(FILE *file, struct elf_ctx *ctx,\n\t\tElf_Phdr *phdr, uint32_t type, unsigned *i)\n{\n\tint rv = EL_OK;\n\n\tfor (; *i < ctx->ehdr.e_phnum; (*i)++) {\n\t\trv = elf_file_read(file, phdr, sizeof(Elf_Phdr), EL_PHOFF(ctx, *i));\n\t\tif (rv)\n\t\t\treturn rv;\n\n\t\tif (phdr->p_type == type)\n\t\t\treturn rv;\n\t}\n\n\t*i = -1;\n\treturn rv;\n}\n\nint elf_init(struct elf_ctx *ctx, FILE *file)\n{\n\tElf_Phdr ph;\n\tint rv = EL_OK;\n\tunsigned i = 0;\n\n\tmemset(ctx, 0, sizeof(struct elf_ctx));\n\n\tif ((rv = elf_file_read(file, &ctx->ehdr, sizeof(ctx->ehdr), 0)))\n\t\treturn rv;\n\n\tif (!IS_ELF(ctx->ehdr))\n\t\treturn EL_NOTELF;\n\n\tif (ctx->ehdr.e_ident[EI_CLASS] != ELFCLASS)\n\t        return EL_WRONGBITS;\n\n\tif (ctx->ehdr.e_ident[EI_DATA] != ELFDATATHIS)\n\t        return EL_WRONGENDIAN;\n\n\tif (ctx->ehdr.e_ident[EI_VERSION] != EV_CURRENT)\n\t        return EL_NOTELF;\n\n\tif (ctx->ehdr.e_type != ET_EXEC || ctx->ehdr.e_type == ET_DYN)\n\t        return EL_NOTEXEC;\n\n\tif (ctx->ehdr.e_machine != EM_THIS)\n\t        return EL_WRONGARCH;\n\n\tif (ctx->ehdr.e_version != EV_CURRENT)\n\t        return EL_NOTELF;\n\n\t/*\n\t * calculate how many memory is needed for this elf file, the\n\t * memory will allocated together.\n\t */\n\tctx->base_load_vbase = (unsigned long)-1;\n\n\tfor(;;) {\n\t\tif ((rv = elf_findphdr(file, ctx, &ph, PT_LOAD, &i)))\n\t\t\treturn rv;\n\n\t        if (i == (unsigned) -1)\n\t\t\tbreak;\n\n\t\tif (ph.p_vaddr < ctx->base_load_vbase)\n\t\t\tctx->base_load_vbase = ph.p_vaddr;\n\n\t        Elf_Addr phend = ph.p_vaddr + ph.p_memsz;\n\t        if (phend > ctx->base_load_vend)\n\t\t\tctx->base_load_vend = phend;\n\n\t        if (ph.p_align > ctx->align)\n\t\t\tctx->align = ph.p_align;\n\t\ti++;\n\t}\n\n\tctx->memsz = PAGE_BALIGN(ctx->base_load_vend - ctx->base_load_vbase);\n\n\treturn rv;\n}\n\nstatic int elf_load_section(FILE *file, void *vaddr, Elf_Shdr *shdr)\n{\n\t/*\n\t * bss section ?\n\t */\n\tif (shdr->sh_type == SHT_NOBITS) {\n\t\tpr_debug(\"bzero elf section [0x%lx 0x%lx 0x%lx %d]\\n\",\n\t\t\tshdr->sh_offset, shdr->sh_addr, shdr->sh_size, shdr->sh_type);\n\t\tmemset(vaddr, 0, shdr->sh_size);\n\t\treturn 0;\n\t}\n\n\tpr_debug(\"loading elf section [0x%lx 0x%lx 0x%lx %d]\\n\",\n\t\t\tshdr->sh_offset, shdr->sh_addr, shdr->sh_size, shdr->sh_type);\n\telf_file_read(file, vaddr, shdr->sh_size, shdr->sh_offset);\n\n\treturn 0;\n}\n\nstatic int elf_findshdr(FILE *file, struct elf_ctx *ctx,\n\t\tElf_Shdr *shdr, unsigned int *i)\n{\n\n\tint rv = EL_OK;\n\tint j = *i;\n\n\tfor ( ;j < ctx->ehdr.e_shnum; j++) {\n\t\trv = elf_file_read(file, shdr, sizeof(Elf64_Ehdr), EL_SHOFF(ctx, j));\n\t\tif (rv)\n\t\t\treturn rv;\n\n\t\tif (shdr->sh_flags & SHF_ALLOC) {\n\t\t\t*i = j;\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t*i = -1;\n\treturn rv;\n}\n\nint load_process_from_file(void *page, struct elf_ctx *ctx, FILE *file)\n{\n\tint rv = EL_OK;\n\tunsigned int i = 0;\n\tvoid *vaddr;\n\tElf_Shdr shdr;\n\n\tfor(;;) {\n\t\tif ((rv = elf_findshdr(file, ctx, &shdr, &i)))\n\t\t\treturn rv;\n\n\t\tif (i == (unsigned int)-1)\n\t\t\tbreak;\n\n\t\tvaddr = page + (shdr.sh_addr - ctx->base_load_vbase);\n\t\trv = elf_load_section(file, vaddr, &shdr);\n\t\tif (rv)\n\t\t\treturn EL_ENOMEM;\n\t\ti++;\n\t}\n\n\treturn rv;\n}\n"
  },
  {
    "path": "user.sbin/nvwa/nvwa.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@163.com)\n */\n\n#include <stdio.h>\n#include <unistd.h>\n#include <inttypes.h>\n#include <stdlib.h>\n#include <string.h>\n#include <errno.h>\n#include <misc.h>\n#include <sys/mman.h>\n#include <sys/epoll.h>\n\n#include <minos/kobject.h>\n#include <minos/debug.h>\n#include <minos/proto.h>\n\n#include \"elf.h\"\n\nstatic int nvwa_handle;\n\nextern int elf_init(struct elf_ctx *ctx, FILE *file);\nextern int load_process_from_file(void *page, struct elf_ctx *ctx, FILE *file);\n\nstruct nvwa_proto {\n\tchar path[FILENAME_MAX];\n\tuint64_t token;\n\tint pma_handle;\n};\n\nstatic struct nvwa_proto nvwa_proto;\n\n#define MAPPING_BASE 0x100000000\n#define MAPPING_SIZE 0x40000000\n\nstatic int nvwa_pma_init(int pma_handle, size_t size)\n{\n\treturn kobject_ctl(pma_handle, KOBJ_PMA_ADD_PAGES, size >> PAGE_SHIFT);\n}\n\nstatic int unmap_elf_memory(int pma_handle, size_t size)\n{\n\treturn sys_unmap(-1, pma_handle, MAPPING_BASE, size);\n}\n\nstatic int map_elf_memory(int pma_handle, size_t size, int perm)\n{\n\treturn sys_map(-1, pma_handle, MAPPING_BASE, size, perm);\n}\n\nstatic int __handle_elf_request(struct nvwa_proto *proto,\n\t\tstruct proto *elf_proto)\n{\n\tint pma_handle = proto->pma_handle;\n\tstruct elf_ctx ctx;\n\tFILE *file = NULL;\n\tint ret;\n\n\tif (proto->path[FILENAME_MAX - 1] != 0) {\n\t\tret = -EINVAL;\n\t\tgoto out;\n\t}\n\n\tfile = fopen(proto->path, \"r\");\n\tif (!file)\n\t\treturn -EIO;\n\n\tret = elf_init(&ctx, file);\n\tif (ret)\n\t\tgoto out;\n\n\tif (ctx.memsz > MAPPING_SIZE) {\n\t\tret = -EINVAL;\n\t\tgoto out;\n\t}\n\n\tret = nvwa_pma_init(pma_handle, ctx.memsz);\n\tif (ret) {\n\t\tpr_err(\"init pma failed\\n\");\n\t\tgoto out;\n\t}\n\n\tret = map_elf_memory(pma_handle, ctx.memsz, KR_RW);\n\tif (ret)\n\t\tgoto out;\n\n\tret = load_process_from_file((void *)MAPPING_BASE, &ctx, file);\n\tunmap_elf_memory(pma_handle, ctx.memsz);\n\tif (ret)\n\t\tgoto out;\n\n\telf_proto->elf_info.token = proto->token;\n\telf_proto->elf_info.ret_code = 0;\n\telf_proto->elf_info.elf_base = ctx.base_load_vbase;\n\telf_proto->elf_info.elf_size = ctx.memsz;\n\telf_proto->elf_info.entry = ctx.ehdr.e_entry;\nout:\n\tfclose(file);\n\tkobject_close(pma_handle);\n\n\treturn ret;\n}\n\nstatic void handle_elf_request(struct nvwa_proto *proto)\n{\n\tstruct proto elf_proto;\n\tint ret;\n\n\t/*\n\t * after loading the content of the elf, nvwa will return\n\t * the elf information and the PMA handle to pangu.\n\t */\n\tret = __handle_elf_request(proto, &elf_proto);\n\tif (ret) {\n\t\tpr_info(\"loading elf file %d fail\\n\", ret);\n\t\tmemset(&elf_proto, 0, sizeof(struct proto));\n\t\telf_proto.elf_info.ret_code = ret;\n\t\telf_proto.elf_info.token = proto->token;\n\t}\n\n\telf_proto.proto_id = PROTO_ELF_INFO;\n\tkobject_write(0, &elf_proto, sizeof(struct proto), NULL, 0, -1);\n}\n\nstatic int nvwa_loop(void)\n{\n\tlong token;\n\n\ti_am_ok();\n\n\tpr_info(\"nvwa waitting elf load request\\n\");\n\n\tfor (; ;) {\n\t\ttoken = kobject_read_simple(nvwa_handle, &nvwa_proto,\n\t\t\t\tsizeof(struct nvwa_proto), -1);\n\t\tif (token < 0) {\n\t\t\tpr_err(\"read request from pangu failed\\n\");\n\t\t\tcontinue;\n\t\t}\n\n\t\tkobject_reply_errcode(nvwa_handle, token, 0);\n\t\thandle_elf_request(&nvwa_proto);\n\t}\n\n\treturn 0;\n}\n\nint main(int argc, char **argv)\n{\n\tint ret;\n\n\tprintf(\"\\n\\nNvWa service start...\\n\\n\");\n\n\tret = get_handles(argc, argv, &nvwa_handle, 1);\n\tif (ret != 1) {\n\t\tpr_err(\"can not get nvwa handle\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\tret = nvwa_loop();\n\tif (ret)\n\t\tpr_err(\"nvwa exit with code %d\\n\", ret);\n\n\treturn ret;\n}\n"
  },
  {
    "path": "user.sbin/pangu/.gitignore",
    "content": "tags\ncscope.in.out\ncscope.out\ncscope.po.out\nlinkmap.txt\npangu.srv\n.*\n*.o\n*.o.*\n*.a\n*.s\n*.ko\n*.so\n*.d\n*.so.dbg\n*.mod.c\n*.i\n*.lst\n*.symtypes\n*.order\n*.elf\n*.bin\n*.tar\n*.gz\n*.bz2\n*.lzma\n*.xz\n*.lz4\n*.lzo\n*.patch\n*.gcno\nmodules.builtin\nModule.symvers\n*.dwo\n*.su\n\n#\n# Top-level generic files\n#\n/tags\n/TAGS\n/linux\n/vmlinux\n/vmlinux.32\n/vmlinux-gdb.py\n/vmlinuz\n/System.map\n/Module.markers\n\n#\n# Debian directory (make deb-pkg)\n#\n/debian/\n\n#\n# tar directory (make tar*-pkg)\n#\n/tar-install/\n\n#\n# git files that we don't want to ignore even if they are dot-files\n#\n!.gitignore\n!.mailmap\n\n#\n# Generated include files\n#\ninclude/config/\ninclude/generated\narch/*/include/generated\n\n# stgit generated dirs\npatches-*\n\n# quilt's files\npatches\nseries\n\n# cscope files\ncscope.*\nncscope.*\n\n# gnu global files\nGPATH\nGRTAGS\nGSYMS\nGTAGS\n\n# id-utils files\nID\n\n*.orig\n*~\n\\#*#\n\n#\n# Leavings from module signing\n#\nextra_certificates\nsigning_key.pem\nsigning_key.priv\nsigning_key.x509\nx509.genkey\n\n# Kconfig presets\nall.config\n\n# Kdevelop4\n*.kdev4\n*.lds\nallsymbols.S\ntmp.minos.symbols\n*.dtb\n*.py[co]\ntools/Kconfiglib/build/\n*.egg-info/\ntools/Kconfiglib/dist/\ntools/fdt_parse/parse_dtb\nasm-offset.h\n"
  },
  {
    "path": "user.sbin/pangu/Makefile",
    "content": "TARGET \t\t= pangu.srv\nAPP_CFLAGS \t= -I./include\nAPP_LINK_LIBS\t= fdt\n\nSRC_C\t:= $(wildcard src/*.c)\n\nAPP_INSTALL_DIR = ramdisk\n\nTEXT_START := 0x8000000\n\ninclude $(projtree)/scripts/app_build.mk\n"
  },
  {
    "path": "user.sbin/pangu/include/pangu/bootarg.h",
    "content": "#ifndef __PANGU_BOOTARG_H__\n#define __PANGU_BOOTARG_H__\n\n#include <inttypes.h>\n\nint bootargs_init(const char *str, int len);\n\nint __get_boot_option(char *name, void *value,\n\t\tint (*parse)(char *args, void *value));\n\nint bootarg_parse_hex32(char *name, uint32_t *v);\nint bootarg_parse_hex64(char *name, uint64_t *v);\nint bootarg_parse_uint(char *name, uint32_t *v);\nint bootarg_parse_bool(char *name, int *v);\nint bootarg_parse_string(char *name, char **v);\n\n#endif\n"
  },
  {
    "path": "user.sbin/pangu/include/pangu/elf.h",
    "content": "#ifndef __PANGU_ELF_H__\n#define __PANGU_ELF_H__\n\n#include <minos/types.h>\n\ntypedef uint8_t     Elf_Byte;\n\ntypedef uint32_t    Elf32_Addr;    /* Unsigned program address */\ntypedef uint32_t    Elf32_Off;     /* Unsigned file offset */\ntypedef int32_t     Elf32_Sword;   /* Signed large integer */\ntypedef uint32_t    Elf32_Word;    /* Unsigned large integer */\ntypedef uint16_t    Elf32_Half;    /* Unsigned medium integer */\n\ntypedef uint64_t    Elf64_Addr;\ntypedef uint64_t    Elf64_Off;\ntypedef int32_t     Elf64_Shalf;\n\n#ifdef __alpha__\ntypedef int64_t     Elf64_Sword;\ntypedef uint64_t    Elf64_Word;\n#else\ntypedef int32_t     Elf64_Sword;\ntypedef uint32_t    Elf64_Word;\n#endif\n\ntypedef int64_t     Elf64_Sxword;\ntypedef uint64_t    Elf64_Xword;\n\ntypedef uint32_t    Elf64_Half;\ntypedef uint16_t    Elf64_Quarter;\n\n#if defined(__i386__)\n#define EM_THIS EM_386\n#define EL_ARCH_USES_REL\n#elif defined(__amd64__)\n#define EM_THIS EM_AMD64\n#define EL_ARCH_USES_RELA\n#elif defined(__arm__)\n#define EM_THIS EM_ARM\n#elif defined(__aarch64__)\n#define EM_THIS EM_AARCH64\n#define EL_ARCH_USES_RELA\n#define EL_ARCH_USES_REL\n#else\n#error specify your ELF architecture\n#endif\n\n#if defined(__LP64__) || defined(__LLP64__)\n#define ELFSIZE 64\n#else\n#define ELFSIZE 32\n#endif\n\n#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__\n#define ELFDATATHIS ELFDATA2LSB\n#else\n#define ELFDATATHIS ELFDATA2MSB\n#endif\n\n#define EI_MAG0        0        /* file ID */\n#define EI_MAG1        1        /* file ID */\n#define EI_MAG2        2        /* file ID */\n#define EI_MAG3        3        /* file ID */\n#define EI_CLASS       4        /* file class */\n#define EI_DATA        5        /* data encoding */\n#define EI_VERSION     6        /* ELF header version */\n#define EI_OSABI       7        /* OS/ABI ID */\n#define EI_ABIVERSION  8        /* ABI version */\n#define EI_PAD         9        /* start of pad bytes */\n#define EI_NIDENT     16        /* Size of e_ident[] */\n\n/* e_ident[] magic number */\n#define    ELFMAG0        0x7f       /* e_ident[EI_MAG0] */\n#define    ELFMAG1        'E'        /* e_ident[EI_MAG1] */\n#define    ELFMAG2        'L'        /* e_ident[EI_MAG2] */\n#define    ELFMAG3        'F'        /* e_ident[EI_MAG3] */\n#define    ELFMAG        \"\\177ELF\"   /* magic */\n#define    SELFMAG        4          /* size of magic */\n\n/* e_ident[] file class */\n#define    ELFCLASSNONE    0        /* invalid */\n#define    ELFCLASS32    1          /* 32-bit objs */\n#define    ELFCLASS64    2          /* 64-bit objs */\n#define    ELFCLASSNUM    3         /* number of classes */\n\n/* e_ident[] data encoding */\n#define ELFDATANONE    0            /* invalid */\n#define ELFDATA2LSB    1            /* Little-Endian */\n#define ELFDATA2MSB    2            /* Big-Endian */\n#define ELFDATANUM     3            /* number of data encode defines */\n\n/* e_ident[] Operating System/ABI */\n#define ELFOSABI_SYSV        0    /* UNIX System V ABI */\n#define ELFOSABI_HPUX        1    /* HP-UX operating system */\n#define ELFOSABI_NETBSD      2    /* NetBSD */\n#define ELFOSABI_LINUX       3    /* GNU/Linux */\n#define ELFOSABI_HURD        4    /* GNU/Hurd */\n#define ELFOSABI_86OPEN      5    /* 86Open common IA32 ABI */\n#define ELFOSABI_SOLARIS     6    /* Solaris */\n#define ELFOSABI_MONTEREY    7    /* Monterey */\n#define ELFOSABI_IRIX        8    /* IRIX */\n#define ELFOSABI_FREEBSD     9    /* FreeBSD */\n#define ELFOSABI_TRU64       10   /* TRU64 UNIX */\n#define ELFOSABI_MODESTO     11   /* Novell Modesto */\n#define ELFOSABI_OPENBSD     12   /* OpenBSD */\n#define ELFOSABI_ARM         97   /* ARM */\n#define ELFOSABI_STANDALONE  255  /* Standalone (embedded) application */\n\n/* e_ident */\n#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \\\n                      (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \\\n                      (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \\\n                      (ehdr).e_ident[EI_MAG3] == ELFMAG3)\n\n/* ELF Header */\ntypedef struct {\n    unsigned char    e_ident[EI_NIDENT];     /* ELF Identification */\n    Elf32_Half       e_type;                 /* object file type */\n    Elf32_Half       e_machine;              /* machine */\n    Elf32_Word       e_version;              /* object file version */\n    Elf32_Addr       e_entry;                /* virtual entry point */\n    Elf32_Off        e_phoff;                /* program header table offset */\n    Elf32_Off        e_shoff;                /* section header table offset */\n    Elf32_Word       e_flags;                /* processor-specific flags */\n    Elf32_Half       e_ehsize;               /* ELF header size */\n    Elf32_Half       e_phentsize;            /* program header entry size */\n    Elf32_Half       e_phnum;                /* number of program header entries */\n    Elf32_Half       e_shentsize;            /* section header entry size */\n    Elf32_Half       e_shnum;                /* number of section header entries */\n    Elf32_Half       e_shstrndx;             /* section header table's \"section\n                                                header string table\" entry offset */\n} Elf32_Ehdr;\n\ntypedef struct {\n    unsigned char    e_ident[EI_NIDENT];    /* Id bytes */\n    Elf64_Quarter    e_type;                /* file type */\n    Elf64_Quarter    e_machine;             /* machine type */\n    Elf64_Half       e_version;             /* version number */\n    Elf64_Addr       e_entry;               /* entry point */\n    Elf64_Off        e_phoff;               /* Program hdr offset */\n    Elf64_Off        e_shoff;               /* Section hdr offset */\n    Elf64_Half       e_flags;               /* Processor flags */\n    Elf64_Quarter    e_ehsize;              /* sizeof ehdr */\n    Elf64_Quarter    e_phentsize;           /* Program header entry size */\n    Elf64_Quarter    e_phnum;               /* Number of program headers */\n    Elf64_Quarter    e_shentsize;           /* Section header entry size */\n    Elf64_Quarter    e_shnum;               /* Number of section headers */\n    Elf64_Quarter    e_shstrndx;            /* String table index */\n} Elf64_Ehdr;\n\n/* e_type */\n#define ET_NONE        0        /* No file type */\n#define ET_REL         1        /* relocatable file */\n#define ET_EXEC        2        /* executable file */\n#define ET_DYN         3        /* shared object file */\n#define ET_CORE        4        /* core file */\n#define ET_NUM         5        /* number of types */\n#define ET_LOPROC      0xff00   /* reserved range for processor */\n#define ET_HIPROC      0xffff   /*  specific e_type */\n\n/* e_machine */\n#define EM_NONE        0        /* No Machine */\n#define EM_M32         1        /* AT&T WE 32100 */\n#define EM_SPARC       2        /* SPARC */\n#define EM_386         3        /* Intel 80386 */\n#define EM_68K         4        /* Motorola 68000 */\n#define EM_88K         5        /* Motorola 88000 */\n#define EM_486         6        /* Intel 80486 - unused? */\n#define EM_860         7        /* Intel 80860 */\n#define EM_MIPS        8        /* MIPS R3000 Big-Endian only */\n/*\n * Don't know if EM_MIPS_RS4_BE,\n * EM_SPARC64, EM_PARISC,\n * or EM_PPC are ABI compliant\n */\n#define EM_MIPS_RS4_BE 10        /* MIPS R4000 Big-Endian */\n#define EM_SPARC64     11        /* SPARC v9 64-bit unofficial */\n#define EM_PARISC      15        /* HPPA */\n#define EM_SPARC32PLUS 18        /* Enhanced instruction set SPARC */\n#define EM_PPC         20        /* PowerPC */\n#define EM_ARM         40        /* ARM AArch32 */\n#define EM_ALPHA       41        /* DEC ALPHA */\n#define EM_SH          42        /* Hitachi/Renesas Super-H */\n#define EM_SPARCV9     43        /* SPARC version 9 */\n#define EM_IA_64       50        /* Intel IA-64 Processor */\n#define EM_AMD64       62        /* AMD64 architecture */\n#define EM_VAX         75        /* DEC VAX */\n#define EM_AARCH64     183       /* ARM AArch64 */\n\n/* Non-standard */\n#define EM_ALPHA_EXP   0x9026        /* DEC ALPHA */\n\n\n/* Version */\n#define EV_NONE        0        /* Invalid */\n#define EV_CURRENT     1        /* Current */\n#define EV_NUM         2        /* number of versions */\n\n/* Section Header */\ntypedef struct {\n    Elf32_Word    sh_name;      /* name - index into section header\n                                 * string table section */\n    Elf32_Word    sh_type;      /* type */\n    Elf32_Word    sh_flags;     /* flags */\n    Elf32_Addr    sh_addr;      /* address */\n    Elf32_Off     sh_offset;    /* file offset */\n    Elf32_Word    sh_size;      /* section size */\n    Elf32_Word    sh_link;      /* section header table index link */\n    Elf32_Word    sh_info;      /* extra information */\n    Elf32_Word    sh_addralign; /* address alignment */\n    Elf32_Word    sh_entsize;   /* section entry size */\n} Elf32_Shdr;\n\ntypedef struct {\n    Elf64_Half    sh_name;       /* section name */\n    Elf64_Half    sh_type;       /* section type */\n    Elf64_Xword   sh_flags;      /* section flags */\n    Elf64_Addr    sh_addr;       /* virtual address */\n    Elf64_Off     sh_offset;     /* file offset */\n    Elf64_Xword   sh_size;       /* section size */\n    Elf64_Half    sh_link;       /* link to another */\n    Elf64_Half    sh_info;       /* misc info */\n    Elf64_Xword   sh_addralign;  /* memory alignment */\n    Elf64_Xword   sh_entsize;    /* table entry size */\n} Elf64_Shdr;\n\n/* Special Section Indexes */\n#define SHN_UNDEF     0             /* undefined */\n#define SHN_LORESERVE 0xff00        /* lower bounds of reserved indexes */\n#define SHN_LOPROC    0xff00        /* reserved range for processor */\n#define SHN_HIPROC    0xff1f        /*   specific section indexes */\n#define SHN_ABS       0xfff1        /* absolute value */\n#define SHN_COMMON    0xfff2        /* common symbol */\n#define SHN_HIRESERVE 0xffff        /* upper bounds of reserved indexes */\n\n/* sh_type */\n#define SHT_NULL     0        /* inactive */\n#define SHT_PROGBITS 1        /* program defined information */\n#define SHT_SYMTAB   2        /* symbol table section */\n#define SHT_STRTAB   3        /* string table section */\n#define SHT_RELA     4        /* relocation section with addends*/\n#define SHT_HASH     5        /* symbol hash table section */\n#define SHT_DYNAMIC  6        /* dynamic section */\n#define SHT_NOTE     7        /* note section */\n#define SHT_NOBITS   8        /* no space section */\n#define SHT_REL      9        /* relation section without addends */\n#define SHT_SHLIB    10       /* reserved - purpose unknown */\n#define SHT_DYNSYM   11       /* dynamic symbol table section */\n#define SHT_NUM      12       /* number of section types */\n#define SHT_LOPROC   0x70000000    /* reserved range for processor */\n#define SHT_HIPROC   0x7fffffff    /*  specific section header types */\n#define SHT_LOUSER   0x80000000    /* reserved range for application */\n#define SHT_HIUSER   0xffffffff    /*  specific indexes */\n\n/* Section names */\n#define ELF_BSS         \".bss\"        /* uninitialized data */\n#define ELF_DATA        \".data\"       /* initialized data */\n#define ELF_DEBUG       \".debug\"      /* debug */\n#define ELF_DYNAMIC     \".dynamic\"    /* dynamic linking information */\n#define ELF_DYNSTR      \".dynstr\"     /* dynamic string table */\n#define ELF_DYNSYM      \".dynsym\"     /* dynamic symbol table */\n#define ELF_FINI        \".fini\"       /* termination code */\n#define ELF_GOT         \".got\"        /* global offset table */\n#define ELF_HASH        \".hash\"       /* symbol hash table */\n#define ELF_INIT        \".init\"       /* initialization code */\n#define ELF_REL_DATA    \".rel.data\"   /* relocation data */\n#define ELF_REL_FINI    \".rel.fini\"   /* relocation termination code */\n#define ELF_REL_INIT    \".rel.init\"   /* relocation initialization code */\n#define ELF_REL_DYN     \".rel.dyn\"    /* relocation dynamic link info */\n#define ELF_REL_RODATA  \".rel.rodata\" /* relocation read-only data */\n#define ELF_REL_TEXT    \".rel.text\"   /* relocation code */\n#define ELF_RODATA      \".rodata\"     /* read-only data */\n#define ELF_SHSTRTAB    \".shstrtab\"   /* section header string table */\n#define ELF_STRTAB      \".strtab\"     /* string table */\n#define ELF_SYMTAB      \".symtab\"     /* symbol table */\n#define ELF_TEXT        \".text\"       /* code */\n\n\n/* Section Attribute Flags - sh_flags */\n#define SHF_WRITE        0x1           /* Writable */\n#define SHF_ALLOC        0x2           /* occupies memory */\n#define SHF_EXECINSTR    0x4           /* executable */\n#define SHF_TLS          0x400         /* thread local storage */\n#define SHF_MASKPROC     0xf0000000    /* reserved bits for processor\n                                        *  specific section attributes */\n\n/* Symbol Table Entry */\ntypedef struct elf32_sym {\n    Elf32_Word    st_name;     /* name - index into string table */\n    Elf32_Addr    st_value;    /* symbol value */\n    Elf32_Word    st_size;     /* symbol size */\n    unsigned char st_info;     /* type and binding */\n    unsigned char st_other;    /* 0 - no defined meaning */\n    Elf32_Half    st_shndx;    /* section header index */\n} Elf32_Sym;\n\ntypedef struct {\n    Elf64_Half    st_name;    /* Symbol name index in str table */\n    Elf_Byte      st_info;    /* type / binding attrs */\n    Elf_Byte      st_other;   /* unused */\n    Elf64_Quarter st_shndx;   /* section index of symbol */\n    Elf64_Xword   st_value;   /* value of symbol */\n    Elf64_Xword   st_size;    /* size of symbol */\n} Elf64_Sym;\n\n/* Symbol table index */\n#define STN_UNDEF    0        /* undefined */\n\n/* Extract symbol info - st_info */\n#define ELF32_ST_BIND(x)    ((x) >> 4)\n#define ELF32_ST_TYPE(x)    (((unsigned int) x) & 0xf)\n#define ELF32_ST_INFO(b,t)  (((b) << 4) + ((t) & 0xf))\n\n#define ELF64_ST_BIND(x)    ((x) >> 4)\n#define ELF64_ST_TYPE(x)    (((unsigned int) x) & 0xf)\n#define ELF64_ST_INFO(b,t)  (((b) << 4) + ((t) & 0xf))\n\n/* Symbol Binding - ELF32_ST_BIND - st_info */\n#define STB_LOCAL    0        /* Local symbol */\n#define STB_GLOBAL   1        /* Global symbol */\n#define STB_WEAK     2        /* like global - lower precedence */\n#define STB_NUM      3        /* number of symbol bindings */\n#define STB_LOPROC  13        /* reserved range for processor */\n#define STB_HIPROC  15        /*  specific symbol bindings */\n\n/* Symbol type - ELF32_ST_TYPE - st_info */\n#define STT_NOTYPE    0        /* not specified */\n#define STT_OBJECT    1        /* data object */\n#define STT_FUNC      2        /* function */\n#define STT_SECTION   3        /* section */\n#define STT_FILE      4        /* file */\n#define STT_TLS       6        /* thread local storage */\n#define STT_LOPROC    13       /* reserved range for processor */\n#define STT_HIPROC    15       /*  specific symbol types */\n\n/* Relocation entry with implicit addend */\ntypedef struct {\n    Elf32_Addr    r_offset;    /* offset of relocation */\n    Elf32_Word    r_info;      /* symbol table index and type */\n} Elf32_Rel;\n\n/* Relocation entry with explicit addend */\ntypedef struct {\n    Elf32_Addr    r_offset;    /* offset of relocation */\n    Elf32_Word    r_info;      /* symbol table index and type */\n    Elf32_Sword   r_addend;\n} Elf32_Rela;\n\n/* Extract relocation info - r_info */\n#define ELF32_R_SYM(i)         ((i) >> 8)\n#define ELF32_R_TYPE(i)        ((unsigned char) (i))\n#define ELF32_R_INFO(s,t)      (((s) << 8) + (unsigned char)(t))\n\ntypedef struct {\n    Elf64_Xword    r_offset;    /* where to do it */\n    Elf64_Xword    r_info;      /* index & type of relocation */\n} Elf64_Rel;\n\ntypedef struct {\n    Elf64_Xword    r_offset;    /* where to do it */\n    Elf64_Xword    r_info;      /* index & type of relocation */\n    Elf64_Sxword    r_addend;   /* adjustment value */\n} Elf64_Rela;\n\n#define    ELF64_R_SYM(info)    ((info) >> 32)\n#define    ELF64_R_TYPE(info)   ((info) & 0xFFFFFFFF)\n#define    ELF64_R_INFO(s,t)    (((s) << 32) + (__uint32_t)(t))\n\n#if defined(__mips64__) && defined(__MIPSEL__)\n/*\n * The 64-bit MIPS ELF ABI uses a slightly different relocation format\n * than the regular ELF ABI: the r_info field is split into several\n * pieces (see gnu/usr.bin/binutils/include/elf/mips.h for details).\n */\n#undef    ELF64_R_SYM\n#undef    ELF64_R_TYPE\n#undef    ELF64_R_INFO\n#define   ELF64_R_TYPE(info)   (swap32((info) >> 32))\n#define   ELF64_R_SYM(info)    ((info) & 0xFFFFFFFF)\n#define   ELF64_R_INFO(s,t)    (((__uint64_t)swap32(t) << 32) + (__uint32_t)(s))\n#endif /* __mips64__ && __MIPSEL__ */\n\n/* Program Header */\ntypedef struct {\n    Elf32_Word    p_type;     /* segment type */\n    Elf32_Off     p_offset;   /* segment offset */\n    Elf32_Addr    p_vaddr;    /* virtual address of segment */\n    Elf32_Addr    p_paddr;    /* physical address - ignored? */\n    Elf32_Word    p_filesz;   /* number of bytes in file for seg. */\n    Elf32_Word    p_memsz;    /* number of bytes in mem. for seg. */\n    Elf32_Word    p_flags;    /* flags */\n    Elf32_Word    p_align;    /* memory alignment */\n} Elf32_Phdr;\n\ntypedef struct {\n    Elf64_Half    p_type;     /* entry type */\n    Elf64_Half    p_flags;    /* flags */\n    Elf64_Off     p_offset;   /* offset */\n    Elf64_Addr    p_vaddr;    /* virtual address */\n    Elf64_Addr    p_paddr;    /* physical address */\n    Elf64_Xword   p_filesz;   /* file size */\n    Elf64_Xword   p_memsz;    /* memory size */\n    Elf64_Xword   p_align;    /* memory & file alignment */\n} Elf64_Phdr;\n\n/* Segment types - p_type */\n#define PT_NULL        0          /* unused */\n#define PT_LOAD        1          /* loadable segment */\n#define PT_DYNAMIC     2          /* dynamic linking section */\n#define PT_INTERP      3          /* the RTLD */\n#define PT_NOTE        4          /* auxiliary information */\n#define PT_SHLIB       5          /* reserved - purpose undefined */\n#define PT_PHDR        6          /* program header */\n#define PT_TLS         7          /* thread local storage */\n#define PT_LOOS        0x60000000 /* reserved range for OS */\n#define PT_HIOS        0x6fffffff /*  specific segment types */\n#define PT_LOPROC      0x70000000 /* reserved range for processor */\n#define PT_HIPROC      0x7fffffff /*  specific segment types */\n\n#define PT_OPENBSD_RANDOMIZE 0x65a3dbe6 /* fill with random data */\n#define PT_GANDR_KERNEL      0x67646b6c /* gdkl */\n\n\n/* Segment flags - p_flags */\n#define PF_X        0x1        /* Executable */\n#define PF_W        0x2        /* Writable */\n#define PF_R        0x4        /* Readable */\n#define PF_MASKPROC 0xf0000000    /* reserved bits for processor */\n                    /*  specific segment flags */\n\n/* Dynamic structure */\ntypedef struct {\n    Elf32_Sword    d_tag;    /* controls meaning of d_val */\n    union {\n        Elf32_Word d_val;    /* Multiple meanings - see d_tag */\n        Elf32_Addr d_ptr;    /* program virtual address */\n    } d_un;\n} Elf32_Dyn;\n\ntypedef struct {\n    Elf64_Xword     d_tag;   /* controls meaning of d_val */\n    union {\n        Elf64_Addr  d_ptr;\n        Elf64_Xword d_val;\n    } d_un;\n} Elf64_Dyn;\n\n/* Dynamic Array Tags - d_tag */\n#define DT_NULL        0        /* marks end of _DYNAMIC array */\n#define DT_NEEDED      1        /* string table offset of needed lib */\n#define DT_PLTRELSZ    2        /* size of relocation entries in PLT */\n#define DT_PLTGOT      3        /* address PLT/GOT */\n#define DT_HASH        4        /* address of symbol hash table */\n#define DT_STRTAB      5        /* address of string table */\n#define DT_SYMTAB      6        /* address of symbol table */\n#define DT_RELA        7        /* address of relocation table */\n#define DT_RELASZ      8        /* size of relocation table */\n#define DT_RELAENT     9        /* size of relocation entry */\n#define DT_STRSZ      10        /* size of string table */\n#define DT_SYMENT     11        /* size of symbol table entry */\n#define DT_INIT       12        /* address of initialization func. */\n#define DT_FINI       13        /* address of termination function */\n#define DT_SONAME     14        /* string table offset of shared obj */\n#define DT_RPATH      15        /* string table offset of library\n                                 * search path */\n#define DT_SYMBOLIC   16        /* start sym search in shared obj. */\n#define DT_REL        17        /* address of rel. tbl. w addends */\n#define DT_RELSZ      18        /* size of DT_REL relocation table */\n#define DT_RELENT     19        /* size of DT_REL relocation entry */\n#define DT_PLTREL     20        /* PLT referenced relocation entry */\n#define DT_DEBUG      21        /* bugger */\n#define DT_TEXTREL    22        /* Allow rel. mod. to unwritable seg */\n#define DT_JMPREL     23        /* add. of PLT's relocation entries */\n#define DT_BIND_NOW   24        /* Bind now regardless of env setting */\n#define DT_LOOS       0x6000000d    /* reserved range for OS */\n#define DT_HIOS       0x6ffff000    /*  specific dynamic array tags */\n#define DT_LOPROC     0x70000000    /* reserved range for processor */\n#define DT_HIPROC     0x7fffffff    /*  specific dynamic array tags */\n\n/* some other useful tags */\n#define DT_RELACOUNT  0x6ffffff9    /* if present, number of RELATIVE */\n#define DT_RELCOUNT   0x6ffffffa    /* relocs, which must come first */\n#define DT_FLAGS_1    0x6ffffffb\n\n/* Dynamic Flags - DT_FLAGS_1 .dynamic entry */\n#define DF_1_NOW       0x00000001\n#define DF_1_GLOBAL    0x00000002\n#define DF_1_GROUP     0x00000004\n#define DF_1_NODELETE  0x00000008\n#define DF_1_LOADFLTR  0x00000010\n#define DF_1_INITFIRST 0x00000020\n#define DF_1_NOOPEN    0x00000040\n#define DF_1_ORIGIN    0x00000080\n#define DF_1_DIRECT    0x00000100\n#define DF_1_TRANS     0x00000200\n#define DF_1_INTERPOSE 0x00000400\n#define DF_1_NODEFLIB  0x00000800\n#define DF_1_NODUMP    0x00001000\n#define DF_1_CONLFAT   0x00002000\n\n/* ld.so: number of low tags that are used saved internally (0 .. DT_NUM-1) */\n#define DT_NUM        (DT_JMPREL+1)\n\n/*\n * Note Definitions\n */\ntypedef struct {\n    Elf32_Word namesz;\n    Elf32_Word descsz;\n    Elf32_Word type;\n} Elf32_Note;\n\ntypedef struct {\n    Elf64_Half namesz;\n    Elf64_Half descsz;\n    Elf64_Half type;\n} Elf64_Note;\n\ntypedef struct {\n\tuint64_t a_type;              /* Entry type */\n\tuint64_t a_val;\n} Elf64_auxv_t;\n\n#define ELFSIZE\t64\n\n#if defined(ELFSIZE) && (ELFSIZE == 32)\n#define Elf_Ehdr    Elf32_Ehdr\n#define Elf_Phdr    Elf32_Phdr\n#define Elf_Shdr    Elf32_Shdr\n#define Elf_Sym     Elf32_Sym\n#define Elf_Rel     Elf32_Rel\n#define Elf_RelA    Elf32_Rela\n#define Elf_Dyn     Elf32_Dyn\n#define Elf_Half    Elf32_Half\n#define Elf_Word    Elf32_Word\n#define Elf_Sword   Elf32_Sword\n#define Elf_Addr    Elf32_Addr\n#define Elf_Off     Elf32_Off\n#define Elf_Nhdr    Elf32_Nhdr\n#define Elf_Note    Elf32_Note\n\n#define ELF_R_SYM   ELF32_R_SYM\n#define ELF_R_TYPE  ELF32_R_TYPE\n#define ELF_R_INFO  ELF32_R_INFO\n#define ELFCLASS    ELFCLASS32\n\n#define ELF_ST_BIND ELF32_ST_BIND\n#define ELF_ST_TYPE ELF32_ST_TYPE\n#define ELF_ST_INFO ELF32_ST_INFO\n\n#elif defined(ELFSIZE) && (ELFSIZE == 64)\n\n#define Elf_Ehdr    Elf64_Ehdr\n#define Elf_Phdr    Elf64_Phdr\n#define Elf_Shdr    Elf64_Shdr\n#define Elf_Sym     Elf64_Sym\n#define Elf_Rel     Elf64_Rel\n#define Elf_RelA    Elf64_Rela\n#define Elf_Dyn     Elf64_Dyn\n#define Elf_Half    Elf64_Half\n#define Elf_Word    Elf64_Word\n#define Elf_Sword   Elf64_Sword\n#define Elf_Addr    Elf64_Addr\n#define Elf_Off     Elf64_Off\n#define Elf_Nhdr    Elf64_Nhdr\n#define Elf_Note    Elf64_Note\n\n#define ELF_R_SYM   ELF64_R_SYM\n#define ELF_R_TYPE  ELF64_R_TYPE\n#define ELF_R_INFO  ELF64_R_INFO\n#define ELFCLASS    ELFCLASS64\n\n#define ELF_ST_BIND ELF64_ST_BIND\n#define ELF_ST_TYPE ELF64_ST_TYPE\n#define ELF_ST_INFO ELF64_ST_INFO\n\n#endif\n\n/* Symbolic values for the entries in the auxiliary table\n   put on the initial stack */\n#define AT_NULL   0     /* end of vector */\n#define AT_IGNORE 1     /* entry should be ignored */\n#define AT_EXECFD 2     /* file descriptor of program */\n#define AT_PHDR   3     /* program headers for program */\n#define AT_PHENT  4     /* size of program header entry */\n#define AT_PHNUM  5     /* number of program headers */\n#define AT_PAGESZ 6     /* system page size */\n#define AT_BASE   7     /* base address of interpreter */\n#define AT_FLAGS  8     /* flags */\n#define AT_ENTRY  9     /* entry point of program */\n#define AT_NOTELF 10    /* program is not ELF */\n#define AT_UID    11    /* real uid */\n#define AT_EUID   12    /* effective uid */\n#define AT_GID    13    /* real gid */\n#define AT_EGID   14    /* effective gid */\n#define AT_PLATFORM 15  /* string identifying CPU for optimizations */\n#define AT_HWCAP  16    /* arch dependent hints at CPU capabilities */\n#define AT_CLKTCK 17    /* frequency at which times() increments */\n/* AT_* values 18 through 22 are reserved */\n#define AT_SECURE 23   /* secure mode boolean */\n#define AT_BASE_PLATFORM 24     /* string identifying real platform, may\n                                 * differ from AT_PLATFORM. */\n#define AT_RANDOM 25    /* address of 16 random bytes */\n#define AT_HWCAP2 26    /* extension of AT_HWCAP */\n\n#define AT_EXECFN  31   /* filename of program */\n\n/* dedicated for minos */\n#define AT_ROOTFS_HANDLE 61\n#define AT_CHIYOU_HANDLE 62\n\nstruct elf_ctx {\n\tElf_Addr base_load_vbase;\n\tElf_Addr base_load_vend;\n\tElf_Addr memsz;\n\tElf_Addr align;\n\tElf_Ehdr ehdr;\n\tElf_Off  dynoff;\n\tElf_Addr dynsize;\n};\n\nenum {\n\tEL_OK         = 0,\n\tEL_EIO,\n    \tEL_ENOMEM,\n    \tEL_NOTELF,\n    \tEL_WRONGBITS,\n    \tEL_WRONGENDIAN,\n    \tEL_WRONGARCH,\n    \tEL_WRONGOS,\n    \tEL_NOTEXEC,\n    \tEL_NODYN,\n    \tEL_BADREL,\n};\n\n#define EL_PHOFF(ctx, num) (((ctx)->ehdr.e_phoff + (num) * (ctx)->ehdr.e_phentsize))\n#define EL_SHOFF(ctx, num) (((ctx)->ehdr.e_shoff + (num) * (ctx)->ehdr.e_shentsize))\n\n#endif\n"
  },
  {
    "path": "user.sbin/pangu/include/pangu/kmalloc.h",
    "content": "#ifndef __LIBC_KMALLOC_H__\n#define __LIBC_KMALLOC_H__\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <inttypes.h>\n\nvoid *kmalloc(size_t size);\nvoid kfree(void *mem);\nvoid *kzalloc(size_t size);\n\nvoid *get_pages(int pages);\nvoid free_pages(void *mem);\n\nstatic inline void *get_page(void)\n{\n\treturn get_pages(1);\n}\n\nint kmalloc_init(unsigned long base, unsigned long end);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "user.sbin/pangu/include/pangu/mm.h",
    "content": "#ifndef __PANGU_MM_H__\n#define __PANGU_MM_H__\n\n#include <minos/types.h>\n#include <minos/list.h>\n\n#define VMA_PERM_R\t(1 << 0)\n#define VMA_PERM_W\t(1 << 1)\n#define VMA_PERM_X\t(1 << 2)\n\n#define VMA_PERM_RW\t(VMA_PERM_R | VMA_PERM_W)\n#define VMA_PERM_RO\t(VMA_PERM_R)\n#define VMA_PERM_RWX\t(VMA_PERM_R | VMA_PERM_W | VMA_PERM_X)\n\nstruct process;\nstruct proto;\n\nstruct vma {\n\tunsigned long start;\n\tunsigned long end;\n\tint anon;\n\tint perm;\n\tint pma_handle;\n\tstruct list_head list;\n};\n\n#define vma_size(vma)\t\\\n\t((vma)->end - (vma)->start)\n\n/*\n * total 512G address space for process.\n * 256G - 512G for kernel use to map shared memory\n * 255G - 256G stack for process. (8k is reserve).\n * 0 - 4k reserve\n */\n#define PROCESS_ADDR_TOP\t(1UL << 38)\n#define PROCESS_ADDR_BOTTOM\t(PAGE_SIZE)\n\n#define PROCESS_STACK_TOP\t(PROCESS_ADDR_TOP - PAGE_SIZE)\n#define PROCESS_STACK_SIZE\t(1UL * 1024 * 1024 * 1024 - PAGE_SIZE)\n#define PROCESS_STACK_INIT_SIZE\t(8 * PAGE_SIZE)\n#define PROCESS_STACK_INIT_BASE\t(PROCESS_STACK_TOP - PROCESS_STACK_INIT_SIZE)\n#define PROCESS_STACK_BASE\t(PROCESS_STACK_TOP - PROCESS_STACK_SIZE)\n\n#define PROCESS_MMAP_TOP\t(PROCESS_STACK_BASE - PAGE_SIZE)\n#define PROCESS_MMAP_SIZE\t(4UL * 1024 * 1024 * 1024 - PAGE_SIZE)\n#define PROCESS_MMAP_BOTTOM\t(PROCESS_MMAP_TOP - PROCESS_MMAP_SIZE)\n\n#define PROCESS_BRK_TOP\t\t(1UL << 32)\n\nstruct vma *__request_vma(struct process *proc, unsigned long base,\n\t\tsize_t size, unsigned int perm, int anon);\n\nstruct vma *request_vma(struct process *proc, int pma_handle,\n\t\tunsigned long base, size_t size,\n\t\tunsigned int perm, int anon);\n\nvoid release_vma(struct process *proc, struct vma *vma);\n\nvoid vspace_init(struct process *proc, unsigned long elf_end);\n\nstruct vma *find_vma(struct process *proc, unsigned long base);\n\nint create_pma(int type, int right, unsigned long base, size_t size);\n\nint process_mm_init(struct process *proc, int elf_pma,\n\t\tunsigned long elf_base, size_t elf_size);\n\nlong pangu_mmap(struct process *proc, struct proto *proto, void *data);\nlong pangu_brk(struct process *proc, struct proto *proto, void *data);\nlong pangu_mprotect(struct process *proc, struct proto *proto, void *data);\n\nlong handle_user_page_fault(struct process *proc,\n\t\tuint64_t virt_addr, unsigned long info, long token);\n\n\n#endif\n"
  },
  {
    "path": "user.sbin/pangu/include/pangu/proc.h",
    "content": "#ifndef __PANGU_PROC_H__\n#define __PANGU_PROC_H__\n\n#include <minos/list.h>\n#include <minos/types.h>\n#include <minos/procinfo.h>\n\n#include <pangu/mm.h>\n\n#define TASK_FLAGS_SRV\t\t\tBIT(0)\n#define TASK_FLAGS_DRV\t\t\tBIT(1)\n#define TASK_FLAGS_VCPU\t\t\tBIT(2)\n#define TASK_FLAGS_REALTIME\t\tBIT(3)\n#define TASK_FLAGS_KERNEL_MASK\t\t(0xff)\n\n#define MAX_ARGC\t(PAGE_SIZE / sizeof(char *))\n\n#define PROCESS_NAME_SIZE 64\n\n#define PROC_FLAGS_VMCTL\t(1 << 0)\n#define PROC_FLAGS_HWCTL\t(1 << 1)\n\n#define PROC_WAIT_NONE\t\t0\n#define PROC_WAIT_PID\t\t1\n#define PROC_WAIT_ANY\t\t2\n\nstruct handle_desc {\n\tint handle;\n\tint right;\n};\n\nstruct wait_entry {\n\tint pid;\n\tint type;\n\tlong token;\n\tstruct list_head list;\n};\n\nstruct process {\n\tint proc_handle;\t\t// used to control the process.\n\tint pid;\n\tint flags;\n\n\tstruct list_head children;\n\tstruct list_head clist;\n\tstruct process *parent;\n\n\tstruct vma elf_vma;\n\tstruct vma init_stack_vma;\n\tstruct vma anon_stack_vma;\n\n\t/*\n\t * mmap used for mmap.\n\t */\n\tstruct list_head vma_free;\n\tstruct list_head vma_used;\n\n\t/*\n\t * heap area.\n\t */\n\tunsigned long brk_end;\n\tunsigned long brk_start;\n\tunsigned long brk_cur;\n\n\tstruct list_head wait_head;\n\n\t/*\n\t * link to the global user_proc_list if this process\n\t * is a children of init process.\n\t */\n\tstruct list_head list;\n};\n\n#define proc_pid(proc) ((proc)->pid)\n#define proc_flags(proc) ((proc)->flags)\n\ntypedef long (*syscall_hdl)(struct process *proc, struct proto *proto, void *data);\n\nextern struct process *self;\nextern struct process *rootfs_proc;\nextern struct process *nvwa_proc;\nextern struct process *chiyou_proc;\n\nextern int fuxi_handle;\nextern int nvwa_handle;\nextern int chiyou_handle;\nextern int proc_epfd;\n\nstruct epoll_event;\nstruct process_proto;\n\ntypedef long (*proc_event_handle_t)(struct process *proc,\n\t\tstruct process_proto *proto, void *data, size_t size);\n\nvoid self_init(int proc_handle, unsigned long vma_base, unsigned long vma_end);\n\nvoid *map_self_memory(int pma_handle, size_t size, int perm);\n\nint unmap_self_memory(void *base);\n\nvoid wakeup_process(struct process *proc);\n\nvoid handle_process_request(struct epoll_event *event, struct process *proc);\n\nlong pangu_procinfo(struct process *proc, struct proto *proto, void *data);\nlong pangu_taskstat(struct process *proc, struct proto *proto, void *data);\nlong pangu_proccnt(struct process *proc, struct proto *proto, void *data);\n\nstruct process *load_ramdisk_process(char *path,\n\t\tstruct handle_desc *hdesc, int num_handle, int flags);\n\nint register_request_entry(int handle, struct process *proc);\nint unregister_request_entry(int handle, struct process *proc);\n\nint alloc_pid(void);\nvoid release_pid(int pid);\n\n#endif\n"
  },
  {
    "path": "user.sbin/pangu/include/pangu/ramdisk.h",
    "content": "#ifndef __PANGU_RAMDISK_H__\n#define __PANGU_RAMDISK_H__\n\n#include <inttypes.h>\n#include <uapi/ramdisk.h>\n#include <pangu/elf.h>\n\nstruct process;\n\nint ramdisk_open(char *name, struct ramdisk_file *file);\n\nint ramdisk_read(struct ramdisk_file *file, void *buf,\n\t\tsize_t size, unsigned long offset);\n\nint elf_init_ramdisk(struct elf_ctx *ctx, struct ramdisk_file *file);\n\nint load_process_from_ramdisk(struct process *proc,\n\t\tstruct elf_ctx *ctx, struct ramdisk_file *file);\n\n#endif\n"
  },
  {
    "path": "user.sbin/pangu/src/bootarg.c",
    "content": "/*\n * Copyright (C) 2020 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <errno.h>\n#include <stdio.h>\n#include <inttypes.h>\n#include <string.h>\n#include <stdlib.h>\n#include <minos/debug.h>\n\n#include <uapi/bootdata.h>\n#include <pangu/kmalloc.h>\n\nstruct boot_option {\n\tchar *name;\n\tchar *args;\n\tchar *sub_args;\n\tstruct boot_option *next;\n};\n\nstatic struct boot_option *boot_options;\nstatic char *cmdline;\n\nint __get_boot_option(char *name, void *value,\n\t\tint (*parse)(char *args, void *value))\n{\n\tstruct boot_option *bo;\n\n\tfor (bo = boot_options; bo != NULL; bo = bo->next) {\n\t\tif (strcmp(name, bo->name) != 0)\n\t\t\tcontinue;\n\n\t\treturn parse(bo->args, value);\n\t}\n\n\treturn -ENOENT;\n}\n\nstatic int __parse_hex32(char *args, void *value)\n{\n\tif (!args)\n\t\treturn -EINVAL;\n\n\t*(uint32_t *)value = strtoul(args, NULL, 16);\n\treturn 0;\n}\n\nstatic int __parse_hex64(char *args, void *value)\n{\n\tif (!args)\n\t\treturn -EINVAL;\n\n\t*(uint64_t *)value = strtoul(args, NULL, 16);\n\treturn 0;\n}\n\nstatic int __parse_uint(char *args, void *value)\n{\n\tif (!args)\n\t\treturn -EINVAL;\n\n\t*(uint32_t *)value = strtoul(args, NULL, 10);\n\treturn 0;\n}\n\nstatic int __parse_bool(char *args, void *value)\n{\n\t*(int*)value = 1;\n\treturn 0;\n}\n\nstatic int __parse_string(char *args, void *value)\n{\n\tif (!args)\n\t\treturn -EINVAL;\n\n\t*(char **)value = args;\n\n\treturn 0;\n}\n\nint bootarg_parse_hex32(char *name, uint32_t *v)\n{\n\treturn __get_boot_option(name, v, __parse_hex32);\n}\n\nint bootarg_parse_hex64(char *name, uint64_t *v)\n{\n\treturn __get_boot_option(name, v, __parse_hex64);\n}\n\nint bootarg_parse_uint(char *name, uint32_t *v)\n{\n\treturn __get_boot_option(name, v, __parse_uint);\n}\n\nint bootarg_parse_bool(char *name, int *v)\n{\n\t*v = 0;\n\treturn __get_boot_option(name, v, __parse_bool);\n}\n\nint bootarg_parse_string(char *name, char **v)\n{\n\treturn __get_boot_option(name, v, __parse_string);\n}\n\nstatic void bootarg_init_one(char *str)\n{\n\tstruct boot_option *bo;\n\n\t/*\n\t * this function will called before mm_init so\n\t * call sys_malloc, the bootarg format is like\n\t * xxx=xxx xxx=xxx xxx=xxx\n\t */\n\tif ((*str == 0) || (*str == ' '))\n\t\treturn;\n\n\tbo = kmalloc(sizeof(struct boot_option));\n\tif (!bo)\n\t\treturn;\n\tmemset(bo, 0, sizeof(struct boot_option));\n\n\tbo->name = strsep(&str, \"=\");\n\tbo->args = str;\n\n\tbo->next = boot_options;\n\tboot_options = bo;\n}\n\nint bootargs_init(const char *str, int len)\n{\n\tchar *tmp;\n\tchar *bootarg;\n\n\tcmdline = kmalloc(CMDLINE_SIZE);\n\tif (!cmdline)\n\t\texit(-ENOMEM);\n\n\tpr_notice(\"bootargs: %s\\n\", str);\n\tlen = len > CMDLINE_SIZE - 1 ? CMDLINE_SIZE - 1 : len;\n\tstrncpy(cmdline, str, len);\n\tcmdline[len] = 0;\n\ttmp = cmdline;\n\n\twhile ((bootarg = strsep(&tmp, \" \")) != NULL)\n\t\tbootarg_init_one(bootarg);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "user.sbin/pangu/src/elf_ramdisk.c",
    "content": "/*\n * Copyright (C) 2020 Min Le (lemin9538@gmail.com)\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <errno.h>\n#include <minos/types.h>\n#include <minos/debug.h>\n#include <minos/kobject.h>\n\n#include <pangu/elf.h>\n#include <pangu/ramdisk.h>\n#include <pangu/proc.h>\n\nint elf_findphdr(struct ramdisk_file *file, struct elf_ctx *ctx,\n\t\tElf_Phdr *phdr, uint32_t type, unsigned *i)\n{\n\tint rv = EL_OK;\n\n    \tfor (; *i < ctx->ehdr.e_phnum; (*i)++) {\n\t\trv = ramdisk_read(file, phdr, sizeof(Elf_Phdr), EL_PHOFF(ctx, *i));\n\t\tif (rv)\n\t\t\treturn rv;\n\t\t\n\t\tif (phdr->p_type == type)\n\t\t\treturn rv;\n    \t}\n\n    \t*i = -1;\n    \treturn rv;\n}\n\nint elf_init_ramdisk(struct elf_ctx *ctx, struct ramdisk_file *file)\n{\n\tElf_Phdr ph;\n\tint rv = EL_OK;\n\tunsigned i = 0;\n\n\tmemset(ctx, 0, sizeof(struct elf_ctx));\n\t\n\tif ((rv = ramdisk_read(file, &ctx->ehdr, sizeof(ctx->ehdr), 0)))\n\t\treturn rv;\n\t\n\tif (!IS_ELF(ctx->ehdr))\n\t\treturn EL_NOTELF;\n\t\n\tif (ctx->ehdr.e_ident[EI_CLASS] != ELFCLASS)\n\t        return EL_WRONGBITS;\n\t\n\tif (ctx->ehdr.e_ident[EI_DATA] != ELFDATATHIS)\n\t        return EL_WRONGENDIAN;\n\t\n\tif (ctx->ehdr.e_ident[EI_VERSION] != EV_CURRENT)\n\t        return EL_NOTELF;\n\t\n\tif (ctx->ehdr.e_type != ET_EXEC || ctx->ehdr.e_type == ET_DYN)\n\t        return EL_NOTEXEC;\n\n\tif (ctx->ehdr.e_machine != EM_THIS)\n\t        return EL_WRONGARCH;\n\t\n\tif (ctx->ehdr.e_version != EV_CURRENT)\n\t        return EL_NOTELF;\n\t\n\t/*\n\t * calculate how many memory is needed for this elf file, the\n\t * memory will allocated together.\n\t */\n\tctx->base_load_vbase = (unsigned long)-1;\n\n\tfor(;;) {\n\t\tif ((rv = elf_findphdr(file, ctx, &ph, PT_LOAD, &i)))\n\t\t\treturn rv;\n\t\n\t        if (i == (unsigned) -1)\n\t\t\tbreak;\n\n\t\tif (ph.p_vaddr < ctx->base_load_vbase)\n\t\t\tctx->base_load_vbase = ph.p_vaddr;\n\t\n\t        Elf_Addr phend = ph.p_vaddr + ph.p_memsz;\n\t        if (phend > ctx->base_load_vend)\n\t\t\tctx->base_load_vend = phend;\n\t\n\t        if (ph.p_align > ctx->align)\n\t\t\tctx->align = ph.p_align;\n\t\ti++;\n\t}\n\n\tctx->memsz = PAGE_BALIGN(ctx->base_load_vend - ctx->base_load_vbase);\n\t\n\treturn rv;\n}\n\nstatic int elf_load_section(struct ramdisk_file *file, void *vaddr, Elf_Shdr *shdr)\n{\n\t/*\n\t * bss section ?\n\t */\n\tif (shdr->sh_type == SHT_NOBITS) {\n\t\tpr_debug(\"bzero elf section [0x%lx 0x%lx 0x%lx %d]\\n\",\n\t\t\tshdr->sh_offset, shdr->sh_addr, shdr->sh_size, shdr->sh_type);\n\t\tmemset(vaddr, 0, shdr->sh_size);\n\t\treturn 0;\n\t}\n\n\tpr_debug(\"loading elf section [0x%lx 0x%lx 0x%lx %d]\\n\",\n\t\t\tshdr->sh_offset, shdr->sh_addr, shdr->sh_size, shdr->sh_type);\n\tramdisk_read(file, vaddr, shdr->sh_size, shdr->sh_offset);\n\n\treturn 0;\n}\n\nstatic int elf_findshdr(struct ramdisk_file *file, struct elf_ctx *ctx,\n\t\tElf_Shdr *shdr, unsigned int *i)\n{\n\n\tint rv = EL_OK;\n\tint j = *i;\n\n\tfor ( ;j < ctx->ehdr.e_shnum; j++) {\n\t\trv = ramdisk_read(file, shdr, sizeof(Elf64_Ehdr), EL_SHOFF(ctx, j));\n\t\tif (rv)\n\t\t\treturn rv;\n\n\t\tif (shdr->sh_flags & SHF_ALLOC) {\n\t\t\t*i = j;\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t*i = -1;\n\treturn rv;\n}\n\nint load_process_from_ramdisk(struct process *proc, struct elf_ctx *ctx,\n\t\tstruct ramdisk_file *file)\n{\n\tstruct vma *vma = &proc->elf_vma;\n\tint rv = EL_OK;\n    \tunsigned int i = 0;\n\tvoid *page;\n\tvoid *vaddr;\n\tElf_Shdr shdr;\n\n\tpage = map_self_memory(vma->pma_handle, ctx->memsz, KOBJ_RIGHT_RW);\n\tif (!page)\n\t\treturn -ENOMEM;\n\n    \tfor(;;) {\n\t\tif ((rv = elf_findshdr(file, ctx, &shdr, &i)))\n            \t\treturn rv;\n\n        \tif (i == (unsigned int)-1)\n            \t\tbreak;\n\n\t\tvaddr = page + (shdr.sh_addr - ctx->base_load_vbase);\n\t\trv = elf_load_section(file, vaddr, &shdr);\n        \tif (rv)\n            \t\treturn EL_ENOMEM;\n        \ti++;\n    \t}\n\n\tunmap_self_memory(page);\n\n\treturn rv;\n}\n"
  },
  {
    "path": "user.sbin/pangu/src/kmalloc.c",
    "content": "/*\n * Copyright (c) 2020 - 2021 Min Le (lemin9538@163.com)\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <strings.h>\n#include <errno.h>\n#include <string.h>\n\n#include <minos/types.h>\n#include <minos/list.h>\n#include <minos/debug.h>\n\n#define HASH_TABLE_SIZE\t8\n\nstruct slab_header {\n\tunsigned long size;\n\tunion {\n\t\tunsigned long magic;\n\t\tstruct slab_header *next;\n\t};\n} __packed;\n\n#define SLAB_MIN_DATA_SIZE\t\t(16)\n#define SLAB_MIN_DATA_SIZE_SHIFT\t(4)\n#define SLAB_HEADER_SIZE\t\tsizeof(struct slab_header)\n#define SLAB_MIN_SIZE\t\t\t(SLAB_MIN_DATA_SIZE + SLAB_HEADER_SIZE)\n#define SLAB_MAGIC\t\t\t(0xdeadbeef)\n\nstruct slab_type {\n\tuint32_t size;\n\tstruct list_head list;\n\tstruct slab_header *head;\n};\n\n/*\n * will try to get hugepage when first time once\n * system bootup.\n */\nstatic struct list_head slab_hash_table[HASH_TABLE_SIZE];\n\nstatic void *slab_base;\nstatic void *slab_end;\nstatic uint32_t slab_size;\n\n#define hash_id(size) (((size) >> SLAB_MIN_DATA_SIZE_SHIFT) % HASH_TABLE_SIZE)\n\nstatic size_t inline get_slab_alloc_size(size_t size)\n{\n\treturn BALIGN(size, SLAB_MIN_DATA_SIZE);\n}\n\nstatic void *malloc_from_hash_table(size_t size)\n{\n\tint id = hash_id(size);\n\tstruct slab_type *st;\n\tstruct slab_header *sh;\n\n\t/*\n\t * find the related slab mem id and try to fetch\n\t * a free slab memory from the hash cache.\n\t */\n\tlist_for_each_entry(st, &slab_hash_table[id], list) {\n\t\tif (st->size != size)\n\t\t\tcontinue;\n\n\t\tif (st->head == NULL)\n\t\t\treturn NULL;\n\n\t\tsh = st->head;\n\t\tst->head = sh->next;\n\t\tsh->magic = SLAB_MAGIC;\n\n\t\treturn ((void *)sh + SLAB_HEADER_SIZE);\n\t}\n\n\treturn NULL;\n}\n\nstatic void *malloc_from_slab_heap(size_t size)\n{\n\tstruct slab_header *sh;\n\n\tsize += SLAB_HEADER_SIZE;\n\tif (slab_size < size)\n\t\treturn NULL;\n\n\tsh = (struct slab_header *)slab_base;\n\tsh->magic = SLAB_MAGIC;\n\tsh->size = size - SLAB_HEADER_SIZE;\n\n\tslab_base += size;\n\tslab_size -= size;\n\n\treturn ((void *)sh + SLAB_HEADER_SIZE);\n}\n\nstatic void free_slab(void *addr)\n{\n\tstruct slab_header *header;\n\tstruct slab_type *st;\n\tint id;\n\n\theader = (struct slab_header *)((unsigned long)addr -\n\t\t\tSLAB_HEADER_SIZE);\n\tif ((header->magic != SLAB_MAGIC) ||\n\t\t\t(header->size < SLAB_MIN_DATA_SIZE)) {\n\t\tpr_warn(\"memory is not a slab mem %p\\n\", addr);\n\t\treturn;\n\t}\n\n\tid = hash_id(header->size);\n\n\tlist_for_each_entry(st, &slab_hash_table[id], list) {\n\t\tif (st->size != header->size)\n\t\t\tcontinue;\n\n\t\theader->next = st->head;\n\t\tst->head = header;\n\t\treturn;\n\t}\n\n\t/*\n\t * create new slab type and add the new slab header\n\t * to the slab cache.\n\t */\n\tst = malloc_from_slab_heap(sizeof(struct slab_type));\n\tif (st == NULL) {\n\t\tpr_err(\"no more memory for pangu\\n\");\n\t\texit(-ENOMEM);\n\t}\n\n\tst->size = header->size;\n\tlist_add_tail(&slab_hash_table[id], &st->list);\n\n\theader->next = NULL;\n\tst->head = header;\n}\n\nvoid kfree(void *addr)\n{\n\tfree_slab(addr);\n}\n\nstatic void *__malloc(size_t size)\n{\n\tvoid *mem;\n\n\tmem = malloc_from_hash_table(size);\n\tif (mem == NULL)\n\t\tmem = malloc_from_slab_heap(size);\n\tif (!mem)\n\t\tpr_err(\"malloc fail for 0x%lx\\n\", size);\n\n\treturn mem;\n}\n\nvoid *kmalloc(size_t size)\n{\n\tif (size == 0)\n\t\tsize = SLAB_MIN_DATA_SIZE;\n\telse\n\t\tsize = get_slab_alloc_size(size);\n\n\treturn __malloc(size);\n}\n\nvoid *kzalloc(size_t size)\n{\n\tvoid *addr = kmalloc(size);\n\tif (addr)\n\t\tmemset(addr, 0, size);\n\treturn addr;\n}\n\nvoid *get_pages(int count)\n{\n\treturn kmalloc(4096);\n}\n\nvoid free_pages(void *base)\n{\n\treturn kfree(base);\n}\n\nint kmalloc_init(unsigned long base, unsigned long end)\n{\n\tint i;\n\n\tif ((end < base) || !IS_PAGE_ALIGN(base) || !IS_PAGE_ALIGN(end)) {\n\t\tfprintf(stderr, \"invalid heap region 0x%lx 0x%lx\\n\", base, end);\n\t\treturn -EINVAL;\n\t}\n\n\t/*\n\t * caculate the real free memory that the process\n\t * can be used.\n\t */\n\tslab_base = (void *)base;\n\tslab_end = (void *)end;\n\tslab_size = end - base;\n\n\tfor (i = 0; i < HASH_TABLE_SIZE; i++)\n\t\tinit_list(&slab_hash_table[i]);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "user.sbin/pangu/src/mm.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n */\n\n#include <stdio.h>\n#include <unistd.h>\n#include <inttypes.h>\n#include <stdlib.h>\n#include <string.h>\n#include <assert.h>\n#include <sys/mman.h>\n#include <errno.h>\n\n#include <minos/debug.h>\n#include <minos/list.h>\n#include <minos/kobject.h>\n#include <minos/proto.h>\n\n#include <pangu/kmalloc.h>\n#include <pangu/proc.h>\n#include <pangu/mm.h>\n\n#define vma_init(vma, _base, _end)\t\\\n\tdo {\t\t\t\t\\\n\t\tvma->pma_handle = -1;\t\\\n\t\tvma->start = _base;\t\\\n\t\tvma->end = _end;\t\\\n\t} while (0)\n\nstatic void __release_vma(struct process *proc, struct vma *vma)\n{\n\tstruct vma *cur, *tmp;\n\n\tvma->pma_handle = -1;\n\tvma->anon = 0;\n\n\tif (vma->list.next != NULL) {\n\t\tpr_err(\"vma is not is in use\\n\");\n\t\treturn;\n\t}\n\n\t/*\n\t * try to merge the vma to a bigger one\n\t */\nrepeat:\n\tlist_for_each_entry_safe(cur, tmp, &proc->vma_free, list) {\n\t\tif (cur->start == vma->end) {\n\t\t\tlist_del(&cur->list);\n\t\t\tvma->end = cur->end;\n\t\t\tkfree(cur);\n\t\t\tgoto repeat;\n\t\t}\n\n\t\tif (vma->start == cur->end) {\n\t\t\tlist_del(&cur->list);\n\t\t\tvma->start = cur->start;\n\t\t\tkfree(cur);\n\t\t\tgoto repeat;\n\t\t}\n\t}\n\n\tlist_add(&proc->vma_free, &vma->list);\n}\n\nvoid release_vma(struct process *proc, struct vma *vma)\n{\n\n\tif (vma->list.next != NULL)\n\t\tlist_del(&vma->list);\n\n\treturn __release_vma(proc, vma);\n}\n\nstatic struct vma *split_vma(struct process *proc, struct vma *vma,\n\t\tunsigned long base, unsigned long end)\n{\n\tsize_t left_size, right_size;\n\tstruct vma *left, *right;\n\n\tleft_size = base - vma->start;\n\tright_size = vma->end - end;\n\n\tif ((left_size == 0) && (right_size == 0))\n\t\treturn vma;\n\n\tif (left_size > 0) {\n\t\tleft = kzalloc(sizeof(struct vma));\n\t\tif (!left)\n\t\t\tgoto out_err;\n\t\tvma_init(left, vma->start, base);\n\t\tlist_add(&proc->vma_free, &left->list);\n\t}\n\n\tif (right_size > 0) {\n\t\tright = kzalloc(sizeof(struct vma));\n\t\tif (!right)\n\t\t\tgoto out_err_right;\n\t\tvma_init(right, end, vma->end);\n\t\tlist_add(&proc->vma_free, &right->list);\n\t}\n\n\tvma->start = base;\n\tvma->end = end;\n\n\treturn vma;\n\nout_err_right:\n\tlist_del(&left->list);\n\tkfree(left);\nout_err:\n\tlist_add(&proc->vma_free, &vma->list);\n\treturn NULL;\n}\n\nstruct vma *__request_vma(struct process *proc, unsigned long base,\n\t\tsize_t size, unsigned int perm, int anon)\n{\n\tunsigned long new_base = base, new_end = base + size;\n\tstruct vma *vma, *old, *out = NULL;\n\n\tif ((base != 0) && (!IS_PAGE_ALIGN(base))) {\n\t\tpr_err(\"%s invalid request address 0x%lx\\n\", __func__, base);\n\t\treturn NULL;\n\t}\n\n\tlist_for_each_entry_safe(vma, old, &proc->vma_free, list) {\n\t\tif (base == 0) {\n\t\t\tnew_base = vma->start;\n\t\t\tnew_end = vma->start + size;\n\t\t}\n\n\t\tif ((new_base >= vma->start) && (new_end <= vma->end)) {\n\t\t\tout = vma;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!out) return NULL;\n\n\tlist_del(&vma->list);\n\tout = split_vma(proc, out, new_base, new_end);\n\tif (out) {\n\t\tout->perm = perm;\n\t\tout->anon = anon;\n\t\tlist_add_tail(&proc->vma_used, &out->list);\n\t}\n\n\treturn out;\n}\n\nint create_pma(int type, int right, unsigned long base, size_t size)\n{\n\tstruct pma_create_arg args = {\n\t\t.size = size,\n\t\t.type = type,\n\t\t.start = base,\n\t\t.right = right,\n\t};\n\n\treturn kobject_create(KOBJ_TYPE_PMA, (unsigned long)&args);\n}\n\nstruct vma *request_vma(struct process *proc, int pma_handle,\n\t\t\tunsigned long base, size_t size,\n\t\t\tunsigned int perm, int anon)\n{\n\tstruct vma *vma;\n\tint ret;\n\t\n\tvma = __request_vma(proc, base, size, perm, anon);\n\tif (!vma)\n\t\treturn NULL;\n\n\t/*\n\t * if this is anon mapping vma area, return directly.\n\t * else allocate a pma for this mapping to share with\n\t * other process or orther usage.\n\t */\n\tif (anon && pma_handle <= 0)\n\t\treturn vma;\n\n\tif (pma_handle <= 0) {\n\t\tvma->pma_handle = create_pma(PMA_TYPE_NORMAL, perm, 0, size);\n\t\tif (vma->pma_handle < 0) {\n\t\t\trelease_vma(proc, vma);\n\t\t\treturn NULL;\n\t\t}\n\t} else {\n\t\tvma->pma_handle = pma_handle;\n\t}\n\n\tret = sys_map(proc->proc_handle, vma->pma_handle, base, size, perm);\n\tif (ret) {\n\t\tif (pma_handle <= 0)\n\t\t\tkobject_close(vma->pma_handle);\n\t\trelease_vma(proc, vma);\n\t\treturn NULL;\n\t}\n\n\treturn vma;\n}\n\nstruct vma *find_vma(struct process *proc, unsigned long base)\n{\n\tstruct vma *vma;\n\n\tlist_for_each_entry(vma, &proc->vma_used, list) {\n\t\tif ((base >= vma->start) && (base < vma->end))\n\t\t\treturn vma;\n\t}\n\n\treturn NULL;\n}\n\nint unmap_self_memory(void *base)\n{\n\tstruct vma *vma;\n\tint ret;\n\n\tif (!IS_PAGE_ALIGN((unsigned long)base)) {\n\t\tpr_err(\"%s address %p is not page align\\n\", __func__, base);\n\t\treturn -EINVAL;\n\t}\n\n\tvma = find_vma(self, (unsigned long)base);\n\tif (!vma)\n\t\treturn -ENOENT;\n\n\tif (vma->pma_handle <= 0) {\n\t\tpr_err(\"%s invalid pma handle\\n\", __func__);\n\t\treturn -EINVAL;\n\t}\n\n\tret = sys_unmap(self->proc_handle, vma->pma_handle,\n\t\t\tvma->start, vma->end - vma->start);\n\tif (ret)\n\t\treturn ret;\n\n\trelease_vma(self, vma);\n\n\treturn 0;\n}\n\nvoid *map_self_memory(int pma_handle, size_t size, int perm)\n{\n\tstruct vma *vma;\n\tint ret;\n\n\tif (pma_handle <= 0) {\n\t\tpr_err(\"%s bad pma handle %d\\n\", __func__, pma_handle);\n\t\treturn NULL;\n\t}\n\n\tvma = __request_vma(self, 0, size, perm, 0);\n\tif (!vma)\n\t\treturn NULL;\n\tvma->pma_handle = pma_handle;\n\n\t/*\n\t * map can only be called by root service, to control\n\t * the mapping of a process.\n\t */\n\tret = sys_map(self->proc_handle, pma_handle, vma->start, size, perm);\n\tif (ret) {\n\t\trelease_vma(self, vma);\n\t\treturn NULL;\n\t}\n\n\treturn (void *)vma->start;\n}\n\nlong pangu_mmap(struct process *proc, struct proto *proto, void *data)\n{\n\tsize_t len = proto->mmap.len;\n\tint prot = proto->mmap.prot;\n\tstruct vma *vma;\n\tint perm = 0;\n\tvoid *addr = (void *)-1;\n\n\tif ((proto->mmap.addr != NULL) || (proto->mmap.fd != -1)) {\n\t\tpr_err(\"only support map anon mapping for process\\n\");\n\t\tgoto out;\n\t}\n\n\tif (prot & PROT_EXEC)\n\t\tperm |= KOBJ_RIGHT_EXEC;\n\tif (prot & PROT_WRITE)\n\t\tperm |= KOBJ_RIGHT_WRITE;\n\tif (prot & PROT_READ)\n\t\tperm |= KOBJ_RIGHT_READ;\n\n\tlen = BALIGN(len, PAGE_SIZE);\n\tvma = request_vma(proc, 0, 0, len, perm, 1);\n\tif (vma)\n\t\taddr = (void *)vma->start;\nout:\n\tkobject_reply_errcode(proc->proc_handle, proto->token, (long)addr);\n\n\treturn 0;\n}\n\nstatic unsigned long __pangu_brk(struct process *proc, struct proto *proto, void *data)\n{\n\tunsigned long addr = (unsigned long)proto->brk.addr;\n\n\tif (addr == 0)\n\t\treturn (long)proc->brk_cur;\n\tif ((addr < proc->brk_start) || (addr >= proc->brk_end))\n\t\treturn -1;\n\tproc->brk_cur = addr;\n\n\treturn addr;\n}\n\nlong pangu_brk(struct process *proc, struct proto *proto, void *data)\n{\n\tunsigned long addr = __pangu_brk(proc, proto, data);\n\tkobject_reply_errcode(proc->proc_handle, proto->token, addr);\n\treturn 0;\n}\n\nlong pangu_mprotect(struct process *proc, struct proto *proto, void *data)\n{\n\tunsigned long end = (unsigned long)proto->mprotect.addr + proto->mprotect.len;\n\tstruct vma *vma = find_vma(proc, (unsigned long)proto->mprotect.addr);\n\tint prot = proto->mprotect.prot;\n\tint ret = 0;\n\n\tif (!vma || (end > vma->end) || !vma->anon) {\n\t\tret = -EINVAL;\n\t\tgoto out;\n\t}\n\n\tif (prot & PROT_EXEC)\n\t\tvma->perm |= KOBJ_RIGHT_EXEC;\n\tif (prot & PROT_WRITE)\n\t\tvma->perm |= KOBJ_RIGHT_WRITE;\n\tif (prot & PROT_READ)\n\t\tvma->perm |= KOBJ_RIGHT_READ;\nout:\n\treturn kobject_reply_errcode(proc->proc_handle, proto->token, ret);\n}\n\nstatic int get_fault_addr(struct process *proc, unsigned long virt, int *perm)\n{\n\tstruct vma *vma;\n\n\t/*\n\t * check the address is stack or heap or mmap.\n\t */\n\tif ((virt >= proc->brk_start) && (virt < proc->brk_cur)) {\n\t\t*perm = KR_RWX;\n\t\treturn 0;\n\t}\n\n\tvma = &proc->anon_stack_vma;\n\tif ((virt >= vma->start) && (virt < vma->end)) {\n\t\t*perm = vma->perm;\n\t\treturn virt;\n\t}\n\n\tvma = find_vma(proc, virt);\n\tif (!vma || !vma->anon)\n\t\treturn -ENOENT;\n\t*perm = vma->perm;\n\n\treturn 0;\n}\n\nstatic void page_fault_ack(struct process *proc, int ret, long token)\n{\n\t/*\n\t * if the page fault handle is fail the process will\n\t * be killed. otherwise the releated task will be wake\n\t * up.\n\t */\n\tret = (ret == 0) ? 0 : proc->proc_handle;\n\tkobject_reply_errcode(proc->proc_handle, token, ret);\n}\n\nlong handle_user_page_fault(struct process *proc, uint64_t virt_addr,\n\t\tunsigned long info, long token)\n{\n\tunsigned long start = PAGE_ALIGN(virt_addr);\n\tint ret, perm = 0, right = info & KOBJ_RIGHT_MASK;\n\n\tret = get_fault_addr(proc, start, &perm);\n\tif (ret) {\n\t\tpr_err(\"can not get fault address 0x%lx for %d\\n\",\n\t\t\t\tvirt_addr, proc_pid(proc));\n\t\tgoto out;\n\t}\n\n\tif ((right & perm) != right) {\n\t\tret = -EPERM;\n\t\tpr_err(\"P%d page fault 0x%lx %ld\\n\", proc_pid(proc), virt_addr, info);\n\t\tgoto out;\n\t}\n\n\tret = sys_map(proc->proc_handle, -1, start, PAGE_SIZE, perm);\n\tif (ret) {\n\t\tpr_err(\"map memory for process %d at 0x%lxfailed\\n\",\n\t\t\t\tproc_pid(proc), virt_addr);\n\t}\n\nout:\n\tpage_fault_ack(proc, ret, token);\n\treturn ret;;\n}\n\nvoid vspace_init(struct process *proc, unsigned long elf_end)\n{\n\tstruct vma *vma;\n\n\tinit_list(&proc->vma_free);\n\tinit_list(&proc->vma_used);\n\n\tvma = kzalloc(sizeof(struct vma));\n\tif (!vma) {\n\t\tpr_err(\"vma init fail for proc\\n\");\n\t\treturn;\n\t}\n\n\t/*\n\t * mmap region\n\t */\n\tvma->start = PROCESS_MMAP_BOTTOM;\n\tvma->end = PROCESS_MMAP_TOP;\n\tlist_add(&proc->vma_free, &vma->list);\n\n\t/*\n\t * brk region\n\t */\n\tproc->brk_start = PAGE_BALIGN(elf_end);\n\tproc->brk_end = PROCESS_BRK_TOP;\n\tproc->brk_cur = proc->brk_start;\n\tassert(proc->brk_end > proc->brk_start);\n}\n\nstatic int elf_vma_init(struct process *proc, int elf_pma,\n\t\tunsigned long ebase, size_t esize)\n{\n\tstruct vma *vma = &proc->elf_vma;\n\n\tvma->start = ebase;\n\tvma->end = ebase + esize;\n\tvma->anon = 0;\n\tvma->perm = KR_RWX;\n\tvma->pma_handle = elf_pma;\n\n\tif (vma->pma_handle <= 0) {\n\t\tvma->pma_handle = create_pma(PMA_TYPE_NORMAL, vma->perm, 0, esize);\n\t\tif (vma->pma_handle <= 0)\n\t\t\treturn -ENOMEM;\n\t}\n\n\treturn sys_map(proc->proc_handle, vma->pma_handle,\n\t\t\tebase, esize, vma->perm);\n}\n\nstatic int stack_vma_init(struct process *proc)\n{\n\tstruct vma *vma = &proc->init_stack_vma;\n\tint ret;\n\n\tvma->start = PROCESS_STACK_INIT_BASE;\n\tvma->end = PROCESS_STACK_INIT_BASE + PROCESS_STACK_INIT_SIZE;\n\tvma->anon = 0;\n\tvma->perm = KR_RW;\n\n\tvma->pma_handle = create_pma(PMA_TYPE_NORMAL, vma->perm,\n\t\t\t0, PROCESS_STACK_INIT_SIZE);\n\tif (vma->pma_handle <= 0)\n\t\treturn -ENOMEM;\n\n\tret = sys_map(proc->proc_handle, vma->pma_handle,\n\t\t\tPROCESS_STACK_INIT_BASE,\n\t\t\tPROCESS_STACK_INIT_SIZE,\n\t\t\tvma->perm);\n\tif (ret)\n\t\treturn ret;\n\n\tvma = &proc->anon_stack_vma;\n\tvma->start = PROCESS_STACK_BASE;\n\tvma->end = PROCESS_STACK_BASE + (PROCESS_STACK_SIZE -\n\t\t\tPROCESS_STACK_INIT_SIZE);\n\tvma->anon = 1;\n\tvma->perm = KR_RW;\n\n\treturn 0;\n}\n\nint process_mm_init(struct process *proc, int elf_pma,\n\t\tunsigned long elf_base, size_t elf_size)\n{\n\tvspace_init(proc, elf_base + elf_size);\n\n\tif (elf_vma_init(proc, elf_pma, elf_base, elf_size)) {\n\t\tpr_err(\"init elf vma for process failed\\n\");\n\t\treturn -ENOMEM;\n\t}\n\n\tif (stack_vma_init(proc)) {\n\t\tpr_err(\"init stack vma for process failed\\n\");\n\t\treturn -ENOMEM;\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "user.sbin/pangu/src/of.c",
    "content": "/*\n * Copyright (C) 2020 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdio.h>\n#include <string.h>\n#include <inttypes.h>\n#include <errno.h>\n#include <sys/param.h>\n#include <minos/debug.h>\n#include <minos/compiler.h>\n\n#include <libfdt/libfdt.h>\n\n#include <pangu/kmalloc.h>\n#include <pangu/bootarg.h>\n\nvoid *dtb_address;\n\nint of_init_bootargs(void)\n{\n\tvoid *dtb = dtb_address;\n\tint node, len;\n\tconst void *data = NULL;\n\n\tnode = fdt_path_offset(dtb, \"/chosen\");\n\tif (node <= 0)\n\t\treturn -ENOENT;\n\n\tdata = fdt_getprop(dtb, node, \"bootargs\", &len);\n\tif (!data || (len == 0))\n\t\treturn -ENOENT;\n\n\tbootargs_init(data, len);\n\n\treturn 0;\n}\n\nint of_init(unsigned long dtb, unsigned long end)\n{\n\tdtb_address = (void *)dtb;\n\tif (!dtb || fdt_check_header(dtb_address)) {\n\t\tpr_err(\"bad device tree address: %p\\n\", dtb_address);\n\t\treturn -EFAULT;\n\t}\n\n\treturn of_init_bootargs();\n}\n"
  },
  {
    "path": "user.sbin/pangu/src/pangu.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@163.com)\n */\n\n#include <stdio.h>\n#include <unistd.h>\n#include <inttypes.h>\n#include <stdlib.h>\n#include <string.h>\n#include <errno.h>\n#include <sys/mman.h>\n#include <sys/epoll.h>\n#include <assert.h>\n\n#include <minos/kobject.h>\n#include <minos/debug.h>\n#include <minos/list.h>\n#include <minos/proto.h>\n#include <minos/libc.h>\n#include <minos/procinfo.h>\n\n#include <uapi/bootdata.h>\n\n#include <pangu/kmalloc.h>\n#include <pangu/proc.h>\n#include <pangu/bootarg.h>\n\nint proc_epfd;\nint fuxi_handle;\nint nvwa_handle;\nint chiyou_handle;\n\nint setup_mem_handle;\n\nstruct process *rootfs_proc;\nstruct process *nvwa_proc;\nstruct process *chiyou_proc;\nstruct process *fuxi_proc;\n\nunsigned long heap_base, heap_end;\n\nextern void ramdisk_init(unsigned long base, unsigned long end);\nextern void of_init(unsigned long base, unsigned long end);\nextern void pangu_main(void);\nextern void procfs_init(void);\nextern void procinfo_init(int max_proc, int t);\n\nstatic struct bootdata *bootdata;\nstatic char *rootfs_default = \"rootfs.drv\";\n\n#define MAX_EVENT 16\n\nint register_request_entry(int handle, struct process *proc)\n{\n       struct epoll_event event;\n\n       event.events = EPOLLIN | EPOLLKERNEL;\n       event.data.ptr = proc;\n\n       return epoll_ctl(proc_epfd, EPOLL_CTL_ADD, handle, &event);\n}\n\nint unregister_request_entry(int handle, struct process *proc)\n{\n\tstruct epoll_event event;\n\n\tevent.events = EPOLLIN | EPOLLKERNEL;\n\tevent.data.ptr = proc;\n\n\treturn epoll_ctl(proc_epfd, EPOLL_CTL_DEL, handle, &event);\n}\n\nstatic void handle_event(struct epoll_event *event)\n{\n\tstruct process *proc = event->data.ptr;\n\n\tif (!proc) {\n\t\tpr_err(\"invalid process event receive\\n\");\n\t\treturn;\n\t}\n\n\treturn handle_process_request(event, proc);\n}\n\nvoid pangu_main(void)\n{\n\tstruct epoll_event events[MAX_EVENT];\n\tlong ret;\n\tint i;\n\n\t/*\n\t * wake up all the process which created by PanGu itself.\n\t * currently only need to wake up the rootfs driver process.\n\t */\n\twakeup_process(rootfs_proc);\n\n\tfor (;;) {\n\t\tret = epoll_wait(proc_epfd, events, MAX_EVENT, -1);\n\t\tif (ret <= 0 || ret > MAX_EVENT) {\n\t\t\tpr_err(\"failed wait for event try again %ld?\\n\", ret);\n\t\t\tcontinue;\n\t\t}\n\n\t\tfor (i = 0; i < ret; i++)\n\t\t\thandle_event(&events[i]);\n\t}\n}\n\nstatic void get_boot_opt(char *str)\n{\n\tchar *pos, *left, *right;\n\n\tif (!str)\n\t\treturn;\n\n\tpos = strchr(str, '=');\n\tif (pos == NULL)\n\t\treturn;\n\n\tleft = str;\n\tright = pos + 1;\n\t*pos = 0;\n\n\tif (strncmp(left, \"bootdata\", 8) == 0)\n\t\tbootdata = (struct bootdata *)strtol(right, NULL, 16);\n}\n\nstatic void dump_boot_info(void)\n{\n\tpr_info(\"dtb     [0x%lx 0x%lx]\\n\",\n                       bootdata->dtb_start, bootdata->dtb_end);\n\tpr_info(\"ramdisk [0x%lx 0x%lx]\\n\",\n                       bootdata->ramdisk_start, bootdata->ramdisk_end);\n\tpr_info(\"vmap    [0x%lx 0x%lx]\\n\",\n                       bootdata->vmap_start, bootdata->vmap_end);\n\tpr_info(\"heap    [0x%lx 0x%lx]\\n\",\n                       bootdata->heap_start, bootdata->heap_end);\n\n\tpr_info(\"sys max proc %d\\n\", bootdata->max_proc);\n\tpr_info(\"task_stat %d\\n\", bootdata->task_stat_handle);\n}\n\nstatic int start_and_wait_process(const char *name, struct process *proc)\n{\n\tstruct proto proto;\n\tint ret;\n\n\tpr_info(\"Start %s and waitting ...\\n\", name);\n\tkobject_ctl(proc->proc_handle, KOBJ_PROCESS_WAKEUP, 0);\n\n\tfor (;;) {\n\t\tret = kobject_read_simple(proc->proc_handle, &proto,\n\t\t\t\tsizeof(struct proto), 0);\n\t\tif (ret > 0)\n\t\t\tbreak;\n\n\t\tif (ret != -EAGAIN)\n\t\t\tbreak;\n\t}\n\n\tif (ret < 0) {\n\t\tpr_info(\"Get response from %s fail %d\\n\", name, ret);\n\t\treturn ret;\n\t}\n\n\tpr_info(\"Get response from %s service %d\\n\", name, proto.proto_id);\n\tif (proto.proto_id != PROTO_IAMOK)\n\t\treturn -EPROTO;\n\n\tkobject_reply_errcode(proc->proc_handle, ret, 0);\n\n\treturn 0;\n}\n\nstatic int load_nvwa_service(void)\n{\n\tstruct handle_desc hdesc[1];\n\t\n\tnvwa_handle = kobject_create_endpoint(0);\n\tif (nvwa_handle <= 0)\n\t\treturn nvwa_handle;\n\n\thdesc[0].handle = nvwa_handle;\n\thdesc[0].right = KR_R;\n\tnvwa_proc = load_ramdisk_process(\"nvwa.srv\", hdesc, 1, TASK_FLAGS_DRV);\n\tif (nvwa_proc == NULL)\n\t\treturn -ENOMEM;\n\n\tkobject_ctl(nvwa_proc->proc_handle, KOBJ_PROCESS_GRANT_RIGHT, PROC_FLAGS_VMCTL);\n\n\treturn start_and_wait_process(\"nvwa.srv\", nvwa_proc);\n}\n\nstatic int load_chiyou_service(void)\n{\n\tunsigned long pbase;\n\tstruct pma_create_arg args;\n\tstruct handle_desc hdesc[2];\n\tint handle;\n\n\t/*\n\t * chiyou service will handle the dtb or setup\n\t * data, each driver or service will get information\n\t * from it.\n\t */\n\tpbase = sys_mtrans(bootdata->dtb_start);\n\tassert(pbase != -1);\n\n\targs.type = PMA_TYPE_PMEM;\n\targs.consequent = 0;\n\targs.start = pbase;\n\targs.size = bootdata->dtb_end - bootdata->dtb_start;\n\targs.right = KR_RW;\n\tsetup_mem_handle = kobject_create(KOBJ_TYPE_PMA, (unsigned long)&args);\n\tassert(setup_mem_handle > 0);\n\n\thandle = kobject_create_port();\n\tassert(handle > 0);\n\n\thdesc[0].handle = handle;\n\thdesc[0].right = KR_R;\n\thdesc[1].handle = setup_mem_handle;\n\thdesc[1].right = KR_RWCM;\n\n\t/*\n\t * the setup_mem_handle will pass to the chiyou service\n\t * then chiyou service can map it to its address space.\n\t */\n\tchiyou_proc = load_ramdisk_process(\"chiyou.srv\", hdesc, 2, TASK_FLAGS_SRV);\n\tif (!chiyou_proc)\n\t\treturn -ENOMEM;\n\n\tkobject_ctl(chiyou_proc->proc_handle, KOBJ_PROCESS_GRANT_RIGHT,\n\t\t\tPROC_FLAGS_VMCTL | PROC_FLAGS_HWCTL);\n\tchiyou_handle = handle;\n\n\treturn kobject_ctl(chiyou_proc->proc_handle, KOBJ_PROCESS_WAKEUP, 0);\n}\n\nstatic int load_fuxi_service(void)\n{\n\tstruct handle_desc hdesc[1];\n\tint handle;\n\n\t/*\n\t * create the endpoint for fuxi service, that it\n\t * can commuicate with other process, this endpoint\n\t * will grant to fuxi service\n\t */\n\thandle = kobject_create_port();\n\tif (handle <= 0)\n\t\treturn handle;\n\n\thdesc[0].handle = handle;\n\thdesc[0].right = KR_R;\n\n\tfuxi_proc = load_ramdisk_process(\"fuxi.srv\", hdesc, 1, TASK_FLAGS_SRV);\n\tif (fuxi_proc == NULL)\n\t\treturn -ENOMEM;\n\n\tfuxi_handle = handle;\n\n\treturn start_and_wait_process(\"fuxi.srv\", fuxi_proc);\n}\n\nstatic int load_rootfs_driver(void)\n{\n\tchar *path = NULL;\n\tint ret;\n\n\tret = bootarg_parse_string(\"rootfs\", &path);\n\tpath = ret ? rootfs_default : path;\n\trootfs_proc = load_ramdisk_process(path, NULL, 0, TASK_FLAGS_DRV);\n\tif (rootfs_proc == NULL)\n\t\treturn -ENOENT;\n\n\treturn kobject_ctl(rootfs_proc->proc_handle,\n\t\t\tKOBJ_PROCESS_GRANT_RIGHT, PROC_FLAGS_VMCTL);\n}\n\nint main(int argc, char **argv)\n{\n\tint i;\n\n\tprintf(\"\\n\\nPanGu service start...\\n\\n\");\n\n\tfor (i = 0; i < argc; i++)\n\t\tget_boot_opt(argv[i]);\n\n\tif (bootdata == NULL) {\n\t\tpr_err(\"bootdata not found\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\tif (bootdata->magic != BOOTDATA_MAGIC) {\n\t\tpr_err(\"bootdata magic wrong\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\theap_base = bootdata->heap_start;\n\theap_end = bootdata->heap_end;\n\tdump_boot_info();\n\n\tassert(!kmalloc_init(heap_base, heap_end));\n\n\tramdisk_init(bootdata->ramdisk_start, bootdata->ramdisk_end);\n\tof_init(bootdata->dtb_start, bootdata->dtb_end);\n\tprocinfo_init(bootdata->max_proc, bootdata->task_stat_handle);\n\tself_init(0, bootdata->vmap_start, bootdata->vmap_end);\n\n\t/*\n\t * create the epoll fd for pangu, pangu will use this handle\n\t * to handle all the request from other process.\n\t */\n\tproc_epfd = epoll_create(0);\n\tif (proc_epfd < 0) {\n\t\tpr_err(\"can not create epoll fd\\n\");\n\t\texit(-ENOENT);\n\t}\n\n\tassert(!load_fuxi_service());\n\tassert(!load_nvwa_service());\n\tassert(!load_chiyou_service());\n\tassert(!load_rootfs_driver());\n\n\t/*\n\t * setup the rootfs handle, so pangu can use fopen\n\t * related LIBC api\n\t */\n\tlibc_set_rootfs_handle(fuxi_handle);\n\n\tpangu_main();\n\n\treturn -1;\n}\n"
  },
  {
    "path": "user.sbin/pangu/src/process.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n */\n\n#include <stdio.h>\n#include <unistd.h>\n#include <dirent.h>\n#include <inttypes.h>\n#include <stdlib.h>\n#include <string.h>\n#include <errno.h>\n#include <fcntl.h>\n#include <sys/mman.h>\n#include <sys/epoll.h>\n#include <assert.h>\n\n#include <minos/kobject.h>\n#include <minos/debug.h>\n#include <minos/list.h>\n#include <minos/proto.h>\n\n#include <pangu/kmalloc.h>\n#include <pangu/proc.h>\n#include <pangu/ramdisk.h>\n#include <pangu/elf.h>\n#include <pangu/mm.h>\n\nstruct execv_request {\n\tint pma_handle;\n\tchar *name;\n\tstruct process *parent;\n\tuint64_t token;\n\tuint64_t reply_token;\n\tvoid *data;\n\tstruct list_head list;\n};\n\nstruct nvwa_proto {\n\tchar path[FILENAME_MAX];\n\tuint64_t token;\n\tint pma_handle;\n};\n\nstatic LIST_HEAD(execv_request_list);\nstatic char proto_buf[PAGE_SIZE];\nstatic char argv_buf[512];\n\nstatic struct process proc_self;\nstruct process *self = &proc_self;\n\nstatic pid_t init_pid;\n\nstatic LIST_HEAD(user_proc_list);\n\nstatic void release_process(struct process *proc);\n\nstatic int sys_create_process(int pid, unsigned long entry,\n\t\tunsigned long stack, int aff,\n\t\tint prio, unsigned long flags)\n{\n\tstruct process_create_arg args = {\n\t\t.entry = entry,\n\t\t.stack = stack,\n\t\t.aff = aff,\n\t\t.prio = prio,\n\t\t.flags = flags & TASK_FLAGS_KERNEL_MASK,\n\t\t.pid = pid,\n\t};\n\n\treturn kobject_create(KOBJ_TYPE_PROCESS, (unsigned long)&args);\n}\n\nstatic struct process *create_new_process(char *name,\n\t\tstruct process *parent, unsigned long entry,\n\t\tint elf_pma, unsigned long elf_base,\n\t\tsize_t elf_size, int flags)\n{\n\tstruct process *proc;\n\tint pid;\n\n\tpid = alloc_pid();\n\tif (pid < 0)\n\t\treturn NULL;\n\n\tproc = kzalloc(sizeof(struct process));\n\tif (!proc)\n\t\treturn NULL;\n\n\tproc->pid = pid;\n\tproc->flags = flags;\n\tproc->proc_handle = sys_create_process(proc->pid,\n\t\t\tentry, PROCESS_STACK_BASE, -1, -1, flags);\n\tif (proc->proc_handle <= 0) {\n\t\tkfree(proc);\n\t\treturn NULL;\n\t}\n\n\tif (process_mm_init(proc, elf_pma, elf_base, elf_size))\n\t\tgoto err_out;\n\n\tif (name)\n\t\tkobject_ctl(proc->proc_handle, KOBJ_PROCESS_SET_NAME,\n\t\t\t\t(unsigned long)name);\n\t/*\n\t * add the process to the process tree.\n\t */\n\tinit_list(&proc->wait_head);\n\tinit_list(&proc->children);\n\tproc->parent = parent ? parent : self;\n\tlist_add_tail(&parent->children, &proc->clist);\n\n\tif (proc_pid(proc->parent) == init_pid)\n\t\tlist_add_tail(&user_proc_list, &proc->list);\n\n\treturn proc;\n\nerr_out:\n\trelease_process(proc);\n\treturn NULL;\n}\n\n#define NEW_AUX_ENT(auxp, type, value)\t\\\n\tdo {\t\t\t\t\\\n\t\tauxp--;\t\t\t\\\n\t\tauxp->a_type = type;\t\\\n\t\tauxp->a_val = value;\t\\\n\t} while (0)\n\nstatic void *copy_argv_string(void *top, int i, char **argv, char *buf)\n{\n\tint size;\n\n\tsize = strlen(buf) + 1;\n\tsize = BALIGN(size, sizeof(unsigned long));\n\ttop -= size;\n\tstrcpy((char *)top, buf);\n\targv[i] = (char *)top;\n\n\treturn top;\n}\n\nstatic void *set_argv_string(void *top, int i, char **argv,\n\t\tchar *opt, char *arg)\n{\n\tchar buf[256];\n\n\tif (opt)\n\t\tsprintf(buf, \"%s=%s\", opt, arg);\n\telse\n\t\tsprintf(buf, \"%s\", arg);\n\n\treturn copy_argv_string(top, i, argv, buf);\n}\n\nstatic void *setup_envp(void *top)\n{\n\ttop -= sizeof(unsigned long);\n\t*(char **)top = NULL;\n\n\treturn top;\n}\n\nstatic void *setup_argv(void *top, int argc, char **argv)\n{\n\tchar **str = (char **)top;\n\tint i;\n\n\tstr--;\n\t*str = NULL;\n\n\tfor (i = 0; i < argc; i++) {\n\t\tstr--;\n\t\t*str = argv[i];\n\t}\n\n\tstr--;\n\t*(unsigned long *)str = argc;\n\n\treturn (void *)str;\n}\n\n#define NEW_AUX_ENT(auxp, type, value)\t\\\n\tdo {\t\t\t\t\\\n\t\tauxp--;\t\t\t\\\n\t\tauxp->a_type = type;\t\\\n\t\tauxp->a_val = value;\t\\\n\t} while (0)\n\nstatic void *setup_auxv(struct process *proc, void *top, int flags)\n{\n\tElf64_auxv_t *auxp = (Elf64_auxv_t *)top;\n\tint fuxi, chiyou;\n\n\tNEW_AUX_ENT(auxp, AT_NULL, 0);\n\tNEW_AUX_ENT(auxp, AT_PAGESZ, PAGE_SIZE);\n\tNEW_AUX_ENT(auxp, AT_HWCAP, 0);\t\t// TBD cpu feature.\n\n\t/*\n\t * pass the fuxi handle to this process, so it can connect\n\t * to the service center. here will not check the return\n\t * value, libc should check it ?\n\t */\n\tif (fuxi_handle > 0) {\n\t\tfuxi = grant(proc->proc_handle, fuxi_handle, KR_W);\n\t\tif (fuxi <= 0)\n\t\t\tpr_err(\"grant fuxi handle to process fail\\n\");\n\t\telse\n\t\t\tNEW_AUX_ENT(auxp, AT_ROOTFS_HANDLE, fuxi);\n\t}\n\n\tif ((chiyou_handle > 0) && (flags & TASK_FLAGS_DRV)) {\n\t\tchiyou = grant(proc->proc_handle, chiyou_handle, KR_W);\n\t\tif (chiyou <= 0)\n\t\t\tpr_err(\"grant chiyou handle to process fail\\n\");\n\t\telse\n\t\t\tNEW_AUX_ENT(auxp, AT_CHIYOU_HANDLE, chiyou);\n\t}\n\n\treturn (void *)auxp;\n}\n\nstatic void *prepare_process_argv(struct process *proc, char *name,\n\t\tvoid *stack, int *argc, char **argv, char **new_argv)\n{\n\tint i, cnt = *argc;\n\n\t/*\n\t * the final argc will store to the argc, and all the argv\n\t * will store to the new_argv.\n\t */\n\tif (cnt > MAX_ARGC) {\n\t\tpr_err(\"argv is too big %d\\n\", cnt);\n\t\treturn NULL;\n\t}\n\n\t/*\n\t * copy the old argv to the new argv array, and store\n\t * the string to the stack.\n\t */\n\tfor (i = 0; i < cnt; i++)\n\t\tstack = copy_argv_string(stack, i, new_argv, argv[i]);\n\n\t/*\n\t * add process name to the latest argv in the buffer.\n\t */\n\tstack = set_argv_string(stack, cnt++, new_argv, NULL, name);\n\t*argc = cnt;\n\n\treturn stack;\n}\n\nstatic char *file_path_to_proc_name(char *path)\n{\n\tchar *name = strrchr(path, '/');\n\n\tif (name == NULL)\n\t\treturn path;\n\telse\n\t\treturn name + 1;\n}\n\nstatic int setup_process(struct process *proc, char *path,\n\t\tint argc, char **argv, int flags)\n{\n\tstruct vma *stack_vma = &proc->init_stack_vma;\n\tvoid *stack, *origin, *tmp;\n\tchar **new_argv;\n\tint i, ret = 0;\n\tchar *name;\n\n\tif (argc > MAX_ARGC) {\n\t\tpr_warn(\"argv is too long %d\\n\", argc);\n\t\treturn -ENOSPC;\n\t}\n\n\tnew_argv = (char **)get_page();\n\tif (!new_argv)\n\t\treturn -ENOMEM;\n\n\ttmp = stack = map_self_memory(stack_vma->pma_handle,\n\t\t\tPROCESS_STACK_INIT_SIZE, KOBJ_RIGHT_RW);\n\tif (!stack) {\n\t\tret = -ENOMEM;\n\t\tgoto err_map_stack_mem;\n\t}\n\n\tstack += PROCESS_STACK_INIT_SIZE;\n\torigin = stack;\n\n\tname = file_path_to_proc_name(path);\n\tstack = prepare_process_argv(proc, name, stack, &argc, argv, new_argv);\n\tif (stack == NULL) {\n\t\tret = -ENOMEM;\n\t\tgoto err_setup_argv;\n\t}\n\n\t/*\n\t * convert the memory address of argv to the process's\n\t * stack address.\n\t */\n\tfor (i = 0; i < argc; i++) {\n\t\tnew_argv[i] = (char *)PROCESS_STACK_TOP -\n\t\t\t((char *)origin - new_argv[i]);\n\t\tpr_debug(\"argv address is %p\\n\", new_argv[i]);\n\t}\n\n\tstack = setup_auxv(proc, stack, proc->flags);\n\tstack = setup_envp(stack);\n\tstack = setup_argv(stack, argc, new_argv);\n\n\t/*\n\t * update the new stack pointer for the process.\n\t */\n\tkobject_ctl(proc->proc_handle, KOBJ_PROCESS_SETUP_SP,\n\t\t\tPROCESS_STACK_TOP - (origin - stack));\n\nerr_setup_argv:\n\tunmap_self_memory(tmp);\nerr_map_stack_mem:\n\tfree_pages(new_argv);\n\n\treturn ret;\n}\n\nstatic int setup_process_handles(struct process *proc, char *buf,\n\t\tstruct handle_desc *hdesc, int num_handle)\n{\n\tint *htarget;\n\tchar *tmp;\n\tint i, size;\n\n\tif (num_handle <= 0 || !hdesc)\n\t\treturn 0;\n\n\thtarget = kzalloc(sizeof(int) * num_handle);\n\tif (!htarget)\n\t\treturn -ENOMEM;\n\n\tfor (i = 0; i < num_handle; i++) {\n\t\thtarget[i] = grant(proc->proc_handle,\n\t\t\t\thdesc[i].handle, hdesc[i].right);\n\t\tif (htarget[i] <= 0) {\n\t\t\tpr_err(\"grant %d to process failed\\n\", hdesc[i].handle);\n\t\t}\n\t}\n\n\tsize = sprintf(buf, \"%s\", \"handle@\");\n\ttmp = buf + size;\n\n\tfor (i = 0; i < num_handle; i++) {\n\t\tif (i == (num_handle - 1))\n\t\t\tsize = sprintf(tmp, \"%d\", htarget[i]);\n\t\telse\n\t\t\tsize = sprintf(tmp, \"%d,\", htarget[i]);\n\t\ttmp += size;\n\t}\n\n\t*tmp = 0;\n\tkfree(htarget);\n\n\treturn 1;\n}\n\nstruct process *load_ramdisk_process(char *path,\n\t\tstruct handle_desc *hdesc,\n\t\tint num_handle, int flags)\n{\n\tstruct process *proc;\n\tstruct ramdisk_file rfile;\n\tstruct elf_ctx ctx;\n\tchar *argv[2] = {argv_buf, NULL};\n\tint ret;\n\n\tret = ramdisk_open(path, &rfile);\n\tif (ret) {\n\t\tpr_err(\"can not find %s in ramdisk\\n\", path);\n\t\treturn NULL;\n\t}\n\n\tret = elf_init_ramdisk(&ctx, &rfile);\n\tif (ret)\n\t\treturn NULL;\n\n\tproc = create_new_process(path, self, ctx.ehdr.e_entry, 0,\n\t\t\tctx.base_load_vbase, ctx.memsz, flags);\n\tif (!proc)\n\t\treturn NULL;\n\n\tret = load_process_from_ramdisk(proc, &ctx, &rfile);\n\tif (ret) {\n\t\trelease_process(proc);\n\t\treturn NULL;\n\t}\n\n\t/*\n\t * all the resource is ok now, setup the process\n\t * to prepare run it. before setup the argv, need to pass\n\t * the handle to the process, which are needed for this\n\t * process.\n\t */\n\tret = setup_process_handles(proc, argv_buf, hdesc, num_handle);\n\tif (ret < 0) {\n\t\tpr_err(\"setup process handles fail\\n\");\n\t\tgoto out_err;\n\t}\n\n\tret = setup_process(proc, path, ret, argv, proc->flags);\n\tif (ret) {\n\t\tpr_err(\"set up process failed\\n\");\n\t\tgoto out_err;\n\t}\n\n\t/*\n\t * keep this action as the latest step.\n\t */\n\tret = register_request_entry(proc->proc_handle, proc);\n\tif (ret) {\n\t\tpr_err(\"listen to process failed\\n\");\n\t\tgoto out_err;\n\t}\n\n\treturn proc;\n\nout_err:\n\trelease_process(proc);\n\treturn NULL;\n}\n\nvoid wakeup_process(struct process *proc)\n{\n\tkobject_ctl(proc->proc_handle, KOBJ_PROCESS_WAKEUP, 0);\n}\n\nvoid self_init(int proc_handle, unsigned long vma_base, unsigned long vma_end)\n{\n\t/*\n\t * init the root service\n\t */\n\tstruct vma *vma;\n\n\tself->pid = alloc_pid();\n\tassert(self->pid == 1);\n\n\tinit_list(&self->vma_free);\n\tinit_list(&self->vma_used);\n\tinit_list(&self->children);\n\tinit_list(&self->wait_head);\n\tself->proc_handle = proc_handle;\n\n\tvma = kzalloc(sizeof(struct vma));\n\tif (!vma)\n\t\texit(-ENOMEM);\n\n\tvma->start = vma_base;\n\tvma->end = vma_end;\n\tlist_add(&self->vma_free, &vma->list);\n}\n\nstatic void proc_mm_deinit(struct process *proc)\n{\n\tstruct vma *vma, *tmp;\n\n\tlist_for_each_entry_safe(vma, tmp, &proc->vma_free, list) {\n\t\tlist_del(&vma->list);\n\t\tkfree(vma);\n\t}\n\n\tlist_for_each_entry_safe(vma, tmp, &proc->vma_used, list) {\n\t\tlist_del(&vma->list);\n\t\tkfree(vma);\n\t}\n\n\tkobject_close(proc->elf_vma.pma_handle);\n\tkobject_close(proc->init_stack_vma.pma_handle);\n}\n\nstatic void finish_wait(struct process * proc, long data0)\n{\n\tstruct process *parent = proc->parent;\n\tstruct wait_entry *entry, *tmp;\n\n\t/*\n\t * wake up the task which waitting for this proc.\n\t */\n\tlist_for_each_entry_safe(entry, tmp, &parent->wait_head, list) {\n\t\tif ((entry->type == PROC_WAIT_ANY) ||\n\t\t\t\t(entry->pid == proc->pid)) {\n\t\t\tlist_del(&entry->list);\n\t\t\tkobject_reply_errcode(parent->proc_handle,\n\t\t\t\t\tentry->token, proc->pid);\n\t\t\tkfree(entry);\n\t\t}\n\t}\n\n\t/*\n\t * release the wait entry which the proc wait.\n\t */\n\tlist_for_each_entry_safe(entry, tmp, &proc->wait_head, list) {\n\t\tlist_del(&entry->list);\n\t\tkfree(entry);\n\t}\n}\n\nstatic void deal_with_child_process(struct process *proc)\n{\n\tstruct process *parent = proc->parent;\n\tstruct process *child, *tmp;\n\n\tlist_for_each_entry_safe(child, tmp, &proc->children, clist) {\n\t\tlist_del(&child->clist);\n\t\tlist_add_tail(&parent->children, &child->clist);\n\t\tchild->parent = parent;\n\t}\n}\n\nstatic void __release_process(struct process *proc)\n{\n\tint proc_handle;\n\n\tif (!proc)\n\t\treturn;\n\n\tproc_handle = proc->proc_handle;\n\tunregister_request_entry(proc_handle, proc);\n\tproc_mm_deinit(proc);\n\trelease_pid(proc->pid);\n\tkfree(proc);\n\n\t/*\n\t * if the process is killed by pangu process, the kernel\n\t * will call kobject_put, and will not get the event when\n\t * kernel release the process.\n\t */\n\tif (proc_handle > 0)\n\t\tkobject_close(proc_handle);\n}\n\nstatic void release_process(struct process *proc)\n{\n\treturn __release_process(proc);\n}\n\nstatic void handle_init_process_exit(struct process *proc)\n{\n\t/*\n\t * if the init process exit(), system will reboot.\n\t */\n\tpr_err(\"init process exit, reboot system\\n\");\n\texit(-1);\n}\n\nstatic long handle_process_exit(struct process *proc, uint64_t data0)\n{\n\t/*\n\t * if the init process was exited, kill all the process and\n\t * then relaunch the init process.\n\t */\n\tif (proc_pid(proc) == init_pid) {\n\t\thandle_init_process_exit(proc);\n\t} else {\n\t\tfinish_wait(proc, data0);\n\t\tdeal_with_child_process(proc);\n\t}\n\n\trelease_process(proc);\n\n\treturn 0;\n}\n\nstatic inline int execv_argv_is_ok(char *argv, int max_size)\n{\n\tint i;\n\n\tfor (i = 0; i < max_size; i++) {\n\t\tif (argv[i] == 0)\n\t\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n\nstatic inline struct execv_request *alloc_execv_request(void *data)\n{\n\tstruct execv_request *er;\n\n\ter = kzalloc(sizeof(struct execv_request));\n\tif (!er)\n\t\treturn NULL;\n\n\ter->data = get_pages(1);\n\tif (!er->data) {\n\t\tkfree(er);\n\t\treturn NULL;\n\t}\n\n\tmemcpy(er->data, data, PAGE_SIZE);\n\n\treturn er;\n}\n\nstatic inline void free_execv_request(struct execv_request *er)\n{\n\tfree_pages(er->data);\n\tfree(er);\n}\n\nstatic int send_elf_load_request(struct process *proc, const char *path, struct execv_request *er)\n{\n\tstruct nvwa_proto proto;\n\tstatic uint64_t nvwa_token = 0;\n\tint ret;\n\n\t/*\n\t * create an empty PMA handle for the target process, then\n\t * grant the pma handle to the nvwa process, so that nvwa\n\t * can allocate memory for the elf file.\n\t */\n\ter->pma_handle = create_pma(PMA_TYPE_NORMAL, KR_RWX, 0, 0);\n\tif (er->pma_handle <= 0)\n\t\treturn er->pma_handle;\n\n\tproto.pma_handle = grant(nvwa_proc->proc_handle, er->pma_handle, KR_RWC);\n\tif (proto.pma_handle <= 0) {\n\t\tkobject_close(er->pma_handle);\n\t\treturn proto.pma_handle;\n\t}\n\n\tstrcpy(proto.path, path);\n\ter->parent = proc;\n\ter->token = proto.token = nvwa_token++;\n\n\tret = kobject_write(nvwa_handle, &proto,\n\t\t\tsizeof(struct nvwa_proto), NULL, 0, 2000);\n\tif (ret == 0)\n\t\tlist_add_tail(&execv_request_list, &er->list);\n\n\treturn ret;\n}\n\nstatic long pangu_execv(struct process *proc, struct proto *proto, void *data)\n{\n\tstruct execv_extra *extra = data;\n\tint *argv_off = extra->argv;\n\tstruct execv_request *er;\n\tunsigned long limit;\n\tint i, ret = -EINVAL;\n\tchar *string;\n\n\tlimit = PAGE_SIZE - sizeof(struct execv_extra);\n\tstring = extra->buf;\n\textra->path[FILENAME_MAX - 1] = 0;\n\n\tfor (i = 0; i < extra->argc; i++) {\n\t\tif (argv_off[i] >= limit)\n\t\t\tgoto out;\n\t\tif (!execv_argv_is_ok(string + argv_off[i], limit - argv_off[i]))\n\t\t\tgoto out;\n\t}\n\n\t/*\n\t * the execv value is correct, then send the elf load\n\t * request to nvwa process.\n\t */\n\ter = alloc_execv_request(data);\n\tif (!er) {\n\t\tret = -ENOMEM;\n\t\tgoto out;\n\t}\n\n\t/*\n\t * copy the reply token, so after the elf image has\n\t * been loaded, can be reply to the task correctly.\n\t */\n\ter->reply_token = proto->token;\n\n\tret = send_elf_load_request(proc, extra->path, er);\n\tif (ret)\n\t\tgoto out_release_er;\n\n\treturn 0;\n\nout_release_er:\n\tfree_execv_request(er);\nout:\n\treturn kobject_reply_errcode(proc->proc_handle, proto->token, ret);\n}\n\nstatic void load_init_process(void)\n{\n\tstruct execv_extra *extra = (struct execv_extra *)proto_buf;\n\tstruct proto proto;\n\n\tmemset(&proto, 0, sizeof(struct proto));\n\tmemset(extra, 0, sizeof(struct execv_extra));\n\tpr_info(\"loading init shell.app ...\\n\");\n\tstrcpy(extra->path, \"/c/bin/shell.app\");\n\n\tassert(!pangu_execv(self, &proto, extra));\n}\n\nstatic void notify_chiyou_service(void)\n{\n\tstruct proto proto;\n\n\tproto.proto_id = PROTO_ROOTFS_READY;\n\tkobject_write(chiyou_handle, &proto, sizeof(struct proto), NULL, 0, -1);\n}\n\nstatic long pangu_iamok(struct process *proc, struct proto *proto, void *data)\n{\n\t/*\n\t * start the init process, current start the shell process.\n\t */\n\tif (proc == rootfs_proc) {\n\t\tload_init_process();\n\t\tnotify_chiyou_service();\n\t}\n\n\treturn kobject_reply_errcode(proc->proc_handle, proto->token, 0);\n}\n\nstatic void handle_process_kernel_request(struct process *proc, struct epoll_event *event)\n{\n\tswitch (event->data.type) {\n\tcase EPOLL_KEV_PAGE_FAULT:\n\t\thandle_user_page_fault(proc, event->data.data0,\n\t\t\t\t(unsigned long)event->data.data1,\n\t\t\t\t(long)event->data.data2);\n\t\tbreak;\n\tcase EPOLL_KEV_PROCESS_EXIT:\n\t\thandle_process_exit(proc, event->data.data0);\n\t\tbreak;\n\tdefault:\n\t\tpr_err(\"unknown request from kernel %d\\n\", event->data.type);\n\t\tbreak;\n\t}\n}\n\nstatic int __do_execv(struct proto *proto, struct execv_request *er)\n{\n\tstruct execv_extra *extra = er->data;\n\tint i, ret = -EINVAL, flags;\n\tstruct process *new;\n\tchar *string;\n\tchar **argv;\n\n\targv = kzalloc(sizeof(char *) * extra->argc);\n\tif (!argv)\n\t\treturn -ENOMEM;\n\n\t/*\n\t * only chiyou service can load the driver process\n\t * now.\n\t */\n\tflags = extra->flags;\n\tif (er->parent != chiyou_proc)\n\t\tflags &= ~TASK_FLAGS_DRV;\n\n\t/*\n\t * do not need to check again, since these content\n\t * has been checked in handle execv function.\n\t */\n\tstring = extra->buf;\n\tfor (i = 0; i < extra->argc; i++) {\n\t\targv[i] = string + (unsigned long)argv[i];\n\t\tpr_debug(\"argv %d is 0x%p\\n\", i, argv[i]);\n\t}\n\n\tnew = create_new_process(extra->path, er->parent, proto->elf_info.entry,\n\t\t\ter->pma_handle, proto->elf_info.elf_base,\n\t\t\tproto->elf_info.elf_size, flags);\n\tif (!new)\n\t\treturn -ENOMEM;\n\n\tret = setup_process(new, extra->path, extra->argc, argv, flags);\n\tif (ret) {\n\t\trelease_process(new);\n\t\treturn ret;\n\t}\n\n\tregister_request_entry(new->proc_handle, new);\n\twakeup_process(new);\n\tkfree(argv);\n\n\treturn new->pid;\n}\n\nstatic int do_execv(struct proto *proto, struct execv_request *er)\n{\n\tint ret = __do_execv(proto, er);\n\n\t/*\n\t * pangu will launch the init process only, so record\n\t * the pid of the init process, once the init process\n\t * is died, launched it again.\n\t */\n\tif (er->parent == self) {\n\t\tinit_pid = ret;\n\t\treturn 0;\n\t}\n\n\treturn kobject_reply_errcode(er->parent->proc_handle, er->reply_token, ret);\n}\n\nstatic long pangu_elf_info(struct process *proc, struct proto *proto, void *data)\n{\n\tstruct execv_request *er, *next;\n\n\t/*\n\t * reply nvwa service.\n\t */\n\tif (proc != nvwa_proc) {\n\t\tpr_err(\"not nvwa proc\\n\");\n\t\treturn kobject_reply_errcode(proc->proc_handle, proto->token, -EPERM);\n\t} else {\n\t\tkobject_reply_errcode(proc->proc_handle, proto->token, 0);\n\t}\n\n\t/*\n\t * do handle the execv request.\n\t */\n\tlist_for_each_entry_safe(er, next, &execv_request_list, list) {\n\t\tif (er->token != proto->elf_info.token)\n\t\t\tcontinue;\n\n\t\tlist_del(&er->list);\n\t\tif (proto->elf_info.ret_code != 0) {\n\t\t\tpr_err(\"nvwa load elf failed\\n\");\n\t\t\tkobject_reply_errcode(er->parent->proc_handle,\n\t\t\t\t\ter->reply_token, proto->elf_info.ret_code);\n\t\t\treturn -EPERM;\n\t\t}\n\n\t\treturn do_execv(proto, er);\n\t}\n\n\tpr_err(\"handle_nvwa_request fail no such request\\n\");\n\treturn -ENOENT;\n}\n\nstatic long pangu_waitpid(struct process *proc, struct proto *proto, void *data)\n{\n\tint pid = proto->waitpid.pid;\n\tstruct process *child;\n\tstruct wait_entry *we;\n\tint found = 0;\n\tint ret;\n\n\tif ((pid != -1) && (pid <= 0)) {\n\t\tpr_err(\"waitpid do not support such mode\\n\");\n\t\tret = -ENOENT;\n\t\tgoto fail;\n\t}\n\n\tif (pid > 0) {\n\t\tlist_for_each_entry(child, &proc->children, clist) {\n\t\t\tif (child->pid == pid) {\n\t\t\t\tfound = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!found) {\n\t\tret = -ENOENT;\n\t\tgoto fail;\n\t}\n\n\twe = kzalloc(sizeof(struct wait_entry));\n\tif (!we) {\n\t\tret = - ENOMEM;\n\t\tgoto fail;\n\t}\n\n\twe->type = (pid == -1) ? PROC_WAIT_ANY : PROC_WAIT_PID;\n\twe->pid = pid;\n\twe->token = proto->token;\n\tlist_add_tail(&proc->wait_head, &we->list);\n\n\treturn 0;\nfail:\n\treturn kobject_reply_errcode(proc->proc_handle, proto->token, ret);\n}\n\nstatic syscall_hdl proc_syscall_handles[] = {\n\t[0 ... PROTO_PROC_ID_MAX] = NULL,\n\t[PROTO_IAMOK_ID]\t= pangu_iamok,\n\t[PROTO_ELF_INFO_ID]\t= pangu_elf_info,\n\t[PROTO_MMAP_ID]\t\t= pangu_mmap,\n\t[PROTO_EXECV_ID]\t= pangu_execv,\n\t[PROTO_BRK_ID]\t\t= pangu_brk,\n\t[PROTO_PROCCNT_ID]\t= pangu_proccnt,\n\t[PROTO_TASKSTAT_ID]\t= pangu_taskstat,\n\t[PROTO_MPROTECT_ID]\t= pangu_mprotect,\n\t[PROTO_WAITPID_ID]\t= pangu_waitpid,\n};\n\nstatic void handle_process_in_request(struct process *proc, struct epoll_event *event)\n{\n\tstruct proto proto;\n\tlong ret;\n\n\tret = sys_read_proto(proc->proc_handle, &proto, proto_buf, PAGE_SIZE, 0);\n\tif (ret < 0)\n\t\treturn;\n\n\tif ((proto.proto_id >= PROTO_PANGU_END) ||\n\t\t\t!proc_syscall_handles[proto.proto_id - PROTO_IAMOK]) {\n\t\tkobject_reply_errcode(proc->proc_handle, proto.token, -ENOSYS);\n\t\treturn;\n\t}\n\n\tret = proc_syscall_handles[proto.proto_id - PROTO_IAMOK](proc, &proto, proto_buf);\n\tif (ret)\n\t\tpr_err(\"handle syscall failed with %ld\\n\", ret);\n}\n\nvoid handle_process_request(struct epoll_event *event, struct process *proc)\n{\n\tswitch (event->events) {\n\tcase EPOLLIN:\n\t\thandle_process_in_request(proc, event);\n\t\tbreak;\n\tcase EPOLLKERNEL:\n\t\thandle_process_kernel_request(proc, event);\n\t\tbreak;\n\tdefault:\n\t\tpr_err(\"invalid event for process\\n\");\n\t\tbreak;\n\t}\n}\n"
  },
  {
    "path": "user.sbin/pangu/src/procinfo.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n */\n\n#include <stdio.h>\n#include <unistd.h>\n#include <dirent.h>\n#include <inttypes.h>\n#include <stdlib.h>\n#include <string.h>\n#include <errno.h>\n#include <fcntl.h>\n#include <sys/mman.h>\n#include <sys/epoll.h>\n#include <assert.h>\n\n#include <minos/kobject.h>\n#include <minos/types.h>\n#include <minos/debug.h>\n#include <minos/list.h>\n#include <minos/procinfo.h>\n#include <minos/proto.h>\n\n#include <pangu/kmalloc.h>\n#include <pangu/proc.h>\n#include <pangu/mm.h>\n#include <pangu/bootarg.h>\n\nstatic uint32_t proc_cnt;\nstatic unsigned char *bitmap;\nstatic int proc_bytes;\n\nstatic int ktask_stat_handle;\n\nint8_t const ffs_one_table[256] = { \n        -1, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x00 to 0x0F */\n        4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x10 to 0x1F */\n        5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x20 to 0x2F */\n        4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x30 to 0x3F */\n        6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x40 to 0x4F */\n        4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x50 to 0x5F */\n        5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x60 to 0x6F */\n        4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x70 to 0x7F */\n        7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x80 to 0x8F */\n        4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x90 to 0x9F */\n        5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xA0 to 0xAF */\n        4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xB0 to 0xBF */\n        6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xC0 to 0xCF */\n        4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xD0 to 0xDF */\n        5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xE0 to 0xEF */\n        4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0  /* 0xF0 to 0xFF */\n};\n\nint alloc_pid(void)\n{\n\tint i, j;\n\n\tfor (i = 0; i < proc_bytes; i++) {\n\t\tif (bitmap[i] == 0)\n\t\t\tcontinue;\n\n\t\tj = ffs_one_table[bitmap[i]];\n\t\tbitmap[i] &= ~(1 << j);\n\n\t\treturn (i * 8 + j);\n\t}\n\n\treturn -1;\n}\n\nvoid procinfo_init(int max_proc, int ktask_handle)\n{\n\tproc_cnt = max_proc;\n\tktask_stat_handle = ktask_handle;\n\tproc_bytes = proc_cnt / 8;\n\n\tbitmap = kmalloc(proc_bytes);\n\tassert(bitmap != NULL);\n\tmemset(bitmap, 0xff, proc_bytes);\n\n\t/*\n\t * PID 0 is for kernel.\n\t */\n\tassert(alloc_pid() == 0);\n}\n\nvoid release_pid(int pid)\n{\n\tint i = pid / 8;\n\tint j = pid % 8;\n\n\tbitmap[i] |= (1 << j);\n}\n\nlong pangu_taskstat(struct process *proc, struct proto *proto, void *data)\n{\n\treturn kobject_reply_handle(proc->proc_handle,\n\t\t\tproto->token, ktask_stat_handle, KR_RM);\n}\n\nlong pangu_proccnt(struct process *proc, struct proto *proto, void *data)\n{\n\treturn kobject_reply_errcode(proc->proc_handle, proto->token, proc_cnt);\n}\n"
  },
  {
    "path": "user.sbin/pangu/src/ramdisk.c",
    "content": "/*\n * Copyright (C) 2021 Min Le (lemin9538@gmail.com)\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdio.h>\n#include <unistd.h>\n#include <inttypes.h>\n#include <stdlib.h>\n#include <string.h>\n#include <errno.h>\n#include <minos/debug.h>\n\n#include <uapi/ramdisk.h>\n\nstatic void *ramdisk_start, *ramdisk_end;\nstatic struct ramdisk_inode *root;\nstatic struct ramdisk_sb *sb;\nstatic void *ramdisk_data;\n\nint ramdisk_init(unsigned long start, unsigned long end)\n{\n\tramdisk_start = (void *)start;\n\tramdisk_end = (void *)end;\n\n\tif (!ramdisk_start || !ramdisk_end) {\n\t\tpr_err(\"ramdisk address is not set\\n\");\n\t\treturn -EINVAL;\n\t}\n\n\tif (strncmp(ramdisk_start, RAMDISK_MAGIC, RAMDISK_MAGIC_SIZE) != 0) {\n\t\tpr_err(\"bad ramdisk format\\n\");\n\t\treturn -EBADF;\n\t}\n\n\t/*\n\t * the ramdisk is read only, init the ramdisk\n\t * information, inclue the superblock and the\n\t * root inode\n\t */\n\tsb = ramdisk_start + RAMDISK_MAGIC_SIZE;\n\troot = ramdisk_start + sb->inode_offset;\n\tramdisk_data = ramdisk_start + sb->data_offset;\n\n\treturn 0;\n}\n\nstatic struct ramdisk_inode *get_file_inode(const char *name)\n{\n\tstruct ramdisk_inode *inode;\n\n\tfor (inode = root; inode < root + sb->file_cnt; inode++) {\n\t\tif (strncmp(inode->f_name, name, RAMDISK_FNAME_SIZE - 1) == 0)\n\t\t\treturn inode;\n\t}\n\n\treturn NULL;\n}\n\nint ramdisk_read(struct ramdisk_file *file, void *buf,\n\t\tsize_t size, unsigned long offset)\n{\n\tif (!file)\n\t\treturn -EINVAL;\n\n\tif ((offset + size) > file->inode->f_size)\n\t\treturn -EINVAL;\n\n\tmemcpy(buf, ramdisk_data + file->inode->f_offset + offset, size);\n\treturn 0;\n}\n\nint ramdisk_open(char *name, struct ramdisk_file *file)\n{\n\tstruct ramdisk_inode *inode;\n\n\tif (!sb) {\n\t\tpr_debug(\"super block not found\\n\");\n\t\treturn -ENOENT;\n\t}\n\n\tinode = get_file_inode(name);\n\tif (!inode)\n\t\treturn -ENOENT;\n\n\tmemset(file, 0, sizeof(struct ramdisk_file));\n\tfile->inode = inode;\n\n\treturn 0;\n}\n"
  }
]