From 4e09bca9e34c226b6d7e34b4fa11248405fd988e Mon Sep 17 00:00:00 2001 From: Anton Kling Date: Sun, 22 Oct 2023 19:50:38 +0200 Subject: Move everything into a new repo. --- .clang-format | 1 + .gitignore | 26 + COPYING | 674 + LICENSE | 14 + Makefile | 33 + README.md | 35 + arch/i386/boot.s | 128 + arch/i386/mmu.c | 565 + cpu/gdt.c | 72 + cpu/gdt.h | 76 + cpu/idt.c | 265 + cpu/idt.h | 76 + cpu/int_syscall.s | 20 + cpu/io.h | 11 + cpu/io.s | 121 + cpu/reload_gdt.s | 17 + cpu/spinlock.c | 2 + cpu/spinlock.h | 5 + cpu/syscall.c | 174 + cpu/syscall.h | 59 + crypto/ChaCha20/chacha20.c | 29 + crypto/ChaCha20/chacha20.h | 15 + crypto/SHA1 | 1 + drivers/ata.c | 253 + drivers/ata.h | 16 + drivers/keyboard.c | 188 + drivers/keyboard.h | 11 + drivers/mouse.c | 144 + drivers/mouse.h | 5 + drivers/pit.c | 55 + drivers/pit.h | 12 + drivers/pst.c | 17 + drivers/pst.h | 7 + drivers/serial.c | 35 + drivers/serial.h | 2 + drivers/vbe.c | 50 + drivers/vbe.h | 7 + elf.c | 73 + elf.h | 99 + fs/devfs.c | 91 + fs/devfs.h | 26 + fs/ext2.c | 633 + fs/ext2.h | 139 + fs/fifo.c | 97 + fs/fifo.h | 26 + fs/shm.c | 98 + fs/shm.h | 13 + fs/tmpfs.c | 94 + fs/tmpfs.h | 16 + fs/vfs.c | 272 + fs/vfs.h | 94 + halts.c | 102 + halts.h | 21 + hashmap | 1 + includes/defs.h | 5 + includes/mmu.h | 61 + includes/sys/types.h | 2 + init/kernel.c | 101 + isodir/boot/grub/grub.cfg | 3 + kmalloc.c | 233 + kmalloc.h | 21 + ksbrk.c | 40 + ksbrk.h | 8 + kubsan.c | 58 + kubsan.h | 79 + libc/exit/assert.c | 12 + libc/include/assert.h | 19 + libc/include/errno.h | 85 + libc/include/limits.h | 1 + libc/include/stdio.h | 9 + libc/include/stdlib.h | 0 libc/include/string.h | 19 + libc/include/time.h | 6 + libc/include/types.h | 27 + libc/stdio/print.c | 97 + libc/string/copy.c | 26 + libc/string/isequal.c | 15 + libc/string/memcmp.c | 12 + libc/string/memcpy.c | 11 + libc/string/memset.c | 9 + libc/string/strcat.c | 6 + libc/string/strcmp.c | 8 + libc/string/strcpy.c | 8 + libc/string/strlcpy.c | 21 + libc/string/strlen.c | 8 + libc/string/strncpy.c | 11 + linker.ld | 41 + log.c | 40 + log.h | 10 + mount/cat | 1 + mount/init | 1 + mount/pid1 | Bin 0 -> 2396 bytes mount/program | Bin 0 -> 1744 bytes mount/sh | Bin 0 -> 45660 bytes multiboot.h | 243 + new.sh | 3 + poll.c | 54 + poll.h | 15 + process.s | 33 + random.c | 142 + random.h | 7 + read_eip.s | 5 + scalls/accept.c | 5 + scalls/accept.h | 9 + scalls/bind.c | 5 + scalls/bind.h | 9 + scalls/clock_gettime.c | 10 + scalls/clock_gettime.h | 8 + scalls/mmap.c | 7 + scalls/mmap.h | 13 + scalls/msleep.c | 9 + scalls/msleep.h | 5 + scalls/ppoll.c | 11 + scalls/ppoll.h | 9 + scalls/shm.c | 10 + scalls/shm.h | 20 + scalls/socket.c | 5 + scalls/socket.h | 9 + scalls/stat.c | 13 + scalls/stat.h | 33 + scalls/uptime.c | 4 + scalls/uptime.h | 2 + sched/scheduler.c | 388 + sched/scheduler.h | 60 + socket.c | 148 + socket.h | 66 + sync.sh | 137 + time.h | 10 + toolchain/3A24BC1E8FB409FA9F14371813FCEF89DD9E3C4F | 38 + toolchain/binutils-2.40.diff | 12573 +++++++++++++++++++ toolchain/build-binutils.sh | 13 + toolchain/build-gcc.sh | 13 + toolchain/download-binutils.sh | 2 + toolchain/download-gcc.sh | 2 + toolchain/download.sh | 9 + toolchain/gcc-13.1.0.diff | 142 + toolchain/get-keys.sh | 3 + userland/ante/Makefile | 15 + userland/ante/ante.c | 296 + userland/cat/Makefile | 10 + userland/cat/cat | Bin 0 -> 33852 bytes userland/cat/cat.c | 24 + userland/init/Makefile | 10 + userland/init/crt0_old.c | 12 + userland/init/init | Bin 0 -> 31476 bytes userland/init/init.c | 15 + userland/json/Makefile | 18 + userland/json/hashmap | 1 + userland/json/json.c | 360 + userland/json/json.h | 39 + userland/json/libjson.a | Bin 0 -> 6304 bytes userland/libc/Makefile | 26 + userland/libc/arpa/inet.h | 4 + userland/libc/arpa/inet/htonl.c | 11 + userland/libc/arpa/inet/htons.c | 10 + userland/libc/assert.c | 9 + userland/libc/assert.h | 10 + userland/libc/crt0.s | 13 + userland/libc/ctype.h | 12 + userland/libc/ctype/isalnum.c | 6 + userland/libc/ctype/isalpha.c | 4 + userland/libc/ctype/isascii.c | 4 + userland/libc/ctype/isdigit.c | 6 + userland/libc/ctype/isprint.c | 3 + userland/libc/ctype/ispunct.c | 6 + userland/libc/ctype/isxdigit.c | 6 + userland/libc/ctype/tolower.c | 7 + userland/libc/ctype/toupper.c | 7 + userland/libc/dirent.h | 28 + userland/libc/dirent/alphasort.c | 7 + userland/libc/dirent/closedir.c | 7 + userland/libc/dirent/opendir.c | 11 + userland/libc/dirent/readdir.c | 14 + userland/libc/dirent/scandir.c | 43 + userland/libc/endian.h | 2 + userland/libc/errno.h | 87 + userland/libc/fcntl.h | 10 + userland/libc/include/arpa/inet.h | 0 userland/libc/include/assert.h | 10 + userland/libc/include/byteswap.h | 0 userland/libc/include/ctype.h | 14 + userland/libc/include/dirent.h | 28 + userland/libc/include/endian.h | 2 + userland/libc/include/err.h | 0 userland/libc/include/errno.h | 87 + userland/libc/include/fcntl.h | 12 + userland/libc/include/fnmatch.h | 0 userland/libc/include/glob.h | 10 + userland/libc/include/grp.h | 0 userland/libc/include/input.h | 9 + userland/libc/include/inttypes.h | 19 + userland/libc/include/langinfo.h | 0 userland/libc/include/libgen.h | 6 + userland/libc/include/limits.h | 4 + userland/libc/include/locale.h | 0 userland/libc/include/math.h | 0 userland/libc/include/net/if.h | 0 userland/libc/include/netdb.h | 0 userland/libc/include/netinet/in.h | 0 userland/libc/include/netinet/tcp.h | 0 userland/libc/include/paths.h | 0 userland/libc/include/poll.h | 17 + userland/libc/include/pty.h | 6 + userland/libc/include/pwd.h | 0 userland/libc/include/regex.h | 0 userland/libc/include/sched.h | 0 userland/libc/include/setjmp.h | 14 + userland/libc/include/signal.h | 9 + userland/libc/include/socket.h | 41 + userland/libc/include/stdio.h | 116 + userland/libc/include/stdlib.h | 32 + userland/libc/include/string.h | 29 + userland/libc/include/strings.h | 0 userland/libc/include/sys/ioctl.h | 10 + userland/libc/include/sys/mman.h | 15 + userland/libc/include/sys/mount.h | 0 userland/libc/include/sys/resource.h | 0 userland/libc/include/sys/socket.h | 0 userland/libc/include/sys/stat.h | 31 + userland/libc/include/sys/statvfs.h | 0 userland/libc/include/sys/syscall.h | 0 userland/libc/include/sys/time.h | 41 + userland/libc/include/sys/times.h | 0 userland/libc/include/sys/types.h | 28 + userland/libc/include/sys/ucontext.h | 0 userland/libc/include/sys/un.h | 0 userland/libc/include/sys/utsname.h | 0 userland/libc/include/sys/wait.h | 0 userland/libc/include/syscall.h | 150 + userland/libc/include/syslog.h | 0 userland/libc/include/termios.h | 0 userland/libc/include/time.h | 35 + userland/libc/include/ubsan.h | 79 + userland/libc/include/unistd.h | 24 + userland/libc/include/utime.h | 0 userland/libc/include/wchar.h | 0 userland/libc/include/wctype.h | 0 userland/libc/input.h | 9 + userland/libc/inttypes.h | 5 + userland/libc/isspace.c | 5 + userland/libc/libc.c | 287 + userland/libc/libgen/basename.c | 45 + userland/libc/libgen/dirname.c | 44 + userland/libc/limits.h | 2 + userland/libc/malloc/malloc.c | 232 + userland/libc/malloc/malloc.h | 9 + userland/libc/malloc/oldmalloc.c | 136 + userland/libc/math.h | 0 userland/libc/memset.c | 15 + userland/libc/mmap.c | 19 + userland/libc/poll.h | 16 + userland/libc/pty.c | 15 + userland/libc/pty.h | 6 + userland/libc/setjmp/longjmp.s | 16 + userland/libc/setjmp/setjmp.s | 23 + userland/libc/socket.h | 41 + userland/libc/stdio.h | 95 + userland/libc/stdio/dprintf.c | 9 + userland/libc/stdio/fclose.c | 10 + userland/libc/stdio/feof.c | 5 + userland/libc/stdio/ferror.c | 5 + userland/libc/stdio/fflush.c | 7 + userland/libc/stdio/fgetc.c | 20 + userland/libc/stdio/fgetpos.c | 7 + userland/libc/stdio/fgets.c | 16 + userland/libc/stdio/fileno.c | 13 + userland/libc/stdio/fopen.c | 57 + userland/libc/stdio/fprintf.c | 9 + userland/libc/stdio/fputc.c | 7 + userland/libc/stdio/fputs.c | 9 + userland/libc/stdio/fread.c | 11 + userland/libc/stdio/fscanf.c | 7 + userland/libc/stdio/fseek.c | 21 + userland/libc/stdio/fsetpos.c | 7 + userland/libc/stdio/ftell.c | 5 + userland/libc/stdio/fwrite.c | 12 + userland/libc/stdio/getchar.c | 4 + userland/libc/stdio/open_memstream.c | 108 + userland/libc/stdio/printf.c | 9 + userland/libc/stdio/putc.c | 3 + userland/libc/stdio/putchar.c | 7 + userland/libc/stdio/puts.c | 6 + userland/libc/stdio/remove.c | 9 + userland/libc/stdio/rename.c | 8 + userland/libc/stdio/setvbuf.c | 6 + userland/libc/stdio/snprintf.c | 42 + userland/libc/stdio/sprintf.c | 33 + userland/libc/stdio/stderr.c | 11 + userland/libc/stdio/stdin.c | 54 + userland/libc/stdio/stdout.c | 13 + userland/libc/stdio/tmpfile.c | 9 + userland/libc/stdio/tmpnam.c | 10 + userland/libc/stdio/ungetc.c | 9 + userland/libc/stdio/vdprintf.c | 77 + userland/libc/stdio/vfprintf.c | 243 + userland/libc/stdio/vprintf.c | 3 + userland/libc/stdlib.h | 17 + userland/libc/stdlib/abort.c | 10 + userland/libc/stdlib/abs.c | 3 + userland/libc/stdlib/atexit.c | 6 + userland/libc/stdlib/atof.c | 5 + userland/libc/stdlib/atoi.c | 4 + userland/libc/stdlib/getenv.c | 6 + userland/libc/stdlib/mkstemp.c | 14 + userland/libc/stdlib/qsort.c | 29 + userland/libc/stdlib/rand.c | 17 + userland/libc/stdlib/srand.c | 8 + userland/libc/stdlib/strtod.c | 70 + userland/libc/stdlib/strtol.c | 52 + userland/libc/stdlib/strtold.c | 9 + userland/libc/stdlib/strtoul.c | 72 + userland/libc/stdlib/system.c | 17 + userland/libc/string.h | 17 + userland/libc/string/memcmp.c | 11 + userland/libc/string/memcpy.c | 9 + userland/libc/string/memmove.c | 14 + userland/libc/string/sscanf.c | 193 + userland/libc/string/strcasecmp.c | 28 + userland/libc/string/strcat.c | 13 + userland/libc/string/strchr.c | 11 + userland/libc/string/strcmp.c | 29 + userland/libc/string/strcpy.c | 7 + userland/libc/string/strcspn.c | 14 + userland/libc/string/strdup.c | 15 + userland/libc/string/strlcpy.c | 20 + userland/libc/string/strlen.c | 8 + userland/libc/string/strncasecmp.c | 29 + userland/libc/string/strncmp.c | 28 + userland/libc/string/strncpy.c | 13 + userland/libc/string/strndup.c | 22 + userland/libc/string/strnlen.c | 9 + userland/libc/string/strpbrk.c | 12 + userland/libc/string/strrchr.c | 12 + userland/libc/string/strspn.c | 18 + userland/libc/string/strstr.c | 21 + userland/libc/string/strtok.c | 26 + userland/libc/strings.h | 0 userland/libc/sys/mman.h | 8 + userland/libc/sys/mman/mmap.c | 19 + userland/libc/sys/stat.h | 30 + userland/libc/sys/stat/mkdir.c | 9 + userland/libc/sys/stat/stat.c | 13 + userland/libc/sys/time/gettimeofday.c | 5 + userland/libc/sys/types.h | 27 + userland/libc/syscall.h | 149 + userland/libc/time.h | 20 + userland/libc/time/clock_gettime.c | 14 + userland/libc/time/ctime_r.c | 13 + userland/libc/time/gmtime.c | 21 + userland/libc/time/localtime.c | 21 + userland/libc/time/strftime.c | 7 + userland/libc/time/time.c | 9 + userland/libc/ubsan.c | 49 + userland/libc/ubsan.h | 79 + userland/libc/unistd.h | 14 + userland/libc/unistd/_exit.c | 8 + userland/libc/unistd/execvp.c | 8 + userland/libc/unistd/getopt.c | 14 + userland/libc/unistd/getpid.c | 7 + userland/libc/unistd/msleep.c | 6 + userland/libc/unistd/unlink.c | 7 + userland/libc/unistd/uptime.c | 6 + userland/libc/wchar.h | 0 userland/libc/wctype.h | 0 userland/libgui/Makefile | 17 + userland/libgui/font.h | 3 + userland/libgui/libgui.c | 290 + userland/libgui/libgui.h | 34 + userland/minibox/Makefile | 12 + userland/minibox/minibox.c | 65 + userland/minibox/utilities/ascii.c | 30 + userland/minibox/utilities/cat.c | 54 + userland/minibox/utilities/echo.c | 30 + userland/minibox/utilities/ed.c | 145 + userland/minibox/utilities/include.h | 41 + userland/minibox/utilities/init.c | 72 + userland/minibox/utilities/ls.c | 42 + userland/minibox/utilities/minibox.c | 15 + userland/minibox/utilities/pwd.c | 12 + userland/minibox/utilities/touch.c | 11 + userland/minibox/utilities/wc.c | 106 + userland/minibox/utilities/yes.c | 13 + userland/sh/Makefile | 13 + userland/sh/sh | Bin 0 -> 44776 bytes userland/sh/sh.c | 224 + userland/sh/sh_a | Bin 0 -> 9200 bytes userland/sh/sh_bad | Bin 0 -> 9188 bytes userland/snake/Makefile | 15 + userland/snake/snake.c | 109 + userland/terminal/Makefile | 15 + userland/terminal/term.c | 166 + userland/test/Makefile | 16 + userland/test/linux.sh | 4 + userland/test/local/a.out | Bin 0 -> 35312 bytes userland/test/local/testfile | 1 + userland/test/test | Bin 0 -> 86144 bytes userland/test/test.c | 722 ++ userland/windowserver/Makefile | 16 + userland/windowserver/draw.c | 80 + userland/windowserver/draw.h | 13 + userland/windowserver/font.h | 133 + userland/windowserver/ws.c | 375 + userland/windowserver/ws.h | 30 + 403 files changed, 28889 insertions(+) create mode 100644 .clang-format create mode 100644 .gitignore create mode 100644 COPYING create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 arch/i386/boot.s create mode 100644 arch/i386/mmu.c create mode 100644 cpu/gdt.c create mode 100644 cpu/gdt.h create mode 100644 cpu/idt.c create mode 100644 cpu/idt.h create mode 100644 cpu/int_syscall.s create mode 100644 cpu/io.h create mode 100644 cpu/io.s create mode 100644 cpu/reload_gdt.s create mode 100644 cpu/spinlock.c create mode 100644 cpu/spinlock.h create mode 100644 cpu/syscall.c create mode 100644 cpu/syscall.h create mode 100644 crypto/ChaCha20/chacha20.c create mode 100644 crypto/ChaCha20/chacha20.h create mode 160000 crypto/SHA1 create mode 100644 drivers/ata.c create mode 100644 drivers/ata.h create mode 100644 drivers/keyboard.c create mode 100644 drivers/keyboard.h create mode 100644 drivers/mouse.c create mode 100644 drivers/mouse.h create mode 100644 drivers/pit.c create mode 100644 drivers/pit.h create mode 100644 drivers/pst.c create mode 100644 drivers/pst.h create mode 100644 drivers/serial.c create mode 100644 drivers/serial.h create mode 100644 drivers/vbe.c create mode 100644 drivers/vbe.h create mode 100644 elf.c create mode 100644 elf.h create mode 100644 fs/devfs.c create mode 100644 fs/devfs.h create mode 100644 fs/ext2.c create mode 100644 fs/ext2.h create mode 100644 fs/fifo.c create mode 100644 fs/fifo.h create mode 100644 fs/shm.c create mode 100644 fs/shm.h create mode 100644 fs/tmpfs.c create mode 100644 fs/tmpfs.h create mode 100644 fs/vfs.c create mode 100644 fs/vfs.h create mode 100644 halts.c create mode 100644 halts.h create mode 160000 hashmap create mode 100644 includes/defs.h create mode 100644 includes/mmu.h create mode 100644 includes/sys/types.h create mode 100644 init/kernel.c create mode 100644 isodir/boot/grub/grub.cfg create mode 100644 kmalloc.c create mode 100644 kmalloc.h create mode 100644 ksbrk.c create mode 100644 ksbrk.h create mode 100644 kubsan.c create mode 100644 kubsan.h create mode 100644 libc/exit/assert.c create mode 100644 libc/include/assert.h create mode 100644 libc/include/errno.h create mode 100644 libc/include/limits.h create mode 100644 libc/include/stdio.h create mode 100644 libc/include/stdlib.h create mode 100644 libc/include/string.h create mode 100644 libc/include/time.h create mode 100644 libc/include/types.h create mode 100644 libc/stdio/print.c create mode 100644 libc/string/copy.c create mode 100644 libc/string/isequal.c create mode 100644 libc/string/memcmp.c create mode 100644 libc/string/memcpy.c create mode 100644 libc/string/memset.c create mode 100644 libc/string/strcat.c create mode 100644 libc/string/strcmp.c create mode 100644 libc/string/strcpy.c create mode 100644 libc/string/strlcpy.c create mode 100644 libc/string/strlen.c create mode 100644 libc/string/strncpy.c create mode 100644 linker.ld create mode 100644 log.c create mode 100644 log.h create mode 120000 mount/cat create mode 120000 mount/init create mode 100755 mount/pid1 create mode 100755 mount/program create mode 100755 mount/sh create mode 100644 multiboot.h create mode 100755 new.sh create mode 100644 poll.c create mode 100644 poll.h create mode 100644 process.s create mode 100644 random.c create mode 100644 random.h create mode 100644 read_eip.s create mode 100644 scalls/accept.c create mode 100644 scalls/accept.h create mode 100644 scalls/bind.c create mode 100644 scalls/bind.h create mode 100644 scalls/clock_gettime.c create mode 100644 scalls/clock_gettime.h create mode 100644 scalls/mmap.c create mode 100644 scalls/mmap.h create mode 100644 scalls/msleep.c create mode 100644 scalls/msleep.h create mode 100644 scalls/ppoll.c create mode 100644 scalls/ppoll.h create mode 100644 scalls/shm.c create mode 100644 scalls/shm.h create mode 100644 scalls/socket.c create mode 100644 scalls/socket.h create mode 100644 scalls/stat.c create mode 100644 scalls/stat.h create mode 100644 scalls/uptime.c create mode 100644 scalls/uptime.h create mode 100644 sched/scheduler.c create mode 100644 sched/scheduler.h create mode 100644 socket.c create mode 100644 socket.h create mode 100755 sync.sh create mode 100644 time.h create mode 100644 toolchain/3A24BC1E8FB409FA9F14371813FCEF89DD9E3C4F create mode 100644 toolchain/binutils-2.40.diff create mode 100755 toolchain/build-binutils.sh create mode 100755 toolchain/build-gcc.sh create mode 100755 toolchain/download-binutils.sh create mode 100755 toolchain/download-gcc.sh create mode 100755 toolchain/download.sh create mode 100644 toolchain/gcc-13.1.0.diff create mode 100755 toolchain/get-keys.sh create mode 100644 userland/ante/Makefile create mode 100644 userland/ante/ante.c create mode 100644 userland/cat/Makefile create mode 100755 userland/cat/cat create mode 100644 userland/cat/cat.c create mode 100644 userland/init/Makefile create mode 100644 userland/init/crt0_old.c create mode 100755 userland/init/init create mode 100644 userland/init/init.c create mode 100644 userland/json/Makefile create mode 160000 userland/json/hashmap create mode 100644 userland/json/json.c create mode 100644 userland/json/json.h create mode 100644 userland/json/libjson.a create mode 100644 userland/libc/Makefile create mode 100644 userland/libc/arpa/inet.h create mode 100644 userland/libc/arpa/inet/htonl.c create mode 100644 userland/libc/arpa/inet/htons.c create mode 100644 userland/libc/assert.c create mode 100644 userland/libc/assert.h create mode 100644 userland/libc/crt0.s create mode 100644 userland/libc/ctype.h create mode 100644 userland/libc/ctype/isalnum.c create mode 100644 userland/libc/ctype/isalpha.c create mode 100644 userland/libc/ctype/isascii.c create mode 100644 userland/libc/ctype/isdigit.c create mode 100644 userland/libc/ctype/isprint.c create mode 100644 userland/libc/ctype/ispunct.c create mode 100644 userland/libc/ctype/isxdigit.c create mode 100644 userland/libc/ctype/tolower.c create mode 100644 userland/libc/ctype/toupper.c create mode 100644 userland/libc/dirent.h create mode 100644 userland/libc/dirent/alphasort.c create mode 100644 userland/libc/dirent/closedir.c create mode 100644 userland/libc/dirent/opendir.c create mode 100644 userland/libc/dirent/readdir.c create mode 100644 userland/libc/dirent/scandir.c create mode 100644 userland/libc/endian.h create mode 100644 userland/libc/errno.h create mode 100644 userland/libc/fcntl.h create mode 100644 userland/libc/include/arpa/inet.h create mode 100644 userland/libc/include/assert.h create mode 100644 userland/libc/include/byteswap.h create mode 100644 userland/libc/include/ctype.h create mode 100644 userland/libc/include/dirent.h create mode 100644 userland/libc/include/endian.h create mode 100644 userland/libc/include/err.h create mode 100644 userland/libc/include/errno.h create mode 100644 userland/libc/include/fcntl.h create mode 100644 userland/libc/include/fnmatch.h create mode 100644 userland/libc/include/glob.h create mode 100644 userland/libc/include/grp.h create mode 100644 userland/libc/include/input.h create mode 100644 userland/libc/include/inttypes.h create mode 100644 userland/libc/include/langinfo.h create mode 100644 userland/libc/include/libgen.h create mode 100644 userland/libc/include/limits.h create mode 100644 userland/libc/include/locale.h create mode 100644 userland/libc/include/math.h create mode 100644 userland/libc/include/net/if.h create mode 100644 userland/libc/include/netdb.h create mode 100644 userland/libc/include/netinet/in.h create mode 100644 userland/libc/include/netinet/tcp.h create mode 100644 userland/libc/include/paths.h create mode 100644 userland/libc/include/poll.h create mode 100644 userland/libc/include/pty.h create mode 100644 userland/libc/include/pwd.h create mode 100644 userland/libc/include/regex.h create mode 100644 userland/libc/include/sched.h create mode 100644 userland/libc/include/setjmp.h create mode 100644 userland/libc/include/signal.h create mode 100644 userland/libc/include/socket.h create mode 100644 userland/libc/include/stdio.h create mode 100644 userland/libc/include/stdlib.h create mode 100644 userland/libc/include/string.h create mode 100644 userland/libc/include/strings.h create mode 100644 userland/libc/include/sys/ioctl.h create mode 100644 userland/libc/include/sys/mman.h create mode 100644 userland/libc/include/sys/mount.h create mode 100644 userland/libc/include/sys/resource.h create mode 100644 userland/libc/include/sys/socket.h create mode 100644 userland/libc/include/sys/stat.h create mode 100644 userland/libc/include/sys/statvfs.h create mode 100644 userland/libc/include/sys/syscall.h create mode 100644 userland/libc/include/sys/time.h create mode 100644 userland/libc/include/sys/times.h create mode 100644 userland/libc/include/sys/types.h create mode 100644 userland/libc/include/sys/ucontext.h create mode 100644 userland/libc/include/sys/un.h create mode 100644 userland/libc/include/sys/utsname.h create mode 100644 userland/libc/include/sys/wait.h create mode 100644 userland/libc/include/syscall.h create mode 100644 userland/libc/include/syslog.h create mode 100644 userland/libc/include/termios.h create mode 100644 userland/libc/include/time.h create mode 100644 userland/libc/include/ubsan.h create mode 100644 userland/libc/include/unistd.h create mode 100644 userland/libc/include/utime.h create mode 100644 userland/libc/include/wchar.h create mode 100644 userland/libc/include/wctype.h create mode 100644 userland/libc/input.h create mode 100644 userland/libc/inttypes.h create mode 100644 userland/libc/isspace.c create mode 100644 userland/libc/libc.c create mode 100644 userland/libc/libgen/basename.c create mode 100644 userland/libc/libgen/dirname.c create mode 100644 userland/libc/limits.h create mode 100644 userland/libc/malloc/malloc.c create mode 100644 userland/libc/malloc/malloc.h create mode 100644 userland/libc/malloc/oldmalloc.c create mode 100644 userland/libc/math.h create mode 100644 userland/libc/memset.c create mode 100644 userland/libc/mmap.c create mode 100644 userland/libc/poll.h create mode 100644 userland/libc/pty.c create mode 100644 userland/libc/pty.h create mode 100644 userland/libc/setjmp/longjmp.s create mode 100644 userland/libc/setjmp/setjmp.s create mode 100644 userland/libc/socket.h create mode 100644 userland/libc/stdio.h create mode 100644 userland/libc/stdio/dprintf.c create mode 100644 userland/libc/stdio/fclose.c create mode 100644 userland/libc/stdio/feof.c create mode 100644 userland/libc/stdio/ferror.c create mode 100644 userland/libc/stdio/fflush.c create mode 100644 userland/libc/stdio/fgetc.c create mode 100644 userland/libc/stdio/fgetpos.c create mode 100644 userland/libc/stdio/fgets.c create mode 100644 userland/libc/stdio/fileno.c create mode 100644 userland/libc/stdio/fopen.c create mode 100644 userland/libc/stdio/fprintf.c create mode 100644 userland/libc/stdio/fputc.c create mode 100644 userland/libc/stdio/fputs.c create mode 100644 userland/libc/stdio/fread.c create mode 100644 userland/libc/stdio/fscanf.c create mode 100644 userland/libc/stdio/fseek.c create mode 100644 userland/libc/stdio/fsetpos.c create mode 100644 userland/libc/stdio/ftell.c create mode 100644 userland/libc/stdio/fwrite.c create mode 100644 userland/libc/stdio/getchar.c create mode 100644 userland/libc/stdio/open_memstream.c create mode 100644 userland/libc/stdio/printf.c create mode 100644 userland/libc/stdio/putc.c create mode 100644 userland/libc/stdio/putchar.c create mode 100644 userland/libc/stdio/puts.c create mode 100644 userland/libc/stdio/remove.c create mode 100644 userland/libc/stdio/rename.c create mode 100644 userland/libc/stdio/setvbuf.c create mode 100644 userland/libc/stdio/snprintf.c create mode 100644 userland/libc/stdio/sprintf.c create mode 100644 userland/libc/stdio/stderr.c create mode 100644 userland/libc/stdio/stdin.c create mode 100644 userland/libc/stdio/stdout.c create mode 100644 userland/libc/stdio/tmpfile.c create mode 100644 userland/libc/stdio/tmpnam.c create mode 100644 userland/libc/stdio/ungetc.c create mode 100644 userland/libc/stdio/vdprintf.c create mode 100644 userland/libc/stdio/vfprintf.c create mode 100644 userland/libc/stdio/vprintf.c create mode 100644 userland/libc/stdlib.h create mode 100644 userland/libc/stdlib/abort.c create mode 100644 userland/libc/stdlib/abs.c create mode 100644 userland/libc/stdlib/atexit.c create mode 100644 userland/libc/stdlib/atof.c create mode 100644 userland/libc/stdlib/atoi.c create mode 100644 userland/libc/stdlib/getenv.c create mode 100644 userland/libc/stdlib/mkstemp.c create mode 100644 userland/libc/stdlib/qsort.c create mode 100644 userland/libc/stdlib/rand.c create mode 100644 userland/libc/stdlib/srand.c create mode 100644 userland/libc/stdlib/strtod.c create mode 100644 userland/libc/stdlib/strtol.c create mode 100644 userland/libc/stdlib/strtold.c create mode 100644 userland/libc/stdlib/strtoul.c create mode 100644 userland/libc/stdlib/system.c create mode 100644 userland/libc/string.h create mode 100644 userland/libc/string/memcmp.c create mode 100644 userland/libc/string/memcpy.c create mode 100644 userland/libc/string/memmove.c create mode 100644 userland/libc/string/sscanf.c create mode 100644 userland/libc/string/strcasecmp.c create mode 100644 userland/libc/string/strcat.c create mode 100644 userland/libc/string/strchr.c create mode 100644 userland/libc/string/strcmp.c create mode 100644 userland/libc/string/strcpy.c create mode 100644 userland/libc/string/strcspn.c create mode 100644 userland/libc/string/strdup.c create mode 100644 userland/libc/string/strlcpy.c create mode 100644 userland/libc/string/strlen.c create mode 100644 userland/libc/string/strncasecmp.c create mode 100644 userland/libc/string/strncmp.c create mode 100644 userland/libc/string/strncpy.c create mode 100644 userland/libc/string/strndup.c create mode 100644 userland/libc/string/strnlen.c create mode 100644 userland/libc/string/strpbrk.c create mode 100644 userland/libc/string/strrchr.c create mode 100644 userland/libc/string/strspn.c create mode 100644 userland/libc/string/strstr.c create mode 100644 userland/libc/string/strtok.c create mode 100644 userland/libc/strings.h create mode 100644 userland/libc/sys/mman.h create mode 100644 userland/libc/sys/mman/mmap.c create mode 100644 userland/libc/sys/stat.h create mode 100644 userland/libc/sys/stat/mkdir.c create mode 100644 userland/libc/sys/stat/stat.c create mode 100644 userland/libc/sys/time/gettimeofday.c create mode 100644 userland/libc/sys/types.h create mode 100644 userland/libc/syscall.h create mode 100644 userland/libc/time.h create mode 100644 userland/libc/time/clock_gettime.c create mode 100644 userland/libc/time/ctime_r.c create mode 100644 userland/libc/time/gmtime.c create mode 100644 userland/libc/time/localtime.c create mode 100644 userland/libc/time/strftime.c create mode 100644 userland/libc/time/time.c create mode 100644 userland/libc/ubsan.c create mode 100644 userland/libc/ubsan.h create mode 100644 userland/libc/unistd.h create mode 100644 userland/libc/unistd/_exit.c create mode 100644 userland/libc/unistd/execvp.c create mode 100644 userland/libc/unistd/getopt.c create mode 100644 userland/libc/unistd/getpid.c create mode 100644 userland/libc/unistd/msleep.c create mode 100644 userland/libc/unistd/unlink.c create mode 100644 userland/libc/unistd/uptime.c create mode 100644 userland/libc/wchar.h create mode 100644 userland/libc/wctype.h create mode 100644 userland/libgui/Makefile create mode 100644 userland/libgui/font.h create mode 100644 userland/libgui/libgui.c create mode 100644 userland/libgui/libgui.h create mode 100644 userland/minibox/Makefile create mode 100644 userland/minibox/minibox.c create mode 100644 userland/minibox/utilities/ascii.c create mode 100644 userland/minibox/utilities/cat.c create mode 100644 userland/minibox/utilities/echo.c create mode 100644 userland/minibox/utilities/ed.c create mode 100644 userland/minibox/utilities/include.h create mode 100644 userland/minibox/utilities/init.c create mode 100644 userland/minibox/utilities/ls.c create mode 100644 userland/minibox/utilities/minibox.c create mode 100644 userland/minibox/utilities/pwd.c create mode 100644 userland/minibox/utilities/touch.c create mode 100644 userland/minibox/utilities/wc.c create mode 100644 userland/minibox/utilities/yes.c create mode 100644 userland/sh/Makefile create mode 100755 userland/sh/sh create mode 100644 userland/sh/sh.c create mode 100755 userland/sh/sh_a create mode 100755 userland/sh/sh_bad create mode 100644 userland/snake/Makefile create mode 100644 userland/snake/snake.c create mode 100644 userland/terminal/Makefile create mode 100644 userland/terminal/term.c create mode 100644 userland/test/Makefile create mode 100755 userland/test/linux.sh create mode 100755 userland/test/local/a.out create mode 100644 userland/test/local/testfile create mode 100755 userland/test/test create mode 100644 userland/test/test.c create mode 100644 userland/windowserver/Makefile create mode 100644 userland/windowserver/draw.c create mode 100644 userland/windowserver/draw.h create mode 100644 userland/windowserver/font.h create mode 100644 userland/windowserver/ws.c create mode 100644 userland/windowserver/ws.h diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..cd89955 --- /dev/null +++ b/.clang-format @@ -0,0 +1 @@ +BasedOnStyle: llvm diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..82848fd --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +*.a +*.o +*.txt +*.log +*.bin +*.iso +*.img +*.tar.xz +*.tar.xz.sig +.cache/ +toolchain/bin/ +toolchain/binutils-*/ +toolchain/gcc-*/ +toolchain/build-* +userland/* +userland/terminal/term +!userland/libc/* +!userland/minibox/* +!userland/windowserver/* +!userland/terminal/* +!userland/libgui/* +!userland/snake/* +!userland/ante/* +!userland/ante/* +ext2.img +mount diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3b16888 --- /dev/null +++ b/LICENSE @@ -0,0 +1,14 @@ +Copyright (C) 2022 - 2023 Anton Kling + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..74f52b4 --- /dev/null +++ b/Makefile @@ -0,0 +1,33 @@ +CC="./sysroot/bin/i686-sb-gcc" +AS="./sysroot/bin/i686-sb-as" +OBJ = arch/i386/boot.o init/kernel.o cpu/gdt.o cpu/reload_gdt.o cpu/idt.o cpu/io.o libc/stdio/print.o drivers/keyboard.o log.o drivers/pit.o libc/string/memcpy.o libc/string/strlen.o libc/string/memcmp.o drivers/ata.o libc/string/memset.o cpu/syscall.o read_eip.o libc/exit/assert.o process.o cpu/int_syscall.o libc/string/strcpy.o arch/i386/mmu.o kmalloc.o fs/ext2.o fs/vfs.o fs/devfs.o cpu/spinlock.o random.o libc/string/strcmp.o crypto/ChaCha20/chacha20.o crypto/SHA1/sha1.o fs/tmpfs.o libc/string/isequal.o drivers/pst.o halts.o scalls/ppoll.o kubsan.o scalls/mmap.o drivers/serial.o scalls/accept.o scalls/bind.o scalls/socket.o socket.o poll.o fs/fifo.o hashmap/hashmap.o fs/shm.o scalls/shm.o elf.o ksbrk.o sched/scheduler.o scalls/stat.o libc/string/copy.o libc/string/strncpy.o drivers/mouse.o libc/string/strlcpy.o libc/string/strcat.o drivers/vbe.o scalls/msleep.o scalls/uptime.o +CFLAGS = -O2 -fsanitize=vla-bound,shift-exponent,pointer-overflow,shift,signed-integer-overflow,bounds -ggdb -ffreestanding -Wall -Werror -mgeneral-regs-only -Wimplicit-fallthrough -I./libc/include/ -I. +INCLUDE=-I./includes/ -I./libc/include/ + +all: myos.iso + +%.o: %.c + $(CC) $(INCLUDE) -c -o $@ $< $(CFLAGS) + +%.o: %.s + $(AS) $< -o $@ + +myos.bin: $(OBJ) + $(CC) $(INCLUDE) -shared -T linker.ld -o myos.bin -ffreestanding -nostdlib $(CFLAGS) $^ -lgcc + +debug: + qemu-system-i386 -no-reboot -no-shutdown -serial file:./serial.log -hda ext2.img -m 1G -cdrom myos.iso -s -S & + gdb -x .gdbinit + +nk: + qemu-system-i386 -d int -no-reboot -no-shutdown -serial file:./serial.log -hda ext2.img -m 1G -cdrom myos.iso -s + +run: + qemu-system-i386 -enable-kvm -d int -no-reboot -no-shutdown -chardev stdio,id=char0,logfile=serial.log,signal=off -serial chardev:char0 -hda ext2.img -m 1G -cdrom myos.iso -s + +myos.iso: myos.bin + cp myos.bin isodir/boot + grub-mkrescue -o myos.iso isodir + +clean: + rm myos.bin myos.iso $(OBJ) diff --git a/README.md b/README.md new file mode 100644 index 0000000..836a31d --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +# sbOS + +A mostly from scratch, UNIX like x86 hobbyist operaing system. Kernel, +libc and the rest of the userland are written from scratch. It only +requires a bootloader that supports the first version of multiboot(such +as GRUB). + +## Features + +* Paging +* Interrupts +* Process scheduling +* VBE graphics +* PS2 Mouse/Keyboard +* VFS +* ext2 filesystem +* DevFS +* UNIX sockets +* libc +* Window Manager +* Terminal Emulator +* Very basic shell +* Shell utilities(cat, yes, echo etc) + +and some other stuff. + +## How do I run it? + +You shouldn't, it is very incomplete and does not have much intreasting +sutff in the userland yet. Setup is currently also sligthly painful if +you don't know what you are doing. + +## Why? + +fun diff --git a/arch/i386/boot.s b/arch/i386/boot.s new file mode 100644 index 0000000..61bbfbb --- /dev/null +++ b/arch/i386/boot.s @@ -0,0 +1,128 @@ +.set ALIGN, 1<<0 +.set MEMINFO, 1<<1 +.set VIDEO_MODE, 1<<2 +.set FLAGS, VIDEO_MODE|ALIGN | MEMINFO +.set MAGIC, 0x1BADB002 +.set CHECKSUM, -(MAGIC + FLAGS) + +#.section .multiboot +.align 16, 0 +.section .multiboot.data, "aw" + .align 4 + .long MAGIC + .long FLAGS + .long CHECKSUM + # unused(padding) + .long 0,0,0,0,0 + # Video mode + .long 0 # Linear graphics + .long 0 # Preferred width + .long 0 # Preferred height + .long 32 # Preferred pixel depth + +# Allocate the initial stack. +.section .bootstrap_stack, "aw", @nobits +stack_bottom: +.skip 16384 # 16 KiB +stack_top: + +.global boot_page_directory +.global boot_page_table1 +.section .bss, "aw", @nobits + .align 4096 +boot_page_directory: + .skip 4096 +boot_page_table1: + .skip 4096 + +.section .multiboot.text, "a" +.global _start +.extern _kernel_end +.type _start, @function +# Kernel entry +_start: + # edi contains the buffer we wish to modify + movl $(boot_page_table1 - 0xC0000000), %edi + + # for loop + movl $0, %esi + movl $1024, %ecx +1: + # esi = address + # If we are in kernel range jump to "label 2" + cmpl $_kernel_start, %esi + jl 2f + + # If we are past the kernel jump to the final stage + # "label 3" + cmpl $(_kernel_end - 0xC0000000), %esi + jge 3f + +2: + # Add permission to the pages + movl %esi, %edx + orl $0x003, %edx + movl %edx, (%edi) + + # Size of page is 4096 bytes. + addl $4096, %esi + # Size of entries in boot_page_table1 is 4 bytes. + addl $4, %edi + # Loop to the next entry if we haven't finished. + loop 1b + +3: + # Map the page table to both virtual addresses 0x00000000 and 0xC0000000. + movl $(boot_page_table1 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 0 + movl $(boot_page_table1 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 768 * 4 + + # Set cr3 to the address of the boot_page_directory. + movl $(boot_page_directory - 0xC0000000), %ecx + movl %ecx, %cr3 + + # Enable paging + movl %cr0, %ecx + orl $0x80000000, %ecx + movl %ecx, %cr0 + + # Jump to higher half with an absolute jump. + lea 4f, %ecx + jmp *%ecx + +.size _start, . - _start + +.section .text + +4: + # At this point, paging is fully set up and enabled. + + # Unmap the identity mapping as it is now unnecessary. + movl $0, boot_page_directory + 0 + + # Reload crc3 to force a TLB flush so the changes to take effect. + movl %cr3, %ecx + movl %ecx, %cr3 + + # Set up the stack. + mov $stack_top, %esp + + # Reset EFLAGS. + pushl $0 + popf + + pushl %esp + + /* Push the pointer to the Multiboot information structure. */ + pushl %ebx + /* Push the magic value. */ + pushl %eax + + mov $_kernel_end, %eax + pushl %eax + # Enter the high-level kernel. + call kernel_main + + # Infinite loop if the system has nothing more to do. + cli +1: hlt + jmp 1b diff --git a/arch/i386/mmu.c b/arch/i386/mmu.c new file mode 100644 index 0000000..6fff8f2 --- /dev/null +++ b/arch/i386/mmu.c @@ -0,0 +1,565 @@ +#include +#include +#include +#include + +#define INDEX_FROM_BIT(a) (a / (32)) +#define OFFSET_FROM_BIT(a) (a % (32)) +#define PAGE_SIZE ((uintptr_t)0x1000) + +#define PAGE_ALLOCATE 1 +#define PAGE_NO_ALLOCATE 0 + +PageDirectory *kernel_directory; +PageDirectory real_kernel_directory; +PageDirectory *active_directory = 0; + +#define END_OF_MEMORY 0x8000000 * 15 +const uint32_t num_of_frames = END_OF_MEMORY / PAGE_SIZE; +uint32_t frames[END_OF_MEMORY / PAGE_SIZE] = {0}; +uint32_t num_allocated_frames = 0; + +#define KERNEL_START 0xc0000000 +extern uintptr_t data_end; + +void write_to_frame(uint32_t frame_address, uint8_t on); + +void *ksbrk(size_t s) { + uintptr_t rc = (uintptr_t)align_page((void *)data_end); + data_end += s; + data_end = (uintptr_t)align_page((void *)data_end); + + if (!get_active_pagedirectory()) { + // If there is no active pagedirectory we + // just assume that the memory is + // already mapped. + return (void *)rc; + } + // Determine whether we are approaching a unallocated table + int table_index = 1 + (rc / (1024 * 0x1000)); + if (!active_directory->tables[table_index]) { + uint32_t physical; + active_directory->tables[table_index] = (PageTable *)0xDEADBEEF; + active_directory->tables[table_index] = + (PageTable *)ksbrk_physical(sizeof(PageTable), (void **)&physical); + memset(active_directory->tables[table_index], 0, sizeof(PageTable)); + active_directory->physical_tables[table_index] = (uint32_t)physical | 0x3; + + kernel_directory->tables[table_index] = + active_directory->tables[table_index]; + kernel_directory->physical_tables[table_index] = + active_directory->physical_tables[table_index]; + return ksbrk(s); + } + mmu_allocate_shared_kernel_region((void *)rc, (data_end - (uintptr_t)rc)); + assert(((uintptr_t)rc % PAGE_SIZE) == 0); + memset((void *)rc, 0x00, s); + + return (void *)rc; +} + +void *ksbrk_physical(size_t s, void **physical) { + void *r = ksbrk(s); + if (physical) { + *physical = (void *)virtual_to_physical(r, 0); + } + return r; +} + +uint32_t mmu_get_number_of_allocated_frames(void) { + return num_allocated_frames; +} + +Page *get_page(void *ptr, PageDirectory *directory, int create_new_page, + int set_user) { + uintptr_t address = (uintptr_t)ptr; + if (!directory) + directory = get_active_pagedirectory(); + address /= 0x1000; + + uint32_t table_index = address / 1024; + if (!directory->tables[table_index]) { + if (!create_new_page) + return 0; + + uint32_t physical; + directory->tables[table_index] = + (PageTable *)ksbrk_physical(sizeof(PageTable), (void **)&physical); + memset(directory->tables[table_index], 0, sizeof(PageTable)); + directory->physical_tables[table_index] = + (uint32_t)physical | ((set_user) ? 0x7 : 0x3); + + if (!set_user) { + kernel_directory->tables[table_index] = directory->tables[table_index]; + kernel_directory->physical_tables[table_index] = + directory->physical_tables[table_index]; + } + } + Page *p = &directory->tables[table_index]->pages[address % 1024]; + if (create_new_page) { + p->present = 0; + } + return &directory->tables[table_index]->pages[address % 1024]; +} + +void mmu_free_pages(void *a, uint32_t n) { + for (; n > 0; n--) { + Page *p = get_page(a, NULL, PAGE_NO_ALLOCATE, 0); + p->present = 0; + write_to_frame(p->frame * 0x1000, 0); + a += 0x1000; + } +} + +void *next_page(void *ptr) { + uintptr_t a = (uintptr_t)ptr; + return (void *)(a + (PAGE_SIZE - ((uint32_t)a & (PAGE_SIZE - 1)))); +} + +void *align_page(void *a) { + if ((uintptr_t)a & (PAGE_SIZE - 1)) + return next_page(a); + + return a; +} + +void flush_tlb(void) { + asm volatile("\ + mov %cr3, %eax;\ + mov %eax, %cr3"); +} + +uint32_t first_free_frame(void) { + asm("cli"); + for (uint32_t i = 1; i < INDEX_FROM_BIT(num_of_frames); i++) { + if (frames[i] == 0xFFFFFFFF) + continue; + + for (uint32_t c = 0; c < 32; c++) + if (!(frames[i] & ((uint32_t)1 << c))) + return i * 32 + c; + } + + kprintf("ERROR Num frames: %x\n", mmu_get_number_of_allocated_frames()); + klog("No free frames, uh oh.", LOG_ERROR); + assert(0); + return 0; +} + +void write_to_frame(uint32_t frame_address, uint8_t on) { + uint32_t frame = frame_address / 0x1000; + assert(INDEX_FROM_BIT(frame) < sizeof(frames) / sizeof(frames[0])); + if (on) { + num_allocated_frames++; + frames[INDEX_FROM_BIT(frame)] |= ((uint32_t)0x1 << OFFSET_FROM_BIT(frame)); + return; + } + num_allocated_frames--; + frames[INDEX_FROM_BIT(frame)] &= ~((uint32_t)0x1 << OFFSET_FROM_BIT(frame)); +} + +PageDirectory *get_active_pagedirectory(void) { return active_directory; } + +PageTable *clone_table(uint32_t src_index, PageDirectory *src_directory, + uint32_t *physical_address) { + PageTable *new_table = + ksbrk_physical(sizeof(PageTable), (void **)physical_address); + PageTable *src = src_directory->tables[src_index]; + + // Copy all the pages + for (uint16_t i = 0; i < 1024; i++) { + if (!src->pages[i].present) { + new_table->pages[i].present = 0; + continue; + } + uint32_t frame_address = first_free_frame(); + write_to_frame(frame_address * 0x1000, 1); + new_table->pages[i].frame = frame_address; + + new_table->pages[i].present |= src->pages[i].present; + new_table->pages[i].rw |= src->pages[i].rw; + new_table->pages[i].user |= src->pages[i].user; + new_table->pages[i].accessed |= src->pages[i].accessed; + new_table->pages[i].dirty |= src->pages[i].dirty; + } + + // Now copy all of the data to the new table. This is done by creating a + // virutal pointer to this newly created tables physical frame so we can + // copy data to it. + for (uint32_t i = 0; i < 1024; i++) { + // Find a unused table + if (src_directory->tables[i]) + continue; + + // Link the table to the new table temporarily + src_directory->tables[i] = new_table; + src_directory->physical_tables[i] = *physical_address | 0x7; + PageDirectory *tmp = get_active_pagedirectory(); + switch_page_directory(src_directory); + + // For each page in the table copy all the data over. + for (uint32_t c = 0; c < 1024; c++) { + // Only copy pages that are used. + if (!src->pages[c].frame || !src->pages[c].present) + continue; + + uint32_t table_data_pointer = i << 22 | c << 12; + uint32_t src_data_pointer = src_index << 22 | c << 12; + memcpy((void *)table_data_pointer, (void *)src_data_pointer, 0x1000); + } + src_directory->tables[i] = 0; + src_directory->physical_tables[i] = 0; + switch_page_directory(tmp); + return new_table; + } + ASSERT_NOT_REACHED; + return 0; +} + +PageTable *copy_table(PageTable *src, uint32_t *physical_address) { + PageTable *new_table = + ksbrk_physical(sizeof(PageTable), (void **)physical_address); + + // copy all the pages + for (uint16_t i = 0; i < 1024; i++) { + if (!src->pages[i].present) { + new_table->pages[i].present = 0; + continue; + } + new_table->pages[i].frame = src->pages[i].frame; + new_table->pages[i].present = src->pages[i].present; + new_table->pages[i].rw = src->pages[i].rw; + new_table->pages[i].user = src->pages[i].user; + new_table->pages[i].accessed = src->pages[i].accessed; + new_table->pages[i].dirty = src->pages[i].dirty; + } + return new_table; +} + +PageDirectory *clone_directory(PageDirectory *original) { + if (!original) + original = get_active_pagedirectory(); + + uint32_t physical_address; + PageDirectory *new_directory = + ksbrk_physical(sizeof(PageDirectory), (void **)&physical_address); + uint32_t offset = + (uint32_t)new_directory->physical_tables - (uint32_t)new_directory; + new_directory->physical_address = physical_address + offset; + + for (int i = 0; i < 1024; i++) { + if (!original->tables[i]) { + new_directory->tables[i] = NULL; + new_directory->physical_tables[i] = (uint32_t)NULL; + continue; + } + + // Make sure to copy instead of cloning the stack. + if (i >= 635 && i <= 641) { + uint32_t physical; + new_directory->tables[i] = clone_table(i, original, &physical); + new_directory->physical_tables[i] = + physical | (original->physical_tables[i] & 0xFFF); + continue; + } + + // if (original->tables[i] == kernel_directory->tables[i]) { + if (i > 641) { + new_directory->tables[i] = kernel_directory->tables[i]; + new_directory->physical_tables[i] = kernel_directory->physical_tables[i]; + continue; + } + + uint32_t physical; + new_directory->tables[i] = clone_table(i, original, &physical); + new_directory->physical_tables[i] = + physical | (original->physical_tables[i] & 0xFFF); + } + + return new_directory; +} + +void mmu_allocate_shared_kernel_region(void *rc, size_t n) { + size_t num_pages = n / PAGE_SIZE; + for (size_t i = 0; i <= num_pages; i++) { + Page *p = get_page((void *)(rc + i * 0x1000), NULL, PAGE_NO_ALLOCATE, 0); + if (!p) { + kprintf("don't have: %x\n", rc + i * 0x1000); + p = get_page((void *)(rc + i * 0x1000), NULL, PAGE_ALLOCATE, 0); + } + if (!p->present || !p->frame) + allocate_frame(p, 0, 1); + } +} + +void mmu_remove_virtual_physical_address_mapping(void *ptr, size_t length) { + size_t num_pages = (uintptr_t)align_page((void *)length) / PAGE_SIZE; + for (size_t i = 0; i < num_pages; i++) { + Page *p = get_page(ptr + (i * PAGE_SIZE), NULL, PAGE_NO_ALLOCATE, 0); + if (!p) + return; + p->frame = 0; + p->present = 0; + } +} + +void *mmu_find_unallocated_virtual_range(void *addr, size_t length) { + addr = align_page(addr); + // Check if the pages already exist + for (size_t i = 0; i < length; i += 0x1000) { + if (get_page(addr + i, NULL, PAGE_NO_ALLOCATE, 0)) { + // Page already exists + return mmu_find_unallocated_virtual_range(addr + 0x1000, length); + } + } + return addr; +} + +int mmu_allocate_region(void *ptr, size_t n, mmu_flags flags) { + size_t num_pages = n / 0x1000; + for (size_t i = 0; i <= num_pages; i++) { + Page *p = get_page((void *)(ptr + i * 0x1000), get_active_pagedirectory(), + PAGE_ALLOCATE, 1); + assert(p); + int rw = (flags & MMU_FLAG_RW); + int kernel = (flags & MMU_FLAG_KERNEL); + if (!allocate_frame(p, rw, kernel)) { + klog("MMU: Frame allocation failed", LOG_WARN); + return 0; + } + } + return 1; +} + +void *mmu_map_frames(void *const ptr, size_t s) { + void *const r = mmu_find_unallocated_virtual_range((void *)0xEF000000, s); + kprintf("r: %x\n", r); + size_t num_pages = s / 0x1000; + for (size_t i = 0; i <= num_pages; i++) { + Page *p = get_page((void *)(r + i * 0x1000), NULL, PAGE_ALLOCATE, 1); + assert(p); + int rw = 1; + int is_kernel = 1; + p->present = 1; + p->rw = rw; + p->user = !is_kernel; + p->frame = (uintptr_t)(ptr + i * 0x1000) / 0x1000; + write_to_frame((uintptr_t)ptr + i * 0x1000, 1); + } + flush_tlb(); + return r; +} + +void *allocate_frame(Page *page, int rw, int is_kernel) { + if (page->present) { + dump_backtrace(5); + klog("Page is already set", 1); + for (;;) + ; + return 0; + } + uint32_t frame_address = first_free_frame(); + assert(frame_address < sizeof(frames) / sizeof(frames[0])); + write_to_frame(frame_address * 0x1000, 1); + + page->present = 1; + page->rw = rw; + page->user = !is_kernel; + page->frame = frame_address; + return (void *)(frame_address * 0x1000); +} + +void mmu_free_address_range(void *ptr, size_t length) { + size_t num_pages = (size_t)align_page((void *)length) / PAGE_SIZE; + for (size_t i = 0; i < num_pages; i++, ptr += PAGE_SIZE) { + Page *page = get_page(ptr, NULL, PAGE_NO_ALLOCATE, 0); + if (!page) + continue; + if (!page->present) + continue; + if (!page->frame) + continue; + // Sanity check that none of the frames are invalid + assert(page->frame < sizeof(frames) / sizeof(frames[0])); + write_to_frame(((uint32_t)page->frame) * 0x1000, 0); + page->present = 0; + page->rw = 0; + page->user = 0; + page->frame = 0; + } +} + +void mmu_map_directories(void *dst, PageDirectory *d, void *src, + PageDirectory *s, size_t length) { + d = (!d) ? get_active_pagedirectory() : d; + s = (!s) ? get_active_pagedirectory() : s; + size_t num_pages = (uint32_t)align_page((void *)length) / 0x1000; + for (size_t i = 0; i < num_pages; i++, dst += 0x1000, src += 0x1000) { + Page *p = get_page(dst, d, PAGE_ALLOCATE, 1); + p->present = 1; + p->rw = 1; + p->user = 1; + void *physical = virtual_to_physical(src, s); + p->frame = (uint32_t)physical / PAGE_SIZE; + } + flush_tlb(); +} + +void mmu_map_physical(void *dst, PageDirectory *d, void *physical, + size_t length) { + d = (!d) ? get_active_pagedirectory() : d; + size_t num_pages = (uint32_t)align_page((void *)length) / 0x1000; + for (size_t i = 0; i < num_pages; i++, dst += 0x1000, physical += 0x1000) { + Page *p = get_page(dst, d, PAGE_ALLOCATE, 1); + p->present = 1; + p->rw = 1; + p->user = 1; + p->frame = (uintptr_t)physical / PAGE_SIZE; + write_to_frame((uintptr_t)physical, 1); + } + flush_tlb(); +} + +void *virtual_to_physical(void *address, PageDirectory *directory) { + if (0 == directory) + directory = get_active_pagedirectory(); + return (void *)((get_page((void *)address, directory, PAGE_NO_ALLOCATE, 0) + ->frame * + 0x1000) + + (((uintptr_t)address) & 0xFFF)); +} + +extern uint32_t inital_esp; +void __attribute__((optimize("O0"))) +move_stack(uint32_t new_stack_address, uint32_t size) { + mmu_allocate_region((void *)(new_stack_address - size), size, + MMU_FLAG_KERNEL); + + uint32_t old_stack_pointer, old_base_pointer; + + register uint32_t eax asm("eax"); + asm volatile("mov %esp, %eax"); + old_stack_pointer = eax; + asm volatile("mov %ebp, %eax"); + old_base_pointer = eax; + + uint32_t new_stack_pointer = + old_stack_pointer + ((uint32_t)new_stack_address - inital_esp); + uint32_t new_base_pointer = + old_base_pointer + ((uint32_t)new_stack_address - inital_esp); + + // Copy the stack + memcpy((void *)new_stack_pointer, (void *)old_stack_pointer, + inital_esp - old_stack_pointer); + for (uint32_t i = (uint32_t)new_stack_address; i > new_stack_address - size; + i -= 4) { + uint32_t tmp = *(uint32_t *)i; + if (old_stack_pointer < tmp && tmp < inital_esp) { + tmp = tmp + (new_stack_address - inital_esp); + uint32_t *tmp2 = (uint32_t *)i; + *tmp2 = tmp; + } + } + + inital_esp = new_stack_pointer; + // Actually change the stack + eax = new_stack_pointer; + asm volatile("mov %eax, %esp"); + eax = new_base_pointer; + asm volatile("mov %eax, %ebp"); +} + +// C strings have a unknown length so it does not makes sense to check +// for a size on the pointer. Instead we check whether the page it +// resides in is accessible to the user. +void *is_valid_user_c_string(const char *ptr, size_t *size) { + void *r = (void *)ptr; + size_t s = 0; + for (;;) { + void *page = (void *)((uintptr_t)ptr & (uintptr_t)(~(PAGE_SIZE - 1))); + if (!is_valid_userpointer(page, PAGE_SIZE)) + return NULL; + for (; (uintptr_t)ptr & (PAGE_SIZE - 1); ptr++, s++) + if (!*ptr) { + if (size) + *size = s; + return r; + } + } +} + +void *is_valid_userpointer(const void *ptr, size_t s) { + uintptr_t t = (uintptr_t)ptr; + size_t num_pages = (uintptr_t)align_page((void *)s) / 0x1000; + for (size_t i = 0; i < num_pages; i++, t += 0x1000) { + Page *page = get_page((void *)t, NULL, PAGE_NO_ALLOCATE, 0); + if (!page) + return NULL; + if (!page->present) + return NULL; + if (!page->user) + return NULL; + } + return (void *)ptr; +} + +void switch_page_directory(PageDirectory *directory) { + active_directory = directory; + asm("mov %0, %%cr3" ::"r"(directory->physical_address)); +} + +void enable_paging(void) { + asm("mov %cr0, %eax\n" + "or 0b10000000000000000000000000000000, %eax\n" + "mov %eax, %cr0\n"); +} + +extern uint32_t boot_page_directory; +extern uint32_t boot_page_table1; + +void paging_init(void) { + uint32_t *cr3; + asm volatile("mov %%cr3, %0" : "=r"(cr3)); + uint32_t *virtual = (uint32_t *)((uint32_t)cr3 + 0xC0000000); + + kernel_directory = &real_kernel_directory; + kernel_directory->physical_address = (uint32_t)cr3; + for (uint32_t i = 0; i < 1024; i++) { + kernel_directory->physical_tables[i] = virtual[i]; + + if (!kernel_directory->physical_tables[i]) { + kernel_directory->tables[i] = NULL; + continue; + } + + kernel_directory->tables[i] = + (PageTable *)(0xC0000000 + (virtual[i] & ~(0xFFF))); + + // Loop through the pages in the table + PageTable *table = kernel_directory->tables[i]; + for (size_t j = 0; j < 1024; j++) { + if (!table->pages[j].present) + continue; + // Add the frame to our bitmap to ensure it does not get used by + // another newly created page. + write_to_frame(table->pages[j].frame * 0x1000, 1); + } + } + + switch_page_directory(kernel_directory); + kernel_directory = clone_directory(kernel_directory); + + // Make null dereferences crash. + switch_page_directory(kernel_directory); + get_page(NULL, kernel_directory, PAGE_ALLOCATE, 0)->present = 0; + switch_page_directory(clone_directory(kernel_directory)); + // FIXME: Really hacky solution. Since page table creation needs to + // allocate memory but memory allocation requires page table creation + // they depend on eachother. The bad/current solution is just to + // allocate a bunch of tables so the memory allocator has enough. + for (uintptr_t i = 0; i < 140; i++) + allocate_frame( + get_page((void *)((0x302 + i) * 0x1000 * 1024), NULL, PAGE_ALLOCATE, 0), + 1, 1); + move_stack(0xA0000000, 0xC00000); +} diff --git a/cpu/gdt.c b/cpu/gdt.c new file mode 100644 index 0000000..28853cf --- /dev/null +++ b/cpu/gdt.c @@ -0,0 +1,72 @@ +#include "gdt.h" + +extern void flush_tss(void); +extern void load_gdt(void *); + +typedef struct tss_entry_struct tss_entry_t; + +tss_entry_t tss_entry; + +typedef union { + struct GDT_Entry s; + uint64_t raw; +} GDT_Entry; + +GDT_Entry gdt_entries[6] = {0}; +GDT_Pointer gdtr; + +extern uint32_t inital_esp; +void write_tss(struct GDT_Entry *gdt_entry) { + uint32_t base = (uint32_t)&tss_entry; + uint32_t limit = sizeof(tss_entry); + + gdt_entry->limit_low = limit; + gdt_entry->base_low = base; + gdt_entry->accessed = 1; + gdt_entry->read_write = 0; + gdt_entry->conforming_expand_down = 0; + gdt_entry->code = 1; + gdt_entry->code_data_segment = 0; + gdt_entry->DPL = 0; + gdt_entry->present = 1; + gdt_entry->limit_high = limit >> 16; + gdt_entry->available = 0; + gdt_entry->long_mode = 0; + gdt_entry->big = 0; + gdt_entry->gran = 0; + gdt_entry->base_high = (base & ((uint32_t)0xff << 24)) >> 24; + + memset(&tss_entry, 0, sizeof tss_entry); + tss_entry.ss0 = GDT_KERNEL_DATA_SEGMENT * GDT_ENTRY_SIZE; + register uint32_t esp asm("esp"); + tss_entry.esp0 = esp; +} + +void gdt_init() { + gdt_entries[GDT_NULL_SEGMENT].raw = 0x0; + gdt_entries[GDT_KERNEL_CODE_SEGMENT].raw = + 0xCF9A000000FFFF; // Kernel code segment + gdt_entries[GDT_KERNEL_DATA_SEGMENT].raw = + 0xCF92000000FFFF; // Kernel data segment + + // Usermode code segment + memcpy(&gdt_entries[GDT_USERMODE_CODE_SEGMENT], + &gdt_entries[GDT_KERNEL_CODE_SEGMENT], GDT_ENTRY_SIZE); + + // Usermode data segment + memcpy(&gdt_entries[GDT_USERMODE_DATA_SEGMENT], + &gdt_entries[GDT_KERNEL_DATA_SEGMENT], GDT_ENTRY_SIZE); + + // Set DPL to 3 to indicate that the segment is in ring 3 + gdt_entries[GDT_USERMODE_CODE_SEGMENT].s.DPL = 3; + gdt_entries[GDT_USERMODE_DATA_SEGMENT].s.DPL = 3; + + write_tss((struct GDT_Entry *)&gdt_entries[GDT_TSS_SEGMENT]); + + gdtr.offset = (uint32_t)&gdt_entries; + gdtr.size = sizeof(gdt_entries) - 1; + + asm("cli"); + load_gdt(&gdtr); + flush_tss(); +} diff --git a/cpu/gdt.h b/cpu/gdt.h new file mode 100644 index 0000000..a490dea --- /dev/null +++ b/cpu/gdt.h @@ -0,0 +1,76 @@ +#ifndef GDT_H +#define GDT_H +#include +#include + +#define GDT_ENTRY_SIZE 0x8 +#define GDT_NULL_SEGMENT 0x0 +#define GDT_KERNEL_CODE_SEGMENT 0x1 +#define GDT_KERNEL_DATA_SEGMENT 0x2 +#define GDT_USERMODE_CODE_SEGMENT 0x3 +#define GDT_USERMODE_DATA_SEGMENT 0x4 +#define GDT_TSS_SEGMENT 0x5 + +struct GDT_Entry +{ + uint16_t limit_low; + uint32_t base_low : 24; + uint32_t accessed : 1; + uint32_t read_write : 1; // readable for code, writable for data + uint32_t conforming_expand_down : 1; // conforming for code, expand down for data + uint32_t code : 1; // 1 for code, 0 for data + uint32_t code_data_segment : 1; // should be 1 for everything but TSS and LDT + uint32_t DPL : 2; // privilege level + uint32_t present : 1; + uint32_t limit_high : 4; + uint32_t available : 1; // only used in software; has no effect on hardware + uint32_t long_mode : 1; + uint32_t big : 1; // 32-bit opcodes for code, uint32_t stack for data + uint32_t gran : 1; // 1 to use 4k page addressing, 0 for byte addressing + uint8_t base_high; +}__attribute__((packed)); + +typedef struct GDT_Pointer +{ + uint16_t size; + uint32_t offset; +}__attribute__((packed)) GDT_Pointer; + +struct tss_entry_struct +{ + uint32_t prev_tss; // The previous TSS - with hardware task switching these form a kind of backward linked list. + uint32_t esp0; // The stack pointer to load when changing to kernel mode. + uint32_t ss0; // The stack segment to load when changing to kernel mode. + // Everything below here is unused. + uint32_t esp1; // esp and ss 1 and 2 would be used when switching to rings 1 or 2. + uint32_t ss1; + uint32_t esp2; + uint32_t ss2; + uint32_t cr3; + uint32_t eip; + uint32_t eflags; + uint32_t eax; + uint32_t ecx; + uint32_t edx; + uint32_t ebx; + uint32_t esp; + uint32_t ebp; + uint32_t esi; + uint32_t edi; + uint32_t es; + uint32_t cs; + uint32_t ss; + uint32_t ds; + uint32_t fs; + uint32_t gs; + uint32_t ldt; + uint16_t trap; + uint16_t iomap_base; +} __attribute__((packed)); + +void gdt_init(); + +uint8_t gen_access_byte(uint8_t priv, uint8_t s, uint8_t ex, uint8_t dc, uint8_t rw); +uint64_t gen_gdt_entry(uint32_t base, uint32_t limit, uint8_t access_byte, uint8_t flag); +uint8_t gen_flag(uint8_t gr, uint8_t sz); +#endif diff --git a/cpu/idt.c b/cpu/idt.c new file mode 100644 index 0000000..832162c --- /dev/null +++ b/cpu/idt.c @@ -0,0 +1,265 @@ +#include +#include +#include + +#define MASTER_PIC_COMMAND_PORT 0x20 +#define MASTER_PIC_DATA_PORT 0x21 +#define SLAVE_PIC_COMMAND_PORT 0xA0 +#define SLAVE_PIC_DATA_PORT 0xA1 +#define KEYBOARD_DATA_PORT 0x60 +#define KEYBOARD_STATUS_PORT 0x64 +#define KERNEL_CODE_SEGMENT_OFFSET GDT_ENTRY_SIZE *GDT_KERNEL_CODE_SEGMENT + +#define IDT_MAX_ENTRY 256 + +struct IDT_Descriptor { + uint16_t low_offset; + uint16_t code_segment_selector; + uint8_t zero; // Always should be zero + uint8_t type_attribute; + uint16_t high_offset; +} __attribute__((packed)) __attribute__((aligned(4))); + +struct IDT_Pointer { + uint16_t size; + struct IDT_Descriptor **interrupt_table; +} __attribute__((packed)); + +struct IDT_Descriptor IDT_Entry[IDT_MAX_ENTRY]; +struct IDT_Pointer idtr; + +extern void load_idtr(void *idtr); + +void format_descriptor(uint32_t offset, uint16_t code_segment, + uint8_t type_attribute, + struct IDT_Descriptor *descriptor) { + descriptor->low_offset = offset & 0xFFFF; + descriptor->high_offset = offset >> 16; + descriptor->type_attribute = type_attribute; + descriptor->code_segment_selector = code_segment; + descriptor->zero = 0; +} + +void install_handler(void (*handler_function)(), uint16_t type_attribute, + uint8_t entry) { + format_descriptor((uint32_t)handler_function, KERNEL_CODE_SEGMENT_OFFSET, + type_attribute, &IDT_Entry[entry]); +} + +__attribute__((no_caller_saved_registers)) void EOI(uint8_t irq) { + if (irq > 7) + outb(SLAVE_PIC_COMMAND_PORT, 0x20); + + outb(MASTER_PIC_COMMAND_PORT, 0x20); +} + +__attribute__((interrupt)) void +kernel_general_protection_fault(kernel_registers_t *regs) { + asm("cli"); + klog("General Protetion Fault", 0x1); + kprintf(" Error Code: %x\n", regs->error_code); + kprintf("Instruction Pointer: %x\n", regs->eip); + dump_backtrace(12); + for (;;) + ; + EOI(0xD - 8); +} + +__attribute__((interrupt)) void general_protection_fault(registers_t *regs) { + kprintf("\n"); + klog("KERNEL General Protetion Fault", 0x1); + kprintf(" Error Code: %x\n", regs->error_code); +#define EXTERNAL_TO_PROCESSOR (1 << 0) + +#define WAS(_b) if (regs->error_code & (_b)) + if (0 == regs->error_code) { + kprintf("This exception is not segment related."); + } else { + WAS(EXTERNAL_TO_PROCESSOR) { + kprintf("Exception originated externally to the processor."); + } + kprintf("Index references: "); + switch ((regs->error_code >> 1) & 0x3) { + case 0: + kprintf("GDT"); + break; + case 3: + case 1: + kprintf("IDT"); + break; + case 2: + kprintf("LDT"); + break; + } + kprintf("\n"); + kprintf("Segmenet index: %x\n", regs->error_code >> 15); + } + /* kprintf(" Page protection violation: %x\n", regs->error_code & 0x1); + kprintf(" Write access: %x\n", (regs->error_code & (0x1<<1)) >> 1); + kprintf(" No privilege violation: %x\n", (regs->error_code & (0x1<<2)) + >> 2); kprintf(" Instruction fetch: %x\n", (regs->error_code & (0x1<<4)) >> + 4); kprintf(" Shadow stack access: %x\n", (regs->error_code & (0x1<<6)) >> + 6);*/ + kprintf("Instruction Pointer: %x\n", regs->eip); + asm("hlt"); + EOI(0xD - 8); +} + +__attribute__((interrupt)) void double_fault(registers_t *regs) { + (void)regs; + klog("DOUBLE FAULT, THIS IS REALLY BAD", LOG_ERROR); + asm("hlt"); + for (;;) + ; +} +__attribute__((interrupt)) void page_fault(registers_t *regs) { + asm("cli"); + klog("Page Fault", LOG_ERROR); + if (get_current_task()) { + kprintf(" PID: %x\n", get_current_task()->pid); + kprintf(" Name: %s\n", get_current_task()->program_name); + } + kprintf(" Error Code: %x\n", regs->error_code); + kprintf(" Interrupt Number: %x\n", regs->interrupt_number); + kprintf(" Instruction Pointer: %x\n", regs->eip); + dump_backtrace(14); + asm("hlt"); + for (;;) + ; +} + +/* +__attribute__((interrupt)) void page_fault(registers_t *regs) { + asm("cli"); + klog("Page Fault", LOG_ERROR); + if (get_current_task()) { + kprintf(" PID: %x\n", get_current_task()->pid); + kprintf(" Name: %s\n", get_current_task()->program_name); + } + kprintf(" Error Code: %x\n", regs->error_code); + kprintf(" Interrupt Number: %x\n", regs->interrupt_number); +#define PAGE_PRESENT (1 << 0) +#define WRITE_ATTEMPT (1 << 1) +#define USER_LEVEL (1 << 2) +#define RESERVED_WRITE (1 << 3) +#define INSTRUCTION_FETCH (1 << 4) +#define PROTECTION_KEY_VIOLATION (1 << 5) +#define SHADOW_STACK_ACCESS (1 << 6) + +#define WAS(_b) if (regs->error_code & (_b)) + + WAS(PAGE_PRESENT) { kprintf(" Page was present.\n"); } + else { + kprintf(" Page is not present.\n"); + } + + WAS(WRITE_ATTEMPT) { kprintf(" Write attempt.\n"); } + else { + kprintf(" Read attempt.\n"); + } + + WAS(USER_LEVEL) { + get_current_task()->dead = 1; + kprintf(" Page fault in ring 3.\n"); + } + else { + kprintf(" Page fault in ring 0-2.\n"); + } + + WAS(INSTRUCTION_FETCH) { kprintf(" Attempted instruction fetch.\n"); } + + WAS(SHADOW_STACK_ACCESS) { kprintf(" Attempted shadow stack access.\n"); } + + kprintf(" Instruction Pointer: %x\n", regs->eip); + dump_backtrace(12); + asm("hlt"); + for (;;) + ; + EOI(0xE - 8); +}*/ + +static inline void io_wait(void) { outb(0x80, 0); } + +#define ICW1_ICW4 0x01 /* ICW4 (not) needed */ +#define ICW1_SINGLE 0x02 /* Single (cascade) mode */ +#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */ +#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */ +#define ICW1_INIT 0x10 /* Initialization - required! */ + +#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */ +#define ICW4_AUTO 0x02 /* Auto (normal) EOI */ +#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */ +#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */ +#define ICW4_SFNM 0x10 /* Special fully nested (not) */ + +void PIC_remap(int offset) { + unsigned char a1, a2; + a1 = inb(MASTER_PIC_DATA_PORT); + a2 = inb(SLAVE_PIC_DATA_PORT); + + // Send ICW1 and tell the PIC that we will issue a ICW4 + // Since there is no ICW1_SINGLE sent to indicate it is cascaded + // it means we will issue a ICW3. + outb(MASTER_PIC_COMMAND_PORT, ICW1_INIT | ICW1_ICW4); + io_wait(); + outb(SLAVE_PIC_COMMAND_PORT, ICW1_INIT | ICW1_ICW4); + io_wait(); + + // As a part of ICW2 this sends the offsets(the position to put IRQ0) of the + // vector tables. + outb(MASTER_PIC_DATA_PORT, offset); + io_wait(); + outb(SLAVE_PIC_DATA_PORT, offset + 0x8); + io_wait(); + + // This tells the master on which lines it is having slaves + outb(MASTER_PIC_DATA_PORT, 4); + io_wait(); + // This tells the slave the cascading identity. + outb(SLAVE_PIC_DATA_PORT, 2); + io_wait(); + + outb(MASTER_PIC_DATA_PORT, ICW4_8086); + io_wait(); + outb(SLAVE_PIC_DATA_PORT, ICW4_8086); + io_wait(); + + outb(MASTER_PIC_DATA_PORT, a1); + outb(SLAVE_PIC_DATA_PORT, a2); +} + +void IRQ_set_mask(unsigned char IRQline) { + uint16_t port; + uint8_t value; + port = (IRQline < 8) ? MASTER_PIC_DATA_PORT : SLAVE_PIC_DATA_PORT; + if (IRQline >= 8) + IRQline -= 8; + value = inb(port) | (1 << IRQline); + outb(port, value); +} + +void IRQ_clear_mask(unsigned char IRQline) { + uint16_t port; + uint8_t value; + port = (IRQline < 8) ? MASTER_PIC_DATA_PORT : SLAVE_PIC_DATA_PORT; + if (IRQline >= 8) { + IRQline -= 8; + } + value = inb(port) & ~(1 << IRQline); + outb(port, value); +} + +void idt_init(void) { + install_handler(page_fault, INT_32_TRAP_GATE(0x3), 0xE); + install_handler(double_fault, INT_32_TRAP_GATE(0x0), 0x8); + install_handler(kernel_general_protection_fault, INT_32_TRAP_GATE(0x0), 0xD); + + PIC_remap(0x20); + // IRQ_set_mask(0xc); + IRQ_set_mask(0xe); + IRQ_clear_mask(2); + + idtr.interrupt_table = (struct IDT_Descriptor **)&IDT_Entry; + idtr.size = (sizeof(struct IDT_Descriptor) * IDT_MAX_ENTRY) - 1; + load_idtr(&idtr); +} diff --git a/cpu/idt.h b/cpu/idt.h new file mode 100644 index 0000000..853b1e0 --- /dev/null +++ b/cpu/idt.h @@ -0,0 +1,76 @@ +typedef struct kernel_registers kernel_registers_t; +typedef struct registers registers_t; +#ifndef IDT_H +#define IDT_H +#include +#include +#include +#include +#include + +/* + * the type_attribute in the IDT_Entry struct + * is divded like this + * 7 0 + * +---+---+---+---+---+---+---+---+ + * | P | DPL | S | GateType | + * +---+---+---+---+---+---+---+---+ + * It is 8 bits(1 byte) long + * + * P + * Present bit. Should be zero for unused + * interrupts. + * + * DPL + * Specifices the maximum ring(0 to 3) the + * interrupt can be called from. + * + * S + * Storage segment. This should be set to + * zero for all interrupt and trap gates. + * + * GateType + * Possible IDT gate types: + * 0b0101 0x5 5 80386 32 bit task gate + * 0b0110 0x6 6 80286 16-bit interrupt gate + * 0b0111 0x7 7 80286 16-bit trap gate + * 0b1110 0xE 14 80386 32-bit interrupt gate + * 0b1111 0xF 15 80386 32-bit trap gate + */ + +// This enables the present bit. +#define INT_PRESENT 0x80 /* 0b10000000 */ + +#define INT_32_TASK_GATE(min_privlege) \ + (INT_PRESENT | 0x05 | (min_privlege << 5)) +#define INT_16_INTERRUPT_GATE(min_privlege) \ + (INT_PRESENT | 0x06 | (min_privlege << 5)) +#define INT_16_TRAP_GATE(min_privlege) \ + (INT_PRESENT | 0x07 | (min_privlege << 5)) +#define INT_32_INTERRUPT_GATE(min_privlege) \ + (INT_PRESENT | 0x0E | (min_privlege << 5)) +#define INT_32_TRAP_GATE(min_privlege) \ + (INT_PRESENT | 0x0F | (min_privlege << 5)) + +struct interrupt_frame; + +struct kernel_registers { + // uint32_t ds; + // uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; + // uint32_t interrupt_number, error_code; + uint32_t error_code; + uint32_t eip, cs, eflags; +}; + +struct registers { + uint32_t ds; + uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; + uint32_t interrupt_number, error_code; + uint32_t eip, cs, eflags, useresp, ss; +}; + +void idt_init(void); +__attribute__((no_caller_saved_registers)) void EOI(unsigned char irq); +void install_handler(void (*handler_function)(), uint16_t type_attribute, + uint8_t entry); +#endif diff --git a/cpu/int_syscall.s b/cpu/int_syscall.s new file mode 100644 index 0000000..8c3c25f --- /dev/null +++ b/cpu/int_syscall.s @@ -0,0 +1,20 @@ +.intel_syntax noprefix +.global int_syscall +.extern syscall_function_handler +int_syscall: + push ebp + push edi + push esi + push edx + push ecx + push ebx + push eax + call syscall_function_handler + add esp, 4 + pop ebx + pop ecx + pop edx + pop esi + pop edi + pop ebp + iretd diff --git a/cpu/io.h b/cpu/io.h new file mode 100644 index 0000000..9c33b66 --- /dev/null +++ b/cpu/io.h @@ -0,0 +1,11 @@ +#include + +__attribute__((no_caller_saved_registers)) extern void outsw(uint16_t, + uint32_t); +__attribute__((no_caller_saved_registers)) extern void outb(uint16_t, uint16_t); +__attribute__((no_caller_saved_registers)) extern uint16_t inb(uint16_t); +__attribute__((no_caller_saved_registers)) extern void +rep_outsw(uint16_t count, uint16_t port, volatile void *addy); +__attribute__((no_caller_saved_registers)) extern void +rep_insw(uint16_t count, uint16_t port, volatile void *addy); +extern void jump_usermode(void (*address)(), uint32_t stack_pointer); diff --git a/cpu/io.s b/cpu/io.s new file mode 100644 index 0000000..fe370a5 --- /dev/null +++ b/cpu/io.s @@ -0,0 +1,121 @@ +.intel_syntax noprefix +.global outsw +.global outb +.global inb +.global rep_outsw +.global rep_insw +.global flush_tss +.global load_idtr + +# ebx, esi, edi, ebp, and esp; +outsw: + push ebp + mov ebp, esp + push esi + mov dx, [ebp + 4+4] + mov esi, [ebp + 8+4] + outsw + pop esi + mov esp, ebp + pop ebp + ret + +outb: + mov al, [esp + 8] + mov dx, [esp + 4] + out dx, al + ret + +inb: + mov dx, [esp + 4] + in al, dx + ret + +rep_outsw: + push ebp + mov ebp, esp + push edi + mov ecx, [ebp + 4+4] #ECX is counter for OUTSW + mov edx, [ebp + 8+4] #Data port, in and out + mov edi, [ebp + 12+4] #Memory area + rep outsw #in to [RDI] + pop edi + mov esp, ebp + pop ebp + ret + +rep_insw: + push ebp + mov ebp, esp + push edi + mov ecx, [ebp + 4+4] #ECX is counter for INSW + mov edx, [ebp + 8+4] #Data port, in and out + mov edi, [ebp + 12+4] #Memory area + rep insw #in to [RDI] + pop edi + mov esp, ebp + pop ebp + ret + +flush_tss: + mov ax, 40 + ltr ax + ret + +load_idtr: + mov edx, [esp + 4] + lidt [edx] + ret + +test_user_function: + mov eax, 0x00 + int 0x80 + mov ecx, 0x03 + mov ebx, 0x04 + mov eax, 0x02 + int 0x80 + mov ebx, eax + mov eax, 0x01 + int 0x80 +loop: + jmp loop + ret + +.global spin_lock +.global spin_unlock +.extern locked + +spin_lock: + mov eax, 1 + xchg eax, ebx + test eax, eax + jnz spin_lock + ret + +spin_unlock: + xor eax, eax + xchg eax, ebx + ret + + +.global jump_usermode +jump_usermode: + mov ax, (4 * 8) | 3 # user data segment with RPL 3 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax # sysexit sets SS + + # setup wrmsr inputs + xor edx, edx # not necessary; set to 0 + mov eax, 0x100008 # SS=0x10+0x10=0x20, CS=0x8+0x10=0x18 + mov ecx, 0x174 # MSR specifier: IA32_SYSENTER_CS + wrmsr # set sysexit segments + + # setup sysexit inputs + mov edx, [esp + 4] # to be loaded into EIP + mov ecx, [esp + 8] # to be loaded into ESP + mov esp, ecx + mov ebp, ecx + sti + sysexit diff --git a/cpu/reload_gdt.s b/cpu/reload_gdt.s new file mode 100644 index 0000000..3a0119b --- /dev/null +++ b/cpu/reload_gdt.s @@ -0,0 +1,17 @@ +.section .text +.global load_gdt + +load_gdt: + mov 4(%esp), %eax + lgdt (%eax) + + mov $0x10, %eax + mov %eax, %ds + mov %eax, %es + mov %eax, %fs + mov %eax, %gs + mov %eax, %ss + jmp $0x8, $.long_jump +.long_jump: + ret + diff --git a/cpu/spinlock.c b/cpu/spinlock.c new file mode 100644 index 0000000..3f87423 --- /dev/null +++ b/cpu/spinlock.c @@ -0,0 +1,2 @@ +#include +uint8_t locked; diff --git a/cpu/spinlock.h b/cpu/spinlock.h new file mode 100644 index 0000000..93290c4 --- /dev/null +++ b/cpu/spinlock.h @@ -0,0 +1,5 @@ +#ifndef SPINLOCK_H +#define SPINLOCK_H +void spin_lock(int *l); +void spin_unlock(int *l); +#endif diff --git a/cpu/syscall.c b/cpu/syscall.c new file mode 100644 index 0000000..19c195f --- /dev/null +++ b/cpu/syscall.c @@ -0,0 +1,174 @@ +// FIXME: Make sure that the args variabel actually points to something +// valid. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#pragma GCC diagnostic ignored "-Wpedantic" + +int syscall_open(SYS_OPEN_PARAMS *args) { + char file[256]; + strcpy(file, args->file); + // const char *file = copy_and_allocate_user_string(args->file); + int flags = args->flags; + int mode = args->mode; + int rc = vfs_open(file, flags, mode); + // kfree((void *)file); + return rc; +} + +int syscall_exec(SYS_EXEC_PARAMS *args) { + const char *filename = copy_and_allocate_user_string(args->path); + + int argc = 0; + for (; args->argv[argc];) { + argc++; + } + + char **new_argv = kallocarray(argc + 1, sizeof(char *)); + for (int i = 0; i < argc; i++) + new_argv[i] = copy_and_allocate_user_string(args->argv[i]); + + new_argv[argc] = NULL; + + exec(filename, new_argv); + kfree((void *)filename); + for (int i = 0; i < argc; i++) + kfree(new_argv[i]); + kfree(new_argv); + return -1; +} + +int syscall_pipe(int fd[2]) { + pipe(fd); // FIXME: Error checking + return 0; +} + +int syscall_pread(SYS_PREAD_PARAMS *args) { + return vfs_pread(args->fd, args->buf, args->count, args->offset); +} + +int syscall_read(SYS_READ_PARAMS *args) { + if (!get_vfs_fd(args->fd)) + return -EBADF; + int rc = vfs_pread(args->fd, args->buf, args->count, + get_current_task()->file_descriptors[args->fd]->offset); + get_current_task()->file_descriptors[args->fd]->offset += rc; + return rc; +} + +int syscall_pwrite(SYS_PWRITE_PARAMS *args) { + return vfs_pwrite(args->fd, args->buf, args->count, args->offset); +} + +int syscall_write(int fd, const char *buf, size_t count) { + if (!get_vfs_fd(fd)) + return -EBADF; + int rc = vfs_pwrite(fd, (char *)buf, count, + get_current_task()->file_descriptors[fd]->offset); + get_current_task()->file_descriptors[fd]->offset += rc; + return rc; +} + +int syscall_dup2(SYS_DUP2_PARAMS *args) { + return vfs_dup2(args->org_fd, args->new_fd); +} + +void syscall_exit(int status) { + exit(status); + assert(0); +} + +void syscall_wait(int *status) { + asm("cli"); + if (!get_current_task()->child) { + if (status) + *status = -1; + return; + } + if (get_current_task()->child->dead) { + if (status) + *status = get_current_task()->child_rc; + return; + } + get_current_task()->halts[WAIT_CHILD_HALT] = 1; + switch_task(); + if (status) + *status = get_current_task()->child_rc; +} + +int syscall_fork(void) { return fork(); } + +int syscall_getpid(void) { return get_current_task()->pid; } + +void *align_page(void *a); + +int syscall_brk(void *addr) { + void *end = get_current_task()->data_segment_end; + if (!mmu_allocate_region(end, addr - end, MMU_FLAG_RW)) + return -ENOMEM; + get_current_task()->data_segment_end = align_page(addr); + return 0; +} + +void *syscall_sbrk(uintptr_t increment) { + asm("cli"); + void *rc = get_current_task()->data_segment_end; + void *n = + (void *)((uintptr_t)(get_current_task()->data_segment_end) + increment); + int rc2; + if (0 > (rc2 = syscall_brk(n))) + return (void *)rc2; + return rc; +} + +int syscall_close(int fd) { return vfs_close(fd); } + +int syscall_openpty(SYS_OPENPTY_PARAMS *args) { + assert(is_valid_userpointer(args, sizeof(SYS_OPENPTY_PARAMS))); + return openpty(args->amaster, args->aslave, args->name, args->termp, + args->winp); +} + +void (*syscall_functions[])() = { + (void(*))syscall_open, (void(*))syscall_read, + (void(*))syscall_write, (void(*))syscall_pread, + (void(*))syscall_pwrite, (void(*))syscall_fork, + (void(*))syscall_exec, (void(*))syscall_getpid, + (void(*))syscall_exit, (void(*))syscall_wait, + (void(*))syscall_brk, (void(*))syscall_sbrk, + (void(*))syscall_pipe, (void(*))syscall_dup2, + (void(*))syscall_close, (void(*))syscall_openpty, + (void(*))syscall_poll, (void(*))syscall_mmap, + (void(*))syscall_accept, (void(*))syscall_bind, + (void(*))syscall_socket, (void(*))syscall_shm_open, + (void(*))syscall_ftruncate, (void(*))syscall_stat, + (void(*))syscall_msleep, (void(*))syscall_uptime, +}; + +void syscall_function_handler(uint32_t eax, uint32_t arg1, uint32_t arg2, + uint32_t arg3, uint32_t arg4, uint32_t arg5) { + assert(eax < sizeof(syscall_functions) / sizeof(syscall_functions[0])); + syscall_functions[eax](arg1, arg2, arg3, arg4, arg5); +} + +extern void int_syscall(void); + +void syscalls_init(void) { + install_handler(int_syscall, INT_32_INTERRUPT_GATE(0x3), 0x80); +} diff --git a/cpu/syscall.h b/cpu/syscall.h new file mode 100644 index 0000000..51d50f2 --- /dev/null +++ b/cpu/syscall.h @@ -0,0 +1,59 @@ +#include "idt.h" +#include +#include + +void syscalls_init(void); + +typedef struct SYS_OPEN_PARAMS { + char *file; + int flags; + int mode; +} __attribute__((packed)) SYS_OPEN_PARAMS; + +typedef struct SYS_PREAD_PARAMS { + int fd; + void *buf; + size_t count; + size_t offset; +} __attribute__((packed)) SYS_PREAD_PARAMS; + +typedef struct SYS_READ_PARAMS { + int fd; + void *buf; + size_t count; +} __attribute__((packed)) SYS_READ_PARAMS; + +typedef struct SYS_PWRITE_PARAMS { + int fd; + void *buf; + size_t count; + size_t offset; +} __attribute__((packed)) SYS_PWRITE_PARAMS; + +typedef struct SYS_WRITE_PARAMS { + int fd; + void *buf; + size_t count; +} __attribute__((packed)) SYS_WRITE_PARAMS; + +typedef struct SYS_EXEC_PARAMS { + char *path; + char **argv; +} __attribute__((packed)) SYS_EXEC_PARAMS; + +typedef struct SYS_WAIT_PARAMS { + int *status; +} __attribute__((packed)) SYS_WAIT_PARAMS; + +typedef struct SYS_DUP2_PARAMS { + int org_fd; + int new_fd; +} __attribute__((packed)) SYS_DUP2_PARAMS; + +typedef struct SYS_OPENPTY_PARAMS { + int *amaster; + int *aslave; + char *name; + /*const struct termios*/ void *termp; + /*const struct winsize*/ void *winp; +} __attribute__((packed)) SYS_OPENPTY_PARAMS; diff --git a/crypto/ChaCha20/chacha20.c b/crypto/ChaCha20/chacha20.c new file mode 100644 index 0000000..5bf7aa2 --- /dev/null +++ b/crypto/ChaCha20/chacha20.c @@ -0,0 +1,29 @@ +#include "chacha20.h" + +#define ROTL(a, b) (((a) << (b)) | ((a) >> (32 - (b)))) +#define QR(a, b, c, d) \ + (a += b, d ^= a, d = ROTL(d, 16), c += d, b ^= c, b = ROTL(b, 12), \ + a += b, d ^= a, d = ROTL(d, 8), c += d, b ^= c, b = ROTL(b, 7)) +#define ROUNDS 20 + +void chacha_block(uint32_t out[16], uint32_t const in[16]) +{ + int i; + uint32_t x[16]; + + for (i = 0; i < 16; ++i) + x[i] = in[i]; + for (i = 0; i < ROUNDS; i += 2) { + QR(x[0], x[4], x[8], x[12]); + QR(x[1], x[5], x[9], x[13]); + QR(x[2], x[6], x[10], x[14]); + QR(x[3], x[7], x[11], x[15]); + + QR(x[0], x[5], x[10], x[15]); + QR(x[1], x[6], x[11], x[12]); + QR(x[2], x[7], x[8], x[13]); + QR(x[3], x[4], x[9], x[14]); + } + for (i = 0; i < 16; ++i) + out[i] = x[i] + in[i]; +} diff --git a/crypto/ChaCha20/chacha20.h b/crypto/ChaCha20/chacha20.h new file mode 100644 index 0000000..17532f3 --- /dev/null +++ b/crypto/ChaCha20/chacha20.h @@ -0,0 +1,15 @@ +#ifndef CHACHA20_H +#define CHACHA20_H +#include + +#define KEY 4 +#define KEY_SIZE 8*sizeof(uint32_t) +#define COUNT 12 +#define COUNT_SIZE sizeof(uint32_t) +#define COUNT_MAX (0x100000000-1) // 2^32 - 1 +#define NONCE 13 +#define NONCE_SIZE 2*sizeof(uint32_t) +#define BLOCK_SIZE 16*sizeof(uint32_t) + +void chacha_block(uint32_t out[16], uint32_t const in[16]); +#endif diff --git a/crypto/SHA1 b/crypto/SHA1 new file mode 160000 index 0000000..237ea70 --- /dev/null +++ b/crypto/SHA1 @@ -0,0 +1 @@ +Subproject commit 237ea7023cad8402932dfbde337d69e5f4d515f6 diff --git a/drivers/ata.c b/drivers/ata.c new file mode 100644 index 0000000..fd9b504 --- /dev/null +++ b/drivers/ata.c @@ -0,0 +1,253 @@ +#include +#include +#include +#include + +#define PRIMARY_BUS_BASEPORT 0x1F0 +#define SECONDAY_BUS_BASEPORT 0x170 + +#define PRIMARY_BUS_IRQ 14 +#define SECONDAY_BUS_IRQ 15 + +#define STATUS_PORT 7 +#define COMMAND_PORT 7 +#define DRIVE_SELECT 6 +#define LBAhi 5 +#define LBAmid 4 +#define LBAlo 3 +#define SECTOR_COUNT 2 +#define DATA_PORT 0 + +#define IDENTIFY 0xEC +#define READ_SECTORS 0x20 +#define WRITE_SECTORS 0x30 +#define CACHE_FLUSH 0xE7 + +#define STATUS_BSY ((1 << 7)) +#define STATUS_DF ((1 << 5)) +#define STATUS_DRQ ((1 << 3)) +#define STATUS_ERR ((1 << 0)) + +uint32_t io_base; + +unsigned char read_buffer[SECTOR_SIZE]; + +void select_drive(uint8_t master_slave) { + outb(io_base + DRIVE_SELECT, (master_slave) ? 0xA0 : 0xB0); +} + +int identify(int master_slave) { + select_drive(master_slave); + outb(io_base + SECTOR_COUNT, 0); + outb(io_base + LBAlo, 0); + outb(io_base + LBAmid, 0); + outb(io_base + LBAhi, 0); + outb(io_base + COMMAND_PORT, IDENTIFY); + if (0 == inb(io_base + STATUS_PORT)) + return 0; // Drive does not exist + + for (; 0 != (inb(io_base + STATUS_PORT) & STATUS_BSY);) + ; + + // Because of some ATAPI drives that do not + // follow spec, at this point we need to check + // the LBAmid and LBAhi ports to see if they are + // non-zero. If so, the drive is not ATA, and we + // should stop polling. + if (0 != inb(io_base + LBAmid) || 0 != inb(io_base + LBAhi)) { + klog("Drive is not ATA.", LOG_ERROR); + return -1; + } + + for (uint16_t status;;) { + status = inb(io_base + STATUS_PORT); + + if (1 == (status & STATUS_ERR)) { + klog("Drive ERR set.", LOG_ERROR); + return -2; + } + + if ((status & STATUS_DRQ)) + break; + } + + // The data is ready to read from the Data + // port (0x1F0). Read 256 16-bit values, + // and store them. + // TODO: This returns some intreasting information. + // https://wiki.osdev.org/ATA_PIO_Mode#Interesting_information_returned_by_IDENTIFY + uint16_t array[256]; + rep_insw(1 * SECTOR_SIZE / 16, io_base + DATA_PORT, array); + return 1; +} + +int poll_status(void) { + for (uint16_t status;;) { + // Read the Regular Status port until... + // We read this 15 times to give some + // time for the drive to catch up. + for (int n = 0; n < 15; n++) + status = inb(io_base + STATUS_PORT); + + // ERR or + // DF sets + if ((status & STATUS_ERR) || (status & STATUS_DF)) { + klog("Drive error set.", LOG_ERROR); + return 0; + } + + // BSY clears + // DRQ sets + if (0 == (status & STATUS_BSY) && 0 != (status & STATUS_DRQ)) + break; + } + return 1; +} + +// Instructions from: https://wiki.osdev.org/ATA_PIO_Mode#28_bit_PIO +void __attribute__((optimize("O0"))) +setup_drive_for_command(uint32_t lba, uint32_t sector_count) { + // 1. Send 0xE0 for the "master" or 0xF0 for + // the "slave", ORed with the highest 4 bits + // of the LBA to port 0x1F6 + outb(io_base + DRIVE_SELECT, 0xE0 | (0 << 4) | ((lba >> 24) & 0x0F)); + + // 2. Send a NULL byte to port 0x1F1, if you + // like (it is ignored and wastes + // lots of CPU time) + + // NOP + + // 3. Send the sectorcount to port 0x1F2 + outb(io_base + SECTOR_COUNT, sector_count); + + // 4. Send the low 8 bits of the LBA to port 0x1F3 + outb(io_base + LBAlo, (lba >> 0) & 0xFF); + + // 5. Send the next 8 bits of the LBA to port 0x1F4 + outb(io_base + LBAmid, (lba >> 8) & 0xFF); + + // 6. Send the next 8 bits of the LBA to port 0x1F5 + outb(io_base + LBAhi, (lba >> 16) & 0xFF); +} + +void delayed_rep_outsw(size_t n, uint16_t port, volatile uint8_t *buffer) { + for (volatile size_t i = 0; i < n; i++) { + outsw(port, (uint32_t)buffer); + buffer += 2; + // outsw(port, buffer); + } +} + +void __attribute__((optimize("O0"))) +ata_write_lba28(uint32_t lba, uint32_t sector_count, + volatile const uint8_t *buffer) { + setup_drive_for_command(lba, sector_count); + + outb(io_base + COMMAND_PORT, WRITE_SECTORS); + + for (volatile uint32_t i = 0; i < sector_count; i++) { + if (!poll_status()) { + // FIXME: Fail properly + for (;;) + ; + } + + delayed_rep_outsw(256, io_base + DATA_PORT, + (void *)((uint32_t)buffer + i * 256)); + } + + // Cache flush + outb(io_base + COMMAND_PORT, CACHE_FLUSH); + + // Wait for BSY to clear + for (;;) { + uint16_t status = inb(io_base + STATUS_PORT); + if (!(status & STATUS_BSY)) + break; + } +} + +// Instructions from: https://wiki.osdev.org/ATA_PIO_Mode#28_bit_PIO +void __attribute__((optimize("O0"))) +ata_read_lba28(uint32_t lba, uint32_t sector_count, volatile void *address) { + // Step 1-6 is done in this function. + setup_drive_for_command(lba, sector_count); + + // 7. Send the "READ SECTORS" command to port 0x17F + outb(io_base + COMMAND_PORT, READ_SECTORS); + + // 8. Wait for an IRQ or poll. + + // This step can be found in the for loop + + // 9. Transfer 256 16-bit values, a uint16_t at a time, + // into your buffer from I/O port 0x1F0 + for (volatile uint32_t i = 0; i < sector_count; i++) { + // 10. Then loop back to waiting for the next IRQ + // or poll again for each successive sector. + // 8. Wait for an IRQ or poll. + if (!poll_status()) { + // FIXME: Fail properly + for (;;) + ; + } + rep_insw(256, io_base + DATA_PORT, (void *)((uint32_t)address + i * 256)); + } +} + +void ata_init(void) { + io_base = PRIMARY_BUS_BASEPORT; + + // Before sending any data to the IO ports, + // read the Regular Status byte. The value + // 0xFF is an illegal status value, and + // indicates that the bus has no drives + if (0xFF == inb(io_base + STATUS_PORT)) { + klog("Bus has no drives", LOG_ERROR); + } + + // Issue IDENTIFY command + select_drive(1); +} + +void __attribute__((optimize("O0"))) +read_lba(uint32_t lba, void *address, size_t size, size_t offset) { + uintptr_t ptr = (uintptr_t)address; + lba += offset / SECTOR_SIZE; + offset = offset % SECTOR_SIZE; + asm("cli"); + size_t total_read = 0; + for (int i = 0; size > 0; i++) { + uint32_t read_len = + (SECTOR_SIZE < (size + offset)) ? (SECTOR_SIZE - offset) : size; + ata_read_lba28(lba + i, 1, read_buffer); + memcpy((void *)ptr, read_buffer + offset, read_len); + size -= read_len; + total_read += read_len; + ptr += read_len; + offset = 0; + } +} + +void write_lba(uint32_t lba, volatile void *address, size_t size, + size_t offset) { + uintptr_t ptr = (uintptr_t)address; + lba += offset / SECTOR_SIZE; + offset = offset % SECTOR_SIZE; + size_t total_write = 0; + uint8_t sector_buffer[512]; + for (int i = 0; size > 0; i++) { + ata_read_lba28(lba + i, 1, sector_buffer); + uint32_t write_len = + (SECTOR_SIZE < (size + offset)) ? (SECTOR_SIZE - offset) : size; + + memcpy(sector_buffer + offset, (void *)ptr, write_len); + ata_write_lba28(lba + i, 1, sector_buffer); + + size -= write_len; + total_write += write_len; + ptr += write_len; + offset = 0; + } +} diff --git a/drivers/ata.h b/drivers/ata.h new file mode 100644 index 0000000..3e88d7f --- /dev/null +++ b/drivers/ata.h @@ -0,0 +1,16 @@ +#include "../cpu/idt.h" +#include + +#define SECTOR_SIZE 512 + +void ata_init(void); + +void read_drive_chs(uint8_t head_index, uint8_t sector_count, + uint8_t sector_index, uint8_t cylinder_low_value, + uint8_t cylinder_high_value, void *address); +void read_drive_lba(uint32_t lba, uint8_t sector_count, void *address); +void read_lba(uint32_t lba, void *address, size_t size, size_t offset); +void write_lba(uint32_t lba, volatile void *address, size_t size, + size_t offset); +void ata_write_lba28(uint32_t lba, uint32_t sector_count, + volatile const uint8_t *buffer); diff --git a/drivers/keyboard.c b/drivers/keyboard.c new file mode 100644 index 0000000..8c96606 --- /dev/null +++ b/drivers/keyboard.c @@ -0,0 +1,188 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define PS2_REG_DATA 0x60 +#define PS2_REG_STATUS 0x64 +#define PS2_REG_COMMAND 0x64 + +#define PS2_CMD_ENABLE_FIRST_PORT 0xAE // no rsp + +#define PS2_CMD_TEST_CONTROLLER 0xAA // has rsp + +#define PS2_RSP_TEST_PASSED 0x55 +#define PS2_RSP_TEST_FAILED 0xFC + +#define PS2_CMD_SET_SCANCODE 0xF0 // has rsp +#define PS2_KB_ACK 0xFA +#define PS2_KB_RESEND 0xFE + +#define PS2_CMD_SET_MAKE_RELEASE 0xF8 // has rsp + +uint8_t kb_scancodes[3] = {0x43, 0x41, 0x3f}; + +FIFO_FILE *keyboard_fifo; + +uint8_t ascii_table[] = { + 'e', '\x1B', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 8, + '\t', + + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', + // 0, // [ + // 0, // ] + // 0, + // 0, // ? + '[', ']', + '\n', // ENTER + 'C', + + 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', + ';', // ; + '\'', // ; + '`', // ; + 'D', // LEFT SHIFT + '\\', // ; + 'z', 'x', 'c', 'v', 'b', 'n', 'm', + ',', // ; + '.', // ; + '/', // ; + 'U', // ; + 'U', // ; + 'U', // ; + ' ', // ; +}; + +uint8_t capital_ascii_table[] = { + 'e', '\x1B', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 8, + '\t', + + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', + // 0, // [ + // 0, // ] + // 0, + // 0, // ? + '{', '}', + '\n', // ENTER + 'C', + + 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', + ':', // ; + '\"', // ; + '~', // ; + 'D', // LEFT SHIFT + '\\', // ; + 'Z', 'X', 'C', 'V', 'B', 'N', 'M', + '<', // ; + '>', // ; + '?', // ; + 'U', // ; + 'U', // ; + 'U', // ; + ' ', // ; +}; + +vfs_inode_t *kb_inode; + +uint8_t keyboard_to_ascii(uint16_t key, uint8_t capital) { + if ((key & 0xFF) > sizeof(ascii_table)) + return 'U'; + if (capital) + return capital_ascii_table[key & 0xFF]; + else + return ascii_table[key & 0xFF]; +} + +uint8_t is_shift_down = 0; +uint8_t is_alt_down = 0; + +struct KEY_EVENT { + char c; + uint8_t mode; // (shift (0 bit)) (alt (1 bit)) + uint8_t release; // 0 pressed, 1 released +}; + +extern process_t *ready_queue; +__attribute__((interrupt)) void +int_keyboard(__attribute__((unused)) struct interrupt_frame *frame) { + outb(0x20, 0x20); + uint16_t c; + c = inb(PS2_REG_DATA); + int released = 0; + if (c & 0x80) { + switch ((c & ~(0x80)) & 0xFF) { + case 0x2A: // Left shift + case 0x36: // Right shift + is_shift_down = 0; + return; + case 0x38: + is_alt_down = 0; + return; + } + released = 1; + } else { + switch (c & 0xFF) { + case 0x2A: // Left shift + case 0x36: // Right shift + is_shift_down = 1; + return; + case 0x38: + is_alt_down = 1; + return; + } + released = 0; + } + unsigned char a = keyboard_to_ascii((c & ~(0x80)) & 0xFF, is_shift_down); + struct KEY_EVENT ev; + ev.c = a; + ev.release = released; + ev.mode = 0; + ev.mode |= is_shift_down << 0; + ev.mode |= is_alt_down << 1; + fifo_object_write((uint8_t *)&ev, 0, sizeof(ev), keyboard_fifo); + kb_inode->has_data = keyboard_fifo->has_data; +} + +#define PS2_WAIT_RECV \ + { \ + for (;;) { \ + uint8_t status = inb(PS2_REG_STATUS); \ + if (status & 0x1) \ + break; \ + } \ + } + +#define PS2_WAIT_SEND \ + { \ + for (;;) { \ + uint8_t status = inb(PS2_REG_STATUS); \ + if (!(status & (0x1 << 1))) \ + break; \ + } \ + } + +void install_keyboard(void) { + keyboard_fifo = create_fifo_object(); + install_handler(int_keyboard, INT_32_INTERRUPT_GATE(0x3), 0x21); +} + +int keyboard_read(uint8_t *buffer, uint64_t offset, uint64_t len, + vfs_fd_t *fd) { + (void)offset; + + if (0 == fd->inode->has_data) { + return -EAGAIN; + } + int rc = fifo_object_read(buffer, 0, len, keyboard_fifo); + fd->inode->has_data = keyboard_fifo->has_data; + return rc; +} + +void add_keyboard(void) { + kb_inode = devfs_add_file("/keyboard", keyboard_read, NULL, NULL, 0, 0, + FS_TYPE_CHAR_DEVICE); +} diff --git a/drivers/keyboard.h b/drivers/keyboard.h new file mode 100644 index 0000000..4b76f22 --- /dev/null +++ b/drivers/keyboard.h @@ -0,0 +1,11 @@ +#ifndef KEYBOARD_H +#define KEYBOARD_H + +#include +#include +#include + +void install_keyboard(void); +void add_keyboard(void); + +#endif diff --git a/drivers/mouse.c b/drivers/mouse.c new file mode 100644 index 0000000..23619a0 --- /dev/null +++ b/drivers/mouse.c @@ -0,0 +1,144 @@ +#include +#include +#include +#include +#include +#include + +uint8_t mouse_cycle = 0; // unsigned char +uint8_t mouse_uint8_t[3]; // signed char +uint8_t mouse_x = 0; // signed char +uint8_t mouse_y = 0; // signed char +vfs_inode_t *mouse_inode; +vfs_fd_t *mouse_fd; + +struct mouse_event { + uint8_t buttons; + uint8_t x; + uint8_t y; +}; + +int fs_mouse_write(uint8_t *buffer, uint64_t offset, uint64_t len, + vfs_fd_t *fd) { + int rc = fifo_object_write(buffer, offset, len, fd->inode->internal_object); + FIFO_FILE *f = fd->inode->internal_object; + mouse_inode->has_data = f->has_data; + return rc; +} + +int fs_mouse_read(uint8_t *buffer, uint64_t offset, uint64_t len, + vfs_fd_t *fd) { + FIFO_FILE *f = fd->inode->internal_object; + if (!mouse_inode->has_data) + return 0; + int rc = fifo_object_read(buffer, offset, len, f); + mouse_inode->has_data = f->has_data; + return rc; +} + +void add_mouse(void) { + mouse_inode = devfs_add_file("/mouse", fs_mouse_read, fs_mouse_write, NULL, 0, + 0, FS_TYPE_CHAR_DEVICE); + mouse_inode->internal_object = create_fifo_object(); + // Don't look at this + int fd = vfs_open("/dev/mouse", O_RDWR, 0); + mouse_fd = get_vfs_fd(fd); + get_current_task()->file_descriptors[fd] = NULL; +} + +__attribute__((interrupt)) void what(registers_t *r) { EOI(0xe); } + +__attribute__((interrupt)) void int_mouse(registers_t *r) { + (void)r; + EOI(12); + switch (mouse_cycle) { + case 0: + mouse_uint8_t[0] = inb(0x60); + if(!(mouse_uint8_t[0] & (1 << 3))) { + mouse_cycle = 0; + return; + } + mouse_cycle++; + break; + case 1: + mouse_uint8_t[1] = inb(0x60); + mouse_cycle++; + break; + case 2: + mouse_uint8_t[2] = inb(0x60); + mouse_x = mouse_uint8_t[1]; + mouse_y = mouse_uint8_t[2]; + mouse_cycle = 0; + struct mouse_event e; + e.buttons = mouse_uint8_t[0]; + e.x = mouse_x; + e.y = mouse_y; + raw_vfs_pwrite(mouse_fd, &e, sizeof(e), 0); + break; + } +} + +void mouse_wait(uint8_t a_type) { + uint32_t _time_out = 100000; + if (a_type == 0) { + while (_time_out--) { + if ((inb(0x64) & 1) == 1) { + return; + } + } + return; + } else { + while (_time_out--) { + if ((inb(0x64) & 2) == 0) { + return; + } + } + return; + } +} + +void mouse_write(uint8_t a_write) { + // Wait to be able to send a command + mouse_wait(1); + // Tell the mouse we are sending a command + outb(0x64, 0xD4); + // Wait for the final part + mouse_wait(1); + // Finally write + outb(0x60, a_write); +} + +uint8_t mouse_read() { + // Get's response from mouse + mouse_wait(0); + return inb(0x60); +} + +void install_mouse(void) { + uint8_t _status; // unsigned char + asm("cli"); + // Enable the auxiliary mouse device + mouse_wait(1); + outb(0x64, 0xA8); + + // Enable the interrupts + mouse_wait(1); + outb(0x64, 0x20); + mouse_wait(0); + _status = (inb(0x60) | 2); + mouse_wait(1); + outb(0x64, 0x60); + mouse_wait(1); + outb(0x60, _status); + + // Tell the mouse to use default settings + mouse_write(0xF6); + mouse_read(); // Acknowledge + + // Enable the mouse + mouse_write(0xF4); + mouse_read(); // Acknowledge + + install_handler(int_mouse, INT_32_INTERRUPT_GATE(0x3), 12 + 0x20); + install_handler(what, INT_32_INTERRUPT_GATE(0x3), 0xe + 0x20); +} diff --git a/drivers/mouse.h b/drivers/mouse.h new file mode 100644 index 0000000..5248143 --- /dev/null +++ b/drivers/mouse.h @@ -0,0 +1,5 @@ +#ifndef MOUSE_H +#define MOUSE_H +void install_mouse(void); +void add_mouse(void); +#endif diff --git a/drivers/pit.c b/drivers/pit.c new file mode 100644 index 0000000..711883c --- /dev/null +++ b/drivers/pit.c @@ -0,0 +1,55 @@ +#include "pit.h" + +#define PIT_IO_CHANNEL_0 0x40 +#define PIT_IO_MODE_COMMAND 0x43 + +uint64_t clock_num_ms_ticks = 0; +uint64_t pit_counter = 0; +uint16_t hertz; + +uint64_t pit_num_ms(void) { return clock_num_ms_ticks; } + +uint16_t read_pit_count(void) { + uint16_t count = 0; + + outb(PIT_IO_MODE_COMMAND, 0x0 /*0b00000000*/); + + count = inb(PIT_IO_CHANNEL_0); + count |= inb(PIT_IO_CHANNEL_0) << 8; + + return count; +} + +void set_pit_count(uint16_t hertz) { + uint16_t divisor = 1193180 / hertz; + + /* + * 0b00110110 + * ^^ + * channel - 0 + * ^^ + * r/w mode - LSB then MSB + * ^^^ + * mode - 3 Square Wave Mode + * ^ + * BCD - no + */ + outb(PIT_IO_MODE_COMMAND, 0x36 /*0b00110110*/); + outb(PIT_IO_CHANNEL_0, divisor & 0xFF); + outb(PIT_IO_CHANNEL_0, (divisor & 0xFF00) >> 8); +} + +__attribute__((interrupt)) void +int_clock(__attribute__((unused)) struct interrupt_frame *frame) { + outb(0x20, 0x20); + pit_counter++; + if (pit_counter >= hertz / 1000) { + pit_counter = 0; + clock_num_ms_ticks++; + } + switch_task(); +} + +void pit_install(void) { + install_handler(int_clock, INT_32_INTERRUPT_GATE(0x0), 0x20); +} diff --git a/drivers/pit.h b/drivers/pit.h new file mode 100644 index 0000000..8d9ce98 --- /dev/null +++ b/drivers/pit.h @@ -0,0 +1,12 @@ +#ifndef PIT_H +#define PIT_H +#include +#include +#include +#include +#include + +void pit_install(void); +void set_pit_count(uint16_t hertz); +uint64_t pit_num_ms(void); +#endif diff --git a/drivers/pst.c b/drivers/pst.c new file mode 100644 index 0000000..d063ec9 --- /dev/null +++ b/drivers/pst.c @@ -0,0 +1,17 @@ +#include +#include + +int openpty(int *amaster, int *aslave, char *name, + /*const struct termios*/ void *termp, + /*const struct winsize*/ void *winp) { + (void)name; + (void)termp; + (void) winp; + int fd[2]; + pipe(fd); // This depends upon that pipe will support read and write + // through the same fd. In reality this should not be the + // case. + *amaster = fd[0]; + *aslave = fd[1]; + return 0; +} diff --git a/drivers/pst.h b/drivers/pst.h new file mode 100644 index 0000000..e8fdfaa --- /dev/null +++ b/drivers/pst.h @@ -0,0 +1,7 @@ +#ifndef PST_H +#define PST_H +#include "../fs/vfs.h" + +int openpty(int *amaster, int *aslave, char *name, /*const struct termios*/ void *termp, + /*const struct winsize*/ void *winp); +#endif diff --git a/drivers/serial.c b/drivers/serial.c new file mode 100644 index 0000000..549d852 --- /dev/null +++ b/drivers/serial.c @@ -0,0 +1,35 @@ +#include "cpu/io.h" + +#define PORT 0x3f8 // COM1 + +int serial_init(void) { + outb(PORT + 1, 0x00); // Disable all interrupts + outb(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor) + outb(PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud + outb(PORT + 1, 0x00); // (hi byte) + outb(PORT + 3, 0x03); // 8 bits, no parity, one stop bit + outb(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold + outb(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set + outb(PORT + 4, 0x1E); // Set in loopback mode, test the serial chip + outb(PORT + 0, 0xAE); // Test serial chip (send byte 0xAE and check if serial + // returns same byte) + + // Check if serial is faulty (i.e: not same byte as sent) + if (inb(PORT + 0) != 0xAE) { + return 1; + } + + // If serial is not faulty set it in normal operation mode + // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled) + outb(PORT + 4, 0x0F); + return 0; +} + +int is_transmit_empty() { return inb(PORT + 5) & 0x20; } + +void write_serial(char a) { + while (is_transmit_empty() == 0) + ; + + outb(PORT, a); +} diff --git a/drivers/serial.h b/drivers/serial.h new file mode 100644 index 0000000..327765b --- /dev/null +++ b/drivers/serial.h @@ -0,0 +1,2 @@ +int serial_init(void); +void write_serial(char a); diff --git a/drivers/vbe.c b/drivers/vbe.c new file mode 100644 index 0000000..97f5507 --- /dev/null +++ b/drivers/vbe.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include +#include + +uint8_t *framebuffer; +uint32_t framebuffer_physical; +uint32_t framebuffer_width; +uint32_t framebuffer_height; +uint64_t framebuffer_size; + +vfs_vm_object_t vbe_vm_object; + +#define CHECK_FLAG(flags, bit) ((flags) & (1 << (bit))) + +void display_driver_init(multiboot_info_t *mbi) { + assert(CHECK_FLAG(mbi->flags, 12)); + framebuffer_width = mbi->framebuffer_width; + framebuffer_height = mbi->framebuffer_height; + + uint32_t bits_pp = mbi->framebuffer_bpp; + uint32_t bytes_pp = (bits_pp / 8) + (8 - (bits_pp % 8)); + + framebuffer_size = bytes_pp * framebuffer_width * framebuffer_height; + + framebuffer_physical = mbi->framebuffer_addr; + framebuffer = + mmu_map_frames((void *)(uint32_t)mbi->framebuffer_addr, framebuffer_size); +} + +vfs_vm_object_t *vbe_get_vm_object(uint64_t length, uint64_t offset, + vfs_fd_t *fd) { + (void)fd; + (void)length; + (void)offset; + vbe_vm_object.size = framebuffer_size; + int n = (uintptr_t)align_page((void *)(uint32_t)framebuffer_size) / 0x1000; + vbe_vm_object.object = kmalloc(sizeof(void *) * n); + for (int i = 0; i < n; i++) { + vbe_vm_object.object[i] = (void *)framebuffer_physical + (i * 0x1000); + } + return &vbe_vm_object; +} + +void add_vbe_device(void) { + devfs_add_file("/vbe", NULL, NULL, vbe_get_vm_object, 1, 1, + FS_TYPE_BLOCK_DEVICE); +} diff --git a/drivers/vbe.h b/drivers/vbe.h new file mode 100644 index 0000000..4df2221 --- /dev/null +++ b/drivers/vbe.h @@ -0,0 +1,7 @@ +#ifndef VBE_H +#define VBE_H +#include +void display_driver_init(multiboot_info_t *mb); +void display_driver_cross(multiboot_info_t *mbi); +void add_vbe_device(void); +#endif // VBE_H diff --git a/elf.c b/elf.c new file mode 100644 index 0000000..ca8f89d --- /dev/null +++ b/elf.c @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include +#include + +void *load_elf_file(const char *f, uint32_t *ds) { + // ELFHeader *header = kmalloc(sizeof(ELFHeader)); + ELFHeader header; + int fd = vfs_open(f, O_RDONLY, 0); + if (fd < 0) { + return NULL; + } + + if (sizeof(header) != vfs_pread(fd, &header, sizeof(header), 0)) { + return NULL; + } + + if (0 != memcmp(header.e_ident, "\x7F\x45\x4C\x46" /* "\x7FELF" */, 4)) { + klog("Incorrect ELF signature", LOG_ERROR); + return NULL; + } + + if (0 > fd) { + return NULL; + } + Elf32_Phdr program_header; + assert(sizeof(program_header) == header.e_phentsize); + uint32_t header_offset = header.e_phoff; + uintptr_t end_of_code = 0; + for (int i = 0; i < header.e_phnum; + i++, header_offset += header.e_phentsize) { + if (0 >= + vfs_pread(fd, &program_header, sizeof(program_header), header_offset)) { + return NULL; + } + + // FIXME: Only one type is supported, which is 1(load). More should be + // added. + assert(1 == program_header.p_type); + + // 1. Clear p_memsz bytes at p_vaddr to 0.(We also allocate frames for + // that range) + uint32_t p_memsz = program_header.p_memsz; + uint32_t p_vaddr = program_header.p_vaddr; + + uint32_t pages_to_allocate = + (uint32_t)align_page((void *)(p_vaddr + p_memsz)); + pages_to_allocate -= p_vaddr - (p_vaddr % 0x1000); + pages_to_allocate /= 0x1000; + + mmu_allocate_region((void *)p_vaddr, pages_to_allocate * 0x1000, + MMU_FLAG_RW); + + flush_tlb(); + + uintptr_t e = program_header.p_vaddr + program_header.p_memsz; + if (e > end_of_code) + end_of_code = e; + + memset((void *)program_header.p_vaddr, 0, program_header.p_memsz); + + // 2. Copy p_filesz bytes from p_offset to p_vaddr + int rc = vfs_pread(fd, (void *)program_header.p_vaddr, + program_header.p_filesz, program_header.p_offset); + + assert(rc == (int)program_header.p_filesz); + } + *ds = end_of_code; + vfs_close(fd); + return (void *)header.e_entry; +} diff --git a/elf.h b/elf.h new file mode 100644 index 0000000..452ddbd --- /dev/null +++ b/elf.h @@ -0,0 +1,99 @@ +#ifndef ELF_H +#define ELF_H +#include +#include +#include +#include + +#define ET_NONE 0 // No file type +#define ET_REL 1 // Relocatable file +#define ET_EXEC 2 // Executable file +#define ET_DYN 3 // Shared object file +#define ET_CORE 4 // Core file +#define ET_LOPROC 0xff00 // Processor-specific +#define ET_HIPROC 0xffff // Processor-specific + +#define EM_NONE 0 // No machine +#define EM_M32 1 // AT&T WE 32100 +#define EM_SPARC 2 // SPARC +#define EM_386 3 // Intel 80386 +#define EM_68K 4 // Motorola 68000 +#define EM_88K 5 // Motorola 88000 +#define EM_860 7 // Intel 80860 +#define EM_MIPS 8 // MIPS RS3000 + +#define EV_NONE 0 // Invalid version +#define EV_CURRENT 1 // Current version + +#define ELF_EXECUTABLE (1 << 0) +#define ELF_WRITABLE (1 << 1) +#define ELF_READABLE (1 << 2) + +#define Elf32_Addr uint32_t // Unsigned program address +#define Elf32_Half uint16_t // Unsigned medium integer +#define Elf32_Off uint32_t // Unsigned file offset +#define Elf32_Sword uint32_t // Signed large integer +#define Elf32_Word uint32_t // Unsigned large integer + +#define ELF_EXEC (1 << 0) +#define ELF_WRITE (1 << 1) +#define ELF_READ (1 << 2) + +// ELF header +typedef struct { + unsigned char e_ident[16]; + Elf32_Half e_type; // Object file type (ET_*) + Elf32_Half e_machine; // Required architecture (EM_*) + Elf32_Word e_version; // Object file version (EV_*) + Elf32_Addr e_entry; // File entry point + Elf32_Off e_phoff; // Program header table's offset(bytes) + Elf32_Off e_shoff; // Section header table's offset(bytes) + Elf32_Word e_flags; + Elf32_Half e_ehsize; // ELF Header size + Elf32_Half + e_phentsize; // Size of program's header tables(all are the same size) + Elf32_Half e_phnum; // Amount of program headers + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; +} __attribute__((packed)) ELFHeader; + +// Section header +typedef struct { + Elf32_Word sh_name; + Elf32_Word sh_type; + Elf32_Word sh_flags; + Elf32_Addr sh_addr; + Elf32_Off sh_offset; + Elf32_Word sh_size; + Elf32_Word sh_link; + Elf32_Word sh_info; + Elf32_Word sh_addralign; + Elf32_Word sh_entsize; +} Elf32_Shdr; + +enum ShT_Types { + SHT_NULL = 0, // Null section + SHT_PROGBITS = 1, // Program information + SHT_SYMTAB = 2, // Symbol table + SHT_STRTAB = 3, // String table + SHT_RELA = 4, // Relocation (w/ addend) + SHT_NOBITS = 8, // Not present in file + SHT_REL = 9, // Relocation (no addend) +}; + +// Program header +typedef struct { + Elf32_Word p_type; + Elf32_Off p_offset; + Elf32_Addr p_vaddr; + Elf32_Addr p_paddr; + Elf32_Word p_filesz; + Elf32_Word p_memsz; + Elf32_Word p_flags; + Elf32_Word p_align; +} __attribute__((packed)) Elf32_Phdr; + + +void *load_elf_file(const char *f, uint32_t *ds); +#endif diff --git a/fs/devfs.c b/fs/devfs.c new file mode 100644 index 0000000..14748a7 --- /dev/null +++ b/fs/devfs.c @@ -0,0 +1,91 @@ +#include +#include +#include +#include +#include + +devfs_file files[20]; +int num_files = 0; + +vfs_inode_t *devfs_add_file( + char *path, + int (*read)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd), + int (*write)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd), + vfs_vm_object_t *(get_vm_object)(uint64_t length, uint64_t offset, + vfs_fd_t *fd), + uint8_t has_data, uint8_t can_write, int type) { + files[num_files].name = copy_and_allocate_string(path); + + vfs_inode_t *i = kmalloc(sizeof(vfs_inode_t)); + files[num_files].inode = i; + i->type = type; + i->read = read; + i->write = write; + i->close = NULL; + i->get_vm_object = get_vm_object; + i->has_data = has_data; + i->is_open = 1; + i->can_write = can_write; + num_files++; + return i; +} + +vfs_inode_t *devfs_open(const char *file) { + for (int i = 0; i < num_files; i++) + if (isequal_n(files[i].name, file, strlen(files[i].name))) + return files[i].inode; + + return 0; +} + +int devfs_read(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + return fd->inode->read(buffer, offset, len, fd); +} + +int devfs_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + return fd->inode->write(buffer, offset, len, fd); +} + +vfs_vm_object_t *devfs_get_vm_object(uint64_t length, uint64_t offset, + vfs_fd_t *fd) { + return fd->inode->get_vm_object(length, offset, fd); +} + +int stdout_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + (void)offset; + (void)fd; + + int rc = len; + for (; len--;) + putc(*buffer++); + return rc; +} + +int serial_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + (void)offset; + (void)fd; + + int rc = len; + for (; len--;) + write_serial(*buffer++); + return rc; +} + +void add_serial(void) { + devfs_add_file("/serial", NULL, serial_write, NULL, 0, 1, + FS_TYPE_CHAR_DEVICE); +} + +void add_stdout(void) { + devfs_add_file("/stdout", NULL, stdout_write, NULL, 0, 1, + FS_TYPE_CHAR_DEVICE); +} + +vfs_inode_t *devfs_mount(void) { + vfs_inode_t *root = kmalloc_eternal(sizeof(vfs_inode_t)); + root->open = devfs_open; + root->read = devfs_read; + root->write = devfs_write; + root->close = NULL; + return root; +} diff --git a/fs/devfs.h b/fs/devfs.h new file mode 100644 index 0000000..23a499e --- /dev/null +++ b/fs/devfs.h @@ -0,0 +1,26 @@ +#ifndef DEVFS_H +#define DEVFS_H +#include +#include +#include + +typedef struct devfs_file { + char *name; + vfs_inode_t *inode; +} devfs_file; + +vfs_inode_t *devfs_mount(void); +vfs_inode_t *devfs_open(const char *file); +int devfs_read(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd); +int devfs_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd); +void add_stdout(void); +void add_serial(void); +vfs_inode_t *devfs_add_file( + char *path, + int (*read)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd), + int (*write)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd), + vfs_vm_object_t *(*get_vm_object)(uint64_t length, uint64_t offset, + vfs_fd_t *fd), + uint8_t has_data, uint8_t can_write, int type); + +#endif diff --git a/fs/ext2.c b/fs/ext2.c new file mode 100644 index 0000000..3b4dba8 --- /dev/null +++ b/fs/ext2.c @@ -0,0 +1,633 @@ +#include +#include +#include +#include +#include + +#define EXT2_SUPERBLOCK_SECTOR 2 +#define EXT2_ROOT_INODE 2 + +#define BLOCKS_REQUIRED(_a, _b) ((_a) / (_b) + (((_a) % (_b)) != 0)) + +superblock_t *superblock; +uint32_t block_byte_size; +uint32_t inode_size; +uint32_t inodes_per_block; + +#define BLOCK_SIZE (block_byte_size) + +void ext2_close(vfs_fd_t *fd) { + return; // There is nothing to clear +} + +int read_inode(int inode_num, unsigned char *data, uint64_t size, + uint64_t offset, uint64_t *file_size); + +void ext2_read_block(uint32_t block, void *address, size_t size, + size_t offset) { + read_lba(block * block_byte_size / 512, address, size, offset); +} + +void ext2_write_block(uint32_t block, void *address, size_t size, + size_t offset) { + write_lba(block * block_byte_size / 512, address, size, offset); +} + +void write_group_descriptor(uint32_t group_index, bgdt_t *block_group) { + int starting_block = (1024 == block_byte_size) ? 2 : 1; + ext2_write_block(starting_block, block_group, sizeof(bgdt_t), + group_index * sizeof(bgdt_t)); +} + +void get_group_descriptor(uint32_t group_index, bgdt_t *block_group) { + int starting_block = (1024 == block_byte_size) ? 2 : 1; + ext2_read_block(starting_block, block_group, sizeof(bgdt_t), + group_index * sizeof(bgdt_t)); +} + +uint32_t num_block_groups(void) { + // Determining the Number of Block Groups + + // From the Superblock, extract the size of each block, the total + // number of inodes, the total number of blocks, the number of blocks + // per block group, and the number of inodes in each block group. From + // this information we can infer the number of block groups there are + // by: + + // Rounding up the total number of blocks divided by the number of + // blocks per block group + uint32_t num_blocks = superblock->num_blocks; + uint32_t num_blocks_in_group = superblock->num_blocks_in_group; + uint32_t b = num_blocks / num_blocks_in_group; + if (num_blocks % num_blocks_in_group != 0) + b++; + + // Rounding up the total number of inodes divided by the number of + // inodes per block group + uint32_t num_inodes = superblock->num_inodes; + uint32_t num_inodes_in_group = superblock->num_inodes_in_group; + uint32_t i = num_inodes / num_inodes_in_group; + if (num_inodes % num_inodes_in_group != 0) + i++; + // Both (and check them against each other) + assert(i == b); + return i; +} + +void ext2_block_containing_inode(uint32_t inode_index, uint32_t *block_index, + uint32_t *offset) { + assert(0 != inode_index); + bgdt_t block_group; + get_group_descriptor((inode_index - 1) / superblock->num_inodes_in_group, + &block_group); + + uint64_t full_offset = + ((inode_index - 1) % superblock->num_inodes_in_group) * inode_size; + *block_index = block_group.starting_inode_table + + (full_offset >> (superblock->block_size + 10)); + *offset = full_offset & (block_byte_size - 1); +} + +void ext2_get_inode_header(int inode_index, inode_t *data) { + uint32_t block_index; + uint32_t block_offset; + ext2_block_containing_inode(inode_index, &block_index, &block_offset); + + uint8_t mem_block[inode_size]; + ext2_read_block(block_index, mem_block, inode_size, block_offset); + + memcpy(data, mem_block, inode_size); +} + +void ext2_write_inode(int inode_index, inode_t *data) { + uint32_t block_index; + uint32_t block_offset; + ext2_block_containing_inode(inode_index, &block_index, &block_offset); + + uint8_t mem_block[inode_size]; + memcpy(mem_block, data, inode_size); + ext2_write_block(block_index, mem_block, inode_size, block_offset); +} + +int ext2_get_inode_in_directory(int dir_inode, char *file, + direntry_header_t *entry) { + // FIXME: Allocate sufficent size each time + unsigned char *data = kmalloc(block_byte_size * 5); + ASSERT_BUT_FIXME_PROPOGATE( + -1 != read_inode(dir_inode, data, block_byte_size * 5, 0, 0)); + + direntry_header_t *dir; + unsigned char *data_p = data; + for (; (dir = (direntry_header_t *)data_p)->inode; data_p += dir->size) { + if (0 == dir->size) + break; + if (0 == dir->name_length) + continue; + if (0 == + memcmp(data_p + sizeof(direntry_header_t), file, dir->name_length)) { + if (strlen(file) > dir->name_length) + continue; + if (entry) + memcpy(entry, data_p, sizeof(direntry_header_t)); + return dir->inode; + } + } + return 0; +} + +int ext2_read_dir(int dir_inode, unsigned char *buffer, size_t len, + size_t offset) { + unsigned char data[block_byte_size]; + read_inode(dir_inode, data, block_byte_size, 0, 0); + + direntry_header_t *dir; + struct dirent tmp_entry; + size_t n_dir = 0; + int rc = 0; + unsigned char *data_p = data; + for (; (dir = (direntry_header_t *)data_p)->inode && len > 0; + data_p += dir->size, n_dir++) { + if (0 == dir->size) + break; + if (0 == dir->name_length) + continue; + if (n_dir < (offset / sizeof(struct dirent))) + continue; + + memcpy(tmp_entry.d_name, data_p + sizeof(direntry_header_t), + dir->name_length); + tmp_entry.d_name[dir->name_length] = '\0'; + uint8_t *p = (uint8_t *)&tmp_entry; + size_t l = sizeof(struct dirent); + + l = (len < l) ? len : l; + memcpy(buffer, p, l); + len -= l; + rc += l; + } + return rc; +} + +uint32_t ext2_find_inode(const char *file) { + int cur_path_inode = EXT2_ROOT_INODE; + + if (*file == '/' && *(file + 1) == '\0') + return cur_path_inode; + + char *str = copy_and_allocate_string(file); + char *orig_str = str; + + char *start; + for (;;) { + int final = 0; + start = str + 1; + str++; + + for (; '/' != *str && '\0' != *str; str++) + ; + if ('\0' == *str) + final = 1; + + *str = '\0'; + + direntry_header_t a; + if (0 == (cur_path_inode = + ext2_get_inode_in_directory(cur_path_inode, start, &a))) { + kfree(orig_str); + return 0; + } + + if (final) + break; + + // The expected returned entry is a directory + if (TYPE_INDICATOR_DIRECTORY != a.type_indicator) { + kfree(orig_str); + kprintf("FAILED\n"); + return 0; + } + } + kfree(orig_str); + return cur_path_inode; +} + +uint32_t get_singly_block_index(uint32_t singly_block_ptr, uint32_t i) { + uint8_t block[block_byte_size]; + ext2_read_block(singly_block_ptr, block, block_byte_size, 0); + uint32_t index = *(uint32_t *)(block + (i * (32 / 8))); + return index; +} + +int get_block(inode_t *inode, uint32_t i) { + if (i < 12) + return inode->block_pointers[i]; + + i -= 12; + uint32_t singly_block_size = block_byte_size / (32 / 8); + uint32_t double_block_size = (singly_block_size * singly_block_size); + if (i < singly_block_size) { + return get_singly_block_index(inode->single_indirect_block_pointer, i); + } else if (i < double_block_size) { + i -= singly_block_size; + uint32_t singly_entry = get_singly_block_index( + inode->double_indirect_block_pointer, i / singly_block_size); + uint32_t offset_in_entry = i % singly_block_size; + int block = get_singly_block_index(singly_entry, offset_in_entry); + return block; + } + assert(0); + return 0; +} + +int get_free_block(int allocate) { + bgdt_t block_group; + uint8_t bitmap[BLOCK_SIZE]; + assert(0 < superblock->num_blocks_unallocated); + for (uint32_t g = 0; g < num_block_groups(); g++) { + get_group_descriptor(g, &block_group); + + if (block_group.num_unallocated_blocks_in_group == 0) { + kprintf("skip\n"); + continue; + } + + ext2_read_block(block_group.block_usage_bitmap, bitmap, BLOCK_SIZE, 0); + for (uint32_t i = 0; i < superblock->num_blocks_in_group; i++) { + if (!(bitmap[i >> 3] & (1 << (i % 8)))) { + if (allocate) { + bitmap[i >> 3] |= (1 << (i % 8)); + ext2_write_block(block_group.block_usage_bitmap, bitmap, BLOCK_SIZE, + 0); + block_group.num_unallocated_blocks_in_group--; + write_group_descriptor(g, &block_group); + superblock->num_blocks_unallocated--; + write_lba(EXT2_SUPERBLOCK_SECTOR, (void *)superblock, 2 * SECTOR_SIZE, + 0); + } + return i + g * superblock->num_blocks_in_group + 1; + } + } + } + return -1; +} + +int get_free_inode(int allocate) { + bgdt_t block_group; + assert(0 < superblock->num_inodes_unallocated); + for (uint32_t g = 0; g < num_block_groups(); g++) { + get_group_descriptor(g, &block_group); + + if (0 == block_group.num_unallocated_inodes_in_group) + continue; + + uint8_t bitmap[BLOCK_SIZE]; + ext2_read_block(block_group.inode_usage_bitmap, bitmap, BLOCK_SIZE, 0); + for (uint32_t i = 0; i < superblock->num_inodes_in_group; i++) { + if (!(bitmap[i / 8] & (1 << (i % 8)))) { + if (allocate) { + bitmap[i / 8] |= (1 << (i % 8)); + ext2_write_block(block_group.inode_usage_bitmap, bitmap, BLOCK_SIZE, + 0); + block_group.num_unallocated_inodes_in_group--; + write_group_descriptor(g, &block_group); + superblock->num_inodes_unallocated--; + write_lba(EXT2_SUPERBLOCK_SECTOR, (void *)superblock, 2 * SECTOR_SIZE, + 0); + } + return i + g * superblock->num_inodes_in_group + 1; + } + } + } + return -1; +} + +int write_inode(int inode_num, unsigned char *data, uint64_t size, + uint64_t offset, uint64_t *file_size, int append) { + (void)file_size; + uint8_t inode_buffer[inode_size]; + ext2_get_inode_header(inode_num, (inode_t *)inode_buffer); + inode_t *inode = (inode_t *)inode_buffer; + + uint64_t fsize = (uint64_t)(((uint64_t)inode->_upper_32size << 32) | + (uint64_t)inode->low_32size); + if (append) + offset = fsize; + + uint32_t block_start = offset / block_byte_size; + uint32_t block_offset = offset % block_byte_size; + + int num_blocks_used = inode->num_disk_sectors / (BLOCK_SIZE / SECTOR_SIZE); + + if (size + offset > fsize) + fsize = size + offset; + + int num_blocks_required = BLOCKS_REQUIRED(fsize, BLOCK_SIZE); + + for (int i = num_blocks_used; i < num_blocks_required; i++) { + if (i > 12) + assert(0); + int b = get_free_block(1 /*true*/); + assert(-1 != b); + inode->block_pointers[i] = b; + } + + inode->num_disk_sectors = num_blocks_required * (BLOCK_SIZE / SECTOR_SIZE); + + int bytes_written = 0; + for (int i = block_start; size; i++) { + uint32_t block = get_block(inode, i); + if (0 == block) { + kprintf("block_not_found\n"); + break; + } + + int write_len = ((size + block_offset) > block_byte_size) + ? (block_byte_size - block_offset) + : size; + ext2_write_block(block, data + bytes_written, write_len, block_offset); + block_offset = 0; + bytes_written += write_len; + size -= write_len; + } + inode->low_32size = fsize; + inode->_upper_32size = (fsize >> 32); + ext2_write_inode(inode_num, inode); + return bytes_written; +} + +int read_inode(int inode_num, unsigned char *data, uint64_t size, + uint64_t offset, uint64_t *file_size) { + // TODO: Fail if size is lower than the size of the file being read, and + // return the size of the file the callers is trying to read. + uint8_t inode_buffer[inode_size]; + ext2_get_inode_header(inode_num, (inode_t *)inode_buffer); + inode_t *inode = (inode_t *)inode_buffer; + + uint64_t fsize = (uint64_t)(((uint64_t)inode->_upper_32size << 32) | + (uint64_t)inode->low_32size); + + if (file_size) + *file_size = fsize; + + if (size > fsize - offset) + size -= ((size + offset) - fsize); + + if (size == 0) + return 0; + + if (offset > fsize) + return 0; + + uint32_t block_start = offset / block_byte_size; + uint32_t block_offset = offset % block_byte_size; + + int bytes_read = 0; + for (int i = block_start; size; i++) { + uint32_t block = get_block(inode, i); + if (0 == block) { + klog("Filesystem EXT2: Unable to find block", LOG_WARN); + return -1; + } + + int read_len = ((size + block_offset) > block_byte_size) + ? (block_byte_size - block_offset) + : size; + ext2_read_block(block, data + bytes_read, read_len, block_offset); + block_offset = 0; + bytes_read += read_len; + size -= read_len; + } + return bytes_read; +} + +size_t ext2_read_file_offset(const char *file, unsigned char *data, + uint64_t size, uint64_t offset, + uint64_t *file_size) { + // TODO: Fail if the file does not exist. + uint32_t inode = ext2_find_inode(file); + return read_inode(inode, data, size, offset, file_size); +} + +size_t ext2_read_file(const char *file, unsigned char *data, size_t size, + uint64_t *file_size) { + return ext2_read_file_offset(file, data, size, 0, file_size); +} + +int resolve_link(int inode_num) { + uint8_t tmp[inode_size]; + inode_t *inode = (inode_t *)tmp; + uint64_t inode_size = + (((uint64_t)inode->_upper_32size) << 32) & inode->low_32size; + assert(inode_size <= 60); + ext2_get_inode_header(inode_num, inode); + char *path = (char *)(tmp + (10 * 4)); + path--; + *path = '/'; + return ext2_find_inode(path); +} + +int ext2_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + uint64_t file_size; + int rc; + int inode_num = fd->inode->inode_num; + assert(fd->inode->type != FS_TYPE_DIRECTORY); + if (fd->inode->type == FS_TYPE_LINK) { + inode_num = resolve_link(inode_num); + } + rc = write_inode(inode_num, buffer, len, offset, &file_size, 0); + return rc; +} + +int ext2_read(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + uint64_t file_size; + int rc; + int inode_num = fd->inode->inode_num; + if (fd->inode->type == FS_TYPE_DIRECTORY) { + rc = ext2_read_dir(inode_num, buffer, len, offset); + return rc; + } + if (fd->inode->type == FS_TYPE_LINK) { + inode_num = resolve_link(inode_num); + } + rc = read_inode(inode_num, buffer, len, offset, &file_size); + return rc; +} + +vfs_inode_t *ext2_open(const char *path) { + uint32_t inode_num = ext2_find_inode(path); + if (0 == inode_num) + return NULL; + + inode_t ext2_inode[inode_size]; + ext2_get_inode_header(inode_num, ext2_inode); + uint64_t file_size = + ((uint64_t)(ext2_inode->_upper_32size) << 32) | ext2_inode->low_32size; + + uint8_t type; + switch ((ext2_inode->types_permissions / 0x1000)) { + case 0xA: + type = FS_TYPE_LINK; + break; + case 0x4: + type = FS_TYPE_DIRECTORY; + break; + default: + type = FS_TYPE_FILE; + break; + } + + return vfs_create_inode(inode_num, type, 1 /*has_data*/, 1 /*can_write*/, + 1 /*is_open*/, NULL /*internal_object*/, file_size, + ext2_open, ext2_create_file, ext2_read, ext2_write, + ext2_close, NULL /*get_vm_object*/); +} + +uint64_t end_of_last_entry_position(int dir_inode, uint64_t *entry_offset, + direntry_header_t *meta) { + // FIXME: Allocate sufficent size each time + unsigned char data[block_byte_size * 5]; + uint64_t file_size = 0; + read_inode(dir_inode, data, block_byte_size * 5, 0, &file_size); + assert(block_byte_size * 5 > file_size); + + direntry_header_t *dir; + unsigned char *data_p = data; + uint64_t pos = 0; + uint64_t prev = pos; + for (; pos < file_size && (dir = (direntry_header_t *)data_p)->size; + data_p += dir->size, prev = pos, pos += dir->size) + ; + if (entry_offset) + *entry_offset = prev; + if (meta) + memcpy(meta, ((char *)data) + prev, sizeof(direntry_header_t)); + return pos; +} + +int ext2_create_entry(const char *path, int mode, int *error) { + (void)mode; + *error = 0; + // Check if the file already exists + { + uint32_t inode_num = ext2_find_inode(path); + if (0 != inode_num) { + klog("ext2_create_file: File already exists", LOG_WARN); + *error = 1; + return inode_num; + } + } + + uint32_t parent_inode; + // Get the parent directory + char path_buffer[strlen(path) + 1]; + strcpy(path_buffer, path); + char *e = path_buffer; + for (; *e; e++) + ; + for (; *e != '/'; e--) + ; + *e = '\0'; + if (*path_buffer == '\0') { + parent_inode = EXT2_ROOT_INODE; + } else { + parent_inode = ext2_find_inode(path_buffer); + } + if (0 == parent_inode) { // Parent does not exist + klog("ext2_create_file: Parent does not exist", LOG_WARN); + *error = 1; + return -1; + } + + const char *filename = e + 1; + + int new_file_inode = get_free_inode(1); + if (-1 == new_file_inode) { + klog("ext2_create_file: Unable to find free inode", LOG_WARN); + *error = 1; + return -1; + } + assert(0 != new_file_inode); + + uint64_t entry_offset = 0; + direntry_header_t meta; + end_of_last_entry_position(parent_inode, &entry_offset, &meta); + + uint32_t padding_in_use = block_byte_size - entry_offset; + + kprintf("meta.size: %x\n", meta.size); + kprintf("padding_in_use: %x\n", padding_in_use); + // assert(padding_in_use == meta.size); + assert(padding_in_use >= (sizeof(direntry_header_t) + strlen(filename))); + + // Modify the entry to have its real size + meta.size = sizeof(direntry_header_t) + meta.name_length; + meta.size += (4 - (meta.size % 4)); + write_inode(parent_inode, (unsigned char *)&meta, sizeof(direntry_header_t), + entry_offset, NULL, 0); + + // Create new entry + uint32_t new_entry_offset = entry_offset + meta.size; + direntry_header_t entry; + entry.inode = new_file_inode; + entry.type_indicator = TYPE_INDICATOR_REGULAR; + entry.name_length = strlen(filename); + entry.size = (sizeof(direntry_header_t) + entry.name_length); + entry.size += (4 - (entry.size % 4)); + + uint32_t length_till_next_block = 1024 - (new_entry_offset % 1024); + if (0 == length_till_next_block) + length_till_next_block = 1024; + assert(entry.size < length_till_next_block); + entry.size = length_till_next_block; + + uint8_t buffer[entry.size]; + memset(buffer, 0, entry.size); + memcpy(buffer, &entry, sizeof(entry)); + memcpy(buffer + sizeof(entry), filename, entry.name_length); + write_inode(parent_inode, (unsigned char *)buffer, entry.size, + new_entry_offset, NULL, 0); + return new_file_inode; +} + +int ext2_create_file(const char *path, int mode) { + int err; + int new_file_inode = ext2_create_entry(path, mode, &err); + if (err) + return 0; + // Create the inode header + uint8_t inode_buffer[inode_size]; + inode_t *new_inode = (inode_t *)inode_buffer; + memset(inode_buffer, 0, inode_size); + new_inode->types_permissions = 0x8000; + new_inode->num_hard_links = 1; + ext2_write_inode(new_file_inode, new_inode); + return new_file_inode; +} + +vfs_inode_t *ext2_mount(void) { + vfs_inode_t *root = kmalloc_eternal(sizeof(vfs_inode_t)); + root->open = ext2_open; + root->read = ext2_read; + root->write = ext2_write; + root->close = ext2_close; + root->create_file = ext2_create_file; + parse_superblock(); + return root; +} + +void parse_superblock(void) { + superblock = ksbrk(2 * SECTOR_SIZE); + read_lba(EXT2_SUPERBLOCK_SECTOR, (void *)superblock, 2 * SECTOR_SIZE, 0); + block_byte_size = 1024 << superblock->block_size; + + if (0xEF53 != superblock->ext2_signature) { + klog("Incorrect ext2 signature in superblock.", LOG_ERROR); + for (;;) + ; // TODO: Fail properly + } + + if (1 <= superblock->major_version) + inode_size = ((ext_superblock_t *)superblock)->inode_size; + + inodes_per_block = block_byte_size / inode_size; +} diff --git a/fs/ext2.h b/fs/ext2.h new file mode 100644 index 0000000..63684da --- /dev/null +++ b/fs/ext2.h @@ -0,0 +1,139 @@ +#ifndef EXT2_H +#define EXT2_H +#include +#include +#include +#include + +typedef struct Superblock { + uint32_t num_inodes; + uint32_t num_blocks; + uint32_t num_blocks_reserved; + uint32_t num_blocks_unallocated; + uint32_t num_inodes_unallocated; + uint32_t superblock_block_num; + uint32_t block_size; + uint32_t fragment_size; + uint32_t num_blocks_in_group; + uint32_t num_fragments_in_group; + uint32_t num_inodes_in_group; + uint32_t last_mount; + uint32_t last_write; + uint16_t num_mounts_since_fsck; + uint16_t num_mounts_allowed; + uint16_t ext2_signature; // 0xEF53 + uint16_t fs_state; + uint16_t when_error; + uint16_t minor_version; + uint32_t last_fsck; + uint32_t interval_fsck; + uint32_t os_id; + uint32_t major_version; + uint16_t userid_reserved_blocks; + uint16_t groupid_reserved_blocks; +} __attribute__((packed)) superblock_t; + +typedef struct ExtendedSuperblock { + uint32_t num_inodes; + uint32_t num_blocks; + uint32_t num_blocks_reserved; + uint32_t num_blocks_unallocated; + uint32_t num_inodes_unallocated; + uint32_t superblock_block_num; + uint32_t block_size; + uint32_t fragment_size; + uint32_t num_blocks_group; + uint32_t num_fragments_group; + uint32_t num_inodes_group; + uint32_t last_mount; + uint32_t last_write; + uint16_t num_mounts_since_fsck; + uint16_t num_mounts_allowed; + uint16_t ext2_signature; // 0xEF53 + uint16_t fs_state; + uint16_t when_error; + uint16_t minor_version; + uint32_t last_fsck; + uint32_t interval_fsck; + uint32_t os_id; + uint32_t major_version; + uint16_t userid_reserved_blocks; + uint16_t groupid_reserved_blocks; + uint32_t pad; + uint16_t inode_size; +} __attribute__((packed)) ext_superblock_t; + +typedef struct BlockGroupDescriptorTable { + uint32_t block_usage_bitmap; + uint32_t inode_usage_bitmap; + uint32_t starting_inode_table; + uint16_t num_unallocated_blocks_in_group; + uint16_t num_unallocated_inodes_in_group; + uint16_t num_directories_group; +} __attribute__((packed)) bgdt_t; + +typedef struct INode { + uint16_t types_permissions; + uint16_t user_id; + uint32_t low_32size; + uint32_t last_access_time; + uint32_t creation_time; + uint32_t last_modification_time; + uint32_t deletion_time; + uint16_t group_id; + uint16_t num_hard_links; + uint32_t num_disk_sectors; + uint32_t flags; + uint32_t os_specific; + uint32_t block_pointers[12]; + uint32_t single_indirect_block_pointer; + uint32_t double_indirect_block_pointer; + uint32_t triple_indirect_block_pointer; + uint32_t gen_number; + uint32_t _extended_attribute_block; + uint32_t _upper_32size; + uint32_t address_fragment; + uint32_t os_specific2; +} __attribute__((packed)) inode_t; + +// 0 Unknown type +// 1 Regular file +// 2 Directory +// 3 Character device +// 4 Block device +// 5 FIFO +// 6 Socket +// 7 Symbolic link (soft link) +#define TYPE_INDICATOR_UNKOWN 0 +#define TYPE_INDICATOR_REGULAR 1 +#define TYPE_INDICATOR_DIRECTORY 2 +#define TYPE_INDICATOR_CHARACTER_DEVICE 3 +#define TYPE_INDICATOR_BLOCK_DEVICE 4 +#define TYPE_INDICATOR_FIFO 5 +#define TYPE_INDICATOR_SOCKET 6 +#define TYPE_INDICATOR_SOFT_LINK 7 + +#define FIFO 0x1000 +#define CHARACTER_DEVICE 0x2000 +#define DIRECTORY 0x4000 +#define BLOCK_DEVICE 0x6000 +#define REGULAR_FILE 0x8000 +#define SYMBOLIC_LINK 0xA000 +#define UNIX_SOCKET 0xC000 + +typedef struct DirectoryEntryHeader { + uint32_t inode; + uint16_t size; + uint8_t name_length; + uint8_t type_indicator; +} __attribute__((packed)) direntry_header_t; + +int ext2_create_file(const char *path, int mode); +vfs_inode_t *ext2_mount(void); +void parse_superblock(void); +size_t ext2_read_file_offset(const char *file, unsigned char *data, + uint64_t size, uint64_t offset, + uint64_t *file_size); +size_t ext2_read_file(const char *file, unsigned char *data, size_t size, + uint64_t *file_size); +#endif diff --git a/fs/fifo.c b/fs/fifo.c new file mode 100644 index 0000000..d515ed7 --- /dev/null +++ b/fs/fifo.c @@ -0,0 +1,97 @@ +#include "fifo.h" +#include + +#define STARTING_SIZE 4096 + +void fifo_close(vfs_fd_t *fd) { + // TODO: Implement + (void)fd; + return; +} + +int fifo_object_write(uint8_t *buffer, uint64_t offset, uint64_t len, + FIFO_FILE *file) { + (void)offset; + file->has_data = 1; + if (file->write_len + len >= file->buffer_len) { + file->can_write = 0; + return -EAGAIN; + } + memcpy(file->buffer + file->write_len, buffer, len); + file->write_len += len; + return len; +} + +int fifo_object_read(uint8_t *buffer, uint64_t offset, uint64_t len, + FIFO_FILE *file) { + (void)offset; + if (file->write_len == 0) { + file->has_data = 0; + return -EAGAIN; + } + + if (len == 0) + return 0; + + file->can_write = 1; + if (len > file->write_len) + len = file->write_len; + + memcpy(buffer, file->buffer, len); + // Shift bufffer to the left + memcpy(file->buffer, file->buffer + len, file->buffer_len - len); + + file->write_len -= len; + if (file->write_len == 0) { + file->has_data = 0; + } + return len; +} + +FIFO_FILE *create_fifo_object(void) { + FIFO_FILE *n = kmalloc(sizeof(FIFO_FILE)); + n->buffer = kmalloc(STARTING_SIZE); + n->buffer_len = STARTING_SIZE; + n->write_len = 0; + return n; +} + +int create_fifo(void) { + + int fd_n = 0; + for (; get_current_task()->file_descriptors[fd_n]; fd_n++) + ; + + vfs_fd_t *fd = kmalloc(sizeof(vfs_fd_t)); + fd->flags = O_RDWR | O_NONBLOCK; + get_current_task()->file_descriptors[fd_n] = fd; + fd->inode = kmalloc(sizeof(vfs_inode_t)); + + fd->inode->internal_object = (void *)create_fifo_object(); + fd->inode->open = NULL; + fd->inode->read = fifo_read; + fd->inode->write = fifo_write; + fd->inode->close = fifo_close; + fd->inode->get_vm_object = NULL; + fd->inode->is_open = 1; + + return fd_n; +} + +int fifo_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + (void)offset; + FIFO_FILE *file = (FIFO_FILE *)fd->inode->internal_object; + int rc = fifo_object_write(buffer, offset, len, file); + fd->inode->has_data = file->has_data; + fd->inode->can_write = file->can_write; + return rc; +} + +int fifo_read(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + FIFO_FILE *file = (FIFO_FILE *)fd->inode->internal_object; + file->is_blocking = !(fd->flags & O_NONBLOCK); + int rc = fifo_object_read(buffer, offset, len, file); + fd->inode->has_data = file->has_data; + fd->inode->can_write = file->can_write; + return rc; +} diff --git a/fs/fifo.h b/fs/fifo.h new file mode 100644 index 0000000..ee91ba1 --- /dev/null +++ b/fs/fifo.h @@ -0,0 +1,26 @@ +#ifndef FIFO_H +#define FIFO_H +#include "vfs.h" +#include +#include + +typedef struct { + char *buffer; + uint64_t buffer_len; + uint64_t write_len; + uint8_t is_blocking; + uint8_t has_data; + uint8_t can_write; +} FIFO_FILE; + +int create_fifo(void); +FIFO_FILE *create_fifo_object(void); +int fifo_object_write(uint8_t *buffer, uint64_t offset, uint64_t len, + FIFO_FILE *file); +int fifo_object_read(uint8_t *buffer, uint64_t offset, uint64_t len, + FIFO_FILE *file); +int fifo_write(uint8_t *buffer, uint64_t offset, uint64_t len, + vfs_fd_t *fd); +int fifo_read(uint8_t *buffer, uint64_t offset, uint64_t len, + vfs_fd_t *fd); +#endif diff --git a/fs/shm.c b/fs/shm.c new file mode 100644 index 0000000..00f8dfb --- /dev/null +++ b/fs/shm.c @@ -0,0 +1,98 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +HashMap *shared_memory_objects; + +void shm_init(void) { shared_memory_objects = hashmap_create(10); } + +int shm_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + vfs_vm_object_t *p = fd->inode->internal_object; + + if (offset > p->size) + return -EFBIG; + + if (offset + len > p->size) + len = p->size - offset; + + memcpy((void *)((uintptr_t)((uintptr_t)p->virtual_object + offset)), buffer, + len); + return len; +} + +int shm_read(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + vfs_vm_object_t *p = fd->inode->internal_object; + + if (offset > p->size) + return -EFBIG; + + if (offset + len > p->size) + len = p->size - offset; + + memcpy((void *)buffer, + (void *)((uintptr_t)((uintptr_t)p->virtual_object + offset)), len); + return len; +} + +vfs_vm_object_t *shm_get_vm_object(uint64_t length, uint64_t offset, + vfs_fd_t *fd) { + (void)length; + (void)offset; + vfs_vm_object_t *p = fd->inode->internal_object; + return p; +} + +int shm_open(const char *name, int oflag, mode_t mode) { + // Try to find or create a new shared memory object. + vfs_vm_object_t *internal_object = + hashmap_get_entry(shared_memory_objects, name); + if (!internal_object) { + // if (!(oflag & O_CREAT)) + // return -EMFILE; + internal_object = kmalloc(sizeof(vfs_vm_object_t)); + internal_object->object = NULL; + internal_object->size = 0; + hashmap_add_entry(shared_memory_objects, name, internal_object, NULL, 0); + } + + vfs_inode_t *inode = + vfs_create_inode(0 /*inode_num*/, 0 /*type*/, 1 /*has_data*/, + 1 /*can_write*/, 1 /*is_open*/, internal_object, + 0 /*file_size*/, NULL /*open*/, NULL /*create_file*/, + shm_read, shm_write, NULL /*close*/, shm_get_vm_object); + + vfs_fd_t *fd_ptr; + int fd = vfs_create_fd(oflag, mode, inode, &fd_ptr); + if (-1 == fd) { + kfree(inode); + return -EMFILE; + } + return fd; +} + +int shm_unlink(const char *name) { + (void)name; + return 0; +} + +int ftruncate(int fildes, uint64_t length) { + kprintf("ftruncate: %d\n", length); + vfs_fd_t *fd = get_current_task()->file_descriptors[fildes]; + if (!fd) + return -EBADF; + vfs_vm_object_t *p = fd->inode->internal_object; + p->size = length; + p->virtual_object = ksbrk(length); + int n = (uintptr_t)align_page((void *)(uint32_t)length) / 0x1000; + p->object = kmalloc(sizeof(void *) * n); + for (int i = 0; i < n; i++) + p->object[i] = + (void *)(get_page(p->virtual_object + (i * 0x1000), NULL, 0, 0)->frame * + 0x1000); + return 0; +} diff --git a/fs/shm.h b/fs/shm.h new file mode 100644 index 0000000..fbbdb5c --- /dev/null +++ b/fs/shm.h @@ -0,0 +1,13 @@ +#ifndef SHM_H +#define SHM_H +#include +#include + +typedef int mode_t; + +void shm_init(void); +int shm_open(const char *name, int oflag, mode_t mode); +int shm_unlink(const char *name); +int ftruncate(int fildes, uint64_t length); + +#endif diff --git a/fs/tmpfs.c b/fs/tmpfs.c new file mode 100644 index 0000000..2c5974b --- /dev/null +++ b/fs/tmpfs.c @@ -0,0 +1,94 @@ +#include +#include +#include +#include +#include +#include +#include + +void tmp_close(vfs_fd_t *fd) { + fd->inode->is_open = 0; + ((tmp_inode *)fd->inode->internal_object)->read_inode->is_open = 0; +} + +int tmp_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + tmp_inode *calling_file = fd->inode->internal_object; + tmp_inode *child_file = calling_file->read_inode->internal_object; + if (child_file->is_closed) + return -EPIPE; + + int rc = fifo_object_write(buffer, offset, len, child_file->fifo); + calling_file->read_inode->has_data = child_file->fifo->has_data; + fd->inode->can_write = child_file->fifo->can_write; + return rc; +} + +int tmp_read(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + tmp_inode *calling_file = fd->inode->internal_object; + tmp_inode *child_file = calling_file->read_inode->internal_object; + if (calling_file->is_closed) + return -EPIPE; + + int rc = fifo_object_read(buffer, offset, len, calling_file->fifo); + fd->inode->has_data = calling_file->fifo->has_data; + calling_file->read_inode->can_write = child_file->fifo->can_write; + return rc; +} + +void dual_pipe(int fd[2]) { + for (int i = 0; i < 2; i++) { + tmp_inode *pipe = kmalloc(sizeof(tmp_inode)); + pipe->fifo = create_fifo_object(); + + int has_data = 0; + int can_write = 1; + int is_open = 1; + void *internal_object = pipe; + vfs_inode_t *inode = vfs_create_inode( + 0 /*inode_num*/, 0 /*type*/, has_data, can_write, is_open, + internal_object, 0 /*file_size*/, NULL /*open*/, NULL /*create_file*/, + tmp_read, tmp_write, tmp_close, NULL /*get_vm_object*/); + assert(inode); + + vfs_fd_t *fd_ptr; + fd[i] = vfs_create_fd(O_RDWR | O_NONBLOCK, 0, inode, &fd_ptr); + assert(-1 != fd[i]); + } + vfs_inode_t *f_inode = get_current_task()->file_descriptors[fd[0]]->inode; + vfs_inode_t *s_inode = get_current_task()->file_descriptors[fd[1]]->inode; + tmp_inode *f_pipe = f_inode->internal_object; + tmp_inode *s_pipe = s_inode->internal_object; + f_pipe->read_inode = s_inode; + s_pipe->read_inode = f_inode; + f_pipe->is_closed = 0; + s_pipe->is_closed = 0; +} + +void pipe(int fd[2]) { + for (int i = 0; i < 2; i++) { + tmp_inode *pipe = kmalloc(sizeof(tmp_inode)); + pipe->fifo = create_fifo_object(); + + int has_data = 0; + int can_write = 1; + int is_open = 1; + void *internal_object = pipe; + vfs_inode_t *inode = vfs_create_inode( + 0 /*inode_num*/, 0 /*type*/, has_data, can_write, is_open, + internal_object, 0 /*file_size*/, NULL /*open*/, NULL /*create_file*/, + tmp_read, tmp_write, tmp_close, NULL /*get_vm_object*/); + assert(inode); + + vfs_fd_t *fd_ptr; + fd[i] = vfs_create_fd(O_RDWR, 0, inode, &fd_ptr); + assert(-1 != fd[i]); + } + vfs_inode_t *f_inode = get_current_task()->file_descriptors[fd[0]]->inode; + vfs_inode_t *s_inode = get_current_task()->file_descriptors[fd[1]]->inode; + tmp_inode *f_pipe = f_inode->internal_object; + tmp_inode *s_pipe = s_inode->internal_object; + f_pipe->read_inode = s_inode; + s_pipe->read_inode = f_inode; + f_pipe->is_closed = 0; + s_pipe->is_closed = 0; +} diff --git a/fs/tmpfs.h b/fs/tmpfs.h new file mode 100644 index 0000000..4052bd5 --- /dev/null +++ b/fs/tmpfs.h @@ -0,0 +1,16 @@ +#ifndef TMP_H +#define TMP_H +#include +#include + +#define TMP_BUFFER_SIZE (1024 * 10) + +typedef struct { + FIFO_FILE *fifo; + uint8_t is_closed; + vfs_inode_t *read_inode; +} tmp_inode; + +void pipe(int fd[2]); +void dual_pipe(int fd[2]); +#endif diff --git a/fs/vfs.c b/fs/vfs.c new file mode 100644 index 0000000..9842e11 --- /dev/null +++ b/fs/vfs.c @@ -0,0 +1,272 @@ +#include +#include +#include +#include +#include + +vfs_inode_t *root_dir; +vfs_mounts_t mounts[10]; +int num_mounts = 0; + +vfs_fd_t *get_vfs_fd(int fd) { + if (fd >= 100) { + klog("get_vfs_fd(): Tried to get out of range fd", LOG_WARN); + dump_backtrace(12); + return NULL; + } + if (fd < 0) { + klog("get_vfs_fd(): Tried to get out of range fd", LOG_WARN); + dump_backtrace(12); + return NULL; + } + return get_current_task()->file_descriptors[fd]; +} + +vfs_inode_t *vfs_create_inode( + int inode_num, int type, uint8_t has_data, uint8_t can_write, + uint8_t is_open, void *internal_object, uint64_t file_size, + vfs_inode_t *(*open)(const char *path), + int (*create_file)(const char *path, int mode), + int (*read)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd), + int (*write)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd), + void (*close)(vfs_fd_t *fd), + vfs_vm_object_t *(*get_vm_object)(uint64_t length, uint64_t offset, + vfs_fd_t *fd)) { + vfs_inode_t *r = kmalloc(sizeof(inode_t)); + r->inode_num = inode_num; + r->type = type; + r->has_data = has_data; + r->can_write = can_write; + r->is_open = is_open; + r->internal_object = internal_object; + r->file_size = file_size; + r->open = open; + r->create_file = create_file; + r->read = read; + r->write = write; + r->close = close; + r->get_vm_object = get_vm_object; + return r; +} + +int vfs_create_fd(int flags, int mode, vfs_inode_t *inode, vfs_fd_t **fd) { + process_t *p = (process_t *)get_current_task(); + int i; + for (i = 0; i < 100; i++) + if (!p->file_descriptors[i]) + break; + if (p->file_descriptors[i]) + return -1; + vfs_fd_t *r = kmalloc(sizeof(vfs_fd_t)); + r->flags = flags; + r->mode = mode; + r->inode = inode; + r->reference_count = 1; + p->file_descriptors[i] = r; + if (fd) + *fd = r; + return i; +} + +int vfs_create_file(const char *file) { + vfs_mounts_t *file_mount = 0; + int length = 0; + for (int i = 0; i < num_mounts; i++) { + int path_len = strlen(mounts[i].path); + if (path_len <= length) + continue; + + if (isequal_n(mounts[i].path, file, path_len)) { + length = path_len; + file_mount = &mounts[i]; + } + } + if (1 != length) + file += length; + + if (!file_mount) { + kprintf("vfs_internal_open could not find mounted path for file : %s\n", + file); + return 0; + } + // ext2_create_file("/etc/oscreated", 0); + assert(file_mount->local_root->create_file); + kprintf("Creating a file\n"); + return file_mount->local_root->create_file(file, 0); +} + +vfs_inode_t *vfs_internal_open(const char *file) { + vfs_mounts_t *file_mount = 0; + int length = 0; + for (int i = 0; i < num_mounts; i++) { + int path_len = strlen(mounts[i].path); + if (path_len <= length) + continue; + + if (isequal_n(mounts[i].path, file, path_len)) { + length = path_len; + file_mount = &mounts[i]; + } + } + if (1 != length) + file += length; + + if (!file_mount) { + kprintf("vfs_internal_open could not find mounted path for file : %s\n", + file); + return NULL; + } + + vfs_inode_t *ret = file_mount->local_root->open(file); + return ret; +} + +char *vfs_clean_path(const char *path, char *resolved_path) { + // char *const clean = kmalloc(strlen(path) + 1); + char *clean = resolved_path; + int prev_slash = 0; + char *ptr = clean; + for (; *path; path++) { + if (prev_slash && '/' == *path) { + continue; + } + prev_slash = ('/' == *path); + *ptr = *path; + ptr++; + } + *ptr = '\0'; + return clean; +} + +char *vfs_resolve_path(const char *file, char *resolved_path) { + if ('/' == *file) { + return vfs_clean_path(file, resolved_path); + } + const char *cwd = get_current_task()->current_working_directory; + size_t l = strlen(cwd); + assert(l > 0); + assert('/' == cwd[l - 1]); + // char *r = kmalloc(l + strlen(file) + 1); + char r[256]; + strcpy(r, cwd); + strcat(r, file); + char *final = vfs_clean_path(r, resolved_path); + // kfree(r); + return final; +} + +int vfs_open(const char *file, int flags, int mode) { + char resolved_path[256] = {0}; + vfs_resolve_path(file, resolved_path); + vfs_inode_t *inode = vfs_internal_open(resolved_path); + if (0 == inode) { + if (mode & O_CREAT) { + if (vfs_create_file(resolved_path)) { + klog("VFS: File created", LOG_NOTE); + return vfs_open(file, flags, mode); + } + klog("VFS: Could not create file", LOG_WARN); + } + return -ENOENT; + } + if (inode->type == FS_TYPE_UNIX_SOCKET) { + return uds_open(resolved_path); + } + + return vfs_create_fd(flags, mode, inode, NULL); +} + +int vfs_close(int fd) { + vfs_fd_t *fd_ptr = get_vfs_fd(fd); + if (NULL == fd_ptr) { + return -1; + } + assert(0 < fd_ptr->reference_count); + // Remove process reference + fd_ptr->reference_count--; + get_current_task()->file_descriptors[fd] = 0; + // If no references left then free the contents + if (0 == fd_ptr->reference_count) { + if (fd_ptr->inode->close) + fd_ptr->inode->close(fd_ptr); + + kfree(fd_ptr); + } + return 0; +} + +int raw_vfs_pread(vfs_fd_t *vfs_fd, void *buf, uint64_t count, + uint64_t offset) { + if (!(vfs_fd->flags & O_READ)) + return -EBADF; + return vfs_fd->inode->read(buf, offset, count, vfs_fd); +} + +int vfs_pread(int fd, void *buf, uint64_t count, uint64_t offset) { + if (fd >= 100) { + kprintf("EBADF : %x\n", fd); + return -EBADF; + } + if (fd < 0) { + dump_backtrace(12); + kprintf("EBADF : %x\n", fd); + return -EBADF; + } + vfs_fd_t *vfs_fd = get_current_task()->file_descriptors[fd]; + if (!vfs_fd) + return -EBADF; + int rc = raw_vfs_pread(vfs_fd, buf, count, offset); + if (-EAGAIN == rc && count > 0) { + if (!(vfs_fd->flags & O_NONBLOCK)) { + struct pollfd fds; + fds.fd = fd; + fds.events = POLLIN; + fds.revents = 0; + poll(&fds, 1, 0); + return vfs_pread(fd, buf, count, offset); + } + } + return rc; +} + +int raw_vfs_pwrite(vfs_fd_t *vfs_fd, void *buf, uint64_t count, + uint64_t offset) { + assert(vfs_fd); + assert(vfs_fd->inode); + assert(vfs_fd->inode->write); + return vfs_fd->inode->write(buf, offset, count, vfs_fd); +} + +int vfs_pwrite(int fd, void *buf, uint64_t count, uint64_t offset) { + vfs_fd_t *vfs_fd = get_vfs_fd(fd); + if (!vfs_fd) + return -EBADF; + if (!(vfs_fd->flags & O_WRITE)) { + return -EBADF; + } + return raw_vfs_pwrite(vfs_fd, buf, count, offset); +} + +vfs_vm_object_t *vfs_get_vm_object(int fd, uint64_t length, uint64_t offset) { + vfs_fd_t *vfs_fd = get_vfs_fd(fd); + if (!vfs_fd) + return NULL; + vfs_vm_object_t *r = vfs_fd->inode->get_vm_object(length, offset, vfs_fd); + return r; +} + +int vfs_dup2(int org_fd, int new_fd) { + get_current_task()->file_descriptors[new_fd] = + get_current_task()->file_descriptors[org_fd]; + get_current_task()->file_descriptors[new_fd]->reference_count++; + return 1; +} + +void vfs_mount(char *path, vfs_inode_t *local_root) { + int len = strlen(path); + mounts[num_mounts].path = kmalloc_eternal(len + 1); + memcpy(mounts[num_mounts].path, path, len); + mounts[num_mounts].path[len] = '\0'; + mounts[num_mounts].local_root = local_root; + num_mounts++; +} diff --git a/fs/vfs.h b/fs/vfs.h new file mode 100644 index 0000000..b3ef3e1 --- /dev/null +++ b/fs/vfs.h @@ -0,0 +1,94 @@ +typedef struct vfs_fd vfs_fd_t; +typedef struct vfs_inode vfs_inode_t; +typedef struct vfs_vm_object vfs_vm_object_t; +typedef struct vfs_mounts vfs_mounts_t; +#ifndef VFS_H +#define VFS_H +#include +#include +#include +#include +#include + +// FIXME: Is there some standard value for this? +#define O_NONBLOCK (1 << 0) +#define O_READ (1 << 1) +#define O_WRITE (1 << 2) +#define O_CREAT (1 << 3) +#define O_RDONLY O_READ +#define O_WRONLY O_WRITE +#define O_RDWR (O_WRITE | O_READ) + +#define FS_TYPE_FILE 0 +#define FS_TYPE_UNIX_SOCKET 1 +#define FS_TYPE_CHAR_DEVICE 2 +#define FS_TYPE_BLOCK_DEVICE 3 +#define FS_TYPE_DIRECTORY 4 +#define FS_TYPE_LINK 7 + +struct vfs_vm_object { + void *virtual_object; + void **object; + uint64_t size; +}; + +struct vfs_mounts { + char *path; + vfs_inode_t *local_root; +}; + +struct dirent { + unsigned int d_ino; // File serial number. + char d_name[PATH_MAX]; // Filename string of entry. +}; + +struct vfs_fd { + size_t offset; + int flags; + int mode; + int reference_count; // Number of usages of this file descriptor, + // once it reaches zero then the contents can + // be freed. + vfs_inode_t *inode; +}; + +struct vfs_inode { + int inode_num; + int type; + uint8_t has_data; + uint8_t can_write; + uint8_t is_open; + void *internal_object; + uint64_t file_size; + vfs_inode_t *(*open)(const char *path); + int (*create_file)(const char *path, int mode); + int (*read)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd); + int (*write)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd); + void (*close)(vfs_fd_t *fd); + vfs_vm_object_t *(*get_vm_object)(uint64_t length, uint64_t offset, + vfs_fd_t *fd); +}; + +int vfs_close(int fd); +vfs_fd_t *get_vfs_fd(int fd); +int vfs_open(const char *file, int flags, int mode); +void vfs_mount(char *path, vfs_inode_t *local_root); +int vfs_pwrite(int fd, void *buf, uint64_t count, uint64_t offset); +int raw_vfs_pwrite(vfs_fd_t *vfs_fd, void *buf, uint64_t count, + uint64_t offset); +int vfs_pread(int fd, void *buf, uint64_t count, uint64_t offset); +vfs_vm_object_t *vfs_get_vm_object(int fd, uint64_t length, uint64_t offset); +int vfs_dup2(int org_fd, int new_fd); +vfs_inode_t *vfs_internal_open(const char *file); +int vfs_create_fd(int flags, int mode, vfs_inode_t *inode, vfs_fd_t **fd); +vfs_inode_t *vfs_create_inode( + int inode_num, int type, uint8_t has_data, uint8_t can_write, + uint8_t is_open, void *internal_object, uint64_t file_size, + vfs_inode_t *(*open)(const char *path), + int (*create_file)(const char *path, int mode), + int (*read)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd), + int (*write)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd), + void (*close)(vfs_fd_t *fd), + vfs_vm_object_t *(*get_vm_object)(uint64_t length, uint64_t offset, + vfs_fd_t *fd)); +#endif diff --git a/halts.c b/halts.c new file mode 100644 index 0000000..821299d --- /dev/null +++ b/halts.c @@ -0,0 +1,102 @@ +#include +#include +#include + +int create_disconnect_inode_halt(vfs_inode_t *inode) { + volatile process_t *p = get_current_task(); + int i; + for (i = 0; i < 100; i++) + if (!p->disconnect_halt_inode[i]) + break; + + if (p->disconnect_halt_inode[i]) + return -1; + + p->disconnect_halt_inode[i] = inode; + + return i; +} + +int create_disconnect_fdhalt(vfs_fd_t *fd) { + assert(fd); + return create_disconnect_inode_halt(fd->inode); +} + +int create_read_inode_halt(vfs_inode_t *inode) { + volatile process_t *p = get_current_task(); + int i; + for (i = 0; i < 100; i++) + if (!p->read_halt_inode[i]) + break; + + if (p->read_halt_inode[i]) + return -1; + + p->read_halt_inode[i] = inode; + + return i; +} + +int create_read_fdhalt(vfs_fd_t *fd) { + assert(fd); + return create_read_inode_halt(fd->inode); +} + +int create_write_inode_halt(vfs_inode_t *inode) { + volatile process_t *p = get_current_task(); + int i; + for (i = 0; i < 100; i++) + if (!p->write_halt_inode[i]) + break; + + if (p->write_halt_inode[i]) + return -1; + + p->write_halt_inode[i] = inode; + + return i; +} + +int create_write_fdhalt(vfs_fd_t *fd) { + return create_write_inode_halt(fd->inode); +} + +void unset_read_fdhalt(int i) { get_current_task()->read_halt_inode[i] = NULL; } + +void unset_write_fdhalt(int i) { + get_current_task()->write_halt_inode[i] = NULL; +} + +void unset_disconnect_fdhalt(int i) { + get_current_task()->disconnect_halt_inode[i] = NULL; +} + +int isset_fdhalt(vfs_inode_t *read_halts[], vfs_inode_t *write_halts[], + vfs_inode_t *disconnect_halts[]) { + int blocked = 0; + for (int i = 0; i < 100; i++) { + if (!read_halts[i]) + continue; + if (read_halts[i]->has_data) { + return 0; + } + blocked = 1; + } + for (int i = 0; i < 100; i++) { + if (!write_halts[i]) + continue; + if (write_halts[i]->can_write) { + return 0; + } + blocked = 1; + } + for (int i = 0; i < 100; i++) { + if (!disconnect_halts[i]) + continue; + if (!disconnect_halts[i]->is_open) { + return 0; + } + blocked = 1; + } + return blocked; +} diff --git a/halts.h b/halts.h new file mode 100644 index 0000000..bd71673 --- /dev/null +++ b/halts.h @@ -0,0 +1,21 @@ +#ifndef HALTS_H +#define HALTS_H +#include +#include + +typedef struct { + uint8_t *ptr; + uint8_t active; +} halt_t; + +int create_read_fdhalt(vfs_fd_t *fd); +int create_read_inode_halt(vfs_inode_t *inode); +void unset_read_fdhalt(int i); +int create_write_fdhalt(vfs_fd_t *fd); +int create_write_inode_halt(vfs_inode_t *inode); +void unset_write_fdhalt(int i); +int create_disconnect_fdhalt(vfs_fd_t *fd); +void unset_disconnect_fdhalt(int i); +int isset_fdhalt(vfs_inode_t *read_halts[], vfs_inode_t *write_halts[], + vfs_inode_t *disconnect_halts[]); +#endif diff --git a/hashmap b/hashmap new file mode 160000 index 0000000..07dfe3b --- /dev/null +++ b/hashmap @@ -0,0 +1 @@ +Subproject commit 07dfe3b606e0d82b2e181b27344b5e4ce8849f31 diff --git a/includes/defs.h b/includes/defs.h new file mode 100644 index 0000000..3a373b3 --- /dev/null +++ b/includes/defs.h @@ -0,0 +1,5 @@ +#ifndef DEFS_H +#define DEFS_H +#define BYTE unsigned char +#define BYTEPTR BYTE* +#endif diff --git a/includes/mmu.h b/includes/mmu.h new file mode 100644 index 0000000..39c951b --- /dev/null +++ b/includes/mmu.h @@ -0,0 +1,61 @@ +#ifndef PAGING_H +#define PAGING_H +#include "kmalloc.h" +#include + +typedef uint8_t mmu_flags; + +#define MMU_FLAG_RW (1 << 0) +#define MMU_FLAG_KERNEL (1 << 1) + +void *next_page(void *a); +void *align_page(void *a); + +typedef struct Page { + uint32_t present : 1; + uint32_t rw : 1; + uint32_t user : 1; + uint32_t accessed : 1; + uint32_t dirty : 1; + uint32_t unused : 7; + uint32_t frame : 20; +} __attribute__((packed)) Page; + +typedef struct PageTable { + Page pages[1024]; +} __attribute__((packed)) PageTable; + +typedef struct PageDirectory { + PageTable *tables[1024]; + uint32_t physical_tables[1024]; + uint32_t physical_address; +} PageDirectory; + +int mmu_allocate_region(void *ptr, size_t n, mmu_flags flags); +void mmu_allocate_shared_kernel_region(void *rc, size_t n); +void *mmu_find_unallocated_virtual_range(void *addr, size_t length); +void mmu_remove_virtual_physical_address_mapping(void *ptr, size_t length); +void mmu_free_address_range(void *ptr, size_t length); +void mmu_map_directories(void *dst, PageDirectory *d, void *src, + PageDirectory *s, size_t length); +uint32_t mmu_get_number_of_allocated_frames(void); +void *mmu_map_frames(void *ptr, size_t s); +void mmu_map_physical(void *dst, PageDirectory *d, void *physical, + size_t length); +void mmu_free_pages(void *a, uint32_t n); + +void flush_tlb(void); +void paging_init(void); +PageDirectory *get_active_pagedirectory(void); +void move_stack(uint32_t new_stack_address, uint32_t size); +void switch_page_directory(PageDirectory *directory); +void *allocate_frame(Page *page, int rw, int is_kernel); +PageDirectory *clone_directory(PageDirectory *original); +void *virtual_to_physical(void *address, PageDirectory *directory); +void *is_valid_userpointer(const void *const p, size_t s); +void *is_valid_user_c_string(const char *ptr, size_t *size); +void *ksbrk(size_t s); + +Page *get_page(void *ptr, PageDirectory *directory, int create_new_page, + int set_user); +#endif diff --git a/includes/sys/types.h b/includes/sys/types.h new file mode 100644 index 0000000..1ccbf63 --- /dev/null +++ b/includes/sys/types.h @@ -0,0 +1,2 @@ +typedef int time_t; +typedef int pid_t; diff --git a/init/kernel.c b/init/kernel.c new file mode 100644 index 0000000..9f507e0 --- /dev/null +++ b/init/kernel.c @@ -0,0 +1,101 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__linux__) +#error "You are not using a cross-compiler." +#endif + +#if !defined(__i386__) +#error "This OS needs to be compiled with a ix86-elf compiler" +#endif + +uint32_t inital_esp; +uintptr_t data_end; + +void kernel_main(uint32_t kernel_end, unsigned long magic, unsigned long addr, + uint32_t inital_stack) { + data_end = kernel_end; + inital_esp = inital_stack; + + asm("cli"); + kprintf("If you see this then the serial driver works :D.\n"); + assert(magic == MULTIBOOT_BOOTLOADER_MAGIC); + + paging_init(); + klog("Paging Initalized", LOG_SUCCESS); + multiboot_info_t *mb = + mmu_map_frames((multiboot_info_t *)addr, sizeof(multiboot_info_t)); + + gdt_init(); + klog("GDT Initalized", LOG_SUCCESS); + + idt_init(); + klog("IDT Initalized", LOG_SUCCESS); + + syscalls_init(); + klog("Syscalls Initalized", LOG_SUCCESS); + + pit_install(); + set_pit_count(2000); + klog("PIT driver installed", LOG_SUCCESS); + + ata_init(); + klog("ATA Initalized", LOG_SUCCESS); + + tasking_init(); + klog("Tasking Initalized", LOG_SUCCESS); + + install_mouse(); + klog("PS2 Mouse driver installed", LOG_SUCCESS); + + install_keyboard(); + klog("PS2 Keyboard driver installed", LOG_SUCCESS); + + vfs_mount("/", ext2_mount()); + vfs_mount("/dev", devfs_mount()); + add_stdout(); + add_serial(); + add_random_devices(); + shm_init(); + + setup_random(); + + add_keyboard(); + add_mouse(); + + display_driver_init(mb); + add_vbe_device(); + int pid; + if (0 == (pid = fork())) { + char *argv[] = {"/init", NULL}; + if (0 == exec("/init", argv)) { + kprintf("exec() failed\n"); + } + } + for (;;) + ; +} diff --git a/isodir/boot/grub/grub.cfg b/isodir/boot/grub/grub.cfg new file mode 100644 index 0000000..b2f8404 --- /dev/null +++ b/isodir/boot/grub/grub.cfg @@ -0,0 +1,3 @@ +menuentry "myos" { + multiboot /boot/myos.bin +} diff --git a/kmalloc.c b/kmalloc.c new file mode 100644 index 0000000..f3c8238 --- /dev/null +++ b/kmalloc.c @@ -0,0 +1,233 @@ +#include +#include +#include +#define NEW_ALLOC_SIZE 0x30000 + +#define IS_FREE (1 << 0) +#define IS_FINAL (1 << 1) + +typedef struct MallocHeader { + uint64_t magic; + uint32_t size; + uint8_t flags; + struct MallocHeader *n; +} MallocHeader; + +size_t max(size_t a, size_t b) { return (a > b) ? a : b; } + +size_t min(size_t a, size_t b) { return (a < b) ? a : b; } + +uint64_t delta_page(uint64_t a) { return 0x1000 - (a % 0x1000); } + +MallocHeader *head = NULL; +MallocHeader *final = NULL; +uint32_t total_heap_size = 0; + +int init_heap(void) { + head = (MallocHeader *)ksbrk(NEW_ALLOC_SIZE); + total_heap_size += NEW_ALLOC_SIZE - sizeof(MallocHeader); + head->magic = 0xdde51ab9410268b1; + head->size = NEW_ALLOC_SIZE - sizeof(MallocHeader); + head->flags = IS_FREE | IS_FINAL; + head->n = NULL; + final = head; + return 1; +} + +int add_heap_memory(size_t min_desired) { + min_desired += sizeof(MallocHeader) + 0x1000; + size_t allocation_size = max(min_desired, NEW_ALLOC_SIZE); + allocation_size += delta_page(allocation_size); + void *p; + if ((void *)(-1) == (p = (void *)ksbrk(allocation_size))) { + return 0; + } + total_heap_size += allocation_size - sizeof(MallocHeader); + void *e = final; + e = (void *)((uint32_t)e + final->size); + if (p == e) { + final->size += allocation_size - sizeof(MallocHeader); + return 1; + } + MallocHeader *new_entry = p; + new_entry->size = allocation_size - sizeof(MallocHeader); + new_entry->flags = IS_FREE | IS_FINAL; + new_entry->n = NULL; + new_entry->magic = 0xdde51ab9410268b1; + final->n = new_entry; + final = new_entry; + return 1; +} + +MallocHeader *next_header(MallocHeader *a) { + assert(a->magic == 0xdde51ab9410268b1); + if (a->n) { + assert(a->n->magic == 0xdde51ab9410268b1); + return a->n; + } + return NULL; +} + +MallocHeader *next_close_header(MallocHeader *a) { + if (!a) { + kprintf("next close header fail\n"); + for (;;) + ; + } + if (a->flags & IS_FINAL) + return NULL; + return next_header(a); +} + +MallocHeader *find_free_entry(uint32_t s) { + // A new header is required as well as the newly allocated chunk + s += sizeof(MallocHeader); + if (!head) + init_heap(); + MallocHeader *p = head; + for (; p; p = next_header(p)) { + assert(p->magic == 0xdde51ab9410268b1); + if (!(p->flags & IS_FREE)) + continue; + uint64_t required_size = s; + if (p->size < required_size) + continue; + return p; + } + return NULL; +} + +void merge_headers(MallocHeader *b) { + if (!(b->flags & IS_FREE)) + return; + + MallocHeader *n = next_close_header(b); + if (!n) + return; + + if (!(n->flags & IS_FREE)) + return; + + b->size += n->size; + b->flags |= n->flags & IS_FINAL; + b->n = n->n; + if (n == final) + final = b; +} + +void *kmalloc(size_t s) { + size_t n = s; + MallocHeader *free_entry = find_free_entry(s); + if (!free_entry) { + if (!add_heap_memory(s)) { + klog("Ran out of memory.", LOG_ERROR); + assert(0); + return NULL; + } + return kmalloc(s); + } + + void *rc = (void *)(free_entry + 1); + + // Create a new header + MallocHeader *new_entry = (MallocHeader *)((uintptr_t)rc + n); + new_entry->flags = free_entry->flags; + new_entry->n = free_entry->n; + new_entry->size = free_entry->size - n - sizeof(MallocHeader); + new_entry->magic = 0xdde51ab9410268b1; + + if (free_entry == final) + final = new_entry; + merge_headers(new_entry); + + // Modify the free entry + free_entry->size = n; + free_entry->flags = 0; + free_entry->n = new_entry; + free_entry->magic = 0xdde51ab9410268b1; + return rc; +} + +#define HEAP 0x00E00000 +#define PHYS 0x403000 + +void *latest = NULL; +uint64_t left = 0; + +void *kmalloc_eternal_physical_align(size_t s, void **physical) { + void *return_address = ksbrk(s); + if (physical) { + if (0 == get_active_pagedirectory()) + *physical = + (void *)((uintptr_t)return_address - (0xC0000000 + PHYS) + HEAP); + else + *physical = (void *)virtual_to_physical(return_address, 0); + } + memset(return_address, 0, 0x1000); + return return_address; +} + +void *kmalloc_eternal_align(size_t s) { + return kmalloc_eternal_physical_align(s, NULL); +} + +void *kmalloc_eternal(size_t s) { return kmalloc_eternal_align(s); } + +size_t get_mem_size(void *ptr) { + if (!ptr) + return 0; + return ((MallocHeader *)((uintptr_t)ptr - sizeof(MallocHeader)))->size; +} + +void *krealloc(void *ptr, size_t size) { + void *rc = kmalloc(size); + if (!rc) + return NULL; + if (!ptr) + return rc; + size_t l = get_mem_size(ptr); + size_t to_copy = min(l, size); + memcpy(rc, ptr, to_copy); + // kfree(ptr); + return rc; +} + +// This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX +// if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW +#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) + +void *kreallocarray(void *ptr, size_t nmemb, size_t size) { + if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && nmemb > 0 && + SIZE_MAX / nmemb < size) { + return NULL; + } + + return krealloc(ptr, nmemb * size); +} + +void *kallocarray(size_t nmemb, size_t size) { + return kreallocarray(NULL, nmemb, size); +} + +void *kcalloc(size_t nelem, size_t elsize) { + void *rc = kallocarray(nelem, elsize); + if (!rc) + return NULL; + memset(rc, 0, nelem * elsize); + return rc; +} + +void kfree(void *p) { + /* +if (!p) +return; +// FIXME: This assumes that p is at the start of a allocated area. +// Could this be avoided in a simple way? +MallocHeader *h = (MallocHeader *)((uintptr_t)p - sizeof(MallocHeader)); +assert(h->magic == 0xdde51ab9410268b1); +if (h->flags & IS_FREE) +return; + +h->flags |= IS_FREE; +merge_headers(h);*/ +} diff --git a/kmalloc.h b/kmalloc.h new file mode 100644 index 0000000..69e0de3 --- /dev/null +++ b/kmalloc.h @@ -0,0 +1,21 @@ +#include +#include +#include +#include +#include + +void kmalloc_allocate_heap(void); + +void *kmalloc_eternal(size_t size); +void *kmalloc_eternal_align(size_t size); +void *kmalloc_eternal_physical(size_t size, void **physical); +void *kmalloc_eternal_physical_align(size_t size, void **physical); + +void *kmalloc(size_t s); +void *kmalloc_align(size_t s); +void *krealloc(void *ptr, size_t size); +void *kreallocarray(void *ptr, size_t nmemb, size_t size); +void *kallocarray(size_t nmemb, size_t size); +void *kcalloc(size_t nelem, size_t elsize); +void kfree(void *p); +int init_heap(void); diff --git a/ksbrk.c b/ksbrk.c new file mode 100644 index 0000000..755a4ed --- /dev/null +++ b/ksbrk.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include +#include + +/* +extern uintptr_t data_end; +extern PageDirectory *kernel_directory; + +#define HEAP 0x00E00000 +#define PHYS 0x403000 +#define PAGE_SIZE ((uintptr_t)0x1000) +void *ksbrk(size_t s) { + uintptr_t rc = (uintptr_t)align_page((void *)data_end); + data_end += s; + data_end = (uintptr_t)align_page((void *)data_end); + + if (!get_active_pagedirectory()) { + // If there is no active pagedirectory we + // just assume that the memory is + // already mapped. + return (void *)rc; + } + mmu_allocate_shared_kernel_region((void *)rc, (data_end - (uintptr_t)rc)); + assert(((uintptr_t)rc % PAGE_SIZE) == 0); + memset((void *)rc, 0xFF, s); + return (void *)rc; +} + +void *ksbrk_physical(size_t s, void **physical) { + void *r = ksbrk(s); + if (physical) { + // if (0 == get_active_pagedirectory()) + // *physical = (void *)((uintptr_t)r - (0xC0000000 + PHYS) + HEAP); + // else + *physical = (void *)virtual_to_physical(r, 0); + } + return r; +}*/ diff --git a/ksbrk.h b/ksbrk.h new file mode 100644 index 0000000..34987dc --- /dev/null +++ b/ksbrk.h @@ -0,0 +1,8 @@ +#ifndef KSBRK_H +#define KSBRK_H +#include +#include + +void* ksbrk(size_t s); +void *ksbrk_physical(size_t s, void **physical); +#endif diff --git a/kubsan.c b/kubsan.c new file mode 100644 index 0000000..c81b3fc --- /dev/null +++ b/kubsan.c @@ -0,0 +1,58 @@ +#include +#include +#include + +void ubsan_log(const char *cause, struct source_location source) { + kprintf("%s: %s : %d\n", cause, source.file_name, source.line); + dump_backtrace(5); + asm("cli"); + asm volatile("1: jmp 1b"); + asm("hlt"); + for (;;) + ; +} + +void __ubsan_handle_shift_out_of_bounds(struct ShiftOutOfBoundsData *data, + unsigned long lhs, unsigned long rhs) { + (void)lhs; + (void)rhs; + ubsan_log("handle_shift_out_of_bounds", data->location); +} + +void __ubsan_handle_add_overflow(struct OverflowData *data, unsigned long lhs, + unsigned long rhs) { + (void)lhs; + (void)rhs; + ubsan_log("handle_add_overflow", data->location); +} + +void __ubsan_handle_sub_overflow(struct OverflowData *data, unsigned long lhs, + unsigned long rhs) { + (void)lhs; + (void)rhs; + ubsan_log("handle_sub_overflow", data->location); +} + +void __ubsan_handle_mul_overflow(struct OverflowData *data, unsigned long lhs, + unsigned long rhs) { + (void)lhs; + (void)rhs; + ubsan_log("handle_mul_overflow", data->location); +} + +void __ubsan_handle_out_of_bounds(struct OutOfBoundsData *data, void *index) { + (void)index; + ubsan_log("handle_out_of_bounds", data->location); +} + +void __ubsan_handle_pointer_overflow(struct OutOfBoundsData *data, + void *index) { + (void)index; + ubsan_log("handle_pointer_overflow", data->location); +} + +void __ubsan_handle_vla_bound_not_positive(struct OutOfBoundsData *data, + void *index) { + (void)index; + ubsan_log("handle_vla_bound_not_positive", data->location); +} diff --git a/kubsan.h b/kubsan.h new file mode 100644 index 0000000..dac5407 --- /dev/null +++ b/kubsan.h @@ -0,0 +1,79 @@ +#include + +enum { type_kind_int = 0, type_kind_float = 1, type_unknown = 0xffff }; + +struct type_descriptor { + uint16_t type_kind; + uint16_t type_info; + char type_name[1]; +}; + +struct source_location { + const char *file_name; + union { + unsigned long reported; + struct { + uint32_t line; + uint32_t column; + }; + }; +}; + +struct OverflowData { + struct source_location location; + struct type_descriptor *type; +}; + +struct type_mismatch_data { + struct source_location location; + struct type_descriptor *type; + unsigned long alignment; + unsigned char type_check_kind; +}; + +struct type_mismatch_data_v1 { + struct source_location location; + struct type_descriptor *type; + unsigned char log_alignment; + unsigned char type_check_kind; +}; + +struct type_mismatch_data_common { + struct source_location *location; + struct type_descriptor *type; + unsigned long alignment; + unsigned char type_check_kind; +}; + +struct nonnull_arg_data { + struct source_location location; + struct source_location attr_location; + int arg_index; +}; + +struct OutOfBoundsData { + struct source_location location; + struct type_descriptor *array_type; + struct type_descriptor *index_type; +}; + +struct ShiftOutOfBoundsData { + struct source_location location; + struct type_descriptor *lhs_type; + struct type_descriptor *rhs_type; +}; + +struct unreachable_data { + struct source_location location; +}; + +struct invalid_value_data { + struct source_location location; + struct type_descriptor *type; +}; + +struct alignment_assumption_data { + struct source_location location; + struct source_location assumption_location; + struct type_descriptor *type; +}; diff --git a/libc/exit/assert.c b/libc/exit/assert.c new file mode 100644 index 0000000..b48773a --- /dev/null +++ b/libc/exit/assert.c @@ -0,0 +1,12 @@ +#include +#include +#include +#include + +void aFailed(char *f, int l) { + kprintf("Assert failed\n"); + kprintf("%s : %d\n", f, l); + dump_backtrace(10); + for (;;) + ; +} diff --git a/libc/include/assert.h b/libc/include/assert.h new file mode 100644 index 0000000..90a0be4 --- /dev/null +++ b/libc/include/assert.h @@ -0,0 +1,19 @@ +#include +#include + +#define assert(expr) \ + { \ + if (!(expr)) \ + aFailed(__FILE__, __LINE__); \ + } + +#define ASSERT_BUT_FIXME_PROPOGATE(expr) \ + { \ + if (!(expr)) \ + kprintf("Performing assert that should have been a propogated error."); \ + assert(expr); \ + } + +void aFailed(char *f, int l); +#define ASSERT_NOT_REACHED \ + { assert(0) } diff --git a/libc/include/errno.h b/libc/include/errno.h new file mode 100644 index 0000000..1ad1004 --- /dev/null +++ b/libc/include/errno.h @@ -0,0 +1,85 @@ +#ifndef ERRNO_H +#define ERRNO_H +// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html +#define E2BIG 1 // Argument list too long. +#define EACCES 2 // Permission denied. +#define EADDRINUSE 3 // Address in use. +#define EADDRNOTAVAIL 4 // Address not available. +#define EAFNOSUPPORT 5 // Address family not supported. +#define EAGAIN 6 // Resource unavailable, try again. +#define EALREADY 7 // Connection already in progress. +#define EBADF 8 // Bad file descriptor. +#define EBADMSG 9 // Bad message. +#define EBUSY 10 // Device or resource busy. +#define ECANCELED 11 // Operation canceled. +#define ECHILD 12 // No child processes. +#define ECONNABORTED 13 // Connection aborted. +#define ECONNREFUSED 14 // Connection refused. +#define ECONNRESET 15 // Connection reset. +#define EDEADLK 16 // Resource deadlock would occur. +#define EDESTADDRREQ 17 // Destination address required. +#define EDOM 18 // Mathematics argument out of domain of function. +#define EDQUOT 19 // Reserved. +#define EEXIST 20 // File exists. +#define EFAULT 21 // Bad address. +#define EFBIG 22 // File too large. +#define EHOSTUNREACH 23 // Host is unreachable. +#define EIDRM 24 // Identifier removed. +#define EILSEQ 25 // Illegal byte sequence. +#define EINPROGRESS 26 // Operation in progress. +#define EINTR 27 // Interrupted function. +#define EINVAL 28 // Invalid argument. +#define EIO 29 // I/O error. +#define EISCONN 30 // Socket is connected. +#define EISDIR 31 // Is a directory. +#define ELOOP 32 // Too many levels of symbolic links. +#define EMFILE 33 // File descriptor value too large. +#define EMLINK 34 // Too many links. +#define EMSGSIZE 35 // Message too large. +#define EMULTIHOP 36 // Reserved. +#define ENAMETOOLONG 37 // Filename too long. +#define ENETDOWN 38 // Network is down. +#define ENETRESET 39 // Connection aborted by network. +#define ENETUNREACH 40 // Network unreachable. +#define ENFILE 41 // Too many files open in system. +#define ENOBUFS 42 // No buffer space available. +#define ENODATA 43 // No message is available on the STREAM head read queue. +#define ENODEV 44 // No such device. +#define ENOENT 45 // No such file or directory. +#define ENOEXEC 46 // Executable file format error. +#define ENOLCK 47 // No locks available. +#define ENOLINK 48 // Reserved. +#define ENOMEM 49 // Not enough space. +#define ENOMSG 50 // No message of the desired type. +#define ENOPROTOOPT 51 // Protocol not available. +#define ENOSPC 52 // No space left on device. +#define ENOSR 53 // No STREAM resources. +#define ENOSTR 54 // Not a STREAM. +#define ENOSYS 55 // Functionality not supported. +#define ENOTCONN 56 // The socket is not connected. +#define ENOTDIR 57 // Not a directory or a symbolic link to a directory. +#define ENOTEMPTY 58 // Directory not empty. +#define ENOTRECOVERABLE 59 // State not recoverable. +#define ENOTSOCK 60 // Not a socket. +#define ENOTSUP 61 // Not supported (may be the same value as. +#define ENOTTY 62 // Inappropriate I/O control operation. +#define ENXIO 63 // No such device or address. +#define EOPNOTSUPP ENOTSUP // Operation not supported on socket. +#define EOVERFLOW 65 // Value too large to be stored in data type. +#define EOWNERDEAD 66 // Previous owner died. +#define EPERM 67 // Operation not permitted. +#define EPIPE 68 // Broken pipe. +#define EPROTO 69 // Protocol error. +#define EPROTONOSUPPORT 70 // Protocol not supported. +#define EPROTOTYPE 71 // Protocol wrong type for socket. +#define ERANGE 72 // Result too large. +#define EROFS 73 // Read-only file system. +#define ESPIPE 74 // Invalid seek. +#define ESRCH 75 // No such process. +#define ESTALE 76 // Reserved. +#define ETIME 77 // Stream ioctl() timeout. +#define ETIMEDOUT 78 // Connection timed out. +#define ETXTBSY 79 // Text file busy. +#define EWOULDBLOCK EAGAIN // Operation would block. +#define EXDEV 81 // Cross-device link. +#endif diff --git a/libc/include/limits.h b/libc/include/limits.h new file mode 100644 index 0000000..05022ec --- /dev/null +++ b/libc/include/limits.h @@ -0,0 +1 @@ +#define PATH_MAX 256 diff --git a/libc/include/stdio.h b/libc/include/stdio.h new file mode 100644 index 0000000..f2bbb32 --- /dev/null +++ b/libc/include/stdio.h @@ -0,0 +1,9 @@ +#ifndef STDIO_H +#define STDIO_H + +void putc(const char c); +int puts(char *str); +void delete_characther(void); +int kprintf(const char *format, ...); + +#endif diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h new file mode 100644 index 0000000..e69de29 diff --git a/libc/include/string.h b/libc/include/string.h new file mode 100644 index 0000000..7cee4b2 --- /dev/null +++ b/libc/include/string.h @@ -0,0 +1,19 @@ +#ifndef STRING_H +#define STRING_H +#include +#include + +unsigned long strlen(const char *s); +void *memcpy(void *dest, const void *src, uint32_t n); +void *memset(void *dst, const unsigned char c, uint32_t n); +int memcmp(const void *s1, const void *s2, uint32_t n); +char *strcpy(char *d, const char *s); +int strcmp(const char *s1, const char *s2); +int isequal(const char *s1, const char *s2); +int isequal_n(const char *s1, const char *s2, uint32_t n); +char *copy_and_allocate_string(const char *s); +char *copy_and_allocate_user_string(const char *s); +char *strncpy(char *dest, const char *src, size_t n); +size_t strlcpy(char *dst, const char *src, size_t dsize); +char *strcat(char *s1, const char *s2); +#endif diff --git a/libc/include/time.h b/libc/include/time.h new file mode 100644 index 0000000..4e356d1 --- /dev/null +++ b/libc/include/time.h @@ -0,0 +1,6 @@ +#include + +struct timespec { + time_t tv_sec; // Seconds. + long tv_nsec; // Nanoseconds. +}; diff --git a/libc/include/types.h b/libc/include/types.h new file mode 100644 index 0000000..ffcf281 --- /dev/null +++ b/libc/include/types.h @@ -0,0 +1,27 @@ +#ifndef TYPES_H +#define TYPES_H +typedef unsigned int ino_t; + +typedef int mode_t; + +typedef int nlink_t; +typedef int uid_t; +typedef int gid_t; +typedef int id_t; + +typedef int blkcnt_t; +typedef int off_t; + +typedef int dev_t; +typedef unsigned int fsblkcnt_t; +typedef unsigned int fsfilcnt_t; +typedef unsigned int ino_t; +//typedef unsigned int size_t; + +typedef int blksize_t; +typedef int pid_t; +typedef int ssize_t; + +//typedef int clock_t; +typedef int time_t; +#endif diff --git a/libc/stdio/print.c b/libc/stdio/print.c new file mode 100644 index 0000000..8174983 --- /dev/null +++ b/libc/stdio/print.c @@ -0,0 +1,97 @@ +#include "../../drivers/serial.h" +#include "../include/assert.h" +#include "../include/stdio.h" +#include + +#define TAB_SIZE 8 + +const char HEX_SET[0x10] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + +inline void putc(const char c) { write_serial(c); } + +int kprint_hex(uint64_t num) { + int c = 2; + + if (num == 0) { + putc('0'); + c++; + return c; + } + + char str[16] = {0}; + int i = 0; + for (; num != 0 && i < 16; i++, num /= 16) + str[i] = HEX_SET[(num % 16)]; + + c += i; + for (i--; i >= 0; i--) + putc(str[i]); + + return c; +} + +int kprint_int(int num) { + int c = 0; + if (0 == num) { + putc('0'); + c++; + return c; + } + char str[10]; + int i = 0; + for (; num != 0 && i < 10; i++, num /= 10) + str[i] = (num % 10) + '0'; + + c += i; + for (i--; i >= 0; i--) + putc(str[i]); + return c; +} + +int kprintf(const char *format, ...) { + int c = 0; + va_list list; + va_start(list, format); + + const char *s = format; + for (; *s; s++) { + if ('%' != *s) { + putc(*s); + c++; + continue; + } + + char flag = *(s + 1); + if ('\0' == flag) + break; + + switch (flag) { + case 'c': + putc((char)va_arg(list, int)); + c++; + break; + case 'd': + c += kprint_int(va_arg(list, int)); + break; + case 's': + for (char *string = va_arg(list, char *); *string; putc(*string++), c++) + ; + break; + case 'x': + c += kprint_hex(va_arg(list, const uint32_t)); + break; + case '%': + putc('%'); + c++; + break; + default: + ASSERT_NOT_REACHED; + break; + } + s++; + } + return c; +} + +int puts(char *str) { return kprintf("%s\n", str); } diff --git a/libc/string/copy.c b/libc/string/copy.c new file mode 100644 index 0000000..277c808 --- /dev/null +++ b/libc/string/copy.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +char *copy_and_allocate_string(const char *s) { + size_t l = strlen(s); + char *r = kmalloc(l + 1); + if (!r) + return NULL; + return strncpy(r, s, l); +} + +char *copy_and_allocate_user_string(const char *s) { + size_t len; + if (!is_valid_user_c_string(s, &len)) + return NULL; + size_t real_len = strlen(s); + assert(real_len == len); + len = real_len; + char *r = kmalloc(len + 1); + if (!r) + return NULL; + strlcpy(r, s, len); + return r; +} diff --git a/libc/string/isequal.c b/libc/string/isequal.c new file mode 100644 index 0000000..cdbd3cc --- /dev/null +++ b/libc/string/isequal.c @@ -0,0 +1,15 @@ +#include "../include/string.h" + +int isequal(const char *s1, const char *s2) { + for(;*s1;s1++,s2++) + if(*s1 != *s2) + return 0; + return 1; +} + +int isequal_n(const char *s1, const char *s2, uint32_t n) { + for(;*s1 && n;s1++,s2++,n--) + if(*s1 != *s2) + return 0; + return 1; +} diff --git a/libc/string/memcmp.c b/libc/string/memcmp.c new file mode 100644 index 0000000..72c680a --- /dev/null +++ b/libc/string/memcmp.c @@ -0,0 +1,12 @@ +#include "../include/string.h" + +int memcmp(const void *s1, const void *s2, uint32_t n) +{ + int return_value = 0; + + for(uint32_t i = 0;i < n;i++) + if(((unsigned char *)(s1))[i] != ((unsigned char *)(s2))[i]) + return_value++; + + return return_value; +} diff --git a/libc/string/memcpy.c b/libc/string/memcpy.c new file mode 100644 index 0000000..70a60c1 --- /dev/null +++ b/libc/string/memcpy.c @@ -0,0 +1,11 @@ +#include "../include/string.h" + +void *__attribute__((optimize("O0"))) +memcpy(void *dest, const void *src, uint32_t n) { + unsigned char *d = dest; + const unsigned char *s = src; + // for(;n--;) *d++ = *s++; + for (; n; n--) + *d++ = *s++; + return dest; +} diff --git a/libc/string/memset.c b/libc/string/memset.c new file mode 100644 index 0000000..a446eb4 --- /dev/null +++ b/libc/string/memset.c @@ -0,0 +1,9 @@ +#include + +void *memset(void *dst, const unsigned char c, uint32_t n) { + uintptr_t d = (uintptr_t)dst; + for (uint32_t i = 0; i < n; i++, d++) + *(unsigned char *)d = c; + + return (void *)d; +} diff --git a/libc/string/strcat.c b/libc/string/strcat.c new file mode 100644 index 0000000..78a9ec6 --- /dev/null +++ b/libc/string/strcat.c @@ -0,0 +1,6 @@ +#include + +char *strcat(char *s1, const char *s2) { + strcpy(s1 + strlen(s1), s2); + return s1; +} diff --git a/libc/string/strcmp.c b/libc/string/strcmp.c new file mode 100644 index 0000000..d7039e2 --- /dev/null +++ b/libc/string/strcmp.c @@ -0,0 +1,8 @@ +#include "../include/string.h" + +int strcmp(const char *s1, const char *s2) +{ + for(;*s1 == *s2 && *s1; s1++, s2++) + ; + return *s1 - *s2; +} diff --git a/libc/string/strcpy.c b/libc/string/strcpy.c new file mode 100644 index 0000000..fa1e336 --- /dev/null +++ b/libc/string/strcpy.c @@ -0,0 +1,8 @@ +#include + +char *strcpy(char *d, const char *s) { + char *s1 = d; + for (; (*d++ = *s++);) + ; + return s1; +} diff --git a/libc/string/strlcpy.c b/libc/string/strlcpy.c new file mode 100644 index 0000000..43d0e58 --- /dev/null +++ b/libc/string/strlcpy.c @@ -0,0 +1,21 @@ +#include +#include + +// Copy string src to buffer dst of size dsize. At most dsize-1 +// chars will be copied. Always NUL terminates (unless dsize == 0). +// Returns strlen(src); if retval >= dsize, truncation occurred. +size_t strlcpy(char *dst, const char *src, size_t dsize) { + size_t n = dsize; + const char *osrc = src; + for (; n; n--) { + if ((*dst++ = *src++) == '\0') + break; + } + if (n == 0) { + if (dsize != 0) + *dst = '\0'; /* NUL-terminate dst */ + while (*src++) + ; + } + return src - osrc - 1; +} diff --git a/libc/string/strlen.c b/libc/string/strlen.c new file mode 100644 index 0000000..4346383 --- /dev/null +++ b/libc/string/strlen.c @@ -0,0 +1,8 @@ +#include "../include/string.h" + +unsigned long strlen(const char *s) +{ + const char * tmp = s; + for(;*tmp++;); + return (tmp - s)-1; +} diff --git a/libc/string/strncpy.c b/libc/string/strncpy.c new file mode 100644 index 0000000..a886895 --- /dev/null +++ b/libc/string/strncpy.c @@ -0,0 +1,11 @@ +#include +#include + +// FIXME: Something is weird with this function +char *strncpy(char *dest, const char *src, size_t n) { + char *r = dest; + for (; n && (*dest = *src); n--, src++, dest++) + ; + *dest = '\0'; + return r; +} diff --git a/linker.ld b/linker.ld new file mode 100644 index 0000000..59b150d --- /dev/null +++ b/linker.ld @@ -0,0 +1,41 @@ +ENTRY (_start) + +SECTIONS +{ + . = 0x00100000; + /* The kernel will live at 3GB + 1MB in the virtual address space, */ + /* which will be mapped to 1MB in the physical address space. */ + /* Note that we page-align the sections. */ + + _kernel_start = .; + .multiboot.data : { + *(.multiboot.data) + } + + .multiboot.text : { + *(.multiboot.text) + } + + . += 0xC0000000; + /* Add a symbol that indicates the start address of the kernel. */ + .text ALIGN (4K) : AT (ADDR (.text) - 0xC0000000) + { + *(.text) + } + .rodata ALIGN (4K) : AT (ADDR (.rodata) - 0xC0000000) + { + *(.rodata) + } + .data ALIGN (4K) : AT (ADDR (.data) - 0xC0000000) + { + *(.data) + } + .bss ALIGN (4K) : AT (ADDR (.bss) - 0xC0000000) + { + *(COMMON) + *(.bss) + *(.bootstrap_stack) + } + /* Add a symbol that indicates the end address of the kernel. */ + _kernel_end = .; +} diff --git a/log.c b/log.c new file mode 100644 index 0000000..56d38e8 --- /dev/null +++ b/log.c @@ -0,0 +1,40 @@ +#include "log.h" +#include + +struct stackframe { + struct stackframe *ebp; + uint32_t eip; +}; + +void dump_backtrace(uint32_t max_frames) { + struct stackframe *stk; + asm("mov %%ebp,%0" : "=r"(stk)::); + kprintf("Stack trace:\n"); + for (uint32_t frame = 0; stk && frame < max_frames; ++frame) { + kprintf(" 0x%x\n", stk->eip); + stk = stk->ebp; + } + if (get_current_task()) { + kprintf(" PID: %x\n", get_current_task()->pid); + } +} + +void klog(char *str, int code) { + switch (code) { + case LOG_NOTE: + kprintf("[NOTE] "); + break; + case LOG_WARN: + kprintf("[WARN] "); + break; + case LOG_ERROR: + kprintf("[ERROR] "); + break; + default: + case LOG_SUCCESS: + kprintf("[SUCCESS] "); + break; + } + + puts(str); +} diff --git a/log.h b/log.h new file mode 100644 index 0000000..fe499bc --- /dev/null +++ b/log.h @@ -0,0 +1,10 @@ +#include +#include + +#define LOG_NOTE 3 +#define LOG_WARN 2 +#define LOG_ERROR 1 +#define LOG_SUCCESS 0 + +void klog(char *str, int code); +void dump_backtrace(uint32_t max_frames); diff --git a/mount/cat b/mount/cat new file mode 120000 index 0000000..a24e907 --- /dev/null +++ b/mount/cat @@ -0,0 +1 @@ +./minibox \ No newline at end of file diff --git a/mount/init b/mount/init new file mode 120000 index 0000000..a24e907 --- /dev/null +++ b/mount/init @@ -0,0 +1 @@ +./minibox \ No newline at end of file diff --git a/mount/pid1 b/mount/pid1 new file mode 100755 index 0000000..773d54c Binary files /dev/null and b/mount/pid1 differ diff --git a/mount/program b/mount/program new file mode 100755 index 0000000..c93d7ba Binary files /dev/null and b/mount/program differ diff --git a/mount/sh b/mount/sh new file mode 100755 index 0000000..c05684c Binary files /dev/null and b/mount/sh differ diff --git a/multiboot.h b/multiboot.h new file mode 100644 index 0000000..ecbb6a0 --- /dev/null +++ b/multiboot.h @@ -0,0 +1,243 @@ +#include +#ifndef MULTIBOOT_HEADER +#define MULTIBOOT_HEADER 1 + +/* How many bytes from the start of the file we search for the header. */ +#define MULTIBOOT_SEARCH 8192 +#define MULTIBOOT_HEADER_ALIGN 4 + +/* The magic field should contain this. */ +#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 + +/* This should be in %eax. */ +#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 + +/* Alignment of multiboot modules. */ +#define MULTIBOOT_MOD_ALIGN 0x00001000 + +/* Alignment of the multiboot info structure. */ +#define MULTIBOOT_INFO_ALIGN 0x00000004 + +/* Flags set in the ’flags’ member of the multiboot header. */ + +/* Align all boot modules on i386 page (4KB) boundaries. */ +#define MULTIBOOT_PAGE_ALIGN 0x00000001 + +/* Must pass memory information to OS. */ +#define MULTIBOOT_MEMORY_INFO 0x00000002 + +/* Must pass video information to OS. */ +#define MULTIBOOT_VIDEO_MODE 0x00000004 + +/* This flag indicates the use of the address fields in the header. */ +#define MULTIBOOT_AOUT_KLUDGE 0x00010000 + +/* Flags to be set in the ’flags’ member of the multiboot info structure. */ + +/* is there basic lower/upper memory information? */ +#define MULTIBOOT_INFO_MEMORY 0x00000001 +/* is there a boot device set? */ +#define MULTIBOOT_INFO_BOOTDEV 0x00000002 +/* is the command-line defined? */ +#define MULTIBOOT_INFO_CMDLINE 0x00000004 +/* are there modules to do something with? */ +#define MULTIBOOT_INFO_MODS 0x00000008 + +/* These next two are mutually exclusive */ + +/* is there a symbol table loaded? */ +#define MULTIBOOT_INFO_AOUT_SYMS 0x00000010 +/* is there an ELF section header table? */ +#define MULTIBOOT_INFO_ELF_SHDR 0X00000020 + +/* is there a full memory map? */ +#define MULTIBOOT_INFO_MEM_MAP 0x00000040 + +/* Is there drive info? */ +#define MULTIBOOT_INFO_DRIVE_INFO 0x00000080 + +/* Is there a config table? */ +#define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100 + +/* Is there a boot loader name? */ +#define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200 + +/* Is there a APM table? */ +#define MULTIBOOT_INFO_APM_TABLE 0x00000400 + +/* Is there video information? */ +#define MULTIBOOT_INFO_VBE_INFO 0x00000800 +#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000 + +#ifndef ASM_FILE + +typedef uint8_t multiboot_uint8_t; +typedef uint16_t multiboot_uint16_t; +typedef uint32_t multiboot_uint32_t; +typedef uint64_t multiboot_uint64_t; + +struct multiboot_header { + /* Must be MULTIBOOT_MAGIC - see above. */ + multiboot_uint32_t magic; + + /* Feature flags. */ + multiboot_uint32_t flags; + + /* The above fields plus this one must equal 0 mod 2^32. */ + multiboot_uint32_t checksum; + + /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */ + multiboot_uint32_t header_addr; + multiboot_uint32_t load_addr; + multiboot_uint32_t load_end_addr; + multiboot_uint32_t bss_end_addr; + multiboot_uint32_t entry_addr; + + /* These are only valid if MULTIBOOT_VIDEO_MODE is set. */ + multiboot_uint32_t mode_type; + multiboot_uint32_t width; + multiboot_uint32_t height; + multiboot_uint32_t depth; +}; + +/* The symbol table for a.out. */ +struct multiboot_aout_symbol_table { + multiboot_uint32_t tabsize; + multiboot_uint32_t strsize; + multiboot_uint32_t addr; + multiboot_uint32_t reserved; +}; +typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t; + +/* The section header table for ELF. */ +struct multiboot_elf_section_header_table { + multiboot_uint32_t num; + multiboot_uint32_t size; + multiboot_uint32_t addr; + multiboot_uint32_t shndx; +}; +typedef struct multiboot_elf_section_header_table + multiboot_elf_section_header_table_t; + +struct multiboot_info { + /* Multiboot info version number */ + multiboot_uint32_t flags; + + /* Available memory from BIOS */ + multiboot_uint32_t mem_lower; + multiboot_uint32_t mem_upper; + + /* "root" partition */ + multiboot_uint32_t boot_device; + + /* Kernel command line */ + multiboot_uint32_t cmdline; + + /* Boot-Module list */ + multiboot_uint32_t mods_count; + multiboot_uint32_t mods_addr; + + union { + multiboot_aout_symbol_table_t aout_sym; + multiboot_elf_section_header_table_t elf_sec; + } u; + + /* Memory Mapping buffer */ + multiboot_uint32_t mmap_length; + multiboot_uint32_t mmap_addr; + + /* Drive Info buffer */ + multiboot_uint32_t drives_length; + multiboot_uint32_t drives_addr; + + /* ROM configuration table */ + multiboot_uint32_t config_table; + + /* Boot Loader Name */ + multiboot_uint32_t boot_loader_name; + + /* APM table */ + multiboot_uint32_t apm_table; + + /* Video */ + multiboot_uint32_t vbe_control_info; + multiboot_uint32_t vbe_mode_info; + multiboot_uint16_t vbe_mode; + multiboot_uint16_t vbe_interface_seg; + multiboot_uint16_t vbe_interface_off; + multiboot_uint16_t vbe_interface_len; + + multiboot_uint64_t framebuffer_addr; + multiboot_uint32_t framebuffer_pitch; + multiboot_uint32_t framebuffer_width; + multiboot_uint32_t framebuffer_height; + multiboot_uint8_t framebuffer_bpp; +#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 +#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 + multiboot_uint8_t framebuffer_type; + union { + struct { + multiboot_uint32_t framebuffer_palette_addr; + multiboot_uint16_t framebuffer_palette_num_colors; + }; + struct { + multiboot_uint8_t framebuffer_red_field_position; + multiboot_uint8_t framebuffer_red_mask_size; + multiboot_uint8_t framebuffer_green_field_position; + multiboot_uint8_t framebuffer_green_mask_size; + multiboot_uint8_t framebuffer_blue_field_position; + multiboot_uint8_t framebuffer_blue_mask_size; + }; + }; +}; +typedef struct multiboot_info multiboot_info_t; + +struct multiboot_color { + multiboot_uint8_t red; + multiboot_uint8_t green; + multiboot_uint8_t blue; +}; + +struct multiboot_mmap_entry { + multiboot_uint32_t size; + multiboot_uint64_t addr; + multiboot_uint64_t len; +#define MULTIBOOT_MEMORY_AVAILABLE 1 +#define MULTIBOOT_MEMORY_RESERVED 2 +#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 +#define MULTIBOOT_MEMORY_NVS 4 +#define MULTIBOOT_MEMORY_BADRAM 5 + multiboot_uint32_t type; +} __attribute__((packed)); +typedef struct multiboot_mmap_entry multiboot_memory_map_t; + +struct multiboot_mod_list { + /* the memory used goes from bytes ’mod_start’ to ’mod_end-1’ inclusive */ + multiboot_uint32_t mod_start; + multiboot_uint32_t mod_end; + + /* Module command line */ + multiboot_uint32_t cmdline; + + /* padding to take it to 16 bytes (must be zero) */ + multiboot_uint32_t pad; +}; +typedef struct multiboot_mod_list multiboot_module_t; + +/* APM BIOS info. */ +struct multiboot_apm_info { + multiboot_uint16_t version; + multiboot_uint16_t cseg; + multiboot_uint32_t offset; + multiboot_uint16_t cseg_16; + multiboot_uint16_t dseg; + multiboot_uint16_t flags; + multiboot_uint16_t cseg_len; + multiboot_uint16_t cseg_16_len; + multiboot_uint16_t dseg_len; +}; + +#endif /* ! ASM_FILE */ + +#endif /* ! MULTIBOOT_HEADER */ diff --git a/new.sh b/new.sh new file mode 100755 index 0000000..60dcc95 --- /dev/null +++ b/new.sh @@ -0,0 +1,3 @@ +#!/bin/sh +cp new_ext2.img ext2.img +./sync.sh diff --git a/poll.c b/poll.c new file mode 100644 index 0000000..5e02723 --- /dev/null +++ b/poll.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include + +int poll(struct pollfd *fds, size_t nfds, int timeout) { + (void)timeout; + int read_locks[nfds]; + int write_locks[nfds]; + int disconnect_locks[nfds]; + for (size_t i = 0; i < nfds; i++) { + if (fds[i].fd < 0) + continue; + vfs_fd_t *f = get_vfs_fd(fds[i].fd); + if (fds[i].events & POLLIN) + read_locks[i] = create_read_fdhalt(f); + if (fds[i].events & POLLOUT) + write_locks[i] = create_write_fdhalt(f); + if (fds[i].events & POLLHUP) + disconnect_locks[i] = create_disconnect_fdhalt(f); + } + + switch_task(); + + for (size_t i = 0; i < nfds; i++) { + if (fds[i].fd < 0) + continue; + if (fds[i].events & POLLIN) + unset_read_fdhalt(read_locks[i]); + if (fds[i].events & POLLOUT) + unset_write_fdhalt(write_locks[i]); + if (fds[i].events & POLLHUP) + unset_disconnect_fdhalt(disconnect_locks[i]); + } + for (size_t i = 0; i < nfds; i++) { + if (0 > fds[i].fd) { + fds[i].revents = 0; + continue; + } + vfs_fd_t *f = get_vfs_fd(fds[i].fd); + if (!f) { + if (fds[i].events & POLLHUP) + fds[i].revents |= POLLHUP; + } else { + if (f->inode->has_data && fds[i].events & POLLIN) + fds[i].revents |= POLLIN; + if (f->inode->can_write && fds[i].events & POLLOUT) + fds[i].revents |= POLLOUT; + if (!(f->inode->is_open) && fds[i].events & POLLHUP) + fds[i].revents |= POLLHUP; + } + } + return 0; +} diff --git a/poll.h b/poll.h new file mode 100644 index 0000000..19698dd --- /dev/null +++ b/poll.h @@ -0,0 +1,15 @@ +#include +#include + +#define POLLIN (1 << 0) +#define POLLPRI (1 << 1) +#define POLLOUT (1 << 2) +#define POLLHUP (1 << 3) + +struct pollfd { + int fd; + short events; + short revents; +}; + +int poll(struct pollfd *fds, size_t nfds, int timeout); diff --git a/process.s b/process.s new file mode 100644 index 0000000..24e1869 --- /dev/null +++ b/process.s @@ -0,0 +1,33 @@ +.intel_syntax noprefix +.global copy_page_physical +.global loop_m +copy_page_physical: + push ebx + pushf + + cli + + mov ebx, [esp+12] + mov ecx, [esp+16] + + mov edx, cr0 + and edx, 0x7fffffff + mov cr0, edx + + mov edx, 1024 + +.loop: + mov eax, [ebx] + mov [ecx], eax + add ebx, 4 + add ecx, 4 + dec edx + jnz .loop + + mov edx, cr0 + or edx, 0x80000000 + mov cr0, edx + + popf + pop ebx + ret diff --git a/random.c b/random.c new file mode 100644 index 0000000..0e1b760 --- /dev/null +++ b/random.c @@ -0,0 +1,142 @@ +// FIXME: This is mostlikely incredibly inefficent and insecure. +#include +#include +#include +#include +#include +#include +#include + +#define HASH_CTX SHA1_CTX +#define HASH_LEN SHA1_LEN + +uint32_t internal_chacha_block[16] = { + // Constant ascii values of "expand 32-byte k" + 0x61707865, + 0x3320646e, + 0x79622d32, + 0x6b206574, + // The unique key + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + // Block counter + 0x00000000, + // Nonce + 0x00000000, + 0x00000000, +}; + +void mix_chacha(void) { + uint8_t rand_data[BLOCK_SIZE]; + get_random((BYTEPTR)rand_data, BLOCK_SIZE); + memcpy(internal_chacha_block + KEY, rand_data, KEY_SIZE); + memcpy(internal_chacha_block + NONCE, rand_data + KEY_SIZE, NONCE_SIZE); + internal_chacha_block[COUNT] = 0; +} + +void get_random(BYTEPTR buffer, uint64_t len) { + uint8_t rand_data[BLOCK_SIZE]; + for (; len > 0;) { + if (COUNT_MAX - 1 == internal_chacha_block[COUNT]) { + // The current block has used up all the 2^32 counts. If the + // key and/or the nonce are not changed and the count + // overflows back to zero then the random values would + // repeate. This is of course not desiered behaviour. The + // solution is to create a new nonce and key using the + // already established chacha block. + internal_chacha_block[COUNT]++; + mix_chacha(); + } + uint32_t read_len = (BLOCK_SIZE < len) ? (BLOCK_SIZE) : len; + chacha_block((uint32_t *)rand_data, internal_chacha_block); + internal_chacha_block[COUNT]++; + memcpy(buffer, rand_data, read_len); + buffer += read_len; + len -= read_len; + } +} + +HASH_CTX hash_pool; +uint32_t hash_pool_size = 0; + +void add_hash_pool(void) { + uint8_t new_chacha_key[KEY_SIZE]; + get_random(new_chacha_key, KEY_SIZE); + + uint8_t hash_buffer[HASH_LEN]; + SHA1_Final(&hash_pool, hash_buffer); + for (size_t i = 0; i < HASH_LEN; i++) + new_chacha_key[i % KEY_SIZE] ^= hash_buffer[i]; + + SHA1_Init(&hash_pool); + SHA1_Update(&hash_pool, hash_buffer, HASH_LEN); + + uint8_t block[BLOCK_SIZE]; + get_random(block, BLOCK_SIZE); + SHA1_Update(&hash_pool, block, BLOCK_SIZE); + + memcpy(internal_chacha_block + KEY, new_chacha_key, KEY_SIZE); + + mix_chacha(); +} + +void add_entropy(uint8_t *buffer, size_t size) { + SHA1_Update(&hash_pool, buffer, size); + hash_pool_size += size; + if (hash_pool_size >= HASH_LEN * 2) + add_hash_pool(); +} + +void setup_random(void) { + SHA1_Init(&hash_pool); + + BYTE seed[1024]; + int rand_fd = vfs_open("/etc/seed", O_RDWR, 0); + if (0 > rand_fd) { + klog("/etc/seed not found", LOG_WARN); + return; + } + + size_t offset = 0; + for (int rc; (rc = vfs_pread(rand_fd, seed, 1024, offset)); offset += rc) { + if (0 > rc) { + klog("/etc/seed read error", LOG_WARN); + break; + } + add_entropy(seed, rc); + } + add_hash_pool(); + + // Update the /etc/seed file to ensure we get a new state upon next + // boot. + get_random(seed, 1024); + vfs_pwrite(rand_fd, seed, 1024, 0); + vfs_close(rand_fd); +} + +int random_write(BYTEPTR buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + (void)offset; + (void)fd; + add_entropy(buffer, len); + return len; // add_entropy() never fails to recieve (len) amount of data. +} + +int random_read(BYTEPTR buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + (void)offset; + (void)fd; + get_random(buffer, len); + return len; // get_random() never fails to give "len" amount of data. +} + +void add_random_devices(void) { + devfs_add_file("/random", random_read, random_write, NULL, 1, 1, + FS_TYPE_CHAR_DEVICE); + devfs_add_file("/urandom", random_read, random_write, NULL, 1, 1, + FS_TYPE_CHAR_DEVICE); +} diff --git a/random.h b/random.h new file mode 100644 index 0000000..437927f --- /dev/null +++ b/random.h @@ -0,0 +1,7 @@ +#include +#include +#include + +void setup_random(void); +void add_random_devices(void); +void get_random(uint8_t* buffer, uint64_t len); diff --git a/read_eip.s b/read_eip.s new file mode 100644 index 0000000..6041db0 --- /dev/null +++ b/read_eip.s @@ -0,0 +1,5 @@ +.intel_syntax noprefix +.global read_eip +read_eip: + pop eax + jmp eax diff --git a/scalls/accept.c b/scalls/accept.c new file mode 100644 index 0000000..3c3f5ad --- /dev/null +++ b/scalls/accept.c @@ -0,0 +1,5 @@ +#include "accept.h" + +int syscall_accept(SYS_ACCEPT_PARAMS *args) { + return accept(args->socket, args->address, args->address_len); +} diff --git a/scalls/accept.h b/scalls/accept.h new file mode 100644 index 0000000..d022999 --- /dev/null +++ b/scalls/accept.h @@ -0,0 +1,9 @@ +#include "../socket.h" + +typedef struct SYS_ACCEPT_PARAMS { + int socket; + struct sockaddr *address; + socklen_t *address_len; +} __attribute__((packed)) SYS_ACCEPT_PARAMS; + +int syscall_accept(SYS_ACCEPT_PARAMS *args); diff --git a/scalls/bind.c b/scalls/bind.c new file mode 100644 index 0000000..76e36ab --- /dev/null +++ b/scalls/bind.c @@ -0,0 +1,5 @@ +#include "bind.h" + +int syscall_bind(SYS_BIND_PARAMS *args) { + return bind(args->sockfd, args->addr, args->addrlen); +} diff --git a/scalls/bind.h b/scalls/bind.h new file mode 100644 index 0000000..5661ad0 --- /dev/null +++ b/scalls/bind.h @@ -0,0 +1,9 @@ +#include "../socket.h" + +typedef struct SYS_BIND_PARAMS { + int sockfd; + const struct sockaddr *addr; + socklen_t addrlen; +} __attribute__((packed)) SYS_BIND_PARAMS; + +int syscall_bind(SYS_BIND_PARAMS *args); diff --git a/scalls/clock_gettime.c b/scalls/clock_gettime.c new file mode 100644 index 0000000..632ea08 --- /dev/null +++ b/scalls/clock_gettime.c @@ -0,0 +1,10 @@ +#include + +int syscall_clock_gettime(SYS_CLOCK_GETTIME_PARAMS *args) { + // FIXME: Actually implement this + if (args->ts) { + args->ts->tv_sec = 0; + args->ts->tv_nsec = 0; + } + return 0; +} diff --git a/scalls/clock_gettime.h b/scalls/clock_gettime.h new file mode 100644 index 0000000..145aa24 --- /dev/null +++ b/scalls/clock_gettime.h @@ -0,0 +1,8 @@ +#include + +typedef struct SYS_CLOCK_GETTIME_PARAMS { + clockid_t clk; + struct timespec *ts; +} __attribute__((packed)) SYS_CLOCK_GETTIME_PARAMS; + +int syscall_clock_gettime(SYS_CLOCK_GETTIME_PARAMS *args); diff --git a/scalls/mmap.c b/scalls/mmap.c new file mode 100644 index 0000000..83fff6a --- /dev/null +++ b/scalls/mmap.c @@ -0,0 +1,7 @@ +#include +#include + +void *syscall_mmap(SYS_MMAP_PARAMS *args) { + return mmap(args->addr, args->length, args->prot, args->flags, args->fd, + args->offset); +} diff --git a/scalls/mmap.h b/scalls/mmap.h new file mode 100644 index 0000000..f5e121e --- /dev/null +++ b/scalls/mmap.h @@ -0,0 +1,13 @@ +#include +#include + +typedef struct SYS_MMAP_PARAMS { + void *addr; + size_t length; + int prot; + int flags; + int fd; + size_t offset; +} __attribute__((packed)) SYS_MMAP_PARAMS; + +void *syscall_mmap(SYS_MMAP_PARAMS *args); diff --git a/scalls/msleep.c b/scalls/msleep.c new file mode 100644 index 0000000..0120f08 --- /dev/null +++ b/scalls/msleep.c @@ -0,0 +1,9 @@ +#include +#include +#include +#include + +void syscall_msleep(uint32_t ms) { + get_current_task()->sleep_until = pit_num_ms() + ms; + switch_task(); +} diff --git a/scalls/msleep.h b/scalls/msleep.h new file mode 100644 index 0000000..71bf269 --- /dev/null +++ b/scalls/msleep.h @@ -0,0 +1,5 @@ +#ifndef MSLEEP_H +#define MSLEEP_H +#include +void syscall_msleep(uint32_t ms); +#endif diff --git a/scalls/ppoll.c b/scalls/ppoll.c new file mode 100644 index 0000000..8feb35c --- /dev/null +++ b/scalls/ppoll.c @@ -0,0 +1,11 @@ +#include +#include +#include +#include + +int syscall_poll(SYS_POLL_PARAMS *args) { + struct pollfd *fds = args->fds; + size_t nfds = args->nfds; + int timeout = args->timeout; + return poll(fds, nfds, timeout); +} diff --git a/scalls/ppoll.h b/scalls/ppoll.h new file mode 100644 index 0000000..13700b5 --- /dev/null +++ b/scalls/ppoll.h @@ -0,0 +1,9 @@ +#include + +typedef struct SYS_POLL_PARAMS { + struct pollfd *fds; + size_t nfds; + int timeout; +} __attribute__((packed)) SYS_POLL_PARAMS; + +int syscall_poll(SYS_POLL_PARAMS *args); diff --git a/scalls/shm.c b/scalls/shm.c new file mode 100644 index 0000000..2e8924f --- /dev/null +++ b/scalls/shm.c @@ -0,0 +1,10 @@ +#include "shm.h" +#include "../fs/shm.h" + +int syscall_shm_open(SYS_SHM_OPEN_PARAMS *args) { + return shm_open(args->name, args->oflag, args->mode); +} + +int syscall_ftruncate(SYS_FTRUNCATE_PARAMS *args) { + return ftruncate(args->fildes, args->length); +} diff --git a/scalls/shm.h b/scalls/shm.h new file mode 100644 index 0000000..6d4e13e --- /dev/null +++ b/scalls/shm.h @@ -0,0 +1,20 @@ +#ifndef SYS_SHM_H +#define SYS_SHM_H +#include +#include +typedef int mode_t; + +typedef struct SYS_SHM_OPEN_PARAMS { + const char *name; + int oflag; + mode_t mode; +} __attribute__((packed)) SYS_SHM_OPEN_PARAMS; + +typedef struct SYS_FTRUNCATE_PARAMS { + int fildes; + uint64_t length; +} __attribute__((packed)) SYS_FTRUNCATE_PARAMS; + +int syscall_shm_open(SYS_SHM_OPEN_PARAMS *args); +int syscall_ftruncate(SYS_FTRUNCATE_PARAMS *args); +#endif diff --git a/scalls/socket.c b/scalls/socket.c new file mode 100644 index 0000000..594c745 --- /dev/null +++ b/scalls/socket.c @@ -0,0 +1,5 @@ +#include "socket.h" + +int syscall_socket(SYS_SOCKET_PARAMS *args) { + return socket(args->domain, args->type, args->protocol); +} diff --git a/scalls/socket.h b/scalls/socket.h new file mode 100644 index 0000000..6540b0f --- /dev/null +++ b/scalls/socket.h @@ -0,0 +1,9 @@ +#include "../socket.h" + +typedef struct SYS_SOCKET_PARAMS { + int domain; + int type; + int protocol; +} __attribute__((packed)) SYS_SOCKET_PARAMS; + +int syscall_socket(SYS_SOCKET_PARAMS *args); diff --git a/scalls/stat.c b/scalls/stat.c new file mode 100644 index 0000000..0850151 --- /dev/null +++ b/scalls/stat.c @@ -0,0 +1,13 @@ +#include +#include +#include + +int syscall_stat(SYS_STAT_PARAMS *args) { + const char *pathname = copy_and_allocate_user_string(args->pathname); + struct stat *statbuf = args->statbuf; + vfs_inode_t *i = vfs_internal_open(pathname); + if (!i) + return -ENOENT; + statbuf->st_size = i->file_size; + return 0; +} diff --git a/scalls/stat.h b/scalls/stat.h new file mode 100644 index 0000000..78e8c45 --- /dev/null +++ b/scalls/stat.h @@ -0,0 +1,33 @@ +#include +#include + +typedef struct SYS_STAT_PARAMS { + const char *pathname; + struct stat *statbuf; +} __attribute__((packed)) SYS_STAT_PARAMS; + +struct stat { + dev_t st_dev; // Device ID of device containing file. + ino_t st_ino; // File serial number. + mode_t st_mode; // Mode of file (see below). + nlink_t st_nlink; // Number of hard links to the file. + uid_t st_uid; // User ID of file. + gid_t st_gid; // Group ID of file. + dev_t st_rdev; // Device ID (if file is character or block special). + off_t st_size; // For regular files, the file size in bytes. + // For symbolic links, the length in bytes of the + // pathname contained in the symbolic link. + // For a shared memory object, the length in bytes. + // For a typed memory object, the length in bytes. + // For other file types, the use of this field is + // unspecified. + struct timespec st_atim; // Last data access timestamp. + struct timespec st_mtim; // Last data modification timestamp. + struct timespec st_ctim; // Last file status change timestamp. + blksize_t st_blksize; // A file system-specific preferred I/O block size + // for this object. In some file system types, this + // may vary from file to file. + blkcnt_t st_blocks; // Number of blocks allocated for this object. +}; + +int syscall_stat(SYS_STAT_PARAMS *args); diff --git a/scalls/uptime.c b/scalls/uptime.c new file mode 100644 index 0000000..866c7e5 --- /dev/null +++ b/scalls/uptime.c @@ -0,0 +1,4 @@ +#include +#include + +uint32_t syscall_uptime(void) { return (uint32_t)pit_num_ms(); } diff --git a/scalls/uptime.h b/scalls/uptime.h new file mode 100644 index 0000000..2b5b0c9 --- /dev/null +++ b/scalls/uptime.h @@ -0,0 +1,2 @@ +#include +uint32_t syscall_uptime(void); diff --git a/sched/scheduler.c b/sched/scheduler.c new file mode 100644 index 0000000..2959693 --- /dev/null +++ b/sched/scheduler.c @@ -0,0 +1,388 @@ +#include +#include +#include +#include +#include +#include +#include + +#define STACK_LOCATION ((void *)0x90000000) +#define STACK_SIZE 0x80000 +#define HEAP_SIZE 0x400000 +#define HEAP_LOCATION (STACK_LOCATION - STACK_SIZE - HEAP_SIZE) + +process_t *ready_queue; +process_t *current_task = NULL; +uint32_t next_pid = 0; + +extern uint32_t read_eip(void); + +process_t *get_current_task(void) { return current_task; } + +process_t *create_process(process_t *p) { + process_t *r; + r = ksbrk(sizeof(process_t)); + r->dead = 0; + r->pid = next_pid++; + r->esp = r->ebp = 0; + r->eip = 0; + r->sleep_until = 0; + if (!p) { + assert(1 == next_pid); + strncpy(r->program_name, "[kernel]", sizeof(current_task->program_name)); + } else + strncpy(r->program_name, "[Not yet named]", + sizeof(current_task->program_name)); + + r->cr3 = (p) ? clone_directory(get_active_pagedirectory()) + : get_active_pagedirectory(); + r->next = 0; + r->parent = p; + r->child = NULL; + r->halt_list = NULL; + strcpy(r->current_working_directory, "/"); + r->data_segment_end = (p) ? p->data_segment_end : NULL; + memset((void *)r->halts, 0, 2 * sizeof(uint32_t)); + for (int i = 0; i < 100; i++) { + if (p) { + r->file_descriptors[i] = p->file_descriptors[i]; + if (r->file_descriptors[i]) { + r->file_descriptors[i]->reference_count++; + } + } + r->read_halt_inode[i] = NULL; + r->write_halt_inode[i] = NULL; + r->disconnect_halt_inode[i] = NULL; + r->maps[i] = NULL; + } + return r; +} + +int get_free_fd(process_t *p, int allocate) { + if (!p) + p = (process_t *)current_task; + int i; + for (i = 0; i < 100; i++) + if (!p->file_descriptors[i]) + break; + if (p->file_descriptors[i]) + return -1; + if (allocate) { + vfs_fd_t *fd = p->file_descriptors[i] = kmalloc(sizeof(vfs_fd_t)); + fd->inode = kmalloc(sizeof(vfs_inode_t)); + } + return i; +} + +void tasking_init(void) { current_task = ready_queue = create_process(NULL); } + +int i = 0; +void __attribute__((optimize("O0"))) free_process(void) { + kprintf("Exiting process: %s\n", get_current_task()->program_name); + // free_process() will purge all contents such as allocated frames + // out of the current process. This will be called by exit() and + // exec*(). + + // Do a special free for shared memory which avoids labeling + // underlying frames as "unused". + for (int i = 0; i < 100; i++) { + vfs_close(i); + if (!current_task->maps[i]) + continue; + MemoryMap *m = current_task->maps[i]; + mmu_remove_virtual_physical_address_mapping(m->u_address, 0x1000); + } + + // NOTE: Kernel stuff begins at 0x90000000 + mmu_free_address_range((void *)0x1000, 0x90000000); +} + +void exit(int status) { + assert(current_task->pid != 1); + if (current_task->parent) { + current_task->parent->halts[WAIT_CHILD_HALT] = 0; + current_task->parent->child_rc = status; + } + process_t *new_task = current_task; + for (; new_task == current_task;) { + if (!new_task->next) + new_task = ready_queue; + new_task = new_task->next; + } + + free_process(); + // Remove current_task from list + for (process_t *tmp = ready_queue; tmp;) { + if (tmp == current_task) // current_task is ready_queue(TODO: + // Figure out whether this could even + // happen) + { + ready_queue = current_task->next; + break; + } + if (tmp->next == current_task) { + tmp->next = tmp->next->next; + break; + } + tmp = tmp->next; + } + current_task->dead = 1; + // This function will enable interrupts + switch_task(); +} + +uint32_t setup_stack(uint32_t stack_pointer, int argc, char **argv) { + mmu_allocate_region(STACK_LOCATION - STACK_SIZE, STACK_SIZE, MMU_FLAG_RW); + flush_tlb(); + + uint32_t ptr = stack_pointer; + + char *argv_ptrs[argc + 1]; + for (int i = 0; i < argc; i++) { + char *s = argv[i]; + size_t l = strlen(s); + ptr -= l + 1; + char *b = (char *)ptr; + memcpy(b, s, l); + b[l] = '\0'; + argv_ptrs[i] = b; + } + + char **ptrs[argc + 1]; + for (int i = argc; i >= 0; i--) { + ptr -= sizeof(char *); + ptrs[i] = (char **)ptr; + if (i != argc) { + *(ptrs[i]) = argv_ptrs[i]; + } else { + *(ptrs[i]) = NULL; + } + } + + char *s = (char *)ptr; + ptr -= sizeof(char **); + *(char ***)ptr = (char **)s; + + ptr -= sizeof(int); + *(int *)ptr = argc; + return ptr; +} + +int exec(const char *filename, char **argv) { + // exec() will "takeover" the process by loading the file specified in + // filename into memory, change from ring 0 to ring 3 and jump to the + // files entry point as decided by the ELF header of the file. + int argc = 0; + for (; argv[argc];) { + argc++; + } + + uint32_t end_of_code; + void *entry = load_elf_file(filename, &end_of_code); + if (!entry) { + return 0; + } + + strncpy(current_task->program_name, filename, + sizeof(current_task->program_name)); + + current_task->data_segment_end = align_page((void *)end_of_code); + + uint32_t ptr = setup_stack(0x90000000, argc, argv); + + jump_usermode((void (*)())(entry), ptr); + ASSERT_NOT_REACHED; + return 0; +} + +int __attribute__((optimize("O0"))) fork(void) { + process_t *parent_task = (process_t *)current_task; + + process_t *new_task = create_process(parent_task); + + process_t *tmp_task = (process_t *)ready_queue; + for (; tmp_task->next;) + tmp_task = tmp_task->next; + + tmp_task->next = new_task; + + uint32_t eip = read_eip(); + + if (current_task != parent_task) { + return 0; + } + + new_task->child_rc = -1; + new_task->parent = current_task; + current_task->child = new_task; + + new_task->eip = eip; + asm("\ + mov %%esp, %0;\ + mov %%ebp, %1;" + : "=r"(new_task->esp), "=r"(new_task->ebp)); + asm("sti"); + return new_task->pid; +} + +int is_halted(process_t *process) { + for (int i = 0; i < 2; i++) + if (process->halts[i]) + return 1; + + if (isset_fdhalt(process->read_halt_inode, process->write_halt_inode, + process->disconnect_halt_inode)) { + return 1; + } + return 0; +} + +extern PageDirectory *active_directory; + +process_t *next_task(process_t *c) { + for (;;) { + c = c->next; + if (!c) + c = ready_queue; + if (c->sleep_until > pit_num_ms()) + continue; + if (is_halted(c) || c->dead) + continue; + break; + } + return c; +} + +int task_save_state(void) { + asm("mov %%esp, %0" : "=r"(current_task->esp)); + asm("mov %%ebp, %0" : "=r"(current_task->ebp)); + + uint32_t eip = read_eip(); + + if (0x1 == eip) { + // Should the returned value from read_eip be equal to one it + // means that we have just switched over to this task after we + // saved the state(since the switch_task() function changes the + // eax register to 1). + return 0; + } + + current_task->eip = eip; + return 1; +} + +void switch_task() { + if (!current_task) + return; + + if (0 == task_save_state()) { + return; + } + + current_task = next_task((process_t *)current_task); + + active_directory = current_task->cr3; + + asm(" \ + mov %0, %%esp; \ + mov %1, %%ebp; \ + mov %2, %%ecx; \ + mov %3, %%cr3; \ + mov $0x1, %%eax; \ + jmp *%%ecx" ::"r"(current_task->esp), + "r"(current_task->ebp), "r"(current_task->eip), + "r"(current_task->cr3->physical_address)); +} + +MemoryMap **get_free_map(void) { + for (int i = 0; i < 100; i++) + if (!(current_task->maps[i])) + return &(current_task->maps[i]); + assert(0); + return NULL; +} + +void *get_free_virtual_memory(size_t length) { + void *n = + (void *)((uintptr_t)(get_current_task()->data_segment_end) + length); + + void *rc = get_current_task()->data_segment_end; + get_current_task()->data_segment_end = align_page(n); + return rc; +} + +void *allocate_virtual_user_memory(size_t length, int prot, int flags) { + (void)prot; + (void)flags; + void *rc = get_free_virtual_memory(length); + if ((void *)-1 == rc) + return (void *)-1; + + mmu_allocate_region(rc, length, MMU_FLAG_RW); + return rc; +} + +void *user_kernel_mapping(void *kernel_addr, size_t length) { + void *rc = get_free_virtual_memory(length); + if ((void *)-1 == rc) + return (void *)-1; + + mmu_map_directories(rc, NULL, kernel_addr, NULL, length); + return rc; +} + +void *create_physical_mapping(void **physical_addresses, size_t length) { + void *rc = get_free_virtual_memory(length); + if ((void *)-1 == rc) + return (void *)-1; + int n = (uintptr_t)align_page((void *)length) / 0x1000; + for (int i = 0; i < n; i++) { + mmu_map_physical(rc + (i * 0x1000), NULL, physical_addresses[i], 0x1000); + } + return rc; +} + +void *mmap(void *addr, size_t length, int prot, int flags, int fd, + size_t offset) { + (void)addr; + if (0 == length) { + kprintf("EINVAL\n"); + return (void *)-EINVAL; + } + + vfs_vm_object_t *vmobject = vfs_get_vm_object(fd, length, offset); + if (!vmobject) { + kprintf("ENODEV\n"); + return (void *)-ENODEV; + } + + if (vmobject->size < length) { + kprintf("EOVERFLOW\n"); + return (void *)-EOVERFLOW; // TODO: Check if this is the correct + // code. + } + + MemoryMap **ptr = get_free_map(); + if (!ptr) { + klog("mmap(): No free memory map.", LOG_WARN); + return (void *)-1; + } + *ptr = kmalloc(sizeof(MemoryMap)); + MemoryMap *free_map = *ptr; + + if (fd == -1) { + void *rc = allocate_virtual_user_memory(length, prot, flags); + if ((void *)-1 == rc) { + kprintf("ENOMEM\n"); + return (void *)-ENOMEM; + } + free_map->u_address = rc; + free_map->k_address = NULL; + free_map->fd = -1; + return rc; + } + + if (length > vmobject->size) + length = vmobject->size; + return create_physical_mapping(vmobject->object, length); +} diff --git a/sched/scheduler.h b/sched/scheduler.h new file mode 100644 index 0000000..7ff0734 --- /dev/null +++ b/sched/scheduler.h @@ -0,0 +1,60 @@ +#ifndef SCHEDULER_H +#define SCHEDULER_H +#include +#include +#include +#include + +#define MAX_PATH 256 +#define KEYBOARD_HALT 0 +#define WAIT_CHILD_HALT 1 + +int fork(void); +int exec(const char *filename, char **argv); +void switch_task(); +void tasking_init(void); +void exit(int status); + +void *mmap(void *addr, size_t length, int prot, int flags, int fd, + size_t offset); +int munmap(void *addr, size_t length); +int msync(void *addr, size_t length, int flags); + +typedef struct { + void *u_address; + void *k_address; + int fd; +} MemoryMap; + +typedef struct Process process_t; + +struct Process { + uint32_t pid; + char program_name[100]; + char current_working_directory[MAX_PATH]; + uint32_t eip, esp, ebp; + PageDirectory *cr3; + vfs_fd_t *file_descriptors[100]; + vfs_inode_t *read_halt_inode[100]; + vfs_inode_t *write_halt_inode[100]; + vfs_inode_t *disconnect_halt_inode[100]; + // struct vfs_fd_t ** file_descriptors; + uint32_t halts[2]; + struct Halt *halt_list; + void *data_segment_end; + // uint32_t *halts; + process_t *next; + process_t *parent; + process_t *child; + MemoryMap *maps[100]; + uint32_t sleep_until; + int child_rc; + int dead; + // FIXME: Create a linkedlisti of childs so that the parent process + // can do stuff such as reap zombies and get status. +}; + +process_t *get_current_task(void); +int get_free_fd(process_t *p, int allocate); +void free_process(void); +#endif diff --git a/socket.c b/socket.c new file mode 100644 index 0000000..0e7437c --- /dev/null +++ b/socket.c @@ -0,0 +1,148 @@ +#include +#include +#include +#include +#include +#include + +OPEN_UNIX_SOCKET *un_sockets[100] = {0}; + +int uds_open(const char *path) { + // FIXME: This is super ugly + + // Find the socket that path belongs to + SOCKET *s = NULL; + for (int i = 0; i < 100; i++) { + if (!un_sockets[i]) + continue; + const char *p = path; + const char *e = p; + for (; *e; e++) + ; + for (; e != p && *e != '/'; e--) + ; + if (0 == strcmp(e, un_sockets[i]->path)) { + s = un_sockets[i]->s; + break; + } + } + if (!s) { + return -1; + } + + // Create a pipe + int fd[2]; + dual_pipe(fd); + + char c = 'i'; + raw_vfs_pwrite(s->ptr_fifo_fd, &c, 1, 0); + raw_vfs_pwrite(s->ptr_socket_fd, &c, 1, 0); + + s->incoming_fd = get_current_task()->file_descriptors[fd[1]]; + // vfs_close(fd[1]); + return fd[0]; +} + +int accept(int socket, struct sockaddr *address, socklen_t *address_len) { + (void)address; + (void)address_len; + vfs_inode_t *inode = get_current_task()->file_descriptors[socket]->inode; + SOCKET *s = (SOCKET *)inode->internal_object; + + if (NULL == s->incoming_fd) { + // Wait until we have gotten a connection + struct pollfd fds[1]; + fds[0].fd = s->fifo_fd; + fds[0].events = POLLIN; + fds[0].revents = 0; + poll(fds, 1, 0); + } + + int n = 0; + for (; get_current_task()->file_descriptors[n]; n++) + ; + get_current_task()->file_descriptors[n] = s->incoming_fd; + get_current_task()->file_descriptors[n]->reference_count++; + s->incoming_fd = NULL; + for (char c; 0 < vfs_pread(s->fifo_fd, &c, 1, 0);) + ; + inode->has_data = 0; + // s->ptr_fifo_fd->inode->has_data = 0; + + return n; +} + +int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { + (void)addrlen; + struct sockaddr_un *un = (struct sockaddr_un *)addr; + + vfs_fd_t *fd = get_vfs_fd(sockfd); + if (!fd) + return -EBADF; + vfs_inode_t *inode = fd->inode; + if (!inode) + return -EBADF; + SOCKET *s = (SOCKET *)inode->internal_object; + + size_t path_len = strlen(un->sun_path); + s->path = kmalloc(path_len + 1); + memcpy(s->path, un->sun_path, path_len); + s->path[path_len] = '\0'; + + OPEN_UNIX_SOCKET *us; + int i = 0; + for (; i < 100; i++) + if (!un_sockets[i]) + break; + + us = un_sockets[i] = kmalloc(sizeof(OPEN_UNIX_SOCKET)); + + us->path = s->path; + us->s = s; + devfs_add_file(us->path, NULL, NULL, NULL, 1, 1, FS_TYPE_UNIX_SOCKET); + return 0; +} + +int socket_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + (void)buffer; + (void)offset; + fd->inode->has_data = 1; + return len; +} + +int socket_read(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + (void)buffer; + (void)offset; + fd->inode->has_data = 0; + return len; +} + +void socket_close(vfs_fd_t *fd) { fd->inode->is_open = 0; } + +int socket(int domain, int type, int protocol) { + if (AF_UNIX != domain) + return -EINVAL; + + SOCKET *new_socket = kmalloc_eternal(sizeof(SOCKET)); + vfs_inode_t *inode = vfs_create_inode( + 0 /*inode_num*/, FS_TYPE_UNIX_SOCKET, 0 /*has_data*/, 1 /*can_write*/, + 1 /*is_open*/, new_socket /*internal_object*/, 0 /*file_size*/, + NULL /*open*/, NULL /*create_file*/, socket_read, socket_write, + socket_close, NULL /*get_vm_object*/); + + vfs_fd_t *fd; + int n = vfs_create_fd(O_RDWR | O_NONBLOCK, 0, inode, &fd); + + new_socket->domain = domain; + new_socket->type = type; + new_socket->protocol = protocol; + new_socket->path = NULL; + new_socket->incoming_fd = NULL; + new_socket->fifo_fd = create_fifo(); + new_socket->ptr_fifo_fd = + get_current_task()->file_descriptors[new_socket->fifo_fd]; + + new_socket->ptr_socket_fd = fd; + + return n; +} diff --git a/socket.h b/socket.h new file mode 100644 index 0000000..debe29d --- /dev/null +++ b/socket.h @@ -0,0 +1,66 @@ +#ifndef SOCKET_H +#define SOCKET_H +#include "fs/vfs.h" +#include +#include + +/* +// Create a directory with the proper permissions +mkdir(path, 0700); +// Append the name of the socket +strcat(path, "/socket_name"); + +// Create the socket normally +sockaddr_un address; +address.sun_family = AF_UNIX; +strcpy(address.sun_path, path); +int fd = socket(AF_UNIX, SOCK_STREAM, 0); +bind(fd, (sockaddr*)(&address), sizeof(address)); +listen(fd, 100); +*/ + +#define AF_UNIX 0 +#define AF_LOCAL AF_UNIX + +#define INADDR_ANY 0 + +typedef struct { + int fifo_fd; + vfs_fd_t *ptr_fifo_fd; + + vfs_fd_t *ptr_socket_fd; + + int domain; + int type; + int protocol; + + // UNIX socket + char *path; + vfs_fd_t *incoming_fd; +} SOCKET; + +typedef struct { + char *path; + SOCKET *s; +} OPEN_UNIX_SOCKET; + +typedef uint32_t in_addr_t; +typedef uint16_t in_port_t; +typedef unsigned int sa_family_t; +typedef uint32_t socklen_t; + +struct sockaddr { + sa_family_t sa_family; /* Address family */ + char *sa_data; /* Socket address */ +}; + +struct sockaddr_un { + sa_family_t sun_family; /* Address family */ + char *sun_path; /* Socket pathname */ +}; + +int uds_open(const char *path); +int socket(int domain, int type, int protocol); +int accept(int socket, struct sockaddr *address, socklen_t *address_len); +int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); +#endif diff --git a/sync.sh b/sync.sh new file mode 100755 index 0000000..1d94ab1 --- /dev/null +++ b/sync.sh @@ -0,0 +1,137 @@ +#!/bin/sh +#pwd +#cd /home/anton/prj/osdev/ +#cd ./userland/json/hashmap +#make clean +#make +#cd ../../.. +# +#cd ./userland/json +#make clean +#make +#cd ../.. +# +cd ./userland/libgui +make clean +make +cd ../.. +# +cd ./userland/libc +#make clean +make +make install +cd ../.. +cd ./userland/nasm-2.16.01 +#make clean +make +#make install +cd ../.. + +cd ./userland/compiler +make +cd ../.. + +#cd ./userland/init +#make clean +#make +#cd ../.. +# +cd ./userland/sh +make clean +make +cd ../.. +cd ./userland/sha1sum +make clean +make +cd ../.. +# +#cd ./userland/cat +#make clean +#make +#cd ../.. +# +cd ./userland/terminal +make clean +make +cd ../.. +# +cd ./userland/snake +make clean +make +cd ../.. +# +cd ./userland/ante +make clean +make +cd ../.. +# +cd ./userland/windowserver +make clean +make +cd ../.. +# +cd ./userland/test +make clean +make +cd ../.. +# +cd ./userland/minibox +make clean +make +cd ../.. + +#cd ./userland/figlet +#cd ./userland/figlet-2.2.5/ +#make clean +#make +#cd ../.. + +pwd +sudo mount ext2.img mount +#sudo cp ./userland/init/init ./mount/init +#sudo cp ./userland/cat/cat ./mount/cat +sudo cp ./userland/sh/sh ./mount/sh +sudo cp ./userland/terminal/term ./mount/term +sudo cp ./userland/snake/snake ./mount/snake +sudo cp ./userland/ante/ante ./mount/ante +sudo cp ./userland/windowserver/ws ./mount/ws +sudo cp ./userland/test/test ./mount/test +sudo cp ./userland/minibox/minibox ./mount/minibox +sudo cp ./userland/nasm-2.16.01/nasm ./mount/nasm + +sudo cp ./userland/figlet-2.2.5/figlet ./mount/ +sudo cp ./userland/figlet-2.2.5/chkfont ./mount/ +sudo cp ./userland/figlet-2.2.5/figlist ./mount/ +sudo cp ./userland/figlet-2.2.5/showfigfonts ./mount/ + +sudo cp ./userland/figlet-2.2.5/fonts/*.flf ./mount/fonts/ +sudo cp ./userland/figlet-2.2.5/fonts/*.flc ./mount/fonts/ + +sudo cp ./DOOM1.WAD ./mount/DOOM1.WAD +sudo cp ./userland/compiler/compiler ./mount/cc +sudo cp ./userland/sha1sum/sha1sum ./mount/sha1sum +sudo cp ./userland/sha1sum/sha1sum ./mount/sa +sudo cp ./userland/fasm/fasm ./mount/fasm +sudo cp ./userland/ed/ed ./mount/ed +sudo cp ./userland/SmallerC/smlrc ./mount/sc +sudo cp ./userland/libc/crt0.o ./mount/crt0.o +sudo cp ./userland/libc/libc.a ./mount/libc.a +sudo cp ./userland/doomgeneric/doomgeneric/doomgeneric ./mount/doomgeneric +echo -e "int main(void) {\nprintf(\"hi\");\nreturn 0;\n}" > /tmp/main.c + +cd ./mount +sudo rm ./init +sudo rm ./cat +sudo rm ./yes +sudo rm ./echo +sudo rm ./wc +sudo rm ./ls +sudo ln -s ./minibox ./init +sudo ln -s ./minibox ./cat +sudo ln -s ./minibox ./yes +sudo ln -s ./minibox ./echo +sudo ln -s ./minibox ./wc +sudo ln -s ./minibox ./ls +sudo cp /tmp/main.c ./main.c +cd .. +sudo umount mount diff --git a/time.h b/time.h new file mode 100644 index 0000000..2d4eef6 --- /dev/null +++ b/time.h @@ -0,0 +1,10 @@ +#ifndef TIME_H +#define TIME_H +#include + +typedef int clockid_t; +struct timespec { + time_t tv_sec; // Seconds. + long tv_nsec; // Nanoseconds. +}; +#endif diff --git a/toolchain/3A24BC1E8FB409FA9F14371813FCEF89DD9E3C4F b/toolchain/3A24BC1E8FB409FA9F14371813FCEF89DD9E3C4F new file mode 100644 index 0000000..b778c91 --- /dev/null +++ b/toolchain/3A24BC1E8FB409FA9F14371813FCEF89DD9E3C4F @@ -0,0 +1,38 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +xsFNBFm/2cUBEADkvRqMWfAryJ52T4J/640Av5cam9ojdFih9MjcX7QWFxIzJfTF +Yq2z+nb4omdfZosdCJL2zGcn6C0AxpHNvxR9HMDkEyFHKrjDh4xWU+pH4z9azQEq +Jh331X7UzbZldqQo16VkuVavgsTJaHcXm+nGIBTcUbl2oiTtHhmuaYxx6JTMcFjC +7vyO5mLBw78wt52HBYweJ0NjHBvvH/JxbAAULSPRUC61K0exlO49VFbFETQNG1hZ +TKEji95fPbre7PpXQ0ewQShUgttEE/J3UA4jYaF9lOcZgUzbA27xTV//KomP0D30 +yr4e4EJEJYYNKa3hofTEHDXeeNgM25tprhBUMdbVRZpf2Keuk2uDVwc+EiOVri48 +rb1NU+60sOXvoGO6Ks81+mhAGmrBrlgLhAp8K1HPHI4MG4gHnrMqX2rEGUGRPFjC +3qqVVlPm8H05PnosNqDLQ1Pf7C0pVgsCx6hKQB7Y1qBui7aoj9zeFaQgpYef+CEE +RIKEcWwrjaOJwK3pi9HFdxS0NNWYZj8HPzz/AsgTTQdsbulPlVq2SsctmOnL42CZ +OCTppGYwl53CG/EqVY+UQBzFzJBaY8TJRFFYVEy5/HH4H11rMoZwqIkk71EOGU3X +6mWlANRikR3M4GhVITRzuaV69Fed+OeXcCmP94ASLfuhBR2uynmcHpBKpwARAQAB +zsFNBFm/2cUBEAC2iRP97tt607zy5IrWkyRaipMD1cpc5MJinb3dqnhBZNasrNid +7QAkzMmFZ2E0l8uRCR9sycoVHy54S6fIyWReKFOUHoTmiT3DJsyPwmUtQJh/o55u +qbpHWQKME8ycreCCkmqa/u5sXMV9WENl3sDJxWKS5AANnR2goS0lPxByV3t/juA4 +BFEUxTGt0kTfyeBjTAWnCl5zEkmMpSOQ3CDmf79CBmuTAFx6z9R8JtawZpaCHIJs +3sXMwX/iHFoAi04chT337/tqXyytV2kvNjswQu30tNaQf3gzpI0ListerCmV+kbe +e77neNLhOWtJaciLQtj+7u0Fi+Mk+aTBfqEvG5t2FoBJ7Vd/NEcmaaoCRmU2Szat +k+GYH4mrnhFeCczpxtv0ERozlKzUGmMysuVdduwk50YOAWBf7ixJosy3CNzt1Nfp +hM+oePMJAKIztQegGfC5vibsTluaLhnK5ExLiBuehnA8DFkvz8P7zbA8jZjgo8vX +hCliYJjJi2qufR6X03fCDnmmMrgEBwLGLf88ystIIjII4QkLbnPfROJ0BPSmeOAy +rJ6kWmyvbN82BNzyJAhSBGXFIiV0l1ljiHSeN4/mMhR1OYal3xAjOq8yhgXgVBk8 +8lnDl+mMETOC80A1ScGBvHFX7Yfr+PyJnF0eNw+FlccQRAIymoNNm/tcnwARAQAB +wsFfBBgBAgAJBQJZv9nFAhsMAAoJEBP874ndnjxP3akP+gKVMILGc7abNDDnUXXY +z8M+OKVl0uTBuOYqzEFxCxkMsZK2n3PJcB3gAWLLaCvHaaKU3CRhN3WRi9yTc9WF +sUOQFeLsqgZ+TfEbm3APDc0eg0D/jhjyMMzJHrb1Qv3G2yg2an9Lkw8t4z+uThYU +pExCMp2L9TG+CSZd0qvoWlG31iwFeZ26Erh5omROgc9vk43aFZDcBwX6asbujJVp +Gvj/fElHJmPIlYT8vUAtVxThnRQxX9ZGIB1tu5hcHbN+TUITQEYH7QFc/RWV67lu +rRSCH4rI6961Yw/UfFYC+5ebzK/cpThaXqZyOvsHdl9eeuh1uxdWcNQyK2NjRy+5 +C+et+Wx6yWOJ+6P5+xJZPwmvzAKs3SGcc+qK313iJrKmejg5+GOOz06Et0692zDT +fTerZjj0GZCRhwwRMW4QIvyafH6VsTJqVQlJenPOXDgQkeLPLWbLxmDo0dwr6iq1 ++G2/BhJa4TrwCWug3ZmV3OwMqFTGk74aat4CWCpguuKKre88CB8GgsU2z+guqFKf +RDUVe5x51zdwZbyIAqOEBLOh5A85JoGJQhDigYg8lTEpDw2XbLKWviuBpVNksIvw +QyTI7Q8cqPitDPNS118TnkXxCHz7Wd3XcQSj72tbkrLs/qWzfXdSWPCqOU/4derL +rItkXlMjSRCWkp4zuc9d00NV +=n5Jz +-----END PGP PUBLIC KEY BLOCK----- diff --git a/toolchain/binutils-2.40.diff b/toolchain/binutils-2.40.diff new file mode 100644 index 0000000..e8eb8bb --- /dev/null +++ b/toolchain/binutils-2.40.diff @@ -0,0 +1,12573 @@ +diff --git a/bfd/config.bfd b/bfd/config.bfd +index 1b0111fd..369f7299 100644 +--- a/bfd/config.bfd ++++ b/bfd/config.bfd +@@ -237,6 +237,11 @@ esac + + case "${targ}" in + # START OF targmatch.h ++ i[3-7]86-*-sb*) ++ targ_defvec=i386_elf32_vec ++ targ_selvecs= ++ targ64_selvecs=x86_64_elf64_vec ++ ;; + #ifdef BFD64 + aarch64-*-darwin*) + targ_defvec=aarch64_mach_o_vec +diff --git a/config.sub b/config.sub +index dba16e84..b30aad24 100755 +--- a/config.sub ++++ b/config.sub +@@ -1754,7 +1754,7 @@ case $os in + | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ + | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \ +- | fiwix* ) ++ | fiwix* | sb* ) + ;; + # This one is extra strict with allowed versions + sco3.2v2 | sco3.2v[4-9]* | sco5v6*) +diff --git a/gas/configure.tgt b/gas/configure.tgt +index 765ba736..85257e12 100644 +--- a/gas/configure.tgt ++++ b/gas/configure.tgt +@@ -125,6 +125,7 @@ esac + generic_target=${cpu_type}-$vendor-$os + # Note: This table is alpha-sorted, please try to keep it that way. + case ${generic_target} in ++ i386-*-sb*) fmt=elf ;; + aarch64*-*-elf*) fmt=elf;; + aarch64*-*-fuchsia*) fmt=elf;; + aarch64*-*-haiku*) fmt=elf em=haiku ;; +diff --git a/ld/Makefile.am b/ld/Makefile.am +index 12b2c3c4..a9864474 100644 +--- a/ld/Makefile.am ++++ b/ld/Makefile.am +@@ -152,6 +152,7 @@ endif + + # These all start with e so 'make clean' can find them. + ALL_EMULATION_SOURCES = \ ++ eelf_i386_sb.c \ + eaix5ppc.c \ + eaix5rs6.c \ + eaixppc.c \ +@@ -770,6 +771,8 @@ $(ALL_EMULATION_SOURCES) $(ALL_64_EMULATION_SOURCES): $(GEN_DEPENDS) + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xtensa.Pc@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32z80.Pc@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386.Pc@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_sb.Pc@am__quote@ ++#@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_sb.Pc@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_be.Pc@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_fbsd.Pc@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_haiku.Pc@am__quote@ +diff --git a/ld/Makefile.in b/ld/Makefile.in +index 3d5685d6..b542e0e8 100644 +--- a/ld/Makefile.in ++++ b/ld/Makefile.in +@@ -1,7 +1,7 @@ +-# Makefile.in generated by automake 1.15.1 from Makefile.am. ++# Makefile.in generated by automake 1.16.5 from Makefile.am. + # @configure_input@ + +-# Copyright (C) 1994-2017 Free Software Foundation, Inc. ++# Copyright (C) 1994-2021 Free Software Foundation, Inc. + + # This Makefile.in is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -110,27 +110,8 @@ target_triplet = @target@ + bin_PROGRAMS = ld-new$(EXEEXT) + subdir = . + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +-am__aclocal_m4_deps = $(top_srcdir)/../bfd/acinclude.m4 \ +- $(top_srcdir)/../bfd/warning.m4 $(top_srcdir)/../config/acx.m4 \ +- $(top_srcdir)/../config/bfd64.m4 \ +- $(top_srcdir)/../config/depstand.m4 \ +- $(top_srcdir)/../config/enable.m4 \ +- $(top_srcdir)/../config/gettext-sister.m4 \ +- $(top_srcdir)/../config/jobserver.m4 \ +- $(top_srcdir)/../config/largefile.m4 \ +- $(top_srcdir)/../config/lcmessage.m4 \ +- $(top_srcdir)/../config/lead-dot.m4 \ +- $(top_srcdir)/../config/nls.m4 \ +- $(top_srcdir)/../config/override.m4 \ +- $(top_srcdir)/../config/pkg.m4 \ +- $(top_srcdir)/../config/plugins.m4 \ +- $(top_srcdir)/../config/po.m4 \ +- $(top_srcdir)/../config/progtest.m4 \ +- $(top_srcdir)/../config/zlib.m4 \ +- $(top_srcdir)/../config/zstd.m4 $(top_srcdir)/../libtool.m4 \ +- $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \ +- $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \ +- $(top_srcdir)/../bfd/version.m4 $(top_srcdir)/configure.ac ++am__aclocal_m4_deps = $(top_srcdir)/../bfd/version.m4 \ ++ $(top_srcdir)/configure.ac + am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) + DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ +@@ -141,6 +122,9 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs + CONFIG_HEADER = config.h + CONFIG_CLEAN_FILES = po/Makefile.in + CONFIG_CLEAN_VPATH_FILES = ++am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bfdplugindir)" \ ++ "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)" ++PROGRAMS = $(bin_PROGRAMS) + am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; + am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ +@@ -168,8 +152,6 @@ am__uninstall_files_from_dir = { \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +-am__installdirs = "$(DESTDIR)$(bfdplugindir)" "$(DESTDIR)$(bindir)" \ +- "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)" + LTLIBRARIES = $(bfdplugin_LTLIBRARIES) $(noinst_LTLIBRARIES) + libdep_la_LIBADD = + am_libdep_la_OBJECTS = libdep_plugin.lo +@@ -206,7 +188,6 @@ libldtestplug4_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libldtestplug4_la_CFLAGS) $(CFLAGS) \ + $(libldtestplug4_la_LDFLAGS) $(LDFLAGS) -o $@ +-PROGRAMS = $(bin_PROGRAMS) + am_ld_new_OBJECTS = ldgram.$(OBJEXT) ldlex-wrapper.$(OBJEXT) \ + lexsup.$(OBJEXT) ldlang.$(OBJEXT) mri.$(OBJEXT) \ + ldctor.$(OBJEXT) ldmain.$(OBJEXT) ldwrite.$(OBJEXT) \ +@@ -230,7 +211,188 @@ am__v_at_0 = @ + am__v_at_1 = + DEFAULT_INCLUDES = -I.@am__isrc@ + depcomp = $(SHELL) $(top_srcdir)/../depcomp +-am__depfiles_maybe = depfiles ++am__maybe_remake_depfiles = depfiles ++am__depfiles_remade = ./$(DEPDIR)/deffilep.Po \ ++ ./$(DEPDIR)/eaarch64cloudabi.Po \ ++ ./$(DEPDIR)/eaarch64cloudabib.Po ./$(DEPDIR)/eaarch64elf.Po \ ++ ./$(DEPDIR)/eaarch64elf32.Po ./$(DEPDIR)/eaarch64elf32b.Po \ ++ ./$(DEPDIR)/eaarch64elfb.Po ./$(DEPDIR)/eaarch64fbsd.Po \ ++ ./$(DEPDIR)/eaarch64fbsdb.Po ./$(DEPDIR)/eaarch64haiku.Po \ ++ ./$(DEPDIR)/eaarch64linux.Po ./$(DEPDIR)/eaarch64linux32.Po \ ++ ./$(DEPDIR)/eaarch64linux32b.Po ./$(DEPDIR)/eaarch64linuxb.Po \ ++ ./$(DEPDIR)/eaarch64pe.Po ./$(DEPDIR)/eaix5ppc.Po \ ++ ./$(DEPDIR)/eaix5rs6.Po ./$(DEPDIR)/eaixppc.Po \ ++ ./$(DEPDIR)/eaixrs6.Po ./$(DEPDIR)/ealpha.Po \ ++ ./$(DEPDIR)/ealphavms.Po ./$(DEPDIR)/earcelf.Po \ ++ ./$(DEPDIR)/earclinux.Po ./$(DEPDIR)/earclinux_nps.Po \ ++ ./$(DEPDIR)/earcv2elf.Po ./$(DEPDIR)/earcv2elfx.Po \ ++ ./$(DEPDIR)/earm_wince_pe.Po ./$(DEPDIR)/earmelf.Po \ ++ ./$(DEPDIR)/earmelf_fbsd.Po ./$(DEPDIR)/earmelf_fuchsia.Po \ ++ ./$(DEPDIR)/earmelf_haiku.Po ./$(DEPDIR)/earmelf_linux.Po \ ++ ./$(DEPDIR)/earmelf_linux_eabi.Po \ ++ ./$(DEPDIR)/earmelf_linux_fdpiceabi.Po \ ++ ./$(DEPDIR)/earmelf_nacl.Po ./$(DEPDIR)/earmelf_nbsd.Po \ ++ ./$(DEPDIR)/earmelf_phoenix.Po ./$(DEPDIR)/earmelf_vxworks.Po \ ++ ./$(DEPDIR)/earmelfb.Po ./$(DEPDIR)/earmelfb_fbsd.Po \ ++ ./$(DEPDIR)/earmelfb_fuchsia.Po ./$(DEPDIR)/earmelfb_linux.Po \ ++ ./$(DEPDIR)/earmelfb_linux_eabi.Po \ ++ ./$(DEPDIR)/earmelfb_linux_fdpiceabi.Po \ ++ ./$(DEPDIR)/earmelfb_nacl.Po ./$(DEPDIR)/earmelfb_nbsd.Po \ ++ ./$(DEPDIR)/earmnto.Po ./$(DEPDIR)/earmpe.Po \ ++ ./$(DEPDIR)/eavr1.Po ./$(DEPDIR)/eavr2.Po \ ++ ./$(DEPDIR)/eavr25.Po ./$(DEPDIR)/eavr3.Po \ ++ ./$(DEPDIR)/eavr31.Po ./$(DEPDIR)/eavr35.Po \ ++ ./$(DEPDIR)/eavr4.Po ./$(DEPDIR)/eavr5.Po \ ++ ./$(DEPDIR)/eavr51.Po ./$(DEPDIR)/eavr6.Po \ ++ ./$(DEPDIR)/eavrtiny.Po ./$(DEPDIR)/eavrxmega1.Po \ ++ ./$(DEPDIR)/eavrxmega2.Po ./$(DEPDIR)/eavrxmega3.Po \ ++ ./$(DEPDIR)/eavrxmega4.Po ./$(DEPDIR)/eavrxmega5.Po \ ++ ./$(DEPDIR)/eavrxmega6.Po ./$(DEPDIR)/eavrxmega7.Po \ ++ ./$(DEPDIR)/ecrisaout.Po ./$(DEPDIR)/ecriself.Po \ ++ ./$(DEPDIR)/ecrislinux.Po ./$(DEPDIR)/ecskyelf.Po \ ++ ./$(DEPDIR)/ecskyelf_linux.Po ./$(DEPDIR)/ed10velf.Po \ ++ ./$(DEPDIR)/ed30v_e.Po ./$(DEPDIR)/ed30v_o.Po \ ++ ./$(DEPDIR)/ed30velf.Po ./$(DEPDIR)/eelf32_dlx.Po \ ++ ./$(DEPDIR)/eelf32_sparc.Po ./$(DEPDIR)/eelf32_sparc_sol2.Po \ ++ ./$(DEPDIR)/eelf32_sparc_vxworks.Po ./$(DEPDIR)/eelf32_spu.Po \ ++ ./$(DEPDIR)/eelf32_tic6x_be.Po \ ++ ./$(DEPDIR)/eelf32_tic6x_elf_be.Po \ ++ ./$(DEPDIR)/eelf32_tic6x_elf_le.Po \ ++ ./$(DEPDIR)/eelf32_tic6x_le.Po \ ++ ./$(DEPDIR)/eelf32_tic6x_linux_be.Po \ ++ ./$(DEPDIR)/eelf32_tic6x_linux_le.Po \ ++ ./$(DEPDIR)/eelf32_x86_64.Po ./$(DEPDIR)/eelf32am33lin.Po \ ++ ./$(DEPDIR)/eelf32b4300.Po ./$(DEPDIR)/eelf32bfin.Po \ ++ ./$(DEPDIR)/eelf32bfinfd.Po ./$(DEPDIR)/eelf32bmip.Po \ ++ ./$(DEPDIR)/eelf32bmipn32.Po ./$(DEPDIR)/eelf32briscv.Po \ ++ ./$(DEPDIR)/eelf32briscv_ilp32.Po \ ++ ./$(DEPDIR)/eelf32briscv_ilp32f.Po ./$(DEPDIR)/eelf32bsmip.Po \ ++ ./$(DEPDIR)/eelf32btsmip.Po ./$(DEPDIR)/eelf32btsmip_fbsd.Po \ ++ ./$(DEPDIR)/eelf32btsmipn32.Po \ ++ ./$(DEPDIR)/eelf32btsmipn32_fbsd.Po ./$(DEPDIR)/eelf32cr16.Po \ ++ ./$(DEPDIR)/eelf32crx.Po ./$(DEPDIR)/eelf32ebmip.Po \ ++ ./$(DEPDIR)/eelf32ebmipvxworks.Po ./$(DEPDIR)/eelf32elmip.Po \ ++ ./$(DEPDIR)/eelf32elmipvxworks.Po \ ++ ./$(DEPDIR)/eelf32epiphany.Po \ ++ ./$(DEPDIR)/eelf32epiphany_4x4.Po ./$(DEPDIR)/eelf32fr30.Po \ ++ ./$(DEPDIR)/eelf32frv.Po ./$(DEPDIR)/eelf32frvfd.Po \ ++ ./$(DEPDIR)/eelf32ft32.Po ./$(DEPDIR)/eelf32ip2k.Po \ ++ ./$(DEPDIR)/eelf32iq10.Po ./$(DEPDIR)/eelf32iq2000.Po \ ++ ./$(DEPDIR)/eelf32l4300.Po ./$(DEPDIR)/eelf32lm32.Po \ ++ ./$(DEPDIR)/eelf32lm32fd.Po ./$(DEPDIR)/eelf32lmip.Po \ ++ ./$(DEPDIR)/eelf32loongarch.Po ./$(DEPDIR)/eelf32lppc.Po \ ++ ./$(DEPDIR)/eelf32lppclinux.Po ./$(DEPDIR)/eelf32lppcnto.Po \ ++ ./$(DEPDIR)/eelf32lppcsim.Po ./$(DEPDIR)/eelf32lr5900.Po \ ++ ./$(DEPDIR)/eelf32lr5900n32.Po ./$(DEPDIR)/eelf32lriscv.Po \ ++ ./$(DEPDIR)/eelf32lriscv_ilp32.Po \ ++ ./$(DEPDIR)/eelf32lriscv_ilp32f.Po ./$(DEPDIR)/eelf32lsmip.Po \ ++ ./$(DEPDIR)/eelf32ltsmip.Po ./$(DEPDIR)/eelf32ltsmip_fbsd.Po \ ++ ./$(DEPDIR)/eelf32ltsmipn32.Po \ ++ ./$(DEPDIR)/eelf32ltsmipn32_fbsd.Po ./$(DEPDIR)/eelf32m32c.Po \ ++ ./$(DEPDIR)/eelf32mb_linux.Po ./$(DEPDIR)/eelf32mbel_linux.Po \ ++ ./$(DEPDIR)/eelf32mcore.Po ./$(DEPDIR)/eelf32mep.Po \ ++ ./$(DEPDIR)/eelf32metag.Po ./$(DEPDIR)/eelf32microblaze.Po \ ++ ./$(DEPDIR)/eelf32microblazeel.Po \ ++ ./$(DEPDIR)/eelf32mipswindiss.Po ./$(DEPDIR)/eelf32moxie.Po \ ++ ./$(DEPDIR)/eelf32mt.Po ./$(DEPDIR)/eelf32or1k.Po \ ++ ./$(DEPDIR)/eelf32or1k_linux.Po ./$(DEPDIR)/eelf32ppc.Po \ ++ ./$(DEPDIR)/eelf32ppc_fbsd.Po ./$(DEPDIR)/eelf32ppchaiku.Po \ ++ ./$(DEPDIR)/eelf32ppclinux.Po ./$(DEPDIR)/eelf32ppcnto.Po \ ++ ./$(DEPDIR)/eelf32ppcsim.Po ./$(DEPDIR)/eelf32ppcvxworks.Po \ ++ ./$(DEPDIR)/eelf32ppcwindiss.Po ./$(DEPDIR)/eelf32rl78.Po \ ++ ./$(DEPDIR)/eelf32rx.Po ./$(DEPDIR)/eelf32rx_linux.Po \ ++ ./$(DEPDIR)/eelf32tilegx.Po ./$(DEPDIR)/eelf32tilegx_be.Po \ ++ ./$(DEPDIR)/eelf32tilepro.Po ./$(DEPDIR)/eelf32vax.Po \ ++ ./$(DEPDIR)/eelf32visium.Po ./$(DEPDIR)/eelf32xstormy16.Po \ ++ ./$(DEPDIR)/eelf32xtensa.Po ./$(DEPDIR)/eelf32z80.Po \ ++ ./$(DEPDIR)/eelf64_aix.Po ./$(DEPDIR)/eelf64_ia64.Po \ ++ ./$(DEPDIR)/eelf64_ia64_fbsd.Po ./$(DEPDIR)/eelf64_ia64_vms.Po \ ++ ./$(DEPDIR)/eelf64_s390.Po ./$(DEPDIR)/eelf64_sparc.Po \ ++ ./$(DEPDIR)/eelf64_sparc_fbsd.Po \ ++ ./$(DEPDIR)/eelf64_sparc_sol2.Po ./$(DEPDIR)/eelf64alpha.Po \ ++ ./$(DEPDIR)/eelf64alpha_fbsd.Po \ ++ ./$(DEPDIR)/eelf64alpha_nbsd.Po ./$(DEPDIR)/eelf64bmip.Po \ ++ ./$(DEPDIR)/eelf64bpf.Po ./$(DEPDIR)/eelf64briscv.Po \ ++ ./$(DEPDIR)/eelf64briscv_lp64.Po \ ++ ./$(DEPDIR)/eelf64briscv_lp64f.Po ./$(DEPDIR)/eelf64btsmip.Po \ ++ ./$(DEPDIR)/eelf64btsmip_fbsd.Po ./$(DEPDIR)/eelf64hppa.Po \ ++ ./$(DEPDIR)/eelf64loongarch.Po ./$(DEPDIR)/eelf64lppc.Po \ ++ ./$(DEPDIR)/eelf64lppc_fbsd.Po ./$(DEPDIR)/eelf64lriscv.Po \ ++ ./$(DEPDIR)/eelf64lriscv_lp64.Po \ ++ ./$(DEPDIR)/eelf64lriscv_lp64f.Po ./$(DEPDIR)/eelf64ltsmip.Po \ ++ ./$(DEPDIR)/eelf64ltsmip_fbsd.Po ./$(DEPDIR)/eelf64mmix.Po \ ++ ./$(DEPDIR)/eelf64ppc.Po ./$(DEPDIR)/eelf64ppc_fbsd.Po \ ++ ./$(DEPDIR)/eelf64rdos.Po ./$(DEPDIR)/eelf64tilegx.Po \ ++ ./$(DEPDIR)/eelf64tilegx_be.Po ./$(DEPDIR)/eelf_i386.Po \ ++ ./$(DEPDIR)/eelf_i386_be.Po ./$(DEPDIR)/eelf_i386_fbsd.Po \ ++ ./$(DEPDIR)/eelf_i386_haiku.Po ./$(DEPDIR)/eelf_i386_ldso.Po \ ++ ./$(DEPDIR)/eelf_i386_sb.Po ./$(DEPDIR)/eelf_i386_sol2.Po \ ++ ./$(DEPDIR)/eelf_i386_vxworks.Po ./$(DEPDIR)/eelf_iamcu.Po \ ++ ./$(DEPDIR)/eelf_mipsel_haiku.Po ./$(DEPDIR)/eelf_s390.Po \ ++ ./$(DEPDIR)/eelf_x86_64.Po ./$(DEPDIR)/eelf_x86_64_cloudabi.Po \ ++ ./$(DEPDIR)/eelf_x86_64_fbsd.Po \ ++ ./$(DEPDIR)/eelf_x86_64_haiku.Po \ ++ ./$(DEPDIR)/eelf_x86_64_sol2.Po ./$(DEPDIR)/eh8300elf.Po \ ++ ./$(DEPDIR)/eh8300elf_linux.Po ./$(DEPDIR)/eh8300helf.Po \ ++ ./$(DEPDIR)/eh8300helf_linux.Po ./$(DEPDIR)/eh8300hnelf.Po \ ++ ./$(DEPDIR)/eh8300self.Po ./$(DEPDIR)/eh8300self_linux.Po \ ++ ./$(DEPDIR)/eh8300snelf.Po ./$(DEPDIR)/eh8300sxelf.Po \ ++ ./$(DEPDIR)/eh8300sxelf_linux.Po ./$(DEPDIR)/eh8300sxnelf.Po \ ++ ./$(DEPDIR)/ehppa64linux.Po ./$(DEPDIR)/ehppaelf.Po \ ++ ./$(DEPDIR)/ehppalinux.Po ./$(DEPDIR)/ehppanbsd.Po \ ++ ./$(DEPDIR)/ehppaobsd.Po ./$(DEPDIR)/ei386aout.Po \ ++ ./$(DEPDIR)/ei386beos.Po ./$(DEPDIR)/ei386bsd.Po \ ++ ./$(DEPDIR)/ei386go32.Po ./$(DEPDIR)/ei386lynx.Po \ ++ ./$(DEPDIR)/ei386moss.Po ./$(DEPDIR)/ei386msdos.Po \ ++ ./$(DEPDIR)/ei386nto.Po ./$(DEPDIR)/ei386pe.Po \ ++ ./$(DEPDIR)/ei386pe_posix.Po ./$(DEPDIR)/ei386pep.Po \ ++ ./$(DEPDIR)/em32relf.Po ./$(DEPDIR)/em32relf_linux.Po \ ++ ./$(DEPDIR)/em32rlelf.Po ./$(DEPDIR)/em32rlelf_linux.Po \ ++ ./$(DEPDIR)/em68hc11elf.Po ./$(DEPDIR)/em68hc11elfb.Po \ ++ ./$(DEPDIR)/em68hc12elf.Po ./$(DEPDIR)/em68hc12elfb.Po \ ++ ./$(DEPDIR)/em68kelf.Po ./$(DEPDIR)/em68kelfnbsd.Po \ ++ ./$(DEPDIR)/em9s12zelf.Po ./$(DEPDIR)/emcorepe.Po \ ++ ./$(DEPDIR)/emmo.Po ./$(DEPDIR)/emn10200.Po \ ++ ./$(DEPDIR)/emn10300.Po ./$(DEPDIR)/emoxiebox.Po \ ++ ./$(DEPDIR)/emsp430X.Po ./$(DEPDIR)/emsp430elf.Po \ ++ ./$(DEPDIR)/ends32belf.Po ./$(DEPDIR)/ends32belf16m.Po \ ++ ./$(DEPDIR)/ends32belf_linux.Po ./$(DEPDIR)/ends32elf.Po \ ++ ./$(DEPDIR)/ends32elf16m.Po ./$(DEPDIR)/ends32elf_linux.Po \ ++ ./$(DEPDIR)/enios2elf.Po ./$(DEPDIR)/enios2linux.Po \ ++ ./$(DEPDIR)/ens32knbsd.Po ./$(DEPDIR)/epc532macha.Po \ ++ ./$(DEPDIR)/epdp11.Po ./$(DEPDIR)/epjelf.Po \ ++ ./$(DEPDIR)/epjlelf.Po ./$(DEPDIR)/eppcmacos.Po \ ++ ./$(DEPDIR)/epruelf.Po ./$(DEPDIR)/escore3_elf.Po \ ++ ./$(DEPDIR)/escore7_elf.Po ./$(DEPDIR)/esh.Po \ ++ ./$(DEPDIR)/eshelf.Po ./$(DEPDIR)/eshelf_fd.Po \ ++ ./$(DEPDIR)/eshelf_linux.Po ./$(DEPDIR)/eshelf_nbsd.Po \ ++ ./$(DEPDIR)/eshelf_nto.Po ./$(DEPDIR)/eshelf_uclinux.Po \ ++ ./$(DEPDIR)/eshelf_vxworks.Po ./$(DEPDIR)/eshl.Po \ ++ ./$(DEPDIR)/eshlelf.Po ./$(DEPDIR)/eshlelf_fd.Po \ ++ ./$(DEPDIR)/eshlelf_linux.Po ./$(DEPDIR)/eshlelf_nbsd.Po \ ++ ./$(DEPDIR)/eshlelf_nto.Po ./$(DEPDIR)/eshlelf_vxworks.Po \ ++ ./$(DEPDIR)/eshpe.Po ./$(DEPDIR)/etic30coff.Po \ ++ ./$(DEPDIR)/etic3xcoff.Po ./$(DEPDIR)/etic3xcoff_onchip.Po \ ++ ./$(DEPDIR)/etic4xcoff.Po ./$(DEPDIR)/etic54xcoff.Po \ ++ ./$(DEPDIR)/ev850.Po ./$(DEPDIR)/ev850_rh850.Po \ ++ ./$(DEPDIR)/evanilla.Po ./$(DEPDIR)/evaxnbsd.Po \ ++ ./$(DEPDIR)/exgateelf.Po ./$(DEPDIR)/ez80.Po \ ++ ./$(DEPDIR)/ez8001.Po ./$(DEPDIR)/ez8002.Po \ ++ ./$(DEPDIR)/ldbuildid.Po ./$(DEPDIR)/ldcref.Po \ ++ ./$(DEPDIR)/ldctor.Po ./$(DEPDIR)/ldelf.Po \ ++ ./$(DEPDIR)/ldelfgen.Po ./$(DEPDIR)/ldemul.Po \ ++ ./$(DEPDIR)/ldexp.Po ./$(DEPDIR)/ldfile.Po \ ++ ./$(DEPDIR)/ldgram.Po ./$(DEPDIR)/ldlang.Po \ ++ ./$(DEPDIR)/ldlex-wrapper.Po ./$(DEPDIR)/ldlex.Po \ ++ ./$(DEPDIR)/ldmain.Po ./$(DEPDIR)/ldmisc.Po \ ++ ./$(DEPDIR)/ldver.Po ./$(DEPDIR)/ldwrite.Po \ ++ ./$(DEPDIR)/lexsup.Po ./$(DEPDIR)/libdep_plugin.Plo \ ++ ./$(DEPDIR)/libldtestplug2_la-testplug2.Plo \ ++ ./$(DEPDIR)/libldtestplug3_la-testplug3.Plo \ ++ ./$(DEPDIR)/libldtestplug4_la-testplug4.Plo \ ++ ./$(DEPDIR)/libldtestplug_la-testplug.Plo ./$(DEPDIR)/mri.Po \ ++ ./$(DEPDIR)/pdb.Po ./$(DEPDIR)/pe-dll.Po \ ++ ./$(DEPDIR)/pep-dll.Po ./$(DEPDIR)/plugin.Po + am__mv = mv -f + COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +@@ -336,8 +498,8 @@ am__recursive_targets = \ + $(am__extra_recursive_targets) + AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope +-am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ +- $(LISP)config.in ++am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ ++ config.in + # Read a list of newline-separated strings from the standard input, + # and print each of them once, without duplicates. Input order is + # *not* preserved. +@@ -354,9 +516,6 @@ am__define_uniq_tagged_files = \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +-ETAGS = etags +-CTAGS = ctags +-CSCOPE = cscope + DEJATOOL = $(PACKAGE) + RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir + DIST_SUBDIRS = $(SUBDIRS) +@@ -369,21 +528,21 @@ AUTOCONF = @AUTOCONF@ + AUTOHEADER = @AUTOHEADER@ + AUTOMAKE = @AUTOMAKE@ + AWK = @AWK@ +-CATALOGS = @CATALOGS@ +-CATOBJEXT = @CATOBJEXT@ + CC = @CC@ + CCDEPMODE = @CCDEPMODE@ + CFLAGS = @CFLAGS@ + CPP = @CPP@ + CPPFLAGS = @CPPFLAGS@ ++CSCOPE = @CSCOPE@ ++CTAGS = @CTAGS@ + CXX = @CXX@ + CXXCPP = @CXXCPP@ + CXXDEPMODE = @CXXDEPMODE@ + CXXFLAGS = @CXXFLAGS@ + CYGPATH_W = @CYGPATH_W@ +-DATADIRNAME = @DATADIRNAME@ + DEFS = @DEFS@ + DEPDIR = @DEPDIR@ ++DLLTOOL = @DLLTOOL@ + DSYMUTIL = @DSYMUTIL@ + DUMPBIN = @DUMPBIN@ + ECHO_C = @ECHO_C@ +@@ -394,29 +553,27 @@ EMUL = @EMUL@ + EMULATION_LIBPATH = @EMULATION_LIBPATH@ + EMULATION_OFILES = @EMULATION_OFILES@ + EMUL_EXTRA_OFILES = @EMUL_EXTRA_OFILES@ ++ETAGS = @ETAGS@ + EXEEXT = @EXEEXT@ + FGREP = @FGREP@ +-GENCAT = @GENCAT@ ++FILECMD = @FILECMD@ ++GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ + GMSGFMT = @GMSGFMT@ ++GMSGFMT_015 = @GMSGFMT_015@ + GREP = @GREP@ + HDEFINES = @HDEFINES@ +-INCINTL = @INCINTL@ + INSTALL = @INSTALL@ + INSTALL_DATA = @INSTALL_DATA@ + INSTALL_PROGRAM = @INSTALL_PROGRAM@ + INSTALL_SCRIPT = @INSTALL_SCRIPT@ + INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +-INSTOBJEXT = @INSTOBJEXT@ + JANSSON_CFLAGS = @JANSSON_CFLAGS@ + JANSSON_LIBS = @JANSSON_LIBS@ +-LARGEFILE_CPPFLAGS = @LARGEFILE_CPPFLAGS@ + LD = @LD@ + LDFLAGS = @LDFLAGS@ + LEX = `if [ -f ../flex/flex ]; then echo ../flex/flex; else echo @LEX@; fi` + LEXLIB = @LEXLIB@ + LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +-LIBINTL = @LIBINTL@ +-LIBINTL_DEP = @LIBINTL_DEP@ + LIBOBJS = @LIBOBJS@ + LIBS = @LIBS@ + LIBTOOL = @LIBTOOL@ +@@ -432,16 +589,17 @@ LIB_PATH = @LIB_PATH@ + LIPO = @LIPO@ + LN_S = @LN_S@ + LTLIBOBJS = @LTLIBOBJS@ ++LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ + MAINT = @MAINT@ + MAKEINFO = @MAKEINFO@ ++MANIFEST_TOOL = @MANIFEST_TOOL@ + MKDIR_P = @MKDIR_P@ +-MKINSTALLDIRS = @MKINSTALLDIRS@ + MSGFMT = @MSGFMT@ + MSGMERGE = @MSGMERGE@ ++MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@ + NATIVE_LIB_DIRS = @NATIVE_LIB_DIRS@ + NM = @NM@ + NMEDIT = @NMEDIT@ +-NO_WERROR = @NO_WERROR@ + OBJDUMP = @OBJDUMP@ + OBJEXT = @OBJEXT@ + OTOOL = @OTOOL@ +@@ -457,7 +615,6 @@ PATH_SEPARATOR = @PATH_SEPARATOR@ + PKG_CONFIG = @PKG_CONFIG@ + PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ + PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +-POSUB = @POSUB@ + RANLIB = @RANLIB@ + SED = @SED@ + SET_MAKE = @SET_MAKE@ +@@ -473,18 +630,16 @@ TESTCTFLIB = @TESTCTFLIB@ + TESTSFRAMELIB = @TESTSFRAMELIB@ + USE_NLS = @USE_NLS@ + VERSION = @VERSION@ +-WARN_CFLAGS = @WARN_CFLAGS@ +-WARN_CFLAGS_FOR_BUILD = @WARN_CFLAGS_FOR_BUILD@ +-WARN_WRITE_STRINGS = @WARN_WRITE_STRINGS@ + XGETTEXT = @XGETTEXT@ ++XGETTEXT_015 = @XGETTEXT_015@ ++XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ + YACC = `if [ -f ../bison/bison ]; then echo ../bison/bison -y -L$(srcdir)/../bison/; else echo @YACC@; fi` + YFLAGS = -d +-ZSTD_CFLAGS = @ZSTD_CFLAGS@ +-ZSTD_LIBS = @ZSTD_LIBS@ + abs_builddir = @abs_builddir@ + abs_srcdir = @abs_srcdir@ + abs_top_builddir = @abs_top_builddir@ + abs_top_srcdir = @abs_top_srcdir@ ++ac_ct_AR = @ac_ct_AR@ + ac_ct_CC = @ac_ct_CC@ + ac_ct_CXX = @ac_ct_CXX@ + ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +@@ -502,7 +657,6 @@ build_vendor = @build_vendor@ + builddir = @builddir@ + datadir = @datadir@ + datarootdir = @datarootdir@ +-do_compare = @do_compare@ + docdir = @docdir@ + dvidir = @dvidir@ + elf_list_options = @elf_list_options@ +@@ -546,8 +700,6 @@ top_build_prefix = @top_build_prefix@ + top_builddir = @top_builddir@ + top_srcdir = @top_srcdir@ + use_sysroot = @use_sysroot@ +-zlibdir = @zlibdir@ +-zlibinc = @zlibinc@ + AUTOMAKE_OPTIONS = dejagnu no-texinfo.tex no-dist foreign info-in-builddir + ACLOCAL_AMFLAGS = -I .. -I ../config -I ../bfd + TEXINFO_TEX = ../texinfo/texinfo.tex +@@ -568,6 +720,8 @@ ELF_CLFAGS = -DELF_LIST_OPTIONS=@elf_list_options@ \ + -DELF_SHLIB_LIST_OPTIONS=@elf_shlib_list_options@ \ + -DELF_PLT_UNWIND_LIST_OPTIONS=@elf_plt_unwind_list_options@ + ++WARN_CFLAGS = @WARN_CFLAGS@ ++NO_WERROR = @NO_WERROR@ + AM_CFLAGS = $(WARN_CFLAGS) $(ELF_CLFAGS) $(JANSSON_CFLAGS) $(ZSTD_CFLAGS) + + # We put the scripts in the directory $(scriptdir)/ldscripts. +@@ -653,6 +807,7 @@ LIBIBERTY = ../libiberty/libiberty.a + + # These all start with e so 'make clean' can find them. + ALL_EMULATION_SOURCES = \ ++ eelf_i386_sb.c \ + eaix5ppc.c \ + eaix5rs6.c \ + eaixppc.c \ +@@ -1095,8 +1250,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ +- echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ +- cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ ++ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ ++ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ + esac; + + $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) +@@ -1124,6 +1279,55 @@ distclean-hdr: + -rm -f config.h stamp-h1 + po/Makefile.in: $(top_builddir)/config.status $(top_srcdir)/po/Make-in + cd $(top_builddir) && $(SHELL) ./config.status $@ ++install-binPROGRAMS: $(bin_PROGRAMS) ++ @$(NORMAL_INSTALL) ++ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ ++ if test -n "$$list"; then \ ++ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ ++ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ ++ fi; \ ++ for p in $$list; do echo "$$p $$p"; done | \ ++ sed 's/$(EXEEXT)$$//' | \ ++ while read p p1; do if test -f $$p \ ++ || test -f $$p1 \ ++ ; then echo "$$p"; echo "$$p"; else :; fi; \ ++ done | \ ++ sed -e 'p;s,.*/,,;n;h' \ ++ -e 's|.*|.|' \ ++ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ ++ sed 'N;N;N;s,\n, ,g' | \ ++ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ ++ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ ++ if ($$2 == $$4) files[d] = files[d] " " $$1; \ ++ else { print "f", $$3 "/" $$4, $$1; } } \ ++ END { for (d in files) print "f", d, files[d] }' | \ ++ while read type dir files; do \ ++ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ ++ test -z "$$files" || { \ ++ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ ++ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ ++ } \ ++ ; done ++ ++uninstall-binPROGRAMS: ++ @$(NORMAL_UNINSTALL) ++ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ ++ files=`for p in $$list; do echo "$$p"; done | \ ++ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ ++ -e 's/$$/$(EXEEXT)/' \ ++ `; \ ++ test -n "$$list" || exit 0; \ ++ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ ++ cd "$(DESTDIR)$(bindir)" && rm -f $$files ++ ++clean-binPROGRAMS: ++ @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ ++ echo " rm -f" $$list; \ ++ rm -f $$list || exit $$?; \ ++ test -n "$(EXEEXT)" || exit 0; \ ++ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ ++ echo " rm -f" $$list; \ ++ rm -f $$list + + install-bfdpluginLTLIBRARIES: $(bfdplugin_LTLIBRARIES) + @$(NORMAL_INSTALL) +@@ -1185,55 +1389,6 @@ libldtestplug3.la: $(libldtestplug3_la_OBJECTS) $(libldtestplug3_la_DEPENDENCIES + + libldtestplug4.la: $(libldtestplug4_la_OBJECTS) $(libldtestplug4_la_DEPENDENCIES) $(EXTRA_libldtestplug4_la_DEPENDENCIES) + $(AM_V_CCLD)$(libldtestplug4_la_LINK) $(libldtestplug4_la_OBJECTS) $(libldtestplug4_la_LIBADD) $(LIBS) +-install-binPROGRAMS: $(bin_PROGRAMS) +- @$(NORMAL_INSTALL) +- @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ +- if test -n "$$list"; then \ +- echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ +- $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ +- fi; \ +- for p in $$list; do echo "$$p $$p"; done | \ +- sed 's/$(EXEEXT)$$//' | \ +- while read p p1; do if test -f $$p \ +- || test -f $$p1 \ +- ; then echo "$$p"; echo "$$p"; else :; fi; \ +- done | \ +- sed -e 'p;s,.*/,,;n;h' \ +- -e 's|.*|.|' \ +- -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ +- sed 'N;N;N;s,\n, ,g' | \ +- $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ +- { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ +- if ($$2 == $$4) files[d] = files[d] " " $$1; \ +- else { print "f", $$3 "/" $$4, $$1; } } \ +- END { for (d in files) print "f", d, files[d] }' | \ +- while read type dir files; do \ +- if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ +- test -z "$$files" || { \ +- echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ +- $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ +- } \ +- ; done +- +-uninstall-binPROGRAMS: +- @$(NORMAL_UNINSTALL) +- @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ +- files=`for p in $$list; do echo "$$p"; done | \ +- sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ +- -e 's/$$/$(EXEEXT)/' \ +- `; \ +- test -n "$$list" || exit 0; \ +- echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ +- cd "$(DESTDIR)$(bindir)" && rm -f $$files +- +-clean-binPROGRAMS: +- @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ +- echo " rm -f" $$list; \ +- rm -f $$list || exit $$?; \ +- test -n "$(EXEEXT)" || exit 0; \ +- list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ +- echo " rm -f" $$list; \ +- rm -f $$list + ldgram.h: ldgram.c + @if test ! -f $@; then rm -f ldgram.c; else :; fi + @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) ldgram.c; else :; fi +@@ -1251,339 +1406,346 @@ mostlyclean-compile: + distclean-compile: + -rm -f *.tab.c + +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/deffilep.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64cloudabi.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64cloudabib.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64elf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64elf32.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64elf32b.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64elfb.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64fbsdb.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64haiku.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64linux32.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64linux32b.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64linuxb.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64pe.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaix5ppc.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaix5rs6.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaixppc.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaixrs6.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ealpha.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ealphavms.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earcelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earclinux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earclinux_nps.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earcv2elf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earcv2elfx.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earm_wince_pe.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_fuchsia.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_haiku.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_linux_eabi.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_linux_fdpiceabi.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_nacl.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_nbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_phoenix.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_vxworks.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_fuchsia.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_linux_eabi.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_linux_fdpiceabi.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_nacl.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_nbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmnto.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmpe.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr1.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr2.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr25.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr3.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr31.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr35.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr4.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr5.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr51.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr6.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrtiny.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega1.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega2.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega3.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega4.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega5.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega6.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega7.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecrisaout.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecriself.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecrislinux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecskyelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecskyelf_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ed10velf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ed30v_e.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ed30v_o.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ed30velf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_dlx.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_sparc.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_sparc_sol2.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_sparc_vxworks.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_spu.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_tic6x_be.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_tic6x_elf_be.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_tic6x_elf_le.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_tic6x_le.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_tic6x_linux_be.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_tic6x_linux_le.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_x86_64.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32am33lin.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32b4300.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32bfin.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32bfinfd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32bmip.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32bmipn32.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32briscv.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32briscv_ilp32.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32briscv_ilp32f.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32bsmip.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32btsmip.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32btsmip_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32btsmipn32.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32btsmipn32_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32cr16.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32crx.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ebmip.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ebmipvxworks.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32elmip.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32elmipvxworks.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32epiphany.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32epiphany_4x4.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32fr30.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32frv.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32frvfd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ft32.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ip2k.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32iq10.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32iq2000.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32l4300.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lm32.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lm32fd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lmip.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32loongarch.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppc.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppclinux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppcnto.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppcsim.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lr5900.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lr5900n32.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lriscv.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lriscv_ilp32.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lriscv_ilp32f.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lsmip.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmip.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmip_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmipn32.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmipn32_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32m32c.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mb_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mbel_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mcore.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mep.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32metag.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32microblaze.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32microblazeel.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mipswindiss.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32moxie.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mt.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32or1k.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32or1k_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppc.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppc_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppchaiku.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppclinux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppcnto.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppcsim.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppcvxworks.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppcwindiss.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32rl78.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32rx.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32rx_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32tilegx.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32tilegx_be.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32tilepro.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32vax.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32visium.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xstormy16.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xtensa.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32z80.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_aix.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64_vms.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_s390.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_sparc.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_sparc_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_sparc_sol2.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64alpha.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64alpha_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64alpha_nbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64bmip.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64bpf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64briscv.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64briscv_lp64.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64briscv_lp64f.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64btsmip.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64btsmip_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64hppa.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64loongarch.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lppc.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lppc_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv_lp64.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv_lp64f.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64ltsmip.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64ltsmip_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64mmix.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64ppc.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64ppc_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64rdos.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64tilegx.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64tilegx_be.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_be.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_haiku.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_ldso.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_sol2.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_vxworks.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_iamcu.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_mipsel_haiku.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_s390.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_cloudabi.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_haiku.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_sol2.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300elf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300elf_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300helf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300helf_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300hnelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300self.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300self_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300snelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300sxelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300sxelf_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300sxnelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ehppa64linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ehppaelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ehppalinux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ehppanbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ehppaobsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386aout.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386beos.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386bsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386go32.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386lynx.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386moss.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386msdos.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386nto.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386pe.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386pe_posix.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386pep.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em32relf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em32relf_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em32rlelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em32rlelf_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68hc11elf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68hc11elfb.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68hc12elf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68hc12elfb.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68kelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68kelfnbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em9s12zelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emcorepe.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emmo.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emn10200.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emn10300.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emoxiebox.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430X.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430elf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ends32belf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ends32belf16m.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ends32belf_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ends32elf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ends32elf16m.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ends32elf_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enios2elf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enios2linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ens32knbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epc532macha.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epdp11.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epjelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epjlelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eppcmacos.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epruelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/escore3_elf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/escore7_elf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/esh.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf_fd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf_nbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf_nto.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf_uclinux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf_vxworks.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshl.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshlelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshlelf_fd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshlelf_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshlelf_nbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshlelf_nto.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshlelf_vxworks.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshpe.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/etic30coff.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/etic3xcoff.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/etic3xcoff_onchip.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/etic4xcoff.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/etic54xcoff.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ev850.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ev850_rh850.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evanilla.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evaxnbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exgateelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ez80.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ez8001.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ez8002.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldbuildid.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldcref.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldctor.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldelfgen.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldemul.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldexp.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldfile.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldgram.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldlang.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldlex-wrapper.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldlex.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldmain.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldmisc.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldver.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldwrite.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lexsup.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdep_plugin.Plo@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libldtestplug2_la-testplug2.Plo@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libldtestplug3_la-testplug3.Plo@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libldtestplug4_la-testplug4.Plo@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libldtestplug_la-testplug.Plo@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mri.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdb.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-dll.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pep-dll.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/deffilep.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64cloudabi.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64cloudabib.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64elf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64elf32.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64elf32b.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64elfb.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64fbsdb.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64haiku.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64linux32.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64linux32b.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64linuxb.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64pe.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaix5ppc.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaix5rs6.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaixppc.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaixrs6.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ealpha.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ealphavms.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earcelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earclinux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earclinux_nps.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earcv2elf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earcv2elfx.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earm_wince_pe.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_fuchsia.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_haiku.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_linux_eabi.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_linux_fdpiceabi.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_nacl.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_nbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_phoenix.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_vxworks.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_fuchsia.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_linux_eabi.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_linux_fdpiceabi.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_nacl.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_nbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmnto.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmpe.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr1.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr2.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr25.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr3.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr31.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr35.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr4.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr5.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr51.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr6.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrtiny.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega1.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega2.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega3.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega4.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega5.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega6.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega7.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecrisaout.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecriself.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecrislinux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecskyelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecskyelf_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ed10velf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ed30v_e.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ed30v_o.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ed30velf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_dlx.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_sparc.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_sparc_sol2.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_sparc_vxworks.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_spu.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_tic6x_be.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_tic6x_elf_be.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_tic6x_elf_le.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_tic6x_le.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_tic6x_linux_be.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_tic6x_linux_le.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_x86_64.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32am33lin.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32b4300.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32bfin.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32bfinfd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32bmip.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32bmipn32.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32briscv.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32briscv_ilp32.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32briscv_ilp32f.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32bsmip.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32btsmip.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32btsmip_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32btsmipn32.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32btsmipn32_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32cr16.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32crx.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ebmip.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ebmipvxworks.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32elmip.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32elmipvxworks.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32epiphany.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32epiphany_4x4.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32fr30.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32frv.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32frvfd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ft32.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ip2k.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32iq10.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32iq2000.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32l4300.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lm32.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lm32fd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lmip.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32loongarch.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppc.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppclinux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppcnto.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppcsim.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lr5900.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lr5900n32.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lriscv.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lriscv_ilp32.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lriscv_ilp32f.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lsmip.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmip.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmip_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmipn32.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmipn32_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32m32c.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mb_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mbel_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mcore.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mep.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32metag.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32microblaze.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32microblazeel.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mipswindiss.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32moxie.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mt.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32or1k.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32or1k_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppc.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppc_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppchaiku.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppclinux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppcnto.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppcsim.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppcvxworks.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppcwindiss.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32rl78.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32rx.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32rx_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32tilegx.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32tilegx_be.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32tilepro.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32vax.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32visium.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xstormy16.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xtensa.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32z80.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_aix.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64_vms.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_s390.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_sparc.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_sparc_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_sparc_sol2.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64alpha.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64alpha_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64alpha_nbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64bmip.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64bpf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64briscv.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64briscv_lp64.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64briscv_lp64f.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64btsmip.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64btsmip_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64hppa.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64loongarch.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lppc.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lppc_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv_lp64.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv_lp64f.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64ltsmip.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64ltsmip_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64mmix.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64ppc.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64ppc_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64rdos.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64tilegx.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64tilegx_be.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_be.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_haiku.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_ldso.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_sb.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_sol2.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_vxworks.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_iamcu.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_mipsel_haiku.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_s390.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_cloudabi.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_haiku.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_sol2.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300elf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300elf_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300helf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300helf_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300hnelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300self.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300self_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300snelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300sxelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300sxelf_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300sxnelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ehppa64linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ehppaelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ehppalinux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ehppanbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ehppaobsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386aout.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386beos.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386bsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386go32.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386lynx.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386moss.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386msdos.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386nto.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386pe.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386pe_posix.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386pep.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em32relf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em32relf_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em32rlelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em32rlelf_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68hc11elf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68hc11elfb.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68hc12elf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68hc12elfb.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68kelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68kelfnbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em9s12zelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emcorepe.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emmo.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emn10200.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emn10300.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emoxiebox.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430X.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430elf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ends32belf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ends32belf16m.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ends32belf_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ends32elf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ends32elf16m.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ends32elf_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enios2elf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enios2linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ens32knbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epc532macha.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epdp11.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epjelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epjlelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eppcmacos.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epruelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/escore3_elf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/escore7_elf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/esh.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf_fd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf_nbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf_nto.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf_uclinux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf_vxworks.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshl.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshlelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshlelf_fd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshlelf_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshlelf_nbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshlelf_nto.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshlelf_vxworks.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshpe.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/etic30coff.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/etic3xcoff.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/etic3xcoff_onchip.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/etic4xcoff.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/etic54xcoff.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ev850.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ev850_rh850.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evanilla.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evaxnbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exgateelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ez80.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ez8001.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ez8002.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldbuildid.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldcref.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldctor.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldelfgen.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldemul.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldexp.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldfile.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldgram.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldlang.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldlex-wrapper.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldlex.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldmain.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldmisc.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldver.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldwrite.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lexsup.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdep_plugin.Plo@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libldtestplug2_la-testplug2.Plo@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libldtestplug3_la-testplug3.Plo@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libldtestplug4_la-testplug4.Plo@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libldtestplug_la-testplug.Plo@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mri.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdb.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-dll.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pep-dll.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin.Po@am__quote@ # am--include-marker ++ ++$(am__depfiles_remade): ++ @$(MKDIR_P) $(@D) ++ @echo '# dummy' >$@-t && $(am__mv) $@-t $@ ++ ++am--depfiles: $(am__depfiles_remade) + + .c.o: + @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@@ -1936,7 +2098,7 @@ site.exp: Makefile $(EXTRA_DEJAGNU_SITE_CONFIG) + @echo '# Do not edit here. If you wish to override these values' >>site.tmp + @echo '# edit the last section' >>site.tmp + @echo 'set srcdir "$(srcdir)"' >>site.tmp +- @echo "set objdir `pwd`" >>site.tmp ++ @echo "set objdir \"`pwd`\"" >>site.tmp + @echo 'set build_alias "$(build_alias)"' >>site.tmp + @echo 'set build_triplet $(build_triplet)' >>site.tmp + @echo 'set host_alias "$(host_alias)"' >>site.tmp +@@ -1966,16 +2128,17 @@ check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU + check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-recursive +-all-am: Makefile $(INFO_DEPS) $(LTLIBRARIES) $(PROGRAMS) $(MANS) \ ++all-am: Makefile $(INFO_DEPS) $(PROGRAMS) $(LTLIBRARIES) $(MANS) \ + config.h + installdirs: installdirs-recursive + installdirs-am: +- for dir in "$(DESTDIR)$(bfdplugindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)"; do \ ++ for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bfdplugindir)" "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done + install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-recursive +-install-exec: install-exec-recursive ++install-exec: $(BUILT_SOURCES) ++ $(MAKE) $(AM_MAKEFLAGS) install-exec-recursive + install-data: install-data-recursive + uninstall: uninstall-recursive + +@@ -2022,7 +2185,340 @@ clean-am: clean-aminfo clean-bfdpluginLTLIBRARIES clean-binPROGRAMS \ + + distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) +- -rm -rf ./$(DEPDIR) ++ -rm -f ./$(DEPDIR)/deffilep.Po ++ -rm -f ./$(DEPDIR)/eaarch64cloudabi.Po ++ -rm -f ./$(DEPDIR)/eaarch64cloudabib.Po ++ -rm -f ./$(DEPDIR)/eaarch64elf.Po ++ -rm -f ./$(DEPDIR)/eaarch64elf32.Po ++ -rm -f ./$(DEPDIR)/eaarch64elf32b.Po ++ -rm -f ./$(DEPDIR)/eaarch64elfb.Po ++ -rm -f ./$(DEPDIR)/eaarch64fbsd.Po ++ -rm -f ./$(DEPDIR)/eaarch64fbsdb.Po ++ -rm -f ./$(DEPDIR)/eaarch64haiku.Po ++ -rm -f ./$(DEPDIR)/eaarch64linux.Po ++ -rm -f ./$(DEPDIR)/eaarch64linux32.Po ++ -rm -f ./$(DEPDIR)/eaarch64linux32b.Po ++ -rm -f ./$(DEPDIR)/eaarch64linuxb.Po ++ -rm -f ./$(DEPDIR)/eaarch64pe.Po ++ -rm -f ./$(DEPDIR)/eaix5ppc.Po ++ -rm -f ./$(DEPDIR)/eaix5rs6.Po ++ -rm -f ./$(DEPDIR)/eaixppc.Po ++ -rm -f ./$(DEPDIR)/eaixrs6.Po ++ -rm -f ./$(DEPDIR)/ealpha.Po ++ -rm -f ./$(DEPDIR)/ealphavms.Po ++ -rm -f ./$(DEPDIR)/earcelf.Po ++ -rm -f ./$(DEPDIR)/earclinux.Po ++ -rm -f ./$(DEPDIR)/earclinux_nps.Po ++ -rm -f ./$(DEPDIR)/earcv2elf.Po ++ -rm -f ./$(DEPDIR)/earcv2elfx.Po ++ -rm -f ./$(DEPDIR)/earm_wince_pe.Po ++ -rm -f ./$(DEPDIR)/earmelf.Po ++ -rm -f ./$(DEPDIR)/earmelf_fbsd.Po ++ -rm -f ./$(DEPDIR)/earmelf_fuchsia.Po ++ -rm -f ./$(DEPDIR)/earmelf_haiku.Po ++ -rm -f ./$(DEPDIR)/earmelf_linux.Po ++ -rm -f ./$(DEPDIR)/earmelf_linux_eabi.Po ++ -rm -f ./$(DEPDIR)/earmelf_linux_fdpiceabi.Po ++ -rm -f ./$(DEPDIR)/earmelf_nacl.Po ++ -rm -f ./$(DEPDIR)/earmelf_nbsd.Po ++ -rm -f ./$(DEPDIR)/earmelf_phoenix.Po ++ -rm -f ./$(DEPDIR)/earmelf_vxworks.Po ++ -rm -f ./$(DEPDIR)/earmelfb.Po ++ -rm -f ./$(DEPDIR)/earmelfb_fbsd.Po ++ -rm -f ./$(DEPDIR)/earmelfb_fuchsia.Po ++ -rm -f ./$(DEPDIR)/earmelfb_linux.Po ++ -rm -f ./$(DEPDIR)/earmelfb_linux_eabi.Po ++ -rm -f ./$(DEPDIR)/earmelfb_linux_fdpiceabi.Po ++ -rm -f ./$(DEPDIR)/earmelfb_nacl.Po ++ -rm -f ./$(DEPDIR)/earmelfb_nbsd.Po ++ -rm -f ./$(DEPDIR)/earmnto.Po ++ -rm -f ./$(DEPDIR)/earmpe.Po ++ -rm -f ./$(DEPDIR)/eavr1.Po ++ -rm -f ./$(DEPDIR)/eavr2.Po ++ -rm -f ./$(DEPDIR)/eavr25.Po ++ -rm -f ./$(DEPDIR)/eavr3.Po ++ -rm -f ./$(DEPDIR)/eavr31.Po ++ -rm -f ./$(DEPDIR)/eavr35.Po ++ -rm -f ./$(DEPDIR)/eavr4.Po ++ -rm -f ./$(DEPDIR)/eavr5.Po ++ -rm -f ./$(DEPDIR)/eavr51.Po ++ -rm -f ./$(DEPDIR)/eavr6.Po ++ -rm -f ./$(DEPDIR)/eavrtiny.Po ++ -rm -f ./$(DEPDIR)/eavrxmega1.Po ++ -rm -f ./$(DEPDIR)/eavrxmega2.Po ++ -rm -f ./$(DEPDIR)/eavrxmega3.Po ++ -rm -f ./$(DEPDIR)/eavrxmega4.Po ++ -rm -f ./$(DEPDIR)/eavrxmega5.Po ++ -rm -f ./$(DEPDIR)/eavrxmega6.Po ++ -rm -f ./$(DEPDIR)/eavrxmega7.Po ++ -rm -f ./$(DEPDIR)/ecrisaout.Po ++ -rm -f ./$(DEPDIR)/ecriself.Po ++ -rm -f ./$(DEPDIR)/ecrislinux.Po ++ -rm -f ./$(DEPDIR)/ecskyelf.Po ++ -rm -f ./$(DEPDIR)/ecskyelf_linux.Po ++ -rm -f ./$(DEPDIR)/ed10velf.Po ++ -rm -f ./$(DEPDIR)/ed30v_e.Po ++ -rm -f ./$(DEPDIR)/ed30v_o.Po ++ -rm -f ./$(DEPDIR)/ed30velf.Po ++ -rm -f ./$(DEPDIR)/eelf32_dlx.Po ++ -rm -f ./$(DEPDIR)/eelf32_sparc.Po ++ -rm -f ./$(DEPDIR)/eelf32_sparc_sol2.Po ++ -rm -f ./$(DEPDIR)/eelf32_sparc_vxworks.Po ++ -rm -f ./$(DEPDIR)/eelf32_spu.Po ++ -rm -f ./$(DEPDIR)/eelf32_tic6x_be.Po ++ -rm -f ./$(DEPDIR)/eelf32_tic6x_elf_be.Po ++ -rm -f ./$(DEPDIR)/eelf32_tic6x_elf_le.Po ++ -rm -f ./$(DEPDIR)/eelf32_tic6x_le.Po ++ -rm -f ./$(DEPDIR)/eelf32_tic6x_linux_be.Po ++ -rm -f ./$(DEPDIR)/eelf32_tic6x_linux_le.Po ++ -rm -f ./$(DEPDIR)/eelf32_x86_64.Po ++ -rm -f ./$(DEPDIR)/eelf32am33lin.Po ++ -rm -f ./$(DEPDIR)/eelf32b4300.Po ++ -rm -f ./$(DEPDIR)/eelf32bfin.Po ++ -rm -f ./$(DEPDIR)/eelf32bfinfd.Po ++ -rm -f ./$(DEPDIR)/eelf32bmip.Po ++ -rm -f ./$(DEPDIR)/eelf32bmipn32.Po ++ -rm -f ./$(DEPDIR)/eelf32briscv.Po ++ -rm -f ./$(DEPDIR)/eelf32briscv_ilp32.Po ++ -rm -f ./$(DEPDIR)/eelf32briscv_ilp32f.Po ++ -rm -f ./$(DEPDIR)/eelf32bsmip.Po ++ -rm -f ./$(DEPDIR)/eelf32btsmip.Po ++ -rm -f ./$(DEPDIR)/eelf32btsmip_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf32btsmipn32.Po ++ -rm -f ./$(DEPDIR)/eelf32btsmipn32_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf32cr16.Po ++ -rm -f ./$(DEPDIR)/eelf32crx.Po ++ -rm -f ./$(DEPDIR)/eelf32ebmip.Po ++ -rm -f ./$(DEPDIR)/eelf32ebmipvxworks.Po ++ -rm -f ./$(DEPDIR)/eelf32elmip.Po ++ -rm -f ./$(DEPDIR)/eelf32elmipvxworks.Po ++ -rm -f ./$(DEPDIR)/eelf32epiphany.Po ++ -rm -f ./$(DEPDIR)/eelf32epiphany_4x4.Po ++ -rm -f ./$(DEPDIR)/eelf32fr30.Po ++ -rm -f ./$(DEPDIR)/eelf32frv.Po ++ -rm -f ./$(DEPDIR)/eelf32frvfd.Po ++ -rm -f ./$(DEPDIR)/eelf32ft32.Po ++ -rm -f ./$(DEPDIR)/eelf32ip2k.Po ++ -rm -f ./$(DEPDIR)/eelf32iq10.Po ++ -rm -f ./$(DEPDIR)/eelf32iq2000.Po ++ -rm -f ./$(DEPDIR)/eelf32l4300.Po ++ -rm -f ./$(DEPDIR)/eelf32lm32.Po ++ -rm -f ./$(DEPDIR)/eelf32lm32fd.Po ++ -rm -f ./$(DEPDIR)/eelf32lmip.Po ++ -rm -f ./$(DEPDIR)/eelf32loongarch.Po ++ -rm -f ./$(DEPDIR)/eelf32lppc.Po ++ -rm -f ./$(DEPDIR)/eelf32lppclinux.Po ++ -rm -f ./$(DEPDIR)/eelf32lppcnto.Po ++ -rm -f ./$(DEPDIR)/eelf32lppcsim.Po ++ -rm -f ./$(DEPDIR)/eelf32lr5900.Po ++ -rm -f ./$(DEPDIR)/eelf32lr5900n32.Po ++ -rm -f ./$(DEPDIR)/eelf32lriscv.Po ++ -rm -f ./$(DEPDIR)/eelf32lriscv_ilp32.Po ++ -rm -f ./$(DEPDIR)/eelf32lriscv_ilp32f.Po ++ -rm -f ./$(DEPDIR)/eelf32lsmip.Po ++ -rm -f ./$(DEPDIR)/eelf32ltsmip.Po ++ -rm -f ./$(DEPDIR)/eelf32ltsmip_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf32ltsmipn32.Po ++ -rm -f ./$(DEPDIR)/eelf32ltsmipn32_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf32m32c.Po ++ -rm -f ./$(DEPDIR)/eelf32mb_linux.Po ++ -rm -f ./$(DEPDIR)/eelf32mbel_linux.Po ++ -rm -f ./$(DEPDIR)/eelf32mcore.Po ++ -rm -f ./$(DEPDIR)/eelf32mep.Po ++ -rm -f ./$(DEPDIR)/eelf32metag.Po ++ -rm -f ./$(DEPDIR)/eelf32microblaze.Po ++ -rm -f ./$(DEPDIR)/eelf32microblazeel.Po ++ -rm -f ./$(DEPDIR)/eelf32mipswindiss.Po ++ -rm -f ./$(DEPDIR)/eelf32moxie.Po ++ -rm -f ./$(DEPDIR)/eelf32mt.Po ++ -rm -f ./$(DEPDIR)/eelf32or1k.Po ++ -rm -f ./$(DEPDIR)/eelf32or1k_linux.Po ++ -rm -f ./$(DEPDIR)/eelf32ppc.Po ++ -rm -f ./$(DEPDIR)/eelf32ppc_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf32ppchaiku.Po ++ -rm -f ./$(DEPDIR)/eelf32ppclinux.Po ++ -rm -f ./$(DEPDIR)/eelf32ppcnto.Po ++ -rm -f ./$(DEPDIR)/eelf32ppcsim.Po ++ -rm -f ./$(DEPDIR)/eelf32ppcvxworks.Po ++ -rm -f ./$(DEPDIR)/eelf32ppcwindiss.Po ++ -rm -f ./$(DEPDIR)/eelf32rl78.Po ++ -rm -f ./$(DEPDIR)/eelf32rx.Po ++ -rm -f ./$(DEPDIR)/eelf32rx_linux.Po ++ -rm -f ./$(DEPDIR)/eelf32tilegx.Po ++ -rm -f ./$(DEPDIR)/eelf32tilegx_be.Po ++ -rm -f ./$(DEPDIR)/eelf32tilepro.Po ++ -rm -f ./$(DEPDIR)/eelf32vax.Po ++ -rm -f ./$(DEPDIR)/eelf32visium.Po ++ -rm -f ./$(DEPDIR)/eelf32xstormy16.Po ++ -rm -f ./$(DEPDIR)/eelf32xtensa.Po ++ -rm -f ./$(DEPDIR)/eelf32z80.Po ++ -rm -f ./$(DEPDIR)/eelf64_aix.Po ++ -rm -f ./$(DEPDIR)/eelf64_ia64.Po ++ -rm -f ./$(DEPDIR)/eelf64_ia64_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64_ia64_vms.Po ++ -rm -f ./$(DEPDIR)/eelf64_s390.Po ++ -rm -f ./$(DEPDIR)/eelf64_sparc.Po ++ -rm -f ./$(DEPDIR)/eelf64_sparc_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64_sparc_sol2.Po ++ -rm -f ./$(DEPDIR)/eelf64alpha.Po ++ -rm -f ./$(DEPDIR)/eelf64alpha_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64alpha_nbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64bmip.Po ++ -rm -f ./$(DEPDIR)/eelf64bpf.Po ++ -rm -f ./$(DEPDIR)/eelf64briscv.Po ++ -rm -f ./$(DEPDIR)/eelf64briscv_lp64.Po ++ -rm -f ./$(DEPDIR)/eelf64briscv_lp64f.Po ++ -rm -f ./$(DEPDIR)/eelf64btsmip.Po ++ -rm -f ./$(DEPDIR)/eelf64btsmip_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64hppa.Po ++ -rm -f ./$(DEPDIR)/eelf64loongarch.Po ++ -rm -f ./$(DEPDIR)/eelf64lppc.Po ++ -rm -f ./$(DEPDIR)/eelf64lppc_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64lriscv.Po ++ -rm -f ./$(DEPDIR)/eelf64lriscv_lp64.Po ++ -rm -f ./$(DEPDIR)/eelf64lriscv_lp64f.Po ++ -rm -f ./$(DEPDIR)/eelf64ltsmip.Po ++ -rm -f ./$(DEPDIR)/eelf64ltsmip_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64mmix.Po ++ -rm -f ./$(DEPDIR)/eelf64ppc.Po ++ -rm -f ./$(DEPDIR)/eelf64ppc_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64rdos.Po ++ -rm -f ./$(DEPDIR)/eelf64tilegx.Po ++ -rm -f ./$(DEPDIR)/eelf64tilegx_be.Po ++ -rm -f ./$(DEPDIR)/eelf_i386.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_be.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_haiku.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_ldso.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_sb.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_sol2.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_vxworks.Po ++ -rm -f ./$(DEPDIR)/eelf_iamcu.Po ++ -rm -f ./$(DEPDIR)/eelf_mipsel_haiku.Po ++ -rm -f ./$(DEPDIR)/eelf_s390.Po ++ -rm -f ./$(DEPDIR)/eelf_x86_64.Po ++ -rm -f ./$(DEPDIR)/eelf_x86_64_cloudabi.Po ++ -rm -f ./$(DEPDIR)/eelf_x86_64_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf_x86_64_haiku.Po ++ -rm -f ./$(DEPDIR)/eelf_x86_64_sol2.Po ++ -rm -f ./$(DEPDIR)/eh8300elf.Po ++ -rm -f ./$(DEPDIR)/eh8300elf_linux.Po ++ -rm -f ./$(DEPDIR)/eh8300helf.Po ++ -rm -f ./$(DEPDIR)/eh8300helf_linux.Po ++ -rm -f ./$(DEPDIR)/eh8300hnelf.Po ++ -rm -f ./$(DEPDIR)/eh8300self.Po ++ -rm -f ./$(DEPDIR)/eh8300self_linux.Po ++ -rm -f ./$(DEPDIR)/eh8300snelf.Po ++ -rm -f ./$(DEPDIR)/eh8300sxelf.Po ++ -rm -f ./$(DEPDIR)/eh8300sxelf_linux.Po ++ -rm -f ./$(DEPDIR)/eh8300sxnelf.Po ++ -rm -f ./$(DEPDIR)/ehppa64linux.Po ++ -rm -f ./$(DEPDIR)/ehppaelf.Po ++ -rm -f ./$(DEPDIR)/ehppalinux.Po ++ -rm -f ./$(DEPDIR)/ehppanbsd.Po ++ -rm -f ./$(DEPDIR)/ehppaobsd.Po ++ -rm -f ./$(DEPDIR)/ei386aout.Po ++ -rm -f ./$(DEPDIR)/ei386beos.Po ++ -rm -f ./$(DEPDIR)/ei386bsd.Po ++ -rm -f ./$(DEPDIR)/ei386go32.Po ++ -rm -f ./$(DEPDIR)/ei386lynx.Po ++ -rm -f ./$(DEPDIR)/ei386moss.Po ++ -rm -f ./$(DEPDIR)/ei386msdos.Po ++ -rm -f ./$(DEPDIR)/ei386nto.Po ++ -rm -f ./$(DEPDIR)/ei386pe.Po ++ -rm -f ./$(DEPDIR)/ei386pe_posix.Po ++ -rm -f ./$(DEPDIR)/ei386pep.Po ++ -rm -f ./$(DEPDIR)/em32relf.Po ++ -rm -f ./$(DEPDIR)/em32relf_linux.Po ++ -rm -f ./$(DEPDIR)/em32rlelf.Po ++ -rm -f ./$(DEPDIR)/em32rlelf_linux.Po ++ -rm -f ./$(DEPDIR)/em68hc11elf.Po ++ -rm -f ./$(DEPDIR)/em68hc11elfb.Po ++ -rm -f ./$(DEPDIR)/em68hc12elf.Po ++ -rm -f ./$(DEPDIR)/em68hc12elfb.Po ++ -rm -f ./$(DEPDIR)/em68kelf.Po ++ -rm -f ./$(DEPDIR)/em68kelfnbsd.Po ++ -rm -f ./$(DEPDIR)/em9s12zelf.Po ++ -rm -f ./$(DEPDIR)/emcorepe.Po ++ -rm -f ./$(DEPDIR)/emmo.Po ++ -rm -f ./$(DEPDIR)/emn10200.Po ++ -rm -f ./$(DEPDIR)/emn10300.Po ++ -rm -f ./$(DEPDIR)/emoxiebox.Po ++ -rm -f ./$(DEPDIR)/emsp430X.Po ++ -rm -f ./$(DEPDIR)/emsp430elf.Po ++ -rm -f ./$(DEPDIR)/ends32belf.Po ++ -rm -f ./$(DEPDIR)/ends32belf16m.Po ++ -rm -f ./$(DEPDIR)/ends32belf_linux.Po ++ -rm -f ./$(DEPDIR)/ends32elf.Po ++ -rm -f ./$(DEPDIR)/ends32elf16m.Po ++ -rm -f ./$(DEPDIR)/ends32elf_linux.Po ++ -rm -f ./$(DEPDIR)/enios2elf.Po ++ -rm -f ./$(DEPDIR)/enios2linux.Po ++ -rm -f ./$(DEPDIR)/ens32knbsd.Po ++ -rm -f ./$(DEPDIR)/epc532macha.Po ++ -rm -f ./$(DEPDIR)/epdp11.Po ++ -rm -f ./$(DEPDIR)/epjelf.Po ++ -rm -f ./$(DEPDIR)/epjlelf.Po ++ -rm -f ./$(DEPDIR)/eppcmacos.Po ++ -rm -f ./$(DEPDIR)/epruelf.Po ++ -rm -f ./$(DEPDIR)/escore3_elf.Po ++ -rm -f ./$(DEPDIR)/escore7_elf.Po ++ -rm -f ./$(DEPDIR)/esh.Po ++ -rm -f ./$(DEPDIR)/eshelf.Po ++ -rm -f ./$(DEPDIR)/eshelf_fd.Po ++ -rm -f ./$(DEPDIR)/eshelf_linux.Po ++ -rm -f ./$(DEPDIR)/eshelf_nbsd.Po ++ -rm -f ./$(DEPDIR)/eshelf_nto.Po ++ -rm -f ./$(DEPDIR)/eshelf_uclinux.Po ++ -rm -f ./$(DEPDIR)/eshelf_vxworks.Po ++ -rm -f ./$(DEPDIR)/eshl.Po ++ -rm -f ./$(DEPDIR)/eshlelf.Po ++ -rm -f ./$(DEPDIR)/eshlelf_fd.Po ++ -rm -f ./$(DEPDIR)/eshlelf_linux.Po ++ -rm -f ./$(DEPDIR)/eshlelf_nbsd.Po ++ -rm -f ./$(DEPDIR)/eshlelf_nto.Po ++ -rm -f ./$(DEPDIR)/eshlelf_vxworks.Po ++ -rm -f ./$(DEPDIR)/eshpe.Po ++ -rm -f ./$(DEPDIR)/etic30coff.Po ++ -rm -f ./$(DEPDIR)/etic3xcoff.Po ++ -rm -f ./$(DEPDIR)/etic3xcoff_onchip.Po ++ -rm -f ./$(DEPDIR)/etic4xcoff.Po ++ -rm -f ./$(DEPDIR)/etic54xcoff.Po ++ -rm -f ./$(DEPDIR)/ev850.Po ++ -rm -f ./$(DEPDIR)/ev850_rh850.Po ++ -rm -f ./$(DEPDIR)/evanilla.Po ++ -rm -f ./$(DEPDIR)/evaxnbsd.Po ++ -rm -f ./$(DEPDIR)/exgateelf.Po ++ -rm -f ./$(DEPDIR)/ez80.Po ++ -rm -f ./$(DEPDIR)/ez8001.Po ++ -rm -f ./$(DEPDIR)/ez8002.Po ++ -rm -f ./$(DEPDIR)/ldbuildid.Po ++ -rm -f ./$(DEPDIR)/ldcref.Po ++ -rm -f ./$(DEPDIR)/ldctor.Po ++ -rm -f ./$(DEPDIR)/ldelf.Po ++ -rm -f ./$(DEPDIR)/ldelfgen.Po ++ -rm -f ./$(DEPDIR)/ldemul.Po ++ -rm -f ./$(DEPDIR)/ldexp.Po ++ -rm -f ./$(DEPDIR)/ldfile.Po ++ -rm -f ./$(DEPDIR)/ldgram.Po ++ -rm -f ./$(DEPDIR)/ldlang.Po ++ -rm -f ./$(DEPDIR)/ldlex-wrapper.Po ++ -rm -f ./$(DEPDIR)/ldlex.Po ++ -rm -f ./$(DEPDIR)/ldmain.Po ++ -rm -f ./$(DEPDIR)/ldmisc.Po ++ -rm -f ./$(DEPDIR)/ldver.Po ++ -rm -f ./$(DEPDIR)/ldwrite.Po ++ -rm -f ./$(DEPDIR)/lexsup.Po ++ -rm -f ./$(DEPDIR)/libdep_plugin.Plo ++ -rm -f ./$(DEPDIR)/libldtestplug2_la-testplug2.Plo ++ -rm -f ./$(DEPDIR)/libldtestplug3_la-testplug3.Plo ++ -rm -f ./$(DEPDIR)/libldtestplug4_la-testplug4.Plo ++ -rm -f ./$(DEPDIR)/libldtestplug_la-testplug.Plo ++ -rm -f ./$(DEPDIR)/mri.Po ++ -rm -f ./$(DEPDIR)/pdb.Po ++ -rm -f ./$(DEPDIR)/pe-dll.Po ++ -rm -f ./$(DEPDIR)/pep-dll.Po ++ -rm -f ./$(DEPDIR)/plugin.Po + -rm -f Makefile + distclean-am: clean-am distclean-DEJAGNU distclean-compile \ + distclean-generic distclean-hdr distclean-libtool \ +@@ -2163,7 +2659,340 @@ installcheck-am: + maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache +- -rm -rf ./$(DEPDIR) ++ -rm -f ./$(DEPDIR)/deffilep.Po ++ -rm -f ./$(DEPDIR)/eaarch64cloudabi.Po ++ -rm -f ./$(DEPDIR)/eaarch64cloudabib.Po ++ -rm -f ./$(DEPDIR)/eaarch64elf.Po ++ -rm -f ./$(DEPDIR)/eaarch64elf32.Po ++ -rm -f ./$(DEPDIR)/eaarch64elf32b.Po ++ -rm -f ./$(DEPDIR)/eaarch64elfb.Po ++ -rm -f ./$(DEPDIR)/eaarch64fbsd.Po ++ -rm -f ./$(DEPDIR)/eaarch64fbsdb.Po ++ -rm -f ./$(DEPDIR)/eaarch64haiku.Po ++ -rm -f ./$(DEPDIR)/eaarch64linux.Po ++ -rm -f ./$(DEPDIR)/eaarch64linux32.Po ++ -rm -f ./$(DEPDIR)/eaarch64linux32b.Po ++ -rm -f ./$(DEPDIR)/eaarch64linuxb.Po ++ -rm -f ./$(DEPDIR)/eaarch64pe.Po ++ -rm -f ./$(DEPDIR)/eaix5ppc.Po ++ -rm -f ./$(DEPDIR)/eaix5rs6.Po ++ -rm -f ./$(DEPDIR)/eaixppc.Po ++ -rm -f ./$(DEPDIR)/eaixrs6.Po ++ -rm -f ./$(DEPDIR)/ealpha.Po ++ -rm -f ./$(DEPDIR)/ealphavms.Po ++ -rm -f ./$(DEPDIR)/earcelf.Po ++ -rm -f ./$(DEPDIR)/earclinux.Po ++ -rm -f ./$(DEPDIR)/earclinux_nps.Po ++ -rm -f ./$(DEPDIR)/earcv2elf.Po ++ -rm -f ./$(DEPDIR)/earcv2elfx.Po ++ -rm -f ./$(DEPDIR)/earm_wince_pe.Po ++ -rm -f ./$(DEPDIR)/earmelf.Po ++ -rm -f ./$(DEPDIR)/earmelf_fbsd.Po ++ -rm -f ./$(DEPDIR)/earmelf_fuchsia.Po ++ -rm -f ./$(DEPDIR)/earmelf_haiku.Po ++ -rm -f ./$(DEPDIR)/earmelf_linux.Po ++ -rm -f ./$(DEPDIR)/earmelf_linux_eabi.Po ++ -rm -f ./$(DEPDIR)/earmelf_linux_fdpiceabi.Po ++ -rm -f ./$(DEPDIR)/earmelf_nacl.Po ++ -rm -f ./$(DEPDIR)/earmelf_nbsd.Po ++ -rm -f ./$(DEPDIR)/earmelf_phoenix.Po ++ -rm -f ./$(DEPDIR)/earmelf_vxworks.Po ++ -rm -f ./$(DEPDIR)/earmelfb.Po ++ -rm -f ./$(DEPDIR)/earmelfb_fbsd.Po ++ -rm -f ./$(DEPDIR)/earmelfb_fuchsia.Po ++ -rm -f ./$(DEPDIR)/earmelfb_linux.Po ++ -rm -f ./$(DEPDIR)/earmelfb_linux_eabi.Po ++ -rm -f ./$(DEPDIR)/earmelfb_linux_fdpiceabi.Po ++ -rm -f ./$(DEPDIR)/earmelfb_nacl.Po ++ -rm -f ./$(DEPDIR)/earmelfb_nbsd.Po ++ -rm -f ./$(DEPDIR)/earmnto.Po ++ -rm -f ./$(DEPDIR)/earmpe.Po ++ -rm -f ./$(DEPDIR)/eavr1.Po ++ -rm -f ./$(DEPDIR)/eavr2.Po ++ -rm -f ./$(DEPDIR)/eavr25.Po ++ -rm -f ./$(DEPDIR)/eavr3.Po ++ -rm -f ./$(DEPDIR)/eavr31.Po ++ -rm -f ./$(DEPDIR)/eavr35.Po ++ -rm -f ./$(DEPDIR)/eavr4.Po ++ -rm -f ./$(DEPDIR)/eavr5.Po ++ -rm -f ./$(DEPDIR)/eavr51.Po ++ -rm -f ./$(DEPDIR)/eavr6.Po ++ -rm -f ./$(DEPDIR)/eavrtiny.Po ++ -rm -f ./$(DEPDIR)/eavrxmega1.Po ++ -rm -f ./$(DEPDIR)/eavrxmega2.Po ++ -rm -f ./$(DEPDIR)/eavrxmega3.Po ++ -rm -f ./$(DEPDIR)/eavrxmega4.Po ++ -rm -f ./$(DEPDIR)/eavrxmega5.Po ++ -rm -f ./$(DEPDIR)/eavrxmega6.Po ++ -rm -f ./$(DEPDIR)/eavrxmega7.Po ++ -rm -f ./$(DEPDIR)/ecrisaout.Po ++ -rm -f ./$(DEPDIR)/ecriself.Po ++ -rm -f ./$(DEPDIR)/ecrislinux.Po ++ -rm -f ./$(DEPDIR)/ecskyelf.Po ++ -rm -f ./$(DEPDIR)/ecskyelf_linux.Po ++ -rm -f ./$(DEPDIR)/ed10velf.Po ++ -rm -f ./$(DEPDIR)/ed30v_e.Po ++ -rm -f ./$(DEPDIR)/ed30v_o.Po ++ -rm -f ./$(DEPDIR)/ed30velf.Po ++ -rm -f ./$(DEPDIR)/eelf32_dlx.Po ++ -rm -f ./$(DEPDIR)/eelf32_sparc.Po ++ -rm -f ./$(DEPDIR)/eelf32_sparc_sol2.Po ++ -rm -f ./$(DEPDIR)/eelf32_sparc_vxworks.Po ++ -rm -f ./$(DEPDIR)/eelf32_spu.Po ++ -rm -f ./$(DEPDIR)/eelf32_tic6x_be.Po ++ -rm -f ./$(DEPDIR)/eelf32_tic6x_elf_be.Po ++ -rm -f ./$(DEPDIR)/eelf32_tic6x_elf_le.Po ++ -rm -f ./$(DEPDIR)/eelf32_tic6x_le.Po ++ -rm -f ./$(DEPDIR)/eelf32_tic6x_linux_be.Po ++ -rm -f ./$(DEPDIR)/eelf32_tic6x_linux_le.Po ++ -rm -f ./$(DEPDIR)/eelf32_x86_64.Po ++ -rm -f ./$(DEPDIR)/eelf32am33lin.Po ++ -rm -f ./$(DEPDIR)/eelf32b4300.Po ++ -rm -f ./$(DEPDIR)/eelf32bfin.Po ++ -rm -f ./$(DEPDIR)/eelf32bfinfd.Po ++ -rm -f ./$(DEPDIR)/eelf32bmip.Po ++ -rm -f ./$(DEPDIR)/eelf32bmipn32.Po ++ -rm -f ./$(DEPDIR)/eelf32briscv.Po ++ -rm -f ./$(DEPDIR)/eelf32briscv_ilp32.Po ++ -rm -f ./$(DEPDIR)/eelf32briscv_ilp32f.Po ++ -rm -f ./$(DEPDIR)/eelf32bsmip.Po ++ -rm -f ./$(DEPDIR)/eelf32btsmip.Po ++ -rm -f ./$(DEPDIR)/eelf32btsmip_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf32btsmipn32.Po ++ -rm -f ./$(DEPDIR)/eelf32btsmipn32_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf32cr16.Po ++ -rm -f ./$(DEPDIR)/eelf32crx.Po ++ -rm -f ./$(DEPDIR)/eelf32ebmip.Po ++ -rm -f ./$(DEPDIR)/eelf32ebmipvxworks.Po ++ -rm -f ./$(DEPDIR)/eelf32elmip.Po ++ -rm -f ./$(DEPDIR)/eelf32elmipvxworks.Po ++ -rm -f ./$(DEPDIR)/eelf32epiphany.Po ++ -rm -f ./$(DEPDIR)/eelf32epiphany_4x4.Po ++ -rm -f ./$(DEPDIR)/eelf32fr30.Po ++ -rm -f ./$(DEPDIR)/eelf32frv.Po ++ -rm -f ./$(DEPDIR)/eelf32frvfd.Po ++ -rm -f ./$(DEPDIR)/eelf32ft32.Po ++ -rm -f ./$(DEPDIR)/eelf32ip2k.Po ++ -rm -f ./$(DEPDIR)/eelf32iq10.Po ++ -rm -f ./$(DEPDIR)/eelf32iq2000.Po ++ -rm -f ./$(DEPDIR)/eelf32l4300.Po ++ -rm -f ./$(DEPDIR)/eelf32lm32.Po ++ -rm -f ./$(DEPDIR)/eelf32lm32fd.Po ++ -rm -f ./$(DEPDIR)/eelf32lmip.Po ++ -rm -f ./$(DEPDIR)/eelf32loongarch.Po ++ -rm -f ./$(DEPDIR)/eelf32lppc.Po ++ -rm -f ./$(DEPDIR)/eelf32lppclinux.Po ++ -rm -f ./$(DEPDIR)/eelf32lppcnto.Po ++ -rm -f ./$(DEPDIR)/eelf32lppcsim.Po ++ -rm -f ./$(DEPDIR)/eelf32lr5900.Po ++ -rm -f ./$(DEPDIR)/eelf32lr5900n32.Po ++ -rm -f ./$(DEPDIR)/eelf32lriscv.Po ++ -rm -f ./$(DEPDIR)/eelf32lriscv_ilp32.Po ++ -rm -f ./$(DEPDIR)/eelf32lriscv_ilp32f.Po ++ -rm -f ./$(DEPDIR)/eelf32lsmip.Po ++ -rm -f ./$(DEPDIR)/eelf32ltsmip.Po ++ -rm -f ./$(DEPDIR)/eelf32ltsmip_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf32ltsmipn32.Po ++ -rm -f ./$(DEPDIR)/eelf32ltsmipn32_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf32m32c.Po ++ -rm -f ./$(DEPDIR)/eelf32mb_linux.Po ++ -rm -f ./$(DEPDIR)/eelf32mbel_linux.Po ++ -rm -f ./$(DEPDIR)/eelf32mcore.Po ++ -rm -f ./$(DEPDIR)/eelf32mep.Po ++ -rm -f ./$(DEPDIR)/eelf32metag.Po ++ -rm -f ./$(DEPDIR)/eelf32microblaze.Po ++ -rm -f ./$(DEPDIR)/eelf32microblazeel.Po ++ -rm -f ./$(DEPDIR)/eelf32mipswindiss.Po ++ -rm -f ./$(DEPDIR)/eelf32moxie.Po ++ -rm -f ./$(DEPDIR)/eelf32mt.Po ++ -rm -f ./$(DEPDIR)/eelf32or1k.Po ++ -rm -f ./$(DEPDIR)/eelf32or1k_linux.Po ++ -rm -f ./$(DEPDIR)/eelf32ppc.Po ++ -rm -f ./$(DEPDIR)/eelf32ppc_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf32ppchaiku.Po ++ -rm -f ./$(DEPDIR)/eelf32ppclinux.Po ++ -rm -f ./$(DEPDIR)/eelf32ppcnto.Po ++ -rm -f ./$(DEPDIR)/eelf32ppcsim.Po ++ -rm -f ./$(DEPDIR)/eelf32ppcvxworks.Po ++ -rm -f ./$(DEPDIR)/eelf32ppcwindiss.Po ++ -rm -f ./$(DEPDIR)/eelf32rl78.Po ++ -rm -f ./$(DEPDIR)/eelf32rx.Po ++ -rm -f ./$(DEPDIR)/eelf32rx_linux.Po ++ -rm -f ./$(DEPDIR)/eelf32tilegx.Po ++ -rm -f ./$(DEPDIR)/eelf32tilegx_be.Po ++ -rm -f ./$(DEPDIR)/eelf32tilepro.Po ++ -rm -f ./$(DEPDIR)/eelf32vax.Po ++ -rm -f ./$(DEPDIR)/eelf32visium.Po ++ -rm -f ./$(DEPDIR)/eelf32xstormy16.Po ++ -rm -f ./$(DEPDIR)/eelf32xtensa.Po ++ -rm -f ./$(DEPDIR)/eelf32z80.Po ++ -rm -f ./$(DEPDIR)/eelf64_aix.Po ++ -rm -f ./$(DEPDIR)/eelf64_ia64.Po ++ -rm -f ./$(DEPDIR)/eelf64_ia64_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64_ia64_vms.Po ++ -rm -f ./$(DEPDIR)/eelf64_s390.Po ++ -rm -f ./$(DEPDIR)/eelf64_sparc.Po ++ -rm -f ./$(DEPDIR)/eelf64_sparc_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64_sparc_sol2.Po ++ -rm -f ./$(DEPDIR)/eelf64alpha.Po ++ -rm -f ./$(DEPDIR)/eelf64alpha_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64alpha_nbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64bmip.Po ++ -rm -f ./$(DEPDIR)/eelf64bpf.Po ++ -rm -f ./$(DEPDIR)/eelf64briscv.Po ++ -rm -f ./$(DEPDIR)/eelf64briscv_lp64.Po ++ -rm -f ./$(DEPDIR)/eelf64briscv_lp64f.Po ++ -rm -f ./$(DEPDIR)/eelf64btsmip.Po ++ -rm -f ./$(DEPDIR)/eelf64btsmip_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64hppa.Po ++ -rm -f ./$(DEPDIR)/eelf64loongarch.Po ++ -rm -f ./$(DEPDIR)/eelf64lppc.Po ++ -rm -f ./$(DEPDIR)/eelf64lppc_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64lriscv.Po ++ -rm -f ./$(DEPDIR)/eelf64lriscv_lp64.Po ++ -rm -f ./$(DEPDIR)/eelf64lriscv_lp64f.Po ++ -rm -f ./$(DEPDIR)/eelf64ltsmip.Po ++ -rm -f ./$(DEPDIR)/eelf64ltsmip_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64mmix.Po ++ -rm -f ./$(DEPDIR)/eelf64ppc.Po ++ -rm -f ./$(DEPDIR)/eelf64ppc_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64rdos.Po ++ -rm -f ./$(DEPDIR)/eelf64tilegx.Po ++ -rm -f ./$(DEPDIR)/eelf64tilegx_be.Po ++ -rm -f ./$(DEPDIR)/eelf_i386.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_be.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_haiku.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_ldso.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_sb.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_sol2.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_vxworks.Po ++ -rm -f ./$(DEPDIR)/eelf_iamcu.Po ++ -rm -f ./$(DEPDIR)/eelf_mipsel_haiku.Po ++ -rm -f ./$(DEPDIR)/eelf_s390.Po ++ -rm -f ./$(DEPDIR)/eelf_x86_64.Po ++ -rm -f ./$(DEPDIR)/eelf_x86_64_cloudabi.Po ++ -rm -f ./$(DEPDIR)/eelf_x86_64_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf_x86_64_haiku.Po ++ -rm -f ./$(DEPDIR)/eelf_x86_64_sol2.Po ++ -rm -f ./$(DEPDIR)/eh8300elf.Po ++ -rm -f ./$(DEPDIR)/eh8300elf_linux.Po ++ -rm -f ./$(DEPDIR)/eh8300helf.Po ++ -rm -f ./$(DEPDIR)/eh8300helf_linux.Po ++ -rm -f ./$(DEPDIR)/eh8300hnelf.Po ++ -rm -f ./$(DEPDIR)/eh8300self.Po ++ -rm -f ./$(DEPDIR)/eh8300self_linux.Po ++ -rm -f ./$(DEPDIR)/eh8300snelf.Po ++ -rm -f ./$(DEPDIR)/eh8300sxelf.Po ++ -rm -f ./$(DEPDIR)/eh8300sxelf_linux.Po ++ -rm -f ./$(DEPDIR)/eh8300sxnelf.Po ++ -rm -f ./$(DEPDIR)/ehppa64linux.Po ++ -rm -f ./$(DEPDIR)/ehppaelf.Po ++ -rm -f ./$(DEPDIR)/ehppalinux.Po ++ -rm -f ./$(DEPDIR)/ehppanbsd.Po ++ -rm -f ./$(DEPDIR)/ehppaobsd.Po ++ -rm -f ./$(DEPDIR)/ei386aout.Po ++ -rm -f ./$(DEPDIR)/ei386beos.Po ++ -rm -f ./$(DEPDIR)/ei386bsd.Po ++ -rm -f ./$(DEPDIR)/ei386go32.Po ++ -rm -f ./$(DEPDIR)/ei386lynx.Po ++ -rm -f ./$(DEPDIR)/ei386moss.Po ++ -rm -f ./$(DEPDIR)/ei386msdos.Po ++ -rm -f ./$(DEPDIR)/ei386nto.Po ++ -rm -f ./$(DEPDIR)/ei386pe.Po ++ -rm -f ./$(DEPDIR)/ei386pe_posix.Po ++ -rm -f ./$(DEPDIR)/ei386pep.Po ++ -rm -f ./$(DEPDIR)/em32relf.Po ++ -rm -f ./$(DEPDIR)/em32relf_linux.Po ++ -rm -f ./$(DEPDIR)/em32rlelf.Po ++ -rm -f ./$(DEPDIR)/em32rlelf_linux.Po ++ -rm -f ./$(DEPDIR)/em68hc11elf.Po ++ -rm -f ./$(DEPDIR)/em68hc11elfb.Po ++ -rm -f ./$(DEPDIR)/em68hc12elf.Po ++ -rm -f ./$(DEPDIR)/em68hc12elfb.Po ++ -rm -f ./$(DEPDIR)/em68kelf.Po ++ -rm -f ./$(DEPDIR)/em68kelfnbsd.Po ++ -rm -f ./$(DEPDIR)/em9s12zelf.Po ++ -rm -f ./$(DEPDIR)/emcorepe.Po ++ -rm -f ./$(DEPDIR)/emmo.Po ++ -rm -f ./$(DEPDIR)/emn10200.Po ++ -rm -f ./$(DEPDIR)/emn10300.Po ++ -rm -f ./$(DEPDIR)/emoxiebox.Po ++ -rm -f ./$(DEPDIR)/emsp430X.Po ++ -rm -f ./$(DEPDIR)/emsp430elf.Po ++ -rm -f ./$(DEPDIR)/ends32belf.Po ++ -rm -f ./$(DEPDIR)/ends32belf16m.Po ++ -rm -f ./$(DEPDIR)/ends32belf_linux.Po ++ -rm -f ./$(DEPDIR)/ends32elf.Po ++ -rm -f ./$(DEPDIR)/ends32elf16m.Po ++ -rm -f ./$(DEPDIR)/ends32elf_linux.Po ++ -rm -f ./$(DEPDIR)/enios2elf.Po ++ -rm -f ./$(DEPDIR)/enios2linux.Po ++ -rm -f ./$(DEPDIR)/ens32knbsd.Po ++ -rm -f ./$(DEPDIR)/epc532macha.Po ++ -rm -f ./$(DEPDIR)/epdp11.Po ++ -rm -f ./$(DEPDIR)/epjelf.Po ++ -rm -f ./$(DEPDIR)/epjlelf.Po ++ -rm -f ./$(DEPDIR)/eppcmacos.Po ++ -rm -f ./$(DEPDIR)/epruelf.Po ++ -rm -f ./$(DEPDIR)/escore3_elf.Po ++ -rm -f ./$(DEPDIR)/escore7_elf.Po ++ -rm -f ./$(DEPDIR)/esh.Po ++ -rm -f ./$(DEPDIR)/eshelf.Po ++ -rm -f ./$(DEPDIR)/eshelf_fd.Po ++ -rm -f ./$(DEPDIR)/eshelf_linux.Po ++ -rm -f ./$(DEPDIR)/eshelf_nbsd.Po ++ -rm -f ./$(DEPDIR)/eshelf_nto.Po ++ -rm -f ./$(DEPDIR)/eshelf_uclinux.Po ++ -rm -f ./$(DEPDIR)/eshelf_vxworks.Po ++ -rm -f ./$(DEPDIR)/eshl.Po ++ -rm -f ./$(DEPDIR)/eshlelf.Po ++ -rm -f ./$(DEPDIR)/eshlelf_fd.Po ++ -rm -f ./$(DEPDIR)/eshlelf_linux.Po ++ -rm -f ./$(DEPDIR)/eshlelf_nbsd.Po ++ -rm -f ./$(DEPDIR)/eshlelf_nto.Po ++ -rm -f ./$(DEPDIR)/eshlelf_vxworks.Po ++ -rm -f ./$(DEPDIR)/eshpe.Po ++ -rm -f ./$(DEPDIR)/etic30coff.Po ++ -rm -f ./$(DEPDIR)/etic3xcoff.Po ++ -rm -f ./$(DEPDIR)/etic3xcoff_onchip.Po ++ -rm -f ./$(DEPDIR)/etic4xcoff.Po ++ -rm -f ./$(DEPDIR)/etic54xcoff.Po ++ -rm -f ./$(DEPDIR)/ev850.Po ++ -rm -f ./$(DEPDIR)/ev850_rh850.Po ++ -rm -f ./$(DEPDIR)/evanilla.Po ++ -rm -f ./$(DEPDIR)/evaxnbsd.Po ++ -rm -f ./$(DEPDIR)/exgateelf.Po ++ -rm -f ./$(DEPDIR)/ez80.Po ++ -rm -f ./$(DEPDIR)/ez8001.Po ++ -rm -f ./$(DEPDIR)/ez8002.Po ++ -rm -f ./$(DEPDIR)/ldbuildid.Po ++ -rm -f ./$(DEPDIR)/ldcref.Po ++ -rm -f ./$(DEPDIR)/ldctor.Po ++ -rm -f ./$(DEPDIR)/ldelf.Po ++ -rm -f ./$(DEPDIR)/ldelfgen.Po ++ -rm -f ./$(DEPDIR)/ldemul.Po ++ -rm -f ./$(DEPDIR)/ldexp.Po ++ -rm -f ./$(DEPDIR)/ldfile.Po ++ -rm -f ./$(DEPDIR)/ldgram.Po ++ -rm -f ./$(DEPDIR)/ldlang.Po ++ -rm -f ./$(DEPDIR)/ldlex-wrapper.Po ++ -rm -f ./$(DEPDIR)/ldlex.Po ++ -rm -f ./$(DEPDIR)/ldmain.Po ++ -rm -f ./$(DEPDIR)/ldmisc.Po ++ -rm -f ./$(DEPDIR)/ldver.Po ++ -rm -f ./$(DEPDIR)/ldwrite.Po ++ -rm -f ./$(DEPDIR)/lexsup.Po ++ -rm -f ./$(DEPDIR)/libdep_plugin.Plo ++ -rm -f ./$(DEPDIR)/libldtestplug2_la-testplug2.Plo ++ -rm -f ./$(DEPDIR)/libldtestplug3_la-testplug3.Plo ++ -rm -f ./$(DEPDIR)/libldtestplug4_la-testplug4.Plo ++ -rm -f ./$(DEPDIR)/libldtestplug_la-testplug.Plo ++ -rm -f ./$(DEPDIR)/mri.Po ++ -rm -f ./$(DEPDIR)/pdb.Po ++ -rm -f ./$(DEPDIR)/pe-dll.Po ++ -rm -f ./$(DEPDIR)/pep-dll.Po ++ -rm -f ./$(DEPDIR)/plugin.Po + -rm -f Makefile + maintainer-clean-am: distclean-am maintainer-clean-aminfo \ + maintainer-clean-generic +@@ -2188,21 +3017,22 @@ uninstall-am: uninstall-bfdpluginLTLIBRARIES uninstall-binPROGRAMS \ + uninstall-man: uninstall-man1 + + .MAKE: $(am__recursive_targets) all check check-am install install-am \ +- install-strip ++ install-exec install-strip + + .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ +- am--refresh check check-DEJAGNU check-am clean clean-aminfo \ +- clean-bfdpluginLTLIBRARIES clean-binPROGRAMS clean-cscope \ +- clean-generic clean-libtool clean-noinstLTLIBRARIES cscope \ +- cscopelist-am ctags ctags-am dist-info distclean \ +- distclean-DEJAGNU distclean-compile distclean-generic \ +- distclean-hdr distclean-libtool distclean-local distclean-tags \ +- dvi dvi-am html html-am html-local info info-am install \ +- install-am install-bfdpluginLTLIBRARIES install-binPROGRAMS \ +- install-data install-data-am install-data-local install-dvi \ +- install-dvi-am install-exec install-exec-am install-exec-local \ +- install-html install-html-am install-info install-info-am \ +- install-man install-man1 install-pdf install-pdf-am install-ps \ ++ am--depfiles am--refresh check check-DEJAGNU check-am clean \ ++ clean-aminfo clean-bfdpluginLTLIBRARIES clean-binPROGRAMS \ ++ clean-cscope clean-generic clean-libtool \ ++ clean-noinstLTLIBRARIES cscope cscopelist-am ctags ctags-am \ ++ dist-info distclean distclean-DEJAGNU distclean-compile \ ++ distclean-generic distclean-hdr distclean-libtool \ ++ distclean-local distclean-tags dvi dvi-am html html-am \ ++ html-local info info-am install install-am \ ++ install-bfdpluginLTLIBRARIES install-binPROGRAMS install-data \ ++ install-data-am install-data-local install-dvi install-dvi-am \ ++ install-exec install-exec-am install-exec-local install-html \ ++ install-html-am install-info install-info-am install-man \ ++ install-man1 install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs installdirs-am maintainer-clean \ + maintainer-clean-aminfo maintainer-clean-generic mostlyclean \ +@@ -2444,6 +3274,8 @@ $(ALL_EMULATION_SOURCES) $(ALL_64_EMULATION_SOURCES): $(GEN_DEPENDS) + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xtensa.Pc@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32z80.Pc@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386.Pc@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_sb.Pc@am__quote@ ++#@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_sb.Pc@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_be.Pc@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_fbsd.Pc@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_haiku.Pc@am__quote@ +diff --git a/ld/aclocal.m4 b/ld/aclocal.m4 +index 893e973e..1cd19c59 100644 +--- a/ld/aclocal.m4 ++++ b/ld/aclocal.m4 +@@ -1,6 +1,6 @@ +-# generated automatically by aclocal 1.15.1 -*- Autoconf -*- ++# generated automatically by aclocal 1.16.5 -*- Autoconf -*- + +-# Copyright (C) 1996-2017 Free Software Foundation, Inc. ++# Copyright (C) 1996-2021 Free Software Foundation, Inc. + + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -20,7 +20,9991 @@ You have another version of autoconf. It may work, but is not guaranteed to. + If you have problems, you may need to regenerate the build system entirely. + To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +-# Copyright (C) 2002-2017 Free Software Foundation, Inc. ++# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- ++# ++# Copyright (C) 1996-2001, 2003-2019, 2021-2022 Free Software ++# Foundation, Inc. ++# Written by Gordon Matzigkeit, 1996 ++# ++# This file is free software; the Free Software Foundation gives ++# unlimited permission to copy and/or distribute it, with or without ++# modifications, as long as this notice is preserved. ++ ++m4_define([_LT_COPYING], [dnl ++# Copyright (C) 2014 Free Software Foundation, Inc. ++# This is free software; see the source for copying conditions. There is NO ++# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ ++# GNU Libtool is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of of the License, or ++# (at your option) any later version. ++# ++# As a special exception to the GNU General Public License, if you ++# distribute this file as part of a program or library that is built ++# using GNU Libtool, you may include this file under the same ++# distribution terms that you use for the rest of that program. ++# ++# GNU Libtool is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++]) ++ ++# serial 59 LT_INIT ++ ++ ++# LT_PREREQ(VERSION) ++# ------------------ ++# Complain and exit if this libtool version is less that VERSION. ++m4_defun([LT_PREREQ], ++[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, ++ [m4_default([$3], ++ [m4_fatal([Libtool version $1 or higher is required], ++ 63)])], ++ [$2])]) ++ ++ ++# _LT_CHECK_BUILDDIR ++# ------------------ ++# Complain if the absolute build directory name contains unusual characters ++m4_defun([_LT_CHECK_BUILDDIR], ++[case `pwd` in ++ *\ * | *\ *) ++ AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; ++esac ++]) ++ ++ ++# LT_INIT([OPTIONS]) ++# ------------------ ++AC_DEFUN([LT_INIT], ++[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK ++AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl ++AC_BEFORE([$0], [LT_LANG])dnl ++AC_BEFORE([$0], [LT_OUTPUT])dnl ++AC_BEFORE([$0], [LTDL_INIT])dnl ++m4_require([_LT_CHECK_BUILDDIR])dnl ++ ++dnl Autoconf doesn't catch unexpanded LT_ macros by default: ++m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl ++m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl ++dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 ++dnl unless we require an AC_DEFUNed macro: ++AC_REQUIRE([LTOPTIONS_VERSION])dnl ++AC_REQUIRE([LTSUGAR_VERSION])dnl ++AC_REQUIRE([LTVERSION_VERSION])dnl ++AC_REQUIRE([LTOBSOLETE_VERSION])dnl ++m4_require([_LT_PROG_LTMAIN])dnl ++ ++_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) ++ ++dnl Parse OPTIONS ++_LT_SET_OPTIONS([$0], [$1]) ++ ++# This can be used to rebuild libtool when needed ++LIBTOOL_DEPS=$ltmain ++ ++# Always use our own libtool. ++LIBTOOL='$(SHELL) $(top_builddir)/libtool' ++AC_SUBST(LIBTOOL)dnl ++ ++_LT_SETUP ++ ++# Only expand once: ++m4_define([LT_INIT]) ++])# LT_INIT ++ ++# Old names: ++AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) ++AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AC_PROG_LIBTOOL], []) ++dnl AC_DEFUN([AM_PROG_LIBTOOL], []) ++ ++ ++# _LT_PREPARE_CC_BASENAME ++# ----------------------- ++m4_defun([_LT_PREPARE_CC_BASENAME], [ ++# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. ++func_cc_basename () ++{ ++ for cc_temp in @S|@*""; do ++ case $cc_temp in ++ compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; ++ distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; ++ \-*) ;; ++ *) break;; ++ esac ++ done ++ func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ++} ++])# _LT_PREPARE_CC_BASENAME ++ ++ ++# _LT_CC_BASENAME(CC) ++# ------------------- ++# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, ++# but that macro is also expanded into generated libtool script, which ++# arranges for $SED and $ECHO to be set by different means. ++m4_defun([_LT_CC_BASENAME], ++[m4_require([_LT_PREPARE_CC_BASENAME])dnl ++AC_REQUIRE([_LT_DECL_SED])dnl ++AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl ++func_cc_basename $1 ++cc_basename=$func_cc_basename_result ++]) ++ ++ ++# _LT_FILEUTILS_DEFAULTS ++# ---------------------- ++# It is okay to use these file commands and assume they have been set ++# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. ++m4_defun([_LT_FILEUTILS_DEFAULTS], ++[: ${CP="cp -f"} ++: ${MV="mv -f"} ++: ${RM="rm -f"} ++])# _LT_FILEUTILS_DEFAULTS ++ ++ ++# _LT_SETUP ++# --------- ++m4_defun([_LT_SETUP], ++[AC_REQUIRE([AC_CANONICAL_HOST])dnl ++AC_REQUIRE([AC_CANONICAL_BUILD])dnl ++AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl ++AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl ++ ++_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl ++dnl ++_LT_DECL([], [host_alias], [0], [The host system])dnl ++_LT_DECL([], [host], [0])dnl ++_LT_DECL([], [host_os], [0])dnl ++dnl ++_LT_DECL([], [build_alias], [0], [The build system])dnl ++_LT_DECL([], [build], [0])dnl ++_LT_DECL([], [build_os], [0])dnl ++dnl ++AC_REQUIRE([AC_PROG_CC])dnl ++AC_REQUIRE([LT_PATH_LD])dnl ++AC_REQUIRE([LT_PATH_NM])dnl ++dnl ++AC_REQUIRE([AC_PROG_LN_S])dnl ++test -z "$LN_S" && LN_S="ln -s" ++_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl ++dnl ++AC_REQUIRE([LT_CMD_MAX_LEN])dnl ++_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl ++_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl ++dnl ++m4_require([_LT_FILEUTILS_DEFAULTS])dnl ++m4_require([_LT_CHECK_SHELL_FEATURES])dnl ++m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl ++m4_require([_LT_CMD_RELOAD])dnl ++m4_require([_LT_DECL_FILECMD])dnl ++m4_require([_LT_CHECK_MAGIC_METHOD])dnl ++m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl ++m4_require([_LT_CMD_OLD_ARCHIVE])dnl ++m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl ++m4_require([_LT_WITH_SYSROOT])dnl ++m4_require([_LT_CMD_TRUNCATE])dnl ++ ++_LT_CONFIG_LIBTOOL_INIT([ ++# See if we are running on zsh, and set the options that allow our ++# commands through without removal of \ escapes INIT. ++if test -n "\${ZSH_VERSION+set}"; then ++ setopt NO_GLOB_SUBST ++fi ++]) ++if test -n "${ZSH_VERSION+set}"; then ++ setopt NO_GLOB_SUBST ++fi ++ ++_LT_CHECK_OBJDIR ++ ++m4_require([_LT_TAG_COMPILER])dnl ++ ++case $host_os in ++aix3*) ++ # AIX sometimes has problems with the GCC collect2 program. For some ++ # reason, if we set the COLLECT_NAMES environment variable, the problems ++ # vanish in a puff of smoke. ++ if test set != "${COLLECT_NAMES+set}"; then ++ COLLECT_NAMES= ++ export COLLECT_NAMES ++ fi ++ ;; ++esac ++ ++# Global variables: ++ofile=libtool ++can_build_shared=yes ++ ++# All known linkers require a '.a' archive for static linking (except MSVC and ++# ICC, which need '.lib'). ++libext=a ++ ++with_gnu_ld=$lt_cv_prog_gnu_ld ++ ++old_CC=$CC ++old_CFLAGS=$CFLAGS ++ ++# Set sane defaults for various variables ++test -z "$CC" && CC=cc ++test -z "$LTCC" && LTCC=$CC ++test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS ++test -z "$LD" && LD=ld ++test -z "$ac_objext" && ac_objext=o ++ ++_LT_CC_BASENAME([$compiler]) ++ ++# Only perform the check for file, if the check method requires it ++test -z "$MAGIC_CMD" && MAGIC_CMD=file ++case $deplibs_check_method in ++file_magic*) ++ if test "$file_magic_cmd" = '$MAGIC_CMD'; then ++ _LT_PATH_MAGIC ++ fi ++ ;; ++esac ++ ++# Use C for the default configuration in the libtool script ++LT_SUPPORTED_TAG([CC]) ++_LT_LANG_C_CONFIG ++_LT_LANG_DEFAULT_CONFIG ++_LT_CONFIG_COMMANDS ++])# _LT_SETUP ++ ++ ++# _LT_PREPARE_SED_QUOTE_VARS ++# -------------------------- ++# Define a few sed substitution that help us do robust quoting. ++m4_defun([_LT_PREPARE_SED_QUOTE_VARS], ++[# Backslashify metacharacters that are still active within ++# double-quoted strings. ++sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' ++ ++# Same as above, but do not quote variable references. ++double_quote_subst='s/\([["`\\]]\)/\\\1/g' ++ ++# Sed substitution to delay expansion of an escaped shell variable in a ++# double_quote_subst'ed string. ++delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' ++ ++# Sed substitution to delay expansion of an escaped single quote. ++delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' ++ ++# Sed substitution to avoid accidental globbing in evaled expressions ++no_glob_subst='s/\*/\\\*/g' ++]) ++ ++# _LT_PROG_LTMAIN ++# --------------- ++# Note that this code is called both from 'configure', and 'config.status' ++# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, ++# 'config.status' has no value for ac_aux_dir unless we are using Automake, ++# so we pass a copy along to make sure it has a sensible value anyway. ++m4_defun([_LT_PROG_LTMAIN], ++[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl ++_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ++ltmain=$ac_aux_dir/ltmain.sh ++])# _LT_PROG_LTMAIN ++ ++ ++ ++# So that we can recreate a full libtool script including additional ++# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS ++# in macros and then make a single call at the end using the 'libtool' ++# label. ++ ++ ++# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) ++# ---------------------------------------- ++# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. ++m4_define([_LT_CONFIG_LIBTOOL_INIT], ++[m4_ifval([$1], ++ [m4_append([_LT_OUTPUT_LIBTOOL_INIT], ++ [$1 ++])])]) ++ ++# Initialize. ++m4_define([_LT_OUTPUT_LIBTOOL_INIT]) ++ ++ ++# _LT_CONFIG_LIBTOOL([COMMANDS]) ++# ------------------------------ ++# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. ++m4_define([_LT_CONFIG_LIBTOOL], ++[m4_ifval([$1], ++ [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], ++ [$1 ++])])]) ++ ++# Initialize. ++m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) ++ ++ ++# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) ++# ----------------------------------------------------- ++m4_defun([_LT_CONFIG_SAVE_COMMANDS], ++[_LT_CONFIG_LIBTOOL([$1]) ++_LT_CONFIG_LIBTOOL_INIT([$2]) ++]) ++ ++ ++# _LT_FORMAT_COMMENT([COMMENT]) ++# ----------------------------- ++# Add leading comment marks to the start of each line, and a trailing ++# full-stop to the whole comment if one is not present already. ++m4_define([_LT_FORMAT_COMMENT], ++[m4_ifval([$1], [ ++m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], ++ [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) ++)]) ++ ++ ++ ++ ++ ++# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) ++# ------------------------------------------------------------------- ++# CONFIGNAME is the name given to the value in the libtool script. ++# VARNAME is the (base) name used in the configure script. ++# VALUE may be 0, 1 or 2 for a computed quote escaped value based on ++# VARNAME. Any other value will be used directly. ++m4_define([_LT_DECL], ++[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], ++ [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], ++ [m4_ifval([$1], [$1], [$2])]) ++ lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) ++ m4_ifval([$4], ++ [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) ++ lt_dict_add_subkey([lt_decl_dict], [$2], ++ [tagged?], [m4_ifval([$5], [yes], [no])])]) ++]) ++ ++ ++# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) ++# -------------------------------------------------------- ++m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) ++ ++ ++# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) ++# ------------------------------------------------ ++m4_define([lt_decl_tag_varnames], ++[_lt_decl_filter([tagged?], [yes], $@)]) ++ ++ ++# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) ++# --------------------------------------------------------- ++m4_define([_lt_decl_filter], ++[m4_case([$#], ++ [0], [m4_fatal([$0: too few arguments: $#])], ++ [1], [m4_fatal([$0: too few arguments: $#: $1])], ++ [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], ++ [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], ++ [lt_dict_filter([lt_decl_dict], $@)])[]dnl ++]) ++ ++ ++# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) ++# -------------------------------------------------- ++m4_define([lt_decl_quote_varnames], ++[_lt_decl_filter([value], [1], $@)]) ++ ++ ++# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) ++# --------------------------------------------------- ++m4_define([lt_decl_dquote_varnames], ++[_lt_decl_filter([value], [2], $@)]) ++ ++ ++# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) ++# --------------------------------------------------- ++m4_define([lt_decl_varnames_tagged], ++[m4_assert([$# <= 2])dnl ++_$0(m4_quote(m4_default([$1], [[, ]])), ++ m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), ++ m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) ++m4_define([_lt_decl_varnames_tagged], ++[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) ++ ++ ++# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) ++# ------------------------------------------------ ++m4_define([lt_decl_all_varnames], ++[_$0(m4_quote(m4_default([$1], [[, ]])), ++ m4_if([$2], [], ++ m4_quote(lt_decl_varnames), ++ m4_quote(m4_shift($@))))[]dnl ++]) ++m4_define([_lt_decl_all_varnames], ++[lt_join($@, lt_decl_varnames_tagged([$1], ++ lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ++]) ++ ++ ++# _LT_CONFIG_STATUS_DECLARE([VARNAME]) ++# ------------------------------------ ++# Quote a variable value, and forward it to 'config.status' so that its ++# declaration there will have the same value as in 'configure'. VARNAME ++# must have a single quote delimited value for this to work. ++m4_define([_LT_CONFIG_STATUS_DECLARE], ++[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) ++ ++ ++# _LT_CONFIG_STATUS_DECLARATIONS ++# ------------------------------ ++# We delimit libtool config variables with single quotes, so when ++# we write them to config.status, we have to be sure to quote all ++# embedded single quotes properly. In configure, this macro expands ++# each variable declared with _LT_DECL (and _LT_TAGDECL) into: ++# ++# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' ++m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], ++[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), ++ [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) ++ ++ ++# _LT_LIBTOOL_TAGS ++# ---------------- ++# Output comment and list of tags supported by the script ++m4_defun([_LT_LIBTOOL_TAGS], ++[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl ++available_tags='_LT_TAGS'dnl ++]) ++ ++ ++# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) ++# ----------------------------------- ++# Extract the dictionary values for VARNAME (optionally with TAG) and ++# expand to a commented shell variable setting: ++# ++# # Some comment about what VAR is for. ++# visible_name=$lt_internal_name ++m4_define([_LT_LIBTOOL_DECLARE], ++[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], ++ [description])))[]dnl ++m4_pushdef([_libtool_name], ++ m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl ++m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), ++ [0], [_libtool_name=[$]$1], ++ [1], [_libtool_name=$lt_[]$1], ++ [2], [_libtool_name=$lt_[]$1], ++ [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl ++m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ++]) ++ ++ ++# _LT_LIBTOOL_CONFIG_VARS ++# ----------------------- ++# Produce commented declarations of non-tagged libtool config variables ++# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' ++# script. Tagged libtool config variables (even for the LIBTOOL CONFIG ++# section) are produced by _LT_LIBTOOL_TAG_VARS. ++m4_defun([_LT_LIBTOOL_CONFIG_VARS], ++[m4_foreach([_lt_var], ++ m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), ++ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) ++ ++ ++# _LT_LIBTOOL_TAG_VARS(TAG) ++# ------------------------- ++m4_define([_LT_LIBTOOL_TAG_VARS], ++[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), ++ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) ++ ++ ++# _LT_TAGVAR(VARNAME, [TAGNAME]) ++# ------------------------------ ++m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) ++ ++ ++# _LT_CONFIG_COMMANDS ++# ------------------- ++# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of ++# variables for single and double quote escaping we saved from calls ++# to _LT_DECL, we can put quote escaped variables declarations ++# into 'config.status', and then the shell code to quote escape them in ++# for loops in 'config.status'. Finally, any additional code accumulated ++# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. ++m4_defun([_LT_CONFIG_COMMANDS], ++[AC_PROVIDE_IFELSE([LT_OUTPUT], ++ dnl If the libtool generation code has been placed in $CONFIG_LT, ++ dnl instead of duplicating it all over again into config.status, ++ dnl then we will have config.status run $CONFIG_LT later, so it ++ dnl needs to know what name is stored there: ++ [AC_CONFIG_COMMANDS([libtool], ++ [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], ++ dnl If the libtool generation code is destined for config.status, ++ dnl expand the accumulated commands and init code now: ++ [AC_CONFIG_COMMANDS([libtool], ++ [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ++])#_LT_CONFIG_COMMANDS ++ ++ ++# Initialize. ++m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], ++[ ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++sed_quote_subst='$sed_quote_subst' ++double_quote_subst='$double_quote_subst' ++delay_variable_subst='$delay_variable_subst' ++_LT_CONFIG_STATUS_DECLARATIONS ++LTCC='$LTCC' ++LTCFLAGS='$LTCFLAGS' ++compiler='$compiler_DEFAULT' ++ ++# A function that is used when there is no print builtin or printf. ++func_fallback_echo () ++{ ++ eval 'cat <<_LTECHO_EOF ++\$[]1 ++_LTECHO_EOF' ++} ++ ++# Quote evaled strings. ++for var in lt_decl_all_varnames([[ \ ++]], lt_decl_quote_varnames); do ++ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in ++ *[[\\\\\\\`\\"\\\$]]*) ++ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ++ ;; ++ *) ++ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ++ ;; ++ esac ++done ++ ++# Double-quote double-evaled strings. ++for var in lt_decl_all_varnames([[ \ ++]], lt_decl_dquote_varnames); do ++ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in ++ *[[\\\\\\\`\\"\\\$]]*) ++ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ++ ;; ++ *) ++ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ++ ;; ++ esac ++done ++ ++_LT_OUTPUT_LIBTOOL_INIT ++]) ++ ++# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) ++# ------------------------------------ ++# Generate a child script FILE with all initialization necessary to ++# reuse the environment learned by the parent script, and make the ++# file executable. If COMMENT is supplied, it is inserted after the ++# '#!' sequence but before initialization text begins. After this ++# macro, additional text can be appended to FILE to form the body of ++# the child script. The macro ends with non-zero status if the ++# file could not be fully written (such as if the disk is full). ++m4_ifdef([AS_INIT_GENERATED], ++[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], ++[m4_defun([_LT_GENERATED_FILE_INIT], ++[m4_require([AS_PREPARE])]dnl ++[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl ++[lt_write_fail=0 ++cat >$1 <<_ASEOF || lt_write_fail=1 ++#! $SHELL ++# Generated by $as_me. ++$2 ++SHELL=\${CONFIG_SHELL-$SHELL} ++export SHELL ++_ASEOF ++cat >>$1 <<\_ASEOF || lt_write_fail=1 ++AS_SHELL_SANITIZE ++_AS_PREPARE ++exec AS_MESSAGE_FD>&1 ++_ASEOF ++test 0 = "$lt_write_fail" && chmod +x $1[]dnl ++m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT ++ ++# LT_OUTPUT ++# --------- ++# This macro allows early generation of the libtool script (before ++# AC_OUTPUT is called), incase it is used in configure for compilation ++# tests. ++AC_DEFUN([LT_OUTPUT], ++[: ${CONFIG_LT=./config.lt} ++AC_MSG_NOTICE([creating $CONFIG_LT]) ++_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], ++[# Run this file to recreate a libtool stub with the current configuration.]) ++ ++cat >>"$CONFIG_LT" <<\_LTEOF ++lt_cl_silent=false ++exec AS_MESSAGE_LOG_FD>>config.log ++{ ++ echo ++ AS_BOX([Running $as_me.]) ++} >&AS_MESSAGE_LOG_FD ++ ++lt_cl_help="\ ++'$as_me' creates a local libtool stub from the current configuration, ++for use in further configure time tests before the real libtool is ++generated. ++ ++Usage: $[0] [[OPTIONS]] ++ ++ -h, --help print this help, then exit ++ -V, --version print version number, then exit ++ -q, --quiet do not print progress messages ++ -d, --debug don't remove temporary files ++ ++Report bugs to ." ++ ++lt_cl_version="\ ++m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl ++m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) ++configured by $[0], generated by m4_PACKAGE_STRING. ++ ++Copyright (C) 2011 Free Software Foundation, Inc. ++This config.lt script is free software; the Free Software Foundation ++gives unlimited permision to copy, distribute and modify it." ++ ++while test 0 != $[#] ++do ++ case $[1] in ++ --version | --v* | -V ) ++ echo "$lt_cl_version"; exit 0 ;; ++ --help | --h* | -h ) ++ echo "$lt_cl_help"; exit 0 ;; ++ --debug | --d* | -d ) ++ debug=: ;; ++ --quiet | --q* | --silent | --s* | -q ) ++ lt_cl_silent=: ;; ++ ++ -*) AC_MSG_ERROR([unrecognized option: $[1] ++Try '$[0] --help' for more information.]) ;; ++ ++ *) AC_MSG_ERROR([unrecognized argument: $[1] ++Try '$[0] --help' for more information.]) ;; ++ esac ++ shift ++done ++ ++if $lt_cl_silent; then ++ exec AS_MESSAGE_FD>/dev/null ++fi ++_LTEOF ++ ++cat >>"$CONFIG_LT" <<_LTEOF ++_LT_OUTPUT_LIBTOOL_COMMANDS_INIT ++_LTEOF ++ ++cat >>"$CONFIG_LT" <<\_LTEOF ++AC_MSG_NOTICE([creating $ofile]) ++_LT_OUTPUT_LIBTOOL_COMMANDS ++AS_EXIT(0) ++_LTEOF ++chmod +x "$CONFIG_LT" ++ ++# configure is writing to config.log, but config.lt does its own redirection, ++# appending to config.log, which fails on DOS, as config.log is still kept ++# open by configure. Here we exec the FD to /dev/null, effectively closing ++# config.log, so it can be properly (re)opened and appended to by config.lt. ++lt_cl_success=: ++test yes = "$silent" && ++ lt_config_lt_args="$lt_config_lt_args --quiet" ++exec AS_MESSAGE_LOG_FD>/dev/null ++$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false ++exec AS_MESSAGE_LOG_FD>>config.log ++$lt_cl_success || AS_EXIT(1) ++])# LT_OUTPUT ++ ++ ++# _LT_CONFIG(TAG) ++# --------------- ++# If TAG is the built-in tag, create an initial libtool script with a ++# default configuration from the untagged config vars. Otherwise add code ++# to config.status for appending the configuration named by TAG from the ++# matching tagged config vars. ++m4_defun([_LT_CONFIG], ++[m4_require([_LT_FILEUTILS_DEFAULTS])dnl ++_LT_CONFIG_SAVE_COMMANDS([ ++ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl ++ m4_if(_LT_TAG, [C], [ ++ # See if we are running on zsh, and set the options that allow our ++ # commands through without removal of \ escapes. ++ if test -n "${ZSH_VERSION+set}"; then ++ setopt NO_GLOB_SUBST ++ fi ++ ++ cfgfile=${ofile}T ++ trap "$RM \"$cfgfile\"; exit 1" 1 2 15 ++ $RM "$cfgfile" ++ ++ cat <<_LT_EOF >> "$cfgfile" ++#! $SHELL ++# Generated automatically by $as_me ($PACKAGE) $VERSION ++# NOTE: Changes made to this file will be lost: look at ltmain.sh. ++ ++# Provide generalized library-building support services. ++# Written by Gordon Matzigkeit, 1996 ++ ++_LT_COPYING ++_LT_LIBTOOL_TAGS ++ ++# Configured defaults for sys_lib_dlsearch_path munging. ++: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} ++ ++# ### BEGIN LIBTOOL CONFIG ++_LT_LIBTOOL_CONFIG_VARS ++_LT_LIBTOOL_TAG_VARS ++# ### END LIBTOOL CONFIG ++ ++_LT_EOF ++ ++ cat <<'_LT_EOF' >> "$cfgfile" ++ ++# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE ++ ++_LT_PREPARE_MUNGE_PATH_LIST ++_LT_PREPARE_CC_BASENAME ++ ++# ### END FUNCTIONS SHARED WITH CONFIGURE ++ ++_LT_EOF ++ ++ case $host_os in ++ aix3*) ++ cat <<\_LT_EOF >> "$cfgfile" ++# AIX sometimes has problems with the GCC collect2 program. For some ++# reason, if we set the COLLECT_NAMES environment variable, the problems ++# vanish in a puff of smoke. ++if test set != "${COLLECT_NAMES+set}"; then ++ COLLECT_NAMES= ++ export COLLECT_NAMES ++fi ++_LT_EOF ++ ;; ++ esac ++ ++ _LT_PROG_LTMAIN ++ ++ # We use sed instead of cat because bash on DJGPP gets confused if ++ # if finds mixed CR/LF and LF-only lines. Since sed operates in ++ # text mode, it properly converts lines to CR/LF. This bash problem ++ # is reportedly fixed, but why not run on old versions too? ++ $SED '$q' "$ltmain" >> "$cfgfile" \ ++ || (rm -f "$cfgfile"; exit 1) ++ ++ mv -f "$cfgfile" "$ofile" || ++ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") ++ chmod +x "$ofile" ++], ++[cat <<_LT_EOF >> "$ofile" ++ ++dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded ++dnl in a comment (ie after a #). ++# ### BEGIN LIBTOOL TAG CONFIG: $1 ++_LT_LIBTOOL_TAG_VARS(_LT_TAG) ++# ### END LIBTOOL TAG CONFIG: $1 ++_LT_EOF ++])dnl /m4_if ++], ++[m4_if([$1], [], [ ++ PACKAGE='$PACKAGE' ++ VERSION='$VERSION' ++ RM='$RM' ++ ofile='$ofile'], []) ++])dnl /_LT_CONFIG_SAVE_COMMANDS ++])# _LT_CONFIG ++ ++ ++# LT_SUPPORTED_TAG(TAG) ++# --------------------- ++# Trace this macro to discover what tags are supported by the libtool ++# --tag option, using: ++# autoconf --trace 'LT_SUPPORTED_TAG:$1' ++AC_DEFUN([LT_SUPPORTED_TAG], []) ++ ++ ++# C support is built-in for now ++m4_define([_LT_LANG_C_enabled], []) ++m4_define([_LT_TAGS], []) ++ ++ ++# LT_LANG(LANG) ++# ------------- ++# Enable libtool support for the given language if not already enabled. ++AC_DEFUN([LT_LANG], ++[AC_BEFORE([$0], [LT_OUTPUT])dnl ++m4_case([$1], ++ [C], [_LT_LANG(C)], ++ [C++], [_LT_LANG(CXX)], ++ [Go], [_LT_LANG(GO)], ++ [Java], [_LT_LANG(GCJ)], ++ [Fortran 77], [_LT_LANG(F77)], ++ [Fortran], [_LT_LANG(FC)], ++ [Windows Resource], [_LT_LANG(RC)], ++ [m4_ifdef([_LT_LANG_]$1[_CONFIG], ++ [_LT_LANG($1)], ++ [m4_fatal([$0: unsupported language: "$1"])])])dnl ++])# LT_LANG ++ ++ ++# _LT_LANG(LANGNAME) ++# ------------------ ++m4_defun([_LT_LANG], ++[m4_ifdef([_LT_LANG_]$1[_enabled], [], ++ [LT_SUPPORTED_TAG([$1])dnl ++ m4_append([_LT_TAGS], [$1 ])dnl ++ m4_define([_LT_LANG_]$1[_enabled], [])dnl ++ _LT_LANG_$1_CONFIG($1)])dnl ++])# _LT_LANG ++ ++ ++m4_ifndef([AC_PROG_GO], [ ++# NOTE: This macro has been submitted for inclusion into # ++# GNU Autoconf as AC_PROG_GO. When it is available in # ++# a released version of Autoconf we should remove this # ++# macro and use it instead. # ++m4_defun([AC_PROG_GO], ++[AC_LANG_PUSH(Go)dnl ++AC_ARG_VAR([GOC], [Go compiler command])dnl ++AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl ++_AC_ARG_VAR_LDFLAGS()dnl ++AC_CHECK_TOOL(GOC, gccgo) ++if test -z "$GOC"; then ++ if test -n "$ac_tool_prefix"; then ++ AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) ++ fi ++fi ++if test -z "$GOC"; then ++ AC_CHECK_PROG(GOC, gccgo, gccgo, false) ++fi ++])#m4_defun ++])#m4_ifndef ++ ++ ++# _LT_LANG_DEFAULT_CONFIG ++# ----------------------- ++m4_defun([_LT_LANG_DEFAULT_CONFIG], ++[AC_PROVIDE_IFELSE([AC_PROG_CXX], ++ [LT_LANG(CXX)], ++ [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) ++ ++AC_PROVIDE_IFELSE([AC_PROG_F77], ++ [LT_LANG(F77)], ++ [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) ++ ++AC_PROVIDE_IFELSE([AC_PROG_FC], ++ [LT_LANG(FC)], ++ [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) ++ ++dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal ++dnl pulling things in needlessly. ++AC_PROVIDE_IFELSE([AC_PROG_GCJ], ++ [LT_LANG(GCJ)], ++ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], ++ [LT_LANG(GCJ)], ++ [AC_PROVIDE_IFELSE([LT_PROG_GCJ], ++ [LT_LANG(GCJ)], ++ [m4_ifdef([AC_PROG_GCJ], ++ [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) ++ m4_ifdef([A][M_PROG_GCJ], ++ [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) ++ m4_ifdef([LT_PROG_GCJ], ++ [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) ++ ++AC_PROVIDE_IFELSE([AC_PROG_GO], ++ [LT_LANG(GO)], ++ [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) ++ ++AC_PROVIDE_IFELSE([LT_PROG_RC], ++ [LT_LANG(RC)], ++ [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ++])# _LT_LANG_DEFAULT_CONFIG ++ ++# Obsolete macros: ++AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) ++AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) ++AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) ++AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) ++AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AC_LIBTOOL_CXX], []) ++dnl AC_DEFUN([AC_LIBTOOL_F77], []) ++dnl AC_DEFUN([AC_LIBTOOL_FC], []) ++dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) ++dnl AC_DEFUN([AC_LIBTOOL_RC], []) ++ ++ ++# _LT_TAG_COMPILER ++# ---------------- ++m4_defun([_LT_TAG_COMPILER], ++[AC_REQUIRE([AC_PROG_CC])dnl ++ ++_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl ++_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl ++_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl ++_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl ++ ++# If no C compiler was specified, use CC. ++LTCC=${LTCC-"$CC"} ++ ++# If no C compiler flags were specified, use CFLAGS. ++LTCFLAGS=${LTCFLAGS-"$CFLAGS"} ++ ++# Allow CC to be a program name with arguments. ++compiler=$CC ++])# _LT_TAG_COMPILER ++ ++ ++# _LT_COMPILER_BOILERPLATE ++# ------------------------ ++# Check for compiler boilerplate output or warnings with ++# the simple compiler test code. ++m4_defun([_LT_COMPILER_BOILERPLATE], ++[m4_require([_LT_DECL_SED])dnl ++ac_outfile=conftest.$ac_objext ++echo "$lt_simple_compile_test_code" >conftest.$ac_ext ++eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_compiler_boilerplate=`cat conftest.err` ++$RM conftest* ++])# _LT_COMPILER_BOILERPLATE ++ ++ ++# _LT_LINKER_BOILERPLATE ++# ---------------------- ++# Check for linker boilerplate output or warnings with ++# the simple link test code. ++m4_defun([_LT_LINKER_BOILERPLATE], ++[m4_require([_LT_DECL_SED])dnl ++ac_outfile=conftest.$ac_objext ++echo "$lt_simple_link_test_code" >conftest.$ac_ext ++eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_linker_boilerplate=`cat conftest.err` ++$RM -r conftest* ++])# _LT_LINKER_BOILERPLATE ++ ++# _LT_REQUIRED_DARWIN_CHECKS ++# ------------------------- ++m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ ++ case $host_os in ++ rhapsody* | darwin*) ++ AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) ++ AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) ++ AC_CHECK_TOOL([LIPO], [lipo], [:]) ++ AC_CHECK_TOOL([OTOOL], [otool], [:]) ++ AC_CHECK_TOOL([OTOOL64], [otool64], [:]) ++ _LT_DECL([], [DSYMUTIL], [1], ++ [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) ++ _LT_DECL([], [NMEDIT], [1], ++ [Tool to change global to local symbols on Mac OS X]) ++ _LT_DECL([], [LIPO], [1], ++ [Tool to manipulate fat objects and archives on Mac OS X]) ++ _LT_DECL([], [OTOOL], [1], ++ [ldd/readelf like tool for Mach-O binaries on Mac OS X]) ++ _LT_DECL([], [OTOOL64], [1], ++ [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) ++ ++ AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], ++ [lt_cv_apple_cc_single_mod=no ++ if test -z "$LT_MULTI_MODULE"; then ++ # By default we will add the -single_module flag. You can override ++ # by either setting the environment variable LT_MULTI_MODULE ++ # non-empty at configure time, or by adding -multi_module to the ++ # link flags. ++ rm -rf libconftest.dylib* ++ echo "int foo(void){return 1;}" > conftest.c ++ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ ++-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD ++ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ ++ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err ++ _lt_result=$? ++ # If there is a non-empty error log, and "single_module" ++ # appears in it, assume the flag caused a linker warning ++ if test -s conftest.err && $GREP single_module conftest.err; then ++ cat conftest.err >&AS_MESSAGE_LOG_FD ++ # Otherwise, if the output was created with a 0 exit code from ++ # the compiler, it worked. ++ elif test -f libconftest.dylib && test 0 = "$_lt_result"; then ++ lt_cv_apple_cc_single_mod=yes ++ else ++ cat conftest.err >&AS_MESSAGE_LOG_FD ++ fi ++ rm -rf libconftest.dylib* ++ rm -f conftest.* ++ fi]) ++ ++ AC_CACHE_CHECK([for -exported_symbols_list linker flag], ++ [lt_cv_ld_exported_symbols_list], ++ [lt_cv_ld_exported_symbols_list=no ++ save_LDFLAGS=$LDFLAGS ++ echo "_main" > conftest.sym ++ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" ++ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], ++ [lt_cv_ld_exported_symbols_list=yes], ++ [lt_cv_ld_exported_symbols_list=no]) ++ LDFLAGS=$save_LDFLAGS ++ ]) ++ ++ AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], ++ [lt_cv_ld_force_load=no ++ cat > conftest.c << _LT_EOF ++int forced_loaded() { return 2;} ++_LT_EOF ++ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD ++ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD ++ echo "$AR $AR_FLAGS libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD ++ $AR $AR_FLAGS libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD ++ echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD ++ $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD ++ cat > conftest.c << _LT_EOF ++int main() { return 0;} ++_LT_EOF ++ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD ++ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err ++ _lt_result=$? ++ if test -s conftest.err && $GREP force_load conftest.err; then ++ cat conftest.err >&AS_MESSAGE_LOG_FD ++ elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then ++ lt_cv_ld_force_load=yes ++ else ++ cat conftest.err >&AS_MESSAGE_LOG_FD ++ fi ++ rm -f conftest.err libconftest.a conftest conftest.c ++ rm -rf conftest.dSYM ++ ]) ++ case $host_os in ++ rhapsody* | darwin1.[[012]]) ++ _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; ++ darwin1.*) ++ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; ++ darwin*) ++ case $MACOSX_DEPLOYMENT_TARGET,$host in ++ 10.[[012]],*|,*powerpc*-darwin[[5-8]]*) ++ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; ++ *) ++ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; ++ esac ++ ;; ++ esac ++ if test yes = "$lt_cv_apple_cc_single_mod"; then ++ _lt_dar_single_mod='$single_module' ++ fi ++ if test yes = "$lt_cv_ld_exported_symbols_list"; then ++ _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' ++ else ++ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' ++ fi ++ if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then ++ _lt_dsymutil='~$DSYMUTIL $lib || :' ++ else ++ _lt_dsymutil= ++ fi ++ ;; ++ esac ++]) ++ ++ ++# _LT_DARWIN_LINKER_FEATURES([TAG]) ++# --------------------------------- ++# Checks for linker and compiler features on darwin ++m4_defun([_LT_DARWIN_LINKER_FEATURES], ++[ ++ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) ++ _LT_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_TAGVAR(hardcode_direct, $1)=no ++ _LT_TAGVAR(hardcode_automatic, $1)=yes ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported ++ if test yes = "$lt_cv_ld_force_load"; then ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' ++ m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], ++ [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) ++ else ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='' ++ fi ++ _LT_TAGVAR(link_all_deplibs, $1)=yes ++ _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined ++ case $cc_basename in ++ ifort*|nagfor*) _lt_dar_can_shared=yes ;; ++ *) _lt_dar_can_shared=$GCC ;; ++ esac ++ if test yes = "$_lt_dar_can_shared"; then ++ output_verbose_link_cmd=func_echo_all ++ _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" ++ _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" ++ _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" ++ _LT_TAGVAR(module_expsym_cmds, $1)="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" ++ m4_if([$1], [CXX], ++[ if test yes != "$lt_cv_apple_cc_single_mod"; then ++ _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" ++ _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" ++ fi ++],[]) ++ else ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++]) ++ ++# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) ++# ---------------------------------- ++# Links a minimal program and checks the executable ++# for the system default hardcoded library path. In most cases, ++# this is /usr/lib:/lib, but when the MPI compilers are used ++# the location of the communication and MPI libs are included too. ++# If we don't find anything, use the default library path according ++# to the aix ld manual. ++# Store the results from the different compilers for each TAGNAME. ++# Allow to override them for all tags through lt_cv_aix_libpath. ++m4_defun([_LT_SYS_MODULE_PATH_AIX], ++[m4_require([_LT_DECL_SED])dnl ++if test set = "${lt_cv_aix_libpath+set}"; then ++ aix_libpath=$lt_cv_aix_libpath ++else ++ AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], ++ [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ ++ lt_aix_libpath_sed='[ ++ /Import File Strings/,/^$/ { ++ /^0/ { ++ s/^0 *\([^ ]*\) *$/\1/ ++ p ++ } ++ }]' ++ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` ++ # Check for a 64-bit object if we didn't find anything. ++ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then ++ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` ++ fi],[]) ++ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then ++ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib ++ fi ++ ]) ++ aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) ++fi ++])# _LT_SYS_MODULE_PATH_AIX ++ ++ ++# _LT_SHELL_INIT(ARG) ++# ------------------- ++m4_define([_LT_SHELL_INIT], ++[m4_divert_text([M4SH-INIT], [$1 ++])])# _LT_SHELL_INIT ++ ++ ++ ++# _LT_PROG_ECHO_BACKSLASH ++# ----------------------- ++# Find how we can fake an echo command that does not interpret backslash. ++# In particular, with Autoconf 2.60 or later we add some code to the start ++# of the generated configure script that will find a shell with a builtin ++# printf (that we can use as an echo command). ++m4_defun([_LT_PROG_ECHO_BACKSLASH], ++[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ++ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ++ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO ++ ++AC_MSG_CHECKING([how to print strings]) ++# Test print first, because it will be a builtin if present. ++if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ ++ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ++ ECHO='print -r --' ++elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ++ ECHO='printf %s\n' ++else ++ # Use this function as a fallback that always works. ++ func_fallback_echo () ++ { ++ eval 'cat <<_LTECHO_EOF ++$[]1 ++_LTECHO_EOF' ++ } ++ ECHO='func_fallback_echo' ++fi ++ ++# func_echo_all arg... ++# Invoke $ECHO with all args, space-separated. ++func_echo_all () ++{ ++ $ECHO "$*" ++} ++ ++case $ECHO in ++ printf*) AC_MSG_RESULT([printf]) ;; ++ print*) AC_MSG_RESULT([print -r]) ;; ++ *) AC_MSG_RESULT([cat]) ;; ++esac ++ ++m4_ifdef([_AS_DETECT_SUGGESTED], ++[_AS_DETECT_SUGGESTED([ ++ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ++ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ++ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ++ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO ++ PATH=/empty FPATH=/empty; export PATH FPATH ++ test "X`printf %s $ECHO`" = "X$ECHO" \ ++ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) ++ ++_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) ++_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ++])# _LT_PROG_ECHO_BACKSLASH ++ ++ ++# _LT_WITH_SYSROOT ++# ---------------- ++AC_DEFUN([_LT_WITH_SYSROOT], ++[m4_require([_LT_DECL_SED])dnl ++AC_MSG_CHECKING([for sysroot]) ++AC_ARG_WITH([sysroot], ++[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], ++ [Search for dependent libraries within DIR (or the compiler's sysroot ++ if not specified).])], ++[], [with_sysroot=no]) ++ ++dnl lt_sysroot will always be passed unquoted. We quote it here ++dnl in case the user passed a directory name. ++lt_sysroot= ++case $with_sysroot in #( ++ yes) ++ if test yes = "$GCC"; then ++ lt_sysroot=`$CC --print-sysroot 2>/dev/null` ++ fi ++ ;; #( ++ /*) ++ lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"` ++ ;; #( ++ no|'') ++ ;; #( ++ *) ++ AC_MSG_RESULT([$with_sysroot]) ++ AC_MSG_ERROR([The sysroot must be an absolute path.]) ++ ;; ++esac ++ ++ AC_MSG_RESULT([${lt_sysroot:-no}]) ++_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl ++[dependent libraries, and where our libraries should be installed.])]) ++ ++# _LT_ENABLE_LOCK ++# --------------- ++m4_defun([_LT_ENABLE_LOCK], ++[AC_ARG_ENABLE([libtool-lock], ++ [AS_HELP_STRING([--disable-libtool-lock], ++ [avoid locking (might break parallel builds)])]) ++test no = "$enable_libtool_lock" || enable_libtool_lock=yes ++ ++# Some flags need to be propagated to the compiler or linker for good ++# libtool support. ++case $host in ++ia64-*-hpux*) ++ # Find out what ABI is being produced by ac_compile, and set mode ++ # options accordingly. ++ echo 'int i;' > conftest.$ac_ext ++ if AC_TRY_EVAL(ac_compile); then ++ case `$FILECMD conftest.$ac_objext` in ++ *ELF-32*) ++ HPUX_IA64_MODE=32 ++ ;; ++ *ELF-64*) ++ HPUX_IA64_MODE=64 ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++*-*-irix6*) ++ # Find out what ABI is being produced by ac_compile, and set linker ++ # options accordingly. ++ echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext ++ if AC_TRY_EVAL(ac_compile); then ++ if test yes = "$lt_cv_prog_gnu_ld"; then ++ case `$FILECMD conftest.$ac_objext` in ++ *32-bit*) ++ LD="${LD-ld} -melf32bsmip" ++ ;; ++ *N32*) ++ LD="${LD-ld} -melf32bmipn32" ++ ;; ++ *64-bit*) ++ LD="${LD-ld} -melf64bmip" ++ ;; ++ esac ++ else ++ case `$FILECMD conftest.$ac_objext` in ++ *32-bit*) ++ LD="${LD-ld} -32" ++ ;; ++ *N32*) ++ LD="${LD-ld} -n32" ++ ;; ++ *64-bit*) ++ LD="${LD-ld} -64" ++ ;; ++ esac ++ fi ++ fi ++ rm -rf conftest* ++ ;; ++ ++mips64*-*linux*) ++ # Find out what ABI is being produced by ac_compile, and set linker ++ # options accordingly. ++ echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext ++ if AC_TRY_EVAL(ac_compile); then ++ emul=elf ++ case `$FILECMD conftest.$ac_objext` in ++ *32-bit*) ++ emul="${emul}32" ++ ;; ++ *64-bit*) ++ emul="${emul}64" ++ ;; ++ esac ++ case `$FILECMD conftest.$ac_objext` in ++ *MSB*) ++ emul="${emul}btsmip" ++ ;; ++ *LSB*) ++ emul="${emul}ltsmip" ++ ;; ++ esac ++ case `$FILECMD conftest.$ac_objext` in ++ *N32*) ++ emul="${emul}n32" ++ ;; ++ esac ++ LD="${LD-ld} -m $emul" ++ fi ++ rm -rf conftest* ++ ;; ++ ++x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ ++s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ++ # Find out what ABI is being produced by ac_compile, and set linker ++ # options accordingly. Note that the listed cases only cover the ++ # situations where additional linker options are needed (such as when ++ # doing 32-bit compilation for a host where ld defaults to 64-bit, or ++ # vice versa); the common cases where no linker options are needed do ++ # not appear in the list. ++ echo 'int i;' > conftest.$ac_ext ++ if AC_TRY_EVAL(ac_compile); then ++ case `$FILECMD conftest.o` in ++ *32-bit*) ++ case $host in ++ x86_64-*kfreebsd*-gnu) ++ LD="${LD-ld} -m elf_i386_fbsd" ++ ;; ++ x86_64-*linux*) ++ case `$FILECMD conftest.o` in ++ *x86-64*) ++ LD="${LD-ld} -m elf32_x86_64" ++ ;; ++ *) ++ LD="${LD-ld} -m elf_i386" ++ ;; ++ esac ++ ;; ++ powerpc64le-*linux*) ++ LD="${LD-ld} -m elf32lppclinux" ++ ;; ++ powerpc64-*linux*) ++ LD="${LD-ld} -m elf32ppclinux" ++ ;; ++ s390x-*linux*) ++ LD="${LD-ld} -m elf_s390" ++ ;; ++ sparc64-*linux*) ++ LD="${LD-ld} -m elf32_sparc" ++ ;; ++ esac ++ ;; ++ *64-bit*) ++ case $host in ++ x86_64-*kfreebsd*-gnu) ++ LD="${LD-ld} -m elf_x86_64_fbsd" ++ ;; ++ x86_64-*linux*) ++ LD="${LD-ld} -m elf_x86_64" ++ ;; ++ powerpcle-*linux*) ++ LD="${LD-ld} -m elf64lppc" ++ ;; ++ powerpc-*linux*) ++ LD="${LD-ld} -m elf64ppc" ++ ;; ++ s390*-*linux*|s390*-*tpf*) ++ LD="${LD-ld} -m elf64_s390" ++ ;; ++ sparc*-*linux*) ++ LD="${LD-ld} -m elf64_sparc" ++ ;; ++ esac ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++ ++*-*-sco3.2v5*) ++ # On SCO OpenServer 5, we need -belf to get full-featured binaries. ++ SAVE_CFLAGS=$CFLAGS ++ CFLAGS="$CFLAGS -belf" ++ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, ++ [AC_LANG_PUSH(C) ++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) ++ AC_LANG_POP]) ++ if test yes != "$lt_cv_cc_needs_belf"; then ++ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf ++ CFLAGS=$SAVE_CFLAGS ++ fi ++ ;; ++*-*solaris*) ++ # Find out what ABI is being produced by ac_compile, and set linker ++ # options accordingly. ++ echo 'int i;' > conftest.$ac_ext ++ if AC_TRY_EVAL(ac_compile); then ++ case `$FILECMD conftest.o` in ++ *64-bit*) ++ case $lt_cv_prog_gnu_ld in ++ yes*) ++ case $host in ++ i?86-*-solaris*|x86_64-*-solaris*) ++ LD="${LD-ld} -m elf_x86_64" ++ ;; ++ sparc*-*-solaris*) ++ LD="${LD-ld} -m elf64_sparc" ++ ;; ++ esac ++ # GNU ld 2.21 introduced _sol2 emulations. Use them if available. ++ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then ++ LD=${LD-ld}_sol2 ++ fi ++ ;; ++ *) ++ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then ++ LD="${LD-ld} -64" ++ fi ++ ;; ++ esac ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++esac ++ ++need_locks=$enable_libtool_lock ++])# _LT_ENABLE_LOCK ++ ++ ++# _LT_PROG_AR ++# ----------- ++m4_defun([_LT_PROG_AR], ++[AC_CHECK_TOOLS(AR, [ar], false) ++: ${AR=ar} ++_LT_DECL([], [AR], [1], [The archiver]) ++ ++# Use ARFLAGS variable as AR's operation code to sync the variable naming with ++# Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have ++# higher priority because thats what people were doing historically (setting ++# ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS ++# variable obsoleted/removed. ++ ++test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} ++lt_ar_flags=$AR_FLAGS ++_LT_DECL([], [lt_ar_flags], [0], [Flags to create an archive (by configure)]) ++ ++# Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override ++# by AR_FLAGS because that was never working and AR_FLAGS is about to die. ++_LT_DECL([], [AR_FLAGS], [\@S|@{ARFLAGS-"\@S|@lt_ar_flags"}], ++ [Flags to create an archive]) ++ ++AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], ++ [lt_cv_ar_at_file=no ++ AC_COMPILE_IFELSE([AC_LANG_PROGRAM], ++ [echo conftest.$ac_objext > conftest.lst ++ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' ++ AC_TRY_EVAL([lt_ar_try]) ++ if test 0 -eq "$ac_status"; then ++ # Ensure the archiver fails upon bogus file names. ++ rm -f conftest.$ac_objext libconftest.a ++ AC_TRY_EVAL([lt_ar_try]) ++ if test 0 -ne "$ac_status"; then ++ lt_cv_ar_at_file=@ ++ fi ++ fi ++ rm -f conftest.* libconftest.a ++ ]) ++ ]) ++ ++if test no = "$lt_cv_ar_at_file"; then ++ archiver_list_spec= ++else ++ archiver_list_spec=$lt_cv_ar_at_file ++fi ++_LT_DECL([], [archiver_list_spec], [1], ++ [How to feed a file listing to the archiver]) ++])# _LT_PROG_AR ++ ++ ++# _LT_CMD_OLD_ARCHIVE ++# ------------------- ++m4_defun([_LT_CMD_OLD_ARCHIVE], ++[_LT_PROG_AR ++ ++AC_CHECK_TOOL(STRIP, strip, :) ++test -z "$STRIP" && STRIP=: ++_LT_DECL([], [STRIP], [1], [A symbol stripping program]) ++ ++AC_CHECK_TOOL(RANLIB, ranlib, :) ++test -z "$RANLIB" && RANLIB=: ++_LT_DECL([], [RANLIB], [1], ++ [Commands used to install an old-style archive]) ++ ++# Determine commands to create old-style static archives. ++old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' ++old_postinstall_cmds='chmod 644 $oldlib' ++old_postuninstall_cmds= ++ ++if test -n "$RANLIB"; then ++ case $host_os in ++ bitrig* | openbsd*) ++ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ++ ;; ++ *) ++ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ++ ;; ++ esac ++ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" ++fi ++ ++case $host_os in ++ darwin*) ++ lock_old_archive_extraction=yes ;; ++ *) ++ lock_old_archive_extraction=no ;; ++esac ++_LT_DECL([], [old_postinstall_cmds], [2]) ++_LT_DECL([], [old_postuninstall_cmds], [2]) ++_LT_TAGDECL([], [old_archive_cmds], [2], ++ [Commands used to build an old-style archive]) ++_LT_DECL([], [lock_old_archive_extraction], [0], ++ [Whether to use a lock for old archive extraction]) ++])# _LT_CMD_OLD_ARCHIVE ++ ++ ++# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, ++# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) ++# ---------------------------------------------------------------- ++# Check whether the given compiler option works ++AC_DEFUN([_LT_COMPILER_OPTION], ++[m4_require([_LT_FILEUTILS_DEFAULTS])dnl ++m4_require([_LT_DECL_SED])dnl ++AC_CACHE_CHECK([$1], [$2], ++ [$2=no ++ m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ # The option is referenced via a variable to avoid confusing sed. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) ++ (eval "$lt_compile" 2>conftest.err) ++ ac_status=$? ++ cat conftest.err >&AS_MESSAGE_LOG_FD ++ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD ++ if (exit $ac_status) && test -s "$ac_outfile"; then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings other than the usual output. ++ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then ++ $2=yes ++ fi ++ fi ++ $RM conftest* ++]) ++ ++if test yes = "[$]$2"; then ++ m4_if([$5], , :, [$5]) ++else ++ m4_if([$6], , :, [$6]) ++fi ++])# _LT_COMPILER_OPTION ++ ++# Old name: ++AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) ++ ++ ++# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, ++# [ACTION-SUCCESS], [ACTION-FAILURE]) ++# ---------------------------------------------------- ++# Check whether the given linker option works ++AC_DEFUN([_LT_LINKER_OPTION], ++[m4_require([_LT_FILEUTILS_DEFAULTS])dnl ++m4_require([_LT_DECL_SED])dnl ++AC_CACHE_CHECK([$1], [$2], ++ [$2=no ++ save_LDFLAGS=$LDFLAGS ++ LDFLAGS="$LDFLAGS $3" ++ echo "$lt_simple_link_test_code" > conftest.$ac_ext ++ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then ++ # The linker can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ if test -s conftest.err; then ++ # Append any errors to the config.log. ++ cat conftest.err 1>&AS_MESSAGE_LOG_FD ++ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if diff conftest.exp conftest.er2 >/dev/null; then ++ $2=yes ++ fi ++ else ++ $2=yes ++ fi ++ fi ++ $RM -r conftest* ++ LDFLAGS=$save_LDFLAGS ++]) ++ ++if test yes = "[$]$2"; then ++ m4_if([$4], , :, [$4]) ++else ++ m4_if([$5], , :, [$5]) ++fi ++])# _LT_LINKER_OPTION ++ ++# Old name: ++AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) ++ ++ ++# LT_CMD_MAX_LEN ++#--------------- ++AC_DEFUN([LT_CMD_MAX_LEN], ++[AC_REQUIRE([AC_CANONICAL_HOST])dnl ++# find the maximum length of command line arguments ++AC_MSG_CHECKING([the maximum length of command line arguments]) ++AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl ++ i=0 ++ teststring=ABCD ++ ++ case $build_os in ++ msdosdjgpp*) ++ # On DJGPP, this test can blow up pretty badly due to problems in libc ++ # (any single argument exceeding 2000 bytes causes a buffer overrun ++ # during glob expansion). Even if it were fixed, the result of this ++ # check would be larger than it should be. ++ lt_cv_sys_max_cmd_len=12288; # 12K is about right ++ ;; ++ ++ gnu*) ++ # Under GNU Hurd, this test is not required because there is ++ # no limit to the length of command line arguments. ++ # Libtool will interpret -1 as no limit whatsoever ++ lt_cv_sys_max_cmd_len=-1; ++ ;; ++ ++ cygwin* | mingw* | cegcc*) ++ # On Win9x/ME, this test blows up -- it succeeds, but takes ++ # about 5 minutes as the teststring grows exponentially. ++ # Worse, since 9x/ME are not pre-emptively multitasking, ++ # you end up with a "frozen" computer, even though with patience ++ # the test eventually succeeds (with a max line length of 256k). ++ # Instead, let's just punt: use the minimum linelength reported by ++ # all of the supported platforms: 8192 (on NT/2K/XP). ++ lt_cv_sys_max_cmd_len=8192; ++ ;; ++ ++ mint*) ++ # On MiNT this can take a long time and run out of memory. ++ lt_cv_sys_max_cmd_len=8192; ++ ;; ++ ++ amigaos*) ++ # On AmigaOS with pdksh, this test takes hours, literally. ++ # So we just punt and use a minimum line length of 8192. ++ lt_cv_sys_max_cmd_len=8192; ++ ;; ++ ++ bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) ++ # This has been around since 386BSD, at least. Likely further. ++ if test -x /sbin/sysctl; then ++ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` ++ elif test -x /usr/sbin/sysctl; then ++ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` ++ else ++ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs ++ fi ++ # And add a safety zone ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ++ ;; ++ ++ interix*) ++ # We know the value 262144 and hardcode it with a safety zone (like BSD) ++ lt_cv_sys_max_cmd_len=196608 ++ ;; ++ ++ os2*) ++ # The test takes a long time on OS/2. ++ lt_cv_sys_max_cmd_len=8192 ++ ;; ++ ++ osf*) ++ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure ++ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not ++ # nice to cause kernel panics so lets avoid the loop below. ++ # First set a reasonable default. ++ lt_cv_sys_max_cmd_len=16384 ++ # ++ if test -x /sbin/sysconfig; then ++ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in ++ *1*) lt_cv_sys_max_cmd_len=-1 ;; ++ esac ++ fi ++ ;; ++ sco3.2v5*) ++ lt_cv_sys_max_cmd_len=102400 ++ ;; ++ sysv5* | sco5v6* | sysv4.2uw2*) ++ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` ++ if test -n "$kargmax"; then ++ lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[[ ]]//'` ++ else ++ lt_cv_sys_max_cmd_len=32768 ++ fi ++ ;; ++ *) ++ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` ++ if test -n "$lt_cv_sys_max_cmd_len" && \ ++ test undefined != "$lt_cv_sys_max_cmd_len"; then ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ++ else ++ # Make teststring a little bigger before we do anything with it. ++ # a 1K string should be a reasonable start. ++ for i in 1 2 3 4 5 6 7 8; do ++ teststring=$teststring$teststring ++ done ++ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} ++ # If test is not a shell built-in, we'll probably end up computing a ++ # maximum length that is only half of the actual maximum length, but ++ # we can't tell. ++ while { test X`env echo "$teststring$teststring" 2>/dev/null` \ ++ = "X$teststring$teststring"; } >/dev/null 2>&1 && ++ test 17 != "$i" # 1/2 MB should be enough ++ do ++ i=`expr $i + 1` ++ teststring=$teststring$teststring ++ done ++ # Only check the string length outside the loop. ++ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` ++ teststring= ++ # Add a significant safety factor because C++ compilers can tack on ++ # massive amounts of additional arguments before passing them to the ++ # linker. It appears as though 1/2 is a usable value. ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` ++ fi ++ ;; ++ esac ++]) ++if test -n "$lt_cv_sys_max_cmd_len"; then ++ AC_MSG_RESULT($lt_cv_sys_max_cmd_len) ++else ++ AC_MSG_RESULT(none) ++fi ++max_cmd_len=$lt_cv_sys_max_cmd_len ++_LT_DECL([], [max_cmd_len], [0], ++ [What is the maximum length of a command?]) ++])# LT_CMD_MAX_LEN ++ ++# Old name: ++AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) ++ ++ ++# _LT_HEADER_DLFCN ++# ---------------- ++m4_defun([_LT_HEADER_DLFCN], ++[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ++])# _LT_HEADER_DLFCN ++ ++ ++# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, ++# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) ++# ---------------------------------------------------------------- ++m4_defun([_LT_TRY_DLOPEN_SELF], ++[m4_require([_LT_HEADER_DLFCN])dnl ++if test yes = "$cross_compiling"; then : ++ [$4] ++else ++ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 ++ lt_status=$lt_dlunknown ++ cat > conftest.$ac_ext <<_LT_EOF ++[#line $LINENO "configure" ++#include "confdefs.h" ++ ++#if HAVE_DLFCN_H ++#include ++#endif ++ ++#include ++ ++#ifdef RTLD_GLOBAL ++# define LT_DLGLOBAL RTLD_GLOBAL ++#else ++# ifdef DL_GLOBAL ++# define LT_DLGLOBAL DL_GLOBAL ++# else ++# define LT_DLGLOBAL 0 ++# endif ++#endif ++ ++/* We may have to define LT_DLLAZY_OR_NOW in the command line if we ++ find out it does not work in some platform. */ ++#ifndef LT_DLLAZY_OR_NOW ++# ifdef RTLD_LAZY ++# define LT_DLLAZY_OR_NOW RTLD_LAZY ++# else ++# ifdef DL_LAZY ++# define LT_DLLAZY_OR_NOW DL_LAZY ++# else ++# ifdef RTLD_NOW ++# define LT_DLLAZY_OR_NOW RTLD_NOW ++# else ++# ifdef DL_NOW ++# define LT_DLLAZY_OR_NOW DL_NOW ++# else ++# define LT_DLLAZY_OR_NOW 0 ++# endif ++# endif ++# endif ++# endif ++#endif ++ ++/* When -fvisibility=hidden is used, assume the code has been annotated ++ correspondingly for the symbols needed. */ ++#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) ++int fnord () __attribute__((visibility("default"))); ++#endif ++ ++int fnord () { return 42; } ++int main () ++{ ++ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); ++ int status = $lt_dlunknown; ++ ++ if (self) ++ { ++ if (dlsym (self,"fnord")) status = $lt_dlno_uscore; ++ else ++ { ++ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; ++ else puts (dlerror ()); ++ } ++ /* dlclose (self); */ ++ } ++ else ++ puts (dlerror ()); ++ ++ return status; ++}] ++_LT_EOF ++ if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then ++ (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null ++ lt_status=$? ++ case x$lt_status in ++ x$lt_dlno_uscore) $1 ;; ++ x$lt_dlneed_uscore) $2 ;; ++ x$lt_dlunknown|x*) $3 ;; ++ esac ++ else : ++ # compilation failed ++ $3 ++ fi ++fi ++rm -fr conftest* ++])# _LT_TRY_DLOPEN_SELF ++ ++ ++# LT_SYS_DLOPEN_SELF ++# ------------------ ++AC_DEFUN([LT_SYS_DLOPEN_SELF], ++[m4_require([_LT_HEADER_DLFCN])dnl ++if test yes != "$enable_dlopen"; then ++ enable_dlopen=unknown ++ enable_dlopen_self=unknown ++ enable_dlopen_self_static=unknown ++else ++ lt_cv_dlopen=no ++ lt_cv_dlopen_libs= ++ ++ case $host_os in ++ beos*) ++ lt_cv_dlopen=load_add_on ++ lt_cv_dlopen_libs= ++ lt_cv_dlopen_self=yes ++ ;; ++ ++ mingw* | pw32* | cegcc*) ++ lt_cv_dlopen=LoadLibrary ++ lt_cv_dlopen_libs= ++ ;; ++ ++ cygwin*) ++ lt_cv_dlopen=dlopen ++ lt_cv_dlopen_libs= ++ ;; ++ ++ darwin*) ++ # if libdl is installed we need to link against it ++ AC_CHECK_LIB([dl], [dlopen], ++ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ ++ lt_cv_dlopen=dyld ++ lt_cv_dlopen_libs= ++ lt_cv_dlopen_self=yes ++ ]) ++ ;; ++ ++ tpf*) ++ # Don't try to run any link tests for TPF. We know it's impossible ++ # because TPF is a cross-compiler, and we know how we open DSOs. ++ lt_cv_dlopen=dlopen ++ lt_cv_dlopen_libs= ++ lt_cv_dlopen_self=no ++ ;; ++ ++ *) ++ AC_CHECK_FUNC([shl_load], ++ [lt_cv_dlopen=shl_load], ++ [AC_CHECK_LIB([dld], [shl_load], ++ [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], ++ [AC_CHECK_FUNC([dlopen], ++ [lt_cv_dlopen=dlopen], ++ [AC_CHECK_LIB([dl], [dlopen], ++ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], ++ [AC_CHECK_LIB([svld], [dlopen], ++ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], ++ [AC_CHECK_LIB([dld], [dld_link], ++ [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) ++ ]) ++ ]) ++ ]) ++ ]) ++ ]) ++ ;; ++ esac ++ ++ if test no = "$lt_cv_dlopen"; then ++ enable_dlopen=no ++ else ++ enable_dlopen=yes ++ fi ++ ++ case $lt_cv_dlopen in ++ dlopen) ++ save_CPPFLAGS=$CPPFLAGS ++ test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" ++ ++ save_LDFLAGS=$LDFLAGS ++ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" ++ ++ save_LIBS=$LIBS ++ LIBS="$lt_cv_dlopen_libs $LIBS" ++ ++ AC_CACHE_CHECK([whether a program can dlopen itself], ++ lt_cv_dlopen_self, [dnl ++ _LT_TRY_DLOPEN_SELF( ++ lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, ++ lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ++ ]) ++ ++ if test yes = "$lt_cv_dlopen_self"; then ++ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" ++ AC_CACHE_CHECK([whether a statically linked program can dlopen itself], ++ lt_cv_dlopen_self_static, [dnl ++ _LT_TRY_DLOPEN_SELF( ++ lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, ++ lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ++ ]) ++ fi ++ ++ CPPFLAGS=$save_CPPFLAGS ++ LDFLAGS=$save_LDFLAGS ++ LIBS=$save_LIBS ++ ;; ++ esac ++ ++ case $lt_cv_dlopen_self in ++ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; ++ *) enable_dlopen_self=unknown ;; ++ esac ++ ++ case $lt_cv_dlopen_self_static in ++ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; ++ *) enable_dlopen_self_static=unknown ;; ++ esac ++fi ++_LT_DECL([dlopen_support], [enable_dlopen], [0], ++ [Whether dlopen is supported]) ++_LT_DECL([dlopen_self], [enable_dlopen_self], [0], ++ [Whether dlopen of programs is supported]) ++_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], ++ [Whether dlopen of statically linked programs is supported]) ++])# LT_SYS_DLOPEN_SELF ++ ++# Old name: ++AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) ++ ++ ++# _LT_COMPILER_C_O([TAGNAME]) ++# --------------------------- ++# Check to see if options -c and -o are simultaneously supported by compiler. ++# This macro does not hard code the compiler like AC_PROG_CC_C_O. ++m4_defun([_LT_COMPILER_C_O], ++[m4_require([_LT_DECL_SED])dnl ++m4_require([_LT_FILEUTILS_DEFAULTS])dnl ++m4_require([_LT_TAG_COMPILER])dnl ++AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], ++ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], ++ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no ++ $RM -r conftest 2>/dev/null ++ mkdir conftest ++ cd conftest ++ mkdir out ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ lt_compiler_flag="-o out/conftest2.$ac_objext" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) ++ (eval "$lt_compile" 2>out/conftest.err) ++ ac_status=$? ++ cat out/conftest.err >&AS_MESSAGE_LOG_FD ++ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD ++ if (exit $ac_status) && test -s out/conftest2.$ac_objext ++ then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp ++ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 ++ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then ++ _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes ++ fi ++ fi ++ chmod u+w . 2>&AS_MESSAGE_LOG_FD ++ $RM conftest* ++ # SGI C++ compiler will create directory out/ii_files/ for ++ # template instantiation ++ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files ++ $RM out/* && rmdir out ++ cd .. ++ $RM -r conftest ++ $RM conftest* ++]) ++_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], ++ [Does compiler simultaneously support -c and -o options?]) ++])# _LT_COMPILER_C_O ++ ++ ++# _LT_COMPILER_FILE_LOCKS([TAGNAME]) ++# ---------------------------------- ++# Check to see if we can do hard links to lock some files if needed ++m4_defun([_LT_COMPILER_FILE_LOCKS], ++[m4_require([_LT_ENABLE_LOCK])dnl ++m4_require([_LT_FILEUTILS_DEFAULTS])dnl ++_LT_COMPILER_C_O([$1]) ++ ++hard_links=nottested ++if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then ++ # do not overwrite the value of need_locks provided by the user ++ AC_MSG_CHECKING([if we can lock with hard links]) ++ hard_links=yes ++ $RM conftest* ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ touch conftest.a ++ ln conftest.a conftest.b 2>&5 || hard_links=no ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ AC_MSG_RESULT([$hard_links]) ++ if test no = "$hard_links"; then ++ AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) ++ need_locks=warn ++ fi ++else ++ need_locks=no ++fi ++_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ++])# _LT_COMPILER_FILE_LOCKS ++ ++ ++# _LT_CHECK_OBJDIR ++# ---------------- ++m4_defun([_LT_CHECK_OBJDIR], ++[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], ++[rm -f .libs 2>/dev/null ++mkdir .libs 2>/dev/null ++if test -d .libs; then ++ lt_cv_objdir=.libs ++else ++ # MS-DOS does not allow filenames that begin with a dot. ++ lt_cv_objdir=_libs ++fi ++rmdir .libs 2>/dev/null]) ++objdir=$lt_cv_objdir ++_LT_DECL([], [objdir], [0], ++ [The name of the directory that contains temporary libtool files])dnl ++m4_pattern_allow([LT_OBJDIR])dnl ++AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", ++ [Define to the sub-directory where libtool stores uninstalled libraries.]) ++])# _LT_CHECK_OBJDIR ++ ++ ++# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) ++# -------------------------------------- ++# Check hardcoding attributes. ++m4_defun([_LT_LINKER_HARDCODE_LIBPATH], ++[AC_MSG_CHECKING([how to hardcode library paths into programs]) ++_LT_TAGVAR(hardcode_action, $1)= ++if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || ++ test -n "$_LT_TAGVAR(runpath_var, $1)" || ++ test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then ++ ++ # We can hardcode non-existent directories. ++ if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && ++ # If the only mechanism to avoid hardcoding is shlibpath_var, we ++ # have to relink, otherwise we might link with an installed library ++ # when we should be linking with a yet-to-be-installed one ++ ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && ++ test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then ++ # Linking always hardcodes the temporary library directory. ++ _LT_TAGVAR(hardcode_action, $1)=relink ++ else ++ # We can link without hardcoding, and we can hardcode nonexisting dirs. ++ _LT_TAGVAR(hardcode_action, $1)=immediate ++ fi ++else ++ # We cannot hardcode anything, or else we can only hardcode existing ++ # directories. ++ _LT_TAGVAR(hardcode_action, $1)=unsupported ++fi ++AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) ++ ++if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || ++ test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then ++ # Fast installation is not supported ++ enable_fast_install=no ++elif test yes = "$shlibpath_overrides_runpath" || ++ test no = "$enable_shared"; then ++ # Fast installation is not necessary ++ enable_fast_install=needless ++fi ++_LT_TAGDECL([], [hardcode_action], [0], ++ [How to hardcode a shared library path into an executable]) ++])# _LT_LINKER_HARDCODE_LIBPATH ++ ++ ++# _LT_CMD_STRIPLIB ++# ---------------- ++m4_defun([_LT_CMD_STRIPLIB], ++[m4_require([_LT_DECL_EGREP]) ++striplib= ++old_striplib= ++AC_MSG_CHECKING([whether stripping libraries is possible]) ++if test -z "$STRIP"; then ++ AC_MSG_RESULT([no]) ++else ++ if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then ++ old_striplib="$STRIP --strip-debug" ++ striplib="$STRIP --strip-unneeded" ++ AC_MSG_RESULT([yes]) ++ else ++ case $host_os in ++ darwin*) ++ # FIXME - insert some real tests, host_os isn't really good enough ++ striplib="$STRIP -x" ++ old_striplib="$STRIP -S" ++ AC_MSG_RESULT([yes]) ++ ;; ++ freebsd*) ++ if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then ++ old_striplib="$STRIP --strip-debug" ++ striplib="$STRIP --strip-unneeded" ++ AC_MSG_RESULT([yes]) ++ else ++ AC_MSG_RESULT([no]) ++ fi ++ ;; ++ *) ++ AC_MSG_RESULT([no]) ++ ;; ++ esac ++ fi ++fi ++_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) ++_LT_DECL([], [striplib], [1]) ++])# _LT_CMD_STRIPLIB ++ ++ ++# _LT_PREPARE_MUNGE_PATH_LIST ++# --------------------------- ++# Make sure func_munge_path_list() is defined correctly. ++m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], ++[[# func_munge_path_list VARIABLE PATH ++# ----------------------------------- ++# VARIABLE is name of variable containing _space_ separated list of ++# directories to be munged by the contents of PATH, which is string ++# having a format: ++# "DIR[:DIR]:" ++# string "DIR[ DIR]" will be prepended to VARIABLE ++# ":DIR[:DIR]" ++# string "DIR[ DIR]" will be appended to VARIABLE ++# "DIRP[:DIRP]::[DIRA:]DIRA" ++# string "DIRP[ DIRP]" will be prepended to VARIABLE and string ++# "DIRA[ DIRA]" will be appended to VARIABLE ++# "DIR[:DIR]" ++# VARIABLE will be replaced by "DIR[ DIR]" ++func_munge_path_list () ++{ ++ case x@S|@2 in ++ x) ++ ;; ++ *:) ++ eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" ++ ;; ++ x:*) ++ eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" ++ ;; ++ *::*) ++ eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" ++ eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" ++ ;; ++ *) ++ eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" ++ ;; ++ esac ++} ++]])# _LT_PREPARE_PATH_LIST ++ ++ ++# _LT_SYS_DYNAMIC_LINKER([TAG]) ++# ----------------------------- ++# PORTME Fill in your ld.so characteristics ++m4_defun([_LT_SYS_DYNAMIC_LINKER], ++[AC_REQUIRE([AC_CANONICAL_HOST])dnl ++m4_require([_LT_DECL_EGREP])dnl ++m4_require([_LT_FILEUTILS_DEFAULTS])dnl ++m4_require([_LT_DECL_OBJDUMP])dnl ++m4_require([_LT_DECL_SED])dnl ++m4_require([_LT_CHECK_SHELL_FEATURES])dnl ++m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl ++AC_MSG_CHECKING([dynamic linker characteristics]) ++m4_if([$1], ++ [], [ ++if test yes = "$GCC"; then ++ case $host_os in ++ darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; ++ *) lt_awk_arg='/^libraries:/' ;; ++ esac ++ case $host_os in ++ mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; ++ *) lt_sed_strip_eq='s|=/|/|g' ;; ++ esac ++ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` ++ case $lt_search_path_spec in ++ *\;*) ++ # if the path contains ";" then we assume it to be the separator ++ # otherwise default to the standard path separator (i.e. ":") - it is ++ # assumed that no part of a normal pathname contains ";" but that should ++ # okay in the real world where ";" in dirpaths is itself problematic. ++ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ++ ;; ++ *) ++ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ++ ;; ++ esac ++ # Ok, now we have the path, separated by spaces, we can step through it ++ # and add multilib dir if necessary... ++ lt_tmp_lt_search_path_spec= ++ lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` ++ # ...but if some path component already ends with the multilib dir we assume ++ # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). ++ case "$lt_multi_os_dir; $lt_search_path_spec " in ++ "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) ++ lt_multi_os_dir= ++ ;; ++ esac ++ for lt_sys_path in $lt_search_path_spec; do ++ if test -d "$lt_sys_path$lt_multi_os_dir"; then ++ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" ++ elif test -n "$lt_multi_os_dir"; then ++ test -d "$lt_sys_path" && \ ++ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" ++ fi ++ done ++ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' ++BEGIN {RS = " "; FS = "/|\n";} { ++ lt_foo = ""; ++ lt_count = 0; ++ for (lt_i = NF; lt_i > 0; lt_i--) { ++ if ($lt_i != "" && $lt_i != ".") { ++ if ($lt_i == "..") { ++ lt_count++; ++ } else { ++ if (lt_count == 0) { ++ lt_foo = "/" $lt_i lt_foo; ++ } else { ++ lt_count--; ++ } ++ } ++ } ++ } ++ if (lt_foo != "") { lt_freq[[lt_foo]]++; } ++ if (lt_freq[[lt_foo]] == 1) { print lt_foo; } ++}'` ++ # AWK program above erroneously prepends '/' to C:/dos/paths ++ # for these hosts. ++ case $host_os in ++ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ ++ $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; ++ esac ++ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` ++else ++ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" ++fi]) ++library_names_spec= ++libname_spec='lib$name' ++soname_spec= ++shrext_cmds=.so ++postinstall_cmds= ++postuninstall_cmds= ++finish_cmds= ++finish_eval= ++shlibpath_var= ++shlibpath_overrides_runpath=unknown ++version_type=none ++dynamic_linker="$host_os ld.so" ++sys_lib_dlsearch_path_spec="/lib /usr/lib" ++need_lib_prefix=unknown ++hardcode_into_libs=no ++ ++# when you set need_version to no, make sure it does not cause -set_version ++# flags to be left without arguments ++need_version=unknown ++ ++AC_ARG_VAR([LT_SYS_LIBRARY_PATH], ++[User-defined run-time library search path.]) ++ ++case $host_os in ++aix3*) ++ version_type=linux # correct to gnu/linux during the next big refactor ++ library_names_spec='$libname$release$shared_ext$versuffix $libname.a' ++ shlibpath_var=LIBPATH ++ ++ # AIX 3 has no versioning support, so we append a major version to the name. ++ soname_spec='$libname$release$shared_ext$major' ++ ;; ++ ++aix[[4-9]]*) ++ version_type=linux # correct to gnu/linux during the next big refactor ++ need_lib_prefix=no ++ need_version=no ++ hardcode_into_libs=yes ++ if test ia64 = "$host_cpu"; then ++ # AIX 5 supports IA64 ++ library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' ++ shlibpath_var=LD_LIBRARY_PATH ++ else ++ # With GCC up to 2.95.x, collect2 would create an import file ++ # for dependence libraries. The import file would start with ++ # the line '#! .'. This would cause the generated library to ++ # depend on '.', always an invalid library. This was fixed in ++ # development snapshots of GCC prior to 3.0. ++ case $host_os in ++ aix4 | aix4.[[01]] | aix4.[[01]].*) ++ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' ++ echo ' yes ' ++ echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then ++ : ++ else ++ can_build_shared=no ++ fi ++ ;; ++ esac ++ # Using Import Files as archive members, it is possible to support ++ # filename-based versioning of shared library archives on AIX. While ++ # this would work for both with and without runtime linking, it will ++ # prevent static linking of such archives. So we do filename-based ++ # shared library versioning with .so extension only, which is used ++ # when both runtime linking and shared linking is enabled. ++ # Unfortunately, runtime linking may impact performance, so we do ++ # not want this to be the default eventually. Also, we use the ++ # versioned .so libs for executables only if there is the -brtl ++ # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. ++ # To allow for filename-based versioning support, we need to create ++ # libNAME.so.V as an archive file, containing: ++ # *) an Import File, referring to the versioned filename of the ++ # archive as well as the shared archive member, telling the ++ # bitwidth (32 or 64) of that shared object, and providing the ++ # list of exported symbols of that shared object, eventually ++ # decorated with the 'weak' keyword ++ # *) the shared object with the F_LOADONLY flag set, to really avoid ++ # it being seen by the linker. ++ # At run time we better use the real file rather than another symlink, ++ # but for link time we create the symlink libNAME.so -> libNAME.so.V ++ ++ case $with_aix_soname,$aix_use_runtimelinking in ++ # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct ++ # soname into executable. Probably we can add versioning support to ++ # collect2, so additional links can be useful in future. ++ aix,yes) # traditional libtool ++ dynamic_linker='AIX unversionable lib.so' ++ # If using run time linking (on AIX 4.2 or later) use lib.so ++ # instead of lib.a to let people know that these are not ++ # typical AIX shared libraries. ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ ;; ++ aix,no) # traditional AIX only ++ dynamic_linker='AIX lib.a[(]lib.so.V[)]' ++ # We preserve .a as extension for shared libraries through AIX4.2 ++ # and later when we are not doing run time linking. ++ library_names_spec='$libname$release.a $libname.a' ++ soname_spec='$libname$release$shared_ext$major' ++ ;; ++ svr4,*) # full svr4 only ++ dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" ++ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' ++ # We do not specify a path in Import Files, so LIBPATH fires. ++ shlibpath_overrides_runpath=yes ++ ;; ++ *,yes) # both, prefer svr4 ++ dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" ++ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' ++ # unpreferred sharedlib libNAME.a needs extra handling ++ postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' ++ postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' ++ # We do not specify a path in Import Files, so LIBPATH fires. ++ shlibpath_overrides_runpath=yes ++ ;; ++ *,no) # both, prefer aix ++ dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" ++ library_names_spec='$libname$release.a $libname.a' ++ soname_spec='$libname$release$shared_ext$major' ++ # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling ++ postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' ++ postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ++ ;; ++ esac ++ shlibpath_var=LIBPATH ++ fi ++ ;; ++ ++amigaos*) ++ case $host_cpu in ++ powerpc) ++ # Since July 2007 AmigaOS4 officially supports .so libraries. ++ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ ;; ++ m68k) ++ library_names_spec='$libname.ixlibrary $libname.a' ++ # Create ${libname}_ixlibrary.a entries in /sys/libs. ++ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ++ ;; ++ esac ++ ;; ++ ++beos*) ++ library_names_spec='$libname$shared_ext' ++ dynamic_linker="$host_os ld.so" ++ shlibpath_var=LIBRARY_PATH ++ ;; ++ ++bsdi[[45]]*) ++ version_type=linux # correct to gnu/linux during the next big refactor ++ need_version=no ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" ++ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" ++ # the default ld.so.conf also contains /usr/contrib/lib and ++ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow ++ # libtool to hard-code these into programs ++ ;; ++ ++cygwin* | mingw* | pw32* | cegcc*) ++ version_type=windows ++ shrext_cmds=.dll ++ need_version=no ++ need_lib_prefix=no ++ ++ case $GCC,$cc_basename in ++ yes,*) ++ # gcc ++ library_names_spec='$libname.dll.a' ++ # DLL is installed to $(libdir)/../bin by postinstall_cmds ++ postinstall_cmds='base_file=`basename \$file`~ ++ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ ++ dldir=$destdir/`dirname \$dlpath`~ ++ test -d \$dldir || mkdir -p \$dldir~ ++ $install_prog $dir/$dlname \$dldir/$dlname~ ++ chmod a+x \$dldir/$dlname~ ++ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then ++ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; ++ fi' ++ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ ++ dlpath=$dir/\$dldll~ ++ $RM \$dlpath' ++ shlibpath_overrides_runpath=yes ++ ++ case $host_os in ++ cygwin*) ++ # Cygwin DLLs use 'cyg' prefix rather than 'lib' ++ soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ++m4_if([$1], [],[ ++ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ++ ;; ++ mingw* | cegcc*) ++ # MinGW DLLs use traditional 'lib' prefix ++ soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ++ ;; ++ pw32*) ++ # pw32 DLLs use 'pw' prefix rather than 'lib' ++ library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ++ ;; ++ esac ++ dynamic_linker='Win32 ld.exe' ++ ;; ++ ++ *,cl* | *,icl*) ++ # Native MSVC or ICC ++ libname_spec='$name' ++ soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ++ library_names_spec='$libname.dll.lib' ++ ++ case $build_os in ++ mingw*) ++ sys_lib_search_path_spec= ++ lt_save_ifs=$IFS ++ IFS=';' ++ for lt_path in $LIB ++ do ++ IFS=$lt_save_ifs ++ # Let DOS variable expansion print the short 8.3 style file name. ++ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` ++ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" ++ done ++ IFS=$lt_save_ifs ++ # Convert to MSYS style. ++ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ++ ;; ++ cygwin*) ++ # Convert to unix form, then to dos form, then back to unix form ++ # but this time dos style (no spaces!) so that the unix form looks ++ # like /cygdrive/c/PROGRA~1:/cygdr... ++ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` ++ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` ++ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ ;; ++ *) ++ sys_lib_search_path_spec=$LIB ++ if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then ++ # It is most probably a Windows format PATH. ++ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi ++ # FIXME: find the short name or the path components, as spaces are ++ # common. (e.g. "Program Files" -> "PROGRA~1") ++ ;; ++ esac ++ ++ # DLL is installed to $(libdir)/../bin by postinstall_cmds ++ postinstall_cmds='base_file=`basename \$file`~ ++ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ ++ dldir=$destdir/`dirname \$dlpath`~ ++ test -d \$dldir || mkdir -p \$dldir~ ++ $install_prog $dir/$dlname \$dldir/$dlname' ++ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ ++ dlpath=$dir/\$dldll~ ++ $RM \$dlpath' ++ shlibpath_overrides_runpath=yes ++ dynamic_linker='Win32 link.exe' ++ ;; ++ ++ *) ++ # Assume MSVC and ICC wrapper ++ library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' ++ dynamic_linker='Win32 ld.exe' ++ ;; ++ esac ++ # FIXME: first we should search . and the directory the executable is in ++ shlibpath_var=PATH ++ ;; ++ ++darwin* | rhapsody*) ++ dynamic_linker="$host_os dyld" ++ version_type=darwin ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' ++ soname_spec='$libname$release$major$shared_ext' ++ shlibpath_overrides_runpath=yes ++ shlibpath_var=DYLD_LIBRARY_PATH ++ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' ++m4_if([$1], [],[ ++ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) ++ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ++ ;; ++ ++dgux*) ++ version_type=linux # correct to gnu/linux during the next big refactor ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++freebsd* | dragonfly* | midnightbsd*) ++ # DragonFly does not have aout. When/if they implement a new ++ # versioning mechanism, adjust this. ++ if test -x /usr/bin/objformat; then ++ objformat=`/usr/bin/objformat` ++ else ++ case $host_os in ++ freebsd[[23]].*) objformat=aout ;; ++ *) objformat=elf ;; ++ esac ++ fi ++ version_type=freebsd-$objformat ++ case $version_type in ++ freebsd-elf*) ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ need_version=no ++ need_lib_prefix=no ++ ;; ++ freebsd-*) ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' ++ need_version=yes ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_os in ++ freebsd2.*) ++ shlibpath_overrides_runpath=yes ++ ;; ++ freebsd3.[[01]]* | freebsdelf3.[[01]]*) ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ ++ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ *) # from 4.6 on, and DragonFly ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ esac ++ ;; ++ ++haiku*) ++ version_type=linux # correct to gnu/linux during the next big refactor ++ need_lib_prefix=no ++ need_version=no ++ dynamic_linker="$host_os runtime_loader" ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ shlibpath_var=LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' ++ hardcode_into_libs=yes ++ ;; ++ ++hpux9* | hpux10* | hpux11*) ++ # Give a soname corresponding to the major version so that dld.sl refuses to ++ # link against other versions. ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ case $host_cpu in ++ ia64*) ++ shrext_cmds='.so' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.so" ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ if test 32 = "$HPUX_IA64_MODE"; then ++ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" ++ sys_lib_dlsearch_path_spec=/usr/lib/hpux32 ++ else ++ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" ++ sys_lib_dlsearch_path_spec=/usr/lib/hpux64 ++ fi ++ ;; ++ hppa*64*) ++ shrext_cmds='.sl' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ *) ++ shrext_cmds='.sl' ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=SHLIB_PATH ++ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ ;; ++ esac ++ # HP-UX runs *really* slowly unless shared libraries are mode 555, ... ++ postinstall_cmds='chmod 555 $lib' ++ # or fails outright, so override atomically: ++ install_override_mode=555 ++ ;; ++ ++interix[[3-9]]*) ++ version_type=linux # correct to gnu/linux during the next big refactor ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ ++irix5* | irix6* | nonstopux*) ++ case $host_os in ++ nonstopux*) version_type=nonstopux ;; ++ *) ++ if test yes = "$lt_cv_prog_gnu_ld"; then ++ version_type=linux # correct to gnu/linux during the next big refactor ++ else ++ version_type=irix ++ fi ;; ++ esac ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='$libname$release$shared_ext$major' ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' ++ case $host_os in ++ irix5* | nonstopux*) ++ libsuff= shlibsuff= ++ ;; ++ *) ++ case $LD in # libtool.m4 will add one of these switches to LD ++ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") ++ libsuff= shlibsuff= libmagic=32-bit;; ++ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") ++ libsuff=32 shlibsuff=N32 libmagic=N32;; ++ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") ++ libsuff=64 shlibsuff=64 libmagic=64-bit;; ++ *) libsuff= shlibsuff= libmagic=never-match;; ++ esac ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" ++ sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" ++ hardcode_into_libs=yes ++ ;; ++ ++# No shared lib support for Linux oldld, aout, or coff. ++linux*oldld* | linux*aout* | linux*coff*) ++ dynamic_linker=no ++ ;; ++ ++linux*android*) ++ version_type=none # Android doesn't support versioned libraries. ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='$libname$release$shared_ext' ++ soname_spec='$libname$release$shared_ext' ++ finish_cmds= ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ++ # This implies no fast_install, which is unacceptable. ++ # Some rework will be needed to allow for fast_install ++ # before this can be enabled. ++ hardcode_into_libs=yes ++ ++ dynamic_linker='Android linker' ++ # Don't embed -rpath directories since the linker doesn't support them. ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ ;; ++ ++# This must be glibc/ELF. ++linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) ++ version_type=linux # correct to gnu/linux during the next big refactor ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ ++ # Some binutils ld are patched to set DT_RUNPATH ++ AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], ++ [lt_cv_shlibpath_overrides_runpath=no ++ save_LDFLAGS=$LDFLAGS ++ save_libdir=$libdir ++ eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ ++ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" ++ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], ++ [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], ++ [lt_cv_shlibpath_overrides_runpath=yes])]) ++ LDFLAGS=$save_LDFLAGS ++ libdir=$save_libdir ++ ]) ++ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath ++ ++ # This implies no fast_install, which is unacceptable. ++ # Some rework will be needed to allow for fast_install ++ # before this can be enabled. ++ hardcode_into_libs=yes ++ ++ # Ideally, we could use ldconfig to report *all* directores which are ++ # searched for libraries, however this is still not possible. Aside from not ++ # being certain /sbin/ldconfig is available, command ++ # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, ++ # even though it is searched at run-time. Try to do the best guess by ++ # appending ld.so.conf contents (and includes) to the search path. ++ if test -f /etc/ld.so.conf; then ++ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` ++ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" ++ fi ++ ++ # We used to test for /lib/ld.so.1 and disable shared libraries on ++ # powerpc, because MkLinux only supported shared libraries with the ++ # GNU dynamic linker. Since this was broken with cross compilers, ++ # most powerpc-linux boxes support dynamic linking these days and ++ # people can always --disable-shared, the test was removed, and we ++ # assume the GNU/Linux dynamic linker is in use. ++ dynamic_linker='GNU/Linux ld.so' ++ ;; ++ ++netbsd*) ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' ++ dynamic_linker='NetBSD (a.out) ld.so' ++ else ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ dynamic_linker='NetBSD ld.elf_so' ++ fi ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ ++newsos6) ++ version_type=linux # correct to gnu/linux during the next big refactor ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++*nto* | *qnx*) ++ version_type=qnx ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='ldqnx.so' ++ ;; ++ ++openbsd* | bitrig*) ++ version_type=sunos ++ sys_lib_dlsearch_path_spec=/usr/lib ++ need_lib_prefix=no ++ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then ++ need_version=no ++ else ++ need_version=yes ++ fi ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++os2*) ++ libname_spec='$name' ++ version_type=windows ++ shrext_cmds=.dll ++ need_version=no ++ need_lib_prefix=no ++ # OS/2 can only load a DLL with a base name of 8 characters or less. ++ soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; ++ v=$($ECHO $release$versuffix | tr -d .-); ++ n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); ++ $ECHO $n$v`$shared_ext' ++ library_names_spec='${libname}_dll.$libext' ++ dynamic_linker='OS/2 ld.exe' ++ shlibpath_var=BEGINLIBPATH ++ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ postinstall_cmds='base_file=`basename \$file`~ ++ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ ++ dldir=$destdir/`dirname \$dlpath`~ ++ test -d \$dldir || mkdir -p \$dldir~ ++ $install_prog $dir/$dlname \$dldir/$dlname~ ++ chmod a+x \$dldir/$dlname~ ++ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then ++ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; ++ fi' ++ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ ++ dlpath=$dir/\$dldll~ ++ $RM \$dlpath' ++ ;; ++ ++osf3* | osf4* | osf5*) ++ version_type=osf ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='$libname$release$shared_ext$major' ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ ++rdos*) ++ dynamic_linker=no ++ ;; ++ ++solaris*) ++ version_type=linux # correct to gnu/linux during the next big refactor ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ # ldd complains unless libraries are executable ++ postinstall_cmds='chmod +x $lib' ++ ;; ++ ++sunos4*) ++ version_type=sunos ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' ++ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ if test yes = "$with_gnu_ld"; then ++ need_lib_prefix=no ++ fi ++ need_version=yes ++ ;; ++ ++sysv4 | sysv4.3*) ++ version_type=linux # correct to gnu/linux during the next big refactor ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_vendor in ++ sni) ++ shlibpath_overrides_runpath=no ++ need_lib_prefix=no ++ runpath_var=LD_RUN_PATH ++ ;; ++ siemens) ++ need_lib_prefix=no ++ ;; ++ motorola) ++ need_lib_prefix=no ++ need_version=no ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ++ ;; ++ esac ++ ;; ++ ++sysv4*MP*) ++ if test -d /usr/nec; then ++ version_type=linux # correct to gnu/linux during the next big refactor ++ library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' ++ soname_spec='$libname$shared_ext.$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ fi ++ ;; ++ ++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) ++ version_type=sco ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ if test yes = "$with_gnu_ld"; then ++ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' ++ else ++ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' ++ case $host_os in ++ sco3.2v5*) ++ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ++ ;; ++ esac ++ fi ++ sys_lib_dlsearch_path_spec='/usr/lib' ++ ;; ++ ++tpf*) ++ # TPF is a cross-target only. Preferred cross-host = GNU/Linux. ++ version_type=linux # correct to gnu/linux during the next big refactor ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ ++uts4*) ++ version_type=linux # correct to gnu/linux during the next big refactor ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++*) ++ dynamic_linker=no ++ ;; ++esac ++AC_MSG_RESULT([$dynamic_linker]) ++test no = "$dynamic_linker" && can_build_shared=no ++ ++variables_saved_for_relink="PATH $shlibpath_var $runpath_var" ++if test yes = "$GCC"; then ++ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" ++fi ++ ++if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then ++ sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec ++fi ++ ++if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then ++ sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec ++fi ++ ++# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... ++configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec ++ ++# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code ++func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" ++ ++# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool ++configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH ++ ++_LT_DECL([], [variables_saved_for_relink], [1], ++ [Variables whose values should be saved in libtool wrapper scripts and ++ restored at link time]) ++_LT_DECL([], [need_lib_prefix], [0], ++ [Do we need the "lib" prefix for modules?]) ++_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) ++_LT_DECL([], [version_type], [0], [Library versioning type]) ++_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) ++_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) ++_LT_DECL([], [shlibpath_overrides_runpath], [0], ++ [Is shlibpath searched before the hard-coded library search path?]) ++_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) ++_LT_DECL([], [library_names_spec], [1], ++ [[List of archive names. First name is the real one, the rest are links. ++ The last name is the one that the linker finds with -lNAME]]) ++_LT_DECL([], [soname_spec], [1], ++ [[The coded name of the library, if different from the real name]]) ++_LT_DECL([], [install_override_mode], [1], ++ [Permission mode override for installation of shared libraries]) ++_LT_DECL([], [postinstall_cmds], [2], ++ [Command to use after installation of a shared archive]) ++_LT_DECL([], [postuninstall_cmds], [2], ++ [Command to use after uninstallation of a shared archive]) ++_LT_DECL([], [finish_cmds], [2], ++ [Commands used to finish a libtool library installation in a directory]) ++_LT_DECL([], [finish_eval], [1], ++ [[As "finish_cmds", except a single script fragment to be evaled but ++ not shown]]) ++_LT_DECL([], [hardcode_into_libs], [0], ++ [Whether we should hardcode library paths into libraries]) ++_LT_DECL([], [sys_lib_search_path_spec], [2], ++ [Compile-time system search path for libraries]) ++_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], ++ [Detected run-time system search path for libraries]) ++_LT_DECL([], [configure_time_lt_sys_library_path], [2], ++ [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) ++])# _LT_SYS_DYNAMIC_LINKER ++ ++ ++# _LT_PATH_TOOL_PREFIX(TOOL) ++# -------------------------- ++# find a file program that can recognize shared library ++AC_DEFUN([_LT_PATH_TOOL_PREFIX], ++[m4_require([_LT_DECL_EGREP])dnl ++AC_MSG_CHECKING([for $1]) ++AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, ++[case $MAGIC_CMD in ++[[\\/*] | ?:[\\/]*]) ++ lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ++ ;; ++*) ++ lt_save_MAGIC_CMD=$MAGIC_CMD ++ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ++dnl $ac_dummy forces splitting on constant user-supplied paths. ++dnl POSIX.2 word splitting is done only on the output of word expansions, ++dnl not every word. This closes a longstanding sh security hole. ++ ac_dummy="m4_if([$2], , $PATH, [$2])" ++ for ac_dir in $ac_dummy; do ++ IFS=$lt_save_ifs ++ test -z "$ac_dir" && ac_dir=. ++ if test -f "$ac_dir/$1"; then ++ lt_cv_path_MAGIC_CMD=$ac_dir/"$1" ++ if test -n "$file_magic_test_file"; then ++ case $deplibs_check_method in ++ "file_magic "*) ++ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` ++ MAGIC_CMD=$lt_cv_path_MAGIC_CMD ++ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | ++ $EGREP "$file_magic_regex" > /dev/null; then ++ : ++ else ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: the command libtool uses to detect shared libraries, ++*** $file_magic_cmd, produces output that libtool cannot recognize. ++*** The result is that libtool may fail to recognize shared libraries ++*** as such. This will affect the creation of libtool libraries that ++*** depend on shared libraries, but programs linked with such libtool ++*** libraries will work regardless of this problem. Nevertheless, you ++*** may want to report the problem to your system manager and/or to ++*** bug-libtool@gnu.org ++ ++_LT_EOF ++ fi ;; ++ esac ++ fi ++ break ++ fi ++ done ++ IFS=$lt_save_ifs ++ MAGIC_CMD=$lt_save_MAGIC_CMD ++ ;; ++esac]) ++MAGIC_CMD=$lt_cv_path_MAGIC_CMD ++if test -n "$MAGIC_CMD"; then ++ AC_MSG_RESULT($MAGIC_CMD) ++else ++ AC_MSG_RESULT(no) ++fi ++_LT_DECL([], [MAGIC_CMD], [0], ++ [Used to examine libraries when file_magic_cmd begins with "file"])dnl ++])# _LT_PATH_TOOL_PREFIX ++ ++# Old name: ++AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) ++ ++ ++# _LT_PATH_MAGIC ++# -------------- ++# find a file program that can recognize a shared library ++m4_defun([_LT_PATH_MAGIC], ++[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) ++if test -z "$lt_cv_path_MAGIC_CMD"; then ++ if test -n "$ac_tool_prefix"; then ++ _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) ++ else ++ MAGIC_CMD=: ++ fi ++fi ++])# _LT_PATH_MAGIC ++ ++ ++# LT_PATH_LD ++# ---------- ++# find the pathname to the GNU or non-GNU linker ++AC_DEFUN([LT_PATH_LD], ++[AC_REQUIRE([AC_PROG_CC])dnl ++AC_REQUIRE([AC_CANONICAL_HOST])dnl ++AC_REQUIRE([AC_CANONICAL_BUILD])dnl ++m4_require([_LT_DECL_SED])dnl ++m4_require([_LT_DECL_EGREP])dnl ++m4_require([_LT_PROG_ECHO_BACKSLASH])dnl ++ ++AC_ARG_WITH([gnu-ld], ++ [AS_HELP_STRING([--with-gnu-ld], ++ [assume the C compiler uses GNU ld @<:@default=no@:>@])], ++ [test no = "$withval" || with_gnu_ld=yes], ++ [with_gnu_ld=no])dnl ++ ++ac_prog=ld ++if test yes = "$GCC"; then ++ # Check if gcc -print-prog-name=ld gives a path. ++ AC_MSG_CHECKING([for ld used by $CC]) ++ case $host in ++ *-*-mingw*) ++ # gcc leaves a trailing carriage return, which upsets mingw ++ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; ++ *) ++ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; ++ esac ++ case $ac_prog in ++ # Accept absolute paths. ++ [[\\/]]* | ?:[[\\/]]*) ++ re_direlt='/[[^/]][[^/]]*/\.\./' ++ # Canonicalize the pathname of ld ++ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` ++ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ++ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` ++ done ++ test -z "$LD" && LD=$ac_prog ++ ;; ++ "") ++ # If it fails, then pretend we aren't using GCC. ++ ac_prog=ld ++ ;; ++ *) ++ # If it is relative, then search for the first ld in PATH. ++ with_gnu_ld=unknown ++ ;; ++ esac ++elif test yes = "$with_gnu_ld"; then ++ AC_MSG_CHECKING([for GNU ld]) ++else ++ AC_MSG_CHECKING([for non-GNU ld]) ++fi ++AC_CACHE_VAL(lt_cv_path_LD, ++[if test -z "$LD"; then ++ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ++ for ac_dir in $PATH; do ++ IFS=$lt_save_ifs ++ test -z "$ac_dir" && ac_dir=. ++ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then ++ lt_cv_path_LD=$ac_dir/$ac_prog ++ # Check to see if the program is GNU ld. I'd rather use --version, ++ # but apparently some variants of GNU ld only accept -v. ++ # Break only if it was the GNU/non-GNU ld that we prefer. ++ case `"$lt_cv_path_LD" -v 2>&1 &1 conftest.i ++cat conftest.i conftest.i >conftest2.i ++: ${lt_DD:=$DD} ++AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], ++[if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then ++ cmp -s conftest.i conftest.out \ ++ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: ++fi]) ++rm -f conftest.i conftest2.i conftest.out]) ++])# _LT_PATH_DD ++ ++ ++# _LT_CMD_TRUNCATE ++# ---------------- ++# find command to truncate a binary pipe ++m4_defun([_LT_CMD_TRUNCATE], ++[m4_require([_LT_PATH_DD]) ++AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], ++[printf 0123456789abcdef0123456789abcdef >conftest.i ++cat conftest.i conftest.i >conftest2.i ++lt_cv_truncate_bin= ++if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then ++ cmp -s conftest.i conftest.out \ ++ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" ++fi ++rm -f conftest.i conftest2.i conftest.out ++test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) ++_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], ++ [Command to truncate a binary pipe]) ++])# _LT_CMD_TRUNCATE ++ ++ ++# _LT_CHECK_MAGIC_METHOD ++# ---------------------- ++# how to check for library dependencies ++# -- PORTME fill in with the dynamic library characteristics ++m4_defun([_LT_CHECK_MAGIC_METHOD], ++[m4_require([_LT_DECL_EGREP]) ++m4_require([_LT_DECL_OBJDUMP]) ++AC_CACHE_CHECK([how to recognize dependent libraries], ++lt_cv_deplibs_check_method, ++[lt_cv_file_magic_cmd='$MAGIC_CMD' ++lt_cv_file_magic_test_file= ++lt_cv_deplibs_check_method='unknown' ++# Need to set the preceding variable on all platforms that support ++# interlibrary dependencies. ++# 'none' -- dependencies not supported. ++# 'unknown' -- same as none, but documents that we really don't know. ++# 'pass_all' -- all dependencies passed with no checks. ++# 'test_compile' -- check by making test program. ++# 'file_magic [[regex]]' -- check by looking for files in library path ++# that responds to the $file_magic_cmd with a given extended regex. ++# If you have 'file' or equivalent on your system and you're not sure ++# whether 'pass_all' will *always* work, you probably want this one. ++ ++case $host_os in ++aix[[4-9]]*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++beos*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++bsdi[[45]]*) ++ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' ++ lt_cv_file_magic_cmd='$FILECMD -L' ++ lt_cv_file_magic_test_file=/shlib/libc.so ++ ;; ++ ++cygwin*) ++ # func_win32_libid is a shell function defined in ltmain.sh ++ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' ++ lt_cv_file_magic_cmd='func_win32_libid' ++ ;; ++ ++mingw* | pw32*) ++ # Base MSYS/MinGW do not provide the 'file' command needed by ++ # func_win32_libid shell function, so use a weaker test based on 'objdump', ++ # unless we find 'file', for example because we are cross-compiling. ++ if ( file / ) >/dev/null 2>&1; then ++ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' ++ lt_cv_file_magic_cmd='func_win32_libid' ++ else ++ # Keep this pattern in sync with the one in func_win32_libid. ++ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' ++ lt_cv_file_magic_cmd='$OBJDUMP -f' ++ fi ++ ;; ++ ++cegcc*) ++ # use the weaker test based on 'objdump'. See mingw*. ++ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' ++ lt_cv_file_magic_cmd='$OBJDUMP -f' ++ ;; ++ ++darwin* | rhapsody*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++freebsd* | dragonfly* | midnightbsd*) ++ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then ++ case $host_cpu in ++ i*86 ) ++ # Not sure whether the presence of OpenBSD here was a mistake. ++ # Let's accept both of them until this is cleared up. ++ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' ++ lt_cv_file_magic_cmd=$FILECMD ++ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ++ ;; ++ esac ++ else ++ lt_cv_deplibs_check_method=pass_all ++ fi ++ ;; ++ ++haiku*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++hpux10.20* | hpux11*) ++ lt_cv_file_magic_cmd=$FILECMD ++ case $host_cpu in ++ ia64*) ++ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' ++ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ++ ;; ++ hppa*64*) ++ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] ++ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ++ ;; ++ *) ++ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' ++ lt_cv_file_magic_test_file=/usr/lib/libc.sl ++ ;; ++ esac ++ ;; ++ ++interix[[3-9]]*) ++ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here ++ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ++ ;; ++ ++irix5* | irix6* | nonstopux*) ++ case $LD in ++ *-32|*"-32 ") libmagic=32-bit;; ++ *-n32|*"-n32 ") libmagic=N32;; ++ *-64|*"-64 ") libmagic=64-bit;; ++ *) libmagic=never-match;; ++ esac ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++# This must be glibc/ELF. ++linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++netbsd*) ++ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then ++ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' ++ else ++ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' ++ fi ++ ;; ++ ++newos6*) ++ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' ++ lt_cv_file_magic_cmd=$FILECMD ++ lt_cv_file_magic_test_file=/usr/lib/libnls.so ++ ;; ++ ++*nto* | *qnx*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++openbsd* | bitrig*) ++ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then ++ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' ++ else ++ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' ++ fi ++ ;; ++ ++osf3* | osf4* | osf5*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++rdos*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++solaris*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++sysv4 | sysv4.3*) ++ case $host_vendor in ++ motorola) ++ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' ++ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ++ ;; ++ ncr) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ sequent) ++ lt_cv_file_magic_cmd='/bin/file' ++ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ++ ;; ++ sni) ++ lt_cv_file_magic_cmd='/bin/file' ++ lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" ++ lt_cv_file_magic_test_file=/lib/libc.so ++ ;; ++ siemens) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ pc) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ esac ++ ;; ++ ++tpf*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++os2*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++esac ++]) ++ ++file_magic_glob= ++want_nocaseglob=no ++if test "$build" = "$host"; then ++ case $host_os in ++ mingw* | pw32*) ++ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then ++ want_nocaseglob=yes ++ else ++ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` ++ fi ++ ;; ++ esac ++fi ++ ++file_magic_cmd=$lt_cv_file_magic_cmd ++deplibs_check_method=$lt_cv_deplibs_check_method ++test -z "$deplibs_check_method" && deplibs_check_method=unknown ++ ++_LT_DECL([], [deplibs_check_method], [1], ++ [Method to check whether dependent libraries are shared objects]) ++_LT_DECL([], [file_magic_cmd], [1], ++ [Command to use when deplibs_check_method = "file_magic"]) ++_LT_DECL([], [file_magic_glob], [1], ++ [How to find potential files when deplibs_check_method = "file_magic"]) ++_LT_DECL([], [want_nocaseglob], [1], ++ [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ++])# _LT_CHECK_MAGIC_METHOD ++ ++ ++# LT_PATH_NM ++# ---------- ++# find the pathname to a BSD- or MS-compatible name lister ++AC_DEFUN([LT_PATH_NM], ++[AC_REQUIRE([AC_PROG_CC])dnl ++AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, ++[if test -n "$NM"; then ++ # Let the user override the test. ++ lt_cv_path_NM=$NM ++else ++ lt_nm_to_check=${ac_tool_prefix}nm ++ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then ++ lt_nm_to_check="$lt_nm_to_check nm" ++ fi ++ for lt_tmp_nm in $lt_nm_to_check; do ++ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ++ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do ++ IFS=$lt_save_ifs ++ test -z "$ac_dir" && ac_dir=. ++ tmp_nm=$ac_dir/$lt_tmp_nm ++ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then ++ # Check to see if the nm accepts a BSD-compat flag. ++ # Adding the 'sed 1q' prevents false positives on HP-UX, which says: ++ # nm: unknown option "B" ignored ++ # Tru64's nm complains that /dev/null is an invalid object file ++ # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty ++ case $build_os in ++ mingw*) lt_bad_file=conftest.nm/nofile ;; ++ *) lt_bad_file=/dev/null ;; ++ esac ++ case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in ++ *$lt_bad_file* | *'Invalid file or object type'*) ++ lt_cv_path_NM="$tmp_nm -B" ++ break 2 ++ ;; ++ *) ++ case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in ++ */dev/null*) ++ lt_cv_path_NM="$tmp_nm -p" ++ break 2 ++ ;; ++ *) ++ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but ++ continue # so that we can try to find one that supports BSD flags ++ ;; ++ esac ++ ;; ++ esac ++ fi ++ done ++ IFS=$lt_save_ifs ++ done ++ : ${lt_cv_path_NM=no} ++fi]) ++if test no != "$lt_cv_path_NM"; then ++ NM=$lt_cv_path_NM ++else ++ # Didn't find any BSD compatible name lister, look for dumpbin. ++ if test -n "$DUMPBIN"; then : ++ # Let the user override the test. ++ else ++ AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) ++ case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in ++ *COFF*) ++ DUMPBIN="$DUMPBIN -symbols -headers" ++ ;; ++ *) ++ DUMPBIN=: ++ ;; ++ esac ++ fi ++ AC_SUBST([DUMPBIN]) ++ if test : != "$DUMPBIN"; then ++ NM=$DUMPBIN ++ fi ++fi ++test -z "$NM" && NM=nm ++AC_SUBST([NM]) ++_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl ++ ++AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], ++ [lt_cv_nm_interface="BSD nm" ++ echo "int some_variable = 0;" > conftest.$ac_ext ++ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) ++ (eval "$ac_compile" 2>conftest.err) ++ cat conftest.err >&AS_MESSAGE_LOG_FD ++ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) ++ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) ++ cat conftest.err >&AS_MESSAGE_LOG_FD ++ (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) ++ cat conftest.out >&AS_MESSAGE_LOG_FD ++ if $GREP 'External.*some_variable' conftest.out > /dev/null; then ++ lt_cv_nm_interface="MS dumpbin" ++ fi ++ rm -f conftest*]) ++])# LT_PATH_NM ++ ++# Old names: ++AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) ++AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AM_PROG_NM], []) ++dnl AC_DEFUN([AC_PROG_NM], []) ++ ++# _LT_CHECK_SHAREDLIB_FROM_LINKLIB ++# -------------------------------- ++# how to determine the name of the shared library ++# associated with a specific link library. ++# -- PORTME fill in with the dynamic library characteristics ++m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], ++[m4_require([_LT_DECL_EGREP]) ++m4_require([_LT_DECL_OBJDUMP]) ++m4_require([_LT_DECL_DLLTOOL]) ++AC_CACHE_CHECK([how to associate runtime and link libraries], ++lt_cv_sharedlib_from_linklib_cmd, ++[lt_cv_sharedlib_from_linklib_cmd='unknown' ++ ++case $host_os in ++cygwin* | mingw* | pw32* | cegcc*) ++ # two different shell functions defined in ltmain.sh; ++ # decide which one to use based on capabilities of $DLLTOOL ++ case `$DLLTOOL --help 2>&1` in ++ *--identify-strict*) ++ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ++ ;; ++ *) ++ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ++ ;; ++ esac ++ ;; ++*) ++ # fallback: assume linklib IS sharedlib ++ lt_cv_sharedlib_from_linklib_cmd=$ECHO ++ ;; ++esac ++]) ++sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd ++test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO ++ ++_LT_DECL([], [sharedlib_from_linklib_cmd], [1], ++ [Command to associate shared and link libraries]) ++])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB ++ ++ ++# _LT_PATH_MANIFEST_TOOL ++# ---------------------- ++# locate the manifest tool ++m4_defun([_LT_PATH_MANIFEST_TOOL], ++[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) ++test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt ++AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], ++ [lt_cv_path_mainfest_tool=no ++ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD ++ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out ++ cat conftest.err >&AS_MESSAGE_LOG_FD ++ if $GREP 'Manifest Tool' conftest.out > /dev/null; then ++ lt_cv_path_mainfest_tool=yes ++ fi ++ rm -f conftest*]) ++if test yes != "$lt_cv_path_mainfest_tool"; then ++ MANIFEST_TOOL=: ++fi ++_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ++])# _LT_PATH_MANIFEST_TOOL ++ ++ ++# _LT_DLL_DEF_P([FILE]) ++# --------------------- ++# True iff FILE is a Windows DLL '.def' file. ++# Keep in sync with func_dll_def_p in the libtool script ++AC_DEFUN([_LT_DLL_DEF_P], ++[dnl ++ test DEF = "`$SED -n dnl ++ -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace ++ -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments ++ -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl ++ -e q dnl Only consider the first "real" line ++ $1`" dnl ++])# _LT_DLL_DEF_P ++ ++ ++# LT_LIB_M ++# -------- ++# check for math library ++AC_DEFUN([LT_LIB_M], ++[AC_REQUIRE([AC_CANONICAL_HOST])dnl ++LIBM= ++case $host in ++*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) ++ # These system don't have libm, or don't need it ++ ;; ++*-ncr-sysv4.3*) ++ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) ++ AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ++ ;; ++*) ++ AC_CHECK_LIB(m, cos, LIBM=-lm) ++ ;; ++esac ++AC_SUBST([LIBM]) ++])# LT_LIB_M ++ ++# Old name: ++AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AC_CHECK_LIBM], []) ++ ++ ++# _LT_COMPILER_NO_RTTI([TAGNAME]) ++# ------------------------------- ++m4_defun([_LT_COMPILER_NO_RTTI], ++[m4_require([_LT_TAG_COMPILER])dnl ++ ++_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= ++ ++if test yes = "$GCC"; then ++ case $cc_basename in ++ nvcc*) ++ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; ++ *) ++ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; ++ esac ++ ++ _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], ++ lt_cv_prog_compiler_rtti_exceptions, ++ [-fno-rtti -fno-exceptions], [], ++ [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) ++fi ++_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], ++ [Compiler flag to turn off builtin functions]) ++])# _LT_COMPILER_NO_RTTI ++ ++ ++# _LT_CMD_GLOBAL_SYMBOLS ++# ---------------------- ++m4_defun([_LT_CMD_GLOBAL_SYMBOLS], ++[AC_REQUIRE([AC_CANONICAL_HOST])dnl ++AC_REQUIRE([AC_PROG_CC])dnl ++AC_REQUIRE([AC_PROG_AWK])dnl ++AC_REQUIRE([LT_PATH_NM])dnl ++AC_REQUIRE([LT_PATH_LD])dnl ++m4_require([_LT_DECL_SED])dnl ++m4_require([_LT_DECL_EGREP])dnl ++m4_require([_LT_TAG_COMPILER])dnl ++ ++# Check for command to grab the raw symbol name followed by C symbol from nm. ++AC_MSG_CHECKING([command to parse $NM output from $compiler object]) ++AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], ++[ ++# These are sane defaults that work on at least a few old systems. ++# [They come from Ultrix. What could be older than Ultrix?!! ;)] ++ ++# Character class describing NM global symbol codes. ++symcode='[[BCDEGRST]]' ++ ++# Regexp to match symbols that can be accessed directly from C. ++sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' ++ ++# Define system-specific variables. ++case $host_os in ++aix*) ++ symcode='[[BCDT]]' ++ ;; ++cygwin* | mingw* | pw32* | cegcc*) ++ symcode='[[ABCDGISTW]]' ++ ;; ++hpux*) ++ if test ia64 = "$host_cpu"; then ++ symcode='[[ABCDEGRST]]' ++ fi ++ ;; ++irix* | nonstopux*) ++ symcode='[[BCDEGRST]]' ++ ;; ++osf*) ++ symcode='[[BCDEGQRST]]' ++ ;; ++solaris*) ++ symcode='[[BDRT]]' ++ ;; ++sco3.2v5*) ++ symcode='[[DT]]' ++ ;; ++sysv4.2uw2*) ++ symcode='[[DT]]' ++ ;; ++sysv5* | sco5v6* | unixware* | OpenUNIX*) ++ symcode='[[ABDT]]' ++ ;; ++sysv4) ++ symcode='[[DFNSTU]]' ++ ;; ++esac ++ ++# If we're using GNU nm, then use its standard symbol codes. ++case `$NM -V 2>&1` in ++*GNU* | *'with BFD'*) ++ symcode='[[ABCDGIRSTW]]' ;; ++esac ++ ++if test "$lt_cv_nm_interface" = "MS dumpbin"; then ++ # Gets list of data symbols to import. ++ lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'" ++ # Adjust the below global symbol transforms to fixup imported variables. ++ lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" ++ lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" ++ lt_c_name_lib_hook="\ ++ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ ++ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" ++else ++ # Disable hooks by default. ++ lt_cv_sys_global_symbol_to_import= ++ lt_cdecl_hook= ++ lt_c_name_hook= ++ lt_c_name_lib_hook= ++fi ++ ++# Transform an extracted symbol line into a proper C declaration. ++# Some systems (esp. on ia64) link data and code symbols differently, ++# so use this general approach. ++lt_cv_sys_global_symbol_to_cdecl="$SED -n"\ ++$lt_cdecl_hook\ ++" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ ++" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" ++ ++# Transform an extracted symbol line into symbol name and symbol address ++lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\ ++$lt_c_name_hook\ ++" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ ++" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" ++ ++# Transform an extracted symbol line into symbol name with lib prefix and ++# symbol address. ++lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\ ++$lt_c_name_lib_hook\ ++" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ ++" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ ++" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" ++ ++# Handle CRLF in mingw tool chain ++opt_cr= ++case $build_os in ++mingw*) ++ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ++ ;; ++esac ++ ++# Try without a prefix underscore, then with it. ++for ac_symprfx in "" "_"; do ++ ++ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. ++ symxfrm="\\1 $ac_symprfx\\2 \\2" ++ ++ # Write the raw and C identifiers. ++ if test "$lt_cv_nm_interface" = "MS dumpbin"; then ++ # Fake it for dumpbin and say T for any non-static function, ++ # D for any global variable and I for any imported variable. ++ # Also find C++ and __fastcall symbols from MSVC++ or ICC, ++ # which start with @ or ?. ++ lt_cv_sys_global_symbol_pipe="$AWK ['"\ ++" {last_section=section; section=\$ 3};"\ ++" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ ++" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ ++" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ ++" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ ++" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ ++" \$ 0!~/External *\|/{next};"\ ++" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ ++" {if(hide[section]) next};"\ ++" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ ++" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ ++" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ ++" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ ++" ' prfx=^$ac_symprfx]" ++ else ++ lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" ++ fi ++ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'" ++ ++ # Check to see that the pipe works correctly. ++ pipe_works=no ++ ++ rm -f conftest* ++ cat > conftest.$ac_ext <<_LT_EOF ++#ifdef __cplusplus ++extern "C" { ++#endif ++char nm_test_var; ++void nm_test_func(void); ++void nm_test_func(void){} ++#ifdef __cplusplus ++} ++#endif ++int main(){nm_test_var='a';nm_test_func();return(0);} ++_LT_EOF ++ ++ if AC_TRY_EVAL(ac_compile); then ++ # Now try to grab the symbols. ++ nlist=conftest.nm ++ if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then ++ # Try sorting and uniquifying the output. ++ if sort "$nlist" | uniq > "$nlist"T; then ++ mv -f "$nlist"T "$nlist" ++ else ++ rm -f "$nlist"T ++ fi ++ ++ # Make sure that we snagged all the symbols we need. ++ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then ++ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then ++ cat <<_LT_EOF > conftest.$ac_ext ++/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ ++#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE ++/* DATA imports from DLLs on WIN32 can't be const, because runtime ++ relocations are performed -- see ld's documentation on pseudo-relocs. */ ++# define LT@&t@_DLSYM_CONST ++#elif defined __osf__ ++/* This system does not cope well with relocations in const data. */ ++# define LT@&t@_DLSYM_CONST ++#else ++# define LT@&t@_DLSYM_CONST const ++#endif ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++_LT_EOF ++ # Now generate the symbol file. ++ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' ++ ++ cat <<_LT_EOF >> conftest.$ac_ext ++ ++/* The mapping between symbol names and symbols. */ ++LT@&t@_DLSYM_CONST struct { ++ const char *name; ++ void *address; ++} ++lt__PROGRAM__LTX_preloaded_symbols[[]] = ++{ ++ { "@PROGRAM@", (void *) 0 }, ++_LT_EOF ++ $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext ++ cat <<\_LT_EOF >> conftest.$ac_ext ++ {0, (void *) 0} ++}; ++ ++/* This works around a problem in FreeBSD linker */ ++#ifdef FREEBSD_WORKAROUND ++static const void *lt_preloaded_setup() { ++ return lt__PROGRAM__LTX_preloaded_symbols; ++} ++#endif ++ ++#ifdef __cplusplus ++} ++#endif ++_LT_EOF ++ # Now try linking the two files. ++ mv conftest.$ac_objext conftstm.$ac_objext ++ lt_globsym_save_LIBS=$LIBS ++ lt_globsym_save_CFLAGS=$CFLAGS ++ LIBS=conftstm.$ac_objext ++ CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" ++ if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then ++ pipe_works=yes ++ fi ++ LIBS=$lt_globsym_save_LIBS ++ CFLAGS=$lt_globsym_save_CFLAGS ++ else ++ echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD ++ fi ++ else ++ echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD ++ fi ++ else ++ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD ++ fi ++ else ++ echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD ++ cat conftest.$ac_ext >&5 ++ fi ++ rm -rf conftest* conftst* ++ ++ # Do not use the global_symbol_pipe unless it works. ++ if test yes = "$pipe_works"; then ++ break ++ else ++ lt_cv_sys_global_symbol_pipe= ++ fi ++done ++]) ++if test -z "$lt_cv_sys_global_symbol_pipe"; then ++ lt_cv_sys_global_symbol_to_cdecl= ++fi ++if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then ++ AC_MSG_RESULT(failed) ++else ++ AC_MSG_RESULT(ok) ++fi ++ ++# Response file support. ++if test "$lt_cv_nm_interface" = "MS dumpbin"; then ++ nm_file_list_spec='@' ++elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then ++ nm_file_list_spec='@' ++fi ++ ++_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], ++ [Take the output of nm and produce a listing of raw symbols and C names]) ++_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], ++ [Transform the output of nm in a proper C declaration]) ++_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], ++ [Transform the output of nm into a list of symbols to manually relocate]) ++_LT_DECL([global_symbol_to_c_name_address], ++ [lt_cv_sys_global_symbol_to_c_name_address], [1], ++ [Transform the output of nm in a C name address pair]) ++_LT_DECL([global_symbol_to_c_name_address_lib_prefix], ++ [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], ++ [Transform the output of nm in a C name address pair when lib prefix is needed]) ++_LT_DECL([nm_interface], [lt_cv_nm_interface], [1], ++ [The name lister interface]) ++_LT_DECL([], [nm_file_list_spec], [1], ++ [Specify filename containing input files for $NM]) ++]) # _LT_CMD_GLOBAL_SYMBOLS ++ ++ ++# _LT_COMPILER_PIC([TAGNAME]) ++# --------------------------- ++m4_defun([_LT_COMPILER_PIC], ++[m4_require([_LT_TAG_COMPILER])dnl ++_LT_TAGVAR(lt_prog_compiler_wl, $1)= ++_LT_TAGVAR(lt_prog_compiler_pic, $1)= ++_LT_TAGVAR(lt_prog_compiler_static, $1)= ++ ++m4_if([$1], [CXX], [ ++ # C++ specific cases for pic, static, wl, etc. ++ if test yes = "$GXX"; then ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ++ ++ case $host_os in ++ aix*) ++ # All AIX code is PIC. ++ if test ia64 = "$host_cpu"; then ++ # AIX 5 now supports IA64 processor ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ fi ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ ++ amigaos*) ++ case $host_cpu in ++ powerpc) ++ # see comment about AmigaOS4 .so support ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ m68k) ++ # FIXME: we need at least 68020 code to build shared libraries, but ++ # adding the '-m68020' flag to GCC prevents building anything better, ++ # like '-m68040'. ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ++ ;; ++ esac ++ ;; ++ ++ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) ++ # PIC is the default for these OSes. ++ ;; ++ mingw* | cygwin* | os2* | pw32* | cegcc*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ # Although the cygwin gcc ignores -fPIC, still need this for old-style ++ # (--disable-auto-import) libraries ++ m4_if([$1], [GCJ], [], ++ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ++ case $host_os in ++ os2*) ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ++ ;; ++ esac ++ ;; ++ darwin* | rhapsody*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ++ ;; ++ *djgpp*) ++ # DJGPP does not support shared libraries at all ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)= ++ ;; ++ haiku*) ++ # PIC is the default for Haiku. ++ # The "-static" flag exists, but is broken. ++ _LT_TAGVAR(lt_prog_compiler_static, $1)= ++ ;; ++ interix[[3-9]]*) ++ # Interix 3.x gcc -fpic/-fPIC options generate broken code. ++ # Instead, we relocate shared libraries at runtime. ++ ;; ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic ++ fi ++ ;; ++ hpux*) ++ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit ++ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag ++ # sets the default TLS model and affects inlining. ++ case $host_cpu in ++ hppa*64*) ++ ;; ++ *) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ esac ++ ;; ++ *qnx* | *nto*) ++ # QNX uses GNU C++, but need to define -shared option too, otherwise ++ # it will coredump. ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ++ ;; ++ *) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ esac ++ else ++ case $host_os in ++ aix[[4-9]]*) ++ # All AIX code is PIC. ++ if test ia64 = "$host_cpu"; then ++ # AIX 5 now supports IA64 processor ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ else ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' ++ fi ++ ;; ++ chorus*) ++ case $cc_basename in ++ cxch68*) ++ # Green Hills C++ Compiler ++ # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ++ ;; ++ esac ++ ;; ++ mingw* | cygwin* | os2* | pw32* | cegcc*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ m4_if([$1], [GCJ], [], ++ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ++ ;; ++ dgux*) ++ case $cc_basename in ++ ec++*) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ ;; ++ ghcx*) ++ # Green Hills C++ Compiler ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ freebsd* | dragonfly* | midnightbsd*) ++ # FreeBSD uses GNU C++ ++ ;; ++ hpux9* | hpux10* | hpux11*) ++ case $cc_basename in ++ CC*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' ++ if test ia64 != "$host_cpu"; then ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ++ fi ++ ;; ++ aCC*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ++ ;; ++ esac ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ interix*) ++ # This is c89, which is MS Visual C++ (no shared libs) ++ # Anyone wants to do a port? ++ ;; ++ irix5* | irix6* | nonstopux*) ++ case $cc_basename in ++ CC*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ # CC pic flag -KPIC is the default. ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) ++ case $cc_basename in ++ KCC*) ++ # KAI C++ Compiler ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ ecpc* ) ++ # old Intel C++ for x86_64, which still supported -KPIC. ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ++ ;; ++ icpc* ) ++ # Intel C++, used to be incompatible with GCC. ++ # ICC 10 doesn't accept -KPIC any more. ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ++ ;; ++ pgCC* | pgcpp*) ++ # Portland Group C++ compiler ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ cxx*) ++ # Compaq C++ ++ # Make sure the PIC flag is empty. It appears that all Alpha ++ # Linux and Compaq Tru64 Unix objects are PIC. ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)= ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ ;; ++ xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) ++ # IBM XL 8.0, 9.0 on PPC and BlueGene ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ++ ;; ++ *) ++ case `$CC -V 2>&1 | $SED 5q` in ++ *Sun\ C*) ++ # Sun C++ 5.9 ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ++ ;; ++ esac ++ ;; ++ esac ++ ;; ++ lynxos*) ++ ;; ++ m88k*) ++ ;; ++ mvs*) ++ case $cc_basename in ++ cxx*) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ netbsd*) ++ ;; ++ *qnx* | *nto*) ++ # QNX uses GNU C++, but need to define -shared option too, otherwise ++ # it will coredump. ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ++ ;; ++ osf3* | osf4* | osf5*) ++ case $cc_basename in ++ KCC*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ++ ;; ++ RCC*) ++ # Rational C++ 2.4.1 ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ++ ;; ++ cxx*) ++ # Digital/Compaq C++ ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ # Make sure the PIC flag is empty. It appears that all Alpha ++ # Linux and Compaq Tru64 Unix objects are PIC. ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)= ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ psos*) ++ ;; ++ solaris*) ++ case $cc_basename in ++ CC* | sunCC*) ++ # Sun C++ 4.2, 5.x and Centerline C++ ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ++ ;; ++ gcx*) ++ # Green Hills C++ Compiler ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ sunos4*) ++ case $cc_basename in ++ CC*) ++ # Sun C++ 4.x ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ lcc*) ++ # Lucid ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) ++ case $cc_basename in ++ CC*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ esac ++ ;; ++ tandem*) ++ case $cc_basename in ++ NCC*) ++ # NonStop-UX NCC 3.20 ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ vxworks*) ++ ;; ++ *) ++ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ++ ;; ++ esac ++ fi ++], ++[ ++ if test yes = "$GCC"; then ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ++ ++ case $host_os in ++ aix*) ++ # All AIX code is PIC. ++ if test ia64 = "$host_cpu"; then ++ # AIX 5 now supports IA64 processor ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ fi ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ ++ amigaos*) ++ case $host_cpu in ++ powerpc) ++ # see comment about AmigaOS4 .so support ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ m68k) ++ # FIXME: we need at least 68020 code to build shared libraries, but ++ # adding the '-m68020' flag to GCC prevents building anything better, ++ # like '-m68040'. ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ++ ;; ++ esac ++ ;; ++ ++ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) ++ # PIC is the default for these OSes. ++ ;; ++ ++ mingw* | cygwin* | pw32* | os2* | cegcc*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ # Although the cygwin gcc ignores -fPIC, still need this for old-style ++ # (--disable-auto-import) libraries ++ m4_if([$1], [GCJ], [], ++ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ++ case $host_os in ++ os2*) ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ++ ;; ++ esac ++ ;; ++ ++ darwin* | rhapsody*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ++ ;; ++ ++ haiku*) ++ # PIC is the default for Haiku. ++ # The "-static" flag exists, but is broken. ++ _LT_TAGVAR(lt_prog_compiler_static, $1)= ++ ;; ++ ++ hpux*) ++ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit ++ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag ++ # sets the default TLS model and affects inlining. ++ case $host_cpu in ++ hppa*64*) ++ # +Z the default ++ ;; ++ *) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ esac ++ ;; ++ ++ interix[[3-9]]*) ++ # Interix 3.x gcc -fpic/-fPIC options generate broken code. ++ # Instead, we relocate shared libraries at runtime. ++ ;; ++ ++ msdosdjgpp*) ++ # Just because we use GCC doesn't mean we suddenly get shared libraries ++ # on systems that don't support them. ++ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ++ enable_shared=no ++ ;; ++ ++ *nto* | *qnx*) ++ # QNX uses GNU C++, but need to define -shared option too, otherwise ++ # it will coredump. ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic ++ fi ++ ;; ++ ++ *) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ esac ++ ++ case $cc_basename in ++ nvcc*) # Cuda Compiler Driver 2.2 ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' ++ if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ++ fi ++ ;; ++ esac ++ else ++ # PORTME Check for flag to pass linker flags through the system compiler. ++ case $host_os in ++ aix*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ if test ia64 = "$host_cpu"; then ++ # AIX 5 now supports IA64 processor ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ else ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' ++ fi ++ ;; ++ ++ darwin* | rhapsody*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ++ case $cc_basename in ++ nagfor*) ++ # NAG Fortran compiler ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ esac ++ ;; ++ ++ mingw* | cygwin* | pw32* | os2* | cegcc*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ m4_if([$1], [GCJ], [], ++ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ++ case $host_os in ++ os2*) ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ++ ;; ++ esac ++ ;; ++ ++ hpux9* | hpux10* | hpux11*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but ++ # not for PA HP-UX. ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ++ ;; ++ esac ++ # Is there a better lt_prog_compiler_static that works with the bundled CC? ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' ++ ;; ++ ++ irix5* | irix6* | nonstopux*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ # PIC (with -KPIC) is the default. ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ ;; ++ ++ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) ++ case $cc_basename in ++ # old Intel for x86_64, which still supported -KPIC. ++ ecc*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ++ ;; ++ # icc used to be incompatible with GCC. ++ # ICC 10 doesn't accept -KPIC any more. ++ icc* | ifort*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ++ ;; ++ # Lahey Fortran 8.1. ++ lf95*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ++ ;; ++ nagfor*) ++ # NAG Fortran compiler ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ tcc*) ++ # Fabrice Bellard et al's Tiny C Compiler ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ++ ;; ++ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) ++ # Portland Group compilers (*not* the Pentium gcc compiler, ++ # which looks to be a dead project) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ ccc*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ # All Alpha code is PIC. ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ ;; ++ xl* | bgxl* | bgf* | mpixl*) ++ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ++ ;; ++ *) ++ case `$CC -V 2>&1 | $SED 5q` in ++ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) ++ # Sun Fortran 8.3 passes all unrecognized flags to the linker ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ++ ;; ++ *Sun\ F* | *Sun*Fortran*) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ++ ;; ++ *Sun\ C*) ++ # Sun C 5.9 ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ ;; ++ *Intel*\ [[CF]]*Compiler*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ++ ;; ++ *Portland\ Group*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ esac ++ ;; ++ esac ++ ;; ++ ++ newsos6) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ ++ *nto* | *qnx*) ++ # QNX uses GNU C++, but need to define -shared option too, otherwise ++ # it will coredump. ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ++ ;; ++ ++ osf3* | osf4* | osf5*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ # All OSF/1 code is PIC. ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ ;; ++ ++ rdos*) ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ ;; ++ ++ solaris*) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ case $cc_basename in ++ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; ++ *) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; ++ esac ++ ;; ++ ++ sunos4*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ ++ sysv4 | sysv4.2uw2* | sysv4.3*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ fi ++ ;; ++ ++ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ ++ unicos*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ++ ;; ++ ++ uts4*) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ ++ *) ++ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ++ ;; ++ esac ++ fi ++]) ++case $host_os in ++ # For platforms that do not support PIC, -DPIC is meaningless: ++ *djgpp*) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)= ++ ;; ++ *) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ++ ;; ++esac ++ ++AC_CACHE_CHECK([for $compiler option to produce PIC], ++ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], ++ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) ++_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) ++ ++# ++# Check to make sure the PIC flag actually works. ++# ++if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then ++ _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], ++ [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], ++ [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], ++ [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in ++ "" | " "*) ;; ++ *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; ++ esac], ++ [_LT_TAGVAR(lt_prog_compiler_pic, $1)= ++ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) ++fi ++_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], ++ [Additional compiler flags for building library objects]) ++ ++_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], ++ [How to pass a linker flag through the compiler]) ++# ++# Check to make sure the static flag actually works. ++# ++wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" ++_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], ++ _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), ++ $lt_tmp_static_flag, ++ [], ++ [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) ++_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], ++ [Compiler flag to prevent dynamic linking]) ++])# _LT_COMPILER_PIC ++ ++ ++# _LT_LINKER_SHLIBS([TAGNAME]) ++# ---------------------------- ++# See if the linker supports building shared libraries. ++m4_defun([_LT_LINKER_SHLIBS], ++[AC_REQUIRE([LT_PATH_LD])dnl ++AC_REQUIRE([LT_PATH_NM])dnl ++m4_require([_LT_PATH_MANIFEST_TOOL])dnl ++m4_require([_LT_FILEUTILS_DEFAULTS])dnl ++m4_require([_LT_DECL_EGREP])dnl ++m4_require([_LT_DECL_SED])dnl ++m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl ++m4_require([_LT_TAG_COMPILER])dnl ++AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) ++m4_if([$1], [CXX], [ ++ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ++ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] ++ case $host_os in ++ aix[[4-9]]*) ++ # If we're using GNU nm, then we don't want the "-C" option. ++ # -C means demangle to GNU nm, but means don't demangle to AIX nm. ++ # Without the "-l" option, or with the "-B" option, AIX nm treats ++ # weak defined symbols like other global defined symbols, whereas ++ # GNU nm marks them as "W". ++ # While the 'weak' keyword is ignored in the Export File, we need ++ # it in the Import File for the 'aix-soname' feature, so we have ++ # to replace the "-B" option with "-P" for AIX nm. ++ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then ++ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' ++ else ++ _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' ++ fi ++ ;; ++ pw32*) ++ _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds ++ ;; ++ cygwin* | mingw* | cegcc*) ++ case $cc_basename in ++ cl* | icl*) ++ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ++ ;; ++ *) ++ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' ++ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ++ ;; ++ esac ++ ;; ++ *) ++ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ++ ;; ++ esac ++], [ ++ runpath_var= ++ _LT_TAGVAR(allow_undefined_flag, $1)= ++ _LT_TAGVAR(always_export_symbols, $1)=no ++ _LT_TAGVAR(archive_cmds, $1)= ++ _LT_TAGVAR(archive_expsym_cmds, $1)= ++ _LT_TAGVAR(compiler_needs_object, $1)=no ++ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)= ++ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ++ _LT_TAGVAR(hardcode_automatic, $1)=no ++ _LT_TAGVAR(hardcode_direct, $1)=no ++ _LT_TAGVAR(hardcode_direct_absolute, $1)=no ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= ++ _LT_TAGVAR(hardcode_libdir_separator, $1)= ++ _LT_TAGVAR(hardcode_minus_L, $1)=no ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported ++ _LT_TAGVAR(inherit_rpath, $1)=no ++ _LT_TAGVAR(link_all_deplibs, $1)=unknown ++ _LT_TAGVAR(module_cmds, $1)= ++ _LT_TAGVAR(module_expsym_cmds, $1)= ++ _LT_TAGVAR(old_archive_from_new_cmds, $1)= ++ _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= ++ _LT_TAGVAR(thread_safe_flag_spec, $1)= ++ _LT_TAGVAR(whole_archive_flag_spec, $1)= ++ # include_expsyms should be a list of space-separated symbols to be *always* ++ # included in the symbol list ++ _LT_TAGVAR(include_expsyms, $1)= ++ # exclude_expsyms can be an extended regexp of symbols to exclude ++ # it will be wrapped by ' (' and ')$', so one must not match beginning or ++ # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', ++ # as well as any symbol that contains 'd'. ++ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] ++ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out ++ # platforms (ab)use it in PIC code, but their linkers get confused if ++ # the symbol is explicitly referenced. Since portable code cannot ++ # rely on this symbol name, it's probably fine to never include it in ++ # preloaded symbol tables. ++ # Exclude shared library initialization/finalization symbols. ++dnl Note also adjust exclude_expsyms for C++ above. ++ extract_expsyms_cmds= ++ ++ case $host_os in ++ cygwin* | mingw* | pw32* | cegcc*) ++ # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time ++ # When not using gcc, we currently assume that we are using ++ # Microsoft Visual C++ or Intel C++ Compiler. ++ if test yes != "$GCC"; then ++ with_gnu_ld=no ++ fi ++ ;; ++ interix*) ++ # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) ++ with_gnu_ld=yes ++ ;; ++ openbsd* | bitrig*) ++ with_gnu_ld=no ++ ;; ++ esac ++ ++ _LT_TAGVAR(ld_shlibs, $1)=yes ++ ++ # On some targets, GNU ld is compatible enough with the native linker ++ # that we're better off using the native interface for both. ++ lt_use_gnu_ld_interface=no ++ if test yes = "$with_gnu_ld"; then ++ case $host_os in ++ aix*) ++ # The AIX port of GNU ld has always aspired to compatibility ++ # with the native linker. However, as the warning in the GNU ld ++ # block says, versions before 2.19.5* couldn't really create working ++ # shared libraries, regardless of the interface used. ++ case `$LD -v 2>&1` in ++ *\ \(GNU\ Binutils\)\ 2.19.5*) ;; ++ *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; ++ *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; ++ *) ++ lt_use_gnu_ld_interface=yes ++ ;; ++ esac ++ ;; ++ *) ++ lt_use_gnu_ld_interface=yes ++ ;; ++ esac ++ fi ++ ++ if test yes = "$lt_use_gnu_ld_interface"; then ++ # If archive_cmds runs LD, not CC, wlarc should be empty ++ wlarc='$wl' ++ ++ # Set some defaults for GNU ld with shared library support. These ++ # are reset later if shared libraries are not supported. Putting them ++ # here allows them to be overridden if necessary. ++ runpath_var=LD_RUN_PATH ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' ++ # ancient GNU ld didn't support --whole-archive et. al. ++ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then ++ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' ++ else ++ _LT_TAGVAR(whole_archive_flag_spec, $1)= ++ fi ++ supports_anon_versioning=no ++ case `$LD -v | $SED -e 's/([[^)]]\+)\s\+//' 2>&1` in ++ *GNU\ gold*) supports_anon_versioning=yes ;; ++ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 ++ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... ++ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... ++ *\ 2.11.*) ;; # other 2.11 versions ++ *) supports_anon_versioning=yes ;; ++ esac ++ ++ # See if GNU ld supports shared libraries. ++ case $host_os in ++ aix[[3-9]]*) ++ # On AIX/PPC, the GNU linker is very broken ++ if test ia64 != "$host_cpu"; then ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: the GNU linker, at least up to release 2.19, is reported ++*** to be unable to reliably create shared libraries on AIX. ++*** Therefore, libtool is disabling shared libraries support. If you ++*** really care for shared libraries, you may want to install binutils ++*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. ++*** You will then need to restart the configuration process. ++ ++_LT_EOF ++ fi ++ ;; ++ ++ amigaos*) ++ case $host_cpu in ++ powerpc) ++ # see comment about AmigaOS4 .so support ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='' ++ ;; ++ m68k) ++ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ ;; ++ esac ++ ;; ++ ++ beos*) ++ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then ++ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported ++ # Joseph Beckenbach says some releases of gcc ++ # support --undefined. This deserves some investigation. FIXME ++ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ else ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ ++ cygwin* | mingw* | pw32* | cegcc*) ++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, ++ # as there is no search path for DLLs. ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' ++ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported ++ _LT_TAGVAR(always_export_symbols, $1)=no ++ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ++ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' ++ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ++ ++ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ # If the export-symbols file already is a .def file, use it as ++ # is; otherwise, prepend EXPORTS... ++ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then ++ cp $export_symbols $output_objdir/$soname.def; ++ else ++ echo EXPORTS > $output_objdir/$soname.def; ++ cat $export_symbols >> $output_objdir/$soname.def; ++ fi~ ++ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ else ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ ++ haiku*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(link_all_deplibs, $1)=yes ++ ;; ++ ++ os2*) ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported ++ shrext_cmds=.dll ++ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ ++ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ ++ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ ++ $ECHO EXPORTS >> $output_objdir/$libname.def~ ++ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ ++ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ ++ emximp -o $lib $output_objdir/$libname.def' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ ++ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ ++ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ ++ $ECHO EXPORTS >> $output_objdir/$libname.def~ ++ prefix_cmds="$SED"~ ++ if test EXPORTS = "`$SED 1q $export_symbols`"; then ++ prefix_cmds="$prefix_cmds -e 1d"; ++ fi~ ++ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ ++ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ ++ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ ++ emximp -o $lib $output_objdir/$libname.def' ++ _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' ++ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ++ _LT_TAGVAR(file_list_spec, $1)='@' ++ ;; ++ ++ interix[[3-9]]*) ++ _LT_TAGVAR(hardcode_direct, $1)=no ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ++ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. ++ # Instead, shared libraries are loaded at an image base (0x10000000 by ++ # default) and relocated if they conflict, which is a slow very memory ++ # consuming and fragmenting process. To avoid this, we pick a random, ++ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link ++ # time. Moving up from 0x10000000 also allows more sbrk(2) space. ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ ;; ++ ++ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) ++ tmp_diet=no ++ if test linux-dietlibc = "$host_os"; then ++ case $cc_basename in ++ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) ++ esac ++ fi ++ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ ++ && test no = "$tmp_diet" ++ then ++ tmp_addflag=' $pic_flag' ++ tmp_sharedflag='-shared' ++ case $cc_basename,$host_cpu in ++ pgcc*) # Portland Group C compiler ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ++ tmp_addflag=' $pic_flag' ++ ;; ++ pgf77* | pgf90* | pgf95* | pgfortran*) ++ # Portland Group f77 and f90 compilers ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ++ tmp_addflag=' $pic_flag -Mnomain' ;; ++ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 ++ tmp_addflag=' -i_dynamic' ;; ++ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 ++ tmp_addflag=' -i_dynamic -nofor_main' ;; ++ ifc* | ifort*) # Intel Fortran compiler ++ tmp_addflag=' -nofor_main' ;; ++ lf95*) # Lahey Fortran 8.1 ++ _LT_TAGVAR(whole_archive_flag_spec, $1)= ++ tmp_sharedflag='--shared' ;; ++ nagfor*) # NAGFOR 5.3 ++ tmp_sharedflag='-Wl,-shared' ;; ++ xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) ++ tmp_sharedflag='-qmkshrobj' ++ tmp_addflag= ;; ++ nvcc*) # Cuda Compiler Driver 2.2 ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ++ _LT_TAGVAR(compiler_needs_object, $1)=yes ++ ;; ++ esac ++ case `$CC -V 2>&1 | $SED 5q` in ++ *Sun\ C*) # Sun C 5.9 ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ++ _LT_TAGVAR(compiler_needs_object, $1)=yes ++ tmp_sharedflag='-G' ;; ++ *Sun\ F*) # Sun Fortran 8.3 ++ tmp_sharedflag='-G' ;; ++ esac ++ _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ ++ if test yes = "$supports_anon_versioning"; then ++ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ ++ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ ++ echo "local: *; };" >> $output_objdir/$libname.ver~ ++ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' ++ fi ++ ++ case $cc_basename in ++ tcc*) ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' ++ ;; ++ xlf* | bgf* | bgxlf* | mpixlf*) ++ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ++ _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' ++ if test yes = "$supports_anon_versioning"; then ++ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ ++ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ ++ echo "local: *; };" >> $output_objdir/$libname.ver~ ++ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' ++ fi ++ ;; ++ esac ++ else ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ ++ netbsd*) ++ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then ++ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' ++ wlarc= ++ else ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ++ fi ++ ;; ++ ++ solaris*) ++ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: The releases 2.8.* of the GNU linker cannot reliably ++*** create shared libraries on Solaris systems. Therefore, libtool ++*** is disabling shared libraries support. We urge you to upgrade GNU ++*** binutils to release 2.9.1 or newer. Another option is to modify ++*** your PATH or compiler configuration so that the native linker is ++*** used, and then restart. ++ ++_LT_EOF ++ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) ++ case `$LD -v 2>&1` in ++ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot ++*** reliably create shared libraries on SCO systems. Therefore, libtool ++*** is disabling shared libraries support. We urge you to upgrade GNU ++*** binutils to release 2.16.91.0.3 or newer. Another option is to modify ++*** your PATH or compiler configuration so that the native linker is ++*** used, and then restart. ++ ++_LT_EOF ++ ;; ++ *) ++ # For security reasons, it is highly recommended that you always ++ # use absolute paths for naming shared libraries, and exclude the ++ # DT_RUNPATH tag from executables and libraries. But doing so ++ # requires that you compile everything twice, which is a pain. ++ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ esac ++ ;; ++ ++ sunos4*) ++ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ wlarc= ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ *) ++ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ esac ++ ++ if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then ++ runpath_var= ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)= ++ _LT_TAGVAR(whole_archive_flag_spec, $1)= ++ fi ++ else ++ # PORTME fill in a description of your system's linker (not GNU ld) ++ case $host_os in ++ aix3*) ++ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported ++ _LT_TAGVAR(always_export_symbols, $1)=yes ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' ++ # Note: this linker hardcodes the directories in LIBPATH if there ++ # are no directories specified by -L. ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then ++ # Neither direct hardcoding nor static linking is supported with a ++ # broken collect2. ++ _LT_TAGVAR(hardcode_direct, $1)=unsupported ++ fi ++ ;; ++ ++ aix[[4-9]]*) ++ if test ia64 = "$host_cpu"; then ++ # On IA64, the linker does run time linking by default, so we don't ++ # have to do anything special. ++ aix_use_runtimelinking=no ++ exp_sym_flag='-Bexport' ++ no_entry_flag= ++ else ++ # If we're using GNU nm, then we don't want the "-C" option. ++ # -C means demangle to GNU nm, but means don't demangle to AIX nm. ++ # Without the "-l" option, or with the "-B" option, AIX nm treats ++ # weak defined symbols like other global defined symbols, whereas ++ # GNU nm marks them as "W". ++ # While the 'weak' keyword is ignored in the Export File, we need ++ # it in the Import File for the 'aix-soname' feature, so we have ++ # to replace the "-B" option with "-P" for AIX nm. ++ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then ++ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' ++ else ++ _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' ++ fi ++ aix_use_runtimelinking=no ++ ++ # Test if we are trying to use run time linking or normal ++ # AIX style linking. If -brtl is somewhere in LDFLAGS, we ++ # have runtime linking enabled, and use it for executables. ++ # For shared libraries, we enable/disable runtime linking ++ # depending on the kind of the shared library created - ++ # when "with_aix_soname,aix_use_runtimelinking" is: ++ # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables ++ # "aix,yes" lib.so shared, rtl:yes, for executables ++ # lib.a static archive ++ # "both,no" lib.so.V(shr.o) shared, rtl:yes ++ # lib.a(lib.so.V) shared, rtl:no, for executables ++ # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables ++ # lib.a(lib.so.V) shared, rtl:no ++ # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables ++ # lib.a static archive ++ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) ++ for ld_flag in $LDFLAGS; do ++ if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then ++ aix_use_runtimelinking=yes ++ break ++ fi ++ done ++ if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then ++ # With aix-soname=svr4, we create the lib.so.V shared archives only, ++ # so we don't have lib.a shared libs to link our executables. ++ # We have to force runtime linking in this case. ++ aix_use_runtimelinking=yes ++ LDFLAGS="$LDFLAGS -Wl,-brtl" ++ fi ++ ;; ++ esac ++ ++ exp_sym_flag='-bexport' ++ no_entry_flag='-bnoentry' ++ fi ++ ++ # When large executables or shared objects are built, AIX ld can ++ # have problems creating the table of contents. If linking a library ++ # or program results in "error TOC overflow" add -mminimal-toc to ++ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not ++ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. ++ ++ _LT_TAGVAR(archive_cmds, $1)='' ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=':' ++ _LT_TAGVAR(link_all_deplibs, $1)=yes ++ _LT_TAGVAR(file_list_spec, $1)='$wl-f,' ++ case $with_aix_soname,$aix_use_runtimelinking in ++ aix,*) ;; # traditional, no import file ++ svr4,* | *,yes) # use import file ++ # The Import File defines what to hardcode. ++ _LT_TAGVAR(hardcode_direct, $1)=no ++ _LT_TAGVAR(hardcode_direct_absolute, $1)=no ++ ;; ++ esac ++ ++ if test yes = "$GCC"; then ++ case $host_os in aix4.[[012]]|aix4.[[012]].*) ++ # We only want to do this on AIX 4.2 and lower, the check ++ # below for broken collect2 doesn't work under 4.3+ ++ collect2name=`$CC -print-prog-name=collect2` ++ if test -f "$collect2name" && ++ strings "$collect2name" | $GREP resolve_lib_name >/dev/null ++ then ++ # We have reworked collect2 ++ : ++ else ++ # We have old collect2 ++ _LT_TAGVAR(hardcode_direct, $1)=unsupported ++ # It fails to find uninstalled libraries when the uninstalled ++ # path is not listed in the libpath. Setting hardcode_minus_L ++ # to unsupported forces relinking ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)= ++ fi ++ ;; ++ esac ++ shared_flag='-shared' ++ if test yes = "$aix_use_runtimelinking"; then ++ shared_flag="$shared_flag "'$wl-G' ++ fi ++ # Need to ensure runtime linking is disabled for the traditional ++ # shared library, or the linker may eventually find shared libraries ++ # /with/ Import File - we do not want to mix them. ++ shared_flag_aix='-shared' ++ shared_flag_svr4='-shared $wl-G' ++ else ++ # not using gcc ++ if test ia64 = "$host_cpu"; then ++ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release ++ # chokes on -Wl,-G. The following line is correct: ++ shared_flag='-G' ++ else ++ if test yes = "$aix_use_runtimelinking"; then ++ shared_flag='$wl-G' ++ else ++ shared_flag='$wl-bM:SRE' ++ fi ++ shared_flag_aix='$wl-bM:SRE' ++ shared_flag_svr4='$wl-G' ++ fi ++ fi ++ ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' ++ # It seems that -bexpall does not export symbols beginning with ++ # underscore (_), so it is better to generate a list of symbols to export. ++ _LT_TAGVAR(always_export_symbols, $1)=yes ++ if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then ++ # Warning - without using the other runtime loading flags (-brtl), ++ # -berok will link without error, but may produce a broken library. ++ _LT_TAGVAR(allow_undefined_flag, $1)='-berok' ++ # Determine the default libpath from the value encoded in an ++ # empty executable. ++ _LT_SYS_MODULE_PATH_AIX([$1]) ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag ++ else ++ if test ia64 = "$host_cpu"; then ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' ++ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" ++ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" ++ else ++ # Determine the default libpath from the value encoded in an ++ # empty executable. ++ _LT_SYS_MODULE_PATH_AIX([$1]) ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" ++ # Warning - without using the other run time loading flags, ++ # -berok will link without error, but may produce a broken library. ++ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' ++ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' ++ if test yes = "$with_gnu_ld"; then ++ # We only use this code for GNU lds that support --whole-archive. ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' ++ else ++ # Exported symbols can be pulled into shared objects from archives ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' ++ fi ++ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' ++ # -brtl affects multiple linker settings, -berok does not and is overridden later ++ compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' ++ if test svr4 != "$with_aix_soname"; then ++ # This is similar to how AIX traditionally builds its shared libraries. ++ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' ++ fi ++ if test aix != "$with_aix_soname"; then ++ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' ++ else ++ # used by -dlpreopen to get the symbols ++ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' ++ fi ++ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' ++ fi ++ fi ++ ;; ++ ++ amigaos*) ++ case $host_cpu in ++ powerpc) ++ # see comment about AmigaOS4 .so support ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='' ++ ;; ++ m68k) ++ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ ;; ++ esac ++ ;; ++ ++ bsdi[[45]]*) ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ++ ;; ++ ++ cygwin* | mingw* | pw32* | cegcc*) ++ # When not using gcc, we currently assume that we are using ++ # Microsoft Visual C++ or Intel C++ Compiler. ++ # hardcode_libdir_flag_spec is actually meaningless, as there is ++ # no search path for DLLs. ++ case $cc_basename in ++ cl* | icl*) ++ # Native MSVC or ICC ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' ++ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported ++ _LT_TAGVAR(always_export_symbols, $1)=yes ++ _LT_TAGVAR(file_list_spec, $1)='@' ++ # Tell ltmain to make .lib files, not .a files. ++ libext=lib ++ # Tell ltmain to make .dll files, not .so files. ++ shrext_cmds=.dll ++ # FIXME: Setting linknames here is a bad hack. ++ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then ++ cp "$export_symbols" "$output_objdir/$soname.def"; ++ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; ++ else ++ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; ++ fi~ ++ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ ++ linknames=' ++ # The linker will not automatically build a static lib if we build a DLL. ++ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' ++ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ++ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ++ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' ++ # Don't use ranlib ++ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' ++ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ ++ lt_tool_outputfile="@TOOL_OUTPUT@"~ ++ case $lt_outputfile in ++ *.exe|*.EXE) ;; ++ *) ++ lt_outputfile=$lt_outputfile.exe ++ lt_tool_outputfile=$lt_tool_outputfile.exe ++ ;; ++ esac~ ++ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then ++ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; ++ $RM "$lt_outputfile.manifest"; ++ fi' ++ ;; ++ *) ++ # Assume MSVC and ICC wrapper ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' ++ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported ++ # Tell ltmain to make .lib files, not .a files. ++ libext=lib ++ # Tell ltmain to make .dll files, not .so files. ++ shrext_cmds=.dll ++ # FIXME: Setting linknames here is a bad hack. ++ _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' ++ # The linker will automatically build a .lib file if we build a DLL. ++ _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' ++ # FIXME: Should let the user specify the lib program. ++ _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' ++ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ++ ;; ++ esac ++ ;; ++ ++ darwin* | rhapsody*) ++ _LT_DARWIN_LINKER_FEATURES($1) ++ ;; ++ ++ dgux*) ++ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor ++ # support. Future versions do this automatically, but an explicit c++rt0.o ++ # does not break anything, and helps significantly (at the cost of a little ++ # extra space). ++ freebsd2.2*) ++ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ # Unfortunately, older versions of FreeBSD 2 do not have this feature. ++ freebsd2.*) ++ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ # FreeBSD 3 and greater uses gcc -shared to do shared libraries. ++ freebsd* | dragonfly* | midnightbsd*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ hpux9*) ++ if test yes = "$GCC"; then ++ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' ++ else ++ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' ++ fi ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ++ ;; ++ ++ hpux10*) ++ if test yes,no = "$GCC,$with_gnu_ld"; then ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ++ fi ++ if test no = "$with_gnu_ld"; then ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ fi ++ ;; ++ ++ hpux11*) ++ if test yes,no = "$GCC,$with_gnu_ld"; then ++ case $host_cpu in ++ hppa*64*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ ia64*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ else ++ case $host_cpu in ++ hppa*64*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ ia64*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ m4_if($1, [], [ ++ # Older versions of the 11.00 compiler do not understand -b yet ++ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) ++ _LT_LINKER_OPTION([if $CC understands -b], ++ _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], ++ [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], ++ [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], ++ [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ++ ;; ++ esac ++ fi ++ if test no = "$with_gnu_ld"; then ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ case $host_cpu in ++ hppa*64*|ia64*) ++ _LT_TAGVAR(hardcode_direct, $1)=no ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ *) ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ ;; ++ esac ++ fi ++ ;; ++ ++ irix5* | irix6* | nonstopux*) ++ if test yes = "$GCC"; then ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ++ # Try to use the -exported_symbol ld option, if it does not ++ # work, assume that -exports_file does not work either and ++ # implicitly export all symbols. ++ # This should be the same for all languages, so no per-tag cache variable. ++ AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], ++ [lt_cv_irix_exported_symbol], ++ [save_LDFLAGS=$LDFLAGS ++ LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" ++ AC_LINK_IFELSE( ++ [AC_LANG_SOURCE( ++ [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], ++ [C++], [[int foo (void) { return 0; }]], ++ [Fortran 77], [[ ++ subroutine foo ++ end]], ++ [Fortran], [[ ++ subroutine foo ++ end]])])], ++ [lt_cv_irix_exported_symbol=yes], ++ [lt_cv_irix_exported_symbol=no]) ++ LDFLAGS=$save_LDFLAGS]) ++ if test yes = "$lt_cv_irix_exported_symbol"; then ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' ++ fi ++ else ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' ++ fi ++ _LT_TAGVAR(archive_cmds_need_lc, $1)='no' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ _LT_TAGVAR(inherit_rpath, $1)=yes ++ _LT_TAGVAR(link_all_deplibs, $1)=yes ++ ;; ++ ++ linux*) ++ case $cc_basename in ++ tcc*) ++ # Fabrice Bellard et al's Tiny C Compiler ++ _LT_TAGVAR(ld_shlibs, $1)=yes ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ ;; ++ ++ netbsd*) ++ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then ++ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out ++ else ++ _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF ++ fi ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ newsos6) ++ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ *nto* | *qnx*) ++ ;; ++ ++ openbsd* | bitrig*) ++ if test -f /usr/libexec/ld.so; then ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes ++ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ++ else ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' ++ fi ++ else ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ ++ os2*) ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported ++ shrext_cmds=.dll ++ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ ++ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ ++ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ ++ $ECHO EXPORTS >> $output_objdir/$libname.def~ ++ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ ++ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ ++ emximp -o $lib $output_objdir/$libname.def' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ ++ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ ++ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ ++ $ECHO EXPORTS >> $output_objdir/$libname.def~ ++ prefix_cmds="$SED"~ ++ if test EXPORTS = "`$SED 1q $export_symbols`"; then ++ prefix_cmds="$prefix_cmds -e 1d"; ++ fi~ ++ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ ++ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ ++ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ ++ emximp -o $lib $output_objdir/$libname.def' ++ _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' ++ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ++ _LT_TAGVAR(file_list_spec, $1)='@' ++ ;; ++ ++ osf3*) ++ if test yes = "$GCC"; then ++ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ++ else ++ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' ++ fi ++ _LT_TAGVAR(archive_cmds_need_lc, $1)='no' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ ;; ++ ++ osf4* | osf5*) # as osf3* with the addition of -msym flag ++ if test yes = "$GCC"; then ++ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ++ else ++ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ ++ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' ++ ++ # Both c and cxx compiler support -rpath directly ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ++ fi ++ _LT_TAGVAR(archive_cmds_need_lc, $1)='no' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ ;; ++ ++ solaris*) ++ _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' ++ if test yes = "$GCC"; then ++ wlarc='$wl' ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ ++ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ++ else ++ case `$CC -V 2>&1` in ++ *"Compilers 5.0"*) ++ wlarc='' ++ _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ ++ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ++ ;; ++ *) ++ wlarc='$wl' ++ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ ++ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ++ ;; ++ esac ++ fi ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ case $host_os in ++ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; ++ *) ++ # The compiler driver will combine and reorder linker options, ++ # but understands '-z linker_flag'. GCC discards it without '$wl', ++ # but is careful enough not to reorder. ++ # Supported since Solaris 2.6 (maybe 2.5.1?) ++ if test yes = "$GCC"; then ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ++ else ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ++ fi ++ ;; ++ esac ++ _LT_TAGVAR(link_all_deplibs, $1)=yes ++ ;; ++ ++ sunos4*) ++ if test sequent = "$host_vendor"; then ++ # Use $CC to link under sequent, because it throws in some extra .o ++ # files that make .init and .fini sections work. ++ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' ++ fi ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ sysv4) ++ case $host_vendor in ++ sni) ++ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ++ ;; ++ siemens) ++ ## LD is ld it makes a PLAMLIB ++ ## CC just makes a GrossModule. ++ _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' ++ _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' ++ _LT_TAGVAR(hardcode_direct, $1)=no ++ ;; ++ motorola) ++ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ++ ;; ++ esac ++ runpath_var='LD_RUN_PATH' ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ sysv4.3*) ++ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ runpath_var=LD_RUN_PATH ++ hardcode_runpath_var=yes ++ _LT_TAGVAR(ld_shlibs, $1)=yes ++ fi ++ ;; ++ ++ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) ++ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' ++ _LT_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ runpath_var='LD_RUN_PATH' ++ ++ if test yes = "$GCC"; then ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ fi ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6*) ++ # Note: We CANNOT use -z defs as we might desire, because we do not ++ # link with -lc, and that would cause any symbols used from libc to ++ # always be unresolved, which means just about no library would ++ # ever link correctly. If we're not using GNU ld we use -z text ++ # though, which does catch some bad symbols but isn't as heavy-handed ++ # as -z defs. ++ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' ++ _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' ++ _LT_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=':' ++ _LT_TAGVAR(link_all_deplibs, $1)=yes ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' ++ runpath_var='LD_RUN_PATH' ++ ++ if test yes = "$GCC"; then ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ fi ++ ;; ++ ++ uts4*) ++ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ *) ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ ++ if test sni = "$host_vendor"; then ++ case $host in ++ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' ++ ;; ++ esac ++ fi ++ fi ++]) ++AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) ++test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no ++ ++_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld ++ ++_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl ++_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl ++_LT_DECL([], [extract_expsyms_cmds], [2], ++ [The commands to extract the exported symbol list from a shared archive]) ++ ++# ++# Do we need to explicitly link libc? ++# ++case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in ++x|xyes) ++ # Assume -lc should be added ++ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes ++ ++ if test yes,yes = "$GCC,$enable_shared"; then ++ case $_LT_TAGVAR(archive_cmds, $1) in ++ *'~'*) ++ # FIXME: we may have to deal with multi-command sequences. ++ ;; ++ '$CC '*) ++ # Test whether the compiler implicitly links with -lc since on some ++ # systems, -lgcc has to come before -lc. If gcc already passes -lc ++ # to ld, don't add -lc before -lgcc. ++ AC_CACHE_CHECK([whether -lc should be explicitly linked in], ++ [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), ++ [$RM conftest* ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ if AC_TRY_EVAL(ac_compile) 2>conftest.err; then ++ soname=conftest ++ lib=conftest ++ libobjs=conftest.$ac_objext ++ deplibs= ++ wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) ++ pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) ++ compiler_flags=-v ++ linker_flags=-v ++ verstring= ++ output_objdir=. ++ libname=conftest ++ lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) ++ _LT_TAGVAR(allow_undefined_flag, $1)= ++ if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) ++ then ++ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no ++ else ++ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes ++ fi ++ _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag ++ else ++ cat conftest.err 1>&5 ++ fi ++ $RM conftest* ++ ]) ++ _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ++ ;; ++ esac ++ fi ++ ;; ++esac ++ ++_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], ++ [Whether or not to add -lc for building shared libraries]) ++_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], ++ [enable_shared_with_static_runtimes], [0], ++ [Whether or not to disallow shared libs when runtime libs are static]) ++_LT_TAGDECL([], [export_dynamic_flag_spec], [1], ++ [Compiler flag to allow reflexive dlopens]) ++_LT_TAGDECL([], [whole_archive_flag_spec], [1], ++ [Compiler flag to generate shared objects directly from archives]) ++_LT_TAGDECL([], [compiler_needs_object], [1], ++ [Whether the compiler copes with passing no objects directly]) ++_LT_TAGDECL([], [old_archive_from_new_cmds], [2], ++ [Create an old-style archive from a shared archive]) ++_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], ++ [Create a temporary old-style archive to link instead of a shared archive]) ++_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) ++_LT_TAGDECL([], [archive_expsym_cmds], [2]) ++_LT_TAGDECL([], [module_cmds], [2], ++ [Commands used to build a loadable module if different from building ++ a shared archive.]) ++_LT_TAGDECL([], [module_expsym_cmds], [2]) ++_LT_TAGDECL([], [with_gnu_ld], [1], ++ [Whether we are building with GNU ld or not]) ++_LT_TAGDECL([], [allow_undefined_flag], [1], ++ [Flag that allows shared libraries with undefined symbols to be built]) ++_LT_TAGDECL([], [no_undefined_flag], [1], ++ [Flag that enforces no undefined symbols]) ++_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], ++ [Flag to hardcode $libdir into a binary during linking. ++ This must work even if $libdir does not exist]) ++_LT_TAGDECL([], [hardcode_libdir_separator], [1], ++ [Whether we need a single "-rpath" flag with a separated argument]) ++_LT_TAGDECL([], [hardcode_direct], [0], ++ [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes ++ DIR into the resulting binary]) ++_LT_TAGDECL([], [hardcode_direct_absolute], [0], ++ [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes ++ DIR into the resulting binary and the resulting library dependency is ++ "absolute", i.e impossible to change by setting $shlibpath_var if the ++ library is relocated]) ++_LT_TAGDECL([], [hardcode_minus_L], [0], ++ [Set to "yes" if using the -LDIR flag during linking hardcodes DIR ++ into the resulting binary]) ++_LT_TAGDECL([], [hardcode_shlibpath_var], [0], ++ [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR ++ into the resulting binary]) ++_LT_TAGDECL([], [hardcode_automatic], [0], ++ [Set to "yes" if building a shared library automatically hardcodes DIR ++ into the library and all subsequent libraries and executables linked ++ against it]) ++_LT_TAGDECL([], [inherit_rpath], [0], ++ [Set to yes if linker adds runtime paths of dependent libraries ++ to runtime path list]) ++_LT_TAGDECL([], [link_all_deplibs], [0], ++ [Whether libtool must link a program against all its dependency libraries]) ++_LT_TAGDECL([], [always_export_symbols], [0], ++ [Set to "yes" if exported symbols are required]) ++_LT_TAGDECL([], [export_symbols_cmds], [2], ++ [The commands to list exported symbols]) ++_LT_TAGDECL([], [exclude_expsyms], [1], ++ [Symbols that should not be listed in the preloaded symbols]) ++_LT_TAGDECL([], [include_expsyms], [1], ++ [Symbols that must always be exported]) ++_LT_TAGDECL([], [prelink_cmds], [2], ++ [Commands necessary for linking programs (against libraries) with templates]) ++_LT_TAGDECL([], [postlink_cmds], [2], ++ [Commands necessary for finishing linking programs]) ++_LT_TAGDECL([], [file_list_spec], [1], ++ [Specify filename containing input files]) ++dnl FIXME: Not yet implemented ++dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], ++dnl [Compiler flag to generate thread safe objects]) ++])# _LT_LINKER_SHLIBS ++ ++ ++# _LT_LANG_C_CONFIG([TAG]) ++# ------------------------ ++# Ensure that the configuration variables for a C compiler are suitably ++# defined. These variables are subsequently used by _LT_CONFIG to write ++# the compiler configuration to 'libtool'. ++m4_defun([_LT_LANG_C_CONFIG], ++[m4_require([_LT_DECL_EGREP])dnl ++lt_save_CC=$CC ++AC_LANG_PUSH(C) ++ ++# Source file extension for C test sources. ++ac_ext=c ++ ++# Object file extension for compiled C test sources. ++objext=o ++_LT_TAGVAR(objext, $1)=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code="int some_variable = 0;" ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code='int main(){return(0);}' ++ ++_LT_TAG_COMPILER ++# Save the default compiler, since it gets overwritten when the other ++# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. ++compiler_DEFAULT=$CC ++ ++# save warnings/boilerplate of simple test code ++_LT_COMPILER_BOILERPLATE ++_LT_LINKER_BOILERPLATE ++ ++if test -n "$compiler"; then ++ _LT_COMPILER_NO_RTTI($1) ++ _LT_COMPILER_PIC($1) ++ _LT_COMPILER_C_O($1) ++ _LT_COMPILER_FILE_LOCKS($1) ++ _LT_LINKER_SHLIBS($1) ++ _LT_SYS_DYNAMIC_LINKER($1) ++ _LT_LINKER_HARDCODE_LIBPATH($1) ++ LT_SYS_DLOPEN_SELF ++ _LT_CMD_STRIPLIB ++ ++ # Report what library types will actually be built ++ AC_MSG_CHECKING([if libtool supports shared libraries]) ++ AC_MSG_RESULT([$can_build_shared]) ++ ++ AC_MSG_CHECKING([whether to build shared libraries]) ++ test no = "$can_build_shared" && enable_shared=no ++ ++ # On AIX, shared libraries and static libraries use the same namespace, and ++ # are all built from PIC. ++ case $host_os in ++ aix3*) ++ test yes = "$enable_shared" && enable_static=no ++ if test -n "$RANLIB"; then ++ archive_cmds="$archive_cmds~\$RANLIB \$lib" ++ postinstall_cmds='$RANLIB $lib' ++ fi ++ ;; ++ ++ aix[[4-9]]*) ++ if test ia64 != "$host_cpu"; then ++ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in ++ yes,aix,yes) ;; # shared object as lib.so file only ++ yes,svr4,*) ;; # shared object as lib.so archive member only ++ yes,*) enable_static=no ;; # shared object in lib.a archive as well ++ esac ++ fi ++ ;; ++ esac ++ AC_MSG_RESULT([$enable_shared]) ++ ++ AC_MSG_CHECKING([whether to build static libraries]) ++ # Make sure either enable_shared or enable_static is yes. ++ test yes = "$enable_shared" || enable_static=yes ++ AC_MSG_RESULT([$enable_static]) ++ ++ _LT_CONFIG($1) ++fi ++AC_LANG_POP ++CC=$lt_save_CC ++])# _LT_LANG_C_CONFIG ++ ++ ++# _LT_LANG_CXX_CONFIG([TAG]) ++# -------------------------- ++# Ensure that the configuration variables for a C++ compiler are suitably ++# defined. These variables are subsequently used by _LT_CONFIG to write ++# the compiler configuration to 'libtool'. ++m4_defun([_LT_LANG_CXX_CONFIG], ++[m4_require([_LT_FILEUTILS_DEFAULTS])dnl ++m4_require([_LT_DECL_EGREP])dnl ++m4_require([_LT_PATH_MANIFEST_TOOL])dnl ++if test -n "$CXX" && ( test no != "$CXX" && ++ ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || ++ (test g++ != "$CXX"))); then ++ AC_PROG_CXXCPP ++else ++ _lt_caught_CXX_error=yes ++fi ++ ++AC_LANG_PUSH(C++) ++_LT_TAGVAR(archive_cmds_need_lc, $1)=no ++_LT_TAGVAR(allow_undefined_flag, $1)= ++_LT_TAGVAR(always_export_symbols, $1)=no ++_LT_TAGVAR(archive_expsym_cmds, $1)= ++_LT_TAGVAR(compiler_needs_object, $1)=no ++_LT_TAGVAR(export_dynamic_flag_spec, $1)= ++_LT_TAGVAR(hardcode_direct, $1)=no ++_LT_TAGVAR(hardcode_direct_absolute, $1)=no ++_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= ++_LT_TAGVAR(hardcode_libdir_separator, $1)= ++_LT_TAGVAR(hardcode_minus_L, $1)=no ++_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported ++_LT_TAGVAR(hardcode_automatic, $1)=no ++_LT_TAGVAR(inherit_rpath, $1)=no ++_LT_TAGVAR(module_cmds, $1)= ++_LT_TAGVAR(module_expsym_cmds, $1)= ++_LT_TAGVAR(link_all_deplibs, $1)=unknown ++_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds ++_LT_TAGVAR(reload_flag, $1)=$reload_flag ++_LT_TAGVAR(reload_cmds, $1)=$reload_cmds ++_LT_TAGVAR(no_undefined_flag, $1)= ++_LT_TAGVAR(whole_archive_flag_spec, $1)= ++_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no ++ ++# Source file extension for C++ test sources. ++ac_ext=cpp ++ ++# Object file extension for compiled C++ test sources. ++objext=o ++_LT_TAGVAR(objext, $1)=$objext ++ ++# No sense in running all these tests if we already determined that ++# the CXX compiler isn't working. Some variables (like enable_shared) ++# are currently assumed to apply to all compilers on this platform, ++# and will be corrupted by setting them based on a non-working compiler. ++if test yes != "$_lt_caught_CXX_error"; then ++ # Code to be used in simple compile tests ++ lt_simple_compile_test_code="int some_variable = 0;" ++ ++ # Code to be used in simple link tests ++ lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' ++ ++ # ltmain only uses $CC for tagged configurations so make sure $CC is set. ++ _LT_TAG_COMPILER ++ ++ # save warnings/boilerplate of simple test code ++ _LT_COMPILER_BOILERPLATE ++ _LT_LINKER_BOILERPLATE ++ ++ # Allow CC to be a program name with arguments. ++ lt_save_CC=$CC ++ lt_save_CFLAGS=$CFLAGS ++ lt_save_LD=$LD ++ lt_save_GCC=$GCC ++ GCC=$GXX ++ lt_save_with_gnu_ld=$with_gnu_ld ++ lt_save_path_LD=$lt_cv_path_LD ++ if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then ++ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx ++ else ++ $as_unset lt_cv_prog_gnu_ld ++ fi ++ if test -n "${lt_cv_path_LDCXX+set}"; then ++ lt_cv_path_LD=$lt_cv_path_LDCXX ++ else ++ $as_unset lt_cv_path_LD ++ fi ++ test -z "${LDCXX+set}" || LD=$LDCXX ++ CC=${CXX-"c++"} ++ CFLAGS=$CXXFLAGS ++ compiler=$CC ++ _LT_TAGVAR(compiler, $1)=$CC ++ _LT_CC_BASENAME([$compiler]) ++ ++ if test -n "$compiler"; then ++ # We don't want -fno-exception when compiling C++ code, so set the ++ # no_builtin_flag separately ++ if test yes = "$GXX"; then ++ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ++ else ++ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= ++ fi ++ ++ if test yes = "$GXX"; then ++ # Set up default GNU C++ configuration ++ ++ LT_PATH_LD ++ ++ # Check if GNU C++ uses GNU ld as the underlying linker, since the ++ # archiving commands below assume that GNU ld is being used. ++ if test yes = "$with_gnu_ld"; then ++ _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ++ ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' ++ ++ # If archive_cmds runs LD, not CC, wlarc should be empty ++ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to ++ # investigate it a little bit more. (MM) ++ wlarc='$wl' ++ ++ # ancient GNU ld didn't support --whole-archive et. al. ++ if eval "`$CC -print-prog-name=ld` --help 2>&1" | ++ $GREP 'no-whole-archive' > /dev/null; then ++ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' ++ else ++ _LT_TAGVAR(whole_archive_flag_spec, $1)= ++ fi ++ else ++ with_gnu_ld=no ++ wlarc= ++ ++ # A generic and very simple default shared library creation ++ # command for GNU C++ for the case where it uses the native ++ # linker, instead of GNU ld. If possible, this setting should ++ # overridden to take advantage of the native linker features on ++ # the platform it is being used on. ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' ++ fi ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' ++ ++ else ++ GXX=no ++ with_gnu_ld=no ++ wlarc= ++ fi ++ ++ # PORTME: fill in a description of your system's C++ link characteristics ++ AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) ++ _LT_TAGVAR(ld_shlibs, $1)=yes ++ case $host_os in ++ aix3*) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ aix[[4-9]]*) ++ if test ia64 = "$host_cpu"; then ++ # On IA64, the linker does run time linking by default, so we don't ++ # have to do anything special. ++ aix_use_runtimelinking=no ++ exp_sym_flag='-Bexport' ++ no_entry_flag= ++ else ++ aix_use_runtimelinking=no ++ ++ # Test if we are trying to use run time linking or normal ++ # AIX style linking. If -brtl is somewhere in LDFLAGS, we ++ # have runtime linking enabled, and use it for executables. ++ # For shared libraries, we enable/disable runtime linking ++ # depending on the kind of the shared library created - ++ # when "with_aix_soname,aix_use_runtimelinking" is: ++ # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables ++ # "aix,yes" lib.so shared, rtl:yes, for executables ++ # lib.a static archive ++ # "both,no" lib.so.V(shr.o) shared, rtl:yes ++ # lib.a(lib.so.V) shared, rtl:no, for executables ++ # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables ++ # lib.a(lib.so.V) shared, rtl:no ++ # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables ++ # lib.a static archive ++ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) ++ for ld_flag in $LDFLAGS; do ++ case $ld_flag in ++ *-brtl*) ++ aix_use_runtimelinking=yes ++ break ++ ;; ++ esac ++ done ++ if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then ++ # With aix-soname=svr4, we create the lib.so.V shared archives only, ++ # so we don't have lib.a shared libs to link our executables. ++ # We have to force runtime linking in this case. ++ aix_use_runtimelinking=yes ++ LDFLAGS="$LDFLAGS -Wl,-brtl" ++ fi ++ ;; ++ esac ++ ++ exp_sym_flag='-bexport' ++ no_entry_flag='-bnoentry' ++ fi ++ ++ # When large executables or shared objects are built, AIX ld can ++ # have problems creating the table of contents. If linking a library ++ # or program results in "error TOC overflow" add -mminimal-toc to ++ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not ++ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. ++ ++ _LT_TAGVAR(archive_cmds, $1)='' ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=':' ++ _LT_TAGVAR(link_all_deplibs, $1)=yes ++ _LT_TAGVAR(file_list_spec, $1)='$wl-f,' ++ case $with_aix_soname,$aix_use_runtimelinking in ++ aix,*) ;; # no import file ++ svr4,* | *,yes) # use import file ++ # The Import File defines what to hardcode. ++ _LT_TAGVAR(hardcode_direct, $1)=no ++ _LT_TAGVAR(hardcode_direct_absolute, $1)=no ++ ;; ++ esac ++ ++ if test yes = "$GXX"; then ++ case $host_os in aix4.[[012]]|aix4.[[012]].*) ++ # We only want to do this on AIX 4.2 and lower, the check ++ # below for broken collect2 doesn't work under 4.3+ ++ collect2name=`$CC -print-prog-name=collect2` ++ if test -f "$collect2name" && ++ strings "$collect2name" | $GREP resolve_lib_name >/dev/null ++ then ++ # We have reworked collect2 ++ : ++ else ++ # We have old collect2 ++ _LT_TAGVAR(hardcode_direct, $1)=unsupported ++ # It fails to find uninstalled libraries when the uninstalled ++ # path is not listed in the libpath. Setting hardcode_minus_L ++ # to unsupported forces relinking ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)= ++ fi ++ esac ++ shared_flag='-shared' ++ if test yes = "$aix_use_runtimelinking"; then ++ shared_flag=$shared_flag' $wl-G' ++ fi ++ # Need to ensure runtime linking is disabled for the traditional ++ # shared library, or the linker may eventually find shared libraries ++ # /with/ Import File - we do not want to mix them. ++ shared_flag_aix='-shared' ++ shared_flag_svr4='-shared $wl-G' ++ else ++ # not using gcc ++ if test ia64 = "$host_cpu"; then ++ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release ++ # chokes on -Wl,-G. The following line is correct: ++ shared_flag='-G' ++ else ++ if test yes = "$aix_use_runtimelinking"; then ++ shared_flag='$wl-G' ++ else ++ shared_flag='$wl-bM:SRE' ++ fi ++ shared_flag_aix='$wl-bM:SRE' ++ shared_flag_svr4='$wl-G' ++ fi ++ fi ++ ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' ++ # It seems that -bexpall does not export symbols beginning with ++ # underscore (_), so it is better to generate a list of symbols to ++ # export. ++ _LT_TAGVAR(always_export_symbols, $1)=yes ++ if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then ++ # Warning - without using the other runtime loading flags (-brtl), ++ # -berok will link without error, but may produce a broken library. ++ # The "-G" linker flag allows undefined symbols. ++ _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' ++ # Determine the default libpath from the value encoded in an empty ++ # executable. ++ _LT_SYS_MODULE_PATH_AIX([$1]) ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" ++ ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag ++ else ++ if test ia64 = "$host_cpu"; then ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' ++ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" ++ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" ++ else ++ # Determine the default libpath from the value encoded in an ++ # empty executable. ++ _LT_SYS_MODULE_PATH_AIX([$1]) ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" ++ # Warning - without using the other run time loading flags, ++ # -berok will link without error, but may produce a broken library. ++ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' ++ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' ++ if test yes = "$with_gnu_ld"; then ++ # We only use this code for GNU lds that support --whole-archive. ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' ++ else ++ # Exported symbols can be pulled into shared objects from archives ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' ++ fi ++ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' ++ # -brtl affects multiple linker settings, -berok does not and is overridden later ++ compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' ++ if test svr4 != "$with_aix_soname"; then ++ # This is similar to how AIX traditionally builds its shared ++ # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. ++ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' ++ fi ++ if test aix != "$with_aix_soname"; then ++ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' ++ else ++ # used by -dlpreopen to get the symbols ++ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' ++ fi ++ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' ++ fi ++ fi ++ ;; ++ ++ beos*) ++ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then ++ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported ++ # Joseph Beckenbach says some releases of gcc ++ # support --undefined. This deserves some investigation. FIXME ++ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ else ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ ++ chorus*) ++ case $cc_basename in ++ *) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ ;; ++ ++ cygwin* | mingw* | pw32* | cegcc*) ++ case $GXX,$cc_basename in ++ ,cl* | no,cl* | ,icl* | no,icl*) ++ # Native MSVC or ICC ++ # hardcode_libdir_flag_spec is actually meaningless, as there is ++ # no search path for DLLs. ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' ++ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported ++ _LT_TAGVAR(always_export_symbols, $1)=yes ++ _LT_TAGVAR(file_list_spec, $1)='@' ++ # Tell ltmain to make .lib files, not .a files. ++ libext=lib ++ # Tell ltmain to make .dll files, not .so files. ++ shrext_cmds=.dll ++ # FIXME: Setting linknames here is a bad hack. ++ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then ++ cp "$export_symbols" "$output_objdir/$soname.def"; ++ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; ++ else ++ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; ++ fi~ ++ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ ++ linknames=' ++ # The linker will not automatically build a static lib if we build a DLL. ++ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' ++ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ++ # Don't use ranlib ++ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' ++ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ ++ lt_tool_outputfile="@TOOL_OUTPUT@"~ ++ case $lt_outputfile in ++ *.exe|*.EXE) ;; ++ *) ++ lt_outputfile=$lt_outputfile.exe ++ lt_tool_outputfile=$lt_tool_outputfile.exe ++ ;; ++ esac~ ++ func_to_tool_file "$lt_outputfile"~ ++ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then ++ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; ++ $RM "$lt_outputfile.manifest"; ++ fi' ++ ;; ++ *) ++ # g++ ++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, ++ # as there is no search path for DLLs. ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' ++ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported ++ _LT_TAGVAR(always_export_symbols, $1)=no ++ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ++ ++ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ # If the export-symbols file already is a .def file, use it as ++ # is; otherwise, prepend EXPORTS... ++ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then ++ cp $export_symbols $output_objdir/$soname.def; ++ else ++ echo EXPORTS > $output_objdir/$soname.def; ++ cat $export_symbols >> $output_objdir/$soname.def; ++ fi~ ++ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ else ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ esac ++ ;; ++ darwin* | rhapsody*) ++ _LT_DARWIN_LINKER_FEATURES($1) ++ ;; ++ ++ os2*) ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported ++ shrext_cmds=.dll ++ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ ++ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ ++ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ ++ $ECHO EXPORTS >> $output_objdir/$libname.def~ ++ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ ++ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ ++ emximp -o $lib $output_objdir/$libname.def' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ ++ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ ++ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ ++ $ECHO EXPORTS >> $output_objdir/$libname.def~ ++ prefix_cmds="$SED"~ ++ if test EXPORTS = "`$SED 1q $export_symbols`"; then ++ prefix_cmds="$prefix_cmds -e 1d"; ++ fi~ ++ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ ++ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ ++ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ ++ emximp -o $lib $output_objdir/$libname.def' ++ _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' ++ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ++ _LT_TAGVAR(file_list_spec, $1)='@' ++ ;; ++ ++ dgux*) ++ case $cc_basename in ++ ec++*) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ ghcx*) ++ # Green Hills C++ Compiler ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ ;; ++ ++ freebsd2.*) ++ # C++ shared libraries reported to be fairly broken before ++ # switch to ELF ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ ++ freebsd-elf*) ++ _LT_TAGVAR(archive_cmds_need_lc, $1)=no ++ ;; ++ ++ freebsd* | dragonfly* | midnightbsd*) ++ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF ++ # conventions ++ _LT_TAGVAR(ld_shlibs, $1)=yes ++ ;; ++ ++ haiku*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(link_all_deplibs, $1)=yes ++ ;; ++ ++ hpux9*) ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, ++ # but as the default ++ # location of the library. ++ ++ case $cc_basename in ++ CC*) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ aCC*) ++ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ++ ;; ++ *) ++ if test yes = "$GXX"; then ++ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' ++ else ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ esac ++ ;; ++ ++ hpux10*|hpux11*) ++ if test no = "$with_gnu_ld"; then ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ case $host_cpu in ++ hppa*64*|ia64*) ++ ;; ++ *) ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ++ ;; ++ esac ++ fi ++ case $host_cpu in ++ hppa*64*|ia64*) ++ _LT_TAGVAR(hardcode_direct, $1)=no ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ *) ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, ++ # but as the default ++ # location of the library. ++ ;; ++ esac ++ ++ case $cc_basename in ++ CC*) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ aCC*) ++ case $host_cpu in ++ hppa*64*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ ia64*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ *) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ esac ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ++ ;; ++ *) ++ if test yes = "$GXX"; then ++ if test no = "$with_gnu_ld"; then ++ case $host_cpu in ++ hppa*64*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ ia64*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ *) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ esac ++ fi ++ else ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ esac ++ ;; ++ ++ interix[[3-9]]*) ++ _LT_TAGVAR(hardcode_direct, $1)=no ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ++ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. ++ # Instead, shared libraries are loaded at an image base (0x10000000 by ++ # default) and relocated if they conflict, which is a slow very memory ++ # consuming and fragmenting process. To avoid this, we pick a random, ++ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link ++ # time. Moving up from 0x10000000 also allows more sbrk(2) space. ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ ;; ++ irix5* | irix6*) ++ case $cc_basename in ++ CC*) ++ # SGI C++ ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' ++ ++ # Archives containing C++ object files must be created using ++ # "CC -ar", where "CC" is the IRIX C++ compiler. This is ++ # necessary to make sure instantiated templates are included ++ # in the archive. ++ _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ++ ;; ++ *) ++ if test yes = "$GXX"; then ++ if test no = "$with_gnu_ld"; then ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ++ else ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' ++ fi ++ fi ++ _LT_TAGVAR(link_all_deplibs, $1)=yes ++ ;; ++ esac ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ _LT_TAGVAR(inherit_rpath, $1)=yes ++ ;; ++ ++ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) ++ case $cc_basename in ++ KCC*) ++ # Kuck and Associates, Inc. (KAI) C++ Compiler ++ ++ # KCC will only create a shared library if the output file ++ # ends with ".so" (or ".sl" for HP-UX), so rename the library ++ # to its proper name (with version) after linking. ++ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ++ ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' ++ ++ # Archives containing C++ object files must be created using ++ # "CC -Bstatic", where "CC" is the KAI C++ compiler. ++ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ++ ;; ++ icpc* | ecpc* ) ++ # Intel C++ ++ with_gnu_ld=yes ++ # version 8.0 and above of icpc choke on multiply defined symbols ++ # if we add $predep_objects and $postdep_objects, however 7.1 and ++ # earlier do not add the objects themselves. ++ case `$CC -V 2>&1` in ++ *"Version 7."*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ++ ;; ++ *) # Version 8.0 or newer ++ tmp_idyn= ++ case $host_cpu in ++ ia64*) tmp_idyn=' -i_dynamic';; ++ esac ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ++ ;; ++ esac ++ _LT_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' ++ ;; ++ pgCC* | pgcpp*) ++ # Portland Group C++ compiler ++ case `$CC -V` in ++ *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) ++ _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ ++ rm -rf $tpldir~ ++ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ ++ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' ++ _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ ++ rm -rf $tpldir~ ++ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ ++ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ ++ $RANLIB $oldlib' ++ _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ ++ rm -rf $tpldir~ ++ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ ++ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ ++ rm -rf $tpldir~ ++ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ ++ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ++ ;; ++ *) # Version 6 and above use weak symbols ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ++ ;; ++ esac ++ ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ++ ;; ++ cxx*) ++ # Compaq C++ ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' ++ ++ runpath_var=LD_RUN_PATH ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ++ ;; ++ xl* | mpixl* | bgxl*) ++ # IBM XL 8.0 on PPC, with GNU ld ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' ++ _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ if test yes = "$supports_anon_versioning"; then ++ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ ++ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ ++ echo "local: *; };" >> $output_objdir/$libname.ver~ ++ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' ++ fi ++ ;; ++ *) ++ case `$CC -V 2>&1 | $SED 5q` in ++ *Sun\ C*) ++ # Sun C++ 5.9 ++ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' ++ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ++ _LT_TAGVAR(compiler_needs_object, $1)=yes ++ ++ # Not sure whether something based on ++ # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 ++ # would be better. ++ output_verbose_link_cmd='func_echo_all' ++ ++ # Archives containing C++ object files must be created using ++ # "CC -xar", where "CC" is the Sun C++ compiler. This is ++ # necessary to make sure instantiated templates are included ++ # in the archive. ++ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ++ ;; ++ esac ++ ;; ++ esac ++ ;; ++ ++ lynxos*) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ ++ m88k*) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ ++ mvs*) ++ case $cc_basename in ++ cxx*) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ ;; ++ ++ netbsd*) ++ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then ++ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' ++ wlarc= ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ fi ++ # Workaround some broken pre-1.5 toolchains ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ++ ;; ++ ++ *nto* | *qnx*) ++ _LT_TAGVAR(ld_shlibs, $1)=yes ++ ;; ++ ++ openbsd* | bitrig*) ++ if test -f /usr/libexec/ld.so; then ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ++ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' ++ fi ++ output_verbose_link_cmd=func_echo_all ++ else ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ ++ osf3* | osf4* | osf5*) ++ case $cc_basename in ++ KCC*) ++ # Kuck and Associates, Inc. (KAI) C++ Compiler ++ ++ # KCC will only create a shared library if the output file ++ # ends with ".so" (or ".sl" for HP-UX), so rename the library ++ # to its proper name (with version) after linking. ++ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' ++ ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ # Archives containing C++ object files must be created using ++ # the KAI C++ compiler. ++ case $host in ++ osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; ++ *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; ++ esac ++ ;; ++ RCC*) ++ # Rational C++ 2.4.1 ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ cxx*) ++ case $host in ++ osf3*) ++ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ++ ;; ++ *) ++ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ ++ echo "-hidden">> $lib.exp~ ++ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ ++ $RM $lib.exp' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ++ ;; ++ esac ++ ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ++ ;; ++ *) ++ if test yes,no = "$GXX,$with_gnu_ld"; then ++ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' ++ case $host in ++ osf3*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ++ ;; ++ *) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ++ ;; ++ esac ++ ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' ++ ++ else ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ esac ++ ;; ++ ++ psos*) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ ++ sunos4*) ++ case $cc_basename in ++ CC*) ++ # Sun C++ 4.x ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ lcc*) ++ # Lucid ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ ;; ++ ++ solaris*) ++ case $cc_basename in ++ CC* | sunCC*) ++ # Sun C++ 4.2, 5.x and Centerline C++ ++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes ++ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' ++ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ ++ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' ++ ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ case $host_os in ++ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; ++ *) ++ # The compiler driver will combine and reorder linker options, ++ # but understands '-z linker_flag'. ++ # Supported since Solaris 2.6 (maybe 2.5.1?) ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ++ ;; ++ esac ++ _LT_TAGVAR(link_all_deplibs, $1)=yes ++ ++ output_verbose_link_cmd='func_echo_all' ++ ++ # Archives containing C++ object files must be created using ++ # "CC -xar", where "CC" is the Sun C++ compiler. This is ++ # necessary to make sure instantiated templates are included ++ # in the archive. ++ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ++ ;; ++ gcx*) ++ # Green Hills C++ Compiler ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' ++ ++ # The C++ compiler must be used to create the archive. ++ _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ++ ;; ++ *) ++ # GNU C++ compiler with Solaris linker ++ if test yes,no = "$GXX,$with_gnu_ld"; then ++ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' ++ if $CC --version | $GREP -v '^2\.7' > /dev/null; then ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ ++ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' ++ else ++ # g++ 2.7 appears to require '-G' NOT '-shared' on this ++ # platform. ++ _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ ++ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' ++ fi ++ ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' ++ case $host_os in ++ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; ++ *) ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ++ ;; ++ esac ++ fi ++ ;; ++ esac ++ ;; ++ ++ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) ++ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' ++ _LT_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ runpath_var='LD_RUN_PATH' ++ ++ case $cc_basename in ++ CC*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6*) ++ # Note: We CANNOT use -z defs as we might desire, because we do not ++ # link with -lc, and that would cause any symbols used from libc to ++ # always be unresolved, which means just about no library would ++ # ever link correctly. If we're not using GNU ld we use -z text ++ # though, which does catch some bad symbols but isn't as heavy-handed ++ # as -z defs. ++ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' ++ _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' ++ _LT_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=':' ++ _LT_TAGVAR(link_all_deplibs, $1)=yes ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' ++ runpath_var='LD_RUN_PATH' ++ ++ case $cc_basename in ++ CC*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ ++ '"$_LT_TAGVAR(old_archive_cmds, $1)" ++ _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ ++ '"$_LT_TAGVAR(reload_cmds, $1)" ++ ;; ++ *) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ ;; ++ ++ tandem*) ++ case $cc_basename in ++ NCC*) ++ # NonStop-UX NCC 3.20 ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ ;; ++ ++ vxworks*) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ ++ *) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ ++ AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) ++ test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no ++ ++ _LT_TAGVAR(GCC, $1)=$GXX ++ _LT_TAGVAR(LD, $1)=$LD ++ ++ ## CAVEAT EMPTOR: ++ ## There is no encapsulation within the following macros, do not change ++ ## the running order or otherwise move them around unless you know exactly ++ ## what you are doing... ++ _LT_SYS_HIDDEN_LIBDEPS($1) ++ _LT_COMPILER_PIC($1) ++ _LT_COMPILER_C_O($1) ++ _LT_COMPILER_FILE_LOCKS($1) ++ _LT_LINKER_SHLIBS($1) ++ _LT_SYS_DYNAMIC_LINKER($1) ++ _LT_LINKER_HARDCODE_LIBPATH($1) ++ ++ _LT_CONFIG($1) ++ fi # test -n "$compiler" ++ ++ CC=$lt_save_CC ++ CFLAGS=$lt_save_CFLAGS ++ LDCXX=$LD ++ LD=$lt_save_LD ++ GCC=$lt_save_GCC ++ with_gnu_ld=$lt_save_with_gnu_ld ++ lt_cv_path_LDCXX=$lt_cv_path_LD ++ lt_cv_path_LD=$lt_save_path_LD ++ lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld ++ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld ++fi # test yes != "$_lt_caught_CXX_error" ++ ++AC_LANG_POP ++])# _LT_LANG_CXX_CONFIG ++ ++ ++# _LT_FUNC_STRIPNAME_CNF ++# ---------------------- ++# func_stripname_cnf prefix suffix name ++# strip PREFIX and SUFFIX off of NAME. ++# PREFIX and SUFFIX must not contain globbing or regex special ++# characters, hashes, percent signs, but SUFFIX may contain a leading ++# dot (in which case that matches only a dot). ++# ++# This function is identical to the (non-XSI) version of func_stripname, ++# except this one can be used by m4 code that may be executed by configure, ++# rather than the libtool script. ++m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl ++AC_REQUIRE([_LT_DECL_SED]) ++AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) ++func_stripname_cnf () ++{ ++ case @S|@2 in ++ .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; ++ *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; ++ esac ++} # func_stripname_cnf ++])# _LT_FUNC_STRIPNAME_CNF ++ ++ ++# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) ++# --------------------------------- ++# Figure out "hidden" library dependencies from verbose ++# compiler output when linking a shared library. ++# Parse the compiler output and extract the necessary ++# objects, libraries and library flags. ++m4_defun([_LT_SYS_HIDDEN_LIBDEPS], ++[m4_require([_LT_FILEUTILS_DEFAULTS])dnl ++AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl ++# Dependencies to place before and after the object being linked: ++_LT_TAGVAR(predep_objects, $1)= ++_LT_TAGVAR(postdep_objects, $1)= ++_LT_TAGVAR(predeps, $1)= ++_LT_TAGVAR(postdeps, $1)= ++_LT_TAGVAR(compiler_lib_search_path, $1)= ++ ++dnl we can't use the lt_simple_compile_test_code here, ++dnl because it contains code intended for an executable, ++dnl not a library. It's possible we should let each ++dnl tag define a new lt_????_link_test_code variable, ++dnl but it's only used here... ++m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF ++int a; ++void foo (void) { a = 0; } ++_LT_EOF ++], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF ++class Foo ++{ ++public: ++ Foo (void) { a = 0; } ++private: ++ int a; ++}; ++_LT_EOF ++], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF ++ subroutine foo ++ implicit none ++ integer*4 a ++ a=0 ++ return ++ end ++_LT_EOF ++], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF ++ subroutine foo ++ implicit none ++ integer a ++ a=0 ++ return ++ end ++_LT_EOF ++], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF ++public class foo { ++ private int a; ++ public void bar (void) { ++ a = 0; ++ } ++}; ++_LT_EOF ++], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF ++package foo ++func foo() { ++} ++_LT_EOF ++]) ++ ++_lt_libdeps_save_CFLAGS=$CFLAGS ++case "$CC $CFLAGS " in #( ++*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; ++*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; ++*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; ++esac ++ ++dnl Parse the compiler output and extract the necessary ++dnl objects, libraries and library flags. ++if AC_TRY_EVAL(ac_compile); then ++ # Parse the compiler output and extract the necessary ++ # objects, libraries and library flags. ++ ++ # Sentinel used to keep track of whether or not we are before ++ # the conftest object file. ++ pre_test_object_deps_done=no ++ ++ for p in `eval "$output_verbose_link_cmd"`; do ++ case $prev$p in ++ ++ -L* | -R* | -l*) ++ # Some compilers place space between "-{L,R}" and the path. ++ # Remove the space. ++ if test x-L = "$p" || ++ test x-R = "$p"; then ++ prev=$p ++ continue ++ fi ++ ++ # Expand the sysroot to ease extracting the directories later. ++ if test -z "$prev"; then ++ case $p in ++ -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; ++ -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; ++ -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; ++ esac ++ fi ++ case $p in ++ =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; ++ esac ++ if test no = "$pre_test_object_deps_done"; then ++ case $prev in ++ -L | -R) ++ # Internal compiler library paths should come after those ++ # provided the user. The postdeps already come after the ++ # user supplied libs so there is no need to process them. ++ if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then ++ _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p ++ else ++ _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" ++ fi ++ ;; ++ # The "-l" case would never come before the object being ++ # linked, so don't bother handling this case. ++ esac ++ else ++ if test -z "$_LT_TAGVAR(postdeps, $1)"; then ++ _LT_TAGVAR(postdeps, $1)=$prev$p ++ else ++ _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" ++ fi ++ fi ++ prev= ++ ;; ++ ++ *.lto.$objext) ;; # Ignore GCC LTO objects ++ *.$objext) ++ # This assumes that the test object file only shows up ++ # once in the compiler output. ++ if test "$p" = "conftest.$objext"; then ++ pre_test_object_deps_done=yes ++ continue ++ fi ++ ++ if test no = "$pre_test_object_deps_done"; then ++ if test -z "$_LT_TAGVAR(predep_objects, $1)"; then ++ _LT_TAGVAR(predep_objects, $1)=$p ++ else ++ _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" ++ fi ++ else ++ if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then ++ _LT_TAGVAR(postdep_objects, $1)=$p ++ else ++ _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" ++ fi ++ fi ++ ;; ++ ++ *) ;; # Ignore the rest. ++ ++ esac ++ done ++ ++ # Clean up. ++ rm -f a.out a.exe ++else ++ echo "libtool.m4: error: problem compiling $1 test program" ++fi ++ ++$RM -f confest.$objext ++CFLAGS=$_lt_libdeps_save_CFLAGS ++ ++# PORTME: override above test on systems where it is broken ++m4_if([$1], [CXX], ++[case $host_os in ++interix[[3-9]]*) ++ # Interix 3.5 installs completely hosed .la files for C++, so rather than ++ # hack all around it, let's just trust "g++" to DTRT. ++ _LT_TAGVAR(predep_objects,$1)= ++ _LT_TAGVAR(postdep_objects,$1)= ++ _LT_TAGVAR(postdeps,$1)= ++ ;; ++esac ++]) ++ ++case " $_LT_TAGVAR(postdeps, $1) " in ++*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; ++esac ++ _LT_TAGVAR(compiler_lib_search_dirs, $1)= ++if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then ++ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` ++fi ++_LT_TAGDECL([], [compiler_lib_search_dirs], [1], ++ [The directories searched by this compiler when creating a shared library]) ++_LT_TAGDECL([], [predep_objects], [1], ++ [Dependencies to place before and after the objects being linked to ++ create a shared library]) ++_LT_TAGDECL([], [postdep_objects], [1]) ++_LT_TAGDECL([], [predeps], [1]) ++_LT_TAGDECL([], [postdeps], [1]) ++_LT_TAGDECL([], [compiler_lib_search_path], [1], ++ [The library search path used internally by the compiler when linking ++ a shared library]) ++])# _LT_SYS_HIDDEN_LIBDEPS ++ ++ ++# _LT_LANG_F77_CONFIG([TAG]) ++# -------------------------- ++# Ensure that the configuration variables for a Fortran 77 compiler are ++# suitably defined. These variables are subsequently used by _LT_CONFIG ++# to write the compiler configuration to 'libtool'. ++m4_defun([_LT_LANG_F77_CONFIG], ++[AC_LANG_PUSH(Fortran 77) ++if test -z "$F77" || test no = "$F77"; then ++ _lt_disable_F77=yes ++fi ++ ++_LT_TAGVAR(archive_cmds_need_lc, $1)=no ++_LT_TAGVAR(allow_undefined_flag, $1)= ++_LT_TAGVAR(always_export_symbols, $1)=no ++_LT_TAGVAR(archive_expsym_cmds, $1)= ++_LT_TAGVAR(export_dynamic_flag_spec, $1)= ++_LT_TAGVAR(hardcode_direct, $1)=no ++_LT_TAGVAR(hardcode_direct_absolute, $1)=no ++_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= ++_LT_TAGVAR(hardcode_libdir_separator, $1)= ++_LT_TAGVAR(hardcode_minus_L, $1)=no ++_LT_TAGVAR(hardcode_automatic, $1)=no ++_LT_TAGVAR(inherit_rpath, $1)=no ++_LT_TAGVAR(module_cmds, $1)= ++_LT_TAGVAR(module_expsym_cmds, $1)= ++_LT_TAGVAR(link_all_deplibs, $1)=unknown ++_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds ++_LT_TAGVAR(reload_flag, $1)=$reload_flag ++_LT_TAGVAR(reload_cmds, $1)=$reload_cmds ++_LT_TAGVAR(no_undefined_flag, $1)= ++_LT_TAGVAR(whole_archive_flag_spec, $1)= ++_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no ++ ++# Source file extension for f77 test sources. ++ac_ext=f ++ ++# Object file extension for compiled f77 test sources. ++objext=o ++_LT_TAGVAR(objext, $1)=$objext ++ ++# No sense in running all these tests if we already determined that ++# the F77 compiler isn't working. Some variables (like enable_shared) ++# are currently assumed to apply to all compilers on this platform, ++# and will be corrupted by setting them based on a non-working compiler. ++if test yes != "$_lt_disable_F77"; then ++ # Code to be used in simple compile tests ++ lt_simple_compile_test_code="\ ++ subroutine t ++ return ++ end ++" ++ ++ # Code to be used in simple link tests ++ lt_simple_link_test_code="\ ++ program t ++ end ++" ++ ++ # ltmain only uses $CC for tagged configurations so make sure $CC is set. ++ _LT_TAG_COMPILER ++ ++ # save warnings/boilerplate of simple test code ++ _LT_COMPILER_BOILERPLATE ++ _LT_LINKER_BOILERPLATE ++ ++ # Allow CC to be a program name with arguments. ++ lt_save_CC=$CC ++ lt_save_GCC=$GCC ++ lt_save_CFLAGS=$CFLAGS ++ CC=${F77-"f77"} ++ CFLAGS=$FFLAGS ++ compiler=$CC ++ _LT_TAGVAR(compiler, $1)=$CC ++ _LT_CC_BASENAME([$compiler]) ++ GCC=$G77 ++ if test -n "$compiler"; then ++ AC_MSG_CHECKING([if libtool supports shared libraries]) ++ AC_MSG_RESULT([$can_build_shared]) ++ ++ AC_MSG_CHECKING([whether to build shared libraries]) ++ test no = "$can_build_shared" && enable_shared=no ++ ++ # On AIX, shared libraries and static libraries use the same namespace, and ++ # are all built from PIC. ++ case $host_os in ++ aix3*) ++ test yes = "$enable_shared" && enable_static=no ++ if test -n "$RANLIB"; then ++ archive_cmds="$archive_cmds~\$RANLIB \$lib" ++ postinstall_cmds='$RANLIB $lib' ++ fi ++ ;; ++ aix[[4-9]]*) ++ if test ia64 != "$host_cpu"; then ++ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in ++ yes,aix,yes) ;; # shared object as lib.so file only ++ yes,svr4,*) ;; # shared object as lib.so archive member only ++ yes,*) enable_static=no ;; # shared object in lib.a archive as well ++ esac ++ fi ++ ;; ++ esac ++ AC_MSG_RESULT([$enable_shared]) ++ ++ AC_MSG_CHECKING([whether to build static libraries]) ++ # Make sure either enable_shared or enable_static is yes. ++ test yes = "$enable_shared" || enable_static=yes ++ AC_MSG_RESULT([$enable_static]) ++ ++ _LT_TAGVAR(GCC, $1)=$G77 ++ _LT_TAGVAR(LD, $1)=$LD ++ ++ ## CAVEAT EMPTOR: ++ ## There is no encapsulation within the following macros, do not change ++ ## the running order or otherwise move them around unless you know exactly ++ ## what you are doing... ++ _LT_COMPILER_PIC($1) ++ _LT_COMPILER_C_O($1) ++ _LT_COMPILER_FILE_LOCKS($1) ++ _LT_LINKER_SHLIBS($1) ++ _LT_SYS_DYNAMIC_LINKER($1) ++ _LT_LINKER_HARDCODE_LIBPATH($1) ++ ++ _LT_CONFIG($1) ++ fi # test -n "$compiler" ++ ++ GCC=$lt_save_GCC ++ CC=$lt_save_CC ++ CFLAGS=$lt_save_CFLAGS ++fi # test yes != "$_lt_disable_F77" ++ ++AC_LANG_POP ++])# _LT_LANG_F77_CONFIG ++ ++ ++# _LT_LANG_FC_CONFIG([TAG]) ++# ------------------------- ++# Ensure that the configuration variables for a Fortran compiler are ++# suitably defined. These variables are subsequently used by _LT_CONFIG ++# to write the compiler configuration to 'libtool'. ++m4_defun([_LT_LANG_FC_CONFIG], ++[AC_LANG_PUSH(Fortran) ++ ++if test -z "$FC" || test no = "$FC"; then ++ _lt_disable_FC=yes ++fi ++ ++_LT_TAGVAR(archive_cmds_need_lc, $1)=no ++_LT_TAGVAR(allow_undefined_flag, $1)= ++_LT_TAGVAR(always_export_symbols, $1)=no ++_LT_TAGVAR(archive_expsym_cmds, $1)= ++_LT_TAGVAR(export_dynamic_flag_spec, $1)= ++_LT_TAGVAR(hardcode_direct, $1)=no ++_LT_TAGVAR(hardcode_direct_absolute, $1)=no ++_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= ++_LT_TAGVAR(hardcode_libdir_separator, $1)= ++_LT_TAGVAR(hardcode_minus_L, $1)=no ++_LT_TAGVAR(hardcode_automatic, $1)=no ++_LT_TAGVAR(inherit_rpath, $1)=no ++_LT_TAGVAR(module_cmds, $1)= ++_LT_TAGVAR(module_expsym_cmds, $1)= ++_LT_TAGVAR(link_all_deplibs, $1)=unknown ++_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds ++_LT_TAGVAR(reload_flag, $1)=$reload_flag ++_LT_TAGVAR(reload_cmds, $1)=$reload_cmds ++_LT_TAGVAR(no_undefined_flag, $1)= ++_LT_TAGVAR(whole_archive_flag_spec, $1)= ++_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no ++ ++# Source file extension for fc test sources. ++ac_ext=${ac_fc_srcext-f} ++ ++# Object file extension for compiled fc test sources. ++objext=o ++_LT_TAGVAR(objext, $1)=$objext ++ ++# No sense in running all these tests if we already determined that ++# the FC compiler isn't working. Some variables (like enable_shared) ++# are currently assumed to apply to all compilers on this platform, ++# and will be corrupted by setting them based on a non-working compiler. ++if test yes != "$_lt_disable_FC"; then ++ # Code to be used in simple compile tests ++ lt_simple_compile_test_code="\ ++ subroutine t ++ return ++ end ++" ++ ++ # Code to be used in simple link tests ++ lt_simple_link_test_code="\ ++ program t ++ end ++" ++ ++ # ltmain only uses $CC for tagged configurations so make sure $CC is set. ++ _LT_TAG_COMPILER ++ ++ # save warnings/boilerplate of simple test code ++ _LT_COMPILER_BOILERPLATE ++ _LT_LINKER_BOILERPLATE ++ ++ # Allow CC to be a program name with arguments. ++ lt_save_CC=$CC ++ lt_save_GCC=$GCC ++ lt_save_CFLAGS=$CFLAGS ++ CC=${FC-"f95"} ++ CFLAGS=$FCFLAGS ++ compiler=$CC ++ GCC=$ac_cv_fc_compiler_gnu ++ ++ _LT_TAGVAR(compiler, $1)=$CC ++ _LT_CC_BASENAME([$compiler]) ++ ++ if test -n "$compiler"; then ++ AC_MSG_CHECKING([if libtool supports shared libraries]) ++ AC_MSG_RESULT([$can_build_shared]) ++ ++ AC_MSG_CHECKING([whether to build shared libraries]) ++ test no = "$can_build_shared" && enable_shared=no ++ ++ # On AIX, shared libraries and static libraries use the same namespace, and ++ # are all built from PIC. ++ case $host_os in ++ aix3*) ++ test yes = "$enable_shared" && enable_static=no ++ if test -n "$RANLIB"; then ++ archive_cmds="$archive_cmds~\$RANLIB \$lib" ++ postinstall_cmds='$RANLIB $lib' ++ fi ++ ;; ++ aix[[4-9]]*) ++ if test ia64 != "$host_cpu"; then ++ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in ++ yes,aix,yes) ;; # shared object as lib.so file only ++ yes,svr4,*) ;; # shared object as lib.so archive member only ++ yes,*) enable_static=no ;; # shared object in lib.a archive as well ++ esac ++ fi ++ ;; ++ esac ++ AC_MSG_RESULT([$enable_shared]) ++ ++ AC_MSG_CHECKING([whether to build static libraries]) ++ # Make sure either enable_shared or enable_static is yes. ++ test yes = "$enable_shared" || enable_static=yes ++ AC_MSG_RESULT([$enable_static]) ++ ++ _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu ++ _LT_TAGVAR(LD, $1)=$LD ++ ++ ## CAVEAT EMPTOR: ++ ## There is no encapsulation within the following macros, do not change ++ ## the running order or otherwise move them around unless you know exactly ++ ## what you are doing... ++ _LT_SYS_HIDDEN_LIBDEPS($1) ++ _LT_COMPILER_PIC($1) ++ _LT_COMPILER_C_O($1) ++ _LT_COMPILER_FILE_LOCKS($1) ++ _LT_LINKER_SHLIBS($1) ++ _LT_SYS_DYNAMIC_LINKER($1) ++ _LT_LINKER_HARDCODE_LIBPATH($1) ++ ++ _LT_CONFIG($1) ++ fi # test -n "$compiler" ++ ++ GCC=$lt_save_GCC ++ CC=$lt_save_CC ++ CFLAGS=$lt_save_CFLAGS ++fi # test yes != "$_lt_disable_FC" ++ ++AC_LANG_POP ++])# _LT_LANG_FC_CONFIG ++ ++ ++# _LT_LANG_GCJ_CONFIG([TAG]) ++# -------------------------- ++# Ensure that the configuration variables for the GNU Java Compiler compiler ++# are suitably defined. These variables are subsequently used by _LT_CONFIG ++# to write the compiler configuration to 'libtool'. ++m4_defun([_LT_LANG_GCJ_CONFIG], ++[AC_REQUIRE([LT_PROG_GCJ])dnl ++AC_LANG_SAVE ++ ++# Source file extension for Java test sources. ++ac_ext=java ++ ++# Object file extension for compiled Java test sources. ++objext=o ++_LT_TAGVAR(objext, $1)=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code="class foo {}" ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' ++ ++# ltmain only uses $CC for tagged configurations so make sure $CC is set. ++_LT_TAG_COMPILER ++ ++# save warnings/boilerplate of simple test code ++_LT_COMPILER_BOILERPLATE ++_LT_LINKER_BOILERPLATE ++ ++# Allow CC to be a program name with arguments. ++lt_save_CC=$CC ++lt_save_CFLAGS=$CFLAGS ++lt_save_GCC=$GCC ++GCC=yes ++CC=${GCJ-"gcj"} ++CFLAGS=$GCJFLAGS ++compiler=$CC ++_LT_TAGVAR(compiler, $1)=$CC ++_LT_TAGVAR(LD, $1)=$LD ++_LT_CC_BASENAME([$compiler]) ++ ++# GCJ did not exist at the time GCC didn't implicitly link libc in. ++_LT_TAGVAR(archive_cmds_need_lc, $1)=no ++ ++_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds ++_LT_TAGVAR(reload_flag, $1)=$reload_flag ++_LT_TAGVAR(reload_cmds, $1)=$reload_cmds ++ ++if test -n "$compiler"; then ++ _LT_COMPILER_NO_RTTI($1) ++ _LT_COMPILER_PIC($1) ++ _LT_COMPILER_C_O($1) ++ _LT_COMPILER_FILE_LOCKS($1) ++ _LT_LINKER_SHLIBS($1) ++ _LT_LINKER_HARDCODE_LIBPATH($1) ++ ++ _LT_CONFIG($1) ++fi ++ ++AC_LANG_RESTORE ++ ++GCC=$lt_save_GCC ++CC=$lt_save_CC ++CFLAGS=$lt_save_CFLAGS ++])# _LT_LANG_GCJ_CONFIG ++ ++ ++# _LT_LANG_GO_CONFIG([TAG]) ++# -------------------------- ++# Ensure that the configuration variables for the GNU Go compiler ++# are suitably defined. These variables are subsequently used by _LT_CONFIG ++# to write the compiler configuration to 'libtool'. ++m4_defun([_LT_LANG_GO_CONFIG], ++[AC_REQUIRE([LT_PROG_GO])dnl ++AC_LANG_SAVE ++ ++# Source file extension for Go test sources. ++ac_ext=go ++ ++# Object file extension for compiled Go test sources. ++objext=o ++_LT_TAGVAR(objext, $1)=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code="package main; func main() { }" ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code='package main; func main() { }' ++ ++# ltmain only uses $CC for tagged configurations so make sure $CC is set. ++_LT_TAG_COMPILER ++ ++# save warnings/boilerplate of simple test code ++_LT_COMPILER_BOILERPLATE ++_LT_LINKER_BOILERPLATE ++ ++# Allow CC to be a program name with arguments. ++lt_save_CC=$CC ++lt_save_CFLAGS=$CFLAGS ++lt_save_GCC=$GCC ++GCC=yes ++CC=${GOC-"gccgo"} ++CFLAGS=$GOFLAGS ++compiler=$CC ++_LT_TAGVAR(compiler, $1)=$CC ++_LT_TAGVAR(LD, $1)=$LD ++_LT_CC_BASENAME([$compiler]) ++ ++# Go did not exist at the time GCC didn't implicitly link libc in. ++_LT_TAGVAR(archive_cmds_need_lc, $1)=no ++ ++_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds ++_LT_TAGVAR(reload_flag, $1)=$reload_flag ++_LT_TAGVAR(reload_cmds, $1)=$reload_cmds ++ ++if test -n "$compiler"; then ++ _LT_COMPILER_NO_RTTI($1) ++ _LT_COMPILER_PIC($1) ++ _LT_COMPILER_C_O($1) ++ _LT_COMPILER_FILE_LOCKS($1) ++ _LT_LINKER_SHLIBS($1) ++ _LT_LINKER_HARDCODE_LIBPATH($1) ++ ++ _LT_CONFIG($1) ++fi ++ ++AC_LANG_RESTORE ++ ++GCC=$lt_save_GCC ++CC=$lt_save_CC ++CFLAGS=$lt_save_CFLAGS ++])# _LT_LANG_GO_CONFIG ++ ++ ++# _LT_LANG_RC_CONFIG([TAG]) ++# ------------------------- ++# Ensure that the configuration variables for the Windows resource compiler ++# are suitably defined. These variables are subsequently used by _LT_CONFIG ++# to write the compiler configuration to 'libtool'. ++m4_defun([_LT_LANG_RC_CONFIG], ++[AC_REQUIRE([LT_PROG_RC])dnl ++AC_LANG_SAVE ++ ++# Source file extension for RC test sources. ++ac_ext=rc ++ ++# Object file extension for compiled RC test sources. ++objext=o ++_LT_TAGVAR(objext, $1)=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code=$lt_simple_compile_test_code ++ ++# ltmain only uses $CC for tagged configurations so make sure $CC is set. ++_LT_TAG_COMPILER ++ ++# save warnings/boilerplate of simple test code ++_LT_COMPILER_BOILERPLATE ++_LT_LINKER_BOILERPLATE ++ ++# Allow CC to be a program name with arguments. ++lt_save_CC=$CC ++lt_save_CFLAGS=$CFLAGS ++lt_save_GCC=$GCC ++GCC= ++CC=${RC-"windres"} ++CFLAGS= ++compiler=$CC ++_LT_TAGVAR(compiler, $1)=$CC ++_LT_CC_BASENAME([$compiler]) ++_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes ++ ++if test -n "$compiler"; then ++ : ++ _LT_CONFIG($1) ++fi ++ ++GCC=$lt_save_GCC ++AC_LANG_RESTORE ++CC=$lt_save_CC ++CFLAGS=$lt_save_CFLAGS ++])# _LT_LANG_RC_CONFIG ++ ++ ++# LT_PROG_GCJ ++# ----------- ++AC_DEFUN([LT_PROG_GCJ], ++[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], ++ [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], ++ [AC_CHECK_TOOL(GCJ, gcj,) ++ test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" ++ AC_SUBST(GCJFLAGS)])])[]dnl ++]) ++ ++# Old name: ++AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([LT_AC_PROG_GCJ], []) ++ ++ ++# LT_PROG_GO ++# ---------- ++AC_DEFUN([LT_PROG_GO], ++[AC_CHECK_TOOL(GOC, gccgo,) ++]) ++ ++ ++# LT_PROG_RC ++# ---------- ++AC_DEFUN([LT_PROG_RC], ++[AC_CHECK_TOOL(RC, windres,) ++]) ++ ++# Old name: ++AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([LT_AC_PROG_RC], []) ++ ++ ++# _LT_DECL_EGREP ++# -------------- ++# If we don't have a new enough Autoconf to choose the best grep ++# available, choose the one first in the user's PATH. ++m4_defun([_LT_DECL_EGREP], ++[AC_REQUIRE([AC_PROG_EGREP])dnl ++AC_REQUIRE([AC_PROG_FGREP])dnl ++test -z "$GREP" && GREP=grep ++_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) ++_LT_DECL([], [EGREP], [1], [An ERE matcher]) ++_LT_DECL([], [FGREP], [1], [A literal string matcher]) ++dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too ++AC_SUBST([GREP]) ++]) ++ ++ ++# _LT_DECL_OBJDUMP ++# -------------- ++# If we don't have a new enough Autoconf to choose the best objdump ++# available, choose the one first in the user's PATH. ++m4_defun([_LT_DECL_OBJDUMP], ++[AC_CHECK_TOOL(OBJDUMP, objdump, false) ++test -z "$OBJDUMP" && OBJDUMP=objdump ++_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) ++AC_SUBST([OBJDUMP]) ++]) ++ ++# _LT_DECL_DLLTOOL ++# ---------------- ++# Ensure DLLTOOL variable is set. ++m4_defun([_LT_DECL_DLLTOOL], ++[AC_CHECK_TOOL(DLLTOOL, dlltool, false) ++test -z "$DLLTOOL" && DLLTOOL=dlltool ++_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) ++AC_SUBST([DLLTOOL]) ++]) ++ ++# _LT_DECL_FILECMD ++# ---------------- ++# Check for a file(cmd) program that can be used to detect file type and magic ++m4_defun([_LT_DECL_FILECMD], ++[AC_CHECK_TOOL([FILECMD], [file], [:]) ++_LT_DECL([], [FILECMD], [1], [A file(cmd) program that detects file types]) ++])# _LD_DECL_FILECMD ++ ++# _LT_DECL_SED ++# ------------ ++# Check for a fully-functional sed program, that truncates ++# as few characters as possible. Prefer GNU sed if found. ++m4_defun([_LT_DECL_SED], ++[AC_PROG_SED ++test -z "$SED" && SED=sed ++Xsed="$SED -e 1s/^X//" ++_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) ++_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], ++ [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ++])# _LT_DECL_SED ++ ++m4_ifndef([AC_PROG_SED], [ ++# NOTE: This macro has been submitted for inclusion into # ++# GNU Autoconf as AC_PROG_SED. When it is available in # ++# a released version of Autoconf we should remove this # ++# macro and use it instead. # ++ ++m4_defun([AC_PROG_SED], ++[AC_MSG_CHECKING([for a sed that does not truncate output]) ++AC_CACHE_VAL(lt_cv_path_SED, ++[# Loop through the user's path and test for sed and gsed. ++# Then use that list of sed's as ones to test for truncation. ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for lt_ac_prog in sed gsed; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then ++ lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" ++ fi ++ done ++ done ++done ++IFS=$as_save_IFS ++lt_ac_max=0 ++lt_ac_count=0 ++# Add /usr/xpg4/bin/sed as it is typically found on Solaris ++# along with /bin/sed that truncates output. ++for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do ++ test ! -f "$lt_ac_sed" && continue ++ cat /dev/null > conftest.in ++ lt_ac_count=0 ++ echo $ECHO_N "0123456789$ECHO_C" >conftest.in ++ # Check for GNU sed and select it if it is found. ++ if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then ++ lt_cv_path_SED=$lt_ac_sed ++ break ++ fi ++ while true; do ++ cat conftest.in conftest.in >conftest.tmp ++ mv conftest.tmp conftest.in ++ cp conftest.in conftest.nl ++ echo >>conftest.nl ++ $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break ++ cmp -s conftest.out conftest.nl || break ++ # 10000 chars as input seems more than enough ++ test 10 -lt "$lt_ac_count" && break ++ lt_ac_count=`expr $lt_ac_count + 1` ++ if test "$lt_ac_count" -gt "$lt_ac_max"; then ++ lt_ac_max=$lt_ac_count ++ lt_cv_path_SED=$lt_ac_sed ++ fi ++ done ++done ++]) ++SED=$lt_cv_path_SED ++AC_SUBST([SED]) ++AC_MSG_RESULT([$SED]) ++])#AC_PROG_SED ++])#m4_ifndef ++ ++# Old name: ++AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([LT_AC_PROG_SED], []) ++ ++ ++# _LT_CHECK_SHELL_FEATURES ++# ------------------------ ++# Find out whether the shell is Bourne or XSI compatible, ++# or has some other useful features. ++m4_defun([_LT_CHECK_SHELL_FEATURES], ++[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then ++ lt_unset=unset ++else ++ lt_unset=false ++fi ++_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl ++ ++# test EBCDIC or ASCII ++case `echo X|tr X '\101'` in ++ A) # ASCII based system ++ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr ++ lt_SP2NL='tr \040 \012' ++ lt_NL2SP='tr \015\012 \040\040' ++ ;; ++ *) # EBCDIC based system ++ lt_SP2NL='tr \100 \n' ++ lt_NL2SP='tr \r\n \100\100' ++ ;; ++esac ++_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl ++_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ++])# _LT_CHECK_SHELL_FEATURES ++ ++ ++# _LT_PATH_CONVERSION_FUNCTIONS ++# ----------------------------- ++# Determine what file name conversion functions should be used by ++# func_to_host_file (and, implicitly, by func_to_host_path). These are needed ++# for certain cross-compile configurations and native mingw. ++m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], ++[AC_REQUIRE([AC_CANONICAL_HOST])dnl ++AC_REQUIRE([AC_CANONICAL_BUILD])dnl ++AC_MSG_CHECKING([how to convert $build file names to $host format]) ++AC_CACHE_VAL(lt_cv_to_host_file_cmd, ++[case $host in ++ *-*-mingw* ) ++ case $build in ++ *-*-mingw* ) # actually msys ++ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ++ ;; ++ *-*-cygwin* ) ++ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ++ ;; ++ * ) # otherwise, assume *nix ++ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ++ ;; ++ esac ++ ;; ++ *-*-cygwin* ) ++ case $build in ++ *-*-mingw* ) # actually msys ++ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ++ ;; ++ *-*-cygwin* ) ++ lt_cv_to_host_file_cmd=func_convert_file_noop ++ ;; ++ * ) # otherwise, assume *nix ++ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ++ ;; ++ esac ++ ;; ++ * ) # unhandled hosts (and "normal" native builds) ++ lt_cv_to_host_file_cmd=func_convert_file_noop ++ ;; ++esac ++]) ++to_host_file_cmd=$lt_cv_to_host_file_cmd ++AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) ++_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], ++ [0], [convert $build file names to $host format])dnl ++ ++AC_MSG_CHECKING([how to convert $build file names to toolchain format]) ++AC_CACHE_VAL(lt_cv_to_tool_file_cmd, ++[#assume ordinary cross tools, or native build. ++lt_cv_to_tool_file_cmd=func_convert_file_noop ++case $host in ++ *-*-mingw* ) ++ case $build in ++ *-*-mingw* ) # actually msys ++ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ++ ;; ++ esac ++ ;; ++esac ++]) ++to_tool_file_cmd=$lt_cv_to_tool_file_cmd ++AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) ++_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], ++ [0], [convert $build files to toolchain format])dnl ++])# _LT_PATH_CONVERSION_FUNCTIONS ++ ++# Helper functions for option handling. -*- Autoconf -*- ++# ++# Copyright (C) 2004-2005, 2007-2009, 2011-2019, 2021-2022 Free ++# Software Foundation, Inc. ++# Written by Gary V. Vaughan, 2004 ++# ++# This file is free software; the Free Software Foundation gives ++# unlimited permission to copy and/or distribute it, with or without ++# modifications, as long as this notice is preserved. ++ ++# serial 8 ltoptions.m4 ++ ++# This is to help aclocal find these macros, as it can't see m4_define. ++AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) ++ ++ ++# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) ++# ------------------------------------------ ++m4_define([_LT_MANGLE_OPTION], ++[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) ++ ++ ++# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) ++# --------------------------------------- ++# Set option OPTION-NAME for macro MACRO-NAME, and if there is a ++# matching handler defined, dispatch to it. Other OPTION-NAMEs are ++# saved as a flag. ++m4_define([_LT_SET_OPTION], ++[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl ++m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), ++ _LT_MANGLE_DEFUN([$1], [$2]), ++ [m4_warning([Unknown $1 option '$2'])])[]dnl ++]) ++ ++ ++# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) ++# ------------------------------------------------------------ ++# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. ++m4_define([_LT_IF_OPTION], ++[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) ++ ++ ++# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) ++# ------------------------------------------------------- ++# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME ++# are set. ++m4_define([_LT_UNLESS_OPTIONS], ++[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), ++ [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), ++ [m4_define([$0_found])])])[]dnl ++m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ++])[]dnl ++]) ++ ++ ++# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) ++# ---------------------------------------- ++# OPTION-LIST is a space-separated list of Libtool options associated ++# with MACRO-NAME. If any OPTION has a matching handler declared with ++# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about ++# the unknown option and exit. ++m4_defun([_LT_SET_OPTIONS], ++[# Set options ++m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), ++ [_LT_SET_OPTION([$1], _LT_Option)]) ++ ++m4_if([$1],[LT_INIT],[ ++ dnl ++ dnl Simply set some default values (i.e off) if boolean options were not ++ dnl specified: ++ _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ++ ]) ++ _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ++ ]) ++ dnl ++ dnl If no reference was made to various pairs of opposing options, then ++ dnl we run the default mode handler for the pair. For example, if neither ++ dnl 'shared' nor 'disable-shared' was passed, we enable building of shared ++ dnl archives by default: ++ _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) ++ _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) ++ _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) ++ _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], ++ [_LT_ENABLE_FAST_INSTALL]) ++ _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], ++ [_LT_WITH_AIX_SONAME([aix])]) ++ ]) ++])# _LT_SET_OPTIONS ++ ++ ++ ++# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) ++# ----------------------------------------- ++m4_define([_LT_MANGLE_DEFUN], ++[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) ++ ++ ++# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) ++# ----------------------------------------------- ++m4_define([LT_OPTION_DEFINE], ++[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ++])# LT_OPTION_DEFINE ++ ++ ++# dlopen ++# ------ ++LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ++]) ++ ++AU_DEFUN([AC_LIBTOOL_DLOPEN], ++[_LT_SET_OPTION([LT_INIT], [dlopen]) ++AC_DIAGNOSE([obsolete], ++[$0: Remove this warning and the call to _LT_SET_OPTION when you ++put the 'dlopen' option into LT_INIT's first parameter.]) ++]) ++ ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) ++ ++ ++# win32-dll ++# --------- ++# Declare package support for building win32 dll's. ++LT_OPTION_DEFINE([LT_INIT], [win32-dll], ++[enable_win32_dll=yes ++ ++case $host in ++*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) ++ AC_CHECK_TOOL(AS, as, false) ++ AC_CHECK_TOOL(DLLTOOL, dlltool, false) ++ AC_CHECK_TOOL(OBJDUMP, objdump, false) ++ ;; ++esac ++ ++test -z "$AS" && AS=as ++_LT_DECL([], [AS], [1], [Assembler program])dnl ++ ++test -z "$DLLTOOL" && DLLTOOL=dlltool ++_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl ++ ++test -z "$OBJDUMP" && OBJDUMP=objdump ++_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ++])# win32-dll ++ ++AU_DEFUN([AC_LIBTOOL_WIN32_DLL], ++[AC_REQUIRE([AC_CANONICAL_HOST])dnl ++_LT_SET_OPTION([LT_INIT], [win32-dll]) ++AC_DIAGNOSE([obsolete], ++[$0: Remove this warning and the call to _LT_SET_OPTION when you ++put the 'win32-dll' option into LT_INIT's first parameter.]) ++]) ++ ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) ++ ++ ++# _LT_ENABLE_SHARED([DEFAULT]) ++# ---------------------------- ++# implement the --enable-shared flag, and supports the 'shared' and ++# 'disable-shared' LT_INIT options. ++# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. ++m4_define([_LT_ENABLE_SHARED], ++[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl ++AC_ARG_ENABLE([shared], ++ [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], ++ [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], ++ [p=${PACKAGE-default} ++ case $enableval in ++ yes) enable_shared=yes ;; ++ no) enable_shared=no ;; ++ *) ++ enable_shared=no ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, ++ for pkg in $enableval; do ++ IFS=$lt_save_ifs ++ if test "X$pkg" = "X$p"; then ++ enable_shared=yes ++ fi ++ done ++ IFS=$lt_save_ifs ++ ;; ++ esac], ++ [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) ++ ++ _LT_DECL([build_libtool_libs], [enable_shared], [0], ++ [Whether or not to build shared libraries]) ++])# _LT_ENABLE_SHARED ++ ++LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) ++LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) ++ ++# Old names: ++AC_DEFUN([AC_ENABLE_SHARED], ++[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ++]) ++ ++AC_DEFUN([AC_DISABLE_SHARED], ++[_LT_SET_OPTION([LT_INIT], [disable-shared]) ++]) ++ ++AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) ++AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) ++ ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AM_ENABLE_SHARED], []) ++dnl AC_DEFUN([AM_DISABLE_SHARED], []) ++ ++ ++ ++# _LT_ENABLE_STATIC([DEFAULT]) ++# ---------------------------- ++# implement the --enable-static flag, and support the 'static' and ++# 'disable-static' LT_INIT options. ++# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. ++m4_define([_LT_ENABLE_STATIC], ++[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl ++AC_ARG_ENABLE([static], ++ [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], ++ [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], ++ [p=${PACKAGE-default} ++ case $enableval in ++ yes) enable_static=yes ;; ++ no) enable_static=no ;; ++ *) ++ enable_static=no ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, ++ for pkg in $enableval; do ++ IFS=$lt_save_ifs ++ if test "X$pkg" = "X$p"; then ++ enable_static=yes ++ fi ++ done ++ IFS=$lt_save_ifs ++ ;; ++ esac], ++ [enable_static=]_LT_ENABLE_STATIC_DEFAULT) ++ ++ _LT_DECL([build_old_libs], [enable_static], [0], ++ [Whether or not to build static libraries]) ++])# _LT_ENABLE_STATIC ++ ++LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) ++LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) ++ ++# Old names: ++AC_DEFUN([AC_ENABLE_STATIC], ++[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ++]) ++ ++AC_DEFUN([AC_DISABLE_STATIC], ++[_LT_SET_OPTION([LT_INIT], [disable-static]) ++]) ++ ++AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) ++AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) ++ ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AM_ENABLE_STATIC], []) ++dnl AC_DEFUN([AM_DISABLE_STATIC], []) ++ ++ ++ ++# _LT_ENABLE_FAST_INSTALL([DEFAULT]) ++# ---------------------------------- ++# implement the --enable-fast-install flag, and support the 'fast-install' ++# and 'disable-fast-install' LT_INIT options. ++# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. ++m4_define([_LT_ENABLE_FAST_INSTALL], ++[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl ++AC_ARG_ENABLE([fast-install], ++ [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], ++ [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], ++ [p=${PACKAGE-default} ++ case $enableval in ++ yes) enable_fast_install=yes ;; ++ no) enable_fast_install=no ;; ++ *) ++ enable_fast_install=no ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, ++ for pkg in $enableval; do ++ IFS=$lt_save_ifs ++ if test "X$pkg" = "X$p"; then ++ enable_fast_install=yes ++ fi ++ done ++ IFS=$lt_save_ifs ++ ;; ++ esac], ++ [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) ++ ++_LT_DECL([fast_install], [enable_fast_install], [0], ++ [Whether or not to optimize for fast installation])dnl ++])# _LT_ENABLE_FAST_INSTALL ++ ++LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) ++LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) ++ ++# Old names: ++AU_DEFUN([AC_ENABLE_FAST_INSTALL], ++[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) ++AC_DIAGNOSE([obsolete], ++[$0: Remove this warning and the call to _LT_SET_OPTION when you put ++the 'fast-install' option into LT_INIT's first parameter.]) ++]) ++ ++AU_DEFUN([AC_DISABLE_FAST_INSTALL], ++[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) ++AC_DIAGNOSE([obsolete], ++[$0: Remove this warning and the call to _LT_SET_OPTION when you put ++the 'disable-fast-install' option into LT_INIT's first parameter.]) ++]) ++ ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) ++dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) ++ ++ ++# _LT_WITH_AIX_SONAME([DEFAULT]) ++# ---------------------------------- ++# implement the --with-aix-soname flag, and support the `aix-soname=aix' ++# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT ++# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. ++m4_define([_LT_WITH_AIX_SONAME], ++[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl ++shared_archive_member_spec= ++case $host,$enable_shared in ++power*-*-aix[[5-9]]*,yes) ++ AC_MSG_CHECKING([which variant of shared library versioning to provide]) ++ AC_ARG_WITH([aix-soname], ++ [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], ++ [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], ++ [case $withval in ++ aix|svr4|both) ++ ;; ++ *) ++ AC_MSG_ERROR([Unknown argument to --with-aix-soname]) ++ ;; ++ esac ++ lt_cv_with_aix_soname=$with_aix_soname], ++ [AC_CACHE_VAL([lt_cv_with_aix_soname], ++ [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) ++ with_aix_soname=$lt_cv_with_aix_soname]) ++ AC_MSG_RESULT([$with_aix_soname]) ++ if test aix != "$with_aix_soname"; then ++ # For the AIX way of multilib, we name the shared archive member ++ # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', ++ # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. ++ # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, ++ # the AIX toolchain works better with OBJECT_MODE set (default 32). ++ if test 64 = "${OBJECT_MODE-32}"; then ++ shared_archive_member_spec=shr_64 ++ else ++ shared_archive_member_spec=shr ++ fi ++ fi ++ ;; ++*) ++ with_aix_soname=aix ++ ;; ++esac ++ ++_LT_DECL([], [shared_archive_member_spec], [0], ++ [Shared archive member basename, for filename based shared library versioning on AIX])dnl ++])# _LT_WITH_AIX_SONAME ++ ++LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) ++LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) ++LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) ++ ++ ++# _LT_WITH_PIC([MODE]) ++# -------------------- ++# implement the --with-pic flag, and support the 'pic-only' and 'no-pic' ++# LT_INIT options. ++# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. ++m4_define([_LT_WITH_PIC], ++[AC_ARG_WITH([pic], ++ [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], ++ [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], ++ [lt_p=${PACKAGE-default} ++ case $withval in ++ yes|no) pic_mode=$withval ;; ++ *) ++ pic_mode=default ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, ++ for lt_pkg in $withval; do ++ IFS=$lt_save_ifs ++ if test "X$lt_pkg" = "X$lt_p"; then ++ pic_mode=yes ++ fi ++ done ++ IFS=$lt_save_ifs ++ ;; ++ esac], ++ [pic_mode=m4_default([$1], [default])]) ++ ++_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ++])# _LT_WITH_PIC ++ ++LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) ++LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) ++ ++# Old name: ++AU_DEFUN([AC_LIBTOOL_PICMODE], ++[_LT_SET_OPTION([LT_INIT], [pic-only]) ++AC_DIAGNOSE([obsolete], ++[$0: Remove this warning and the call to _LT_SET_OPTION when you ++put the 'pic-only' option into LT_INIT's first parameter.]) ++]) ++ ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ++ ++ ++m4_define([_LTDL_MODE], []) ++LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], ++ [m4_define([_LTDL_MODE], [nonrecursive])]) ++LT_OPTION_DEFINE([LTDL_INIT], [recursive], ++ [m4_define([_LTDL_MODE], [recursive])]) ++LT_OPTION_DEFINE([LTDL_INIT], [subproject], ++ [m4_define([_LTDL_MODE], [subproject])]) ++ ++m4_define([_LTDL_TYPE], []) ++LT_OPTION_DEFINE([LTDL_INIT], [installable], ++ [m4_define([_LTDL_TYPE], [installable])]) ++LT_OPTION_DEFINE([LTDL_INIT], [convenience], ++ [m4_define([_LTDL_TYPE], [convenience])]) ++ ++# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- ++# ++# Copyright (C) 2004-2005, 2007-2008, 2011-2019, 2021-2022 Free Software ++# Foundation, Inc. ++# Written by Gary V. Vaughan, 2004 ++# ++# This file is free software; the Free Software Foundation gives ++# unlimited permission to copy and/or distribute it, with or without ++# modifications, as long as this notice is preserved. ++ ++# serial 6 ltsugar.m4 ++ ++# This is to help aclocal find these macros, as it can't see m4_define. ++AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) ++ ++ ++# lt_join(SEP, ARG1, [ARG2...]) ++# ----------------------------- ++# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their ++# associated separator. ++# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier ++# versions in m4sugar had bugs. ++m4_define([lt_join], ++[m4_if([$#], [1], [], ++ [$#], [2], [[$2]], ++ [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) ++m4_define([_lt_join], ++[m4_if([$#$2], [2], [], ++ [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) ++ ++ ++# lt_car(LIST) ++# lt_cdr(LIST) ++# ------------ ++# Manipulate m4 lists. ++# These macros are necessary as long as will still need to support ++# Autoconf-2.59, which quotes differently. ++m4_define([lt_car], [[$1]]) ++m4_define([lt_cdr], ++[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], ++ [$#], 1, [], ++ [m4_dquote(m4_shift($@))])]) ++m4_define([lt_unquote], $1) ++ ++ ++# lt_append(MACRO-NAME, STRING, [SEPARATOR]) ++# ------------------------------------------ ++# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. ++# Note that neither SEPARATOR nor STRING are expanded; they are appended ++# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). ++# No SEPARATOR is output if MACRO-NAME was previously undefined (different ++# than defined and empty). ++# ++# This macro is needed until we can rely on Autoconf 2.62, since earlier ++# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. ++m4_define([lt_append], ++[m4_define([$1], ++ m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) ++ ++ ++ ++# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) ++# ---------------------------------------------------------- ++# Produce a SEP delimited list of all paired combinations of elements of ++# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list ++# has the form PREFIXmINFIXSUFFIXn. ++# Needed until we can rely on m4_combine added in Autoconf 2.62. ++m4_define([lt_combine], ++[m4_if(m4_eval([$# > 3]), [1], ++ [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl ++[[m4_foreach([_Lt_prefix], [$2], ++ [m4_foreach([_Lt_suffix], ++ ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, ++ [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) ++ ++ ++# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) ++# ----------------------------------------------------------------------- ++# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited ++# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. ++m4_define([lt_if_append_uniq], ++[m4_ifdef([$1], ++ [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], ++ [lt_append([$1], [$2], [$3])$4], ++ [$5])], ++ [lt_append([$1], [$2], [$3])$4])]) ++ ++ ++# lt_dict_add(DICT, KEY, VALUE) ++# ----------------------------- ++m4_define([lt_dict_add], ++[m4_define([$1($2)], [$3])]) ++ ++ ++# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) ++# -------------------------------------------- ++m4_define([lt_dict_add_subkey], ++[m4_define([$1($2:$3)], [$4])]) ++ ++ ++# lt_dict_fetch(DICT, KEY, [SUBKEY]) ++# ---------------------------------- ++m4_define([lt_dict_fetch], ++[m4_ifval([$3], ++ m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), ++ m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) ++ ++ ++# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) ++# ----------------------------------------------------------------- ++m4_define([lt_if_dict_fetch], ++[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], ++ [$5], ++ [$6])]) ++ ++ ++# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) ++# -------------------------------------------------------------- ++m4_define([lt_dict_filter], ++[m4_if([$5], [], [], ++ [lt_join(m4_quote(m4_default([$4], [[, ]])), ++ lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), ++ [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ++]) ++ ++# ltversion.m4 -- version numbers -*- Autoconf -*- ++# ++# Copyright (C) 2004, 2011-2019, 2021-2022 Free Software Foundation, ++# Inc. ++# Written by Scott James Remnant, 2004 ++# ++# This file is free software; the Free Software Foundation gives ++# unlimited permission to copy and/or distribute it, with or without ++# modifications, as long as this notice is preserved. ++ ++# @configure_input@ ++ ++# serial 4249 ltversion.m4 ++# This file is part of GNU Libtool ++ ++m4_define([LT_PACKAGE_VERSION], [2.4.7.4-1ec8f-dirty]) ++m4_define([LT_PACKAGE_REVISION], [2.4.7.4]) ++ ++AC_DEFUN([LTVERSION_VERSION], ++[macro_version='2.4.7.4-1ec8f-dirty' ++macro_revision='2.4.7.4' ++_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) ++_LT_DECL(, macro_revision, 0) ++]) ++ ++# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- ++# ++# Copyright (C) 2004-2005, 2007, 2009, 2011-2019, 2021-2022 Free ++# Software Foundation, Inc. ++# Written by Scott James Remnant, 2004. ++# ++# This file is free software; the Free Software Foundation gives ++# unlimited permission to copy and/or distribute it, with or without ++# modifications, as long as this notice is preserved. ++ ++# serial 5 lt~obsolete.m4 ++ ++# These exist entirely to fool aclocal when bootstrapping libtool. ++# ++# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), ++# which have later been changed to m4_define as they aren't part of the ++# exported API, or moved to Autoconf or Automake where they belong. ++# ++# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN ++# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us ++# using a macro with the same name in our local m4/libtool.m4 it'll ++# pull the old libtool.m4 in (it doesn't see our shiny new m4_define ++# and doesn't know about Autoconf macros at all.) ++# ++# So we provide this file, which has a silly filename so it's always ++# included after everything else. This provides aclocal with the ++# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything ++# because those macros already exist, or will be overwritten later. ++# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. ++# ++# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. ++# Yes, that means every name once taken will need to remain here until ++# we give up compatibility with versions before 1.7, at which point ++# we need to keep only those names which we still refer to. ++ ++# This is to help aclocal find these macros, as it can't see m4_define. ++AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) ++ ++m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) ++m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) ++m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) ++m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) ++m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) ++m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) ++m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) ++m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) ++m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) ++m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) ++m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) ++m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) ++m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) ++m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) ++m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) ++m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) ++m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) ++m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) ++m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) ++m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) ++m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) ++m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) ++m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) ++m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) ++m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) ++m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) ++m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) ++m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) ++m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) ++m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) ++m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) ++m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) ++m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) ++m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) ++m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) ++m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) ++m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) ++m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) ++m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) ++m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) ++m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) ++m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) ++m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) ++m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) ++m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) ++m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) ++m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) ++m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) ++m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) ++m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) ++m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) ++m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) ++m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) ++m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) ++m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) ++m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) ++m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) ++m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) ++m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) ++m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) ++m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) ++ ++# nls.m4 serial 6 (gettext-0.20.2) ++dnl Copyright (C) 1995-2003, 2005-2006, 2008-2014, 2016, 2019-2022 Free ++dnl Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++dnl ++dnl This file can be used in projects which are not available under ++dnl the GNU General Public License or the GNU Lesser General Public ++dnl License but which still want to provide support for the GNU gettext ++dnl functionality. ++dnl Please note that the actual code of the GNU gettext library is covered ++dnl by the GNU Lesser General Public License, and the rest of the GNU ++dnl gettext package is covered by the GNU General Public License. ++dnl They are *not* in the public domain. ++ ++dnl Authors: ++dnl Ulrich Drepper , 1995-2000. ++dnl Bruno Haible , 2000-2003. ++ ++AC_PREREQ([2.50]) ++ ++AC_DEFUN([AM_NLS], ++[ ++ AC_MSG_CHECKING([whether NLS is requested]) ++ dnl Default is enabled NLS ++ AC_ARG_ENABLE([nls], ++ [ --disable-nls do not use Native Language Support], ++ USE_NLS=$enableval, USE_NLS=yes) ++ AC_MSG_RESULT([$USE_NLS]) ++ AC_SUBST([USE_NLS]) ++]) ++ ++# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- ++# serial 11 (pkg-config-0.29.1) ++ ++dnl Copyright © 2004 Scott James Remnant . ++dnl Copyright © 2012-2015 Dan Nicholson ++dnl ++dnl This program is free software; you can redistribute it and/or modify ++dnl it under the terms of the GNU General Public License as published by ++dnl the Free Software Foundation; either version 2 of the License, or ++dnl (at your option) any later version. ++dnl ++dnl This program is distributed in the hope that it will be useful, but ++dnl WITHOUT ANY WARRANTY; without even the implied warranty of ++dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++dnl General Public License for more details. ++dnl ++dnl You should have received a copy of the GNU General Public License ++dnl along with this program; if not, write to the Free Software ++dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA ++dnl 02111-1307, USA. ++dnl ++dnl As a special exception to the GNU General Public License, if you ++dnl distribute this file as part of a program that contains a ++dnl configuration script generated by Autoconf, you may include it under ++dnl the same distribution terms that you use for the rest of that ++dnl program. ++ ++dnl PKG_PREREQ(MIN-VERSION) ++dnl ----------------------- ++dnl Since: 0.29 ++dnl ++dnl Verify that the version of the pkg-config macros are at least ++dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's ++dnl installed version of pkg-config, this checks the developer's version ++dnl of pkg.m4 when generating configure. ++dnl ++dnl To ensure that this macro is defined, also add: ++dnl m4_ifndef([PKG_PREREQ], ++dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) ++dnl ++dnl See the "Since" comment for each macro you use to see what version ++dnl of the macros you require. ++m4_defun([PKG_PREREQ], ++[m4_define([PKG_MACROS_VERSION], [0.29.1]) ++m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, ++ [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ++])dnl PKG_PREREQ ++ ++dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) ++dnl ---------------------------------- ++dnl Since: 0.16 ++dnl ++dnl Search for the pkg-config tool and set the PKG_CONFIG variable to ++dnl first found in the path. Checks that the version of pkg-config found ++dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is ++dnl used since that's the first version where most current features of ++dnl pkg-config existed. ++AC_DEFUN([PKG_PROG_PKG_CONFIG], ++[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) ++m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) ++m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) ++AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) ++AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) ++AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) ++ ++if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then ++ AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) ++fi ++if test -n "$PKG_CONFIG"; then ++ _pkg_min_version=m4_default([$1], [0.9.0]) ++ AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) ++ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then ++ AC_MSG_RESULT([yes]) ++ else ++ AC_MSG_RESULT([no]) ++ PKG_CONFIG="" ++ fi ++fi[]dnl ++])dnl PKG_PROG_PKG_CONFIG ++ ++dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) ++dnl ------------------------------------------------------------------- ++dnl Since: 0.18 ++dnl ++dnl Check to see whether a particular set of modules exists. Similar to ++dnl PKG_CHECK_MODULES(), but does not set variables or print errors. ++dnl ++dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) ++dnl only at the first occurence in configure.ac, so if the first place ++dnl it's called might be skipped (such as if it is within an "if", you ++dnl have to call PKG_CHECK_EXISTS manually ++AC_DEFUN([PKG_CHECK_EXISTS], ++[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl ++if test -n "$PKG_CONFIG" && \ ++ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then ++ m4_default([$2], [:]) ++m4_ifvaln([$3], [else ++ $3])dnl ++fi]) ++ ++dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) ++dnl --------------------------------------------- ++dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting ++dnl pkg_failed based on the result. ++m4_define([_PKG_CONFIG], ++[if test -n "$$1"; then ++ pkg_cv_[]$1="$$1" ++ elif test -n "$PKG_CONFIG"; then ++ PKG_CHECK_EXISTS([$3], ++ [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` ++ test "x$?" != "x0" && pkg_failed=yes ], ++ [pkg_failed=yes]) ++ else ++ pkg_failed=untried ++fi[]dnl ++])dnl _PKG_CONFIG ++ ++dnl _PKG_SHORT_ERRORS_SUPPORTED ++dnl --------------------------- ++dnl Internal check to see if pkg-config supports short errors. ++AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], ++[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) ++if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then ++ _pkg_short_errors_supported=yes ++else ++ _pkg_short_errors_supported=no ++fi[]dnl ++])dnl _PKG_SHORT_ERRORS_SUPPORTED ++ ++ ++dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], ++dnl [ACTION-IF-NOT-FOUND]) ++dnl -------------------------------------------------------------- ++dnl Since: 0.4.0 ++dnl ++dnl Note that if there is a possibility the first call to ++dnl PKG_CHECK_MODULES might not happen, you should be sure to include an ++dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac ++AC_DEFUN([PKG_CHECK_MODULES], ++[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl ++AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl ++AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl ++ ++pkg_failed=no ++AC_MSG_CHECKING([for $1]) ++ ++_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) ++_PKG_CONFIG([$1][_LIBS], [libs], [$2]) ++ ++m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS ++and $1[]_LIBS to avoid the need to call pkg-config. ++See the pkg-config man page for more details.]) ++ ++if test $pkg_failed = yes; then ++ AC_MSG_RESULT([no]) ++ _PKG_SHORT_ERRORS_SUPPORTED ++ if test $_pkg_short_errors_supported = yes; then ++ $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` ++ else ++ $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` ++ fi ++ # Put the nasty error message in config.log where it belongs ++ echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD ++ ++ m4_default([$4], [AC_MSG_ERROR( ++[Package requirements ($2) were not met: ++ ++$$1_PKG_ERRORS ++ ++Consider adjusting the PKG_CONFIG_PATH environment variable if you ++installed software in a non-standard prefix. ++ ++_PKG_TEXT])[]dnl ++ ]) ++elif test $pkg_failed = untried; then ++ AC_MSG_RESULT([no]) ++ m4_default([$4], [AC_MSG_FAILURE( ++[The pkg-config script could not be found or is too old. Make sure it ++is in your PATH or set the PKG_CONFIG environment variable to the full ++path to pkg-config. ++ ++_PKG_TEXT ++ ++To get pkg-config, see .])[]dnl ++ ]) ++else ++ $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS ++ $1[]_LIBS=$pkg_cv_[]$1[]_LIBS ++ AC_MSG_RESULT([yes]) ++ $3 ++fi[]dnl ++])dnl PKG_CHECK_MODULES ++ ++ ++dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], ++dnl [ACTION-IF-NOT-FOUND]) ++dnl --------------------------------------------------------------------- ++dnl Since: 0.29 ++dnl ++dnl Checks for existence of MODULES and gathers its build flags with ++dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags ++dnl and VARIABLE-PREFIX_LIBS from --libs. ++dnl ++dnl Note that if there is a possibility the first call to ++dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to ++dnl include an explicit call to PKG_PROG_PKG_CONFIG in your ++dnl configure.ac. ++AC_DEFUN([PKG_CHECK_MODULES_STATIC], ++[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl ++_save_PKG_CONFIG=$PKG_CONFIG ++PKG_CONFIG="$PKG_CONFIG --static" ++PKG_CHECK_MODULES($@) ++PKG_CONFIG=$_save_PKG_CONFIG[]dnl ++])dnl PKG_CHECK_MODULES_STATIC ++ ++ ++dnl PKG_INSTALLDIR([DIRECTORY]) ++dnl ------------------------- ++dnl Since: 0.27 ++dnl ++dnl Substitutes the variable pkgconfigdir as the location where a module ++dnl should install pkg-config .pc files. By default the directory is ++dnl $libdir/pkgconfig, but the default can be changed by passing ++dnl DIRECTORY. The user can override through the --with-pkgconfigdir ++dnl parameter. ++AC_DEFUN([PKG_INSTALLDIR], ++[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) ++m4_pushdef([pkg_description], ++ [pkg-config installation directory @<:@]pkg_default[@:>@]) ++AC_ARG_WITH([pkgconfigdir], ++ [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, ++ [with_pkgconfigdir=]pkg_default) ++AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) ++m4_popdef([pkg_default]) ++m4_popdef([pkg_description]) ++])dnl PKG_INSTALLDIR ++ ++ ++dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) ++dnl -------------------------------- ++dnl Since: 0.27 ++dnl ++dnl Substitutes the variable noarch_pkgconfigdir as the location where a ++dnl module should install arch-independent pkg-config .pc files. By ++dnl default the directory is $datadir/pkgconfig, but the default can be ++dnl changed by passing DIRECTORY. The user can override through the ++dnl --with-noarch-pkgconfigdir parameter. ++AC_DEFUN([PKG_NOARCH_INSTALLDIR], ++[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) ++m4_pushdef([pkg_description], ++ [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) ++AC_ARG_WITH([noarch-pkgconfigdir], ++ [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, ++ [with_noarch_pkgconfigdir=]pkg_default) ++AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) ++m4_popdef([pkg_default]) ++m4_popdef([pkg_description]) ++])dnl PKG_NOARCH_INSTALLDIR ++ ++ ++dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, ++dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) ++dnl ------------------------------------------- ++dnl Since: 0.28 ++dnl ++dnl Retrieves the value of the pkg-config variable for the given module. ++AC_DEFUN([PKG_CHECK_VAR], ++[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl ++AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl ++ ++_PKG_CONFIG([$1], [variable="][$3]["], [$2]) ++AS_VAR_COPY([$1], [pkg_cv_][$1]) ++ ++AS_VAR_IF([$1], [""], [$5], [$4])dnl ++])dnl PKG_CHECK_VAR ++ ++dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES, ++dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND], ++dnl [DESCRIPTION], [DEFAULT]) ++dnl ------------------------------------------ ++dnl ++dnl Prepare a "--with-" configure option using the lowercase ++dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and ++dnl PKG_CHECK_MODULES in a single macro. ++AC_DEFUN([PKG_WITH_MODULES], ++[ ++m4_pushdef([with_arg], m4_tolower([$1])) ++ ++m4_pushdef([description], ++ [m4_default([$5], [build with ]with_arg[ support])]) ++ ++m4_pushdef([def_arg], [m4_default([$6], [auto])]) ++m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes]) ++m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no]) ++ ++m4_case(def_arg, ++ [yes],[m4_pushdef([with_without], [--without-]with_arg)], ++ [m4_pushdef([with_without],[--with-]with_arg)]) ++ ++AC_ARG_WITH(with_arg, ++ AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),, ++ [AS_TR_SH([with_]with_arg)=def_arg]) ++ ++AS_CASE([$AS_TR_SH([with_]with_arg)], ++ [yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)], ++ [auto],[PKG_CHECK_MODULES([$1],[$2], ++ [m4_n([def_action_if_found]) $3], ++ [m4_n([def_action_if_not_found]) $4])]) ++ ++m4_popdef([with_arg]) ++m4_popdef([description]) ++m4_popdef([def_arg]) ++ ++])dnl PKG_WITH_MODULES ++ ++dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES, ++dnl [DESCRIPTION], [DEFAULT]) ++dnl ----------------------------------------------- ++dnl ++dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES ++dnl check._[VARIABLE-PREFIX] is exported as make variable. ++AC_DEFUN([PKG_HAVE_WITH_MODULES], ++[ ++PKG_WITH_MODULES([$1],[$2],,,[$3],[$4]) ++ ++AM_CONDITIONAL([HAVE_][$1], ++ [test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"]) ++])dnl PKG_HAVE_WITH_MODULES ++ ++dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES, ++dnl [DESCRIPTION], [DEFAULT]) ++dnl ------------------------------------------------------ ++dnl ++dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after ++dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make ++dnl and preprocessor variable. ++AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES], ++[ ++PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4]) ++ ++AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"], ++ [AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])]) ++])dnl PKG_HAVE_DEFINE_WITH_MODULES ++ ++# po.m4 serial 32 (gettext-0.21.1) ++dnl Copyright (C) 1995-2014, 2016, 2018-2022 Free Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++dnl ++dnl This file can be used in projects which are not available under ++dnl the GNU General Public License or the GNU Lesser General Public ++dnl License but which still want to provide support for the GNU gettext ++dnl functionality. ++dnl Please note that the actual code of the GNU gettext library is covered ++dnl by the GNU Lesser General Public License, and the rest of the GNU ++dnl gettext package is covered by the GNU General Public License. ++dnl They are *not* in the public domain. ++ ++dnl Authors: ++dnl Ulrich Drepper , 1995-2000. ++dnl Bruno Haible , 2000-2003. ++ ++AC_PREREQ([2.60]) ++ ++dnl Checks for all prerequisites of the po subdirectory. ++AC_DEFUN([AM_PO_SUBDIRS], ++[ ++ AC_REQUIRE([AC_PROG_MAKE_SET])dnl ++ AC_REQUIRE([AC_PROG_INSTALL])dnl ++ AC_REQUIRE([AC_PROG_MKDIR_P])dnl ++ AC_REQUIRE([AC_PROG_SED])dnl ++ AC_REQUIRE([AM_NLS])dnl ++ ++ dnl Release version of the gettext macros. This is used to ensure that ++ dnl the gettext macros and po/Makefile.in.in are in sync. ++ AC_SUBST([GETTEXT_MACRO_VERSION], [0.20]) ++ ++ dnl Perform the following tests also if --disable-nls has been given, ++ dnl because they are needed for "make dist" to work. ++ ++ dnl Search for GNU msgfmt in the PATH. ++ dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. ++ dnl The second test excludes FreeBSD msgfmt. ++ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, ++ [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && ++ (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], ++ :) ++ AC_PATH_PROG([GMSGFMT], [gmsgfmt], [$MSGFMT]) ++ ++ dnl Test whether it is GNU msgfmt >= 0.15. ++changequote(,)dnl ++ case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in ++ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;; ++ *) GMSGFMT_015=$GMSGFMT ;; ++ esac ++changequote([,])dnl ++ AC_SUBST([GMSGFMT_015]) ++ ++ dnl Search for GNU xgettext 0.12 or newer in the PATH. ++ dnl The first test excludes Solaris xgettext and early GNU xgettext versions. ++ dnl The second test excludes FreeBSD xgettext. ++ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, ++ [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && ++ (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], ++ :) ++ dnl Remove leftover from FreeBSD xgettext call. ++ rm -f messages.po ++ ++ dnl Test whether it is GNU xgettext >= 0.15. ++changequote(,)dnl ++ case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in ++ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;; ++ *) XGETTEXT_015=$XGETTEXT ;; ++ esac ++changequote([,])dnl ++ AC_SUBST([XGETTEXT_015]) ++ ++ dnl Search for GNU msgmerge 0.11 or newer in the PATH. ++ AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, ++ [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :) ++ ++ dnl Test whether it is GNU msgmerge >= 0.20. ++ if LC_ALL=C $MSGMERGE --help | grep ' --for-msgfmt ' >/dev/null; then ++ MSGMERGE_FOR_MSGFMT_OPTION='--for-msgfmt' ++ else ++ dnl Test whether it is GNU msgmerge >= 0.12. ++ if LC_ALL=C $MSGMERGE --help | grep ' --no-fuzzy-matching ' >/dev/null; then ++ MSGMERGE_FOR_MSGFMT_OPTION='--no-fuzzy-matching --no-location --quiet' ++ else ++ dnl With these old versions, $(MSGMERGE) $(MSGMERGE_FOR_MSGFMT_OPTION) is ++ dnl slow. But this is not a big problem, as such old gettext versions are ++ dnl hardly in use any more. ++ MSGMERGE_FOR_MSGFMT_OPTION='--no-location --quiet' ++ fi ++ fi ++ AC_SUBST([MSGMERGE_FOR_MSGFMT_OPTION]) ++ ++ dnl Support for AM_XGETTEXT_OPTION. ++ test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS= ++ AC_SUBST([XGETTEXT_EXTRA_OPTIONS]) ++ ++ AC_CONFIG_COMMANDS([po-directories], [[ ++ for ac_file in $CONFIG_FILES; do ++ # Support "outfile[:infile[:infile...]]" ++ case "$ac_file" in ++ *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; ++ esac ++ # PO directories have a Makefile.in generated from Makefile.in.in. ++ case "$ac_file" in */Makefile.in) ++ # Adjust a relative srcdir. ++ ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` ++ ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'` ++ ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` ++ # In autoconf-2.13 it is called $ac_given_srcdir. ++ # In autoconf-2.50 it is called $srcdir. ++ test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" ++ case "$ac_given_srcdir" in ++ .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; ++ /*) top_srcdir="$ac_given_srcdir" ;; ++ *) top_srcdir="$ac_dots$ac_given_srcdir" ;; ++ esac ++ # Treat a directory as a PO directory if and only if it has a ++ # POTFILES.in file. This allows packages to have multiple PO ++ # directories under different names or in different locations. ++ if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then ++ rm -f "$ac_dir/POTFILES" ++ test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" ++ gt_tab=`printf '\t'` ++ cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ${gt_tab}]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" ++ POMAKEFILEDEPS="POTFILES.in" ++ # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend ++ # on $ac_dir but don't depend on user-specified configuration ++ # parameters. ++ if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then ++ # The LINGUAS file contains the set of available languages. ++ if test -n "$OBSOLETE_ALL_LINGUAS"; then ++ test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" ++ fi ++ ALL_LINGUAS=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` ++ POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" ++ else ++ # The set of available languages was given in configure.in. ++ ALL_LINGUAS=$OBSOLETE_ALL_LINGUAS ++ fi ++ # Compute POFILES ++ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) ++ # Compute UPDATEPOFILES ++ # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) ++ # Compute DUMMYPOFILES ++ # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) ++ # Compute GMOFILES ++ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) ++ case "$ac_given_srcdir" in ++ .) srcdirpre= ;; ++ *) srcdirpre='$(srcdir)/' ;; ++ esac ++ POFILES= ++ UPDATEPOFILES= ++ DUMMYPOFILES= ++ GMOFILES= ++ for lang in $ALL_LINGUAS; do ++ POFILES="$POFILES $srcdirpre$lang.po" ++ UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" ++ DUMMYPOFILES="$DUMMYPOFILES $lang.nop" ++ GMOFILES="$GMOFILES $srcdirpre$lang.gmo" ++ done ++ # CATALOGS depends on both $ac_dir and the user's LINGUAS ++ # environment variable. ++ INST_LINGUAS= ++ if test -n "$ALL_LINGUAS"; then ++ for presentlang in $ALL_LINGUAS; do ++ useit=no ++ if test "%UNSET%" != "$LINGUAS"; then ++ desiredlanguages="$LINGUAS" ++ else ++ desiredlanguages="$ALL_LINGUAS" ++ fi ++ for desiredlang in $desiredlanguages; do ++ # Use the presentlang catalog if desiredlang is ++ # a. equal to presentlang, or ++ # b. a variant of presentlang (because in this case, ++ # presentlang can be used as a fallback for messages ++ # which are not translated in the desiredlang catalog). ++ case "$desiredlang" in ++ "$presentlang" | "$presentlang"_* | "$presentlang".* | "$presentlang"@*) ++ useit=yes ++ ;; ++ esac ++ done ++ if test $useit = yes; then ++ INST_LINGUAS="$INST_LINGUAS $presentlang" ++ fi ++ done ++ fi ++ CATALOGS= ++ if test -n "$INST_LINGUAS"; then ++ for lang in $INST_LINGUAS; do ++ CATALOGS="$CATALOGS $lang.gmo" ++ done ++ fi ++ test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" ++ sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" ++ for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do ++ if test -f "$f"; then ++ case "$f" in ++ *.orig | *.bak | *~) ;; ++ *) cat "$f" >> "$ac_dir/Makefile" ;; ++ esac ++ fi ++ done ++ fi ++ ;; ++ esac ++ done]], ++ [# Capture the value of obsolete ALL_LINGUAS because we need it to compute ++ # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. ++ OBSOLETE_ALL_LINGUAS="$ALL_LINGUAS" ++ # Capture the value of LINGUAS because we need it to compute CATALOGS. ++ LINGUAS="${LINGUAS-%UNSET%}" ++ ]) ++]) ++ ++dnl Postprocesses a Makefile in a directory containing PO files. ++AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE], ++[ ++ # When this code is run, in config.status, two variables have already been ++ # set: ++ # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in, ++ # - LINGUAS is the value of the environment variable LINGUAS at configure ++ # time. ++ ++changequote(,)dnl ++ # Adjust a relative srcdir. ++ ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` ++ ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'` ++ ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` ++ # In autoconf-2.13 it is called $ac_given_srcdir. ++ # In autoconf-2.50 it is called $srcdir. ++ test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" ++ case "$ac_given_srcdir" in ++ .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; ++ /*) top_srcdir="$ac_given_srcdir" ;; ++ *) top_srcdir="$ac_dots$ac_given_srcdir" ;; ++ esac ++ ++ # Find a way to echo strings without interpreting backslash. ++ if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then ++ gt_echo='echo' ++ else ++ if test "X`(printf '%s\n' '\t') 2>/dev/null`" = 'X\t'; then ++ gt_echo='printf %s\n' ++ else ++ echo_func () { ++ cat < "$ac_file.tmp" ++ tab=`printf '\t'` ++ if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then ++ # Add dependencies that cannot be formulated as a simple suffix rule. ++ for lang in $ALL_LINGUAS; do ++ frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` ++ cat >> "$ac_file.tmp" < /dev/null; then ++ # Add dependencies that cannot be formulated as a simple suffix rule. ++ for lang in $ALL_LINGUAS; do ++ frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'` ++ cat >> "$ac_file.tmp" <> "$ac_file.tmp" <, 1996. ++ ++AC_PREREQ([2.53]) ++ ++# Search path for a program which passes the given test. ++ ++dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, ++dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) ++AC_DEFUN([AM_PATH_PROG_WITH_TEST], ++[ ++# Prepare PATH_SEPARATOR. ++# The user is always right. ++if test "${PATH_SEPARATOR+set}" != set; then ++ # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which ++ # contains only /bin. Note that ksh looks also at the FPATH variable, ++ # so we have to set that as well for the test. ++ PATH_SEPARATOR=: ++ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ ++ && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ ++ || PATH_SEPARATOR=';' ++ } ++fi ++ ++# Find out how to test for executable files. Don't use a zero-byte file, ++# as systems may use methods other than mode bits to determine executability. ++cat >conf$$.file <<_ASEOF ++#! /bin/sh ++exit 0 ++_ASEOF ++chmod +x conf$$.file ++if test -x conf$$.file >/dev/null 2>&1; then ++ ac_executable_p="test -x" ++else ++ ac_executable_p="test -f" ++fi ++rm -f conf$$.file ++ ++# Extract the first word of "$2", so it can be a program name with args. ++set dummy $2; ac_word=[$]2 ++AC_MSG_CHECKING([for $ac_word]) ++AC_CACHE_VAL([ac_cv_path_$1], ++[case "[$]$1" in ++ [[\\/]]* | ?:[[\\/]]*) ++ ac_cv_path_$1="[$]$1" # Let the user override the test with a path. ++ ;; ++ *) ++ ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR ++ for ac_dir in m4_if([$5], , $PATH, [$5]); do ++ IFS="$ac_save_IFS" ++ test -z "$ac_dir" && ac_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then ++ echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD ++ if [$3]; then ++ ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext" ++ break 2 ++ fi ++ fi ++ done ++ done ++ IFS="$ac_save_IFS" ++dnl If no 4th arg is given, leave the cache variable unset, ++dnl so AC_PATH_PROGS will keep looking. ++m4_if([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" ++])dnl ++ ;; ++esac])dnl ++$1="$ac_cv_path_$1" ++if test m4_if([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then ++ AC_MSG_RESULT([$][$1]) ++else ++ AC_MSG_RESULT([no]) ++fi ++AC_SUBST([$1])dnl ++]) ++ ++# Copyright (C) 2002-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -32,10 +10016,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.]) + # generated from the m4 files accompanying Automake X.Y. + # (This private macro should not be called outside this file.) + AC_DEFUN([AM_AUTOMAKE_VERSION], +-[am__api_version='1.15' ++[am__api_version='1.16' + dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to + dnl require some minimum version. Point them to the right macro. +-m4_if([$1], [1.15.1], [], ++m4_if([$1], [1.16.5], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl + ]) + +@@ -51,14 +10035,14 @@ m4_define([_AM_AUTOCONF_VERSION], []) + # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. + # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. + AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +-[AM_AUTOMAKE_VERSION([1.15.1])dnl ++[AM_AUTOMAKE_VERSION([1.16.5])dnl + m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl + _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + + # AM_AUX_DIR_EXPAND -*- Autoconf -*- + +-# Copyright (C) 2001-2017 Free Software Foundation, Inc. ++# Copyright (C) 2001-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -110,7 +10094,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` + + # AM_CONDITIONAL -*- Autoconf -*- + +-# Copyright (C) 1997-2017 Free Software Foundation, Inc. ++# Copyright (C) 1997-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -141,7 +10125,7 @@ AC_CONFIG_COMMANDS_PRE( + Usually this means the macro was only invoked conditionally.]]) + fi])]) + +-# Copyright (C) 1999-2017 Free Software Foundation, Inc. ++# Copyright (C) 1999-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -332,13 +10316,12 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl + + # Generate code to set up dependency tracking. -*- Autoconf -*- + +-# Copyright (C) 1999-2017 Free Software Foundation, Inc. ++# Copyright (C) 1999-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, + # with or without modifications, as long as this notice is preserved. + +- + # _AM_OUTPUT_DEPENDENCY_COMMANDS + # ------------------------------ + AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +@@ -346,49 +10329,43 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. +- case $CONFIG_FILES in +- *\'*) eval set x "$CONFIG_FILES" ;; +- *) set x $CONFIG_FILES ;; +- esac ++ # TODO: see whether this extra hack can be removed once we start ++ # requiring Autoconf 2.70 or later. ++ AS_CASE([$CONFIG_FILES], ++ [*\'*], [eval set x "$CONFIG_FILES"], ++ [*], [set x $CONFIG_FILES]) + shift +- for mf ++ # Used to flag and report bootstrapping failures. ++ am_rc=0 ++ for am_mf + do + # Strip MF so we end up with the name of the file. +- mf=`echo "$mf" | sed -e 's/:.*$//'` +- # Check whether this is an Automake generated Makefile or not. +- # We used to match only the files named 'Makefile.in', but +- # some people rename them; so instead we look at the file content. +- # Grep'ing the first line is not enough: some people post-process +- # each Makefile.in and add a new line on top of each file to say so. +- # Grep'ing the whole file is not good either: AIX grep has a line ++ am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` ++ # Check whether this is an Automake generated Makefile which includes ++ # dependency-tracking related rules and includes. ++ # Grep'ing the whole file directly is not great: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. +- if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then +- dirpart=`AS_DIRNAME("$mf")` +- else +- continue +- fi +- # Extract the definition of DEPDIR, am__include, and am__quote +- # from the Makefile without running 'make'. +- DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` +- test -z "$DEPDIR" && continue +- am__include=`sed -n 's/^am__include = //p' < "$mf"` +- test -z "$am__include" && continue +- am__quote=`sed -n 's/^am__quote = //p' < "$mf"` +- # Find all dependency output files, they are included files with +- # $(DEPDIR) in their names. We invoke sed twice because it is the +- # simplest approach to changing $(DEPDIR) to its actual value in the +- # expansion. +- for file in `sed -n " +- s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ +- sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do +- # Make sure the directory exists. +- test -f "$dirpart/$file" && continue +- fdir=`AS_DIRNAME(["$file"])` +- AS_MKDIR_P([$dirpart/$fdir]) +- # echo "creating $dirpart/$file" +- echo '# dummy' > "$dirpart/$file" +- done ++ sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ ++ || continue ++ am_dirpart=`AS_DIRNAME(["$am_mf"])` ++ am_filepart=`AS_BASENAME(["$am_mf"])` ++ AM_RUN_LOG([cd "$am_dirpart" \ ++ && sed -e '/# am--include-marker/d' "$am_filepart" \ ++ | $MAKE -f - am--depfiles]) || am_rc=$? + done ++ if test $am_rc -ne 0; then ++ AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments ++ for automatic dependency tracking. If GNU make was not used, consider ++ re-running the configure script with MAKE="gmake" (or whatever is ++ necessary). You can also try re-running configure with the ++ '--disable-dependency-tracking' option to at least be able to build ++ the package (albeit without support for automatic dependency tracking).]) ++ fi ++ AS_UNSET([am_dirpart]) ++ AS_UNSET([am_filepart]) ++ AS_UNSET([am_mf]) ++ AS_UNSET([am_rc]) ++ rm -f conftest-deps.mk + } + ])# _AM_OUTPUT_DEPENDENCY_COMMANDS + +@@ -397,18 +10374,17 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], + # ----------------------------- + # This macro should only be invoked once -- use via AC_REQUIRE. + # +-# This code is only required when automatic dependency tracking +-# is enabled. FIXME. This creates each '.P' file that we will +-# need in order to bootstrap the dependency handling code. ++# This code is only required when automatic dependency tracking is enabled. ++# This creates each '.Po' and '.Plo' makefile fragment that we'll need in ++# order to bootstrap the dependency handling code. + AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], + [AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], +- [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +-]) ++ [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) + + # Do all the work for Automake. -*- Autoconf -*- + +-# Copyright (C) 1996-2017 Free Software Foundation, Inc. ++# Copyright (C) 1996-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -436,6 +10412,10 @@ m4_defn([AC_PROG_CC]) + # release and drop the old call support. + AC_DEFUN([AM_INIT_AUTOMAKE], + [AC_PREREQ([2.65])dnl ++m4_ifdef([_$0_ALREADY_INIT], ++ [m4_fatal([$0 expanded multiple times ++]m4_defn([_$0_ALREADY_INIT]))], ++ [m4_define([_$0_ALREADY_INIT], m4_expansion_stack)])dnl + dnl Autoconf wants to disallow AM_ names. We explicitly allow + dnl the ones we care about. + m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +@@ -472,7 +10452,7 @@ m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + [_AM_SET_OPTIONS([$1])dnl + dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. + m4_if( +- m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), ++ m4_ifset([AC_PACKAGE_NAME], [ok]):m4_ifset([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl +@@ -495,8 +10475,8 @@ AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl + AC_REQUIRE([AC_PROG_MKDIR_P])dnl + # For better backward compatibility. To be removed once Automake 1.9.x + # dies out for good. For more background, see: +-# +-# ++# ++# + AC_SUBST([mkdir_p], ['$(MKDIR_P)']) + # We need awk for the "check" target (and possibly the TAP driver). The + # system "awk" is bad on some platforms. +@@ -524,6 +10504,20 @@ AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl + ]) ++# Variables for tags utilities; see am/tags.am ++if test -z "$CTAGS"; then ++ CTAGS=ctags ++fi ++AC_SUBST([CTAGS]) ++if test -z "$ETAGS"; then ++ ETAGS=etags ++fi ++AC_SUBST([ETAGS]) ++if test -z "$CSCOPE"; then ++ CSCOPE=cscope ++fi ++AC_SUBST([CSCOPE]) ++ + AC_REQUIRE([AM_SILENT_RULES])dnl + dnl The testsuite driver may need to know about EXEEXT, so add the + dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +@@ -563,7 +10557,7 @@ END + Aborting the configuration process, to ensure you take notice of the issue. + + You can download and install GNU coreutils to get an 'rm' implementation +-that behaves properly: . ++that behaves properly: . + + If you want to complete the configuration process using your problematic + 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +@@ -605,7 +10599,7 @@ for _am_header in $config_headers :; do + done + echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +-# Copyright (C) 2001-2017 Free Software Foundation, Inc. ++# Copyright (C) 2001-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -626,7 +10620,26 @@ if test x"${install_sh+set}" != xset; then + fi + AC_SUBST([install_sh])]) + +-# Copyright (C) 1998-2017 Free Software Foundation, Inc. ++# Copyright (C) 2003-2021 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# Check whether the underlying file-system supports filenames ++# with a leading dot. For instance MS-DOS doesn't. ++AC_DEFUN([AM_SET_LEADING_DOT], ++[rm -rf .tst 2>/dev/null ++mkdir .tst 2>/dev/null ++if test -d .tst; then ++ am__leading_dot=. ++else ++ am__leading_dot=_ ++fi ++rmdir .tst 2>/dev/null ++AC_SUBST([am__leading_dot])]) ++ ++# Copyright (C) 1998-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -647,7 +10660,7 @@ fi]) + # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- + # From Jim Meyering + +-# Copyright (C) 1996-2017 Free Software Foundation, Inc. ++# Copyright (C) 1996-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -682,7 +10695,7 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + + # Check to see how 'make' treats includes. -*- Autoconf -*- + +-# Copyright (C) 2001-2017 Free Software Foundation, Inc. ++# Copyright (C) 2001-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -690,49 +10703,42 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + + # AM_MAKE_INCLUDE() + # ----------------- +-# Check to see how make treats includes. ++# Check whether make has an 'include' directive that can support all ++# the idioms we need for our automatic dependency tracking code. + AC_DEFUN([AM_MAKE_INCLUDE], +-[am_make=${MAKE-make} +-cat > confinc << 'END' ++[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) ++cat > confinc.mk << 'END' + am__doit: +- @echo this is the am__doit target ++ @echo this is the am__doit target >confinc.out + .PHONY: am__doit + END +-# If we don't find an include directive, just comment out the code. +-AC_MSG_CHECKING([for style of include used by $am_make]) + am__include="#" + am__quote= +-_am_result=none +-# First try GNU make style include. +-echo "include confinc" > confmf +-# Ignore all kinds of additional output from 'make'. +-case `$am_make -s -f confmf 2> /dev/null` in #( +-*the\ am__doit\ target*) +- am__include=include +- am__quote= +- _am_result=GNU +- ;; +-esac +-# Now try BSD make style include. +-if test "$am__include" = "#"; then +- echo '.include "confinc"' > confmf +- case `$am_make -s -f confmf 2> /dev/null` in #( +- *the\ am__doit\ target*) +- am__include=.include +- am__quote="\"" +- _am_result=BSD +- ;; +- esac +-fi +-AC_SUBST([am__include]) +-AC_SUBST([am__quote]) +-AC_MSG_RESULT([$_am_result]) +-rm -f confinc confmf +-]) ++# BSD make does it like this. ++echo '.include "confinc.mk" # ignored' > confmf.BSD ++# Other make implementations (GNU, Solaris 10, AIX) do it like this. ++echo 'include confinc.mk # ignored' > confmf.GNU ++_am_result=no ++for s in GNU BSD; do ++ AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) ++ AS_CASE([$?:`cat confinc.out 2>/dev/null`], ++ ['0:this is the am__doit target'], ++ [AS_CASE([$s], ++ [BSD], [am__include='.include' am__quote='"'], ++ [am__include='include' am__quote=''])]) ++ if test "$am__include" != "#"; then ++ _am_result="yes ($s style)" ++ break ++ fi ++done ++rm -f confinc.* confmf.* ++AC_MSG_RESULT([${_am_result}]) ++AC_SUBST([am__include])]) ++AC_SUBST([am__quote])]) + + # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +-# Copyright (C) 1997-2017 Free Software Foundation, Inc. ++# Copyright (C) 1997-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -753,12 +10759,7 @@ AC_DEFUN([AM_MISSING_HAS_RUN], + [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl + AC_REQUIRE_AUX_FILE([missing])dnl + if test x"${MISSING+set}" != xset; then +- case $am_aux_dir in +- *\ * | *\ *) +- MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; +- *) +- MISSING="\${SHELL} $am_aux_dir/missing" ;; +- esac ++ MISSING="\${SHELL} '$am_aux_dir/missing'" + fi + # Use eval to expand $SHELL + if eval "$MISSING --is-lightweight"; then +@@ -771,7 +10772,7 @@ fi + + # Helper functions for option handling. -*- Autoconf -*- + +-# Copyright (C) 2001-2017 Free Software Foundation, Inc. ++# Copyright (C) 2001-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -800,7 +10801,7 @@ AC_DEFUN([_AM_SET_OPTIONS], + AC_DEFUN([_AM_IF_OPTION], + [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +-# Copyright (C) 1999-2017 Free Software Foundation, Inc. ++# Copyright (C) 1999-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -847,7 +10848,7 @@ AC_LANG_POP([C])]) + # For backward compatibility. + AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +-# Copyright (C) 2001-2017 Free Software Foundation, Inc. ++# Copyright (C) 2001-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -866,7 +10867,7 @@ AC_DEFUN([AM_RUN_LOG], + + # Check to make sure that the build environment is sane. -*- Autoconf -*- + +-# Copyright (C) 1996-2017 Free Software Foundation, Inc. ++# Copyright (C) 1996-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -947,7 +10948,7 @@ AC_CONFIG_COMMANDS_PRE( + rm -f conftest.file + ]) + +-# Copyright (C) 2009-2017 Free Software Foundation, Inc. ++# Copyright (C) 2009-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -1007,7 +11008,7 @@ AC_SUBST([AM_BACKSLASH])dnl + _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl + ]) + +-# Copyright (C) 2001-2017 Free Software Foundation, Inc. ++# Copyright (C) 2001-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -1035,7 +11036,7 @@ fi + INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +-# Copyright (C) 2006-2017 Free Software Foundation, Inc. ++# Copyright (C) 2006-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -1054,7 +11055,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + + # Check how to create a tarball. -*- Autoconf -*- + +-# Copyright (C) 2004-2017 Free Software Foundation, Inc. ++# Copyright (C) 2004-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -1185,27 +11186,3 @@ AC_SUBST([am__tar]) + AC_SUBST([am__untar]) + ]) # _AM_PROG_TAR + +-m4_include([../bfd/acinclude.m4]) +-m4_include([../bfd/warning.m4]) +-m4_include([../config/acx.m4]) +-m4_include([../config/bfd64.m4]) +-m4_include([../config/depstand.m4]) +-m4_include([../config/enable.m4]) +-m4_include([../config/gettext-sister.m4]) +-m4_include([../config/jobserver.m4]) +-m4_include([../config/largefile.m4]) +-m4_include([../config/lcmessage.m4]) +-m4_include([../config/lead-dot.m4]) +-m4_include([../config/nls.m4]) +-m4_include([../config/override.m4]) +-m4_include([../config/pkg.m4]) +-m4_include([../config/plugins.m4]) +-m4_include([../config/po.m4]) +-m4_include([../config/progtest.m4]) +-m4_include([../config/zlib.m4]) +-m4_include([../config/zstd.m4]) +-m4_include([../libtool.m4]) +-m4_include([../ltoptions.m4]) +-m4_include([../ltsugar.m4]) +-m4_include([../ltversion.m4]) +-m4_include([../lt~obsolete.m4]) +diff --git a/ld/configure.tgt b/ld/configure.tgt +index de04a44b..baceb2cc 100644 +--- a/ld/configure.tgt ++++ b/ld/configure.tgt +@@ -81,6 +81,15 @@ fi + # Please try to keep this table more or less in alphabetic order - it + # makes it much easier to lookup a specific archictecture. + case "${targ}" in ++i[3-7]86-*-sb*) ++ targ_emul=elf_i386_sb ++ targ_extra_emuls=elf_i386 ++# targ64_extra_emuls="elf_x86_64_sb_x86_64" ++ ;; ++#x86_64-*-sb*) ++# targ_emul=elf_x86_64_sb ++# targ_extra_emuls="elf_i386_sb elf_x86_64 elf_i386" ++# ;; + aarch64_be-*-elf) targ_emul=aarch64elfb + targ_extra_emuls="aarch64elf aarch64elf32 aarch64elf32b armelfb armelf" + ;; +diff --git a/ld/emulparams/elf_i386_sb.sh b/ld/emulparams/elf_i386_sb.sh +new file mode 100644 +index 00000000..06482257 +--- /dev/null ++++ b/ld/emulparams/elf_i386_sb.sh +@@ -0,0 +1,2 @@ ++source_sh ${srcdir}/emulparams/elf_i386.sh ++TEXT_START_ADDR=0x08000000 +diff --git a/ld/emulparams/elf_x86_64_sb.sh b/ld/emulparams/elf_x86_64_sb.sh +new file mode 100644 +index 00000000..59e7df71 +--- /dev/null ++++ b/ld/emulparams/elf_x86_64_sb.sh +@@ -0,0 +1 @@ ++source_sh ${srcdir}/emulparams/elf_x86_64.sh +diff --git a/ld/emulparams/elf_x86_64_sb_x86_64.sh b/ld/emulparams/elf_x86_64_sb_x86_64.sh +new file mode 100644 +index 00000000..59e7df71 +--- /dev/null ++++ b/ld/emulparams/elf_x86_64_sb_x86_64.sh +@@ -0,0 +1 @@ ++source_sh ${srcdir}/emulparams/elf_x86_64.sh diff --git a/toolchain/build-binutils.sh b/toolchain/build-binutils.sh new file mode 100755 index 0000000..12bcde9 --- /dev/null +++ b/toolchain/build-binutils.sh @@ -0,0 +1,13 @@ +#!/bin/sh +./download-binutils.sh +tar -xf binutils*.tar.xz +cd ./binutils-*/ +patch -f -p1 -i ../binutils-2.40.diff +cd .. +mkdir bin +#PREFIX="/home/anton/prj/osdev/sysroot" +PREFIX="$(pwd)/bin" +mkdir build-binutils +cd build-binutils +../binutils*/configure --target=i686-sb --prefix="$PREFIX" --with-sysroot="/home/anton/prj/osdev/sysroot" --disable-werror +make -j8 && make install diff --git a/toolchain/build-gcc.sh b/toolchain/build-gcc.sh new file mode 100755 index 0000000..c9af8a1 --- /dev/null +++ b/toolchain/build-gcc.sh @@ -0,0 +1,13 @@ +#!/bin/sh +./download-gcc.sh +tar -xf gcc-*.tar.xz +cd ./gcc-*/ +patch -f -p1 -i ../gcc-13.1.0.diff +cd .. +mkdir bin +PREFIX=$(pwd)"/bin" +#PREFIX="/home/anton/prj/osdev/sysroot" +mkdir build-gcc +cd build-gcc +../gcc-*/configure --target=i686-sb --prefix="$PREFIX" --with-gmp --with-mpfr --with-sysroot="/home/anton/prj/osdev/sysroot" --enable-languages=c,c++ +make -j6 all-gcc all-target-libgcc && make install-gcc install-target-libgcc diff --git a/toolchain/download-binutils.sh b/toolchain/download-binutils.sh new file mode 100755 index 0000000..4a72cf9 --- /dev/null +++ b/toolchain/download-binutils.sh @@ -0,0 +1,2 @@ +#!/bin/sh +BIN="binutils-2.40.tar.xz" URL="https://ftp.gnu.org/gnu/binutils" ./download.sh diff --git a/toolchain/download-gcc.sh b/toolchain/download-gcc.sh new file mode 100755 index 0000000..a7e2c94 --- /dev/null +++ b/toolchain/download-gcc.sh @@ -0,0 +1,2 @@ +#!/bin/sh +BIN="gcc-13.1.0.tar.xz" URL="https://ftp.gnu.org/gnu/gcc/gcc-13.1.0" ./download.sh diff --git a/toolchain/download.sh b/toolchain/download.sh new file mode 100755 index 0000000..770e812 --- /dev/null +++ b/toolchain/download.sh @@ -0,0 +1,9 @@ +#!/bin/sh +[ -f "$BIN.sig" ] && gpg --verify $BIN.sig $BIN && exit 0 +[ -f "$BIN.sig" ] || wget "$URL/$BIN.sig" +[ -f "$BIN" ] && gpg --verify $BIN.sig $BIN && exit 0 +wget "$URL/$BIN" +gpg --verify $BIN.sig $BIN && exit 0 +rm $BIN +echo "Signature failed" +exit 1 diff --git a/toolchain/gcc-13.1.0.diff b/toolchain/gcc-13.1.0.diff new file mode 100644 index 0000000..eb15a77 --- /dev/null +++ b/toolchain/gcc-13.1.0.diff @@ -0,0 +1,142 @@ +diff --git a/config.sub b/config.sub +index 38f3d037a..44169ef44 100755 +--- a/config.sub ++++ b/config.sub +@@ -1749,7 +1749,7 @@ case $os in + | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ + | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \ +- | fiwix* ) ++ | fiwix* | sb*) + ;; + # This one is extra strict with allowed versions + sco3.2v2 | sco3.2v[4-9]* | sco5v6*) +diff --git a/fixincludes/mkfixinc.sh b/fixincludes/mkfixinc.sh +index df90720b7..fdd219967 100755 +--- a/fixincludes/mkfixinc.sh ++++ b/fixincludes/mkfixinc.sh +@@ -11,6 +11,8 @@ target=fixinc.sh + + # Check for special fix rules for particular targets + case $machine in ++ *-sb* | \ ++ *-*-sb* | \ + i?86-*-cygwin* | \ + i?86-*-mingw32* | \ + x86_64-*-mingw32* | \ +diff --git a/gcc/config.gcc b/gcc/config.gcc +index 6fd159448..c4c05ce9e 100644 +--- a/gcc/config.gcc ++++ b/gcc/config.gcc +@@ -690,6 +690,12 @@ x86_cpus="generic intel" + + # Common parts for widely ported systems. + case ${target} in ++*-*-sb*) ++ gas=yes ++ gnu_ld=yes ++ default_use_cxa_atexit=yes ++ use_gcc_stdint=provide ++ ;; + *-*-darwin*) + tmake_file="t-darwin " + tm_file="${tm_file} darwin.h" +@@ -1126,6 +1132,9 @@ case ${target} in + esac + + case ${target} in ++#i[34567]86-*-sb*) # UNSURE ++# tm_file="${tm_file} i386/unix.h i386/att.h elfos.h glibc-stdint.h i386/i386elf.h sb.h" ++# ;; + aarch64*-*-elf | aarch64*-*-fuchsia* | aarch64*-*-rtems*) + tm_file="${tm_file} elfos.h newlib-stdint.h" + tm_file="${tm_file} aarch64/aarch64-elf.h aarch64/aarch64-errata.h aarch64/aarch64-elf-raw.h" +@@ -2327,6 +2336,10 @@ m68k-*-elf* | fido-*-elf*) + ;; + esac + ;; ++#AAAAAAAAAAAAAAAAAAA ++i[34567]86-*-sb*) # UNSURE ++ tm_file="${tm_file} i386/unix.h i386/att.h elfos.h glibc-stdint.h i386/i386elf.h sb.h" ++ ;; + m68k*-*-netbsdelf*) + default_m68k_cpu=68020 + default_cf_cpu=5475 +diff --git a/gcc/config/sb.h b/gcc/config/sb.h +new file mode 100644 +index 000000000..b721cb53f +--- /dev/null ++++ b/gcc/config/sb.h +@@ -0,0 +1,28 @@ ++/* Useful if you wish to make target-specific GCC changes. */ ++#undef TARGET_SB ++#define TARGET_SB 1 ++ ++/* Default arguments you want when running your ++ i686-myos-gcc/x86_64-myos-gcc toolchain */ ++#undef LIB_SPEC ++#define LIB_SPEC "-lc" /* link against C standard library */ ++ ++/* Files that are linked before user code. ++ The %s tells GCC to look for these files in the library directory. */ ++#undef STARTFILE_SPEC ++#define STARTFILE_SPEC "crt0.o%s crti.o%s crtbegin.o%s" ++ ++/* Files that are linked after user code. */ ++#undef ENDFILE_SPEC ++#define ENDFILE_SPEC "crtend.o%s crtn.o%s" ++ ++/* Additional predefined macros. */ ++#undef TARGET_OS_CPP_BUILTINS ++#define TARGET_OS_CPP_BUILTINS() \ ++ do { \ ++ builtin_define("__sb__"); \ ++ builtin_define("__unix__"); \ ++ builtin_assert("system=sb"); \ ++ builtin_assert("system=unix"); \ ++ builtin_assert("system=posix"); \ ++ } while (0); +diff --git a/libgcc/config.host b/libgcc/config.host +index b9975de90..da9323956 100644 +--- a/libgcc/config.host ++++ b/libgcc/config.host +@@ -220,6 +220,10 @@ esac + + # Common parts for widely ported systems. + case ${host} in ++#i[34567]86-*-sb*) ++# extra_parts="$extra_parts crti.o crtbegin.o crtend.o crtn.o" ++# tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic" ++# ;; + *-*-darwin*) + asm_hidden_op=.private_extern + tmake_file="$tmake_file t-darwin ${cpu_type}/t-darwin t-libgcc-pic" +@@ -1503,6 +1507,10 @@ am33_2.0-*-linux*) + m32c-*-elf*) + tmake_file="$tmake_file m32c/t-m32c" + ;; ++i[34567]86-*-sb*) ++ extra_parts="$extra_parts crti.o crtbegin.o crtend.o crtn.o" ++ tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic" ++ ;; + nvptx-*) + tmake_file="$tmake_file nvptx/t-nvptx" + extra_parts="crt0.o" +diff --git a/libstdc++-v3/crossconfig.m4 b/libstdc++-v3/crossconfig.m4 +index b3269cb88..8c0bc1e6f 100644 +--- a/libstdc++-v3/crossconfig.m4 ++++ b/libstdc++-v3/crossconfig.m4 +@@ -8,7 +8,12 @@ case "${host}" in + arm*-*-symbianelf*) + # This is a freestanding configuration; there is nothing to do here. + ;; +- ++ *-sb*) ++ GLIBCXX_CHECK_COMPILER_FEATURES ++ GLIBCXX_CHECK_LINKER_FEATURES ++ GLIBCXX_CHECK_MATH_SUPPORT ++ GLIBCXX_CHECK_STDLIB_SUPPORT ++ ;; + avr*-*-*) + AC_DEFINE(HAVE_ACOSF) + AC_DEFINE(HAVE_ASINF) diff --git a/toolchain/get-keys.sh b/toolchain/get-keys.sh new file mode 100755 index 0000000..0210b8f --- /dev/null +++ b/toolchain/get-keys.sh @@ -0,0 +1,3 @@ +#!/bin/sh +gpg --recv-key 3A24BC1E8FB409FA9F14371813FCEF89DD9E3C4F +gpg --recv-key D3A93CAD751C2AF4F8C7AD516C35B99309B5FA62 diff --git a/userland/ante/Makefile b/userland/ante/Makefile new file mode 100644 index 0000000..412b302 --- /dev/null +++ b/userland/ante/Makefile @@ -0,0 +1,15 @@ +CC="/home/anton/prj/osdev/sysroot/bin/i686-sb-gcc" +CFLAGS = -ggdb -O2 -Wall -Wextra -pedantic -static +LIB=-L../libgui -lgui -lgcc +INC=-I../libgui/ +BINS=ante +all: $(BINS) + +ante.o: ante.c + $(CC) $(CFLAGS) $(INC) $(LIB) -o $@ -c $< + +ante: ante.o + $(CC) $(CFLAGS) -o $@ $^ $(LIB) + +clean: + rm $(BINS) *.o diff --git a/userland/ante/ante.c b/userland/ante/ante.c new file mode 100644 index 0000000..753e7f2 --- /dev/null +++ b/userland/ante/ante.c @@ -0,0 +1,296 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BACKGROUND_COLOR 0x000000 + +int file_fd; +char *file_buffer; +uint64_t file_buffer_size; +uint64_t file_size = 0; +uint64_t file_real_position = 0; +GUI_Window *global_w; + +typedef enum { + NORMAL, + INSERT, + COMMAND, +} editor_mode_t; + +editor_mode_t current_mode = NORMAL; +uint32_t cursor_pos_x = 0; +uint64_t cursor_pos_y = 0; +void draw_file(void); +void write_file(void); + +int clamp(int *x, int *y) { + int clamped = 0; + if (*x < 0) { + *x = 0; + clamped = 1; + } + if (*y < 0) { + *y = 0; + clamped = 1; + } + if (*x + 8 > global_w->sx) { + *x = (global_w->sx - 8) / 8; + clamped = 1; + } + if (*y + 8 > global_w->sy) { + *y = (global_w->sy - 8) / 8; + clamped = 1; + } + return clamped; +} + +void insert_char(int pos, char c) { + if (0 == file_size) { + file_size++; + file_buffer[0] = c; + return; + } + + // Shift the buffer at 'pos' to the right by one. + memmove(file_buffer + pos + 1, file_buffer + pos, file_size - pos); + + file_buffer[pos] = c; + file_size++; +} + +void delete_char(int pos, int *deleted_newline) { + if (0 == pos) { + return; + } + // Delete the characther at 'pos'. This makes sense if 'pos' is + // at the end of the file and as a result the shift operation done + // later in the function is not overwritting the characther. + if ('\n' == file_buffer[pos - 1]) + *deleted_newline = 1; + file_buffer[pos - 1] = 0; + + // Shift the buffer at 'pos' to the left by one + memmove(file_buffer + pos - 1, file_buffer + pos, file_size - pos); + file_size--; +} + +uint64_t cursor_to_real(int x, int y, int *is_valid) { + *is_valid = 0; + if (clamp(&x, &y)) + return file_real_position; + if (0 == file_size) { + if (0 == x && 0 == y) { + *is_valid = 1; + return 0; + } + return 0; + } + uint64_t p = 0; + int cx = 0; + int cy = 0; + for (; p < file_size; p++) { + if (cx == x && cy == y) { + *is_valid = 1; + break; + } + if ('\n' == file_buffer[p]) { + cx = 0; + cy++; + continue; + } + cx++; + } + if (*is_valid) + return p; + else + return file_real_position; +} + +void key_event(char c) { + int x = 0; + int y = 0; + if (COMMAND == current_mode) { + if ('w' == c) { + printf("wrote to file\n"); + write_file(); + current_mode = NORMAL; + return; + } + if ('q' == c) { + close(file_fd); + close(global_w->ws_socket); + current_mode = NORMAL; + exit(0); + return; + } + return; + } else if (NORMAL == current_mode) { + switch (c) { + case 'j': + y++; + break; + case 'k': + y--; + break; + case 'l': + x++; + break; + case 'h': + x--; + break; + case 'c': + printf("entering command mode\n"); + current_mode = COMMAND; + return; + break; + case 'i': + current_mode = INSERT; + return; + break; + default: + return; + } + } else { + if ('\x1B' == c) { + current_mode = NORMAL; + return; + } + if ('\b' == c) { + int deleted_newline = 0; + delete_char(file_real_position, &deleted_newline); + if (deleted_newline) { + y--; + } else { + x--; + } + GUI_ClearScreen(global_w, BACKGROUND_COLOR); + } else { + insert_char(file_real_position, c); + printf("inserting char: %c\n", c); + if ('\n' == c) { + cursor_pos_x = 0; + y++; + } else { + x++; + } + GUI_ClearScreen(global_w, BACKGROUND_COLOR); + } + } + + int is_valid_position = 0; + file_real_position = + cursor_to_real(cursor_pos_x + x, cursor_pos_y + y, &is_valid_position); + if (!is_valid_position) { + return; + } + GUI_OverwriteFont(global_w, cursor_pos_x * 8, cursor_pos_y * 8, + BACKGROUND_COLOR); + draw_file(); + cursor_pos_x += x; + cursor_pos_y += y; + GUI_OverwriteFont(global_w, cursor_pos_x * 8, cursor_pos_y * 8, 0xFFFFFF); + + GUI_UpdateWindow(global_w); +} + +void draw_file(void) { + assert(file_buffer); + uint32_t screen_pos_x = 0; + uint64_t screen_pos_y = 0; + for (uint64_t i = 0; i < file_size; i++) { + char c = file_buffer[i]; + if ('\n' == c) { + screen_pos_x = 0; + screen_pos_y += 8; + continue; + } + GUI_DrawFont(global_w, screen_pos_x, screen_pos_y, c); + screen_pos_x += 8; + } +} + +void write_file(void) { + assert(file_buffer); + pwrite(file_fd, file_buffer, file_size, 0); +} + +int open_file(const char *file) { + file_fd = open(file, O_RDWR, O_CREAT); + printf("file_fd: %d\n", file_fd); + if (0 > file_fd) { + perror("open"); + return 0; + } + + file_buffer_size = 0x1000; + file_buffer = malloc(file_buffer_size); + uint64_t index = 0; + assert(file_buffer); + for (;;) { + char buffer[4096]; + int rc = read(file_fd, buffer, 4096); + if (-1 == rc) { + perror("read"); + assert(0); + } + + if (0 == rc) + break; + + file_size += rc; + if (file_size > file_buffer_size) { + file_buffer_size = file_size; + file_buffer = realloc(file_buffer, file_buffer_size); + assert(file_buffer); + } + + for (int i = 0; i < rc; i++, index++) { + file_buffer[index] = buffer[i]; + } + } + return 1; +} + +void run() { + struct pollfd fds[1]; + fds[0].fd = global_w->ws_socket; + fds[0].events = POLLIN; + fds[0].revents = 0; + for (;; fds[0].revents = 0) { + poll(fds, 1, 0); + if (fds[0].revents & POLLIN) { + WS_EVENT e; + int rc; + if (0 >= (rc = read(global_w->ws_socket, &e, sizeof(e)))) + continue; + if (0 == e.c) + continue; + key_event(e.c); + } + } +} + +int main(int argc, char **argv) { + if (argc < 2) { + printf("File has to be specified.\n"); + return 1; + } + global_w = GUI_CreateWindow(10, 10, 150 * 4, 150 * 4); + assert(global_w); + GUI_ClearScreen(global_w, BACKGROUND_COLOR); + GUI_UpdateWindow(global_w); + + assert(open_file(argv[1])); + draw_file(); + run(); + return 0; +} diff --git a/userland/cat/Makefile b/userland/cat/Makefile new file mode 100644 index 0000000..b45fae9 --- /dev/null +++ b/userland/cat/Makefile @@ -0,0 +1,10 @@ +CC="/home/anton/opt/cross/bin/i686-elf-gcc" +CFLAGS = -ggdb -ffreestanding -O0 -Wall -Wextra -pedantic -mgeneral-regs-only -Wimplicit-fallthrough +BINS=cat +all: $(BINS) + +cat.o: cat.c + $(CC) $(CFLAGS) -L../libc/ -lc -c cat.c -I../libc/ + +cat: cat.o + $(CC) -shared -o cat -ffreestanding -nostdlib $(CFLAGS) cat.o -L../libc/ -lc -lgcc #-L../libc/c.a diff --git a/userland/cat/cat b/userland/cat/cat new file mode 100755 index 0000000..2ba0c4d Binary files /dev/null and b/userland/cat/cat differ diff --git a/userland/cat/cat.c b/userland/cat/cat.c new file mode 100644 index 0000000..b143581 --- /dev/null +++ b/userland/cat/cat.c @@ -0,0 +1,24 @@ +#include +#include +#include + +int main(int argc, char **argv) { + DIR *d = opendir("/"); + struct dirent *de = readdir(d); + printf("x : %x\n", de->d_name[0]); + for (;;) + ; + /* + int fd = 0; + if (argc < 2) + goto read_stdin; + for (int i = 1; i < argc; i++) { + if ((fd = open(argv[i], O_RDONLY, 0)) == -1) { + return 1; + } + read_stdin: + for (char c[4096], int rc; (rc = read(fd, c, 4096) > 0);) + write(1, c, rc); + }*/ + return 0; +} diff --git a/userland/init/Makefile b/userland/init/Makefile new file mode 100644 index 0000000..932fcd3 --- /dev/null +++ b/userland/init/Makefile @@ -0,0 +1,10 @@ +CC="/home/anton/opt/cross/bin/i686-elf-gcc" +CFLAGS = -ggdb -ffreestanding -O0 -Wall -Wextra -pedantic -mgeneral-regs-only -Wimplicit-fallthrough +BINS=init +all: $(BINS) + +init.o: init.c + $(CC) $(CFLAGS) -I../libc/ -L../libc/ -lc -c init.c + +init: init.o + $(CC) -shared -o init -ffreestanding -nostdlib $(CFLAGS) init.o -L../libc/ -lc -lgcc #-L../libc/c.a diff --git a/userland/init/crt0_old.c b/userland/init/crt0_old.c new file mode 100644 index 0000000..7d1e977 --- /dev/null +++ b/userland/init/crt0_old.c @@ -0,0 +1,12 @@ +#include +int main(int argc, char **argv); +//int main(); + +void _start(int a, int b, int argc, char** argv) +{ + (void)a; + kprintf("argc : %x\n", &argc); + kprintf("argv : %x\n", &argv); + for(;;); +// main(argc, t); +} diff --git a/userland/init/init b/userland/init/init new file mode 100755 index 0000000..3ae9020 Binary files /dev/null and b/userland/init/init differ diff --git a/userland/init/init.c b/userland/init/init.c new file mode 100644 index 0000000..78c4420 --- /dev/null +++ b/userland/init/init.c @@ -0,0 +1,15 @@ +#include +#include +#include +#include +#include + +int main(void) { + if (fork()) + for (;;) + wait(NULL); + + char *a[] = {NULL}; + execv("/term", a); + return 1; +} diff --git a/userland/json/Makefile b/userland/json/Makefile new file mode 100644 index 0000000..9fcb567 --- /dev/null +++ b/userland/json/Makefile @@ -0,0 +1,18 @@ +#CC="/home/anton/opt/cross/bin/i686-elf-gcc" +#AR="/home/anton/opt/cross/bin/i686-elf-ar" +CC="/home/anton/prj/osdev/sysroot/bin/i686-sb-gcc" +AR="/home/anton/prj/osdev/sysroot/bin/i686-sb-ar" +CFLAGS = -O0 -Wall -Wextra -pedantic -Wimplicit-fallthrough -static -Wno-undef +BINS=libjson.a +all: $(BINS) +LIBS=-L./hashmap -lhashmap +OBJ=json.o + +json.o: json.c + $(CC) $(CFLAGS) $(LIBS) -c json.c + +libjson.a: $(OBJ) + $(AR) rcs libjson.a $^ + +clean: + rm libjson.a json.o diff --git a/userland/json/hashmap b/userland/json/hashmap new file mode 160000 index 0000000..07dfe3b --- /dev/null +++ b/userland/json/hashmap @@ -0,0 +1 @@ +Subproject commit 07dfe3b606e0d82b2e181b27344b5e4ce8849f31 diff --git a/userland/json/json.c b/userland/json/json.c new file mode 100644 index 0000000..6449193 --- /dev/null +++ b/userland/json/json.c @@ -0,0 +1,360 @@ +// +// Copyright (C) 2022 by Anton Kling +// +// SPDX-License-Identifier: BSD-2-Clause +// +#include "hashmap/hashmap.h" +#include +#include +#include +#include +#include +#include + +typedef enum JSON_TYPE { + NONE, + STRING, + NUMBER, + OBJECT, + ARRAY, // FIXME + BOOL, + JSON_NULL, +} JSON_TYPE; + +typedef struct JSON_ENTRY { + char *name; + JSON_TYPE type; + void *value; +} JSON_ENTRY; + +typedef struct JSON_OBJECT { + size_t size; + JSON_ENTRY *entries; + HashMap *hash_indexes; +} JSON_OBJECT; + +typedef struct JSON_CTX { + JSON_ENTRY global_object; +} JSON_CTX; + +void JSON_Init(JSON_CTX *ctx) { + ctx->global_object.name = NULL; + ctx->global_object.type = OBJECT; + ctx->global_object.value = malloc(sizeof(JSON_OBJECT)); + JSON_OBJECT *obj = ctx->global_object.value; + obj->size = 0; + obj->entries = NULL; +} + +const char *skip_whitespace(const char *str) { + for (; *str; str++) + switch (*str) { + case ' ': + case '\t': + case '\n': + case '\r': + break; + default: + goto _exit; + } +_exit: + return str; +} + +char to_lower(char c) { + if (c <= 'Z') + return c | 32; + return c; +} + +int low_strequ(const char *s1, const char *s2, size_t l) { + for (; 0 < l; l--, s2++, s1++) { + if (to_lower(*s2) != to_lower(*s1)) + return 0; + } + return 1; +} + +const char *find_name(const char *json, char *name_buffer, size_t buffer_len, + size_t *name_length, int *rc) { + *rc = 0; + json = skip_whitespace(json); + if ('"' != *json) + return json; + + // This *can* be the name + json++; + const char *tmp = json; + for (; *tmp && '"' != *tmp; tmp++) + ; + if (!(*tmp && ':' == *(tmp + 1))) { + // Invalid name + // FIXME: Do something better than this. + assert(0); + } + // The name was found. + *rc = 1; + size_t str_len; + if (tmp == json) + str_len = 0; + else + str_len = (tmp - json - 1); + if (str_len + 1 > buffer_len) { + // JSON string is too long for the buffer + // FIXME: Do something better than this. + assert(0); + } + memcpy(name_buffer, json, str_len + 1); + name_buffer[str_len + 1] = '\0'; + *name_length = str_len; + return tmp + 2; +} + +const char *find_entry(const char *json, char *name_buffer, size_t buffer_len, + size_t *name_length, JSON_TYPE *entry_type, int *rc) { + *rc = 0; + json = skip_whitespace(json); + json = find_name(json, name_buffer, 4096, name_length, rc); + json = skip_whitespace(json); + switch (*json) { + case '{': + *entry_type = OBJECT; + break; + case '"': + *entry_type = STRING; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + *entry_type = NUMBER; + break; + case '[': + *entry_type = ARRAY; + break; + case 'T': + case 'F': + case 't': + case 'f': + *entry_type = BOOL; + break; + case 'N': + case 'n': + *entry_type = JSON_NULL; + break; + case '}': + *rc = 2; + break; + default: + *entry_type = NONE; + break; + } + return json; +} + +const char *extract_int(const char *json, uint32_t **value, int *rc) { + *value = malloc(sizeof(uint32_t)); + *rc = 0; + json = skip_whitespace(json); + // FIXME: Do some checking to determine that this is a int. + **value = 0; + for (; *json && ',' != *json && '}' != *json;) { + **value *= 10; + **value += (uint32_t)(*json - '0'); + json++; + json = skip_whitespace(json); + } + if ('\0' != *json) + *rc = 1; + return json; +} + +const char *extract_string(const char *json, char **value, int *rc) { + *value = malloc(4096); + *rc = 0; + int escape = 0; + json++; + char *tmp = *value; + for (; *json; json++) { + if ('"' == *json && !escape) + break; + escape = 0; + + if ('\\' == *json && !escape) { + escape = 1; + continue; + } + *tmp = *json; + tmp++; + } + *tmp = '\0'; + if ('\0' != *json) + *rc = 1; + return json; +} + +const char *extract_bool(const char *json, uint8_t **value, int *rc) { + *value = malloc(sizeof(uint8_t)); + *rc = 0; + if (low_strequ(json, "true", 3)) { + **value = 1; + json += 4; + *rc = 1; + return json; + } else if (low_strequ(json, "false", 4)) { + **value = 0; + json += 5; + *rc = 1; + return json; + } + return json; +} + +const char *extract_null(const char *json, uint8_t **value, int *rc) { + *value = malloc(sizeof(uint8_t)); + *rc = 0; + + if (low_strequ(json, "null", 3)) { + **value = 0; + json += 4; + *rc = 1; + return json; + } + return json; +} + +void hashmap_free_value(char *key, void *value) { + (void)key; + free(value); +} + +JSON_ENTRY *JSON_at(JSON_ENTRY *entry, size_t i); + +void JSON_Parse(JSON_CTX *ctx, const char *json) { + int rc; + char name_buffer[4096]; + size_t name_length; + JSON_TYPE entry_type; + JSON_OBJECT *object_stack[64]; + memset(object_stack, 0, sizeof(JSON_OBJECT *[64])); + size_t parent_num = 0; + object_stack[parent_num] = ctx->global_object.value; + object_stack[parent_num]->size = 0; + + for (;; json++) { + json = find_entry(json, name_buffer, 4096, &name_length, &entry_type, &rc); + if ('\0' == *json) + return; + + if (2 == rc) { + if (0 == parent_num) + return; + parent_num--; + json++; + json = skip_whitespace(json); + if (',' == *json) + json++; + continue; + } + + if (NULL == object_stack[parent_num]->entries) { + object_stack[parent_num]->entries = malloc(sizeof(JSON_ENTRY[30])); + object_stack[parent_num]->size = 0; + object_stack[parent_num]->hash_indexes = hashmap_create(30); + } + + size_t entry_num = object_stack[parent_num]->size; + object_stack[parent_num]->size++; + + if (NULL == object_stack[parent_num]->entries) { + void *rc = object_stack[parent_num]->entries = + malloc(sizeof(JSON_ENTRY[30])); + object_stack[parent_num]->entries = rc; + object_stack[parent_num]->size = 0; + object_stack[parent_num]->hash_indexes = hashmap_create(30); + } + JSON_ENTRY *entry = &object_stack[parent_num]->entries[entry_num]; + if (1 == rc) { + name_length++; + entry->name = malloc(name_length + 2); + memcpy(entry->name, name_buffer, name_length); + entry->name[name_length] = '\0'; + size_t *b = malloc(sizeof(size_t)); + *b = entry_num; + hashmap_add_entry(object_stack[parent_num]->hash_indexes, entry->name, b, + hashmap_free_value, 1); + } else { + entry->name = NULL; + } + entry->type = entry_type; + if (OBJECT == entry_type) { + entry->value = malloc(sizeof(JSON_OBJECT)); + parent_num++; + object_stack[parent_num] = entry->value; + object_stack[parent_num]->entries = NULL; + continue; + } else if (NUMBER == entry_type) { + json = extract_int(json, (uint32_t **)&entry->value, &rc); + } else if (STRING == entry_type) { + json = extract_string(json, (char **)&entry->value, &rc); + } else if (BOOL == entry_type) { + json = extract_bool(json, (uint8_t **)&entry->value, &rc); + } else if (JSON_NULL == entry_type) { + json = extract_null(json, (uint8_t **)&entry->value, &rc); + } + json++; + } +} + +JSON_ENTRY *JSON_at(JSON_ENTRY *entry, size_t i) { + if (OBJECT != entry->type) + return NULL; + return &((JSON_OBJECT *)(entry->value))->entries[i]; +} + +JSON_ENTRY *JSON_search_name(JSON_ENTRY *entry, char *name) { + if (OBJECT != entry->type) + return NULL; + size_t *i = + hashmap_get_entry(((JSON_OBJECT *)(entry->value))->hash_indexes, name); + if (!i) + return NULL; + return JSON_at(entry, *i); +} + +void write_entry_content(int fd, size_t indent, JSON_ENTRY *entry) { +#define PLACE_TABS \ + { \ + for (size_t i = 0; i < indent; i++) \ + dprintf(fd, "\t"); \ + } + PLACE_TABS + if (entry->name) + dprintf(fd, "\"%s\": ", entry->name); + if (OBJECT == entry->type) { + JSON_OBJECT *object = entry->value; + dprintf(fd, "{\n"); + for (size_t i = 0; i < object->size; i++) + write_entry_content(fd, indent + 1, &object->entries[i]); + PLACE_TABS + dprintf(fd, "},\n"); + } else if (NUMBER == entry->type) + dprintf(fd, "%d,\n", *(uint32_t *)entry->value); + else if (STRING == entry->type) + dprintf(fd, "\"%s\",\n", (char *)entry->value); + else if (BOOL == entry->type) + dprintf(fd, "%s,\n", ((*(uint8_t *)entry->value) ? "true" : "false")); + else if (JSON_NULL == entry->type) + dprintf(fd, "null,\n"); +} + +void JSON_extract_fd(JSON_CTX *ctx, int fd) { + JSON_ENTRY *entry = &ctx->global_object; + write_entry_content(fd, 0, &((JSON_OBJECT *)entry->value)->entries[0]); +} diff --git a/userland/json/json.h b/userland/json/json.h new file mode 100644 index 0000000..642a878 --- /dev/null +++ b/userland/json/json.h @@ -0,0 +1,39 @@ +#ifndef JSON_H +#define JSON_H +#include "hashmap/hashmap.h" +#include +#include + +typedef enum JSON_TYPE { + NONE, + STRING, + NUMBER, + OBJECT, + ARRAY, // FIXME + BOOL, + JSON_NULL, +} JSON_TYPE; + +typedef struct JSON_ENTRY { + char *name; + JSON_TYPE type; + void *value; +} JSON_ENTRY; + +typedef struct JSON_OBJECT { + uint64_t size; + JSON_ENTRY *entries; + HashMap *hash_indexes; +} JSON_OBJECT; + +typedef struct JSON_CTX { + JSON_ENTRY global_object; +} JSON_CTX; + +void JSON_Init(JSON_CTX *ctx); +void JSON_Parse(JSON_CTX *ctx, const char *json); +void JSON_extract_fd(JSON_CTX *ctx, int whitespace, int fd); +uint64_t JSON_extract_length(JSON_CTX *ctx, int whitespace); +JSON_ENTRY *JSON_at(JSON_ENTRY *entry, uint64_t i); +JSON_ENTRY *JSON_search_name(JSON_ENTRY *entry, char *name); +#endif diff --git a/userland/json/libjson.a b/userland/json/libjson.a new file mode 100644 index 0000000..ca66650 Binary files /dev/null and b/userland/json/libjson.a differ diff --git a/userland/libc/Makefile b/userland/libc/Makefile new file mode 100644 index 0000000..98d81d4 --- /dev/null +++ b/userland/libc/Makefile @@ -0,0 +1,26 @@ +CC="/home/anton/prj/osdev/sysroot/bin/i686-sb-gcc" +AR="/home/anton/prj/osdev/sysroot/bin/i686-sb-ar" +AS="/home/anton/prj/osdev/sysroot/bin/i686-sb-as" +#CFLAGS = -ggdb -ffreestanding -O0 -Wall -Wextra -pedantic -mgeneral-regs-only -Wimplicit-fallthrough -I./include/ -static -fsanitize=shift,signed-integer-overflow,bounds +CFLAGS = -ggdb -ffreestanding -O2 -Wall -pedantic -Wimplicit-fallthrough -I./include/ -static +#BINS=c.a libc.o crt0.o malloc.o pty.o mmap.o +OBJ=crt0.o libc.o malloc/malloc.o pty.o sys/mman/mmap.o memset.o assert.o stdio/snprintf.o stdio/vfprintf.o string/memcpy.o string/memcmp.o string/strcmp.o ubsan.o string/strcpy.o isspace.o stdio/puts.o stdio/putchar.o dirent/opendir.o dirent/readdir.o dirent/closedir.o unistd/getopt.o dirent/scandir.o dirent/alphasort.o stdio/printf.o stdio/vdprintf.o stdio/vprintf.o stdio/dprintf.o stdio/vprintf.o string/strlen.o string/strnlen.o stdio/stdin.o stdio/stdout.o stdio/stderr.o stdio/getchar.o stdio/fgetc.o arpa/inet/htons.o arpa/inet/htonl.o stdio/fread.o stdio/fwrite.o stdio/fopen.o stdio/fclose.o stdio/fseek.o ctype/isascii.o stdio/fprintf.o stdlib/atoi.o stdlib/strtol.o ctype/toupper.o ctype/tolower.o string/strcat.o string/strchr.o string/sscanf.o sys/stat/stat.o stdlib/getenv.o string/strrchr.o stdio/ftell.o stdio/tmpfile.o stdio/fgets.o stdio/feof.o stdio/fscanf.o stdio/ungetc.o string/strncmp.o stdio/fputc.o string/strncpy.o stdio/remove.o stdio/ferror.o stdio/fputs.o stdlib/rand.o stdlib/srand.o unistd/getpid.o stdlib/strtoul.o stdio/fflush.o stdlib/abort.o string/strcspn.o time/localtime.o time/time.o time/clock_gettime.o time/gmtime.o time/strftime.o string/strpbrk.o ctype/isdigit.o ctype/isalpha.o ctype/isxdigit.o ctype/ispunct.o stdio/setvbuf.o stdio/fileno.o stdio/putc.o stdio/sprintf.o stdlib/abs.o string/strspn.o stdlib/qsort.o string/memmove.o setjmp/longjmp.o setjmp/setjmp.o libgen/basename.o string/strdup.o string/strndup.o string/strlcpy.o stdlib/atexit.o stdio/open_memstream.o libgen/dirname.o unistd/unlink.o string/strstr.o string/strcasecmp.o string/strncasecmp.o stdlib/mkstemp.o string/strtok.o unistd/execvp.o unistd/_exit.o ctype/isalnum.o time/ctime_r.o stdlib/strtold.o sys/time/gettimeofday.o stdio/fgetpos.o stdio/fsetpos.o ctype/isprint.o stdlib/system.o stdio/tmpnam.o unistd/msleep.o stdlib/atof.o stdlib/strtod.o stdio/rename.o sys/stat/mkdir.o unistd/uptime.o +#OBJ=crt0.o libc.o malloc/malloc.o pty.o sys/mman/mmap.o memset.o assert.o stdio/snprintf.o stdio/vfprintf.o string/memcpy.o string/memcmp.o string/strcmp.o ubsan.o string/strcpy.o isspace.o stdio/puts.o stdio/putchar.o dirent/opendir.o dirent/readdir.o dirent/closedir.o unistd/getopt.o dirent/scandir.o dirent/alphasort.o stdio/printf.o stdio/vdprintf.o stdio/vprintf.o stdio/dprintf.o stdio/vprintf.o string/strlen.o string/strnlen.o stdio/stdin.o stdio/stdout.o stdio/stderr.o stdio/getchar.o stdio/fgetc.o arpa/inet/htons.o arpa/inet/htonl.o stdio/fread.o stdio/fwrite.o stdio/fopen.o stdio/fclose.o stdio/fseek.o ctype/isascii.o stdio/fprintf.o stdlib/atoi.o stdlib/strtol.o ctype/toupper.o ctype/tolower.o string/strcat.o string/strchr.o string/sscanf.o sys/stat/stat.o stdlib/getenv.o string/strrchr.o stdio/ftell.o stdio/tmpfile.o stdio/fgets.o stdio/feof.o stdio/fscanf.o stdio/ungetc.o string/strncmp.o stdio/fputc.o string/strncpy.o stdio/remove.o stdio/ferror.o stdio/fputs.o stdlib/rand.o stdlib/srand.o unistd/getpid.o stdlib/strtoul.o stdio/fflush.o stdlib/abort.o string/strcspn.o time/localtime.o time/time.o time/clock_gettime.o time/gmtime.o time/strftime.o string/strpbrk.o ctype/isdigit.o ctype/isalpha.o ctype/isxdigit.o ctype/ispunct.o stdio/setvbuf.o stdio/fileno.o stdio/putc.o stdio/sprintf.o stdlib/abs.o string/strspn.o stdlib/qsort.o string/memmove.o setjmp/longjmp.o setjmp/setjmp.o +all: libc.a + +%.o: %.c + $(CC) $(CFLAGS) -O0 -I. -o $@ -c $< -lgcc + +%.o: %.s + $(AS) $< -o $@ + +libc.a: $(OBJ) + $(AR) rcs libc.a $(OBJ) + +install: + cp crt0.o /home/anton/prj/osdev/sysroot/lib/ + cp libc.a /home/anton/prj/osdev/sysroot/lib/ + cp -r include /home/anton/prj/osdev/sysroot/usr/ + +clean: + rm libc.a *.o */*.o */*/*.o diff --git a/userland/libc/arpa/inet.h b/userland/libc/arpa/inet.h new file mode 100644 index 0000000..7a033f2 --- /dev/null +++ b/userland/libc/arpa/inet.h @@ -0,0 +1,4 @@ +#include + +uint32_t htonl(uint32_t hostlong); +uint16_t htons(uint16_t hostlong); diff --git a/userland/libc/arpa/inet/htonl.c b/userland/libc/arpa/inet/htonl.c new file mode 100644 index 0000000..4b66747 --- /dev/null +++ b/userland/libc/arpa/inet/htonl.c @@ -0,0 +1,11 @@ +#include +#include +#include + +uint32_t htonl(uint32_t hostlong) { +#if BYTE_ORDER == LITTLE_ENDIAN + hostlong = (uint32_t)(htons(hostlong >> 16)) | + (uint32_t)(htons(hostlong & 0xFFFF) << 16); +#endif + return hostlong; +} diff --git a/userland/libc/arpa/inet/htons.c b/userland/libc/arpa/inet/htons.c new file mode 100644 index 0000000..798a64a --- /dev/null +++ b/userland/libc/arpa/inet/htons.c @@ -0,0 +1,10 @@ +#include +#include +#include + +uint16_t htons(uint16_t hostlong) { +#if BYTE_ORDER == LITTLE_ENDIAN + hostlong = ((hostlong & 0xFF00) >> 8) | ((hostlong & 0x00FF) << 8); +#endif + return hostlong; +} diff --git a/userland/libc/assert.c b/userland/libc/assert.c new file mode 100644 index 0000000..4082f64 --- /dev/null +++ b/userland/libc/assert.c @@ -0,0 +1,9 @@ +#include +#include +#include + +void aFailed(char *f, int l) { + printf("Assert failed\n"); + printf("%s : %d\n", f, l); + exit(1); +} diff --git a/userland/libc/assert.h b/userland/libc/assert.h new file mode 100644 index 0000000..a009e5f --- /dev/null +++ b/userland/libc/assert.h @@ -0,0 +1,10 @@ +#ifndef ASSERT_H +#define ASSERT_H + +#define assert(expr) \ + { \ + if (!(expr)) \ + aFailed(__FILE__, __LINE__); \ + } +void aFailed(char *f, int l); +#endif diff --git a/userland/libc/crt0.s b/userland/libc/crt0.s new file mode 100644 index 0000000..05144d4 --- /dev/null +++ b/userland/libc/crt0.s @@ -0,0 +1,13 @@ +.global _start +.extern main +_start: + call main + mov %eax, %ebx + mov $8, %eax + int $0x80 +l: + nop + nop + nop + nop + jmp l diff --git a/userland/libc/ctype.h b/userland/libc/ctype.h new file mode 100644 index 0000000..5be4a89 --- /dev/null +++ b/userland/libc/ctype.h @@ -0,0 +1,12 @@ +#ifndef CTYPE_H +#define CTYPE_H + +int isspace(int c); +int isascii(int c); +int toupper(int c); +int tolower(int c); +int isdigit(int c); +int isalpha(int c); +int isxdigit(int c); +int ispunct(int c); +#endif diff --git a/userland/libc/ctype/isalnum.c b/userland/libc/ctype/isalnum.c new file mode 100644 index 0000000..870728d --- /dev/null +++ b/userland/libc/ctype/isalnum.c @@ -0,0 +1,6 @@ +#include + +// This is probably the most useless libc function I have seen so far. +int isalnum(int c) { + return isalpha(c) || isdigit(c); +} diff --git a/userland/libc/ctype/isalpha.c b/userland/libc/ctype/isalpha.c new file mode 100644 index 0000000..130f493 --- /dev/null +++ b/userland/libc/ctype/isalpha.c @@ -0,0 +1,4 @@ +#include + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/isalpha.html +int isalpha(int c) { return (('A' <= toupper(c)) && ('Z' >= toupper(c))); } diff --git a/userland/libc/ctype/isascii.c b/userland/libc/ctype/isascii.c new file mode 100644 index 0000000..660c8bb --- /dev/null +++ b/userland/libc/ctype/isascii.c @@ -0,0 +1,4 @@ +#include + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/isascii.html +int isascii(int c) { return (c < 128); } diff --git a/userland/libc/ctype/isdigit.c b/userland/libc/ctype/isdigit.c new file mode 100644 index 0000000..790b9f1 --- /dev/null +++ b/userland/libc/ctype/isdigit.c @@ -0,0 +1,6 @@ +#include + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/isdigit.html +int isdigit(int c) { + return ('0' <= c && c <= '9'); +} diff --git a/userland/libc/ctype/isprint.c b/userland/libc/ctype/isprint.c new file mode 100644 index 0000000..e6a3d0e --- /dev/null +++ b/userland/libc/ctype/isprint.c @@ -0,0 +1,3 @@ +#include + +int isprint(int c) { return c > 0x20 && 0x7F != c; } diff --git a/userland/libc/ctype/ispunct.c b/userland/libc/ctype/ispunct.c new file mode 100644 index 0000000..18dc7d8 --- /dev/null +++ b/userland/libc/ctype/ispunct.c @@ -0,0 +1,6 @@ +#include + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/ispunct.html +int ispunct(int c) { + return (c == '.'); +} diff --git a/userland/libc/ctype/isxdigit.c b/userland/libc/ctype/isxdigit.c new file mode 100644 index 0000000..c843725 --- /dev/null +++ b/userland/libc/ctype/isxdigit.c @@ -0,0 +1,6 @@ +#include + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/isxdigit.html +int isxdigit(int c) { + return isdigit(c) || ('A' >= toupper(c) && 'Z' <= toupper(c)); +} diff --git a/userland/libc/ctype/tolower.c b/userland/libc/ctype/tolower.c new file mode 100644 index 0000000..f1bb163 --- /dev/null +++ b/userland/libc/ctype/tolower.c @@ -0,0 +1,7 @@ +#include + +int tolower(int c) { + if (c >= 'A' && c <= 'Z') + return c - 'A' + 'a'; + return c; +} diff --git a/userland/libc/ctype/toupper.c b/userland/libc/ctype/toupper.c new file mode 100644 index 0000000..0f33886 --- /dev/null +++ b/userland/libc/ctype/toupper.c @@ -0,0 +1,7 @@ +#include + +int toupper(int c) { + if (c >= 'a' && c <= 'z') + return c - 'a' + 'A'; + return c; +} diff --git a/userland/libc/dirent.h b/userland/libc/dirent.h new file mode 100644 index 0000000..f190a7c --- /dev/null +++ b/userland/libc/dirent.h @@ -0,0 +1,28 @@ +#ifndef DIRENT_H +#define DIRENT_H +#include +#include +#include +#include +#include +#include + +struct dirent { + ino_t d_ino; // File serial number. + char d_name[PATH_MAX]; // Filename string of entry. +}; + +typedef struct { + int fd; + struct dirent internal_direntry; + int dir_num; +} DIR; + +DIR *opendir(const char *dirname); +struct dirent *readdir(DIR *dir); +int closedir(DIR *dirp); +int alphasort(const struct dirent **d1, const struct dirent **d2); +int scandir(const char *dir, struct dirent ***namelist, + int (*sel)(const struct dirent *), + int (*compar)(const struct dirent **, const struct dirent **)); +#endif diff --git a/userland/libc/dirent/alphasort.c b/userland/libc/dirent/alphasort.c new file mode 100644 index 0000000..43a4b5f --- /dev/null +++ b/userland/libc/dirent/alphasort.c @@ -0,0 +1,7 @@ +#include + +int alphasort(const struct dirent **d1, const struct dirent **d2) { + // TODO: Actually sort it + *d2 = *d1; + return 0; +} diff --git a/userland/libc/dirent/closedir.c b/userland/libc/dirent/closedir.c new file mode 100644 index 0000000..e216d7c --- /dev/null +++ b/userland/libc/dirent/closedir.c @@ -0,0 +1,7 @@ +#include + +int closedir(DIR *dir) { + close(dir->fd); + free(dir); + return 0; +} diff --git a/userland/libc/dirent/opendir.c b/userland/libc/dirent/opendir.c new file mode 100644 index 0000000..7bfa562 --- /dev/null +++ b/userland/libc/dirent/opendir.c @@ -0,0 +1,11 @@ +#include + +DIR *opendir(const char *dirname) { + int fd = open(dirname, O_RDONLY, 0); + if (-1 == fd) + return NULL; + DIR *rc = malloc(sizeof(DIR)); + rc->fd = fd; + rc->dir_num = 0; + return rc; +} diff --git a/userland/libc/dirent/readdir.c b/userland/libc/dirent/readdir.c new file mode 100644 index 0000000..88aff48 --- /dev/null +++ b/userland/libc/dirent/readdir.c @@ -0,0 +1,14 @@ +#include + +struct dirent *readdir(DIR *dir) { + size_t offset = dir->dir_num * sizeof(struct dirent); + int rc; + if (-1 == (rc = pread(dir->fd, &dir->internal_direntry, sizeof(struct dirent), + offset))) + return NULL; + if (rc < sizeof(struct dirent)) + return NULL; + + dir->dir_num++; + return &(dir->internal_direntry); +} diff --git a/userland/libc/dirent/scandir.c b/userland/libc/dirent/scandir.c new file mode 100644 index 0000000..1520140 --- /dev/null +++ b/userland/libc/dirent/scandir.c @@ -0,0 +1,43 @@ +#include +#include +#include + +int nop_sel(const struct dirent *unused) { + (void)unused; + return 1; +} + +int nop_compar(const struct dirent **d1, const struct dirent **d2) { + *d2 = *d1; + return 0; +} + +int scandir(const char *dir, struct dirent ***namelist, + int (*sel)(const struct dirent *), + int (*compar)(const struct dirent **, const struct dirent **)) { + if (!sel) + sel = nop_sel; + + if (!compar) + compar = nop_compar; + + DIR *d = opendir(dir); + struct dirent **list = NULL; + struct dirent *e; + int rc = 0; + for (; (e = readdir(d));) { + if (!sel(e)) + continue; + struct dirent *p = malloc(sizeof(struct dirent)); + memcpy(p, e, sizeof(struct dirent)); + list = realloc(list, (rc + 1) * sizeof(struct dirent *)); + list[rc] = p; + rc++; + } + // struct dirent **new_list; + // compar((const struct dirent **)list, (const struct dirent **)new_list); + // *namelist = new_list; + *namelist = list; + // closedir(d); + return rc; +} diff --git a/userland/libc/endian.h b/userland/libc/endian.h new file mode 100644 index 0000000..f265a67 --- /dev/null +++ b/userland/libc/endian.h @@ -0,0 +1,2 @@ +#define LITTLE_ENDIAN 0 +#define BYTE_ORDER LITTLE_ENDIAN diff --git a/userland/libc/errno.h b/userland/libc/errno.h new file mode 100644 index 0000000..ec9a25e --- /dev/null +++ b/userland/libc/errno.h @@ -0,0 +1,87 @@ +#ifndef ERRNO_H +#define ERRNO_H +// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html +#define E2BIG 1 // Argument list too long. +#define EACCES 2 // Permission denied. +#define EADDRINUSE 3 // Address in use. +#define EADDRNOTAVAIL 4 // Address not available. +#define EAFNOSUPPORT 5 // Address family not supported. +#define EAGAIN 6 // Resource unavailable, try again. +#define EALREADY 7 // Connection already in progress. +#define EBADF 8 // Bad file descriptor. +#define EBADMSG 9 // Bad message. +#define EBUSY 10 // Device or resource busy. +#define ECANCELED 11 // Operation canceled. +#define ECHILD 12 // No child processes. +#define ECONNABORTED 13 // Connection aborted. +#define ECONNREFUSED 14 // Connection refused. +#define ECONNRESET 15 // Connection reset. +#define EDEADLK 16 // Resource deadlock would occur. +#define EDESTADDRREQ 17 // Destination address required. +#define EDOM 18 // Mathematics argument out of domain of function. +#define EDQUOT 19 // Reserved. +#define EEXIST 20 // File exists. +#define EFAULT 21 // Bad address. +#define EFBIG 22 // File too large. +#define EHOSTUNREACH 23 // Host is unreachable. +#define EIDRM 24 // Identifier removed. +#define EILSEQ 25 // Illegal byte sequence. +#define EINPROGRESS 26 // Operation in progress. +#define EINTR 27 // Interrupted function. +#define EINVAL 28 // Invalid argument. +#define EIO 29 // I/O error. +#define EISCONN 30 // Socket is connected. +#define EISDIR 31 // Is a directory. +#define ELOOP 32 // Too many levels of symbolic links. +#define EMFILE 33 // File descriptor value too large. +#define EMLINK 34 // Too many links. +#define EMSGSIZE 35 // Message too large. +#define EMULTIHOP 36 // Reserved. +#define ENAMETOOLONG 37 // Filename too long. +#define ENETDOWN 38 // Network is down. +#define ENETRESET 39 // Connection aborted by network. +#define ENETUNREACH 40 // Network unreachable. +#define ENFILE 41 // Too many files open in system. +#define ENOBUFS 42 // No buffer space available. +#define ENODATA 43 // No message is available on the STREAM head read queue. +#define ENODEV 44 // No such device. +#define ENOENT 45 // No such file or directory. +#define ENOEXEC 46 // Executable file format error. +#define ENOLCK 47 // No locks available. +#define ENOLINK 48 // Reserved. +#define ENOMEM 49 // Not enough space. +#define ENOMSG 50 // No message of the desired type. +#define ENOPROTOOPT 51 // Protocol not available. +#define ENOSPC 52 // No space left on device. +#define ENOSR 53 // No STREAM resources. +#define ENOSTR 54 // Not a STREAM. +#define ENOSYS 55 // Functionality not supported. +#define ENOTCONN 56 // The socket is not connected. +#define ENOTDIR 57 // Not a directory or a symbolic link to a directory. +#define ENOTEMPTY 58 // Directory not empty. +#define ENOTRECOVERABLE 59 // State not recoverable. +#define ENOTSOCK 60 // Not a socket. +#define ENOTSUP 61 // Not supported (may be the same value as. +#define ENOTTY 62 // Inappropriate I/O control operation. +#define ENXIO 63 // No such device or address. +#define EOPNOTSUPP ENOTSUP // Operation not supported on socket. +#define EOVERFLOW 65 // Value too large to be stored in data type. +#define EOWNERDEAD 66 // Previous owner died. +#define EPERM 67 // Operation not permitted. +#define EPIPE 68 // Broken pipe. +#define EPROTO 69 // Protocol error. +#define EPROTONOSUPPORT 70 // Protocol not supported. +#define EPROTOTYPE 71 // Protocol wrong type for socket. +#define ERANGE 72 // Result too large. +#define EROFS 73 // Read-only file system. +#define ESPIPE 74 // Invalid seek. +#define ESRCH 75 // No such process. +#define ESTALE 76 // Reserved. +#define ETIME 77 // Stream ioctl() timeout. +#define ETIMEDOUT 78 // Connection timed out. +#define ETXTBSY 79 // Text file busy. +#define EWOULDBLOCK EAGAIN // Operation would block. +#define EXDEV 81 // Cross-device link. + +extern int errno; +#endif diff --git a/userland/libc/fcntl.h b/userland/libc/fcntl.h new file mode 100644 index 0000000..4c1eb9c --- /dev/null +++ b/userland/libc/fcntl.h @@ -0,0 +1,10 @@ +// FIXME: Is there some standard value for this? +#define O_NONBLOCK (1 << 0) +#define O_READ (1 << 1) +#define O_WRITE (1 << 2) +#define O_CREAT (1 << 3) +#define O_RDONLY O_READ +#define O_WRONLY O_WRITE +#define O_RDWR (O_WRITE | O_READ) + +int open(const char *file, int flags, int mode); diff --git a/userland/libc/include/arpa/inet.h b/userland/libc/include/arpa/inet.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/assert.h b/userland/libc/include/assert.h new file mode 100644 index 0000000..a009e5f --- /dev/null +++ b/userland/libc/include/assert.h @@ -0,0 +1,10 @@ +#ifndef ASSERT_H +#define ASSERT_H + +#define assert(expr) \ + { \ + if (!(expr)) \ + aFailed(__FILE__, __LINE__); \ + } +void aFailed(char *f, int l); +#endif diff --git a/userland/libc/include/byteswap.h b/userland/libc/include/byteswap.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/ctype.h b/userland/libc/include/ctype.h new file mode 100644 index 0000000..7c8c311 --- /dev/null +++ b/userland/libc/include/ctype.h @@ -0,0 +1,14 @@ +#ifndef CTYPE_H +#define CTYPE_H + +int isspace(int c); +int isascii(int c); +int toupper(int c); +int tolower(int c); +int isdigit(int c); +int isalpha(int c); +int isxdigit(int c); +int ispunct(int c); +int isalnum(int c); +int isprint(int c); +#endif diff --git a/userland/libc/include/dirent.h b/userland/libc/include/dirent.h new file mode 100644 index 0000000..f190a7c --- /dev/null +++ b/userland/libc/include/dirent.h @@ -0,0 +1,28 @@ +#ifndef DIRENT_H +#define DIRENT_H +#include +#include +#include +#include +#include +#include + +struct dirent { + ino_t d_ino; // File serial number. + char d_name[PATH_MAX]; // Filename string of entry. +}; + +typedef struct { + int fd; + struct dirent internal_direntry; + int dir_num; +} DIR; + +DIR *opendir(const char *dirname); +struct dirent *readdir(DIR *dir); +int closedir(DIR *dirp); +int alphasort(const struct dirent **d1, const struct dirent **d2); +int scandir(const char *dir, struct dirent ***namelist, + int (*sel)(const struct dirent *), + int (*compar)(const struct dirent **, const struct dirent **)); +#endif diff --git a/userland/libc/include/endian.h b/userland/libc/include/endian.h new file mode 100644 index 0000000..f265a67 --- /dev/null +++ b/userland/libc/include/endian.h @@ -0,0 +1,2 @@ +#define LITTLE_ENDIAN 0 +#define BYTE_ORDER LITTLE_ENDIAN diff --git a/userland/libc/include/err.h b/userland/libc/include/err.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/errno.h b/userland/libc/include/errno.h new file mode 100644 index 0000000..ec9a25e --- /dev/null +++ b/userland/libc/include/errno.h @@ -0,0 +1,87 @@ +#ifndef ERRNO_H +#define ERRNO_H +// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html +#define E2BIG 1 // Argument list too long. +#define EACCES 2 // Permission denied. +#define EADDRINUSE 3 // Address in use. +#define EADDRNOTAVAIL 4 // Address not available. +#define EAFNOSUPPORT 5 // Address family not supported. +#define EAGAIN 6 // Resource unavailable, try again. +#define EALREADY 7 // Connection already in progress. +#define EBADF 8 // Bad file descriptor. +#define EBADMSG 9 // Bad message. +#define EBUSY 10 // Device or resource busy. +#define ECANCELED 11 // Operation canceled. +#define ECHILD 12 // No child processes. +#define ECONNABORTED 13 // Connection aborted. +#define ECONNREFUSED 14 // Connection refused. +#define ECONNRESET 15 // Connection reset. +#define EDEADLK 16 // Resource deadlock would occur. +#define EDESTADDRREQ 17 // Destination address required. +#define EDOM 18 // Mathematics argument out of domain of function. +#define EDQUOT 19 // Reserved. +#define EEXIST 20 // File exists. +#define EFAULT 21 // Bad address. +#define EFBIG 22 // File too large. +#define EHOSTUNREACH 23 // Host is unreachable. +#define EIDRM 24 // Identifier removed. +#define EILSEQ 25 // Illegal byte sequence. +#define EINPROGRESS 26 // Operation in progress. +#define EINTR 27 // Interrupted function. +#define EINVAL 28 // Invalid argument. +#define EIO 29 // I/O error. +#define EISCONN 30 // Socket is connected. +#define EISDIR 31 // Is a directory. +#define ELOOP 32 // Too many levels of symbolic links. +#define EMFILE 33 // File descriptor value too large. +#define EMLINK 34 // Too many links. +#define EMSGSIZE 35 // Message too large. +#define EMULTIHOP 36 // Reserved. +#define ENAMETOOLONG 37 // Filename too long. +#define ENETDOWN 38 // Network is down. +#define ENETRESET 39 // Connection aborted by network. +#define ENETUNREACH 40 // Network unreachable. +#define ENFILE 41 // Too many files open in system. +#define ENOBUFS 42 // No buffer space available. +#define ENODATA 43 // No message is available on the STREAM head read queue. +#define ENODEV 44 // No such device. +#define ENOENT 45 // No such file or directory. +#define ENOEXEC 46 // Executable file format error. +#define ENOLCK 47 // No locks available. +#define ENOLINK 48 // Reserved. +#define ENOMEM 49 // Not enough space. +#define ENOMSG 50 // No message of the desired type. +#define ENOPROTOOPT 51 // Protocol not available. +#define ENOSPC 52 // No space left on device. +#define ENOSR 53 // No STREAM resources. +#define ENOSTR 54 // Not a STREAM. +#define ENOSYS 55 // Functionality not supported. +#define ENOTCONN 56 // The socket is not connected. +#define ENOTDIR 57 // Not a directory or a symbolic link to a directory. +#define ENOTEMPTY 58 // Directory not empty. +#define ENOTRECOVERABLE 59 // State not recoverable. +#define ENOTSOCK 60 // Not a socket. +#define ENOTSUP 61 // Not supported (may be the same value as. +#define ENOTTY 62 // Inappropriate I/O control operation. +#define ENXIO 63 // No such device or address. +#define EOPNOTSUPP ENOTSUP // Operation not supported on socket. +#define EOVERFLOW 65 // Value too large to be stored in data type. +#define EOWNERDEAD 66 // Previous owner died. +#define EPERM 67 // Operation not permitted. +#define EPIPE 68 // Broken pipe. +#define EPROTO 69 // Protocol error. +#define EPROTONOSUPPORT 70 // Protocol not supported. +#define EPROTOTYPE 71 // Protocol wrong type for socket. +#define ERANGE 72 // Result too large. +#define EROFS 73 // Read-only file system. +#define ESPIPE 74 // Invalid seek. +#define ESRCH 75 // No such process. +#define ESTALE 76 // Reserved. +#define ETIME 77 // Stream ioctl() timeout. +#define ETIMEDOUT 78 // Connection timed out. +#define ETXTBSY 79 // Text file busy. +#define EWOULDBLOCK EAGAIN // Operation would block. +#define EXDEV 81 // Cross-device link. + +extern int errno; +#endif diff --git a/userland/libc/include/fcntl.h b/userland/libc/include/fcntl.h new file mode 100644 index 0000000..7f0906d --- /dev/null +++ b/userland/libc/include/fcntl.h @@ -0,0 +1,12 @@ +// FIXME: Is there some standard value for this? +#define O_NONBLOCK (1 << 0) +#define O_READ (1 << 1) +#define O_WRITE (1 << 2) +#define O_CREAT (1 << 3) +#define O_TRUNC (1 << 4) + +#define O_RDONLY O_READ +#define O_WRONLY O_WRITE +#define O_RDWR (O_WRITE | O_READ) + +int open(const char *file, int flags, int mode); diff --git a/userland/libc/include/fnmatch.h b/userland/libc/include/fnmatch.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/glob.h b/userland/libc/include/glob.h new file mode 100644 index 0000000..f9e9c57 --- /dev/null +++ b/userland/libc/include/glob.h @@ -0,0 +1,10 @@ +#ifndef GLOB_H +#define GLOB_H +#include + +typedef struct { + size_t gl_pathc; // Count of paths matched by pattern. + char **gl_pathv; // Pointer to a list of matched pathnames + size_t gl_offs; // Slots to reserve at the beginning of gl_pathv. +} glob_t; +#endif diff --git a/userland/libc/include/grp.h b/userland/libc/include/grp.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/input.h b/userland/libc/include/input.h new file mode 100644 index 0000000..a6602f5 --- /dev/null +++ b/userland/libc/include/input.h @@ -0,0 +1,9 @@ +#ifndef INPUT_H +#define INPUT_H +#include + +struct input_event { + uint16_t key; + uint8_t status; +}; +#endif diff --git a/userland/libc/include/inttypes.h b/userland/libc/include/inttypes.h new file mode 100644 index 0000000..adde7c8 --- /dev/null +++ b/userland/libc/include/inttypes.h @@ -0,0 +1,19 @@ +#include + +// FIXME: These are not correct +#define PRId8 "d" +#define PRId16 "d" +#define PRId32 "d" +#define PRId64 "d" +#define PRIu8 "d" +#define PRIu16 "d" +#define PRIu32 "d" +#define PRIu64 "d" +#define PRIx8 "x" +#define PRIx16 "x" +#define PRIx32 "x" +#define PRIx64 "x" +#define PRIX8 "x" +#define PRIX16 "x" +#define PRIX32 "x" +#define PRIX64 "x" diff --git a/userland/libc/include/langinfo.h b/userland/libc/include/langinfo.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/libgen.h b/userland/libc/include/libgen.h new file mode 100644 index 0000000..16dc3ed --- /dev/null +++ b/userland/libc/include/libgen.h @@ -0,0 +1,6 @@ +#ifndef LIBGEN_H +#define LIBGEN_H + +char *basename(char *path); +char *dirname(char *path); +#endif diff --git a/userland/libc/include/limits.h b/userland/libc/include/limits.h new file mode 100644 index 0000000..6d0abe0 --- /dev/null +++ b/userland/libc/include/limits.h @@ -0,0 +1,4 @@ +#define PATH_MAX 256 +#define FILENAME_MAX PATH_MAX +#define ULONG_MAX 0xFFFFFFFFUL +#define LONG_MAX 2147483647 diff --git a/userland/libc/include/locale.h b/userland/libc/include/locale.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/math.h b/userland/libc/include/math.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/net/if.h b/userland/libc/include/net/if.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/netdb.h b/userland/libc/include/netdb.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/netinet/in.h b/userland/libc/include/netinet/in.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/netinet/tcp.h b/userland/libc/include/netinet/tcp.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/paths.h b/userland/libc/include/paths.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/poll.h b/userland/libc/include/poll.h new file mode 100644 index 0000000..e3c6d8d --- /dev/null +++ b/userland/libc/include/poll.h @@ -0,0 +1,17 @@ +#ifndef POLL_H +#define POLL_H +#include + +#define POLLIN (1 << 0) +#define POLLPRI (1 << 1) +#define POLLOUT (1 << 2) +#define POLLHUP (1 << 3) + +struct pollfd { + int fd; + short events; + short revents; +}; + +int poll(struct pollfd *fds, size_t nfds, int timeout); +#endif diff --git a/userland/libc/include/pty.h b/userland/libc/include/pty.h new file mode 100644 index 0000000..b8ce978 --- /dev/null +++ b/userland/libc/include/pty.h @@ -0,0 +1,6 @@ +#ifndef PTY_H +#define PTY_H +int openpty(int *amaster, int *aslave, char *name, + /*const struct termios*/ void *termp, + /*const struct winsize*/ void *winp); +#endif diff --git a/userland/libc/include/pwd.h b/userland/libc/include/pwd.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/regex.h b/userland/libc/include/regex.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/sched.h b/userland/libc/include/sched.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/setjmp.h b/userland/libc/include/setjmp.h new file mode 100644 index 0000000..ea15cf3 --- /dev/null +++ b/userland/libc/include/setjmp.h @@ -0,0 +1,14 @@ +#ifndef SETJMP_H +#define SETJMP_H +typedef unsigned long __jmp_buf[6]; +typedef struct __jmp_buf_tag { + __jmp_buf __jb; + unsigned long __fl; + unsigned long __ss[128/sizeof(long)]; +} jmp_buf[1]; +typedef jmp_buf sigjmp_buf; + +void _longjmp(jmp_buf, int); +void longjmp(jmp_buf, int); +void siglongjmp(sigjmp_buf, int); +#endif diff --git a/userland/libc/include/signal.h b/userland/libc/include/signal.h new file mode 100644 index 0000000..2e6566d --- /dev/null +++ b/userland/libc/include/signal.h @@ -0,0 +1,9 @@ +#ifndef SIGNAL_H +#define SIGNAL_H +#define SIGHUP 0 +#define SIGINT 1 +#define SIGWINCH 2 +#define SIGQUIT 3 +#define SIG_IGN 4 +typedef int sig_atomic_t; +#endif // SIGNAL_H diff --git a/userland/libc/include/socket.h b/userland/libc/include/socket.h new file mode 100644 index 0000000..5e86b45 --- /dev/null +++ b/userland/libc/include/socket.h @@ -0,0 +1,41 @@ +#include +#include + +#define AF_UNIX 0 +#define AF_LOCAL AF_UNIX + +#define INADDR_ANY 0 + +typedef struct { + int domain; + int type; + int protocol; + + // UNIX socket + char *path; + int incoming_fd; +} SOCKET; + +typedef struct { + char *path; + SOCKET *s; +} OPEN_UNIX_SOCKET; + +typedef uint32_t in_addr_t; +typedef uint16_t in_port_t; +typedef unsigned int sa_family_t; +typedef uint32_t socklen_t; + +struct sockaddr { + sa_family_t sa_family; /* Address family */ + char *sa_data; /* Socket address */ +}; + +struct sockaddr_un { + sa_family_t sun_family; /* Address family */ + char *sun_path; /* Socket pathname */ +}; + +int socket(int domain, int type, int protocol); +int accept(int socket, struct sockaddr *address, socklen_t *address_len); +int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); diff --git a/userland/libc/include/stdio.h b/userland/libc/include/stdio.h new file mode 100644 index 0000000..014e2ac --- /dev/null +++ b/userland/libc/include/stdio.h @@ -0,0 +1,116 @@ +#ifndef STDIO_H +#define STDIO_H +#include +#include +#include + +// FIXME: Most of these should probably not be here. But I am too lazy +// to fix it right now. This is futures mees problem to deal wth. + +#define EOF (-1) + +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 + +#define BUFSIZ 4096 + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/setvbuf.html +#define _IOFBF 1 // shall cause input/output to be fully buffered. +#define _IOLBF 2 // shall cause input/output to be line buffered. +#define _IONBF 3 // shall cause input/output to be unbuffered. + +typedef long fpos_t; + +typedef struct __IO_FILE FILE; +struct __IO_FILE { + size_t (*write)(FILE *, const unsigned char *, size_t); + size_t (*read)(FILE *, unsigned char *, size_t); + int (*seek)(FILE *, long, int); + long offset_in_file; + int buffered_char; + int has_buffered_char; + int fd; + uint8_t is_eof; + uint8_t has_error; + uint64_t file_size; + void *cookie; +}; + +size_t write_fd(FILE *f, const unsigned char *s, size_t l); +size_t read_fd(FILE *f, unsigned char *s, size_t l); +int seek_fd(FILE *stream, long offset, int whence); + +typedef struct { + int fd; +} FILE_FD_COOKIE; + +extern FILE __stdin_FILE; +extern FILE __stdout_FILE; +extern FILE __stderr_FILE; + +#define stdin (&__stdin_FILE) +#define stdout (&__stdout_FILE) +//#define stderr (&__stderr_FILE) +#define stderr (&__stdout_FILE) + +typedef int mode_t; + +void perror(const char *s); + +int putchar(int c); +int puts(const char *s); +int brk(void *addr); +void *sbrk(intptr_t increment); +int write(int fd, const char *buf, size_t count); +int pwrite(int fd, const char *buf, size_t count, size_t offset); +int printf(const char *format, ...); +int pread(int fd, void *buf, size_t count, size_t offset); +int read(int fd, void *buf, size_t count); +int fork(void); +int memcmp(const void *s1, const void *s2, size_t n); +int wait(int *stat_loc); +void exit(int status); +void *memcpy(void *dest, const void *src, uint32_t n); +int shm_open(const char *name, int oflag, mode_t mode); +int dprintf(int fd, const char *format, ...); +int vdprintf(int fd, const char *format, va_list ap); +int vprintf(const char *format, va_list ap); +int snprintf(char *str, size_t size, const char *format, ...); +int vsnprintf(char *str, size_t size, const char *format, va_list ap); +int vfprintf(FILE *f, const char *fmt, va_list ap); +int fgetc(FILE *stream); +int getchar(void); +#define getc(_a) fgetc(_a) +size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); +size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); +FILE *fopen(const char *pathname, const char *mode); +int fclose(FILE *stream); +int fseek(FILE *stream, long offset, int whence); +int fprintf(FILE *f, const char *fmt, ...); +int atoi(const char *str); +long strtol(const char *nptr, char **endptr, int base); +char *strchr(const char *s, int c); +char *strcat(char *s1, const char *s2); +char *fgets(char *s, int n, FILE *stream); +FILE *tmpfile(void); +int feof(FILE *stream); +int fscanf(FILE *stream, const char *format, ...); +int ungetc(int c, FILE *stream); +long ftell(FILE *stream); +int fputc(int c, FILE *stream); +int remove(const char *path); +int ferror(FILE *stream); +int fputs(const char *s, FILE *stream); +int fflush(FILE *stream); +int setvbuf(FILE *stream, char *restrict buf, int type, size_t size); +int fileno(FILE *stream); +int putc(int c, FILE *stream); +int vsprintf(char *str, const char *format, va_list ap); +int sprintf(char *str, const char *format, ...); +FILE *open_memstream(char **bufp, size_t *sizep); +int fsetpos(FILE *stream, const fpos_t *pos); +int fgetpos(FILE *restrict stream, fpos_t *restrict pos); +char *tmpnam(char *s); +int rename(const char *old, const char *new); +#endif diff --git a/userland/libc/include/stdlib.h b/userland/libc/include/stdlib.h new file mode 100644 index 0000000..c88f2f3 --- /dev/null +++ b/userland/libc/include/stdlib.h @@ -0,0 +1,32 @@ +#ifndef STDLIB_H +#define STDLIB_H +#include +#include +#define RAND_MAX (UINT32_MAX) +#define EXIT_SUCCESS 0 +#define EXIT_FAILURE 1 + +typedef size_t size_t; // only for 32 bit + +void *malloc(size_t s); +void *calloc(size_t nelem, size_t elsize); +void *realloc(void *ptr, size_t size); +void free(void *p); +char *getenv(const char *name); +int rand(void); +void srand(unsigned int seed); +unsigned long strtoul(const char *restrict str, char **restrict endptr, + int base); +long strtol(const char *str, char **restrict endptr, int base); +void abort(void); +int abs(int i); +void qsort(void *base, size_t nel, size_t width, + int (*compar)(const void *, const void *)); +int atexit(void (*func)(void)); +int mkstemp(char *template); +long double strtold(const char *restrict nptr, char **restrict endptr); +int system(const char *command); +double atof(const char *str); +double strtod(const char *restrict nptr, char **restrict endptr); +int atoi(const char *str); +#endif diff --git a/userland/libc/include/string.h b/userland/libc/include/string.h new file mode 100644 index 0000000..0c61efa --- /dev/null +++ b/userland/libc/include/string.h @@ -0,0 +1,29 @@ +#ifndef STRING_H +#define STRING_H +#include +#include + +char *strerror(int errnum); +void *memset(void *s, int c, size_t n); +void *memcpy(void *dest, const void *src, uint32_t n); +int strcmp(const char *s1, const char *s2); +char *strcpy(char *dest, const char *src); +size_t strlen(const char *s); +size_t strnlen(const char *s, size_t maxlen); +int sscanf(const char *s, const char *restrict format, ...); +char *strrchr(const char *s, int c); +int strncmp(const char *s1, const char *s2, size_t n); +char *strncpy(char *s1, const char *s2, size_t n); +size_t *strlcpy(char *s1, const char *s2, size_t n); +size_t strcspn(const char *s1, const char *s2); +char *strpbrk(const char *s1, const char *s2); +size_t strspn(const char *s1, const char *s2); +void *memmove(void *s1, const void *s2, size_t n); +char *strdup(const char *s); +char *strndup(const char *s, size_t size); +char *strstr(const char *s1, const char *s2); +int strncasecmp(const char *s1, const char *s2, size_t n); +int strcasecmp(const char *s1, const char *s2); +char *strtok(char *restrict s, const char *restrict sep); +char *strcat(char *restrict s1, const char *restrict s2); +#endif diff --git a/userland/libc/include/strings.h b/userland/libc/include/strings.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/sys/ioctl.h b/userland/libc/include/sys/ioctl.h new file mode 100644 index 0000000..a373a4b --- /dev/null +++ b/userland/libc/include/sys/ioctl.h @@ -0,0 +1,10 @@ +#ifndef IOCTL_H +#define IOCTL_H +#define TIOCGWINSZ 0 +struct winsize { + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; +#endif // IOCTL_H diff --git a/userland/libc/include/sys/mman.h b/userland/libc/include/sys/mman.h new file mode 100644 index 0000000..7dfe29a --- /dev/null +++ b/userland/libc/include/sys/mman.h @@ -0,0 +1,15 @@ +#ifndef MMAP_H +#define MMAP_H +#include +#include + +#define PROT_READ (1 << 0) +#define PROT_WRITE (1 << 1) + +#define MAP_PRIVATE (1 << 0) +#define MAP_ANONYMOUS (1<< 1) +#define MAP_SHARED (1<< 2) + +void *mmap(void *addr, size_t length, int prot, int flags, int fd, + size_t offset); +#endif diff --git a/userland/libc/include/sys/mount.h b/userland/libc/include/sys/mount.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/sys/resource.h b/userland/libc/include/sys/resource.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/sys/socket.h b/userland/libc/include/sys/socket.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/sys/stat.h b/userland/libc/include/sys/stat.h new file mode 100644 index 0000000..178d014 --- /dev/null +++ b/userland/libc/include/sys/stat.h @@ -0,0 +1,31 @@ +#ifndef STAT_H +#define STAT_H +#include +#include + +struct stat { + dev_t st_dev; // Device ID of device containing file. + ino_t st_ino; // File serial number. + mode_t st_mode; // Mode of file (see below). + nlink_t st_nlink; // Number of hard links to the file. + uid_t st_uid; // User ID of file. + gid_t st_gid; // Group ID of file. + dev_t st_rdev; // Device ID (if file is character or block special). + off_t st_size; // For regular files, the file size in bytes. + // For symbolic links, the length in bytes of the + // pathname contained in the symbolic link. + // For a shared memory object, the length in bytes. + // For a typed memory object, the length in bytes. + // For other file types, the use of this field is + // unspecified. + struct timespec st_atime; // Last data access timestamp. + struct timespec st_mtime; // Last data modification timestamp. + struct timespec st_ctime; // Last file status change timestamp. + blksize_t st_blksize; // A file system-specific preferred I/O block size + // for this object. In some file system types, this + // may vary from file to file. + blkcnt_t st_blocks; // Number of blocks allocated for this object. +}; +int stat(const char *path, struct stat *buf); +int mkdir(const char *path, mode_t mode); +#endif diff --git a/userland/libc/include/sys/statvfs.h b/userland/libc/include/sys/statvfs.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/sys/syscall.h b/userland/libc/include/sys/syscall.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/sys/time.h b/userland/libc/include/sys/time.h new file mode 100644 index 0000000..a675d9e --- /dev/null +++ b/userland/libc/include/sys/time.h @@ -0,0 +1,41 @@ +#ifndef TIME_H +#define TIME_H +#include +#include +#include + +#define CLOCK_REALTIME 0 + +struct tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + long __tm_gmtoff; + const char *__tm_zone; +}; + +typedef int clockid_t; +struct timespec { + time_t tv_sec; // Seconds. + long tv_nsec; // Nanoseconds. +}; + +struct timeval { + time_t tv_sec; + suseconds_t tv_usec; +}; + +time_t time(time_t *tloc); +int clock_gettime(clockid_t clock_id, struct timespec *tp); +struct tm *localtime(const time_t *timer); +struct tm *gmtime(const time_t *timer); +size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, + const struct tm *restrict timeptr); +int gettimeofday(struct timeval *tp, void *tzp); +#endif diff --git a/userland/libc/include/sys/times.h b/userland/libc/include/sys/times.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/sys/types.h b/userland/libc/include/sys/types.h new file mode 100644 index 0000000..48c57f9 --- /dev/null +++ b/userland/libc/include/sys/types.h @@ -0,0 +1,28 @@ +#ifndef TYPES_H +#define TYPES_H +typedef unsigned int ino_t; + +typedef int mode_t; + +typedef int nlink_t; +typedef int uid_t; +typedef int gid_t; +typedef int id_t; + +typedef int blkcnt_t; +typedef int off_t; + +typedef int dev_t; +typedef unsigned int fsblkcnt_t; +typedef unsigned int fsfilcnt_t; +typedef unsigned int ino_t; +//typedef unsigned int size_t; + +typedef int blksize_t; +typedef int pid_t; +typedef int ssize_t; + +//typedef int clock_t; +typedef int time_t; +typedef unsigned int suseconds_t; +#endif diff --git a/userland/libc/include/sys/ucontext.h b/userland/libc/include/sys/ucontext.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/sys/un.h b/userland/libc/include/sys/un.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/sys/utsname.h b/userland/libc/include/sys/utsname.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/sys/wait.h b/userland/libc/include/sys/wait.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/syscall.h b/userland/libc/include/syscall.h new file mode 100644 index 0000000..caa7779 --- /dev/null +++ b/userland/libc/include/syscall.h @@ -0,0 +1,150 @@ +#ifndef SYSCALL_H +#define SYSCALL_H +#include "socket.h" +#include +#include +#include + +#define SYS_OPEN 0 +#define SYS_READ 1 +#define SYS_WRITE 2 +#define SYS_PREAD 3 +#define SYS_PWRITE 4 +#define SYS_FORK 5 +#define SYS_EXEC 6 +#define SYS_GETPID 7 +#define SYS_EXIT 8 +#define SYS_WAIT 9 +#define SYS_BRK 10 +#define SYS_SBRK 11 +#define SYS_PIPE 12 +#define SYS_DUP2 13 +#define SYS_CLOSE 14 +#define SYS_OPENPTY 15 +#define SYS_POLL 16 +#define SYS_MMAP 17 +#define SYS_ACCEPT 18 +#define SYS_BIND 19 +#define SYS_SOCKET 20 +#define SYS_SHM_OPEN 21 +#define SYS_FTRUNCATE 22 +#define SYS_STAT 23 +#define SYS_MSLEEP 24 +#define SYS_UPTIME 25 + +int syscall(uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx, + uint32_t esi, uint32_t edi); +int s_syscall(int sys); + +extern int errno; +#define RC_ERRNO(_rc) \ + { \ + int c = _rc; \ + if (c < 0) { \ + errno = -(c); \ + return -1; \ + } \ + return c; \ + } + +typedef int mode_t; + +typedef struct SYS_OPEN_PARAMS { + const char *file; + int flags; + int mode; +} __attribute__((packed)) SYS_OPEN_PARAMS; + +typedef struct SYS_PREAD_PARAMS { + int fd; + void *buf; + size_t count; + size_t offset; +} __attribute__((packed)) SYS_PREAD_PARAMS; + +typedef struct SYS_READ_PARAMS { + int fd; + void *buf; + size_t count; +} __attribute__((packed)) SYS_READ_PARAMS; + +typedef struct SYS_PWRITE_PARAMS { + int fd; + const void *buf; + size_t count; + size_t offset; +} __attribute__((packed)) SYS_PWRITE_PARAMS; + +typedef struct SYS_WRITE_PARAMS { + int fd; + const void *buf; + size_t count; +} __attribute__((packed)) SYS_WRITE_PARAMS; + +typedef struct SYS_EXEC_PARAMS { + const char *path; + char **argv; +} __attribute__((packed)) SYS_EXEC_PARAMS; + +typedef struct SYS_DUP2_PARAMS { + int org_fd; + int new_fd; +} __attribute__((packed)) SYS_DUP2_PARAMS; + +typedef struct SYS_OPENPTY_PARAMS { + int *amaster; + int *aslave; + char *name; + /*const struct termios*/ void *termp; + /*const struct winsize*/ void *winp; +} __attribute__((packed)) SYS_OPENPTY_PARAMS; + +typedef struct SYS_POLL_PARAMS { + struct pollfd *fds; + size_t nfds; + int timeout; +} __attribute__((packed)) SYS_POLL_PARAMS; + +typedef struct SYS_MMAP_PARAMS { + void *addr; + size_t length; + int prot; + int flags; + int fd; + size_t offset; +} __attribute__((packed)) SYS_MMAP_PARAMS; + +typedef struct SYS_SOCKET_PARAMS { + int domain; + int type; + int protocol; +} __attribute__((packed)) SYS_SOCKET_PARAMS; + +typedef struct SYS_BIND_PARAMS { + int sockfd; + const struct sockaddr *addr; + socklen_t addrlen; +} __attribute__((packed)) SYS_BIND_PARAMS; + +typedef struct SYS_ACCEPT_PARAMS { + int socket; + struct sockaddr *address; + socklen_t *address_len; +} __attribute__((packed)) SYS_ACCEPT_PARAMS; + +typedef struct SYS_SHM_OPEN_PARAMS { + const char *name; + int oflag; + mode_t mode; +} __attribute__((packed)) SYS_SHM_OPEN_PARAMS; + +typedef struct SYS_FTRUNCATE_PARAMS { + int fildes; + size_t length; +} __attribute__((packed)) SYS_FTRUNCATE_PARAMS; + +typedef struct SYS_STAT_PARAMS { + const char *pathname; + struct stat *statbuf; +} __attribute__((packed)) SYS_STAT_PARAMS; +#endif diff --git a/userland/libc/include/syslog.h b/userland/libc/include/syslog.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/termios.h b/userland/libc/include/termios.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/time.h b/userland/libc/include/time.h new file mode 100644 index 0000000..567e9ef --- /dev/null +++ b/userland/libc/include/time.h @@ -0,0 +1,35 @@ +#ifndef TIME_H +#define TIME_H +#include +#include + +#define CLOCK_REALTIME 0 + +struct tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + long __tm_gmtoff; + const char *__tm_zone; +}; + +typedef int clockid_t; +struct timespec { + time_t tv_sec; // Seconds. + long tv_nsec; // Nanoseconds. +}; + +time_t time(time_t *tloc); +int clock_gettime(clockid_t clock_id, struct timespec *tp); +struct tm *localtime(const time_t *timer); +struct tm *gmtime(const time_t *timer); +size_t strftime(char *restrict s, size_t maxsize, + const char *restrict format, const struct tm *restrict timeptr); +char *ctime_r(const time_t *clock, char *buf); +#endif diff --git a/userland/libc/include/ubsan.h b/userland/libc/include/ubsan.h new file mode 100644 index 0000000..dac5407 --- /dev/null +++ b/userland/libc/include/ubsan.h @@ -0,0 +1,79 @@ +#include + +enum { type_kind_int = 0, type_kind_float = 1, type_unknown = 0xffff }; + +struct type_descriptor { + uint16_t type_kind; + uint16_t type_info; + char type_name[1]; +}; + +struct source_location { + const char *file_name; + union { + unsigned long reported; + struct { + uint32_t line; + uint32_t column; + }; + }; +}; + +struct OverflowData { + struct source_location location; + struct type_descriptor *type; +}; + +struct type_mismatch_data { + struct source_location location; + struct type_descriptor *type; + unsigned long alignment; + unsigned char type_check_kind; +}; + +struct type_mismatch_data_v1 { + struct source_location location; + struct type_descriptor *type; + unsigned char log_alignment; + unsigned char type_check_kind; +}; + +struct type_mismatch_data_common { + struct source_location *location; + struct type_descriptor *type; + unsigned long alignment; + unsigned char type_check_kind; +}; + +struct nonnull_arg_data { + struct source_location location; + struct source_location attr_location; + int arg_index; +}; + +struct OutOfBoundsData { + struct source_location location; + struct type_descriptor *array_type; + struct type_descriptor *index_type; +}; + +struct ShiftOutOfBoundsData { + struct source_location location; + struct type_descriptor *lhs_type; + struct type_descriptor *rhs_type; +}; + +struct unreachable_data { + struct source_location location; +}; + +struct invalid_value_data { + struct source_location location; + struct type_descriptor *type; +}; + +struct alignment_assumption_data { + struct source_location location; + struct source_location assumption_location; + struct type_descriptor *type; +}; diff --git a/userland/libc/include/unistd.h b/userland/libc/include/unistd.h new file mode 100644 index 0000000..e43dc33 --- /dev/null +++ b/userland/libc/include/unistd.h @@ -0,0 +1,24 @@ +#ifndef UNISTD_H +#define UNISTD_H +#include +#include +#include + +#define STDIN_FILENO 0 + +extern int opterr, optind, optopt; +extern char *optarg; + +int close(int fildes); +int ftruncate(int fildes, uint64_t length); +int execv(char *path, char **argv); +int pipe(int fd[2]); +int dup2(int org_fd, int new_fd); +int getopt(int argc, char *const argv[], const char *optstring); +pid_t getpid(void); +int unlink(const char *path); +int execvp(const char *file, char *const argv[]); +void _exit(int status); +void msleep(uint32_t ms); // not standard +uint32_t uptime(void); // not standard +#endif diff --git a/userland/libc/include/utime.h b/userland/libc/include/utime.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/wchar.h b/userland/libc/include/wchar.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/include/wctype.h b/userland/libc/include/wctype.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/input.h b/userland/libc/input.h new file mode 100644 index 0000000..a6602f5 --- /dev/null +++ b/userland/libc/input.h @@ -0,0 +1,9 @@ +#ifndef INPUT_H +#define INPUT_H +#include + +struct input_event { + uint16_t key; + uint8_t status; +}; +#endif diff --git a/userland/libc/inttypes.h b/userland/libc/inttypes.h new file mode 100644 index 0000000..0bf39d1 --- /dev/null +++ b/userland/libc/inttypes.h @@ -0,0 +1,5 @@ +#include + +// FIXME: These are not correct +#define PRId64 "d" +#define PRId32 "d" diff --git a/userland/libc/isspace.c b/userland/libc/isspace.c new file mode 100644 index 0000000..9ba2766 --- /dev/null +++ b/userland/libc/isspace.c @@ -0,0 +1,5 @@ +#include + +int isspace(int c) { + return c == ' ' || (unsigned)c-'\t' < 5; +} diff --git a/userland/libc/libc.c b/userland/libc/libc.c new file mode 100644 index 0000000..259ef0c --- /dev/null +++ b/userland/libc/libc.c @@ -0,0 +1,287 @@ +#include +#include +#include +#include +#include + +int errno; + +char *errno_strings[] = { + "", + "Argument list too long.", + "Permission denied.", + "Address in use.", + "Address not available.", + "Address family not supported.", + "Resource unavailable, try again (may be the same value as [EWOULDBLOCK]).", + "Connection already in progress.", + "Bad file descriptor.", + "Bad message.", + "Device or resource busy.", + "Operation canceled.", + "No child processes.", + "Connection aborted.", + "Connection refused.", + "Connection reset.", + "Resource deadlock would occur.", + "Destination address required.", + "Mathematics argument out of domain of function.", + "Reserved.", + "File exists.", + "Bad address.", + "File too large.", + "Host is unreachable.", + "Identifier removed.", + "Illegal byte sequence.", + "Operation in progress.", + "Interrupted function.", + "Invalid argument.", + "I/O error.", + "Socket is connected.", + "Is a directory.", + "Too many levels of symbolic links.", + "File descriptor value too large.", + "Too many links.", + "Message too large.", + "Reserved.", + "Filename too long.", + "Network is down.", + "Connection aborted by network.", + "Network unreachable.", + "Too many files open in system.", + "No buffer space available.", + "No message is available on the STREAM head read " + "queue. [Option End]", + "No such device.", + "No such file or directory.", + "Executable file format error.", + "No locks available.", + "Reserved.", + "Not enough space.", + "No message of the desired type.", + "Protocol not available.", + "No space left on device.", + "No STREAM resources.", + "Not a STREAM.", + "Functionality not supported.", + "The socket is not connected.", + "Not a directory or a symbolic link to a directory.", + "Directory not empty.", + "State not recoverable.", + "Not a socket.", + "Not supported (may be the same value as [EOPNOTSUPP]).", + "Inappropriate I/O control operation.", + "No such device or address.", + "Operation not supported on socket (may be the same value as [ENOTSUP]).", + "Value too large to be stored in data type.", + "Previous owner died.", + "Operation not permitted.", + "Broken pipe.", + "Protocol error.", + "Protocol not supported.", + "Protocol wrong type for socket.", + "Result too large.", + "Read-only file system.", + "Invalid seek.", + "No such process.", + "Reserved.", + "Stream ioctl() timeout. [Option End]", + "Connection timed out.", + "Text file busy.", + "Operation would block (may be the same value as [EAGAIN]).", + "Cross-device link. ", +}; + +#define ASSERT_NOT_REACHED assert(0) + +#define TAB_SIZE 8 + +// Functions preserve the registers ebx, esi, edi, ebp, and esp; while +// eax, ecx, edx are scratch registers. + +// Syscall: eax ebx ecx edx esi edi +int syscall(uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx, + uint32_t esi, uint32_t edi) { + asm volatile("push %edi\n" + "push %esi\n" + "push %ebx\n" + "mov 0x1C(%ebp), %edi\n" + "mov 0x18(%ebp), %esi\n" + "mov 0x14(%ebp), %edx\n" + "mov 0x10(%ebp), %ecx\n" + "mov 0xc(%ebp), %ebx\n" + "mov 0x8(%ebp), %eax\n" + "int $0x80\n" + "pop %ebx\n" + "pop %esi\n" + "pop %edi\n"); +} + +int pipe(int fd[2]) { return syscall(SYS_PIPE, fd, 0, 0, 0, 0); } + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/strerror.html +char *strerror(int errnum) { + // The strerror() function shall map the error number in errnum to a + // locale-dependent error message string and shall return a pointer to it. + return errno_strings[errnum]; +} + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/perror.html +void perror(const char *s) { + // The perror() function shall map the error number accessed through the + // symbol errno to a language-dependent error message, which shall be written + // to the standard error stream as follows: + + // (First (if s is not a null pointer and the character pointed to + // by s is not the null byte), + if (s && *s != '\0') { + // the string pointed to by s + // followed by a and a . + printf("%s: ", s); + } + + // Then an error message string followed by a . + // The contents of the error message strings shall be the same as those + // returned by strerror() with argument errno. + printf("%s\n", strerror(errno)); +} + +int open(const char *file, int flags, int mode) { + struct SYS_OPEN_PARAMS args = { + .file = file, + .flags = flags, + .mode = mode, + }; + RC_ERRNO(syscall(SYS_OPEN, &args, 0, 0, 0, 0)); +} + +int close(int fd) { return syscall(SYS_CLOSE, (void *)fd, 0, 0, 0, 0); } + +int execv(char *path, char **argv) { + struct SYS_EXEC_PARAMS args = {.path = path, .argv = argv}; + return syscall(SYS_EXEC, &args, 0, 0, 0, 0); +} +/* +int syscall(int sys, void *args) { + asm volatile("push %ebx\n" + "mov 0xc(%ebp), %ebx\n" + "mov 0x8(%ebp), %eax\n" + "int $0x80\n" + "pop %ebx\n"); +}*/ + +int s_syscall(int sys) { + asm volatile("movl %0, %%eax\n" + "int $0x80\n" ::"r"((uint32_t)sys)); +} + +int write(int fd, const char *buf, size_t count) { + /* + struct SYS_WRITE_PARAMS args = { + .fd = fd, + .buf = buf, + .count = count, + };*/ + return syscall(SYS_WRITE, fd, buf, count, 0, 0); +} + +int pwrite(int fd, const char *buf, size_t count, size_t offset) { + struct SYS_PWRITE_PARAMS args = { + .fd = fd, + .buf = buf, + .count = count, + .offset = offset, + }; + return syscall(SYS_PWRITE, &args, 0, 0, 0, 0); +} + +int wait(int *stat_loc) { return syscall(SYS_WAIT, stat_loc, 0, 0, 0, 0); } + +void exit(int status) { syscall(SYS_EXIT, (void *)status, 0, 0, 0, 0); } + +int pread(int fd, void *buf, size_t count, size_t offset) { + struct SYS_PREAD_PARAMS args = { + .fd = fd, + .buf = buf, + .count = count, + .offset = offset, + }; + RC_ERRNO(syscall(SYS_PREAD, &args, 0, 0, 0, 0)); +} + +int read(int fd, void *buf, size_t count) { + struct SYS_READ_PARAMS args = { + .fd = fd, + .buf = buf, + .count = count, + }; + RC_ERRNO(syscall(SYS_READ, &args, 0, 0, 0, 0)); +} + +int dup2(int org_fd, int new_fd) { + struct SYS_DUP2_PARAMS args = { + .org_fd = org_fd, + .new_fd = new_fd, + }; + RC_ERRNO(syscall(SYS_DUP2, &args, 0, 0, 0, 0)); +} + +int fork(void) { return s_syscall(SYS_FORK); } + +void dputc(int fd, const char c) { pwrite(fd, &c, 1, 0); } + +int brk(void *addr) { return syscall(SYS_BRK, addr, 0, 0, 0, 0); } + +void *sbrk(intptr_t increment) { + return (void *)syscall(SYS_SBRK, (void *)increment, 0, 0, 0, 0); +} + +int poll(struct pollfd *fds, size_t nfds, int timeout) { + SYS_POLL_PARAMS args = { + .fds = fds, + .nfds = nfds, + .timeout = timeout, + }; + RC_ERRNO(syscall(SYS_POLL, &args, 0, 0, 0, 0)); +} + +int socket(int domain, int type, int protocol) { + SYS_SOCKET_PARAMS args = { + .domain = domain, + .type = type, + .protocol = protocol, + }; + RC_ERRNO(syscall(SYS_SOCKET, &args, 0, 0, 0, 0)); +} + +int accept(int socket, struct sockaddr *address, socklen_t *address_len) { + SYS_ACCEPT_PARAMS args = { + .socket = socket, + .address = address, + .address_len = address_len, + }; + RC_ERRNO(syscall(SYS_ACCEPT, &args, 0, 0, 0, 0)); +} + +int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { + SYS_BIND_PARAMS args = { + .sockfd = sockfd, + .addr = addr, + .addrlen = addrlen, + }; + RC_ERRNO(syscall(SYS_BIND, &args, 0, 0, 0, 0)); +} + +int shm_open(const char *name, int oflag, mode_t mode) { + SYS_SHM_OPEN_PARAMS args = { + .name = name, + .oflag = oflag, + .mode = mode, + }; + RC_ERRNO(syscall(SYS_SHM_OPEN, &args, 0, 0, 0, 0)); +} + +int ftruncate(int fildes, uint64_t length) { + SYS_FTRUNCATE_PARAMS args = {.fildes = fildes, .length = length}; + RC_ERRNO(syscall(SYS_FTRUNCATE, &args, 0, 0, 0, 0)); +} diff --git a/userland/libc/libgen/basename.c b/userland/libc/libgen/basename.c new file mode 100644 index 0000000..a0a8adb --- /dev/null +++ b/userland/libc/libgen/basename.c @@ -0,0 +1,45 @@ +#include +#include + +/* +The basename() function shall take the pathname pointed to by path and +return a pointer to the final component of the pathname, deleting any +trailing '/' characters. + + +The basename() function may modify the string pointed to by path, and +may return a pointer to internal storage. The returned pointer might be +invalidated or the storage might be overwritten by a subsequent call to +basename(). The returned pointer might also be invalidated if the +calling thread is terminated. +*/ + +char *basename_empty_return_value = "."; +char *basename_slash_return_value = "/"; +char *basename(char *path) { + // If path is a null pointer or points to an empty string, basename() + // shall return a pointer to the string ".". + if (NULL == path || '\0' == *path) + return basename_empty_return_value; + + char *start = path; + // Move the string to the end + for (; *path; path++) + ; + if (start == path) + return start; + path--; + if ('/' == *path) // Trailing slash + *path = '\0'; + // Loop until next slash is found + for (; path != start && '/' != *path; path--) + ; + // If the string pointed to by path consists entirely of the '/' character, + // basename() shall return a pointer to the string "/". If the string + // pointed to by path is exactly "//", it is implementation-defined whether + //'/' or "//" is returned. + path++; + if ('\0' == *path) + return basename_slash_return_value; + return path; +} diff --git a/userland/libc/libgen/dirname.c b/userland/libc/libgen/dirname.c new file mode 100644 index 0000000..fb3c813 --- /dev/null +++ b/userland/libc/libgen/dirname.c @@ -0,0 +1,44 @@ +#include + +char *dirname_empty_return_value = "."; +char *dirname_slash_return_value = "/"; +char *dirname(char *path) { + // If path is a null pointer or points to an empty string, + // dirname() shall return a pointer to the string "." + if (!path) + return dirname_empty_return_value; + if ('\0' == *path) + return dirname_empty_return_value; + + char *start = path; + for (; *path; path++) + ; + path--; + if ('/' == *path) { + if (start == path) + return path; + path--; + } + + for (; path != start && '/' != *path; path--) + ; + // If path does not contain a '/', then dirname() shall return a pointer to + // the string ".". + if ('/' != *path) + return dirname_empty_return_value; + + if (path == start) + return dirname_slash_return_value; + + *path = '\0'; + path--; + + for (; path != start && '/' != *path; path--) + ; + + if ('/' != *path) + return dirname_empty_return_value; + + path++; + return path; +} diff --git a/userland/libc/limits.h b/userland/libc/limits.h new file mode 100644 index 0000000..0c9389a --- /dev/null +++ b/userland/libc/limits.h @@ -0,0 +1,2 @@ +#define PATH_MAX 256 +#define FILENAME_MAX PATH_MAX diff --git a/userland/libc/malloc/malloc.c b/userland/libc/malloc/malloc.c new file mode 100644 index 0000000..f351291 --- /dev/null +++ b/userland/libc/malloc/malloc.c @@ -0,0 +1,232 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define NEW_ALLOC_SIZE 0x20000 +#define MALLOC_HEADER_MAGIC 0x1337F00D +#define MALLOC_HEADER_PAD 0x11223344 + +#define IS_FREE (1 << 0) +#define IS_FINAL (1 << 1) + +typedef struct MallocHeader { + uint32_t magic; + uint32_t size; + uint8_t flags; + struct MallocHeader *n; +} MallocHeader; + +size_t max(size_t a, size_t b) { return (a > b) ? a : b; } + +//;size_t min(size_t a, size_t b) { return (a < b) ? a : b; } + +uint64_t delta_page(uint64_t a) { return 0x1000 - (a % 0x1000); } + +MallocHeader *head = NULL; +MallocHeader *final = NULL; +uint32_t total_heap_size = 0; + +int init_heap(void) { + head = (MallocHeader *)sbrk(NEW_ALLOC_SIZE); + if ((void *)-1 == head) { + perror("sbrk"); + exit(1); + } + total_heap_size += NEW_ALLOC_SIZE - sizeof(MallocHeader); + head->magic = MALLOC_HEADER_MAGIC; + head->size = NEW_ALLOC_SIZE - sizeof(MallocHeader); + head->flags = IS_FREE | IS_FINAL; + head->n = NULL; + final = head; + return 1; +} + +int add_heap_memory(size_t min_desired) { + min_desired += sizeof(MallocHeader) + 0x1000; + size_t allocation_size = max(min_desired, NEW_ALLOC_SIZE); + allocation_size += delta_page(allocation_size); + void *p; + if ((void *)(-1) == (p = (void *)sbrk(allocation_size))) { + perror("sbrk"); + return 0; + } + total_heap_size += allocation_size - sizeof(MallocHeader); + void *e = final; + e = (void *)((uint32_t)e + final->size); + if (p == e) { + final->size += allocation_size - sizeof(MallocHeader); + return 1; + } + MallocHeader *new_entry = p; + new_entry->magic = MALLOC_HEADER_MAGIC; + new_entry->size = allocation_size - sizeof(MallocHeader); + new_entry->flags = IS_FREE | IS_FINAL; + new_entry->n = NULL; + final->n = new_entry; + final = new_entry; + return 1; +} + +MallocHeader *next_header(MallocHeader *a) { return a->n; } + +MallocHeader *next_close_header(MallocHeader *a) { + if (!a) { + printf("next close header fail\n"); + for (;;) + ; + } + if (a->flags & IS_FINAL) + return NULL; + return next_header(a); +} + +MallocHeader *find_free_entry(uint32_t s, int align) { + // A new header is required as well as the newly allocated chunk + if (!head) + init_heap(); + MallocHeader *p = head; + for (; p; p = next_header(p)) { + if (!(p->flags & IS_FREE)) + continue; + uint64_t required_size = s; + if (align) { + void *addy = p; + addy = (void *)((uint32_t)addy + sizeof(MallocHeader)); + uint64_t d = delta_page((uint32_t)addy); + if (d < sizeof(MallocHeader) && d != 0) + continue; + required_size += d; + } + if (p->size < required_size) + continue; + return p; + } + return NULL; +} + +void merge_headers(MallocHeader *b) { + if (!(b->flags & IS_FREE)) + return; + + MallocHeader *n = next_close_header(b); + if (!n) + return; + + if (n > 0xf58c0820 - 0x8 && n < 0xf58c0820 + 0x8) { + printf("b: %x\n", b); + printf("b->n: %x\n", b->n); + asm("hlt"); + assert(0); + } + if (!(n->flags & IS_FREE)) + return; + + // Remove the next header and just increase the newly freed header + b->size += n->size; + b->flags |= n->flags & IS_FINAL; + b->n = n->n; + if (n == final) + final = b; +} + +extern int errno; +// https://pubs.opengroup.org/onlinepubs/9699919799/ +void *int_malloc(size_t s, int align) { + if (!head) + init_heap(); + size_t n = s; + MallocHeader *free_entry = find_free_entry(s, align); + if (!free_entry) { + if (!add_heap_memory(s)) { + errno = ENOMEM; + printf("ENOMEM\n"); + return NULL; + } + return int_malloc(s, align); + } + + void *rc = (void *)((uint32_t)free_entry + sizeof(MallocHeader)); + + if (align) { + uint64_t d = delta_page((uint32_t)rc); + n = d; + n -= sizeof(MallocHeader); + } + + // Create a new header + MallocHeader *new_entry = + (MallocHeader *)((uint32_t)free_entry + n + sizeof(MallocHeader)); + new_entry->magic = MALLOC_HEADER_MAGIC; + new_entry->flags = free_entry->flags; + new_entry->n = free_entry->n; + new_entry->size = free_entry->size - n - sizeof(MallocHeader); + if (free_entry == final) + final = new_entry; + merge_headers(new_entry); + + // Modify the free entry + free_entry->size = n; + free_entry->flags = 0; + free_entry->n = new_entry; + + if (align && ((uint32_t)rc % 0x1000) != 0) { + void *c = int_malloc(s, 1); + free(rc); + rc = c; + return rc; + } + return rc; +} + +void *malloc(size_t s) { return int_malloc(s + 1, 0); } + +// https://pubs.opengroup.org/onlinepubs/9699919799/ +void *calloc(size_t nelem, size_t elsize) { + // The calloc() function shall allocate unused space for an array of + // nelem elements each of whose size in bytes is elsize. + size_t alloc_size = nelem * elsize; + void *rc = malloc(alloc_size); + // The space shall be initialized to all bits 0. + memset(rc, 0, alloc_size); + return rc; +} + +size_t get_mem_size(void *ptr) { + if (!ptr) + return 0; + return ((MallocHeader *)(ptr - sizeof(MallocHeader)))->size; +} + +void *realloc(void *ptr, size_t size) { + void *rc = malloc(size); + if (!rc) + return NULL; + size_t l = get_mem_size(ptr); + size_t to_copy = min(l, size); + memcpy(rc, ptr, to_copy); + free(ptr); + return rc; +} + +void free(void *p) { + if (!p) + return; + // FIXME: This assumes that p is at the start of a allocated area. + // Is this a assumption that can be made? + MallocHeader *h = (MallocHeader *)((uint32_t)p - sizeof(MallocHeader)); + if (MALLOC_HEADER_MAGIC != h->magic) { + printf("h->magic: %x\n", h->magic); + printf("&h->magic: %x\n", &(h->magic)); + assert(0); + } + if (h->flags & IS_FREE) + return; + + h->flags |= IS_FREE; + merge_headers(h); +} diff --git a/userland/libc/malloc/malloc.h b/userland/libc/malloc/malloc.h new file mode 100644 index 0000000..082d8ad --- /dev/null +++ b/userland/libc/malloc/malloc.h @@ -0,0 +1,9 @@ +#ifndef MALLOC_H +#define MALLOC_H +#include +#include + +void *malloc(size_t s); +void *calloc(size_t nelem, size_t elsize); +void free(void *p); +#endif diff --git a/userland/libc/malloc/oldmalloc.c b/userland/libc/malloc/oldmalloc.c new file mode 100644 index 0000000..042049d --- /dev/null +++ b/userland/libc/malloc/oldmalloc.c @@ -0,0 +1,136 @@ +#include "stdio.h" +#include "stdlib.h" +#include "../errno.h" +#include +#include +#include + +#define NEW_ALLOC_SIZE 0x1000 + +#define IS_FREE (1 << 0) +#define IS_FINAL (1 << 1) + +typedef struct MallocHeader { + uint32_t size; + uint8_t flags; +} MallocHeader; + +MallocHeader *head = NULL; +MallocHeader *final = NULL; +uint32_t total_heap_size = 0; + +int init_heap(void) { + head = sbrk(NEW_ALLOC_SIZE); + if ((void *)-1 == head) { + // perror("sbrk"); + return 0; + } + total_heap_size += NEW_ALLOC_SIZE; + head->size = NEW_ALLOC_SIZE; + head->flags = IS_FREE | IS_FINAL; + final = head; + return 1; +} + +int add_heap_memory(void) { + if ((void *)-1 == sbrk(NEW_ALLOC_SIZE)) { + // perror("sbrk"); + return 0; + } + total_heap_size += NEW_ALLOC_SIZE; + final->size += NEW_ALLOC_SIZE; + return 1; +} + +MallocHeader *next_header(MallocHeader *a) { + if (a->flags & IS_FINAL) + return NULL; + return ((void *)a) + a->size; +} + +MallocHeader *find_free_entry(uint32_t s) { + // A new header is required as well as the newly allocated chunk + s += sizeof(MallocHeader); + if (!head) + init_heap(); + MallocHeader *p = head; + for (; p; p = next_header(p)) { + if (!(p->flags & IS_FREE)) + continue; + if (p->size < s) + continue; + return p; + } + return NULL; +} + +void merge_headers(MallocHeader *b) { + if (!(b->flags & IS_FREE)) + return; + + MallocHeader *n = next_header(b); + if (!n) + return; + + if (!(n->flags & IS_FREE)) + return; + + // Remove the next header and just increase the newly freed header + b->size += n->size; + b->flags |= n->flags & IS_FINAL; + if (b->flags & IS_FINAL) + final = b; +} + +extern int errno; +// https://pubs.opengroup.org/onlinepubs/9699919799/ +void *malloc(size_t s) { + if(s == 0) + s = 1; + + MallocHeader *free_entry = find_free_entry(s); + if (!free_entry) { + if (!add_heap_memory()) { + errno = ENOMEM; + return NULL; + } + return malloc(s); + } + + // Create a new header + MallocHeader *new_entry = ((void *)free_entry) + s; + new_entry->flags |= IS_FREE; + new_entry->size = free_entry->size - s - sizeof(MallocHeader); + new_entry->flags |= free_entry->flags & IS_FINAL; + if (new_entry->flags & IS_FINAL) + final = new_entry; + merge_headers(new_entry); + + // Modify the free entry + free_entry->size = s; + free_entry->flags = 0; + + return ((void *)free_entry) + sizeof(MallocHeader); +} + +// https://pubs.opengroup.org/onlinepubs/9699919799/ +void *calloc(size_t nelem, size_t elsize) { + // The calloc() function shall allocate unused space for an array of + // nelem elements each of whose size in bytes is elsize. + size_t alloc_size = nelem*elsize; + void *rc = malloc(alloc_size); + // The space shall be initialized to all bits 0. + memset(rc, 0, alloc_size); + return rc; +} + +void free(void *p) { + // FIXME: This assumes that p is at the start of a allocated area. + // Is this a assumption that can be made? + MallocHeader *h = p - sizeof(MallocHeader); + if (h->flags & IS_FREE) + return; + + h->flags |= IS_FREE; + merge_headers(h); +} diff --git a/userland/libc/math.h b/userland/libc/math.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/memset.c b/userland/libc/memset.c new file mode 100644 index 0000000..51910e9 --- /dev/null +++ b/userland/libc/memset.c @@ -0,0 +1,15 @@ +#include + +// https://pubs.opengroup.org/onlinepubs/9699919799/ +void *memset(void *s, int c, size_t n) { + // The memset() function shall copy c (converted to an unsigned + // char) into each of the first n bytes of the object pointed to by + // s. + + unsigned char *p = s; + for (; n > 0; n--, p++) + *p = (unsigned char)c; + + // The memset() function shall return s + return s; +} diff --git a/userland/libc/mmap.c b/userland/libc/mmap.c new file mode 100644 index 0000000..06b79bd --- /dev/null +++ b/userland/libc/mmap.c @@ -0,0 +1,19 @@ +#include +#include +#include + +extern int errno; + +void *mmap(void *addr, size_t length, int prot, int flags, int fd, + size_t offset) { + SYS_MMAP_PARAMS args = { + .addr = addr, + .length = length, + .prot = prot, + .flags = flags, + .fd = fd, + .offset = offset, + }; +// return (void*)syscall(SYS_MMAP, &args); + RC_ERRNO(syscall(SYS_MMAP, &args)); +} diff --git a/userland/libc/poll.h b/userland/libc/poll.h new file mode 100644 index 0000000..88e98b3 --- /dev/null +++ b/userland/libc/poll.h @@ -0,0 +1,16 @@ +#ifndef POLL_H +#define POLL_H +#include + +#define POLLIN (1 << 0) +#define POLLPRI (1 << 1) +#define POLLOUT (1 << 2) + +struct pollfd { + int fd; + short events; + short revents; +}; + +int poll(struct pollfd *fds, size_t nfds, int timeout); +#endif diff --git a/userland/libc/pty.c b/userland/libc/pty.c new file mode 100644 index 0000000..b7ddf00 --- /dev/null +++ b/userland/libc/pty.c @@ -0,0 +1,15 @@ +#include "pty.h" +#include "syscall.h" + +int openpty(int *amaster, int *aslave, char *name, + /*const struct termios*/ void *termp, + /*const struct winsize*/ void *winp) { + SYS_OPENPTY_PARAMS args = { + .amaster = amaster, + .aslave = aslave, + .name = name, + .termp = termp, + .winp = winp, + }; + syscall(SYS_OPENPTY, &args, 0, 0, 0, 0); +} diff --git a/userland/libc/pty.h b/userland/libc/pty.h new file mode 100644 index 0000000..b8ce978 --- /dev/null +++ b/userland/libc/pty.h @@ -0,0 +1,6 @@ +#ifndef PTY_H +#define PTY_H +int openpty(int *amaster, int *aslave, char *name, + /*const struct termios*/ void *termp, + /*const struct winsize*/ void *winp); +#endif diff --git a/userland/libc/setjmp/longjmp.s b/userland/libc/setjmp/longjmp.s new file mode 100644 index 0000000..8188f06 --- /dev/null +++ b/userland/libc/setjmp/longjmp.s @@ -0,0 +1,16 @@ +.global _longjmp +.global longjmp +.type _longjmp,@function +.type longjmp,@function +_longjmp: +longjmp: + mov 4(%esp),%edx + mov 8(%esp),%eax + cmp $1,%eax + adc $0, %al + mov (%edx),%ebx + mov 4(%edx),%esi + mov 8(%edx),%edi + mov 12(%edx),%ebp + mov 16(%edx),%esp + jmp *20(%edx) diff --git a/userland/libc/setjmp/setjmp.s b/userland/libc/setjmp/setjmp.s new file mode 100644 index 0000000..4d19cf8 --- /dev/null +++ b/userland/libc/setjmp/setjmp.s @@ -0,0 +1,23 @@ +.global ___setjmp +.hidden ___setjmp +.global __setjmp +.global _setjmp +.global setjmp +.type __setjmp,@function +.type _setjmp,@function +.type setjmp,@function +___setjmp: +__setjmp: +_setjmp: +setjmp: + mov 4(%esp), %eax + mov %ebx, (%eax) + mov %esi, 4(%eax) + mov %edi, 8(%eax) + mov %ebp, 12(%eax) + lea 4(%esp), %ecx + mov %ecx, 16(%eax) + mov (%esp), %ecx + mov %ecx, 20(%eax) + xor %eax, %eax + ret diff --git a/userland/libc/socket.h b/userland/libc/socket.h new file mode 100644 index 0000000..5e86b45 --- /dev/null +++ b/userland/libc/socket.h @@ -0,0 +1,41 @@ +#include +#include + +#define AF_UNIX 0 +#define AF_LOCAL AF_UNIX + +#define INADDR_ANY 0 + +typedef struct { + int domain; + int type; + int protocol; + + // UNIX socket + char *path; + int incoming_fd; +} SOCKET; + +typedef struct { + char *path; + SOCKET *s; +} OPEN_UNIX_SOCKET; + +typedef uint32_t in_addr_t; +typedef uint16_t in_port_t; +typedef unsigned int sa_family_t; +typedef uint32_t socklen_t; + +struct sockaddr { + sa_family_t sa_family; /* Address family */ + char *sa_data; /* Socket address */ +}; + +struct sockaddr_un { + sa_family_t sun_family; /* Address family */ + char *sun_path; /* Socket pathname */ +}; + +int socket(int domain, int type, int protocol); +int accept(int socket, struct sockaddr *address, socklen_t *address_len); +int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); diff --git a/userland/libc/stdio.h b/userland/libc/stdio.h new file mode 100644 index 0000000..38aaf22 --- /dev/null +++ b/userland/libc/stdio.h @@ -0,0 +1,95 @@ +#ifndef STDIO_H +#define STDIO_H +#include +#include +#include + +// FIXME: Most of these should probably not be here. But I am too lazy +// to fix it right now. This is futures mees problem to deal wth. + +#define EOF (-1) + +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 + +typedef struct __IO_FILE FILE; +struct __IO_FILE { + size_t (*write)(FILE *, const unsigned char *, size_t); + size_t (*read)(FILE *, unsigned char *, size_t); + int (*seek)(FILE *, long, int); + long offset_in_file; + int buffered_char; + int has_buffered_char; + uint8_t is_eof; + uint8_t has_error; + uint64_t file_size; + void *cookie; +}; + +size_t write_fd(FILE *f, const unsigned char *s, size_t l); +size_t read_fd(FILE *f, unsigned char *s, size_t l); +int seek_fd(FILE *stream, long offset, int whence); + +typedef struct { + int fd; +} FILE_FD_COOKIE; + +extern FILE __stdin_FILE; +extern FILE __stdout_FILE; +extern FILE __stderr_FILE; + +#define stdin (&__stdin_FILE) +#define stdout (&__stdout_FILE) +//#define stderr (&__stderr_FILE) +#define stderr (&__stdout_FILE) + +typedef int mode_t; + +void perror(const char *s); + +int putchar(int c); +int puts(const char *s); +int brk(void *addr); +void *sbrk(intptr_t increment); +int write(int fd, const char *buf, size_t count); +int pwrite(int fd, const char *buf, size_t count, size_t offset); +int printf(const char *format, ...); +int pread(int fd, void *buf, size_t count, size_t offset); +int read(int fd, void *buf, size_t count); +int fork(void); +int memcmp(const void *s1, const void *s2, size_t n); +int wait(int *stat_loc); +void exit(int status); +void *memcpy(void *dest, const void *src, uint32_t n); +int shm_open(const char *name, int oflag, mode_t mode); +int dprintf(int fd, const char *format, ...); +int vdprintf(int fd, const char *format, va_list ap); +int vprintf(const char *format, va_list ap); +int snprintf(char *str, size_t size, const char *format, ...); +int vsnprintf(char *str, size_t size, const char *format, va_list ap); +int vfprintf(FILE *f, const char *fmt, va_list ap); +int fgetc(FILE *stream); +int getchar(void); +#define getc(_a) fgetc(_a) +size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); +size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); +FILE *fopen(const char *pathname, const char *mode); +int fclose(FILE *stream); +int fseek(FILE *stream, long offset, int whence); +int fprintf(FILE *f, const char *fmt, ...); +long strtol(const char *nptr, char **endptr, int base); +char *strchr(const char *s, int c); +char *strcat(char *s1, const char *s2); +char *fgets(char *s, int n, FILE *stream); +FILE *tmpfile(void); +int feof(FILE *stream); +int fscanf(FILE *stream, const char *format, ...); +int ungetc(int c, FILE *stream); +long ftell(FILE *stream); +int fputc(int c, FILE *stream); +int remove(const char *path); +int ferror(FILE *stream); +int fputs(const char *s, FILE *stream); +int fflush(FILE *stream); +#endif diff --git a/userland/libc/stdio/dprintf.c b/userland/libc/stdio/dprintf.c new file mode 100644 index 0000000..2f2aadb --- /dev/null +++ b/userland/libc/stdio/dprintf.c @@ -0,0 +1,9 @@ +#include + +int dprintf(int fd, const char *format, ...) { + va_list ap; + va_start(ap, format); + int rc = vdprintf(fd, format, ap); + va_end(ap); + return rc; +} diff --git a/userland/libc/stdio/fclose.c b/userland/libc/stdio/fclose.c new file mode 100644 index 0000000..02d93ae --- /dev/null +++ b/userland/libc/stdio/fclose.c @@ -0,0 +1,10 @@ +#include +#include + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/fclose.html +// FIXME: Do some actual error checking. +int fclose(FILE *stream) { + free(stream->cookie); + free(stream); + return 0; +} diff --git a/userland/libc/stdio/feof.c b/userland/libc/stdio/feof.c new file mode 100644 index 0000000..7f46301 --- /dev/null +++ b/userland/libc/stdio/feof.c @@ -0,0 +1,5 @@ +#include + +int feof(FILE *stream) { + return stream->is_eof; +} diff --git a/userland/libc/stdio/ferror.c b/userland/libc/stdio/ferror.c new file mode 100644 index 0000000..8cb46cf --- /dev/null +++ b/userland/libc/stdio/ferror.c @@ -0,0 +1,5 @@ +#include + +int ferror(FILE *stream) { + return stream->has_error; +} diff --git a/userland/libc/stdio/fflush.c b/userland/libc/stdio/fflush.c new file mode 100644 index 0000000..7a37c79 --- /dev/null +++ b/userland/libc/stdio/fflush.c @@ -0,0 +1,7 @@ +#include + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/fflush.html +int fflush(FILE *stream) { + // FIXME: Implement + return 0; +} diff --git a/userland/libc/stdio/fgetc.c b/userland/libc/stdio/fgetc.c new file mode 100644 index 0000000..c69211f --- /dev/null +++ b/userland/libc/stdio/fgetc.c @@ -0,0 +1,20 @@ +#include +#include + +int fgetc(FILE *stream) { + if (stream->has_buffered_char) { + stream->has_buffered_char = 0; + return stream->buffered_char; + } + char c; + if (1 == fread(&c, 1, 1, stream)) + return (int)c; + // FIXME: Should use feof and ferror + if (stream->has_error) + return EOF; + if (stream->is_eof) + return EOF; + // How did we get here? + assert(0); + return EOF; +} diff --git a/userland/libc/stdio/fgetpos.c b/userland/libc/stdio/fgetpos.c new file mode 100644 index 0000000..7f34d6a --- /dev/null +++ b/userland/libc/stdio/fgetpos.c @@ -0,0 +1,7 @@ +#include + +// FIXME: Error handling +int fgetpos(FILE *restrict stream, fpos_t *restrict pos) { + *pos = (fpos_t)stream->offset_in_file; + return 0; +} diff --git a/userland/libc/stdio/fgets.c b/userland/libc/stdio/fgets.c new file mode 100644 index 0000000..8e21501 --- /dev/null +++ b/userland/libc/stdio/fgets.c @@ -0,0 +1,16 @@ +#include + +char *fgets(char *s, int n, FILE *stream) { + for (int i = 0; i < n; i++) { + char c; + fread(&c, 1, 1, stream); + if (stream->has_error) + return NULL; + if (stream->is_eof) + return NULL; + s[i] = c; + if (c == '\n') + break; + } + return s; +} diff --git a/userland/libc/stdio/fileno.c b/userland/libc/stdio/fileno.c new file mode 100644 index 0000000..246cc51 --- /dev/null +++ b/userland/libc/stdio/fileno.c @@ -0,0 +1,13 @@ +#include +#include + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/fileno.html +// The fileno() function shall return the integer file descriptor associated +// with the stream pointed to by stream. +int fileno(FILE *stream) { + if (-1 == stream->fd) { + errno = EBADF; + return -1; + } + return stream->fd; +} diff --git a/userland/libc/stdio/fopen.c b/userland/libc/stdio/fopen.c new file mode 100644 index 0000000..a29c7ef --- /dev/null +++ b/userland/libc/stdio/fopen.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include + +// FIXME: All modes not implemented +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html +FILE *fopen(const char *pathname, const char *mode) { + uint8_t read = 0; + uint8_t write = 0; + uint8_t append = 0; + // FIXME: Not parsed correctly + for (; *mode; mode++) { + // r or rb + // Open file for reading. + // w or wb + // Truncate to zero length or create file for writing. + // a or ab + // Append; open or create file for writing at + // end-of-file. + switch (*mode) { + case 'r': + read = 1; + break; + case 'w': + write = 1; + break; + case 'a': + append = 1; + break; + } + } + int flag = 0; + if (read) + flag |= O_READ; + if (write) + flag |= O_WRITE; + + int fd = open(pathname, flag, 0); + if (-1 == fd) + return NULL; + + struct stat s; + stat(pathname, &s); + + FILE *r = malloc(sizeof(FILE)); + r->read = read_fd; + r->write = write_fd; + r->seek = seek_fd; + r->has_error = 0; + r->is_eof = 0; + r->offset_in_file = 0; + r->file_size = s.st_size; + r->cookie = NULL; + r->fd = fd; + return r; +} diff --git a/userland/libc/stdio/fprintf.c b/userland/libc/stdio/fprintf.c new file mode 100644 index 0000000..f983065 --- /dev/null +++ b/userland/libc/stdio/fprintf.c @@ -0,0 +1,9 @@ +#include + +int fprintf(FILE *f, const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + int rc = vfprintf(f, fmt, ap); + va_end(ap); + return rc; +} diff --git a/userland/libc/stdio/fputc.c b/userland/libc/stdio/fputc.c new file mode 100644 index 0000000..7c8fa7c --- /dev/null +++ b/userland/libc/stdio/fputc.c @@ -0,0 +1,7 @@ +#include + +int fputc(int c, FILE *stream) { + if (fwrite(&c, 1, 1, stream) > 0) + return c; + return EOF; +} diff --git a/userland/libc/stdio/fputs.c b/userland/libc/stdio/fputs.c new file mode 100644 index 0000000..1b70c66 --- /dev/null +++ b/userland/libc/stdio/fputs.c @@ -0,0 +1,9 @@ +#include + +int fputs(const char *s, FILE *stream) { + const char *b = s; + for (; *s; s++) + if (0 == fwrite(s, 1, 1, stream)) + return EOF; + return s - b; +} diff --git a/userland/libc/stdio/fread.c b/userland/libc/stdio/fread.c new file mode 100644 index 0000000..1a27afa --- /dev/null +++ b/userland/libc/stdio/fread.c @@ -0,0 +1,11 @@ +#include +#include + +size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) { + // FIXME: Check for overflow + ssize_t bytes_to_read = nmemb * size; + size_t rc = stream->read(stream, ptr, bytes_to_read); + // On success, fread() return the number of items read + rc /= size; + return rc; +} diff --git a/userland/libc/stdio/fscanf.c b/userland/libc/stdio/fscanf.c new file mode 100644 index 0000000..785ce4b --- /dev/null +++ b/userland/libc/stdio/fscanf.c @@ -0,0 +1,7 @@ +#include +#include + +int fscanf(FILE *stream, const char *format, ...) { + // FIXME + assert(0); +} diff --git a/userland/libc/stdio/fseek.c b/userland/libc/stdio/fseek.c new file mode 100644 index 0000000..fb891ec --- /dev/null +++ b/userland/libc/stdio/fseek.c @@ -0,0 +1,21 @@ +#include +#include + +int fseek(FILE *stream, long offset, int whence) { + return stream->seek(stream, offset, whence); + /* + switch (whence) { + case SEEK_SET: + stream->offset_in_file = offset; + break; + case SEEK_CUR: + stream->offset_in_file += offset; + break; + case SEEK_END: + // FIXME + assert(0); + break; + } + // FIXME: Error checking + return 0;*/ +} diff --git a/userland/libc/stdio/fsetpos.c b/userland/libc/stdio/fsetpos.c new file mode 100644 index 0000000..c39c545 --- /dev/null +++ b/userland/libc/stdio/fsetpos.c @@ -0,0 +1,7 @@ +#include + +// FIXME: Error handling +int fsetpos(FILE *stream, const fpos_t *pos) { + stream->offset_in_file = (long)(*pos); + return 0; +} diff --git a/userland/libc/stdio/ftell.c b/userland/libc/stdio/ftell.c new file mode 100644 index 0000000..35076d0 --- /dev/null +++ b/userland/libc/stdio/ftell.c @@ -0,0 +1,5 @@ +#include + +long ftell(FILE *stream) { + return stream->offset_in_file; +} diff --git a/userland/libc/stdio/fwrite.c b/userland/libc/stdio/fwrite.c new file mode 100644 index 0000000..552bbd6 --- /dev/null +++ b/userland/libc/stdio/fwrite.c @@ -0,0 +1,12 @@ +#include +#include + +size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) { + // FIXME: Check for overflow + ssize_t bytes_to_write = nmemb * size; + size_t rc = stream->write(stream, ptr, bytes_to_write); + // On success, fwrite() return the number of items + // written. + rc /= size; + return rc; +} diff --git a/userland/libc/stdio/getchar.c b/userland/libc/stdio/getchar.c new file mode 100644 index 0000000..dad2263 --- /dev/null +++ b/userland/libc/stdio/getchar.c @@ -0,0 +1,4 @@ +#include + +// The getchar() function shall be equivalent to getc(stdin). +int getchar(void) { return fgetc(stdin); } diff --git a/userland/libc/stdio/open_memstream.c b/userland/libc/stdio/open_memstream.c new file mode 100644 index 0000000..8f359b9 --- /dev/null +++ b/userland/libc/stdio/open_memstream.c @@ -0,0 +1,108 @@ +#include +#include +#include +#include +/* +struct __IO_FILE { + size_t (*write)(FILE *, const unsigned char *, size_t); + size_t (*read)(FILE *, unsigned char *, size_t); + int (*seek)(FILE *, long, int); + long offset_in_file; + int buffered_char; + int has_buffered_char; + int fd; + uint8_t is_eof; + uint8_t has_error; + uint64_t file_size; + void *cookie; +}; +*/ + +struct Memstream { + size_t buffer_usage; + char *buffer; +}; + +#define MEMSTREAM_DEF_SIZE 4096 + +size_t memstream_write(FILE *fp, const unsigned char *buf, size_t n) { + struct Memstream *c = fp->cookie; + // FIXME: Do a reallocation + if (c->buffer_usage + n >= fp->file_size) { + n = fp->file_size - c->buffer_usage; + } + + memcpy(c->buffer + fp->offset_in_file, buf, n); + fp->offset_in_file += n; + if (fp->offset_in_file > c->buffer_usage) + c->buffer_usage = fp->offset_in_file; + return n; +} + +size_t memstream_read(FILE *fp, unsigned char *buf, size_t n) { + struct Memstream *c = fp->cookie; + size_t length_left = c->buffer_usage - fp->offset_in_file; + n = min(length_left, n); + memcpy(buf, c->buffer + fp->offset_in_file, n); + fp->offset_in_file += n; + if (0 == n) + fp->is_eof = 1; + return n; +} + +int memstream_seek(FILE *stream, long offset, int whence) { + switch (whence) { + case SEEK_SET: + stream->offset_in_file = offset; + break; + case SEEK_CUR: + stream->offset_in_file += offset; + break; + case SEEK_END: + stream->offset_in_file = stream->file_size + offset; + break; + default: + assert(0); + break; + } + // FIXME: Error checking + return 0; +} + +FILE *open_memstream(char **bufp, size_t *sizep) { + struct Memstream *c = NULL; + FILE *fp = malloc(sizeof(FILE)); + if (!fp) + return NULL; + + fp->offset_in_file = 0; + fp->buffered_char = 0; + fp->has_buffered_char = 0; + fp->seek = memstream_seek; + fp->fd = -1; + fp->is_eof = 0; + fp->has_error = 0; + fp->file_size = MEMSTREAM_DEF_SIZE; + + fp->write = memstream_write; + fp->read = memstream_read; + + c = malloc(sizeof(struct Memstream)); + if (!c) { + goto _exit_memstream_fail; + } + + fp->cookie = (void *)c; + + c->buffer = *bufp = malloc(MEMSTREAM_DEF_SIZE); + if (!bufp) { + goto _exit_memstream_fail; + } + c->buffer_usage = 0; + + return fp; +_exit_memstream_fail: + free(c); + free(fp); + return NULL; +} diff --git a/userland/libc/stdio/printf.c b/userland/libc/stdio/printf.c new file mode 100644 index 0000000..d26568a --- /dev/null +++ b/userland/libc/stdio/printf.c @@ -0,0 +1,9 @@ +#include + +int printf(const char *format, ...) { + va_list ap; + va_start(ap, format); + int rc = vprintf(format, ap); + va_end(ap); + return rc; +} diff --git a/userland/libc/stdio/putc.c b/userland/libc/stdio/putc.c new file mode 100644 index 0000000..a468a95 --- /dev/null +++ b/userland/libc/stdio/putc.c @@ -0,0 +1,3 @@ +#include + +int putc(int c, FILE *stream) { return fputc(c, stream);} diff --git a/userland/libc/stdio/putchar.c b/userland/libc/stdio/putchar.c new file mode 100644 index 0000000..3fcf7ca --- /dev/null +++ b/userland/libc/stdio/putchar.c @@ -0,0 +1,7 @@ +#include +#include + +int putchar(int c) { + printf("%c", (char)c); + return c; +} diff --git a/userland/libc/stdio/puts.c b/userland/libc/stdio/puts.c new file mode 100644 index 0000000..4a72e66 --- /dev/null +++ b/userland/libc/stdio/puts.c @@ -0,0 +1,6 @@ +#include + +int puts(const char *s) { + int rc = printf("%s\n", s); + return rc; +} diff --git a/userland/libc/stdio/remove.c b/userland/libc/stdio/remove.c new file mode 100644 index 0000000..35b41ad --- /dev/null +++ b/userland/libc/stdio/remove.c @@ -0,0 +1,9 @@ +#include +#include + +extern int errno; +int remove(const char *path) { + // FIXME + errno = ENAMETOOLONG; + return -1; +} diff --git a/userland/libc/stdio/rename.c b/userland/libc/stdio/rename.c new file mode 100644 index 0000000..15d4bf5 --- /dev/null +++ b/userland/libc/stdio/rename.c @@ -0,0 +1,8 @@ +#include +#include + +int rename(const char *old, const char *new) { + (void)old; + (void)new; + assert(0); // TODO: Implement + } diff --git a/userland/libc/stdio/setvbuf.c b/userland/libc/stdio/setvbuf.c new file mode 100644 index 0000000..7f91518 --- /dev/null +++ b/userland/libc/stdio/setvbuf.c @@ -0,0 +1,6 @@ +#include + +int setvbuf(FILE *restrict stream, char *restrict buf, int type, size_t size) { + // TODO + return 0; +} diff --git a/userland/libc/stdio/snprintf.c b/userland/libc/stdio/snprintf.c new file mode 100644 index 0000000..328442a --- /dev/null +++ b/userland/libc/stdio/snprintf.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include + +struct sn_cookie { + char *s; + size_t n; +}; + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +size_t sn_write(FILE *f, const unsigned char *s, const size_t l) { + struct sn_cookie *c = f->cookie; + size_t k = MIN(l, c->n); + memcpy(c->s, s, k); + c->s += k; + c->n -= k; + *(c->s) = '\0'; + // Upon successful completion, the snprintf() function shall return the number + // of bytes that would be written to s had n been sufficiently large excluding + // the terminating null byte. + return l; +} + +int vsnprintf(char *str, size_t size, const char *format, va_list ap) { + char dummy[1]; + struct sn_cookie c = {.s = (size ? str : dummy), .n = (size ? size - 1 : 0)}; + FILE f = { + .write = sn_write, + .cookie = &c, + }; + return vfprintf(&f, format, ap); +} + +int snprintf(char *str, size_t size, const char *format, ...) { + va_list ap; + va_start(ap, format); + int rc = vsnprintf(str, size, format, ap); + va_end(ap); + return rc; +} diff --git a/userland/libc/stdio/sprintf.c b/userland/libc/stdio/sprintf.c new file mode 100644 index 0000000..deffbbe --- /dev/null +++ b/userland/libc/stdio/sprintf.c @@ -0,0 +1,33 @@ +#include +#include +#include +#include + +struct s_cookie { + char *s; +}; + +size_t s_write(FILE *f, const unsigned char *s, size_t l) { + struct s_cookie *c = f->cookie; + memcpy(c->s, s, l); + c->s += l; + *(c->s) = '\0'; + return l; +} + +int vsprintf(char *str, const char *format, va_list ap) { + struct s_cookie c = {.s = str}; + FILE f = { + .write = s_write, + .cookie = &c, + }; + return vfprintf(&f, format, ap); +} + +int sprintf(char *str, const char *format, ...) { + va_list ap; + va_start(ap, format); + int rc = vsprintf(str, format, ap); + va_end(ap); + return rc; +} diff --git a/userland/libc/stdio/stderr.c b/userland/libc/stdio/stderr.c new file mode 100644 index 0000000..76597e2 --- /dev/null +++ b/userland/libc/stdio/stderr.c @@ -0,0 +1,11 @@ +#include +#include + +FILE __stderr_FILE = { + .write = write_fd, + .read = read_fd, + .is_eof = 0, + .has_error = 0, + .cookie = NULL, + .fd = 2, +}; diff --git a/userland/libc/stdio/stdin.c b/userland/libc/stdio/stdin.c new file mode 100644 index 0000000..ae3ab8d --- /dev/null +++ b/userland/libc/stdio/stdin.c @@ -0,0 +1,54 @@ +#include +#include +#include + +size_t write_fd(FILE *f, const unsigned char *s, size_t l) { + int rc = pwrite(f->fd, s, l, f->offset_in_file); + if (rc == -1) { + f->has_error = 1; + return 0; + } + f->offset_in_file += rc; + return rc; +} + +size_t read_fd(FILE *f, unsigned char *s, size_t l) { + int rc = pread(f->fd, s, l, f->offset_in_file); + if (rc == 0) + f->is_eof = 1; + if (rc == -1) { + f->has_error = 1; + return 0; + } + f->offset_in_file += rc; + return rc; +} + +int seek_fd(FILE *stream, long offset, int whence) { + switch (whence) { + case SEEK_SET: + stream->offset_in_file = offset; + break; + case SEEK_CUR: + stream->offset_in_file += offset; + break; + case SEEK_END: + stream->offset_in_file = stream->file_size + offset; + break; + default: + assert(0); + break; + } + // FIXME: Error checking + return 0; +} + +FILE __stdin_FILE = { + .write = write_fd, + .read = read_fd, + .seek = NULL, + .is_eof = 0, + .has_error = 0, + .cookie = NULL, + .fd = 0, +}; diff --git a/userland/libc/stdio/stdout.c b/userland/libc/stdio/stdout.c new file mode 100644 index 0000000..7f4edf0 --- /dev/null +++ b/userland/libc/stdio/stdout.c @@ -0,0 +1,13 @@ +#include +#include + +FILE __stdout_FILE = { + .write = write_fd, + .read = read_fd, + .is_eof = 0, + .has_error = 0, + .seek = NULL, + .cookie = NULL, + .fd = 1, +}; +FILE __stderr_FILE; diff --git a/userland/libc/stdio/tmpfile.c b/userland/libc/stdio/tmpfile.c new file mode 100644 index 0000000..cee6e0a --- /dev/null +++ b/userland/libc/stdio/tmpfile.c @@ -0,0 +1,9 @@ +#include +#include + +FILE *tmpfile(void) { + // TODO + printf("TODO: Implement tmpfile()\n"); + assert(0); + return NULL; +} diff --git a/userland/libc/stdio/tmpnam.c b/userland/libc/stdio/tmpnam.c new file mode 100644 index 0000000..aafe67d --- /dev/null +++ b/userland/libc/stdio/tmpnam.c @@ -0,0 +1,10 @@ +#include +#include + +char *tmpnam(char *s) { + assert(!s); + s = malloc(100); + strcpy(s, "/tmp.XXXXXX"); + mkstemp(s); + return s; +} diff --git a/userland/libc/stdio/ungetc.c b/userland/libc/stdio/ungetc.c new file mode 100644 index 0000000..8d649bc --- /dev/null +++ b/userland/libc/stdio/ungetc.c @@ -0,0 +1,9 @@ +#include + +int ungetc(int c, FILE *stream) { + if (stream->has_buffered_char) + return EOF; + stream->buffered_char = c; + stream->has_buffered_char = 1; + return c; +} diff --git a/userland/libc/stdio/vdprintf.c b/userland/libc/stdio/vdprintf.c new file mode 100644 index 0000000..b3fa065 --- /dev/null +++ b/userland/libc/stdio/vdprintf.c @@ -0,0 +1,77 @@ +#include +#include +#include +#include + +struct vd_cookie { + int fd; + char *buffer; + uint8_t buf_len; + uint8_t buf_used; + int sent_bytes; +}; + +size_t min(size_t a, size_t b) { return (a < b) ? a : b; } + +size_t vd_write(FILE *f, const unsigned char *s, size_t l) { + struct vd_cookie *c = f->cookie; + + int clear_buffer = 0; + size_t b_copy = min(l, c->buf_len - (c->buf_used)); + for (int i = 0; i < b_copy; i++) { + c->buffer[c->buf_used + i] = s[i]; + if (s[i] == '\n') + clear_buffer = 1; + } + c->buf_used += b_copy; + + if (clear_buffer) { + int rc = write(c->fd, c->buffer, c->buf_used); + c->buf_used = 0; + if (-1 == rc) { + return (size_t)-1; + } + c->sent_bytes += rc; + } + return l; +} + +int vdprintf(int fd, const char *format, va_list ap) { + FILE f = { + .write = write_fd, + .fd = fd, + }; + return vfprintf(&f, format, ap); + // return -1; + /* +char buffer[32]; +struct vd_cookie c = {.fd = fd, + .buffer = buffer, + .buf_len = 32, + .buf_used = 0, + .sent_bytes = 0}; +FILE f = { +.write = vd_write, +.cookie = &c, +}; + +// If an output error was encountered, these functions shall return a +// negative value and set errno to indicate the error. +if (-1 == vfprintf(&f, format, ap)) +return -1; + +// Upon successful completion, the dprintf(), +// fprintf(), and printf() functions shall return the number of bytes +// transmitted. + +if(0 == c.buf_used) +return c.sent_bytes; + +// First the current buffer needs to be cleared +int rc = write(fd, buffer, c.buf_used); +if (-1 == rc) { +return -1; +} +c.sent_bytes += rc; +return c.sent_bytes;*/ +} diff --git a/userland/libc/stdio/vfprintf.c b/userland/libc/stdio/vfprintf.c new file mode 100644 index 0000000..79a22fb --- /dev/null +++ b/userland/libc/stdio/vfprintf.c @@ -0,0 +1,243 @@ +#include +#include +#include +#include + +const char HEX_SET[0x10] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + +#define FILE_WRITE(_f, _s, _l, _r) \ + { \ + size_t _rc = _f->write(_f, (const unsigned char *)_s, _l); \ + if ((size_t)-1 == _rc) \ + assert(0); \ + *(int *)(_r) += _rc; \ + } +// if ((size_t)0 == _rc) \ +// assert(0); \ + +int fprint_num(FILE *f, int n, int base, char *char_set, int prefix, + int zero_padding, int right_padding) { + int c = 0; + if (0 == n) { + zero_padding = 1; + prefix = 1; + } + char str[32]; + int i = 0; + for (; n != 0 && i < 32; i++, n /= base) + // str[i] = (n % base) + '0'; + str[i] = char_set[(n % base)]; + + char t = (zero_padding) ? '0' : ' '; + int orig_i = i; + + if (!right_padding) { + for (; prefix - orig_i > 0; prefix--) + FILE_WRITE(f, &t, 1, &c); + } + + for (i--; i >= 0; i--) + FILE_WRITE(f, &(str[i]), 1, &c); + + if (right_padding) { + for (; prefix - orig_i > 0; prefix--) + FILE_WRITE(f, &t, 1, &c); + } + return c; +} + +int fprint_int(FILE *f, int n, int prefix, int zero_padding, + int right_padding) { + return fprint_num(f, n, 10, "0123456789", prefix, zero_padding, + right_padding); +} + +int fprint_hex(FILE *f, int n, int prefix, int zero_padding, + int right_padding) { + return fprint_num(f, n, 16, "0123456789abcdef", prefix, zero_padding, + right_padding); +} + +int fprint_octal(FILE *f, int n, int prefix, int zero_padding, + int right_padding) { + return fprint_num(f, n, 8, "012345678", prefix, zero_padding, right_padding); +} + +int print_string(FILE *f, const char *s, int *rc, int prefix, int right_padding, + int precision) { + int l = strlen(s); + char t = ' '; + int c = 0; + if (!right_padding) { + if (prefix) + assert(-1 == precision); // FIXME: Is this correct? + for (; prefix - l > 0; prefix--) + FILE_WRITE(f, &t, 1, &c); + } + int bl = precision; + for (; *s; s++, (*rc)++) { + if (precision != -1) { + if (0 == bl) + break; + bl--; + } + int r; + FILE_WRITE(f, (const unsigned char *)s, 1, &r); + assert(r != 0); + } + if (right_padding) { + assert(-1 == precision); // FIXME: Is this correct? + for (; prefix - l > 0; prefix--) + FILE_WRITE(f, &t, 1, &c); + } + (*rc) += c; + return 0; +} + +int parse_precision(const char **fmt) { + const char *s = *fmt; + int rc = 0; + for (int i = 0;; i++, s++) { + if ('\0' == *s) + break; + const char c = *s; + if ('*' == c) { + assert(i == 0); + return -1; + } else if (!(c >= '0' && c <= '9')) { + s--; + break; + } + rc *= 10; + rc += c - '0'; + } + *fmt = s; + return rc; +} + +int vfprintf(FILE *f, const char *fmt, va_list ap) { + int rc = 0; + const char *s = fmt; + int prefix = 0; + + int zero_padding = 0; + int right_padding = 0; + + int cont = 0; + int precision = -1; + for (; *s; s++) { + if (!cont && '%' != *s) { + FILE_WRITE(f, (const unsigned char *)s, 1, &rc); + continue; + } + if (!cont) { + cont = 1; + continue; + } + + if ('\0' == *s) + break; + + switch (*s) { + case '.': + s++; + assert('\0' != *s); + precision = parse_precision(&s); + assert('\0' != *s); + if (-1 == precision) + precision = va_arg(ap, int); + cont = 1; + break; + case '0': + prefix *= 10; + if (0 == prefix) + zero_padding = 1; + cont = 1; + break; + case '-': + assert(0 == prefix); + right_padding = 1; + cont = 1; + break; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + prefix *= 10; + prefix += (*s) - '0'; + cont = 1; + break; + case 'i': + case 'd': + if(-1 != precision) { + zero_padding = 1; + prefix = precision; + right_padding = 0; + } + rc += fprint_int(f, va_arg(ap, int), prefix, zero_padding, right_padding); + cont = 0; + break; + case 'u': + assert(-1 == precision); + rc += fprint_int(f, va_arg(ap, unsigned int), prefix, zero_padding, + right_padding); + cont = 0; + break; + case 's': { + assert(!zero_padding); // this is not supported to strings + char *a = va_arg(ap, char *); + if (!a) { + if (-1 == + print_string(f, "(NULL)", &rc, prefix, right_padding, precision)) + return -1; + cont = 0; + break; + } + if (-1 == print_string(f, a, &rc, prefix, right_padding, precision)) + return -1; + cont = 0; + break; + } + case 'p': // TODO: Print this out in a nicer way + case 'x': + assert(-1 == precision); + rc += fprint_hex(f, va_arg(ap, const uint32_t), prefix, zero_padding, + right_padding); + cont = 0; + break; + case 'o': + assert(-1 == precision); + rc += fprint_octal(f, va_arg(ap, const uint32_t), prefix, zero_padding, + right_padding); + cont = 0; + break; + case '%': { + FILE_WRITE(f, (const unsigned char *)"%", 1, &rc); + cont = 0; + break; + } + case 'c': { + char c = va_arg(ap, const int); + FILE_WRITE(f, (const unsigned char *)&c, 1, &rc); + cont = 0; + break; + } + default: + printf("got %c but that is not supported by printf\n", *s); + assert(0); + break; + } + if (!cont) { + prefix = 0; + zero_padding = right_padding = 0; + precision = -1; + } + } + return rc; +} diff --git a/userland/libc/stdio/vprintf.c b/userland/libc/stdio/vprintf.c new file mode 100644 index 0000000..8a8dc33 --- /dev/null +++ b/userland/libc/stdio/vprintf.c @@ -0,0 +1,3 @@ +#include + +int vprintf(const char *format, va_list ap) { return vdprintf(1, format, ap); } diff --git a/userland/libc/stdlib.h b/userland/libc/stdlib.h new file mode 100644 index 0000000..bba5d84 --- /dev/null +++ b/userland/libc/stdlib.h @@ -0,0 +1,17 @@ +#ifndef STDLIB_H +#define STDLIB_H +#include +#include +#define RAND_MAX (UINT32_MAX) + +void *malloc(size_t s); +void *calloc(size_t nelem, size_t elsize); +void *realloc(void *ptr, size_t size); +void free(void *p); +char *getenv(const char *name); +int rand(void); +void srand(unsigned int seed); +unsigned long strtoul(const char *restrict str, + char **restrict endptr, int base); +int atoi(const char *str); +#endif diff --git a/userland/libc/stdlib/abort.c b/userland/libc/stdlib/abort.c new file mode 100644 index 0000000..7fd747e --- /dev/null +++ b/userland/libc/stdlib/abort.c @@ -0,0 +1,10 @@ +#include +#include + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/abort.html +void abort(void) { + printf("aborting!!!!\n"); + assert(0); + for (;;) + ; +} diff --git a/userland/libc/stdlib/abs.c b/userland/libc/stdlib/abs.c new file mode 100644 index 0000000..1079beb --- /dev/null +++ b/userland/libc/stdlib/abs.c @@ -0,0 +1,3 @@ +#include + +int abs(int i) { return (i < 0) ? (-i) : (i); } diff --git a/userland/libc/stdlib/atexit.c b/userland/libc/stdlib/atexit.c new file mode 100644 index 0000000..0e401ff --- /dev/null +++ b/userland/libc/stdlib/atexit.c @@ -0,0 +1,6 @@ +#include + +int atexit(void (*func)(void)) { + //TODO + return 0; +} diff --git a/userland/libc/stdlib/atof.c b/userland/libc/stdlib/atof.c new file mode 100644 index 0000000..8524f8b --- /dev/null +++ b/userland/libc/stdlib/atof.c @@ -0,0 +1,5 @@ +#include + +double atof(const char *str) { + return strtod(str,(char **)NULL); +} diff --git a/userland/libc/stdlib/atoi.c b/userland/libc/stdlib/atoi.c new file mode 100644 index 0000000..2183306 --- /dev/null +++ b/userland/libc/stdlib/atoi.c @@ -0,0 +1,4 @@ +#include + +// https://pubs.opengroup.org/onlinepubs/9699919799/ +int atoi(const char *str) { return (int)strtol(str, (char **)NULL, 10); } diff --git a/userland/libc/stdlib/getenv.c b/userland/libc/stdlib/getenv.c new file mode 100644 index 0000000..9a6a4e5 --- /dev/null +++ b/userland/libc/stdlib/getenv.c @@ -0,0 +1,6 @@ +#include + +char *getenv(const char *name) { + // FIXME + return NULL; +} diff --git a/userland/libc/stdlib/mkstemp.c b/userland/libc/stdlib/mkstemp.c new file mode 100644 index 0000000..1ea8790 --- /dev/null +++ b/userland/libc/stdlib/mkstemp.c @@ -0,0 +1,14 @@ +#include +#include + +char rand_char(void) { return 'A' + (rand() % 10); } + +int mkstemp(char *template) { + // FIXME: Incomplete + const char *s = template; + for (; *template; template ++) { + if ('X' == *template) + *template = rand_char(); + } + return open(s, O_RDWR, O_CREAT); +} diff --git a/userland/libc/stdlib/qsort.c b/userland/libc/stdlib/qsort.c new file mode 100644 index 0000000..3f87db5 --- /dev/null +++ b/userland/libc/stdlib/qsort.c @@ -0,0 +1,29 @@ +#include +#include + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/qsort.html +void qsort(void *base, size_t nel, size_t width, + int (*compar)(const void *, const void *)) { + // If the nel argument has the value zero, the comparison function pointed to + // by compar shall not be called and no rearrangement shall take place. + if (0 == nel) + return; + + // AB + // Results in negative + // BA + // Results in positive + + // Using bubblesort + unsigned char *p = base; + for (size_t i = 1; i < nel; i++) { + for (size_t j = 0; j < nel; j++) { + if (compar((p + i * width), (p + j * width)) < 0) { + unsigned char tmp[width]; + memcpy(tmp, (p + i * width), width); + memcpy((p + i * width), (p + j * width), width); + memcpy((p + j * width), tmp, width); + } + } + } +} diff --git a/userland/libc/stdlib/rand.c b/userland/libc/stdlib/rand.c new file mode 100644 index 0000000..e186af7 --- /dev/null +++ b/userland/libc/stdlib/rand.c @@ -0,0 +1,17 @@ +#include +#include + +uint32_t xorshift(uint32_t x) { + uint32_t f = x; + x ^= x << 13; + x ^= x >> 17; + x ^= x << 5; + return f + x; +} + +extern uint32_t __INTERNAL_RNG_STATE; +int rand(void) { + uint32_t x = xorshift(__INTERNAL_RNG_STATE); + __INTERNAL_RNG_STATE++; + return x; +} diff --git a/userland/libc/stdlib/srand.c b/userland/libc/stdlib/srand.c new file mode 100644 index 0000000..a35185a --- /dev/null +++ b/userland/libc/stdlib/srand.c @@ -0,0 +1,8 @@ +#include +#include + +uint32_t __INTERNAL_RNG_STATE; +void srand(unsigned int seed) { + __INTERNAL_RNG_STATE = seed; + __INTERNAL_RNG_STATE = rand(); // rand() used the internal rng state +} diff --git a/userland/libc/stdlib/strtod.c b/userland/libc/stdlib/strtod.c new file mode 100644 index 0000000..2c83879 --- /dev/null +++ b/userland/libc/stdlib/strtod.c @@ -0,0 +1,70 @@ +#include +#include +#include + +int ctoi(char c) { return c - '0'; } + +double strtod(const char *restrict nptr, char **restrict endptr) { + double r = 0; + // An initial, possibly empty, sequence of white-space characters (as + // specified by isspace()) + for (; isspace(*nptr); nptr++) + ; + + // A subject sequence interpreted as a floating-point constant or representing + // infinity or NaN + + { + // The expected form of the subject sequence is an optional '+' or '-' sign + int sign = 0; + int exp_sign = 0; + if ('+' == *nptr) { + sign = 0; + nptr++; + } else if ('-' == *nptr) { + sign = 1; + nptr++; + } + + // A non-empty sequence of decimal digits optionally containing a radix + // character + double exp = 0; + for (; isdigit(*nptr); nptr++) { + r *= 10; + r += ctoi(*nptr); + } + if ('.' == *nptr) { + double div = 10; + for (; isdigit(*nptr); nptr++) { + r += ctoi(*nptr) / div; + div *= 10; + } + } + r *= (sign) ? (-1) : (1); + + // then an optional exponent part consisting of the character 'e' or + // the character 'E' + if ('e' == tolower(*nptr)) { + // optionally followed by a '+' or '-' character + if ('+' == *nptr) { + exp_sign = 0; + nptr++; + } else if ('-' == *nptr) { + exp_sign = 1; + nptr++; + } + // and then followed by one or more decimal digits + for (; isdigit(*nptr); nptr++) { + exp *= 10; + exp += ctoi(*nptr); + } + exp *= (exp_sign) ? (-1) : (1); + } + assert(0 == exp); // TODO + } + + // A final string of one or more unrecognized characters, including the + // terminating NUL character of the input string + ; + return r; +} diff --git a/userland/libc/stdlib/strtol.c b/userland/libc/stdlib/strtol.c new file mode 100644 index 0000000..7aa7760 --- /dev/null +++ b/userland/libc/stdlib/strtol.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include + +extern int errno; +extern int get_value(char c, long base); + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/strtol.html +long strtol(const char *str, char **restrict endptr, int base) { + long ret_value = 0; + if (endptr) + *endptr = str; + // Ignore inital white-space sequence + for (; *str && isspace(*str); str++) + ; + if (!*str) + return ret_value; + + int sign = 0; + if ('-' == *str) { + // FIXME + sign = 1; + str++; + assert(0); + } else if ('+' == *str) { + str++; + } + + if (0 == base) { + // FIXME + assert(0); + } + + if (2 <= base && 36 >= base) { + for (; *str; str++) { + ret_value *= base; + int val = get_value(*str, base); + if (ret_value > LONG_MAX - val) { + errno = ERANGE; + return 0; + } + ret_value += val; + } + } else { + errno = EINVAL; + return 0; + } + if (endptr) + *endptr = str; + return ret_value; +} diff --git a/userland/libc/stdlib/strtold.c b/userland/libc/stdlib/strtold.c new file mode 100644 index 0000000..222464e --- /dev/null +++ b/userland/libc/stdlib/strtold.c @@ -0,0 +1,9 @@ +#include +#include + +long double strtold(const char *restrict nptr, char **restrict endptr) { + // TODO + // I will do this some other day + assert(NULL); + return 0; +} diff --git a/userland/libc/stdlib/strtoul.c b/userland/libc/stdlib/strtoul.c new file mode 100644 index 0000000..4d9a51d --- /dev/null +++ b/userland/libc/stdlib/strtoul.c @@ -0,0 +1,72 @@ +#include +#include +#include +#include + +extern int errno; +int get_value(char c, long base) { + int r; + if (c >= '0' && c <= '9') + r = c - '0'; + else if (c >= 'A' && c <= 'Z') + r = c - 'A'; + else if (c >= 'a' && c <= 'z') + r = c - 'a'; + else + return -1; + if (r >= base) + return -1; + return r; +} + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/strtoul.html +unsigned long strtoul(const char *restrict str, char **restrict endptr, + int base) { + unsigned long ret_value = 0; + if (endptr) + *endptr = str; + // Ignore inital white-space sequence + for (; *str && isspace(*str); str++) + ; + if (!*str) + return ret_value; + + int sign = 0; + if ('-' == *str) { + // FIXME + sign = 1; + str++; + assert(0); + } else if ('+' == *str) { + str++; + } + + if (0 == base) { + // FIXME + assert(0); + } + + if (2 <= base && 36 >= base) { + for (; *str; str++) { + ret_value *= base; + int val = get_value(*str, base); + /* + if (-1 == val) { + errno = ERANGE; + return 0; + }*/ + if (ret_value > ULONG_MAX - val) { + errno = ERANGE; + return 0; + } + + ret_value += val; + } + } else { + errno = EINVAL; + return 0; + } + if (endptr) + *endptr = str; + return ret_value; +} diff --git a/userland/libc/stdlib/system.c b/userland/libc/stdlib/system.c new file mode 100644 index 0000000..d951c5c --- /dev/null +++ b/userland/libc/stdlib/system.c @@ -0,0 +1,17 @@ +#include + +int system(const char *command) { + if (!command) + return NULL; + int pid = fork(); + if (0 == pid) { + char *argv[2]; + argv[0] = "/sh"; + argv[1] = command; + execv("/sh", argv); + } + // FIXME: Use waitpid + int rc; + (void)wait(&rc); + return rc; +} diff --git a/userland/libc/string.h b/userland/libc/string.h new file mode 100644 index 0000000..f811dba --- /dev/null +++ b/userland/libc/string.h @@ -0,0 +1,17 @@ +#ifndef STRING_H +#define STRING_H +#include +#include + +char *strerror(int errnum); +void *memset(void *s, int c, size_t n); +void *memcpy(void *dest, const void *src, uint32_t n); +int strcmp(const char *s1, const char *s2); +char *strcpy(char *dest, const char *src); +size_t strlen(const char *s); +size_t strnlen(const char *s, size_t maxlen); +int sscanf(const char *s, const char *restrict format, ...); +char *strrchr(const char *s, int c); +int strncmp(const char *s1, const char *s2, size_t n); +char *strncpy(char *s1, const char *s2, size_t n); +#endif diff --git a/userland/libc/string/memcmp.c b/userland/libc/string/memcmp.c new file mode 100644 index 0000000..01109b8 --- /dev/null +++ b/userland/libc/string/memcmp.c @@ -0,0 +1,11 @@ +#include + +int memcmp(const void *s1, const void *s2, size_t n) { + int return_value = 0; + + for (uint32_t i = 0; i < n; i++) + if (((unsigned char *)(s1))[i] != ((unsigned char *)(s2))[i]) + return_value++; + + return return_value; +} diff --git a/userland/libc/string/memcpy.c b/userland/libc/string/memcpy.c new file mode 100644 index 0000000..e19dec9 --- /dev/null +++ b/userland/libc/string/memcpy.c @@ -0,0 +1,9 @@ +#include + +void *memcpy(void *dest, const void *src, uint32_t n) { + unsigned char *d = dest; + const unsigned char *s = src; + for (; n; n--) + *d++ = *s++; + return dest; +} diff --git a/userland/libc/string/memmove.c b/userland/libc/string/memmove.c new file mode 100644 index 0000000..5fc49f7 --- /dev/null +++ b/userland/libc/string/memmove.c @@ -0,0 +1,14 @@ +#include + +// copy bytes in memory with overlapping areas +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/memmove.html +void *memmove(void *s1, const void *s2, size_t n) { + // Copying takes place as if the n bytes from the object pointed to by s2 are + // first copied into a temporary array of n bytes that does not overlap the + // objects pointed to by s1 and s2, and then the n bytes from the temporary + // array are copied into the object pointed to by s1. + unsigned char tmp[n]; + memcpy(tmp, s2, n); + memcpy(s1, tmp, n); + return s1; +} diff --git a/userland/libc/string/sscanf.c b/userland/libc/string/sscanf.c new file mode 100644 index 0000000..28e1ce1 --- /dev/null +++ b/userland/libc/string/sscanf.c @@ -0,0 +1,193 @@ +#include +#include +#include +#include +#include +#include +#include + +extern int errno; +extern int get_value(char c, long base); + +long ftnum(FILE *stream, int base, int *error) { + char c; + long ret_value = 0; + *error = 0; + // Ignore inital white-space sequence + for (;;) { + if (EOF == (c = fgetc(stream))) { + *error = 1; + return 0; + } + + if (!isspace(c)) { + ungetc(c, stream); + break; + } + } + if (c == '\0') { + *error = 1; + return 0; + } + if (!isdigit(c)) { + *error = 1; + return 0; + } + if (!(2 <= base && 36 >= base)) { + *error = 1; + return 0; + } + for (;;) { + if (EOF == (c = fgetc(stream))) + break; + if (c == '\0') { + ungetc(c, stream); + break; + } + int val = get_value(c, base); + if (-1 == val) { + ungetc(c, stream); + break; + } + if (ret_value * base > LONG_MAX - val) { + ungetc(c, stream); + errno = ERANGE; + *error = 1; + return 0; + } + ret_value *= base; + ret_value += val; + } + return ret_value; +} + +int vfscanf(FILE *stream, const char *format, va_list ap) { + int rc = 0; // Upon successful completion, these functions shall return the + // number of successfully matched and assigned input items + int cont = 0; + int suppress = 0; + for (; *format; format++) { + if (*format != '%' && !cont) { + char c; + if (isspace(*format)) + continue; + if (EOF == (c = fgetc(stream))) { + break; + } + if (*format == c) // TODO: Make sure this is the correct behaviour + continue; + // TODO: Make sure this is the correct behaviour + errno = EINVAL; + assert(0); + break; + } + + if (*format == '%' && !cont) { + cont = 1; + continue; + } + + int is_long = 0; + switch (*format) { + case 'l': + is_long++; + assert(is_long < 3); + cont = 1; + break; + case 'i': // Matches an optionally signed integer, whose format is the same + // as expected for the subject sequence of strtol() with 0 for the + // base argument. + case 'd': { + // Matches an optionally signed decimal integer, whose format is the + // same as expected for the subject sequence of strtol() with the value + // 10 for the base argument. In the absence of a size modifier, the + // application shall ensure that the corresponding argument is a pointer + // to int. + int err = 0; + int result = ftnum(stream, 10, &err); + if (err) { + cont = 0; + break; + } + if (!suppress) { + if (2 == is_long) { + *((long long *)va_arg(ap, long long *)) = result; + } else if (1 == is_long) { + *((long *)va_arg(ap, long *)) = result; + } else { + *((int *)va_arg(ap, int *)) = result; + } + rc++; + } + assert(0 == err); + cont = 0; + break; + } + case 'c': { + char result = fgetc(stream); + if (!suppress) { + *((char *)va_arg(ap, char *)) = result; + rc++; + } + cont = 0; + break; + } + case '*': // Assignment suppression + suppress = 1; + cont = 1; + break; + default: + printf("vfscanf: Got %c but not supported.\n", *format); + assert(0); + break; + } + if (!cont) { + suppress = 0; + } + } + return rc; +} + +struct sscanf_cookie { + const char *s; +}; + +size_t sscanf_read(FILE *f, unsigned char *s, size_t l) { + struct sscanf_cookie *c = f->cookie; + if (!*(c->s)) { + return 0; + } + size_t r = 0; + for (; l && *(c->s); l--, c->s += 1) { + *s = *(c->s); + s++; + r++; + } + if (!(*(c->s))) + f->is_eof = 1; + /* + memcpy(s, c->s, l); + c->s += l;*/ + return r; +} + +int vsscanf(const char *s, const char *restrict format, va_list ap) { + struct sscanf_cookie c = {.s = s}; + FILE f = { + .read = sscanf_read, + .cookie = &c, + .has_buffered_char = 0, + .is_eof = 0, + .has_error = 0, + .offset_in_file = 0, + }; + return vfscanf(&f, format, ap); +} + +int sscanf(const char *s, const char *restrict format, ...) { + va_list ap; + va_start(ap, format); + int rc = vsscanf(s, format, ap); + va_end(ap); + return rc; +} diff --git a/userland/libc/string/strcasecmp.c b/userland/libc/string/strcasecmp.c new file mode 100644 index 0000000..eed337b --- /dev/null +++ b/userland/libc/string/strcasecmp.c @@ -0,0 +1,28 @@ +#include + +int strcasecmp(const char *s1, const char *s2) { + // The strcmp() function shall compare the string pointed to by s1 + // to the string pointed to by s2. + int l1, l2, rc; + l1 = l2 = rc = 0; + for (; (*s1 || *s2);) { + if (tolower(*s1) != tolower(*s2)) + rc++; + if (*s1) { + l1++; + s1++; + } + if (*s2) { + l2++; + s2++; + } + } + + // Upon completion, strcmp() shall return an integer greater than, + // equal to, or less than 0, if the string pointed to by s1 is + // greater than, equal to, or less than the string pointed to by + // s2, respectively. + if (l2 > l1) + return -rc; + return rc; +} diff --git a/userland/libc/string/strcat.c b/userland/libc/string/strcat.c new file mode 100644 index 0000000..c430698 --- /dev/null +++ b/userland/libc/string/strcat.c @@ -0,0 +1,13 @@ +#include + +char *strcat(char *s1, const char *s2) { + strcpy(s1 + strlen(s1), s2); + return s1; + /* +char *r = s1; +for (; *s1; s1++) +; +for (; *s2; s2++, s1++) +*s1 = *s2; +return r;*/ +} diff --git a/userland/libc/string/strchr.c b/userland/libc/string/strchr.c new file mode 100644 index 0000000..1995547 --- /dev/null +++ b/userland/libc/string/strchr.c @@ -0,0 +1,11 @@ +#include + +char *strchr(const char *s, int c) { + for (; *s; s++) { + if (*s == (char)c) + return (char*)s; + } + if ((char)c == '\0') + return (char *)s; + return NULL; +} diff --git a/userland/libc/string/strcmp.c b/userland/libc/string/strcmp.c new file mode 100644 index 0000000..368b8fb --- /dev/null +++ b/userland/libc/string/strcmp.c @@ -0,0 +1,29 @@ +#include + +// https://pubs.opengroup.org/onlinepubs/9699919799/ +int strcmp(const char *s1, const char *s2) { + // The strcmp() function shall compare the string pointed to by s1 + // to the string pointed to by s2. + int l1, l2, rc; + l1 = l2 = rc = 0; + for (; *s1 || *s2;) { + if (*s1 != *s2) + rc++; + if (*s1) { + l1++; + s1++; + } + if (*s2) { + l2++; + s2++; + } + } + + // Upon completion, strcmp() shall return an integer greater than, + // equal to, or less than 0, if the string pointed to by s1 is + // greater than, equal to, or less than the string pointed to by + // s2, respectively. + if (l2 > l1) + return -rc; + return rc; +} diff --git a/userland/libc/string/strcpy.c b/userland/libc/string/strcpy.c new file mode 100644 index 0000000..9023fd1 --- /dev/null +++ b/userland/libc/string/strcpy.c @@ -0,0 +1,7 @@ +#include + +char *strcpy(char *dest, const char *src) { + for (; (*dest = *src); dest++, src++) + ; + return dest; +} diff --git a/userland/libc/string/strcspn.c b/userland/libc/string/strcspn.c new file mode 100644 index 0000000..2ad38d5 --- /dev/null +++ b/userland/libc/string/strcspn.c @@ -0,0 +1,14 @@ +#include + +size_t strcspn(const char *s1, const char *s2) { + size_t r = 0; + for (; *s1; s1++) { + for (const char *t = s2; *t; t++) { + if (*s1 == *s2) { + r++; + break; + } + } + } + return r; +} diff --git a/userland/libc/string/strdup.c b/userland/libc/string/strdup.c new file mode 100644 index 0000000..9e22f94 --- /dev/null +++ b/userland/libc/string/strdup.c @@ -0,0 +1,15 @@ +#include +#include +#include + +// The strdup() function shall return a pointer to a new string, which is a +// duplicate of the string pointed to by s. The returned pointer can be passed +// to free(). A null pointer is returned if the new string cannot be created. +char *strdup(const char *s) { + size_t l = strlen(s); + char *r = malloc(l + 1); + if (!r) + return NULL; + strcpy(r, s); + return r; +} diff --git a/userland/libc/string/strlcpy.c b/userland/libc/string/strlcpy.c new file mode 100644 index 0000000..a2d3dd9 --- /dev/null +++ b/userland/libc/string/strlcpy.c @@ -0,0 +1,20 @@ +#include + +// Copy string s2 to buffer s1 of size n. At most n-1 +// chars will be copied. Always NUL terminates (unless n == 0). +// Returns strlen(s2); if retval >= n, truncation occurred. +size_t *strlcpy(char *s1, const char *s2, size_t n) { + size_t tmp_n = n; + const char *os2 = s2; + for (; tmp_n; tmp_n--) { + if ((*s1++ = *s2++) == '\0') + break; + } + if (tmp_n == 0) { + if (n != 0) + *s1 = '\0'; /* NUL-terminate s1 */ + while (*s2++) + ; + } + return s2 - os2 - 1; +} diff --git a/userland/libc/string/strlen.c b/userland/libc/string/strlen.c new file mode 100644 index 0000000..8e3e77a --- /dev/null +++ b/userland/libc/string/strlen.c @@ -0,0 +1,8 @@ +#include + +size_t strlen(const char *s) { + const char *d = s; + for (; *s; s++) + ; + return s - d; +} diff --git a/userland/libc/string/strncasecmp.c b/userland/libc/string/strncasecmp.c new file mode 100644 index 0000000..9ce8c04 --- /dev/null +++ b/userland/libc/string/strncasecmp.c @@ -0,0 +1,29 @@ +#include +#include + +int strncasecmp(const char *s1, const char *s2, size_t n) { + // The strcmp() function shall compare the string pointed to by s1 + // to the string pointed to by s2. + int l1, l2, rc; + l1 = l2 = rc = 0; + for (; (*s1 || *s2) && n > 0; n--) { + if (tolower(*s1) != tolower(*s2)) + rc++; + if (*s1) { + l1++; + s1++; + } + if (*s2) { + l2++; + s2++; + } + } + + // Upon completion, strcmp() shall return an integer greater than, + // equal to, or less than 0, if the string pointed to by s1 is + // greater than, equal to, or less than the string pointed to by + // s2, respectively. + if (l2 > l1) + return -rc; + return rc; +} diff --git a/userland/libc/string/strncmp.c b/userland/libc/string/strncmp.c new file mode 100644 index 0000000..fd46189 --- /dev/null +++ b/userland/libc/string/strncmp.c @@ -0,0 +1,28 @@ +#include + +int strncmp(const char *s1, const char *s2, size_t n) { + // The strcmp() function shall compare the string pointed to by s1 + // to the string pointed to by s2. + int l1, l2, rc; + l1 = l2 = rc = 0; + for (; (*s1 || *s2) && n > 0; n--) { + if (*s1 != *s2) + rc++; + if (*s1) { + l1++; + s1++; + } + if (*s2) { + l2++; + s2++; + } + } + + // Upon completion, strcmp() shall return an integer greater than, + // equal to, or less than 0, if the string pointed to by s1 is + // greater than, equal to, or less than the string pointed to by + // s2, respectively. + if (l2 > l1) + return -rc; + return rc; +} diff --git a/userland/libc/string/strncpy.c b/userland/libc/string/strncpy.c new file mode 100644 index 0000000..0e88c63 --- /dev/null +++ b/userland/libc/string/strncpy.c @@ -0,0 +1,13 @@ +#include + +char *strncpy(char *s1, const char *s2, size_t n) { + char *rc = s1; + for (; n > 0; s1++, s2++, n--) { + *s1 = *s2; + if (!*s2) + break; + } + for (; n > 0; n--,s1++) + *s1 = '\0'; + return rc; +} diff --git a/userland/libc/string/strndup.c b/userland/libc/string/strndup.c new file mode 100644 index 0000000..ffb2088 --- /dev/null +++ b/userland/libc/string/strndup.c @@ -0,0 +1,22 @@ +#include +#include +#include + +// The strndup() function shall be equivalent to the strdup() function, +// duplicating the provided s in a new block of memory allocated as if +// by using malloc(), with the exception being that strndup() copies at +// most size plus one bytes into the newly allocated memory, terminating +// the new string with a NUL character. If the length of s is larger +// than size, only size bytes shall be duplicated. If size is larger +// than the length of s, all bytes in s shall be copied into the new +// memory buffer, including the terminating NUL character. The newly +// created string shall always be properly terminated. +char *strndup(const char *s, size_t size) { + size_t l = strlen(s); + size_t real_l = min(l, size); + char *r = malloc(real_l + 1); + if (!r) + return NULL; + strlcpy(r, s, real_l); + return r; +} diff --git a/userland/libc/string/strnlen.c b/userland/libc/string/strnlen.c new file mode 100644 index 0000000..86df42e --- /dev/null +++ b/userland/libc/string/strnlen.c @@ -0,0 +1,9 @@ +#include + +size_t strnlen(const char *s, size_t maxlen) { + size_t i; + for (i = 0; i < maxlen; i++) + if (s[i] == 0) + break; + return i; +} diff --git a/userland/libc/string/strpbrk.c b/userland/libc/string/strpbrk.c new file mode 100644 index 0000000..fb16b0c --- /dev/null +++ b/userland/libc/string/strpbrk.c @@ -0,0 +1,12 @@ +#include + +char *strpbrk(const char *s1, const char *s2) { + for (; *s1; s1++) { + for (const char *t = s2; *t; t++) { + if (*s1 == *t) { + return s1; + } + } + } + return NULL; +} diff --git a/userland/libc/string/strrchr.c b/userland/libc/string/strrchr.c new file mode 100644 index 0000000..a44199a --- /dev/null +++ b/userland/libc/string/strrchr.c @@ -0,0 +1,12 @@ +#include + +char *strrchr(const char *s, int c) { + char *last = NULL; + for (; *s; s++) { + if (*s == (char)c) + last = (char *)s; + } + if ((char)c == '\0') + last = (char*)s; + return last; +} diff --git a/userland/libc/string/strspn.c b/userland/libc/string/strspn.c new file mode 100644 index 0000000..2a7d3ae --- /dev/null +++ b/userland/libc/string/strspn.c @@ -0,0 +1,18 @@ +#include + +size_t strspn(const char *s1, const char *s2) { + size_t r = 0; + for (; *s1; s1++) { + int e = 0; + for (const char *t = s2; *t; t++) { + if (*s1 == *t) { + e = 1; + break; + } + } + if (!e) + break; + r++; + } + return r; +} diff --git a/userland/libc/string/strstr.c b/userland/libc/string/strstr.c new file mode 100644 index 0000000..20b9dc2 --- /dev/null +++ b/userland/libc/string/strstr.c @@ -0,0 +1,21 @@ +#include + +char *strstr(const char *s1, const char *s2) { + // If s2 points to a string with zero length, the function shall return s1. + if ('\0' == *s2) + return s1; + for (; *s1; s1++) { + const char *t1 = s1; + const char *t2 = s2; + int is_dif = 0; + for (; *t2 && *t1; t1++, t2++) { + if (*t2 != *t1) { + is_dif = 1; + break; + } + } + if (!is_dif) + return s1; + } + return NULL; +} diff --git a/userland/libc/string/strtok.c b/userland/libc/string/strtok.c new file mode 100644 index 0000000..7b8d0e3 --- /dev/null +++ b/userland/libc/string/strtok.c @@ -0,0 +1,26 @@ +#include + +char *strtok_s; + +char *strtok(char *restrict s, const char *restrict sep) { + if (s) { + strtok_s = s; + return strtok(NULL, sep); + } + if(!strtok_s) + return NULL; + char *e = strpbrk(strtok_s, sep); + if (!e) { + char *r = strtok_s; + strtok_s = NULL; + return r; + } + *e = '\0'; + e--; + for (; *sep; sep++) + e++; + e++; + char *r = strtok_s; + strtok_s = e; + return r; +} diff --git a/userland/libc/strings.h b/userland/libc/strings.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/sys/mman.h b/userland/libc/sys/mman.h new file mode 100644 index 0000000..e3ff734 --- /dev/null +++ b/userland/libc/sys/mman.h @@ -0,0 +1,8 @@ +#ifndef MMAP_H +#define MMAP_H +#include +#include + +void *mmap(void *addr, size_t length, int prot, int flags, int fd, + size_t offset); +#endif diff --git a/userland/libc/sys/mman/mmap.c b/userland/libc/sys/mman/mmap.c new file mode 100644 index 0000000..b9ad3a2 --- /dev/null +++ b/userland/libc/sys/mman/mmap.c @@ -0,0 +1,19 @@ +#include +#include +#include + +extern int errno; + +void *mmap(void *addr, size_t length, int prot, int flags, int fd, + size_t offset) { + SYS_MMAP_PARAMS args = { + .addr = addr, + .length = length, + .prot = prot, + .flags = flags, + .fd = fd, + .offset = offset, + }; +// return (void*)syscall(SYS_MMAP, &args, 0, 0, 0, 0); + RC_ERRNO(syscall(SYS_MMAP, &args, 0, 0, 0, 0)); +} diff --git a/userland/libc/sys/stat.h b/userland/libc/sys/stat.h new file mode 100644 index 0000000..2fe6cdc --- /dev/null +++ b/userland/libc/sys/stat.h @@ -0,0 +1,30 @@ +#ifndef STAT_H +#define STAT_H +#include +#include + +struct stat { + dev_t st_dev; // Device ID of device containing file. + ino_t st_ino; // File serial number. + mode_t st_mode; // Mode of file (see below). + nlink_t st_nlink; // Number of hard links to the file. + uid_t st_uid; // User ID of file. + gid_t st_gid; // Group ID of file. + dev_t st_rdev; // Device ID (if file is character or block special). + off_t st_size; // For regular files, the file size in bytes. + // For symbolic links, the length in bytes of the + // pathname contained in the symbolic link. + // For a shared memory object, the length in bytes. + // For a typed memory object, the length in bytes. + // For other file types, the use of this field is + // unspecified. + struct timespec st_atime; // Last data access timestamp. + struct timespec st_mtime; // Last data modification timestamp. + struct timespec st_ctime; // Last file status change timestamp. + blksize_t st_blksize; // A file system-specific preferred I/O block size + // for this object. In some file system types, this + // may vary from file to file. + blkcnt_t st_blocks; // Number of blocks allocated for this object. +}; +int stat(const char *path, struct stat *buf); +#endif diff --git a/userland/libc/sys/stat/mkdir.c b/userland/libc/sys/stat/mkdir.c new file mode 100644 index 0000000..c057fa7 --- /dev/null +++ b/userland/libc/sys/stat/mkdir.c @@ -0,0 +1,9 @@ +#include +#include + +int mkdir(const char *path, mode_t mode) { + (void)path; + (void)mode; + assert(0); // TODO: Implement + return 0; +} diff --git a/userland/libc/sys/stat/stat.c b/userland/libc/sys/stat/stat.c new file mode 100644 index 0000000..e37223e --- /dev/null +++ b/userland/libc/sys/stat/stat.c @@ -0,0 +1,13 @@ +#include +#include +#include +#include +#include + +int stat(const char *path, struct stat *buf) { + SYS_STAT_PARAMS args = { + .pathname = path, + .statbuf = buf, + }; + RC_ERRNO(syscall(SYS_STAT, &args, 0, 0, 0, 0)); +} diff --git a/userland/libc/sys/time/gettimeofday.c b/userland/libc/sys/time/gettimeofday.c new file mode 100644 index 0000000..e172cf2 --- /dev/null +++ b/userland/libc/sys/time/gettimeofday.c @@ -0,0 +1,5 @@ +#include +#include + +static int return_tod =0; +int gettimeofday(struct timeval *tp, void *tzp) {return return_tod++;} diff --git a/userland/libc/sys/types.h b/userland/libc/sys/types.h new file mode 100644 index 0000000..ffcf281 --- /dev/null +++ b/userland/libc/sys/types.h @@ -0,0 +1,27 @@ +#ifndef TYPES_H +#define TYPES_H +typedef unsigned int ino_t; + +typedef int mode_t; + +typedef int nlink_t; +typedef int uid_t; +typedef int gid_t; +typedef int id_t; + +typedef int blkcnt_t; +typedef int off_t; + +typedef int dev_t; +typedef unsigned int fsblkcnt_t; +typedef unsigned int fsfilcnt_t; +typedef unsigned int ino_t; +//typedef unsigned int size_t; + +typedef int blksize_t; +typedef int pid_t; +typedef int ssize_t; + +//typedef int clock_t; +typedef int time_t; +#endif diff --git a/userland/libc/syscall.h b/userland/libc/syscall.h new file mode 100644 index 0000000..952492f --- /dev/null +++ b/userland/libc/syscall.h @@ -0,0 +1,149 @@ +#ifndef SYSCALL_H +#define SYSCALL_H +#include "socket.h" +#include +#include + +#define SYS_OPEN 0 +#define SYS_READ 1 +#define SYS_WRITE 2 +#define SYS_PREAD 3 +#define SYS_PWRITE 4 +#define SYS_FORK 5 +#define SYS_EXEC 6 +#define SYS_GETPID 7 +#define SYS_EXIT 8 +#define SYS_WAIT 9 +#define SYS_BRK 10 +#define SYS_SBRK 11 +#define SYS_PIPE 12 +#define SYS_DUP2 13 +#define SYS_CLOSE 14 +#define SYS_OPENPTY 15 +#define SYS_POLL 16 +#define SYS_MMAP 17 +#define SYS_ACCEPT 18 +#define SYS_BIND 19 +#define SYS_SOCKET 20 +#define SYS_SHM_OPEN 21 +#define SYS_FTRUNCATE 22 +#define SYS_STAT 23 +#define SYS_MSLEEP 24 +#define SYS_UPTIME 25 + +int syscall(uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx, + uint32_t esi, uint32_t edi); +int s_syscall(int sys); + +extern int errno; +#define RC_ERRNO(_rc) \ + { \ + int c = _rc; \ + if (c < 0) { \ + errno = -(c); \ + return -1; \ + } \ + return c; \ + } + +typedef int mode_t; + +typedef struct SYS_OPEN_PARAMS { + char *file; + int flags; + int mode; +} __attribute__((packed)) SYS_OPEN_PARAMS; + +typedef struct SYS_PREAD_PARAMS { + int fd; + void *buf; + size_t count; + size_t offset; +} __attribute__((packed)) SYS_PREAD_PARAMS; + +typedef struct SYS_READ_PARAMS { + int fd; + void *buf; + size_t count; +} __attribute__((packed)) SYS_READ_PARAMS; + +typedef struct SYS_PWRITE_PARAMS { + int fd; + void *buf; + size_t count; + size_t offset; +} __attribute__((packed)) SYS_PWRITE_PARAMS; + +typedef struct SYS_WRITE_PARAMS { + int fd; + void *buf; + size_t count; +} __attribute__((packed)) SYS_WRITE_PARAMS; + +typedef struct SYS_EXEC_PARAMS { + char *path; + char **argv; +} __attribute__((packed)) SYS_EXEC_PARAMS; + +typedef struct SYS_DUP2_PARAMS { + int org_fd; + int new_fd; +} __attribute__((packed)) SYS_DUP2_PARAMS; + +typedef struct SYS_OPENPTY_PARAMS { + int *amaster; + int *aslave; + char *name; + /*const struct termios*/ void *termp; + /*const struct winsize*/ void *winp; +} __attribute__((packed)) SYS_OPENPTY_PARAMS; + +typedef struct SYS_POLL_PARAMS { + struct pollfd *fds; + size_t nfds; + int timeout; +} __attribute__((packed)) SYS_POLL_PARAMS; + +typedef struct SYS_MMAP_PARAMS { + void *addr; + size_t length; + int prot; + int flags; + int fd; + size_t offset; +} __attribute__((packed)) SYS_MMAP_PARAMS; + +typedef struct SYS_SOCKET_PARAMS { + int domain; + int type; + int protocol; +} __attribute__((packed)) SYS_SOCKET_PARAMS; + +typedef struct SYS_BIND_PARAMS { + int sockfd; + const struct sockaddr *addr; + socklen_t addrlen; +} __attribute__((packed)) SYS_BIND_PARAMS; + +typedef struct SYS_ACCEPT_PARAMS { + int socket; + struct sockaddr *address; + socklen_t *address_len; +} __attribute__((packed)) SYS_ACCEPT_PARAMS; + +typedef struct SYS_SHM_OPEN_PARAMS { + const char *name; + int oflag; + mode_t mode; +} __attribute__((packed)) SYS_SHM_OPEN_PARAMS; + +typedef struct SYS_FTRUNCATE_PARAMS { + int fildes; + uint64_t length; +} __attribute__((packed)) SYS_FTRUNCATE_PARAMS; + +typedef struct SYS_STAT_PARAMS { + const char *pathname; + struct stat *statbuf; +} __attribute__((packed)) SYS_STAT_PARAMS; +#endif diff --git a/userland/libc/time.h b/userland/libc/time.h new file mode 100644 index 0000000..771e430 --- /dev/null +++ b/userland/libc/time.h @@ -0,0 +1,20 @@ +#include + +struct tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + long __tm_gmtoff; + const char *__tm_zone; +}; + +struct timespec { + time_t tv_sec; // Seconds. + long tv_nsec; // Nanoseconds. +}; diff --git a/userland/libc/time/clock_gettime.c b/userland/libc/time/clock_gettime.c new file mode 100644 index 0000000..15f0cb7 --- /dev/null +++ b/userland/libc/time/clock_gettime.c @@ -0,0 +1,14 @@ +#include +#include + +int clock_gettime(clockid_t clock_id, struct timespec *tp) { + tp->tv_sec = 0; + tp->tv_nsec = 0; + return 0; + /* +SYS_CLOCK_GETTIME_PARAMS args = { +.clk = clock_id, +.ts = tp, +}; +return syscall(SYS_CLOCK_GETTIME, &args);*/ +} diff --git a/userland/libc/time/ctime_r.c b/userland/libc/time/ctime_r.c new file mode 100644 index 0000000..66e6416 --- /dev/null +++ b/userland/libc/time/ctime_r.c @@ -0,0 +1,13 @@ +#include +#include + +// TODO: Implement this + +// Time, formatting and parsing are some of the most annoying parts of +// programming. Lets just hope this function is not important +char *ctime_r(const time_t *clock, char *buf) { + (void)clock; + size_t l = strlen(buf); + memset(buf, '0', l); + return buf; +} diff --git a/userland/libc/time/gmtime.c b/userland/libc/time/gmtime.c new file mode 100644 index 0000000..44e0ff3 --- /dev/null +++ b/userland/libc/time/gmtime.c @@ -0,0 +1,21 @@ +#include + +struct tm gmtime_r = { + .tm_sec = 0, + .tm_min = 0, + .tm_hour = 0, + .tm_mday = 0, + .tm_mon = 0, + .tm_year = 0, + .tm_wday = 0, + .tm_yday = 0, + .tm_isdst = 0, + .__tm_gmtoff = 0, + .__tm_zone = 0, +}; + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/gmtime.html +struct tm *gmtime(const time_t *timer) { + // TODO: Implement + return &gmtime_r; +} diff --git a/userland/libc/time/localtime.c b/userland/libc/time/localtime.c new file mode 100644 index 0000000..40ca351 --- /dev/null +++ b/userland/libc/time/localtime.c @@ -0,0 +1,21 @@ +#include + + struct tm localtime_r = { + .tm_sec = 0, + .tm_min = 0, + .tm_hour = 0, + .tm_mday = 0, + .tm_mon = 0, + .tm_year = 0, + .tm_wday = 0, + .tm_yday = 0, + .tm_isdst = 0, + .__tm_gmtoff = 0, + .__tm_zone = 0, + }; + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/localtime.html +struct tm *localtime(const time_t *timer) { + // TODO: Implement + return &localtime_r; +} diff --git a/userland/libc/time/strftime.c b/userland/libc/time/strftime.c new file mode 100644 index 0000000..30a080d --- /dev/null +++ b/userland/libc/time/strftime.c @@ -0,0 +1,7 @@ +#include +#include + +size_t strftime(char *restrict s, size_t maxsize, + const char *restrict format, const struct tm *restrict timeptr) { + return 0; +} diff --git a/userland/libc/time/time.c b/userland/libc/time/time.c new file mode 100644 index 0000000..9931b71 --- /dev/null +++ b/userland/libc/time/time.c @@ -0,0 +1,9 @@ +#include + +time_t time(time_t *tloc) { + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + if (tloc) + *tloc = ts.tv_sec; + return ts.tv_sec; +} diff --git a/userland/libc/ubsan.c b/userland/libc/ubsan.c new file mode 100644 index 0000000..9ac9879 --- /dev/null +++ b/userland/libc/ubsan.c @@ -0,0 +1,49 @@ +#include +#include + +void ubsan_log(const char *cause, struct source_location source) { + printf("UBSAN\n"); + printf("%s: %s : %d\n", cause, source.file_name, source.line); + for (;;) + ; +} + +void __ubsan_handle_shift_out_of_bounds(struct ShiftOutOfBoundsData *data, + unsigned long lhs, unsigned long rhs) { + (void)lhs; + (void)rhs; + ubsan_log("handle_shift_out_of_bounds", data->location); +} + +void __ubsan_handle_add_overflow(struct OverflowData *data, unsigned long lhs, + unsigned long rhs) { + (void)lhs; + (void)rhs; + ubsan_log("handle_add_overflow", data->location); +} + +void __ubsan_handle_sub_overflow(struct OverflowData *data, unsigned long lhs, + unsigned long rhs) { + (void)lhs; + (void)rhs; + ubsan_log("handle_sub_overflow", data->location); +} + +void __ubsan_handle_negate_overflow(struct OverflowData *data, unsigned long lhs, + unsigned long rhs) { + (void)lhs; + (void)rhs; + ubsan_log("handle_negate_overflow", data->location); +} + +void __ubsan_handle_mul_overflow(struct OverflowData *data, unsigned long lhs, + unsigned long rhs) { + (void)lhs; + (void)rhs; + ubsan_log("handle_mul_overflow", data->location); +} + +void __ubsan_handle_out_of_bounds(struct OutOfBoundsData *data, void *index) { + (void)index; + ubsan_log("handle_out_of_bounds", data->location); +} diff --git a/userland/libc/ubsan.h b/userland/libc/ubsan.h new file mode 100644 index 0000000..dac5407 --- /dev/null +++ b/userland/libc/ubsan.h @@ -0,0 +1,79 @@ +#include + +enum { type_kind_int = 0, type_kind_float = 1, type_unknown = 0xffff }; + +struct type_descriptor { + uint16_t type_kind; + uint16_t type_info; + char type_name[1]; +}; + +struct source_location { + const char *file_name; + union { + unsigned long reported; + struct { + uint32_t line; + uint32_t column; + }; + }; +}; + +struct OverflowData { + struct source_location location; + struct type_descriptor *type; +}; + +struct type_mismatch_data { + struct source_location location; + struct type_descriptor *type; + unsigned long alignment; + unsigned char type_check_kind; +}; + +struct type_mismatch_data_v1 { + struct source_location location; + struct type_descriptor *type; + unsigned char log_alignment; + unsigned char type_check_kind; +}; + +struct type_mismatch_data_common { + struct source_location *location; + struct type_descriptor *type; + unsigned long alignment; + unsigned char type_check_kind; +}; + +struct nonnull_arg_data { + struct source_location location; + struct source_location attr_location; + int arg_index; +}; + +struct OutOfBoundsData { + struct source_location location; + struct type_descriptor *array_type; + struct type_descriptor *index_type; +}; + +struct ShiftOutOfBoundsData { + struct source_location location; + struct type_descriptor *lhs_type; + struct type_descriptor *rhs_type; +}; + +struct unreachable_data { + struct source_location location; +}; + +struct invalid_value_data { + struct source_location location; + struct type_descriptor *type; +}; + +struct alignment_assumption_data { + struct source_location location; + struct source_location assumption_location; + struct type_descriptor *type; +}; diff --git a/userland/libc/unistd.h b/userland/libc/unistd.h new file mode 100644 index 0000000..b1e3434 --- /dev/null +++ b/userland/libc/unistd.h @@ -0,0 +1,14 @@ +#ifndef UNISTD_H +#define UNISTD_H +#include + +extern int opterr, optind, optopt; +extern char *optarg; + +int close(int fildes); +int ftruncate(int fildes, size_t length); +int execv(char *path, char **argv); +int pipe(int fd[2]); +int dup2(int org_fd, int new_fd); +int getopt(int argc, char * const argv[], const char *optstring); +#endif diff --git a/userland/libc/unistd/_exit.c b/userland/libc/unistd/_exit.c new file mode 100644 index 0000000..c6d64be --- /dev/null +++ b/userland/libc/unistd/_exit.c @@ -0,0 +1,8 @@ +#include +#include + +// FIXME: Technically exit and _exit are different but this +// stackoverflow answer says that it does not usually matter. So lets +// hope that is the case. +// https://stackoverflow.com/a/5423108 +void _exit(int status) { syscall(SYS_EXIT, (void *)status, 0, 0, 0, 0); } diff --git a/userland/libc/unistd/execvp.c b/userland/libc/unistd/execvp.c new file mode 100644 index 0000000..573e822 --- /dev/null +++ b/userland/libc/unistd/execvp.c @@ -0,0 +1,8 @@ +#include +#include + +// FIXME: Path resolution +int execvp(const char *file, char *const argv[]) { + struct SYS_EXEC_PARAMS args = {.path = file, .argv = argv}; + return syscall(SYS_EXEC, &args, 0, 0, 0, 0); +} diff --git a/userland/libc/unistd/getopt.c b/userland/libc/unistd/getopt.c new file mode 100644 index 0000000..a026b59 --- /dev/null +++ b/userland/libc/unistd/getopt.c @@ -0,0 +1,14 @@ +#include +#include + +int opterr, optind, optopt; +char *optarg; + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/getopt.html +int getopt(int argc, char *const argv[], const char *optstring) { + // TODO + optind = 1; + optarg = NULL; + // assert(0); + return -1; +} diff --git a/userland/libc/unistd/getpid.c b/userland/libc/unistd/getpid.c new file mode 100644 index 0000000..8aeef10 --- /dev/null +++ b/userland/libc/unistd/getpid.c @@ -0,0 +1,7 @@ +#include +#include +#include + +pid_t getpid(void) { + return s_syscall(SYS_GETPID); +} diff --git a/userland/libc/unistd/msleep.c b/userland/libc/unistd/msleep.c new file mode 100644 index 0000000..0b016c6 --- /dev/null +++ b/userland/libc/unistd/msleep.c @@ -0,0 +1,6 @@ +// Not standard, but it feels like it should be. +#include +#include +#include + +void msleep(uint32_t ms) { syscall(SYS_MSLEEP, (void *)ms, 0, 0, 0, 0); } diff --git a/userland/libc/unistd/unlink.c b/userland/libc/unistd/unlink.c new file mode 100644 index 0000000..ccac0df --- /dev/null +++ b/userland/libc/unistd/unlink.c @@ -0,0 +1,7 @@ +#include + +int unlink(const char *path) { + // TODO + printf("TODO: Implement unlink"); + return 0; +} diff --git a/userland/libc/unistd/uptime.c b/userland/libc/unistd/uptime.c new file mode 100644 index 0000000..090a0e5 --- /dev/null +++ b/userland/libc/unistd/uptime.c @@ -0,0 +1,6 @@ +// Not standard, but it feels like it should be. +#include +#include +#include + +uint32_t uptime(void) { return syscall(SYS_UPTIME, 0, 0, 0, 0, 0); } diff --git a/userland/libc/wchar.h b/userland/libc/wchar.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libc/wctype.h b/userland/libc/wctype.h new file mode 100644 index 0000000..e69de29 diff --git a/userland/libgui/Makefile b/userland/libgui/Makefile new file mode 100644 index 0000000..5a895c4 --- /dev/null +++ b/userland/libgui/Makefile @@ -0,0 +1,17 @@ +CC="/home/anton/prj/osdev/sysroot/bin/i686-sb-gcc" +AR="/home/anton/prj/osdev/sysroot/bin/i686-sb-ar" +#CFLAGS = -ggdb -ffreestanding -O0 -Wall -Wextra -pedantic -mgeneral-regs-only -Wimplicit-fallthrough -nostdlib -static -Wno-undef -fsanitize=shift,signed-integer-overflow,bounds +CFLAGS = -O2 -ggdb -ffreestanding -O0 -Wall -Wextra -pedantic -mgeneral-regs-only -Wimplicit-fallthrough -nostdlib -static -Wno-undef +BINS=libgui.a +all: $(BINS) +LIBS=-L../libc -lc -L../json -ljson -lgcc +OBJ=libgui.o + +libgui.o: libgui.c + $(CC) $(CFLAGS) -c libgui.c -I../libc/ -I../json/ $(LIBS) + +libgui.a: $(OBJ) + $(AR) rcs libgui.a $^ + +clean: + rm $(OBJ) $(BINS) diff --git a/userland/libgui/font.h b/userland/libgui/font.h new file mode 100644 index 0000000..763b438 --- /dev/null +++ b/userland/libgui/font.h @@ -0,0 +1,3 @@ +#ifndef FONT_H +#define FONT_H +#endif diff --git a/userland/libgui/libgui.c b/userland/libgui/libgui.c new file mode 100644 index 0000000..5f5526d --- /dev/null +++ b/userland/libgui/libgui.c @@ -0,0 +1,290 @@ +#include "libgui.h" +#include "font.h" +#include +#include +#include +#include +#include +#include +#include + +#define place_pixel_pos(_p, _pos) \ + { *(uint32_t *)(w->bitmap_ptr + _pos) = _p; } + +static const unsigned char font8x8_basic[128][8] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0000 (nul) + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0001 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0002 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0003 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0004 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0005 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0006 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0007 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0008 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0009 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000A + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000B + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000C + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000D + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000E + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000F + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0010 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0011 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0012 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0013 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0014 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0015 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0016 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0017 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0018 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0019 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001A + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001B + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001C + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001D + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001E + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001F + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0020 (space) + {0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00}, // U+0021 (!) + {0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0022 (") + {0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00}, // U+0023 (#) + {0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00}, // U+0024 ($) + {0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00}, // U+0025 (%) + {0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00}, // U+0026 (&) + {0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0027 (') + {0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00}, // U+0028 (() + {0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00}, // U+0029 ()) + {0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00}, // U+002A (*) + {0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00}, // U+002B (+) + {0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+002C (,) + {0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00}, // U+002D (-) + {0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+002E (.) + {0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00}, // U+002F (/) + {0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00}, // U+0030 (0) + {0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00}, // U+0031 (1) + {0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00}, // U+0032 (2) + {0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00}, // U+0033 (3) + {0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00}, // U+0034 (4) + {0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00}, // U+0035 (5) + {0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00}, // U+0036 (6) + {0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00}, // U+0037 (7) + {0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+0038 (8) + {0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00}, // U+0039 (9) + {0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+003A (:) + {0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+003B (;) + {0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00}, // U+003C (<) + {0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00}, // U+003D (=) + {0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00}, // U+003E (>) + {0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00}, // U+003F (?) + {0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00}, // U+0040 (@) + {0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00}, // U+0041 (A) + {0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00}, // U+0042 (B) + {0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00}, // U+0043 (C) + {0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00}, // U+0044 (D) + {0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00}, // U+0045 (E) + {0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00}, // U+0046 (F) + {0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00}, // U+0047 (G) + {0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00}, // U+0048 (H) + {0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0049 (I) + {0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00}, // U+004A (J) + {0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00}, // U+004B (K) + {0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00}, // U+004C (L) + {0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00}, // U+004D (M) + {0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00}, // U+004E (N) + {0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00}, // U+004F (O) + {0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00}, // U+0050 (P) + {0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00}, // U+0051 (Q) + {0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00}, // U+0052 (R) + {0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00}, // U+0053 (S) + {0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0054 (T) + {0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00}, // U+0055 (U) + {0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0056 (V) + {0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00}, // U+0057 (W) + {0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00}, // U+0058 (X) + {0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // U+0059 (Y) + {0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00}, // U+005A (Z) + {0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00}, // U+005B ([) + {0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00}, // U+005C (\) + {0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00}, // U+005D (]) + {0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00}, // U+005E (^) + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, // U+005F (_) + {0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0060 (`) + {0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00}, // U+0061 (a) + {0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00}, // U+0062 (b) + {0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00}, // U+0063 (c) + {0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00}, // U+0064 (d) + {0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00}, // U+0065 (e) + {0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00}, // U+0066 (f) + {0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0067 (g) + {0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00}, // U+0068 (h) + {0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0069 (i) + {0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E}, // U+006A (j) + {0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00}, // U+006B (k) + {0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+006C (l) + {0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00}, // U+006D (m) + {0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00}, // U+006E (n) + {0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+006F (o) + {0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F}, // U+0070 (p) + {0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78}, // U+0071 (q) + {0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00}, // U+0072 (r) + {0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00}, // U+0073 (s) + {0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+0074 (t) + {0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00}, // U+0075 (u) + {0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0076 (v) + {0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00}, // U+0077 (w) + {0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00}, // U+0078 (x) + {0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0079 (y) + {0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00}, // U+007A (z) + {0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00}, // U+007B ({) + {0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, // U+007C (|) + {0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00}, // U+007D (}) + {0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+007E (~) + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // U+007F +}; + +#define pokeb(S, O, V) (*(unsigned char *)((S) + (O)) = (V)) + +// Very temporary +char *random_string(void) { + int fd = open("/dev/urandom", O_RDONLY, 0); + char *r = malloc(sizeof(char[10])); + for (int i = 0; i < 10 - 1; i++) { + char c; + read(fd, &c, 1); + r[i] = 'a' + (c & 0xF); + } + close(fd); + r[9] = '\0'; + printf("r: %s\n", r); + return r; +} + +int get_bitmap_value(const unsigned char bitmap[], int i) { + int array_index = i / 8; + int byte_index = i % 8; + int rc = (bitmap[array_index] >> byte_index) & 0x1; + return rc; +} + +void GUI_OverwriteFont(GUI_Window *w, uint32_t px, uint32_t py, + const uint32_t color) { + int sx, sy; + sx = 8; + sy = 8; + int x, y; + x = px; + y = py; + if (px + sx > w->sx) + return; + if (py + sy > w->sy) + return; + for (int i = 0; i < sx * sy; i++) { + int pos = x + y * w->sx; + place_pixel_pos(color, pos); + x++; + if (x >= sx + px) { + y++; + x = px; + } + if (y > py + sy) + break; + } +} + +void GUI_DrawFont(GUI_Window *w, uint32_t px, uint32_t py, const uint32_t c) { + int sx, sy; + sx = 8; + sy = 8; + int x, y; + x = px; + y = py; + if (px + sx > w->sx) + return; + if (py + sy > w->sy) + return; + const unsigned char *bitmap = font8x8_basic[c]; + for (int i = 0; i < sx * sy; i++) { + int pos = x + y * w->sx; + if (get_bitmap_value(bitmap, i)) { + place_pixel_pos(0xFFFFFF, pos); + } else { + place_pixel_pos(0x0, pos); + } + x++; + if (x >= sx + px) { + y++; + x = px; + } + if (y > py + sy) + break; + } +} + +typedef struct { + uint16_t px; + uint16_t py; + uint16_t sx; + uint16_t sy; + uint8_t name_len; +} WS_EVENT_CREATE; + +void GUI_ClearScreen(GUI_Window *w, uint32_t color) { + for (int i = 0; i < w->sx * w->sy; i++) + w->bitmap_ptr[i] =color; +} + +GUI_Window *GUI_CreateWindow(uint32_t x, uint32_t y, uint32_t sx, uint32_t sy) { + GUI_Window *w = malloc(sizeof(GUI_Window)); + if (!w) + return NULL; + w->x = x; + w->y = y; + w->sx = sx; + w->sy = sy; + + // Connect to the windowserver + int ws_fd = -1; + for (; - 1 == ws_fd;) { + ws_fd = open("/dev/windowserver", O_RDWR | O_NONBLOCK, 0); + } + w->ws_socket = ws_fd; + char *str = random_string(); + WS_EVENT_CREATE e; + e.px = x; + e.py = y; + e.sx = sx; + e.sy = sy; + e.name_len = (uint8_t)strlen(str) + 1; + + // Create bitmap + w->bitmap_fd = shm_open(str, O_RDWR, 0); + if (!((int)w->bitmap_fd >= 0)) { + printf("bitmap_fd: %x\n", w->bitmap_fd); + assert(0); + } + ftruncate(w->bitmap_fd, sx * sy * sizeof(uint32_t)); + void *rc = mmap(NULL, sx * sy * sizeof(uint32_t), 0, 0, w->bitmap_fd, 0); + if (!((int)rc >= 0)) { + printf("rc: %x\n", rc); + assert(0); + } + w->bitmap_ptr = rc; + + // Send the request to the windowserver + uint8_t l = 1; + uint8_t len = sizeof(l) + sizeof(e) + e.name_len; + char *buffer = malloc(len); + char *p = buffer; + memcpy(p, &l, sizeof(l)); + p += sizeof(l); + memcpy(p, &e, sizeof(e)); + p += sizeof(e); + strcpy(p, str); + write(ws_fd, buffer, len); + return w; +} + +void GUI_UpdateWindow(GUI_Window *w) { + uint8_t l = 0; + write(w->ws_socket, &l, sizeof(l)); +} diff --git a/userland/libgui/libgui.h b/userland/libgui/libgui.h new file mode 100644 index 0000000..d58c23c --- /dev/null +++ b/userland/libgui/libgui.h @@ -0,0 +1,34 @@ +#ifndef LIBGUI_H +#define LIBGUI_H +#include +#include + +typedef struct { + int ws_socket; + int bitmap_fd; + uint32_t *bitmap_ptr; + int x; + int y; + int sx; + int sy; +} GUI_Window; + +// Taken from drivers/keyboard.c +struct KEY_EVENT { + char c; + uint8_t mode; // (shift (0 bit)) (alt (1 bit)) + uint8_t release; // 0 pressed, 1 released +}; + +typedef struct { + int type; + struct KEY_EVENT ev; +} WS_EVENT; + +GUI_Window *GUI_CreateWindow(uint32_t x, uint32_t y, uint32_t sx, uint32_t sy); +void GUI_DrawFont(GUI_Window *w, uint32_t px, uint32_t py, const uint32_t c); +void GUI_UpdateWindow(GUI_Window *w); +void GUI_OverwriteFont(GUI_Window *w, uint32_t px, uint32_t py, + const uint32_t color); +void GUI_ClearScreen(GUI_Window *w, uint32_t color); +#endif diff --git a/userland/minibox/Makefile b/userland/minibox/Makefile new file mode 100644 index 0000000..5448f96 --- /dev/null +++ b/userland/minibox/Makefile @@ -0,0 +1,12 @@ +CC="/home/anton/prj/osdev/sysroot/bin/i686-sb-gcc" +CFLAGS=-Wall -Wextra -pedantic -Wimplicit-fallthrough -g -O0 +OBJ=minibox.o utilities/cat.o utilities/echo.o utilities/yes.o utilities/minibox.o utilities/ascii.o utilities/wc.o utilities/init.o utilities/ls.o utilities/touch.o utilities/ed.o + +%.o: %.c + $(CC) $(CFLAGS) $(INCLUDE) $(LIBS) -c $< -o $@ + +minibox: $(OBJ) + $(CC) $(INCLUDE) -o $@ $^ $(CFLAGS) $(LIBS) + +clean: + rm minibox $(OBJ) diff --git a/userland/minibox/minibox.c b/userland/minibox/minibox.c new file mode 100644 index 0000000..63eaee8 --- /dev/null +++ b/userland/minibox/minibox.c @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: 0BSD +// TODO: Possibly use getprogname() instead of using argv[0] to get the +// utility name. +#include +#include +#include + +#include "utilities/include.h" + +#define ARRAY_LENGTH(array) (sizeof(array) / sizeof((array)[0])) + +typedef struct Command { + char *name; + int (*function)(int, char **); +} Command; + +#define STR2(_x) #_x +#define STR(_x) STR2(_x) +#define COMMAND(NAME) \ + { STR(NAME), NAME##_main } + +Command utilities[] = {COMMAND(minibox), COMMAND(ascii), COMMAND(echo), + COMMAND(cat), COMMAND(yes), COMMAND(wc), + COMMAND(init), COMMAND(ls), COMMAND(touch), + COMMAND(ed)}; + +char *parse_filename(char *str) { + char *tmp = NULL, *is = str; + for (; *is++;) + if ('/' == *is) + tmp = is; + return tmp ? tmp + 1 : str; +} + +void usage(void) { + for (int i = 0; i < ARRAY_LENGTH(utilities); i++) { + printf("%s ", utilities[i].name); + } + printf("\n"); +} + +int main(int argc, char **argv) { + if (argc < 1) + return 1; +#ifdef SINGLE_MAIN + return utilities[0].function(argc, argv); +#endif + + // argv[0] will be checked to determine what utility + // is supposed to be ran. + // NOTE: "minibox" is a utility than can be ran. "minibox" + // will switch argv and argc so that argv[1] -> argv[0] + // then it will rerun main(). This allows utlities + // to be ran like "minibox " or + // even "minibox minibox " + const char *utility_name = parse_filename(argv[0]); + if (*utility_name == '/') + utility_name++; + for (int i = 0; i < ARRAY_LENGTH(utilities); i++) + if (0 == strcmp(utility_name, utilities[i].name)) + return utilities[i].function(argc, argv); + + usage(); + return 0; +} diff --git a/userland/minibox/utilities/ascii.c b/userland/minibox/utilities/ascii.c new file mode 100644 index 0000000..53429dc --- /dev/null +++ b/userland/minibox/utilities/ascii.c @@ -0,0 +1,30 @@ +#include + +const char * const ascii_table[] = +{ +"Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex", +" 0 00 NUL 16 10 DLE 32 20 48 30 0 64 40 @ 80 50 P 96 60 ` 112 70 p", +" 1 01 SOH 17 11 DC1 33 21 ! 49 31 1 65 41 A 81 51 Q 97 61 a 113 71 q", +" 2 02 STX 18 12 DC2 34 22 \" 50 32 2 66 42 B 82 52 R 98 62 b 114 72 r", +" 3 03 ETX 19 13 DC3 35 23 # 51 33 3 67 43 C 83 53 S 99 63 c 115 73 s", +" 4 04 EOT 20 14 DC4 36 24 $ 52 34 4 68 44 D 84 54 T 100 64 d 116 74 t", +" 5 05 ENQ 21 15 NAK 37 25 % 53 35 5 69 45 E 85 55 U 101 65 e 117 75 u", +" 6 06 ACK 22 16 SYN 38 26 & 54 36 6 70 46 F 86 56 V 102 66 f 118 76 v", +" 7 07 BEL 23 17 ETB 39 27 ' 55 37 7 71 47 G 87 57 W 103 67 g 119 77 w", +" 8 08 BS 24 18 CAN 40 28 ( 56 38 8 72 48 H 88 58 X 104 68 h 120 78 x", +" 9 09 HT 25 19 EM 41 29 ) 57 39 9 73 49 I 89 59 Y 105 69 i 121 79 y", +" 10 0A LF 26 1A SUB 42 2A * 58 3A : 74 4A J 90 5A Z 106 6A j 122 7A z", +" 11 0B VT 27 1B ESC 43 2B + 59 3B ; 75 4B K 91 5B [ 107 6B k 123 7B {", +" 12 0C FF 28 1C FS 44 2C , 60 3C < 76 4C L 92 5C \\ 108 6C l 124 7C |", +" 13 0D CR 29 1D GS 45 2D - 61 3D = 77 4D M 93 5D ] 109 6D m 125 7D }", +" 14 0E SO 30 1E RS 46 2E . 62 3E > 78 4E N 94 5E ^ 110 6E n 126 7E ~", +" 15 0F SI 31 1F US 47 2F / 63 3F ? 79 4F O 95 5F _ 111 6F o 127 7F DEL", +}; + +int ascii_main(int argc, char ** argv) +{ + for(int i = 0;i < sizeof(ascii_table)/sizeof(ascii_table[0]);i++) + puts(ascii_table[i]); + + return 0; +} diff --git a/userland/minibox/utilities/cat.c b/userland/minibox/utilities/cat.c new file mode 100644 index 0000000..c528d49 --- /dev/null +++ b/userland/minibox/utilities/cat.c @@ -0,0 +1,54 @@ +// cat - concatenate and print files +// https://pubs.opengroup.org/onlinepubs/9699919799/ +// +// TODO: Add -u flag "Write bytes from the input file to the standard +// output without delay as each is read." +#include "include.h" +#include +#include +#include +#include +#include + +int fd_to_stdout(int fd) { + int rc; + for (char buffer[CAT_BUFFER]; (rc = read(fd, &buffer, sizeof(buffer)));) { + if (-1 == rc) + return 0; + if (-1 == write(fd_stdout, buffer, rc)) + return 0; + } + return 1; +} + +int cat_main(int argc, char **argv) { + int fd = fd_stdin; + + // If no file operands are specified, the standard input shall be + // used. + if (argc < 2) { + return (fd_to_stdout(0)) ? 0 : 1; + } + + argv++; + for (; *argv; argv++) { + // If a file is '-', the cat utility shall read from the standard + // input at that point in the sequence. + if (0 == strcmp(*argv, "-")) { + if (!fd_to_stdout(0)) + return 1; + continue; + } + + if (-1 == (fd = open(*argv, O_RDONLY, 0))) { + printf("cat: "); + // fflush(stdout); + perror(*argv); + return 1; + } + if (!fd_to_stdout(fd)) + return 1; + close(fd); + } + return 0; +} diff --git a/userland/minibox/utilities/echo.c b/userland/minibox/utilities/echo.c new file mode 100644 index 0000000..5ec68a7 --- /dev/null +++ b/userland/minibox/utilities/echo.c @@ -0,0 +1,30 @@ +#include "include.h" +#include +#include +#include +#include + +int echo(char **str, int new_line) { + for (; *str;) { + printf("%s", *str); + if (*++str) + putchar(' '); + } + + if (new_line) + putchar('\n'); + return 0; +} + +int echo_main(int argc, char **argv) { + int new_line = 1; + + for (; *++argv && '-' == **argv;) + switch (*(*argv + 1)) { + case 'n': + new_line = 0; + break; + } + + return echo(argv, new_line); +} diff --git a/userland/minibox/utilities/ed.c b/userland/minibox/utilities/ed.c new file mode 100644 index 0000000..53270dc --- /dev/null +++ b/userland/minibox/utilities/ed.c @@ -0,0 +1,145 @@ +// ed - edit text +// ed [-p string] [-s] [file] +#include +#include +#include +#define COMMAND_MODE 0 +#define INPUT_MODE 1 + +int mode = COMMAND_MODE; + +FILE *fp = NULL; +FILE *mem_fp = NULL; +int line_number = 1; + +int getline(char *buffer, size_t s) { + (void)s; + int i = 0; + char c; + for (;; i++) { + int rc = read(0, &c, 1); + assert(rc > 0); + printf("%c", c); + buffer[i] = c; + if ('\n' == c) + break; + } + buffer[i] = '\0'; + return i; +} + +void goto_line(void) { + char c; + fseek(mem_fp, 0, SEEK_SET); + int line = 1; + if (1 != line_number) { + // Goto line + for (; fread(&c, 1, 1, mem_fp);) { + if ('\n' == c) + line++; + if (line == line_number) + return; + } + printf("got to line: %d\n", line); + assert(0); + } +} + +void read_line(void) { + char c; + goto_line(); + for (; fread(&c, 1, 1, mem_fp);) { + if ('\n' == c) + break; + printf("%c", c); + } + printf("\n"); +} + +void goto_end_of_line(void) { + char c; + for (; fread(&c, 1, 1, mem_fp);) { + if ('\n' == c) + break; + } +} + +void delete_line(void) { + long s = ftell(mem_fp); + printf("s: %d\n", s); + goto_end_of_line(); + long end = ftell(mem_fp); + printf("end: %d\n", end); + long offset = end - s; + for (char buffer[4096];;) { + int rc = fread(buffer, 1, 100, mem_fp); + long reset = ftell(mem_fp); + if (0 == rc) + break; + fseek(mem_fp, s, SEEK_SET); + fwrite(buffer, 1, rc, mem_fp); + s += rc; + fseek(mem_fp, reset, SEEK_SET); + } +} + +void read_command(void) { + char buffer[4096]; + char *s = buffer; + getline(buffer, 4096); + int a = -1; + int rc = sscanf(buffer, "%d", &a); + if (0 < rc) { + line_number = a; + } + for (; isdigit(*s); s++) + ; + if (0 == strcmp(s, "i")) { + mode = INPUT_MODE; + return; + } + if (0 == strcmp(s, ".")) { + read_line(); + return; + } + return; +} + +void read_input(void) { + char buffer[4096]; + int l = getline(buffer, 4096); + if (0 == strcmp(buffer, ".")) { + mode = COMMAND_MODE; + return; + } + goto_line(); + delete_line(); + goto_line(); + assert(fwrite(buffer, l, 1, mem_fp)); + return; +} + +int ed_main(char argc, char **argv) { + if (argc < 2) + return 1; + char *buffer; + size_t size; + mem_fp = open_memstream(&buffer, &size); + assert(mem_fp); + fp = fopen(argv[1], "r"); + assert(fp); + char r_buffer[4096]; + for (int rc; (rc = fread(buffer, 1, 4096, fp));) { + fwrite(r_buffer, 1, rc, mem_fp); + } + + for (;;) { + if (COMMAND_MODE == mode) + read_command(); + else + read_input(); + } + fclose(fp); + fclose(mem_fp); + return 0; +} diff --git a/userland/minibox/utilities/include.h b/userland/minibox/utilities/include.h new file mode 100644 index 0000000..7ffd136 --- /dev/null +++ b/userland/minibox/utilities/include.h @@ -0,0 +1,41 @@ +#include +/* General constants */ +#define fd_stdin 0 /* standard in file descriptor */ +#define fd_stdout 1 /* standard out file descriptor */ +#define ASSERT_NOT_REACHED assert(0); +/* END General constants */ + +/* CAT SETTINGS */ +#define CAT_BUFFER 4096 /* size of the read buffer */ +/* END CAT SETTINGS */ + +/* HTTP SETTINGS */ +#define HTTP_MAX_BUFFER 4096 /* size of the read buffer */ +#define HTTP_DEFAULT_PORT 1337 /* default port should -p not be supplied */ +#define HTTP_WEBSITE_ROOT "site/" /* default directory that it chroots into */ + +/* should xxx.html not exist these will be supplied instead */ +#define HTTP_DEFAULT_404_SITE "404 - Not Found" +#define HTTP_DEFAULT_400_SITE "400 - Bad Request" +/* END HTTP SETTINGS */ + +#define COND_PERROR_EXP(condition, function_name, expression) \ + if (condition) { \ + perror(function_name); \ + expression; \ + } + +int minibox_main(int argc, char **argv); +int ascii_main(int argc, char **argv); +int echo_main(int argc, char **argv); +int http_main(int argc, char **argv); +int lock_main(int argc, char **argv); +int yes_main(int argc, char **argv); +int cat_main(int argc, char **argv); +int pwd_main(int argc, char **argv); +int wc_main(int argc, char **argv); +int ls_main(int argc, char **argv); +int touch_main(int argc, char **argv); +int ed_main(int argc, char **argv); + +int init_main(void); diff --git a/userland/minibox/utilities/init.c b/userland/minibox/utilities/init.c new file mode 100644 index 0000000..35bedf2 --- /dev/null +++ b/userland/minibox/utilities/init.c @@ -0,0 +1,72 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int cmdfd; + +void execsh(void) { + char *argv[] = {NULL}; + execv("/sh", argv); +} + +void newtty(void) { + int m; + int s; + openpty(&m, &s, NULL, NULL, NULL); + int pid = fork(); + if (0 == pid) { + dup2(s, 0); + dup2(s, 1); + dup2(s, 2); + execsh(); + return; + } + close(s); + cmdfd = m; +} + +void shell() { + struct pollfd fds[2]; + fds[0].fd = cmdfd; + fds[0].events = POLLIN; + fds[0].revents = 0; + fds[1].fd = open("/dev/keyboard", O_RDONLY, 0); + fds[1].events = POLLIN; + fds[1].revents = 0; + for (;; fds[0].revents = fds[1].revents = 0) { + poll(fds, 2, 0); + if (fds[0].revents & POLLIN) { + char c[4096]; + int rc = read(fds[0].fd, c, 4096); + assert(rc > 0); + for (int i = 0; i < rc; i++) + putchar(c[i]); + } + if (fds[1].revents & POLLIN) { + char c; + int rc = read(fds[1].fd, &c, 1); + assert(rc > 0); + write(cmdfd, &c, 1); + // putchar(c); + } + } +} + +int init_main(void) { + if (1 != getpid()) { + printf("minibox init must be launched as pid1.\n"); + return 1; + } + if (fork()) + for (;;) + wait(NULL); + char *a[] = {NULL}; + execv("/term", a); + return 1; +} diff --git a/userland/minibox/utilities/ls.c b/userland/minibox/utilities/ls.c new file mode 100644 index 0000000..dc93d36 --- /dev/null +++ b/userland/minibox/utilities/ls.c @@ -0,0 +1,42 @@ +#include "include.h" +#include +#include +#include +#include +#include +#include + +int ls_main(int argc, char **argv) { + int list_hidden = 0; + int newline = 0; + /* + for (int ch;-1 != (ch = getopt(argc, argv, "a1"));) + switch ((char)ch) + { + case 'a': + list_hidden = 1; + break; + case '1': + newline = 1; + break; + }*/ + struct dirent **namelist; + int n; + COND_PERROR_EXP(-1 == (n = scandir("/", &namelist, 0, 0)), "scandir", + return 1); + + int prev = 0; + for (int i = 0; i < n; i++) { + if (!list_hidden) + if ('.' == *namelist[i]->d_name) + continue; + + if (prev) + putchar(newline ? '\n' : ' '); + else + prev = 1; + printf("%s", namelist[i]->d_name); + } + putchar('\n'); + return 0; +} diff --git a/userland/minibox/utilities/minibox.c b/userland/minibox/utilities/minibox.c new file mode 100644 index 0000000..ec5fdbd --- /dev/null +++ b/userland/minibox/utilities/minibox.c @@ -0,0 +1,15 @@ +#include "include.h" + +void usage(void); +int main(int argc, char **argv); + +// Should a command be called via "minibox " then shift +// argv and argc to become " " and rerun main() +int minibox_main(int argc, char **argv) { + if (argc < 2) + usage(); + + argc--; + argv++; + return main(argc, argv); +} diff --git a/userland/minibox/utilities/pwd.c b/userland/minibox/utilities/pwd.c new file mode 100644 index 0000000..29d8129 --- /dev/null +++ b/userland/minibox/utilities/pwd.c @@ -0,0 +1,12 @@ +#include "include.h" +#include +#include +#include +#include + +int pwd_main(int argc, char **argv) { + char cwd[PATH_MAX]; + COND_PERROR_EXP(NULL == (getcwd(cwd, PATH_MAX)), "getcwd", return 1); + puts(cwd); + return 0; +} diff --git a/userland/minibox/utilities/touch.c b/userland/minibox/utilities/touch.c new file mode 100644 index 0000000..949ad96 --- /dev/null +++ b/userland/minibox/utilities/touch.c @@ -0,0 +1,11 @@ +#include "include.h" +#include + +int touch_main(int argc, char **argv) { + if (argc < 2) + return 1; + int fd; + COND_PERROR_EXP(open(argv[1], 0, O_CREAT), "open", return 1) + close(fd); + return 0; +} diff --git a/userland/minibox/utilities/wc.c b/userland/minibox/utilities/wc.c new file mode 100644 index 0000000..886eb9e --- /dev/null +++ b/userland/minibox/utilities/wc.c @@ -0,0 +1,106 @@ +#include +#include +#include +#include +#include +#include "include.h" + +int cmode, wmode, lmode; + +void output(const char * str, size_t lines, size_t words, size_t chars) +{ + if(lmode) + printf("%d", lines); + + if(wmode) + { + if(lmode) putchar(' '); + + printf("%d", words); + } + + if(cmode) + { + if(lmode) putchar(' '); + + printf("%d", chars); + } + + if(str) printf(" %s", str); + + putchar('\n'); +} + +void wc(int argc, char ** argv) +{ + int fd = fd_stdin; + size_t total_chars, total_words, total_lines; + total_chars = total_words = total_lines = 0; + + if(NULL == *argv) + goto read_stdin; + + + for(;*argv;argv++) + { + int new_word = 1; + size_t chars = 0, + words = chars, + lines = chars; + + fd = open(*argv, O_RDONLY, 0); +read_stdin: + for(char c;read(fd, &c, 1);) + { + if(cmode) + chars++; + + if(wmode) + { + if(isspace(c)) { + new_word = 1; + } else if(new_word) { + words++; + new_word = 0; + } + } + + if(lmode) + if('\n' == c) + lines++; + } + close(fd); + if(lmode) total_lines += lines; + if(wmode) total_words += words; + if(cmode) total_chars += chars; + + output(*argv, lines, words, chars); + if(NULL == *argv) return; // We read from stdin + } + + if(argc > 1) output("total", total_lines, total_words, total_chars); +} + +int wc_main(int argc, char ** argv) +{ + cmode = wmode = lmode = 0; + for(argc--;*++argv && '-' == **argv;argc--) + switch(*(*argv+1)) + { + case 'l': + lmode = 1; + break; + case 'w': + wmode = 1; + break; + case 'c': + cmode = 1; + break; + } + + if(!(lmode || cmode || wmode)) + cmode = wmode = lmode = 1; + + wc(argc, argv); + return 0; +} diff --git a/userland/minibox/utilities/yes.c b/userland/minibox/utilities/yes.c new file mode 100644 index 0000000..ff19004 --- /dev/null +++ b/userland/minibox/utilities/yes.c @@ -0,0 +1,13 @@ +#include "include.h" +#include + +int yes_main(int argc, char **argv) { + if (argc < 2) + for (;;) + puts("y"); + + for (;; putchar('\n')) + for (int i = 1; i < argc; i++) + printf("%s ", argv[i]); + return 0; +} diff --git a/userland/sh/Makefile b/userland/sh/Makefile new file mode 100644 index 0000000..adccfb3 --- /dev/null +++ b/userland/sh/Makefile @@ -0,0 +1,13 @@ +CC="/home/anton/prj/osdev/sysroot/bin/i686-sb-gcc" +CFLAGS = -ggdb -ffreestanding -O0 -Wall -Wextra -pedantic -mgeneral-regs-only -Wimplicit-fallthrough -fsanitize=shift,signed-integer-overflow,bounds +BINS=sh +all: $(BINS) + +sh.o: sh.c + $(CC) $(CFLAGS) -L../libc/ -lc -c sh.c -I../libc/ +# $(CC) $(CFLAGS) ../libc/libc.o ../libc/crt0.o sh.c -I../libc/ + +clean: + rm sh sh.o +sh: sh.o + $(CC) -shared -o sh -ffreestanding -nostdlib $(CFLAGS) sh.o -L../libc/ -lc -lgcc #-L../libc/c.a diff --git a/userland/sh/sh b/userland/sh/sh new file mode 100755 index 0000000..7791495 Binary files /dev/null and b/userland/sh/sh differ diff --git a/userland/sh/sh.c b/userland/sh/sh.c new file mode 100644 index 0000000..5fe7f63 --- /dev/null +++ b/userland/sh/sh.c @@ -0,0 +1,224 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define MAX_ARGS 20 + +#define IS_SPECIAL(_c) (';' == _c || '\n' == _c || '&' == _c || '|' == _c) + +char *PATH = "/:/bin"; + +int can_open(char *f) { + int rc; + if (-1 == (rc = open(f, O_RDONLY, 0))) + return 0; + close(rc); + return 1; +} + +int find_path(char *file, char *buf) { + if ('/' == *file || '.' == *file) { // Real path + if (!can_open(file)) { + return 0; + } + strcpy(buf, file); + return 1; + } + + char *p = PATH; + for (;;) { + char *b = p; + for (; *p && ':' != *p; p++) + ; + size_t l = p - b; + strlcpy(buf, b, l); + strcat(buf, "/"); + strcat(buf, file); + if (can_open(buf)) { + return 1; + } + if (!*p) + break; + p++; + } + return 0; +} + +int internal_exec(char *file, char **argv) { + char r_path[PATH_MAX]; + if (!find_path(file, r_path)) + return 0; + if (-1 == execv(r_path, argv)) { + perror("exec"); + return 0; + } + return 1; +} + +int execute_program(char *s, size_t l, int ignore_rc, int f_stdout, + int *new_out) { + if (!l) + return -1; + + char c[l + 1]; + memcpy(c, s, l); + c[l] = 0; + + char *argv[MAX_ARGS]; + int args = 0; + char *p = c; + for (size_t i = 0; i <= l; i++) { + if (' ' == c[i]) { + if (p == c + i) { + for (; ' ' == *p; p++, i++) + ; + i--; + continue; + } + c[i] = '\0'; + + if (strlen(p) == 0) + break; + + argv[args] = p; + args++; + p = c + i + 1; + } else if (i == l) { + if (strlen(p) == 0) + break; + argv[args] = p; + args++; + } + } + argv[args] = NULL; + + int fd[2]; + pipe(fd); + + int pid = fork(); + if (0 == pid) { + if (new_out) + dup2(fd[1], 1); + if (-1 != f_stdout) + dup2(f_stdout, 0); + close(fd[0]); + if (!internal_exec(argv[0], argv)) { + printf("exec failed\n"); + exit(1); + } + } + + close(fd[1]); + if (new_out) + *new_out = fd[0]; + + if (ignore_rc) + return 0; + + int rc; + wait(&rc); + return rc; +} + +int compute_expression(char *exp) { + char *n = exp; + int ignore_next = 0; + int rc; + int f_stdout = -1; + int new_out = f_stdout; + for (; *exp; exp++) { + if (!IS_SPECIAL(*exp)) { + continue; + } + if ('\n' == *exp) + break; + if (';' == *exp) { + if (!ignore_next) { + execute_program(n, exp - n, 0, f_stdout, NULL); + } + n = exp + 1; + continue; + } + if ('&' == *exp && '&' == *(exp + 1)) { + if (!ignore_next) { + rc = execute_program(n, exp - n, 0, f_stdout, NULL); + if (0 != rc) + ignore_next = 1; + } + n = exp + 2; + exp++; + continue; + } else if ('&' == *exp) { + if (!ignore_next) { + execute_program(n, exp - n, 1, f_stdout, NULL); + } + n = exp + 1; + continue; + } + if ('|' == *exp && '|' == *(exp + 1)) { + if (!ignore_next) { + rc = execute_program(n, exp - n, 0, f_stdout, NULL); + if (0 == rc) + ignore_next = 1; + } + n = exp + 2; + exp++; + continue; + } else if ('|' == *exp) { + if (!ignore_next) { + execute_program(n, exp - n, 1, f_stdout, &new_out); + f_stdout = new_out; + } + n = exp + 1; + continue; + } + } + if (!ignore_next) + rc = execute_program(n, exp - n, 0, f_stdout, NULL); + return rc; +} + +char *get_line(void) { + char *str = malloc(1024); + char *p = str; + int rc; + for (;;) { + if (0 == (rc = read(0, p, 1))) { + continue; + } + if (0 > rc) { + perror("read"); + continue; + } + if (8 == *p) { + if (p == str) + continue; + putchar(*p); + p--; + continue; + } + putchar(*p); + if ('\n' == *p) { + break; + } + p++; + } + p++; + *p = '\0'; + return str; +} + +int main(void) { + for (;;) { + printf("/ : "); + char *l = get_line(); + compute_expression(l); + free(l); + } + return 0; +} diff --git a/userland/sh/sh_a b/userland/sh/sh_a new file mode 100755 index 0000000..7b435ab Binary files /dev/null and b/userland/sh/sh_a differ diff --git a/userland/sh/sh_bad b/userland/sh/sh_bad new file mode 100755 index 0000000..7f93418 Binary files /dev/null and b/userland/sh/sh_bad differ diff --git a/userland/snake/Makefile b/userland/snake/Makefile new file mode 100644 index 0000000..f29df30 --- /dev/null +++ b/userland/snake/Makefile @@ -0,0 +1,15 @@ +CC="/home/anton/prj/osdev/sysroot/bin/i686-sb-gcc" +CFLAGS = -ggdb -ffreestanding -O0 -Wall -Wextra -pedantic -mgeneral-regs-only -Wimplicit-fallthrough -static -fsanitize=shift,signed-integer-overflow,bounds +LIB=-L../libgui -lgui -L../json -ljson -L../libc -lc -lgcc +INC=-I../libc/ -I../json/ -I../libgui/ +BINS=snake +all: $(BINS) + +snake.o: snake.c + $(CC) $(CFLAGS) $(INC) $(LIB) -o $@ -c $< + +snake: snake.o + $(CC) -nostdlib $(CFLAGS) -o $@ $^ $(LIB) + +clean: + rm $(BINS) *.o diff --git a/userland/snake/snake.c b/userland/snake/snake.c new file mode 100644 index 0000000..7bfb312 --- /dev/null +++ b/userland/snake/snake.c @@ -0,0 +1,109 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GUI_Window *global_w; + +#define SNAKE_WIDTH 10 + +int get_key_event(char *c) { + if (0 >= read(global_w->ws_socket, c, 1)) + return 0; + if (0 == *c) + return 0; + return 1; +} + +void draw_snake(int x, int y) { + int sx = global_w->sx; + uint32_t *b = &global_w->bitmap_ptr[y * sx + x]; + for (int i = 0; i < SNAKE_WIDTH; i++) { + for (int j = 0; j < SNAKE_WIDTH; j++) { + b[j] = 0xFF00FF; + } + b += sx; + } +} + +int clamp(int *x, int *y) { + int clamped = 0; + if (*x + SNAKE_WIDTH > global_w->sx) { + *x = global_w->sx - SNAKE_WIDTH; + clamped = 1; + } + if (*y + SNAKE_WIDTH > global_w->sy) { + *y = global_w->sy - SNAKE_WIDTH; + clamped = 1; + } + return clamped; +} + +void loop() { + int vel = SNAKE_WIDTH; + static int y_dir = SNAKE_WIDTH; + static int x_dir = 0; + static int snake_x = 10; + static int snake_y = 10; + static int ticks = 0; + ticks++; + char c; + if (get_key_event(&c)) { + switch (c) { + case 'w': + y_dir = -1 * vel; + x_dir = 0; + break; + case 's': + y_dir = vel; + x_dir = 0; + break; + case 'a': + x_dir = -1 * vel; + y_dir = 0; + break; + case 'd': + x_dir = vel; + y_dir = 0; + break; + case 'q': + exit(0); + break; + default: + break; + } + } + + if (!(ticks > 5)) + return; + ticks = 0; + + snake_x += x_dir; + snake_y += y_dir; + if (clamp(&snake_x, &snake_y)) + return; + draw_snake(snake_x, snake_y); + if (y_dir || x_dir) + GUI_UpdateWindow(global_w); +} + +int main(void) { + global_w = GUI_CreateWindow(10, 10, 150 * 4, 150 * 4); + assert(global_w); + for (int i = 0; i < 150 * 150 * 4 * 4; i++) + global_w->bitmap_ptr[i] = 0xFFFFFF; + GUI_UpdateWindow(global_w); + for (;;) { + loop(); + msleep(50); + } + return 0; +} diff --git a/userland/terminal/Makefile b/userland/terminal/Makefile new file mode 100644 index 0000000..330f6e0 --- /dev/null +++ b/userland/terminal/Makefile @@ -0,0 +1,15 @@ +CC="/home/anton/prj/osdev/sysroot/bin/i686-sb-gcc" +CFLAGS = -ggdb -ffreestanding -O0 -Wall -Wextra -pedantic -mgeneral-regs-only -Wimplicit-fallthrough -static -fsanitize=shift,signed-integer-overflow,bounds +LIB=-L../libgui -lgui -L../json -ljson -L../libc -lc -lgcc +INC=-I../libc/ -I../json/ -I../libgui/ +BINS=term +all: $(BINS) + +term.o: term.c + $(CC) $(CFLAGS) $(INC) $(LIB) -o $@ -c $< + +term: term.o + $(CC) -nostdlib $(CFLAGS) -o $@ $^ $(LIB) + +clean: + rm $(BINS) *.o diff --git a/userland/terminal/term.c b/userland/terminal/term.c new file mode 100644 index 0000000..8a2ae83 --- /dev/null +++ b/userland/terminal/term.c @@ -0,0 +1,166 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TERM_BACKGROUND 0x000000 + +int cmdfd; +GUI_Window *global_w; +uint32_t screen_pos_x = 0; +uint32_t screen_pos_y = 0; +int serial_fd; + +void execsh(void) { + char *argv[] = {NULL}; + execv("/sh", argv); +} + +uint32_t cursor_pos_x = 0; +uint32_t cursor_pos_y = 0; + +void screen_remove_old_cursor() { + GUI_OverwriteFont(global_w, cursor_pos_x, cursor_pos_y, TERM_BACKGROUND); +} + +void screen_update_cursor() { + GUI_OverwriteFont(global_w, screen_pos_x, screen_pos_y, 0xFFFFFF); + cursor_pos_x = screen_pos_x; + cursor_pos_y = screen_pos_y; +} + +void screen_putchar(uint32_t c) { + if (c == '\n') { + screen_pos_x = 0; + screen_pos_y += 8; + screen_remove_old_cursor(); + screen_update_cursor(); + return; + } + if (screen_pos_y > global_w->sy - 8) { + uint8_t line[global_w->sx * sizeof(uint32_t)]; + for (int i = 0; i < global_w->sy - 8; i++) { + memcpy(line, global_w->bitmap_ptr + ((i + 8) * global_w->sx), + global_w->sx * sizeof(uint32_t)); + memcpy(global_w->bitmap_ptr + (i * global_w->sx), line, + global_w->sx * sizeof(uint32_t)); + } + for (int i = 0; i < global_w->sx; i += 8) { + GUI_OverwriteFont(global_w, i, screen_pos_y - 8, TERM_BACKGROUND); + } + screen_pos_x = 0; + screen_pos_y -= 8; + } + GUI_DrawFont(global_w, screen_pos_x, screen_pos_y, c); + screen_pos_x += 8; + if (screen_pos_x >= global_w->sx - 8) { + screen_pos_x = 0; + screen_pos_y += 8; + } + screen_update_cursor(); +} + +void screen_delete_char(void) { + GUI_OverwriteFont(global_w, screen_pos_x, screen_pos_y, TERM_BACKGROUND); + screen_pos_x -= 8; + GUI_OverwriteFont(global_w, screen_pos_x, screen_pos_y, TERM_BACKGROUND); + screen_update_cursor(); +} + +void screen_print(const unsigned char *s, int l) { + for (; l; l--, s++) { + if ('\b' == *s) { + screen_delete_char(); + continue; + } + screen_putchar((uint32_t)*s); + } +} + +void newtty(void) { + int m; + int s; + openpty(&m, &s, NULL, NULL, NULL); + int pid = fork(); + if (0 == pid) { + dup2(s, 0); + dup2(s, 1); + dup2(s, 2); + execsh(); + return; + } + close(s); + cmdfd = m; +} + +void writetty(const char *b, size_t len) { + write(serial_fd, b, len); + for (int rc; len; len -= rc) { + rc = write(cmdfd, b, len); + if (-1 == rc) { + perror("write"); + assert(0); + } + } +} + +void run() { + char buffer[4096]; + struct pollfd fds[2]; + fds[0].fd = cmdfd; + fds[0].events = POLLIN; + fds[0].revents = 0; + fds[1].fd = global_w->ws_socket; + fds[1].events = POLLIN; + fds[1].revents = 0; + for (;; fds[0].revents = fds[1].revents = 0) { + poll(fds, 2, 0); + if (fds[0].revents & POLLIN) { + int rc; + if ((rc = read(cmdfd, buffer, 4096))) { + screen_print(buffer, rc); + GUI_UpdateWindow(global_w); + } + } + if (fds[1].revents & POLLIN) { + WS_EVENT e; + int rc; + if (0 >= (rc = read(global_w->ws_socket, &e, sizeof(e)))) + continue; + if (1 == e.ev.release) + continue; + if (0 == e.ev.c) + continue; + write(cmdfd, &e.ev.c, 1); + } + } +} + +int main(void) { + open("/dev/serial", O_RDWR, 0); + open("/dev/serial", O_RDWR, 0); + printf("running the terminal\n"); + int pid = fork(); + if (0 == pid) { + char *argv[] = {NULL}; + execv("/ws", argv); + } + + global_w = GUI_CreateWindow(20, 20, 250 * 4, 150 * 4); + assert(global_w); + for (int i = 0; i < 250 * 150 * 4 * 4; i++) + global_w->bitmap_ptr[i] = TERM_BACKGROUND; + // memset(global_w->bitmap_ptr, 0x0, 50 * 50); + GUI_UpdateWindow(global_w); + newtty(); + run(); + return 0; +} diff --git a/userland/test/Makefile b/userland/test/Makefile new file mode 100644 index 0000000..7287939 --- /dev/null +++ b/userland/test/Makefile @@ -0,0 +1,16 @@ +#CC="/home/anton/opt/cross/bin/i686-elf-gcc" +CC="/home/anton/prj/osdev/sysroot/bin/i686-sb-gcc" +CFLAGS = -O2 -Wall -Wextra -pedantic -Wimplicit-fallthrough -static +LIB=-L../json -L../json/hashmap -ljson -lhashmap +INC=-I../json/ +BINS=test +all: $(BINS) + +test.o: test.c + $(CC) $(CFLAGS) $(INC) $(LIB) -o $@ -c $< + +test: test.o + $(CC) $(CFLAGS) -o $@ $^ $(LIB) + +clean: + rm test.o test diff --git a/userland/test/linux.sh b/userland/test/linux.sh new file mode 100755 index 0000000..d40d6cc --- /dev/null +++ b/userland/test/linux.sh @@ -0,0 +1,4 @@ +#!/bin/bash +gcc -DLINUX test.c -o ./local/a.out +cd local +./a.out diff --git a/userland/test/local/a.out b/userland/test/local/a.out new file mode 100755 index 0000000..1069f1f Binary files /dev/null and b/userland/test/local/a.out differ diff --git a/userland/test/local/testfile b/userland/test/local/testfile new file mode 100644 index 0000000..629ae5e --- /dev/null +++ b/userland/test/local/testfile @@ -0,0 +1 @@ +ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz diff --git a/userland/test/test b/userland/test/test new file mode 100755 index 0000000..63f9d8b Binary files /dev/null and b/userland/test/test differ diff --git a/userland/test/test.c b/userland/test/test.c new file mode 100644 index 0000000..041b08a --- /dev/null +++ b/userland/test/test.c @@ -0,0 +1,722 @@ +#include +#include +//#include +#include +#include +#include +#include +#include +#include + +#if 1 +void dbgln(const char *fmt) { printf("%s\n", fmt); } +#else +void dbgln(const char *fmt, ...) { + printf("| "); + va_list ap; + va_start(ap, fmt); + int rc = vdprintf(1, fmt, ap); + va_end(ap); + printf("\n"); +} +#endif + +void isx_test() { + dbgln("isx TEST"); + { + assert(isspace(' ')); + assert(isspace('\t')); + assert(!isspace('A')); + + assert(isalpha('A')); + assert(!isalpha('9')); + assert(!isalpha(' ')); + assert(!isalpha('z' + 1)); + + assert(isascii('A')); + assert(isascii('9')); + assert(isascii(' ')); + assert(!isascii(0xFF)); + + assert(ispunct('.')); + assert(!ispunct('A')); + + assert(isdigit('9')); + assert(!isdigit('A')); + } + dbgln("isx TEST PASSED"); +} + +void malloc_test(void) { + dbgln("malloc TEST"); + for (int j = 0; j < 100; j++) { + // printf("j : %x\n", j); + uint8_t *t = malloc(400 + j); + memset(t, 0x43 + (j % 10), 400 + j); + uint8_t *p = malloc(900 + j); + memset(p, 0x13 + (j % 10), 900 + j); + assert(p > t && p > (t + 400 + j)); + + for (int i = 0; i < 400 + j; i++) + if (t[i] != 0x43 + (j % 10)) { + printf("t addy: %x, val: %x, should be: %x\n", t + i, t[i], + 0x43 + (j % 10)); + assert(0); + } + + for (int i = 0; i < 900 + j; i++) + if (p[i] != 0x13 + (j % 10)) { + printf("p addy: %x, val: %x, should be: %x\n", p + i, t[i], + 0x13 + (j % 10)); + assert(0); + } + free(t); + } + dbgln("malloc TEST PASSED"); +} + +void memcmp_test(void) { + dbgln("memcmp TEST"); + { + assert(0 == memcmp("\xAA\xBB\xCC", "\xAA\xBB\xCC", 3)); + assert(1 == memcmp("\xAF\xBB\xCC", "\xAA\xBB\xCC", 3)); + } + dbgln("memcmp TEST PASSED"); +} + +void memcpy_test(void) { + dbgln("memcpy TEST"); + { + char buf[100]; + assert(buf == memcpy(buf, "\xAA\xBB\xCC", 3)); + assert(0 == memcmp(buf, "\xAA\xBB\xCC", 3)); + assert(buf == memcpy(buf, "\xCC\xBB\xCC", 3)); + assert(0 == memcmp(buf, "\xCC\xBB\xCC", 3)); + + assert(buf == memcpy(buf, "\xAA\xBB\xCC\xDD", 4)); + assert(0 == memcmp(buf, "\xAA\xBB\xCC\xDD", 4)); + assert(buf == memcpy(buf, "\xAA\xBB\xCC\xEE", 3)); + assert(0 == memcmp(buf, "\xAA\xBB\xCC\xDD", 4)); + } + dbgln("memcpy TEST PASSED"); +} + +void memmove_test(void) { + dbgln("memmove TEST"); + { + char buf[100]; + memcpy(buf, "foobar", 6); + const char *p = buf + 2; // obar + + assert(buf == memmove(buf, p, 4)); + assert(0 == memcmp(buf, "obarar", 6)); + } + dbgln("memmove TEST PASSED"); +} + +void strlen_test(void) { + dbgln("strlen TEST"); + { + assert(0 == strlen("")); + assert(3 == strlen("%is")); + assert(3 == strlen("foo")); + assert(3 == strlen("bar")); + assert(6 == strlen("foobar")); + } + dbgln("strlen TEST PASSED"); +} + +void strnlen_test(void) { + dbgln("strnlen TEST"); + { + assert(0 == strnlen("", 0)); + assert(0 == strnlen("", 3)); + assert(3 == strnlen("foo", 3)); + assert(2 == strnlen("bar", 2)); + assert(3 == strnlen("foobar", 3)); + assert(6 == strnlen("foobar", 6)); + assert(6 == strnlen("foobar", 8)); + } + dbgln("strnlen TEST PASSED"); +} + +/* +void json_test(void) { + dbgln("JSON TEST"); + { + const char *s = "{\"string\": \"hello\", \"object\": {\"string\": \"ff\"}}"; + JSON_CTX ctx; + JSON_Init(&ctx); + JSON_Parse(&ctx, s); + JSON_ENTRY *main_entry = JSON_at(&ctx.global_object, 0); + assert(main_entry != NULL); + JSON_ENTRY *index_entry = JSON_at(main_entry, 0); + JSON_ENTRY *string_entry = JSON_search_name(main_entry, "string"); + assert(index_entry != NULL); + assert(index_entry == string_entry); + char *str = index_entry->value; + assert(0 == strcmp(str, "hello")); + + JSON_ENTRY *object = JSON_search_name(main_entry, "object"); + assert(object != NULL); + JSON_ENTRY *object_string = JSON_search_name(object, "string"); + assert(object_string != NULL); + assert(0 == strcmp(object_string->value, "ff")); + } + dbgln("JSON TEST PASSED"); +}*/ + +void random_test(void) { + dbgln("/dev/random TEST"); + { + int fd = open("/dev/random", O_RDONLY, 0); + uint8_t buffer_1[256]; + assert(256 == read(fd, buffer_1, 256)); + close(fd); + fd = open("/dev/random", O_RDONLY, 0); + uint8_t buffer_2[256]; + assert(256 == read(fd, buffer_2, 256)); + close(fd); + assert(0 != memcmp(buffer_1, buffer_2, 256)); + } + dbgln("/dev/random TEST PASSED"); +} + +void sscanf_test(void) { + dbgln("sscanf TEST"); + { + int d1; + int d2; + sscanf("1337:7331", "%d:%d", &d1, &d2); + assert(1337 == d1); + assert(7331 == d2); + sscanf(" 1234 31415", "%d%d", &d1, &d2); + assert(1234 == d1); + assert(31415 == d2); + sscanf(" 1234 441122", "%*d%d", &d1); + assert(441122 == d1); + + char f; + char b; + sscanf("f:b", "%c:%c", &f, &b); + assert('f' == f); + assert('b' == b); + } + dbgln("sscanf TEST PASSED"); +} + +void strtoul_test(void) { + dbgln("strtoul TEST"); + { + long r; + char *s = "1234"; + char *endptr; + r = strtoul("1234", &endptr, 10); + assert(1234 == r); + assert(endptr == (s + 4)); + } + dbgln("strtoul TEST PASSED"); +} + +void strcspn_test(void) { + dbgln("strcspn TEST"); + { + assert(4 == strcspn("1234", "")); + assert(3 == strcspn("1234", "4")); + assert(2 == strcspn("1234", "43")); + assert(0 == strcspn("1234", "2143")); + } + dbgln("strcspn TEST PASSED"); +} + +void strpbrk_test(void) { + dbgln("strpbrk TEST"); + { + char *s = "01234"; + assert(s + 3 == strpbrk(s, "3")); + assert(s + 4 == strpbrk(s, "4")); + assert(s + 2 == strpbrk(s, "2")); + assert(s + 2 == strpbrk(s, "23")); + assert(NULL == strpbrk(s, "5")); + } + dbgln("strpbrk TEST PASSED"); +} + +void strcpy_test(void) { + dbgln("strcpy TEST"); + { + char buf[10]; + memset(buf, '\xBB', 10); + strcpy(buf, "hello"); + assert(0 == memcmp(buf, "hello\0\xBB\xBB\xBB\xBB", 10)); + } + dbgln("strcpy TEST PASSED"); +} + +void strncpy_test(void) { + dbgln("strncpy TEST"); + { + char buf[10]; + memset(buf, '\xBB', 10); + strncpy(buf, "hello", 3); + assert(0 == memcmp(buf, "hel\xBB\xBB\xBB\xBB\xBB\xBB\xBB", 10)); + strncpy(buf, "hello", 6); + assert(0 == memcmp(buf, "hello\0\xBB\xBB\xBB\xBB", 10)); + } + dbgln("strncpy TEST PASSED"); +} + +void strlcpy_test(void) { + dbgln("strlcpy TEST"); + { + char buf[10]; + memset(buf, '\xBB', 10); + strlcpy(buf, "hello", 3); + assert(0 == memcmp(buf, "hel\x00\xBB\xBB\xBB\xBB\xBB\xBB", 10)); + } + dbgln("strlcpy TEST PASSED"); +} + +void strcat_test(void) { + dbgln("strcat TEST"); + { + char buf[10]; + memset(buf, '\xBB', 10); + strcpy(buf, "hel"); + assert(0 == memcmp(buf, "hel\0\xBB\xBB\xBB\xBB\xBB\xBB", 10)); + strcat(buf, "lo"); + assert(0 == memcmp(buf, "hello\0\xBB\xBB\xBB\xBB", 10)); + } + dbgln("strcat TEST PASSED"); +} + +void strchr_test(void) { + dbgln("strchr TEST"); + { + char *s = "0123412345"; + assert(s + 3 == strchr(s, '3')); + assert(s + 4 + 5 == strchr(s, '5')); + assert(s + 4 == strchr(s, '4')); + assert(NULL == strchr(s, '9')); + } + dbgln("strchr TEST PASSED"); +} + +void strrchr_test(void) { + dbgln("strrchr TEST"); + { + char *s = "0123412345"; + assert(s + 3 + 4 == strrchr(s, '3')); + assert(s == strrchr(s, '0')); + assert(s + 4 + 5 == strrchr(s, '5')); + assert(NULL == strrchr(s, '9')); + } + dbgln("strrchr TEST PASSED"); +} + +void strdup_test(void) { + dbgln("strdup TEST"); + { + char *s; + s = strdup("hello"); + assert(s); + assert(0 == strcmp(s, "hello")); + free(s); + + s = strdup("abc"); + assert(s); + assert(0 == strcmp(s, "abc")); + free(s); + } + dbgln("strdup TEST PASSED"); +} + +void strndup_test(void) { + dbgln("strdup TEST"); + { + char *s; + s = strndup("hello", 5); + assert(s); + assert(0 == strcmp(s, "hello")); + free(s); + + s = strndup("hello", 3); + assert(s); + assert(0 == strcmp(s, "hel")); + free(s); + } + dbgln("strndup TEST PASSED"); +} + +void abs_test(void) { + dbgln("abs TEST"); + { + assert(1 == abs(1)); + assert(1 == abs(-1)); + assert(0 == abs(0)); + } + dbgln("abs TEST PASSED"); +} + +void strspn_test(void) { + dbgln("strspn TEST"); + { + assert(0 == strspn("abc", "")); + assert(0 == strspn("abc", "xyz")); + assert(1 == strspn("abc", "a")); + assert(2 == strspn("abc", "ab")); + assert(3 == strspn("abcd", "abc")); + assert(3 == strspn("abcde", "abce")); + } + dbgln("strspn TEST PASSED"); +} + +void strtol_test(void) { + dbgln("strtol TEST"); + { + char *s = "1234"; + char *e; + long r; + assert(1234 == strtol(s, &e, 10)); + assert(e == (s + 4)); + } + dbgln("strtol TEST PASSED"); +} + +void strcmp_test(void) { +#define EQ(_s1) \ + { assert(0 == strcmp(_s1, _s1)); } + dbgln("strcmp TEST"); + { + EQ("hello, world"); + EQ(""); + EQ("int: 100, hex: 64, octal: 144 a"); + } + dbgln("strcmp TEST PASSED"); +} + +void strncmp_test(void) { + dbgln("strncmp TEST"); + { + assert(0 == strncmp("hello", "hello", 5)); + assert(0 < strncmp("foo", "bar", 3)); + assert(0 == strncmp("foobar", "foofoo", 3)); + } + dbgln("strncmp TEST PASSED"); +} + +void strcasecmp_test(void) { + dbgln("strcasecmp TEST"); + { + assert(0 == strcasecmp("foobar", "FOObar")); + assert(0 == strcasecmp("foobar", "foobar")); + assert(6 == strcasecmp("foobar", "bar")); + } + dbgln("strcasecmp TEST PASSED"); +} + +void strncasecmp_test(void) { + dbgln("strncasecmp TEST"); + { + assert(0 == strncasecmp("foobar", "FOObar", 6)); + assert(0 == strncasecmp("foobar", "foobar", 6)); + assert(0 == strncasecmp("foo", "foobar", 3)); + assert(-1 == strncasecmp("foo", "foobar", 4)); + } + dbgln("strncasecmp TEST PASSED"); +} + +void strstr_test(void) { + dbgln("strstr TEST"); + { + const char *a = "foobar123"; + const char *b = "bar"; + assert(a + 3 == strstr(a, b)); + } + dbgln("strstr TEST PASSED"); +} + +void strtok_test(void) { + dbgln("strtok TEST"); + { + char *s = "hello,world,goodbye"; + assert(0 == strcmp(strtok(s, ","), "hello")); + assert(0 == strcmp(strtok(NULL, ","), "world")); + assert(0 == strcmp(strtok(NULL, ","), "goodbye")); + assert(NULL == strtok(NULL, ",")); + char *s2 = "hello,,world,,goodbye,test"; + assert(0 == strcmp(strtok(s2, ",,"), "hello")); + assert(0 == strcmp(strtok(NULL, ",,"), "world")); + assert(0 == strcmp(strtok(NULL, ","), "goodbye")); + assert(0 == strcmp(strtok(NULL, ","), "test")); + assert(NULL == strtok(NULL, ",")); + } + dbgln("strtok TEST PASSED"); +} + +void fseek_test(void) { + dbgln("fseek TEST"); + { +#ifndef LINUX + FILE *fp = fopen("/testfile", "r"); +#else + FILE *fp = fopen("testfile", "r"); +#endif + assert(NULL != fp); + char c; + assert(0 == ftell(fp)); + assert(1 == fread(&c, 1, 1, fp)); + assert('A' == c); + + assert(1 == ftell(fp)); + assert(1 == fread(&c, 1, 1, fp)); + assert('B' == c); + + assert(2 == ftell(fp)); + fseek(fp, 0, SEEK_SET); + assert(0 == ftell(fp)); + assert(1 == fread(&c, 1, 1, fp)); + assert('A' == c); + fseek(fp, 2, SEEK_SET); + assert(2 == ftell(fp)); + + assert(1 == fread(&c, 1, 1, fp)); + assert('C' == c); + fseek(fp, 2, SEEK_CUR); + assert(5 == ftell(fp)); + assert(1 == fread(&c, 1, 1, fp)); + assert('F' == c); + + char buffer[100]; + assert(6 == ftell(fp)); + fseek(fp, 0, SEEK_SET); + assert(1 == fread(buffer, 10, 1, fp)); + assert(0 == memcmp(buffer, "ABCDEFGHIJK", 10)); + assert(10 == ftell(fp)); + fseek(fp, 1, SEEK_SET); + assert(10 == fread(buffer, 1, 10, fp)); + assert(0 == memcmp(buffer, "BCDEFGHIJKL", 10)); + + fseek(fp, 0, SEEK_END); + assert(0 == fread(&c, 1, 1, fp)); + fseek(fp, -2, SEEK_CUR); + assert(1 == fread(&c, 1, 1, fp)); + assert('z' == c); + fseek(fp, -3, SEEK_END); + assert(1 == fread(&c, 1, 1, fp)); + assert('y' == c); + + assert(0 == fclose(fp)); + } + dbgln("fseek TEST PASSED"); +} + +void printf_test(void) { +#define EXP(exp) \ + { \ + int exp_n = strlen(exp); \ + if (0 != strcmp(buf, exp) || buf_n != exp_n) { \ + printf("buf n : %d\n", buf_n); \ + printf("exp n : %d\n", snprintf(NULL, 0, "%s", exp)); \ + printf("Expected: %s", exp); \ + printf("\n"); \ + printf("Got: %s", buf); \ + printf("\n"); \ + assert(0); \ + } \ + } + dbgln("printf TEST"); + { + char buf[200]; + int buf_n; + buf_n = sprintf(buf, "hello"); + EXP("hello"); + buf_n = sprintf(buf, "hello %s\n", "world"); + EXP("hello world\n"); + buf_n = sprintf(buf, "int: %d", 100); + EXP("int: 100"); + buf_n = sprintf(buf, "int: %d, hex: %x, octal: %o a", 100, 100, 100); + EXP("int: 100, hex: 64, octal: 144 a"); + + buf_n = sprintf(buf, "int: %02d", 1); + EXP("int: 01"); + buf_n = sprintf(buf, "int: %2d", 1); + EXP("int: 1"); + buf_n = sprintf(buf, "int: %00d", 1); + EXP("int: 1"); + + buf_n = sprintf(buf, "hex: %02x", 1); + EXP("hex: 01"); + buf_n = sprintf(buf, "hex: %2x", 1); + EXP("hex: 1"); + buf_n = sprintf(buf, "hex: %00x", 1); + EXP("hex: 1"); + buf_n = sprintf(buf, "hex: %x", 0x622933f2); + EXP("hex: 622933f2"); + + buf_n = sprintf(buf, "oct: %02o", 1); + EXP("oct: 01"); + buf_n = sprintf(buf, "oct: %2o", 1); + EXP("oct: 1"); + buf_n = sprintf(buf, "oct: %00o", 1); + EXP("oct: 1"); + + buf_n = sprintf(buf, "int: %-2dend", 1); + EXP("int: 1 end"); + buf_n = sprintf(buf, "int: %-2dend", 12); + EXP("int: 12end"); + buf_n = sprintf(buf, "int: %-0dend", 1); + EXP("int: 1end"); + + buf_n = sprintf(buf, "int: %-2xend", 1); + EXP("int: 1 end"); + buf_n = sprintf(buf, "int: %-2xend", 12); + EXP("int: c end"); + buf_n = sprintf(buf, "int: %-0xend", 1); + EXP("int: 1end"); + + buf_n = sprintf(buf, "int: %-2oend", 1); + EXP("int: 1 end"); + buf_n = sprintf(buf, "int: %-2oend", 12); + EXP("int: 14end"); + buf_n = sprintf(buf, "int: %-0oend", 1); + EXP("int: 1end"); + + buf_n = sprintf(buf, "string: %.3s", "foobar"); + EXP("string: foo"); + buf_n = sprintf(buf, "string: %.4s", "foobar"); + EXP("string: foob"); + + buf_n = sprintf(buf, "string: %s\n", "ABCDEFGHIJKLMNOPQRSTUVXYZ"); + EXP("string: ABCDEFGHIJKLMNOPQRSTUVXYZ\n"); + + buf_n = sprintf(buf, "string: %6send", "hello"); + EXP("string: helloend"); + buf_n = sprintf(buf, "string: %-6send", "hello"); + EXP("string: hello end"); + const char *data = "hello"; + char *foo = "foo"; + buf_n = sprintf(buf, " %-20s Legacy alias for \"%s\"\n", data, foo); + EXP(" hello Legacy alias for \"foo\"\n"); + buf_n = sprintf(buf, " %-20s %s%s\n", data, foo, "bar"); + EXP(" hello foobar\n"); + // Make sure that parameters have not changed + assert(0 == strcmp(data, "hello")); + assert(0 == strcmp(foo, "foo")); + + /* snprintf test */ + char out_buffer[100]; + memset(out_buffer, 'A', 100); + assert(5 == snprintf(out_buffer, 5, "hello")); + memcmp("helloAAAAA", out_buffer, 10); + assert(10 == snprintf(out_buffer, 5, "hellofoooo")); + memcmp("helloAAAAA", out_buffer, 10); + assert(10 == snprintf(out_buffer, 10, "hellofoooo")); + memcmp("hellofoookAA", out_buffer, 12); + } + dbgln("printf TEST PASSED"); +} + +int cmpfunc(const void *a, const void *b) { return (*(char *)a - *(char *)b); } + +void qsort_test(void) { + dbgln("qsort TEST"); + { + char buf[] = {'B', 'D', 'C', 'A', '\0'}; + qsort(buf, 4, sizeof(char), cmpfunc); + assert(0 == memcmp(buf, "ABCD", 4)); + } + dbgln("qsort TEST PASSED"); +} + +void basename_test(void) { + dbgln("basename TEST"); + { + char path[100]; + const char *s; + strcpy(path, "/foo/bar"); + s = basename(path); + assert(0 == strcmp(s, "bar")); + + strcpy(path, "/foo/bar/"); + s = basename(path); + assert(0 == strcmp(s, "bar")); + + strcpy(path, "/"); + s = basename(path); + assert(0 == strcmp(s, "/")); + + strcpy(path, "//"); + s = basename(path); + assert(0 == strcmp(s, "/")); + + strcpy(path, ""); + s = basename(path); + assert(0 == strcmp(s, ".")); + + s = basename(NULL); + assert(0 == strcmp(s, ".")); + } + dbgln("basename TEST PASSED"); +} + +void dirname_test(void) { + dbgln("dirname TEST"); + { + char path[100]; + const char *s; + strcpy(path, "/foo/bar"); + s = dirname(path); + assert(0 == strcmp(s, "foo")); + + strcpy(path, "/foo/bar/"); + s = dirname(path); + assert(0 == strcmp(s, "foo")); + + strcpy(path, "/foo/bar/zoo"); + s = dirname(path); + assert(0 == strcmp(s, "bar")); + } + dbgln("dirname TEST PASSED"); +} + +int main(void) { + dbgln("START"); + malloc_test(); + // json_test(); + // random_test(); + isx_test(); + memcmp_test(); + memcpy_test(); + memmove_test(); + strlen_test(); + strnlen_test(); + sscanf_test(); + strtoul_test(); + strcspn_test(); + strpbrk_test(); + strcpy_test(); + strncpy_test(); + strlcpy_test(); + strcat_test(); + strchr_test(); + strrchr_test(); + strdup_test(); + strndup_test(); + strspn_test(); + strtol_test(); + strcmp_test(); + strncmp_test(); + strcasecmp_test(); + strncasecmp_test(); + strstr_test(); + strtok_test(); + abs_test(); + // fseek_test(); + printf_test(); + qsort_test(); + basename_test(); + dirname_test(); + // TODO: Add mkstemp + return 0; +} diff --git a/userland/windowserver/Makefile b/userland/windowserver/Makefile new file mode 100644 index 0000000..f67bd66 --- /dev/null +++ b/userland/windowserver/Makefile @@ -0,0 +1,16 @@ +CC="/home/anton/prj/osdev/sysroot/bin/i686-sb-gcc" +CFLAGS = -ggdb -ffreestanding -O2 -Wall -Wextra -pedantic -mgeneral-regs-only -Wimplicit-fallthrough -fsanitize=shift,signed-integer-overflow,bounds +BIN=ws +LIB=-L../json -ljson -L../json/hashmap -lhashmap -L../libc -lc -lgcc +INC=-I../json/ -I../libgui/ +all: $(BIN) +OBJ=ws.o draw.o + +%.o: %.c + $(CC) $(CFLAGS) $(INC) $(LIB) -o $@ -c $< + +clean: + rm $(OBJ) ws + +$(BIN): $(OBJ) + $(CC) -o $(BIN) -ffreestanding -nostdlib $(CFLAGS) $(OBJ) $(LIB) diff --git a/userland/windowserver/draw.c b/userland/windowserver/draw.c new file mode 100644 index 0000000..caa16a2 --- /dev/null +++ b/userland/windowserver/draw.c @@ -0,0 +1,80 @@ +#include "draw.h" +#include + +#define BPP 4 + +#define place_pixel(_p, _w, _h) \ + { *(uint32_t *)(disp->back_buffer + BPP * (_w) + (WIDTH * BPP * (_h))) = _p; } + +#define place_pixel_pos(_p, _pos) \ + { *(uint32_t *)(disp->back_buffer + BPP * (_pos)) = _p; } + +int mx; +int my; + +void update_display(DISPLAY *disp) { + for (int i = 0; i < 20; i++) { + place_pixel(0xFFFFFFFF, mx + i, my + i); + place_pixel(0xFFFFFFFF, mx, my + i / 2); + place_pixel(0xFFFFFFFF, mx + i / 2, my); + } + for (int i = 0; i < disp->size; i++) + disp->true_buffer[i] = disp->back_buffer[i]; + // memcpy(disp->true_buffer, disp->back_buffer, disp->size); +} + +void draw_wallpaper(DISPLAY *disp) { + for (int i = 0; i < disp->size / BPP; i++) { + place_pixel_pos(0xFF00FF, i); + } +} + +void draw_mouse(DISPLAY *disp, int mouse_x, int mouse_y) { + mx = mouse_x; + my = mouse_y; + update_full_display(disp, mouse_x, mouse_y); +} + +void draw_window(DISPLAY *disp, const WINDOW *w) { + int x, y; + uint8_t border_size = disp->border_size; + const int px = w->x + border_size; + const int py = w->y; + const int sx = w->sx; + const int sy = w->sy; + x = px; + y = py; + for (int i = 0; i < sy; i++) { + if((i+py)*WIDTH + px > HEIGHT*WIDTH) + break; + uint32_t *ptr = disp->back_buffer + BPP * ((i + py) * WIDTH) + px * BPP; + if(i*sx > HEIGHT*WIDTH) + break; + uint32_t *bm = &w->bitmap_ptr[i * sx]; + // ((uint8_t *)w->bitmap_ptr) + BPP * ((i + py) * WIDTH) + px * BPP; + for (int j = 0; j < sx; j++) { + ptr[j] = bm[j]; + } + } +} + +void update_active_window(DISPLAY *disp) { + for (int i = 0; i < 100; i++) { + if (!disp->clients[i]) + continue; + if (!disp->clients[i]->w) + continue; + draw_window(disp, disp->clients[i]->w); + } +} + +void update_full_display(DISPLAY *disp, int mouse_x, int mouse_y) { + draw_wallpaper(disp); /* + for (int i = 0; i < 100; i++) { + if (!disp->windows[i]) + continue; + draw_window(disp, disp->windows[i]); + }*/ + update_active_window(disp); + update_display(disp); +} diff --git a/userland/windowserver/draw.h b/userland/windowserver/draw.h new file mode 100644 index 0000000..bf9ff4f --- /dev/null +++ b/userland/windowserver/draw.h @@ -0,0 +1,13 @@ +#ifndef DRAW_H +#define DRAW_H +#include "ws.h" + +#define WIDTH 0x500 +#define HEIGHT 0x320 + +void draw_wallpaper(DISPLAY *disp); +void draw_window(DISPLAY *disp, const WINDOW *w); +void update_full_display(DISPLAY *disp, int mouse_x, int mouse_y); +void update_active_window(DISPLAY *disp); +void draw_mouse(DISPLAY *disp, int mouse_x, int mouse_y); +#endif diff --git a/userland/windowserver/font.h b/userland/windowserver/font.h new file mode 100644 index 0000000..ad63e41 --- /dev/null +++ b/userland/windowserver/font.h @@ -0,0 +1,133 @@ +#ifndef FONT_H +#define FONT_H +char font8x8_basic[128][8] = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0000 (nul) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0001 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0002 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0003 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0004 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0005 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0006 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0007 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0008 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0009 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000A + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000B + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000C + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000D + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000E + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000F + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0010 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0011 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0012 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0013 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0014 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0015 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0016 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0017 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0018 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0019 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001A + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001B + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001C + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001D + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001E + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001F + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0020 (space) + { 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00}, // U+0021 (!) + { 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0022 (") + { 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00}, // U+0023 (#) + { 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00}, // U+0024 ($) + { 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00}, // U+0025 (%) + { 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00}, // U+0026 (&) + { 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0027 (') + { 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00}, // U+0028 (() + { 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00}, // U+0029 ()) + { 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00}, // U+002A (*) + { 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00}, // U+002B (+) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+002C (,) + { 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00}, // U+002D (-) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+002E (.) + { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00}, // U+002F (/) + { 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00}, // U+0030 (0) + { 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00}, // U+0031 (1) + { 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00}, // U+0032 (2) + { 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00}, // U+0033 (3) + { 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00}, // U+0034 (4) + { 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00}, // U+0035 (5) + { 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00}, // U+0036 (6) + { 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00}, // U+0037 (7) + { 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+0038 (8) + { 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00}, // U+0039 (9) + { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+003A (:) + { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+003B (;) + { 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00}, // U+003C (<) + { 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00}, // U+003D (=) + { 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00}, // U+003E (>) + { 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00}, // U+003F (?) + { 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00}, // U+0040 (@) + { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00}, // U+0041 (A) + { 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00}, // U+0042 (B) + { 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00}, // U+0043 (C) + { 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00}, // U+0044 (D) + { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00}, // U+0045 (E) + { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00}, // U+0046 (F) + { 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00}, // U+0047 (G) + { 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00}, // U+0048 (H) + { 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0049 (I) + { 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00}, // U+004A (J) + { 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00}, // U+004B (K) + { 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00}, // U+004C (L) + { 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00}, // U+004D (M) + { 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00}, // U+004E (N) + { 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00}, // U+004F (O) + { 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00}, // U+0050 (P) + { 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00}, // U+0051 (Q) + { 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00}, // U+0052 (R) + { 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00}, // U+0053 (S) + { 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0054 (T) + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00}, // U+0055 (U) + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0056 (V) + { 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00}, // U+0057 (W) + { 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00}, // U+0058 (X) + { 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // U+0059 (Y) + { 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00}, // U+005A (Z) + { 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00}, // U+005B ([) + { 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00}, // U+005C (\) + { 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00}, // U+005D (]) + { 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00}, // U+005E (^) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, // U+005F (_) + { 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0060 (`) + { 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00}, // U+0061 (a) + { 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00}, // U+0062 (b) + { 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00}, // U+0063 (c) + { 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00}, // U+0064 (d) + { 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00}, // U+0065 (e) + { 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00}, // U+0066 (f) + { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0067 (g) + { 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00}, // U+0068 (h) + { 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0069 (i) + { 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E}, // U+006A (j) + { 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00}, // U+006B (k) + { 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+006C (l) + { 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00}, // U+006D (m) + { 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00}, // U+006E (n) + { 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+006F (o) + { 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F}, // U+0070 (p) + { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78}, // U+0071 (q) + { 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00}, // U+0072 (r) + { 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00}, // U+0073 (s) + { 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+0074 (t) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00}, // U+0075 (u) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0076 (v) + { 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00}, // U+0077 (w) + { 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00}, // U+0078 (x) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0079 (y) + { 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00}, // U+007A (z) + { 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00}, // U+007B ({) + { 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, // U+007C (|) + { 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00}, // U+007D (}) + { 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+007E (~) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // U+007F +}; +#endif diff --git a/userland/windowserver/ws.c b/userland/windowserver/ws.c new file mode 100644 index 0000000..e4f1a9e --- /dev/null +++ b/userland/windowserver/ws.c @@ -0,0 +1,375 @@ +#include +#include +#include +#include +//#include +#include "draw.h" +#include "font.h" +#include "ws.h" +#include +#include +#include +#include +#include +#include + +#define WINDOW_SERVER_SOCKET "/windowserver" + +CLIENT *clients[100]; +CLIENT *active_client; + +int mouse_x = 0; +int mouse_y = 0; + +// void *true_display; +// void *buffer_display; +// uint64_t display_size; +// int border_size; +// uint8_t border_color; +DISPLAY main_display; + +struct pollfd *fds; +uint64_t num_fds; + +uint64_t socket_fd_poll; +uint64_t keyboard_fd_poll; +uint64_t mouse_fd_poll; + +// Taken from drivers/keyboard.c +struct KEY_EVENT { + char c; + uint8_t mode; // (shift (0 bit)) (alt (1 bit)) + uint8_t release; // 0 pressed, 1 released +}; + +int create_socket(void) { + struct sockaddr_un address; + int fd = socket(AF_UNIX, 0, 0); + address.sun_family = AF_UNIX; + size_t str_len = strlen(WINDOW_SERVER_SOCKET); + address.sun_path = malloc(str_len + 1); + memcpy(address.sun_path, WINDOW_SERVER_SOCKET, str_len); + address.sun_path[str_len] = 0; + + bind(fd, (struct sockaddr *)(&address), sizeof(address)); + // for(;;); + /*free(address.sun_path);*/ + return fd; +} + +void setup_display(DISPLAY *disp, const char *path, uint64_t size) { + disp->wallpaper_color = 0x3; + disp->size = size; + disp->vga_fd = open(path, O_RDWR, 0); + if (-1 == disp->vga_fd) { + perror("open"); + for (;;) + ; + } + disp->true_buffer = mmap(NULL, size, 0, 0, disp->vga_fd, 0); + disp->back_buffer = malloc(size + 0x1000); + disp->clients = clients; +} + +void setup(void) { + setup_display(&main_display, "/dev/vbe", 0xBB8000); + draw_wallpaper(&main_display); + update_display(&main_display); + + main_display.border_size = 1; + main_display.border_color = 0xF; + active_client = NULL; + for (int i = 0; i < 100; i++) { + clients[i] = NULL; + } + + num_fds = 100; + fds = malloc(sizeof(struct pollfd[num_fds])); + memset(fds, 0, sizeof(struct pollfd[num_fds])); + for (size_t i = 0; i < num_fds; i++) + fds[i].fd = -1; + // Create socket + int socket_fd = create_socket(); + assert(socket_fd >= 0); + socket_fd_poll = 0; + fds[socket_fd_poll].fd = socket_fd; + fds[socket_fd_poll].events = POLLIN; + fds[socket_fd_poll].revents = 0; + int keyboard_fd = open("/dev/keyboard", O_RDONLY | O_NONBLOCK, 0); + assert(keyboard_fd >= 0); + keyboard_fd_poll = 1; + fds[keyboard_fd_poll].fd = keyboard_fd; + fds[keyboard_fd_poll].events = POLLIN; + fds[keyboard_fd_poll].revents = 0; + int mouse_fd = open("/dev/mouse", O_RDONLY, 0); + assert(mouse_fd >= 0); + mouse_fd_poll = 2; + fds[mouse_fd_poll].fd = mouse_fd; + fds[mouse_fd_poll].events = POLLIN; + fds[mouse_fd_poll].revents = 0; +} + +void reset_revents(struct pollfd *fds, size_t s) { + for (size_t i = 0; i < s - 1; i++) + fds[i].revents = 0; +} + +void add_fd(int fd) { + int i; + for (i = 0; i < num_fds; i++) + if (-1 == fds[i].fd) + break; + + fds[i].fd = fd; + fds[i].events = POLLIN | POLLHUP; + // fds[i].events = POLLIN; + fds[i].revents = 0; +} + +void add_client(int fd) { + int client_socket = accept(fd, NULL, NULL); + add_fd(client_socket); + int i; + for (i = 0; i < 100; i++) + if (!clients[i]) + break; + printf("adding client: %d\n", i); + CLIENT *c = clients[i] = malloc(sizeof(CLIENT)); + c->fd = client_socket; + active_client = c; + printf("clients[0]: %x\n", clients[0]); +} + +#define CLIENT_EVENT_CREATESCREEN 0 +#define CLIENT_EVENT_UPDATESCREEN 1 + +void add_window(CLIENT *c, int fd, int x, int y, int sx, int sy) { + WINDOW *w = malloc(sizeof(WINDOW)); + w->bitmap_fd = fd; + w->bitmap_ptr = mmap(NULL, sx * sy * sizeof(uint32_t), 0, 0, fd, 0); + w->x = x; + w->y = y; + w->sx = sx; + w->sy = sy; + c->w = w; +} + +typedef struct { + uint16_t px; + uint16_t py; + uint16_t sx; + uint16_t sy; + uint8_t name_len; +} WS_EVENT_CREATE; + +void parse_client_event(CLIENT *c) { + uint8_t event_type; + if (0 == read(c->fd, &event_type, sizeof(uint8_t))) { + printf("empty\n"); + return; + } + if (0 == event_type) { + update_full_display(&main_display, mouse_x, mouse_y); + return; + } + if (1 == event_type) { + WS_EVENT_CREATE e; + for (; 0 == read(c->fd, &e, sizeof(e));) + ; + uint8_t bitmap_name[e.name_len + 1]; + read(c->fd, bitmap_name, e.name_len); + bitmap_name[e.name_len] = '\0'; + int bitmap_fd = shm_open(bitmap_name, O_RDWR, O_CREAT); + add_window(c, bitmap_fd, e.px, e.py, e.sx, e.sy); + update_full_display(&main_display, mouse_x, mouse_y); + } +} + +typedef struct { + int type; + struct KEY_EVENT ev; +} WS_EVENT; + +void send_to_client(struct KEY_EVENT ev) { + WS_EVENT e = { + .type = 0, + .ev = ev, + }; + write(active_client->fd, &e, sizeof(e)); +} + +void clamp_screen_position(int *x, int *y) { + if (0 > *x) { + *x = 0; + } + if (0 > *y) { + *y = 0; + } + if (WIDTH < *x) { + *x = WIDTH; + } + if (HEIGHT < *y) { + *y = HEIGHT; + } +} + +int windowserver_key_events(struct KEY_EVENT ev, int *redraw) { + if (!(ev.mode & (1 << 1))) + return 0; + if (!active_client) + return 0; + int x = 0; + int y = 0; + switch (ev.c) { + case 'l': + x++; + break; + case 'h': + x--; + break; + case 'k': + y--; + break; + case 'j': + y++; + break; + } + if (x || y) { + active_client->w->x += x; + active_client->w->y += y; + clamp_screen_position(&active_client->w->x, &active_client->w->y); + *redraw = 1; + return 1; + } + return 0; +} + +struct mouse_event { + uint8_t buttons; + uint8_t x; + uint8_t y; +}; + +void update_mouse(void) { + draw_mouse(&main_display, mouse_x, mouse_y); + return; +} + +void parse_mouse_event(int fd) { + int16_t xc = 0; + int16_t yc = 0; + int middle_button = 0; + for (;;) { + struct mouse_event e[100]; + int rc = read(fd, e, sizeof(e)); + if (rc <= 0) + break; + + int n = rc / sizeof(e[0]); + for (int i = 0; i < n; i++) { + uint8_t xs = e[i].buttons & (1 << 4); + uint8_t ys = e[i].buttons & (1 << 5); + middle_button = e[i].buttons & (1 << 2); + int16_t x = e[i].x; + int16_t y = e[i].y; + if (xs) + x |= 0xFF00; + if (ys) + y |= 0xFF00; + xc += *(int16_t *)&x; + yc += *(int16_t *)&y; + } + } + mouse_x += xc; + mouse_y -= yc; + if (mouse_x < 0) + mouse_x = 0; + if (mouse_y < 0) + mouse_y = 0; + if (middle_button) { + active_client->w->x += xc; + active_client->w->y -= yc; + clamp_screen_position(&active_client->w->x, &active_client->w->y); + } + update_mouse(); +} + +void parse_keyboard_event(int fd) { + if (!active_client) { + return; + } + struct KEY_EVENT ev[250]; + int redraw = 0; + for (;;) { + int rc; + if (0 > (rc = read(fd, &ev[0], sizeof(ev)))) + break; + int n = rc / sizeof(ev[0]); + for (int i = 0; i < n; i++) { + if (windowserver_key_events(ev[i], &redraw)) + continue; + send_to_client(ev[i]); + } + } + if (redraw) + update_full_display(&main_display, mouse_x, mouse_y); +} + +CLIENT *get_client(int fd) { + for (int i = 0; i < 100; i++) { + if (!clients[i]) + continue; + if (clients[i]->fd == fd) + return clients[i]; + } + return NULL; +} + +void kill_client(CLIENT *c) { + c->w = NULL; + update_full_display(&main_display, mouse_x, mouse_y); + active_client = clients[0]; +} + +void parse_revents(struct pollfd *fds, size_t s) { + for (size_t i = 0; i < s - 1; i++) { + if (!fds[i].revents) + continue; + if (-1 == fds[i].fd) + continue; + if (socket_fd_poll == i && fds[i].revents & POLLIN) { + add_client(fds[i].fd); + continue; + } else if (keyboard_fd_poll == i) { + parse_keyboard_event(fds[i].fd); + continue; + } else if (mouse_fd_poll == i) { + parse_mouse_event(fds[i].fd); + continue; + } + CLIENT *c = get_client(fds[i].fd); + assert(c); + if (fds[i].revents & POLLHUP) { + kill_client(c); + fds[i].fd = -1; + } else { + parse_client_event(c); + } + } +} + +void run(void) { + for (;;) { + poll(fds, num_fds, 0); + parse_revents(fds, num_fds); + reset_revents(fds, num_fds); + } +} + +int main(void) { + open("/dev/serial", O_WRITE, 0); + open("/dev/serial", O_WRITE, 0); + setup(); + run(); + return 0; +} diff --git a/userland/windowserver/ws.h b/userland/windowserver/ws.h new file mode 100644 index 0000000..c4daf7b --- /dev/null +++ b/userland/windowserver/ws.h @@ -0,0 +1,30 @@ +#ifndef WS_H +#define WS_H +#include +#include + +typedef struct { + int bitmap_fd; + uint32_t *bitmap_ptr; + int x; + int y; + int sx; + int sy; +} WINDOW; + +typedef struct { + int fd; + WINDOW *w; +} CLIENT; + +typedef struct { + int vga_fd; + uint8_t *back_buffer; + uint8_t *true_buffer; + size_t size; + uint8_t border_size; + uint8_t border_color; + uint8_t wallpaper_color; + CLIENT **clients; +} DISPLAY; +#endif -- cgit v1.2.3